@open-mercato/core 0.6.7-develop.6758.1.697eade236 → 0.6.7-develop.6766.1.40c9011995

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 (263) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/modules/api_keys/backend/api-keys/page.js +2 -1
  3. package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
  4. package/dist/modules/api_keys/extension-points.js +16 -0
  5. package/dist/modules/api_keys/extension-points.js.map +7 -0
  6. package/dist/modules/audit_logs/components/AccessLogsTable.js +2 -1
  7. package/dist/modules/audit_logs/components/AccessLogsTable.js.map +2 -2
  8. package/dist/modules/audit_logs/components/AuditLogsActions.js +2 -1
  9. package/dist/modules/audit_logs/components/AuditLogsActions.js.map +2 -2
  10. package/dist/modules/audit_logs/extension-points.js +14 -0
  11. package/dist/modules/audit_logs/extension-points.js.map +7 -0
  12. package/dist/modules/auth/backend/roles/page.js +2 -1
  13. package/dist/modules/auth/backend/roles/page.js.map +2 -2
  14. package/dist/modules/auth/backend/users/page.js +2 -1
  15. package/dist/modules/auth/backend/users/page.js.map +2 -2
  16. package/dist/modules/auth/extension-points.js +21 -0
  17. package/dist/modules/auth/extension-points.js.map +7 -0
  18. package/dist/modules/auth/frontend/login.js +2 -1
  19. package/dist/modules/auth/frontend/login.js.map +2 -2
  20. package/dist/modules/business_rules/backend/rules/page.js +2 -1
  21. package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
  22. package/dist/modules/business_rules/events.js +13 -0
  23. package/dist/modules/business_rules/events.js.map +7 -0
  24. package/dist/modules/business_rules/extension-points.js +13 -0
  25. package/dist/modules/business_rules/extension-points.js.map +7 -0
  26. package/dist/modules/catalog/backend/catalog/products/[id]/page.js +2 -1
  27. package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
  28. package/dist/modules/catalog/backend/catalog/products/create/page.js +2 -1
  29. package/dist/modules/catalog/backend/catalog/products/create/page.js.map +2 -2
  30. package/dist/modules/catalog/components/categories/CategoriesDataTable.js +2 -1
  31. package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
  32. package/dist/modules/catalog/components/products/ProductsDataTable.js +3 -2
  33. package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
  34. package/dist/modules/catalog/events.js +1 -0
  35. package/dist/modules/catalog/events.js.map +2 -2
  36. package/dist/modules/catalog/extension-points.js +27 -0
  37. package/dist/modules/catalog/extension-points.js.map +7 -0
  38. package/dist/modules/communication_channels/backend/communication_channels/channels/page.js +2 -1
  39. package/dist/modules/communication_channels/backend/communication_channels/channels/page.js.map +2 -2
  40. package/dist/modules/communication_channels/backend/profile/communication-channels/page.js +3 -2
  41. package/dist/modules/communication_channels/backend/profile/communication-channels/page.js.map +2 -2
  42. package/dist/modules/communication_channels/extension-points.js +20 -0
  43. package/dist/modules/communication_channels/extension-points.js.map +7 -0
  44. package/dist/modules/configs/backend/config/system-status/page.js +2 -1
  45. package/dist/modules/configs/backend/config/system-status/page.js.map +2 -2
  46. package/dist/modules/configs/extension-points.js +18 -0
  47. package/dist/modules/configs/extension-points.js.map +7 -0
  48. package/dist/modules/currencies/backend/currencies/page.js +2 -1
  49. package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
  50. package/dist/modules/currencies/backend/exchange-rates/page.js +2 -1
  51. package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
  52. package/dist/modules/currencies/extension-points.js +14 -0
  53. package/dist/modules/currencies/extension-points.js.map +7 -0
  54. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +2 -1
  55. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js.map +2 -2
  56. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +2 -1
  57. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
  58. package/dist/modules/customer_accounts/extension-points.js +14 -0
  59. package/dist/modules/customer_accounts/extension-points.js.map +7 -0
  60. package/dist/modules/customers/backend/customers/companies/[id]/page.js +2 -1
  61. package/dist/modules/customers/backend/customers/companies/[id]/page.js.map +2 -2
  62. package/dist/modules/customers/backend/customers/companies/page.js +2 -1
  63. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  64. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +5 -4
  65. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
  66. package/dist/modules/customers/backend/customers/deals/[id]/page.js +5 -4
  67. package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
  68. package/dist/modules/customers/backend/customers/deals/page.js +2 -1
  69. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  70. package/dist/modules/customers/backend/customers/people/[id]/page.js +2 -1
  71. package/dist/modules/customers/backend/customers/people/[id]/page.js.map +2 -2
  72. package/dist/modules/customers/backend/customers/people/page.js +2 -1
  73. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  74. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +5 -4
  75. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
  76. package/dist/modules/customers/components/CustomerTodosTable.js +2 -1
  77. package/dist/modules/customers/components/CustomerTodosTable.js.map +2 -2
  78. package/dist/modules/customers/extension-points.js +42 -0
  79. package/dist/modules/customers/extension-points.js.map +7 -0
  80. package/dist/modules/customers/lib/calendar/format.js +8 -4
  81. package/dist/modules/customers/lib/calendar/format.js.map +2 -2
  82. package/dist/modules/data_sync/backend/data-sync/page.js +2 -1
  83. package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
  84. package/dist/modules/data_sync/extension-points.js +13 -0
  85. package/dist/modules/data_sync/extension-points.js.map +7 -0
  86. package/dist/modules/directory/backend/directory/organizations/page.js +2 -1
  87. package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
  88. package/dist/modules/directory/backend/directory/tenants/page.js +2 -1
  89. package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
  90. package/dist/modules/directory/extension-points.js +14 -0
  91. package/dist/modules/directory/extension-points.js.map +7 -0
  92. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +5 -1
  93. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
  94. package/dist/modules/entities/components/SystemEntitiesTable.js +2 -1
  95. package/dist/modules/entities/components/SystemEntitiesTable.js.map +2 -2
  96. package/dist/modules/entities/components/UserEntitiesTable.js +2 -1
  97. package/dist/modules/entities/components/UserEntitiesTable.js.map +2 -2
  98. package/dist/modules/entities/extension-points.js +21 -0
  99. package/dist/modules/entities/extension-points.js.map +7 -0
  100. package/dist/modules/integrations/backend/integrations/[id]/page.js +2 -4
  101. package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
  102. package/dist/modules/integrations/extension-points.js +30 -0
  103. package/dist/modules/integrations/extension-points.js.map +7 -0
  104. package/dist/modules/messages/components/ComposeMessagePageClient.js +2 -1
  105. package/dist/modules/messages/components/ComposeMessagePageClient.js.map +2 -2
  106. package/dist/modules/messages/components/MessageDetailPageClient.js +3 -2
  107. package/dist/modules/messages/components/MessageDetailPageClient.js.map +2 -2
  108. package/dist/modules/messages/components/MessagesInboxPageClient.js +2 -1
  109. package/dist/modules/messages/components/MessagesInboxPageClient.js.map +2 -2
  110. package/dist/modules/messages/extension-points.js +16 -0
  111. package/dist/modules/messages/extension-points.js.map +7 -0
  112. package/dist/modules/payment_gateways/backend/payment-gateways/page.js +3 -2
  113. package/dist/modules/payment_gateways/backend/payment-gateways/page.js.map +2 -2
  114. package/dist/modules/payment_gateways/extension-points.js +19 -0
  115. package/dist/modules/payment_gateways/extension-points.js.map +7 -0
  116. package/dist/modules/portal/extension-points.js +32 -0
  117. package/dist/modules/portal/extension-points.js.map +7 -0
  118. package/dist/modules/portal/frontend/[orgSlug]/portal/dashboard/page.js +3 -3
  119. package/dist/modules/portal/frontend/[orgSlug]/portal/dashboard/page.js.map +2 -2
  120. package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js +3 -3
  121. package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js.map +2 -2
  122. package/dist/modules/portal/frontend/[orgSlug]/portal/page.js +3 -3
  123. package/dist/modules/portal/frontend/[orgSlug]/portal/page.js.map +2 -2
  124. package/dist/modules/portal/frontend/[orgSlug]/portal/profile/page.js +3 -3
  125. package/dist/modules/portal/frontend/[orgSlug]/portal/profile/page.js.map +2 -2
  126. package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.js +3 -3
  127. package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.js.map +2 -2
  128. package/dist/modules/portal/frontend/[orgSlug]/portal/signup/page.js +3 -3
  129. package/dist/modules/portal/frontend/[orgSlug]/portal/signup/page.js.map +2 -2
  130. package/dist/modules/query_index/components/QueryIndexesTable.js +2 -1
  131. package/dist/modules/query_index/components/QueryIndexesTable.js.map +2 -2
  132. package/dist/modules/query_index/events.js +20 -0
  133. package/dist/modules/query_index/events.js.map +7 -0
  134. package/dist/modules/query_index/extension-points.js +13 -0
  135. package/dist/modules/query_index/extension-points.js.map +7 -0
  136. package/dist/modules/resources/backend/resources/resource-types/page.js +2 -1
  137. package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
  138. package/dist/modules/resources/backend/resources/resources/page.js +2 -1
  139. package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
  140. package/dist/modules/resources/extension-points.js +14 -0
  141. package/dist/modules/resources/extension-points.js.map +7 -0
  142. package/dist/modules/sales/backend/sales/documents/[id]/page.js +11 -3
  143. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  144. package/dist/modules/sales/components/documents/ItemsSection.js +2 -1
  145. package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
  146. package/dist/modules/sales/components/documents/SalesDocumentsTable.js +4 -1
  147. package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
  148. package/dist/modules/sales/events.js +1 -0
  149. package/dist/modules/sales/events.js.map +2 -2
  150. package/dist/modules/sales/extension-points.js +36 -0
  151. package/dist/modules/sales/extension-points.js.map +7 -0
  152. package/dist/modules/wms/components/backend/WmsConfigurationPage.js +5 -4
  153. package/dist/modules/wms/components/backend/WmsConfigurationPage.js.map +2 -2
  154. package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js +4 -3
  155. package/dist/modules/wms/components/backend/WmsInventoryConsolePage.js.map +2 -2
  156. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js +3 -2
  157. package/dist/modules/wms/components/backend/WmsLocationDetailPage.js.map +2 -2
  158. package/dist/modules/wms/components/backend/WmsLotDetailPage.js +3 -2
  159. package/dist/modules/wms/components/backend/WmsLotDetailPage.js.map +2 -2
  160. package/dist/modules/wms/components/backend/WmsLotsListPage.js +2 -1
  161. package/dist/modules/wms/components/backend/WmsLotsListPage.js.map +2 -2
  162. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js +3 -2
  163. package/dist/modules/wms/components/backend/WmsSkuDetailPage.js.map +2 -2
  164. package/dist/modules/wms/extension-points.js +26 -0
  165. package/dist/modules/wms/extension-points.js.map +7 -0
  166. package/dist/modules/workflows/backend/definitions/page.js +2 -1
  167. package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
  168. package/dist/modules/workflows/backend/instances/page.js +2 -1
  169. package/dist/modules/workflows/backend/instances/page.js.map +2 -2
  170. package/dist/modules/workflows/backend/tasks/page.js +2 -1
  171. package/dist/modules/workflows/backend/tasks/page.js.map +2 -2
  172. package/dist/modules/workflows/events.js +1 -0
  173. package/dist/modules/workflows/events.js.map +2 -2
  174. package/dist/modules/workflows/extension-points.js +15 -0
  175. package/dist/modules/workflows/extension-points.js.map +7 -0
  176. package/package.json +7 -7
  177. package/src/modules/api_keys/backend/api-keys/page.tsx +2 -1
  178. package/src/modules/api_keys/extension-points.ts +13 -0
  179. package/src/modules/audit_logs/components/AccessLogsTable.tsx +2 -1
  180. package/src/modules/audit_logs/components/AuditLogsActions.tsx +2 -1
  181. package/src/modules/audit_logs/extension-points.ts +11 -0
  182. package/src/modules/auth/backend/roles/page.tsx +2 -1
  183. package/src/modules/auth/backend/users/page.tsx +2 -1
  184. package/src/modules/auth/extension-points.ts +18 -0
  185. package/src/modules/auth/frontend/login.tsx +2 -1
  186. package/src/modules/business_rules/backend/rules/page.tsx +2 -1
  187. package/src/modules/business_rules/events.ts +10 -0
  188. package/src/modules/business_rules/extension-points.ts +10 -0
  189. package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +2 -1
  190. package/src/modules/catalog/backend/catalog/products/create/page.tsx +2 -1
  191. package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +2 -1
  192. package/src/modules/catalog/components/products/ProductsDataTable.tsx +3 -2
  193. package/src/modules/catalog/events.ts +1 -0
  194. package/src/modules/catalog/extension-points.ts +24 -0
  195. package/src/modules/communication_channels/backend/communication_channels/channels/page.tsx +2 -1
  196. package/src/modules/communication_channels/backend/profile/communication-channels/page.tsx +3 -2
  197. package/src/modules/communication_channels/extension-points.ts +17 -0
  198. package/src/modules/configs/backend/config/system-status/page.tsx +2 -1
  199. package/src/modules/configs/extension-points.ts +15 -0
  200. package/src/modules/currencies/backend/currencies/page.tsx +2 -1
  201. package/src/modules/currencies/backend/exchange-rates/page.tsx +2 -1
  202. package/src/modules/currencies/extension-points.ts +11 -0
  203. package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +2 -1
  204. package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +2 -1
  205. package/src/modules/customer_accounts/extension-points.ts +11 -0
  206. package/src/modules/customers/backend/customers/companies/[id]/page.tsx +2 -1
  207. package/src/modules/customers/backend/customers/companies/page.tsx +2 -1
  208. package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +5 -4
  209. package/src/modules/customers/backend/customers/deals/[id]/page.tsx +5 -4
  210. package/src/modules/customers/backend/customers/deals/page.tsx +2 -1
  211. package/src/modules/customers/backend/customers/people/[id]/page.tsx +2 -1
  212. package/src/modules/customers/backend/customers/people/page.tsx +2 -1
  213. package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +5 -4
  214. package/src/modules/customers/components/CustomerTodosTable.tsx +2 -1
  215. package/src/modules/customers/extension-points.ts +40 -0
  216. package/src/modules/customers/lib/calendar/format.ts +10 -4
  217. package/src/modules/data_sync/backend/data-sync/page.tsx +2 -1
  218. package/src/modules/data_sync/extension-points.ts +10 -0
  219. package/src/modules/directory/backend/directory/organizations/page.tsx +2 -1
  220. package/src/modules/directory/backend/directory/tenants/page.tsx +2 -1
  221. package/src/modules/directory/extension-points.ts +11 -0
  222. package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +5 -1
  223. package/src/modules/entities/components/SystemEntitiesTable.tsx +2 -1
  224. package/src/modules/entities/components/UserEntitiesTable.tsx +2 -1
  225. package/src/modules/entities/extension-points.ts +18 -0
  226. package/src/modules/integrations/backend/integrations/[id]/page.tsx +2 -2
  227. package/src/modules/integrations/extension-points.ts +27 -0
  228. package/src/modules/messages/components/ComposeMessagePageClient.tsx +2 -1
  229. package/src/modules/messages/components/MessageDetailPageClient.tsx +3 -2
  230. package/src/modules/messages/components/MessagesInboxPageClient.tsx +2 -1
  231. package/src/modules/messages/extension-points.ts +13 -0
  232. package/src/modules/payment_gateways/backend/payment-gateways/page.tsx +3 -2
  233. package/src/modules/payment_gateways/extension-points.ts +16 -0
  234. package/src/modules/portal/extension-points.ts +30 -0
  235. package/src/modules/portal/frontend/[orgSlug]/portal/dashboard/page.tsx +3 -3
  236. package/src/modules/portal/frontend/[orgSlug]/portal/login/page.tsx +3 -3
  237. package/src/modules/portal/frontend/[orgSlug]/portal/page.tsx +3 -3
  238. package/src/modules/portal/frontend/[orgSlug]/portal/profile/page.tsx +3 -3
  239. package/src/modules/portal/frontend/[orgSlug]/portal/reset-password/page.tsx +4 -4
  240. package/src/modules/portal/frontend/[orgSlug]/portal/signup/page.tsx +3 -3
  241. package/src/modules/query_index/components/QueryIndexesTable.tsx +2 -1
  242. package/src/modules/query_index/events.ts +17 -0
  243. package/src/modules/query_index/extension-points.ts +10 -0
  244. package/src/modules/resources/backend/resources/resource-types/page.tsx +2 -1
  245. package/src/modules/resources/backend/resources/resources/page.tsx +2 -1
  246. package/src/modules/resources/extension-points.ts +11 -0
  247. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +11 -3
  248. package/src/modules/sales/components/documents/ItemsSection.tsx +2 -1
  249. package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +6 -1
  250. package/src/modules/sales/events.ts +1 -0
  251. package/src/modules/sales/extension-points.ts +33 -0
  252. package/src/modules/wms/components/backend/WmsConfigurationPage.tsx +5 -4
  253. package/src/modules/wms/components/backend/WmsInventoryConsolePage.tsx +4 -3
  254. package/src/modules/wms/components/backend/WmsLocationDetailPage.tsx +3 -2
  255. package/src/modules/wms/components/backend/WmsLotDetailPage.tsx +3 -2
  256. package/src/modules/wms/components/backend/WmsLotsListPage.tsx +2 -1
  257. package/src/modules/wms/components/backend/WmsSkuDetailPage.tsx +3 -2
  258. package/src/modules/wms/extension-points.ts +23 -0
  259. package/src/modules/workflows/backend/definitions/page.tsx +2 -1
  260. package/src/modules/workflows/backend/instances/page.tsx +2 -1
  261. package/src/modules/workflows/backend/tasks/page.tsx +2 -1
  262. package/src/modules/workflows/events.ts +1 -0
  263. package/src/modules/workflows/extension-points.ts +12 -0
@@ -1,6 +1,7 @@
1
1
 
2
2
  "use client"
3
3
  import * as React from 'react'
4
+ import { extensionPoints } from '@open-mercato/core/modules/entities/extension-points'
4
5
  import Link from 'next/link'
5
6
  import { useQuery } from '@tanstack/react-query'
6
7
  import type { ColumnDef, SortingState } from '@tanstack/react-table'
@@ -96,7 +97,7 @@ export default function UserEntitiesTable() {
96
97
  sortable
97
98
  sorting={sorting}
98
99
  onSortingChange={setSorting}
99
- perspective={{ tableId: 'entities.user.list' }}
100
+ perspective={{ tableId: extensionPoints.hosts.userEntitiesTable.tableId }}
100
101
  emptyState={(
101
102
  <ListEmptyState
102
103
  entityName={t('entities.user.table.title', 'User Entities')}
@@ -0,0 +1,18 @@
1
+ import { dataTableExtensionHost, defineModuleExtensionPoints, injectionExtensionHost } from '@open-mercato/shared/modules/widgets/extension-points'
2
+
3
+ export const extensionPoints = defineModuleExtensionPoints({
4
+ moduleId: 'entities',
5
+ hosts: {
6
+ systemEntitiesTable: dataTableExtensionHost({ tableId: 'entities.system.list', source: 'components/SystemEntitiesTable.tsx' }),
7
+ userEntitiesTable: dataTableExtensionHost({ tableId: 'entities.user.list', source: 'components/UserEntitiesTable.tsx' }),
8
+ userRecordsTable: injectionExtensionHost({
9
+ family: 'entity',
10
+ pattern: 'data-table:entities.user.records.{entityId}',
11
+ parameters: { entityId: { source: 'route.params.entityId' } },
12
+ supported: ['render-widget', 'headless-widget', 'column-widget', 'row-action', 'bulk-action', 'filter-widget'],
13
+ source: 'backend/entities/user/[entityId]/records/page.tsx',
14
+ }),
15
+ },
16
+ })
17
+
18
+ export default extensionPoints
@@ -1,5 +1,6 @@
1
1
  "use client"
2
2
  import * as React from 'react'
3
+ import { extensionPoints } from '@open-mercato/core/modules/integrations/extension-points'
3
4
  import { usePathname, useRouter, useSearchParams } from 'next/navigation'
4
5
  import { z } from 'zod'
5
6
  import { Page, PageBody } from '@open-mercato/ui/backend/Page'
@@ -31,7 +32,6 @@ import { raiseCrudError } from '@open-mercato/ui/backend/utils/serverErrors'
31
32
  import { useT } from '@open-mercato/shared/lib/i18n/context'
32
33
  import { cn } from '@open-mercato/shared/lib/utils'
33
34
  import {
34
- LEGACY_INTEGRATION_DETAIL_TABS_SPOT_ID,
35
35
  type CredentialFieldType,
36
36
  type IntegrationCredentialField,
37
37
  type IntegrationDetailBuiltInTab,
@@ -530,7 +530,7 @@ export default function IntegrationDetailPage({ params }: IntegrationDetailPageP
530
530
  }, [logLevel, resolveCurrentIntegrationId])
531
531
 
532
532
  const detailWidgetSpotId = React.useMemo(
533
- () => resolveIntegrationDetailWidgetSpotId(detail?.integration ?? null, LEGACY_INTEGRATION_DETAIL_TABS_SPOT_ID),
533
+ () => resolveIntegrationDetailWidgetSpotId(detail?.integration ?? null, extensionPoints.hosts.legacyDetailTabs.spotId),
534
534
  [detail?.integration],
535
535
  )
536
536
  const mutationContextId = React.useMemo(
@@ -0,0 +1,27 @@
1
+ import { defineModuleExtensionPoints, injectionExtensionHost } from '@open-mercato/shared/modules/widgets/extension-points'
2
+
3
+ export const extensionPoints = defineModuleExtensionPoints({
4
+ moduleId: 'integrations',
5
+ hosts: {
6
+ detail: injectionExtensionHost({
7
+ family: 'integration',
8
+ pattern: 'integrations.detail:{integrationId}',
9
+ parameters: {
10
+ integrationId: { source: 'IntegrationDefinition.id', pattern: '^[a-z0-9_]+$' },
11
+ },
12
+ fallbacks: ['integrations.detail:tabs'],
13
+ supported: ['render-widget'],
14
+ contextContract: 'integrations.detail.v1',
15
+ source: 'backend/integrations/[id]/page.tsx',
16
+ }),
17
+ legacyDetailTabs: injectionExtensionHost({
18
+ family: 'integration',
19
+ spotId: 'integrations.detail:tabs',
20
+ supported: ['render-widget'],
21
+ contextContract: 'integrations.detail.v1',
22
+ source: 'backend/integrations/[id]/page.tsx',
23
+ }),
24
+ },
25
+ })
26
+
27
+ export default extensionPoints
@@ -1,6 +1,7 @@
1
1
  "use client"
2
2
 
3
3
  import { useRouter } from 'next/navigation'
4
+ import { extensionPoints } from '@open-mercato/core/modules/messages/extension-points'
4
5
  import { MessageComposer } from '@open-mercato/ui/backend/messages'
5
6
  // UMES extension surface — compose page injection spot (SPEC-045d §9.3a).
6
7
  // Channel provider packages inject "composer capabilities" widgets here
@@ -21,7 +22,7 @@ export function ComposeMessagePageClient() {
21
22
  scoping) into this spot purely as additional UI siblings.
22
23
  */}
23
24
  <InjectionSpot
24
- spotId="crud-form:messages:message:fields"
25
+ spotId={extensionPoints.hosts.composeFields.spotId}
25
26
  context={{ form: 'compose' }}
26
27
  data={{}}
27
28
  />
@@ -1,6 +1,7 @@
1
1
  "use client"
2
2
 
3
3
  import * as React from 'react'
4
+ import { extensionPoints } from '@open-mercato/core/modules/messages/extension-points'
4
5
  import { MessageComposer } from '@open-mercato/ui/backend/messages'
5
6
  import { apiCall } from '@open-mercato/ui/backend/utils/apiCall'
6
7
  import { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'
@@ -94,7 +95,7 @@ function MessageConversationDetailItem({
94
95
 
95
96
  {/* UMES — channel payload renderer mounts here (channel-linked emails, Slack blocks, etc.). */}
96
97
  <InjectionSpot
97
- spotId="detail:messages:message:body:after"
98
+ spotId={extensionPoints.hosts.detailBodyAfter.spotId}
98
99
  context={{ messageId }}
99
100
  data={state.detail}
100
101
  />
@@ -105,7 +106,7 @@ function MessageConversationDetailItem({
105
106
  `userFeatures` lets feature-gated widgets (e.g. the channel reassignment editor,
106
107
  gated on `communication_channels.assign`) render their controls for permitted users. */}
107
108
  <InjectionSpot
108
- spotId="detail:messages:message:sidebar"
109
+ spotId={extensionPoints.hosts.detailSidebar.spotId}
109
110
  context={{ messageId, userFeatures }}
110
111
  data={state.detail}
111
112
  />
@@ -1,6 +1,7 @@
1
1
  "use client"
2
2
 
3
3
  import * as React from 'react'
4
+ import { extensionPoints } from '@open-mercato/core/modules/messages/extension-points'
4
5
  import Link from 'next/link'
5
6
  import { useRouter } from 'next/navigation'
6
7
  import { useQuery, useQueryClient } from '@tanstack/react-query'
@@ -369,7 +370,7 @@ export function MessagesInboxPageClient() {
369
370
  // UMES extension surface — opt into widget injection at:
370
371
  // data-table:messages:columns / :row-actions / :bulk-actions / :filters / :toolbar / :search-trailing
371
372
  // (SPEC-045d §9.3a — communication_channels hub renders channel badge + delivery status here)
372
- extensionTableId="messages"
373
+ extensionTableId={extensionPoints.hosts.inboxTable.tableId}
373
374
  columns={columns}
374
375
  data={rows}
375
376
  bulkActions={bulkActions}
@@ -0,0 +1,13 @@
1
+ import { dataTableExtensionHost, defineModuleExtensionPoints, injectionExtensionHost } from '@open-mercato/shared/modules/widgets/extension-points'
2
+
3
+ export const extensionPoints = defineModuleExtensionPoints({
4
+ moduleId: 'messages',
5
+ hosts: {
6
+ inboxTable: dataTableExtensionHost({ tableId: 'messages', source: 'components/MessagesInboxPageClient.tsx' }),
7
+ composeFields: injectionExtensionHost({ family: 'generic', spotId: 'crud-form:messages:message:fields', supported: ['render-widget'], source: 'components/ComposeMessagePageClient.tsx' }),
8
+ detailBodyAfter: injectionExtensionHost({ family: 'detail', spotId: 'detail:messages:message:body:after', supported: ['render-widget'], source: 'components/MessageDetailPageClient.tsx' }),
9
+ detailSidebar: injectionExtensionHost({ family: 'detail', spotId: 'detail:messages:message:sidebar', supported: ['render-widget'], source: 'components/MessageDetailPageClient.tsx' }),
10
+ },
11
+ })
12
+
13
+ export default extensionPoints
@@ -1,5 +1,6 @@
1
1
  "use client"
2
2
  import * as React from 'react'
3
+ import { extensionPoints } from '@open-mercato/core/modules/payment_gateways/extension-points'
3
4
  import { useSearchParams } from 'next/navigation'
4
5
  import type { ColumnDef } from '@tanstack/react-table'
5
6
  import type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'
@@ -472,7 +473,7 @@ export default function PaymentTransactionsPage() {
472
473
  searchValue={search}
473
474
  onSearchChange={(value) => { setSearch(value); setPage(1) }}
474
475
  searchPlaceholder={t('payment_gateways.transactions.searchPlaceholder', 'Search by payment, transaction, session, or gateway id')}
475
- perspective={{ tableId: 'payment_gateways.transactions.list' }}
476
+ perspective={{ tableId: extensionPoints.hosts.transactionsTable.tableId }}
476
477
  pagination={{ page, pageSize: 20, total, totalPages, onPageChange: setPage }}
477
478
  isLoading={isLoading}
478
479
  onRowClick={(row) => setSelectedId((current) => current === row.id ? null : row.id)}
@@ -691,7 +692,7 @@ export default function PaymentTransactionsPage() {
691
692
  className="p-4"
692
693
  />
693
694
  <InjectionSpot
694
- spotId="admin.page:payment-gateways/transactions:after"
695
+ spotId={extensionPoints.hosts.transactionsAfter.spotId}
695
696
  context={{ selectedPaymentId: detail.transaction.paymentId }}
696
697
  />
697
698
  </div>
@@ -0,0 +1,16 @@
1
+ import { dataTableExtensionHost, defineModuleExtensionPoints, injectionExtensionHost } from '@open-mercato/shared/modules/widgets/extension-points'
2
+
3
+ export const extensionPoints = defineModuleExtensionPoints({
4
+ moduleId: 'payment_gateways',
5
+ hosts: {
6
+ transactionsTable: dataTableExtensionHost({ tableId: 'payment_gateways.transactions.list', source: 'backend/payment-gateways/page.tsx' }),
7
+ transactionsAfter: injectionExtensionHost({
8
+ family: 'detail',
9
+ spotId: 'admin.page:payment-gateways/transactions:after',
10
+ supported: ['render-widget'],
11
+ source: 'backend/payment-gateways/page.tsx',
12
+ }),
13
+ },
14
+ })
15
+
16
+ export default extensionPoints
@@ -0,0 +1,30 @@
1
+ import { defineModuleExtensionPoints, injectionExtensionHost } from '@open-mercato/shared/modules/widgets/extension-points'
2
+
3
+ const portalPageHost = (spotId: string, source: string) => injectionExtensionHost({
4
+ family: 'portal-page',
5
+ spotId,
6
+ supported: ['render-widget'],
7
+ contextContract: 'portal.page.v1',
8
+ scopeContract: 'tenant.organization.customer-session',
9
+ source,
10
+ })
11
+
12
+ export const extensionPoints = defineModuleExtensionPoints({
13
+ moduleId: 'portal',
14
+ hosts: {
15
+ dashboardBefore: portalPageHost('portal:dashboard:before', 'frontend/[orgSlug]/portal/dashboard/page.tsx'),
16
+ dashboardAfter: portalPageHost('portal:dashboard:after', 'frontend/[orgSlug]/portal/dashboard/page.tsx'),
17
+ loginBefore: portalPageHost('portal:login:before', 'frontend/[orgSlug]/portal/login/page.tsx'),
18
+ loginAfter: portalPageHost('portal:login:after', 'frontend/[orgSlug]/portal/login/page.tsx'),
19
+ homeBefore: portalPageHost('portal:home:before', 'frontend/[orgSlug]/portal/page.tsx'),
20
+ homeAfter: portalPageHost('portal:home:after', 'frontend/[orgSlug]/portal/page.tsx'),
21
+ profileBefore: portalPageHost('portal:profile:before', 'frontend/[orgSlug]/portal/profile/page.tsx'),
22
+ profileAfter: portalPageHost('portal:profile:after', 'frontend/[orgSlug]/portal/profile/page.tsx'),
23
+ resetPasswordBefore: portalPageHost('portal:reset-password:before', 'frontend/[orgSlug]/portal/reset-password/page.tsx'),
24
+ resetPasswordAfter: portalPageHost('portal:reset-password:after', 'frontend/[orgSlug]/portal/reset-password/page.tsx'),
25
+ signupBefore: portalPageHost('portal:signup:before', 'frontend/[orgSlug]/portal/signup/page.tsx'),
26
+ signupAfter: portalPageHost('portal:signup:after', 'frontend/[orgSlug]/portal/signup/page.tsx'),
27
+ },
28
+ })
29
+
30
+ export default extensionPoints
@@ -1,5 +1,6 @@
1
1
  "use client"
2
2
  import React, { useEffect, useMemo, useState, useCallback } from 'react'
3
+ import { extensionPoints } from '@open-mercato/core/modules/portal/extension-points'
3
4
  import { useRouter } from 'next/navigation'
4
5
  import { useT } from '@open-mercato/shared/lib/i18n/context'
5
6
  import { Button } from '@open-mercato/ui/primitives/button'
@@ -10,7 +11,6 @@ import { PortalCard, PortalCardHeader } from '@open-mercato/ui/portal/components
10
11
  import { PortalEmptyState } from '@open-mercato/ui/portal/components/PortalEmptyState'
11
12
  import { usePortalDashboardWidgets } from '@open-mercato/ui/portal/hooks/usePortalDashboardWidgets'
12
13
  import { InjectionSpot } from '@open-mercato/ui/backend/injection/InjectionSpot'
13
- import { PortalInjectionSpots } from '@open-mercato/ui/backend/injection/spotIds'
14
14
  import {
15
15
  loadHiddenWidgets,
16
16
  saveHiddenWidgets,
@@ -107,7 +107,7 @@ export default function PortalDashboardPage({ params }: Props) {
107
107
  }
108
108
  />
109
109
 
110
- <InjectionSpot spotId={PortalInjectionSpots.pageBefore('dashboard')} context={injectionContext} />
110
+ <InjectionSpot spotId={extensionPoints.hosts.dashboardBefore.spotId} context={injectionContext} />
111
111
 
112
112
  {editing && dashboardWidgets.length > 0 ? (
113
113
  <PortalCard>
@@ -151,7 +151,7 @@ export default function PortalDashboardPage({ params }: Props) {
151
151
  />
152
152
  ) : null}
153
153
 
154
- <InjectionSpot spotId={PortalInjectionSpots.pageAfter('dashboard')} context={injectionContext} />
154
+ <InjectionSpot spotId={extensionPoints.hosts.dashboardAfter.spotId} context={injectionContext} />
155
155
  </div>
156
156
  )
157
157
  }
@@ -1,5 +1,6 @@
1
1
  "use client"
2
2
  import { useCallback, useMemo, useState } from 'react'
3
+ import { extensionPoints } from '@open-mercato/core/modules/portal/extension-points'
3
4
  import Link from 'next/link'
4
5
  import { useT } from '@open-mercato/shared/lib/i18n/context'
5
6
  import { EmailInput } from '@open-mercato/ui/primitives/email-input'
@@ -13,7 +14,6 @@ import { Spinner } from '@open-mercato/ui/primitives/spinner'
13
14
  import { apiCall } from '@open-mercato/ui/backend/utils/apiCall'
14
15
  import { usePortalContext } from '@open-mercato/ui/portal/PortalContext'
15
16
  import { InjectionSpot } from '@open-mercato/ui/backend/injection/InjectionSpot'
16
- import { PortalInjectionSpots } from '@open-mercato/ui/backend/injection/spotIds'
17
17
 
18
18
  type Props = { params: { orgSlug: string } }
19
19
 
@@ -97,7 +97,7 @@ export default function PortalLoginPage({ params }: Props) {
97
97
  <p className="mt-1.5 text-sm text-muted-foreground">{t('portal.login.description', 'Enter your credentials to access the portal.')}</p>
98
98
  </div>
99
99
 
100
- <InjectionSpot spotId={PortalInjectionSpots.pageBefore('login')} context={injectionContext} />
100
+ <InjectionSpot spotId={extensionPoints.hosts.loginBefore.spotId} context={injectionContext} />
101
101
 
102
102
  <form onSubmit={handleSubmit} className="flex flex-col gap-4">
103
103
  {error ? (
@@ -128,7 +128,7 @@ export default function PortalLoginPage({ params }: Props) {
128
128
  </p>
129
129
  </form>
130
130
 
131
- <InjectionSpot spotId={PortalInjectionSpots.pageAfter('login')} context={injectionContext} />
131
+ <InjectionSpot spotId={extensionPoints.hosts.loginAfter.spotId} context={injectionContext} />
132
132
  </div>
133
133
  )
134
134
  }
@@ -1,5 +1,6 @@
1
1
  "use client"
2
2
  import { useEffect, useMemo } from 'react'
3
+ import { extensionPoints } from '@open-mercato/core/modules/portal/extension-points'
3
4
  import Link from 'next/link'
4
5
  import { useRouter } from 'next/navigation'
5
6
  import { useT } from '@open-mercato/shared/lib/i18n/context'
@@ -10,7 +11,6 @@ import { SearchX, ShoppingBag, User, Shield } from 'lucide-react'
10
11
  import { usePortalContext } from '@open-mercato/ui/portal/PortalContext'
11
12
  import { PortalFeatureCard } from '@open-mercato/ui/portal/components/PortalFeatureCard'
12
13
  import { InjectionSpot } from '@open-mercato/ui/backend/injection/InjectionSpot'
13
- import { PortalInjectionSpots } from '@open-mercato/ui/backend/injection/spotIds'
14
14
 
15
15
  type Props = { params: { orgSlug: string } }
16
16
 
@@ -54,7 +54,7 @@ export default function PortalLandingPage({ params }: Props) {
54
54
 
55
55
  return (
56
56
  <>
57
- <InjectionSpot spotId={PortalInjectionSpots.pageBefore('home')} context={injectionContext} />
57
+ <InjectionSpot spotId={extensionPoints.hosts.homeBefore.spotId} context={injectionContext} />
58
58
 
59
59
  <section className="flex flex-col items-center gap-5 py-8 text-center sm:py-16">
60
60
  <p className="text-overline font-semibold uppercase tracking-widest text-muted-foreground/60">
@@ -94,7 +94,7 @@ export default function PortalLandingPage({ params }: Props) {
94
94
  />
95
95
  </section>
96
96
 
97
- <InjectionSpot spotId={PortalInjectionSpots.pageAfter('home')} context={injectionContext} />
97
+ <InjectionSpot spotId={extensionPoints.hosts.homeAfter.spotId} context={injectionContext} />
98
98
  </>
99
99
  )
100
100
  }
@@ -1,5 +1,6 @@
1
1
  "use client"
2
2
  import { useEffect, useMemo } from 'react'
3
+ import { extensionPoints } from '@open-mercato/core/modules/portal/extension-points'
3
4
  import { useRouter } from 'next/navigation'
4
5
  import { useT } from '@open-mercato/shared/lib/i18n/context'
5
6
  import { Badge } from '@open-mercato/ui/primitives/badge'
@@ -8,7 +9,6 @@ import { usePortalContext } from '@open-mercato/ui/portal/PortalContext'
8
9
  import { PortalPageHeader } from '@open-mercato/ui/portal/components/PortalPageHeader'
9
10
  import { PortalCard, PortalCardHeader, PortalStatRow, PortalCardDivider } from '@open-mercato/ui/portal/components/PortalCard'
10
11
  import { InjectionSpot } from '@open-mercato/ui/backend/injection/InjectionSpot'
11
- import { PortalInjectionSpots } from '@open-mercato/ui/backend/injection/spotIds'
12
12
 
13
13
  type Props = { params: { orgSlug: string } }
14
14
 
@@ -49,7 +49,7 @@ export default function PortalProfilePage({ params }: Props) {
49
49
  title={t('portal.profile.title', 'Profile')}
50
50
  />
51
51
 
52
- <InjectionSpot spotId={PortalInjectionSpots.pageBefore('profile')} context={injectionContext} />
52
+ <InjectionSpot spotId={extensionPoints.hosts.profileBefore.spotId} context={injectionContext} />
53
53
 
54
54
  <div className="grid gap-5 md:grid-cols-2">
55
55
  <PortalCard>
@@ -106,7 +106,7 @@ export default function PortalProfilePage({ params }: Props) {
106
106
  </PortalCard>
107
107
  </div>
108
108
 
109
- <InjectionSpot spotId={PortalInjectionSpots.pageAfter('profile')} context={injectionContext} />
109
+ <InjectionSpot spotId={extensionPoints.hosts.profileAfter.spotId} context={injectionContext} />
110
110
  </div>
111
111
  )
112
112
  }
@@ -1,5 +1,6 @@
1
1
  "use client"
2
2
  import { useCallback, useMemo, useState, useEffect } from 'react'
3
+ import { extensionPoints } from '@open-mercato/core/modules/portal/extension-points'
3
4
  import { useSearchParams } from 'next/navigation'
4
5
  import Link from 'next/link'
5
6
  import { useT } from '@open-mercato/shared/lib/i18n/context'
@@ -13,7 +14,6 @@ import { Spinner } from '@open-mercato/ui/primitives/spinner'
13
14
  import { apiCall } from '@open-mercato/ui/backend/utils/apiCall'
14
15
  import { usePortalContext } from '@open-mercato/ui/portal/PortalContext'
15
16
  import { InjectionSpot } from '@open-mercato/ui/backend/injection/InjectionSpot'
16
- import { PortalInjectionSpots } from '@open-mercato/ui/backend/injection/spotIds'
17
17
 
18
18
  type Props = { params: { orgSlug: string } }
19
19
 
@@ -136,7 +136,7 @@ export default function PortalResetPasswordPage({ params }: Props) {
136
136
  <p className="mt-1.5 text-sm text-muted-foreground">{t('portal.resetPassword.description', 'Enter your new password below.')}</p>
137
137
  </div>
138
138
 
139
- <InjectionSpot spotId={PortalInjectionSpots.pageBefore('reset-password')} context={injectionContext} />
139
+ <InjectionSpot spotId={extensionPoints.hosts.resetPasswordBefore.spotId} context={injectionContext} />
140
140
 
141
141
  <form onSubmit={handleSubmit} className="flex flex-col gap-4">
142
142
  {error ? (
@@ -167,7 +167,7 @@ export default function PortalResetPasswordPage({ params }: Props) {
167
167
  </p>
168
168
  </form>
169
169
 
170
- <InjectionSpot spotId={PortalInjectionSpots.pageAfter('reset-password')} context={injectionContext} />
170
+ <InjectionSpot spotId={extensionPoints.hosts.resetPasswordAfter.spotId} context={injectionContext} />
171
171
  </div>
172
172
  )
173
- }
173
+ }
@@ -1,5 +1,6 @@
1
1
  "use client"
2
2
  import { useCallback, useMemo, useState } from 'react'
3
+ import { extensionPoints } from '@open-mercato/core/modules/portal/extension-points'
3
4
  import Link from 'next/link'
4
5
  import { useT } from '@open-mercato/shared/lib/i18n/context'
5
6
  import { Input } from '@open-mercato/ui/primitives/input'
@@ -14,7 +15,6 @@ import { Spinner } from '@open-mercato/ui/primitives/spinner'
14
15
  import { apiCall } from '@open-mercato/ui/backend/utils/apiCall'
15
16
  import { usePortalContext } from '@open-mercato/ui/portal/PortalContext'
16
17
  import { InjectionSpot } from '@open-mercato/ui/backend/injection/InjectionSpot'
17
- import { PortalInjectionSpots } from '@open-mercato/ui/backend/injection/spotIds'
18
18
 
19
19
  type Props = { params: { orgSlug: string } }
20
20
  type SignupResponse = { ok: boolean; error?: string; details?: Record<string, string[]> }
@@ -134,7 +134,7 @@ export default function PortalSignupPage({ params }: Props) {
134
134
  <p className="mt-1.5 text-sm text-muted-foreground">{t('portal.signup.description', 'Sign up for a portal account.')}</p>
135
135
  </div>
136
136
 
137
- <InjectionSpot spotId={PortalInjectionSpots.pageBefore('signup')} context={injectionContext} />
137
+ <InjectionSpot spotId={extensionPoints.hosts.signupBefore.spotId} context={injectionContext} />
138
138
 
139
139
  <form onSubmit={handleSubmit} className="flex flex-col gap-4">
140
140
  {error ? (
@@ -173,7 +173,7 @@ export default function PortalSignupPage({ params }: Props) {
173
173
  </p>
174
174
  </form>
175
175
 
176
- <InjectionSpot spotId={PortalInjectionSpots.pageAfter('signup')} context={injectionContext} />
176
+ <InjectionSpot spotId={extensionPoints.hosts.signupAfter.spotId} context={injectionContext} />
177
177
  </div>
178
178
  )
179
179
  }
@@ -1,5 +1,6 @@
1
1
  "use client"
2
2
  import * as React from 'react'
3
+ import { extensionPoints } from '@open-mercato/core/modules/query_index/extension-points'
3
4
  import { useQuery, useQueryClient } from '@tanstack/react-query'
4
5
  import type { ColumnDef, SortingState } from '@tanstack/react-table'
5
6
  import { DataTable } from '@open-mercato/ui/backend/DataTable'
@@ -563,7 +564,7 @@ export default function QueryIndexesTable() {
563
564
  setSorting(next)
564
565
  setPage(1)
565
566
  }}
566
- perspective={{ tableId: 'query_index.status.list' }}
567
+ perspective={{ tableId: extensionPoints.hosts.statusTable.tableId }}
567
568
  rowActions={(row) => {
568
569
  const items: Array<{ id: string; label: string; onSelect: () => void; destructive?: boolean }> = [
569
570
  { id: 'reindex', label: t('query_index.table.actions.reindex'), onSelect: () => void trigger('reindex', row.entityId) },
@@ -0,0 +1,17 @@
1
+ import { createModuleEvents } from '@open-mercato/shared/modules/events'
2
+
3
+ const events = [
4
+ { id: 'query_index.coverage.refresh', label: 'Coverage Refresh', category: 'lifecycle' },
5
+ { id: 'query_index.coverage.warmup', label: 'Coverage Warmup', category: 'lifecycle' },
6
+ { id: 'query_index.delete_one', label: 'Delete One', category: 'lifecycle' },
7
+ { id: 'query_index.purge', label: 'Purge', category: 'lifecycle' },
8
+ { id: 'query_index.reindex', label: 'Reindex', category: 'lifecycle' },
9
+ { id: 'query_index.upsert_one', label: 'Upsert One', category: 'lifecycle' },
10
+ { id: 'query_index.vectorize_one', label: 'Vectorize One', category: 'lifecycle' },
11
+ { id: 'query_index.vectorize_purge', label: 'Vectorize Purge', category: 'lifecycle' },
12
+ ] as const
13
+
14
+ export const eventsConfig = createModuleEvents({ moduleId: 'query_index', events })
15
+ export const emitQueryIndexEvent = eventsConfig.emit
16
+ export type QueryIndexEventId = typeof events[number]['id']
17
+ export default eventsConfig
@@ -0,0 +1,10 @@
1
+ import { dataTableExtensionHost, defineModuleExtensionPoints } from '@open-mercato/shared/modules/widgets/extension-points'
2
+
3
+ export const extensionPoints = defineModuleExtensionPoints({
4
+ moduleId: 'query_index',
5
+ hosts: {
6
+ statusTable: dataTableExtensionHost({ tableId: 'query_index.status.list', source: 'components/QueryIndexesTable.tsx' }),
7
+ },
8
+ })
9
+
10
+ export default extensionPoints
@@ -1,6 +1,7 @@
1
1
  "use client"
2
2
 
3
3
  import * as React from 'react'
4
+ import { extensionPoints } from '@open-mercato/core/modules/resources/extension-points'
4
5
  import { useRouter } from 'next/navigation'
5
6
  import Link from 'next/link'
6
7
  import type { ColumnDef, SortingState } from '@tanstack/react-table'
@@ -318,7 +319,7 @@ export default function ResourcesResourceTypesPage() {
318
319
  />
319
320
  )}
320
321
  onRowClick={(row) => router.push(`/backend/resources/resource-types/${row.id}/edit`)}
321
- perspective={{ tableId: 'resources.resource-types.list' }}
322
+ perspective={{ tableId: extensionPoints.hosts.resourceTypesTable.tableId }}
322
323
  />
323
324
  </PageBody>
324
325
  {ConfirmDialogElement}
@@ -1,6 +1,7 @@
1
1
  "use client"
2
2
 
3
3
  import * as React from 'react'
4
+ import { extensionPoints } from '@open-mercato/core/modules/resources/extension-points'
4
5
  import Link from 'next/link'
5
6
  import { usePathname, useRouter, useSearchParams } from 'next/navigation'
6
7
  import type { ColumnDef } from '@tanstack/react-table'
@@ -524,7 +525,7 @@ export default function ResourcesResourcesPage() {
524
525
  filterValues={filterValues}
525
526
  onFiltersApply={handleFiltersApply}
526
527
  onFiltersClear={handleFiltersClear}
527
- perspective={{ tableId: 'resources.resources.list' }}
528
+ perspective={{ tableId: extensionPoints.hosts.resourcesTable.tableId }}
528
529
  rowActions={(row) => {
529
530
  if (!canManage || row.rowKind !== 'resource') return null
530
531
  return (
@@ -0,0 +1,11 @@
1
+ import { dataTableExtensionHost, defineModuleExtensionPoints } from '@open-mercato/shared/modules/widgets/extension-points'
2
+
3
+ export const extensionPoints = defineModuleExtensionPoints({
4
+ moduleId: 'resources',
5
+ hosts: {
6
+ resourcesTable: dataTableExtensionHost({ tableId: 'resources.resources.list', source: 'backend/resources/resources/page.tsx' }),
7
+ resourceTypesTable: dataTableExtensionHost({ tableId: 'resources.resource-types.list', source: 'backend/resources/resource-types/page.tsx' }),
8
+ },
9
+ })
10
+
11
+ export default extensionPoints
@@ -3,6 +3,8 @@
3
3
  "use client"
4
4
 
5
5
  import * as React from 'react'
6
+ import { extensionPoints } from '@open-mercato/core/modules/sales/extension-points'
7
+ import { resolveExtensionPointPattern } from '@open-mercato/shared/modules/widgets/extension-points'
6
8
  import { useSearchParams, useRouter, usePathname } from 'next/navigation'
7
9
  import { Page, PageBody } from '@open-mercato/ui/backend/Page'
8
10
  import {
@@ -1949,7 +1951,10 @@ export default function SalesDocumentDetailPage({
1949
1951
  () => (record?.id ? `sales-document:${kind}:${record.id}` : `sales-document:${kind}:pending`),
1950
1952
  [kind, record?.id],
1951
1953
  )
1952
- const detailsInjectionSpotId = React.useMemo(() => `sales.document.detail.${kind}:details`, [kind])
1954
+ const detailsInjectionSpotId = React.useMemo(
1955
+ () => resolveExtensionPointPattern(extensionPoints.hosts.documentDetail.pattern, { kind, surface: 'details' }),
1956
+ [kind],
1957
+ )
1953
1958
  const { runMutation, retryLastMutation } = useGuardedMutation<{
1954
1959
  kind: SalesDocumentKind
1955
1960
  record: DocumentRecord | null
@@ -3988,7 +3993,10 @@ export default function SalesDocumentDetailPage({
3988
3993
  const { payload: backendChromePayload, isReady: backendChromeReady } = useBackendChrome()
3989
3994
  const canComposeMessages = backendChromeReady && hasFeature(backendChromePayload?.grantedFeatures, 'messages.compose')
3990
3995
 
3991
- const tabInjectionSpotId = React.useMemo(() => `sales.document.detail.${kind}:tabs`, [kind])
3996
+ const tabInjectionSpotId = React.useMemo(
3997
+ () => resolveExtensionPointPattern(extensionPoints.hosts.documentDetail.pattern, { kind, surface: 'tabs' }),
3998
+ [kind],
3999
+ )
3992
4000
  const { widgets: injectedTabWidgets } = useInjectionWidgets(tabInjectionSpotId, {
3993
4001
  context: detailInjectionContext,
3994
4002
  triggerOnLoad: true,
@@ -4263,7 +4271,7 @@ export default function SalesDocumentDetailPage({
4263
4271
  onAddComment={appendShipmentComment}
4264
4272
  />
4265
4273
  <InjectionSpot
4266
- spotId="detail:sales.order:shipping"
4274
+ spotId={extensionPoints.hosts.orderShipping.spotId}
4267
4275
  context={detailInjectionContext}
4268
4276
  data={record}
4269
4277
  onDataChange={(next) => setRecord(next as unknown as DocumentRecord)}
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  import * as React from "react";
4
+ import { extensionPoints } from "@open-mercato/core/modules/sales/extension-points";
4
5
  import { apiCall, withScopedApiRequestHeaders } from "@open-mercato/ui/backend/utils/apiCall";
5
6
  import { buildOptimisticLockHeader } from "@open-mercato/ui/backend/utils/optimisticLock";
6
7
  import { deleteCrud } from "@open-mercato/ui/backend/utils/crud";
@@ -165,7 +166,7 @@ export function SalesDocumentItemsSection({
165
166
  );
166
167
 
167
168
  const { widgets: allColumnWidgets } = useInjectionDataWidgets(
168
- "data-table:sales.order.items:columns",
169
+ extensionPoints.hosts.orderItemColumns.spotId,
169
170
  );
170
171
  const columnWidgets = kind === "order" ? allColumnWidgets : [];
171
172
  const injectedColumns = React.useMemo<InjectionColumnDefinition[]>(() => {
@@ -1,6 +1,7 @@
1
1
  "use client"
2
2
 
3
3
  import * as React from 'react'
4
+ import { extensionPoints } from '@open-mercato/core/modules/sales/extension-points'
4
5
  import Link from 'next/link'
5
6
  import { useRouter } from 'next/navigation'
6
7
  import type { ColumnDef, SortingState } from '@tanstack/react-table'
@@ -738,7 +739,11 @@ export function SalesDocumentsTable({ kind }: { kind: SalesDocumentKind }) {
738
739
  ]}
739
740
  />
740
741
  )}
741
- perspective={{ tableId: kind === 'order' ? 'sales.orders' : 'sales.quotes' }}
742
+ perspective={{
743
+ tableId: kind === 'order'
744
+ ? extensionPoints.hosts.ordersTable.tableId
745
+ : extensionPoints.hosts.quotesTable.tableId,
746
+ }}
742
747
  onRowClick={handleRowClick}
743
748
  emptyState={
744
749
  <div className="py-10 text-center text-sm text-muted-foreground">
@@ -17,6 +17,7 @@ const events = [
17
17
  { id: 'sales.quote.created', label: 'Quote Created', entity: 'quote', category: 'crud' },
18
18
  { id: 'sales.quote.updated', label: 'Quote Updated', entity: 'quote', category: 'crud' },
19
19
  { id: 'sales.quote.deleted', label: 'Quote Deleted', entity: 'quote', category: 'crud' },
20
+ { id: 'sales.quote.expiring', label: 'Quote Expiring', entity: 'quote', category: 'lifecycle' },
20
21
 
21
22
  // Invoices
22
23
  { id: 'sales.invoice.created', label: 'Invoice Created', entity: 'invoice', category: 'crud' },