ligbox-ops-platform/specs/004-onboard-funnel-events/plan.md
Ligbox Spec Hub 3a2c64834b Initial import: ligbox-ops-platform + specs + LAPTOP + obsidian merge (CT130)
Source: VM122 /opt + obsidian-infra + LAPTOP
Hub: CT130 spec-hub 10.10.10.130
2026-06-19 17:26:41 +00:00

126 lines
4.4 KiB
Markdown

# Implementation Plan: Funil de Onboarding Completo (004)
**Branch**: `004-onboard-funnel-events` | **Date**: 2026-06-08 | **Spec**: [spec.md](./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
```text
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](./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 para `session_id`, append nota timeline (JSON em payload ou tabela `ticket_events`).
- `onboarding.completed`: PATCH interno ticket → tag/note `ready_for_ops`.
- `TICKET_EVENTS`: manter `account.created`, `onboarding.failed`; outros só timeline.
## Implementation Phases
### Phase A — Ops API funil (~2h)
1. Função `_session_timeline(session_id)` query `webhook_events`
2. Função `_funnel_summary()` — agrega última fase por sessão (48h)
3. Endpoints GET funnel + timeline
4. Enriquecer `get_ticket` com timeline
5. Actualizar `TICKET_EVENTS_BY_SOURCE` se necessário
### Phase B — Portal emissor (~2h)
1. Helper `_emit_once(session_id, event, ...)` com flag in-memory ou check activity log (preferir idempotência no Ops)
2. Hooks nos 5 pontos do router onboarding
3. `onboarding.failed` no except de create_account
### Phase C — UI Desk (~2h)
1. Dashboard: card funil com barras/contadores por fase
2. Ticket detail: secção timeline vertical
3. Link sessão → filtro eventos
### Phase D — Validação (~1h)
1. Script verify-funnel-webhook.sh
2. Deploy VM112 + VM122
3. 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) |