diff --git a/docs/superpowers/specs/2026-07-17-golive-cluster-design.md b/docs/superpowers/specs/2026-07-17-golive-cluster-design.md index df1ab74..3f84041 100644 --- a/docs/superpowers/specs/2026-07-17-golive-cluster-design.md +++ b/docs/superpowers/specs/2026-07-17-golive-cluster-design.md @@ -17,6 +17,8 @@ Six workstreams that take the console from "feature-complete" to "safe to go liv | **D** | **Documents list page** + honest pagination on `GET /documents` | Documents are only reachable via client ledger/pipeline today; the endpoint returns ALL rows (rule-8 violation at scale) | | **E** | **Shell & profile**: collapsible sidebar, self-service profile (name + own password), "My Day" dashboard mode, minimal employee extras (phone/title) | Self password change doesn't exist; the old app's most-used surface was the per-person workbench | | **F** | **Client support data** from APEX: AnyDesk/OS/DB-password (encrypted), district + sector, WhatsApp + secretary contacts | AnyDesk was referenced 44× in the old app — support opens it daily; district/sector are the team's main list filters | +| **G** | **Editable module→clients roster** + one-click *Convert & send* from list views | Founder call: both directions (client→modules, module→clients) must be editable, and proforma→invoice must be one click from anywhere | +| **H** | **Section-per-module quotation PDF** | Founder call: a quote spanning all 5 modules prints each module as its own titled section (name, inclusions, price) with clean page breaks, totals + terms on the last page | Hard rules apply throughout (paise, one billing engine, dated config, immutable documents, portable repos, audited mutations in-txn, no silent caps, strict TS + green suite). @@ -31,6 +33,13 @@ portable repos, audited mutations in-txn, no silent caps, strict TS + green suit refresh token (`crypto.ts`). No `HQ_SECRET_KEY` ⇒ the field refuses to save, loudly. - **A4** Import UI accepts the same two CSVs the CLI does; parsing/verification/commit logic is **reused, not reimplemented** (`import-apex.ts` functions get routes, not a rewrite). +- **A5** Roster editing (WS-G) reuses the SAME audited repo calls Client 360 uses + (`updateClientModule`, `assignModule`) with the same gating — no second write path, so + the two views can never disagree. +- **A6** The sectioned layout (WS-H) applies to **QUOTATION** documents only; invoices and + proformas keep the compact billing table (they are payment paper, not proposals). It is + rendered inside the ONE shared `documentHtml` renderer, so the preview-fidelity guarantee + (screen HTML ≡ PDF HTML, byte-identical) is preserved by the existing golden test. - **Non-goals:** Postgres switch (next task); support ticket desk; WhatsApp *sending*; HR fields (DOB/joining/leave/payroll — permanently out per D16); bulk actions; kanban board. @@ -82,6 +91,18 @@ portable repos, audited mutations in-txn, no silent caps, strict TS + green suit WhatsApp/secretary typed rows. - **Composer**: Due date field on INVOICE drafts, auto-filled from terms, editable. - **Invoice PDF**: prints "Due date: " when present. +- **Module roster — full edit (WS-G)**: each row gains inline controls for kind, edition, + next renewal and lifecycle status (saving through `updateClientModule`, audited); an ✕ + unassigns (sets the link inactive); an **Assign client…** type-ahead (existing client + search) adds a client to the module via `assignModule`. Same gating as Client 360. +- **One-click convert everywhere (WS-G)**: issued proformas show a **Convert & send** + quick action on the Documents page rows and Pipeline rows — the same + `POST /documents/:id/convert-and-send` behind the same confirm dialog. +- **Quotation PDF — section per module (WS-H)**: page 1 = letterhead + client + a one-line + summary of the modules quoted; then one titled section per line — module name (+ pack/ + edition), its "what's included" block, its line price — with `page-break-inside: avoid` + and a break before each section so no module splits mid-section; final page = totals, + GST split, terms, jurisdiction, signature. Modules without content print a tight section. ## 6. Due-date mechanics (WS-A detail) @@ -109,6 +130,8 @@ portable repos, audited mutations in-txn, no silent caps, strict TS + green suit 5. **Sidebar collapse + My Day** — shell toggle + dashboard mine/everyone. *(Accept: collapse persists; staff default to mine.)* 6. **Client support fields** — columns + encrypted password + reveal + Client 360 card + district/sector filters + contact types. *(Accept: reveal audited; password absent from all list payloads; saving without HQ_SECRET_KEY fails loudly.)* 7. **Import UI** — routes over existing importer + `/import` screen. *(Accept: commit refuses with problems; re-stage idempotent; series seeding preserved.)* -8. **Docs refresh** — STATUS/README/CLAUDE/D-number record. +8. **Editable roster + quick convert** — inline edit/assign/unassign on the module roster; Convert & send on Documents + Pipeline rows. *(Accept: roster edits round-trip through the same audited repo fns as Client 360; unassign hides the row and shrinks totals; quick convert = exactly one invoice + one email.)* +9. **Sectioned quotation PDF** — section-per-module layout in `documentHtml` for QUOTATION. *(Accept: 5-module quote renders 5 titled sections + totals page; no section splits across pages; preview-fidelity golden test still passes; INVOICE/PI layout unchanged.)* +10. **Docs refresh** — STATUS/README/CLAUDE/D-number record. -**Total: 8 phases.** After this slice: the **Postgres switch**, then the real cutover. +**Total: 10 phases.** After this slice: the **Postgres switch**, then the real cutover.