Skip to content

feat: /v2/apis/createApi endpoint#3108

Merged
chronark merged 2 commits intomainfrom
v2-api-create-api
Apr 14, 2025
Merged

feat: /v2/apis/createApi endpoint#3108
chronark merged 2 commits intomainfrom
v2-api-create-api

Conversation

@chronark
Copy link
Collaborator

@chronark chronark commented Apr 13, 2025

Summary by CodeRabbit

  • New Features
    • Introduced a new API creation endpoint with structured request/response formats and improved validation for API names.
    • Updated Slack notifications for quota-exceed events to display clearer organization and payment identifiers.
    • Adjusted system rate limits to allow a higher tolerance for requests under heavy load, ensuring smoother performance.
    • Added new SQL queries for retrieving and inserting API records, enhancing database interactions.
  • Bug Fixes
    • Improved error handling for unauthorized access attempts and permission checks in the API creation process.
  • Documentation
    • Enhanced documentation for existing API request/response structures and validation rules.

@vercel
Copy link

vercel bot commented Apr 13, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
engineering ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 13, 2025 1:13pm
play ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 13, 2025 1:13pm
www ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 13, 2025 1:13pm
1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
dashboard ⬜️ Ignored (Inspect) Visit Preview Apr 13, 2025 1:13pm

@changeset-bot
Copy link

changeset-bot bot commented Apr 13, 2025

⚠️ No Changeset found

Latest commit: 7ffc340

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 13, 2025

📝 Walkthrough

Walkthrough

This pull request makes several coordinated modifications across the codebase. It adjusts the rate limiting test threshold, introduces a new API creation endpoint with associated types and a handler, and includes comprehensive tests for positive and negative scenarios. In addition, the changes update Slack notification messages, add new SQL queries and methods for API and audit log operations, and modify the workspace schema by renaming fields and adding new ones. Finally, database schema restructuring is performed in the Drizzle migrations and meta snapshots.

Changes

File(s) Change Summary
go/apps/api/integration/multi_node_ratelimiting/run.go Updated rate limit test: increased upper tolerance from 1.1× to 1.2× of maxAllowed while keeping the lower limit unchanged.
go/apps/api/openapi/gen.go, go/apps/api/openapi/openapi.json, go/apps/api/routes/v2_apis_create_api/handler.go Introduced new API creation endpoint (/v2/apis.createApi): added request/response types, new route/handler implementation, and updated public API definitions.
go/apps/api/routes/v2_apis_create_api/200_test.go, go/apps/api/routes/v2_apis_create_api/400_test.go, go/apps/api/routes/v2_apis_create_api/401_test.go, go/apps/api/routes/v2_apis_create_api/403_test.go Added unit tests for API creation covering successful creation, bad requests, unauthorized access, and forbidden operations.
go/cmd/quotacheck/main.go Modified Slack notification payload to now display "Organisation ID" and "Stripe ID" in place of previous fields.
go/pkg/db/api_find_by_id.sql_generated.go, go/pkg/db/api_insert.sql_generated.go, go/pkg/db/querier_generated.go, go/pkg/db/queries/api_find_by_id.sql, go/pkg/db/queries/api_insert.sql Added new SQL queries, generated methods, and updated the querier interface for finding and inserting API records.
go/pkg/db/audit_log_find_target_by_id.sql_generated.go, go/pkg/db/queries/audit_log_find_target_by_id.sql Introduced a SQL query and corresponding method for retrieving audit log target records by ID.
go/pkg/db/models_generated.go, go/pkg/db/workspace_find_by_id.sql_generated.go, go/pkg/db/workspace_insert.sql_generated.go, go/pkg/db/workspaces_list.sql_generated.go, go/pkg/db/queries/workspace_insert.sql, go/pkg/testutil/seed/seed.go Updated workspace schema: replaced tenant_id with org_id, added subscriptions, removed obsolete fields, and adjusted corresponding SQL queries and seed data.
internal/db/drizzle/0000_motionless_vargas.sql, internal/db/drizzle/meta/0000_snapshot.json, internal/db/drizzle/meta/_journal.json Restructured database schema: removed tenant_id, enforced org_id as NOT NULL, added bucket columns with defaults and new indexes in audit log tables, and updated meta snapshot and journal entries.

Sequence Diagram(s)

sequenceDiagram
    participant C as Client
    participant H as API Handler
    participant K as KeyService
    participant P as PermissionService
    participant DB as Database
    participant A as AuditLog Service

    C->>H: POST /v2/apis.createApi with JSON payload
    H->>K: Verify root key
    K-->>H: Key verification result
    H->>P: Check permissions
    P-->>H: Permissions status
    H->>DB: Begin transaction
    H->>DB: Insert new API record
    DB-->>H: Record insertion result
    H->>A: Log API creation event
    A-->>H: Logging result
    H->>DB: Commit transaction
    H-->>C: Return JSON response with API ID and Name
Loading

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (1.64.8)

Error: you are using a configuration file for golangci-lint v2 with golangci-lint v1: please use golangci-lint v2
Failed executing command with error: you are using a configuration file for golangci-lint v2 with golangci-lint v1: please use golangci-lint v2

Tip

⚡💬 Agentic Chat (Pro Plan, General Availability)
  • We're introducing multi-step agentic chat in review comments and issue comments, within and outside of PR's. This feature enhances review and issue discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments and add commits to existing pull requests.

🪧 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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

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.

@github-actions
Copy link
Contributor

github-actions bot commented Apr 13, 2025

Thank you for following the naming conventions for pull request titles! 🙏

@vercel vercel bot temporarily deployed to Preview – www April 13, 2025 08:55 Inactive
@vercel vercel bot temporarily deployed to Preview – play April 13, 2025 08:55 Inactive
@vercel vercel bot temporarily deployed to Preview – dashboard April 13, 2025 08:56 Inactive
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 (3)
go/apps/api/integration/multi_node_ratelimiting/run.go (1)

88-89: Tolerance threshold for rate limit test increased to 20%

The acceptance threshold for the rate limit test has been increased from 10% to 20%, making the test more lenient. This change likely helps reduce flaky tests in distributed environments where exact timing is difficult to guarantee.

Consider adding a comment explaining why this threshold was increased to help future developers understand the rationale behind this specific value.

go/pkg/db/querier_generated.go (1)

187-206: InsertApi documentation is consistent, but consider initializing optional columns.
Everything matches InsertApiParams. If you’d like more uniform behavior, optionally set updated_at_m at insert time to mirror the creation timestamp.

go/pkg/db/schema.sql (1)

260-270: Introducing the audit_log_bucket table.
Allows you to manage distinct audit log groupings with delete_protection. Consider enforcing foreign key constraints from audit_log.bucket_id to audit_log_bucket.id to maintain referential integrity.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 36becb3 and aeec9ac.

📒 Files selected for processing (26)
  • go/apps/api/integration/multi_node_ratelimiting/run.go (1 hunks)
  • go/apps/api/openapi/gen.go (3 hunks)
  • go/apps/api/openapi/openapi.json (2 hunks)
  • go/apps/api/routes/v2_apis_create_api/200_test.go (1 hunks)
  • go/apps/api/routes/v2_apis_create_api/400_test.go (1 hunks)
  • go/apps/api/routes/v2_apis_create_api/401_test.go (1 hunks)
  • go/apps/api/routes/v2_apis_create_api/403_test.go (1 hunks)
  • go/apps/api/routes/v2_apis_create_api/handler.go (1 hunks)
  • go/cmd/quotacheck/main.go (1 hunks)
  • go/pkg/db/api_find_by_id.sql_generated.go (1 hunks)
  • go/pkg/db/api_insert.sql_generated.go (1 hunks)
  • go/pkg/db/audit_log_find_target_by_id.sql_generated.go (1 hunks)
  • go/pkg/db/models_generated.go (3 hunks)
  • go/pkg/db/querier_generated.go (6 hunks)
  • go/pkg/db/queries/api_find_by_id.sql (1 hunks)
  • go/pkg/db/queries/api_insert.sql (1 hunks)
  • go/pkg/db/queries/audit_log_find_target_by_id.sql (1 hunks)
  • go/pkg/db/queries/workspace_insert.sql (1 hunks)
  • go/pkg/db/schema.sql (4 hunks)
  • go/pkg/db/workspace_find_by_id.sql_generated.go (1 hunks)
  • go/pkg/db/workspace_insert.sql_generated.go (6 hunks)
  • go/pkg/db/workspaces_list.sql_generated.go (3 hunks)
  • go/pkg/testutil/seed/seed.go (5 hunks)
  • internal/db/drizzle/0000_motionless_vargas.sql (4 hunks)
  • internal/db/drizzle/meta/0000_snapshot.json (7 hunks)
  • internal/db/drizzle/meta/_journal.json (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (12)
go/pkg/db/workspace_find_by_id.sql_generated.go (2)
go/pkg/db/models_generated.go (1)
  • Workspace (457-473)
internal/billing/src/subscriptions.ts (1)
  • Subscriptions (24-24)
go/pkg/testutil/seed/seed.go (2)
go/pkg/db/database.go (1)
  • New (39-84)
go/pkg/uid/uid.go (1)
  • New (63-83)
go/pkg/db/api_find_by_id.sql_generated.go (1)
go/pkg/db/models_generated.go (1)
  • Api (225-236)
go/apps/api/routes/v2_apis_create_api/400_test.go (5)
go/pkg/testutil/http.go (1)
  • CallRoute (180-214)
go/apps/api/routes/v2_apis_create_api/handler.go (4)
  • New (35-172)
  • Services (27-33)
  • Request (24-24)
  • Response (25-25)
go/pkg/testutil/seed/seed.go (2)
  • New (34-40)
  • Resources (18-24)
go/apps/api/routes/register.go (1)
  • Register (18-108)
go/apps/api/openapi/gen.go (2)
  • BadRequestErrorResponse (46-49)
  • Meta (100-104)
go/apps/api/routes/v2_apis_create_api/401_test.go (2)
go/pkg/testutil/http.go (2)
  • NewHarness (50-149)
  • CallRoute (180-214)
go/apps/api/routes/v2_apis_create_api/handler.go (4)
  • New (35-172)
  • Services (27-33)
  • Request (24-24)
  • Response (25-25)
go/pkg/db/api_insert.sql_generated.go (2)
go/pkg/db/models_generated.go (1)
  • NullApisAuthType (33-36)
internal/db/src/types.ts (1)
  • InsertApi (8-8)
go/cmd/quotacheck/main.go (1)
go/pkg/db/models_generated.go (1)
  • Workspace (457-473)
go/apps/api/routes/v2_apis_create_api/200_test.go (4)
go/pkg/testutil/http.go (1)
  • CallRoute (180-214)
go/apps/api/routes/v2_apis_create_api/handler.go (4)
  • New (35-172)
  • Services (27-33)
  • Request (24-24)
  • Response (25-25)
go/pkg/db/api_insert.sql_generated.go (1)
  • InsertApiParams (33-40)
go/pkg/db/models_generated.go (3)
  • NullApisAuthType (33-36)
  • ApisAuthType (14-14)
  • ApisAuthTypeKey (17-17)
go/pkg/db/workspaces_list.sql_generated.go (2)
go/pkg/db/models_generated.go (1)
  • Workspace (457-473)
internal/billing/src/subscriptions.ts (1)
  • Subscriptions (24-24)
go/apps/api/routes/v2_apis_create_api/handler.go (6)
go/apps/api/openapi/gen.go (4)
  • V2ApisCreateApiRequestBody (198-201)
  • V2ApisCreateApiResponseBody (204-207)
  • Meta (100-104)
  • ApisCreateApiResponseData (16-22)
go/pkg/zen/route.go (1)
  • NewRoute (46-52)
go/pkg/fault/tag.go (3)
  • INTERNAL_SERVER_ERROR (32-32)
  • INSUFFICIENT_PERMISSIONS (28-28)
  • DATABASE_ERROR (30-30)
go/pkg/rbac/permissions.go (2)
  • Tuple (169-178)
  • ResourceType (11-11)
go/pkg/db/models_generated.go (3)
  • Api (225-236)
  • NullApisAuthType (33-36)
  • ApisAuthType (14-14)
go/pkg/db/api_insert.sql_generated.go (1)
  • InsertApiParams (33-40)
go/pkg/db/models_generated.go (2)
apps/dashboard/app/(app)/apis/[apiId]/settings/delete-protection.tsx (1)
  • DeleteProtection (43-179)
internal/billing/src/subscriptions.ts (1)
  • Subscriptions (24-24)
go/pkg/db/audit_log_find_target_by_id.sql_generated.go (1)
go/pkg/db/models_generated.go (2)
  • AuditLogTarget (266-278)
  • AuditLog (238-254)
⏰ Context from checks skipped due to timeout of 90000ms (20)
  • GitHub Check: Test Go API Local / Test (Shard 5/8)
  • GitHub Check: Test Go API Local / Test (Shard 6/8)
  • GitHub Check: Test Go API Local / Test (Shard 7/8)
  • GitHub Check: Test Go API Local / Test (Shard 3/8)
  • GitHub Check: Test Packages / Test ./packages/rbac
  • GitHub Check: Test Go API Local / Test (Shard 8/8)
  • GitHub Check: Test Go API Local / Test (Shard 2/8)
  • GitHub Check: Test Go API Local / Test (Shard 1/8)
  • GitHub Check: Test Go API Local / Test (Shard 4/8)
  • GitHub Check: Test Packages / Test ./internal/id
  • GitHub Check: Test Packages / Test ./packages/api
  • GitHub Check: Test Packages / Test ./packages/cache
  • GitHub Check: Test Packages / Test ./internal/resend
  • GitHub Check: Test Packages / Test ./internal/billing
  • GitHub Check: Test Packages / Test ./internal/encryption
  • GitHub Check: Test Agent Local / test_agent_local
  • GitHub Check: Test API / API Test Local
  • GitHub Check: Build / Build
  • GitHub Check: autofix
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (75)
internal/db/drizzle/meta/_journal.json (1)

8-9: Database migration metadata updated correctly.

The timestamp and tag fields have been updated to reflect the new database migration. This is consistent with the migration from using tenant_id to org_id in the workspaces table as mentioned in the PR summary.

go/pkg/db/queries/api_find_by_id.sql (1)

1-2:

Details

❓ Verification inconclusive

Query looks good, but ensure proper index exists.

This query will be used to fetch an API by ID. It's correctly parameterized to prevent SQL injection and follows the sqlc naming convention.


🏁 Script executed:

#!/bin/bash
# Check if there's an index on the id column in the apis table
echo "Checking for index on apis.id column..."
ast-grep --pattern "CREATE TABLE \`apis\`" -A 20 | grep -E "PRIMARY KEY|INDEX.*id"

Length of output: 171


Index Verification Required for apis.id Column

The SQL query itself is correctly parameterized and follows the sqlc conventions. However, the automated check for an index on the id column of the apis table produced no output. This may indicate that the necessary index (or primary key) isn’t defined in the same file or is created elsewhere. Please manually verify that the apis table has a proper index or primary key on the id column—check the migration files or database schema to ensure the expected performance optimizations are in place.

  • File: go/pkg/db/queries/api_find_by_id.sql (lines 1–2)
  • Action: Confirm via migration or schema review that an index (or primary key) exists on apis.id.
go/pkg/db/queries/audit_log_find_target_by_id.sql (1)

1-5: Well-structured join query with appropriate embedding.

This query efficiently retrieves audit log targets with their related audit logs, using sqlc.embed to generate properly structured result objects. The parameterization with sqlc.arg(id) prevents SQL injection.

go/pkg/db/queries/api_insert.sql (1)

1-18:

Details

❓ Verification inconclusive

API insertion query is well-structured.

The INSERT query is complete with all necessary fields and properly sets deleted_at_m to NULL by default, implementing the soft deletion pattern. All parameters are properly placeholdered to prevent SQL injection.


🏁 Script executed:

#!/bin/bash
# Verify that all required fields are included in the INSERT statement
echo "Checking apis table schema to ensure all required fields are covered..."
ast-grep --pattern "CREATE TABLE \`apis\`" -A 30

Length of output: 201


Action: Confirm apis table schema for consistency with the INSERT query.

The API insertion query in go/pkg/db/queries/api_insert.sql is well-structured—with all parameters appropriately placeholdered and the soft deletion pattern implemented (by setting deleted_at_m to NULL). However, our initial attempt to retrieve the table definition of apis via the script did not return any schema details. Please verify that the table definition indeed includes the following columns with the expected properties:

  • id
  • name
  • workspace_id
  • auth_type
  • key_auth_id
  • created_at_m
  • deleted_at_m

Once confirmed that the database schema matches these fields, this portion of the code is approved.

go/cmd/quotacheck/main.go (1)

159-159: Updated field name in Slack notification.

Changed from displaying "Clerk ID" to "Organisation ID" using e.Workspace.OrgID, which aligns with the workspace schema changes mentioned in the PR summary.

go/pkg/db/workspace_find_by_id.sql_generated.go (2)

34-34: Updated Scan method to include new Subscriptions field

The Workspace scan operation now includes the Subscriptions field, matching the updated schema.


13-13:

Details

❓ Verification inconclusive

Schema change: Added 'subscriptions' field to workspace model

The SQL query has been updated to include the new 'subscriptions' field and use 'org_id' instead of 'tenant_id', reflecting the workspace schema changes.


🏁 Script executed:

#!/bin/bash
# Verify that all references to workspace schema have been updated consistently

# Check for any remaining references to tenant_id in the codebase
echo "Checking for remaining references to tenant_id..."
rg -i "tenant_id" --type go

# Check all workspace-related SQL queries to ensure they include subscriptions field
echo "Checking workspace queries for subscriptions field..."
rg -i "SELECT.*FROM.*workspaces" --type sql

Length of output: 434


Workspace Schema Update Verified – Confirm Consistency Across Queries

The generated file go/pkg/db/workspace_find_by_id.sql_generated.go now correctly lists all required columns—including the new subscriptions field—and uses org_id in place of tenant_id. The verification also shows no stray references to tenant_id in Go code.

Please note the following:

  • The SQL query in go/pkg/db/queries/workspace_find_by_id.sql still uses SELECT * FROM workspaces rather than an explicit column list. Verify whether this is intentional or if it should be updated for consistency with the schema change.
  • The query in tools/migrate/timestamps.sql also uses SELECT *, so please confirm that this approach aligns with your schema update strategy.

Overall, the auto-generated SQL meets the intended schema modifications. Please review the additional query definitions to ensure consistency across the codebase.

go/pkg/db/queries/workspace_insert.sql (2)

4-4: Schema migration: Replaced 'tenant_id' with 'org_id'

The workspace model now uses 'org_id' instead of 'tenant_id', suggesting a conceptual shift from tenant-based to organization-based identification.

Also applies to: 15-15


7-7: Field name and value standardization: 'plan' → 'tier' and 'free' → 'Free'

The field has been renamed from 'plan' to 'tier', and the default value is now capitalized ('Free'). This suggests a standardization of enum values across the codebase.

Also applies to: 18-18

go/pkg/testutil/seed/seed.go (3)

47-47: Updated test data to use OrgID instead of TenantID

The test seeder has been updated to match the schema changes replacing TenantID with OrgID in multiple workspace parameter sets, ensuring consistency with the database schema changes.

Also applies to: 77-77, 90-90


130-130: Added logging for permission creation

Added log statement to show when permissions are created for a key, which improves debugging capabilities during tests.


143-150:

Details

✅ Verification successful

Simplified MySQL error handling for duplicate entries

The error handling for MySQL has been streamlined to directly check for error code 1062 (duplicate entry) without checking for other error codes.

Do you expect any other MySQL error codes to occur during permission creation, or is 1062 (duplicate entry) the only expected error?


🏁 Script executed:

#!/bin/bash
# Check for other instances of MySQL error handling to ensure consistency

# Look for other places that handle MySQL errors
echo "Checking for MySQL error handling patterns..."
rg "mysql\.MySQLError" --type go -A 5 -B 5

Length of output: 2036


Streamlined MySQL Duplicate Entry Error Handling

It appears that the code intentionally limits error handling to the duplicate entry case (error code 1062). Our search in the repository confirms that this pattern is consistent—for example, the same 1062 check is used in both the seed utility and the identity creation handler. Could you please confirm that duplicate entry (1062) is indeed the only error condition we expect for permission creation, or should we consider adding handling for any additional MySQL error codes?

go/pkg/db/api_find_by_id.sql_generated.go (1)

1-36: The new API finder function looks good!

This generated file correctly implements the FindApiById function to retrieve an API record by its ID. The SQL query selects all required fields from the apis table and the function properly scans the result into an Api struct.

go/pkg/db/workspaces_list.sql_generated.go (1)

14-14: Correctly updated to include the 'subscriptions' field.

The SQL query and corresponding scan operation have been properly updated to include the new subscriptions field, while removing several deprecated fields. This aligns with the broader workspace schema restructuring.

Also applies to: 57-57

go/apps/api/routes/v2_apis_create_api/401_test.go (1)

14-61: Test for unauthorized API access is well-structured.

This test thoroughly verifies unauthorized access scenarios for the new API creation endpoint, covering both invalid auth tokens and tokens from incorrect workspaces. The assertions and test setup look good.

go/pkg/db/workspace_insert.sql_generated.go (2)

15-15: SQL and struct updated to use 'org_id' instead of 'tenant_id'.

The changes consistently rename the field from tenant_id to org_id throughout the SQL query, struct definition, and function implementation. The plan default value has also been updated from 'free' to 'Free' for standardization.

Also applies to: 29-29, 39-39, 48-48, 51-51, 62-62, 71-71


18-18:

Details

❓ Verification inconclusive

Verify the relationship between 'tier' and 'Free'.

The SQL query uses the column name tier but assigns it the value 'Free', which seems like a plan name rather than a tier designation. Consider verifying that this is the intended behavior.

Also applies to: 29-29


🏁 Script executed:

#!/bin/bash
# Check if 'Free' is actually a valid value for the 'tier' column
# or if there might be a mismatch between column name and value type

# Look for other instances of tier/plan usage in the codebase
echo "Searching for tier usage in the codebase:"
rg -A 2 -B 2 "tier\s*[=:]" --type go

echo "Searching for 'Free' value assignments in the codebase:"
rg -A 2 -B 2 "'Free'" --type go

# Check workspace model definition
echo "Checking workspace model definition:"
rg "type\s+Workspace\s+struct" --type go -A 20

Length of output: 3047


Action: Confirm the 'Free' value for the tier field

After reviewing the codebase, we confirmed that the generated SQL for workspace insertion assigns the literal 'Free' to the tier column (lines 18 and 29 in go/pkg/db/workspace_insert.sql_generated.go). Additionally, the Workspace model in go/pkg/db/models_generated.go defines a separate Plan field (of type NullWorkspacesPlan) alongside Tier (a sql.NullString). This suggests that storing 'Free' in tier is deliberate—perhaps to indicate a default or specific tier—while detailed plan information is handled differently.

Please verify that using 'Free' for the tier column (instead of, or in addition to, the Plan field) is indeed the intended behavior. If so, consider adding a short inline comment or documentation to clarify the distinction between tier and Plan for future maintainers.

go/apps/api/routes/v2_apis_create_api/403_test.go (4)

15-27: Well-structured test setup

The test harness setup is clean and follows good practices by injecting all required dependencies. The route registration approach ensures the test uses the same handler configuration as the production code.


28-33: Good authentication test setup

Creating a root key with insufficient permissions explicitly tests the negative case first, which is a good security-focused approach.


35-42: Clear and focused permission test

The test explicitly verifies that without the required "api.*.create_api" permission, the request is properly rejected with a 403 status code.


44-85: Comprehensive permission test cases

The test covers multiple permission scenarios with a table-driven approach, which is excellent for maintainability. The verification of database state in successful cases adds an extra layer of validation to ensure the API was actually created.

go/pkg/db/audit_log_find_target_by_id.sql_generated.go (3)

12-17: SQL query looks correct for the intended purpose

The query properly joins the audit_log_target table with audit_log on the audit_log_id field and filters by the target ID.


19-22: Well-structured return type

The struct correctly captures both the AuditLogTarget and the related AuditLog in a single data structure, making it easy to access both entities from the query result.


30-78: Thorough error handling in the query implementation

The implementation correctly handles potential errors at multiple points: during query execution, row scanning, and closing the result set. It also properly manages resources by deferring the closing of rows.

go/apps/api/routes/v2_apis_create_api/400_test.go (4)

14-31: Good test setup with proper permissions

Unlike the 403 test, this test correctly sets up a root key with the "api.*.create_api" permission, ensuring that permission issues don't interfere with validation testing.


33-41: Clear minimum name length validation test

The test explicitly verifies that the API rejects names shorter than 3 characters with a 400 status code.


43-60: Thorough name validation tests

The tests cover both missing name (empty struct) and empty name string scenarios, which are distinct cases that could be handled differently by validators.


62-81: Detailed error response structure verification

The test goes beyond just checking status codes to verify the entire error response structure, including request ID, error type, title, and validation details. This ensures API clients receive informative error messages.

go/pkg/db/api_insert.sql_generated.go (3)

13-31: SQL insertion query looks correct

The SQL statement properly specifies all required fields and explicitly sets deleted_at_m to NULL for new API records.


33-40: Well-defined parameter struct

The InsertApiParams struct includes all necessary fields with appropriate types, including NullApisAuthType for the optional auth_type field and sql.NullString for the optional key_auth_id field.


61-71: Straightforward query execution with proper error handling

The InsertApi method correctly maps struct fields to SQL parameters and returns any errors encountered during execution.

internal/db/drizzle/0000_motionless_vargas.sql (3)

1-14: Well-structured apis table with appropriate fields and constraints.

The apis table design looks comprehensive with all necessary fields:

  • Primary key and unique constraints are properly defined
  • Includes fields for authentication type with an enum constraint (key or jwt)
  • Has timestamp fields for created/updated/deleted tracking
  • Includes delete protection flag for preventing accidental deletion
  • Links to the authentication mechanism via key_auth_id

179-179: Strengthened data integrity with NOT NULL constraint on org_id.

The change from optional to required org_id indicates a shift from tenant-based to organization-based workspace model, which improves data integrity by ensuring every workspace is associated with an organization.

Also applies to: 194-194


244-244: Enhanced audit logging with categorization capability.

The addition of the bucket column with default value 'unkey_mutations' to both audit tables, along with corresponding indexes, allows for better categorization and filtering of audit logs. This is a good practice for systems with extensive audit requirements.

Also applies to: 275-275, 301-301, 305-305

go/apps/api/openapi/openapi.json (3)

632-644: Well-defined request schema for API creation.

The request schema follows best practices:

  • It requires a name field with appropriate validation (minimum length of 3)
  • Includes good example and description
  • Properly restricts additional properties to maintain schema integrity

645-658: Clear response data structure with required fields.

The response data structure is well-defined with all necessary fields properly marked as required. Both the API ID and name are returned, giving the client all the information needed after API creation.


1174-1246: Complete API endpoint definition with proper security and error handling.

The endpoint definition is comprehensive:

  • Uses the correct HTTP method (POST) for resource creation
  • Includes appropriate security requirements
  • Defines all relevant response codes with corresponding schemas
  • Contains meaningful descriptions for responses
go/apps/api/routes/v2_apis_create_api/200_test.go (6)

18-31: Good test setup with proper harness initialization.

The test setup correctly initializes the test harness and registers the route with all required dependencies. The structure follows Go testing best practices with a main test function containing sub-tests for different scenarios.


39-68: Comprehensive database operation verification test.

This test validates the underlying database operations directly, which is excellent for ensuring the data access layer works properly. It creates both the key authentication entry and the API record, then verifies all fields match the expected values.


71-114: Complete end-to-end API creation test with thorough validation.

This test effectively covers the entire API creation flow and validates:

  1. The HTTP response status and body
  2. The API record in the database
  3. The associated key authentication record
  4. The audit log entry

Particularly good is checking that the audit log contains the specific "api.create" event.


116-147: Good test for creating multiple APIs and verifying uniqueness.

This test ensures that multiple APIs can be created in sequence and that each gets a unique ID. The use of a map to verify uniqueness is an elegant solution.


149-179: Comprehensive edge case testing for API names.

These tests validate that the system handles both long names and special characters correctly. This is important for ensuring the API is robust when dealing with various input formats.


181-201: Good test for UUID-based names and default property verification.

This test validates both using a UUID as an API name and checks that the delete protection is set to false by default. This covers an important aspect of the API's default behavior.

go/apps/api/openapi/gen.go (4)

15-22: Well-structured response data type with proper documentation.

The ApisCreateApiResponseData struct correctly matches the schema defined in the OpenAPI specification, including field names, types, and JSON tags. The documentation comments are clear and helpful.


197-201: Properly defined request body type matching the OpenAPI schema.

The V2ApisCreateApiRequestBody struct contains the required name field with appropriate documentation that explains its purpose and usage.


203-207: Well-structured response body type following API conventions.

The V2ApisCreateApiResponseBody struct follows the established pattern in the API of including both metadata and the actual data payload, maintaining consistency with other endpoints.


372-373: Consistent type alias for JSON request body.

The CreateApiJSONRequestBody type alias follows the same pattern used for other endpoints in the API, ensuring consistency throughout the codebase.

go/pkg/db/querier_generated.go (4)

19-22: Looks correct for retrieving API by ID.
This method correctly retrieves the fields corresponding to the Api struct. Pay attention to downstream usage if no record is found, as it may return sql.ErrNoRows.


23-29: No concerns, methodically retrieves audit log target data.
This slice-based return type is appropriate for multiple results. Ensure call sites handle an empty slice scenario gracefully.


178-178: Updated query for retrieving workspaces.
Including subscriptions in the selected columns aligns with the schema changes. This query remains coherent.


473-473: Expanded selection for listing workspaces is consistent with new fields.
The extended fields in the ListWorkspaces query reflect schema changes (subscribing to the new subscriptions column).

go/apps/api/routes/v2_apis_create_api/handler.go (10)

1-10: Package declaration and imports look fine.
No concerns with these imported modules. They are standard libraries and internal packages that appear relevant to this feature.


24-26: Clear request/response type aliases.
Using aliases for OpenAPI-generated structs simplifies references. No issues found.


27-33: Services struct is well-organized.
It concisely groups dependencies needed by the handler, adhering to good dependency-injection patterns.


35-76: Route definition, root key verification, and request binding appear logical.

  1. Verifying the root key speeds up short-circuiting on authentication failures.
  2. Binding the request body into Request is straightforward; the error wrapping with fault is consistent with the rest of the codebase.
  3. Permission checks happen early, which is good practice.

77-91: Transaction management approach is sound.
Starting a transaction and deferring the rollback is a standard approach for ensuring atomic operations when subsequent steps fail.


92-106: Creating a new key ring.

  1. Generating a new keyAuthId with a UID prefix is consistent with your ID patterns.
  2. Inserting via InsertKeyringParams looks correct.
  3. Error handling is robust, wrapping with fault.INTERNAL_SERVER_ERROR.

108-122: Inserting the new API record.

  1. Inserting with InsertApi ensures the new API references the newly created key ring.
  2. Using the same transaction maintains consistency between the API record and its key ring.

124-152: Audit log insertion.
Recording creation events is essential for traceability. This is well-structured, including relevant details like actor info and resource data.


154-161: Transaction commit is properly handled.
Errors are wrapped, ensuring database integrity if commits fail.


162-171: Final JSON response.
Returning the newly created API’s ID and name is straightforward, aligning with the specified OpenAPI response structure.

go/pkg/db/schema.sql (5)

179-179: Workspace schema adjustments.

  1. Making org_id non-null and uniquely constrained emphasizes strict organizational linkage.
  2. Adding a subscriptions JSON column can accommodate flexible subscription data.
  3. Dropping the tenant_id-based uniqueness in favor of org_id uniqueness is consistent with the PR’s description.

Also applies to: 187-187, 194-194


244-244: New default value for audit_log.bucket.
Defaulting to 'unkey_mutations' is valid, but ensure any existing references are updated or handle the new default gracefully.


275-275: Audit log target bucket default.
Similarly, 'unkey_mutations' is used as a bucket default to align with audit_log. This keeps the data consistent across tables.


301-301: Index on audit_log.bucket.
Adding an index can help query performance for bucket-based lookups. Watch out for increased write overhead if logs are frequently inserted.


305-305: Index on audit_log_target.bucket.
Mirroring the index strategy of audit_log is consistent for bucket-based queries.

go/pkg/db/models_generated.go (4)

242-242: Field order changed in AuditLog struct.

The BucketID field has been moved to appear after the Bucket field in the AuditLog struct. This reordering aligns with the database schema changes where the bucket field is now a primary concept across audit log related tables.


256-264: New AuditLogBucket struct added to support bucket-based audit log organization.

This new struct introduces a dedicated table for managing audit log buckets, providing better organization and retention management for audit logs. The inclusion of DeleteProtection is consistent with similar protection mechanisms used for APIs, as seen in the provided code snippets.


270-270: Field order changed in AuditLogTarget struct.

The AuditLogID field has been moved to appear after the Bucket field in the AuditLogTarget struct, maintaining consistency with the schema changes seen in other audit log related structures.


457-472:

Details

❓ Verification inconclusive

Workspace struct updated with subscription management capabilities.

The Workspace struct has been updated to:

  1. Remove the PlanDowngradeRequest field (consistent with DB schema changes)
  2. Add a new Subscriptions field of type []byte to store subscription information

This change aligns with the TypeScript Subscriptions type defined in internal/billing/src/subscriptions.ts and suggests a shift toward a more flexible subscription management system.


🏁 Script executed:

#!/bin/bash
# Check if there are any references to the removed PlanDowngradeRequest field that might break
rg -i "PlanDowngradeRequest" --type go

Length of output: 38


Subscription management update in Workspace struct

  • The Workspace struct in go/pkg/db/models_generated.go (lines 457–472) now reflects the intended changes: the PlanDowngradeRequest field has been removed and a new Subscriptions field (of type []byte) has been added.
  • A repository-wide search for the removed PlanDowngradeRequest field returned no results, suggesting that no references remain. However, please manually verify this removal in the broader context of the codebase to ensure nothing was overlooked.
  • This change aligns the Go Subscriptions field with the corresponding TypeScript type defined in internal/billing/src/subscriptions.ts, supporting a more flexible subscription management system.
internal/db/drizzle/meta/0000_snapshot.json (5)

4-4: Schema snapshot ID updated.

The schema snapshot ID has been updated, indicating a new version of the database schema. This is expected when making structural changes to the database.


1214-1214: Workspaces indexes updated to enforce org_id uniqueness.

The workspace table's indexes have been cleared and a new unique constraint has been added for the org_id column. This ensures that each organization ID is unique across workspaces, preventing duplicate organizations.

Also applies to: 1222-1227


1521-1528: Added bucket column to audit_log table with default value.

A new bucket column has been added to the audit_log table with a default value of 'unkey_mutations' and a corresponding index. This change supports organizing audit logs into logical buckets for better management and querying.

Also applies to: 1625-1629


1742-1749: Added bucket column to audit_log_target table with default value.

Similar to the audit_log table, a bucket column has been added to the audit_log_target table with a default value and index. This maintains consistency between related tables and ensures proper bucket-based filtering.

Also applies to: 1808-1812


1114-1114:

Details

❓ Verification inconclusive

Organization ID is now required in workspaces table.

The notNull constraint for the org_id column has been changed from false to true, making it a required field. This ensures that every workspace is associated with an organization.


🏁 Script executed:

#!/bin/bash
# Check if existing code assumes org_id can be null
rg "org_id.*null" --type go

Length of output: 29


I'll generate a new verification script to search for both nil and null references related to org_id in the Go codebase. This should help us confirm whether any part of the code still assumes that org_id can be nullable.

Once we review the output of this script, we can determine if further manual verification is needed.


🏁 Script executed:

#!/bin/bash
# Search for instances where org_id may be compared to either nil or null in Go files,
# including a few context lines for clarity.
rg -C 5 'org_id.*(nil|null)' --type go

Length of output: 40


Action Required: Verify org_id nullable assumptions

The snapshot change in internal/db/drizzle/meta/0000_snapshot.json (line 1114) correctly updates the notNull constraint for the org_id column, ensuring every workspace is now associated with an organization. Our automated searches in the Go codebase did not return any evidence that any parts of the code expect org_id to be nullable. However, since the grep-based verifications produced no output, please manually verify that no conditional logic or error handling elsewhere assumes org_id might be null.

  • Confirm that no other parts of the code explicitly check for a null or nil value for org_id.
  • Review any related business logic in workspace handling that might be affected by this change.

@vercel vercel bot temporarily deployed to Preview – engineering April 13, 2025 08:56 Inactive
@vercel vercel bot temporarily deployed to Preview – play April 13, 2025 13:12 Inactive
@vercel vercel bot temporarily deployed to Preview – engineering April 13, 2025 13:12 Inactive
@vercel vercel bot temporarily deployed to Preview – www April 13, 2025 13:13 Inactive
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 (1)
.github/actions/install/action.yaml (1)

23-23: Ensure consistency of working directories.
The go mod download step now runs in ./go as per the restructuring. However, note that the subsequent "Install tparse" step (line 29) still uses the legacy ./apps/agent working directory. Verify if this is intentional or if it needs to be updated for consistency.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aeec9ac and 7ffc340.

⛔ Files ignored due to path filters (1)
  • go/go.sum is excluded by !**/*.sum
📒 Files selected for processing (2)
  • .github/actions/install/action.yaml (1 hunks)
  • go/go.mod (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (18)
  • GitHub Check: Test Go API Local / Test (Shard 4/8)
  • GitHub Check: Test Go API Local / Test (Shard 8/8)
  • GitHub Check: Test Packages / Test ./packages/rbac
  • GitHub Check: Test Packages / Test ./apps/dashboard
  • GitHub Check: Test Go API Local / Test (Shard 2/8)
  • GitHub Check: Test Go API Local / Test (Shard 5/8)
  • GitHub Check: Test Go API Local / Test (Shard 3/8)
  • GitHub Check: Test Go API Local / Test (Shard 1/8)
  • GitHub Check: Test Go API Local / Test (Shard 6/8)
  • GitHub Check: Test Packages / Test ./packages/hono
  • GitHub Check: Test Agent Local / test_agent_local
  • GitHub Check: Test Packages / Test ./internal/clickhouse
  • GitHub Check: Test Packages / Test ./packages/api
  • GitHub Check: Test Packages / Test ./internal/keys
  • GitHub Check: Test API / API Test Local
  • GitHub Check: Build / Build
  • GitHub Check: autofix
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (6)
.github/actions/install/action.yaml (1)

17-18: Update Go configuration paths to match the new structure.
The go-version-file and cache-dependency-path values have been updated from the previous ./apps/agent location to the new ./go directory. Confirm that all other build processes are aligned with this updated directory structure.

go/go.mod (5)

15-16: Upgrade dependency versions for API creation requirements.
The versions for github.com/pb33f/libopenapi-validator and github.com/prometheus/client_golang have been bumped to v0.3.1 and v1.22.0, respectively. These changes are critical to support the new /v2/apis/createApi endpoint. Please verify that all parts of the API functionality integrate seamlessly with these updated dependencies.


31-31: New dependency added: google.golang.org/protobuf.
A new dependency on google.golang.org/protobuf v1.36.6 has been introduced. This addition is likely needed for enhanced handling of API request/response protocols. Ensure that its usage is consistent and that it doesn’t conflict with other protobuf-related libraries.


105-105: Prometheus client model version update.
The dependency github.com/prometheus/client_model is updated to v0.6.2. Verify that the updated version remains compatible with any metrics or monitoring integrations in the application.


136-139: Upgrade of golang.org/x/crypto and golang.org/x/net.
Both golang.org/x/crypto and golang.org/x/net have been updated to v0.37.0 and v0.39.0, respectively. It is recommended to run integration tests to ensure no breaking changes occur due to these upgrades.


143-144: Update Genproto dependencies.
The google.golang.org/genproto/googleapis/api and google.golang.org/genproto/googleapis/rpc dependencies have been updated to newer revisions. These updates should support the new API endpoint functionality. Double-check that their changes are compatible with the generated API types and any related serialization logic.

@chronark chronark merged commit 878fa7f into main Apr 14, 2025
81 of 86 checks passed
@chronark chronark deleted the v2-api-create-api branch April 14, 2025 07:36
@coderabbitai coderabbitai bot mentioned this pull request Jul 21, 2025
18 tasks
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.

1 participant