@open-mercato/core 0.4.2-canary-d0a025141f → 0.4.2-canary-3efa759f5c
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/dist/generated/entities.ids.generated.js +0 -1
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +0 -2
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/modules/business_rules/data/validators.js +0 -34
- package/dist/modules/business_rules/data/validators.js.map +2 -2
- package/dist/modules/business_rules/index.js +1 -21
- package/dist/modules/business_rules/index.js.map +2 -2
- package/dist/modules/business_rules/lib/rule-engine.js +1 -182
- package/dist/modules/business_rules/lib/rule-engine.js.map +2 -2
- package/dist/modules/sales/acl.js +0 -1
- package/dist/modules/sales/acl.js.map +2 -2
- package/dist/modules/sales/backend/sales/documents/[id]/page.js +0 -12
- package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
- package/dist/modules/sales/commands/documents.js +0 -62
- package/dist/modules/sales/commands/documents.js.map +2 -2
- package/dist/modules/sales/lib/dictionaries.js +0 -3
- package/dist/modules/sales/lib/dictionaries.js.map +2 -2
- package/dist/modules/workflows/acl.js +0 -2
- package/dist/modules/workflows/acl.js.map +2 -2
- package/dist/modules/workflows/api/instances/route.js +6 -18
- package/dist/modules/workflows/api/instances/route.js.map +2 -2
- package/dist/modules/workflows/api/tasks/route.js +1 -6
- package/dist/modules/workflows/api/tasks/route.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/[id]/page.js +1 -9
- package/dist/modules/workflows/backend/definitions/[id]/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/[id]/page.meta.js +1 -1
- package/dist/modules/workflows/backend/definitions/[id]/page.meta.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/create/page.js +15 -24
- package/dist/modules/workflows/backend/definitions/create/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/create/page.meta.js +1 -1
- package/dist/modules/workflows/backend/definitions/create/page.meta.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js +132 -150
- package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
- package/dist/modules/workflows/backend/definitions/visual-editor/page.meta.js +1 -1
- package/dist/modules/workflows/backend/definitions/visual-editor/page.meta.js.map +2 -2
- package/dist/modules/workflows/backend/events/[id]/page.js +1 -1
- package/dist/modules/workflows/backend/events/[id]/page.js.map +2 -2
- package/dist/modules/workflows/backend/events/[id]/page.meta.js +2 -2
- package/dist/modules/workflows/backend/events/[id]/page.meta.js.map +2 -2
- package/dist/modules/workflows/backend/instances/[id]/page.meta.js +2 -2
- package/dist/modules/workflows/backend/instances/[id]/page.meta.js.map +2 -2
- package/dist/modules/workflows/backend/tasks/[id]/page.js +1 -1
- package/dist/modules/workflows/backend/tasks/[id]/page.js.map +2 -2
- package/dist/modules/workflows/backend/tasks/[id]/page.meta.js +2 -2
- package/dist/modules/workflows/backend/tasks/[id]/page.meta.js.map +2 -2
- package/dist/modules/workflows/backend/tasks/page.js +6 -5
- package/dist/modules/workflows/backend/tasks/page.js.map +2 -2
- package/dist/modules/workflows/cli.js +3 -81
- package/dist/modules/workflows/cli.js.map +3 -3
- package/dist/modules/workflows/data/entities.js +1 -64
- package/dist/modules/workflows/data/entities.js.map +2 -2
- package/dist/modules/workflows/data/validators.js +0 -115
- package/dist/modules/workflows/data/validators.js.map +2 -2
- package/dist/modules/workflows/examples/checkout-demo-definition.json +5 -1
- package/dist/modules/workflows/lib/activity-executor.js +13 -75
- package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
- package/dist/modules/workflows/lib/graph-utils.js +2 -71
- package/dist/modules/workflows/lib/graph-utils.js.map +2 -2
- package/dist/modules/workflows/lib/seeds.js +5 -22
- package/dist/modules/workflows/lib/seeds.js.map +2 -2
- package/dist/modules/workflows/lib/start-validator.js +23 -33
- package/dist/modules/workflows/lib/start-validator.js.map +2 -2
- package/dist/modules/workflows/lib/transition-handler.js +45 -157
- package/dist/modules/workflows/lib/transition-handler.js.map +3 -3
- package/generated/entities.ids.generated.ts +0 -1
- package/generated/entity-fields-registry.ts +0 -2
- package/package.json +2 -2
- package/src/modules/business_rules/data/validators.ts +0 -40
- package/src/modules/business_rules/index.ts +0 -25
- package/src/modules/business_rules/lib/rule-engine.ts +1 -281
- package/src/modules/sales/acl.ts +0 -1
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +0 -16
- package/src/modules/sales/commands/documents.ts +1 -74
- package/src/modules/sales/lib/dictionaries.ts +0 -3
- package/src/modules/workflows/acl.ts +0 -2
- package/src/modules/workflows/api/__tests__/instances.route.test.ts +2 -5
- package/src/modules/workflows/api/instances/route.ts +7 -21
- package/src/modules/workflows/api/tasks/route.ts +1 -7
- package/src/modules/workflows/backend/definitions/[id]/page.meta.ts +1 -1
- package/src/modules/workflows/backend/definitions/[id]/page.tsx +0 -9
- package/src/modules/workflows/backend/definitions/create/page.meta.ts +1 -1
- package/src/modules/workflows/backend/definitions/create/page.tsx +0 -9
- package/src/modules/workflows/backend/definitions/visual-editor/page.meta.ts +1 -1
- package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +3 -21
- package/src/modules/workflows/backend/events/[id]/page.meta.ts +2 -2
- package/src/modules/workflows/backend/events/[id]/page.tsx +1 -1
- package/src/modules/workflows/backend/instances/[id]/page.meta.ts +2 -2
- package/src/modules/workflows/backend/tasks/[id]/page.meta.ts +2 -2
- package/src/modules/workflows/backend/tasks/[id]/page.tsx +1 -1
- package/src/modules/workflows/backend/tasks/page.tsx +6 -5
- package/src/modules/workflows/cli.ts +0 -111
- package/src/modules/workflows/data/entities.ts +0 -124
- package/src/modules/workflows/data/validators.ts +0 -138
- package/src/modules/workflows/examples/checkout-demo-definition.json +5 -1
- package/src/modules/workflows/i18n/en.json +0 -71
- package/src/modules/workflows/lib/__tests__/activity-executor.test.ts +36 -43
- package/src/modules/workflows/lib/__tests__/transition-handler.test.ts +90 -170
- package/src/modules/workflows/lib/activity-executor.ts +16 -129
- package/src/modules/workflows/lib/graph-utils.ts +2 -117
- package/src/modules/workflows/lib/seeds.ts +8 -34
- package/src/modules/workflows/lib/start-validator.ts +28 -38
- package/src/modules/workflows/lib/transition-handler.ts +55 -208
- package/dist/generated/entities/workflow_event_trigger/index.js +0 -33
- package/dist/generated/entities/workflow_event_trigger/index.js.map +0 -7
- package/dist/modules/auth/events.js +0 -30
- package/dist/modules/auth/events.js.map +0 -7
- package/dist/modules/business_rules/api/execute/[ruleId]/route.js +0 -145
- package/dist/modules/business_rules/api/execute/[ruleId]/route.js.map +0 -7
- package/dist/modules/catalog/events.js +0 -34
- package/dist/modules/catalog/events.js.map +0 -7
- package/dist/modules/customers/events.js +0 -49
- package/dist/modules/customers/events.js.map +0 -7
- package/dist/modules/directory/events.js +0 -23
- package/dist/modules/directory/events.js.map +0 -7
- package/dist/modules/sales/events.js +0 -63
- package/dist/modules/sales/events.js.map +0 -7
- package/dist/modules/sales/lib/frontend/documentDataEvents.js +0 -25
- package/dist/modules/sales/lib/frontend/documentDataEvents.js.map +0 -7
- package/dist/modules/workflows/components/DefinitionTriggersEditor.js +0 -481
- package/dist/modules/workflows/components/DefinitionTriggersEditor.js.map +0 -7
- package/dist/modules/workflows/components/EventTriggersEditor.js +0 -553
- package/dist/modules/workflows/components/EventTriggersEditor.js.map +0 -7
- package/dist/modules/workflows/events.js +0 -38
- package/dist/modules/workflows/events.js.map +0 -7
- package/dist/modules/workflows/examples/order-approval-definition.json +0 -257
- package/dist/modules/workflows/examples/order-approval-guard-rules.json +0 -32
- package/dist/modules/workflows/lib/event-trigger-service.js +0 -308
- package/dist/modules/workflows/lib/event-trigger-service.js.map +0 -7
- package/dist/modules/workflows/migrations/Migration20260123143500.js +0 -36
- package/dist/modules/workflows/migrations/Migration20260123143500.js.map +0 -7
- package/dist/modules/workflows/subscribers/event-trigger.js +0 -78
- package/dist/modules/workflows/subscribers/event-trigger.js.map +0 -7
- package/dist/modules/workflows/widgets/injection/order-approval/widget.client.js +0 -323
- package/dist/modules/workflows/widgets/injection/order-approval/widget.client.js.map +0 -7
- package/dist/modules/workflows/widgets/injection/order-approval/widget.js +0 -17
- package/dist/modules/workflows/widgets/injection/order-approval/widget.js.map +0 -7
- package/dist/modules/workflows/widgets/injection-table.js +0 -19
- package/dist/modules/workflows/widgets/injection-table.js.map +0 -7
- package/generated/entities/workflow_event_trigger/index.ts +0 -15
- package/src/modules/auth/events.ts +0 -39
- package/src/modules/business_rules/api/execute/[ruleId]/route.ts +0 -163
- package/src/modules/catalog/events.ts +0 -45
- package/src/modules/customers/events.ts +0 -63
- package/src/modules/directory/events.ts +0 -31
- package/src/modules/sales/events.ts +0 -82
- package/src/modules/sales/lib/frontend/documentDataEvents.ts +0 -28
- package/src/modules/workflows/components/DefinitionTriggersEditor.tsx +0 -581
- package/src/modules/workflows/components/EventTriggersEditor.tsx +0 -664
- package/src/modules/workflows/events.ts +0 -49
- package/src/modules/workflows/examples/order-approval-definition.json +0 -257
- package/src/modules/workflows/examples/order-approval-guard-rules.json +0 -32
- package/src/modules/workflows/lib/event-trigger-service.ts +0 -557
- package/src/modules/workflows/migrations/Migration20260123143500.ts +0 -38
- package/src/modules/workflows/subscribers/event-trigger.ts +0 -109
- package/src/modules/workflows/widgets/injection/order-approval/widget.client.tsx +0 -446
- package/src/modules/workflows/widgets/injection/order-approval/widget.ts +0 -16
- package/src/modules/workflows/widgets/injection-table.ts +0 -21
|
@@ -7,8 +7,6 @@ import checkoutDemoDefinition from '../examples/checkout-demo-definition.json'
|
|
|
7
7
|
import guardRulesExample from '../examples/guard-rules-example.json'
|
|
8
8
|
import salesPipelineDefinition from '../examples/sales-pipeline-definition.json'
|
|
9
9
|
import simpleApprovalDefinition from '../examples/simple-approval-definition.json'
|
|
10
|
-
import orderApprovalDefinition from '../examples/order-approval-definition.json'
|
|
11
|
-
import orderApprovalGuardRules from '../examples/order-approval-guard-rules.json'
|
|
12
10
|
|
|
13
11
|
export type WorkflowSeedScope = { tenantId: string; organizationId: string }
|
|
14
12
|
|
|
@@ -53,8 +51,6 @@ const embeddedSeeds: Record<string, unknown> = {
|
|
|
53
51
|
'guard-rules-example.json': guardRulesExample,
|
|
54
52
|
'sales-pipeline-definition.json': salesPipelineDefinition,
|
|
55
53
|
'simple-approval-definition.json': simpleApprovalDefinition,
|
|
56
|
-
'order-approval-definition.json': orderApprovalDefinition,
|
|
57
|
-
'order-approval-guard-rules.json': orderApprovalGuardRules,
|
|
58
54
|
}
|
|
59
55
|
|
|
60
56
|
function readExampleJson<T>(fileName: string): T {
|
|
@@ -94,35 +90,16 @@ async function seedWorkflowDefinition(
|
|
|
94
90
|
})
|
|
95
91
|
|
|
96
92
|
if (existing) {
|
|
97
|
-
// Check if the definition needs to be updated
|
|
98
|
-
const seedStepCount = seed.definition.steps.length
|
|
99
|
-
const existingStepCount = existing.definition.steps.length
|
|
100
|
-
const seedTransitionCount = seed.definition.transitions.length
|
|
101
|
-
const existingTransitionCount = existing.definition.transitions.length
|
|
102
|
-
|
|
103
|
-
// Check for preConditions on transitions
|
|
104
|
-
const seedHasTransitionPreConditions = seed.definition.transitions.some(
|
|
105
|
-
(t: any) => t.preConditions && t.preConditions.length > 0
|
|
106
|
-
)
|
|
107
|
-
const existingHasTransitionPreConditions = existing.definition.transitions.some(
|
|
108
|
-
(t: any) => t.preConditions && t.preConditions.length > 0
|
|
109
|
-
)
|
|
110
|
-
|
|
111
|
-
// Check for preConditions on START step
|
|
93
|
+
// Check if the definition needs to be updated (e.g., missing preConditions on START step)
|
|
112
94
|
const seedStartStep = seed.definition.steps.find((s: any) => s.stepType === 'START')
|
|
113
95
|
const existingStartStep = existing.definition.steps.find((s: any) => s.stepType === 'START')
|
|
114
|
-
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
(seedHasStartPreConditions && !existingHasStartPreConditions) ||
|
|
122
|
-
(seedHasTransitionPreConditions && !existingHasTransitionPreConditions)
|
|
123
|
-
|
|
124
|
-
if (needsUpdate) {
|
|
125
|
-
console.log(`[seed] Updating workflow ${workflowId} (steps: ${existingStepCount}→${seedStepCount}, transitions: ${existingTransitionCount}→${seedTransitionCount})`)
|
|
96
|
+
|
|
97
|
+
const seedHasPreConditions = seedStartStep?.preConditions && seedStartStep.preConditions.length > 0
|
|
98
|
+
const existingHasPreConditions = existingStartStep?.preConditions && existingStartStep.preConditions.length > 0
|
|
99
|
+
|
|
100
|
+
// Update if seed has preConditions but existing doesn't
|
|
101
|
+
if (seedHasPreConditions && !existingHasPreConditions) {
|
|
102
|
+
console.log(`[seed] Updating workflow ${workflowId} with preConditions`)
|
|
126
103
|
existing.definition = seed.definition
|
|
127
104
|
await em.flush()
|
|
128
105
|
return true
|
|
@@ -195,7 +172,4 @@ export async function seedExampleWorkflows(em: EntityManager, scope: WorkflowSee
|
|
|
195
172
|
await seedGuardRules(em, scope, 'guard-rules-example.json')
|
|
196
173
|
await seedWorkflowDefinition(em, scope, 'sales-pipeline-definition.json')
|
|
197
174
|
await seedWorkflowDefinition(em, scope, 'simple-approval-definition.json')
|
|
198
|
-
// Seed order approval guard rules before the workflow definition
|
|
199
|
-
await seedGuardRules(em, scope, 'order-approval-guard-rules.json')
|
|
200
|
-
await seedWorkflowDefinition(em, scope, 'order-approval-definition.json')
|
|
201
175
|
}
|
|
@@ -128,69 +128,59 @@ export async function validateWorkflowStart(
|
|
|
128
128
|
const validatedRules: ValidatedRule[] = []
|
|
129
129
|
|
|
130
130
|
for (const condition of preConditions) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
131
|
+
const ruleContext: ruleEngine.RuleEngineContext = {
|
|
132
|
+
entityType: `workflow:${workflowId}:start`,
|
|
133
|
+
entityId: 'pre_start_validation',
|
|
134
|
+
eventType: 'validate_start',
|
|
134
135
|
data: {
|
|
135
136
|
workflowId,
|
|
136
137
|
workflowContext: context,
|
|
137
138
|
},
|
|
138
139
|
tenantId,
|
|
139
140
|
organizationId,
|
|
140
|
-
entityType: `workflow:${workflowId}:start`,
|
|
141
|
-
entityId: 'pre_start_validation',
|
|
142
|
-
eventType: 'validate_start',
|
|
143
141
|
dryRun: true, // Don't log execution during validation
|
|
144
|
-
}
|
|
142
|
+
}
|
|
145
143
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
144
|
+
// Find applicable rules for this context
|
|
145
|
+
const rules = await ruleEngine.findApplicableRules(em, {
|
|
146
|
+
entityType: ruleContext.entityType,
|
|
147
|
+
eventType: ruleContext.eventType,
|
|
148
|
+
tenantId,
|
|
149
|
+
organizationId,
|
|
150
|
+
ruleType: 'GUARD',
|
|
150
151
|
})
|
|
151
152
|
|
|
152
|
-
|
|
153
|
-
|
|
153
|
+
const rule = rules.find(r => r.ruleId === condition.ruleId)
|
|
154
|
+
|
|
155
|
+
if (!rule) {
|
|
156
|
+
// Rule not found - if required, this is an error
|
|
154
157
|
if (condition.required) {
|
|
155
158
|
errors.push({
|
|
156
159
|
ruleId: condition.ruleId,
|
|
157
|
-
message: getLocalizedMessage(condition, null, locale, `Business rule
|
|
160
|
+
message: getLocalizedMessage(condition, null, locale, `Business rule '${condition.ruleId}' not found`),
|
|
158
161
|
code: 'RULE_NOT_FOUND',
|
|
159
162
|
})
|
|
163
|
+
validatedRules.push({ ruleId: condition.ruleId, passed: false })
|
|
160
164
|
}
|
|
161
165
|
continue
|
|
162
166
|
}
|
|
163
167
|
|
|
164
|
-
//
|
|
165
|
-
|
|
166
|
-
if (condition.required) {
|
|
167
|
-
errors.push({
|
|
168
|
-
ruleId: condition.ruleId,
|
|
169
|
-
message: getLocalizedMessage(condition, null, locale, `Business rule is disabled: ${result.ruleName}`),
|
|
170
|
-
code: 'RULE_DISABLED',
|
|
171
|
-
})
|
|
172
|
-
}
|
|
173
|
-
continue
|
|
174
|
-
}
|
|
168
|
+
// Execute the single rule
|
|
169
|
+
const result = await ruleEngine.executeSingleRule(em, rule, ruleContext)
|
|
175
170
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
code: 'RULE_ERROR',
|
|
182
|
-
})
|
|
183
|
-
continue
|
|
184
|
-
}
|
|
171
|
+
validatedRules.push({
|
|
172
|
+
ruleId: condition.ruleId,
|
|
173
|
+
passed: result.conditionResult,
|
|
174
|
+
executionTime: result.executionTime,
|
|
175
|
+
})
|
|
185
176
|
|
|
186
|
-
// Handle condition failure
|
|
187
177
|
if (!result.conditionResult && condition.required) {
|
|
188
|
-
// Get localized message from condition
|
|
178
|
+
// Get localized message from condition, rule failure actions, or default
|
|
189
179
|
const message = getLocalizedMessage(
|
|
190
180
|
condition,
|
|
191
|
-
|
|
181
|
+
rule,
|
|
192
182
|
locale,
|
|
193
|
-
`Pre-condition '${
|
|
183
|
+
`Pre-condition '${rule.ruleName || condition.ruleId}' failed`
|
|
194
184
|
)
|
|
195
185
|
errors.push({
|
|
196
186
|
ruleId: condition.ruleId,
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
} from '../data/entities'
|
|
20
20
|
import * as ruleEvaluator from '../../business_rules/lib/rule-evaluator'
|
|
21
21
|
import * as ruleEngine from '../../business_rules/lib/rule-engine'
|
|
22
|
+
import type { RuleEngineContext } from '../../business_rules/lib/rule-engine'
|
|
22
23
|
import * as activityExecutor from './activity-executor'
|
|
23
24
|
import type { ActivityDefinition } from './activity-executor'
|
|
24
25
|
import * as stepHandler from './step-handler'
|
|
@@ -193,15 +194,11 @@ export async function evaluateTransition(
|
|
|
193
194
|
/**
|
|
194
195
|
* Find all valid transitions from current step
|
|
195
196
|
*
|
|
196
|
-
* This function evaluates both inline conditions AND preConditions (business rules)
|
|
197
|
-
* to determine which transitions are truly valid. This is important for decision
|
|
198
|
-
* branching where multiple transitions exist with different preConditions.
|
|
199
|
-
*
|
|
200
197
|
* @param em - Entity manager
|
|
201
198
|
* @param instance - Workflow instance
|
|
202
199
|
* @param fromStepId - Current step ID
|
|
203
200
|
* @param context - Evaluation context
|
|
204
|
-
* @returns Array of evaluation results for all transitions
|
|
201
|
+
* @returns Array of evaluation results for all transitions
|
|
205
202
|
*/
|
|
206
203
|
export async function findValidTransitions(
|
|
207
204
|
em: EntityManager,
|
|
@@ -219,17 +216,16 @@ export async function findValidTransitions(
|
|
|
219
216
|
return []
|
|
220
217
|
}
|
|
221
218
|
|
|
222
|
-
// Find all transitions from current step
|
|
223
|
-
const transitions = (definition.definition.transitions || [])
|
|
224
|
-
|
|
225
|
-
|
|
219
|
+
// Find all transitions from current step
|
|
220
|
+
const transitions = (definition.definition.transitions || []).filter(
|
|
221
|
+
(t: any) => t.fromStepId === fromStepId
|
|
222
|
+
)
|
|
226
223
|
|
|
227
|
-
// Evaluate each transition
|
|
224
|
+
// Evaluate each transition
|
|
228
225
|
const results: TransitionEvaluationResult[] = []
|
|
229
226
|
|
|
230
227
|
for (const transition of transitions) {
|
|
231
|
-
|
|
232
|
-
const conditionResult = await evaluateTransition(
|
|
228
|
+
const result = await evaluateTransition(
|
|
233
229
|
em,
|
|
234
230
|
instance,
|
|
235
231
|
fromStepId,
|
|
@@ -237,42 +233,7 @@ export async function findValidTransitions(
|
|
|
237
233
|
context
|
|
238
234
|
)
|
|
239
235
|
|
|
240
|
-
|
|
241
|
-
results.push(conditionResult)
|
|
242
|
-
continue
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// Also evaluate preConditions if they exist
|
|
246
|
-
const preConditions = transition.preConditions || []
|
|
247
|
-
if (preConditions.length > 0) {
|
|
248
|
-
const preConditionsResult = await evaluatePreConditions(
|
|
249
|
-
em,
|
|
250
|
-
instance,
|
|
251
|
-
transition,
|
|
252
|
-
context as TransitionExecutionContext
|
|
253
|
-
)
|
|
254
|
-
|
|
255
|
-
if (!preConditionsResult.allowed) {
|
|
256
|
-
// Transition is invalid due to preConditions
|
|
257
|
-
const failedRules = preConditionsResult.executedRules
|
|
258
|
-
.filter((r) => !r.conditionResult)
|
|
259
|
-
.map((r) => r.rule.ruleId || r.rule.ruleName)
|
|
260
|
-
|
|
261
|
-
results.push({
|
|
262
|
-
isValid: false,
|
|
263
|
-
transition,
|
|
264
|
-
reason: `Pre-conditions failed: ${failedRules.join(', ')}`,
|
|
265
|
-
failedConditions: failedRules,
|
|
266
|
-
})
|
|
267
|
-
continue
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
// Transition is valid (both condition and preConditions passed)
|
|
272
|
-
results.push({
|
|
273
|
-
...conditionResult,
|
|
274
|
-
transition,
|
|
275
|
-
})
|
|
236
|
+
results.push(result)
|
|
276
237
|
}
|
|
277
238
|
|
|
278
239
|
return results
|
|
@@ -688,10 +649,6 @@ async function evaluateTransitionConditions(
|
|
|
688
649
|
* Pre-conditions are GUARD rules that must pass before transition can execute.
|
|
689
650
|
* If any GUARD rule fails, the transition is blocked.
|
|
690
651
|
*
|
|
691
|
-
* If the transition defines specific preConditions with ruleIds, those are
|
|
692
|
-
* executed directly via executeRuleByRuleId. Otherwise, falls back to
|
|
693
|
-
* discovery-based execution via executeRules.
|
|
694
|
-
*
|
|
695
652
|
* @param em - Entity manager
|
|
696
653
|
* @param instance - Workflow instance
|
|
697
654
|
* @param transition - Transition definition
|
|
@@ -718,88 +675,32 @@ async function evaluatePreConditions(
|
|
|
718
675
|
}
|
|
719
676
|
}
|
|
720
677
|
|
|
721
|
-
//
|
|
722
|
-
const
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
const startTime = Date.now()
|
|
735
|
-
const executedRules: ruleEngine.RuleExecutionResult[] = []
|
|
736
|
-
const errors: string[] = []
|
|
737
|
-
let allowed = true
|
|
738
|
-
|
|
739
|
-
for (const condition of preConditions) {
|
|
740
|
-
const result = await ruleEngine.executeRuleByRuleId(em, {
|
|
741
|
-
ruleId: condition.ruleId, // String identifier
|
|
742
|
-
data: {
|
|
743
|
-
workflowInstanceId: instance.id,
|
|
744
|
-
workflowId: definition.workflowId,
|
|
745
|
-
fromStepId: transition.fromStepId,
|
|
746
|
-
toStepId: transition.toStepId,
|
|
747
|
-
workflowContext: {
|
|
748
|
-
...instance.context,
|
|
749
|
-
...context.workflowContext,
|
|
750
|
-
},
|
|
751
|
-
triggerData: context.triggerData,
|
|
678
|
+
// Build rule engine context
|
|
679
|
+
const ruleContext: RuleEngineContext = {
|
|
680
|
+
entityType: `workflow:${definition.workflowId}:transition`,
|
|
681
|
+
entityId: transition.transitionId || `${transition.fromStepId}->${transition.toStepId}`,
|
|
682
|
+
eventType: 'pre_transition',
|
|
683
|
+
data: {
|
|
684
|
+
workflowInstanceId: instance.id,
|
|
685
|
+
workflowId: definition.workflowId,
|
|
686
|
+
fromStepId: transition.fromStepId,
|
|
687
|
+
toStepId: transition.toStepId,
|
|
688
|
+
workflowContext: {
|
|
689
|
+
...instance.context,
|
|
690
|
+
...context.workflowContext,
|
|
752
691
|
},
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
eventType: 'pre_transition',
|
|
760
|
-
})
|
|
761
|
-
|
|
762
|
-
// Create a compatible RuleExecutionResult for tracking
|
|
763
|
-
// We don't have the full BusinessRule entity, but we can create a partial result
|
|
764
|
-
const ruleResult: ruleEngine.RuleExecutionResult = {
|
|
765
|
-
rule: {
|
|
766
|
-
ruleId: result.ruleId,
|
|
767
|
-
ruleName: result.ruleName,
|
|
768
|
-
ruleType: 'GUARD',
|
|
769
|
-
} as any,
|
|
770
|
-
conditionResult: result.conditionResult,
|
|
771
|
-
actionsExecuted: result.actionsExecuted,
|
|
772
|
-
executionTime: result.executionTime,
|
|
773
|
-
error: result.error,
|
|
774
|
-
logId: result.logId,
|
|
775
|
-
}
|
|
776
|
-
executedRules.push(ruleResult)
|
|
777
|
-
|
|
778
|
-
// Handle rule errors
|
|
779
|
-
if (result.error) {
|
|
780
|
-
// Rule not found, disabled, or other errors
|
|
781
|
-
const isRequired = condition.required !== false // Default to required
|
|
782
|
-
if (isRequired) {
|
|
783
|
-
allowed = false
|
|
784
|
-
errors.push(`Rule '${result.ruleId}': ${result.error}`)
|
|
785
|
-
}
|
|
786
|
-
continue
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
// If required and condition failed, block transition
|
|
790
|
-
const isRequired = condition.required !== false // Default to required
|
|
791
|
-
if (isRequired && !result.conditionResult) {
|
|
792
|
-
allowed = false
|
|
793
|
-
errors.push(`Pre-condition '${result.ruleName || result.ruleId}' failed`)
|
|
794
|
-
}
|
|
692
|
+
triggerData: context.triggerData,
|
|
693
|
+
},
|
|
694
|
+
user: context.userId ? { id: context.userId } : undefined,
|
|
695
|
+
tenantId: instance.tenantId,
|
|
696
|
+
organizationId: instance.organizationId,
|
|
697
|
+
executedBy: context.userId,
|
|
795
698
|
}
|
|
796
699
|
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
errors: errors.length > 0 ? errors : undefined,
|
|
802
|
-
}
|
|
700
|
+
// Execute rules - only GUARD rules will affect the 'allowed' status
|
|
701
|
+
const result = await ruleEngine.executeRules(em, ruleContext)
|
|
702
|
+
|
|
703
|
+
return result
|
|
803
704
|
} catch (error) {
|
|
804
705
|
console.error('Error evaluating pre-conditions:', error)
|
|
805
706
|
return {
|
|
@@ -817,9 +718,6 @@ async function evaluatePreConditions(
|
|
|
817
718
|
* Post-conditions are GUARD rules that should pass after transition executes.
|
|
818
719
|
* Unlike pre-conditions, post-condition failures are logged but don't block the transition.
|
|
819
720
|
*
|
|
820
|
-
* If the transition defines specific postConditions with ruleIds, those are
|
|
821
|
-
* executed directly via executeRuleByRuleId. Otherwise, returns allowed: true.
|
|
822
|
-
*
|
|
823
721
|
* @param em - Entity manager
|
|
824
722
|
* @param instance - Workflow instance
|
|
825
723
|
* @param transition - Transition definition
|
|
@@ -846,83 +744,32 @@ async function evaluatePostConditions(
|
|
|
846
744
|
}
|
|
847
745
|
}
|
|
848
746
|
|
|
849
|
-
//
|
|
850
|
-
const
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
const startTime = Date.now()
|
|
863
|
-
const executedRules: ruleEngine.RuleExecutionResult[] = []
|
|
864
|
-
const errors: string[] = []
|
|
865
|
-
let allowed = true
|
|
866
|
-
|
|
867
|
-
for (const condition of postConditions) {
|
|
868
|
-
const result = await ruleEngine.executeRuleByRuleId(em, {
|
|
869
|
-
ruleId: condition.ruleId, // String identifier
|
|
870
|
-
data: {
|
|
871
|
-
workflowInstanceId: instance.id,
|
|
872
|
-
workflowId: definition.workflowId,
|
|
873
|
-
fromStepId: transition.fromStepId,
|
|
874
|
-
toStepId: transition.toStepId,
|
|
875
|
-
workflowContext: {
|
|
876
|
-
...instance.context,
|
|
877
|
-
...context.workflowContext,
|
|
878
|
-
},
|
|
879
|
-
triggerData: context.triggerData,
|
|
747
|
+
// Build rule engine context
|
|
748
|
+
const ruleContext: RuleEngineContext = {
|
|
749
|
+
entityType: `workflow:${definition.workflowId}:transition`,
|
|
750
|
+
entityId: transition.transitionId || `${transition.fromStepId}->${transition.toStepId}`,
|
|
751
|
+
eventType: 'post_transition',
|
|
752
|
+
data: {
|
|
753
|
+
workflowInstanceId: instance.id,
|
|
754
|
+
workflowId: definition.workflowId,
|
|
755
|
+
fromStepId: transition.fromStepId,
|
|
756
|
+
toStepId: transition.toStepId,
|
|
757
|
+
workflowContext: {
|
|
758
|
+
...instance.context,
|
|
759
|
+
...context.workflowContext,
|
|
880
760
|
},
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
eventType: 'post_transition',
|
|
888
|
-
})
|
|
889
|
-
|
|
890
|
-
// Create a compatible RuleExecutionResult for tracking
|
|
891
|
-
const ruleResult: ruleEngine.RuleExecutionResult = {
|
|
892
|
-
rule: {
|
|
893
|
-
ruleId: result.ruleId,
|
|
894
|
-
ruleName: result.ruleName,
|
|
895
|
-
ruleType: 'GUARD',
|
|
896
|
-
} as any,
|
|
897
|
-
conditionResult: result.conditionResult,
|
|
898
|
-
actionsExecuted: result.actionsExecuted,
|
|
899
|
-
executionTime: result.executionTime,
|
|
900
|
-
error: result.error,
|
|
901
|
-
logId: result.logId,
|
|
902
|
-
}
|
|
903
|
-
executedRules.push(ruleResult)
|
|
904
|
-
|
|
905
|
-
// Handle rule errors
|
|
906
|
-
if (result.error) {
|
|
907
|
-
errors.push(`Rule '${result.ruleId}': ${result.error}`)
|
|
908
|
-
// Post-conditions don't block, but track the failure
|
|
909
|
-
allowed = false
|
|
910
|
-
continue
|
|
911
|
-
}
|
|
912
|
-
|
|
913
|
-
// Track condition failures (post-conditions are warnings, not blockers)
|
|
914
|
-
if (!result.conditionResult) {
|
|
915
|
-
allowed = false
|
|
916
|
-
errors.push(`Post-condition '${result.ruleName || result.ruleId}' failed`)
|
|
917
|
-
}
|
|
761
|
+
triggerData: context.triggerData,
|
|
762
|
+
},
|
|
763
|
+
user: context.userId ? { id: context.userId } : undefined,
|
|
764
|
+
tenantId: instance.tenantId,
|
|
765
|
+
organizationId: instance.organizationId,
|
|
766
|
+
executedBy: context.userId,
|
|
918
767
|
}
|
|
919
768
|
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
errors: errors.length > 0 ? errors : undefined,
|
|
925
|
-
}
|
|
769
|
+
// Execute rules
|
|
770
|
+
const result = await ruleEngine.executeRules(em, ruleContext)
|
|
771
|
+
|
|
772
|
+
return result
|
|
926
773
|
} catch (error) {
|
|
927
774
|
console.error('Error evaluating post-conditions:', error)
|
|
928
775
|
return {
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
const id = "id";
|
|
2
|
-
const name = "name";
|
|
3
|
-
const description = "description";
|
|
4
|
-
const workflow_definition_id = "workflow_definition_id";
|
|
5
|
-
const event_pattern = "event_pattern";
|
|
6
|
-
const config = "config";
|
|
7
|
-
const enabled = "enabled";
|
|
8
|
-
const priority = "priority";
|
|
9
|
-
const tenant_id = "tenant_id";
|
|
10
|
-
const organization_id = "organization_id";
|
|
11
|
-
const created_by = "created_by";
|
|
12
|
-
const updated_by = "updated_by";
|
|
13
|
-
const created_at = "created_at";
|
|
14
|
-
const updated_at = "updated_at";
|
|
15
|
-
const deleted_at = "deleted_at";
|
|
16
|
-
export {
|
|
17
|
-
config,
|
|
18
|
-
created_at,
|
|
19
|
-
created_by,
|
|
20
|
-
deleted_at,
|
|
21
|
-
description,
|
|
22
|
-
enabled,
|
|
23
|
-
event_pattern,
|
|
24
|
-
id,
|
|
25
|
-
name,
|
|
26
|
-
organization_id,
|
|
27
|
-
priority,
|
|
28
|
-
tenant_id,
|
|
29
|
-
updated_at,
|
|
30
|
-
updated_by,
|
|
31
|
-
workflow_definition_id
|
|
32
|
-
};
|
|
33
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../../generated/entities/workflow_event_trigger/index.ts"],
|
|
4
|
-
"sourcesContent": ["export const id = 'id'\nexport const name = 'name'\nexport const description = 'description'\nexport const workflow_definition_id = 'workflow_definition_id'\nexport const event_pattern = 'event_pattern'\nexport const config = 'config'\nexport const enabled = 'enabled'\nexport const priority = 'priority'\nexport const tenant_id = 'tenant_id'\nexport const organization_id = 'organization_id'\nexport const created_by = 'created_by'\nexport const updated_by = 'updated_by'\nexport const created_at = 'created_at'\nexport const updated_at = 'updated_at'\nexport const deleted_at = 'deleted_at'\n"],
|
|
5
|
-
"mappings": "AAAO,MAAM,KAAK;AACX,MAAM,OAAO;AACb,MAAM,cAAc;AACpB,MAAM,yBAAyB;AAC/B,MAAM,gBAAgB;AACtB,MAAM,SAAS;AACf,MAAM,UAAU;AAChB,MAAM,WAAW;AACjB,MAAM,YAAY;AAClB,MAAM,kBAAkB;AACxB,MAAM,aAAa;AACnB,MAAM,aAAa;AACnB,MAAM,aAAa;AACnB,MAAM,aAAa;AACnB,MAAM,aAAa;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { createModuleEvents } from "@open-mercato/shared/modules/events";
|
|
2
|
-
const events = [
|
|
3
|
-
// Users
|
|
4
|
-
{ id: "auth.users.created", label: "User Created", entity: "users", category: "crud" },
|
|
5
|
-
{ id: "auth.users.updated", label: "User Updated", entity: "users", category: "crud" },
|
|
6
|
-
{ id: "auth.users.deleted", label: "User Deleted", entity: "users", category: "crud" },
|
|
7
|
-
// Roles
|
|
8
|
-
{ id: "auth.roles.created", label: "Role Created", entity: "roles", category: "crud" },
|
|
9
|
-
{ id: "auth.roles.updated", label: "Role Updated", entity: "roles", category: "crud" },
|
|
10
|
-
{ id: "auth.roles.deleted", label: "Role Deleted", entity: "roles", category: "crud" },
|
|
11
|
-
// Authentication events
|
|
12
|
-
{ id: "auth.login.success", label: "Login Successful", category: "lifecycle" },
|
|
13
|
-
{ id: "auth.login.failed", label: "Login Failed", category: "lifecycle" },
|
|
14
|
-
{ id: "auth.logout", label: "User Logged Out", category: "lifecycle" },
|
|
15
|
-
{ id: "auth.password.changed", label: "Password Changed", category: "lifecycle" },
|
|
16
|
-
{ id: "auth.password.reset.requested", label: "Password Reset Requested", category: "lifecycle" },
|
|
17
|
-
{ id: "auth.password.reset.completed", label: "Password Reset Completed", category: "lifecycle" }
|
|
18
|
-
];
|
|
19
|
-
const eventsConfig = createModuleEvents({
|
|
20
|
-
moduleId: "auth",
|
|
21
|
-
events
|
|
22
|
-
});
|
|
23
|
-
const emitAuthEvent = eventsConfig.emit;
|
|
24
|
-
var events_default = eventsConfig;
|
|
25
|
-
export {
|
|
26
|
-
events_default as default,
|
|
27
|
-
emitAuthEvent,
|
|
28
|
-
eventsConfig
|
|
29
|
-
};
|
|
30
|
-
//# sourceMappingURL=events.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/modules/auth/events.ts"],
|
|
4
|
-
"sourcesContent": ["import { createModuleEvents } from '@open-mercato/shared/modules/events'\n\n/**\n * Auth Module Events\n *\n * Declares all events that can be emitted by the auth module.\n */\nconst events = [\n // Users\n { id: 'auth.users.created', label: 'User Created', entity: 'users', category: 'crud' },\n { id: 'auth.users.updated', label: 'User Updated', entity: 'users', category: 'crud' },\n { id: 'auth.users.deleted', label: 'User Deleted', entity: 'users', category: 'crud' },\n\n // Roles\n { id: 'auth.roles.created', label: 'Role Created', entity: 'roles', category: 'crud' },\n { id: 'auth.roles.updated', label: 'Role Updated', entity: 'roles', category: 'crud' },\n { id: 'auth.roles.deleted', label: 'Role Deleted', entity: 'roles', category: 'crud' },\n\n // Authentication events\n { id: 'auth.login.success', label: 'Login Successful', category: 'lifecycle' },\n { id: 'auth.login.failed', label: 'Login Failed', category: 'lifecycle' },\n { id: 'auth.logout', label: 'User Logged Out', category: 'lifecycle' },\n { id: 'auth.password.changed', label: 'Password Changed', category: 'lifecycle' },\n { id: 'auth.password.reset.requested', label: 'Password Reset Requested', category: 'lifecycle' },\n { id: 'auth.password.reset.completed', label: 'Password Reset Completed', category: 'lifecycle' },\n] as const\n\nexport const eventsConfig = createModuleEvents({\n moduleId: 'auth',\n events,\n})\n\n/** Type-safe event emitter for auth module */\nexport const emitAuthEvent = eventsConfig.emit\n\n/** Event IDs that can be emitted by the auth module */\nexport type AuthEventId = typeof events[number]['id']\n\nexport default eventsConfig\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,0BAA0B;AAOnC,MAAM,SAAS;AAAA;AAAA,EAEb,EAAE,IAAI,sBAAsB,OAAO,gBAAgB,QAAQ,SAAS,UAAU,OAAO;AAAA,EACrF,EAAE,IAAI,sBAAsB,OAAO,gBAAgB,QAAQ,SAAS,UAAU,OAAO;AAAA,EACrF,EAAE,IAAI,sBAAsB,OAAO,gBAAgB,QAAQ,SAAS,UAAU,OAAO;AAAA;AAAA,EAGrF,EAAE,IAAI,sBAAsB,OAAO,gBAAgB,QAAQ,SAAS,UAAU,OAAO;AAAA,EACrF,EAAE,IAAI,sBAAsB,OAAO,gBAAgB,QAAQ,SAAS,UAAU,OAAO;AAAA,EACrF,EAAE,IAAI,sBAAsB,OAAO,gBAAgB,QAAQ,SAAS,UAAU,OAAO;AAAA;AAAA,EAGrF,EAAE,IAAI,sBAAsB,OAAO,oBAAoB,UAAU,YAAY;AAAA,EAC7E,EAAE,IAAI,qBAAqB,OAAO,gBAAgB,UAAU,YAAY;AAAA,EACxE,EAAE,IAAI,eAAe,OAAO,mBAAmB,UAAU,YAAY;AAAA,EACrE,EAAE,IAAI,yBAAyB,OAAO,oBAAoB,UAAU,YAAY;AAAA,EAChF,EAAE,IAAI,iCAAiC,OAAO,4BAA4B,UAAU,YAAY;AAAA,EAChG,EAAE,IAAI,iCAAiC,OAAO,4BAA4B,UAAU,YAAY;AAClG;AAEO,MAAM,eAAe,mBAAmB;AAAA,EAC7C,UAAU;AAAA,EACV;AACF,CAAC;AAGM,MAAM,gBAAgB,aAAa;AAK1C,IAAO,iBAAQ;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|