Skip to content

Split inspection lifecycle status from report status + report review workflow - #147

Merged
important-new merged 8 commits into
InspectorHub:mainfrom
important-new:feat/inspection-report-status-split
Jun 15, 2026
Merged

Split inspection lifecycle status from report status + report review workflow#147
important-new merged 8 commits into
InspectorHub:mainfrom
important-new:feat/inspection-report-status-split

Conversation

@important-new

Copy link
Copy Markdown
Contributor

Summary

Splits the conflated inspections.status enum (8 values) into two independent axes, mirroring industry practice (Spectora):

  • Inspection lifecycle status: requested | scheduled | confirmed | completed | cancelled
  • Report (deliverable) report_status (NEW): in_progress | submitted | published

Plus a report review workflow (Submit → Publish / Return / Unpublish) gated by the existing publish capability, 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), and status==='delivered'||'published' was hardcoded across ~6+ sites. The report deliverable now has its own lifecycle independent of the inspection event.

Changes

  • Single source of truth: server/lib/status/inspection-status.ts + report-status.ts (const tuple + type + named consts + labels + guards), mirroring roles.ts. App re-exports via app/lib/status.ts. ESLint guard against bare status literals.
  • Schema/migration: new report_status column; status enum reduced to lifecycle. Migration 0007_status_split.sql is purely additive (ADD COLUMN + backfill) to avoid a D1 FK-table rebuild; status DB default intentionally left (accepted db:check drift, same class as users.role).
  • Service: publishInspection sets report_status='published' (no longer overwrites status); new submitReport/returnReport/unpublishReport with precondition guards; stats/buckets/icons key on report_status.
  • API: POST /:id/submit (any authed user), /return + /unpublish (require publish capability); publish endpoint already gated.
  • Frontend: hub-blocks pills + canPublish/isReportShipped; inspection-hub Submit/Publish/Return/Unpublish actions; dashboard tabs split by axis (+ to_review queue); new /inspections list grouped by lifecycle status.

Behavior notes

  • Editing a published report does NOT change its status (living document; Spectora-aligned). Re-publish creates a new version; Unpublish is explicit.
  • Migration backfill: delivered/publishedstatus=completed + report_status=published; draftrequested; in_progresscompleted + report_status=in_progress.

Testing

  • type-check (app+api): green
  • lint: 0 errors
  • unit: 1714 pass · web: 380 pass · workers: 41 pass
  • db:check: only the accepted pre-existing drift (no report_status drift)

important-new and others added 8 commits June 15, 2026 08:32
…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
…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>
@important-new
important-new merged commit 288da4a into InspectorHub:main Jun 15, 2026
4 checks passed
@important-new
important-new deleted the feat/inspection-report-status-split branch June 15, 2026 03:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant