# Lambda Ingest — Descoberta e Mapeamento de Campos **Fase:** 7 **Status:** Documentação de cutover (código Lambda fora deste repositório) --- ## 1. Localização da Lambda | Item | Valor | |------|-------| | Nome referenciado | `workorder-ingest` | | Referência código | [TODO.md](../../../TODO.md) L50–51 | | Fluxo atual | Lambda → DynamoDB (`WorkOrders`) → `POST api/Sync/WorkOrders` | | Fluxo alvo | Lambda → `POST api/workorders/ingest` (API key) | **Ação pendente ops:** localizar repositório/infra AWS (SAM, Terraform, console Lambda) e preencher owner na [phase-7-gates-signoff.md](phase-7-gates-signoff.md). --- ## 2. Tabelas DynamoDB (SyncController) | Tabela | Endpoint sync | Uso | |--------|---------------|-----| | `WorkOrders` | `POST api/Sync/WorkOrders` | Upsert WO por `work_order_id` | | `WorkOrderComments` | `POST api/Sync/Comments` | Comentários cliente | | `VendorReplies` | `POST api/Sync/VendorReplies` | Respostas vendor | Cutover Fase 7 foca em **WorkOrders**; comments/replies permanecem no Sync até migração separada. --- ## 3. Mapeamento DynamoDB → API ingest Campos lidos em [SyncController.cs](../../../Api.SeaHavenIndustries/Controllers/SyncController.cs) e espelhados em `WorkOrderIngestPayload`: | Campo Dynamo | Campo API ingest | Campo SQL | Merge policy (update) | |--------------|------------------|-----------|------------------------| | `work_order_id` | `externalWorkOrderId` | `ExternalWorkOrderId` | Chave idempotente | | `description` | `description` | `Description`, `WorkerOrderTitle` | Sim se não locked | | `wo_status` | `woStatus` | `Status` (mapeado) | Sim se não locked | | `severity` | `severity` | `Priority`, `Severity` | Sim se não locked | | `customer` | `customer` | `Customer` | Direto na criação | | `site_code` | `siteCode` | `SiteCode` | Sim se não locked | | `building` | `building` | `Building` | Sim se não locked | | `address` | `address` | `Locations` (resolve/create) | LocationId | | `due_date` | `dueDate` | `DueDate` | Sim se não locked | | `date_reported` | `dateReported` | `DateReported` | Direto | | `scheduled_start` | `scheduledStart` | `ScheduledStart` | Direto | | `source_email_s3_key` | `sourceEmailS3Key` | `SourceEmailS3Key` | Direto | | `created_at` | `createdAt` | `CreatedDate` | Criação only | ### Mapeamento `wo_status` → SQL `Status` | Dynamo | SQL | |--------|-----| | `new`, `assigned`, `unknown` | `Open` | | `in_progress` | `In Progress` | | `on_hold` | `On Hold` | | `completed` | `Done` | | `cancelled` | `Cancelled` | ### Mapeamento `severity` → `Priority` `Sev {severity}` (ex.: `3` → `Sev 3`) --- ## 4. Auth serviço-a-serviço | Header | Config | |--------|--------| | `X-Ingest-Key` | `WorkOrderIngest:ApiKey` (env `WorkOrderIngest__ApiKey`) | Lambda deve enviar o header em cada `POST /api/workorders/ingest`. Não usar JWT de usuário dispatcher. --- ## 5. Estratégia dual-run 1. **Semana 1–2:** Lambda grava DynamoDB **e** chama API ingest 2. **Validação:** `GET /api/workorders/ops/health` + script amostra `ExternalWorkOrderId` 3. **Cutover:** Lambda só API; `Sync:Enabled=false` 4. **Retire:** backup DynamoDB → desativar tabelas --- ## 6. Critérios de cutover - [ ] `POST /api/workorders/board` estável (criação SHOC) - [ ] Auth ingest testada em staging - [ ] Zero drift em amostra de 100 WOs - [ ] Owner Lambda assinou runbook