fix(legacy-stage): purge 9-stage enum keys from rank tables and stale copy
Some checks failed
Build & Push Docker Images / lint (push) Successful in 2m4s
Build & Push Docker Images / build-and-push (push) Has been cancelled

L-001 hunt landed these:

  - src/lib/services/clients.service.ts — stageRank used pre-refactor
    9-stage names exclusively (`contract_signed`, `deposit_10pct`, …).
    Every modern 7-stage interest fell to rank 0, making client-list
    "most-progressed deal" sort effectively random. Modern values now
    own the canonical ranks; legacy aliases map to their 7-stage
    equivalents so historical audit data still sorts.

  - src/lib/services/berth-recommender.service.ts — STAGE_ORDER had
    the same 9-stage shape. LATE_STAGE_THRESHOLD pointed at the (now
    nonexistent) `deposit_10pct` slot. Reworked to the 7-stage scale;
    threshold now at `deposit_paid` (5).

  - Stale comments referencing `deposit_10pct` in schema (clients,
    financial) and client-archive services updated to current copy.

  - Smart-archive dialog rendered `i.pipelineStage` as raw enum; now
    routes through `stageLabelFor` (the new helper added with A2).

Test fixture updates: berth-recommender.test.ts numeric inputs
re-mapped to the new 7-stage scale (eoi_signed=5 → eoi=3, etc.).
1373/1373 vitest pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-15 01:18:13 +02:00
parent 0d9208a052
commit 98211066a5
10 changed files with 65 additions and 31 deletions

View File

@@ -40,7 +40,7 @@ export const clients = pgTable(
/** Better-auth user id of the operator who archived this client. */
archivedBy: text('archived_by'),
/** Free-text reason captured at archive time. Required when archiving a
* client at deposit_10pct or later (compliance trail). Optional when
* client at deposit_paid or later (compliance trail). Optional when
* archiving an early-stage lead. */
archiveReason: text('archive_reason'),
/** Per-decision metadata captured during smart-archive flow. Used by

View File

@@ -120,7 +120,7 @@ export const invoices = pgTable(
pdfFileId: text('pdf_file_id').references(() => files.id),
/** Optional link to a sales interest. When the invoice is paid and `kind`
* is 'deposit', recordPayment auto-advances the interest's pipelineStage
* to deposit_10pct (no-op if already further along). */
* to deposit_paid (no-op if already further along). */
interestId: text('interest_id').references(() => interests.id, { onDelete: 'set null' }),
/** Invoice kind. 'general' (default) is everyday billing; 'deposit' marks
* the 10% berth-purchase deposit and is what triggers the stage advance. */

View File

@@ -18,10 +18,10 @@ export type RolePermissions = {
edit: boolean;
delete: boolean;
change_stage: boolean;
/** Bypass the canTransitionStage table (e.g. mark a contract_signed
* deal as completed without going through deposit_10pct first when
* the data was entered out of order). Audit-logged with the reason
* the rep gives. Sales-team-restricted. */
/** Bypass the canTransitionStage table (e.g. jump a deal straight to
* Contract without going through Deposit Paid first when the data
* was entered out of order). Audit-logged with the reason the rep
* gives. Sales-team-restricted. */
override_stage: boolean;
generate_eoi: boolean;
export: boolean;