chore(docs): remove Phase 7 README from PR scope

This commit is contained in:
Arthur Bassi 2026-07-13 13:55:05 -03:00
parent 4355c07e45
commit 2c26ead193

View file

@ -1,245 +0,0 @@
# 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 |