From 7b23f394dfbaa24632ab2a7ef063b830fc356803 Mon Sep 17 00:00:00 2001 From: Aditya Choudhari Date: Thu, 9 Apr 2026 11:04:31 -0700 Subject: [PATCH 1/2] chore: wire together deployment planning --- apps/api/openapi/openapi.json | 55 ++++++++++++++----- apps/api/openapi/schemas/deployments.jsonnet | 26 +++++++-- .../src/routes/v1/workspaces/deployments.ts | 29 +++++----- apps/api/src/types/openapi.ts | 18 ++++-- packages/workspace-engine-sdk/src/schema.ts | 9 +++ 5 files changed, 95 insertions(+), 42 deletions(-) diff --git a/apps/api/openapi/openapi.json b/apps/api/openapi/openapi.json index fd3cf28ea..375a09872 100644 --- a/apps/api/openapi/openapi.json +++ b/apps/api/openapi/openapi.json @@ -565,32 +565,60 @@ }, "DeploymentPlanTarget": { "properties": { - "contentHash": { - "description": "Hash of the rendered output for change detection", + "environmentId": { "type": "string" }, - "current": { - "description": "Full rendered output of the currently deployed state", + "environmentName": { "type": "string" }, - "environmentId": { + "hasChanges": { + "description": "True if any result for this target has changes", + "type": "boolean" + }, + "resourceId": { "type": "string" }, - "environmentName": { + "resourceName": { + "type": "string" + }, + "results": { + "items": { + "$ref": "#/components/schemas/DeploymentPlanTargetResult" + }, + "type": "array" + } + }, + "required": [ + "environmentId", + "environmentName", + "resourceId", + "resourceName", + "results" + ], + "type": "object" + }, + "DeploymentPlanTargetResult": { + "properties": { + "contentHash": { + "description": "Hash of the rendered output for change detection", + "type": "string" + }, + "current": { + "description": "Full rendered output of the currently deployed state", "type": "string" }, "hasChanges": { - "nullable": true, "type": "boolean" }, - "proposed": { - "description": "Full rendered output of the proposed version", + "id": { "type": "string" }, - "resourceId": { + "message": { + "description": "Agent message (e.g. error explanation or summary)", "type": "string" }, - "resourceName": { + "proposed": { + "description": "Full rendered output of the proposed version", "type": "string" }, "status": { @@ -604,10 +632,7 @@ } }, "required": [ - "environmentId", - "environmentName", - "resourceId", - "resourceName", + "id", "status" ], "type": "object" diff --git a/apps/api/openapi/schemas/deployments.jsonnet b/apps/api/openapi/schemas/deployments.jsonnet index 70646a8dc..97367106a 100644 --- a/apps/api/openapi/schemas/deployments.jsonnet +++ b/apps/api/openapi/schemas/deployments.jsonnet @@ -108,19 +108,33 @@ local jobAgentConfig = { }, }, + DeploymentPlanTargetResult: { + type: 'object', + required: ['id', 'status'], + properties: { + id: { type: 'string' }, + status: { type: 'string', enum: ['computing', 'completed', 'errored', 'unsupported'] }, + hasChanges: { type: 'boolean' }, + contentHash: { type: 'string', description: 'Hash of the rendered output for change detection' }, + current: { type: 'string', description: 'Full rendered output of the currently deployed state' }, + proposed: { type: 'string', description: 'Full rendered output of the proposed version' }, + message: { type: 'string', description: 'Agent message (e.g. error explanation or summary)' }, + }, + }, + DeploymentPlanTarget: { type: 'object', - required: ['environmentId', 'environmentName', 'resourceId', 'resourceName', 'status'], + required: ['environmentId', 'environmentName', 'resourceId', 'resourceName', 'results'], properties: { environmentId: { type: 'string' }, environmentName: { type: 'string' }, resourceId: { type: 'string' }, resourceName: { type: 'string' }, - status: { type: 'string', enum: ['computing', 'completed', 'errored', 'unsupported'] }, - hasChanges: { type: 'boolean', nullable: true }, - contentHash: { type: 'string', description: 'Hash of the rendered output for change detection' }, - current: { type: 'string', description: 'Full rendered output of the currently deployed state' }, - proposed: { type: 'string', description: 'Full rendered output of the proposed version' }, + hasChanges: { type: 'boolean', description: 'True if any result for this target has changes' }, + results: { + type: 'array', + items: openapi.schemaRef('DeploymentPlanTargetResult'), + }, }, }, diff --git a/apps/api/src/routes/v1/workspaces/deployments.ts b/apps/api/src/routes/v1/workspaces/deployments.ts index 656de5302..dfbebc03f 100644 --- a/apps/api/src/routes/v1/workspaces/deployments.ts +++ b/apps/api/src/routes/v1/workspaces/deployments.ts @@ -396,7 +396,7 @@ const createDeploymentPlan: AsyncTypedHandler< res.status(202).json({ id: planId, status: "computing", - summary: null, + summary: { total: 0, changed: 0, unchanged: 0, errored: 0, unsupported: 0 }, targets: [], }); }; @@ -437,11 +437,11 @@ const getDeploymentPlan: AsyncTypedHandler< results: t.results.map((r) => ({ id: r.id, status: r.status, - hasChanges: r.hasChanges, - current: r.current, - proposed: r.proposed, - contentHash: r.contentHash, - message: r.message, + hasChanges: r.hasChanges ?? false, + contentHash: r.contentHash ?? "", + current: r.current ?? "", + proposed: r.proposed ?? "", + message: r.message ?? "", })), })); @@ -455,16 +455,13 @@ const getDeploymentPlan: AsyncTypedHandler< const status = computing > 0 ? "computing" : errored > 0 ? "failed" : "completed"; - const summary = - status === "computing" - ? null - : { - total: allResults.length, - changed, - unchanged, - errored, - unsupported, - }; + const summary = { + total: allResults.length, + changed, + unchanged, + errored, + unsupported, + }; res.status(200).json({ id: plan.id, diff --git a/apps/api/src/types/openapi.ts b/apps/api/src/types/openapi.ts index 43c14df94..8d56857a9 100644 --- a/apps/api/src/types/openapi.ts +++ b/apps/api/src/types/openapi.ts @@ -1254,17 +1254,25 @@ export interface components { unsupported?: number; }; DeploymentPlanTarget: { + environmentId: string; + environmentName: string; + /** @description True if any result for this target has changes */ + hasChanges?: boolean; + resourceId: string; + resourceName: string; + results: components["schemas"]["DeploymentPlanTargetResult"][]; + }; + DeploymentPlanTargetResult: { /** @description Hash of the rendered output for change detection */ contentHash?: string; /** @description Full rendered output of the currently deployed state */ current?: string; - environmentId: string; - environmentName: string; - hasChanges?: boolean | null; + hasChanges?: boolean; + id: string; + /** @description Agent message (e.g. error explanation or summary) */ + message?: string; /** @description Full rendered output of the proposed version */ proposed?: string; - resourceId: string; - resourceName: string; /** @enum {string} */ status: "computing" | "completed" | "errored" | "unsupported"; }; diff --git a/packages/workspace-engine-sdk/src/schema.ts b/packages/workspace-engine-sdk/src/schema.ts index 4f392c7d1..87386b07f 100644 --- a/packages/workspace-engine-sdk/src/schema.ts +++ b/packages/workspace-engine-sdk/src/schema.ts @@ -1391,6 +1391,15 @@ export interface operations { "application/json": components["schemas"]["ErrorResponse"]; }; }; + /** @description Resource not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ErrorResponse"]; + }; + }; }; }; listReleaseTargets: { From 1e83d45183c162cfe691acee6cc1f1f6834fa0ce Mon Sep 17 00:00:00 2001 From: Aditya Choudhari Date: Thu, 9 Apr 2026 11:14:19 -0700 Subject: [PATCH 2/2] cleanup --- apps/api/openapi/openapi.json | 8 +++++++- apps/api/openapi/schemas/deployments.jsonnet | 4 ++-- apps/api/src/types/openapi.ts | 12 ++++++------ 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/apps/api/openapi/openapi.json b/apps/api/openapi/openapi.json index 375a09872..ca72e83e9 100644 --- a/apps/api/openapi/openapi.json +++ b/apps/api/openapi/openapi.json @@ -593,6 +593,7 @@ "environmentName", "resourceId", "resourceName", + "hasChanges", "results" ], "type": "object" @@ -633,7 +634,12 @@ }, "required": [ "id", - "status" + "status", + "hasChanges", + "contentHash", + "current", + "proposed", + "message" ], "type": "object" }, diff --git a/apps/api/openapi/schemas/deployments.jsonnet b/apps/api/openapi/schemas/deployments.jsonnet index 97367106a..be1891e15 100644 --- a/apps/api/openapi/schemas/deployments.jsonnet +++ b/apps/api/openapi/schemas/deployments.jsonnet @@ -110,7 +110,7 @@ local jobAgentConfig = { DeploymentPlanTargetResult: { type: 'object', - required: ['id', 'status'], + required: ['id', 'status', 'hasChanges', 'contentHash', 'current', 'proposed', 'message'], properties: { id: { type: 'string' }, status: { type: 'string', enum: ['computing', 'completed', 'errored', 'unsupported'] }, @@ -124,7 +124,7 @@ local jobAgentConfig = { DeploymentPlanTarget: { type: 'object', - required: ['environmentId', 'environmentName', 'resourceId', 'resourceName', 'results'], + required: ['environmentId', 'environmentName', 'resourceId', 'resourceName', 'hasChanges', 'results'], properties: { environmentId: { type: 'string' }, environmentName: { type: 'string' }, diff --git a/apps/api/src/types/openapi.ts b/apps/api/src/types/openapi.ts index 8d56857a9..883238336 100644 --- a/apps/api/src/types/openapi.ts +++ b/apps/api/src/types/openapi.ts @@ -1257,22 +1257,22 @@ export interface components { environmentId: string; environmentName: string; /** @description True if any result for this target has changes */ - hasChanges?: boolean; + hasChanges: boolean; resourceId: string; resourceName: string; results: components["schemas"]["DeploymentPlanTargetResult"][]; }; DeploymentPlanTargetResult: { /** @description Hash of the rendered output for change detection */ - contentHash?: string; + contentHash: string; /** @description Full rendered output of the currently deployed state */ - current?: string; - hasChanges?: boolean; + current: string; + hasChanges: boolean; id: string; /** @description Agent message (e.g. error explanation or summary) */ - message?: string; + message: string; /** @description Full rendered output of the proposed version */ - proposed?: string; + proposed: string; /** @enum {string} */ status: "computing" | "completed" | "errored" | "unsupported"; };