204 lines
9.6 KiB
Markdown
204 lines
9.6 KiB
Markdown
# Phase 3 — The flow atlas (verified)
|
||
|
||
**Depends on:** Phase 0, Phase 2 · **Blocks:** Phase 4 · **Size:** 2–4 sessions — the biggest phase
|
||
|
||
## Goal
|
||
|
||
Build **the one go-to place** that answers, for every flow in the product:
|
||
|
||
1. What is it, and who does it?
|
||
2. **Is it actually implemented — really, or only mocked?**
|
||
3. What screens and endpoints does it use?
|
||
4. **How do I test it, step by step, with which account?**
|
||
5. What's known to be broken or missing?
|
||
|
||
This is the phase where "verify the load-bearing claims" earns its keep. The existing
|
||
[manual-testing-plan.md](../../dev/post-phase/manual-testing-plan.md) is the closest predecessor and
|
||
it is already wrong about bring-up (it tells you to set `user-secrets`, which the code no longer
|
||
reads). Copying it forward would reproduce the problem this chain exists to fix.
|
||
|
||
**Run this phase in slices.** One session does `testing-setup.md` + 4–6 flows. Later sessions pick up
|
||
the next slice. The index table tracks which flows are done.
|
||
|
||
---
|
||
|
||
## Inputs
|
||
|
||
- [dev/post-phase/manual-testing-plan.md](../../dev/post-phase/manual-testing-plan.md) — flow
|
||
walkthroughs, test accounts, the seeded world, the mock-vs-real map, the numbers the UI must respect
|
||
- [dev/post-phase/refinement/RUNBOOK.md](../../dev/post-phase/refinement/RUNBOOK.md) — bring-up, demo
|
||
accounts, login round-trip, reset, troubleshooting
|
||
- [dev/shared-working-context/reports/mocks-registry.md](../../dev/shared-working-context/reports/mocks-registry.md)
|
||
- `docs/integration/` — from Phase 2, the endpoint truth
|
||
- `product/business/*` — the 14 requirement areas; what "correct" means
|
||
- The seeder code (`DemoWorldSeeder`, `DemoLifecycleSeeder`) — **the authority on test accounts and
|
||
seeded state**, over any doc
|
||
- `client/src/app/[locale]/**` — 83 routes across `(customer)`, `(customer-focused)`, `nurse`,
|
||
`admin`, `partner`, `(public-routes)`
|
||
- `client/src/services/*/` — 22 domains, each with a mock/real flag
|
||
|
||
## Outputs
|
||
|
||
```
|
||
docs/flows/
|
||
index.md the status table — every flow, one row
|
||
testing-setup.md bring-up, accounts, seeded world, OTP, reset, troubleshooting
|
||
<flow>.md one per flow (see the candidate list)
|
||
```
|
||
|
||
---
|
||
|
||
## Candidate flow list
|
||
|
||
Derived from the route groups, the 22 service domains, and the 14 business areas. Confirm and adjust
|
||
in the first session; the point is one file per *user-meaningful journey*, not per screen.
|
||
|
||
| # | Flow | Actor | Primary routes |
|
||
| --- | --- | --- | --- |
|
||
| 1 | `auth-login-otp` | all | `(public-routes)/login`, `select-role` |
|
||
| 2 | `public-front-door` | guest | `/`, `welcome`, `terms`, `privacy` |
|
||
| 3 | `onboarding-customer` | customer | onboarding, account |
|
||
| 4 | `care-circle-patients` | customer | patients / care-circle |
|
||
| 5 | `addresses-and-map` | customer | addresses, Neshan pin |
|
||
| 6 | `onboarding-nurse` | nurse | profile, bank account |
|
||
| 7 | `nurse-service-areas` | nurse | coverage, whole-city (`districtId = null`) |
|
||
| 8 | `nurse-verification` | nurse + admin | verification journey, document upload, review queue |
|
||
| 9 | `nurse-catalog-and-pricing` | nurse | services, variant builder |
|
||
| 10 | `search-and-discovery` | customer | C1–C3, filters, nurse profile |
|
||
| 11 | `booking-request` | customer + nurse | C4/C5, nurse inbox, countdown, accept/reject |
|
||
| 12 | `checkout-and-payment` | customer | C6, gateway return, confirmation, escrow |
|
||
| 13 | `bnpl-installments` | customer | D1–D5 |
|
||
| 14 | `booking-lifecycle-evv` | nurse + customer | check-in/out, two-stage clinical gate |
|
||
| 15 | `cancellation-and-refunds` | customer + admin | cancel, policy, refund settlement |
|
||
| 16 | `reviews` | customer | post-visit review, moderation |
|
||
| 17 | `patient-care-records` | nurse + customer | append-only records |
|
||
| 18 | `nurse-earnings-and-payouts` | nurse | earnings, weekly payout run |
|
||
| 19 | `messaging-tickets` | all | threads, `is_internal` boundary |
|
||
| 20 | `notifications` | all | bell, day-grouped list |
|
||
| 21 | `admin-backoffice` | admin | config, holidays, audit, RBAC, queues |
|
||
| 22 | `partner-center` | partner | the separately-scoped portal |
|
||
| 23 | `account-and-settings` | all | profile, theme/language (settings-only since iteration 1) |
|
||
|
||
---
|
||
|
||
## Steps
|
||
|
||
### 1. Write `testing-setup.md` — and **actually boot it**
|
||
|
||
Do not transcribe RUNBOOK.md. Follow it, note where it is wrong, and write what really happens.
|
||
|
||
Must cover:
|
||
|
||
- Prerequisites and the two-terminal run (`dotnet run` + `npm run dev`).
|
||
- **Configuration** — the current, correct story: config in `appsettings.*.json` and `.env.*`;
|
||
`user-secrets` **is not used and is not read** (`<UserSecretsId>` was removed). The four crypto
|
||
values still matter and must match whatever the target DB was encrypted under — booting with
|
||
different `Seams:FieldEncryption` keys makes every phone lookup miss and every PII read throw
|
||
`Padding is invalid`. Say where they live now.
|
||
- **Which database.** The dev config has pointed at a *remote* SQL Server. Confirm the current
|
||
target, and give the local-DB alternative.
|
||
- **Test accounts** — read them out of the seeder, not the old doc. Note the phone-OTP admins
|
||
(`09120000020` super_admin, `09120000021` finance) and what each demo account is set up to
|
||
demonstrate.
|
||
- **Getting the OTP** — server console (`MOCK SMS — OTP code …`), `GET /api/v1/dev/last_otp/{phone}`,
|
||
or the Telegram relay. Note the limits: 120 s resend window, 5 wrong attempts, 60 s validity, and
|
||
that the OTP endpoints are IP rate-limited (scripted logins will 429).
|
||
- **The seeded world** — what `DemoLifecycleSeeder` builds (the 8-booking world), and the fact that
|
||
**time-relative scenarios age out** and need a reseed.
|
||
- **Reset** — the drop-and-reseed procedure, verified.
|
||
- **Troubleshooting** — the failures you actually hit while doing the above.
|
||
|
||
### 2. Build the mock-vs-real map — from code
|
||
|
||
The single most important input to every flow file, and the thing most likely to be stale in the
|
||
docs. For each of the 22 client `services/` domains, read the code:
|
||
|
||
- Is the mock flag on or off?
|
||
- If real, does the whole domain hit the API, or only part of it?
|
||
- Server-side: which seams are mocked (SMS, payment gateway, BNPL provider, object storage,
|
||
geocoder, search) and which have a real adapter available behind config (refinement-phase-8)?
|
||
|
||
Cross-check `mocks-registry.md` and **correct it** — Phase 0 already flagged that the registry has
|
||
had stale rows before. Put the result in `docs/flows/index.md` as a column, and in each flow file as
|
||
a header block.
|
||
|
||
Known suspects from the hardening audit (2026-07-16, never ticked off — verify each against current
|
||
code, do not assume): verification fully mocked while catalog/search are real; the refunds mock
|
||
reading a retired store; the BNPL wizard on a disconnected store; nurse earnings fabricated despite
|
||
live endpoints; `patientRecords` id-type mismatch.
|
||
|
||
### 3. Write one file per flow
|
||
|
||
Template — keep each under ~200 lines:
|
||
|
||
```markdown
|
||
# Flow — <name>
|
||
|
||
> Last verified: <date> against <commit>
|
||
|
||
**Actor(s):** · **Status:** built | partial | mocked | not started
|
||
**Business source:** product/business/NN-….md
|
||
|
||
## What it does
|
||
Two or three sentences. The user's intent, not the implementation.
|
||
|
||
## Screens
|
||
| Step | Route | Component/notes |
|
||
|
||
## API
|
||
| Call | Endpoint | Notes |
|
||
Link to docs/integration/domains/<domain>.md — don't restate shapes here.
|
||
|
||
## Rules that must hold
|
||
The load-bearing numbers and invariants, with their product/ source.
|
||
(e.g. commission 0.15, VAT 0.10 on commission only; forward-only status;
|
||
escrow released after confirmed check-out; whole-city = districtId NULL)
|
||
|
||
## How to test
|
||
1. Log in as <account> (see testing-setup.md)
|
||
2. …
|
||
**Expect:** …
|
||
|
||
## Known gaps
|
||
- [BL-xxx] … (filled by Phase 4; leave a plain list here for now)
|
||
```
|
||
|
||
**Verification standard per flow.** For each, do at least the cheap check — trace the route → service
|
||
→ endpoint → handler and confirm the chain is real. For the money flows (11–15, 18) and auth (1), do
|
||
the expensive check too: run the walkthrough against a booted app. If you cannot run it, mark the
|
||
flow's status `UNVERIFIED` in the index and say why — an honest gap beats a confident guess.
|
||
|
||
### 4. Write `index.md`
|
||
|
||
The status table, and nothing else of substance:
|
||
|
||
| Flow | Actor | Status | Client | Server | Verified | File |
|
||
| --- | --- | --- | --- | --- | --- | --- |
|
||
| booking-request | customer + nurse | built | real | real | 2026-…-… | [link] |
|
||
|
||
Statuses: `built` (end-to-end real) · `partial` (real but with gaps) · `mocked` (UI real, data fake) ·
|
||
`not started`. `Client`/`Server` columns say `real`/`mock` independently — a flow can have a real UI
|
||
on a mocked service, which is exactly the trap the hardening audit found.
|
||
|
||
---
|
||
|
||
## Verification
|
||
|
||
- [ ] `testing-setup.md` was executed, not transcribed — the agent booted the API and the client.
|
||
- [ ] Every flow file has a status backed by a code trace, or an explicit `UNVERIFIED` mark.
|
||
- [ ] The mock-vs-real map was derived from code and disagreements with `mocks-registry.md` are logged.
|
||
- [ ] No flow file restates an API shape that `docs/integration/` already owns.
|
||
- [ ] The index accounts for all 22 client service domains and all 14 business areas — anything with
|
||
no flow is either intentional or a Phase 4 backlog item.
|
||
- [ ] Every flow file carries a `Last verified:` line.
|
||
|
||
## Definition of done
|
||
|
||
You can hand someone `docs/flows/testing-setup.md` and `docs/flows/index.md` and they can test the
|
||
product without asking you a single question — and without hitting an instruction that no longer works.
|
||
|
||
## Handoff
|
||
|
||
_(filled in per slice — which flows are done, which are `UNVERIFIED` and why, and the running list of
|
||
gaps found, which is Phase 4's primary input)_
|