Commit Graph

2 Commits (b5d252b7dcfcefa321588e33b49de6971692a66b)

Author SHA1 Message Date
Thomas Joise 747026fa3b feat(modules): roster full-edit + assign/unassign; one-click Convert & send on the documents register (Phase 8, D18 WS-G)
- listClientsByModule rows carry cmId; ClientModulePatch gains kind/edition
  (kind validated against module.allowedKinds — same audited write path as
  Client 360, so the two views can never disagree)
- Modules roster: inline edit (kind/edition/renewal/status), ✕ unassign with
  confirm (deactivates the link, totals shrink), Assign client… type-ahead
- Documents register: issued proformas get a Convert & send quick action
  (same convert-and-send endpoint + confirm as the document view)
- 2 tests; suite 333 green

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
5 days ago
Thomas Joise 953cf1dff8 feat(modules): module→client roster, notify-all, CSV export (Phase 10, spec §10)
- listClientsByModule: reverse lookup over active links, ordered by client name,
  paginated with a true total; per-row dated price via priceOn + next renewal;
  footer revenue total spans ALL links (active=0 excluded by design, stated)
- GET /modules/:id/clients (paginated) + /clients.csv (streams every row, no cap)
- POST /modules/:id/notify (owner/manager): resolves the full roster first, sends
  via the Gmail path, one email_log + one audit row per attempted recipient,
  names every unreachable client in the response (warn, never truncate)
- Modules page roster panel: table + revenue footer + Notify-all composer + CSV
- 8 tests; suite green

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
5 days ago