Record ADR-0023: Installation in Progress gated on Retrofit Design Document 🟪

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Daniel Roth 2026-07-24 13:54:27 +00:00
parent 80cf21922e
commit 1db2e7c92c

View file

@ -0,0 +1,96 @@
# 23. Installation in Progress is gated on the Retrofit Design Document, not the HubSpot designStatus flag
Date: 2026-07-24
## Status
Accepted
## Context
On the Live projects screen (`your-projects/live`), a Property's delivery stage
is derived from HubSpot deal fields by the stage classifier
(`resolveDisplayStage``classifyDeals``computeLiveTrackerData` in
`transforms.ts`). After coordination is complete, the classifier decided
*Design in Progress* vs *Installation in Progress* from the self-reported
`designStatus` text field: `designStatus === "UPLOADED"` meant "design is done,
installation can happen".
That flag is set in the CRM independently of the actual design work. Observed
values include `"UPLOADED"`, `"uploaded"` and `"IN PROGRESS"`, and it is
routinely set before — or without — the **Retrofit Design Document**
(`retrofit_design_doc`) ever being uploaded. The CRM flag and the document store
are two independent sources of truth that had silently diverged, so large
numbers of Properties with no design in place showed as *Installation in
Progress*. Managers could not trust the pipeline counts, the funnel, or the
stage badges, and Properties genuinely waiting on design were hidden inside a
later stage.
The domain owner confirmed there is only ever one design document per Property —
the Retrofit Design Document — and its presence is the correct trigger for
*Installation in Progress*.
## Decision
**Design-document presence, not the `designStatus` flag, drives the
Design-vs-Installation boundary.**
- The classifier stops reading `designStatus`. `designStatus` remains on the
deal record and may still be displayed (and still feeds the separate design
throughput trends chart), but it no longer influences the stage.
- Whether a `retrofit_design_doc` exists for a deal is passed **into** the pure
classifier as an explicit input — `resolveDisplayStage(deal, hasDesignDoc)`,
`classifyDeals(deals, designDocDealIds)`,
`computeLiveTrackerData(deals, designDocDealIds)`. The classification
functions perform no I/O; presence is derived by
`deriveDesignDocDealIds(docsByDealId)` from the documents already fetched
(direct deal-id match and UPRN fallback), using `DESIGN_DOC_TYPES` as the
definition of a design document. `page.tsx` and `[dealId]/page.tsx` now fetch
documents ahead of classification so the same fetch feeds both the presence
set and the document-status map.
- **After coordination, downstream evidence wins; document presence only
decides the Design/Installation boundary.** For a coordination-complete deal
(a `(V1|V2|V3) IOE/MTP COMPLETE` marker, not an RA issue) the stage resolves
in this priority:
```
full lodgement date present → Project Complete
measures lodgement date present → At Post Survey
lodgement status present → At Lodgement
measures installed OR installer handover→ Installation Complete
Retrofit Design Document present → Installation in Progress
otherwise → Design in Progress
```
Gating the whole post-coordination block on document presence would drag a
genuinely installed or lodged Property back to *Design in Progress* when its
design document is merely missing from the store. Document presence is the
weakest signal in the ladder, not a gate on the rest.
- The document-status map's install bucket is corrected: a `retrofit_design_doc`
is no longer mis-bucketed as an install document, so a Property holding only a
design document is not reported as having install documents.
Coordination and earlier stages are untouched — the RA-issue → Queries path,
the removed-Property short-circuits, the dealstage-id → raw-stage mapping and
the Coordination in Progress path all behave exactly as before.
## Consequences
- A Property shows *Installation in Progress* only once its Retrofit Design
Document exists; one whose coordination is complete but whose document is
missing stays at *Design in Progress*, where the outstanding design work is
visible. Funnel and stage-progress counts (and the "All Projects" roll-up)
follow the corrected per-deal classification, as does the Properties-tab stage
filter.
- A prematurely-set or stale `designStatus` flag can no longer push a Property
into *Installation in Progress*.
- `DESIGN_DOC_TYPES` (previously defined but unused) becomes load-bearing as the
single definition of what counts as a design document.
- Out of scope, deliberately: correcting the underlying `designStatus` data or
alerting on CRM-vs-document mismatch; surfacing a design-completeness badge on
the Documents tab; multi-document or per-measure design requirements (there is
only ever one design document per Property). The Live projects feature itself
remains superseded-in-principle by Ara Projects per ADR-0018; this fix keeps
it correct in the meantime.