@codemation/host 0.1.0 → 0.1.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 (70) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/{AppConfigFactory-Ciz9YKWx.js → AppConfigFactory-ByT1D8dM.js} +253 -15
  3. package/dist/{AppConfigFactory-Ciz9YKWx.js.map → AppConfigFactory-ByT1D8dM.js.map} +1 -1
  4. package/dist/{AppConfigFactory-CiBPHleh.d.ts → AppConfigFactory-_fqSok1J.d.ts} +6565 -177
  5. package/dist/{AppContainerFactory-DH88oxpg.js → AppContainerFactory-BRU02PTm.js} +838 -145
  6. package/dist/AppContainerFactory-BRU02PTm.js.map +1 -0
  7. package/dist/{CodemationConfig-DfK1KLvO.d.ts → CodemationConfig-CNfytKR6.d.ts} +2 -2
  8. package/dist/{CodemationConfigNormalizer-BKgIOeLm.d.ts → CodemationConfigNormalizer-BuKWVNEq.d.ts} +2 -2
  9. package/dist/{CodemationConsumerConfigLoader-bdhJsBKt.d.ts → CodemationConsumerConfigLoader-Mv4cywWu.d.ts} +2 -2
  10. package/dist/{CodemationPluginListMerger-BFZeO0WG.d.ts → CodemationPluginListMerger-BD5mR6gK.d.ts} +11 -5
  11. package/dist/{CredentialServices-aKIwHEhf.d.ts → CredentialServices-BQsEtctT.d.ts} +8 -7
  12. package/dist/{CredentialServices-DNb3CZwW.js → CredentialServices-xVxVA9Tq.js} +60 -114
  13. package/dist/CredentialServices-xVxVA9Tq.js.map +1 -0
  14. package/dist/{PublicFrontendBootstrapFactory-6ahaU0XM.d.ts → PublicFrontendBootstrapFactory-kTyAJdHI.d.ts} +2 -2
  15. package/dist/consumer.d.ts +4 -4
  16. package/dist/credentials.d.ts +3 -3
  17. package/dist/credentials.js +1 -1
  18. package/dist/devServerSidecar.d.ts +1 -1
  19. package/dist/{index-BYbzmUwS.d.ts → index-CX752QE9.d.ts} +68 -4
  20. package/dist/index.d.ts +10 -10
  21. package/dist/index.js +5 -5
  22. package/dist/nextServer.d.ts +20 -15
  23. package/dist/nextServer.js +35 -58
  24. package/dist/nextServer.js.map +1 -1
  25. package/dist/{persistenceServer-DL8yBGDU.d.ts → persistenceServer-CLY4qtMo.d.ts} +2 -2
  26. package/dist/{persistenceServer-CuAqL_fF.js → persistenceServer-DMvIOGW8.js} +2 -2
  27. package/dist/{persistenceServer-CuAqL_fF.js.map → persistenceServer-DMvIOGW8.js.map} +1 -1
  28. package/dist/persistenceServer.d.ts +5 -5
  29. package/dist/persistenceServer.js +2 -2
  30. package/dist/{server-EbxQft_X.js → server-ChTCEc6R.js} +4 -4
  31. package/dist/{server-EbxQft_X.js.map → server-ChTCEc6R.js.map} +1 -1
  32. package/dist/{server-BceIfIJf.d.ts → server-DwpcwzFb.d.ts} +6 -5
  33. package/dist/server.d.ts +8 -8
  34. package/dist/server.js +5 -5
  35. package/package.json +5 -5
  36. package/prisma/migrations/20260407140000_run_normalized_persistence/migration.sql +327 -0
  37. package/prisma/migrations/20260407193000_rename_run_projection_to_run_slot_projection/migration.sql +10 -0
  38. package/prisma/migrations.sqlite/20260407140000_run_normalized_persistence/migration.sql +326 -0
  39. package/prisma/migrations.sqlite/20260407193000_rename_run_projection_to_run_slot_projection/migration.sql +38 -0
  40. package/prisma/schema.postgresql.prisma +100 -1
  41. package/prisma/schema.sqlite.prisma +101 -1
  42. package/scripts/integration-database-global-setup.mjs +0 -3
  43. package/src/application/mapping/WorkflowDefinitionMapper.ts +95 -56
  44. package/src/application/mapping/WorkflowPolicyUiPresentationFactory.ts +1 -1
  45. package/src/application/queries/GetWorkflowRunDetailQuery.ts +8 -0
  46. package/src/application/queries/GetWorkflowRunDetailQueryHandler.ts +24 -0
  47. package/src/application/queries/WorkflowQueryHandlers.ts +1 -0
  48. package/src/application/runs/WorkflowRunRetentionPruneScheduler.ts +52 -27
  49. package/src/domain/credentials/WorkflowCredentialNodeResolver.ts +113 -158
  50. package/src/domain/runs/WorkflowRunRepository.ts +7 -1
  51. package/src/infrastructure/persistence/InMemoryWorkflowRunRepository.ts +123 -1
  52. package/src/infrastructure/persistence/PrismaMigrationDeployer.ts +226 -6
  53. package/src/infrastructure/persistence/PrismaWorkflowRunRepository.ts +796 -109
  54. package/src/infrastructure/persistence/generated/prisma-postgresql-client/edge.js +85 -5
  55. package/src/infrastructure/persistence/generated/prisma-postgresql-client/index-browser.js +81 -1
  56. package/src/infrastructure/persistence/generated/prisma-postgresql-client/index.d.ts +7107 -237
  57. package/src/infrastructure/persistence/generated/prisma-postgresql-client/index.js +85 -5
  58. package/src/infrastructure/persistence/generated/prisma-postgresql-client/package.json +1 -1
  59. package/src/infrastructure/persistence/generated/prisma-postgresql-client/schema.prisma +101 -1
  60. package/src/infrastructure/persistence/generated/prisma-sqlite-client/edge.js +85 -5
  61. package/src/infrastructure/persistence/generated/prisma-sqlite-client/index-browser.js +81 -1
  62. package/src/infrastructure/persistence/generated/prisma-sqlite-client/index.d.ts +7104 -242
  63. package/src/infrastructure/persistence/generated/prisma-sqlite-client/index.js +85 -5
  64. package/src/infrastructure/persistence/generated/prisma-sqlite-client/package.json +1 -1
  65. package/src/infrastructure/persistence/generated/prisma-sqlite-client/schema.prisma +101 -1
  66. package/src/presentation/http/ApiPaths.ts +4 -0
  67. package/src/presentation/http/hono/registrars/RunHonoApiRouteRegistrar.ts +1 -0
  68. package/src/presentation/http/routeHandlers/RunHttpRouteHandler.ts +13 -0
  69. package/dist/AppContainerFactory-DH88oxpg.js.map +0 -1
  70. package/dist/CredentialServices-DNb3CZwW.js.map +0 -1
@@ -1,7 +1,7 @@
1
- import { a as CodemationConfig, g as AppConfig, y as CodemationPlugin } from "./CodemationConfig-DfK1KLvO.js";
2
- import { t as CodemationConsumerConfigLoader } from "./CodemationConsumerConfigLoader-bdhJsBKt.js";
3
- import { t as AppConfigFactory } from "./AppConfigFactory-CiBPHleh.js";
4
- import { a as WorkflowDto, o as WorkflowSummary } from "./PublicFrontendBootstrapFactory-6ahaU0XM.js";
1
+ import { a as CodemationConfig, g as AppConfig, y as CodemationPlugin } from "./CodemationConfig-CNfytKR6.js";
2
+ import { t as CodemationConsumerConfigLoader } from "./CodemationConsumerConfigLoader-Mv4cywWu.js";
3
+ import { t as AppConfigFactory } from "./AppConfigFactory-_fqSok1J.js";
4
+ import { a as WorkflowDto, o as WorkflowSummary } from "./PublicFrontendBootstrapFactory-kTyAJdHI.js";
5
5
 
6
6
  //#region src/presentation/http/ApiPaths.d.ts
7
7
  declare class ApiPaths {
@@ -53,6 +53,7 @@ declare class ApiPaths {
53
53
  static userInviteRegenerate(userId: string): string;
54
54
  static userStatus(userId: string): string;
55
55
  static runState(runId: string): string;
56
+ static runDetail(runId: string): string;
56
57
  static runWorkflowSnapshot(runId: string): string;
57
58
  static runNodePin(runId: string, nodeId: string): string;
58
59
  static runNode(runId: string, nodeId: string): string;
@@ -149,4 +150,4 @@ declare class WorkflowDiscoveryPathSegmentsComputer {
149
150
  }
150
151
  //#endregion
151
152
  export { CodemationResolvedPluginPackage as a, CodemationServerGateway as c, CodemationPluginDiscovery as i, ApiPaths as l, WorkflowModulePathFinder as n, AppConfigLoadResult as o, CodemationDiscoveredPluginPackage as r, AppConfigLoader as s, WorkflowDiscoveryPathSegmentsComputer as t };
152
- //# sourceMappingURL=server-BceIfIJf.d.ts.map
153
+ //# sourceMappingURL=server-DwpcwzFb.d.ts.map
package/dist/server.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import "./CodemationAuthConfig-7hEfICPf.js";
2
2
  import { n as InternalAuthBootstrap, r as FrontendAppConfig, t as PublicFrontendBootstrap } from "./PublicFrontendBootstrap-DCniMBGu.js";
3
3
  import { i as CodemationFrontendAuthSnapshotJsonCodec, n as InternalAuthBootstrapJsonCodec, r as FrontendAppConfigJsonCodec, t as PublicFrontendBootstrapJsonCodec } from "./PublicFrontendBootstrapJsonCodec-BE0mhe1v.js";
4
- import "./index-BYbzmUwS.js";
5
- import "./CodemationConfig-DfK1KLvO.js";
6
- import "./CodemationConfigNormalizer-BKgIOeLm.js";
7
- import { i as CodemationConsumerAppResolver, n as CodemationConsumerConfigResolution, r as CodemationConsumerApp, t as CodemationConsumerConfigLoader } from "./CodemationConsumerConfigLoader-bdhJsBKt.js";
8
- import { r as PrismaDatabaseClient } from "./AppConfigFactory-CiBPHleh.js";
9
- import { t as CodemationPostgresPrismaClientFactory } from "./persistenceServer-DL8yBGDU.js";
10
- import { a as CodemationResolvedPluginPackage, c as CodemationServerGateway, i as CodemationPluginDiscovery, l as ApiPaths, n as WorkflowModulePathFinder, o as AppConfigLoadResult, r as CodemationDiscoveredPluginPackage, s as AppConfigLoader, t as WorkflowDiscoveryPathSegmentsComputer } from "./server-BceIfIJf.js";
11
- import { i as CodemationFrontendAuthSnapshotFactory, n as InternalAuthBootstrapFactory, r as FrontendAppConfigFactory, t as PublicFrontendBootstrapFactory } from "./PublicFrontendBootstrapFactory-6ahaU0XM.js";
4
+ import "./index-CX752QE9.js";
5
+ import "./CodemationConfig-CNfytKR6.js";
6
+ import "./CodemationConfigNormalizer-BuKWVNEq.js";
7
+ import { i as CodemationConsumerAppResolver, n as CodemationConsumerConfigResolution, r as CodemationConsumerApp, t as CodemationConsumerConfigLoader } from "./CodemationConsumerConfigLoader-Mv4cywWu.js";
8
+ import { r as PrismaDatabaseClient } from "./AppConfigFactory-_fqSok1J.js";
9
+ import { t as CodemationPostgresPrismaClientFactory } from "./persistenceServer-CLY4qtMo.js";
10
+ import { a as CodemationResolvedPluginPackage, c as CodemationServerGateway, i as CodemationPluginDiscovery, l as ApiPaths, n as WorkflowModulePathFinder, o as AppConfigLoadResult, r as CodemationDiscoveredPluginPackage, s as AppConfigLoader, t as WorkflowDiscoveryPathSegmentsComputer } from "./server-DwpcwzFb.js";
11
+ import { i as CodemationFrontendAuthSnapshotFactory, n as InternalAuthBootstrapFactory, r as FrontendAppConfigFactory, t as PublicFrontendBootstrapFactory } from "./PublicFrontendBootstrapFactory-kTyAJdHI.js";
12
12
  export { ApiPaths, AppConfigLoadResult, AppConfigLoader, CodemationConsumerApp, CodemationConsumerAppResolver, CodemationConsumerConfigLoader, CodemationConsumerConfigResolution, CodemationDiscoveredPluginPackage, CodemationFrontendAuthSnapshotFactory, CodemationFrontendAuthSnapshotJsonCodec, CodemationPluginDiscovery, CodemationPostgresPrismaClientFactory, CodemationResolvedPluginPackage, CodemationServerGateway, FrontendAppConfig, FrontendAppConfigFactory, FrontendAppConfigJsonCodec, InternalAuthBootstrap, InternalAuthBootstrapFactory, InternalAuthBootstrapJsonCodec, PrismaDatabaseClient as PrismaClient, PublicFrontendBootstrap, PublicFrontendBootstrapFactory, PublicFrontendBootstrapJsonCodec, WorkflowDiscoveryPathSegmentsComputer, WorkflowModulePathFinder };
package/dist/server.js CHANGED
@@ -4,10 +4,10 @@ import { i as CodemationConsumerAppResolver, n as WorkflowDiscoveryPathSegmentsC
4
4
  import "./ServerLoggerFactory-BltIIDfQ.js";
5
5
  import "./decorateParam-DrsXNPuw.js";
6
6
  import "./decorate-B0PP651O.js";
7
- import "./CredentialServices-DNb3CZwW.js";
8
- import { _ as CodemationFrontendAuthSnapshotFactory, g as FrontendAppConfigFactory, h as InternalAuthBootstrapFactory, m as PublicFrontendBootstrapFactory, y as ApiPaths } from "./AppContainerFactory-DH88oxpg.js";
9
- import "./AppConfigFactory-Ciz9YKWx.js";
10
- import { t as CodemationPostgresPrismaClientFactory } from "./persistenceServer-CuAqL_fF.js";
11
- import { n as AppConfigLoader, r as CodemationServerGateway, t as CodemationPluginDiscovery } from "./server-EbxQft_X.js";
7
+ import "./CredentialServices-xVxVA9Tq.js";
8
+ import { _ as CodemationFrontendAuthSnapshotFactory, g as FrontendAppConfigFactory, h as InternalAuthBootstrapFactory, m as PublicFrontendBootstrapFactory, y as ApiPaths } from "./AppContainerFactory-BRU02PTm.js";
9
+ import "./AppConfigFactory-ByT1D8dM.js";
10
+ import { t as CodemationPostgresPrismaClientFactory } from "./persistenceServer-DMvIOGW8.js";
11
+ import { n as AppConfigLoader, r as CodemationServerGateway, t as CodemationPluginDiscovery } from "./server-ChTCEc6R.js";
12
12
 
13
13
  export { ApiPaths, AppConfigLoader, CodemationConsumerAppResolver, CodemationConsumerConfigLoader, CodemationFrontendAuthSnapshotFactory, CodemationFrontendAuthSnapshotJsonCodec, CodemationPluginDiscovery, CodemationPostgresPrismaClientFactory, CodemationServerGateway, FrontendAppConfigFactory, FrontendAppConfigJsonCodec, InternalAuthBootstrapFactory, InternalAuthBootstrapJsonCodec, PublicFrontendBootstrapFactory, PublicFrontendBootstrapJsonCodec, WorkflowDiscoveryPathSegmentsComputer, WorkflowModulePathFinder };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemation/host",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -112,9 +112,9 @@
112
112
  "tsx": "^4.21.0",
113
113
  "ws": "^8.19.0",
114
114
  "zxcvbn": "^4.4.2",
115
- "@codemation/eventbus-redis": "0.0.19",
116
- "@codemation/core": "0.0.19",
117
- "@codemation/core-nodes": "0.0.19"
115
+ "@codemation/core": "0.2.0",
116
+ "@codemation/core-nodes": "0.0.21",
117
+ "@codemation/eventbus-redis": "0.0.21"
118
118
  },
119
119
  "devDependencies": {
120
120
  "@playwright/test": "^1.58.2",
@@ -139,7 +139,7 @@
139
139
  "tsdown": "^0.15.5",
140
140
  "typescript": "^5.9.3",
141
141
  "vitest": "^4.0.18",
142
- "@codemation/core-nodes-gmail": "0.0.21"
142
+ "@codemation/core-nodes-gmail": "0.0.23"
143
143
  },
144
144
  "scripts": {
145
145
  "prisma:generate": "node ./scripts/generate-prisma-clients.mjs && node ./scripts/ensure-prisma-runtime-sourcemaps.mjs",
@@ -0,0 +1,327 @@
1
+ -- Replace monolithic Run.state_json with normalized runtime storage.
2
+
3
+ ALTER TABLE "Run" ADD COLUMN IF NOT EXISTS "finished_at" TEXT;
4
+ ALTER TABLE "Run" ADD COLUMN IF NOT EXISTS "revision" INTEGER NOT NULL DEFAULT 0;
5
+ ALTER TABLE "Run" ADD COLUMN IF NOT EXISTS "control_json" TEXT;
6
+ ALTER TABLE "Run" ADD COLUMN IF NOT EXISTS "workflow_snapshot_json" TEXT;
7
+ ALTER TABLE "Run" ADD COLUMN IF NOT EXISTS "policy_snapshot_json" TEXT;
8
+ ALTER TABLE "Run" ADD COLUMN IF NOT EXISTS "engine_counters_json" TEXT;
9
+ ALTER TABLE "Run" ADD COLUMN IF NOT EXISTS "mutable_state_json" TEXT;
10
+ ALTER TABLE "Run" ADD COLUMN IF NOT EXISTS "outputs_by_node_json" TEXT;
11
+
12
+ UPDATE "Run"
13
+ SET
14
+ "control_json" = CASE
15
+ WHEN "state_json"::jsonb ? 'control' THEN ("state_json"::jsonb->'control')::text
16
+ ELSE NULL
17
+ END,
18
+ "workflow_snapshot_json" = CASE
19
+ WHEN "state_json"::jsonb ? 'workflowSnapshot' THEN ("state_json"::jsonb->'workflowSnapshot')::text
20
+ ELSE NULL
21
+ END,
22
+ "policy_snapshot_json" = CASE
23
+ WHEN "state_json"::jsonb ? 'policySnapshot' THEN ("state_json"::jsonb->'policySnapshot')::text
24
+ ELSE NULL
25
+ END,
26
+ "engine_counters_json" = CASE
27
+ WHEN "state_json"::jsonb ? 'engineCounters' THEN ("state_json"::jsonb->'engineCounters')::text
28
+ ELSE NULL
29
+ END,
30
+ "mutable_state_json" = CASE
31
+ WHEN "state_json"::jsonb ? 'mutableState' THEN ("state_json"::jsonb->'mutableState')::text
32
+ ELSE NULL
33
+ END,
34
+ "outputs_by_node_json" = COALESCE(("state_json"::jsonb->'outputsByNode')::text, '{}')
35
+ WHERE "outputs_by_node_json" IS NULL;
36
+
37
+ ALTER TABLE "Run" ALTER COLUMN "outputs_by_node_json" SET NOT NULL;
38
+
39
+ CREATE TABLE IF NOT EXISTS "RunWorkItem" (
40
+ "work_item_id" TEXT NOT NULL,
41
+ "run_id" TEXT NOT NULL,
42
+ "workflow_id" TEXT NOT NULL,
43
+ "status" TEXT NOT NULL,
44
+ "target_node_id" TEXT NOT NULL,
45
+ "batch_id" TEXT NOT NULL,
46
+ "queue_name" TEXT,
47
+ "claim_token" TEXT,
48
+ "claimed_by" TEXT,
49
+ "claimed_at" TEXT,
50
+ "available_at" TEXT NOT NULL,
51
+ "enqueued_at" TEXT NOT NULL,
52
+ "completed_at" TEXT,
53
+ "failed_at" TEXT,
54
+ "source_instance_id" TEXT,
55
+ "parent_instance_id" TEXT,
56
+ "items_in" INTEGER NOT NULL,
57
+ "inputs_by_port_json" TEXT NOT NULL,
58
+ "error_json" TEXT,
59
+
60
+ CONSTRAINT "RunWorkItem_pkey" PRIMARY KEY ("work_item_id")
61
+ );
62
+
63
+ CREATE INDEX IF NOT EXISTS "RunWorkItem_run_id_status_available_at_idx"
64
+ ON "RunWorkItem"("run_id", "status", "available_at");
65
+ CREATE INDEX IF NOT EXISTS "RunWorkItem_run_id_target_node_id_batch_id_idx"
66
+ ON "RunWorkItem"("run_id", "target_node_id", "batch_id");
67
+
68
+ CREATE TABLE IF NOT EXISTS "ExecutionInstance" (
69
+ "instance_id" TEXT NOT NULL,
70
+ "run_id" TEXT NOT NULL,
71
+ "workflow_id" TEXT NOT NULL,
72
+ "slot_node_id" TEXT NOT NULL,
73
+ "workflow_node_id" TEXT NOT NULL,
74
+ "kind" TEXT NOT NULL,
75
+ "connection_kind" TEXT,
76
+ "activation_id" TEXT,
77
+ "batch_id" TEXT NOT NULL,
78
+ "run_index" INTEGER NOT NULL,
79
+ "parent_instance_id" TEXT,
80
+ "parent_run_id" TEXT,
81
+ "worker_claim_token" TEXT,
82
+ "status" TEXT NOT NULL,
83
+ "queued_at" TEXT,
84
+ "started_at" TEXT,
85
+ "finished_at" TEXT,
86
+ "updated_at" TEXT NOT NULL,
87
+ "item_count" INTEGER NOT NULL,
88
+ "input_json" TEXT,
89
+ "output_json" TEXT,
90
+ "error_json" TEXT,
91
+ "input_item_indices_json" TEXT,
92
+ "output_item_count" INTEGER,
93
+ "successful_item_count" INTEGER,
94
+ "failed_item_count" INTEGER,
95
+ "input_storage_kind" TEXT,
96
+ "output_storage_kind" TEXT,
97
+ "input_bytes" INTEGER,
98
+ "output_bytes" INTEGER,
99
+ "input_preview_json" TEXT,
100
+ "output_preview_json" TEXT,
101
+ "input_payload_ref" TEXT,
102
+ "output_payload_ref" TEXT,
103
+ "input_truncated" BOOLEAN,
104
+ "output_truncated" BOOLEAN,
105
+ "used_pinned_output" BOOLEAN,
106
+
107
+ CONSTRAINT "ExecutionInstance_pkey" PRIMARY KEY ("instance_id")
108
+ );
109
+
110
+ CREATE INDEX IF NOT EXISTS "ExecutionInstance_run_id_slot_node_id_updated_at_idx"
111
+ ON "ExecutionInstance"("run_id", "slot_node_id", "updated_at");
112
+ CREATE INDEX IF NOT EXISTS "ExecutionInstance_run_id_parent_instance_id_updated_at_idx"
113
+ ON "ExecutionInstance"("run_id", "parent_instance_id", "updated_at");
114
+ CREATE INDEX IF NOT EXISTS "ExecutionInstance_run_id_kind_updated_at_idx"
115
+ ON "ExecutionInstance"("run_id", "kind", "updated_at");
116
+ CREATE UNIQUE INDEX IF NOT EXISTS "ExecutionInstance_run_id_slot_node_id_run_index_key"
117
+ ON "ExecutionInstance"("run_id", "slot_node_id", "run_index");
118
+
119
+ CREATE TABLE IF NOT EXISTS "RunProjection" (
120
+ "run_id" TEXT NOT NULL,
121
+ "workflow_id" TEXT NOT NULL,
122
+ "revision" INTEGER NOT NULL,
123
+ "updated_at" TEXT NOT NULL,
124
+ "slot_states_json" TEXT NOT NULL,
125
+ "mutable_state_json" TEXT,
126
+
127
+ CONSTRAINT "RunProjection_pkey" PRIMARY KEY ("run_id")
128
+ );
129
+
130
+ CREATE INDEX IF NOT EXISTS "RunProjection_workflow_id_updated_at_idx"
131
+ ON "RunProjection"("workflow_id", "updated_at");
132
+
133
+ ALTER TABLE "RunWorkItem" DROP CONSTRAINT IF EXISTS "RunWorkItem_run_id_fkey";
134
+ ALTER TABLE "RunWorkItem"
135
+ ADD CONSTRAINT "RunWorkItem_run_id_fkey"
136
+ FOREIGN KEY ("run_id") REFERENCES "Run"("run_id") ON DELETE CASCADE ON UPDATE CASCADE;
137
+
138
+ ALTER TABLE "ExecutionInstance" DROP CONSTRAINT IF EXISTS "ExecutionInstance_run_id_fkey";
139
+ ALTER TABLE "ExecutionInstance"
140
+ ADD CONSTRAINT "ExecutionInstance_run_id_fkey"
141
+ FOREIGN KEY ("run_id") REFERENCES "Run"("run_id") ON DELETE CASCADE ON UPDATE CASCADE;
142
+
143
+ ALTER TABLE "RunProjection" DROP CONSTRAINT IF EXISTS "RunProjection_run_id_fkey";
144
+ ALTER TABLE "RunProjection"
145
+ ADD CONSTRAINT "RunProjection_run_id_fkey"
146
+ FOREIGN KEY ("run_id") REFERENCES "Run"("run_id") ON DELETE CASCADE ON UPDATE CASCADE;
147
+
148
+ -- Backfill current queue / pending work items from the legacy aggregate.
149
+ INSERT INTO "RunWorkItem" (
150
+ "work_item_id",
151
+ "run_id",
152
+ "workflow_id",
153
+ "status",
154
+ "target_node_id",
155
+ "batch_id",
156
+ "available_at",
157
+ "enqueued_at",
158
+ "items_in",
159
+ "inputs_by_port_json"
160
+ )
161
+ SELECT
162
+ CONCAT(r."run_id", ':queue:', q.ordinality),
163
+ r."run_id",
164
+ r."workflow_id",
165
+ 'queued',
166
+ q.entry->>'nodeId',
167
+ COALESCE(q.entry->>'batchId', 'batch_1'),
168
+ r."updated_at",
169
+ r."updated_at",
170
+ COALESCE(jsonb_array_length(COALESCE(q.entry->'input', '[]'::jsonb)), 0),
171
+ CASE
172
+ WHEN q.entry ? 'collect' THEN COALESCE((q.entry->'collect'->'received')::text, '{}'::text)
173
+ ELSE jsonb_build_object(COALESCE(q.entry->>'toInput', 'in'), COALESCE(q.entry->'input', '[]'::jsonb))::text
174
+ END
175
+ FROM "Run" r
176
+ CROSS JOIN LATERAL jsonb_array_elements(COALESCE(r."state_json"::jsonb->'queue', '[]'::jsonb)) WITH ORDINALITY AS q(entry, ordinality)
177
+ WHERE r."state_json" IS NOT NULL;
178
+
179
+ INSERT INTO "RunWorkItem" (
180
+ "work_item_id",
181
+ "run_id",
182
+ "workflow_id",
183
+ "status",
184
+ "target_node_id",
185
+ "batch_id",
186
+ "queue_name",
187
+ "available_at",
188
+ "enqueued_at",
189
+ "items_in",
190
+ "inputs_by_port_json"
191
+ )
192
+ SELECT
193
+ COALESCE(r."state_json"::jsonb->'pending'->>'activationId', CONCAT(r."run_id", ':pending')),
194
+ r."run_id",
195
+ r."workflow_id",
196
+ 'claimed',
197
+ r."state_json"::jsonb->'pending'->>'nodeId',
198
+ COALESCE(r."state_json"::jsonb->'pending'->>'batchId', 'batch_1'),
199
+ r."state_json"::jsonb->'pending'->>'queue',
200
+ COALESCE(r."state_json"::jsonb->'pending'->>'enqueuedAt', r."updated_at"),
201
+ COALESCE(r."state_json"::jsonb->'pending'->>'enqueuedAt', r."updated_at"),
202
+ COALESCE((r."state_json"::jsonb->'pending'->>'itemsIn')::INTEGER, 0),
203
+ COALESCE((r."state_json"::jsonb->'pending'->'inputsByPort')::text, '{}'::text)
204
+ FROM "Run" r
205
+ WHERE r."state_json" IS NOT NULL
206
+ AND r."state_json"::jsonb ? 'pending'
207
+ AND r."state_json"::jsonb->'pending' IS NOT NULL;
208
+
209
+ -- Backfill latest workflow-node snapshots and connection invocations as execution instances.
210
+ INSERT INTO "ExecutionInstance" (
211
+ "instance_id",
212
+ "run_id",
213
+ "workflow_id",
214
+ "slot_node_id",
215
+ "workflow_node_id",
216
+ "kind",
217
+ "activation_id",
218
+ "batch_id",
219
+ "run_index",
220
+ "status",
221
+ "queued_at",
222
+ "started_at",
223
+ "finished_at",
224
+ "updated_at",
225
+ "item_count",
226
+ "input_json",
227
+ "output_json",
228
+ "error_json",
229
+ "used_pinned_output"
230
+ )
231
+ SELECT
232
+ CONCAT(r."run_id", ':node:', s.key, ':', COALESCE(s.value->>'activationId', 'na')),
233
+ r."run_id",
234
+ r."workflow_id",
235
+ s.key,
236
+ s.key,
237
+ 'workflowNodeActivation',
238
+ s.value->>'activationId',
239
+ COALESCE(r."state_json"::jsonb->'pending'->>'batchId', 'batch_1'),
240
+ 1,
241
+ COALESCE(s.value->>'status', 'completed'),
242
+ s.value->>'queuedAt',
243
+ s.value->>'startedAt',
244
+ s.value->>'finishedAt',
245
+ COALESCE(s.value->>'updatedAt', r."updated_at"),
246
+ COALESCE(jsonb_array_length(COALESCE(s.value->'outputs'->'main', '[]'::jsonb)), 0),
247
+ CASE WHEN s.value ? 'inputsByPort' THEN (s.value->'inputsByPort')::text ELSE NULL END,
248
+ CASE WHEN s.value ? 'outputs' THEN (s.value->'outputs')::text ELSE NULL END,
249
+ CASE WHEN s.value ? 'error' THEN (s.value->'error')::text ELSE NULL END,
250
+ CASE WHEN s.value ? 'usedPinnedOutput' THEN (s.value->>'usedPinnedOutput')::BOOLEAN ELSE NULL END
251
+ FROM "Run" r
252
+ CROSS JOIN LATERAL jsonb_each(COALESCE(r."state_json"::jsonb->'nodeSnapshotsByNodeId', '{}'::jsonb)) AS s(key, value)
253
+ WHERE r."state_json" IS NOT NULL;
254
+
255
+ INSERT INTO "ExecutionInstance" (
256
+ "instance_id",
257
+ "run_id",
258
+ "workflow_id",
259
+ "slot_node_id",
260
+ "workflow_node_id",
261
+ "kind",
262
+ "connection_kind",
263
+ "activation_id",
264
+ "batch_id",
265
+ "run_index",
266
+ "status",
267
+ "queued_at",
268
+ "started_at",
269
+ "finished_at",
270
+ "updated_at",
271
+ "item_count",
272
+ "input_json",
273
+ "output_json",
274
+ "error_json"
275
+ )
276
+ SELECT
277
+ inv.value->>'invocationId',
278
+ r."run_id",
279
+ r."workflow_id",
280
+ inv.value->>'connectionNodeId',
281
+ inv.value->>'parentAgentNodeId',
282
+ 'connectionInvocation',
283
+ 'languageModel',
284
+ inv.value->>'parentAgentActivationId',
285
+ COALESCE(r."state_json"::jsonb->'pending'->>'batchId', 'batch_1'),
286
+ 1000000 + inv.ordinality::INTEGER,
287
+ COALESCE(inv.value->>'status', 'completed'),
288
+ inv.value->>'queuedAt',
289
+ inv.value->>'startedAt',
290
+ inv.value->>'finishedAt',
291
+ COALESCE(inv.value->>'updatedAt', r."updated_at"),
292
+ 0,
293
+ CASE WHEN inv.value ? 'managedInput' THEN (inv.value->'managedInput')::text ELSE NULL END,
294
+ CASE WHEN inv.value ? 'managedOutput' THEN (inv.value->'managedOutput')::text ELSE NULL END,
295
+ CASE WHEN inv.value ? 'error' THEN (inv.value->'error')::text ELSE NULL END
296
+ FROM "Run" r
297
+ CROSS JOIN LATERAL jsonb_array_elements(COALESCE(r."state_json"::jsonb->'connectionInvocations', '[]'::jsonb)) WITH ORDINALITY AS inv(value, ordinality)
298
+ WHERE r."state_json" IS NOT NULL;
299
+
300
+ UPDATE "Run"
301
+ SET "finished_at" = COALESCE(
302
+ (
303
+ SELECT MAX(value->>'finishedAt')
304
+ FROM jsonb_each(COALESCE("state_json"::jsonb->'nodeSnapshotsByNodeId', '{}'::jsonb))
305
+ ),
306
+ "updated_at"
307
+ )
308
+ WHERE "status" IN ('completed', 'failed')
309
+ AND "state_json" IS NOT NULL;
310
+
311
+ INSERT INTO "RunProjection" ("run_id", "workflow_id", "revision", "updated_at", "slot_states_json", "mutable_state_json")
312
+ SELECT
313
+ r."run_id",
314
+ r."workflow_id",
315
+ r."revision",
316
+ r."updated_at",
317
+ jsonb_build_object('slotStatesByNodeId', '{}'::jsonb)::text,
318
+ NULL
319
+ FROM "Run" r
320
+ ON CONFLICT ("run_id") DO NOTHING;
321
+
322
+ CREATE INDEX IF NOT EXISTS "Run_workflow_id_started_at_idx"
323
+ ON "Run"("workflow_id", "started_at");
324
+ CREATE INDEX IF NOT EXISTS "Run_workflow_id_status_finished_at_idx"
325
+ ON "Run"("workflow_id", "status", "finished_at");
326
+
327
+ ALTER TABLE "Run" DROP COLUMN IF EXISTS "state_json";
@@ -0,0 +1,10 @@
1
+ ALTER TABLE "RunProjection" RENAME TO "RunSlotProjection";
2
+
3
+ ALTER INDEX IF EXISTS "RunProjection_pkey" RENAME TO "RunSlotProjection_pkey";
4
+ ALTER INDEX IF EXISTS "RunProjection_workflow_id_updated_at_idx" RENAME TO "RunSlotProjection_workflow_id_updated_at_idx";
5
+
6
+ ALTER TABLE "RunSlotProjection"
7
+ RENAME CONSTRAINT "RunProjection_run_id_fkey" TO "RunSlotProjection_run_id_fkey";
8
+
9
+ ALTER TABLE "RunSlotProjection"
10
+ DROP COLUMN IF EXISTS "mutable_state_json";