--- gsd_state_version: 1.0 milestone: v2.0 milestone_name: Business Operations Suite status: executing last_updated: "2026-06-11T06:28:00Z" last_activity: 2026-06-11 progress: total_phases: 5 completed_phases: 1 total_plans: 8 completed_plans: 2 percent: 25 --- # 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: 09-quote-builder-client-acceptance (Planning just finished) Plans: 07 (complete) | 08 (planned, ready exec) | 09 (planned, ready exec) Status: Phase 7 executed ✓ | Phase 8-9 planned & ready for execution Last activity: 2026-06-11T06:40:00Z — Phase 9 planning complete (3 plans, 2 waves) ## 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-11T04:21:50Z Phase 7 Plan 1 execution complete (Unified Service Catalog schema + backfill scripts). Database migration ready but pending external connectivity. Next: Phase 7 Plan 2 planning or database migration when connectivity restored. ## Operator Next Steps ### Immediate (Phase 7 Database Sync) - Run database migration when Postgres is reachable: `scripts/push-services-migration.ts`, `scripts/migrate-services.ts`, `scripts/validate-services-migration.ts` - Verify validation script exits 0: `npx tsx scripts/validate-services-migration.ts` ### Next Phase (Phase 8 Planning) - Phase 8 focus: Offer Phase service assignments and quote template builder - Dependencies on Phase 7: ✓ services table ready, ✓ admin catalog CRUD operational - Start Phase 8 planning: `/gsd-plan-phase 8`