Re-scoped Offer Editor (Tier A/B/C, Tag & Prezzo Pubblico) per 2026-06-14 user decision: 5-plan wave structure (schema migration -> prod apply checkpoint -> query/action layer -> list + detail editor UI), OFFER-12 CSV/Notion import deferred.
6.0 KiB
phase, phase_name, source, status
| phase | phase_name | source | status |
|---|---|---|---|
| 12 | offer-editor-tier-tag-prezzo-pubblico | user mockups + decisions (2026-06-14) | decisions-locked |
Phase 12 — Context (User Decisions)
Catturato da 2 mockup utente + risposte dirette il 2026-06-14. Questo documento è autorevole per il planner: dove confligge con la roadmap originale ("drag&drop + CSV"), vince questo. La Phase 12 è stata ri-scoped da "Offer Composition Drag&Drop & CSV Import" a "Offer Editor — Tier A/B/C, Tag & Prezzo Pubblico".
Decisioni bloccate
| # | Decisione | Valore |
|---|---|---|
| D-1 | Scope | Editor offerte completo (lista + dettaglio). Import CSV/Notion (ex OFFER-12) rimandato a fase futura. |
| D-2 | UX composizione tier | Matrice di checkbox servizio × tier (A/B/C), NON drag&drop puro. Totale servizi live per colonna/tier. @dnd-kit usato solo (eventualmente) per riordinare le righe. |
| D-3 | Fonte servizi | Catalogo unificato services (Phase 11), non il legacy offer_services. |
| D-4 | Filtro servizi per categoria | Il servizio porta già, a livello di catalogo, la designazione di categoria offerta (entry / signature / retainer). L'editor mostra/pre-filtra nella matrice i servizi pertinenti alla categoria dell'offerta in modifica. |
| D-5 | Prezzo | Per ogni tier: Totale servizi (auto-somma dei servizi spuntati) + Prezzo Pubblico (manuale, indipendente). Coerente con la decisione PROJECT.md "prezzi pacchetti per-preventivo, non da catalogo". |
| D-6 | Schema | Solo additivo (Data Safety LOCKED). Riusare le tabelle offerte esistenti, non ricostruire. |
Modello dati (intento — il planner produce la migration esatta)
Mappatura mockup → schema esistente (src/db/schema.ts):
- Offerta →
offer_macros(esiste:internal_name,public_name,transformation_promise,sort_order). Aggiunte additive previste: descrizione breve, flagis_archived, campi strutturati della promessa di trasformazione (Cliente Ideale / Risultato / tempo / Pain / Metodo). - Tier A/B/C →
offer_micros(esiste:macro_id,cumulative_price,duration_months, ...). Aggiunte additive previste: lettera tier (A|B|C) epublic_price(prezzo pubblico manuale). Un'offerta = una macro con (fino a) 3 micro-tier. - Matrice servizi × tier → junction tier ↔
services. La junction legacyoffer_micro_servicespunta aoffer_services; non modificarla. Approccio additivo consigliato: nuova tabella di junction (es.offer_tier_services: tier_id →offer_micros.id, service_id →services.id) così da non toccare dati legacy e agganciare il catalogo unificato. Il planner decide il nome/struttura esatti; deve restare additivo. - Tag multi-dimensione (categoria / ticket / tipo / obiettivo) → riusare la tabella polimorfica
tags(entity_type,entity_id,name) di Phase 11 conentity_type = "offer_macros"(o simile). Le 4 dimensioni vanno distinte: il planner valuta se serve un campodimensionadditivo sulla tabellatags, oppure colonne single-select dedicate suoffer_macrosper categoria/ticket (singole)- tag multipli per tipo/obiettivo. Da chiarire in research; resta additivo.
- Designazione categoria del servizio (entry/signature/retainer, D-4): verificare se va su
services.category(single-select già esistente), su un tag, o su una nuova colonna additiva dedicata. NON sovrascrivere la semantica attuale diservices.category/services.fasese già usata diversamente in/admin/catalog— il planner verifica l'uso corrente prima di scegliere.
UI (riferimento mockup)
Lista offerte (/admin/offers ridisegnata): card filtrabili per categoria (Entry / Signature /
Retainer Offer come chip colorati), ogni card = nome custom + breve descrizione + chip categoria;
toggle "mostra offerte archiviate"; bottone "+ Nuova Offerta".
Editor offerta: nome custom editabile in alto; chip Categoria + Ticket; chip Tipo (Audit / Done For You) e Obiettivo (Primo Acquisto / Up Scala Valore / Lead Generation); tabella "servizi inclusi" con colonne A / B / C e checkbox per cella, prezzo del servizio a sinistra; riga "Totale dei servizi" (auto) e "Prezzo Pubblico" (manuale) per ogni tier; blocco "Promessa di Trasformazione" strutturato (Aiuto Cliente Ideale / A ottenere Risultato / in tempo / Senza Pain / Grazie a Metodo); bottone "Salva Offerta".
Stile: continuità con Phase 11 (vista database Notion-like, palette brand #1A463C / #DEF168, EditableCell,
OptionMultiSelect/tag, server actions requireAdmin-guarded). Vedi 12-UI-SPEC.md (da rigenerare su
questo scope).
Vincoli (da CLAUDE.md / PROJECT.md)
- Data Safety LOCKED: migration solo additive su
clients/projects/payments/phases; nessun drop/truncate. Anche le tabelle offerte vanno estese, non ricostruite. - Migration manuali:
drizzle-kit generateè non funzionante (snapshot fuori sync da migration 0001) — scrivere SQL a mano seguendo la convenzione 0003-0007. Applicare a prod via SSH+docker exec PRIMA di pushare codice che dipende dal nuovo schema (DB prod firewalled, raggiungibile solo via SSH). quote_itemsmai esposti via client API. L'editor offerte è admin-only (/admin/*, sessione Auth.js).
Fuori scope (questa fase)
- Import CSV / import da Notion (OFFER-12, rimandato).
- Sezioni analitiche Notion (psicologia/rating/performance — OFFER-14, v2).
- Collegamento offerta→preventivo/pagamento (Proposal AI, Phase 16/17).
- Pagina pubblica dell'offerta (Phase 17).
Domande risolte (erano aperte nel primo RESEARCH)
- Placement composer →
/admin/offersridisegnata (lista + editor). ✓ - Persistenza offerta → macro = offerta, micro = tier A/B/C (riuso additivo). ✓
- Tag audit CSV → N/A (import rimandato). ✓
- Duplicati / parsing CSV → N/A (import rimandato). ✓
- Prezzi servizi editabili → no inline qui: il tier ha totale auto + prezzo pubblico manuale; i
prezzi unitari restano gestiti nel catalogo
services(Phase 11). ✓