Split inspection lifecycle status from report status + report review workflow - #147
Merged
important-new merged 8 commits intoJun 15, 2026
Conversation
…migration, no FK rebuild) - report_status enum column (in_progress/submitted/published) default in_progress - status enum reduced to 5 lifecycle values (type-layer only) - migration 0007_status_split.sql: ADD COLUMN + backfill (delivered/published->completed+report published; draft->requested); purely additive to avoid D1 FK-table rebuild - status DB default left 'draft' (accepted db:check drift, same class as users.role; db:check not a deploy gate) - renumbered off image-studio's 0006_bent_gamma_corps to 0007
…ecycle consts + stats on report_status
…ions/+inspections list - app/lib/status.ts: new re-export barrel for both status axes - app/lib/hub-blocks.ts: add reportStatus to HubPayload; deriveReport/canPublish/isReportShipped all now read reportStatus; add deriveInspectionPill + deriveReportPill exports - app/routes/inspection-hub.tsx: add reportActions() pure function; add submit/return/unpublish action handlers; loader fetches canPublishCap from auth.me; fix reportShipped to use isReportPublished(reportStatus) - app/routes/dashboard.tsx: add tabMatches() + keep matchesWorkflow as compat alias; new TABS (requested + to_review); statusTone/REPORT_STATE_TONE updated for new axes; status dropdown uses new statuses - app/routes/inspections.tsx: new dedicated /inspections list route grouped by lifecycle status - app/routes.ts: wire /inspections to inspections.tsx - server/services/inspection.service.ts: getInspectionHub now returns reportStatus - tests: 4 new spec files + 2 updated for status split semantics Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- eslint.config.js: add status-literal guard banning 'requested' and
'submitted' (the two unambiguous new-model values); exempted via the
existing override blocks covering server/lib/**, server/api/**,
server/services/**, app/** — fires only on new code outside those zones.
Collision-prone values ('draft', 'published', 'in_progress', etc.) are
intentionally excluded with inline rationale.
- Fix pre-existing lint errors in app/routes:
- inspection-hub.tsx: remove unused publishReady + canPublish import
- inspections.tsx: drop unused isReportPublished import; let → const
- Test fixtures (42 files): update all inspection-row seeds from removed
status values to the two-axis model:
'draft' → 'requested'
'published' → status:'completed', reportStatus:'published'
'delivered' → status:'completed', reportStatus:'published'
'in_progress' → status:'completed', reportStatus:'in_progress'
Invoice/outbox/filter-tab 'draft'/'published' left intact.
- tests/workers/db-batch-atomicity.spec.ts: add report_status column to
inline inspections DDL; update 'draft' seed to 'requested'.
Gate: type-check (app+api) GREEN, lint 0 errors, test:unit 1714/1722
pass, test:web 380/380 pass, test:workers 41/41 pass.
db:check drift: only accepted (inspections.status dflt draft vs requested,
users.role dflt admin vs manager, apprentice_reviews/guest_invites lost).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Splits the conflated
inspections.statusenum (8 values) into two independent axes, mirroring industry practice (Spectora):status:requested | scheduled | confirmed | completed | cancelledreport_status(NEW):in_progress | submitted | publishedPlus a report review workflow (Submit → Publish / Return / Unpublish) gated by the existing
publishcapability, and status values driven from a single source of truth (no hardcoded literals).Why
Publishing previously set
status='delivered', overwriting the lifecycle state (data loss).'published'/'signed'were enum values never written (tech debt), andstatus==='delivered'||'published'was hardcoded across ~6+ sites. The report deliverable now has its own lifecycle independent of the inspection event.Changes
server/lib/status/inspection-status.ts+report-status.ts(const tuple + type + named consts + labels + guards), mirroringroles.ts. App re-exports viaapp/lib/status.ts. ESLint guard against bare status literals.report_statuscolumn;statusenum reduced to lifecycle. Migration0007_status_split.sqlis purely additive (ADD COLUMN + backfill) to avoid a D1 FK-table rebuild;statusDB default intentionally left (accepteddb:checkdrift, same class asusers.role).publishInspectionsetsreport_status='published'(no longer overwritesstatus); newsubmitReport/returnReport/unpublishReportwith precondition guards; stats/buckets/icons key onreport_status.POST /:id/submit(any authed user),/return+/unpublish(requirepublishcapability); publish endpoint already gated.canPublish/isReportShipped; inspection-hub Submit/Publish/Return/Unpublish actions; dashboard tabs split by axis (+to_reviewqueue); new/inspectionslist grouped by lifecycle status.Behavior notes
delivered/published→status=completed+report_status=published;draft→requested;in_progress→completed+report_status=in_progress.Testing
report_statusdrift)