Patterns
Close, reopen and recover from delivery failure
Make inactive state and failed outbound delivery understandable with specific next actions.
On this page
User goal
Make inactive state and failed outbound delivery understandable with specific next actions.
Workflow
| Step | Expected behavior |
|---|---|
| 1 | Close a completed active conversation with the explicit Close action. |
| 2 | Read the closed explanation and Reopen action when revisiting. |
| 3 | Restore Junk with a separate named action. |
| 4 | For failed/blocked messages, inspect delivery details and recipient identity. |
| 5 | Use Retry only after resolving the relevant issue; source updates local status to sending. |
Decision and composition rules
- Closing clears unread and waiting context.
- Reopening restores needs-reply with waiting now.
- Delivery failure does not automatically change work type or customer relationship.
Edge cases and recovery
- Retry queued in the prototype is a local toast, not an actual job receipt.
- A real outbox retry needs idempotency and authoritative provider events.
- Transient notifications must not be the only failure record.
- Server status and frontend status unions need an explicit DTO adapter.
Persistence boundary
The demonstrated frontend uses local React state or static fixtures. Read the readiness topic before connecting these actions to authenticated persistence. A visible toast, badge or timer is not a server acknowledgement.
Source references
| File | Responsibility |
|---|---|
| components/inbox/conversation-detail.tsx | Failure banner and lifecycle |
| components/inbox/message-details-dialog.tsx | Delivery view |
| lib/server/jobs/process-email.ts | Separate worker boundary |
Examples from the app
Actual Sonarist components with fictional conversations, people, example.com addresses and simulated operational states. Captured at 2× resolution or higher. Select an image to inspect it full size.
Related topics
Source audit: 2026-10-08 · Revision 10f45d1377b5 · Documentation v1.0.0