# Review package: 159af2e..ce399e5 ## Commits ce399e5 PDF: tabella dvr_pdf (stato/cache PDF per agenzia) ## Files changed app/migrations/2026-06-24-phase3-dvr-pdf.sql | 10 ++++++++++ app/src/lib/server/db/schema.ts | 16 ++++++++++++++++ 2 files changed, 26 insertions(+) ## Diff diff --git a/app/migrations/2026-06-24-phase3-dvr-pdf.sql b/app/migrations/2026-06-24-phase3-dvr-pdf.sql new file mode 100644 index 0000000..0e73a7c --- /dev/null +++ b/app/migrations/2026-06-24-phase3-dvr-pdf.sql @@ -0,0 +1,10 @@ +-- 2026-06-24 Fase 3 — tabella stato PDF per agenzia (cache PDF su R2) +CREATE TABLE IF NOT EXISTS dvr_pdf ( + agenzia_id INTEGER PRIMARY KEY REFERENCES agenzie(id) ON DELETE CASCADE, + r2_key TEXT, + data_hash TEXT, + stato TEXT CHECK (stato IN ('ready','generating','error')), + generato_il TEXT, + error_msg TEXT, + updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP +); diff --git a/app/src/lib/server/db/schema.ts b/app/src/lib/server/db/schema.ts index b41b275..a362f4d 100644 --- a/app/src/lib/server/db/schema.ts +++ b/app/src/lib/server/db/schema.ts @@ -478,20 +478,36 @@ export const dvrAttivitaMiglioramento = sqliteTable( noteRisoluzione: text('note_risoluzione'), createdAt: text('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), updatedAt: text('updated_at').notNull().default(sql`CURRENT_TIMESTAMP`) }, (t) => ({ idxDvr: index('idx_dvr_attivita_dvr').on(t.dvrId), idxSrc: index('idx_dvr_attivita_src').on(t.sourceType, t.sourceId) }) ); +// ============== STATO/CACHE PDF PER AGENZIA ============== +// Una riga per agenzia; traccia lo stato del PDF su R2 e il data_hash per la cache. +export const dvrPdf = sqliteTable('dvr_pdf', { + agenziaId: integer('agenzia_id') + .primaryKey() + .references(() => agenzie.id, { onDelete: 'cascade' }), + r2Key: text('r2_key'), + dataHash: text('data_hash'), + stato: text('stato', { enum: ['ready', 'generating', 'error'] }), + generatoIl: text('generato_il'), + errorMsg: text('error_msg'), + updatedAt: text('updated_at') + .notNull() + .default(sql`CURRENT_TIMESTAMP`) +}); + // ============== IMPOSTAZIONI GLOBALI (singleton id=1) ============== // Pannello di configurazione: nominativi DL/RSPP costanti per tutta Alleanza. export const appSettings = sqliteTable('app_settings', { id: integer('id').primaryKey().default(1), datoreLavoroNome: text('datore_lavoro_nome'), datoreLavoroQualifica: text('datore_lavoro_qualifica'), rsppNome: text('rspp_nome'), rsppQualifica: text('rspp_qualifica'), updatedAt: text('updated_at') .notNull()