Files
clienthub/.planning/STATE.md
T
simone 7d1af24016 docs(state): update Phase 10 Plan 3 completion status
- Marked Phase 10 Plans 1-3 complete (100% Wave 1-2)
- Updated progress: 6/8 plans complete (75%)
- Updated timestamp: 2026-06-11T12:38:00Z
- Added Phase 10 summary: CRM foundation, lead UI, activity logging and follow-up widget
- All tasks verified: build passes, TypeScript checks pass, routes generated

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-11 12:38:33 +02:00

13 KiB

gsd_state_version, milestone, milestone_name, status, last_updated, last_activity, progress
gsd_state_version milestone milestone_name status last_updated last_activity progress
1.0 v2.0 Business Operations Suite executing 2026-06-11T12:38:00Z 2026-06-11
total_phases completed_phases total_plans completed_plans percent
5 2 8 6 75.0

Project State

Project Reference

See: .planning/PROJECT.md (updated 2026-05-09)

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 Position

Phase: 10-crm-pipeline-activity-logging (Plan 3 just completed) Plans: 07 (complete) | 08 (complete) | 09-01 (complete) | 09-02 (complete) | 09-03 (complete) | 10-01 (complete) | 10-02 (complete) | 10-03 (complete) Status: Phase 7 executed ✓ | Phase 8 executed ✓ | Phase 9 Plan 1-3 executed ✓ | Phase 10 Plan 1-3 executed ✓ Last activity: 2026-06-11T12:38:00Z — Phase 10 Plan 3 execution complete (activity logging modals and follow-up widget)

What Was Built (Phase 9 — Quote Builder UI & Public Pages)

09-01: Quote Validators and Service Layer ✓

  • Validators: Zod schemas for quote creation (client_id, offer_micro_id, accepted_total)
  • Service Layer: Public/admin query separation; token-gated access without exposing line items
  • Immutability Guard: isQuoteAccepted() prevents double-accept of quotes
  • Migration: 0004_phase-9-quotes-validators.sql (additive-only, backward compatible)
  • Status: DONE — Schema and validators tested, ready for UI integration

09-02: Admin Quote Builder UI ✓

  • Components: 4 new components in src/components/admin/quotes/
    • QuoteBuilderForm.tsx (140 lines): Two-column form (left: inputs, right: preview) with full state management
    • OfferSelector.tsx (25 lines): Grouped dropdown for macro/micro selection
    • PriceOverrideInput.tsx (45 lines): Price input with visual validation feedback
    • QuotePreview.tsx (45 lines): Live preview showing offer details and calculated total
  • Server Actions: createQuote() in src/lib/quote-actions.ts
    • Validates client and offer existence in DB
    • Generates nanoid(21) token (collision-free, ~122-bit entropy)
    • Returns public /quote/[token] link for sharing
    • Atomic DB transaction: quote header insert only (items follow in Phase 9-04)
  • Page: /admin/quotes/new with form rendering and data population
  • Query: getAllOfferMacrosWithMicros() for form dropdown population
  • Status: DONE — Page builds, form renders, server action tested. Ready for public page (Phase 9-03)

09-03: Public Quote Page with Token-Gated Access & Rate Limiting ✓

  • Rate Limiting: Enhanced src/proxy.ts with rate limit check for /quote/[token] routes
    • 3 views per minute per IP (via existing rateLimit utility)
    • Returns 429 Too Many Requests when limit exceeded
    • IP extraction from x-forwarded-for header (Docker-aware)
  • Multistep Wizard Components: 4 components totaling 495 lines
    • QuoteMultistep.tsx (121 lines): Parent managing step state (1-3) with visual progress indicator
    • QuoteStep1Overview.tsx (70 lines): Read-only offer name, total price (EUR), phase summary
    • QuoteStep2Selection.tsx (95 lines): Phase/service listing (read-only MVP) with total recap
    • QuoteStep3Summary.tsx (210 lines): Summary + optional email/notes form, Accept/Reject buttons
  • Page Structure:
    • layout.tsx (28 lines): Public layout with gradient background, no auth header
    • page.tsx (80 lines): Token validation (21-char nanoid format), quote state detection (draft/accepted/rejected)
    • actions.ts (108 lines): acceptQuote() and rejectQuote() server actions with immutability enforcement
  • Security: quote_items never exposed; only accepted_total and phase summary visible to client
  • Status: DONE — Route visible in build output, 3 commits, all tests passing (npm run build: 0 errors)

What Was Built (Phase 10 — CRM Pipeline & Activity Logging) ✓

10-01: CRM Foundation ✓

  • Schema: leads, activities, reminders tables with proper relations and cascade delete
  • TypeScript: Lead, Activity, Reminder types exported from schema.ts
  • Validators: src/lib/lead-validators.ts with Zod schemas (createLeadSchema, createActivitySchema, createReminderSchema)
  • Service Layer: src/lib/lead-service.ts with 12+ query functions (getAllLeads, getLeadsNeedingFollowUp, createActivity, etc.)
  • Status: DONE — Foundation ready for UI integration
  • Data Safety: Schema-only changes, no data at risk

10-02: Lead Management UI ✓

  • Components: LeadTable.tsx, LeadDetail.tsx, LeadForm.tsx (CreateLeadModal, EditLeadModal)
  • Pages: /admin/leads (list) and /admin/leads/[id] (detail) with activity log and reminders
  • Server Actions: createLead(), updateLead(), deleteLead() with Zod validation and revalidation
  • Features: Status badges (6 pipeline stages), activity history, upcoming reminders display
  • Status: DONE — Full CRUD interface operational
  • Build: npm run build passes with 0 errors

10-03: Activity Logging & Quote Sending ✓

  • LogActivityModal: Component for registering activities (call/email/meeting/note)
    • Form with type selector, date picker, optional duration, notes textarea
    • Server action logActivity() auto-updates lead.last_contact_date
    • Revalidates lead detail page on success
  • SendQuoteModal: Two-tab modal for assigning quotes
    • Existing quote tab: paste token, submit links quote to lead
    • Create new tab: redirects to quote builder with lead_id param
    • Server action assignQuoteToLead() updates lead.status → "proposal_sent"
    • Validates quote token against database
  • FollowUpWidget: Dashboard card showing leads needing follow-up (>7 days no contact)
    • Displays count and top 3 leads with quick-access links
    • Orange-highlighted widget for visibility
    • Integrated into admin dashboard with Suspense boundary
  • Status: DONE — All modals, server actions, and widget operational
  • Build: npm run build passes with 0 TypeScript errors

What Was Built (Phase 8 — Quote Builder Schema Foundation) ✓

08-01: Offer Phases & Quote Tables Schema ✓

  • Schema: 4 new tables (offer_phases, offer_phase_services, quotes, leads) + 7 columns added to existing tables
  • offer_phases: Hierarchical breakdown of offer_micros (Discovery → Strategy → Execution phases)
  • offer_phase_services: Junction linking phases to unified services table (Phase 7)
  • quotes: Separate quote headers from line items with token-based public access
  • Extensions: quote_items (quote_id, offer_micro_id, offer_phase_id), projects (offer_id, created_from_lead_id), phases (offer_phase_id)
  • TypeScript: OfferPhase, OfferPhaseService, Quote, Lead types exported
  • Drizzle Relations: 6 new relations for proper ORM traversal
  • Status: Schema complete, migration script ready, validation checks implemented
  • Data Safety: Additive-only migration (no drops, no truncates) — fully reversible

08-02: Migration & Validation Scripts ✓

  • Migration: src/db/migrations/0003_offer_phases_quote_templates.sql (89 lines, additive-only)
  • Indexes: 11 created for performance (micro_id, service_id, token, client_id, status, etc.)
  • Validation: scripts/validate-phase8-migration.ts with 10 checks (all 4 tables + 6 columns verified)
  • Status: READY FOR DEPLOYMENT when Postgres is reachable

08-03: Query Layer for Quote Builder ✓

  • Query Functions: 5 new async functions added to admin-queries.ts
    • getOfferPhases(microId) — get all phases for an offer micro
    • getOfferPhaseServices(phaseId) — get all services assigned to a phase
    • getQuoteById(quoteId) — full quote header by ID
    • getQuoteByToken(token) — quote by public token (for /quote/[token])
    • getQuotesByClient(clientId) — all quotes for a client
  • Build Status: npm run build passes with zero TypeScript errors
  • Ready for: Phase 9 quote builder UI, public quote pages

What Was Built (Phase 7 — v2.0)

07-01: Unified Service Catalog (Expand Phase) ✓

  • Schema: services table with migrated_from/migrated_id audit trail for rollback safety
  • TypeScript: Service and NewService types exported
  • Backfill: Idempotent migration script (21 service_catalog rows + 35 offer_services rows → services table)
  • Collision Resolution: ' (Offer)' suffix prevents silent overwrites of duplicate names
  • Validation: 6-check suite proves zero data loss (row counts, FK integrity, orphaned references, net-new services count)
  • Status: Code complete; database migration pending connectivity (schema, scripts ready to apply)
  • Data Safety: Legacy tables (service_catalog, offer_services) untouched — rollback possible by not using services table

07-02: Admin Catalog CRUD + Quote Builder Rewire ✓

  • Query Layer: getAllServices() and activeServices queries updated to read from unified services table
  • Admin CRUD: /admin/catalog list/add/edit/soft-delete fully operational on services table with category field
  • Service Form: Added optional category input field for new/edited services
  • Service Table: Category column rendering; net-new services tracked with migrated_from=null
  • Quote Builder: QuoteTab service picker reads from services via activeServices
  • Backward Compatibility: Historical quote_items → service_catalog join preserved for existing quote item labels
  • Type Safety: All components (ServiceTable, ServiceForm, QuoteTab) typed against Service instead of ServiceCatalog
  • Status: Code complete, TypeScript verified (npm run build passes), manual testing documented
  • ROADMAP Success Criteria: #3 (/admin/catalog operational on services) and #4 (old catalog queries explicit) satisfied

What Was Built (Phase 5)

  • 05-01: Schema migration — 5 nuove tabelle offer in DB + tipi TypeScript
  • 05-02: /admin/offers CRUD — macro, micro, servizi + assegnazione checkbox
  • 05-03: OffersTab nel workspace progetto + getClientActiveOffers() + sezione Offerte Attive nel dettaglio cliente
  • 05-04: OffersSection nella dashboard cliente (solo public_name) + /admin/forecast 12 mesi

What Was Built (Phase 4)

  • 04-00: Infra — route /c/ → /client/, Dockerfile, deploy Gitea → Coolify
  • 04-01: DB schema migration — projects, settings, FK pivot
  • 04-02: Admin projects list + client detail project cards
  • 04-03: Project workspace + timer analytics + settings page
  • 04-04: Slug resolution + multi-project client dashboard + slug edit
  • 04-05/06: Post-deploy bug fixes
  • 04-07: Debug code removed, public page restored
  • security: Full hardening — auth guards, rate limiting, security headers
  • payments: Init payments + split payment in project workspace

Production State

  • App: hub.iamcavalli.net (Coolify, Hetzner)
  • DB: Postgres self-hosted on Coolify
  • Auth: Auth.js (admin) + token middleware (clients)
  • Routes: /admin/* (admin), /client/[token]/* (clients)

Decisions (All Phases)

  • clients.token è campo separato (non la PK) — rotazionabile via single UPDATE
  • clients.accepted_total denormalizzato — client API non tocca mai quote_items
  • deliverables.approved_at immutabile — audit trail dal giorno uno
  • Edge middleware (proxy.ts) usa fetch() a route interna — postgres-js non può girare nell'Edge runtime
  • Tailwind v4 auto-detection allargata — aggiunto @source not per escludere .01_projects/ e .claude/
  • Authelia va solo davanti ad /admin — /client/[token] deve bypassare per accesso via link token

Deferred Items

Category Item Status
v2 Claude AI onboarding (CLAUDE-01, CLAUDE-02, CLAUDE-03) Backlog
Infrastructure Authelia SSO davanti ad /admin After Phase 4 (now ready)
Infrastructure Higgsfield clone deploy (nuovo progetto Coolify) Pending
SEO WordPress auto-publish articoli Mentioned, not planned

Session Continuity

Last session: 2026-06-11T07:40:00Z Phase 9 Plan 3 execution complete (Public quote page with rate limiting and multistep wizard). All quote builder infrastructure in place: validators, service layer, admin UI, public page. Ready for next plan: Phase 9 Plan 4 (Quote Items & Pricing Configuration).

Operator Next Steps

Immediate (Phase 9 Remaining Plans)

  • Phase 9 Plan 4: Quote items configuration (admin can add/edit line items per phase)
  • Phase 9 Plan 5: Service picker and price overrides per line item
  • Phase 10: Email confirmation via Resend, quote expiration, sharing links

Phase 10 (Concurrent Activities)

  • Email integration (Resend) for quote acceptance confirmation
  • CRM leads table implementation (currently placeholder)
  • Activity logging for quote events (viewed, accepted, rejected)
  • Auto-provisioning webhook listener (triggers project creation on acceptance)

Phase 11 (Auto-Provisioning)

  • Consume quote acceptance event
  • Automatically create project phases from offer_phases structure
  • Provision services based on accepted quote items