docs(planning): archivia v2.1/v2.2/v2.3 e documenta v2.4

.planning/ documentava in dettaglio cio che era vecchio e per niente cio
che e in produzione: le fasi 11-22 (v2.1 e v2.2, chiuse a giugno) erano
ancora in phases/ mentre v1.0 e v2.0 stavano gia in milestones/, e il
lavoro degli ultimi due mesi - gate OTP e ciclo di vita dei retainer, cioe
quello che gira su hub.iamcavalli.net - non aveva nessuna cartella.

- phases/{11,12,14} -> milestones/v2.1-phases/, phases/{18..22} ->
  milestones/v2.2-phases/. Ora phases/ contiene solo la milestone in
  corso, che e quello che state.cjs conta per il progresso
- v2.1-ROADMAP.md ricostruito: era l'unica milestone senza archivio,
  interrotta dal reset del 19/06 e mai chiusa formalmente
- v2.3-ROADMAP.md + v2.3-REQUIREMENTS.md: v2.3 e stata eseguita fuori dal
  ciclo GSD, non esistono PLAN/SUMMARY per fase. L'archivio E la doc
- REQUIREMENTS.md riscritto per v2.4 con il backlog reale
- phases/13 e phases/26: SUMMARY ricostruiti da commit, migration e
  STATUS.md. 26 e il primo numero libero
- research/: cancellate 4 varianti dello stesso PITFALLS e FEATURES/
  SUMMARY, superati da PROJECT.md. Diverse anti-feature erano ormai
  contraddette dai fatti (il Kanban e stato costruito in Phase 19,
  l'email in v2.3, il time tracking esiste)
- cancellati UI-RULES.md e DESIGN-SYSTEM.md (CLAUDE.md li dichiara
  superseded: impongono l'inverso della regola attuale) e HANDOFF.md,
  fermo al 13/06
- SECURITY-*.md -> security/: audit chiuso, ma i report restano la doc di
  cosa e stato ruotato e perche
- PROJECT.md/MILESTONES.md/ROADMAP.md allineati: milestone corrente v2.4,
  sessione OTP 90gg non 30, migrazioni fino alla 0016

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-08 22:38:36 +02:00
parent 187550fedf
commit f7eb7eec23
86 changed files with 1659 additions and 2859 deletions
+24 -96
View File
@@ -4,10 +4,10 @@
-**v1.0 Client Portal & Offer System** — Phases 16 (shipped 2026-06-10) — [archive](milestones/v1.0-ROADMAP.md)
-**v2.0 Business Operations Suite** — Phases 710 (shipped 2026-06-13) — [archive](milestones/v2.0-ROADMAP.md)
-**v2.1 Offer Studio + CRM** — Phases 1114 parziale (chiuso 2026-06-19, reset → v2.2)
-**v2.1 Offer Studio + CRM** — Phases 11, 12, 14 (chiusa per reset 2026-06-19) — [archive](milestones/v2.1-ROADMAP.md)
-**v2.2 Sales Loop** — Phases 1822 (shipped 2026-06-20) — [archive](milestones/v2.2-ROADMAP.md)
-**v2.3 Email & Accesso** — Phases 2325 (shipped 2026-07-29)
- 🔨 **v2.4 Post-vendita** — Phase 13 (in corso)
-**v2.3 Email & Accesso** — Phases 2325 (shipped 2026-07-29) — [archive](milestones/v2.3-ROADMAP.md)
- 🔨 **v2.4 Post-vendita** — Phases 13 + 26 (entrambe in produzione)
## Phases
@@ -15,10 +15,10 @@
<summary>✅ v1.0 + v2.0 + v2.1 (Phases 117) — SHIPPED / CHIUSE</summary>
Vedi archivi:
- `milestones/v1.0-ROADMAP.md` — Phases 16
- `milestones/v2.0-ROADMAP.md` — Phases 710
- Phases 11, 12, 14 — Offer Studio + CRM Attio (shipped in prod)
- Phases 13, 15, 16, 17 — congelate/abbandonate/ri-scopate in v2.2
- `milestones/v2.1-ROADMAP.md` — Phases 11, 12, 14 shipped; 15/16/17 abbandonate o ri-scopate; **Phase 13 ripresa in v2.4**
</details>
@@ -35,57 +35,27 @@ Archivio completo: [milestones/v2.2-ROADMAP.md](milestones/v2.2-ROADMAP.md)
</details>
### 🔨 v2.3 — Email & Accesso (Phases 2325)
<details>
<summary>✅ v2.3 Email & Accesso (Phases 2325) — SHIPPED 2026-07-29</summary>
- [x] **Phase 23: Resend Setup** — SDK Resend + `src/lib/mailer.ts` + template OTP *(l'invio preventivo è stato rinviato a v2.4 il 2026-07-28)*
- [x] **Phase 24: Schema + Whitelist Admin** — Tabelle `client_emails` e `otp_codes`, admin UI gestione whitelist + revoca sessioni
- [x] **Phase 25: OTP Gate + Sessione**Gate OTP completo, sessione **90gg**, rate limiting, no enumeration
- [x] Phase 23: Resend Setup — SDK + `src/lib/mailer.ts` + template OTP *(SEND-01/02 rinviati al backlog il 2026-07-28)*
- [x] Phase 24: Schema + Whitelist Admin `client_emails`, `otp_codes`, UI whitelist + revoca sessioni (migr. 0015)
- [x] Phase 25: OTP Gate + Sessione — gate completo, sessione **90gg**, rate limiting, no enumeration
**Shipped 2026-07-29** (commit `27da969`), verificata end-to-end su `hub.iamcavalli.net`. SEND-01/02 rinviati a backlog.
Shipped col commit `27da969`, verificata end-to-end su `hub.iamcavalli.net`.
Archivio completo: [milestones/v2.3-ROADMAP.md](milestones/v2.3-ROADMAP.md)
### 🔨 v2.4 — Post-vendita (Phase 13)
</details>
- [ ] **Phase 13: Ciclo di vita dei servizi ricorrenti**`project_offers.status` + `end_date` (migr. 0016), forecast che si ferma davvero, comandi Sospendi/Riattiva/Cessa nella tab Offerte, stato dell'abbonamento visibile al cliente.
### 🔨 v2.4 — Post-vendita (Phases 13 + 26)
Fuori scope di questo giro, rimandato: tracciamento dei canoni mese per mese (serve una tabella nuova — `payments` è protetta e la sua riscalatura è pensata per i piani una tantum).
- [x] **Phase 13: Ciclo di vita dei servizi ricorrenti**`project_offers.status` + `end_date` (migr. 0016), forecast che si ferma davvero, comandi Sospendi/Riattiva/Cessa nella tab Offerte, stato dell'abbonamento visibile al cliente. ✅ **prod 2026-08-01** (`5177a37`) — [13-SUMMARY.md](phases/13-ciclo-vita-servizi-ricorrenti/13-SUMMARY.md)
- [x] **Phase 26: Anteprima admin del portale + toggle password**`?preview=1` con sessione Auth.js valida apre il portale di un cliente in sola lettura, senza gate OTP. ✅ **prod 2026-08-08** (`09a5b1f`, `187550f`) — [26-SUMMARY.md](phases/26-anteprima-admin-e-login/26-SUMMARY.md)
## 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
**Nessuna fase aperta.** Il prossimo lavoro va scelto dal backlog in
[REQUIREMENTS.md](REQUIREMENTS.md) — i candidati principali sono RET-06 (canoni
mensili tracciabili, richiede una tabella nuova perché `payments` è protetta) e
DEBT-01 (debito design, ~40 file).
## Progress
@@ -95,10 +65,9 @@ Fuori scope di questo giro, rimandato: tracciamento dei canoni mese per mese (se
| 710. Unified Catalog → CRM Pipeline | v2.0 | 12/12 | ✅ Done | 2026-06-13 |
| 11. Catalog Database-View UX | v2.1 | 4/4 | ✅ Done | 2026-06-13 |
| 12. Offer Editor Tier A/B/C | v2.1 | 5/5 | ✅ Done | 2026-06-18 |
| 13. Workspace Servizi Attivi | v2.1 | — | ❌ Congelata | — |
| 14. CRM Attio-style & Fix | v2.1 | 3/3 | ✅ Done | 2026-06-14 |
| 15. Dashboard Revenue Stats | v2.1 | — | ❌ Abbandonata | — |
| 1617. Proposal AI originale | v2.1 | — | Ri-scopata in v2.2 | — |
| 1617. Proposal AI originale | v2.1 | — | ♻️ Ri-scopata in v2.2 | — |
| 18. Cleanup & Consolidamento | v2.2 | 3/3 | ✅ Done | 2026-06-19 |
| 19. Pipeline CRM Kanban | v2.2 | 1/1 | ✅ Done | 2026-06-19 |
| 20. Knowledge Base Cliente | v2.2 | 3/3 | ✅ Done | 2026-06-20 |
@@ -107,50 +76,9 @@ Fuori scope di questo giro, rimandato: tracciamento dei canoni mese per mese (se
| 23. Resend Setup | v2.3 | 1/1 | ✅ Done | 2026-07-28 |
| 24. Schema + Whitelist Admin | v2.3 | 1/1 | ✅ Done | 2026-07-28 |
| 25. OTP Gate + Sessione | v2.3 | 1/1 | ✅ Done | 2026-07-29 |
| 13. Ciclo di vita servizi ricorrenti | v2.4 | 1/1 | 🔨 In corso | — |
| 13. Ciclo di vita servizi ricorrenti | v2.4 | 1/1 | ✅ Done | 2026-08-01 |
| 26. Anteprima admin + login | v2.4 | 1/1 | ✅ Done | 2026-08-08 |
---
*Roadmap aggiornata: 2026-08-08 — v2.3 archiviata, v2.4 documentata a posteriori*
## 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, come consegnata):** rate limiting su entrambi gli endpoint OTP; risposta identica per email in whitelist e non; OTP 6 cifre, scade 15 minuti, monouso (`consumed_at` al primo uso), max 5 tentativi; cookie HttpOnly + Secure + SameSite=Lax, **MaxAge 90 giorni** (non 30: modificato il 2026-07-28, compensato dalla revoca admin), per-cliente. Il gate sta in cima alla `page`, non nel layout — vedi la lezione in `STATE.md`.
---
*Roadmap created: 2026-06-21 — v2.3 Email & Accesso*