# HANDOFF — Generazione PDF DVR (2026-06-24)

> Documento di ripresa generato da un'altra sessione dopo che la sessione originale
> (`d9c209c1`) si è bloccata su un `API Error: 529 Overloaded`. Serve a far ripartire
> il lavoro in una sessione pulita senza perdere contesto.

## TL;DR — dove siamo

**Spec e piano sono scritti, committati e approvati da Paolo. NIENTE è ancora implementato.**
Il prossimo passo è **eseguire il piano a 9 task**. La sessione precedente si è interrotta
*esattamente* al bivio "come eseguiamo?" (subagent-driven vs inline), prima di toccare codice.

- ✅ Design PDF approvato dal cliente (prototipo `pdf-prototype/`, v11)
- ✅ Architettura decisa e validata con Paolo
- ✅ Spec committata → `docs/superpowers/specs/2026-06-24-pdf-generation-design.md` (commit `a2acdd0`)
- ✅ Piano 9 task committato → `docs/superpowers/plans/2026-06-24-pdf-generation.md` (commit `159af2e`)
- ✅ Memoria aggiornata → `memory/pdf_generation_2026_06_24.md` + `MEMORY.md`
- ❌ **Implementazione: 0/9 task.** Tutte le checkbox del piano sono `- [ ]`.

**Stato git:** branch `main`, **ahead 2** rispetto a `origin/main` (i 2 commit spec+piano NON sono pushati — sono solo documenti, niente deploy innescato). Working tree pulito a parte untracked non rilevanti (`pdf-prototype/`, `pdf-spike-pdfmake/`, alcune immagini). I file del piano (`app/src/lib/server/pdf/`, `app/scripts/pdf/`, `.github/workflows/`) **non esistono ancora** → conferma che nessun task è stato avviato.

## Cos'era "l'errore"

Non è un bug del codice. Alle 13:56 del 2026-06-24 la sessione ha ricevuto `API Error: 529 Overloaded`
(sovraccarico lato server Anthropic, temporaneo) proprio mentre stava per partire l'esecuzione del piano.
Da lì è entrata nel loop "Continue from where you left off" → "No response requested" senza produrre lavoro
(context era al 63%). **Nessun file è stato corrotto o lasciato a metà.** Si riparte semplicemente da capo
con l'esecuzione del piano.

## Architettura decisa (sintesi)

- **Motore: Chromium/Puppeteer** riusando `pdf-prototype/template.js` (fedeltà 1:1). **pdfmake SCARTATO**
  (spike `pdf-spike-pdfmake/`: veloce ma perde angoli arrotondati di pill/legende, gradiente copertina, font →
  Paolo l'ha bocciato per fedeltà/professionalità).
- **Vercel Hobby (free)** → Chromium NON gira su Vercel (limite 10s). La generazione gira su **GitHub Actions**
  (repo `paoloalby/alleanza-dvr`, trigger `repository_dispatch`).
- **Cache per hash su R2**: PDF in `pdf/{codiceFisico}_DVR.pdf`, etichettati con un **hash content-based** dei
  dati DVR (le tabelle figlie non hanno `updated_at` → si hasha il contenuto). Tabella nuova `dvr_pdf`.
- **Flusso**: click → l'app calcola l'hash corrente e lo confronta col salvato. Uguale → download da R2 istantaneo.
  Diverso → `markGenerating` + trigger Action → UX **asincrona** ("in aggiornamento ~1 min", resta scaricabile la
  versione precedente) + polling. Staleness **pigra** (nessuna modifica agli autosave).
- **Gemelle**: il PDF usa il contenuto DVR della compagna (`resolveDvrAgenziaId`) ma anagrafica/codice/nome-file
  propri della gemella.

## Prossima azione (da fare nella sessione nuova)

1. Apri Claude Code **in `/Users/paolo/Server/Siti Web/Lavoro/Inlumia/Alleanza`**.
2. Leggi il piano: `docs/superpowers/plans/2026-06-24-pdf-generation.md` (è self-contained, task-by-task, con codice e comandi).
3. Eseguilo con la skill **`superpowers:subagent-driven-development`** (consigliata: un subagent fresco per task,
   review tra un task e l'altro) — oppure `superpowers:executing-plans` (inline, a checkpoint).
4. **Ordine**: 1→2→3 (logica app) · 4 (generazione, verificabile subito in locale) · 5→6→7 (trigger/endpoint/UI) · 8→9 (Action + seed).

### Prompt pronto da incollare

```
Riprendiamo la generazione PDF dei DVR. Spec e piano sono già scritti e committati,
niente è ancora implementato (la sessione precedente si è bloccata su un 529 prima di iniziare).
Leggi docs/superpowers/HANDOFF-2026-06-24-pdf-generation.md e
docs/superpowers/plans/2026-06-24-pdf-generation.md, poi esegui il piano task-by-task
con superpowers:subagent-driven-development. Parti dal Task 1.
```

## Prerequisiti che servono DA PAOLO (per i task 4, 5, 8, 9)

Non bloccano i task 1–3 (logica pura + tabella), ma servono per generazione/dispatch/Action/seed.
Valori in `memory/infrastruttura_alleanza.md`.

- **PAT GitHub** fine-grained (repo `alleanza-dvr`, permesso *Contents: read & write*) → env Vercel `GITHUB_DISPATCH_TOKEN`.
- **Secrets repo GitHub** (Settings → Secrets → Actions): `DATABASE_URL`, `DATABASE_AUTH_TOKEN`, `R2_ACCOUNT_ID`,
  `R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY`, `R2_BUCKET`.
- **Env Vercel** `PUPPETEER_SKIP_DOWNLOAD=true` (così il build Vercel non scarica Chromium inutilmente; in CI NON impostarla).
- **Seed iniziale**: lanciare la Action con `agenzia_id=all` (o `npx tsx scripts/pdf/generate.ts all` in locale) → ~806 PDF su R2.

## Gotchas / vincoli da non dimenticare

- **Il codice Puppeteer NON deve finire nel bundle Vercel** (sta solo in `app/scripts/`, importato solo dallo script/Action). Verifica con `npm run build` (Task 4 Step 7).
- **Migrazioni SQL applicate a mano** (prassi del progetto): `sqlite3` locale + `turso db shell alleanza-dvr-prod`. Non c'è `drizzle-kit migrate` automatico.
- **TDD solo sulle funzioni pure** (`hashFingerprintInput`, `derivePdfState`, costruzione richiesta dispatch) con vitest (nuovo). Generazione/Action/endpoint/UI si verificano con esecuzione reale, non unit test su Puppeteer/R2/rete.
- **Credenziali**: mai committate. Solo su Vercel env + GitHub Secrets.
- **DB locale**: `import-tools/db/dev.db`. Prod Turso: `alleanza-dvr-prod`.
- Riferimenti memoria utili: `pdf_generation_2026_06_24.md`, `project_alleanza_dvr.md`, `infrastruttura_alleanza.md`, `pdf_prototype_alleanza.md`, `matrice_rischio_2026_05_25.md`.

## Contesto progetto (per chi parte da zero)

Gestionale DVR (D.Lgs. 81/08) per ~800 sedi Alleanza Assicurazioni, cliente via Inlumia, sviluppato da Paolo.
Stack: **SvelteKit 2 / Svelte 5 + Drizzle ORM + Turso (libSQL) + Cloudflare R2**, hosting **Vercel Hobby**.
La generazione PDF è la **3ª macro-consegna** (DB+import e gestionale web sono già fatti). Dettagli completi in `CLAUDE.md`.
