-- Migration: Add budget_plans and budget_plan_lines tables to all tenant schemas DO $migration$ DECLARE s TEXT; BEGIN FOR s IN SELECT schema_name FROM information_schema.schemata WHERE schema_name LIKE 'tenant_%' LOOP -- budget_plans EXECUTE format(' CREATE TABLE IF NOT EXISTS %I.budget_plans ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), fiscal_year INTEGER NOT NULL, status VARCHAR(20) NOT NULL DEFAULT ''planning'' CHECK (status IN (''planning'', ''approved'', ''ratified'')), base_year INTEGER NOT NULL, inflation_rate DECIMAL(5,2) NOT NULL DEFAULT 2.50, notes TEXT, created_by UUID, approved_by UUID, approved_at TIMESTAMPTZ, ratified_by UUID, ratified_at TIMESTAMPTZ, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW(), UNIQUE(fiscal_year) )', s); -- budget_plan_lines EXECUTE format(' CREATE TABLE IF NOT EXISTS %I.budget_plan_lines ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), budget_plan_id UUID NOT NULL REFERENCES %I.budget_plans(id) ON DELETE CASCADE, account_id UUID NOT NULL REFERENCES %I.accounts(id), fund_type VARCHAR(20) NOT NULL CHECK (fund_type IN (''operating'', ''reserve'')), jan DECIMAL(12,2) DEFAULT 0, feb DECIMAL(12,2) DEFAULT 0, mar DECIMAL(12,2) DEFAULT 0, apr DECIMAL(12,2) DEFAULT 0, may DECIMAL(12,2) DEFAULT 0, jun DECIMAL(12,2) DEFAULT 0, jul DECIMAL(12,2) DEFAULT 0, aug DECIMAL(12,2) DEFAULT 0, sep DECIMAL(12,2) DEFAULT 0, oct DECIMAL(12,2) DEFAULT 0, nov DECIMAL(12,2) DEFAULT 0, dec_amt DECIMAL(12,2) DEFAULT 0, is_manually_adjusted BOOLEAN DEFAULT FALSE, notes TEXT, UNIQUE(budget_plan_id, account_id, fund_type) )', s, s, s); -- Indexes EXECUTE format('CREATE INDEX IF NOT EXISTS idx_%s_bp_year ON %I.budget_plans(fiscal_year)', replace(s, 'tenant_', ''), s); EXECUTE format('CREATE INDEX IF NOT EXISTS idx_%s_bp_status ON %I.budget_plans(status)', replace(s, 'tenant_', ''), s); EXECUTE format('CREATE INDEX IF NOT EXISTS idx_%s_bpl_plan ON %I.budget_plan_lines(budget_plan_id)', replace(s, 'tenant_', ''), s); RAISE NOTICE 'Migrated schema: %', s; END LOOP; END; $migration$;