pr_01m47d15m3e54sn21z27rpy5n9/services/billing/migrations/0006_prices.sql
| 1 | -- Prices that keep themselves current. See src/keeper.rs. |
| 2 | |
| 3 | -- Which AI Gateway session a run's model requests went through, and what |
| 4 | -- the gateway priced them at once settled. A run is first charged what |
| 5 | -- the sandbox reported; settling corrects it to the gateway's figure. |
| 6 | ALTER TABLE runs ADD COLUMN session_id TEXT; |
| 7 | ALTER TABLE runs ADD COLUMN settled_at TEXT; |
| 8 | ALTER TABLE runs ADD COLUMN gateway_cost_micros INTEGER; |
| 9 | |
| 10 | -- What each metered unit costs g1t, and the markup it is sold at. Price |
| 11 | -- is always cost × (100 + markup) / 100, so when a cost moves, the price |
| 12 | -- moves with it. |
| 13 | CREATE TABLE prices ( |
| 14 | meter TEXT PRIMARY KEY, |
| 15 | title TEXT NOT NULL, |
| 16 | -- second, million requests, million CPU ms, app-month. |
| 17 | unit TEXT NOT NULL, |
| 18 | -- Millionths of a dollar per unit; fractions allowed. |
| 19 | cost_micros REAL NOT NULL, |
| 20 | markup_percent INTEGER NOT NULL, |
| 21 | -- list (Cloudflare's published price) or cloudflare (what Cloudflare |
| 22 | -- actually billed g1t, measured). |
| 23 | source TEXT NOT NULL, |
| 24 | checked_at TEXT, |
| 25 | updated_at TEXT NOT NULL |
| 26 | ); |
| 27 | |
| 28 | INSERT INTO prices (meter, title, unit, cost_micros, markup_percent, source, updated_at) VALUES |
| 29 | ('sandbox_second', 'Sandbox time', 'second', 21, 138, 'list', '2026-10-04T00:00:00Z'), |
| 30 | ('build_second', 'Deploy builds', 'second', 21, 20, 'list', '2026-10-04T00:00:00Z'), |
| 31 | ('app_requests', 'App requests', 'million requests', 300000, 20, 'list', '2026-10-04T00:00:00Z'), |
| 32 | ('app_cpu', 'App CPU time', 'million CPU ms', 20000, 20, 'list', '2026-10-04T00:00:00Z'), |
| 33 | ('app_month', 'Apps up past the plan', 'app-month', 20000, 20, 'list', '2026-10-04T00:00:00Z'); |
| 34 | |
| 35 | -- Every time a cost moved, and why: the public record of price changes. |
| 36 | CREATE TABLE price_changes ( |
| 37 | id TEXT PRIMARY KEY, |
| 38 | meter TEXT NOT NULL, |
| 39 | old_cost_micros REAL NOT NULL, |
| 40 | new_cost_micros REAL NOT NULL, |
| 41 | markup_percent INTEGER NOT NULL, |
| 42 | reason TEXT NOT NULL, |
| 43 | created_at TEXT NOT NULL |
| 44 | ); |
| 45 | CREATE INDEX price_changes_by_time ON price_changes (created_at); |
| 46 | |
| 47 | -- What Cloudflare billed g1t's account, as its usage API reports it, kept |
| 48 | -- as given so the measured costs can be checked. |
| 49 | CREATE TABLE cloudflare_usage ( |
| 50 | period_start TEXT NOT NULL, |
| 51 | period_end TEXT NOT NULL, |
| 52 | service TEXT NOT NULL, |
| 53 | unit TEXT NOT NULL, |
| 54 | quantity REAL NOT NULL, |
| 55 | cost_usd REAL NOT NULL, |
| 56 | fetched_at TEXT NOT NULL, |
| 57 | PRIMARY KEY (period_start, service, unit) |
| 58 | ); |