Files
Cozy-Den/src/lib/db.ts
T

58 lines
1.8 KiB
TypeScript

import Database from 'better-sqlite3';
import { mkdirSync } from 'node:fs';
import { dirname, resolve } from 'node:path';
const dbPath = resolve(process.env.DB_PATH ?? './data/guestbook.db');
// Ensure directory exists
mkdirSync(dirname(dbPath), { recursive: true });
const db = new Database(dbPath);
// WAL mode improves concurrent read performance
db.pragma('journal_mode = WAL');
db.pragma('foreign_keys = ON');
db.exec(`
CREATE TABLE IF NOT EXISTS guestbook_entries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
display_name TEXT NOT NULL,
message TEXT NOT NULL,
website TEXT,
ip_hash TEXT,
status TEXT NOT NULL DEFAULT 'pending',
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
moderated_at TEXT,
moderation_note TEXT
);
CREATE TABLE IF NOT EXISTS admin_sessions (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
expires_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS rate_limit (
id INTEGER PRIMARY KEY AUTOINCREMENT,
ip_hash TEXT NOT NULL,
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now'))
);
CREATE TABLE IF NOT EXISTS audit_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
action TEXT NOT NULL,
entry_id INTEGER,
admin_session TEXT,
note TEXT,
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now'))
);
CREATE INDEX IF NOT EXISTS idx_entries_status ON guestbook_entries(status);
CREATE INDEX IF NOT EXISTS idx_entries_created ON guestbook_entries(created_at);
CREATE INDEX IF NOT EXISTS idx_rate_limit_ip ON rate_limit(ip_hash, created_at);
CREATE INDEX IF NOT EXISTS idx_sessions_expires ON admin_sessions(expires_at);
`);
export default db;