docs(03-04): complete Job Orders plan
Tasks completed: 2/2 - Task 1: JobOrder schema, migration, and tenant scoping - Task 2: Job order service, API routes, and integration tests SUMMARY: .planning/phases/03-operational-modules/03-04-SUMMARY.md
This commit is contained in:
142
.planning/phases/03-operational-modules/03-04-SUMMARY.md
Normal file
142
.planning/phases/03-operational-modules/03-04-SUMMARY.md
Normal file
@@ -0,0 +1,142 @@
|
||||
---
|
||||
phase: 03-operational-modules
|
||||
plan: "04"
|
||||
subsystem: api
|
||||
tags: [prisma, postgresql, job-orders, tickets, technician, lifecycle, tenant-isolation]
|
||||
|
||||
# Dependency graph
|
||||
requires:
|
||||
- phase: 03-03
|
||||
provides: Ticket model with lifecycle (OPEN/ASSIGNED/RESOLVED/CLOSED), resolveTicket, transitionTicketStatus
|
||||
provides:
|
||||
- JobOrder model with 1:many ticket relation and PENDING/IN_PROGRESS/COMPLETED/CANCELLED lifecycle
|
||||
- createJobOrder with OPEN->ASSIGNED auto-transition
|
||||
- updateJobOrderStatus with guard map + ticket sync (auto-resolve, revert-to-open)
|
||||
- Ticket auto-resolve when all non-cancelled job orders COMPLETED
|
||||
- Ticket revert-to-OPEN when all job orders CANCELLED
|
||||
- Technician self-service status updates (getMyJobOrders)
|
||||
- 4 API routes: POST /api/tickets/[id]/job-orders, GET+PUT /api/job-orders/[id], POST /api/job-orders/[id]/status, GET /api/job-orders
|
||||
- 17 integration tests: lifecycle, bidirectional sync, partial completion, isolation
|
||||
affects:
|
||||
- 03-05 (if any final operational module uses job orders)
|
||||
- Phase 4 (inventory may link to job orders)
|
||||
- Phase 5 (reporting may aggregate job order metrics)
|
||||
|
||||
# Tech tracking
|
||||
tech-stack:
|
||||
added: []
|
||||
patterns:
|
||||
- "VALID_JO_TRANSITIONS guard map: same pattern as VALID_TICKET_TRANSITIONS from 03-03"
|
||||
- "Bidirectional sync: job order service calls checkTicketAutoResolve/checkTicketRevertToOpen from ticket-service"
|
||||
- "TECHNICIAN self-service: getMyJobOrders delegates to listJobOrders with assignedToId filter"
|
||||
- "Idempotent ticket resolve: resolveTicket silently no-ops on already-RESOLVED tickets (prevents race conditions)"
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- prisma/migrations/20260304235859_add_job_orders/migration.sql
|
||||
- src/lib/services/job-order-service.ts
|
||||
- src/app/api/tickets/[id]/job-orders/route.ts
|
||||
- src/app/api/job-orders/route.ts
|
||||
- src/app/api/job-orders/[id]/route.ts
|
||||
- src/app/api/job-orders/[id]/status/route.ts
|
||||
- src/lib/__tests__/job-order-service.test.ts
|
||||
modified:
|
||||
- prisma/schema.prisma
|
||||
- src/lib/prisma-tenant.ts
|
||||
- src/lib/services/ticket-service.ts
|
||||
|
||||
key-decisions:
|
||||
- "checkTicketAutoResolve counts non-cancelled jobs: if count > 0 AND all COMPLETED -> resolve; if count == 0 (all cancelled) -> do nothing (checkTicketRevertToOpen handles that path)"
|
||||
- "checkTicketRevertToOpen only triggers on ASSIGNED tickets: RESOLVED/CLOSED tickets are not reverted even if all jobs are cancelled"
|
||||
- "COMPLETED requires outcomeNotes: validated in service, not API layer — ensures completeness regardless of caller"
|
||||
- "JO-NNNN sequential numbering: findFirst with orderBy desc on orderNumber field, same pattern as TKT-NNNN"
|
||||
- "TECHNICIAN role auto-filter in GET /api/job-orders: checks !ADMIN && !OFFICE_STAFF to allow staff with both TECHNICIAN and OFFICE_STAFF roles full visibility"
|
||||
- "Inline tech2 cleanup in getMyJobOrders test: must delete job orders before deleting user (FK constraint on assignedToId)"
|
||||
|
||||
patterns-established:
|
||||
- "Job order lifecycle guard map: VALID_JO_TRANSITIONS mirrors VALID_TICKET_TRANSITIONS pattern"
|
||||
- "Ticket sync after status change: always call checkTicketAutoResolve (COMPLETED) or checkTicketRevertToOpen (CANCELLED) at end of updateJobOrderStatus"
|
||||
- "Outcome notes validation at service layer: error thrown in service, not in API handler"
|
||||
|
||||
# Metrics
|
||||
duration: 6min
|
||||
completed: 2026-03-05
|
||||
---
|
||||
|
||||
# Phase 3 Plan 04: Job Orders Summary
|
||||
|
||||
**JobOrder model (JO-NNNN) with PENDING/IN_PROGRESS/COMPLETED/CANCELLED lifecycle, bidirectional ticket sync (auto-resolve on all complete, revert-to-OPEN on all cancelled), and 17 passing integration tests**
|
||||
|
||||
## Performance
|
||||
|
||||
- **Duration:** 6 min
|
||||
- **Started:** 2026-03-04T23:58:04Z
|
||||
- **Completed:** 2026-03-05T00:04:26Z
|
||||
- **Tasks:** 2
|
||||
- **Files modified:** 10
|
||||
|
||||
## Accomplishments
|
||||
- JobOrder model with 1:many ticket relation, sequential JO-NNNN numbering, tenant scoping via full 12-operation extension block
|
||||
- Job order lifecycle enforced by VALID_JO_TRANSITIONS guard map: PENDING->IN_PROGRESS->COMPLETED(requires outcomeNotes)/CANCELLED
|
||||
- Bidirectional ticket sync: OPEN->ASSIGNED on first job creation; auto-resolve when all non-cancelled jobs complete; revert-to-OPEN when all jobs cancelled
|
||||
- 17 integration tests covering full lifecycle, auto-resolve, revert-to-open, partial completion, technician self-service, cross-tenant isolation — all green
|
||||
|
||||
## Task Commits
|
||||
|
||||
Each task was committed atomically:
|
||||
|
||||
1. **Task 1: JobOrder schema, migration, and tenant scoping** - `d59f1d5` (feat)
|
||||
2. **Task 2: Job order service, ticket sync, API routes, and integration tests** - `86284f1` (feat)
|
||||
|
||||
**Plan metadata:** (docs commit below)
|
||||
|
||||
## Files Created/Modified
|
||||
- `prisma/schema.prisma` - Added JobOrderStatus enum, JobOrder model, reverse relations on Ticket and User
|
||||
- `prisma/migrations/20260304235859_add_job_orders/migration.sql` - Migration adding job_orders table with all indexes
|
||||
- `src/lib/prisma-tenant.ts` - Added "jobOrder" to TENANT_SCOPED_MODELS with full 12-operation extension block
|
||||
- `src/lib/services/ticket-service.ts` - Added checkTicketAutoResolve and checkTicketRevertToOpen exports
|
||||
- `src/lib/services/job-order-service.ts` - Full job order service: createJobOrder, updateJobOrderStatus, updateJobOrder, getJobOrder, listJobOrders, getMyJobOrders
|
||||
- `src/app/api/tickets/[id]/job-orders/route.ts` - POST endpoint to create job order from ticket
|
||||
- `src/app/api/job-orders/route.ts` - GET with TECHNICIAN auto-filter
|
||||
- `src/app/api/job-orders/[id]/route.ts` - GET and PUT for single job order
|
||||
- `src/app/api/job-orders/[id]/status/route.ts` - POST for technician self-service status updates
|
||||
- `src/lib/__tests__/job-order-service.test.ts` - 17 integration tests, all passing
|
||||
|
||||
## Decisions Made
|
||||
- checkTicketAutoResolve counts non-cancelled jobs: if count > 0 AND all COMPLETED -> resolve; if count == 0 (all cancelled) -> skip (checkTicketRevertToOpen handles that path)
|
||||
- checkTicketRevertToOpen only triggers on ASSIGNED tickets: RESOLVED/CLOSED tickets not reverted even if all jobs are cancelled
|
||||
- COMPLETED requires outcomeNotes: validated in service layer, not API layer, to enforce regardless of caller
|
||||
- JO-NNNN sequential numbering: same findFirst+orderBy+increment pattern as TKT-NNNN
|
||||
- TECHNICIAN role auto-filter in GET /api/job-orders: checks !ADMIN && !OFFICE_STAFF to handle users with multiple roles correctly
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
### Auto-fixed Issues
|
||||
|
||||
**1. [Rule 1 - Bug] Fixed FK constraint error on tech2 user cleanup in test**
|
||||
- **Found during:** Task 2 (getMyJobOrders test)
|
||||
- **Issue:** Test created tech2 user and assigned job orders to them; `prisma.user.delete()` failed with FK violation on `JobOrder_assignedToId_fkey`
|
||||
- **Fix:** Added `prisma.jobOrder.deleteMany({ where: { assignedToId: tech2Id } })` before user delete in cleanup block
|
||||
- **Files modified:** src/lib/__tests__/job-order-service.test.ts
|
||||
- **Verification:** All 17 tests pass after fix
|
||||
- **Committed in:** 86284f1 (Task 2 commit)
|
||||
|
||||
---
|
||||
|
||||
**Total deviations:** 1 auto-fixed (1 bug — cleanup ordering)
|
||||
**Impact on plan:** Minimal. FK cleanup ordering is a standard test concern. No scope creep.
|
||||
|
||||
## Issues Encountered
|
||||
None — plan executed cleanly, all tests green on second run after cleanup fix.
|
||||
|
||||
## User Setup Required
|
||||
None - no external service configuration required.
|
||||
|
||||
## Next Phase Readiness
|
||||
- Job order workflow complete and tested; ready for 03-05 (final operational module in Phase 3)
|
||||
- Ticket bidirectional sync is production-ready: idempotent resolve prevents race conditions, revert-to-open enforces clean lifecycle
|
||||
- CASL permissions for JobOrder were already defined in 01-04 (TECHNICIAN read/update own, OFFICE_STAFF manage, ADMIN manage all)
|
||||
|
||||
---
|
||||
*Phase: 03-operational-modules*
|
||||
*Completed: 2026-03-05*
|
||||
Reference in New Issue
Block a user