@open-mercato/core 0.6.2-develop.3461.1.605f31c2c9 → 0.6.2
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.
- package/.turbo/turbo-build.log +1 -1
- package/dist/helpers/integration/queue-runner.js +15 -3
- package/dist/helpers/integration/queue-runner.js.map +2 -2
- package/dist/helpers/integration/queue.js +1 -1
- package/dist/helpers/integration/queue.js.map +2 -2
- package/dist/helpers/integration/salesUi.js +24 -1
- package/dist/helpers/integration/salesUi.js.map +2 -2
- package/dist/modules/auth/api/roles/acl/route.js +37 -1
- package/dist/modules/auth/api/roles/acl/route.js.map +2 -2
- package/dist/modules/auth/api/roles/route.js +36 -2
- package/dist/modules/auth/api/roles/route.js.map +2 -2
- package/dist/modules/auth/api/users/acl/route.js +36 -1
- package/dist/modules/auth/api/users/acl/route.js.map +2 -2
- package/dist/modules/auth/api/users/route.js +101 -13
- package/dist/modules/auth/api/users/route.js.map +2 -2
- package/dist/modules/auth/backend/roles/[id]/edit/page.js +32 -14
- package/dist/modules/auth/backend/roles/[id]/edit/page.js.map +2 -2
- package/dist/modules/auth/backend/users/[id]/edit/page.js +1 -1
- package/dist/modules/auth/backend/users/[id]/edit/page.js.map +2 -2
- package/dist/modules/auth/backend/users/create/page.js +1 -1
- package/dist/modules/auth/backend/users/create/page.js.map +2 -2
- package/dist/modules/auth/backend/users/roleOptions.js +1 -1
- package/dist/modules/auth/backend/users/roleOptions.js.map +2 -2
- package/dist/modules/auth/commands/roles.js +8 -0
- package/dist/modules/auth/commands/roles.js.map +2 -2
- package/dist/modules/auth/commands/users.js +3 -0
- package/dist/modules/auth/commands/users.js.map +2 -2
- package/dist/modules/auth/components/AclEditor.js +53 -26
- package/dist/modules/auth/components/AclEditor.js.map +2 -2
- package/dist/modules/auth/frontend/login.js +35 -0
- package/dist/modules/auth/frontend/login.js.map +2 -2
- package/dist/modules/auth/lib/grantChecks.js +97 -2
- package/dist/modules/auth/lib/grantChecks.js.map +2 -2
- package/dist/modules/business_rules/lib/expression-evaluator.js +9 -7
- package/dist/modules/business_rules/lib/expression-evaluator.js.map +2 -2
- package/dist/modules/business_rules/lib/rule-evaluator.js +3 -3
- package/dist/modules/business_rules/lib/rule-evaluator.js.map +2 -2
- package/dist/modules/customers/ai-agents.js +10 -1
- package/dist/modules/customers/ai-agents.js.map +2 -2
- package/dist/modules/customers/ai-tools/settings-pack.js +55 -1
- package/dist/modules/customers/ai-tools/settings-pack.js.map +2 -2
- package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js +13 -5
- package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +2 -2
- package/dist/modules/customers/lib/personCompanyLinkTable.js +4 -30
- package/dist/modules/customers/lib/personCompanyLinkTable.js.map +2 -2
- package/dist/modules/customers/migrations/Migration20260521175027.js +12 -0
- package/dist/modules/customers/migrations/Migration20260521175027.js.map +7 -0
- package/dist/modules/dashboards/components/WidgetVisibilityEditor.js +41 -12
- package/dist/modules/dashboards/components/WidgetVisibilityEditor.js.map +2 -2
- package/dist/modules/data_sync/api/options.js +2 -0
- package/dist/modules/data_sync/api/options.js.map +2 -2
- package/dist/modules/data_sync/api/run.js +77 -58
- package/dist/modules/data_sync/api/run.js.map +2 -2
- package/dist/modules/data_sync/backend/data-sync/page.js +3 -2
- package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
- package/dist/modules/data_sync/components/IntegrationScheduleTab.js +8 -3
- package/dist/modules/data_sync/components/IntegrationScheduleTab.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/[id]/page.js +15 -13
- package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
- package/dist/modules/integrations/data/validators.js +9 -6
- package/dist/modules/integrations/data/validators.js.map +2 -2
- package/dist/modules/messages/api/route.js +2 -2
- package/dist/modules/messages/api/route.js.map +2 -2
- package/dist/modules/messages/commands/messages.js +42 -2
- package/dist/modules/messages/commands/messages.js.map +2 -2
- package/dist/modules/messages/components/MessagesInboxPageClient.js +70 -89
- package/dist/modules/messages/components/MessagesInboxPageClient.js.map +2 -2
- package/dist/modules/messages/components/defaults/DefaultMessageListItem.js +8 -6
- package/dist/modules/messages/components/defaults/DefaultMessageListItem.js.map +2 -2
- package/dist/modules/messages/components/inboxFilters.js +133 -0
- package/dist/modules/messages/components/inboxFilters.js.map +7 -0
- package/dist/modules/messages/components/messageListLabels.js +14 -0
- package/dist/modules/messages/components/messageListLabels.js.map +7 -0
- package/dist/modules/messages/components/useMessagesInboxBulkActions.js +47 -23
- package/dist/modules/messages/components/useMessagesInboxBulkActions.js.map +2 -2
- package/dist/modules/messages/data/validators.js +8 -6
- package/dist/modules/messages/data/validators.js.map +2 -2
- package/dist/modules/progress/api/jobs/route.js +26 -16
- package/dist/modules/progress/api/jobs/route.js.map +2 -2
- package/dist/modules/query_index/di.js +8 -6
- package/dist/modules/query_index/di.js.map +2 -2
- package/dist/modules/query_index/lib/indexer.js +12 -10
- package/dist/modules/query_index/lib/indexer.js.map +2 -2
- package/dist/modules/query_index/subscribers/upsert_one.js +7 -1
- package/dist/modules/query_index/subscribers/upsert_one.js.map +2 -2
- package/dist/modules/sales/api/order-adjustments/route.js.map +2 -2
- package/dist/modules/sales/api/quote-adjustments/route.js.map +2 -2
- package/dist/modules/sales/commands/documents.js +104 -0
- package/dist/modules/sales/commands/documents.js.map +2 -2
- package/dist/modules/sales/data/validators.js +20 -1
- package/dist/modules/sales/data/validators.js.map +2 -2
- package/dist/modules/sales/lib/makeSalesLineRoute.js.map +2 -2
- package/dist/modules/sync_excel/api/import/route.js +126 -116
- package/dist/modules/sync_excel/api/import/route.js.map +2 -2
- package/dist/modules/sync_excel/lib/adapters/customers.js +1 -0
- package/dist/modules/sync_excel/lib/adapters/customers.js.map +2 -2
- package/dist/modules/translations/components/TranslationManager.js +9 -4
- package/dist/modules/translations/components/TranslationManager.js.map +2 -2
- package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
- package/dist/modules/workflows/lib/event-trigger-service.js +23 -11
- package/dist/modules/workflows/lib/event-trigger-service.js.map +2 -2
- package/jest.config.cjs +4 -1
- package/package.json +15 -16
- package/src/helpers/integration/queue-runner.ts +21 -2
- package/src/helpers/integration/queue.ts +1 -1
- package/src/helpers/integration/salesUi.ts +26 -1
- package/src/modules/auth/api/roles/acl/route.ts +39 -1
- package/src/modules/auth/api/roles/route.ts +38 -2
- package/src/modules/auth/api/users/acl/route.ts +41 -1
- package/src/modules/auth/api/users/route.ts +105 -12
- package/src/modules/auth/backend/roles/[id]/edit/page.tsx +35 -13
- package/src/modules/auth/backend/users/[id]/edit/page.tsx +1 -1
- package/src/modules/auth/backend/users/create/page.tsx +1 -1
- package/src/modules/auth/backend/users/roleOptions.ts +2 -1
- package/src/modules/auth/commands/roles.ts +8 -0
- package/src/modules/auth/commands/users.ts +3 -0
- package/src/modules/auth/components/AclEditor.tsx +50 -24
- package/src/modules/auth/frontend/login.tsx +40 -0
- package/src/modules/auth/lib/grantChecks.ts +116 -2
- package/src/modules/business_rules/lib/expression-evaluator.ts +9 -13
- package/src/modules/business_rules/lib/rule-evaluator.ts +3 -3
- package/src/modules/customers/ai-agents.ts +10 -1
- package/src/modules/customers/ai-tools/settings-pack.ts +62 -1
- package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +18 -7
- package/src/modules/customers/lib/personCompanyLinkTable.ts +33 -41
- package/src/modules/customers/migrations/Migration20260521175027.ts +39 -0
- package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +38 -12
- package/src/modules/data_sync/api/options.ts +2 -0
- package/src/modules/data_sync/api/run.ts +80 -61
- package/src/modules/data_sync/backend/data-sync/page.tsx +10 -0
- package/src/modules/data_sync/components/IntegrationScheduleTab.tsx +17 -3
- package/src/modules/data_sync/i18n/de.json +3 -0
- package/src/modules/data_sync/i18n/en.json +3 -0
- package/src/modules/data_sync/i18n/es.json +3 -0
- package/src/modules/data_sync/i18n/pl.json +3 -0
- package/src/modules/data_sync/lib/adapter.ts +9 -0
- package/src/modules/integrations/backend/integrations/[id]/page.tsx +15 -13
- package/src/modules/integrations/data/validators.ts +5 -4
- package/src/modules/messages/api/route.ts +2 -2
- package/src/modules/messages/commands/messages.ts +54 -2
- package/src/modules/messages/components/MessagesInboxPageClient.tsx +80 -92
- package/src/modules/messages/components/defaults/DefaultMessageListItem.tsx +9 -5
- package/src/modules/messages/components/inboxFilters.ts +162 -0
- package/src/modules/messages/components/messageListLabels.ts +29 -0
- package/src/modules/messages/components/useMessagesInboxBulkActions.ts +58 -26
- package/src/modules/messages/data/validators.ts +7 -5
- package/src/modules/messages/i18n/de.json +7 -4
- package/src/modules/messages/i18n/en.json +7 -4
- package/src/modules/messages/i18n/es.json +7 -4
- package/src/modules/messages/i18n/pl.json +7 -4
- package/src/modules/progress/api/jobs/route.ts +30 -20
- package/src/modules/query_index/di.ts +9 -7
- package/src/modules/query_index/lib/indexer.ts +13 -11
- package/src/modules/query_index/subscribers/upsert_one.ts +9 -1
- package/src/modules/sales/api/order-adjustments/route.ts +2 -1
- package/src/modules/sales/api/quote-adjustments/route.ts +2 -1
- package/src/modules/sales/commands/documents.ts +116 -0
- package/src/modules/sales/data/validators.ts +38 -0
- package/src/modules/sales/i18n/de.json +2 -0
- package/src/modules/sales/i18n/en.json +2 -0
- package/src/modules/sales/i18n/es.json +2 -0
- package/src/modules/sales/i18n/pl.json +2 -0
- package/src/modules/sales/lib/makeSalesLineRoute.ts +2 -1
- package/src/modules/staff/i18n/de.json +1 -0
- package/src/modules/staff/i18n/en.json +1 -0
- package/src/modules/staff/i18n/es.json +1 -0
- package/src/modules/staff/i18n/pl.json +1 -0
- package/src/modules/sync_excel/api/import/route.ts +141 -131
- package/src/modules/sync_excel/lib/adapters/customers.ts +1 -0
- package/src/modules/translations/components/TranslationManager.tsx +9 -4
- package/src/modules/workflows/lib/activity-executor.ts +4 -3
- package/src/modules/workflows/lib/event-trigger-service.ts +24 -11
- package/tsconfig.json +1 -0
|
@@ -46,137 +46,147 @@ export const openApi = {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
export async function POST(request: Request) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
existingMapping
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
49
|
+
try {
|
|
50
|
+
const auth = await getAuthFromRequest(request)
|
|
51
|
+
if (!auth?.tenantId) {
|
|
52
|
+
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const payload = await readJsonSafe(request)
|
|
56
|
+
const parsedPayload = syncExcelImportRequestSchema.safeParse(payload)
|
|
57
|
+
if (!parsedPayload.success) {
|
|
58
|
+
return NextResponse.json({ error: 'Invalid import payload.' }, { status: 422 })
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const container = await createRequestContainer()
|
|
62
|
+
const em = container.resolve('em') as EntityManager
|
|
63
|
+
const syncRunService = container.resolve('dataSyncRunService') as SyncRunService
|
|
64
|
+
const progressService = container.resolve('progressService') as ProgressService
|
|
65
|
+
const credentialsService = container.resolve('integrationCredentialsService') as CredentialsService
|
|
66
|
+
const integrationStateService = container.resolve('integrationStateService') as IntegrationStateService
|
|
67
|
+
const scopeResult = await resolveSyncExcelConcreteScope({ auth, container, request })
|
|
68
|
+
if (!scopeResult.ok) {
|
|
69
|
+
return NextResponse.json({ error: scopeResult.error }, { status: scopeResult.status })
|
|
70
|
+
}
|
|
71
|
+
const { scope } = scopeResult
|
|
72
|
+
|
|
73
|
+
const upload = await findOneWithDecryption(
|
|
74
|
+
em,
|
|
75
|
+
SyncExcelUpload,
|
|
76
|
+
{
|
|
77
|
+
id: parsedPayload.data.uploadId,
|
|
78
|
+
organizationId: scope.organizationId,
|
|
79
|
+
tenantId: scope.tenantId,
|
|
80
|
+
},
|
|
81
|
+
undefined,
|
|
82
|
+
scope,
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
if (!upload) {
|
|
86
|
+
return NextResponse.json({ error: 'Upload preview not found.' }, { status: 404 })
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const attachment = await findOneWithDecryption(
|
|
90
|
+
em,
|
|
91
|
+
Attachment,
|
|
92
|
+
{
|
|
93
|
+
id: upload.attachmentId,
|
|
94
|
+
organizationId: scope.organizationId,
|
|
95
|
+
tenantId: scope.tenantId,
|
|
96
|
+
},
|
|
97
|
+
undefined,
|
|
98
|
+
scope,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
if (!attachment) {
|
|
102
|
+
return NextResponse.json({ error: 'Upload attachment not found.' }, { status: 404 })
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (upload.entityType !== parsedPayload.data.entityType) {
|
|
106
|
+
return NextResponse.json({ error: 'Upload entity type does not match requested import target.' }, { status: 422 })
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (parsedPayload.data.mapping.entityType !== parsedPayload.data.entityType) {
|
|
110
|
+
return NextResponse.json({ error: 'Mapping entity type does not match requested import target.' }, { status: 422 })
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const overlap = await syncRunService.findRunningOverlap('sync_excel', parsedPayload.data.entityType, 'import', scope)
|
|
114
|
+
if (overlap) {
|
|
115
|
+
return NextResponse.json({ error: 'A sync_excel import is already in progress for this entity type.' }, { status: 409 })
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const existingMapping = await findOneWithDecryption(
|
|
119
|
+
em,
|
|
120
|
+
SyncMapping,
|
|
121
|
+
{
|
|
122
|
+
integrationId: 'sync_excel',
|
|
123
|
+
entityType: parsedPayload.data.entityType,
|
|
124
|
+
organizationId: scope.organizationId,
|
|
125
|
+
tenantId: scope.tenantId,
|
|
126
|
+
},
|
|
127
|
+
undefined,
|
|
128
|
+
scope,
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
if (existingMapping) {
|
|
132
|
+
existingMapping.mapping = parsedPayload.data.mapping
|
|
133
|
+
} else {
|
|
134
|
+
em.persist(em.create(SyncMapping, {
|
|
135
|
+
integrationId: 'sync_excel',
|
|
136
|
+
entityType: parsedPayload.data.entityType,
|
|
137
|
+
mapping: parsedPayload.data.mapping,
|
|
138
|
+
organizationId: scope.organizationId,
|
|
139
|
+
tenantId: scope.tenantId,
|
|
140
|
+
}))
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
await credentialsService.save('sync_excel', {}, scope)
|
|
144
|
+
await integrationStateService.upsert('sync_excel', { isEnabled: true }, scope)
|
|
145
|
+
await em.flush()
|
|
146
|
+
|
|
147
|
+
const { run, progressJob } = await startDataSyncRun({
|
|
148
|
+
syncRunService,
|
|
149
|
+
progressService,
|
|
150
|
+
scope: {
|
|
151
|
+
...scope,
|
|
152
|
+
userId: auth.sub,
|
|
153
|
+
},
|
|
154
|
+
input: {
|
|
155
|
+
integrationId: 'sync_excel',
|
|
156
|
+
entityType: parsedPayload.data.entityType,
|
|
157
|
+
direction: 'import',
|
|
158
|
+
cursor: createCursor(upload.id, 0),
|
|
159
|
+
triggeredBy: auth.sub,
|
|
160
|
+
batchSize: parsedPayload.data.batchSize ?? 100,
|
|
161
|
+
progressJob: {
|
|
162
|
+
jobType: 'sync_excel:import',
|
|
163
|
+
name: `CSV import — ${parsedPayload.data.entityType}`,
|
|
164
|
+
description: upload.filename,
|
|
165
|
+
meta: {
|
|
166
|
+
integrationId: 'sync_excel',
|
|
167
|
+
uploadId: upload.id,
|
|
168
|
+
hiddenFromTopBar: false,
|
|
169
|
+
},
|
|
168
170
|
},
|
|
169
171
|
},
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
status:
|
|
181
|
-
})
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
upload.syncRunId = run.id
|
|
175
|
+
upload.status = 'importing'
|
|
176
|
+
await em.flush()
|
|
177
|
+
|
|
178
|
+
return NextResponse.json(syncExcelImportResponseSchema.parse({
|
|
179
|
+
runId: run.id,
|
|
180
|
+
progressJobId: progressJob?.id ?? null,
|
|
181
|
+
status: run.status,
|
|
182
|
+
}), { status: 201 })
|
|
183
|
+
} catch (error) {
|
|
184
|
+
const message = error instanceof Error ? error.message : String(error)
|
|
185
|
+
const stack = error instanceof Error ? error.stack : undefined
|
|
186
|
+
console.error('[sync_excel.import] unhandled error', { message, stack })
|
|
187
|
+
return NextResponse.json(
|
|
188
|
+
{ error: 'Failed to start sync_excel import.', message, stack },
|
|
189
|
+
{ status: 500 },
|
|
190
|
+
)
|
|
191
|
+
}
|
|
182
192
|
}
|
|
@@ -993,6 +993,7 @@ async function processRow(params: {
|
|
|
993
993
|
|
|
994
994
|
export const syncExcelCustomersAdapter: DataSyncAdapter = {
|
|
995
995
|
providerKey: 'excel',
|
|
996
|
+
runMode: 'provider',
|
|
996
997
|
operationalTelemetry: true,
|
|
997
998
|
direction: 'import',
|
|
998
999
|
supportedEntities: ['customers.person'],
|
|
@@ -69,6 +69,7 @@ export function TranslationManager({
|
|
|
69
69
|
const [editedTranslations, setEditedTranslations] = React.useState<Record<string, Record<string, string>>>({})
|
|
70
70
|
const editedTranslationsRef = React.useRef<Record<string, Record<string, string>>>({})
|
|
71
71
|
const [hasUserEdited, setHasUserEdited] = React.useState(false)
|
|
72
|
+
const hasUserEditedRef = React.useRef(false)
|
|
72
73
|
|
|
73
74
|
const entityType = isEmbedded ? (propEntityType ?? '') : selectedEntityType
|
|
74
75
|
const recordId = isEmbedded ? (propRecordId ?? '') : selectedRecordId
|
|
@@ -191,11 +192,11 @@ export function TranslationManager({
|
|
|
191
192
|
|
|
192
193
|
React.useEffect(() => {
|
|
193
194
|
const sig = translationSignature
|
|
194
|
-
if (sig === lastTranslationSignatureRef.current &&
|
|
195
|
+
if (sig === lastTranslationSignatureRef.current && hasUserEditedRef.current) return
|
|
195
196
|
lastTranslationSignatureRef.current = sig
|
|
196
197
|
|
|
197
198
|
if (!translationData?.translations) {
|
|
198
|
-
if (!
|
|
199
|
+
if (!hasUserEditedRef.current) {
|
|
199
200
|
editedTranslationsRef.current = {}
|
|
200
201
|
setEditedTranslations({})
|
|
201
202
|
}
|
|
@@ -210,11 +211,11 @@ export function TranslationManager({
|
|
|
210
211
|
parsed[locale][key] = typeof val === 'string' ? val : ''
|
|
211
212
|
}
|
|
212
213
|
}
|
|
213
|
-
if (!
|
|
214
|
+
if (!hasUserEditedRef.current) {
|
|
214
215
|
editedTranslationsRef.current = parsed
|
|
215
216
|
setEditedTranslations(parsed)
|
|
216
217
|
}
|
|
217
|
-
}, [translationSignature, translationData
|
|
218
|
+
}, [translationSignature, translationData])
|
|
218
219
|
|
|
219
220
|
const mutation = useMutation({
|
|
220
221
|
mutationFn: async () => {
|
|
@@ -252,6 +253,7 @@ export function TranslationManager({
|
|
|
252
253
|
},
|
|
253
254
|
onSuccess: () => {
|
|
254
255
|
flash(t('translations.manager.flash.saved', 'Translations saved'), 'success')
|
|
256
|
+
hasUserEditedRef.current = false
|
|
255
257
|
setHasUserEdited(false)
|
|
256
258
|
void refetchTranslation()
|
|
257
259
|
},
|
|
@@ -262,6 +264,7 @@ export function TranslationManager({
|
|
|
262
264
|
})
|
|
263
265
|
|
|
264
266
|
const updateFieldValue = (locale: string, fieldKey: string, value: string) => {
|
|
267
|
+
hasUserEditedRef.current = true
|
|
265
268
|
setHasUserEdited(true)
|
|
266
269
|
const next = {
|
|
267
270
|
...editedTranslationsRef.current,
|
|
@@ -288,6 +291,7 @@ export function TranslationManager({
|
|
|
288
291
|
value={selectedRecordId}
|
|
289
292
|
onChange={(next) => {
|
|
290
293
|
setSelectedRecordId(next)
|
|
294
|
+
hasUserEditedRef.current = false
|
|
291
295
|
setHasUserEdited(false)
|
|
292
296
|
}}
|
|
293
297
|
placeholder={t('translations.manager.searchRecords', 'Search records...')}
|
|
@@ -482,6 +486,7 @@ export function TranslationManager({
|
|
|
482
486
|
onChange={(next) => {
|
|
483
487
|
setSelectedEntityType(next)
|
|
484
488
|
setSelectedRecordId('')
|
|
489
|
+
hasUserEditedRef.current = false
|
|
485
490
|
setHasUserEdited(false)
|
|
486
491
|
}}
|
|
487
492
|
placeholder={t('translations.manager.placeholder', 'Select an entity')}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { EntityManager } from '@mikro-orm/core'
|
|
14
|
+
import type { EntityManager as PostgreSqlEntityManager } from '@mikro-orm/postgresql'
|
|
14
15
|
import type { AwilixContainer } from 'awilix'
|
|
15
16
|
import { WorkflowInstance } from '../data/entities'
|
|
16
17
|
import { createModuleQueue, Queue } from '@open-mercato/queue'
|
|
@@ -406,7 +407,7 @@ export async function executeSendEmail(
|
|
|
406
407
|
|
|
407
408
|
// Check if email service is available in container
|
|
408
409
|
try {
|
|
409
|
-
const emailService = container.resolve('emailService')
|
|
410
|
+
const emailService = container.resolve<{ send: (input: unknown) => Promise<unknown> | unknown }>('emailService')
|
|
410
411
|
if (emailService && typeof emailService.send === 'function') {
|
|
411
412
|
await emailService.send({
|
|
412
413
|
to,
|
|
@@ -441,7 +442,7 @@ export async function executeEmitEvent(
|
|
|
441
442
|
}
|
|
442
443
|
|
|
443
444
|
// Get event bus from container
|
|
444
|
-
const eventBus = container.resolve('eventBus')
|
|
445
|
+
const eventBus = container.resolve<{ emitEvent: (event: string, payload: unknown, options?: unknown) => Promise<unknown> | unknown }>('eventBus')
|
|
445
446
|
|
|
446
447
|
if (!eventBus || typeof eventBus.emitEvent !== 'function') {
|
|
447
448
|
throw new Error('Event bus not available in container')
|
|
@@ -789,7 +790,7 @@ export async function executeCallApi(
|
|
|
789
790
|
const { withOnetimeApiKey } = await import('../../api_keys/services/apiKeyService')
|
|
790
791
|
|
|
791
792
|
// 4. Get EntityManager from container (for correct type)
|
|
792
|
-
const apiKeyEm = container.resolve('em')
|
|
793
|
+
const apiKeyEm = container.resolve<PostgreSqlEntityManager>('em')
|
|
793
794
|
|
|
794
795
|
// 5. Resolve the roles that the one-time API key will inherit.
|
|
795
796
|
//
|
|
@@ -6,9 +6,12 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { EntityManager } from '@mikro-orm/core'
|
|
9
|
+
import type { EntityManager as PostgreSqlEntityManager } from '@mikro-orm/postgresql'
|
|
9
10
|
import type { AwilixContainer } from 'awilix'
|
|
10
11
|
import type { CacheService } from '@open-mercato/cache'
|
|
11
12
|
import { matchEventPattern } from '@open-mercato/shared/lib/events/patterns'
|
|
13
|
+
import { findWithDecryption } from '@open-mercato/shared/lib/encryption/find'
|
|
14
|
+
import { testLinearRegex } from '@open-mercato/shared/lib/regex/linear'
|
|
12
15
|
import {
|
|
13
16
|
WorkflowEventTrigger,
|
|
14
17
|
WorkflowDefinition,
|
|
@@ -257,11 +260,12 @@ function evaluateCondition(condition: TriggerFilterCondition, payload: Record<st
|
|
|
257
260
|
if (typeof value !== 'string' || typeof expected !== 'string') return false
|
|
258
261
|
if (value.length > MAX_WORKFLOW_REGEX_INPUT_LENGTH) return false
|
|
259
262
|
if (!isSafeWorkflowRegexPattern(expected)) return false
|
|
260
|
-
|
|
261
|
-
const
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
263
|
+
{
|
|
264
|
+
const result = testLinearRegex(expected, value, {
|
|
265
|
+
maxPatternLength: MAX_WORKFLOW_REGEX_PATTERN_LENGTH,
|
|
266
|
+
maxInputLength: MAX_WORKFLOW_REGEX_INPUT_LENGTH,
|
|
267
|
+
})
|
|
268
|
+
return result.ok ? result.matched : false
|
|
265
269
|
}
|
|
266
270
|
|
|
267
271
|
default:
|
|
@@ -325,7 +329,9 @@ async function loadLegacyTriggers(
|
|
|
325
329
|
tenantId: string,
|
|
326
330
|
organizationId: string
|
|
327
331
|
): Promise<UnifiedTrigger[]> {
|
|
328
|
-
const
|
|
332
|
+
const postgresEm = em as unknown as PostgreSqlEntityManager
|
|
333
|
+
const legacyTriggers = await findWithDecryption(
|
|
334
|
+
postgresEm,
|
|
329
335
|
WorkflowEventTrigger,
|
|
330
336
|
{
|
|
331
337
|
tenantId,
|
|
@@ -335,16 +341,19 @@ async function loadLegacyTriggers(
|
|
|
335
341
|
},
|
|
336
342
|
{
|
|
337
343
|
orderBy: { priority: 'DESC', createdAt: 'ASC' },
|
|
338
|
-
}
|
|
344
|
+
},
|
|
345
|
+
{ tenantId, organizationId },
|
|
339
346
|
)
|
|
340
347
|
|
|
341
348
|
// Get definitions for these triggers to get workflowId
|
|
342
349
|
const definitionIds = [...new Set(legacyTriggers.map(t => t.workflowDefinitionId))]
|
|
343
|
-
const definitions = definitionIds.length > 0 ? await
|
|
350
|
+
const definitions = definitionIds.length > 0 ? await findWithDecryption(postgresEm, WorkflowDefinition, {
|
|
344
351
|
id: { $in: definitionIds },
|
|
352
|
+
tenantId,
|
|
353
|
+
organizationId,
|
|
345
354
|
enabled: true,
|
|
346
355
|
deletedAt: null,
|
|
347
|
-
}) : []
|
|
356
|
+
}, {}, { tenantId, organizationId }) : []
|
|
348
357
|
const definitionMap = new Map(definitions.map(d => [d.id, d]))
|
|
349
358
|
|
|
350
359
|
return legacyTriggers
|
|
@@ -379,15 +388,19 @@ async function loadEmbeddedTriggers(
|
|
|
379
388
|
tenantId: string,
|
|
380
389
|
organizationId: string
|
|
381
390
|
): Promise<UnifiedTrigger[]> {
|
|
391
|
+
const postgresEm = em as unknown as PostgreSqlEntityManager
|
|
382
392
|
// Load all enabled definitions that may have triggers
|
|
383
|
-
const definitions = await
|
|
393
|
+
const definitions = await findWithDecryption(
|
|
394
|
+
postgresEm,
|
|
384
395
|
WorkflowDefinition,
|
|
385
396
|
{
|
|
386
397
|
tenantId,
|
|
387
398
|
organizationId,
|
|
388
399
|
enabled: true,
|
|
389
400
|
deletedAt: null,
|
|
390
|
-
}
|
|
401
|
+
},
|
|
402
|
+
{},
|
|
403
|
+
{ tenantId, organizationId },
|
|
391
404
|
)
|
|
392
405
|
|
|
393
406
|
const triggers: UnifiedTrigger[] = []
|