@baruk/core 0.1.0 → 0.3.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 (429) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/dist/auth/password-reset.d.ts.map +1 -1
  3. package/dist/auth/password-reset.js +2 -4
  4. package/dist/auth/password-reset.js.map +1 -1
  5. package/dist/auth/password.d.ts +2 -18
  6. package/dist/auth/password.d.ts.map +1 -1
  7. package/dist/auth/password.js +12 -51
  8. package/dist/auth/password.js.map +1 -1
  9. package/dist/auth/service.d.ts +0 -12
  10. package/dist/auth/service.d.ts.map +1 -1
  11. package/dist/auth/service.js +3 -36
  12. package/dist/auth/service.js.map +1 -1
  13. package/dist/auth/session-token.d.ts +5 -2
  14. package/dist/auth/session-token.d.ts.map +1 -1
  15. package/dist/auth/session-token.js +7 -12
  16. package/dist/auth/session-token.js.map +1 -1
  17. package/dist/billing/dunning.d.ts +33 -0
  18. package/dist/billing/dunning.d.ts.map +1 -0
  19. package/dist/billing/dunning.js +49 -0
  20. package/dist/billing/dunning.js.map +1 -0
  21. package/dist/billing/provider/asaas.d.ts +15 -0
  22. package/dist/billing/provider/asaas.d.ts.map +1 -0
  23. package/dist/billing/provider/asaas.js +121 -0
  24. package/dist/billing/provider/asaas.js.map +1 -0
  25. package/dist/billing/provider/manual.d.ts +14 -0
  26. package/dist/billing/provider/manual.d.ts.map +1 -0
  27. package/dist/billing/provider/manual.js +24 -0
  28. package/dist/billing/provider/manual.js.map +1 -0
  29. package/dist/billing/provider/registry.d.ts +12 -0
  30. package/dist/billing/provider/registry.d.ts.map +1 -0
  31. package/dist/billing/provider/registry.js +22 -0
  32. package/dist/billing/provider/registry.js.map +1 -0
  33. package/dist/billing/provider/types.d.ts +76 -0
  34. package/dist/billing/provider/types.d.ts.map +1 -0
  35. package/dist/billing/provider/types.js +9 -0
  36. package/dist/billing/provider/types.js.map +1 -0
  37. package/dist/billing/receivable.d.ts +108 -0
  38. package/dist/billing/receivable.d.ts.map +1 -0
  39. package/dist/billing/receivable.js +2 -0
  40. package/dist/billing/receivable.js.map +1 -0
  41. package/dist/billing/repository.d.ts +97 -0
  42. package/dist/billing/repository.d.ts.map +1 -0
  43. package/dist/billing/repository.js +167 -0
  44. package/dist/billing/repository.js.map +1 -0
  45. package/dist/cjs/audit/audit.js +31 -0
  46. package/dist/cjs/audit/audit.js.map +1 -0
  47. package/dist/cjs/audit/repository.js +32 -0
  48. package/dist/cjs/audit/repository.js.map +1 -0
  49. package/dist/cjs/auth/password-reset.js +58 -0
  50. package/dist/cjs/auth/password-reset.js.map +1 -0
  51. package/dist/cjs/auth/password.js +32 -0
  52. package/dist/cjs/auth/password.js.map +1 -0
  53. package/dist/cjs/auth/service.js +191 -0
  54. package/dist/cjs/auth/service.js.map +1 -0
  55. package/dist/cjs/auth/session-token.js +18 -0
  56. package/dist/cjs/auth/session-token.js.map +1 -0
  57. package/dist/cjs/billing/dunning.js +54 -0
  58. package/dist/cjs/billing/dunning.js.map +1 -0
  59. package/dist/cjs/billing/provider/asaas.js +125 -0
  60. package/dist/cjs/billing/provider/asaas.js.map +1 -0
  61. package/dist/cjs/billing/provider/manual.js +28 -0
  62. package/dist/cjs/billing/provider/manual.js.map +1 -0
  63. package/dist/cjs/billing/provider/registry.js +27 -0
  64. package/dist/cjs/billing/provider/registry.js.map +1 -0
  65. package/dist/cjs/billing/provider/types.js +10 -0
  66. package/dist/cjs/billing/provider/types.js.map +1 -0
  67. package/dist/cjs/billing/receivable.js +3 -0
  68. package/dist/cjs/billing/receivable.js.map +1 -0
  69. package/dist/cjs/billing/repository.js +180 -0
  70. package/dist/cjs/billing/repository.js.map +1 -0
  71. package/dist/cjs/clients/repository.js +123 -0
  72. package/dist/cjs/clients/repository.js.map +1 -0
  73. package/dist/cjs/commercial-catalog/catalog.js +108 -0
  74. package/dist/cjs/commercial-catalog/catalog.js.map +1 -0
  75. package/dist/cjs/commercial-catalog/consumption-contracts.js +10 -0
  76. package/dist/cjs/commercial-catalog/consumption-contracts.js.map +1 -0
  77. package/dist/cjs/commercial-catalog/coupon.js +63 -0
  78. package/dist/cjs/commercial-catalog/coupon.js.map +1 -0
  79. package/dist/cjs/commercial-catalog/index.js +16 -0
  80. package/dist/cjs/commercial-catalog/index.js.map +1 -0
  81. package/dist/cjs/commercial-catalog/offer-application.js +53 -0
  82. package/dist/cjs/commercial-catalog/offer-application.js.map +1 -0
  83. package/dist/cjs/commercial-catalog/types.js +26 -0
  84. package/dist/cjs/commercial-catalog/types.js.map +1 -0
  85. package/dist/cjs/crm/repository.js +195 -0
  86. package/dist/cjs/crm/repository.js.map +1 -0
  87. package/dist/cjs/dashboard/repository.js +39 -0
  88. package/dist/cjs/dashboard/repository.js.map +1 -0
  89. package/dist/cjs/db/client.js +27 -0
  90. package/dist/cjs/db/client.js.map +1 -0
  91. package/dist/cjs/db/context.js +43 -0
  92. package/dist/cjs/db/context.js.map +1 -0
  93. package/dist/cjs/db/load-env.js +47 -0
  94. package/dist/cjs/db/load-env.js.map +1 -0
  95. package/dist/cjs/db/seed.js +69 -0
  96. package/dist/cjs/db/seed.js.map +1 -0
  97. package/dist/cjs/entitlements/decision.js +203 -0
  98. package/dist/cjs/entitlements/decision.js.map +1 -0
  99. package/dist/cjs/entitlements/derive.js +46 -0
  100. package/dist/cjs/entitlements/derive.js.map +1 -0
  101. package/dist/cjs/entitlements/index.js +23 -0
  102. package/dist/cjs/entitlements/index.js.map +1 -0
  103. package/dist/cjs/entitlements/sources.js +60 -0
  104. package/dist/cjs/entitlements/sources.js.map +1 -0
  105. package/dist/cjs/entitlements/standing.js +42 -0
  106. package/dist/cjs/entitlements/standing.js.map +1 -0
  107. package/dist/cjs/entitlements/types.js +16 -0
  108. package/dist/cjs/entitlements/types.js.map +1 -0
  109. package/dist/cjs/import/clients-import.js +147 -0
  110. package/dist/cjs/import/clients-import.js.map +1 -0
  111. package/dist/cjs/index.js +335 -0
  112. package/dist/cjs/index.js.map +1 -0
  113. package/dist/cjs/mail/dedup-store.js +56 -0
  114. package/dist/cjs/mail/dedup-store.js.map +1 -0
  115. package/dist/cjs/mail/index.js +24 -0
  116. package/dist/cjs/mail/index.js.map +1 -0
  117. package/dist/cjs/mail/provider.js +251 -0
  118. package/dist/cjs/mail/provider.js.map +1 -0
  119. package/dist/cjs/mail/resend-client.js +103 -0
  120. package/dist/cjs/mail/resend-client.js.map +1 -0
  121. package/dist/cjs/mail/resend.js +21 -0
  122. package/dist/cjs/mail/resend.js.map +1 -0
  123. package/dist/cjs/mail/sanitize.js +56 -0
  124. package/dist/cjs/mail/sanitize.js.map +1 -0
  125. package/dist/cjs/mail/sender-resolver.js +15 -0
  126. package/dist/cjs/mail/sender-resolver.js.map +1 -0
  127. package/dist/cjs/mail/template-renderer.js +21 -0
  128. package/dist/cjs/mail/template-renderer.js.map +1 -0
  129. package/dist/cjs/mail/types.js +38 -0
  130. package/dist/cjs/mail/types.js.map +1 -0
  131. package/dist/cjs/notifications/repository.js +49 -0
  132. package/dist/cjs/notifications/repository.js.map +1 -0
  133. package/dist/cjs/onboarding/domain.js +370 -0
  134. package/dist/cjs/onboarding/domain.js.map +1 -0
  135. package/dist/cjs/onboarding/interaction-review.js +425 -0
  136. package/dist/cjs/onboarding/interaction-review.js.map +1 -0
  137. package/dist/cjs/onboarding/persistence.js +444 -0
  138. package/dist/cjs/onboarding/persistence.js.map +1 -0
  139. package/dist/cjs/onboarding/portal-actions.js +157 -0
  140. package/dist/cjs/onboarding/portal-actions.js.map +1 -0
  141. package/dist/cjs/onboarding/portal.js +177 -0
  142. package/dist/cjs/onboarding/portal.js.map +1 -0
  143. package/dist/cjs/package.json +3 -0
  144. package/dist/cjs/portal/repository.js +37 -0
  145. package/dist/cjs/portal/repository.js.map +1 -0
  146. package/dist/cjs/pricing-engine/bundle.js +49 -0
  147. package/dist/cjs/pricing-engine/bundle.js.map +1 -0
  148. package/dist/cjs/pricing-engine/errors.js +48 -0
  149. package/dist/cjs/pricing-engine/errors.js.map +1 -0
  150. package/dist/cjs/pricing-engine/index.js +30 -0
  151. package/dist/cjs/pricing-engine/index.js.map +1 -0
  152. package/dist/cjs/pricing-engine/money.js +69 -0
  153. package/dist/cjs/pricing-engine/money.js.map +1 -0
  154. package/dist/cjs/pricing-engine/pipeline.js +330 -0
  155. package/dist/cjs/pricing-engine/pipeline.js.map +1 -0
  156. package/dist/cjs/pricing-engine/proration.js +53 -0
  157. package/dist/cjs/pricing-engine/proration.js.map +1 -0
  158. package/dist/cjs/pricing-engine/shadow.js +58 -0
  159. package/dist/cjs/pricing-engine/shadow.js.map +1 -0
  160. package/dist/cjs/pricing-engine/types.js +34 -0
  161. package/dist/cjs/pricing-engine/types.js.map +1 -0
  162. package/dist/cjs/products/catalog.js +10 -0
  163. package/dist/cjs/products/catalog.js.map +1 -0
  164. package/dist/cjs/products/repository.js +61 -0
  165. package/dist/cjs/products/repository.js.map +1 -0
  166. package/dist/cjs/rbac/authorize.js +36 -0
  167. package/dist/cjs/rbac/authorize.js.map +1 -0
  168. package/dist/cjs/rbac/catalog.js +455 -0
  169. package/dist/cjs/rbac/catalog.js.map +1 -0
  170. package/dist/cjs/requests/repository.js +114 -0
  171. package/dist/cjs/requests/repository.js.map +1 -0
  172. package/dist/cjs/subscription-billing/dunning.js +26 -0
  173. package/dist/cjs/subscription-billing/dunning.js.map +1 -0
  174. package/dist/cjs/subscription-billing/events.js +45 -0
  175. package/dist/cjs/subscription-billing/events.js.map +1 -0
  176. package/dist/cjs/subscription-billing/index.js +62 -0
  177. package/dist/cjs/subscription-billing/index.js.map +1 -0
  178. package/dist/cjs/subscription-billing/plans.js +88 -0
  179. package/dist/cjs/subscription-billing/plans.js.map +1 -0
  180. package/dist/cjs/subscription-billing/product-config.js +54 -0
  181. package/dist/cjs/subscription-billing/product-config.js.map +1 -0
  182. package/dist/cjs/subscription-billing/provider/asaas.js +233 -0
  183. package/dist/cjs/subscription-billing/provider/asaas.js.map +1 -0
  184. package/dist/cjs/subscription-billing/provider/disabled.js +46 -0
  185. package/dist/cjs/subscription-billing/provider/disabled.js.map +1 -0
  186. package/dist/cjs/subscription-billing/provider/registry.js +29 -0
  187. package/dist/cjs/subscription-billing/provider/registry.js.map +1 -0
  188. package/dist/cjs/subscription-billing/reconcile.js +198 -0
  189. package/dist/cjs/subscription-billing/reconcile.js.map +1 -0
  190. package/dist/cjs/subscription-billing/repository.js +359 -0
  191. package/dist/cjs/subscription-billing/repository.js.map +1 -0
  192. package/dist/cjs/subscription-billing/service.js +838 -0
  193. package/dist/cjs/subscription-billing/service.js.map +1 -0
  194. package/dist/cjs/subscription-billing/types.js +28 -0
  195. package/dist/cjs/subscription-billing/types.js.map +1 -0
  196. package/dist/cjs/tenancy/provisioning.js +126 -0
  197. package/dist/cjs/tenancy/provisioning.js.map +1 -0
  198. package/dist/cjs/users/repository.js +83 -0
  199. package/dist/cjs/users/repository.js.map +1 -0
  200. package/dist/cjs/vault/crypto.js +94 -0
  201. package/dist/cjs/vault/crypto.js.map +1 -0
  202. package/dist/cjs/vault/repository.js +120 -0
  203. package/dist/cjs/vault/repository.js.map +1 -0
  204. package/dist/commercial-catalog/catalog.d.ts +27 -0
  205. package/dist/commercial-catalog/catalog.d.ts.map +1 -0
  206. package/dist/commercial-catalog/catalog.js +104 -0
  207. package/dist/commercial-catalog/catalog.js.map +1 -0
  208. package/dist/commercial-catalog/consumption-contracts.d.ts +33 -0
  209. package/dist/commercial-catalog/consumption-contracts.d.ts.map +1 -0
  210. package/dist/commercial-catalog/consumption-contracts.js +9 -0
  211. package/dist/commercial-catalog/consumption-contracts.js.map +1 -0
  212. package/dist/commercial-catalog/coupon.d.ts +43 -0
  213. package/dist/commercial-catalog/coupon.d.ts.map +1 -0
  214. package/dist/commercial-catalog/coupon.js +57 -0
  215. package/dist/commercial-catalog/coupon.js.map +1 -0
  216. package/dist/commercial-catalog/index.d.ts +10 -0
  217. package/dist/commercial-catalog/index.d.ts.map +1 -0
  218. package/dist/commercial-catalog/index.js +5 -0
  219. package/dist/commercial-catalog/index.js.map +1 -0
  220. package/dist/commercial-catalog/offer-application.d.ts +39 -0
  221. package/dist/commercial-catalog/offer-application.d.ts.map +1 -0
  222. package/dist/commercial-catalog/offer-application.js +50 -0
  223. package/dist/commercial-catalog/offer-application.js.map +1 -0
  224. package/dist/commercial-catalog/types.d.ts +175 -0
  225. package/dist/commercial-catalog/types.d.ts.map +1 -0
  226. package/dist/commercial-catalog/types.js +23 -0
  227. package/dist/commercial-catalog/types.js.map +1 -0
  228. package/dist/crm/repository.d.ts +109 -0
  229. package/dist/crm/repository.d.ts.map +1 -0
  230. package/dist/crm/repository.js +181 -0
  231. package/dist/crm/repository.js.map +1 -0
  232. package/dist/db/context.d.ts +2 -0
  233. package/dist/db/context.d.ts.map +1 -1
  234. package/dist/db/context.js +3 -0
  235. package/dist/db/context.js.map +1 -1
  236. package/dist/db/migrate.js +7 -2
  237. package/dist/db/migrate.js.map +1 -1
  238. package/dist/db/seed.js +4 -1
  239. package/dist/db/seed.js.map +1 -1
  240. package/dist/entitlements/decision.d.ts +86 -0
  241. package/dist/entitlements/decision.d.ts.map +1 -0
  242. package/dist/entitlements/decision.js +196 -0
  243. package/dist/entitlements/decision.js.map +1 -0
  244. package/dist/entitlements/derive.d.ts +30 -0
  245. package/dist/entitlements/derive.d.ts.map +1 -0
  246. package/dist/entitlements/derive.js +42 -0
  247. package/dist/entitlements/derive.js.map +1 -0
  248. package/dist/entitlements/index.d.ts +10 -0
  249. package/dist/entitlements/index.d.ts.map +1 -0
  250. package/dist/entitlements/index.js +7 -0
  251. package/dist/entitlements/index.js.map +1 -0
  252. package/dist/entitlements/sources.d.ts +30 -0
  253. package/dist/entitlements/sources.d.ts.map +1 -0
  254. package/dist/entitlements/sources.js +55 -0
  255. package/dist/entitlements/sources.js.map +1 -0
  256. package/dist/entitlements/standing.d.ts +22 -0
  257. package/dist/entitlements/standing.d.ts.map +1 -0
  258. package/dist/entitlements/standing.js +38 -0
  259. package/dist/entitlements/standing.js.map +1 -0
  260. package/dist/entitlements/types.d.ts +26 -0
  261. package/dist/entitlements/types.d.ts.map +1 -0
  262. package/dist/entitlements/types.js +15 -0
  263. package/dist/entitlements/types.js.map +1 -0
  264. package/dist/index.d.ts +74 -3
  265. package/dist/index.d.ts.map +1 -1
  266. package/dist/index.js +51 -4
  267. package/dist/index.js.map +1 -1
  268. package/dist/mail/dedup-store.d.ts +25 -0
  269. package/dist/mail/dedup-store.d.ts.map +1 -0
  270. package/dist/mail/dedup-store.js +51 -0
  271. package/dist/mail/dedup-store.js.map +1 -0
  272. package/dist/mail/index.d.ts +10 -0
  273. package/dist/mail/index.d.ts.map +1 -0
  274. package/dist/mail/index.js +9 -0
  275. package/dist/mail/index.js.map +1 -0
  276. package/dist/mail/provider.d.ts +31 -0
  277. package/dist/mail/provider.d.ts.map +1 -0
  278. package/dist/mail/provider.js +248 -0
  279. package/dist/mail/provider.js.map +1 -0
  280. package/dist/mail/resend-client.d.ts +16 -0
  281. package/dist/mail/resend-client.d.ts.map +1 -0
  282. package/dist/mail/resend-client.js +100 -0
  283. package/dist/mail/resend-client.js.map +1 -0
  284. package/dist/mail/resend.d.ts.map +1 -1
  285. package/dist/mail/resend.js +2 -0
  286. package/dist/mail/resend.js.map +1 -1
  287. package/dist/mail/sanitize.d.ts +17 -0
  288. package/dist/mail/sanitize.d.ts.map +1 -0
  289. package/dist/mail/sanitize.js +51 -0
  290. package/dist/mail/sanitize.js.map +1 -0
  291. package/dist/mail/sender-resolver.d.ts +8 -0
  292. package/dist/mail/sender-resolver.d.ts.map +1 -0
  293. package/dist/mail/sender-resolver.js +11 -0
  294. package/dist/mail/sender-resolver.js.map +1 -0
  295. package/dist/mail/template-renderer.d.ts +10 -0
  296. package/dist/mail/template-renderer.d.ts.map +1 -0
  297. package/dist/mail/template-renderer.js +17 -0
  298. package/dist/mail/template-renderer.js.map +1 -0
  299. package/dist/mail/types.d.ts +143 -0
  300. package/dist/mail/types.d.ts.map +1 -0
  301. package/dist/mail/types.js +34 -0
  302. package/dist/mail/types.js.map +1 -0
  303. package/dist/onboarding/domain.d.ts +146 -0
  304. package/dist/onboarding/domain.d.ts.map +1 -0
  305. package/dist/onboarding/domain.js +348 -0
  306. package/dist/onboarding/domain.js.map +1 -0
  307. package/dist/onboarding/interaction-review.d.ts +123 -0
  308. package/dist/onboarding/interaction-review.d.ts.map +1 -0
  309. package/dist/onboarding/interaction-review.js +413 -0
  310. package/dist/onboarding/interaction-review.js.map +1 -0
  311. package/dist/onboarding/persistence.d.ts +106 -0
  312. package/dist/onboarding/persistence.d.ts.map +1 -0
  313. package/dist/onboarding/persistence.js +430 -0
  314. package/dist/onboarding/persistence.js.map +1 -0
  315. package/dist/onboarding/portal-actions.d.ts +48 -0
  316. package/dist/onboarding/portal-actions.d.ts.map +1 -0
  317. package/dist/onboarding/portal-actions.js +153 -0
  318. package/dist/onboarding/portal-actions.js.map +1 -0
  319. package/dist/onboarding/portal.d.ts +58 -0
  320. package/dist/onboarding/portal.d.ts.map +1 -0
  321. package/dist/onboarding/portal.js +170 -0
  322. package/dist/onboarding/portal.js.map +1 -0
  323. package/dist/pricing-engine/bundle.d.ts +22 -0
  324. package/dist/pricing-engine/bundle.d.ts.map +1 -0
  325. package/dist/pricing-engine/bundle.js +44 -0
  326. package/dist/pricing-engine/bundle.js.map +1 -0
  327. package/dist/pricing-engine/errors.d.ts +32 -0
  328. package/dist/pricing-engine/errors.d.ts.map +1 -0
  329. package/dist/pricing-engine/errors.js +44 -0
  330. package/dist/pricing-engine/errors.js.map +1 -0
  331. package/dist/pricing-engine/index.d.ts +12 -0
  332. package/dist/pricing-engine/index.d.ts.map +1 -0
  333. package/dist/pricing-engine/index.js +8 -0
  334. package/dist/pricing-engine/index.js.map +1 -0
  335. package/dist/pricing-engine/money.d.ts +32 -0
  336. package/dist/pricing-engine/money.d.ts.map +1 -0
  337. package/dist/pricing-engine/money.js +58 -0
  338. package/dist/pricing-engine/money.js.map +1 -0
  339. package/dist/pricing-engine/pipeline.d.ts +3 -0
  340. package/dist/pricing-engine/pipeline.d.ts.map +1 -0
  341. package/dist/pricing-engine/pipeline.js +327 -0
  342. package/dist/pricing-engine/pipeline.js.map +1 -0
  343. package/dist/pricing-engine/proration.d.ts +3 -0
  344. package/dist/pricing-engine/proration.d.ts.map +1 -0
  345. package/dist/pricing-engine/proration.js +50 -0
  346. package/dist/pricing-engine/proration.js.map +1 -0
  347. package/dist/pricing-engine/shadow.d.ts +51 -0
  348. package/dist/pricing-engine/shadow.d.ts.map +1 -0
  349. package/dist/pricing-engine/shadow.js +54 -0
  350. package/dist/pricing-engine/shadow.js.map +1 -0
  351. package/dist/pricing-engine/types.d.ts +184 -0
  352. package/dist/pricing-engine/types.d.ts.map +1 -0
  353. package/dist/pricing-engine/types.js +31 -0
  354. package/dist/pricing-engine/types.js.map +1 -0
  355. package/dist/rbac/authorize.d.ts +3 -6
  356. package/dist/rbac/authorize.d.ts.map +1 -1
  357. package/dist/rbac/authorize.js +4 -8
  358. package/dist/rbac/authorize.js.map +1 -1
  359. package/dist/rbac/catalog.d.ts.map +1 -1
  360. package/dist/rbac/catalog.js +414 -21
  361. package/dist/rbac/catalog.js.map +1 -1
  362. package/dist/subscription-billing/dunning.d.ts +18 -0
  363. package/dist/subscription-billing/dunning.d.ts.map +1 -0
  364. package/dist/subscription-billing/dunning.js +28 -0
  365. package/dist/subscription-billing/dunning.js.map +1 -0
  366. package/dist/subscription-billing/events.d.ts +58 -0
  367. package/dist/subscription-billing/events.d.ts.map +1 -0
  368. package/dist/subscription-billing/events.js +38 -0
  369. package/dist/subscription-billing/events.js.map +1 -0
  370. package/dist/subscription-billing/index.d.ts +18 -0
  371. package/dist/subscription-billing/index.d.ts.map +1 -0
  372. package/dist/subscription-billing/index.js +16 -0
  373. package/dist/subscription-billing/index.js.map +1 -0
  374. package/dist/subscription-billing/plans.d.ts +34 -0
  375. package/dist/subscription-billing/plans.d.ts.map +1 -0
  376. package/dist/subscription-billing/plans.js +85 -0
  377. package/dist/subscription-billing/plans.js.map +1 -0
  378. package/dist/subscription-billing/product-config.d.ts +61 -0
  379. package/dist/subscription-billing/product-config.d.ts.map +1 -0
  380. package/dist/subscription-billing/product-config.js +50 -0
  381. package/dist/subscription-billing/product-config.js.map +1 -0
  382. package/dist/subscription-billing/provider/asaas.d.ts +26 -0
  383. package/dist/subscription-billing/provider/asaas.d.ts.map +1 -0
  384. package/dist/subscription-billing/provider/asaas.js +229 -0
  385. package/dist/subscription-billing/provider/asaas.js.map +1 -0
  386. package/dist/subscription-billing/provider/disabled.d.ts +30 -0
  387. package/dist/subscription-billing/provider/disabled.d.ts.map +1 -0
  388. package/dist/subscription-billing/provider/disabled.js +42 -0
  389. package/dist/subscription-billing/provider/disabled.js.map +1 -0
  390. package/dist/subscription-billing/provider/registry.d.ts +10 -0
  391. package/dist/subscription-billing/provider/registry.d.ts.map +1 -0
  392. package/dist/subscription-billing/provider/registry.js +26 -0
  393. package/dist/subscription-billing/provider/registry.js.map +1 -0
  394. package/dist/subscription-billing/reconcile.d.ts +45 -0
  395. package/dist/subscription-billing/reconcile.d.ts.map +1 -0
  396. package/dist/subscription-billing/reconcile.js +192 -0
  397. package/dist/subscription-billing/reconcile.js.map +1 -0
  398. package/dist/subscription-billing/repository.d.ts +168 -0
  399. package/dist/subscription-billing/repository.d.ts.map +1 -0
  400. package/dist/subscription-billing/repository.js +336 -0
  401. package/dist/subscription-billing/repository.js.map +1 -0
  402. package/dist/subscription-billing/service.d.ts +175 -0
  403. package/dist/subscription-billing/service.d.ts.map +1 -0
  404. package/dist/subscription-billing/service.js +818 -0
  405. package/dist/subscription-billing/service.js.map +1 -0
  406. package/dist/subscription-billing/types.d.ts +161 -0
  407. package/dist/subscription-billing/types.d.ts.map +1 -0
  408. package/dist/subscription-billing/types.js +24 -0
  409. package/dist/subscription-billing/types.js.map +1 -0
  410. package/dist/vault/crypto.d.ts +22 -0
  411. package/dist/vault/crypto.d.ts.map +1 -0
  412. package/dist/vault/crypto.js +88 -0
  413. package/dist/vault/crypto.js.map +1 -0
  414. package/dist/vault/repository.d.ts +45 -0
  415. package/dist/vault/repository.d.ts.map +1 -0
  416. package/dist/vault/repository.js +111 -0
  417. package/dist/vault/repository.js.map +1 -0
  418. package/package.json +23 -13
  419. package/src/db/migrations/0012_vault.sql +51 -0
  420. package/src/db/migrations/0013_crm.sql +67 -0
  421. package/src/db/migrations/0014_billing.sql +146 -0
  422. package/src/db/migrations/0015_merchant_billing_ar.sql +201 -0
  423. package/src/db/migrations/0016_office_onboarding.sql +162 -0
  424. package/src/db/migrations/0017_office_onboarding_api.sql +21 -0
  425. package/src/db/migrations/0018_office_onboarding_portal_actions.sql +60 -0
  426. package/src/db/migrations/0019_office_onboarding_interaction_review.sql +134 -0
  427. package/src/db/migrations/0020_saas_billing.sql +157 -0
  428. package/src/db/migrations/0021_saas_billing_indexes.sql +23 -0
  429. package/src/db/migrations/0022_saas_billing_multi_product.sql +75 -0
@@ -0,0 +1,60 @@
1
+ -- 0018 — Interações públicas controladas do Portal no onboarding.
2
+ -- Não representa upload, validação documental ou workflow interno.
3
+
4
+ CREATE TABLE onboarding_portal_interaction (
5
+ id uuid PRIMARY KEY,
6
+ tenant_id uuid NOT NULL REFERENCES tenant(id),
7
+ onboarding_id uuid NOT NULL,
8
+ client_id uuid NOT NULL,
9
+ item_id uuid,
10
+ document_requirement_id uuid,
11
+ author_user_id uuid NOT NULL REFERENCES "user"(id),
12
+ kind text NOT NULL CHECK (kind IN ('response', 'comment', 'external_delivery_confirmation')),
13
+ status text NOT NULL CHECK (status IN ('submitted', 'under_review', 'needs_clarification', 'accepted', 'superseded')) DEFAULT 'submitted',
14
+ visibility text NOT NULL CHECK (visibility = 'public_to_client'),
15
+ body text,
16
+ external_channel text CHECK (external_channel IS NULL OR external_channel IN ('email', 'whatsapp', 'in_person', 'other')),
17
+ external_delivered_at date,
18
+ supersedes_id uuid REFERENCES onboarding_portal_interaction(id),
19
+ created_at timestamptz NOT NULL DEFAULT now(),
20
+ updated_at timestamptz NOT NULL DEFAULT now(),
21
+ CONSTRAINT onboarding_portal_interaction_onboarding_fk
22
+ FOREIGN KEY (tenant_id, onboarding_id)
23
+ REFERENCES onboarding_instance(tenant_id, id),
24
+ CONSTRAINT onboarding_portal_interaction_item_fk
25
+ FOREIGN KEY (tenant_id, item_id)
26
+ REFERENCES onboarding_item(tenant_id, id),
27
+ CONSTRAINT onboarding_portal_interaction_document_fk
28
+ FOREIGN KEY (tenant_id, document_requirement_id)
29
+ REFERENCES onboarding_document_requirement(tenant_id, id),
30
+ CONSTRAINT onboarding_portal_interaction_target_ck CHECK (
31
+ (kind = 'response' AND item_id IS NOT NULL AND document_requirement_id IS NULL AND body IS NOT NULL AND external_channel IS NULL AND external_delivered_at IS NULL)
32
+ OR (kind = 'comment' AND item_id IS NULL AND document_requirement_id IS NULL AND body IS NOT NULL AND external_channel IS NULL AND external_delivered_at IS NULL)
33
+ OR (kind = 'external_delivery_confirmation' AND item_id IS NULL AND document_requirement_id IS NOT NULL AND external_channel IS NOT NULL AND external_delivered_at IS NOT NULL)
34
+ )
35
+ );
36
+
37
+ CREATE INDEX onboarding_portal_interaction_scope_idx
38
+ ON onboarding_portal_interaction (tenant_id, client_id, onboarding_id, created_at);
39
+ CREATE INDEX onboarding_portal_interaction_item_idx
40
+ ON onboarding_portal_interaction (tenant_id, item_id, created_at);
41
+ CREATE INDEX onboarding_portal_interaction_document_idx
42
+ ON onboarding_portal_interaction (tenant_id, document_requirement_id, created_at);
43
+
44
+ ALTER TABLE onboarding_portal_interaction ENABLE ROW LEVEL SECURITY;
45
+ ALTER TABLE onboarding_portal_interaction FORCE ROW LEVEL SECURITY;
46
+ CREATE POLICY onboarding_portal_interaction_scope ON onboarding_portal_interaction
47
+ USING (
48
+ tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid
49
+ AND (
50
+ NULLIF(current_setting('app.current_client', true), '') IS NULL
51
+ OR client_id = NULLIF(current_setting('app.current_client', true), '')::uuid
52
+ )
53
+ )
54
+ WITH CHECK (
55
+ tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid
56
+ AND (
57
+ NULLIF(current_setting('app.current_client', true), '') IS NULL
58
+ OR client_id = NULLIF(current_setting('app.current_client', true), '')::uuid
59
+ )
60
+ );
@@ -0,0 +1,134 @@
1
+ -- 0019 — Revisão administrativa das interações públicas de onboarding.
2
+ -- Não altera workflow do onboarding, Storage, Billing ou Communication.
3
+
4
+ -- 0018 tinha PK simples; esta chave composta permite manter a mesma defesa de
5
+ -- tenant nas FKs das tabelas de revisão sem editar a migration histórica.
6
+ ALTER TABLE onboarding_portal_interaction
7
+ ADD CONSTRAINT onboarding_portal_interaction_tenant_id_uq UNIQUE (tenant_id, id);
8
+
9
+ CREATE TABLE onboarding_interaction_review (
10
+ interaction_id uuid PRIMARY KEY,
11
+ tenant_id uuid NOT NULL,
12
+ client_id uuid NOT NULL,
13
+ onboarding_id uuid NOT NULL,
14
+ status text NOT NULL DEFAULT 'pending_review'
15
+ CHECK (status IN ('pending_review', 'in_review', 'accepted', 'clarification_requested', 'resolved', 'dismissed')),
16
+ reviewer_id uuid REFERENCES "user"(id),
17
+ assigned_to uuid REFERENCES "user"(id),
18
+ priority text NOT NULL DEFAULT 'normal'
19
+ CHECK (priority IN ('low', 'normal', 'high', 'urgent')),
20
+ due_at timestamptz NOT NULL,
21
+ breached_at timestamptz,
22
+ reviewed_at timestamptz,
23
+ resolved_at timestamptz,
24
+ resolution_type text CHECK (resolution_type IS NULL OR resolution_type IN ('information_accepted', 'clarification_requested', 'duplicate', 'no_action_required', 'handled_manually', 'superseded')),
25
+ internal_summary text,
26
+ version int NOT NULL DEFAULT 1 CHECK (version > 0),
27
+ created_at timestamptz NOT NULL DEFAULT now(),
28
+ updated_at timestamptz NOT NULL DEFAULT now(),
29
+ CONSTRAINT onboarding_interaction_review_scope_fk
30
+ FOREIGN KEY (tenant_id, interaction_id) REFERENCES onboarding_portal_interaction(tenant_id, id) ON DELETE CASCADE,
31
+ CONSTRAINT onboarding_interaction_review_onboarding_fk
32
+ FOREIGN KEY (tenant_id, onboarding_id) REFERENCES onboarding_instance(tenant_id, id) ON DELETE CASCADE,
33
+ CONSTRAINT onboarding_interaction_review_client_fk
34
+ FOREIGN KEY (tenant_id, client_id) REFERENCES client(tenant_id, id),
35
+ CHECK (due_at >= created_at)
36
+ );
37
+
38
+ CREATE INDEX onboarding_interaction_review_queue_idx
39
+ ON onboarding_interaction_review (tenant_id, status, due_at, priority, created_at DESC);
40
+ CREATE INDEX onboarding_interaction_review_assignee_idx
41
+ ON onboarding_interaction_review (tenant_id, assigned_to, status, due_at);
42
+
43
+ CREATE TABLE onboarding_interaction_internal_note (
44
+ id uuid PRIMARY KEY,
45
+ tenant_id uuid NOT NULL,
46
+ client_id uuid NOT NULL,
47
+ onboarding_id uuid NOT NULL,
48
+ interaction_id uuid NOT NULL,
49
+ author_id uuid NOT NULL REFERENCES "user"(id),
50
+ body text NOT NULL CHECK (length(body) BETWEEN 1 AND 4000),
51
+ created_at timestamptz NOT NULL DEFAULT now(),
52
+ CONSTRAINT onboarding_interaction_note_scope_fk
53
+ FOREIGN KEY (tenant_id, interaction_id) REFERENCES onboarding_portal_interaction(tenant_id, id) ON DELETE CASCADE,
54
+ CONSTRAINT onboarding_interaction_note_onboarding_fk
55
+ FOREIGN KEY (tenant_id, onboarding_id) REFERENCES onboarding_instance(tenant_id, id) ON DELETE CASCADE,
56
+ CONSTRAINT onboarding_interaction_note_client_fk
57
+ FOREIGN KEY (tenant_id, client_id) REFERENCES client(tenant_id, id)
58
+ );
59
+
60
+ CREATE INDEX onboarding_interaction_note_idx
61
+ ON onboarding_interaction_internal_note (tenant_id, interaction_id, created_at);
62
+
63
+ CREATE TABLE onboarding_interaction_public_reply (
64
+ id uuid PRIMARY KEY,
65
+ tenant_id uuid NOT NULL,
66
+ client_id uuid NOT NULL,
67
+ onboarding_id uuid NOT NULL,
68
+ interaction_id uuid NOT NULL,
69
+ author_id uuid NOT NULL REFERENCES "user"(id),
70
+ body text NOT NULL CHECK (length(body) BETWEEN 1 AND 2000),
71
+ visibility text NOT NULL CHECK (visibility = 'public_to_client'),
72
+ created_at timestamptz NOT NULL DEFAULT now(),
73
+ CONSTRAINT onboarding_interaction_reply_scope_fk
74
+ FOREIGN KEY (tenant_id, interaction_id) REFERENCES onboarding_portal_interaction(tenant_id, id) ON DELETE CASCADE,
75
+ CONSTRAINT onboarding_interaction_reply_onboarding_fk
76
+ FOREIGN KEY (tenant_id, onboarding_id) REFERENCES onboarding_instance(tenant_id, id) ON DELETE CASCADE,
77
+ CONSTRAINT onboarding_interaction_reply_client_fk
78
+ FOREIGN KEY (tenant_id, client_id) REFERENCES client(tenant_id, id)
79
+ );
80
+
81
+ CREATE INDEX onboarding_interaction_reply_idx
82
+ ON onboarding_interaction_public_reply (tenant_id, onboarding_id, created_at);
83
+
84
+ -- Interações existentes entram na fila sem alterar o histórico público.
85
+ INSERT INTO onboarding_interaction_review (interaction_id, tenant_id, client_id, onboarding_id, due_at)
86
+ SELECT id, tenant_id, client_id, onboarding_id, created_at + interval '2 days'
87
+ FROM onboarding_portal_interaction
88
+ ON CONFLICT (interaction_id) DO NOTHING;
89
+
90
+ -- Novas interações públicas entram automaticamente na fila administrativa.
91
+ CREATE OR REPLACE FUNCTION create_onboarding_interaction_review()
92
+ RETURNS trigger LANGUAGE plpgsql SECURITY DEFINER SET search_path = public, pg_temp AS $$
93
+ BEGIN
94
+ INSERT INTO onboarding_interaction_review (interaction_id, tenant_id, client_id, onboarding_id, due_at)
95
+ VALUES (NEW.id, NEW.tenant_id, NEW.client_id, NEW.onboarding_id, NEW.created_at + interval '2 days')
96
+ ON CONFLICT (interaction_id) DO NOTHING;
97
+ RETURN NEW;
98
+ END;
99
+ $$;
100
+
101
+ CREATE TRIGGER onboarding_interaction_review_after_insert
102
+ AFTER INSERT ON onboarding_portal_interaction
103
+ FOR EACH ROW EXECUTE FUNCTION create_onboarding_interaction_review();
104
+
105
+ ALTER TABLE onboarding_interaction_review ENABLE ROW LEVEL SECURITY;
106
+ ALTER TABLE onboarding_interaction_review FORCE ROW LEVEL SECURITY;
107
+ ALTER TABLE onboarding_interaction_internal_note ENABLE ROW LEVEL SECURITY;
108
+ ALTER TABLE onboarding_interaction_internal_note FORCE ROW LEVEL SECURITY;
109
+ ALTER TABLE onboarding_interaction_public_reply ENABLE ROW LEVEL SECURITY;
110
+ ALTER TABLE onboarding_interaction_public_reply FORCE ROW LEVEL SECURITY;
111
+
112
+ CREATE POLICY onboarding_interaction_review_staff_scope ON onboarding_interaction_review
113
+ USING (
114
+ tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid
115
+ AND current_setting('app.current_surface', true) <> 'portal'
116
+ )
117
+ WITH CHECK (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid);
118
+
119
+ CREATE POLICY onboarding_interaction_note_staff_scope ON onboarding_interaction_internal_note
120
+ USING (
121
+ tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid
122
+ AND current_setting('app.current_surface', true) <> 'portal'
123
+ )
124
+ WITH CHECK (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid);
125
+
126
+ CREATE POLICY onboarding_interaction_reply_scope ON onboarding_interaction_public_reply
127
+ USING (
128
+ tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid
129
+ AND (
130
+ current_setting('app.current_surface', true) <> 'portal'
131
+ OR client_id = NULLIF(current_setting('app.current_client', true), '')::uuid
132
+ )
133
+ )
134
+ WITH CHECK (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid);
@@ -0,0 +1,157 @@
1
+ -- 0020 — Billing SaaS (Concern A): a Baruk cobra o TENANT pela assinatura da
2
+ -- plataforma. Persistência do domínio puro `subscription-billing/` (RFC-CAPABILITY-
3
+ -- BILLING-001 v0.1). NUNCA mistura com Merchant Billing (0014/0015, Concern B):
4
+ -- contratos de domínio separados por ADR-ECO-0007.
5
+
6
+ -- ── Catálogo de planos do SaaS (global, como `product`: read-only p/ app) ────
7
+ -- Preço vive no plano nesta v0.1 (pricingModel 'flat'); a CommercialPriceTable
8
+ -- versionada do commercial-catalog é evolução prevista, não regressão.
9
+ CREATE TABLE saas_plan (
10
+ id uuid PRIMARY KEY,
11
+ key text NOT NULL, -- starter | pro | enterprise
12
+ name text NOT NULL,
13
+ description text,
14
+ amount_cents integer NOT NULL CHECK (amount_cents >= 0),
15
+ currency text NOT NULL DEFAULT 'BRL',
16
+ periodicity text NOT NULL DEFAULT 'monthly'
17
+ CHECK (periodicity IN ('monthly', 'quarterly', 'yearly')),
18
+ trial_days integer NOT NULL DEFAULT 0 CHECK (trial_days >= 0),
19
+ -- Módulos inclusos (codes) e limites/franquias — consumidos pelos Entitlements
20
+ -- finos (EntitlementSource 'PLAN') e pela página comercial.
21
+ modules jsonb NOT NULL DEFAULT '[]'::jsonb,
22
+ limits jsonb NOT NULL DEFAULT '{}'::jsonb,
23
+ is_public boolean NOT NULL DEFAULT true, -- aparece na página de planos
24
+ is_active boolean NOT NULL DEFAULT true, -- contratável
25
+ sort_order integer NOT NULL DEFAULT 0,
26
+ created_at timestamptz NOT NULL DEFAULT now(),
27
+ updated_at timestamptz NOT NULL DEFAULT now()
28
+ );
29
+ CREATE UNIQUE INDEX saas_plan_key_uq ON saas_plan (key);
30
+
31
+ -- ── Assinatura do tenant (fonte de verdade interna; gateway é espelho) ───────
32
+ -- Cardinalidade v0.1: exatamente UMA assinatura por tenant (reconcile.ts usa
33
+ -- `sub_<tenantId>`); o UNIQUE em tenant_id materializa a invariante.
34
+ CREATE TABLE saas_subscription (
35
+ id uuid PRIMARY KEY,
36
+ tenant_id uuid NOT NULL REFERENCES tenant(id),
37
+ plan_key text NOT NULL REFERENCES saas_plan(key),
38
+ status text NOT NULL
39
+ CHECK (status IN ('trialing','active','past_due','canceled','paused')),
40
+ current_period_end date,
41
+ trial_ends_at date,
42
+ canceled_at timestamptz,
43
+ sequence integer NOT NULL DEFAULT 0,
44
+ provider text, -- gateway pedido (ex.: 'asaas')
45
+ provider_customer_id text,
46
+ provider_subscription_id text,
47
+ created_at timestamptz NOT NULL DEFAULT now(),
48
+ updated_at timestamptz NOT NULL DEFAULT now()
49
+ );
50
+ CREATE UNIQUE INDEX saas_subscription_tenant_uq ON saas_subscription (tenant_id);
51
+ CREATE INDEX saas_subscription_status_idx ON saas_subscription (status);
52
+
53
+ -- ── Faturas do SaaS (espelho normalizado das cobranças do gateway) ───────────
54
+ CREATE TABLE saas_invoice (
55
+ id uuid PRIMARY KEY,
56
+ tenant_id uuid NOT NULL REFERENCES tenant(id),
57
+ subscription_id uuid REFERENCES saas_subscription(id),
58
+ provider text NOT NULL,
59
+ external_id text NOT NULL,
60
+ status text NOT NULL
61
+ CHECK (status IN ('pending','confirmed','received','overdue','refunded','canceled','failed')),
62
+ amount_cents integer NOT NULL CHECK (amount_cents >= 0),
63
+ due_date date,
64
+ paid_at timestamptz,
65
+ invoice_url text,
66
+ description text,
67
+ created_at timestamptz NOT NULL DEFAULT now(),
68
+ updated_at timestamptz NOT NULL DEFAULT now()
69
+ );
70
+ -- Idempotência de espelho: 1 cobrança no gateway ↔ 1 fatura interna.
71
+ CREATE UNIQUE INDEX saas_invoice_external_uq ON saas_invoice (provider, external_id);
72
+ CREATE INDEX saas_invoice_tenant_idx ON saas_invoice (tenant_id);
73
+
74
+ -- ── Eventos de domínio (envelope events.ts; sequence monotônica por assinatura) ──
75
+ CREATE TABLE saas_billing_event (
76
+ id uuid PRIMARY KEY, -- eventId (idempotência do consumidor)
77
+ subscription_id uuid NOT NULL REFERENCES saas_subscription(id),
78
+ tenant_id uuid NOT NULL REFERENCES tenant(id),
79
+ type text NOT NULL,
80
+ sequence integer NOT NULL,
81
+ occurred_at timestamptz NOT NULL,
82
+ causation_event_id text,
83
+ data jsonb NOT NULL DEFAULT '{}'::jsonb,
84
+ created_at timestamptz NOT NULL DEFAULT now()
85
+ );
86
+ CREATE UNIQUE INDEX saas_billing_event_seq_uq ON saas_billing_event (subscription_id, sequence);
87
+ CREATE INDEX saas_billing_event_tenant_idx ON saas_billing_event (tenant_id);
88
+
89
+ -- ── Régua de inadimplência: passos já executados (stepKey idempotente) ───────
90
+ CREATE TABLE saas_dunning_event (
91
+ id uuid PRIMARY KEY,
92
+ tenant_id uuid NOT NULL REFERENCES tenant(id),
93
+ subscription_id uuid NOT NULL REFERENCES saas_subscription(id),
94
+ step_key text NOT NULL, -- ex.: 'D+7:email'
95
+ reference_date date NOT NULL, -- currentPeriodEnd do ciclo em atraso
96
+ executed_at timestamptz NOT NULL DEFAULT now()
97
+ );
98
+ CREATE UNIQUE INDEX saas_dunning_step_uq ON saas_dunning_event (subscription_id, reference_date, step_key);
99
+
100
+ -- ── Webhook inbound (CROSS-TENANT de propósito — mesmo padrão do 0015) ───────
101
+ -- Dedup por (provider, external_event_id) ANTES de resolver tenant; tenant_id é
102
+ -- preenchido depois. Sem RLS: escrita em contexto de sistema, pré-`current_tenant`.
103
+ CREATE TABLE saas_webhook_event (
104
+ id uuid PRIMARY KEY,
105
+ tenant_id uuid REFERENCES tenant(id),
106
+ provider text NOT NULL,
107
+ external_event_id text NOT NULL,
108
+ event_type text NOT NULL,
109
+ status text NOT NULL DEFAULT 'received'
110
+ CHECK (status IN ('received','processed','ignored','failed')),
111
+ payload jsonb,
112
+ error text,
113
+ processed_at timestamptz,
114
+ created_at timestamptz NOT NULL DEFAULT now()
115
+ );
116
+ CREATE UNIQUE INDEX saas_webhook_event_idempotency_uq ON saas_webhook_event (provider, external_event_id);
117
+ CREATE INDEX saas_webhook_event_tenant_idx ON saas_webhook_event (tenant_id) WHERE tenant_id IS NOT NULL;
118
+
119
+ -- ── RLS FORCE nas tabelas tenant-scoped ──────────────────────────────────────
120
+ -- Política dupla: (a) isolamento por tenant via GUC `app.current_tenant`;
121
+ -- (b) acesso de operadora (backoffice Baruk) via GUC `app.platform_operator`,
122
+ -- setada EXCLUSIVAMENTE pelas rotas de backoffice após verificação de operador.
123
+ ALTER TABLE saas_subscription ENABLE ROW LEVEL SECURITY;
124
+ ALTER TABLE saas_subscription FORCE ROW LEVEL SECURITY;
125
+ CREATE POLICY saas_subscription_tenant_isolation ON saas_subscription
126
+ USING (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid)
127
+ WITH CHECK (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid);
128
+ CREATE POLICY saas_subscription_operator ON saas_subscription
129
+ USING (current_setting('app.platform_operator', true) = 'true')
130
+ WITH CHECK (current_setting('app.platform_operator', true) = 'true');
131
+
132
+ ALTER TABLE saas_invoice ENABLE ROW LEVEL SECURITY;
133
+ ALTER TABLE saas_invoice FORCE ROW LEVEL SECURITY;
134
+ CREATE POLICY saas_invoice_tenant_isolation ON saas_invoice
135
+ USING (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid)
136
+ WITH CHECK (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid);
137
+ CREATE POLICY saas_invoice_operator ON saas_invoice
138
+ USING (current_setting('app.platform_operator', true) = 'true')
139
+ WITH CHECK (current_setting('app.platform_operator', true) = 'true');
140
+
141
+ ALTER TABLE saas_billing_event ENABLE ROW LEVEL SECURITY;
142
+ ALTER TABLE saas_billing_event FORCE ROW LEVEL SECURITY;
143
+ CREATE POLICY saas_billing_event_tenant_isolation ON saas_billing_event
144
+ USING (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid)
145
+ WITH CHECK (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid);
146
+ CREATE POLICY saas_billing_event_operator ON saas_billing_event
147
+ USING (current_setting('app.platform_operator', true) = 'true')
148
+ WITH CHECK (current_setting('app.platform_operator', true) = 'true');
149
+
150
+ ALTER TABLE saas_dunning_event ENABLE ROW LEVEL SECURITY;
151
+ ALTER TABLE saas_dunning_event FORCE ROW LEVEL SECURITY;
152
+ CREATE POLICY saas_dunning_event_tenant_isolation ON saas_dunning_event
153
+ USING (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid)
154
+ WITH CHECK (tenant_id = NULLIF(current_setting('app.current_tenant', true), '')::uuid);
155
+ CREATE POLICY saas_dunning_event_operator ON saas_dunning_event
156
+ USING (current_setting('app.platform_operator', true) = 'true')
157
+ WITH CHECK (current_setting('app.platform_operator', true) = 'true');
@@ -0,0 +1,23 @@
1
+ -- 0021 — Índices do Billing SaaS para as queries reais (achados da revisão
2
+ -- adversarial BILL-01): scan do cron (índices parciais por status), ordenações
3
+ -- do backoffice e FKs usadas em JOIN.
4
+
5
+ -- Cron: listSubscriptionsForCron usa OR de 3 predicados por status.
6
+ CREATE INDEX saas_subscription_trialing_idx
7
+ ON saas_subscription (trial_ends_at) WHERE status = 'trialing';
8
+ CREATE INDEX saas_subscription_active_period_idx
9
+ ON saas_subscription (current_period_end) WHERE status = 'active';
10
+ CREATE INDEX saas_subscription_past_due_idx
11
+ ON saas_subscription (updated_at) WHERE status = 'past_due';
12
+
13
+ -- Backoffice: ordenações por recência.
14
+ CREATE INDEX saas_subscription_updated_idx ON saas_subscription (updated_at DESC);
15
+ CREATE INDEX saas_webhook_event_created_idx ON saas_webhook_event (created_at DESC);
16
+ -- Reprocessamento de failed pelo cron.
17
+ CREATE INDEX saas_webhook_event_failed_idx
18
+ ON saas_webhook_event (created_at) WHERE status = 'failed';
19
+
20
+ -- FKs usadas em JOIN/queries.
21
+ CREATE INDEX saas_subscription_plan_key_idx ON saas_subscription (plan_key);
22
+ CREATE INDEX saas_invoice_subscription_idx ON saas_invoice (subscription_id);
23
+ CREATE INDEX saas_dunning_event_tenant_idx ON saas_dunning_event (tenant_id);
@@ -0,0 +1,75 @@
1
+ -- BILL-01 / Multi-produto — o motor de Billing é infraestrutura compartilhada do
2
+ -- ecossistema, mas cada PRODUTO (Baruk Contábil/Office, Rep, Ind, futuro Varejo,
3
+ -- Dental) tem catálogo de planos, módulos e superfície comercial próprios.
4
+ --
5
+ -- Antes desta migração o billing era single-product por construção:
6
+ -- · `saas_plan.key` era UNIQUE global → dois produtos não podiam ter "pro";
7
+ -- · `saas_subscription` era UNIQUE por tenant → um tenant não podia assinar
8
+ -- dois produtos, e um webhook de qualquer produto aterrissava na mesma linha.
9
+ --
10
+ -- O catálogo `product` (0010) já é a fonte de verdade de produtos e já tem N:N
11
+ -- com tenant (`tenant_product`). Esta migração conecta o billing a ele.
12
+ --
13
+ -- Compatibilidade: tudo que existe hoje é do Contábil, então o default
14
+ -- 'contabil' preserva os dados atuais sem backfill manual.
15
+
16
+ -- ── saas_plan: plano pertence a um produto ───────────────────────────────────
17
+ ALTER TABLE saas_plan
18
+ ADD COLUMN IF NOT EXISTS product_key TEXT NOT NULL DEFAULT 'contabil';
19
+
20
+ -- A chave do plano passa a ser única DENTRO do produto: 'pro' do Office e 'pro'
21
+ -- do Rep são planos distintos.
22
+ --
23
+ -- `saas_subscription.plan_key` referencia `saas_plan(key)` (0020:37), e essa FK
24
+ -- depende do índice único global. A ordem obrigatória é: soltar a FK → trocar o
25
+ -- índice → recriar a FK apontando para o novo par (product_key, key).
26
+ ALTER TABLE saas_subscription
27
+ DROP CONSTRAINT IF EXISTS saas_subscription_plan_key_fkey;
28
+
29
+ DROP INDEX IF EXISTS saas_plan_key_uq;
30
+ CREATE UNIQUE INDEX IF NOT EXISTS saas_plan_product_key_uq
31
+ ON saas_plan (product_key, key);
32
+
33
+ -- Integridade referencial contra o catálogo de produtos (0010).
34
+ ALTER TABLE saas_plan
35
+ DROP CONSTRAINT IF EXISTS saas_plan_product_fk;
36
+ ALTER TABLE saas_plan
37
+ ADD CONSTRAINT saas_plan_product_fk
38
+ FOREIGN KEY (product_key) REFERENCES product (key) ON UPDATE CASCADE;
39
+
40
+ -- ── saas_subscription: uma assinatura por (tenant, produto) ──────────────────
41
+ ALTER TABLE saas_subscription
42
+ ADD COLUMN IF NOT EXISTS product_key TEXT NOT NULL DEFAULT 'contabil';
43
+
44
+ DROP INDEX IF EXISTS saas_subscription_tenant_uq;
45
+ CREATE UNIQUE INDEX IF NOT EXISTS saas_subscription_tenant_product_uq
46
+ ON saas_subscription (tenant_id, product_key);
47
+
48
+ ALTER TABLE saas_subscription
49
+ DROP CONSTRAINT IF EXISTS saas_subscription_product_fk;
50
+ ALTER TABLE saas_subscription
51
+ ADD CONSTRAINT saas_subscription_product_fk
52
+ FOREIGN KEY (product_key) REFERENCES product (key) ON UPDATE CASCADE;
53
+
54
+ -- Recria a FK do plano no par completo: uma assinatura só pode apontar para um
55
+ -- plano DO SEU PRÓPRIO produto. É esta constraint que torna impossível, no
56
+ -- banco, um tenant do Office assinar um plano do Rep.
57
+ ALTER TABLE saas_subscription
58
+ DROP CONSTRAINT IF EXISTS saas_subscription_product_plan_fk;
59
+ ALTER TABLE saas_subscription
60
+ ADD CONSTRAINT saas_subscription_product_plan_fk
61
+ FOREIGN KEY (product_key, plan_key) REFERENCES saas_plan (product_key, key)
62
+ ON UPDATE CASCADE;
63
+
64
+ -- ── Rastros: produto explícito onde a atribuição do evento é decidida ────────
65
+ -- Fatura e evento de webhook carregam o produto para que a conciliação e o
66
+ -- backoffice nunca precisem inferi-lo a partir do tenant.
67
+ ALTER TABLE saas_invoice
68
+ ADD COLUMN IF NOT EXISTS product_key TEXT NOT NULL DEFAULT 'contabil';
69
+
70
+ ALTER TABLE saas_webhook_event
71
+ ADD COLUMN IF NOT EXISTS product_key TEXT;
72
+
73
+ CREATE INDEX IF NOT EXISTS saas_plan_product_idx ON saas_plan (product_key, sort_order);
74
+ CREATE INDEX IF NOT EXISTS saas_subscription_product_idx ON saas_subscription (product_key, status);
75
+ CREATE INDEX IF NOT EXISTS saas_invoice_product_idx ON saas_invoice (product_key, status);