-- AwoooP Phase 2.6: budget_ledger 建表 + 欄位定義 -- 2026-05-04 ogt + Claude Sonnet 4.6(ADR-120 D5 實作) -- -- 防止 $47k 事故的三層 Hard Kill 架構中的 accounting 層: -- - 每次 LLM call 完成後寫入一筆 ledger record -- - 供 Tenant Budget Cache 計算 / 儀表板消費統計 / 告警閾值觸發 -- -- Phase 1 Control Plane migration 必須先執行(awooop_projects 表存在) -- awooop_run_state 欄位在 Phase 3 SAGA 實作後補加 -- ========================================================= -- STEP 1: 建立 budget_ledger 表 -- ========================================================= CREATE TABLE IF NOT EXISTS budget_ledger ( id UUID DEFAULT gen_random_uuid() PRIMARY KEY, project_id VARCHAR(64) NOT NULL DEFAULT 'awoooi', agent_id VARCHAR(128), run_id UUID, model VARCHAR(64), provider VARCHAR(32), prompt_tokens INT, completion_tokens INT, cost_usd NUMERIC(10, 4) NOT NULL DEFAULT 0.0000, recorded_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); COMMENT ON TABLE budget_ledger IS 'ADR-120: 每次 LLM call 的 token/cost accounting 記錄'; COMMENT ON COLUMN budget_ledger.cost_usd IS 'prompt + completion token 的估算費用(USD)'; -- ========================================================= -- STEP 2: Index(分析 + 查詢效率) -- ========================================================= CREATE INDEX IF NOT EXISTS idx_budget_ledger_project_date ON budget_ledger(project_id, recorded_at DESC); CREATE INDEX IF NOT EXISTS idx_budget_ledger_run ON budget_ledger(run_id) WHERE run_id IS NOT NULL; CREATE INDEX IF NOT EXISTS idx_budget_ledger_agent ON budget_ledger(project_id, agent_id, recorded_at DESC) WHERE agent_id IS NOT NULL; -- ========================================================= -- STEP 3: RLS(ADR-118 多租戶隔離) -- ========================================================= ALTER TABLE budget_ledger ENABLE ROW LEVEL SECURITY; ALTER TABLE budget_ledger FORCE ROW LEVEL SECURITY; DROP POLICY IF EXISTS budget_ledger_tenant_isolation ON budget_ledger; CREATE POLICY budget_ledger_tenant_isolation ON budget_ledger FOR ALL TO awooop_app USING (project_id = current_setting('app.project_id', TRUE)) WITH CHECK (project_id = current_setting('app.project_id', TRUE)); -- ========================================================= -- STEP 4: GRANT -- ========================================================= GRANT SELECT, INSERT ON budget_ledger TO awooop_app; -- ========================================================= -- 驗收查詢 -- ========================================================= -- SELECT tablename, rowsecurity FROM pg_tables WHERE tablename = 'budget_ledger'; -- -- 結果:rowsecurity = true -- SELECT count(*) FROM budget_ledger; -- = 0(剛建)