183 lines
11 KiB
Markdown
183 lines
11 KiB
Markdown
# Phase 5 — Roadmap & technical requirements
|
||
|
||
**Depends on:** Phase 4 · **Size:** one session
|
||
|
||
## Goal
|
||
|
||
Answer "what next?" — recording every already-decided future item **and** proposing a sequenced
|
||
order, with the technical prerequisites each step needs. The ordering is a proposal you can overrule;
|
||
the recording is not negotiable.
|
||
|
||
---
|
||
|
||
## Inputs
|
||
|
||
- `docs/status/backlog.md` and `implemented.md` — Phase 4's output, the ground truth
|
||
- `docs/flows/index.md` — what's mocked vs built
|
||
- The **deferrals with pull-triggers** from the STATUS logs: Elasticsearch `INurseSearch`, real
|
||
SMS/push `INotificationDispatcher`, the analytics pipeline, the holiday feed, **8 unbuilt product
|
||
tables**, and the refinement-phase-9 items 9.7–9.11
|
||
- [product/notes/future-ideas.md](../../product/notes/future-ideas.md) and
|
||
[open-questions.md](../../product/notes/open-questions.md) — including PWA/Workbox caching
|
||
- ui-phase-13's follow-ups: **tier (c)** — guest search + public nurse profiles (REQ-066/067), blocked
|
||
on a backend phase **and an explicit privacy sign-off on the nurse-profile field list**; the OG
|
||
image Persian variant
|
||
- Root [CLAUDE.md](../../CLAUDE.md) §6 + [DEPLOY.md](../../DEPLOY.md) "Going to Production" — the
|
||
credential-rotation obligation
|
||
- `product/business/*` — anything specified but never built
|
||
- `product/research/*` — go-to-market, legal landscape (informs sequencing, not scope)
|
||
|
||
## Outputs
|
||
|
||
```
|
||
docs/roadmap/
|
||
index.md the proposed sequence + the reasoning, in one page
|
||
next-up.md the next 3-5 units of work, each spec'd enough to start
|
||
deferred.md recorded, with the trigger that pulls each one forward
|
||
tech-debt.md what must be paid before scale, and what it costs to defer
|
||
pre-launch.md the hard gate before real users touch this
|
||
```
|
||
|
||
---
|
||
|
||
## Steps
|
||
|
||
### 1. `pre-launch.md` first — it's the one with a deadline
|
||
|
||
Everything that must be true before a real user with real money uses the platform. Known already:
|
||
|
||
- **Rotate the committed credentials** and move the secret half out of git. The repo currently
|
||
contains live credentials by deliberate pre-launch decision. Note the exception: `Seams:FieldEncryption:Key`
|
||
/ `:HashKey` decrypt existing PII and derive the phone-lookup hash — rotating those requires a data
|
||
migration, not a config edit. Spell out that migration as its own item.
|
||
- **Real external rails** — which seams are still mocked in production config (payment gateway, SMS,
|
||
BNPL provider, object storage). Phase 3's mock-vs-real map is the input; this is the list of seams
|
||
that must flip.
|
||
- **Running as Development in production** — `DEPLOY.md` documents this as a deliberate trade.
|
||
State what it implies (gRPC reflection, dev endpoints such as `/dev/last_otp`, seeding behaviour,
|
||
log verbosity) and what must change.
|
||
- Anything Phase 4 marked `blocker`.
|
||
- Legal/tax items from `product/business/13-tax-invoicing-and-legal.md` that are code-side.
|
||
|
||
Each item: what, why it blocks launch, roughly what it takes.
|
||
|
||
### 2. `deferred.md` — record faithfully, don't re-decide
|
||
|
||
One row per deferral: **item · why deferred · the pull-trigger (the condition that makes it
|
||
necessary) · rough size · where it was decided**. The pull-triggers already exist in the STATUS logs
|
||
— preserve them verbatim in substance. A deferral with a trigger is a decision; a deferral without
|
||
one is just a forgotten task, so any you find without a trigger, give one.
|
||
|
||
Include the 8 unbuilt product tables, named individually.
|
||
|
||
### 3. `tech-debt.md`
|
||
|
||
Debt is different from backlog: it doesn't block a flow, it raises the cost of everything after it.
|
||
Candidates to assess: the single-instance in-process scheduler; search without Elasticsearch; the
|
||
absence of E2E tests over the money paths; the remaining raw-state forms; the Windows-generated
|
||
client lockfile wrinkle in `DEPLOY.md`; test coverage asymmetry between the two projects.
|
||
|
||
For each: what it costs now, what it costs at 10× usage, and the trigger to pay it.
|
||
|
||
### 4. `next-up.md` — the opinionated part
|
||
|
||
Three to five units of work, each with: goal, why now, what it unblocks, technical prerequisites,
|
||
affected flows, rough size, and the backlog ids it closes. Enough that a fresh agent session could
|
||
start one without re-deriving the context.
|
||
|
||
**Sequencing principle to apply, and state explicitly in `index.md`:** the product's own promise is
|
||
trust-first and money-holding. So the order is (1) anything that makes a *money or trust* flow lie to
|
||
a user, (2) anything that makes a built flow unusable, (3) anything that makes a mocked flow real,
|
||
(4) new surface area. Tier (c) guest search is new surface — it ranks below making the authenticated
|
||
flows honest, regardless of how visible it is.
|
||
|
||
Where a proposed item conflicts with something in `product/`, say so and defer to `product/`.
|
||
|
||
### 5. `index.md`
|
||
|
||
The one-page sequence: a table of the proposed order with rationale per step, plus the standing
|
||
answer to "what are we not doing, and why" (a pointer to `deferred.md`). Mark clearly which parts are
|
||
**recorded decisions** and which are **this document's proposal** — the reader must be able to tell
|
||
your judgement from the project's.
|
||
|
||
---
|
||
|
||
## Verification
|
||
|
||
- [ ] Every `deferred` item in `docs/status/backlog.md` appears in `deferred.md` with a trigger.
|
||
- [ ] Every recorded deferral from the STATUS logs is present, including the 8 unbuilt tables.
|
||
- [ ] `pre-launch.md` covers credential rotation, every still-mocked production seam, and the
|
||
Development-in-production trade.
|
||
- [ ] Every `next-up.md` item names the backlog ids it closes and the flows it affects.
|
||
- [ ] Proposal is visibly distinguished from record.
|
||
|
||
## Definition of done
|
||
|
||
You can pick the next piece of work in five minutes, and you can explain to someone else why it's
|
||
that piece and not another.
|
||
|
||
## Handoff
|
||
|
||
**Done 2026-08-02 against `cd8144e`, in one session, single agent (no subagent fan-out needed — the inputs
|
||
were five already-triaged status files plus a handful of small product docs, not a fresh harvest).**
|
||
|
||
### What was produced
|
||
|
||
`docs/roadmap/` — `pre-launch.md`, `deferred.md`, `tech-debt.md`, `next-up.md`, `index.md`. All five
|
||
verification checklist items pass: every deferred item in `backlog.md` (51 total — the labeled 43 plus 8
|
||
more filed by severity elsewhere that also carry deferred status) appears in `deferred.md` with its trigger
|
||
preserved in substance; all 8 unbuilt product tables are named individually; `pre-launch.md` covers credential
|
||
rotation, all 11 still-mocked production rails, and the Development-in-production trade; every `next-up.md`
|
||
unit names the backlog ids it closes and the flows it affects; proposal is labeled apart from record
|
||
throughout (index.md marks each claim **recorded** or **this phase's proposal** explicitly).
|
||
|
||
### How it was verified
|
||
|
||
Read `backlog.md`, `implemented.md`, `decisions.md`, and `backlog-closed.md` in full (not sampled) since
|
||
`next-up.md`/`deferred.md`/`pre-launch.md` all need to cite exact `BL-###` ids. Cross-checked the phase
|
||
brief's tech-debt candidates against the actual code rather than restating them: **two turned out overstated.**
|
||
"Absence of E2E tests over the money paths" — false as stated; `Baya.Test.Api` and `Baya.Test.Foundation`
|
||
carry ~119 test files with real WebApplicationFactory integration coverage over Payments/Bookings/BNPL/
|
||
Payouts/Refunds. The real gap, confirmed by grepping for Playwright/Cypress in `client/package.json` (none),
|
||
is that nothing automated drives a real browser against a real API — a narrower, more precise claim than the
|
||
brief's. "Test coverage asymmetry" — also not a raw-count gap (119 server files vs 125 client files); the
|
||
actual asymmetry is that `docs/rules/server/cqrs.md` makes testing mandatory for every new feature while root
|
||
`CLAUDE.md`'s client gate is reactive ("if you touched a tested component"). Both corrected in
|
||
[tech-debt.md](../roadmap/tech-debt.md) rather than carried forward as-stated. One new debt item was found
|
||
and added that the brief didn't name: no OpenAPI→TypeScript codegen pipeline exists (confirmed absent by grep),
|
||
which is the mechanism that would have caught the client/server DTO drifts phases 2 and 3 had to discover by
|
||
hand.
|
||
|
||
One deferred item, [BL-245](../status/backlog.md#deferred-43), carried its own trigger — "phase 5 verification
|
||
pass" — naming this phase directly. Rather than deferring it again, it was executed: grepped the server for
|
||
`SuspendNurse`/`ResolveSupportAlert`/`FlagConcern`. Two of three are real and code-traced
|
||
(`ResolveSupportAlert` + `AssignSupportAlert` in `SupportAlertsController.cs`; nurse suspension as
|
||
`AdminSuspendVerificationCommand`); only `FlagConcern` is genuinely absent. Corrected in place in `backlog.md`
|
||
and logged in `decisions.md`, both outside this phase's own output folder — a deliberate, narrow exception to
|
||
"stay in your own phase's files," made because the alternative was knowingly publishing a roadmap that cites
|
||
a stale row its own source phase had flagged as needing exactly this check.
|
||
|
||
### The sequencing call worth flagging
|
||
|
||
Applying the brief's stated principle (money/trust lies > unusable > mocked→real > new surface) literally
|
||
puts admin RBAC ([BL-001](../status/backlog.md#blockers-18)/[BL-002](../status/backlog.md#blockers-18)) third
|
||
in `next-up.md`, behind two smaller truth-fixes (nurse-verification status, checkout/payment-window honesty)
|
||
— even though RBAC has zero prerequisites of its own and unblocks the most downstream work of anything in the
|
||
backlog (11 of 14 business areas). `next-up.md` and `index.md` both say this outright rather than quietly
|
||
picking one reading: the ranking follows the letter of the stated principle, and a reader who'd rather
|
||
optimize for unlock-radius should run unit 3 first. Two more mocked domains that are just as legitimate as
|
||
the four chosen (patient/care-records, partner-center) didn't fit the 3-5 slot cap and are named explicitly
|
||
as next-in-line rather than silently dropped.
|
||
|
||
### What was left undone, and why
|
||
|
||
- **Patient/care-records and partner-center de-mocks are not among the 5 `next-up.md` units** — both are
|
||
real candidates (see above), left out only by the slot cap, not by judgment that they matter less.
|
||
- **No code was written or changed** — pure roadmap synthesis, as scoped. The one exception is the BL-245
|
||
correction above, which is a fact-check, not a feature.
|
||
- **This phase did not re-audit `product/business/*` line by line for "specified but never built" beyond what
|
||
`backlog.md`'s Deferred section already carries** — a grep for `DEFERRED` across all 14 business docs
|
||
confirmed every theme they name (the 8 tables, holiday/surge pricing, GPS discovery, double-blind reviews,
|
||
tiered commission, organizations, etc.) already has a `BL-###` home. Re-deriving that reconciliation from
|
||
scratch would have been redoing phase 4's job, not phase 5's.
|