Files
simone 03898f2a59 docs(planning): v2.1 milestone setup + Phase 11 context/patterns
- Archive v2.0 phases (07-10) under .planning/milestones/
- v2.1 REQUIREMENTS/ROADMAP (Phases 11-17: Offer Studio + Proposal AI)
- DESIGN-SYSTEM.md (database-view UI contract for Phases 11-14)
- Phase 11 CONTEXT, DISCUSSION-LOG, PATTERNS

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 15:07:06 +02:00

9.7 KiB

Phase 11: Catalog Database-View UX & Legacy Consolidation - Context

Gathered: 2026-06-13 Status: Ready for planning

## Phase Boundary

Trasformare /admin/catalog (tabella services) in una vista database stile Notion/Airtable — inline edit su ogni cella, tag multi-select con creazione al volo, quick-add row, filtro/ricerca istantanei (client-side) — e consolidare i dati storici di service_catalog e offer_services/offer_micro_services dentro services in modo additivo, senza perdita (verificabile via conteggio righe).

Esplicitamente FUORI scope per Phase 11 (deferiti a fasi successive, vedi <deferred>):

  • Rewiring di /admin/offers e OffersSection (dashboard cliente) per leggere da services — Phase 12
  • Composizione drag&drop offerte e import CSV — Phase 12
  • Riuso del sistema tag per i lead — Phase 14 (schema pronto ora, UI lead dopo)
## Implementation Decisions

Consolidamento Legacy (service_catalog, offer_services)

  • D-01: Migrazione additiva (pattern Phase 7): copia le righe di service_catalog e offer_services dentro services, popolando migrated_from/migrated_id per audit trail. Zero behavior change a /admin/offers e OffersSection — quelle UI restano sulle tabelle legacy (offer_services/offer_micro_services), che NON vengono toccate/droppate.
  • D-02: Le righe migrate da offer_services ricevono automaticamente il tag "Offerta" (tag normale, vedi D-08) per distinguerle nella tabella unificata dai servizi a costo interno.
  • D-03: /admin/offers resta status quo — continua a creare nuove voci in offer_services/offer_micro_services come oggi. Il rewiring per leggere/scrivere da services è Phase 12 (già dipende da "catalogo unificato e tabellare").
  • D-04: Verifica "senza perdita" (OFFER-13, conteggio righe) tramite script/log one-shot durante la migrazione (come Phase 7) — nessun indicatore permanente in /admin/catalog.

Sistema Tag

  • D-05: Nuova tabella tags + junction polimorfica (entity_type + entity_id, pattern simile a comments in src/db/schema.ts) — costruita ora per essere riusata da Phase 14 (CRM-09, tag sui lead) senza rifare lo schema.
  • D-06: Pool di tag scoped per entity_type — i tag del catalogo (services) e i tag dei lead (futuro) sono pool separati, anche se condividono la tabella tags. Il dropdown "+" per creare/assegnare un tag mostra solo i tag dell'entity_type corrente.
  • D-07: Colore badge derivato deterministicamente dal nome del tag (hash → palette fissa 6-8 colori pastello, da .planning/DESIGN-SYSTEM.md) — nessuna colonna color in tags.
  • D-08: Il tag "Offerta" (D-02) è un tag normale del pool services — rinominabile/eliminabile dall'utente come ogni altro tag, nessuna logica di protezione/system-tag.

Campo category

  • D-09: services.category (testo libero, esistente) resta un campo separato, accanto ai tag multi-select — due dimensioni di classificazione indipendenti (categoria primaria + tag flessibili). NON viene migrato/fuso nei tag.
  • D-10: Servizi senza category restano senza tag corrispondente — nessun tag di default ("Senza categoria"/"Generale") viene creato.

Tabella database-view — colonne e comportamenti

  • D-11: "Descrizione" resta una colonna piena della tabella — testo troncato con ellipsis, click-to-edit inline (textarea espansa al click), stesso pattern EditableCell delle altre colonne. Non esce dalla riga principale.
  • D-12: Quick-add row (OFFER-09, "nome + invio"): scrivere solo il nome e premere invio crea il servizio con unit_price = 0. La riga diventa immediatamente una riga normale ed editabile — il prezzo (mostrato "€0,00") si corregge inline subito dopo, click sulla cella prezzo.
  • D-13: Servizi disattivati (active=false): restano visibili, attenuati (opacità ridotta, comportamento attuale di ServiceTable.tsx), ma ordinati in fondo alla tabella sotto una riga divisoria che li separa visivamente dai servizi attivi.
  • D-14: Nessuna colonna "azioni" per riga. Lo stato attivo/disattivo diventa una cella inline (toggle/checkbox cliccabile, stesso pattern EditableCell). Tutte le modifiche avvengono via click-to-edit sulle celle — stile Notion/Airtable puro, zero bottoni per riga.

Claude's Discretion

  • Implementazione esatta dei componenti EditableCell e TagMultiSelect (entrambi previsti in .planning/DESIGN-SYSTEM.md, non ancora costruiti — command/popover shadcn da valutare).
  • Mapping esatto dei campi nella migrazione offer_servicesservices (es. priceunit_price, transformation_descriptiondescription).
  • Verifica del JOIN quote_itemsservice_catalog in src/lib/admin-queries.ts (righe 335/343, 531/539) — oggi l'unico consumer rimasto di service_catalog, possibile disallineamento con quote_items.service_id (che secondo schema.ts referenzia services.id, non service_catalog.id). Il researcher deve verificare se il join è ancora funzionante; se rotto, trattarlo come bugfix separato e a basso rischio, non bloccante per i success criteria di Phase 11.
  • Palette colori esatta per i badge tag (6-8 pastello, da DESIGN-SYSTEM.md) e algoritmo hash nome→colore.
  • Posizionamento/stile esatto della riga divisoria "inattivi" (D-13).

<canonical_refs>

Canonical References

Downstream agents MUST read these before planning or implementing.

Requisiti e roadmap

  • .planning/REQUIREMENTS.md — sezione "Offer Studio — Catalogo & Offerte (v1)": OFFER-07, OFFER-08, OFFER-09, OFFER-10, OFFER-13 sono i requisiti di questa fase
  • .planning/ROADMAP.md — sezione "Phase 11: Catalog Database-View UX & Legacy Consolidation" per goal e success criteria

Design contract (UI)

  • .planning/DESIGN-SYSTEM.mdvincolante: direzione ClickUp/Pipedrive flat, token brand invariati (#1A463C/#DEF168/#e5e7eb/etc.), pattern tabella (riga ~40px, inline edit con ring-1 ring-primary, badge tag a rotazione colori, quick-add row, header sticky), componenti da costruire (EditableCell, TagMultiSelect), checklist pre-delivery (contrasto, focus ring, transizioni 150-250ms, responsive)

Decisioni di progetto

  • .planning/PROJECT.md — sezione "Key Decisions": ordine Offer Studio→Proposal AI, "Catalogo/Offerte UX = database view custom (non Notion-clone)", catalogo unificato services da Phase 7

No external specs beyond questi — requisiti/decisioni catturati sopra.

</canonical_refs>

<code_context>

Existing Code Insights

Reusable Assets

  • src/components/ui/badge.tsx, select.tsx, input.tsx, table.tsx — base per costruire EditableCell e TagMultiSelect (DESIGN-SYSTEM.md)
  • src/lib/admin-queries.tsgetAllServices() — query layer esistente su services, da estendere con join sulla nuova tabella tags
  • src/db/schema.tscomments table (polimorfico entity_type/entity_id) — precedente diretto per la junction tags (D-05)
  • src/db/schema.tsservices.migrated_from/migrated_id (Phase 7) — pattern di audit trail da riusare per la migrazione service_catalog/offer_servicesservices

Established Patterns

  • src/app/admin/catalog/actions.ts (createService/updateService/toggleServiceActive) — pattern requireAdmin() + validazione zod + revalidatePath("/admin/catalog"), da estendere per inline edit (probabilmente una action per campo o un'action generica updateServiceField)
  • Migrations manuali via SSH+docker exec, applicate a prod PRIMA del push del codice dipendente (vedi .planning/HANDOFF.md)

Integration Points

  • src/app/admin/catalog/page.tsxServiceTable/ServiceForm (src/components/admin/catalog/) — punto di sostituzione principale per la nuova tabella database-view
  • offer_phase_services (Phase 8, già esistente) collega offer_phasesservices — riferimento utile per Phase 12 quando comporrà offerte direttamente da services
  • src/lib/admin-queries.ts righe ~250-345 e ~520-545 — JOIN legacy su service_catalog per label quote_items (vedi Claude's Discretion)

Tabelle legacy coinvolte (stato attuale)

  • service_catalog (src/db/schema.ts:170) — solo consumer rimasto: JOIN per label quote_items legacy in admin-queries.ts
  • offer_services + offer_micro_services (src/db/schema.ts:259-283) — ATTIVI: usati da /admin/offers (src/app/admin/offers/, src/lib/offer-queries.ts) e da OffersSection lato cliente (src/lib/client-view.ts, cumulative_price)

</code_context>

## Specific Ideas
  • "compartimenti stagni" + Data Safety LOCKED (CLAUDE.md) → ogni migrazione di questa fase è additiva, nessun drop/truncate di service_catalog, offer_services, offer_micro_services
  • DESIGN-SYSTEM.md è stato prodotto appositamente per questa fase (e per 12-14) via skill ui-ux-pro-max — è il contratto visivo, non solo un suggerimento
## Deferred Ideas
  • Rewiring completo di /admin/offers + OffersSection per leggere/scrivere da services (invece di offer_services/offer_micro_services) → Phase 12 (Offer Composition Drag&Drop & CSV Import), che già dipende dal "catalogo unificato e tabellare" prodotto da questa fase
  • Riuso della tabella tags/junction polimorfica per i lead (CRM-09) → Phase 14 (CRM Attio-style & Fix) — schema già pronto (D-05/D-06), serve solo la UI lato lead
  • Fix del JOIN quote_itemsservice_catalog se il researcher lo trova rotto → bugfix separato, non parte dei success criteria di Phase 11

None — discussion stayed within phase scope (oltre ai punti sopra, già tracciati per fasi specifiche).


Phase: 11-catalog-database-view-ux-legacy-consolidation Context gathered: 2026-06-13