Skip to content

Conversation

@adityachoudhari26
Copy link
Contributor

@adityachoudhari26 adityachoudhari26 commented Apr 2, 2025

Summary by CodeRabbit

  • New Features

    • Introduced new API endpoints for creating, updating, upserting, and deleting deployment versions and channels.
    • Added support for specifying multiple deployment version channels in environment creation.
    • Enhanced job definitions with additional deployment version metadata.
    • Added a new property for optional version specification in job updates.
  • Bug Fixes

    • Improved request validation and error messaging for more robust operations.
  • Documentation

    • Updated API specifications with clear, detailed request and response schemas.
    • Refined security measures for authentication and authorization to ensure smooth integration.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 2, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

This update introduces multiple new OpenAPI specification files and route handlers for managing deployment version channels, deployment versions, environments, and jobs. New endpoints using POST, PATCH, and DELETE methods have been defined or updated, incorporating middleware for authentication, authorization, and body parsing. Enhancements include additional properties in request schemas (e.g., deploymentVersionChannels), refined error handling, variable renaming for consistency, and an updated security scheme using bearer authentication. Global API documentation now also includes a newly defined DeploymentVersion schema.

Changes

File(s) Change Summary
apps/webservice/src/app/api/v1/deployment-version-channels/openapi.ts
apps/webservice/src/app/api/v1/deployment-version-channels/route.ts
Added OpenAPI spec and POST route handler for creating/updating deployment version channels with authentication, body parsing, and conflict-update logic.
apps/webservice/src/app/api/v1/deployment-versions/[deploymentVersionId]/openapi.ts
apps/webservice/src/app/api/v1/deployment-versions/[deploymentVersionId]/route.ts
Introduced OpenAPI spec and PATCH handler for updating deployment versions including middleware use, metadata insertion, and release job trigger processing.
apps/webservice/src/app/api/v1/deployment-versions/openapi.ts
apps/webservice/src/app/api/v1/deployment-versions/route.ts
Created OpenAPI spec and POST route for upserting deployment versions with thorough schema validation and release trigger logic based on status checks.
apps/webservice/src/app/api/v1/deployments/[deploymentId]/deployment-version-channels/name/[name]/openapi.ts
apps/webservice/src/app/api/v1/deployments/[deploymentId]/deployment-version-channels/name/[name]/route.ts
Added OpenAPI spec and DELETE handler for removing deployment version channels by deployment ID and name, with appropriate error responses.
apps/webservice/src/app/api/v1/environments/openapi.ts
apps/webservice/src/app/api/v1/environments/route.ts
Extended environment schemas and POST handler to include a new property deploymentVersionChannels, revising query conditions to combine channel arrays.
apps/webservice/src/app/api/v1/jobs/[jobId]/openapi.ts
apps/webservice/src/app/api/v1/jobs/[jobId]/route.ts
Updated job schema by adding a deploymentVersion property and renamed a variable from version to deploymentVersion in the GET handler for consistency.
apps/webservice/src/app/api/v1/openapi.ts
openapi.v1.json
Integrated global API documentation changes including a new DeploymentVersion schema and updated endpoint definitions with bearer authentication.

Sequence Diagram(s)

sequenceDiagram
    participant C as Client
    participant M as Middleware (auth, parsing)
    participant H as Deployment Channel Handler
    participant DB as Database
    C->>M: Send POST /v1/deployment-version-channels
    M->>H: Forward validated request
    H->>DB: Insert new channel or update conflict record
    DB-->>H: Return result (success/error)
    H-->>C: Respond with JSON (200, 409, 500)
Loading
sequenceDiagram
    participant C as Client
    participant M as Middleware (auth, parsing)
    participant H as Deployment Version PATCH Handler
    participant DB as Database
    C->>M: Send PATCH /v1/deployment-versions/{deploymentVersionId}
    M->>H: Forward validated payload
    H->>DB: Update deployment version & metadata
    DB-->>H: Return operation outcome
    H-->>C: Respond with updated version JSON or error
Loading

Possibly related PRs

Suggested reviewers

  • jsbroks

Poem

I'm a rabbit on the run,
Hopping through code with zest and fun,
New endpoints bloom like carrots bright,
Schemas and routes aligned just right,
I nibble bugs with a twitch and a hop,
Celebrating changes as I happily bop!


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c779823 and a10354c.

📒 Files selected for processing (2)
  • apps/webservice/src/app/[workspaceSlug]/(app)/(deploy)/(raw)/systems/[systemSlug]/(raw)/environments/[environmentId]/deployments/EnvironmentDeploymentsPageContent.tsx (2 hunks)
  • apps/webservice/src/app/api/v1/deployment-versions/route.ts (1 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@adityachoudhari26 adityachoudhari26 changed the title fix: Refactor release endpoints v2 refactor: Refactor release endpoints v2 Apr 2, 2025
@adityachoudhari26 adityachoudhari26 changed the title refactor: Refactor release endpoints v2 refactor: Introduce deployment version endpoints in api v1 Apr 2, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (15)
apps/webservice/src/app/api/v1/deployment-version-channels/route.ts (1)

28-45: Refine Error Handling Strategy.

Currently, the entire error object is returned in the 500 response. This can risk exposing sensitive stack traces or internal details. Consider returning a sanitized error message or logging the detailed error separately.

 .catch((error) => {
-  return NextResponse.json({ error }, { status: 500 });
+  console.error("Deployment version channel insert error:", error);
+  return NextResponse.json(
+    { error: "Internal server error" },
+    { status: 500 }
+  );
});
apps/webservice/src/app/api/v1/jobs/[jobId]/route.ts (1)

104-108: Preserving Existing Metadata (Optional).

At line 106, replacing metadata with an empty object discards potential metadata from row.deployment_version. If any existing metadata is desired, consider merging or preserving it. Otherwise, this is acceptable if no prior metadata is expected.

- ? { ...row.deployment_version, metadata: {} }
+ ? { ...row.deployment_version, metadata: row.deployment_version.metadata ?? {} }
apps/webservice/src/app/api/v1/deployments/[deploymentId]/deployment-version-channels/name/[name]/route.ts (1)

10-45: Check Affected Row Count on Deletion.

After performing the delete operation, consider checking if any row was actually deleted. You might return a 404 if no matching record was found, improving client feedback.

try {
  const result = await ctx.db
    .delete(schema.deploymentVersionChannel)
    .where(
      and(
        eq(schema.deploymentVersionChannel.deploymentId, params.deploymentId),
        eq(schema.deploymentVersionChannel.name, params.name),
      ),
    );

+  if (result.rowCount === 0) {
+    return NextResponse.json({ error: "Not found" }, { status: 404 });
+  }

  return NextResponse.json(
    { message: "Deployment version channel deleted" },
    { status: 200 },
  );
} catch {
apps/webservice/src/app/api/v1/deployment-versions/openapi.ts (1)

56-69: Consider adding required fields to 409 response schema

The error response schema for the 409 conflict status doesn't specify required fields, unlike other error responses in the codebase. For consistency, consider adding the required fields as shown below:

  properties: {
    error: { type: "string" },
    id: { type: "string" },
  },
+ required: ["error", "id"],
apps/webservice/src/app/api/v1/deployment-versions/[deploymentVersionId]/openapi.ts (2)

52-61: Add error response definitions

The current specification only defines a success (200) response. Consider adding error response definitions for common scenarios like 404 (not found), 401 (unauthorized), 403 (forbidden), and 500 (server error) to match the pattern used in other API specifications.

responses: {
  "200": {
    description: "OK",
    content: {
      "application/json": {
        schema: { $ref: "#/components/schemas/DeploymentVersion" },
      },
    },
  },
+ "404": {
+   description: "Deployment version not found",
+   content: {
+     "application/json": {
+       schema: {
+         type: "object",
+         properties: { error: { type: "string" } },
+         required: ["error"],
+       },
+     },
+   },
+ },
+ "500": {
+   description: "Failed to update deployment version",
+   content: {
+     "application/json": {
+       schema: {
+         type: "object",
+         properties: { error: { type: "string" } },
+         required: ["error"],
+       },
+     },
+   },
+ },
},

5-65: Consider adding security configuration

Similar to the previous file, this OpenAPI specification doesn't include a security configuration. If authentication is required for updating deployment versions, consider adding security:

export const openapi: Swagger.SwaggerV3 = {
  // existing code...
  paths: {
    "/v1/deployment-versions/{deploymentVersionId}": {
      patch: {
        // existing code...
+       security: [{ bearerAuth: [] }],
      },
    },
  },
+ components: {
+   securitySchemes: { bearerAuth: { type: "http", scheme: "bearer" } },
+ },
};
apps/webservice/src/app/api/v1/deployments/[deploymentId]/deployment-version-channels/name/[name]/openapi.ts (1)

3-81: Consider adding security configuration

The OpenAPI specification doesn't include security requirements. If authentication is needed for deleting deployment version channels, consider adding a security scheme:

export const openapi: Swagger.SwaggerV3 = {
  // existing code...
  paths: {
    "/v1/deployments/{deploymentId}/deployment-version-channels/name/{name}": {
      delete: {
        // existing code...
+       security: [{ bearerAuth: [] }],
      },
    },
  },
+ components: {
+   securitySchemes: { bearerAuth: { type: "http", scheme: "bearer" } },
+ },
};

Otherwise, this is a well-structured OpenAPI spec with comprehensive response definitions for success and error cases.

apps/webservice/src/app/api/v1/deployment-versions/[deploymentVersionId]/route.ts (3)

22-24: Consider validating metadata structure further.

While this schema allows any string value in metadata, you might want to add constraints like maximum length or stricter formatting if there's a risk of receiving overly large or malformed data.


51-70: Be mindful of metadata key removals.

This logic updates or creates new metadata keys but does not remove keys that were deleted from the request. If you need full synchronization of metadata, consider removing old keys not present in the request.


71-90: Refactor nested .then calls for clarity.

Chaining multiple .then calls introduces nesting and reduces readability. Converting these calls to async/await can simplify error handling and improve maintainability.

- createReleaseJobTriggers(ctx.db, "version_updated")
-   .causedById(user.id)
-   .filter(isPassingChannelSelectorPolicy)
-   .versions([deploymentVersionId])
-   .then(createJobApprovals)
-   .insert()
-   .then((releaseJobTriggers) => {
-     dispatchReleaseJobTriggers(ctx.db)
-       .releaseTriggers(releaseJobTriggers)
-       .filter(isPassingAllPolicies)
-       .then(cancelOldReleaseJobTriggersOnJobDispatch)
-       .dispatch();
-   })
-   .then(() => logger.info(...));
+ const releaseJobTriggers = await createReleaseJobTriggers(ctx.db, "version_updated")
+   .causedById(user.id)
+   .filter(isPassingChannelSelectorPolicy)
+   .versions([deploymentVersionId])
+   .then(createJobApprovals)
+   .insert();
+
+ await dispatchReleaseJobTriggers(ctx.db)
+   .releaseTriggers(releaseJobTriggers)
+   .filter(isPassingAllPolicies)
+   .then(cancelOldReleaseJobTriggersOnJobDispatch)
+   .dispatch();
+
+ logger.info(...);
apps/webservice/src/app/api/v1/deployment-versions/route.ts (2)

31-36: Unify schema validation with PATCH.

Consider centralizing shared fields (e.g., metadata) in a common schema or utility function to reduce duplicated logic between POST and PATCH routes.


112-141: Convert .then chains to async/await.

Rewriting these chained calls using async/await reduces complexity and makes error handling more straightforward.

openapi.v1.json (3)

63-221: Endpoint "/v1/deployment-version-channels" Definition.
This new endpoint for creating a deployment version channel is comprehensively defined—with clear requirements on the request body (including required properties such as deploymentId, name, and versionSelector), detailed response schemas for both success and various error cases, and correct application of bearer authentication. Consider adding example values or further descriptions (e.g., for versionSelector) to enhance the clarity of its intended usage.


3472-3474: Integration of "deploymentVersion" in JobWithTrigger Schema.
The new deploymentVersion property has been added and correctly references the newly defined DeploymentVersion schema. For improved documentation, consider adding a brief description to explain its purpose within the context of a job trigger.


3710-3753: New "DeploymentVersion" Schema Definition.
The DeploymentVersion schema is well-structured and includes the appropriate required properties (id, name, tag, config, jobAgentConfig, deploymentId, createdAt, and metadata). To further enhance the specification, adding descriptive text for fields like tag and metadata can help clarify their expected values and usage.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fb9fc5f and d1a7582.

📒 Files selected for processing (14)
  • apps/webservice/src/app/api/v1/deployment-version-channels/openapi.ts (1 hunks)
  • apps/webservice/src/app/api/v1/deployment-version-channels/route.ts (1 hunks)
  • apps/webservice/src/app/api/v1/deployment-versions/[deploymentVersionId]/openapi.ts (1 hunks)
  • apps/webservice/src/app/api/v1/deployment-versions/[deploymentVersionId]/route.ts (1 hunks)
  • apps/webservice/src/app/api/v1/deployment-versions/openapi.ts (1 hunks)
  • apps/webservice/src/app/api/v1/deployment-versions/route.ts (1 hunks)
  • apps/webservice/src/app/api/v1/deployments/[deploymentId]/deployment-version-channels/name/[name]/openapi.ts (1 hunks)
  • apps/webservice/src/app/api/v1/deployments/[deploymentId]/deployment-version-channels/name/[name]/route.ts (1 hunks)
  • apps/webservice/src/app/api/v1/environments/openapi.ts (1 hunks)
  • apps/webservice/src/app/api/v1/environments/route.ts (2 hunks)
  • apps/webservice/src/app/api/v1/jobs/[jobId]/openapi.ts (1 hunks)
  • apps/webservice/src/app/api/v1/jobs/[jobId]/route.ts (3 hunks)
  • apps/webservice/src/app/api/v1/openapi.ts (1 hunks)
  • openapi.v1.json (5 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{ts,tsx}`: **Note on Error Handling:** Avoid strict enforcement of try/catch blocks. Code may use early returns, Promise chains (.then().catch()), or other patterns for error...

**/*.{ts,tsx}: Note on Error Handling:
Avoid strict enforcement of try/catch blocks. Code may use early returns, Promise chains (.then().catch()), or other patterns for error handling. These are acceptable as long as they maintain clarity and predictability.

  • apps/webservice/src/app/api/v1/jobs/[jobId]/openapi.ts
  • apps/webservice/src/app/api/v1/environments/openapi.ts
  • apps/webservice/src/app/api/v1/jobs/[jobId]/route.ts
  • apps/webservice/src/app/api/v1/environments/route.ts
  • apps/webservice/src/app/api/v1/deployments/[deploymentId]/deployment-version-channels/name/[name]/route.ts
  • apps/webservice/src/app/api/v1/deployment-version-channels/route.ts
  • apps/webservice/src/app/api/v1/openapi.ts
  • apps/webservice/src/app/api/v1/deployment-versions/route.ts
  • apps/webservice/src/app/api/v1/deployments/[deploymentId]/deployment-version-channels/name/[name]/openapi.ts
  • apps/webservice/src/app/api/v1/deployment-version-channels/openapi.ts
  • apps/webservice/src/app/api/v1/deployment-versions/[deploymentVersionId]/openapi.ts
  • apps/webservice/src/app/api/v1/deployment-versions/[deploymentVersionId]/route.ts
  • apps/webservice/src/app/api/v1/deployment-versions/openapi.ts
🧬 Code Definitions (5)
apps/webservice/src/app/api/v1/jobs/[jobId]/route.ts (1)
packages/db/src/schema/deployment-version.ts (1)
  • deploymentVersion (106-131)
apps/webservice/src/app/api/v1/deployment-version-channels/openapi.ts (4)
apps/webservice/src/app/api/v1/deployment-versions/[deploymentVersionId]/openapi.ts (1)
  • openapi (5-65)
apps/webservice/src/app/api/v1/deployment-versions/openapi.ts (1)
  • openapi (5-74)
apps/webservice/src/app/api/v1/deployments/[deploymentId]/deployment-version-channels/name/[name]/openapi.ts (1)
  • openapi (3-81)
apps/webservice/src/app/api/v1/openapi.ts (1)
  • openapi (3-336)
apps/webservice/src/app/api/v1/deployment-versions/[deploymentVersionId]/openapi.ts (2)
apps/webservice/src/app/api/v1/deployment-versions/openapi.ts (1)
  • openapi (5-74)
apps/webservice/src/app/api/v1/openapi.ts (1)
  • openapi (3-336)
apps/webservice/src/app/api/v1/deployment-versions/[deploymentVersionId]/route.ts (1)
apps/webservice/src/app/api/v1/jobs/[jobId]/route.ts (1)
  • PATCH (163-174)
apps/webservice/src/app/api/v1/deployment-versions/openapi.ts (3)
apps/webservice/src/app/api/v1/deployment-versions/[deploymentVersionId]/openapi.ts (1)
  • openapi (5-65)
apps/webservice/src/app/api/v1/deployment-version-channels/openapi.ts (1)
  • openapi (3-116)
apps/webservice/src/app/api/v1/openapi.ts (1)
  • openapi (3-336)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: build (linux/amd64)
  • GitHub Check: Typecheck
  • GitHub Check: Lint
🔇 Additional comments (21)
apps/webservice/src/app/api/v1/environments/openapi.ts (1)

50-55: Properly extends request body schema with new property.

The addition of the deploymentVersionChannels property to the environment creation request body is well-structured and consistent with the existing schema design pattern. This new property will allow clients to specify deployment version channels when creating environments.

apps/webservice/src/app/api/v1/jobs/[jobId]/openapi.ts (1)

18-20: Good addition of deploymentVersion reference.

The addition of the deploymentVersion property to the JobWithTrigger schema properly references the new DeploymentVersion schema. This enhances the job definition by providing access to detailed deployment version information.

apps/webservice/src/app/api/v1/openapi.ts (1)

122-143: Well-structured DeploymentVersion schema.

The new DeploymentVersion schema is properly defined with appropriate types and formats for each property. It follows the same pattern as other schema definitions in this file, maintaining consistency in the API design.

apps/webservice/src/app/api/v1/environments/route.ts (2)

19-19: Correct schema extension for deploymentVersionChannels.

Adding deploymentVersionChannels to the body schema as an array of strings matches the OpenAPI specification and properly extends the request validation.


40-43: Good implementation of combined channel handling.

The code correctly combines both releaseChannels and deploymentVersionChannels using the spread operator, allowing the query to consider both types of channels. This is an elegant solution that maintains backward compatibility while adding new functionality.

apps/webservice/src/app/api/v1/deployment-version-channels/route.ts (2)

1-12: Consistent Setup and Imports.

All imports and declarations appear valid and logically organized. The use of typed imports and clear separation of responsibilities looks good.


25-27: Clear Separation of versionSelector.

Extracting versionSelector before passing it to the database insertion call improves clarity. This approach helps keep the main insert flow concise.

apps/webservice/src/app/api/v1/jobs/[jobId]/route.ts (3)

115-115: Good Structuring of the Job Execution Object.

Adding deploymentVersion to the je object centralizes relevant details for the job. This improves readability and discoverability of the version data.


121-122: Conditional Fetch for Approval Details.

The short-circuit check on je.deploymentVersion?.id && policyId is a neat approach, ensuring the DB call occurs only when necessary.


142-143: Renaming Tagged Field to version.

Renaming the tag property to version for the release object is reasonable if consumers expect a property named version. Ensure downstream code is updated accordingly.

apps/webservice/src/app/api/v1/deployments/[deploymentId]/deployment-version-channels/name/[name]/route.ts (1)

1-2: Imports and Setup Look Good.

Imports for database operations, authentication, and authorization are standard and well-structured.

apps/webservice/src/app/api/v1/deployment-version-channels/openapi.ts (1)

1-116: Well-structured OpenAPI specification with complete documentation

The OpenAPI specification for deployment version channels is comprehensive, with all required components:

  • Properly defined request body schema with required fields
  • Thorough response definitions for success and error cases
  • Appropriate security scheme using bearer authentication
  • Consistent formatting and structure

This follows best practices for API documentation and aligns well with other API specs in the codebase.

apps/webservice/src/app/api/v1/deployment-versions/[deploymentVersionId]/route.ts (3)

26-39: Middleware chaining is well-structured.

Chaining authn, parseBody, and authz in a linear flow enhances maintainability and readability while ensuring proper checks at each stage.


92-98: General error handling is consistent.

Catching and logging exceptions before returning a 500 response is a robust approach. This helps maintain clarity for debugging and user feedback.


44-49:

❓ Verification inconclusive

Verify partial update behavior.

Using .set(body) might overwrite unspecified fields with undefined or null if they aren't provided, depending on how SCHEMA.updateDeploymentVersion is structured. Please confirm this aligns with the intended partial update logic.


🏁 Script executed:

#!/bin/bash
# Searching for usage of updateDeploymentVersion schema to confirm partial or full update handling
ast-grep --pattern $'updateDeploymentVersion($_)' || rg "updateDeploymentVersion"

Length of output: 50


Partial Update Behavior: Manual Verification Required

The executed script did not return any indications regarding the handling of unspecified fields. Please manually verify that the use of .set(body) in this update:

  • Ensures that fields not provided in body are left unchanged rather than being overwritten to undefined or null.
  • Aligns with the intended partial update logic specified by the schema (i.e., the behavior expected from updateDeploymentVersion).

Review the schema configuration and the underlying implementation of how partial updates are handled to confirm that this behavior is correct.

apps/webservice/src/app/api/v1/deployment-versions/route.ts (5)

38-47: Middleware usage looks solid.

Authentication, body parsing, and permission checks are consistently applied, which helps maintain a clean, modular API structure.


53-59: Validation for version name is appropriate.

Returning an HTTP 400 if name or tag is missing ensures proper handling of invalid inputs early.


72-90: Upsert logic is well-implemented.

Merging or creating deployment versions on conflict streamlines usage. The use of buildConflictUpdateColumns is clear and follows best practices for upserts.


91-111: Consistent metadata upsert.

Similar to the PATCH route, metadata is updated or inserted, but not removed. This is acceptable if partial metadata is desired. Otherwise, consider a cleanup approach.


147-159: Zod error handling is nicely handled.

Differentiating validation errors (400) from other exceptions (500) makes API responses more transparent for clients.

openapi.v1.json (1)

4068-4071: Updated Security Scheme to "bearerAuth".
The security scheme has been updated to use HTTP bearer authentication, which aligns well with the new endpoints and modern API security practices. Ensure that the corresponding backend authentication logic is updated accordingly to validate bearer tokens.

Comment on lines +5 to +74
export const openapi: Swagger.SwaggerV3 = {
openapi: "3.0.0",
info: {
title: "Ctrlplane API",
version: "1.0.0",
},
paths: {
"/v1/deployment-versions": {
post: {
summary: "Upserts a deployment version",
operationId: "upsertDeploymentVersion",
requestBody: {
required: true,
content: {
"application/json": {
schema: {
type: "object",
properties: {
tag: { type: "string" },
deploymentId: { type: "string" },
createdAt: { type: "string", format: "date-time" },
name: { type: "string" },
config: { type: "object", additionalProperties: true },
jobAgentConfig: {
type: "object",
additionalProperties: true,
},
status: {
type: "string",
enum: Object.values(DeploymentVersionStatus),
},
message: { type: "string" },
metadata: {
type: "object",
additionalProperties: { type: "string" },
},
},
required: ["tag", "deploymentId"],
},
},
},
},
responses: {
"200": {
description: "OK",
content: {
"application/json": {
schema: { $ref: "#/components/schemas/DeploymentVersion" },
},
},
},
"409": {
description: "Deployment version already exists",
content: {
"application/json": {
schema: {
type: "object",
properties: {
error: { type: "string" },
id: { type: "string" },
},
},
},
},
},
},
},
},
},
};
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Consider adding security configuration

Unlike the deployment-version-channels OpenAPI specification, this file doesn't include a security configuration. If authentication is required for this endpoint, consider adding a security scheme and security requirement:

export const openapi: Swagger.SwaggerV3 = {
  // existing code...
  paths: {
    "/v1/deployment-versions": {
      post: {
        // existing code...
+       security: [{ bearerAuth: [] }],
      },
    },
  },
+ components: {
+   securitySchemes: { bearerAuth: { type: "http", scheme: "bearer" } },
+ },
};

🏁 Script executed:

#!/bin/bash
# Check if other API endpoints use security configurations
grep -r "security: \[\{ bearerAuth: \[\] \}\]" apps/webservice/src/app/api/

Length of output: 107


I'm going to re-check whether other API endpoints in our repository include a security configuration. Please run the following script to search for any occurrences of "security:" and "bearerAuth" in the API directory:

Based on the output of these commands, there isn’t immediate evidence of a shared security configuration like that in the commented diff. However, if authentication is required for this endpoint, please consider adding a security configuration similar to the example diff below. If the omission is intentional (for example, if authentication is handled elsewhere), please double-check for consistency.


Action Required: Include Security Configuration if Authentication Is Intended

It appears the OpenAPI spec for the deployment-versions endpoint (in apps/webservice/src/app/api/v1/deployment-versions/openapi.ts) doesn’t include any security configuration. If this endpoint should be secured, consider updating it like so:

export const openapi: Swagger.SwaggerV3 = {
  openapi: "3.0.0",
  info: {
    title: "Ctrlplane API",
    version: "1.0.0",
  },
  paths: {
    "/v1/deployment-versions": {
      post: {
        summary: "Upserts a deployment version",
        operationId: "upsertDeploymentVersion",
        requestBody: { ... },
        responses: { ... },
+       security: [{ bearerAuth: [] }],
      },
    },
  },
+ components: {
+   securitySchemes: { bearerAuth: { type: "http", scheme: "bearer" } },
+ },
};

If authentication is meant to be applied here, please add the configuration. Otherwise, if the lack of security is deliberate, confirm that this aligns with our overall API security strategy.


🏁 Script executed:

#!/bin/bash
echo "Searching for 'security:' keyword in API endpoints..."
rg -F "security:" apps/webservice/src/app/api/

echo "Searching for 'bearerAuth' usage in API endpoints..."
rg -F "bearerAuth" apps/webservice/src/app/api/

Length of output: 1263


Security Configuration Consistency — Add Missing Security Schema

The endpoint at apps/webservice/src/app/api/v1/deployment-versions/openapi.ts currently does not include a security configuration, unlike similar endpoints. Our repository shows that endpoints in the following files have the security configuration already set up:

  • apps/webservice/src/app/api/v1/release-channels/openapi.ts
  • apps/webservice/src/app/api/v1/relationship/resource-to-resource/openapi.ts
  • apps/webservice/src/app/api/v1/deployment-version-channels/openapi.ts

If this endpoint is meant to be authenticated, please add a matching security configuration. For example:

 export const openapi: Swagger.SwaggerV3 = {
   openapi: "3.0.0",
   info: {
     title: "Ctrlplane API",
     version: "1.0.0",
   },
   paths: {
     "/v1/deployment-versions": {
       post: {
         summary: "Upserts a deployment version",
         operationId: "upsertDeploymentVersion",
         requestBody: {
           required: true,
           content: {
             "application/json": {
               schema: {
                 // schema details...
               },
             },
           },
         },
         responses: {
           "200": {
             description: "OK",
             content: {
               "application/json": {
                 schema: { $ref: "#/components/schemas/DeploymentVersion" },
               },
             },
           },
           "409": {
             description: "Deployment version already exists",
             content: {
               "application/json": {
                 schema: {
                   type: "object",
                   properties: {
                     error: { type: "string" },
                     id: { type: "string" },
                   },
                 },
               },
             },
           },
         },
+        security: [{ bearerAuth: [] }],
       },
     },
   },
+  components: {
+    securitySchemes: { bearerAuth: { type: "http", scheme: "bearer" } },
+  },
 };

If—including authentication for this endpoint—is intentional per our API design, then please add the above configuration for consistency. Otherwise, ensure that the absence of the security configuration is clearly documented and aligned with our overall security strategy.

📝 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
export const openapi: Swagger.SwaggerV3 = {
openapi: "3.0.0",
info: {
title: "Ctrlplane API",
version: "1.0.0",
},
paths: {
"/v1/deployment-versions": {
post: {
summary: "Upserts a deployment version",
operationId: "upsertDeploymentVersion",
requestBody: {
required: true,
content: {
"application/json": {
schema: {
type: "object",
properties: {
tag: { type: "string" },
deploymentId: { type: "string" },
createdAt: { type: "string", format: "date-time" },
name: { type: "string" },
config: { type: "object", additionalProperties: true },
jobAgentConfig: {
type: "object",
additionalProperties: true,
},
status: {
type: "string",
enum: Object.values(DeploymentVersionStatus),
},
message: { type: "string" },
metadata: {
type: "object",
additionalProperties: { type: "string" },
},
},
required: ["tag", "deploymentId"],
},
},
},
},
responses: {
"200": {
description: "OK",
content: {
"application/json": {
schema: { $ref: "#/components/schemas/DeploymentVersion" },
},
},
},
"409": {
description: "Deployment version already exists",
content: {
"application/json": {
schema: {
type: "object",
properties: {
error: { type: "string" },
id: { type: "string" },
},
},
},
},
},
},
},
},
},
};
export const openapi: Swagger.SwaggerV3 = {
openapi: "3.0.0",
info: {
title: "Ctrlplane API",
version: "1.0.0",
},
paths: {
"/v1/deployment-versions": {
post: {
summary: "Upserts a deployment version",
operationId: "upsertDeploymentVersion",
requestBody: {
required: true,
content: {
"application/json": {
schema: {
type: "object",
properties: {
tag: { type: "string" },
deploymentId: { type: "string" },
createdAt: { type: "string", format: "date-time" },
name: { type: "string" },
config: { type: "object", additionalProperties: true },
jobAgentConfig: {
type: "object",
additionalProperties: true,
},
status: {
type: "string",
enum: Object.values(DeploymentVersionStatus),
},
message: { type: "string" },
metadata: {
type: "object",
additionalProperties: { type: "string" },
},
},
required: ["tag", "deploymentId"],
},
},
},
},
responses: {
"200": {
description: "OK",
content: {
"application/json": {
schema: { $ref: "#/components/schemas/DeploymentVersion" },
},
},
},
"409": {
description: "Deployment version already exists",
content: {
"application/json": {
schema: {
type: "object",
properties: {
error: { type: "string" },
id: { type: "string" },
},
},
},
},
},
},
security: [{ bearerAuth: [] }],
},
},
},
components: {
securitySchemes: { bearerAuth: { type: "http", scheme: "bearer" } },
},
};

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
apps/webservice/src/app/api/v1/releases/[releaseId]/route.ts (1)

47-47: Consider documenting the fallback behavior

The fallback from tag to version is implemented correctly, but it might be helpful to add a comment explaining this fallback behavior for future developers.

-      const tag = body.tag ?? body.version;
+      // Use tag if available, otherwise fall back to version field
+      const tag = body.tag ?? body.version;
packages/db/src/schema/deployment-version.ts (1)

267-275: Consider refactoring duplicate condition building logic

The buildTagCondition function duplicates the logic from buildVersionCondition since both operate on the tag field. Consider refactoring to reduce duplication.

-const buildTagCondition = (cond: TagCondition): SQL => {
-  if (cond.operator === ColumnOperator.Equals)
-    return eq(deploymentVersion.tag, cond.value);
-  if (cond.operator === ColumnOperator.StartsWith)
-    return ilike(deploymentVersion.tag, `${cond.value}%`);
-  if (cond.operator === ColumnOperator.EndsWith)
-    return ilike(deploymentVersion.tag, `%${cond.value}`);
-  return ilike(deploymentVersion.tag, `%${cond.value}%`);
-};

+// Generic function to build conditions for string columns
+const buildStringColumnCondition = (
+  column: typeof deploymentVersion.tag,
+  operator: ColumnOperator,
+  value: string
+): SQL => {
+  if (operator === ColumnOperator.Equals)
+    return eq(column, value);
+  if (operator === ColumnOperator.StartsWith)
+    return ilike(column, `${value}%`);
+  if (operator === ColumnOperator.EndsWith)
+    return ilike(column, `%${value}`);
+  return ilike(column, `%${value}%`);
+};
+
+const buildVersionCondition = (cond: VersionCondition): SQL => {
+  return buildStringColumnCondition(deploymentVersion.tag, cond.operator, cond.value);
+};
+
+const buildTagCondition = (cond: TagCondition): SQL => {
+  return buildStringColumnCondition(deploymentVersion.tag, cond.operator, cond.value);
+};
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d1a7582 and c779823.

📒 Files selected for processing (7)
  • apps/webservice/src/app/api/v1/deployment-version-channels/route.ts (1 hunks)
  • apps/webservice/src/app/api/v1/releases/[releaseId]/route.ts (2 hunks)
  • packages/db/src/schema/deployment-version.ts (2 hunks)
  • packages/validators/src/releases/conditions/comparison-condition.ts (3 hunks)
  • packages/validators/src/releases/conditions/index.ts (1 hunks)
  • packages/validators/src/releases/conditions/release-condition.ts (4 hunks)
  • packages/validators/src/releases/conditions/tag-condition.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/webservice/src/app/api/v1/deployment-version-channels/route.ts
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{ts,tsx}`: **Note on Error Handling:** Avoid strict enforcement of try/catch blocks. Code may use early returns, Promise chains (.then().catch()), or other patterns for error...

**/*.{ts,tsx}: Note on Error Handling:
Avoid strict enforcement of try/catch blocks. Code may use early returns, Promise chains (.then().catch()), or other patterns for error handling. These are acceptable as long as they maintain clarity and predictability.

  • packages/validators/src/releases/conditions/index.ts
  • packages/validators/src/releases/conditions/tag-condition.ts
  • packages/validators/src/releases/conditions/comparison-condition.ts
  • packages/validators/src/releases/conditions/release-condition.ts
  • apps/webservice/src/app/api/v1/releases/[releaseId]/route.ts
  • packages/db/src/schema/deployment-version.ts
🧬 Code Definitions (4)
packages/validators/src/releases/conditions/comparison-condition.ts (1)
packages/validators/src/releases/conditions/tag-condition.ts (2)
  • tagCondition (5-9)
  • TagCondition (11-11)
packages/validators/src/releases/conditions/release-condition.ts (4)
packages/validators/src/releases/conditions/comparison-condition.ts (2)
  • ComparisonCondition (30-41)
  • comparisonCondition (13-28)
packages/validators/src/conditions/metadata-condition.ts (2)
  • MetadataCondition (56-56)
  • metadataCondition (48-54)
packages/validators/src/conditions/index.ts (2)
  • VersionCondition (42-42)
  • versionCondition (36-40)
packages/validators/src/releases/conditions/tag-condition.ts (2)
  • TagCondition (11-11)
  • tagCondition (5-9)
apps/webservice/src/app/api/v1/releases/[releaseId]/route.ts (1)
packages/db/src/schema/release.ts (1)
  • release (42-55)
packages/db/src/schema/deployment-version.ts (2)
packages/validators/src/releases/conditions/tag-condition.ts (1)
  • TagCondition (11-11)
packages/validators/src/releases/conditions/release-condition.ts (1)
  • DeploymentVersionCondition (15-20)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Typecheck
  • GitHub Check: build (linux/amd64)
  • GitHub Check: Lint
🔇 Additional comments (12)
packages/validators/src/releases/conditions/index.ts (1)

3-3: Looks good - introducing tag condition export

The added export for tag-condition.js follows the same pattern as existing exports, appropriately integrating the new tag condition functionality.

packages/validators/src/releases/conditions/tag-condition.ts (1)

1-11: LGTM: Tag condition schema implementation

The implementation is clean and follows the project's patterns for defining Zod schemas and exporting types. The schema appropriately validates tag conditions with the required properties.

apps/webservice/src/app/api/v1/releases/[releaseId]/route.ts (2)

23-26: Appropriate addition of version field to schema

Adding the optional version field to the patch schema aligns with the PR objectives for the deployment version endpoints.


50-50: Looks good - spreading body and setting tag

The update to include the tag variable in the set operation ensures the correct value is used regardless of which field was provided in the request.

packages/db/src/schema/deployment-version.ts (2)

6-9: Appropriate import of TagCondition type

The import statement is correctly updated to include the TagCondition type from the validators package.


284-285: Good implementation of tag condition handling

The condition handling for tag type is correctly implemented in the buildCondition function.

packages/validators/src/releases/conditions/release-condition.ts (3)

9-9: Well-integrated: TagCondition imports and type additions

The TagCondition type and schema have been properly imported and integrated into the existing DeploymentVersionCondition union type and deploymentVersionCondition Zod schema. These changes follow the established pattern for condition types in the system.

Also applies to: 13-13, 20-20, 27-27


45-45: Good addition: DeploymentVersionConditionType enum updated

The Tag entry is correctly added to the DeploymentVersionConditionType enum, which is necessary for the condition type checking throughout the system.


101-104: Well-implemented: Type guard and validation

The isTagCondition type guard function follows the same pattern as other type guards in the file. The additional validation in isValidDeploymentVersionCondition correctly ensures that tag values have a length greater than zero, maintaining consistent validation across different condition types.

Also applies to: 114-114

packages/validators/src/releases/conditions/comparison-condition.ts (3)

8-8: Imported tag condition types correctly.

The additions of imports for both the TagCondition type and the tagCondition Zod schema from the tag-condition module align with the existing pattern used for other conditions.

Also applies to: 11-11


24-24: Successfully added tag condition to the union of valid conditions.

Adding tagCondition to the z.union array properly integrates tag-based conditions into the validation logic, which extends the functionality to support tag filtering alongside existing condition types.


39-39: Properly updated the ComparisonCondition type definition.

The type definition now correctly includes TagCondition in the union type for the conditions array, maintaining type consistency with the Zod schema implementation above.

@adityachoudhari26 adityachoudhari26 merged commit e92cea2 into main Apr 3, 2025
4 of 9 checks passed
@adityachoudhari26 adityachoudhari26 deleted the refactor-release-endpoints-v2 branch April 3, 2025 00:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants