simone
86c86cd420
docs(21): capture phase context — AI preventivo struttura sezioni fisse, 3 tier
2026-06-20 12:24:52 +02:00
simone
009466ac18
docs(20): commit plan summaries 20-02 and 20-03
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-20 08:58:24 +02:00
simone
9f5a6dcbe5
feat(20-03): add transcript UI — modal, list, expand/collapse, delete
...
TranscriptModal.tsx: new component — call_date input, optional title,
content textarea (min-h-48). Calls addTranscript server action.
LeadDetail.tsx: adds transcripts prop (ClientTranscript[]), TranscriptModal
button in header, "Transcript Call" Card after Storico Attività with
call_date formatted in Italian, 3-line preview with expand/collapse toggle,
Elimina button via deleteTranscript. border-l-4 border-purple-300.
page.tsx: getTranscripts(id) added to Promise.all, transcripts prop
passed to LeadDetail. Build: clean, TypeScript: no errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-20 08:58:06 +02:00
simone
b96b6a2083
feat(20-02): add clientTranscripts data layer
...
schema.ts: clientTranscripts table (id, lead_id/client_id nullable FKs,
title, content NOT NULL, call_date, created_at) + leadsRelations/
clientsRelations updated + clientTranscriptsRelations + TS types.
lead-service.ts: getTranscripts(leadId) — call_date DESC ordering.
actions.ts: addTranscript + deleteTranscript with requireAdmin guard,
Zod validation, and revalidatePath. TypeScript: no errors.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-20 08:55:46 +02:00
simone
a46e8b0bc8
docs(20-01): plan 20-01 complete — migration 0009 applied to prod
...
client_transcripts table verified in production: 7 columns (id, lead_id,
client_id, title, content, call_date, created_at). Applied via SSH tunnel.
Plans 20-02 and 20-03 unblocked.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-20 08:54:06 +02:00
simone
70a101ca98
feat(20-01): add migration 0009_client_transcripts.sql
...
DDL for client_transcripts table: id (nanoid PK), lead_id/client_id
(nullable FKs with ON DELETE CASCADE), title, content (NOT NULL),
call_date (date NOT NULL), created_at (timestamptz). Three indexes on
lead_id, client_id, call_date DESC. APPLY TO PROD via SSH before
pushing schema-dependent code (Plan 20-02/20-03).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-19 18:59:41 +02:00
simone
dc934fb04a
docs(20): create phase plan — Knowledge Base Cliente transcript
...
3 piani: 20-01 migration BLOCKING, 20-02 schema+actions, 20-03 UI.
KB-01 e KB-02 coperti. Wave 1→2→3 sequenziali per vincolo migration-prima-del-codice.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-19 18:52:16 +02:00
simone
3e10f97215
docs(20): capture phase context — Knowledge Base Cliente
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-19 18:26:02 +02:00
simone
b7ff3fe430
docs(phase-19): verification passed — PIPE-01 PIPE-02 complete
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-19 18:10:42 +02:00
simone
bac757a987
docs(phase-19): complete plan 19-01 — LeadsKanbanBoard + toggle PIPE-01/PIPE-02
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-19 18:07:44 +02:00
simone
b0dbd341a9
fix(19-01): add min-h-[300px] to LeadTable scroll container to prevent dropdown clipping
2026-06-19 18:04:28 +02:00
simone
9f8eafffb0
fix(19-01): remove overflow-hidden from LeadTable to allow dropdown overflow
2026-06-19 18:00:15 +02:00
simone
34be9341bb
feat(19-01): wire LeadsViewToggle into leads page + build verified
...
- page.tsx: import LeadsViewToggle from @/components/admin/leads/LeadsViewToggle
- page.tsx: render <LeadsViewToggle leads={leads} options={options} />
- Removed direct LeadsSearch import from page (re-exported via LeadsSearch.tsx)
- Build: Next.js 16.2.6 Turbopack — Compiled successfully, TypeScript clean
2026-06-19 17:49:28 +02:00
simone
607c2578f0
feat(19-01): add LeadsViewToggle with integrated search + list/kanban pill toggle
...
- LeadsViewToggle: client wrapper with useState<list|kanban>, useMemo filtered
- Search input (left) + pill toggle Lista/Kanban (right) on single row
- Filters leads by name/email/company/status/tags across both views
- Search state preserved when switching between Lista and Kanban
- LeadsSearch.tsx: replaced with re-export of LeadsViewToggle (backward compat)
2026-06-19 17:48:31 +02:00
simone
2c67e6fd72
feat(19-01): add LeadsKanbanBoard with @dnd-kit drag-drop between 6 stage columns
...
- 6-column Kanban board: contacted, qualified, proposal_sent, negotiating, won, lost
- DroppableColumn with useDroppable, isOver highlight (border-[#1A463C])
- DraggableLeadCard with useDraggable, opacity-30 on drag, name/company/next_action
- Optimistic update via setLeadStatuses + startTransition + updateLeadField + router.refresh
- Client-side guard: VALID_STAGES check before calling server action (T-19-01)
- DragOverlay dropAnimation={null} ghost card with rotate-1 shadow-xl
- overflow-x-auto wrapper with grid-cols-6 min-w-[1080px]
2026-06-19 17:48:00 +02:00
simone
5e4b2239cb
docs(phase-19): create phase plan — LeadsKanbanBoard + view toggle (PIPE-01, PIPE-02)
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-19 17:37:32 +02:00
simone
84c426e66c
docs(phase-18): complete phase — all 3 plans done, state advanced to Phase 19
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-19 17:17:53 +02:00
simone
044a056480
docs(phase-18): plan 03 — mark CLEAN-01..04 complete, build verified
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-19 16:20:50 +02:00
simone
afe4274de9
docs(18-02): complete plan — analytics consolidated into admin dashboard
2026-06-19 12:09:54 +02:00
simone
c00ec25e48
docs(18-01): complete plan — remove forecast and manual quote builder routes
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-19 12:09:17 +02:00
simone
268f56ccd2
chore(18-01): remove quote builder route, exclusive components, and SendQuoteModal entry point (CLEAN-02)
...
- Delete src/app/admin/quotes/new/page.tsx and actions.ts re-export
- Delete QuoteBuilderForm, OfferSelector, PriceOverrideInput, QuotePreview components
- Rewrite SendQuoteModal: remove "Crea Nuovo" tab and window.location navigation to quotes/new
- Remove stale JSDoc comment referencing /admin/quotes/new from admin-queries.ts
2026-06-19 12:07:48 +02:00
simone
14bdbab880
feat(phase-18): plan 02 — consolidate analytics into admin dashboard
...
- Merge /admin/analytics content (MetricCard, MonthlyChart, time tracking) into /admin
- AdminDashboard now accepts searchParams and year query param
- Add getAnalyticsByYear, getMonthlyCollected, getAvailableYears, getTimeByClient, getTotalTrackedHours queries
- Unify fmtEur to accept number (more robust); update KPI card callers with parseFloat()
- Add MetricCard and fmtSeconds helpers to admin/page.tsx
- YearSelector navigates to /admin?year=Y (was /admin/analytics?year=Y)
- Delete src/app/admin/analytics/page.tsx — /admin/analytics now returns 404
2026-06-19 12:07:31 +02:00
simone
7d884099aa
chore(18-01): remove forecast route, sidebar entry, and revalidatePath calls (CLEAN-01)
...
- Remove Forecast NAV_ITEMS entry and TrendingUp import from AdminSidebar
- Delete src/app/admin/forecast/page.tsx and empty directory
- Remove revalidatePath("/admin/forecast") from assignOfferToProject, removeProjectOffer, updateProjectOfferTotal
2026-06-19 12:05:05 +02:00
simone
b3670d164b
docs(phase-18): create phase plan — cleanup & consolidamento
...
3 piani in 2 wave: 18-01 (rimozioni Forecast+QuoteBuilder),
18-02 (fusione analytics→dashboard), 18-03 (CLEAN-04 verify + build check).
ROADMAP.md aggiornato con plan list Phase 18.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-19 11:51:03 +02:00
simone
10a390239a
docs: reset milestone v2.2 "Sales Loop"
...
Strategic reset after articulating the real sales flow (piano in
.claude/plans/glittery-sprouting-pudding.md). v2.1 delivered Offer Studio
(Phase 11+12) + CRM Attio (Phase 14); residual phases re-scoped:
- Phase 13 (Servizi Attivi) → frozen (touches post-sale portal, kept as-is)
- Phase 15 (Dashboard Revenue) → dropped (analytics merges into dashboard)
- Phase 16/17 (Proposal AI) → re-scoped into v2.2 with transcripts added
New milestone v2.2 = sales loop, Phase 18→22 (R1→R5):
- R1 Cleanup: remove forecast + manual quote builder, merge analytics into dashboard
- R2 Pipeline CRM Kanban (Pipedrive-style)
- R3 Knowledge Base (dated call transcripts per lead/client)
- R4 AI agent (admin picks offer, Claude personalizes proposal from transcripts)
- R5 Public /preventivo/[slug] page + email
New requirements: CLEAN-01..04, PIPE-01/02, KB-01/02, AI-01/02, PUB-01/02/03.
Updated ROADMAP, REQUIREMENTS, STATE, PROJECT. No code changed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-19 11:37:08 +02:00
simone
43238341c1
feat: service offer tags, catalog cleanup, offer editor filter
...
- Import 58 offer membership tags for all 55 services (entity_type="services")
via scripts/import-service-offer-tags.ts (already run on prod)
- ServiceTable: remove Categoria column, rename Tag → Offerta; QuickAddRow
no longer has a category field (offer tags set post-creation)
- offer-queries: getOfferEditorData fetches offerTags per service (join on
tags WHERE entity_type="services") and exposes them in OfferEditorData
- OfferEditorClient: filter chips above "Servizi Inclusi" — Tutti / Entry
Offer / Signature Offer / Retainer Offer, derived from actual tag data
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-18 21:58:34 +02:00
simone
696a95950c
chore: add Notion service import scripts
...
scripts/reset-and-import-services.ts — deletes 3 legacy test services,
imports 55 services from Notion "DB Offerta: Attività SC" CSV export
(Signature Offer / Entry Offer / Retainer Offer, with fase metadata).
scripts/import-services-notion.ts — standalone idempotent version.
Run via SSH tunnel with DATABASE_URL pointed at 127.0.0.1:54321.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-18 21:46:17 +02:00
simone
27e8706e39
fix(offer-editor): show all services regardless of offer category
...
offer_macros.category ("Entry Offer") and services.category are different
taxonomies — filtering one by the other always returns empty. Remove the
client-side category filter; all active services are always shown.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-18 18:35:37 +02:00
simone
4f7e0033c4
fix(offer-editor): fix category bug, add ripristina, always-saveable
...
- Bug: remove server-side category pre-filter from getOfferEditorData;
services now loaded unfiltered, client-side filter handles display →
changing category no longer wipes the service list
- Fix tierTotals to use full service map (not filtered subset) so totals
stay correct when category is edited mid-session
- Add Ripristina button for archived offers (calls toggleOfferArchived false)
- Remove canSave gate: always allow saving; button is "Salva Bozza"
(secondary style, stays on page) when no services assigned, "Salva
Offerta" (primary, redirects to list) when at least one tier has services
- Show "Bozza salvata." inline feedback after draft save
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-18 18:25:50 +02:00
simone
56f9fd1d07
docs(phase-12): complete phase execution
...
Phase 12 (Offer Editor: Tier A/B/C, Tag & Prezzo Pubblico) fully executed
and verified. All 5 plans complete, build gate passed, 5/5 requirements
confirmed in codebase (OFFER-11, OFFER-15, OFFER-16, OFFER-17, OFFER-18).
- 12-REVIEW.md: 0 critical, 6 warnings, 4 info (advisory, non-blocking)
- 12-VERIFICATION.md: all requirements PASS
- REQUIREMENTS.md: OFFER-11/15/16/17/18 → Complete
- STATE.md: advanced to Phase 13 as next
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-18 17:24:19 +02:00
simone
9a74e5ccfa
docs(phase-12): update tracking after wave 4
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-15 10:31:07 +02:00
simone
791a6e64b1
chore: merge executor worktree (worktree-agent-a44f854f45ac76582)
2026-06-15 10:28:07 +02:00
simone
605dc323b6
chore: merge executor worktree (worktree-agent-a26188c3b00c610ed)
2026-06-15 10:27:55 +02:00
simone
a486d27a2b
docs(12-04): append self-check results to plan summary
2026-06-15 10:26:58 +02:00
simone
ca3712612f
docs(12-04): add plan summary for offer list page redesign
2026-06-15 10:26:38 +02:00
simone
b7203c3da2
docs(12-05): complete offer editor detail page plan
...
- Add 12-05-SUMMARY.md documenting OfferEditorClient + edit route
2026-06-15 10:26:24 +02:00
simone
7df4b9c74a
feat(12-04): build OfferListClient with category filter, archive toggle, card grid
...
- Category filter chips ("Tutti" + dynamic categoryOptions), active/inactive
styling per UI-SPEC (#1A463C / #e5e7eb)
- "Mostra offerte archiviate" toggle (default off), filters via useMemo
- Responsive card grid (1/2/3 cols) linking to /admin/offers/[id]/edit,
with category badge and "Archiviata" indicator
- "+ Nuova Offerta" inline form calling createOfferMacro via useTransition
+ router.refresh()
- Empty state with "Nessuna offerta" / "Inizia creando la tua prima offerta"
2026-06-15 10:25:15 +02:00
simone
68dc1b605b
feat(12-04): rewrite /admin/offers page.tsx as new list page entry point
...
- Replace legacy macro/micro/offer_services CRUD page with thin server
component fetching getOfferListCards() + getOfferFieldOptions()
- Delegate rendering to new OfferListClient (Task 2)
2026-06-15 10:25:03 +02:00
simone
8c5c918304
feat(12-05): build offer editor client component
...
- Add OfferEditorClient: full editor for /admin/offers/[id]/edit
- Categoria/Ticket single-select (OptionSelect) + Tipo/Obiettivo
multi-select with on-the-fly creation (OptionMultiSelect)
- Services matrix (A/B/C checkboxes) pre-filtered by macro.category,
with live "Totale Servizi" recalculation via useMemo (OFFER-11)
- Independent manual "Prezzo Pubblico" per tier (OFFER-16)
- 5-field "Promessa di Trasformazione" block via EditableCell (OFFER-17)
- Salva Offerta / Annulla / Archivia actions wired to saveOfferEditor,
toggleOfferArchived and renameOfferOption (OFFER-15)
2026-06-15 10:25:02 +02:00
simone
8e0e4b9c59
feat(12-05): create offer editor route server component
...
- Add src/app/admin/offers/[id]/edit/page.tsx as async server component
- Fetches getOfferEditorData(id) + getOfferFieldOptions() via Promise.all
- Calls notFound() when offer id does not exist
- Delegates rendering to OfferEditorClient
2026-06-15 10:24:49 +02:00
simone
e46607d217
docs(phase-12): update tracking after wave 3
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-15 10:19:52 +02:00
simone
f01fa347c4
chore: merge executor worktree (worktree-agent-acd37263857560e21)
2026-06-15 10:19:13 +02:00
simone
8bdc854a6a
docs(12-03): complete offer editor query layer & server actions plan
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-15 10:18:46 +02:00
simone
a372c613e2
feat(12-03): add offer editor server actions
...
- saveOfferEditor(macroId, payload): persists macro scalars, per-tier
upsert (tier_letter Zod-validated A/B/C), offer_tier_services
delete-then-reinsert, and Tipo/Obiettivo tags delete-then-reinsert,
all in one call
- toggleOfferArchived(macroId, archived) for OFFER-18
- addOfferTag/removeOfferTag/renameOfferOption for Tipo/Obiettivo/
Categoria/Ticket dimensions, mirroring catalog option-pool pattern
- createOfferMacro(formData) — Plan 04 "+ Nuova Offerta" target
- scripts/verify-12-03-actions.ts documents the 9 spec'd test cases
(typecheck-only, requireAdmin needs a request context)
2026-06-15 10:17:07 +02:00
simone
0d742f2328
feat(12-03): add offer editor query layer
...
- getOfferListCards() for Plan 04 list page (category + archive status)
- getOfferEditorData(macroId) returns macro fields, A/B/C tiers with
assignedServiceIds + computed servicesTotal, category-filtered
availableServices, and tipoTags/obiettivoTags
- getOfferFieldOptions() for categoria/ticket/tipo/obiettivo select pools
- scripts/verify-12-03-queries.ts documents the 5 spec'd test cases
(typecheck-only, no test runner configured, prod DB not mutated)
2026-06-15 10:15:19 +02:00
simone
e2d6e97168
docs(phase-12): update tracking after wave 2 checkpoint
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-15 09:50:23 +02:00
simone
d4c89b4170
docs(12-02): apply migration 0008 to production (blocking checkpoint complete)
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-15 09:50:23 +02:00
simone
b8f14fad4d
docs(phase-12): update tracking after wave 1
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-14 21:22:37 +02:00
simone
827604084e
chore: merge executor worktree (worktree-agent-ab7d5b1ee10efadff)
2026-06-14 21:22:10 +02:00
simone
b80f0563b8
docs(12-01): fix markdown lint formatting in summary
...
- Add blank lines around headings and lists per MD022/MD032
2026-06-14 21:21:37 +02:00