import { query } from "./db-client"; import { getTableConfig } from "./table-config"; export async function ensureFinanceTables(): Promise { try { // Overrides tables await query(` CREATE TABLE IF NOT EXISTS income_category_overrides ( record_id TEXT PRIMARY KEY, category_id TEXT NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ) `); await query(` CREATE TABLE IF NOT EXISTS expense_category_overrides ( record_id TEXT PRIMARY KEY, category_id TEXT NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ) `); // Tags tables await query(` CREATE TABLE IF NOT EXISTS node_tags ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, color TEXT NOT NULL DEFAULT '#2563eb' ) `); await query(` CREATE TABLE IF NOT EXISTS node_tag_assignments ( id SERIAL PRIMARY KEY, node_id TEXT NOT NULL, tag_id INTEGER NOT NULL REFERENCES node_tags(id) ON DELETE CASCADE, context TEXT NOT NULL DEFAULT 'income', UNIQUE(node_id, tag_id, context) ) `); } catch (err) { console.error("[FINANCE] Failed to ensure metadata tables:", err); } } async function tableExists(tableName: string): Promise { try { const result = await query( `SELECT EXISTS ( SELECT FROM information_schema.tables WHERE table_schema = 'public' AND table_name = $1 ) as exists`, [tableName] ); return result.rows[0]?.exists === true; } catch { return false; } } export async function ensureViews(): Promise { const config = getTableConfig(); try { const incomeExists = await tableExists(config.incomeTable); const expenseExists = await tableExists(config.expenseTable); if (!incomeExists && !expenseExists) { return; } if (incomeExists) { // CREATE OR REPLACE VIEW не умеет менять типы столбцов (тип stavkands в источнике // изменился text ↔ varchar) — пересоздаём view целиком. Зависимых объектов нет. await query(`DROP VIEW IF EXISTS vw_income_effective`); await query(` CREATE VIEW vw_income_effective AS SELECT t.*, o.category_id as _override_category_id FROM "${config.incomeTable}" t LEFT JOIN income_category_overrides o ON o.record_id = t.id::text `); } if (expenseExists) { await query(`DROP VIEW IF EXISTS vw_expense_effective`); await query(` CREATE VIEW vw_expense_effective AS SELECT t.*, o.category_id as _override_category_id FROM "${config.expenseTable}" t LEFT JOIN expense_category_overrides o ON o.record_id = t.id::text `); } } catch (err) { console.error("[FINANCE] Failed to create views:", err); } }