Files
Paperless-Contracts/src/db.ts
2025-10-11 19:34:54 +02:00

85 lines
2.2 KiB
TypeScript

import Database from "better-sqlite3";
import { existsSync, mkdirSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { config } from "./config.js";
import { createLogger } from "./logger.js";
import { DEFAULT_CATEGORY_NAMES } from "./categoryDefaults.js";
const logger = createLogger(config.logLevel);
const absolutePath = resolve(config.databasePath);
const directory = dirname(absolutePath);
if (!existsSync(directory)) {
mkdirSync(directory, { recursive: true });
logger.info(`Created data directory at ${directory}`);
}
const db = new Database(absolutePath);
db.pragma("journal_mode = WAL");
db.exec(`
CREATE TABLE IF NOT EXISTS contracts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
paperless_document_id INTEGER,
provider TEXT,
category TEXT,
contract_start_date TEXT,
contract_end_date TEXT,
termination_notice_days INTEGER,
renewal_period_months INTEGER,
auto_renew INTEGER DEFAULT 0,
price_cents INTEGER,
currency TEXT DEFAULT 'EUR',
notes TEXT,
tags TEXT DEFAULT '[]',
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS settings (
key TEXT PRIMARY KEY,
value TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS categories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE COLLATE NOCASE,
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now'))
);
`);
const categoryRow = db.prepare(`SELECT COUNT(*) as count FROM categories`).get() as { count: number } | undefined;
const categoryCount = categoryRow?.count ?? 0;
if (categoryCount === 0) {
const insertStmt = db.prepare(`INSERT OR IGNORE INTO categories (name) VALUES (?)`);
for (const name of DEFAULT_CATEGORY_NAMES) {
insertStmt.run(name);
}
}
export type ContractDbRow = {
id: number;
title: string;
paperless_document_id: number | null;
provider: string | null;
category: string | null;
contract_start_date: string | null;
contract_end_date: string | null;
termination_notice_days: number | null;
renewal_period_months: number | null;
auto_renew: number;
price_cents: number | null;
currency: string | null;
notes: string | null;
tags: string | null;
created_at: string;
updated_at: string;
};
export default db;