@acorex/connectivity 20.7.11 → 20.7.13

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.
@@ -22,7 +22,7 @@ import { AXMPermissionsKeys as AXMPermissionsKeys$3, AXMFolderServiceImpl, AXMDo
22
22
  import { AXMSettingsManagementPermissionKeys } from '@acorex/modules/settings-management';
23
23
  import { RootConfig as RootConfig$6 } from '@acorex/modules/business-core';
24
24
  import { RootConfig as RootConfig$7 } from '@acorex/modules/calendar-management';
25
- import { AXPActivityDefinitionService, AXP_WORKFLOW_PROVIDER, AXP_WORKFLOW_ENGINE, AXPWorkflowManager, AXPWorkflowDefinitionService, AXP_WORKFLOW_CATEGORY_PROVIDER } from '@acorex/platform/workflow';
25
+ import { AXPActivityDefinitionService, AXP_WORKFLOW_PROVIDER, AXP_WORKFLOW_ENGINE, AXP_WORKFLOW_CATEGORY_PROVIDER } from '@acorex/platform/workflow';
26
26
  import Dexie from 'dexie';
27
27
  import { AXFileService } from '@acorex/core/file';
28
28
  import { RootConfig as RootConfig$8 } from '@acorex/modules/contact-management';
@@ -18467,21 +18467,29 @@ const DOCUMENT_TYPES = [
18467
18467
  enableVersioning: true,
18468
18468
  enableExpiration: false,
18469
18469
  requiresReview: true,
18470
- metaDataList: [
18471
- {
18472
- id: AXPDataGenerator.uuid(),
18473
- text: 'Description',
18474
- // "parentId": "9e3c7586-4722-4170-bc55-e612ca2ab4b5",
18475
- hasCheckbox: true,
18476
- isSelected: true,
18477
- interface: '{"type":"text-editor","name":"description-editor1","meta":{"header":true},"options":{"multiple":false,"disabled":false,"hasClearButton":false},"defaultValue":"","path":"description"}',
18478
- name: 'description',
18479
- title: 'Description',
18480
- isRequired: true,
18481
- placeholder: '',
18482
- status: 'active',
18483
- },
18484
- ],
18470
+ metaDataList: {
18471
+ groups: [
18472
+ {
18473
+ name: 'default',
18474
+ title: 'Metadata',
18475
+ order: 0,
18476
+ fields: [
18477
+ {
18478
+ id: AXPDataGenerator.uuid(),
18479
+ text: 'Description',
18480
+ hasCheckbox: true,
18481
+ isSelected: true,
18482
+ interface: '{"type":"text-editor","name":"description-editor1","meta":{"header":true},"options":{"multiple":false,"disabled":false,"hasClearButton":false},"defaultValue":"","path":"description"}',
18483
+ name: 'description',
18484
+ title: 'Description',
18485
+ isRequired: true,
18486
+ placeholder: '',
18487
+ status: 'active',
18488
+ },
18489
+ ],
18490
+ },
18491
+ ],
18492
+ },
18485
18493
  type: {
18486
18494
  selectedItems: [
18487
18495
  {
@@ -18521,7 +18529,7 @@ const DOCUMENT_TYPES = [
18521
18529
  enableExpiration: false,
18522
18530
  requiresReview: false,
18523
18531
  control: { isSystem: true },
18524
- metaDataList: [],
18532
+ metaDataList: { groups: [] },
18525
18533
  type: {
18526
18534
  selectedItems: [],
18527
18535
  context: {
@@ -18541,21 +18549,29 @@ const DOCUMENT_TYPES = [
18541
18549
  enableVersioning: true,
18542
18550
  enableExpiration: true,
18543
18551
  requiresReview: true,
18544
- metaDataList: [
18545
- {
18546
- id: AXPDataGenerator.uuid(),
18547
- text: 'Description',
18548
- // "parentId": "9e3c7586-4722-4170-bc55-e612ca2ab4b5",
18549
- hasCheckbox: true,
18550
- isSelected: true,
18551
- interface: '{"type":"text-editor","name":"description-editor1","meta":{"header":true},"options":{"multiple":false,"disabled":false,"hasClearButton":false},"defaultValue":"","path":"description"}',
18552
- name: 'description',
18553
- title: 'Description',
18554
- isRequired: true,
18555
- placeholder: '',
18556
- status: 'active',
18557
- },
18558
- ],
18552
+ metaDataList: {
18553
+ groups: [
18554
+ {
18555
+ name: 'default',
18556
+ title: 'Metadata',
18557
+ order: 0,
18558
+ fields: [
18559
+ {
18560
+ id: AXPDataGenerator.uuid(),
18561
+ text: 'Description',
18562
+ hasCheckbox: true,
18563
+ isSelected: true,
18564
+ interface: '{"type":"text-editor","name":"description-editor1","meta":{"header":true},"options":{"multiple":false,"disabled":false,"hasClearButton":false},"defaultValue":"","path":"description"}',
18565
+ name: 'description',
18566
+ title: 'Description',
18567
+ isRequired: true,
18568
+ placeholder: '',
18569
+ status: 'active',
18570
+ },
18571
+ ],
18572
+ },
18573
+ ],
18574
+ },
18559
18575
  type: {
18560
18576
  selectedItems: [
18561
18577
  {
@@ -50509,318 +50525,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
50509
50525
  type: Injectable
50510
50526
  }] });
50511
50527
 
50512
- /**
50513
- * Workflow Trigger Middleware
50514
- *
50515
- * Automatically starts workflow instances when entity records are created/updated,
50516
- * based on workflow bindings configured in Workflow Management.
50517
- *
50518
- * Architecture:
50519
- * - Entities do NOT choose workflows (no hardcoded workflow names)
50520
- * - Workflows are configured with bindings (entityTypes + eventTypes) in Workflow Management
50521
- * - This middleware detects bindings and starts instances automatically
50522
- * - Plugin "workflow" only marks entity as workflow-capable (capability + UI hooks)
50523
- *
50524
- * Behavior:
50525
- * - Runs AFTER record is successfully persisted (post-create, post-update)
50526
- * - Checks if entity has WORKFLOW plugin enabled (workflow-capable check)
50527
- * - Queries all published workflow definitions with bindings
50528
- * - For each matching binding (entityType + eventType):
50529
- * - Starts workflow instance via workflow engine
50530
- * - Uses correlationId to prevent duplicates: `${entityType}:${recordId}:${workflowName}`
50531
- * - Passes workflow input: { entityType, recordId, eventType, recordData }
50532
- * - If instance already exists (by correlationId), skips (idempotent)
50533
- *
50534
- * Order: 40 (after audit/history middlewares, before other plugins)
50535
- *
50536
- * Location: libs/connectivity/mock/src/lib/workflow-management/middlewares/
50537
- * This is a BACKEND/MOCK middleware that runs in the storage layer.
50538
- */
50539
- const workflowTriggerMiddleware = {
50540
- target: {
50541
- ops: ['create', 'update'], // Support OnCreate and OnUpdate events
50542
- order: 40, // After audit/history (15-20), before other plugins (50+)
50543
- },
50544
- execute: async (ctx, next) => {
50545
- const entityRegistry = inject(AXPEntityDefinitionRegistryService);
50546
- const workflowManager = inject(AXPWorkflowManager);
50547
- const storageService = inject(AXPEntityStorageService);
50548
- const workflowDefinitionService = inject(AXPWorkflowDefinitionService);
50549
- console.log(`[WorkflowTriggerMiddleware] 🔍 Starting workflow trigger check for ${ctx.entityName}:${ctx.op}`);
50550
- console.log(`[WorkflowTriggerMiddleware] 📝 Context details:`, {
50551
- entityName: ctx.entityName,
50552
- op: ctx.op,
50553
- hasData: !!ctx.data,
50554
- dataKeys: ctx.data ? Object.keys(ctx.data) : [],
50555
- });
50556
- // Execute next middleware first to ensure record is persisted
50557
- await next();
50558
- // Only proceed if record was persisted successfully
50559
- if (!ctx.result) {
50560
- console.log(`[WorkflowTriggerMiddleware] ⚠️ No result from ${ctx.op} operation, skipping workflow trigger`);
50561
- return;
50562
- }
50563
- const recordId = ctx.result;
50564
- console.log(`[WorkflowTriggerMiddleware] ✅ Record persisted: ${ctx.entityName}:${recordId}`);
50565
- try {
50566
- // Get entity definition
50567
- const [moduleName, entityName] = ctx.entityName.split('.');
50568
- console.log(`[WorkflowTriggerMiddleware] 📋 Resolving entity definition: ${moduleName}.${entityName}`);
50569
- const entityDef = await entityRegistry.resolve(moduleName, entityName);
50570
- if (!entityDef) {
50571
- console.log(`[WorkflowTriggerMiddleware] ⚠️ Entity definition not found for ${ctx.entityName}`);
50572
- return;
50573
- }
50574
- console.log(`[WorkflowTriggerMiddleware] ✅ Entity definition found, checking plugins...`);
50575
- // Check if entity has WORKFLOW plugin enabled (workflow-capable check)
50576
- const hasWorkflowPlugin = (entityDef.plugins ?? []).some((p) => p.name === 'workflow');
50577
- console.log(`[WorkflowTriggerMiddleware] 🔌 Workflow plugin check: ${hasWorkflowPlugin ? '✅ Enabled' : '❌ Not enabled'}`);
50578
- if (!hasWorkflowPlugin) {
50579
- // Entity is not workflow-capable, skip
50580
- console.log(`[WorkflowTriggerMiddleware] ⏭️ Entity ${ctx.entityName} is not workflow-capable, skipping`);
50581
- return;
50582
- }
50583
- // Use operation directly as event type
50584
- const eventType = ctx.op;
50585
- console.log(`[WorkflowTriggerMiddleware] 📌 Event type: ${eventType}`);
50586
- // Get all workflow definitions from providers (using workflow definition service)
50587
- // We need to get all categories first, then get workflows for each category
50588
- const allWorkflowDefinitions = [];
50589
- console.log(`[WorkflowTriggerMiddleware] 📚 Fetching workflow definitions from providers...`);
50590
- // Get root categories
50591
- const rootCategories = await workflowDefinitionService.getCategories();
50592
- console.log(`[WorkflowTriggerMiddleware] 📁 Found ${rootCategories.length} root categories`);
50593
- // Recursively get workflows from all categories
50594
- const getAllWorkflowsFromCategory = async (categoryId) => {
50595
- const workflows = await workflowDefinitionService.getWorkflowsByCategoryId(categoryId);
50596
- console.log(`[WorkflowTriggerMiddleware] 📄 Category ${categoryId}: ${workflows.length} workflows`);
50597
- allWorkflowDefinitions.push(...workflows);
50598
- // Get child categories and recurse
50599
- const childCategories = await workflowDefinitionService.getCategories(categoryId);
50600
- for (const childCategory of childCategories) {
50601
- await getAllWorkflowsFromCategory(childCategory.id);
50602
- }
50603
- };
50604
- // Start from root categories
50605
- for (const category of rootCategories) {
50606
- await getAllWorkflowsFromCategory(category.id);
50607
- }
50608
- console.log(`[WorkflowTriggerMiddleware] 📚 Total workflows from providers: ${allWorkflowDefinitions.length}`);
50609
- // Get metadata (id, isPublished, isLatest, bindings) from storage service for each workflow
50610
- // Query all workflow definitions from storage to get metadata
50611
- console.log(`[WorkflowTriggerMiddleware] 💾 Querying workflow definitions from storage...`);
50612
- const workflowMetadata = await storageService.query('WorkflowManagement.WorkflowDefinition', {
50613
- filter: {
50614
- field: 'isPublished',
50615
- operator: { type: 'equal' },
50616
- value: true,
50617
- },
50618
- skip: 0,
50619
- take: 1000,
50620
- });
50621
- console.log(`[WorkflowTriggerMiddleware] 💾 Published workflows in storage: ${workflowMetadata.items?.length || 0}`);
50622
- // If no workflows from providers, try to get them from storage
50623
- if (allWorkflowDefinitions.length === 0) {
50624
- console.log(`[WorkflowTriggerMiddleware] ⚠️ No workflows found from providers, checking storage...`);
50625
- if (!workflowMetadata.items || workflowMetadata.items.length === 0) {
50626
- // No published workflows, nothing to trigger
50627
- console.log(`[WorkflowTriggerMiddleware] ⚠️ No published workflows in storage either`);
50628
- return;
50629
- }
50630
- // Convert storage items to workflow definitions
50631
- console.log(`[WorkflowTriggerMiddleware] 📦 Converting ${workflowMetadata.items.length} workflows from storage to definitions...`);
50632
- for (const item of workflowMetadata.items) {
50633
- // Convert storage entity to workflow definition format
50634
- const workflowDef = {
50635
- schemaVersion: item.schemaVersion,
50636
- name: item.name,
50637
- title: item.title,
50638
- description: item.description,
50639
- variables: item.variables || [],
50640
- inputs: item.inputs || [],
50641
- outputs: item.outputs || [],
50642
- graph: item.graph,
50643
- customProperties: item.customProperties || {},
50644
- extensions: item.extensions || {},
50645
- bindings: item.bindings || [],
50646
- };
50647
- allWorkflowDefinitions.push(workflowDef);
50648
- }
50649
- console.log(`[WorkflowTriggerMiddleware] ✅ Loaded ${allWorkflowDefinitions.length} workflows from storage`);
50650
- }
50651
- // If still no workflows found, nothing to trigger
50652
- if (allWorkflowDefinitions.length === 0) {
50653
- console.log(`[WorkflowTriggerMiddleware] ⚠️ No workflows found from providers or storage`);
50654
- return;
50655
- }
50656
- // Merge workflow definitions from providers with metadata from storage
50657
- const publishedWorkflows = [];
50658
- console.log(`[WorkflowTriggerMiddleware] 🔗 Merging workflow definitions with metadata...`);
50659
- for (const workflowDef of allWorkflowDefinitions) {
50660
- // Find matching metadata by workflow name
50661
- const metadata = workflowMetadata.items?.find((m) => m.name === workflowDef.name);
50662
- console.log(`[WorkflowTriggerMiddleware] 🔍 Checking workflow '${workflowDef.name}': metadata found=${!!metadata}, isPublished=${metadata?.isPublished}`);
50663
- if (metadata && metadata.isPublished === true) {
50664
- // Parse bindings: prefer metadata.bindings, fallback to workflowDef.bindings
50665
- let bindings = [];
50666
- // First try metadata.bindings (from entity storage)
50667
- if (metadata.bindings) {
50668
- console.log(`[WorkflowTriggerMiddleware] 📋 Metadata has bindings (type: ${typeof metadata.bindings})`);
50669
- if (typeof metadata.bindings === 'string') {
50670
- try {
50671
- bindings = JSON.parse(metadata.bindings);
50672
- console.log(`[WorkflowTriggerMiddleware] ✅ Parsed bindings from JSON:`, bindings);
50673
- }
50674
- catch (error) {
50675
- console.warn(`[WorkflowTriggerMiddleware] ❌ Failed to parse bindings for workflow '${workflowDef.name}':`, error);
50676
- // Fall through to use workflowDef.bindings
50677
- }
50678
- }
50679
- else if (Array.isArray(metadata.bindings)) {
50680
- bindings = metadata.bindings;
50681
- console.log(`[WorkflowTriggerMiddleware] ✅ Using bindings from metadata array:`, bindings);
50682
- }
50683
- }
50684
- // Fallback to workflowDef.bindings if metadata doesn't have bindings
50685
- if (bindings.length === 0 && workflowDef.bindings && workflowDef.bindings.length > 0) {
50686
- bindings = workflowDef.bindings;
50687
- console.log(`[WorkflowTriggerMiddleware] ✅ Using bindings from workflow definition:`, bindings);
50688
- }
50689
- console.log(`[WorkflowTriggerMiddleware] 📌 Final bindings for '${workflowDef.name}':`, bindings);
50690
- publishedWorkflows.push({
50691
- ...workflowDef,
50692
- bindings,
50693
- });
50694
- }
50695
- }
50696
- console.log(`[WorkflowTriggerMiddleware] 📚 Total published workflows with bindings: ${publishedWorkflows.length}`);
50697
- if (publishedWorkflows.length === 0) {
50698
- // No published workflows with matching definitions, nothing to trigger
50699
- return;
50700
- }
50701
- // Find matching bindings for this entity + event
50702
- const matchingWorkflows = [];
50703
- for (const workflow of publishedWorkflows) {
50704
- // Skip if workflow has no bindings
50705
- if (!workflow.bindings || workflow.bindings.length === 0) {
50706
- continue;
50707
- }
50708
- // Check each binding
50709
- for (const binding of workflow.bindings) {
50710
- // Skip disabled bindings
50711
- if (!binding.enabled) {
50712
- continue;
50713
- }
50714
- // Check if event type matches
50715
- if (!binding.eventTypes.includes(eventType)) {
50716
- continue;
50717
- }
50718
- // Check if entity type matches
50719
- // Empty entityTypes array means applies to all workflow-capable entities
50720
- if (binding.entityTypes.length > 0 && !binding.entityTypes.includes(ctx.entityName)) {
50721
- continue;
50722
- }
50723
- // Match found!
50724
- matchingWorkflows.push({ workflow, binding });
50725
- }
50726
- }
50727
- if (matchingWorkflows.length === 0) {
50728
- // No matching bindings found
50729
- console.log(`[WorkflowTriggerMiddleware] ⚠️ No matching workflow bindings for ${ctx.entityName}:${recordId} on ${eventType}`);
50730
- console.log(`[WorkflowTriggerMiddleware] 📋 Available workflows:`, publishedWorkflows.map(w => ({ name: w.name, bindings: w.bindings })));
50731
- return;
50732
- }
50733
- console.log(`[WorkflowTriggerMiddleware] ✅ Found ${matchingWorkflows.length} matching workflow(s) for ${ctx.entityName}:${recordId} on ${eventType}`);
50734
- // Start workflow instances for each matching binding
50735
- for (const { workflow, binding } of matchingWorkflows) {
50736
- try {
50737
- // Construct correlationId to prevent duplicates
50738
- // Format: `${entityType}:${recordId}:${workflowName}`
50739
- const correlationId = `${ctx.entityName}:${recordId}:${workflow.name}`;
50740
- // Check if workflow instance already exists (idempotency)
50741
- try {
50742
- const existingInstances = await storageService.query('WorkflowManagement.WorkflowInstance', {
50743
- filter: {
50744
- field: 'correlationId',
50745
- operator: { type: 'equal' },
50746
- value: correlationId,
50747
- },
50748
- skip: 0,
50749
- take: 1,
50750
- });
50751
- if (existingInstances.items && existingInstances.items.length > 0) {
50752
- const existingInstance = existingInstances.items[0];
50753
- console.log(`[WorkflowTriggerMiddleware] Workflow instance already exists for ${correlationId}: ${existingInstance.id}`);
50754
- continue; // Skip this workflow, instance already exists
50755
- }
50756
- }
50757
- catch (queryError) {
50758
- // If query fails, continue anyway (might be first time)
50759
- console.warn(`[WorkflowTriggerMiddleware] Could not query existing instances:`, queryError);
50760
- }
50761
- // Get record data for workflow input (optional, for workflows that need it)
50762
- let recordData = null;
50763
- try {
50764
- recordData = await storageService.getOne(ctx.entityName, recordId);
50765
- }
50766
- catch (error) {
50767
- console.warn(`[WorkflowTriggerMiddleware] Could not load record data for workflow input:`, error);
50768
- // Continue without record data
50769
- }
50770
- // Prepare workflow input
50771
- const workflowInput = {
50772
- refId: recordId,
50773
- refType: ctx.entityName,
50774
- eventType,
50775
- recordData, // Include record data if available
50776
- correlationId, // Pass correlationId in input so workflow engine can use it
50777
- };
50778
- //TODO: Remove this once we have a proper signature workflow
50779
- // For signature workflows, add default signers if not provided
50780
- if (workflow.name === 'entity-signature-workflow' && !workflowInput.signers) {
50781
- // Get default users for signing (first 2 users as default signers)
50782
- try {
50783
- const usersResult = await storageService.query('SecurityManagement.User', { skip: 0, take: 10 });
50784
- if (usersResult.items && usersResult.items.length > 0) {
50785
- workflowInput.signers = usersResult.items.slice(0, 2).map((user) => user.id);
50786
- console.log(`[WorkflowTriggerMiddleware] Added default signers for signature workflow:`, workflowInput.signers);
50787
- }
50788
- }
50789
- catch (error) {
50790
- console.warn(`[WorkflowTriggerMiddleware] Could not load default signers:`, error);
50791
- }
50792
- }
50793
- console.log(`[WorkflowTriggerMiddleware] 🚀 Starting workflow '${workflow.name}' for ${ctx.entityName}:${recordId} on ${eventType}`, {
50794
- correlationId,
50795
- workflowName: workflow.name,
50796
- });
50797
- // Start workflow with correlationId
50798
- const startResult = await workflowManager.start(workflow.name, workflowInput);
50799
- if (!startResult.success || !startResult.instanceId) {
50800
- console.error(`[WorkflowTriggerMiddleware] ❌ Failed to start workflow '${workflow.name}':`, startResult.error);
50801
- // Continue with other workflows even if one fails
50802
- continue;
50803
- }
50804
- console.log(`[WorkflowTriggerMiddleware] ✅ Workflow '${workflow.name}' started successfully. Instance ID: ${startResult.instanceId}. Instance will be visible in Workflow > Instances.`);
50805
- // Note: The workflow engine will automatically:
50806
- // 1. Execute backend activities
50807
- // 2. Create a bookmark when it reaches the first frontend/human activity
50808
- // 3. Set status to Suspended/Waiting
50809
- // 4. The instance will be visible in Workflow > Instances UI
50810
- }
50811
- catch (error) {
50812
- // Log error but continue with other workflows
50813
- console.error(`[WorkflowTriggerMiddleware] Error starting workflow '${workflow.name}':`, error);
50814
- }
50815
- }
50816
- }
50817
- catch (error) {
50818
- // Log error but don't fail the create/update operation
50819
- console.error(`[WorkflowTriggerMiddleware] Error in workflow trigger pipeline:`, error);
50820
- }
50821
- },
50822
- };
50823
-
50824
50528
  class AXCWorkflowManagementMockModule {
50825
50529
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXCWorkflowManagementMockModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
50826
50530
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.16", ngImport: i0, type: AXCWorkflowManagementMockModule }); }
@@ -50879,7 +50583,7 @@ class AXCWorkflowManagementMockModule {
50879
50583
  multi: true,
50880
50584
  },
50881
50585
  // Workflow Trigger Middleware
50882
- { provide: AXP_ENTITY_STORAGE_MIDDLEWARE, multi: true, useValue: workflowTriggerMiddleware }, // order: 40 - Auto-trigger workflows based on bindings
50586
+ // { provide: AXP_ENTITY_STORAGE_MIDDLEWARE, multi: true, useValue: workflowTriggerMiddleware }, // order: 40 - Auto-trigger workflows based on bindings
50883
50587
  ] }); }
50884
50588
  }
50885
50589
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXCWorkflowManagementMockModule, decorators: [{
@@ -50943,7 +50647,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
50943
50647
  multi: true,
50944
50648
  },
50945
50649
  // Workflow Trigger Middleware
50946
- { provide: AXP_ENTITY_STORAGE_MIDDLEWARE, multi: true, useValue: workflowTriggerMiddleware }, // order: 40 - Auto-trigger workflows based on bindings
50650
+ // { provide: AXP_ENTITY_STORAGE_MIDDLEWARE, multi: true, useValue: workflowTriggerMiddleware }, // order: 40 - Auto-trigger workflows based on bindings
50947
50651
  ],
50948
50652
  }]
50949
50653
  }] });