fix
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
-- +goose Up
|
||||
-- Durable AI cost accounting, deliberately separate from ai_call_logs.
|
||||
--
|
||||
-- ai_call_logs holds full prompts and is pruned after 7 days. Cost has to outlive
|
||||
-- that by years, so usage is rolled up per day / company / user / model / role at
|
||||
-- capture time. One row per combination per day keeps three years small: a busy
|
||||
-- tenant with 5 users and 3 roles adds ~45 rows a day, not one per product.
|
||||
--
|
||||
-- Cost is stored in micro-USD integers, never floats: summing millions of
|
||||
-- fractional-cent calls in float drifts, and money must add up exactly.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ai_model_prices (
|
||||
model TEXT PRIMARY KEY,
|
||||
-- Micro-USD per 1,000,000 tokens. $0.20/1M = 200000 micros.
|
||||
input_micros_per_mtok BIGINT NOT NULL DEFAULT 0,
|
||||
cached_input_micros_per_mtok BIGINT NOT NULL DEFAULT 0,
|
||||
output_micros_per_mtok BIGINT NOT NULL DEFAULT 0,
|
||||
source TEXT NOT NULL DEFAULT '',
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- OpenAI GPT-5.6 family, rates effective 2026-07-30.
|
||||
-- Admin can UPDATE these when list prices change; already-recorded cost is never
|
||||
-- recalculated, so history keeps the price that applied at the time.
|
||||
INSERT INTO ai_model_prices (model, input_micros_per_mtok, cached_input_micros_per_mtok, output_micros_per_mtok, source)
|
||||
VALUES
|
||||
('gpt-5.6-luna', 200000, 20000, 1200000, 'openai list price 2026-07-30'),
|
||||
('gpt-5.6-terra', 2000000, 200000, 12000000, 'openai list price 2026-07-30'),
|
||||
('gpt-5.6-sol', 5000000, 500000, 30000000, 'openai list price 2026-07-30')
|
||||
ON CONFLICT (model) DO NOTHING;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ai_usage_daily (
|
||||
day DATE NOT NULL,
|
||||
-- Nil UUID rather than NULL: these are primary-key columns and NULL would let
|
||||
-- duplicate rows accumulate instead of upserting.
|
||||
company_id UUID NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
|
||||
user_id UUID NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
|
||||
model TEXT NOT NULL DEFAULT '',
|
||||
role TEXT NOT NULL DEFAULT 'other',
|
||||
calls BIGINT NOT NULL DEFAULT 0,
|
||||
failed_calls BIGINT NOT NULL DEFAULT 0,
|
||||
prompt_tokens BIGINT NOT NULL DEFAULT 0,
|
||||
cached_prompt_tokens BIGINT NOT NULL DEFAULT 0,
|
||||
completion_tokens BIGINT NOT NULL DEFAULT 0,
|
||||
total_tokens BIGINT NOT NULL DEFAULT 0,
|
||||
cost_micros BIGINT NOT NULL DEFAULT 0,
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (day, company_id, user_id, model, role)
|
||||
);
|
||||
|
||||
-- No FK to companies/users: cost history must survive a tenant or user being
|
||||
-- deleted, otherwise the yearly total silently drops.
|
||||
|
||||
CREATE INDEX IF NOT EXISTS ai_usage_daily_company_day_idx
|
||||
ON ai_usage_daily (company_id, day DESC);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS ai_usage_daily_user_day_idx
|
||||
ON ai_usage_daily (user_id, day DESC);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS ai_usage_daily_day_idx
|
||||
ON ai_usage_daily (day DESC);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS ai_usage_daily;
|
||||
DROP TABLE IF EXISTS ai_model_prices;
|
||||
Reference in New Issue
Block a user