La roadmap era ferma al 2026-08-08 e diceva ancora "nessuna fase aperta" mentre
v2.5 era gia' partita e Phase 27 era a meta'; REQUIREMENTS.md era ancora quello
di v2.4. STATE.md invece era corretto — segno che aggiornare solo quello non
basta. Da qui la divisione dei ruoli, ora esplicita in testa a ogni file:
- STATE.md orientamento breve (99 righe): dove sta cosa, come funziona il
motore, i blocchi vivi. Niente narrativa.
- ROADMAP.md tutte le fasi 1->30, con lo stato di ciascuna
- REQUIREMENTS.md i 25 requisiti di v2.5 (AUD-01..25) e il backlog
- STATUS.md l'unica narrativa lunga: lezioni e note tecniche
v2.4 chiusa e archiviata in milestones/v2.4-REQUIREMENTS.md.
Decisione nuova: il documento di restituzione usa il design system dell'area
admin ("Quiet Luxury"), non una tipografia sua — token semantici, Plus Jakarta
Sans, Geist Mono per metriche e date, StatusBadge per gli impatti. Sostituisce
la deroga tipografica prevista dal piano. I font sono gia' self-hostati da
next/font/google, quindi la CSP font-src 'self' e' soddisfatta senza lavoro, e
il documento non aggiunge debito a DEBT-01 perche' nasce gia' a token.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
8.2 KiB
Requirements: ClientHub v2.5 Audit
Definiti: 2026-08-16 (piano approvato) · rivisti: 2026-08-18 (motore) Core Value della milestone: L'imprenditore paga un'analisi del suo sito e riceve un documento che gli dice, con numeri misurati, cosa non funziona e cosa costa — non un elenco di quaranta punti generato da un tool gratuito.
Milestone precedente: v2.4 Post-vendita, chiusa 2026-08-08.
Piani di riferimento (fuori dal repo, in ~/.claude/plans/):
dovremmo-fare-una-cosa-woolly-puddle.md (documento, editor, template) +
vorrei-solo-farti-capire-radiant-valley.md (motore — sostituisce §6/§7 del primo).
Il prodotto
Tre livelli venduti, che sono configurazioni di un unico documento, non tre documenti:
| Livello | Blocchi inclusi |
|---|---|
| Radiografia | 1, 2, 2b, 3, 4, 5, 8, 9 |
| Prima/Dopo | + 6 (il redesign), 6b (cosa il redesign non risolve) |
| Rotta | + 7 (le ottimizzazioni, con priorità e impegno in giornate) |
I blocchi non pertinenti non esistono nel DOM, non sono nascosti via CSS.
Requisiti
Motore (Phase 27)
- AUD-01: Schema additivo per audit, finding, ottimizzazioni, rubrica, esiti, run e visite — migration
0017_audits.sql, in prod 2026-08-18 - AUD-02: La rubrica del motore (264 voci falsificabili) vive in
checklist_items, non nel documento — in prod 2026-08-18 - AUD-03: Le fonti raccolgono rilevazioni, non stime: PageSpeed (153 audit sul DOM renderizzato), CrUX (utenti reali), Wayback, RDAP, robots/sitemap/JSON-LD, header —
src/lib/audit/sources/, provato sul campo 2026-08-18, non ancora pushato - AUD-04: Ogni fonte fallisce in modo non fatale e dice perché: "non ha risposto" e "ha risposto che non ci sono dati" sono informazioni diverse
- AUD-05: Quando CrUX non ha dati di campo il documento lo dice ("i visitatori non sono abbastanza numerosi perché Google raccolga dati"), non lascia un buco —
notaincrux.ts; il caso "zero dati" resta da vedere su un sito vero - AUD-06: Ogni output di modello è validato con Zod,
safeParse, fallimento duro — nessun loop di riparazione (precedente:src/lib/proposal/schema.ts) - AUD-07: Quattro sub-agent in parallelo (checklist, visivo, storico, tecnico) più un sintetizzatore che incrocia le loro osservazioni in un solo finding con più evidenze indipendenti
- AUD-08: Massimo 10 finding, ordinati per impatto su tre soli valori (
alto|medio|basso); la sfumatura sta nell'ordine dentro il gruppo - AUD-09: Disciplina sui numeri imposta nel prompt di sistema — un numero entra nel documento solo se misurato, e ogni numero consegnato è rintracciabile in
audit_runs.raw - AUD-10: Fan-out con tetto di concorrenza e retry con backoff sulle 429/529 di Anthropic
- AUD-11: Heartbeat a ogni passo su
audit_runs; una run senza battito va inerrore "Rilancia" riparte dall'ultimo passo completato (un redeploy Coolify uccide un job in corso)
Storage immagini (Phase 28)
- AUD-12: Volume persistente Coolify su
/app/uploads, lettura da/api/uploads/[...path]con guardia sul path traversal, whitelist MIME e limite di dimensione - AUD-13: Due immagini caricate a mano per audit (hero prima e dopo del redesign, JPG ≤ 512 KB); due scritte dalla pipeline (screenshot mobile e desktop da PageSpeed)
Editor admin (Phase 29)
- AUD-14: Creazione manuale di un audit (livello, profilo, URL, cliente/lead). L'ingresso Whop è predisposto nello schema (
origin,external_ref) ma non costruito - AUD-15: Editor a payload intero (modello:
admin/offers/actions.ts) che salva sempre, anche a metà — tutti i campi di contenuto sono nullable, la validazione di completezza scatta solo alla consegna - AUD-16: Riordino di finding e ottimizzazioni con
@dnd-kit/sortable, con re-sync degli id dei figli - AUD-17: Il blocco 8 (La direzione) resta manuale, foglio bianco — è il blocco che giustifica il prezzo; se diventa formula il cliente lo sente
- AUD-18: Il registro delle visite è visibile nell'editor, in ordine cronologico
Documento pubblico (Phase 30)
- AUD-19:
/audit/[slug]— pagina privata,X-Robots-Tag: noindex, nofollow, rate limit sul matcher diproxy.ts - AUD-20: Il template è congelato alla creazione (
template_version): migliorare il documento tocca gli audit successivi, mai quelli già consegnati - AUD-21: PDF via print CSS, non libreria: interruzioni di pagina corrette, slider impilato in due immagini, nessun marcatore di lavorazione sopravvissuto
- AUD-22: In scala di grigi impatti e metriche restano distinguibili — il colore non può essere l'unico portatore di informazione
- AUD-23: Il documento usa il design system dell'area admin ("Quiet Luxury",
design-reference/DESIGN-SYSTEM.md): token semantici, Plus Jakarta Sans per il testo, Geist Mono per metriche, punteggi e date, e i primitivi già esistenti (StatusBadgeper gli impatti). Decisione del 2026-08-18, sostituisce la deroga tipografica prevista dal piano. Due conseguenze: i font sono già self-hostati danext/font/google, quindi la CSPfont-src 'self'è soddisfatta senza lavoro; e il documento non aggiunge debito a DEBT-01 perché nasce già a token. - AUD-24: Tracciamento delle aperture (
view) e delle stampe (print) via isola client + Server Action; un admin loggato non viene contato (altrimenti i numeri li inquiniamo noi rileggendo le bozze) - AUD-25: L'IP non si salva in chiaro — SHA-256 di
ip + NEXTAUTH_SECRET, come il digest del gate admin
Vincoli che questa milestone tocca
- LOCKED #5 (no file hosting) — emendato limitatamente agli asset di audit, deroga già annotata in
CLAUDE.md. Non estendere ad altre entità. - Nessun renderer headless, da nessuna parte. Il VPS non regge Chromium (RAM), e non serve: gli audit Lighthouse arrivano già fatti sul DOM renderizzato.
Backlog (ereditato, nessuno in corso)
- SEND-01 / SEND-02 — Invio del link
/preventivo/[slug]via email. Il mailer è già in produzione dalla v2.3: manca il pulsante e l'action. Rinviati il 2026-07-28. - PROP-03 — Stripe Payment Link sul deck pubblico del preventivo.
- PROP-04 — Auto-provisioning cliente / progetto / fasi al passaggio del lead a "Vinto".
- RET-06 — Canoni mensili tracciabili. Serve una tabella nuova:
paymentsè protetta dai vincoli di Data Safety. - OFFER-14 — Sezioni analitiche stile Notion sull'offerta.
- ARCH-01 — Split del modulo "compartimento stagno" in un deploy separato. Solo se cresce.
- DEBT-01 — Debito design: ~40 file, ~450 occorrenze di palette raw/hex al posto dei token. Cluster in
/admin/projects/[id](~182),/admin/offers/[id]/edit(~79),/admin/clients/[id](~59),/quote/[token](~48, ed è rivolto al cliente),ChatPanel(37),ui/dialog.tsx. Misurato il 2026-08-08. - DEBT-02 — Tabelle legacy
service_catalog/offer_services/offer_micro_services;createService/serviceSchemadead code.
Rinviati esplicitamente da v2.5
- Allegato tecnico — seconda vista sugli stessi finding con registro da sviluppatore (selettori, file, stime). Renderebbe vera la promessa del blocco 9 "il documento resta tuo e puoi darlo a chiunque lavorerà sul sito". Da valutare dopo il primo audit consegnato.
- Affettare lo screenshot a pagina intera — richiede
sharp, da verificare sunode:20-alpine. Non serve in fase 1:final-screenshot(250×498) è leggibile. - Ingresso via webhook Whop — schema predisposto, costruzione in fase 2.
Aperto, non un requisito
Whitelist del portale vuota per 3 clienti su 4. La migration 0015 ha seedato solo
mario@test.it. Protocollo Estetico, Caruso Speaker e Teckell hanno whitelist vuota e
finché lo è il loro portale non è accessibile. Si popola da /admin/clients/<id> →
"Accessi al portale", poi va reinviato il link.
Fuori scope
- Tabella utenti / multi-admin: l'auth resta una singola credenziale da env.
- File hosting per i documenti del portale cliente: restano URL esterni (LOCKED #5, non emendato per quelli).