Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
1 Skipped Deployment
|
|
📝 WalkthroughWalkthroughThis update enhances the OpenAPI schema and Go type definitions by adding comprehensive example data, refining documentation comments, clarifying response types, and tightening schema constraints. It notably changes Changes
Sequence Diagram(s)Not applicable: No new control flow or feature logic introduced; changes are documentation, schema, and type clarifications. Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested labels
Suggested reviewers
✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
|
Thank you for following the naming conventions for pull request titles! 🙏 |
There was a problem hiding this comment.
Actionable comments posted: 40
🔭 Outside diff range comments (11)
go/apps/api/openapi/spec/paths/v2/permissions/createRole/V2PermissionsCreateRoleResponseData.yaml (1)
7-13: Regex does not match description – role IDs should start withrole_The description mandates a
role_prefix, but the pattern allows any alphanumeric string. Update the pattern to prevent invalid IDs slipping through code-gen validation.- pattern: "^[a-zA-Z0-9_]+$" +# Must start with 'role_' followed by 1+ word chars + pattern: "^role_[a-zA-Z0-9_]+$"Failing to align these will allow responses that contradict the contract.
go/apps/api/openapi/spec/paths/v2/keys/deleteKey/V2KeysDeleteKeyResponseBody.yaml (1)
10-42: Consider dropping the duplicate unnamed example
example:duplicates the first entry inexamples:. Keeping both increases spec size without adding value and may confuse some generators that pick one arbitrarily.go/apps/api/openapi/spec/paths/v2/apis/getApi/V2ApisGetApiResponseBody.yaml (1)
11-63:examplesfield is invalid/mis-shaped for a Schema ObjectThis schema now contains both
example:(scalar) andexamples:(map of named examples). In OpenAPI 3.1:
exampleson a Schema Object must be an array of values (JSON-Schema semantics), not an object keyed by names.exampleandexamplesare mutually exclusive.The current form will fail strict OpenAPI validation.
- examples: - basicApiInfo: - summary: Basic API information - description: Standard response showing API ID and name - value: - meta: - requestId: req_1234abcd - data: - id: api_1234abcd - name: Payment Service Production +# Option A – keep a single canonical example (remove `examples`) +# (no further change needed, validators will be happy) + +# Option B – use JSON-Schema `examples` array +# examples: +# - meta: +# requestId: req_1234abcd +# data: +# id: api_1234abcd +# name: Payment Service ProductionPick one of the two approaches above; removing the
examplesblock is simplest.go/apps/api/openapi/spec/common/role.yaml (1)
59-70: Role example uses invalid permission fields / formats
name: users.readandslug: users-readboth violate the permission slug regex (^[a-zA-Z0-9_]+$).- The
Permissionschema does not expose a separatenamefield (it usesslug). Includingnamemay break tooling that resolves againstPermission.yaml.- - id: perm_1234567890abcdef - name: users.read - slug: users-read - description: Allows reading user profile information + - id: perm_1234567890abcdef + slug: users_read + description: Allows reading user profile informationgo/apps/api/openapi/spec/paths/v2/permissions/createRole/V2PermissionsCreateRoleRequestBody.yaml (1)
32-48:exampleskeyword is invalid inside a Schema object – remove or renameOAS 3.1 Schema objects may contain
example(singular) but notexamples.
Having both will fail validation and will break server/client generation tools.-example: - name: support.readonly - description: Provides read-only access for customer support representatives -examples: - adminRole: - summary: Create admin role - description: Create a role for administrative users - value: - name: admin - description: Full administrative access to all resources - editorRole: - summary: Create editor role - description: Create a role for content editors - value: - name: editor - description: Can create and edit content but not manage users +example: + name: support.readonly + description: Provides read-only access for customer-support representatives + +# If you need multiple examples, move them to the MediaType level +# (requestBody > content > application/json > examples) or keep them +# under a vendor extension, e.g. `x-examples:`.go/apps/api/openapi/spec/paths/v2/apis/listKeys/V2ApisListKeysResponseBody.yaml (1)
13-134:examplesobject violates JSON-Schema/OAS 3.1 – must be an array, not a mapInside a Schema Object the plural keyword must be:
examples: - { … } # array of example _values_A named map of examples is only valid in the Media Type or Parameter level, not within the schema itself.
This will break validation with tools likespeakeasy,oapi-codegen, and the OpenAPI VS Code plugin.Two possible fixes:
- examples: - dashboardKeyList: - summary: … - description: … - value: … + examples: + - summary: Dashboard key management display + description: Typical response for displaying user keys in a dashboard interface + value: … # keep the existing payloador move the named examples up one level to the surrounding
contentobject.Adjust the remaining named examples (
paginatedResponse,emptyResponse,decryptedKeyList) accordingly.go/apps/api/openapi/spec/paths/v2/keys/verifyKey/V2KeysVerifyKeyResponseBody.yaml (1)
11-48: Separateexampleandexamplesin your Schema Object
OAS 3.1 doesn’t allow a named‐examples mapping alongsideexamplein a Schema Object. You must choose one of the following fixes:
• Remove the top‐levelexampleblock under the schema, leaving only your namedexamples.
• Move theexamples:mapping into the Media Type (content: application/json:) section of the response.Files to update:
- go/apps/api/openapi/spec/paths/v2/keys/verifyKey/V2KeysVerifyKeyResponseBody.yaml
Minimal diff to remove the single example:
properties: meta: $ref: "../../../../common/Meta.yaml" data: "$ref": "./KeysVerifyKeyResponseData.yaml" additionalProperties: false -example: - meta: - requestId: req_1234567890abcdef - data: - code: VALID - valid: true - enabled: true - keyId: key_1234567890abcdef - name: Production API Key - permissions: - - documents.read - - documents.write - credits: 950 - expires: 1735689600000 - meta: - userId: user_12345 - plan: premium examples: validKey: summary: Valid key with full details …go/apps/api/openapi/spec/paths/v2/keys/getKey/V2KeysGetKeyResponseBody.yaml (1)
32-60: Examples block in schema is invalid JSON-Schema / OAS 3.1 usageThe
examplesproperty in a Schema Object must be a JSON-Schemaexamplesarray (JSON-Schema §8.3), not an object keyed by example name. Using a named map here will break strict validators and client generators.• File to update:
go/apps/api/openapi/spec/paths/v2/keys/getKey/V2KeysGetKeyResponseBody.yaml (remove theexamples:map at lines 32–60)
• Recommended fix #1: convert to a JSON-Schema array or vendor extension at the schema level:examples: - summary: Dashboard key information for display description: Typical response for displaying key details without decryption value: { … } - summary: Decrypted key for API playground description: Response including plaintext key for testing API calls value: { … } # …other scenariosOr, if you need custom keys, use a vendor extension such as
x-examples:in the same array form.
• Recommended fix #2 (preferred): move each named example into the response’s MediaType layer (application/json), e.g.:responses: '200': description: OK content: application/json: schema: $ref: ../spec/paths/v2/keys/getKey/V2KeysGetKeyResponseBody.yaml examples: dashboardKeyDetails: summary: Dashboard key information for display description: Typical response for displaying key details without decryption value: { … } apiPlaygroundWithDecryption: summary: Decrypted key for API playground description: Response including plaintext key for testing API calls value: { … } keyWithIdentity: summary: Key with associated identity information description: Response showing key linked to an identity value: { … }• If only one canonical example is needed, retain the schema’s singular
example:and drop the extra scenarios here.go/apps/api/openapi/spec/paths/v2/keys/removePermissions/V2KeysRemovePermissionsRequestBody.yaml (1)
24-37: Description refers toname, schema & example useslug– align wording for consistencyLines 24 (
"Use either ID for existing permissions or name for exact string matching.") conflicts with the newpermissionReferenceschema, which exposesslug, and the example below accordingly usesslug.
Rename the wording fromname→slug(or vice-versa) so docs, schema and examples speak the same language.- Use either ID for existing permissions or name for exact string matching. + Use either ID for existing permissions or slug for exact string matching.go/apps/api/openapi/spec/paths/v2/identities/createIdentity/V2IdentitiesCreateIdentityResponseBody.yaml (1)
10-32:examplesobject is invalid inside a Schema ‒ convert to array or move to Media-Type levelIn JSON Schema / OpenAPI 3.1 a
Schema Objectmay have:
example: single valueexamples: array of values (mirroring JSON Schema)Here,
examplesis a map keyed bybasic,withMetadata, which is only valid inside a Media Type Object. This will trip OpenAPI validators.Fix options:
- Keep schema-level
exampleand dropexamples:example: meta: requestId: req_1234567890abcdef data: identityId: id_1234567890abcdef -examples: - basic: - summary: Basic identity created - description: Successfully created a simple identity - value: { … } - withMetadata: - summary: Identity with metadata created - description: Created an identity with rich metadata and rate limits - value: { … }
- If multiple named examples are desired, move them under the
content: application/json:envelope for this response.go/apps/api/openapi/openapi-generated.yaml (1)
1784-1842: Example values violate declared regex patterns
slug: documents-read(line ~1789) contradicts pattern^[a-zA-Z0-9_.]+$→ hyphen not allowed.name: support.readonly(line ~1840) violates rolenamepattern^[a-zA-Z][a-zA-Z0-9_-]*$→ dot not allowed.Either relax the regexes or change the examples (preferred: keep validation strict, update examples):
- slug: documents-read + slug: documents.read - name: support.readonly + name: support_readonly
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (107)
go/apps/api/openapi/gen.go(8 hunks)go/apps/api/openapi/openapi-generated.yaml(124 hunks)go/apps/api/openapi/openapi-split.yaml(1 hunks)go/apps/api/openapi/spec/common/KeyCreditsData.yaml(1 hunks)go/apps/api/openapi/spec/common/KeyResponseData.yaml(1 hunks)go/apps/api/openapi/spec/common/addPermissionReference.yaml(1 hunks)go/apps/api/openapi/spec/common/identity.yaml(1 hunks)go/apps/api/openapi/spec/common/keyCreditsRefill.yaml(1 hunks)go/apps/api/openapi/spec/common/meta.yaml(1 hunks)go/apps/api/openapi/spec/common/pagination.yaml(1 hunks)go/apps/api/openapi/spec/common/permission.yaml(1 hunks)go/apps/api/openapi/spec/common/permissionReference.yaml(1 hunks)go/apps/api/openapi/spec/common/ratelimitOverride.yaml(1 hunks)go/apps/api/openapi/spec/common/ratelimitRequest.yaml(1 hunks)go/apps/api/openapi/spec/common/ratelimitResponse.yaml(1 hunks)go/apps/api/openapi/spec/common/role.yaml(1 hunks)go/apps/api/openapi/spec/common/roleReference.yaml(1 hunks)go/apps/api/openapi/spec/error/PreconditionFailedErrorResponse.yaml(1 hunks)go/apps/api/openapi/spec/error/badRequestErrorDetails.yaml(1 hunks)go/apps/api/openapi/spec/error/badRequestErrorResponse.yaml(1 hunks)go/apps/api/openapi/spec/error/baseError.yaml(1 hunks)go/apps/api/openapi/spec/error/conflictErrorResponse.yaml(1 hunks)go/apps/api/openapi/spec/error/forbiddenErrorResponse.yaml(1 hunks)go/apps/api/openapi/spec/error/internalServerErrorResponse.yaml(1 hunks)go/apps/api/openapi/spec/error/notFoundErrorResponse.yaml(1 hunks)go/apps/api/openapi/spec/error/unauthorizedErrorResponse.yaml(1 hunks)go/apps/api/openapi/spec/error/validationError.yaml(1 hunks)go/apps/api/openapi/spec/paths/chproxy/metrics/ChproxyMetricsRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/chproxy/metrics/ChproxyMetricsResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/chproxy/metrics/index.yaml(1 hunks)go/apps/api/openapi/spec/paths/chproxy/ratelimits/ChproxyRatelimitsRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/chproxy/ratelimits/ChproxyRatelimitsResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/chproxy/ratelimits/index.yaml(1 hunks)go/apps/api/openapi/spec/paths/chproxy/verifications/ChproxyVerificationsRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/chproxy/verifications/ChproxyVerificationsResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/chproxy/verifications/index.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/apis/createApi/V2ApisCreateApiRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/apis/createApi/V2ApisCreateApiResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/apis/createApi/V2ApisCreateApiResponseData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/apis/deleteApi/V2ApisDeleteApiRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/apis/deleteApi/V2ApisDeleteApiResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/apis/getApi/V2ApisGetApiRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/apis/getApi/V2ApisGetApiResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/apis/getApi/V2ApisGetApiResponseData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/apis/listKeys/V2ApisListKeysRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/apis/listKeys/V2ApisListKeysResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/apis/listKeys/V2ApisListKeysResponseData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/identities/createIdentity/V2IdentitiesCreateIdentityRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/identities/createIdentity/V2IdentitiesCreateIdentityResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/identities/createIdentity/V2IdentitiesCreateIdentityResponseData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/identities/deleteIdentity/V2IdentitiesDeleteIdentityRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/identities/deleteIdentity/V2IdentitiesDeleteIdentityResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/identities/getIdentity/V2IdentitiesGetIdentityRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/identities/getIdentity/V2IdentitiesGetIdentityResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/identities/getIdentity/V2IdentitiesGetIdentityResponseData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/identities/listIdentities/V2IdentitiesListIdentitiesRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/identities/listIdentities/V2IdentitiesListIdentitiesResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/identities/listIdentities/V2IdentitiesListIdentitiesResponseData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/identities/updateIdentity/V2IdentitiesUpdateIdentityRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/identities/updateIdentity/V2IdentitiesUpdateIdentityResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/addPermissions/V2KeysAddPermissionsRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/addPermissions/V2KeysAddPermissionsResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/addPermissions/V2KeysAddPermissionsResponseData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/addRoles/V2KeysAddRolesRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/addRoles/V2KeysAddRolesResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/addRoles/V2KeysAddRolesResponseData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/createKey/V2KeysCreateKeyRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/createKey/V2KeysCreateKeyResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/createKey/V2KeysCreateKeyResponseData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/deleteKey/KeysDeleteKeyResponseData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/deleteKey/V2KeysDeleteKeyRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/deleteKey/V2KeysDeleteKeyResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/deleteKey/index.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/getKey/V2KeysGetKeyRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/getKey/V2KeysGetKeyResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/removePermissions/V2KeysRemovePermissionsRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/removePermissions/V2KeysRemovePermissionsResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/removePermissions/V2KeysRemovePermissionsResponseData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/removeRoles/V2KeysRemoveRolesRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/removeRoles/V2KeysRemoveRolesResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/removeRoles/V2KeysRemoveRolesResponseData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/setPermissions/V2KeysSetPermissionsRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/setPermissions/V2KeysSetPermissionsResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/setPermissions/V2KeysSetPermissionsResponseData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/setRoles/V2KeysSetRolesRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/setRoles/V2KeysSetRolesResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/setRoles/V2KeysSetRolesResponseData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/updateCredits/V2KeysUpdateCreditsRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/updateCredits/V2KeysUpdateCreditsResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/updateKey/V2KeysUpdateKeyRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/updateKey/V2KeysUpdateKeyResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/updateKey/V2KeysUpdateKeyResponseData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/verifyKey/KeysVerifyKeyCredits.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/verifyKey/KeysVerifyKeyRatelimit.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/verifyKey/KeysVerifyKeyResponseData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/verifyKey/V2KeysVerifyKeyRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/verifyKey/V2KeysVerifyKeyResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/verifyKey/VerifyKeyRatelimitData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/liveness/V2LivenessResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/liveness/V2LivenessResponseData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/permissions/createPermission/V2PermissionsCreatePermissionRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/permissions/createPermission/V2PermissionsCreatePermissionResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/permissions/createPermission/V2PermissionsCreatePermissionResponseData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/permissions/createRole/V2PermissionsCreateRoleRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/permissions/createRole/V2PermissionsCreateRoleResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/permissions/createRole/V2PermissionsCreateRoleResponseData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/permissions/deletePermission/V2PermissionsDeletePermissionRequestBody.yaml(1 hunks)
⛔ Files not processed due to max files limit (29)
- go/apps/api/openapi/spec/paths/v2/permissions/deletePermission/V2PermissionsDeletePermissionResponseBody.yaml
- go/apps/api/openapi/spec/paths/v2/permissions/deleteRole/V2PermissionsDeleteRoleRequestBody.yaml
- go/apps/api/openapi/spec/paths/v2/permissions/deleteRole/V2PermissionsDeleteRoleResponseBody.yaml
- go/apps/api/openapi/spec/paths/v2/permissions/getPermission/V2PermissionsGetPermissionRequestBody.yaml
- go/apps/api/openapi/spec/paths/v2/permissions/getPermission/V2PermissionsGetPermissionResponseBody.yaml
- go/apps/api/openapi/spec/paths/v2/permissions/getPermission/V2PermissionsGetPermissionResponseData.yaml
- go/apps/api/openapi/spec/paths/v2/permissions/getRole/V2PermissionsGetRoleRequestBody.yaml
- go/apps/api/openapi/spec/paths/v2/permissions/getRole/V2PermissionsGetRoleResponseBody.yaml
- go/apps/api/openapi/spec/paths/v2/permissions/getRole/V2PermissionsGetRoleResponseData.yaml
- go/apps/api/openapi/spec/paths/v2/permissions/listPermissions/V2PermissionsListPermissionsRequestBody.yaml
- go/apps/api/openapi/spec/paths/v2/permissions/listPermissions/V2PermissionsListPermissionsResponseBody.yaml
- go/apps/api/openapi/spec/paths/v2/permissions/listPermissions/V2PermissionsListPermissionsResponseData.yaml
- go/apps/api/openapi/spec/paths/v2/permissions/listRoles/V2PermissionsListRolesRequestBody.yaml
- go/apps/api/openapi/spec/paths/v2/permissions/listRoles/V2PermissionsListRolesResponseBody.yaml
- go/apps/api/openapi/spec/paths/v2/permissions/listRoles/V2PermissionsListRolesResponseData.yaml
- go/apps/api/openapi/spec/paths/v2/ratelimit/deleteOverride/V2RatelimitDeleteOverrideRequestBody.yaml
- go/apps/api/openapi/spec/paths/v2/ratelimit/deleteOverride/V2RatelimitDeleteOverrideResponseBody.yaml
- go/apps/api/openapi/spec/paths/v2/ratelimit/deleteOverride/V2RatelimitDeleteOverrideResponseData.yaml
- go/apps/api/openapi/spec/paths/v2/ratelimit/getOverride/V2RatelimitGetOverrideRequestBody.yaml
- go/apps/api/openapi/spec/paths/v2/ratelimit/getOverride/V2RatelimitGetOverrideResponseBody.yaml
- go/apps/api/openapi/spec/paths/v2/ratelimit/limit/V2RatelimitLimitRequestBody.yaml
- go/apps/api/openapi/spec/paths/v2/ratelimit/limit/V2RatelimitLimitResponseBody.yaml
- go/apps/api/openapi/spec/paths/v2/ratelimit/limit/V2RatelimitLimitResponseData.yaml
- go/apps/api/openapi/spec/paths/v2/ratelimit/listOverrides/V2RatelimitListOverridesRequestBody.yaml
- go/apps/api/openapi/spec/paths/v2/ratelimit/listOverrides/V2RatelimitListOverridesResponseBody.yaml
- go/apps/api/openapi/spec/paths/v2/ratelimit/listOverrides/V2RatelimitListOverridesResponseData.yaml
- go/apps/api/openapi/spec/paths/v2/ratelimit/setOverride/V2RatelimitSetOverrideRequestBody.yaml
- go/apps/api/openapi/spec/paths/v2/ratelimit/setOverride/V2RatelimitSetOverrideResponseBody.yaml
- go/apps/api/openapi/spec/paths/v2/ratelimit/setOverride/V2RatelimitSetOverrideResponseData.yaml
🧰 Additional context used
🧠 Learnings (72)
📓 Common learnings
Learnt from: Flo4604
PR: unkeyed/unkey#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.
Learnt from: chronark
PR: unkeyed/unkey#3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
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/openapi/spec/common/ratelimitResponse.yaml (1)
Learnt from: chronark
PR: #2544
File: apps/api/src/pkg/env.ts:4-6
Timestamp: 2024-10-23T12:05:31.121Z
Learning: The cloudflareRatelimiter type definition in apps/api/src/pkg/env.ts should not have its interface changed; it should keep the limit method returning Promise<{ success: boolean }> without additional error properties.
go/apps/api/openapi/spec/common/meta.yaml (1)
Learnt from: ogzhanolguncu
PR: #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/openapi/spec/common/KeyCreditsData.yaml (1)
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.
go/apps/api/openapi/spec/paths/v2/identities/getIdentity/V2IdentitiesGetIdentityRequestBody.yaml (3)
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.
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.
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.
go/apps/api/openapi/spec/paths/v2/keys/deleteKey/KeysDeleteKeyResponseData.yaml (1)
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.
go/apps/api/openapi/spec/paths/v2/keys/verifyKey/V2KeysVerifyKeyRequestBody.yaml (6)
Learnt from: chronark
PR: #3617
File: go/apps/api/openapi/openapi.yaml:3309-3312
Timestamp: 2025-07-16T17:51:57.297Z
Learning: In the Unkey API OpenAPI schema, the permissions query regex for the verifyKey endpoint intentionally allows all whitespace characters (including tabs and newlines) via \s. Do not flag this as an error in future reviews.
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.
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.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:353-466
Timestamp: 2025-07-15T14:25:05.608Z
Learning: In the Unkey codebase, input validation for API endpoints is handled at the OpenAPI schema layer, which validates request fields like permission slugs (pattern: "^[a-zA-Z0-9_]+$", length: 1-100 characters) before requests reach the handler code. This validation occurs during the zen.BindBody call in handlers.
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.
Learnt from: ogzhanolguncu
PR: #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/openapi/spec/paths/v2/keys/updateKey/V2KeysUpdateKeyResponseData.yaml (2)
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.
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.
go/apps/api/openapi/spec/paths/v2/keys/updateKey/V2KeysUpdateKeyRequestBody.yaml (4)
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.
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.
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.
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.
go/apps/api/openapi/spec/paths/v2/keys/setPermissions/V2KeysSetPermissionsResponseBody.yaml (1)
Learnt from: chronark
PR: #3617
File: go/apps/api/openapi/openapi.yaml:3309-3312
Timestamp: 2025-07-16T17:51:57.297Z
Learning: In the Unkey API OpenAPI schema, the permissions query regex for the verifyKey endpoint intentionally allows all whitespace characters (including tabs and newlines) via \s. Do not flag this as an error in future reviews.
go/apps/api/openapi/spec/paths/chproxy/metrics/index.yaml (2)
Learnt from: ogzhanolguncu
PR: #2825
File: apps/dashboard/app/(app)/logs/components/table/query-logs.schema.ts:49-58
Timestamp: 2025-01-30T20:43:19.720Z
Learning: Status code validation is handled at the ClickHouse query level rather than in the schema, as invalid status codes will cause query failures that are caught by TRPC error handling.
Learnt from: chronark
PR: #3161
File: go/pkg/clickhouse/schema/databases/001_verifications/002_raw_key_verifications_v1.sql:31-33
Timestamp: 2025-04-22T14:40:51.459Z
Learning: The ClickHouse table schemas in the codebase mirror the production environment and cannot be modified directly in PRs without careful migration planning.
go/apps/api/openapi/spec/error/internalServerErrorResponse.yaml (1)
Learnt from: Flo4604
PR: #3647
File: go/apps/api/openapi/openapi-generated.yaml:3569-3575
Timestamp: 2025-07-22T18:09:41.800Z
Learning: In the Unkey codebase, using non-standard HTTP status code 529 for internal-only endpoints is acceptable and should not be flagged as an issue in future reviews.
go/apps/api/openapi/spec/paths/v2/keys/verifyKey/KeysVerifyKeyCredits.yaml (1)
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.
go/apps/api/openapi/spec/paths/v2/identities/deleteIdentity/V2IdentitiesDeleteIdentityResponseBody.yaml (1)
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.
go/apps/api/openapi/spec/error/forbiddenErrorResponse.yaml (1)
Learnt from: ogzhanolguncu
PR: #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/openapi/spec/paths/v2/keys/deleteKey/index.yaml (2)
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.
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.
go/apps/api/openapi/spec/common/role.yaml (3)
Learnt from: AkshayBandi027
PR: #2215
File: apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx:28-29
Timestamp: 2024-10-08T15:33:04.290Z
Learning: In authorization/roles/[roleId]/update-role.tsx, the tag role-${role.id} is revalidated after updating a role to ensure that the caching mechanism is properly handled for roles.
Learnt from: ogzhanolguncu
PR: #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.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
go/apps/api/openapi/spec/paths/v2/apis/getApi/V2ApisGetApiRequestBody.yaml (1)
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.
go/apps/api/openapi/spec/common/keyCreditsRefill.yaml (1)
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.
go/apps/api/openapi/spec/error/badRequestErrorResponse.yaml (4)
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.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:353-466
Timestamp: 2025-07-15T14:25:05.608Z
Learning: In the Unkey codebase, input validation for API endpoints is handled at the OpenAPI schema layer, which validates request fields like permission slugs (pattern: "^[a-zA-Z0-9_]+$", length: 1-100 characters) before requests reach the handler code. This validation occurs during the zen.BindBody call in handlers.
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.
Learnt from: ogzhanolguncu
PR: #3321
File: apps/dashboard/lib/trpc/routers/authorization/roles/keys/schema-with-helpers.ts:5-8
Timestamp: 2025-06-18T12:28:10.449Z
Learning: In the unkey dashboard application, API validation for pagination limits is controlled at the UI level rather than requiring additional server-side validation, as the APIs are internal and protected by UI logic.
go/apps/api/openapi/spec/paths/v2/apis/listKeys/V2ApisListKeysRequestBody.yaml (4)
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.
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.
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.
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.
go/apps/api/openapi/spec/paths/chproxy/verifications/ChproxyVerificationsRequestBody.yaml (2)
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.
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.
go/apps/api/openapi/spec/paths/v2/identities/listIdentities/V2IdentitiesListIdentitiesRequestBody.yaml (1)
Learnt from: ogzhanolguncu
PR: #2896
File: internal/clickhouse/src/ratelimits.ts:468-592
Timestamp: 2025-02-21T11:15:16.185Z
Learning: The cursor logic in getRatelimitOverviewLogs query uses (time, request_id) < (cursorTime, cursorRequestId) comparison which works well with descending order but may need adjustment for ascending sorts based on real usage patterns.
go/apps/api/openapi/spec/paths/v2/identities/getIdentity/V2IdentitiesGetIdentityResponseData.yaml (1)
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.
go/apps/api/openapi/spec/paths/chproxy/ratelimits/index.yaml (3)
Learnt from: chronark
PR: #2544
File: apps/api/src/pkg/env.ts:4-6
Timestamp: 2024-10-23T12:05:31.121Z
Learning: The cloudflareRatelimiter type definition in apps/api/src/pkg/env.ts should not have its interface changed; it should keep the limit method returning Promise<{ success: boolean }> without additional error properties.
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.
Learnt from: CR
PR: unkeyed/unkey#0
File: go/deploy/CLAUDE.md:0-0
Timestamp: 2025-07-21T18:05:58.236Z
Learning: Applies to go/deploy/**/*.{go,js,ts,tsx,py,sh,md,txt,json,yaml,yml,ini,env,conf,html,css,scss,xml,c,h,cpp,java,rb,rs,php,pl,sql} : Update relevant anchors when modifying associated code.
go/apps/api/openapi/spec/paths/v2/keys/addPermissions/V2KeysAddPermissionsResponseBody.yaml (2)
Learnt from: chronark
PR: #3617
File: go/apps/api/openapi/openapi.yaml:3309-3312
Timestamp: 2025-07-16T17:51:57.297Z
Learning: In the Unkey API OpenAPI schema, the permissions query regex for the verifyKey endpoint intentionally allows all whitespace characters (including tabs and newlines) via \s. Do not flag this as an error in future reviews.
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.
go/apps/api/openapi/spec/paths/v2/keys/addRoles/V2KeysAddRolesRequestBody.yaml (5)
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.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
Learnt from: ogzhanolguncu
PR: #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.
Learnt from: AkshayBandi027
PR: #2215
File: apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx:28-29
Timestamp: 2024-10-08T15:33:04.290Z
Learning: In authorization/roles/[roleId]/update-role.tsx, the tag role-${role.id} is revalidated after updating a role to ensure that the caching mechanism is properly handled for roles.
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.
go/apps/api/openapi/spec/paths/v2/permissions/createRole/V2PermissionsCreateRoleResponseData.yaml (2)
Learnt from: ogzhanolguncu
PR: #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.
Learnt from: AkshayBandi027
PR: #2215
File: apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx:28-29
Timestamp: 2024-10-08T15:33:04.290Z
Learning: In authorization/roles/[roleId]/update-role.tsx, the tag role-${role.id} is revalidated after updating a role to ensure that the caching mechanism is properly handled for roles.
go/apps/api/openapi/spec/common/identity.yaml (2)
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.
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.
go/apps/api/openapi/spec/paths/v2/keys/verifyKey/KeysVerifyKeyRatelimit.yaml (3)
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.
Learnt from: chronark
PR: #2544
File: apps/api/src/pkg/env.ts:4-6
Timestamp: 2024-10-23T12:05:31.121Z
Learning: The cloudflareRatelimiter type definition in apps/api/src/pkg/env.ts should not have its interface changed; it should keep the limit method returning Promise<{ success: boolean }> without additional error properties.
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.
go/apps/api/openapi/spec/paths/v2/keys/removePermissions/V2KeysRemovePermissionsRequestBody.yaml (5)
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.
Learnt from: chronark
PR: #3617
File: go/apps/api/openapi/openapi.yaml:3309-3312
Timestamp: 2025-07-16T17:51:57.297Z
Learning: In the Unkey API OpenAPI schema, the permissions query regex for the verifyKey endpoint intentionally allows all whitespace characters (including tabs and newlines) via \s. Do not flag this as an error in future reviews.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:353-466
Timestamp: 2025-07-15T14:25:05.608Z
Learning: In the Unkey codebase, input validation for API endpoints is handled at the OpenAPI schema layer, which validates request fields like permission slugs (pattern: "^[a-zA-Z0-9_]+$", length: 1-100 characters) before requests reach the handler code. This validation occurs during the zen.BindBody call in handlers.
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.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
go/apps/api/openapi/spec/paths/v2/apis/listKeys/V2ApisListKeysResponseBody.yaml (2)
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.
Learnt from: ogzhanolguncu
PR: #3321
File: apps/dashboard/lib/trpc/routers/authorization/roles/keys/schema-with-helpers.ts:5-8
Timestamp: 2025-06-18T12:28:10.449Z
Learning: In the unkey dashboard application, API validation for pagination limits is controlled at the UI level rather than requiring additional server-side validation, as the APIs are internal and protected by UI logic.
go/apps/api/openapi/spec/paths/v2/keys/removePermissions/V2KeysRemovePermissionsResponseBody.yaml (1)
Learnt from: chronark
PR: #3617
File: go/apps/api/openapi/openapi.yaml:3309-3312
Timestamp: 2025-07-16T17:51:57.297Z
Learning: In the Unkey API OpenAPI schema, the permissions query regex for the verifyKey endpoint intentionally allows all whitespace characters (including tabs and newlines) via \s. Do not flag this as an error in future reviews.
go/apps/api/openapi/spec/paths/chproxy/verifications/index.yaml (4)
Learnt from: ogzhanolguncu
PR: #2825
File: apps/dashboard/app/(app)/logs/components/table/query-logs.schema.ts:49-58
Timestamp: 2025-01-30T20:43:19.720Z
Learning: Status code validation is handled at the ClickHouse query level rather than in the schema, as invalid status codes will cause query failures that are caught by TRPC error handling.
Learnt from: chronark
PR: #3161
File: go/pkg/clickhouse/schema/databases/001_verifications/002_raw_key_verifications_v1.sql:31-33
Timestamp: 2025-04-22T14:40:51.459Z
Learning: The ClickHouse table schemas in the codebase mirror the production environment and cannot be modified directly in PRs without careful migration planning.
Learnt from: chronark
PR: #3617
File: go/apps/api/openapi/openapi.yaml:3309-3312
Timestamp: 2025-07-16T17:51:57.297Z
Learning: In the Unkey API OpenAPI schema, the permissions query regex for the verifyKey endpoint intentionally allows all whitespace characters (including tabs and newlines) via \s. Do not flag this as an error in future reviews.
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.
go/apps/api/openapi/spec/paths/chproxy/ratelimits/ChproxyRatelimitsRequestBody.yaml (2)
Learnt from: chronark
PR: #2544
File: apps/api/src/pkg/env.ts:4-6
Timestamp: 2024-10-23T12:05:31.121Z
Learning: The cloudflareRatelimiter type definition in apps/api/src/pkg/env.ts should not have its interface changed; it should keep the limit method returning Promise<{ success: boolean }> without additional error properties.
Learnt from: ogzhanolguncu
PR: #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/openapi/spec/paths/v2/apis/getApi/V2ApisGetApiResponseBody.yaml (1)
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.
go/apps/api/openapi/spec/paths/v2/identities/updateIdentity/V2IdentitiesUpdateIdentityResponseBody.yaml (1)
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.
go/apps/api/openapi/spec/paths/v2/keys/removeRoles/V2KeysRemoveRolesResponseData.yaml (1)
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
go/apps/api/openapi/spec/paths/v2/keys/verifyKey/VerifyKeyRatelimitData.yaml (1)
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.
go/apps/api/openapi/spec/paths/v2/keys/createKey/V2KeysCreateKeyRequestBody.yaml (3)
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.
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.
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.
go/apps/api/openapi/spec/paths/v2/keys/verifyKey/V2KeysVerifyKeyResponseBody.yaml (3)
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.
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.
Learnt from: chronark
PR: #3617
File: go/apps/api/openapi/openapi.yaml:3309-3312
Timestamp: 2025-07-16T17:51:57.297Z
Learning: In the Unkey API OpenAPI schema, the permissions query regex for the verifyKey endpoint intentionally allows all whitespace characters (including tabs and newlines) via \s. Do not flag this as an error in future reviews.
go/apps/api/openapi/spec/paths/v2/permissions/createRole/V2PermissionsCreateRoleRequestBody.yaml (3)
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
Learnt from: AkshayBandi027
PR: #2215
File: apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx:28-29
Timestamp: 2024-10-08T15:33:04.290Z
Learning: In authorization/roles/[roleId]/update-role.tsx, the tag role-${role.id} is revalidated after updating a role to ensure that the caching mechanism is properly handled for roles.
Learnt from: ogzhanolguncu
PR: #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/openapi/spec/paths/v2/keys/createKey/V2KeysCreateKeyResponseBody.yaml (1)
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.
go/apps/api/openapi/spec/paths/v2/identities/createIdentity/V2IdentitiesCreateIdentityResponseBody.yaml (1)
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.
go/apps/api/openapi/spec/common/ratelimitRequest.yaml (1)
Learnt from: chronark
PR: #2544
File: apps/api/src/pkg/env.ts:4-6
Timestamp: 2024-10-23T12:05:31.121Z
Learning: The cloudflareRatelimiter type definition in apps/api/src/pkg/env.ts should not have its interface changed; it should keep the limit method returning Promise<{ success: boolean }> without additional error properties.
go/apps/api/openapi/spec/paths/v2/keys/verifyKey/KeysVerifyKeyResponseData.yaml (3)
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.
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.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:353-466
Timestamp: 2025-07-15T14:25:05.608Z
Learning: In the Unkey codebase, input validation for API endpoints is handled at the OpenAPI schema layer, which validates request fields like permission slugs (pattern: "^[a-zA-Z0-9_]+$", length: 1-100 characters) before requests reach the handler code. This validation occurs during the zen.BindBody call in handlers.
go/apps/api/openapi/spec/paths/v2/keys/setRoles/V2KeysSetRolesRequestBody.yaml (5)
Learnt from: ogzhanolguncu
PR: #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.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
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.
Learnt from: AkshayBandi027
PR: #2215
File: apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx:28-29
Timestamp: 2024-10-08T15:33:04.290Z
Learning: In authorization/roles/[roleId]/update-role.tsx, the tag role-${role.id} is revalidated after updating a role to ensure that the caching mechanism is properly handled for roles.
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.
go/apps/api/openapi/spec/paths/v2/keys/removePermissions/V2KeysRemovePermissionsResponseData.yaml (1)
Learnt from: chronark
PR: #3617
File: go/apps/api/openapi/openapi.yaml:3309-3312
Timestamp: 2025-07-16T17:51:57.297Z
Learning: In the Unkey API OpenAPI schema, the permissions query regex for the verifyKey endpoint intentionally allows all whitespace characters (including tabs and newlines) via \s. Do not flag this as an error in future reviews.
go/apps/api/openapi/spec/paths/v2/keys/addPermissions/V2KeysAddPermissionsRequestBody.yaml (4)
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.
Learnt from: chronark
PR: #3617
File: go/apps/api/openapi/openapi.yaml:3309-3312
Timestamp: 2025-07-16T17:51:57.297Z
Learning: In the Unkey API OpenAPI schema, the permissions query regex for the verifyKey endpoint intentionally allows all whitespace characters (including tabs and newlines) via \s. Do not flag this as an error in future reviews.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:353-466
Timestamp: 2025-07-15T14:25:05.608Z
Learning: In the Unkey codebase, input validation for API endpoints is handled at the OpenAPI schema layer, which validates request fields like permission slugs (pattern: "^[a-zA-Z0-9_]+$", length: 1-100 characters) before requests reach the handler code. This validation occurs during the zen.BindBody call in handlers.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
go/apps/api/openapi/spec/common/permission.yaml (2)
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.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
go/apps/api/openapi/spec/paths/v2/identities/deleteIdentity/V2IdentitiesDeleteIdentityRequestBody.yaml (3)
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.
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.
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.
go/apps/api/openapi/spec/paths/v2/keys/removeRoles/V2KeysRemoveRolesRequestBody.yaml (5)
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.
Learnt from: ogzhanolguncu
PR: #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.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
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.
Learnt from: AkshayBandi027
PR: #2215
File: apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx:28-29
Timestamp: 2024-10-08T15:33:04.290Z
Learning: In authorization/roles/[roleId]/update-role.tsx, the tag role-${role.id} is revalidated after updating a role to ensure that the caching mechanism is properly handled for roles.
go/apps/api/openapi/spec/common/addPermissionReference.yaml (1)
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.
go/apps/api/openapi/spec/paths/v2/identities/createIdentity/V2IdentitiesCreateIdentityRequestBody.yaml (4)
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.
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.
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.
Learnt from: ogzhanolguncu
PR: #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/openapi/spec/common/permissionReference.yaml (3)
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:353-466
Timestamp: 2025-07-15T14:25:05.608Z
Learning: In the Unkey codebase, input validation for API endpoints is handled at the OpenAPI schema layer, which validates request fields like permission slugs (pattern: "^[a-zA-Z0-9_]+$", length: 1-100 characters) before requests reach the handler code. This validation occurs during the zen.BindBody call in handlers.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
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.
go/apps/api/openapi/spec/common/roleReference.yaml (3)
Learnt from: ogzhanolguncu
PR: #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.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
Learnt from: AkshayBandi027
PR: #2215
File: apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx:28-29
Timestamp: 2024-10-08T15:33:04.290Z
Learning: In authorization/roles/[roleId]/update-role.tsx, the tag role-${role.id} is revalidated after updating a role to ensure that the caching mechanism is properly handled for roles.
go/apps/api/openapi/spec/paths/v2/keys/updateKey/V2KeysUpdateKeyResponseBody.yaml (2)
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.
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.
go/apps/api/openapi/spec/paths/v2/apis/deleteApi/V2ApisDeleteApiRequestBody.yaml (1)
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.
go/apps/api/openapi/spec/error/validationError.yaml (2)
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:353-466
Timestamp: 2025-07-15T14:25:05.608Z
Learning: In the Unkey codebase, input validation for API endpoints is handled at the OpenAPI schema layer, which validates request fields like permission slugs (pattern: "^[a-zA-Z0-9_]+$", length: 1-100 characters) before requests reach the handler code. This validation occurs during the zen.BindBody call in handlers.
go/apps/api/openapi/spec/paths/v2/permissions/createRole/V2PermissionsCreateRoleResponseBody.yaml (2)
Learnt from: ogzhanolguncu
PR: #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.
Learnt from: AkshayBandi027
PR: #2215
File: apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx:28-29
Timestamp: 2024-10-08T15:33:04.290Z
Learning: In authorization/roles/[roleId]/update-role.tsx, the tag role-${role.id} is revalidated after updating a role to ensure that the caching mechanism is properly handled for roles.
go/apps/api/openapi/spec/paths/v2/keys/deleteKey/V2KeysDeleteKeyRequestBody.yaml (4)
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.
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.
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.
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.
go/apps/api/openapi/spec/common/KeyResponseData.yaml (1)
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.
go/apps/api/openapi/spec/paths/v2/identities/updateIdentity/V2IdentitiesUpdateIdentityRequestBody.yaml (2)
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.
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.
go/apps/api/openapi/spec/paths/v2/keys/setPermissions/V2KeysSetPermissionsRequestBody.yaml (3)
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:353-466
Timestamp: 2025-07-15T14:25:05.608Z
Learning: In the Unkey codebase, input validation for API endpoints is handled at the OpenAPI schema layer, which validates request fields like permission slugs (pattern: "^[a-zA-Z0-9_]+$", length: 1-100 characters) before requests reach the handler code. This validation occurs during the zen.BindBody call in handlers.
Learnt from: chronark
PR: #3617
File: go/apps/api/openapi/openapi.yaml:3309-3312
Timestamp: 2025-07-16T17:51:57.297Z
Learning: In the Unkey API OpenAPI schema, the permissions query regex for the verifyKey endpoint intentionally allows all whitespace characters (including tabs and newlines) via \s. Do not flag this as an error in future reviews.
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.
go/apps/api/openapi/spec/common/ratelimitOverride.yaml (2)
Learnt from: ogzhanolguncu
PR: #2707
File: apps/dashboard/lib/trpc/routers/ratelimit/createOverride.ts:63-63
Timestamp: 2024-12-05T13:27:55.555Z
Learning: In apps/dashboard/lib/trpc/routers/ratelimit/createOverride.ts, when determining the maximum number of rate limit overrides (max), the intentional use of const max = hasWorkspaceAccess("ratelimitOverrides", namespace.workspace) || 5; allows max to fall back to 5 when hasWorkspaceAccess returns 0 or false. This fallback behavior is expected and intended in the codebase.
Learnt from: chronark
PR: #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.
go/apps/api/openapi/spec/paths/v2/keys/getKey/V2KeysGetKeyRequestBody.yaml (1)
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.
go/apps/api/openapi/spec/paths/v2/keys/getKey/V2KeysGetKeyResponseBody.yaml (1)
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.
go/apps/api/openapi/spec/paths/v2/apis/listKeys/V2ApisListKeysResponseData.yaml (1)
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.
go/apps/api/openapi/spec/paths/v2/identities/createIdentity/V2IdentitiesCreateIdentityResponseData.yaml (2)
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.
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.
go/apps/api/openapi/gen.go (4)
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
Learnt from: ogzhanolguncu
PR: #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.
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.
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.
go/apps/api/openapi/spec/paths/v2/keys/deleteKey/V2KeysDeleteKeyResponseBody.yaml (1)
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.
go/apps/api/openapi/openapi-generated.yaml (13)
Learnt from: mcstepp
PR: #3662
File: apps/dashboard/lib/trpc/routers/deployment/getOpenApiDiff.ts:110-147
Timestamp: 2025-07-25T19:11:00.208Z
Learning: In apps/dashboard/lib/trpc/routers/deployment/getOpenApiDiff.ts, the user mcstepp prefers to keep mock data fallbacks in POC/demonstration code for simplicity, even if it wouldn't be production-ready. This aligns with the PR being work-in-progress for demonstration purposes.
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.
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.
Learnt from: ogzhanolguncu
PR: #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.
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.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
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.
Learnt from: AkshayBandi027
PR: #2215
File: apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx:28-29
Timestamp: 2024-10-08T15:33:04.290Z
Learning: In authorization/roles/[roleId]/update-role.tsx, the tag role-${role.id} is revalidated after updating a role to ensure that the caching mechanism is properly handled for roles.
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.
Learnt from: chronark
PR: #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: #3156
File: apps/dashboard/app/(app)/apis/[apiId]/_components/create-key/components/ratelimit-setup.tsx:36-47
Timestamp: 2025-04-22T11:48:39.670Z
Learning: The Unkey dashboard's form validation for numeric values like rate limits is handled through the Zod schema validation (with .positive() validators and additional checks in superRefine), rather than HTML input attributes like min.
Learnt from: ogzhanolguncu
PR: #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.
Learnt from: ogzhanolguncu
PR: #2825
File: apps/dashboard/app/(app)/logs/components/table/query-logs.schema.ts:49-58
Timestamp: 2025-01-30T20:43:19.720Z
Learning: Status code validation is handled at the ClickHouse query level rather than in the schema, as invalid status codes will cause query failures that are caught by TRPC error handling.
🪛 Gitleaks (8.27.2)
go/apps/api/openapi/spec/paths/v2/keys/verifyKey/V2KeysVerifyKeyRequestBody.yaml
84-84: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
go/apps/api/openapi/spec/paths/chproxy/verifications/ChproxyVerificationsRequestBody.yaml
7-7: Found a Stripe Access Token, posing a risk to payment processing services and sensitive financial data.
(stripe-access-token)
12-12: Found a Stripe Access Token, posing a risk to payment processing services and sensitive financial data.
(stripe-access-token)
go/apps/api/openapi/spec/paths/v2/keys/createKey/V2KeysCreateKeyResponseData.yaml
27-27: Found a Stripe Access Token, posing a risk to payment processing services and sensitive financial data.
(stripe-access-token)
🪛 YAMLlint (1.37.1)
go/apps/api/openapi/spec/paths/chproxy/metrics/ChproxyMetricsRequestBody.yaml
[error] 24-24: no new line character at the end of file
(new-line-at-end-of-file)
go/apps/api/openapi/spec/paths/chproxy/metrics/ChproxyMetricsResponseBody.yaml
[error] 10-10: no new line character at the end of file
(new-line-at-end-of-file)
go/apps/api/openapi/spec/paths/chproxy/verifications/ChproxyVerificationsRequestBody.yaml
[error] 16-16: no new line character at the end of file
(new-line-at-end-of-file)
go/apps/api/openapi/spec/paths/chproxy/ratelimits/ChproxyRatelimitsResponseBody.yaml
[error] 10-10: no new line character at the end of file
(new-line-at-end-of-file)
go/apps/api/openapi/spec/paths/chproxy/verifications/ChproxyVerificationsResponseBody.yaml
[error] 10-10: no new line character at the end of file
(new-line-at-end-of-file)
go/apps/api/openapi/spec/paths/chproxy/ratelimits/ChproxyRatelimitsRequestBody.yaml
[error] 16-16: no new line character at the end of file
(new-line-at-end-of-file)
go/apps/api/openapi/spec/common/addPermissionReference.yaml
[error] 40-40: no new line character at the end of file
(new-line-at-end-of-file)
go/apps/api/openapi/spec/common/permissionReference.yaml
[error] 29-29: no new line character at the end of file
(new-line-at-end-of-file)
go/apps/api/openapi/spec/common/roleReference.yaml
[error] 29-29: no new line character at the end of file
(new-line-at-end-of-file)
go/apps/api/openapi/spec/error/validationError.yaml
[error] 38-38: no new line character at the end of file
(new-line-at-end-of-file)
go/apps/api/openapi/openapi-generated.yaml
[error] 648-648: wrong indentation: expected 26 but found 24
(indentation)
[error] 652-652: wrong indentation: expected 26 but found 24
(indentation)
[error] 658-658: wrong indentation: expected 26 but found 24
(indentation)
[error] 662-662: wrong indentation: expected 26 but found 24
(indentation)
[error] 2123-2123: wrong indentation: expected 26 but found 24
(indentation)
[error] 2133-2133: wrong indentation: expected 26 but found 24
(indentation)
[error] 2677-2677: wrong indentation: expected 22 but found 20
(indentation)
[error] 2680-2680: wrong indentation: expected 22 but found 20
(indentation)
[error] 2683-2683: wrong indentation: expected 22 but found 20
(indentation)
[error] 2685-2685: wrong indentation: expected 22 but found 20
(indentation)
[error] 2690-2690: wrong indentation: expected 22 but found 20
(indentation)
[error] 2707-2707: wrong indentation: expected 22 but found 20
(indentation)
[error] 2709-2709: wrong indentation: expected 22 but found 20
(indentation)
[error] 3119-3119: wrong indentation: expected 22 but found 20
(indentation)
[error] 3123-3123: wrong indentation: expected 22 but found 20
(indentation)
[error] 3129-3129: wrong indentation: expected 22 but found 20
(indentation)
[error] 3133-3133: wrong indentation: expected 22 but found 20
(indentation)
[error] 4020-4020: wrong indentation: expected 22 but found 20
(indentation)
[error] 4035-4035: wrong indentation: expected 22 but found 20
(indentation)
⏰ 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). (6)
- GitHub Check: Test Agent Local / test_agent_local
- GitHub Check: Test Go API Local / Test
- GitHub Check: Test API / API Test Local
- GitHub Check: Build / Build
- GitHub Check: Test Packages / Test
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (80)
go/apps/api/openapi/spec/common/meta.yaml (1)
19-20: Duplicate examples may confuse generatorsThere is already an
exampleon therequestIdproperty (line 11). Adding a second, top-levelexampleis perfectly legal in OAS 3.1, but some tooling may pick only one. Verify that your chosen generators/renderers don’t end up dropping or overriding either example unintentionally.go/apps/api/openapi/spec/common/pagination.yaml (1)
25-27: Example addition looks greatThe concrete cursor/hasMore pair rounds out the documentation nicely and matches the property-level examples.
go/apps/api/openapi/spec/paths/v2/identities/deleteIdentity/V2IdentitiesDeleteIdentityRequestBody.yaml (1)
14-15: Example addition LGTMRoot-level example is well-formed and demonstrates a realistic
externalId.go/apps/api/openapi/spec/paths/v2/identities/getIdentity/V2IdentitiesGetIdentityRequestBody.yaml (1)
12-13: Example addition LGTMConsistent with other identity endpoints and improves doc clarity.
go/apps/api/openapi/spec/paths/v2/keys/deleteKey/index.yaml (1)
26-28: Well-placed media-type exampleThe inline example correctly lives under
content → application/jsonand helps consumers understand required fields.go/apps/api/openapi/spec/paths/v2/permissions/createPermission/V2PermissionsCreatePermissionResponseData.yaml (1)
17-18: Root-level example looks good – consistent with property-level example.No schema or linting issues detected.
go/apps/api/openapi/spec/paths/v2/identities/deleteIdentity/V2IdentitiesDeleteIdentityResponseBody.yaml (1)
8-10: 👍 Example addition improves docs clarity.The example aligns with the referenced
Metaschema.go/apps/api/openapi/spec/paths/v2/keys/updateKey/V2KeysUpdateKeyResponseData.yaml (1)
5-5: LGTM – empty object example matches the schema (additionalProperties: false).Nothing else to address.
go/apps/api/openapi/spec/paths/v2/identities/listIdentities/V2IdentitiesListIdentitiesRequestBody.yaml (1)
17-19: Example looks good and matches schema constraints.go/apps/api/openapi/spec/common/ratelimitResponse.yaml (1)
42-47: Example correctly aggregates field-level samples – no issues.go/apps/api/openapi/spec/paths/v2/keys/verifyKey/KeysVerifyKeyCredits.yaml (1)
21-22: Looks good – top-level example adds clarityAdding an object-level
exampleis valid in OpenAPI 3.1 and helps consumers see a concrete payload without digging into property docs. No further changes needed.go/apps/api/openapi/spec/paths/v2/apis/createApi/V2ApisCreateApiResponseData.yaml (1)
24-25: 👍 Example is valid and matches schemaThe added example follows the documented pattern (
api_…) and stays within length constraints. Clear improvement for docs.go/apps/api/openapi/spec/paths/v2/keys/verifyKey/KeysVerifyKeyRatelimit.yaml (1)
27-31: Comprehensive example providedExample object covers every overridable field (
name,cost,limit,duration) and respects min/max constraints. Documentation benefit acknowledged.go/apps/api/openapi/spec/paths/v2/apis/listKeys/V2ApisListKeysRequestBody.yaml (1)
54-57: Example improves request-body usabilityThe sample illustrates combined pagination and filtering parameters and stays within schema limits (limit ≤ 100). No issues spotted.
go/apps/api/openapi/spec/common/keyCreditsRefill.yaml (1)
31-34: Valid refill configuration exampleValues align with enum and numeric bounds, providing a clear reference for clients configuring automatic credit refills.
go/apps/api/openapi/spec/paths/v2/keys/deleteKey/V2KeysDeleteKeyResponseBody.yaml (1)
10-42: Ensure emptydataobject is schema-compliant
The top-level and named examples both provide an emptydata: {}. Please double-check thatKeysDeleteKeyResponseData.yamldoes not declare any required fields; otherwise these examples will fail validation in tooling that enforces the schema.go/apps/api/openapi/spec/common/KeyCreditsData.yaml (1)
17-22: LGTM – helpful, self-contained example
The added example covers bothremainingand nestedrefill, improving docs clarity.go/apps/api/openapi/spec/paths/v2/keys/getKey/V2KeysGetKeyRequestBody.yaml (1)
40-42: LGTM – concise default request example
The example correctly demonstrates thekeyIdbranch of theoneOfwithout decryption.go/apps/api/openapi/spec/paths/v2/permissions/createRole/V2PermissionsCreateRoleResponseBody.yaml (1)
11-15: LGTM – response example matches schema contracts
meta.requestIdanddata.roleIdsatisfy required properties and use expected naming (roleId).go/apps/api/openapi/spec/paths/v2/keys/updateKey/V2KeysUpdateKeyRequestBody.yaml (1)
133-139: Example payload looks good and matches the schemaThe added top-level
exampleis concise yet realistic and respects all validation constraints (keyIdpattern,namelength, booleanenabled, free-formmeta). Nice addition.go/apps/api/openapi/spec/paths/v2/keys/setRoles/V2KeysSetRolesResponseData.yaml (1)
16-20: 👍 Solid illustrative exampleThe
examplearray aligns perfectly with the object schema and clearly shows the expected alphabetical ordering.go/apps/api/openapi/spec/paths/v2/apis/createApi/V2ApisCreateApiResponseBody.yaml (1)
11-15: Example correctly reflects required structure
meta.requestIdanddata.apiIdfulfil the referenced component schemas and offer a helpful minimal sample.go/apps/api/openapi/spec/paths/v2/keys/removeRoles/V2KeysRemoveRolesResponseBody.yaml (1)
10-15: Valid and useful exampleThe response
examplemirrors the schema exactly and demonstrates the common single-role removal case.go/apps/api/openapi/spec/paths/v2/apis/getApi/V2ApisGetApiRequestBody.yaml (1)
15-16: Top-level example addition improves clarity – no issues foundThe new root-level
examplecomplements existing named examples and follows OAS 3.1 rules. No action needed.go/apps/api/openapi/spec/common/ratelimitRequest.yaml (1)
56-60: Example payload looks correct and adheres to schemaValues respect min/max constraints and illustrate typical usage.
go/apps/api/openapi/spec/error/baseError.yaml (1)
41-45: Good addition of canonical error exampleThe example aligns with the RFC-7807 structure and your field descriptions.
go/apps/api/openapi/spec/paths/v2/keys/createKey/V2KeysCreateKeyResponseBody.yaml (1)
10-15:example+examplesin the same Schema object may break OpenAPI validationOpenAPI 3.1 still inherits the 3.0 rule that, inside a Schema object, you can use either
exampleorexamples, not both. Tooling such asopenapi-generator,oas-linter, orswagger-uiwill emit a warning or fail hard.
Verify that your generator tolerates this dual usage; otherwise drop one of them (usually keepexamplesand remove the top-levelexample).go/apps/api/openapi/spec/paths/v2/keys/removePermissions/V2KeysRemovePermissionsResponseBody.yaml (1)
10-15: Sameexamplevsexamplescollision as in create-key response – ensure your tooling accepts both keys in a Schema object.go/apps/api/openapi/spec/paths/v2/keys/addPermissions/V2KeysAddPermissionsResponseBody.yaml (1)
10-16:example+examplesduplication – confirm linter acceptance or keep only one.go/apps/api/openapi/spec/paths/v2/keys/updateKey/V2KeysUpdateKeyResponseBody.yaml (1)
10-13: Good default example, but mind theexample/examplesclashSame validation concern: Schema objects should not carry both keys simultaneously.
go/apps/api/openapi/spec/error/conflictErrorResponse.yaml (1)
17-24: Confirmstatusfield type matchesBaseErrorschemaGreat to see a concrete example added.
Small sanity-check: in several error schemasstatusis defined as a string (e.g.,"409"), while this example uses an integer (409). IfBaseError.yamlkeepsstatusastype: string, this will violate schema validation in generators likeopenapi-generator.- status: 409 + status: "409"Please verify the underlying
BaseErrorspec and align the example accordingly.go/apps/api/openapi/spec/paths/v2/permissions/createPermission/V2PermissionsCreatePermissionResponseBody.yaml (1)
11-15:example+examplesduplication can confuse toolingThis schema now contains both a top-level
example:and anexamples:map. Several OpenAPI/JSON-Schema validators (e.g., Spectral, Redocly) treat this as mutually exclusive and will surface a warning or error.If you need just one canonical example, consider dropping the
example:block or moving the named variants into the array form accepted by JSON-Schema (examples: [ … ]).go/apps/api/openapi/spec/paths/v2/keys/addRoles/V2KeysAddRolesResponseBody.yaml (1)
10-17: Verifydataexample shape vs. referenced schema
datapoints toV2KeysAddRolesResponseData.yaml, but the inline example shows an array of role objects. If the referenced schema wraps roles differently (e.g.,{ roles: [...] }) this will drift from the contract.Please cross-check the target schema and adjust either the example or the schema reference to stay consistent.
go/apps/api/openapi/spec/paths/v2/apis/deleteApi/V2ApisDeleteApiResponseBody.yaml (1)
8-10: LGTM – helpful default exampleThe added default example improves quick-start readability and poses no schema concerns. 👍
go/apps/api/openapi/spec/paths/v2/keys/setPermissions/V2KeysSetPermissionsResponseBody.yaml (1)
10-16: Example looks correct – verify it matchesV2KeysSetPermissionsResponseDataschemaThe top-level example is clear and helpful.
Please just double-check that./V2KeysSetPermissionsResponseData.yamlindeed defines an array of plain strings; otherwise the example will fail validation.go/apps/api/openapi/spec/error/unauthorizedErrorResponse.yaml (1)
17-24: 👍 Well-structured example addedThe example payload mirrors the schema fields (
meta,error) and uses realistic values. No further action needed.go/apps/api/openapi/spec/paths/v2/apis/createApi/V2ApisCreateApiRequestBody.yaml (1)
15-28: Duplicateexample+examplesis valid under OpenAPI 3.1OpenAPI 3.1 aligns with JSON Schema and allows both
exampleandexampleson Schema Objects. When both are present, theexamplesfield takes precedence, so this duplication is spec-compliant. No change is required. If you’d like to streamline the document, you may optionally remove the standaloneexample, but it is not mandatory.Likely an incorrect or invalid review comment.
go/apps/api/openapi/spec/paths/v2/keys/removeRoles/V2KeysRemoveRolesResponseData.yaml (1)
16-20: Example aligns with required fields
idandnameare provided for each role and the list is alphabetically sorted, matching the description. Looks good.go/apps/api/openapi/spec/paths/v2/keys/removePermissions/V2KeysRemovePermissionsResponseData.yaml (1)
16-22: Good illustrative exampleAll required properties (
id,name,slug) are present and values follow the documented patterns. No issues spotted.go/apps/api/openapi/spec/error/PreconditionFailedErrorResponse.yaml (1)
17-24: Example addition looks goodThe example matches the schema structure (
meta,error) and uses realistic field values. 👍go/apps/api/openapi/spec/paths/v2/identities/getIdentity/V2IdentitiesGetIdentityResponseData.yaml (1)
27-39: LGTM – stricter schema plus illustrative exampleAdding
additionalProperties: falsetightens validation, and the example accurately reflects the defined fields. No further action needed.go/apps/api/openapi/spec/paths/v2/keys/setRoles/V2KeysSetRolesResponseBody.yaml (1)
10-17: 👍 Helpful top-level exampleThe illustrative response looks correct and matches the referenced
roleReferenceschema (fieldsid,name). No issues spotted.go/apps/api/openapi/spec/error/notFoundErrorResponse.yaml (1)
16-23: LGTM – example enhances documentationgo/apps/api/openapi/spec/error/forbiddenErrorResponse.yaml (1)
17-24: Example payload looks good – just ensure it matches the underlyingMeta/BaseErrorschemasThe shape and keys in the example line-up with what
Meta.yaml(requestId) andBaseError.yaml(title,detail,status,type) define, so no issues spotted.
Nothing further to do here.go/apps/api/openapi/spec/paths/v2/liveness/V2LivenessResponseData.yaml (1)
12-18:additionalProperties: falsetightens the contract – verify the live handler never emits extra fieldsThis is a response schema, so the stricter rule won’t break clients, but it will make the spec invalid if the implementation ever appends debug metadata (e.g.
uptime,version) in the future.
Please double-check the Go handler that writes the liveness JSON only emits{ "message": "OK" }.go/apps/api/openapi/spec/error/badRequestErrorDetails.yaml (1)
20-31: Solid, descriptive example – no schema mismatches foundThe example follows the extended schema: top-level
title/detail/status/typefromBaseErrorplus anerrorsarray ofValidationErroritems. Looks consistent.go/apps/api/openapi/spec/paths/chproxy/ratelimits/index.yaml (1)
30-36: Reference filenames fixed, but the chosen HTTP status529is non-standard
- Capitalisation fixes (
BadRequestErrorResponse,InternalServerErrorResponse) resolve broken$refs – good.529is not an official HTTP status code. If this endpoint really returns it, that’s fine, but many client generators / middleware will treat it as unknown. Consider mapping overloads to503 Service Unavailableto stay within RFC-defined ranges.go/apps/api/openapi/spec/paths/chproxy/metrics/ChproxyMetricsRequestBody.yaml (1)
5-15: Verify trailing newline & intentional schema wideningPlease double-check the following in
go/apps/api/openapi/spec/paths/chproxy/metrics/ChproxyMetricsRequestBody.yaml:
- Ensure the file ends with a single newline (YAML-lint will flag a missing EOF newline).
- Confirm that
additionalProperties: trueis deliberate. If you want to restrict keys, switch to an explicitproperties:list or useadditionalProperties: false.Suggested diff to add a newline at EOF:
time: 1701425460000 + # ← add exactly one trailing newline herego/apps/api/openapi/spec/paths/v2/identities/listIdentities/V2IdentitiesListIdentitiesResponseData.yaml (1)
5-25: Example LGTM – please confirmratelimitsmatches Identity schemaThe added sample is clear and realistic.
Quick sanity-check thatratelimits(array of objects) exists incommon/Identity.yaml; if that schema omits it, the example will break generator tooling.go/apps/api/openapi/spec/paths/v2/identities/updateIdentity/V2IdentitiesUpdateIdentityResponseBody.yaml (1)
10-23: Solid illustrative exampleThe response example mirrors the list schema and should help consumers.
Only verify thatMeta.yamlalready declaresrequestId; if not, move it under a documented key.go/apps/api/openapi/spec/paths/v2/keys/setRoles/V2KeysSetRolesRequestBody.yaml (1)
30-37: Good switch to reusableroleReferenceReferencing a common schema reduces duplication and keeps validation logic in one place.
Confirm thatroleReference.yamlallows eitheridorname(not both required) so the mixed example passes validation.go/apps/api/openapi/spec/paths/v2/identities/updateIdentity/V2IdentitiesUpdateIdentityRequestBody.yaml (1)
45-55: LGTM – example is consistent and covers all optional sectionsThe added example exercises
metaandratelimits, demonstrating full-object replacement semantics. No schema mismatches spotted.go/apps/api/openapi/spec/error/badRequestErrorResponse.yaml (1)
17-32: Example looks correct and mirrors the error detail schemaFields match
BadRequestErrorDetails.yaml(title, detail, status, type, errors). Nice touch including multiple validation errors.go/apps/api/openapi/spec/paths/v2/keys/verifyKey/KeysVerifyKeyResponseData.yaml (1)
101-133: Comprehensive example – no schema issues foundThe sample covers every major branch (credits, ratelimits, identity). Timestamp and int32 ranges are respected; permissions/roles align with earlier specs. 👍
go/apps/api/openapi/spec/paths/v2/permissions/createPermission/V2PermissionsCreatePermissionRequestBody.yaml (1)
48-51: Example looks good – ensure name/slug stay in syncThe added example complies with the regexes and length constraints.
No action needed.go/apps/api/openapi/spec/paths/v2/keys/verifyKey/VerifyKeyRatelimitData.yaml (1)
64-72: LGTM – example values satisfy schema limits•
id,name, numeric ranges and booleans all fall within the declared constraints.
•remaining≤limit, which mirrors realistic state.No issues spotted.
go/apps/api/openapi/spec/paths/v2/identities/createIdentity/V2IdentitiesCreateIdentityRequestBody.yaml (1)
48-83:additionalProperties: falseis a breaking change – confirm server acceptanceDisallowing unknown fields is great for strictness, but existing clients that send superfluous keys will now receive 4xx errors.
Double-check:
- Server handlers don’t rely on loose decoding (
map[string]any) for this payload.- There is no production traffic with extra keys (analytics or logs can confirm).
go/apps/api/openapi/spec/paths/v2/identities/getIdentity/V2IdentitiesGetIdentityResponseBody.yaml (1)
10-24: Response example valid – mirrors schema constraintsAll shown properties (
externalId, nestedmeta, ratelimit fields) conform to their respective schemas.
Nice addition for docs.go/apps/api/openapi/spec/common/KeyResponseData.yaml (1)
95-124: Confirm field names in nestedcredits.refillmatch the referenced schemaThe inlined example uses
refillDay. Please ensure the referencedKeyCreditsRefillschema really exposes that exact camel-case field; historical variants (day,refill_day) existed in earlier revisions and mismatching names slip through because examples are not validated.go/apps/api/openapi/spec/paths/v2/keys/addPermissions/V2KeysAddPermissionsRequestBody.yaml (1)
31-38: Example slugs are valid per schemaThe
addPermissionReference.yamlschema defines theslugfield with pattern^[a-zA-Z0-9_.]+$, explicitly allowing dots.
The examplesdocuments.writeandusers.readconform to this regex, so no changes are required.Likely an incorrect or invalid review comment.
go/apps/api/openapi/spec/paths/v2/keys/addRoles/V2KeysAddRolesRequestBody.yaml (1)
30-37: LGTM – centralising role schema improves consistencyReplacing the inline role object with a
$reftoroleReference.yamlremoves duplication and keeps validation rules in one place. The example covers bothidandnamecases. Nice cleanup.go/apps/api/openapi/spec/paths/v2/keys/removePermissions/V2KeysRemovePermissionsRequestBody.yaml (2)
30-30: Verify$refpath correctnessPath looks right, but a quick sanity check that
permissionReference.yamllives exactly four levels up is advisable to avoid broken references when bundling.
32-37: Great addition of illustrative exampleThe example makes the request body crystal-clear.
go/apps/api/openapi/spec/paths/v2/identities/listIdentities/V2IdentitiesListIdentitiesResponseBody.yaml (1)
14-40: 👍 Comprehensive example improves consumer understandingExample matches the underlying schema (meta, data array of identities, pagination). Good use of realistic values.
go/apps/api/openapi/spec/common/identity.yaml (2)
22-32: LGTM – Full object example adds valuable contextExample aligns with required fields and data types.
10-13: Duplicatemetaexample could be trimmedYou now have an example for
metahere and the same structure repeated in the root-level example below. Keeping both is valid but redundant; removing the property-level snippet reduces noise without losing clarity.⛔ Skipped due to learnings
Learnt from: unrenamed PR: unkeyed/unkey#2652 File: apps/dashboard/components/dashboard/copy-button.tsx:38-38 Timestamp: 2024-11-08T11:40:17.737Z Learning: The `copyToClipboardWithMeta` function currently has an unused `_meta` parameter. Consider removing it or utilizing it appropriately, especially when introducing the `useCopyToClipboard` hook.go/apps/api/openapi/spec/paths/v2/keys/removeRoles/V2KeysRemoveRolesRequestBody.yaml (1)
30-37: Solid refactor to reusableroleReferenceplus clear exampleReusable schema reduces duplication and the example demonstrates both
idandnamereferences.go/apps/api/openapi/spec/paths/v2/keys/deleteKey/V2KeysDeleteKeyRequestBody.yaml (1)
33-41:examplesstructure is not JSON-Schema compliantUnder OAS 3.1 a Schema Object’s
exampleskeyword must be an array of literal examples, not a map of named Example Objects. A correct shape would be:examples: - { keyId: key_1234abcd } - { keyId: key_5678efgh, permanent: true }If you need named examples, move them one level up to the
mediaTypelayer or prefix withx-.⛔ Skipped due to learnings
Learnt from: Flo4604 PR: unkeyed/unkey#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.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/openapi/spec/paths/v2/identities/createIdentity/V2IdentitiesCreateIdentityResponseData.yaml (1)
13-17: Great to seeadditionalProperties: falseExplicitly disallowing extras keeps the contract tight and prevents silent garbage from creeping into responses.
go/apps/api/openapi/spec/paths/v2/apis/listKeys/V2ApisListKeysResponseData.yaml (1)
6-49: Validate example againstKeyResponseDataThis large example is helpful, but if any field (
start, nestedcredits.refill.interval, etc.) is missing fromKeyResponseData.yaml, schema validation will fail during code-gen.Please run
speakeasy validate(or similar) to confirm the example conforms, especially for optional nested objects.go/apps/api/openapi/spec/common/roleReference.yaml (1)
29-29: Add trailing newlineThe linter complains: “no new line character at the end of file”.
[ suggest_nitpick ]- name: admin + name: admin +go/apps/api/openapi/openapi-split.yaml (1)
100-114: Nice taxonomy additionThe new
tagssection meaningfully groups endpoints and improves generated docs sidebar organisation.go/apps/api/openapi/gen.go (8)
147-150: LGTM! Clean field reorganization in Identity struct.The removal of the unused
Descriptionfield and reorganization of theMetaandRatelimitsfields improves the struct definition clarity. This aligns with the schema cleanup mentioned in the AI summary.
713-718: Good refactoring from generic map to structured type.The change from
map[string]interface{}to a proper struct with explicitIdentityId stringfield provides better type safety and API clarity. This matches the enhanced OpenAPI schema for identity creation response data mentioned in the summary.
826-826: Excellent refactoring to named reference type.Replacing the inline anonymous struct with
AddPermissionReferenceimproves code reusability and maintainability. This change is part of the coordinated refactoring mentioned in the AI summary to centralize permission reference definitions.
885-885: Consistent use of named role reference type.The change to
RoleReferencemaintains consistency with the permission reference refactoring and provides better type reusability across the API.
1103-1103: Proper use of PermissionReference for remove operations.Using
PermissionReferenceinstead ofAddPermissionReferencefor the remove permissions endpoint is semantically correct, as removal operations don't support auto-creation functionality.
1174-1174: Consistent role reference usage in remove operations.The use of
RoleReferencehere maintains consistency with other role-related endpoints and the overall refactoring approach.
1307-1307: Final consistency with role reference types.This completes the refactoring pattern by using
RoleReferencein the set roles endpoint, ensuring all role-related operations use the same reference type.
2057-2113: Well-designed named reference types with comprehensive documentation.The new
AddPermissionReference,PermissionReference, andRoleReferencestruct definitions are properly documented and provide clear field descriptions. Key observations:
- AddPermissionReference correctly includes the
Createfield for auto-creation functionality- PermissionReference uses
Slugfield (notName) which aligns with the learned validation patterns- RoleReference uses
Namefield which is consistent with role naming conventions- All types properly handle the precedence of ID over name/slug when both are provided
The documentation clearly explains the use cases and security considerations for each type.
| "$ref": "#/components/schemas/Pagination" | ||
| additionalProperties: false | ||
| example: | ||
| meta: | ||
| requestId: req_1234567890abcdef | ||
| data: | ||
| - externalId: user_1234567890abcdef | ||
| meta: | ||
| plan: premium | ||
| region: us-east-1 | ||
| userId: "12345" | ||
| ratelimits: | ||
| - name: requests | ||
| limit: 100 | ||
| remaining: 95 | ||
| reset: 1701425400000 | ||
| - externalId: user_2345678901bcdefg | ||
| meta: | ||
| plan: basic | ||
| region: us-west-2 | ||
| userId: "67890" | ||
| ratelimits: | ||
| - name: requests | ||
| limit: 50 | ||
| remaining: 48 | ||
| reset: 1701425400000 | ||
| pagination: |
There was a problem hiding this comment.
Fix YAML indentation – examples under V2IdentitiesListIdentitiesResponseBody are invalid
yamllint flags four array‐item blocks (plan, remaining, etc.) as 2 spaces short.
Broken indentation renders this whole example invalid YAML, and several generators (e.g. openapi-generator, redocly) will refuse to parse the file.
Diff-style outline (apply uniformly to every mis-indented line in this block):
- - name: requests # currently indented 12 spaces
+ - name: requests # 14 spaces = align with parent array itemAdjust all children of the two identity objects (plan, ratelimits, …) likewise.
After fixing, rerun yamllint – the block should be clean.
Committable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 YAMLlint (1.37.1)
[error] 648-648: wrong indentation: expected 26 but found 24
(indentation)
[error] 652-652: wrong indentation: expected 26 but found 24
(indentation)
[error] 658-658: wrong indentation: expected 26 but found 24
(indentation)
[error] 662-662: wrong indentation: expected 26 but found 24
(indentation)
🤖 Prompt for AI Agents
In go/apps/api/openapi/openapi-generated.yaml between lines 640 and 666, the
YAML example under V2IdentitiesListIdentitiesResponseBody has incorrect
indentation causing yamllint errors and parsing failures. Fix the indentation by
increasing the indent of all child properties under each identity object (such
as plan, region, userId, ratelimits, and their nested fields) by 2 spaces to
align properly within the array items. After adjusting, rerun yamllint to
confirm the example block is valid YAML.
| "$ref": "#/components/schemas/KeyResponseData" | ||
| description: Array of API keys with complete configuration and metadata. | ||
| example: | ||
| - keyId: key_1234567890abcdef | ||
| start: sk_test_abc123 | ||
| enabled: true | ||
| name: Production API Key | ||
| createdAt: 1701425400000 | ||
| updatedAt: 1701425400000 | ||
| expires: 1735689600000 | ||
| externalId: user_12345 | ||
| meta: | ||
| plan: premium | ||
| region: us-east-1 | ||
| permissions: | ||
| - documents.read | ||
| - documents.write | ||
| roles: | ||
| - editor | ||
| credits: | ||
| remaining: 1000 | ||
| refill: | ||
| interval: daily | ||
| amount: 1000 | ||
| identity: | ||
| externalId: user_1234567890abcdef | ||
| meta: | ||
| plan: premium | ||
| region: us-east-1 | ||
| userId: "12345" | ||
| ratelimits: | ||
| - name: requests | ||
| limit: 100 | ||
| remaining: 95 | ||
| reset: 1701425400000 | ||
| - keyId: key_2345678901bcdefg | ||
| start: sk_test_def456 | ||
| enabled: false | ||
| name: Development Key | ||
| createdAt: 1701425400000 | ||
| updatedAt: 1701425400000 | ||
| meta: | ||
| environment: development | ||
| permissions: | ||
| - documents.read |
There was a problem hiding this comment.
Multiple yamllint errors – examples for V2ApisListKeysResponseData
plan, permissions, roles, credits, identity, etc. are all out of alignment (errors 2677-2709).
YAML remains parsable only by accident; strict parsers fail.
Same fix pattern as previous comments – shift inner properties two spaces right.
🧰 Tools
🪛 YAMLlint (1.37.1)
[error] 2677-2677: wrong indentation: expected 22 but found 20
(indentation)
[error] 2680-2680: wrong indentation: expected 22 but found 20
(indentation)
[error] 2683-2683: wrong indentation: expected 22 but found 20
(indentation)
[error] 2685-2685: wrong indentation: expected 22 but found 20
(indentation)
[error] 2690-2690: wrong indentation: expected 22 but found 20
(indentation)
[error] 2707-2707: wrong indentation: expected 22 but found 20
(indentation)
[error] 2709-2709: wrong indentation: expected 22 but found 20
(indentation)
🤖 Prompt for AI Agents
In go/apps/api/openapi/openapi-generated.yaml between lines 2665 and 2709, the
nested properties under keys like plan, permissions, roles, credits, and
identity are misaligned, causing yamllint errors and potential parsing failures.
Fix this by shifting all these inner properties two spaces to the right to
ensure proper YAML indentation and alignment according to the schema structure.
| reset: 1701425400000 | ||
| V2IdentitiesListIdentitiesResponseData: | ||
| type: array | ||
| items: | ||
| "$ref": "#/components/schemas/Identity" | ||
| description: List of identities matching the specified criteria. | ||
| example: | ||
| - externalId: user_1234567890abcdef | ||
| meta: | ||
| plan: premium | ||
| region: us-east-1 | ||
| userId: "12345" | ||
| ratelimits: | ||
| - name: requests | ||
| limit: 100 | ||
| remaining: 95 | ||
| reset: 1701425400000 | ||
| - externalId: user_2345678901bcdefg | ||
| meta: | ||
| plan: basic | ||
| region: us-west-2 | ||
| userId: "67890" | ||
| ratelimits: | ||
| - name: requests | ||
| limit: 50 | ||
| remaining: 48 | ||
| reset: 1701425400000 | ||
| addPermissionReference: | ||
| type: object | ||
| properties: | ||
| id: | ||
| type: string | ||
| minLength: 3 | ||
| maxLength: 255 | ||
| pattern: "^[a-zA-Z0-9_]+$" | ||
| description: | | ||
| References an existing permission by its database identifier. | ||
| Use when you know the exact permission ID and want to ensure you're referencing a specific permission. | ||
| Takes precedence over slug when both are provided in the same object. |
There was a problem hiding this comment.
Wrong indentation in V2IdentitiesListIdentitiesResponseData blocks
Errors 3119, 3123, 3129, 3133 -> identical root cause (array items too shallow).
Repair before releasing – these are the public docs users will copy-paste.
🧰 Tools
🪛 YAMLlint (1.37.1)
[error] 3119-3119: wrong indentation: expected 22 but found 20
(indentation)
[error] 3123-3123: wrong indentation: expected 22 but found 20
(indentation)
[error] 3129-3129: wrong indentation: expected 22 but found 20
(indentation)
[error] 3133-3133: wrong indentation: expected 22 but found 20
(indentation)
🤖 Prompt for AI Agents
In go/apps/api/openapi/openapi-generated.yaml around lines 3110 to 3148, the
indentation for the V2IdentitiesListIdentitiesResponseData schema is incorrect,
specifically the array items are not properly nested under the type array. Fix
the indentation by ensuring the "items" field is correctly indented as a child
of the "type: array" line, and all nested properties under "items" are properly
aligned to reflect the correct YAML structure for the schema definition.
| example: | ||
| - id: perm_1234567890abcdef | ||
| name: documents.read | ||
| - id: perm_2345678901bcdefg | ||
| name: documents.write | ||
| - id: perm_3456789012cdefgh | ||
| name: users.read |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Align example id patterns with existing schema-level example
Property-level id example uses a 24-char base-62 value (perm_1n9McEIBSqy44Qy7hzWyM5), whereas the array-level examples switch to 16-char hex strings. Mixing formats can confuse consumers and implies multiple valid patterns when the schema likely accepts only one. Consider normalising the examples so all permission IDs share the same canonical format.
- - id: perm_1234567890abcdef
+ - id: perm_1n9McEIBSqy44Qy7hzWyM5🤖 Prompt for AI Agents
In
go/apps/api/openapi/spec/paths/v2/keys/setPermissions/V2KeysSetPermissionsResponseData.yaml
around lines 28 to 34, the example `id` values use inconsistent formats: the
property-level example uses a 24-character base-62 string, while the array-level
examples use 16-character hex strings. To fix this, update the array-level
example `id` values to match the 24-character base-62 format used in the
property-level example, ensuring all permission IDs follow the same canonical
pattern for consistency.
| example: | ||
| keyId: key_1234567890abcdef | ||
| operation: set | ||
| value: 1000 |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Redundant example vs. examples may confuse tooling
The schema now carries both a single example object and a named examples map. Several OpenAPI generators (e.g. Go-oapi-codegen <1.15) will only honour one of them, sometimes shadowing the other silently.
If you want one canonical example, keep example and drop the top-level examples map; if you need multiple named samples, drop the new example field.
🤖 Prompt for AI Agents
In
go/apps/api/openapi/spec/paths/v2/keys/updateCredits/V2KeysUpdateCreditsRequestBody.yaml
around lines 37 to 40, the schema defines both a single example and a named
examples map, which can confuse OpenAPI tooling. To fix this, decide whether you
want a single canonical example or multiple named examples. If a single example
suffices, keep the example field and remove the examples map; if multiple
examples are needed, remove the example field and keep the examples map.
| example: | ||
| meta: | ||
| requestId: req_1234567890abcdef | ||
| data: | ||
| remaining: 1000 | ||
| refill: | ||
| interval: monthly | ||
| amount: 1000 | ||
| refillDay: 1 |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Avoid duplicating unnamed (example) and named (examples) examples on the same schema
OpenAPI tooling often prefers a single example or a MediaType.examples map. Having both a top-level example plus the existing examples object on the same schema can confuse generators and cause one of them to be ignored. Pick one style (named examples → move this into the existing examples map, or keep the single example and drop the map).
🤖 Prompt for AI Agents
In
go/apps/api/openapi/spec/paths/v2/keys/updateCredits/V2KeysUpdateCreditsResponseBody.yaml
between lines 11 and 19, there is a duplication of example data using both a
top-level `example` and a named `examples` map on the same schema. To fix this,
remove the top-level `example` and instead move its content into the existing
`examples` map, ensuring only one style of example is used to avoid confusion in
OpenAPI tooling.
| example: | ||
| apiId: api_1234567890abcdef | ||
| key: sk_1234567890abcdef | ||
| permissions: documents.read | ||
| tags: | ||
| - endpoint=/users/profile | ||
| - method=GET |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Tweak sample values to avoid false “secret” detections & quoting edge-cases
-
CI secret-scanners (e.g., Gitleaks) flagged
sk_1234567890abcdefas a potential real key. Prefixing with something likesk_test_...(or reducing entropy) keeps examples obviously fake and silences noisy scanners. -
YAML treats
documents.readas a plain string, but quoting ("documents.read") removes any doubt for copy-paste consumers.
- key: sk_1234567890abcdef
+ key: sk_test_1234567890abcdef
- permissions: documents.read
+ permissions: "documents.read"Pure documentation nit, but saves future pipeline noise.
🧰 Tools
🪛 Gitleaks (8.27.2)
84-84: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🤖 Prompt for AI Agents
In
go/apps/api/openapi/spec/paths/v2/keys/verifyKey/V2KeysVerifyKeyRequestBody.yaml
around lines 82 to 88, update the example values to avoid triggering secret
scanners and YAML parsing issues. Change the key prefix from "sk_" to "sk_test_"
to clearly indicate a fake key and prevent false secret detections. Also, add
quotes around the permissions value "documents.read" to ensure it is treated as
a string and avoid any YAML parsing edge cases during copy-paste.
| example: | ||
| meta: | ||
| requestId: req_1234567890abcdef | ||
| data: | ||
| status: ok | ||
| message: Service is healthy |
There was a problem hiding this comment.
Example violates referenced schema – status is undefined.
data is a $ref to V2LivenessResponseData.yaml, which (per recent schema change) only allows:
type: object
required:
- message
properties:
message: { type: string }
additionalProperties: falseIncluding a status field therefore makes the example invalid and will break example-driven validation tools.
example:
meta:
requestId: req_1234567890abcdef
data:
- status: ok
- message: Service is healthy
+ message: Service is healthy🤖 Prompt for AI Agents
In go/apps/api/openapi/spec/paths/v2/liveness/V2LivenessResponseBody.yaml around
lines 10 to 15, the example includes a `status` field under `data` which is not
defined in the referenced schema V2LivenessResponseData.yaml. Remove the
`status` field from the example so that `data` only contains the `message` field
as required by the schema, ensuring the example is valid and compliant with the
schema constraints.
Graphite Automations"Notify author when CI fails" took an action on this PR • (07/28/25)1 teammate was notified to this PR based on Andreas Thomas's automation. |
| Slugs must be unique within your workspace and support wildcard matching during verification. | ||
| Combined with `create=true`, allows automatic permission creation for streamlined workflows. | ||
| example: documents.write | ||
| create: |
There was a problem hiding this comment.
This would be from the old permissions stuff, we dont have the creat param anymore
There was a problem hiding this comment.
yeah I think I botched the conflicts a little, it got very confusing
| properties: {} | ||
| additionalProperties: false | ||
| description: Empty response object by design. A successful response indicates this operation was successfully executed. | ||
| description: Empty response object by design. A successful response indicates the key was deleted successfully. |
There was a problem hiding this comment.
This is not only used for key deletion and should reain its > this operation was successfully executed.
| plan: premium | ||
| region: us-east-1 | ||
| userId: "12345" | ||
| ratelimits: |
There was a problem hiding this comment.
i think we are missing autoApply here
| name: users.read | ||
| slug: users-read | ||
| description: Allows reading user profile information and account details | ||
| createdAt: 1701425400000 |
There was a problem hiding this comment.
we are not using this either (botched from merge changes)
There was a problem hiding this comment.
Actionable comments posted: 25
🔭 Outside diff range comments (3)
go/apps/api/openapi/spec/paths/v2/permissions/getRole/V2PermissionsGetRoleRequestBody.yaml (1)
18-20: Example object does not follow the schema – wrong property nameThe schema defines a single required field
role, but the new example usesroleId.
Tools that validate or render examples will flag this as invalid.-example: - roleId: role_1234567890abcdef +example: + role: role_1234567890abcdefgo/apps/api/openapi/spec/paths/v2/keys/addPermissions/V2KeysAddPermissionsRequestBody.yaml (1)
32-39: Example payload does not conform to declaredstringitem type
permissionsis typed as an array of string slugs (lines 27-30). The example introduces objects (id,slug,create), making the example invalid and misleading.Quick fix (keep current schema):
permissions: - - id: perm_1234567890abcdef - - slug: documents.write - create: true - - slug: users.read + - perm_1234567890abcdef + - documents.write + - users.readIf object syntax is desired, refactor the schema to use
permissionReferenceviaoneOf.go/apps/api/openapi/spec/paths/v2/keys/verifyKey/V2KeysVerifyKeyResponseBody.yaml (1)
11-86: Invalidexamplesmapping inside Schema ObjectSame issue as in the rate-limit schema: OpenAPI/JSON-Schema does not allow a map-shaped
examplesunder a Schema Object. Tooling will flag this.Action: move the named examples to the Media Type object or convert to an array.
♻️ Duplicate comments (6)
go/apps/api/openapi/spec/paths/v2/keys/verifyKey/V2KeysVerifyKeyRequestBody.yaml (1)
72-75: Use obvious-fake key prefix & quote permission to silence secret-scannersSame concern flagged in an earlier review:
sk_123456…triggers Gitleaks. Switching tosk_test_…(and quoting the permission) avoids false positives and YAML edge cases.example: apiId: api_1234567890abcdef - key: sk_1234567890abcdef - permissions: documents.read + key: sk_test_1234567890abcdef + permissions: "documents.read"go/apps/api/openapi/openapi-generated.yaml (5)
645-667: Indentation still broken – YAML remains invalid
Same 2-space mis-alignment previously flagged underV2IdentitiesListIdentitiesResponseBody. Please fix or regenerate; tools likeopenapi-generatorwill choke.
2116-2138: Indentation error repeats in second role object
This block was already highlighted; it still violates YAML indentation (seeyamllintoutput).
2644-2688: Mis-indented nested fields underV2ApisListKeysResponseData
The array items’ children (meta,permissions,roles, etc.) are two spaces short.
3090-3116:V2IdentitiesListIdentitiesResponseDataindentation still off
Parsing fails at themetaandratelimitskeys – identical to the earlier review comment.
3789-3814: Indentation error – permissions list inside role
Keys underpermissions:need +2 spaces. This is the same outstanding issue.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (33)
go/apps/api/openapi/gen.go(8 hunks)go/apps/api/openapi/openapi-generated.yaml(115 hunks)go/apps/api/openapi/openapi-split.yaml(1 hunks)go/apps/api/openapi/spec/common/EmptyResponse.yaml(1 hunks)go/apps/api/openapi/spec/common/KeyResponseData.yaml(1 hunks)go/apps/api/openapi/spec/common/permission.yaml(1 hunks)go/apps/api/openapi/spec/common/role.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/apis/deleteApi/V2ApisDeleteApiResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/addPermissions/V2KeysAddPermissionsRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/addRoles/V2KeysAddRolesRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/deleteKey/V2KeysDeleteKeyResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/removePermissions/V2KeysRemovePermissionsRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/removePermissions/V2KeysRemovePermissionsResponseData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/removeRoles/V2KeysRemoveRolesRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/removeRoles/V2KeysRemoveRolesResponseData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/setPermissions/V2KeysSetPermissionsRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/setRoles/V2KeysSetRolesRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/setRoles/V2KeysSetRolesResponseData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/updateKey/V2KeysUpdateKeyRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/updateKey/V2KeysUpdateKeyResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/verifyKey/V2KeysVerifyKeyRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/verifyKey/V2KeysVerifyKeyResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/keys/verifyKey/V2KeysVerifyKeyResponseData.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/permissions/deletePermission/V2PermissionsDeletePermissionRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/permissions/deletePermission/V2PermissionsDeletePermissionResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/permissions/deleteRole/V2PermissionsDeleteRoleRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/permissions/deleteRole/V2PermissionsDeleteRoleResponseBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/permissions/getPermission/V2PermissionsGetPermissionRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/permissions/getRole/V2PermissionsGetRoleRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/ratelimit/deleteOverride/V2RatelimitDeleteOverrideRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/ratelimit/limit/V2RatelimitLimitRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/ratelimit/listOverrides/V2RatelimitListOverridesRequestBody.yaml(1 hunks)go/apps/api/openapi/spec/paths/v2/ratelimit/setOverride/V2RatelimitSetOverrideRequestBody.yaml(1 hunks)
🧰 Additional context used
🧠 Learnings (27)
📓 Common learnings
Learnt from: Flo4604
PR: unkeyed/unkey#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.
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#3661
File: go/apps/api/routes/v2_identities_update_identity/handler.go:115-119
Timestamp: 2025-07-28T11:47:43.144Z
Learning: The v2 update identity endpoint (go/apps/api/routes/v2_identities_update_identity/handler.go) intentionally uses `ExternalId` field instead of the unified `Identity` field used in other v2 identity endpoints. This is because the update endpoint needs to both find by externalId and potentially update the externalId value, making the specific field name more appropriate than the generic `Identity` field.
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/openapi/spec/paths/v2/permissions/deletePermission/V2PermissionsDeletePermissionRequestBody.yaml (6)
Learnt from: CR
PR: unkeyed/unkey#0
File: go/deploy/CLAUDE.md:0-0
Timestamp: 2025-07-21T18:05:58.236Z
Learning: Applies to go/deploy/**/*.{go,js,ts,tsx,py,sh,md,txt,json,yaml,yml,ini,env,conf,html,css,scss,xml,c,h,cpp,java,rb,rs,php,pl,sql} : Use AIDEV-NOTE:, AIDEV-TODO:, AIDEV-BUSINESS_RULE:, or AIDEV-QUESTION: (all-caps prefix) as anchor comments aimed at AI and developers.
Learnt from: CR
PR: unkeyed/unkey#0
File: go/deploy/CLAUDE.md:0-0
Timestamp: 2025-07-21T18:05:58.236Z
Learning: Applies to go/deploy/**/*.{go,js,ts,tsx,py,sh,md,txt,json,yaml,yml,ini,env,conf,html,css,scss,xml,c,h,cpp,java,rb,rs,php,pl,sql} : Do not remove AIDEV-*s without explicit human instruction.
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.
Learnt from: chronark
PR: #3617
File: go/apps/api/openapi/openapi.yaml:3309-3312
Timestamp: 2025-07-16T17:51:57.297Z
Learning: In the Unkey API OpenAPI schema, the permissions query regex for the verifyKey endpoint intentionally allows all whitespace characters (including tabs and newlines) via \s. Do not flag this as an error in future reviews.
Learnt from: CR
PR: unkeyed/unkey#0
File: go/deploy/CLAUDE.md:0-0
Timestamp: 2025-07-21T18:05:58.236Z
Learning: Applies to go/deploy/**/*.{go,js,ts,tsx,py,sh,md,txt,json,yaml,yml,ini,env,conf,html,css,scss,xml,c,h,cpp,java,rb,rs,php,pl,sql} : Make sure to add relevant anchor comments whenever a file or piece of code is too complex, very important, confusing, or could have a bug.
Learnt from: mcstepp
PR: #3662
File: apps/dashboard/lib/trpc/routers/deployment/getOpenApiDiff.ts:110-147
Timestamp: 2025-07-25T19:11:00.208Z
Learning: In apps/dashboard/lib/trpc/routers/deployment/getOpenApiDiff.ts, the user mcstepp prefers to keep mock data fallbacks in POC/demonstration code for simplicity, even if it wouldn't be production-ready. This aligns with the PR being work-in-progress for demonstration purposes.
go/apps/api/openapi/spec/common/permission.yaml (6)
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:353-466
Timestamp: 2025-07-15T14:25:05.608Z
Learning: In the Unkey codebase, input validation for API endpoints is handled at the OpenAPI schema layer, which validates request fields like permission slugs (pattern: "^[a-zA-Z0-9_]+$", length: 1-100 characters) before requests reach the handler code. This validation occurs during the zen.BindBody call in handlers.
Learnt from: chronark
PR: #3617
File: go/apps/api/openapi/openapi.yaml:3309-3312
Timestamp: 2025-07-16T17:51:57.297Z
Learning: In the Unkey API OpenAPI schema, the permissions query regex for the verifyKey endpoint intentionally allows all whitespace characters (including tabs and newlines) via \s. Do not flag this as an error in future reviews.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
Learnt from: CR
PR: unkeyed/unkey#0
File: go/deploy/CLAUDE.md:0-0
Timestamp: 2025-07-21T18:05:58.236Z
Learning: Applies to go/deploy/**/*.{go,js,ts,tsx,py,sh,md,txt,json,yaml,yml,ini,env,conf,html,css,scss,xml,c,h,cpp,java,rb,rs,php,pl,sql} : Use AIDEV-NOTE:, AIDEV-TODO:, AIDEV-BUSINESS_RULE:, or AIDEV-QUESTION: (all-caps prefix) as anchor comments aimed at AI and developers.
Learnt from: CR
PR: unkeyed/unkey#0
File: go/deploy/CLAUDE.md:0-0
Timestamp: 2025-07-21T18:05:58.236Z
Learning: Applies to go/deploy/**/*.{go,js,ts,tsx,py,sh,md,txt,json,yaml,yml,ini,env,conf,html,css,scss,xml,c,h,cpp,java,rb,rs,php,pl,sql} : Do not remove AIDEV-*s without explicit human instruction.
Learnt from: CR
PR: unkeyed/unkey#0
File: go/deploy/CLAUDE.md:0-0
Timestamp: 2025-07-21T18:05:58.236Z
Learning: Applies to go/deploy/**/*.{go,js,ts,tsx,py,sh,md,txt,json,yaml,yml,ini,env,conf,html,css,scss,xml,c,h,cpp,java,rb,rs,php,pl,sql} : Make sure to add relevant anchor comments whenever a file or piece of code is too complex, very important, confusing, or could have a bug.
go/apps/api/openapi/spec/paths/v2/keys/setRoles/V2KeysSetRolesResponseData.yaml (1)
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
go/apps/api/openapi/spec/paths/v2/keys/addPermissions/V2KeysAddPermissionsRequestBody.yaml (4)
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:353-466
Timestamp: 2025-07-15T14:25:05.608Z
Learning: In the Unkey codebase, input validation for API endpoints is handled at the OpenAPI schema layer, which validates request fields like permission slugs (pattern: "^[a-zA-Z0-9_]+$", length: 1-100 characters) before requests reach the handler code. This validation occurs during the zen.BindBody call in handlers.
Learnt from: chronark
PR: #3617
File: go/apps/api/openapi/openapi.yaml:3309-3312
Timestamp: 2025-07-16T17:51:57.297Z
Learning: In the Unkey API OpenAPI schema, the permissions query regex for the verifyKey endpoint intentionally allows all whitespace characters (including tabs and newlines) via \s. Do not flag this as an error in future reviews.
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.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
go/apps/api/openapi/spec/paths/v2/keys/removePermissions/V2KeysRemovePermissionsResponseData.yaml (1)
Learnt from: chronark
PR: #3617
File: go/apps/api/openapi/openapi.yaml:3309-3312
Timestamp: 2025-07-16T17:51:57.297Z
Learning: In the Unkey API OpenAPI schema, the permissions query regex for the verifyKey endpoint intentionally allows all whitespace characters (including tabs and newlines) via \s. Do not flag this as an error in future reviews.
go/apps/api/openapi/spec/paths/v2/ratelimit/setOverride/V2RatelimitSetOverrideRequestBody.yaml (1)
Learnt from: chronark
PR: #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.
go/apps/api/openapi/spec/paths/v2/ratelimit/deleteOverride/V2RatelimitDeleteOverrideRequestBody.yaml (1)
Learnt from: chronark
PR: #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.
go/apps/api/openapi/spec/paths/v2/keys/deleteKey/V2KeysDeleteKeyResponseBody.yaml (1)
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.
go/apps/api/openapi/spec/paths/v2/permissions/deleteRole/V2PermissionsDeleteRoleRequestBody.yaml (2)
Learnt from: ogzhanolguncu
PR: #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.
Learnt from: AkshayBandi027
PR: #2215
File: apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx:28-29
Timestamp: 2024-10-08T15:33:04.290Z
Learning: In authorization/roles/[roleId]/update-role.tsx, the tag role-${role.id} is revalidated after updating a role to ensure that the caching mechanism is properly handled for roles.
go/apps/api/openapi/spec/paths/v2/permissions/getRole/V2PermissionsGetRoleRequestBody.yaml (2)
Learnt from: ogzhanolguncu
PR: #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.
Learnt from: AkshayBandi027
PR: #2215
File: apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx:28-29
Timestamp: 2024-10-08T15:33:04.290Z
Learning: In authorization/roles/[roleId]/update-role.tsx, the tag role-${role.id} is revalidated after updating a role to ensure that the caching mechanism is properly handled for roles.
go/apps/api/openapi/spec/paths/v2/keys/updateKey/V2KeysUpdateKeyRequestBody.yaml (4)
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.
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.
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.
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.
go/apps/api/openapi/spec/paths/v2/keys/updateKey/V2KeysUpdateKeyResponseBody.yaml (2)
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.
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.
go/apps/api/openapi/spec/paths/v2/keys/addRoles/V2KeysAddRolesRequestBody.yaml (2)
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
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.
go/apps/api/openapi/spec/paths/v2/keys/verifyKey/V2KeysVerifyKeyResponseData.yaml (5)
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.
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.
Learnt from: chronark
PR: #3617
File: go/apps/api/openapi/openapi.yaml:3309-3312
Timestamp: 2025-07-16T17:51:57.297Z
Learning: In the Unkey API OpenAPI schema, the permissions query regex for the verifyKey endpoint intentionally allows all whitespace characters (including tabs and newlines) via \s. Do not flag this as an error in future reviews.
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.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:353-466
Timestamp: 2025-07-15T14:25:05.608Z
Learning: In the Unkey codebase, input validation for API endpoints is handled at the OpenAPI schema layer, which validates request fields like permission slugs (pattern: "^[a-zA-Z0-9_]+$", length: 1-100 characters) before requests reach the handler code. This validation occurs during the zen.BindBody call in handlers.
go/apps/api/openapi/spec/paths/v2/keys/setPermissions/V2KeysSetPermissionsRequestBody.yaml (4)
Learnt from: chronark
PR: #3617
File: go/apps/api/openapi/openapi.yaml:3309-3312
Timestamp: 2025-07-16T17:51:57.297Z
Learning: In the Unkey API OpenAPI schema, the permissions query regex for the verifyKey endpoint intentionally allows all whitespace characters (including tabs and newlines) via \s. Do not flag this as an error in future reviews.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:353-466
Timestamp: 2025-07-15T14:25:05.608Z
Learning: In the Unkey codebase, input validation for API endpoints is handled at the OpenAPI schema layer, which validates request fields like permission slugs (pattern: "^[a-zA-Z0-9_]+$", length: 1-100 characters) before requests reach the handler code. This validation occurs during the zen.BindBody call in handlers.
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.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
go/apps/api/openapi/spec/paths/v2/keys/verifyKey/V2KeysVerifyKeyRequestBody.yaml (10)
Learnt from: chronark
PR: #3617
File: go/apps/api/openapi/openapi.yaml:3309-3312
Timestamp: 2025-07-16T17:51:57.297Z
Learning: In the Unkey API OpenAPI schema, the permissions query regex for the verifyKey endpoint intentionally allows all whitespace characters (including tabs and newlines) via \s. Do not flag this as an error in future reviews.
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.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:353-466
Timestamp: 2025-07-15T14:25:05.608Z
Learning: In the Unkey codebase, input validation for API endpoints is handled at the OpenAPI schema layer, which validates request fields like permission slugs (pattern: "^[a-zA-Z0-9_]+$", length: 1-100 characters) before requests reach the handler code. This validation occurs during the zen.BindBody call in handlers.
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.
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.
Learnt from: ogzhanolguncu
PR: #2910
File: apps/engineering/content/design/components/form/form-input.variants.tsx:38-38
Timestamp: 2025-02-24T13:35:00.816Z
Learning: In the Unkey codebase, example values in documentation and demo components intentionally use themed fake data (e.g., Middle Earth references) rather than generic placeholder text.
Learnt from: CR
PR: unkeyed/unkey#0
File: go/deploy/CLAUDE.md:0-0
Timestamp: 2025-07-21T18:05:58.236Z
Learning: Applies to go/deploy/**/*.{go,js,ts,tsx,py,sh,md,txt,json,yaml,yml,ini,env,conf,html,css,scss,xml,c,h,cpp,java,rb,rs,php,pl,sql} : Do not remove AIDEV-*s without explicit human instruction.
Learnt from: CR
PR: unkeyed/unkey#0
File: go/deploy/CLAUDE.md:0-0
Timestamp: 2025-07-21T18:05:58.236Z
Learning: Applies to go/deploy/**/*.{go,js,ts,tsx,py,sh,md,txt,json,yaml,yml,ini,env,conf,html,css,scss,xml,c,h,cpp,java,rb,rs,php,pl,sql} : Use AIDEV-NOTE:, AIDEV-TODO:, AIDEV-BUSINESS_RULE:, or AIDEV-QUESTION: (all-caps prefix) as anchor comments aimed at AI and developers.
Learnt from: CR
PR: unkeyed/unkey#0
File: go/deploy/CLAUDE.md:0-0
Timestamp: 2025-07-21T18:05:58.236Z
Learning: Applies to go/deploy/**/*.{go,js,ts,tsx,py,sh,md,txt,json,yaml,yml,ini,env,conf,html,css,scss,xml,c,h,cpp,java,rb,rs,php,pl,sql} : Make sure to add relevant anchor comments whenever a file or piece of code is too complex, very important, confusing, or could have a bug.
Learnt from: ogzhanolguncu
PR: #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/openapi/spec/paths/v2/keys/removePermissions/V2KeysRemovePermissionsRequestBody.yaml (5)
Learnt from: chronark
PR: #3617
File: go/apps/api/openapi/openapi.yaml:3309-3312
Timestamp: 2025-07-16T17:51:57.297Z
Learning: In the Unkey API OpenAPI schema, the permissions query regex for the verifyKey endpoint intentionally allows all whitespace characters (including tabs and newlines) via \s. Do not flag this as an error in future reviews.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:353-466
Timestamp: 2025-07-15T14:25:05.608Z
Learning: In the Unkey codebase, input validation for API endpoints is handled at the OpenAPI schema layer, which validates request fields like permission slugs (pattern: "^[a-zA-Z0-9_]+$", length: 1-100 characters) before requests reach the handler code. This validation occurs during the zen.BindBody call in handlers.
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.
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.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
go/apps/api/openapi/spec/paths/v2/keys/removeRoles/V2KeysRemoveRolesResponseData.yaml (1)
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
go/apps/api/openapi/spec/paths/v2/keys/removeRoles/V2KeysRemoveRolesRequestBody.yaml (2)
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.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
go/apps/api/openapi/spec/paths/v2/keys/setRoles/V2KeysSetRolesRequestBody.yaml (2)
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
Learnt from: ogzhanolguncu
PR: #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/openapi/spec/common/role.yaml (3)
Learnt from: AkshayBandi027
PR: #2215
File: apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx:28-29
Timestamp: 2024-10-08T15:33:04.290Z
Learning: In authorization/roles/[roleId]/update-role.tsx, the tag role-${role.id} is revalidated after updating a role to ensure that the caching mechanism is properly handled for roles.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
Learnt from: ogzhanolguncu
PR: #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/openapi/spec/common/KeyResponseData.yaml (2)
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.
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.
go/apps/api/openapi/spec/paths/v2/keys/verifyKey/V2KeysVerifyKeyResponseBody.yaml (3)
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.
Learnt from: chronark
PR: #3617
File: go/apps/api/openapi/openapi.yaml:3309-3312
Timestamp: 2025-07-16T17:51:57.297Z
Learning: In the Unkey API OpenAPI schema, the permissions query regex for the verifyKey endpoint intentionally allows all whitespace characters (including tabs and newlines) via \s. Do not flag this as an error in future reviews.
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.
go/apps/api/openapi/gen.go (2)
Learnt from: ogzhanolguncu
PR: #3661
File: go/apps/api/routes/v2_identities_update_identity/handler.go:115-119
Timestamp: 2025-07-28T11:47:43.144Z
Learning: The v2 update identity endpoint (go/apps/api/routes/v2_identities_update_identity/handler.go) intentionally uses ExternalId field instead of the unified Identity field used in other v2 identity endpoints. This is because the update endpoint needs to both find by externalId and potentially update the externalId value, making the specific field name more appropriate than the generic Identity field.
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.
go/apps/api/openapi/openapi-split.yaml (1)
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.
go/apps/api/openapi/openapi-generated.yaml (16)
Learnt from: mcstepp
PR: #3662
File: apps/dashboard/lib/trpc/routers/deployment/getOpenApiDiff.ts:110-147
Timestamp: 2025-07-25T19:11:00.208Z
Learning: In apps/dashboard/lib/trpc/routers/deployment/getOpenApiDiff.ts, the user mcstepp prefers to keep mock data fallbacks in POC/demonstration code for simplicity, even if it wouldn't be production-ready. This aligns with the PR being work-in-progress for demonstration purposes.
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.
Learnt from: CR
PR: unkeyed/unkey#0
File: go/deploy/CLAUDE.md:0-0
Timestamp: 2025-07-21T18:05:58.236Z
Learning: Applies to go/deploy/**/*.{go,js,ts,tsx,py,sh,md,txt,json,yaml,yml,ini,env,conf,html,css,scss,xml,c,h,cpp,java,rb,rs,php,pl,sql} : Use AIDEV-NOTE:, AIDEV-TODO:, AIDEV-BUSINESS_RULE:, or AIDEV-QUESTION: (all-caps prefix) as anchor comments aimed at AI and developers.
Learnt from: CR
PR: unkeyed/unkey#0
File: go/deploy/CLAUDE.md:0-0
Timestamp: 2025-07-21T18:05:58.236Z
Learning: Applies to go/deploy/**/*.{go,js,ts,tsx,py,sh,md,txt,json,yaml,yml,ini,env,conf,html,css,scss,xml,c,h,cpp,java,rb,rs,php,pl,sql} : Do not remove AIDEV-*s without explicit human instruction.
Learnt from: CR
PR: unkeyed/unkey#0
File: go/deploy/CLAUDE.md:0-0
Timestamp: 2025-07-21T18:05:58.236Z
Learning: Applies to go/deploy/**/*.{go,js,ts,tsx,py,sh,md,txt,json,yaml,yml,ini,env,conf,html,css,scss,xml,c,h,cpp,java,rb,rs,php,pl,sql} : Make sure to add relevant anchor comments whenever a file or piece of code is too complex, very important, confusing, or could have a bug.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:468-581
Timestamp: 2025-07-15T14:47:20.490Z
Learning: In the Unkey codebase, role and permission names are validated at the OpenAPI schema layer with strict regex patterns: role names must match "^[a-zA-Z][a-zA-Z0-9_-]*$" (start with letter, followed by letters/numbers/underscores/hyphens) and permission names must match "^[a-zA-Z0-9_]+$" (letters, numbers, underscores only). This validation occurs during zen.BindBody call before handlers run, preventing malicious or improperly formatted names from reaching auto-creation logic.
Learnt from: chronark
PR: #3617
File: go/apps/api/openapi/openapi.yaml:3309-3312
Timestamp: 2025-07-16T17:51:57.297Z
Learning: In the Unkey API OpenAPI schema, the permissions query regex for the verifyKey endpoint intentionally allows all whitespace characters (including tabs and newlines) via \s. Do not flag this as an error in future reviews.
Learnt from: ogzhanolguncu
PR: #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.
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.
Learnt from: ogzhanolguncu
PR: #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.
Learnt from: chronark
PR: #3560
File: go/apps/api/routes/v2_keys_create_key/handler.go:353-466
Timestamp: 2025-07-15T14:25:05.608Z
Learning: In the Unkey codebase, input validation for API endpoints is handled at the OpenAPI schema layer, which validates request fields like permission slugs (pattern: "^[a-zA-Z0-9_]+$", length: 1-100 characters) before requests reach the handler code. This validation occurs during the zen.BindBody call in handlers.
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.
Learnt from: ogzhanolguncu
PR: #3661
File: go/apps/api/routes/v2_identities_update_identity/handler.go:115-119
Timestamp: 2025-07-28T11:47:43.144Z
Learning: The v2 update identity endpoint (go/apps/api/routes/v2_identities_update_identity/handler.go) intentionally uses ExternalId field instead of the unified Identity field used in other v2 identity endpoints. This is because the update endpoint needs to both find by externalId and potentially update the externalId value, making the specific field name more appropriate than the generic Identity field.
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.
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.
Learnt from: ogzhanolguncu
PR: #3156
File: apps/dashboard/app/(app)/apis/[apiId]/_components/create-key/components/ratelimit-setup.tsx:36-47
Timestamp: 2025-04-22T11:48:39.670Z
Learning: The Unkey dashboard's form validation for numeric values like rate limits is handled through the Zod schema validation (with .positive() validators and additional checks in superRefine), rather than HTML input attributes like min.
🪛 Gitleaks (8.27.2)
go/apps/api/openapi/spec/paths/v2/keys/verifyKey/V2KeysVerifyKeyRequestBody.yaml
74-74: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🪛 YAMLlint (1.37.1)
go/apps/api/openapi/openapi-generated.yaml
[error] 650-650: wrong indentation: expected 26 but found 24
(indentation)
[error] 654-654: wrong indentation: expected 26 but found 24
(indentation)
[error] 660-660: wrong indentation: expected 26 but found 24
(indentation)
[error] 664-664: wrong indentation: expected 26 but found 24
(indentation)
[error] 2123-2123: wrong indentation: expected 26 but found 24
(indentation)
[error] 2133-2133: wrong indentation: expected 26 but found 24
(indentation)
[error] 2656-2656: wrong indentation: expected 22 but found 20
(indentation)
[error] 2659-2659: wrong indentation: expected 22 but found 20
(indentation)
[error] 2662-2662: wrong indentation: expected 22 but found 20
(indentation)
[error] 2664-2664: wrong indentation: expected 22 but found 20
(indentation)
[error] 2669-2669: wrong indentation: expected 22 but found 20
(indentation)
[error] 2686-2686: wrong indentation: expected 22 but found 20
(indentation)
[error] 2688-2688: wrong indentation: expected 22 but found 20
(indentation)
[error] 3098-3098: wrong indentation: expected 22 but found 20
(indentation)
[error] 3102-3102: wrong indentation: expected 22 but found 20
(indentation)
[error] 3108-3108: wrong indentation: expected 22 but found 20
(indentation)
[error] 3112-3112: wrong indentation: expected 22 but found 20
(indentation)
[error] 3794-3794: wrong indentation: expected 22 but found 20
(indentation)
[error] 3809-3809: wrong indentation: expected 22 but found 20
(indentation)
⏰ 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). (6)
- GitHub Check: Test API / API Test Local
- GitHub Check: Test Agent Local / test_agent_local
- GitHub Check: Test Go API Local / Test
- GitHub Check: Build / Build
- GitHub Check: Test Packages / Test
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (11)
go/apps/api/openapi/spec/paths/v2/keys/setRoles/V2KeysSetRolesResponseData.yaml (1)
16-20: Verify role ID sample conforms to therole.idpatternThe second sample ID (
role_2345678901bcdefg) contains a non-hex character (g).
Ifcommon/role.yamlenforces a hex-only suffix (common in this codebase:^[0-9a-f]{16}$), this example will fail validation in some tooling.- - id: role_2345678901bcdefg + - id: role_2345678901bcdefe # ensure hex-onlygo/apps/api/openapi/spec/paths/v2/keys/deleteKey/V2KeysDeleteKeyResponseBody.yaml (1)
11-14: Consider keeping eitherexampleorexamples, not bothOpenAPI 3.1 allows
exampleon a Schema object andexampleson Media-Type objects.
Having both on the same Schema may be harmless, but some generators (incl. Speakeasy in older versions) emit a warning or pick only one, leading to inconsistent docs.If both are required, ensure your lint configuration explicitly permits the pattern.
⛔ Skipped due to learnings
Learnt from: Flo4604 PR: unkeyed/unkey#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.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 destructive operations like deletion in the Unkey API, oneOf validation is preferred over anyOf to enforce explicit targeting and prevent ambiguity.go/apps/api/openapi/spec/paths/v2/keys/updateKey/V2KeysUpdateKeyRequestBody.yaml (1)
133-140: LGTM – helpful minimal example addedThe top-level example mirrors the schema correctly and is concise.
No further action needed.go/apps/api/openapi/spec/paths/v2/keys/updateKey/V2KeysUpdateKeyResponseBody.yaml (1)
11-14: LGTM – example aligns with empty-data response contractThe added single example is correct and consistent with
EmptyResponse.go/apps/api/openapi/spec/paths/v2/keys/removePermissions/V2KeysRemovePermissionsResponseData.yaml (1)
11-17: Example looks good and matches the referencedPermissionschema.
id,name, andslugalign with the usual Permission object structure; array typing is respected. No action required.go/apps/api/openapi/spec/paths/v2/keys/verifyKey/V2KeysVerifyKeyResponseData.yaml (1)
102-134: Example looks coherent – no structural issues spottedThe new example exercises every optional branch (
identity, nestedratelimits, etc.) and matches declared types. Good addition for documentation purposes.go/apps/api/openapi/spec/common/KeyResponseData.yaml (1)
95-125: Comprehensive example added – nicely covers nested structuresThe example now shows credits + refill and ratelimits, which will help SDK generators and docs consumers. No schema inconsistencies detected with the new sample.
go/apps/api/openapi/openapi-split.yaml (1)
100-115: Review globaltagsordering and casing in openapi-split.yamlThe existing tag list is valid, but for better scan-ability and to match naming conventions, you may want to:
- Alphabetically sort the entries under
tags:- Convert each
nameto Title-caseIf you apply these changes, ensure every operation under
paths:still references the updated tag names—otherwise Speakeasy lint will report missing tags.File:
go/apps/api/openapi/openapi-split.yaml
Locations to update:
• Lines 100–115 – reorder and rename tags
• Lines 116+ – update each operation’stags:entries to match the new namestags: - - name: apis - description: Operations for managing API configurations - - name: identities - description: Operations for managing identities and identity-based access - - name: keys - description: Operations for managing API keys - - name: liveness - description: Health check and service status endpoints - - name: permissions - description: Operations for managing permissions and roles - - name: ratelimit - description: Operations for managing rate limiting and overrides - - name: chproxy - description: Internal ClickHouse proxy endpoints + - name: Apis + description: Operations for managing API configurations + - name: Chproxy + description: Internal ClickHouse proxy endpoints + - name: Identities + description: Operations for managing identities and identity-based access + - name: Keys + description: Operations for managing API keys + - name: Liveness + description: Health check and service status endpoints + - name: Permissions + description: Operations for managing permissions and roles + - name: Ratelimit + description: Operations for managing rate limiting and overridesgo/apps/api/openapi/gen.go (3)
145-150: Pointer switch onIdentity.Metachanges the public contract
Metachanged frommap[string]anyto*map[string]any. This is a breaking change for callers that previously treated the field as a value type:
- Need to nil-check before use (
if id.Meta != nil { … }).- Existing code doing
id.Meta["foo"]will no longer compile.Confirm all usages in the codebase (handlers, tests, scripts) are updated accordingly.
632-637: Breaking type change:V2IdentitiesCreateIdentityResponseDatais now a structYou replaced the previous
map[string]interface{}alias with a strongly-typed struct containingIdentityId.
- Compilation will break wherever callers expected a map.
- JSON produced by existing clients might differ (previously
{}).Search & update all references to the old alias before merging.
943-945: Same “key deleted” copy-paste error for DeleteKey response
V2KeysDeleteKeyResponseBodyis correct, but please adjust wording to avoid cascading to unrelated endpoints:-… indicates the key was deleted successfully. +… indicates the key was deleted successfully.(The comment is fine here, but make sure the generic description isn’t reused elsewhere.)
⛔ Skipped due to learnings
Learnt from: MichaelUnkey PR: unkeyed/unkey#3173 File: apps/docs/security/delete-protection.mdx:32-36 Timestamp: 2025-04-22T17:33:28.162Z Learning: In the Unkey dashboard UI for delete protection, the button/link to initiate the process is labeled "Disable Delete Protection" while the confirmation button is labeled "Disable API Delete Protection". The documentation should maintain these different labels to match the actual UI.Learnt from: MichaelUnkey PR: unkeyed/unkey#3173 File: apps/docs/security/delete-protection.mdx:21-24 Timestamp: 2025-04-22T17:34:04.438Z Learning: In the Unkey dashboard UI for enabling delete protection, the button/link to initiate the process is labeled "Enable Delete Protection" while the confirmation button is labeled "Enable API Delete Protection". The documentation should maintain these different labels to match the actual UI.Learnt from: Flo4604 PR: unkeyed/unkey#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.
| // EmptyResponse Empty response object by design. A successful response indicates the key was deleted successfully. | ||
| type EmptyResponse = map[string]interface{} |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Docstring wrongly hard-codes “key deleted” – generalise the message
EmptyResponse is reused by many endpoints (API, permission, role, etc.). Locking the wording to “key was deleted” misleads readers and leaks into multiple downstream comments via $ref. Please update the OpenAPI description to something neutral, e.g.:
-// EmptyResponse Empty response object by design. A successful response indicates the key was deleted successfully.
+// EmptyResponse Empty response object by design. A successful response indicates the request succeeded.🤖 Prompt for AI Agents
In go/apps/api/openapi/gen.go around lines 123 to 124, the docstring for the
EmptyResponse type currently hardcodes the message "key was deleted," which is
misleading since this type is reused across multiple endpoints. Update the
comment to use a neutral description that does not reference key deletion, such
as stating it represents an empty response object by design, indicating a
successful operation without specifying the action.
| // Data Empty response object by design. A successful response indicates the key was deleted successfully. | ||
| Data EmptyResponse `json:"data"` | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Misleading comment – deleting an API, not a key
The response for V2ApisDeleteApi still says “…the key was deleted…”.
-// Data Empty response object by design. A successful response indicates the key was deleted successfully.
+// Data Empty response object by design. A successful response indicates the API was deleted successfully.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Data Empty response object by design. A successful response indicates the key was deleted successfully. | |
| Data EmptyResponse `json:"data"` | |
| // Data Empty response object by design. A successful response indicates the API was deleted successfully. | |
| Data EmptyResponse `json:"data"` |
🤖 Prompt for AI Agents
In go/apps/api/openapi/gen.go around lines 502 to 504, the comment for the Data
field incorrectly states that a key was deleted, but it should refer to an API
being deleted. Update the comment to accurately describe that a successful
response indicates the API was deleted successfully, not a key.
| // Data Empty response object by design. A successful response indicates the key was deleted successfully. | ||
| Data EmptyResponse `json:"data"` | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Incorrect description – UpdateKey is an update, not a deletion
-// Data Empty response object by design. A successful response indicates the key was deleted successfully.
+// Data Empty response object by design. A successful response indicates the key was updated successfully.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Data Empty response object by design. A successful response indicates the key was deleted successfully. | |
| Data EmptyResponse `json:"data"` | |
| // Data Empty response object by design. A successful response indicates the key was updated successfully. | |
| Data EmptyResponse `json:"data"` |
🤖 Prompt for AI Agents
In go/apps/api/openapi/gen.go around lines 1252 to 1254, the comment incorrectly
describes the UpdateKey response as a deletion success. Update the comment to
accurately reflect that this response indicates a successful update operation,
not a deletion.
| Data EmptyResponse `json:"data"` | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Incorrect wording – this endpoint deletes a permission
Adjust description accordingly to avoid confusion:
-… indicates the key was deleted successfully.
+… indicates the permission was deleted successfully.Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In go/apps/api/openapi/gen.go around lines 1510 to 1511, the description for the
endpoint incorrectly states it deletes a resource other than a permission.
Update the description text to clearly indicate that this endpoint deletes a
permission to avoid confusion.
| // Data Empty response object by design. A successful response indicates the key was deleted successfully. | ||
| Data EmptyResponse `json:"data"` | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Incorrect wording – this endpoint deletes a role
-… indicates the key was deleted successfully.
+… indicates the role was deleted successfully.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Data Empty response object by design. A successful response indicates the key was deleted successfully. | |
| Data EmptyResponse `json:"data"` | |
| // Data Empty response object by design. A successful response indicates the role was deleted successfully. | |
| Data EmptyResponse `json:"data"` |
🤖 Prompt for AI Agents
In go/apps/api/openapi/gen.go around lines 1536 to 1538, the comment incorrectly
states that the endpoint deletes a key, but it actually deletes a role. Update
the comment to accurately reflect that this endpoint deletes a role, ensuring
the description matches the functionality.
| example: | ||
| permissionId: perm_1234567890abcdef |
There was a problem hiding this comment.
Root-level example uses wrong property name (permissionId vs. permission).
The schema defines the single required field as permission, yet the top-level example object shows permissionId. This renders the example invalid against the very schema it illustrates and will trigger linting/validation errors.
-example:
- permissionId: perm_1234567890abcdef
+example:
+ permission: perm_1234567890abcdef📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| example: | |
| permissionId: perm_1234567890abcdef | |
| example: | |
| permission: perm_1234567890abcdef |
🤖 Prompt for AI Agents
In
go/apps/api/openapi/spec/paths/v2/permissions/getPermission/V2PermissionsGetPermissionRequestBody.yaml
at lines 14 to 15, the example uses the incorrect property name `permissionId`
instead of the required `permission` as defined in the schema. Update the
example to replace `permissionId` with `permission` to ensure it matches the
schema and passes validation.
| example: | ||
| namespaceId: namespace_1234567890abcdef | ||
| identifier: premium_user_* |
There was a problem hiding this comment.
Incorrect field name in example (namespaceId vs namespace)
The example should use exactly the same property names defined in properties to remain valid.
-example:
- namespaceId: namespace_1234567890abcdef
- identifier: premium_user_*
+example:
+ namespace: namespace_1234567890abcdef
+ identifier: premium_user_*📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| example: | |
| namespaceId: namespace_1234567890abcdef | |
| identifier: premium_user_* | |
| example: | |
| namespace: namespace_1234567890abcdef | |
| identifier: premium_user_* |
🤖 Prompt for AI Agents
In
go/apps/api/openapi/spec/paths/v2/ratelimit/deleteOverride/V2RatelimitDeleteOverrideRequestBody.yaml
around lines 36 to 38, the example uses the field name `namespaceId` which does
not match the property name `namespace` defined in the schema. Update the
example to replace `namespaceId` with `namespace` to ensure the example is valid
and consistent with the schema.
| example: | ||
| namespace: api.requests | ||
| identifier: user_1234567890abcdef | ||
| limit: 1000 | ||
| duration: 3600000 | ||
| cost: 1 | ||
| examples: | ||
| basic: | ||
| summary: Basic rate limit request | ||
| description: Simple rate limiting for user API requests | ||
| value: | ||
| namespace: api.requests | ||
| identifier: user_1234567890abcdef | ||
| limit: 1000 | ||
| duration: 3600000 | ||
| withCost: | ||
| summary: Weighted rate limit request | ||
| description: Rate limiting with custom cost for expensive operations | ||
| value: | ||
| namespace: sms.verification | ||
| identifier: user_1234567890abcdef | ||
| limit: 10 | ||
| duration: 60000 | ||
| cost: 5 |
There was a problem hiding this comment.
examples object shape violates JSON-Schema/OpenAPI – will break tooling
Inside a Schema Object the examples field (plural) must be an array (JSON-Schema) or should be placed under the media-type (content) layer in OpenAPI. A mapping keyed by example names is invalid.
-examples:
- basic:
- summary: Basic rate limit request
- description: Simple rate limiting for user API requests
- value:
- namespace: api.requests
- identifier: user_1234567890abcdef
- limit: 1000
- duration: 3600000
- withCost:
- summary: Weighted rate limit request
- description: Rate limiting with custom cost for expensive operations
- value:
- namespace: sms.verification
- identifier: user_1234567890abcdef
- limit: 10
- duration: 60000
- cost: 5
+# Move these to the requestBody content level or convert to the JSON-Schema
+# `examples: [ {...}, {...} ]` array form. Keeping the current map will cause
+# speakeasy / swagger-codegen to error out.Please restructure before merging.
🤖 Prompt for AI Agents
In
go/apps/api/openapi/spec/paths/v2/ratelimit/limit/V2RatelimitLimitRequestBody.yaml
lines 62 to 85, the `examples` field is incorrectly defined as a mapping keyed
by example names, which violates JSON-Schema/OpenAPI specifications. To fix
this, convert the `examples` object into an array of example objects or move the
examples under the media-type `content` layer as per OpenAPI guidelines,
ensuring the examples field is either an array or correctly nested to comply
with the schema and avoid tooling issues.
| example: | ||
| namespaceId: namespace_1234567890abcdef | ||
| limit: 10 |
There was a problem hiding this comment.
namespaceId field in example does not exist in schema
The schema defines the property as namespace, but the example uses namespaceId, which will trigger lint errors and confuse readers.
Apply the fix:
-example:
- namespaceId: namespace_1234567890abcdef
- limit: 10
+example:
+ namespace: namespace_1234567890abcdef
+ limit: 10📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| example: | |
| namespaceId: namespace_1234567890abcdef | |
| limit: 10 | |
| example: | |
| namespace: namespace_1234567890abcdef | |
| limit: 10 |
🤖 Prompt for AI Agents
In
go/apps/api/openapi/spec/paths/v2/ratelimit/listOverrides/V2RatelimitListOverridesRequestBody.yaml
at lines 31 to 33, the example uses the field name `namespaceId` which does not
exist in the schema; the correct field name is `namespace`. Update the example
to replace `namespaceId` with `namespace` to match the schema and avoid lint
errors.
| example: | ||
| namespaceId: ns_1234567890abcdef | ||
| identifier: premium_* | ||
| limit: 10000 | ||
| duration: 3600000 |
There was a problem hiding this comment.
Example uses non-existent field namespaceId; schema requires namespace.
This breaks example validity and contradicts the required field list.
-example:
- namespaceId: ns_1234567890abcdef
+example:
+ namespace: ns_1234567890abcdef📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| example: | |
| namespaceId: ns_1234567890abcdef | |
| identifier: premium_* | |
| limit: 10000 | |
| duration: 3600000 | |
| example: | |
| namespace: ns_1234567890abcdef | |
| identifier: premium_* | |
| limit: 10000 | |
| duration: 3600000 |
🤖 Prompt for AI Agents
In
go/apps/api/openapi/spec/paths/v2/ratelimit/setOverride/V2RatelimitSetOverrideRequestBody.yaml
between lines 66 and 70, the example uses the field `namespaceId` which does not
exist in the schema; the correct required field is `namespace`. Replace
`namespaceId` with `namespace` in the example to align it with the schema and
maintain example validity.

What does this PR do?
This PR addresses ~500 lint warnings from speakeasy
Fixes # (issue)
If there is not an issue for this, please create one first. This is used to tracking purposes and also helps use understand why this PR exists
Type of change
How should this be tested?
Checklist
Required
pnpm buildpnpm fmtconsole.logsgit pull origin mainAppreciated
Summary by CodeRabbit
Documentation
Refactor
Style