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.

269 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// Complimentary enrollment against the complete migrated schema, using the
7// production SQL: the allocation that posts usage, and the terms change as
8// `admin_set_complimentary` writes it.
9const source = (name) => readFileSync(new URL(`../services/billing/src/${name}.rs`, import.meta.url), "utf8");
10const sqlFile = (name) => readFileSync(new URL(`../services/billing/src/${name}.sql`, import.meta.url), "utf8");
11const constant = (file, name) => {
12 const match = source(file).match(new RegExp(`const ${name}: &str = "([\\s\\S]*?)";`));
13 assert.ok(match, `${file}::${name}`);
14 return match[1];
15};
16const prepares = (file, from, to) => {
17 const text = source(file).split(from)[1].split(to)[0];
18 return [...text.matchAll(/\.prepare\(\s*"([\s\S]*?)"\s*,?\s*\)/g)].map((m) => m[1]);
19};
20const migrations = new URL("../services/billing/migrations/", import.meta.url);
21const names = readdirSync(migrations)
22 .filter((n) => n.endsWith(".sql"))
23 .sort();
24function database(before = null) {
25 const db = new DatabaseSync(":memory:");
26 for (const name of names.filter((n) => before === null || n < before)) db.exec(readFileSync(new URL(name, migrations), "utf8"));
27 return db;
28}
29function batch(db, writes) {
30 db.exec("BEGIN");
31 try {
32 for (const [sql, args] of writes) db.prepare(sql).run(...args);
33 db.exec("COMMIT");
34 } catch (e) {
35 db.exec("ROLLBACK");
36 throw e;
37 }
38}
39const at = "2026-10-14T12:00:00.000Z";
40function usage(id, reference, workspace, gross, { plan = 10_000_000, trial = 1, given = 0, when = at } = {}) {
41 const insert = prepares("storage", "pub(crate) async fn post_usage_with(", "/// Takes `charged`")[0];
42 const balance = prepares("storage", "pub(crate) fn balance_if_posted(", "/// Writes down")[0];
43 const month = when.slice(0, 7);
44 return [
45 [insert, [id, workspace, -gross, "Usage", `${workspace}/repo`, "sandbox", gross, reference, when, 0, 0, 0, 0, null]],
46 [sqlFile("allocate_usage"), [id, workspace, month, plan, trial, `${workspace}/repo`, 1_000_000, 1_000_000, given]],
47 [constant("allocation", "PLAN"), [id, month]],
48 [constant("allocation", "GIFT"), [id, month]],
49 [constant("allocation", "TRIAL"), [id]],
50 [constant("allocation", "OSS_POOL"), [id, month]],
51 [constant("allocation", "OSS_REPO"), [id, month, `${workspace}/repo`]],
52 [balance, [workspace, when, id]],
53 ];
54}
55const enrolledAt = "2026-10-01T00:00:00.000Z";
56function enroll(db, workspace, allowance, { unlimited = 0, overage = "stop" } = {}) {
57 db.prepare(
58 `INSERT INTO complimentary (workspace, grant_id, status, allowance_micros, unlimited, fee_cents, note, created_by, created_at, created_ms, updated_by, updated_at, subscription_id, overage)
59 VALUES (?, ?, 'active', ?, ?, 0, 'partner', 'staff', ?, 0, 'staff', ?, ?, ?)`,
60 ).run(workspace, `cmp_${workspace}`, allowance, unlimited, enrolledAt, enrolledAt, `sub_${workspace}`, overage);
61 db.prepare(
62 `INSERT INTO complimentary_periods (id, workspace, grant_id, starts_at, allowance_micros, unlimited, fee_cents, note, created_by, created_at, overage)
63 VALUES (?, ?, ?, ?, ?, ?, 0, 'partner', 'staff', ?, ?)`,
64 ).run(`p_${workspace}`, workspace, `cmp_${workspace}`, enrolledAt, allowance, unlimited, enrolledAt, overage);
65}
66const termsChange = prepares("complimentary", "// One batch: the open period closes", "self.audit(");
67function changeTerms(db, workspace, allowance, when, overage = "stop") {
68 assert.equal(termsChange.length, 3);
69 batch(db, [
70 [termsChange[0], [workspace, when]],
71 [termsChange[1], [`p_${when}`, workspace, `cmp_${workspace}`, when, allowance, 0, 0, "changed", "staff", overage]],
72 [termsChange[2], [workspace, allowance, 0, 0, "changed", "staff", when, JSON.stringify({ op: "terms", period: `p_${when}` }), overage]],
73 ]);
74}
75const line = (db, id) => ({
76 ...db.prepare("SELECT amount_micros, credit_micros, gift_micros, trial_micros, oss_micros, given_micros FROM ledger WHERE id=?").get(id),
77});
78const giftUsed = (db, workspace, month = "2026-10") =>
79 db.prepare("SELECT used FROM allowance_use WHERE kind='complimentary' AND scope=? AND month=?").get(workspace, month)?.used ?? 0;
80
81test("a complimentary allowance pays first and alone, and past it g1t covers rather than charging", () => {
82 const db = database();
83 enroll(db, "acme", 10_000_000);
84 db.prepare("INSERT INTO trial_grants (workspace, month, granted_micros, used_micros, created_at) VALUES ('acme', '2026-10', 5000000, 0, ?)").run(at);
85 batch(db, usage("a", "run/a", "acme", 6_000_000));
86 assert.deepEqual(line(db, "a"), { amount_micros: 0, credit_micros: 0, gift_micros: 6_000_000, trial_micros: 0, oss_micros: 0, given_micros: 0 });
87 // Running work that outlasts the allowance: the rest is g1t's, recorded
88 // apart from the allowance, and nothing is owed.
89 batch(db, usage("b", "run/b", "acme", 6_000_000));
90 assert.deepEqual(line(db, "b"), { amount_micros: 0, credit_micros: 0, gift_micros: 4_000_000, trial_micros: 0, oss_micros: 0, given_micros: 2_000_000 });
91 assert.equal(giftUsed(db, "acme"), 10_000_000);
92 assert.equal(db.prepare("SELECT balance_micros FROM accounts WHERE workspace='acme'").get().balance_micros, 0);
93 // Plan credit, the trial and the pools were never touched.
94 assert.equal(db.prepare("SELECT COUNT(*) n FROM allowance_use WHERE kind IN ('plan_credit','oss_pool','oss_repo')").get().n, 0);
95 assert.equal(db.prepare("SELECT used_micros FROM trial_grants WHERE workspace='acme'").get().used_micros, 0);
96 // A duplicate delivery consumes nothing more.
97 batch(db, usage("dup", "run/b", "acme", 6_000_000));
98 assert.equal(giftUsed(db, "acme"), 10_000_000);
99 assert.equal(db.prepare("SELECT COUNT(*) n FROM ledger").get().n, 2);
100 db.close();
101});
102
103test("changing the amount keeps the month's consumption; lowering it never creates a debt", () => {
104 const db = database();
105 enroll(db, "acme", 10_000_000);
106 batch(db, usage("a", "run/a", "acme", 8_000_000, { when: "2026-10-10T00:00:00.000Z" }));
107 changeTerms(db, "acme", 5_000_000, "2026-10-11T00:00:00.000Z");
108 assert.equal(db.prepare("SELECT COUNT(*) n FROM complimentary_periods WHERE workspace='acme' AND ends_at IS NULL").get().n, 1);
109 assert.equal(db.prepare("SELECT allowance_micros FROM complimentary WHERE workspace='acme'").get().allowance_micros, 5_000_000);
110 // Lowered below what was used: nothing more from it, nothing owed.
111 batch(db, usage("b", "run/b", "acme", 1_000_000, { when: "2026-10-12T00:00:00.000Z" }));
112 assert.deepEqual(line(db, "b"), { amount_micros: 0, credit_micros: 0, gift_micros: 0, trial_micros: 0, oss_micros: 0, given_micros: 1_000_000 });
113 assert.equal(giftUsed(db, "acme"), 8_000_000, "the earlier draw is kept, not reset");
114 // Raised: only what is over the month's use is left.
115 changeTerms(db, "acme", 20_000_000, "2026-10-13T00:00:00.000Z");
116 batch(db, usage("c", "run/c", "acme", 15_000_000, { when: "2026-10-14T00:00:00.000Z" }));
117 assert.equal(line(db, "c").gift_micros, 12_000_000);
118 assert.equal(line(db, "c").given_micros, 3_000_000);
119 assert.equal(giftUsed(db, "acme"), 20_000_000);
120 // A new month starts the allowance again, with no rollover.
121 batch(db, usage("d", "run/d", "acme", 25_000_000, { when: "2026-11-01T00:00:01.000Z" }));
122 assert.equal(line(db, "d").gift_micros, 20_000_000);
123 assert.equal(giftUsed(db, "acme", "2026-11"), 20_000_000);
124 assert.equal(db.prepare("SELECT SUM(amount_micros) n FROM ledger").get().n, 0, "nothing was ever charged");
125 db.close();
126});
127
128test("late usage draws on the period it happened in, not the one it is posted in", () => {
129 const db = database();
130 enroll(db, "acme", 10_000_000);
131 // Converted to the plan on the 15th.
132 db.exec("UPDATE complimentary_periods SET ends_at='2026-10-15T00:00:00.000Z'; UPDATE complimentary SET status='ended', ended_reason='converted'");
133 batch(db, usage("before", "run/before", "acme", 3_000_000, { when: "2026-10-14T23:00:00.000Z" }));
134 assert.equal(line(db, "before").gift_micros, 3_000_000, "gifted usage is never repriced after conversion");
135 assert.equal(line(db, "before").amount_micros, 0);
136 batch(db, usage("after", "run/after", "acme", 3_000_000, { when: "2026-10-15T01:00:00.000Z" }));
137 assert.deepEqual(line(db, "after"), { amount_micros: 0, credit_micros: 3_000_000, gift_micros: 0, trial_micros: 0, oss_micros: 0, given_micros: 0 });
138 db.close();
139});
140
141test("charged past the allowance: g1t pays the allowance, the workspace's own card the rest", () => {
142 const db = database();
143 enroll(db, "friend", 10_000_000, { overage: "charge" });
144 // No card yet: past the allowance it is g1t's, never a debt.
145 batch(db, usage("z", "run/z", "friend", 12_000_000, { when: "2026-11-02T00:00:00.000Z" }));
146 assert.deepEqual(line(db, "z"), { amount_micros: 0, credit_micros: 0, gift_micros: 10_000_000, trial_micros: 0, oss_micros: 0, given_micros: 2_000_000 });
147 db.prepare("INSERT INTO card_checks (workspace, setup_intent, payment_method, checked_by, checked_at) VALUES ('friend', 'seti_1', 'pm_1', 'owner', ?)").run(
148 at,
149 );
150 batch(db, usage("a", "run/a", "friend", 6_000_000));
151 batch(db, usage("b", "run/b", "friend", 7_000_000));
152 // 4 of 7 from the allowance, 3 charged; nothing covered by g1t.
153 assert.deepEqual(line(db, "b"), { amount_micros: -3_000_000, credit_micros: 0, gift_micros: 4_000_000, trial_micros: 0, oss_micros: 0, given_micros: 0 });
154 assert.equal(db.prepare("SELECT balance_micros FROM accounts WHERE workspace='friend'").get().balance_micros, -3_000_000);
155 // Switched to stop mid-month: from then, past the allowance is g1t's.
156 changeTerms(db, "friend", 10_000_000, "2026-10-15T00:00:00.000Z", "stop");
157 batch(db, usage("c", "run/c", "friend", 1_000_000, { when: "2026-10-16T00:00:00.000Z" }));
158 assert.deepEqual(line(db, "c"), { amount_micros: 0, credit_micros: 0, gift_micros: 0, trial_micros: 0, oss_micros: 0, given_micros: 1_000_000 });
159 // Usage from before the switch, posted late, keeps the period it happened in.
160 batch(db, usage("d", "run/d", "friend", 2_000_000, { when: "2026-10-14T00:00:00.000Z" }));
161 assert.equal(line(db, "d").amount_micros, -2_000_000);
162 db.close();
163});
164
165test("an enrollment's fee paid while enrolled is not evidence of the plan", () => {
166 const db = database();
167 enroll(db, "acme", 10_000_000);
168 db.exec("UPDATE complimentary_periods SET ends_at='2026-10-15T00:00:00.000Z'");
169 const evidence = db.prepare(constant("storage", "PLAN_EVIDENCE"));
170 db.exec("UPDATE complimentary_periods SET fee_cents = 2500");
171 db.prepare("INSERT INTO plan_payments (invoice_id, workspace, amount_micros, paid_at) VALUES ('in_fee', 'acme', 25000000, '2026-10-02T00:00:00.000Z')").run();
172 assert.equal(evidence.get("acme", "2026-10-01", "2026-11-01", "2026-10").had, 0);
173 // The conversion's first plan payment, made while the period is still open, is the plan.
174 db.prepare(
175 "INSERT INTO plan_payments (invoice_id, workspace, amount_micros, paid_at) VALUES ('in_plan', 'acme', 21000000, '2026-10-14T23:59:00.000Z')",
176 ).run();
177 assert.equal(evidence.get("acme", "2026-10-01", "2026-11-01", "2026-10").had, 1);
178 db.close();
179});
180
181test("an unlimited enrollment pays everything and still records what it used", () => {
182 const db = database();
183 enroll(db, "flagon-io", 0, { unlimited: 1 });
184 batch(db, usage("a", "run/a", "flagon-io", 900_000_000));
185 assert.equal(line(db, "a").gift_micros, 900_000_000);
186 assert.equal(line(db, "a").given_micros, 0);
187 assert.equal(giftUsed(db, "flagon-io"), 900_000_000);
188 db.close();
189});
190
191test("an interrupted posting consumes no complimentary allowance", () => {
192 const db = database();
193 enroll(db, "acme", 10_000_000);
194 db.exec("CREATE TRIGGER fail_balance BEFORE INSERT ON accounts WHEN NEW.workspace='acme' BEGIN SELECT RAISE(ABORT, 'injected failure'); END");
195 assert.throws(() => batch(db, usage("a", "run/a", "acme", 4_000_000)), /injected failure/);
196 assert.equal(giftUsed(db, "acme"), 0);
197 db.exec("DROP TRIGGER fail_balance");
198 batch(db, usage("b", "run/a", "acme", 4_000_000));
199 assert.equal(giftUsed(db, "acme"), 4_000_000);
200 db.close();
201});
202
203test("one open period per workspace", () => {
204 const db = database();
205 enroll(db, "acme", 1);
206 assert.throws(
207 () =>
208 db
209 .prepare(
210 `INSERT INTO complimentary_periods (id, workspace, grant_id, starts_at, allowance_micros, note, created_by, created_at)
211 VALUES ('second', 'acme', 'cmp_acme', ?, 1, 'x', 'staff', ?)`,
212 )
213 .run(at, at),
214 /UNIQUE/,
215 );
216 db.close();
217});
218
219test("migration 0065 returns every workspace but flagon-io to Free, with an audit entry", () => {
220 const db = database("0065");
221 const account = db.prepare(
222 "INSERT INTO billing_accounts (id, kind, name, terms_kind, discount_percent, team_granted, created_by, created_at) VALUES (?, ?, ?, ?, ?, ?, 'staff', ?)",
223 );
224 account.run("ws_flagon-io-x", "workspace", "flagon-io-x", "comped", 100, 0, at);
225 db.prepare("UPDATE billing_accounts SET terms_kind='custom' WHERE id='ws_flagon-io'").run();
226 account.run("ws_partner", "workspace", "partner", "comped", 100, 0, at);
227 account.run("ws_given", "workspace", "given", "standard", 0, 1, at);
228 account.run("ws_plain", "workspace", "plain", "standard", 0, 0, at);
229 db.prepare("INSERT INTO account_members (workspace, account_id, added_by, added_at) VALUES ('member', 'ent_x', 'staff', ?)").run(at);
230 // One on an enterprise invoice still being made: kept, not a failed deploy.
231 db.prepare("INSERT INTO account_members (workspace, account_id, added_by, added_at) VALUES ('invoicing', 'ent_y', 'staff', ?)").run(at);
232 db.prepare("INSERT INTO enterprise_invoice_attempts (account_id, id, payload, created_ms) VALUES ('ent_y', 'att', ?, 1)").run(
233 JSON.stringify({ lines: [{ workspace: "invoicing", amountMicros: 1 }] }),
234 );
235 const flagonBefore = db.prepare("SELECT * FROM billing_accounts WHERE id='ws_flagon-io'").get();
236 db.exec(
237 readFileSync(
238 new URL(
239 names.find((n) => n.startsWith("0065")),
240 migrations,
241 ),
242 "utf8",
243 ),
244 );
245 const terms = Object.fromEntries(
246 db
247 .prepare("SELECT id, terms_kind, discount_percent, team_granted FROM billing_accounts")
248 .all()
249 .map((r) => [r.id, [r.terms_kind, r.discount_percent, r.team_granted]]),
250 );
251 assert.deepEqual({ ...db.prepare("SELECT * FROM billing_accounts WHERE id='ws_flagon-io'").get() }, { ...flagonBefore }, "flagon-io is untouched");
252 assert.deepEqual(terms["ws_flagon-io-x"], ["standard", 0, 0], "only flagon-io itself is kept");
253 assert.deepEqual(terms.ws_partner, ["standard", 0, 0]);
254 assert.deepEqual(terms.ws_given, ["standard", 0, 0]);
255 assert.deepEqual(terms.ws_plain, ["standard", 0, 0]);
256 assert.deepEqual(
257 db
258 .prepare("SELECT workspace FROM account_members")
259 .all()
260 .map((r) => r.workspace),
261 ["invoicing"],
262 );
263 const audited = db
264 .prepare("SELECT account FROM admin_actions WHERE by='billing' ORDER BY account")
265 .all()
266 .map((r) => r.account);
267 assert.deepEqual(audited, ["ent_x", "ws_flagon-io-x", "ws_given", "ws_partner"]);
268 db.close();
269});