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>
Plan §4.4 + §13: pure SQL recommender, no AI. Single CTE chain
(feasible -> aggregates) + JS-side tier classification, fall-through
cooldown filter, heat scoring, and fit ranking. Per-port settings via
system_settings layered over global + DEFAULT_RECOMMENDER_SETTINGS.
Tier ladder (default):
A : no interest history
B : lost-only history (still recommendable + boosted by heat)
C : active interest in early stage (open..eoi_signed)
D : active interest at deposit_10pct or beyond (hidden by default)
Heat (only for tier B):
recency weight 30 full @ <=30 days, decays to 0 @ 365 days
furthest stage weight 40 full when prior reached deposit
interest count weight 15 saturates at 5+
EOI count weight 15 saturates at 3+
Multi-port isolation enforced (§14.10 critical): the SQL filters by
port_id AND the entry-point function rejects cross-port interest
lookups with an explicit error. Fall-through policy supports
immediate_with_heat (default), cooldown, and never_auto_recommend.
15 unit tests covering tier classification, heat saturation, weight
tuning, zero-weight guard. Smoke-tested end-to-end via
scripts/dev-recommender-smoke.ts.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>