shoc-backend/docs/work-orders/phase-7/README.md

245 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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](../phase-0/README.md) … [Fase 6](../phase-6/README.md) concluídas e validadas em staging.
---
## Gates
- **Entrada:** [phase-7-gates-signoff.md](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)
1. Fechar gates de entrada Fase 7
2. Deploy API com ops health + ingest (ingest desabilitado em prod inicialmente)
3. SHOC: feature flag board em staging → piloto 1–2 dispatchers em prod
4. UAT dispatchers ([roteiros abaixo](#uat-dispatchers))
5. Rollout gradual SHOC até 100%
6. Habilitar dual-run Lambda (`ingest` + Dynamo)
7. Validar drift → cutover Lambda só API
8. `Sync:Enabled=false`
9. `BlazorWorkOrderSunset:Enabled=true`
10. `LegacyEndpoints:DeprecationEnabled=true` + data Sunset
11. 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
```json
{
"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](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):**
```json
{
"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:**
```json
{
"items": [ { "externalWorkOrderId": "...", "description": "..." } ]
}
```
**Response:**
```json
{
"created": 1,
"updated": 0,
"results": [{ "externalWorkOrderId": "ext-wo-12345", "workOrderId": 42, "created": true }]
}
```
Mapeamento completo: [lambda-ingest-discovery.md](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`)
```json
{
"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](../../../.env.example)
### Blazor (`SeaHavenIndustries`)
```json
{
"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 board` latência aceitável (Tier S)
- Vendor Portal regression verde
---
## Sunset Blazor
Ver [data-ownership-model.md](../phase-0/data-ownership-model.md) §3.
1. Congelar `WorkorderService` (bugfix only) até data PO
2. Habilitar `BlazorWorkOrderSunset:Enabled`
3. Smoke final [smoke-checklist.md](../phase-0/smoke-checklist.md) Blazor EF
---
## Cutover Lambda
Ver [lambda-ingest-discovery.md](lambda-ingest-discovery.md).
---
## Testes automatizados
```powershell
dotnet test SeaHavenIndustries.Tests --filter "FullyQualifiedName~WorkOrderPhase7"
```
Suite: `WorkOrderPhase7CoexistenceTests.cs`
---
## Critérios de aceite Fase 7
- [x] `GET /api/workorders/ops/health`
- [x] `POST /api/workorders/ingest` com API key
- [x] `Sync:Enabled` feature flag
- [x] Legacy deprecation middleware
- [x] Blazor sunset config + guard mutações
- [x] 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 |