DPD Schedule Frequency & Approval Filtering
Changes to improve DPD claim processing speed and clean up stale reminder approvals.
Overview
Two related improvements:
- DPD backfill schedule: Changed from once daily (11AM UK) to every 4 hours — new claims get picked up faster
- Reminder filtering: Reminder approvals for resolved or DOR claims are now filtered out at the workflow and UI layers
Schedule Change
graph LR
subgraph Before["Before"]
A[11AM Daily<br/>CalendarSpec] --> B[Up to 24h delay]
end
subgraph After["After"]
C[Every 4 Hours<br/>IntervalSpec] --> D[Max 4h delay]
endFile: EmailProcessing.Worker/Program.cs — EnsureDpdBackfillScheduleAsync
- Create path:
ScheduleIntervalSpec(Every: 4h)replacesScheduleCalendarSpecat 11AM - Update path: Now replaces
existing.Specwith the new interval spec (previously preserved old spec) - Existing schedules migrate automatically on next deploy
ScheduleOverlapPolicy.Skipretained to prevent overlapping runs
DOR Reminder Filtering
DOR (Dispute of Resolution) statuses 17-20 are not terminal — claims may return from dispute resolution — but reminders are pointless while DOR is in progress. DOR is now filtered at the workflow and UI layers:
graph TB
subgraph Workflow["Layer 1: Workflow Real-Time"]
WF[IsClaimStatusRemindable]
WF --> |"DOR detected"| SKIP[Skip reminder scheduling]
end
subgraph UI["Layer 2: UI Filter"]
PA[PendingApprovalsService]
PA --> |"DOR detected"| HIDE[Hide from approvals list]
end
subgraph Cleanup["Backfill Cleanup — unchanged"]
CL[CleanupTerminalClaimsActivity]
CL --> |"DOR is NOT terminal"| KEEP[Workflow stays running]
end
Workflow -.-> |"Prevents new approvals"| UI
UI -.-> |"Hides stale approvals"| USER[User sees clean list]Files Changed
| File | Change |
|---|---|
EmailProcessing.Worker/Program.cs |
Schedule spec: daily calendar → 4-hour interval; update path migrates existing |
ClaimWorkflowBase.cs |
IsClaimStatusRemindable() now excludes DOR statuses 17-20 |
PendingApprovalsService.cs |
New DB filter removes approvals for terminal + DOR + Accepted claims |
Status Coverage
All statuses that suppress reminder approvals:
| Status | ID | Terminal? | Filtered by |
|---|---|---|---|
| Accepted | 5 | No (in-flight) | Workflow, UI |
| Credited | 6 | Yes | Workflow, Cleanup, UI |
| RejectedAssumed | 8 | Yes | Workflow, Cleanup, UI |
| Rejected | 9 | Yes | Workflow, Cleanup, UI |
| Found | 12 | Yes | Workflow, Cleanup, UI |
| OldClaim | 14 | Yes | Workflow, Cleanup, UI |
| DorSubmittedByCourier | 17 | No | Workflow, UI (new) |
| DorSubmittedByClaimit | 18 | No | Workflow, UI (new) |
| DorReceivedByCourier | 19 | No | Workflow, UI (new) |
| DorReceivedByClaimit | 20 | No | Workflow, UI (new) |
| Invalid | 22 | Yes | Workflow, Cleanup, UI |
DOR claims keep their workflows running — the cleanup activity does not terminate them. If a DOR claim returns to a remindable status, reminders will resume automatically.
EmailSimulator Filtering Detail
sequenceDiagram
participant UI as Approvals Panel
participant SVC as PendingApprovalsService
participant TC as Temporal Cloud
participant DB as SQL Database
UI->>SVC: GetPendingApprovalsAsync()
SVC->>TC: ListWorkflowsAsync<br/>(HasPendingIntervention = true)
TC-->>SVC: Workflow list with search attributes
SVC->>DB: Batch query claim statuses<br/>for all tracking numbers
DB-->>SVC: Current ClaimStatusId per claim
SVC->>SVC: Filter out non-remindable statuses
SVC-->>UI: Clean approval listThe DB query runs on every panel load — no caching — so status changes are reflected immediately.