STATE.md diceva "Phase 27, nessun bloccante" mentre v2.5 e' ferma per scelta e in produzione e' andato altro. Ora dice cosa e' vero: v2.5 in pausa, modifiche hub in corso, blocchi A/B/C1 in produzione, e due bloccanti scritti con cosa manca e chi li sblocca — le credenziali API di TidyCal e LEAD_WEBHOOK_SECRET su Coolify, senza la quale la route rifiuta tutti (fallimento chiuso voluto). Sta di nuovo sotto le 100 righe: ci e' rientrato togliendo cio' che STATUS.md gia' racconta per esteso, non accorciando i bloccanti. REQUIREMENTS.md guadagna HUB-01..13, con lo stato reale: otto fatti, cinque no. Fra quelli aperti c'e' anche la conferma del payload Elementor, che oggi e' gestito in modo difensivo e non verificato sul campo — distinguere "scritto" da "visto funzionare" e' il punto della regola. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
10 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.
Modifiche hub (richieste 2026-08-18, in corso)
Fuori dalla milestone v2.5, che è in pausa. Piano in
~/.claude/plans/sei-arrivato-qua-search-recursive-kettle.md.
- HUB-01: Via il tab Commenti dal progetto —
/admin/conversazionili aggrega già tutti con l'etichetta dell'entità. Perde solo la risposta sulla singola entità, che era già confluita sul thread generale. - HUB-02: Via il timer dalla lista progetti — si avvia dove c'è il contesto
- HUB-03: Riepilogo soldi + avanzamento in testa al progetto, senza query nuove
- HUB-04: Timer per fase e task — migration
0018,ON DELETE SET NULLperché le ore sopravvivono al task - HUB-05: Inbox in cima alla dashboard, con da-quanto-aspetta e contesto del messaggio
- HUB-06: Analytics per linea di prodotto (Entry/Signature/Retainer) dalla tassonomia, con l'incassato non attribuibile mostrato a parte
- HUB-07: Timeline delle consegne con semaforo ritardo/anticipo; scadenza dedotta da offerta + durata,
projects.due_datecome override - HUB-08:
POST /api/webhooks/lead— un endpoint per form del sito e bridge, con dedup sull'email - HUB-09: Confermare la forma del payload Elementor con un invio vero — oggi è gestita in modo difensivo
- HUB-10:
LEAD_WEBHOOK_SECRETsu Coolify — finché manca, la route risponde 403 a tutti - HUB-11: TidyCal. [BLOCCANTE] Niente webhook (loro FAQ): serve polling della REST API. Path e filtri stanno dietro il login → servono token o documentazione dall'utente
- HUB-12: Alleggerire l'hub. Senza perimetro: si definisce guardando cosa è poco usato
- HUB-13: Whop → progetto + audit automatico. Dipende dal motore v2.5 (AUD-06→11)
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).