docs(11): create phase plan — 4 plans, 4 waves
Catalog Database-View UX & Legacy Consolidation (OFFER-07/08/09/10/13) - 11-01: tags table + polymorphic junction + additive legacy migration - 11-02: getAllServices tag join + inline-edit/tag/quick-add server actions - 11-03: EditableCell + TagMultiSelect components - 11-04: database-view ServiceTable + client-side search Verified by gsd-plan-checker (VERIFICATION PASSED). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+56
-176
@@ -1,215 +1,95 @@
|
||||
---
|
||||
gsd_state_version: 1.0
|
||||
milestone: v2.0
|
||||
milestone_name: Business Operations Suite
|
||||
milestone: v2.1
|
||||
milestone_name: milestone
|
||||
status: executing
|
||||
last_updated: "2026-06-11T19:00:00Z"
|
||||
last_activity: 2026-06-11
|
||||
stopped_at: Phase 11 context gathered
|
||||
last_updated: "2026-06-13T13:00:38.635Z"
|
||||
last_activity: 2026-06-13 -- Phase 11 planning complete
|
||||
progress:
|
||||
total_phases: 5
|
||||
completed_phases: 4
|
||||
total_plans: 11
|
||||
completed_plans: 11
|
||||
percent: 80
|
||||
total_phases: 11
|
||||
completed_phases: 8
|
||||
total_plans: 37
|
||||
completed_plans: 30
|
||||
percent: 81
|
||||
---
|
||||
|
||||
# Project State
|
||||
|
||||
## Project Reference
|
||||
|
||||
See: .planning/PROJECT.md (updated 2026-05-09)
|
||||
See: .planning/PROJECT.md (updated 2026-06-13)
|
||||
|
||||
**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:** Phase 11 — Catalog Database-View UX & Legacy Consolidation
|
||||
|
||||
## Current Position
|
||||
|
||||
Phase: 10-crm-pipeline-activity-logging (redo complete, deployed)
|
||||
Plans: 07 (complete) | 08 (complete) | 09-01..03 (complete) | 10-01..03 (complete, redeployed 2026-06-11)
|
||||
Status: Phase 7 ✓ | Phase 8 ✓ | Phase 9 ✓ | Phase 10 ✓ (staged redo after rollback)
|
||||
Last activity: 2026-06-11T19:00:00Z — Phase 10 staged redo deployed; production DB migrations 0001/0003/0004/0005 applied
|
||||
Phase: 11 of 17 (Catalog Database-View UX & Legacy Consolidation)
|
||||
Plan: — (not yet planned)
|
||||
Status: Ready to execute
|
||||
Last activity: 2026-06-13 -- Phase 11 planning complete
|
||||
|
||||
## What Was Built (Phase 10 — CRM Pipeline & Activity Logging, redo)
|
||||
Progress: [░░░░░░░░░░] 0%
|
||||
|
||||
### Root cause of the original Phase 10 production crash (resolved)
|
||||
## Performance Metrics
|
||||
|
||||
Production Postgres (Coolify container) had **no migrations applied after 0000** — `services`, `leads`, `offer_phases`, `offer_phase_services`, `quotes` did not exist. Phase 7/8/9 summaries said "migration pending connectivity" and were never followed up. Any page querying those tables 500'd: catalog (services), quote builder + /quote/[token] (quotes), and after Phase 10 deploy also dashboard (FollowUpWidget → leads). The Phase 10 rollback only masked the dashboard symptom.
|
||||
**Velocity:**
|
||||
|
||||
**Fix (2026-06-11):** migrations 0001+0003+0004+0005 applied atomically (single transaction, additive-only, verified zero DROP/TRUNCATE) via SSH → docker exec psql on container `xwkk0040w0kk0gsgcgog8owk`, db `clienthub`. Protected rows verified intact post-migration (4 clients, 5 projects, 13 payments, 6 phases). `/quote/[token]` 500 → 404 (correct behavior) confirmed.
|
||||
- Total plans completed: 0 (v2.1)
|
||||
- Average duration: —
|
||||
- Total execution time: —
|
||||
|
||||
### Delivered (redo commits 5aa6614 + 008a434)
|
||||
**By Phase:**
|
||||
|
||||
- **Stage A** (`5aa6614`): deps `@radix-ui/react-dialog`, `date-fns` + shared `ui/dialog.tsx`, `ui/form.tsx`
|
||||
- **Stage B**: production DB schema aligned (see above) — script `scripts/push-phase10-migration.ts` for future reuse
|
||||
- **Stage C** (`008a434`): schema.ts CRM tables (leads expansion, activities, reminders + relations), lead-service/lead-validators, `/admin/leads` list+detail+actions, LeadTable/LeadDetail/LeadForm, LogActivityModal, SendQuoteModal, FollowUpWidget on dashboard, sidebar link
|
||||
| Phase | Plans | Total | Avg/Plan |
|
||||
|-------|-------|-------|----------|
|
||||
| - | - | - | - |
|
||||
|
||||
## What Was Built (Phase 9 — Quote Builder UI & Public Pages)
|
||||
**Recent Trend:**
|
||||
|
||||
### 09-01: Quote Validators and Service Layer ✓
|
||||
- Last 5 plans: —
|
||||
- Trend: —
|
||||
|
||||
- **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
|
||||
*Updated after each plan completion*
|
||||
|
||||
### 09-02: Admin Quote Builder UI ✓
|
||||
## Accumulated Context
|
||||
|
||||
- **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)
|
||||
### Decisions
|
||||
|
||||
### 09-03: Public Quote Page with Token-Gated Access & Rate Limiting ✓
|
||||
Decisions are logged in PROJECT.md Key Decisions table.
|
||||
Recent decisions affecting current work:
|
||||
|
||||
- **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)
|
||||
- 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`
|
||||
- Phase 13 (Workspace — Servizi Attivi) is independent of Phases 11/12 — can execute in parallel order if useful, but numbered after for narrative flow
|
||||
- Phase 15 (Dashboard Revenue Stats / DASH-11) is isolated and BLOCKED on user-provided mockup; no other phase depends on it — can be deferred/skipped without blocking Phase 16/17
|
||||
- Phase 16/17 split: schema/automation (payment link field + auto-provisioning) first, then AI builder + public page redesign + email — keeps the AI-dependent work last
|
||||
|
||||
## What Was Built (Phase 8 — Quote Builder Schema Foundation) ✓
|
||||
### Pending Todos
|
||||
|
||||
### 08-01: Offer Phases & Quote Tables Schema ✓
|
||||
[From .planning/todos/pending/ — ideas captured during sessions]
|
||||
|
||||
- **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
|
||||
None yet.
|
||||
|
||||
### 08-02: Migration & Validation Scripts ✓
|
||||
### Blockers/Concerns
|
||||
|
||||
- **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
|
||||
- **Phase 15 (DASH-11)**: Blocked pending dashboard mockup from user. Do not start until mockup provided; safe to skip in execution order without impacting Phase 16/17.
|
||||
- **Migrations**: Per CLAUDE.md, every phase touching schema (11 legacy consolidation, 13 recurring-revenue tracking, 16 payment link + provisioning) MUST have its migration applied to prod via SSH+docker exec BEFORE pushing dependent code.
|
||||
|
||||
## 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 |
|
||||
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 | ARCH-01 — Split modulo "compartimento stagno" in deploy separato | Backlog (only if module grows) | v2.1 kickoff |
|
||||
|
||||
## Session Continuity
|
||||
|
||||
Last session: 2026-06-11T19:00:00Z
|
||||
Phase 10 staged redo complete: production DB migrations applied (0001/0003/0004/0005), CRM module deployed.
|
||||
Dangling work recovered from `phase10-wip` branch (anchor of reflog commit 8e2752a — branch can be deleted once redo verified in production).
|
||||
Lesson recorded: migrations are applied manually in this project — every deploy touching schema MUST apply the migration to prod BEFORE pushing code.
|
||||
|
||||
## Operator Next Steps
|
||||
|
||||
### Immediate
|
||||
|
||||
- Verify in browser (authenticated): /admin (FollowUpWidget), /admin/leads, /admin/catalog, /admin/quotes/new
|
||||
- Re-run `/gsd-plan-phase 11` and `/gsd-plan-phase 12` (planning folders never committed, must be regenerated)
|
||||
- Optionally cherry-pick sidebar "App shortcuts" dangling commit 5d75752 if still wanted
|
||||
|
||||
### 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
|
||||
Last session: 2026-06-13T10:02:08.473Z
|
||||
Stopped at: Phase 11 context gathered
|
||||
Resume file: .planning/phases/11-catalog-database-view-ux-legacy-consolidation/11-CONTEXT.md
|
||||
|
||||
Reference in New Issue
Block a user