@contractspec/example.workflow-system 1.46.1 → 1.47.0

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 (85) hide show
  1. package/dist/approval/approval.enum.d.ts +3 -3
  2. package/dist/approval/approval.enum.d.ts.map +1 -1
  3. package/dist/approval/approval.event.d.ts +32 -32
  4. package/dist/approval/approval.event.d.ts.map +1 -1
  5. package/dist/approval/approval.event.js +5 -5
  6. package/dist/approval/approval.event.js.map +1 -1
  7. package/dist/approval/approval.handler.js.map +1 -1
  8. package/dist/approval/approval.operations.d.ts +134 -134
  9. package/dist/approval/approval.schema.d.ts +24 -24
  10. package/dist/entities/approval.d.ts +36 -36
  11. package/dist/entities/approval.d.ts.map +1 -1
  12. package/dist/entities/index.d.ts +127 -127
  13. package/dist/entities/index.js.map +1 -1
  14. package/dist/entities/instance.d.ts +47 -47
  15. package/dist/entities/step.d.ts +32 -32
  16. package/dist/entities/workflow.d.ts +23 -23
  17. package/dist/example.d.ts +2 -2
  18. package/dist/example.d.ts.map +1 -1
  19. package/dist/example.js +4 -2
  20. package/dist/example.js.map +1 -1
  21. package/dist/handlers/index.d.ts +2 -0
  22. package/dist/handlers/index.js +3 -0
  23. package/dist/handlers/workflow.handlers.d.ts +122 -0
  24. package/dist/handlers/workflow.handlers.d.ts.map +1 -0
  25. package/dist/handlers/workflow.handlers.js +263 -0
  26. package/dist/handlers/workflow.handlers.js.map +1 -0
  27. package/dist/index.d.ts +6 -1
  28. package/dist/index.js +6 -1
  29. package/dist/instance/instance.enum.d.ts +2 -2
  30. package/dist/instance/instance.event.d.ts +87 -87
  31. package/dist/instance/instance.event.d.ts.map +1 -1
  32. package/dist/instance/instance.event.js +4 -4
  33. package/dist/instance/instance.event.js.map +1 -1
  34. package/dist/instance/instance.handler.js.map +1 -1
  35. package/dist/instance/instance.operations.d.ts +256 -256
  36. package/dist/instance/instance.schema.d.ts +54 -54
  37. package/dist/presentations/index.d.ts +23 -24
  38. package/dist/presentations/index.d.ts.map +1 -1
  39. package/dist/presentations/index.js +26 -23
  40. package/dist/presentations/index.js.map +1 -1
  41. package/dist/seeders/index.d.ts +10 -0
  42. package/dist/seeders/index.d.ts.map +1 -0
  43. package/dist/seeders/index.js +19 -0
  44. package/dist/seeders/index.js.map +1 -0
  45. package/dist/state-machine/index.js.map +1 -1
  46. package/dist/tests/operations.test-spec.d.ts +10 -0
  47. package/dist/tests/operations.test-spec.d.ts.map +1 -0
  48. package/dist/tests/operations.test-spec.js +123 -0
  49. package/dist/tests/operations.test-spec.js.map +1 -0
  50. package/dist/ui/WorkflowDashboard.d.ts +7 -0
  51. package/dist/ui/WorkflowDashboard.d.ts.map +1 -0
  52. package/dist/ui/WorkflowDashboard.js +223 -0
  53. package/dist/ui/WorkflowDashboard.js.map +1 -0
  54. package/dist/ui/hooks/index.d.ts +2 -0
  55. package/dist/ui/hooks/index.js +5 -0
  56. package/dist/ui/hooks/useWorkflowList.d.ts +22 -0
  57. package/dist/ui/hooks/useWorkflowList.d.ts.map +1 -0
  58. package/dist/ui/hooks/useWorkflowList.js +55 -0
  59. package/dist/ui/hooks/useWorkflowList.js.map +1 -0
  60. package/dist/ui/index.d.ts +6 -0
  61. package/dist/ui/index.js +6 -0
  62. package/dist/ui/renderers/index.d.ts +2 -0
  63. package/dist/ui/renderers/index.js +3 -0
  64. package/dist/ui/renderers/workflow.markdown.d.ts +28 -0
  65. package/dist/ui/renderers/workflow.markdown.d.ts.map +1 -0
  66. package/dist/ui/renderers/workflow.markdown.js +234 -0
  67. package/dist/ui/renderers/workflow.markdown.js.map +1 -0
  68. package/dist/workflow/workflow.enum.d.ts +5 -5
  69. package/dist/workflow/workflow.enum.d.ts.map +1 -1
  70. package/dist/workflow/workflow.event.d.ts +33 -33
  71. package/dist/workflow/workflow.event.js +3 -3
  72. package/dist/workflow/workflow.event.js.map +1 -1
  73. package/dist/workflow/workflow.handler.js.map +1 -1
  74. package/dist/workflow/workflow.operations.d.ts +246 -246
  75. package/dist/workflow/workflow.schema.d.ts +63 -63
  76. package/dist/workflow/workflow.schema.d.ts.map +1 -1
  77. package/dist/workflow-system.capability.d.ts +9 -0
  78. package/dist/workflow-system.capability.d.ts.map +1 -0
  79. package/dist/workflow-system.capability.js +34 -0
  80. package/dist/workflow-system.capability.js.map +1 -0
  81. package/dist/workflow-system.feature.d.ts +2 -2
  82. package/dist/workflow-system.feature.d.ts.map +1 -1
  83. package/dist/workflow-system.feature.js +9 -2
  84. package/dist/workflow-system.feature.js.map +1 -1
  85. package/package.json +24 -8
@@ -1,49 +1,49 @@
1
- import * as _contractspec_lib_schema456 from "@contractspec/lib.schema";
1
+ import * as _contractspec_lib_schema393 from "@contractspec/lib.schema";
2
2
 
3
3
  //#region src/entities/step.d.ts
4
4
  /**
5
5
  * Step type enum - what kind of step this is.
6
6
  */
7
- declare const StepTypeEnum: _contractspec_lib_schema456.EntityEnumDef;
7
+ declare const StepTypeEnum: _contractspec_lib_schema393.EntityEnumDef;
8
8
  /**
9
9
  * Approval mode enum - how approvals are handled.
10
10
  */
11
- declare const ApprovalModeEnum: _contractspec_lib_schema456.EntityEnumDef;
11
+ declare const ApprovalModeEnum: _contractspec_lib_schema393.EntityEnumDef;
12
12
  /**
13
13
  * WorkflowStep entity - defines a step in a workflow.
14
14
  *
15
15
  * Each step represents a state in the workflow state machine,
16
16
  * with transitions defined by the `transitions` JSON field.
17
17
  */
18
- declare const WorkflowStepEntity: _contractspec_lib_schema456.EntitySpec<{
19
- id: _contractspec_lib_schema456.EntityScalarField;
20
- workflowDefinitionId: _contractspec_lib_schema456.EntityScalarField;
21
- name: _contractspec_lib_schema456.EntityScalarField;
22
- key: _contractspec_lib_schema456.EntityScalarField;
23
- description: _contractspec_lib_schema456.EntityScalarField;
24
- type: _contractspec_lib_schema456.EntityEnumField;
25
- position: _contractspec_lib_schema456.EntityScalarField;
26
- transitions: _contractspec_lib_schema456.EntityScalarField;
27
- approvalMode: _contractspec_lib_schema456.EntityEnumField;
28
- approverRoles: _contractspec_lib_schema456.EntityScalarField;
29
- approverUserIds: _contractspec_lib_schema456.EntityScalarField;
30
- escalationConfig: _contractspec_lib_schema456.EntityScalarField;
31
- assigneeRoles: _contractspec_lib_schema456.EntityScalarField;
32
- taskTemplate: _contractspec_lib_schema456.EntityScalarField;
33
- conditionExpression: _contractspec_lib_schema456.EntityScalarField;
34
- waitDuration: _contractspec_lib_schema456.EntityScalarField;
35
- waitForEvent: _contractspec_lib_schema456.EntityScalarField;
36
- actionType: _contractspec_lib_schema456.EntityScalarField;
37
- actionConfig: _contractspec_lib_schema456.EntityScalarField;
38
- timeoutSeconds: _contractspec_lib_schema456.EntityScalarField;
39
- slaSeconds: _contractspec_lib_schema456.EntityScalarField;
40
- notifyOnEnter: _contractspec_lib_schema456.EntityScalarField;
41
- notifyOnExit: _contractspec_lib_schema456.EntityScalarField;
42
- metadata: _contractspec_lib_schema456.EntityScalarField;
43
- createdAt: _contractspec_lib_schema456.EntityScalarField;
44
- updatedAt: _contractspec_lib_schema456.EntityScalarField;
45
- workflowDefinition: _contractspec_lib_schema456.EntityRelationField;
46
- executions: _contractspec_lib_schema456.EntityRelationField;
18
+ declare const WorkflowStepEntity: _contractspec_lib_schema393.EntitySpec<{
19
+ id: _contractspec_lib_schema393.EntityScalarField;
20
+ workflowDefinitionId: _contractspec_lib_schema393.EntityScalarField;
21
+ name: _contractspec_lib_schema393.EntityScalarField;
22
+ key: _contractspec_lib_schema393.EntityScalarField;
23
+ description: _contractspec_lib_schema393.EntityScalarField;
24
+ type: _contractspec_lib_schema393.EntityEnumField;
25
+ position: _contractspec_lib_schema393.EntityScalarField;
26
+ transitions: _contractspec_lib_schema393.EntityScalarField;
27
+ approvalMode: _contractspec_lib_schema393.EntityEnumField;
28
+ approverRoles: _contractspec_lib_schema393.EntityScalarField;
29
+ approverUserIds: _contractspec_lib_schema393.EntityScalarField;
30
+ escalationConfig: _contractspec_lib_schema393.EntityScalarField;
31
+ assigneeRoles: _contractspec_lib_schema393.EntityScalarField;
32
+ taskTemplate: _contractspec_lib_schema393.EntityScalarField;
33
+ conditionExpression: _contractspec_lib_schema393.EntityScalarField;
34
+ waitDuration: _contractspec_lib_schema393.EntityScalarField;
35
+ waitForEvent: _contractspec_lib_schema393.EntityScalarField;
36
+ actionType: _contractspec_lib_schema393.EntityScalarField;
37
+ actionConfig: _contractspec_lib_schema393.EntityScalarField;
38
+ timeoutSeconds: _contractspec_lib_schema393.EntityScalarField;
39
+ slaSeconds: _contractspec_lib_schema393.EntityScalarField;
40
+ notifyOnEnter: _contractspec_lib_schema393.EntityScalarField;
41
+ notifyOnExit: _contractspec_lib_schema393.EntityScalarField;
42
+ metadata: _contractspec_lib_schema393.EntityScalarField;
43
+ createdAt: _contractspec_lib_schema393.EntityScalarField;
44
+ updatedAt: _contractspec_lib_schema393.EntityScalarField;
45
+ workflowDefinition: _contractspec_lib_schema393.EntityRelationField;
46
+ executions: _contractspec_lib_schema393.EntityRelationField;
47
47
  }>;
48
48
  //#endregion
49
49
  export { ApprovalModeEnum, StepTypeEnum, WorkflowStepEntity };
@@ -1,40 +1,40 @@
1
- import * as _contractspec_lib_schema572 from "@contractspec/lib.schema";
1
+ import * as _contractspec_lib_schema509 from "@contractspec/lib.schema";
2
2
 
3
3
  //#region src/entities/workflow.d.ts
4
4
  /**
5
5
  * Workflow status enum - the lifecycle state of a workflow definition.
6
6
  */
7
- declare const WorkflowStatusEnum: _contractspec_lib_schema572.EntityEnumDef;
7
+ declare const WorkflowStatusEnum: _contractspec_lib_schema509.EntityEnumDef;
8
8
  /**
9
9
  * Workflow trigger type enum - what initiates a workflow.
10
10
  */
11
- declare const WorkflowTriggerTypeEnum: _contractspec_lib_schema572.EntityEnumDef;
11
+ declare const WorkflowTriggerTypeEnum: _contractspec_lib_schema509.EntityEnumDef;
12
12
  /**
13
13
  * WorkflowDefinition entity - defines a workflow blueprint.
14
14
  *
15
15
  * A workflow definition specifies the structure, steps, and rules
16
16
  * for a business process. Instances are created from definitions.
17
17
  */
18
- declare const WorkflowDefinitionEntity: _contractspec_lib_schema572.EntitySpec<{
19
- id: _contractspec_lib_schema572.EntityScalarField;
20
- name: _contractspec_lib_schema572.EntityScalarField;
21
- key: _contractspec_lib_schema572.EntityScalarField;
22
- description: _contractspec_lib_schema572.EntityScalarField;
23
- version: _contractspec_lib_schema572.EntityScalarField;
24
- status: _contractspec_lib_schema572.EntityEnumField;
25
- triggerType: _contractspec_lib_schema572.EntityEnumField;
26
- triggerConfig: _contractspec_lib_schema572.EntityScalarField;
27
- initialStepId: _contractspec_lib_schema572.EntityScalarField;
28
- featureFlagKey: _contractspec_lib_schema572.EntityScalarField;
29
- settings: _contractspec_lib_schema572.EntityScalarField;
30
- metadata: _contractspec_lib_schema572.EntityScalarField;
31
- organizationId: _contractspec_lib_schema572.EntityScalarField;
32
- createdBy: _contractspec_lib_schema572.EntityScalarField;
33
- createdAt: _contractspec_lib_schema572.EntityScalarField;
34
- updatedAt: _contractspec_lib_schema572.EntityScalarField;
35
- publishedAt: _contractspec_lib_schema572.EntityScalarField;
36
- steps: _contractspec_lib_schema572.EntityRelationField;
37
- instances: _contractspec_lib_schema572.EntityRelationField;
18
+ declare const WorkflowDefinitionEntity: _contractspec_lib_schema509.EntitySpec<{
19
+ id: _contractspec_lib_schema509.EntityScalarField;
20
+ name: _contractspec_lib_schema509.EntityScalarField;
21
+ key: _contractspec_lib_schema509.EntityScalarField;
22
+ description: _contractspec_lib_schema509.EntityScalarField;
23
+ version: _contractspec_lib_schema509.EntityScalarField;
24
+ status: _contractspec_lib_schema509.EntityEnumField;
25
+ triggerType: _contractspec_lib_schema509.EntityEnumField;
26
+ triggerConfig: _contractspec_lib_schema509.EntityScalarField;
27
+ initialStepId: _contractspec_lib_schema509.EntityScalarField;
28
+ featureFlagKey: _contractspec_lib_schema509.EntityScalarField;
29
+ settings: _contractspec_lib_schema509.EntityScalarField;
30
+ metadata: _contractspec_lib_schema509.EntityScalarField;
31
+ organizationId: _contractspec_lib_schema509.EntityScalarField;
32
+ createdBy: _contractspec_lib_schema509.EntityScalarField;
33
+ createdAt: _contractspec_lib_schema509.EntityScalarField;
34
+ updatedAt: _contractspec_lib_schema509.EntityScalarField;
35
+ publishedAt: _contractspec_lib_schema509.EntityScalarField;
36
+ steps: _contractspec_lib_schema509.EntityRelationField;
37
+ instances: _contractspec_lib_schema509.EntityRelationField;
38
38
  }>;
39
39
  //#endregion
40
40
  export { WorkflowDefinitionEntity, WorkflowStatusEnum, WorkflowTriggerTypeEnum };
package/dist/example.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { ExampleSpec } from "@contractspec/lib.contracts";
1
+ import * as _contractspec_lib_contracts0 from "@contractspec/lib.contracts";
2
2
 
3
3
  //#region src/example.d.ts
4
- declare const example: ExampleSpec;
4
+ declare const example: _contractspec_lib_contracts0.ExampleSpec;
5
5
  //#endregion
6
6
  export { example as default };
7
7
  //# sourceMappingURL=example.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"example.d.ts","names":[],"sources":["../src/example.ts"],"sourcesContent":[],"mappings":";;;cAEM,SAAS"}
1
+ {"version":3,"file":"example.d.ts","names":[],"sources":["../src/example.ts"],"sourcesContent":[],"mappings":";;;cAEM,SAoCJ,4BAAA,CApCW"}
package/dist/example.js CHANGED
@@ -1,5 +1,7 @@
1
+ import { defineExample } from "@contractspec/lib.contracts";
2
+
1
3
  //#region src/example.ts
2
- const example = {
4
+ const example = defineExample({
3
5
  meta: {
4
6
  key: "workflow-system",
5
7
  version: "1.0.0",
@@ -48,7 +50,7 @@ const example = {
48
50
  },
49
51
  mcp: { enabled: true }
50
52
  }
51
- };
53
+ });
52
54
  var example_default = example;
53
55
 
54
56
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"example.js","names":["example: ExampleSpec"],"sources":["../src/example.ts"],"sourcesContent":["import type { ExampleSpec } from '@contractspec/lib.contracts';\n\nconst example: ExampleSpec = {\n meta: {\n key: 'workflow-system',\n version: '1.0.0',\n title: 'Workflow / Approval System',\n description:\n 'State-machine driven approvals with RBAC, audit trail, notifications, and jobs.',\n kind: 'template',\n visibility: 'public',\n stability: 'experimental',\n owners: ['@platform.core'],\n tags: ['workflow', 'approval', 'state-machine', 'rbac'],\n },\n docs: {\n rootDocId: 'docs.examples.workflow-system',\n goalDocId: 'docs.examples.workflow-system.goal',\n usageDocId: 'docs.examples.workflow-system.usage',\n constraintsDocId: 'docs.examples.workflow-system.constraints',\n },\n entrypoints: {\n packageName: '@contractspec/example.workflow-system',\n feature: './feature',\n contracts: './contracts',\n presentations: './presentations',\n handlers: './handlers',\n docs: './docs',\n },\n surfaces: {\n templates: true,\n sandbox: {\n enabled: true,\n modes: ['playground', 'specs', 'builder', 'markdown', 'evolution'],\n },\n studio: { enabled: true, installable: true },\n mcp: { enabled: true },\n },\n};\n\nexport default example;\n"],"mappings":";AAEA,MAAMA,UAAuB;CAC3B,MAAM;EACJ,KAAK;EACL,SAAS;EACT,OAAO;EACP,aACE;EACF,MAAM;EACN,YAAY;EACZ,WAAW;EACX,QAAQ,CAAC,iBAAiB;EAC1B,MAAM;GAAC;GAAY;GAAY;GAAiB;GAAO;EACxD;CACD,MAAM;EACJ,WAAW;EACX,WAAW;EACX,YAAY;EACZ,kBAAkB;EACnB;CACD,aAAa;EACX,aAAa;EACb,SAAS;EACT,WAAW;EACX,eAAe;EACf,UAAU;EACV,MAAM;EACP;CACD,UAAU;EACR,WAAW;EACX,SAAS;GACP,SAAS;GACT,OAAO;IAAC;IAAc;IAAS;IAAW;IAAY;IAAY;GACnE;EACD,QAAQ;GAAE,SAAS;GAAM,aAAa;GAAM;EAC5C,KAAK,EAAE,SAAS,MAAM;EACvB;CACF;AAED,sBAAe"}
1
+ {"version":3,"file":"example.js","names":[],"sources":["../src/example.ts"],"sourcesContent":["import { defineExample } from '@contractspec/lib.contracts';\n\nconst example = defineExample({\n meta: {\n key: 'workflow-system',\n version: '1.0.0',\n title: 'Workflow / Approval System',\n description:\n 'State-machine driven approvals with RBAC, audit trail, notifications, and jobs.',\n kind: 'template',\n visibility: 'public',\n stability: 'experimental',\n owners: ['@platform.core'],\n tags: ['workflow', 'approval', 'state-machine', 'rbac'],\n },\n docs: {\n rootDocId: 'docs.examples.workflow-system',\n goalDocId: 'docs.examples.workflow-system.goal',\n usageDocId: 'docs.examples.workflow-system.usage',\n constraintsDocId: 'docs.examples.workflow-system.constraints',\n },\n entrypoints: {\n packageName: '@contractspec/example.workflow-system',\n feature: './feature',\n contracts: './contracts',\n presentations: './presentations',\n handlers: './handlers',\n docs: './docs',\n },\n surfaces: {\n templates: true,\n sandbox: {\n enabled: true,\n modes: ['playground', 'specs', 'builder', 'markdown', 'evolution'],\n },\n studio: { enabled: true, installable: true },\n mcp: { enabled: true },\n },\n});\n\nexport default example;\n"],"mappings":";;;AAEA,MAAM,UAAU,cAAc;CAC5B,MAAM;EACJ,KAAK;EACL,SAAS;EACT,OAAO;EACP,aACE;EACF,MAAM;EACN,YAAY;EACZ,WAAW;EACX,QAAQ,CAAC,iBAAiB;EAC1B,MAAM;GAAC;GAAY;GAAY;GAAiB;GAAO;EACxD;CACD,MAAM;EACJ,WAAW;EACX,WAAW;EACX,YAAY;EACZ,kBAAkB;EACnB;CACD,aAAa;EACX,aAAa;EACb,SAAS;EACT,WAAW;EACX,eAAe;EACf,UAAU;EACV,MAAM;EACP;CACD,UAAU;EACR,WAAW;EACX,SAAS;GACP,SAAS;GACT,OAAO;IAAC;IAAc;IAAS;IAAW;IAAY;IAAY;GACnE;EACD,QAAQ;GAAE,SAAS;GAAM,aAAa;GAAM;EAC5C,KAAK,EAAE,SAAS,MAAM;EACvB;CACF,CAAC;AAEF,sBAAe"}
@@ -0,0 +1,2 @@
1
+ import { AddWorkflowStepInput, ApproveStepInput, CreateWorkflowDefinitionInput, ListWorkflowDefinitionsInput, ListWorkflowDefinitionsOutput, ListWorkflowInstancesInput, ListWorkflowInstancesOutput, RejectStepInput, StartWorkflowInput, WorkflowApproval, WorkflowDefinition, WorkflowHandlers, WorkflowInstance, WorkflowStep, createWorkflowHandlers } from "./workflow.handlers.js";
2
+ export { AddWorkflowStepInput, ApproveStepInput, CreateWorkflowDefinitionInput, ListWorkflowDefinitionsInput, ListWorkflowDefinitionsOutput, ListWorkflowInstancesInput, ListWorkflowInstancesOutput, RejectStepInput, StartWorkflowInput, WorkflowApproval, WorkflowDefinition, WorkflowHandlers, WorkflowInstance, WorkflowStep, createWorkflowHandlers };
@@ -0,0 +1,3 @@
1
+ import { createWorkflowHandlers } from "./workflow.handlers.js";
2
+
3
+ export { createWorkflowHandlers };
@@ -0,0 +1,122 @@
1
+ import { DatabasePort } from "@contractspec/lib.runtime-sandbox";
2
+
3
+ //#region src/handlers/workflow.handlers.d.ts
4
+
5
+ interface WorkflowDefinition {
6
+ id: string;
7
+ projectId: string;
8
+ organizationId: string;
9
+ name: string;
10
+ description?: string;
11
+ type: 'APPROVAL' | 'SEQUENTIAL' | 'PARALLEL';
12
+ status: 'DRAFT' | 'ACTIVE' | 'ARCHIVED';
13
+ createdAt: Date;
14
+ updatedAt: Date;
15
+ }
16
+ interface WorkflowStep {
17
+ id: string;
18
+ definitionId: string;
19
+ name: string;
20
+ description?: string;
21
+ stepOrder: number;
22
+ type: 'APPROVAL' | 'TASK' | 'NOTIFICATION';
23
+ requiredRoles: string[];
24
+ autoApproveCondition?: string;
25
+ timeoutHours?: number;
26
+ createdAt: Date;
27
+ }
28
+ interface WorkflowInstance {
29
+ id: string;
30
+ projectId: string;
31
+ definitionId: string;
32
+ status: 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'REJECTED' | 'CANCELLED';
33
+ currentStepId?: string;
34
+ data?: Record<string, unknown>;
35
+ requestedBy: string;
36
+ startedAt: Date;
37
+ completedAt?: Date;
38
+ }
39
+ interface WorkflowApproval {
40
+ id: string;
41
+ instanceId: string;
42
+ stepId: string;
43
+ status: 'PENDING' | 'APPROVED' | 'REJECTED' | 'DELEGATED';
44
+ actorId?: string;
45
+ comment?: string;
46
+ decidedAt?: Date;
47
+ createdAt: Date;
48
+ }
49
+ interface CreateWorkflowDefinitionInput {
50
+ name: string;
51
+ description?: string;
52
+ type?: 'APPROVAL' | 'SEQUENTIAL' | 'PARALLEL';
53
+ }
54
+ interface AddWorkflowStepInput {
55
+ definitionId: string;
56
+ name: string;
57
+ description?: string;
58
+ type?: 'APPROVAL' | 'TASK' | 'NOTIFICATION';
59
+ requiredRoles: string[];
60
+ autoApproveCondition?: string;
61
+ timeoutHours?: number;
62
+ }
63
+ interface StartWorkflowInput {
64
+ definitionId: string;
65
+ data?: Record<string, unknown>;
66
+ }
67
+ interface ApproveStepInput {
68
+ instanceId: string;
69
+ comment?: string;
70
+ }
71
+ interface RejectStepInput {
72
+ instanceId: string;
73
+ reason: string;
74
+ }
75
+ interface ListWorkflowDefinitionsInput {
76
+ projectId: string;
77
+ status?: 'DRAFT' | 'ACTIVE' | 'ARCHIVED' | 'all';
78
+ search?: string;
79
+ limit?: number;
80
+ offset?: number;
81
+ }
82
+ interface ListWorkflowDefinitionsOutput {
83
+ definitions: WorkflowDefinition[];
84
+ total: number;
85
+ }
86
+ interface ListWorkflowInstancesInput {
87
+ projectId: string;
88
+ definitionId?: string;
89
+ status?: 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'REJECTED' | 'CANCELLED' | 'all';
90
+ requestedBy?: string;
91
+ limit?: number;
92
+ offset?: number;
93
+ }
94
+ interface ListWorkflowInstancesOutput {
95
+ instances: WorkflowInstance[];
96
+ total: number;
97
+ }
98
+ declare function createWorkflowHandlers(db: DatabasePort): {
99
+ listDefinitions: (input: ListWorkflowDefinitionsInput) => Promise<ListWorkflowDefinitionsOutput>;
100
+ createDefinition: (input: CreateWorkflowDefinitionInput, context: {
101
+ projectId: string;
102
+ organizationId: string;
103
+ }) => Promise<WorkflowDefinition>;
104
+ addStep: (input: AddWorkflowStepInput) => Promise<WorkflowStep>;
105
+ getSteps: (definitionId: string) => Promise<WorkflowStep[]>;
106
+ listInstances: (input: ListWorkflowInstancesInput) => Promise<ListWorkflowInstancesOutput>;
107
+ startInstance: (input: StartWorkflowInput, context: {
108
+ projectId: string;
109
+ requestedBy: string;
110
+ }) => Promise<WorkflowInstance>;
111
+ approveStep: (input: ApproveStepInput, context: {
112
+ actorId: string;
113
+ }) => Promise<WorkflowInstance>;
114
+ rejectStep: (input: RejectStepInput, context: {
115
+ actorId: string;
116
+ }) => Promise<WorkflowInstance>;
117
+ getApprovals: (instanceId: string) => Promise<WorkflowApproval[]>;
118
+ };
119
+ type WorkflowHandlers = ReturnType<typeof createWorkflowHandlers>;
120
+ //#endregion
121
+ export { AddWorkflowStepInput, ApproveStepInput, CreateWorkflowDefinitionInput, ListWorkflowDefinitionsInput, ListWorkflowDefinitionsOutput, ListWorkflowInstancesInput, ListWorkflowInstancesOutput, RejectStepInput, StartWorkflowInput, WorkflowApproval, WorkflowDefinition, WorkflowHandlers, WorkflowInstance, WorkflowStep, createWorkflowHandlers };
122
+ //# sourceMappingURL=workflow.handlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow.handlers.d.ts","names":[],"sources":["../../src/handlers/workflow.handlers.ts"],"sourcesContent":[],"mappings":";;;;AA2CS,UA/BQ,kBAAA,CA+BR;EAEI,EAAA,EAAA,MAAA;EACG,SAAA,EAAA,MAAA;EAAI,cAAA,EAAA,MAAA;EAGH,IAAA,EAAA,MAAA;EAWA,WAAA,CAAA,EAAA,MAAA;EAMA,IAAA,EAAA,UAAA,GAAA,YAAoB,GAAA,UAAA;EAUpB,MAAA,EAAA,OAAA,GAAA,QAAkB,GAAA,UAE1B;EAGQ,SAAA,EA7DJ,IA6DI;EAKA,SAAA,EAjEJ,IAiEI;AAKjB;AAQiB,UA3EA,YAAA,CA2EA;EAKA,EAAA,EAAA,MAAA;EAeA,YAAA,EAAA,MAAA;EAiHD,IAAA,EAAA,MAAA;EAA2B,WAAA,CAAA,EAAA,MAAA;EAKhC,SAAA,EAAA,MAAA;EACE,IAAA,EAAA,UAAA,GAAA,MAAA,GAAA,cAAA;EAAR,aAAA,EAAA,MAAA,EAAA;EAyCM,oBAAA,CAAA,EAAA,MAAA;EAEE,YAAA,CAAA,EAAA,MAAA;EAAR,SAAA,EAvPQ,IAuPR;;AA8B0D,UAlR9C,gBAAA,CAkR8C;EAAR,EAAA,EAAA,MAAA;EAwCE,SAAA,EAAA,MAAA;EAAR,YAAA,EAAA,MAAA;EAetC,MAAA,EAAA,SAAA,GAAA,aAAA,GAAA,WAAA,GAAA,UAAA,GAAA,WAAA;EACE,aAAA,CAAA,EAAA,MAAA;EAAR,IAAA,CAAA,EApUI,MAoUJ,CAAA,MAAA,EAAA,OAAA,CAAA;EAqDM,WAAA,EAAA,MAAA;EAEE,SAAA,EAzXA,IAyXA;EAAR,WAAA,CAAA,EAxXW,IAwXX;;AAmDQ,UAxaI,gBAAA,CAwaJ;EAAR,EAAA,EAAA,MAAA;EAmFM,UAAA,EAAA,MAAA;EAEE,MAAA,EAAA,MAAA;EAAR,MAAA,EAAA,SAAA,GAAA,UAAA,GAAA,UAAA,GAAA,WAAA;EA6CsD,OAAA,CAAA,EAAA,MAAA;EAAR,OAAA,CAAA,EAAA,MAAA;EAAO,SAAA,CAAA,EAniB5C,IAmiB4C;EAwB9C,SAAA,EA1jBC,IA0jBD;;UAvjBK,6BAAA;;;;;UAMA,oBAAA;;;;;;;;;UAUA,kBAAA;;SAER;;UAGQ,gBAAA;;;;UAKA,eAAA;;;;UAKA,4BAAA;;;;;;;UAQA,6BAAA;eACF;;;UAIE,0BAAA;;;;;;;;UAeA,2BAAA;aACJ;;;iBAgHG,sBAAA,KAA2B;2BAKhC,iCACN,QAAQ;4BAyCF;;;QAEN,QAAQ;mBA8BmB,yBAAuB,QAAQ;sCAwCd,QAAQ;yBAe9C,+BACN,QAAQ;yBAqDF;;;QAEN,QAAQ;uBAiDF;;QAEN,QAAQ;sBAmFF;;QAEN,QAAQ;wCA6CsC,QAAQ;;KAwB/C,gBAAA,GAAmB,kBAAkB"}
@@ -0,0 +1,263 @@
1
+ import { web } from "@contractspec/lib.runtime-sandbox";
2
+
3
+ //#region src/handlers/workflow.handlers.ts
4
+ const { generateId } = web;
5
+ function rowToDefinition(row) {
6
+ return {
7
+ id: row.id,
8
+ projectId: row.projectId,
9
+ organizationId: row.organizationId,
10
+ name: row.name,
11
+ description: row.description ?? void 0,
12
+ type: row.type,
13
+ status: row.status,
14
+ createdAt: new Date(row.createdAt),
15
+ updatedAt: new Date(row.updatedAt)
16
+ };
17
+ }
18
+ function rowToStep(row) {
19
+ return {
20
+ id: row.id,
21
+ definitionId: row.definitionId,
22
+ name: row.name,
23
+ description: row.description ?? void 0,
24
+ stepOrder: row.stepOrder,
25
+ type: row.type,
26
+ requiredRoles: row.requiredRoles ? JSON.parse(row.requiredRoles) : [],
27
+ autoApproveCondition: row.autoApproveCondition ?? void 0,
28
+ timeoutHours: row.timeoutHours ?? void 0,
29
+ createdAt: new Date(row.createdAt)
30
+ };
31
+ }
32
+ function rowToInstance(row) {
33
+ return {
34
+ id: row.id,
35
+ projectId: row.projectId,
36
+ definitionId: row.definitionId,
37
+ status: row.status,
38
+ currentStepId: row.currentStepId ?? void 0,
39
+ data: row.data ? JSON.parse(row.data) : void 0,
40
+ requestedBy: row.requestedBy,
41
+ startedAt: new Date(row.startedAt),
42
+ completedAt: row.completedAt ? new Date(row.completedAt) : void 0
43
+ };
44
+ }
45
+ function rowToApproval(row) {
46
+ return {
47
+ id: row.id,
48
+ instanceId: row.instanceId,
49
+ stepId: row.stepId,
50
+ status: row.status,
51
+ actorId: row.actorId ?? void 0,
52
+ comment: row.comment ?? void 0,
53
+ decidedAt: row.decidedAt ? new Date(row.decidedAt) : void 0,
54
+ createdAt: new Date(row.createdAt)
55
+ };
56
+ }
57
+ function createWorkflowHandlers(db) {
58
+ /**
59
+ * List workflow definitions
60
+ */
61
+ async function listDefinitions(input) {
62
+ const { projectId, status, search, limit = 20, offset = 0 } = input;
63
+ let whereClause = "WHERE projectId = ?";
64
+ const params = [projectId];
65
+ if (status && status !== "all") {
66
+ whereClause += " AND status = ?";
67
+ params.push(status);
68
+ }
69
+ if (search) {
70
+ whereClause += " AND name LIKE ?";
71
+ params.push(`%${search}%`);
72
+ }
73
+ const total = (await db.query(`SELECT COUNT(*) as count FROM workflow_definition ${whereClause}`, params)).rows[0]?.count ?? 0;
74
+ return {
75
+ definitions: (await db.query(`SELECT * FROM workflow_definition ${whereClause} ORDER BY updatedAt DESC LIMIT ? OFFSET ?`, [
76
+ ...params,
77
+ limit,
78
+ offset
79
+ ])).rows.map(rowToDefinition),
80
+ total
81
+ };
82
+ }
83
+ /**
84
+ * Create a workflow definition
85
+ */
86
+ async function createDefinition(input, context) {
87
+ const id = generateId("wfdef");
88
+ const now = (/* @__PURE__ */ new Date()).toISOString();
89
+ await db.execute(`INSERT INTO workflow_definition (id, projectId, organizationId, name, description, type, status, createdAt, updatedAt)
90
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
91
+ id,
92
+ context.projectId,
93
+ context.organizationId,
94
+ input.name,
95
+ input.description ?? null,
96
+ input.type ?? "APPROVAL",
97
+ "DRAFT",
98
+ now,
99
+ now
100
+ ]);
101
+ const rows = (await db.query(`SELECT * FROM workflow_definition WHERE id = ?`, [id])).rows;
102
+ return rowToDefinition(rows[0]);
103
+ }
104
+ /**
105
+ * Add a step to a workflow definition
106
+ */
107
+ async function addStep(input) {
108
+ const id = generateId("wfstep");
109
+ const now = (/* @__PURE__ */ new Date()).toISOString();
110
+ const nextOrder = ((await db.query(`SELECT MAX(stepOrder) as maxOrder FROM workflow_step WHERE definitionId = ?`, [input.definitionId])).rows[0]?.maxOrder ?? 0) + 1;
111
+ await db.execute(`INSERT INTO workflow_step (id, definitionId, name, description, stepOrder, type, requiredRoles, autoApproveCondition, timeoutHours, createdAt)
112
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
113
+ id,
114
+ input.definitionId,
115
+ input.name,
116
+ input.description ?? null,
117
+ nextOrder,
118
+ input.type ?? "APPROVAL",
119
+ JSON.stringify(input.requiredRoles),
120
+ input.autoApproveCondition ?? null,
121
+ input.timeoutHours ?? null,
122
+ now
123
+ ]);
124
+ const rows = (await db.query(`SELECT * FROM workflow_step WHERE id = ?`, [id])).rows;
125
+ return rowToStep(rows[0]);
126
+ }
127
+ /**
128
+ * Get steps for a workflow definition
129
+ */
130
+ async function getSteps(definitionId) {
131
+ return (await db.query(`SELECT * FROM workflow_step WHERE definitionId = ? ORDER BY stepOrder`, [definitionId])).rows.map(rowToStep);
132
+ }
133
+ /**
134
+ * List workflow instances
135
+ */
136
+ async function listInstances(input) {
137
+ const { projectId, definitionId, status, requestedBy, limit = 20, offset = 0 } = input;
138
+ let whereClause = "WHERE projectId = ?";
139
+ const params = [projectId];
140
+ if (definitionId) {
141
+ whereClause += " AND definitionId = ?";
142
+ params.push(definitionId);
143
+ }
144
+ if (status && status !== "all") {
145
+ whereClause += " AND status = ?";
146
+ params.push(status);
147
+ }
148
+ if (requestedBy) {
149
+ whereClause += " AND requestedBy = ?";
150
+ params.push(requestedBy);
151
+ }
152
+ const total = (await db.query(`SELECT COUNT(*) as count FROM workflow_instance ${whereClause}`, params)).rows[0]?.count ?? 0;
153
+ return {
154
+ instances: (await db.query(`SELECT * FROM workflow_instance ${whereClause} ORDER BY startedAt DESC LIMIT ? OFFSET ?`, [
155
+ ...params,
156
+ limit,
157
+ offset
158
+ ])).rows.map(rowToInstance),
159
+ total
160
+ };
161
+ }
162
+ /**
163
+ * Start a workflow instance
164
+ */
165
+ async function startInstance(input, context) {
166
+ const id = generateId("wfinst");
167
+ const now = (/* @__PURE__ */ new Date()).toISOString();
168
+ const firstStepId = (await db.query(`SELECT * FROM workflow_step WHERE definitionId = ? ORDER BY stepOrder LIMIT 1`, [input.definitionId])).rows[0]?.id ?? null;
169
+ await db.execute(`INSERT INTO workflow_instance (id, projectId, definitionId, status, currentStepId, data, requestedBy, startedAt)
170
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, [
171
+ id,
172
+ context.projectId,
173
+ input.definitionId,
174
+ firstStepId ? "IN_PROGRESS" : "PENDING",
175
+ firstStepId,
176
+ input.data ? JSON.stringify(input.data) : null,
177
+ context.requestedBy,
178
+ now
179
+ ]);
180
+ if (firstStepId) await db.execute(`INSERT INTO workflow_approval (id, instanceId, stepId, status, createdAt)
181
+ VALUES (?, ?, ?, ?, ?)`, [
182
+ generateId("wfappr"),
183
+ id,
184
+ firstStepId,
185
+ "PENDING",
186
+ now
187
+ ]);
188
+ const rows = (await db.query(`SELECT * FROM workflow_instance WHERE id = ?`, [id])).rows;
189
+ return rowToInstance(rows[0]);
190
+ }
191
+ /**
192
+ * Approve current step
193
+ */
194
+ async function approveStep(input, context) {
195
+ const now = (/* @__PURE__ */ new Date()).toISOString();
196
+ const instances = (await db.query(`SELECT * FROM workflow_instance WHERE id = ?`, [input.instanceId])).rows;
197
+ if (!instances[0]) throw new Error("NOT_FOUND");
198
+ const instance = instances[0];
199
+ await db.execute(`UPDATE workflow_approval SET status = 'APPROVED', actorId = ?, comment = ?, decidedAt = ?
200
+ WHERE instanceId = ? AND stepId = ? AND status = 'PENDING'`, [
201
+ context.actorId,
202
+ input.comment ?? null,
203
+ now,
204
+ input.instanceId,
205
+ instance.currentStepId
206
+ ]);
207
+ const currentStep = (await db.query(`SELECT * FROM workflow_step WHERE id = ?`, [instance.currentStepId])).rows;
208
+ const nextSteps = (await db.query(`SELECT * FROM workflow_step WHERE definitionId = ? AND stepOrder > ? ORDER BY stepOrder LIMIT 1`, [instance.definitionId, currentStep[0]?.stepOrder ?? 0])).rows;
209
+ if (nextSteps[0]) {
210
+ await db.execute(`UPDATE workflow_instance SET currentStepId = ? WHERE id = ?`, [nextSteps[0].id, input.instanceId]);
211
+ await db.execute(`INSERT INTO workflow_approval (id, instanceId, stepId, status, createdAt)
212
+ VALUES (?, ?, ?, ?, ?)`, [
213
+ generateId("wfappr"),
214
+ input.instanceId,
215
+ nextSteps[0].id,
216
+ "PENDING",
217
+ now
218
+ ]);
219
+ } else await db.execute(`UPDATE workflow_instance SET status = 'COMPLETED', currentStepId = NULL, completedAt = ? WHERE id = ?`, [now, input.instanceId]);
220
+ const updated = (await db.query(`SELECT * FROM workflow_instance WHERE id = ?`, [input.instanceId])).rows;
221
+ return rowToInstance(updated[0]);
222
+ }
223
+ /**
224
+ * Reject current step
225
+ */
226
+ async function rejectStep(input, context) {
227
+ const now = (/* @__PURE__ */ new Date()).toISOString();
228
+ const instances = (await db.query(`SELECT * FROM workflow_instance WHERE id = ?`, [input.instanceId])).rows;
229
+ if (!instances[0]) throw new Error("NOT_FOUND");
230
+ await db.execute(`UPDATE workflow_approval SET status = 'REJECTED', actorId = ?, comment = ?, decidedAt = ?
231
+ WHERE instanceId = ? AND stepId = ? AND status = 'PENDING'`, [
232
+ context.actorId,
233
+ input.reason,
234
+ now,
235
+ input.instanceId,
236
+ instances[0].currentStepId
237
+ ]);
238
+ await db.execute(`UPDATE workflow_instance SET status = 'REJECTED', completedAt = ? WHERE id = ?`, [now, input.instanceId]);
239
+ const updated = (await db.query(`SELECT * FROM workflow_instance WHERE id = ?`, [input.instanceId])).rows;
240
+ return rowToInstance(updated[0]);
241
+ }
242
+ /**
243
+ * Get approvals for an instance
244
+ */
245
+ async function getApprovals(instanceId) {
246
+ return (await db.query(`SELECT * FROM workflow_approval WHERE instanceId = ? ORDER BY createdAt`, [instanceId])).rows.map(rowToApproval);
247
+ }
248
+ return {
249
+ listDefinitions,
250
+ createDefinition,
251
+ addStep,
252
+ getSteps,
253
+ listInstances,
254
+ startInstance,
255
+ approveStep,
256
+ rejectStep,
257
+ getApprovals
258
+ };
259
+ }
260
+
261
+ //#endregion
262
+ export { createWorkflowHandlers };
263
+ //# sourceMappingURL=workflow.handlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow.handlers.js","names":[],"sources":["../../src/handlers/workflow.handlers.ts"],"sourcesContent":["/**\n * Runtime-local Workflow handlers\n *\n * Database-backed handlers for the workflow-system template.\n */\nimport type { DatabasePort, DbRow } from '@contractspec/lib.runtime-sandbox';\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\nimport { web } from '@contractspec/lib.runtime-sandbox';\nconst { generateId } = web;\n\n// ============ Types ============\n\nexport interface WorkflowDefinition {\n id: string;\n projectId: string;\n organizationId: string;\n name: string;\n description?: string;\n type: 'APPROVAL' | 'SEQUENTIAL' | 'PARALLEL';\n status: 'DRAFT' | 'ACTIVE' | 'ARCHIVED';\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface WorkflowStep {\n id: string;\n definitionId: string;\n name: string;\n description?: string;\n stepOrder: number;\n type: 'APPROVAL' | 'TASK' | 'NOTIFICATION';\n requiredRoles: string[];\n autoApproveCondition?: string;\n timeoutHours?: number;\n createdAt: Date;\n}\n\nexport interface WorkflowInstance {\n id: string;\n projectId: string;\n definitionId: string;\n status: 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'REJECTED' | 'CANCELLED';\n currentStepId?: string;\n data?: Record<string, unknown>;\n requestedBy: string;\n startedAt: Date;\n completedAt?: Date;\n}\n\nexport interface WorkflowApproval {\n id: string;\n instanceId: string;\n stepId: string;\n status: 'PENDING' | 'APPROVED' | 'REJECTED' | 'DELEGATED';\n actorId?: string;\n comment?: string;\n decidedAt?: Date;\n createdAt: Date;\n}\n\nexport interface CreateWorkflowDefinitionInput {\n name: string;\n description?: string;\n type?: 'APPROVAL' | 'SEQUENTIAL' | 'PARALLEL';\n}\n\nexport interface AddWorkflowStepInput {\n definitionId: string;\n name: string;\n description?: string;\n type?: 'APPROVAL' | 'TASK' | 'NOTIFICATION';\n requiredRoles: string[];\n autoApproveCondition?: string;\n timeoutHours?: number;\n}\n\nexport interface StartWorkflowInput {\n definitionId: string;\n data?: Record<string, unknown>;\n}\n\nexport interface ApproveStepInput {\n instanceId: string;\n comment?: string;\n}\n\nexport interface RejectStepInput {\n instanceId: string;\n reason: string;\n}\n\nexport interface ListWorkflowDefinitionsInput {\n projectId: string;\n status?: 'DRAFT' | 'ACTIVE' | 'ARCHIVED' | 'all';\n search?: string;\n limit?: number;\n offset?: number;\n}\n\nexport interface ListWorkflowDefinitionsOutput {\n definitions: WorkflowDefinition[];\n total: number;\n}\n\nexport interface ListWorkflowInstancesInput {\n projectId: string;\n definitionId?: string;\n status?:\n | 'PENDING'\n | 'IN_PROGRESS'\n | 'COMPLETED'\n | 'REJECTED'\n | 'CANCELLED'\n | 'all';\n requestedBy?: string;\n limit?: number;\n offset?: number;\n}\n\nexport interface ListWorkflowInstancesOutput {\n instances: WorkflowInstance[];\n total: number;\n}\n\n// ============ Row Types ============\n\ninterface WorkflowDefinitionRow {\n id: string;\n projectId: string;\n organizationId: string;\n name: string;\n description: string | null;\n type: string;\n status: string;\n createdAt: string;\n updatedAt: string;\n}\n\ninterface WorkflowStepRow {\n id: string;\n definitionId: string;\n name: string;\n description: string | null;\n stepOrder: number;\n type: string;\n requiredRoles: string | null;\n autoApproveCondition: string | null;\n timeoutHours: number | null;\n createdAt: string;\n}\n\ninterface WorkflowInstanceRow {\n id: string;\n projectId: string;\n definitionId: string;\n status: string;\n currentStepId: string | null;\n data: string | null;\n requestedBy: string;\n startedAt: string;\n completedAt: string | null;\n}\n\ninterface WorkflowApprovalRow {\n id: string;\n instanceId: string;\n stepId: string;\n status: string;\n actorId: string | null;\n comment: string | null;\n decidedAt: string | null;\n createdAt: string;\n}\n\nfunction rowToDefinition(row: WorkflowDefinitionRow): WorkflowDefinition {\n return {\n id: row.id,\n projectId: row.projectId,\n organizationId: row.organizationId,\n name: row.name,\n description: row.description ?? undefined,\n type: row.type as WorkflowDefinition['type'],\n status: row.status as WorkflowDefinition['status'],\n createdAt: new Date(row.createdAt),\n updatedAt: new Date(row.updatedAt),\n };\n}\n\nfunction rowToStep(row: WorkflowStepRow): WorkflowStep {\n return {\n id: row.id,\n definitionId: row.definitionId,\n name: row.name,\n description: row.description ?? undefined,\n stepOrder: row.stepOrder,\n type: row.type as WorkflowStep['type'],\n requiredRoles: row.requiredRoles ? JSON.parse(row.requiredRoles) : [],\n autoApproveCondition: row.autoApproveCondition ?? undefined,\n timeoutHours: row.timeoutHours ?? undefined,\n createdAt: new Date(row.createdAt),\n };\n}\n\nfunction rowToInstance(row: WorkflowInstanceRow): WorkflowInstance {\n return {\n id: row.id,\n projectId: row.projectId,\n definitionId: row.definitionId,\n status: row.status as WorkflowInstance['status'],\n currentStepId: row.currentStepId ?? undefined,\n data: row.data ? JSON.parse(row.data) : undefined,\n requestedBy: row.requestedBy,\n startedAt: new Date(row.startedAt),\n completedAt: row.completedAt ? new Date(row.completedAt) : undefined,\n };\n}\n\nfunction rowToApproval(row: WorkflowApprovalRow): WorkflowApproval {\n return {\n id: row.id,\n instanceId: row.instanceId,\n stepId: row.stepId,\n status: row.status as WorkflowApproval['status'],\n actorId: row.actorId ?? undefined,\n comment: row.comment ?? undefined,\n decidedAt: row.decidedAt ? new Date(row.decidedAt) : undefined,\n createdAt: new Date(row.createdAt),\n };\n}\n\n// ============ Handler Factory ============\n\nexport function createWorkflowHandlers(db: DatabasePort) {\n /**\n * List workflow definitions\n */\n async function listDefinitions(\n input: ListWorkflowDefinitionsInput\n ): Promise<ListWorkflowDefinitionsOutput> {\n const { projectId, status, search, limit = 20, offset = 0 } = input;\n\n let whereClause = 'WHERE projectId = ?';\n const params: (string | number)[] = [projectId];\n\n if (status && status !== 'all') {\n whereClause += ' AND status = ?';\n params.push(status);\n }\n\n if (search) {\n whereClause += ' AND name LIKE ?';\n params.push(`%${search}%`);\n }\n\n const countResult = (\n await db.query(\n `SELECT COUNT(*) as count FROM workflow_definition ${whereClause}`,\n params\n )\n ).rows as DbRow[];\n const total = (countResult[0]?.count as number) ?? 0;\n\n const rows = (\n await db.query(\n `SELECT * FROM workflow_definition ${whereClause} ORDER BY updatedAt DESC LIMIT ? OFFSET ?`,\n [...params, limit, offset]\n )\n ).rows as unknown as WorkflowDefinitionRow[];\n\n return {\n definitions: rows.map(rowToDefinition),\n total,\n };\n }\n\n /**\n * Create a workflow definition\n */\n async function createDefinition(\n input: CreateWorkflowDefinitionInput,\n context: { projectId: string; organizationId: string }\n ): Promise<WorkflowDefinition> {\n const id = generateId('wfdef');\n const now = new Date().toISOString();\n\n await db.execute(\n `INSERT INTO workflow_definition (id, projectId, organizationId, name, description, type, status, createdAt, updatedAt)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n [\n id,\n context.projectId,\n context.organizationId,\n input.name,\n input.description ?? null,\n input.type ?? 'APPROVAL',\n 'DRAFT',\n now,\n now,\n ]\n );\n\n const rows = (\n await db.query(`SELECT * FROM workflow_definition WHERE id = ?`, [id])\n ).rows as unknown as WorkflowDefinitionRow[];\n\n return rowToDefinition(rows[0]!);\n }\n\n /**\n * Add a step to a workflow definition\n */\n async function addStep(input: AddWorkflowStepInput): Promise<WorkflowStep> {\n const id = generateId('wfstep');\n const now = new Date().toISOString();\n\n // Get current max order\n const maxOrderResult = (\n await db.query(\n `SELECT MAX(stepOrder) as maxOrder FROM workflow_step WHERE definitionId = ?`,\n [input.definitionId]\n )\n ).rows as DbRow[];\n const nextOrder = ((maxOrderResult[0]?.maxOrder as number) ?? 0) + 1;\n\n await db.execute(\n `INSERT INTO workflow_step (id, definitionId, name, description, stepOrder, type, requiredRoles, autoApproveCondition, timeoutHours, createdAt)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n [\n id,\n input.definitionId,\n input.name,\n input.description ?? null,\n nextOrder,\n input.type ?? 'APPROVAL',\n JSON.stringify(input.requiredRoles),\n input.autoApproveCondition ?? null,\n input.timeoutHours ?? null,\n now,\n ]\n );\n\n const rows = (\n await db.query(`SELECT * FROM workflow_step WHERE id = ?`, [id])\n ).rows as unknown as WorkflowStepRow[];\n\n return rowToStep(rows[0]!);\n }\n\n /**\n * Get steps for a workflow definition\n */\n async function getSteps(definitionId: string): Promise<WorkflowStep[]> {\n const rows = (\n await db.query(\n `SELECT * FROM workflow_step WHERE definitionId = ? ORDER BY stepOrder`,\n [definitionId]\n )\n ).rows as unknown as WorkflowStepRow[];\n\n return rows.map(rowToStep);\n }\n\n /**\n * List workflow instances\n */\n async function listInstances(\n input: ListWorkflowInstancesInput\n ): Promise<ListWorkflowInstancesOutput> {\n const {\n projectId,\n definitionId,\n status,\n requestedBy,\n limit = 20,\n offset = 0,\n } = input;\n\n let whereClause = 'WHERE projectId = ?';\n const params: (string | number)[] = [projectId];\n\n if (definitionId) {\n whereClause += ' AND definitionId = ?';\n params.push(definitionId);\n }\n\n if (status && status !== 'all') {\n whereClause += ' AND status = ?';\n params.push(status);\n }\n\n if (requestedBy) {\n whereClause += ' AND requestedBy = ?';\n params.push(requestedBy);\n }\n\n const countResult = (\n await db.query(\n `SELECT COUNT(*) as count FROM workflow_instance ${whereClause}`,\n params\n )\n ).rows as DbRow[];\n const total = (countResult[0]?.count as number) ?? 0;\n\n const rows = (\n await db.query(\n `SELECT * FROM workflow_instance ${whereClause} ORDER BY startedAt DESC LIMIT ? OFFSET ?`,\n [...params, limit, offset]\n )\n ).rows as unknown as WorkflowInstanceRow[];\n\n return {\n instances: rows.map(rowToInstance),\n total,\n };\n }\n\n /**\n * Start a workflow instance\n */\n async function startInstance(\n input: StartWorkflowInput,\n context: { projectId: string; requestedBy: string }\n ): Promise<WorkflowInstance> {\n const id = generateId('wfinst');\n const now = new Date().toISOString();\n\n // Get first step\n const steps = (\n await db.query(\n `SELECT * FROM workflow_step WHERE definitionId = ? ORDER BY stepOrder LIMIT 1`,\n [input.definitionId]\n )\n ).rows as unknown as WorkflowStepRow[];\n\n const firstStepId = steps[0]?.id ?? null;\n\n await db.execute(\n `INSERT INTO workflow_instance (id, projectId, definitionId, status, currentStepId, data, requestedBy, startedAt)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,\n [\n id,\n context.projectId,\n input.definitionId,\n firstStepId ? 'IN_PROGRESS' : 'PENDING',\n firstStepId,\n input.data ? JSON.stringify(input.data) : null,\n context.requestedBy,\n now,\n ]\n );\n\n // Create first approval if there's a step\n if (firstStepId) {\n await db.execute(\n `INSERT INTO workflow_approval (id, instanceId, stepId, status, createdAt)\n VALUES (?, ?, ?, ?, ?)`,\n [generateId('wfappr'), id, firstStepId, 'PENDING', now]\n );\n }\n\n const rows = (\n await db.query(`SELECT * FROM workflow_instance WHERE id = ?`, [id])\n ).rows as unknown as WorkflowInstanceRow[];\n\n return rowToInstance(rows[0]!);\n }\n\n /**\n * Approve current step\n */\n async function approveStep(\n input: ApproveStepInput,\n context: { actorId: string }\n ): Promise<WorkflowInstance> {\n const now = new Date().toISOString();\n\n // Get instance\n const instances = (\n await db.query(`SELECT * FROM workflow_instance WHERE id = ?`, [\n input.instanceId,\n ])\n ).rows as unknown as WorkflowInstanceRow[];\n\n if (!instances[0]) {\n throw new Error('NOT_FOUND');\n }\n\n const instance = instances[0];\n\n // Update current approval\n await db.execute(\n `UPDATE workflow_approval SET status = 'APPROVED', actorId = ?, comment = ?, decidedAt = ? \n WHERE instanceId = ? AND stepId = ? AND status = 'PENDING'`,\n [\n context.actorId,\n input.comment ?? null,\n now,\n input.instanceId,\n instance.currentStepId,\n ]\n );\n\n // Get next step\n const currentStep = (\n await db.query(`SELECT * FROM workflow_step WHERE id = ?`, [\n instance.currentStepId,\n ])\n ).rows as unknown as WorkflowStepRow[];\n\n const nextSteps = (\n await db.query(\n `SELECT * FROM workflow_step WHERE definitionId = ? AND stepOrder > ? ORDER BY stepOrder LIMIT 1`,\n [instance.definitionId, currentStep[0]?.stepOrder ?? 0]\n )\n ).rows as unknown as WorkflowStepRow[];\n\n if (nextSteps[0]) {\n // Move to next step\n await db.execute(\n `UPDATE workflow_instance SET currentStepId = ? WHERE id = ?`,\n [nextSteps[0].id, input.instanceId]\n );\n\n // Create approval for next step\n await db.execute(\n `INSERT INTO workflow_approval (id, instanceId, stepId, status, createdAt)\n VALUES (?, ?, ?, ?, ?)`,\n [\n generateId('wfappr'),\n input.instanceId,\n nextSteps[0].id,\n 'PENDING',\n now,\n ]\n );\n } else {\n // Complete workflow\n await db.execute(\n `UPDATE workflow_instance SET status = 'COMPLETED', currentStepId = NULL, completedAt = ? WHERE id = ?`,\n [now, input.instanceId]\n );\n }\n\n const updated = (\n await db.query(`SELECT * FROM workflow_instance WHERE id = ?`, [\n input.instanceId,\n ])\n ).rows as unknown as WorkflowInstanceRow[];\n\n return rowToInstance(updated[0]!);\n }\n\n /**\n * Reject current step\n */\n async function rejectStep(\n input: RejectStepInput,\n context: { actorId: string }\n ): Promise<WorkflowInstance> {\n const now = new Date().toISOString();\n\n // Get instance\n const instances = (\n await db.query(`SELECT * FROM workflow_instance WHERE id = ?`, [\n input.instanceId,\n ])\n ).rows as unknown as WorkflowInstanceRow[];\n\n if (!instances[0]) {\n throw new Error('NOT_FOUND');\n }\n\n // Update current approval\n await db.execute(\n `UPDATE workflow_approval SET status = 'REJECTED', actorId = ?, comment = ?, decidedAt = ? \n WHERE instanceId = ? AND stepId = ? AND status = 'PENDING'`,\n [\n context.actorId,\n input.reason,\n now,\n input.instanceId,\n instances[0].currentStepId,\n ]\n );\n\n // Reject workflow\n await db.execute(\n `UPDATE workflow_instance SET status = 'REJECTED', completedAt = ? WHERE id = ?`,\n [now, input.instanceId]\n );\n\n const updated = (\n await db.query(`SELECT * FROM workflow_instance WHERE id = ?`, [\n input.instanceId,\n ])\n ).rows as unknown as WorkflowInstanceRow[];\n\n return rowToInstance(updated[0]!);\n }\n\n /**\n * Get approvals for an instance\n */\n async function getApprovals(instanceId: string): Promise<WorkflowApproval[]> {\n const rows = (\n await db.query(\n `SELECT * FROM workflow_approval WHERE instanceId = ? ORDER BY createdAt`,\n [instanceId]\n )\n ).rows as unknown as WorkflowApprovalRow[];\n\n return rows.map(rowToApproval);\n }\n\n return {\n listDefinitions,\n createDefinition,\n addStep,\n getSteps,\n listInstances,\n startInstance,\n approveStep,\n rejectStep,\n getApprovals,\n };\n}\n\nexport type WorkflowHandlers = ReturnType<typeof createWorkflowHandlers>;\n"],"mappings":"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"}