shoc-backend/docs/work-orders/phase-5
2026-06-30 10:09:48 -03:00
..
README.md wip: work orders phases 1-7 (isolated from phase 0 foundation) 2026-06-30 10:09:48 -03:00

Fase 5 — Scheduled Domain Events

Programa: Work Orders Board
Objetivo: Jobs agendados in-process (IHostedService) para WeekRolled → CarriedOver++ com idempotência WO+semana, audit System, cache opcional de PastDue, e garantia de que leituras do board continuam on-read como fonte da verdade.

Depende de: Fase 0, Fase 1, Fase 2, Fase 3, Fase 4


Regra de elegibilidade WeekRolled

sourceWeek = semana operacional encerrada (segunda a sexta UTC)
Elegível se:
  - ScheduledDate.Date ∈ [sourceWeekStart, sourceWeekEnd]
  - LifecycleStatus ∉ {Complete, Canceled, Closed}
  - istemplate != true (ou null)
  - Ainda não processado em WorkOrderWeekRolledLedger (WorkOrderId + SourceWeekStart)

Gate PO (pendente): confirmar se WOs só com TargetWeek (sem ScheduledDate) entram no carry-over. A implementação atual considera apenas WOs com ScheduledDate na janela.


Idempotência

Chave composta (WorkOrderId, SourceWeekStart) na tabela WorkOrderWeekRolledLedger. Re-execução do job ou endpoint admin na mesma semana não duplica CarriedOver.


Contrato de audit

Um evento WeekRolled por WO processado:

Campo Valor
EventType System
ActorType System
Action WeekRolled
FieldName CarriedOver
OldValue / NewValue numéricos (string)
CorrelationId week:{yyyy-MM-dd} (segunda da semana fonte)

Não aciona ManualEditFlag nem field locks.


Regra de ouro — isPastDue

Jobs nunca são fonte da verdade para isPastDue. O board continua calculando via WorkOrderDerivedFields.IsPastDue on-read. O cache OperationalFlags.PastDue é otimização opcional (WorkOrderJobs:PastDueCache:Enabled, default false).


Configuração

"WorkOrderJobs": {
  "WeekRolled": { "Enabled": true, "RunAtUtc": "00:05", "DayOfWeek": "Monday" },
  "PastDueCache": { "Enabled": false, "RunAtUtc": "00:10" }
}

Variáveis de ambiente (.env.example):

WorkOrderJobs__WeekRolled__Enabled=true
WorkOrderJobs__PastDueCache__Enabled=false

Endpoints admin (ops-only)

Endpoint Auth Descrição
POST /api/workorders/jobs/week-rolled?sourceWeekStart=2026-06-16 Admin Reprocessa semana (segunda-feira). Idempotente.
POST /api/workorders/jobs/past-due-cache Admin Atualiza cache OperationalFlags.PastDue

Código entregue

Camada Arquivo
Ledger Data.SeaHavenIndustries/Models/WorkOrderWeekRolledLedger.cs
Migration 20260624210000_Phase5_DomainEvents.cs
Data SeaHaven.DataServices/Implementation/WorkOrderDomainJobDataService.cs
WeekRolled SeaHaven.Services/Implementation/WorkOrderWeekRolledService.cs
PastDue cache SeaHaven.Services/Implementation/PastDueCacheService.cs
Hosted Api.SeaHavenIndustries/HostedServices/*.cs
API WorkOrderJobsController
Testes SeaHavenIndustries.Tests/WorkOrderWeekRolledTests.cs

Monitoramento

Logs estruturados com CorrelationId da semana. Ao concluir: processed, skipped, failed, durationMs.

Alerta ops: se failed > 0 ou job não executou em 8 dias → investigar + POST /jobs/week-rolled manual.


Critérios de aceite

  • Job semanal incrementa carriedOver para WOs elegíveis da semana anterior
  • Re-execução na mesma semana não duplica (ledger WO+semana)
  • Audit WeekRolled System com old/new CarriedOver e CorrelationId
  • GET /api/workorders/board continua com isPastDue derivado on-read
  • Endpoint admin permite reprocessar semana específica
  • Testes cobrem idempotência, terminal skip, audit e on-read correctness

Fora de escopo

  • Message queue / worker externo
  • Alteração do contrato REST do board para usar OperationalFlags
  • WOs week-only (TargetWeek sem ScheduledDate) — gate PO