@open-mercato/core 0.6.8-develop.6924.1.a8d208fcdc → 0.6.8-develop.6930.1.1e5976efc3

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 (453) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/generated/entities/eudr_due_diligence_statement/index.js +47 -0
  3. package/dist/generated/entities/eudr_due_diligence_statement/index.js.map +7 -0
  4. package/dist/generated/entities/eudr_evidence_submission/index.js +51 -0
  5. package/dist/generated/entities/eudr_evidence_submission/index.js.map +7 -0
  6. package/dist/generated/entities/eudr_mitigation_action/index.js +31 -0
  7. package/dist/generated/entities/eudr_mitigation_action/index.js.map +7 -0
  8. package/dist/generated/entities/eudr_plot/index.js +39 -0
  9. package/dist/generated/entities/eudr_plot/index.js.map +7 -0
  10. package/dist/generated/entities/eudr_product_mapping/index.js +31 -0
  11. package/dist/generated/entities/eudr_product_mapping/index.js.map +7 -0
  12. package/dist/generated/entities/eudr_risk_assessment/index.js +35 -0
  13. package/dist/generated/entities/eudr_risk_assessment/index.js.map +7 -0
  14. package/dist/generated/entities/role/index.js +2 -0
  15. package/dist/generated/entities/role/index.js.map +2 -2
  16. package/dist/generated/entities.ids.generated.js +9 -0
  17. package/dist/generated/entities.ids.generated.js.map +2 -2
  18. package/dist/generated/entity-fields-registry.js +121 -0
  19. package/dist/generated/entity-fields-registry.js.map +2 -2
  20. package/dist/helpers/integration/api.js +4 -0
  21. package/dist/helpers/integration/api.js.map +2 -2
  22. package/dist/modules/attachments/fields/attachment.js +5 -1
  23. package/dist/modules/attachments/fields/attachment.js.map +2 -2
  24. package/dist/modules/attachments/lib/crud.js +3 -1
  25. package/dist/modules/attachments/lib/crud.js.map +2 -2
  26. package/dist/modules/audit_logs/api/audit-logs/actions/redo/route.js +5 -0
  27. package/dist/modules/audit_logs/api/audit-logs/actions/redo/route.js.map +2 -2
  28. package/dist/modules/audit_logs/api/audit-logs/actions/undo/route.js +5 -0
  29. package/dist/modules/audit_logs/api/audit-logs/actions/undo/route.js.map +2 -2
  30. package/dist/modules/audit_logs/backend/audit-logs/page.js +4 -4
  31. package/dist/modules/audit_logs/backend/audit-logs/page.js.map +2 -2
  32. package/dist/modules/audit_logs/components/AuditLogsActions.js +9 -2
  33. package/dist/modules/audit_logs/components/AuditLogsActions.js.map +2 -2
  34. package/dist/modules/auth/api/login.js +5 -2
  35. package/dist/modules/auth/api/login.js.map +2 -2
  36. package/dist/modules/auth/api/users/route.js +8 -5
  37. package/dist/modules/auth/api/users/route.js.map +2 -2
  38. package/dist/modules/auth/backend/users/[id]/edit/page.js +15 -1
  39. package/dist/modules/auth/backend/users/[id]/edit/page.js.map +2 -2
  40. package/dist/modules/auth/backend/users/page.js +7 -1
  41. package/dist/modules/auth/backend/users/page.js.map +2 -2
  42. package/dist/modules/auth/commands/users.js +175 -76
  43. package/dist/modules/auth/commands/users.js.map +2 -2
  44. package/dist/modules/auth/data/entities.js +4 -0
  45. package/dist/modules/auth/data/entities.js.map +2 -2
  46. package/dist/modules/auth/lib/sessionIntegrity.js +1 -1
  47. package/dist/modules/auth/lib/sessionIntegrity.js.map +2 -2
  48. package/dist/modules/auth/lib/setup-app.js +1 -1
  49. package/dist/modules/auth/lib/setup-app.js.map +2 -2
  50. package/dist/modules/auth/migrations/Migration20260728134212_auth.js +14 -0
  51. package/dist/modules/auth/migrations/Migration20260728134212_auth.js.map +7 -0
  52. package/dist/modules/eudr/acl.js +43 -0
  53. package/dist/modules/eudr/acl.js.map +7 -0
  54. package/dist/modules/eudr/ai-agents.js +205 -0
  55. package/dist/modules/eudr/ai-agents.js.map +7 -0
  56. package/dist/modules/eudr/ai-tools/compliance-pack.js +495 -0
  57. package/dist/modules/eudr/ai-tools/compliance-pack.js.map +7 -0
  58. package/dist/modules/eudr/ai-tools/types.js +10 -0
  59. package/dist/modules/eudr/ai-tools/types.js.map +7 -0
  60. package/dist/modules/eudr/ai-tools.js +10 -0
  61. package/dist/modules/eudr/ai-tools.js.map +7 -0
  62. package/dist/modules/eudr/api/dashboard/widgets/compliance-overview/route.js +386 -0
  63. package/dist/modules/eudr/api/dashboard/widgets/compliance-overview/route.js.map +7 -0
  64. package/dist/modules/eudr/api/evidence-submissions/route.js +318 -0
  65. package/dist/modules/eudr/api/evidence-submissions/route.js.map +7 -0
  66. package/dist/modules/eudr/api/mitigation-actions/route.js +249 -0
  67. package/dist/modules/eudr/api/mitigation-actions/route.js.map +7 -0
  68. package/dist/modules/eudr/api/openapi.js +27 -0
  69. package/dist/modules/eudr/api/openapi.js.map +7 -0
  70. package/dist/modules/eudr/api/plots/import/route.js +294 -0
  71. package/dist/modules/eudr/api/plots/import/route.js.map +7 -0
  72. package/dist/modules/eudr/api/plots/route.js +279 -0
  73. package/dist/modules/eudr/api/plots/route.js.map +7 -0
  74. package/dist/modules/eudr/api/product-mappings/route.js +257 -0
  75. package/dist/modules/eudr/api/product-mappings/route.js.map +7 -0
  76. package/dist/modules/eudr/api/product-mappings/suggestions/apply/route.js +298 -0
  77. package/dist/modules/eudr/api/product-mappings/suggestions/apply/route.js.map +7 -0
  78. package/dist/modules/eudr/api/product-mappings/suggestions/route.js +132 -0
  79. package/dist/modules/eudr/api/product-mappings/suggestions/route.js.map +7 -0
  80. package/dist/modules/eudr/api/reports/annual/route.js +266 -0
  81. package/dist/modules/eudr/api/reports/annual/route.js.map +7 -0
  82. package/dist/modules/eudr/api/risk-assessments/route.js +300 -0
  83. package/dist/modules/eudr/api/risk-assessments/route.js.map +7 -0
  84. package/dist/modules/eudr/api/statements/[id]/export/route.js +631 -0
  85. package/dist/modules/eudr/api/statements/[id]/export/route.js.map +7 -0
  86. package/dist/modules/eudr/api/statements/[id]/readiness/route.js +111 -0
  87. package/dist/modules/eudr/api/statements/[id]/readiness/route.js.map +7 -0
  88. package/dist/modules/eudr/api/statements/route.js +314 -0
  89. package/dist/modules/eudr/api/statements/route.js.map +7 -0
  90. package/dist/modules/eudr/api/suppliers/compliance/route.js +173 -0
  91. package/dist/modules/eudr/api/suppliers/compliance/route.js.map +7 -0
  92. package/dist/modules/eudr/backend/eudr/evidence-submissions/[id]/page.js +468 -0
  93. package/dist/modules/eudr/backend/eudr/evidence-submissions/[id]/page.js.map +7 -0
  94. package/dist/modules/eudr/backend/eudr/evidence-submissions/[id]/page.meta.js +16 -0
  95. package/dist/modules/eudr/backend/eudr/evidence-submissions/[id]/page.meta.js.map +7 -0
  96. package/dist/modules/eudr/backend/eudr/evidence-submissions/create/page.js +351 -0
  97. package/dist/modules/eudr/backend/eudr/evidence-submissions/create/page.js.map +7 -0
  98. package/dist/modules/eudr/backend/eudr/evidence-submissions/create/page.meta.js +17 -0
  99. package/dist/modules/eudr/backend/eudr/evidence-submissions/create/page.meta.js.map +7 -0
  100. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js +313 -0
  101. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js.map +7 -0
  102. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.meta.js +16 -0
  103. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.meta.js.map +7 -0
  104. package/dist/modules/eudr/backend/eudr/page.js +360 -0
  105. package/dist/modules/eudr/backend/eudr/page.js.map +7 -0
  106. package/dist/modules/eudr/backend/eudr/page.meta.js +16 -0
  107. package/dist/modules/eudr/backend/eudr/page.meta.js.map +7 -0
  108. package/dist/modules/eudr/backend/eudr/plots/[id]/page.js +346 -0
  109. package/dist/modules/eudr/backend/eudr/plots/[id]/page.js.map +7 -0
  110. package/dist/modules/eudr/backend/eudr/plots/[id]/page.meta.js +16 -0
  111. package/dist/modules/eudr/backend/eudr/plots/[id]/page.meta.js.map +7 -0
  112. package/dist/modules/eudr/backend/eudr/plots/create/page.js +253 -0
  113. package/dist/modules/eudr/backend/eudr/plots/create/page.js.map +7 -0
  114. package/dist/modules/eudr/backend/eudr/plots/create/page.meta.js +17 -0
  115. package/dist/modules/eudr/backend/eudr/plots/create/page.meta.js.map +7 -0
  116. package/dist/modules/eudr/backend/eudr/plots/page.js +386 -0
  117. package/dist/modules/eudr/backend/eudr/plots/page.js.map +7 -0
  118. package/dist/modules/eudr/backend/eudr/plots/page.meta.js +16 -0
  119. package/dist/modules/eudr/backend/eudr/plots/page.meta.js.map +7 -0
  120. package/dist/modules/eudr/backend/eudr/product-mappings/[id]/page.js +253 -0
  121. package/dist/modules/eudr/backend/eudr/product-mappings/[id]/page.js.map +7 -0
  122. package/dist/modules/eudr/backend/eudr/product-mappings/[id]/page.meta.js +16 -0
  123. package/dist/modules/eudr/backend/eudr/product-mappings/[id]/page.meta.js.map +7 -0
  124. package/dist/modules/eudr/backend/eudr/product-mappings/create/page.js +174 -0
  125. package/dist/modules/eudr/backend/eudr/product-mappings/create/page.js.map +7 -0
  126. package/dist/modules/eudr/backend/eudr/product-mappings/create/page.meta.js +17 -0
  127. package/dist/modules/eudr/backend/eudr/product-mappings/create/page.meta.js.map +7 -0
  128. package/dist/modules/eudr/backend/eudr/product-mappings/page.js +306 -0
  129. package/dist/modules/eudr/backend/eudr/product-mappings/page.js.map +7 -0
  130. package/dist/modules/eudr/backend/eudr/product-mappings/page.meta.js +16 -0
  131. package/dist/modules/eudr/backend/eudr/product-mappings/page.meta.js.map +7 -0
  132. package/dist/modules/eudr/backend/eudr/risk-assessments/[id]/page.js +335 -0
  133. package/dist/modules/eudr/backend/eudr/risk-assessments/[id]/page.js.map +7 -0
  134. package/dist/modules/eudr/backend/eudr/risk-assessments/[id]/page.meta.js +16 -0
  135. package/dist/modules/eudr/backend/eudr/risk-assessments/[id]/page.meta.js.map +7 -0
  136. package/dist/modules/eudr/backend/eudr/risk-assessments/create/page.js +220 -0
  137. package/dist/modules/eudr/backend/eudr/risk-assessments/create/page.js.map +7 -0
  138. package/dist/modules/eudr/backend/eudr/risk-assessments/create/page.meta.js +17 -0
  139. package/dist/modules/eudr/backend/eudr/risk-assessments/create/page.meta.js.map +7 -0
  140. package/dist/modules/eudr/backend/eudr/risk-assessments/page.js +324 -0
  141. package/dist/modules/eudr/backend/eudr/risk-assessments/page.js.map +7 -0
  142. package/dist/modules/eudr/backend/eudr/risk-assessments/page.meta.js +16 -0
  143. package/dist/modules/eudr/backend/eudr/risk-assessments/page.meta.js.map +7 -0
  144. package/dist/modules/eudr/backend/eudr/statements/[id]/page.js +648 -0
  145. package/dist/modules/eudr/backend/eudr/statements/[id]/page.js.map +7 -0
  146. package/dist/modules/eudr/backend/eudr/statements/[id]/page.meta.js +16 -0
  147. package/dist/modules/eudr/backend/eudr/statements/[id]/page.meta.js.map +7 -0
  148. package/dist/modules/eudr/backend/eudr/statements/create/page.js +432 -0
  149. package/dist/modules/eudr/backend/eudr/statements/create/page.js.map +7 -0
  150. package/dist/modules/eudr/backend/eudr/statements/create/page.meta.js +17 -0
  151. package/dist/modules/eudr/backend/eudr/statements/create/page.meta.js.map +7 -0
  152. package/dist/modules/eudr/backend/eudr/statements/page.js +309 -0
  153. package/dist/modules/eudr/backend/eudr/statements/page.js.map +7 -0
  154. package/dist/modules/eudr/backend/eudr/statements/page.meta.js +16 -0
  155. package/dist/modules/eudr/backend/eudr/statements/page.meta.js.map +7 -0
  156. package/dist/modules/eudr/ce.js +56 -0
  157. package/dist/modules/eudr/ce.js.map +7 -0
  158. package/dist/modules/eudr/commands/evidence-submissions.js +571 -0
  159. package/dist/modules/eudr/commands/evidence-submissions.js.map +7 -0
  160. package/dist/modules/eudr/commands/index.js +7 -0
  161. package/dist/modules/eudr/commands/index.js.map +7 -0
  162. package/dist/modules/eudr/commands/lifecycle-events.js +19 -0
  163. package/dist/modules/eudr/commands/lifecycle-events.js.map +7 -0
  164. package/dist/modules/eudr/commands/mitigation-actions.js +488 -0
  165. package/dist/modules/eudr/commands/mitigation-actions.js.map +7 -0
  166. package/dist/modules/eudr/commands/plots.js +517 -0
  167. package/dist/modules/eudr/commands/plots.js.map +7 -0
  168. package/dist/modules/eudr/commands/product-mappings.js +468 -0
  169. package/dist/modules/eudr/commands/product-mappings.js.map +7 -0
  170. package/dist/modules/eudr/commands/risk-assessments.js +599 -0
  171. package/dist/modules/eudr/commands/risk-assessments.js.map +7 -0
  172. package/dist/modules/eudr/commands/statements.js +747 -0
  173. package/dist/modules/eudr/commands/statements.js.map +7 -0
  174. package/dist/modules/eudr/components/CountrySelectField.js +64 -0
  175. package/dist/modules/eudr/components/CountrySelectField.js.map +7 -0
  176. package/dist/modules/eudr/components/GeometryInput.js +133 -0
  177. package/dist/modules/eudr/components/GeometryInput.js.map +7 -0
  178. package/dist/modules/eudr/components/MappingSuggestionsDialog.js +307 -0
  179. package/dist/modules/eudr/components/MappingSuggestionsDialog.js.map +7 -0
  180. package/dist/modules/eudr/components/MitigationActionsSection.js +345 -0
  181. package/dist/modules/eudr/components/MitigationActionsSection.js.map +7 -0
  182. package/dist/modules/eudr/components/OrderSelectField.js +88 -0
  183. package/dist/modules/eudr/components/OrderSelectField.js.map +7 -0
  184. package/dist/modules/eudr/components/PlotImportDialog.js +229 -0
  185. package/dist/modules/eudr/components/PlotImportDialog.js.map +7 -0
  186. package/dist/modules/eudr/components/PlotMapPreview.js +35 -0
  187. package/dist/modules/eudr/components/PlotMapPreview.js.map +7 -0
  188. package/dist/modules/eudr/components/PlotMapPreviewImpl.js +97 -0
  189. package/dist/modules/eudr/components/PlotMapPreviewImpl.js.map +7 -0
  190. package/dist/modules/eudr/components/PlotMultiSelectField.js +198 -0
  191. package/dist/modules/eudr/components/PlotMultiSelectField.js.map +7 -0
  192. package/dist/modules/eudr/components/RiskCriteriaField.js +128 -0
  193. package/dist/modules/eudr/components/RiskCriteriaField.js.map +7 -0
  194. package/dist/modules/eudr/components/StatementLifecycleBar.js +274 -0
  195. package/dist/modules/eudr/components/StatementLifecycleBar.js.map +7 -0
  196. package/dist/modules/eudr/components/StatementReadinessChecklist.js +56 -0
  197. package/dist/modules/eudr/components/StatementReadinessChecklist.js.map +7 -0
  198. package/dist/modules/eudr/components/StatementRiskSection.js +179 -0
  199. package/dist/modules/eudr/components/StatementRiskSection.js.map +7 -0
  200. package/dist/modules/eudr/components/crudErrorI18n.js +31 -0
  201. package/dist/modules/eudr/components/crudErrorI18n.js.map +7 -0
  202. package/dist/modules/eudr/components/formConfig.js +593 -0
  203. package/dist/modules/eudr/components/formConfig.js.map +7 -0
  204. package/dist/modules/eudr/components/plotForm.js +68 -0
  205. package/dist/modules/eudr/components/plotForm.js.map +7 -0
  206. package/dist/modules/eudr/data/enrichers.js +62 -0
  207. package/dist/modules/eudr/data/enrichers.js.map +7 -0
  208. package/dist/modules/eudr/data/entities.js +437 -0
  209. package/dist/modules/eudr/data/entities.js.map +7 -0
  210. package/dist/modules/eudr/data/validators.js +271 -0
  211. package/dist/modules/eudr/data/validators.js.map +7 -0
  212. package/dist/modules/eudr/encryption.js +33 -0
  213. package/dist/modules/eudr/encryption.js.map +7 -0
  214. package/dist/modules/eudr/events.js +38 -0
  215. package/dist/modules/eudr/events.js.map +7 -0
  216. package/dist/modules/eudr/index.js +15 -0
  217. package/dist/modules/eudr/index.js.map +7 -0
  218. package/dist/modules/eudr/lib/annual-report.js +104 -0
  219. package/dist/modules/eudr/lib/annual-report.js.map +7 -0
  220. package/dist/modules/eudr/lib/completeness.js +64 -0
  221. package/dist/modules/eudr/lib/completeness.js.map +7 -0
  222. package/dist/modules/eudr/lib/detail-read-scope.js +16 -0
  223. package/dist/modules/eudr/lib/detail-read-scope.js.map +7 -0
  224. package/dist/modules/eudr/lib/geometry.js +142 -0
  225. package/dist/modules/eudr/lib/geometry.js.map +7 -0
  226. package/dist/modules/eudr/lib/notifications.js +56 -0
  227. package/dist/modules/eudr/lib/notifications.js.map +7 -0
  228. package/dist/modules/eudr/lib/plural.js +26 -0
  229. package/dist/modules/eudr/lib/plural.js.map +7 -0
  230. package/dist/modules/eudr/lib/reference-data.js +240 -0
  231. package/dist/modules/eudr/lib/reference-data.js.map +7 -0
  232. package/dist/modules/eudr/lib/species.js +10 -0
  233. package/dist/modules/eudr/lib/species.js.map +7 -0
  234. package/dist/modules/eudr/lib/statement-lifecycle.js +84 -0
  235. package/dist/modules/eudr/lib/statement-lifecycle.js.map +7 -0
  236. package/dist/modules/eudr/lib/statement-seeding.js +49 -0
  237. package/dist/modules/eudr/lib/statement-seeding.js.map +7 -0
  238. package/dist/modules/eudr/migrations/Migration20260706102002_eudr.js +15 -0
  239. package/dist/modules/eudr/migrations/Migration20260706102002_eudr.js.map +7 -0
  240. package/dist/modules/eudr/migrations/Migration20260706152612_eudr.js +24 -0
  241. package/dist/modules/eudr/migrations/Migration20260706152612_eudr.js.map +7 -0
  242. package/dist/modules/eudr/migrations/Migration20260722100000_eudr.js +15 -0
  243. package/dist/modules/eudr/migrations/Migration20260722100000_eudr.js.map +7 -0
  244. package/dist/modules/eudr/notifications.js +58 -0
  245. package/dist/modules/eudr/notifications.js.map +7 -0
  246. package/dist/modules/eudr/search.js +186 -0
  247. package/dist/modules/eudr/search.js.map +7 -0
  248. package/dist/modules/eudr/setup.js +12 -0
  249. package/dist/modules/eudr/setup.js.map +7 -0
  250. package/dist/modules/eudr/subscribers/notify-mitigation-completed.js +34 -0
  251. package/dist/modules/eudr/subscribers/notify-mitigation-completed.js.map +7 -0
  252. package/dist/modules/eudr/subscribers/notify-risk-concluded.js +35 -0
  253. package/dist/modules/eudr/subscribers/notify-risk-concluded.js.map +7 -0
  254. package/dist/modules/eudr/subscribers/notify-statement-reference-issued.js +37 -0
  255. package/dist/modules/eudr/subscribers/notify-statement-reference-issued.js.map +7 -0
  256. package/dist/modules/eudr/subscribers/notify-statement-submitted.js +34 -0
  257. package/dist/modules/eudr/subscribers/notify-statement-submitted.js.map +7 -0
  258. package/dist/modules/eudr/subscribers/notify-statement-withdrawn.js +34 -0
  259. package/dist/modules/eudr/subscribers/notify-statement-withdrawn.js.map +7 -0
  260. package/dist/modules/eudr/subscribers/recompute-completeness-on-attachment-created.js +124 -0
  261. package/dist/modules/eudr/subscribers/recompute-completeness-on-attachment-created.js.map +7 -0
  262. package/dist/modules/eudr/subscribers/recompute-completeness-on-attachment-deleted.js +22 -0
  263. package/dist/modules/eudr/subscribers/recompute-completeness-on-attachment-deleted.js.map +7 -0
  264. package/dist/modules/eudr/widgets/dashboard/compliance-overview/widget.client.js +203 -0
  265. package/dist/modules/eudr/widgets/dashboard/compliance-overview/widget.client.js.map +7 -0
  266. package/dist/modules/eudr/widgets/dashboard/compliance-overview/widget.js +23 -0
  267. package/dist/modules/eudr/widgets/dashboard/compliance-overview/widget.js.map +7 -0
  268. package/dist/modules/eudr/widgets/injection/eudr-product-column/widget.client.js +19 -0
  269. package/dist/modules/eudr/widgets/injection/eudr-product-column/widget.client.js.map +7 -0
  270. package/dist/modules/eudr/widgets/injection/eudr-product-column/widget.js +31 -0
  271. package/dist/modules/eudr/widgets/injection/eudr-product-column/widget.js.map +7 -0
  272. package/dist/modules/eudr/widgets/injection/order-compliance/widget.client.js +100 -0
  273. package/dist/modules/eudr/widgets/injection/order-compliance/widget.client.js.map +7 -0
  274. package/dist/modules/eudr/widgets/injection/order-compliance/widget.js +17 -0
  275. package/dist/modules/eudr/widgets/injection/order-compliance/widget.js.map +7 -0
  276. package/dist/modules/eudr/widgets/injection/supplier-compliance/widget.client.js +116 -0
  277. package/dist/modules/eudr/widgets/injection/supplier-compliance/widget.client.js.map +7 -0
  278. package/dist/modules/eudr/widgets/injection/supplier-compliance/widget.js +17 -0
  279. package/dist/modules/eudr/widgets/injection/supplier-compliance/widget.js.map +7 -0
  280. package/dist/modules/eudr/widgets/injection-table.js +32 -0
  281. package/dist/modules/eudr/widgets/injection-table.js.map +7 -0
  282. package/dist/modules/notifications/lib/notificationService.js +67 -3
  283. package/dist/modules/notifications/lib/notificationService.js.map +2 -2
  284. package/dist/modules/query_index/lib/engine.js +121 -48
  285. package/dist/modules/query_index/lib/engine.js.map +2 -2
  286. package/dist/modules/sales/api/documents/factory.js +17 -0
  287. package/dist/modules/sales/api/documents/factory.js.map +2 -2
  288. package/dist/modules/sales/commands/documents.js +32 -18
  289. package/dist/modules/sales/commands/documents.js.map +2 -2
  290. package/dist/modules/sales/data/entities.js +1 -0
  291. package/dist/modules/sales/data/entities.js.map +2 -2
  292. package/dist/modules/sales/migrations/Migration20260806120000_sales_tag_assignment_document_idx.js +17 -0
  293. package/dist/modules/sales/migrations/Migration20260806120000_sales_tag_assignment_document_idx.js.map +7 -0
  294. package/generated/entities/eudr_due_diligence_statement/index.ts +22 -0
  295. package/generated/entities/eudr_evidence_submission/index.ts +24 -0
  296. package/generated/entities/eudr_mitigation_action/index.ts +14 -0
  297. package/generated/entities/eudr_plot/index.ts +18 -0
  298. package/generated/entities/eudr_product_mapping/index.ts +14 -0
  299. package/generated/entities/eudr_risk_assessment/index.ts +16 -0
  300. package/generated/entities/role/index.ts +1 -0
  301. package/generated/entities.ids.generated.ts +9 -0
  302. package/generated/entity-fields-registry.ts +121 -0
  303. package/package.json +7 -7
  304. package/src/helpers/integration/api.ts +13 -0
  305. package/src/modules/attachments/fields/attachment.tsx +5 -0
  306. package/src/modules/attachments/lib/crud.ts +2 -0
  307. package/src/modules/audit_logs/api/audit-logs/actions/redo/route.ts +7 -0
  308. package/src/modules/audit_logs/api/audit-logs/actions/undo/route.ts +9 -0
  309. package/src/modules/audit_logs/backend/audit-logs/page.tsx +4 -4
  310. package/src/modules/audit_logs/components/AuditLogsActions.tsx +20 -4
  311. package/src/modules/auth/api/login.ts +9 -2
  312. package/src/modules/auth/api/users/route.ts +8 -4
  313. package/src/modules/auth/backend/users/[id]/edit/page.tsx +17 -1
  314. package/src/modules/auth/backend/users/page.tsx +11 -0
  315. package/src/modules/auth/commands/users.ts +251 -85
  316. package/src/modules/auth/data/entities.ts +3 -0
  317. package/src/modules/auth/i18n/de.json +6 -0
  318. package/src/modules/auth/i18n/en.json +6 -0
  319. package/src/modules/auth/i18n/es.json +6 -0
  320. package/src/modules/auth/i18n/ko.json +6 -0
  321. package/src/modules/auth/i18n/pl.json +6 -0
  322. package/src/modules/auth/lib/sessionIntegrity.ts +1 -1
  323. package/src/modules/auth/lib/setup-app.ts +1 -1
  324. package/src/modules/auth/migrations/.snapshot-open-mercato.json +16 -0
  325. package/src/modules/auth/migrations/Migration20260728134212_auth.ts +14 -0
  326. package/src/modules/eudr/acl.ts +39 -0
  327. package/src/modules/eudr/ai-agents.ts +258 -0
  328. package/src/modules/eudr/ai-tools/compliance-pack.ts +618 -0
  329. package/src/modules/eudr/ai-tools/types.ts +44 -0
  330. package/src/modules/eudr/ai-tools.ts +15 -0
  331. package/src/modules/eudr/api/dashboard/widgets/compliance-overview/route.ts +481 -0
  332. package/src/modules/eudr/api/evidence-submissions/route.ts +335 -0
  333. package/src/modules/eudr/api/mitigation-actions/route.ts +263 -0
  334. package/src/modules/eudr/api/openapi.ts +28 -0
  335. package/src/modules/eudr/api/plots/import/route.ts +369 -0
  336. package/src/modules/eudr/api/plots/route.ts +296 -0
  337. package/src/modules/eudr/api/product-mappings/route.ts +269 -0
  338. package/src/modules/eudr/api/product-mappings/suggestions/apply/route.ts +382 -0
  339. package/src/modules/eudr/api/product-mappings/suggestions/route.ts +169 -0
  340. package/src/modules/eudr/api/reports/annual/route.ts +457 -0
  341. package/src/modules/eudr/api/risk-assessments/route.ts +323 -0
  342. package/src/modules/eudr/api/statements/[id]/export/route.ts +713 -0
  343. package/src/modules/eudr/api/statements/[id]/readiness/route.ts +129 -0
  344. package/src/modules/eudr/api/statements/route.ts +329 -0
  345. package/src/modules/eudr/api/suppliers/compliance/route.ts +241 -0
  346. package/src/modules/eudr/backend/eudr/evidence-submissions/[id]/page.meta.ts +12 -0
  347. package/src/modules/eudr/backend/eudr/evidence-submissions/[id]/page.tsx +545 -0
  348. package/src/modules/eudr/backend/eudr/evidence-submissions/create/page.meta.ts +13 -0
  349. package/src/modules/eudr/backend/eudr/evidence-submissions/create/page.tsx +383 -0
  350. package/src/modules/eudr/backend/eudr/evidence-submissions/page.meta.ts +12 -0
  351. package/src/modules/eudr/backend/eudr/evidence-submissions/page.tsx +379 -0
  352. package/src/modules/eudr/backend/eudr/page.meta.ts +12 -0
  353. package/src/modules/eudr/backend/eudr/page.tsx +477 -0
  354. package/src/modules/eudr/backend/eudr/plots/[id]/page.meta.ts +12 -0
  355. package/src/modules/eudr/backend/eudr/plots/[id]/page.tsx +404 -0
  356. package/src/modules/eudr/backend/eudr/plots/create/page.meta.ts +13 -0
  357. package/src/modules/eudr/backend/eudr/plots/create/page.tsx +267 -0
  358. package/src/modules/eudr/backend/eudr/plots/page.meta.ts +12 -0
  359. package/src/modules/eudr/backend/eudr/plots/page.tsx +442 -0
  360. package/src/modules/eudr/backend/eudr/product-mappings/[id]/page.meta.ts +12 -0
  361. package/src/modules/eudr/backend/eudr/product-mappings/[id]/page.tsx +311 -0
  362. package/src/modules/eudr/backend/eudr/product-mappings/create/page.meta.ts +13 -0
  363. package/src/modules/eudr/backend/eudr/product-mappings/create/page.tsx +190 -0
  364. package/src/modules/eudr/backend/eudr/product-mappings/page.meta.ts +12 -0
  365. package/src/modules/eudr/backend/eudr/product-mappings/page.tsx +344 -0
  366. package/src/modules/eudr/backend/eudr/risk-assessments/[id]/page.meta.ts +12 -0
  367. package/src/modules/eudr/backend/eudr/risk-assessments/[id]/page.tsx +421 -0
  368. package/src/modules/eudr/backend/eudr/risk-assessments/create/page.meta.ts +13 -0
  369. package/src/modules/eudr/backend/eudr/risk-assessments/create/page.tsx +247 -0
  370. package/src/modules/eudr/backend/eudr/risk-assessments/page.meta.ts +12 -0
  371. package/src/modules/eudr/backend/eudr/risk-assessments/page.tsx +383 -0
  372. package/src/modules/eudr/backend/eudr/statements/[id]/page.meta.ts +12 -0
  373. package/src/modules/eudr/backend/eudr/statements/[id]/page.tsx +777 -0
  374. package/src/modules/eudr/backend/eudr/statements/create/page.meta.ts +13 -0
  375. package/src/modules/eudr/backend/eudr/statements/create/page.tsx +511 -0
  376. package/src/modules/eudr/backend/eudr/statements/page.meta.ts +12 -0
  377. package/src/modules/eudr/backend/eudr/statements/page.tsx +372 -0
  378. package/src/modules/eudr/ce.ts +52 -0
  379. package/src/modules/eudr/commands/evidence-submissions.ts +699 -0
  380. package/src/modules/eudr/commands/index.ts +6 -0
  381. package/src/modules/eudr/commands/lifecycle-events.ts +28 -0
  382. package/src/modules/eudr/commands/mitigation-actions.ts +574 -0
  383. package/src/modules/eudr/commands/plots.ts +627 -0
  384. package/src/modules/eudr/commands/product-mappings.ts +556 -0
  385. package/src/modules/eudr/commands/risk-assessments.ts +728 -0
  386. package/src/modules/eudr/commands/statements.ts +933 -0
  387. package/src/modules/eudr/components/CountrySelectField.tsx +77 -0
  388. package/src/modules/eudr/components/GeometryInput.tsx +170 -0
  389. package/src/modules/eudr/components/MappingSuggestionsDialog.tsx +385 -0
  390. package/src/modules/eudr/components/MitigationActionsSection.tsx +417 -0
  391. package/src/modules/eudr/components/OrderSelectField.tsx +116 -0
  392. package/src/modules/eudr/components/PlotImportDialog.tsx +277 -0
  393. package/src/modules/eudr/components/PlotMapPreview.tsx +46 -0
  394. package/src/modules/eudr/components/PlotMapPreviewImpl.tsx +111 -0
  395. package/src/modules/eudr/components/PlotMultiSelectField.tsx +238 -0
  396. package/src/modules/eudr/components/RiskCriteriaField.tsx +173 -0
  397. package/src/modules/eudr/components/StatementLifecycleBar.tsx +363 -0
  398. package/src/modules/eudr/components/StatementReadinessChecklist.tsx +82 -0
  399. package/src/modules/eudr/components/StatementRiskSection.tsx +242 -0
  400. package/src/modules/eudr/components/crudErrorI18n.ts +36 -0
  401. package/src/modules/eudr/components/formConfig.tsx +717 -0
  402. package/src/modules/eudr/components/plotForm.ts +75 -0
  403. package/src/modules/eudr/data/enrichers.ts +82 -0
  404. package/src/modules/eudr/data/entities.ts +369 -0
  405. package/src/modules/eudr/data/validators.ts +357 -0
  406. package/src/modules/eudr/encryption.ts +31 -0
  407. package/src/modules/eudr/events.ts +38 -0
  408. package/src/modules/eudr/i18n/de.json +747 -0
  409. package/src/modules/eudr/i18n/en.json +747 -0
  410. package/src/modules/eudr/i18n/es.json +747 -0
  411. package/src/modules/eudr/i18n/ko.json +747 -0
  412. package/src/modules/eudr/i18n/pl.json +747 -0
  413. package/src/modules/eudr/index.ts +13 -0
  414. package/src/modules/eudr/lib/annual-report.ts +120 -0
  415. package/src/modules/eudr/lib/completeness.ts +90 -0
  416. package/src/modules/eudr/lib/detail-read-scope.ts +44 -0
  417. package/src/modules/eudr/lib/geometry.ts +191 -0
  418. package/src/modules/eudr/lib/notifications.ts +85 -0
  419. package/src/modules/eudr/lib/plural.ts +36 -0
  420. package/src/modules/eudr/lib/reference-data.ts +128 -0
  421. package/src/modules/eudr/lib/species.ts +12 -0
  422. package/src/modules/eudr/lib/statement-lifecycle.ts +109 -0
  423. package/src/modules/eudr/lib/statement-seeding.ts +86 -0
  424. package/src/modules/eudr/migrations/.snapshot-open-mercato.json +2046 -0
  425. package/src/modules/eudr/migrations/Migration20260706102002_eudr.ts +16 -0
  426. package/src/modules/eudr/migrations/Migration20260706152612_eudr.ts +30 -0
  427. package/src/modules/eudr/migrations/Migration20260722100000_eudr.ts +17 -0
  428. package/src/modules/eudr/notifications.ts +56 -0
  429. package/src/modules/eudr/search.ts +212 -0
  430. package/src/modules/eudr/setup.ts +10 -0
  431. package/src/modules/eudr/subscribers/notify-mitigation-completed.ts +56 -0
  432. package/src/modules/eudr/subscribers/notify-risk-concluded.ts +58 -0
  433. package/src/modules/eudr/subscribers/notify-statement-reference-issued.ts +59 -0
  434. package/src/modules/eudr/subscribers/notify-statement-submitted.ts +49 -0
  435. package/src/modules/eudr/subscribers/notify-statement-withdrawn.ts +49 -0
  436. package/src/modules/eudr/subscribers/recompute-completeness-on-attachment-created.ts +189 -0
  437. package/src/modules/eudr/subscribers/recompute-completeness-on-attachment-deleted.ts +31 -0
  438. package/src/modules/eudr/widgets/dashboard/compliance-overview/widget.client.tsx +271 -0
  439. package/src/modules/eudr/widgets/dashboard/compliance-overview/widget.ts +24 -0
  440. package/src/modules/eudr/widgets/injection/eudr-product-column/widget.client.tsx +37 -0
  441. package/src/modules/eudr/widgets/injection/eudr-product-column/widget.ts +30 -0
  442. package/src/modules/eudr/widgets/injection/order-compliance/widget.client.tsx +131 -0
  443. package/src/modules/eudr/widgets/injection/order-compliance/widget.ts +16 -0
  444. package/src/modules/eudr/widgets/injection/supplier-compliance/widget.client.tsx +168 -0
  445. package/src/modules/eudr/widgets/injection/supplier-compliance/widget.ts +16 -0
  446. package/src/modules/eudr/widgets/injection-table.ts +31 -0
  447. package/src/modules/notifications/lib/notificationService.ts +83 -4
  448. package/src/modules/query_index/lib/engine.ts +139 -51
  449. package/src/modules/sales/api/documents/factory.ts +29 -0
  450. package/src/modules/sales/commands/documents.ts +65 -18
  451. package/src/modules/sales/data/entities.ts +1 -0
  452. package/src/modules/sales/migrations/.snapshot-open-mercato.json +10 -0
  453. package/src/modules/sales/migrations/Migration20260806120000_sales_tag_assignment_document_idx.ts +59 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/eudr/lib/completeness.ts"],
4
+ "sourcesContent": ["import { GEOJSON_TYPES } from '../data/validators'\n\nexport const COMPLETENESS_DIMENSIONS = ['origin_country', 'geolocation', 'quantity', 'harvest_period', 'producer', 'documents'] as const\nexport const REQUIRED_DIMENSIONS = COMPLETENESS_DIMENSIONS\nexport type CompletenessDimension = (typeof COMPLETENESS_DIMENSIONS)[number]\n\nexport type CompletenessInput = {\n originCountry?: string | null\n geolocation?: unknown\n quantityKg?: string | number | null\n harvestFrom?: Date | string | null\n harvestTo?: Date | string | null\n producerName?: string | null\n attachmentIds?: string[] | null\n}\n\nexport type CompletenessContext = {\n linkedAttachmentCount?: number\n activePlotCount?: number\n}\n\nexport type CompletenessResult = { score: number; missingFields: CompletenessDimension[] }\n\nfunction isOriginCountryComplete(value: string | null | undefined): boolean {\n return typeof value === 'string' && /^[A-Za-z]{2}$/.test(value.trim())\n}\n\nfunction isGeolocationComplete(value: unknown): boolean {\n if (value === null || typeof value !== 'object') return false\n const candidate = value as { type?: unknown }\n return typeof candidate.type === 'string' && GEOJSON_TYPES.includes(candidate.type as (typeof GEOJSON_TYPES)[number])\n}\n\nfunction isQuantityComplete(value: string | number | null | undefined): boolean {\n if (typeof value !== 'string' && typeof value !== 'number') return false\n const quantity = Number(value)\n return Number.isFinite(quantity) && quantity > 0\n}\n\nfunction parseDate(value: Date | string | null | undefined): Date | null {\n if (value == null) return null\n const date = value instanceof Date ? value : new Date(value)\n return Number.isNaN(date.getTime()) ? null : date\n}\n\nfunction isHarvestPeriodComplete(harvestFrom: Date | string | null | undefined, harvestTo: Date | string | null | undefined): boolean {\n const parsedHarvestFrom = parseDate(harvestFrom)\n const parsedHarvestTo = parseDate(harvestTo)\n return parsedHarvestFrom !== null && parsedHarvestTo !== null && parsedHarvestFrom <= parsedHarvestTo\n}\n\nfunction isProducerComplete(value: string | null | undefined): boolean {\n return typeof value === 'string' && value.trim().length > 0\n}\n\nfunction isDocumentsComplete(value: string[] | null | undefined): boolean {\n return Array.isArray(value) && value.length >= 1\n}\n\nexport function computeCompleteness(input: CompletenessInput, context: CompletenessContext = {}): CompletenessResult {\n const completionByDimension: Record<CompletenessDimension, boolean> = {\n origin_country: isOriginCountryComplete(input.originCountry),\n geolocation: isGeolocationComplete(input.geolocation) || (context.activePlotCount ?? 0) > 0,\n quantity: isQuantityComplete(input.quantityKg),\n harvest_period: isHarvestPeriodComplete(input.harvestFrom, input.harvestTo),\n producer: isProducerComplete(input.producerName),\n documents: isDocumentsComplete(input.attachmentIds) || (context.linkedAttachmentCount ?? 0) > 0,\n }\n\n const missingFields = COMPLETENESS_DIMENSIONS.filter((dimension) => !completionByDimension[dimension])\n const metCount = COMPLETENESS_DIMENSIONS.length - missingFields.length\n const score = Math.round((metCount / COMPLETENESS_DIMENSIONS.length) * 100)\n\n return { score, missingFields }\n}\n\nexport function computeSubmissionCompleteness(input: CompletenessInput, context?: CompletenessContext): CompletenessResult {\n return computeCompleteness(input, context)\n}\n\nexport const HARVEST_CUTOFF_DATE = new Date('2020-12-31T23:59:59.999Z')\n\nexport function computeHarvestCutoffWarning(\n harvestFrom: Date | string | null | undefined,\n harvestTo: Date | string | null | undefined,\n): 'harvest_before_cutoff' | null {\n const windowEnd = parseDate(harvestTo) ?? parseDate(harvestFrom)\n if (!windowEnd) return null\n return windowEnd.getTime() <= HARVEST_CUTOFF_DATE.getTime() ? 'harvest_before_cutoff' : null\n}\n"],
5
+ "mappings": "AAAA,SAAS,qBAAqB;AAEvB,MAAM,0BAA0B,CAAC,kBAAkB,eAAe,YAAY,kBAAkB,YAAY,WAAW;AACvH,MAAM,sBAAsB;AAoBnC,SAAS,wBAAwB,OAA2C;AAC1E,SAAO,OAAO,UAAU,YAAY,gBAAgB,KAAK,MAAM,KAAK,CAAC;AACvE;AAEA,SAAS,sBAAsB,OAAyB;AACtD,MAAI,UAAU,QAAQ,OAAO,UAAU,SAAU,QAAO;AACxD,QAAM,YAAY;AAClB,SAAO,OAAO,UAAU,SAAS,YAAY,cAAc,SAAS,UAAU,IAAsC;AACtH;AAEA,SAAS,mBAAmB,OAAoD;AAC9E,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,SAAU,QAAO;AACnE,QAAM,WAAW,OAAO,KAAK;AAC7B,SAAO,OAAO,SAAS,QAAQ,KAAK,WAAW;AACjD;AAEA,SAAS,UAAU,OAAsD;AACvE,MAAI,SAAS,KAAM,QAAO;AAC1B,QAAM,OAAO,iBAAiB,OAAO,QAAQ,IAAI,KAAK,KAAK;AAC3D,SAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,IAAI,OAAO;AAC/C;AAEA,SAAS,wBAAwB,aAA+C,WAAsD;AACpI,QAAM,oBAAoB,UAAU,WAAW;AAC/C,QAAM,kBAAkB,UAAU,SAAS;AAC3C,SAAO,sBAAsB,QAAQ,oBAAoB,QAAQ,qBAAqB;AACxF;AAEA,SAAS,mBAAmB,OAA2C;AACrE,SAAO,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS;AAC5D;AAEA,SAAS,oBAAoB,OAA6C;AACxE,SAAO,MAAM,QAAQ,KAAK,KAAK,MAAM,UAAU;AACjD;AAEO,SAAS,oBAAoB,OAA0B,UAA+B,CAAC,GAAuB;AACnH,QAAM,wBAAgE;AAAA,IACpE,gBAAgB,wBAAwB,MAAM,aAAa;AAAA,IAC3D,aAAa,sBAAsB,MAAM,WAAW,MAAM,QAAQ,mBAAmB,KAAK;AAAA,IAC1F,UAAU,mBAAmB,MAAM,UAAU;AAAA,IAC7C,gBAAgB,wBAAwB,MAAM,aAAa,MAAM,SAAS;AAAA,IAC1E,UAAU,mBAAmB,MAAM,YAAY;AAAA,IAC/C,WAAW,oBAAoB,MAAM,aAAa,MAAM,QAAQ,yBAAyB,KAAK;AAAA,EAChG;AAEA,QAAM,gBAAgB,wBAAwB,OAAO,CAAC,cAAc,CAAC,sBAAsB,SAAS,CAAC;AACrG,QAAM,WAAW,wBAAwB,SAAS,cAAc;AAChE,QAAM,QAAQ,KAAK,MAAO,WAAW,wBAAwB,SAAU,GAAG;AAE1E,SAAO,EAAE,OAAO,cAAc;AAChC;AAEO,SAAS,8BAA8B,OAA0B,SAAmD;AACzH,SAAO,oBAAoB,OAAO,OAAO;AAC3C;AAEO,MAAM,sBAAsB,oBAAI,KAAK,0BAA0B;AAE/D,SAAS,4BACd,aACA,WACgC;AAChC,QAAM,YAAY,UAAU,SAAS,KAAK,UAAU,WAAW;AAC/D,MAAI,CAAC,UAAW,QAAO;AACvB,SAAO,UAAU,QAAQ,KAAK,oBAAoB,QAAQ,IAAI,0BAA0B;AAC1F;",
6
+ "names": []
7
+ }
@@ -0,0 +1,16 @@
1
+ function resolveDetailReadScope(ctx) {
2
+ const tenantId = ctx.auth?.tenantId ?? null;
3
+ if (!tenantId) return null;
4
+ const scopedOrganizationIds = Array.isArray(ctx.organizationIds) && ctx.organizationIds.length ? Array.from(new Set(ctx.organizationIds)) : null;
5
+ const singleOrganizationId = ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null;
6
+ if (!scopedOrganizationIds && !singleOrganizationId) return null;
7
+ return {
8
+ tenantId,
9
+ organizationFilter: scopedOrganizationIds ? { $in: scopedOrganizationIds } : singleOrganizationId,
10
+ decryptionOrganizationId: singleOrganizationId
11
+ };
12
+ }
13
+ export {
14
+ resolveDetailReadScope
15
+ };
16
+ //# sourceMappingURL=detail-read-scope.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/eudr/lib/detail-read-scope.ts"],
4
+ "sourcesContent": ["export type DetailReadScope = {\n tenantId: string\n /** Matches the organization scope the list query itself used. */\n organizationFilter: string | { $in: string[] }\n /**\n * Fallback organization for decryption only. `decryptEntitiesWithFallbackScope`\n * prefers each record's own tenant/organization and consults this only when the\n * record carries none, so a single value stays correct for multi-org reads.\n */\n decryptionOrganizationId: string | null\n}\n\ntype DetailReadScopeContext = {\n auth?: { tenantId?: string | null; orgId?: string | null } | null\n organizationIds?: string[] | null\n selectedOrganizationId?: string | null\n}\n\n/**\n * Resolves the scope for an `afterList` detail re-fetch (the decryption pass).\n *\n * The list query is scoped by the full `organizationIds` array, so re-fetching by\n * a single organization silently drops decrypted fields for a multi-org user who\n * has not selected one. Returns null when no scope can be established, so callers\n * fail closed rather than reading across the tenant.\n */\nexport function resolveDetailReadScope(ctx: DetailReadScopeContext): DetailReadScope | null {\n const tenantId = ctx.auth?.tenantId ?? null\n if (!tenantId) return null\n\n const scopedOrganizationIds = Array.isArray(ctx.organizationIds) && ctx.organizationIds.length\n ? Array.from(new Set(ctx.organizationIds))\n : null\n const singleOrganizationId = ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null\n if (!scopedOrganizationIds && !singleOrganizationId) return null\n\n return {\n tenantId,\n organizationFilter: scopedOrganizationIds\n ? { $in: scopedOrganizationIds }\n : (singleOrganizationId as string),\n decryptionOrganizationId: singleOrganizationId,\n }\n}\n"],
5
+ "mappings": "AA0BO,SAAS,uBAAuB,KAAqD;AAC1F,QAAM,WAAW,IAAI,MAAM,YAAY;AACvC,MAAI,CAAC,SAAU,QAAO;AAEtB,QAAM,wBAAwB,MAAM,QAAQ,IAAI,eAAe,KAAK,IAAI,gBAAgB,SACpF,MAAM,KAAK,IAAI,IAAI,IAAI,eAAe,CAAC,IACvC;AACJ,QAAM,uBAAuB,IAAI,0BAA0B,IAAI,MAAM,SAAS;AAC9E,MAAI,CAAC,yBAAyB,CAAC,qBAAsB,QAAO;AAE5D,SAAO;AAAA,IACL;AAAA,IACA,oBAAoB,wBAChB,EAAE,KAAK,sBAAsB,IAC5B;AAAA,IACL,0BAA0B;AAAA,EAC5B;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,142 @@
1
+ const MAX_GEOMETRY_SIZE = 262144;
2
+ const MAX_IMPORT_SIZE = 1048576;
3
+ const MAX_FEATURE_COLLECTION_FEATURES = 500;
4
+ const EARTH_RADIUS_METERS = 63710088e-1;
5
+ const POINT_MAX_AREA_HA = 4;
6
+ function isRecord(value) {
7
+ return value !== null && typeof value === "object" && !Array.isArray(value);
8
+ }
9
+ function serializedLength(value) {
10
+ try {
11
+ const serialized = JSON.stringify(value);
12
+ return typeof serialized === "string" ? serialized.length : null;
13
+ } catch {
14
+ return null;
15
+ }
16
+ }
17
+ function decimalPlaces(value) {
18
+ const decimal = String(value).split(/[eE]/)[0]?.split(".")[1];
19
+ return decimal?.length ?? 0;
20
+ }
21
+ function validatePosition(input) {
22
+ if (!Array.isArray(input) || input.length < 2) return { ok: false, errorKey: "geometryOutOfRange" };
23
+ const [longitude, latitude] = input;
24
+ if (typeof longitude !== "number" || typeof latitude !== "number") return { ok: false, errorKey: "geometryOutOfRange" };
25
+ if (!Number.isFinite(longitude) || !Number.isFinite(latitude)) return { ok: false, errorKey: "geometryOutOfRange" };
26
+ if (longitude < -180 || longitude > 180 || latitude < -90 || latitude > 90) return { ok: false, errorKey: "geometryOutOfRange" };
27
+ return {
28
+ ok: true,
29
+ position: [longitude, latitude],
30
+ lowPrecision: decimalPlaces(longitude) < 6 || decimalPlaces(latitude) < 6
31
+ };
32
+ }
33
+ function positionsEqual(left, right) {
34
+ return left[0] === right[0] && left[1] === right[1];
35
+ }
36
+ function validateRing(input) {
37
+ if (!Array.isArray(input)) return { ok: false, errorKey: "geometryInvalid" };
38
+ if (input.length < 4) return { ok: false, errorKey: "geometryRingNotClosed" };
39
+ const ring = [];
40
+ let lowPrecision = false;
41
+ for (const candidate of input) {
42
+ const result = validatePosition(candidate);
43
+ if (!result.ok) return result;
44
+ ring.push(result.position);
45
+ lowPrecision = lowPrecision || result.lowPrecision;
46
+ }
47
+ if (!positionsEqual(ring[0], ring[ring.length - 1])) return { ok: false, errorKey: "geometryRingNotClosed" };
48
+ return { ok: true, ring, lowPrecision };
49
+ }
50
+ function validatePolygonCoordinates(input) {
51
+ if (!Array.isArray(input) || input.length === 0) return { ok: false, errorKey: "geometryInvalid" };
52
+ const rings = [];
53
+ let lowPrecision = false;
54
+ for (const candidate of input) {
55
+ const result = validateRing(candidate);
56
+ if (!result.ok) return result;
57
+ rings.push(result.ring);
58
+ lowPrecision = lowPrecision || result.lowPrecision;
59
+ }
60
+ return { ok: true, rings, lowPrecision };
61
+ }
62
+ function validateGeometry(input) {
63
+ if (!isRecord(input) || typeof input.type !== "string") return { ok: false, errorKey: "geometryInvalid" };
64
+ if (input.type === "Point") {
65
+ const result = validatePosition(input.coordinates);
66
+ if (!result.ok) return result;
67
+ return { ok: true, geometry: { type: "Point", coordinates: result.position }, lowPrecision: result.lowPrecision };
68
+ }
69
+ if (input.type === "Polygon") {
70
+ const result = validatePolygonCoordinates(input.coordinates);
71
+ if (!result.ok) return result;
72
+ return { ok: true, geometry: { type: "Polygon", coordinates: result.rings }, lowPrecision: result.lowPrecision };
73
+ }
74
+ if (input.type === "MultiPolygon") {
75
+ if (!Array.isArray(input.coordinates) || input.coordinates.length === 0) return { ok: false, errorKey: "geometryInvalid" };
76
+ const polygons = [];
77
+ let lowPrecision = false;
78
+ for (const candidate of input.coordinates) {
79
+ const result = validatePolygonCoordinates(candidate);
80
+ if (!result.ok) return result;
81
+ polygons.push(result.rings);
82
+ lowPrecision = lowPrecision || result.lowPrecision;
83
+ }
84
+ return { ok: true, geometry: { type: "MultiPolygon", coordinates: polygons }, lowPrecision };
85
+ }
86
+ return { ok: false, errorKey: "geometryInvalid" };
87
+ }
88
+ function toRadians(value) {
89
+ return value * Math.PI / 180;
90
+ }
91
+ function ringAreaSquareMeters(ring) {
92
+ let total = 0;
93
+ for (let index = 0; index < ring.length - 1; index += 1) {
94
+ const [longitude1, latitude1] = ring[index];
95
+ const [longitude2, latitude2] = ring[index + 1];
96
+ total += (toRadians(longitude2) - toRadians(longitude1)) * (2 + Math.sin(toRadians(latitude1)) + Math.sin(toRadians(latitude2)));
97
+ }
98
+ return Math.abs(total * EARTH_RADIUS_METERS * EARTH_RADIUS_METERS / 2);
99
+ }
100
+ function polygonAreaSquareMeters(rings) {
101
+ const [exterior, ...holes] = rings;
102
+ const holesArea = holes.reduce((sum, ring) => sum + ringAreaSquareMeters(ring), 0);
103
+ return Math.max(0, ringAreaSquareMeters(exterior) - holesArea);
104
+ }
105
+ function areaHa(geometry) {
106
+ const squareMeters = geometry.type === "Polygon" ? polygonAreaSquareMeters(geometry.coordinates) : geometry.coordinates.reduce((sum, polygon) => sum + polygonAreaSquareMeters(polygon), 0);
107
+ return Math.round(squareMeters / 1e4 * 1e4) / 1e4;
108
+ }
109
+ function validatePlotGeometry(input) {
110
+ const length = serializedLength(input);
111
+ if (length === null) return { ok: false, errorKey: "geometryInvalid" };
112
+ if (length > MAX_GEOMETRY_SIZE) return { ok: false, errorKey: "geometryTooLarge" };
113
+ const isFeature = isRecord(input) && input.type === "Feature";
114
+ const geometryInput = isFeature ? input.geometry : input;
115
+ const properties = isFeature && isRecord(input.properties) ? input.properties : {};
116
+ const result = validateGeometry(geometryInput);
117
+ if (!result.ok) return result;
118
+ const plotType = result.geometry.type === "Point" ? "point" : "polygon";
119
+ return {
120
+ ok: true,
121
+ feature: { type: "Feature", properties, geometry: result.geometry },
122
+ plotType,
123
+ computedAreaHa: result.geometry.type === "Point" ? null : areaHa(result.geometry),
124
+ warnings: result.lowPrecision ? ["low_precision"] : []
125
+ };
126
+ }
127
+ function collectFeatures(featureCollection) {
128
+ const length = serializedLength(featureCollection);
129
+ if (length === null) return { ok: false, errorKey: "geometryInvalid" };
130
+ if (length > MAX_IMPORT_SIZE) return { ok: false, errorKey: "importTooLarge" };
131
+ if (!isRecord(featureCollection) || featureCollection.type !== "FeatureCollection" || !Array.isArray(featureCollection.features)) {
132
+ return { ok: false, errorKey: "geometryInvalid" };
133
+ }
134
+ if (featureCollection.features.length > MAX_FEATURE_COLLECTION_FEATURES) return { ok: false, errorKey: "importTooManyFeatures" };
135
+ return { ok: true, features: featureCollection.features };
136
+ }
137
+ export {
138
+ POINT_MAX_AREA_HA,
139
+ collectFeatures,
140
+ validatePlotGeometry
141
+ };
142
+ //# sourceMappingURL=geometry.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/eudr/lib/geometry.ts"],
4
+ "sourcesContent": ["export type EudrPlotGeometryType = 'point' | 'polygon'\n\ntype GeoJsonPosition = [number, number]\ntype GeoJsonPoint = { type: 'Point'; coordinates: GeoJsonPosition }\ntype GeoJsonPolygon = { type: 'Polygon'; coordinates: GeoJsonPosition[][] }\ntype GeoJsonMultiPolygon = { type: 'MultiPolygon'; coordinates: GeoJsonPosition[][][] }\ntype GeoJsonSupportedGeometry = GeoJsonPoint | GeoJsonPolygon | GeoJsonMultiPolygon\n\nexport type GeoJsonFeature = {\n type: 'Feature'\n properties: Record<string, unknown>\n geometry: GeoJsonSupportedGeometry\n}\n\nexport type GeometryValidationResult =\n | { ok: true; feature: GeoJsonFeature; plotType: EudrPlotGeometryType; computedAreaHa: number | null; warnings: string[] }\n | { ok: false; errorKey: string }\n\ntype PositionValidationResult =\n | { ok: true; position: GeoJsonPosition; lowPrecision: boolean }\n | { ok: false; errorKey: 'geometryOutOfRange' }\n\nconst MAX_GEOMETRY_SIZE = 262_144\nconst MAX_IMPORT_SIZE = 1_048_576\nconst MAX_FEATURE_COLLECTION_FEATURES = 500\nconst EARTH_RADIUS_METERS = 6_371_008.8\n\nexport const POINT_MAX_AREA_HA = 4\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction serializedLength(value: unknown): number | null {\n try {\n const serialized = JSON.stringify(value)\n return typeof serialized === 'string' ? serialized.length : null\n } catch {\n return null\n }\n}\n\nfunction decimalPlaces(value: number): number {\n const decimal = String(value).split(/[eE]/)[0]?.split('.')[1]\n return decimal?.length ?? 0\n}\n\nfunction validatePosition(input: unknown): PositionValidationResult {\n if (!Array.isArray(input) || input.length < 2) return { ok: false, errorKey: 'geometryOutOfRange' }\n const [longitude, latitude] = input\n if (typeof longitude !== 'number' || typeof latitude !== 'number') return { ok: false, errorKey: 'geometryOutOfRange' }\n if (!Number.isFinite(longitude) || !Number.isFinite(latitude)) return { ok: false, errorKey: 'geometryOutOfRange' }\n if (longitude < -180 || longitude > 180 || latitude < -90 || latitude > 90) return { ok: false, errorKey: 'geometryOutOfRange' }\n\n return {\n ok: true,\n position: [longitude, latitude],\n lowPrecision: decimalPlaces(longitude) < 6 || decimalPlaces(latitude) < 6,\n }\n}\n\nfunction positionsEqual(left: GeoJsonPosition, right: GeoJsonPosition): boolean {\n return left[0] === right[0] && left[1] === right[1]\n}\n\nfunction validateRing(input: unknown): { ok: true; ring: GeoJsonPosition[]; lowPrecision: boolean } | { ok: false; errorKey: string } {\n if (!Array.isArray(input)) return { ok: false, errorKey: 'geometryInvalid' }\n if (input.length < 4) return { ok: false, errorKey: 'geometryRingNotClosed' }\n\n const ring: GeoJsonPosition[] = []\n let lowPrecision = false\n for (const candidate of input) {\n const result = validatePosition(candidate)\n if (!result.ok) return result\n ring.push(result.position)\n lowPrecision = lowPrecision || result.lowPrecision\n }\n\n if (!positionsEqual(ring[0], ring[ring.length - 1])) return { ok: false, errorKey: 'geometryRingNotClosed' }\n return { ok: true, ring, lowPrecision }\n}\n\nfunction validatePolygonCoordinates(input: unknown): { ok: true; rings: GeoJsonPosition[][]; lowPrecision: boolean } | { ok: false; errorKey: string } {\n if (!Array.isArray(input) || input.length === 0) return { ok: false, errorKey: 'geometryInvalid' }\n\n const rings: GeoJsonPosition[][] = []\n let lowPrecision = false\n for (const candidate of input) {\n const result = validateRing(candidate)\n if (!result.ok) return result\n rings.push(result.ring)\n lowPrecision = lowPrecision || result.lowPrecision\n }\n\n return { ok: true, rings, lowPrecision }\n}\n\nfunction validateGeometry(input: unknown): { ok: true; geometry: GeoJsonSupportedGeometry; lowPrecision: boolean } | { ok: false; errorKey: string } {\n if (!isRecord(input) || typeof input.type !== 'string') return { ok: false, errorKey: 'geometryInvalid' }\n\n if (input.type === 'Point') {\n const result = validatePosition(input.coordinates)\n if (!result.ok) return result\n return { ok: true, geometry: { type: 'Point', coordinates: result.position }, lowPrecision: result.lowPrecision }\n }\n\n if (input.type === 'Polygon') {\n const result = validatePolygonCoordinates(input.coordinates)\n if (!result.ok) return result\n return { ok: true, geometry: { type: 'Polygon', coordinates: result.rings }, lowPrecision: result.lowPrecision }\n }\n\n if (input.type === 'MultiPolygon') {\n if (!Array.isArray(input.coordinates) || input.coordinates.length === 0) return { ok: false, errorKey: 'geometryInvalid' }\n const polygons: GeoJsonPosition[][][] = []\n let lowPrecision = false\n for (const candidate of input.coordinates) {\n const result = validatePolygonCoordinates(candidate)\n if (!result.ok) return result\n polygons.push(result.rings)\n lowPrecision = lowPrecision || result.lowPrecision\n }\n return { ok: true, geometry: { type: 'MultiPolygon', coordinates: polygons }, lowPrecision }\n }\n\n return { ok: false, errorKey: 'geometryInvalid' }\n}\n\nfunction toRadians(value: number): number {\n return (value * Math.PI) / 180\n}\n\nfunction ringAreaSquareMeters(ring: GeoJsonPosition[]): number {\n let total = 0\n for (let index = 0; index < ring.length - 1; index += 1) {\n const [longitude1, latitude1] = ring[index]\n const [longitude2, latitude2] = ring[index + 1]\n total += (toRadians(longitude2) - toRadians(longitude1)) * (2 + Math.sin(toRadians(latitude1)) + Math.sin(toRadians(latitude2)))\n }\n return Math.abs((total * EARTH_RADIUS_METERS * EARTH_RADIUS_METERS) / 2)\n}\n\nfunction polygonAreaSquareMeters(rings: GeoJsonPosition[][]): number {\n const [exterior, ...holes] = rings\n const holesArea = holes.reduce((sum, ring) => sum + ringAreaSquareMeters(ring), 0)\n return Math.max(0, ringAreaSquareMeters(exterior) - holesArea)\n}\n\nfunction areaHa(geometry: GeoJsonPolygon | GeoJsonMultiPolygon): number {\n // Spherical-excess area is approximate, but is within about 0.5% at normal\n // plot scale and sufficient for the 4-ha EUDR threshold hinting flow.\n const squareMeters = geometry.type === 'Polygon'\n ? polygonAreaSquareMeters(geometry.coordinates)\n : geometry.coordinates.reduce((sum, polygon) => sum + polygonAreaSquareMeters(polygon), 0)\n\n return Math.round((squareMeters / 10_000) * 10_000) / 10_000\n}\n\nexport function validatePlotGeometry(input: unknown): GeometryValidationResult {\n const length = serializedLength(input)\n if (length === null) return { ok: false, errorKey: 'geometryInvalid' }\n if (length > MAX_GEOMETRY_SIZE) return { ok: false, errorKey: 'geometryTooLarge' }\n\n const isFeature = isRecord(input) && input.type === 'Feature'\n const geometryInput = isFeature ? input.geometry : input\n const properties = isFeature && isRecord(input.properties) ? input.properties : {}\n const result = validateGeometry(geometryInput)\n if (!result.ok) return result\n\n const plotType: EudrPlotGeometryType = result.geometry.type === 'Point' ? 'point' : 'polygon'\n return {\n ok: true,\n feature: { type: 'Feature', properties, geometry: result.geometry },\n plotType,\n computedAreaHa: result.geometry.type === 'Point' ? null : areaHa(result.geometry),\n warnings: result.lowPrecision ? ['low_precision'] : [],\n }\n}\n\nexport function collectFeatures(featureCollection: unknown): { ok: true; features: unknown[] } | { ok: false; errorKey: string } {\n const length = serializedLength(featureCollection)\n if (length === null) return { ok: false, errorKey: 'geometryInvalid' }\n if (length > MAX_IMPORT_SIZE) return { ok: false, errorKey: 'importTooLarge' }\n\n if (!isRecord(featureCollection) || featureCollection.type !== 'FeatureCollection' || !Array.isArray(featureCollection.features)) {\n return { ok: false, errorKey: 'geometryInvalid' }\n }\n\n if (featureCollection.features.length > MAX_FEATURE_COLLECTION_FEATURES) return { ok: false, errorKey: 'importTooManyFeatures' }\n return { ok: true, features: featureCollection.features }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,56 @@
1
+ import { createLogger } from "@open-mercato/shared/lib/logger";
2
+ import { buildFeatureNotificationFromType } from "../../notifications/lib/notificationBuilder.js";
3
+ import { resolveNotificationService } from "../../notifications/lib/notificationService.js";
4
+ import { notificationTypes } from "../notifications.js";
5
+ const logger = createLogger("eudr").child({ component: "notifications" });
6
+ const REQUIRED_FEATURE_BY_TYPE = {
7
+ "eudr.statement.submitted": "eudr.statements.manage",
8
+ "eudr.statement.reference_issued": "eudr.statements.manage",
9
+ "eudr.statement.withdrawn": "eudr.statements.manage",
10
+ "eudr.risk.non_negligible": "eudr.risk.manage",
11
+ "eudr.mitigation.completed": "eudr.risk.manage"
12
+ };
13
+ async function deliverEudrNotification({
14
+ container,
15
+ typeId,
16
+ payload
17
+ }) {
18
+ let notificationService;
19
+ try {
20
+ notificationService = resolveNotificationService(container);
21
+ } catch (err) {
22
+ logger.debug("Notification service unavailable; skipping EUDR notification", {
23
+ typeId,
24
+ entityId: payload.entityId,
25
+ err
26
+ });
27
+ return;
28
+ }
29
+ const typeDef = notificationTypes.find((candidate) => candidate.type === typeId);
30
+ if (!typeDef) {
31
+ throw new Error(`[internal] EUDR notification type is not registered: ${typeId}`);
32
+ }
33
+ const requiredFeature = REQUIRED_FEATURE_BY_TYPE[typeId];
34
+ const content = buildFeatureNotificationFromType(typeDef, {
35
+ requiredFeature,
36
+ bodyVariables: payload.bodyVariables,
37
+ sourceEntityType: payload.sourceEntityType,
38
+ sourceEntityId: payload.entityId,
39
+ linkHref: payload.linkHref,
40
+ groupKey: `${typeId}:${payload.entityId}:${payload.occurredAt}`
41
+ });
42
+ await notificationService.createForFeature(
43
+ {
44
+ ...content,
45
+ restrictRecipientsToOrganization: true
46
+ },
47
+ {
48
+ tenantId: payload.tenantId,
49
+ organizationId: payload.organizationId
50
+ }
51
+ );
52
+ }
53
+ export {
54
+ deliverEudrNotification
55
+ };
56
+ //# sourceMappingURL=notifications.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/eudr/lib/notifications.ts"],
4
+ "sourcesContent": ["import { createLogger } from '@open-mercato/shared/lib/logger'\nimport { buildFeatureNotificationFromType } from '../../notifications/lib/notificationBuilder'\nimport { resolveNotificationService } from '../../notifications/lib/notificationService'\nimport { notificationTypes } from '../notifications'\n\nconst logger = createLogger('eudr').child({ component: 'notifications' })\n\nexport type EudrNotificationTypeId =\n | 'eudr.statement.submitted'\n | 'eudr.statement.reference_issued'\n | 'eudr.statement.withdrawn'\n | 'eudr.risk.non_negligible'\n | 'eudr.mitigation.completed'\n\nexport type EudrNotificationContainer = {\n resolve: (name: string) => unknown\n}\n\ntype EudrNotificationPayload = {\n tenantId: string\n organizationId: string | null\n entityId: string\n occurredAt: string\n bodyVariables: Record<string, string>\n linkHref: string\n sourceEntityType: string\n}\n\ntype DeliverEudrNotificationInput = {\n container: EudrNotificationContainer\n typeId: EudrNotificationTypeId\n payload: EudrNotificationPayload\n}\n\nconst REQUIRED_FEATURE_BY_TYPE: Record<EudrNotificationTypeId, string> = {\n 'eudr.statement.submitted': 'eudr.statements.manage',\n 'eudr.statement.reference_issued': 'eudr.statements.manage',\n 'eudr.statement.withdrawn': 'eudr.statements.manage',\n 'eudr.risk.non_negligible': 'eudr.risk.manage',\n 'eudr.mitigation.completed': 'eudr.risk.manage',\n}\n\nexport async function deliverEudrNotification({\n container,\n typeId,\n payload,\n}: DeliverEudrNotificationInput): Promise<void> {\n let notificationService: ReturnType<typeof resolveNotificationService>\n try {\n notificationService = resolveNotificationService(container)\n } catch (err) {\n logger.debug('Notification service unavailable; skipping EUDR notification', {\n typeId,\n entityId: payload.entityId,\n err,\n })\n return\n }\n\n const typeDef = notificationTypes.find((candidate) => candidate.type === typeId)\n if (!typeDef) {\n throw new Error(`[internal] EUDR notification type is not registered: ${typeId}`)\n }\n\n const requiredFeature = REQUIRED_FEATURE_BY_TYPE[typeId]\n const content = buildFeatureNotificationFromType(typeDef, {\n requiredFeature,\n bodyVariables: payload.bodyVariables,\n sourceEntityType: payload.sourceEntityType,\n sourceEntityId: payload.entityId,\n linkHref: payload.linkHref,\n groupKey: `${typeId}:${payload.entityId}:${payload.occurredAt}`,\n })\n\n await notificationService.createForFeature(\n {\n ...content,\n restrictRecipientsToOrganization: true,\n },\n {\n tenantId: payload.tenantId,\n organizationId: payload.organizationId,\n },\n )\n}\n"],
5
+ "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,wCAAwC;AACjD,SAAS,kCAAkC;AAC3C,SAAS,yBAAyB;AAElC,MAAM,SAAS,aAAa,MAAM,EAAE,MAAM,EAAE,WAAW,gBAAgB,CAAC;AA6BxE,MAAM,2BAAmE;AAAA,EACvE,4BAA4B;AAAA,EAC5B,mCAAmC;AAAA,EACnC,4BAA4B;AAAA,EAC5B,4BAA4B;AAAA,EAC5B,6BAA6B;AAC/B;AAEA,eAAsB,wBAAwB;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AACF,GAAgD;AAC9C,MAAI;AACJ,MAAI;AACF,0BAAsB,2BAA2B,SAAS;AAAA,EAC5D,SAAS,KAAK;AACZ,WAAO,MAAM,gEAAgE;AAAA,MAC3E;AAAA,MACA,UAAU,QAAQ;AAAA,MAClB;AAAA,IACF,CAAC;AACD;AAAA,EACF;AAEA,QAAM,UAAU,kBAAkB,KAAK,CAAC,cAAc,UAAU,SAAS,MAAM;AAC/E,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,wDAAwD,MAAM,EAAE;AAAA,EAClF;AAEA,QAAM,kBAAkB,yBAAyB,MAAM;AACvD,QAAM,UAAU,iCAAiC,SAAS;AAAA,IACxD;AAAA,IACA,eAAe,QAAQ;AAAA,IACvB,kBAAkB,QAAQ;AAAA,IAC1B,gBAAgB,QAAQ;AAAA,IACxB,UAAU,QAAQ;AAAA,IAClB,UAAU,GAAG,MAAM,IAAI,QAAQ,QAAQ,IAAI,QAAQ,UAAU;AAAA,EAC/D,CAAC;AAED,QAAM,oBAAoB;AAAA,IACxB;AAAA,MACE,GAAG;AAAA,MACH,kCAAkC;AAAA,IACpC;AAAA,IACA;AAAA,MACE,UAAU,QAAQ;AAAA,MAClB,gBAAgB,QAAQ;AAAA,IAC1B;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,26 @@
1
+ const pluralRulesCache = /* @__PURE__ */ new Map();
2
+ function pluralRulesFor(locale) {
3
+ const cached = pluralRulesCache.get(locale);
4
+ if (cached) return cached;
5
+ let rules;
6
+ try {
7
+ rules = new Intl.PluralRules(locale);
8
+ } catch {
9
+ rules = new Intl.PluralRules("en");
10
+ }
11
+ pluralRulesCache.set(locale, rules);
12
+ return rules;
13
+ }
14
+ function translatePlural(translate, locale, baseKey, count, params) {
15
+ const category = pluralRulesFor(locale).select(count);
16
+ const mergedParams = { count, ...params ?? {} };
17
+ for (const key of [`${baseKey}.${category}`, `${baseKey}.other`, baseKey]) {
18
+ const result = translate(key, mergedParams);
19
+ if (result !== key) return result;
20
+ }
21
+ return translate(baseKey, mergedParams);
22
+ }
23
+ export {
24
+ translatePlural
25
+ };
26
+ //# sourceMappingURL=plural.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/eudr/lib/plural.ts"],
4
+ "sourcesContent": ["type Translator = (\n key: string,\n fallbackOrParams?: string | Record<string, string | number>,\n params?: Record<string, string | number>,\n) => string\n\nconst pluralRulesCache = new Map<string, Intl.PluralRules>()\n\nfunction pluralRulesFor(locale: string): Intl.PluralRules {\n const cached = pluralRulesCache.get(locale)\n if (cached) return cached\n let rules: Intl.PluralRules\n try {\n rules = new Intl.PluralRules(locale)\n } catch {\n rules = new Intl.PluralRules('en')\n }\n pluralRulesCache.set(locale, rules)\n return rules\n}\n\nexport function translatePlural(\n translate: Translator,\n locale: string,\n baseKey: string,\n count: number,\n params?: Record<string, string | number>,\n): string {\n const category = pluralRulesFor(locale).select(count)\n const mergedParams = { count, ...(params ?? {}) }\n for (const key of [`${baseKey}.${category}`, `${baseKey}.other`, baseKey]) {\n const result = translate(key, mergedParams)\n if (result !== key) return result\n }\n return translate(baseKey, mergedParams)\n}\n"],
5
+ "mappings": "AAMA,MAAM,mBAAmB,oBAAI,IAA8B;AAE3D,SAAS,eAAe,QAAkC;AACxD,QAAM,SAAS,iBAAiB,IAAI,MAAM;AAC1C,MAAI,OAAQ,QAAO;AACnB,MAAI;AACJ,MAAI;AACF,YAAQ,IAAI,KAAK,YAAY,MAAM;AAAA,EACrC,QAAQ;AACN,YAAQ,IAAI,KAAK,YAAY,IAAI;AAAA,EACnC;AACA,mBAAiB,IAAI,QAAQ,KAAK;AAClC,SAAO;AACT;AAEO,SAAS,gBACd,WACA,QACA,SACA,OACA,QACQ;AACR,QAAM,WAAW,eAAe,MAAM,EAAE,OAAO,KAAK;AACpD,QAAM,eAAe,EAAE,OAAO,GAAI,UAAU,CAAC,EAAG;AAChD,aAAW,OAAO,CAAC,GAAG,OAAO,IAAI,QAAQ,IAAI,GAAG,OAAO,UAAU,OAAO,GAAG;AACzE,UAAM,SAAS,UAAU,KAAK,YAAY;AAC1C,QAAI,WAAW,IAAK,QAAO;AAAA,EAC7B;AACA,SAAO,UAAU,SAAS,YAAY;AACxC;",
6
+ "names": []
7
+ }
@@ -0,0 +1,240 @@
1
+ const EUDR_HIGH_RISK_COUNTRIES = ["BY", "KP", "MM", "RU"];
2
+ const EUDR_LOW_RISK_COUNTRIES = [
3
+ "AD",
4
+ "AE",
5
+ "AF",
6
+ "AG",
7
+ "AL",
8
+ "AM",
9
+ "AT",
10
+ "AU",
11
+ "AZ",
12
+ "BA",
13
+ "BB",
14
+ "BD",
15
+ "BE",
16
+ "BG",
17
+ "BH",
18
+ "BI",
19
+ "BN",
20
+ "BS",
21
+ "BT",
22
+ "CA",
23
+ "CF",
24
+ "CG",
25
+ "CH",
26
+ "CL",
27
+ "CN",
28
+ "CR",
29
+ "CU",
30
+ "CV",
31
+ "CY",
32
+ "CZ",
33
+ "DE",
34
+ "DJ",
35
+ "DK",
36
+ "DM",
37
+ "DO",
38
+ "DZ",
39
+ "EE",
40
+ "EG",
41
+ "ES",
42
+ "FI",
43
+ "FJ",
44
+ "FM",
45
+ "FR",
46
+ "GA",
47
+ "GB",
48
+ "GD",
49
+ "GE",
50
+ "GH",
51
+ "GR",
52
+ "GY",
53
+ "HR",
54
+ "HU",
55
+ "IE",
56
+ "IN",
57
+ "IQ",
58
+ "IR",
59
+ "IS",
60
+ "IT",
61
+ "JM",
62
+ "JO",
63
+ "JP",
64
+ "KE",
65
+ "KG",
66
+ "KI",
67
+ "KM",
68
+ "KN",
69
+ "KR",
70
+ "KW",
71
+ "KZ",
72
+ "LA",
73
+ "LB",
74
+ "LC",
75
+ "LI",
76
+ "LK",
77
+ "LS",
78
+ "LT",
79
+ "LU",
80
+ "LV",
81
+ "LY",
82
+ "MA",
83
+ "MC",
84
+ "MD",
85
+ "ME",
86
+ "MG",
87
+ "MH",
88
+ "MK",
89
+ "ML",
90
+ "MN",
91
+ "MT",
92
+ "MU",
93
+ "MV",
94
+ "NL",
95
+ "NO",
96
+ "NP",
97
+ "NR",
98
+ "NZ",
99
+ "OM",
100
+ "PG",
101
+ "PH",
102
+ "PL",
103
+ "PS",
104
+ "PT",
105
+ "PW",
106
+ "QA",
107
+ "RO",
108
+ "RS",
109
+ "RW",
110
+ "SA",
111
+ "SB",
112
+ "SC",
113
+ "SE",
114
+ "SG",
115
+ "SI",
116
+ "SK",
117
+ "SM",
118
+ "SR",
119
+ "SS",
120
+ "ST",
121
+ "SY",
122
+ "SZ",
123
+ "TG",
124
+ "TH",
125
+ "TJ",
126
+ "TL",
127
+ "TM",
128
+ "TN",
129
+ "TO",
130
+ "TR",
131
+ "TT",
132
+ "TV",
133
+ "UA",
134
+ "UG",
135
+ "US",
136
+ "UY",
137
+ "UZ",
138
+ "VC",
139
+ "VN",
140
+ "VU",
141
+ "WS",
142
+ "YE",
143
+ "ZA"
144
+ ];
145
+ function getCountryRiskTier(code) {
146
+ const normalized = code?.trim().toUpperCase() ?? "";
147
+ if (!/^[A-Z]{2}$/.test(normalized)) return "unknown";
148
+ if (EUDR_HIGH_RISK_COUNTRIES.includes(normalized)) return "high";
149
+ if (EUDR_LOW_RISK_COUNTRIES.includes(normalized)) return "low";
150
+ return "standard";
151
+ }
152
+ const EUDR_APPLICATION_DATES = {
153
+ largeAndMedium: "2026-12-30",
154
+ microAndSmallNonTimber: "2027-06-30"
155
+ };
156
+ const EUDR_SUPPLEMENTARY_UNIT_HS_PREFIXES = [
157
+ "4011",
158
+ "4013",
159
+ "4104",
160
+ "4403",
161
+ "4406",
162
+ "4408",
163
+ "4410",
164
+ "4411",
165
+ "4412",
166
+ "4413",
167
+ "4701",
168
+ "4702",
169
+ "4704",
170
+ "4705"
171
+ ];
172
+ const EUDR_ANNEX1_HS_PREFIXES = {
173
+ cattle: ["0102", "0201", "0202", "0206", "1602"],
174
+ cocoa: ["1801", "1802", "1803", "1804", "1805", "1806"],
175
+ coffee: ["0901", "2101"],
176
+ oil_palm: ["1511", "1513", "2306", "1207", "3823", "2905"],
177
+ rubber: ["4001", "4005", "4006", "4007", "4008", "4009", "4010", "4011", "4012", "4013", "4015", "4016", "4017"],
178
+ soya: ["1201", "1208", "1507", "2304"],
179
+ wood: [
180
+ "4401",
181
+ "4402",
182
+ "4403",
183
+ "4404",
184
+ "4405",
185
+ "4406",
186
+ "4407",
187
+ "4408",
188
+ "4409",
189
+ "4410",
190
+ "4411",
191
+ "4412",
192
+ "4413",
193
+ "4414",
194
+ "4415",
195
+ "4416",
196
+ "4417",
197
+ "4418",
198
+ "4419",
199
+ "4420",
200
+ "4421",
201
+ "9401",
202
+ "9403",
203
+ "9406",
204
+ "44",
205
+ "47",
206
+ "48"
207
+ ]
208
+ };
209
+ function suggestCommodityForHsCode(hsCode) {
210
+ const digits = hsCode?.replace(/\D/g, "") ?? "";
211
+ if (digits.length === 0) return null;
212
+ let match = null;
213
+ for (const [commodity, prefixes] of Object.entries(EUDR_ANNEX1_HS_PREFIXES)) {
214
+ for (const prefix of prefixes) {
215
+ if (!digits.startsWith(prefix)) continue;
216
+ if (match !== null && prefix.length <= match.prefixLength) continue;
217
+ match = { commodity, prefixLength: prefix.length };
218
+ }
219
+ }
220
+ return match?.commodity ?? null;
221
+ }
222
+ const EUDR_RISK_CRITERIA_GROUPS = [
223
+ { key: "country", criteria: ["deforestation_trend", "environmental_governance", "corruption_land_use"] },
224
+ { key: "supply_chain", criteria: ["chain_complexity", "intermediaries_count", "mixing_risk", "prior_noncompliance"] },
225
+ { key: "plot_supplier", criteria: ["land_title_permits", "indigenous_rights", "protected_areas", "labor_human_rights", "plot_deforestation_history"] },
226
+ { key: "documentation", criteria: ["document_completeness", "document_verifiability", "supplier_transparency"] }
227
+ ];
228
+ const EUDR_RISK_CRITERIA_KEYS = EUDR_RISK_CRITERIA_GROUPS.flatMap((group) => [...group.criteria]);
229
+ export {
230
+ EUDR_ANNEX1_HS_PREFIXES,
231
+ EUDR_APPLICATION_DATES,
232
+ EUDR_HIGH_RISK_COUNTRIES,
233
+ EUDR_LOW_RISK_COUNTRIES,
234
+ EUDR_RISK_CRITERIA_GROUPS,
235
+ EUDR_RISK_CRITERIA_KEYS,
236
+ EUDR_SUPPLEMENTARY_UNIT_HS_PREFIXES,
237
+ getCountryRiskTier,
238
+ suggestCommodityForHsCode
239
+ };
240
+ //# sourceMappingURL=reference-data.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/eudr/lib/reference-data.ts"],
4
+ "sourcesContent": ["import type { EudrCommodity } from '../data/validators'\n\n/**\n * EUDR reference data.\n *\n * Source: Commission Implementing Regulation (EU) 2025/1093 country\n * benchmarking (22 May 2025; in force \u2014 the July 2025 EP objection was\n * non-binding \u2014 subject to the Commission's 2026 review), the Commission\n * Green Forum country-classification list (cross-checked against independent\n * reproductions; 141 low-risk + 4 high-risk entries), EUDR application dates,\n * and Annex-I/Appendix-I HS data. Effective as of 2026-07. Keep this file as\n * the single update point when the legal reference data changes. Unlisted\n * countries (~48 standard-risk, e.g. BR, ID, MY, and IL per corroborated\n * sources) default to `standard` so full due diligence remains the\n * conservative fallback. Note: CD (DR Congo) is standard; CG (Congo) is low.\n */\n\nexport type EudrCountryRiskTier = 'low' | 'standard' | 'high' | 'unknown'\n\nexport const EUDR_HIGH_RISK_COUNTRIES = ['BY', 'KP', 'MM', 'RU'] as const\n\nexport const EUDR_LOW_RISK_COUNTRIES = [\n 'AD', 'AE', 'AF', 'AG', 'AL', 'AM', 'AT', 'AU', 'AZ', 'BA', 'BB', 'BD',\n 'BE', 'BG', 'BH', 'BI', 'BN', 'BS', 'BT', 'CA', 'CF', 'CG', 'CH', 'CL',\n 'CN', 'CR', 'CU', 'CV', 'CY', 'CZ', 'DE', 'DJ', 'DK', 'DM', 'DO', 'DZ',\n 'EE', 'EG', 'ES', 'FI', 'FJ', 'FM', 'FR', 'GA', 'GB', 'GD', 'GE', 'GH',\n 'GR', 'GY', 'HR', 'HU', 'IE', 'IN', 'IQ', 'IR', 'IS', 'IT', 'JM', 'JO',\n 'JP', 'KE', 'KG', 'KI', 'KM', 'KN', 'KR', 'KW', 'KZ', 'LA', 'LB', 'LC',\n 'LI', 'LK', 'LS', 'LT', 'LU', 'LV', 'LY', 'MA', 'MC', 'MD', 'ME', 'MG',\n 'MH', 'MK', 'ML', 'MN', 'MT', 'MU', 'MV', 'NL', 'NO', 'NP', 'NR', 'NZ',\n 'OM', 'PG', 'PH', 'PL', 'PS', 'PT', 'PW', 'QA', 'RO', 'RS', 'RW', 'SA',\n 'SB', 'SC', 'SE', 'SG', 'SI', 'SK', 'SM', 'SR', 'SS', 'ST', 'SY', 'SZ',\n 'TG', 'TH', 'TJ', 'TL', 'TM', 'TN', 'TO', 'TR', 'TT', 'TV', 'UA', 'UG',\n 'US', 'UY', 'UZ', 'VC', 'VN', 'VU', 'WS', 'YE', 'ZA',\n] as const\n\nexport function getCountryRiskTier(code: string | null | undefined): EudrCountryRiskTier {\n const normalized = code?.trim().toUpperCase() ?? ''\n if (!/^[A-Z]{2}$/.test(normalized)) return 'unknown'\n if ((EUDR_HIGH_RISK_COUNTRIES as readonly string[]).includes(normalized)) return 'high'\n if ((EUDR_LOW_RISK_COUNTRIES as readonly string[]).includes(normalized)) return 'low'\n return 'standard'\n}\n\nexport const EUDR_APPLICATION_DATES = {\n largeAndMedium: '2026-12-30',\n microAndSmallNonTimber: '2027-06-30',\n} as const\n\nexport const EUDR_SUPPLEMENTARY_UNIT_HS_PREFIXES = [\n '4011',\n '4013',\n '4104',\n '4403',\n '4406',\n '4408',\n '4410',\n '4411',\n '4412',\n '4413',\n '4701',\n '4702',\n '4704',\n '4705',\n] as const\n\nexport const EUDR_ANNEX1_HS_PREFIXES: Record<EudrCommodity, readonly string[]> = {\n cattle: ['0102', '0201', '0202', '0206', '1602'],\n cocoa: ['1801', '1802', '1803', '1804', '1805', '1806'],\n coffee: ['0901', '2101'],\n oil_palm: ['1511', '1513', '2306', '1207', '3823', '2905'],\n rubber: ['4001', '4005', '4006', '4007', '4008', '4009', '4010', '4011', '4012', '4013', '4015', '4016', '4017'],\n soya: ['1201', '1208', '1507', '2304'],\n wood: [\n '4401',\n '4402',\n '4403',\n '4404',\n '4405',\n '4406',\n '4407',\n '4408',\n '4409',\n '4410',\n '4411',\n '4412',\n '4413',\n '4414',\n '4415',\n '4416',\n '4417',\n '4418',\n '4419',\n '4420',\n '4421',\n '9401',\n '9403',\n '9406',\n '44',\n '47',\n '48',\n ],\n} as const\n\nexport function suggestCommodityForHsCode(hsCode: string | null | undefined): EudrCommodity | null {\n const digits = hsCode?.replace(/\\D/g, '') ?? ''\n if (digits.length === 0) return null\n\n let match: { commodity: EudrCommodity; prefixLength: number } | null = null\n for (const [commodity, prefixes] of Object.entries(EUDR_ANNEX1_HS_PREFIXES) as Array<[EudrCommodity, readonly string[]]>) {\n for (const prefix of prefixes) {\n if (!digits.startsWith(prefix)) continue\n if (match !== null && prefix.length <= match.prefixLength) continue\n match = { commodity, prefixLength: prefix.length }\n }\n }\n\n return match?.commodity ?? null\n}\n\nexport const EUDR_RISK_CRITERIA_GROUPS = [\n { key: 'country', criteria: ['deforestation_trend', 'environmental_governance', 'corruption_land_use'] },\n { key: 'supply_chain', criteria: ['chain_complexity', 'intermediaries_count', 'mixing_risk', 'prior_noncompliance'] },\n { key: 'plot_supplier', criteria: ['land_title_permits', 'indigenous_rights', 'protected_areas', 'labor_human_rights', 'plot_deforestation_history'] },\n { key: 'documentation', criteria: ['document_completeness', 'document_verifiability', 'supplier_transparency'] },\n] as const\n\nexport const EUDR_RISK_CRITERIA_KEYS: readonly string[] = EUDR_RISK_CRITERIA_GROUPS.flatMap((group) => [...group.criteria])\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,10 @@
1
+ const WOOD_COMMODITY = "wood";
2
+ function hasMissingSpecies(mapping) {
3
+ if (mapping.commodity !== WOOD_COMMODITY) return false;
4
+ return !mapping.speciesScientificName?.trim() || !mapping.speciesCommonName?.trim();
5
+ }
6
+ export {
7
+ WOOD_COMMODITY,
8
+ hasMissingSpecies
9
+ };
10
+ //# sourceMappingURL=species.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/eudr/lib/species.ts"],
4
+ "sourcesContent": ["import type { EudrCommodity } from '../data/validators'\n\nexport const WOOD_COMMODITY = 'wood' satisfies EudrCommodity\n\nexport function hasMissingSpecies(mapping: {\n commodity: string\n speciesScientificName?: string | null\n speciesCommonName?: string | null\n}): boolean {\n if (mapping.commodity !== WOOD_COMMODITY) return false\n return !mapping.speciesScientificName?.trim() || !mapping.speciesCommonName?.trim()\n}\n"],
5
+ "mappings": "AAEO,MAAM,iBAAiB;AAEvB,SAAS,kBAAkB,SAItB;AACV,MAAI,QAAQ,cAAc,eAAgB,QAAO;AACjD,SAAO,CAAC,QAAQ,uBAAuB,KAAK,KAAK,CAAC,QAAQ,mBAAmB,KAAK;AACpF;",
6
+ "names": []
7
+ }