@wopr-network/platform-core 1.13.3 → 1.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/.github/workflows/dependabot-auto-merge.yml +1 -2
  2. package/dist/api/routes/admin-credits.d.ts +2 -2
  3. package/dist/api/routes/admin-credits.js +9 -4
  4. package/dist/api/routes/quota.d.ts +2 -2
  5. package/dist/api/routes/verify-email.d.ts +3 -3
  6. package/dist/backup/on-demand-snapshot-service.d.ts +2 -2
  7. package/dist/billing/payram/webhook.d.ts +3 -3
  8. package/dist/billing/payram/webhook.js +5 -1
  9. package/dist/billing/payram/webhook.test.js +5 -4
  10. package/dist/billing/stripe/stripe-payment-processor.d.ts +2 -2
  11. package/dist/billing/stripe/stripe-payment-processor.test.js +7 -0
  12. package/dist/billing/stripe/tenant-store.d.ts +1 -1
  13. package/dist/billing/stripe/tenant-store.js +1 -1
  14. package/dist/credits/auto-topup-charge.d.ts +2 -2
  15. package/dist/credits/auto-topup-charge.js +5 -1
  16. package/dist/credits/auto-topup-charge.test.js +5 -4
  17. package/dist/credits/auto-topup-usage.d.ts +2 -2
  18. package/dist/credits/auto-topup-usage.test.js +53 -12
  19. package/dist/credits/credit-expiry-cron.d.ts +2 -2
  20. package/dist/credits/credit-expiry-cron.js +7 -4
  21. package/dist/credits/credit-expiry-cron.test.js +25 -8
  22. package/dist/credits/credit-ledger.d.ts +2 -2
  23. package/dist/credits/credit-ledger.js +1 -1
  24. package/dist/credits/dividend-cron.d.ts +4 -6
  25. package/dist/credits/dividend-cron.js +10 -16
  26. package/dist/credits/dividend-cron.test.js +31 -44
  27. package/dist/credits/dividend-repository.js +19 -22
  28. package/dist/credits/dividend-repository.test.js +4 -3
  29. package/dist/credits/index.d.ts +4 -2
  30. package/dist/credits/index.js +2 -1
  31. package/dist/credits/ledger.d.ts +195 -0
  32. package/dist/credits/ledger.js +561 -0
  33. package/dist/credits/ledger.test.js +418 -0
  34. package/dist/credits/signup-grant.d.ts +2 -2
  35. package/dist/credits/signup-grant.js +4 -4
  36. package/dist/credits/signup-grant.test.js +5 -3
  37. package/dist/credits/trial-balance-cron.d.ts +19 -0
  38. package/dist/credits/trial-balance-cron.js +30 -0
  39. package/dist/credits/trial-balance-cron.test.js +55 -0
  40. package/dist/db/schema/index.d.ts +1 -0
  41. package/dist/db/schema/index.js +1 -0
  42. package/dist/db/schema/ledger.d.ts +442 -0
  43. package/dist/db/schema/ledger.js +76 -0
  44. package/dist/gateway/credit-gate.d.ts +2 -2
  45. package/dist/gateway/credit-gate.js +5 -1
  46. package/dist/gateway/credit-gate.test.js +35 -33
  47. package/dist/gateway/protocol/deps.d.ts +2 -2
  48. package/dist/gateway/protocol/handlers.test.js +461 -0
  49. package/dist/gateway/proxy.d.ts +2 -2
  50. package/dist/gateway/types.d.ts +2 -2
  51. package/dist/metering/reconciliation-cron.test.js +9 -8
  52. package/dist/metering/reconciliation-repository.js +12 -10
  53. package/dist/metering/reconciliation-repository.test.js +9 -8
  54. package/dist/monetization/affiliate/affiliate-admin-repository.js +10 -8
  55. package/dist/monetization/affiliate/affiliate-admin-repository.test.js +32 -13
  56. package/dist/monetization/affiliate/credit-match.d.ts +2 -2
  57. package/dist/monetization/affiliate/credit-match.js +4 -1
  58. package/dist/monetization/affiliate/credit-match.test.js +58 -13
  59. package/dist/monetization/affiliate/new-user-bonus.d.ts +2 -2
  60. package/dist/monetization/affiliate/new-user-bonus.js +4 -1
  61. package/dist/monetization/affiliate/new-user-bonus.test.js +4 -3
  62. package/dist/monetization/credits/auto-topup-charge.d.ts +2 -2
  63. package/dist/monetization/credits/auto-topup-charge.js +5 -1
  64. package/dist/monetization/credits/auto-topup-charge.test.js +5 -4
  65. package/dist/monetization/credits/auto-topup-usage.d.ts +2 -2
  66. package/dist/monetization/credits/auto-topup-usage.test.js +53 -12
  67. package/dist/monetization/credits/bot-billing.d.ts +3 -3
  68. package/dist/monetization/credits/bot-billing.test.js +18 -5
  69. package/dist/monetization/credits/credit-expiry-cron.test.js +25 -8
  70. package/dist/monetization/credits/dividend-cron.d.ts +2 -4
  71. package/dist/monetization/credits/dividend-cron.js +7 -4
  72. package/dist/monetization/credits/dividend-cron.test.js +26 -46
  73. package/dist/monetization/credits/dividend-repository.js +15 -24
  74. package/dist/monetization/credits/dividend-repository.test.js +4 -3
  75. package/dist/monetization/credits/index.d.ts +2 -2
  76. package/dist/monetization/credits/index.js +1 -1
  77. package/dist/monetization/credits/member-usage.test.js +23 -10
  78. package/dist/monetization/credits/phone-billing.d.ts +2 -2
  79. package/dist/monetization/credits/phone-billing.js +5 -1
  80. package/dist/monetization/credits/phone-billing.test.js +9 -12
  81. package/dist/monetization/credits/runtime-cron.d.ts +2 -2
  82. package/dist/monetization/credits/runtime-cron.js +32 -8
  83. package/dist/monetization/credits/runtime-cron.test.js +28 -27
  84. package/dist/monetization/credits/runtime-scheduler.d.ts +2 -2
  85. package/dist/monetization/credits/runtime-scheduler.test.js +1 -1
  86. package/dist/monetization/credits/signup-grant.test.js +5 -3
  87. package/dist/monetization/credits/storage-tier-cron.test.js +3 -2
  88. package/dist/monetization/credits/trial-balance-cron.test.js +42 -0
  89. package/dist/monetization/feature-gate.d.ts +3 -3
  90. package/dist/monetization/index.d.ts +3 -3
  91. package/dist/monetization/index.js +1 -1
  92. package/dist/monetization/metering/reconciliation-cron.test.js +9 -8
  93. package/dist/monetization/metering/reconciliation-repository.js +11 -10
  94. package/dist/monetization/metering/reconciliation-repository.test.js +9 -8
  95. package/dist/monetization/payram/webhook.d.ts +2 -2
  96. package/dist/monetization/payram/webhook.js +5 -1
  97. package/dist/monetization/payram/webhook.test.js +5 -4
  98. package/dist/monetization/promotions/engine.d.ts +2 -2
  99. package/dist/monetization/promotions/engine.js +4 -1
  100. package/dist/monetization/promotions/engine.test.js +3 -1
  101. package/dist/monetization/repository-types.d.ts +1 -1
  102. package/dist/monetization/stripe/stripe-payment-processor.d.ts +2 -2
  103. package/dist/monetization/stripe/stripe-payment-processor.test.js +7 -0
  104. package/dist/monetization/stripe/webhook.d.ts +2 -2
  105. package/dist/monetization/stripe/webhook.js +70 -6
  106. package/dist/monetization/stripe/webhook.test.js +20 -15
  107. package/dist/onboarding/onboarding-service.d.ts +2 -2
  108. package/dist/onboarding/onboarding-service.js +6 -2
  109. package/drizzle/migrations/0003_double_entry_ledger.sql +82 -0
  110. package/drizzle/migrations/meta/_journal.json +7 -0
  111. package/package.json +1 -1
  112. package/src/api/routes/admin-credits.ts +11 -14
  113. package/src/api/routes/quota.ts +2 -2
  114. package/src/api/routes/verify-email.ts +4 -4
  115. package/src/backup/on-demand-snapshot-service.test.ts +3 -3
  116. package/src/backup/on-demand-snapshot-service.ts +3 -3
  117. package/src/billing/payram/webhook.test.ts +7 -5
  118. package/src/billing/payram/webhook.ts +8 -11
  119. package/src/billing/stripe/stripe-payment-processor.test.ts +10 -3
  120. package/src/billing/stripe/stripe-payment-processor.ts +3 -3
  121. package/src/billing/stripe/tenant-store.ts +1 -1
  122. package/src/credits/auto-topup-charge.test.ts +7 -5
  123. package/src/credits/auto-topup-charge.ts +7 -10
  124. package/src/credits/auto-topup-usage.test.ts +55 -13
  125. package/src/credits/auto-topup-usage.ts +2 -2
  126. package/src/credits/credit-expiry-cron.test.ts +26 -45
  127. package/src/credits/credit-expiry-cron.ts +9 -12
  128. package/src/credits/credit-ledger.ts +3 -3
  129. package/src/credits/dividend-cron.test.ts +38 -45
  130. package/src/credits/dividend-cron.ts +12 -26
  131. package/src/credits/dividend-repository.test.ts +4 -3
  132. package/src/credits/dividend-repository.ts +21 -23
  133. package/src/credits/index.ts +23 -4
  134. package/src/credits/ledger.test.ts +514 -0
  135. package/src/credits/ledger.ts +851 -0
  136. package/src/credits/signup-grant.test.ts +7 -4
  137. package/src/credits/signup-grant.ts +6 -12
  138. package/src/credits/trial-balance-cron.test.ts +68 -0
  139. package/src/credits/trial-balance-cron.ts +46 -0
  140. package/src/db/schema/index.ts +1 -0
  141. package/src/db/schema/ledger.ts +94 -0
  142. package/src/gateway/credit-gate-wiring.test.ts +3 -3
  143. package/src/gateway/credit-gate.test.ts +35 -33
  144. package/src/gateway/credit-gate.ts +6 -10
  145. package/src/gateway/gateway-routes.test.ts +5 -5
  146. package/src/gateway/protocol/deps.ts +2 -2
  147. package/src/gateway/protocol/handlers.test.ts +549 -1
  148. package/src/gateway/proxy.ts +2 -2
  149. package/src/gateway/route-mounting.test.ts +2 -2
  150. package/src/gateway/types.ts +2 -2
  151. package/src/metering/reconciliation-cron.test.ts +10 -9
  152. package/src/metering/reconciliation-repository.test.ts +10 -9
  153. package/src/metering/reconciliation-repository.ts +14 -11
  154. package/src/monetization/affiliate/affiliate-admin-repository.test.ts +32 -19
  155. package/src/monetization/affiliate/affiliate-admin-repository.ts +16 -8
  156. package/src/monetization/affiliate/credit-match.test.ts +60 -14
  157. package/src/monetization/affiliate/credit-match.ts +6 -9
  158. package/src/monetization/affiliate/new-user-bonus.test.ts +6 -4
  159. package/src/monetization/affiliate/new-user-bonus.ts +6 -9
  160. package/src/monetization/credits/auto-topup-charge.test.ts +7 -5
  161. package/src/monetization/credits/auto-topup-charge.ts +7 -10
  162. package/src/monetization/credits/auto-topup-usage.test.ts +55 -13
  163. package/src/monetization/credits/auto-topup-usage.ts +2 -2
  164. package/src/monetization/credits/bot-billing.test.ts +20 -6
  165. package/src/monetization/credits/bot-billing.ts +3 -3
  166. package/src/monetization/credits/credit-expiry-cron.test.ts +26 -45
  167. package/src/monetization/credits/dividend-cron.test.ts +34 -48
  168. package/src/monetization/credits/dividend-cron.ts +9 -14
  169. package/src/monetization/credits/dividend-repository.test.ts +4 -3
  170. package/src/monetization/credits/dividend-repository.ts +19 -25
  171. package/src/monetization/credits/index.ts +4 -4
  172. package/src/monetization/credits/member-usage.test.ts +25 -11
  173. package/src/monetization/credits/phone-billing.test.ts +18 -26
  174. package/src/monetization/credits/phone-billing.ts +7 -10
  175. package/src/monetization/credits/runtime-cron.test.ts +29 -28
  176. package/src/monetization/credits/runtime-cron.ts +34 -58
  177. package/src/monetization/credits/runtime-scheduler.test.ts +1 -1
  178. package/src/monetization/credits/runtime-scheduler.ts +2 -2
  179. package/src/monetization/credits/signup-grant.test.ts +7 -4
  180. package/src/monetization/credits/storage-tier-cron.test.ts +5 -3
  181. package/src/monetization/credits/trial-balance-cron.test.ts +52 -0
  182. package/src/monetization/feature-gate.ts +3 -3
  183. package/src/monetization/index.ts +4 -4
  184. package/src/monetization/metering/reconciliation-cron.test.ts +10 -9
  185. package/src/monetization/metering/reconciliation-repository.test.ts +11 -9
  186. package/src/monetization/metering/reconciliation-repository.ts +13 -11
  187. package/src/monetization/payram/webhook.test.ts +7 -5
  188. package/src/monetization/payram/webhook.ts +7 -10
  189. package/src/monetization/promotions/engine.test.ts +6 -5
  190. package/src/monetization/promotions/engine.ts +6 -3
  191. package/src/monetization/repository-types.ts +1 -1
  192. package/src/monetization/stripe/stripe-payment-processor.test.ts +10 -3
  193. package/src/monetization/stripe/stripe-payment-processor.ts +3 -3
  194. package/src/monetization/stripe/webhook.test.ts +22 -16
  195. package/src/monetization/stripe/webhook.ts +75 -50
  196. package/src/onboarding/onboarding-service.ts +8 -11
  197. package/dist/credits/credit-ledger-extra.test.js +0 -40
  198. package/dist/credits/credit-ledger.bench.js +0 -33
  199. package/dist/credits/credit-ledger.test.d.ts +0 -4
  200. package/dist/credits/credit-ledger.test.js +0 -203
  201. package/dist/credits/credit-transaction-repository.test.js +0 -232
  202. package/dist/monetization/credits/credit-ledger-extra.test.d.ts +0 -1
  203. package/dist/monetization/credits/credit-ledger-extra.test.js +0 -39
  204. package/dist/monetization/credits/credit-ledger.bench.d.ts +0 -1
  205. package/dist/monetization/credits/credit-ledger.bench.js +0 -32
  206. package/dist/monetization/credits/credit-ledger.test.d.ts +0 -4
  207. package/dist/monetization/credits/credit-ledger.test.js +0 -202
  208. package/dist/monetization/credits/credit-transaction-repository.test.d.ts +0 -1
  209. package/dist/monetization/credits/credit-transaction-repository.test.js +0 -232
  210. package/src/credits/credit-ledger-extra.test.ts +0 -57
  211. package/src/credits/credit-ledger.bench.ts +0 -56
  212. package/src/credits/credit-ledger.test.ts +0 -276
  213. package/src/credits/credit-transaction-repository.test.ts +0 -274
  214. package/src/monetization/credits/credit-ledger-extra.test.ts +0 -56
  215. package/src/monetization/credits/credit-ledger.bench.ts +0 -55
  216. package/src/monetization/credits/credit-ledger.test.ts +0 -275
  217. package/src/monetization/credits/credit-transaction-repository.test.ts +0 -274
  218. /package/dist/credits/{credit-ledger-extra.test.d.ts → ledger.test.d.ts} +0 -0
  219. /package/dist/credits/{credit-ledger.bench.d.ts → trial-balance-cron.test.d.ts} +0 -0
  220. /package/dist/{credits/credit-transaction-repository.test.d.ts → monetization/credits/trial-balance-cron.test.d.ts} +0 -0
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Tests for gateway credit gate — grace buffer and credits_exhausted behavior (WOP-821).
3
3
  */
4
- import { Credit, CreditLedger } from "@wopr-network/platform-core/credits";
4
+ import { Credit, DrizzleLedger } from "@wopr-network/platform-core/credits";
5
5
  import { Hono } from "hono";
6
6
  import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
7
7
  import { createTestDb, truncateAllTables } from "../test/db.js";
@@ -39,35 +39,36 @@ afterAll(async () => {
39
39
  describe("creditBalanceCheck grace buffer", () => {
40
40
  beforeEach(async () => {
41
41
  await truncateAllTables(pool);
42
+ await new DrizzleLedger(db).seedSystemAccounts();
42
43
  });
43
44
  it("returns null when balance is above estimated cost (passes)", async () => {
44
- const ledger = new CreditLedger(db);
45
- await ledger.credit("t1", Credit.fromCents(500), "purchase", "setup");
45
+ const ledger = new DrizzleLedger(db);
46
+ await ledger.credit("t1", Credit.fromCents(500), "purchase", { description: "setup" });
46
47
  const c = await buildHonoContext("t1");
47
48
  const deps = { creditLedger: ledger, topUpUrl: "/billing" };
48
49
  expect(await creditBalanceCheck(c, deps, 1)).toBeNull();
49
50
  });
50
51
  it("returns null when balance is zero but within default grace buffer (passes)", async () => {
51
52
  // Balance at exactly 0 — within the -50 grace buffer
52
- const ledger = new CreditLedger(db);
53
- await ledger.credit("t1", Credit.fromCents(10), "purchase", "setup");
54
- await ledger.debit("t1", Credit.fromCents(10), "adapter_usage", "drain");
53
+ const ledger = new DrizzleLedger(db);
54
+ await ledger.credit("t1", Credit.fromCents(10), "purchase", { description: "setup" });
55
+ await ledger.debit("t1", Credit.fromCents(10), "adapter_usage", { description: "drain" });
55
56
  const c = await buildHonoContext("t1");
56
57
  const deps = { creditLedger: ledger, topUpUrl: "/billing" };
57
58
  expect(await creditBalanceCheck(c, deps, 0)).toBeNull();
58
59
  });
59
60
  it("returns null when balance is -49 (within 50-cent grace buffer)", async () => {
60
- const ledger = new CreditLedger(db);
61
- await ledger.credit("t1", Credit.fromCents(1), "purchase", "setup");
62
- await ledger.debit("t1", Credit.fromCents(50), "adapter_usage", "drain", undefined, true); // balance = -49
61
+ const ledger = new DrizzleLedger(db);
62
+ await ledger.credit("t1", Credit.fromCents(1), "purchase", { description: "setup" });
63
+ await ledger.debit("t1", Credit.fromCents(50), "adapter_usage", { description: "drain", allowNegative: true }); // balance = -49
63
64
  const c = await buildHonoContext("t1");
64
65
  const deps = { creditLedger: ledger, topUpUrl: "/billing" };
65
66
  expect(await creditBalanceCheck(c, deps, 0)).toBeNull();
66
67
  });
67
68
  it("returns credits_exhausted when balance is at -50 (at grace buffer limit)", async () => {
68
- const ledger = new CreditLedger(db);
69
- await ledger.credit("t1", Credit.fromCents(1), "purchase", "setup");
70
- await ledger.debit("t1", Credit.fromCents(51), "adapter_usage", "drain", undefined, true); // balance = -50
69
+ const ledger = new DrizzleLedger(db);
70
+ await ledger.credit("t1", Credit.fromCents(1), "purchase", { description: "setup" });
71
+ await ledger.debit("t1", Credit.fromCents(51), "adapter_usage", { description: "drain", allowNegative: true }); // balance = -50
71
72
  const c = await buildHonoContext("t1");
72
73
  const deps = { creditLedger: ledger, topUpUrl: "/billing" };
73
74
  const result = await creditBalanceCheck(c, deps, 0);
@@ -75,9 +76,9 @@ describe("creditBalanceCheck grace buffer", () => {
75
76
  expect(result?.code).toBe("credits_exhausted");
76
77
  });
77
78
  it("returns credits_exhausted when balance is at -51 (beyond grace buffer)", async () => {
78
- const ledger = new CreditLedger(db);
79
- await ledger.credit("t1", Credit.fromCents(1), "purchase", "setup");
80
- await ledger.debit("t1", Credit.fromCents(52), "adapter_usage", "drain", undefined, true); // balance = -51
79
+ const ledger = new DrizzleLedger(db);
80
+ await ledger.credit("t1", Credit.fromCents(1), "purchase", { description: "setup" });
81
+ await ledger.debit("t1", Credit.fromCents(52), "adapter_usage", { description: "drain", allowNegative: true }); // balance = -51
81
82
  const c = await buildHonoContext("t1");
82
83
  const deps = { creditLedger: ledger, topUpUrl: "/billing" };
83
84
  const result = await creditBalanceCheck(c, deps, 0);
@@ -85,9 +86,9 @@ describe("creditBalanceCheck grace buffer", () => {
85
86
  expect(result?.code).toBe("credits_exhausted");
86
87
  });
87
88
  it("returns credits_exhausted when custom graceBufferCents=0 and balance is 0", async () => {
88
- const ledger = new CreditLedger(db);
89
- await ledger.credit("t1", Credit.fromCents(10), "purchase", "setup");
90
- await ledger.debit("t1", Credit.fromCents(10), "adapter_usage", "drain"); // balance = 0
89
+ const ledger = new DrizzleLedger(db);
90
+ await ledger.credit("t1", Credit.fromCents(10), "purchase", { description: "setup" });
91
+ await ledger.debit("t1", Credit.fromCents(10), "adapter_usage", { description: "drain" }); // balance = 0
91
92
  const c = await buildHonoContext("t1");
92
93
  const deps = { creditLedger: ledger, topUpUrl: "/billing", graceBufferCents: 0 };
93
94
  const result = await creditBalanceCheck(c, deps, 0);
@@ -95,8 +96,8 @@ describe("creditBalanceCheck grace buffer", () => {
95
96
  expect(result?.code).toBe("credits_exhausted");
96
97
  });
97
98
  it("returns insufficient_credits when balance positive but below estimated cost", async () => {
98
- const ledger = new CreditLedger(db);
99
- await ledger.credit("t1", Credit.fromCents(5), "purchase", "setup");
99
+ const ledger = new DrizzleLedger(db);
100
+ await ledger.credit("t1", Credit.fromCents(5), "purchase", { description: "setup" });
100
101
  const c = await buildHonoContext("t1");
101
102
  const deps = { creditLedger: ledger, topUpUrl: "/billing" };
102
103
  const result = await creditBalanceCheck(c, deps, 10);
@@ -110,26 +111,27 @@ describe("creditBalanceCheck grace buffer", () => {
110
111
  describe("debitCredits with allowNegative and onBalanceExhausted", () => {
111
112
  beforeEach(async () => {
112
113
  await truncateAllTables(pool);
114
+ await new DrizzleLedger(db).seedSystemAccounts();
113
115
  });
114
116
  it("debit with cost that would exceed balance succeeds (allowNegative=true)", async () => {
115
- const ledger = new CreditLedger(db);
116
- await ledger.credit("t1", Credit.fromCents(5), "purchase", "setup"); // balance = 5 cents
117
+ const ledger = new DrizzleLedger(db);
118
+ await ledger.credit("t1", Credit.fromCents(5), "purchase", { description: "setup" }); // balance = 5 cents
117
119
  // costUsd = $0.10 = 10 cents, margin = 1.0
118
120
  // This should push balance negative without throwing
119
121
  await expect(debitCredits({ creditLedger: ledger, topUpUrl: "/billing" }, "t1", 0.1, 1.0, "chat-completions", "openrouter")).resolves.not.toThrow();
120
122
  expect((await ledger.balance("t1")).isNegative()).toBe(true);
121
123
  });
122
124
  it("fires onBalanceExhausted when debit causes balance to cross zero", async () => {
123
- const ledger = new CreditLedger(db);
124
- await ledger.credit("t1", Credit.fromCents(5), "purchase", "setup"); // balance = 5 cents
125
+ const ledger = new DrizzleLedger(db);
126
+ await ledger.credit("t1", Credit.fromCents(5), "purchase", { description: "setup" }); // balance = 5 cents
125
127
  const onBalanceExhausted = vi.fn();
126
128
  // costUsd = $0.10 = 10 cents with margin 1.0 → chargeCents = 10, pushes balance to -5
127
129
  await debitCredits({ creditLedger: ledger, topUpUrl: "/billing", onBalanceExhausted }, "t1", 0.1, 1.0, "chat-completions", "openrouter");
128
130
  expect(onBalanceExhausted).toHaveBeenCalledWith("t1", -5);
129
131
  });
130
132
  it("does NOT fire onBalanceExhausted when balance stays positive after debit", async () => {
131
- const ledger = new CreditLedger(db);
132
- await ledger.credit("t1", Credit.fromCents(500), "purchase", "setup"); // balance = 500 cents
133
+ const ledger = new DrizzleLedger(db);
134
+ await ledger.credit("t1", Credit.fromCents(500), "purchase", { description: "setup" }); // balance = 500 cents
133
135
  const onBalanceExhausted = vi.fn();
134
136
  // costUsd = $0.01 = 1 cent → balance stays at 499
135
137
  await debitCredits({ creditLedger: ledger, topUpUrl: "/billing", onBalanceExhausted }, "t1", 0.01, 1.0, "chat-completions", "openrouter");
@@ -137,8 +139,8 @@ describe("debitCredits with allowNegative and onBalanceExhausted", () => {
137
139
  expect((await ledger.balance("t1")).greaterThan(Credit.ZERO)).toBe(true);
138
140
  });
139
141
  it("onBalanceExhausted callback receives correct tenantId and negative balance", async () => {
140
- const ledger = new CreditLedger(db);
141
- await ledger.credit("t1", Credit.fromCents(3), "purchase", "setup"); // balance = 3 cents
142
+ const ledger = new DrizzleLedger(db);
143
+ await ledger.credit("t1", Credit.fromCents(3), "purchase", { description: "setup" }); // balance = 3 cents
142
144
  const onBalanceExhausted = vi.fn();
143
145
  // costUsd = $0.05 = 5 cents with margin 1.0 → pushes balance to -2
144
146
  await debitCredits({ creditLedger: ledger, topUpUrl: "/billing", onBalanceExhausted }, "t1", 0.05, 1.0, "chat-completions", "openrouter");
@@ -146,17 +148,17 @@ describe("debitCredits with allowNegative and onBalanceExhausted", () => {
146
148
  expect(onBalanceExhausted).toHaveBeenCalledWith("t1", -2);
147
149
  });
148
150
  it("calls onSpendAlertCrossed after successful debit", async () => {
149
- const ledger = new CreditLedger(db);
150
- await ledger.credit("t1", Credit.fromCents(500), "purchase", "setup");
151
+ const ledger = new DrizzleLedger(db);
152
+ await ledger.credit("t1", Credit.fromCents(500), "purchase", { description: "setup" });
151
153
  const onSpendAlertCrossed = vi.fn();
152
154
  await debitCredits({ creditLedger: ledger, topUpUrl: "/billing", onSpendAlertCrossed }, "t1", 0.05, 1.0, "chat-completions", "openrouter");
153
155
  expect(onSpendAlertCrossed).toHaveBeenCalledWith("t1");
154
156
  });
155
157
  it("does NOT fire onBalanceExhausted when balance was already negative before debit", async () => {
156
- const ledger = new CreditLedger(db);
158
+ const ledger = new DrizzleLedger(db);
157
159
  // Start with negative balance: credit 5, debit 10 → balance = -5
158
- await ledger.credit("t1", Credit.fromCents(5), "purchase", "setup");
159
- await ledger.debit("t1", Credit.fromCents(10), "adapter_usage", "drain", undefined, true);
160
+ await ledger.credit("t1", Credit.fromCents(5), "purchase", { description: "setup" });
161
+ await ledger.debit("t1", Credit.fromCents(10), "adapter_usage", { description: "drain", allowNegative: true });
160
162
  const onBalanceExhausted = vi.fn();
161
163
  // Another debit of 1 cent — balance goes from -5 to -6, but was already negative
162
164
  await debitCredits({ creditLedger: ledger, topUpUrl: "/billing", onBalanceExhausted }, "t1", 0.01, 1.0, "chat-completions", "openrouter");
@@ -4,7 +4,7 @@
4
4
  * Both the Anthropic and OpenAI handlers need the same set of services:
5
5
  * budget checking, metering, provider configs, fetch, and service key resolution.
6
6
  */
7
- import type { Credit, ICreditLedger } from "@wopr-network/platform-core/credits";
7
+ import type { Credit, ILedger } from "@wopr-network/platform-core/credits";
8
8
  import type { MeterEmitter } from "@wopr-network/platform-core/metering";
9
9
  import type { IRateLimitRepository } from "../../api/rate-limit-repository.js";
10
10
  import type { IBudgetChecker } from "../../monetization/budget/budget-checker.js";
@@ -16,7 +16,7 @@ import type { FetchFn, GatewayTenant, ProviderConfig } from "../types.js";
16
16
  export interface ProtocolDeps {
17
17
  meter: MeterEmitter;
18
18
  budgetChecker: IBudgetChecker;
19
- creditLedger?: ICreditLedger;
19
+ creditLedger?: ILedger;
20
20
  topUpUrl: string;
21
21
  graceBufferCents?: number;
22
22
  providers: ProviderConfig;