mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 17:43:12 +00:00
| .. | ||
| README.md | ||
Fase 2 — Inline Edit + Concorrência
Programa: Work Orders Board
Objetivo: Edição spreadsheet-style célula a célula no board SHOC, com dual RowVersion, audit granular e regras de domínio no backend.
Endpoints
PATCH /api/workorders/{id}/board
Atualiza um único campo do board com validação otimista de concorrência.
Autenticação: Bearer JWT ([Authorize])
Request body:
{
"field": "scheduledDate",
"value": "2026-06-25",
"workOrderVersion": "<base64 RowVersion>",
"dispatchVersion": "<base64 RowVersion | null para campos WO-only>",
"primaryDispatchId": 123
}
| Campo | Obrigatório | Descrição |
|---|---|---|
field |
Sim | Nome canônico do campo (case-insensitive) |
value |
Sim* | Valor serializado como string (*pode ser vazio para limpar datas) |
workOrderVersion |
Sim | RowVersion atual da WO (Base64) |
dispatchVersion |
Condicional | Obrigatório para campos Dispatch quando dispatch já existe |
primaryDispatchId |
Não | Valida que o dispatch pertence à WO |
Responses:
| HTTP | Body | Quando |
|---|---|---|
| 200 | WorkOrderBoardRowDto |
Sucesso — row completo com versões atualizadas |
| 409 | WorkOrderBoardConflictDto + currentState |
Conflito de versão |
| 422 | WorkOrderBoardValidationErrorDto |
Regra de domínio violada |
| 400 | Response |
Erro genérico / argumento inválido |
Exemplo:
curl -X PATCH -H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"field":"siteCode","value":"BK5","workOrderVersion":"AQAAAAAAAAA="}' \
"https://localhost:5001/api/workorders/1/board"
Campos editáveis
| field (API) | Agregado | Coluna board | Audit FieldName |
|---|---|---|---|
woNumber |
WorkOrder | WO# | InternalWONumber |
workOrderType |
WorkOrder | Type | WorkOrderType |
siteCode |
WorkOrder | Site | SiteCode |
lifecycleStatus |
WorkOrder | Status | LifecycleStatus |
assignTo |
WorkOrder | Assignee | AssignTo |
dueDate |
WorkOrder | Due | DueDate |
scheduledDate |
WorkOrder | Scheduled | ScheduledDate |
targetWeek |
WorkOrder | Scheduled (week-only) | TargetWeek |
scheduleWeekOnly |
WorkOrder | Scheduled | ScheduleWeekOnly |
vendorId |
Dispatch | Vendor | VendorId |
apptDate |
Dispatch | Appt | ApptDate |
apptTime |
Dispatch/WO | Appt | ApptTime |
docStatus |
WorkOrder | Doc | DocStatus |
Read-only: isPastDue, carriedOver, rescheduleCount (badge derivado; count incrementado por regra).
Dual RowVersion
| Agregado | Quando exigir versão |
|---|---|
| WorkOrder | Sempre (workOrderVersion) |
| Dispatch | Campos vendor/appt quando dispatch primário já existe (dispatchVersion) |
O GET board retorna rowVersion, dispatchRowVersion e primaryDispatchId em cada row.
409 currentState: inclui row recarregado do DB para refresh imediato no FE.
Regras de domínio
| Regra | Comportamento |
|---|---|
| Auto-schedule | Incomplete + scheduledDate + assignTo → Scheduled |
| Reschedule | Mudança de scheduledDate com data anterior → rescheduleCount++ |
| Set-once tracking | Primeira scheduledDate → OriginalDate / OriginalWeek |
| Past Due block | Não permite mudar lifecycleStatus quando isPastDue |
| Cancel read-only | Status terminal (Canceled, Closed, Complete) bloqueia PATCH |
| WO# 11 dígitos | Normalização numérica + unicidade |
| Vendor ADR | Mutação em Dispatch; cria dispatch primário se ausente |
Audit
- 1 evento por campo alterado (
FieldChanged,StatusChanged, ouAssignmentChanged) - Side effects (auto-schedule, rescheduleCount) geram eventos adicionais
- Field lock (
WorkOrderFieldLocks) criado automaticamente em edições manuais - Eventos Dispatch incluem
dispatchId
Código entregue
| Camada | Arquivo |
|---|---|
| DTOs | SeaHaven.Services/DTOs/WorkOrderBoardDTOs.cs |
| Helpers | WorkOrderBoardMutationRules, WorkOrderNumberNormalizer, WorkOrderBoardFieldNames, WorkOrderBoardApptTimeParser |
| Update service | SeaHaven.Services/Implementation/WorkOrderBoardUpdateService.cs |
| Audit | IWorkOrderAuditService.StageFieldChanged, LogFieldChangedAsync |
| API | WorkOrderController — PATCH {id}/board |
| Testes | WorkOrderBoardMutationRulesTests, WorkOrderNumberNormalizerTests, WorkOrderBoardUpdateServiceTests, WorkOrderBoardConcurrencyTests |
Gates de aceite
Desenvolvimento
PATCH /api/workorders/{id}/boardpara todos os campos da matriz- Dual RowVersion validado; 409 com
currentState - Auto-schedule Incomplete→Scheduled
- RescheduleCount++ em reagendamento
- Bloqueio status quando PastDue; reagendar limpa flag on-read
- WO cancelado/closed rejeita edição (422)
- WO# normalizado 11 dígitos + unicidade
- Vendor/appt muta Dispatch; cria primário se ausente
- 1 audit event por campo; field lock criado
- 51 testes unitários total (25 Fase 2 + 26 Fases 0–1)
Staging (pendente)
- Smoke Sync durante edição SHOC
- UAT dispatcher: editar células reais no board
- Latência PATCH aceitável (<200ms p95 Tier S)
Próximo passo
Fase 3 — Criação wizard/inline, soft cancel dedicado, ManualEditFlag na criação.