@baruk/core 0.3.1 → 0.5.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 (1047) hide show
  1. package/.baruk-provenance.json +10 -0
  2. package/CHANGELOG.md +127 -0
  3. package/dist/audit/repository.d.ts +33 -1
  4. package/dist/audit/repository.d.ts.map +1 -1
  5. package/dist/audit/repository.js +41 -7
  6. package/dist/audit/repository.js.map +1 -1
  7. package/dist/auth/password-reset.d.ts +30 -1
  8. package/dist/auth/password-reset.d.ts.map +1 -1
  9. package/dist/auth/password-reset.js +139 -11
  10. package/dist/auth/password-reset.js.map +1 -1
  11. package/dist/auth/service.d.ts +60 -2
  12. package/dist/auth/service.d.ts.map +1 -1
  13. package/dist/auth/service.js +121 -11
  14. package/dist/auth/service.js.map +1 -1
  15. package/dist/billing/ar-repository.d.ts +374 -0
  16. package/dist/billing/ar-repository.d.ts.map +1 -0
  17. package/dist/billing/ar-repository.js +783 -0
  18. package/dist/billing/ar-repository.js.map +1 -0
  19. package/dist/billing/auto-generation.d.ts +87 -0
  20. package/dist/billing/auto-generation.d.ts.map +1 -0
  21. package/dist/billing/auto-generation.js +181 -0
  22. package/dist/billing/auto-generation.js.map +1 -0
  23. package/dist/billing/live-guard.d.ts +64 -0
  24. package/dist/billing/live-guard.d.ts.map +1 -0
  25. package/dist/billing/live-guard.js +68 -0
  26. package/dist/billing/live-guard.js.map +1 -0
  27. package/dist/billing/payment-means-catalog.d.ts +17 -0
  28. package/dist/billing/payment-means-catalog.d.ts.map +1 -0
  29. package/dist/billing/payment-means-catalog.js +21 -0
  30. package/dist/billing/payment-means-catalog.js.map +1 -0
  31. package/dist/billing/payment-means.d.ts +38 -0
  32. package/dist/billing/payment-means.d.ts.map +1 -0
  33. package/dist/billing/payment-means.js +29 -0
  34. package/dist/billing/payment-means.js.map +1 -0
  35. package/dist/billing/payment-rail.d.ts +118 -0
  36. package/dist/billing/payment-rail.d.ts.map +1 -0
  37. package/dist/billing/payment-rail.js +295 -0
  38. package/dist/billing/payment-rail.js.map +1 -0
  39. package/dist/billing/provider/asaas.d.ts +46 -1
  40. package/dist/billing/provider/asaas.d.ts.map +1 -1
  41. package/dist/billing/provider/asaas.js +194 -14
  42. package/dist/billing/provider/asaas.js.map +1 -1
  43. package/dist/billing/provider/manual.js +1 -1
  44. package/dist/billing/provider/manual.js.map +1 -1
  45. package/dist/billing/provider/types.d.ts +115 -8
  46. package/dist/billing/provider/types.d.ts.map +1 -1
  47. package/dist/billing/provider-account.d.ts +127 -0
  48. package/dist/billing/provider-account.d.ts.map +1 -0
  49. package/dist/billing/provider-account.js +217 -0
  50. package/dist/billing/provider-account.js.map +1 -0
  51. package/dist/billing/provider-onboarding.d.ts +67 -0
  52. package/dist/billing/provider-onboarding.d.ts.map +1 -0
  53. package/dist/billing/provider-onboarding.js +234 -0
  54. package/dist/billing/provider-onboarding.js.map +1 -0
  55. package/dist/billing/receivable.d.ts +5 -1
  56. package/dist/billing/receivable.d.ts.map +1 -1
  57. package/dist/billing/reconcile.d.ts +58 -0
  58. package/dist/billing/reconcile.d.ts.map +1 -0
  59. package/dist/billing/reconcile.js +138 -0
  60. package/dist/billing/reconcile.js.map +1 -0
  61. package/dist/billing/repository.d.ts +134 -1
  62. package/dist/billing/repository.d.ts.map +1 -1
  63. package/dist/billing/repository.js +193 -20
  64. package/dist/billing/repository.js.map +1 -1
  65. package/dist/cjs/audit/repository.js +41 -7
  66. package/dist/cjs/audit/repository.js.map +1 -1
  67. package/dist/cjs/auth/password-reset.js +141 -11
  68. package/dist/cjs/auth/password-reset.js.map +1 -1
  69. package/dist/cjs/auth/service.js +121 -10
  70. package/dist/cjs/auth/service.js.map +1 -1
  71. package/dist/cjs/billing/ar-repository.js +804 -0
  72. package/dist/cjs/billing/ar-repository.js.map +1 -0
  73. package/dist/cjs/billing/auto-generation.js +186 -0
  74. package/dist/cjs/billing/auto-generation.js.map +1 -0
  75. package/dist/cjs/billing/live-guard.js +72 -0
  76. package/dist/cjs/billing/live-guard.js.map +1 -0
  77. package/dist/cjs/billing/payment-means-catalog.js +25 -0
  78. package/dist/cjs/billing/payment-means-catalog.js.map +1 -0
  79. package/dist/cjs/billing/payment-means.js +33 -0
  80. package/dist/cjs/billing/payment-means.js.map +1 -0
  81. package/dist/cjs/billing/payment-rail.js +301 -0
  82. package/dist/cjs/billing/payment-rail.js.map +1 -0
  83. package/dist/cjs/billing/provider/asaas.js +194 -14
  84. package/dist/cjs/billing/provider/asaas.js.map +1 -1
  85. package/dist/cjs/billing/provider/manual.js +1 -1
  86. package/dist/cjs/billing/provider/manual.js.map +1 -1
  87. package/dist/cjs/billing/provider-account.js +229 -0
  88. package/dist/cjs/billing/provider-account.js.map +1 -0
  89. package/dist/cjs/billing/provider-onboarding.js +239 -0
  90. package/dist/cjs/billing/provider-onboarding.js.map +1 -0
  91. package/dist/cjs/billing/reconcile.js +143 -0
  92. package/dist/cjs/billing/reconcile.js.map +1 -0
  93. package/dist/cjs/billing/repository.js +197 -19
  94. package/dist/cjs/billing/repository.js.map +1 -1
  95. package/dist/cjs/clients/ibge.js +103 -0
  96. package/dist/cjs/clients/ibge.js.map +1 -0
  97. package/dist/cjs/clients/repository.js +276 -23
  98. package/dist/cjs/clients/repository.js.map +1 -1
  99. package/dist/cjs/collection/branding.js +330 -0
  100. package/dist/cjs/collection/branding.js.map +1 -0
  101. package/dist/cjs/collection/channel-accounts.js +137 -0
  102. package/dist/cjs/collection/channel-accounts.js.map +1 -0
  103. package/dist/cjs/collection/channel.js +17 -0
  104. package/dist/cjs/collection/channel.js.map +1 -0
  105. package/dist/cjs/collection/clearance-store.js +74 -0
  106. package/dist/cjs/collection/clearance-store.js.map +1 -0
  107. package/dist/cjs/collection/communication-bridge.js +140 -0
  108. package/dist/cjs/collection/communication-bridge.js.map +1 -0
  109. package/dist/cjs/collection/communication-runtime.js +256 -0
  110. package/dist/cjs/collection/communication-runtime.js.map +1 -0
  111. package/dist/cjs/collection/consent-repository.js +84 -0
  112. package/dist/cjs/collection/consent-repository.js.map +1 -0
  113. package/dist/cjs/collection/copy.js +125 -0
  114. package/dist/cjs/collection/copy.js.map +1 -0
  115. package/dist/cjs/collection/delivery-callback.js +151 -0
  116. package/dist/cjs/collection/delivery-callback.js.map +1 -0
  117. package/dist/cjs/collection/email-layout.js +252 -0
  118. package/dist/cjs/collection/email-layout.js.map +1 -0
  119. package/dist/cjs/collection/engine.js +434 -0
  120. package/dist/cjs/collection/engine.js.map +1 -0
  121. package/dist/cjs/collection/format.js +76 -0
  122. package/dist/cjs/collection/format.js.map +1 -0
  123. package/dist/cjs/collection/payment-block.js +3 -0
  124. package/dist/cjs/collection/payment-block.js.map +1 -0
  125. package/dist/cjs/collection/policy.js +175 -0
  126. package/dist/cjs/collection/policy.js.map +1 -0
  127. package/dist/cjs/collection/repository.js +260 -0
  128. package/dist/cjs/collection/repository.js.map +1 -0
  129. package/dist/cjs/collection/subject.js +104 -0
  130. package/dist/cjs/collection/subject.js.map +1 -0
  131. package/dist/cjs/collection/template-catalog.js +165 -0
  132. package/dist/cjs/collection/template-catalog.js.map +1 -0
  133. package/dist/cjs/collection/template.js +78 -0
  134. package/dist/cjs/collection/template.js.map +1 -0
  135. package/dist/cjs/communication/adapters/email.js +132 -0
  136. package/dist/cjs/communication/adapters/email.js.map +1 -0
  137. package/dist/cjs/communication/adapters/sms.js +127 -0
  138. package/dist/cjs/communication/adapters/sms.js.map +1 -0
  139. package/dist/cjs/communication/adapters/whatsapp-language.js +39 -0
  140. package/dist/cjs/communication/adapters/whatsapp-language.js.map +1 -0
  141. package/dist/cjs/communication/adapters/whatsapp-templates.js +100 -0
  142. package/dist/cjs/communication/adapters/whatsapp-templates.js.map +1 -0
  143. package/dist/cjs/communication/adapters/whatsapp.js +213 -0
  144. package/dist/cjs/communication/adapters/whatsapp.js.map +1 -0
  145. package/dist/cjs/communication/audit.js +61 -0
  146. package/dist/cjs/communication/audit.js.map +1 -0
  147. package/dist/cjs/communication/capabilities.js +76 -0
  148. package/dist/cjs/communication/capabilities.js.map +1 -0
  149. package/dist/cjs/communication/channel.js +53 -0
  150. package/dist/cjs/communication/channel.js.map +1 -0
  151. package/dist/cjs/communication/claim.js +228 -0
  152. package/dist/cjs/communication/claim.js.map +1 -0
  153. package/dist/cjs/communication/clearance.js +18 -0
  154. package/dist/cjs/communication/clearance.js.map +1 -0
  155. package/dist/cjs/communication/consent.js +43 -0
  156. package/dist/cjs/communication/consent.js.map +1 -0
  157. package/dist/cjs/communication/context.js +45 -0
  158. package/dist/cjs/communication/context.js.map +1 -0
  159. package/dist/cjs/communication/credentials.js +121 -0
  160. package/dist/cjs/communication/credentials.js.map +1 -0
  161. package/dist/cjs/communication/dry-run-scenario.js +166 -0
  162. package/dist/cjs/communication/dry-run-scenario.js.map +1 -0
  163. package/dist/cjs/communication/dry-run.js +97 -0
  164. package/dist/cjs/communication/dry-run.js.map +1 -0
  165. package/dist/cjs/communication/engine.js +495 -0
  166. package/dist/cjs/communication/engine.js.map +1 -0
  167. package/dist/cjs/communication/graph.js +50 -0
  168. package/dist/cjs/communication/graph.js.map +1 -0
  169. package/dist/cjs/communication/idempotency.js +26 -0
  170. package/dist/cjs/communication/idempotency.js.map +1 -0
  171. package/dist/cjs/communication/identity.js +110 -0
  172. package/dist/cjs/communication/identity.js.map +1 -0
  173. package/dist/cjs/communication/index.js +135 -0
  174. package/dist/cjs/communication/index.js.map +1 -0
  175. package/dist/cjs/communication/onboarding.js +297 -0
  176. package/dist/cjs/communication/onboarding.js.map +1 -0
  177. package/dist/cjs/communication/policy.js +16 -0
  178. package/dist/cjs/communication/policy.js.map +1 -0
  179. package/dist/cjs/communication/routing.js +77 -0
  180. package/dist/cjs/communication/routing.js.map +1 -0
  181. package/dist/cjs/communication/sender-profile.js +128 -0
  182. package/dist/cjs/communication/sender-profile.js.map +1 -0
  183. package/dist/cjs/communication/status.js +86 -0
  184. package/dist/cjs/communication/status.js.map +1 -0
  185. package/dist/cjs/communication/stores/onboarding.js +135 -0
  186. package/dist/cjs/communication/stores/onboarding.js.map +1 -0
  187. package/dist/cjs/communication/stores/postgres.js +458 -0
  188. package/dist/cjs/communication/stores/postgres.js.map +1 -0
  189. package/dist/cjs/communication/stores/routing.js +334 -0
  190. package/dist/cjs/communication/stores/routing.js.map +1 -0
  191. package/dist/cjs/communication/stores/secrets.js +126 -0
  192. package/dist/cjs/communication/stores/secrets.js.map +1 -0
  193. package/dist/cjs/communication/template-provider.js +22 -0
  194. package/dist/cjs/communication/template-provider.js.map +1 -0
  195. package/dist/cjs/communication/template.js +63 -0
  196. package/dist/cjs/communication/template.js.map +1 -0
  197. package/dist/cjs/communication/webhook-subscription.js +258 -0
  198. package/dist/cjs/communication/webhook-subscription.js.map +1 -0
  199. package/dist/cjs/communication/webhook.js +292 -0
  200. package/dist/cjs/communication/webhook.js.map +1 -0
  201. package/dist/cjs/competence/business-days.js +155 -0
  202. package/dist/cjs/competence/business-days.js.map +1 -0
  203. package/dist/cjs/competence/catalog-validation.js +174 -0
  204. package/dist/cjs/competence/catalog-validation.js.map +1 -0
  205. package/dist/cjs/competence/obligation-preview.js +190 -0
  206. package/dist/cjs/competence/obligation-preview.js.map +1 -0
  207. package/dist/cjs/competence/repository.js +622 -0
  208. package/dist/cjs/competence/repository.js.map +1 -0
  209. package/dist/cjs/contacts/phone.js +192 -0
  210. package/dist/cjs/contacts/phone.js.map +1 -0
  211. package/dist/cjs/dashboard/pilot-panel.js +90 -0
  212. package/dist/cjs/dashboard/pilot-panel.js.map +1 -0
  213. package/dist/cjs/dashboard/repository.js +11 -1
  214. package/dist/cjs/dashboard/repository.js.map +1 -1
  215. package/dist/cjs/db/client.js +17 -11
  216. package/dist/cjs/db/client.js.map +1 -1
  217. package/dist/cjs/db/provision-e2e-identity.js +111 -0
  218. package/dist/cjs/db/provision-e2e-identity.js.map +1 -0
  219. package/dist/cjs/db/seed-catalog.js +48 -0
  220. package/dist/cjs/db/seed-catalog.js.map +1 -0
  221. package/dist/cjs/db/seed.js +15 -7
  222. package/dist/cjs/db/seed.js.map +1 -1
  223. package/dist/cjs/documents/repository.js +244 -0
  224. package/dist/cjs/documents/repository.js.map +1 -0
  225. package/dist/cjs/documents/requests.js +136 -0
  226. package/dist/cjs/documents/requests.js.map +1 -0
  227. package/dist/cjs/fiscal/applicability.js +164 -0
  228. package/dist/cjs/fiscal/applicability.js.map +1 -0
  229. package/dist/cjs/fiscal/conditions.js +198 -0
  230. package/dist/cjs/fiscal/conditions.js.map +1 -0
  231. package/dist/cjs/fiscal/contracts/nfse-adn-contract.js +390 -0
  232. package/dist/cjs/fiscal/contracts/nfse-adn-contract.js.map +1 -0
  233. package/dist/cjs/fiscal/contracts/nfse-adn-endpoint.js +108 -0
  234. package/dist/cjs/fiscal/contracts/nfse-adn-endpoint.js.map +1 -0
  235. package/dist/cjs/fiscal/contracts/nfse-adn-envelope.js +220 -0
  236. package/dist/cjs/fiscal/contracts/nfse-adn-envelope.js.map +1 -0
  237. package/dist/cjs/fiscal/coverage/model.js +127 -0
  238. package/dist/cjs/fiscal/coverage/model.js.map +1 -0
  239. package/dist/cjs/fiscal/coverage/requests.js +99 -0
  240. package/dist/cjs/fiscal/coverage/requests.js.map +1 -0
  241. package/dist/cjs/fiscal/credentials/material.js +168 -0
  242. package/dist/cjs/fiscal/credentials/material.js.map +1 -0
  243. package/dist/cjs/fiscal/credentials/readiness.js +163 -0
  244. package/dist/cjs/fiscal/credentials/readiness.js.map +1 -0
  245. package/dist/cjs/fiscal/eligibility.js +199 -0
  246. package/dist/cjs/fiscal/eligibility.js.map +1 -0
  247. package/dist/cjs/fiscal/ingestion/__fixtures__/nfse.js +128 -0
  248. package/dist/cjs/fiscal/ingestion/__fixtures__/nfse.js.map +1 -0
  249. package/dist/cjs/fiscal/ingestion/adn-transport.js +229 -0
  250. package/dist/cjs/fiscal/ingestion/adn-transport.js.map +1 -0
  251. package/dist/cjs/fiscal/ingestion/direction.js +36 -0
  252. package/dist/cjs/fiscal/ingestion/direction.js.map +1 -0
  253. package/dist/cjs/fiscal/ingestion/nfse-adn.js +228 -0
  254. package/dist/cjs/fiscal/ingestion/nfse-adn.js.map +1 -0
  255. package/dist/cjs/fiscal/ingestion/pipeline.js +704 -0
  256. package/dist/cjs/fiscal/ingestion/pipeline.js.map +1 -0
  257. package/dist/cjs/fiscal/ingestion/provider.js +51 -0
  258. package/dist/cjs/fiscal/ingestion/provider.js.map +1 -0
  259. package/dist/cjs/fiscal/ingestion/repository.js +132 -0
  260. package/dist/cjs/fiscal/ingestion/repository.js.map +1 -0
  261. package/dist/cjs/fiscal/ingestion/synthetic-provider.js +103 -0
  262. package/dist/cjs/fiscal/ingestion/synthetic-provider.js.map +1 -0
  263. package/dist/cjs/fiscal/ingestion/synthetic-transport-types.js +13 -0
  264. package/dist/cjs/fiscal/ingestion/synthetic-transport-types.js.map +1 -0
  265. package/dist/cjs/fiscal/ingestion/synthetic-transport.js +61 -0
  266. package/dist/cjs/fiscal/ingestion/synthetic-transport.js.map +1 -0
  267. package/dist/cjs/fiscal/ingestion/xml-reader.js +121 -0
  268. package/dist/cjs/fiscal/ingestion/xml-reader.js.map +1 -0
  269. package/dist/cjs/fiscal/repository.js +470 -0
  270. package/dist/cjs/fiscal/repository.js.map +1 -0
  271. package/dist/cjs/fiscal/sync/circuit.js +124 -0
  272. package/dist/cjs/fiscal/sync/circuit.js.map +1 -0
  273. package/dist/cjs/fiscal/sync/intervention.js +140 -0
  274. package/dist/cjs/fiscal/sync/intervention.js.map +1 -0
  275. package/dist/cjs/fiscal/sync/lease.js +146 -0
  276. package/dist/cjs/fiscal/sync/lease.js.map +1 -0
  277. package/dist/cjs/fiscal/sync/observability.js +244 -0
  278. package/dist/cjs/fiscal/sync/observability.js.map +1 -0
  279. package/dist/cjs/fiscal/sync/orchestrator.js +490 -0
  280. package/dist/cjs/fiscal/sync/orchestrator.js.map +1 -0
  281. package/dist/cjs/fiscal/sync/policy.js +143 -0
  282. package/dist/cjs/fiscal/sync/policy.js.map +1 -0
  283. package/dist/cjs/fiscal/sync/reprocess.js +241 -0
  284. package/dist/cjs/fiscal/sync/reprocess.js.map +1 -0
  285. package/dist/cjs/fiscal/sync/retry.js +183 -0
  286. package/dist/cjs/fiscal/sync/retry.js.map +1 -0
  287. package/dist/cjs/fiscal/sync/secret-boundary.js +123 -0
  288. package/dist/cjs/fiscal/sync/secret-boundary.js.map +1 -0
  289. package/dist/cjs/fiscal/transport/https.js +309 -0
  290. package/dist/cjs/fiscal/transport/https.js.map +1 -0
  291. package/dist/cjs/fiscal/transport/synthetic-tls.js +328 -0
  292. package/dist/cjs/fiscal/transport/synthetic-tls.js.map +1 -0
  293. package/dist/cjs/fiscal/transport/types.js +93 -0
  294. package/dist/cjs/fiscal/transport/types.js.map +1 -0
  295. package/dist/cjs/import/br-documents.js +85 -0
  296. package/dist/cjs/import/br-documents.js.map +1 -0
  297. package/dist/cjs/import/clients-import.js +347 -40
  298. package/dist/cjs/import/clients-import.js.map +1 -1
  299. package/dist/cjs/index.js +711 -39
  300. package/dist/cjs/index.js.map +1 -1
  301. package/dist/cjs/legal/documents.js +224 -17
  302. package/dist/cjs/legal/documents.js.map +1 -1
  303. package/dist/cjs/legal/index.js +3 -1
  304. package/dist/cjs/legal/index.js.map +1 -1
  305. package/dist/cjs/legal/types.js +1 -0
  306. package/dist/cjs/legal/types.js.map +1 -1
  307. package/dist/cjs/mail/auth-templates.js +29 -0
  308. package/dist/cjs/mail/auth-templates.js.map +1 -0
  309. package/dist/cjs/mail/dedup-store.js +12 -51
  310. package/dist/cjs/mail/dedup-store.js.map +1 -1
  311. package/dist/cjs/mail/index.js +16 -4
  312. package/dist/cjs/mail/index.js.map +1 -1
  313. package/dist/cjs/mail/provider.js +12 -247
  314. package/dist/cjs/mail/provider.js.map +1 -1
  315. package/dist/cjs/mail/resend.js +14 -18
  316. package/dist/cjs/mail/resend.js.map +1 -1
  317. package/dist/cjs/mail/sender-resolver.js +12 -11
  318. package/dist/cjs/mail/sender-resolver.js.map +1 -1
  319. package/dist/cjs/mail/template-renderer.js +11 -16
  320. package/dist/cjs/mail/template-renderer.js.map +1 -1
  321. package/dist/cjs/mail/transactional-outbound.js +117 -0
  322. package/dist/cjs/mail/transactional-outbound.js.map +1 -0
  323. package/dist/cjs/mail/types.js +8 -35
  324. package/dist/cjs/mail/types.js.map +1 -1
  325. package/dist/cjs/onboarding/persistence.js +4 -4
  326. package/dist/cjs/onboarding/persistence.js.map +1 -1
  327. package/dist/cjs/pilot/go-live-checklist.js +212 -0
  328. package/dist/cjs/pilot/go-live-checklist.js.map +1 -0
  329. package/dist/cjs/pilot/milestone.js +79 -0
  330. package/dist/cjs/pilot/milestone.js.map +1 -0
  331. package/dist/cjs/platform/capabilities.js +144 -0
  332. package/dist/cjs/platform/capabilities.js.map +1 -0
  333. package/dist/cjs/platform/job-contract.js +411 -0
  334. package/dist/cjs/platform/job-contract.js.map +1 -0
  335. package/dist/cjs/portal/provisioning.js +144 -0
  336. package/dist/cjs/portal/provisioning.js.map +1 -0
  337. package/dist/cjs/pricing-engine/canonical.js +42 -0
  338. package/dist/cjs/pricing-engine/canonical.js.map +1 -0
  339. package/dist/cjs/pricing-engine/errors.js +6 -1
  340. package/dist/cjs/pricing-engine/errors.js.map +1 -1
  341. package/dist/cjs/pricing-engine/index.js +12 -1
  342. package/dist/cjs/pricing-engine/index.js.map +1 -1
  343. package/dist/cjs/pricing-engine/pipeline.js +200 -26
  344. package/dist/cjs/pricing-engine/pipeline.js.map +1 -1
  345. package/dist/cjs/pricing-engine/shadow-adapter.js +79 -0
  346. package/dist/cjs/pricing-engine/shadow-adapter.js.map +1 -0
  347. package/dist/cjs/pricing-engine/shadow-diff.js +55 -0
  348. package/dist/cjs/pricing-engine/shadow-diff.js.map +1 -0
  349. package/dist/cjs/pricing-engine/shadow-facade.js +85 -0
  350. package/dist/cjs/pricing-engine/shadow-facade.js.map +1 -0
  351. package/dist/cjs/pricing-engine/shadow-legacy-types.js +19 -0
  352. package/dist/cjs/pricing-engine/shadow-legacy-types.js.map +1 -0
  353. package/dist/cjs/pricing-engine/shadow-metrics.js +34 -0
  354. package/dist/cjs/pricing-engine/shadow-metrics.js.map +1 -0
  355. package/dist/cjs/pricing-engine/shadow-normalizer.js +42 -0
  356. package/dist/cjs/pricing-engine/shadow-normalizer.js.map +1 -0
  357. package/dist/cjs/rbac/authorize.js +28 -0
  358. package/dist/cjs/rbac/authorize.js.map +1 -1
  359. package/dist/cjs/rbac/catalog.js +101 -1
  360. package/dist/cjs/rbac/catalog.js.map +1 -1
  361. package/dist/cjs/rbac/workload-provisioning.js +160 -0
  362. package/dist/cjs/rbac/workload-provisioning.js.map +1 -0
  363. package/dist/cjs/rbac/workload.js +191 -0
  364. package/dist/cjs/rbac/workload.js.map +1 -0
  365. package/dist/cjs/storage/checksum.js +15 -0
  366. package/dist/cjs/storage/checksum.js.map +1 -0
  367. package/dist/cjs/storage/key.js +72 -0
  368. package/dist/cjs/storage/key.js.map +1 -0
  369. package/dist/cjs/storage/local.js +100 -0
  370. package/dist/cjs/storage/local.js.map +1 -0
  371. package/dist/cjs/storage/r2.js +181 -0
  372. package/dist/cjs/storage/r2.js.map +1 -0
  373. package/dist/cjs/storage/registry.js +41 -0
  374. package/dist/cjs/storage/registry.js.map +1 -0
  375. package/dist/cjs/storage/types.js +50 -0
  376. package/dist/cjs/storage/types.js.map +1 -0
  377. package/dist/cjs/subscription-billing/index.js +2 -1
  378. package/dist/cjs/subscription-billing/index.js.map +1 -1
  379. package/dist/cjs/subscription-billing/provider/asaas.js +32 -7
  380. package/dist/cjs/subscription-billing/provider/asaas.js.map +1 -1
  381. package/dist/cjs/subscription-billing/provider/disabled.js +8 -0
  382. package/dist/cjs/subscription-billing/provider/disabled.js.map +1 -1
  383. package/dist/cjs/subscription-billing/provider/registry.js +17 -0
  384. package/dist/cjs/subscription-billing/provider/registry.js.map +1 -1
  385. package/dist/cjs/subscription-billing/service.js +208 -83
  386. package/dist/cjs/subscription-billing/service.js.map +1 -1
  387. package/dist/cjs/subscription-billing/types.js.map +1 -1
  388. package/dist/cjs/tenancy/features.js +131 -0
  389. package/dist/cjs/tenancy/features.js.map +1 -0
  390. package/dist/cjs/tenancy/provisioning.js +32 -8
  391. package/dist/cjs/tenancy/provisioning.js.map +1 -1
  392. package/dist/cjs/tenancy/settings.js +224 -0
  393. package/dist/cjs/tenancy/settings.js.map +1 -0
  394. package/dist/cjs/users/repository.js +143 -3
  395. package/dist/cjs/users/repository.js.map +1 -1
  396. package/dist/cjs/vault/repository.js +81 -0
  397. package/dist/cjs/vault/repository.js.map +1 -1
  398. package/dist/clients/ibge.d.ts +17 -0
  399. package/dist/clients/ibge.d.ts.map +1 -0
  400. package/dist/clients/ibge.js +98 -0
  401. package/dist/clients/ibge.js.map +1 -0
  402. package/dist/clients/repository.d.ts +196 -0
  403. package/dist/clients/repository.d.ts.map +1 -1
  404. package/dist/clients/repository.js +270 -24
  405. package/dist/clients/repository.js.map +1 -1
  406. package/dist/collection/branding.d.ts +137 -0
  407. package/dist/collection/branding.d.ts.map +1 -0
  408. package/dist/collection/branding.js +322 -0
  409. package/dist/collection/branding.js.map +1 -0
  410. package/dist/collection/channel-accounts.d.ts +57 -0
  411. package/dist/collection/channel-accounts.d.ts.map +1 -0
  412. package/dist/collection/channel-accounts.js +133 -0
  413. package/dist/collection/channel-accounts.js.map +1 -0
  414. package/dist/collection/channel.d.ts +24 -0
  415. package/dist/collection/channel.d.ts.map +1 -0
  416. package/dist/collection/channel.js +16 -0
  417. package/dist/collection/channel.js.map +1 -0
  418. package/dist/collection/clearance-store.d.ts +39 -0
  419. package/dist/collection/clearance-store.d.ts.map +1 -0
  420. package/dist/collection/clearance-store.js +69 -0
  421. package/dist/collection/clearance-store.js.map +1 -0
  422. package/dist/collection/communication-bridge.d.ts +66 -0
  423. package/dist/collection/communication-bridge.d.ts.map +1 -0
  424. package/dist/collection/communication-bridge.js +134 -0
  425. package/dist/collection/communication-bridge.js.map +1 -0
  426. package/dist/collection/communication-runtime.d.ts +132 -0
  427. package/dist/collection/communication-runtime.d.ts.map +1 -0
  428. package/dist/collection/communication-runtime.js +249 -0
  429. package/dist/collection/communication-runtime.js.map +1 -0
  430. package/dist/collection/consent-repository.d.ts +32 -0
  431. package/dist/collection/consent-repository.d.ts.map +1 -0
  432. package/dist/collection/consent-repository.js +79 -0
  433. package/dist/collection/consent-repository.js.map +1 -0
  434. package/dist/collection/copy.d.ts +50 -0
  435. package/dist/collection/copy.d.ts.map +1 -0
  436. package/dist/collection/copy.js +122 -0
  437. package/dist/collection/copy.js.map +1 -0
  438. package/dist/collection/delivery-callback.d.ts +49 -0
  439. package/dist/collection/delivery-callback.d.ts.map +1 -0
  440. package/dist/collection/delivery-callback.js +147 -0
  441. package/dist/collection/delivery-callback.js.map +1 -0
  442. package/dist/collection/email-layout.d.ts +45 -0
  443. package/dist/collection/email-layout.d.ts.map +1 -0
  444. package/dist/collection/email-layout.js +247 -0
  445. package/dist/collection/email-layout.js.map +1 -0
  446. package/dist/collection/engine.d.ts +200 -0
  447. package/dist/collection/engine.d.ts.map +1 -0
  448. package/dist/collection/engine.js +427 -0
  449. package/dist/collection/engine.js.map +1 -0
  450. package/dist/collection/format.d.ts +32 -0
  451. package/dist/collection/format.d.ts.map +1 -0
  452. package/dist/collection/format.js +70 -0
  453. package/dist/collection/format.js.map +1 -0
  454. package/dist/collection/payment-block.d.ts +24 -0
  455. package/dist/collection/payment-block.d.ts.map +1 -0
  456. package/dist/collection/payment-block.js +2 -0
  457. package/dist/collection/payment-block.js.map +1 -0
  458. package/dist/collection/policy.d.ts +78 -0
  459. package/dist/collection/policy.d.ts.map +1 -0
  460. package/dist/collection/policy.js +168 -0
  461. package/dist/collection/policy.js.map +1 -0
  462. package/dist/collection/repository.d.ts +129 -0
  463. package/dist/collection/repository.d.ts.map +1 -0
  464. package/dist/collection/repository.js +246 -0
  465. package/dist/collection/repository.js.map +1 -0
  466. package/dist/collection/subject.d.ts +66 -0
  467. package/dist/collection/subject.d.ts.map +1 -0
  468. package/dist/collection/subject.js +99 -0
  469. package/dist/collection/subject.js.map +1 -0
  470. package/dist/collection/template-catalog.d.ts +16 -0
  471. package/dist/collection/template-catalog.d.ts.map +1 -0
  472. package/dist/collection/template-catalog.js +162 -0
  473. package/dist/collection/template-catalog.js.map +1 -0
  474. package/dist/collection/template.d.ts +37 -0
  475. package/dist/collection/template.d.ts.map +1 -0
  476. package/dist/collection/template.js +73 -0
  477. package/dist/collection/template.js.map +1 -0
  478. package/dist/communication/adapters/email.d.ts +28 -0
  479. package/dist/communication/adapters/email.d.ts.map +1 -0
  480. package/dist/communication/adapters/email.js +129 -0
  481. package/dist/communication/adapters/email.js.map +1 -0
  482. package/dist/communication/adapters/sms.d.ts +95 -0
  483. package/dist/communication/adapters/sms.d.ts.map +1 -0
  484. package/dist/communication/adapters/sms.js +121 -0
  485. package/dist/communication/adapters/sms.js.map +1 -0
  486. package/dist/communication/adapters/whatsapp-language.d.ts +34 -0
  487. package/dist/communication/adapters/whatsapp-language.d.ts.map +1 -0
  488. package/dist/communication/adapters/whatsapp-language.js +36 -0
  489. package/dist/communication/adapters/whatsapp-language.js.map +1 -0
  490. package/dist/communication/adapters/whatsapp-templates.d.ts +18 -0
  491. package/dist/communication/adapters/whatsapp-templates.d.ts.map +1 -0
  492. package/dist/communication/adapters/whatsapp-templates.js +97 -0
  493. package/dist/communication/adapters/whatsapp-templates.js.map +1 -0
  494. package/dist/communication/adapters/whatsapp.d.ts +29 -0
  495. package/dist/communication/adapters/whatsapp.d.ts.map +1 -0
  496. package/dist/communication/adapters/whatsapp.js +210 -0
  497. package/dist/communication/adapters/whatsapp.js.map +1 -0
  498. package/dist/communication/audit.d.ts +105 -0
  499. package/dist/communication/audit.d.ts.map +1 -0
  500. package/dist/communication/audit.js +56 -0
  501. package/dist/communication/audit.js.map +1 -0
  502. package/dist/communication/capabilities.d.ts +88 -0
  503. package/dist/communication/capabilities.d.ts.map +1 -0
  504. package/dist/communication/capabilities.js +72 -0
  505. package/dist/communication/capabilities.js.map +1 -0
  506. package/dist/communication/channel.d.ts +125 -0
  507. package/dist/communication/channel.d.ts.map +1 -0
  508. package/dist/communication/channel.js +47 -0
  509. package/dist/communication/channel.js.map +1 -0
  510. package/dist/communication/claim.d.ts +368 -0
  511. package/dist/communication/claim.d.ts.map +1 -0
  512. package/dist/communication/claim.js +224 -0
  513. package/dist/communication/claim.js.map +1 -0
  514. package/dist/communication/clearance.d.ts +53 -0
  515. package/dist/communication/clearance.d.ts.map +1 -0
  516. package/dist/communication/clearance.js +15 -0
  517. package/dist/communication/clearance.js.map +1 -0
  518. package/dist/communication/consent.d.ts +65 -0
  519. package/dist/communication/consent.d.ts.map +1 -0
  520. package/dist/communication/consent.js +40 -0
  521. package/dist/communication/consent.js.map +1 -0
  522. package/dist/communication/context.d.ts +48 -0
  523. package/dist/communication/context.d.ts.map +1 -0
  524. package/dist/communication/context.js +41 -0
  525. package/dist/communication/context.js.map +1 -0
  526. package/dist/communication/credentials.d.ts +74 -0
  527. package/dist/communication/credentials.d.ts.map +1 -0
  528. package/dist/communication/credentials.js +115 -0
  529. package/dist/communication/credentials.js.map +1 -0
  530. package/dist/communication/dry-run-scenario.d.ts +37 -0
  531. package/dist/communication/dry-run-scenario.d.ts.map +1 -0
  532. package/dist/communication/dry-run-scenario.js +163 -0
  533. package/dist/communication/dry-run-scenario.js.map +1 -0
  534. package/dist/communication/dry-run.d.ts +40 -0
  535. package/dist/communication/dry-run.d.ts.map +1 -0
  536. package/dist/communication/dry-run.js +92 -0
  537. package/dist/communication/dry-run.js.map +1 -0
  538. package/dist/communication/engine.d.ts +163 -0
  539. package/dist/communication/engine.d.ts.map +1 -0
  540. package/dist/communication/engine.js +492 -0
  541. package/dist/communication/engine.js.map +1 -0
  542. package/dist/communication/graph.d.ts +38 -0
  543. package/dist/communication/graph.d.ts.map +1 -0
  544. package/dist/communication/graph.js +45 -0
  545. package/dist/communication/graph.js.map +1 -0
  546. package/dist/communication/idempotency.d.ts +33 -0
  547. package/dist/communication/idempotency.d.ts.map +1 -0
  548. package/dist/communication/idempotency.js +23 -0
  549. package/dist/communication/idempotency.js.map +1 -0
  550. package/dist/communication/identity.d.ts +127 -0
  551. package/dist/communication/identity.d.ts.map +1 -0
  552. package/dist/communication/identity.js +105 -0
  553. package/dist/communication/identity.js.map +1 -0
  554. package/dist/communication/index.d.ts +66 -0
  555. package/dist/communication/index.d.ts.map +1 -0
  556. package/dist/communication/index.js +42 -0
  557. package/dist/communication/index.js.map +1 -0
  558. package/dist/communication/onboarding.d.ts +223 -0
  559. package/dist/communication/onboarding.d.ts.map +1 -0
  560. package/dist/communication/onboarding.js +287 -0
  561. package/dist/communication/onboarding.js.map +1 -0
  562. package/dist/communication/policy.d.ts +115 -0
  563. package/dist/communication/policy.d.ts.map +1 -0
  564. package/dist/communication/policy.js +13 -0
  565. package/dist/communication/policy.js.map +1 -0
  566. package/dist/communication/routing.d.ts +99 -0
  567. package/dist/communication/routing.d.ts.map +1 -0
  568. package/dist/communication/routing.js +73 -0
  569. package/dist/communication/routing.js.map +1 -0
  570. package/dist/communication/sender-profile.d.ts +100 -0
  571. package/dist/communication/sender-profile.d.ts.map +1 -0
  572. package/dist/communication/sender-profile.js +123 -0
  573. package/dist/communication/sender-profile.js.map +1 -0
  574. package/dist/communication/status.d.ts +48 -0
  575. package/dist/communication/status.d.ts.map +1 -0
  576. package/dist/communication/status.js +79 -0
  577. package/dist/communication/status.js.map +1 -0
  578. package/dist/communication/stores/onboarding.d.ts +88 -0
  579. package/dist/communication/stores/onboarding.d.ts.map +1 -0
  580. package/dist/communication/stores/onboarding.js +127 -0
  581. package/dist/communication/stores/onboarding.js.map +1 -0
  582. package/dist/communication/stores/postgres.d.ts +81 -0
  583. package/dist/communication/stores/postgres.d.ts.map +1 -0
  584. package/dist/communication/stores/postgres.js +453 -0
  585. package/dist/communication/stores/postgres.js.map +1 -0
  586. package/dist/communication/stores/routing.d.ts +169 -0
  587. package/dist/communication/stores/routing.d.ts.map +1 -0
  588. package/dist/communication/stores/routing.js +324 -0
  589. package/dist/communication/stores/routing.js.map +1 -0
  590. package/dist/communication/stores/secrets.d.ts +89 -0
  591. package/dist/communication/stores/secrets.d.ts.map +1 -0
  592. package/dist/communication/stores/secrets.js +122 -0
  593. package/dist/communication/stores/secrets.js.map +1 -0
  594. package/dist/communication/template-provider.d.ts +85 -0
  595. package/dist/communication/template-provider.d.ts.map +1 -0
  596. package/dist/communication/template-provider.js +21 -0
  597. package/dist/communication/template-provider.js.map +1 -0
  598. package/dist/communication/template.d.ts +87 -0
  599. package/dist/communication/template.d.ts.map +1 -0
  600. package/dist/communication/template.js +59 -0
  601. package/dist/communication/template.js.map +1 -0
  602. package/dist/communication/webhook-subscription.d.ts +156 -0
  603. package/dist/communication/webhook-subscription.d.ts.map +1 -0
  604. package/dist/communication/webhook-subscription.js +252 -0
  605. package/dist/communication/webhook-subscription.js.map +1 -0
  606. package/dist/communication/webhook.d.ts +121 -0
  607. package/dist/communication/webhook.d.ts.map +1 -0
  608. package/dist/communication/webhook.js +283 -0
  609. package/dist/communication/webhook.js.map +1 -0
  610. package/dist/competence/business-days.d.ts +51 -0
  611. package/dist/competence/business-days.d.ts.map +1 -0
  612. package/dist/competence/business-days.js +145 -0
  613. package/dist/competence/business-days.js.map +1 -0
  614. package/dist/competence/catalog-validation.d.ts +86 -0
  615. package/dist/competence/catalog-validation.d.ts.map +1 -0
  616. package/dist/competence/catalog-validation.js +168 -0
  617. package/dist/competence/catalog-validation.js.map +1 -0
  618. package/dist/competence/obligation-preview.d.ts +103 -0
  619. package/dist/competence/obligation-preview.d.ts.map +1 -0
  620. package/dist/competence/obligation-preview.js +184 -0
  621. package/dist/competence/obligation-preview.js.map +1 -0
  622. package/dist/competence/repository.d.ts +285 -0
  623. package/dist/competence/repository.d.ts.map +1 -0
  624. package/dist/competence/repository.js +602 -0
  625. package/dist/competence/repository.js.map +1 -0
  626. package/dist/contacts/phone.d.ts +70 -0
  627. package/dist/contacts/phone.d.ts.map +1 -0
  628. package/dist/contacts/phone.js +186 -0
  629. package/dist/contacts/phone.js.map +1 -0
  630. package/dist/dashboard/pilot-panel.d.ts +100 -0
  631. package/dist/dashboard/pilot-panel.d.ts.map +1 -0
  632. package/dist/dashboard/pilot-panel.js +87 -0
  633. package/dist/dashboard/pilot-panel.js.map +1 -0
  634. package/dist/dashboard/repository.d.ts.map +1 -1
  635. package/dist/dashboard/repository.js +11 -1
  636. package/dist/dashboard/repository.js.map +1 -1
  637. package/dist/db/client.d.ts +45 -0
  638. package/dist/db/client.d.ts.map +1 -1
  639. package/dist/db/client.js +16 -11
  640. package/dist/db/client.js.map +1 -1
  641. package/dist/db/migrate.d.ts +36 -1
  642. package/dist/db/migrate.d.ts.map +1 -1
  643. package/dist/db/migrate.js +208 -35
  644. package/dist/db/migrate.js.map +1 -1
  645. package/dist/db/provision-e2e-identity.d.ts +2 -0
  646. package/dist/db/provision-e2e-identity.d.ts.map +1 -0
  647. package/dist/db/provision-e2e-identity.js +109 -0
  648. package/dist/db/provision-e2e-identity.js.map +1 -0
  649. package/dist/db/seed-catalog.d.ts +18 -0
  650. package/dist/db/seed-catalog.d.ts.map +1 -0
  651. package/dist/db/seed-catalog.js +45 -0
  652. package/dist/db/seed-catalog.js.map +1 -0
  653. package/dist/db/seed.js +16 -8
  654. package/dist/db/seed.js.map +1 -1
  655. package/dist/documents/repository.d.ts +97 -0
  656. package/dist/documents/repository.d.ts.map +1 -0
  657. package/dist/documents/repository.js +236 -0
  658. package/dist/documents/repository.js.map +1 -0
  659. package/dist/documents/requests.d.ts +73 -0
  660. package/dist/documents/requests.d.ts.map +1 -0
  661. package/dist/documents/requests.js +127 -0
  662. package/dist/documents/requests.js.map +1 -0
  663. package/dist/fiscal/applicability.d.ts +73 -0
  664. package/dist/fiscal/applicability.d.ts.map +1 -0
  665. package/dist/fiscal/applicability.js +160 -0
  666. package/dist/fiscal/applicability.js.map +1 -0
  667. package/dist/fiscal/conditions.d.ts +99 -0
  668. package/dist/fiscal/conditions.d.ts.map +1 -0
  669. package/dist/fiscal/conditions.js +190 -0
  670. package/dist/fiscal/conditions.js.map +1 -0
  671. package/dist/fiscal/contracts/nfse-adn-contract.d.ts +315 -0
  672. package/dist/fiscal/contracts/nfse-adn-contract.d.ts.map +1 -0
  673. package/dist/fiscal/contracts/nfse-adn-contract.js +386 -0
  674. package/dist/fiscal/contracts/nfse-adn-contract.js.map +1 -0
  675. package/dist/fiscal/contracts/nfse-adn-endpoint.d.ts +13 -0
  676. package/dist/fiscal/contracts/nfse-adn-endpoint.d.ts.map +1 -0
  677. package/dist/fiscal/contracts/nfse-adn-endpoint.js +103 -0
  678. package/dist/fiscal/contracts/nfse-adn-endpoint.js.map +1 -0
  679. package/dist/fiscal/contracts/nfse-adn-envelope.d.ts +77 -0
  680. package/dist/fiscal/contracts/nfse-adn-envelope.d.ts.map +1 -0
  681. package/dist/fiscal/contracts/nfse-adn-envelope.js +215 -0
  682. package/dist/fiscal/contracts/nfse-adn-envelope.js.map +1 -0
  683. package/dist/fiscal/coverage/model.d.ts +86 -0
  684. package/dist/fiscal/coverage/model.d.ts.map +1 -0
  685. package/dist/fiscal/coverage/model.js +120 -0
  686. package/dist/fiscal/coverage/model.js.map +1 -0
  687. package/dist/fiscal/coverage/requests.d.ts +70 -0
  688. package/dist/fiscal/coverage/requests.d.ts.map +1 -0
  689. package/dist/fiscal/coverage/requests.js +95 -0
  690. package/dist/fiscal/coverage/requests.js.map +1 -0
  691. package/dist/fiscal/credentials/material.d.ts +81 -0
  692. package/dist/fiscal/credentials/material.d.ts.map +1 -0
  693. package/dist/fiscal/credentials/material.js +164 -0
  694. package/dist/fiscal/credentials/material.js.map +1 -0
  695. package/dist/fiscal/credentials/readiness.d.ts +92 -0
  696. package/dist/fiscal/credentials/readiness.d.ts.map +1 -0
  697. package/dist/fiscal/credentials/readiness.js +159 -0
  698. package/dist/fiscal/credentials/readiness.js.map +1 -0
  699. package/dist/fiscal/eligibility.d.ts +106 -0
  700. package/dist/fiscal/eligibility.d.ts.map +1 -0
  701. package/dist/fiscal/eligibility.js +194 -0
  702. package/dist/fiscal/eligibility.js.map +1 -0
  703. package/dist/fiscal/ingestion/__fixtures__/nfse.d.ts +57 -0
  704. package/dist/fiscal/ingestion/__fixtures__/nfse.d.ts.map +1 -0
  705. package/dist/fiscal/ingestion/__fixtures__/nfse.js +121 -0
  706. package/dist/fiscal/ingestion/__fixtures__/nfse.js.map +1 -0
  707. package/dist/fiscal/ingestion/adn-transport.d.ts +123 -0
  708. package/dist/fiscal/ingestion/adn-transport.d.ts.map +1 -0
  709. package/dist/fiscal/ingestion/adn-transport.js +220 -0
  710. package/dist/fiscal/ingestion/adn-transport.js.map +1 -0
  711. package/dist/fiscal/ingestion/direction.d.ts +60 -0
  712. package/dist/fiscal/ingestion/direction.d.ts.map +1 -0
  713. package/dist/fiscal/ingestion/direction.js +32 -0
  714. package/dist/fiscal/ingestion/direction.js.map +1 -0
  715. package/dist/fiscal/ingestion/nfse-adn.d.ts +91 -0
  716. package/dist/fiscal/ingestion/nfse-adn.d.ts.map +1 -0
  717. package/dist/fiscal/ingestion/nfse-adn.js +222 -0
  718. package/dist/fiscal/ingestion/nfse-adn.js.map +1 -0
  719. package/dist/fiscal/ingestion/pipeline.d.ts +168 -0
  720. package/dist/fiscal/ingestion/pipeline.d.ts.map +1 -0
  721. package/dist/fiscal/ingestion/pipeline.js +699 -0
  722. package/dist/fiscal/ingestion/pipeline.js.map +1 -0
  723. package/dist/fiscal/ingestion/provider.d.ts +206 -0
  724. package/dist/fiscal/ingestion/provider.d.ts.map +1 -0
  725. package/dist/fiscal/ingestion/provider.js +47 -0
  726. package/dist/fiscal/ingestion/provider.js.map +1 -0
  727. package/dist/fiscal/ingestion/repository.d.ts +82 -0
  728. package/dist/fiscal/ingestion/repository.d.ts.map +1 -0
  729. package/dist/fiscal/ingestion/repository.js +127 -0
  730. package/dist/fiscal/ingestion/repository.js.map +1 -0
  731. package/dist/fiscal/ingestion/synthetic-provider.d.ts +92 -0
  732. package/dist/fiscal/ingestion/synthetic-provider.d.ts.map +1 -0
  733. package/dist/fiscal/ingestion/synthetic-provider.js +99 -0
  734. package/dist/fiscal/ingestion/synthetic-provider.js.map +1 -0
  735. package/dist/fiscal/ingestion/synthetic-transport-types.d.ts +19 -0
  736. package/dist/fiscal/ingestion/synthetic-transport-types.d.ts.map +1 -0
  737. package/dist/fiscal/ingestion/synthetic-transport-types.js +9 -0
  738. package/dist/fiscal/ingestion/synthetic-transport-types.js.map +1 -0
  739. package/dist/fiscal/ingestion/synthetic-transport.d.ts +55 -0
  740. package/dist/fiscal/ingestion/synthetic-transport.d.ts.map +1 -0
  741. package/dist/fiscal/ingestion/synthetic-transport.js +57 -0
  742. package/dist/fiscal/ingestion/synthetic-transport.js.map +1 -0
  743. package/dist/fiscal/ingestion/xml-reader.d.ts +55 -0
  744. package/dist/fiscal/ingestion/xml-reader.d.ts.map +1 -0
  745. package/dist/fiscal/ingestion/xml-reader.js +112 -0
  746. package/dist/fiscal/ingestion/xml-reader.js.map +1 -0
  747. package/dist/fiscal/repository.d.ts +220 -0
  748. package/dist/fiscal/repository.d.ts.map +1 -0
  749. package/dist/fiscal/repository.js +449 -0
  750. package/dist/fiscal/repository.js.map +1 -0
  751. package/dist/fiscal/sync/circuit.d.ts +86 -0
  752. package/dist/fiscal/sync/circuit.d.ts.map +1 -0
  753. package/dist/fiscal/sync/circuit.js +118 -0
  754. package/dist/fiscal/sync/circuit.js.map +1 -0
  755. package/dist/fiscal/sync/intervention.d.ts +81 -0
  756. package/dist/fiscal/sync/intervention.d.ts.map +1 -0
  757. package/dist/fiscal/sync/intervention.js +135 -0
  758. package/dist/fiscal/sync/intervention.js.map +1 -0
  759. package/dist/fiscal/sync/lease.d.ts +118 -0
  760. package/dist/fiscal/sync/lease.d.ts.map +1 -0
  761. package/dist/fiscal/sync/lease.js +139 -0
  762. package/dist/fiscal/sync/lease.js.map +1 -0
  763. package/dist/fiscal/sync/observability.d.ts +148 -0
  764. package/dist/fiscal/sync/observability.d.ts.map +1 -0
  765. package/dist/fiscal/sync/observability.js +239 -0
  766. package/dist/fiscal/sync/observability.js.map +1 -0
  767. package/dist/fiscal/sync/orchestrator.d.ts +132 -0
  768. package/dist/fiscal/sync/orchestrator.d.ts.map +1 -0
  769. package/dist/fiscal/sync/orchestrator.js +487 -0
  770. package/dist/fiscal/sync/orchestrator.js.map +1 -0
  771. package/dist/fiscal/sync/policy.d.ts +87 -0
  772. package/dist/fiscal/sync/policy.d.ts.map +1 -0
  773. package/dist/fiscal/sync/policy.js +136 -0
  774. package/dist/fiscal/sync/policy.js.map +1 -0
  775. package/dist/fiscal/sync/reprocess.d.ts +76 -0
  776. package/dist/fiscal/sync/reprocess.d.ts.map +1 -0
  777. package/dist/fiscal/sync/reprocess.js +237 -0
  778. package/dist/fiscal/sync/reprocess.js.map +1 -0
  779. package/dist/fiscal/sync/retry.d.ts +82 -0
  780. package/dist/fiscal/sync/retry.d.ts.map +1 -0
  781. package/dist/fiscal/sync/retry.js +176 -0
  782. package/dist/fiscal/sync/retry.js.map +1 -0
  783. package/dist/fiscal/sync/secret-boundary.d.ts +169 -0
  784. package/dist/fiscal/sync/secret-boundary.d.ts.map +1 -0
  785. package/dist/fiscal/sync/secret-boundary.js +116 -0
  786. package/dist/fiscal/sync/secret-boundary.js.map +1 -0
  787. package/dist/fiscal/transport/https.d.ts +86 -0
  788. package/dist/fiscal/transport/https.d.ts.map +1 -0
  789. package/dist/fiscal/transport/https.js +303 -0
  790. package/dist/fiscal/transport/https.js.map +1 -0
  791. package/dist/fiscal/transport/synthetic-tls.d.ts +80 -0
  792. package/dist/fiscal/transport/synthetic-tls.d.ts.map +1 -0
  793. package/dist/fiscal/transport/synthetic-tls.js +323 -0
  794. package/dist/fiscal/transport/synthetic-tls.js.map +1 -0
  795. package/dist/fiscal/transport/types.d.ts +134 -0
  796. package/dist/fiscal/transport/types.d.ts.map +1 -0
  797. package/dist/fiscal/transport/types.js +88 -0
  798. package/dist/fiscal/transport/types.js.map +1 -0
  799. package/dist/import/br-documents.d.ts +26 -0
  800. package/dist/import/br-documents.d.ts.map +1 -0
  801. package/dist/import/br-documents.js +78 -0
  802. package/dist/import/br-documents.js.map +1 -0
  803. package/dist/import/clients-import.d.ts +122 -4
  804. package/dist/import/clients-import.d.ts.map +1 -1
  805. package/dist/import/clients-import.js +341 -41
  806. package/dist/import/clients-import.js.map +1 -1
  807. package/dist/index.d.ts +217 -17
  808. package/dist/index.d.ts.map +1 -1
  809. package/dist/index.js +196 -11
  810. package/dist/index.js.map +1 -1
  811. package/dist/legal/documents.d.ts +12 -1
  812. package/dist/legal/documents.d.ts.map +1 -1
  813. package/dist/legal/documents.js +222 -16
  814. package/dist/legal/documents.js.map +1 -1
  815. package/dist/legal/index.d.ts +2 -2
  816. package/dist/legal/index.d.ts.map +1 -1
  817. package/dist/legal/index.js +1 -1
  818. package/dist/legal/index.js.map +1 -1
  819. package/dist/legal/types.d.ts +69 -3
  820. package/dist/legal/types.d.ts.map +1 -1
  821. package/dist/legal/types.js +1 -0
  822. package/dist/legal/types.js.map +1 -1
  823. package/dist/mail/auth-templates.d.ts +15 -0
  824. package/dist/mail/auth-templates.d.ts.map +1 -0
  825. package/dist/mail/auth-templates.js +26 -0
  826. package/dist/mail/auth-templates.js.map +1 -0
  827. package/dist/mail/dedup-store.d.ts +1 -24
  828. package/dist/mail/dedup-store.d.ts.map +1 -1
  829. package/dist/mail/dedup-store.js +9 -48
  830. package/dist/mail/dedup-store.js.map +1 -1
  831. package/dist/mail/index.d.ts +2 -1
  832. package/dist/mail/index.d.ts.map +1 -1
  833. package/dist/mail/index.js +13 -2
  834. package/dist/mail/index.js.map +1 -1
  835. package/dist/mail/provider.d.ts +2 -30
  836. package/dist/mail/provider.d.ts.map +1 -1
  837. package/dist/mail/provider.js +10 -246
  838. package/dist/mail/provider.js.map +1 -1
  839. package/dist/mail/resend.d.ts +2 -12
  840. package/dist/mail/resend.d.ts.map +1 -1
  841. package/dist/mail/resend.js +11 -17
  842. package/dist/mail/resend.js.map +1 -1
  843. package/dist/mail/sender-resolver.d.ts +1 -7
  844. package/dist/mail/sender-resolver.d.ts.map +1 -1
  845. package/dist/mail/sender-resolver.js +11 -10
  846. package/dist/mail/sender-resolver.js.map +1 -1
  847. package/dist/mail/template-renderer.d.ts +1 -9
  848. package/dist/mail/template-renderer.d.ts.map +1 -1
  849. package/dist/mail/template-renderer.js +10 -15
  850. package/dist/mail/template-renderer.js.map +1 -1
  851. package/dist/mail/transactional-outbound.d.ts +115 -0
  852. package/dist/mail/transactional-outbound.d.ts.map +1 -0
  853. package/dist/mail/transactional-outbound.js +113 -0
  854. package/dist/mail/transactional-outbound.js.map +1 -0
  855. package/dist/mail/types.d.ts +2 -142
  856. package/dist/mail/types.d.ts.map +1 -1
  857. package/dist/mail/types.js +1 -33
  858. package/dist/mail/types.js.map +1 -1
  859. package/dist/onboarding/persistence.d.ts +10 -1
  860. package/dist/onboarding/persistence.d.ts.map +1 -1
  861. package/dist/onboarding/persistence.js +4 -4
  862. package/dist/onboarding/persistence.js.map +1 -1
  863. package/dist/pilot/go-live-checklist.d.ts +41 -0
  864. package/dist/pilot/go-live-checklist.d.ts.map +1 -0
  865. package/dist/pilot/go-live-checklist.js +209 -0
  866. package/dist/pilot/go-live-checklist.js.map +1 -0
  867. package/dist/pilot/milestone.d.ts +56 -0
  868. package/dist/pilot/milestone.d.ts.map +1 -0
  869. package/dist/pilot/milestone.js +74 -0
  870. package/dist/pilot/milestone.js.map +1 -0
  871. package/dist/platform/capabilities.d.ts +88 -0
  872. package/dist/platform/capabilities.d.ts.map +1 -0
  873. package/dist/platform/capabilities.js +140 -0
  874. package/dist/platform/capabilities.js.map +1 -0
  875. package/dist/platform/job-contract.d.ts +232 -0
  876. package/dist/platform/job-contract.d.ts.map +1 -0
  877. package/dist/platform/job-contract.js +403 -0
  878. package/dist/platform/job-contract.js.map +1 -0
  879. package/dist/portal/provisioning.d.ts +58 -0
  880. package/dist/portal/provisioning.d.ts.map +1 -0
  881. package/dist/portal/provisioning.js +139 -0
  882. package/dist/portal/provisioning.js.map +1 -0
  883. package/dist/pricing-engine/canonical.d.ts +14 -0
  884. package/dist/pricing-engine/canonical.d.ts.map +1 -0
  885. package/dist/pricing-engine/canonical.js +39 -0
  886. package/dist/pricing-engine/canonical.js.map +1 -0
  887. package/dist/pricing-engine/errors.d.ts.map +1 -1
  888. package/dist/pricing-engine/errors.js +6 -1
  889. package/dist/pricing-engine/errors.js.map +1 -1
  890. package/dist/pricing-engine/index.d.ts +12 -2
  891. package/dist/pricing-engine/index.d.ts.map +1 -1
  892. package/dist/pricing-engine/index.js +6 -1
  893. package/dist/pricing-engine/index.js.map +1 -1
  894. package/dist/pricing-engine/pipeline.d.ts.map +1 -1
  895. package/dist/pricing-engine/pipeline.js +202 -28
  896. package/dist/pricing-engine/pipeline.js.map +1 -1
  897. package/dist/pricing-engine/shadow-adapter.d.ts +37 -0
  898. package/dist/pricing-engine/shadow-adapter.d.ts.map +1 -0
  899. package/dist/pricing-engine/shadow-adapter.js +75 -0
  900. package/dist/pricing-engine/shadow-adapter.js.map +1 -0
  901. package/dist/pricing-engine/shadow-diff.d.ts +26 -0
  902. package/dist/pricing-engine/shadow-diff.d.ts.map +1 -0
  903. package/dist/pricing-engine/shadow-diff.js +52 -0
  904. package/dist/pricing-engine/shadow-diff.js.map +1 -0
  905. package/dist/pricing-engine/shadow-facade.d.ts +42 -0
  906. package/dist/pricing-engine/shadow-facade.d.ts.map +1 -0
  907. package/dist/pricing-engine/shadow-facade.js +82 -0
  908. package/dist/pricing-engine/shadow-facade.js.map +1 -0
  909. package/dist/pricing-engine/shadow-legacy-types.d.ts +64 -0
  910. package/dist/pricing-engine/shadow-legacy-types.d.ts.map +1 -0
  911. package/dist/pricing-engine/shadow-legacy-types.js +18 -0
  912. package/dist/pricing-engine/shadow-legacy-types.js.map +1 -0
  913. package/dist/pricing-engine/shadow-metrics.d.ts +33 -0
  914. package/dist/pricing-engine/shadow-metrics.d.ts.map +1 -0
  915. package/dist/pricing-engine/shadow-metrics.js +31 -0
  916. package/dist/pricing-engine/shadow-metrics.js.map +1 -0
  917. package/dist/pricing-engine/shadow-normalizer.d.ts +17 -0
  918. package/dist/pricing-engine/shadow-normalizer.d.ts.map +1 -0
  919. package/dist/pricing-engine/shadow-normalizer.js +39 -0
  920. package/dist/pricing-engine/shadow-normalizer.js.map +1 -0
  921. package/dist/pricing-engine/types.d.ts +2 -0
  922. package/dist/pricing-engine/types.d.ts.map +1 -1
  923. package/dist/rbac/authorize.d.ts +12 -0
  924. package/dist/rbac/authorize.d.ts.map +1 -1
  925. package/dist/rbac/authorize.js +27 -0
  926. package/dist/rbac/authorize.js.map +1 -1
  927. package/dist/rbac/catalog.d.ts.map +1 -1
  928. package/dist/rbac/catalog.js +101 -1
  929. package/dist/rbac/catalog.js.map +1 -1
  930. package/dist/rbac/workload-provisioning.d.ts +66 -0
  931. package/dist/rbac/workload-provisioning.d.ts.map +1 -0
  932. package/dist/rbac/workload-provisioning.js +153 -0
  933. package/dist/rbac/workload-provisioning.js.map +1 -0
  934. package/dist/rbac/workload.d.ts +124 -0
  935. package/dist/rbac/workload.d.ts.map +1 -0
  936. package/dist/rbac/workload.js +184 -0
  937. package/dist/rbac/workload.js.map +1 -0
  938. package/dist/storage/checksum.d.ts +9 -0
  939. package/dist/storage/checksum.d.ts.map +1 -0
  940. package/dist/storage/checksum.js +12 -0
  941. package/dist/storage/checksum.js.map +1 -0
  942. package/dist/storage/key.d.ts +37 -0
  943. package/dist/storage/key.d.ts.map +1 -0
  944. package/dist/storage/key.js +67 -0
  945. package/dist/storage/key.js.map +1 -0
  946. package/dist/storage/local.d.ts +40 -0
  947. package/dist/storage/local.d.ts.map +1 -0
  948. package/dist/storage/local.js +96 -0
  949. package/dist/storage/local.js.map +1 -0
  950. package/dist/storage/r2.d.ts +43 -0
  951. package/dist/storage/r2.d.ts.map +1 -0
  952. package/dist/storage/r2.js +177 -0
  953. package/dist/storage/r2.js.map +1 -0
  954. package/dist/storage/registry.d.ts +23 -0
  955. package/dist/storage/registry.d.ts.map +1 -0
  956. package/dist/storage/registry.js +37 -0
  957. package/dist/storage/registry.js.map +1 -0
  958. package/dist/storage/types.d.ts +67 -0
  959. package/dist/storage/types.d.ts.map +1 -0
  960. package/dist/storage/types.js +45 -0
  961. package/dist/storage/types.js.map +1 -0
  962. package/dist/subscription-billing/index.d.ts +6 -5
  963. package/dist/subscription-billing/index.d.ts.map +1 -1
  964. package/dist/subscription-billing/index.js +3 -3
  965. package/dist/subscription-billing/index.js.map +1 -1
  966. package/dist/subscription-billing/provider/asaas.d.ts +14 -0
  967. package/dist/subscription-billing/provider/asaas.d.ts.map +1 -1
  968. package/dist/subscription-billing/provider/asaas.js +32 -7
  969. package/dist/subscription-billing/provider/asaas.js.map +1 -1
  970. package/dist/subscription-billing/provider/disabled.d.ts +9 -0
  971. package/dist/subscription-billing/provider/disabled.d.ts.map +1 -1
  972. package/dist/subscription-billing/provider/disabled.js +8 -0
  973. package/dist/subscription-billing/provider/disabled.js.map +1 -1
  974. package/dist/subscription-billing/provider/registry.d.ts +10 -0
  975. package/dist/subscription-billing/provider/registry.d.ts.map +1 -1
  976. package/dist/subscription-billing/provider/registry.js +17 -0
  977. package/dist/subscription-billing/provider/registry.js.map +1 -1
  978. package/dist/subscription-billing/service.d.ts +38 -1
  979. package/dist/subscription-billing/service.d.ts.map +1 -1
  980. package/dist/subscription-billing/service.js +147 -23
  981. package/dist/subscription-billing/service.js.map +1 -1
  982. package/dist/subscription-billing/types.d.ts +13 -0
  983. package/dist/subscription-billing/types.d.ts.map +1 -1
  984. package/dist/subscription-billing/types.js.map +1 -1
  985. package/dist/tenancy/features.d.ts +69 -0
  986. package/dist/tenancy/features.d.ts.map +1 -0
  987. package/dist/tenancy/features.js +123 -0
  988. package/dist/tenancy/features.js.map +1 -0
  989. package/dist/tenancy/provisioning.d.ts.map +1 -1
  990. package/dist/tenancy/provisioning.js +32 -8
  991. package/dist/tenancy/provisioning.js.map +1 -1
  992. package/dist/tenancy/settings.d.ts +63 -0
  993. package/dist/tenancy/settings.d.ts.map +1 -0
  994. package/dist/tenancy/settings.js +218 -0
  995. package/dist/tenancy/settings.js.map +1 -0
  996. package/dist/users/repository.d.ts +54 -1
  997. package/dist/users/repository.d.ts.map +1 -1
  998. package/dist/users/repository.js +142 -4
  999. package/dist/users/repository.js.map +1 -1
  1000. package/dist/vault/repository.d.ts +67 -0
  1001. package/dist/vault/repository.d.ts.map +1 -1
  1002. package/dist/vault/repository.js +78 -0
  1003. package/dist/vault/repository.js.map +1 -1
  1004. package/package.json +20 -4
  1005. package/src/db/migrations/0023_user_invite_activation.sql +15 -0
  1006. package/src/db/migrations/0024_set_user_password_function.sql +32 -0
  1007. package/src/db/migrations/0025_revoke_user_session_function.sql +28 -0
  1008. package/src/db/migrations/0026_documents_and_competence.sql +353 -0
  1009. package/src/db/migrations/0027_receivable_client_isolation.sql +58 -0
  1010. package/src/db/migrations/0028_collection_engine.sql +94 -0
  1011. package/src/db/migrations/0029_payment_rail.sql +107 -0
  1012. package/src/db/migrations/0030_provider_account_uniqueness.sql +22 -0
  1013. package/src/db/migrations/0031_provider_account_environment_scope.sql +21 -0
  1014. package/src/db/migrations/0032_settlement_reversal.sql +76 -0
  1015. package/src/db/migrations/0033_receivable_idempotency.sql +28 -0
  1016. package/src/db/migrations/0034_payment_customer_reconcile.sql +30 -0
  1017. package/src/db/migrations/0035_payment_account_environments.sql +61 -0
  1018. package/src/db/migrations/0036_primary_backfill_under_force_rls.sql +41 -0
  1019. package/src/db/migrations/0037_receivable_generation_source.sql +29 -0
  1020. package/src/db/migrations/0038_notification_channels.sql +175 -0
  1021. package/src/db/migrations/0039_communication_dispatch_claim.sql +193 -0
  1022. package/src/db/migrations/0040_communication_unknown_outcome.sql +99 -0
  1023. package/src/db/migrations/0041_channel_binding_routing.sql +146 -0
  1024. package/src/db/migrations/0042_channel_route_read_isolation.sql +165 -0
  1025. package/src/db/migrations/0043_workload_identity.sql +105 -0
  1026. package/src/db/migrations/0044_channel_onboarding_session.sql +96 -0
  1027. package/src/db/migrations/0045_role_write_scope.sql +122 -0
  1028. package/src/db/migrations/0046_pilot_activation_model.sql +184 -0
  1029. package/src/db/migrations/0047_recipient_clearance.sql +89 -0
  1030. package/src/db/migrations/0048_item_type_note.sql +16 -0
  1031. package/src/db/migrations/0049_national_fiscal_engine.sql +279 -0
  1032. package/src/db/migrations/0050_fiscal_vocabulary_readonly.sql +29 -0
  1033. package/src/db/migrations/0051_seed_rules_from_catalog.sql +72 -0
  1034. package/src/db/migrations/0052_fiscal_rule_delete_scope.sql +57 -0
  1035. package/src/db/migrations/0053_rule_validity_lower_bound.sql +44 -0
  1036. package/src/db/migrations/0054_tenant_profile_and_rule_source.sql +89 -0
  1037. package/src/db/migrations/0055_job_capability_contract.sql +300 -0
  1038. package/src/db/migrations/0056_fiscal_document_ingestion.sql +337 -0
  1039. package/src/db/migrations/0057_fiscal_pending_event_inbox.sql +228 -0
  1040. package/src/db/migrations/0058_fiscal_operational_engine.sql +516 -0
  1041. package/src/db/migrations/0059_fiscal_contract_version.sql +59 -0
  1042. package/dist/cjs/mail/resend-client.js +0 -103
  1043. package/dist/cjs/mail/resend-client.js.map +0 -1
  1044. package/dist/mail/resend-client.d.ts +0 -16
  1045. package/dist/mail/resend-client.d.ts.map +0 -1
  1046. package/dist/mail/resend-client.js +0 -100
  1047. package/dist/mail/resend-client.js.map +0 -1
@@ -0,0 +1,783 @@
1
+ import { ConflictError, NotFoundError, ValidationError, uuidv7 } from '@baruk/shared';
2
+ import { availableMeansOf } from './payment-means-catalog.js';
3
+ /**
4
+ * Accounts Receivable — M1 do Merchant Billing Core
5
+ * (RFC-CAPABILITY-MERCHANT-BILLING-CORE-001 §4/§20). O M0 entregou schema e
6
+ * contratos; aqui entram a geração por competência, a máquina de estados e as
7
+ * consultas financeiras.
8
+ *
9
+ * A separação do M0 continua valendo e não pode ser colapsada: `Receivable` é a
10
+ * DÍVIDA do cliente com o escritório; `Charge` é o INSTRUMENTO (boleto/pix) que
11
+ * tenta recebê-la; `Payment` é o dinheiro que chegou. Um mesmo Receivable pode
12
+ * ter vários Charges (reemissão) e vários Payments (parcial).
13
+ *
14
+ * Tenant-scoped por RLS: nenhuma query aqui filtra `tenant_id` na mão — quem
15
+ * garante o recorte é a policy, e o contexto vem de `withContext`.
16
+ */
17
+ // ── Vencido é uma DERIVAÇÃO, não um estado que alguém precisa lembrar de gravar ──
18
+ //
19
+ // Um recebível `open` cuja data passou já está vencido — mesmo que nenhum job
20
+ // tenha rodado. Gravar 'overdue' numa coluna faria o número do dashboard depender
21
+ // de um cron ter executado; quando o cron falha, o escritório vê inadimplência
22
+ // menor do que a real, que é o pior erro possível neste domínio.
23
+ //
24
+ // Então o status efetivo é calculado na leitura. `markOverdueReceivables` existe
25
+ // para MATERIALIZAR a transição — não para descobri-la — porque a régua de
26
+ // cobrança precisa de um instante definido para disparar RECEIVABLE_OVERDUE.
27
+ // `partially_paid` entra junto de `open`: um recebível pago pela metade cujo
28
+ // vencimento passou TEM saldo em atraso. Considerar só `open` fazia o resumo
29
+ // dizer "vencido: R$ 0" enquanto o aging listava o mesmo saldo na faixa de 1-7
30
+ // dias — dois números verdadeiros contando coisas diferentes, e o mais visível
31
+ // deles subestimando a inadimplência.
32
+ const EFFECTIVE_STATUS_SQL = `
33
+ CASE WHEN r.status IN ('open','partially_paid')
34
+ AND r.due_date IS NOT NULL AND r.due_date < CURRENT_DATE
35
+ THEN 'overdue' ELSE r.status END`;
36
+ /** Status que ainda representam dinheiro a receber. */
37
+ const OPEN_STATUSES = ['open', 'partially_paid', 'overdue'];
38
+ const iso = (d) => (d ? d.toISOString().slice(0, 10) : null);
39
+ /** Texto de `metadata`, ou null. Ignora número/objeto: metadata é livre. */
40
+ function metaText(metadata, key) {
41
+ const v = metadata?.[key];
42
+ return typeof v === 'string' && v.trim() ? v.trim() : null;
43
+ }
44
+ function mapReceivable(r) {
45
+ const amount = Number(r.amount);
46
+ const amountPaid = Number(r.amount_paid);
47
+ return {
48
+ id: r.id,
49
+ clientId: r.client_id,
50
+ clientName: r.client_name,
51
+ feeAgreementId: r.fee_agreement_id,
52
+ competence: r.competence,
53
+ amount,
54
+ status: r.status,
55
+ effectiveStatus: r.effective_status,
56
+ dueDate: iso(r.due_date),
57
+ issuedAt: r.issued_at.toISOString(),
58
+ renegotiatedFromId: r.renegotiated_from_id,
59
+ createdAt: r.created_at.toISOString(),
60
+ amountPaid,
61
+ outstandingAmount: Math.max(0, Number((amount - amountPaid).toFixed(2))),
62
+ daysOverdue: r.days_overdue,
63
+ // A origem é o `fee_agreement_id` e nada mais. Derivar da competência —
64
+ // tentador, porque quase todo recorrente tem uma — classificaria como
65
+ // recorrente todo avulso que o operador competenciou, que é justamente o
66
+ // caso em que a distinção importa.
67
+ origin: r.fee_agreement_id ? 'recurring' : 'one_off',
68
+ generatedBy: r.generated_by,
69
+ description: r.description,
70
+ notes: metaText(r.metadata, 'notes'),
71
+ serviceCategory: metaText(r.metadata, 'serviceCategory'),
72
+ activeCharge: r.charge_id
73
+ ? {
74
+ id: r.charge_id,
75
+ status: r.charge_status,
76
+ means: availableMeansOf(r.charge_metadata),
77
+ }
78
+ : null,
79
+ };
80
+ }
81
+ /**
82
+ * Descrição do recebível a partir dos seus itens.
83
+ *
84
+ * Hoje tanto a geração por competência quanto o avulso criam exatamente UM
85
+ * item, mas o schema permite vários (RFC §4) — então junta em vez de pegar o
86
+ * primeiro: com dois itens, "Honorários" sozinho esconderia metade da dívida.
87
+ */
88
+ const DESCRIPTION_SQL = `
89
+ (SELECT string_agg(i.description, ' · ' ORDER BY i.created_at, i.id)
90
+ FROM receivable_item i WHERE i.receivable_id = r.id)`;
91
+ const SELECT_RECEIVABLE = `
92
+ SELECT r.id, r.client_id, c.display_name AS client_name, r.fee_agreement_id, r.competence,
93
+ r.amount, r.status, ${EFFECTIVE_STATUS_SQL} AS effective_status, r.generated_by,
94
+ r.due_date, r.issued_at, r.renegotiated_from_id, r.created_at, r.metadata,
95
+ ${DESCRIPTION_SQL} AS description,
96
+ ac.id AS charge_id, ac.status AS charge_status, ac.metadata AS charge_metadata,
97
+ COALESCE((SELECT sum(p.amount) FROM payment p
98
+ WHERE p.receivable_id = r.id AND p.status = 'confirmed'), 0) AS amount_paid,
99
+ GREATEST(0, COALESCE(CURRENT_DATE - r.due_date, 0))::int AS days_overdue
100
+ FROM receivable r
101
+ LEFT JOIN client c ON c.id = r.client_id AND c.deleted_at IS NULL
102
+ -- LATERAL, e não uma subquery por coluna: as três colunas da cobrança
103
+ -- precisam vir da MESMA linha. Três subqueries independentes poderiam, com
104
+ -- mais de uma cobrança viva, montar um Frankenstein com o id de uma e os
105
+ -- meios de outra.
106
+ LEFT JOIN LATERAL (
107
+ SELECT ch.id, ch.status, ch.metadata
108
+ FROM charge ch
109
+ WHERE ch.receivable_id = r.id
110
+ AND ch.deleted_at IS NULL
111
+ AND ch.status NOT IN ('canceled', 'refunded')
112
+ ORDER BY ch.created_at DESC
113
+ LIMIT 1
114
+ ) ac ON true`;
115
+ // ── Competência ──────────────────────────────────────────────────────────────
116
+ const COMPETENCE_RE = /^\d{4}-(0[1-9]|1[0-2])$/;
117
+ export function assertCompetence(competence) {
118
+ if (!COMPETENCE_RE.test(competence)) {
119
+ throw new ValidationError('Competência deve estar no formato YYYY-MM, com mês entre 01 e 12');
120
+ }
121
+ }
122
+ /**
123
+ * Data de vencimento de uma competência, respeitando o `due_day` do honorário.
124
+ *
125
+ * `due_day` é limitado a 28 no schema justamente para não existir "dia 31 de
126
+ * fevereiro"; ainda assim clampamos ao último dia do mês, porque a regra de
127
+ * negócio não pode depender de uma constraint continuar existindo.
128
+ */
129
+ export function dueDateFor(competence, dueDay) {
130
+ assertCompetence(competence);
131
+ const [year, month] = competence.split('-').map(Number);
132
+ const lastDay = new Date(Date.UTC(year, month, 0)).getUTCDate();
133
+ const day = Math.min(Math.max(dueDay ?? lastDay, 1), lastDay);
134
+ return `${competence}-${String(day).padStart(2, '0')}`;
135
+ }
136
+ const DUE_DATE_RE = /^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/;
137
+ /**
138
+ * Janela tolerada entre a competência e o vencimento de um lançamento avulso.
139
+ *
140
+ * No fluxo por competência não existe folga: `dueDateFor` devolve sempre uma data
141
+ * DENTRO do mês da competência. O avulso relaxa isso de propósito — competência e
142
+ * vencimento são campos independentes do payload — e é justamente aí que um erro
143
+ * de digitação vira "honorários de março/2027 vencendo em agosto/2026" no e-mail
144
+ * que o cliente lê.
145
+ *
146
+ * A folga é assimétrica porque a prática comercial é assimétrica: faturar um mês
147
+ * adiantado acontece; dar três meses de prazo acontece; sete meses de distância,
148
+ * em qualquer direção, não é arranjo comercial — é dedo trocado.
149
+ */
150
+ const DUE_MONTHS_BEFORE_COMPETENCE = 1;
151
+ const DUE_MONTHS_AFTER_COMPETENCE = 3;
152
+ /**
153
+ * A competência e o vencimento informados fazem sentido juntos?
154
+ *
155
+ * Aritmética de mês em inteiros, não em `Date`: o que importa é a distância entre
156
+ * dois meses do calendário, e converter para instante só introduziria fuso onde
157
+ * não há hora nenhuma envolvida.
158
+ */
159
+ export function checkCompetenceDueDate(competence, dueDate) {
160
+ assertCompetence(competence);
161
+ if (!DUE_DATE_RE.test(dueDate)) {
162
+ throw new ValidationError('Vencimento deve estar no formato YYYY-MM-DD');
163
+ }
164
+ const monthIndex = (year, month) => year * 12 + (month - 1);
165
+ const [cy, cm] = competence.split('-').map(Number);
166
+ const [dy, dm] = dueDate.split('-').map(Number);
167
+ const monthsFromCompetence = monthIndex(dy, dm) - monthIndex(cy, cm);
168
+ const coherent = monthsFromCompetence >= -DUE_MONTHS_BEFORE_COMPETENCE &&
169
+ monthsFromCompetence <= DUE_MONTHS_AFTER_COMPETENCE;
170
+ return { coherent, monthsFromCompetence };
171
+ }
172
+ /**
173
+ * Mensagem do 422. Diz o que veio, qual é a distância e como confirmar — quem lê
174
+ * precisa conseguir decidir entre "corrigi o dedo trocado" e "é isso mesmo".
175
+ */
176
+ function competenceMismatchMessage(competence, dueDate, monthsFromCompetence) {
177
+ const distance = Math.abs(monthsFromCompetence);
178
+ const direction = monthsFromCompetence < 0 ? 'antes' : 'depois';
179
+ const plural = distance === 1 ? 'mês' : 'meses';
180
+ return (`Competência ${competence} com vencimento em ${dueDate}: o vencimento está ` +
181
+ `${distance} ${plural} ${direction} do mês da competência. O esperado é entre ` +
182
+ `${DUE_MONTHS_BEFORE_COMPETENCE} mês antes e ${DUE_MONTHS_AFTER_COMPETENCE} meses ` +
183
+ `depois. Se a combinação está correta, reenvie confirmando explicitamente ` +
184
+ `(competenceMismatchAck).`);
185
+ }
186
+ /** Ver `FeeCompetenceVerdict`. Pura: nenhum I/O, nenhum relógio. */
187
+ export function classifyFeeForCompetence(fee, competence) {
188
+ if (fee.status === 'suspended')
189
+ return 'suspended';
190
+ if (fee.status !== 'active')
191
+ return 'canceled';
192
+ const first = `${competence}-01`;
193
+ const [year, month] = competence.split('-').map(Number);
194
+ const last = `${competence}-${String(new Date(Date.UTC(year, month, 0)).getUTCDate()).padStart(2, '0')}`;
195
+ // Vigência: o honorário precisa estar valendo em ALGUM dia da competência.
196
+ if (fee.startsOn && fee.startsOn > last)
197
+ return 'before_term';
198
+ if (fee.endsOn && fee.endsOn < first)
199
+ return 'after_term';
200
+ switch (fee.periodicity) {
201
+ case 'monthly':
202
+ return 'eligible';
203
+ // Trimestral/anual ancoram no mês de início da vigência — sem `startsOn` não
204
+ // há âncora, e gerar todo mês seria cobrar a mais. Fail-safe: não gera.
205
+ case 'quarterly': {
206
+ if (!fee.startsOn)
207
+ return 'no_anchor';
208
+ const anchor = Number(fee.startsOn.slice(5, 7));
209
+ return (month - anchor) % 3 === 0 ? 'eligible' : 'off_cycle';
210
+ }
211
+ case 'yearly': {
212
+ if (!fee.startsOn)
213
+ return 'no_anchor';
214
+ return Number(fee.startsOn.slice(5, 7)) === month ? 'eligible' : 'off_cycle';
215
+ }
216
+ // Avulso nunca é gerado em lote: nasce por lançamento manual.
217
+ case 'one_time':
218
+ return 'one_time';
219
+ default:
220
+ return 'off_cycle';
221
+ }
222
+ }
223
+ /** Um honorário vale para a competência? Considera vigência e periodicidade. */
224
+ export function feeAppliesTo(fee, competence) {
225
+ return classifyFeeForCompetence(fee, competence) === 'eligible';
226
+ }
227
+ /**
228
+ * Gera os recebíveis de uma competência a partir dos honorários ativos.
229
+ *
230
+ * Idempotente por construção: o índice único `(tenant_id, fee_agreement_id,
231
+ * competence)` do M0 é a garantia real, e o `ON CONFLICT DO NOTHING` a
232
+ * transforma em "pular" em vez de "explodir". Rodar duas vezes no mesmo mês não
233
+ * duplica cobrança — o que aqui não é detalhe técnico: cobrar o cliente duas
234
+ * vezes é o erro que destrói a confiança no sistema.
235
+ */
236
+ export async function generateReceivablesForCompetence(tx, input) {
237
+ assertCompetence(input.competence);
238
+ const source = input.source ?? 'manual';
239
+ const fees = await tx `
240
+ SELECT id, client_id, description, amount, periodicity, due_day, discount, status, starts_on, ends_on
241
+ FROM fee_agreement
242
+ WHERE deleted_at IS NULL
243
+ ${input.feeAgreementIds?.length ? tx `AND id IN ${tx(input.feeAgreementIds)}` : tx ``}
244
+ `;
245
+ const created = [];
246
+ let skipped = 0;
247
+ let notApplicable = 0;
248
+ for (const fee of fees) {
249
+ // A decisão de gerar vem de UM lugar só.
250
+ //
251
+ // Até a fase 2.3 havia duas: um `AND status = 'active'` no SELECT acima e a
252
+ // checagem de status dentro de `feeAppliesTo`. As duas concordavam, e por
253
+ // isso o arranjo parecia inofensivo — mas um teste de mutação mostrou o
254
+ // custo: com a regra do status quebrada dentro da função, o SELECT continuava
255
+ // segurando, e nenhum teste de "suspenso não gera" reprovava. A garantia
256
+ // estava numa cláusula SQL que ninguém estava testando, enquanto o dry-run
257
+ // — que decide se o scheduler pode ser ligado — usava a OUTRA cópia.
258
+ //
259
+ // Duas cópias de uma regra financeira só precisam divergir uma vez.
260
+ const verdict = classifyFeeForCompetence({
261
+ periodicity: fee.periodicity,
262
+ startsOn: iso(fee.starts_on),
263
+ endsOn: iso(fee.ends_on),
264
+ status: fee.status,
265
+ }, input.competence);
266
+ if (verdict !== 'eligible') {
267
+ // Suspenso e encerrado ficam FORA da contagem, e não é descuido: quem lê
268
+ // "3 fora de vigência" na tela está perguntando quantos acordos vigentes o
269
+ // calendário deixou de fora nesta competência. Um acordo cancelado no ano
270
+ // passado não é resposta a essa pergunta, e somá-lo aqui inflaria o número
271
+ // todo mês, para sempre, com o acervo morto do escritório.
272
+ if (verdict !== 'suspended' && verdict !== 'canceled')
273
+ notApplicable += 1;
274
+ continue;
275
+ }
276
+ // O desconto acordado entra no valor do recebível: a dívida é o líquido, e
277
+ // guardar o bruto obrigaria toda leitura a lembrar de subtrair.
278
+ const amount = Math.max(0, Number(fee.amount) - Number(fee.discount));
279
+ const dueDate = dueDateFor(input.competence, fee.due_day);
280
+ const receivableId = uuidv7();
281
+ const rows = await tx `
282
+ INSERT INTO receivable (id, tenant_id, client_id, fee_agreement_id, competence,
283
+ amount, status, due_date, created_by, generated_by)
284
+ VALUES (${receivableId},
285
+ (NULLIF(current_setting('app.current_tenant', true), ''))::uuid,
286
+ ${fee.client_id}, ${fee.id}, ${input.competence},
287
+ ${amount}, 'open', ${dueDate}, ${input.createdBy ?? null}, ${source})
288
+ -- O predicado precisa casar EXATAMENTE com o do índice parcial do M0,
289
+ -- senão o Postgres não reconhece o índice e o INSERT volta a estourar.
290
+ ON CONFLICT (tenant_id, fee_agreement_id, competence)
291
+ WHERE fee_agreement_id IS NOT NULL AND competence IS NOT NULL AND deleted_at IS NULL
292
+ DO NOTHING
293
+ RETURNING id
294
+ `;
295
+ if (!rows[0]) {
296
+ skipped += 1;
297
+ continue;
298
+ }
299
+ await tx `
300
+ INSERT INTO receivable_item (id, tenant_id, receivable_id, description, amount)
301
+ VALUES (${uuidv7()},
302
+ (NULLIF(current_setting('app.current_tenant', true), ''))::uuid,
303
+ ${receivableId}, ${fee.description}, ${amount})
304
+ `;
305
+ const full = await getReceivable(tx, receivableId);
306
+ created.push(full);
307
+ }
308
+ return { competence: input.competence, created, skipped, notApplicable };
309
+ }
310
+ /**
311
+ * Lançamento avulso — serviço extra que não vem de honorário recorrente.
312
+ *
313
+ * A guarda de coerência mora AQUI, e não na rota, porque quem chama o domínio
314
+ * direto (script de importação, backfill, outro serviço) precisa da mesma
315
+ * proteção que o operador tem pela tela. Uma validação só na borda HTTP protege
316
+ * a borda HTTP.
317
+ */
318
+ export async function createOneOffReceivable(tx, input) {
319
+ if (input.amount <= 0)
320
+ throw new ValidationError('Valor deve ser maior que zero');
321
+ if (input.competence) {
322
+ const check = checkCompetenceDueDate(input.competence, input.dueDate);
323
+ if (!check.coherent && !input.competenceMismatchAck) {
324
+ throw new ValidationError(competenceMismatchMessage(input.competence, input.dueDate, check.monthsFromCompetence));
325
+ }
326
+ }
327
+ const id = uuidv7();
328
+ const notes = input.notes?.trim() || null;
329
+ const serviceCategory = input.serviceCategory?.trim() || null;
330
+ const metadata = {};
331
+ if (notes)
332
+ metadata.notes = notes;
333
+ if (serviceCategory)
334
+ metadata.serviceCategory = serviceCategory;
335
+ // `ON CONFLICT DO NOTHING` sobre a chave da tentativa: quem chega primeiro
336
+ // grava, quem repete não insere e é devolvido ao recebível existente. A
337
+ // alternativa — consultar antes e inserir depois — deixa uma janela entre as
338
+ // duas operações, e duplo clique acontece exatamente dentro dela.
339
+ const inserted = await tx `
340
+ INSERT INTO receivable (id, tenant_id, client_id, fee_agreement_id, competence,
341
+ amount, status, due_date, created_by, idempotency_key, metadata)
342
+ VALUES (${id},
343
+ (NULLIF(current_setting('app.current_tenant', true), ''))::uuid,
344
+ ${input.clientId}, NULL, ${input.competence ?? null},
345
+ ${input.amount}, 'open', ${input.dueDate}, ${input.createdBy ?? null},
346
+ ${input.idempotencyKey ?? null}, ${tx.json(metadata)})
347
+ ON CONFLICT (tenant_id, idempotency_key) WHERE idempotency_key IS NOT NULL
348
+ DO NOTHING
349
+ RETURNING id
350
+ `;
351
+ if (!inserted[0]) {
352
+ // Tentativa repetida. Devolve o que a primeira criou — nunca um erro: para
353
+ // quem clicou duas vezes, o lançamento deu certo, e um 409 mandaria a pessoa
354
+ // tentar de novo.
355
+ const existing = await tx `
356
+ SELECT id FROM receivable
357
+ WHERE idempotency_key = ${input.idempotencyKey ?? null} AND deleted_at IS NULL
358
+ `;
359
+ if (!existing[0])
360
+ throw new ConflictError('Lançamento avulso em conflito');
361
+ return getReceivable(tx, existing[0].id);
362
+ }
363
+ await tx `
364
+ INSERT INTO receivable_item (id, tenant_id, receivable_id, description, amount)
365
+ VALUES (${uuidv7()},
366
+ (NULLIF(current_setting('app.current_tenant', true), ''))::uuid,
367
+ ${id}, ${input.description}, ${input.amount})
368
+ `;
369
+ return getReceivable(tx, id);
370
+ }
371
+ /**
372
+ * O WHERE compartilhado entre a página e a contagem.
373
+ *
374
+ * Escrito uma vez de propósito: quando a lista e o total repetiam os mesmos
375
+ * predicados lado a lado, bastava acrescentar um filtro num deles para a tela
376
+ * dizer "mostrando 12 de 47" com os dois números medindo carteiras diferentes.
377
+ */
378
+ function receivableWhere(tx, filter) {
379
+ const search = filter.search?.trim();
380
+ return tx `
381
+ r.deleted_at IS NULL
382
+ ${filter.clientId ? tx `AND r.client_id = ${filter.clientId}` : tx ``}
383
+ ${filter.competence ? tx `AND r.competence = ${filter.competence}` : tx ``}
384
+ ${filter.status ? tx `AND ${tx.unsafe(EFFECTIVE_STATUS_SQL)} = ${filter.status}` : tx ``}
385
+ ${filter.openOnly ? tx `AND r.status IN ('open','partially_paid','overdue')` : tx ``}
386
+ ${filter.overdueOnly ? tx `AND ${tx.unsafe(EFFECTIVE_STATUS_SQL)} = 'overdue'` : tx ``}
387
+ ${filter.origin
388
+ ? filter.origin === 'recurring'
389
+ ? tx `AND r.fee_agreement_id IS NOT NULL`
390
+ : tx `AND r.fee_agreement_id IS NULL`
391
+ : tx ``}
392
+ ${filter.dueFrom ? tx `AND r.due_date >= ${filter.dueFrom}::date` : tx ``}
393
+ ${filter.dueTo ? tx `AND r.due_date <= ${filter.dueTo}::date` : tx ``}
394
+ ${search
395
+ ? tx `AND (c.display_name ILIKE ${'%' + search + '%'}
396
+ OR EXISTS (SELECT 1 FROM receivable_item i
397
+ WHERE i.receivable_id = r.id
398
+ AND i.description ILIKE ${'%' + search + '%'}))`
399
+ : tx ``}
400
+ `;
401
+ }
402
+ export async function listReceivables(tx, filter = {}) {
403
+ const limit = Math.min(Math.max(filter.limit ?? 50, 1), 200);
404
+ const offset = Math.max(filter.offset ?? 0, 0);
405
+ const where = receivableWhere(tx, filter);
406
+ const rows = await tx `
407
+ ${tx.unsafe(SELECT_RECEIVABLE)}
408
+ WHERE ${where}
409
+ ORDER BY r.due_date NULLS LAST, r.created_at
410
+ LIMIT ${limit} OFFSET ${offset}
411
+ `;
412
+ // O `LEFT JOIN client` acompanha a contagem porque a busca textual alcança o
413
+ // nome do cliente: sem ele, filtrar por nome quebraria o total.
414
+ const totals = await tx `
415
+ SELECT count(*) AS n FROM receivable r
416
+ LEFT JOIN client c ON c.id = r.client_id AND c.deleted_at IS NULL
417
+ WHERE ${where}
418
+ `;
419
+ return { items: rows.map(mapReceivable), total: Number(totals[0]?.n ?? 0) };
420
+ }
421
+ export async function getReceivable(tx, id) {
422
+ const rows = await tx `
423
+ ${tx.unsafe(SELECT_RECEIVABLE)} WHERE r.id = ${id} AND r.deleted_at IS NULL
424
+ `;
425
+ const row = rows[0];
426
+ if (!row)
427
+ throw new NotFoundError('Recebível não encontrado');
428
+ return mapReceivable(row);
429
+ }
430
+ export async function listReceivableItems(tx, receivableId) {
431
+ const rows = await tx `
432
+ SELECT id, receivable_id, description, amount, service_item_ref, created_at
433
+ FROM receivable_item WHERE receivable_id = ${receivableId} ORDER BY created_at
434
+ `;
435
+ return rows.map((r) => ({
436
+ id: r.id,
437
+ receivableId: r.receivable_id,
438
+ description: r.description,
439
+ amount: Number(r.amount),
440
+ serviceItemRef: r.service_item_ref,
441
+ createdAt: r.created_at.toISOString(),
442
+ }));
443
+ }
444
+ export async function listPayments(tx, receivableId) {
445
+ const rows = await tx `
446
+ SELECT id, receivable_id, charge_id, amount, method, status, paid_at, created_at
447
+ FROM payment WHERE receivable_id = ${receivableId} ORDER BY paid_at
448
+ `;
449
+ return rows.map((r) => ({
450
+ id: r.id,
451
+ receivableId: r.receivable_id,
452
+ chargeId: r.charge_id,
453
+ amount: Number(r.amount),
454
+ method: r.method,
455
+ status: r.status,
456
+ paidAt: r.paid_at.toISOString(),
457
+ createdAt: r.created_at.toISOString(),
458
+ }));
459
+ }
460
+ /**
461
+ * Registra dinheiro recebido e reavalia o status do recebível.
462
+ *
463
+ * A soma dos pagamentos confirmados é a fonte da verdade do que foi pago — o
464
+ * status é consequência dela, nunca o contrário. Por isso o recálculo lê a soma
465
+ * do banco em vez de somar em memória: dois lançamentos concorrentes não podem
466
+ * produzir um `paid` com saldo em aberto.
467
+ */
468
+ export async function registerPayment(tx, input) {
469
+ if (input.amount <= 0)
470
+ throw new ValidationError('Valor do pagamento deve ser maior que zero');
471
+ const current = await getReceivable(tx, input.receivableId);
472
+ if (current.status === 'canceled') {
473
+ throw new ConflictError('Recebível cancelado não aceita baixa');
474
+ }
475
+ if (input.amount > current.outstandingAmount + 0.001) {
476
+ throw new ValidationError(`Valor excede o saldo em aberto (${current.outstandingAmount.toFixed(2)})`);
477
+ }
478
+ await tx `
479
+ INSERT INTO payment (id, tenant_id, receivable_id, charge_id, amount, method, status, paid_at, metadata)
480
+ VALUES (${uuidv7()},
481
+ (NULLIF(current_setting('app.current_tenant', true), ''))::uuid,
482
+ ${input.receivableId}, ${input.chargeId ?? null}, ${input.amount},
483
+ ${input.method ?? 'manual'}, 'confirmed',
484
+ ${input.paidAt ?? new Date().toISOString()},
485
+ ${tx.json({ note: input.note ?? null })})
486
+ `;
487
+ const [totals] = await tx `
488
+ SELECT COALESCE((SELECT sum(p.amount) FROM payment p
489
+ WHERE p.receivable_id = r.id AND p.status = 'confirmed'), 0) AS paid,
490
+ r.amount
491
+ FROM receivable r WHERE r.id = ${input.receivableId}
492
+ `;
493
+ const paid = Number(totals.paid);
494
+ const total = Number(totals.amount);
495
+ // Tolerância de um centavo: `numeric(14,2)` não sofre erro de ponto flutuante,
496
+ // mas o valor chega da borda HTTP como number — e 0.1+0.2 continua sendo
497
+ // 0.30000000000000004 em JavaScript.
498
+ const nextStatus = paid + 0.001 >= total ? 'paid' : 'partially_paid';
499
+ await tx `
500
+ UPDATE receivable
501
+ SET status = ${nextStatus},
502
+ updated_at = now(),
503
+ version = version + 1
504
+ WHERE id = ${input.receivableId}
505
+ `;
506
+ return getReceivable(tx, input.receivableId);
507
+ }
508
+ /**
509
+ * Anula a liquidação registrada para uma cobrança — o dinheiro nunca entrou.
510
+ *
511
+ * Não confundir com estorno. No estorno o dinheiro **entrou e saiu**: são dois
512
+ * fatos de caixa, a dívida foi quitada, e reabri-la seria cobrar de novo algo
513
+ * que foi pago. Aqui não há fato novo — há um fato anterior que deixou de valer,
514
+ * e manter o recebível quitado seria o sistema afirmando um recebimento que a
515
+ * própria origem já negou.
516
+ *
517
+ * **Nada é apagado.** A linha de `payment` permanece com valor, método e data em
518
+ * que se acreditou ter recebido; ela sai do saldo e passa a dizer quando e por
519
+ * que foi anulada. `charge.paid_at` também permanece — é o registro de quando a
520
+ * cobrança esteve liquidada.
521
+ *
522
+ * **Idempotente por construção:** o `UPDATE` só alcança pagamentos ainda
523
+ * `confirmed`. Uma segunda reversão do mesmo evento encontra zero linhas, não
524
+ * mexe em nada e devolve `reversedPayments: 0`. Não há contador a decrementar
525
+ * duas vezes.
526
+ *
527
+ * Só toca pagamentos **desta cobrança**. Uma baixa manual que o escritório deu
528
+ * por fora (`charge_id IS NULL`) é outro fato, de outra origem, e o gateway não
529
+ * tem autoridade sobre ela.
530
+ */
531
+ export async function reverseSettlementForCharge(tx, chargeId, reason) {
532
+ const reversed = await tx `
533
+ UPDATE payment
534
+ SET status = 'reversed', reversed_at = now(), reversal_reason = ${reason}
535
+ WHERE charge_id = ${chargeId} AND status = 'confirmed'
536
+ RETURNING receivable_id, amount
537
+ `;
538
+ // A cobrança sai de `paid` mesmo quando não havia pagamento a anular: o evento
539
+ // é da origem, e o estado tem de refletir o que ela diz. `reversed` não entra
540
+ // na lista de cobranças mortas — o boleto ou o PIX continuam pagáveis, e esta
541
+ // segue sendo a cobrança viva do recebível.
542
+ await tx `
543
+ UPDATE charge
544
+ SET status = 'reversed', reversed_at = now(), updated_at = now()
545
+ WHERE id = ${chargeId} AND status IN ('paid', 'sent', 'pending', 'overdue')
546
+ `;
547
+ const receivableId = reversed[0]?.receivable_id ?? null;
548
+ const reversedAmount = reversed.reduce((sum, r) => sum + Number(r.amount), 0);
549
+ if (!receivableId) {
550
+ return {
551
+ reversedPayments: reversed.length,
552
+ reversedAmount,
553
+ receivableId: null,
554
+ receivable: null,
555
+ };
556
+ }
557
+ // O status do recebível é recalculado a partir do que SOBROU de confirmado —
558
+ // nunca assumido como `open`. Uma baixa parcial anterior, ou uma baixa manual
559
+ // do escritório, continua valendo e o recebível continua parcialmente pago.
560
+ const [totals] = await tx `
561
+ SELECT COALESCE((SELECT sum(p.amount) FROM payment p
562
+ WHERE p.receivable_id = r.id AND p.status = 'confirmed'), 0) AS paid,
563
+ r.amount
564
+ FROM receivable r WHERE r.id = ${receivableId}
565
+ `;
566
+ const paid = Number(totals.paid);
567
+ const total = Number(totals.amount);
568
+ const nextStatus = paid + 0.001 >= total ? 'paid' : paid > 0 ? 'partially_paid' : 'open';
569
+ // `canceled`, `renegotiated` e `written_off` são decisões do escritório sobre
570
+ // a dívida, e um evento de gateway não as revoga.
571
+ await tx `
572
+ UPDATE receivable
573
+ SET status = ${nextStatus}, updated_at = now(), version = version + 1
574
+ WHERE id = ${receivableId}
575
+ AND status IN ('open', 'partially_paid', 'paid', 'overdue')
576
+ `;
577
+ return {
578
+ reversedPayments: reversed.length,
579
+ reversedAmount,
580
+ receivableId,
581
+ receivable: await getReceivable(tx, receivableId),
582
+ };
583
+ }
584
+ /**
585
+ * Cancela a obrigação, preservando o que já foi pago.
586
+ *
587
+ * ## Cancelar não é pagar, e não é estornar
588
+ *
589
+ * O que morre aqui é o **saldo em aberto**. O dinheiro que já entrou continua
590
+ * tendo entrado: os pagamentos não são tocados, e seguem somando em "Recebido".
591
+ * Transformar o saldo cancelado em recebimento inventaria receita; apagar o
592
+ * pagamento anterior apagaria dinheiro que existe na conta do escritório.
593
+ *
594
+ * ## Por que aceita pagamento parcial agora
595
+ *
596
+ * A versão anterior recusava qualquer recebível com pagamento — o que deixava
597
+ * sem saída exatamente o caso mais comum de cancelamento legítimo: cliente pagou
598
+ * parte, o serviço foi cancelado, e o resto não é mais devido. Sem esta operação,
599
+ * a única forma de tirar o saldo do painel seria fingir um pagamento ou apagar a
600
+ * linha no banco. As duas são piores.
601
+ *
602
+ * Recebível **totalmente pago** continua recusado: ali não há obrigação a
603
+ * cancelar, e desfazer dinheiro recebido é estorno — outra operação, com outras
604
+ * consequências contábeis.
605
+ */
606
+ export async function cancelReceivable(tx, id, input) {
607
+ const motivo = input.reason?.trim() ?? '';
608
+ if (motivo.length < 3) {
609
+ throw new ValidationError('Informe o motivo do cancelamento — ele fica na trilha de auditoria e é o que explica, depois, por que esta cobrança deixou de existir.');
610
+ }
611
+ const current = await getReceivable(tx, id);
612
+ if (current.status === 'canceled') {
613
+ throw new ConflictError('Este recebível já está cancelado.');
614
+ }
615
+ if (current.outstandingAmount <= 0) {
616
+ // Sem saldo, não há obrigação a cancelar. Se houve pagamento, o caminho é
617
+ // estorno; se o valor era zero, não havia o que cobrar.
618
+ throw new ConflictError('Não há saldo em aberto para cancelar. Um recebível quitado se desfaz por estorno do pagamento, não por cancelamento.');
619
+ }
620
+ // Fail-closed: cobrança viva no gateway não pode ficar órfã de obrigação.
621
+ //
622
+ // Cancelar só do lado de cá deixaria no provedor um boleto que o cliente ainda
623
+ // consegue pagar — e o escritório achando que cancelou. É o mesmo defeito que
624
+ // a auditoria encontrou no cancelamento de cobrança, com o dinheiro indo na
625
+ // direção contrária.
626
+ const [viva] = await tx `
627
+ SELECT count(*)::int AS n FROM charge
628
+ WHERE receivable_id = ${id}
629
+ AND deleted_at IS NULL
630
+ AND provider <> 'manual'
631
+ AND status NOT IN ('canceled', 'refunded')
632
+ `;
633
+ if ((viva?.n ?? 0) > 0) {
634
+ throw new ConflictError('Este recebível tem cobrança emitida no provedor de pagamento. Cancele a cobrança primeiro — cancelar só aqui deixaria um boleto que o cliente ainda consegue pagar.', { code: 'RECEIVABLE_HAS_ACTIVE_EXTERNAL_CHARGE' });
635
+ }
636
+ const canceledOutstanding = current.outstandingAmount;
637
+ const preservedPayments = current.amountPaid;
638
+ await tx `
639
+ UPDATE receivable
640
+ SET status = 'canceled',
641
+ metadata = coalesce(metadata, '{}'::jsonb) || ${tx.json({
642
+ canceledReason: motivo,
643
+ canceledAt: new Date().toISOString(),
644
+ canceledBy: input.actorId ?? null,
645
+ canceledFromStatus: current.effectiveStatus,
646
+ canceledOutstanding,
647
+ preservedPayments,
648
+ })},
649
+ updated_at = now(),
650
+ version = version + 1
651
+ WHERE id = ${id} AND deleted_at IS NULL
652
+ `;
653
+ const atual = await getReceivable(tx, id);
654
+ return { ...atual, canceledOutstanding, preservedPayments };
655
+ }
656
+ /**
657
+ * Materializa a transição para `overdue`.
658
+ *
659
+ * A leitura já deriva o vencido (ver nota no topo) — esta função existe para dar
660
+ * um INSTANTE à transição, que é o que a régua de cobrança precisa para disparar
661
+ * `RECEIVABLE_OVERDUE` uma única vez. Retorna os ids afetados justamente para
662
+ * quem for emitir os eventos na próxima onda.
663
+ */
664
+ export async function markOverdueReceivables(tx) {
665
+ const rows = await tx `
666
+ UPDATE receivable
667
+ SET status = 'overdue', updated_at = now(), version = version + 1
668
+ WHERE deleted_at IS NULL
669
+ AND status = 'open'
670
+ AND due_date IS NOT NULL
671
+ AND due_date < CURRENT_DATE
672
+ RETURNING id
673
+ `;
674
+ return rows.map((r) => r.id);
675
+ }
676
+ export async function financialSummary(tx) {
677
+ const [r] = await tx `
678
+ -- Cancelado sai da base de OBRIGAÇÃO, e o dinheiro já recebido fica.
679
+ --
680
+ -- A base exclui cancelados porque eles não são mais exigíveis: não entram em
681
+ -- "A receber", "Vencido" nem "A vencer". Mas o pagamento que já entrou
682
+ -- ENTROU — cancelar a obrigação não devolve dinheiro ao cliente, e tirá-lo
683
+ -- de "Recebido" faria o total do escritório encolher sozinho no dia em que
684
+ -- alguém cancelasse um recebível parcialmente pago.
685
+ --
686
+ -- Por isso "Recebido" é somado à parte, sobre todos os recebíveis vivos.
687
+ WITH base AS (
688
+ SELECT r.*, ${tx.unsafe(EFFECTIVE_STATUS_SQL)} AS eff,
689
+ COALESCE((SELECT sum(p.amount) FROM payment p
690
+ WHERE p.receivable_id = r.id AND p.status = 'confirmed'), 0) AS paid
691
+ FROM receivable r WHERE r.deleted_at IS NULL AND r.status <> 'canceled'
692
+ ),
693
+ recebido AS (
694
+ SELECT COALESCE(sum(p.amount), 0) AS total
695
+ FROM payment p
696
+ JOIN receivable r ON r.id = p.receivable_id AND r.deleted_at IS NULL
697
+ WHERE p.status = 'confirmed'
698
+ )
699
+ SELECT
700
+ COALESCE(sum(amount), 0) AS total_receivable,
701
+ COALESCE(sum(amount - paid) FILTER (WHERE eff IN ('open','partially_paid','overdue')), 0) AS total_open,
702
+ COALESCE(sum(amount - paid) FILTER (WHERE eff = 'overdue'), 0) AS total_overdue,
703
+ (SELECT total FROM recebido) AS total_paid,
704
+ COALESCE(sum(amount - paid) FILTER (
705
+ WHERE eff IN ('open','partially_paid')
706
+ AND due_date BETWEEN CURRENT_DATE AND CURRENT_DATE + 7), 0) AS total_due_soon,
707
+ COALESCE(count(DISTINCT client_id) FILTER (WHERE eff = 'overdue'), 0)::int AS overdue_client_count,
708
+ COALESCE(count(*) FILTER (WHERE eff IN ('open','partially_paid','overdue')), 0)::int AS open_count,
709
+ COALESCE(count(*) FILTER (WHERE eff = 'overdue'), 0)::int AS overdue_count
710
+ FROM base
711
+ `;
712
+ return {
713
+ totalReceivable: Number(r.total_receivable),
714
+ totalOpen: Number(r.total_open),
715
+ totalOverdue: Number(r.total_overdue),
716
+ totalPaid: Number(r.total_paid),
717
+ totalDueSoon: Number(r.total_due_soon),
718
+ overdueClientCount: r.overdue_client_count,
719
+ openCount: r.open_count,
720
+ overdueCount: r.overdue_count,
721
+ };
722
+ }
723
+ /**
724
+ * Faixas de aging. Padrão do produto, **não** política imutável: as faixas são
725
+ * parâmetro justamente para que um escritório possa usar as suas sem alteração
726
+ * de código.
727
+ */
728
+ export const DEFAULT_AGING_BUCKETS = [
729
+ { label: '1-7', from: 1, to: 7 },
730
+ { label: '8-15', from: 8, to: 15 },
731
+ { label: '16-30', from: 16, to: 30 },
732
+ { label: '31-60', from: 31, to: 60 },
733
+ { label: '61-90', from: 61, to: 90 },
734
+ { label: '90+', from: 91, to: null },
735
+ ];
736
+ export async function agingBuckets(tx, buckets = DEFAULT_AGING_BUCKETS) {
737
+ const rows = await tx `
738
+ SELECT (CURRENT_DATE - r.due_date)::int AS days_overdue,
739
+ (r.amount - COALESCE((SELECT sum(p.amount) FROM payment p
740
+ WHERE p.receivable_id = r.id AND p.status = 'confirmed'), 0)) AS outstanding,
741
+ r.client_id
742
+ FROM receivable r
743
+ WHERE r.deleted_at IS NULL
744
+ AND r.status IN ('open','partially_paid','overdue')
745
+ AND r.due_date IS NOT NULL
746
+ AND r.due_date < CURRENT_DATE
747
+ `;
748
+ return buckets.map((b) => {
749
+ const inBucket = rows.filter((r) => r.days_overdue >= b.from && (b.to === null || r.days_overdue <= b.to));
750
+ return {
751
+ ...b,
752
+ amount: Number(inBucket.reduce((s, r) => s + Number(r.outstanding), 0).toFixed(2)),
753
+ count: inBucket.length,
754
+ clientCount: new Set(inBucket.map((r) => r.client_id)).size,
755
+ };
756
+ });
757
+ }
758
+ /** Situação financeira de um cliente — usada no console e no portal. */
759
+ export async function clientFinancialSummary(tx, clientId) {
760
+ const [r] = await tx `
761
+ WITH base AS (
762
+ SELECT r.*, ${tx.unsafe(EFFECTIVE_STATUS_SQL)} AS eff,
763
+ COALESCE((SELECT sum(p.amount) FROM payment p
764
+ WHERE p.receivable_id = r.id AND p.status = 'confirmed'), 0) AS paid
765
+ FROM receivable r
766
+ WHERE r.deleted_at IS NULL AND r.client_id = ${clientId} AND r.status <> 'canceled'
767
+ )
768
+ SELECT
769
+ COALESCE(sum(amount - paid) FILTER (WHERE eff IN ('open','partially_paid','overdue')), 0) AS open,
770
+ COALESCE(sum(amount - paid) FILTER (WHERE eff = 'overdue'), 0) AS overdue,
771
+ COALESCE(sum(paid), 0) AS paid,
772
+ min(due_date) FILTER (WHERE eff IN ('open','partially_paid')) AS next_due
773
+ FROM base
774
+ `;
775
+ return {
776
+ open: Number(r.open),
777
+ overdue: Number(r.overdue),
778
+ paid: Number(r.paid),
779
+ nextDueDate: iso(r.next_due),
780
+ };
781
+ }
782
+ export { OPEN_STATUSES };
783
+ //# sourceMappingURL=ar-repository.js.map