@open-mercato/core 0.6.5-develop.5337.1.534b781eac → 0.6.5

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 (350) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/AGENTS.md +1 -1
  3. package/dist/bootstrap.js +46 -6
  4. package/dist/bootstrap.js.map +2 -2
  5. package/dist/generated/entities/organization/index.js +2 -0
  6. package/dist/generated/entities/organization/index.js.map +2 -2
  7. package/dist/generated/entity-fields-registry.js +1 -0
  8. package/dist/generated/entity-fields-registry.js.map +2 -2
  9. package/dist/helpers/integration/crmFixtures.js +4 -0
  10. package/dist/helpers/integration/crmFixtures.js.map +2 -2
  11. package/dist/modules/attachments/api/library/route.js +2 -2
  12. package/dist/modules/attachments/api/library/route.js.map +2 -2
  13. package/dist/modules/attachments/api/route.js +2 -0
  14. package/dist/modules/attachments/api/route.js.map +2 -2
  15. package/dist/modules/attachments/components/AttachmentContentPreview.js +9 -5
  16. package/dist/modules/attachments/components/AttachmentContentPreview.js.map +2 -2
  17. package/dist/modules/attachments/lib/access.js +18 -0
  18. package/dist/modules/attachments/lib/access.js.map +2 -2
  19. package/dist/modules/audit_logs/api/audit-logs/actions/redo/route.js +3 -2
  20. package/dist/modules/audit_logs/api/audit-logs/actions/redo/route.js.map +2 -2
  21. package/dist/modules/audit_logs/data/entities.js +2 -1
  22. package/dist/modules/audit_logs/data/entities.js.map +2 -2
  23. package/dist/modules/audit_logs/migrations/Migration20260611104500.js +13 -0
  24. package/dist/modules/audit_logs/migrations/Migration20260611104500.js.map +7 -0
  25. package/dist/modules/audit_logs/services/accessLogService.js +10 -0
  26. package/dist/modules/audit_logs/services/accessLogService.js.map +2 -2
  27. package/dist/modules/auth/api/admin/nav.js +9 -0
  28. package/dist/modules/auth/api/admin/nav.js.map +2 -2
  29. package/dist/modules/auth/api/login.js +4 -13
  30. package/dist/modules/auth/api/login.js.map +2 -2
  31. package/dist/modules/auth/commands/users.js +20 -14
  32. package/dist/modules/auth/commands/users.js.map +2 -2
  33. package/dist/modules/auth/data/entities.js +4 -2
  34. package/dist/modules/auth/data/entities.js.map +2 -2
  35. package/dist/modules/auth/lib/backendChrome.js +35 -2
  36. package/dist/modules/auth/lib/backendChrome.js.map +2 -2
  37. package/dist/modules/auth/lib/consentIntegrity.js +3 -3
  38. package/dist/modules/auth/lib/consentIntegrity.js.map +2 -2
  39. package/dist/modules/auth/migrations/Migration20260610120000.js +30 -0
  40. package/dist/modules/auth/migrations/Migration20260610120000.js.map +7 -0
  41. package/dist/modules/auth/migrations/Migration20260611103000.js +15 -0
  42. package/dist/modules/auth/migrations/Migration20260611103000.js.map +7 -0
  43. package/dist/modules/auth/services/authService.js +5 -3
  44. package/dist/modules/auth/services/authService.js.map +2 -2
  45. package/dist/modules/auth/services/rbacService.js +3 -2
  46. package/dist/modules/auth/services/rbacService.js.map +2 -2
  47. package/dist/modules/catalog/ai-tools/configuration-pack.js.map +1 -1
  48. package/dist/modules/catalog/ai-tools/prices-offers-pack.js.map +1 -1
  49. package/dist/modules/catalog/ai-tools/products-pack.js.map +1 -1
  50. package/dist/modules/catalog/ai-tools/variants-pack.js.map +1 -1
  51. package/dist/modules/communication_channels/data/entities.js.map +1 -1
  52. package/dist/modules/communication_channels/encryption.js.map +1 -1
  53. package/dist/modules/communication_channels/lib/thread-matcher.js.map +1 -1
  54. package/dist/modules/communication_channels/lib/thread-token.js.map +1 -1
  55. package/dist/modules/currencies/api/currencies/route.js +4 -3
  56. package/dist/modules/currencies/api/currencies/route.js.map +2 -2
  57. package/dist/modules/customer_accounts/api/admin/roles.js +2 -1
  58. package/dist/modules/customer_accounts/api/admin/roles.js.map +2 -2
  59. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.js +0 -3
  60. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.js.map +2 -2
  61. package/dist/modules/customer_accounts/events.js +1 -1
  62. package/dist/modules/customer_accounts/events.js.map +1 -1
  63. package/dist/modules/customer_accounts/lib/resolveTenantContext.js.map +1 -1
  64. package/dist/modules/customers/acl.js +1 -1
  65. package/dist/modules/customers/acl.js.map +1 -1
  66. package/dist/modules/customers/ai-tools/companies-pack.js.map +1 -1
  67. package/dist/modules/customers/ai-tools/deals-pack.js.map +1 -1
  68. package/dist/modules/customers/ai-tools/people-pack.js.map +1 -1
  69. package/dist/modules/customers/api/companies/route.js +4 -4
  70. package/dist/modules/customers/api/companies/route.js.map +2 -2
  71. package/dist/modules/customers/api/deals/route.js +43 -2
  72. package/dist/modules/customers/api/deals/route.js.map +2 -2
  73. package/dist/modules/customers/api/deals/summary/route.js +402 -0
  74. package/dist/modules/customers/api/deals/summary/route.js.map +7 -0
  75. package/dist/modules/customers/api/people/route.js +4 -4
  76. package/dist/modules/customers/api/people/route.js.map +2 -2
  77. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js +16 -5
  78. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js.map +2 -2
  79. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealData.js +22 -5
  80. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealData.js.map +2 -2
  81. package/dist/modules/customers/backend/customers/deals/[id]/page.js +12 -2
  82. package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
  83. package/dist/modules/customers/backend/customers/deals/page.js +221 -56
  84. package/dist/modules/customers/backend/customers/deals/page.js.map +3 -3
  85. package/dist/modules/customers/backend/customers/deals/pipeline/page.js +1 -1
  86. package/dist/modules/customers/backend/customers/deals/pipeline/page.js.map +2 -2
  87. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +18 -0
  88. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
  89. package/dist/modules/customers/cli.js +15 -9
  90. package/dist/modules/customers/cli.js.map +2 -2
  91. package/dist/modules/customers/commands/addresses.js +5 -5
  92. package/dist/modules/customers/commands/addresses.js.map +2 -2
  93. package/dist/modules/customers/commands/comments.js +5 -5
  94. package/dist/modules/customers/commands/comments.js.map +2 -2
  95. package/dist/modules/customers/commands/deals.js +2 -2
  96. package/dist/modules/customers/commands/deals.js.map +2 -2
  97. package/dist/modules/customers/commands/entity-roles.js +2 -1
  98. package/dist/modules/customers/commands/entity-roles.js.map +2 -2
  99. package/dist/modules/customers/commands/interactions.js +8 -5
  100. package/dist/modules/customers/commands/interactions.js.map +2 -2
  101. package/dist/modules/customers/commands/shared.js +21 -6
  102. package/dist/modules/customers/commands/shared.js.map +2 -2
  103. package/dist/modules/customers/commands/tags.js +3 -3
  104. package/dist/modules/customers/commands/tags.js.map +2 -2
  105. package/dist/modules/customers/components/DealsKpiStrip.js +282 -0
  106. package/dist/modules/customers/components/DealsKpiStrip.js.map +7 -0
  107. package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js +0 -1
  108. package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js.map +2 -2
  109. package/dist/modules/customers/components/detail/DealForm.js +100 -17
  110. package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
  111. package/dist/modules/customers/components/detail/PersonDetailTabs.js +11 -3
  112. package/dist/modules/customers/components/detail/PersonDetailTabs.js.map +2 -2
  113. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js +1 -2
  114. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js.map +2 -2
  115. package/dist/modules/customers/components/detail/assignableStaff.js +21 -8
  116. package/dist/modules/customers/components/detail/assignableStaff.js.map +2 -2
  117. package/dist/modules/customers/components/kpi/PipelineStageBar.js +63 -0
  118. package/dist/modules/customers/components/kpi/PipelineStageBar.js.map +7 -0
  119. package/dist/modules/customers/lib/dealsMetrics.js +82 -0
  120. package/dist/modules/customers/lib/dealsMetrics.js.map +7 -0
  121. package/dist/modules/customers/migrations/Migration20260519120000_pipeline_stage_color_tones.js.map +1 -1
  122. package/dist/modules/data_sync/api/run.js +1 -1
  123. package/dist/modules/data_sync/api/run.js.map +2 -2
  124. package/dist/modules/directory/api/organization-branding/route.js +214 -0
  125. package/dist/modules/directory/api/organization-branding/route.js.map +7 -0
  126. package/dist/modules/directory/api/organizations/route.js +7 -0
  127. package/dist/modules/directory/api/organizations/route.js.map +3 -3
  128. package/dist/modules/directory/backend/directory/branding/page.js +214 -0
  129. package/dist/modules/directory/backend/directory/branding/page.js.map +7 -0
  130. package/dist/modules/directory/backend/directory/branding/page.meta.js +26 -0
  131. package/dist/modules/directory/backend/directory/branding/page.meta.js.map +7 -0
  132. package/dist/modules/directory/commands/organizations.js +8 -1
  133. package/dist/modules/directory/commands/organizations.js.map +2 -2
  134. package/dist/modules/directory/data/entities.js +3 -0
  135. package/dist/modules/directory/data/entities.js.map +2 -2
  136. package/dist/modules/directory/data/validators.js +9 -0
  137. package/dist/modules/directory/data/validators.js.map +2 -2
  138. package/dist/modules/directory/migrations/Migration20260607222259_directory.js +13 -0
  139. package/dist/modules/directory/migrations/Migration20260607222259_directory.js.map +7 -0
  140. package/dist/modules/directory/subscribers/invalidateOrgScopeCache.js +2 -1
  141. package/dist/modules/directory/subscribers/invalidateOrgScopeCache.js.map +2 -2
  142. package/dist/modules/directory/utils/organizationScope.js +59 -27
  143. package/dist/modules/directory/utils/organizationScope.js.map +2 -2
  144. package/dist/modules/entities/api/definitions.batch.js +2 -1
  145. package/dist/modules/entities/api/definitions.batch.js.map +2 -2
  146. package/dist/modules/entities/api/entities.js +7 -0
  147. package/dist/modules/entities/api/entities.js.map +2 -2
  148. package/dist/modules/entities/api/records.js +26 -15
  149. package/dist/modules/entities/api/records.js.map +2 -2
  150. package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js +14 -0
  151. package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js.map +2 -2
  152. package/dist/modules/entities/backend/entities/user/[entityId]/records/create/page.js +14 -0
  153. package/dist/modules/entities/backend/entities/user/[entityId]/records/create/page.js.map +2 -2
  154. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +12 -0
  155. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
  156. package/dist/modules/entities/components/useRecordsEntityGuard.js +30 -0
  157. package/dist/modules/entities/components/useRecordsEntityGuard.js.map +7 -0
  158. package/dist/modules/payment_gateways/api/transactions/route.js +2 -4
  159. package/dist/modules/payment_gateways/api/transactions/route.js.map +2 -2
  160. package/dist/modules/progress/api/jobs/[id]/route.js +7 -2
  161. package/dist/modules/progress/api/jobs/[id]/route.js.map +2 -2
  162. package/dist/modules/progress/api/jobs/route.js +1 -1
  163. package/dist/modules/progress/api/jobs/route.js.map +2 -2
  164. package/dist/modules/progress/lib/progressServiceImpl.js +8 -2
  165. package/dist/modules/progress/lib/progressServiceImpl.js.map +2 -2
  166. package/dist/modules/query_index/data/entities.js +2 -1
  167. package/dist/modules/query_index/data/entities.js.map +2 -2
  168. package/dist/modules/query_index/lib/engine.js +4 -2
  169. package/dist/modules/query_index/lib/engine.js.map +2 -2
  170. package/dist/modules/query_index/migrations/Migration20260611103000_query_index.js +16 -0
  171. package/dist/modules/query_index/migrations/Migration20260611103000_query_index.js.map +7 -0
  172. package/dist/modules/resources/api/resources.js +2 -3
  173. package/dist/modules/resources/api/resources.js.map +2 -2
  174. package/dist/modules/sales/api/documents/factory.js +2 -2
  175. package/dist/modules/sales/api/documents/factory.js.map +2 -2
  176. package/dist/modules/sales/commands/documents.js +7 -5
  177. package/dist/modules/sales/commands/documents.js.map +2 -2
  178. package/dist/modules/sales/components/documents/SalesDocumentsTable.js +2 -1
  179. package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
  180. package/dist/modules/sales/components/documents/salesDocumentsColumns.js +10 -0
  181. package/dist/modules/sales/components/documents/salesDocumentsColumns.js.map +7 -0
  182. package/dist/modules/staff/api/team-members.js +9 -2
  183. package/dist/modules/staff/api/team-members.js.map +2 -2
  184. package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.js +24 -1
  185. package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.js.map +2 -2
  186. package/dist/modules/staff/backend/staff/team-members/[id]/page.js +11 -6
  187. package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
  188. package/dist/modules/staff/commands/team-members.js +1 -1
  189. package/dist/modules/staff/commands/team-members.js.map +2 -2
  190. package/dist/modules/staff/components/TeamMemberForm.js +1 -1
  191. package/dist/modules/staff/components/TeamMemberForm.js.map +2 -2
  192. package/dist/modules/staff/lib/scheduleSwitch.js +23 -0
  193. package/dist/modules/staff/lib/scheduleSwitch.js.map +7 -0
  194. package/dist/modules/sync_excel/api/import/route.js +1 -1
  195. package/dist/modules/sync_excel/api/import/route.js.map +2 -2
  196. package/dist/modules/workflows/api/definitions/route.js +3 -2
  197. package/dist/modules/workflows/api/definitions/route.js.map +2 -2
  198. package/dist/modules/workflows/backend/definitions/create/page.js +1 -2
  199. package/dist/modules/workflows/backend/definitions/create/page.js.map +2 -2
  200. package/dist/modules/workflows/backend/definitions/visual-editor/page.js +1 -2
  201. package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
  202. package/dist/modules/workflows/components/DefinitionTriggersEditor.js +1 -2
  203. package/dist/modules/workflows/components/DefinitionTriggersEditor.js.map +2 -2
  204. package/dist/modules/workflows/components/NodeEditDialog.js +4 -13
  205. package/dist/modules/workflows/components/NodeEditDialog.js.map +2 -2
  206. package/dist/modules/workflows/components/NodeEditDialogCrudForm.js +4 -13
  207. package/dist/modules/workflows/components/NodeEditDialogCrudForm.js.map +2 -2
  208. package/dist/modules/workflows/components/WorkflowGraphImpl.js +1 -4
  209. package/dist/modules/workflows/components/WorkflowGraphImpl.js.map +2 -2
  210. package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js +2 -5
  211. package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js.map +2 -2
  212. package/generated/entities/organization/index.ts +1 -0
  213. package/generated/entity-fields-registry.ts +1 -0
  214. package/package.json +11 -12
  215. package/src/bootstrap.ts +65 -7
  216. package/src/helpers/integration/crmFixtures.ts +21 -1
  217. package/src/modules/attachments/AGENTS.md +79 -0
  218. package/src/modules/attachments/api/library/route.ts +2 -2
  219. package/src/modules/attachments/api/route.ts +2 -0
  220. package/src/modules/attachments/components/AttachmentContentPreview.tsx +6 -6
  221. package/src/modules/attachments/lib/access.ts +36 -0
  222. package/src/modules/audit_logs/api/audit-logs/actions/redo/route.ts +14 -2
  223. package/src/modules/audit_logs/data/entities.ts +1 -0
  224. package/src/modules/audit_logs/migrations/.snapshot-open-mercato.json +10 -0
  225. package/src/modules/audit_logs/migrations/Migration20260611104500.ts +13 -0
  226. package/src/modules/audit_logs/services/accessLogService.ts +15 -0
  227. package/src/modules/auth/api/admin/nav.ts +9 -0
  228. package/src/modules/auth/api/login.ts +13 -13
  229. package/src/modules/auth/commands/users.ts +32 -15
  230. package/src/modules/auth/data/entities.ts +13 -1
  231. package/src/modules/auth/i18n/de.json +0 -1
  232. package/src/modules/auth/i18n/en.json +0 -1
  233. package/src/modules/auth/i18n/es.json +0 -1
  234. package/src/modules/auth/i18n/pl.json +0 -1
  235. package/src/modules/auth/lib/backendChrome.tsx +37 -1
  236. package/src/modules/auth/lib/consentIntegrity.ts +6 -3
  237. package/src/modules/auth/migrations/.snapshot-open-mercato.json +20 -10
  238. package/src/modules/auth/migrations/Migration20260610120000.ts +53 -0
  239. package/src/modules/auth/migrations/Migration20260611103000.ts +21 -0
  240. package/src/modules/auth/services/authService.ts +24 -4
  241. package/src/modules/auth/services/rbacService.ts +11 -2
  242. package/src/modules/catalog/ai-tools/configuration-pack.ts +1 -1
  243. package/src/modules/catalog/ai-tools/prices-offers-pack.ts +1 -1
  244. package/src/modules/catalog/ai-tools/products-pack.ts +1 -1
  245. package/src/modules/catalog/ai-tools/variants-pack.ts +1 -1
  246. package/src/modules/communication_channels/data/entities.ts +2 -2
  247. package/src/modules/communication_channels/encryption.ts +1 -1
  248. package/src/modules/communication_channels/lib/adapter.ts +1 -1
  249. package/src/modules/communication_channels/lib/thread-matcher.ts +1 -1
  250. package/src/modules/communication_channels/lib/thread-token.ts +1 -1
  251. package/src/modules/currencies/api/currencies/route.ts +4 -3
  252. package/src/modules/customer_accounts/api/admin/roles.ts +2 -1
  253. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.tsx +0 -3
  254. package/src/modules/customer_accounts/events.ts +1 -1
  255. package/src/modules/customer_accounts/lib/resolveTenantContext.ts +2 -2
  256. package/src/modules/customers/acl.ts +1 -1
  257. package/src/modules/customers/ai-tools/companies-pack.ts +1 -1
  258. package/src/modules/customers/ai-tools/deals-pack.ts +1 -1
  259. package/src/modules/customers/ai-tools/people-pack.ts +1 -1
  260. package/src/modules/customers/api/companies/route.ts +4 -4
  261. package/src/modules/customers/api/deals/route.ts +51 -2
  262. package/src/modules/customers/api/deals/summary/route.ts +496 -0
  263. package/src/modules/customers/api/people/route.ts +4 -4
  264. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.ts +28 -6
  265. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealData.ts +33 -6
  266. package/src/modules/customers/backend/customers/deals/[id]/page.tsx +17 -2
  267. package/src/modules/customers/backend/customers/deals/page.tsx +254 -66
  268. package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +1 -2
  269. package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +18 -0
  270. package/src/modules/customers/cli.ts +15 -15
  271. package/src/modules/customers/commands/addresses.ts +5 -5
  272. package/src/modules/customers/commands/comments.ts +5 -5
  273. package/src/modules/customers/commands/deals.ts +2 -2
  274. package/src/modules/customers/commands/entity-roles.ts +2 -1
  275. package/src/modules/customers/commands/interactions.ts +8 -5
  276. package/src/modules/customers/commands/shared.ts +26 -4
  277. package/src/modules/customers/commands/tags.ts +3 -3
  278. package/src/modules/customers/components/DealsKpiStrip.tsx +389 -0
  279. package/src/modules/customers/components/detail/ConfirmDealLostDialog.tsx +0 -1
  280. package/src/modules/customers/components/detail/DealForm.tsx +121 -19
  281. package/src/modules/customers/components/detail/PersonDetailTabs.tsx +12 -2
  282. package/src/modules/customers/components/detail/ScheduleActivityDialog.tsx +1 -2
  283. package/src/modules/customers/components/detail/assignableStaff.ts +32 -8
  284. package/src/modules/customers/components/kpi/PipelineStageBar.tsx +77 -0
  285. package/src/modules/customers/i18n/de.json +43 -0
  286. package/src/modules/customers/i18n/en.json +43 -0
  287. package/src/modules/customers/i18n/es.json +43 -0
  288. package/src/modules/customers/i18n/pl.json +43 -0
  289. package/src/modules/customers/lib/dealsMetrics.ts +159 -0
  290. package/src/modules/customers/migrations/Migration20260519120000_pipeline_stage_color_tones.ts +1 -1
  291. package/src/modules/data_sync/api/run.ts +1 -1
  292. package/src/modules/directory/api/organization-branding/route.ts +238 -0
  293. package/src/modules/directory/api/organizations/route.ts +7 -0
  294. package/src/modules/directory/backend/directory/branding/page.meta.ts +24 -0
  295. package/src/modules/directory/backend/directory/branding/page.tsx +248 -0
  296. package/src/modules/directory/commands/organizations.ts +9 -1
  297. package/src/modules/directory/data/entities.ts +3 -0
  298. package/src/modules/directory/data/validators.ts +12 -0
  299. package/src/modules/directory/i18n/de.json +21 -0
  300. package/src/modules/directory/i18n/en.json +21 -0
  301. package/src/modules/directory/i18n/es.json +21 -0
  302. package/src/modules/directory/i18n/pl.json +21 -0
  303. package/src/modules/directory/migrations/.snapshot-open-mercato.json +40 -0
  304. package/src/modules/directory/migrations/Migration20260607222259_directory.ts +13 -0
  305. package/src/modules/directory/subscribers/invalidateOrgScopeCache.ts +3 -1
  306. package/src/modules/directory/utils/organizationScope.ts +85 -30
  307. package/src/modules/entities/api/definitions.batch.ts +11 -7
  308. package/src/modules/entities/api/entities.ts +11 -0
  309. package/src/modules/entities/api/records.ts +46 -25
  310. package/src/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.tsx +15 -0
  311. package/src/modules/entities/backend/entities/user/[entityId]/records/create/page.tsx +15 -0
  312. package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +23 -0
  313. package/src/modules/entities/components/useRecordsEntityGuard.ts +41 -0
  314. package/src/modules/entities/i18n/de.json +1 -0
  315. package/src/modules/entities/i18n/en.json +1 -0
  316. package/src/modules/entities/i18n/es.json +1 -0
  317. package/src/modules/entities/i18n/pl.json +1 -0
  318. package/src/modules/payment_gateways/api/transactions/route.ts +2 -5
  319. package/src/modules/progress/api/jobs/[id]/route.ts +6 -1
  320. package/src/modules/progress/api/jobs/route.ts +1 -1
  321. package/src/modules/progress/lib/progressServiceImpl.ts +7 -1
  322. package/src/modules/query_index/data/entities.ts +1 -0
  323. package/src/modules/query_index/lib/engine.ts +11 -5
  324. package/src/modules/query_index/migrations/.snapshot-open-mercato.json +11 -0
  325. package/src/modules/query_index/migrations/Migration20260611103000_query_index.ts +29 -0
  326. package/src/modules/resources/api/resources.ts +2 -3
  327. package/src/modules/sales/api/documents/factory.ts +2 -2
  328. package/src/modules/sales/commands/documents.ts +7 -5
  329. package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +2 -1
  330. package/src/modules/sales/components/documents/salesDocumentsColumns.ts +6 -0
  331. package/src/modules/staff/AGENTS.md +1 -1
  332. package/src/modules/staff/api/team-members.ts +9 -2
  333. package/src/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.ts +31 -1
  334. package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +18 -8
  335. package/src/modules/staff/commands/team-members.ts +5 -2
  336. package/src/modules/staff/components/TeamMemberForm.tsx +4 -1
  337. package/src/modules/staff/i18n/de.json +1 -0
  338. package/src/modules/staff/i18n/en.json +1 -0
  339. package/src/modules/staff/i18n/es.json +1 -0
  340. package/src/modules/staff/i18n/pl.json +1 -0
  341. package/src/modules/staff/lib/scheduleSwitch.ts +46 -0
  342. package/src/modules/sync_excel/api/import/route.ts +1 -1
  343. package/src/modules/workflows/api/definitions/route.ts +3 -2
  344. package/src/modules/workflows/backend/definitions/create/page.tsx +1 -2
  345. package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +1 -2
  346. package/src/modules/workflows/components/DefinitionTriggersEditor.tsx +1 -2
  347. package/src/modules/workflows/components/NodeEditDialog.tsx +1 -4
  348. package/src/modules/workflows/components/NodeEditDialogCrudForm.tsx +4 -7
  349. package/src/modules/workflows/components/WorkflowGraphImpl.tsx +1 -2
  350. package/src/modules/workflows/components/fields/FormFieldArrayEditor.tsx +2 -3
@@ -33,6 +33,7 @@ import { ScheduleActivityDialog } from "../../../../components/detail/ScheduleAc
33
33
  import { PersonDetailHeader } from "../../../../components/detail/PersonDetailHeader.js";
34
34
  import { ChangelogTab } from "../../../../components/detail/ChangelogTab.js";
35
35
  import { PersonDetailTabs, resolveLegacyTab } from "../../../../components/detail/PersonDetailTabs.js";
36
+ import { AddressesSection } from "../../../../components/detail/AddressesSection.js";
36
37
  import { PersonCompaniesSection } from "../../../../components/detail/PersonCompaniesSection.js";
37
38
  import { MobilePersonDetail } from "../../../../components/detail/MobilePersonDetail.js";
38
39
  import {
@@ -408,6 +409,7 @@ function PersonDetailV2Page({ params }) {
408
409
  activitiesCount: interactionCount,
409
410
  dealsCount: dealCount,
410
411
  companiesCount: companyCount,
412
+ addressesCount: data?.counts?.addresses ?? 0,
411
413
  tasksCount: todoCount,
412
414
  sectionAction,
413
415
  children: /* @__PURE__ */ jsx("div", { className: "min-w-0", children: (() => {
@@ -485,6 +487,22 @@ function PersonDetailV2Page({ params }) {
485
487
  }
486
488
  );
487
489
  }
490
+ if (activeTab === "addresses") {
491
+ return /* @__PURE__ */ jsx(
492
+ AddressesSection,
493
+ {
494
+ entityId: personId,
495
+ emptyLabel: t("customers.people.detail.empty.addresses", "No addresses linked to this person."),
496
+ addActionLabel: t("customers.people.detail.addresses.add", "Add address"),
497
+ emptyState: {
498
+ title: t("customers.people.detail.emptyState.addresses.title", "No addresses yet"),
499
+ actionLabel: t("customers.people.detail.emptyState.addresses.action", "Add address")
500
+ },
501
+ onActionChange: handleSectionActionChange,
502
+ translator: detailTranslator
503
+ }
504
+ );
505
+ }
488
506
  if (activeTab === "tasks") {
489
507
  return /* @__PURE__ */ jsx(
490
508
  TasksSection,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/customers/backend/customers/people-v2/%5Bid%5D/page.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter, useSearchParams } from 'next/navigation'\nimport { User, Hash, Users, Building2 } from 'lucide-react'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { CrudForm } from '@open-mercato/ui/backend/CrudForm'\nimport { CollapsibleZoneLayout, type ZoneSectionDescriptor } from '@open-mercato/ui/backend/crud/CollapsibleZoneLayout'\nimport { useIsMobile } from '@open-mercato/ui/hooks/useIsMobile'\nimport { updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { apiCallOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { E } from '#generated/entities.ids.generated'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useOrganizationScopeDetail } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { AttachmentsSection, ErrorMessage, LoadingMessage, RecordNotFoundState, type SectionAction } from '@open-mercato/ui/backend/detail'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { InjectionSpot, useInjectionWidgets } from '@open-mercato/ui/backend/injection/InjectionSpot'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { createTranslatorWithFallback } from '@open-mercato/shared/lib/i18n/translate'\n\nimport { ActivitiesSection } from '../../../../components/detail/ActivitiesSection'\nimport { PersonEmailThreadsTab } from '../../../../components/detail/PersonEmailThreadsTab'\nimport { ActivitiesCard } from '../../../../components/detail/ActivitiesCard'\nimport type { ActivityKind } from '../../../../components/detail/ActivitiesAddNewMenu'\nimport { DealsSection } from '../../../../components/detail/DealsSection'\nimport { TasksSection } from '../../../../components/detail/TasksSection'\nimport type { TagSummary } from '../../../../components/detail/types'\nimport { ScheduleActivityDialog, type ScheduleActivityEditData } from '../../../../components/detail/ScheduleActivityDialog'\nimport { PersonDetailHeader } from '../../../../components/detail/PersonDetailHeader'\nimport { ChangelogTab } from '../../../../components/detail/ChangelogTab'\nimport { PersonDetailTabs, resolveLegacyTab, type PersonTabId } from '../../../../components/detail/PersonDetailTabs'\nimport { PersonCompaniesSection } from '../../../../components/detail/PersonCompaniesSection'\nimport { MobilePersonDetail } from '../../../../components/detail/MobilePersonDetail'\nimport type { TagsSectionController } from '@open-mercato/ui/backend/detail'\nimport {\n buildPersonEditPayload,\n createPersonEditFields,\n createPersonPersonalDataGroups,\n createPersonEditSchema,\n mapPersonOverviewToFormValues,\n type PersonEditFormValues,\n type PersonOverview,\n} from '../../../../components/formConfig'\nimport { coerceDisplayName, coerceDisplayNameOrNull } from '../../../../lib/displayName'\n\nexport default function PersonDetailV2Page({ params }: { params?: { id?: string } }) {\n const id = params?.id\n const t = useT()\n const router = useRouter()\n const searchParams = useSearchParams()\n const { organizationId } = useOrganizationScopeDetail()\n const isMobile = useIsMobile()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n\n const detailTranslator = React.useMemo(() => createTranslatorWithFallback(t), [t])\n\n\n const formSchema = React.useMemo(() => createPersonEditSchema(), [])\n const fields = React.useMemo(() => createPersonEditFields(t), [t])\n\n const [data, setData] = React.useState<PersonOverview | null>(null)\n // Mirror the latest `data` into a ref so save handlers always read the current\n // optimistic-lock token (`person.updatedAt`) instead of the value captured in\n // their `useCallback` closure. Without this, a header-field save issued after a\n // prior in-page reload would send a stale token (or none), letting a concurrent\n // two-tab overwrite slip through without the 409 + conflict bar (#2055, Alina A7).\n const dataRef = React.useRef<PersonOverview | null>(null)\n React.useEffect(() => {\n dataRef.current = data\n }, [data])\n const [isLoading, setIsLoading] = React.useState(true)\n const [error, setError] = React.useState<string | null>(null)\n const [isNotFound, setIsNotFound] = React.useState(false)\n\n // Form state lifted for header Save button\n const [isDirty, setIsDirty] = React.useState(false)\n const [isSaving, setIsSaving] = React.useState(false)\n const formWrapperRef = React.useRef<HTMLDivElement>(null)\n\n const initialTab = React.useMemo(() => {\n return resolveLegacyTab(searchParams?.get('tab'))\n }, [searchParams])\n const [activeTab, setActiveTab] = React.useState<PersonTabId>(initialTab)\n const [sectionAction, setSectionAction] = React.useState<SectionAction | null>(null)\n const [scheduleDialogOpen, setScheduleDialogOpen] = React.useState(false)\n const [scheduleEditData, setScheduleEditData] = React.useState<ScheduleActivityEditData | null>(null)\n const [activityRefreshKey, setActivityRefreshKey] = React.useState(0)\n const [dealCount, setDealCount] = React.useState(0)\n\n const currentPersonId = data?.person?.id ?? null\n const mutationContextId = React.useMemo(\n () => (currentPersonId ? `customer-person:${currentPersonId}` : `customer-person:${id ?? 'pending'}`),\n [currentPersonId, id],\n )\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n personId?: string | null\n resourceKind: string\n resourceId?: string\n data: PersonOverview | null\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: mutationContextId,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n const personDisplayName = coerceDisplayName(data?.person?.displayName)\n const personName = personDisplayName.trim().length\n ? personDisplayName\n : t('customers.people.list.deleteFallbackName', 'this person')\n\n const personDisplayNameForGroups = personDisplayName.trim().length\n ? personDisplayName.trim()\n : null\n\n const scheduleDialogCompanyName = coerceDisplayNameOrNull(\n data?.company?.displayName ?? data?.companies?.[0]?.displayName ?? null,\n )\n\n const groups = React.useMemo(\n () => createPersonPersonalDataGroups(t, { entityName: personDisplayNameForGroups }),\n [t, personDisplayNameForGroups],\n )\n\n const zoneSections = React.useMemo<ZoneSectionDescriptor[]>(() => [\n { id: 'personalData', icon: User, label: t('customers.people.form.groups.personalData', 'Personal data') },\n { id: 'companyRole', icon: Building2, label: t('customers.people.form.groups.companyRole', 'Company & role') },\n { id: 'customFields', icon: Hash, label: t('customers.people.form.groups.customAttributes', 'Custom attributes') },\n { id: 'roles', icon: Users, label: t('customers.people.form.groups.roles', 'My roles') },\n ], [t])\n\n // Data loading\n const initialLoadDoneRef = React.useRef(false)\n const loadData = React.useCallback(async (lockTokenOverride?: string | null) => {\n if (!id) {\n setIsNotFound(true)\n setIsLoading(false)\n return\n }\n if (!initialLoadDoneRef.current) {\n setIsLoading(true)\n }\n setError(null)\n setIsNotFound(false)\n try {\n const payload = await readApiResultOrThrow<PersonOverview>(\n `/api/customers/people/${encodeURIComponent(id)}`,\n undefined,\n { errorMessage: t('customers.people.detail.error.load', 'Failed to load person.') },\n )\n // When the caller is the save handler, pin the optimistic-lock token to the\n // value the write itself returned rather than the one this GET observed \u2014 a\n // concurrent third-party bump between save and reload must stay stale so the\n // next in-page save 409s (#2055, Alina A7). Applied in the same state update\n // as the refresh to avoid a redundant second re-render.\n const next = lockTokenOverride && payload?.person\n ? { ...payload, person: { ...payload.person, updatedAt: lockTokenOverride, updated_at: lockTokenOverride } }\n : payload\n setData(next as PersonOverview)\n } catch (err) {\n if ((err as { status?: number }).status === 404) {\n setIsNotFound(true)\n } else {\n const message = err instanceof Error ? err.message : t('customers.people.detail.error.load', 'Failed to load person.')\n setError(message)\n }\n if (!initialLoadDoneRef.current) setData(null)\n } finally {\n setIsLoading(false)\n initialLoadDoneRef.current = true\n }\n }, [id, t])\n\n React.useEffect(() => {\n loadData().catch((err) => console.warn('[people-v2] loadData failed', err))\n }, [loadData])\n\n React.useEffect(() => {\n setDealCount(data?.counts?.deals ?? 0)\n }, [data?.counts?.deals])\n\n const handleActivityCreated = React.useCallback(() => {\n setActivityRefreshKey((k) => k + 1)\n loadData().catch((err) => console.warn('[people-v2] reload after activity failed', err))\n }, [loadData])\n\n const plannedActivities = React.useMemo(() => {\n return data?.plannedActivitiesPreview ?? []\n }, [data?.plannedActivitiesPreview])\n\n // Injection context for UMES\n const injectionContext = React.useMemo(\n () => ({\n formId: mutationContextId,\n personId: currentPersonId,\n resourceKind: 'customers.person',\n resourceId: currentPersonId ?? (id ?? undefined),\n data,\n retryLastMutation,\n }),\n [currentPersonId, data, id, mutationContextId, retryLastMutation],\n )\n const runMutationWithContext = React.useCallback(\n async <T,>(operation: () => Promise<T>, mutationPayload?: Record<string, unknown>): Promise<T> => {\n return runMutation({\n operation,\n mutationPayload,\n context: injectionContext,\n })\n },\n [injectionContext, runMutation],\n )\n\n const handleAddActivity = React.useCallback((kind: ActivityKind) => {\n setScheduleEditData({\n id: '',\n interactionType: kind,\n title: null,\n body: null,\n scheduledAt: null,\n durationMinutes: null,\n location: null,\n allDay: null,\n recurrenceRule: null,\n recurrenceEnd: null,\n participants: null,\n reminderMinutes: null,\n visibility: null,\n linkedEntities: null,\n guestPermissions: null,\n })\n setScheduleDialogOpen(true)\n }, [])\n\n const handleEditActivity = React.useCallback((activity: { id: string; interactionType?: string; title?: string | null; body?: string | null; scheduledAt?: string | null; occurredAt?: string | null; [key: string]: unknown }) => {\n const raw = activity as Record<string, unknown>\n const durationValue = typeof raw.duration === 'number'\n ? raw.duration\n : typeof raw.durationMinutes === 'number'\n ? raw.durationMinutes as number\n : null\n // Forward `customValues` so per-type chip state (callPhoneNumber, callDirection,\n // taskPriority, \u2026) round-trips on edit (#1808 phone persistence).\n // Forward `occurredAt` so historical activity edits prefill from the original\n // moment instead of \"today\" (#1807 prefill).\n const editPayload = {\n id: activity.id,\n updatedAt: typeof raw.updatedAt === 'string' ? raw.updatedAt as string : typeof raw.updated_at === 'string' ? raw.updated_at as string : null,\n interactionType: typeof activity.interactionType === 'string' ? activity.interactionType : undefined,\n title: typeof activity.title === 'string' ? activity.title : null,\n body: typeof activity.body === 'string' ? activity.body : null,\n scheduledAt: typeof activity.scheduledAt === 'string' ? activity.scheduledAt : null,\n occurredAt: typeof activity.occurredAt === 'string' ? activity.occurredAt : null,\n durationMinutes: durationValue,\n location: typeof raw.location === 'string' ? raw.location as string : null,\n allDay: typeof raw.allDay === 'boolean' ? raw.allDay as boolean : null,\n recurrenceRule: typeof raw.recurrenceRule === 'string' ? raw.recurrenceRule as string : null,\n recurrenceEnd: typeof raw.recurrenceEnd === 'string' ? raw.recurrenceEnd as string : null,\n participants: Array.isArray(raw.participants) ? raw.participants as ScheduleActivityEditData['participants'] : null,\n reminderMinutes: typeof raw.reminderMinutes === 'number' ? raw.reminderMinutes as number : null,\n visibility: typeof raw.visibility === 'string' ? raw.visibility as string : null,\n linkedEntities: Array.isArray(raw.linkedEntities) ? raw.linkedEntities as ScheduleActivityEditData['linkedEntities'] : null,\n guestPermissions: raw.guestPermissions && typeof raw.guestPermissions === 'object'\n ? raw.guestPermissions as ScheduleActivityEditData['guestPermissions']\n : null,\n customValues: raw.customValues && typeof raw.customValues === 'object'\n ? raw.customValues as Record<string, unknown>\n : null,\n phoneNumber: typeof raw.phoneNumber === 'string' ? raw.phoneNumber as string : null,\n } as ScheduleActivityEditData & { customValues?: Record<string, unknown> | null; phoneNumber?: string | null }\n setScheduleEditData(editPayload)\n setScheduleDialogOpen(true)\n }, [])\n\n // Injected tabs from UMES\n const { widgets: injectedTabWidgets } = useInjectionWidgets('detail:customers.person:tabs', {\n context: injectionContext,\n triggerOnLoad: true,\n })\n\n const injectedTabs = React.useMemo(\n () =>\n (injectedTabWidgets ?? [])\n .filter((widget) => (widget.placement?.kind ?? 'tab') === 'tab')\n .map((widget) => {\n const tabId = widget.placement?.groupId ?? widget.widgetId\n const label = widget.placement?.groupLabel ?? widget.module.metadata.title ?? tabId\n const priority = typeof widget.placement?.priority === 'number' ? widget.placement.priority : 0\n const render = () => (\n <widget.module.Widget\n context={injectionContext}\n data={data}\n onDataChange={(next: unknown) => setData(next as PersonOverview)}\n />\n )\n return { id: tabId, label, priority, render }\n })\n .sort((a, b) => b.priority - a.priority),\n [data, injectedTabWidgets, injectionContext],\n )\n\n const injectedTabMap = React.useMemo(() => new Map(injectedTabs.map((tab) => [tab.id, tab.render])), [injectedTabs])\n\n // Tags\n const handleTagsChange = React.useCallback((nextTags: TagSummary[]) => {\n setData((prev) => (prev ? { ...prev, tags: nextTags } : prev))\n }, [])\n const tagsSectionControllerRef = React.useRef<TagsSectionController | null>(null)\n\n // Section action (for tabs that expose add/create buttons)\n const handleSectionActionChange = React.useCallback((action: SectionAction | null) => {\n setSectionAction((prev) => (action !== null ? action : prev))\n }, [])\n\n React.useEffect(() => {\n setSectionAction(null)\n }, [activeTab])\n\n // Deals scope\n const dealsScope = React.useMemo(\n () => (currentPersonId ? ({ kind: 'person', entityId: currentPersonId } as const) : null),\n [currentPersonId],\n )\n\n const initialValues = React.useMemo(\n () => (data ? mapPersonOverviewToFormValues(data) : undefined),\n [data],\n )\n\n // Form submit/delete\n const handleFormSubmit = React.useCallback(\n async (values: PersonEditFormValues) => {\n setIsSaving(true)\n try {\n await tagsSectionControllerRef.current?.flush()\n\n let payload: Record<string, unknown>\n try {\n payload = buildPersonEditPayload(values, organizationId)\n } catch (err) {\n if (err instanceof Error && err.message === 'DISPLAY_NAME_REQUIRED') {\n const message = t('customers.people.form.displayName.error')\n throw createCrudFormError(message, { displayName: message })\n }\n throw err\n }\n\n // Attach the current optimistic-lock token directly on this write path so\n // every header-field edit (displayName/status/\u2026) carries `updatedAt`, not\n // just the fields the embedded CrudForm intercepts. Read from `dataRef` so\n // the token reflects the latest in-page reload rather than a stale closure\n // capture, and let the 409 propagate to CrudForm's surfaceRecordConflict so\n // the unified conflict bar renders (#2055, Alina A7).\n const lockedUpdatedAt = dataRef.current?.person?.updatedAt\n ?? dataRef.current?.person?.updated_at\n ?? null\n const updateResponse = await withScopedApiRequestHeaders(\n buildOptimisticLockHeader(lockedUpdatedAt),\n () => updateCrud<{ updatedAt?: string | null }>('customers/people', payload),\n )\n flash(t('customers.people.form.updateSuccess', 'Person updated.'), 'success')\n // Refresh the view and pin the optimistic-lock token to the write's OWN\n // authoritative `updatedAt` in a single reload (see loadData) so a\n // concurrent third-party bump stays stale on the next save (#2055, Alina A7).\n const savedUpdatedAt = typeof updateResponse.result?.updatedAt === 'string'\n ? updateResponse.result.updatedAt\n : null\n await loadData(savedUpdatedAt)\n } finally {\n setIsSaving(false)\n }\n },\n [loadData, organizationId, t],\n )\n\n const handleFormDelete = React.useCallback(\n async () => {\n const personId = data?.person?.id ?? ''\n if (!personId) return\n const approved = await confirm({\n title: t('customers.people.detail.deleteConfirmTitle', 'Delete person?'),\n description: t('customers.people.detail.deleteConfirmDescription', 'This action cannot be undone.'),\n confirmText: t('customers.people.detail.actions.delete', 'Delete'),\n cancelText: t('customers.people.detail.actions.cancel', 'Cancel'),\n variant: 'destructive',\n })\n if (!approved) return\n try {\n await runMutationWithContext(\n () => withScopedApiRequestHeaders(\n buildOptimisticLockHeader(data?.person?.updatedAt ?? data?.person?.updated_at ?? null),\n () => deleteCrud('customers/people', { id: personId }),\n ),\n { id: personId, operation: 'deletePerson' },\n )\n } catch (err) {\n // The guarded mutation routes a 409 to the unified conflict bar; surface\n // any other server error (e.g. a linked-records delete guard) as a flash\n // instead of letting it crash the page.\n if (!surfaceRecordConflict(err, t)) {\n flash(\n err instanceof Error && err.message.trim().length > 0\n ? err.message\n : t('customers.people.detail.deleteError', 'Failed to delete person.'),\n 'error',\n )\n }\n return\n }\n flash(t('customers.people.list.deleteSuccess', 'Person deleted.'), 'success')\n router.push('/backend/customers/people')\n },\n [confirm, data?.person?.id, router, runMutationWithContext, t],\n )\n\n const handleHeaderSave = React.useCallback(() => {\n const form = formWrapperRef.current?.querySelector('form')\n if (form) form.requestSubmit()\n }, [])\n\n // Counts for tab badges\n const interactionCount = data?.counts?.activities ?? 0\n const todoCount = data?.counts?.todos ?? 0\n const companyCount = data?.counts?.companies ?? (data?.companies?.length ?? (data?.company ? 1 : 0))\n\n // Loading / error states\n if (isLoading) {\n return (\n <Page>\n <PageBody>\n <LoadingMessage label={t('customers.people.detail.loading', 'Loading person\u2026')} />\n </PageBody>\n </Page>\n )\n }\n\n if (isNotFound) {\n return (\n <Page>\n <PageBody>\n <RecordNotFoundState\n label={t('customers.people.detail.error.notFound', 'Person not found.')}\n backHref=\"/backend/customers/people\"\n backLabel={t('customers.people.detail.actions.backToList', 'Back to people')}\n />\n </PageBody>\n </Page>\n )\n }\n\n if (error || !data?.person?.id || !initialValues) {\n return (\n <Page>\n <PageBody>\n <ErrorMessage\n label={error ?? t('customers.people.detail.error.load', 'Failed to load person.')}\n action={(\n <Button asChild variant=\"outline\">\n <Link href=\"/backend/customers/people\">\n {t('customers.people.detail.actions.backToList', 'Back to people')}\n </Link>\n </Button>\n )}\n />\n </PageBody>\n </Page>\n )\n }\n\n const personId = data.person.id\n const useCanonicalInteractions = data.interactionMode === 'canonical'\n\n return (\n <Page>\n <PageBody>\n <div className=\"space-y-4\">\n {/* UMES header injection (third-party extensions) */}\n <InjectionSpot spotId=\"detail:customers.person:header\" context={injectionContext} data={data} />\n <InjectionSpot spotId=\"detail:customers.person:status-badges\" context={injectionContext} data={data} />\n\n {/* Persistent person header */}\n <PersonDetailHeader\n data={data}\n onTagsChange={handleTagsChange}\n tagsSectionControllerRef={tagsSectionControllerRef}\n onSave={handleHeaderSave}\n onDelete={handleFormDelete}\n isDirty={isDirty}\n isSaving={isSaving}\n onOpenCompaniesTab={() => setActiveTab('companies')}\n onDataReload={() => { loadData().catch((err) => console.warn('[people-v2] onDataReload failed', err)) }}\n onFocusField={(fieldName) => {\n const selectorMap: Record<string, string> = {\n primaryEmail: 'input[type=\"email\"]',\n primaryPhone: 'input[type=\"tel\"]',\n }\n const selector = selectorMap[fieldName]\n const input = selector ? formWrapperRef.current?.querySelector<HTMLInputElement>(selector) : null\n if (input) {\n input.scrollIntoView({ behavior: 'smooth', block: 'center' })\n requestAnimationFrame(() => input.focus())\n }\n }}\n />\n\n {/* Zone content shared between desktop (CollapsibleZoneLayout) and mobile (MobilePersonDetail). */}\n {(() => {\n const zone1Content = (\n <div ref={formWrapperRef}>\n <CrudForm<PersonEditFormValues>\n embedded\n trackDirtyWhenEmbedded\n injectionSpotId=\"customers.person\"\n entityIds={[E.customers.customer_entity, E.customers.customer_person_profile]}\n schema={formSchema}\n fields={fields}\n groups={groups}\n initialValues={initialValues}\n optimisticLockUpdatedAt={data.person.updatedAt ?? data.person.updated_at ?? null}\n onSubmit={handleFormSubmit}\n onDelete={handleFormDelete}\n hideFooterActions\n collapsibleGroups={{ pageType: 'person-v2', chevronPosition: 'right' }}\n sortableGroups={{ pageType: 'person-v2' }}\n onDirtyChange={setIsDirty}\n />\n </div>\n )\n const zone2Content = (\n <PersonDetailTabs\n activeTab={activeTab}\n onTabChange={setActiveTab}\n injectedTabs={injectedTabs.map((tab) => ({ id: tab.id, label: tab.label }))}\n activitiesCount={interactionCount}\n dealsCount={dealCount}\n companiesCount={companyCount}\n tasksCount={todoCount}\n sectionAction={sectionAction}\n >\n <div className=\"min-w-0\">\n {(() => {\n // Injected tab content\n const injected = injectedTabMap.get(activeTab)\n if (injected) return injected()\n\n if (activeTab === 'activities') {\n return (\n <div className=\"space-y-4\">\n <ActivitiesCard\n entityId={personId}\n plannedActivities={plannedActivities}\n refreshKey={activityRefreshKey}\n onAddNew={handleAddActivity}\n onEditActivity={handleEditActivity}\n entityCompanyName={data.company?.displayName ?? data.companies?.[0]?.displayName ?? null}\n />\n <ActivitiesSection\n entityId={personId}\n entityName={personName}\n useCanonicalInteractions={useCanonicalInteractions}\n runGuardedMutation={runMutationWithContext}\n onDataRefresh={handleActivityCreated}\n refreshKey={activityRefreshKey}\n addActionLabel={t('customers.people.detail.activities.add', 'Log activity')}\n emptyState={{\n title: t('customers.people.detail.emptyState.activities.title', 'No activities logged yet'),\n actionLabel: t('customers.people.detail.emptyState.activities.action', 'Log activity'),\n }}\n onActionChange={handleSectionActionChange}\n onEditActivity={handleEditActivity}\n />\n </div>\n )\n }\n\n if (activeTab === 'emails') {\n return (\n <PersonEmailThreadsTab\n personId={personId}\n defaultRecipient={data.person?.primaryEmail ?? null}\n />\n )\n }\n\n if (activeTab === 'deals') {\n return (\n <DealsSection\n scope={dealsScope}\n emptyLabel={t('customers.people.detail.empty.deals', 'No deals linked to this person.')}\n addActionLabel={t('customers.people.detail.actions.addDeal', 'Add deal')}\n emptyState={{\n title: t('customers.people.detail.emptyState.deals.title', 'No deals yet'),\n actionLabel: t('customers.people.detail.emptyState.deals.action', 'Create a deal'),\n }}\n onActionChange={handleSectionActionChange}\n translator={detailTranslator}\n runGuardedMutation={runMutationWithContext}\n onCountDelta={(delta) => setDealCount((current) => Math.max(0, current + delta))}\n />\n )\n }\n\n if (activeTab === 'companies') {\n return (\n <PersonCompaniesSection\n personId={personId}\n personName={personName}\n initialLinkedCompanies={data?.companies ?? []}\n onChanged={loadData}\n runGuardedMutation={runMutationWithContext}\n />\n )\n }\n\n if (activeTab === 'tasks') {\n return (\n <TasksSection\n entityId={personId}\n initialTasks={[]}\n useCanonicalInteractions={useCanonicalInteractions}\n runGuardedMutation={runMutationWithContext}\n onDataRefresh={loadData}\n emptyLabel={t('customers.people.detail.empty.todos', 'No tasks linked to this person.')}\n addActionLabel={t('customers.people.detail.tasks.add', 'Add task')}\n emptyState={{\n title: t('customers.people.detail.emptyState.tasks.title', 'Plan what happens next'),\n actionLabel: t('customers.people.detail.emptyState.tasks.action', 'Create task'),\n }}\n onActionChange={handleSectionActionChange}\n translator={detailTranslator}\n entityName={personName}\n dialogContextKey=\"customers.people.detail.tasks.dialog.context\"\n dialogContextFallback=\"This task will be linked to {{name}}\"\n />\n )\n }\n\n if (activeTab === 'files') {\n return (\n <AttachmentsSection\n entityId={E.customers.customer_entity}\n recordId={personId}\n title={t('customers.people.detail.tabs.files', 'Files')}\n description={t('customers.people.detail.files.subtitle', 'Upload and manage files linked to this person.')}\n />\n )\n }\n\n if (activeTab === 'changelog') {\n return <ChangelogTab entityId={personId} entityType=\"person\" />\n }\n\n return null\n })()}\n </div>\n </PersonDetailTabs>\n )\n // Render only the layout variant that matches the viewport. Mounting\n // both the mobile and desktop layouts at once would create two\n // CrudForm instances bound to one `formWrapperRef`, so header Save\n // could submit the hidden instance's stale values and silently\n // discard the edit (#2453). `useIsMobile` is SSR-safe.\n return isMobile ? (\n <MobilePersonDetail zone1={zone1Content} zone2={zone2Content} />\n ) : (\n <CollapsibleZoneLayout\n pageType=\"person-v2\"\n entityName={personName}\n isDirty={isDirty}\n sections={zoneSections}\n zone1={zone1Content}\n zone2={zone2Content}\n />\n )\n })()}\n\n {/* UMES footer injection */}\n <InjectionSpot spotId=\"detail:customers.person:footer\" context={injectionContext} data={data} />\n\n {/* Schedule Activity Dialog \u2014 opened from PlannedActivities \"+ Schedule\" or other triggers */}\n <ScheduleActivityDialog\n open={scheduleDialogOpen}\n onClose={() => { setScheduleDialogOpen(false); setScheduleEditData(null) }}\n entityId={personId}\n entityName={personName}\n companyName={scheduleDialogCompanyName}\n entityType=\"person\"\n onActivityCreated={handleActivityCreated}\n editData={scheduleEditData}\n />\n {ConfirmDialogElement}\n </div>\n </PageBody>\n </Page>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter, useSearchParams } from 'next/navigation'\nimport { User, Hash, Users, Building2 } from 'lucide-react'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { CrudForm } from '@open-mercato/ui/backend/CrudForm'\nimport { CollapsibleZoneLayout, type ZoneSectionDescriptor } from '@open-mercato/ui/backend/crud/CollapsibleZoneLayout'\nimport { useIsMobile } from '@open-mercato/ui/hooks/useIsMobile'\nimport { updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { apiCallOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { E } from '#generated/entities.ids.generated'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useOrganizationScopeDetail } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { AttachmentsSection, ErrorMessage, LoadingMessage, RecordNotFoundState, type SectionAction } from '@open-mercato/ui/backend/detail'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { InjectionSpot, useInjectionWidgets } from '@open-mercato/ui/backend/injection/InjectionSpot'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { createTranslatorWithFallback } from '@open-mercato/shared/lib/i18n/translate'\n\nimport { ActivitiesSection } from '../../../../components/detail/ActivitiesSection'\nimport { PersonEmailThreadsTab } from '../../../../components/detail/PersonEmailThreadsTab'\nimport { ActivitiesCard } from '../../../../components/detail/ActivitiesCard'\nimport type { ActivityKind } from '../../../../components/detail/ActivitiesAddNewMenu'\nimport { DealsSection } from '../../../../components/detail/DealsSection'\nimport { TasksSection } from '../../../../components/detail/TasksSection'\nimport type { TagSummary } from '../../../../components/detail/types'\nimport { ScheduleActivityDialog, type ScheduleActivityEditData } from '../../../../components/detail/ScheduleActivityDialog'\nimport { PersonDetailHeader } from '../../../../components/detail/PersonDetailHeader'\nimport { ChangelogTab } from '../../../../components/detail/ChangelogTab'\nimport { PersonDetailTabs, resolveLegacyTab, type PersonTabId } from '../../../../components/detail/PersonDetailTabs'\nimport { AddressesSection } from '../../../../components/detail/AddressesSection'\nimport { PersonCompaniesSection } from '../../../../components/detail/PersonCompaniesSection'\nimport { MobilePersonDetail } from '../../../../components/detail/MobilePersonDetail'\nimport type { TagsSectionController } from '@open-mercato/ui/backend/detail'\nimport {\n buildPersonEditPayload,\n createPersonEditFields,\n createPersonPersonalDataGroups,\n createPersonEditSchema,\n mapPersonOverviewToFormValues,\n type PersonEditFormValues,\n type PersonOverview,\n} from '../../../../components/formConfig'\nimport { coerceDisplayName, coerceDisplayNameOrNull } from '../../../../lib/displayName'\n\nexport default function PersonDetailV2Page({ params }: { params?: { id?: string } }) {\n const id = params?.id\n const t = useT()\n const router = useRouter()\n const searchParams = useSearchParams()\n const { organizationId } = useOrganizationScopeDetail()\n const isMobile = useIsMobile()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n\n const detailTranslator = React.useMemo(() => createTranslatorWithFallback(t), [t])\n\n\n const formSchema = React.useMemo(() => createPersonEditSchema(), [])\n const fields = React.useMemo(() => createPersonEditFields(t), [t])\n\n const [data, setData] = React.useState<PersonOverview | null>(null)\n // Mirror the latest `data` into a ref so save handlers always read the current\n // optimistic-lock token (`person.updatedAt`) instead of the value captured in\n // their `useCallback` closure. Without this, a header-field save issued after a\n // prior in-page reload would send a stale token (or none), letting a concurrent\n // two-tab overwrite slip through without the 409 + conflict bar (#2055, Alina A7).\n const dataRef = React.useRef<PersonOverview | null>(null)\n React.useEffect(() => {\n dataRef.current = data\n }, [data])\n const [isLoading, setIsLoading] = React.useState(true)\n const [error, setError] = React.useState<string | null>(null)\n const [isNotFound, setIsNotFound] = React.useState(false)\n\n // Form state lifted for header Save button\n const [isDirty, setIsDirty] = React.useState(false)\n const [isSaving, setIsSaving] = React.useState(false)\n const formWrapperRef = React.useRef<HTMLDivElement>(null)\n\n const initialTab = React.useMemo(() => {\n return resolveLegacyTab(searchParams?.get('tab'))\n }, [searchParams])\n const [activeTab, setActiveTab] = React.useState<PersonTabId>(initialTab)\n const [sectionAction, setSectionAction] = React.useState<SectionAction | null>(null)\n const [scheduleDialogOpen, setScheduleDialogOpen] = React.useState(false)\n const [scheduleEditData, setScheduleEditData] = React.useState<ScheduleActivityEditData | null>(null)\n const [activityRefreshKey, setActivityRefreshKey] = React.useState(0)\n const [dealCount, setDealCount] = React.useState(0)\n\n const currentPersonId = data?.person?.id ?? null\n const mutationContextId = React.useMemo(\n () => (currentPersonId ? `customer-person:${currentPersonId}` : `customer-person:${id ?? 'pending'}`),\n [currentPersonId, id],\n )\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n personId?: string | null\n resourceKind: string\n resourceId?: string\n data: PersonOverview | null\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: mutationContextId,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n const personDisplayName = coerceDisplayName(data?.person?.displayName)\n const personName = personDisplayName.trim().length\n ? personDisplayName\n : t('customers.people.list.deleteFallbackName', 'this person')\n\n const personDisplayNameForGroups = personDisplayName.trim().length\n ? personDisplayName.trim()\n : null\n\n const scheduleDialogCompanyName = coerceDisplayNameOrNull(\n data?.company?.displayName ?? data?.companies?.[0]?.displayName ?? null,\n )\n\n const groups = React.useMemo(\n () => createPersonPersonalDataGroups(t, { entityName: personDisplayNameForGroups }),\n [t, personDisplayNameForGroups],\n )\n\n const zoneSections = React.useMemo<ZoneSectionDescriptor[]>(() => [\n { id: 'personalData', icon: User, label: t('customers.people.form.groups.personalData', 'Personal data') },\n { id: 'companyRole', icon: Building2, label: t('customers.people.form.groups.companyRole', 'Company & role') },\n { id: 'customFields', icon: Hash, label: t('customers.people.form.groups.customAttributes', 'Custom attributes') },\n { id: 'roles', icon: Users, label: t('customers.people.form.groups.roles', 'My roles') },\n ], [t])\n\n // Data loading\n const initialLoadDoneRef = React.useRef(false)\n const loadData = React.useCallback(async (lockTokenOverride?: string | null) => {\n if (!id) {\n setIsNotFound(true)\n setIsLoading(false)\n return\n }\n if (!initialLoadDoneRef.current) {\n setIsLoading(true)\n }\n setError(null)\n setIsNotFound(false)\n try {\n const payload = await readApiResultOrThrow<PersonOverview>(\n `/api/customers/people/${encodeURIComponent(id)}`,\n undefined,\n { errorMessage: t('customers.people.detail.error.load', 'Failed to load person.') },\n )\n // When the caller is the save handler, pin the optimistic-lock token to the\n // value the write itself returned rather than the one this GET observed \u2014 a\n // concurrent third-party bump between save and reload must stay stale so the\n // next in-page save 409s (#2055, Alina A7). Applied in the same state update\n // as the refresh to avoid a redundant second re-render.\n const next = lockTokenOverride && payload?.person\n ? { ...payload, person: { ...payload.person, updatedAt: lockTokenOverride, updated_at: lockTokenOverride } }\n : payload\n setData(next as PersonOverview)\n } catch (err) {\n if ((err as { status?: number }).status === 404) {\n setIsNotFound(true)\n } else {\n const message = err instanceof Error ? err.message : t('customers.people.detail.error.load', 'Failed to load person.')\n setError(message)\n }\n if (!initialLoadDoneRef.current) setData(null)\n } finally {\n setIsLoading(false)\n initialLoadDoneRef.current = true\n }\n }, [id, t])\n\n React.useEffect(() => {\n loadData().catch((err) => console.warn('[people-v2] loadData failed', err))\n }, [loadData])\n\n React.useEffect(() => {\n setDealCount(data?.counts?.deals ?? 0)\n }, [data?.counts?.deals])\n\n const handleActivityCreated = React.useCallback(() => {\n setActivityRefreshKey((k) => k + 1)\n loadData().catch((err) => console.warn('[people-v2] reload after activity failed', err))\n }, [loadData])\n\n const plannedActivities = React.useMemo(() => {\n return data?.plannedActivitiesPreview ?? []\n }, [data?.plannedActivitiesPreview])\n\n // Injection context for UMES\n const injectionContext = React.useMemo(\n () => ({\n formId: mutationContextId,\n personId: currentPersonId,\n resourceKind: 'customers.person',\n resourceId: currentPersonId ?? (id ?? undefined),\n data,\n retryLastMutation,\n }),\n [currentPersonId, data, id, mutationContextId, retryLastMutation],\n )\n const runMutationWithContext = React.useCallback(\n async <T,>(operation: () => Promise<T>, mutationPayload?: Record<string, unknown>): Promise<T> => {\n return runMutation({\n operation,\n mutationPayload,\n context: injectionContext,\n })\n },\n [injectionContext, runMutation],\n )\n\n const handleAddActivity = React.useCallback((kind: ActivityKind) => {\n setScheduleEditData({\n id: '',\n interactionType: kind,\n title: null,\n body: null,\n scheduledAt: null,\n durationMinutes: null,\n location: null,\n allDay: null,\n recurrenceRule: null,\n recurrenceEnd: null,\n participants: null,\n reminderMinutes: null,\n visibility: null,\n linkedEntities: null,\n guestPermissions: null,\n })\n setScheduleDialogOpen(true)\n }, [])\n\n const handleEditActivity = React.useCallback((activity: { id: string; interactionType?: string; title?: string | null; body?: string | null; scheduledAt?: string | null; occurredAt?: string | null; [key: string]: unknown }) => {\n const raw = activity as Record<string, unknown>\n const durationValue = typeof raw.duration === 'number'\n ? raw.duration\n : typeof raw.durationMinutes === 'number'\n ? raw.durationMinutes as number\n : null\n // Forward `customValues` so per-type chip state (callPhoneNumber, callDirection,\n // taskPriority, \u2026) round-trips on edit (#1808 phone persistence).\n // Forward `occurredAt` so historical activity edits prefill from the original\n // moment instead of \"today\" (#1807 prefill).\n const editPayload = {\n id: activity.id,\n updatedAt: typeof raw.updatedAt === 'string' ? raw.updatedAt as string : typeof raw.updated_at === 'string' ? raw.updated_at as string : null,\n interactionType: typeof activity.interactionType === 'string' ? activity.interactionType : undefined,\n title: typeof activity.title === 'string' ? activity.title : null,\n body: typeof activity.body === 'string' ? activity.body : null,\n scheduledAt: typeof activity.scheduledAt === 'string' ? activity.scheduledAt : null,\n occurredAt: typeof activity.occurredAt === 'string' ? activity.occurredAt : null,\n durationMinutes: durationValue,\n location: typeof raw.location === 'string' ? raw.location as string : null,\n allDay: typeof raw.allDay === 'boolean' ? raw.allDay as boolean : null,\n recurrenceRule: typeof raw.recurrenceRule === 'string' ? raw.recurrenceRule as string : null,\n recurrenceEnd: typeof raw.recurrenceEnd === 'string' ? raw.recurrenceEnd as string : null,\n participants: Array.isArray(raw.participants) ? raw.participants as ScheduleActivityEditData['participants'] : null,\n reminderMinutes: typeof raw.reminderMinutes === 'number' ? raw.reminderMinutes as number : null,\n visibility: typeof raw.visibility === 'string' ? raw.visibility as string : null,\n linkedEntities: Array.isArray(raw.linkedEntities) ? raw.linkedEntities as ScheduleActivityEditData['linkedEntities'] : null,\n guestPermissions: raw.guestPermissions && typeof raw.guestPermissions === 'object'\n ? raw.guestPermissions as ScheduleActivityEditData['guestPermissions']\n : null,\n customValues: raw.customValues && typeof raw.customValues === 'object'\n ? raw.customValues as Record<string, unknown>\n : null,\n phoneNumber: typeof raw.phoneNumber === 'string' ? raw.phoneNumber as string : null,\n } as ScheduleActivityEditData & { customValues?: Record<string, unknown> | null; phoneNumber?: string | null }\n setScheduleEditData(editPayload)\n setScheduleDialogOpen(true)\n }, [])\n\n // Injected tabs from UMES\n const { widgets: injectedTabWidgets } = useInjectionWidgets('detail:customers.person:tabs', {\n context: injectionContext,\n triggerOnLoad: true,\n })\n\n const injectedTabs = React.useMemo(\n () =>\n (injectedTabWidgets ?? [])\n .filter((widget) => (widget.placement?.kind ?? 'tab') === 'tab')\n .map((widget) => {\n const tabId = widget.placement?.groupId ?? widget.widgetId\n const label = widget.placement?.groupLabel ?? widget.module.metadata.title ?? tabId\n const priority = typeof widget.placement?.priority === 'number' ? widget.placement.priority : 0\n const render = () => (\n <widget.module.Widget\n context={injectionContext}\n data={data}\n onDataChange={(next: unknown) => setData(next as PersonOverview)}\n />\n )\n return { id: tabId, label, priority, render }\n })\n .sort((a, b) => b.priority - a.priority),\n [data, injectedTabWidgets, injectionContext],\n )\n\n const injectedTabMap = React.useMemo(() => new Map(injectedTabs.map((tab) => [tab.id, tab.render])), [injectedTabs])\n\n // Tags\n const handleTagsChange = React.useCallback((nextTags: TagSummary[]) => {\n setData((prev) => (prev ? { ...prev, tags: nextTags } : prev))\n }, [])\n const tagsSectionControllerRef = React.useRef<TagsSectionController | null>(null)\n\n // Section action (for tabs that expose add/create buttons)\n const handleSectionActionChange = React.useCallback((action: SectionAction | null) => {\n setSectionAction((prev) => (action !== null ? action : prev))\n }, [])\n\n React.useEffect(() => {\n setSectionAction(null)\n }, [activeTab])\n\n // Deals scope\n const dealsScope = React.useMemo(\n () => (currentPersonId ? ({ kind: 'person', entityId: currentPersonId } as const) : null),\n [currentPersonId],\n )\n\n const initialValues = React.useMemo(\n () => (data ? mapPersonOverviewToFormValues(data) : undefined),\n [data],\n )\n\n // Form submit/delete\n const handleFormSubmit = React.useCallback(\n async (values: PersonEditFormValues) => {\n setIsSaving(true)\n try {\n await tagsSectionControllerRef.current?.flush()\n\n let payload: Record<string, unknown>\n try {\n payload = buildPersonEditPayload(values, organizationId)\n } catch (err) {\n if (err instanceof Error && err.message === 'DISPLAY_NAME_REQUIRED') {\n const message = t('customers.people.form.displayName.error')\n throw createCrudFormError(message, { displayName: message })\n }\n throw err\n }\n\n // Attach the current optimistic-lock token directly on this write path so\n // every header-field edit (displayName/status/\u2026) carries `updatedAt`, not\n // just the fields the embedded CrudForm intercepts. Read from `dataRef` so\n // the token reflects the latest in-page reload rather than a stale closure\n // capture, and let the 409 propagate to CrudForm's surfaceRecordConflict so\n // the unified conflict bar renders (#2055, Alina A7).\n const lockedUpdatedAt = dataRef.current?.person?.updatedAt\n ?? dataRef.current?.person?.updated_at\n ?? null\n const updateResponse = await withScopedApiRequestHeaders(\n buildOptimisticLockHeader(lockedUpdatedAt),\n () => updateCrud<{ updatedAt?: string | null }>('customers/people', payload),\n )\n flash(t('customers.people.form.updateSuccess', 'Person updated.'), 'success')\n // Refresh the view and pin the optimistic-lock token to the write's OWN\n // authoritative `updatedAt` in a single reload (see loadData) so a\n // concurrent third-party bump stays stale on the next save (#2055, Alina A7).\n const savedUpdatedAt = typeof updateResponse.result?.updatedAt === 'string'\n ? updateResponse.result.updatedAt\n : null\n await loadData(savedUpdatedAt)\n } finally {\n setIsSaving(false)\n }\n },\n [loadData, organizationId, t],\n )\n\n const handleFormDelete = React.useCallback(\n async () => {\n const personId = data?.person?.id ?? ''\n if (!personId) return\n const approved = await confirm({\n title: t('customers.people.detail.deleteConfirmTitle', 'Delete person?'),\n description: t('customers.people.detail.deleteConfirmDescription', 'This action cannot be undone.'),\n confirmText: t('customers.people.detail.actions.delete', 'Delete'),\n cancelText: t('customers.people.detail.actions.cancel', 'Cancel'),\n variant: 'destructive',\n })\n if (!approved) return\n try {\n await runMutationWithContext(\n () => withScopedApiRequestHeaders(\n buildOptimisticLockHeader(data?.person?.updatedAt ?? data?.person?.updated_at ?? null),\n () => deleteCrud('customers/people', { id: personId }),\n ),\n { id: personId, operation: 'deletePerson' },\n )\n } catch (err) {\n // The guarded mutation routes a 409 to the unified conflict bar; surface\n // any other server error (e.g. a linked-records delete guard) as a flash\n // instead of letting it crash the page.\n if (!surfaceRecordConflict(err, t)) {\n flash(\n err instanceof Error && err.message.trim().length > 0\n ? err.message\n : t('customers.people.detail.deleteError', 'Failed to delete person.'),\n 'error',\n )\n }\n return\n }\n flash(t('customers.people.list.deleteSuccess', 'Person deleted.'), 'success')\n router.push('/backend/customers/people')\n },\n [confirm, data?.person?.id, router, runMutationWithContext, t],\n )\n\n const handleHeaderSave = React.useCallback(() => {\n const form = formWrapperRef.current?.querySelector('form')\n if (form) form.requestSubmit()\n }, [])\n\n // Counts for tab badges\n const interactionCount = data?.counts?.activities ?? 0\n const todoCount = data?.counts?.todos ?? 0\n const companyCount = data?.counts?.companies ?? (data?.companies?.length ?? (data?.company ? 1 : 0))\n\n // Loading / error states\n if (isLoading) {\n return (\n <Page>\n <PageBody>\n <LoadingMessage label={t('customers.people.detail.loading', 'Loading person\u2026')} />\n </PageBody>\n </Page>\n )\n }\n\n if (isNotFound) {\n return (\n <Page>\n <PageBody>\n <RecordNotFoundState\n label={t('customers.people.detail.error.notFound', 'Person not found.')}\n backHref=\"/backend/customers/people\"\n backLabel={t('customers.people.detail.actions.backToList', 'Back to people')}\n />\n </PageBody>\n </Page>\n )\n }\n\n if (error || !data?.person?.id || !initialValues) {\n return (\n <Page>\n <PageBody>\n <ErrorMessage\n label={error ?? t('customers.people.detail.error.load', 'Failed to load person.')}\n action={(\n <Button asChild variant=\"outline\">\n <Link href=\"/backend/customers/people\">\n {t('customers.people.detail.actions.backToList', 'Back to people')}\n </Link>\n </Button>\n )}\n />\n </PageBody>\n </Page>\n )\n }\n\n const personId = data.person.id\n const useCanonicalInteractions = data.interactionMode === 'canonical'\n\n return (\n <Page>\n <PageBody>\n <div className=\"space-y-4\">\n {/* UMES header injection (third-party extensions) */}\n <InjectionSpot spotId=\"detail:customers.person:header\" context={injectionContext} data={data} />\n <InjectionSpot spotId=\"detail:customers.person:status-badges\" context={injectionContext} data={data} />\n\n {/* Persistent person header */}\n <PersonDetailHeader\n data={data}\n onTagsChange={handleTagsChange}\n tagsSectionControllerRef={tagsSectionControllerRef}\n onSave={handleHeaderSave}\n onDelete={handleFormDelete}\n isDirty={isDirty}\n isSaving={isSaving}\n onOpenCompaniesTab={() => setActiveTab('companies')}\n onDataReload={() => { loadData().catch((err) => console.warn('[people-v2] onDataReload failed', err)) }}\n onFocusField={(fieldName) => {\n const selectorMap: Record<string, string> = {\n primaryEmail: 'input[type=\"email\"]',\n primaryPhone: 'input[type=\"tel\"]',\n }\n const selector = selectorMap[fieldName]\n const input = selector ? formWrapperRef.current?.querySelector<HTMLInputElement>(selector) : null\n if (input) {\n input.scrollIntoView({ behavior: 'smooth', block: 'center' })\n requestAnimationFrame(() => input.focus())\n }\n }}\n />\n\n {/* Zone content shared between desktop (CollapsibleZoneLayout) and mobile (MobilePersonDetail). */}\n {(() => {\n const zone1Content = (\n <div ref={formWrapperRef}>\n <CrudForm<PersonEditFormValues>\n embedded\n trackDirtyWhenEmbedded\n injectionSpotId=\"customers.person\"\n entityIds={[E.customers.customer_entity, E.customers.customer_person_profile]}\n schema={formSchema}\n fields={fields}\n groups={groups}\n initialValues={initialValues}\n optimisticLockUpdatedAt={data.person.updatedAt ?? data.person.updated_at ?? null}\n onSubmit={handleFormSubmit}\n onDelete={handleFormDelete}\n hideFooterActions\n collapsibleGroups={{ pageType: 'person-v2', chevronPosition: 'right' }}\n sortableGroups={{ pageType: 'person-v2' }}\n onDirtyChange={setIsDirty}\n />\n </div>\n )\n const zone2Content = (\n <PersonDetailTabs\n activeTab={activeTab}\n onTabChange={setActiveTab}\n injectedTabs={injectedTabs.map((tab) => ({ id: tab.id, label: tab.label }))}\n activitiesCount={interactionCount}\n dealsCount={dealCount}\n companiesCount={companyCount}\n addressesCount={data?.counts?.addresses ?? 0}\n tasksCount={todoCount}\n sectionAction={sectionAction}\n >\n <div className=\"min-w-0\">\n {(() => {\n // Injected tab content\n const injected = injectedTabMap.get(activeTab)\n if (injected) return injected()\n\n if (activeTab === 'activities') {\n return (\n <div className=\"space-y-4\">\n <ActivitiesCard\n entityId={personId}\n plannedActivities={plannedActivities}\n refreshKey={activityRefreshKey}\n onAddNew={handleAddActivity}\n onEditActivity={handleEditActivity}\n entityCompanyName={data.company?.displayName ?? data.companies?.[0]?.displayName ?? null}\n />\n <ActivitiesSection\n entityId={personId}\n entityName={personName}\n useCanonicalInteractions={useCanonicalInteractions}\n runGuardedMutation={runMutationWithContext}\n onDataRefresh={handleActivityCreated}\n refreshKey={activityRefreshKey}\n addActionLabel={t('customers.people.detail.activities.add', 'Log activity')}\n emptyState={{\n title: t('customers.people.detail.emptyState.activities.title', 'No activities logged yet'),\n actionLabel: t('customers.people.detail.emptyState.activities.action', 'Log activity'),\n }}\n onActionChange={handleSectionActionChange}\n onEditActivity={handleEditActivity}\n />\n </div>\n )\n }\n\n if (activeTab === 'emails') {\n return (\n <PersonEmailThreadsTab\n personId={personId}\n defaultRecipient={data.person?.primaryEmail ?? null}\n />\n )\n }\n\n if (activeTab === 'deals') {\n return (\n <DealsSection\n scope={dealsScope}\n emptyLabel={t('customers.people.detail.empty.deals', 'No deals linked to this person.')}\n addActionLabel={t('customers.people.detail.actions.addDeal', 'Add deal')}\n emptyState={{\n title: t('customers.people.detail.emptyState.deals.title', 'No deals yet'),\n actionLabel: t('customers.people.detail.emptyState.deals.action', 'Create a deal'),\n }}\n onActionChange={handleSectionActionChange}\n translator={detailTranslator}\n runGuardedMutation={runMutationWithContext}\n onCountDelta={(delta) => setDealCount((current) => Math.max(0, current + delta))}\n />\n )\n }\n\n if (activeTab === 'companies') {\n return (\n <PersonCompaniesSection\n personId={personId}\n personName={personName}\n initialLinkedCompanies={data?.companies ?? []}\n onChanged={loadData}\n runGuardedMutation={runMutationWithContext}\n />\n )\n }\n\n if (activeTab === 'addresses') {\n return (\n <AddressesSection\n entityId={personId}\n emptyLabel={t('customers.people.detail.empty.addresses', 'No addresses linked to this person.')}\n addActionLabel={t('customers.people.detail.addresses.add', 'Add address')}\n emptyState={{\n title: t('customers.people.detail.emptyState.addresses.title', 'No addresses yet'),\n actionLabel: t('customers.people.detail.emptyState.addresses.action', 'Add address'),\n }}\n onActionChange={handleSectionActionChange}\n translator={detailTranslator}\n />\n )\n }\n\n if (activeTab === 'tasks') {\n return (\n <TasksSection\n entityId={personId}\n initialTasks={[]}\n useCanonicalInteractions={useCanonicalInteractions}\n runGuardedMutation={runMutationWithContext}\n onDataRefresh={loadData}\n emptyLabel={t('customers.people.detail.empty.todos', 'No tasks linked to this person.')}\n addActionLabel={t('customers.people.detail.tasks.add', 'Add task')}\n emptyState={{\n title: t('customers.people.detail.emptyState.tasks.title', 'Plan what happens next'),\n actionLabel: t('customers.people.detail.emptyState.tasks.action', 'Create task'),\n }}\n onActionChange={handleSectionActionChange}\n translator={detailTranslator}\n entityName={personName}\n dialogContextKey=\"customers.people.detail.tasks.dialog.context\"\n dialogContextFallback=\"This task will be linked to {{name}}\"\n />\n )\n }\n\n if (activeTab === 'files') {\n return (\n <AttachmentsSection\n entityId={E.customers.customer_entity}\n recordId={personId}\n title={t('customers.people.detail.tabs.files', 'Files')}\n description={t('customers.people.detail.files.subtitle', 'Upload and manage files linked to this person.')}\n />\n )\n }\n\n if (activeTab === 'changelog') {\n return <ChangelogTab entityId={personId} entityType=\"person\" />\n }\n\n return null\n })()}\n </div>\n </PersonDetailTabs>\n )\n // Render only the layout variant that matches the viewport. Mounting\n // both the mobile and desktop layouts at once would create two\n // CrudForm instances bound to one `formWrapperRef`, so header Save\n // could submit the hidden instance's stale values and silently\n // discard the edit (#2453). `useIsMobile` is SSR-safe.\n return isMobile ? (\n <MobilePersonDetail zone1={zone1Content} zone2={zone2Content} />\n ) : (\n <CollapsibleZoneLayout\n pageType=\"person-v2\"\n entityName={personName}\n isDirty={isDirty}\n sections={zoneSections}\n zone1={zone1Content}\n zone2={zone2Content}\n />\n )\n })()}\n\n {/* UMES footer injection */}\n <InjectionSpot spotId=\"detail:customers.person:footer\" context={injectionContext} data={data} />\n\n {/* Schedule Activity Dialog \u2014 opened from PlannedActivities \"+ Schedule\" or other triggers */}\n <ScheduleActivityDialog\n open={scheduleDialogOpen}\n onClose={() => { setScheduleDialogOpen(false); setScheduleEditData(null) }}\n entityId={personId}\n entityName={personName}\n companyName={scheduleDialogCompanyName}\n entityType=\"person\"\n onActivityCreated={handleActivityCreated}\n editData={scheduleEditData}\n />\n {ConfirmDialogElement}\n </div>\n </PageBody>\n </Page>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["personId"]
7
7
  }
@@ -167,7 +167,7 @@ const CUSTOMER_EXAMPLES = [
167
167
  primaryPhone: "+1 415-555-0148",
168
168
  source: "partner_referral",
169
169
  lifecycleStage: "customer",
170
- status: "customer",
170
+ status: "active",
171
171
  custom: {
172
172
  relationship_health: "healthy",
173
173
  renewal_quarter: "Q3",
@@ -224,7 +224,7 @@ const CUSTOMER_EXAMPLES = [
224
224
  phone: "+1 628-555-0199",
225
225
  timezone: "America/Los_Angeles",
226
226
  linkedInUrl: "https://www.linkedin.com/in/danielcho-energy/",
227
- source: "outbound_campaign",
227
+ source: "cold_outreach",
228
228
  custom: {
229
229
  buying_role: "economic_buyer",
230
230
  preferred_pronouns: "he/him",
@@ -298,7 +298,7 @@ const CUSTOMER_EXAMPLES = [
298
298
  valueCurrency: "USD",
299
299
  expectedCloseAt: isoDaysFromNow(65),
300
300
  probability: 40,
301
- source: "inbound_web",
301
+ source: "web_form",
302
302
  custom: {
303
303
  competitive_risk: "high",
304
304
  implementation_complexity: "complex",
@@ -372,7 +372,7 @@ const CUSTOMER_EXAMPLES = [
372
372
  description: "Boston-based analytics platform helping consumer brands optimize merchandising decisions.",
373
373
  primaryEmail: "info@harborviewanalytics.com",
374
374
  primaryPhone: "+1 617-555-0024",
375
- source: "industry_event",
375
+ source: "event",
376
376
  lifecycleStage: "prospect",
377
377
  status: "active",
378
378
  custom: {
@@ -404,7 +404,7 @@ const CUSTOMER_EXAMPLES = [
404
404
  phone: "+1 617-555-0168",
405
405
  timezone: "America/New_York",
406
406
  linkedInUrl: "https://www.linkedin.com/in/arjunpatel-sales/",
407
- source: "industry_event",
407
+ source: "event",
408
408
  custom: {
409
409
  buying_role: "economic_buyer",
410
410
  preferred_pronouns: "he/him",
@@ -422,7 +422,7 @@ const CUSTOMER_EXAMPLES = [
422
422
  phone: "+1 617-555-0179",
423
423
  timezone: "America/New_York",
424
424
  linkedInUrl: "https://www.linkedin.com/in/lenaortiz-retail/",
425
- source: "industry_event",
425
+ source: "event",
426
426
  custom: {
427
427
  buying_role: "champion",
428
428
  preferred_pronouns: "she/her",
@@ -441,7 +441,7 @@ const CUSTOMER_EXAMPLES = [
441
441
  valueCurrency: "USD",
442
442
  expectedCloseAt: isoDaysFromNow(-25),
443
443
  probability: 100,
444
- source: "industry_event",
444
+ source: "event",
445
445
  custom: {
446
446
  competitive_risk: "low",
447
447
  implementation_complexity: "standard",
@@ -496,7 +496,7 @@ const CUSTOMER_EXAMPLES = [
496
496
  valueCurrency: "USD",
497
497
  expectedCloseAt: isoDaysFromNow(120),
498
498
  probability: 35,
499
- source: "outbound_campaign",
499
+ source: "cold_outreach",
500
500
  custom: {
501
501
  competitive_risk: "medium",
502
502
  implementation_complexity: "complex",
@@ -573,7 +573,7 @@ const CUSTOMER_EXAMPLES = [
573
573
  primaryPhone: "+1 512-555-0456",
574
574
  source: "customer_referral",
575
575
  lifecycleStage: "customer",
576
- status: "customer",
576
+ status: "active",
577
577
  custom: {
578
578
  relationship_health: "healthy",
579
579
  renewal_quarter: "Q1",
@@ -2647,6 +2647,12 @@ async function ensureCustomerCustomFieldDefinitions(em, tenantId) {
2647
2647
  });
2648
2648
  }
2649
2649
  export {
2650
+ CUSTOMER_EXAMPLES,
2651
+ DEAL_STATUS_DEFAULTS,
2652
+ ENTITY_LIFECYCLE_STAGE_DEFAULTS,
2653
+ ENTITY_SOURCE_DEFAULTS,
2654
+ ENTITY_STATUS_DEFAULTS,
2655
+ PIPELINE_STAGE_DEFAULTS,
2650
2656
  cli_default as default,
2651
2657
  ensureCustomerCustomFieldDefinitions,
2652
2658
  seedCurrencyDictionary,