6.1 KiB
Fase 7 — Rollout e Produção
Programa: Work Orders Board
Objetivo: Piloto SHOC, rollout gradual, monitoramento de coexistência, sunset Blazor WO, cutover Lambda→API e deprecação legado.
Depende de: Fase 0 … Fase 6 concluídas e validadas em staging.
Gates
- Entrada: phase-7-gates-signoff.md
- Saída: piloto UAT, 100% SHOC, zero P1 × 2 semanas, Blazor sunset, Lambda cutover, ops health ativo
Runbook de rollout (ordem obrigatória)
- Fechar gates de entrada Fase 7
- Deploy API com ops health + ingest (ingest desabilitado em prod inicialmente)
- SHOC: feature flag board em staging → piloto 1–2 dispatchers em prod
- UAT dispatchers (roteiros abaixo)
- Rollout gradual SHOC até 100%
- Habilitar dual-run Lambda (
ingest+ Dynamo) - Validar drift → cutover Lambda só API
Sync:Enabled=falseBlazorWorkOrderSunset:Enabled=trueLegacyEndpoints:DeprecationEnabled=true+ data Sunset- Remover Sync/legado após período de aviso (30 dias)
Endpoints Fase 7
GET /api/workorders/ops/health
Saúde operacional para coexistência multi-consumidor.
Auth: Admin JWT
{
"lastWeekRolledRunUtc": "2026-06-23T00:05:12Z",
"lastPastDueCacheRunUtc": null,
"lastWeekRolledError": null,
"lastPastDueCacheError": null,
"syncRejectedLast24h": 3,
"fieldLockCount": 142,
"syncEnabled": true,
"ingestEnabled": true,
"legacyDeprecationEnabled": false,
"legacySunsetDate": null,
"checkedAtUtc": "2026-06-25T12:00:00Z"
}
Ver cloudwatch-alerts.md.
POST /api/workorders/ingest
Ingest direto idempotente (substitui ponte DynamoDB para WOs).
Auth: header X-Ingest-Key (config WorkOrderIngest:ApiKey)
Body (single ou batch):
{
"externalWorkOrderId": "ext-wo-12345",
"description": "HVAC unit not cooling",
"woStatus": "new",
"severity": "2",
"customer": "Acme Corp",
"siteCode": "BK5",
"building": "Building A",
"address": "123 Main St",
"dueDate": "2026-07-01T00:00:00Z",
"dateReported": "2026-06-20T10:00:00Z",
"scheduledStart": null,
"sourceEmailS3Key": null,
"createdAt": "2026-06-20T10:00:00Z"
}
Batch:
{
"items": [ { "externalWorkOrderId": "...", "description": "..." } ]
}
Response:
{
"created": 1,
"updated": 0,
"results": [{ "externalWorkOrderId": "ext-wo-12345", "workOrderId": 42, "created": true }]
}
Mapeamento completo: lambda-ingest-discovery.md
Matriz de endpoints
| Tipo | Exemplos | Política Fase 7 |
|---|---|---|
| Board (SHOC) | GET board, PATCH {id}/board, POST board |
Produção |
| Slide-over | GET {id}/detail, completion-doc, media |
Produção |
| Ingest | POST ingest |
Dual-run → produção |
| Sync | POST api/Sync/WorkOrders |
Desligar após cutover (Sync:Enabled) |
| Legado | GetWorkOrderList, AddWorkorder, ChangeStatus |
Deprecation headers |
| Jobs | POST jobs/week-rolled |
Ops Admin |
Configuração
API (Api.SeaHavenIndustries)
{
"FrontendBaseUrl": "https://shoc.seahaven.com",
"WorkOrderIngest": {
"Enabled": true,
"ApiKey": "${WORKORDER_INGEST_API_KEY}"
},
"Sync": {
"Enabled": true
},
"LegacyEndpoints": {
"DeprecationEnabled": false,
"SunsetDate": "2026-12-31"
}
}
Env vars: ver .env.example
Blazor (SeaHavenIndustries)
{
"BlazorWorkOrderSunset": {
"Enabled": false,
"ShocBaseUrl": "https://shoc.seahaven.com"
}
}
Quando Enabled=true: nav Work Orders aponta para SHOC; mutações EF bloqueadas; banner nas páginas WO.
UAT dispatchers
Roteiro manual — marcar cada item antes de expandir rollout.
| # | Cenário | Pass |
|---|---|---|
| 1 | Login SHOC; carregar semana (Mon–Fri + Unscheduled) | [ ] |
| 2 | Filtros: dispatcher, My WOs, tipo, busca contextual | [ ] |
| 3 | Inline edit célula (status, assignee, due) | [ ] |
| 4 | Conflito 409 — outro usuário editou; mensagem clara | [ ] |
| 5 | Criar WO wizard (Incomplete → Scheduled auto) | [ ] |
| 6 | Cancel soft; campos read-only pós-cancel | [ ] |
| 7 | Advanced search cross-week | [ ] |
| 8 | Slide-over: detail, comments, audit, media | [ ] |
| 9 | Upload completion doc; docStatus no board | [ ] |
| 10 | Badge PastDue / CarriedOver após segunda-feira | [ ] |
Sign-off UAT
| Dispatcher | Data | PO |
|---|---|---|
Piloto e rollout SHOC
Controle somente no frontend (feature flags). Backend não filtra dispatchers.
Critérios para avançar:
- Zero P1 na semana do piloto
GET boardlatência aceitável (Tier S)- Vendor Portal regression verde
Sunset Blazor
Ver data-ownership-model.md §3.
- Congelar
WorkorderService(bugfix only) até data PO - Habilitar
BlazorWorkOrderSunset:Enabled - Smoke final smoke-checklist.md Blazor EF
Cutover Lambda
Ver lambda-ingest-discovery.md.
Testes automatizados
dotnet test SeaHavenIndustries.Tests --filter "FullyQualifiedName~WorkOrderPhase7"
Suite: WorkOrderPhase7CoexistenceTests.cs
Critérios de aceite Fase 7
GET /api/workorders/ops/healthPOST /api/workorders/ingestcom API keySync:Enabledfeature flag- Legacy deprecation middleware
- Blazor sunset config + guard mutações
- Documentação gates, UAT, Lambda mapping
- Piloto prod (ops/PO)
- 100% dispatchers SHOC (ops/PO)
- Zero P1 × 2 semanas (ops/PO)
- Lambda cutover executado (ops)
Comunicação
| Audiência | Mensagem | Quando |
|---|---|---|
| Dispatchers piloto | Novo board SHOC; suporte dedicado | Início piloto |
| Todos dispatchers | Rollout gradual; treinamento | Durante rollout |
| Usuários Blazor | WO migrou para SHOC; link direto | Sunset Blazor |
| Engenharia | Sync desligado; usar ingest API | Pós-cutover |