User flow
Make the path executable, including what happens when the system does not give a clean answer. Use the existing workflow and permissions as evidence.
Work
- Name the actor, entry point, goal, required information, and success destination.
- Trace the shortest complete path. At each transition, name the user action, system response, data owner, and visible feedback.
- Add relevant validation, authorization, timeout, conflict, cancellation, session expiry, and back-navigation branches. Avoid an exhaustive list of unreachable states.
- For writes, distinguish pending, committed, rejected, and outcome-unknown. A lost response may follow a successful write; define reconciliation or server-enforced idempotency before retrying.
- Decide what input survives interruption and for how long. Do not automatically store sensitive drafts in localStorage; match persistence to the data and shared-device risk.
- On a running feature, reproduce the path where possible and mark untested branches. Preserve product intent while correcting friction.
Deliver
A compact flow diagram or ordered path with a branch table: trigger → visible state → recovery → data/permission contract. Include acceptance examples for consequential branches.
Follow this shape:
User flow: [goal]
User: ... Entry: ... Success: ...
Path: [Start] → ... → [Success]
Branches: trigger → visible state → recovery → data/permission contract
UI states: ...
Open questions: ...
Example: a timed-out project creation first checks the operation's result before offering another create. A disabled button helps prevent repeat clicks but does not guarantee one server write.
Verify entry, success, interruption, and return behavior with the applicable input methods. Use $states for cross-screen coverage and $component for the interaction contract of a particular control.
Worked example
User flow: Create project
User: Project manager (authenticated) Entry: Dashboard "New project" button Success: Project created; user lands on its detail page.
Path: [Dashboard] → [Create form] → validation pass → POST /api/projects → [Project detail]
Branches:
- Validation error → inline field errors; keep all input → correct and resubmit → no write yet.
- API failure (network/500) → toast plus retry; preserve form → retry the same operation → check result before re-creating.
- Name exists (409) → field error → rename and resubmit.
- Cancel/back with non-empty fields → confirm discard → discard draft.
- Expired session → login with return URL; restore draft → resume.
UI states: idle; submitting with spinner and disabled button ("Create project" → "Creating…"); error banner.
Data/permission contract: POST /api/projects requires auth; validate name and teamId from session; define idempotency before retry.
V1 scope: defer templates and bulk import.
Open questions: auto-invite team members on create?
Gotchas
- Do not offer blind retry after an unknown write outcome; check the result or require idempotency first.
- Do not treat a disabled button as duplicate-write protection.
- Do not persist sensitive drafts in localStorage by default; match lifetime to shared-device risk.
- Do not enumerate unreachable states; cover relevant validation, auth, timeout, conflict, cancel, session, and back branches.
- Do not collapse pending, committed, rejected, and outcome-unknown into one generic error.
Boundaries
- Do not use when page or route structure is the question — use
$sitemap instead.
- Do not use when a single control needs an interaction contract — use
$component instead.
1---2name: flow3description: Map or review a task from entry to outcome, including mutations, interruptions, and recovery. Use when mapping onboarding, checkout, creation, editing, approval, or account flows including failure and recovery branches.4---56# User flow78Make the path executable, including what happens when the system does not give a clean answer. Use the existing workflow and permissions as evidence.910## Work1112- Name the actor, entry point, goal, required information, and success destination.13- Trace the shortest complete path. At each transition, name the user action, system response, data owner, and visible feedback.14- Add relevant validation, authorization, timeout, conflict, cancellation, session expiry, and back-navigation branches. Avoid an exhaustive list of unreachable states.15- For writes, distinguish pending, committed, rejected, and outcome-unknown. A lost response may follow a successful write; define reconciliation or server-enforced idempotency before retrying.16- Decide what input survives interruption and for how long. Do not automatically store sensitive drafts in localStorage; match persistence to the data and shared-device risk.17- On a running feature, reproduce the path where possible and mark untested branches. Preserve product intent while correcting friction.1819## Deliver2021A compact flow diagram or ordered path with a branch table: **trigger → visible state → recovery → data/permission contract**. Include acceptance examples for consequential branches.2223Follow this shape:2425## User flow: [goal]26**User:** ... **Entry:** ... **Success:** ...27Path: [Start] → ... → [Success]28Branches: trigger → visible state → recovery → data/permission contract29UI states: ...30Open questions: ...3132Example: a timed-out project creation first checks the operation's result before offering another create. A disabled button helps prevent repeat clicks but does not guarantee one server write.3334Verify entry, success, interruption, and return behavior with the applicable input methods. Use `$states` for cross-screen coverage and `$component` for the interaction contract of a particular control.3536## Worked example3738## User flow: Create project3940**User:** Project manager (authenticated) **Entry:** Dashboard "New project" button **Success:** Project created; user lands on its detail page.41Path: [Dashboard] → [Create form] → validation pass → POST /api/projects → [Project detail]42Branches:43- Validation error → inline field errors; keep all input → correct and resubmit → no write yet.44- API failure (network/500) → toast plus retry; preserve form → retry the same operation → check result before re-creating.45- Name exists (409) → field error → rename and resubmit.46- Cancel/back with non-empty fields → confirm discard → discard draft.47- Expired session → login with return URL; restore draft → resume.48UI states: idle; submitting with spinner and disabled button ("Create project" → "Creating…"); error banner.49Data/permission contract: POST /api/projects requires auth; validate name and teamId from session; define idempotency before retry.50V1 scope: defer templates and bulk import.51Open questions: auto-invite team members on create?5253## Gotchas5455- Do not offer blind retry after an unknown write outcome; check the result or require idempotency first.56- Do not treat a disabled button as duplicate-write protection.57- Do not persist sensitive drafts in localStorage by default; match lifetime to shared-device risk.58- Do not enumerate unreachable states; cover relevant validation, auth, timeout, conflict, cancel, session, and back branches.59- Do not collapse pending, committed, rejected, and outcome-unknown into one generic error.6061## Boundaries6263- Do not use when page or route structure is the question — use `$sitemap` instead.64- Do not use when a single control needs an interaction contract — use `$component` instead.