114 lines
4.6 KiB
Markdown
114 lines
4.6 KiB
Markdown
# Tasks: Webhook VM112 → Ops Platform
|
||
|
||
**Input**: [spec.md](./spec.md) · [plan.md](./plan.md) · [contracts/webhook-onboard.md](./contracts/webhook-onboard.md)
|
||
|
||
**Prerequisites**: plan.md ✅ · spec.md ✅ · research.md ✅ · data-model.md ✅
|
||
|
||
## Format: `[ID] [P?] [Story] Description`
|
||
|
||
---
|
||
|
||
## Phase 1: Setup
|
||
|
||
**Purpose**: Preparar paths e configuração partilhada
|
||
|
||
- [ ] T001 Confirmar VM122 API healthy: `curl http://10.10.10.122:8080/health`
|
||
- [ ] T002 Confirmar VM112 portal healthy: `curl http://10.10.10.112:8090/api/onboarding/health`
|
||
- [ ] T003 [P] Documentar secret actual em ambos `.env` (VM122 `WEBHOOK_SECRET`, VM112 `OPS_WEBHOOK_SECRET` a criar)
|
||
- [ ] T004 [P] Criar `scripts/verify-webhook.sh` em `ligbox-ops-platform/scripts/`
|
||
|
||
**Checkpoint**: Ambos serviços acessíveis na LAN
|
||
|
||
---
|
||
|
||
## Phase 2: Foundational — Ops Receptor (VM122)
|
||
|
||
**Purpose**: Idempotência e tickets melhorados no receptor existente
|
||
|
||
**⚠️ CRITICAL**: Completar antes do emissor portal
|
||
|
||
- [ ] T005 [US1] Adicionar função `_is_duplicate_event(conn, event, session_id, domain)` em `api/app/main.py` (VM122 deploy path)
|
||
- [ ] T006 [US1] Em `webhook_onboard`: skip INSERT ticket se duplicado; sempre INSERT webhook_events
|
||
- [ ] T007 [US1] Melhorar subject ticket: `[{event}] {domain} — {email}` quando `data.email` presente
|
||
- [ ] T008 [P] [US1] Rebuild e restart: `docker-compose -f docker-compose.mvp.yml up -d --build api` na VM122
|
||
- [ ] T009 [US1] Testar idempotência com curl duplicado (quickstart §2)
|
||
|
||
**Checkpoint**: Receptor pronto para receber do portal
|
||
|
||
---
|
||
|
||
## Phase 3: User Story 1 — Ticket automático ao criar conta (P1) 🎯 MVP
|
||
|
||
**Goal**: Portal emite `account.created` → ticket no Ops Desk
|
||
|
||
- [ ] T010 [P] [US1] Adicionar campos `ops_webhook_url`, `ops_webhook_secret`, `ops_webhook_enabled` em `backend/app/config.py` (obsidian-infra path)
|
||
- [ ] T011 [US1] Criar `backend/app/services/ops_webhook.py` com `emit_event()` + retry 3x (1s, 3s, 9s) + httpx timeout 5s
|
||
- [ ] T012 [US1] Em `ops_webhook.py`: log warn via `activity_log` em falha; nunca raise
|
||
- [ ] T013 [US1] Em `backend/app/routers/onboarding.py` `create_account`: obter `session_id` de `request.state` e chamar `ops_webhook.emit_event("account.created", ...)` via `BackgroundTasks`
|
||
- [ ] T014 [US1] Payload `data`: `email`, `account_verified`, `needs_review`, `dns_mode`, `mail_aliases`
|
||
- [ ] T015 [US1] Adicionar `.env` entries em VM112: `OPS_WEBHOOK_URL=http://10.10.10.122:8080/api/v1/webhooks/onboard`
|
||
- [ ] T016 [US1] Deploy portal VM112 (rsync + restart backend)
|
||
- [ ] T017 [US1] E2E: onboarding teste → verificar ticket em `GET /api/v1/desk/tickets`
|
||
|
||
**Checkpoint**: MVP US1 completo e testável
|
||
|
||
---
|
||
|
||
## Phase 4: User Story 2 — Rastreio de sessão (P2)
|
||
|
||
**Goal**: Eventos correlacionados por `session_id`
|
||
|
||
- [ ] T018 [US2] Garantir `session_id` sempre enviado em `emit_event` (fallback `""` aceite pelo Ops)
|
||
- [ ] T019 [US2] Adicionar endpoint `GET /api/v1/webhooks/events?session_id=` no Ops (opcional, consulta audit log)
|
||
- [ ] T020 [US2] Testar 2 eventos mesma sessão — ambos em `webhook_events`
|
||
|
||
**Checkpoint**: Sessão rastreável no Ops
|
||
|
||
---
|
||
|
||
## Phase 5: User Story 3 — Falha não bloqueia onboarding (P2)
|
||
|
||
**Goal**: Portal resiliente com Ops offline
|
||
|
||
- [ ] T021 [US3] Teste: parar API VM122, completar onboarding, confirmar resposta 200 ao cliente
|
||
- [ ] T022 [US3] Verificar activity log portal contém warn de falha webhook
|
||
- [ ] T023 [US3] Confirmar `OPS_WEBHOOK_ENABLED=false` desactiva envio sem erro
|
||
|
||
**Checkpoint**: Resiliência validada
|
||
|
||
---
|
||
|
||
## Phase 6: User Story 4 — Eventos funil P3 (opcional)
|
||
|
||
**Goal**: Visibilidade pipeline completo
|
||
|
||
- [ ] T024 [P] [US4] Hook `domain.validated` em endpoint validate-domain do portal
|
||
- [ ] T025 [P] [US4] Hook `dns.applied` em cloudflare apply
|
||
- [ ] T026 [US4] Hook `onboarding.completed` / `onboarding.failed` nos pontos finais
|
||
- [ ] T027 [US4] Ops: eventos não-ticket só INSERT webhook_events
|
||
|
||
**Checkpoint**: Funil completo visível no Ops
|
||
|
||
---
|
||
|
||
## Phase 7: Polish & Docs
|
||
|
||
- [ ] T028 [P] Actualizar `README.md` do ligbox-ops-platform com link para spec
|
||
- [ ] T029 [P] Rotacionar `WEBHOOK_SECRET` para valor produção (não dev default)
|
||
- [ ] T030 Executar `scripts/verify-security.sh` na VM122 pós-deploy
|
||
- [ ] T031 Actualizar inventário VMs / backlog Obsidian com INT-2 concluído
|
||
|
||
---
|
||
|
||
## Dependencies
|
||
|
||
```text
|
||
Phase 1 → Phase 2 → Phase 3 (MVP)
|
||
→ Phase 4, 5 (paralelo após Phase 3)
|
||
→ Phase 6 (opcional)
|
||
→ Phase 7
|
||
```
|
||
|
||
## MVP Scope (mínimo entregável)
|
||
|
||
**T001–T017** — US1 completa: portal emite, ops recebe, ticket criado, idempotente.
|