| 1 | import assert from "node:assert/strict"; |
| 2 | import { readFileSync, readdirSync } from "node:fs"; |
| 3 | import { DatabaseSync } from "node:sqlite"; |
| 4 | import { test } from "node:test"; |
| 5 | |
| 6 | // Execute production SQL against the complete migrated schema. These verify |
| 7 | // transaction/retry contracts; Stripe HTTP and Worker execution need staging. |
| 8 | const source = name => readFileSync(new URL(`../services/billing/src/${name}.rs`, import.meta.url), "utf8"); |
| 9 | const constant = (file, name) => { |
| 10 | const match = source(file).match(new RegExp(`const ${name}: &str = "([\\s\\S]*?)";`)); |
| 11 | assert.ok(match, `${file}::${name}`); |
| 12 | return match[1]; |
| 13 | }; |
| 14 | const prepares = (file, from, to) => { |
| 15 | const text = source(file).split(from)[1].split(to)[0]; |
| 16 | return [...text.matchAll(/\.prepare\(\s*"([\s\S]*?)"\s*,?\s*\)/g)].map(m => m[1]); |
| 17 | }; |
| 18 | function database() { |
| 19 | const db = new DatabaseSync(":memory:"); |
| 20 | const dir = new URL("../services/billing/migrations/", import.meta.url); |
| 21 | for (const name of readdirSync(dir).filter(n => n.endsWith(".sql")).sort()) db.exec(readFileSync(new URL(name, dir), "utf8")); |
| 22 | return db; |
| 23 | } |
| 24 | const at = "2026-10-14T12:00:00Z"; |
| 25 | test('late enterprise overdue writes cannot reopen terminal invoices or pause paid workspaces', () => { |
| 26 | const db = database(); |
| 27 | db.prepare("INSERT INTO accounts(workspace,balance_micros,created_at) VALUES ('fixture',0,?)").run(at); |
| 28 | db.prepare("INSERT INTO enterprise_invoices(invoice_id,account_id,period,amount_micros,status,created_by,created_at) VALUES ('in_fixture','ent_fixture','now',10000000,'open','staff',?)").run(at); |
| 29 | const update = db.prepare(constant('webhooks','ENTERPRISE_STATUS')); |
| 30 | const stop = db.prepare(constant('webhooks','ENTERPRISE_OVERDUE_STOP')); |
| 31 | update.get('overdue','in_fixture'); |
| 32 | stop.run('fixture',at,'overdue','in_fixture'); |
| 33 | assert.equal(db.prepare("SELECT autopay_error FROM limits WHERE workspace='fixture'").get().autopay_error,'overdue'); |
| 34 | batch(db, [["UPDATE enterprise_invoices SET status='paid' WHERE invoice_id='in_fixture'", []], [constant('lib','CLEAR_STOP'), ['fixture']]]); |
| 35 | assert.equal(update.get('overdue','in_fixture'), undefined); |
| 36 | stop.run('fixture',at,'late overdue','in_fixture'); |
| 37 | assert.equal(db.prepare("SELECT autopay_error FROM limits WHERE workspace='fixture'").get().autopay_error,null); |
| 38 | db.exec("UPDATE enterprise_invoices SET status='void'"); |
| 39 | assert.equal(update.get('overdue','in_fixture'), undefined); |
| 40 | stop.run('fixture',at,'late overdue','in_fixture'); |
| 41 | assert.equal(db.prepare("SELECT autopay_error FROM limits WHERE workspace='fixture'").get().autopay_error,null); |
| 42 | }); |
| 43 | test("enterprise invoice acquisition freezes one payload and rejects stale balances after completion", () => { |
| 44 | const db = database(); |
| 45 | db.prepare("INSERT INTO accounts(workspace,balance_micros,created_at) VALUES ('fixture',-10000000,?)").run(at); |
| 46 | db.prepare("INSERT INTO account_members(workspace,account_id,added_by,added_at) VALUES ('fixture','ent_fixture','staff',?)").run(at); |
| 47 | const snapshots = JSON.stringify([{workspace:'fixture',balance:-10000000,invoiced:0}]); |
| 48 | const acquire = db.prepare(constant('enterprise_attempt', 'INSERT')); |
| 49 | const payload = JSON.stringify({lines:[{workspace:'fixture',amountMicros:10000000}]}); |
| 50 | acquire.run('ent_fixture','first',payload,1,snapshots); |
| 51 | acquire.run('ent_fixture','second','{"amount":20000000}',2,snapshots); |
| 52 | assert.deepEqual({...db.prepare('SELECT id,payload FROM enterprise_invoice_attempts').get()}, {id:'first',payload}); |
| 53 | assert.throws(() => db.exec("UPDATE account_members SET account_id='ent_other' WHERE workspace='fixture'"), /pending enterprise invoice/); |
| 54 | assert.throws(() => db.exec("DELETE FROM account_members WHERE workspace='fixture'"), /pending enterprise invoice/); |
| 55 | db.prepare("INSERT INTO enterprise_invoices(invoice_id,account_id,period,amount_micros,status,created_by,created_at) VALUES ('in_first','ent_fixture','now',10000000,'open','staff',?)").run(at); |
| 56 | db.exec("INSERT INTO enterprise_invoice_lines VALUES ('in_first','fixture',10000000); UPDATE enterprise_invoice_attempts SET completed=1"); |
| 57 | db.prepare(constant('enterprise_attempt','RETIRE')).run('ent_fixture'); |
| 58 | acquire.run('ent_fixture','stale','{}',3,snapshots); |
| 59 | assert.equal(db.prepare('SELECT COUNT(*) n FROM enterprise_invoice_attempts').get().n,0); |
| 60 | db.exec("UPDATE accounts SET balance_micros=-15000000 WHERE workspace='fixture'"); |
| 61 | const fresh = JSON.stringify([{workspace:'fixture',balance:-15000000,invoiced:10000000}]); |
| 62 | acquire.run('ent_fixture','additional','{"amount":5000000}',4,fresh); |
| 63 | assert.equal(db.prepare('SELECT id FROM enterprise_invoice_attempts').get().id,'additional'); |
| 64 | }); |
| 65 | test("a late enterprise invoice writer cannot recreate old lines after completion and rename", () => { |
| 66 | const db = database(); |
| 67 | const writes = prepares('webhooks', 'async fn finish_enterprise_attempt(', '/// An enterprise invoice paid:') |
| 68 | .filter(sql => sql.startsWith('INSERT INTO enterprise_invoice')); |
| 69 | assert.equal(writes.length,2); |
| 70 | db.prepare("INSERT INTO enterprise_invoice_attempts(account_id,id,payload,created_ms) VALUES ('ent_fixture','attempt','{}',1)").run(); |
| 71 | const invoice = ['in_fixture','ent_fixture','now',10000000,null,'staff',at,'attempt']; |
| 72 | const line = ['in_fixture','old',10000000,'attempt']; |
| 73 | batch(db,[[writes[0],invoice],[writes[1],line]]); |
| 74 | db.exec("UPDATE enterprise_invoice_attempts SET completed=1; UPDATE enterprise_invoice_lines SET workspace='renamed'"); |
| 75 | batch(db,[[writes[0],invoice],[writes[1],line]]); |
| 76 | assert.deepEqual(db.prepare('SELECT workspace FROM enterprise_invoice_lines').all().map(r=>r.workspace),['renamed']); |
| 77 | db.prepare(constant('enterprise_attempt','RETIRE')).run('ent_fixture'); |
| 78 | batch(db,[[writes[0],invoice],[writes[1],line]]); |
| 79 | assert.equal(db.prepare('SELECT SUM(amount_micros) n FROM enterprise_invoice_lines').get().n,10000000); |
| 80 | }); |
| 81 | test("fee waivers refuse subscriptions that may still charge, including delinquent plans", () => { |
| 82 | const db = database(); |
| 83 | const insert = db.prepare("INSERT INTO subscriptions (workspace, feature, subscription_id, status, started_by, started_at, updated_at) VALUES (?, 'plan', ?, ?, 'staff', ?, ?)"); |
| 84 | for (const status of ['active', 'past_due', 'incomplete', 'unpaid', 'canceled']) { |
| 85 | insert.run(status, `sub_${status}`, status, at, at); |
| 86 | const found = db.prepare(constant('accounts', 'FEE_WAIVER_SUBSCRIPTIONS')).get(status); |
| 87 | assert.equal(Boolean(found), status !== 'canceled', status); |
| 88 | } |
| 89 | assert.equal(db.prepare(constant('accounts', 'FEE_WAIVER_SUBSCRIPTIONS')).get('new-workspace'), undefined); |
| 90 | }); |
| 91 | test("demo detach finds all sources through bounded compound selects", () => { |
| 92 | const db = database(); |
| 93 | db.prepare("INSERT INTO accounts (workspace,balance_micros,created_at) VALUES ('demo',8000000,?)").run(at); |
| 94 | db.prepare("INSERT INTO allowance_use (kind,scope,month,used) VALUES ('plan_credit','allowance-only','2026-10',500)").run(); |
| 95 | const sql = constant('detach', 'FOUND').replace('{internal}', constant('sales', 'INTERNAL_SQL')); |
| 96 | const rows = db.prepare(sql).all(null, '2026-10'); |
| 97 | assert.deepEqual(rows.map(r => r.workspace), ['allowance-only', 'demo']); |
| 98 | assert.equal(rows[0].plan_credit, 500); |
| 99 | assert.equal(rows[1].balance, 8000000); |
| 100 | assert.deepEqual(db.prepare(sql).all('demo', '2026-10').map(r => r.workspace), ['demo']); |
| 101 | // D1 rejects the former long UNION. Each candidate CTE stays small. |
| 102 | for (const cte of sql.split('AS MATERIALIZED (').slice(1)) { |
| 103 | assert.ok((cte.split(')')[0].match(/UNION/g) ?? []).length <= 3); |
| 104 | } |
| 105 | }); |
| 106 | function batch(db, writes) { |
| 107 | db.exec("BEGIN"); |
| 108 | try { for (const [sql, args] of writes) db.prepare(sql).run(...args); db.exec("COMMIT"); } |
| 109 | catch (e) { db.exec("ROLLBACK"); throw e; } |
| 110 | } |
| 111 | const entries = prepares("lib", "pub(crate) fn entry_statements(", "/// What follows an entry"); |
| 112 | const stops = prepares("lib", "fn after_entry_statements(", "async fn account("); |
| 113 | const extras = prepares("tax", "pub(crate) fn extras_statements(", "/// A payment's tax and fee"); |
| 114 | function payment(reference, amount = 25_000_000) { |
| 115 | assert.equal(entries.length, 2); |
| 116 | assert.equal(stops.length, 1); |
| 117 | assert.equal(extras.length, 1); |
| 118 | return [ |
| 119 | [entries[0], [reference, "fixture", "top_up", amount, "Paid in advance", null, reference, null, at]], |
| 120 | [entries[1], ["fixture", amount, "cus_fixture", at]], |
| 121 | [stops[0], ["fixture", amount]], |
| 122 | [constant("lib", "CLEAR_STOP"), ["fixture"]], |
| 123 | [extras[0], [`${reference}/tax`, "fixture", "tax", 2_000_000, reference, "pi_fixture", null, at]], |
| 124 | ]; |
| 125 | } |
| 126 | test("payment, balance, dispute repayment and tax commit once together", () => { |
| 127 | const db = database(); |
| 128 | db.prepare("INSERT INTO limits (workspace, updated_at, dispute_owed_micros, autopay_failed_at) VALUES (?, ?, ?, ?)").run("fixture", at, 30_000_000, at); |
| 129 | batch(db, payment("cs_fixture")); |
| 130 | assert.equal(db.prepare("SELECT balance_micros FROM accounts WHERE workspace='fixture'").get().balance_micros, 25_000_000); |
| 131 | assert.equal(db.prepare("SELECT dispute_owed_micros FROM limits WHERE workspace='fixture'").get().dispute_owed_micros, 5_000_000); |
| 132 | assert.throws(() => batch(db, payment("cs_fixture")), /UNIQUE/); |
| 133 | assert.equal(db.prepare("SELECT dispute_owed_micros FROM limits WHERE workspace='fixture'").get().dispute_owed_micros, 5_000_000); |
| 134 | assert.equal(db.prepare("SELECT COUNT(*) n FROM tax_and_fees").get().n, 1); |
| 135 | batch(db, payment("cs_second", 5_000_000)); |
| 136 | assert.equal(db.prepare("SELECT autopay_failed_at FROM limits WHERE workspace='fixture'").get().autopay_failed_at, null); |
| 137 | db.close(); |
| 138 | }); |
| 139 | test("a failure writing tax rolls back the credit and payment-stop updates", () => { |
| 140 | const db = database(); |
| 141 | db.prepare("INSERT INTO limits (workspace, updated_at, dispute_owed_micros, autopay_failed_at) VALUES (?, ?, ?, ?)").run("fixture", at, 25_000_000, at); |
| 142 | db.exec("CREATE TRIGGER fail_tax BEFORE INSERT ON tax_and_fees BEGIN SELECT RAISE(ABORT, 'injected failure'); END"); |
| 143 | assert.throws(() => batch(db, payment("cs_fixture")), /injected failure/); |
| 144 | assert.equal(db.prepare("SELECT COUNT(*) n FROM ledger").get().n, 0); |
| 145 | assert.equal(db.prepare("SELECT COUNT(*) n FROM accounts WHERE workspace='fixture'").get().n, 0); |
| 146 | assert.equal(db.prepare("SELECT dispute_owed_micros FROM limits WHERE workspace='fixture'").get().dispute_owed_micros, 25_000_000); |
| 147 | db.exec("DROP TRIGGER fail_tax"); |
| 148 | batch(db, payment("cs_fixture")); |
| 149 | assert.equal(db.prepare("SELECT COUNT(*) n FROM tax_and_fees").get().n, 1); |
| 150 | db.close(); |
| 151 | }); |
| 152 | test("payment never clears an open dispute", () => { |
| 153 | const db = database(); |
| 154 | db.prepare("INSERT INTO limits (workspace, updated_at, autopay_failed_at) VALUES (?, ?, ?)").run("fixture", at, at); |
| 155 | db.prepare("INSERT INTO disputes (dispute_id, workspace, charge_id, status, updated_at) VALUES ('dp_fixture', 'fixture', 'ch_fixture', 'open', ?)").run(at); |
| 156 | batch(db, payment("cs_fixture")); |
| 157 | assert.equal(db.prepare("SELECT autopay_failed_at FROM limits WHERE workspace='fixture'").get().autopay_failed_at, at); |
| 158 | db.close(); |
| 159 | }); |
| 160 | test("concurrent invoice requests freeze one payload even as usage changes", () => { |
| 161 | const db = database(); |
| 162 | db.prepare("INSERT INTO accounts (workspace, balance_micros, created_at) VALUES ('fixture', -10000000, ?)").run(at); |
| 163 | const insert = db.prepare(constant("invoice_attempt", "INSERT")); |
| 164 | insert.run("attempt_a", "fixture", '{"amount":1000}', 1000, -10_000_000); |
| 165 | db.exec("UPDATE accounts SET balance_micros=-20000000 WHERE workspace='fixture'"); |
| 166 | insert.run("attempt_b", "fixture", '{"amount":2000}', 2000, -20_000_000); |
| 167 | assert.deepEqual({ ...db.prepare("SELECT id, payload FROM invoice_attempts").get() }, { id: "attempt_a", payload: '{"amount":1000}' }); |
| 168 | assert.equal(db.prepare(constant("invoice_attempt", "RETIRE")).run("fixture").changes, 0); |
| 169 | assert.equal(db.prepare(constant("closing", "UNPAID_INVOICES_SQL")).get("fixture").n, 1); |
| 170 | db.close(); |
| 171 | }); |
| 172 | test("a stale invoice calculation cannot create an attempt after payment changes the balance", () => { |
| 173 | const db = database(); |
| 174 | db.prepare("INSERT INTO accounts (workspace, balance_micros, created_at) VALUES ('fixture', 0, ?)").run(at); |
| 175 | const result = db.prepare(constant("invoice_attempt", "INSERT")).run("attempt_a", "fixture", "{}", 1000, -10_000_000); |
| 176 | assert.equal(result.changes, 0); |
| 177 | db.close(); |
| 178 | }); |
| 179 | test("the migration registry covers every billing migration", () => { |
| 180 | const dir = new URL("../services/billing/migrations/", import.meta.url); |
| 181 | const lib = source("lib"); |
| 182 | for (const name of readdirSync(dir).filter(n => n.endsWith(".sql"))) assert.ok(lib.includes(`include_str!("../migrations/${name}")`), name); |
| 183 | }); |
| 184 | |
| 185 | const sqlFile = name => readFileSync(new URL(`../services/billing/src/${name}.sql`, import.meta.url), "utf8"); |
| 186 | function refund(db, cents, tax, plan = false) { |
| 187 | const reference = `refund/ch_fixture/${cents + tax}`; |
| 188 | const writes = [[sqlFile(plan ? "refund_plan" : "refund_ledger"), [reference, "fixture", cents * 10_000, reference, at, "refund/ch_fixture/%"]]]; |
| 189 | if (!plan) writes.push([constant("webhooks", "REFUND_BALANCE"), [reference, "fixture"]]); |
| 190 | writes.push([sqlFile("refund_extras"), [`${reference}/tax`, "fixture", "tax", tax * 10_000, reference, "pi_fixture", at, "refund/ch_fixture/%"]]); |
| 191 | batch(db, writes); |
| 192 | } |
| 193 | test("partial refunds, duplicate deliveries and reversed ordering debit only the cumulative total", () => { |
| 194 | for (const order of [[1000, 2500, 2500], [2500, 1000, 2500]]) { |
| 195 | const db = database(); |
| 196 | batch(db, payment("cs_fixture")); |
| 197 | for (const cents of order) refund(db, cents, cents * 0.08); |
| 198 | assert.equal(db.prepare("SELECT balance_micros FROM accounts WHERE workspace='fixture'").get().balance_micros, 0); |
| 199 | assert.equal(db.prepare("SELECT SUM(amount_micros) n FROM tax_and_fees WHERE workspace='fixture'").get().n, 0); |
| 200 | db.close(); |
| 201 | } |
| 202 | }); |
| 203 | test("refund tax failure rolls back the reversal and retries without a second debit", () => { |
| 204 | const db = database(); |
| 205 | batch(db, payment("cs_fixture")); |
| 206 | db.exec("CREATE TRIGGER fail_refund_tax BEFORE INSERT ON tax_and_fees WHEN NEW.amount_micros < 0 BEGIN SELECT RAISE(ABORT, 'injected failure'); END"); |
| 207 | assert.throws(() => refund(db, 2500, 200), /injected failure/); |
| 208 | assert.equal(db.prepare("SELECT balance_micros FROM accounts WHERE workspace='fixture'").get().balance_micros, 25_000_000); |
| 209 | db.exec("DROP TRIGGER fail_refund_tax"); |
| 210 | refund(db, 2500, 200); |
| 211 | refund(db, 2500, 200); |
| 212 | assert.equal(db.prepare("SELECT balance_micros FROM accounts WHERE workspace='fixture'").get().balance_micros, 0); |
| 213 | db.close(); |
| 214 | }); |
| 215 | test("plan refunds reduce revenue without debiting prepaid usage credit", () => { |
| 216 | const db = database(); |
| 217 | batch(db, payment("cs_fixture")); |
| 218 | refund(db, 1000, 80, true); |
| 219 | refund(db, 2500, 200, true); |
| 220 | refund(db, 1000, 80, true); |
| 221 | assert.equal(db.prepare("SELECT SUM(amount_micros) n FROM plan_payments WHERE workspace='fixture'").get().n, -25_000_000); |
| 222 | assert.equal(db.prepare("SELECT balance_micros FROM accounts WHERE workspace='fixture'").get().balance_micros, 25_000_000); |
| 223 | db.close(); |
| 224 | }); |
| 225 | |
| 226 | test("one card cannot fund concurrent trials or another trial after being replaced", () => { |
| 227 | const db = database(); |
| 228 | const grantSql = prepares("credits", "pub(crate) async fn ensure_grant(", "/// Takes up to")[0]; |
| 229 | const card = db.prepare("INSERT INTO card_checks (workspace, setup_intent, payment_method, fingerprint, funding, checked_by, checked_at) VALUES (?, ?, ?, ?, 'credit', 'fixture', ?)"); |
| 230 | card.run("trial_a", "seti_a", "pm_a", "same_card", at); |
| 231 | card.run("trial_b", "seti_b", "pm_b", "same_card", at); |
| 232 | const grant = db.prepare(grantSql); |
| 233 | grant.run("trial_a", "2026-10", 5_000_000, at, 100_000_000); |
| 234 | grant.run("trial_b", "2026-10", 5_000_000, at, 100_000_000); |
| 235 | assert.equal(db.prepare("SELECT COUNT(*) n FROM trial_grants WHERE workspace IN ('trial_a','trial_b')").get().n, 1); |
| 236 | db.exec("UPDATE card_checks SET fingerprint='replacement_card' WHERE workspace='trial_a'"); |
| 237 | grant.run("trial_b", "2026-10", 5_000_000, at, 100_000_000); |
| 238 | assert.equal(db.prepare("SELECT COUNT(*) n FROM trial_grants WHERE workspace='trial_b'").get().n, 0); |
| 239 | db.close(); |
| 240 | }); |
| 241 | |
| 242 | function usage(id, reference, workspace, gross, { plan = 10_000_000, trial = 1, pool = 1_000_000, repo = 1_000_000, given = 0, when = at } = {}) { |
| 243 | const insert = prepares("storage", "pub(crate) async fn post_usage_with(", "/// Takes `charged`")[0]; |
| 244 | const balance = prepares("storage", "pub(crate) fn balance_if_posted(", "/// Writes down")[0]; |
| 245 | const month = when.slice(0, 7); |
| 246 | return [ |
| 247 | [insert, [id, workspace, -gross, "Usage", `${workspace}/repo`, "sandbox", gross, reference, when, 0, 0, 0, 0, null]], |
| 248 | [sqlFile("allocate_usage"), [id, workspace, month, plan, trial, `${workspace}/repo`, pool, repo, given]], |
| 249 | [constant("allocation", "PLAN"), [id, month]], |
| 250 | [constant("allocation", "GIFT"), [id, month]], |
| 251 | [constant("allocation", "TRIAL"), [id]], |
| 252 | [constant("allocation", "OSS_POOL"), [id, month]], |
| 253 | [constant("allocation", "OSS_REPO"), [id, month, `${workspace}/repo`]], |
| 254 | [balance, [workspace, at, id]], |
| 255 | ]; |
| 256 | } |
| 257 | test("usage allocation, source debits and ledger posting conserve credit across retries", () => { |
| 258 | const db = database(); |
| 259 | db.prepare("INSERT INTO trial_grants (workspace, month, granted_micros, used_micros, created_at) VALUES ('fixture', '2026-10', 1000000, 0, ?)").run(at); |
| 260 | batch(db, usage("usage_a", "run/a", "fixture", 12_000_000)); |
| 261 | const read = () => ({ ...db.prepare("SELECT amount_micros, credit_micros, trial_micros, oss_micros FROM ledger WHERE id='usage_a'").get() }); |
| 262 | assert.deepEqual(read(), { amount_micros: 0, credit_micros: 10_000_000, trial_micros: 1_000_000, oss_micros: 1_000_000 }); |
| 263 | batch(db, usage("duplicate", "run/a", "fixture", 12_000_000)); |
| 264 | assert.equal(db.prepare("SELECT SUM(used) n FROM allowance_use WHERE kind='plan_credit'").get().n, 10_000_000); |
| 265 | batch(db, usage("usage_b", "run/b", "fixture", 2_000_000)); |
| 266 | assert.equal(db.prepare("SELECT balance_micros FROM accounts WHERE workspace='fixture'").get().balance_micros, -2_000_000); |
| 267 | db.close(); |
| 268 | }); |
| 269 | test("an interrupted usage transaction consumes no allowance and a retry posts once", () => { |
| 270 | const db = database(); |
| 271 | db.exec("CREATE TRIGGER fail_usage_balance BEFORE INSERT ON accounts WHEN NEW.workspace='fixture' BEGIN SELECT RAISE(ABORT, 'injected failure'); END"); |
| 272 | assert.throws(() => batch(db, usage("usage_a", "run/a", "fixture", 5_000_000)), /injected failure/); |
| 273 | assert.equal(db.prepare("SELECT COUNT(*) n FROM ledger WHERE id='usage_a'").get().n, 0); |
| 274 | assert.equal(db.prepare("SELECT COUNT(*) n FROM allowance_use WHERE scope='fixture'").get().n, 0); |
| 275 | db.exec("DROP TRIGGER fail_usage_balance"); |
| 276 | batch(db, usage("usage_b", "run/a", "fixture", 5_000_000)); |
| 277 | assert.equal(db.prepare("SELECT used FROM allowance_use WHERE scope='fixture' AND kind='plan_credit'").get().used, 5_000_000); |
| 278 | db.close(); |
| 279 | }); |
| 280 | test("different workspaces share one bounded OSS pool and free overruns remain explicit", () => { |
| 281 | const db = database(); |
| 282 | batch(db, usage("a", "run/a", "a", 800_000, { plan: 0, trial: 0 })); |
| 283 | batch(db, usage("b", "run/b", "b", 800_000, { plan: 0, trial: 0, given: 1 })); |
| 284 | assert.equal(db.prepare("SELECT used FROM allowance_use WHERE kind='oss_pool'").get().used, 1_000_000); |
| 285 | assert.deepEqual({ ...db.prepare("SELECT amount_micros, oss_micros, given_micros FROM ledger WHERE id='b'").get() }, { amount_micros: 0, oss_micros: 200_000, given_micros: 600_000 }); |
| 286 | db.close(); |
| 287 | }); |