docs(v2.2): close planning docs — SUMMARY.md 21+22, req Complete
- 21-01-SUMMARY.md: agente AI Opus 4.8, schema Zod, proposals table - 22-01-SUMMARY.md: deck 20+ slide 100vh, accept/reject, PUB-03 deferred - REQUIREMENTS.md: PIPE/KB/AI-01/02 + PUB-01/02 → Complete; PUB-03 deferred - ROADMAP.md: Phase 20/21/22 → [x] con date - STATE.md: status complete, percent 100, 5/5 fasi Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
---
|
||||
phase: 21-agente-ai-generazione-preventivo
|
||||
plan: "01"
|
||||
status: complete
|
||||
completed_at: "2026-06-20"
|
||||
requirements_satisfied:
|
||||
- AI-01
|
||||
- AI-02
|
||||
---
|
||||
|
||||
# Plan 21-01 Summary: Agente AI — Generazione Preventivo
|
||||
|
||||
## What Was Built
|
||||
|
||||
Sistema completo di generazione preventivo AI: l'admin seleziona un lead/cliente e un'offerta, il sistema legge i transcript della call e chiama Claude Opus 4.8 per generare una bozza di preventivo strutturata in JSON. La bozza viene salvata nel DB come `draft`, l'admin la rivede e la pubblica.
|
||||
|
||||
## Key Files
|
||||
|
||||
### Created
|
||||
- `src/lib/proposal/schema.ts` — Zod schema `ProposalContent` (vision, problems 3-5, solutions, scope, deliverables, timeline, stagesRecap, comparisonMatrix)
|
||||
- `src/lib/proposal/agent.ts` — `generateProposalContent()`: chiama Claude Opus 4.8, valida output Zod, gestisce JSON wrapping in backtick
|
||||
- `src/lib/proposal/assemble.ts` — `assembleProposal()`: fonde content AI + offerta DB (snapshot prezzi) + profilo consulente in `AssembledProposal`
|
||||
- `src/lib/proposal/profile.ts` — `CONSULTANT_PROFILE`: fonte di verità statica (bio, facts, testimonianze, legal, nextSteps) — editare direttamente per aggiornare
|
||||
- `src/lib/proposal/queries.ts` — `listProposals`, `getProposalById`, `getProposalBySlug` con join leads/clients/offer_macros
|
||||
- `src/app/admin/preventivi/actions.ts` — `generateProposalDraft`, `publishProposal`, `updateProposalTitle`, `deleteProposal` (server actions)
|
||||
- `src/app/admin/preventivi/page.tsx` — lista preventivi admin con stato (bozza/pubblicato/accettato/rifiutato)
|
||||
- `src/app/admin/preventivi/genera/page.tsx` + `GeneraProposalForm.tsx` — form builder con pre-fill `?lead_id=X` da LeadDetail
|
||||
- `src/app/admin/preventivi/[id]/page.tsx` — review bozza: titolo editabile, pubblica, elimina
|
||||
- `src/db/migrations/0010_proposals.sql` — `CREATE TABLE IF NOT EXISTS proposals` (id, slug, lead_id, client_id, offer_macro_id, title, content jsonb, model, state, selected_tier, accepted_at immutabile, client_email, client_notes)
|
||||
|
||||
### Modified
|
||||
- `src/db/schema.ts` — tabella `proposals` + `proposalsRelations` + tipi `Proposal`/`NewProposal`
|
||||
- `src/components/admin/AdminSidebar.tsx` — voce "Preventivi" + CTA globale lime "Genera preventivo"
|
||||
- `src/components/admin/leads/LeadDetail.tsx` — pulsante "Genera preventivo" → `/admin/preventivi/genera?lead_id=X`
|
||||
|
||||
## Architecture Decisions
|
||||
|
||||
| Decisione | Scelta | Motivo |
|
||||
|-----------|--------|--------|
|
||||
| Output AI | JSON strutturato → Zod validate | Coerenza visiva garantita, zero rischio HTML rotto |
|
||||
| Storage | `content jsonb` snapshot completo | Parser automatico postgres-js, type-safe, immutabile |
|
||||
| Profile | File `profile.ts` hardcoded | No UI necessaria v1, editing diretto semplice |
|
||||
| Modello | `claude-opus-4-8` | Qualità copywriting strategico superiore |
|
||||
|
||||
## Requirements Verified
|
||||
|
||||
- AI-01: ✅ Admin seleziona cliente+offerta → AI legge transcript + offerta → genera bozza personalizzata
|
||||
- AI-02: ✅ Admin rivede ed edita il titolo della bozza, la pubblica o elimina prima dell'invio
|
||||
|
||||
## Post-Deploy Steps Completed
|
||||
|
||||
- Migration 0010 applicata a prod via SSH tunnel (2026-06-20 14:29)
|
||||
- `ANTHROPIC_API_KEY` configurata in Coolify (2026-06-20 — fix chiave invalida)
|
||||
@@ -0,0 +1,56 @@
|
||||
---
|
||||
phase: 22-pagina-pubblica-preventivo
|
||||
plan: "01"
|
||||
status: complete
|
||||
completed_at: "2026-06-20"
|
||||
requirements_satisfied:
|
||||
- PUB-01
|
||||
- PUB-02
|
||||
known_gaps:
|
||||
- PUB-03 (email Resend — non implementata, deferred to backlog)
|
||||
---
|
||||
|
||||
# Plan 22-01 Summary: Pagina Pubblica Preventivo + Deck
|
||||
|
||||
## What Was Built
|
||||
|
||||
Pagina pubblica `/preventivo/[slug]` che presenta la proposta generata come deck interattivo di 20+ slide navigabili (frecce, tasti keyboard, dot navigator). Il cliente sceglie il tier A/B/C e accetta/rifiuta dalla pagina; l'esito si riflette nel DB con `accepted_at` immutabile. PUB-03 (invio email Resend) non implementato — il link va condiviso manualmente.
|
||||
|
||||
## Key Files
|
||||
|
||||
### Created
|
||||
- `src/app/preventivo/[slug]/page.tsx` — server component pubblico; gestisce stati: draft (blocca accesso), published (mostra + accept), accepted/rejected (mostra con stato)
|
||||
- `src/app/preventivo/[slug]/actions.ts` — `acceptProposal` (guard `accepted_at` immutabile + `selected_tier` validato A/B/C), `rejectProposal`
|
||||
- `src/components/public/proposal/ProposalDeck.tsx` — deck client component: navigazione keyboard (←/→), dot cliccabili, topbar fissa (titolo + counter), bottombar fissa (frecce + dots); `h-screen overflow-hidden` per 100vh per slide
|
||||
- `src/components/public/proposal/sections/` — 20 componenti slide:
|
||||
- CoverSection, VisionSection, IndexSection
|
||||
- ChapterDivider (×5), StrategistSection, FactsSection, TestimonialsSection
|
||||
- ProblemNodeSection, SynthesisDiagramSection
|
||||
- SolutionNodeSection, SolutionSynthesisSection
|
||||
- ScopeSection, DeliverablesSection, TimelineSection
|
||||
- PricingSection, StagesRecapSection, ComparisonMatrixSection
|
||||
- NextStepsSection, AcceptSection, ClosingSection
|
||||
|
||||
## Architecture Decisions
|
||||
|
||||
| Decisione | Scelta | Motivo |
|
||||
|-----------|--------|--------|
|
||||
| Layout | `h-screen overflow-hidden` per slide | Nessun scroll di pagina, navigazione slide-by-slide |
|
||||
| Navigazione | Keyboard + dots + click frecce | Universale, funziona su desktop e touch |
|
||||
| Accettazione | `accepted_at` immutabile (guard server action) | Pattern coerente con `deliverables.approved_at` |
|
||||
| Tier selezione | Radio A/B/C prima dell'accettazione | Cliente sceglie l'opzione, l'esito è univoco |
|
||||
| Email | Non implementata (PUB-03) | Scope minimo, link condiviso manualmente per ora |
|
||||
|
||||
## Requirements Verified
|
||||
|
||||
- PUB-01: ✅ Proposta visibile come pagina pubblica HTML a `/preventivo/[slug]`, deck 20+ slide
|
||||
- PUB-02: ✅ Cliente accetta/rifiuta dalla pagina; `state` + `accepted_at` + `selected_tier` aggiornati nel DB; admin vede esito nella lista preventivi
|
||||
|
||||
## Known Gap
|
||||
|
||||
- **PUB-03 — Email Resend**: il link preventivo non viene inviato automaticamente. Va copiato dall'admin e condiviso manualmente (es. via WhatsApp/email). Da implementare nella prossima milestone come prima feature.
|
||||
|
||||
## Fix Post-Deploy
|
||||
|
||||
- 2026-06-20: fix `h-screen overflow-hidden` su tutte le slide (erano `min-h-screen`, causavano scroll di pagina)
|
||||
- 2026-06-20: `ANTHROPIC_API_KEY` mancante in Coolify — aggiunta via PHP artisan + redeploy
|
||||
Reference in New Issue
Block a user