@contractspec/example.workflow-system 3.7.6 → 3.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +72 -119
  2. package/dist/approval/approval.event.js +1 -1
  3. package/dist/approval/approval.handler.d.ts +1 -1
  4. package/dist/approval/index.d.ts +4 -4
  5. package/dist/approval/index.js +1 -1
  6. package/dist/browser/approval/approval.event.js +1 -1
  7. package/dist/browser/approval/index.js +1 -1
  8. package/dist/browser/entities/index.js +166 -166
  9. package/dist/browser/handlers/index.js +43 -43
  10. package/dist/browser/handlers/workflow.handlers.js +43 -43
  11. package/dist/browser/index.js +1935 -1548
  12. package/dist/browser/instance/index.js +210 -210
  13. package/dist/browser/instance/instance.event.js +1 -1
  14. package/dist/browser/shared/demo-scenario.js +213 -0
  15. package/dist/browser/ui/WorkflowDashboard.visualizations.js +239 -0
  16. package/dist/browser/ui/hooks/index.js +0 -47
  17. package/dist/browser/ui/hooks/useWorkflowList.js +6 -4
  18. package/dist/browser/ui/index.js +6 -4
  19. package/dist/browser/ui/renderers/index.js +409 -73
  20. package/dist/browser/ui/renderers/workflow.markdown.js +409 -73
  21. package/dist/browser/visualizations/catalog.js +132 -0
  22. package/dist/browser/visualizations/index.js +133 -0
  23. package/dist/browser/visualizations/selectors.js +195 -0
  24. package/dist/entities/index.d.ts +53 -53
  25. package/dist/entities/index.js +166 -166
  26. package/dist/example.test.d.ts +1 -0
  27. package/dist/handlers/index.js +43 -43
  28. package/dist/handlers/workflow.handlers.js +43 -43
  29. package/dist/index.d.ts +6 -5
  30. package/dist/index.js +1935 -1548
  31. package/dist/instance/index.d.ts +3 -3
  32. package/dist/instance/index.js +210 -210
  33. package/dist/instance/instance.event.js +1 -1
  34. package/dist/instance/instance.handler.d.ts +1 -1
  35. package/dist/shared/demo-scenario.d.ts +43 -0
  36. package/dist/shared/demo-scenario.js +214 -0
  37. package/dist/shared/index.d.ts +1 -1
  38. package/dist/shared/mock-data.d.ts +1 -1
  39. package/dist/ui/WorkflowDashboard.visualizations.d.ts +4 -0
  40. package/dist/ui/WorkflowDashboard.visualizations.js +240 -0
  41. package/dist/ui/hooks/index.js +0 -47
  42. package/dist/ui/hooks/useWorkflowList.d.ts +2 -1
  43. package/dist/ui/hooks/useWorkflowList.js +6 -4
  44. package/dist/ui/index.d.ts +1 -1
  45. package/dist/ui/index.js +6 -4
  46. package/dist/ui/renderers/index.js +409 -73
  47. package/dist/ui/renderers/workflow.markdown.js +409 -73
  48. package/dist/visualizations/catalog.d.ts +11 -0
  49. package/dist/visualizations/catalog.js +133 -0
  50. package/dist/visualizations/index.d.ts +2 -0
  51. package/dist/visualizations/index.js +134 -0
  52. package/dist/visualizations/selectors.d.ts +11 -0
  53. package/dist/visualizations/selectors.js +196 -0
  54. package/dist/visualizations/selectors.test.d.ts +1 -0
  55. package/dist/workflow/index.d.ts +4 -4
  56. package/dist/workflow/workflow.handler.d.ts +1 -1
  57. package/package.json +71 -10
@@ -55,9 +55,19 @@ function rowToApproval(row) {
55
55
  };
56
56
  }
57
57
  function createWorkflowHandlers(db) {
58
+ function normalizeSql(sql) {
59
+ let placeholderIndex = 0;
60
+ return sql.replace(/\?/g, () => `$${++placeholderIndex}`);
61
+ }
62
+ async function queryRows(sql, params = []) {
63
+ return (await db.query(normalizeSql(sql), params)).rows;
64
+ }
65
+ async function execute(sql, params = []) {
66
+ await db.execute(normalizeSql(sql), params);
67
+ }
58
68
  async function listDefinitions(input) {
59
69
  const { projectId, status, search, limit = 20, offset = 0 } = input;
60
- let whereClause = "WHERE projectId = ?";
70
+ let whereClause = 'WHERE "projectId" = ?';
61
71
  const params = [projectId];
62
72
  if (status && status !== "all") {
63
73
  whereClause += " AND status = ?";
@@ -67,9 +77,9 @@ function createWorkflowHandlers(db) {
67
77
  whereClause += " AND name LIKE ?";
68
78
  params.push(`%${search}%`);
69
79
  }
70
- const countResult = (await db.query(`SELECT COUNT(*) as count FROM workflow_definition ${whereClause}`, params)).rows;
80
+ const countResult = await queryRows(`SELECT COUNT(*) as count FROM workflow_definition ${whereClause}`, params);
71
81
  const total = countResult[0]?.count ?? 0;
72
- const rows = (await db.query(`SELECT * FROM workflow_definition ${whereClause} ORDER BY updatedAt DESC LIMIT ? OFFSET ?`, [...params, limit, offset])).rows;
82
+ const rows = await queryRows(`SELECT * FROM workflow_definition ${whereClause} ORDER BY "updatedAt" DESC LIMIT ? OFFSET ?`, [...params, limit, offset]);
73
83
  return {
74
84
  definitions: rows.map(rowToDefinition),
75
85
  total
@@ -78,7 +88,7 @@ function createWorkflowHandlers(db) {
78
88
  async function createDefinition(input, context) {
79
89
  const id = generateId("wfdef");
80
90
  const now = new Date().toISOString();
81
- await db.execute(`INSERT INTO workflow_definition (id, projectId, organizationId, name, description, type, status, createdAt, updatedAt)
91
+ await execute(`INSERT INTO workflow_definition (id, "projectId", "organizationId", name, description, type, status, "createdAt", "updatedAt")
82
92
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
83
93
  id,
84
94
  context.projectId,
@@ -90,15 +100,15 @@ function createWorkflowHandlers(db) {
90
100
  now,
91
101
  now
92
102
  ]);
93
- const rows = (await db.query(`SELECT * FROM workflow_definition WHERE id = ?`, [id])).rows;
103
+ const rows = await queryRows(`SELECT * FROM workflow_definition WHERE id = ?`, [id]);
94
104
  return rowToDefinition(rows[0]);
95
105
  }
96
106
  async function addStep(input) {
97
107
  const id = generateId("wfstep");
98
108
  const now = new Date().toISOString();
99
- const maxOrderResult = (await db.query(`SELECT MAX(stepOrder) as maxOrder FROM workflow_step WHERE definitionId = ?`, [input.definitionId])).rows;
109
+ const maxOrderResult = await queryRows(`SELECT MAX("stepOrder") as maxOrder FROM workflow_step WHERE "definitionId" = ?`, [input.definitionId]);
100
110
  const nextOrder = (maxOrderResult[0]?.maxOrder ?? 0) + 1;
101
- await db.execute(`INSERT INTO workflow_step (id, definitionId, name, description, stepOrder, type, requiredRoles, autoApproveCondition, timeoutHours, createdAt)
111
+ await execute(`INSERT INTO workflow_step (id, "definitionId", name, description, "stepOrder", type, "requiredRoles", "autoApproveCondition", "timeoutHours", "createdAt")
102
112
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
103
113
  id,
104
114
  input.definitionId,
@@ -111,11 +121,11 @@ function createWorkflowHandlers(db) {
111
121
  input.timeoutHours ?? null,
112
122
  now
113
123
  ]);
114
- const rows = (await db.query(`SELECT * FROM workflow_step WHERE id = ?`, [id])).rows;
124
+ const rows = await queryRows(`SELECT * FROM workflow_step WHERE id = ?`, [id]);
115
125
  return rowToStep(rows[0]);
116
126
  }
117
127
  async function getSteps(definitionId) {
118
- const rows = (await db.query(`SELECT * FROM workflow_step WHERE definitionId = ? ORDER BY stepOrder`, [definitionId])).rows;
128
+ const rows = await queryRows(`SELECT * FROM workflow_step WHERE "definitionId" = ? ORDER BY "stepOrder"`, [definitionId]);
119
129
  return rows.map(rowToStep);
120
130
  }
121
131
  async function listInstances(input) {
@@ -127,10 +137,10 @@ function createWorkflowHandlers(db) {
127
137
  limit = 20,
128
138
  offset = 0
129
139
  } = input;
130
- let whereClause = "WHERE projectId = ?";
140
+ let whereClause = 'WHERE "projectId" = ?';
131
141
  const params = [projectId];
132
142
  if (definitionId) {
133
- whereClause += " AND definitionId = ?";
143
+ whereClause += ' AND "definitionId" = ?';
134
144
  params.push(definitionId);
135
145
  }
136
146
  if (status && status !== "all") {
@@ -138,12 +148,12 @@ function createWorkflowHandlers(db) {
138
148
  params.push(status);
139
149
  }
140
150
  if (requestedBy) {
141
- whereClause += " AND requestedBy = ?";
151
+ whereClause += ' AND "requestedBy" = ?';
142
152
  params.push(requestedBy);
143
153
  }
144
- const countResult = (await db.query(`SELECT COUNT(*) as count FROM workflow_instance ${whereClause}`, params)).rows;
154
+ const countResult = await queryRows(`SELECT COUNT(*) as count FROM workflow_instance ${whereClause}`, params);
145
155
  const total = countResult[0]?.count ?? 0;
146
- const rows = (await db.query(`SELECT * FROM workflow_instance ${whereClause} ORDER BY startedAt DESC LIMIT ? OFFSET ?`, [...params, limit, offset])).rows;
156
+ const rows = await queryRows(`SELECT * FROM workflow_instance ${whereClause} ORDER BY "startedAt" DESC LIMIT ? OFFSET ?`, [...params, limit, offset]);
147
157
  return {
148
158
  instances: rows.map(rowToInstance),
149
159
  total
@@ -152,9 +162,9 @@ function createWorkflowHandlers(db) {
152
162
  async function startInstance(input, context) {
153
163
  const id = generateId("wfinst");
154
164
  const now = new Date().toISOString();
155
- const steps = (await db.query(`SELECT * FROM workflow_step WHERE definitionId = ? ORDER BY stepOrder LIMIT 1`, [input.definitionId])).rows;
165
+ const steps = await queryRows(`SELECT * FROM workflow_step WHERE "definitionId" = ? ORDER BY "stepOrder" LIMIT 1`, [input.definitionId]);
156
166
  const firstStepId = steps[0]?.id ?? null;
157
- await db.execute(`INSERT INTO workflow_instance (id, projectId, definitionId, status, currentStepId, data, requestedBy, startedAt)
167
+ await execute(`INSERT INTO workflow_instance (id, "projectId", "definitionId", status, "currentStepId", data, "requestedBy", "startedAt")
158
168
  VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, [
159
169
  id,
160
170
  context.projectId,
@@ -166,36 +176,32 @@ function createWorkflowHandlers(db) {
166
176
  now
167
177
  ]);
168
178
  if (firstStepId) {
169
- await db.execute(`INSERT INTO workflow_approval (id, instanceId, stepId, status, createdAt)
179
+ await execute(`INSERT INTO workflow_approval (id, "instanceId", "stepId", status, "createdAt")
170
180
  VALUES (?, ?, ?, ?, ?)`, [generateId("wfappr"), id, firstStepId, "PENDING", now]);
171
181
  }
172
- const rows = (await db.query(`SELECT * FROM workflow_instance WHERE id = ?`, [id])).rows;
182
+ const rows = await queryRows(`SELECT * FROM workflow_instance WHERE id = ?`, [id]);
173
183
  return rowToInstance(rows[0]);
174
184
  }
175
185
  async function approveStep(input, context) {
176
186
  const now = new Date().toISOString();
177
- const instances = (await db.query(`SELECT * FROM workflow_instance WHERE id = ?`, [
178
- input.instanceId
179
- ])).rows;
187
+ const instances = await queryRows(`SELECT * FROM workflow_instance WHERE id = ?`, [input.instanceId]);
180
188
  if (!instances[0]) {
181
189
  throw new Error("NOT_FOUND");
182
190
  }
183
191
  const instance = instances[0];
184
- await db.execute(`UPDATE workflow_approval SET status = 'APPROVED', actorId = ?, comment = ?, decidedAt = ?
185
- WHERE instanceId = ? AND stepId = ? AND status = 'PENDING'`, [
192
+ await execute(`UPDATE workflow_approval SET status = 'APPROVED', "actorId" = ?, comment = ?, "decidedAt" = ?
193
+ WHERE "instanceId" = ? AND "stepId" = ? AND status = 'PENDING'`, [
186
194
  context.actorId,
187
195
  input.comment ?? null,
188
196
  now,
189
197
  input.instanceId,
190
198
  instance.currentStepId
191
199
  ]);
192
- const currentStep = (await db.query(`SELECT * FROM workflow_step WHERE id = ?`, [
193
- instance.currentStepId
194
- ])).rows;
195
- const nextSteps = (await db.query(`SELECT * FROM workflow_step WHERE definitionId = ? AND stepOrder > ? ORDER BY stepOrder LIMIT 1`, [instance.definitionId, currentStep[0]?.stepOrder ?? 0])).rows;
200
+ const currentStep = await queryRows(`SELECT * FROM workflow_step WHERE id = ?`, [instance.currentStepId]);
201
+ const nextSteps = await queryRows(`SELECT * FROM workflow_step WHERE "definitionId" = ? AND "stepOrder" > ? ORDER BY "stepOrder" LIMIT 1`, [instance.definitionId, currentStep[0]?.stepOrder ?? 0]);
196
202
  if (nextSteps[0]) {
197
- await db.execute(`UPDATE workflow_instance SET currentStepId = ? WHERE id = ?`, [nextSteps[0].id, input.instanceId]);
198
- await db.execute(`INSERT INTO workflow_approval (id, instanceId, stepId, status, createdAt)
203
+ await execute(`UPDATE workflow_instance SET "currentStepId" = ? WHERE id = ?`, [nextSteps[0].id, input.instanceId]);
204
+ await execute(`INSERT INTO workflow_approval (id, "instanceId", "stepId", status, "createdAt")
199
205
  VALUES (?, ?, ?, ?, ?)`, [
200
206
  generateId("wfappr"),
201
207
  input.instanceId,
@@ -204,37 +210,31 @@ function createWorkflowHandlers(db) {
204
210
  now
205
211
  ]);
206
212
  } else {
207
- await db.execute(`UPDATE workflow_instance SET status = 'COMPLETED', currentStepId = NULL, completedAt = ? WHERE id = ?`, [now, input.instanceId]);
213
+ await execute(`UPDATE workflow_instance SET status = 'COMPLETED', "currentStepId" = NULL, "completedAt" = ? WHERE id = ?`, [now, input.instanceId]);
208
214
  }
209
- const updated = (await db.query(`SELECT * FROM workflow_instance WHERE id = ?`, [
210
- input.instanceId
211
- ])).rows;
215
+ const updated = await queryRows(`SELECT * FROM workflow_instance WHERE id = ?`, [input.instanceId]);
212
216
  return rowToInstance(updated[0]);
213
217
  }
214
218
  async function rejectStep(input, context) {
215
219
  const now = new Date().toISOString();
216
- const instances = (await db.query(`SELECT * FROM workflow_instance WHERE id = ?`, [
217
- input.instanceId
218
- ])).rows;
220
+ const instances = await queryRows(`SELECT * FROM workflow_instance WHERE id = ?`, [input.instanceId]);
219
221
  if (!instances[0]) {
220
222
  throw new Error("NOT_FOUND");
221
223
  }
222
- await db.execute(`UPDATE workflow_approval SET status = 'REJECTED', actorId = ?, comment = ?, decidedAt = ?
223
- WHERE instanceId = ? AND stepId = ? AND status = 'PENDING'`, [
224
+ await execute(`UPDATE workflow_approval SET status = 'REJECTED', "actorId" = ?, comment = ?, "decidedAt" = ?
225
+ WHERE "instanceId" = ? AND "stepId" = ? AND status = 'PENDING'`, [
224
226
  context.actorId,
225
227
  input.reason,
226
228
  now,
227
229
  input.instanceId,
228
230
  instances[0].currentStepId
229
231
  ]);
230
- await db.execute(`UPDATE workflow_instance SET status = 'REJECTED', completedAt = ? WHERE id = ?`, [now, input.instanceId]);
231
- const updated = (await db.query(`SELECT * FROM workflow_instance WHERE id = ?`, [
232
- input.instanceId
233
- ])).rows;
232
+ await execute(`UPDATE workflow_instance SET status = 'REJECTED', "completedAt" = ? WHERE id = ?`, [now, input.instanceId]);
233
+ const updated = await queryRows(`SELECT * FROM workflow_instance WHERE id = ?`, [input.instanceId]);
234
234
  return rowToInstance(updated[0]);
235
235
  }
236
236
  async function getApprovals(instanceId) {
237
- const rows = (await db.query(`SELECT * FROM workflow_approval WHERE instanceId = ? ORDER BY createdAt`, [instanceId])).rows;
237
+ const rows = await queryRows(`SELECT * FROM workflow_approval WHERE "instanceId" = ? ORDER BY "createdAt"`, [instanceId]);
238
238
  return rows.map(rowToApproval);
239
239
  }
240
240
  return {
package/dist/index.d.ts CHANGED
@@ -3,12 +3,13 @@
3
3
  *
4
4
  * Demonstrates a complete workflow/approval system with state machine engine.
5
5
  */
6
- export * from './workflow';
7
- export * from './instance';
8
6
  export * from './approval';
9
- export * from './shared';
10
7
  export * from './handlers/workflow.handlers';
11
- export * from './state-machine';
8
+ export * from './instance';
12
9
  export * from './presentations';
13
- export * from './workflow-system.feature';
10
+ export * from './shared';
11
+ export * from './state-machine';
14
12
  export * from './ui';
13
+ export * from './visualizations';
14
+ export * from './workflow';
15
+ export * from './workflow-system.feature';