Workbench pipeline fix — cert-queue API was missing project_status field, causing PipelineIndicator to default to “Intake”
Added project_status to cert-queue response via PROJECT_STATUS_MAP
Cert/invoice status normalization — cert-queue returned lowercase snake_case but UI expected Title Case
Added normalizeItem() in Workbench.tsx
Supabase string resolution in resolve functions — resolve_cert_state() and resolve_inv_state() only handled SmartSuite value IDs, not Supabase resolved strings
Added _SUPA_CERT_TO_PORTAL and _SUPA_INV_TO_PORTAL fallback maps
Both-sent filter — excluded projects where both cert AND invoice are sent from cert-queue (removed 196 dead-letter items)
Reparse SOW line fix — list_products() returns a list but code called .items() expecting a dict
SOW display fix — Supabase fallback was regex-matching project ID instead of product code
SOW backfill script — backfill_sow_lines.py: finds post-cutover projects with permit/plan PDFs but no SOW lines, runs Claude Vision parsing