Wires the X-SES-CONFIGURATION-SET header on outbound auth emails so SES
bounce/delivery events flow through dev-ses-config to the dev-ses-events
SNS topic. Replaces the fire-and-forget "EMAIL MAGIC LINK SENT" log
(which fired before the SMTP transaction and swallowed downstream errors)
with structured EMAIL_MAGIC_LINK_SUCCESS/_FAILURE logs carrying the
Nodemailer messageId, so app-side sends are now correlatable with SES
events.
Motivated by the Atkins / Sustainable Building UK silent-quarantine
incidents where we couldn't tell whether SES had even tried to send.
Plan doc at docs/wip/auth-email-code-fallback-plan.md tracks the
broader email-code-fallback design that PR 2 will implement.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Created removalState.ts with two functions: deriveEffectiveRemovalState (single DB row → EffectiveRemovalState) and computeRemovalStatusByDeal (ordered rows → RemovalStatusByDeal map, owns deduplication).
Created removalState.test.ts with 11 tests covering all 6 (type, status) combinations and the map-building edge cases (empty input, deduplication, none entries excluded).
live/page.tsx: replaced a 14-line seen-set loop with a single computeRemovalStatusByDeal(removalRows) call.
live/[dealId]/page.tsx: replaced an if/else block with deriveEffectiveRemovalState(removalRows[0]).
Delete WorkPhaseStats type and its four computation blocks (coordination,
design, install, lodgement) from transforms.ts and types.ts — the computed
values were never read by any component.
Extract mapDbRowToHubspotDeal, DealRow, and the coordinator/designer aliases
into a new dealQuery.ts module, eliminating the verbatim duplication between
the live tracker page and the deal detail page.
Replace the inline doc status computation in [dealId]/page.tsx with calls
to the existing fetchDocsByDealId and computeDocStatusMap from docStatus.ts,
so both paths now share a single implementation.
server component into a dedicated docStatus.ts module. computeDocStatusMap
is now a pure function with full test coverage (8 tests). Also consolidates
the double user table lookup in page.tsx into a single query.