@baruk/core 0.3.1 → 0.4.2

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 (696) hide show
  1. package/.baruk-provenance.json +10 -0
  2. package/CHANGELOG.md +85 -0
  3. package/dist/auth/password-reset.d.ts +30 -1
  4. package/dist/auth/password-reset.d.ts.map +1 -1
  5. package/dist/auth/password-reset.js +139 -11
  6. package/dist/auth/password-reset.js.map +1 -1
  7. package/dist/auth/service.d.ts +39 -2
  8. package/dist/auth/service.d.ts.map +1 -1
  9. package/dist/auth/service.js +75 -10
  10. package/dist/auth/service.js.map +1 -1
  11. package/dist/billing/ar-repository.d.ts +334 -0
  12. package/dist/billing/ar-repository.d.ts.map +1 -0
  13. package/dist/billing/ar-repository.js +707 -0
  14. package/dist/billing/ar-repository.js.map +1 -0
  15. package/dist/billing/auto-generation.d.ts +87 -0
  16. package/dist/billing/auto-generation.d.ts.map +1 -0
  17. package/dist/billing/auto-generation.js +181 -0
  18. package/dist/billing/auto-generation.js.map +1 -0
  19. package/dist/billing/live-guard.d.ts +64 -0
  20. package/dist/billing/live-guard.d.ts.map +1 -0
  21. package/dist/billing/live-guard.js +68 -0
  22. package/dist/billing/live-guard.js.map +1 -0
  23. package/dist/billing/payment-means-catalog.d.ts +17 -0
  24. package/dist/billing/payment-means-catalog.d.ts.map +1 -0
  25. package/dist/billing/payment-means-catalog.js +21 -0
  26. package/dist/billing/payment-means-catalog.js.map +1 -0
  27. package/dist/billing/payment-means.d.ts +38 -0
  28. package/dist/billing/payment-means.d.ts.map +1 -0
  29. package/dist/billing/payment-means.js +29 -0
  30. package/dist/billing/payment-means.js.map +1 -0
  31. package/dist/billing/payment-rail.d.ts +118 -0
  32. package/dist/billing/payment-rail.d.ts.map +1 -0
  33. package/dist/billing/payment-rail.js +295 -0
  34. package/dist/billing/payment-rail.js.map +1 -0
  35. package/dist/billing/provider/asaas.d.ts +46 -1
  36. package/dist/billing/provider/asaas.d.ts.map +1 -1
  37. package/dist/billing/provider/asaas.js +194 -14
  38. package/dist/billing/provider/asaas.js.map +1 -1
  39. package/dist/billing/provider/manual.js +1 -1
  40. package/dist/billing/provider/manual.js.map +1 -1
  41. package/dist/billing/provider/types.d.ts +115 -8
  42. package/dist/billing/provider/types.d.ts.map +1 -1
  43. package/dist/billing/provider-account.d.ts +89 -0
  44. package/dist/billing/provider-account.d.ts.map +1 -0
  45. package/dist/billing/provider-account.js +161 -0
  46. package/dist/billing/provider-account.js.map +1 -0
  47. package/dist/billing/provider-onboarding.d.ts +67 -0
  48. package/dist/billing/provider-onboarding.d.ts.map +1 -0
  49. package/dist/billing/provider-onboarding.js +234 -0
  50. package/dist/billing/provider-onboarding.js.map +1 -0
  51. package/dist/billing/receivable.d.ts +5 -1
  52. package/dist/billing/receivable.d.ts.map +1 -1
  53. package/dist/billing/reconcile.d.ts +58 -0
  54. package/dist/billing/reconcile.d.ts.map +1 -0
  55. package/dist/billing/reconcile.js +138 -0
  56. package/dist/billing/reconcile.js.map +1 -0
  57. package/dist/billing/repository.d.ts +90 -1
  58. package/dist/billing/repository.d.ts.map +1 -1
  59. package/dist/billing/repository.js +148 -19
  60. package/dist/billing/repository.js.map +1 -1
  61. package/dist/cjs/auth/password-reset.js +141 -11
  62. package/dist/cjs/auth/password-reset.js.map +1 -1
  63. package/dist/cjs/auth/service.js +75 -9
  64. package/dist/cjs/auth/service.js.map +1 -1
  65. package/dist/cjs/billing/ar-repository.js +728 -0
  66. package/dist/cjs/billing/ar-repository.js.map +1 -0
  67. package/dist/cjs/billing/auto-generation.js +186 -0
  68. package/dist/cjs/billing/auto-generation.js.map +1 -0
  69. package/dist/cjs/billing/live-guard.js +72 -0
  70. package/dist/cjs/billing/live-guard.js.map +1 -0
  71. package/dist/cjs/billing/payment-means-catalog.js +25 -0
  72. package/dist/cjs/billing/payment-means-catalog.js.map +1 -0
  73. package/dist/cjs/billing/payment-means.js +33 -0
  74. package/dist/cjs/billing/payment-means.js.map +1 -0
  75. package/dist/cjs/billing/payment-rail.js +301 -0
  76. package/dist/cjs/billing/payment-rail.js.map +1 -0
  77. package/dist/cjs/billing/provider/asaas.js +194 -14
  78. package/dist/cjs/billing/provider/asaas.js.map +1 -1
  79. package/dist/cjs/billing/provider/manual.js +1 -1
  80. package/dist/cjs/billing/provider/manual.js.map +1 -1
  81. package/dist/cjs/billing/provider-account.js +170 -0
  82. package/dist/cjs/billing/provider-account.js.map +1 -0
  83. package/dist/cjs/billing/provider-onboarding.js +239 -0
  84. package/dist/cjs/billing/provider-onboarding.js.map +1 -0
  85. package/dist/cjs/billing/reconcile.js +143 -0
  86. package/dist/cjs/billing/reconcile.js.map +1 -0
  87. package/dist/cjs/billing/repository.js +150 -18
  88. package/dist/cjs/billing/repository.js.map +1 -1
  89. package/dist/cjs/clients/repository.js +96 -20
  90. package/dist/cjs/clients/repository.js.map +1 -1
  91. package/dist/cjs/collection/branding.js +140 -0
  92. package/dist/cjs/collection/branding.js.map +1 -0
  93. package/dist/cjs/collection/channel-accounts.js +137 -0
  94. package/dist/cjs/collection/channel-accounts.js.map +1 -0
  95. package/dist/cjs/collection/channel.js +17 -0
  96. package/dist/cjs/collection/channel.js.map +1 -0
  97. package/dist/cjs/collection/communication-bridge.js +140 -0
  98. package/dist/cjs/collection/communication-bridge.js.map +1 -0
  99. package/dist/cjs/collection/communication-runtime.js +193 -0
  100. package/dist/cjs/collection/communication-runtime.js.map +1 -0
  101. package/dist/cjs/collection/consent-repository.js +84 -0
  102. package/dist/cjs/collection/consent-repository.js.map +1 -0
  103. package/dist/cjs/collection/copy.js +125 -0
  104. package/dist/cjs/collection/copy.js.map +1 -0
  105. package/dist/cjs/collection/delivery-callback.js +151 -0
  106. package/dist/cjs/collection/delivery-callback.js.map +1 -0
  107. package/dist/cjs/collection/email-layout.js +252 -0
  108. package/dist/cjs/collection/email-layout.js.map +1 -0
  109. package/dist/cjs/collection/engine.js +414 -0
  110. package/dist/cjs/collection/engine.js.map +1 -0
  111. package/dist/cjs/collection/format.js +76 -0
  112. package/dist/cjs/collection/format.js.map +1 -0
  113. package/dist/cjs/collection/payment-block.js +3 -0
  114. package/dist/cjs/collection/payment-block.js.map +1 -0
  115. package/dist/cjs/collection/policy.js +147 -0
  116. package/dist/cjs/collection/policy.js.map +1 -0
  117. package/dist/cjs/collection/repository.js +260 -0
  118. package/dist/cjs/collection/repository.js.map +1 -0
  119. package/dist/cjs/collection/subject.js +104 -0
  120. package/dist/cjs/collection/subject.js.map +1 -0
  121. package/dist/cjs/collection/template-catalog.js +165 -0
  122. package/dist/cjs/collection/template-catalog.js.map +1 -0
  123. package/dist/cjs/collection/template.js +78 -0
  124. package/dist/cjs/collection/template.js.map +1 -0
  125. package/dist/cjs/communication/adapters/email.js +132 -0
  126. package/dist/cjs/communication/adapters/email.js.map +1 -0
  127. package/dist/cjs/communication/adapters/sms.js +127 -0
  128. package/dist/cjs/communication/adapters/sms.js.map +1 -0
  129. package/dist/cjs/communication/adapters/whatsapp-language.js +39 -0
  130. package/dist/cjs/communication/adapters/whatsapp-language.js.map +1 -0
  131. package/dist/cjs/communication/adapters/whatsapp-templates.js +100 -0
  132. package/dist/cjs/communication/adapters/whatsapp-templates.js.map +1 -0
  133. package/dist/cjs/communication/adapters/whatsapp.js +213 -0
  134. package/dist/cjs/communication/adapters/whatsapp.js.map +1 -0
  135. package/dist/cjs/communication/audit.js +61 -0
  136. package/dist/cjs/communication/audit.js.map +1 -0
  137. package/dist/cjs/communication/capabilities.js +76 -0
  138. package/dist/cjs/communication/capabilities.js.map +1 -0
  139. package/dist/cjs/communication/channel.js +53 -0
  140. package/dist/cjs/communication/channel.js.map +1 -0
  141. package/dist/cjs/communication/claim.js +228 -0
  142. package/dist/cjs/communication/claim.js.map +1 -0
  143. package/dist/cjs/communication/consent.js +43 -0
  144. package/dist/cjs/communication/consent.js.map +1 -0
  145. package/dist/cjs/communication/context.js +45 -0
  146. package/dist/cjs/communication/context.js.map +1 -0
  147. package/dist/cjs/communication/credentials.js +121 -0
  148. package/dist/cjs/communication/credentials.js.map +1 -0
  149. package/dist/cjs/communication/dry-run-scenario.js +161 -0
  150. package/dist/cjs/communication/dry-run-scenario.js.map +1 -0
  151. package/dist/cjs/communication/dry-run.js +97 -0
  152. package/dist/cjs/communication/dry-run.js.map +1 -0
  153. package/dist/cjs/communication/engine.js +483 -0
  154. package/dist/cjs/communication/engine.js.map +1 -0
  155. package/dist/cjs/communication/graph.js +50 -0
  156. package/dist/cjs/communication/graph.js.map +1 -0
  157. package/dist/cjs/communication/idempotency.js +26 -0
  158. package/dist/cjs/communication/idempotency.js.map +1 -0
  159. package/dist/cjs/communication/identity.js +110 -0
  160. package/dist/cjs/communication/identity.js.map +1 -0
  161. package/dist/cjs/communication/index.js +135 -0
  162. package/dist/cjs/communication/index.js.map +1 -0
  163. package/dist/cjs/communication/onboarding.js +297 -0
  164. package/dist/cjs/communication/onboarding.js.map +1 -0
  165. package/dist/cjs/communication/policy.js +16 -0
  166. package/dist/cjs/communication/policy.js.map +1 -0
  167. package/dist/cjs/communication/routing.js +77 -0
  168. package/dist/cjs/communication/routing.js.map +1 -0
  169. package/dist/cjs/communication/sender-profile.js +128 -0
  170. package/dist/cjs/communication/sender-profile.js.map +1 -0
  171. package/dist/cjs/communication/status.js +86 -0
  172. package/dist/cjs/communication/status.js.map +1 -0
  173. package/dist/cjs/communication/stores/onboarding.js +135 -0
  174. package/dist/cjs/communication/stores/onboarding.js.map +1 -0
  175. package/dist/cjs/communication/stores/postgres.js +458 -0
  176. package/dist/cjs/communication/stores/postgres.js.map +1 -0
  177. package/dist/cjs/communication/stores/routing.js +334 -0
  178. package/dist/cjs/communication/stores/routing.js.map +1 -0
  179. package/dist/cjs/communication/stores/secrets.js +126 -0
  180. package/dist/cjs/communication/stores/secrets.js.map +1 -0
  181. package/dist/cjs/communication/template-provider.js +22 -0
  182. package/dist/cjs/communication/template-provider.js.map +1 -0
  183. package/dist/cjs/communication/template.js +63 -0
  184. package/dist/cjs/communication/template.js.map +1 -0
  185. package/dist/cjs/communication/webhook-subscription.js +258 -0
  186. package/dist/cjs/communication/webhook-subscription.js.map +1 -0
  187. package/dist/cjs/communication/webhook.js +292 -0
  188. package/dist/cjs/communication/webhook.js.map +1 -0
  189. package/dist/cjs/competence/repository.js +309 -0
  190. package/dist/cjs/competence/repository.js.map +1 -0
  191. package/dist/cjs/contacts/phone.js +192 -0
  192. package/dist/cjs/contacts/phone.js.map +1 -0
  193. package/dist/cjs/db/seed-catalog.js +48 -0
  194. package/dist/cjs/db/seed-catalog.js.map +1 -0
  195. package/dist/cjs/db/seed.js +15 -7
  196. package/dist/cjs/db/seed.js.map +1 -1
  197. package/dist/cjs/documents/repository.js +244 -0
  198. package/dist/cjs/documents/repository.js.map +1 -0
  199. package/dist/cjs/documents/requests.js +136 -0
  200. package/dist/cjs/documents/requests.js.map +1 -0
  201. package/dist/cjs/index.js +406 -39
  202. package/dist/cjs/index.js.map +1 -1
  203. package/dist/cjs/legal/documents.js +125 -3
  204. package/dist/cjs/legal/documents.js.map +1 -1
  205. package/dist/cjs/legal/types.js +1 -0
  206. package/dist/cjs/legal/types.js.map +1 -1
  207. package/dist/cjs/mail/auth-templates.js +29 -0
  208. package/dist/cjs/mail/auth-templates.js.map +1 -0
  209. package/dist/cjs/mail/dedup-store.js +12 -51
  210. package/dist/cjs/mail/dedup-store.js.map +1 -1
  211. package/dist/cjs/mail/index.js +16 -4
  212. package/dist/cjs/mail/index.js.map +1 -1
  213. package/dist/cjs/mail/provider.js +12 -247
  214. package/dist/cjs/mail/provider.js.map +1 -1
  215. package/dist/cjs/mail/resend.js +14 -18
  216. package/dist/cjs/mail/resend.js.map +1 -1
  217. package/dist/cjs/mail/sender-resolver.js +12 -11
  218. package/dist/cjs/mail/sender-resolver.js.map +1 -1
  219. package/dist/cjs/mail/template-renderer.js +11 -16
  220. package/dist/cjs/mail/template-renderer.js.map +1 -1
  221. package/dist/cjs/mail/transactional-outbound.js +117 -0
  222. package/dist/cjs/mail/transactional-outbound.js.map +1 -0
  223. package/dist/cjs/mail/types.js +8 -35
  224. package/dist/cjs/mail/types.js.map +1 -1
  225. package/dist/cjs/portal/provisioning.js +144 -0
  226. package/dist/cjs/portal/provisioning.js.map +1 -0
  227. package/dist/cjs/pricing-engine/canonical.js +42 -0
  228. package/dist/cjs/pricing-engine/canonical.js.map +1 -0
  229. package/dist/cjs/pricing-engine/errors.js +6 -1
  230. package/dist/cjs/pricing-engine/errors.js.map +1 -1
  231. package/dist/cjs/pricing-engine/index.js +12 -1
  232. package/dist/cjs/pricing-engine/index.js.map +1 -1
  233. package/dist/cjs/pricing-engine/pipeline.js +200 -26
  234. package/dist/cjs/pricing-engine/pipeline.js.map +1 -1
  235. package/dist/cjs/pricing-engine/shadow-adapter.js +79 -0
  236. package/dist/cjs/pricing-engine/shadow-adapter.js.map +1 -0
  237. package/dist/cjs/pricing-engine/shadow-diff.js +55 -0
  238. package/dist/cjs/pricing-engine/shadow-diff.js.map +1 -0
  239. package/dist/cjs/pricing-engine/shadow-facade.js +85 -0
  240. package/dist/cjs/pricing-engine/shadow-facade.js.map +1 -0
  241. package/dist/cjs/pricing-engine/shadow-legacy-types.js +19 -0
  242. package/dist/cjs/pricing-engine/shadow-legacy-types.js.map +1 -0
  243. package/dist/cjs/pricing-engine/shadow-metrics.js +34 -0
  244. package/dist/cjs/pricing-engine/shadow-metrics.js.map +1 -0
  245. package/dist/cjs/pricing-engine/shadow-normalizer.js +42 -0
  246. package/dist/cjs/pricing-engine/shadow-normalizer.js.map +1 -0
  247. package/dist/cjs/rbac/authorize.js +28 -0
  248. package/dist/cjs/rbac/authorize.js.map +1 -1
  249. package/dist/cjs/rbac/catalog.js +67 -1
  250. package/dist/cjs/rbac/catalog.js.map +1 -1
  251. package/dist/cjs/rbac/workload-provisioning.js +160 -0
  252. package/dist/cjs/rbac/workload-provisioning.js.map +1 -0
  253. package/dist/cjs/rbac/workload.js +191 -0
  254. package/dist/cjs/rbac/workload.js.map +1 -0
  255. package/dist/cjs/storage/checksum.js +15 -0
  256. package/dist/cjs/storage/checksum.js.map +1 -0
  257. package/dist/cjs/storage/key.js +72 -0
  258. package/dist/cjs/storage/key.js.map +1 -0
  259. package/dist/cjs/storage/local.js +100 -0
  260. package/dist/cjs/storage/local.js.map +1 -0
  261. package/dist/cjs/storage/r2.js +181 -0
  262. package/dist/cjs/storage/r2.js.map +1 -0
  263. package/dist/cjs/storage/registry.js +41 -0
  264. package/dist/cjs/storage/registry.js.map +1 -0
  265. package/dist/cjs/storage/types.js +50 -0
  266. package/dist/cjs/storage/types.js.map +1 -0
  267. package/dist/cjs/subscription-billing/provider/asaas.js +32 -7
  268. package/dist/cjs/subscription-billing/provider/asaas.js.map +1 -1
  269. package/dist/cjs/subscription-billing/provider/disabled.js +8 -0
  270. package/dist/cjs/subscription-billing/provider/disabled.js.map +1 -1
  271. package/dist/cjs/subscription-billing/provider/registry.js +17 -0
  272. package/dist/cjs/subscription-billing/provider/registry.js.map +1 -1
  273. package/dist/cjs/subscription-billing/service.js +57 -8
  274. package/dist/cjs/subscription-billing/service.js.map +1 -1
  275. package/dist/cjs/subscription-billing/types.js.map +1 -1
  276. package/dist/cjs/tenancy/provisioning.js +32 -8
  277. package/dist/cjs/tenancy/provisioning.js.map +1 -1
  278. package/dist/cjs/users/repository.js +119 -2
  279. package/dist/cjs/users/repository.js.map +1 -1
  280. package/dist/cjs/vault/repository.js +81 -0
  281. package/dist/cjs/vault/repository.js.map +1 -1
  282. package/dist/clients/repository.d.ts +42 -0
  283. package/dist/clients/repository.d.ts.map +1 -1
  284. package/dist/clients/repository.js +94 -21
  285. package/dist/clients/repository.js.map +1 -1
  286. package/dist/collection/branding.d.ts +72 -0
  287. package/dist/collection/branding.d.ts.map +1 -0
  288. package/dist/collection/branding.js +136 -0
  289. package/dist/collection/branding.js.map +1 -0
  290. package/dist/collection/channel-accounts.d.ts +57 -0
  291. package/dist/collection/channel-accounts.d.ts.map +1 -0
  292. package/dist/collection/channel-accounts.js +133 -0
  293. package/dist/collection/channel-accounts.js.map +1 -0
  294. package/dist/collection/channel.d.ts +24 -0
  295. package/dist/collection/channel.d.ts.map +1 -0
  296. package/dist/collection/channel.js +16 -0
  297. package/dist/collection/channel.js.map +1 -0
  298. package/dist/collection/communication-bridge.d.ts +66 -0
  299. package/dist/collection/communication-bridge.d.ts.map +1 -0
  300. package/dist/collection/communication-bridge.js +134 -0
  301. package/dist/collection/communication-bridge.js.map +1 -0
  302. package/dist/collection/communication-runtime.d.ts +95 -0
  303. package/dist/collection/communication-runtime.d.ts.map +1 -0
  304. package/dist/collection/communication-runtime.js +187 -0
  305. package/dist/collection/communication-runtime.js.map +1 -0
  306. package/dist/collection/consent-repository.d.ts +32 -0
  307. package/dist/collection/consent-repository.d.ts.map +1 -0
  308. package/dist/collection/consent-repository.js +79 -0
  309. package/dist/collection/consent-repository.js.map +1 -0
  310. package/dist/collection/copy.d.ts +50 -0
  311. package/dist/collection/copy.d.ts.map +1 -0
  312. package/dist/collection/copy.js +122 -0
  313. package/dist/collection/copy.js.map +1 -0
  314. package/dist/collection/delivery-callback.d.ts +49 -0
  315. package/dist/collection/delivery-callback.d.ts.map +1 -0
  316. package/dist/collection/delivery-callback.js +147 -0
  317. package/dist/collection/delivery-callback.js.map +1 -0
  318. package/dist/collection/email-layout.d.ts +45 -0
  319. package/dist/collection/email-layout.d.ts.map +1 -0
  320. package/dist/collection/email-layout.js +247 -0
  321. package/dist/collection/email-layout.js.map +1 -0
  322. package/dist/collection/engine.d.ts +177 -0
  323. package/dist/collection/engine.d.ts.map +1 -0
  324. package/dist/collection/engine.js +407 -0
  325. package/dist/collection/engine.js.map +1 -0
  326. package/dist/collection/format.d.ts +32 -0
  327. package/dist/collection/format.d.ts.map +1 -0
  328. package/dist/collection/format.js +70 -0
  329. package/dist/collection/format.js.map +1 -0
  330. package/dist/collection/payment-block.d.ts +24 -0
  331. package/dist/collection/payment-block.d.ts.map +1 -0
  332. package/dist/collection/payment-block.js +2 -0
  333. package/dist/collection/payment-block.js.map +1 -0
  334. package/dist/collection/policy.d.ts +53 -0
  335. package/dist/collection/policy.d.ts.map +1 -0
  336. package/dist/collection/policy.js +141 -0
  337. package/dist/collection/policy.js.map +1 -0
  338. package/dist/collection/repository.d.ts +129 -0
  339. package/dist/collection/repository.d.ts.map +1 -0
  340. package/dist/collection/repository.js +246 -0
  341. package/dist/collection/repository.js.map +1 -0
  342. package/dist/collection/subject.d.ts +66 -0
  343. package/dist/collection/subject.d.ts.map +1 -0
  344. package/dist/collection/subject.js +99 -0
  345. package/dist/collection/subject.js.map +1 -0
  346. package/dist/collection/template-catalog.d.ts +16 -0
  347. package/dist/collection/template-catalog.d.ts.map +1 -0
  348. package/dist/collection/template-catalog.js +162 -0
  349. package/dist/collection/template-catalog.js.map +1 -0
  350. package/dist/collection/template.d.ts +37 -0
  351. package/dist/collection/template.d.ts.map +1 -0
  352. package/dist/collection/template.js +73 -0
  353. package/dist/collection/template.js.map +1 -0
  354. package/dist/communication/adapters/email.d.ts +28 -0
  355. package/dist/communication/adapters/email.d.ts.map +1 -0
  356. package/dist/communication/adapters/email.js +129 -0
  357. package/dist/communication/adapters/email.js.map +1 -0
  358. package/dist/communication/adapters/sms.d.ts +95 -0
  359. package/dist/communication/adapters/sms.d.ts.map +1 -0
  360. package/dist/communication/adapters/sms.js +121 -0
  361. package/dist/communication/adapters/sms.js.map +1 -0
  362. package/dist/communication/adapters/whatsapp-language.d.ts +34 -0
  363. package/dist/communication/adapters/whatsapp-language.d.ts.map +1 -0
  364. package/dist/communication/adapters/whatsapp-language.js +36 -0
  365. package/dist/communication/adapters/whatsapp-language.js.map +1 -0
  366. package/dist/communication/adapters/whatsapp-templates.d.ts +18 -0
  367. package/dist/communication/adapters/whatsapp-templates.d.ts.map +1 -0
  368. package/dist/communication/adapters/whatsapp-templates.js +97 -0
  369. package/dist/communication/adapters/whatsapp-templates.js.map +1 -0
  370. package/dist/communication/adapters/whatsapp.d.ts +29 -0
  371. package/dist/communication/adapters/whatsapp.d.ts.map +1 -0
  372. package/dist/communication/adapters/whatsapp.js +210 -0
  373. package/dist/communication/adapters/whatsapp.js.map +1 -0
  374. package/dist/communication/audit.d.ts +105 -0
  375. package/dist/communication/audit.d.ts.map +1 -0
  376. package/dist/communication/audit.js +56 -0
  377. package/dist/communication/audit.js.map +1 -0
  378. package/dist/communication/capabilities.d.ts +88 -0
  379. package/dist/communication/capabilities.d.ts.map +1 -0
  380. package/dist/communication/capabilities.js +72 -0
  381. package/dist/communication/capabilities.js.map +1 -0
  382. package/dist/communication/channel.d.ts +125 -0
  383. package/dist/communication/channel.d.ts.map +1 -0
  384. package/dist/communication/channel.js +47 -0
  385. package/dist/communication/channel.js.map +1 -0
  386. package/dist/communication/claim.d.ts +368 -0
  387. package/dist/communication/claim.d.ts.map +1 -0
  388. package/dist/communication/claim.js +224 -0
  389. package/dist/communication/claim.js.map +1 -0
  390. package/dist/communication/consent.d.ts +65 -0
  391. package/dist/communication/consent.d.ts.map +1 -0
  392. package/dist/communication/consent.js +40 -0
  393. package/dist/communication/consent.js.map +1 -0
  394. package/dist/communication/context.d.ts +48 -0
  395. package/dist/communication/context.d.ts.map +1 -0
  396. package/dist/communication/context.js +41 -0
  397. package/dist/communication/context.js.map +1 -0
  398. package/dist/communication/credentials.d.ts +74 -0
  399. package/dist/communication/credentials.d.ts.map +1 -0
  400. package/dist/communication/credentials.js +115 -0
  401. package/dist/communication/credentials.js.map +1 -0
  402. package/dist/communication/dry-run-scenario.d.ts +37 -0
  403. package/dist/communication/dry-run-scenario.d.ts.map +1 -0
  404. package/dist/communication/dry-run-scenario.js +158 -0
  405. package/dist/communication/dry-run-scenario.js.map +1 -0
  406. package/dist/communication/dry-run.d.ts +40 -0
  407. package/dist/communication/dry-run.d.ts.map +1 -0
  408. package/dist/communication/dry-run.js +92 -0
  409. package/dist/communication/dry-run.js.map +1 -0
  410. package/dist/communication/engine.d.ts +153 -0
  411. package/dist/communication/engine.d.ts.map +1 -0
  412. package/dist/communication/engine.js +480 -0
  413. package/dist/communication/engine.js.map +1 -0
  414. package/dist/communication/graph.d.ts +38 -0
  415. package/dist/communication/graph.d.ts.map +1 -0
  416. package/dist/communication/graph.js +45 -0
  417. package/dist/communication/graph.js.map +1 -0
  418. package/dist/communication/idempotency.d.ts +33 -0
  419. package/dist/communication/idempotency.d.ts.map +1 -0
  420. package/dist/communication/idempotency.js +23 -0
  421. package/dist/communication/idempotency.js.map +1 -0
  422. package/dist/communication/identity.d.ts +127 -0
  423. package/dist/communication/identity.d.ts.map +1 -0
  424. package/dist/communication/identity.js +105 -0
  425. package/dist/communication/identity.js.map +1 -0
  426. package/dist/communication/index.d.ts +66 -0
  427. package/dist/communication/index.d.ts.map +1 -0
  428. package/dist/communication/index.js +42 -0
  429. package/dist/communication/index.js.map +1 -0
  430. package/dist/communication/onboarding.d.ts +223 -0
  431. package/dist/communication/onboarding.d.ts.map +1 -0
  432. package/dist/communication/onboarding.js +287 -0
  433. package/dist/communication/onboarding.js.map +1 -0
  434. package/dist/communication/policy.d.ts +99 -0
  435. package/dist/communication/policy.d.ts.map +1 -0
  436. package/dist/communication/policy.js +13 -0
  437. package/dist/communication/policy.js.map +1 -0
  438. package/dist/communication/routing.d.ts +99 -0
  439. package/dist/communication/routing.d.ts.map +1 -0
  440. package/dist/communication/routing.js +73 -0
  441. package/dist/communication/routing.js.map +1 -0
  442. package/dist/communication/sender-profile.d.ts +100 -0
  443. package/dist/communication/sender-profile.d.ts.map +1 -0
  444. package/dist/communication/sender-profile.js +123 -0
  445. package/dist/communication/sender-profile.js.map +1 -0
  446. package/dist/communication/status.d.ts +48 -0
  447. package/dist/communication/status.d.ts.map +1 -0
  448. package/dist/communication/status.js +79 -0
  449. package/dist/communication/status.js.map +1 -0
  450. package/dist/communication/stores/onboarding.d.ts +88 -0
  451. package/dist/communication/stores/onboarding.d.ts.map +1 -0
  452. package/dist/communication/stores/onboarding.js +127 -0
  453. package/dist/communication/stores/onboarding.js.map +1 -0
  454. package/dist/communication/stores/postgres.d.ts +81 -0
  455. package/dist/communication/stores/postgres.d.ts.map +1 -0
  456. package/dist/communication/stores/postgres.js +453 -0
  457. package/dist/communication/stores/postgres.js.map +1 -0
  458. package/dist/communication/stores/routing.d.ts +169 -0
  459. package/dist/communication/stores/routing.d.ts.map +1 -0
  460. package/dist/communication/stores/routing.js +324 -0
  461. package/dist/communication/stores/routing.js.map +1 -0
  462. package/dist/communication/stores/secrets.d.ts +89 -0
  463. package/dist/communication/stores/secrets.d.ts.map +1 -0
  464. package/dist/communication/stores/secrets.js +122 -0
  465. package/dist/communication/stores/secrets.js.map +1 -0
  466. package/dist/communication/template-provider.d.ts +85 -0
  467. package/dist/communication/template-provider.d.ts.map +1 -0
  468. package/dist/communication/template-provider.js +21 -0
  469. package/dist/communication/template-provider.js.map +1 -0
  470. package/dist/communication/template.d.ts +87 -0
  471. package/dist/communication/template.d.ts.map +1 -0
  472. package/dist/communication/template.js +59 -0
  473. package/dist/communication/template.js.map +1 -0
  474. package/dist/communication/webhook-subscription.d.ts +156 -0
  475. package/dist/communication/webhook-subscription.d.ts.map +1 -0
  476. package/dist/communication/webhook-subscription.js +252 -0
  477. package/dist/communication/webhook-subscription.js.map +1 -0
  478. package/dist/communication/webhook.d.ts +121 -0
  479. package/dist/communication/webhook.d.ts.map +1 -0
  480. package/dist/communication/webhook.js +283 -0
  481. package/dist/communication/webhook.js.map +1 -0
  482. package/dist/competence/repository.d.ts +147 -0
  483. package/dist/competence/repository.d.ts.map +1 -0
  484. package/dist/competence/repository.js +294 -0
  485. package/dist/competence/repository.js.map +1 -0
  486. package/dist/contacts/phone.d.ts +70 -0
  487. package/dist/contacts/phone.d.ts.map +1 -0
  488. package/dist/contacts/phone.js +186 -0
  489. package/dist/contacts/phone.js.map +1 -0
  490. package/dist/db/migrate.js +17 -11
  491. package/dist/db/migrate.js.map +1 -1
  492. package/dist/db/seed-catalog.d.ts +18 -0
  493. package/dist/db/seed-catalog.d.ts.map +1 -0
  494. package/dist/db/seed-catalog.js +45 -0
  495. package/dist/db/seed-catalog.js.map +1 -0
  496. package/dist/db/seed.js +16 -8
  497. package/dist/db/seed.js.map +1 -1
  498. package/dist/documents/repository.d.ts +97 -0
  499. package/dist/documents/repository.d.ts.map +1 -0
  500. package/dist/documents/repository.js +236 -0
  501. package/dist/documents/repository.js.map +1 -0
  502. package/dist/documents/requests.d.ts +73 -0
  503. package/dist/documents/requests.d.ts.map +1 -0
  504. package/dist/documents/requests.js +127 -0
  505. package/dist/documents/requests.js.map +1 -0
  506. package/dist/index.d.ts +109 -13
  507. package/dist/index.d.ts.map +1 -1
  508. package/dist/index.js +100 -8
  509. package/dist/index.js.map +1 -1
  510. package/dist/legal/documents.d.ts.map +1 -1
  511. package/dist/legal/documents.js +125 -3
  512. package/dist/legal/documents.js.map +1 -1
  513. package/dist/legal/index.d.ts +1 -1
  514. package/dist/legal/index.d.ts.map +1 -1
  515. package/dist/legal/types.d.ts +32 -1
  516. package/dist/legal/types.d.ts.map +1 -1
  517. package/dist/legal/types.js +1 -0
  518. package/dist/legal/types.js.map +1 -1
  519. package/dist/mail/auth-templates.d.ts +15 -0
  520. package/dist/mail/auth-templates.d.ts.map +1 -0
  521. package/dist/mail/auth-templates.js +26 -0
  522. package/dist/mail/auth-templates.js.map +1 -0
  523. package/dist/mail/dedup-store.d.ts +1 -24
  524. package/dist/mail/dedup-store.d.ts.map +1 -1
  525. package/dist/mail/dedup-store.js +9 -48
  526. package/dist/mail/dedup-store.js.map +1 -1
  527. package/dist/mail/index.d.ts +2 -1
  528. package/dist/mail/index.d.ts.map +1 -1
  529. package/dist/mail/index.js +13 -2
  530. package/dist/mail/index.js.map +1 -1
  531. package/dist/mail/provider.d.ts +2 -30
  532. package/dist/mail/provider.d.ts.map +1 -1
  533. package/dist/mail/provider.js +10 -246
  534. package/dist/mail/provider.js.map +1 -1
  535. package/dist/mail/resend.d.ts +2 -12
  536. package/dist/mail/resend.d.ts.map +1 -1
  537. package/dist/mail/resend.js +11 -17
  538. package/dist/mail/resend.js.map +1 -1
  539. package/dist/mail/sender-resolver.d.ts +1 -7
  540. package/dist/mail/sender-resolver.d.ts.map +1 -1
  541. package/dist/mail/sender-resolver.js +11 -10
  542. package/dist/mail/sender-resolver.js.map +1 -1
  543. package/dist/mail/template-renderer.d.ts +1 -9
  544. package/dist/mail/template-renderer.d.ts.map +1 -1
  545. package/dist/mail/template-renderer.js +10 -15
  546. package/dist/mail/template-renderer.js.map +1 -1
  547. package/dist/mail/transactional-outbound.d.ts +115 -0
  548. package/dist/mail/transactional-outbound.d.ts.map +1 -0
  549. package/dist/mail/transactional-outbound.js +113 -0
  550. package/dist/mail/transactional-outbound.js.map +1 -0
  551. package/dist/mail/types.d.ts +2 -142
  552. package/dist/mail/types.d.ts.map +1 -1
  553. package/dist/mail/types.js +1 -33
  554. package/dist/mail/types.js.map +1 -1
  555. package/dist/portal/provisioning.d.ts +58 -0
  556. package/dist/portal/provisioning.d.ts.map +1 -0
  557. package/dist/portal/provisioning.js +139 -0
  558. package/dist/portal/provisioning.js.map +1 -0
  559. package/dist/pricing-engine/canonical.d.ts +14 -0
  560. package/dist/pricing-engine/canonical.d.ts.map +1 -0
  561. package/dist/pricing-engine/canonical.js +39 -0
  562. package/dist/pricing-engine/canonical.js.map +1 -0
  563. package/dist/pricing-engine/errors.d.ts.map +1 -1
  564. package/dist/pricing-engine/errors.js +6 -1
  565. package/dist/pricing-engine/errors.js.map +1 -1
  566. package/dist/pricing-engine/index.d.ts +12 -2
  567. package/dist/pricing-engine/index.d.ts.map +1 -1
  568. package/dist/pricing-engine/index.js +6 -1
  569. package/dist/pricing-engine/index.js.map +1 -1
  570. package/dist/pricing-engine/pipeline.d.ts.map +1 -1
  571. package/dist/pricing-engine/pipeline.js +202 -28
  572. package/dist/pricing-engine/pipeline.js.map +1 -1
  573. package/dist/pricing-engine/shadow-adapter.d.ts +37 -0
  574. package/dist/pricing-engine/shadow-adapter.d.ts.map +1 -0
  575. package/dist/pricing-engine/shadow-adapter.js +75 -0
  576. package/dist/pricing-engine/shadow-adapter.js.map +1 -0
  577. package/dist/pricing-engine/shadow-diff.d.ts +26 -0
  578. package/dist/pricing-engine/shadow-diff.d.ts.map +1 -0
  579. package/dist/pricing-engine/shadow-diff.js +52 -0
  580. package/dist/pricing-engine/shadow-diff.js.map +1 -0
  581. package/dist/pricing-engine/shadow-facade.d.ts +42 -0
  582. package/dist/pricing-engine/shadow-facade.d.ts.map +1 -0
  583. package/dist/pricing-engine/shadow-facade.js +82 -0
  584. package/dist/pricing-engine/shadow-facade.js.map +1 -0
  585. package/dist/pricing-engine/shadow-legacy-types.d.ts +64 -0
  586. package/dist/pricing-engine/shadow-legacy-types.d.ts.map +1 -0
  587. package/dist/pricing-engine/shadow-legacy-types.js +18 -0
  588. package/dist/pricing-engine/shadow-legacy-types.js.map +1 -0
  589. package/dist/pricing-engine/shadow-metrics.d.ts +33 -0
  590. package/dist/pricing-engine/shadow-metrics.d.ts.map +1 -0
  591. package/dist/pricing-engine/shadow-metrics.js +31 -0
  592. package/dist/pricing-engine/shadow-metrics.js.map +1 -0
  593. package/dist/pricing-engine/shadow-normalizer.d.ts +17 -0
  594. package/dist/pricing-engine/shadow-normalizer.d.ts.map +1 -0
  595. package/dist/pricing-engine/shadow-normalizer.js +39 -0
  596. package/dist/pricing-engine/shadow-normalizer.js.map +1 -0
  597. package/dist/pricing-engine/types.d.ts +2 -0
  598. package/dist/pricing-engine/types.d.ts.map +1 -1
  599. package/dist/rbac/authorize.d.ts +12 -0
  600. package/dist/rbac/authorize.d.ts.map +1 -1
  601. package/dist/rbac/authorize.js +27 -0
  602. package/dist/rbac/authorize.js.map +1 -1
  603. package/dist/rbac/catalog.d.ts.map +1 -1
  604. package/dist/rbac/catalog.js +67 -1
  605. package/dist/rbac/catalog.js.map +1 -1
  606. package/dist/rbac/workload-provisioning.d.ts +66 -0
  607. package/dist/rbac/workload-provisioning.d.ts.map +1 -0
  608. package/dist/rbac/workload-provisioning.js +153 -0
  609. package/dist/rbac/workload-provisioning.js.map +1 -0
  610. package/dist/rbac/workload.d.ts +124 -0
  611. package/dist/rbac/workload.d.ts.map +1 -0
  612. package/dist/rbac/workload.js +184 -0
  613. package/dist/rbac/workload.js.map +1 -0
  614. package/dist/storage/checksum.d.ts +9 -0
  615. package/dist/storage/checksum.d.ts.map +1 -0
  616. package/dist/storage/checksum.js +12 -0
  617. package/dist/storage/checksum.js.map +1 -0
  618. package/dist/storage/key.d.ts +37 -0
  619. package/dist/storage/key.d.ts.map +1 -0
  620. package/dist/storage/key.js +67 -0
  621. package/dist/storage/key.js.map +1 -0
  622. package/dist/storage/local.d.ts +40 -0
  623. package/dist/storage/local.d.ts.map +1 -0
  624. package/dist/storage/local.js +96 -0
  625. package/dist/storage/local.js.map +1 -0
  626. package/dist/storage/r2.d.ts +43 -0
  627. package/dist/storage/r2.d.ts.map +1 -0
  628. package/dist/storage/r2.js +177 -0
  629. package/dist/storage/r2.js.map +1 -0
  630. package/dist/storage/registry.d.ts +23 -0
  631. package/dist/storage/registry.d.ts.map +1 -0
  632. package/dist/storage/registry.js +37 -0
  633. package/dist/storage/registry.js.map +1 -0
  634. package/dist/storage/types.d.ts +67 -0
  635. package/dist/storage/types.d.ts.map +1 -0
  636. package/dist/storage/types.js +45 -0
  637. package/dist/storage/types.js.map +1 -0
  638. package/dist/subscription-billing/provider/asaas.d.ts +14 -0
  639. package/dist/subscription-billing/provider/asaas.d.ts.map +1 -1
  640. package/dist/subscription-billing/provider/asaas.js +32 -7
  641. package/dist/subscription-billing/provider/asaas.js.map +1 -1
  642. package/dist/subscription-billing/provider/disabled.d.ts +9 -0
  643. package/dist/subscription-billing/provider/disabled.d.ts.map +1 -1
  644. package/dist/subscription-billing/provider/disabled.js +8 -0
  645. package/dist/subscription-billing/provider/disabled.js.map +1 -1
  646. package/dist/subscription-billing/provider/registry.d.ts +10 -0
  647. package/dist/subscription-billing/provider/registry.d.ts.map +1 -1
  648. package/dist/subscription-billing/provider/registry.js +17 -0
  649. package/dist/subscription-billing/provider/registry.js.map +1 -1
  650. package/dist/subscription-billing/service.d.ts +17 -1
  651. package/dist/subscription-billing/service.d.ts.map +1 -1
  652. package/dist/subscription-billing/service.js +57 -8
  653. package/dist/subscription-billing/service.js.map +1 -1
  654. package/dist/subscription-billing/types.d.ts +13 -0
  655. package/dist/subscription-billing/types.d.ts.map +1 -1
  656. package/dist/subscription-billing/types.js.map +1 -1
  657. package/dist/tenancy/provisioning.d.ts.map +1 -1
  658. package/dist/tenancy/provisioning.js +32 -8
  659. package/dist/tenancy/provisioning.js.map +1 -1
  660. package/dist/users/repository.d.ts +38 -0
  661. package/dist/users/repository.d.ts.map +1 -1
  662. package/dist/users/repository.js +118 -3
  663. package/dist/users/repository.js.map +1 -1
  664. package/dist/vault/repository.d.ts +67 -0
  665. package/dist/vault/repository.d.ts.map +1 -1
  666. package/dist/vault/repository.js +78 -0
  667. package/dist/vault/repository.js.map +1 -1
  668. package/package.json +13 -4
  669. package/src/db/migrations/0023_user_invite_activation.sql +15 -0
  670. package/src/db/migrations/0024_set_user_password_function.sql +32 -0
  671. package/src/db/migrations/0025_revoke_user_session_function.sql +28 -0
  672. package/src/db/migrations/0026_documents_and_competence.sql +353 -0
  673. package/src/db/migrations/0027_receivable_client_isolation.sql +58 -0
  674. package/src/db/migrations/0028_collection_engine.sql +94 -0
  675. package/src/db/migrations/0029_payment_rail.sql +107 -0
  676. package/src/db/migrations/0030_provider_account_uniqueness.sql +22 -0
  677. package/src/db/migrations/0031_provider_account_environment_scope.sql +21 -0
  678. package/src/db/migrations/0032_settlement_reversal.sql +76 -0
  679. package/src/db/migrations/0033_receivable_idempotency.sql +28 -0
  680. package/src/db/migrations/0034_payment_customer_reconcile.sql +30 -0
  681. package/src/db/migrations/0035_payment_account_environments.sql +61 -0
  682. package/src/db/migrations/0036_primary_backfill_under_force_rls.sql +41 -0
  683. package/src/db/migrations/0037_receivable_generation_source.sql +29 -0
  684. package/src/db/migrations/0038_notification_channels.sql +175 -0
  685. package/src/db/migrations/0039_communication_dispatch_claim.sql +193 -0
  686. package/src/db/migrations/0040_communication_unknown_outcome.sql +99 -0
  687. package/src/db/migrations/0041_channel_binding_routing.sql +146 -0
  688. package/src/db/migrations/0042_channel_route_read_isolation.sql +165 -0
  689. package/src/db/migrations/0043_workload_identity.sql +105 -0
  690. package/src/db/migrations/0044_channel_onboarding_session.sql +96 -0
  691. package/dist/cjs/mail/resend-client.js +0 -103
  692. package/dist/cjs/mail/resend-client.js.map +0 -1
  693. package/dist/mail/resend-client.d.ts +0 -16
  694. package/dist/mail/resend-client.d.ts.map +0 -1
  695. package/dist/mail/resend-client.js +0 -100
  696. package/dist/mail/resend-client.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel.js","sourceRoot":"","sources":["../../src/collection/channel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * A régua da SC como CONSUMIDORA do motor compartilhado.
3
+ *
4
+ * Esta é a fronteira do adendo §14, e ela cai deste lado: tudo aqui é regra da
5
+ * SC — quais eventos existem, quais variáveis a cobrança expõe, como o texto do
6
+ * escritório vira conteúdo de cada canal. Nada disto entra em
7
+ * `communication/`, porque no dia em que a Dental for o segundo consumidor o
8
+ * motor não pode ter aprendido contabilidade.
9
+ *
10
+ * O caminho inverso também vale: nenhuma linha deste arquivo sabe o que é Meta,
11
+ * Resend ou Twilio.
12
+ */
13
+ import { type ChannelKey, type CommunicationContext, type MessageContent } from '../communication/index.js';
14
+ import type { TenantBranding } from './branding.js';
15
+ import type { EmailBlock } from './email-layout.js';
16
+ /** Slug do produto no ecossistema. Estável — entra em toda chave de idempotência. */
17
+ export declare const SC_PRODUCT = "sc-organizacao-contabil";
18
+ /**
19
+ * Evento de negócio a partir da etapa da régua.
20
+ *
21
+ * Deriva de `stepKey` (`D-3`, `D0`, `D+7`), que é o identificador que o tenant
22
+ * configura e que já garante a idempotência do agendamento. Assim o vocabulário
23
+ * de evento acompanha a régua do escritório em vez de ser uma segunda lista que
24
+ * alguém precisa lembrar de atualizar junto.
25
+ */
26
+ export declare function collectionEventType(stepKey: string): string;
27
+ /** Contexto da SC para um tenant. A marca é a do próprio escritório. */
28
+ export declare function collectionContext(tenantId: string, brand: string): CommunicationContext;
29
+ export interface CollectionVariablesInput {
30
+ clientName: string;
31
+ officeName: string;
32
+ outstandingAmount: number;
33
+ dueDate: string | null;
34
+ reference: string | null;
35
+ paymentUrl?: string;
36
+ }
37
+ /**
38
+ * Variáveis expostas à camada de template, por NOME.
39
+ *
40
+ * O motor as reordena conforme o template declara — a ordem posicional que o
41
+ * WhatsApp exige é resolvida lá, não aqui. Amarrar a ordem neste ponto faria
42
+ * cada template novo do escritório exigir mudança de código.
43
+ */
44
+ export declare function collectionVariables(input: CollectionVariablesInput): Record<string, string>;
45
+ export interface ContentBuilderInput {
46
+ branding: TenantBranding;
47
+ /** Conteúdo estruturado já produzido por `renderCopy`. */
48
+ subject: string;
49
+ block: EmailBlock;
50
+ }
51
+ /**
52
+ * Constrói o conteúdo do canal escolhido — **depois** de o canal ser escolhido.
53
+ *
54
+ * É aqui que o gap G1 da auditoria se fecha. A abstração anterior
55
+ * (`collection/channel.ts`) exigia `subject` + `html` no payload: um adapter de
56
+ * WhatsApp receberia HTML renderizado e teria de desmontá-lo em texto. Agora o
57
+ * e-mail é renderizado só quando o canal é e-mail, e o WhatsApp recebe o que o
58
+ * WhatsApp aceita — template aprovado com variáveis posicionais.
59
+ */
60
+ export declare function buildCollectionContent(input: ContentBuilderInput): (channel: ChannelKey, template: {
61
+ providerTemplateName?: string;
62
+ body?: string;
63
+ subject?: string;
64
+ locale: string;
65
+ }, ordered: string[], variables: Record<string, string>) => MessageContent | null;
66
+ //# sourceMappingURL=communication-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"communication-bridge.d.ts","sourceRoot":"","sources":["../../src/collection/communication-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,KAAK,UAAU,EACf,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAIpD,qFAAqF;AACrF,eAAO,MAAM,UAAU,4BAA4B,CAAC;AAEpD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAQ3D;AAED,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,oBAAoB,CAEvF;AAED,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAa3F;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,cAAc,CAAC;IACzB,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,UAAU,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,mBAAmB,GACzB,CACD,OAAO,EAAE,UAAU,EACnB,QAAQ,EAAE;IAAE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAC5F,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC9B,cAAc,GAAG,IAAI,CAkCzB"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * A régua da SC como CONSUMIDORA do motor compartilhado.
3
+ *
4
+ * Esta é a fronteira do adendo §14, e ela cai deste lado: tudo aqui é regra da
5
+ * SC — quais eventos existem, quais variáveis a cobrança expõe, como o texto do
6
+ * escritório vira conteúdo de cada canal. Nada disto entra em
7
+ * `communication/`, porque no dia em que a Dental for o segundo consumidor o
8
+ * motor não pode ter aprendido contabilidade.
9
+ *
10
+ * O caminho inverso também vale: nenhuma linha deste arquivo sabe o que é Meta,
11
+ * Resend ou Twilio.
12
+ */
13
+ import {} from '../communication/index.js';
14
+ import { renderCollectionEmail, renderCollectionText } from './email-layout.js';
15
+ import { formatBRL, formatDateBR } from './format.js';
16
+ /** Slug do produto no ecossistema. Estável — entra em toda chave de idempotência. */
17
+ export const SC_PRODUCT = 'sc-organizacao-contabil';
18
+ /**
19
+ * Evento de negócio a partir da etapa da régua.
20
+ *
21
+ * Deriva de `stepKey` (`D-3`, `D0`, `D+7`), que é o identificador que o tenant
22
+ * configura e que já garante a idempotência do agendamento. Assim o vocabulário
23
+ * de evento acompanha a régua do escritório em vez de ser uma segunda lista que
24
+ * alguém precisa lembrar de atualizar junto.
25
+ */
26
+ export function collectionEventType(stepKey) {
27
+ const slug = stepKey
28
+ .toLowerCase()
29
+ .replace(/\+/g, 'plus')
30
+ .replace(/-/g, 'minus')
31
+ .replace(/[^a-z0-9]+/g, '_')
32
+ .replace(/^_+|_+$/g, '');
33
+ return `billing.dunning.${slug || 'step'}`;
34
+ }
35
+ /** Contexto da SC para um tenant. A marca é a do próprio escritório. */
36
+ export function collectionContext(tenantId, brand) {
37
+ return { tenantId, product: SC_PRODUCT, brand };
38
+ }
39
+ /**
40
+ * Variáveis expostas à camada de template, por NOME.
41
+ *
42
+ * O motor as reordena conforme o template declara — a ordem posicional que o
43
+ * WhatsApp exige é resolvida lá, não aqui. Amarrar a ordem neste ponto faria
44
+ * cada template novo do escritório exigir mudança de código.
45
+ */
46
+ export function collectionVariables(input) {
47
+ const vars = {
48
+ clientName: input.clientName,
49
+ officeName: input.officeName,
50
+ amount: formatBRL(input.outstandingAmount),
51
+ dueDate: formatDateBR(input.dueDate),
52
+ reference: input.reference ?? '',
53
+ };
54
+ // Só entra quando existe. Uma variável vazia num template de WhatsApp faz a
55
+ // Meta recusar a mensagem inteira — melhor o template não pedir o campo do que
56
+ // o campo chegar em branco.
57
+ if (input.paymentUrl)
58
+ vars.paymentUrl = input.paymentUrl;
59
+ return vars;
60
+ }
61
+ /**
62
+ * Constrói o conteúdo do canal escolhido — **depois** de o canal ser escolhido.
63
+ *
64
+ * É aqui que o gap G1 da auditoria se fecha. A abstração anterior
65
+ * (`collection/channel.ts`) exigia `subject` + `html` no payload: um adapter de
66
+ * WhatsApp receberia HTML renderizado e teria de desmontá-lo em texto. Agora o
67
+ * e-mail é renderizado só quando o canal é e-mail, e o WhatsApp recebe o que o
68
+ * WhatsApp aceita — template aprovado com variáveis posicionais.
69
+ */
70
+ export function buildCollectionContent(input) {
71
+ return (channel, template, ordered, variables) => {
72
+ if (channel === 'email') {
73
+ return {
74
+ kind: 'email',
75
+ subject: template.subject ?? input.subject,
76
+ html: renderCollectionEmail(input.branding, input.block),
77
+ text: renderCollectionText(input.branding, input.block),
78
+ };
79
+ }
80
+ if (channel === 'whatsapp') {
81
+ // Sem template registrado no provider não há envio ativo possível: fora da
82
+ // janela de 24h o WhatsApp só aceita template aprovado. Devolver texto
83
+ // livre aqui produziria uma recusa do provider que pareceria falha do
84
+ // destinatário.
85
+ if (!template.providerTemplateName)
86
+ return null;
87
+ return {
88
+ kind: 'whatsapp_template',
89
+ templateName: template.providerTemplateName,
90
+ language: template.locale,
91
+ variables: ordered,
92
+ };
93
+ }
94
+ if (channel === 'sms' || channel === 'notification') {
95
+ const body = template.body
96
+ ? renderPlain(template.body, variables)
97
+ : plainFromBlock(input.block);
98
+ return { kind: 'text', body };
99
+ }
100
+ return null;
101
+ };
102
+ }
103
+ /**
104
+ * Substituição por ALLOWLIST das variáveis fornecidas — `{{x}}` só resolve se
105
+ * `x` existir. Qualquer outra coisa fica literal e visível.
106
+ *
107
+ * Mesma regra do `template.ts` da cobrança, e pela mesma razão: o texto vem de
108
+ * configuração de tenant, e interpolação livre sobre dado editável pelo usuário
109
+ * é execução arbitrária. Falha à vista é melhor que falha silenciosa.
110
+ */
111
+ function renderPlain(text, vars) {
112
+ return text.replace(/\{\{\s*([a-zA-Z][a-zA-Z0-9]*)\s*\}\}/g, (whole, name) => Object.prototype.hasOwnProperty.call(vars, name) ? vars[name] : whole);
113
+ }
114
+ /**
115
+ * Texto curto a partir do conteúdo estruturado, quando o tenant não configurou
116
+ * corpo próprio.
117
+ *
118
+ * Deliberadamente enxuto: em SMS cada segmento é cobrado, e o corpo de um e-mail
119
+ * de cobrança inteiro custaria cinco. Leva a saudação, o essencial do valor e o
120
+ * link de pagamento quando existe — que é o que faz o cliente agir.
121
+ */
122
+ function plainFromBlock(block) {
123
+ const parts = [block.greeting];
124
+ if (block.highlight) {
125
+ parts.push(`${block.highlight.label}: ${block.highlight.amount} (${block.highlight.dueValue}).`);
126
+ }
127
+ else if (block.paragraphs[0]) {
128
+ parts.push(block.paragraphs[0]);
129
+ }
130
+ if (block.payment?.url)
131
+ parts.push(block.payment.url);
132
+ return parts.join(' ');
133
+ }
134
+ //# sourceMappingURL=communication-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"communication-bridge.js","sourceRoot":"","sources":["../../src/collection/communication-bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Montagem ÚNICA do consumo do motor compartilhado pela cobrança da SC.
3
+ *
4
+ * Este arquivo existe por causa de um defeito de arquitetura, não de código: até
5
+ * aqui havia dois caminhos capazes de mandar mensagem ao cliente.
6
+ *
7
+ * `collection-cron.ts` montava o motor compartilhado — mas SÓ quando o
8
+ * escritório tinha conta de WhatsApp ou SMS. Sem
9
+ * elas, caía no adapter legado.
10
+ * `routes/collections.ts` montava o adapter legado SEMPRE. A rota manual
11
+ * nunca passou pelo motor compartilhado.
12
+ *
13
+ * Dois caminhos com duas idempotências diferentes: o legado usava
14
+ * `receivableId:stepKey` e não gravava nada, o compartilhado usava a chave
15
+ * composta pelo motor. Um cron e um clique no botão "rodar agora", no mesmo
16
+ * minuto, não se enxergavam — e a proteção de cada um era invisível para o
17
+ * outro. É o `LEGACY_SHARED_COEXISTENCE=BLOCKING` do certificador.
18
+ *
19
+ * A correção é ter UM lugar que monta o consumo, e ambos chamarem este. Não é
20
+ * organização de código: é o que faz "existe uma única autoridade de envio" ser
21
+ * uma propriedade verificável em vez de uma intenção.
22
+ */
23
+ import type { Db, Tx } from '../db/client.js';
24
+ import { type ChannelKey, type SmsTransport } from '../communication/index.js';
25
+ import type { TenantBranding } from './branding.js';
26
+ import { SC_PRODUCT } from './communication-bridge.js';
27
+ import type { CollectionCommunication } from './engine.js';
28
+ /**
29
+ * Slug estável da marca do escritório, para o contexto do motor.
30
+ *
31
+ * Vive aqui, e não no cron, porque entra na chave de idempotência: duas
32
+ * derivações do mesmo nome produziriam duas chaves para o mesmo aviso, e a
33
+ * proteção contra envio duplo evaporaria entre o cron e a rota manual sem que
34
+ * nada parecesse errado.
35
+ */
36
+ export declare function brandKeyFor(branding: TenantBranding): string;
37
+ export interface CollectionCommunicationOptions {
38
+ /**
39
+ * Pool. Usado SÓ pela reserva de envio, que precisa de transação própria e
40
+ * curta para ficar visível a outros workers antes do fim do ciclo.
41
+ */
42
+ db: Db;
43
+ /** Transação do ciclo. Templates, consentimento e trilha vivem nela. */
44
+ tx: Tx;
45
+ tenantId: string;
46
+ branding: TenantBranding;
47
+ /**
48
+ * Remetente de e-mail da plataforma — o fallback governado.
49
+ *
50
+ * Explícito no chamador de propósito: enquanto era `process.env.RESEND_*` lido
51
+ * lá dentro, o fallback global era invisível para quem lia a montagem.
52
+ */
53
+ platformEmail: {
54
+ senderId: string;
55
+ credentialRef: string;
56
+ };
57
+ /**
58
+ * Traduz referência lógica de credencial em segredo. O valor nunca volta ao
59
+ * domínio; morre dentro do adapter.
60
+ */
61
+ resolveCredential: (ref: string) => Promise<string | undefined>;
62
+ /**
63
+ * Trava de envio real de WhatsApp. **Desligada por omissão** e ligada só por
64
+ * ato humano com autorização. Ver `adapters/whatsapp.ts`.
65
+ */
66
+ whatsappLiveSend?: boolean;
67
+ /** Transporte de SMS. Ausente = canal não registrado, que é a verdade hoje. */
68
+ smsTransport?: SmsTransport;
69
+ /** Percorre tudo e relata, sem chamar adapter nenhum e sem reservar chave. */
70
+ dryRun?: boolean;
71
+ }
72
+ /**
73
+ * Monta o consumo do motor para UM tenant.
74
+ *
75
+ * Devolve sempre — nunca `undefined`. O desenho anterior devolvia `undefined`
76
+ * quando não havia canal de telefone configurado, e era isso que empurrava o
77
+ * e-mail de volta para o caminho legado. O e-mail é UM canal entre outros; se
78
+ * ele fosse o caso especial, todo canal novo teria de imitá-lo.
79
+ */
80
+ export declare function buildCollectionCommunication(options: CollectionCommunicationOptions): Promise<CollectionCommunication>;
81
+ /**
82
+ * Referência lógica → segredo, a partir do ambiente do processo.
83
+ *
84
+ * O que o tenant configura é o NOME (`RESEND_API_KEY`, `vault://.../whatsapp`);
85
+ * o valor vem daqui e não atravessa o domínio. A allowlist por FORMA do nome
86
+ * (maiúsculas, dígitos e `_`) impede que um `credentialRef` colado no jsonb de
87
+ * configuração de tenant leia qualquer coisa do ambiente do processo — o jsonb é
88
+ * editável por quem administra o escritório, e `PATH` ou `DATABASE_URL` também
89
+ * são variáveis de ambiente.
90
+ */
91
+ export declare function environmentCredentialResolver(): (ref: string) => Promise<string | undefined>;
92
+ /** Canais que este produto sabe operar. Consultado por tela e por teste. */
93
+ export declare const SC_SUPPORTED_CHANNELS: readonly ChannelKey[];
94
+ export { SC_PRODUCT };
95
+ //# sourceMappingURL=communication-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"communication-runtime.d.ts","sourceRoot":"","sources":["../../src/collection/communication-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAWL,KAAK,UAAU,EAEf,KAAK,YAAY,EAClB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,EAAqB,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAG1E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAE3D;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAY5D;AAED,MAAM,WAAW,8BAA8B;IAC7C;;;OAGG;IACH,EAAE,EAAE,EAAE,CAAC;IACP,wEAAwE;IACxE,EAAE,EAAE,EAAE,CAAC;IACP,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,cAAc,CAAC;IACzB;;;;;OAKG;IACH,aAAa,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D;;;OAGG;IACH,iBAAiB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAChE;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,+EAA+E;IAC/E,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,8EAA8E;IAC9E,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,uBAAuB,CAAC,CAoGlC;AAED;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,IAAI,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAoB5F;AAED,4EAA4E;AAC5E,eAAO,MAAM,qBAAqB,EAAE,SAAS,UAAU,EAAiC,CAAC;AAEzF,OAAO,EAAE,UAAU,EAAE,CAAC"}
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Montagem ÚNICA do consumo do motor compartilhado pela cobrança da SC.
3
+ *
4
+ * Este arquivo existe por causa de um defeito de arquitetura, não de código: até
5
+ * aqui havia dois caminhos capazes de mandar mensagem ao cliente.
6
+ *
7
+ * `collection-cron.ts` montava o motor compartilhado — mas SÓ quando o
8
+ * escritório tinha conta de WhatsApp ou SMS. Sem
9
+ * elas, caía no adapter legado.
10
+ * `routes/collections.ts` montava o adapter legado SEMPRE. A rota manual
11
+ * nunca passou pelo motor compartilhado.
12
+ *
13
+ * Dois caminhos com duas idempotências diferentes: o legado usava
14
+ * `receivableId:stepKey` e não gravava nada, o compartilhado usava a chave
15
+ * composta pelo motor. Um cron e um clique no botão "rodar agora", no mesmo
16
+ * minuto, não se enxergavam — e a proteção de cada um era invisível para o
17
+ * outro. É o `LEGACY_SHARED_COEXISTENCE=BLOCKING` do certificador.
18
+ *
19
+ * A correção é ter UM lugar que monta o consumo, e ambos chamarem este. Não é
20
+ * organização de código: é o que faz "existe uma única autoridade de envio" ser
21
+ * uma propriedade verificável em vez de uma intenção.
22
+ */
23
+ import { createEmailChannel, createPostgresAuditSink, createPostgresChannelBindingStore, createPostgresDispatchClaimStore, createSmsChannel, createWhatsAppChannel, credentialResolverFor, resolveSenderProfile, routeAccountsByChannel, withSenderFallback, } from '../communication/index.js';
24
+ import { collectionSenderFallback, createTenantChannelAccountStore } from './channel-accounts.js';
25
+ import { collectionContext, SC_PRODUCT } from './communication-bridge.js';
26
+ import { createConsentStore } from './consent-repository.js';
27
+ import { createCollectionTemplateStore } from './template-catalog.js';
28
+ /**
29
+ * Slug estável da marca do escritório, para o contexto do motor.
30
+ *
31
+ * Vive aqui, e não no cron, porque entra na chave de idempotência: duas
32
+ * derivações do mesmo nome produziriam duas chaves para o mesmo aviso, e a
33
+ * proteção contra envio duplo evaporaria entre o cron e a rota manual sem que
34
+ * nada parecesse errado.
35
+ */
36
+ export function brandKeyFor(branding) {
37
+ const slug = branding.officeName
38
+ .toLowerCase()
39
+ .normalize('NFD')
40
+ .replace(/[\u0300-\u036f]/g, '')
41
+ .replace(/[^a-z0-9]+/g, '-')
42
+ .replace(/^-+|-+$/g, '')
43
+ .slice(0, 60);
44
+ // Nome que não produz slug válido cai num valor fixo do produto, em vez de
45
+ // fazer o motor recusar o contexto e a régua inteira parar por causa de um
46
+ // nome de escritório com caracteres incomuns.
47
+ return /^[a-z][a-z0-9-]*[a-z0-9]$/.test(slug) ? slug : 'baruk-office';
48
+ }
49
+ /**
50
+ * Monta o consumo do motor para UM tenant.
51
+ *
52
+ * Devolve sempre — nunca `undefined`. O desenho anterior devolvia `undefined`
53
+ * quando não havia canal de telefone configurado, e era isso que empurrava o
54
+ * e-mail de volta para o caminho legado. O e-mail é UM canal entre outros; se
55
+ * ele fosse o caso especial, todo canal novo teria de imitá-lo.
56
+ */
57
+ export async function buildCollectionCommunication(options) {
58
+ const { db, tx, tenantId, branding } = options;
59
+ const brand = brandKeyFor(branding);
60
+ const ctx = collectionContext(tenantId, brand);
61
+ const tenantAccounts = createTenantChannelAccountStore(tx);
62
+ /*
63
+ * Telefone tem registro CANÔNICO próprio: `channel_binding` (0041), escrito
64
+ * pelo onboarding do Embedded Signup.
65
+ *
66
+ * Antes desta composição, TODO canal era resolvido por
67
+ * `createTenantChannelAccountStore` — o jsonb `tenant.settings.channels`. O
68
+ * onboarding gravava numa tabela que ninguém lia: a tela dizia "ativo",
69
+ * `GET /v1/communication/channels` dizia `not_configured`, e o motor teria
70
+ * respondido `no_account` no primeiro envio. Canal pronto na Meta e invisível
71
+ * para quem despacha.
72
+ *
73
+ * É o mesmo defeito que `registerChannelBinding` teve na outra ponta — existir
74
+ * e não ser chamado —, agora do lado do consumo.
75
+ */
76
+ const bindingAccounts = createPostgresChannelBindingStore(tx);
77
+ const fallback = collectionSenderFallback(branding, options.platformEmail);
78
+ /*
79
+ * Precedência POR CANAL, explícita — e não um `??` entre dois stores.
80
+ *
81
+ * Um fallback genérico resolveria o sintoma e esconderia a política: ninguém
82
+ * conseguiria dizer, lendo o código, de onde vem a conta de WhatsApp de um
83
+ * escritório. Aqui a resposta é uma linha do mapa.
84
+ *
85
+ * email → configuração do tenant + remetente de plataforma (contrato
86
+ * certificado, intocado)
87
+ * whatsapp → SOMENTE `channel_binding`. Sem fallback para o jsonb: aceitar
88
+ * as duas fontes criaria a segunda verdade que a 0041 existe
89
+ * para eliminar, e o legado sequer satisfaz
90
+ * `channel_binding_phone_credential_ref_chk` (telefone exige
91
+ * `vault://`).
92
+ * sms → mesma regra do WhatsApp.
93
+ *
94
+ * Canal sem rota resolve para ausente. Um canal novo entra fechado.
95
+ */
96
+ const accounts = routeAccountsByChannel({
97
+ email: withSenderFallback(tenantAccounts, fallback),
98
+ whatsapp: bindingAccounts,
99
+ sms: bindingAccounts,
100
+ });
101
+ const channels = {};
102
+ const email = await resolveSenderProfile(tenantAccounts, ctx, 'email', fallback);
103
+ if (email.ok) {
104
+ channels.email = createEmailChannel({
105
+ account: email.profile.account,
106
+ // Resolvedor preso à conta: nenhuma outra referência de credencial passa
107
+ // por aqui, nem por engano de código.
108
+ resolveCredential: credentialResolverFor(email.profile.account, options.resolveCredential),
109
+ });
110
+ }
111
+ // Telefone NUNCA tem fallback de plataforma — o motor recusa por construção,
112
+ // e aqui nem se oferece a opção. Sem conta própria do tenant, o canal
113
+ // simplesmente não existe, e o motor devolve `no_identity`, que é a verdade.
114
+ // Telefone consulta o store do TENANT, sem decoração: o fallback de plataforma
115
+ // é proibido nesses canais, e passar pelo decorado só faria o motor recusar
116
+ // duas vezes.
117
+ const whatsapp = await bindingAccounts.find(ctx, 'whatsapp');
118
+ if (whatsapp) {
119
+ channels.whatsapp = createWhatsAppChannel({
120
+ account: whatsapp,
121
+ resolveCredential: credentialResolverFor(whatsapp, options.resolveCredential),
122
+ liveSend: options.whatsappLiveSend === true,
123
+ });
124
+ }
125
+ const sms = await bindingAccounts.find(ctx, 'sms');
126
+ if (sms && options.smsTransport) {
127
+ // O SMS resolve a própria credencial DENTRO do transporte, e por isso o
128
+ // adapter não a recebe: o contrato de transporte é provider-agnostic e
129
+ // nenhum provider está contratado. Quando houver, a trava de credencial por
130
+ // conta entra na construção do transporte, não aqui.
131
+ channels.sms = createSmsChannel({ account: sms, transport: options.smsTransport });
132
+ }
133
+ // Sem transporte contratado, o canal fica FORA do registry. O motor devolve
134
+ // `channel_not_registered`, que diz a verdade — registrar um adapter sem
135
+ // transporte trocaria esse motivo por uma falha de entrega inexplicável.
136
+ return {
137
+ tenantId,
138
+ brand,
139
+ channels,
140
+ accounts,
141
+ templates: createCollectionTemplateStore(tx),
142
+ consent: createConsentStore(tx),
143
+ // Fail-safe em todo canal de telefone: sem permissão registrada, não sai.
144
+ // O e-mail transacional de cobrança se apoia na relação contratual, e por
145
+ // isso é o único cujo indefinido é tratado como permitido.
146
+ consentPolicy: { onUnknown: { email: 'allow', whatsapp: 'fail_safe', sms: 'fail_safe' } },
147
+ claims: createPostgresDispatchClaimStore(db, tenantId),
148
+ audit: createPostgresAuditSink(tx, tenantId),
149
+ emailSenderOrigin: email.ok ? email.profile.origin : null,
150
+ dryRun: options.dryRun,
151
+ };
152
+ }
153
+ /**
154
+ * Referência lógica → segredo, a partir do ambiente do processo.
155
+ *
156
+ * O que o tenant configura é o NOME (`RESEND_API_KEY`, `vault://.../whatsapp`);
157
+ * o valor vem daqui e não atravessa o domínio. A allowlist por FORMA do nome
158
+ * (maiúsculas, dígitos e `_`) impede que um `credentialRef` colado no jsonb de
159
+ * configuração de tenant leia qualquer coisa do ambiente do processo — o jsonb é
160
+ * editável por quem administra o escritório, e `PATH` ou `DATABASE_URL` também
161
+ * são variáveis de ambiente.
162
+ */
163
+ export function environmentCredentialResolver() {
164
+ // `WHATSAPP_ACCESS_TOKEN` e `SMS_API_KEY` SAÍRAM desta lista na Fase L.
165
+ //
166
+ // Nenhum tenant os usava — não há canal de telefone configurado em lugar
167
+ // nenhum do ecossistema —, então a remoção não interrompe nada. O que ela
168
+ // impede é o desfecho que a lista tornava inevitável no dia em que o SEGUNDO
169
+ // tenant ligasse WhatsApp: ou os dois apontam para o mesmo nome e compartilham
170
+ // o token, ou apontam para nomes distintos e nenhum resolve. Num canal em que
171
+ // o bloqueio se propaga de uma marca para as outras, a primeira opção é a pior
172
+ // das duas — e era a que "funcionava".
173
+ //
174
+ // `RESEND_API_KEY` fica porque a SC entrega e-mail em produção por ela hoje.
175
+ const ALLOWED = new Set(['RESEND_API_KEY']);
176
+ return async (ref) => {
177
+ const name = ref.split('/').pop() ?? '';
178
+ // Allowlist de NOMES, não de forma. Filtrar por padrão deixaria `DATABASE_URL`
179
+ // passar inteiro — o defeito que a política de segredos deste repositório
180
+ // descreve explicitamente.
181
+ return ALLOWED.has(name) ? process.env[name] : undefined;
182
+ };
183
+ }
184
+ /** Canais que este produto sabe operar. Consultado por tela e por teste. */
185
+ export const SC_SUPPORTED_CHANNELS = ['email', 'whatsapp', 'sms'];
186
+ export { SC_PRODUCT };
187
+ //# sourceMappingURL=communication-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"communication-runtime.js","sourceRoot":"","sources":["../../src/collection/communication-runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Permissão de contato do cliente — leitura e escrita.
3
+ *
4
+ * Sobre `client_channel_consent` (migration 0038). A ausência de linha NÃO é
5
+ * permissão: é ausência de decisão, e quem decide o que fazer com ela é a
6
+ * política do tenant, não esta camada.
7
+ */
8
+ import type { Tx } from '../db/client.js';
9
+ import type { ChannelKey, ConsentRecord, ConsentSource, ConsentState, ConsentStore } from '../communication/index.js';
10
+ export declare function createConsentStore(tx: Tx): ConsentStore;
11
+ /** Todas as decisões de um cliente — para a ficha dele na tela. */
12
+ export declare function listClientConsent(tx: Tx, clientId: string): Promise<ConsentRecord[]>;
13
+ export interface RecordConsentInput {
14
+ tenantId: string;
15
+ clientId: string;
16
+ channel: ChannelKey;
17
+ state: ConsentState;
18
+ source: ConsentSource;
19
+ note?: string;
20
+ decidedBy?: string | null;
21
+ }
22
+ /**
23
+ * Registra a decisão. Uma linha viva por (cliente, canal).
24
+ *
25
+ * **Um opt-out do próprio cliente não é revertido por operador.** Quando a linha
26
+ * existente veio de `customer_reply` com `denied`, só outra manifestação do
27
+ * cliente a muda: alguém no escritório desmarcando isso na tela — por engano, ou
28
+ * porque "o cliente disse que pode" — é exatamente o caminho pelo qual uma
29
+ * régua automática passa por cima de um pedido de silêncio.
30
+ */
31
+ export declare function recordConsent(tx: Tx, input: RecordConsentInput): Promise<ConsentRecord>;
32
+ //# sourceMappingURL=consent-repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consent-repository.d.ts","sourceRoot":"","sources":["../../src/collection/consent-repository.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,KAAK,EACV,UAAU,EACV,aAAa,EACb,aAAa,EACb,YAAY,EACZ,YAAY,EACb,MAAM,2BAA2B,CAAC;AAoBnC,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,EAAE,GAAG,YAAY,CAavD;AAED,mEAAmE;AACnE,wBAAsB,iBAAiB,CAAC,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAQ1F;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,UAAU,CAAC;IACpB,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CAgC7F"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Permissão de contato do cliente — leitura e escrita.
3
+ *
4
+ * Sobre `client_channel_consent` (migration 0038). A ausência de linha NÃO é
5
+ * permissão: é ausência de decisão, e quem decide o que fazer com ela é a
6
+ * política do tenant, não esta camada.
7
+ */
8
+ import { uuidv7 } from '@baruk/shared';
9
+ function toRecord(row) {
10
+ return {
11
+ channel: row.channel,
12
+ state: row.state,
13
+ source: row.source,
14
+ decidedAt: row.decided_at instanceof Date ? row.decided_at.toISOString() : String(row.decided_at),
15
+ };
16
+ }
17
+ export function createConsentStore(tx) {
18
+ return {
19
+ async find(recipientRef, channel) {
20
+ const rows = await tx `
21
+ SELECT channel, state, source, decided_at
22
+ FROM client_channel_consent
23
+ WHERE client_id = ${recipientRef} AND channel = ${channel}
24
+ LIMIT 1
25
+ `;
26
+ const row = rows[0];
27
+ return row ? toRecord(row) : null;
28
+ },
29
+ };
30
+ }
31
+ /** Todas as decisões de um cliente — para a ficha dele na tela. */
32
+ export async function listClientConsent(tx, clientId) {
33
+ const rows = await tx `
34
+ SELECT channel, state, source, decided_at
35
+ FROM client_channel_consent
36
+ WHERE client_id = ${clientId}
37
+ ORDER BY channel
38
+ `;
39
+ return rows.map(toRecord);
40
+ }
41
+ /**
42
+ * Registra a decisão. Uma linha viva por (cliente, canal).
43
+ *
44
+ * **Um opt-out do próprio cliente não é revertido por operador.** Quando a linha
45
+ * existente veio de `customer_reply` com `denied`, só outra manifestação do
46
+ * cliente a muda: alguém no escritório desmarcando isso na tela — por engano, ou
47
+ * porque "o cliente disse que pode" — é exatamente o caminho pelo qual uma
48
+ * régua automática passa por cima de um pedido de silêncio.
49
+ */
50
+ export async function recordConsent(tx, input) {
51
+ const existing = await tx `
52
+ SELECT channel, state, source, decided_at
53
+ FROM client_channel_consent
54
+ WHERE client_id = ${input.clientId} AND channel = ${input.channel}
55
+ LIMIT 1
56
+ `;
57
+ const current = existing[0];
58
+ const lockedByCustomer = current?.state === 'denied' && current.source === 'customer_reply';
59
+ if (lockedByCustomer && input.source !== 'customer_reply') {
60
+ return toRecord(current);
61
+ }
62
+ const rows = await tx `
63
+ INSERT INTO client_channel_consent
64
+ (id, tenant_id, client_id, channel, state, source, note, decided_at, decided_by)
65
+ VALUES
66
+ (${uuidv7()}, ${input.tenantId}, ${input.clientId}, ${input.channel},
67
+ ${input.state}, ${input.source}, ${input.note ?? null}, now(), ${input.decidedBy ?? null})
68
+ ON CONFLICT (tenant_id, client_id, channel) DO UPDATE
69
+ SET state = EXCLUDED.state,
70
+ source = EXCLUDED.source,
71
+ note = EXCLUDED.note,
72
+ decided_at = now(),
73
+ decided_by = EXCLUDED.decided_by,
74
+ updated_at = now()
75
+ RETURNING channel, state, source, decided_at
76
+ `;
77
+ return toRecord(rows[0]);
78
+ }
79
+ //# sourceMappingURL=consent-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consent-repository.js","sourceRoot":"","sources":["../../src/collection/consent-repository.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AASvC,SAAS,QAAQ,CAAC,GAAQ;IACxB,OAAO;QACL,OAAO,EAAE,GAAG,CAAC,OAAqB;QAClC,KAAK,EAAE,GAAG,CAAC,KAAqB;QAChC,MAAM,EAAE,GAAG,CAAC,MAAuB;QACnC,SAAS,EACP,GAAG,CAAC,UAAU,YAAY,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC;KACzF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,EAAM;IACvC,OAAO;QACL,KAAK,CAAC,IAAI,CAAC,YAAoB,EAAE,OAAmB;YAClD,MAAM,IAAI,GAAG,MAAM,EAAE,CAAO;;;6BAGL,YAAY,kBAAkB,OAAO;;OAE3D,CAAC;YACF,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACpB,OAAO,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACpC,CAAC;KACF,CAAC;AACJ,CAAC;AAED,mEAAmE;AACnE,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,EAAM,EAAE,QAAgB;IAC9D,MAAM,IAAI,GAAG,MAAM,EAAE,CAAO;;;yBAGL,QAAQ;;GAE9B,CAAC;IACF,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAC5B,CAAC;AAYD;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAAM,EAAE,KAAyB;IACnE,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAO;;;yBAGT,KAAK,CAAC,QAAQ,kBAAkB,KAAK,CAAC,OAAO;;GAEnE,CAAC;IAEF,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC5B,MAAM,gBAAgB,GAAG,OAAO,EAAE,KAAK,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,KAAK,gBAAgB,CAAC;IAE5F,IAAI,gBAAgB,IAAI,KAAK,CAAC,MAAM,KAAK,gBAAgB,EAAE,CAAC;QAC1D,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,EAAE,CAAO;;;;SAIrB,MAAM,EAAE,KAAK,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,OAAO;SAChE,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,IAAI,IAAI,IAAI,YAAY,KAAK,CAAC,SAAS,IAAI,IAAI;;;;;;;;;GAS5F,CAAC;IAEF,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC;AAC5B,CAAC"}