@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,167 @@
1
+ import { NotFoundError, uuidv7 } from '@baruk/shared';
2
+ function mapFee(r) {
3
+ return {
4
+ id: r.id,
5
+ clientId: r.client_id,
6
+ description: r.description,
7
+ amount: Number(r.amount),
8
+ periodicity: r.periodicity,
9
+ dueDay: r.due_day,
10
+ billingMethod: r.billing_method,
11
+ discount: Number(r.discount),
12
+ finePercent: Number(r.fine_percent),
13
+ interestPercent: Number(r.interest_percent),
14
+ status: r.status,
15
+ startsOn: r.starts_on ? r.starts_on.toISOString().slice(0, 10) : null,
16
+ endsOn: r.ends_on ? r.ends_on.toISOString().slice(0, 10) : null,
17
+ createdAt: r.created_at.toISOString(),
18
+ };
19
+ }
20
+ const FEE_COLS = `
21
+ id, client_id, description, amount, periodicity, due_day, billing_method,
22
+ discount, fine_percent, interest_percent, status, starts_on, ends_on, created_at
23
+ `;
24
+ export async function createFeeAgreement(tx, input) {
25
+ const rows = await tx `
26
+ INSERT INTO fee_agreement (
27
+ id, tenant_id, client_id, description, amount, periodicity, due_day,
28
+ billing_method, discount, fine_percent, interest_percent, starts_on, created_by
29
+ ) VALUES (
30
+ ${uuidv7()}, current_setting('app.current_tenant')::uuid, ${input.clientId},
31
+ ${input.description ?? 'Honorários'}, ${input.amount}, ${input.periodicity ?? 'monthly'},
32
+ ${input.dueDay ?? null}, ${input.billingMethod ?? 'pix'}, ${input.discount ?? 0},
33
+ ${input.finePercent ?? 0}, ${input.interestPercent ?? 0}, ${input.startsOn ?? null}, ${input.createdBy ?? null}
34
+ )
35
+ RETURNING ${tx.unsafe(FEE_COLS)}
36
+ `;
37
+ return mapFee(rows[0]);
38
+ }
39
+ export async function listFeeAgreements(tx, clientId) {
40
+ const rows = await tx `
41
+ SELECT ${tx.unsafe(FEE_COLS)} FROM fee_agreement
42
+ WHERE deleted_at IS NULL
43
+ AND (${clientId ?? null}::uuid IS NULL OR client_id = ${clientId ?? null})
44
+ ORDER BY created_at DESC
45
+ `;
46
+ return rows.map(mapFee);
47
+ }
48
+ export async function setFeeStatus(tx, id, status) {
49
+ const rows = await tx `
50
+ UPDATE fee_agreement SET status = ${status}, updated_at = now(), version = version + 1
51
+ WHERE id = ${id} AND deleted_at IS NULL RETURNING id
52
+ `;
53
+ return rows.count;
54
+ }
55
+ function mapCharge(r) {
56
+ return {
57
+ id: r.id,
58
+ clientId: r.client_id,
59
+ feeAgreementId: r.fee_agreement_id,
60
+ provider: r.provider,
61
+ externalId: r.external_id,
62
+ method: r.method,
63
+ amount: Number(r.amount),
64
+ status: r.status,
65
+ description: r.description,
66
+ dueDate: r.due_date ? r.due_date.toISOString().slice(0, 10) : null,
67
+ paidAt: r.paid_at ? r.paid_at.toISOString() : null,
68
+ metadata: r.metadata ?? {},
69
+ createdAt: r.created_at.toISOString(),
70
+ };
71
+ }
72
+ const CHARGE_COLS = `
73
+ id, client_id, fee_agreement_id, provider, external_id, method, amount,
74
+ status, description, due_date, paid_at, metadata, created_at
75
+ `;
76
+ export async function createCharge(tx, input) {
77
+ const rows = await tx `
78
+ INSERT INTO charge (
79
+ id, tenant_id, client_id, fee_agreement_id, provider, external_id, method,
80
+ amount, status, description, due_date, metadata, created_by
81
+ ) VALUES (
82
+ ${uuidv7()}, current_setting('app.current_tenant')::uuid, ${input.clientId},
83
+ ${input.feeAgreementId ?? null}, ${input.provider ?? 'manual'}, ${input.externalId ?? null},
84
+ ${input.method ?? 'pix'}, ${input.amount}, ${input.status ?? 'pending'},
85
+ ${input.description ?? null}, ${input.dueDate ?? null},
86
+ ${tx.json((input.metadata ?? {}))}, ${input.createdBy ?? null}
87
+ )
88
+ RETURNING ${tx.unsafe(CHARGE_COLS)}
89
+ `;
90
+ return mapCharge(rows[0]);
91
+ }
92
+ export async function listCharges(tx, filter = {}) {
93
+ const limit = Math.min(filter.limit ?? 50, 200);
94
+ const offset = filter.offset ?? 0;
95
+ const rows = await tx `
96
+ SELECT ${tx.unsafe(CHARGE_COLS)}, count(*) OVER() AS total
97
+ FROM charge
98
+ WHERE deleted_at IS NULL
99
+ AND (${filter.clientId ?? null}::uuid IS NULL OR client_id = ${filter.clientId ?? null})
100
+ AND (${filter.status ?? null}::text IS NULL OR status = ${filter.status ?? null})
101
+ ORDER BY created_at DESC
102
+ LIMIT ${limit} OFFSET ${offset}
103
+ `;
104
+ const total = rows[0] ? Number(rows[0].total) : 0;
105
+ return { items: rows.map(mapCharge), total };
106
+ }
107
+ export async function getCharge(tx, id) {
108
+ const rows = await tx `
109
+ SELECT ${tx.unsafe(CHARGE_COLS)} FROM charge WHERE id = ${id} AND deleted_at IS NULL
110
+ `;
111
+ if (!rows[0])
112
+ throw new NotFoundError('Cobrança não encontrada');
113
+ return mapCharge(rows[0]);
114
+ }
115
+ export async function markChargePaid(tx, id, paidAt) {
116
+ const rows = await tx `
117
+ UPDATE charge SET status = 'paid', paid_at = COALESCE(${paidAt ?? null}::timestamptz, now()),
118
+ updated_at = now(), version = version + 1
119
+ WHERE id = ${id} AND deleted_at IS NULL AND status <> 'paid' RETURNING id
120
+ `;
121
+ return rows.count;
122
+ }
123
+ /** Reconciliação por webhook: encontra a cobrança pelo (provider, external_id) e marca paga. */
124
+ export async function markChargePaidByExternal(tx, provider, externalId, paidAt) {
125
+ const rows = await tx `
126
+ UPDATE charge SET status = 'paid', paid_at = COALESCE(${paidAt ?? null}::timestamptz, now()),
127
+ updated_at = now(), version = version + 1
128
+ WHERE provider = ${provider} AND external_id = ${externalId}
129
+ AND deleted_at IS NULL AND status <> 'paid' RETURNING id
130
+ `;
131
+ return rows.count;
132
+ }
133
+ export async function setChargeStatus(tx, id, status) {
134
+ const rows = await tx `
135
+ UPDATE charge SET status = ${status}, updated_at = now(), version = version + 1
136
+ WHERE id = ${id} AND deleted_at IS NULL RETURNING id
137
+ `;
138
+ return rows.count;
139
+ }
140
+ /** KPIs financeiros do dashboard: previsto, recebido e inadimplência. */
141
+ export async function billingSummary(tx) {
142
+ const rows = await tx `
143
+ SELECT
144
+ COALESCE(sum(amount) FILTER (WHERE status IN ('pending','sent','overdue')), 0) AS expected,
145
+ COALESCE(sum(amount) FILTER (WHERE status = 'paid'), 0) AS received,
146
+ COALESCE(sum(amount) FILTER (WHERE status = 'overdue'), 0) AS overdue,
147
+ COALESCE(count(*) FILTER (WHERE status = 'overdue'), 0)::int AS overdue_count
148
+ FROM charge WHERE deleted_at IS NULL
149
+ `;
150
+ const r = rows[0];
151
+ return {
152
+ expected: Number(r.expected),
153
+ received: Number(r.received),
154
+ overdue: Number(r.overdue),
155
+ overdueCount: r.overdue_count,
156
+ };
157
+ }
158
+ /** Cobranças em aberto vencidas até `today` — usadas pela régua de inadimplência. */
159
+ export async function listOpenCharges(tx) {
160
+ const rows = await tx `
161
+ SELECT ${tx.unsafe(CHARGE_COLS)} FROM charge
162
+ WHERE deleted_at IS NULL AND status IN ('pending','sent','overdue') AND due_date IS NOT NULL
163
+ ORDER BY due_date ASC
164
+ `;
165
+ return rows.map(mapCharge);
166
+ }
167
+ //# sourceMappingURL=repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository.js","sourceRoot":"","sources":["../../src/billing/repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.appendAudit = appendAudit;
4
+ const shared_1 = require("@baruk/shared");
5
+ /**
6
+ * Registra uma linha na trilha append-only. DEVE rodar dentro de um contexto de
7
+ * tenant (`withContext`): o `tenant_id` é derivado da GUC `app.current_tenant`,
8
+ * então a linha auditada sempre pertence ao tenant corrente e satisfaz a RLS.
9
+ */
10
+ async function appendAudit(tx, entry) {
11
+ await tx `
12
+ INSERT INTO audit_log (
13
+ id, tenant_id, actor_type, actor_id, action, resource_type,
14
+ resource_id, result, diff, metadata, ip, user_agent
15
+ ) VALUES (
16
+ ${(0, shared_1.uuidv7)()},
17
+ current_setting('app.current_tenant')::uuid,
18
+ ${entry.actorType ?? 'user'},
19
+ ${entry.actorId ?? null},
20
+ ${entry.action},
21
+ ${entry.resourceType},
22
+ ${entry.resourceId ?? null},
23
+ ${entry.result ?? 'success'},
24
+ ${entry.diff === undefined ? null : tx.json(entry.diff)},
25
+ ${tx.json((entry.metadata ?? {}))},
26
+ ${entry.ip ?? null},
27
+ ${entry.userAgent ?? null}
28
+ )
29
+ `;
30
+ }
31
+ //# sourceMappingURL=audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../../src/audit/audit.ts"],"names":[],"mappings":";;AAsBA,kCAoBC;AA1CD,0CAAuD;AAiBvD;;;;GAIG;AACI,KAAK,UAAU,WAAW,CAAC,EAAM,EAAE,KAAiB;IACzD,MAAM,EAAE,CAAA;;;;;QAKF,IAAA,eAAM,GAAE;;QAER,KAAK,CAAC,SAAS,IAAI,MAAM;QACzB,KAAK,CAAC,OAAO,IAAI,IAAI;QACrB,KAAK,CAAC,MAAM;QACZ,KAAK,CAAC,YAAY;QAClB,KAAK,CAAC,UAAU,IAAI,IAAI;QACxB,KAAK,CAAC,MAAM,IAAI,SAAS;QACzB,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAa,CAAC;QAC9D,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAU,CAAC;QACxC,KAAK,CAAC,EAAE,IAAI,IAAI;QAChB,KAAK,CAAC,SAAS,IAAI,IAAI;;GAE5B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.listAudit = listAudit;
4
+ /** Lista a trilha de auditoria do tenant corrente (RLS já isola). Somente leitura. */
5
+ async function listAudit(tx, filter = {}) {
6
+ const limit = Math.min(filter.limit ?? 30, 100);
7
+ const offset = filter.offset ?? 0;
8
+ const rows = await tx `
9
+ SELECT id, actor_type, actor_id, action, resource_type, resource_id, result,
10
+ occurred_at, count(*) OVER() AS total
11
+ FROM audit_log
12
+ WHERE (${filter.action ?? null}::text IS NULL OR action = ${filter.action ?? null})
13
+ AND (${filter.resourceType ?? null}::text IS NULL OR resource_type = ${filter.resourceType ?? null})
14
+ ORDER BY occurred_at DESC
15
+ LIMIT ${limit} OFFSET ${offset}
16
+ `;
17
+ const total = rows[0] ? Number(rows[0].total) : 0;
18
+ return {
19
+ total,
20
+ items: rows.map((r) => ({
21
+ id: r.id,
22
+ actorType: r.actor_type,
23
+ actorId: r.actor_id,
24
+ action: r.action,
25
+ resourceType: r.resource_type,
26
+ resourceId: r.resource_id,
27
+ result: r.result,
28
+ occurredAt: r.occurred_at.toISOString(),
29
+ })),
30
+ };
31
+ }
32
+ //# sourceMappingURL=repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository.js","sourceRoot":"","sources":["../../../src/audit/repository.ts"],"names":[],"mappings":";;AAcA,8BA+BC;AAhCD,sFAAsF;AAC/E,KAAK,UAAU,SAAS,CAC7B,EAAM,EACN,SAAsF,EAAE;IAExF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,MAAM,EAAE,CAEpB;;;;aAIU,MAAM,CAAC,MAAM,IAAI,IAAI,8BAA8B,MAAM,CAAC,MAAM,IAAI,IAAI;aACxE,MAAM,CAAC,YAAY,IAAI,IAAI,qCAAqC,MAAM,CAAC,YAAY,IAAI,IAAI;;YAE5F,KAAK,WAAW,MAAM;GAC/B,CAAC;IACF,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,OAAO;QACL,KAAK;QACL,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACtB,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,SAAS,EAAE,CAAC,CAAC,UAAU;YACvB,OAAO,EAAE,CAAC,CAAC,QAAQ;YACnB,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,YAAY,EAAE,CAAC,CAAC,aAAa;YAC7B,UAAU,EAAE,CAAC,CAAC,WAAW;YACzB,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,UAAU,EAAE,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE;SACxC,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.requestPasswordReset = requestPasswordReset;
4
+ exports.resetPassword = resetPassword;
5
+ const shared_1 = require("@baruk/shared");
6
+ const password_js_1 = require("./password.js");
7
+ const session_token_js_1 = require("./session-token.js");
8
+ const RESET_TTL_MS = 60 * 60 * 1000; // 1h
9
+ const REAL_CLOCK = { now: () => Date.now() };
10
+ /**
11
+ * Solicita reset. Retorna o token EM CLARO (para compor o link do e-mail) e o
12
+ * userId — ou null se o e-mail não existe (o chamador responde genericamente
13
+ * de qualquer forma, para não revelar existência de conta).
14
+ */
15
+ async function requestPasswordReset(db, email, clock = REAL_CLOCK) {
16
+ const users = await db `
17
+ SELECT id, status FROM "user" WHERE email = ${email} AND deleted_at IS NULL
18
+ `;
19
+ const user = users[0];
20
+ if (!user || user.status === 'disabled')
21
+ return null;
22
+ const { token, tokenHash } = (0, session_token_js_1.generateSessionToken)();
23
+ const now = clock.now();
24
+ await db `
25
+ INSERT INTO password_reset (id, user_id, token_hash, expires_at)
26
+ VALUES (${(0, shared_1.uuidv7)()}, ${user.id}, ${tokenHash}, ${new Date(now + RESET_TTL_MS)})
27
+ `;
28
+ return { token, userId: user.id };
29
+ }
30
+ /**
31
+ * Redefine a senha usando um token válido (não usado, não expirado). Marca o
32
+ * token como usado, limpa `must_change_password` e revoga sessões anteriores.
33
+ */
34
+ async function resetPassword(db, token, newPassword, clock = REAL_CLOCK) {
35
+ if (newPassword.length < 8)
36
+ return false;
37
+ const th = (0, session_token_js_1.hashToken)(token);
38
+ const rows = await db `
39
+ SELECT id, user_id FROM password_reset
40
+ WHERE token_hash = ${th} AND used_at IS NULL AND expires_at > ${new Date(clock.now())}
41
+ `;
42
+ const reset = rows[0];
43
+ if (!reset)
44
+ return false;
45
+ await db.begin(async (tx) => {
46
+ await tx `
47
+ INSERT INTO user_credential (user_id, password_hash, must_change_password)
48
+ VALUES (${reset.user_id}, ${(0, password_js_1.hashPassword)(newPassword)}, false)
49
+ ON CONFLICT (user_id) DO UPDATE
50
+ SET password_hash = EXCLUDED.password_hash, must_change_password = false, updated_at = now()
51
+ `;
52
+ await tx `UPDATE password_reset SET used_at = now() WHERE id = ${reset.id}`;
53
+ // Revoga sessões anteriores (uso único de fato).
54
+ await tx `UPDATE user_session SET revoked_at = now() WHERE user_id = ${reset.user_id} AND revoked_at IS NULL`;
55
+ });
56
+ return true;
57
+ }
58
+ //# sourceMappingURL=password-reset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password-reset.js","sourceRoot":"","sources":["../../../src/auth/password-reset.ts"],"names":[],"mappings":";;AAiBA,oDAkBC;AAMD,sCA2BC;AApED,0CAAuC;AAEvC,+CAA6C;AAC7C,yDAAqE;AAErE,MAAM,YAAY,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,KAAK;AAK1C,MAAM,UAAU,GAAU,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;AAEpD;;;;GAIG;AACI,KAAK,UAAU,oBAAoB,CACxC,EAAM,EACN,KAAa,EACb,QAAe,UAAU;IAEzB,MAAM,KAAK,GAAG,MAAM,EAAE,CAAkC;kDACR,KAAK;GACpD,CAAC;IACF,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACtB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC;IAErD,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,IAAA,uCAAoB,GAAE,CAAC;IACpD,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;IACxB,MAAM,EAAE,CAAA;;cAEI,IAAA,eAAM,GAAE,KAAK,IAAI,CAAC,EAAE,KAAK,SAAS,KAAK,IAAI,IAAI,CAAC,GAAG,GAAG,YAAY,CAAC;GAC9E,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;AACpC,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,aAAa,CACjC,EAAM,EACN,KAAa,EACb,WAAmB,EACnB,QAAe,UAAU;IAEzB,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACzC,MAAM,EAAE,GAAG,IAAA,4BAAS,EAAC,KAAK,CAAC,CAAC;IAC5B,MAAM,IAAI,GAAG,MAAM,EAAE,CAAmC;;yBAEjC,EAAE,yCAAyC,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;GACtF,CAAC;IACF,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACtB,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAEzB,MAAM,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;QAC1B,MAAM,EAAE,CAAA;;gBAEI,KAAK,CAAC,OAAO,KAAK,IAAA,0BAAY,EAAC,WAAW,CAAC;;;KAGtD,CAAC;QACF,MAAM,EAAE,CAAA,wDAAwD,KAAK,CAAC,EAAE,EAAE,CAAC;QAC3E,iDAAiD;QACjD,MAAM,EAAE,CAAA,8DAA8D,KAAK,CAAC,OAAO,yBAAyB,CAAC;IAC/G,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hashPassword = hashPassword;
4
+ exports.verifyPassword = verifyPassword;
5
+ const node_crypto_1 = require("node:crypto");
6
+ // scrypt (nativo do Node, sem dependência). Parâmetros dentro do maxmem padrão.
7
+ const N = 16384;
8
+ const R = 8;
9
+ const P = 1;
10
+ const KEYLEN = 64;
11
+ /** Deriva um hash scrypt com salt aleatório, no formato `scrypt$N$r$p$salt$hash`. */
12
+ function hashPassword(password) {
13
+ const salt = (0, node_crypto_1.randomBytes)(16);
14
+ const derived = (0, node_crypto_1.scryptSync)(password, salt, KEYLEN, { N, r: R, p: P });
15
+ return ['scrypt', N, R, P, salt.toString('base64'), derived.toString('base64')].join('$');
16
+ }
17
+ /** Verifica uma senha contra o hash armazenado, em tempo constante. */
18
+ function verifyPassword(password, stored) {
19
+ const parts = stored.split('$');
20
+ if (parts.length !== 6 || parts[0] !== 'scrypt')
21
+ return false;
22
+ const [, n, r, p, saltB64, hashB64] = parts;
23
+ const salt = Buffer.from(saltB64, 'base64');
24
+ const expected = Buffer.from(hashB64, 'base64');
25
+ const derived = (0, node_crypto_1.scryptSync)(password, salt, expected.length, {
26
+ N: Number(n),
27
+ r: Number(r),
28
+ p: Number(p),
29
+ });
30
+ return derived.length === expected.length && (0, node_crypto_1.timingSafeEqual)(derived, expected);
31
+ }
32
+ //# sourceMappingURL=password.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password.js","sourceRoot":"","sources":["../../../src/auth/password.ts"],"names":[],"mappings":";;AASA,oCAIC;AAGD,wCAYC;AA5BD,6CAAuE;AAEvE,gFAAgF;AAChF,MAAM,CAAC,GAAG,KAAK,CAAC;AAChB,MAAM,CAAC,GAAG,CAAC,CAAC;AACZ,MAAM,CAAC,GAAG,CAAC,CAAC;AACZ,MAAM,MAAM,GAAG,EAAE,CAAC;AAElB,qFAAqF;AACrF,SAAgB,YAAY,CAAC,QAAgB;IAC3C,MAAM,IAAI,GAAG,IAAA,yBAAW,EAAC,EAAE,CAAC,CAAC;IAC7B,MAAM,OAAO,GAAG,IAAA,wBAAU,EAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACtE,OAAO,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC5F,CAAC;AAED,uEAAuE;AACvE,SAAgB,cAAc,CAAC,QAAgB,EAAE,MAAc;IAC7D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC;IAC5C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,OAAQ,EAAE,QAAQ,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,OAAQ,EAAE,QAAQ,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,IAAA,wBAAU,EAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE;QAC1D,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACZ,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACZ,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;KACb,CAAC,CAAC;IACH,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,IAAI,IAAA,6BAAe,EAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AAClF,CAAC"}
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.upsertUserWithPassword = upsertUserWithPassword;
4
+ exports.login = login;
5
+ exports.listMemberships = listMemberships;
6
+ exports.selectTenant = selectTenant;
7
+ exports.authenticate = authenticate;
8
+ exports.sessionMemberships = sessionMemberships;
9
+ exports.sessionProducts = sessionProducts;
10
+ exports.logout = logout;
11
+ const shared_1 = require("@baruk/shared");
12
+ const context_js_1 = require("../db/context.js");
13
+ const audit_js_1 = require("../audit/audit.js");
14
+ const authorize_js_1 = require("../rbac/authorize.js");
15
+ const repository_js_1 = require("../portal/repository.js");
16
+ const repository_js_2 = require("../products/repository.js");
17
+ const password_js_1 = require("./password.js");
18
+ const session_token_js_1 = require("./session-token.js");
19
+ const SESSION_TTL_MS = 12 * 60 * 60 * 1000; // 12h
20
+ const REAL_CLOCK = { now: () => Date.now() };
21
+ /** Cria (ou atualiza) um usuário staff com senha local. Usado pelo seed. */
22
+ async function upsertUserWithPassword(db, input) {
23
+ const rows = await db `
24
+ INSERT INTO "user" (id, email, full_name, user_type, auth_provider)
25
+ VALUES (${(0, shared_1.uuidv7)()}, ${input.email}, ${input.fullName}, ${input.userType ?? 'staff'}, 'password')
26
+ ON CONFLICT (email) WHERE deleted_at IS NULL
27
+ DO UPDATE SET full_name = EXCLUDED.full_name, updated_at = now()
28
+ RETURNING id
29
+ `;
30
+ const userId = rows[0].id;
31
+ await db `
32
+ INSERT INTO user_credential (user_id, password_hash)
33
+ VALUES (${userId}, ${(0, password_js_1.hashPassword)(input.password)})
34
+ ON CONFLICT (user_id) DO UPDATE SET password_hash = EXCLUDED.password_hash, updated_at = now()
35
+ `;
36
+ return {
37
+ id: userId,
38
+ email: input.email,
39
+ fullName: input.fullName,
40
+ userType: input.userType ?? 'staff',
41
+ };
42
+ }
43
+ /** Login com e-mail/senha. Emite sessão; auto-seleciona tenant se houver só um. */
44
+ async function login(db, input, clock = REAL_CLOCK) {
45
+ const users = await db `
46
+ SELECT id, email, full_name, user_type, status
47
+ FROM "user" WHERE email = ${input.email} AND deleted_at IS NULL
48
+ `;
49
+ const user = users[0];
50
+ if (!user || user.status !== 'active') {
51
+ throw new shared_1.UnauthorizedError('Credenciais inválidas');
52
+ }
53
+ const creds = await db `
54
+ SELECT password_hash FROM user_credential WHERE user_id = ${user.id}
55
+ `;
56
+ if (!creds[0] || !(0, password_js_1.verifyPassword)(input.password, creds[0].password_hash)) {
57
+ throw new shared_1.UnauthorizedError('Credenciais inválidas');
58
+ }
59
+ const { token, tokenHash } = (0, session_token_js_1.generateSessionToken)();
60
+ const now = clock.now();
61
+ const sessionId = (0, shared_1.uuidv7)();
62
+ const expiresAt = new Date(now + SESSION_TTL_MS);
63
+ await db `
64
+ INSERT INTO user_session (id, user_id, token_hash, active_tenant_id, expires_at)
65
+ VALUES (${sessionId}, ${user.id}, ${tokenHash}, NULL, ${expiresAt})
66
+ `;
67
+ await db `UPDATE "user" SET last_login_at = ${new Date(now)} WHERE id = ${user.id}`;
68
+ const memberships = await listMemberships(db, user.id);
69
+ let activeTenantId = null;
70
+ if (memberships.length === 1) {
71
+ activeTenantId = memberships[0].tenantId;
72
+ await db `UPDATE user_session SET active_tenant_id = ${activeTenantId} WHERE id = ${sessionId}`;
73
+ await auditWithinTenant(db, activeTenantId, user.id, {
74
+ action: 'login',
75
+ resourceType: 'user_session',
76
+ resourceId: sessionId,
77
+ ip: input.ip,
78
+ userAgent: input.userAgent,
79
+ });
80
+ }
81
+ return {
82
+ token,
83
+ user: { id: user.id, email: user.email, fullName: user.full_name, userType: user.user_type },
84
+ memberships,
85
+ activeTenantId,
86
+ };
87
+ }
88
+ /** Lista os tenants a que o usuário pertence (usa RLS self-clause de membership). */
89
+ async function listMemberships(db, userId) {
90
+ return (0, context_js_1.withContext)(db, { userId }, async (tx) => {
91
+ const rows = await tx `
92
+ SELECT m.tenant_id, t.code, t.display_name, m.status
93
+ FROM membership m
94
+ JOIN tenant t ON t.id = m.tenant_id
95
+ WHERE m.user_id = ${userId} AND m.deleted_at IS NULL AND m.status = 'active'
96
+ ORDER BY t.display_name
97
+ `;
98
+ return rows.map((r) => ({
99
+ tenantId: r.tenant_id,
100
+ tenantCode: r.code,
101
+ tenantName: r.display_name,
102
+ status: r.status,
103
+ }));
104
+ });
105
+ }
106
+ /** Escolhe/troca o tenant ativo de uma sessão, validando a membership. */
107
+ async function selectTenant(db, input) {
108
+ const session = await resolveSessionRow(db, input.token);
109
+ const memberships = await listMemberships(db, session.user_id);
110
+ const allowed = memberships.some((m) => m.tenantId === input.tenantId);
111
+ if (!allowed) {
112
+ throw new shared_1.ForbiddenError('Usuário não pertence a este tenant');
113
+ }
114
+ await db `
115
+ UPDATE user_session SET active_tenant_id = ${input.tenantId} WHERE id = ${session.id}
116
+ `;
117
+ return (0, context_js_1.withContext)(db, { tenantId: input.tenantId, userId: session.user_id }, async (tx) => {
118
+ const permissions = await (0, authorize_js_1.loadUserPermissions)(tx, session.user_id);
119
+ await (0, audit_js_1.appendAudit)(tx, {
120
+ actorId: session.user_id,
121
+ action: 'select_tenant',
122
+ resourceType: 'tenant',
123
+ resourceId: input.tenantId,
124
+ ip: input.ip,
125
+ userAgent: input.userAgent,
126
+ });
127
+ return {
128
+ userId: session.user_id,
129
+ userType: session.user_type,
130
+ tenantId: input.tenantId,
131
+ permissions,
132
+ };
133
+ });
134
+ }
135
+ /**
136
+ * Resolve uma sessão ativa em contexto autenticado (o que o middleware da API
137
+ * chama por request). Exige tenant ativo já selecionado.
138
+ */
139
+ async function authenticate(db, token, clock = REAL_CLOCK) {
140
+ const session = await resolveSessionRow(db, token, clock);
141
+ if (!session.active_tenant_id) {
142
+ throw new shared_1.UnauthorizedError('Nenhum tenant selecionado para esta sessão');
143
+ }
144
+ const tenantId = session.active_tenant_id;
145
+ return (0, context_js_1.withContext)(db, { tenantId, userId: session.user_id }, async (tx) => {
146
+ const permissions = await (0, authorize_js_1.loadUserPermissions)(tx, session.user_id);
147
+ const ctx = {
148
+ userId: session.user_id,
149
+ userType: session.user_type,
150
+ tenantId,
151
+ permissions,
152
+ };
153
+ if (session.user_type === 'client_portal') {
154
+ ctx.clientId = await (0, repository_js_1.getPortalClientId)(tx, session.user_id);
155
+ }
156
+ return ctx;
157
+ });
158
+ }
159
+ async function resolveSessionRow(db, token, clock = REAL_CLOCK) {
160
+ const rows = await db `
161
+ SELECT s.id, s.user_id, u.user_type, s.active_tenant_id
162
+ FROM user_session s
163
+ JOIN "user" u ON u.id = s.user_id
164
+ WHERE s.token_hash = ${(0, session_token_js_1.hashToken)(token)}
165
+ AND s.revoked_at IS NULL
166
+ AND s.expires_at > ${new Date(clock.now())}
167
+ AND u.deleted_at IS NULL
168
+ `;
169
+ if (!rows[0])
170
+ throw new shared_1.UnauthorizedError('Sessão inválida ou expirada');
171
+ return rows[0];
172
+ }
173
+ /** Memberships da sessão atual (para o seletor de tenant, antes de escolher um). */
174
+ async function sessionMemberships(db, token) {
175
+ const session = await resolveSessionRow(db, token);
176
+ return listMemberships(db, session.user_id);
177
+ }
178
+ /** Produtos que a sessão pode acessar (entitlements) + audiência. Roteamento do Hub. */
179
+ async function sessionProducts(db, token) {
180
+ const session = await resolveSessionRow(db, token);
181
+ const products = await (0, context_js_1.withContext)(db, { userId: session.user_id }, (tx) => (0, repository_js_2.listProductsForUser)(tx, session.user_id));
182
+ return { userType: session.user_type, products };
183
+ }
184
+ /** Revoga a sessão (logout). */
185
+ async function logout(db, token) {
186
+ await db `UPDATE user_session SET revoked_at = now() WHERE token_hash = ${(0, session_token_js_1.hashToken)(token)}`;
187
+ }
188
+ async function auditWithinTenant(db, tenantId, actorId, entry) {
189
+ await (0, context_js_1.withContext)(db, { tenantId, userId: actorId }, (tx) => (0, audit_js_1.appendAudit)(tx, entry));
190
+ }
191
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../../src/auth/service.ts"],"names":[],"mappings":";;AAmDA,wDAuBC;AAGD,sBAsDC;AAGD,0CAkBC;AAGD,oCA8BC;AAMD,oCAuBC;AA4BD,gDAGC;AAGD,0CASC;AAGD,wBAEC;AAtQD,0CAAyF;AAGzF,iDAA+C;AAC/C,gDAAgD;AAChD,uDAA2D;AAC3D,2DAA4D;AAC5D,6DAAoF;AACpF,+CAA6D;AAC7D,yDAAqE;AAErE,MAAM,cAAc,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,MAAM;AAqClD,MAAM,UAAU,GAAU,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;AAEpD,4EAA4E;AACrE,KAAK,UAAU,sBAAsB,CAC1C,EAAM,EACN,KAAiF;IAEjF,MAAM,IAAI,GAAG,MAAM,EAAE,CAAkB;;cAE3B,IAAA,eAAM,GAAE,KAAK,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ,IAAI,OAAO;;;;GAIpF,CAAC;IACF,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC;IAC3B,MAAM,EAAE,CAAA;;cAEI,MAAM,KAAK,IAAA,0BAAY,EAAC,KAAK,CAAC,QAAQ,CAAC;;GAElD,CAAC;IACF,OAAO;QACL,EAAE,EAAE,MAAM;QACV,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,OAAO;KACpC,CAAC;AACJ,CAAC;AAED,mFAAmF;AAC5E,KAAK,UAAU,KAAK,CACzB,EAAM,EACN,KAAyD,EACzD,QAAe,UAAU;IAEzB,MAAM,KAAK,GAAG,MAAM,EAAE,CAErB;;gCAE6B,KAAK,CAAC,KAAK;GACxC,CAAC;IACF,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACtB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACtC,MAAM,IAAI,0BAAiB,CAAC,uBAAuB,CAAC,CAAC;IACvD,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,EAAE,CAA6B;gEACW,IAAI,CAAC,EAAE;GACpE,CAAC;IACF,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAA,4BAAc,EAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC;QACzE,MAAM,IAAI,0BAAiB,CAAC,uBAAuB,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,IAAA,uCAAoB,GAAE,CAAC;IACpD,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;IACxB,MAAM,SAAS,GAAG,IAAA,eAAM,GAAE,CAAC;IAC3B,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,cAAc,CAAC,CAAC;IAEjD,MAAM,EAAE,CAAA;;cAEI,SAAS,KAAK,IAAI,CAAC,EAAE,KAAK,SAAS,WAAW,SAAS;GAClE,CAAC;IACF,MAAM,EAAE,CAAA,qCAAqC,IAAI,IAAI,CAAC,GAAG,CAAC,eAAe,IAAI,CAAC,EAAE,EAAE,CAAC;IAEnF,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IAEvD,IAAI,cAAc,GAAkB,IAAI,CAAC;IACzC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,cAAc,GAAG,WAAW,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC;QAC1C,MAAM,EAAE,CAAA,8CAA8C,cAAc,eAAe,SAAS,EAAE,CAAC;QAC/F,MAAM,iBAAiB,CAAC,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE;YACnD,MAAM,EAAE,OAAO;YACf,YAAY,EAAE,cAAc;YAC5B,UAAU,EAAE,SAAS;YACrB,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,SAAS,EAAE,KAAK,CAAC,SAAS;SAC3B,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,KAAK;QACL,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE;QAC5F,WAAW;QACX,cAAc;KACf,CAAC;AACJ,CAAC;AAED,qFAAqF;AAC9E,KAAK,UAAU,eAAe,CAAC,EAAM,EAAE,MAAc;IAC1D,OAAO,IAAA,wBAAW,EAAC,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;QAC9C,MAAM,IAAI,GAAG,MAAM,EAAE,CAEpB;;;;0BAIqB,MAAM;;KAE3B,CAAC;QACF,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACtB,QAAQ,EAAE,CAAC,CAAC,SAAS;YACrB,UAAU,EAAE,CAAC,CAAC,IAAI;YAClB,UAAU,EAAE,CAAC,CAAC,YAAY;YAC1B,MAAM,EAAE,CAAC,CAAC,MAAM;SACjB,CAAC,CAAC,CAAC;IACN,CAAC,CAAC,CAAC;AACL,CAAC;AAED,0EAA0E;AACnE,KAAK,UAAU,YAAY,CAChC,EAAM,EACN,KAAyD;IAEzD,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;IACzD,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/D,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ,CAAC,CAAC;IACvE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,uBAAc,CAAC,oCAAoC,CAAC,CAAC;IACjE,CAAC;IACD,MAAM,EAAE,CAAA;iDACuC,KAAK,CAAC,QAAQ,eAAe,OAAO,CAAC,EAAE;GACrF,CAAC;IACF,OAAO,IAAA,wBAAW,EAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;QACzF,MAAM,WAAW,GAAG,MAAM,IAAA,kCAAmB,EAAC,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QACnE,MAAM,IAAA,sBAAW,EAAC,EAAE,EAAE;YACpB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,MAAM,EAAE,eAAe;YACvB,YAAY,EAAE,QAAQ;YACtB,UAAU,EAAE,KAAK,CAAC,QAAQ;YAC1B,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,SAAS,EAAE,KAAK,CAAC,SAAS;SAC3B,CAAC,CAAC;QACH,OAAO;YACL,MAAM,EAAE,OAAO,CAAC,OAAO;YACvB,QAAQ,EAAE,OAAO,CAAC,SAAS;YAC3B,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,WAAW;SACZ,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,YAAY,CAChC,EAAM,EACN,KAAa,EACb,QAAe,UAAU;IAEzB,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC1D,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC;QAC9B,MAAM,IAAI,0BAAiB,CAAC,4CAA4C,CAAC,CAAC;IAC5E,CAAC;IACD,MAAM,QAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAC1C,OAAO,IAAA,wBAAW,EAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;QACzE,MAAM,WAAW,GAAG,MAAM,IAAA,kCAAmB,EAAC,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QACnE,MAAM,GAAG,GAAgB;YACvB,MAAM,EAAE,OAAO,CAAC,OAAO;YACvB,QAAQ,EAAE,OAAO,CAAC,SAAS;YAC3B,QAAQ;YACR,WAAW;SACZ,CAAC;QACF,IAAI,OAAO,CAAC,SAAS,KAAK,eAAe,EAAE,CAAC;YAC1C,GAAG,CAAC,QAAQ,GAAG,MAAM,IAAA,iCAAiB,EAAC,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,CAAC,CAAC;AACL,CAAC;AASD,KAAK,UAAU,iBAAiB,CAC9B,EAAM,EACN,KAAa,EACb,QAAe,UAAU;IAEzB,MAAM,IAAI,GAAG,MAAM,EAAE,CAAc;;;;2BAIV,IAAA,4BAAS,EAAC,KAAK,CAAC;;2BAEhB,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;;GAE7C,CAAC;IACF,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,MAAM,IAAI,0BAAiB,CAAC,6BAA6B,CAAC,CAAC;IACzE,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC;AAED,oFAAoF;AAC7E,KAAK,UAAU,kBAAkB,CAAC,EAAM,EAAE,KAAa;IAC5D,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IACnD,OAAO,eAAe,CAAC,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;AAC9C,CAAC;AAED,wFAAwF;AACjF,KAAK,UAAU,eAAe,CACnC,EAAM,EACN,KAAa;IAEb,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAG,MAAM,IAAA,wBAAW,EAAC,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CACzE,IAAA,mCAAmB,EAAC,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,CACzC,CAAC;IACF,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC;AACnD,CAAC;AAED,gCAAgC;AACzB,KAAK,UAAU,MAAM,CAAC,EAAM,EAAE,KAAa;IAChD,MAAM,EAAE,CAAA,iEAAiE,IAAA,4BAAS,EAAC,KAAK,CAAC,EAAE,CAAC;AAC9F,CAAC;AAED,KAAK,UAAU,iBAAiB,CAC9B,EAAM,EACN,QAAgB,EAChB,OAAe,EACf,KAAwC;IAExC,MAAM,IAAA,wBAAW,EAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,IAAA,sBAAW,EAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;AACvF,CAAC"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateSessionToken = generateSessionToken;
4
+ exports.hashToken = hashToken;
5
+ const node_crypto_1 = require("node:crypto");
6
+ /**
7
+ * Sessão opaca: o cliente recebe um token aleatório; o banco guarda apenas o
8
+ * hash SHA-256 (nunca o token em claro). Resolver a sessão = hashear o token
9
+ * recebido e buscar por igualdade.
10
+ */
11
+ function generateSessionToken() {
12
+ const token = (0, node_crypto_1.randomBytes)(32).toString('base64url');
13
+ return { token, tokenHash: hashToken(token) };
14
+ }
15
+ function hashToken(token) {
16
+ return (0, node_crypto_1.createHash)('sha256').update(token).digest('hex');
17
+ }
18
+ //# sourceMappingURL=session-token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-token.js","sourceRoot":"","sources":["../../../src/auth/session-token.ts"],"names":[],"mappings":";;AAOA,oDAGC;AAED,8BAEC;AAdD,6CAAsD;AAEtD;;;;GAIG;AACH,SAAgB,oBAAoB;IAClC,MAAM,KAAK,GAAG,IAAA,yBAAW,EAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IACpD,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;AAChD,CAAC;AAED,SAAgB,SAAS,CAAC,KAAa;IACrC,OAAO,IAAA,wBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ /**
3
+ * Motor de régua de inadimplência (dunning) — PURO e determinístico. Não envia
4
+ * nada: apenas decide QUAIS passos estão vencidos para uma cobrança numa data de
5
+ * referência. O disparo efetivo (WhatsApp/Email/Notificação) é responsabilidade
6
+ * do Communication/Automation Engine — o Billing só define a política. Assim a
7
+ * régua é 100% testável sem I/O e pronta para rodar num cron/queue.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.DEFAULT_DUNNING_STEPS = void 0;
11
+ exports.stepKey = stepKey;
12
+ exports.dueDunningSteps = dueDunningSteps;
13
+ /** Régua padrão de contabilidade: lembrete antes + escalonamento após o vencimento. */
14
+ exports.DEFAULT_DUNNING_STEPS = [
15
+ { offsetDays: -3, channel: 'whatsapp', template: 'lembrete_previo' },
16
+ { offsetDays: 0, channel: 'whatsapp', template: 'vencimento_hoje' },
17
+ { offsetDays: 3, channel: 'whatsapp', template: 'atraso_3d' },
18
+ { offsetDays: 7, channel: 'email', template: 'atraso_7d' },
19
+ { offsetDays: 15, channel: 'email', template: 'atraso_15d' },
20
+ { offsetDays: 30, channel: 'whatsapp', template: 'atraso_30d' },
21
+ { offsetDays: 60, channel: 'email', template: 'atraso_60d' },
22
+ { offsetDays: 90, channel: 'notification', template: 'atraso_90d' },
23
+ ];
24
+ function stepKey(step) {
25
+ const tag = step.offsetDays === 0 ? 'D0' : step.offsetDays > 0 ? `D+${step.offsetDays}` : `D${step.offsetDays}`;
26
+ return `${tag}:${step.channel}`;
27
+ }
28
+ function addDays(isoDate, days) {
29
+ const d = new Date(`${isoDate}T00:00:00Z`);
30
+ d.setUTCDate(d.getUTCDate() + days);
31
+ return d.toISOString().slice(0, 10);
32
+ }
33
+ /**
34
+ * Retorna os passos VENCIDOS (data agendada <= hoje) ainda não executados, para
35
+ * uma cobrança em aberto. `today` e `executed` são injetados (determinismo).
36
+ */
37
+ function dueDunningSteps(steps, charge, today, executed = new Set()) {
38
+ if (!charge.dueDate)
39
+ return [];
40
+ if (charge.status === 'paid' || charge.status === 'canceled' || charge.status === 'refunded')
41
+ return [];
42
+ const due = [];
43
+ for (const step of steps) {
44
+ const key = stepKey(step);
45
+ if (executed.has(key))
46
+ continue;
47
+ const scheduledFor = addDays(charge.dueDate, step.offsetDays);
48
+ if (scheduledFor <= today) {
49
+ due.push({ ...step, stepKey: key, scheduledFor });
50
+ }
51
+ }
52
+ return due.sort((a, b) => a.scheduledFor.localeCompare(b.scheduledFor));
53
+ }
54
+ //# sourceMappingURL=dunning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dunning.js","sourceRoot":"","sources":["../../../src/billing/dunning.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AA8BH,0BAGC;AAiBD,0CAmBC;AAnDD,uFAAuF;AAC1E,QAAA,qBAAqB,GAA2B;IAC3D,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,iBAAiB,EAAE;IACpE,EAAE,UAAU,EAAE,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,iBAAiB,EAAE;IACnE,EAAE,UAAU,EAAE,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE;IAC7D,EAAE,UAAU,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE;IAC1D,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE;IAC5D,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE;IAC/D,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE;IAC5D,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY,EAAE;CACpE,CAAC;AAEF,SAAgB,OAAO,CAAC,IAAiB;IACvC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;IAChH,OAAO,GAAG,GAAG,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;AAClC,CAAC;AAED,SAAS,OAAO,CAAC,OAAe,EAAE,IAAY;IAC5C,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,OAAO,YAAY,CAAC,CAAC;IAC3C,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,CAAC;IACpC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACtC,CAAC;AAOD;;;GAGG;AACH,SAAgB,eAAe,CAC7B,KAA6B,EAC7B,MAAyB,EACzB,KAAa,EACb,WAAgC,IAAI,GAAG,EAAE;IAEzC,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IAC/B,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU;QAAE,OAAO,EAAE,CAAC;IAExG,MAAM,GAAG,GAAqB,EAAE,CAAC;IACjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAChC,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9D,IAAI,YAAY,IAAI,KAAK,EAAE,CAAC;YAC1B,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;AAC1E,CAAC"}