From ba3e824157216cf9ca1e43132cb3602801b38e6c Mon Sep 17 00:00:00 2001 From: Simone Cavalli Date: Sun, 21 Jun 2026 11:23:56 +0200 Subject: [PATCH] docs: create milestone v2.3 roadmap (3 phases, 9 requirements mapped) Co-Authored-By: Claude Sonnet 4.6 --- .planning/REQUIREMENTS.md | 24 ++++----- .planning/ROADMAP.md | 100 ++++++++++++++++++++++++++++++++++---- .planning/STATE.md | 44 +++++++++-------- 3 files changed, 127 insertions(+), 41 deletions(-) diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 4d7a076..f3c0582 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -48,21 +48,21 @@ Admin invia link deck pubblico al lead direttamente dall'admin UI. Usa stessa in | Requirement | Phase | Status | |-------------|-------|--------| -| OTP-01 | — | Pending | -| OTP-02 | — | Pending | -| OTP-03 | — | Pending | -| OTP-04 | — | Pending | -| OTP-05 | — | Pending | -| OTP-06 | — | Pending | -| OTP-07 | — | Pending | -| SEND-01 | — | Pending | -| SEND-02 | — | Pending | +| OTP-01 | Phase 24 | Pending | +| OTP-02 | Phase 25 | Pending | +| OTP-03 | Phase 25 | Pending | +| OTP-04 | Phase 25 | Pending | +| OTP-05 | Phase 25 | Pending | +| OTP-06 | Phase 25 | Pending | +| OTP-07 | Phase 25 | Pending | +| SEND-01 | Phase 23 | Pending | +| SEND-02 | Phase 23 | Pending | **Coverage:** - v2.3 requirements: 9 total -- Mapped to phases: 0 (roadmap pending) -- Unmapped: 9 ⚠️ +- Mapped to phases: 9 +- Unmapped: 0 ✓ --- *Requirements defined: 2026-06-21* -*Last updated: 2026-06-21 — initial definition* +*Last updated: 2026-06-21 — traceability filled after roadmap creation* diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index e19e405..0b6a194 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -6,7 +6,7 @@ - ✅ **v2.0 Business Operations Suite** — Phases 7–10 (shipped 2026-06-13) — [archive](milestones/v2.0-ROADMAP.md) - ✅ **v2.1 Offer Studio + CRM** — Phases 11–14 parziale (chiuso 2026-06-19, reset → v2.2) - ✅ **v2.2 Sales Loop** — Phases 18–22 (shipped 2026-06-20) — [archive](milestones/v2.2-ROADMAP.md) -- 📋 **v2.3** — prossima milestone (in definizione) +- 🔨 **v2.3 Email & Accesso** — Phases 23–25 (in corso) ## Phases @@ -34,15 +34,49 @@ Archivio completo: [milestones/v2.2-ROADMAP.md](milestones/v2.2-ROADMAP.md) -### 📋 v2.3 — Prossima Milestone (in definizione) +### 🔨 v2.3 — Email & Accesso (Phases 23–25) -Candidati backlog (da formalizzare con `/gsd-new-milestone`): +- [ ] **Phase 23: Resend Setup + Invio Preventivo** — Integrazione Resend e invio link deck dall'admin +- [ ] **Phase 24: Schema + Whitelist Admin** — Tabelle `client_emails` e `otp_codes`, admin UI gestione whitelist +- [ ] **Phase 25: OTP Gate + Sessione** — Gate OTP completo, sessione 30gg, rate limiting, no enumeration -- [ ] PUB-03 — Invio link preventivo via email Resend -- [ ] PROP-03 — Stripe Payment Link su offerta pubblica -- [ ] PROP-04 — Auto-provisioning cliente/progetto/fasi al "Vinto" -- [ ] AUTH-OTP-01 — Accesso cliente via OTP email (design pronto) -- [ ] Phase 13 — Servizi attivi/ricorrenti post-vendita (congelata, ripescabile) +## Phase Details + +### Phase 23: Resend Setup + Invio Preventivo +**Goal**: Admin può inviare il link `/preventivo/[slug]` via email con un click dall'admin UI +**Depends on**: Nothing — primo uso di Resend, nessuna dipendenza DB +**Requirements**: SEND-01, SEND-02 +**Success Criteria** (what must be TRUE): + 1. Admin fa click su "Invia preventivo" nel dettaglio lead/preventivo e l'email parte senza uscire dall'app + 2. Il destinatario riceve un'email in italiano con nome cliente e link cliccabile al deck pubblico + 3. L'invio usa Resend con le variabili d'ambiente configurate su Coolify (`RESEND_API_KEY`, `RESEND_FROM`) + 4. In caso di errore Resend, l'admin vede un messaggio di errore chiaro nell'UI (non un crash silenzioso) +**Plans**: TBD +**UI hint**: yes + +### Phase 24: Schema + Whitelist Admin +**Goal**: Admin può gestire la whitelist email di ogni cliente, con le tabelle DB pronte per l'OTP gate +**Depends on**: Phase 23 (Resend SDK già installato e variabili d'ambiente configurate) +**Requirements**: OTP-01 +**Success Criteria** (what must be TRUE): + 1. Admin può aggiungere una o più email alla whitelist di un cliente dalla pagina dettaglio cliente + 2. Admin può rimuovere un'email dalla whitelist di un cliente + 3. Le tabelle `client_emails` e `otp_codes` esistono in produzione (migration additive applicata via SSH prima del codice) + 4. La migration non tocca nessuna delle tabelle protette (`clients`, `projects`, `payments`, `phases`) +**Plans**: TBD +**UI hint**: yes + +### Phase 25: OTP Gate + Sessione +**Goal**: Il portale `/client/[token]/*` richiede verifica OTP email prima di mostrare la dashboard +**Depends on**: Phase 24 (tabelle `client_emails` e `otp_codes` in prod) +**Requirements**: OTP-02, OTP-03, OTP-04, OTP-05, OTP-06, OTP-07 +**Success Criteria** (what must be TRUE): + 1. Cliente senza sessione OTP valida vede una schermata "inserisci la tua email" al posto della dashboard + 2. Inserita un'email in whitelist, il cliente riceve il codice OTP via Resend; inserendo il codice corretto ottiene accesso con cookie valido 30 giorni + 3. Un'email non in whitelist non riceve OTP — il messaggio d'errore mostrato è identico a quello per email valide (no enumeration) + 4. Un codice OTP non utilizzato entro 15 minuti viene rifiutato; il cliente deve richiederne uno nuovo + 5. Tentativi ripetuti sugli endpoint OTP vengono bloccati dal rate limiter (no brute force) +**Plans**: TBD ## Progress @@ -61,4 +95,52 @@ Candidati backlog (da formalizzare con `/gsd-new-milestone`): | 20. Knowledge Base Cliente | v2.2 | 3/3 | ✅ Done | 2026-06-20 | | 21. Agente AI Preventivo | v2.2 | 1/1 | ✅ Done | 2026-06-20 | | 22. Pagina Pubblica + Deck | v2.2 | 1/1 | ✅ Done | 2026-06-20 | -| 23+. v2.3 TBD | v2.3 | TBD | 📋 Planned | — | +| 23. Resend Setup + Invio Preventivo | v2.3 | 0/? | Not started | — | +| 24. Schema + Whitelist Admin | v2.3 | 0/? | Not started | — | +| 25. OTP Gate + Sessione | v2.3 | 0/? | Not started | — | + +--- + +## Requirement Coverage (v2.3) + +| Requirement | Phase | +|-------------|-------| +| SEND-01 | Phase 23 | +| SEND-02 | Phase 23 | +| OTP-01 | Phase 24 | +| OTP-02 | Phase 25 | +| OTP-03 | Phase 25 | +| OTP-04 | Phase 25 | +| OTP-05 | Phase 25 | +| OTP-06 | Phase 25 | +| OTP-07 | Phase 25 | + +**Mapped: 9/9. No orphans.** + +--- + +## Dependency Chain (v2.3) + +``` +Phase 23 (Resend config + SDK) + └── Phase 24 (schema DB additive: client_emails + otp_codes) + └── Phase 25 (OTP gate + sessione cookie 30gg) +``` + +Phase 23 first: Resend SDK e variabili d'ambiente sono infrastruttura condivisa con Phase 25 (email OTP). +Phase 24 before Phase 25: le tabelle `client_emails` e `otp_codes` devono essere in prod (via SSH migration) prima del gate. + +--- + +## Implementation Notes (v2.3) + +**Migration constraint:** `client_emails` e `otp_codes` sono nuove tabelle — migration additiva pura. SQL a mano (drizzle-kit generate rotto da Phase 8). Applicare via SSH tunnel PRIMA di pushare il codice dipendente. + +**OTP middleware layer:** Il token middleware esistente (proxy.ts → `/api/internal/validate-token`) rimane invariato. Il gate OTP è uno strato aggiuntivo dopo la validazione del token, non un suo rimpiazzo. + +**Resend shared infra:** La stessa istanza Resend client e le stesse variabili d'ambiente (`RESEND_API_KEY`, `RESEND_FROM`) servono sia Phase 23 (email preventivo) sia Phase 25 (email OTP). Configurare una volta in Phase 23, riusare in Phase 25. + +**Security invariants (Phase 25):** Rate limiting su entrambi gli endpoint OTP; risposta identica per email in whitelist e non; OTP 6 cifre, scade 15 minuti, monouso (`consumed_at` impostato al primo uso); cookie HttpOnly, SameSite=Lax, MaxAge 30 giorni. + +--- +*Roadmap created: 2026-06-21 — v2.3 Email & Accesso* diff --git a/.planning/STATE.md b/.planning/STATE.md index 6c98245..e9e8c45 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -4,10 +4,10 @@ milestone: v2.3 milestone_name: Email & Accesso status: planning stopped_at: "" -last_updated: "2026-06-21T17:22:00.000Z" -last_activity: 2026-06-21 -- Milestone v2.3 started +last_updated: "2026-06-21T11:05:00.000Z" +last_activity: 2026-06-21 -- Roadmap v2.3 created (Phases 23-25) progress: - total_phases: 0 + total_phases: 3 completed_phases: 0 total_plans: 0 completed_plans: 0 @@ -18,28 +18,28 @@ progress: ## Project Reference -See: .planning/PROJECT.md (updated 2026-06-13) +See: .planning/PROJECT.md (updated 2026-06-21) **Core value:** Il cliente apre il link e vede esattamente a che punto è il suo progetto, cosa deve ancora succedere e cosa ha già approvato — senza dover scrivere email per chiedere aggiornamenti. -**Current focus:** Milestone **v2.2 "Sales Loop"** (reset 2026-06-19). North-star: lead in pipeline Kanban → transcript call → agente AI genera preventivo → pagina pubblica `/preventivo/[slug]` → vinto/perso. Piano: `.claude/plans/glittery-sprouting-pudding.md`. Prossimo passo: eseguire Phase 19 (R2) Pipeline CRM Kanban. +**Current focus:** Milestone **v2.3 "Email & Accesso"** (started 2026-06-21). North-star: OTP gate per il portale cliente + invio link preventivo via email — un'unica integrazione Resend condivisa. Roadmap: `.planning/ROADMAP.md` (Phases 23–25). Prossimo passo: `/gsd-plan-phase 23`. ## Current Position -Phase: Not started (defining requirements) +Phase: Not started Plan: — -Status: Defining requirements -Last activity: 2026-06-21 — Milestone v2.3 started +Status: Roadmap created, ready to plan Phase 23 +Last activity: 2026-06-21 — Roadmap v2.3 created (Phases 23–25, 9 requirements mapped) -### Fasi completate (v2.1, storico) +### Fasi completate (v2.2, storico) -Phase 11 (catalogo), Phase 12 (offer editor), Phase 14 (CRM Attio) — consegnate e in prod. 55 servizi reali + tag offerta caricati. +Phase 18 (cleanup), Phase 19 (Kanban CRM), Phase 20 (transcript KB), Phase 21 (AI agent), Phase 22 (deck pubblico) — consegnate e in prod 2026-06-20. ## Performance Metrics **Velocity:** -- Total plans completed: 7 (v2.1) +- Total plans completed: 7 (v2.1) + 9 (v2.2) = 16 totali - Average duration: — - Total execution time: — @@ -68,6 +68,9 @@ Phase 11 (catalogo), Phase 12 (offer editor), Phase 14 (CRM Attio) — consegnat Decisions are logged in PROJECT.md Key Decisions table. Recent decisions affecting current work: +- **[v2.3 2026-06-21] Resend come provider email unico** — PUB-03 (invio preventivo) e AUTH-OTP-01 (OTP gate) condividono la stessa integrazione Resend. Phase 23 configura SDK + env vars, Phase 25 li riusa. +- **[v2.3 2026-06-21] OTP gate è strato aggiuntivo, non rimpiazzo del token middleware** — proxy.ts e `/api/internal/validate-token` rimangono invariati. Il gate OTP interviene dopo la validazione del token, nel rendering della route `/client/[token]/*`. +- **[v2.3 2026-06-21] Migration Phase 24 è additiva pura** — `client_emails` e `otp_codes` sono nuove tabelle. Nessun drop/truncate. SQL a mano (drizzle-kit generate rotto). Applicare via SSH prima del codice dipendente. - **[RESET 2026-06-19] Milestone v2.2 "Sales Loop"** sostituisce le fasi residue v2.1. Decisioni bloccate: (1) URL preventivo = `/preventivo/[slug]` pubblico; (2) tagliare Forecast + quote builder manuale + Phase 15, fondere `/admin/analytics` nella dashboard; (3) portale post-vendita resta core, non si tocca (Phase 13 congelata); (4) agente AI = "io scelgo l'offerta, l'AI personalizza" leggendo i transcript, provider Claude. Piano: `.claude/plans/glittery-sprouting-pudding.md` - [SUPERSEDED dal reset] v2.1 roadmap: Offer Studio (Phases 11-15) sequenced before Proposal AI (Phases 16-17) — clean/fast data UX before the AI builder - Phase 11 bundles catalog database-view UX (OFFER-07..10) with legacy consolidation (OFFER-13) since the new UX should be built on a single unified `services` table, not on top of legacy `service_catalog`/`offer_services` @@ -89,10 +92,9 @@ None yet. ### Blockers/Concerns -- **Migrations (sempre valido)**: ogni fase con schema (es. Phase 20 transcript) DEVE avere la migration applicata a prod via tunnel SSH (`ssh -L 54321:localhost:54321 root@178.104.27.55`, `DATABASE_URL` riscritto a `127.0.0.1:54321`) PRIMA di pushare il codice dipendente. `drizzle-kit generate` rotto → SQL a mano. -- **Phase 21 (AI)**: nessuna integrazione AI ancora nel codice. Servirà chiave Anthropic API in env (Coolify) + decisioni modello/prompt in fase di planning. -- **Debito tecnico (non bloccante)**: tabelle legacy `service_catalog`/`offer_services`/`offer_micro_services` restano come deadweight; `createService`/`serviceSchema` dead code in `catalog/actions.ts`. Script di validazione consolidamento Phase 11 (migrate/validate) mai eseguiti ma OFFER-13 è di fatto soddisfatto (catalogo `services` in uso, 55 servizi reali caricati). -- **[RISOLTO]** ~~Phase 15 bloccata su mockup~~ → fase abbandonata dal reset 2026-06-19. +- **Migrations (sempre valido)**: ogni fase con schema (Phase 24: `client_emails` + `otp_codes`) DEVE avere la migration applicata a prod via tunnel SSH (`ssh -L 54321:localhost:54321 root@178.104.27.55`, `DATABASE_URL` riscritto a `127.0.0.1:54321`) PRIMA di pushare il codice dipendente. `drizzle-kit generate` rotto → SQL a mano. +- **Resend env vars**: `RESEND_API_KEY` e `RESEND_FROM` devono essere aggiunti a Coolify prima di testare Phase 23 in prod. Stessa procedura di `ANTHROPIC_API_KEY` (2026-06-20). +- **Debito tecnico (non bloccante)**: tabelle legacy `service_catalog`/`offer_services`/`offer_micro_services` restano come deadweight; `createService`/`serviceSchema` dead code in `catalog/actions.ts`. ## Deferred Items @@ -100,12 +102,14 @@ Items acknowledged and carried forward from previous milestone close: | Category | Item | Status | Deferred At | |----------|------|--------|-------------| -| v2 | OFFER-14 — Sezioni analitiche stile Notion (psicologia/rating/performance) | Backlog | v2.1 kickoff | -| v2 | AUTH-OTP-01 — Accesso dashboard cliente via OTP email | Design ready, deferred | v2.1 kickoff | +| v2.4 | PROP-03 — Stripe Payment Link su deck pubblico | Backlog | v2.3 kickoff | +| v2.4 | PROP-04 — Auto-provisioning cliente/progetto/fasi al "Vinto" | Backlog | v2.3 kickoff | +| v2+ | Phase 13 — Servizi attivi/ricorrenti post-vendita | Congelata | v2.1 kickoff | +| v2 | OFFER-14 — Sezioni analitiche stile Notion | Backlog | v2.1 kickoff | | v2 | ARCH-01 — Split modulo "compartimento stagno" in deploy separato | Backlog (only if module grows) | v2.1 kickoff | ## Session Continuity -Last session: 2026-06-19T18:05:00.000Z -Stopped at: Phase 19 complete — 19-01-SUMMARY.md scritto, PIPE-01/PIPE-02 verificati, checkpoint umano approvato. Next: /gsd-plan-phase 20 -Resume file: .planning/phases/19-pipeline-crm-kanban/19-01-SUMMARY.md +Last session: 2026-06-21T11:05:00.000Z +Stopped at: Roadmap v2.3 created — Phases 23–25, 9/9 requirements mapped. Next: `/gsd-plan-phase 23` +Resume file: .planning/ROADMAP.md