@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
package/dist/index.js CHANGED
@@ -20,7 +20,7 @@ var ApprovalDecisionEnum = defineEnum("ApprovalDecision", [
20
20
 
21
21
  // src/approval/approval.event.ts
22
22
  import { defineEvent } from "@contractspec/lib.contracts-spec";
23
- import { ScalarTypeEnum, defineSchemaModel } from "@contractspec/lib.schema";
23
+ import { defineSchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
24
24
  var ApprovalRequestedPayload = defineSchemaModel({
25
25
  name: "ApprovalRequestedEventPayload",
26
26
  description: "Payload when approval is requested",
@@ -716,9 +716,19 @@ function rowToApproval(row) {
716
716
  };
717
717
  }
718
718
  function createWorkflowHandlers(db) {
719
+ function normalizeSql(sql) {
720
+ let placeholderIndex = 0;
721
+ return sql.replace(/\?/g, () => `$${++placeholderIndex}`);
722
+ }
723
+ async function queryRows(sql, params = []) {
724
+ return (await db.query(normalizeSql(sql), params)).rows;
725
+ }
726
+ async function execute(sql, params = []) {
727
+ await db.execute(normalizeSql(sql), params);
728
+ }
719
729
  async function listDefinitions(input) {
720
730
  const { projectId, status, search, limit = 20, offset = 0 } = input;
721
- let whereClause = "WHERE projectId = ?";
731
+ let whereClause = 'WHERE "projectId" = ?';
722
732
  const params = [projectId];
723
733
  if (status && status !== "all") {
724
734
  whereClause += " AND status = ?";
@@ -728,9 +738,9 @@ function createWorkflowHandlers(db) {
728
738
  whereClause += " AND name LIKE ?";
729
739
  params.push(`%${search}%`);
730
740
  }
731
- const countResult = (await db.query(`SELECT COUNT(*) as count FROM workflow_definition ${whereClause}`, params)).rows;
741
+ const countResult = await queryRows(`SELECT COUNT(*) as count FROM workflow_definition ${whereClause}`, params);
732
742
  const total = countResult[0]?.count ?? 0;
733
- const rows = (await db.query(`SELECT * FROM workflow_definition ${whereClause} ORDER BY updatedAt DESC LIMIT ? OFFSET ?`, [...params, limit, offset])).rows;
743
+ const rows = await queryRows(`SELECT * FROM workflow_definition ${whereClause} ORDER BY "updatedAt" DESC LIMIT ? OFFSET ?`, [...params, limit, offset]);
734
744
  return {
735
745
  definitions: rows.map(rowToDefinition),
736
746
  total
@@ -739,7 +749,7 @@ function createWorkflowHandlers(db) {
739
749
  async function createDefinition(input, context) {
740
750
  const id = generateId("wfdef");
741
751
  const now = new Date().toISOString();
742
- await db.execute(`INSERT INTO workflow_definition (id, projectId, organizationId, name, description, type, status, createdAt, updatedAt)
752
+ await execute(`INSERT INTO workflow_definition (id, "projectId", "organizationId", name, description, type, status, "createdAt", "updatedAt")
743
753
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
744
754
  id,
745
755
  context.projectId,
@@ -751,15 +761,15 @@ function createWorkflowHandlers(db) {
751
761
  now,
752
762
  now
753
763
  ]);
754
- const rows = (await db.query(`SELECT * FROM workflow_definition WHERE id = ?`, [id])).rows;
764
+ const rows = await queryRows(`SELECT * FROM workflow_definition WHERE id = ?`, [id]);
755
765
  return rowToDefinition(rows[0]);
756
766
  }
757
767
  async function addStep(input) {
758
768
  const id = generateId("wfstep");
759
769
  const now = new Date().toISOString();
760
- const maxOrderResult = (await db.query(`SELECT MAX(stepOrder) as maxOrder FROM workflow_step WHERE definitionId = ?`, [input.definitionId])).rows;
770
+ const maxOrderResult = await queryRows(`SELECT MAX("stepOrder") as maxOrder FROM workflow_step WHERE "definitionId" = ?`, [input.definitionId]);
761
771
  const nextOrder = (maxOrderResult[0]?.maxOrder ?? 0) + 1;
762
- await db.execute(`INSERT INTO workflow_step (id, definitionId, name, description, stepOrder, type, requiredRoles, autoApproveCondition, timeoutHours, createdAt)
772
+ await execute(`INSERT INTO workflow_step (id, "definitionId", name, description, "stepOrder", type, "requiredRoles", "autoApproveCondition", "timeoutHours", "createdAt")
763
773
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
764
774
  id,
765
775
  input.definitionId,
@@ -772,11 +782,11 @@ function createWorkflowHandlers(db) {
772
782
  input.timeoutHours ?? null,
773
783
  now
774
784
  ]);
775
- const rows = (await db.query(`SELECT * FROM workflow_step WHERE id = ?`, [id])).rows;
785
+ const rows = await queryRows(`SELECT * FROM workflow_step WHERE id = ?`, [id]);
776
786
  return rowToStep(rows[0]);
777
787
  }
778
788
  async function getSteps(definitionId) {
779
- const rows = (await db.query(`SELECT * FROM workflow_step WHERE definitionId = ? ORDER BY stepOrder`, [definitionId])).rows;
789
+ const rows = await queryRows(`SELECT * FROM workflow_step WHERE "definitionId" = ? ORDER BY "stepOrder"`, [definitionId]);
780
790
  return rows.map(rowToStep);
781
791
  }
782
792
  async function listInstances(input) {
@@ -788,10 +798,10 @@ function createWorkflowHandlers(db) {
788
798
  limit = 20,
789
799
  offset = 0
790
800
  } = input;
791
- let whereClause = "WHERE projectId = ?";
801
+ let whereClause = 'WHERE "projectId" = ?';
792
802
  const params = [projectId];
793
803
  if (definitionId) {
794
- whereClause += " AND definitionId = ?";
804
+ whereClause += ' AND "definitionId" = ?';
795
805
  params.push(definitionId);
796
806
  }
797
807
  if (status && status !== "all") {
@@ -799,12 +809,12 @@ function createWorkflowHandlers(db) {
799
809
  params.push(status);
800
810
  }
801
811
  if (requestedBy) {
802
- whereClause += " AND requestedBy = ?";
812
+ whereClause += ' AND "requestedBy" = ?';
803
813
  params.push(requestedBy);
804
814
  }
805
- const countResult = (await db.query(`SELECT COUNT(*) as count FROM workflow_instance ${whereClause}`, params)).rows;
815
+ const countResult = await queryRows(`SELECT COUNT(*) as count FROM workflow_instance ${whereClause}`, params);
806
816
  const total = countResult[0]?.count ?? 0;
807
- const rows = (await db.query(`SELECT * FROM workflow_instance ${whereClause} ORDER BY startedAt DESC LIMIT ? OFFSET ?`, [...params, limit, offset])).rows;
817
+ const rows = await queryRows(`SELECT * FROM workflow_instance ${whereClause} ORDER BY "startedAt" DESC LIMIT ? OFFSET ?`, [...params, limit, offset]);
808
818
  return {
809
819
  instances: rows.map(rowToInstance),
810
820
  total
@@ -813,9 +823,9 @@ function createWorkflowHandlers(db) {
813
823
  async function startInstance(input, context) {
814
824
  const id = generateId("wfinst");
815
825
  const now = new Date().toISOString();
816
- const steps = (await db.query(`SELECT * FROM workflow_step WHERE definitionId = ? ORDER BY stepOrder LIMIT 1`, [input.definitionId])).rows;
826
+ const steps = await queryRows(`SELECT * FROM workflow_step WHERE "definitionId" = ? ORDER BY "stepOrder" LIMIT 1`, [input.definitionId]);
817
827
  const firstStepId = steps[0]?.id ?? null;
818
- await db.execute(`INSERT INTO workflow_instance (id, projectId, definitionId, status, currentStepId, data, requestedBy, startedAt)
828
+ await execute(`INSERT INTO workflow_instance (id, "projectId", "definitionId", status, "currentStepId", data, "requestedBy", "startedAt")
819
829
  VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, [
820
830
  id,
821
831
  context.projectId,
@@ -827,36 +837,32 @@ function createWorkflowHandlers(db) {
827
837
  now
828
838
  ]);
829
839
  if (firstStepId) {
830
- await db.execute(`INSERT INTO workflow_approval (id, instanceId, stepId, status, createdAt)
840
+ await execute(`INSERT INTO workflow_approval (id, "instanceId", "stepId", status, "createdAt")
831
841
  VALUES (?, ?, ?, ?, ?)`, [generateId("wfappr"), id, firstStepId, "PENDING", now]);
832
842
  }
833
- const rows = (await db.query(`SELECT * FROM workflow_instance WHERE id = ?`, [id])).rows;
843
+ const rows = await queryRows(`SELECT * FROM workflow_instance WHERE id = ?`, [id]);
834
844
  return rowToInstance(rows[0]);
835
845
  }
836
846
  async function approveStep(input, context) {
837
847
  const now = new Date().toISOString();
838
- const instances = (await db.query(`SELECT * FROM workflow_instance WHERE id = ?`, [
839
- input.instanceId
840
- ])).rows;
848
+ const instances = await queryRows(`SELECT * FROM workflow_instance WHERE id = ?`, [input.instanceId]);
841
849
  if (!instances[0]) {
842
850
  throw new Error("NOT_FOUND");
843
851
  }
844
852
  const instance = instances[0];
845
- await db.execute(`UPDATE workflow_approval SET status = 'APPROVED', actorId = ?, comment = ?, decidedAt = ?
846
- WHERE instanceId = ? AND stepId = ? AND status = 'PENDING'`, [
853
+ await execute(`UPDATE workflow_approval SET status = 'APPROVED', "actorId" = ?, comment = ?, "decidedAt" = ?
854
+ WHERE "instanceId" = ? AND "stepId" = ? AND status = 'PENDING'`, [
847
855
  context.actorId,
848
856
  input.comment ?? null,
849
857
  now,
850
858
  input.instanceId,
851
859
  instance.currentStepId
852
860
  ]);
853
- const currentStep = (await db.query(`SELECT * FROM workflow_step WHERE id = ?`, [
854
- instance.currentStepId
855
- ])).rows;
856
- 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;
861
+ const currentStep = await queryRows(`SELECT * FROM workflow_step WHERE id = ?`, [instance.currentStepId]);
862
+ const nextSteps = await queryRows(`SELECT * FROM workflow_step WHERE "definitionId" = ? AND "stepOrder" > ? ORDER BY "stepOrder" LIMIT 1`, [instance.definitionId, currentStep[0]?.stepOrder ?? 0]);
857
863
  if (nextSteps[0]) {
858
- await db.execute(`UPDATE workflow_instance SET currentStepId = ? WHERE id = ?`, [nextSteps[0].id, input.instanceId]);
859
- await db.execute(`INSERT INTO workflow_approval (id, instanceId, stepId, status, createdAt)
864
+ await execute(`UPDATE workflow_instance SET "currentStepId" = ? WHERE id = ?`, [nextSteps[0].id, input.instanceId]);
865
+ await execute(`INSERT INTO workflow_approval (id, "instanceId", "stepId", status, "createdAt")
860
866
  VALUES (?, ?, ?, ?, ?)`, [
861
867
  generateId("wfappr"),
862
868
  input.instanceId,
@@ -865,37 +871,31 @@ function createWorkflowHandlers(db) {
865
871
  now
866
872
  ]);
867
873
  } else {
868
- await db.execute(`UPDATE workflow_instance SET status = 'COMPLETED', currentStepId = NULL, completedAt = ? WHERE id = ?`, [now, input.instanceId]);
874
+ await execute(`UPDATE workflow_instance SET status = 'COMPLETED', "currentStepId" = NULL, "completedAt" = ? WHERE id = ?`, [now, input.instanceId]);
869
875
  }
870
- const updated = (await db.query(`SELECT * FROM workflow_instance WHERE id = ?`, [
871
- input.instanceId
872
- ])).rows;
876
+ const updated = await queryRows(`SELECT * FROM workflow_instance WHERE id = ?`, [input.instanceId]);
873
877
  return rowToInstance(updated[0]);
874
878
  }
875
879
  async function rejectStep(input, context) {
876
880
  const now = new Date().toISOString();
877
- const instances = (await db.query(`SELECT * FROM workflow_instance WHERE id = ?`, [
878
- input.instanceId
879
- ])).rows;
881
+ const instances = await queryRows(`SELECT * FROM workflow_instance WHERE id = ?`, [input.instanceId]);
880
882
  if (!instances[0]) {
881
883
  throw new Error("NOT_FOUND");
882
884
  }
883
- await db.execute(`UPDATE workflow_approval SET status = 'REJECTED', actorId = ?, comment = ?, decidedAt = ?
884
- WHERE instanceId = ? AND stepId = ? AND status = 'PENDING'`, [
885
+ await execute(`UPDATE workflow_approval SET status = 'REJECTED', "actorId" = ?, comment = ?, "decidedAt" = ?
886
+ WHERE "instanceId" = ? AND "stepId" = ? AND status = 'PENDING'`, [
885
887
  context.actorId,
886
888
  input.reason,
887
889
  now,
888
890
  input.instanceId,
889
891
  instances[0].currentStepId
890
892
  ]);
891
- await db.execute(`UPDATE workflow_instance SET status = 'REJECTED', completedAt = ? WHERE id = ?`, [now, input.instanceId]);
892
- const updated = (await db.query(`SELECT * FROM workflow_instance WHERE id = ?`, [
893
- input.instanceId
894
- ])).rows;
893
+ await execute(`UPDATE workflow_instance SET status = 'REJECTED', "completedAt" = ? WHERE id = ?`, [now, input.instanceId]);
894
+ const updated = await queryRows(`SELECT * FROM workflow_instance WHERE id = ?`, [input.instanceId]);
895
895
  return rowToInstance(updated[0]);
896
896
  }
897
897
  async function getApprovals(instanceId) {
898
- const rows = (await db.query(`SELECT * FROM workflow_approval WHERE instanceId = ? ORDER BY createdAt`, [instanceId])).rows;
898
+ const rows = await queryRows(`SELECT * FROM workflow_approval WHERE "instanceId" = ? ORDER BY "createdAt"`, [instanceId]);
899
899
  return rows.map(rowToApproval);
900
900
  }
901
901
  return {
@@ -911,398 +911,596 @@ function createWorkflowHandlers(db) {
911
911
  };
912
912
  }
913
913
 
914
- // src/workflow/workflow.enum.ts
914
+ // src/instance/instance.enum.ts
915
915
  import { defineEnum as defineEnum2 } from "@contractspec/lib.schema";
916
- var WorkflowStatusEnum = defineEnum2("WorkflowStatus", [
917
- "DRAFT",
918
- "ACTIVE",
919
- "DEPRECATED",
920
- "ARCHIVED"
921
- ]);
922
- var TriggerTypeEnum = defineEnum2("WorkflowTriggerType", [
923
- "MANUAL",
924
- "EVENT",
925
- "SCHEDULED",
926
- "API"
927
- ]);
928
- var StepTypeEnum = defineEnum2("StepType", [
929
- "START",
930
- "APPROVAL",
931
- "TASK",
932
- "CONDITION",
933
- "PARALLEL",
934
- "WAIT",
935
- "ACTION",
936
- "END"
937
- ]);
938
- var ApprovalModeEnum = defineEnum2("ApprovalMode", [
939
- "ANY",
940
- "ALL",
941
- "MAJORITY",
942
- "SEQUENTIAL"
916
+ var InstanceStatusEnum = defineEnum2("InstanceStatus", [
917
+ "PENDING",
918
+ "RUNNING",
919
+ "WAITING",
920
+ "PAUSED",
921
+ "COMPLETED",
922
+ "CANCELLED",
923
+ "FAILED",
924
+ "TIMEOUT"
943
925
  ]);
944
926
 
945
- // src/workflow/workflow.schema.ts
927
+ // src/instance/instance.event.ts
928
+ import { defineEvent as defineEvent2 } from "@contractspec/lib.contracts-spec";
946
929
  import { defineSchemaModel as defineSchemaModel4, ScalarTypeEnum as ScalarTypeEnum4 } from "@contractspec/lib.schema";
947
- var WorkflowStepModel = defineSchemaModel4({
948
- name: "WorkflowStepModel",
949
- description: "A step in a workflow definition",
950
- fields: {
951
- id: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
952
- key: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
953
- name: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
954
- description: { type: ScalarTypeEnum4.String_unsecure(), isOptional: true },
955
- type: { type: StepTypeEnum, isOptional: false },
956
- position: { type: ScalarTypeEnum4.Int_unsecure(), isOptional: false },
957
- transitions: { type: ScalarTypeEnum4.JSON(), isOptional: false },
958
- approvalMode: { type: ApprovalModeEnum, isOptional: true },
959
- approverRoles: {
960
- type: ScalarTypeEnum4.String_unsecure(),
961
- isArray: true,
962
- isOptional: true
963
- }
964
- }
965
- });
966
- var WorkflowDefinitionModel = defineSchemaModel4({
967
- name: "WorkflowDefinitionModel",
968
- description: "A workflow definition",
930
+ var InstanceEventPayload = defineSchemaModel4({
931
+ name: "InstanceEventPayload",
932
+ description: "Base payload for instance events",
969
933
  fields: {
970
- id: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
971
- name: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
972
- key: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
973
- description: { type: ScalarTypeEnum4.String_unsecure(), isOptional: true },
974
- version: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
975
- status: { type: WorkflowStatusEnum, isOptional: false },
976
- triggerType: { type: TriggerTypeEnum, isOptional: false },
977
- initialStepId: {
978
- type: ScalarTypeEnum4.String_unsecure(),
979
- isOptional: true
980
- },
981
- featureFlagKey: {
934
+ instanceId: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
935
+ workflowId: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
936
+ workflowKey: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
937
+ status: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
938
+ referenceId: { type: ScalarTypeEnum4.String_unsecure(), isOptional: true },
939
+ referenceType: {
982
940
  type: ScalarTypeEnum4.String_unsecure(),
983
941
  isOptional: true
984
942
  },
943
+ triggeredBy: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
985
944
  organizationId: {
986
945
  type: ScalarTypeEnum4.String_unsecure(),
987
946
  isOptional: false
988
947
  },
989
- createdAt: { type: ScalarTypeEnum4.DateTime(), isOptional: false },
990
- updatedAt: { type: ScalarTypeEnum4.DateTime(), isOptional: false },
991
- steps: { type: WorkflowStepModel, isArray: true, isOptional: true }
948
+ timestamp: { type: ScalarTypeEnum4.DateTime(), isOptional: false }
992
949
  }
993
950
  });
994
- var CreateWorkflowInputModel = defineSchemaModel4({
995
- name: "CreateWorkflowInput",
996
- description: "Input for creating a workflow definition",
951
+ var StepTransitionPayload = defineSchemaModel4({
952
+ name: "StepTransitionEventPayload",
953
+ description: "Payload for step transition events",
997
954
  fields: {
998
- name: { type: ScalarTypeEnum4.NonEmptyString(), isOptional: false },
999
- key: { type: ScalarTypeEnum4.NonEmptyString(), isOptional: false },
1000
- description: { type: ScalarTypeEnum4.String_unsecure(), isOptional: true },
1001
- triggerType: { type: TriggerTypeEnum, isOptional: true },
1002
- triggerConfig: { type: ScalarTypeEnum4.JSON(), isOptional: true },
1003
- featureFlagKey: {
955
+ instanceId: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
956
+ workflowId: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
957
+ fromStepKey: { type: ScalarTypeEnum4.String_unsecure(), isOptional: true },
958
+ toStepKey: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
959
+ action: { type: ScalarTypeEnum4.String_unsecure(), isOptional: true },
960
+ executedBy: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
961
+ timestamp: { type: ScalarTypeEnum4.DateTime(), isOptional: false }
962
+ }
963
+ });
964
+ var InstanceCompletedPayload = defineSchemaModel4({
965
+ name: "InstanceCompletedEventPayload",
966
+ description: "Payload when instance completes",
967
+ fields: {
968
+ instanceId: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
969
+ workflowId: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
970
+ workflowKey: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
971
+ outcome: { type: ScalarTypeEnum4.String_unsecure(), isOptional: false },
972
+ referenceId: { type: ScalarTypeEnum4.String_unsecure(), isOptional: true },
973
+ referenceType: {
1004
974
  type: ScalarTypeEnum4.String_unsecure(),
1005
975
  isOptional: true
1006
976
  },
1007
- settings: { type: ScalarTypeEnum4.JSON(), isOptional: true }
977
+ duration: { type: ScalarTypeEnum4.Int_unsecure(), isOptional: false },
978
+ timestamp: { type: ScalarTypeEnum4.DateTime(), isOptional: false }
1008
979
  }
1009
980
  });
1010
- var UpdateWorkflowInputModel = defineSchemaModel4({
1011
- name: "UpdateWorkflowInput",
1012
- description: "Input for updating a workflow definition",
981
+ var InstanceStartedEvent = defineEvent2({
982
+ meta: {
983
+ key: "workflow.instance.started",
984
+ version: "1.0.0",
985
+ description: "A new workflow instance has been started.",
986
+ stability: "stable",
987
+ owners: ["@workflow-team"],
988
+ tags: ["workflow", "instance", "started"]
989
+ },
990
+ payload: InstanceEventPayload
991
+ });
992
+ var StepEnteredEvent = defineEvent2({
993
+ meta: {
994
+ key: "workflow.step.entered",
995
+ version: "1.0.0",
996
+ description: "A workflow instance has entered a new step.",
997
+ stability: "stable",
998
+ owners: ["@workflow-team"],
999
+ tags: ["workflow", "step", "entered"]
1000
+ },
1001
+ payload: StepTransitionPayload
1002
+ });
1003
+ var StepExitedEvent = defineEvent2({
1004
+ meta: {
1005
+ key: "workflow.step.exited",
1006
+ version: "1.0.0",
1007
+ description: "A workflow instance has exited a step.",
1008
+ stability: "stable",
1009
+ owners: ["@workflow-team"],
1010
+ tags: ["workflow", "step", "exited"]
1011
+ },
1012
+ payload: StepTransitionPayload
1013
+ });
1014
+ var InstanceCompletedEvent = defineEvent2({
1015
+ meta: {
1016
+ key: "workflow.instance.completed",
1017
+ version: "1.0.0",
1018
+ description: "A workflow instance has completed.",
1019
+ stability: "stable",
1020
+ owners: ["@workflow-team"],
1021
+ tags: ["workflow", "instance", "completed"]
1022
+ },
1023
+ payload: InstanceCompletedPayload
1024
+ });
1025
+ var InstanceCancelledEvent = defineEvent2({
1026
+ meta: {
1027
+ key: "workflow.instance.cancelled",
1028
+ version: "1.0.0",
1029
+ description: "A workflow instance has been cancelled.",
1030
+ stability: "stable",
1031
+ owners: ["@workflow-team"],
1032
+ tags: ["workflow", "instance", "cancelled"]
1033
+ },
1034
+ payload: InstanceEventPayload
1035
+ });
1036
+ var InstancePausedEvent = defineEvent2({
1037
+ meta: {
1038
+ key: "workflow.instance.paused",
1039
+ version: "1.0.0",
1040
+ description: "A workflow instance has been paused.",
1041
+ stability: "stable",
1042
+ owners: ["@workflow-team"],
1043
+ tags: ["workflow", "instance", "paused"]
1044
+ },
1045
+ payload: InstanceEventPayload
1046
+ });
1047
+ var InstanceResumedEvent = defineEvent2({
1048
+ meta: {
1049
+ key: "workflow.instance.resumed",
1050
+ version: "1.0.0",
1051
+ description: "A workflow instance has been resumed.",
1052
+ stability: "stable",
1053
+ owners: ["@workflow-team"],
1054
+ tags: ["workflow", "instance", "resumed"]
1055
+ },
1056
+ payload: InstanceEventPayload
1057
+ });
1058
+ var InstanceFailedEvent = defineEvent2({
1059
+ meta: {
1060
+ key: "workflow.instance.failed",
1061
+ version: "1.0.0",
1062
+ description: "A workflow instance has failed.",
1063
+ stability: "stable",
1064
+ owners: ["@workflow-team"],
1065
+ tags: ["workflow", "instance", "failed"]
1066
+ },
1067
+ payload: InstanceEventPayload
1068
+ });
1069
+ var InstanceTimedOutEvent = defineEvent2({
1070
+ meta: {
1071
+ key: "workflow.instance.timedOut",
1072
+ version: "1.0.0",
1073
+ description: "A workflow instance has timed out.",
1074
+ stability: "stable",
1075
+ owners: ["@workflow-team"],
1076
+ tags: ["workflow", "instance", "timeout"]
1077
+ },
1078
+ payload: InstanceEventPayload
1079
+ });
1080
+
1081
+ // src/instance/instance.schema.ts
1082
+ import { defineSchemaModel as defineSchemaModel5, ScalarTypeEnum as ScalarTypeEnum5 } from "@contractspec/lib.schema";
1083
+ var WorkflowInstanceModel = defineSchemaModel5({
1084
+ name: "WorkflowInstanceModel",
1085
+ description: "A running workflow instance",
1013
1086
  fields: {
1014
- workflowId: {
1015
- type: ScalarTypeEnum4.String_unsecure(),
1087
+ id: { type: ScalarTypeEnum5.String_unsecure(), isOptional: false },
1088
+ workflowDefinitionId: {
1089
+ type: ScalarTypeEnum5.String_unsecure(),
1016
1090
  isOptional: false
1017
1091
  },
1018
- name: { type: ScalarTypeEnum4.String_unsecure(), isOptional: true },
1019
- description: { type: ScalarTypeEnum4.String_unsecure(), isOptional: true },
1020
- triggerType: { type: TriggerTypeEnum, isOptional: true },
1021
- triggerConfig: { type: ScalarTypeEnum4.JSON(), isOptional: true },
1022
- featureFlagKey: {
1023
- type: ScalarTypeEnum4.String_unsecure(),
1092
+ referenceId: { type: ScalarTypeEnum5.String_unsecure(), isOptional: true },
1093
+ referenceType: {
1094
+ type: ScalarTypeEnum5.String_unsecure(),
1095
+ isOptional: true
1096
+ },
1097
+ status: { type: InstanceStatusEnum, isOptional: false },
1098
+ currentStepId: {
1099
+ type: ScalarTypeEnum5.String_unsecure(),
1100
+ isOptional: true
1101
+ },
1102
+ contextData: { type: ScalarTypeEnum5.JSON(), isOptional: true },
1103
+ triggeredBy: { type: ScalarTypeEnum5.String_unsecure(), isOptional: false },
1104
+ organizationId: {
1105
+ type: ScalarTypeEnum5.String_unsecure(),
1106
+ isOptional: false
1107
+ },
1108
+ priority: { type: ScalarTypeEnum5.Int_unsecure(), isOptional: false },
1109
+ dueAt: { type: ScalarTypeEnum5.DateTime(), isOptional: true },
1110
+ outcome: { type: ScalarTypeEnum5.String_unsecure(), isOptional: true },
1111
+ resultData: { type: ScalarTypeEnum5.JSON(), isOptional: true },
1112
+ errorMessage: {
1113
+ type: ScalarTypeEnum5.String_unsecure(),
1024
1114
  isOptional: true
1025
1115
  },
1026
- settings: { type: ScalarTypeEnum4.JSON(), isOptional: true }
1116
+ createdAt: { type: ScalarTypeEnum5.DateTime(), isOptional: false },
1117
+ startedAt: { type: ScalarTypeEnum5.DateTime(), isOptional: true },
1118
+ completedAt: { type: ScalarTypeEnum5.DateTime(), isOptional: true }
1027
1119
  }
1028
1120
  });
1029
- var AddStepInputModel = defineSchemaModel4({
1030
- name: "AddStepInput",
1031
- description: "Input for adding a step to a workflow",
1121
+ var StartWorkflowInputModel = defineSchemaModel5({
1122
+ name: "StartWorkflowInput",
1123
+ description: "Input for starting a workflow",
1032
1124
  fields: {
1033
- workflowId: {
1034
- type: ScalarTypeEnum4.String_unsecure(),
1035
- isOptional: false
1125
+ workflowKey: { type: ScalarTypeEnum5.NonEmptyString(), isOptional: false },
1126
+ contextData: { type: ScalarTypeEnum5.JSON(), isOptional: true },
1127
+ referenceId: { type: ScalarTypeEnum5.String_unsecure(), isOptional: true },
1128
+ referenceType: {
1129
+ type: ScalarTypeEnum5.String_unsecure(),
1130
+ isOptional: true
1036
1131
  },
1037
- key: { type: ScalarTypeEnum4.NonEmptyString(), isOptional: false },
1038
- name: { type: ScalarTypeEnum4.NonEmptyString(), isOptional: false },
1039
- description: { type: ScalarTypeEnum4.String_unsecure(), isOptional: true },
1040
- type: { type: StepTypeEnum, isOptional: false },
1041
- position: { type: ScalarTypeEnum4.Int_unsecure(), isOptional: true },
1042
- transitions: { type: ScalarTypeEnum4.JSON(), isOptional: false },
1043
- approvalMode: { type: ApprovalModeEnum, isOptional: true },
1044
- approverRoles: {
1045
- type: ScalarTypeEnum4.String_unsecure(),
1046
- isArray: true,
1132
+ priority: { type: ScalarTypeEnum5.Int_unsecure(), isOptional: true },
1133
+ dueAt: { type: ScalarTypeEnum5.DateTime(), isOptional: true }
1134
+ }
1135
+ });
1136
+ var TransitionInputModel = defineSchemaModel5({
1137
+ name: "TransitionInput",
1138
+ description: "Input for transitioning a workflow",
1139
+ fields: {
1140
+ instanceId: { type: ScalarTypeEnum5.String_unsecure(), isOptional: false },
1141
+ action: { type: ScalarTypeEnum5.NonEmptyString(), isOptional: false },
1142
+ data: { type: ScalarTypeEnum5.JSON(), isOptional: true },
1143
+ comment: { type: ScalarTypeEnum5.String_unsecure(), isOptional: true }
1144
+ }
1145
+ });
1146
+ var TransitionResultModel = defineSchemaModel5({
1147
+ name: "TransitionResult",
1148
+ description: "Result of a workflow transition",
1149
+ fields: {
1150
+ success: { type: ScalarTypeEnum5.Boolean(), isOptional: false },
1151
+ instance: { type: WorkflowInstanceModel, isOptional: false },
1152
+ previousStepKey: {
1153
+ type: ScalarTypeEnum5.String_unsecure(),
1047
1154
  isOptional: true
1048
1155
  },
1049
- approverUserIds: {
1050
- type: ScalarTypeEnum4.String_unsecure(),
1051
- isArray: true,
1156
+ currentStepKey: {
1157
+ type: ScalarTypeEnum5.String_unsecure(),
1052
1158
  isOptional: true
1053
1159
  },
1054
- timeoutSeconds: { type: ScalarTypeEnum4.Int_unsecure(), isOptional: true },
1055
- slaSeconds: { type: ScalarTypeEnum4.Int_unsecure(), isOptional: true }
1160
+ message: { type: ScalarTypeEnum5.String_unsecure(), isOptional: true }
1056
1161
  }
1057
1162
  });
1058
1163
 
1059
- // src/workflow/workflow.operations.ts
1164
+ // src/instance/instance.operations.ts
1060
1165
  import {
1061
1166
  defineCommand as defineCommand2,
1062
1167
  defineQuery as defineQuery2
1063
1168
  } from "@contractspec/lib.contracts-spec/operations";
1064
- import { defineSchemaModel as defineSchemaModel5, ScalarTypeEnum as ScalarTypeEnum5 } from "@contractspec/lib.schema";
1169
+ import { defineSchemaModel as defineSchemaModel6, ScalarTypeEnum as ScalarTypeEnum6 } from "@contractspec/lib.schema";
1065
1170
  var OWNERS2 = ["@example.workflow-system"];
1066
- var CreateWorkflowContract = defineCommand2({
1171
+ var StartWorkflowContract = defineCommand2({
1067
1172
  meta: {
1068
- key: "workflow.definition.create",
1173
+ key: "workflow.instance.start",
1069
1174
  version: "1.0.0",
1070
1175
  stability: "stable",
1071
1176
  owners: [...OWNERS2],
1072
- tags: ["workflow", "definition", "create"],
1073
- description: "Create a new workflow definition.",
1074
- goal: "Allow users to define new workflow blueprints.",
1075
- context: "Workflow designer, admin panel."
1177
+ tags: ["workflow", "instance", "start"],
1178
+ description: "Start a new workflow instance.",
1179
+ goal: "Initiate a workflow for a business process.",
1180
+ context: "Order creation, request submission, etc."
1076
1181
  },
1077
1182
  io: {
1078
- input: CreateWorkflowInputModel,
1079
- output: WorkflowDefinitionModel
1183
+ input: StartWorkflowInputModel,
1184
+ output: WorkflowInstanceModel
1080
1185
  },
1081
1186
  policy: { auth: "user" },
1082
1187
  sideEffects: {
1083
1188
  emits: [
1084
1189
  {
1085
- key: "workflow.definition.created",
1190
+ key: "workflow.instance.started",
1086
1191
  version: "1.0.0",
1087
- when: "Workflow is created",
1088
- payload: WorkflowDefinitionModel
1192
+ when: "Workflow starts",
1193
+ payload: WorkflowInstanceModel
1194
+ },
1195
+ {
1196
+ key: "workflow.step.entered",
1197
+ version: "1.0.0",
1198
+ when: "First step entered",
1199
+ payload: WorkflowInstanceModel
1089
1200
  }
1090
1201
  ],
1091
- audit: ["workflow.definition.created"]
1202
+ audit: ["workflow.instance.started"]
1092
1203
  },
1093
1204
  acceptance: {
1094
1205
  scenarios: [
1095
1206
  {
1096
- key: "create-workflow-happy-path",
1097
- given: ["User is admin"],
1098
- when: ["User creates new workflow definition"],
1099
- then: [
1100
- "Definition is created",
1101
- "WorkflowDefinitionCreated event is emitted"
1102
- ]
1207
+ key: "start-workflow-happy-path",
1208
+ given: ["Workflow definition exists"],
1209
+ when: ["User starts workflow"],
1210
+ then: ["Instance is created and started"]
1103
1211
  }
1104
1212
  ],
1105
1213
  examples: [
1106
1214
  {
1107
- key: "create-onboarding",
1215
+ key: "start-onboarding",
1108
1216
  input: {
1109
- key: "onboarding-v1",
1110
- name: "Employee Onboarding",
1111
- version: "1.0.0"
1217
+ workflowKey: "onboarding-v1",
1218
+ context: { employeeId: "emp-123" }
1112
1219
  },
1113
- output: { id: "def-123", status: "draft" }
1220
+ output: { id: "inst-456", status: "running" }
1114
1221
  }
1115
1222
  ]
1116
1223
  }
1117
1224
  });
1118
- var UpdateWorkflowContract = defineCommand2({
1225
+ var TransitionWorkflowContract = defineCommand2({
1119
1226
  meta: {
1120
- key: "workflow.definition.update",
1227
+ key: "workflow.instance.transition",
1121
1228
  version: "1.0.0",
1122
1229
  stability: "stable",
1123
1230
  owners: [...OWNERS2],
1124
- tags: ["workflow", "definition", "update"],
1125
- description: "Update an existing workflow definition.",
1126
- goal: "Allow users to modify workflow blueprints.",
1127
- context: "Workflow designer."
1231
+ tags: ["workflow", "instance", "transition", "state-machine"],
1232
+ description: "Transition a workflow instance to the next step.",
1233
+ goal: "Move workflow forward based on action.",
1234
+ context: "Task completion, approval decisions."
1128
1235
  },
1129
1236
  io: {
1130
- input: UpdateWorkflowInputModel,
1131
- output: WorkflowDefinitionModel
1237
+ input: TransitionInputModel,
1238
+ output: TransitionResultModel
1132
1239
  },
1133
1240
  policy: { auth: "user" },
1134
1241
  sideEffects: {
1135
1242
  emits: [
1136
1243
  {
1137
- key: "workflow.definition.updated",
1244
+ key: "workflow.step.exited",
1138
1245
  version: "1.0.0",
1139
- when: "Workflow is updated",
1140
- payload: WorkflowDefinitionModel
1246
+ when: "Step is exited",
1247
+ payload: WorkflowInstanceModel
1248
+ },
1249
+ {
1250
+ key: "workflow.step.entered",
1251
+ version: "1.0.0",
1252
+ when: "New step is entered",
1253
+ payload: WorkflowInstanceModel
1254
+ },
1255
+ {
1256
+ key: "workflow.instance.completed",
1257
+ version: "1.0.0",
1258
+ when: "Workflow reaches end",
1259
+ payload: WorkflowInstanceModel
1141
1260
  }
1142
1261
  ],
1143
- audit: ["workflow.definition.updated"]
1262
+ audit: ["workflow.instance.transitioned"]
1144
1263
  },
1145
1264
  acceptance: {
1146
1265
  scenarios: [
1147
1266
  {
1148
- key: "update-workflow-happy-path",
1149
- given: ["Workflow definition exists"],
1150
- when: ["User updates definition"],
1151
- then: [
1152
- "Definition is updated",
1153
- "WorkflowDefinitionUpdated event is emitted"
1154
- ]
1267
+ key: "transition-workflow-happy-path",
1268
+ given: ["Workflow instance is waiting at step"],
1269
+ when: ["User provides input"],
1270
+ then: ["Instance moves to next step"]
1155
1271
  }
1156
1272
  ],
1157
1273
  examples: [
1158
1274
  {
1159
- key: "update-name",
1160
- input: { workflowId: "def-123", name: "New Employee Onboarding" },
1161
- output: { id: "def-123", name: "New Employee Onboarding" }
1275
+ key: "complete-task",
1276
+ input: {
1277
+ instanceId: "inst-456",
1278
+ action: "complete",
1279
+ data: { approved: true }
1280
+ },
1281
+ output: { success: true, nextStep: "notify-hr" }
1162
1282
  }
1163
1283
  ]
1164
1284
  }
1165
1285
  });
1166
- var AddStepContract = defineCommand2({
1286
+ var PauseWorkflowContract = defineCommand2({
1167
1287
  meta: {
1168
- key: "workflow.step.add",
1288
+ key: "workflow.instance.pause",
1169
1289
  version: "1.0.0",
1170
1290
  stability: "stable",
1171
1291
  owners: [...OWNERS2],
1172
- tags: ["workflow", "step", "add"],
1173
- description: "Add a step to a workflow definition.",
1174
- goal: "Build workflow structure step by step.",
1175
- context: "Workflow designer."
1292
+ tags: ["workflow", "instance", "pause"],
1293
+ description: "Pause a running workflow instance.",
1294
+ goal: "Temporarily halt workflow execution.",
1295
+ context: "Administrative action, emergency stop."
1176
1296
  },
1177
1297
  io: {
1178
- input: AddStepInputModel,
1179
- output: WorkflowStepModel
1298
+ input: defineSchemaModel6({
1299
+ name: "PauseResumeInput",
1300
+ fields: {
1301
+ instanceId: {
1302
+ type: ScalarTypeEnum6.String_unsecure(),
1303
+ isOptional: false
1304
+ },
1305
+ reason: { type: ScalarTypeEnum6.String_unsecure(), isOptional: true }
1306
+ }
1307
+ }),
1308
+ output: WorkflowInstanceModel
1180
1309
  },
1181
1310
  policy: { auth: "user" },
1182
1311
  sideEffects: {
1183
1312
  emits: [
1184
1313
  {
1185
- key: "workflow.step.added",
1314
+ key: "workflow.instance.paused",
1186
1315
  version: "1.0.0",
1187
- when: "Step is added",
1188
- payload: WorkflowStepModel
1316
+ when: "Workflow is paused",
1317
+ payload: WorkflowInstanceModel
1189
1318
  }
1190
1319
  ],
1191
- audit: ["workflow.step.added"]
1320
+ audit: ["workflow.instance.paused"]
1192
1321
  },
1193
1322
  acceptance: {
1194
1323
  scenarios: [
1195
1324
  {
1196
- key: "add-step-happy-path",
1197
- given: ["Workflow definition exists"],
1198
- when: ["User adds a step"],
1199
- then: ["Step is added", "StepAdded event is emitted"]
1325
+ key: "pause-workflow-happy-path",
1326
+ given: ["Workflow is running"],
1327
+ when: ["Admin pauses workflow"],
1328
+ then: ["Instance status becomes PAUSED"]
1200
1329
  }
1201
1330
  ],
1202
1331
  examples: [
1203
1332
  {
1204
- key: "add-approval-step",
1205
- input: {
1206
- workflowId: "def-123",
1207
- stepKey: "approve-contract",
1208
- type: "approval"
1333
+ key: "pause-maintenance",
1334
+ input: { instanceId: "inst-456", reason: "System maintenance" },
1335
+ output: { id: "inst-456", status: "paused" }
1336
+ }
1337
+ ]
1338
+ }
1339
+ });
1340
+ var ResumeWorkflowContract = defineCommand2({
1341
+ meta: {
1342
+ key: "workflow.instance.resume",
1343
+ version: "1.0.0",
1344
+ stability: "stable",
1345
+ owners: [...OWNERS2],
1346
+ tags: ["workflow", "instance", "resume"],
1347
+ description: "Resume a paused workflow instance.",
1348
+ goal: "Continue workflow execution.",
1349
+ context: "Administrative action."
1350
+ },
1351
+ io: {
1352
+ input: defineSchemaModel6({
1353
+ name: "PauseResumeInput",
1354
+ fields: {
1355
+ instanceId: {
1356
+ type: ScalarTypeEnum6.String_unsecure(),
1357
+ isOptional: false
1209
1358
  },
1210
- output: { id: "step-456", key: "approve-contract" }
1359
+ reason: { type: ScalarTypeEnum6.String_unsecure(), isOptional: true }
1360
+ }
1361
+ }),
1362
+ output: WorkflowInstanceModel
1363
+ },
1364
+ policy: { auth: "user" },
1365
+ sideEffects: {
1366
+ emits: [
1367
+ {
1368
+ key: "workflow.instance.resumed",
1369
+ version: "1.0.0",
1370
+ when: "Workflow is resumed",
1371
+ payload: WorkflowInstanceModel
1372
+ }
1373
+ ],
1374
+ audit: ["workflow.instance.resumed"]
1375
+ },
1376
+ acceptance: {
1377
+ scenarios: [
1378
+ {
1379
+ key: "resume-workflow-happy-path",
1380
+ given: ["Workflow is paused"],
1381
+ when: ["Admin resumes workflow"],
1382
+ then: ["Instance status becomes RUNNING"]
1383
+ }
1384
+ ],
1385
+ examples: [
1386
+ {
1387
+ key: "resume-normal",
1388
+ input: { instanceId: "inst-456", reason: "Issue resolved" },
1389
+ output: { id: "inst-456", status: "running" }
1211
1390
  }
1212
1391
  ]
1213
1392
  }
1214
1393
  });
1215
- var PublishWorkflowContract = defineCommand2({
1394
+ var CancelWorkflowContract = defineCommand2({
1216
1395
  meta: {
1217
- key: "workflow.definition.publish",
1396
+ key: "workflow.instance.cancel",
1218
1397
  version: "1.0.0",
1219
1398
  stability: "stable",
1220
1399
  owners: [...OWNERS2],
1221
- tags: ["workflow", "definition", "publish"],
1222
- description: "Publish a workflow definition to make it available for use.",
1223
- goal: "Activate workflow for production use.",
1224
- context: "Workflow designer, deployment."
1400
+ tags: ["workflow", "instance", "cancel"],
1401
+ description: "Cancel a workflow instance.",
1402
+ goal: "Terminate workflow without completion.",
1403
+ context: "User request, system cancellation."
1225
1404
  },
1226
1405
  io: {
1227
- input: defineSchemaModel5({
1228
- name: "PublishWorkflowInput",
1406
+ input: defineSchemaModel6({
1407
+ name: "CancelWorkflowInput",
1229
1408
  fields: {
1230
- workflowId: {
1231
- type: ScalarTypeEnum5.String_unsecure(),
1409
+ instanceId: {
1410
+ type: ScalarTypeEnum6.String_unsecure(),
1411
+ isOptional: false
1412
+ },
1413
+ reason: {
1414
+ type: ScalarTypeEnum6.String_unsecure(),
1232
1415
  isOptional: false
1233
1416
  }
1234
1417
  }
1235
1418
  }),
1236
- output: WorkflowDefinitionModel
1419
+ output: WorkflowInstanceModel
1237
1420
  },
1238
1421
  policy: { auth: "user" },
1239
1422
  sideEffects: {
1240
1423
  emits: [
1241
1424
  {
1242
- key: "workflow.definition.published",
1425
+ key: "workflow.instance.cancelled",
1243
1426
  version: "1.0.0",
1244
- when: "Workflow is published",
1245
- payload: WorkflowDefinitionModel
1427
+ when: "Workflow is cancelled",
1428
+ payload: WorkflowInstanceModel
1246
1429
  }
1247
1430
  ],
1248
- audit: ["workflow.definition.published"]
1431
+ audit: ["workflow.instance.cancelled"]
1249
1432
  },
1250
1433
  acceptance: {
1251
1434
  scenarios: [
1252
1435
  {
1253
- key: "publish-workflow-happy-path",
1254
- given: ["Workflow definition is valid"],
1255
- when: ["User publishes workflow"],
1256
- then: ["Workflow becomes active", "WorkflowPublished event is emitted"]
1436
+ key: "cancel-workflow-happy-path",
1437
+ given: ["Workflow is running"],
1438
+ when: ["User cancels workflow"],
1439
+ then: ["Instance status becomes CANCELLED"]
1257
1440
  }
1258
1441
  ],
1259
1442
  examples: [
1260
1443
  {
1261
- key: "publish-onboarding",
1262
- input: { workflowId: "def-123" },
1263
- output: { id: "def-123", status: "published" }
1444
+ key: "cancel-mistake",
1445
+ input: { instanceId: "inst-456", reason: "Created by mistake" },
1446
+ output: { id: "inst-456", status: "cancelled" }
1264
1447
  }
1265
1448
  ]
1266
1449
  }
1267
1450
  });
1268
- var ListWorkflowsContract = defineQuery2({
1451
+ var ListInstancesContract = defineQuery2({
1269
1452
  meta: {
1270
- key: "workflow.definition.list",
1453
+ key: "workflow.instance.list",
1271
1454
  version: "1.0.0",
1272
1455
  stability: "stable",
1273
1456
  owners: [...OWNERS2],
1274
- tags: ["workflow", "definition", "list"],
1275
- description: "List workflow definitions with filtering.",
1276
- goal: "Browse and search available workflows.",
1277
- context: "Workflow list, search."
1457
+ tags: ["workflow", "instance", "list"],
1458
+ description: "List workflow instances with filtering.",
1459
+ goal: "Browse and search running workflows.",
1460
+ context: "Dashboard, monitoring."
1278
1461
  },
1279
1462
  io: {
1280
- input: defineSchemaModel5({
1281
- name: "ListWorkflowsInput",
1463
+ input: defineSchemaModel6({
1464
+ name: "ListInstancesInput",
1282
1465
  fields: {
1283
- status: { type: WorkflowStatusEnum, isOptional: true },
1284
- search: { type: ScalarTypeEnum5.String_unsecure(), isOptional: true },
1466
+ workflowKey: {
1467
+ type: ScalarTypeEnum6.String_unsecure(),
1468
+ isOptional: true
1469
+ },
1470
+ status: { type: InstanceStatusEnum, isOptional: true },
1471
+ referenceType: {
1472
+ type: ScalarTypeEnum6.String_unsecure(),
1473
+ isOptional: true
1474
+ },
1475
+ referenceId: {
1476
+ type: ScalarTypeEnum6.String_unsecure(),
1477
+ isOptional: true
1478
+ },
1479
+ triggeredBy: {
1480
+ type: ScalarTypeEnum6.String_unsecure(),
1481
+ isOptional: true
1482
+ },
1285
1483
  limit: {
1286
- type: ScalarTypeEnum5.Int_unsecure(),
1484
+ type: ScalarTypeEnum6.Int_unsecure(),
1287
1485
  isOptional: true,
1288
1486
  defaultValue: 20
1289
1487
  },
1290
1488
  offset: {
1291
- type: ScalarTypeEnum5.Int_unsecure(),
1489
+ type: ScalarTypeEnum6.Int_unsecure(),
1292
1490
  isOptional: true,
1293
1491
  defaultValue: 0
1294
1492
  }
1295
1493
  }
1296
1494
  }),
1297
- output: defineSchemaModel5({
1298
- name: "ListWorkflowsOutput",
1495
+ output: defineSchemaModel6({
1496
+ name: "ListInstancesOutput",
1299
1497
  fields: {
1300
- workflows: {
1301
- type: WorkflowDefinitionModel,
1498
+ instances: {
1499
+ type: WorkflowInstanceModel,
1302
1500
  isArray: true,
1303
1501
  isOptional: false
1304
1502
  },
1305
- total: { type: ScalarTypeEnum5.Int_unsecure(), isOptional: false }
1503
+ total: { type: ScalarTypeEnum6.Int_unsecure(), isOptional: false }
1306
1504
  }
1307
1505
  })
1308
1506
  },
@@ -1310,1333 +1508,984 @@ var ListWorkflowsContract = defineQuery2({
1310
1508
  acceptance: {
1311
1509
  scenarios: [
1312
1510
  {
1313
- key: "list-workflows-happy-path",
1314
- given: ["Workflow definitions exist"],
1315
- when: ["User lists workflows"],
1316
- then: ["List of workflows is returned"]
1511
+ key: "list-instances-happy-path",
1512
+ given: ["Workflow instances exist"],
1513
+ when: ["User lists instances"],
1514
+ then: ["List of instances is returned"]
1317
1515
  }
1318
1516
  ],
1319
1517
  examples: [
1320
1518
  {
1321
- key: "list-all",
1322
- input: { limit: 10 },
1323
- output: { workflows: [], total: 5 }
1519
+ key: "list-running",
1520
+ input: { status: "running", limit: 10 },
1521
+ output: { instances: [], total: 5 }
1324
1522
  }
1325
1523
  ]
1326
1524
  }
1327
1525
  });
1328
- var GetWorkflowContract = defineQuery2({
1526
+ var GetInstanceContract = defineQuery2({
1329
1527
  meta: {
1330
- key: "workflow.definition.get",
1528
+ key: "workflow.instance.get",
1331
1529
  version: "1.0.0",
1332
1530
  stability: "stable",
1333
1531
  owners: [...OWNERS2],
1334
- tags: ["workflow", "definition", "get"],
1335
- description: "Get a workflow definition with all steps.",
1336
- goal: "View workflow details.",
1337
- context: "Workflow designer, detail view."
1532
+ tags: ["workflow", "instance", "get"],
1533
+ description: "Get a workflow instance with details.",
1534
+ goal: "View workflow instance details.",
1535
+ context: "Instance detail view."
1338
1536
  },
1339
1537
  io: {
1340
- input: defineSchemaModel5({
1341
- name: "GetWorkflowInput",
1538
+ input: defineSchemaModel6({
1539
+ name: "GetInstanceInput",
1342
1540
  fields: {
1343
- workflowId: {
1344
- type: ScalarTypeEnum5.String_unsecure(),
1541
+ instanceId: {
1542
+ type: ScalarTypeEnum6.String_unsecure(),
1345
1543
  isOptional: false
1346
1544
  }
1347
1545
  }
1348
1546
  }),
1349
- output: WorkflowDefinitionModel
1547
+ output: WorkflowInstanceModel
1350
1548
  },
1351
1549
  policy: { auth: "user" },
1352
1550
  acceptance: {
1353
1551
  scenarios: [
1354
1552
  {
1355
- key: "get-workflow-happy-path",
1356
- given: ["Workflow definition exists"],
1357
- when: ["User requests workflow details"],
1358
- then: ["Workflow details are returned"]
1553
+ key: "get-instance-happy-path",
1554
+ given: ["Instance exists"],
1555
+ when: ["User requests instance details"],
1556
+ then: ["Instance details are returned"]
1359
1557
  }
1360
1558
  ],
1361
1559
  examples: [
1362
1560
  {
1363
1561
  key: "get-details",
1364
- input: { workflowId: "def-123" },
1365
- output: { id: "def-123", name: "Employee Onboarding" }
1562
+ input: { instanceId: "inst-456" },
1563
+ output: { id: "inst-456", workflowKey: "onboarding-v1" }
1366
1564
  }
1367
1565
  ]
1368
1566
  }
1369
1567
  });
1370
-
1371
- // src/workflow/workflow.event.ts
1372
- import { defineEvent as defineEvent2 } from "@contractspec/lib.contracts-spec";
1373
- import { ScalarTypeEnum as ScalarTypeEnum6, defineSchemaModel as defineSchemaModel6 } from "@contractspec/lib.schema";
1374
- var WorkflowDefinitionPayload = defineSchemaModel6({
1375
- name: "WorkflowDefinitionEventPayload",
1376
- description: "Payload for workflow definition events",
1377
- fields: {
1378
- workflowId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
1379
- key: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
1380
- name: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
1381
- version: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
1382
- organizationId: {
1383
- type: ScalarTypeEnum6.String_unsecure(),
1384
- isOptional: false
1385
- },
1386
- createdBy: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
1387
- timestamp: { type: ScalarTypeEnum6.DateTime(), isOptional: false }
1388
- }
1389
- });
1390
- var StepAddedPayload = defineSchemaModel6({
1391
- name: "StepAddedEventPayload",
1392
- description: "Payload when a step is added",
1393
- fields: {
1394
- stepId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
1395
- workflowId: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
1396
- stepKey: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
1397
- stepType: { type: ScalarTypeEnum6.String_unsecure(), isOptional: false },
1398
- position: { type: ScalarTypeEnum6.Int_unsecure(), isOptional: false },
1399
- timestamp: { type: ScalarTypeEnum6.DateTime(), isOptional: false }
1400
- }
1401
- });
1402
- var WorkflowCreatedEvent = defineEvent2({
1403
- meta: {
1404
- key: "workflow.definition.created",
1405
- version: "1.0.0",
1406
- description: "A new workflow definition has been created.",
1407
- stability: "stable",
1408
- owners: ["@workflow-team"],
1409
- tags: ["workflow", "definition", "created"]
1410
- },
1411
- payload: WorkflowDefinitionPayload
1412
- });
1413
- var WorkflowUpdatedEvent = defineEvent2({
1414
- meta: {
1415
- key: "workflow.definition.updated",
1416
- version: "1.0.0",
1417
- description: "A workflow definition has been updated.",
1418
- stability: "stable",
1419
- owners: ["@workflow-team"],
1420
- tags: ["workflow", "definition", "updated"]
1421
- },
1422
- payload: WorkflowDefinitionPayload
1423
- });
1424
- var WorkflowPublishedEvent = defineEvent2({
1425
- meta: {
1426
- key: "workflow.definition.published",
1427
- version: "1.0.0",
1428
- description: "A workflow definition has been published and is now active.",
1429
- stability: "stable",
1430
- owners: ["@workflow-team"],
1431
- tags: ["workflow", "definition", "published"]
1432
- },
1433
- payload: WorkflowDefinitionPayload
1434
- });
1435
- var StepAddedEvent = defineEvent2({
1436
- meta: {
1437
- key: "workflow.step.added",
1438
- version: "1.0.0",
1439
- description: "A step has been added to a workflow definition.",
1440
- stability: "stable",
1441
- owners: ["@workflow-team"],
1442
- tags: ["workflow", "step", "added"]
1443
- },
1444
- payload: StepAddedPayload
1445
- });
1446
- // src/instance/instance.enum.ts
1568
+ // src/workflow/workflow.enum.ts
1447
1569
  import { defineEnum as defineEnum3 } from "@contractspec/lib.schema";
1448
- var InstanceStatusEnum = defineEnum3("InstanceStatus", [
1449
- "PENDING",
1450
- "RUNNING",
1451
- "WAITING",
1452
- "PAUSED",
1453
- "COMPLETED",
1454
- "CANCELLED",
1455
- "FAILED",
1456
- "TIMEOUT"
1570
+ var WorkflowStatusEnum = defineEnum3("WorkflowStatus", [
1571
+ "DRAFT",
1572
+ "ACTIVE",
1573
+ "DEPRECATED",
1574
+ "ARCHIVED"
1575
+ ]);
1576
+ var TriggerTypeEnum = defineEnum3("WorkflowTriggerType", [
1577
+ "MANUAL",
1578
+ "EVENT",
1579
+ "SCHEDULED",
1580
+ "API"
1581
+ ]);
1582
+ var StepTypeEnum = defineEnum3("StepType", [
1583
+ "START",
1584
+ "APPROVAL",
1585
+ "TASK",
1586
+ "CONDITION",
1587
+ "PARALLEL",
1588
+ "WAIT",
1589
+ "ACTION",
1590
+ "END"
1591
+ ]);
1592
+ var ApprovalModeEnum = defineEnum3("ApprovalMode", [
1593
+ "ANY",
1594
+ "ALL",
1595
+ "MAJORITY",
1596
+ "SEQUENTIAL"
1457
1597
  ]);
1458
1598
 
1459
- // src/instance/instance.schema.ts
1599
+ // src/workflow/workflow.schema.ts
1460
1600
  import { defineSchemaModel as defineSchemaModel7, ScalarTypeEnum as ScalarTypeEnum7 } from "@contractspec/lib.schema";
1461
- var WorkflowInstanceModel = defineSchemaModel7({
1462
- name: "WorkflowInstanceModel",
1463
- description: "A running workflow instance",
1601
+ var WorkflowStepModel = defineSchemaModel7({
1602
+ name: "WorkflowStepModel",
1603
+ description: "A step in a workflow definition",
1464
1604
  fields: {
1465
1605
  id: { type: ScalarTypeEnum7.String_unsecure(), isOptional: false },
1466
- workflowDefinitionId: {
1606
+ key: { type: ScalarTypeEnum7.String_unsecure(), isOptional: false },
1607
+ name: { type: ScalarTypeEnum7.String_unsecure(), isOptional: false },
1608
+ description: { type: ScalarTypeEnum7.String_unsecure(), isOptional: true },
1609
+ type: { type: StepTypeEnum, isOptional: false },
1610
+ position: { type: ScalarTypeEnum7.Int_unsecure(), isOptional: false },
1611
+ transitions: { type: ScalarTypeEnum7.JSON(), isOptional: false },
1612
+ approvalMode: { type: ApprovalModeEnum, isOptional: true },
1613
+ approverRoles: {
1467
1614
  type: ScalarTypeEnum7.String_unsecure(),
1468
- isOptional: false
1469
- },
1470
- referenceId: { type: ScalarTypeEnum7.String_unsecure(), isOptional: true },
1471
- referenceType: {
1615
+ isArray: true,
1616
+ isOptional: true
1617
+ }
1618
+ }
1619
+ });
1620
+ var WorkflowDefinitionModel = defineSchemaModel7({
1621
+ name: "WorkflowDefinitionModel",
1622
+ description: "A workflow definition",
1623
+ fields: {
1624
+ id: { type: ScalarTypeEnum7.String_unsecure(), isOptional: false },
1625
+ name: { type: ScalarTypeEnum7.String_unsecure(), isOptional: false },
1626
+ key: { type: ScalarTypeEnum7.String_unsecure(), isOptional: false },
1627
+ description: { type: ScalarTypeEnum7.String_unsecure(), isOptional: true },
1628
+ version: { type: ScalarTypeEnum7.String_unsecure(), isOptional: false },
1629
+ status: { type: WorkflowStatusEnum, isOptional: false },
1630
+ triggerType: { type: TriggerTypeEnum, isOptional: false },
1631
+ initialStepId: {
1472
1632
  type: ScalarTypeEnum7.String_unsecure(),
1473
1633
  isOptional: true
1474
1634
  },
1475
- status: { type: InstanceStatusEnum, isOptional: false },
1476
- currentStepId: {
1635
+ featureFlagKey: {
1477
1636
  type: ScalarTypeEnum7.String_unsecure(),
1478
1637
  isOptional: true
1479
1638
  },
1480
- contextData: { type: ScalarTypeEnum7.JSON(), isOptional: true },
1481
- triggeredBy: { type: ScalarTypeEnum7.String_unsecure(), isOptional: false },
1482
1639
  organizationId: {
1483
1640
  type: ScalarTypeEnum7.String_unsecure(),
1484
1641
  isOptional: false
1485
1642
  },
1486
- priority: { type: ScalarTypeEnum7.Int_unsecure(), isOptional: false },
1487
- dueAt: { type: ScalarTypeEnum7.DateTime(), isOptional: true },
1488
- outcome: { type: ScalarTypeEnum7.String_unsecure(), isOptional: true },
1489
- resultData: { type: ScalarTypeEnum7.JSON(), isOptional: true },
1490
- errorMessage: {
1491
- type: ScalarTypeEnum7.String_unsecure(),
1492
- isOptional: true
1493
- },
1494
1643
  createdAt: { type: ScalarTypeEnum7.DateTime(), isOptional: false },
1495
- startedAt: { type: ScalarTypeEnum7.DateTime(), isOptional: true },
1496
- completedAt: { type: ScalarTypeEnum7.DateTime(), isOptional: true }
1644
+ updatedAt: { type: ScalarTypeEnum7.DateTime(), isOptional: false },
1645
+ steps: { type: WorkflowStepModel, isArray: true, isOptional: true }
1497
1646
  }
1498
1647
  });
1499
- var StartWorkflowInputModel = defineSchemaModel7({
1500
- name: "StartWorkflowInput",
1501
- description: "Input for starting a workflow",
1648
+ var CreateWorkflowInputModel = defineSchemaModel7({
1649
+ name: "CreateWorkflowInput",
1650
+ description: "Input for creating a workflow definition",
1502
1651
  fields: {
1503
- workflowKey: { type: ScalarTypeEnum7.NonEmptyString(), isOptional: false },
1504
- contextData: { type: ScalarTypeEnum7.JSON(), isOptional: true },
1505
- referenceId: { type: ScalarTypeEnum7.String_unsecure(), isOptional: true },
1506
- referenceType: {
1652
+ name: { type: ScalarTypeEnum7.NonEmptyString(), isOptional: false },
1653
+ key: { type: ScalarTypeEnum7.NonEmptyString(), isOptional: false },
1654
+ description: { type: ScalarTypeEnum7.String_unsecure(), isOptional: true },
1655
+ triggerType: { type: TriggerTypeEnum, isOptional: true },
1656
+ triggerConfig: { type: ScalarTypeEnum7.JSON(), isOptional: true },
1657
+ featureFlagKey: {
1507
1658
  type: ScalarTypeEnum7.String_unsecure(),
1508
1659
  isOptional: true
1509
1660
  },
1510
- priority: { type: ScalarTypeEnum7.Int_unsecure(), isOptional: true },
1511
- dueAt: { type: ScalarTypeEnum7.DateTime(), isOptional: true }
1661
+ settings: { type: ScalarTypeEnum7.JSON(), isOptional: true }
1512
1662
  }
1513
1663
  });
1514
- var TransitionInputModel = defineSchemaModel7({
1515
- name: "TransitionInput",
1516
- description: "Input for transitioning a workflow",
1664
+ var UpdateWorkflowInputModel = defineSchemaModel7({
1665
+ name: "UpdateWorkflowInput",
1666
+ description: "Input for updating a workflow definition",
1517
1667
  fields: {
1518
- instanceId: { type: ScalarTypeEnum7.String_unsecure(), isOptional: false },
1519
- action: { type: ScalarTypeEnum7.NonEmptyString(), isOptional: false },
1520
- data: { type: ScalarTypeEnum7.JSON(), isOptional: true },
1521
- comment: { type: ScalarTypeEnum7.String_unsecure(), isOptional: true }
1668
+ workflowId: {
1669
+ type: ScalarTypeEnum7.String_unsecure(),
1670
+ isOptional: false
1671
+ },
1672
+ name: { type: ScalarTypeEnum7.String_unsecure(), isOptional: true },
1673
+ description: { type: ScalarTypeEnum7.String_unsecure(), isOptional: true },
1674
+ triggerType: { type: TriggerTypeEnum, isOptional: true },
1675
+ triggerConfig: { type: ScalarTypeEnum7.JSON(), isOptional: true },
1676
+ featureFlagKey: {
1677
+ type: ScalarTypeEnum7.String_unsecure(),
1678
+ isOptional: true
1679
+ },
1680
+ settings: { type: ScalarTypeEnum7.JSON(), isOptional: true }
1522
1681
  }
1523
1682
  });
1524
- var TransitionResultModel = defineSchemaModel7({
1525
- name: "TransitionResult",
1526
- description: "Result of a workflow transition",
1683
+ var AddStepInputModel = defineSchemaModel7({
1684
+ name: "AddStepInput",
1685
+ description: "Input for adding a step to a workflow",
1527
1686
  fields: {
1528
- success: { type: ScalarTypeEnum7.Boolean(), isOptional: false },
1529
- instance: { type: WorkflowInstanceModel, isOptional: false },
1530
- previousStepKey: {
1687
+ workflowId: {
1688
+ type: ScalarTypeEnum7.String_unsecure(),
1689
+ isOptional: false
1690
+ },
1691
+ key: { type: ScalarTypeEnum7.NonEmptyString(), isOptional: false },
1692
+ name: { type: ScalarTypeEnum7.NonEmptyString(), isOptional: false },
1693
+ description: { type: ScalarTypeEnum7.String_unsecure(), isOptional: true },
1694
+ type: { type: StepTypeEnum, isOptional: false },
1695
+ position: { type: ScalarTypeEnum7.Int_unsecure(), isOptional: true },
1696
+ transitions: { type: ScalarTypeEnum7.JSON(), isOptional: false },
1697
+ approvalMode: { type: ApprovalModeEnum, isOptional: true },
1698
+ approverRoles: {
1531
1699
  type: ScalarTypeEnum7.String_unsecure(),
1700
+ isArray: true,
1532
1701
  isOptional: true
1533
1702
  },
1534
- currentStepKey: {
1703
+ approverUserIds: {
1535
1704
  type: ScalarTypeEnum7.String_unsecure(),
1705
+ isArray: true,
1536
1706
  isOptional: true
1537
1707
  },
1538
- message: { type: ScalarTypeEnum7.String_unsecure(), isOptional: true }
1708
+ timeoutSeconds: { type: ScalarTypeEnum7.Int_unsecure(), isOptional: true },
1709
+ slaSeconds: { type: ScalarTypeEnum7.Int_unsecure(), isOptional: true }
1539
1710
  }
1540
1711
  });
1541
1712
 
1542
- // src/instance/instance.operations.ts
1713
+ // src/presentations/index.ts
1543
1714
  import {
1544
- defineCommand as defineCommand3,
1545
- defineQuery as defineQuery3
1546
- } from "@contractspec/lib.contracts-spec/operations";
1547
- import { defineSchemaModel as defineSchemaModel8, ScalarTypeEnum as ScalarTypeEnum8 } from "@contractspec/lib.schema";
1548
- var OWNERS3 = ["@example.workflow-system"];
1549
- var StartWorkflowContract = defineCommand3({
1715
+ definePresentation,
1716
+ StabilityEnum
1717
+ } from "@contractspec/lib.contracts-spec";
1718
+ var WorkflowDesignerPresentation = definePresentation({
1550
1719
  meta: {
1551
- key: "workflow.instance.start",
1720
+ key: "workflow.designer",
1552
1721
  version: "1.0.0",
1553
- stability: "stable",
1554
- owners: [...OWNERS3],
1555
- tags: ["workflow", "instance", "start"],
1556
- description: "Start a new workflow instance.",
1557
- goal: "Initiate a workflow for a business process.",
1558
- context: "Order creation, request submission, etc."
1722
+ title: "Workflow Designer",
1723
+ description: "Visual workflow designer with drag-and-drop steps",
1724
+ domain: "workflow-system",
1725
+ owners: ["@workflow-team"],
1726
+ tags: ["workflow", "designer", "admin"],
1727
+ stability: StabilityEnum.Experimental,
1728
+ goal: "Building and modifying workflow definitions",
1729
+ context: "Workflow administration and setup"
1559
1730
  },
1560
- io: {
1561
- input: StartWorkflowInputModel,
1562
- output: WorkflowInstanceModel
1731
+ source: {
1732
+ type: "component",
1733
+ framework: "react",
1734
+ componentKey: "WorkflowDesigner",
1735
+ props: WorkflowDefinitionModel
1563
1736
  },
1564
- policy: { auth: "user" },
1565
- sideEffects: {
1566
- emits: [
1567
- {
1568
- key: "workflow.instance.started",
1569
- version: "1.0.0",
1570
- when: "Workflow starts",
1571
- payload: WorkflowInstanceModel
1572
- },
1573
- {
1574
- key: "workflow.step.entered",
1575
- version: "1.0.0",
1576
- when: "First step entered",
1577
- payload: WorkflowInstanceModel
1578
- }
1579
- ],
1580
- audit: ["workflow.instance.started"]
1737
+ targets: ["react"],
1738
+ policy: {
1739
+ flags: ["workflow.designer.enabled"]
1740
+ }
1741
+ });
1742
+ var WorkflowListPresentation = definePresentation({
1743
+ meta: {
1744
+ key: "workflow.definition.viewList",
1745
+ version: "1.0.0",
1746
+ title: "Workflow List",
1747
+ description: "List of workflow definitions with status and actions",
1748
+ domain: "workflow-system",
1749
+ owners: ["@workflow-team"],
1750
+ tags: ["workflow", "list", "admin"],
1751
+ stability: StabilityEnum.Experimental,
1752
+ goal: "Overview of all defined workflows",
1753
+ context: "Workflow management dashboard"
1581
1754
  },
1582
- acceptance: {
1583
- scenarios: [
1584
- {
1585
- key: "start-workflow-happy-path",
1586
- given: ["Workflow definition exists"],
1587
- when: ["User starts workflow"],
1588
- then: ["Instance is created and started"]
1589
- }
1590
- ],
1591
- examples: [
1592
- {
1593
- key: "start-onboarding",
1594
- input: {
1595
- workflowKey: "onboarding-v1",
1596
- context: { employeeId: "emp-123" }
1597
- },
1598
- output: { id: "inst-456", status: "running" }
1599
- }
1600
- ]
1755
+ source: {
1756
+ type: "component",
1757
+ framework: "react",
1758
+ componentKey: "WorkflowDefinitionList",
1759
+ props: WorkflowDefinitionModel
1760
+ },
1761
+ targets: ["react", "markdown"],
1762
+ policy: {
1763
+ flags: ["workflow.enabled"]
1601
1764
  }
1602
1765
  });
1603
- var TransitionWorkflowContract = defineCommand3({
1766
+ var WorkflowDetailPresentation = definePresentation({
1604
1767
  meta: {
1605
- key: "workflow.instance.transition",
1768
+ key: "workflow.definition.detail",
1606
1769
  version: "1.0.0",
1607
- stability: "stable",
1608
- owners: [...OWNERS3],
1609
- tags: ["workflow", "instance", "transition", "state-machine"],
1610
- description: "Transition a workflow instance to the next step.",
1611
- goal: "Move workflow forward based on action.",
1612
- context: "Task completion, approval decisions."
1613
- },
1614
- io: {
1615
- input: TransitionInputModel,
1616
- output: TransitionResultModel
1770
+ title: "Workflow Details",
1771
+ description: "Detailed view of a workflow definition with steps",
1772
+ domain: "workflow-system",
1773
+ owners: ["@workflow-team"],
1774
+ tags: ["workflow", "detail"],
1775
+ stability: StabilityEnum.Experimental,
1776
+ goal: "Viewing technical details of a workflow definition",
1777
+ context: "Workflow inspection and debugging"
1617
1778
  },
1618
- policy: { auth: "user" },
1619
- sideEffects: {
1620
- emits: [
1621
- {
1622
- key: "workflow.step.exited",
1623
- version: "1.0.0",
1624
- when: "Step is exited",
1625
- payload: WorkflowInstanceModel
1626
- },
1627
- {
1628
- key: "workflow.step.entered",
1629
- version: "1.0.0",
1630
- when: "New step is entered",
1631
- payload: WorkflowInstanceModel
1632
- },
1633
- {
1634
- key: "workflow.instance.completed",
1635
- version: "1.0.0",
1636
- when: "Workflow reaches end",
1637
- payload: WorkflowInstanceModel
1638
- }
1639
- ],
1640
- audit: ["workflow.instance.transitioned"]
1779
+ source: {
1780
+ type: "component",
1781
+ framework: "react",
1782
+ componentKey: "WorkflowDefinitionDetail",
1783
+ props: WorkflowDefinitionModel
1641
1784
  },
1642
- acceptance: {
1643
- scenarios: [
1644
- {
1645
- key: "transition-workflow-happy-path",
1646
- given: ["Workflow instance is waiting at step"],
1647
- when: ["User provides input"],
1648
- then: ["Instance moves to next step"]
1649
- }
1650
- ],
1651
- examples: [
1652
- {
1653
- key: "complete-task",
1654
- input: {
1655
- instanceId: "inst-456",
1656
- action: "complete",
1657
- data: { approved: true }
1658
- },
1659
- output: { success: true, nextStep: "notify-hr" }
1660
- }
1661
- ]
1785
+ targets: ["react", "markdown"],
1786
+ policy: {
1787
+ flags: ["workflow.enabled"]
1662
1788
  }
1663
1789
  });
1664
- var PauseWorkflowContract = defineCommand3({
1790
+ var InstanceListPresentation = definePresentation({
1665
1791
  meta: {
1666
- key: "workflow.instance.pause",
1792
+ key: "workflow.instance.viewList",
1667
1793
  version: "1.0.0",
1668
- stability: "stable",
1669
- owners: [...OWNERS3],
1670
- tags: ["workflow", "instance", "pause"],
1671
- description: "Pause a running workflow instance.",
1672
- goal: "Temporarily halt workflow execution.",
1673
- context: "Administrative action, emergency stop."
1674
- },
1675
- io: {
1676
- input: defineSchemaModel8({
1677
- name: "PauseResumeInput",
1678
- fields: {
1679
- instanceId: {
1680
- type: ScalarTypeEnum8.String_unsecure(),
1681
- isOptional: false
1682
- },
1683
- reason: { type: ScalarTypeEnum8.String_unsecure(), isOptional: true }
1684
- }
1685
- }),
1686
- output: WorkflowInstanceModel
1794
+ title: "Instance List",
1795
+ description: "List of workflow instances with status and progress",
1796
+ domain: "workflow-system",
1797
+ owners: ["@workflow-team"],
1798
+ tags: ["workflow", "instance", "list"],
1799
+ stability: StabilityEnum.Experimental,
1800
+ goal: "Monitoring active and past workflow executions",
1801
+ context: "Operations monitoring"
1687
1802
  },
1688
- policy: { auth: "user" },
1689
- sideEffects: {
1690
- emits: [
1691
- {
1692
- key: "workflow.instance.paused",
1693
- version: "1.0.0",
1694
- when: "Workflow is paused",
1695
- payload: WorkflowInstanceModel
1696
- }
1697
- ],
1698
- audit: ["workflow.instance.paused"]
1803
+ source: {
1804
+ type: "component",
1805
+ framework: "react",
1806
+ componentKey: "WorkflowInstanceList",
1807
+ props: WorkflowInstanceModel
1699
1808
  },
1700
- acceptance: {
1701
- scenarios: [
1702
- {
1703
- key: "pause-workflow-happy-path",
1704
- given: ["Workflow is running"],
1705
- when: ["Admin pauses workflow"],
1706
- then: ["Instance status becomes PAUSED"]
1707
- }
1708
- ],
1709
- examples: [
1710
- {
1711
- key: "pause-maintenance",
1712
- input: { instanceId: "inst-456", reason: "System maintenance" },
1713
- output: { id: "inst-456", status: "paused" }
1714
- }
1715
- ]
1809
+ targets: ["react", "markdown"],
1810
+ policy: {
1811
+ flags: ["workflow.enabled"]
1716
1812
  }
1717
1813
  });
1718
- var ResumeWorkflowContract = defineCommand3({
1814
+ var InstanceDetailPresentation = definePresentation({
1719
1815
  meta: {
1720
- key: "workflow.instance.resume",
1816
+ key: "workflow.instance.detail",
1721
1817
  version: "1.0.0",
1722
- stability: "stable",
1723
- owners: [...OWNERS3],
1724
- tags: ["workflow", "instance", "resume"],
1725
- description: "Resume a paused workflow instance.",
1726
- goal: "Continue workflow execution.",
1727
- context: "Administrative action."
1728
- },
1729
- io: {
1730
- input: defineSchemaModel8({
1731
- name: "PauseResumeInput",
1732
- fields: {
1733
- instanceId: {
1734
- type: ScalarTypeEnum8.String_unsecure(),
1735
- isOptional: false
1736
- },
1737
- reason: { type: ScalarTypeEnum8.String_unsecure(), isOptional: true }
1738
- }
1739
- }),
1740
- output: WorkflowInstanceModel
1818
+ title: "Instance Details",
1819
+ description: "Detailed view of a workflow instance with step timeline",
1820
+ domain: "workflow-system",
1821
+ owners: ["@workflow-team"],
1822
+ tags: ["workflow", "instance", "detail", "timeline"],
1823
+ stability: StabilityEnum.Experimental,
1824
+ goal: "Detailed inspection of a specific workflow instance",
1825
+ context: "Case management and troubleshooting"
1741
1826
  },
1742
- policy: { auth: "user" },
1743
- sideEffects: {
1744
- emits: [
1745
- {
1746
- key: "workflow.instance.resumed",
1747
- version: "1.0.0",
1748
- when: "Workflow is resumed",
1749
- payload: WorkflowInstanceModel
1750
- }
1751
- ],
1752
- audit: ["workflow.instance.resumed"]
1827
+ source: {
1828
+ type: "component",
1829
+ framework: "react",
1830
+ componentKey: "WorkflowInstanceDetail",
1831
+ props: WorkflowInstanceModel
1753
1832
  },
1754
- acceptance: {
1755
- scenarios: [
1756
- {
1757
- key: "resume-workflow-happy-path",
1758
- given: ["Workflow is paused"],
1759
- when: ["Admin resumes workflow"],
1760
- then: ["Instance status becomes RUNNING"]
1761
- }
1762
- ],
1763
- examples: [
1764
- {
1765
- key: "resume-normal",
1766
- input: { instanceId: "inst-456", reason: "Issue resolved" },
1767
- output: { id: "inst-456", status: "running" }
1768
- }
1769
- ]
1833
+ targets: ["react", "markdown"],
1834
+ policy: {
1835
+ flags: ["workflow.enabled"]
1770
1836
  }
1771
1837
  });
1772
- var CancelWorkflowContract = defineCommand3({
1838
+ var ProgressTrackerPresentation = definePresentation({
1773
1839
  meta: {
1774
- key: "workflow.instance.cancel",
1840
+ key: "workflow.instance.progress",
1775
1841
  version: "1.0.0",
1776
- stability: "stable",
1777
- owners: [...OWNERS3],
1778
- tags: ["workflow", "instance", "cancel"],
1779
- description: "Cancel a workflow instance.",
1780
- goal: "Terminate workflow without completion.",
1781
- context: "User request, system cancellation."
1842
+ title: "Progress Tracker",
1843
+ description: "Visual progress tracker showing current step in workflow",
1844
+ domain: "workflow-system",
1845
+ owners: ["@workflow-team"],
1846
+ tags: ["workflow", "progress", "widget"],
1847
+ stability: StabilityEnum.Experimental,
1848
+ goal: "Quick view of current progress for a workflow",
1849
+ context: "Embedded progress indicator in entity views"
1782
1850
  },
1783
- io: {
1784
- input: defineSchemaModel8({
1785
- name: "CancelWorkflowInput",
1786
- fields: {
1787
- instanceId: {
1788
- type: ScalarTypeEnum8.String_unsecure(),
1789
- isOptional: false
1790
- },
1791
- reason: {
1792
- type: ScalarTypeEnum8.String_unsecure(),
1793
- isOptional: false
1794
- }
1795
- }
1796
- }),
1797
- output: WorkflowInstanceModel
1851
+ source: {
1852
+ type: "component",
1853
+ framework: "react",
1854
+ componentKey: "WorkflowProgressTracker",
1855
+ props: WorkflowInstanceModel
1798
1856
  },
1799
- policy: { auth: "user" },
1800
- sideEffects: {
1801
- emits: [
1802
- {
1803
- key: "workflow.instance.cancelled",
1804
- version: "1.0.0",
1805
- when: "Workflow is cancelled",
1806
- payload: WorkflowInstanceModel
1807
- }
1808
- ],
1809
- audit: ["workflow.instance.cancelled"]
1810
- },
1811
- acceptance: {
1812
- scenarios: [
1813
- {
1814
- key: "cancel-workflow-happy-path",
1815
- given: ["Workflow is running"],
1816
- when: ["User cancels workflow"],
1817
- then: ["Instance status becomes CANCELLED"]
1818
- }
1819
- ],
1820
- examples: [
1821
- {
1822
- key: "cancel-mistake",
1823
- input: { instanceId: "inst-456", reason: "Created by mistake" },
1824
- output: { id: "inst-456", status: "cancelled" }
1825
- }
1826
- ]
1857
+ targets: ["react"],
1858
+ policy: {
1859
+ flags: ["workflow.enabled"]
1827
1860
  }
1828
1861
  });
1829
- var ListInstancesContract = defineQuery3({
1862
+ var ApprovalInboxPresentation = definePresentation({
1830
1863
  meta: {
1831
- key: "workflow.instance.list",
1864
+ key: "workflow.approval.inbox",
1832
1865
  version: "1.0.0",
1833
- stability: "stable",
1834
- owners: [...OWNERS3],
1835
- tags: ["workflow", "instance", "list"],
1836
- description: "List workflow instances with filtering.",
1837
- goal: "Browse and search running workflows.",
1838
- context: "Dashboard, monitoring."
1866
+ title: "Approval Inbox",
1867
+ description: "Inbox showing pending approval requests for current user",
1868
+ domain: "workflow-system",
1869
+ owners: ["@workflow-team"],
1870
+ tags: ["workflow", "approval", "inbox"],
1871
+ stability: StabilityEnum.Experimental,
1872
+ goal: "Managing personal workload of approval requests",
1873
+ context: "Personal task management"
1839
1874
  },
1840
- io: {
1841
- input: defineSchemaModel8({
1842
- name: "ListInstancesInput",
1843
- fields: {
1844
- workflowKey: {
1845
- type: ScalarTypeEnum8.String_unsecure(),
1846
- isOptional: true
1847
- },
1848
- status: { type: InstanceStatusEnum, isOptional: true },
1849
- referenceType: {
1850
- type: ScalarTypeEnum8.String_unsecure(),
1851
- isOptional: true
1852
- },
1853
- referenceId: {
1854
- type: ScalarTypeEnum8.String_unsecure(),
1855
- isOptional: true
1856
- },
1857
- triggeredBy: {
1858
- type: ScalarTypeEnum8.String_unsecure(),
1859
- isOptional: true
1860
- },
1861
- limit: {
1862
- type: ScalarTypeEnum8.Int_unsecure(),
1863
- isOptional: true,
1864
- defaultValue: 20
1865
- },
1866
- offset: {
1867
- type: ScalarTypeEnum8.Int_unsecure(),
1868
- isOptional: true,
1869
- defaultValue: 0
1870
- }
1871
- }
1872
- }),
1873
- output: defineSchemaModel8({
1874
- name: "ListInstancesOutput",
1875
- fields: {
1876
- instances: {
1877
- type: WorkflowInstanceModel,
1878
- isArray: true,
1879
- isOptional: false
1880
- },
1881
- total: { type: ScalarTypeEnum8.Int_unsecure(), isOptional: false }
1882
- }
1883
- })
1875
+ source: {
1876
+ type: "component",
1877
+ framework: "react",
1878
+ componentKey: "ApprovalInbox",
1879
+ props: ApprovalRequestModel
1884
1880
  },
1885
- policy: { auth: "user" },
1886
- acceptance: {
1887
- scenarios: [
1888
- {
1889
- key: "list-instances-happy-path",
1890
- given: ["Workflow instances exist"],
1891
- when: ["User lists instances"],
1892
- then: ["List of instances is returned"]
1893
- }
1894
- ],
1895
- examples: [
1896
- {
1897
- key: "list-running",
1898
- input: { status: "running", limit: 10 },
1899
- output: { instances: [], total: 5 }
1900
- }
1901
- ]
1881
+ targets: ["react", "markdown"],
1882
+ policy: {
1883
+ flags: ["workflow.approvals.enabled"]
1902
1884
  }
1903
1885
  });
1904
- var GetInstanceContract = defineQuery3({
1886
+ var ApprovalDetailPresentation = definePresentation({
1905
1887
  meta: {
1906
- key: "workflow.instance.get",
1888
+ key: "workflow.approval.detail",
1907
1889
  version: "1.0.0",
1908
- stability: "stable",
1909
- owners: [...OWNERS3],
1910
- tags: ["workflow", "instance", "get"],
1911
- description: "Get a workflow instance with details.",
1912
- goal: "View workflow instance details.",
1913
- context: "Instance detail view."
1890
+ title: "Approval Details",
1891
+ description: "Detailed approval request view with context and actions",
1892
+ domain: "workflow-system",
1893
+ owners: ["@workflow-team"],
1894
+ tags: ["workflow", "approval", "detail"],
1895
+ stability: StabilityEnum.Experimental,
1896
+ goal: "Decision support for an approval request",
1897
+ context: "Specific approval action"
1914
1898
  },
1915
- io: {
1916
- input: defineSchemaModel8({
1917
- name: "GetInstanceInput",
1918
- fields: {
1919
- instanceId: {
1920
- type: ScalarTypeEnum8.String_unsecure(),
1921
- isOptional: false
1922
- }
1923
- }
1924
- }),
1925
- output: WorkflowInstanceModel
1899
+ source: {
1900
+ type: "component",
1901
+ framework: "react",
1902
+ componentKey: "ApprovalRequestDetail",
1903
+ props: ApprovalRequestModel
1926
1904
  },
1927
- policy: { auth: "user" },
1928
- acceptance: {
1929
- scenarios: [
1930
- {
1931
- key: "get-instance-happy-path",
1932
- given: ["Instance exists"],
1933
- when: ["User requests instance details"],
1934
- then: ["Instance details are returned"]
1935
- }
1936
- ],
1937
- examples: [
1938
- {
1939
- key: "get-details",
1940
- input: { instanceId: "inst-456" },
1941
- output: { id: "inst-456", workflowKey: "onboarding-v1" }
1942
- }
1943
- ]
1944
- }
1945
- });
1946
-
1947
- // src/instance/instance.event.ts
1948
- import { defineEvent as defineEvent3 } from "@contractspec/lib.contracts-spec";
1949
- import { ScalarTypeEnum as ScalarTypeEnum9, defineSchemaModel as defineSchemaModel9 } from "@contractspec/lib.schema";
1950
- var InstanceEventPayload = defineSchemaModel9({
1951
- name: "InstanceEventPayload",
1952
- description: "Base payload for instance events",
1953
- fields: {
1954
- instanceId: { type: ScalarTypeEnum9.String_unsecure(), isOptional: false },
1955
- workflowId: { type: ScalarTypeEnum9.String_unsecure(), isOptional: false },
1956
- workflowKey: { type: ScalarTypeEnum9.String_unsecure(), isOptional: false },
1957
- status: { type: ScalarTypeEnum9.String_unsecure(), isOptional: false },
1958
- referenceId: { type: ScalarTypeEnum9.String_unsecure(), isOptional: true },
1959
- referenceType: {
1960
- type: ScalarTypeEnum9.String_unsecure(),
1961
- isOptional: true
1962
- },
1963
- triggeredBy: { type: ScalarTypeEnum9.String_unsecure(), isOptional: false },
1964
- organizationId: {
1965
- type: ScalarTypeEnum9.String_unsecure(),
1966
- isOptional: false
1967
- },
1968
- timestamp: { type: ScalarTypeEnum9.DateTime(), isOptional: false }
1969
- }
1970
- });
1971
- var StepTransitionPayload = defineSchemaModel9({
1972
- name: "StepTransitionEventPayload",
1973
- description: "Payload for step transition events",
1974
- fields: {
1975
- instanceId: { type: ScalarTypeEnum9.String_unsecure(), isOptional: false },
1976
- workflowId: { type: ScalarTypeEnum9.String_unsecure(), isOptional: false },
1977
- fromStepKey: { type: ScalarTypeEnum9.String_unsecure(), isOptional: true },
1978
- toStepKey: { type: ScalarTypeEnum9.String_unsecure(), isOptional: false },
1979
- action: { type: ScalarTypeEnum9.String_unsecure(), isOptional: true },
1980
- executedBy: { type: ScalarTypeEnum9.String_unsecure(), isOptional: false },
1981
- timestamp: { type: ScalarTypeEnum9.DateTime(), isOptional: false }
1982
- }
1983
- });
1984
- var InstanceCompletedPayload = defineSchemaModel9({
1985
- name: "InstanceCompletedEventPayload",
1986
- description: "Payload when instance completes",
1987
- fields: {
1988
- instanceId: { type: ScalarTypeEnum9.String_unsecure(), isOptional: false },
1989
- workflowId: { type: ScalarTypeEnum9.String_unsecure(), isOptional: false },
1990
- workflowKey: { type: ScalarTypeEnum9.String_unsecure(), isOptional: false },
1991
- outcome: { type: ScalarTypeEnum9.String_unsecure(), isOptional: false },
1992
- referenceId: { type: ScalarTypeEnum9.String_unsecure(), isOptional: true },
1993
- referenceType: {
1994
- type: ScalarTypeEnum9.String_unsecure(),
1995
- isOptional: true
1996
- },
1997
- duration: { type: ScalarTypeEnum9.Int_unsecure(), isOptional: false },
1998
- timestamp: { type: ScalarTypeEnum9.DateTime(), isOptional: false }
1905
+ targets: ["react", "markdown"],
1906
+ policy: {
1907
+ flags: ["workflow.approvals.enabled"]
1999
1908
  }
2000
1909
  });
2001
- var InstanceStartedEvent = defineEvent3({
1910
+ var ApprovalFormPresentation = definePresentation({
2002
1911
  meta: {
2003
- key: "workflow.instance.started",
1912
+ key: "workflow.approval.form",
2004
1913
  version: "1.0.0",
2005
- description: "A new workflow instance has been started.",
2006
- stability: "stable",
1914
+ title: "Approval Form",
1915
+ description: "Form for submitting approval decisions",
1916
+ domain: "workflow-system",
2007
1917
  owners: ["@workflow-team"],
2008
- tags: ["workflow", "instance", "started"]
1918
+ tags: ["workflow", "approval", "form"],
1919
+ stability: StabilityEnum.Experimental,
1920
+ goal: "Submitting a decision on an approval request",
1921
+ context: "Approval decision dialog"
2009
1922
  },
2010
- payload: InstanceEventPayload
2011
- });
2012
- var StepEnteredEvent = defineEvent3({
2013
- meta: {
2014
- key: "workflow.step.entered",
2015
- version: "1.0.0",
2016
- description: "A workflow instance has entered a new step.",
2017
- stability: "stable",
2018
- owners: ["@workflow-team"],
2019
- tags: ["workflow", "step", "entered"]
1923
+ source: {
1924
+ type: "component",
1925
+ framework: "react",
1926
+ componentKey: "ApprovalDecisionForm"
2020
1927
  },
2021
- payload: StepTransitionPayload
1928
+ targets: ["react"],
1929
+ policy: {
1930
+ flags: ["workflow.approvals.enabled"]
1931
+ }
2022
1932
  });
2023
- var StepExitedEvent = defineEvent3({
1933
+ var PendingApprovalsBadgePresentation = definePresentation({
2024
1934
  meta: {
2025
- key: "workflow.step.exited",
1935
+ key: "workflow.approval.badge",
2026
1936
  version: "1.0.0",
2027
- description: "A workflow instance has exited a step.",
2028
- stability: "stable",
1937
+ title: "Pending Approvals Badge",
1938
+ description: "Badge showing count of pending approvals",
1939
+ domain: "workflow-system",
2029
1940
  owners: ["@workflow-team"],
2030
- tags: ["workflow", "step", "exited"]
1941
+ tags: ["workflow", "approval", "badge", "widget"],
1942
+ stability: StabilityEnum.Experimental,
1943
+ goal: "Visual notification of pending approvals",
1944
+ context: "Global navigation or sidebar"
2031
1945
  },
2032
- payload: StepTransitionPayload
2033
- });
2034
- var InstanceCompletedEvent = defineEvent3({
2035
- meta: {
2036
- key: "workflow.instance.completed",
2037
- version: "1.0.0",
2038
- description: "A workflow instance has completed.",
2039
- stability: "stable",
2040
- owners: ["@workflow-team"],
2041
- tags: ["workflow", "instance", "completed"]
1946
+ source: {
1947
+ type: "component",
1948
+ framework: "react",
1949
+ componentKey: "PendingApprovalsBadge"
2042
1950
  },
2043
- payload: InstanceCompletedPayload
1951
+ targets: ["react"],
1952
+ policy: {
1953
+ flags: ["workflow.approvals.enabled"]
1954
+ }
2044
1955
  });
2045
- var InstanceCancelledEvent = defineEvent3({
1956
+ var WorkflowMetricsPresentation = definePresentation({
2046
1957
  meta: {
2047
- key: "workflow.instance.cancelled",
1958
+ key: "workflow.metrics",
2048
1959
  version: "1.0.0",
2049
- description: "A workflow instance has been cancelled.",
2050
- stability: "stable",
1960
+ title: "Workflow Metrics",
1961
+ description: "Dashboard widget showing workflow metrics and statistics",
1962
+ domain: "workflow-system",
2051
1963
  owners: ["@workflow-team"],
2052
- tags: ["workflow", "instance", "cancelled"]
2053
- },
2054
- payload: InstanceEventPayload
2055
- });
2056
- var InstancePausedEvent = defineEvent3({
2057
- meta: {
2058
- key: "workflow.instance.paused",
2059
- version: "1.0.0",
2060
- description: "A workflow instance has been paused.",
2061
- stability: "stable",
2062
- owners: ["@workflow-team"],
2063
- tags: ["workflow", "instance", "paused"]
2064
- },
2065
- payload: InstanceEventPayload
2066
- });
2067
- var InstanceResumedEvent = defineEvent3({
2068
- meta: {
2069
- key: "workflow.instance.resumed",
2070
- version: "1.0.0",
2071
- description: "A workflow instance has been resumed.",
2072
- stability: "stable",
2073
- owners: ["@workflow-team"],
2074
- tags: ["workflow", "instance", "resumed"]
2075
- },
2076
- payload: InstanceEventPayload
2077
- });
2078
- var InstanceFailedEvent = defineEvent3({
2079
- meta: {
2080
- key: "workflow.instance.failed",
2081
- version: "1.0.0",
2082
- description: "A workflow instance has failed.",
2083
- stability: "stable",
2084
- owners: ["@workflow-team"],
2085
- tags: ["workflow", "instance", "failed"]
2086
- },
2087
- payload: InstanceEventPayload
2088
- });
2089
- var InstanceTimedOutEvent = defineEvent3({
2090
- meta: {
2091
- key: "workflow.instance.timedOut",
2092
- version: "1.0.0",
2093
- description: "A workflow instance has timed out.",
2094
- stability: "stable",
2095
- owners: ["@workflow-team"],
2096
- tags: ["workflow", "instance", "timeout"]
2097
- },
2098
- payload: InstanceEventPayload
2099
- });
2100
- // src/presentations/index.ts
2101
- import {
2102
- definePresentation,
2103
- StabilityEnum
2104
- } from "@contractspec/lib.contracts-spec";
2105
- var WorkflowDesignerPresentation = definePresentation({
2106
- meta: {
2107
- key: "workflow.designer",
2108
- version: "1.0.0",
2109
- title: "Workflow Designer",
2110
- description: "Visual workflow designer with drag-and-drop steps",
2111
- domain: "workflow-system",
2112
- owners: ["@workflow-team"],
2113
- tags: ["workflow", "designer", "admin"],
1964
+ tags: ["workflow", "metrics", "dashboard"],
2114
1965
  stability: StabilityEnum.Experimental,
2115
- goal: "Building and modifying workflow definitions",
2116
- context: "Workflow administration and setup"
1966
+ goal: "Monitoring throughput and bottlenecks",
1967
+ context: "System performance dashboard"
2117
1968
  },
2118
1969
  source: {
2119
1970
  type: "component",
2120
1971
  framework: "react",
2121
- componentKey: "WorkflowDesigner",
2122
- props: WorkflowDefinitionModel
1972
+ componentKey: "WorkflowMetricsDashboard"
2123
1973
  },
2124
- targets: ["react"],
1974
+ targets: ["react", "markdown"],
2125
1975
  policy: {
2126
- flags: ["workflow.designer.enabled"]
1976
+ flags: ["workflow.metrics.enabled"]
2127
1977
  }
2128
1978
  });
2129
- var WorkflowListPresentation = definePresentation({
2130
- meta: {
2131
- key: "workflow.definition.viewList",
2132
- version: "1.0.0",
2133
- title: "Workflow List",
2134
- description: "List of workflow definitions with status and actions",
2135
- domain: "workflow-system",
2136
- owners: ["@workflow-team"],
2137
- tags: ["workflow", "list", "admin"],
2138
- stability: StabilityEnum.Experimental,
2139
- goal: "Overview of all defined workflows",
2140
- context: "Workflow management dashboard"
1979
+ var WorkflowSystemPresentations = {
1980
+ WorkflowDesignerPresentation,
1981
+ WorkflowListPresentation,
1982
+ WorkflowDetailPresentation,
1983
+ InstanceListPresentation,
1984
+ InstanceDetailPresentation,
1985
+ ProgressTrackerPresentation,
1986
+ ApprovalInboxPresentation,
1987
+ ApprovalDetailPresentation,
1988
+ ApprovalFormPresentation,
1989
+ PendingApprovalsBadgePresentation,
1990
+ WorkflowMetricsPresentation
1991
+ };
1992
+ // src/ui/hooks/useWorkflowList.ts
1993
+ import { useTemplateRuntime } from "@contractspec/lib.example-shared-ui";
1994
+ import { useCallback, useEffect, useState } from "react";
1995
+ "use client";
1996
+ function useWorkflowList(projectIdOverride) {
1997
+ const { handlers, projectId: runtimeProjectId } = useTemplateRuntime();
1998
+ const projectId = projectIdOverride ?? runtimeProjectId;
1999
+ const workflow = handlers.workflow;
2000
+ const [definitions, setDefinitions] = useState([]);
2001
+ const [instances, setInstances] = useState([]);
2002
+ const [loading, setLoading] = useState(true);
2003
+ const [error, setError] = useState(null);
2004
+ const fetchData = useCallback(async () => {
2005
+ try {
2006
+ setLoading(true);
2007
+ setError(null);
2008
+ const [defResult, instResult] = await Promise.all([
2009
+ workflow.listDefinitions({ projectId, limit: 100 }),
2010
+ workflow.listInstances({ projectId, limit: 100 })
2011
+ ]);
2012
+ setDefinitions(defResult.definitions);
2013
+ setInstances(instResult.instances);
2014
+ } catch (err) {
2015
+ setError(err instanceof Error ? err : new Error("Failed to load workflows"));
2016
+ } finally {
2017
+ setLoading(false);
2018
+ }
2019
+ }, [projectId, workflow]);
2020
+ useEffect(() => {
2021
+ fetchData();
2022
+ }, [fetchData]);
2023
+ const stats = {
2024
+ totalDefinitions: definitions.length,
2025
+ activeDefinitions: definitions.filter((d) => d.status === "ACTIVE").length,
2026
+ totalInstances: instances.length,
2027
+ pendingInstances: instances.filter((i) => i.status === "PENDING").length,
2028
+ inProgressInstances: instances.filter((i) => i.status === "IN_PROGRESS").length,
2029
+ completedInstances: instances.filter((i) => i.status === "COMPLETED").length,
2030
+ rejectedInstances: instances.filter((i) => i.status === "REJECTED").length
2031
+ };
2032
+ return {
2033
+ definitions,
2034
+ instances,
2035
+ loading,
2036
+ error,
2037
+ stats,
2038
+ refetch: fetchData
2039
+ };
2040
+ }
2041
+
2042
+ // src/ui/hooks/index.ts
2043
+ "use client";
2044
+
2045
+ // src/shared/demo-scenario.ts
2046
+ var WORKFLOW_SYSTEM_DEMO_PROJECT_ID = "workflow-system-demo";
2047
+ var WORKFLOW_SYSTEM_DEMO_ORGANIZATION_ID = "org_demo";
2048
+ var WORKFLOW_SYSTEM_DEMO_DEFINITIONS = [
2049
+ {
2050
+ id: "wf_expense",
2051
+ name: "Expense Approval",
2052
+ description: "Approve non-trivial spend before finance releases budget.",
2053
+ type: "APPROVAL",
2054
+ status: "ACTIVE",
2055
+ createdAt: "2026-03-10T09:00:00.000Z",
2056
+ updatedAt: "2026-03-20T08:15:00.000Z",
2057
+ steps: [
2058
+ {
2059
+ id: "wfstep_expense_manager",
2060
+ name: "Manager Review",
2061
+ description: "Validate business value and team budget.",
2062
+ stepOrder: 1,
2063
+ type: "APPROVAL",
2064
+ requiredRoles: ["manager"],
2065
+ createdAt: "2026-03-10T09:00:00.000Z"
2066
+ },
2067
+ {
2068
+ id: "wfstep_expense_finance",
2069
+ name: "Finance Review",
2070
+ description: "Confirm ledger coding and spending threshold.",
2071
+ stepOrder: 2,
2072
+ type: "APPROVAL",
2073
+ requiredRoles: ["finance"],
2074
+ createdAt: "2026-03-10T09:10:00.000Z"
2075
+ }
2076
+ ]
2141
2077
  },
2142
- source: {
2143
- type: "component",
2144
- framework: "react",
2145
- componentKey: "WorkflowDefinitionList",
2146
- props: WorkflowDefinitionModel
2078
+ {
2079
+ id: "wf_vendor",
2080
+ name: "Vendor Onboarding",
2081
+ description: "Sequence security, procurement, and legal before activation.",
2082
+ type: "SEQUENTIAL",
2083
+ status: "ACTIVE",
2084
+ createdAt: "2026-03-08T11:00:00.000Z",
2085
+ updatedAt: "2026-03-19T13:10:00.000Z",
2086
+ steps: [
2087
+ {
2088
+ id: "wfstep_vendor_security",
2089
+ name: "Security Check",
2090
+ description: "Review data access and integration scope.",
2091
+ stepOrder: 1,
2092
+ type: "APPROVAL",
2093
+ requiredRoles: ["security"],
2094
+ createdAt: "2026-03-08T11:00:00.000Z"
2095
+ },
2096
+ {
2097
+ id: "wfstep_vendor_procurement",
2098
+ name: "Procurement Check",
2099
+ description: "Validate pricing, procurement policy, and owner.",
2100
+ stepOrder: 2,
2101
+ type: "APPROVAL",
2102
+ requiredRoles: ["procurement"],
2103
+ createdAt: "2026-03-08T11:05:00.000Z"
2104
+ },
2105
+ {
2106
+ id: "wfstep_vendor_legal",
2107
+ name: "Legal Sign-off",
2108
+ description: "Approve terms before the vendor goes live.",
2109
+ stepOrder: 3,
2110
+ type: "APPROVAL",
2111
+ requiredRoles: ["legal"],
2112
+ createdAt: "2026-03-08T11:10:00.000Z"
2113
+ }
2114
+ ]
2147
2115
  },
2148
- targets: ["react", "markdown"],
2149
- policy: {
2150
- flags: ["workflow.enabled"]
2116
+ {
2117
+ id: "wf_policy_exception",
2118
+ name: "Policy Exception",
2119
+ description: "Escalate a temporary exception through team lead and compliance.",
2120
+ type: "APPROVAL",
2121
+ status: "DRAFT",
2122
+ createdAt: "2026-03-15T07:30:00.000Z",
2123
+ updatedAt: "2026-03-18T11:20:00.000Z",
2124
+ steps: [
2125
+ {
2126
+ id: "wfstep_policy_lead",
2127
+ name: "Team Lead Review",
2128
+ description: "Check urgency and expected blast radius.",
2129
+ stepOrder: 1,
2130
+ type: "APPROVAL",
2131
+ requiredRoles: ["team-lead"],
2132
+ createdAt: "2026-03-15T07:30:00.000Z"
2133
+ },
2134
+ {
2135
+ id: "wfstep_policy_compliance",
2136
+ name: "Compliance Review",
2137
+ description: "Accept or reject the exception request.",
2138
+ stepOrder: 2,
2139
+ type: "APPROVAL",
2140
+ requiredRoles: ["compliance"],
2141
+ createdAt: "2026-03-15T07:40:00.000Z"
2142
+ }
2143
+ ]
2151
2144
  }
2152
- });
2153
- var WorkflowDetailPresentation = definePresentation({
2154
- meta: {
2155
- key: "workflow.definition.detail",
2156
- version: "1.0.0",
2157
- title: "Workflow Details",
2158
- description: "Detailed view of a workflow definition with steps",
2159
- domain: "workflow-system",
2160
- owners: ["@workflow-team"],
2161
- tags: ["workflow", "detail"],
2162
- stability: StabilityEnum.Experimental,
2163
- goal: "Viewing technical details of a workflow definition",
2164
- context: "Workflow inspection and debugging"
2145
+ ];
2146
+ var WORKFLOW_SYSTEM_DEMO_INSTANCES = [
2147
+ {
2148
+ id: "wfinst_expense_open",
2149
+ definitionId: "wf_expense",
2150
+ status: "IN_PROGRESS",
2151
+ currentStepId: "wfstep_expense_finance",
2152
+ data: {
2153
+ amount: 4200,
2154
+ currency: "EUR",
2155
+ vendor: "Nimbus AI"
2156
+ },
2157
+ requestedBy: "sarah@contractspec.io",
2158
+ startedAt: "2026-03-20T08:00:00.000Z",
2159
+ approvals: [
2160
+ {
2161
+ id: "wfappr_expense_manager",
2162
+ stepId: "wfstep_expense_manager",
2163
+ status: "APPROVED",
2164
+ actorId: "manager.demo",
2165
+ comment: "Approved for the Q2 automation budget.",
2166
+ decidedAt: "2026-03-20T08:15:00.000Z",
2167
+ createdAt: "2026-03-20T08:05:00.000Z"
2168
+ },
2169
+ {
2170
+ id: "wfappr_expense_finance",
2171
+ stepId: "wfstep_expense_finance",
2172
+ status: "PENDING",
2173
+ createdAt: "2026-03-20T08:15:00.000Z"
2174
+ }
2175
+ ]
2165
2176
  },
2166
- source: {
2167
- type: "component",
2168
- framework: "react",
2169
- componentKey: "WorkflowDefinitionDetail",
2170
- props: WorkflowDefinitionModel
2177
+ {
2178
+ id: "wfinst_vendor_done",
2179
+ definitionId: "wf_vendor",
2180
+ status: "COMPLETED",
2181
+ data: {
2182
+ vendor: "Acme Cloud",
2183
+ riskTier: "medium"
2184
+ },
2185
+ requestedBy: "leo@contractspec.io",
2186
+ startedAt: "2026-03-19T09:30:00.000Z",
2187
+ completedAt: "2026-03-19T13:10:00.000Z",
2188
+ approvals: [
2189
+ {
2190
+ id: "wfappr_vendor_security",
2191
+ stepId: "wfstep_vendor_security",
2192
+ status: "APPROVED",
2193
+ actorId: "security.demo",
2194
+ comment: "SOC2 scope is acceptable.",
2195
+ decidedAt: "2026-03-19T10:10:00.000Z",
2196
+ createdAt: "2026-03-19T09:35:00.000Z"
2197
+ },
2198
+ {
2199
+ id: "wfappr_vendor_procurement",
2200
+ stepId: "wfstep_vendor_procurement",
2201
+ status: "APPROVED",
2202
+ actorId: "procurement.demo",
2203
+ comment: "Commercial terms match the preferred vendor tier.",
2204
+ decidedAt: "2026-03-19T11:25:00.000Z",
2205
+ createdAt: "2026-03-19T10:15:00.000Z"
2206
+ },
2207
+ {
2208
+ id: "wfappr_vendor_legal",
2209
+ stepId: "wfstep_vendor_legal",
2210
+ status: "APPROVED",
2211
+ actorId: "legal.demo",
2212
+ comment: "MSA redlines are complete.",
2213
+ decidedAt: "2026-03-19T13:05:00.000Z",
2214
+ createdAt: "2026-03-19T11:30:00.000Z"
2215
+ }
2216
+ ]
2171
2217
  },
2172
- targets: ["react", "markdown"],
2173
- policy: {
2174
- flags: ["workflow.enabled"]
2218
+ {
2219
+ id: "wfinst_policy_rejected",
2220
+ definitionId: "wf_policy_exception",
2221
+ status: "REJECTED",
2222
+ currentStepId: "wfstep_policy_compliance",
2223
+ data: {
2224
+ policy: "Model rollout freeze",
2225
+ durationDays: 14
2226
+ },
2227
+ requestedBy: "maya@contractspec.io",
2228
+ startedAt: "2026-03-18T10:00:00.000Z",
2229
+ completedAt: "2026-03-18T11:20:00.000Z",
2230
+ approvals: [
2231
+ {
2232
+ id: "wfappr_policy_lead",
2233
+ stepId: "wfstep_policy_lead",
2234
+ status: "APPROVED",
2235
+ actorId: "lead.demo",
2236
+ comment: "Escalation justified for the release train.",
2237
+ decidedAt: "2026-03-18T10:30:00.000Z",
2238
+ createdAt: "2026-03-18T10:05:00.000Z"
2239
+ },
2240
+ {
2241
+ id: "wfappr_policy_compliance",
2242
+ stepId: "wfstep_policy_compliance",
2243
+ status: "REJECTED",
2244
+ actorId: "compliance.demo",
2245
+ comment: "Exception exceeds the allowed blast radius.",
2246
+ decidedAt: "2026-03-18T11:15:00.000Z",
2247
+ createdAt: "2026-03-18T10:35:00.000Z"
2248
+ }
2249
+ ]
2175
2250
  }
2176
- });
2177
- var InstanceListPresentation = definePresentation({
2251
+ ];
2252
+
2253
+ // src/visualizations/catalog.ts
2254
+ import {
2255
+ defineVisualization,
2256
+ VisualizationRegistry
2257
+ } from "@contractspec/lib.contracts-spec/visualizations";
2258
+ var INSTANCE_LIST_REF = {
2259
+ key: "workflow.instance.list",
2260
+ version: "1.0.0"
2261
+ };
2262
+ var META = {
2263
+ version: "1.0.0",
2264
+ domain: "workflow",
2265
+ stability: "experimental",
2266
+ owners: ["@example.workflow-system"],
2267
+ tags: ["workflow", "visualization", "operations"]
2268
+ };
2269
+ var WorkflowInstanceStatusVisualization = defineVisualization({
2178
2270
  meta: {
2179
- key: "workflow.instance.viewList",
2180
- version: "1.0.0",
2181
- title: "Instance List",
2182
- description: "List of workflow instances with status and progress",
2183
- domain: "workflow-system",
2184
- owners: ["@workflow-team"],
2185
- tags: ["workflow", "instance", "list"],
2186
- stability: StabilityEnum.Experimental,
2187
- goal: "Monitoring active and past workflow executions",
2188
- context: "Operations monitoring"
2189
- },
2190
- source: {
2191
- type: "component",
2192
- framework: "react",
2193
- componentKey: "WorkflowInstanceList",
2194
- props: WorkflowInstanceModel
2195
- },
2196
- targets: ["react", "markdown"],
2197
- policy: {
2198
- flags: ["workflow.enabled"]
2271
+ ...META,
2272
+ key: "workflow-system.visualization.instance-status",
2273
+ title: "Instance Status Breakdown",
2274
+ description: "Distribution of workflow instance states.",
2275
+ goal: "Surface the current workload mix.",
2276
+ context: "Workflow operations overview."
2277
+ },
2278
+ source: { primary: INSTANCE_LIST_REF, resultPath: "data" },
2279
+ visualization: {
2280
+ kind: "pie",
2281
+ nameDimension: "status",
2282
+ valueMeasure: "instances",
2283
+ dimensions: [
2284
+ { key: "status", label: "Status", dataPath: "status", type: "category" }
2285
+ ],
2286
+ measures: [
2287
+ {
2288
+ key: "instances",
2289
+ label: "Instances",
2290
+ dataPath: "instances",
2291
+ format: "number"
2292
+ }
2293
+ ],
2294
+ table: { caption: "Workflow instance counts by status." }
2199
2295
  }
2200
2296
  });
2201
- var InstanceDetailPresentation = definePresentation({
2297
+ var WorkflowThroughputVisualization = defineVisualization({
2202
2298
  meta: {
2203
- key: "workflow.instance.detail",
2204
- version: "1.0.0",
2205
- title: "Instance Details",
2206
- description: "Detailed view of a workflow instance with step timeline",
2207
- domain: "workflow-system",
2208
- owners: ["@workflow-team"],
2209
- tags: ["workflow", "instance", "detail", "timeline"],
2210
- stability: StabilityEnum.Experimental,
2211
- goal: "Detailed inspection of a specific workflow instance",
2212
- context: "Case management and troubleshooting"
2213
- },
2214
- source: {
2215
- type: "component",
2216
- framework: "react",
2217
- componentKey: "WorkflowInstanceDetail",
2218
- props: WorkflowInstanceModel
2219
- },
2220
- targets: ["react", "markdown"],
2221
- policy: {
2222
- flags: ["workflow.enabled"]
2223
- }
2224
- });
2225
- var ProgressTrackerPresentation = definePresentation({
2226
- meta: {
2227
- key: "workflow.instance.progress",
2228
- version: "1.0.0",
2229
- title: "Progress Tracker",
2230
- description: "Visual progress tracker showing current step in workflow",
2231
- domain: "workflow-system",
2232
- owners: ["@workflow-team"],
2233
- tags: ["workflow", "progress", "widget"],
2234
- stability: StabilityEnum.Experimental,
2235
- goal: "Quick view of current progress for a workflow",
2236
- context: "Embedded progress indicator in entity views"
2237
- },
2238
- source: {
2239
- type: "component",
2240
- framework: "react",
2241
- componentKey: "WorkflowProgressTracker",
2242
- props: WorkflowInstanceModel
2243
- },
2244
- targets: ["react"],
2245
- policy: {
2246
- flags: ["workflow.enabled"]
2247
- }
2248
- });
2249
- var ApprovalInboxPresentation = definePresentation({
2250
- meta: {
2251
- key: "workflow.approval.inbox",
2252
- version: "1.0.0",
2253
- title: "Approval Inbox",
2254
- description: "Inbox showing pending approval requests for current user",
2255
- domain: "workflow-system",
2256
- owners: ["@workflow-team"],
2257
- tags: ["workflow", "approval", "inbox"],
2258
- stability: StabilityEnum.Experimental,
2259
- goal: "Managing personal workload of approval requests",
2260
- context: "Personal task management"
2261
- },
2262
- source: {
2263
- type: "component",
2264
- framework: "react",
2265
- componentKey: "ApprovalInbox",
2266
- props: ApprovalRequestModel
2267
- },
2268
- targets: ["react", "markdown"],
2269
- policy: {
2270
- flags: ["workflow.approvals.enabled"]
2271
- }
2272
- });
2273
- var ApprovalDetailPresentation = definePresentation({
2274
- meta: {
2275
- key: "workflow.approval.detail",
2276
- version: "1.0.0",
2277
- title: "Approval Details",
2278
- description: "Detailed approval request view with context and actions",
2279
- domain: "workflow-system",
2280
- owners: ["@workflow-team"],
2281
- tags: ["workflow", "approval", "detail"],
2282
- stability: StabilityEnum.Experimental,
2283
- goal: "Decision support for an approval request",
2284
- context: "Specific approval action"
2285
- },
2286
- source: {
2287
- type: "component",
2288
- framework: "react",
2289
- componentKey: "ApprovalRequestDetail",
2290
- props: ApprovalRequestModel
2291
- },
2292
- targets: ["react", "markdown"],
2293
- policy: {
2294
- flags: ["workflow.approvals.enabled"]
2295
- }
2296
- });
2297
- var ApprovalFormPresentation = definePresentation({
2298
- meta: {
2299
- key: "workflow.approval.form",
2300
- version: "1.0.0",
2301
- title: "Approval Form",
2302
- description: "Form for submitting approval decisions",
2303
- domain: "workflow-system",
2304
- owners: ["@workflow-team"],
2305
- tags: ["workflow", "approval", "form"],
2306
- stability: StabilityEnum.Experimental,
2307
- goal: "Submitting a decision on an approval request",
2308
- context: "Approval decision dialog"
2309
- },
2310
- source: {
2311
- type: "component",
2312
- framework: "react",
2313
- componentKey: "ApprovalDecisionForm"
2314
- },
2315
- targets: ["react"],
2316
- policy: {
2317
- flags: ["workflow.approvals.enabled"]
2299
+ ...META,
2300
+ key: "workflow-system.visualization.throughput",
2301
+ title: "Run Throughput",
2302
+ description: "Daily workflow instance starts.",
2303
+ goal: "Show operational throughput over time.",
2304
+ context: "Workflow trend monitoring."
2305
+ },
2306
+ source: { primary: INSTANCE_LIST_REF, resultPath: "data" },
2307
+ visualization: {
2308
+ kind: "cartesian",
2309
+ variant: "line",
2310
+ xDimension: "day",
2311
+ yMeasures: ["instances"],
2312
+ dimensions: [{ key: "day", label: "Day", dataPath: "day", type: "time" }],
2313
+ measures: [
2314
+ {
2315
+ key: "instances",
2316
+ label: "Instances",
2317
+ dataPath: "instances",
2318
+ format: "number",
2319
+ color: "#0f766e"
2320
+ }
2321
+ ],
2322
+ table: { caption: "Daily workflow instance starts." }
2318
2323
  }
2319
2324
  });
2320
- var PendingApprovalsBadgePresentation = definePresentation({
2325
+ var WorkflowActiveMetricVisualization = defineVisualization({
2321
2326
  meta: {
2322
- key: "workflow.approval.badge",
2323
- version: "1.0.0",
2324
- title: "Pending Approvals Badge",
2325
- description: "Badge showing count of pending approvals",
2326
- domain: "workflow-system",
2327
- owners: ["@workflow-team"],
2328
- tags: ["workflow", "approval", "badge", "widget"],
2329
- stability: StabilityEnum.Experimental,
2330
- goal: "Visual notification of pending approvals",
2331
- context: "Global navigation or sidebar"
2332
- },
2333
- source: {
2334
- type: "component",
2335
- framework: "react",
2336
- componentKey: "PendingApprovalsBadge"
2337
- },
2338
- targets: ["react"],
2339
- policy: {
2340
- flags: ["workflow.approvals.enabled"]
2327
+ ...META,
2328
+ key: "workflow-system.visualization.active-work",
2329
+ title: "Active Work",
2330
+ description: "Current in-flight or pending workflow instances.",
2331
+ goal: "Expose active operational workload.",
2332
+ context: "Workflow workload comparison."
2333
+ },
2334
+ source: { primary: INSTANCE_LIST_REF, resultPath: "data" },
2335
+ visualization: {
2336
+ kind: "metric",
2337
+ measure: "value",
2338
+ measures: [
2339
+ { key: "value", label: "Instances", dataPath: "value", format: "number" }
2340
+ ],
2341
+ table: { caption: "Active workflow count." }
2341
2342
  }
2342
2343
  });
2343
- var WorkflowMetricsPresentation = definePresentation({
2344
+ var WorkflowCompletedMetricVisualization = defineVisualization({
2344
2345
  meta: {
2345
- key: "workflow.metrics",
2346
- version: "1.0.0",
2347
- title: "Workflow Metrics",
2348
- description: "Dashboard widget showing workflow metrics and statistics",
2349
- domain: "workflow-system",
2350
- owners: ["@workflow-team"],
2351
- tags: ["workflow", "metrics", "dashboard"],
2352
- stability: StabilityEnum.Experimental,
2353
- goal: "Monitoring throughput and bottlenecks",
2354
- context: "System performance dashboard"
2355
- },
2356
- source: {
2357
- type: "component",
2358
- framework: "react",
2359
- componentKey: "WorkflowMetricsDashboard"
2360
- },
2361
- targets: ["react", "markdown"],
2362
- policy: {
2363
- flags: ["workflow.metrics.enabled"]
2346
+ ...META,
2347
+ key: "workflow-system.visualization.completed-work",
2348
+ title: "Completed Work",
2349
+ description: "Completed workflow instances in the current sample.",
2350
+ goal: "Show output against active workload.",
2351
+ context: "Workflow workload comparison."
2352
+ },
2353
+ source: { primary: INSTANCE_LIST_REF, resultPath: "data" },
2354
+ visualization: {
2355
+ kind: "metric",
2356
+ measure: "value",
2357
+ measures: [
2358
+ { key: "value", label: "Instances", dataPath: "value", format: "number" }
2359
+ ],
2360
+ table: { caption: "Completed workflow count." }
2364
2361
  }
2365
2362
  });
2366
- var WorkflowSystemPresentations = {
2367
- WorkflowDesignerPresentation,
2368
- WorkflowListPresentation,
2369
- WorkflowDetailPresentation,
2370
- InstanceListPresentation,
2371
- InstanceDetailPresentation,
2372
- ProgressTrackerPresentation,
2373
- ApprovalInboxPresentation,
2374
- ApprovalDetailPresentation,
2375
- ApprovalFormPresentation,
2376
- PendingApprovalsBadgePresentation,
2377
- WorkflowMetricsPresentation
2378
- };
2363
+ var WorkflowVisualizationSpecs = [
2364
+ WorkflowInstanceStatusVisualization,
2365
+ WorkflowThroughputVisualization,
2366
+ WorkflowActiveMetricVisualization,
2367
+ WorkflowCompletedMetricVisualization
2368
+ ];
2369
+ var WorkflowVisualizationRegistry = new VisualizationRegistry([
2370
+ ...WorkflowVisualizationSpecs
2371
+ ]);
2372
+ var WorkflowVisualizationRefs = WorkflowVisualizationSpecs.map((spec) => ({
2373
+ key: spec.meta.key,
2374
+ version: spec.meta.version
2375
+ }));
2379
2376
 
2380
- // src/workflow-system.feature.ts
2381
- import { defineFeature } from "@contractspec/lib.contracts-spec";
2382
- var WorkflowSystemFeature = defineFeature({
2383
- meta: {
2384
- key: "workflow-system",
2385
- title: "Workflow & Approval System",
2386
- description: "State machine-based workflow engine with role-based approvals, delegation, and escalation",
2387
- domain: "workflow",
2388
- owners: ["@workflow-team"],
2389
- tags: ["workflow", "approval", "state-machine", "automation"],
2390
- stability: "experimental",
2391
- version: "1.0.0"
2392
- },
2393
- operations: [
2394
- { key: "workflow.definition.create", version: "1.0.0" },
2395
- { key: "workflow.definition.update", version: "1.0.0" },
2396
- { key: "workflow.step.add", version: "1.0.0" },
2397
- { key: "workflow.definition.publish", version: "1.0.0" },
2398
- { key: "workflow.definition.list", version: "1.0.0" },
2399
- { key: "workflow.definition.get", version: "1.0.0" },
2400
- { key: "workflow.instance.start", version: "1.0.0" },
2401
- { key: "workflow.instance.transition", version: "1.0.0" },
2402
- { key: "workflow.instance.pause", version: "1.0.0" },
2403
- { key: "workflow.instance.resume", version: "1.0.0" },
2404
- { key: "workflow.instance.cancel", version: "1.0.0" },
2405
- { key: "workflow.instance.list", version: "1.0.0" },
2406
- { key: "workflow.instance.get", version: "1.0.0" },
2407
- { key: "workflow.approval.decide", version: "1.0.0" },
2408
- { key: "workflow.approval.delegate", version: "1.0.0" },
2409
- { key: "workflow.approval.comment.add", version: "1.0.0" },
2410
- { key: "workflow.approval.list.mine", version: "1.0.0" },
2411
- { key: "workflow.approval.get", version: "1.0.0" }
2412
- ],
2413
- events: [
2414
- { key: "workflow.definition.created", version: "1.0.0" },
2415
- { key: "workflow.definition.updated", version: "1.0.0" },
2416
- { key: "workflow.definition.published", version: "1.0.0" },
2417
- { key: "workflow.step.added", version: "1.0.0" },
2418
- { key: "workflow.instance.started", version: "1.0.0" },
2419
- { key: "workflow.step.entered", version: "1.0.0" },
2420
- { key: "workflow.step.exited", version: "1.0.0" },
2421
- { key: "workflow.instance.completed", version: "1.0.0" },
2422
- { key: "workflow.instance.cancelled", version: "1.0.0" },
2423
- { key: "workflow.instance.paused", version: "1.0.0" },
2424
- { key: "workflow.instance.resumed", version: "1.0.0" },
2425
- { key: "workflow.instance.failed", version: "1.0.0" },
2426
- { key: "workflow.instance.timedOut", version: "1.0.0" },
2427
- { key: "workflow.approval.requested", version: "1.0.0" },
2428
- { key: "workflow.approval.decided", version: "1.0.0" },
2429
- { key: "workflow.approval.delegated", version: "1.0.0" },
2430
- { key: "workflow.approval.escalated", version: "1.0.0" }
2431
- ],
2432
- presentations: [
2433
- { key: "workflow.designer", version: "1.0.0" },
2434
- { key: "workflow.definition.viewList", version: "1.0.0" },
2435
- { key: "workflow.definition.detail", version: "1.0.0" },
2436
- { key: "workflow.instance.viewList", version: "1.0.0" },
2437
- { key: "workflow.instance.detail", version: "1.0.0" },
2438
- { key: "workflow.instance.progress", version: "1.0.0" },
2439
- { key: "workflow.approval.inbox", version: "1.0.0" },
2440
- { key: "workflow.approval.detail", version: "1.0.0" },
2441
- { key: "workflow.approval.form", version: "1.0.0" },
2442
- { key: "workflow.approval.badge", version: "1.0.0" },
2443
- { key: "workflow.metrics", version: "1.0.0" }
2444
- ],
2445
- opToPresentation: [
2377
+ // src/visualizations/selectors.ts
2378
+ function toDayKey(value) {
2379
+ const date = value instanceof Date ? value : new Date(value);
2380
+ return date.toISOString().slice(0, 10);
2381
+ }
2382
+ function createWorkflowVisualizationSections(instances) {
2383
+ const statusCounts = new Map;
2384
+ const throughput = new Map;
2385
+ let activeCount = 0;
2386
+ let completedCount = 0;
2387
+ for (const instance of instances) {
2388
+ statusCounts.set(instance.status, (statusCounts.get(instance.status) ?? 0) + 1);
2389
+ const day = toDayKey(instance.startedAt);
2390
+ throughput.set(day, (throughput.get(day) ?? 0) + 1);
2391
+ if (instance.status === "PENDING" || instance.status === "IN_PROGRESS") {
2392
+ activeCount += 1;
2393
+ }
2394
+ if (instance.status === "COMPLETED") {
2395
+ completedCount += 1;
2396
+ }
2397
+ }
2398
+ const primaryItems = [
2446
2399
  {
2447
- op: { key: "workflow.definition.list", version: "1.0.0" },
2448
- pres: { key: "workflow.definition.viewList", version: "1.0.0" }
2400
+ key: "workflow-status",
2401
+ spec: WorkflowInstanceStatusVisualization,
2402
+ data: {
2403
+ data: Array.from(statusCounts.entries()).map(([status, count]) => ({
2404
+ status,
2405
+ instances: count
2406
+ }))
2407
+ },
2408
+ title: "Instance Status Breakdown",
2409
+ description: "Status mix across workflow instances.",
2410
+ height: 260
2449
2411
  },
2450
2412
  {
2451
- op: { key: "workflow.instance.list", version: "1.0.0" },
2452
- pres: { key: "workflow.instance.viewList", version: "1.0.0" }
2453
- },
2413
+ key: "workflow-throughput",
2414
+ spec: WorkflowThroughputVisualization,
2415
+ data: {
2416
+ data: Array.from(throughput.entries()).sort(([left], [right]) => left.localeCompare(right)).map(([day, count]) => ({ day, instances: count }))
2417
+ },
2418
+ title: "Run Throughput",
2419
+ description: "Daily workflow starts from current instances."
2420
+ }
2421
+ ];
2422
+ const comparisonItems = [
2454
2423
  {
2455
- op: { key: "workflow.approval.list.mine", version: "1.0.0" },
2456
- pres: { key: "workflow.approval.inbox", version: "1.0.0" }
2424
+ key: "workflow-active",
2425
+ spec: WorkflowActiveMetricVisualization,
2426
+ data: { data: [{ value: activeCount }] },
2427
+ title: "Active Work",
2428
+ description: "Pending and in-progress workflows.",
2429
+ height: 200
2457
2430
  },
2458
2431
  {
2459
- op: { key: "workflow.approval.decide", version: "1.0.0" },
2460
- pres: { key: "workflow.approval.form", version: "1.0.0" }
2461
- }
2462
- ],
2463
- presentationsTargets: [
2464
- { key: "workflow.designer", version: "1.0.0", targets: ["react"] },
2465
- {
2466
- key: "workflow.definition.viewList",
2467
- version: "1.0.0",
2468
- targets: ["react", "markdown"]
2469
- },
2470
- {
2471
- key: "workflow.definition.detail",
2472
- version: "1.0.0",
2473
- targets: ["react", "markdown"]
2474
- },
2475
- {
2476
- key: "workflow.instance.viewList",
2477
- version: "1.0.0",
2478
- targets: ["react", "markdown"]
2479
- },
2480
- {
2481
- key: "workflow.instance.detail",
2482
- version: "1.0.0",
2483
- targets: ["react", "markdown"]
2484
- },
2485
- { key: "workflow.instance.progress", version: "1.0.0", targets: ["react"] },
2486
- {
2487
- key: "workflow.approval.inbox",
2488
- version: "1.0.0",
2489
- targets: ["react", "markdown"]
2490
- },
2491
- {
2492
- key: "workflow.approval.detail",
2493
- version: "1.0.0",
2494
- targets: ["react", "markdown"]
2495
- },
2496
- {
2497
- key: "workflow.metrics",
2498
- version: "1.0.0",
2499
- targets: ["react", "markdown"]
2432
+ key: "workflow-completed",
2433
+ spec: WorkflowCompletedMetricVisualization,
2434
+ data: { data: [{ value: completedCount }] },
2435
+ title: "Completed Work",
2436
+ description: "Completed workflows in the current sample.",
2437
+ height: 200
2500
2438
  }
2501
- ],
2502
- capabilities: {
2503
- requires: [
2504
- { key: "identity", version: "1.0.0" },
2505
- { key: "audit-trail", version: "1.0.0" },
2506
- { key: "notifications", version: "1.0.0" },
2507
- { key: "feature-flags", version: "1.0.0" }
2508
- ],
2509
- provides: [
2510
- { key: "workflow", version: "1.0.0" },
2511
- { key: "approval", version: "1.0.0" },
2512
- { key: "state-machine", version: "1.0.0" }
2513
- ]
2514
- },
2515
- workflows: [
2516
- { key: "workflow-system.workflow.approval-chain", version: "1.0.0" }
2517
- ],
2518
- telemetry: [{ key: "workflow-system.telemetry", version: "1.0.0" }],
2519
- jobs: [
2520
- { key: "workflow-system.job.instance-timeout", version: "1.0.0" },
2521
- { key: "workflow-system.job.escalation", version: "1.0.0" }
2522
- ],
2523
- docs: [
2524
- "docs.examples.workflow-system",
2525
- "docs.examples.workflow-system.goal",
2526
- "docs.examples.workflow-system.usage",
2527
- "docs.examples.workflow-system.constraints"
2528
- ]
2529
- });
2530
-
2439
+ ];
2440
+ return {
2441
+ primaryItems,
2442
+ comparisonItems
2443
+ };
2444
+ }
2531
2445
  // src/ui/renderers/workflow.markdown.ts
2532
- var mockWorkflowDefinitions = [
2533
- {
2534
- id: "wf-1",
2535
- name: "Purchase Approval",
2536
- type: "APPROVAL",
2537
- steps: [
2538
- {
2539
- id: "s1",
2540
- name: "Manager Review",
2541
- order: 1,
2542
- requiredRoles: ["manager"]
2543
- },
2544
- {
2545
- id: "s2",
2546
- name: "Finance Review",
2547
- order: 2,
2548
- requiredRoles: ["finance"]
2549
- },
2550
- { id: "s3", name: "Final Approval", order: 3, requiredRoles: ["admin"] }
2551
- ],
2552
- status: "ACTIVE"
2553
- },
2554
- {
2555
- id: "wf-2",
2556
- name: "Leave Request",
2557
- type: "APPROVAL",
2558
- steps: [
2559
- {
2560
- id: "s1",
2561
- name: "Supervisor Approval",
2562
- order: 1,
2563
- requiredRoles: ["supervisor"]
2564
- },
2565
- { id: "s2", name: "HR Review", order: 2, requiredRoles: ["hr"] }
2566
- ],
2567
- status: "ACTIVE"
2568
- },
2569
- {
2570
- id: "wf-3",
2571
- name: "Document Review",
2572
- type: "SEQUENTIAL",
2573
- steps: [
2574
- { id: "s1", name: "Author Review", order: 1, requiredRoles: ["author"] },
2575
- { id: "s2", name: "Peer Review", order: 2, requiredRoles: ["reviewer"] },
2576
- { id: "s3", name: "Publish", order: 3, requiredRoles: ["publisher"] }
2577
- ],
2578
- status: "DRAFT"
2579
- }
2580
- ];
2581
- var mockWorkflowInstances = [
2582
- {
2583
- id: "inst-1",
2584
- definitionId: "wf-1",
2585
- definitionName: "Purchase Approval",
2586
- status: "IN_PROGRESS",
2587
- currentStepId: "s2",
2588
- startedAt: "2024-01-15T10:00:00Z",
2589
- requestedBy: "John Doe"
2590
- },
2591
- {
2592
- id: "inst-2",
2593
- definitionId: "wf-1",
2594
- definitionName: "Purchase Approval",
2595
- status: "COMPLETED",
2596
- currentStepId: null,
2597
- startedAt: "2024-01-10T09:00:00Z",
2598
- completedAt: "2024-01-12T14:00:00Z",
2599
- requestedBy: "Jane Smith"
2600
- },
2601
- {
2602
- id: "inst-3",
2603
- definitionId: "wf-2",
2604
- definitionName: "Leave Request",
2605
- status: "PENDING",
2606
- currentStepId: "s1",
2607
- startedAt: "2024-01-16T08:00:00Z",
2608
- requestedBy: "Bob Wilson"
2609
- }
2610
- ];
2446
+ var workflowDefinitions = WORKFLOW_SYSTEM_DEMO_DEFINITIONS;
2447
+ var workflowInstances = WORKFLOW_SYSTEM_DEMO_INSTANCES;
2448
+ var workflowDefinitionById = new Map(workflowDefinitions.map((definition) => [definition.id, definition]));
2449
+ function formatDate(value) {
2450
+ return new Date(value).toISOString().slice(0, 10);
2451
+ }
2611
2452
  var workflowDashboardMarkdownRenderer = {
2612
2453
  target: "markdown",
2613
2454
  render: async (desc) => {
2614
2455
  if (desc.source.type !== "component" || desc.source.componentKey !== "WorkflowDashboard") {
2615
2456
  throw new Error("workflowDashboardMarkdownRenderer: not WorkflowDashboard");
2616
2457
  }
2617
- const definitions = mockWorkflowDefinitions;
2618
- const instances = mockWorkflowInstances;
2458
+ const definitions = workflowDefinitions;
2459
+ const instances = workflowInstances;
2460
+ const visualizations = createWorkflowVisualizationSections(instances);
2619
2461
  const activeDefinitions = definitions.filter((d) => d.status === "ACTIVE");
2620
- const pendingInstances = instances.filter((i) => i.status === "PENDING");
2621
- const inProgressInstances = instances.filter((i) => i.status === "IN_PROGRESS");
2622
- const completedInstances = instances.filter((i) => i.status === "COMPLETED");
2462
+ const awaitingActionInstances = instances.filter((i) => i.status === "PENDING" || i.status === "IN_PROGRESS");
2623
2463
  const lines = [
2624
2464
  "# Workflow Dashboard",
2625
2465
  "",
2626
- "> Workflow and approval management overview",
2466
+ "> Seeded workflow and approval overview for the sandbox demo.",
2627
2467
  "",
2628
2468
  "## Summary",
2629
2469
  "",
2630
2470
  "| Metric | Value |",
2631
2471
  "|--------|-------|",
2632
2472
  `| Active Workflows | ${activeDefinitions.length} |`,
2633
- `| Pending Approvals | ${pendingInstances.length} |`,
2634
- `| In Progress | ${inProgressInstances.length} |`,
2635
- `| Completed | ${completedInstances.length} |`,
2636
- "",
2637
- "## Active Workflow Definitions",
2473
+ `| Awaiting Action | ${awaitingActionInstances.length} |`,
2474
+ `| Completed | ${instances.filter((i) => i.status === "COMPLETED").length} |`,
2475
+ `| Rejected | ${instances.filter((i) => i.status === "REJECTED").length} |`,
2638
2476
  ""
2639
2477
  ];
2478
+ lines.push("## Visualization Overview");
2479
+ lines.push("");
2480
+ for (const item of [
2481
+ ...visualizations.primaryItems,
2482
+ ...visualizations.comparisonItems
2483
+ ]) {
2484
+ lines.push(`- **${item.title}** via \`${item.spec.meta.key}\``);
2485
+ }
2486
+ lines.push("");
2487
+ lines.push("## Active Workflow Definitions");
2488
+ lines.push("");
2640
2489
  if (activeDefinitions.length === 0) {
2641
2490
  lines.push("_No active workflow definitions._");
2642
2491
  } else {
@@ -2655,8 +2504,9 @@ var workflowDashboardMarkdownRenderer = {
2655
2504
  lines.push("| Workflow | Requested By | Status | Started |");
2656
2505
  lines.push("|----------|--------------|--------|---------|");
2657
2506
  for (const inst of instances.slice(0, 10)) {
2658
- const startedDate = new Date(inst.startedAt).toLocaleDateString();
2659
- lines.push(`| ${inst.definitionName} | ${inst.requestedBy} | ${inst.status} | ${startedDate} |`);
2507
+ const startedDate = formatDate(inst.startedAt);
2508
+ const definitionName = workflowDefinitionById.get(inst.definitionId)?.name ?? inst.definitionId;
2509
+ lines.push(`| ${definitionName} | ${inst.requestedBy} | ${inst.status} | ${startedDate} |`);
2660
2510
  }
2661
2511
  }
2662
2512
  return {
@@ -2672,7 +2522,7 @@ var workflowDefinitionListMarkdownRenderer = {
2672
2522
  if (desc.source.type !== "component" || desc.source.componentKey !== "WorkflowDefinitionList") {
2673
2523
  throw new Error("workflowDefinitionListMarkdownRenderer: not WorkflowDefinitionList");
2674
2524
  }
2675
- const definitions = mockWorkflowDefinitions;
2525
+ const definitions = workflowDefinitions;
2676
2526
  const lines = [
2677
2527
  "# Workflow Definitions",
2678
2528
  "",
@@ -2687,7 +2537,7 @@ var workflowDefinitionListMarkdownRenderer = {
2687
2537
  lines.push("### Steps");
2688
2538
  lines.push("");
2689
2539
  for (const step of def.steps) {
2690
- lines.push(`${step.order}. **${step.name}** - Roles: ${step.requiredRoles.join(", ")}`);
2540
+ lines.push(`${step.stepOrder}. **${step.name}** - Roles: ${step.requiredRoles.join(", ")}`);
2691
2541
  }
2692
2542
  lines.push("");
2693
2543
  }
@@ -2704,7 +2554,7 @@ var workflowInstanceDetailMarkdownRenderer = {
2704
2554
  if (desc.source.type !== "component" || desc.source.componentKey !== "WorkflowInstanceDetail") {
2705
2555
  throw new Error("workflowInstanceDetailMarkdownRenderer: not WorkflowInstanceDetail");
2706
2556
  }
2707
- const instance = mockWorkflowInstances[0];
2557
+ const instance = workflowInstances.find((workflowInstance) => workflowInstance.status === "IN_PROGRESS") ?? workflowInstances[0];
2708
2558
  if (!instance) {
2709
2559
  return {
2710
2560
  mimeType: "text/markdown",
@@ -2713,14 +2563,14 @@ var workflowInstanceDetailMarkdownRenderer = {
2713
2563
  No workflow instances available.`
2714
2564
  };
2715
2565
  }
2716
- const definition = mockWorkflowDefinitions.find((d) => d.id === instance.definitionId);
2566
+ const definition = workflowDefinitions.find((d) => d.id === instance.definitionId);
2717
2567
  const lines = [
2718
- `# Workflow: ${instance.definitionName}`,
2568
+ `# Workflow: ${definition?.name ?? instance.definitionId}`,
2719
2569
  "",
2720
2570
  `**Instance ID:** ${instance.id}`,
2721
2571
  `**Status:** ${instance.status}`,
2722
2572
  `**Requested By:** ${instance.requestedBy}`,
2723
- `**Started:** ${new Date(instance.startedAt).toLocaleString()}`,
2573
+ `**Started:** ${formatDate(instance.startedAt)}`,
2724
2574
  "",
2725
2575
  "## Steps Progress",
2726
2576
  ""
@@ -2741,7 +2591,7 @@ No workflow instances available.`
2741
2591
  lines.push("## Actions");
2742
2592
  lines.push("");
2743
2593
  lines.push("- **Approve** - Move to next step");
2744
- lines.push("- **Reject** - Reject and return");
2594
+ lines.push("- **Reject** - End the workflow with a rejection outcome");
2745
2595
  lines.push("- **Delegate** - Assign to another approver");
2746
2596
  return {
2747
2597
  mimeType: "text/markdown",
@@ -2750,56 +2600,52 @@ No workflow instances available.`
2750
2600
  };
2751
2601
  }
2752
2602
  };
2753
- // src/ui/hooks/useWorkflowList.ts
2754
- import { useCallback, useEffect, useState } from "react";
2755
- import { useTemplateRuntime } from "@contractspec/lib.example-shared-ui";
2603
+ // src/ui/WorkflowDashboard.visualizations.tsx
2604
+ import {
2605
+ ComparisonView,
2606
+ VisualizationCard,
2607
+ VisualizationGrid
2608
+ } from "@contractspec/lib.design-system";
2609
+ import { jsxDEV } from "react/jsx-dev-runtime";
2756
2610
  "use client";
2757
- function useWorkflowList(projectId = "local-project") {
2758
- const { handlers } = useTemplateRuntime();
2759
- const workflow = handlers.workflow;
2760
- const [definitions, setDefinitions] = useState([]);
2761
- const [instances, setInstances] = useState([]);
2762
- const [loading, setLoading] = useState(true);
2763
- const [error, setError] = useState(null);
2764
- const fetchData = useCallback(async () => {
2765
- try {
2766
- setLoading(true);
2767
- setError(null);
2768
- const [defResult, instResult] = await Promise.all([
2769
- workflow.listDefinitions({ projectId, limit: 100 }),
2770
- workflow.listInstances({ projectId, limit: 100 })
2771
- ]);
2772
- setDefinitions(defResult.definitions);
2773
- setInstances(instResult.instances);
2774
- } catch (err) {
2775
- setError(err instanceof Error ? err : new Error("Failed to load workflows"));
2776
- } finally {
2777
- setLoading(false);
2778
- }
2779
- }, [handlers, projectId]);
2780
- useEffect(() => {
2781
- fetchData();
2782
- }, [fetchData]);
2783
- const stats = {
2784
- totalDefinitions: definitions.length,
2785
- activeDefinitions: definitions.filter((d) => d.status === "ACTIVE").length,
2786
- totalInstances: instances.length,
2787
- pendingInstances: instances.filter((i) => i.status === "PENDING").length,
2788
- completedInstances: instances.filter((i) => i.status === "COMPLETED").length,
2789
- rejectedInstances: instances.filter((i) => i.status === "REJECTED").length
2790
- };
2791
- return {
2792
- definitions,
2793
- instances,
2794
- loading,
2795
- error,
2796
- stats,
2797
- refetch: fetchData
2798
- };
2611
+ function WorkflowVisualizationOverview({
2612
+ instances
2613
+ }) {
2614
+ const { primaryItems, comparisonItems } = createWorkflowVisualizationSections(instances);
2615
+ return /* @__PURE__ */ jsxDEV("section", {
2616
+ className: "space-y-4",
2617
+ children: [
2618
+ /* @__PURE__ */ jsxDEV("div", {
2619
+ children: [
2620
+ /* @__PURE__ */ jsxDEV("h3", {
2621
+ className: "font-semibold text-lg",
2622
+ children: "Workflow Visualizations"
2623
+ }, undefined, false, undefined, this),
2624
+ /* @__PURE__ */ jsxDEV("p", {
2625
+ className: "text-muted-foreground text-sm",
2626
+ children: "Contract-backed charts for workflow health and throughput."
2627
+ }, undefined, false, undefined, this)
2628
+ ]
2629
+ }, undefined, true, undefined, this),
2630
+ /* @__PURE__ */ jsxDEV(VisualizationGrid, {
2631
+ children: primaryItems.map((item) => /* @__PURE__ */ jsxDEV(VisualizationCard, {
2632
+ data: item.data,
2633
+ description: item.description,
2634
+ height: item.height,
2635
+ spec: item.spec,
2636
+ title: item.title
2637
+ }, item.key, false, undefined, this))
2638
+ }, undefined, false, undefined, this),
2639
+ /* @__PURE__ */ jsxDEV(ComparisonView, {
2640
+ description: "Shared comparison surface for active versus completed work.",
2641
+ items: comparisonItems,
2642
+ title: "Workload Comparison"
2643
+ }, undefined, false, undefined, this)
2644
+ ]
2645
+ }, undefined, true, undefined, this);
2799
2646
  }
2800
2647
 
2801
2648
  // src/ui/WorkflowDashboard.tsx
2802
- import { useState as useState2 } from "react";
2803
2649
  import {
2804
2650
  Button,
2805
2651
  ErrorState,
@@ -2807,7 +2653,8 @@ import {
2807
2653
  StatCard,
2808
2654
  StatCardGroup
2809
2655
  } from "@contractspec/lib.design-system";
2810
- import { jsxDEV } from "react/jsx-dev-runtime";
2656
+ import { useState as useState2 } from "react";
2657
+ import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
2811
2658
  "use client";
2812
2659
  var STATUS_COLORS = {
2813
2660
  ACTIVE: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400",
@@ -2827,153 +2674,150 @@ function WorkflowDashboard() {
2827
2674
  { id: "instances", label: "Instances", icon: "\uD83D\uDD04" }
2828
2675
  ];
2829
2676
  if (loading) {
2830
- return /* @__PURE__ */ jsxDEV(LoaderBlock, {
2677
+ return /* @__PURE__ */ jsxDEV2(LoaderBlock, {
2831
2678
  label: "Loading Workflows..."
2832
2679
  }, undefined, false, undefined, this);
2833
2680
  }
2834
2681
  if (error) {
2835
- return /* @__PURE__ */ jsxDEV(ErrorState, {
2682
+ return /* @__PURE__ */ jsxDEV2(ErrorState, {
2836
2683
  title: "Failed to load Workflows",
2837
2684
  description: error.message,
2838
2685
  onRetry: refetch,
2839
2686
  retryLabel: "Retry"
2840
2687
  }, undefined, false, undefined, this);
2841
2688
  }
2842
- return /* @__PURE__ */ jsxDEV("div", {
2689
+ return /* @__PURE__ */ jsxDEV2("div", {
2843
2690
  className: "space-y-6",
2844
2691
  children: [
2845
- /* @__PURE__ */ jsxDEV("div", {
2692
+ /* @__PURE__ */ jsxDEV2("div", {
2846
2693
  className: "flex items-center justify-between",
2847
2694
  children: [
2848
- /* @__PURE__ */ jsxDEV("h2", {
2849
- className: "text-2xl font-bold",
2695
+ /* @__PURE__ */ jsxDEV2("h2", {
2696
+ className: "font-bold text-2xl",
2850
2697
  children: "Workflow System"
2851
2698
  }, undefined, false, undefined, this),
2852
- /* @__PURE__ */ jsxDEV(Button, {
2853
- onClick: () => alert("Create workflow modal"),
2854
- children: [
2855
- /* @__PURE__ */ jsxDEV("span", {
2856
- className: "mr-2",
2857
- children: "+"
2858
- }, undefined, false, undefined, this),
2859
- " New Workflow"
2860
- ]
2861
- }, undefined, true, undefined, this)
2699
+ /* @__PURE__ */ jsxDEV2(Button, {
2700
+ onClick: () => void refetch(),
2701
+ children: "Refresh"
2702
+ }, undefined, false, undefined, this)
2862
2703
  ]
2863
2704
  }, undefined, true, undefined, this),
2864
- /* @__PURE__ */ jsxDEV(StatCardGroup, {
2705
+ /* @__PURE__ */ jsxDEV2(StatCardGroup, {
2865
2706
  children: [
2866
- /* @__PURE__ */ jsxDEV(StatCard, {
2707
+ /* @__PURE__ */ jsxDEV2(StatCard, {
2867
2708
  label: "Workflows",
2868
2709
  value: stats.totalDefinitions,
2869
2710
  hint: `${stats.activeDefinitions} active`
2870
2711
  }, undefined, false, undefined, this),
2871
- /* @__PURE__ */ jsxDEV(StatCard, {
2712
+ /* @__PURE__ */ jsxDEV2(StatCard, {
2872
2713
  label: "Instances",
2873
2714
  value: stats.totalInstances,
2874
2715
  hint: "total runs"
2875
2716
  }, undefined, false, undefined, this),
2876
- /* @__PURE__ */ jsxDEV(StatCard, {
2877
- label: "Pending",
2878
- value: stats.pendingInstances,
2879
- hint: "awaiting action"
2717
+ /* @__PURE__ */ jsxDEV2(StatCard, {
2718
+ label: "Awaiting Action",
2719
+ value: stats.pendingInstances + stats.inProgressInstances,
2720
+ hint: "open approvals"
2880
2721
  }, undefined, false, undefined, this),
2881
- /* @__PURE__ */ jsxDEV(StatCard, {
2722
+ /* @__PURE__ */ jsxDEV2(StatCard, {
2882
2723
  label: "Completed",
2883
2724
  value: stats.completedInstances,
2884
2725
  hint: "finished"
2885
2726
  }, undefined, false, undefined, this)
2886
2727
  ]
2887
2728
  }, undefined, true, undefined, this),
2888
- /* @__PURE__ */ jsxDEV("nav", {
2889
- className: "bg-muted flex gap-1 rounded-lg p-1",
2729
+ /* @__PURE__ */ jsxDEV2(WorkflowVisualizationOverview, {
2730
+ instances
2731
+ }, undefined, false, undefined, this),
2732
+ /* @__PURE__ */ jsxDEV2("nav", {
2733
+ className: "flex gap-1 rounded-lg bg-muted p-1",
2890
2734
  role: "tablist",
2891
- children: tabs.map((tab) => /* @__PURE__ */ jsxDEV(Button, {
2735
+ children: tabs.map((tab) => /* @__PURE__ */ jsxDEV2(Button, {
2892
2736
  type: "button",
2893
2737
  role: "tab",
2894
2738
  "aria-selected": activeTab === tab.id,
2895
2739
  onClick: () => setActiveTab(tab.id),
2896
- className: `flex flex-1 items-center justify-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-colors ${activeTab === tab.id ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"}`,
2740
+ className: `flex flex-1 items-center justify-center gap-2 rounded-md px-4 py-2 font-medium text-sm transition-colors ${activeTab === tab.id ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"}`,
2897
2741
  children: [
2898
- /* @__PURE__ */ jsxDEV("span", {
2742
+ /* @__PURE__ */ jsxDEV2("span", {
2899
2743
  children: tab.icon
2900
2744
  }, undefined, false, undefined, this),
2901
2745
  tab.label
2902
2746
  ]
2903
2747
  }, tab.id, true, undefined, this))
2904
2748
  }, undefined, false, undefined, this),
2905
- /* @__PURE__ */ jsxDEV("div", {
2749
+ /* @__PURE__ */ jsxDEV2("div", {
2906
2750
  className: "min-h-[400px]",
2907
2751
  role: "tabpanel",
2908
2752
  children: [
2909
- activeTab === "definitions" && /* @__PURE__ */ jsxDEV("div", {
2910
- className: "border-border rounded-lg border",
2911
- children: /* @__PURE__ */ jsxDEV("table", {
2753
+ activeTab === "definitions" && /* @__PURE__ */ jsxDEV2("div", {
2754
+ className: "rounded-lg border border-border",
2755
+ children: /* @__PURE__ */ jsxDEV2("table", {
2912
2756
  className: "w-full",
2913
2757
  children: [
2914
- /* @__PURE__ */ jsxDEV("thead", {
2915
- className: "border-border bg-muted/30 border-b",
2916
- children: /* @__PURE__ */ jsxDEV("tr", {
2758
+ /* @__PURE__ */ jsxDEV2("thead", {
2759
+ className: "border-border border-b bg-muted/30",
2760
+ children: /* @__PURE__ */ jsxDEV2("tr", {
2917
2761
  children: [
2918
- /* @__PURE__ */ jsxDEV("th", {
2919
- className: "px-4 py-3 text-left text-sm font-medium",
2762
+ /* @__PURE__ */ jsxDEV2("th", {
2763
+ className: "px-4 py-3 text-left font-medium text-sm",
2920
2764
  children: "Name"
2921
2765
  }, undefined, false, undefined, this),
2922
- /* @__PURE__ */ jsxDEV("th", {
2923
- className: "px-4 py-3 text-left text-sm font-medium",
2766
+ /* @__PURE__ */ jsxDEV2("th", {
2767
+ className: "px-4 py-3 text-left font-medium text-sm",
2924
2768
  children: "Type"
2925
2769
  }, undefined, false, undefined, this),
2926
- /* @__PURE__ */ jsxDEV("th", {
2927
- className: "px-4 py-3 text-left text-sm font-medium",
2770
+ /* @__PURE__ */ jsxDEV2("th", {
2771
+ className: "px-4 py-3 text-left font-medium text-sm",
2928
2772
  children: "Status"
2929
2773
  }, undefined, false, undefined, this),
2930
- /* @__PURE__ */ jsxDEV("th", {
2931
- className: "px-4 py-3 text-left text-sm font-medium",
2774
+ /* @__PURE__ */ jsxDEV2("th", {
2775
+ className: "px-4 py-3 text-left font-medium text-sm",
2932
2776
  children: "Created"
2933
2777
  }, undefined, false, undefined, this)
2934
2778
  ]
2935
2779
  }, undefined, true, undefined, this)
2936
2780
  }, undefined, false, undefined, this),
2937
- /* @__PURE__ */ jsxDEV("tbody", {
2938
- className: "divide-border divide-y",
2781
+ /* @__PURE__ */ jsxDEV2("tbody", {
2782
+ className: "divide-y divide-border",
2939
2783
  children: [
2940
- definitions.map((def) => /* @__PURE__ */ jsxDEV("tr", {
2784
+ definitions.map((def) => /* @__PURE__ */ jsxDEV2("tr", {
2941
2785
  className: "hover:bg-muted/50",
2942
2786
  children: [
2943
- /* @__PURE__ */ jsxDEV("td", {
2787
+ /* @__PURE__ */ jsxDEV2("td", {
2944
2788
  className: "px-4 py-3",
2945
2789
  children: [
2946
- /* @__PURE__ */ jsxDEV("div", {
2790
+ /* @__PURE__ */ jsxDEV2("div", {
2947
2791
  className: "font-medium",
2948
2792
  children: def.name
2949
2793
  }, undefined, false, undefined, this),
2950
- /* @__PURE__ */ jsxDEV("div", {
2794
+ /* @__PURE__ */ jsxDEV2("div", {
2951
2795
  className: "text-muted-foreground text-sm",
2952
2796
  children: def.description
2953
2797
  }, undefined, false, undefined, this)
2954
2798
  ]
2955
2799
  }, undefined, true, undefined, this),
2956
- /* @__PURE__ */ jsxDEV("td", {
2800
+ /* @__PURE__ */ jsxDEV2("td", {
2957
2801
  className: "px-4 py-3 font-mono text-sm",
2958
2802
  children: def.type
2959
2803
  }, undefined, false, undefined, this),
2960
- /* @__PURE__ */ jsxDEV("td", {
2804
+ /* @__PURE__ */ jsxDEV2("td", {
2961
2805
  className: "px-4 py-3",
2962
- children: /* @__PURE__ */ jsxDEV("span", {
2963
- className: `inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${STATUS_COLORS[def.status] ?? ""}`,
2806
+ children: /* @__PURE__ */ jsxDEV2("span", {
2807
+ className: `inline-flex rounded-full px-2 py-0.5 font-medium text-xs ${STATUS_COLORS[def.status] ?? ""}`,
2964
2808
  children: def.status
2965
2809
  }, undefined, false, undefined, this)
2966
2810
  }, undefined, false, undefined, this),
2967
- /* @__PURE__ */ jsxDEV("td", {
2968
- className: "text-muted-foreground px-4 py-3 text-sm",
2811
+ /* @__PURE__ */ jsxDEV2("td", {
2812
+ className: "px-4 py-3 text-muted-foreground text-sm",
2969
2813
  children: def.createdAt.toLocaleDateString()
2970
2814
  }, undefined, false, undefined, this)
2971
2815
  ]
2972
2816
  }, def.id, true, undefined, this)),
2973
- definitions.length === 0 && /* @__PURE__ */ jsxDEV("tr", {
2974
- children: /* @__PURE__ */ jsxDEV("td", {
2817
+ definitions.length === 0 && /* @__PURE__ */ jsxDEV2("tr", {
2818
+ children: /* @__PURE__ */ jsxDEV2("td", {
2975
2819
  colSpan: 4,
2976
- className: "text-muted-foreground px-4 py-8 text-center",
2820
+ className: "px-4 py-8 text-center text-muted-foreground",
2977
2821
  children: "No workflow definitions found"
2978
2822
  }, undefined, false, undefined, this)
2979
2823
  }, undefined, false, undefined, this)
@@ -2982,65 +2826,65 @@ function WorkflowDashboard() {
2982
2826
  ]
2983
2827
  }, undefined, true, undefined, this)
2984
2828
  }, undefined, false, undefined, this),
2985
- activeTab === "instances" && /* @__PURE__ */ jsxDEV("div", {
2986
- className: "border-border rounded-lg border",
2987
- children: /* @__PURE__ */ jsxDEV("table", {
2829
+ activeTab === "instances" && /* @__PURE__ */ jsxDEV2("div", {
2830
+ className: "rounded-lg border border-border",
2831
+ children: /* @__PURE__ */ jsxDEV2("table", {
2988
2832
  className: "w-full",
2989
2833
  children: [
2990
- /* @__PURE__ */ jsxDEV("thead", {
2991
- className: "border-border bg-muted/30 border-b",
2992
- children: /* @__PURE__ */ jsxDEV("tr", {
2834
+ /* @__PURE__ */ jsxDEV2("thead", {
2835
+ className: "border-border border-b bg-muted/30",
2836
+ children: /* @__PURE__ */ jsxDEV2("tr", {
2993
2837
  children: [
2994
- /* @__PURE__ */ jsxDEV("th", {
2995
- className: "px-4 py-3 text-left text-sm font-medium",
2838
+ /* @__PURE__ */ jsxDEV2("th", {
2839
+ className: "px-4 py-3 text-left font-medium text-sm",
2996
2840
  children: "Instance ID"
2997
2841
  }, undefined, false, undefined, this),
2998
- /* @__PURE__ */ jsxDEV("th", {
2999
- className: "px-4 py-3 text-left text-sm font-medium",
2842
+ /* @__PURE__ */ jsxDEV2("th", {
2843
+ className: "px-4 py-3 text-left font-medium text-sm",
3000
2844
  children: "Status"
3001
2845
  }, undefined, false, undefined, this),
3002
- /* @__PURE__ */ jsxDEV("th", {
3003
- className: "px-4 py-3 text-left text-sm font-medium",
2846
+ /* @__PURE__ */ jsxDEV2("th", {
2847
+ className: "px-4 py-3 text-left font-medium text-sm",
3004
2848
  children: "Requested By"
3005
2849
  }, undefined, false, undefined, this),
3006
- /* @__PURE__ */ jsxDEV("th", {
3007
- className: "px-4 py-3 text-left text-sm font-medium",
2850
+ /* @__PURE__ */ jsxDEV2("th", {
2851
+ className: "px-4 py-3 text-left font-medium text-sm",
3008
2852
  children: "Started"
3009
2853
  }, undefined, false, undefined, this)
3010
2854
  ]
3011
2855
  }, undefined, true, undefined, this)
3012
2856
  }, undefined, false, undefined, this),
3013
- /* @__PURE__ */ jsxDEV("tbody", {
3014
- className: "divide-border divide-y",
2857
+ /* @__PURE__ */ jsxDEV2("tbody", {
2858
+ className: "divide-y divide-border",
3015
2859
  children: [
3016
- instances.map((inst) => /* @__PURE__ */ jsxDEV("tr", {
2860
+ instances.map((inst) => /* @__PURE__ */ jsxDEV2("tr", {
3017
2861
  className: "hover:bg-muted/50",
3018
2862
  children: [
3019
- /* @__PURE__ */ jsxDEV("td", {
2863
+ /* @__PURE__ */ jsxDEV2("td", {
3020
2864
  className: "px-4 py-3 font-mono text-sm",
3021
2865
  children: inst.id
3022
2866
  }, undefined, false, undefined, this),
3023
- /* @__PURE__ */ jsxDEV("td", {
2867
+ /* @__PURE__ */ jsxDEV2("td", {
3024
2868
  className: "px-4 py-3",
3025
- children: /* @__PURE__ */ jsxDEV("span", {
3026
- className: `inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${STATUS_COLORS[inst.status] ?? ""}`,
2869
+ children: /* @__PURE__ */ jsxDEV2("span", {
2870
+ className: `inline-flex rounded-full px-2 py-0.5 font-medium text-xs ${STATUS_COLORS[inst.status] ?? ""}`,
3027
2871
  children: inst.status
3028
2872
  }, undefined, false, undefined, this)
3029
2873
  }, undefined, false, undefined, this),
3030
- /* @__PURE__ */ jsxDEV("td", {
2874
+ /* @__PURE__ */ jsxDEV2("td", {
3031
2875
  className: "px-4 py-3 text-sm",
3032
2876
  children: inst.requestedBy
3033
2877
  }, undefined, false, undefined, this),
3034
- /* @__PURE__ */ jsxDEV("td", {
3035
- className: "text-muted-foreground px-4 py-3 text-sm",
2878
+ /* @__PURE__ */ jsxDEV2("td", {
2879
+ className: "px-4 py-3 text-muted-foreground text-sm",
3036
2880
  children: inst.startedAt.toLocaleDateString()
3037
2881
  }, undefined, false, undefined, this)
3038
2882
  ]
3039
2883
  }, inst.id, true, undefined, this)),
3040
- instances.length === 0 && /* @__PURE__ */ jsxDEV("tr", {
3041
- children: /* @__PURE__ */ jsxDEV("td", {
2884
+ instances.length === 0 && /* @__PURE__ */ jsxDEV2("tr", {
2885
+ children: /* @__PURE__ */ jsxDEV2("td", {
3042
2886
  colSpan: 4,
3043
- className: "text-muted-foreground px-4 py-8 text-center",
2887
+ className: "px-4 py-8 text-center text-muted-foreground",
3044
2888
  children: "No workflow instances found"
3045
2889
  }, undefined, false, undefined, this)
3046
2890
  }, undefined, false, undefined, this)
@@ -3054,20 +2898,560 @@ function WorkflowDashboard() {
3054
2898
  ]
3055
2899
  }, undefined, true, undefined, this);
3056
2900
  }
2901
+ // src/workflow/workflow.event.ts
2902
+ import { defineEvent as defineEvent3 } from "@contractspec/lib.contracts-spec";
2903
+ import { defineSchemaModel as defineSchemaModel8, ScalarTypeEnum as ScalarTypeEnum8 } from "@contractspec/lib.schema";
2904
+ var WorkflowDefinitionPayload = defineSchemaModel8({
2905
+ name: "WorkflowDefinitionEventPayload",
2906
+ description: "Payload for workflow definition events",
2907
+ fields: {
2908
+ workflowId: { type: ScalarTypeEnum8.String_unsecure(), isOptional: false },
2909
+ key: { type: ScalarTypeEnum8.String_unsecure(), isOptional: false },
2910
+ name: { type: ScalarTypeEnum8.String_unsecure(), isOptional: false },
2911
+ version: { type: ScalarTypeEnum8.String_unsecure(), isOptional: false },
2912
+ organizationId: {
2913
+ type: ScalarTypeEnum8.String_unsecure(),
2914
+ isOptional: false
2915
+ },
2916
+ createdBy: { type: ScalarTypeEnum8.String_unsecure(), isOptional: false },
2917
+ timestamp: { type: ScalarTypeEnum8.DateTime(), isOptional: false }
2918
+ }
2919
+ });
2920
+ var StepAddedPayload = defineSchemaModel8({
2921
+ name: "StepAddedEventPayload",
2922
+ description: "Payload when a step is added",
2923
+ fields: {
2924
+ stepId: { type: ScalarTypeEnum8.String_unsecure(), isOptional: false },
2925
+ workflowId: { type: ScalarTypeEnum8.String_unsecure(), isOptional: false },
2926
+ stepKey: { type: ScalarTypeEnum8.String_unsecure(), isOptional: false },
2927
+ stepType: { type: ScalarTypeEnum8.String_unsecure(), isOptional: false },
2928
+ position: { type: ScalarTypeEnum8.Int_unsecure(), isOptional: false },
2929
+ timestamp: { type: ScalarTypeEnum8.DateTime(), isOptional: false }
2930
+ }
2931
+ });
2932
+ var WorkflowCreatedEvent = defineEvent3({
2933
+ meta: {
2934
+ key: "workflow.definition.created",
2935
+ version: "1.0.0",
2936
+ description: "A new workflow definition has been created.",
2937
+ stability: "stable",
2938
+ owners: ["@workflow-team"],
2939
+ tags: ["workflow", "definition", "created"]
2940
+ },
2941
+ payload: WorkflowDefinitionPayload
2942
+ });
2943
+ var WorkflowUpdatedEvent = defineEvent3({
2944
+ meta: {
2945
+ key: "workflow.definition.updated",
2946
+ version: "1.0.0",
2947
+ description: "A workflow definition has been updated.",
2948
+ stability: "stable",
2949
+ owners: ["@workflow-team"],
2950
+ tags: ["workflow", "definition", "updated"]
2951
+ },
2952
+ payload: WorkflowDefinitionPayload
2953
+ });
2954
+ var WorkflowPublishedEvent = defineEvent3({
2955
+ meta: {
2956
+ key: "workflow.definition.published",
2957
+ version: "1.0.0",
2958
+ description: "A workflow definition has been published and is now active.",
2959
+ stability: "stable",
2960
+ owners: ["@workflow-team"],
2961
+ tags: ["workflow", "definition", "published"]
2962
+ },
2963
+ payload: WorkflowDefinitionPayload
2964
+ });
2965
+ var StepAddedEvent = defineEvent3({
2966
+ meta: {
2967
+ key: "workflow.step.added",
2968
+ version: "1.0.0",
2969
+ description: "A step has been added to a workflow definition.",
2970
+ stability: "stable",
2971
+ owners: ["@workflow-team"],
2972
+ tags: ["workflow", "step", "added"]
2973
+ },
2974
+ payload: StepAddedPayload
2975
+ });
3057
2976
 
3058
- // src/ui/hooks/index.ts
3059
- "use client";
2977
+ // src/workflow/workflow.operations.ts
2978
+ import {
2979
+ defineCommand as defineCommand3,
2980
+ defineQuery as defineQuery3
2981
+ } from "@contractspec/lib.contracts-spec/operations";
2982
+ import { defineSchemaModel as defineSchemaModel9, ScalarTypeEnum as ScalarTypeEnum9 } from "@contractspec/lib.schema";
2983
+ var OWNERS3 = ["@example.workflow-system"];
2984
+ var CreateWorkflowContract = defineCommand3({
2985
+ meta: {
2986
+ key: "workflow.definition.create",
2987
+ version: "1.0.0",
2988
+ stability: "stable",
2989
+ owners: [...OWNERS3],
2990
+ tags: ["workflow", "definition", "create"],
2991
+ description: "Create a new workflow definition.",
2992
+ goal: "Allow users to define new workflow blueprints.",
2993
+ context: "Workflow designer, admin panel."
2994
+ },
2995
+ io: {
2996
+ input: CreateWorkflowInputModel,
2997
+ output: WorkflowDefinitionModel
2998
+ },
2999
+ policy: { auth: "user" },
3000
+ sideEffects: {
3001
+ emits: [
3002
+ {
3003
+ key: "workflow.definition.created",
3004
+ version: "1.0.0",
3005
+ when: "Workflow is created",
3006
+ payload: WorkflowDefinitionModel
3007
+ }
3008
+ ],
3009
+ audit: ["workflow.definition.created"]
3010
+ },
3011
+ acceptance: {
3012
+ scenarios: [
3013
+ {
3014
+ key: "create-workflow-happy-path",
3015
+ given: ["User is admin"],
3016
+ when: ["User creates new workflow definition"],
3017
+ then: [
3018
+ "Definition is created",
3019
+ "WorkflowDefinitionCreated event is emitted"
3020
+ ]
3021
+ }
3022
+ ],
3023
+ examples: [
3024
+ {
3025
+ key: "create-onboarding",
3026
+ input: {
3027
+ key: "onboarding-v1",
3028
+ name: "Employee Onboarding",
3029
+ version: "1.0.0"
3030
+ },
3031
+ output: { id: "def-123", status: "draft" }
3032
+ }
3033
+ ]
3034
+ }
3035
+ });
3036
+ var UpdateWorkflowContract = defineCommand3({
3037
+ meta: {
3038
+ key: "workflow.definition.update",
3039
+ version: "1.0.0",
3040
+ stability: "stable",
3041
+ owners: [...OWNERS3],
3042
+ tags: ["workflow", "definition", "update"],
3043
+ description: "Update an existing workflow definition.",
3044
+ goal: "Allow users to modify workflow blueprints.",
3045
+ context: "Workflow designer."
3046
+ },
3047
+ io: {
3048
+ input: UpdateWorkflowInputModel,
3049
+ output: WorkflowDefinitionModel
3050
+ },
3051
+ policy: { auth: "user" },
3052
+ sideEffects: {
3053
+ emits: [
3054
+ {
3055
+ key: "workflow.definition.updated",
3056
+ version: "1.0.0",
3057
+ when: "Workflow is updated",
3058
+ payload: WorkflowDefinitionModel
3059
+ }
3060
+ ],
3061
+ audit: ["workflow.definition.updated"]
3062
+ },
3063
+ acceptance: {
3064
+ scenarios: [
3065
+ {
3066
+ key: "update-workflow-happy-path",
3067
+ given: ["Workflow definition exists"],
3068
+ when: ["User updates definition"],
3069
+ then: [
3070
+ "Definition is updated",
3071
+ "WorkflowDefinitionUpdated event is emitted"
3072
+ ]
3073
+ }
3074
+ ],
3075
+ examples: [
3076
+ {
3077
+ key: "update-name",
3078
+ input: { workflowId: "def-123", name: "New Employee Onboarding" },
3079
+ output: { id: "def-123", name: "New Employee Onboarding" }
3080
+ }
3081
+ ]
3082
+ }
3083
+ });
3084
+ var AddStepContract = defineCommand3({
3085
+ meta: {
3086
+ key: "workflow.step.add",
3087
+ version: "1.0.0",
3088
+ stability: "stable",
3089
+ owners: [...OWNERS3],
3090
+ tags: ["workflow", "step", "add"],
3091
+ description: "Add a step to a workflow definition.",
3092
+ goal: "Build workflow structure step by step.",
3093
+ context: "Workflow designer."
3094
+ },
3095
+ io: {
3096
+ input: AddStepInputModel,
3097
+ output: WorkflowStepModel
3098
+ },
3099
+ policy: { auth: "user" },
3100
+ sideEffects: {
3101
+ emits: [
3102
+ {
3103
+ key: "workflow.step.added",
3104
+ version: "1.0.0",
3105
+ when: "Step is added",
3106
+ payload: WorkflowStepModel
3107
+ }
3108
+ ],
3109
+ audit: ["workflow.step.added"]
3110
+ },
3111
+ acceptance: {
3112
+ scenarios: [
3113
+ {
3114
+ key: "add-step-happy-path",
3115
+ given: ["Workflow definition exists"],
3116
+ when: ["User adds a step"],
3117
+ then: ["Step is added", "StepAdded event is emitted"]
3118
+ }
3119
+ ],
3120
+ examples: [
3121
+ {
3122
+ key: "add-approval-step",
3123
+ input: {
3124
+ workflowId: "def-123",
3125
+ stepKey: "approve-contract",
3126
+ type: "approval"
3127
+ },
3128
+ output: { id: "step-456", key: "approve-contract" }
3129
+ }
3130
+ ]
3131
+ }
3132
+ });
3133
+ var PublishWorkflowContract = defineCommand3({
3134
+ meta: {
3135
+ key: "workflow.definition.publish",
3136
+ version: "1.0.0",
3137
+ stability: "stable",
3138
+ owners: [...OWNERS3],
3139
+ tags: ["workflow", "definition", "publish"],
3140
+ description: "Publish a workflow definition to make it available for use.",
3141
+ goal: "Activate workflow for production use.",
3142
+ context: "Workflow designer, deployment."
3143
+ },
3144
+ io: {
3145
+ input: defineSchemaModel9({
3146
+ name: "PublishWorkflowInput",
3147
+ fields: {
3148
+ workflowId: {
3149
+ type: ScalarTypeEnum9.String_unsecure(),
3150
+ isOptional: false
3151
+ }
3152
+ }
3153
+ }),
3154
+ output: WorkflowDefinitionModel
3155
+ },
3156
+ policy: { auth: "user" },
3157
+ sideEffects: {
3158
+ emits: [
3159
+ {
3160
+ key: "workflow.definition.published",
3161
+ version: "1.0.0",
3162
+ when: "Workflow is published",
3163
+ payload: WorkflowDefinitionModel
3164
+ }
3165
+ ],
3166
+ audit: ["workflow.definition.published"]
3167
+ },
3168
+ acceptance: {
3169
+ scenarios: [
3170
+ {
3171
+ key: "publish-workflow-happy-path",
3172
+ given: ["Workflow definition is valid"],
3173
+ when: ["User publishes workflow"],
3174
+ then: ["Workflow becomes active", "WorkflowPublished event is emitted"]
3175
+ }
3176
+ ],
3177
+ examples: [
3178
+ {
3179
+ key: "publish-onboarding",
3180
+ input: { workflowId: "def-123" },
3181
+ output: { id: "def-123", status: "published" }
3182
+ }
3183
+ ]
3184
+ }
3185
+ });
3186
+ var ListWorkflowsContract = defineQuery3({
3187
+ meta: {
3188
+ key: "workflow.definition.list",
3189
+ version: "1.0.0",
3190
+ stability: "stable",
3191
+ owners: [...OWNERS3],
3192
+ tags: ["workflow", "definition", "list"],
3193
+ description: "List workflow definitions with filtering.",
3194
+ goal: "Browse and search available workflows.",
3195
+ context: "Workflow list, search."
3196
+ },
3197
+ io: {
3198
+ input: defineSchemaModel9({
3199
+ name: "ListWorkflowsInput",
3200
+ fields: {
3201
+ status: { type: WorkflowStatusEnum, isOptional: true },
3202
+ search: { type: ScalarTypeEnum9.String_unsecure(), isOptional: true },
3203
+ limit: {
3204
+ type: ScalarTypeEnum9.Int_unsecure(),
3205
+ isOptional: true,
3206
+ defaultValue: 20
3207
+ },
3208
+ offset: {
3209
+ type: ScalarTypeEnum9.Int_unsecure(),
3210
+ isOptional: true,
3211
+ defaultValue: 0
3212
+ }
3213
+ }
3214
+ }),
3215
+ output: defineSchemaModel9({
3216
+ name: "ListWorkflowsOutput",
3217
+ fields: {
3218
+ workflows: {
3219
+ type: WorkflowDefinitionModel,
3220
+ isArray: true,
3221
+ isOptional: false
3222
+ },
3223
+ total: { type: ScalarTypeEnum9.Int_unsecure(), isOptional: false }
3224
+ }
3225
+ })
3226
+ },
3227
+ policy: { auth: "user" },
3228
+ acceptance: {
3229
+ scenarios: [
3230
+ {
3231
+ key: "list-workflows-happy-path",
3232
+ given: ["Workflow definitions exist"],
3233
+ when: ["User lists workflows"],
3234
+ then: ["List of workflows is returned"]
3235
+ }
3236
+ ],
3237
+ examples: [
3238
+ {
3239
+ key: "list-all",
3240
+ input: { limit: 10 },
3241
+ output: { workflows: [], total: 5 }
3242
+ }
3243
+ ]
3244
+ }
3245
+ });
3246
+ var GetWorkflowContract = defineQuery3({
3247
+ meta: {
3248
+ key: "workflow.definition.get",
3249
+ version: "1.0.0",
3250
+ stability: "stable",
3251
+ owners: [...OWNERS3],
3252
+ tags: ["workflow", "definition", "get"],
3253
+ description: "Get a workflow definition with all steps.",
3254
+ goal: "View workflow details.",
3255
+ context: "Workflow designer, detail view."
3256
+ },
3257
+ io: {
3258
+ input: defineSchemaModel9({
3259
+ name: "GetWorkflowInput",
3260
+ fields: {
3261
+ workflowId: {
3262
+ type: ScalarTypeEnum9.String_unsecure(),
3263
+ isOptional: false
3264
+ }
3265
+ }
3266
+ }),
3267
+ output: WorkflowDefinitionModel
3268
+ },
3269
+ policy: { auth: "user" },
3270
+ acceptance: {
3271
+ scenarios: [
3272
+ {
3273
+ key: "get-workflow-happy-path",
3274
+ given: ["Workflow definition exists"],
3275
+ when: ["User requests workflow details"],
3276
+ then: ["Workflow details are returned"]
3277
+ }
3278
+ ],
3279
+ examples: [
3280
+ {
3281
+ key: "get-details",
3282
+ input: { workflowId: "def-123" },
3283
+ output: { id: "def-123", name: "Employee Onboarding" }
3284
+ }
3285
+ ]
3286
+ }
3287
+ });
3288
+ // src/workflow-system.feature.ts
3289
+ import { defineFeature } from "@contractspec/lib.contracts-spec";
3290
+ var WorkflowSystemFeature = defineFeature({
3291
+ meta: {
3292
+ key: "workflow-system",
3293
+ title: "Workflow & Approval System",
3294
+ description: "State machine-based workflow engine with role-based approvals, delegation, and escalation",
3295
+ domain: "workflow",
3296
+ owners: ["@workflow-team"],
3297
+ tags: ["workflow", "approval", "state-machine", "automation"],
3298
+ stability: "experimental",
3299
+ version: "1.0.0"
3300
+ },
3301
+ operations: [
3302
+ { key: "workflow.definition.create", version: "1.0.0" },
3303
+ { key: "workflow.definition.update", version: "1.0.0" },
3304
+ { key: "workflow.step.add", version: "1.0.0" },
3305
+ { key: "workflow.definition.publish", version: "1.0.0" },
3306
+ { key: "workflow.definition.list", version: "1.0.0" },
3307
+ { key: "workflow.definition.get", version: "1.0.0" },
3308
+ { key: "workflow.instance.start", version: "1.0.0" },
3309
+ { key: "workflow.instance.transition", version: "1.0.0" },
3310
+ { key: "workflow.instance.pause", version: "1.0.0" },
3311
+ { key: "workflow.instance.resume", version: "1.0.0" },
3312
+ { key: "workflow.instance.cancel", version: "1.0.0" },
3313
+ { key: "workflow.instance.list", version: "1.0.0" },
3314
+ { key: "workflow.instance.get", version: "1.0.0" },
3315
+ { key: "workflow.approval.decide", version: "1.0.0" },
3316
+ { key: "workflow.approval.delegate", version: "1.0.0" },
3317
+ { key: "workflow.approval.comment.add", version: "1.0.0" },
3318
+ { key: "workflow.approval.list.mine", version: "1.0.0" },
3319
+ { key: "workflow.approval.get", version: "1.0.0" }
3320
+ ],
3321
+ events: [
3322
+ { key: "workflow.definition.created", version: "1.0.0" },
3323
+ { key: "workflow.definition.updated", version: "1.0.0" },
3324
+ { key: "workflow.definition.published", version: "1.0.0" },
3325
+ { key: "workflow.step.added", version: "1.0.0" },
3326
+ { key: "workflow.instance.started", version: "1.0.0" },
3327
+ { key: "workflow.step.entered", version: "1.0.0" },
3328
+ { key: "workflow.step.exited", version: "1.0.0" },
3329
+ { key: "workflow.instance.completed", version: "1.0.0" },
3330
+ { key: "workflow.instance.cancelled", version: "1.0.0" },
3331
+ { key: "workflow.instance.paused", version: "1.0.0" },
3332
+ { key: "workflow.instance.resumed", version: "1.0.0" },
3333
+ { key: "workflow.instance.failed", version: "1.0.0" },
3334
+ { key: "workflow.instance.timedOut", version: "1.0.0" },
3335
+ { key: "workflow.approval.requested", version: "1.0.0" },
3336
+ { key: "workflow.approval.decided", version: "1.0.0" },
3337
+ { key: "workflow.approval.delegated", version: "1.0.0" },
3338
+ { key: "workflow.approval.escalated", version: "1.0.0" }
3339
+ ],
3340
+ presentations: [
3341
+ { key: "workflow.designer", version: "1.0.0" },
3342
+ { key: "workflow.definition.viewList", version: "1.0.0" },
3343
+ { key: "workflow.definition.detail", version: "1.0.0" },
3344
+ { key: "workflow.instance.viewList", version: "1.0.0" },
3345
+ { key: "workflow.instance.detail", version: "1.0.0" },
3346
+ { key: "workflow.instance.progress", version: "1.0.0" },
3347
+ { key: "workflow.approval.inbox", version: "1.0.0" },
3348
+ { key: "workflow.approval.detail", version: "1.0.0" },
3349
+ { key: "workflow.approval.form", version: "1.0.0" },
3350
+ { key: "workflow.approval.badge", version: "1.0.0" },
3351
+ { key: "workflow.metrics", version: "1.0.0" }
3352
+ ],
3353
+ opToPresentation: [
3354
+ {
3355
+ op: { key: "workflow.definition.list", version: "1.0.0" },
3356
+ pres: { key: "workflow.definition.viewList", version: "1.0.0" }
3357
+ },
3358
+ {
3359
+ op: { key: "workflow.instance.list", version: "1.0.0" },
3360
+ pres: { key: "workflow.instance.viewList", version: "1.0.0" }
3361
+ },
3362
+ {
3363
+ op: { key: "workflow.approval.list.mine", version: "1.0.0" },
3364
+ pres: { key: "workflow.approval.inbox", version: "1.0.0" }
3365
+ },
3366
+ {
3367
+ op: { key: "workflow.approval.decide", version: "1.0.0" },
3368
+ pres: { key: "workflow.approval.form", version: "1.0.0" }
3369
+ }
3370
+ ],
3371
+ presentationsTargets: [
3372
+ { key: "workflow.designer", version: "1.0.0", targets: ["react"] },
3373
+ {
3374
+ key: "workflow.definition.viewList",
3375
+ version: "1.0.0",
3376
+ targets: ["react", "markdown"]
3377
+ },
3378
+ {
3379
+ key: "workflow.definition.detail",
3380
+ version: "1.0.0",
3381
+ targets: ["react", "markdown"]
3382
+ },
3383
+ {
3384
+ key: "workflow.instance.viewList",
3385
+ version: "1.0.0",
3386
+ targets: ["react", "markdown"]
3387
+ },
3388
+ {
3389
+ key: "workflow.instance.detail",
3390
+ version: "1.0.0",
3391
+ targets: ["react", "markdown"]
3392
+ },
3393
+ { key: "workflow.instance.progress", version: "1.0.0", targets: ["react"] },
3394
+ {
3395
+ key: "workflow.approval.inbox",
3396
+ version: "1.0.0",
3397
+ targets: ["react", "markdown"]
3398
+ },
3399
+ {
3400
+ key: "workflow.approval.detail",
3401
+ version: "1.0.0",
3402
+ targets: ["react", "markdown"]
3403
+ },
3404
+ {
3405
+ key: "workflow.metrics",
3406
+ version: "1.0.0",
3407
+ targets: ["react", "markdown"]
3408
+ }
3409
+ ],
3410
+ visualizations: WorkflowVisualizationRefs,
3411
+ capabilities: {
3412
+ requires: [
3413
+ { key: "identity", version: "1.0.0" },
3414
+ { key: "audit-trail", version: "1.0.0" },
3415
+ { key: "notifications", version: "1.0.0" },
3416
+ { key: "feature-flags", version: "1.0.0" }
3417
+ ],
3418
+ provides: [
3419
+ { key: "workflow", version: "1.0.0" },
3420
+ { key: "approval", version: "1.0.0" },
3421
+ { key: "state-machine", version: "1.0.0" }
3422
+ ]
3423
+ },
3424
+ workflows: [
3425
+ { key: "workflow-system.workflow.approval-chain", version: "1.0.0" }
3426
+ ],
3427
+ telemetry: [{ key: "workflow-system.telemetry", version: "1.0.0" }],
3428
+ jobs: [
3429
+ { key: "workflow-system.job.instance-timeout", version: "1.0.0" },
3430
+ { key: "workflow-system.job.escalation", version: "1.0.0" }
3431
+ ],
3432
+ docs: [
3433
+ "docs.examples.workflow-system",
3434
+ "docs.examples.workflow-system.goal",
3435
+ "docs.examples.workflow-system.usage",
3436
+ "docs.examples.workflow-system.constraints"
3437
+ ]
3438
+ });
3060
3439
  export {
3061
3440
  workflowInstanceDetailMarkdownRenderer,
3062
3441
  workflowDefinitionListMarkdownRenderer,
3063
3442
  workflowDashboardMarkdownRenderer,
3064
3443
  useWorkflowList,
3065
3444
  mockDataStore,
3445
+ createWorkflowVisualizationSections,
3066
3446
  createWorkflowHandlers,
3067
3447
  createStateMachineEngine,
3068
3448
  createInitialState,
3069
3449
  buildStateMachineDefinition,
3450
+ WorkflowVisualizationSpecs,
3451
+ WorkflowVisualizationRegistry,
3452
+ WorkflowVisualizationRefs,
3070
3453
  WorkflowUpdatedEvent,
3454
+ WorkflowThroughputVisualization,
3071
3455
  WorkflowSystemPresentations,
3072
3456
  WorkflowSystemFeature,
3073
3457
  WorkflowStepModel,
@@ -3075,12 +3459,15 @@ export {
3075
3459
  WorkflowPublishedEvent,
3076
3460
  WorkflowMetricsPresentation,
3077
3461
  WorkflowListPresentation,
3462
+ WorkflowInstanceStatusVisualization,
3078
3463
  WorkflowInstanceModel,
3079
3464
  WorkflowDetailPresentation,
3080
3465
  WorkflowDesignerPresentation,
3081
3466
  WorkflowDefinitionModel,
3082
3467
  WorkflowDashboard,
3083
3468
  WorkflowCreatedEvent,
3469
+ WorkflowCompletedMetricVisualization,
3470
+ WorkflowActiveMetricVisualization,
3084
3471
  UpdateWorkflowInputModel,
3085
3472
  UpdateWorkflowContract,
3086
3473
  TriggerTypeEnum,