Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Convert endpoints to reference deployment version instead of release #392

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@ export const openapi: Swagger.SwaggerV3 = {
version: "1.0.0",
},
paths: {
"/v1/release-channels": {
"/v1/channels": {
post: {
summary: "Create a release channel",
operationId: "createReleaseChannel",
summary: "Create a channel",
operationId: "createChannel",
requestBody: {
required: true,
content: {
"application/json": {
schema: {
type: "object",
required: ["deploymentId", "name", "releaseFilter"],
required: ["deploymentId", "name", "versionSelector"],
properties: {
deploymentId: { type: "string" },
name: { type: "string" },
description: { type: "string", nullable: true },
releaseFilter: {
versionSelector: {
type: "object",
additionalProperties: true,
},
Expand All @@ -33,7 +33,7 @@ export const openapi: Swagger.SwaggerV3 = {
},
responses: {
"200": {
description: "Release channel created successfully",
description: "Channel created successfully",
content: {
"application/json": {
schema: {
Expand All @@ -44,7 +44,7 @@ export const openapi: Swagger.SwaggerV3 = {
name: { type: "string" },
description: { type: "string", nullable: true },
createdAt: { type: "string", format: "date-time" },
releaseFilter: {
versionSelector: {
type: "object",
additionalProperties: true,
},
Expand All @@ -55,7 +55,7 @@ export const openapi: Swagger.SwaggerV3 = {
},
},
"409": {
description: "Release channel already exists",
description: "Channel already exists",
content: {
"application/json": {
schema: {
Expand All @@ -70,7 +70,7 @@ export const openapi: Swagger.SwaggerV3 = {
},
},
"500": {
description: "Failed to create release channel",
description: "Failed to create channel",
content: {
"application/json": {
schema: {
Expand Down
43 changes: 43 additions & 0 deletions apps/webservice/src/app/api/v1/channels/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import type { z } from "zod";
import { NextResponse } from "next/server";

import { buildConflictUpdateColumns, takeFirst } from "@ctrlplane/db";
import { createDeploymentVersionChannel } from "@ctrlplane/db/schema";
import * as SCHEMA from "@ctrlplane/db/schema";
import { Permission } from "@ctrlplane/validators/auth";

import { authn, authz } from "../auth";
import { parseBody } from "../body-parser";
import { request } from "../middleware";

export const POST = request()
.use(authn)
.use(parseBody(createDeploymentVersionChannel))
.use(
authz(({ ctx, can }) =>
can
.perform(Permission.DeploymentVersionChannelCreate)
.on({ type: "deployment", id: ctx.body.deploymentId }),
),
)
.handle<{ body: z.infer<typeof createDeploymentVersionChannel> }>(
({ db, body }) =>
db
.insert(SCHEMA.deploymentVersionChannel)
.values(body)
.onConflictDoUpdate({
target: [
SCHEMA.deploymentVersionChannel.deploymentId,
SCHEMA.deploymentVersionChannel.name,
],
set: buildConflictUpdateColumns(SCHEMA.deploymentVersionChannel, [
"versionSelector",
]),
})
.returning()
.then(takeFirst)
.then((deploymentVersionChannel) =>
NextResponse.json(deploymentVersionChannel),
)
.catch((error) => NextResponse.json({ error }, { status: 500 })),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid exposing the raw error object in responses.

Returning error directly may leak sensitive information. It is considered safer to log the full error (for debugging) but return a more generic message to the user.

Below is a proposed diff for safer error handling:

 .catch((error) => {
-  return NextResponse.json({ error }, { status: 500 });
+  logger.error("Failed to create or update deploymentVersionChannel:", error);
+  return NextResponse.json(
+    { error: "Internal Server Error" },
+    { status: 500 }
+  );
});
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.catch((error) => NextResponse.json({ error }, { status: 500 })),
.catch((error) => {
logger.error("Failed to create or update deploymentVersionChannel:", error);
return NextResponse.json(
{ error: "Internal Server Error" },
{ status: 500 }
);
}),

);
4 changes: 2 additions & 2 deletions apps/webservice/src/app/api/v1/config/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,10 @@ const upsertVersions = async (db: Tx, config: CacV1, userId: string) => {
d.deployment.slug === deploymentSlug && d.system.slug === systemSlug,
);
if (deployment == null) return false;
const existingRelease = deployment.versions.find(
const existingVersion = deployment.versions.find(
(r) => r.tag === version.tag,
);
return existingRelease == null;
return existingVersion == null;
},
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ export const openapi: Swagger.SwaggerV3 = {
version: "1.0.0",
},
paths: {
"/v1/deployments/{deploymentId}/release-channels/name/{name}": {
"/v1/deployments/{deploymentId}/channels/name/{name}": {
delete: {
summary: "Delete a release channel",
operationId: "deleteReleaseChannel",
summary: "Delete a channel",
operationId: "deleteChannel",
parameters: [
{
name: "deploymentId",
Expand All @@ -27,7 +27,7 @@ export const openapi: Swagger.SwaggerV3 = {
],
responses: {
"200": {
description: "Release channel deleted",
description: "Channel deleted",
content: {
"application/json": {
schema: {
Expand All @@ -51,7 +51,7 @@ export const openapi: Swagger.SwaggerV3 = {
},
},
"404": {
description: "Release channel not found",
description: "Channel not found",
content: {
"application/json": {
schema: {
Expand All @@ -63,7 +63,7 @@ export const openapi: Swagger.SwaggerV3 = {
},
},
"500": {
description: "Failed to delete release channel",
description: "Failed to delete channel",
content: {
"application/json": {
schema: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ export const DELETE = request()
);

return NextResponse.json(
{ message: "Release channel deleted" },
{ message: "Channel deleted" },
{ status: 200 },
);
} catch {
return NextResponse.json(
{ error: "Failed to delete release channel" },
{ error: "Failed to delete channel" },
{ status: 500 },
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import * as SCHEMA from "@ctrlplane/db/schema";
import { logger } from "@ctrlplane/logger";
import { Permission } from "@ctrlplane/validators/auth";

import { authn, authz } from "../../auth";
import { request } from "../../middleware";
import { authn, authz } from "~/app/api/v1/auth";
import { request } from "~/app/api/v1/middleware";

export const GET = request()
.use(authn)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ export const openapi: Swagger.SwaggerV3 = {
openapi: "3.0.0",
info: { title: "Ctrlplane API", version: "1.0.0" },
paths: {
"/v1/releases/{releaseId}": {
"/v1/deployments/versions/{versionId}": {
patch: {
summary: "Updates a release",
operationId: "updateRelease",
summary: "Updates a deployment version",
operationId: "updateDeploymentVersion",
parameters: [
{
name: "releaseId",
name: "versionId",
in: "path",
required: true,
schema: { type: "string" },
description: "The release ID",
description: "The ID of the deployment version",
},
],
requestBody: {
Expand All @@ -26,7 +26,7 @@ export const openapi: Swagger.SwaggerV3 = {
schema: {
type: "object",
properties: {
version: { type: "string" },
tag: { type: "string" },
deploymentId: { type: "string" },
createdAt: { type: "string", format: "date-time" },
name: { type: "string" },
Expand Down Expand Up @@ -54,7 +54,7 @@ export const openapi: Swagger.SwaggerV3 = {
description: "OK",
content: {
"application/json": {
schema: { $ref: "#/components/schemas/Release" },
schema: { $ref: "#/components/schemas/DeploymentVersion" },
},
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import {
import { logger } from "@ctrlplane/logger";
import { Permission } from "@ctrlplane/validators/auth";

import { authn, authz } from "../../auth";
import { parseBody } from "../../body-parser";
import { request } from "../../middleware";
import { authn, authz } from "~/app/api/v1/auth";
import { parseBody } from "~/app/api/v1/body-parser";
import { request } from "~/app/api/v1/middleware";

const patchSchema = SCHEMA.updateDeploymentVersion.and(
z.object({ metadata: z.record(z.string()).optional() }),
Expand All @@ -30,18 +30,18 @@ export const PATCH = request()
authz(({ can, extra: { params } }) =>
can
.perform(Permission.DeploymentVersionUpdate)
.on({ type: "deploymentVersion", id: params.releaseId }),
.on({ type: "deploymentVersion", id: params.versionId }),
),
)
.handle<
{ body: z.infer<typeof patchSchema>; user: SCHEMA.User },
{ params: { releaseId: string } }
{ params: { versionId: string } }
>(async (ctx, { params }) => {
const { releaseId: versionId } = params;
const { versionId } = params;
const { body, user, req } = ctx;

try {
const release = await ctx.db
const deploymentVersion = await ctx.db
.update(SCHEMA.deploymentVersion)
.set(body)
.where(eq(SCHEMA.deploymentVersion.id, versionId))
Expand Down Expand Up @@ -83,12 +83,12 @@ export const PATCH = request()
})
.then(() =>
logger.info(
`Version for ${versionId} job triggers created and dispatched.`,
`Jobs for deployment version ${versionId} created and dispatched.`,
req,
),
);

return NextResponse.json(release);
return NextResponse.json(deploymentVersion);
} catch (error) {
logger.error(error);
return NextResponse.json(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ export const openapi: Swagger.SwaggerV3 = {
version: "1.0.0",
},
paths: {
"/v1/releases": {
"/v1/deployments/versions": {
post: {
summary: "Upserts a release",
operationId: "upsertRelease",
summary: "Upserts a deployment version",
operationId: "upsertDeploymentVersion",
requestBody: {
required: true,
content: {
"application/json": {
schema: {
type: "object",
properties: {
version: { type: "string" },
tag: { type: "string" },
deploymentId: { type: "string" },
createdAt: { type: "string", format: "date-time" },
name: { type: "string" },
Expand All @@ -39,7 +39,7 @@ export const openapi: Swagger.SwaggerV3 = {
additionalProperties: { type: "string" },
},
},
required: ["version", "deploymentId"],
required: ["tag", "deploymentId"],
},
},
},
Expand All @@ -49,12 +49,12 @@ export const openapi: Swagger.SwaggerV3 = {
description: "OK",
content: {
"application/json": {
schema: { $ref: "#/components/schemas/Release" },
schema: { $ref: "#/components/schemas/DeploymentVersion" },
},
},
},
"409": {
description: "Release already exists",
description: "Deployment version already exists",
content: {
"application/json": {
schema: {
Expand Down
Loading
Loading