@wopr-network/platform-core 0.1.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 (694) hide show
  1. package/biome.json +61 -0
  2. package/dist/admin/admin-audit-log-repository.d.ts +33 -0
  3. package/dist/admin/admin-audit-log-repository.js +102 -0
  4. package/dist/admin/audit-log.d.ts +49 -0
  5. package/dist/admin/audit-log.js +63 -0
  6. package/dist/admin/index.d.ts +6 -0
  7. package/dist/admin/index.js +3 -0
  8. package/dist/admin/role-store.d.ts +37 -0
  9. package/dist/admin/role-store.js +106 -0
  10. package/dist/auth/api-key-repository.d.ts +11 -0
  11. package/dist/auth/api-key-repository.js +33 -0
  12. package/dist/auth/api-key-repository.test.d.ts +1 -0
  13. package/dist/auth/api-key-repository.test.js +46 -0
  14. package/dist/auth/auth.test.d.ts +1 -0
  15. package/dist/auth/auth.test.js +140 -0
  16. package/dist/auth/better-auth.d.ts +42 -0
  17. package/dist/auth/better-auth.js +196 -0
  18. package/dist/auth/index.d.ts +186 -0
  19. package/dist/auth/index.js +422 -0
  20. package/dist/auth/login-history-repository.d.ts +14 -0
  21. package/dist/auth/login-history-repository.js +15 -0
  22. package/dist/auth/login-history-repository.test.d.ts +1 -0
  23. package/dist/auth/login-history-repository.test.js +47 -0
  24. package/dist/auth/middleware.d.ts +55 -0
  25. package/dist/auth/middleware.js +101 -0
  26. package/dist/auth/middleware.test.d.ts +1 -0
  27. package/dist/auth/middleware.test.js +213 -0
  28. package/dist/auth/scoped-tokens.test.d.ts +1 -0
  29. package/dist/auth/scoped-tokens.test.js +306 -0
  30. package/dist/auth/tenant-access.test.d.ts +1 -0
  31. package/dist/auth/tenant-access.test.js +62 -0
  32. package/dist/auth/user-creator.d.ts +9 -0
  33. package/dist/auth/user-creator.js +47 -0
  34. package/dist/auth/user-creator.test.d.ts +1 -0
  35. package/dist/auth/user-creator.test.js +78 -0
  36. package/dist/auth/user-role-repository.d.ts +31 -0
  37. package/dist/auth/user-role-repository.js +53 -0
  38. package/dist/auth/user-role-repository.test.d.ts +1 -0
  39. package/dist/auth/user-role-repository.test.js +122 -0
  40. package/dist/billing/drizzle-webhook-seen-repository.d.ts +10 -0
  41. package/dist/billing/drizzle-webhook-seen-repository.js +28 -0
  42. package/dist/billing/index.d.ts +7 -0
  43. package/dist/billing/index.js +7 -0
  44. package/dist/billing/payment-processor.d.ts +127 -0
  45. package/dist/billing/payment-processor.js +8 -0
  46. package/dist/billing/payment-processor.test.d.ts +1 -0
  47. package/dist/billing/payment-processor.test.js +71 -0
  48. package/dist/billing/payram/cents-credits-boundary.test.d.ts +1 -0
  49. package/dist/billing/payram/cents-credits-boundary.test.js +75 -0
  50. package/dist/billing/payram/charge-store.d.ts +41 -0
  51. package/dist/billing/payram/charge-store.js +72 -0
  52. package/dist/billing/payram/charge-store.test.d.ts +1 -0
  53. package/dist/billing/payram/charge-store.test.js +64 -0
  54. package/dist/billing/payram/checkout.d.ts +15 -0
  55. package/dist/billing/payram/checkout.js +24 -0
  56. package/dist/billing/payram/checkout.test.d.ts +1 -0
  57. package/dist/billing/payram/checkout.test.js +74 -0
  58. package/dist/billing/payram/client.d.ts +7 -0
  59. package/dist/billing/payram/client.js +15 -0
  60. package/dist/billing/payram/client.test.d.ts +1 -0
  61. package/dist/billing/payram/client.test.js +52 -0
  62. package/dist/billing/payram/index.d.ts +8 -0
  63. package/dist/billing/payram/index.js +4 -0
  64. package/dist/billing/payram/types.d.ts +40 -0
  65. package/dist/billing/payram/types.js +1 -0
  66. package/dist/billing/payram/webhook.d.ts +19 -0
  67. package/dist/billing/payram/webhook.js +67 -0
  68. package/dist/billing/payram/webhook.test.d.ts +7 -0
  69. package/dist/billing/payram/webhook.test.js +248 -0
  70. package/dist/billing/stripe/cents-credits-boundary.test.d.ts +1 -0
  71. package/dist/billing/stripe/cents-credits-boundary.test.js +62 -0
  72. package/dist/billing/stripe/checkout.d.ts +20 -0
  73. package/dist/billing/stripe/checkout.js +63 -0
  74. package/dist/billing/stripe/checkout.test.d.ts +1 -0
  75. package/dist/billing/stripe/checkout.test.js +148 -0
  76. package/dist/billing/stripe/client.d.ts +14 -0
  77. package/dist/billing/stripe/client.js +33 -0
  78. package/dist/billing/stripe/client.test.d.ts +1 -0
  79. package/dist/billing/stripe/client.test.js +58 -0
  80. package/dist/billing/stripe/credit-prices.d.ts +63 -0
  81. package/dist/billing/stripe/credit-prices.js +81 -0
  82. package/dist/billing/stripe/credit-prices.test.d.ts +1 -0
  83. package/dist/billing/stripe/credit-prices.test.js +87 -0
  84. package/dist/billing/stripe/index.d.ts +14 -0
  85. package/dist/billing/stripe/index.js +8 -0
  86. package/dist/billing/stripe/payment-methods-detach-all.test.d.ts +1 -0
  87. package/dist/billing/stripe/payment-methods-detach-all.test.js +40 -0
  88. package/dist/billing/stripe/payment-methods.d.ts +25 -0
  89. package/dist/billing/stripe/payment-methods.js +53 -0
  90. package/dist/billing/stripe/payment-methods.test.d.ts +1 -0
  91. package/dist/billing/stripe/payment-methods.test.js +122 -0
  92. package/dist/billing/stripe/portal.d.ts +10 -0
  93. package/dist/billing/stripe/portal.js +16 -0
  94. package/dist/billing/stripe/portal.test.d.ts +1 -0
  95. package/dist/billing/stripe/portal.test.js +48 -0
  96. package/dist/billing/stripe/setup-intent.d.ts +16 -0
  97. package/dist/billing/stripe/setup-intent.js +22 -0
  98. package/dist/billing/stripe/setup-intent.test.d.ts +1 -0
  99. package/dist/billing/stripe/setup-intent.test.js +58 -0
  100. package/dist/billing/stripe/stripe-payment-processor.d.ts +49 -0
  101. package/dist/billing/stripe/stripe-payment-processor.js +166 -0
  102. package/dist/billing/stripe/stripe-payment-processor.test.d.ts +1 -0
  103. package/dist/billing/stripe/stripe-payment-processor.test.js +413 -0
  104. package/dist/billing/stripe/tenant-store.d.ts +56 -0
  105. package/dist/billing/stripe/tenant-store.js +119 -0
  106. package/dist/billing/stripe/tenant-store.test.d.ts +1 -0
  107. package/dist/billing/stripe/tenant-store.test.js +97 -0
  108. package/dist/billing/stripe/types.d.ts +49 -0
  109. package/dist/billing/stripe/types.js +1 -0
  110. package/dist/billing/webhook-seen-repository.d.ts +14 -0
  111. package/dist/billing/webhook-seen-repository.js +13 -0
  112. package/dist/config/billing-env.test.d.ts +1 -0
  113. package/dist/config/billing-env.test.js +48 -0
  114. package/dist/config/index.d.ts +46 -0
  115. package/dist/config/index.js +38 -0
  116. package/dist/config/logger.d.ts +2 -0
  117. package/dist/config/logger.js +11 -0
  118. package/dist/config/provider-endpoints.d.ts +6 -0
  119. package/dist/config/provider-endpoints.js +12 -0
  120. package/dist/credits/auto-topup-charge.d.ts +27 -0
  121. package/dist/credits/auto-topup-charge.js +139 -0
  122. package/dist/credits/auto-topup-charge.test.d.ts +1 -0
  123. package/dist/credits/auto-topup-charge.test.js +242 -0
  124. package/dist/credits/auto-topup-event-log-repository.d.ts +16 -0
  125. package/dist/credits/auto-topup-event-log-repository.js +18 -0
  126. package/dist/credits/auto-topup-event-log-repository.test.d.ts +1 -0
  127. package/dist/credits/auto-topup-event-log-repository.test.js +83 -0
  128. package/dist/credits/auto-topup-schedule.d.ts +27 -0
  129. package/dist/credits/auto-topup-schedule.js +66 -0
  130. package/dist/credits/auto-topup-schedule.test.d.ts +1 -0
  131. package/dist/credits/auto-topup-schedule.test.js +145 -0
  132. package/dist/credits/auto-topup-settings-repository.d.ts +54 -0
  133. package/dist/credits/auto-topup-settings-repository.js +184 -0
  134. package/dist/credits/auto-topup-settings-repository.test.d.ts +1 -0
  135. package/dist/credits/auto-topup-settings-repository.test.js +104 -0
  136. package/dist/credits/auto-topup-usage.d.ts +22 -0
  137. package/dist/credits/auto-topup-usage.js +56 -0
  138. package/dist/credits/auto-topup-usage.test.d.ts +1 -0
  139. package/dist/credits/auto-topup-usage.test.js +181 -0
  140. package/dist/credits/credit-expiry-cron.d.ts +19 -0
  141. package/dist/credits/credit-expiry-cron.js +50 -0
  142. package/dist/credits/credit-expiry-cron.test.d.ts +1 -0
  143. package/dist/credits/credit-expiry-cron.test.js +67 -0
  144. package/dist/credits/credit-ledger-extra.test.d.ts +1 -0
  145. package/dist/credits/credit-ledger-extra.test.js +40 -0
  146. package/dist/credits/credit-ledger.bench.d.ts +1 -0
  147. package/dist/credits/credit-ledger.bench.js +33 -0
  148. package/dist/credits/credit-ledger.d.ts +130 -0
  149. package/dist/credits/credit-ledger.js +293 -0
  150. package/dist/credits/credit-ledger.test.d.ts +4 -0
  151. package/dist/credits/credit-ledger.test.js +203 -0
  152. package/dist/credits/credit-transaction-repository.d.ts +17 -0
  153. package/dist/credits/credit-transaction-repository.js +35 -0
  154. package/dist/credits/credit-transaction-repository.test.d.ts +1 -0
  155. package/dist/credits/credit-transaction-repository.test.js +232 -0
  156. package/dist/credits/credit.d.ts +75 -0
  157. package/dist/credits/credit.js +139 -0
  158. package/dist/credits/credit.test.d.ts +1 -0
  159. package/dist/credits/credit.test.js +196 -0
  160. package/dist/credits/dividend-cron.d.ts +29 -0
  161. package/dist/credits/dividend-cron.js +88 -0
  162. package/dist/credits/dividend-cron.test.d.ts +1 -0
  163. package/dist/credits/dividend-cron.test.js +128 -0
  164. package/dist/credits/dividend-repository.d.ts +29 -0
  165. package/dist/credits/dividend-repository.js +126 -0
  166. package/dist/credits/dividend-repository.test.d.ts +1 -0
  167. package/dist/credits/dividend-repository.test.js +176 -0
  168. package/dist/credits/index.d.ts +9 -0
  169. package/dist/credits/index.js +5 -0
  170. package/dist/credits/repository-types.d.ts +29 -0
  171. package/dist/credits/repository-types.js +1 -0
  172. package/dist/credits/signup-grant.d.ts +12 -0
  173. package/dist/credits/signup-grant.js +35 -0
  174. package/dist/credits/signup-grant.test.d.ts +1 -0
  175. package/dist/credits/signup-grant.test.js +51 -0
  176. package/dist/credits/tenant-customer-repository.d.ts +30 -0
  177. package/dist/credits/tenant-customer-repository.js +5 -0
  178. package/dist/db/auth-user-repository.d.ts +46 -0
  179. package/dist/db/auth-user-repository.js +90 -0
  180. package/dist/db/credit-column.d.ts +27 -0
  181. package/dist/db/credit-column.js +13 -0
  182. package/dist/db/index.d.ts +14 -0
  183. package/dist/db/index.js +8 -0
  184. package/dist/db/schema/account-deletion-requests.d.ts +203 -0
  185. package/dist/db/schema/account-deletion-requests.js +36 -0
  186. package/dist/db/schema/account-export-requests.d.ts +148 -0
  187. package/dist/db/schema/account-export-requests.js +19 -0
  188. package/dist/db/schema/admin-audit.d.ts +194 -0
  189. package/dist/db/schema/admin-audit.js +21 -0
  190. package/dist/db/schema/admin-users.d.ts +177 -0
  191. package/dist/db/schema/admin-users.js +23 -0
  192. package/dist/db/schema/affiliate-fraud.d.ts +160 -0
  193. package/dist/db/schema/affiliate-fraud.js +18 -0
  194. package/dist/db/schema/affiliate.d.ts +277 -0
  195. package/dist/db/schema/affiliate.js +32 -0
  196. package/dist/db/schema/coupon-codes.d.ts +143 -0
  197. package/dist/db/schema/coupon-codes.js +17 -0
  198. package/dist/db/schema/credit-auto-topup-settings.d.ts +232 -0
  199. package/dist/db/schema/credit-auto-topup-settings.js +27 -0
  200. package/dist/db/schema/credit-auto-topup.d.ts +130 -0
  201. package/dist/db/schema/credit-auto-topup.js +21 -0
  202. package/dist/db/schema/credits.d.ts +283 -0
  203. package/dist/db/schema/credits.js +38 -0
  204. package/dist/db/schema/dividend-distributions.d.ts +130 -0
  205. package/dist/db/schema/dividend-distributions.js +19 -0
  206. package/dist/db/schema/email-notifications.d.ts +99 -0
  207. package/dist/db/schema/email-notifications.js +21 -0
  208. package/dist/db/schema/index.d.ts +33 -0
  209. package/dist/db/schema/index.js +33 -0
  210. package/dist/db/schema/meter-events.d.ts +599 -0
  211. package/dist/db/schema/meter-events.js +55 -0
  212. package/dist/db/schema/notification-preferences.d.ts +165 -0
  213. package/dist/db/schema/notification-preferences.js +18 -0
  214. package/dist/db/schema/notification-queue.d.ts +236 -0
  215. package/dist/db/schema/notification-queue.js +40 -0
  216. package/dist/db/schema/org-memberships.d.ts +63 -0
  217. package/dist/db/schema/org-memberships.js +15 -0
  218. package/dist/db/schema/organization-members.d.ts +235 -0
  219. package/dist/db/schema/organization-members.js +27 -0
  220. package/dist/db/schema/payram.d.ts +164 -0
  221. package/dist/db/schema/payram.js +21 -0
  222. package/dist/db/schema/platform-api-keys.d.ts +143 -0
  223. package/dist/db/schema/platform-api-keys.js +20 -0
  224. package/dist/db/schema/promotion-redemptions.d.ts +143 -0
  225. package/dist/db/schema/promotion-redemptions.js +18 -0
  226. package/dist/db/schema/promotions.d.ts +445 -0
  227. package/dist/db/schema/promotions.js +48 -0
  228. package/dist/db/schema/provider-credentials.d.ts +201 -0
  229. package/dist/db/schema/provider-credentials.js +36 -0
  230. package/dist/db/schema/rate-limit-entries.d.ts +75 -0
  231. package/dist/db/schema/rate-limit-entries.js +7 -0
  232. package/dist/db/schema/secret-audit-log.d.ts +109 -0
  233. package/dist/db/schema/secret-audit-log.js +15 -0
  234. package/dist/db/schema/session-usage.d.ts +194 -0
  235. package/dist/db/schema/session-usage.js +19 -0
  236. package/dist/db/schema/spending-limits.d.ts +92 -0
  237. package/dist/db/schema/spending-limits.js +8 -0
  238. package/dist/db/schema/tenant-addons.d.ts +58 -0
  239. package/dist/db/schema/tenant-addons.js +9 -0
  240. package/dist/db/schema/tenant-api-keys.d.ts +131 -0
  241. package/dist/db/schema/tenant-api-keys.js +21 -0
  242. package/dist/db/schema/tenant-capability-settings.d.ts +79 -0
  243. package/dist/db/schema/tenant-capability-settings.js +12 -0
  244. package/dist/db/schema/tenant-customers.d.ts +303 -0
  245. package/dist/db/schema/tenant-customers.js +25 -0
  246. package/dist/db/schema/tenants.d.ts +126 -0
  247. package/dist/db/schema/tenants.js +18 -0
  248. package/dist/db/schema/user-roles.d.ts +98 -0
  249. package/dist/db/schema/user-roles.js +18 -0
  250. package/dist/db/schema/webhook-seen-events.d.ts +58 -0
  251. package/dist/db/schema/webhook-seen-events.js +9 -0
  252. package/dist/email/billing-emails.d.ts +51 -0
  253. package/dist/email/billing-emails.js +163 -0
  254. package/dist/email/billing-emails.test.d.ts +1 -0
  255. package/dist/email/billing-emails.test.js +162 -0
  256. package/dist/email/client.d.ts +51 -0
  257. package/dist/email/client.js +102 -0
  258. package/dist/email/client.test.d.ts +1 -0
  259. package/dist/email/client.test.js +120 -0
  260. package/dist/email/drizzle-billing-email-repository.d.ts +21 -0
  261. package/dist/email/drizzle-billing-email-repository.js +36 -0
  262. package/dist/email/drizzle-billing-email-repository.test.d.ts +1 -0
  263. package/dist/email/drizzle-billing-email-repository.test.js +42 -0
  264. package/dist/email/index.d.ts +33 -0
  265. package/dist/email/index.js +22 -0
  266. package/dist/email/notification-preferences-store.d.ts +12 -0
  267. package/dist/email/notification-preferences-store.js +82 -0
  268. package/dist/email/notification-preferences-store.test.d.ts +1 -0
  269. package/dist/email/notification-preferences-store.test.js +86 -0
  270. package/dist/email/notification-queue-store.d.ts +25 -0
  271. package/dist/email/notification-queue-store.js +97 -0
  272. package/dist/email/notification-queue-store.test.d.ts +1 -0
  273. package/dist/email/notification-queue-store.test.js +177 -0
  274. package/dist/email/notification-repository-types.d.ts +70 -0
  275. package/dist/email/notification-repository-types.js +6 -0
  276. package/dist/email/notification-service.d.ts +41 -0
  277. package/dist/email/notification-service.js +196 -0
  278. package/dist/email/notification-service.test.d.ts +1 -0
  279. package/dist/email/notification-service.test.js +160 -0
  280. package/dist/email/notification-templates.d.ts +18 -0
  281. package/dist/email/notification-templates.js +574 -0
  282. package/dist/email/notification-templates.test.d.ts +1 -0
  283. package/dist/email/notification-templates.test.js +238 -0
  284. package/dist/email/notification-worker.d.ts +24 -0
  285. package/dist/email/notification-worker.js +109 -0
  286. package/dist/email/notification-worker.test.d.ts +1 -0
  287. package/dist/email/notification-worker.test.js +153 -0
  288. package/dist/email/require-verified.d.ts +25 -0
  289. package/dist/email/require-verified.js +52 -0
  290. package/dist/email/require-verified.test.d.ts +1 -0
  291. package/dist/email/require-verified.test.js +62 -0
  292. package/dist/email/resend-adapter.d.ts +47 -0
  293. package/dist/email/resend-adapter.js +137 -0
  294. package/dist/email/resend-adapter.test.d.ts +1 -0
  295. package/dist/email/resend-adapter.test.js +190 -0
  296. package/dist/email/templates.d.ts +22 -0
  297. package/dist/email/templates.js +359 -0
  298. package/dist/email/templates.test.d.ts +1 -0
  299. package/dist/email/templates.test.js +170 -0
  300. package/dist/email/verification.d.ts +42 -0
  301. package/dist/email/verification.js +83 -0
  302. package/dist/email/verification.test.d.ts +1 -0
  303. package/dist/email/verification.test.js +141 -0
  304. package/dist/index.d.ts +13 -0
  305. package/dist/index.js +23 -0
  306. package/dist/metering/aggregator.d.ts +54 -0
  307. package/dist/metering/aggregator.js +123 -0
  308. package/dist/metering/aggregator.test.d.ts +1 -0
  309. package/dist/metering/aggregator.test.js +179 -0
  310. package/dist/metering/dlq.d.ts +31 -0
  311. package/dist/metering/dlq.js +82 -0
  312. package/dist/metering/dlq.test.d.ts +1 -0
  313. package/dist/metering/dlq.test.js +117 -0
  314. package/dist/metering/drizzle-usage-summary-repository.d.ts +67 -0
  315. package/dist/metering/drizzle-usage-summary-repository.js +98 -0
  316. package/dist/metering/emitter.d.ts +66 -0
  317. package/dist/metering/emitter.js +185 -0
  318. package/dist/metering/emitter.test.d.ts +1 -0
  319. package/dist/metering/emitter.test.js +171 -0
  320. package/dist/metering/index.d.ts +11 -0
  321. package/dist/metering/index.js +5 -0
  322. package/dist/metering/load-test.bench.d.ts +1 -0
  323. package/dist/metering/load-test.bench.js +103 -0
  324. package/dist/metering/meter-event-repository.d.ts +33 -0
  325. package/dist/metering/meter-event-repository.js +58 -0
  326. package/dist/metering/meter-repositories.test.d.ts +1 -0
  327. package/dist/metering/meter-repositories.test.js +419 -0
  328. package/dist/metering/metering.test.d.ts +1 -0
  329. package/dist/metering/metering.test.js +1046 -0
  330. package/dist/metering/reconciliation-cron.d.ts +37 -0
  331. package/dist/metering/reconciliation-cron.js +85 -0
  332. package/dist/metering/reconciliation-cron.test.d.ts +1 -0
  333. package/dist/metering/reconciliation-cron.test.js +162 -0
  334. package/dist/metering/reconciliation-repository.d.ts +27 -0
  335. package/dist/metering/reconciliation-repository.js +43 -0
  336. package/dist/metering/reconciliation-repository.test.d.ts +1 -0
  337. package/dist/metering/reconciliation-repository.test.js +160 -0
  338. package/dist/metering/types.d.ts +88 -0
  339. package/dist/metering/types.js +1 -0
  340. package/dist/metering/wal.d.ts +49 -0
  341. package/dist/metering/wal.js +124 -0
  342. package/dist/metering/wal.test.d.ts +1 -0
  343. package/dist/metering/wal.test.js +175 -0
  344. package/dist/middleware/csrf.d.ts +24 -0
  345. package/dist/middleware/csrf.js +80 -0
  346. package/dist/middleware/csrf.test.d.ts +1 -0
  347. package/dist/middleware/csrf.test.js +152 -0
  348. package/dist/middleware/drizzle-rate-limit-repository.d.ts +9 -0
  349. package/dist/middleware/drizzle-rate-limit-repository.js +52 -0
  350. package/dist/middleware/drizzle-rate-limit-repository.test.d.ts +1 -0
  351. package/dist/middleware/drizzle-rate-limit-repository.test.js +74 -0
  352. package/dist/middleware/get-client-ip.d.ts +22 -0
  353. package/dist/middleware/get-client-ip.js +51 -0
  354. package/dist/middleware/get-client-ip.test.d.ts +1 -0
  355. package/dist/middleware/get-client-ip.test.js +40 -0
  356. package/dist/middleware/index.d.ts +5 -0
  357. package/dist/middleware/index.js +4 -0
  358. package/dist/middleware/rate-limit-repository.d.ts +19 -0
  359. package/dist/middleware/rate-limit-repository.js +1 -0
  360. package/dist/middleware/rate-limit.d.ts +57 -0
  361. package/dist/middleware/rate-limit.js +109 -0
  362. package/dist/middleware/rate-limit.test.d.ts +1 -0
  363. package/dist/middleware/rate-limit.test.js +247 -0
  364. package/dist/security/credential-vault/audit-repository.d.ts +27 -0
  365. package/dist/security/credential-vault/audit-repository.js +42 -0
  366. package/dist/security/credential-vault/audit-repository.test.d.ts +1 -0
  367. package/dist/security/credential-vault/audit-repository.test.js +78 -0
  368. package/dist/security/credential-vault/credential-repository.d.ts +94 -0
  369. package/dist/security/credential-vault/credential-repository.js +145 -0
  370. package/dist/security/credential-vault/credential-repository.test.d.ts +1 -0
  371. package/dist/security/credential-vault/credential-repository.test.js +206 -0
  372. package/dist/security/credential-vault/index.d.ts +12 -0
  373. package/dist/security/credential-vault/index.js +6 -0
  374. package/dist/security/credential-vault/key-rotation.d.ts +18 -0
  375. package/dist/security/credential-vault/key-rotation.js +52 -0
  376. package/dist/security/credential-vault/key-rotation.test.d.ts +1 -0
  377. package/dist/security/credential-vault/key-rotation.test.js +95 -0
  378. package/dist/security/credential-vault/migrate-plaintext.d.ts +15 -0
  379. package/dist/security/credential-vault/migrate-plaintext.js +80 -0
  380. package/dist/security/credential-vault/migrate-plaintext.test.d.ts +1 -0
  381. package/dist/security/credential-vault/migrate-plaintext.test.js +111 -0
  382. package/dist/security/credential-vault/migration-check.d.ts +15 -0
  383. package/dist/security/credential-vault/migration-check.js +71 -0
  384. package/dist/security/credential-vault/migration-check.test.d.ts +1 -0
  385. package/dist/security/credential-vault/migration-check.test.js +457 -0
  386. package/dist/security/credential-vault/store.d.ts +106 -0
  387. package/dist/security/credential-vault/store.js +181 -0
  388. package/dist/security/credential-vault/store.test.d.ts +1 -0
  389. package/dist/security/credential-vault/store.test.js +482 -0
  390. package/dist/security/encryption.d.ts +22 -0
  391. package/dist/security/encryption.js +53 -0
  392. package/dist/security/encryption.test.d.ts +1 -0
  393. package/dist/security/encryption.test.js +95 -0
  394. package/dist/security/host-validation.d.ts +11 -0
  395. package/dist/security/host-validation.js +108 -0
  396. package/dist/security/host-validation.test.d.ts +1 -0
  397. package/dist/security/host-validation.test.js +106 -0
  398. package/dist/security/index.d.ts +11 -0
  399. package/dist/security/index.js +11 -0
  400. package/dist/security/key-audit.d.ts +16 -0
  401. package/dist/security/key-audit.js +35 -0
  402. package/dist/security/key-audit.test.d.ts +1 -0
  403. package/dist/security/key-audit.test.js +50 -0
  404. package/dist/security/key-injection.d.ts +28 -0
  405. package/dist/security/key-injection.js +57 -0
  406. package/dist/security/key-injection.test.d.ts +1 -0
  407. package/dist/security/key-injection.test.js +97 -0
  408. package/dist/security/key-validation.d.ts +16 -0
  409. package/dist/security/key-validation.js +78 -0
  410. package/dist/security/key-validation.test.d.ts +1 -0
  411. package/dist/security/key-validation.test.js +87 -0
  412. package/dist/security/redirect-allowlist.d.ts +6 -0
  413. package/dist/security/redirect-allowlist.js +36 -0
  414. package/dist/security/redirect-allowlist.test.d.ts +1 -0
  415. package/dist/security/redirect-allowlist.test.js +55 -0
  416. package/dist/security/tenant-keys/capability-settings-store.d.ts +22 -0
  417. package/dist/security/tenant-keys/capability-settings-store.js +33 -0
  418. package/dist/security/tenant-keys/capability-settings-store.test.d.ts +1 -0
  419. package/dist/security/tenant-keys/capability-settings-store.test.js +77 -0
  420. package/dist/security/tenant-keys/index.d.ts +10 -0
  421. package/dist/security/tenant-keys/index.js +5 -0
  422. package/dist/security/tenant-keys/key-resolution-repository.d.ts +15 -0
  423. package/dist/security/tenant-keys/key-resolution-repository.js +18 -0
  424. package/dist/security/tenant-keys/key-resolution-repository.test.d.ts +1 -0
  425. package/dist/security/tenant-keys/key-resolution-repository.test.js +72 -0
  426. package/dist/security/tenant-keys/key-resolution.d.ts +39 -0
  427. package/dist/security/tenant-keys/key-resolution.js +59 -0
  428. package/dist/security/tenant-keys/key-resolution.test.d.ts +1 -0
  429. package/dist/security/tenant-keys/key-resolution.test.js +97 -0
  430. package/dist/security/tenant-keys/org-key-resolution.d.ts +30 -0
  431. package/dist/security/tenant-keys/org-key-resolution.js +50 -0
  432. package/dist/security/tenant-keys/org-key-resolution.test.d.ts +1 -0
  433. package/dist/security/tenant-keys/org-key-resolution.test.js +103 -0
  434. package/dist/security/tenant-keys/tenant-key-repository.d.ts +36 -0
  435. package/dist/security/tenant-keys/tenant-key-repository.js +96 -0
  436. package/dist/security/tenant-keys/tenant-key-repository.test.d.ts +1 -0
  437. package/dist/security/tenant-keys/tenant-key-repository.test.js +114 -0
  438. package/dist/security/types.d.ts +35 -0
  439. package/dist/security/types.js +15 -0
  440. package/dist/tenancy/drizzle-org-repository.d.ts +40 -0
  441. package/dist/tenancy/drizzle-org-repository.js +126 -0
  442. package/dist/tenancy/index.d.ts +6 -0
  443. package/dist/tenancy/index.js +3 -0
  444. package/dist/tenancy/org-member-repository.d.ts +57 -0
  445. package/dist/tenancy/org-member-repository.js +99 -0
  446. package/dist/tenancy/org-repository.test.d.ts +1 -0
  447. package/dist/tenancy/org-repository.test.js +143 -0
  448. package/dist/tenancy/org-service.d.ts +70 -0
  449. package/dist/tenancy/org-service.js +223 -0
  450. package/dist/tenancy/org-service.test.d.ts +1 -0
  451. package/dist/tenancy/org-service.test.js +550 -0
  452. package/dist/test/db.d.ts +33 -0
  453. package/dist/test/db.js +65 -0
  454. package/dist/trpc/index.d.ts +1 -0
  455. package/dist/trpc/index.js +1 -0
  456. package/dist/trpc/init.d.ts +49 -0
  457. package/dist/trpc/init.js +108 -0
  458. package/dist/trpc/init.test.d.ts +1 -0
  459. package/dist/trpc/init.test.js +154 -0
  460. package/drizzle/migrations/0000_slippery_mandrill.sql +559 -0
  461. package/drizzle/migrations/meta/0000_snapshot.json +4374 -0
  462. package/drizzle/migrations/meta/_journal.json +13 -0
  463. package/drizzle.config.ts +41 -0
  464. package/package.json +64 -0
  465. package/src/admin/admin-audit-log-repository.ts +135 -0
  466. package/src/admin/audit-log.ts +111 -0
  467. package/src/admin/index.ts +6 -0
  468. package/src/admin/role-store.ts +134 -0
  469. package/src/auth/api-key-repository.test.ts +63 -0
  470. package/src/auth/api-key-repository.ts +46 -0
  471. package/src/auth/auth.test.ts +166 -0
  472. package/src/auth/better-auth.ts +216 -0
  473. package/src/auth/index.ts +520 -0
  474. package/src/auth/login-history-repository.test.ts +54 -0
  475. package/src/auth/login-history-repository.ts +28 -0
  476. package/src/auth/middleware.test.ts +264 -0
  477. package/src/auth/middleware.ts +117 -0
  478. package/src/auth/scoped-tokens.test.ts +362 -0
  479. package/src/auth/tenant-access.test.ts +69 -0
  480. package/src/auth/user-creator.test.ts +98 -0
  481. package/src/auth/user-creator.ts +54 -0
  482. package/src/auth/user-role-repository.test.ts +149 -0
  483. package/src/auth/user-role-repository.ts +67 -0
  484. package/src/billing/drizzle-webhook-seen-repository.ts +34 -0
  485. package/src/billing/index.ts +22 -0
  486. package/src/billing/payment-processor.test.ts +93 -0
  487. package/src/billing/payment-processor.ts +150 -0
  488. package/src/billing/payram/cents-credits-boundary.test.ts +84 -0
  489. package/src/billing/payram/charge-store.test.ts +84 -0
  490. package/src/billing/payram/charge-store.ts +109 -0
  491. package/src/billing/payram/checkout.test.ts +99 -0
  492. package/src/billing/payram/checkout.ts +40 -0
  493. package/src/billing/payram/client.test.ts +62 -0
  494. package/src/billing/payram/client.ts +21 -0
  495. package/src/billing/payram/index.ts +14 -0
  496. package/src/billing/payram/types.ts +44 -0
  497. package/src/billing/payram/webhook.test.ts +318 -0
  498. package/src/billing/payram/webhook.ts +97 -0
  499. package/src/billing/stripe/cents-credits-boundary.test.ts +70 -0
  500. package/src/billing/stripe/checkout.test.ts +186 -0
  501. package/src/billing/stripe/checkout.ts +82 -0
  502. package/src/billing/stripe/client.test.ts +64 -0
  503. package/src/billing/stripe/client.ts +39 -0
  504. package/src/billing/stripe/credit-prices.test.ts +114 -0
  505. package/src/billing/stripe/credit-prices.ts +113 -0
  506. package/src/billing/stripe/index.ts +14 -0
  507. package/src/billing/stripe/payment-methods-detach-all.test.ts +53 -0
  508. package/src/billing/stripe/payment-methods.test.ts +157 -0
  509. package/src/billing/stripe/payment-methods.ts +76 -0
  510. package/src/billing/stripe/portal.test.ts +63 -0
  511. package/src/billing/stripe/portal.ts +25 -0
  512. package/src/billing/stripe/setup-intent.test.ts +78 -0
  513. package/src/billing/stripe/setup-intent.ts +34 -0
  514. package/src/billing/stripe/stripe-payment-processor.test.ts +517 -0
  515. package/src/billing/stripe/stripe-payment-processor.ts +255 -0
  516. package/src/billing/stripe/tenant-store.test.ts +124 -0
  517. package/src/billing/stripe/tenant-store.ts +151 -0
  518. package/src/billing/stripe/types.ts +53 -0
  519. package/src/billing/webhook-seen-repository.ts +24 -0
  520. package/src/config/billing-env.test.ts +54 -0
  521. package/src/config/index.ts +44 -0
  522. package/src/config/logger.ts +12 -0
  523. package/src/config/provider-endpoints.ts +14 -0
  524. package/src/credits/auto-topup-charge.test.ts +292 -0
  525. package/src/credits/auto-topup-charge.ts +171 -0
  526. package/src/credits/auto-topup-event-log-repository.test.ts +99 -0
  527. package/src/credits/auto-topup-event-log-repository.ts +30 -0
  528. package/src/credits/auto-topup-schedule.test.ts +179 -0
  529. package/src/credits/auto-topup-schedule.ts +93 -0
  530. package/src/credits/auto-topup-settings-repository.test.ts +123 -0
  531. package/src/credits/auto-topup-settings-repository.ts +245 -0
  532. package/src/credits/auto-topup-usage.test.ts +220 -0
  533. package/src/credits/auto-topup-usage.ts +68 -0
  534. package/src/credits/credit-expiry-cron.test.ts +125 -0
  535. package/src/credits/credit-expiry-cron.ts +76 -0
  536. package/src/credits/credit-ledger-extra.test.ts +57 -0
  537. package/src/credits/credit-ledger.bench.ts +56 -0
  538. package/src/credits/credit-ledger.test.ts +276 -0
  539. package/src/credits/credit-ledger.ts +450 -0
  540. package/src/credits/credit-transaction-repository.test.ts +274 -0
  541. package/src/credits/credit-transaction-repository.ts +62 -0
  542. package/src/credits/credit.test.ts +234 -0
  543. package/src/credits/credit.ts +160 -0
  544. package/src/credits/dividend-cron.test.ts +158 -0
  545. package/src/credits/dividend-cron.ts +127 -0
  546. package/src/credits/dividend-repository.test.ts +223 -0
  547. package/src/credits/dividend-repository.ts +182 -0
  548. package/src/credits/index.ts +25 -0
  549. package/src/credits/repository-types.ts +33 -0
  550. package/src/credits/signup-grant.test.ts +63 -0
  551. package/src/credits/signup-grant.ts +44 -0
  552. package/src/credits/tenant-customer-repository.ts +28 -0
  553. package/src/db/auth-user-repository.ts +124 -0
  554. package/src/db/credit-column.ts +17 -0
  555. package/src/db/index.ts +21 -0
  556. package/src/db/schema/account-deletion-requests.ts +41 -0
  557. package/src/db/schema/account-export-requests.ts +24 -0
  558. package/src/db/schema/admin-audit.ts +26 -0
  559. package/src/db/schema/admin-users.ts +31 -0
  560. package/src/db/schema/affiliate-fraud.ts +23 -0
  561. package/src/db/schema/affiliate.ts +38 -0
  562. package/src/db/schema/coupon-codes.ts +22 -0
  563. package/src/db/schema/credit-auto-topup-settings.ts +32 -0
  564. package/src/db/schema/credit-auto-topup.ts +26 -0
  565. package/src/db/schema/credits.ts +44 -0
  566. package/src/db/schema/dividend-distributions.ts +24 -0
  567. package/src/db/schema/email-notifications.ts +26 -0
  568. package/src/db/schema/index.ts +33 -0
  569. package/src/db/schema/meter-events.ts +70 -0
  570. package/src/db/schema/notification-preferences.ts +19 -0
  571. package/src/db/schema/notification-queue.ts +45 -0
  572. package/src/db/schema/org-memberships.ts +20 -0
  573. package/src/db/schema/organization-members.ts +37 -0
  574. package/src/db/schema/payram.ts +26 -0
  575. package/src/db/schema/platform-api-keys.ts +25 -0
  576. package/src/db/schema/promotion-redemptions.ts +23 -0
  577. package/src/db/schema/promotions.ts +57 -0
  578. package/src/db/schema/provider-credentials.ts +41 -0
  579. package/src/db/schema/rate-limit-entries.ts +12 -0
  580. package/src/db/schema/secret-audit-log.ts +20 -0
  581. package/src/db/schema/session-usage.ts +24 -0
  582. package/src/db/schema/spending-limits.ts +9 -0
  583. package/src/db/schema/tenant-addons.ts +14 -0
  584. package/src/db/schema/tenant-api-keys.ts +26 -0
  585. package/src/db/schema/tenant-capability-settings.ts +17 -0
  586. package/src/db/schema/tenant-customers.ts +35 -0
  587. package/src/db/schema/tenants.ts +23 -0
  588. package/src/db/schema/user-roles.ts +23 -0
  589. package/src/db/schema/webhook-seen-events.ts +14 -0
  590. package/src/email/billing-emails.test.ts +198 -0
  591. package/src/email/billing-emails.ts +211 -0
  592. package/src/email/client.test.ts +149 -0
  593. package/src/email/client.ts +137 -0
  594. package/src/email/drizzle-billing-email-repository.test.ts +52 -0
  595. package/src/email/drizzle-billing-email-repository.ts +59 -0
  596. package/src/email/index.ts +57 -0
  597. package/src/email/notification-preferences-store.test.ts +102 -0
  598. package/src/email/notification-preferences-store.ts +90 -0
  599. package/src/email/notification-queue-store.test.ts +215 -0
  600. package/src/email/notification-queue-store.ts +127 -0
  601. package/src/email/notification-repository-types.ts +101 -0
  602. package/src/email/notification-service.test.ts +178 -0
  603. package/src/email/notification-service.ts +265 -0
  604. package/src/email/notification-templates.test.ts +261 -0
  605. package/src/email/notification-templates.ts +727 -0
  606. package/src/email/notification-worker.test.ts +189 -0
  607. package/src/email/notification-worker.ts +133 -0
  608. package/src/email/require-verified.ts +65 -0
  609. package/src/email/resend-adapter.test.ts +253 -0
  610. package/src/email/resend-adapter.ts +157 -0
  611. package/src/email/templates.test.ts +217 -0
  612. package/src/email/templates.ts +469 -0
  613. package/src/email/verification.test.ts +185 -0
  614. package/src/email/verification.ts +110 -0
  615. package/src/index.ts +51 -0
  616. package/src/metering/aggregator.test.ts +239 -0
  617. package/src/metering/aggregator.ts +160 -0
  618. package/src/metering/dlq.test.ts +134 -0
  619. package/src/metering/dlq.ts +102 -0
  620. package/src/metering/drizzle-usage-summary-repository.ts +167 -0
  621. package/src/metering/emitter.test.ts +202 -0
  622. package/src/metering/emitter.ts +227 -0
  623. package/src/metering/index.ts +21 -0
  624. package/src/metering/load-test.bench.ts +130 -0
  625. package/src/metering/meter-event-repository.ts +87 -0
  626. package/src/metering/meter-repositories.test.ts +491 -0
  627. package/src/metering/metering.test.ts +1317 -0
  628. package/src/metering/reconciliation-cron.test.ts +202 -0
  629. package/src/metering/reconciliation-cron.ts +134 -0
  630. package/src/metering/reconciliation-repository.test.ts +196 -0
  631. package/src/metering/reconciliation-repository.ts +83 -0
  632. package/src/metering/types.ts +93 -0
  633. package/src/metering/wal.test.ts +222 -0
  634. package/src/metering/wal.ts +139 -0
  635. package/src/middleware/csrf.test.ts +178 -0
  636. package/src/middleware/csrf.ts +101 -0
  637. package/src/middleware/drizzle-rate-limit-repository.test.ts +97 -0
  638. package/src/middleware/drizzle-rate-limit-repository.ts +57 -0
  639. package/src/middleware/get-client-ip.test.ts +49 -0
  640. package/src/middleware/get-client-ip.ts +62 -0
  641. package/src/middleware/index.ts +12 -0
  642. package/src/middleware/rate-limit-repository.ts +22 -0
  643. package/src/middleware/rate-limit.test.ts +338 -0
  644. package/src/middleware/rate-limit.ts +169 -0
  645. package/src/security/credential-vault/audit-repository.test.ts +91 -0
  646. package/src/security/credential-vault/audit-repository.ts +64 -0
  647. package/src/security/credential-vault/credential-repository.test.ts +264 -0
  648. package/src/security/credential-vault/credential-repository.ts +233 -0
  649. package/src/security/credential-vault/index.ts +26 -0
  650. package/src/security/credential-vault/key-rotation.test.ts +139 -0
  651. package/src/security/credential-vault/key-rotation.ts +70 -0
  652. package/src/security/credential-vault/migrate-plaintext.test.ts +138 -0
  653. package/src/security/credential-vault/migrate-plaintext.ts +101 -0
  654. package/src/security/credential-vault/migration-check.test.ts +533 -0
  655. package/src/security/credential-vault/migration-check.ts +88 -0
  656. package/src/security/credential-vault/store.test.ts +569 -0
  657. package/src/security/credential-vault/store.ts +284 -0
  658. package/src/security/encryption.test.ts +114 -0
  659. package/src/security/encryption.ts +65 -0
  660. package/src/security/host-validation.test.ts +136 -0
  661. package/src/security/host-validation.ts +116 -0
  662. package/src/security/index.ts +59 -0
  663. package/src/security/key-audit.test.ts +57 -0
  664. package/src/security/key-audit.ts +45 -0
  665. package/src/security/key-injection.test.ts +131 -0
  666. package/src/security/key-injection.ts +71 -0
  667. package/src/security/key-validation.test.ts +111 -0
  668. package/src/security/key-validation.ts +84 -0
  669. package/src/security/redirect-allowlist.test.ts +70 -0
  670. package/src/security/redirect-allowlist.ts +35 -0
  671. package/src/security/tenant-keys/capability-settings-store.test.ts +98 -0
  672. package/src/security/tenant-keys/capability-settings-store.ts +53 -0
  673. package/src/security/tenant-keys/index.ts +10 -0
  674. package/src/security/tenant-keys/key-resolution-repository.test.ts +95 -0
  675. package/src/security/tenant-keys/key-resolution-repository.ts +31 -0
  676. package/src/security/tenant-keys/key-resolution.test.ts +173 -0
  677. package/src/security/tenant-keys/key-resolution.ts +87 -0
  678. package/src/security/tenant-keys/org-key-resolution.test.ts +217 -0
  679. package/src/security/tenant-keys/org-key-resolution.ts +76 -0
  680. package/src/security/tenant-keys/tenant-key-repository.test.ts +143 -0
  681. package/src/security/tenant-keys/tenant-key-repository.ts +130 -0
  682. package/src/security/types.ts +43 -0
  683. package/src/tenancy/drizzle-org-repository.ts +169 -0
  684. package/src/tenancy/index.ts +6 -0
  685. package/src/tenancy/org-member-repository.ts +159 -0
  686. package/src/tenancy/org-repository.test.ts +172 -0
  687. package/src/tenancy/org-service.test.ts +634 -0
  688. package/src/tenancy/org-service.ts +290 -0
  689. package/src/test/db.ts +97 -0
  690. package/src/trpc/index.ts +11 -0
  691. package/src/trpc/init.test.ts +196 -0
  692. package/src/trpc/init.ts +138 -0
  693. package/tsconfig.json +20 -0
  694. package/vitest.config.ts +8 -0
@@ -0,0 +1,41 @@
1
+ import type { PlatformDb } from "../../db/index.js";
2
+ import type { PayRamPaymentState } from "./types.js";
3
+ export interface PayRamChargeRecord {
4
+ referenceId: string;
5
+ tenantId: string;
6
+ amountUsdCents: number;
7
+ status: string;
8
+ currency: string | null;
9
+ filledAmount: string | null;
10
+ creditedAt: string | null;
11
+ createdAt: string;
12
+ updatedAt: string;
13
+ }
14
+ export interface IPayRamChargeRepository {
15
+ create(referenceId: string, tenantId: string, amountUsdCents: number): Promise<void>;
16
+ getByReferenceId(referenceId: string): Promise<PayRamChargeRecord | null>;
17
+ updateStatus(referenceId: string, status: PayRamPaymentState, currency?: string, filledAmount?: string): Promise<void>;
18
+ markCredited(referenceId: string): Promise<void>;
19
+ isCredited(referenceId: string): Promise<boolean>;
20
+ }
21
+ /**
22
+ * Manages PayRam charge records in PostgreSQL.
23
+ *
24
+ * Each charge maps a PayRam reference_id to a tenant and tracks
25
+ * the payment lifecycle (OPEN -> VERIFYING -> FILLED/CANCELLED).
26
+ */
27
+ export declare class DrizzlePayRamChargeRepository implements IPayRamChargeRepository {
28
+ private readonly db;
29
+ constructor(db: PlatformDb);
30
+ /** Create a new charge record when a payment session is initiated. */
31
+ create(referenceId: string, tenantId: string, amountUsdCents: number): Promise<void>;
32
+ /** Get a charge by reference ID. Returns null if not found. */
33
+ getByReferenceId(referenceId: string): Promise<PayRamChargeRecord | null>;
34
+ /** Update charge status and payment details from webhook. */
35
+ updateStatus(referenceId: string, status: PayRamPaymentState, currency?: string, filledAmount?: string): Promise<void>;
36
+ /** Mark a charge as credited (idempotency flag). */
37
+ markCredited(referenceId: string): Promise<void>;
38
+ /** Check if a charge has already been credited (for idempotency). */
39
+ isCredited(referenceId: string): Promise<boolean>;
40
+ }
41
+ export { DrizzlePayRamChargeRepository as PayRamChargeRepository };
@@ -0,0 +1,72 @@
1
+ import { eq, sql } from "drizzle-orm";
2
+ import { payramCharges } from "../../db/schema/payram.js";
3
+ /**
4
+ * Manages PayRam charge records in PostgreSQL.
5
+ *
6
+ * Each charge maps a PayRam reference_id to a tenant and tracks
7
+ * the payment lifecycle (OPEN -> VERIFYING -> FILLED/CANCELLED).
8
+ */
9
+ export class DrizzlePayRamChargeRepository {
10
+ db;
11
+ constructor(db) {
12
+ this.db = db;
13
+ }
14
+ /** Create a new charge record when a payment session is initiated. */
15
+ async create(referenceId, tenantId, amountUsdCents) {
16
+ await this.db.insert(payramCharges).values({
17
+ referenceId,
18
+ tenantId,
19
+ amountUsdCents,
20
+ status: "OPEN",
21
+ });
22
+ }
23
+ /** Get a charge by reference ID. Returns null if not found. */
24
+ async getByReferenceId(referenceId) {
25
+ const row = (await this.db.select().from(payramCharges).where(eq(payramCharges.referenceId, referenceId)))[0];
26
+ if (!row)
27
+ return null;
28
+ return {
29
+ referenceId: row.referenceId,
30
+ tenantId: row.tenantId,
31
+ amountUsdCents: row.amountUsdCents,
32
+ status: row.status,
33
+ currency: row.currency ?? null,
34
+ filledAmount: row.filledAmount ?? null,
35
+ creditedAt: row.creditedAt ?? null,
36
+ createdAt: row.createdAt,
37
+ updatedAt: row.updatedAt,
38
+ };
39
+ }
40
+ /** Update charge status and payment details from webhook. */
41
+ async updateStatus(referenceId, status, currency, filledAmount) {
42
+ await this.db
43
+ .update(payramCharges)
44
+ .set({
45
+ status,
46
+ currency,
47
+ filledAmount,
48
+ updatedAt: sql `now()`,
49
+ })
50
+ .where(eq(payramCharges.referenceId, referenceId));
51
+ }
52
+ /** Mark a charge as credited (idempotency flag). */
53
+ async markCredited(referenceId) {
54
+ await this.db
55
+ .update(payramCharges)
56
+ .set({
57
+ creditedAt: sql `now()`,
58
+ updatedAt: sql `now()`,
59
+ })
60
+ .where(eq(payramCharges.referenceId, referenceId));
61
+ }
62
+ /** Check if a charge has already been credited (for idempotency). */
63
+ async isCredited(referenceId) {
64
+ const row = (await this.db
65
+ .select({ creditedAt: payramCharges.creditedAt })
66
+ .from(payramCharges)
67
+ .where(eq(payramCharges.referenceId, referenceId)))[0];
68
+ return row?.creditedAt != null;
69
+ }
70
+ }
71
+ // Backward-compat alias.
72
+ export { DrizzlePayRamChargeRepository as PayRamChargeRepository };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,64 @@
1
+ import { afterAll, beforeAll, beforeEach, describe, expect, it } from "vitest";
2
+ import { beginTestTransaction, createTestDb, endTestTransaction, rollbackTestTransaction } from "../../test/db.js";
3
+ import { PayRamChargeRepository } from "./charge-store.js";
4
+ describe("PayRamChargeRepository", () => {
5
+ let pool;
6
+ let db;
7
+ let store;
8
+ beforeAll(async () => {
9
+ ({ db, pool } = await createTestDb());
10
+ await beginTestTransaction(pool);
11
+ });
12
+ afterAll(async () => {
13
+ await endTestTransaction(pool);
14
+ await pool.close();
15
+ });
16
+ beforeEach(async () => {
17
+ await rollbackTestTransaction(pool);
18
+ store = new PayRamChargeRepository(db);
19
+ });
20
+ it("create() stores a charge", async () => {
21
+ await store.create("ref-001", "tenant-1", 2500);
22
+ const charge = await store.getByReferenceId("ref-001");
23
+ expect(charge).not.toBeNull();
24
+ expect(charge?.referenceId).toBe("ref-001");
25
+ expect(charge?.tenantId).toBe("tenant-1");
26
+ expect(charge?.amountUsdCents).toBe(2500);
27
+ expect(charge?.status).toBe("OPEN");
28
+ expect(charge?.creditedAt).toBeNull();
29
+ });
30
+ it("getByReferenceId() returns null when not found", async () => {
31
+ const charge = await store.getByReferenceId("ref-nonexistent");
32
+ expect(charge).toBeNull();
33
+ });
34
+ it("updateStatus() updates status, currency and filled_amount", async () => {
35
+ await store.create("ref-002", "tenant-2", 5000);
36
+ await store.updateStatus("ref-002", "FILLED", "USDC", "50.00");
37
+ const charge = await store.getByReferenceId("ref-002");
38
+ expect(charge?.status).toBe("FILLED");
39
+ expect(charge?.currency).toBe("USDC");
40
+ expect(charge?.filledAmount).toBe("50.00");
41
+ });
42
+ it("updateStatus() handles partial updates (no currency)", async () => {
43
+ await store.create("ref-003", "tenant-3", 1000);
44
+ await store.updateStatus("ref-003", "VERIFYING");
45
+ const charge = await store.getByReferenceId("ref-003");
46
+ expect(charge?.status).toBe("VERIFYING");
47
+ expect(charge?.currency).toBeNull();
48
+ });
49
+ it("isCredited() returns false before markCredited", async () => {
50
+ await store.create("ref-004", "tenant-4", 1500);
51
+ expect(await store.isCredited("ref-004")).toBe(false);
52
+ });
53
+ it("markCredited() sets creditedAt", async () => {
54
+ await store.create("ref-005", "tenant-5", 3000);
55
+ await store.markCredited("ref-005");
56
+ const charge = await store.getByReferenceId("ref-005");
57
+ expect(charge?.creditedAt).not.toBeNull();
58
+ });
59
+ it("isCredited() returns true after markCredited", async () => {
60
+ await store.create("ref-006", "tenant-6", 2000);
61
+ await store.markCredited("ref-006");
62
+ expect(await store.isCredited("ref-006")).toBe(true);
63
+ });
64
+ });
@@ -0,0 +1,15 @@
1
+ import type { Payram } from "payram";
2
+ import type { PayRamChargeRepository } from "./charge-store.js";
3
+ import type { PayRamCheckoutOpts } from "./types.js";
4
+ /** Minimum payment amount in USD. */
5
+ export declare const MIN_PAYMENT_USD = 10;
6
+ /**
7
+ * Create a PayRam payment session and store the charge record.
8
+ *
9
+ * Returns the PayRam-hosted payment page URL and reference ID.
10
+ * The user is redirected to this URL to complete the crypto payment.
11
+ */
12
+ export declare function createPayRamCheckout(payram: Payram, chargeStore: PayRamChargeRepository, opts: PayRamCheckoutOpts): Promise<{
13
+ referenceId: string;
14
+ url: string;
15
+ }>;
@@ -0,0 +1,24 @@
1
+ /** Minimum payment amount in USD. */
2
+ export const MIN_PAYMENT_USD = 10;
3
+ /**
4
+ * Create a PayRam payment session and store the charge record.
5
+ *
6
+ * Returns the PayRam-hosted payment page URL and reference ID.
7
+ * The user is redirected to this URL to complete the crypto payment.
8
+ */
9
+ export async function createPayRamCheckout(payram, chargeStore, opts) {
10
+ if (opts.amountUsd < MIN_PAYMENT_USD) {
11
+ throw new Error(`Minimum payment amount is $${MIN_PAYMENT_USD}`);
12
+ }
13
+ const result = await payram.payments.initiatePayment({
14
+ customerEmail: `${opts.tenant}@${process.env.PLATFORM_DOMAIN ?? "wopr.bot"}`,
15
+ customerId: opts.tenant,
16
+ amountInUSD: opts.amountUsd,
17
+ });
18
+ // Store the charge record for webhook correlation.
19
+ await chargeStore.create(result.reference_id, opts.tenant, Math.round(opts.amountUsd * 100));
20
+ return {
21
+ referenceId: result.reference_id,
22
+ url: result.url,
23
+ };
24
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,74 @@
1
+ import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
2
+ import { beginTestTransaction, createTestDb, endTestTransaction, rollbackTestTransaction } from "../../test/db.js";
3
+ import { PayRamChargeRepository } from "./charge-store.js";
4
+ import { createPayRamCheckout, MIN_PAYMENT_USD } from "./checkout.js";
5
+ function createMockPayram(overrides = {}) {
6
+ return {
7
+ payments: {
8
+ initiatePayment: overrides.initiatePayment ??
9
+ vi.fn().mockResolvedValue({
10
+ reference_id: "ref-mock-001",
11
+ url: "https://payram.example.com/pay/ref-mock-001",
12
+ }),
13
+ },
14
+ };
15
+ }
16
+ describe("createPayRamCheckout", () => {
17
+ let pool;
18
+ let db;
19
+ let chargeStore;
20
+ let payram;
21
+ beforeAll(async () => {
22
+ ({ db, pool } = await createTestDb());
23
+ await beginTestTransaction(pool);
24
+ });
25
+ afterAll(async () => {
26
+ await endTestTransaction(pool);
27
+ await pool.close();
28
+ });
29
+ beforeEach(async () => {
30
+ await rollbackTestTransaction(pool);
31
+ chargeStore = new PayRamChargeRepository(db);
32
+ payram = createMockPayram();
33
+ });
34
+ it("rejects amounts below $10 minimum", async () => {
35
+ await expect(createPayRamCheckout(payram, chargeStore, { tenant: "t-1", amountUsd: 5 })).rejects.toThrow(`Minimum payment amount is $${MIN_PAYMENT_USD}`);
36
+ });
37
+ it("rejects amounts of exactly $0", async () => {
38
+ await expect(createPayRamCheckout(payram, chargeStore, { tenant: "t-1", amountUsd: 0 })).rejects.toThrow();
39
+ });
40
+ it("calls payram.payments.initiatePayment with correct params", async () => {
41
+ const initiatePayment = vi.fn().mockResolvedValue({
42
+ reference_id: "ref-abc",
43
+ url: "https://payram.example.com/pay/ref-abc",
44
+ });
45
+ const mockPayram = createMockPayram({ initiatePayment });
46
+ await createPayRamCheckout(mockPayram, chargeStore, { tenant: "t-test", amountUsd: 25 });
47
+ expect(initiatePayment).toHaveBeenCalledWith({
48
+ customerEmail: "t-test@wopr.bot",
49
+ customerId: "t-test",
50
+ amountInUSD: 25,
51
+ });
52
+ });
53
+ it("stores the charge with correct amountUsdCents (converts from USD)", async () => {
54
+ const initiatePayment = vi.fn().mockResolvedValue({
55
+ reference_id: "ref-store-test",
56
+ url: "https://payram.example.com/pay/ref-store-test",
57
+ });
58
+ const mockPayram = createMockPayram({ initiatePayment });
59
+ await createPayRamCheckout(mockPayram, chargeStore, { tenant: "t-2", amountUsd: 25 });
60
+ const charge = await chargeStore.getByReferenceId("ref-store-test");
61
+ expect(charge).not.toBeNull();
62
+ expect(charge?.tenantId).toBe("t-2");
63
+ expect(charge?.amountUsdCents).toBe(2500); // $25.00 = 2500 cents
64
+ expect(charge?.status).toBe("OPEN");
65
+ });
66
+ it("returns referenceId and url from PayRam response", async () => {
67
+ const result = await createPayRamCheckout(payram, chargeStore, { tenant: "t-3", amountUsd: 10 });
68
+ expect(result.referenceId).toBe("ref-mock-001");
69
+ expect(result.url).toBe("https://payram.example.com/pay/ref-mock-001");
70
+ });
71
+ it("accepts exactly $10 (minimum boundary)", async () => {
72
+ await expect(createPayRamCheckout(payram, chargeStore, { tenant: "t-4", amountUsd: 10 })).resolves.not.toBeNull();
73
+ });
74
+ });
@@ -0,0 +1,7 @@
1
+ import { Payram } from "payram";
2
+ export interface PayRamConfig {
3
+ apiKey: string;
4
+ baseUrl: string;
5
+ }
6
+ export declare function createPayRamClient(config: PayRamConfig): Payram;
7
+ export declare function loadPayRamConfig(): PayRamConfig | null;
@@ -0,0 +1,15 @@
1
+ import { Payram } from "payram";
2
+ export function createPayRamClient(config) {
3
+ return new Payram({
4
+ apiKey: config.apiKey,
5
+ baseUrl: config.baseUrl,
6
+ config: { timeoutMs: 30_000, maxRetries: 2, retryPolicy: "safe" },
7
+ });
8
+ }
9
+ export function loadPayRamConfig() {
10
+ const apiKey = process.env.PAYRAM_API_KEY;
11
+ const baseUrl = process.env.PAYRAM_BASE_URL;
12
+ if (!apiKey || !baseUrl)
13
+ return null;
14
+ return { apiKey, baseUrl };
15
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,52 @@
1
+ import { Payram } from "payram";
2
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
3
+ import { createPayRamClient, loadPayRamConfig } from "./client.js";
4
+ describe("createPayRamClient", () => {
5
+ it("returns a Payram instance", () => {
6
+ const client = createPayRamClient({ apiKey: "test-key", baseUrl: "https://api.payram.test" });
7
+ expect(client).toBeInstanceOf(Payram);
8
+ });
9
+ it("passes config through to the Payram constructor", () => {
10
+ const client = createPayRamClient({ apiKey: "pk_live_123", baseUrl: "https://api.payram.io" });
11
+ expect(client).toBeInstanceOf(Payram);
12
+ });
13
+ });
14
+ describe("loadPayRamConfig", () => {
15
+ beforeEach(() => {
16
+ delete process.env.PAYRAM_API_KEY;
17
+ delete process.env.PAYRAM_BASE_URL;
18
+ });
19
+ afterEach(() => {
20
+ vi.unstubAllEnvs();
21
+ });
22
+ it("returns null when PAYRAM_API_KEY is missing", () => {
23
+ vi.stubEnv("PAYRAM_BASE_URL", "https://api.payram.test");
24
+ expect(loadPayRamConfig()).toBeNull();
25
+ });
26
+ it("returns null when PAYRAM_BASE_URL is missing", () => {
27
+ vi.stubEnv("PAYRAM_API_KEY", "pk_test_123");
28
+ expect(loadPayRamConfig()).toBeNull();
29
+ });
30
+ it("returns null when PAYRAM_API_KEY is an empty string", () => {
31
+ vi.stubEnv("PAYRAM_API_KEY", "");
32
+ vi.stubEnv("PAYRAM_BASE_URL", "https://api.payram.test");
33
+ expect(loadPayRamConfig()).toBeNull();
34
+ });
35
+ it("returns null when PAYRAM_BASE_URL is an empty string", () => {
36
+ vi.stubEnv("PAYRAM_API_KEY", "pk_test_123");
37
+ vi.stubEnv("PAYRAM_BASE_URL", "");
38
+ expect(loadPayRamConfig()).toBeNull();
39
+ });
40
+ it("returns config when both env vars are set", () => {
41
+ vi.stubEnv("PAYRAM_API_KEY", "pk_test_123");
42
+ vi.stubEnv("PAYRAM_BASE_URL", "https://api.payram.test");
43
+ const config = loadPayRamConfig();
44
+ expect(config).toEqual({
45
+ apiKey: "pk_test_123",
46
+ baseUrl: "https://api.payram.test",
47
+ });
48
+ });
49
+ it("returns null when both env vars are missing", () => {
50
+ expect(loadPayRamConfig()).toBeNull();
51
+ });
52
+ });
@@ -0,0 +1,8 @@
1
+ export type { IPayRamChargeRepository, PayRamChargeRecord } from "./charge-store.js";
2
+ export { DrizzlePayRamChargeRepository, PayRamChargeRepository } from "./charge-store.js";
3
+ export { createPayRamCheckout, MIN_PAYMENT_USD } from "./checkout.js";
4
+ export type { PayRamConfig } from "./client.js";
5
+ export { createPayRamClient, loadPayRamConfig } from "./client.js";
6
+ export type { PayRamBillingConfig, PayRamCheckoutOpts, PayRamPaymentState, PayRamWebhookPayload, PayRamWebhookResult, } from "./types.js";
7
+ export type { PayRamWebhookDeps } from "./webhook.js";
8
+ export { handlePayRamWebhook } from "./webhook.js";
@@ -0,0 +1,4 @@
1
+ export { DrizzlePayRamChargeRepository, PayRamChargeRepository } from "./charge-store.js";
2
+ export { createPayRamCheckout, MIN_PAYMENT_USD } from "./checkout.js";
3
+ export { createPayRamClient, loadPayRamConfig } from "./client.js";
4
+ export { handlePayRamWebhook } from "./webhook.js";
@@ -0,0 +1,40 @@
1
+ /** PayRam payment states (from PayRam API docs). */
2
+ export type PayRamPaymentState = "OPEN" | "VERIFYING" | "FILLED" | "OVER_FILLED" | "PARTIALLY_FILLED" | "CANCELLED";
3
+ /** Options for creating a PayRam payment session. */
4
+ export interface PayRamCheckoutOpts {
5
+ /** Internal tenant ID. */
6
+ tenant: string;
7
+ /** Amount in USD (minimum $10). */
8
+ amountUsd: number;
9
+ }
10
+ /** Webhook payload received from PayRam. */
11
+ export interface PayRamWebhookPayload {
12
+ /** Unique payment reference from session creation. */
13
+ reference_id: string;
14
+ /** Merchant invoice ID (echoed back if sent). */
15
+ invoice_id?: string;
16
+ /** Payment status. */
17
+ status: PayRamPaymentState;
18
+ /** Amount filled in this update. */
19
+ amount: string;
20
+ /** Currency symbol (ETH, USDC, USDT, etc.). */
21
+ currency: string;
22
+ /** Cumulative total filled so far. */
23
+ filled_amount: string;
24
+ }
25
+ /** Configuration for PayRam billing integration. */
26
+ export interface PayRamBillingConfig {
27
+ /** PayRam API key (from dashboard). */
28
+ apiKey: string;
29
+ /** PayRam self-hosted server base URL. */
30
+ baseUrl: string;
31
+ }
32
+ /** Result of processing a PayRam webhook event. */
33
+ export interface PayRamWebhookResult {
34
+ handled: boolean;
35
+ status: string;
36
+ tenant?: string;
37
+ creditedCents?: number;
38
+ reactivatedBots?: string[];
39
+ duplicate?: boolean;
40
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,19 @@
1
+ import type { ICreditLedger } from "../../credits/credit-ledger.js";
2
+ import type { IWebhookSeenRepository } from "../webhook-seen-repository.js";
3
+ import type { PayRamChargeRepository } from "./charge-store.js";
4
+ import type { PayRamWebhookPayload, PayRamWebhookResult } from "./types.js";
5
+ export interface PayRamWebhookDeps {
6
+ chargeStore: PayRamChargeRepository;
7
+ creditLedger: ICreditLedger;
8
+ replayGuard: IWebhookSeenRepository;
9
+ /** Called after credits are purchased — consumer can reactivate suspended resources. Returns reactivated resource IDs. */
10
+ onCreditsPurchased?: (tenantId: string, ledger: ICreditLedger) => Promise<string[]>;
11
+ }
12
+ /**
13
+ * Process a PayRam webhook event.
14
+ *
15
+ * Only credits the ledger on FILLED or OVER_FILLED status.
16
+ * Uses the PayRam reference_id mapped to the stored charge record
17
+ * for tenant resolution and idempotency.
18
+ */
19
+ export declare function handlePayRamWebhook(deps: PayRamWebhookDeps, payload: PayRamWebhookPayload): Promise<PayRamWebhookResult>;
@@ -0,0 +1,67 @@
1
+ import { Credit } from "../../credits/credit.js";
2
+ /**
3
+ * Process a PayRam webhook event.
4
+ *
5
+ * Only credits the ledger on FILLED or OVER_FILLED status.
6
+ * Uses the PayRam reference_id mapped to the stored charge record
7
+ * for tenant resolution and idempotency.
8
+ */
9
+ export async function handlePayRamWebhook(deps, payload) {
10
+ const { chargeStore, creditLedger } = deps;
11
+ // Replay guard: deduplicate by reference_id + status combination.
12
+ const dedupeKey = `${payload.reference_id}:${payload.status}`;
13
+ if (await deps.replayGuard.isDuplicate(dedupeKey, "payram")) {
14
+ return { handled: true, status: payload.status, duplicate: true };
15
+ }
16
+ // Look up the charge record to find the tenant.
17
+ const charge = await chargeStore.getByReferenceId(payload.reference_id);
18
+ if (!charge) {
19
+ return { handled: false, status: payload.status };
20
+ }
21
+ // Update charge status regardless of payment state.
22
+ await chargeStore.updateStatus(payload.reference_id, payload.status, payload.currency, payload.filled_amount);
23
+ let result;
24
+ if (payload.status === "FILLED" || payload.status === "OVER_FILLED") {
25
+ // Idempotency: skip if already credited.
26
+ if (await chargeStore.isCredited(payload.reference_id)) {
27
+ result = {
28
+ handled: true,
29
+ status: payload.status,
30
+ tenant: charge.tenantId,
31
+ creditedCents: 0,
32
+ };
33
+ }
34
+ else {
35
+ // Credit the original USD amount requested (not the crypto amount).
36
+ // For OVER_FILLED, we still credit the requested amount — the
37
+ // overpayment stays in the PayRam wallet as a buffer.
38
+ const creditCents = charge.amountUsdCents;
39
+ await creditLedger.credit(charge.tenantId, Credit.fromCents(creditCents), "purchase", `Crypto credit purchase via PayRam (ref: ${payload.reference_id}, ${payload.currency ?? "crypto"})`, `payram:${payload.reference_id}`, "payram");
40
+ await chargeStore.markCredited(payload.reference_id);
41
+ // Reactivate suspended resources after credit purchase.
42
+ let reactivatedBots;
43
+ if (deps.onCreditsPurchased) {
44
+ reactivatedBots = await deps.onCreditsPurchased(charge.tenantId, creditLedger);
45
+ if (reactivatedBots.length === 0)
46
+ reactivatedBots = undefined;
47
+ }
48
+ result = {
49
+ handled: true,
50
+ status: payload.status,
51
+ tenant: charge.tenantId,
52
+ creditedCents: creditCents,
53
+ reactivatedBots,
54
+ };
55
+ }
56
+ }
57
+ else {
58
+ // OPEN, VERIFYING, PARTIALLY_FILLED, CANCELLED — just track status.
59
+ result = {
60
+ handled: true,
61
+ status: payload.status,
62
+ tenant: charge.tenantId,
63
+ };
64
+ }
65
+ await deps.replayGuard.markSeen(dedupeKey, "payram");
66
+ return result;
67
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Unit tests for PayRam webhook handler (WOP-407).
3
+ *
4
+ * Covers FILLED/OVER_FILLED crediting the ledger, PARTIALLY_FILLED/CANCELLED
5
+ * no-op status, idempotency, replay guard, and bot reactivation.
6
+ */
7
+ export {};