-- Migration 006: Landvex, Compliance, Analytics tables -- Allt som tidigare var hårdkodat i Go flyttas till databas -- Landvex: Entities (bolag) CREATE TABLE IF NOT EXISTS boc_landvex_entities ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), entity_id TEXT UNIQUE NOT NULL, -- t.ex. "lvx-ab", "lvx-inc" name TEXT NOT NULL, jurisdiction TEXT NOT NULL, -- SE, US, etc. entity_type TEXT NOT NULL, -- holding, operating status TEXT NOT NULL DEFAULT 'active', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); -- Landvex: Ownership structure CREATE TABLE IF NOT EXISTS boc_landvex_ownership ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), entity_id TEXT NOT NULL REFERENCES boc_landvex_entities(entity_id), owner_name TEXT NOT NULL, owner_email TEXT, ownership_percent NUMERIC(5,2) NOT NULL DEFAULT 100, parent_entity_id TEXT REFERENCES boc_landvex_entities(entity_id), created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); -- Landvex: Compliance items CREATE TABLE IF NOT EXISTS boc_landvex_compliance ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), entity_id TEXT NOT NULL REFERENCES boc_landvex_entities(entity_id), category TEXT NOT NULL, -- tax, annual_report, audit, etc. title TEXT NOT NULL, status TEXT NOT NULL DEFAULT 'pending', -- pending, completed, overdue due_date DATE, completed_at TIMESTAMPTZ, notes TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); -- Compliance: Legal cases CREATE TABLE IF NOT EXISTS boc_legal_cases ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), case_id TEXT UNIQUE NOT NULL, -- t.ex. "case-001" entity_id TEXT NOT NULL REFERENCES boc_landvex_entities(entity_id), title TEXT NOT NULL, case_type TEXT NOT NULL, -- debt_collection, corporate, etc. status TEXT NOT NULL DEFAULT 'active', -- active, pending, closed priority TEXT NOT NULL DEFAULT 'medium', -- low, medium, high description TEXT NOT NULL, opposing_party TEXT NOT NULL, lawyer TEXT, opened_at DATE NOT NULL, closed_at DATE, value NUMERIC(15,2) DEFAULT 0, currency TEXT DEFAULT 'SEK', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); -- Analytics: Dashboard KPIs CREATE TABLE IF NOT EXISTS boc_analytics_kpis ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), kpi_key TEXT UNIQUE NOT NULL, -- t.ex. "revenue_h1", "moms_att_betala" label TEXT NOT NULL, value NUMERIC(15,2) NOT NULL DEFAULT 0, currency TEXT, trend NUMERIC(5,2), -- procent, t.ex. 0.15 för 15% period TEXT, -- t.ex. "H1 2026", "all" updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); -- Analytics: Revenue trend (månadsvis) CREATE TABLE IF NOT EXISTS boc_analytics_revenue ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), month TEXT NOT NULL, -- t.ex. "Jan", "Feb" year INTEGER NOT NULL, revenue NUMERIC(15,2) NOT NULL DEFAULT 0, UNIQUE(year, month) ); -- Analytics: Expenses by category CREATE TABLE IF NOT EXISTS boc_analytics_expenses ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), category TEXT NOT NULL, -- t.ex. "IT/Molntjänster" amount NUMERIC(15,2) NOT NULL DEFAULT 0, period TEXT DEFAULT 'all', UNIQUE(category, period) ); -- Analytics: Alerts CREATE TABLE IF NOT EXISTS boc_analytics_alerts ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), alert_type TEXT NOT NULL, -- warning, info, danger message TEXT NOT NULL, due_date DATE, dismissed BOOLEAN NOT NULL DEFAULT FALSE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); -- Insert default Landvex data INSERT INTO boc_landvex_entities (entity_id, name, jurisdiction, entity_type, status) VALUES ('lvx-ab', 'Landvex AB', 'SE', 'holding', 'active'), ('lvx-inc', 'Landvex Inc.', 'US', 'operating', 'active') ON CONFLICT (entity_id) DO NOTHING; -- Insert ownership INSERT INTO boc_landvex_ownership (entity_id, owner_name, ownership_percent) VALUES ('lvx-ab', 'Erik Svensson', 100), ('lvx-inc', 'Landvex AB', 100) ON CONFLICT DO NOTHING; -- Insert compliance items INSERT INTO boc_landvex_compliance (entity_id, category, title, status, due_date) VALUES ('lvx-ab', 'tax', 'Momsdeklaration H1 2026', 'pending', '2026-08-12'), ('lvx-ab', 'annual_report', 'Årsredovisning 2025', 'overdue', '2026-07-31'), ('lvx-ab', 'tax', 'Inkomstdeklaration 2025', 'overdue', '2026-05-02'), ('lvx-ab', 'annual_report', 'Årsredovisning 2024', 'completed', '2025-07-31'), ('lvx-ab', 'audit', 'Revisorns granskning 2025', 'pending', '2026-09-30'), ('lvx-inc', 'tax', 'Federal Tax Return 2025', 'pending', '2026-04-15') ON CONFLICT DO NOTHING; -- Insert legal cases INSERT INTO boc_legal_cases (case_id, entity_id, title, case_type, status, priority, description, opposing_party, lawyer, opened_at, value, currency) VALUES ('case-001', 'lvx-ab', 'Leon Russo De Cerame — krav på återbetalning', 'debt_collection', 'active', 'high', 'Obehöriga uttag på företagskort, totalt 212 921,60 SEK', 'Leon Maurizio Russo De Cerame', 'Advokatfirman X', '2026-06-16', 212921.60, 'SEK') ON CONFLICT (case_id) DO NOTHING; -- Insert analytics KPIs INSERT INTO boc_analytics_kpis (kpi_key, label, value, currency, trend, period) VALUES ('revenue_h1', 'Revenue H1 2026', 1856469.00, 'SEK', 0.15, 'H1 2026'), ('moms_att_betala', 'MOMS att betala', 440783.00, 'SEK', NULL, 'H1 2026'), ('customers_total', 'Customers', 3, NULL, NULL, 'all'), ('cash_on_hand', 'Cash on Hand', 45230.00, 'SEK', NULL, 'all') ON CONFLICT (kpi_key) DO NOTHING; -- Insert revenue trend INSERT INTO boc_analytics_revenue (month, year, revenue) VALUES ('Jan', 2026, 811147), ('Feb', 2026, 0), ('Mar', 2026, 0), ('Apr', 2026, 955317), ('May', 2026, 0), ('Jun', 2026, 0) ON CONFLICT (year, month) DO NOTHING; -- Insert expenses by category INSERT INTO boc_analytics_expenses (category, amount) VALUES ('IT/Molntjänster', 449984), ('Resekostnader', 276712), ('Representation', 84742), ('Externa tjänster', 152727), ('Löner', 100047), ('Övrigt', 45291) ON CONFLICT (category, period) DO NOTHING; -- Insert alerts INSERT INTO boc_analytics_alerts (alert_type, message, due_date) VALUES ('warning', 'Momsdeklaration H1 2026 deadline: 12 augusti', '2026-08-12'), ('warning', 'Årsredovisning 2025 måste lämnas', '2026-07-31'), ('info', 'Inkomstdeklaration 2025 försenad', '2026-05-02') ON CONFLICT DO NOTHING;