Review findings on the quote-to-close slice, each verified against the code:
- convertDocument: ANY conversion now flips the source to 'invoiced' (previously
only ->INVOICE), so a QT->PI quote leaves the daily scan's 'sent' set and the
pipeline's Quoted/Waiting — the chase never resumes after convert (spec 7 stop
conditions). Scan additionally excludes quotes with a live forward child
(covers rows converted before this fix) and quotes of lost clients.
- convertDocument rule-4 guard (spec 8 F4): a live non-cancelled forward child
blocks re-convert — one sale, one legal document; cancelling the child
re-opens the path. Rule-2 fix (spec 8 F3): ->INVOICE recomputes the carried
lines through computeBill on the invoice's own doc_date (mirrors
createCreditNote); QT->PI stays copy-only (both non-legal).
- cancelDocument dismisses a cancelled quotation's open follow-up nudges in the
same transaction, per-row audited — dead paper is not chased.
- GET /reminders?status= no longer bypasses the owner scope and pagination: the
status param narrows the same scoped listQueue view. Web badge (Layout) now
uses the honest scoped total instead of an unscoped flat list length.
- listQueue/queueCounts staff scope keeps doc-less reminders (renewal_due,
amc_expiring, follow_up, email_bounced) visible — they have no derived owner
and are shared work; previously they vanished for every staff viewer.
- sendReminder resolves the recipient BEFORE minting a public share (a send
that can never succeed leaves no live artifact) and refuses quote_followup
sends loudly when share.base_url is unset instead of emailing a dead relative
link. The scheduler auto-drain parks a hard-failing send as 'failed' with its
reason instead of crashing the scan.
- reminderContext takes an injectable today (threaded from deps.now in the send
path) so dated schedule text resolves deterministically.
- Pipeline: quote-less lost clients (client.status=lost) now appear under
filter=lost (spec 9); Dashboard queue table marks first-page truncation
honestly (rule 8).
Typecheck clean; 270 tests green (255 before, +15 covering each fix).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Phase 2 of the quote-to-close funnel slice. Six /employees routes in
apps/hq/src/api.ts (GET requireAuth for the picker; POST/PATCH/deactivate/
reactivate/password owner-only, acting as the signed-in user); Employees
page (table + add/edit/reset-password forms, email immutable on edit,
count shown, no truncation); owner-only nav item beside Document Template;
typed client fns in hq-web api.ts. 6 new route tests (192 total).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>