@open-mercato/core 0.6.7-develop.6605.1.761dd4c810 → 0.6.7-develop.6621.1.cdbe9dee3d

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 (114) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/modules/auth/api/session/refresh.js +12 -11
  3. package/dist/modules/auth/api/session/refresh.js.map +2 -2
  4. package/dist/modules/auth/lib/rateLimitCheck.js +4 -4
  5. package/dist/modules/auth/lib/rateLimitCheck.js.map +2 -2
  6. package/dist/modules/catalog/api/categories/route.js +8 -14
  7. package/dist/modules/catalog/api/categories/route.js.map +2 -2
  8. package/dist/modules/catalog/api/tags/route.js +3 -10
  9. package/dist/modules/catalog/api/tags/route.js.map +2 -2
  10. package/dist/modules/customers/api/interactions/[id]/visibility/route.js +15 -17
  11. package/dist/modules/customers/api/interactions/[id]/visibility/route.js.map +2 -2
  12. package/dist/modules/customers/api/people/[id]/email-threads/route.js +6 -4
  13. package/dist/modules/customers/api/people/[id]/email-threads/route.js.map +2 -2
  14. package/dist/modules/customers/api/people/[id]/emails/route.js +19 -17
  15. package/dist/modules/customers/api/people/[id]/emails/route.js.map +2 -2
  16. package/dist/modules/customers/components/detail/CustomFieldValuesList.js +22 -5
  17. package/dist/modules/customers/components/detail/CustomFieldValuesList.js.map +2 -2
  18. package/dist/modules/customers/components/detail/create/CreateDealForm.js +5 -2
  19. package/dist/modules/customers/components/detail/create/CreateDealForm.js.map +2 -2
  20. package/dist/modules/customers/components/detail/customFieldUtils.js +10 -3
  21. package/dist/modules/customers/components/detail/customFieldUtils.js.map +2 -2
  22. package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.meta.js +4 -2
  23. package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.meta.js.map +2 -2
  24. package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.meta.js +4 -2
  25. package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.meta.js.map +2 -2
  26. package/dist/modules/entities/backend/entities/user/[entityId]/page.js +3 -2
  27. package/dist/modules/entities/backend/entities/user/[entityId]/page.js.map +2 -2
  28. package/dist/modules/entities/backend/entities/user/create/page.js +2 -1
  29. package/dist/modules/entities/backend/entities/user/create/page.js.map +2 -2
  30. package/dist/modules/entities/data/entities.js.map +1 -1
  31. package/dist/modules/integrations/api/[id]/credentials/route.js +10 -7
  32. package/dist/modules/integrations/api/[id]/credentials/route.js.map +2 -2
  33. package/dist/modules/integrations/api/[id]/health/route.js +6 -4
  34. package/dist/modules/integrations/api/[id]/health/route.js.map +2 -2
  35. package/dist/modules/integrations/api/[id]/route.js +4 -2
  36. package/dist/modules/integrations/api/[id]/route.js.map +2 -2
  37. package/dist/modules/integrations/api/[id]/state/route.js +7 -5
  38. package/dist/modules/integrations/api/[id]/state/route.js.map +2 -2
  39. package/dist/modules/integrations/api/[id]/version/route.js +7 -5
  40. package/dist/modules/integrations/api/[id]/version/route.js.map +2 -2
  41. package/dist/modules/integrations/api/logs/route.js +4 -2
  42. package/dist/modules/integrations/api/logs/route.js.map +2 -2
  43. package/dist/modules/integrations/api/route.js +4 -2
  44. package/dist/modules/integrations/api/route.js.map +2 -2
  45. package/dist/modules/integrations/api/umes-read.js +2 -1
  46. package/dist/modules/integrations/api/umes-read.js.map +2 -2
  47. package/dist/modules/integrations/lib/organization-scope.js +12 -0
  48. package/dist/modules/integrations/lib/organization-scope.js.map +7 -0
  49. package/dist/modules/payment_gateways/lib/gateway-service.js +10 -1
  50. package/dist/modules/payment_gateways/lib/gateway-service.js.map +2 -2
  51. package/dist/modules/sales/api/document-history/route.js +6 -9
  52. package/dist/modules/sales/api/document-history/route.js.map +2 -2
  53. package/dist/modules/sales/api/quotes/accept/route.js +3 -3
  54. package/dist/modules/sales/api/quotes/accept/route.js.map +2 -2
  55. package/dist/modules/sales/api/returns/[id]/route.js +6 -9
  56. package/dist/modules/sales/api/returns/[id]/route.js.map +2 -2
  57. package/dist/modules/sales/backend/sales/documents/[id]/page.js +6 -2
  58. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  59. package/dist/modules/sales/components/documents/AddressesSection.js +6 -4
  60. package/dist/modules/sales/components/documents/AddressesSection.js.map +2 -2
  61. package/dist/modules/sales/workflows.js +1 -1
  62. package/dist/modules/sales/workflows.js.map +1 -1
  63. package/dist/modules/workflows/api/definitions/[id]/route.js +10 -1
  64. package/dist/modules/workflows/api/definitions/[id]/route.js.map +2 -2
  65. package/dist/modules/workflows/lib/event-trigger-service.js +44 -3
  66. package/dist/modules/workflows/lib/event-trigger-service.js.map +2 -2
  67. package/package.json +7 -7
  68. package/src/modules/auth/api/session/refresh.ts +19 -11
  69. package/src/modules/auth/lib/rateLimitCheck.ts +4 -4
  70. package/src/modules/catalog/api/categories/route.ts +14 -16
  71. package/src/modules/catalog/api/tags/route.ts +6 -10
  72. package/src/modules/catalog/i18n/pl.json +9 -9
  73. package/src/modules/customer_accounts/i18n/pl.json +129 -129
  74. package/src/modules/customers/api/interactions/[id]/visibility/route.ts +24 -20
  75. package/src/modules/customers/api/people/[id]/email-threads/route.ts +10 -6
  76. package/src/modules/customers/api/people/[id]/emails/route.ts +25 -21
  77. package/src/modules/customers/components/detail/CustomFieldValuesList.tsx +28 -4
  78. package/src/modules/customers/components/detail/create/CreateDealForm.tsx +7 -2
  79. package/src/modules/customers/components/detail/customFieldUtils.ts +15 -3
  80. package/src/modules/data_sync/i18n/pl.json +68 -68
  81. package/src/modules/directory/backend/directory/organizations/[id]/edit/page.meta.ts +4 -2
  82. package/src/modules/directory/backend/directory/tenants/[id]/edit/page.meta.ts +4 -2
  83. package/src/modules/entities/backend/entities/user/[entityId]/page.tsx +2 -1
  84. package/src/modules/entities/backend/entities/user/create/page.tsx +1 -0
  85. package/src/modules/entities/data/entities.ts +1 -1
  86. package/src/modules/entities/i18n/de.json +2 -0
  87. package/src/modules/entities/i18n/en.json +2 -0
  88. package/src/modules/entities/i18n/es.json +2 -0
  89. package/src/modules/entities/i18n/pl.json +2 -0
  90. package/src/modules/integrations/api/[id]/credentials/route.ts +10 -7
  91. package/src/modules/integrations/api/[id]/health/route.ts +6 -4
  92. package/src/modules/integrations/api/[id]/route.ts +4 -2
  93. package/src/modules/integrations/api/[id]/state/route.ts +7 -5
  94. package/src/modules/integrations/api/[id]/version/route.ts +7 -5
  95. package/src/modules/integrations/api/logs/route.ts +4 -2
  96. package/src/modules/integrations/api/route.ts +4 -2
  97. package/src/modules/integrations/api/umes-read.ts +2 -1
  98. package/src/modules/integrations/i18n/de.json +0 -76
  99. package/src/modules/integrations/i18n/en.json +0 -76
  100. package/src/modules/integrations/i18n/es.json +0 -76
  101. package/src/modules/integrations/i18n/pl.json +0 -76
  102. package/src/modules/integrations/lib/organization-scope.ts +27 -0
  103. package/src/modules/payment_gateways/lib/gateway-service.ts +12 -1
  104. package/src/modules/sales/api/document-history/route.ts +10 -9
  105. package/src/modules/sales/api/quotes/accept/route.ts +3 -3
  106. package/src/modules/sales/api/returns/[id]/route.ts +10 -9
  107. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +26 -19
  108. package/src/modules/sales/components/documents/AddressesSection.tsx +8 -4
  109. package/src/modules/sales/i18n/pl.json +24 -24
  110. package/src/modules/sales/workflows.ts +1 -1
  111. package/src/modules/staff/i18n/pl.json +178 -178
  112. package/src/modules/workflows/api/definitions/[id]/route.ts +14 -1
  113. package/src/modules/workflows/i18n/pl.json +128 -128
  114. package/src/modules/workflows/lib/event-trigger-service.ts +87 -8
@@ -26,6 +26,7 @@
26
26
  "entities.customFields.editor.editor": "Editor",
27
27
  "entities.customFields.editor.editorHtmlRichText": "Texto enriquecido (HTML)",
28
28
  "entities.customFields.editor.editorMarkdown": "Markdown (UIW)",
29
+ "entities.customFields.editor.editorPlain": "Área de texto sin formato",
29
30
  "entities.customFields.editor.editorSimpleMarkdown": "Markdown simple",
30
31
  "entities.customFields.editor.existingGroups": "Grupos existentes",
31
32
  "entities.customFields.editor.group": "Grupo",
@@ -227,6 +228,7 @@
227
228
  "entities.userEntities.form.defaultEditor.options.default": "Predeterminado (Markdown)",
228
229
  "entities.userEntities.form.defaultEditor.options.htmlRichText": "HTML enriquecido",
229
230
  "entities.userEntities.form.defaultEditor.options.markdown": "Markdown (UIW)",
231
+ "entities.userEntities.form.defaultEditor.options.plain": "Área de texto sin formato",
230
232
  "entities.userEntities.form.defaultEditor.options.simpleMarkdown": "Markdown simple",
231
233
  "entities.userEntities.form.description.label": "Descripción",
232
234
  "entities.userEntities.form.entityId.label": "ID de la entidad",
@@ -26,6 +26,7 @@
26
26
  "entities.customFields.editor.editor": "Edytor",
27
27
  "entities.customFields.editor.editorHtmlRichText": "Tekst sformatowany (HTML)",
28
28
  "entities.customFields.editor.editorMarkdown": "Markdown (UIW)",
29
+ "entities.customFields.editor.editorPlain": "Zwykłe pole tekstowe",
29
30
  "entities.customFields.editor.editorSimpleMarkdown": "Prosty Markdown",
30
31
  "entities.customFields.editor.existingGroups": "Istniejące grupy",
31
32
  "entities.customFields.editor.group": "Grupa",
@@ -227,6 +228,7 @@
227
228
  "entities.userEntities.form.defaultEditor.options.default": "Domyślne (Markdown)",
228
229
  "entities.userEntities.form.defaultEditor.options.htmlRichText": "HTML Rich Text",
229
230
  "entities.userEntities.form.defaultEditor.options.markdown": "Markdown (UIW)",
231
+ "entities.userEntities.form.defaultEditor.options.plain": "Zwykłe pole tekstowe",
230
232
  "entities.userEntities.form.defaultEditor.options.simpleMarkdown": "Prosty Markdown",
231
233
  "entities.userEntities.form.description.label": "Opis",
232
234
  "entities.userEntities.form.entityId.label": "Identyfikator encji",
@@ -21,6 +21,7 @@ import {
21
21
  runIntegrationMutationGuardAfterSuccess,
22
22
  runIntegrationMutationGuards,
23
23
  } from '../../guards'
24
+ import { resolveIntegrationsOrganizationId } from '../../../lib/organization-scope'
24
25
 
25
26
  const idParamsSchema = z.object({ id: z.string().min(1) })
26
27
 
@@ -44,7 +45,8 @@ function resolveParams(ctx: { params?: Promise<{ id?: string }> | { id?: string
44
45
 
45
46
  export async function GET(req: Request, ctx: { params?: Promise<{ id?: string }> | { id?: string } }) {
46
47
  const auth = await getAuthFromRequest(req)
47
- if (!auth?.tenantId || !auth.orgId) {
48
+ const organizationId = resolveIntegrationsOrganizationId(auth)
49
+ if (!auth?.tenantId || !organizationId) {
48
50
  return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
49
51
  }
50
52
 
@@ -61,7 +63,7 @@ export async function GET(req: Request, ctx: { params?: Promise<{ id?: string }>
61
63
 
62
64
  const container = await createRequestContainer()
63
65
  const credentialsService = container.resolve('integrationCredentialsService') as CredentialsService
64
- const scope = { organizationId: auth.orgId as string, tenantId: auth.tenantId }
66
+ const scope = { organizationId: organizationId, tenantId: auth.tenantId }
65
67
 
66
68
  let values: Record<string, unknown> | null
67
69
  let updatedAt: Date | null
@@ -89,7 +91,8 @@ export async function GET(req: Request, ctx: { params?: Promise<{ id?: string }>
89
91
 
90
92
  export async function PUT(req: Request, ctx: { params?: Promise<{ id?: string }> | { id?: string } }) {
91
93
  const auth = await getAuthFromRequest(req)
92
- if (!auth?.tenantId || !auth.orgId) {
94
+ const organizationId = resolveIntegrationsOrganizationId(auth)
95
+ if (!auth?.tenantId || !organizationId) {
93
96
  return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
94
97
  }
95
98
 
@@ -115,7 +118,7 @@ export async function PUT(req: Request, ctx: { params?: Promise<{ id?: string }>
115
118
  container,
116
119
  {
117
120
  tenantId: auth.tenantId,
118
- organizationId: auth.orgId,
121
+ organizationId,
119
122
  userId: auth.sub ?? '',
120
123
  resourceKind: 'integrations.integration',
121
124
  resourceId: integration.id,
@@ -141,7 +144,7 @@ export async function PUT(req: Request, ctx: { params?: Promise<{ id?: string }>
141
144
  }
142
145
 
143
146
  const credentialsService = container.resolve('integrationCredentialsService') as CredentialsService
144
- const scope = { organizationId: auth.orgId as string, tenantId: auth.tenantId }
147
+ const scope = { organizationId: organizationId, tenantId: auth.tenantId }
145
148
  const schema = credentialsService.getSchema(integration.id)
146
149
 
147
150
  try {
@@ -190,13 +193,13 @@ export async function PUT(req: Request, ctx: { params?: Promise<{ id?: string }>
190
193
  await emitIntegrationsEvent('integrations.credentials.updated', {
191
194
  integrationId: integration.id,
192
195
  tenantId: auth.tenantId,
193
- organizationId: auth.orgId,
196
+ organizationId,
194
197
  userId: auth.sub,
195
198
  })
196
199
 
197
200
  await runIntegrationMutationGuardAfterSuccess(guardResult.afterSuccessCallbacks, {
198
201
  tenantId: auth.tenantId,
199
- organizationId: auth.orgId,
202
+ organizationId,
200
203
  userId: auth.sub ?? '',
201
204
  resourceKind: 'integrations.integration',
202
205
  resourceId: integration.id,
@@ -9,6 +9,7 @@ import {
9
9
  runIntegrationMutationGuardAfterSuccess,
10
10
  runIntegrationMutationGuards,
11
11
  } from '../../guards'
12
+ import { resolveIntegrationsOrganizationId } from '../../../lib/organization-scope'
12
13
 
13
14
  const idParamsSchema = z.object({ id: z.string().min(1) })
14
15
 
@@ -23,7 +24,8 @@ export const openApi = {
23
24
 
24
25
  export async function POST(req: Request, ctx: { params?: Promise<{ id?: string }> | { id?: string } }) {
25
26
  const auth = await getAuthFromRequest(req)
26
- if (!auth?.tenantId || !auth.orgId) {
27
+ const organizationId = resolveIntegrationsOrganizationId(auth)
28
+ if (!auth?.tenantId || !organizationId) {
27
29
  return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
28
30
  }
29
31
 
@@ -46,7 +48,7 @@ export async function POST(req: Request, ctx: { params?: Promise<{ id?: string }
46
48
  container,
47
49
  {
48
50
  tenantId: auth.tenantId,
49
- organizationId: auth.orgId,
51
+ organizationId,
50
52
  userId: auth.sub ?? '',
51
53
  resourceKind: 'integrations.integration',
52
54
  resourceId: integration.id,
@@ -65,12 +67,12 @@ export async function POST(req: Request, ctx: { params?: Promise<{ id?: string }
65
67
 
66
68
  const result = await healthService.runHealthCheck(
67
69
  integration.id,
68
- { organizationId: auth.orgId as string, tenantId: auth.tenantId },
70
+ { organizationId: organizationId, tenantId: auth.tenantId },
69
71
  )
70
72
 
71
73
  await runIntegrationMutationGuardAfterSuccess(guardResult.afterSuccessCallbacks, {
72
74
  tenantId: auth.tenantId,
73
- organizationId: auth.orgId,
75
+ organizationId,
74
76
  userId: auth.sub ?? '',
75
77
  resourceKind: 'integrations.integration',
76
78
  resourceId: integration.id,
@@ -12,6 +12,7 @@ import {
12
12
  integrationApiRoutePaths,
13
13
  runIntegrationsReadBeforeInterceptors,
14
14
  } from '../umes-read'
15
+ import { resolveIntegrationsOrganizationId } from '../../lib/organization-scope'
15
16
 
16
17
  const idParamsSchema = z.object({ id: z.string().min(1) })
17
18
 
@@ -26,7 +27,8 @@ export const openApi = {
26
27
 
27
28
  export async function GET(req: Request, ctx: { params?: Promise<{ id?: string }> | { id?: string } }) {
28
29
  const auth = await getAuthFromRequest(req)
29
- if (!auth?.tenantId || !auth.orgId) {
30
+ const organizationId = resolveIntegrationsOrganizationId(auth)
31
+ if (!auth?.tenantId || !organizationId) {
30
32
  return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
31
33
  }
32
34
 
@@ -57,7 +59,7 @@ export async function GET(req: Request, ctx: { params?: Promise<{ id?: string }>
57
59
  const credentialsService = container.resolve('integrationCredentialsService') as CredentialsService
58
60
  const stateService = container.resolve('integrationStateService') as IntegrationStateService
59
61
  const logService = container.resolve('integrationLogService') as IntegrationLogService
60
- const scope = { organizationId: auth.orgId as string, tenantId: auth.tenantId }
62
+ const scope = { organizationId: organizationId, tenantId: auth.tenantId }
61
63
 
62
64
  const [credentials, credentialsUpdatedAt, state, analyticsMap] = await Promise.all([
63
65
  credentialsService.resolve(integration.id, scope).catch((err) => {
@@ -13,6 +13,7 @@ import {
13
13
  runIntegrationMutationGuardAfterSuccess,
14
14
  runIntegrationMutationGuards,
15
15
  } from '../../guards'
16
+ import { resolveIntegrationsOrganizationId } from '../../../lib/organization-scope'
16
17
 
17
18
  const idParamsSchema = z.object({ id: z.string().min(1) })
18
19
 
@@ -27,7 +28,8 @@ export const openApi = {
27
28
 
28
29
  export async function PUT(req: Request, ctx: { params?: Promise<{ id?: string }> | { id?: string } }) {
29
30
  const auth = await getAuthFromRequest(req)
30
- if (!auth?.tenantId || !auth.orgId) {
31
+ const organizationId = resolveIntegrationsOrganizationId(auth)
32
+ if (!auth?.tenantId || !organizationId) {
31
33
  return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
32
34
  }
33
35
 
@@ -56,7 +58,7 @@ export async function PUT(req: Request, ctx: { params?: Promise<{ id?: string }>
56
58
  container,
57
59
  {
58
60
  tenantId: auth.tenantId,
59
- organizationId: auth.orgId,
61
+ organizationId,
60
62
  userId: auth.sub ?? '',
61
63
  resourceKind: 'integrations.integration',
62
64
  resourceId: integration.id,
@@ -82,7 +84,7 @@ export async function PUT(req: Request, ctx: { params?: Promise<{ id?: string }>
82
84
  }
83
85
 
84
86
  const stateService = container.resolve('integrationStateService') as IntegrationStateService
85
- const stateScope = { organizationId: auth.orgId as string, tenantId: auth.tenantId }
87
+ const stateScope = { organizationId: organizationId, tenantId: auth.tenantId }
86
88
 
87
89
  try {
88
90
  const current = await stateService.resolveState(integration.id, stateScope)
@@ -113,13 +115,13 @@ export async function PUT(req: Request, ctx: { params?: Promise<{ id?: string }>
113
115
  isEnabled: state.isEnabled,
114
116
  reauthRequired: state.reauthRequired,
115
117
  tenantId: auth.tenantId,
116
- organizationId: auth.orgId,
118
+ organizationId,
117
119
  userId: auth.sub,
118
120
  })
119
121
 
120
122
  await runIntegrationMutationGuardAfterSuccess(guardResult.afterSuccessCallbacks, {
121
123
  tenantId: auth.tenantId,
122
- organizationId: auth.orgId,
124
+ organizationId,
123
125
  userId: auth.sub ?? '',
124
126
  resourceKind: 'integrations.integration',
125
127
  resourceId: integration.id,
@@ -14,6 +14,7 @@ import {
14
14
  runIntegrationMutationGuardAfterSuccess,
15
15
  runIntegrationMutationGuards,
16
16
  } from '../../guards'
17
+ import { resolveIntegrationsOrganizationId } from '../../../lib/organization-scope'
17
18
 
18
19
  const idParamsSchema = z.object({ id: z.string().min(1) })
19
20
 
@@ -28,7 +29,8 @@ export const openApi = {
28
29
 
29
30
  export async function PUT(req: Request, ctx: { params?: Promise<{ id?: string }> | { id?: string } }) {
30
31
  const auth = await getAuthFromRequest(req)
31
- if (!auth?.tenantId || !auth.orgId) {
32
+ const organizationId = resolveIntegrationsOrganizationId(auth)
33
+ if (!auth?.tenantId || !organizationId) {
32
34
  return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
33
35
  }
34
36
 
@@ -73,7 +75,7 @@ export async function PUT(req: Request, ctx: { params?: Promise<{ id?: string }>
73
75
  container,
74
76
  {
75
77
  tenantId: auth.tenantId,
76
- organizationId: auth.orgId,
78
+ organizationId,
77
79
  userId: auth.sub ?? '',
78
80
  resourceKind: 'integrations.integration',
79
81
  resourceId: integration.id,
@@ -102,7 +104,7 @@ export async function PUT(req: Request, ctx: { params?: Promise<{ id?: string }>
102
104
  }
103
105
 
104
106
  const stateService = container.resolve('integrationStateService') as IntegrationStateService
105
- const scope = { organizationId: auth.orgId as string, tenantId: auth.tenantId }
107
+ const scope = { organizationId: organizationId, tenantId: auth.tenantId }
106
108
 
107
109
  const currentState = await stateService.resolveState(integration.id, scope)
108
110
  try {
@@ -127,13 +129,13 @@ export async function PUT(req: Request, ctx: { params?: Promise<{ id?: string }>
127
129
  previousVersion: before ?? defaultVersion,
128
130
  apiVersion: payloadData.apiVersion,
129
131
  tenantId: auth.tenantId,
130
- organizationId: auth.orgId,
132
+ organizationId,
131
133
  userId: auth.sub,
132
134
  })
133
135
 
134
136
  await runIntegrationMutationGuardAfterSuccess(guardResult.afterSuccessCallbacks, {
135
137
  tenantId: auth.tenantId,
136
- organizationId: auth.orgId,
138
+ organizationId,
137
139
  userId: auth.sub ?? '',
138
140
  resourceKind: 'integrations.integration',
139
141
  resourceId: integration.id,
@@ -8,6 +8,7 @@ import {
8
8
  integrationApiRoutePaths,
9
9
  runIntegrationsReadBeforeInterceptors,
10
10
  } from '../umes-read'
11
+ import { resolveIntegrationsOrganizationId } from '../../lib/organization-scope'
11
12
 
12
13
  export const metadata = {
13
14
  GET: { requireAuth: true, requireFeatures: ['integrations.manage'] },
@@ -20,7 +21,8 @@ export const openApi = {
20
21
 
21
22
  export async function GET(req: Request) {
22
23
  const auth = await getAuthFromRequest(req)
23
- if (!auth?.tenantId || !auth.orgId) {
24
+ const organizationId = resolveIntegrationsOrganizationId(auth)
25
+ if (!auth?.tenantId || !organizationId) {
24
26
  return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
25
27
  }
26
28
 
@@ -52,7 +54,7 @@ export async function GET(req: Request) {
52
54
  const logService = container.resolve('integrationLogService') as IntegrationLogService
53
55
 
54
56
  const { items, total } = await logService.query(parsed.data, {
55
- organizationId: auth.orgId as string,
57
+ organizationId: organizationId,
56
58
  tenantId: auth.tenantId,
57
59
  })
58
60
 
@@ -14,6 +14,7 @@ import {
14
14
  integrationApiRoutePaths,
15
15
  runIntegrationsReadBeforeInterceptors,
16
16
  } from './umes-read'
17
+ import { resolveIntegrationsOrganizationId } from '../lib/organization-scope'
17
18
 
18
19
  export const metadata = {
19
20
  GET: { requireAuth: true, requireFeatures: ['integrations.view'] },
@@ -46,7 +47,8 @@ function matchesSearchQuery(
46
47
 
47
48
  export async function GET(req: Request) {
48
49
  const auth = await getAuthFromRequest(req)
49
- if (!auth?.tenantId || !auth.orgId) {
50
+ const organizationId = resolveIntegrationsOrganizationId(auth)
51
+ if (!auth?.tenantId || !organizationId) {
50
52
  return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
51
53
  }
52
54
 
@@ -71,7 +73,7 @@ export async function GET(req: Request) {
71
73
  const stateService = container.resolve('integrationStateService') as IntegrationStateService
72
74
  const logService = container.resolve('integrationLogService') as IntegrationLogService
73
75
 
74
- const scope = { organizationId: auth.orgId as string, tenantId: auth.tenantId as string }
76
+ const scope = { organizationId: organizationId, tenantId: auth.tenantId as string }
75
77
  const searchNeedle = query.q?.trim().toLowerCase() ?? ''
76
78
 
77
79
  type ListRow = {
@@ -4,6 +4,7 @@ import type { AwilixContainer } from 'awilix'
4
4
  import { runApiInterceptorsAfter, runApiInterceptorsBefore, type RunInterceptorsBeforeResult } from '@open-mercato/shared/lib/crud/interceptor-runner'
5
5
  import { applyResponseEnrichers, applyResponseEnricherToRecord } from '@open-mercato/shared/lib/crud/enricher-runner'
6
6
  import type { ApiInterceptorMethod, InterceptorRequest } from '@open-mercato/shared/lib/crud/api-interceptor'
7
+ import { resolveIntegrationsOrganizationId } from '../lib/organization-scope'
7
8
 
8
9
  export const integrationApiRoutePaths = {
9
10
  list: 'integrations',
@@ -66,7 +67,7 @@ function mergeAdditiveBody(
66
67
 
67
68
  function getEnricherContext(input: ReadRouteContext) {
68
69
  return {
69
- organizationId: input.auth.orgId as string,
70
+ organizationId: resolveIntegrationsOrganizationId(input.auth) as string,
70
71
  tenantId: input.auth.tenantId as string,
71
72
  userId: input.auth.sub ?? '',
72
73
  em: input.container.resolve('em') as EntityManager,
@@ -1,80 +1,4 @@
1
1
  {
2
- "example.mutationLifecycle.description": "Validation page for mutation guards, sync event subscribers, client-side event filtering, and command interceptors.",
3
- "example.mutationLifecycle.hintHeading": "What should be visible and how it should work",
4
- "example.mutationLifecycle.m1.createFailed": "Guard probe failed: expected 201, got {value}.",
5
- "example.mutationLifecycle.m1.description": "Create a todo via the CRUD pipeline to verify the mutation guard registry evaluates the `example.todo-limit` guard on POST.",
6
- "example.mutationLifecycle.m1.hint1": "1. Guard `example.todo-limit` targets `example.todo` on `create` operations with priority 50.",
7
- "example.mutationLifecycle.m1.hint2": "2. Guard validates `organizationId` presence — creation fails with 422 if missing.",
8
- "example.mutationLifecycle.m1.hint3": "3. Multiple guards run by priority order; first rejection stops the pipeline.",
9
- "example.mutationLifecycle.m1.hint4": "4. Legacy `crudMutationGuardService` is automatically bridged as a guard with priority 0.",
10
- "example.mutationLifecycle.m1.run": "Run guard probe",
11
- "example.mutationLifecycle.m1.title": "Phase m1 — Mutation Guard Registry",
12
- "example.mutationLifecycle.m2.createFailed": "Could not create todo for sync subscriber probe.",
13
- "example.mutationLifecycle.m2.description": "Run a multi-step probe: create a todo (verify auto-default-priority), mark as done then try to revert (verify prevent-uncomplete blocks with 422), and delete (verify audit-delete fires).",
14
- "example.mutationLifecycle.m2.hint1": "1. `auto-default-priority`: Injects `priority: 'normal'` when creating a todo without explicit priority (sync before-create).",
15
- "example.mutationLifecycle.m2.hint2": "2. `prevent-uncomplete`: Blocks reverting completed todos to pending with 422 (sync before-update).",
16
- "example.mutationLifecycle.m2.hint3": "3. `audit-delete`: Logs deletion audit trail to server console (sync after-delete, non-blocking).",
17
- "example.mutationLifecycle.m2.hint4": "4. Sync subscribers run inside the CRUD pipeline, before/after the actual mutation — unlike async subscribers which run post-commit.",
18
- "example.mutationLifecycle.m2.partial": "One or more sync subscriber probes failed. Review rows below.",
19
- "example.mutationLifecycle.m2.probe.auditDelete.error": "Expected 200, got {value}.",
20
- "example.mutationLifecycle.m2.probe.auditDelete.label": "audit-delete (after-delete)",
21
- "example.mutationLifecycle.m2.probe.auditDelete.ok": "Todo deleted (200). Sync after-event example.todo.deleted fired — audit-delete subscriber logged to server console.",
22
- "example.mutationLifecycle.m2.probe.defaultPriority.error": "Expected 201, got {value}.",
23
- "example.mutationLifecycle.m2.probe.defaultPriority.label": "auto-default-priority (before-create)",
24
- "example.mutationLifecycle.m2.probe.defaultPriority.ok": "Todo created (201). Sync before-event example.todo.creating fired — auto-default-priority subscriber injects priority if absent.",
25
- "example.mutationLifecycle.m2.probe.preventUncomplete.error": "Expected 422 (blocked), got {value}.",
26
- "example.mutationLifecycle.m2.probe.preventUncomplete.label": "prevent-uncomplete (before-update)",
27
- "example.mutationLifecycle.m2.probe.preventUncomplete.markDoneFailed": "Failed to mark todo as done: status {value}.",
28
- "example.mutationLifecycle.m2.probe.preventUncomplete.ok": "Revert blocked (422). Sync before-event example.todo.updating fired — prevent-uncomplete subscriber rejected the operation.",
29
- "example.mutationLifecycle.m2.probe.skipped": "Skipped — no todo was created in probe 1.",
30
- "example.mutationLifecycle.m2.run": "Run sync subscriber probe",
31
- "example.mutationLifecycle.m2.title": "Phase m2 — Sync Event Subscribers",
32
- "example.mutationLifecycle.m3.description": "Widget injection event handlers can now declare an operation filter to skip events for specific CRUD operations.",
33
- "example.mutationLifecycle.m3.hint1": "1. Widgets can declare `eventHandlers.filter.operations` to skip specific CRUD operations (e.g., only fire on `update`).",
34
- "example.mutationLifecycle.m3.hint2": "2. CrudForm now passes `operation` ('create' or 'update') in the injection context.",
35
- "example.mutationLifecycle.m3.hint3": "3. Widgets without a filter continue to fire for all operations (backward compatible).",
36
- "example.mutationLifecycle.m3.hint4": "4. Type: `WidgetInjectionEventFilter = { operations?: ('create' | 'update' | 'delete')[] }`",
37
- "example.mutationLifecycle.m3.note": "The filter is a type-level extension. See Phase G page for CrudForm injection demo.",
38
- "example.mutationLifecycle.m3.openPhaseG": "Open Phase G — CrudForm injection",
39
- "example.mutationLifecycle.m3.title": "Phase m3 — Client-Side Event Filtering",
40
- "example.mutationLifecycle.m4.description": "The `example.audit-logging` interceptor wraps all `customers.*` command bus operations with timing metadata.",
41
- "example.mutationLifecycle.m4.hint1": "1. `example.audit-logging` intercepts all `customers.*` commands (wildcard pattern).",
42
- "example.mutationLifecycle.m4.hint2": "2. `beforeExecute` stores `auditStartedAt` timestamp in metadata.",
43
- "example.mutationLifecycle.m4.hint3": "3. `afterExecute` reads metadata and logs: `[example:audit] Command {id} completed in {ms}ms`.",
44
- "example.mutationLifecycle.m4.hint4": "4. Pattern matching supports `*` (all), exact ID, and `prefix.*` (namespace wildcard).",
45
- "example.mutationLifecycle.m4.hint5": "5. Interceptors run on both `execute()` and `undo()` code paths.",
46
- "example.mutationLifecycle.m4.note": "Create or edit a customer, then check server console for the audit log entry.",
47
- "example.mutationLifecycle.m4.openCustomers": "Open customers",
48
- "example.mutationLifecycle.m4.title": "Phase m4 — Command Interceptors",
49
- "example.mutationLifecycle.title": "UMES Phase M — Mutation Lifecycle",
50
- "example.umes.queryExtensions.description": "Validation page for Phase N query engine extensions: enricher opt-in, surface-aware registry, sync query events, and scope guard re-application.",
51
- "example.umes.queryExtensions.enrichers.description": "Registers three enrichers (API-only, query-enabled for all engines, basic-only) and probes `getEnrichersForEntity` with different surface selectors.",
52
- "example.umes.queryExtensions.enrichers.hint1": "1. No selector / `api-response` surface: returns all 3 enrichers (backward compatible).",
53
- "example.umes.queryExtensions.enrichers.hint2": "2. `query-engine` surface (no engine filter): returns 2 enrichers (query-enabled + basic-only).",
54
- "example.umes.queryExtensions.enrichers.hint3": "3. `query-engine` + `basic` engine: returns 2 enrichers (query-enabled defaults to both, basic-only matches).",
55
- "example.umes.queryExtensions.enrichers.hint4": "4. `query-engine` + `hybrid` engine: returns 1 enricher (only query-enabled, basic-only excluded).",
56
- "example.umes.queryExtensions.enrichers.run": "Run enricher registry probe",
57
- "example.umes.queryExtensions.enrichers.title": "N.1 Surface-Aware Enricher Registry",
58
- "example.umes.queryExtensions.entityIds.description": "Validates `entityIdToEventEntity` which converts query engine format (`module:entity`) to event format (`module.entity`).",
59
- "example.umes.queryExtensions.entityIds.hint1": "1. `customers:person` should convert to `customers.person`.",
60
- "example.umes.queryExtensions.entityIds.hint2": "2. `catalog:product:variant` should convert to `catalog.product.variant` (multiple colons).",
61
- "example.umes.queryExtensions.entityIds.hint3": "3. All conversions should show `ok: true`.",
62
- "example.umes.queryExtensions.entityIds.run": "Run entity ID conversion probe",
63
- "example.umes.queryExtensions.entityIds.title": "N.4 Entity ID Conversion",
64
- "example.umes.queryExtensions.hintHeading": "What should be visible and how it should work",
65
- "example.umes.queryExtensions.scopeGuards.description": "Demonstrates that `reapplyScopeGuards` restores tenant/org constraints after subscriber modifications while preserving other query options.",
66
- "example.umes.queryExtensions.scopeGuards.hint1": "1. Tampered tenantId/organizationId should be restored to original values.",
67
- "example.umes.queryExtensions.scopeGuards.hint2": "2. Non-scope fields (filters, withDeleted) should remain unchanged.",
68
- "example.umes.queryExtensions.scopeGuards.hint3": "3. This ensures subscribers cannot bypass multi-tenant isolation.",
69
- "example.umes.queryExtensions.scopeGuards.run": "Run scope guard probe",
70
- "example.umes.queryExtensions.scopeGuards.title": "N.3 Scope Guard Re-application",
71
- "example.umes.queryExtensions.subscribers.description": "Registers three sync subscribers (querying, queried, wildcard) and probes `collectQuerySubscribers` with different event IDs.",
72
- "example.umes.queryExtensions.subscribers.hint1": "1. `example.todo.querying` should match 2 subscribers (exact + wildcard `example.*.querying`).",
73
- "example.umes.queryExtensions.subscribers.hint2": "2. `example.todo.queried` should match 1 subscriber (exact match only).",
74
- "example.umes.queryExtensions.subscribers.hint3": "3. `customers.person.querying` should match 0 subscribers (no cross-entity leakage).",
75
- "example.umes.queryExtensions.subscribers.run": "Run subscriber collection probe",
76
- "example.umes.queryExtensions.subscribers.title": "N.2 Sync Query Event Subscribers",
77
- "example.umes.queryExtensions.title": "UMES Phase N — Query Engine Extensibility",
78
2
  "integrations.bundle.configureIntegration": "Konfigurieren",
79
3
  "integrations.bundle.integrationToggles": "Integrationen",
80
4
  "integrations.bundle.sharedCredentials": "Gemeinsame Zugangsdaten",
@@ -1,80 +1,4 @@
1
1
  {
2
- "example.mutationLifecycle.description": "Validation page for mutation guards, sync event subscribers, client-side event filtering, and command interceptors.",
3
- "example.mutationLifecycle.hintHeading": "What should be visible and how it should work",
4
- "example.mutationLifecycle.m1.createFailed": "Guard probe failed: expected 201, got {value}.",
5
- "example.mutationLifecycle.m1.description": "Create a todo via the CRUD pipeline to verify the mutation guard registry evaluates the `example.todo-limit` guard on POST.",
6
- "example.mutationLifecycle.m1.hint1": "1. Guard `example.todo-limit` targets `example.todo` on `create` operations with priority 50.",
7
- "example.mutationLifecycle.m1.hint2": "2. Guard validates `organizationId` presence — creation fails with 422 if missing.",
8
- "example.mutationLifecycle.m1.hint3": "3. Multiple guards run by priority order; first rejection stops the pipeline.",
9
- "example.mutationLifecycle.m1.hint4": "4. Legacy `crudMutationGuardService` is automatically bridged as a guard with priority 0.",
10
- "example.mutationLifecycle.m1.run": "Run guard probe",
11
- "example.mutationLifecycle.m1.title": "Phase m1 — Mutation Guard Registry",
12
- "example.mutationLifecycle.m2.createFailed": "Could not create todo for sync subscriber probe.",
13
- "example.mutationLifecycle.m2.description": "Run a multi-step probe: create a todo (verify auto-default-priority), mark as done then try to revert (verify prevent-uncomplete blocks with 422), and delete (verify audit-delete fires).",
14
- "example.mutationLifecycle.m2.hint1": "1. `auto-default-priority`: Injects `priority: 'normal'` when creating a todo without explicit priority (sync before-create).",
15
- "example.mutationLifecycle.m2.hint2": "2. `prevent-uncomplete`: Blocks reverting completed todos to pending with 422 (sync before-update).",
16
- "example.mutationLifecycle.m2.hint3": "3. `audit-delete`: Logs deletion audit trail to server console (sync after-delete, non-blocking).",
17
- "example.mutationLifecycle.m2.hint4": "4. Sync subscribers run inside the CRUD pipeline, before/after the actual mutation — unlike async subscribers which run post-commit.",
18
- "example.mutationLifecycle.m2.partial": "One or more sync subscriber probes failed. Review rows below.",
19
- "example.mutationLifecycle.m2.probe.auditDelete.error": "Expected 200, got {value}.",
20
- "example.mutationLifecycle.m2.probe.auditDelete.label": "audit-delete (after-delete)",
21
- "example.mutationLifecycle.m2.probe.auditDelete.ok": "Todo deleted (200). Sync after-event example.todo.deleted fired — audit-delete subscriber logged to server console.",
22
- "example.mutationLifecycle.m2.probe.defaultPriority.error": "Expected 201, got {value}.",
23
- "example.mutationLifecycle.m2.probe.defaultPriority.label": "auto-default-priority (before-create)",
24
- "example.mutationLifecycle.m2.probe.defaultPriority.ok": "Todo created (201). Sync before-event example.todo.creating fired — auto-default-priority subscriber injects priority if absent.",
25
- "example.mutationLifecycle.m2.probe.preventUncomplete.error": "Expected 422 (blocked), got {value}.",
26
- "example.mutationLifecycle.m2.probe.preventUncomplete.label": "prevent-uncomplete (before-update)",
27
- "example.mutationLifecycle.m2.probe.preventUncomplete.markDoneFailed": "Failed to mark todo as done: status {value}.",
28
- "example.mutationLifecycle.m2.probe.preventUncomplete.ok": "Revert blocked (422). Sync before-event example.todo.updating fired — prevent-uncomplete subscriber rejected the operation.",
29
- "example.mutationLifecycle.m2.probe.skipped": "Skipped — no todo was created in probe 1.",
30
- "example.mutationLifecycle.m2.run": "Run sync subscriber probe",
31
- "example.mutationLifecycle.m2.title": "Phase m2 — Sync Event Subscribers",
32
- "example.mutationLifecycle.m3.description": "Widget injection event handlers can now declare an operation filter to skip events for specific CRUD operations.",
33
- "example.mutationLifecycle.m3.hint1": "1. Widgets can declare `eventHandlers.filter.operations` to skip specific CRUD operations (e.g., only fire on `update`).",
34
- "example.mutationLifecycle.m3.hint2": "2. CrudForm now passes `operation` ('create' or 'update') in the injection context.",
35
- "example.mutationLifecycle.m3.hint3": "3. Widgets without a filter continue to fire for all operations (backward compatible).",
36
- "example.mutationLifecycle.m3.hint4": "4. Type: `WidgetInjectionEventFilter = { operations?: ('create' | 'update' | 'delete')[] }`",
37
- "example.mutationLifecycle.m3.note": "The filter is a type-level extension. See Phase G page for CrudForm injection demo.",
38
- "example.mutationLifecycle.m3.openPhaseG": "Open Phase G — CrudForm injection",
39
- "example.mutationLifecycle.m3.title": "Phase m3 — Client-Side Event Filtering",
40
- "example.mutationLifecycle.m4.description": "The `example.audit-logging` interceptor wraps all `customers.*` command bus operations with timing metadata.",
41
- "example.mutationLifecycle.m4.hint1": "1. `example.audit-logging` intercepts all `customers.*` commands (wildcard pattern).",
42
- "example.mutationLifecycle.m4.hint2": "2. `beforeExecute` stores `auditStartedAt` timestamp in metadata.",
43
- "example.mutationLifecycle.m4.hint3": "3. `afterExecute` reads metadata and logs: `[example:audit] Command {id} completed in {ms}ms`.",
44
- "example.mutationLifecycle.m4.hint4": "4. Pattern matching supports `*` (all), exact ID, and `prefix.*` (namespace wildcard).",
45
- "example.mutationLifecycle.m4.hint5": "5. Interceptors run on both `execute()` and `undo()` code paths.",
46
- "example.mutationLifecycle.m4.note": "Create or edit a customer, then check server console for the audit log entry.",
47
- "example.mutationLifecycle.m4.openCustomers": "Open customers",
48
- "example.mutationLifecycle.m4.title": "Phase m4 — Command Interceptors",
49
- "example.mutationLifecycle.title": "UMES Phase M — Mutation Lifecycle",
50
- "example.umes.queryExtensions.description": "Validation page for Phase N query engine extensions: enricher opt-in, surface-aware registry, sync query events, and scope guard re-application.",
51
- "example.umes.queryExtensions.enrichers.description": "Registers three enrichers (API-only, query-enabled for all engines, basic-only) and probes `getEnrichersForEntity` with different surface selectors.",
52
- "example.umes.queryExtensions.enrichers.hint1": "1. No selector / `api-response` surface: returns all 3 enrichers (backward compatible).",
53
- "example.umes.queryExtensions.enrichers.hint2": "2. `query-engine` surface (no engine filter): returns 2 enrichers (query-enabled + basic-only).",
54
- "example.umes.queryExtensions.enrichers.hint3": "3. `query-engine` + `basic` engine: returns 2 enrichers (query-enabled defaults to both, basic-only matches).",
55
- "example.umes.queryExtensions.enrichers.hint4": "4. `query-engine` + `hybrid` engine: returns 1 enricher (only query-enabled, basic-only excluded).",
56
- "example.umes.queryExtensions.enrichers.run": "Run enricher registry probe",
57
- "example.umes.queryExtensions.enrichers.title": "N.1 Surface-Aware Enricher Registry",
58
- "example.umes.queryExtensions.entityIds.description": "Validates `entityIdToEventEntity` which converts query engine format (`module:entity`) to event format (`module.entity`).",
59
- "example.umes.queryExtensions.entityIds.hint1": "1. `customers:person` should convert to `customers.person`.",
60
- "example.umes.queryExtensions.entityIds.hint2": "2. `catalog:product:variant` should convert to `catalog.product.variant` (multiple colons).",
61
- "example.umes.queryExtensions.entityIds.hint3": "3. All conversions should show `ok: true`.",
62
- "example.umes.queryExtensions.entityIds.run": "Run entity ID conversion probe",
63
- "example.umes.queryExtensions.entityIds.title": "N.4 Entity ID Conversion",
64
- "example.umes.queryExtensions.hintHeading": "What should be visible and how it should work",
65
- "example.umes.queryExtensions.scopeGuards.description": "Demonstrates that `reapplyScopeGuards` restores tenant/org constraints after subscriber modifications while preserving other query options.",
66
- "example.umes.queryExtensions.scopeGuards.hint1": "1. Tampered tenantId/organizationId should be restored to original values.",
67
- "example.umes.queryExtensions.scopeGuards.hint2": "2. Non-scope fields (filters, withDeleted) should remain unchanged.",
68
- "example.umes.queryExtensions.scopeGuards.hint3": "3. This ensures subscribers cannot bypass multi-tenant isolation.",
69
- "example.umes.queryExtensions.scopeGuards.run": "Run scope guard probe",
70
- "example.umes.queryExtensions.scopeGuards.title": "N.3 Scope Guard Re-application",
71
- "example.umes.queryExtensions.subscribers.description": "Registers three sync subscribers (querying, queried, wildcard) and probes `collectQuerySubscribers` with different event IDs.",
72
- "example.umes.queryExtensions.subscribers.hint1": "1. `example.todo.querying` should match 2 subscribers (exact + wildcard `example.*.querying`).",
73
- "example.umes.queryExtensions.subscribers.hint2": "2. `example.todo.queried` should match 1 subscriber (exact match only).",
74
- "example.umes.queryExtensions.subscribers.hint3": "3. `customers.person.querying` should match 0 subscribers (no cross-entity leakage).",
75
- "example.umes.queryExtensions.subscribers.run": "Run subscriber collection probe",
76
- "example.umes.queryExtensions.subscribers.title": "N.2 Sync Query Event Subscribers",
77
- "example.umes.queryExtensions.title": "UMES Phase N — Query Engine Extensibility",
78
2
  "integrations.bundle.configureIntegration": "Configure",
79
3
  "integrations.bundle.integrationToggles": "Integrations",
80
4
  "integrations.bundle.sharedCredentials": "Shared Credentials",
@@ -1,80 +1,4 @@
1
1
  {
2
- "example.mutationLifecycle.description": "Validation page for mutation guards, sync event subscribers, client-side event filtering, and command interceptors.",
3
- "example.mutationLifecycle.hintHeading": "What should be visible and how it should work",
4
- "example.mutationLifecycle.m1.createFailed": "Guard probe failed: expected 201, got {value}.",
5
- "example.mutationLifecycle.m1.description": "Create a todo via the CRUD pipeline to verify the mutation guard registry evaluates the `example.todo-limit` guard on POST.",
6
- "example.mutationLifecycle.m1.hint1": "1. Guard `example.todo-limit` targets `example.todo` on `create` operations with priority 50.",
7
- "example.mutationLifecycle.m1.hint2": "2. Guard validates `organizationId` presence — creation fails with 422 if missing.",
8
- "example.mutationLifecycle.m1.hint3": "3. Multiple guards run by priority order; first rejection stops the pipeline.",
9
- "example.mutationLifecycle.m1.hint4": "4. Legacy `crudMutationGuardService` is automatically bridged as a guard with priority 0.",
10
- "example.mutationLifecycle.m1.run": "Run guard probe",
11
- "example.mutationLifecycle.m1.title": "Phase m1 — Mutation Guard Registry",
12
- "example.mutationLifecycle.m2.createFailed": "Could not create todo for sync subscriber probe.",
13
- "example.mutationLifecycle.m2.description": "Run a multi-step probe: create a todo (verify auto-default-priority), mark as done then try to revert (verify prevent-uncomplete blocks with 422), and delete (verify audit-delete fires).",
14
- "example.mutationLifecycle.m2.hint1": "1. `auto-default-priority`: Injects `priority: 'normal'` when creating a todo without explicit priority (sync before-create).",
15
- "example.mutationLifecycle.m2.hint2": "2. `prevent-uncomplete`: Blocks reverting completed todos to pending with 422 (sync before-update).",
16
- "example.mutationLifecycle.m2.hint3": "3. `audit-delete`: Logs deletion audit trail to server console (sync after-delete, non-blocking).",
17
- "example.mutationLifecycle.m2.hint4": "4. Sync subscribers run inside the CRUD pipeline, before/after the actual mutation — unlike async subscribers which run post-commit.",
18
- "example.mutationLifecycle.m2.partial": "One or more sync subscriber probes failed. Review rows below.",
19
- "example.mutationLifecycle.m2.probe.auditDelete.error": "Expected 200, got {value}.",
20
- "example.mutationLifecycle.m2.probe.auditDelete.label": "audit-delete (after-delete)",
21
- "example.mutationLifecycle.m2.probe.auditDelete.ok": "Todo deleted (200). Sync after-event example.todo.deleted fired — audit-delete subscriber logged to server console.",
22
- "example.mutationLifecycle.m2.probe.defaultPriority.error": "Expected 201, got {value}.",
23
- "example.mutationLifecycle.m2.probe.defaultPriority.label": "auto-default-priority (before-create)",
24
- "example.mutationLifecycle.m2.probe.defaultPriority.ok": "Todo created (201). Sync before-event example.todo.creating fired — auto-default-priority subscriber injects priority if absent.",
25
- "example.mutationLifecycle.m2.probe.preventUncomplete.error": "Expected 422 (blocked), got {value}.",
26
- "example.mutationLifecycle.m2.probe.preventUncomplete.label": "prevent-uncomplete (before-update)",
27
- "example.mutationLifecycle.m2.probe.preventUncomplete.markDoneFailed": "Failed to mark todo as done: status {value}.",
28
- "example.mutationLifecycle.m2.probe.preventUncomplete.ok": "Revert blocked (422). Sync before-event example.todo.updating fired — prevent-uncomplete subscriber rejected the operation.",
29
- "example.mutationLifecycle.m2.probe.skipped": "Skipped — no todo was created in probe 1.",
30
- "example.mutationLifecycle.m2.run": "Run sync subscriber probe",
31
- "example.mutationLifecycle.m2.title": "Phase m2 — Sync Event Subscribers",
32
- "example.mutationLifecycle.m3.description": "Widget injection event handlers can now declare an operation filter to skip events for specific CRUD operations.",
33
- "example.mutationLifecycle.m3.hint1": "1. Widgets can declare `eventHandlers.filter.operations` to skip specific CRUD operations (e.g., only fire on `update`).",
34
- "example.mutationLifecycle.m3.hint2": "2. CrudForm now passes `operation` ('create' or 'update') in the injection context.",
35
- "example.mutationLifecycle.m3.hint3": "3. Widgets without a filter continue to fire for all operations (backward compatible).",
36
- "example.mutationLifecycle.m3.hint4": "4. Type: `WidgetInjectionEventFilter = { operations?: ('create' | 'update' | 'delete')[] }`",
37
- "example.mutationLifecycle.m3.note": "The filter is a type-level extension. See Phase G page for CrudForm injection demo.",
38
- "example.mutationLifecycle.m3.openPhaseG": "Open Phase G — CrudForm injection",
39
- "example.mutationLifecycle.m3.title": "Phase m3 — Client-Side Event Filtering",
40
- "example.mutationLifecycle.m4.description": "The `example.audit-logging` interceptor wraps all `customers.*` command bus operations with timing metadata.",
41
- "example.mutationLifecycle.m4.hint1": "1. `example.audit-logging` intercepts all `customers.*` commands (wildcard pattern).",
42
- "example.mutationLifecycle.m4.hint2": "2. `beforeExecute` stores `auditStartedAt` timestamp in metadata.",
43
- "example.mutationLifecycle.m4.hint3": "3. `afterExecute` reads metadata and logs: `[example:audit] Command {id} completed in {ms}ms`.",
44
- "example.mutationLifecycle.m4.hint4": "4. Pattern matching supports `*` (all), exact ID, and `prefix.*` (namespace wildcard).",
45
- "example.mutationLifecycle.m4.hint5": "5. Interceptors run on both `execute()` and `undo()` code paths.",
46
- "example.mutationLifecycle.m4.note": "Create or edit a customer, then check server console for the audit log entry.",
47
- "example.mutationLifecycle.m4.openCustomers": "Open customers",
48
- "example.mutationLifecycle.m4.title": "Phase m4 — Command Interceptors",
49
- "example.mutationLifecycle.title": "UMES Phase M — Mutation Lifecycle",
50
- "example.umes.queryExtensions.description": "Validation page for Phase N query engine extensions: enricher opt-in, surface-aware registry, sync query events, and scope guard re-application.",
51
- "example.umes.queryExtensions.enrichers.description": "Registers three enrichers (API-only, query-enabled for all engines, basic-only) and probes `getEnrichersForEntity` with different surface selectors.",
52
- "example.umes.queryExtensions.enrichers.hint1": "1. No selector / `api-response` surface: returns all 3 enrichers (backward compatible).",
53
- "example.umes.queryExtensions.enrichers.hint2": "2. `query-engine` surface (no engine filter): returns 2 enrichers (query-enabled + basic-only).",
54
- "example.umes.queryExtensions.enrichers.hint3": "3. `query-engine` + `basic` engine: returns 2 enrichers (query-enabled defaults to both, basic-only matches).",
55
- "example.umes.queryExtensions.enrichers.hint4": "4. `query-engine` + `hybrid` engine: returns 1 enricher (only query-enabled, basic-only excluded).",
56
- "example.umes.queryExtensions.enrichers.run": "Run enricher registry probe",
57
- "example.umes.queryExtensions.enrichers.title": "N.1 Surface-Aware Enricher Registry",
58
- "example.umes.queryExtensions.entityIds.description": "Validates `entityIdToEventEntity` which converts query engine format (`module:entity`) to event format (`module.entity`).",
59
- "example.umes.queryExtensions.entityIds.hint1": "1. `customers:person` should convert to `customers.person`.",
60
- "example.umes.queryExtensions.entityIds.hint2": "2. `catalog:product:variant` should convert to `catalog.product.variant` (multiple colons).",
61
- "example.umes.queryExtensions.entityIds.hint3": "3. All conversions should show `ok: true`.",
62
- "example.umes.queryExtensions.entityIds.run": "Run entity ID conversion probe",
63
- "example.umes.queryExtensions.entityIds.title": "N.4 Entity ID Conversion",
64
- "example.umes.queryExtensions.hintHeading": "What should be visible and how it should work",
65
- "example.umes.queryExtensions.scopeGuards.description": "Demonstrates that `reapplyScopeGuards` restores tenant/org constraints after subscriber modifications while preserving other query options.",
66
- "example.umes.queryExtensions.scopeGuards.hint1": "1. Tampered tenantId/organizationId should be restored to original values.",
67
- "example.umes.queryExtensions.scopeGuards.hint2": "2. Non-scope fields (filters, withDeleted) should remain unchanged.",
68
- "example.umes.queryExtensions.scopeGuards.hint3": "3. This ensures subscribers cannot bypass multi-tenant isolation.",
69
- "example.umes.queryExtensions.scopeGuards.run": "Run scope guard probe",
70
- "example.umes.queryExtensions.scopeGuards.title": "N.3 Scope Guard Re-application",
71
- "example.umes.queryExtensions.subscribers.description": "Registers three sync subscribers (querying, queried, wildcard) and probes `collectQuerySubscribers` with different event IDs.",
72
- "example.umes.queryExtensions.subscribers.hint1": "1. `example.todo.querying` should match 2 subscribers (exact + wildcard `example.*.querying`).",
73
- "example.umes.queryExtensions.subscribers.hint2": "2. `example.todo.queried` should match 1 subscriber (exact match only).",
74
- "example.umes.queryExtensions.subscribers.hint3": "3. `customers.person.querying` should match 0 subscribers (no cross-entity leakage).",
75
- "example.umes.queryExtensions.subscribers.run": "Run subscriber collection probe",
76
- "example.umes.queryExtensions.subscribers.title": "N.2 Sync Query Event Subscribers",
77
- "example.umes.queryExtensions.title": "UMES Phase N — Query Engine Extensibility",
78
2
  "integrations.bundle.configureIntegration": "Configurar",
79
3
  "integrations.bundle.integrationToggles": "Integraciones",
80
4
  "integrations.bundle.sharedCredentials": "Credenciales compartidas",