@auto-engineer/pipeline 1.68.0 → 1.70.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-test.log +6 -6
  3. package/.turbo/turbo-type-check.log +1 -1
  4. package/CHANGELOG.md +63 -0
  5. package/dist/src/engine/workflow-processor.d.ts +3 -0
  6. package/dist/src/engine/workflow-processor.d.ts.map +1 -1
  7. package/dist/src/engine/workflow-processor.js +50 -7
  8. package/dist/src/engine/workflow-processor.js.map +1 -1
  9. package/dist/src/index.d.ts +0 -2
  10. package/dist/src/index.d.ts.map +1 -1
  11. package/dist/src/index.js +0 -2
  12. package/dist/src/index.js.map +1 -1
  13. package/dist/src/server/phased-bridge.d.ts +13 -0
  14. package/dist/src/server/phased-bridge.d.ts.map +1 -0
  15. package/dist/src/server/phased-bridge.js +103 -0
  16. package/dist/src/server/phased-bridge.js.map +1 -0
  17. package/dist/src/server/pipeline-server.d.ts +2 -2
  18. package/dist/src/server/pipeline-server.d.ts.map +1 -1
  19. package/dist/src/server/pipeline-server.js +19 -39
  20. package/dist/src/server/pipeline-server.js.map +1 -1
  21. package/dist/src/server/v2-runtime-bridge.d.ts +21 -0
  22. package/dist/src/server/v2-runtime-bridge.d.ts.map +1 -0
  23. package/dist/src/server/v2-runtime-bridge.js +184 -0
  24. package/dist/src/server/v2-runtime-bridge.js.map +1 -0
  25. package/dist/src/store/pipeline-event-store.d.ts.map +1 -1
  26. package/dist/src/store/pipeline-event-store.js +0 -30
  27. package/dist/src/store/pipeline-event-store.js.map +1 -1
  28. package/dist/src/store/pipeline-read-model.d.ts +0 -15
  29. package/dist/src/store/pipeline-read-model.d.ts.map +1 -1
  30. package/dist/src/store/pipeline-read-model.js +0 -49
  31. package/dist/src/store/pipeline-read-model.js.map +1 -1
  32. package/dist/tsconfig.tsbuildinfo +1 -1
  33. package/ketchup-plan.md +10 -12
  34. package/package.json +3 -3
  35. package/src/engine/workflow-processor.specs.ts +101 -0
  36. package/src/engine/workflow-processor.ts +54 -8
  37. package/src/index.ts +0 -2
  38. package/src/server/phased-bridge.specs.ts +272 -0
  39. package/src/server/phased-bridge.ts +130 -0
  40. package/src/server/pipeline-server.specs.ts +94 -0
  41. package/src/server/pipeline-server.ts +21 -42
  42. package/src/server/v2-runtime-bridge.specs.ts +347 -0
  43. package/src/server/v2-runtime-bridge.ts +255 -0
  44. package/src/store/pipeline-event-store.specs.ts +0 -137
  45. package/src/store/pipeline-event-store.ts +0 -35
  46. package/src/store/pipeline-read-model.specs.ts +0 -567
  47. package/src/store/pipeline-read-model.ts +0 -71
  48. package/dist/src/projections/phased-execution-projection.d.ts +0 -77
  49. package/dist/src/projections/phased-execution-projection.d.ts.map +0 -1
  50. package/dist/src/projections/phased-execution-projection.js +0 -54
  51. package/dist/src/projections/phased-execution-projection.js.map +0 -1
  52. package/dist/src/projections/settled-instance-projection.d.ts +0 -67
  53. package/dist/src/projections/settled-instance-projection.d.ts.map +0 -1
  54. package/dist/src/projections/settled-instance-projection.js +0 -66
  55. package/dist/src/projections/settled-instance-projection.js.map +0 -1
  56. package/dist/src/runtime/phased-executor.d.ts +0 -34
  57. package/dist/src/runtime/phased-executor.d.ts.map +0 -1
  58. package/dist/src/runtime/phased-executor.js +0 -172
  59. package/dist/src/runtime/phased-executor.js.map +0 -1
  60. package/dist/src/runtime/settled-tracker.d.ts +0 -44
  61. package/dist/src/runtime/settled-tracker.d.ts.map +0 -1
  62. package/dist/src/runtime/settled-tracker.js +0 -170
  63. package/dist/src/runtime/settled-tracker.js.map +0 -1
  64. package/src/projections/phased-execution-projection.specs.ts +0 -202
  65. package/src/projections/phased-execution-projection.ts +0 -146
  66. package/src/projections/settled-instance-projection.specs.ts +0 -296
  67. package/src/projections/settled-instance-projection.ts +0 -160
  68. package/src/runtime/phased-executor.specs.ts +0 -680
  69. package/src/runtime/phased-executor.ts +0 -230
  70. package/src/runtime/settled-tracker.specs.ts +0 -1044
  71. package/src/runtime/settled-tracker.ts +0 -235
@@ -3,8 +3,6 @@ import { beforeEach, describe, expect, it } from 'vitest';
3
3
  import type { ItemStatusDocument } from '../projections/item-status-projection';
4
4
  import type { MessageLogDocument } from '../projections/message-log-projection';
5
5
  import type { NodeStatusDocument } from '../projections/node-status-projection';
6
- import type { PhasedExecutionDocument } from '../projections/phased-execution-projection';
7
- import type { SettledInstanceDocument } from '../projections/settled-instance-projection';
8
6
  import type { StatsDocument } from '../projections/stats-projection';
9
7
  import { PipelineReadModel } from './pipeline-read-model';
10
8
 
@@ -602,569 +600,4 @@ describe('PipelineReadModel', () => {
602
600
  });
603
601
  });
604
602
  });
605
-
606
- describe('getSettledInstance', () => {
607
- it('should return null when no settled instance exists', async () => {
608
- const result = await readModel.getSettledInstance('template-CmdA', 'c1');
609
-
610
- expect(result).toBeNull();
611
- });
612
-
613
- it('should return settled instance from collection', async () => {
614
- const collection = database.collection<WithId<SettledInstanceDocument>>('SettledInstance');
615
- await collection.insertOne({
616
- _id: 'template-CmdA-c1',
617
- instanceId: 'template-CmdA-c1',
618
- templateId: 'template-CmdA',
619
- correlationId: 'c1',
620
- commandTrackers: [{ commandType: 'CmdA', hasStarted: true, hasCompleted: false, events: [] }],
621
- status: 'active',
622
- firedCount: 0,
623
- });
624
-
625
- const result = await readModel.getSettledInstance('template-CmdA', 'c1');
626
-
627
- expect(result).toMatchObject({
628
- instanceId: 'template-CmdA-c1',
629
- templateId: 'template-CmdA',
630
- correlationId: 'c1',
631
- status: 'active',
632
- });
633
- });
634
-
635
- it('should return null for different templateId', async () => {
636
- const collection = database.collection<WithId<SettledInstanceDocument>>('SettledInstance');
637
- await collection.insertOne({
638
- _id: 'template-CmdA-c1',
639
- instanceId: 'template-CmdA-c1',
640
- templateId: 'template-CmdA',
641
- correlationId: 'c1',
642
- commandTrackers: [],
643
- status: 'active',
644
- firedCount: 0,
645
- });
646
-
647
- const result = await readModel.getSettledInstance('template-CmdB', 'c1');
648
-
649
- expect(result).toBeNull();
650
- });
651
-
652
- it('should return null for different correlationId', async () => {
653
- const collection = database.collection<WithId<SettledInstanceDocument>>('SettledInstance');
654
- await collection.insertOne({
655
- _id: 'template-CmdA-c1',
656
- instanceId: 'template-CmdA-c1',
657
- templateId: 'template-CmdA',
658
- correlationId: 'c1',
659
- commandTrackers: [],
660
- status: 'active',
661
- firedCount: 0,
662
- });
663
-
664
- const result = await readModel.getSettledInstance('template-CmdA', 'c2');
665
-
666
- expect(result).toBeNull();
667
- });
668
- });
669
-
670
- describe('getActiveSettledInstances', () => {
671
- it('should return empty array when no instances exist', async () => {
672
- const result = await readModel.getActiveSettledInstances('c1');
673
-
674
- expect(result).toEqual([]);
675
- });
676
-
677
- it('should return only active instances for correlationId', async () => {
678
- const collection = database.collection<WithId<SettledInstanceDocument>>('SettledInstance');
679
- await collection.insertOne({
680
- _id: 'template-CmdA-c1',
681
- instanceId: 'template-CmdA-c1',
682
- templateId: 'template-CmdA',
683
- correlationId: 'c1',
684
- commandTrackers: [],
685
- status: 'active',
686
- firedCount: 0,
687
- });
688
- await collection.insertOne({
689
- _id: 'template-CmdB-c1',
690
- instanceId: 'template-CmdB-c1',
691
- templateId: 'template-CmdB',
692
- correlationId: 'c1',
693
- commandTrackers: [],
694
- status: 'fired',
695
- firedCount: 1,
696
- });
697
-
698
- const result = await readModel.getActiveSettledInstances('c1');
699
-
700
- expect(result).toHaveLength(1);
701
- expect(result[0].templateId).toBe('template-CmdA');
702
- });
703
-
704
- it('should filter by correlationId', async () => {
705
- const collection = database.collection<WithId<SettledInstanceDocument>>('SettledInstance');
706
- await collection.insertOne({
707
- _id: 'template-CmdA-c1',
708
- instanceId: 'template-CmdA-c1',
709
- templateId: 'template-CmdA',
710
- correlationId: 'c1',
711
- commandTrackers: [],
712
- status: 'active',
713
- firedCount: 0,
714
- });
715
- await collection.insertOne({
716
- _id: 'template-CmdA-c2',
717
- instanceId: 'template-CmdA-c2',
718
- templateId: 'template-CmdA',
719
- correlationId: 'c2',
720
- commandTrackers: [],
721
- status: 'active',
722
- firedCount: 0,
723
- });
724
-
725
- const result = await readModel.getActiveSettledInstances('c1');
726
-
727
- expect(result).toHaveLength(1);
728
- expect(result[0].correlationId).toBe('c1');
729
- });
730
-
731
- it('should exclude cleaned instances', async () => {
732
- const collection = database.collection<WithId<SettledInstanceDocument>>('SettledInstance');
733
- await collection.insertOne({
734
- _id: 'template-CmdA-c1',
735
- instanceId: 'template-CmdA-c1',
736
- templateId: 'template-CmdA',
737
- correlationId: 'c1',
738
- commandTrackers: [],
739
- status: 'cleaned',
740
- firedCount: 0,
741
- });
742
-
743
- const result = await readModel.getActiveSettledInstances('c1');
744
-
745
- expect(result).toEqual([]);
746
- });
747
- });
748
-
749
- describe('getPhasedExecution', () => {
750
- it('should return null when no execution exists', async () => {
751
- const result = await readModel.getPhasedExecution('exec-1');
752
-
753
- expect(result).toBeNull();
754
- });
755
-
756
- it('should return execution from collection', async () => {
757
- const collection = database.collection<WithId<PhasedExecutionDocument>>('PhasedExecution');
758
- const triggerEvent = { type: 'TestEvent', correlationId: 'c1', data: {} };
759
- await collection.insertOne({
760
- _id: 'exec-1',
761
- executionId: 'exec-1',
762
- correlationId: 'c1',
763
- handlerId: 'handler-1',
764
- triggerEvent,
765
- items: [{ key: 'a', phase: 'prepare', dispatched: false, completed: false }],
766
- phases: ['prepare'],
767
- currentPhaseIndex: 0,
768
- status: 'active',
769
- failedItems: [],
770
- });
771
-
772
- const result = await readModel.getPhasedExecution('exec-1');
773
-
774
- expect(result).toMatchObject({
775
- executionId: 'exec-1',
776
- correlationId: 'c1',
777
- handlerId: 'handler-1',
778
- status: 'active',
779
- });
780
- });
781
-
782
- it('should return null for different executionId', async () => {
783
- const collection = database.collection<WithId<PhasedExecutionDocument>>('PhasedExecution');
784
- const triggerEvent = { type: 'TestEvent', correlationId: 'c1', data: {} };
785
- await collection.insertOne({
786
- _id: 'exec-1',
787
- executionId: 'exec-1',
788
- correlationId: 'c1',
789
- handlerId: 'handler-1',
790
- triggerEvent,
791
- items: [],
792
- phases: ['prepare'],
793
- currentPhaseIndex: 0,
794
- status: 'active',
795
- failedItems: [],
796
- });
797
-
798
- const result = await readModel.getPhasedExecution('exec-2');
799
-
800
- expect(result).toBeNull();
801
- });
802
- });
803
-
804
- describe('getActivePhasedExecutions', () => {
805
- it('should return empty array when no executions exist', async () => {
806
- const result = await readModel.getActivePhasedExecutions('c1');
807
-
808
- expect(result).toEqual([]);
809
- });
810
-
811
- it('should return only active executions for correlationId', async () => {
812
- const collection = database.collection<WithId<PhasedExecutionDocument>>('PhasedExecution');
813
- const triggerEvent = { type: 'TestEvent', correlationId: 'c1', data: {} };
814
- await collection.insertOne({
815
- _id: 'exec-1',
816
- executionId: 'exec-1',
817
- correlationId: 'c1',
818
- handlerId: 'handler-1',
819
- triggerEvent,
820
- items: [],
821
- phases: ['prepare'],
822
- currentPhaseIndex: 0,
823
- status: 'active',
824
- failedItems: [],
825
- });
826
- await collection.insertOne({
827
- _id: 'exec-2',
828
- executionId: 'exec-2',
829
- correlationId: 'c1',
830
- handlerId: 'handler-2',
831
- triggerEvent,
832
- items: [],
833
- phases: ['prepare'],
834
- currentPhaseIndex: 0,
835
- status: 'completed',
836
- failedItems: [],
837
- });
838
-
839
- const result = await readModel.getActivePhasedExecutions('c1');
840
-
841
- expect(result).toHaveLength(1);
842
- expect(result[0].executionId).toBe('exec-1');
843
- });
844
-
845
- it('should filter by correlationId', async () => {
846
- const collection = database.collection<WithId<PhasedExecutionDocument>>('PhasedExecution');
847
- const triggerEvent1 = { type: 'TestEvent', correlationId: 'c1', data: {} };
848
- const triggerEvent2 = { type: 'TestEvent', correlationId: 'c2', data: {} };
849
- await collection.insertOne({
850
- _id: 'exec-1',
851
- executionId: 'exec-1',
852
- correlationId: 'c1',
853
- handlerId: 'handler-1',
854
- triggerEvent: triggerEvent1,
855
- items: [],
856
- phases: ['prepare'],
857
- currentPhaseIndex: 0,
858
- status: 'active',
859
- failedItems: [],
860
- });
861
- await collection.insertOne({
862
- _id: 'exec-2',
863
- executionId: 'exec-2',
864
- correlationId: 'c2',
865
- handlerId: 'handler-1',
866
- triggerEvent: triggerEvent2,
867
- items: [],
868
- phases: ['prepare'],
869
- currentPhaseIndex: 0,
870
- status: 'active',
871
- failedItems: [],
872
- });
873
-
874
- const result = await readModel.getActivePhasedExecutions('c1');
875
-
876
- expect(result).toHaveLength(1);
877
- expect(result[0].correlationId).toBe('c1');
878
- });
879
-
880
- it('should exclude failed executions', async () => {
881
- const collection = database.collection<WithId<PhasedExecutionDocument>>('PhasedExecution');
882
- const triggerEvent = { type: 'TestEvent', correlationId: 'c1', data: {} };
883
- await collection.insertOne({
884
- _id: 'exec-1',
885
- executionId: 'exec-1',
886
- correlationId: 'c1',
887
- handlerId: 'handler-1',
888
- triggerEvent,
889
- items: [],
890
- phases: ['prepare'],
891
- currentPhaseIndex: 0,
892
- status: 'failed',
893
- failedItems: [{ key: 'a', error: { message: 'Failed' } }],
894
- });
895
-
896
- const result = await readModel.getActivePhasedExecutions('c1');
897
-
898
- expect(result).toEqual([]);
899
- });
900
- });
901
-
902
- describe('computeSettledStats', () => {
903
- it('should return idle when no instance exists', async () => {
904
- const result = await readModel.computeSettledStats('c1', 'template-A');
905
-
906
- expect(result).toEqual({
907
- status: 'idle',
908
- pendingCount: 0,
909
- endedCount: 0,
910
- });
911
- });
912
-
913
- it('should return pendingCount=1 and status=running when instance is active', async () => {
914
- const collection = database.collection<WithId<SettledInstanceDocument>>('SettledInstance');
915
- await collection.insertOne({
916
- _id: 'template-CheckTests,CheckTypes,CheckLint-c1',
917
- instanceId: 'template-CheckTests,CheckTypes,CheckLint-c1',
918
- templateId: 'template-CheckTests,CheckTypes,CheckLint',
919
- correlationId: 'c1',
920
- commandTrackers: [
921
- { commandType: 'CheckTests', hasStarted: true, hasCompleted: false, events: [] },
922
- { commandType: 'CheckTypes', hasStarted: true, hasCompleted: false, events: [] },
923
- { commandType: 'CheckLint', hasStarted: true, hasCompleted: false, events: [] },
924
- ],
925
- status: 'active',
926
- firedCount: 0,
927
- });
928
-
929
- const result = await readModel.computeSettledStats('c1', 'template-CheckTests,CheckTypes,CheckLint');
930
-
931
- expect(result).toEqual({
932
- status: 'running',
933
- pendingCount: 1,
934
- endedCount: 0,
935
- });
936
- });
937
-
938
- it('should return status=error when any collected event contains Failed', async () => {
939
- const collection = database.collection<WithId<SettledInstanceDocument>>('SettledInstance');
940
- await collection.insertOne({
941
- _id: 'template-CheckTests,CheckTypes,CheckLint-c1',
942
- instanceId: 'template-CheckTests,CheckTypes,CheckLint-c1',
943
- templateId: 'template-CheckTests,CheckTypes,CheckLint',
944
- correlationId: 'c1',
945
- commandTrackers: [
946
- {
947
- commandType: 'CheckTests',
948
- hasStarted: true,
949
- hasCompleted: true,
950
- events: [{ type: 'TestsPassed', correlationId: 'c1', data: {} }],
951
- },
952
- {
953
- commandType: 'CheckTypes',
954
- hasStarted: true,
955
- hasCompleted: true,
956
- events: [{ type: 'TypeCheckFailed', correlationId: 'c1', data: { errors: 'TS2322' } }],
957
- },
958
- { commandType: 'CheckLint', hasStarted: true, hasCompleted: false, events: [] },
959
- ],
960
- status: 'active',
961
- firedCount: 0,
962
- });
963
-
964
- const result = await readModel.computeSettledStats('c1', 'template-CheckTests,CheckTypes,CheckLint');
965
-
966
- expect(result).toEqual({
967
- status: 'error',
968
- pendingCount: 1,
969
- endedCount: 0,
970
- });
971
- });
972
-
973
- it('should return endedCount=1 and status=success after handler fires without failures', async () => {
974
- const collection = database.collection<WithId<SettledInstanceDocument>>('SettledInstance');
975
- await collection.insertOne({
976
- _id: 'template-CheckTests,CheckTypes,CheckLint-c1',
977
- instanceId: 'template-CheckTests,CheckTypes,CheckLint-c1',
978
- templateId: 'template-CheckTests,CheckTypes,CheckLint',
979
- correlationId: 'c1',
980
- commandTrackers: [
981
- { commandType: 'CheckTests', hasStarted: true, hasCompleted: false, events: [] },
982
- { commandType: 'CheckTypes', hasStarted: true, hasCompleted: false, events: [] },
983
- { commandType: 'CheckLint', hasStarted: true, hasCompleted: false, events: [] },
984
- ],
985
- status: 'active',
986
- firedCount: 1,
987
- });
988
-
989
- const result = await readModel.computeSettledStats('c1', 'template-CheckTests,CheckTypes,CheckLint');
990
-
991
- expect(result).toEqual({
992
- status: 'success',
993
- pendingCount: 1,
994
- endedCount: 1,
995
- });
996
- });
997
-
998
- it('should return pendingCount=0 and endedCount when instance status is fired', async () => {
999
- const collection = database.collection<WithId<SettledInstanceDocument>>('SettledInstance');
1000
- await collection.insertOne({
1001
- _id: 'template-CheckTests-c1',
1002
- instanceId: 'template-CheckTests-c1',
1003
- templateId: 'template-CheckTests',
1004
- correlationId: 'c1',
1005
- commandTrackers: [
1006
- {
1007
- commandType: 'CheckTests',
1008
- hasStarted: true,
1009
- hasCompleted: true,
1010
- events: [{ type: 'TestsPassed', correlationId: 'c1', data: {} }],
1011
- },
1012
- ],
1013
- status: 'fired',
1014
- firedCount: 2,
1015
- });
1016
-
1017
- const result = await readModel.computeSettledStats('c1', 'template-CheckTests');
1018
-
1019
- expect(result).toEqual({
1020
- status: 'success',
1021
- pendingCount: 0,
1022
- endedCount: 2,
1023
- });
1024
- });
1025
-
1026
- it('should return status=error when fired instance has failed events', async () => {
1027
- const collection = database.collection<WithId<SettledInstanceDocument>>('SettledInstance');
1028
- await collection.insertOne({
1029
- _id: 'template-CheckTests-c1',
1030
- instanceId: 'template-CheckTests-c1',
1031
- templateId: 'template-CheckTests',
1032
- correlationId: 'c1',
1033
- commandTrackers: [
1034
- {
1035
- commandType: 'CheckTests',
1036
- hasStarted: true,
1037
- hasCompleted: true,
1038
- events: [{ type: 'TestsFailed', correlationId: 'c1', data: {} }],
1039
- },
1040
- ],
1041
- status: 'fired',
1042
- firedCount: 1,
1043
- });
1044
-
1045
- const result = await readModel.computeSettledStats('c1', 'template-CheckTests');
1046
-
1047
- expect(result).toEqual({
1048
- status: 'error',
1049
- pendingCount: 0,
1050
- endedCount: 1,
1051
- });
1052
- });
1053
-
1054
- it('should return pendingCount=0 and endedCount when instance status is cleaned', async () => {
1055
- const collection = database.collection<WithId<SettledInstanceDocument>>('SettledInstance');
1056
- await collection.insertOne({
1057
- _id: 'template-CheckTests-c1',
1058
- instanceId: 'template-CheckTests-c1',
1059
- templateId: 'template-CheckTests',
1060
- correlationId: 'c1',
1061
- commandTrackers: [
1062
- {
1063
- commandType: 'CheckTests',
1064
- hasStarted: true,
1065
- hasCompleted: true,
1066
- events: [{ type: 'TestsPassed', correlationId: 'c1', data: {} }],
1067
- },
1068
- ],
1069
- status: 'cleaned',
1070
- firedCount: 3,
1071
- });
1072
-
1073
- const result = await readModel.computeSettledStats('c1', 'template-CheckTests');
1074
-
1075
- expect(result).toEqual({
1076
- status: 'success',
1077
- pendingCount: 0,
1078
- endedCount: 3,
1079
- });
1080
- });
1081
-
1082
- it('should return pendingCount=0 when active instance has firedCount but all commands completed (BUG: settled showing running)', async () => {
1083
- const collection = database.collection<WithId<SettledInstanceDocument>>('SettledInstance');
1084
- await collection.insertOne({
1085
- _id: 'template-CheckTests,CheckTypes,CheckLint-c1',
1086
- instanceId: 'template-CheckTests,CheckTypes,CheckLint-c1',
1087
- templateId: 'template-CheckTests,CheckTypes,CheckLint',
1088
- correlationId: 'c1',
1089
- commandTrackers: [
1090
- {
1091
- commandType: 'CheckTests',
1092
- hasStarted: true,
1093
- hasCompleted: true,
1094
- events: [{ type: 'TestsPassed', correlationId: 'c1', data: {} }],
1095
- },
1096
- {
1097
- commandType: 'CheckTypes',
1098
- hasStarted: true,
1099
- hasCompleted: true,
1100
- events: [{ type: 'TypeCheckPassed', correlationId: 'c1', data: {} }],
1101
- },
1102
- {
1103
- commandType: 'CheckLint',
1104
- hasStarted: true,
1105
- hasCompleted: true,
1106
- events: [{ type: 'LintCheckPassed', correlationId: 'c1', data: {} }],
1107
- },
1108
- ],
1109
- status: 'active',
1110
- firedCount: 7,
1111
- });
1112
-
1113
- const result = await readModel.computeSettledStats('c1', 'template-CheckTests,CheckTypes,CheckLint');
1114
-
1115
- expect(result).toEqual({
1116
- status: 'success',
1117
- pendingCount: 0,
1118
- endedCount: 7,
1119
- });
1120
- });
1121
-
1122
- it('should default endedCount to 0 when firedCount is undefined', async () => {
1123
- const collection = database.collection<WithId<SettledInstanceDocument>>('SettledInstance');
1124
- await collection.insertOne({
1125
- _id: 'template-CheckTests-c1',
1126
- instanceId: 'template-CheckTests-c1',
1127
- templateId: 'template-CheckTests',
1128
- correlationId: 'c1',
1129
- commandTrackers: [{ commandType: 'CheckTests', hasStarted: true, hasCompleted: false, events: [] }],
1130
- status: 'active',
1131
- } as SettledInstanceDocument);
1132
-
1133
- const result = await readModel.computeSettledStats('c1', 'template-CheckTests');
1134
-
1135
- expect(result).toEqual({
1136
- status: 'running',
1137
- pendingCount: 1,
1138
- endedCount: 0,
1139
- });
1140
- });
1141
-
1142
- it('should return status=idle when fired instance has zero firedCount', async () => {
1143
- const collection = database.collection<WithId<SettledInstanceDocument>>('SettledInstance');
1144
- await collection.insertOne({
1145
- _id: 'template-CheckTests-c1',
1146
- instanceId: 'template-CheckTests-c1',
1147
- templateId: 'template-CheckTests',
1148
- correlationId: 'c1',
1149
- commandTrackers: [
1150
- {
1151
- commandType: 'CheckTests',
1152
- hasStarted: true,
1153
- hasCompleted: true,
1154
- events: [{ type: 'TestsPassed', correlationId: 'c1', data: {} }],
1155
- },
1156
- ],
1157
- status: 'fired',
1158
- firedCount: 0,
1159
- });
1160
-
1161
- const result = await readModel.computeSettledStats('c1', 'template-CheckTests');
1162
-
1163
- expect(result).toEqual({
1164
- status: 'idle',
1165
- pendingCount: 0,
1166
- endedCount: 0,
1167
- });
1168
- });
1169
- });
1170
603
  });
@@ -5,8 +5,6 @@ import type { ItemStatusDocument } from '../projections/item-status-projection';
5
5
  import type { LatestRunDocument } from '../projections/latest-run-projection';
6
6
  import type { MessageLogDocument } from '../projections/message-log-projection';
7
7
  import type { NodeStatusDocument } from '../projections/node-status-projection';
8
- import type { PhasedExecutionDocument } from '../projections/phased-execution-projection';
9
- import type { SettledInstanceDocument } from '../projections/settled-instance-projection';
10
8
  import type { StatsDocument } from '../projections/stats-projection';
11
9
 
12
10
  export interface CommandStats {
@@ -15,12 +13,6 @@ export interface CommandStats {
15
13
  aggregateStatus: NodeStatus;
16
14
  }
17
15
 
18
- export interface SettledStats {
19
- status: NodeStatus;
20
- pendingCount: number;
21
- endedCount: number;
22
- }
23
-
24
16
  export interface MessageStats {
25
17
  totalMessages: number;
26
18
  totalCommands: number;
@@ -33,8 +25,6 @@ export class PipelineReadModel {
33
25
  private readonly messageLogCollection;
34
26
  private readonly statsCollection;
35
27
  private readonly latestRunCollection;
36
- private readonly settledInstanceCollection;
37
- private readonly phasedExecutionCollection;
38
28
  private readonly awaitTrackerCollection;
39
29
 
40
30
  constructor(database: InMemoryDatabase) {
@@ -43,8 +33,6 @@ export class PipelineReadModel {
43
33
  this.messageLogCollection = database.collection<MessageLogDocument>('MessageLog');
44
34
  this.statsCollection = database.collection<StatsDocument>('Stats');
45
35
  this.latestRunCollection = database.collection<LatestRunDocument>('LatestRun');
46
- this.settledInstanceCollection = database.collection<SettledInstanceDocument>('SettledInstance');
47
- this.phasedExecutionCollection = database.collection<PhasedExecutionDocument>('PhasedExecution');
48
36
  this.awaitTrackerCollection = database.collection<AwaitTrackerDocument>('AwaitTracker');
49
37
  }
50
38
 
@@ -152,32 +140,6 @@ export class PipelineReadModel {
152
140
  return docs[0].latestCorrelationId;
153
141
  }
154
142
 
155
- async getSettledInstance(templateId: string, correlationId: string): Promise<SettledInstanceDocument | null> {
156
- const instances = await this.settledInstanceCollection.find(
157
- (doc) => doc.templateId === templateId && doc.correlationId === correlationId,
158
- );
159
- if (instances.length === 0) {
160
- return null;
161
- }
162
- return instances[0];
163
- }
164
-
165
- async getActiveSettledInstances(correlationId: string): Promise<SettledInstanceDocument[]> {
166
- return this.settledInstanceCollection.find((doc) => doc.correlationId === correlationId && doc.status === 'active');
167
- }
168
-
169
- async getPhasedExecution(executionId: string): Promise<PhasedExecutionDocument | null> {
170
- const executions = await this.phasedExecutionCollection.find((doc) => doc.executionId === executionId);
171
- if (executions.length === 0) {
172
- return null;
173
- }
174
- return executions[0];
175
- }
176
-
177
- async getActivePhasedExecutions(correlationId: string): Promise<PhasedExecutionDocument[]> {
178
- return this.phasedExecutionCollection.find((doc) => doc.correlationId === correlationId && doc.status === 'active');
179
- }
180
-
181
143
  async getAwaitState(correlationId: string): Promise<AwaitTrackerDocument | null> {
182
144
  const docs = await this.awaitTrackerCollection.find(
183
145
  (doc) => doc.correlationId === correlationId && doc.status === 'pending',
@@ -187,37 +149,4 @@ export class PipelineReadModel {
187
149
  }
188
150
  return docs[0];
189
151
  }
190
-
191
- async computeSettledStats(correlationId: string, templateId: string): Promise<SettledStats> {
192
- const instance = await this.getSettledInstance(templateId, correlationId);
193
-
194
- if (instance === null) {
195
- return { status: 'idle', pendingCount: 0, endedCount: 0 };
196
- }
197
-
198
- const endedCount = instance.firedCount ?? 0;
199
-
200
- if (instance.status === 'active') {
201
- const hasFailure = this.hasFailedEvent(instance);
202
- const hasFiredBefore = endedCount > 0;
203
- const allCompleted = instance.commandTrackers.every((t) => t.hasCompleted);
204
- const isPending = !allCompleted;
205
- const status = hasFailure ? 'error' : hasFiredBefore ? 'success' : 'running';
206
- return { status, pendingCount: isPending ? 1 : 0, endedCount };
207
- }
208
-
209
- const status = this.hasFailedEvent(instance) ? 'error' : endedCount > 0 ? 'success' : 'idle';
210
- return { status, pendingCount: 0, endedCount };
211
- }
212
-
213
- private hasFailedEvent(instance: SettledInstanceDocument): boolean {
214
- for (const tracker of instance.commandTrackers) {
215
- for (const event of tracker.events) {
216
- if (event.type.includes('Failed')) {
217
- return true;
218
- }
219
- }
220
- }
221
- return false;
222
- }
223
152
  }