docs(phase-9): tighten picker description, swap owner labels

Spec changes from feedback:

1. §5.1 — the picker description was written as if the user could
   see the rendered HTML. Replaced with an ASCII sketch and a
   stronger 'no internal concepts reach the rendered surface' line.

2. §7 — added a binding label-mapping table for every owner-facing
   term. The internal names stay (in the DB, in code, in the spec);
   only rendered text changes. Soft-language variants:
     intake_links     -> 'Request link'
     Mint a link      -> 'New request link'
     Per-link daily cap -> 'Daily cap'
     Revoke           -> 'Pause'
     Re-activate      -> 'Resume'
     show_in_intake   -> 'List on request page'
This commit is contained in:
Dave 2026-09-21 12:58:56 +02:00
parent 917736ebb0
commit c2bbe3319f

View file

@ -237,7 +237,25 @@ as Phase 8 — it does not care whether the row carries `project` or
`client`). On unknown/revoked/expired, **404 with the same wording as
the wizard** so a hostile body cannot probe.
On success, renders a project picker:
On success, renders a project picker. The user's experience is
intentionally minimal — they see plain project names, click one, and
the wizard starts. No mention of phases, tokens, or any other internal
concept ever reaches the rendered HTML. A rough sketch:
```
┌─────────────────────────────────────────────┐
│ Acme — let's talk │
│ │
│ Tell us which project you have a question │
│ about: │
│ │
│ ▸ Acme Site Redesign │
│ ▸ Acme POS │
│ ▸ Acme Rebrand │
└─────────────────────────────────────────────┘
```
Mechanics:
- Reads every project on the link's client with
`active = true AND show_in_intake = true`.
@ -325,24 +343,38 @@ with both tokens and project ids on the wire.
## 7. Owner UI
The owner-facing surface uses natural-language labels. Internal names
(`intake_links`, `show_in_intake`) live in the database, in the code,
and in this spec — never in the rendered HTML. The mapping below is
binding for every button, header, and tooltip in Phase 9.
| Internal code name | Owner-facing label |
|---|---|
| `intake_links` row | **Request link** |
| "Mint a link" button | **New request link** |
| "Per-link daily cap" | **Daily cap** |
| "Revoke" | **Pause** |
| "Re-activate" | **Resume** |
| `projects.show_in_intake` toggle | **List on request page** |
| "Per-project intake count" | "Submissions today" |
### 7.1 Client admin page (new)
`/admin/clients/[clientId]` currently exists? (No — Phase 8 only added
links at the project level.) Phase 9 adds:
`/admin/clients/[clientId]` did not exist before Phase 9 — Phase 8 only
added request links at the project level. Phase 9 adds:
- A new route `/admin/clients/[clientId]` (server component,
owner-only via the existing admin layout).
- Reads the client plus the active projects on it (the owner's view of
what's deployable for intake purposes).
- Renders three panels stacked:
1. **Public intake links** — the same `<IntakeLinksPanel>` from
1. **Request links** — the same `<IntakeLinksPanel>` shape from
Phase 8, but now `link.project` is always empty on new rows.
Mint / rotate / revoke / per-link daily cap.
New request link / rotate / pause / resume / daily cap.
2. **Projects** — a list of the client's projects with a small
`<ShowInIntakeToggle>` next to each (one toggle calls one new
Server Action per project). Disabled + active styled. Toggling
`show_in_intake` is two clicks, not three.
3. *(Future)* a "client URL" badge — a copyable URL of the form
`<ShowInIntakeToggle>` (rendered as "List on request page") next
to each. One toggle calls one new Server Action per project.
3. *(Future)* a "Client URL" badge — a copyable URL of the form
`https://<host>/intake/<token>` — landed on the page when at
least one active link and at least one opted-in project exist.
@ -355,10 +387,11 @@ needed here.
- A new `<ShowInIntakeToggle projectId={...} current={...} />` rendered
in the existing admin page, just above the
`<BackgroundMdEditor>`. It calls a new Server Action
`<BackgroundMdEditor>`. The toggle is labelled "List on request page"
in the rendered UI. It calls a new Server Action
`setProjectShowInIntakeAction({ projectId, show })`. Owner-only.
The Public-intake-links section on the project page stays (Phase 8
The "Request links" section on the project page stays (Phase 8
shape: a per-project link can still be minted). It just becomes the
"legacy / experimental" path; the new client-level link is the
default.