@soulbatical/tetra-core 0.10.5 → 0.11.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 (245) hide show
  1. package/README.md +32 -6
  2. package/dist/core/createApp.d.ts +1 -1
  3. package/dist/core/createApp.d.ts.map +1 -1
  4. package/dist/generators/rls-checker.d.ts +1 -1
  5. package/dist/generators/rls-checker.js +1 -1
  6. package/dist/generators/rls-exec-sql.d.ts +1 -1
  7. package/dist/generators/rls-exec-sql.js +1 -1
  8. package/dist/generators/rpc/index.d.ts +1 -1
  9. package/dist/generators/rpc/index.js +1 -1
  10. package/dist/index.d.ts +0 -6
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +3 -9
  13. package/dist/index.js.map +1 -1
  14. package/dist/middleware/securityMiddleware.d.ts +1 -1
  15. package/dist/middleware/securityMiddleware.d.ts.map +1 -1
  16. package/dist/utils/logger.d.ts.map +1 -1
  17. package/dist/utils/logger.js +12 -1
  18. package/dist/utils/logger.js.map +1 -1
  19. package/package.json +30 -44
  20. package/dist/affiliate.d.ts +0 -11
  21. package/dist/affiliate.d.ts.map +0 -1
  22. package/dist/affiliate.js +0 -10
  23. package/dist/affiliate.js.map +0 -1
  24. package/dist/billing.d.ts +0 -8
  25. package/dist/billing.d.ts.map +0 -1
  26. package/dist/billing.js +0 -7
  27. package/dist/billing.js.map +0 -1
  28. package/dist/email.d.ts +0 -9
  29. package/dist/email.d.ts.map +0 -1
  30. package/dist/email.js +0 -8
  31. package/dist/email.js.map +0 -1
  32. package/dist/generators/rls-exec-sql.sql +0 -57
  33. package/dist/generators.d.ts +0 -9
  34. package/dist/generators.d.ts.map +0 -1
  35. package/dist/generators.js +0 -8
  36. package/dist/generators.js.map +0 -1
  37. package/dist/mcp.d.ts +0 -8
  38. package/dist/mcp.d.ts.map +0 -1
  39. package/dist/mcp.js +0 -7
  40. package/dist/mcp.js.map +0 -1
  41. package/dist/planner.d.ts +0 -8
  42. package/dist/planner.d.ts.map +0 -1
  43. package/dist/planner.js +0 -7
  44. package/dist/planner.js.map +0 -1
  45. package/dist/shared/affiliate/AffiliateAttributionService.d.ts +0 -47
  46. package/dist/shared/affiliate/AffiliateAttributionService.d.ts.map +0 -1
  47. package/dist/shared/affiliate/AffiliateAttributionService.js +0 -308
  48. package/dist/shared/affiliate/AffiliateAttributionService.js.map +0 -1
  49. package/dist/shared/affiliate/AffiliateClickService.d.ts +0 -35
  50. package/dist/shared/affiliate/AffiliateClickService.d.ts.map +0 -1
  51. package/dist/shared/affiliate/AffiliateClickService.js +0 -87
  52. package/dist/shared/affiliate/AffiliateClickService.js.map +0 -1
  53. package/dist/shared/affiliate/affiliateFeatureConfig.d.ts +0 -11
  54. package/dist/shared/affiliate/affiliateFeatureConfig.d.ts.map +0 -1
  55. package/dist/shared/affiliate/affiliateFeatureConfig.js +0 -242
  56. package/dist/shared/affiliate/affiliateFeatureConfig.js.map +0 -1
  57. package/dist/shared/affiliate/index.d.ts +0 -11
  58. package/dist/shared/affiliate/index.d.ts.map +0 -1
  59. package/dist/shared/affiliate/index.js +0 -13
  60. package/dist/shared/affiliate/index.js.map +0 -1
  61. package/dist/shared/affiliate/routes.d.ts +0 -87
  62. package/dist/shared/affiliate/routes.d.ts.map +0 -1
  63. package/dist/shared/affiliate/routes.js +0 -404
  64. package/dist/shared/affiliate/routes.js.map +0 -1
  65. package/dist/shared/affiliate/types.d.ts +0 -170
  66. package/dist/shared/affiliate/types.d.ts.map +0 -1
  67. package/dist/shared/affiliate/types.js +0 -11
  68. package/dist/shared/affiliate/types.js.map +0 -1
  69. package/dist/shared/billing/BillingService.d.ts +0 -56
  70. package/dist/shared/billing/BillingService.d.ts.map +0 -1
  71. package/dist/shared/billing/BillingService.js +0 -588
  72. package/dist/shared/billing/BillingService.js.map +0 -1
  73. package/dist/shared/billing/SeatBillingService.d.ts +0 -106
  74. package/dist/shared/billing/SeatBillingService.d.ts.map +0 -1
  75. package/dist/shared/billing/SeatBillingService.js +0 -292
  76. package/dist/shared/billing/SeatBillingService.js.map +0 -1
  77. package/dist/shared/billing/index.d.ts +0 -30
  78. package/dist/shared/billing/index.d.ts.map +0 -1
  79. package/dist/shared/billing/index.js +0 -27
  80. package/dist/shared/billing/index.js.map +0 -1
  81. package/dist/shared/billing/routes.d.ts +0 -45
  82. package/dist/shared/billing/routes.d.ts.map +0 -1
  83. package/dist/shared/billing/routes.js +0 -184
  84. package/dist/shared/billing/routes.js.map +0 -1
  85. package/dist/shared/billing/seat-pricing.d.ts +0 -53
  86. package/dist/shared/billing/seat-pricing.d.ts.map +0 -1
  87. package/dist/shared/billing/seat-pricing.js +0 -81
  88. package/dist/shared/billing/seat-pricing.js.map +0 -1
  89. package/dist/shared/billing/types.d.ts +0 -109
  90. package/dist/shared/billing/types.d.ts.map +0 -1
  91. package/dist/shared/billing/types.js +0 -8
  92. package/dist/shared/billing/types.js.map +0 -1
  93. package/dist/shared/email/EmailService.d.ts +0 -64
  94. package/dist/shared/email/EmailService.d.ts.map +0 -1
  95. package/dist/shared/email/EmailService.js +0 -300
  96. package/dist/shared/email/EmailService.js.map +0 -1
  97. package/dist/shared/email/adminRoutes.d.ts +0 -30
  98. package/dist/shared/email/adminRoutes.d.ts.map +0 -1
  99. package/dist/shared/email/adminRoutes.js +0 -227
  100. package/dist/shared/email/adminRoutes.js.map +0 -1
  101. package/dist/shared/email/gmail.d.ts +0 -208
  102. package/dist/shared/email/gmail.d.ts.map +0 -1
  103. package/dist/shared/email/gmail.js +0 -626
  104. package/dist/shared/email/gmail.js.map +0 -1
  105. package/dist/shared/email/index.d.ts +0 -15
  106. package/dist/shared/email/index.d.ts.map +0 -1
  107. package/dist/shared/email/index.js +0 -18
  108. package/dist/shared/email/index.js.map +0 -1
  109. package/dist/shared/email/mailgun.d.ts +0 -18
  110. package/dist/shared/email/mailgun.d.ts.map +0 -1
  111. package/dist/shared/email/mailgun.js +0 -76
  112. package/dist/shared/email/mailgun.js.map +0 -1
  113. package/dist/shared/email/sanitize.d.ts +0 -25
  114. package/dist/shared/email/sanitize.d.ts.map +0 -1
  115. package/dist/shared/email/sanitize.js +0 -39
  116. package/dist/shared/email/sanitize.js.map +0 -1
  117. package/dist/shared/email/smtp.d.ts +0 -20
  118. package/dist/shared/email/smtp.d.ts.map +0 -1
  119. package/dist/shared/email/smtp.js +0 -53
  120. package/dist/shared/email/smtp.js.map +0 -1
  121. package/dist/shared/email/types.d.ts +0 -113
  122. package/dist/shared/email/types.d.ts.map +0 -1
  123. package/dist/shared/email/types.js +0 -7
  124. package/dist/shared/email/types.js.map +0 -1
  125. package/dist/shared/email/webhookRoutes.d.ts +0 -29
  126. package/dist/shared/email/webhookRoutes.d.ts.map +0 -1
  127. package/dist/shared/email/webhookRoutes.js +0 -125
  128. package/dist/shared/email/webhookRoutes.js.map +0 -1
  129. package/dist/shared/mcp/index.d.ts +0 -51
  130. package/dist/shared/mcp/index.d.ts.map +0 -1
  131. package/dist/shared/mcp/index.js +0 -51
  132. package/dist/shared/mcp/index.js.map +0 -1
  133. package/dist/shared/mcp/mcp-auth-routes.d.ts +0 -26
  134. package/dist/shared/mcp/mcp-auth-routes.d.ts.map +0 -1
  135. package/dist/shared/mcp/mcp-auth-routes.js +0 -141
  136. package/dist/shared/mcp/mcp-auth-routes.js.map +0 -1
  137. package/dist/shared/mcp/mcp-db.d.ts +0 -99
  138. package/dist/shared/mcp/mcp-db.d.ts.map +0 -1
  139. package/dist/shared/mcp/mcp-db.js +0 -106
  140. package/dist/shared/mcp/mcp-db.js.map +0 -1
  141. package/dist/shared/mcp/mcp-routes.d.ts +0 -29
  142. package/dist/shared/mcp/mcp-routes.d.ts.map +0 -1
  143. package/dist/shared/mcp/mcp-routes.js +0 -171
  144. package/dist/shared/mcp/mcp-routes.js.map +0 -1
  145. package/dist/shared/mcp/mcp-tokens-routes.d.ts +0 -35
  146. package/dist/shared/mcp/mcp-tokens-routes.d.ts.map +0 -1
  147. package/dist/shared/mcp/mcp-tokens-routes.js +0 -94
  148. package/dist/shared/mcp/mcp-tokens-routes.js.map +0 -1
  149. package/dist/shared/mcp/mcp-usage-routes.d.ts +0 -17
  150. package/dist/shared/mcp/mcp-usage-routes.d.ts.map +0 -1
  151. package/dist/shared/mcp/mcp-usage-routes.js +0 -81
  152. package/dist/shared/mcp/mcp-usage-routes.js.map +0 -1
  153. package/dist/shared/mcp/tenant-context.d.ts +0 -59
  154. package/dist/shared/mcp/tenant-context.d.ts.map +0 -1
  155. package/dist/shared/mcp/tenant-context.js +0 -136
  156. package/dist/shared/mcp/tenant-context.js.map +0 -1
  157. package/dist/shared/mcp/types.d.ts +0 -74
  158. package/dist/shared/mcp/types.d.ts.map +0 -1
  159. package/dist/shared/mcp/types.js +0 -7
  160. package/dist/shared/mcp/types.js.map +0 -1
  161. package/dist/shared/planner/GoogleCalendarService.d.ts +0 -137
  162. package/dist/shared/planner/GoogleCalendarService.d.ts.map +0 -1
  163. package/dist/shared/planner/GoogleCalendarService.js +0 -525
  164. package/dist/shared/planner/GoogleCalendarService.js.map +0 -1
  165. package/dist/shared/planner/PlannerService.d.ts +0 -264
  166. package/dist/shared/planner/PlannerService.d.ts.map +0 -1
  167. package/dist/shared/planner/PlannerService.js +0 -1393
  168. package/dist/shared/planner/PlannerService.js.map +0 -1
  169. package/dist/shared/planner/index.d.ts +0 -37
  170. package/dist/shared/planner/index.d.ts.map +0 -1
  171. package/dist/shared/planner/index.js +0 -35
  172. package/dist/shared/planner/index.js.map +0 -1
  173. package/dist/shared/planner/intervals.d.ts +0 -60
  174. package/dist/shared/planner/intervals.d.ts.map +0 -1
  175. package/dist/shared/planner/intervals.js +0 -141
  176. package/dist/shared/planner/intervals.js.map +0 -1
  177. package/dist/shared/planner/routes.d.ts +0 -69
  178. package/dist/shared/planner/routes.d.ts.map +0 -1
  179. package/dist/shared/planner/routes.js +0 -770
  180. package/dist/shared/planner/routes.js.map +0 -1
  181. package/dist/shared/planner/types.d.ts +0 -328
  182. package/dist/shared/planner/types.d.ts.map +0 -1
  183. package/dist/shared/planner/types.js +0 -9
  184. package/dist/shared/planner/types.js.map +0 -1
  185. package/dist/shared/storage/ImageProcessingService.d.ts +0 -32
  186. package/dist/shared/storage/ImageProcessingService.d.ts.map +0 -1
  187. package/dist/shared/storage/ImageProcessingService.js +0 -127
  188. package/dist/shared/storage/ImageProcessingService.js.map +0 -1
  189. package/dist/shared/storage/StorageProxyService.d.ts +0 -47
  190. package/dist/shared/storage/StorageProxyService.d.ts.map +0 -1
  191. package/dist/shared/storage/StorageProxyService.js +0 -196
  192. package/dist/shared/storage/StorageProxyService.js.map +0 -1
  193. package/dist/shared/storage/StorageUploadService.d.ts +0 -126
  194. package/dist/shared/storage/StorageUploadService.d.ts.map +0 -1
  195. package/dist/shared/storage/StorageUploadService.js +0 -206
  196. package/dist/shared/storage/StorageUploadService.js.map +0 -1
  197. package/dist/shared/storage/creative-urls.d.ts +0 -14
  198. package/dist/shared/storage/creative-urls.d.ts.map +0 -1
  199. package/dist/shared/storage/creative-urls.js +0 -30
  200. package/dist/shared/storage/creative-urls.js.map +0 -1
  201. package/dist/shared/storage/index.d.ts +0 -28
  202. package/dist/shared/storage/index.d.ts.map +0 -1
  203. package/dist/shared/storage/index.js +0 -27
  204. package/dist/shared/storage/index.js.map +0 -1
  205. package/dist/shared/storage/routes.d.ts +0 -42
  206. package/dist/shared/storage/routes.d.ts.map +0 -1
  207. package/dist/shared/storage/routes.js +0 -160
  208. package/dist/shared/storage/routes.js.map +0 -1
  209. package/dist/shared/storage/types.d.ts +0 -53
  210. package/dist/shared/storage/types.d.ts.map +0 -1
  211. package/dist/shared/storage/types.js +0 -2
  212. package/dist/shared/storage/types.js.map +0 -1
  213. package/dist/shared/telegram/index.d.ts +0 -4
  214. package/dist/shared/telegram/index.d.ts.map +0 -1
  215. package/dist/shared/telegram/index.js +0 -3
  216. package/dist/shared/telegram/index.js.map +0 -1
  217. package/dist/shared/telegram/routes.d.ts +0 -48
  218. package/dist/shared/telegram/routes.d.ts.map +0 -1
  219. package/dist/shared/telegram/routes.js +0 -918
  220. package/dist/shared/telegram/routes.js.map +0 -1
  221. package/dist/shared/telegram/types.d.ts +0 -186
  222. package/dist/shared/telegram/types.d.ts.map +0 -1
  223. package/dist/shared/telegram/types.js +0 -7
  224. package/dist/shared/telegram/types.js.map +0 -1
  225. package/dist/shared/telegram/utils.d.ts +0 -44
  226. package/dist/shared/telegram/utils.d.ts.map +0 -1
  227. package/dist/shared/telegram/utils.js +0 -121
  228. package/dist/shared/telegram/utils.js.map +0 -1
  229. package/dist/storage.d.ts +0 -9
  230. package/dist/storage.d.ts.map +0 -1
  231. package/dist/storage.js +0 -8
  232. package/dist/storage.js.map +0 -1
  233. package/dist/telemetry.d.ts +0 -9
  234. package/dist/telemetry.d.ts.map +0 -1
  235. package/dist/telemetry.js +0 -8
  236. package/dist/telemetry.js.map +0 -1
  237. package/scripts/postinstall.js +0 -79
  238. package/src/shared/affiliate/migrations/001_create_affiliates.sql +0 -49
  239. package/src/shared/affiliate/migrations/002_create_affiliate_commissions.sql +0 -31
  240. package/src/shared/affiliate/migrations/003_create_affiliate_clicks.sql +0 -26
  241. package/src/shared/affiliate/migrations/004_create_affiliate_payments.sql +0 -34
  242. package/src/shared/affiliate/migrations/005_create_affiliate_tier_history.sql +0 -19
  243. package/src/shared/affiliate/migrations/006_create_affiliate_rpc_functions.sql +0 -209
  244. package/src/shared/affiliate/migrations/007_create_affiliate_rls_policies.sql +0 -123
  245. package/src/shared/billing/migrations/00000000000001_billing.sql +0 -114
@@ -1,184 +0,0 @@
1
- /**
2
- * Billing Route Helpers — factory functions for standard billing endpoints
3
- *
4
- * Usage:
5
- * ```typescript
6
- * import { addBillingRoutes, addBillingWebhookRoutes } from '@soulbatical/tetra-core';
7
- *
8
- * // Authenticated routes (mount behind auth middleware)
9
- * const billingRouter = Router();
10
- * billingRouter.use(authenticateToken);
11
- * addBillingRoutes(billingRouter, { config, getOrgId, getBillingStatus });
12
- *
13
- * // Webhook routes (no auth, raw body for Stripe)
14
- * addBillingWebhookRoutes(app, { config, basePath: '/api/billing/webhook' });
15
- * ```
16
- */
17
- import { BillingService } from './BillingService.js';
18
- import { RFC7807ErrorResponse } from '../rfc7807ErrorResponse.js';
19
- import { createLogger } from '../../utils/logger.js';
20
- const logger = createLogger('billing:routes');
21
- const DEFAULT_MOLLIE_IPS = [
22
- '87.233.217.240', '87.233.217.241', '87.233.217.242', '87.233.217.243',
23
- '87.233.217.244', '87.233.217.245', '87.233.217.246', '87.233.217.247',
24
- ];
25
- /**
26
- * Add authenticated billing routes to a router.
27
- *
28
- * Adds:
29
- * - POST /checkout — Stripe checkout
30
- * - POST /checkout/mollie — Mollie/iDEAL checkout
31
- * - POST /portal — Stripe customer portal
32
- * - GET /status — Billing status
33
- * - GET /invoices — Stripe invoices
34
- */
35
- export function addBillingRoutes(router, options) {
36
- const service = new BillingService(options.config);
37
- // POST /checkout — Stripe
38
- router.post('/checkout', async (req, res) => {
39
- try {
40
- const orgId = options.getOrgId(req);
41
- if (!orgId) {
42
- RFC7807ErrorResponse.badRequest(res, 'No active organization.');
43
- return;
44
- }
45
- const { plan, cycle = 'monthly' } = req.body;
46
- if (!plan || !service.getPlan(plan)) {
47
- RFC7807ErrorResponse.badRequest(res, 'Invalid plan.');
48
- return;
49
- }
50
- const result = await service.createStripeCheckout(orgId, plan, cycle);
51
- res.json({ success: true, data: result });
52
- }
53
- catch (err) {
54
- logger.error({ error: err }, 'Stripe checkout error');
55
- RFC7807ErrorResponse.internalError(res, err.message || 'Checkout failed.');
56
- }
57
- });
58
- // POST /checkout/mollie — iDEAL
59
- router.post('/checkout/mollie', async (req, res) => {
60
- try {
61
- const orgId = options.getOrgId(req);
62
- if (!orgId) {
63
- RFC7807ErrorResponse.badRequest(res, 'No active organization.');
64
- return;
65
- }
66
- const { plan, cycle = 'monthly' } = req.body;
67
- if (!plan || !service.getPlan(plan)) {
68
- RFC7807ErrorResponse.badRequest(res, 'Invalid plan.');
69
- return;
70
- }
71
- const result = await service.createMollieCheckout(orgId, plan, cycle);
72
- res.json({ success: true, data: result });
73
- }
74
- catch (err) {
75
- logger.error({ error: err }, 'Mollie checkout error');
76
- RFC7807ErrorResponse.internalError(res, err.message || 'Checkout failed.');
77
- }
78
- });
79
- // POST /portal — Stripe Customer Portal
80
- router.post('/portal', async (req, res) => {
81
- try {
82
- const orgId = options.getOrgId(req);
83
- if (!orgId) {
84
- RFC7807ErrorResponse.badRequest(res, 'No active organization.');
85
- return;
86
- }
87
- const result = await service.createStripePortal(orgId);
88
- res.json({ success: true, data: result });
89
- }
90
- catch (err) {
91
- logger.error({ error: err }, 'Portal error');
92
- RFC7807ErrorResponse.internalError(res, err.message || 'Portal failed.');
93
- }
94
- });
95
- // GET /status — Billing status
96
- router.get('/status', async (req, res) => {
97
- try {
98
- const orgId = options.getOrgId(req);
99
- if (!orgId) {
100
- RFC7807ErrorResponse.badRequest(res, 'No active organization.');
101
- return;
102
- }
103
- const status = await options.getBillingStatus(orgId);
104
- res.json({ success: true, data: status });
105
- }
106
- catch (err) {
107
- logger.error({ error: err }, 'Status error');
108
- RFC7807ErrorResponse.internalError(res, err.message || 'Status failed.');
109
- }
110
- });
111
- // GET /invoices — Stripe invoices
112
- router.get('/invoices', async (req, res) => {
113
- try {
114
- const orgId = options.getOrgId(req);
115
- if (!orgId) {
116
- RFC7807ErrorResponse.badRequest(res, 'No active organization.');
117
- return;
118
- }
119
- const invoices = await service.getInvoices(orgId);
120
- res.json({ success: true, data: { invoices } });
121
- }
122
- catch (err) {
123
- logger.error({ error: err }, 'Invoices error');
124
- RFC7807ErrorResponse.internalError(res, err.message || 'Invoices failed.');
125
- }
126
- });
127
- return service;
128
- }
129
- /**
130
- * Add webhook routes for Stripe and Mollie.
131
- *
132
- * IMPORTANT: Stripe needs raw body. Configure express.raw() for the Stripe webhook path
133
- * BEFORE mounting these routes.
134
- *
135
- * Adds:
136
- * - POST {basePath}/stripe — Stripe webhook (signature verified)
137
- * - POST {basePath}/mollie — Mollie webhook (IP whitelist in production)
138
- */
139
- export function addBillingWebhookRoutes(router, options) {
140
- const service = new BillingService(options.config);
141
- const basePath = options.basePath || '/webhook';
142
- const mollieIPs = options.config.mollieWebhookIPs || DEFAULT_MOLLIE_IPS;
143
- // POST /webhook/stripe
144
- router.post(`${basePath}/stripe`, async (req, res) => {
145
- try {
146
- const sig = req.headers['stripe-signature'];
147
- if (!sig) {
148
- RFC7807ErrorResponse.badRequest(res, 'Missing signature.');
149
- return;
150
- }
151
- // Return 200 immediately, process async
152
- res.json({ success: true, data: { received: true } });
153
- await service.handleStripeWebhook(req.body, sig);
154
- }
155
- catch (err) {
156
- logger.error({ error: err }, 'Stripe webhook error');
157
- if (!res.headersSent) {
158
- RFC7807ErrorResponse.badRequest(res, err.message || 'Webhook failed.');
159
- }
160
- }
161
- });
162
- // POST /webhook/mollie
163
- router.post(`${basePath}/mollie`, async (req, res) => {
164
- // IP whitelist (production only)
165
- if (process.env.NODE_ENV === 'production') {
166
- const clientIp = req.headers['x-forwarded-for']?.split(',')[0]?.trim() || req.ip;
167
- if (!mollieIPs.includes(clientIp || '')) {
168
- logger.warn({ clientIp }, 'Mollie webhook from unauthorized IP');
169
- RFC7807ErrorResponse.forbidden(res, 'Not authorized.');
170
- return;
171
- }
172
- }
173
- // Return 200 immediately (Mollie requirement)
174
- res.status(200).send('OK');
175
- try {
176
- await service.handleMollieWebhook(req.body?.id);
177
- }
178
- catch (err) {
179
- logger.error({ error: err }, 'Mollie webhook error');
180
- }
181
- });
182
- return service;
183
- }
184
- //# sourceMappingURL=routes.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../src/shared/billing/routes.ts"],"names":[],"mappings":"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"}
@@ -1,53 +0,0 @@
1
- /**
2
- * Seat-based pricing calculator
3
- *
4
- * Shared logic for per-user pricing with volume discounts and tier minimums.
5
- * Used by: website pricing calculator, SeatBillingService, license validation.
6
- *
7
- * @module @soulbatical/tetra-core/billing
8
- */
9
- export interface SeatTier {
10
- /** Minimum users for this tier (inclusive) */
11
- min: number;
12
- /** Maximum users for this tier (inclusive, Infinity for last tier) */
13
- max: number;
14
- /** Price per user per month in EUR */
15
- pricePerUser: number;
16
- /** Minimum monthly charge for this tier (prevents price dips at tier boundary) */
17
- minimum: number;
18
- }
19
- /** Default Tetra seat pricing tiers */
20
- export declare const DEFAULT_SEAT_TIERS: SeatTier[];
21
- export interface SeatPriceResult {
22
- /** Total monthly price in EUR */
23
- monthlyPrice: number;
24
- /** Total yearly price in EUR */
25
- yearlyPrice: number;
26
- /** Number of free users */
27
- freeUsers: number;
28
- /** Number of paid users */
29
- paidUsers: number;
30
- /** Effective price per user (total / users) */
31
- effectivePricePerUser: number;
32
- /** Which tier the user count falls in */
33
- tierIndex: number;
34
- /** The tier's listed price per user */
35
- tierPricePerUser: number;
36
- /** Whether the minimum was applied */
37
- minimumApplied: boolean;
38
- }
39
- /**
40
- * Calculate the monthly price for a given number of seat users.
41
- *
42
- * Rules:
43
- * - First 10 users are free
44
- * - Price per user decreases with volume
45
- * - Each tier has a minimum monthly charge (prevents price dips at boundary)
46
- * - For 1000+ users, the last tier rate applies
47
- */
48
- export declare function calculateSeatPrice(users: number, tiers?: SeatTier[]): SeatPriceResult;
49
- /**
50
- * Convert seat price to Stripe-compatible amount in cents.
51
- */
52
- export declare function seatPriceToCents(monthlyPrice: number): number;
53
- //# sourceMappingURL=seat-pricing.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"seat-pricing.d.ts","sourceRoot":"","sources":["../../../src/shared/billing/seat-pricing.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,QAAQ;IACvB,8CAA8C;IAC9C,GAAG,EAAE,MAAM,CAAC;IACZ,sEAAsE;IACtE,GAAG,EAAE,MAAM,CAAC;IACZ,sCAAsC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,kFAAkF;IAClF,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,uCAAuC;AACvC,eAAO,MAAM,kBAAkB,EAAE,QAAQ,EAMxC,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,iCAAiC;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,gCAAgC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,2BAA2B;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,2BAA2B;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,qBAAqB,EAAE,MAAM,CAAC;IAC9B,yCAAyC;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,gBAAgB,EAAE,MAAM,CAAC;IACzB,sCAAsC;IACtC,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,QAAQ,EAAuB,GACrC,eAAe,CAuDjB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAE7D"}
@@ -1,81 +0,0 @@
1
- /**
2
- * Seat-based pricing calculator
3
- *
4
- * Shared logic for per-user pricing with volume discounts and tier minimums.
5
- * Used by: website pricing calculator, SeatBillingService, license validation.
6
- *
7
- * @module @soulbatical/tetra-core/billing
8
- */
9
- /** Default Tetra seat pricing tiers */
10
- export const DEFAULT_SEAT_TIERS = [
11
- { min: 1, max: 10, pricePerUser: 0, minimum: 0 },
12
- { min: 11, max: 100, pricePerUser: 3.90, minimum: 0 },
13
- { min: 101, max: 250, pricePerUser: 2.90, minimum: 351 },
14
- { min: 251, max: 500, pricePerUser: 1.90, minimum: 725 },
15
- { min: 501, max: 1000, pricePerUser: 0.90, minimum: 950 },
16
- ];
17
- /**
18
- * Calculate the monthly price for a given number of seat users.
19
- *
20
- * Rules:
21
- * - First 10 users are free
22
- * - Price per user decreases with volume
23
- * - Each tier has a minimum monthly charge (prevents price dips at boundary)
24
- * - For 1000+ users, the last tier rate applies
25
- */
26
- export function calculateSeatPrice(users, tiers = DEFAULT_SEAT_TIERS) {
27
- if (users <= 0) {
28
- return {
29
- monthlyPrice: 0,
30
- yearlyPrice: 0,
31
- freeUsers: 0,
32
- paidUsers: 0,
33
- effectivePricePerUser: 0,
34
- tierIndex: 0,
35
- tierPricePerUser: 0,
36
- minimumApplied: false,
37
- };
38
- }
39
- // Find the tier
40
- let tierIndex = 0;
41
- let tierPricePerUser = 0;
42
- for (let i = 0; i < tiers.length; i++) {
43
- if (users >= tiers[i].min && users <= tiers[i].max) {
44
- tierIndex = i;
45
- tierPricePerUser = tiers[i].pricePerUser;
46
- break;
47
- }
48
- }
49
- // Beyond last tier: use last tier's rate
50
- if (users > tiers[tiers.length - 1].max) {
51
- const lastTier = tiers[tiers.length - 1];
52
- tierIndex = tiers.length - 1;
53
- tierPricePerUser = lastTier.pricePerUser;
54
- }
55
- const tier = tiers[tierIndex];
56
- const freeUsers = Math.min(users, tiers[0].max);
57
- const paidUsers = Math.max(0, users - tiers[0].max);
58
- // Calculate raw price
59
- const rawPrice = users * tierPricePerUser;
60
- // Apply minimum
61
- const minimum = tier?.minimum ?? 0;
62
- const minimumApplied = rawPrice < minimum && minimum > 0;
63
- const monthlyPrice = Math.max(rawPrice, minimum);
64
- return {
65
- monthlyPrice: Math.round(monthlyPrice * 100) / 100,
66
- yearlyPrice: Math.round(monthlyPrice * 12 * 100) / 100,
67
- freeUsers,
68
- paidUsers,
69
- effectivePricePerUser: users > 0 ? Math.round((monthlyPrice / users) * 100) / 100 : 0,
70
- tierIndex,
71
- tierPricePerUser,
72
- minimumApplied,
73
- };
74
- }
75
- /**
76
- * Convert seat price to Stripe-compatible amount in cents.
77
- */
78
- export function seatPriceToCents(monthlyPrice) {
79
- return Math.round(monthlyPrice * 100);
80
- }
81
- //# sourceMappingURL=seat-pricing.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"seat-pricing.js","sourceRoot":"","sources":["../../../src/shared/billing/seat-pricing.ts"],"names":[],"mappings":"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"}
@@ -1,109 +0,0 @@
1
- /**
2
- * Billing types — shared across all Tetra projects
3
- *
4
- * Projects provide their own plan configs via BillingConfig.
5
- * The billing module handles Stripe + Mollie checkout, webhooks, and subscription lifecycle.
6
- */
7
- import type { SupabaseClient } from '@supabase/supabase-js';
8
- export interface PlanConfig {
9
- /** Display name */
10
- name: string;
11
- /** Monthly price in EUR cents (1900 = €19.00) */
12
- priceMonthCents: number;
13
- /** Yearly price in EUR cents (19000 = €190.00) */
14
- priceYearCents: number;
15
- /** Stripe price ID for monthly billing */
16
- stripePriceMonthly: string;
17
- /** Stripe price ID for yearly billing */
18
- stripePriceYearly: string;
19
- /** Mollie amount string for monthly (e.g. "19.00") */
20
- mollieAmountMonthly: string;
21
- /** Mollie amount string for yearly (e.g. "190.00") */
22
- mollieAmountYearly: string;
23
- }
24
- export type BillingCycle = 'monthly' | 'yearly';
25
- export type SubscriptionStatus = 'trialing' | 'active' | 'past_due' | 'canceled' | 'unpaid';
26
- export type BillingProvider = 'stripe' | 'mollie';
27
- export interface BillingConfig {
28
- /** Plan definitions keyed by plan slug (e.g. { starter: {...}, pro: {...} }) */
29
- plans: Record<string, PlanConfig>;
30
- /** Stripe configuration */
31
- stripe: {
32
- secretKey: string;
33
- webhookSecret: string;
34
- };
35
- /** Mollie configuration */
36
- mollie: {
37
- apiKey: string;
38
- webhookBaseUrl: string;
39
- };
40
- /** Frontend URL for redirect after checkout */
41
- frontendUrl: string;
42
- /** Number of trial days for Stripe subscriptions (0 = no trial) */
43
- trialDays: number;
44
- /** Success redirect path (appended to frontendUrl) */
45
- successPath: string;
46
- /** Cancel redirect path (appended to frontendUrl) */
47
- cancelPath: string;
48
- /** Metadata key prefix for org ID in Stripe/Mollie metadata (default: "org_id") */
49
- orgIdMetadataKey?: string;
50
- /** Product name for Mollie payment descriptions (e.g. "VinciFox", "Agentrook") */
51
- productName: string;
52
- /** Function to get a system-level DB client (bypasses RLS) */
53
- getSystemDB: () => SupabaseClient;
54
- /** Function to get a webhook-level DB client (bypasses RLS, for webhook handlers) */
55
- getWebhookDB: (context: string) => SupabaseClient;
56
- /** Optional: callback after successful subscription creation */
57
- onSubscriptionCreated?: (orgId: string, plan: string, provider: BillingProvider) => Promise<void>;
58
- /** Optional: callback after subscription canceled */
59
- onSubscriptionCanceled?: (orgId: string) => Promise<void>;
60
- /** Optional: callback after payment failed */
61
- onPaymentFailed?: (orgId: string) => Promise<void>;
62
- /** Mollie webhook IP whitelist (production only). Defaults to standard Mollie IPs. */
63
- mollieWebhookIPs?: string[];
64
- }
65
- export interface SubscriptionRecord {
66
- id: string;
67
- organization_id: string;
68
- provider: BillingProvider;
69
- external_subscription_id: string | null;
70
- external_customer_id: string | null;
71
- plan: string;
72
- billing_cycle: BillingCycle;
73
- price_amount_cents: number;
74
- status: SubscriptionStatus;
75
- trial_end: string | null;
76
- current_period_start: string;
77
- current_period_end: string;
78
- cancel_at: string | null;
79
- canceled_at: string | null;
80
- ended_at: string | null;
81
- created_at: string;
82
- updated_at: string;
83
- }
84
- export interface BillingStatusResponse {
85
- plan: string;
86
- limits: Record<string, unknown>;
87
- usage: Record<string, number>;
88
- subscription: {
89
- id: string;
90
- provider: BillingProvider;
91
- status: SubscriptionStatus;
92
- billing_cycle: BillingCycle;
93
- trial_end: string | null;
94
- current_period_start: string;
95
- current_period_end: string;
96
- cancel_at: string | null;
97
- canceled_at: string | null;
98
- } | null;
99
- has_stripe: boolean;
100
- }
101
- export interface BillingRouteOptions {
102
- /** The billing configuration */
103
- config: BillingConfig;
104
- /** Function to resolve orgId from authenticated request */
105
- getOrgId: (req: any) => string | undefined;
106
- /** Function to get billing status for an org (plan, limits, usage) */
107
- getBillingStatus: (orgId: string) => Promise<BillingStatusResponse>;
108
- }
109
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/shared/billing/types.ts"],"names":[],"mappings":"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"}
@@ -1,8 +0,0 @@
1
- /**
2
- * Billing types — shared across all Tetra projects
3
- *
4
- * Projects provide their own plan configs via BillingConfig.
5
- * The billing module handles Stripe + Mollie checkout, webhooks, and subscription lifecycle.
6
- */
7
- export {};
8
- //# sourceMappingURL=types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/shared/billing/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -1,64 +0,0 @@
1
- /**
2
- * EmailService — Core service for sending templated emails.
3
- *
4
- * Template lookup with language + org fallback, Handlebars rendering,
5
- * DB logging, and multi-transport delivery (Gmail, SMTP, Mailgun).
6
- *
7
- * @module @soulbatical/tetra-core/email
8
- */
9
- import type { SupabaseClient } from '@supabase/supabase-js';
10
- import type { EmailConfig, SendEmailOpts } from './types.js';
11
- export declare class EmailService {
12
- private supabase;
13
- private config;
14
- private templateCache;
15
- constructor(supabase: SupabaseClient, config: EmailConfig);
16
- /**
17
- * Send a templated email.
18
- *
19
- * Template lookup order:
20
- * 1. slug + language + organization_id (org-specific translation)
21
- * 2. slug + language + org IS NULL (system default in requested language)
22
- * 3. slug + 'en' + org IS NULL (English fallback)
23
- * 4. fallbackSubject / fallbackHtml from code
24
- */
25
- send(opts: SendEmailOpts): Promise<{
26
- success: boolean;
27
- logId?: string;
28
- }>;
29
- /**
30
- * Clear template cache. Call after template is updated via admin UI.
31
- */
32
- clearCache(slug?: string): void;
33
- /**
34
- * Resolve transport and send email.
35
- * Priority: explicit config.transport > auto-detect (gmail > smtp > mailgun).
36
- */
37
- private deliver;
38
- /**
39
- * Send via Gmail API using stored OAuth tokens.
40
- */
41
- private deliverViaGmail;
42
- private resolveTransport;
43
- /**
44
- * Template lookup with language + org fallback chain.
45
- * Results are cached for 5 minutes.
46
- */
47
- private loadTemplate;
48
- private getCached;
49
- private setCache;
50
- /**
51
- * Render a Handlebars template string with variables.
52
- * Rejects templates with triple-brace {{{…}}} syntax to prevent escaping bypass.
53
- */
54
- private render;
55
- /**
56
- * Create a pending email log entry.
57
- */
58
- private createLog;
59
- /**
60
- * Update an email log entry after send attempt.
61
- */
62
- private updateLog;
63
- }
64
- //# sourceMappingURL=EmailService.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"EmailService.d.ts","sourceRoot":"","sources":["../../../src/shared/email/EmailService.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAqD,MAAM,YAAY,CAAC;AAahH,qBAAa,YAAY;IAIrB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,MAAM;IAJhB,OAAO,CAAC,aAAa,CAAiC;gBAG5C,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,WAAW;IAG7B;;;;;;;;OAQG;IACG,IAAI,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAsD9E;;OAEG;IACH,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAa/B;;;OAGG;YACW,OAAO;IA6CrB;;OAEG;YACW,eAAe;IAmC7B,OAAO,CAAC,gBAAgB;IAOxB;;;OAGG;YACW,YAAY;IAqE1B,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,QAAQ;IAIhB;;;OAGG;IACH,OAAO,CAAC,MAAM;IAQd;;OAEG;YACW,SAAS;IA0CvB;;OAEG;YACW,SAAS;CAkBxB"}