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