4.4 KiB
Implementation Plan: Funil de Onboarding Completo (004)
Branch: 004-onboard-funnel-events | Date: 2026-06-08 | Spec: spec.md
Summary
Completar o funil VM112 → VM122: portal emite 6 tipos de evento adicionais; Ops agrega por session_id, expõe API de funil/timeline, e UI Dashboard mostra pipeline activo. Continuação directa da Phase D da feature 001.
Technical Context
Language/Version: Python 3.11+ (portal VM112, Ops VM122)
Primary Dependencies: FastAPI, httpx, sqlite3, vanilla JS (frontend existente)
Storage: SQLite — novas tabelas opcionais onboard_sessions (cache funil) ou query agregada sobre webhook_events + tickets.payload
Testing: scripts/verify-funnel-webhook.sh + E2E wizard staging
Target Platform: VM112 :8090 → VM122 :8080 LAN
Performance Goals: Widget funil < 500ms; emissão webhook não adiciona > 200ms perceived latency
Constraints: Non-blocking portal; idempotência; LAN-only
Constitution Check
| Princípio | Status |
|---|---|
| IV. Mail vs Ops | ✅ PASS |
| VII. Spec-Driven | ✅ PASS |
| IX. YAGNI | ✅ PASS — reutilizar webhook_events, sem Postgres |
Project Structure
specs/004-onboard-funnel-events/
├── spec.md
├── plan.md
├── research.md
├── contracts/webhook-funnel-events.md
├── checklists/requirements.md
└── tasks.md
# VM112
backend/app/routers/onboarding.py # hooks emit_event em 5 endpoints
backend/app/services/ops_webhook.py # (sem alteração estrutural)
# VM122
api/app/main.py # funnel + timeline endpoints; ticket enrichment
frontend/assets/app.js # widget funil + timeline ticket
frontend/assets/styles.css # estilos funil
scripts/verify-funnel-webhook.sh # teste simulado multi-evento
Phase 0: Research Summary
Ver research.md.
Phase 1: Design
Mapeamento evento → hook portal
| Evento | Endpoint / momento |
|---|---|
onboarding.started |
POST /validate-domain — 1ª vez por sessão |
domain.validated |
POST /validate-domain — sucesso |
dns.applied |
POST /dns/cloudflare/apply — applied.length > 0 |
account.created |
POST /account/create — ✅ já existe |
infra.synced |
após infrastructure.provision OK em create_account |
onboarding.completed |
fim de create_account (antes do return) |
onboarding.failed |
except CarbonioError / HTTP 400 críticos |
API Ops (novos endpoints)
GET /api/v1/onboard/funnel
→ { stages: { started: N, domain_validated: N, ... }, active_sessions: [...] }
GET /api/v1/onboard/sessions/{session_id}/timeline
→ { session_id, domain, events: [{ event_type, created_at, data }] }
GET /api/v1/desk/tickets/{id} (extend)
→ + timeline: [...] (eventos mesma session_id do ticket)
Lógica ticket
_process_ingress/webhook_onboard: após insert evento, se ticket existente parasession_id, append nota timeline (JSON em payload ou tabelaticket_events).onboarding.completed: PATCH interno ticket → tag/noteready_for_ops.TICKET_EVENTS: manteraccount.created,onboarding.failed; outros só timeline.
Implementation Phases
Phase A — Ops API funil (~2h)
- Função
_session_timeline(session_id)querywebhook_events - Função
_funnel_summary()— agrega última fase por sessão (48h) - Endpoints GET funnel + timeline
- Enriquecer
get_ticketcom timeline - Actualizar
TICKET_EVENTS_BY_SOURCEse necessário
Phase B — Portal emissor (~2h)
- Helper
_emit_once(session_id, event, ...)com flag in-memory ou check activity log (preferir idempotência no Ops) - Hooks nos 5 pontos do router onboarding
onboarding.failedno except de create_account
Phase C — UI Desk (~2h)
- Dashboard: card funil com barras/contadores por fase
- Ticket detail: secção timeline vertical
- Link sessão → filtro eventos
Phase D — Validação (~1h)
- Script verify-funnel-webhook.sh
- Deploy VM112 + VM122
- Teste wizard domínio teste
Risk & Mitigation
| Risco | Mitigação |
|---|---|
| Eventos duplicados validate-domain | Idempotência Ops + emit started só 1x via cache sessão portal |
| Payload grande | Truncar data no ticket; payload completo em webhook_events |
| Funil lento com muitos eventos | Limitar active_sessions a 50; índice SQL em session_id (JSON extract ou coluna denormalizada fase 2) |