From c7d9d4ba5dd95ffa48bd4456c90b3260ea608586 Mon Sep 17 00:00:00 2001 From: AdrianoDev Date: Sun, 5 Jul 2026 15:28:17 +0200 Subject: [PATCH] feat: tabella content_blocks e colonna role utenti --- src/lib/db.ts | 13 +++++++++++++ tests/content-db.test.ts | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 tests/content-db.test.ts diff --git a/src/lib/db.ts b/src/lib/db.ts index 537d0aa..0b64cb7 100644 --- a/src/lib/db.ts +++ b/src/lib/db.ts @@ -27,6 +27,14 @@ CREATE TABLE IF NOT EXISTS sessions ( expires_at TEXT NOT NULL ); CREATE INDEX IF NOT EXISTS idx_posts_pub ON posts (draft, published_at DESC); +CREATE TABLE IF NOT EXISTS content_blocks ( + tag TEXT PRIMARY KEY, + type TEXT NOT NULL CHECK (type IN ('text','html','image')), + value TEXT NOT NULL DEFAULT '', + styles TEXT NOT NULL DEFAULT '{}', + updated_at TEXT NOT NULL DEFAULT (datetime('now')), + updated_by TEXT +); `; export function createDb(path?: string): Database.Database { @@ -36,6 +44,11 @@ export function createDb(path?: string): Database.Database { db.pragma('journal_mode = WAL'); db.pragma('foreign_keys = ON'); db.exec(SCHEMA); + // Migrazione additiva: DB creati prima dell'introduzione dei ruoli non hanno users.role. + const userCols = db.prepare(`PRAGMA table_info(users)`).all() as { name: string }[]; + if (!userCols.some((c) => c.name === 'role')) { + db.exec(`ALTER TABLE users ADD COLUMN role TEXT NOT NULL DEFAULT 'admin'`); + } return db; } diff --git a/tests/content-db.test.ts b/tests/content-db.test.ts new file mode 100644 index 0000000..de6ec64 --- /dev/null +++ b/tests/content-db.test.ts @@ -0,0 +1,34 @@ +import { describe, it, expect } from 'vitest'; +import { createDb } from '../src/lib/db'; + +describe('schema content_blocks e ruoli', () => { + it('crea la tabella content_blocks', () => { + const db = createDb(':memory:'); + const cols = db.prepare(`PRAGMA table_info(content_blocks)`).all() as { name: string }[]; + expect(cols.map((c) => c.name)).toEqual( + expect.arrayContaining(['tag', 'type', 'value', 'styles', 'updated_at', 'updated_by']) + ); + }); + + it('rifiuta type non valido', () => { + const db = createDb(':memory:'); + expect(() => + db.prepare(`INSERT INTO content_blocks (tag, type, value) VALUES ('x.y', 'video', '')`).run() + ).toThrow(); + }); + + it('users ha colonna role con default admin', () => { + const db = createDb(':memory:'); + db.prepare(`INSERT INTO users (username, password_hash) VALUES ('a', 'h')`).run(); + const row = db.prepare(`SELECT role FROM users WHERE username = 'a'`).get() as { role: string }; + expect(row.role).toBe('admin'); + }); + + it('migra un DB esistente senza colonna role', () => { + // simula DB vecchio: createDb due volte sullo stesso path in-memory non รจ possibile, + // quindi si verifica che la migrazione sia idempotente (doppia esecuzione non lancia) + const db = createDb(':memory:'); + expect(() => createDb(':memory:')).not.toThrow(); + expect(db.prepare(`PRAGMA table_info(users)`).all().length).toBeGreaterThanOrEqual(4); + }); +});