Overview
Complete lifecycle of an Asendia claim from portal submission through to final resolution. The workflow is orchestrated by Temporal, with automated email processing, LLM classification, reminder escalation, and human intervention gates.
Full Workflow Lifecycle
flowchart TD
subgraph Portal["Portal Submission"]
A([Customer submits claim<br/>via Claimit Portal]) --> B[Claim created in DB<br/>Status: New]
B --> C{Client & Claim<br/>Reason?}
C -->|Frasers Disputed Delivery| D[Select Frasers DD Template]
C -->|Coat Paints| E[Select Coat Paints Template]
C -->|All Others| F[Select Default Asendia Template]
C -->|Spain Country 724| G[Route to Web Automation<br/>Not email workflow]
end
D --> H
E --> H
F --> H
subgraph Submission["Claim Submission to Asendia"]
H[Wait 20 minutes<br/>Allow user edits] --> I[Fetch claim & attachments]
I --> J[Look up courier email<br/>from CourierEmails table]
J --> K{DRY-RUN<br/>mode?}
K -->|Yes| L[Log to Slack<br/>Skip sending]
K -->|No| M[Send submission email<br/>via Microsoft Graph API]
M --> N[Status: SubmittedSent]
end
N --> O
subgraph MainLoop["Email Processing Loop"]
O{Wait for email<br/>or timeout}
O -->|Email received| P[EmailReceivedSignal]
O -->|30 days no email| TIMEOUT
P --> Q{Duplicate<br/>email?}
Q -->|Yes| O
Q -->|No| R[Send to LLM for<br/>classification]
R --> S{Classification<br/>confidence?}
S -->|Below 0.7 threshold| T[Skip email<br/>Low confidence]
T --> O
S -->|Above threshold| U{Classification<br/>type enabled?}
U -->|No| O
U -->|Yes| V[Process email details<br/>Extract amounts, reasons, refs]
end
subgraph Classification["Email Classification & Status Update"]
V --> W{What did Asendia<br/>say?}
W -->|"Claim logged/registered/received"<br/>Confidence boost to 0.95| ACK2[Status: SubmittedAck]
W -->|Acknowledgment| ACK2
W -->|Request more info| MI[Status: MoreInfo]
W -->|Credit approved| CR[Status: Accepted]
W -->|Rejection| RJ[Status: Rejected]
W -->|Item found| FD[Status: Found]
W -->|Chasing response| CH[Status: Chasing]
ACK2 --> CONT[Continue waiting]
MI --> CONT
CH --> CONT
CONT --> O
end
subgraph Reminders["Reminder & Escalation Logic"]
O -->|7 days no response| R1{Reminder #1 Due}
R1 --> HI1[Create Human Intervention<br/>Request: ReminderApproval]
HI1 --> HR1{Human Decision}
HR1 -->|Approve| SEND1[Send Reminder #1<br/>Status: Chasing]
HR1 -->|Reject| O
HR1 -->|Email arrives<br/>while waiting| CANCEL1[Auto-cancel intervention]
CANCEL1 --> P
SEND1 --> O
O -->|14 days no response| R2{Reminder #2 Due}
R2 --> HI2[Human Intervention<br/>Request]
HI2 --> SEND2[Send Reminder #2<br/>Status: Chasing]
SEND2 --> O
O -->|21 days no response| R3{Reminder #3 Due}
R3 --> HI3[Human Intervention<br/>Request]
HI3 --> SEND3[Send Reminder #3<br/>TO ESCALATION EMAIL]
SEND3 --> O
end
subgraph Final["Workflow Completion"]
CR --> FIN
RJ --> FIN
FD --> FIN
TIMEOUT[Timeout: 30 days<br/>no email received] --> FIN
FIN([Finalize Workflow]) --> RES[Record result:<br/>FinalStatus, EmailsProcessed,<br/>Duration, CompletionReason]
RES --> AUDIT[Write audit log<br/>10-20 business events]
AUDIT --> DONE([Workflow Complete])
end
subgraph ContinueAsNew["Long-Running Protection"]
O -->|20+ emails processed| CAN[Continue-As-New<br/>Preserve state, reset history]
CAN --> O
end
style A fill:#e1f5fe,stroke:#0288d1,color:#000
style B fill:#e1f5fe,stroke:#0288d1,color:#000
style N fill:#e8f5e9,stroke:#388e3c,color:#000
style ACK2 fill:#e8f5e9,stroke:#388e3c,color:#000
style MI fill:#fff3e0,stroke:#f57c00,color:#000
style CH fill:#fff3e0,stroke:#f57c00,color:#000
style CR fill:#e8f5e9,stroke:#2e7d32,color:#000
style RJ fill:#fce4ec,stroke:#c62828,color:#000
style FD fill:#f3e5f5,stroke:#7b1fa2,color:#000
style TIMEOUT fill:#fce4ec,stroke:#c62828,color:#000
style DONE fill:#e8f5e9,stroke:#2e7d32,color:#000
style G fill:#fff9c4,stroke:#f9a825,color:#000
style HI1 fill:#fff9c4,stroke:#f9a825,color:#000
style HI2 fill:#fff9c4,stroke:#f9a825,color:#000
style HI3 fill:#fff9c4,stroke:#f9a825,color:#000
style CAN fill:#f3e5f5,stroke:#7b1fa2,color:#000
style L fill:#fff9c4,stroke:#f9a825,color:#000Claim Status Transitions
stateDiagram-v2
[*] --> New: Claim Created
New --> SubmittedSent: Email sent to Asendia<br/>(after 20min delay)
New --> WebAutomation: Spain claims only
SubmittedSent --> SubmittedAck: Asendia acknowledges
SubmittedSent --> Accepted: Credit approved
SubmittedSent --> Rejected: Claim denied
SubmittedSent --> Found: Item located
SubmittedSent --> MoreInfo: Info requested
SubmittedSent --> Chasing: Reminder sent
SubmittedAck --> Accepted: Credit approved
SubmittedAck --> Rejected: Claim denied
SubmittedAck --> Found: Item located
SubmittedAck --> MoreInfo: Info requested
SubmittedAck --> Chasing: Reminder sent
MoreInfo --> Accepted: Credit approved
MoreInfo --> Rejected: Claim denied
MoreInfo --> Chasing: Reminder sent
Chasing --> Accepted: Credit approved
Chasing --> Rejected: Claim denied
Chasing --> Found: Item located
Chasing --> Chasing: Another reminder sent
Accepted --> [*]: FINAL
Rejected --> [*]: FINAL
Found --> [*]: FINAL
note right of New: Status ID 1
note right of SubmittedSent: Status ID 3
note right of SubmittedAck: Status ID 4
note right of MoreInfo: Status ID 2
note right of Chasing: Status ID 7
note right of Accepted: Status ID 5
note right of Rejected: Status ID 9
note right of Found: Status ID 12Email Classification Pipeline
flowchart LR
subgraph Input
EMAIL[Incoming Email<br/>from Asendia]
end
subgraph LLM["LLM Classification"]
PARSE[Parse email body] --> CLASSIFY[Send to OpenRouter<br/>LLM]
CLASSIFY --> PRED[PredictedCategory<br/>+ Confidence Score]
end
subgraph AsendiaBoost["Asendia-Specific"]
BOOST{"Matches pattern?<br/>claim (is)? (logged|<br/>registered|received)"}
BOOST -->|Yes| HIGH[Boost confidence<br/>to 0.95]
BOOST -->|No| KEEP[Keep original<br/>confidence]
end
subgraph Threshold["Threshold Check"]
CHECK{Confidence<br/>>= 0.7?}
CHECK -->|No| SKIP[Skip - low confidence]
CHECK -->|Yes| ENABLED{Classification<br/>type enabled?}
ENABLED -->|No| SKIP2[Skip - disabled]
ENABLED -->|Yes| APPLY[Apply classification]
end
EMAIL --> PARSE
PRED --> BOOST
HIGH --> CHECK
KEEP --> CHECK
subgraph Outcomes
APPLY --> CREDIT[CREDIT]
APPLY --> REJECT[REJECTION]
APPLY --> FOUND2[FOUND]
APPLY --> MOREINFO[MORE_INFO]
APPLY --> ACKNOWLEDGE[ACKNOWLEDGE]
end
style EMAIL fill:#e1f5fe,stroke:#0288d1,color:#000
style HIGH fill:#e8f5e9,stroke:#388e3c,color:#000
style SKIP fill:#fce4ec,stroke:#c62828,color:#000
style SKIP2 fill:#fce4ec,stroke:#c62828,color:#000
style CREDIT fill:#e8f5e9,stroke:#2e7d32,color:#000
style REJECT fill:#fce4ec,stroke:#c62828,color:#000
style FOUND2 fill:#f3e5f5,stroke:#7b1fa2,color:#000Reminder Escalation Timeline
gantt
title Reminder Schedule After Last Asendia Response
dateFormat X
axisFormat Day %s
section Wait Periods
Wait for response :wait1, 0, 7
Wait after Reminder 1 :wait2, 7, 14
Wait after Reminder 2 :wait3, 14, 21
Wait for timeout :wait4, 21, 30
section Actions
Reminder 1 - Standard :milestone, r1, 7, 0
Reminder 2 - Standard :milestone, r2, 14, 0
Reminder 3 - ESCALATION :milestone, r3, 21, 0
TIMEOUT - Workflow Ends :milestone, t1, 30, 0Happy Path vs Problematic Paths
Happy Path — Credit Approved
sequenceDiagram
participant U as User
participant P as Portal
participant W as Workflow
participant A as Asendia
U->>P: Submit claim
P->>W: Create claim (Status: New)
Note over W: Wait 20 minutes
W->>A: Send submission email
Note over W: Status: SubmittedSent
A->>W: "Claim logged"
Note over W: Status: SubmittedAck
A->>W: "Credit approved £X.XX"
Note over W: Status: Accepted
W->>W: Finalize — SUCCESSWith Reminders — Eventually Rejected
sequenceDiagram
participant W as Workflow
participant H as Human Reviewer
participant A as Asendia
W->>A: Submit claim
Note over W: Status: SubmittedSent
Note over W,A: 7 days pass — no response
W->>H: Intervention: Approve Reminder #1?
H->>W: Approved
W->>A: Reminder #1
Note over W: Status: Chasing
Note over W,A: 7 more days — no response
W->>H: Intervention: Approve Reminder #2?
H->>W: Approved
W->>A: Reminder #2
Note over W,A: 7 more days — no response
W->>H: Intervention: Approve Reminder #3?
H->>W: Approved
W->>A: Reminder #3 (ESCALATION EMAIL)
A->>W: "Claim rejected — insufficient evidence"
Note over W: Status: Rejected
W->>W: Finalize — REJECTEDTimeout — No Response
sequenceDiagram
participant W as Workflow
participant A as Asendia
W->>A: Submit claim
Note over W: Status: SubmittedSent
Note over W,A: Reminders sent at days 7, 14, 21
Note over W,A: 30 days total — no email received
W->>W: TIMEOUT
Note over W: Status remains: Chasing
W->>W: Finalize — TIMEOUTStatus Reference
| ID | Status | Terminal? | Remindable? | Triggered By |
|---|---|---|---|---|
| 1 | New | No | Yes | Portal submission |
| 2 | MoreInfo | No | Yes | Asendia requests info |
| 3 | SubmittedSent | No | Yes | Submission email sent |
| 4 | SubmittedAck | No | Yes | Asendia acknowledges |
| 5 | Accepted | Yes | No | Credit approved |
| 6 | Credited | Yes | No | Payment received |
| 7 | Chasing | No | Yes | Reminder sent |
| 8 | RejectedAssumed | Yes | No | No response (legacy) |
| 9 | Rejected | Yes | No | Asendia rejects |
| 12 | Found | Yes | No | Item located |
| 14 | OldClaim | Yes | No | Historical import |
| 21 | Investigating | No | Yes | Under investigation |
| 22 | Invalid | Yes | No | Claim invalid |
Key Temporal Patterns
- SignalWithStart: Email poller uses this to create workflows or signal existing ones
- Continue-As-New: After 20 emails processed, workflow restarts with preserved state to prevent history bloat
- Human Intervention: Reminders require approval via
HumanInterventionRequest— workflow pauses until human acts or email arrives (auto-cancels) - Search Attributes:
HasPendingIntervention,RemindersSent,WorkflowStatus,ClaimStatusNameenable monitoring queries - DRY-RUN Mode: Dev/test environments log to Slack instead of sending real emails