import Database from 'better-sqlite3'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const dbPath = path.join(__dirname, 'data.db'); export const db = new Database(dbPath); db.pragma('journal_mode = WAL'); db.pragma('foreign_keys = ON'); db.exec(` CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL UNIQUE, password_hash TEXT NOT NULL, created_at TEXT NOT NULL DEFAULT (datetime('now')) ); CREATE TABLE IF NOT EXISTS articles ( id TEXT PRIMARY KEY, title TEXT NOT NULL, category TEXT, type TEXT, author TEXT, author_role TEXT, author_initial TEXT, publish_date TEXT, pages INTEGER DEFAULT 0, price INTEGER DEFAULT 0, is_free INTEGER DEFAULT 1, summary TEXT, body TEXT, cover_image TEXT, tags TEXT, featured INTEGER DEFAULT 0, created_at TEXT NOT NULL DEFAULT (datetime('now')), updated_at TEXT NOT NULL DEFAULT (datetime('now')) ); CREATE INDEX IF NOT EXISTS idx_articles_created ON articles(created_at DESC); CREATE INDEX IF NOT EXISTS idx_articles_featured ON articles(featured); `); export function rowToArticle(row) { if (!row) return null; return { id: row.id, title: row.title, category: row.category, type: row.type, author: row.author, authorRole: row.author_role, authorInitial: row.author_initial, publishDate: row.publish_date, pages: row.pages, price: row.price, isFree: !!row.is_free, summary: row.summary, body: row.body, coverImage: row.cover_image, tags: row.tags ? JSON.parse(row.tags) : [], featured: !!row.featured, createdAt: row.created_at, updatedAt: row.updated_at, }; }