@contractspec/example.workflow-system 1.57.0 → 1.58.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 (209) hide show
  1. package/dist/approval/approval.enum.d.ts +2 -7
  2. package/dist/approval/approval.enum.d.ts.map +1 -1
  3. package/dist/approval/approval.enum.js +20 -26
  4. package/dist/approval/approval.event.d.ts +108 -114
  5. package/dist/approval/approval.event.d.ts.map +1 -1
  6. package/dist/approval/approval.event.js +103 -210
  7. package/dist/approval/approval.handler.d.ts +17 -18
  8. package/dist/approval/approval.handler.d.ts.map +1 -1
  9. package/dist/approval/approval.operations.d.ts +429 -435
  10. package/dist/approval/approval.operations.d.ts.map +1 -1
  11. package/dist/approval/approval.operations.js +364 -339
  12. package/dist/approval/approval.schema.d.ts +86 -91
  13. package/dist/approval/approval.schema.d.ts.map +1 -1
  14. package/dist/approval/approval.schema.js +71 -107
  15. package/dist/approval/index.d.ts +8 -5
  16. package/dist/approval/index.d.ts.map +1 -0
  17. package/dist/approval/index.js +484 -5
  18. package/dist/browser/approval/approval.enum.js +22 -0
  19. package/dist/browser/approval/approval.event.js +112 -0
  20. package/dist/browser/approval/approval.operations.js +369 -0
  21. package/dist/browser/approval/approval.schema.js +73 -0
  22. package/dist/browser/approval/index.js +484 -0
  23. package/dist/browser/docs/index.js +103 -0
  24. package/dist/browser/docs/workflow-system.docblock.js +103 -0
  25. package/dist/browser/entities/approval.js +119 -0
  26. package/dist/browser/entities/index.js +508 -0
  27. package/dist/browser/entities/instance.js +161 -0
  28. package/dist/browser/entities/step.js +124 -0
  29. package/dist/browser/entities/workflow.js +82 -0
  30. package/dist/browser/example.js +42 -0
  31. package/dist/browser/handlers/index.js +253 -0
  32. package/dist/browser/handlers/workflow.handlers.js +253 -0
  33. package/dist/browser/index.js +3120 -0
  34. package/dist/browser/instance/index.js +677 -0
  35. package/dist/browser/instance/instance.enum.js +15 -0
  36. package/dist/browser/instance/instance.event.js +164 -0
  37. package/dist/browser/instance/instance.handler.js +356 -0
  38. package/dist/browser/instance/instance.operations.js +9 -0
  39. package/dist/browser/instance/instance.schema.js +101 -0
  40. package/dist/browser/presentations/index.js +109 -0
  41. package/dist/browser/seeders/index.js +3 -0
  42. package/dist/browser/shared/index.js +3 -0
  43. package/dist/browser/shared/mock-data.js +11 -0
  44. package/dist/browser/shared/types.js +0 -0
  45. package/dist/browser/state-machine/index.js +6 -0
  46. package/dist/browser/tests/operations.test-spec.js +6 -0
  47. package/dist/browser/ui/WorkflowDashboard.js +3 -0
  48. package/dist/browser/ui/hooks/index.js +50 -0
  49. package/dist/browser/ui/hooks/useWorkflowList.js +50 -0
  50. package/dist/browser/ui/index.js +54 -0
  51. package/dist/browser/ui/renderers/index.js +227 -0
  52. package/dist/browser/ui/renderers/workflow.markdown.js +227 -0
  53. package/dist/browser/workflow/index.js +21 -0
  54. package/dist/browser/workflow/workflow.enum.js +36 -0
  55. package/dist/browser/workflow/workflow.event.js +6 -0
  56. package/dist/browser/workflow/workflow.handler.js +5 -0
  57. package/dist/browser/workflow/workflow.operations.js +8 -0
  58. package/dist/browser/workflow/workflow.schema.js +151 -0
  59. package/dist/browser/workflow-system.capability.js +5 -0
  60. package/dist/browser/workflow-system.feature.js +3 -0
  61. package/dist/docs/index.d.ts +2 -1
  62. package/dist/docs/index.d.ts.map +1 -0
  63. package/dist/docs/index.js +104 -1
  64. package/dist/docs/workflow-system.docblock.d.ts +2 -1
  65. package/dist/docs/workflow-system.docblock.d.ts.map +1 -0
  66. package/dist/docs/workflow-system.docblock.js +45 -56
  67. package/dist/entities/approval.d.ts +35 -40
  68. package/dist/entities/approval.d.ts.map +1 -1
  69. package/dist/entities/approval.js +116 -124
  70. package/dist/entities/index.d.ts +132 -137
  71. package/dist/entities/index.d.ts.map +1 -1
  72. package/dist/entities/index.js +506 -29
  73. package/dist/entities/instance.d.ts +46 -51
  74. package/dist/entities/instance.d.ts.map +1 -1
  75. package/dist/entities/instance.js +158 -164
  76. package/dist/entities/step.d.ts +31 -36
  77. package/dist/entities/step.d.ts.map +1 -1
  78. package/dist/entities/step.js +122 -132
  79. package/dist/entities/workflow.d.ts +22 -27
  80. package/dist/entities/workflow.d.ts.map +1 -1
  81. package/dist/entities/workflow.js +80 -99
  82. package/dist/example.d.ts +2 -6
  83. package/dist/example.d.ts.map +1 -1
  84. package/dist/example.js +41 -55
  85. package/dist/handlers/index.d.ts +2 -2
  86. package/dist/handlers/index.d.ts.map +1 -0
  87. package/dist/handlers/index.js +254 -3
  88. package/dist/handlers/workflow.handlers.d.ts +107 -106
  89. package/dist/handlers/workflow.handlers.d.ts.map +1 -1
  90. package/dist/handlers/workflow.handlers.js +237 -246
  91. package/dist/index.d.ts +15 -26
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +3121 -26
  94. package/dist/instance/index.d.ts +8 -5
  95. package/dist/instance/index.d.ts.map +1 -0
  96. package/dist/instance/index.js +677 -5
  97. package/dist/instance/instance.enum.d.ts +1 -6
  98. package/dist/instance/instance.enum.d.ts.map +1 -1
  99. package/dist/instance/instance.enum.js +14 -18
  100. package/dist/instance/instance.event.d.ts +313 -319
  101. package/dist/instance/instance.event.d.ts.map +1 -1
  102. package/dist/instance/instance.event.js +151 -279
  103. package/dist/instance/instance.handler.d.ts +21 -22
  104. package/dist/instance/instance.handler.d.ts.map +1 -1
  105. package/dist/instance/instance.handler.js +352 -89
  106. package/dist/instance/instance.operations.d.ts +819 -825
  107. package/dist/instance/instance.operations.d.ts.map +1 -1
  108. package/dist/instance/instance.operations.js +10 -464
  109. package/dist/instance/instance.schema.d.ts +196 -201
  110. package/dist/instance/instance.schema.d.ts.map +1 -1
  111. package/dist/instance/instance.schema.js +97 -167
  112. package/dist/presentations/index.d.ts +23 -28
  113. package/dist/presentations/index.d.ts.map +1 -1
  114. package/dist/presentations/index.js +104 -334
  115. package/dist/seeders/index.d.ts +4 -8
  116. package/dist/seeders/index.d.ts.map +1 -1
  117. package/dist/seeders/index.js +4 -19
  118. package/dist/shared/index.d.ts +6 -3
  119. package/dist/shared/index.d.ts.map +1 -0
  120. package/dist/shared/index.js +4 -3
  121. package/dist/shared/mock-data.d.ts +16 -16
  122. package/dist/shared/mock-data.d.ts.map +1 -1
  123. package/dist/shared/mock-data.js +11 -11
  124. package/dist/shared/types.d.ts +69 -72
  125. package/dist/shared/types.d.ts.map +1 -1
  126. package/dist/shared/types.js +1 -0
  127. package/dist/state-machine/index.d.ts +92 -95
  128. package/dist/state-machine/index.d.ts.map +1 -1
  129. package/dist/state-machine/index.js +6 -157
  130. package/dist/tests/operations.test-spec.d.ts +4 -9
  131. package/dist/tests/operations.test-spec.d.ts.map +1 -1
  132. package/dist/tests/operations.test-spec.js +7 -123
  133. package/dist/ui/WorkflowDashboard.d.ts +1 -6
  134. package/dist/ui/WorkflowDashboard.d.ts.map +1 -1
  135. package/dist/ui/WorkflowDashboard.js +3 -222
  136. package/dist/ui/hooks/index.d.ts +2 -2
  137. package/dist/ui/hooks/index.d.ts.map +1 -0
  138. package/dist/ui/hooks/index.js +51 -5
  139. package/dist/ui/hooks/useWorkflowList.d.ts +15 -19
  140. package/dist/ui/hooks/useWorkflowList.d.ts.map +1 -1
  141. package/dist/ui/hooks/useWorkflowList.js +47 -51
  142. package/dist/ui/index.d.ts +7 -6
  143. package/dist/ui/index.d.ts.map +1 -0
  144. package/dist/ui/index.js +55 -6
  145. package/dist/ui/renderers/index.d.ts +2 -2
  146. package/dist/ui/renderers/index.d.ts.map +1 -0
  147. package/dist/ui/renderers/index.js +227 -2
  148. package/dist/ui/renderers/workflow.markdown.d.ts +13 -14
  149. package/dist/ui/renderers/workflow.markdown.d.ts.map +1 -1
  150. package/dist/ui/renderers/workflow.markdown.js +223 -229
  151. package/dist/workflow/index.d.ts +8 -5
  152. package/dist/workflow/index.d.ts.map +1 -0
  153. package/dist/workflow/index.js +22 -6
  154. package/dist/workflow/workflow.enum.d.ts +4 -9
  155. package/dist/workflow/workflow.enum.d.ts.map +1 -1
  156. package/dist/workflow/workflow.enum.js +32 -42
  157. package/dist/workflow/workflow.event.d.ts +112 -118
  158. package/dist/workflow/workflow.event.d.ts.map +1 -1
  159. package/dist/workflow/workflow.event.js +7 -150
  160. package/dist/workflow/workflow.handler.d.ts +23 -24
  161. package/dist/workflow/workflow.handler.d.ts.map +1 -1
  162. package/dist/workflow/workflow.handler.js +6 -66
  163. package/dist/workflow/workflow.operations.d.ts +847 -853
  164. package/dist/workflow/workflow.operations.d.ts.map +1 -1
  165. package/dist/workflow/workflow.operations.js +9 -345
  166. package/dist/workflow/workflow.schema.d.ts +229 -234
  167. package/dist/workflow/workflow.schema.d.ts.map +1 -1
  168. package/dist/workflow/workflow.schema.js +146 -243
  169. package/dist/workflow-system.capability.d.ts +3 -8
  170. package/dist/workflow-system.capability.d.ts.map +1 -1
  171. package/dist/workflow-system.capability.js +6 -34
  172. package/dist/workflow-system.feature.d.ts +1 -6
  173. package/dist/workflow-system.feature.d.ts.map +1 -1
  174. package/dist/workflow-system.feature.js +4 -346
  175. package/package.json +415 -93
  176. package/dist/approval/approval.enum.js.map +0 -1
  177. package/dist/approval/approval.event.js.map +0 -1
  178. package/dist/approval/approval.handler.js +0 -72
  179. package/dist/approval/approval.handler.js.map +0 -1
  180. package/dist/approval/approval.operations.js.map +0 -1
  181. package/dist/approval/approval.schema.js.map +0 -1
  182. package/dist/docs/workflow-system.docblock.js.map +0 -1
  183. package/dist/entities/approval.js.map +0 -1
  184. package/dist/entities/index.js.map +0 -1
  185. package/dist/entities/instance.js.map +0 -1
  186. package/dist/entities/step.js.map +0 -1
  187. package/dist/entities/workflow.js.map +0 -1
  188. package/dist/example.js.map +0 -1
  189. package/dist/handlers/workflow.handlers.js.map +0 -1
  190. package/dist/instance/instance.enum.js.map +0 -1
  191. package/dist/instance/instance.event.js.map +0 -1
  192. package/dist/instance/instance.handler.js.map +0 -1
  193. package/dist/instance/instance.operations.js.map +0 -1
  194. package/dist/instance/instance.schema.js.map +0 -1
  195. package/dist/presentations/index.js.map +0 -1
  196. package/dist/seeders/index.js.map +0 -1
  197. package/dist/shared/mock-data.js.map +0 -1
  198. package/dist/state-machine/index.js.map +0 -1
  199. package/dist/tests/operations.test-spec.js.map +0 -1
  200. package/dist/ui/WorkflowDashboard.js.map +0 -1
  201. package/dist/ui/hooks/useWorkflowList.js.map +0 -1
  202. package/dist/ui/renderers/workflow.markdown.js.map +0 -1
  203. package/dist/workflow/workflow.enum.js.map +0 -1
  204. package/dist/workflow/workflow.event.js.map +0 -1
  205. package/dist/workflow/workflow.handler.js.map +0 -1
  206. package/dist/workflow/workflow.operations.js.map +0 -1
  207. package/dist/workflow/workflow.schema.js.map +0 -1
  208. package/dist/workflow-system.capability.js.map +0 -1
  209. package/dist/workflow-system.feature.js.map +0 -1
@@ -1,72 +0,0 @@
1
- import { mockDataStore } from "../shared/mock-data.js";
2
- import { handleTransitionWorkflow } from "../instance/instance.handler.js";
3
-
4
- //#region src/approval/approval.handler.ts
5
- async function createApprovalRequests(instance, step, _context) {
6
- const now = /* @__PURE__ */ new Date();
7
- for (let i = 0; i < step.approverRoles.length; i++) {
8
- const role = step.approverRoles[i];
9
- const id = `approval_${Date.now()}_${i}`;
10
- const request = {
11
- id,
12
- workflowInstanceId: instance.id,
13
- stepExecutionId: `exec_${instance.id}_${step.id}`,
14
- approverId: `user_${role}`,
15
- approverRole: role,
16
- title: `Approval required for ${step.name}`,
17
- description: step.description,
18
- status: "PENDING",
19
- contextSnapshot: instance.contextData,
20
- sequenceOrder: i,
21
- createdAt: now,
22
- updatedAt: now
23
- };
24
- mockDataStore.approvals.set(id, request);
25
- }
26
- }
27
- async function handleSubmitDecision(input, context) {
28
- const request = mockDataStore.approvals.get(input.requestId);
29
- if (!request) throw new Error(`Approval request ${input.requestId} not found`);
30
- if (request.approverId !== context.userId && !context.userRoles.includes(request.approverRole ?? "")) throw new Error("User is not authorized to make this decision");
31
- const now = /* @__PURE__ */ new Date();
32
- request.decision = input.decision;
33
- request.decisionComment = input.comment;
34
- request.decidedAt = now;
35
- request.updatedAt = now;
36
- if (input.decision === "APPROVE") {
37
- request.status = "APPROVED";
38
- await handleTransitionWorkflow({
39
- instanceId: request.workflowInstanceId,
40
- action: "approve",
41
- data: input.data,
42
- comment: input.comment
43
- }, context);
44
- } else if (input.decision === "REJECT") {
45
- request.status = "REJECTED";
46
- await handleTransitionWorkflow({
47
- instanceId: request.workflowInstanceId,
48
- action: "reject",
49
- data: input.data,
50
- comment: input.comment
51
- }, context);
52
- }
53
- return request;
54
- }
55
- async function handleListMyApprovals(input, context) {
56
- let requests = Array.from(mockDataStore.approvals.values()).filter((r) => r.approverId === context.userId || context.userRoles.includes(r.approverRole ?? ""));
57
- const pendingCount = requests.filter((r) => r.status === "PENDING").length;
58
- if (input.status) requests = requests.filter((r) => r.status === input.status);
59
- const total = requests.length;
60
- const offset = input.offset ?? 0;
61
- const limit = input.limit ?? 20;
62
- requests = requests.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime()).slice(offset, offset + limit);
63
- return {
64
- requests,
65
- total,
66
- pendingCount
67
- };
68
- }
69
-
70
- //#endregion
71
- export { createApprovalRequests, handleListMyApprovals, handleSubmitDecision };
72
- //# sourceMappingURL=approval.handler.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"approval.handler.js","names":[],"sources":["../../src/approval/approval.handler.ts"],"sourcesContent":["/**\n * Approval handlers.\n */\n\nimport type {\n ApprovalRequestRecord,\n WorkflowInstanceRecord,\n WorkflowStepRecord,\n HandlerContext,\n} from '../shared/types';\nimport { mockDataStore } from '../shared/mock-data';\nimport { handleTransitionWorkflow } from '../instance/instance.handler';\n\nexport async function createApprovalRequests(\n instance: WorkflowInstanceRecord,\n step: WorkflowStepRecord,\n _context: HandlerContext\n): Promise<void> {\n const now = new Date();\n\n // Create approval request for each approver role\n // In production, this would resolve roles to actual users\n for (let i = 0; i < step.approverRoles.length; i++) {\n const role = step.approverRoles[i];\n const id = `approval_${Date.now()}_${i}`;\n\n const request: ApprovalRequestRecord = {\n id,\n workflowInstanceId: instance.id,\n stepExecutionId: `exec_${instance.id}_${step.id}`,\n approverId: `user_${role}`, // In production, resolve to actual user\n approverRole: role,\n title: `Approval required for ${step.name}`,\n description: step.description,\n status: 'PENDING',\n contextSnapshot: instance.contextData,\n sequenceOrder: i,\n createdAt: now,\n updatedAt: now,\n };\n\n mockDataStore.approvals.set(id, request);\n }\n}\n\nexport async function handleSubmitDecision(\n input: {\n requestId: string;\n decision: 'APPROVE' | 'REJECT' | 'REQUEST_CHANGES' | 'DELEGATE' | 'ABSTAIN';\n comment?: string;\n data?: Record<string, unknown>;\n },\n context: HandlerContext\n): Promise<ApprovalRequestRecord> {\n const request = mockDataStore.approvals.get(input.requestId);\n if (!request) {\n throw new Error(`Approval request ${input.requestId} not found`);\n }\n\n // Verify approver\n if (\n request.approverId !== context.userId &&\n !context.userRoles.includes(request.approverRole ?? '')\n ) {\n throw new Error('User is not authorized to make this decision');\n }\n\n const now = new Date();\n request.decision = input.decision;\n request.decisionComment = input.comment;\n request.decidedAt = now;\n request.updatedAt = now;\n\n if (input.decision === 'APPROVE') {\n request.status = 'APPROVED';\n // Trigger workflow transition\n await handleTransitionWorkflow(\n {\n instanceId: request.workflowInstanceId,\n action: 'approve',\n data: input.data,\n comment: input.comment,\n },\n context\n );\n } else if (input.decision === 'REJECT') {\n request.status = 'REJECTED';\n await handleTransitionWorkflow(\n {\n instanceId: request.workflowInstanceId,\n action: 'reject',\n data: input.data,\n comment: input.comment,\n },\n context\n );\n }\n\n return request;\n}\n\nexport async function handleListMyApprovals(\n input: {\n status?:\n | 'PENDING'\n | 'APPROVED'\n | 'REJECTED'\n | 'DELEGATED'\n | 'ESCALATED'\n | 'WITHDRAWN'\n | 'EXPIRED';\n limit?: number;\n offset?: number;\n },\n context: HandlerContext\n): Promise<{\n requests: ApprovalRequestRecord[];\n total: number;\n pendingCount: number;\n}> {\n let requests = Array.from(mockDataStore.approvals.values()).filter(\n (r) =>\n r.approverId === context.userId ||\n context.userRoles.includes(r.approverRole ?? '')\n );\n\n const pendingCount = requests.filter((r) => r.status === 'PENDING').length;\n\n if (input.status) {\n requests = requests.filter((r) => r.status === input.status);\n }\n\n const total = requests.length;\n const offset = input.offset ?? 0;\n const limit = input.limit ?? 20;\n\n requests = requests\n .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())\n .slice(offset, offset + limit);\n\n return { requests, total, pendingCount };\n}\n"],"mappings":";;;;AAaA,eAAsB,uBACpB,UACA,MACA,UACe;CACf,MAAM,sBAAM,IAAI,MAAM;AAItB,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,cAAc,QAAQ,KAAK;EAClD,MAAM,OAAO,KAAK,cAAc;EAChC,MAAM,KAAK,YAAY,KAAK,KAAK,CAAC,GAAG;EAErC,MAAM,UAAiC;GACrC;GACA,oBAAoB,SAAS;GAC7B,iBAAiB,QAAQ,SAAS,GAAG,GAAG,KAAK;GAC7C,YAAY,QAAQ;GACpB,cAAc;GACd,OAAO,yBAAyB,KAAK;GACrC,aAAa,KAAK;GAClB,QAAQ;GACR,iBAAiB,SAAS;GAC1B,eAAe;GACf,WAAW;GACX,WAAW;GACZ;AAED,gBAAc,UAAU,IAAI,IAAI,QAAQ;;;AAI5C,eAAsB,qBACpB,OAMA,SACgC;CAChC,MAAM,UAAU,cAAc,UAAU,IAAI,MAAM,UAAU;AAC5D,KAAI,CAAC,QACH,OAAM,IAAI,MAAM,oBAAoB,MAAM,UAAU,YAAY;AAIlE,KACE,QAAQ,eAAe,QAAQ,UAC/B,CAAC,QAAQ,UAAU,SAAS,QAAQ,gBAAgB,GAAG,CAEvD,OAAM,IAAI,MAAM,+CAA+C;CAGjE,MAAM,sBAAM,IAAI,MAAM;AACtB,SAAQ,WAAW,MAAM;AACzB,SAAQ,kBAAkB,MAAM;AAChC,SAAQ,YAAY;AACpB,SAAQ,YAAY;AAEpB,KAAI,MAAM,aAAa,WAAW;AAChC,UAAQ,SAAS;AAEjB,QAAM,yBACJ;GACE,YAAY,QAAQ;GACpB,QAAQ;GACR,MAAM,MAAM;GACZ,SAAS,MAAM;GAChB,EACD,QACD;YACQ,MAAM,aAAa,UAAU;AACtC,UAAQ,SAAS;AACjB,QAAM,yBACJ;GACE,YAAY,QAAQ;GACpB,QAAQ;GACR,MAAM,MAAM;GACZ,SAAS,MAAM;GAChB,EACD,QACD;;AAGH,QAAO;;AAGT,eAAsB,sBACpB,OAYA,SAKC;CACD,IAAI,WAAW,MAAM,KAAK,cAAc,UAAU,QAAQ,CAAC,CAAC,QACzD,MACC,EAAE,eAAe,QAAQ,UACzB,QAAQ,UAAU,SAAS,EAAE,gBAAgB,GAAG,CACnD;CAED,MAAM,eAAe,SAAS,QAAQ,MAAM,EAAE,WAAW,UAAU,CAAC;AAEpE,KAAI,MAAM,OACR,YAAW,SAAS,QAAQ,MAAM,EAAE,WAAW,MAAM,OAAO;CAG9D,MAAM,QAAQ,SAAS;CACvB,MAAM,SAAS,MAAM,UAAU;CAC/B,MAAM,QAAQ,MAAM,SAAS;AAE7B,YAAW,SACR,MAAM,GAAG,MAAM,EAAE,UAAU,SAAS,GAAG,EAAE,UAAU,SAAS,CAAC,CAC7D,MAAM,QAAQ,SAAS,MAAM;AAEhC,QAAO;EAAE;EAAU;EAAO;EAAc"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"approval.operations.js","names":[],"sources":["../../src/approval/approval.operations.ts"],"sourcesContent":["import {\n defineCommand,\n defineQuery,\n} from '@contractspec/lib.contracts/operations';\nimport { defineSchemaModel, ScalarTypeEnum } from '@contractspec/lib.schema';\nimport { ApprovalDecisionEnum, ApprovalStatusEnum } from './approval.enum';\nimport { ApprovalCommentModel, ApprovalRequestModel } from './approval.schema';\n\nconst OWNERS = ['@example.workflow-system'] as const;\n\n/**\n * Approve or reject an approval request.\n */\nexport const SubmitDecisionContract = defineCommand({\n meta: {\n key: 'workflow.approval.decide',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['workflow', 'approval', 'decision'],\n description: 'Submit an approval decision (approve/reject).',\n goal: 'Allow approvers to make decisions on requests.',\n context: 'Approval inbox, workflow detail.',\n },\n io: {\n input: defineSchemaModel({\n name: 'ApproveRejectInput',\n fields: {\n requestId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n decision: { type: ApprovalDecisionEnum, isOptional: false },\n comment: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n data: { type: ScalarTypeEnum.JSON(), isOptional: true },\n },\n }),\n output: ApprovalRequestModel,\n },\n policy: { auth: 'user' },\n sideEffects: {\n emits: [\n {\n key: 'workflow.approval.decided',\n version: '1.0.0',\n when: 'Decision is made',\n payload: ApprovalRequestModel,\n },\n ],\n audit: ['workflow.approval.decided'],\n },\n acceptance: {\n scenarios: [\n {\n key: 'approve-request-happy-path',\n given: ['Approval request is pending', 'User is assignee'],\n when: ['User approves request'],\n then: ['Request is approved', 'ApprovalDecided event is emitted'],\n },\n ],\n examples: [\n {\n key: 'approve-basic',\n input: {\n requestId: 'req-123',\n decision: 'approve',\n comment: 'Looks good',\n },\n output: { id: 'req-123', status: 'approved' },\n },\n ],\n },\n});\n\n/**\n * Delegate an approval to another user.\n */\nexport const DelegateApprovalContract = defineCommand({\n meta: {\n key: 'workflow.approval.delegate',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['workflow', 'approval', 'delegate'],\n description: 'Delegate an approval request to another user.',\n goal: 'Allow approvers to pass approval to others.',\n context: 'Approval inbox.',\n },\n io: {\n input: defineSchemaModel({\n name: 'DelegateInput',\n fields: {\n requestId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n delegateTo: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n reason: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n },\n }),\n output: ApprovalRequestModel,\n },\n policy: { auth: 'user' },\n sideEffects: {\n emits: [\n {\n key: 'workflow.approval.delegated',\n version: '1.0.0',\n when: 'Approval is delegated',\n payload: ApprovalRequestModel,\n },\n ],\n audit: ['workflow.approval.delegated'],\n },\n acceptance: {\n scenarios: [\n {\n key: 'delegate-approval-happy-path',\n given: ['Approval request is pending', 'User is assignee'],\n when: ['User delegates to another user'],\n then: ['Assignee is updated', 'ApprovalDelegated event is emitted'],\n },\n ],\n examples: [\n {\n key: 'delegate-to-manager',\n input: {\n requestId: 'req-123',\n delegateTo: 'user-456',\n reason: 'Out of office',\n },\n output: { id: 'req-123', assigneeId: 'user-456' },\n },\n ],\n },\n});\n\n/**\n * Add a comment to an approval request.\n */\nexport const AddApprovalCommentContract = defineCommand({\n meta: {\n key: 'workflow.approval.comment.add',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['workflow', 'approval', 'comment'],\n description: 'Add a comment to an approval request.',\n goal: 'Allow discussion on approval requests.',\n context: 'Approval detail view.',\n },\n io: {\n input: defineSchemaModel({\n name: 'AddCommentInput',\n fields: {\n requestId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n content: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },\n isInternal: { type: ScalarTypeEnum.Boolean(), isOptional: true },\n },\n }),\n output: ApprovalCommentModel,\n },\n policy: { auth: 'user' },\n sideEffects: {\n emits: [\n {\n key: 'workflow.approval.comment.added',\n version: '1.0.0',\n when: 'Comment is added',\n payload: ApprovalCommentModel,\n },\n ],\n },\n acceptance: {\n scenarios: [\n {\n key: 'add-comment-happy-path',\n given: ['Approval request exists'],\n when: ['User adds a comment'],\n then: ['Comment is added', 'CommentAdded event is emitted'],\n },\n ],\n examples: [\n {\n key: 'add-question',\n input: {\n requestId: 'req-123',\n content: 'Can you clarify budget?',\n isInternal: false,\n },\n output: { id: 'com-789', content: 'Can you clarify budget?' },\n },\n ],\n },\n});\n\n/**\n * List approvals assigned to the current user.\n */\nexport const ListMyApprovalsContract = defineQuery({\n meta: {\n key: 'workflow.approval.list.mine',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['workflow', 'approval', 'list', 'inbox'],\n description: 'List approval requests assigned to current user.',\n goal: 'Show pending approvals in user inbox.',\n context: 'Approval inbox, dashboard widget.',\n },\n io: {\n input: defineSchemaModel({\n name: 'ListMyApprovalsInput',\n fields: {\n status: { type: ApprovalStatusEnum, isOptional: true },\n limit: {\n type: ScalarTypeEnum.Int_unsecure(),\n isOptional: true,\n defaultValue: 20,\n },\n offset: {\n type: ScalarTypeEnum.Int_unsecure(),\n isOptional: true,\n defaultValue: 0,\n },\n },\n }),\n output: defineSchemaModel({\n name: 'ListMyApprovalsOutput',\n fields: {\n requests: {\n type: ApprovalRequestModel,\n isArray: true,\n isOptional: false,\n },\n total: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n pendingCount: {\n type: ScalarTypeEnum.Int_unsecure(),\n isOptional: false,\n },\n },\n }),\n },\n policy: { auth: 'user' },\n acceptance: {\n scenarios: [\n {\n key: 'list-approvals-happy-path',\n given: ['User has assigned approvals'],\n when: ['User lists approvals'],\n then: ['List of requests is returned'],\n },\n ],\n examples: [\n {\n key: 'list-pending',\n input: { status: 'pending', limit: 10 },\n output: { requests: [], total: 2, pendingCount: 2 },\n },\n ],\n },\n});\n\n/**\n * Get a single approval request.\n */\nexport const GetApprovalContract = defineQuery({\n meta: {\n key: 'workflow.approval.get',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['workflow', 'approval', 'get'],\n description: 'Get an approval request with details.',\n goal: 'View approval request details.',\n context: 'Approval detail view.',\n },\n io: {\n input: defineSchemaModel({\n name: 'GetApprovalInput',\n fields: {\n requestId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n },\n }),\n output: ApprovalRequestModel,\n },\n policy: { auth: 'user' },\n acceptance: {\n scenarios: [\n {\n key: 'get-approval-happy-path',\n given: ['Approval request exists'],\n when: ['User requests approval details'],\n then: ['Approval details are returned'],\n },\n ],\n examples: [\n {\n key: 'get-basic',\n input: { requestId: 'req-123' },\n output: { id: 'req-123', status: 'pending' },\n },\n ],\n },\n});\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"approval.schema.js","names":[],"sources":["../../src/approval/approval.schema.ts"],"sourcesContent":["import { defineSchemaModel, ScalarTypeEnum } from '@contractspec/lib.schema';\nimport { ApprovalStatusEnum, ApprovalDecisionEnum } from './approval.enum';\n\n/**\n * An approval request.\n */\nexport const ApprovalRequestModel = defineSchemaModel({\n name: 'ApprovalRequestModel',\n description: 'An approval request',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n workflowInstanceId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n stepExecutionId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n approverId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n approverRole: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n title: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n description: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n status: { type: ApprovalStatusEnum, isOptional: false },\n decision: { type: ApprovalDecisionEnum, isOptional: true },\n decisionComment: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n decidedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n dueAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n contextSnapshot: { type: ScalarTypeEnum.JSON(), isOptional: true },\n sequenceOrder: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\n/**\n * A comment on an approval.\n */\nexport const ApprovalCommentModel = defineSchemaModel({\n name: 'ApprovalCommentModel',\n description: 'A comment on an approval',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n approvalRequestId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n authorId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n content: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n isInternal: { type: ScalarTypeEnum.Boolean(), isOptional: false },\n createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n"],"mappings":";;;;;;;AAMA,MAAa,uBAAuB,kBAAkB;CACpD,MAAM;CACN,aAAa;CACb,QAAQ;EACN,IAAI;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACjE,oBAAoB;GAClB,MAAM,eAAe,iBAAiB;GACtC,YAAY;GACb;EACD,iBAAiB;GACf,MAAM,eAAe,iBAAiB;GACtC,YAAY;GACb;EACD,YAAY;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACzE,cAAc;GACZ,MAAM,eAAe,iBAAiB;GACtC,YAAY;GACb;EACD,OAAO;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACpE,aAAa;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EACzE,QAAQ;GAAE,MAAM;GAAoB,YAAY;GAAO;EACvD,UAAU;GAAE,MAAM;GAAsB,YAAY;GAAM;EAC1D,iBAAiB;GACf,MAAM,eAAe,iBAAiB;GACtC,YAAY;GACb;EACD,WAAW;GAAE,MAAM,eAAe,UAAU;GAAE,YAAY;GAAM;EAChE,OAAO;GAAE,MAAM,eAAe,UAAU;GAAE,YAAY;GAAM;EAC5D,iBAAiB;GAAE,MAAM,eAAe,MAAM;GAAE,YAAY;GAAM;EAClE,eAAe;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAO;EACzE,WAAW;GAAE,MAAM,eAAe,UAAU;GAAE,YAAY;GAAO;EAClE;CACF,CAAC;;;;AAKF,MAAa,uBAAuB,kBAAkB;CACpD,MAAM;CACN,aAAa;CACb,QAAQ;EACN,IAAI;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACjE,mBAAmB;GACjB,MAAM,eAAe,iBAAiB;GACtC,YAAY;GACb;EACD,UAAU;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACvE,SAAS;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACtE,YAAY;GAAE,MAAM,eAAe,SAAS;GAAE,YAAY;GAAO;EACjE,WAAW;GAAE,MAAM,eAAe,UAAU;GAAE,YAAY;GAAO;EAClE;CACF,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"workflow-system.docblock.js","names":[],"sources":["../../src/docs/workflow-system.docblock.ts"],"sourcesContent":["import type { DocBlock } from '@contractspec/lib.contracts/docs';\nimport { registerDocBlocks } from '@contractspec/lib.contracts/docs';\n\nconst workflowSystemDocBlocks: DocBlock[] = [\n {\n id: 'docs.examples.workflow-system',\n title: 'Workflow / Approval System',\n summary:\n 'Reference app showing state-machine driven approvals with RBAC, audit trail, notifications, and jobs.',\n kind: 'reference',\n visibility: 'public',\n route: '/docs/examples/workflow-system',\n tags: ['workflow', 'approval', 'state-machine', 'rbac'],\n body: `## Entities\n\n- WorkflowDefinition, WorkflowStep, WorkflowInstance, Approval.\n- State machine expressed in \\`src/state-machine\\` with allowed transitions and role gates.\n\n## Contracts\n\n- \\`workflow.definition.create\\`, \\`workflow.instance.start\\`, \\`workflow.step.approve\\`, \\`workflow.step.reject\\`, \\`workflow.instance.comment\\`.\n- Policies enforced via Identity/RBAC module; audit trail emitted on each transition.\n\n## Events & Jobs\n\n- Emits \\`workflow.instance.started\\`, \\`workflow.step.completed\\`, \\`workflow.step.rejected\\`, \\`workflow.instance.finished\\`.\n- Reminder jobs can be scheduled via @contractspec/lib.jobs for pending approvals.\n\n## UI / Presentations\n\n- Dashboard, definition list/editor, instance detail with action buttons derived from state machine.\n- Templates registered in Studio Template Registry under \\`workflow-system\\`.\n\n## Notes\n\n- Keep transitions declarative to enable safe regeneration; role guards live in spec.\n- Use Notification Center for approval requests and outcomes; attach files via Files module if needed.\n`,\n },\n {\n id: 'docs.examples.workflow-system.goal',\n title: 'Workflow System — Goal',\n summary:\n 'Why the workflow/approval template exists and outcomes it targets.',\n kind: 'goal',\n visibility: 'public',\n route: '/docs/examples/workflow-system/goal',\n tags: ['workflow', 'goal'],\n body: `## Why it matters\n- Provides a regenerable, role-gated approval engine using declarative state machines.\n- Keeps workflow rules consistent across UI/API/events with auditability.\n\n## Business/Product goal\n- Enable approvals with clear transitions, reminders, and notifications.\n- Support compliance via Audit Trail and Feature Flags for staged changes.\n\n## Success criteria\n- State changes are declarative and regenerate cleanly.\n- Every transition emits auditable events and respects RBAC guards.`,\n },\n {\n id: 'docs.examples.workflow-system.usage',\n title: 'Workflow System — Usage',\n summary: 'How to configure workflows, transitions, and regenerate safely.',\n kind: 'usage',\n visibility: 'public',\n route: '/docs/examples/workflow-system/usage',\n tags: ['workflow', 'usage'],\n body: `## Setup\n1) Define WorkflowDefinition steps and allowed transitions with role gates in spec.\n2) Seed sample workflows/instances (if provided) or create via UI; enable reminders via Jobs.\n\n## Extend & regenerate\n1) Add steps/transitions or approval conditions in spec; include PII paths if comments/files.\n2) Regenerate to sync UI action buttons and API/state machine behavior.\n3) Use Feature Flags to trial new transitions or escalation rules.\n\n## Guardrails\n- Emit events for every transition; log to Audit Trail.\n- Use Notifications for approvals/rejections; schedule reminders for pending steps.\n- Keep transitions declarative; avoid imperative branching in handlers.`,\n },\n {\n id: 'docs.examples.workflow-system.constraints',\n title: 'Workflow System — Constraints & Safety',\n summary:\n 'Internal guardrails for state machines, RBAC, and regeneration semantics.',\n kind: 'reference',\n visibility: 'internal',\n route: '/docs/examples/workflow-system/constraints',\n tags: ['workflow', 'constraints', 'internal'],\n body: `## Constraints\n- State machine (steps/transitions) must stay declarative in spec; no hidden code paths.\n- Events to emit: instance.started, step.completed/rejected, instance.finished.\n- Regeneration must not change approval logic without explicit spec diff.\n\n## PII & Compliance\n- Mark any PII in comments/attachments; redact in markdown/JSON.\n- Ensure Audit Trail captures every transition; Notifications for approvals/rejections.\n\n## Verification\n- Add fixtures for transition changes and role gates.\n- Validate reminders (Jobs) stay aligned with pending states after regeneration.\n- Use Feature Flags for new transitions/escalation rules; default safe/off.`,\n },\n];\n\nregisterDocBlocks(workflowSystemDocBlocks);\n"],"mappings":";;;AA2GA,kBAxG4C;CAC1C;EACE,IAAI;EACJ,OAAO;EACP,SACE;EACF,MAAM;EACN,YAAY;EACZ,OAAO;EACP,MAAM;GAAC;GAAY;GAAY;GAAiB;GAAO;EACvD,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;EAyBP;CACD;EACE,IAAI;EACJ,OAAO;EACP,SACE;EACF,MAAM;EACN,YAAY;EACZ,OAAO;EACP,MAAM,CAAC,YAAY,OAAO;EAC1B,MAAM;;;;;;;;;;;EAWP;CACD;EACE,IAAI;EACJ,OAAO;EACP,SAAS;EACT,MAAM;EACN,YAAY;EACZ,OAAO;EACP,MAAM,CAAC,YAAY,QAAQ;EAC3B,MAAM;;;;;;;;;;;;;EAaP;CACD;EACE,IAAI;EACJ,OAAO;EACP,SACE;EACF,MAAM;EACN,YAAY;EACZ,OAAO;EACP,MAAM;GAAC;GAAY;GAAe;GAAW;EAC7C,MAAM;;;;;;;;;;;;;EAaP;CACF,CAEyC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"approval.js","names":[],"sources":["../../src/entities/approval.ts"],"sourcesContent":["import {\n defineEntity,\n defineEntityEnum,\n field,\n index,\n} from '@contractspec/lib.schema';\n\n/**\n * Approval status enum.\n */\nexport const ApprovalStatusEnum = defineEntityEnum({\n name: 'ApprovalStatus',\n values: [\n 'PENDING', // Awaiting decision\n 'APPROVED', // Approved\n 'REJECTED', // Rejected\n 'DELEGATED', // Delegated to another user\n 'ESCALATED', // Escalated due to timeout\n 'WITHDRAWN', // Request withdrawn\n 'EXPIRED', // Request expired\n ] as const,\n schema: 'workflow',\n description: 'Status of an approval request.',\n});\n\n/**\n * Approval decision enum.\n */\nexport const ApprovalDecisionEnum = defineEntityEnum({\n name: 'ApprovalDecision',\n values: [\n 'APPROVE',\n 'REJECT',\n 'REQUEST_CHANGES',\n 'DELEGATE',\n 'ABSTAIN',\n ] as const,\n schema: 'workflow',\n description: 'Possible approval decisions.',\n});\n\n/**\n * ApprovalRequest entity - a request for approval from a user.\n *\n * Created when a workflow reaches an APPROVAL step. Multiple requests\n * may be created depending on the approval mode.\n */\nexport const ApprovalRequestEntity = defineEntity({\n name: 'ApprovalRequest',\n description: 'A pending approval request for a workflow step.',\n schema: 'workflow',\n map: 'approval_request',\n fields: {\n id: field.id({ description: 'Unique approval request ID' }),\n\n // Parent\n workflowInstanceId: field.foreignKey(),\n stepExecutionId: field.foreignKey(),\n\n // Approver\n approverId: field.foreignKey({ description: 'User requested to approve' }),\n approverRole: field.string({\n isOptional: true,\n description: 'Role of the approver',\n }),\n\n // Request details\n title: field.string({ description: 'Approval request title' }),\n description: field.string({ isOptional: true }),\n\n // Status\n status: field.enum('ApprovalStatus', { default: 'PENDING' }),\n\n // Decision\n decision: field.enum('ApprovalDecision', { isOptional: true }),\n decisionComment: field.string({\n isOptional: true,\n description: 'Comment explaining decision',\n }),\n decidedAt: field.dateTime({ isOptional: true }),\n\n // Delegation\n delegatedTo: field.string({\n isOptional: true,\n description: 'User delegated to',\n }),\n delegationReason: field.string({ isOptional: true }),\n\n // Escalation\n escalationLevel: field.int({\n default: 0,\n description: 'Current escalation level',\n }),\n escalatedAt: field.dateTime({ isOptional: true }),\n\n // Deadlines\n dueAt: field.dateTime({\n isOptional: true,\n description: 'When approval is due',\n }),\n reminderSentAt: field.dateTime({ isOptional: true }),\n\n // Context - data to display for approval\n contextSnapshot: field.json({\n isOptional: true,\n description: 'Snapshot of relevant data for review',\n }),\n\n // Order (for sequential approvals)\n sequenceOrder: field.int({\n default: 0,\n description: 'Order in approval chain',\n }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n\n // Relations\n workflowInstance: field.belongsTo(\n 'WorkflowInstance',\n ['workflowInstanceId'],\n ['id'],\n { onDelete: 'Cascade' }\n ),\n stepExecution: field.belongsTo(\n 'StepExecution',\n ['stepExecutionId'],\n ['id']\n ),\n },\n indexes: [\n index.on(['approverId', 'status']),\n index.on(['workflowInstanceId', 'status']),\n index.on(['stepExecutionId']),\n index.on(['status', 'dueAt']),\n index.on(['createdAt']),\n ],\n enums: [ApprovalStatusEnum, ApprovalDecisionEnum],\n});\n\n/**\n * ApprovalComment entity - comments on approval requests.\n */\nexport const ApprovalCommentEntity = defineEntity({\n name: 'ApprovalComment',\n description: 'A comment on an approval request.',\n schema: 'workflow',\n map: 'approval_comment',\n fields: {\n id: field.id(),\n\n approvalRequestId: field.foreignKey(),\n\n // Author\n authorId: field.foreignKey(),\n\n // Content\n content: field.string({ description: 'Comment text' }),\n\n // Type\n isInternal: field.boolean({\n default: false,\n description: 'Internal note vs public comment',\n }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n\n // Relations\n approvalRequest: field.belongsTo(\n 'ApprovalRequest',\n ['approvalRequestId'],\n ['id'],\n { onDelete: 'Cascade' }\n ),\n },\n indexes: [index.on(['approvalRequestId', 'createdAt'])],\n});\n"],"mappings":";;;;;;AAUA,MAAa,qBAAqB,iBAAiB;CACjD,MAAM;CACN,QAAQ;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,QAAQ;CACR,aAAa;CACd,CAAC;;;;AAKF,MAAa,uBAAuB,iBAAiB;CACnD,MAAM;CACN,QAAQ;EACN;EACA;EACA;EACA;EACA;EACD;CACD,QAAQ;CACR,aAAa;CACd,CAAC;;;;;;;AAQF,MAAa,wBAAwB,aAAa;CAChD,MAAM;CACN,aAAa;CACb,QAAQ;CACR,KAAK;CACL,QAAQ;EACN,IAAI,MAAM,GAAG,EAAE,aAAa,8BAA8B,CAAC;EAG3D,oBAAoB,MAAM,YAAY;EACtC,iBAAiB,MAAM,YAAY;EAGnC,YAAY,MAAM,WAAW,EAAE,aAAa,6BAA6B,CAAC;EAC1E,cAAc,MAAM,OAAO;GACzB,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,OAAO,MAAM,OAAO,EAAE,aAAa,0BAA0B,CAAC;EAC9D,aAAa,MAAM,OAAO,EAAE,YAAY,MAAM,CAAC;EAG/C,QAAQ,MAAM,KAAK,kBAAkB,EAAE,SAAS,WAAW,CAAC;EAG5D,UAAU,MAAM,KAAK,oBAAoB,EAAE,YAAY,MAAM,CAAC;EAC9D,iBAAiB,MAAM,OAAO;GAC5B,YAAY;GACZ,aAAa;GACd,CAAC;EACF,WAAW,MAAM,SAAS,EAAE,YAAY,MAAM,CAAC;EAG/C,aAAa,MAAM,OAAO;GACxB,YAAY;GACZ,aAAa;GACd,CAAC;EACF,kBAAkB,MAAM,OAAO,EAAE,YAAY,MAAM,CAAC;EAGpD,iBAAiB,MAAM,IAAI;GACzB,SAAS;GACT,aAAa;GACd,CAAC;EACF,aAAa,MAAM,SAAS,EAAE,YAAY,MAAM,CAAC;EAGjD,OAAO,MAAM,SAAS;GACpB,YAAY;GACZ,aAAa;GACd,CAAC;EACF,gBAAgB,MAAM,SAAS,EAAE,YAAY,MAAM,CAAC;EAGpD,iBAAiB,MAAM,KAAK;GAC1B,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,eAAe,MAAM,IAAI;GACvB,SAAS;GACT,aAAa;GACd,CAAC;EAGF,WAAW,MAAM,WAAW;EAC5B,WAAW,MAAM,WAAW;EAG5B,kBAAkB,MAAM,UACtB,oBACA,CAAC,qBAAqB,EACtB,CAAC,KAAK,EACN,EAAE,UAAU,WAAW,CACxB;EACD,eAAe,MAAM,UACnB,iBACA,CAAC,kBAAkB,EACnB,CAAC,KAAK,CACP;EACF;CACD,SAAS;EACP,MAAM,GAAG,CAAC,cAAc,SAAS,CAAC;EAClC,MAAM,GAAG,CAAC,sBAAsB,SAAS,CAAC;EAC1C,MAAM,GAAG,CAAC,kBAAkB,CAAC;EAC7B,MAAM,GAAG,CAAC,UAAU,QAAQ,CAAC;EAC7B,MAAM,GAAG,CAAC,YAAY,CAAC;EACxB;CACD,OAAO,CAAC,oBAAoB,qBAAqB;CAClD,CAAC;;;;AAKF,MAAa,wBAAwB,aAAa;CAChD,MAAM;CACN,aAAa;CACb,QAAQ;CACR,KAAK;CACL,QAAQ;EACN,IAAI,MAAM,IAAI;EAEd,mBAAmB,MAAM,YAAY;EAGrC,UAAU,MAAM,YAAY;EAG5B,SAAS,MAAM,OAAO,EAAE,aAAa,gBAAgB,CAAC;EAGtD,YAAY,MAAM,QAAQ;GACxB,SAAS;GACT,aAAa;GACd,CAAC;EAGF,WAAW,MAAM,WAAW;EAC5B,WAAW,MAAM,WAAW;EAG5B,iBAAiB,MAAM,UACrB,mBACA,CAAC,oBAAoB,EACrB,CAAC,KAAK,EACN,EAAE,UAAU,WAAW,CACxB;EACF;CACD,SAAS,CAAC,MAAM,GAAG,CAAC,qBAAqB,YAAY,CAAC,CAAC;CACxD,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/entities/index.ts"],"sourcesContent":["// Workflow Definition entities\nexport {\n WorkflowStatusEnum,\n WorkflowTriggerTypeEnum,\n WorkflowDefinitionEntity,\n} from './workflow';\n\n// Step entities\nexport { StepTypeEnum, ApprovalModeEnum, WorkflowStepEntity } from './step';\n\n// Instance entities\nexport {\n InstanceStatusEnum,\n StepExecutionStatusEnum,\n WorkflowInstanceEntity,\n StepExecutionEntity,\n} from './instance';\n\n// Approval entities\nexport {\n ApprovalStatusEnum,\n ApprovalDecisionEnum,\n ApprovalRequestEntity,\n ApprovalCommentEntity,\n} from './approval';\n\n// Schema contribution\nimport {\n WorkflowStatusEnum,\n WorkflowTriggerTypeEnum,\n WorkflowDefinitionEntity,\n} from './workflow';\nimport { StepTypeEnum, ApprovalModeEnum, WorkflowStepEntity } from './step';\nimport {\n InstanceStatusEnum,\n StepExecutionStatusEnum,\n WorkflowInstanceEntity,\n StepExecutionEntity,\n} from './instance';\nimport {\n ApprovalStatusEnum,\n ApprovalDecisionEnum,\n ApprovalRequestEntity,\n ApprovalCommentEntity,\n} from './approval';\nimport type { ModuleSchemaContribution } from '@contractspec/lib.schema';\n\nexport const workflowSystemEntities = [\n WorkflowDefinitionEntity,\n WorkflowStepEntity,\n WorkflowInstanceEntity,\n StepExecutionEntity,\n ApprovalRequestEntity,\n ApprovalCommentEntity,\n];\n\nexport const workflowSystemSchemaContribution: ModuleSchemaContribution = {\n moduleId: '@contractspec/example.workflow-system',\n entities: workflowSystemEntities,\n enums: [\n WorkflowStatusEnum,\n WorkflowTriggerTypeEnum,\n StepTypeEnum,\n ApprovalModeEnum,\n InstanceStatusEnum,\n StepExecutionStatusEnum,\n ApprovalStatusEnum,\n ApprovalDecisionEnum,\n ],\n};\n"],"mappings":";;;;;;AA+CA,MAAa,yBAAyB;CACpC;CACA;CACA;CACA;CACA;CACA;CACD;AAED,MAAa,mCAA6D;CACxE,UAAU;CACV,UAAU;CACV,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"instance.js","names":[],"sources":["../../src/entities/instance.ts"],"sourcesContent":["import {\n defineEntity,\n defineEntityEnum,\n field,\n index,\n} from '@contractspec/lib.schema';\n\n/**\n * Instance status enum - lifecycle of a workflow instance.\n */\nexport const InstanceStatusEnum = defineEntityEnum({\n name: 'InstanceStatus',\n values: [\n 'PENDING', // Created but not started\n 'RUNNING', // Currently executing\n 'WAITING', // Waiting for approval/event\n 'PAUSED', // Manually paused\n 'COMPLETED', // Successfully completed\n 'CANCELLED', // Cancelled by user\n 'FAILED', // Failed due to error\n 'TIMEOUT', // Timed out\n ] as const,\n schema: 'workflow',\n description: 'Status of a workflow instance.',\n});\n\n/**\n * Step execution status enum.\n */\nexport const StepExecutionStatusEnum = defineEntityEnum({\n name: 'StepExecutionStatus',\n values: [\n 'PENDING', // Not yet started\n 'ACTIVE', // Currently active\n 'COMPLETED', // Successfully completed\n 'SKIPPED', // Skipped due to condition\n 'FAILED', // Failed\n 'TIMEOUT', // Timed out\n ] as const,\n schema: 'workflow',\n description: 'Status of a step execution.',\n});\n\n/**\n * WorkflowInstance entity - a running instance of a workflow.\n *\n * When a workflow is triggered, an instance is created. The instance\n * tracks the current state and all data associated with this execution.\n */\nexport const WorkflowInstanceEntity = defineEntity({\n name: 'WorkflowInstance',\n description: 'A running instance of a workflow definition.',\n schema: 'workflow',\n map: 'workflow_instance',\n fields: {\n id: field.id({ description: 'Unique instance ID' }),\n\n // Parent workflow\n workflowDefinitionId: field.foreignKey(),\n\n // Reference\n referenceId: field.string({\n isOptional: true,\n description: 'External reference (e.g., order ID)',\n }),\n referenceType: field.string({\n isOptional: true,\n description: 'Type of reference (e.g., \"Order\")',\n }),\n\n // Current state\n status: field.enum('InstanceStatus', { default: 'PENDING' }),\n currentStepId: field.string({\n isOptional: true,\n description: 'Current step being executed',\n }),\n\n // Context data - passed through the workflow\n contextData: field.json({ description: 'Data context for this instance' }),\n\n // Trigger info\n triggeredBy: field.foreignKey({\n description: 'User who triggered the workflow',\n }),\n triggerSource: field.string({\n isOptional: true,\n description: 'Source of trigger (e.g., \"api\", \"ui\")',\n }),\n\n // Ownership\n organizationId: field.foreignKey(),\n\n // Priority\n priority: field.int({\n default: 0,\n description: 'Processing priority (higher = more urgent)',\n }),\n\n // Deadlines\n dueAt: field.dateTime({\n isOptional: true,\n description: 'When this instance should complete',\n }),\n\n // Results\n outcome: field.string({\n isOptional: true,\n description: 'Final outcome (e.g., \"approved\", \"rejected\")',\n }),\n resultData: field.json({\n isOptional: true,\n description: 'Final result data',\n }),\n errorMessage: field.string({\n isOptional: true,\n description: 'Error message if failed',\n }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n startedAt: field.dateTime({ isOptional: true }),\n completedAt: field.dateTime({ isOptional: true }),\n\n // Relations\n workflowDefinition: field.belongsTo(\n 'WorkflowDefinition',\n ['workflowDefinitionId'],\n ['id']\n ),\n currentStep: field.belongsTo('WorkflowStep', ['currentStepId'], ['id']),\n stepExecutions: field.hasMany('StepExecution'),\n approvalRequests: field.hasMany('ApprovalRequest'),\n },\n indexes: [\n index.on(['organizationId', 'status']),\n index.on(['workflowDefinitionId', 'status']),\n index.on(['referenceType', 'referenceId']),\n index.on(['triggeredBy', 'status']),\n index.on(['status', 'dueAt']),\n index.on(['createdAt']),\n ],\n enums: [InstanceStatusEnum],\n});\n\n/**\n * StepExecution entity - tracks execution of a step within an instance.\n */\nexport const StepExecutionEntity = defineEntity({\n name: 'StepExecution',\n description: 'Execution record of a step within a workflow instance.',\n schema: 'workflow',\n map: 'step_execution',\n fields: {\n id: field.id({ description: 'Unique execution ID' }),\n\n // Parent\n workflowInstanceId: field.foreignKey(),\n workflowStepId: field.foreignKey(),\n\n // Status\n status: field.enum('StepExecutionStatus', { default: 'PENDING' }),\n\n // Execution order\n executionOrder: field.int({\n default: 0,\n description: 'Order of execution within instance',\n }),\n\n // Input/Output\n inputData: field.json({\n isOptional: true,\n description: 'Data when entering step',\n }),\n outputData: field.json({\n isOptional: true,\n description: 'Data when exiting step',\n }),\n\n // Action taken\n actionTaken: field.string({\n isOptional: true,\n description: 'Action that caused transition (e.g., \"approve\")',\n }),\n transitionedTo: field.string({\n isOptional: true,\n description: 'Step key transitioned to',\n }),\n\n // Executor\n executedBy: field.string({\n isOptional: true,\n description: 'User who completed this step',\n }),\n\n // Error\n errorMessage: field.string({ isOptional: true }),\n errorDetails: field.json({ isOptional: true }),\n\n // Retries\n retryCount: field.int({ default: 0 }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n startedAt: field.dateTime({ isOptional: true }),\n completedAt: field.dateTime({ isOptional: true }),\n\n // Relations\n workflowInstance: field.belongsTo(\n 'WorkflowInstance',\n ['workflowInstanceId'],\n ['id'],\n { onDelete: 'Cascade' }\n ),\n workflowStep: field.belongsTo('WorkflowStep', ['workflowStepId'], ['id']),\n },\n indexes: [\n index.on(['workflowInstanceId', 'executionOrder']),\n index.on(['workflowInstanceId', 'workflowStepId']),\n index.on(['status']),\n ],\n enums: [StepExecutionStatusEnum],\n});\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"step.js","names":[],"sources":["../../src/entities/step.ts"],"sourcesContent":["import {\n defineEntity,\n defineEntityEnum,\n field,\n index,\n} from '@contractspec/lib.schema';\n\n/**\n * Step type enum - what kind of step this is.\n */\nexport const StepTypeEnum = defineEntityEnum({\n name: 'StepType',\n values: [\n 'START', // Entry point\n 'APPROVAL', // Requires human approval\n 'TASK', // Task to be completed\n 'CONDITION', // Branching based on conditions\n 'PARALLEL', // Parallel execution\n 'WAIT', // Wait for event/time\n 'ACTION', // Automated action\n 'END', // Terminal state\n ] as const,\n schema: 'workflow',\n description: 'Type of workflow step.',\n});\n\n/**\n * Approval mode enum - how approvals are handled.\n */\nexport const ApprovalModeEnum = defineEntityEnum({\n name: 'ApprovalMode',\n values: [\n 'ANY', // Any one approver can approve\n 'ALL', // All approvers must approve\n 'MAJORITY', // Majority must approve\n 'SEQUENTIAL', // Approvers must approve in order\n ] as const,\n schema: 'workflow',\n description: 'How multiple approvers are handled.',\n});\n\n/**\n * WorkflowStep entity - defines a step in a workflow.\n *\n * Each step represents a state in the workflow state machine,\n * with transitions defined by the `transitions` JSON field.\n */\nexport const WorkflowStepEntity = defineEntity({\n name: 'WorkflowStep',\n description: 'A single step/state in a workflow definition.',\n schema: 'workflow',\n map: 'workflow_step',\n fields: {\n id: field.id({ description: 'Unique step ID' }),\n\n // Parent workflow\n workflowDefinitionId: field.foreignKey(),\n\n // Identity\n name: field.string({ description: 'Human-readable step name' }),\n key: field.string({\n description: 'Unique key within workflow (e.g., \"manager_approval\")',\n }),\n description: field.string({ isOptional: true }),\n\n // Type\n type: field.enum('StepType', { default: 'TASK' }),\n\n // Position in UI\n position: field.int({ default: 0, description: 'Order for display' }),\n\n // State machine transitions (JSON: { \"approve\": \"next_step\", \"reject\": \"rejected\" })\n transitions: field.json({ description: 'Map of action -> next step key' }),\n\n // Approval configuration (when type is APPROVAL)\n approvalMode: field.enum('ApprovalMode', {\n default: 'ANY',\n isOptional: true,\n }),\n approverRoles: field.string({\n isArray: true,\n description: 'Roles that can approve',\n }),\n approverUserIds: field.string({\n isArray: true,\n description: 'Specific users that can approve',\n }),\n escalationConfig: field.json({\n isOptional: true,\n description: 'Escalation rules',\n }),\n\n // Task configuration (when type is TASK)\n assigneeRoles: field.string({\n isArray: true,\n description: 'Roles that can be assigned',\n }),\n taskTemplate: field.json({\n isOptional: true,\n description: 'Template for task creation',\n }),\n\n // Condition configuration (when type is CONDITION)\n conditionExpression: field.string({\n isOptional: true,\n description: 'Expression for branching',\n }),\n\n // Wait configuration (when type is WAIT)\n waitDuration: field.int({\n isOptional: true,\n description: 'Wait duration in seconds',\n }),\n waitForEvent: field.string({\n isOptional: true,\n description: 'Event name to wait for',\n }),\n\n // Action configuration (when type is ACTION)\n actionType: field.string({\n isOptional: true,\n description: 'Action to execute',\n }),\n actionConfig: field.json({\n isOptional: true,\n description: 'Action parameters',\n }),\n\n // Timeout & SLA\n timeoutSeconds: field.int({\n isOptional: true,\n description: 'Step timeout',\n }),\n slaSeconds: field.int({ isOptional: true, description: 'SLA deadline' }),\n\n // Notifications\n notifyOnEnter: field.json({\n isOptional: true,\n description: 'Notification config when entering step',\n }),\n notifyOnExit: field.json({\n isOptional: true,\n description: 'Notification config when exiting step',\n }),\n\n // Metadata\n metadata: field.json({ isOptional: true }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n\n // Relations\n workflowDefinition: field.belongsTo(\n 'WorkflowDefinition',\n ['workflowDefinitionId'],\n ['id'],\n { onDelete: 'Cascade' }\n ),\n executions: field.hasMany('StepExecution'),\n },\n indexes: [\n index.unique(['workflowDefinitionId', 'key']),\n index.on(['workflowDefinitionId', 'position']),\n index.on(['type']),\n ],\n enums: [StepTypeEnum, ApprovalModeEnum],\n});\n"],"mappings":";;;;;;AAUA,MAAa,eAAe,iBAAiB;CAC3C,MAAM;CACN,QAAQ;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,QAAQ;CACR,aAAa;CACd,CAAC;;;;AAKF,MAAa,mBAAmB,iBAAiB;CAC/C,MAAM;CACN,QAAQ;EACN;EACA;EACA;EACA;EACD;CACD,QAAQ;CACR,aAAa;CACd,CAAC;;;;;;;AAQF,MAAa,qBAAqB,aAAa;CAC7C,MAAM;CACN,aAAa;CACb,QAAQ;CACR,KAAK;CACL,QAAQ;EACN,IAAI,MAAM,GAAG,EAAE,aAAa,kBAAkB,CAAC;EAG/C,sBAAsB,MAAM,YAAY;EAGxC,MAAM,MAAM,OAAO,EAAE,aAAa,4BAA4B,CAAC;EAC/D,KAAK,MAAM,OAAO,EAChB,aAAa,2DACd,CAAC;EACF,aAAa,MAAM,OAAO,EAAE,YAAY,MAAM,CAAC;EAG/C,MAAM,MAAM,KAAK,YAAY,EAAE,SAAS,QAAQ,CAAC;EAGjD,UAAU,MAAM,IAAI;GAAE,SAAS;GAAG,aAAa;GAAqB,CAAC;EAGrE,aAAa,MAAM,KAAK,EAAE,aAAa,kCAAkC,CAAC;EAG1E,cAAc,MAAM,KAAK,gBAAgB;GACvC,SAAS;GACT,YAAY;GACb,CAAC;EACF,eAAe,MAAM,OAAO;GAC1B,SAAS;GACT,aAAa;GACd,CAAC;EACF,iBAAiB,MAAM,OAAO;GAC5B,SAAS;GACT,aAAa;GACd,CAAC;EACF,kBAAkB,MAAM,KAAK;GAC3B,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,eAAe,MAAM,OAAO;GAC1B,SAAS;GACT,aAAa;GACd,CAAC;EACF,cAAc,MAAM,KAAK;GACvB,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,qBAAqB,MAAM,OAAO;GAChC,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,cAAc,MAAM,IAAI;GACtB,YAAY;GACZ,aAAa;GACd,CAAC;EACF,cAAc,MAAM,OAAO;GACzB,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,YAAY,MAAM,OAAO;GACvB,YAAY;GACZ,aAAa;GACd,CAAC;EACF,cAAc,MAAM,KAAK;GACvB,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,gBAAgB,MAAM,IAAI;GACxB,YAAY;GACZ,aAAa;GACd,CAAC;EACF,YAAY,MAAM,IAAI;GAAE,YAAY;GAAM,aAAa;GAAgB,CAAC;EAGxE,eAAe,MAAM,KAAK;GACxB,YAAY;GACZ,aAAa;GACd,CAAC;EACF,cAAc,MAAM,KAAK;GACvB,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,UAAU,MAAM,KAAK,EAAE,YAAY,MAAM,CAAC;EAG1C,WAAW,MAAM,WAAW;EAC5B,WAAW,MAAM,WAAW;EAG5B,oBAAoB,MAAM,UACxB,sBACA,CAAC,uBAAuB,EACxB,CAAC,KAAK,EACN,EAAE,UAAU,WAAW,CACxB;EACD,YAAY,MAAM,QAAQ,gBAAgB;EAC3C;CACD,SAAS;EACP,MAAM,OAAO,CAAC,wBAAwB,MAAM,CAAC;EAC7C,MAAM,GAAG,CAAC,wBAAwB,WAAW,CAAC;EAC9C,MAAM,GAAG,CAAC,OAAO,CAAC;EACnB;CACD,OAAO,CAAC,cAAc,iBAAiB;CACxC,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"workflow.js","names":[],"sources":["../../src/entities/workflow.ts"],"sourcesContent":["import {\n defineEntity,\n defineEntityEnum,\n field,\n index,\n} from '@contractspec/lib.schema';\n\n/**\n * Workflow status enum - the lifecycle state of a workflow definition.\n */\nexport const WorkflowStatusEnum = defineEntityEnum({\n name: 'WorkflowStatus',\n values: ['DRAFT', 'ACTIVE', 'DEPRECATED', 'ARCHIVED'] as const,\n schema: 'workflow',\n description: 'Status of a workflow definition.',\n});\n\n/**\n * Workflow trigger type enum - what initiates a workflow.\n */\nexport const WorkflowTriggerTypeEnum = defineEntityEnum({\n name: 'WorkflowTriggerType',\n values: ['MANUAL', 'EVENT', 'SCHEDULED', 'API'] as const,\n schema: 'workflow',\n description: 'What triggers workflow instantiation.',\n});\n\n/**\n * WorkflowDefinition entity - defines a workflow blueprint.\n *\n * A workflow definition specifies the structure, steps, and rules\n * for a business process. Instances are created from definitions.\n */\nexport const WorkflowDefinitionEntity = defineEntity({\n name: 'WorkflowDefinition',\n description: 'A workflow blueprint that defines the process structure.',\n schema: 'workflow',\n map: 'workflow_definition',\n fields: {\n id: field.id({ description: 'Unique workflow definition ID' }),\n\n // Identity\n name: field.string({ description: 'Human-readable workflow name' }),\n key: field.string({\n description: 'Unique key for referencing (e.g., \"purchase_approval\")',\n }),\n description: field.string({\n isOptional: true,\n description: 'Detailed description',\n }),\n version: field.int({\n default: 1,\n description: 'Version number for versioning definitions',\n }),\n\n // Status\n status: field.enum('WorkflowStatus', { default: 'DRAFT' }),\n\n // Trigger\n triggerType: field.enum('WorkflowTriggerType', { default: 'MANUAL' }),\n triggerConfig: field.json({\n isOptional: true,\n description: 'Trigger-specific configuration',\n }),\n\n // Initial step\n initialStepId: field.string({\n isOptional: true,\n description: 'First step when workflow starts',\n }),\n\n // Feature flag integration\n featureFlagKey: field.string({\n isOptional: true,\n description: 'Feature flag to control availability',\n }),\n\n // Configuration\n settings: field.json({\n isOptional: true,\n description: 'Workflow-wide settings',\n }),\n metadata: field.json({ isOptional: true, description: 'Custom metadata' }),\n\n // Ownership\n organizationId: field.foreignKey({ description: 'Owning organization' }),\n createdBy: field.foreignKey({\n description: 'User who created this workflow',\n }),\n\n // Timestamps\n createdAt: field.createdAt(),\n updatedAt: field.updatedAt(),\n publishedAt: field.dateTime({\n isOptional: true,\n description: 'When workflow was activated',\n }),\n\n // Relations\n steps: field.hasMany('WorkflowStep'),\n instances: field.hasMany('WorkflowInstance'),\n },\n indexes: [\n index.unique(['organizationId', 'key', 'version']),\n index.on(['organizationId', 'status']),\n index.on(['key', 'version']),\n ],\n enums: [WorkflowStatusEnum, WorkflowTriggerTypeEnum],\n});\n"],"mappings":";;;;;;AAUA,MAAa,qBAAqB,iBAAiB;CACjD,MAAM;CACN,QAAQ;EAAC;EAAS;EAAU;EAAc;EAAW;CACrD,QAAQ;CACR,aAAa;CACd,CAAC;;;;AAKF,MAAa,0BAA0B,iBAAiB;CACtD,MAAM;CACN,QAAQ;EAAC;EAAU;EAAS;EAAa;EAAM;CAC/C,QAAQ;CACR,aAAa;CACd,CAAC;;;;;;;AAQF,MAAa,2BAA2B,aAAa;CACnD,MAAM;CACN,aAAa;CACb,QAAQ;CACR,KAAK;CACL,QAAQ;EACN,IAAI,MAAM,GAAG,EAAE,aAAa,iCAAiC,CAAC;EAG9D,MAAM,MAAM,OAAO,EAAE,aAAa,gCAAgC,CAAC;EACnE,KAAK,MAAM,OAAO,EAChB,aAAa,4DACd,CAAC;EACF,aAAa,MAAM,OAAO;GACxB,YAAY;GACZ,aAAa;GACd,CAAC;EACF,SAAS,MAAM,IAAI;GACjB,SAAS;GACT,aAAa;GACd,CAAC;EAGF,QAAQ,MAAM,KAAK,kBAAkB,EAAE,SAAS,SAAS,CAAC;EAG1D,aAAa,MAAM,KAAK,uBAAuB,EAAE,SAAS,UAAU,CAAC;EACrE,eAAe,MAAM,KAAK;GACxB,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,eAAe,MAAM,OAAO;GAC1B,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,gBAAgB,MAAM,OAAO;GAC3B,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,UAAU,MAAM,KAAK;GACnB,YAAY;GACZ,aAAa;GACd,CAAC;EACF,UAAU,MAAM,KAAK;GAAE,YAAY;GAAM,aAAa;GAAmB,CAAC;EAG1E,gBAAgB,MAAM,WAAW,EAAE,aAAa,uBAAuB,CAAC;EACxE,WAAW,MAAM,WAAW,EAC1B,aAAa,kCACd,CAAC;EAGF,WAAW,MAAM,WAAW;EAC5B,WAAW,MAAM,WAAW;EAC5B,aAAa,MAAM,SAAS;GAC1B,YAAY;GACZ,aAAa;GACd,CAAC;EAGF,OAAO,MAAM,QAAQ,eAAe;EACpC,WAAW,MAAM,QAAQ,mBAAmB;EAC7C;CACD,SAAS;EACP,MAAM,OAAO;GAAC;GAAkB;GAAO;GAAU,CAAC;EAClD,MAAM,GAAG,CAAC,kBAAkB,SAAS,CAAC;EACtC,MAAM,GAAG,CAAC,OAAO,UAAU,CAAC;EAC7B;CACD,OAAO,CAAC,oBAAoB,wBAAwB;CACrD,CAAC"}
@@ -1 +0,0 @@
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"}
@@ -1 +0,0 @@
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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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"instance.enum.js","names":[],"sources":["../../src/instance/instance.enum.ts"],"sourcesContent":["import { defineEnum } from '@contractspec/lib.schema';\n\n/**\n * Instance status enum.\n */\nexport const InstanceStatusEnum = defineEnum('InstanceStatus', [\n 'PENDING',\n 'RUNNING',\n 'WAITING',\n 'PAUSED',\n 'COMPLETED',\n 'CANCELLED',\n 'FAILED',\n 'TIMEOUT',\n]);\n"],"mappings":";;;;;;AAKA,MAAa,qBAAqB,WAAW,kBAAkB;CAC7D;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"instance.event.js","names":[],"sources":["../../src/instance/instance.event.ts"],"sourcesContent":["import { defineEvent, defineSchemaModel } from '@contractspec/lib.contracts';\nimport { ScalarTypeEnum } from '@contractspec/lib.schema';\n\n/**\n * Base payload for instance events.\n */\nconst InstanceEventPayload = defineSchemaModel({\n name: 'InstanceEventPayload',\n description: 'Base payload for instance events',\n fields: {\n instanceId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n workflowId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n workflowKey: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n status: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n referenceId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n referenceType: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n triggeredBy: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n organizationId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n timestamp: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\n/**\n * Payload for step transition events.\n */\nconst StepTransitionPayload = defineSchemaModel({\n name: 'StepTransitionEventPayload',\n description: 'Payload for step transition events',\n fields: {\n instanceId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n workflowId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n fromStepKey: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n toStepKey: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n action: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n executedBy: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n timestamp: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\n/**\n * Payload when instance completes.\n */\nconst InstanceCompletedPayload = defineSchemaModel({\n name: 'InstanceCompletedEventPayload',\n description: 'Payload when instance completes',\n fields: {\n instanceId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n workflowId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n workflowKey: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n outcome: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n referenceId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n referenceType: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n duration: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n timestamp: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n },\n});\n\n/**\n * InstanceStartedEvent - A new workflow instance has been started.\n */\nexport const InstanceStartedEvent = defineEvent({\n meta: {\n key: 'workflow.instance.started',\n version: '1.0.0',\n description: 'A new workflow instance has been started.',\n stability: 'stable',\n owners: ['@workflow-team'],\n tags: ['workflow', 'instance', 'started'],\n },\n payload: InstanceEventPayload,\n});\n\n/**\n * StepEnteredEvent - A workflow instance has entered a new step.\n */\nexport const StepEnteredEvent = defineEvent({\n meta: {\n key: 'workflow.step.entered',\n version: '1.0.0',\n description: 'A workflow instance has entered a new step.',\n stability: 'stable',\n owners: ['@workflow-team'],\n tags: ['workflow', 'step', 'entered'],\n },\n payload: StepTransitionPayload,\n});\n\n/**\n * StepExitedEvent - A workflow instance has exited a step.\n */\nexport const StepExitedEvent = defineEvent({\n meta: {\n key: 'workflow.step.exited',\n version: '1.0.0',\n description: 'A workflow instance has exited a step.',\n stability: 'stable',\n owners: ['@workflow-team'],\n tags: ['workflow', 'step', 'exited'],\n },\n payload: StepTransitionPayload,\n});\n\n/**\n * InstanceCompletedEvent - A workflow instance has completed.\n */\nexport const InstanceCompletedEvent = defineEvent({\n meta: {\n key: 'workflow.instance.completed',\n version: '1.0.0',\n description: 'A workflow instance has completed.',\n stability: 'stable',\n owners: ['@workflow-team'],\n tags: ['workflow', 'instance', 'completed'],\n },\n payload: InstanceCompletedPayload,\n});\n\n/**\n * InstanceCancelledEvent - A workflow instance has been cancelled.\n */\nexport const InstanceCancelledEvent = defineEvent({\n meta: {\n key: 'workflow.instance.cancelled',\n version: '1.0.0',\n description: 'A workflow instance has been cancelled.',\n stability: 'stable',\n owners: ['@workflow-team'],\n tags: ['workflow', 'instance', 'cancelled'],\n },\n payload: InstanceEventPayload,\n});\n\n/**\n * InstancePausedEvent - A workflow instance has been paused.\n */\nexport const InstancePausedEvent = defineEvent({\n meta: {\n key: 'workflow.instance.paused',\n version: '1.0.0',\n description: 'A workflow instance has been paused.',\n stability: 'stable',\n owners: ['@workflow-team'],\n tags: ['workflow', 'instance', 'paused'],\n },\n payload: InstanceEventPayload,\n});\n\n/**\n * InstanceResumedEvent - A workflow instance has been resumed.\n */\nexport const InstanceResumedEvent = defineEvent({\n meta: {\n key: 'workflow.instance.resumed',\n version: '1.0.0',\n description: 'A workflow instance has been resumed.',\n stability: 'stable',\n owners: ['@workflow-team'],\n tags: ['workflow', 'instance', 'resumed'],\n },\n payload: InstanceEventPayload,\n});\n\n/**\n * InstanceFailedEvent - A workflow instance has failed.\n */\nexport const InstanceFailedEvent = defineEvent({\n meta: {\n key: 'workflow.instance.failed',\n version: '1.0.0',\n description: 'A workflow instance has failed.',\n stability: 'stable',\n owners: ['@workflow-team'],\n tags: ['workflow', 'instance', 'failed'],\n },\n payload: InstanceEventPayload,\n});\n\n/**\n * InstanceTimedOutEvent - A workflow instance has timed out.\n */\nexport const InstanceTimedOutEvent = defineEvent({\n meta: {\n key: 'workflow.instance.timedOut',\n version: '1.0.0',\n description: 'A workflow instance has timed out.',\n stability: 'stable',\n owners: ['@workflow-team'],\n tags: ['workflow', 'instance', 'timeout'],\n },\n payload: InstanceEventPayload,\n});\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"instance.handler.js","names":[],"sources":["../../src/instance/instance.handler.ts"],"sourcesContent":["/**\n * Workflow instance handlers.\n */\n\nimport type { StateMachineState, TransitionContext } from '../state-machine';\nimport {\n createStateMachineEngine,\n buildStateMachineDefinition,\n} from '../state-machine';\nimport type { WorkflowInstanceRecord, HandlerContext } from '../shared/types';\nimport { mockDataStore } from '../shared/mock-data';\nimport { createApprovalRequests } from '../approval/approval.handler';\n\nexport async function handleStartWorkflow(\n input: {\n workflowKey: string;\n contextData?: Record<string, unknown>;\n referenceId?: string;\n referenceType?: string;\n priority?: number;\n dueAt?: Date;\n },\n context: HandlerContext\n): Promise<WorkflowInstanceRecord> {\n // Find active workflow by key\n const workflow = Array.from(mockDataStore.workflows.values()).find(\n (w) =>\n w.key === input.workflowKey &&\n w.status === 'ACTIVE' &&\n w.organizationId === context.organizationId\n );\n\n if (!workflow) {\n throw new Error(`Active workflow ${input.workflowKey} not found`);\n }\n\n const id = `inst_${Date.now()}`;\n const now = new Date();\n\n const instance: WorkflowInstanceRecord = {\n id,\n workflowDefinitionId: workflow.id,\n referenceId: input.referenceId,\n referenceType: input.referenceType,\n status: 'RUNNING',\n currentStepId: workflow.initialStepId,\n contextData: input.contextData ?? {},\n triggeredBy: context.userId,\n organizationId: context.organizationId,\n priority: input.priority ?? 0,\n dueAt: input.dueAt,\n createdAt: now,\n updatedAt: now,\n startedAt: now,\n };\n\n mockDataStore.instances.set(id, instance);\n\n // Check if first step is an approval step\n if (workflow.initialStepId) {\n const firstStep = mockDataStore.steps.get(workflow.initialStepId);\n if (firstStep?.type === 'APPROVAL') {\n instance.status = 'WAITING';\n await createApprovalRequests(instance, firstStep, context);\n }\n }\n\n return instance;\n}\n\nexport async function handleTransitionWorkflow(\n input: {\n instanceId: string;\n action: string;\n data?: Record<string, unknown>;\n comment?: string;\n },\n context: HandlerContext\n): Promise<{\n success: boolean;\n instance: WorkflowInstanceRecord;\n previousStepKey?: string;\n currentStepKey?: string;\n message?: string;\n}> {\n const instance = mockDataStore.instances.get(input.instanceId);\n if (!instance) {\n throw new Error(`Instance ${input.instanceId} not found`);\n }\n\n const workflow = mockDataStore.workflows.get(instance.workflowDefinitionId);\n if (!workflow) {\n throw new Error(`Workflow ${instance.workflowDefinitionId} not found`);\n }\n\n // Get all steps for this workflow\n const steps = Array.from(mockDataStore.steps.values()).filter(\n (s) => s.workflowDefinitionId === workflow.id\n );\n\n // Build state machine\n const definition = buildStateMachineDefinition(\n {\n key: workflow.key,\n name: workflow.name,\n version: workflow.version,\n initialStepId: workflow.initialStepId ?? null,\n },\n steps\n );\n const currentStep = steps.find((s) => s.id === instance.currentStepId);\n\n const state: StateMachineState = {\n currentStepKey: currentStep?.key ?? '',\n status: instance.status,\n contextData: instance.contextData,\n history: [],\n };\n\n const transitionContext: TransitionContext = {\n userId: context.userId,\n userRoles: context.userRoles,\n data: input.data,\n };\n\n const engine = createStateMachineEngine();\n const result = engine.transition(\n definition,\n state,\n input.action,\n transitionContext\n );\n\n if (!result.success) {\n return {\n success: false,\n instance,\n message: result.error,\n };\n }\n\n // Update instance\n const previousStepKey = currentStep?.key;\n const newStep = steps.find((s) => s.key === result.currentStepKey);\n\n instance.currentStepId = newStep?.id;\n instance.status = result.status;\n instance.contextData = { ...instance.contextData, ...input.data };\n instance.updatedAt = new Date();\n\n if (result.status === 'COMPLETED') {\n instance.completedAt = new Date();\n instance.outcome = input.action;\n }\n\n // Handle approval steps\n if (newStep?.type === 'APPROVAL') {\n instance.status = 'WAITING';\n await createApprovalRequests(instance, newStep, context);\n }\n\n return {\n success: true,\n instance,\n previousStepKey,\n currentStepKey: result.currentStepKey ?? undefined,\n };\n}\n"],"mappings":";;;;;AAaA,eAAsB,oBACpB,OAQA,SACiC;CAEjC,MAAM,WAAW,MAAM,KAAK,cAAc,UAAU,QAAQ,CAAC,CAAC,MAC3D,MACC,EAAE,QAAQ,MAAM,eAChB,EAAE,WAAW,YACb,EAAE,mBAAmB,QAAQ,eAChC;AAED,KAAI,CAAC,SACH,OAAM,IAAI,MAAM,mBAAmB,MAAM,YAAY,YAAY;CAGnE,MAAM,KAAK,QAAQ,KAAK,KAAK;CAC7B,MAAM,sBAAM,IAAI,MAAM;CAEtB,MAAM,WAAmC;EACvC;EACA,sBAAsB,SAAS;EAC/B,aAAa,MAAM;EACnB,eAAe,MAAM;EACrB,QAAQ;EACR,eAAe,SAAS;EACxB,aAAa,MAAM,eAAe,EAAE;EACpC,aAAa,QAAQ;EACrB,gBAAgB,QAAQ;EACxB,UAAU,MAAM,YAAY;EAC5B,OAAO,MAAM;EACb,WAAW;EACX,WAAW;EACX,WAAW;EACZ;AAED,eAAc,UAAU,IAAI,IAAI,SAAS;AAGzC,KAAI,SAAS,eAAe;EAC1B,MAAM,YAAY,cAAc,MAAM,IAAI,SAAS,cAAc;AACjE,MAAI,WAAW,SAAS,YAAY;AAClC,YAAS,SAAS;AAClB,SAAM,uBAAuB,UAAU,WAAW,QAAQ;;;AAI9D,QAAO;;AAGT,eAAsB,yBACpB,OAMA,SAOC;CACD,MAAM,WAAW,cAAc,UAAU,IAAI,MAAM,WAAW;AAC9D,KAAI,CAAC,SACH,OAAM,IAAI,MAAM,YAAY,MAAM,WAAW,YAAY;CAG3D,MAAM,WAAW,cAAc,UAAU,IAAI,SAAS,qBAAqB;AAC3E,KAAI,CAAC,SACH,OAAM,IAAI,MAAM,YAAY,SAAS,qBAAqB,YAAY;CAIxE,MAAM,QAAQ,MAAM,KAAK,cAAc,MAAM,QAAQ,CAAC,CAAC,QACpD,MAAM,EAAE,yBAAyB,SAAS,GAC5C;CAGD,MAAM,aAAa,4BACjB;EACE,KAAK,SAAS;EACd,MAAM,SAAS;EACf,SAAS,SAAS;EAClB,eAAe,SAAS,iBAAiB;EAC1C,EACD,MACD;CACD,MAAM,cAAc,MAAM,MAAM,MAAM,EAAE,OAAO,SAAS,cAAc;CAEtE,MAAM,QAA2B;EAC/B,gBAAgB,aAAa,OAAO;EACpC,QAAQ,SAAS;EACjB,aAAa,SAAS;EACtB,SAAS,EAAE;EACZ;CAED,MAAM,oBAAuC;EAC3C,QAAQ,QAAQ;EAChB,WAAW,QAAQ;EACnB,MAAM,MAAM;EACb;CAGD,MAAM,SADS,0BAA0B,CACnB,WACpB,YACA,OACA,MAAM,QACN,kBACD;AAED,KAAI,CAAC,OAAO,QACV,QAAO;EACL,SAAS;EACT;EACA,SAAS,OAAO;EACjB;CAIH,MAAM,kBAAkB,aAAa;CACrC,MAAM,UAAU,MAAM,MAAM,MAAM,EAAE,QAAQ,OAAO,eAAe;AAElE,UAAS,gBAAgB,SAAS;AAClC,UAAS,SAAS,OAAO;AACzB,UAAS,cAAc;EAAE,GAAG,SAAS;EAAa,GAAG,MAAM;EAAM;AACjE,UAAS,4BAAY,IAAI,MAAM;AAE/B,KAAI,OAAO,WAAW,aAAa;AACjC,WAAS,8BAAc,IAAI,MAAM;AACjC,WAAS,UAAU,MAAM;;AAI3B,KAAI,SAAS,SAAS,YAAY;AAChC,WAAS,SAAS;AAClB,QAAM,uBAAuB,UAAU,SAAS,QAAQ;;AAG1D,QAAO;EACL,SAAS;EACT;EACA;EACA,gBAAgB,OAAO,kBAAkB;EAC1C"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"instance.operations.js","names":[],"sources":["../../src/instance/instance.operations.ts"],"sourcesContent":["import {\n defineCommand,\n defineQuery,\n} from '@contractspec/lib.contracts/operations';\nimport { defineSchemaModel, ScalarTypeEnum } from '@contractspec/lib.schema';\nimport { InstanceStatusEnum } from './instance.enum';\nimport {\n StartWorkflowInputModel,\n TransitionInputModel,\n TransitionResultModel,\n WorkflowInstanceModel,\n} from './instance.schema';\n\nconst OWNERS = ['@example.workflow-system'] as const;\n\n/**\n * Start a new workflow instance.\n */\nexport const StartWorkflowContract = defineCommand({\n meta: {\n key: 'workflow.instance.start',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['workflow', 'instance', 'start'],\n description: 'Start a new workflow instance.',\n goal: 'Initiate a workflow for a business process.',\n context: 'Order creation, request submission, etc.',\n },\n io: {\n input: StartWorkflowInputModel,\n output: WorkflowInstanceModel,\n },\n policy: { auth: 'user' },\n sideEffects: {\n emits: [\n {\n key: 'workflow.instance.started',\n version: '1.0.0',\n when: 'Workflow starts',\n payload: WorkflowInstanceModel,\n },\n {\n key: 'workflow.step.entered',\n version: '1.0.0',\n when: 'First step entered',\n payload: WorkflowInstanceModel,\n },\n ],\n audit: ['workflow.instance.started'],\n },\n acceptance: {\n scenarios: [\n {\n key: 'start-workflow-happy-path',\n given: ['Workflow definition exists'],\n when: ['User starts workflow'],\n then: ['Instance is created and started'],\n },\n ],\n examples: [\n {\n key: 'start-onboarding',\n input: {\n workflowKey: 'onboarding-v1',\n context: { employeeId: 'emp-123' },\n },\n output: { id: 'inst-456', status: 'running' },\n },\n ],\n },\n});\n\n/**\n * Transition workflow to next step.\n */\nexport const TransitionWorkflowContract = defineCommand({\n meta: {\n key: 'workflow.instance.transition',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['workflow', 'instance', 'transition', 'state-machine'],\n description: 'Transition a workflow instance to the next step.',\n goal: 'Move workflow forward based on action.',\n context: 'Task completion, approval decisions.',\n },\n io: {\n input: TransitionInputModel,\n output: TransitionResultModel,\n },\n policy: { auth: 'user' },\n sideEffects: {\n emits: [\n {\n key: 'workflow.step.exited',\n version: '1.0.0',\n when: 'Step is exited',\n payload: WorkflowInstanceModel,\n },\n {\n key: 'workflow.step.entered',\n version: '1.0.0',\n when: 'New step is entered',\n payload: WorkflowInstanceModel,\n },\n {\n key: 'workflow.instance.completed',\n version: '1.0.0',\n when: 'Workflow reaches end',\n payload: WorkflowInstanceModel,\n },\n ],\n audit: ['workflow.instance.transitioned'],\n },\n acceptance: {\n scenarios: [\n {\n key: 'transition-workflow-happy-path',\n given: ['Workflow instance is waiting at step'],\n when: ['User provides input'],\n then: ['Instance moves to next step'],\n },\n ],\n examples: [\n {\n key: 'complete-task',\n input: {\n instanceId: 'inst-456',\n action: 'complete',\n data: { approved: true },\n },\n output: { success: true, nextStep: 'notify-hr' },\n },\n ],\n },\n});\n\n/**\n * Pause a running workflow.\n */\nexport const PauseWorkflowContract = defineCommand({\n meta: {\n key: 'workflow.instance.pause',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['workflow', 'instance', 'pause'],\n description: 'Pause a running workflow instance.',\n goal: 'Temporarily halt workflow execution.',\n context: 'Administrative action, emergency stop.',\n },\n io: {\n input: defineSchemaModel({\n name: 'PauseResumeInput',\n fields: {\n instanceId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n reason: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n },\n }),\n output: WorkflowInstanceModel,\n },\n policy: { auth: 'user' },\n sideEffects: {\n emits: [\n {\n key: 'workflow.instance.paused',\n version: '1.0.0',\n when: 'Workflow is paused',\n payload: WorkflowInstanceModel,\n },\n ],\n audit: ['workflow.instance.paused'],\n },\n acceptance: {\n scenarios: [\n {\n key: 'pause-workflow-happy-path',\n given: ['Workflow is running'],\n when: ['Admin pauses workflow'],\n then: ['Instance status becomes PAUSED'],\n },\n ],\n examples: [\n {\n key: 'pause-maintenance',\n input: { instanceId: 'inst-456', reason: 'System maintenance' },\n output: { id: 'inst-456', status: 'paused' },\n },\n ],\n },\n});\n\n/**\n * Resume a paused workflow.\n */\nexport const ResumeWorkflowContract = defineCommand({\n meta: {\n key: 'workflow.instance.resume',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['workflow', 'instance', 'resume'],\n description: 'Resume a paused workflow instance.',\n goal: 'Continue workflow execution.',\n context: 'Administrative action.',\n },\n io: {\n input: defineSchemaModel({\n name: 'PauseResumeInput',\n fields: {\n instanceId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n reason: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n },\n }),\n output: WorkflowInstanceModel,\n },\n policy: { auth: 'user' },\n sideEffects: {\n emits: [\n {\n key: 'workflow.instance.resumed',\n version: '1.0.0',\n when: 'Workflow is resumed',\n payload: WorkflowInstanceModel,\n },\n ],\n audit: ['workflow.instance.resumed'],\n },\n acceptance: {\n scenarios: [\n {\n key: 'resume-workflow-happy-path',\n given: ['Workflow is paused'],\n when: ['Admin resumes workflow'],\n then: ['Instance status becomes RUNNING'],\n },\n ],\n examples: [\n {\n key: 'resume-normal',\n input: { instanceId: 'inst-456', reason: 'Issue resolved' },\n output: { id: 'inst-456', status: 'running' },\n },\n ],\n },\n});\n\n/**\n * Cancel a workflow instance.\n */\nexport const CancelWorkflowContract = defineCommand({\n meta: {\n key: 'workflow.instance.cancel',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['workflow', 'instance', 'cancel'],\n description: 'Cancel a workflow instance.',\n goal: 'Terminate workflow without completion.',\n context: 'User request, system cancellation.',\n },\n io: {\n input: defineSchemaModel({\n name: 'CancelWorkflowInput',\n fields: {\n instanceId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n reason: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n },\n }),\n output: WorkflowInstanceModel,\n },\n policy: { auth: 'user' },\n sideEffects: {\n emits: [\n {\n key: 'workflow.instance.cancelled',\n version: '1.0.0',\n when: 'Workflow is cancelled',\n payload: WorkflowInstanceModel,\n },\n ],\n audit: ['workflow.instance.cancelled'],\n },\n acceptance: {\n scenarios: [\n {\n key: 'cancel-workflow-happy-path',\n given: ['Workflow is running'],\n when: ['User cancels workflow'],\n then: ['Instance status becomes CANCELLED'],\n },\n ],\n examples: [\n {\n key: 'cancel-mistake',\n input: { instanceId: 'inst-456', reason: 'Created by mistake' },\n output: { id: 'inst-456', status: 'cancelled' },\n },\n ],\n },\n});\n\n/**\n * List workflow instances.\n */\nexport const ListInstancesContract = defineQuery({\n meta: {\n key: 'workflow.instance.list',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['workflow', 'instance', 'list'],\n description: 'List workflow instances with filtering.',\n goal: 'Browse and search running workflows.',\n context: 'Dashboard, monitoring.',\n },\n io: {\n input: defineSchemaModel({\n name: 'ListInstancesInput',\n fields: {\n workflowKey: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n status: { type: InstanceStatusEnum, isOptional: true },\n referenceType: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n referenceId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n triggeredBy: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n limit: {\n type: ScalarTypeEnum.Int_unsecure(),\n isOptional: true,\n defaultValue: 20,\n },\n offset: {\n type: ScalarTypeEnum.Int_unsecure(),\n isOptional: true,\n defaultValue: 0,\n },\n },\n }),\n output: defineSchemaModel({\n name: 'ListInstancesOutput',\n fields: {\n instances: {\n type: WorkflowInstanceModel,\n isArray: true,\n isOptional: false,\n },\n total: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n },\n }),\n },\n policy: { auth: 'user' },\n acceptance: {\n scenarios: [\n {\n key: 'list-instances-happy-path',\n given: ['Workflow instances exist'],\n when: ['User lists instances'],\n then: ['List of instances is returned'],\n },\n ],\n examples: [\n {\n key: 'list-running',\n input: { status: 'running', limit: 10 },\n output: { instances: [], total: 5 },\n },\n ],\n },\n});\n\n/**\n * Get a single workflow instance.\n */\nexport const GetInstanceContract = defineQuery({\n meta: {\n key: 'workflow.instance.get',\n version: '1.0.0',\n stability: 'stable',\n owners: [...OWNERS],\n tags: ['workflow', 'instance', 'get'],\n description: 'Get a workflow instance with details.',\n goal: 'View workflow instance details.',\n context: 'Instance detail view.',\n },\n io: {\n input: defineSchemaModel({\n name: 'GetInstanceInput',\n fields: {\n instanceId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n },\n }),\n output: WorkflowInstanceModel,\n },\n policy: { auth: 'user' },\n acceptance: {\n scenarios: [\n {\n key: 'get-instance-happy-path',\n given: ['Instance exists'],\n when: ['User requests instance details'],\n then: ['Instance details are returned'],\n },\n ],\n examples: [\n {\n key: 'get-details',\n input: { instanceId: 'inst-456' },\n output: { id: 'inst-456', workflowKey: 'onboarding-v1' },\n },\n ],\n },\n});\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"instance.schema.js","names":[],"sources":["../../src/instance/instance.schema.ts"],"sourcesContent":["import { defineSchemaModel, ScalarTypeEnum } from '@contractspec/lib.schema';\nimport { InstanceStatusEnum } from './instance.enum';\n\n/**\n * A running workflow instance.\n */\nexport const WorkflowInstanceModel = defineSchemaModel({\n name: 'WorkflowInstanceModel',\n description: 'A running workflow instance',\n fields: {\n id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n workflowDefinitionId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n referenceId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n referenceType: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n status: { type: InstanceStatusEnum, isOptional: false },\n currentStepId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n contextData: { type: ScalarTypeEnum.JSON(), isOptional: true },\n triggeredBy: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n organizationId: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: false,\n },\n priority: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },\n dueAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n outcome: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n resultData: { type: ScalarTypeEnum.JSON(), isOptional: true },\n errorMessage: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false },\n startedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n completedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n },\n});\n\n/**\n * Input for starting a workflow.\n */\nexport const StartWorkflowInputModel = defineSchemaModel({\n name: 'StartWorkflowInput',\n description: 'Input for starting a workflow',\n fields: {\n workflowKey: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },\n contextData: { type: ScalarTypeEnum.JSON(), isOptional: true },\n referenceId: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n referenceType: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n priority: { type: ScalarTypeEnum.Int_unsecure(), isOptional: true },\n dueAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },\n },\n});\n\n/**\n * Input for transitioning a workflow.\n */\nexport const TransitionInputModel = defineSchemaModel({\n name: 'TransitionInput',\n description: 'Input for transitioning a workflow',\n fields: {\n instanceId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n action: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },\n data: { type: ScalarTypeEnum.JSON(), isOptional: true },\n comment: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n },\n});\n\n/**\n * Result of a workflow transition.\n */\nexport const TransitionResultModel = defineSchemaModel({\n name: 'TransitionResult',\n description: 'Result of a workflow transition',\n fields: {\n success: { type: ScalarTypeEnum.Boolean(), isOptional: false },\n instance: { type: WorkflowInstanceModel, isOptional: false },\n previousStepKey: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n currentStepKey: {\n type: ScalarTypeEnum.String_unsecure(),\n isOptional: true,\n },\n message: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },\n },\n});\n"],"mappings":";;;;;;;AAMA,MAAa,wBAAwB,kBAAkB;CACrD,MAAM;CACN,aAAa;CACb,QAAQ;EACN,IAAI;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACjE,sBAAsB;GACpB,MAAM,eAAe,iBAAiB;GACtC,YAAY;GACb;EACD,aAAa;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EACzE,eAAe;GACb,MAAM,eAAe,iBAAiB;GACtC,YAAY;GACb;EACD,QAAQ;GAAE,MAAM;GAAoB,YAAY;GAAO;EACvD,eAAe;GACb,MAAM,eAAe,iBAAiB;GACtC,YAAY;GACb;EACD,aAAa;GAAE,MAAM,eAAe,MAAM;GAAE,YAAY;GAAM;EAC9D,aAAa;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EAC1E,gBAAgB;GACd,MAAM,eAAe,iBAAiB;GACtC,YAAY;GACb;EACD,UAAU;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAO;EACpE,OAAO;GAAE,MAAM,eAAe,UAAU;GAAE,YAAY;GAAM;EAC5D,SAAS;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EACrE,YAAY;GAAE,MAAM,eAAe,MAAM;GAAE,YAAY;GAAM;EAC7D,cAAc;GACZ,MAAM,eAAe,iBAAiB;GACtC,YAAY;GACb;EACD,WAAW;GAAE,MAAM,eAAe,UAAU;GAAE,YAAY;GAAO;EACjE,WAAW;GAAE,MAAM,eAAe,UAAU;GAAE,YAAY;GAAM;EAChE,aAAa;GAAE,MAAM,eAAe,UAAU;GAAE,YAAY;GAAM;EACnE;CACF,CAAC;;;;AAKF,MAAa,0BAA0B,kBAAkB;CACvD,MAAM;CACN,aAAa;CACb,QAAQ;EACN,aAAa;GAAE,MAAM,eAAe,gBAAgB;GAAE,YAAY;GAAO;EACzE,aAAa;GAAE,MAAM,eAAe,MAAM;GAAE,YAAY;GAAM;EAC9D,aAAa;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EACzE,eAAe;GACb,MAAM,eAAe,iBAAiB;GACtC,YAAY;GACb;EACD,UAAU;GAAE,MAAM,eAAe,cAAc;GAAE,YAAY;GAAM;EACnE,OAAO;GAAE,MAAM,eAAe,UAAU;GAAE,YAAY;GAAM;EAC7D;CACF,CAAC;;;;AAKF,MAAa,uBAAuB,kBAAkB;CACpD,MAAM;CACN,aAAa;CACb,QAAQ;EACN,YAAY;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAO;EACzE,QAAQ;GAAE,MAAM,eAAe,gBAAgB;GAAE,YAAY;GAAO;EACpE,MAAM;GAAE,MAAM,eAAe,MAAM;GAAE,YAAY;GAAM;EACvD,SAAS;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EACtE;CACF,CAAC;;;;AAKF,MAAa,wBAAwB,kBAAkB;CACrD,MAAM;CACN,aAAa;CACb,QAAQ;EACN,SAAS;GAAE,MAAM,eAAe,SAAS;GAAE,YAAY;GAAO;EAC9D,UAAU;GAAE,MAAM;GAAuB,YAAY;GAAO;EAC5D,iBAAiB;GACf,MAAM,eAAe,iBAAiB;GACtC,YAAY;GACb;EACD,gBAAgB;GACd,MAAM,eAAe,iBAAiB;GACtC,YAAY;GACb;EACD,SAAS;GAAE,MAAM,eAAe,iBAAiB;GAAE,YAAY;GAAM;EACtE;CACF,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/presentations/index.ts"],"sourcesContent":["/**\n * Workflow System Presentation Descriptors\n */\nimport { definePresentation, StabilityEnum } from '@contractspec/lib.contracts';\nimport { WorkflowDefinitionModel } from '../workflow/workflow.schema';\nimport { WorkflowInstanceModel } from '../instance/instance.schema';\nimport { ApprovalRequestModel } from '../approval/approval.schema';\n\n// ============ Workflow Definition Presentations ============\n\n/**\n * Workflow designer canvas for building workflows.\n */\nexport const WorkflowDesignerPresentation = definePresentation({\n meta: {\n key: 'workflow.designer',\n version: '1.0.0',\n title: 'Workflow Designer',\n description: 'Visual workflow designer with drag-and-drop steps',\n domain: 'workflow-system',\n owners: ['@workflow-team'],\n tags: ['workflow', 'designer', 'admin'],\n stability: StabilityEnum.Experimental,\n goal: 'Building and modifying workflow definitions',\n context: 'Workflow administration and setup',\n },\n source: {\n type: 'component',\n framework: 'react',\n componentKey: 'WorkflowDesigner',\n props: WorkflowDefinitionModel,\n },\n targets: ['react'],\n policy: {\n flags: ['workflow.designer.enabled'],\n },\n});\n\n/**\n * List of workflow definitions.\n */\nexport const WorkflowListPresentation = definePresentation({\n meta: {\n key: 'workflow.definition.viewList',\n version: '1.0.0',\n title: 'Workflow List',\n description: 'List of workflow definitions with status and actions',\n domain: 'workflow-system',\n owners: ['@workflow-team'],\n tags: ['workflow', 'list', 'admin'],\n stability: StabilityEnum.Experimental,\n goal: 'Overview of all defined workflows',\n context: 'Workflow management dashboard',\n },\n source: {\n type: 'component',\n framework: 'react',\n componentKey: 'WorkflowDefinitionList',\n props: WorkflowDefinitionModel,\n },\n targets: ['react', 'markdown'],\n policy: {\n flags: ['workflow.enabled'],\n },\n});\n\n/**\n * Workflow definition detail view.\n */\nexport const WorkflowDetailPresentation = definePresentation({\n meta: {\n key: 'workflow.definition.detail',\n version: '1.0.0',\n title: 'Workflow Details',\n description: 'Detailed view of a workflow definition with steps',\n domain: 'workflow-system',\n owners: ['@workflow-team'],\n tags: ['workflow', 'detail'],\n stability: StabilityEnum.Experimental,\n goal: 'Viewing technical details of a workflow definition',\n context: 'Workflow inspection and debugging',\n },\n source: {\n type: 'component',\n framework: 'react',\n componentKey: 'WorkflowDefinitionDetail',\n props: WorkflowDefinitionModel,\n },\n targets: ['react', 'markdown'],\n policy: {\n flags: ['workflow.enabled'],\n },\n});\n\n// ============ Workflow Instance Presentations ============\n\n/**\n * List of running workflow instances.\n */\nexport const InstanceListPresentation = definePresentation({\n meta: {\n key: 'workflow.instance.viewList',\n version: '1.0.0',\n title: 'Instance List',\n description: 'List of workflow instances with status and progress',\n domain: 'workflow-system',\n owners: ['@workflow-team'],\n tags: ['workflow', 'instance', 'list'],\n stability: StabilityEnum.Experimental,\n goal: 'Monitoring active and past workflow executions',\n context: 'Operations monitoring',\n },\n source: {\n type: 'component',\n framework: 'react',\n componentKey: 'WorkflowInstanceList',\n props: WorkflowInstanceModel,\n },\n targets: ['react', 'markdown'],\n policy: {\n flags: ['workflow.enabled'],\n },\n});\n\n/**\n * Workflow instance detail view with timeline.\n */\nexport const InstanceDetailPresentation = definePresentation({\n meta: {\n key: 'workflow.instance.detail',\n version: '1.0.0',\n title: 'Instance Details',\n description: 'Detailed view of a workflow instance with step timeline',\n domain: 'workflow-system',\n owners: ['@workflow-team'],\n tags: ['workflow', 'instance', 'detail', 'timeline'],\n stability: StabilityEnum.Experimental,\n goal: 'Detailed inspection of a specific workflow instance',\n context: 'Case management and troubleshooting',\n },\n source: {\n type: 'component',\n framework: 'react',\n componentKey: 'WorkflowInstanceDetail',\n props: WorkflowInstanceModel,\n },\n targets: ['react', 'markdown'],\n policy: {\n flags: ['workflow.enabled'],\n },\n});\n\n/**\n * Workflow progress tracker widget.\n */\nexport const ProgressTrackerPresentation = definePresentation({\n meta: {\n key: 'workflow.instance.progress',\n version: '1.0.0',\n title: 'Progress Tracker',\n description: 'Visual progress tracker showing current step in workflow',\n domain: 'workflow-system',\n owners: ['@workflow-team'],\n tags: ['workflow', 'progress', 'widget'],\n stability: StabilityEnum.Experimental,\n goal: 'Quick view of current progress for a workflow',\n context: 'Embedded progress indicator in entity views',\n },\n source: {\n type: 'component',\n framework: 'react',\n componentKey: 'WorkflowProgressTracker',\n props: WorkflowInstanceModel,\n },\n targets: ['react'],\n policy: {\n flags: ['workflow.enabled'],\n },\n});\n\n// ============ Approval Presentations ============\n\n/**\n * Approval inbox - list of pending approvals.\n */\nexport const ApprovalInboxPresentation = definePresentation({\n meta: {\n key: 'workflow.approval.inbox',\n version: '1.0.0',\n title: 'Approval Inbox',\n description: 'Inbox showing pending approval requests for current user',\n domain: 'workflow-system',\n owners: ['@workflow-team'],\n tags: ['workflow', 'approval', 'inbox'],\n stability: StabilityEnum.Experimental,\n goal: 'Managing personal workload of approval requests',\n context: 'Personal task management',\n },\n source: {\n type: 'component',\n framework: 'react',\n componentKey: 'ApprovalInbox',\n props: ApprovalRequestModel,\n },\n targets: ['react', 'markdown'],\n policy: {\n flags: ['workflow.approvals.enabled'],\n },\n});\n\n/**\n * Approval request detail view.\n */\nexport const ApprovalDetailPresentation = definePresentation({\n meta: {\n key: 'workflow.approval.detail',\n version: '1.0.0',\n title: 'Approval Details',\n description: 'Detailed approval request view with context and actions',\n domain: 'workflow-system',\n owners: ['@workflow-team'],\n tags: ['workflow', 'approval', 'detail'],\n stability: StabilityEnum.Experimental,\n goal: 'Decision support for an approval request',\n context: 'Specific approval action',\n },\n source: {\n type: 'component',\n framework: 'react',\n componentKey: 'ApprovalRequestDetail',\n props: ApprovalRequestModel,\n },\n targets: ['react', 'markdown'],\n policy: {\n flags: ['workflow.approvals.enabled'],\n },\n});\n\n/**\n * Approval decision form.\n */\nexport const ApprovalFormPresentation = definePresentation({\n meta: {\n key: 'workflow.approval.form',\n version: '1.0.0',\n title: 'Approval Form',\n description: 'Form for submitting approval decisions',\n domain: 'workflow-system',\n owners: ['@workflow-team'],\n tags: ['workflow', 'approval', 'form'],\n stability: StabilityEnum.Experimental,\n goal: 'Submitting a decision on an approval request',\n context: 'Approval decision dialog',\n },\n source: {\n type: 'component',\n framework: 'react',\n componentKey: 'ApprovalDecisionForm',\n },\n targets: ['react'],\n policy: {\n flags: ['workflow.approvals.enabled'],\n },\n});\n\n// ============ Dashboard Widgets ============\n\n/**\n * Pending approvals count badge.\n */\nexport const PendingApprovalsBadgePresentation = definePresentation({\n meta: {\n key: 'workflow.approval.badge',\n version: '1.0.0',\n title: 'Pending Approvals Badge',\n description: 'Badge showing count of pending approvals',\n domain: 'workflow-system',\n owners: ['@workflow-team'],\n tags: ['workflow', 'approval', 'badge', 'widget'],\n stability: StabilityEnum.Experimental,\n goal: 'Visual notification of pending approvals',\n context: 'Global navigation or sidebar',\n },\n source: {\n type: 'component',\n framework: 'react',\n componentKey: 'PendingApprovalsBadge',\n },\n targets: ['react'],\n policy: {\n flags: ['workflow.approvals.enabled'],\n },\n});\n\n/**\n * Workflow metrics dashboard widget.\n */\nexport const WorkflowMetricsPresentation = definePresentation({\n meta: {\n key: 'workflow.metrics',\n version: '1.0.0',\n title: 'Workflow Metrics',\n description: 'Dashboard widget showing workflow metrics and statistics',\n domain: 'workflow-system',\n owners: ['@workflow-team'],\n tags: ['workflow', 'metrics', 'dashboard'],\n stability: StabilityEnum.Experimental,\n goal: 'Monitoring throughput and bottlenecks',\n context: 'System performance dashboard',\n },\n source: {\n type: 'component',\n framework: 'react',\n componentKey: 'WorkflowMetricsDashboard',\n },\n targets: ['react', 'markdown'],\n policy: {\n flags: ['workflow.metrics.enabled'],\n },\n});\n\n// ============ All Presentations ============\n\nexport const WorkflowSystemPresentations = {\n // Definition\n WorkflowDesignerPresentation,\n WorkflowListPresentation,\n WorkflowDetailPresentation,\n\n // Instance\n InstanceListPresentation,\n InstanceDetailPresentation,\n ProgressTrackerPresentation,\n\n // Approval\n ApprovalInboxPresentation,\n ApprovalDetailPresentation,\n ApprovalFormPresentation,\n PendingApprovalsBadgePresentation,\n\n // Dashboard\n WorkflowMetricsPresentation,\n};\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/seeders/index.ts"],"sourcesContent":["import type { DatabasePort } from '@contractspec/lib.runtime-sandbox';\n\nexport async function seedWorkflowSystem(params: {\n projectId: string;\n db: DatabasePort;\n}) {\n const { projectId, db } = params;\n\n const existing = await db.query(\n `SELECT COUNT(*) as count FROM workflow_definition WHERE \"projectId\" = $1`,\n [projectId]\n );\n if ((existing.rows[0]?.count as number) > 0) return;\n\n await db.execute(\n `INSERT INTO workflow_definition (id, \"projectId\", \"organizationId\", name, description, type, status)\n VALUES ($1, $2, $3, $4, $5, $6, $7)`,\n [\n 'wf_1',\n projectId,\n 'org_demo',\n 'Approval Workflow',\n 'Demo approval workflow',\n 'APPROVAL',\n 'ACTIVE',\n ]\n );\n}\n"],"mappings":";AAEA,eAAsB,mBAAmB,QAGtC;CACD,MAAM,EAAE,WAAW,OAAO;AAM1B,MAJiB,MAAM,GAAG,MACxB,4EACA,CAAC,UAAU,CACZ,EACa,KAAK,IAAI,QAAmB,EAAG;AAE7C,OAAM,GAAG,QACP;2CAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"mock-data.js","names":[],"sources":["../../src/shared/mock-data.ts"],"sourcesContent":["/**\n * Mock data store for workflow system.\n * In production, this would be backed by a database.\n */\n\nimport type {\n WorkflowDefinitionRecord,\n WorkflowStepRecord,\n WorkflowInstanceRecord,\n ApprovalRequestRecord,\n} from './types';\n\nexport const mockDataStore = {\n workflows: new Map<string, WorkflowDefinitionRecord>(),\n steps: new Map<string, WorkflowStepRecord>(),\n instances: new Map<string, WorkflowInstanceRecord>(),\n approvals: new Map<string, ApprovalRequestRecord>(),\n stepExecutions: new Map<\n string,\n { id: string; instanceId: string; stepId: string; status: string }\n >(),\n};\n"],"mappings":";AAYA,MAAa,gBAAgB;CAC3B,2BAAW,IAAI,KAAuC;CACtD,uBAAO,IAAI,KAAiC;CAC5C,2BAAW,IAAI,KAAqC;CACpD,2BAAW,IAAI,KAAoC;CACnD,gCAAgB,IAAI,KAGjB;CACJ"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/state-machine/index.ts"],"sourcesContent":["/**\n * Workflow State Machine Engine\n *\n * Provides state machine logic for workflow transitions.\n * This is a spec-level abstraction that defines the interface\n * for workflow state transitions.\n */\n\n// ============ Types ============\n\n/**\n * Represents a transition definition in a workflow step.\n */\nexport interface TransitionDefinition {\n /** The action that triggers this transition (e.g., \"approve\", \"reject\") */\n action: string;\n /** The target step key to transition to */\n targetStepKey: string;\n /** Optional condition expression for conditional transitions */\n condition?: string;\n /** Optional guard roles - only users with these roles can take this action */\n allowedRoles?: string[];\n}\n\n/**\n * Step definition for state machine.\n */\nexport interface StateMachineStep {\n key: string;\n name: string;\n type:\n | 'START'\n | 'APPROVAL'\n | 'TASK'\n | 'CONDITION'\n | 'PARALLEL'\n | 'WAIT'\n | 'ACTION'\n | 'END';\n /** Map of action -> transition definition */\n transitions: Record<string, string | TransitionDefinition>;\n /** For approval steps: how approvals are handled */\n approvalMode?: 'ANY' | 'ALL' | 'MAJORITY' | 'SEQUENTIAL';\n /** Roles that can approve/act on this step */\n allowedRoles?: string[];\n /** Timeout in seconds */\n timeoutSeconds?: number;\n /** Condition expression for CONDITION type */\n conditionExpression?: string;\n}\n\n/**\n * Workflow state machine definition.\n */\nexport interface StateMachineDefinition {\n key: string;\n name: string;\n version: string;\n initialStepKey: string;\n steps: Record<string, StateMachineStep>;\n}\n\n/**\n * Current state of an instance.\n */\nexport interface StateMachineState {\n currentStepKey: string;\n status:\n | 'PENDING'\n | 'RUNNING'\n | 'WAITING'\n | 'PAUSED'\n | 'COMPLETED'\n | 'CANCELLED'\n | 'FAILED'\n | 'TIMEOUT';\n contextData: Record<string, unknown>;\n history: {\n stepKey: string;\n action: string;\n timestamp: Date;\n executedBy: string;\n }[];\n}\n\n/**\n * Result of a transition attempt.\n */\nexport interface TransitionResult {\n success: boolean;\n previousStepKey: string;\n currentStepKey: string | null;\n status: StateMachineState['status'];\n error?: string;\n}\n\n/**\n * Context for transition validation.\n */\nexport interface TransitionContext {\n userId: string;\n userRoles: string[];\n data?: Record<string, unknown>;\n}\n\n// ============ State Machine Engine ============\n\n/**\n * State machine engine interface.\n * Implementation should be provided at runtime.\n */\nexport interface IStateMachineEngine {\n /**\n * Validate that a transition is allowed.\n */\n canTransition(\n definition: StateMachineDefinition,\n state: StateMachineState,\n action: string,\n context: TransitionContext\n ): { allowed: boolean; reason?: string };\n\n /**\n * Get available actions for the current step.\n */\n getAvailableActions(\n definition: StateMachineDefinition,\n state: StateMachineState,\n context: TransitionContext\n ): string[];\n\n /**\n * Execute a transition.\n */\n transition(\n definition: StateMachineDefinition,\n state: StateMachineState,\n action: string,\n context: TransitionContext\n ): TransitionResult;\n\n /**\n * Evaluate a condition expression.\n */\n evaluateCondition(\n expression: string,\n contextData: Record<string, unknown>\n ): boolean;\n}\n\n/**\n * Basic state machine engine implementation.\n * This is a reference implementation for spec validation.\n */\nexport class BasicStateMachineEngine implements IStateMachineEngine {\n canTransition(\n definition: StateMachineDefinition,\n state: StateMachineState,\n action: string,\n context: TransitionContext\n ): { allowed: boolean; reason?: string } {\n // Check if state allows transitions\n if (state.status !== 'RUNNING' && state.status !== 'WAITING') {\n return {\n allowed: false,\n reason: `Workflow is ${state.status}, cannot transition`,\n };\n }\n\n const currentStep = definition.steps[state.currentStepKey];\n if (!currentStep) {\n return {\n allowed: false,\n reason: `Step ${state.currentStepKey} not found`,\n };\n }\n\n // Check if action exists for this step\n const transition = currentStep.transitions[action];\n if (!transition) {\n return {\n allowed: false,\n reason: `Action ${action} not available in step ${state.currentStepKey}`,\n };\n }\n\n // Check role-based access\n if (currentStep.allowedRoles && currentStep.allowedRoles.length > 0) {\n const hasRole = currentStep.allowedRoles.some((role) =>\n context.userRoles.includes(role)\n );\n if (!hasRole) {\n return {\n allowed: false,\n reason: `User lacks required role for this action`,\n };\n }\n }\n\n // Check transition-specific roles if defined\n if (\n typeof transition === 'object' &&\n transition.allowedRoles &&\n transition.allowedRoles.length > 0\n ) {\n const hasRole = transition.allowedRoles.some((role) =>\n context.userRoles.includes(role)\n );\n if (!hasRole) {\n return {\n allowed: false,\n reason: `User lacks required role for action ${action}`,\n };\n }\n }\n\n return { allowed: true };\n }\n\n getAvailableActions(\n definition: StateMachineDefinition,\n state: StateMachineState,\n context: TransitionContext\n ): string[] {\n if (state.status !== 'RUNNING' && state.status !== 'WAITING') {\n return [];\n }\n\n const currentStep = definition.steps[state.currentStepKey];\n if (!currentStep) {\n return [];\n }\n\n return Object.keys(currentStep.transitions).filter((action) => {\n const result = this.canTransition(definition, state, action, context);\n return result.allowed;\n });\n }\n\n transition(\n definition: StateMachineDefinition,\n state: StateMachineState,\n action: string,\n context: TransitionContext\n ): TransitionResult {\n const validation = this.canTransition(definition, state, action, context);\n if (!validation.allowed) {\n return {\n success: false,\n previousStepKey: state.currentStepKey,\n currentStepKey: state.currentStepKey,\n status: state.status,\n error: validation.reason,\n };\n }\n\n const currentStep = definition.steps[state.currentStepKey];\n if (!currentStep) {\n return {\n success: false,\n previousStepKey: state.currentStepKey,\n currentStepKey: state.currentStepKey,\n status: state.status,\n error: `Current step ${state.currentStepKey} not found`,\n };\n }\n const transition = currentStep.transitions[action];\n if (!transition) {\n return {\n success: false,\n previousStepKey: state.currentStepKey,\n currentStepKey: state.currentStepKey,\n status: state.status,\n error: `Transition for action ${action} not found`,\n };\n }\n const targetStepKey =\n typeof transition === 'string' ? transition : transition.targetStepKey;\n const targetStep = definition.steps[targetStepKey];\n\n if (!targetStep) {\n return {\n success: false,\n previousStepKey: state.currentStepKey,\n currentStepKey: state.currentStepKey,\n status: state.status,\n error: `Target step ${targetStepKey} not found`,\n };\n }\n\n // Determine new status\n let newStatus: StateMachineState['status'] = 'RUNNING';\n if (targetStep.type === 'END') {\n newStatus = 'COMPLETED';\n } else if (targetStep.type === 'APPROVAL' || targetStep.type === 'WAIT') {\n newStatus = 'WAITING';\n }\n\n return {\n success: true,\n previousStepKey: state.currentStepKey,\n currentStepKey: targetStepKey,\n status: newStatus,\n };\n }\n\n evaluateCondition(\n expression: string,\n contextData: Record<string, unknown>\n ): boolean {\n // Basic condition evaluation\n // In production, this should use a proper expression language\n try {\n // Simple property checks like \"amount > 1000\"\n const match = expression.match(\n /^(\\w+)\\s*(>=|<=|>|<|===|!==|==|!=)\\s*(.+)$/\n );\n if (match) {\n const [, prop, operator, value] = match;\n if (!prop || !operator || value === undefined) {\n return false;\n }\n const propValue = contextData[prop];\n const compareValue = JSON.parse(value);\n\n switch (operator) {\n case '>':\n return Number(propValue) > Number(compareValue);\n case '<':\n return Number(propValue) < Number(compareValue);\n case '>=':\n return Number(propValue) >= Number(compareValue);\n case '<=':\n return Number(propValue) <= Number(compareValue);\n case '===':\n case '==':\n return propValue === compareValue;\n case '!==':\n case '!=':\n return propValue !== compareValue;\n }\n }\n\n // Check for boolean property\n if (expression in contextData) {\n return Boolean(contextData[expression]);\n }\n\n return false;\n } catch {\n return false;\n }\n }\n}\n\n/**\n * Create a new state machine engine instance.\n */\nexport function createStateMachineEngine(): IStateMachineEngine {\n return new BasicStateMachineEngine();\n}\n\n// ============ Utility Functions ============\n\n/**\n * Build a state machine definition from workflow entities.\n */\nexport function buildStateMachineDefinition(\n workflow: {\n key: string;\n name: string;\n version: string;\n initialStepId: string | null;\n },\n steps: {\n key: string;\n name: string;\n type: string;\n transitions: Record<string, string | TransitionDefinition>;\n approvalMode?: string;\n approverRoles?: string[];\n timeoutSeconds?: number;\n conditionExpression?: string;\n }[]\n): StateMachineDefinition {\n const stepMap: Record<string, StateMachineStep> = {};\n\n for (const step of steps) {\n stepMap[step.key] = {\n key: step.key,\n name: step.name,\n type: step.type as StateMachineStep['type'],\n transitions: step.transitions,\n approvalMode: step.approvalMode as StateMachineStep['approvalMode'],\n allowedRoles: step.approverRoles,\n timeoutSeconds: step.timeoutSeconds,\n conditionExpression: step.conditionExpression,\n };\n }\n\n // Find initial step\n const startStep = steps.find((s) => s.type === 'START');\n const initialStepKey = startStep?.key ?? steps[0]?.key ?? '';\n\n return {\n key: workflow.key,\n name: workflow.name,\n version: workflow.version,\n initialStepKey,\n steps: stepMap,\n };\n}\n\n/**\n * Create initial state for a new workflow instance.\n */\nexport function createInitialState(\n definition: StateMachineDefinition,\n contextData: Record<string, unknown> = {}\n): StateMachineState {\n return {\n currentStepKey: definition.initialStepKey,\n status: 'RUNNING',\n contextData,\n history: [],\n };\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"operations.test-spec.js","names":[],"sources":["../../src/tests/operations.test-spec.ts"],"sourcesContent":["import { defineTestSpec } from '@contractspec/lib.contracts';\n\nexport const DefinitionListTest = defineTestSpec({\n meta: {\n key: 'workflow.definition.list.test',\n version: '1.0.0',\n stability: 'experimental',\n owners: ['@example.workflow-system'],\n description: 'Test for listing workflow definitions',\n tags: ['test'],\n },\n target: {\n type: 'operation',\n operation: { key: 'workflow.definition.list', version: '1.0.0' },\n },\n scenarios: [\n {\n key: 'success',\n when: { operation: { key: 'workflow.definition.list' } },\n then: [{ type: 'expectOutput', match: {} }],\n },\n {\n key: 'error',\n when: { operation: { key: 'workflow.definition.list' } },\n then: [{ type: 'expectError' }],\n },\n ],\n});\n\nexport const InstanceListTest = defineTestSpec({\n meta: {\n key: 'workflow.instance.list.test',\n version: '1.0.0',\n stability: 'experimental',\n owners: ['@example.workflow-system'],\n description: 'Test for listing workflow instances',\n tags: ['test'],\n },\n target: {\n type: 'operation',\n operation: { key: 'workflow.instance.list', version: '1.0.0' },\n },\n scenarios: [\n {\n key: 'success',\n when: { operation: { key: 'workflow.instance.list' } },\n then: [{ type: 'expectOutput', match: {} }],\n },\n {\n key: 'error',\n when: { operation: { key: 'workflow.instance.list' } },\n then: [{ type: 'expectError' }],\n },\n ],\n});\n\nexport const ApprovalListMineTest = defineTestSpec({\n meta: {\n key: 'workflow.approval.list.mine.test',\n version: '1.0.0',\n stability: 'experimental',\n owners: ['@example.workflow-system'],\n description: 'Test for listing my approvals',\n tags: ['test'],\n },\n target: {\n type: 'operation',\n operation: { key: 'workflow.approval.list.mine', version: '1.0.0' },\n },\n scenarios: [\n {\n key: 'success',\n when: { operation: { key: 'workflow.approval.list.mine' } },\n then: [{ type: 'expectOutput', match: {} }],\n },\n {\n key: 'error',\n when: { operation: { key: 'workflow.approval.list.mine' } },\n then: [{ type: 'expectError' }],\n },\n ],\n});\n\nexport const ApprovalDecideTest = defineTestSpec({\n meta: {\n key: 'workflow.approval.decide.test',\n version: '1.0.0',\n stability: 'experimental',\n owners: ['@example.workflow-system'],\n description: 'Test for deciding on approval',\n tags: ['test'],\n },\n target: {\n type: 'operation',\n operation: { key: 'workflow.approval.decide', version: '1.0.0' },\n },\n scenarios: [\n {\n key: 'success',\n when: { operation: { key: 'workflow.approval.decide' } },\n then: [{ type: 'expectOutput', match: {} }],\n },\n {\n key: 'error',\n when: { operation: { key: 'workflow.approval.decide' } },\n then: [{ type: 'expectError' }],\n },\n ],\n});\n"],"mappings":";;;AAEA,MAAa,qBAAqB,eAAe;CAC/C,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,2BAA2B;EACpC,aAAa;EACb,MAAM,CAAC,OAAO;EACf;CACD,QAAQ;EACN,MAAM;EACN,WAAW;GAAE,KAAK;GAA4B,SAAS;GAAS;EACjE;CACD,WAAW,CACT;EACE,KAAK;EACL,MAAM,EAAE,WAAW,EAAE,KAAK,4BAA4B,EAAE;EACxD,MAAM,CAAC;GAAE,MAAM;GAAgB,OAAO,EAAE;GAAE,CAAC;EAC5C,EACD;EACE,KAAK;EACL,MAAM,EAAE,WAAW,EAAE,KAAK,4BAA4B,EAAE;EACxD,MAAM,CAAC,EAAE,MAAM,eAAe,CAAC;EAChC,CACF;CACF,CAAC;AAEF,MAAa,mBAAmB,eAAe;CAC7C,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,2BAA2B;EACpC,aAAa;EACb,MAAM,CAAC,OAAO;EACf;CACD,QAAQ;EACN,MAAM;EACN,WAAW;GAAE,KAAK;GAA0B,SAAS;GAAS;EAC/D;CACD,WAAW,CACT;EACE,KAAK;EACL,MAAM,EAAE,WAAW,EAAE,KAAK,0BAA0B,EAAE;EACtD,MAAM,CAAC;GAAE,MAAM;GAAgB,OAAO,EAAE;GAAE,CAAC;EAC5C,EACD;EACE,KAAK;EACL,MAAM,EAAE,WAAW,EAAE,KAAK,0BAA0B,EAAE;EACtD,MAAM,CAAC,EAAE,MAAM,eAAe,CAAC;EAChC,CACF;CACF,CAAC;AAEF,MAAa,uBAAuB,eAAe;CACjD,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,2BAA2B;EACpC,aAAa;EACb,MAAM,CAAC,OAAO;EACf;CACD,QAAQ;EACN,MAAM;EACN,WAAW;GAAE,KAAK;GAA+B,SAAS;GAAS;EACpE;CACD,WAAW,CACT;EACE,KAAK;EACL,MAAM,EAAE,WAAW,EAAE,KAAK,+BAA+B,EAAE;EAC3D,MAAM,CAAC;GAAE,MAAM;GAAgB,OAAO,EAAE;GAAE,CAAC;EAC5C,EACD;EACE,KAAK;EACL,MAAM,EAAE,WAAW,EAAE,KAAK,+BAA+B,EAAE;EAC3D,MAAM,CAAC,EAAE,MAAM,eAAe,CAAC;EAChC,CACF;CACF,CAAC;AAEF,MAAa,qBAAqB,eAAe;CAC/C,MAAM;EACJ,KAAK;EACL,SAAS;EACT,WAAW;EACX,QAAQ,CAAC,2BAA2B;EACpC,aAAa;EACb,MAAM,CAAC,OAAO;EACf;CACD,QAAQ;EACN,MAAM;EACN,WAAW;GAAE,KAAK;GAA4B,SAAS;GAAS;EACjE;CACD,WAAW,CACT;EACE,KAAK;EACL,MAAM,EAAE,WAAW,EAAE,KAAK,4BAA4B,EAAE;EACxD,MAAM,CAAC;GAAE,MAAM;GAAgB,OAAO,EAAE;GAAE,CAAC;EAC5C,EACD;EACE,KAAK;EACL,MAAM,EAAE,WAAW,EAAE,KAAK,4BAA4B,EAAE;EACxD,MAAM,CAAC,EAAE,MAAM,eAAe,CAAC;EAChC,CACF;CACF,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"WorkflowDashboard.js","names":[],"sources":["../../src/ui/WorkflowDashboard.tsx"],"sourcesContent":["'use client';\n\n/**\n * Workflow Dashboard\n *\n * Interactive dashboard for the workflow-system template.\n * Displays workflow definitions and instances with stats.\n */\nimport { useState } from 'react';\nimport {\n Button,\n ErrorState,\n LoaderBlock,\n StatCard,\n StatCardGroup,\n} from '@contractspec/lib.design-system';\nimport { useWorkflowList } from './hooks/useWorkflowList';\n\ntype Tab = 'definitions' | 'instances';\n\nconst STATUS_COLORS: Record<string, string> = {\n ACTIVE:\n 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',\n DRAFT: 'bg-gray-100 text-gray-700 dark:bg-gray-900/30 dark:text-gray-400',\n ARCHIVED:\n 'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400',\n PENDING: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400',\n IN_PROGRESS:\n 'bg-indigo-100 text-indigo-700 dark:bg-indigo-900/30 dark:text-indigo-400',\n COMPLETED:\n 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400',\n REJECTED: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400',\n CANCELLED: 'bg-gray-100 text-gray-700 dark:bg-gray-900/30 dark:text-gray-400',\n};\n\nexport function WorkflowDashboard() {\n const [activeTab, setActiveTab] = useState<Tab>('definitions');\n const { definitions, instances, loading, error, stats, refetch } =\n useWorkflowList();\n\n const tabs: { id: Tab; label: string; icon: string }[] = [\n { id: 'definitions', label: 'Definitions', icon: '📋' },\n { id: 'instances', label: 'Instances', icon: '🔄' },\n ];\n\n if (loading) {\n return <LoaderBlock label=\"Loading Workflows...\" />;\n }\n\n if (error) {\n return (\n <ErrorState\n title=\"Failed to load Workflows\"\n description={error.message}\n onRetry={refetch}\n retryLabel=\"Retry\"\n />\n );\n }\n\n return (\n <div className=\"space-y-6\">\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-2xl font-bold\">Workflow System</h2>\n <Button onClick={() => alert('Create workflow modal')}>\n <span className=\"mr-2\">+</span> New Workflow\n </Button>\n </div>\n\n {/* Stats Row */}\n <StatCardGroup>\n <StatCard\n label=\"Workflows\"\n value={stats.totalDefinitions}\n hint={`${stats.activeDefinitions} active`}\n />\n <StatCard\n label=\"Instances\"\n value={stats.totalInstances}\n hint=\"total runs\"\n />\n <StatCard\n label=\"Pending\"\n value={stats.pendingInstances}\n hint=\"awaiting action\"\n />\n <StatCard\n label=\"Completed\"\n value={stats.completedInstances}\n hint=\"finished\"\n />\n </StatCardGroup>\n\n {/* Navigation Tabs */}\n <nav className=\"bg-muted flex gap-1 rounded-lg p-1\" role=\"tablist\">\n {tabs.map((tab) => (\n <Button\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={activeTab === tab.id}\n onClick={() => setActiveTab(tab.id)}\n className={`flex flex-1 items-center justify-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-colors ${\n activeTab === tab.id\n ? 'bg-background text-foreground shadow-sm'\n : 'text-muted-foreground hover:text-foreground'\n }`}\n >\n <span>{tab.icon}</span>\n {tab.label}\n </Button>\n ))}\n </nav>\n\n {/* Tab Content */}\n <div className=\"min-h-[400px]\" role=\"tabpanel\">\n {activeTab === 'definitions' && (\n <div className=\"border-border rounded-lg border\">\n <table className=\"w-full\">\n <thead className=\"border-border bg-muted/30 border-b\">\n <tr>\n <th className=\"px-4 py-3 text-left text-sm font-medium\">\n Name\n </th>\n <th className=\"px-4 py-3 text-left text-sm font-medium\">\n Type\n </th>\n <th className=\"px-4 py-3 text-left text-sm font-medium\">\n Status\n </th>\n <th className=\"px-4 py-3 text-left text-sm font-medium\">\n Created\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-border divide-y\">\n {definitions.map((def) => (\n <tr key={def.id} className=\"hover:bg-muted/50\">\n <td className=\"px-4 py-3\">\n <div className=\"font-medium\">{def.name}</div>\n <div className=\"text-muted-foreground text-sm\">\n {def.description}\n </div>\n </td>\n <td className=\"px-4 py-3 font-mono text-sm\">{def.type}</td>\n <td className=\"px-4 py-3\">\n <span\n className={`inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${STATUS_COLORS[def.status] ?? ''}`}\n >\n {def.status}\n </span>\n </td>\n <td className=\"text-muted-foreground px-4 py-3 text-sm\">\n {def.createdAt.toLocaleDateString()}\n </td>\n </tr>\n ))}\n {definitions.length === 0 && (\n <tr>\n <td\n colSpan={4}\n className=\"text-muted-foreground px-4 py-8 text-center\"\n >\n No workflow definitions found\n </td>\n </tr>\n )}\n </tbody>\n </table>\n </div>\n )}\n\n {activeTab === 'instances' && (\n <div className=\"border-border rounded-lg border\">\n <table className=\"w-full\">\n <thead className=\"border-border bg-muted/30 border-b\">\n <tr>\n <th className=\"px-4 py-3 text-left text-sm font-medium\">\n Instance ID\n </th>\n <th className=\"px-4 py-3 text-left text-sm font-medium\">\n Status\n </th>\n <th className=\"px-4 py-3 text-left text-sm font-medium\">\n Requested By\n </th>\n <th className=\"px-4 py-3 text-left text-sm font-medium\">\n Started\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-border divide-y\">\n {instances.map((inst) => (\n <tr key={inst.id} className=\"hover:bg-muted/50\">\n <td className=\"px-4 py-3 font-mono text-sm\">{inst.id}</td>\n <td className=\"px-4 py-3\">\n <span\n className={`inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${STATUS_COLORS[inst.status] ?? ''}`}\n >\n {inst.status}\n </span>\n </td>\n <td className=\"px-4 py-3 text-sm\">{inst.requestedBy}</td>\n <td className=\"text-muted-foreground px-4 py-3 text-sm\">\n {inst.startedAt.toLocaleDateString()}\n </td>\n </tr>\n ))}\n {instances.length === 0 && (\n <tr>\n <td\n colSpan={4}\n className=\"text-muted-foreground px-4 py-8 text-center\"\n >\n No workflow instances found\n </td>\n </tr>\n )}\n </tbody>\n </table>\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"useWorkflowList.js","names":[],"sources":["../../../src/ui/hooks/useWorkflowList.ts"],"sourcesContent":["'use client';\n\nimport { useCallback, useEffect, useState } from 'react';\nimport type {\n WorkflowDefinition,\n WorkflowInstance,\n WorkflowHandlers,\n} from '../../handlers/workflow.handlers';\nimport { useTemplateRuntime } from '@contractspec/lib.example-shared-ui';\n\nexport interface WorkflowStats {\n totalDefinitions: number;\n activeDefinitions: number;\n totalInstances: number;\n pendingInstances: number;\n completedInstances: number;\n rejectedInstances: number;\n}\n\nexport function useWorkflowList(projectId = 'local-project') {\n const { handlers } = useTemplateRuntime<{ workflow: WorkflowHandlers }>();\n const workflow = handlers.workflow;\n const [definitions, setDefinitions] = useState<WorkflowDefinition[]>([]);\n const [instances, setInstances] = useState<WorkflowInstance[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const fetchData = useCallback(async () => {\n try {\n setLoading(true);\n setError(null);\n\n const [defResult, instResult] = await Promise.all([\n workflow.listDefinitions({ projectId, limit: 100 }),\n workflow.listInstances({ projectId, limit: 100 }),\n ]);\n\n setDefinitions(defResult.definitions);\n setInstances(instResult.instances);\n } catch (err) {\n setError(\n err instanceof Error ? err : new Error('Failed to load workflows')\n );\n } finally {\n setLoading(false);\n }\n }, [handlers, projectId]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n const stats: WorkflowStats = {\n totalDefinitions: definitions.length,\n activeDefinitions: definitions.filter((d) => d.status === 'ACTIVE').length,\n totalInstances: instances.length,\n pendingInstances: instances.filter((i) => i.status === 'PENDING').length,\n completedInstances: instances.filter((i) => i.status === 'COMPLETED')\n .length,\n rejectedInstances: instances.filter((i) => i.status === 'REJECTED').length,\n };\n\n return {\n definitions,\n instances,\n loading,\n error,\n stats,\n refetch: fetchData,\n };\n}\n"],"mappings":";;;;;;AAmBA,SAAgB,gBAAgB,YAAY,iBAAiB;CAC3D,MAAM,EAAE,aAAa,oBAAoD;CACzE,MAAM,WAAW,SAAS;CAC1B,MAAM,CAAC,aAAa,kBAAkB,SAA+B,EAAE,CAAC;CACxE,MAAM,CAAC,WAAW,gBAAgB,SAA6B,EAAE,CAAC;CAClE,MAAM,CAAC,SAAS,cAAc,SAAS,KAAK;CAC5C,MAAM,CAAC,OAAO,YAAY,SAAuB,KAAK;CAEtD,MAAM,YAAY,YAAY,YAAY;AACxC,MAAI;AACF,cAAW,KAAK;AAChB,YAAS,KAAK;GAEd,MAAM,CAAC,WAAW,cAAc,MAAM,QAAQ,IAAI,CAChD,SAAS,gBAAgB;IAAE;IAAW,OAAO;IAAK,CAAC,EACnD,SAAS,cAAc;IAAE;IAAW,OAAO;IAAK,CAAC,CAClD,CAAC;AAEF,kBAAe,UAAU,YAAY;AACrC,gBAAa,WAAW,UAAU;WAC3B,KAAK;AACZ,YACE,eAAe,QAAQ,sBAAM,IAAI,MAAM,2BAA2B,CACnE;YACO;AACR,cAAW,MAAM;;IAElB,CAAC,UAAU,UAAU,CAAC;AAEzB,iBAAgB;AACd,aAAW;IACV,CAAC,UAAU,CAAC;AAYf,QAAO;EACL;EACA;EACA;EACA;EACA,OAf2B;GAC3B,kBAAkB,YAAY;GAC9B,mBAAmB,YAAY,QAAQ,MAAM,EAAE,WAAW,SAAS,CAAC;GACpE,gBAAgB,UAAU;GAC1B,kBAAkB,UAAU,QAAQ,MAAM,EAAE,WAAW,UAAU,CAAC;GAClE,oBAAoB,UAAU,QAAQ,MAAM,EAAE,WAAW,YAAY,CAClE;GACH,mBAAmB,UAAU,QAAQ,MAAM,EAAE,WAAW,WAAW,CAAC;GACrE;EAQC,SAAS;EACV"}