Skip to content

chore: remove identityID from v2#3560

Merged
chronark merged 13 commits intomainfrom
feat/v2/keys.updateKey
Jul 15, 2025
Merged

chore: remove identityID from v2#3560
chronark merged 13 commits intomainfrom
feat/v2/keys.updateKey

Conversation

@Flo4604
Copy link
Member

@Flo4604 Flo4604 commented Jul 15, 2025

What does this PR do?

Removes identityID from responses and requests
fixes read only dsn flag
uses correct bind function

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • Chore (refactoring code, technical debt, workflow improvements)
  • Enhancement (small improvements)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How should this be tested?

  • Test A
  • Test B

Checklist

Required

  • Filled out the "How to test" section in this PR
  • Read Contributing Guide
  • Self-reviewed my own code
  • Commented on my code in hard-to-understand areas
  • Ran pnpm build
  • Ran pnpm fmt
  • Checked for warnings, there are none
  • Removed all console.logs
  • Merged the latest changes from main onto my branch with git pull origin main
  • My changes don't cause any responsiveness issues

Appreciated

  • If a UI change was made: Added a screen recording or screenshots to this PR
  • Updated the Unkey Docs if changes were necessary

Summary by CodeRabbit

  • New Features

    • Added support for automatically creating missing permissions when creating keys, enhancing key and identity management.
  • Breaking Changes

    • Identity operations now exclusively use external IDs; all internal identity ID fields and related union types removed from API requests, responses, and documentation.
    • Response data for identity and key operations no longer includes internal identity IDs, only external IDs and metadata.
  • Bug Fixes

    • Improved error handling for database "not found" cases across services.
  • Refactor

    • Simplified request body parsing and error handling throughout the API using generic binding functions.
    • Consolidated identity lookup logic to rely solely on external IDs.
    • Streamlined permission and role resolution inside transactions.
    • Removed redundant or complex union type handling in identity request bodies.
  • Documentation

    • Updated OpenAPI specs to remove internal identity IDs and simplify response descriptions.
  • Tests

    • Updated tests to remove identity ID usage and focus on external IDs.
    • Removed tests related to internal identity ID operations and permissions scoped by identity ID.
  • Chores

    • Minor formatting and whitespace improvements in SQL queries and code.

@changeset-bot
Copy link

changeset-bot bot commented Jul 15, 2025

⚠️ No Changeset found

Latest commit: 3c5467b

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

@vercel
Copy link

vercel bot commented Jul 15, 2025

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

2 Skipped Deployments
Name Status Preview Comments Updated (UTC)
dashboard ⬜️ Ignored (Inspect) Visit Preview Jul 15, 2025 3:15pm
engineering ⬜️ Ignored (Inspect) Visit Preview Jul 15, 2025 3:15pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 15, 2025

Warning

Rate limit exceeded

@Flo4604 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 27 minutes and 15 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 0da76e1 and 3c5467b.

📒 Files selected for processing (2)
  • go/apps/api/openapi/openapi.yaml (11 hunks)
  • go/apps/api/routes/v2_identities_update_identity/handler.go (7 hunks)
📝 Walkthrough

Walkthrough

This change removes support for union types and optional internal identity IDs from identity-related API request and response types, consolidating all identity operations to use only the external ID. The OpenAPI schema, Go structs, handlers, and tests are updated accordingly. Additional refactoring simplifies request binding and error handling throughout the codebase.

Changes

Files/Paths Change Summary
go/apps/api/openapi/gen.go, go/apps/api/openapi/openapi.yaml Removed union types and internal identity ID fields from identity-related request/response types and OpenAPI schemas; all identity operations now use only external ID. Simplified comments and descriptions, and removed related union handling code.
go/apps/api/routes/v2_identities_/handler.go, .../v2_identities_/200_test.go, .../400_test.go, .../401_test.go, .../403_test.go, .../404_test.go Refactored handlers and tests to remove support for identity ID and union types. All identity lookups, updates, deletions, and assertions now use external ID only. Removed related helper methods and permission checks.
go/apps/api/routes/v2_apis_/handler.go, go/apps/api/routes/v2_ratelimit_/handler.go Refactored request body binding to use generic zen.BindBody helper, simplifying error handling and code structure.
go/apps/api/routes/v2_apis_list_keys/handler.go, .../200_test.go, .../v2_keys_*/handler.go, .../v2_keys_verify_key/200_test.go Removed usage of internal identity ID in key-related handlers and tests; responses now include only external ID for identities.
go/apps/api/routes/v2_identities_list_identities/handler.go, .../200_test.go, .../403_test.go, .../cross_workspace_test.go Switched all identity matching and assertions from internal ID to external ID.
go/apps/api/routes/v2_identities_create_identity/handler.go, .../409_test.go Removed identity ID from creation response and related assertions; now relies on external ID for queries and assertions.
go/pkg/db/queries/permission_find_by_slugs.sql, .../role_find_by_names.sql, .../permission_find_by_slugs.sql_generated.go, .../role_find_by_names.sql_generated.go, .../querier_generated.go Added new SQL queries and generated Go code for finding permissions by slug and roles by name within a workspace.
go/apps/api/routes/v2_keys_create_key/handler.go Moved permission and role resolution to within transaction, supporting auto-creation. Added logic for identity association by external ID.
go/apps/ctrl/services/version/create_version.go, go/cmd/version/bootstrap.go, go/pkg/hydra/worker.go, go/pkg/hydra/store/sqlc_store.go.bak Standardized error handling for "not found" cases using db.IsNotFound(err) instead of direct SQL error comparison.
go/pkg/zen/README.md, go/pkg/zen/request_util.go, go/pkg/zen/middleware_errors.go Updated documentation and removed extraneous blank lines; no functional changes.
go/deploy/metald/internal/database/repository.go Removed trailing spaces in SQL queries; no logic changes.
go/cmd/api/main.go Renamed CLI flag for database replica connection string.
go/pkg/db/tx.go Minor formatting adjustment (blank lines) in transaction helper.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant API_Handler
    participant DB

    Client->>API_Handler: Send identity operation (create/get/update/delete) with externalId
    API_Handler->>DB: Query or modify identity by externalId
    DB-->>API_Handler: Identity data or operation result
    API_Handler-->>Client: Response (externalId, meta, ratelimits)
Loading

Possibly related PRs

  • feat: v2/identitiesDeleteIdentity #3151: Introduces union-type request body for deleting identities supporting both identity ID and external ID; this PR directly removes such union type and internal identity ID support, making the changes strongly related but in opposite directions.

Suggested labels

Needs Approval

Suggested reviewers

  • perkinsjr
  • mcstepp
  • MichaelUnkey
  • ogzhanolguncu
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @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.

Copy link
Member Author

Flo4604 commented Jul 15, 2025

This stack of pull requests is managed by Graphite. Learn more about stacking.

@Flo4604 Flo4604 mentioned this pull request Jul 15, 2025
18 tasks
@Flo4604 Flo4604 changed the title feat: keys.updateKey chore: remove identityID from v2 Jul 15, 2025
@Flo4604 Flo4604 marked this pull request as ready for review July 15, 2025 13:32
@github-actions
Copy link
Contributor

github-actions bot commented Jul 15, 2025

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

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: 11

🔭 Outside diff range comments (3)
go/apps/api/routes/v2_identities_create_identity/handler.go (1)

96-207: Consider returning the external ID in the response.

While the removal of internal identity ID aligns with the PR objectives, the response now returns an empty data object. Consider including the externalId in the response to help clients confirm the created identity without needing a separate query.

go/apps/api/routes/v2_keys_create_key/handler.go (1)

178-619: Performance consideration: Extended transaction scope.

Moving permission and role operations inside the transaction ensures consistency but significantly extends the transaction duration. This could lead to:

  • Increased lock contention
  • Slower response times
  • Potential deadlocks with concurrent operations

Consider whether all operations need to be atomic or if some could be moved outside the transaction with appropriate error handling.

go/apps/api/openapi/openapi.yaml (1)

2306-2410: Fix remaining identityId occurrences

Our repository scan still shows identityId used in several places. These references must be removed or migrated to externalId to avoid inconsistencies:

  • packages/api/src/openapi.d.ts
    • Lines 4342, 4399, 4590–4595, 4744: OpenAPI type definitions still reference identityId.
  • internal/db/src/schema/identity.ts
    • Lines 64–70, 83, 99: DB schema comments and column definitions.
  • internal/db/src/schema/keys.ts
    • Lines 45, 93, 122: Key schema indexed on identityId.
  • go/pkg/db/identity_list_ratelimits.sql_generated.go
    • Lines 26–27: Generated query method parameter.
  • tools/local/src/cmd/seed/event-generator.ts
    • Lines 175, 186: Seed script setting identityId.
  • tools/local/src/cmd/seed/apis.ts
    • Line 125: Seed data field.
  • internal/metrics/src/index.ts
    • Line 148: Zod schema allows identityId.

Next steps:

  • Update OpenAPI definitions in openapi.yaml and regenerate openapi.d.ts.
  • Rename or deprecate DB columns and indexes referencing identity_id, then run migrations and regenerate queries.
  • Remove identityId from seed generators and metrics schemas.
  • Run tests and regenerate any codegen clients to ensure no identityId remains.
♻️ Duplicate comments (1)
go/pkg/db/role_find_by_names.sql_generated.go (1)

34-41: Same optimization opportunity as in permission queries.

This file has the same empty slice handling pattern as permission_find_by_slugs.sql_generated.go. See the previous comment about optimizing sqlc templates.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 31bb842 and 75c47e8.

📒 Files selected for processing (57)
  • go/apps/api/openapi/gen.go (7 hunks)
  • go/apps/api/openapi/openapi.yaml (11 hunks)
  • go/apps/api/routes/v2_apis_create_api/handler.go (1 hunks)
  • go/apps/api/routes/v2_apis_delete_api/handler.go (1 hunks)
  • go/apps/api/routes/v2_apis_get_api/handler.go (1 hunks)
  • go/apps/api/routes/v2_apis_list_keys/200_test.go (0 hunks)
  • go/apps/api/routes/v2_apis_list_keys/handler.go (1 hunks)
  • go/apps/api/routes/v2_identities_create_identity/200_test.go (10 hunks)
  • go/apps/api/routes/v2_identities_create_identity/409_test.go (0 hunks)
  • go/apps/api/routes/v2_identities_create_identity/handler.go (5 hunks)
  • go/apps/api/routes/v2_identities_delete_identity/200_test.go (6 hunks)
  • go/apps/api/routes/v2_identities_delete_identity/400_test.go (5 hunks)
  • go/apps/api/routes/v2_identities_delete_identity/401_test.go (8 hunks)
  • go/apps/api/routes/v2_identities_delete_identity/403_test.go (7 hunks)
  • go/apps/api/routes/v2_identities_delete_identity/404_test.go (5 hunks)
  • go/apps/api/routes/v2_identities_delete_identity/handler.go (1 hunks)
  • go/apps/api/routes/v2_identities_get_identity/200_test.go (7 hunks)
  • go/apps/api/routes/v2_identities_get_identity/400_test.go (5 hunks)
  • go/apps/api/routes/v2_identities_get_identity/401_test.go (1 hunks)
  • go/apps/api/routes/v2_identities_get_identity/403_test.go (2 hunks)
  • go/apps/api/routes/v2_identities_get_identity/404_test.go (2 hunks)
  • go/apps/api/routes/v2_identities_get_identity/handler.go (1 hunks)
  • go/apps/api/routes/v2_identities_list_identities/200_test.go (4 hunks)
  • go/apps/api/routes/v2_identities_list_identities/403_test.go (2 hunks)
  • go/apps/api/routes/v2_identities_list_identities/cross_workspace_test.go (2 hunks)
  • go/apps/api/routes/v2_identities_list_identities/handler.go (0 hunks)
  • go/apps/api/routes/v2_identities_update_identity/200_test.go (5 hunks)
  • go/apps/api/routes/v2_identities_update_identity/400_test.go (6 hunks)
  • go/apps/api/routes/v2_identities_update_identity/401_test.go (5 hunks)
  • go/apps/api/routes/v2_identities_update_identity/403_test.go (3 hunks)
  • go/apps/api/routes/v2_identities_update_identity/404_test.go (1 hunks)
  • go/apps/api/routes/v2_identities_update_identity/handler.go (6 hunks)
  • go/apps/api/routes/v2_keys_create_key/handler.go (2 hunks)
  • go/apps/api/routes/v2_keys_get_key/handler.go (0 hunks)
  • go/apps/api/routes/v2_keys_verify_key/200_test.go (1 hunks)
  • go/apps/api/routes/v2_keys_verify_key/handler.go (0 hunks)
  • go/apps/api/routes/v2_ratelimit_delete_override/handler.go (1 hunks)
  • go/apps/api/routes/v2_ratelimit_get_override/handler.go (1 hunks)
  • go/apps/api/routes/v2_ratelimit_limit/handler.go (1 hunks)
  • go/apps/api/routes/v2_ratelimit_list_overrides/handler.go (1 hunks)
  • go/apps/api/routes/v2_ratelimit_set_override/handler.go (1 hunks)
  • go/apps/ctrl/services/version/create_version.go (3 hunks)
  • go/cmd/api/main.go (1 hunks)
  • go/cmd/version/bootstrap.go (2 hunks)
  • go/deploy/assetmanagerd/internal/registry/registry.go (2 hunks)
  • go/deploy/metald/internal/database/repository.go (1 hunks)
  • go/pkg/db/permission_find_by_slugs.sql_generated.go (1 hunks)
  • go/pkg/db/querier_generated.go (2 hunks)
  • go/pkg/db/queries/permission_find_by_slugs.sql (1 hunks)
  • go/pkg/db/queries/role_find_by_names.sql (1 hunks)
  • go/pkg/db/role_find_by_names.sql_generated.go (1 hunks)
  • go/pkg/db/tx.go (1 hunks)
  • go/pkg/hydra/store/sqlc_store.go.bak (7 hunks)
  • go/pkg/hydra/worker.go (8 hunks)
  • go/pkg/zen/README.md (5 hunks)
  • go/pkg/zen/middleware_errors.go (2 hunks)
  • go/pkg/zen/request_util.go (0 hunks)
💤 Files with no reviewable changes (6)
  • go/apps/api/routes/v2_identities_list_identities/handler.go
  • go/apps/api/routes/v2_keys_verify_key/handler.go
  • go/pkg/zen/request_util.go
  • go/apps/api/routes/v2_keys_get_key/handler.go
  • go/apps/api/routes/v2_apis_list_keys/200_test.go
  • go/apps/api/routes/v2_identities_create_identity/409_test.go
🧰 Additional context used
📓 Path-based instructions (3)
go/deploy/**/*.{go,js,ts,tsx,py,sh,md,txt,json,yaml,yml,ini,env,conf,rb,java,c,cpp,h,cs,rs,php,html,css,scss,xml}

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • go/deploy/CLAUDE.md
go/deploy/**/*.{go,js,ts,tsx,py,sh,md,txt,json,yaml,yml,ini,rb,java,c,cpp,h,cs,rs,php,html,css,scss,xml}

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • go/deploy/CLAUDE.md
go/deploy/{assetmanagerd,billaged,builderd,metald}/**/*.go

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • go/deploy/CLAUDE.md
🧠 Learnings (33)
📓 Common learnings
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
Learnt from: Flo4604
PR: unkeyed/unkey#2955
File: go/apps/api/routes/v2_identities_create_identity/handler.go:162-202
Timestamp: 2025-03-19T09:25:59.751Z
Learning: In the Unkey codebase, input validation for API endpoints is primarily handled through OpenAPI schema validation, which occurs before requests reach the handler code. For example, in the identities.createIdentity endpoint, minimum values for ratelimit duration and limit are defined in the OpenAPI schema rather than duplicating these checks in the handler.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3324
File: apps/dashboard/app/(app)/authorization/roles/components/table/components/actions/keys-table-action.popover.constants.tsx:17-18
Timestamp: 2025-06-19T11:48:05.070Z
Learning: In the authorization roles refactor, the RoleBasic type uses `roleId` as the property name for the role identifier, not `id`. This is consistent throughout the codebase in apps/dashboard/lib/trpc/routers/authorization/roles/query.ts.
go/apps/api/routes/v2_identities_get_identity/403_test.go (2)
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
go/apps/api/routes/v2_identities_delete_identity/401_test.go (2)
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
go/cmd/version/bootstrap.go (3)
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: In the Unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` directly instead of fetching the workspace separately for better performance and security.
Learnt from: chronark
PR: unkeyed/unkey#2180
File: apps/dashboard/lib/constants/workspace-navigations.tsx:56-118
Timestamp: 2024-10-04T20:44:38.489Z
Learning: When typing the `workspace` parameter in functions like `createWorkspaceNavigation`, prefer importing the `Workspace` type from the database module and picking the necessary keys (e.g., `features`) instead of redefining the interface.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: When querying or updating namespaces in the Unkey dashboard, always scope the operations to the current workspace using `eq(table.workspaceId, ctx.workspace.id)` to prevent cross-workspace access.
go/apps/api/routes/v2_identities_delete_identity/403_test.go (2)
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
go/apps/api/routes/v2_identities_get_identity/404_test.go (3)
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
Learnt from: Flo4604
PR: unkeyed/unkey#2955
File: go/apps/api/routes/v2_identities_create_identity/handler.go:162-202
Timestamp: 2025-03-19T09:25:59.751Z
Learning: In the Unkey codebase, input validation for API endpoints is primarily handled through OpenAPI schema validation, which occurs before requests reach the handler code. For example, in the identities.createIdentity endpoint, minimum values for ratelimit duration and limit are defined in the OpenAPI schema rather than duplicating these checks in the handler.
go/deploy/assetmanagerd/internal/registry/registry.go (1)
Learnt from: CR
PR: unkeyed/unkey#0
File: go/deploy/CLAUDE.md:0-0
Timestamp: 2025-07-09T08:42:29.316Z
Learning: Applies to go/deploy/{assetmanagerd,billaged,builderd,metald}/**/*.go : When a service's `*.go` code changes significantly, increase the patch-level version number.
go/apps/api/routes/v2_keys_verify_key/200_test.go (4)
Learnt from: MichaelUnkey
PR: unkeyed/unkey#2114
File: apps/api/src/routes/v1_keys_updateKey.error.test.ts:0-0
Timestamp: 2024-09-27T15:20:05.475Z
Learning: In the `v1/keys.updateKey` endpoint, the server validates the refill configuration before checking if the key exists. Therefore, tests can assert validation errors without needing to create the key first.
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
Learnt from: Flo4604
PR: unkeyed/unkey#2955
File: go/apps/api/routes/v2_identities_create_identity/handler.go:162-202
Timestamp: 2025-03-19T09:25:59.751Z
Learning: In the Unkey codebase, input validation for API endpoints is primarily handled through OpenAPI schema validation, which occurs before requests reach the handler code. For example, in the identities.createIdentity endpoint, minimum values for ratelimit duration and limit are defined in the OpenAPI schema rather than duplicating these checks in the handler.
go/apps/api/routes/v2_identities_get_identity/handler.go (3)
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3315
File: apps/dashboard/app/(app)/apis/[apiId]/_components/create-key/components/general-setup.tsx:40-50
Timestamp: 2025-06-19T13:01:55.338Z
Learning: In the create-key form's GeneralSetup component, the Controller is intentionally bound to "identityId" as the primary field while "externalId" is set explicitly via setValue. The ExternalIdField component has been designed to handle this pattern where it receives identityId as its value prop but manages both identityId and externalId through its onChange callback.
go/apps/api/routes/v2_identities_get_identity/401_test.go (2)
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
go/apps/api/routes/v2_identities_delete_identity/404_test.go (3)
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: When querying or updating namespaces in the Unkey dashboard, always scope the operations to the current workspace using `eq(table.workspaceId, ctx.workspace.id)` to prevent cross-workspace access.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: In the Unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` directly instead of fetching the workspace separately for better performance and security.
go/apps/api/routes/v2_apis_list_keys/handler.go (3)
Learnt from: Flo4604
PR: unkeyed/unkey#2955
File: go/apps/api/routes/v2_identities_create_identity/handler.go:162-202
Timestamp: 2025-03-19T09:25:59.751Z
Learning: In the Unkey codebase, input validation for API endpoints is primarily handled through OpenAPI schema validation, which occurs before requests reach the handler code. For example, in the identities.createIdentity endpoint, minimum values for ratelimit duration and limit are defined in the OpenAPI schema rather than duplicating these checks in the handler.
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
go/apps/ctrl/services/version/create_version.go (4)
Learnt from: CR
PR: unkeyed/unkey#0
File: go/deploy/CLAUDE.md:0-0
Timestamp: 2025-07-09T08:42:29.316Z
Learning: Applies to go/deploy/{assetmanagerd,billaged,builderd,metald}/**/*.go : When a service's `*.go` code changes significantly, increase the patch-level version number.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: In the Unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` directly instead of fetching the workspace separately for better performance and security.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: When querying or updating namespaces in the Unkey dashboard, always scope the operations to the current workspace using `eq(table.workspaceId, ctx.workspace.id)` to prevent cross-workspace access.
Learnt from: chronark
PR: unkeyed/unkey#2180
File: apps/dashboard/lib/constants/workspace-navigations.tsx:56-118
Timestamp: 2024-10-04T20:44:38.489Z
Learning: When typing the `workspace` parameter in functions like `createWorkspaceNavigation`, prefer importing the `Workspace` type from the database module and picking the necessary keys (e.g., `features`) instead of redefining the interface.
go/apps/api/routes/v2_identities_list_identities/cross_workspace_test.go (4)
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: In the Unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` directly instead of fetching the workspace separately for better performance and security.
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: When querying or updating namespaces in the Unkey dashboard, always scope the operations to the current workspace using `eq(table.workspaceId, ctx.workspace.id)` to prevent cross-workspace access.
go/pkg/hydra/store/sqlc_store.go.bak (2)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: When querying or updating namespaces in the Unkey dashboard, always scope the operations to the current workspace using `eq(table.workspaceId, ctx.workspace.id)` to prevent cross-workspace access.
go/apps/api/routes/v2_identities_update_identity/403_test.go (3)
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3315
File: apps/dashboard/app/(app)/apis/[apiId]/_components/create-key/components/general-setup.tsx:40-50
Timestamp: 2025-06-19T13:01:55.338Z
Learning: In the create-key form's GeneralSetup component, the Controller is intentionally bound to "identityId" as the primary field while "externalId" is set explicitly via setValue. The ExternalIdField component has been designed to handle this pattern where it receives identityId as its value prop but manages both identityId and externalId through its onChange callback.
go/apps/api/routes/v2_identities_list_identities/200_test.go (2)
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
go/apps/api/routes/v2_identities_update_identity/401_test.go (4)
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: In the Unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` directly instead of fetching the workspace separately for better performance and security.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: When querying or updating namespaces in the Unkey dashboard, always scope the operations to the current workspace using `eq(table.workspaceId, ctx.workspace.id)` to prevent cross-workspace access.
go/apps/api/routes/v2_identities_update_identity/400_test.go (4)
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
Learnt from: chronark
PR: unkeyed/unkey#2126
File: apps/api/src/routes/v1_ratelimit_getOverride.happy.test.ts:36-36
Timestamp: 2024-11-13T19:06:36.786Z
Learning: In the rate limit test files (e.g., `apps/api/src/routes/v1_ratelimit_getOverride.happy.test.ts`), URL parameters like `namespaceId` and `identifier` do not need to be URL-encoded in the test code because the values used are always considered safe within the test environment.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2866
File: apps/dashboard/app/(app)/ratelimits/[namespaceId]/logs/components/control-cloud/index.tsx:13-30
Timestamp: 2025-02-05T11:49:04.098Z
Learning: In the ratelimits logs context, "requestId" is used for single request IDs, while "requestIds" is used when dealing with multiple request IDs.
go/apps/api/routes/v2_identities_update_identity/404_test.go (2)
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
go/apps/api/routes/v2_identities_get_identity/400_test.go (4)
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
Learnt from: chronark
PR: unkeyed/unkey#2126
File: apps/api/src/routes/v1_ratelimit_getOverride.happy.test.ts:36-36
Timestamp: 2024-11-13T19:06:36.786Z
Learning: In the rate limit test files (e.g., `apps/api/src/routes/v1_ratelimit_getOverride.happy.test.ts`), URL parameters like `namespaceId` and `identifier` do not need to be URL-encoded in the test code because the values used are always considered safe within the test environment.
Learnt from: Flo4604
PR: unkeyed/unkey#2955
File: go/apps/api/routes/v2_identities_create_identity/handler.go:162-202
Timestamp: 2025-03-19T09:25:59.751Z
Learning: In the Unkey codebase, input validation for API endpoints is primarily handled through OpenAPI schema validation, which occurs before requests reach the handler code. For example, in the identities.createIdentity endpoint, minimum values for ratelimit duration and limit are defined in the OpenAPI schema rather than duplicating these checks in the handler.
go/apps/api/routes/v2_identities_delete_identity/handler.go (4)
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
Learnt from: Flo4604
PR: unkeyed/unkey#2955
File: go/apps/api/routes/v2_identities_create_identity/handler.go:162-202
Timestamp: 2025-03-19T09:25:59.751Z
Learning: In the Unkey codebase, input validation for API endpoints is primarily handled through OpenAPI schema validation, which occurs before requests reach the handler code. For example, in the identities.createIdentity endpoint, minimum values for ratelimit duration and limit are defined in the OpenAPI schema rather than duplicating these checks in the handler.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: In the Unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` directly instead of fetching the workspace separately for better performance and security.
go/apps/api/routes/v2_identities_get_identity/200_test.go (2)
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
go/apps/api/routes/v2_identities_delete_identity/400_test.go (4)
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
Learnt from: chronark
PR: unkeyed/unkey#2126
File: apps/api/src/routes/v1_ratelimit_getOverride.happy.test.ts:36-36
Timestamp: 2024-11-13T19:06:36.786Z
Learning: In the rate limit test files (e.g., `apps/api/src/routes/v1_ratelimit_getOverride.happy.test.ts`), URL parameters like `namespaceId` and `identifier` do not need to be URL-encoded in the test code because the values used are always considered safe within the test environment.
Learnt from: Flo4604
PR: unkeyed/unkey#2955
File: go/apps/api/routes/v2_identities_create_identity/handler.go:162-202
Timestamp: 2025-03-19T09:25:59.751Z
Learning: In the Unkey codebase, input validation for API endpoints is primarily handled through OpenAPI schema validation, which occurs before requests reach the handler code. For example, in the identities.createIdentity endpoint, minimum values for ratelimit duration and limit are defined in the OpenAPI schema rather than duplicating these checks in the handler.
go/apps/api/routes/v2_identities_delete_identity/200_test.go (2)
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
go/pkg/db/permission_find_by_slugs.sql_generated.go (1)
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: In the Unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` directly instead of fetching the workspace separately for better performance and security.
go/apps/api/routes/v2_keys_create_key/handler.go (3)
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
Learnt from: Flo4604
PR: unkeyed/unkey#2955
File: go/apps/api/routes/v2_identities_create_identity/handler.go:162-202
Timestamp: 2025-03-19T09:25:59.751Z
Learning: In the Unkey codebase, input validation for API endpoints is primarily handled through OpenAPI schema validation, which occurs before requests reach the handler code. For example, in the identities.createIdentity endpoint, minimum values for ratelimit duration and limit are defined in the OpenAPI schema rather than duplicating these checks in the handler.
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
go/apps/api/routes/v2_identities_update_identity/handler.go (4)
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
Learnt from: Flo4604
PR: unkeyed/unkey#2955
File: go/apps/api/routes/v2_identities_create_identity/handler.go:162-202
Timestamp: 2025-03-19T09:25:59.751Z
Learning: In the Unkey codebase, input validation for API endpoints is primarily handled through OpenAPI schema validation, which occurs before requests reach the handler code. For example, in the identities.createIdentity endpoint, minimum values for ratelimit duration and limit are defined in the OpenAPI schema rather than duplicating these checks in the handler.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: In the Unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` directly instead of fetching the workspace separately for better performance and security.
go/pkg/hydra/worker.go (2)
Learnt from: chronark
PR: unkeyed/unkey#3420
File: go/pkg/hydra/store/gorm/gorm.go:486-498
Timestamp: 2025-07-02T11:51:58.572Z
Learning: The Hydra package (go/pkg/hydra) is planned to be migrated from GORM to sqlc for database operations, which explains why raw SQL queries are acceptable in the current implementation.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: In the Unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` directly instead of fetching the workspace separately for better performance and security.
go/apps/api/routes/v2_identities_update_identity/200_test.go (2)
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
go/apps/api/openapi/openapi.yaml (9)

undefined

<retrieved_learning>
Learnt from: Flo4604
PR: #3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
</retrieved_learning>

<retrieved_learning>
Learnt from: chronark
PR: #2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In apps/api/src/routes/v1_keys_updateKey.ts, the code intentionally handles externalId and ownerId separately for clarity. The ownerId field will be removed in the future, simplifying the code.
</retrieved_learning>

<retrieved_learning>
Learnt from: Flo4604
PR: #3421
File: go/apps/api/openapi/openapi.yaml:196-200
Timestamp: 2025-07-03T05:58:10.699Z
Learning: In the Unkey codebase, OpenAPI 3.1 is used, which allows sibling keys (such as description) alongside $ref in schema objects. Do not flag this as an error in future reviews.
</retrieved_learning>

<retrieved_learning>
Learnt from: Flo4604
PR: #2955
File: go/apps/api/routes/v2_identities_create_identity/handler.go:162-202
Timestamp: 2025-03-19T09:25:59.751Z
Learning: In the Unkey codebase, input validation for API endpoints is primarily handled through OpenAPI schema validation, which occurs before requests reach the handler code. For example, in the identities.createIdentity endpoint, minimum values for ratelimit duration and limit are defined in the OpenAPI schema rather than duplicating these checks in the handler.
</retrieved_learning>

<retrieved_learning>
Learnt from: ogzhanolguncu
PR: #3315
File: apps/dashboard/app/(app)/apis/[apiId]/_components/create-key/components/general-setup.tsx:40-50
Timestamp: 2025-06-19T13:01:55.338Z
Learning: In the create-key form's GeneralSetup component, the Controller is intentionally bound to "identityId" as the primary field while "externalId" is set explicitly via setValue. The ExternalIdField component has been designed to handle this pattern where it receives identityId as its value prop but manages both identityId and externalId through its onChange callback.
</retrieved_learning>

<retrieved_learning>
Learnt from: MichaelUnkey
PR: #2114
File: apps/api/src/routes/v1_keys_updateKey.error.test.ts:0-0
Timestamp: 2024-09-27T15:20:05.475Z
Learning: In the v1/keys.updateKey endpoint, the server validates the refill configuration before checking if the key exists. Therefore, tests can assert validation errors without needing to create the key first.
</retrieved_learning>

<retrieved_learning>
Learnt from: Flo4604
PR: #3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For destructive operations like deletion in the Unkey API, oneOf validation is preferred over anyOf to enforce explicit targeting and prevent ambiguity.
</retrieved_learning>

<retrieved_learning>
Learnt from: chronark
PR: #2159
File: apps/api/src/routes/v1_keys_getWhoAmI.ts:12-13
Timestamp: 2024-10-03T09:51:43.832Z
Learning: When implementing endpoints that require a key, avoid sending the key as part of the URL. Use POST methods with the key in the request body instead, as URLs get logged and could leak sensitive information.
</retrieved_learning>

<retrieved_learning>
Learnt from: chronark
PR: #2159
File: apps/api/src/routes/v1_keys_getWhoAmI.ts:12-13
Timestamp: 2024-10-08T15:33:04.290Z
Learning: When implementing endpoints that require a key, avoid sending the key as part of the URL. Use POST methods with the key in the request body instead, as URLs get logged and could leak sensitive information.
</retrieved_learning>

go/apps/api/routes/v2_identities_create_identity/200_test.go (3)
Learnt from: Flo4604
PR: unkeyed/unkey#3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
Learnt from: chronark
PR: unkeyed/unkey#2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In `apps/api/src/routes/v1_keys_updateKey.ts`, the code intentionally handles `externalId` and `ownerId` separately for clarity. The `ownerId` field will be removed in the future, simplifying the code.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2872
File: apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts:36-39
Timestamp: 2025-04-08T09:34:24.576Z
Learning: In the Unkey dashboard, when making database queries involving workspaces, use `ctx.workspace.id` directly instead of fetching the workspace separately for better performance and security.
go/apps/api/openapi/gen.go (2)

undefined

<retrieved_learning>
Learnt from: Flo4604
PR: #3151
File: go/apps/api/openapi/gen.go:221-233
Timestamp: 2025-04-18T20:01:33.812Z
Learning: For identity deletion operations in the Unkey API, identityId takes precedence over externalId when both are provided in the request body.
</retrieved_learning>

<retrieved_learning>
Learnt from: chronark
PR: #2693
File: apps/api/src/routes/v1_keys_updateKey.ts:350-368
Timestamp: 2024-11-29T15:15:47.308Z
Learning: In apps/api/src/routes/v1_keys_updateKey.ts, the code intentionally handles externalId and ownerId separately for clarity. The ownerId field will be removed in the future, simplifying the code.
</retrieved_learning>

🧬 Code Graph Analysis (22)
go/pkg/db/tx.go (1)
go/pkg/fault/wrap.go (3)
  • Wrap (25-67)
  • Internal (75-89)
  • Public (97-111)
go/apps/api/routes/v2_identities_delete_identity/401_test.go (1)
go/apps/api/routes/v2_identities_delete_identity/handler.go (1)
  • Request (21-21)
go/apps/api/routes/v2_ratelimit_limit/handler.go (1)
go/pkg/zen/request_util.go (1)
  • BindBody (10-22)
go/cmd/version/bootstrap.go (1)
go/pkg/db/handle_err_no_rows.go (1)
  • IsNotFound (8-10)
go/apps/api/routes/v2_apis_delete_api/handler.go (1)
go/pkg/zen/request_util.go (1)
  • BindBody (10-22)
go/apps/api/routes/v2_ratelimit_delete_override/handler.go (1)
go/pkg/zen/request_util.go (1)
  • BindBody (10-22)
go/deploy/assetmanagerd/internal/registry/registry.go (1)
go/pkg/db/handle_err_no_rows.go (1)
  • IsNotFound (8-10)
go/apps/api/routes/v2_ratelimit_list_overrides/handler.go (1)
go/pkg/zen/request_util.go (1)
  • BindBody (10-22)
go/apps/api/routes/v2_identities_get_identity/handler.go (1)
go/pkg/db/identity_find_by_external_id.sql_generated.go (1)
  • FindIdentityByExternalIDParams (16-20)
go/apps/ctrl/services/version/create_version.go (1)
go/pkg/db/handle_err_no_rows.go (1)
  • IsNotFound (8-10)
go/pkg/zen/middleware_errors.go (1)
go/apps/api/openapi/gen.go (3)
  • InternalServerErrorResponse (211-217)
  • Meta (372-375)
  • BaseError (111-123)
go/apps/api/routes/v2_ratelimit_set_override/handler.go (1)
go/pkg/zen/request_util.go (1)
  • BindBody (10-22)
go/apps/api/routes/v2_identities_update_identity/401_test.go (2)
go/pkg/uid/uid.go (1)
  • IdentityPrefix (28-28)
go/apps/api/routes/v2_identities_update_identity/handler.go (1)
  • Request (24-24)
go/apps/api/routes/v2_apis_create_api/handler.go (1)
go/pkg/zen/request_util.go (1)
  • BindBody (10-22)
go/pkg/db/querier_generated.go (3)
go/pkg/hydra/store/db.go (1)
  • DBTX (8-13)
go/pkg/db/permission_find_by_slugs.sql_generated.go (2)
  • FindPermissionsBySlugsParams (17-20)
  • FindPermissionsBySlugsRow (22-25)
go/pkg/db/role_find_by_names.sql_generated.go (2)
  • FindRolesByNamesParams (17-20)
  • FindRolesByNamesRow (22-25)
go/apps/api/routes/v2_identities_delete_identity/handler.go (5)
go/pkg/zen/request_util.go (1)
  • BindBody (10-22)
go/pkg/rbac/query.go (1)
  • T (84-90)
go/pkg/rbac/permissions.go (2)
  • Tuple (175-184)
  • DeleteIdentity (160-160)
go/pkg/db/models_generated.go (1)
  • Identity (655-664)
go/pkg/db/identity_find_by_external_id.sql_generated.go (1)
  • FindIdentityByExternalIDParams (16-20)
go/deploy/metald/internal/database/repository.go (1)
go/pkg/db/handle_err_no_rows.go (1)
  • IsNotFound (8-10)
go/apps/api/routes/v2_identities_get_identity/200_test.go (2)
go/pkg/rbac/permissions.go (1)
  • CreateIdentity (151-151)
go/pkg/testutil/seed/seed.go (1)
  • CreateIdentityRequest (324-329)
go/apps/api/routes/v2_identities_delete_identity/200_test.go (1)
go/apps/api/routes/v2_identities_delete_identity/handler.go (1)
  • Request (21-21)
go/pkg/db/role_find_by_names.sql_generated.go (1)
go/pkg/hydra/store/db.go (2)
  • Queries (19-21)
  • DBTX (8-13)
go/pkg/db/permission_find_by_slugs.sql_generated.go (1)
go/pkg/hydra/store/db.go (2)
  • Queries (19-21)
  • DBTX (8-13)
go/pkg/hydra/worker.go (1)
go/pkg/db/handle_err_no_rows.go (1)
  • IsNotFound (8-10)
🪛 markdownlint-cli2 (0.17.2)
go/pkg/zen/README.md

94-94: Hard tabs
Column: 1

(MD010, no-hard-tabs)


95-95: Hard tabs
Column: 1

(MD010, no-hard-tabs)


96-96: Hard tabs
Column: 1

(MD010, no-hard-tabs)


173-173: Hard tabs
Column: 1

(MD010, no-hard-tabs)


174-174: Hard tabs
Column: 1

(MD010, no-hard-tabs)


175-175: Hard tabs
Column: 1

(MD010, no-hard-tabs)


176-176: Hard tabs
Column: 1

(MD010, no-hard-tabs)


177-177: Hard tabs
Column: 1

(MD010, no-hard-tabs)


178-178: Hard tabs
Column: 1

(MD010, no-hard-tabs)


179-179: Hard tabs
Column: 1

(MD010, no-hard-tabs)


181-181: Hard tabs
Column: 1

(MD010, no-hard-tabs)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (18)
  • GitHub Check: Test Go API Local / Test (Shard 4/8)
  • GitHub Check: Test Go API Local / Test (Shard 7/8)
  • GitHub Check: Test Go API Local / Test (Shard 8/8)
  • GitHub Check: Test Go API Local / Test (Shard 6/8)
  • GitHub Check: Test Go API Local / Test (Shard 1/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 2/8)
  • GitHub Check: Test Agent Local / test_agent_local
  • GitHub Check: Test API / API Test Local
  • GitHub Check: Build / Build
  • GitHub Check: Test Packages / Test ./packages/nextjs
  • GitHub Check: Test Packages / Test ./internal/resend
  • GitHub Check: Test Packages / Test ./internal/clickhouse
  • GitHub Check: Test Packages / Test ./packages/api
  • GitHub Check: Test Packages / Test ./internal/keys
  • GitHub Check: Test Packages / Test ./packages/cache
  • GitHub Check: Test Packages / Test ./internal/encryption
🔇 Additional comments (60)
go/apps/api/routes/v2_keys_verify_key/200_test.go (1)

506-506: Test assertion correctly updated to reflect API changes.

The removal of the Id field from the Identity struct assertion is consistent with the PR objective to remove identityID from v2 responses. The test continues to validate the essential fields (ExternalId, Meta, Ratelimits) while properly excluding the internal identity ID that's no longer exposed in the API.

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

127-127: LGTM: Formatting improvement enhances readability.

The added blank lines around the rollback error check improve visual separation of the error handling logic, making the code more readable.

Also applies to: 134-134

go/deploy/assetmanagerd/internal/registry/registry.go (1)

195-195: LGTM: Standardized error handling using abstracted helper.

The change from direct sql.ErrNoRows comparisons to db.IsNotFound(err) provides better error handling abstraction and consistency across the codebase. This follows the pattern established in other parts of the system.

Also applies to: 407-407

go/apps/api/routes/v2_ratelimit_get_override/handler.go (1)

52-55: LGTM: Simplified request binding using generic helper.

The refactoring to use zen.BindBody[Request](s) reduces boilerplate code and streamlines error handling. This change is consistent with the pattern applied across other route handlers in this PR.

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

33-33: LGTM: Simplified test structure aligns with API refactoring.

The removal of ptr.P() wrapper and direct assignment of UIDs to the ExternalId field simplifies the test code and aligns with the broader refactoring to consolidate identity identification using only external IDs.

Also applies to: 51-51, 69-69, 87-87, 105-105, 123-123, 146-146, 164-164

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

1-2: LGTM: Well-structured SQL query for batch permission retrieval.

The query efficiently retrieves permissions by multiple slugs within a workspace using sqlc's slice functionality for dynamic IN clauses. The structure is clear and follows good practices by filtering on workspace_id first.

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

25-25: LGTM! Consistent with identity ID removal.

The change from using a pointer to IdentityId to using ExternalId as a direct string correctly implements the PR's objective of removing internal identity ID support from v2.

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

216-216: LGTM! Flag rename aligns with PR objectives.

The flag name change from "database-readonly-replica" to "database-replica" is a clean simplification that aligns with the PR's DSN flag fix objective.

go/apps/api/routes/v2_ratelimit_set_override/handler.go (1)

55-58: LGTM! Improved request binding with better error handling.

The refactoring to use zen.BindBody[Request](s) is a good improvement that:

  • Reduces boilerplate code
  • Provides consistent error handling with proper fault wrapping
  • Aligns with the PR's objective to use the correct bind function

The generic function properly handles validation errors and returns appropriate fault codes as shown in the go/pkg/zen/request_util.go implementation.

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

27-32: LGTM! Consistent identity ID removal across all test cases.

All test cases have been consistently updated to:

  • Use ExternalId instead of IdentityId
  • Replace pointer usage with direct string assignment
  • Update variable names from identityID to externalID

This correctly implements the PR's objective of removing internal identity ID support from v2 APIs.

Also applies to: 47-52, 67-72, 87-92, 112-117

go/apps/api/routes/v2_identities_update_identity/404_test.go (1)

38-38: LGTM! Consistent with identity ID removal pattern.

The change to use ExternalId as a direct string instead of a pointer correctly implements the consolidation to external ID-only identity identification.

go/apps/api/routes/v2_ratelimit_delete_override/handler.go (1)

52-55: LGTM: Request body binding refactoring is consistent and correct.

The change to use zen.BindBody[Request](s) is a good refactoring that standardizes request parsing across handlers. The error handling is properly simplified since zen.BindBody already wraps errors with appropriate fault codes.

go/apps/api/routes/v2_identities_get_identity/handler.go (1)

63-67: LGTM: Identity lookup simplified to use external ID only.

The change to always use FindIdentityByExternalID aligns with the PR objective of removing identityID support from v2 API. This simplification removes the conditional logic and consolidates identity identification to use only external IDs, which is consistent with the broader API changes.

go/apps/api/routes/v2_apis_get_api/handler.go (1)

46-49: LGTM: Consistent request body binding refactoring.

The change to use zen.BindBody[Request](s) follows the same pattern being applied across the codebase for standardized request parsing and error handling.

go/apps/api/routes/v2_ratelimit_list_overrides/handler.go (1)

45-48: LGTM: Consistent request body binding refactoring.

The change to use zen.BindBody[Request](s) maintains consistency with the standardized request parsing pattern being applied across the API handlers.

go/cmd/version/bootstrap.go (1)

70-70: Good refactoring to use standardized error handling.

The change from direct sql.ErrNoRows comparison to db.IsNotFound(err) improves code consistency and maintainability by centralizing error handling logic.

Also applies to: 98-98

go/apps/api/routes/v2_identities_get_identity/403_test.go (1)

75-75: Consistent with API simplification to use only external ID.

The change from pointer to direct string value for ExternalId aligns with the PR objective of removing identityID support and consolidating identity identification to use only external IDs.

Also applies to: 93-93

go/apps/api/routes/v2_apis_list_keys/handler.go (2)

53-55: Good refactoring to use streamlined request binding.

The change to zen.BindBody[Request](s) simplifies the code by using a generic helper that handles error wrapping internally, making the handler more concise.


396-399: Consistent with removing identity ID from v2 API.

The removal of the Id field from the identity response aligns with the PR objective of consolidating identity identification to use only external IDs. The response now correctly includes only ExternalId, Meta, and Ratelimits.

go/apps/api/routes/v2_ratelimit_limit/handler.go (1)

62-65: Consistent refactoring to standardize request binding.

The change to zen.BindBody[Request](s) is part of a broader standardization effort across route handlers. This improves code consistency and maintainability by using a centralized helper function that handles error wrapping.

go/apps/api/routes/v2_identities_get_identity/404_test.go (1)

37-37: Consistent test updates for API simplification.

The change from pointer to direct string value for ExternalId is consistent with the broader API changes removing identityID support. The tests maintain proper coverage for both non-existent and deleted identity scenarios.

Also applies to: 78-78

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

1-2: LGTM! Well-structured batch query with proper workspace scoping.

The SQL query correctly implements batch role retrieval with workspace-scoped security using parameter binding. The use of sqlc.slice for the IN clause is appropriate for batch operations.

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

47-49: LGTM! Clean refactoring to use generic request binding.

The migration to zen.BindBody[Request](s) is well-executed. The error handling is correctly simplified since the generic function already handles fault wrapping internally (as shown in the relevant code snippet from go/pkg/zen/request_util.go).

go/apps/api/routes/v2_identities_update_identity/403_test.go (1)

42-42: LGTM! Test updates align with API changes.

The migration from IdentityId to ExternalId in test requests and assertions is consistent with the PR objective to remove internal identity IDs from v2 API. Test logic remains intact while adapting to the new API contract.

Also applies to: 64-64, 108-108, 113-113

go/apps/api/routes/v2_identities_list_identities/403_test.go (1)

112-112: LGTM! Consistent test updates for external ID usage.

The migration from identity.Id to identity.ExternalId in test assertions maintains test functionality while aligning with the API's shift to external-only identity identification.

Also applies to: 144-144, 147-147, 150-150

go/apps/api/routes/v2_identities_list_identities/cross_workspace_test.go (1)

56-56: LGTM! Improved test maintainability with consistent external ID usage.

The refactoring to use a variable for the external ID and updating the assertion to use ExternalId improves test readability while maintaining the cross-workspace security verification. The test correctly ensures workspace isolation is preserved.

Also applies to: 59-59, 82-82

go/apps/ctrl/services/version/create_version.go (1)

23-23: LGTM: Good refactoring to use centralized error handling.

The replacement of direct sql.ErrNoRows comparisons with db.IsNotFound(err) is a positive change that centralizes error detection logic and improves maintainability. The function calls are consistent across all locations and maintain the existing control flow.

Also applies to: 33-33, 62-62

go/apps/api/routes/v2_apis_delete_api/handler.go (1)

53-56: LGTM: Good refactoring to use generic request binding.

The change from the old pattern of declaring a variable and calling s.BindBody(&req) to using zen.BindBody[Request](s) is an improvement. The zen.BindBody function already provides appropriate fault wrapping internally, so removing the redundant error wrapping here is correct.

go/apps/api/routes/v2_identities_update_identity/200_test.go (1)

116-116: LGTM: Consistent removal of identityId usage.

The changes successfully eliminate identityId usage in favor of ExternalId as a non-pointer string, which aligns with the PR objective to remove identityId from v2. The test assertions have been updated appropriately to check ExternalId instead of the internal Id field.

Also applies to: 159-159, 167-167, 206-206, 214-214, 226-226, 234-234, 257-257

go/apps/api/routes/v2_identities_delete_identity/403_test.go (1)

34-34: LGTM: Consistent removal of identityId usage in authorization tests.

The changes successfully eliminate identityId usage in favor of ExternalId as a non-pointer string, which aligns with the PR objective to remove identityId from v2. The test scenarios for authorization continue to cover all relevant permission cases.

Also applies to: 53-53, 72-72, 91-91, 110-110, 132-132, 151-151

go/pkg/zen/middleware_errors.go (1)

24-51: Well-implemented context error handling.

The addition of explicit handling for context.Canceled and context.DeadlineExceeded errors is excellent. The placement before other error processing ensures proper precedence, and the HTTP status codes (499 for client closed, 408 for timeout) are appropriate. The error response structure maintains consistency with the existing error handling patterns.

go/pkg/hydra/worker.go (2)

912-912: Improved error handling using db.IsNotFound abstraction.

The change from direct sql.ErrNoRows comparison to db.IsNotFound(err) is a good improvement. This abstraction provides consistency across the codebase and uses the proper errors.Is comparison internally.


404-404: Good SQL formatting cleanup.

The removal of trailing spaces after table names and in subqueries improves code consistency and readability.

Also applies to: 408-408, 498-498, 502-502, 518-518, 522-522, 574-574, 578-578, 847-847, 851-851, 950-950

go/apps/api/routes/v2_identities_list_identities/200_test.go (1)

104-107: Consistent migration to external ID usage.

The systematic replacement of internal identity ID references with external ID usage throughout the test assertions aligns perfectly with the PR objective of removing identityId from v2 API. The test logic remains functionally equivalent while using the correct field.

Also applies to: 168-178, 216-216, 260-260

go/apps/api/routes/v2_identities_update_identity/400_test.go (1)

32-48: Clean migration away from identityId usage.

The systematic removal of identityId references and migration to externalId is well-executed. The test name change from "missing both identityId and externalId" to "missing externalId" accurately reflects the new API structure, and the direct string assignment pattern is cleaner than pointer usage.

Also applies to: 56-68, 71-89, 98-108

go/pkg/zen/README.md (1)

94-97: Updated example code reflects the new binding pattern.

The change from s.BindBody(&req) to zen.BindBody[CreateUserRequest](s) accurately demonstrates the new generic binding approach that's being adopted across the codebase. This simplifies the code and provides better type safety.

go/apps/api/routes/v2_identities_delete_identity/400_test.go (2)

33-33: Test name accurately reflects the simplified validation.

The test name change from "missing both identity ID and external ID" to "missing externalID" correctly reflects the API's shift to externalId-only identification.


48-48: Direct string assignments improve code clarity.

Replacing pointer wrappers with direct string assignments makes the test code cleaner and more readable while maintaining the same validation logic.

Also applies to: 62-62, 77-77, 92-92

go/apps/api/routes/v2_identities_delete_identity/404_test.go (1)

37-37: Consistent removal of pointer wrappers improves readability.

The direct string assignments are cleaner than the previous pointer wrapper approach and maintain the same test functionality.

Also applies to: 73-73, 88-88, 91-91, 104-104, 118-118

go/apps/api/routes/v2_identities_create_identity/200_test.go (3)

109-113: Database queries correctly updated for external ID lookup.

The replacement of FindIdentityByID with FindIdentityByExternalID is implemented correctly, properly scoping queries by workspace ID for security.

Also applies to: 131-135, 172-176, 231-235, 307-311, 378-382, 418-422


180-180: Rate limit queries correctly use identity ID from database result.

Using identity.ID from the database query result instead of the response body is the correct approach since the response no longer contains internal identity IDs.

Also applies to: 246-246


338-356: Multiple identities test logic properly updated.

The loop correctly queries each identity by external ID and collects the internal identity IDs from the database results for subsequent validation.

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

321-324: New bulk permission query method supports enhanced API functionality.

The FindPermissionsBySlugs method provides efficient bulk querying of permissions by their slugs, which aligns with the enhanced permission management capabilities mentioned in the PR.


428-431: New bulk role query method supports enhanced API functionality.

The FindRolesByNames method provides efficient bulk querying of roles by their names, complementing the permission query method for enhanced role management.

go/apps/api/routes/v2_identities_get_identity/400_test.go (3)

12-12: Import updated to support external ID generation.

The change from ptr to uid package aligns with the removal of pointer wrappers and the need to generate external IDs for testing.


30-30: Test name and error location correctly updated for externalId validation.

The test name change to "missing externalId" and the error location update to "/properties/externalId/minLength" correctly reflect the new validation schema.

Also applies to: 39-39


47-47: Direct string assignments and ID generation improve test clarity.

Replacing pointer wrappers with direct assignments and using uid.New() for generating test external IDs makes the test code cleaner and more maintainable.

Also applies to: 62-62, 76-76

go/apps/api/routes/v2_identities_delete_identity/handler.go (2)

51-54: LGTM! Clean request binding implementation.

The use of zen.BindBody[Request](s) is consistent with the PR's objective and simplifies the code while maintaining proper error handling through the generic helper.


71-75: LGTM! Simplified identity lookup.

The code now exclusively uses external ID for identity lookup, which aligns with the PR's objective to remove internal identity ID support.

go/apps/api/routes/v2_identities_get_identity/200_test.go (1)

53-376: LGTM! Comprehensive test coverage with external ID.

The tests have been properly updated to use ExternalId throughout, maintaining good coverage of various scenarios including edge cases like empty metadata and multiple rate limits.

go/apps/api/routes/v2_identities_delete_identity/200_test.go (1)

94-236: LGTM! Test suite properly updated for external ID deletion.

The tests correctly use ExternalId for all deletion requests and maintain comprehensive coverage including edge cases like duplicate key handling and audit log verification.

go/apps/api/routes/v2_identities_create_identity/handler.go (1)

59-62: LGTM! Consistent request binding.

The use of zen.BindBody[Request](s) maintains consistency across handlers.

go/apps/api/routes/v2_keys_create_key/handler.go (1)

202-246: LGTM! Identity auto-creation from external ID.

The implementation correctly handles identity lookup and creation using only the external ID. Note that this auto-creates identities if they don't exist, which should be documented in the API reference.

go/apps/api/routes/v2_identities_update_identity/handler.go (3)

59-61: Good refactoring to use generic binding.

The change to use zen.BindBody[Request](s) simplifies the code and aligns with the pattern used in other handlers.


398-398: Verify that returning request metadata is intentional.

The response now returns req.Meta directly instead of fetching and unmarshalling the actual stored metadata. This improves performance but could be misleading if the metadata update fails within the transaction.

Is this behavior intentional? If metadata updates can fail independently, consider fetching the actual stored metadata to ensure the response reflects the true state.


83-83: Good improvement to error formatting.

Using %q properly quotes and escapes the ratelimit name in error messages.

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

169-169: Verify the change from typed response to generic map.

The IdentitiesCreateIdentityResponseData type changed from a structured response to map[string]interface{}. While this provides flexibility, it reduces type safety and makes the API contract less clear for consumers.

Consider whether this aligns with your API design goals, as clients will lose compile-time type checking and IDE autocompletion for response fields.


294-295: Clear and concise documentation improvements.

The updated comments for KeysDeleteKeyResponseData and KeysUpdateKeyResponseData are more direct and clearly communicate that these are intentionally empty response objects.

Also applies to: 297-298


839-844: Successful removal of identityId fields aligns with PR objectives.

The consolidation to use only ExternalId in identity request bodies (V2IdentitiesDeleteIdentityRequestBody, V2IdentitiesGetIdentityRequestBody, and V2IdentitiesUpdateIdentityRequestBody) successfully implements the PR's goal of removing identityID from v2. This simplification:

  • Removes the complexity of handling precedence between identityId and externalId
  • Provides a cleaner, more consistent API interface
  • Aligns with the design decision to use only external identifiers

Also applies to: 854-856, 886-891


1174-1175: Consistent documentation pattern maintained.

The updated comments for the Data fields in V2KeysDeleteKeyResponseBody and V2KeysUpdateKeyResponseBody maintain consistency with the response type definitions, clearly indicating these are intentionally empty response objects.

Also applies to: 1616-1617

Copy link
Collaborator

I think we can whitelist this bot in the CLA, but I don’t recall how
@perkinsjr do you still know how to whitelist bots?

Copy link
Member

Yes I do.

Copy link
Member

Done

Copy link
Collaborator

🥨

Copy link
Collaborator

lol
:ty:

@chronark chronark disabled auto-merge July 15, 2025 15:41
@chronark chronark merged commit 79c1648 into main Jul 15, 2025
26 of 30 checks passed
@chronark chronark deleted the feat/v2/keys.updateKey branch July 15, 2025 15:41
@coderabbitai coderabbitai bot mentioned this pull request Oct 22, 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.

4 participants