Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

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