@wopr-network/platform-core 1.13.2 → 1.14.0

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 (238) hide show
  1. package/dist/api/routes/admin-credits.d.ts +2 -2
  2. package/dist/api/routes/admin-credits.js +9 -4
  3. package/dist/api/routes/quota.d.ts +2 -2
  4. package/dist/api/routes/verify-email.d.ts +3 -3
  5. package/dist/backup/on-demand-snapshot-service.d.ts +2 -2
  6. package/dist/billing/payram/webhook.d.ts +3 -3
  7. package/dist/billing/payram/webhook.js +5 -1
  8. package/dist/billing/payram/webhook.test.js +5 -4
  9. package/dist/billing/stripe/stripe-payment-processor.d.ts +2 -2
  10. package/dist/billing/stripe/stripe-payment-processor.test.js +7 -0
  11. package/dist/billing/stripe/tenant-store.d.ts +1 -1
  12. package/dist/billing/stripe/tenant-store.js +1 -1
  13. package/dist/credits/auto-topup-charge.d.ts +2 -2
  14. package/dist/credits/auto-topup-charge.js +5 -1
  15. package/dist/credits/auto-topup-charge.test.js +5 -4
  16. package/dist/credits/auto-topup-usage.d.ts +2 -2
  17. package/dist/credits/auto-topup-usage.test.js +53 -12
  18. package/dist/credits/credit-expiry-cron.d.ts +2 -2
  19. package/dist/credits/credit-expiry-cron.js +7 -4
  20. package/dist/credits/credit-expiry-cron.test.js +25 -8
  21. package/dist/credits/credit-ledger.d.ts +2 -2
  22. package/dist/credits/credit-ledger.js +1 -1
  23. package/dist/credits/dividend-cron.d.ts +4 -6
  24. package/dist/credits/dividend-cron.js +10 -16
  25. package/dist/credits/dividend-cron.test.js +31 -44
  26. package/dist/credits/dividend-repository.js +19 -22
  27. package/dist/credits/dividend-repository.test.js +4 -3
  28. package/dist/credits/index.d.ts +4 -2
  29. package/dist/credits/index.js +2 -1
  30. package/dist/credits/ledger.d.ts +195 -0
  31. package/dist/credits/ledger.js +561 -0
  32. package/dist/credits/ledger.test.js +418 -0
  33. package/dist/credits/signup-grant.d.ts +2 -2
  34. package/dist/credits/signup-grant.js +4 -4
  35. package/dist/credits/signup-grant.test.js +5 -3
  36. package/dist/credits/trial-balance-cron.d.ts +19 -0
  37. package/dist/credits/trial-balance-cron.js +30 -0
  38. package/dist/credits/trial-balance-cron.test.js +55 -0
  39. package/dist/db/schema/gateway-service-keys.d.ts +109 -0
  40. package/dist/db/schema/gateway-service-keys.js +18 -0
  41. package/dist/db/schema/index.d.ts +2 -0
  42. package/dist/db/schema/index.js +2 -0
  43. package/dist/db/schema/ledger.d.ts +442 -0
  44. package/dist/db/schema/ledger.js +76 -0
  45. package/dist/gateway/credit-gate.d.ts +2 -2
  46. package/dist/gateway/credit-gate.js +5 -1
  47. package/dist/gateway/credit-gate.test.js +35 -33
  48. package/dist/gateway/gateway-routes.test.js +1 -1
  49. package/dist/gateway/index.d.ts +2 -0
  50. package/dist/gateway/index.js +1 -0
  51. package/dist/gateway/protocol/anthropic.js +1 -1
  52. package/dist/gateway/protocol/deps.d.ts +5 -5
  53. package/dist/gateway/protocol/openai.js +1 -1
  54. package/dist/gateway/proxy.d.ts +4 -4
  55. package/dist/gateway/route-mounting.test.js +1 -1
  56. package/dist/gateway/service-key-auth.d.ts +1 -1
  57. package/dist/gateway/service-key-auth.js +1 -1
  58. package/dist/gateway/service-key-repository.d.ts +27 -0
  59. package/dist/gateway/service-key-repository.js +64 -0
  60. package/dist/gateway/types.d.ts +5 -5
  61. package/dist/metering/reconciliation-cron.test.js +9 -8
  62. package/dist/metering/reconciliation-repository.js +12 -10
  63. package/dist/metering/reconciliation-repository.test.js +9 -8
  64. package/dist/monetization/affiliate/affiliate-admin-repository.js +10 -8
  65. package/dist/monetization/affiliate/affiliate-admin-repository.test.js +32 -13
  66. package/dist/monetization/affiliate/credit-match.d.ts +2 -2
  67. package/dist/monetization/affiliate/credit-match.js +4 -1
  68. package/dist/monetization/affiliate/credit-match.test.js +58 -13
  69. package/dist/monetization/affiliate/new-user-bonus.d.ts +2 -2
  70. package/dist/monetization/affiliate/new-user-bonus.js +4 -1
  71. package/dist/monetization/affiliate/new-user-bonus.test.js +4 -3
  72. package/dist/monetization/credits/auto-topup-charge.d.ts +2 -2
  73. package/dist/monetization/credits/auto-topup-charge.js +5 -1
  74. package/dist/monetization/credits/auto-topup-charge.test.js +5 -4
  75. package/dist/monetization/credits/auto-topup-usage.d.ts +2 -2
  76. package/dist/monetization/credits/auto-topup-usage.test.js +53 -12
  77. package/dist/monetization/credits/bot-billing.d.ts +3 -3
  78. package/dist/monetization/credits/bot-billing.test.js +18 -5
  79. package/dist/monetization/credits/credit-expiry-cron.test.js +25 -8
  80. package/dist/monetization/credits/dividend-cron.d.ts +2 -4
  81. package/dist/monetization/credits/dividend-cron.js +7 -4
  82. package/dist/monetization/credits/dividend-cron.test.js +26 -46
  83. package/dist/monetization/credits/dividend-repository.js +15 -24
  84. package/dist/monetization/credits/dividend-repository.test.js +4 -3
  85. package/dist/monetization/credits/index.d.ts +2 -2
  86. package/dist/monetization/credits/index.js +1 -1
  87. package/dist/monetization/credits/member-usage.test.js +23 -10
  88. package/dist/monetization/credits/phone-billing.d.ts +2 -2
  89. package/dist/monetization/credits/phone-billing.js +5 -1
  90. package/dist/monetization/credits/phone-billing.test.js +9 -12
  91. package/dist/monetization/credits/runtime-cron.d.ts +2 -2
  92. package/dist/monetization/credits/runtime-cron.js +32 -8
  93. package/dist/monetization/credits/runtime-cron.test.js +28 -27
  94. package/dist/monetization/credits/runtime-scheduler.d.ts +2 -2
  95. package/dist/monetization/credits/runtime-scheduler.test.js +1 -1
  96. package/dist/monetization/credits/signup-grant.test.js +5 -3
  97. package/dist/monetization/credits/storage-tier-cron.test.js +3 -2
  98. package/dist/monetization/credits/trial-balance-cron.test.js +42 -0
  99. package/dist/monetization/feature-gate.d.ts +3 -3
  100. package/dist/monetization/index.d.ts +3 -3
  101. package/dist/monetization/index.js +1 -1
  102. package/dist/monetization/metering/reconciliation-cron.test.js +9 -8
  103. package/dist/monetization/metering/reconciliation-repository.js +11 -10
  104. package/dist/monetization/metering/reconciliation-repository.test.js +9 -8
  105. package/dist/monetization/payram/webhook.d.ts +2 -2
  106. package/dist/monetization/payram/webhook.js +5 -1
  107. package/dist/monetization/payram/webhook.test.js +5 -4
  108. package/dist/monetization/promotions/engine.d.ts +2 -2
  109. package/dist/monetization/promotions/engine.js +4 -1
  110. package/dist/monetization/promotions/engine.test.js +3 -1
  111. package/dist/monetization/repository-types.d.ts +1 -1
  112. package/dist/monetization/socket/socket.d.ts +3 -3
  113. package/dist/monetization/stripe/stripe-payment-processor.d.ts +2 -2
  114. package/dist/monetization/stripe/stripe-payment-processor.test.js +7 -0
  115. package/dist/monetization/stripe/webhook.d.ts +2 -2
  116. package/dist/monetization/stripe/webhook.js +70 -6
  117. package/dist/monetization/stripe/webhook.test.js +20 -15
  118. package/dist/onboarding/onboarding-service.d.ts +2 -2
  119. package/dist/onboarding/onboarding-service.js +6 -2
  120. package/drizzle/migrations/0002_gateway_service_keys.sql +14 -0
  121. package/drizzle/migrations/0003_double_entry_ledger.sql +82 -0
  122. package/drizzle/migrations/meta/_journal.json +14 -0
  123. package/package.json +1 -1
  124. package/src/api/routes/admin-credits.ts +11 -14
  125. package/src/api/routes/quota.ts +2 -2
  126. package/src/api/routes/verify-email.ts +4 -4
  127. package/src/backup/on-demand-snapshot-service.test.ts +3 -3
  128. package/src/backup/on-demand-snapshot-service.ts +3 -3
  129. package/src/billing/payram/webhook.test.ts +7 -5
  130. package/src/billing/payram/webhook.ts +8 -11
  131. package/src/billing/stripe/stripe-payment-processor.test.ts +10 -3
  132. package/src/billing/stripe/stripe-payment-processor.ts +3 -3
  133. package/src/billing/stripe/tenant-store.ts +1 -1
  134. package/src/credits/auto-topup-charge.test.ts +7 -5
  135. package/src/credits/auto-topup-charge.ts +7 -10
  136. package/src/credits/auto-topup-usage.test.ts +55 -13
  137. package/src/credits/auto-topup-usage.ts +2 -2
  138. package/src/credits/credit-expiry-cron.test.ts +26 -45
  139. package/src/credits/credit-expiry-cron.ts +9 -12
  140. package/src/credits/credit-ledger.ts +3 -3
  141. package/src/credits/dividend-cron.test.ts +38 -45
  142. package/src/credits/dividend-cron.ts +12 -26
  143. package/src/credits/dividend-repository.test.ts +4 -3
  144. package/src/credits/dividend-repository.ts +21 -23
  145. package/src/credits/index.ts +23 -4
  146. package/src/credits/ledger.test.ts +514 -0
  147. package/src/credits/ledger.ts +851 -0
  148. package/src/credits/signup-grant.test.ts +7 -4
  149. package/src/credits/signup-grant.ts +6 -12
  150. package/src/credits/trial-balance-cron.test.ts +68 -0
  151. package/src/credits/trial-balance-cron.ts +46 -0
  152. package/src/db/schema/gateway-service-keys.ts +23 -0
  153. package/src/db/schema/index.ts +2 -0
  154. package/src/db/schema/ledger.ts +94 -0
  155. package/src/gateway/credit-gate-wiring.test.ts +3 -3
  156. package/src/gateway/credit-gate.test.ts +35 -33
  157. package/src/gateway/credit-gate.ts +6 -10
  158. package/src/gateway/gateway-routes.test.ts +6 -6
  159. package/src/gateway/index.ts +2 -0
  160. package/src/gateway/protocol/anthropic.ts +2 -2
  161. package/src/gateway/protocol/deps.ts +5 -5
  162. package/src/gateway/protocol/openai.ts +2 -2
  163. package/src/gateway/proxy.ts +4 -4
  164. package/src/gateway/route-mounting.test.ts +3 -3
  165. package/src/gateway/service-key-auth.ts +4 -2
  166. package/src/gateway/service-key-repository.ts +87 -0
  167. package/src/gateway/types.ts +5 -5
  168. package/src/metering/reconciliation-cron.test.ts +10 -9
  169. package/src/metering/reconciliation-repository.test.ts +10 -9
  170. package/src/metering/reconciliation-repository.ts +14 -11
  171. package/src/monetization/affiliate/affiliate-admin-repository.test.ts +32 -19
  172. package/src/monetization/affiliate/affiliate-admin-repository.ts +16 -8
  173. package/src/monetization/affiliate/credit-match.test.ts +60 -14
  174. package/src/monetization/affiliate/credit-match.ts +6 -9
  175. package/src/monetization/affiliate/new-user-bonus.test.ts +6 -4
  176. package/src/monetization/affiliate/new-user-bonus.ts +6 -9
  177. package/src/monetization/credits/auto-topup-charge.test.ts +7 -5
  178. package/src/monetization/credits/auto-topup-charge.ts +7 -10
  179. package/src/monetization/credits/auto-topup-usage.test.ts +55 -13
  180. package/src/monetization/credits/auto-topup-usage.ts +2 -2
  181. package/src/monetization/credits/bot-billing.test.ts +20 -6
  182. package/src/monetization/credits/bot-billing.ts +3 -3
  183. package/src/monetization/credits/credit-expiry-cron.test.ts +26 -45
  184. package/src/monetization/credits/dividend-cron.test.ts +34 -48
  185. package/src/monetization/credits/dividend-cron.ts +9 -14
  186. package/src/monetization/credits/dividend-repository.test.ts +4 -3
  187. package/src/monetization/credits/dividend-repository.ts +19 -25
  188. package/src/monetization/credits/index.ts +4 -4
  189. package/src/monetization/credits/member-usage.test.ts +25 -11
  190. package/src/monetization/credits/phone-billing.test.ts +18 -26
  191. package/src/monetization/credits/phone-billing.ts +7 -10
  192. package/src/monetization/credits/runtime-cron.test.ts +29 -28
  193. package/src/monetization/credits/runtime-cron.ts +34 -58
  194. package/src/monetization/credits/runtime-scheduler.test.ts +1 -1
  195. package/src/monetization/credits/runtime-scheduler.ts +2 -2
  196. package/src/monetization/credits/signup-grant.test.ts +7 -4
  197. package/src/monetization/credits/storage-tier-cron.test.ts +5 -3
  198. package/src/monetization/credits/trial-balance-cron.test.ts +52 -0
  199. package/src/monetization/feature-gate.ts +3 -3
  200. package/src/monetization/index.ts +4 -4
  201. package/src/monetization/metering/reconciliation-cron.test.ts +10 -9
  202. package/src/monetization/metering/reconciliation-repository.test.ts +11 -9
  203. package/src/monetization/metering/reconciliation-repository.ts +13 -11
  204. package/src/monetization/payram/webhook.test.ts +7 -5
  205. package/src/monetization/payram/webhook.ts +7 -10
  206. package/src/monetization/promotions/engine.test.ts +6 -5
  207. package/src/monetization/promotions/engine.ts +6 -3
  208. package/src/monetization/repository-types.ts +1 -1
  209. package/src/monetization/socket/socket.ts +4 -4
  210. package/src/monetization/stripe/stripe-payment-processor.test.ts +10 -3
  211. package/src/monetization/stripe/stripe-payment-processor.ts +3 -3
  212. package/src/monetization/stripe/webhook.test.ts +22 -16
  213. package/src/monetization/stripe/webhook.ts +75 -50
  214. package/src/onboarding/onboarding-service.ts +8 -11
  215. package/dist/credits/credit-ledger-extra.test.js +0 -40
  216. package/dist/credits/credit-ledger.bench.js +0 -33
  217. package/dist/credits/credit-ledger.test.d.ts +0 -4
  218. package/dist/credits/credit-ledger.test.js +0 -203
  219. package/dist/credits/credit-transaction-repository.test.js +0 -232
  220. package/dist/monetization/credits/credit-ledger-extra.test.d.ts +0 -1
  221. package/dist/monetization/credits/credit-ledger-extra.test.js +0 -39
  222. package/dist/monetization/credits/credit-ledger.bench.d.ts +0 -1
  223. package/dist/monetization/credits/credit-ledger.bench.js +0 -32
  224. package/dist/monetization/credits/credit-ledger.test.d.ts +0 -4
  225. package/dist/monetization/credits/credit-ledger.test.js +0 -202
  226. package/dist/monetization/credits/credit-transaction-repository.test.d.ts +0 -1
  227. package/dist/monetization/credits/credit-transaction-repository.test.js +0 -232
  228. package/src/credits/credit-ledger-extra.test.ts +0 -57
  229. package/src/credits/credit-ledger.bench.ts +0 -56
  230. package/src/credits/credit-ledger.test.ts +0 -276
  231. package/src/credits/credit-transaction-repository.test.ts +0 -274
  232. package/src/monetization/credits/credit-ledger-extra.test.ts +0 -56
  233. package/src/monetization/credits/credit-ledger.bench.ts +0 -55
  234. package/src/monetization/credits/credit-ledger.test.ts +0 -275
  235. package/src/monetization/credits/credit-transaction-repository.test.ts +0 -274
  236. /package/dist/credits/{credit-ledger-extra.test.d.ts → ledger.test.d.ts} +0 -0
  237. /package/dist/credits/{credit-ledger.bench.d.ts → trial-balance-cron.test.d.ts} +0 -0
  238. /package/dist/{credits/credit-transaction-repository.test.d.ts → monetization/credits/trial-balance-cron.test.d.ts} +0 -0
@@ -0,0 +1,109 @@
1
+ export declare const gatewayServiceKeys: import("drizzle-orm/pg-core").PgTableWithColumns<{
2
+ name: "gateway_service_keys";
3
+ schema: undefined;
4
+ columns: {
5
+ id: import("drizzle-orm/pg-core").PgColumn<{
6
+ name: "id";
7
+ tableName: "gateway_service_keys";
8
+ dataType: "string";
9
+ columnType: "PgText";
10
+ data: string;
11
+ driverParam: string;
12
+ notNull: true;
13
+ hasDefault: false;
14
+ isPrimaryKey: true;
15
+ isAutoincrement: false;
16
+ hasRuntimeDefault: false;
17
+ enumValues: [string, ...string[]];
18
+ baseColumn: never;
19
+ identity: undefined;
20
+ generated: undefined;
21
+ }, {}, {}>;
22
+ keyHash: import("drizzle-orm/pg-core").PgColumn<{
23
+ name: "key_hash";
24
+ tableName: "gateway_service_keys";
25
+ dataType: "string";
26
+ columnType: "PgText";
27
+ data: string;
28
+ driverParam: string;
29
+ notNull: true;
30
+ hasDefault: false;
31
+ isPrimaryKey: false;
32
+ isAutoincrement: false;
33
+ hasRuntimeDefault: false;
34
+ enumValues: [string, ...string[]];
35
+ baseColumn: never;
36
+ identity: undefined;
37
+ generated: undefined;
38
+ }, {}, {}>;
39
+ tenantId: import("drizzle-orm/pg-core").PgColumn<{
40
+ name: "tenant_id";
41
+ tableName: "gateway_service_keys";
42
+ dataType: "string";
43
+ columnType: "PgText";
44
+ data: string;
45
+ driverParam: string;
46
+ notNull: true;
47
+ hasDefault: false;
48
+ isPrimaryKey: false;
49
+ isAutoincrement: false;
50
+ hasRuntimeDefault: false;
51
+ enumValues: [string, ...string[]];
52
+ baseColumn: never;
53
+ identity: undefined;
54
+ generated: undefined;
55
+ }, {}, {}>;
56
+ instanceId: import("drizzle-orm/pg-core").PgColumn<{
57
+ name: "instance_id";
58
+ tableName: "gateway_service_keys";
59
+ dataType: "string";
60
+ columnType: "PgText";
61
+ data: string;
62
+ driverParam: string;
63
+ notNull: true;
64
+ hasDefault: false;
65
+ isPrimaryKey: false;
66
+ isAutoincrement: false;
67
+ hasRuntimeDefault: false;
68
+ enumValues: [string, ...string[]];
69
+ baseColumn: never;
70
+ identity: undefined;
71
+ generated: undefined;
72
+ }, {}, {}>;
73
+ createdAt: import("drizzle-orm/pg-core").PgColumn<{
74
+ name: "created_at";
75
+ tableName: "gateway_service_keys";
76
+ dataType: "number";
77
+ columnType: "PgBigInt53";
78
+ data: number;
79
+ driverParam: string | number;
80
+ notNull: true;
81
+ hasDefault: false;
82
+ isPrimaryKey: false;
83
+ isAutoincrement: false;
84
+ hasRuntimeDefault: false;
85
+ enumValues: undefined;
86
+ baseColumn: never;
87
+ identity: undefined;
88
+ generated: undefined;
89
+ }, {}, {}>;
90
+ revokedAt: import("drizzle-orm/pg-core").PgColumn<{
91
+ name: "revoked_at";
92
+ tableName: "gateway_service_keys";
93
+ dataType: "number";
94
+ columnType: "PgBigInt53";
95
+ data: number;
96
+ driverParam: string | number;
97
+ notNull: false;
98
+ hasDefault: false;
99
+ isPrimaryKey: false;
100
+ isAutoincrement: false;
101
+ hasRuntimeDefault: false;
102
+ enumValues: undefined;
103
+ baseColumn: never;
104
+ identity: undefined;
105
+ generated: undefined;
106
+ }, {}, {}>;
107
+ };
108
+ dialect: "pg";
109
+ }>;
@@ -0,0 +1,18 @@
1
+ import { bigint, index, pgTable, text, uniqueIndex } from "drizzle-orm/pg-core";
2
+ export const gatewayServiceKeys = pgTable("gateway_service_keys", {
3
+ id: text("id").primaryKey(),
4
+ /** SHA-256 hex digest of the raw service key. Raw key is NEVER stored. */
5
+ keyHash: text("key_hash").notNull(),
6
+ /** Tenant this key bills against. */
7
+ tenantId: text("tenant_id").notNull(),
8
+ /** Instance ID this key was issued for (one key per instance). */
9
+ instanceId: text("instance_id").notNull(),
10
+ /** Unix epoch ms. */
11
+ createdAt: bigint("created_at", { mode: "number" }).notNull(),
12
+ /** Unix epoch ms. Null = not revoked. */
13
+ revokedAt: bigint("revoked_at", { mode: "number" }),
14
+ }, (table) => [
15
+ uniqueIndex("idx_gateway_service_keys_hash").on(table.keyHash),
16
+ index("idx_gateway_service_keys_tenant").on(table.tenantId),
17
+ index("idx_gateway_service_keys_instance").on(table.instanceId),
18
+ ]);
@@ -21,9 +21,11 @@ export * from "./email-notifications.js";
21
21
  export * from "./fleet-event-history.js";
22
22
  export * from "./fleet-events.js";
23
23
  export * from "./gateway-metrics.js";
24
+ export * from "./gateway-service-keys.js";
24
25
  export * from "./gpu-allocations.js";
25
26
  export * from "./gpu-configurations.js";
26
27
  export * from "./gpu-nodes.js";
28
+ export * from "./ledger.js";
27
29
  export * from "./marketplace-plugins.js";
28
30
  export * from "./meter-events.js";
29
31
  export * from "./node-registration-tokens.js";
@@ -21,9 +21,11 @@ export * from "./email-notifications.js";
21
21
  export * from "./fleet-event-history.js";
22
22
  export * from "./fleet-events.js";
23
23
  export * from "./gateway-metrics.js";
24
+ export * from "./gateway-service-keys.js";
24
25
  export * from "./gpu-allocations.js";
25
26
  export * from "./gpu-configurations.js";
26
27
  export * from "./gpu-nodes.js";
28
+ export * from "./ledger.js";
27
29
  export * from "./marketplace-plugins.js";
28
30
  export * from "./meter-events.js";
29
31
  export * from "./node-registration-tokens.js";
@@ -0,0 +1,442 @@
1
+ export declare const accountTypeEnum: import("drizzle-orm/pg-core").PgEnum<["asset", "liability", "equity", "revenue", "expense"]>;
2
+ export declare const entrySideEnum: import("drizzle-orm/pg-core").PgEnum<["debit", "credit"]>;
3
+ /**
4
+ * Chart of accounts — every account that can appear in a journal line.
5
+ *
6
+ * System accounts (tenant_id IS NULL) are seeded at migration time.
7
+ * Per-tenant liability accounts are created lazily on first transaction.
8
+ */
9
+ export declare const accounts: import("drizzle-orm/pg-core").PgTableWithColumns<{
10
+ name: "accounts";
11
+ schema: undefined;
12
+ columns: {
13
+ id: import("drizzle-orm/pg-core").PgColumn<{
14
+ name: "id";
15
+ tableName: "accounts";
16
+ dataType: "string";
17
+ columnType: "PgText";
18
+ data: string;
19
+ driverParam: string;
20
+ notNull: true;
21
+ hasDefault: false;
22
+ isPrimaryKey: true;
23
+ isAutoincrement: false;
24
+ hasRuntimeDefault: false;
25
+ enumValues: [string, ...string[]];
26
+ baseColumn: never;
27
+ identity: undefined;
28
+ generated: undefined;
29
+ }, {}, {}>;
30
+ code: import("drizzle-orm/pg-core").PgColumn<{
31
+ name: "code";
32
+ tableName: "accounts";
33
+ dataType: "string";
34
+ columnType: "PgText";
35
+ data: string;
36
+ driverParam: string;
37
+ notNull: true;
38
+ hasDefault: false;
39
+ isPrimaryKey: false;
40
+ isAutoincrement: false;
41
+ hasRuntimeDefault: false;
42
+ enumValues: [string, ...string[]];
43
+ baseColumn: never;
44
+ identity: undefined;
45
+ generated: undefined;
46
+ }, {}, {}>;
47
+ name: import("drizzle-orm/pg-core").PgColumn<{
48
+ name: "name";
49
+ tableName: "accounts";
50
+ dataType: "string";
51
+ columnType: "PgText";
52
+ data: string;
53
+ driverParam: string;
54
+ notNull: true;
55
+ hasDefault: false;
56
+ isPrimaryKey: false;
57
+ isAutoincrement: false;
58
+ hasRuntimeDefault: false;
59
+ enumValues: [string, ...string[]];
60
+ baseColumn: never;
61
+ identity: undefined;
62
+ generated: undefined;
63
+ }, {}, {}>;
64
+ type: import("drizzle-orm/pg-core").PgColumn<{
65
+ name: "type";
66
+ tableName: "accounts";
67
+ dataType: "string";
68
+ columnType: "PgEnumColumn";
69
+ data: "asset" | "liability" | "equity" | "revenue" | "expense";
70
+ driverParam: string;
71
+ notNull: true;
72
+ hasDefault: false;
73
+ isPrimaryKey: false;
74
+ isAutoincrement: false;
75
+ hasRuntimeDefault: false;
76
+ enumValues: ["asset", "liability", "equity", "revenue", "expense"];
77
+ baseColumn: never;
78
+ identity: undefined;
79
+ generated: undefined;
80
+ }, {}, {}>;
81
+ normalSide: import("drizzle-orm/pg-core").PgColumn<{
82
+ name: "normal_side";
83
+ tableName: "accounts";
84
+ dataType: "string";
85
+ columnType: "PgEnumColumn";
86
+ data: "debit" | "credit";
87
+ driverParam: string;
88
+ notNull: true;
89
+ hasDefault: false;
90
+ isPrimaryKey: false;
91
+ isAutoincrement: false;
92
+ hasRuntimeDefault: false;
93
+ enumValues: ["debit", "credit"];
94
+ baseColumn: never;
95
+ identity: undefined;
96
+ generated: undefined;
97
+ }, {}, {}>;
98
+ tenantId: import("drizzle-orm/pg-core").PgColumn<{
99
+ name: "tenant_id";
100
+ tableName: "accounts";
101
+ dataType: "string";
102
+ columnType: "PgText";
103
+ data: string;
104
+ driverParam: string;
105
+ notNull: false;
106
+ hasDefault: false;
107
+ isPrimaryKey: false;
108
+ isAutoincrement: false;
109
+ hasRuntimeDefault: false;
110
+ enumValues: [string, ...string[]];
111
+ baseColumn: never;
112
+ identity: undefined;
113
+ generated: undefined;
114
+ }, {}, {}>;
115
+ createdAt: import("drizzle-orm/pg-core").PgColumn<{
116
+ name: "created_at";
117
+ tableName: "accounts";
118
+ dataType: "string";
119
+ columnType: "PgText";
120
+ data: string;
121
+ driverParam: string;
122
+ notNull: true;
123
+ hasDefault: true;
124
+ isPrimaryKey: false;
125
+ isAutoincrement: false;
126
+ hasRuntimeDefault: false;
127
+ enumValues: [string, ...string[]];
128
+ baseColumn: never;
129
+ identity: undefined;
130
+ generated: undefined;
131
+ }, {}, {}>;
132
+ };
133
+ dialect: "pg";
134
+ }>;
135
+ /**
136
+ * Journal entries — the header for each balanced transaction.
137
+ * One business event = one journal entry = two or more journal lines that sum to zero.
138
+ */
139
+ export declare const journalEntries: import("drizzle-orm/pg-core").PgTableWithColumns<{
140
+ name: "journal_entries";
141
+ schema: undefined;
142
+ columns: {
143
+ id: import("drizzle-orm/pg-core").PgColumn<{
144
+ name: "id";
145
+ tableName: "journal_entries";
146
+ dataType: "string";
147
+ columnType: "PgText";
148
+ data: string;
149
+ driverParam: string;
150
+ notNull: true;
151
+ hasDefault: false;
152
+ isPrimaryKey: true;
153
+ isAutoincrement: false;
154
+ hasRuntimeDefault: false;
155
+ enumValues: [string, ...string[]];
156
+ baseColumn: never;
157
+ identity: undefined;
158
+ generated: undefined;
159
+ }, {}, {}>;
160
+ postedAt: import("drizzle-orm/pg-core").PgColumn<{
161
+ name: "posted_at";
162
+ tableName: "journal_entries";
163
+ dataType: "string";
164
+ columnType: "PgText";
165
+ data: string;
166
+ driverParam: string;
167
+ notNull: true;
168
+ hasDefault: true;
169
+ isPrimaryKey: false;
170
+ isAutoincrement: false;
171
+ hasRuntimeDefault: false;
172
+ enumValues: [string, ...string[]];
173
+ baseColumn: never;
174
+ identity: undefined;
175
+ generated: undefined;
176
+ }, {}, {}>;
177
+ entryType: import("drizzle-orm/pg-core").PgColumn<{
178
+ name: "entry_type";
179
+ tableName: "journal_entries";
180
+ dataType: "string";
181
+ columnType: "PgText";
182
+ data: string;
183
+ driverParam: string;
184
+ notNull: true;
185
+ hasDefault: false;
186
+ isPrimaryKey: false;
187
+ isAutoincrement: false;
188
+ hasRuntimeDefault: false;
189
+ enumValues: [string, ...string[]];
190
+ baseColumn: never;
191
+ identity: undefined;
192
+ generated: undefined;
193
+ }, {}, {}>;
194
+ description: import("drizzle-orm/pg-core").PgColumn<{
195
+ name: "description";
196
+ tableName: "journal_entries";
197
+ dataType: "string";
198
+ columnType: "PgText";
199
+ data: string;
200
+ driverParam: string;
201
+ notNull: false;
202
+ hasDefault: false;
203
+ isPrimaryKey: false;
204
+ isAutoincrement: false;
205
+ hasRuntimeDefault: false;
206
+ enumValues: [string, ...string[]];
207
+ baseColumn: never;
208
+ identity: undefined;
209
+ generated: undefined;
210
+ }, {}, {}>;
211
+ referenceId: import("drizzle-orm/pg-core").PgColumn<{
212
+ name: "reference_id";
213
+ tableName: "journal_entries";
214
+ dataType: "string";
215
+ columnType: "PgText";
216
+ data: string;
217
+ driverParam: string;
218
+ notNull: false;
219
+ hasDefault: false;
220
+ isPrimaryKey: false;
221
+ isAutoincrement: false;
222
+ hasRuntimeDefault: false;
223
+ enumValues: [string, ...string[]];
224
+ baseColumn: never;
225
+ identity: undefined;
226
+ generated: undefined;
227
+ }, {}, {}>;
228
+ tenantId: import("drizzle-orm/pg-core").PgColumn<{
229
+ name: "tenant_id";
230
+ tableName: "journal_entries";
231
+ dataType: "string";
232
+ columnType: "PgText";
233
+ data: string;
234
+ driverParam: string;
235
+ notNull: true;
236
+ hasDefault: false;
237
+ isPrimaryKey: false;
238
+ isAutoincrement: false;
239
+ hasRuntimeDefault: false;
240
+ enumValues: [string, ...string[]];
241
+ baseColumn: never;
242
+ identity: undefined;
243
+ generated: undefined;
244
+ }, {}, {}>;
245
+ metadata: import("drizzle-orm/pg-core").PgColumn<{
246
+ name: "metadata";
247
+ tableName: "journal_entries";
248
+ dataType: "json";
249
+ columnType: "PgJsonb";
250
+ data: unknown;
251
+ driverParam: unknown;
252
+ notNull: false;
253
+ hasDefault: false;
254
+ isPrimaryKey: false;
255
+ isAutoincrement: false;
256
+ hasRuntimeDefault: false;
257
+ enumValues: undefined;
258
+ baseColumn: never;
259
+ identity: undefined;
260
+ generated: undefined;
261
+ }, {}, {}>;
262
+ createdBy: import("drizzle-orm/pg-core").PgColumn<{
263
+ name: "created_by";
264
+ tableName: "journal_entries";
265
+ dataType: "string";
266
+ columnType: "PgText";
267
+ data: string;
268
+ driverParam: string;
269
+ notNull: false;
270
+ hasDefault: false;
271
+ isPrimaryKey: false;
272
+ isAutoincrement: false;
273
+ hasRuntimeDefault: false;
274
+ enumValues: [string, ...string[]];
275
+ baseColumn: never;
276
+ identity: undefined;
277
+ generated: undefined;
278
+ }, {}, {}>;
279
+ };
280
+ dialect: "pg";
281
+ }>;
282
+ /**
283
+ * Journal lines — the individual debits and credits within a journal entry.
284
+ * Invariant: for every journal_entry, SUM(debit amounts) = SUM(credit amounts).
285
+ * Amount is always positive; `side` determines the direction.
286
+ * Stored in nanodollars (Credit.toRaw()).
287
+ */
288
+ export declare const journalLines: import("drizzle-orm/pg-core").PgTableWithColumns<{
289
+ name: "journal_lines";
290
+ schema: undefined;
291
+ columns: {
292
+ id: import("drizzle-orm/pg-core").PgColumn<{
293
+ name: "id";
294
+ tableName: "journal_lines";
295
+ dataType: "string";
296
+ columnType: "PgText";
297
+ data: string;
298
+ driverParam: string;
299
+ notNull: true;
300
+ hasDefault: false;
301
+ isPrimaryKey: true;
302
+ isAutoincrement: false;
303
+ hasRuntimeDefault: false;
304
+ enumValues: [string, ...string[]];
305
+ baseColumn: never;
306
+ identity: undefined;
307
+ generated: undefined;
308
+ }, {}, {}>;
309
+ journalEntryId: import("drizzle-orm/pg-core").PgColumn<{
310
+ name: "journal_entry_id";
311
+ tableName: "journal_lines";
312
+ dataType: "string";
313
+ columnType: "PgText";
314
+ data: string;
315
+ driverParam: string;
316
+ notNull: true;
317
+ hasDefault: false;
318
+ isPrimaryKey: false;
319
+ isAutoincrement: false;
320
+ hasRuntimeDefault: false;
321
+ enumValues: [string, ...string[]];
322
+ baseColumn: never;
323
+ identity: undefined;
324
+ generated: undefined;
325
+ }, {}, {}>;
326
+ accountId: import("drizzle-orm/pg-core").PgColumn<{
327
+ name: "account_id";
328
+ tableName: "journal_lines";
329
+ dataType: "string";
330
+ columnType: "PgText";
331
+ data: string;
332
+ driverParam: string;
333
+ notNull: true;
334
+ hasDefault: false;
335
+ isPrimaryKey: false;
336
+ isAutoincrement: false;
337
+ hasRuntimeDefault: false;
338
+ enumValues: [string, ...string[]];
339
+ baseColumn: never;
340
+ identity: undefined;
341
+ generated: undefined;
342
+ }, {}, {}>;
343
+ amount: import("drizzle-orm/pg-core").PgColumn<{
344
+ name: "amount";
345
+ tableName: "journal_lines";
346
+ dataType: "number";
347
+ columnType: "PgBigInt53";
348
+ data: number;
349
+ driverParam: string | number;
350
+ notNull: true;
351
+ hasDefault: false;
352
+ isPrimaryKey: false;
353
+ isAutoincrement: false;
354
+ hasRuntimeDefault: false;
355
+ enumValues: undefined;
356
+ baseColumn: never;
357
+ identity: undefined;
358
+ generated: undefined;
359
+ }, {}, {}>;
360
+ side: import("drizzle-orm/pg-core").PgColumn<{
361
+ name: "side";
362
+ tableName: "journal_lines";
363
+ dataType: "string";
364
+ columnType: "PgEnumColumn";
365
+ data: "debit" | "credit";
366
+ driverParam: string;
367
+ notNull: true;
368
+ hasDefault: false;
369
+ isPrimaryKey: false;
370
+ isAutoincrement: false;
371
+ hasRuntimeDefault: false;
372
+ enumValues: ["debit", "credit"];
373
+ baseColumn: never;
374
+ identity: undefined;
375
+ generated: undefined;
376
+ }, {}, {}>;
377
+ };
378
+ dialect: "pg";
379
+ }>;
380
+ /**
381
+ * Materialized account balances — cache derived from journal_lines.
382
+ * Updated atomically within the same transaction as the journal line insert.
383
+ * Can always be reconstructed from journal_lines if corrupted.
384
+ */
385
+ export declare const accountBalances: import("drizzle-orm/pg-core").PgTableWithColumns<{
386
+ name: "account_balances";
387
+ schema: undefined;
388
+ columns: {
389
+ accountId: import("drizzle-orm/pg-core").PgColumn<{
390
+ name: "account_id";
391
+ tableName: "account_balances";
392
+ dataType: "string";
393
+ columnType: "PgText";
394
+ data: string;
395
+ driverParam: string;
396
+ notNull: true;
397
+ hasDefault: false;
398
+ isPrimaryKey: true;
399
+ isAutoincrement: false;
400
+ hasRuntimeDefault: false;
401
+ enumValues: [string, ...string[]];
402
+ baseColumn: never;
403
+ identity: undefined;
404
+ generated: undefined;
405
+ }, {}, {}>;
406
+ balance: import("drizzle-orm/pg-core").PgColumn<{
407
+ name: "balance";
408
+ tableName: "account_balances";
409
+ dataType: "number";
410
+ columnType: "PgBigInt53";
411
+ data: number;
412
+ driverParam: string | number;
413
+ notNull: true;
414
+ hasDefault: true;
415
+ isPrimaryKey: false;
416
+ isAutoincrement: false;
417
+ hasRuntimeDefault: false;
418
+ enumValues: undefined;
419
+ baseColumn: never;
420
+ identity: undefined;
421
+ generated: undefined;
422
+ }, {}, {}>;
423
+ lastUpdated: import("drizzle-orm/pg-core").PgColumn<{
424
+ name: "last_updated";
425
+ tableName: "account_balances";
426
+ dataType: "string";
427
+ columnType: "PgText";
428
+ data: string;
429
+ driverParam: string;
430
+ notNull: true;
431
+ hasDefault: true;
432
+ isPrimaryKey: false;
433
+ isAutoincrement: false;
434
+ hasRuntimeDefault: false;
435
+ enumValues: [string, ...string[]];
436
+ baseColumn: never;
437
+ identity: undefined;
438
+ generated: undefined;
439
+ }, {}, {}>;
440
+ };
441
+ dialect: "pg";
442
+ }>;
@@ -0,0 +1,76 @@
1
+ import { sql } from "drizzle-orm";
2
+ import { bigint, index, jsonb, pgEnum, pgTable, text, uniqueIndex } from "drizzle-orm/pg-core";
3
+ export const accountTypeEnum = pgEnum("account_type", ["asset", "liability", "equity", "revenue", "expense"]);
4
+ export const entrySideEnum = pgEnum("entry_side", ["debit", "credit"]);
5
+ /**
6
+ * Chart of accounts — every account that can appear in a journal line.
7
+ *
8
+ * System accounts (tenant_id IS NULL) are seeded at migration time.
9
+ * Per-tenant liability accounts are created lazily on first transaction.
10
+ */
11
+ export const accounts = pgTable("accounts", {
12
+ id: text("id").primaryKey(),
13
+ code: text("code").notNull(),
14
+ name: text("name").notNull(),
15
+ type: accountTypeEnum("type").notNull(),
16
+ normalSide: entrySideEnum("normal_side").notNull(),
17
+ tenantId: text("tenant_id"), // NULL = system account
18
+ createdAt: text("created_at").notNull().default(sql `(now())`),
19
+ }, (table) => [
20
+ uniqueIndex("idx_accounts_code").on(table.code),
21
+ index("idx_accounts_tenant").on(table.tenantId).where(sql `${table.tenantId} IS NOT NULL`),
22
+ index("idx_accounts_type").on(table.type),
23
+ ]);
24
+ /**
25
+ * Journal entries — the header for each balanced transaction.
26
+ * One business event = one journal entry = two or more journal lines that sum to zero.
27
+ */
28
+ export const journalEntries = pgTable("journal_entries", {
29
+ id: text("id").primaryKey(),
30
+ postedAt: text("posted_at").notNull().default(sql `(now())`),
31
+ entryType: text("entry_type").notNull(), // purchase, usage, grant, refund, dividend, expiry, correction
32
+ description: text("description"),
33
+ referenceId: text("reference_id"),
34
+ tenantId: text("tenant_id").notNull(),
35
+ metadata: jsonb("metadata"), // funding_source, attributed_user_id, stripe_fingerprint, etc.
36
+ createdBy: text("created_by"), // system, admin:<id>, cron:expiry, etc.
37
+ }, (table) => [
38
+ uniqueIndex("idx_je_reference").on(table.referenceId).where(sql `${table.referenceId} IS NOT NULL`),
39
+ index("idx_je_tenant").on(table.tenantId),
40
+ index("idx_je_type").on(table.entryType),
41
+ index("idx_je_posted").on(table.postedAt),
42
+ index("idx_je_tenant_posted").on(table.tenantId, table.postedAt),
43
+ ]);
44
+ /**
45
+ * Journal lines — the individual debits and credits within a journal entry.
46
+ * Invariant: for every journal_entry, SUM(debit amounts) = SUM(credit amounts).
47
+ * Amount is always positive; `side` determines the direction.
48
+ * Stored in nanodollars (Credit.toRaw()).
49
+ */
50
+ export const journalLines = pgTable("journal_lines", {
51
+ id: text("id").primaryKey(),
52
+ journalEntryId: text("journal_entry_id")
53
+ .notNull()
54
+ .references(() => journalEntries.id),
55
+ accountId: text("account_id")
56
+ .notNull()
57
+ .references(() => accounts.id),
58
+ amount: bigint("amount", { mode: "number" }).notNull(), // nanodollars, always positive
59
+ side: entrySideEnum("side").notNull(),
60
+ }, (table) => [
61
+ index("idx_jl_entry").on(table.journalEntryId),
62
+ index("idx_jl_account").on(table.accountId),
63
+ index("idx_jl_account_side").on(table.accountId, table.side),
64
+ ]);
65
+ /**
66
+ * Materialized account balances — cache derived from journal_lines.
67
+ * Updated atomically within the same transaction as the journal line insert.
68
+ * Can always be reconstructed from journal_lines if corrupted.
69
+ */
70
+ export const accountBalances = pgTable("account_balances", {
71
+ accountId: text("account_id")
72
+ .primaryKey()
73
+ .references(() => accounts.id),
74
+ balance: bigint("balance", { mode: "number" }).notNull().default(0), // net balance in nanodollars
75
+ lastUpdated: text("last_updated").notNull().default(sql `(now())`),
76
+ });
@@ -5,11 +5,11 @@
5
5
  * (OpenAI, Anthropic) to ensure consistent credit billing across all
6
6
  * gateway endpoints.
7
7
  */
8
- import type { ICreditLedger } from "@wopr-network/platform-core/credits";
8
+ import type { ILedger } from "@wopr-network/platform-core/credits";
9
9
  import type { Context } from "hono";
10
10
  import type { GatewayAuthEnv } from "./service-key-auth.js";
11
11
  export interface CreditGateDeps {
12
- creditLedger?: ICreditLedger;
12
+ creditLedger?: ILedger;
13
13
  topUpUrl: string;
14
14
  /** Maximum negative balance allowed before hard-stop, in cents. Default: 50 (-$0.50). */
15
15
  graceBufferCents?: number;