Skip to content

feat: api keys list #3035

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 47 commits into from
Apr 15, 2025
Merged

feat: api keys list #3035

merged 47 commits into from
Apr 15, 2025

Conversation

ogzhanolguncu
Copy link
Contributor

@ogzhanolguncu ogzhanolguncu commented Mar 27, 2025

What does this PR do?

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

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

How should this be tested?

  • Test A
  • Test B

Checklist

Required

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

Appreciated

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

Summary by CodeRabbit

  • New Features
    • Introduced a comprehensive API key management interface with advanced filtering, natural language search powered by AI, and detailed usage analytics.
    • Added new components for API key details, verification bar charts, status indicators, and skeleton loaders to enhance user experience.
    • Unified API navigation with a new navigation bar supporting contextual breadcrumbs and active page highlighting.
    • Expanded icon set and updated color palette for improved UI consistency and accessibility.
  • Improvements
    • Enhanced table layouts with support for classic and grid modes, configurable row borders, padding, and spacing.
    • Added flexible timestamp display options including local, UTC, and relative formats.
    • Streamlined data fetching by consolidating API and workspace queries, improving performance and code clarity.
    • Improved error handling and user feedback during key management and search operations.
  • Style
    • Updated background colors and transparency for layout and navigation components to create a cleaner, modern look.
  • Chores
    • Added new hooks, schemas, and utilities to support filtering, querying, and status management.
    • Exported internal components for broader reuse.
    • Refined color generation logic to include new color variants.

Copy link

vercel bot commented Mar 27, 2025

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

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

Copy link

changeset-bot bot commented Mar 27, 2025

⚠️ No Changeset found

Latest commit: e7af653

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

This PR includes no changesets

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

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

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

Copy link
Contributor

coderabbitai bot commented Mar 27, 2025

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

This set of changes introduces a comprehensive refactor and feature expansion for API key management within the dashboard application. The update centralizes API and workspace data fetching via a new fetchApiAndWorkspaceDataFromDb function, which is now used across multiple API-related pages, replacing previous direct database queries. The navigation structure is overhauled, removing old breadcrumb-based components and introducing a unified ApisNavbar for consistent navigation. The API keys management UI is rebuilt with new modular React components, including advanced filtering, search (with LLM-powered structured search), status display, and virtualized tables. Supporting schemas, hooks, and backend procedures for querying, filtering, and managing keys are added, along with new icons and UI enhancements. Several files are removed as part of the migration to the new structure.

Changes

File(s) / Path(s) Change Summary
apps/dashboard/app/(app)/apis/[apiId]/actions.ts Adds ApiLayoutData type and fetchApiAndWorkspaceDataFromDb function for centralized API/workspace data fetching.
apps/dashboard/app/(app)/apis/[apiId]/api-id-navbar.tsx Updates ApisNavbar to accept an optional keyId prop and conditionally render navigation items for keys.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/page.tsx Refactors API keys page to use new data-fetching function and new component structure; removes old navigation and content layout.
apps/dashboard/app/(app)/apis/[apiId]/page.tsx Refactors to use fetchApiAndWorkspaceDataFromDb for data retrieval, simplifying control flow.
apps/dashboard/app/(app)/apis/_components/hooks/use-query-timeseries.ts Adds TRPC query config to skip batching in timeseries query hook.
apps/dashboard/app/(app)/layout.tsx Changes default background color to white for light mode.
apps/dashboard/app/(app)/ratelimits/[namespaceId]/_overview/components/charts/bar-chart/hooks/use-fetch-timeseries.ts Adds TRPC query config to skip batching in ratelimit overview timeseries hook.
apps/dashboard/components/navigation/navbar.tsx Changes navbar background to transparent.
apps/dashboard/components/timestamp-info.tsx Adds displayType prop for timestamp display format and updates relative time formatting.
apps/dashboard/components/virtual-table/constants.ts Adds new layout and styling config options to virtual table defaults.
apps/dashboard/components/virtual-table/index.tsx Refactors props handling, adds support for multiple layout modes, improves keyboard navigation, and updates skeleton row logic.
apps/dashboard/components/virtual-table/types.ts Updates and expands type definitions for table data, layout modes, and skeleton row rendering.
apps/dashboard/lib/trpc/routers/api/keys/llm-search-api-keys/index.ts, utils.ts Adds LLM-powered structured search for API keys, with OpenAI integration and robust error handling.
apps/dashboard/lib/trpc/routers/api/keys/query-api-keys/get-all-keys.ts, index.ts, schema.ts Adds backend logic and schemas for querying API keys with filtering and pagination.
apps/dashboard/lib/trpc/routers/api/keys/query-key-usage-timeseries/index.ts Adds backend procedure for key usage timeseries data.
apps/dashboard/lib/trpc/routers/api/keys/query-latest-verification/index.ts Adds backend procedure for fetching latest key verification time.
apps/dashboard/lib/trpc/routers/api/keys/toggle-key-enabled/index.ts Adds backend procedure to enable a disabled key.
apps/dashboard/lib/trpc/routers/index.ts Integrates new API key management procedures into the main router.
internal/clickhouse/src/latest_verifications.ts Adds a limit parameter to latest verifications query for flexible result limits.
internal/icons/src/icons/chart-activity-2.tsx, circle-caret-down.tsx, circle-half-dotted-clock.tsx, circle-lock.tsx, shield-key.tsx Adds new icons and updates existing ones for dynamic sizing and enhanced visuals.
internal/icons/src/index.ts Updates exports to include new and reorganized icons.
internal/ui/colors.css, internal/ui/tailwind.config.js Adds new orange alpha color palette and updates base color opacities for UI theming.
internal/ui/src/components/button.tsx Exports AnimatedLoadingSpinner for wider use.
apps/dashboard/app/(app)/identities/page.tsx Makes Results component's search and limit props optional.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/[keyId]/page.tsx Refactors to use new data-fetching and navigation components; updates to use ApisNavbar and new data structure.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/control-cloud/index.tsx Adds KeysListControlCloud component for filter management and display.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/controls/components/logs-filters/index.tsx Adds LogsFilters component for interactive log filtering.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/controls/components/logs-search/index.tsx Adds LogsSearch component with LLM-powered query integration and error handling.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/controls/index.tsx Adds KeysListControls component to aggregate search and filter controls.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/components/bar-chart/index.tsx Adds VerificationBarChart component for visualizing key usage timeseries.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/components/bar-chart/outcome-explainer.tsx Adds OutcomeExplainer component for summarizing timeseries outcomes.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/components/bar-chart/query-timeseries.schema.ts, use-fetch-timeseries.ts Adds schema and hook for fetching and processing verification timeseries data.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/components/hidden-value.tsx Adds HiddenValueCell component for masked value display and copy-to-clipboard.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/components/last-used.tsx Adds LastUsedCell component to display last key usage with loading/error states.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/components/skeletons.tsx Adds skeleton loader components for table columns.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/components/status-cell/constants.tsx Adds status type definitions and constants for key status display.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/components/status-cell/index.tsx Adds StatusDisplay component for key status with enable/disable logic and tooltips.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/components/status-cell/query-timeseries.schema.ts Adds schema for status cell timeseries queries.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/components/status-cell/use-key-status.ts Adds useKeyStatus hook for computing key status from timeseries and key data.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/components/status-cell/components/status-badge.tsx Adds StatusBadge component for visual status representation.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/hooks/use-keys-list-query.ts Adds useKeysListQuery hook for paginated, filtered key list fetching and state management.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/keys-list.tsx Adds KeysList component for virtualized, interactive key table with custom columns.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/query-logs.schema.ts Adds schema for key logs query filtering.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/utils/get-row-class.ts Adds utility for determining table row styles based on selection and status.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/filters.schema.ts Adds schema and config for key list filter fields and operators.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/hooks/use-filters.ts Adds useFilters hook for managing and updating filter state from URL/query params.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/keys-client.tsx Adds KeysClient component to aggregate controls and key list.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/keys.tsx, navigation.tsx, settings/navigation.tsx Removes obsolete key list and navigation components in favor of new structure.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/navigation.tsx, settings/navigation.tsx Removes old navigation components, replaced by ApisNavbar.
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/settings/page.tsx Replaces old navigation with ApisNavbar in API settings page.
apps/docs/api-reference/errors-v2/unkey/data/invalid_input.mdx, apps/docs/docs.json Removes documentation for a specific error and its navigation entry.
go/apps/api/routes/v2_ratelimit_limit/401_test.go, go/pkg/codes/constants_gen.go Minor non-functional changes: whitespace and timestamp update.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ApisNavbar
    participant fetchApiAndWorkspaceDataFromDb
    participant DB
    participant KeysClient
    participant KeysListControls
    participant KeysListControlCloud
    participant KeysList
    participant useKeysListQuery
    participant BackendAPI

    User->>ApisNavbar: Navigates to API/Key page
    ApisNavbar->>fetchApiAndWorkspaceDataFromDb: fetch(apiId)
    fetchApiAndWorkspaceDataFromDb->>DB: Query API and workspace APIs
    fetchApiAndWorkspaceDataFromDb-->>ApisNavbar: Return { currentApi, workspaceApis }
    ApisNavbar-->>User: Render navigation

    User->>KeysClient: View key management UI
    KeysClient->>KeysListControls: Render search & filter controls
    KeysClient->>KeysListControlCloud: Render filter cloud
    KeysClient->>KeysList: Render key list
    KeysList->>useKeysListQuery: Fetch keys (with filters, pagination)
    useKeysListQuery->>BackendAPI: Query keys list (with filters)
    BackendAPI-->>useKeysListQuery: Return keys data
    useKeysListQuery-->>KeysList: Provide keys, loading, pagination
    KeysList-->>User: Display virtualized key table
Loading

Possibly related PRs

Suggested labels

Feature, Dashboard

Suggested reviewers

  • perkinsjr
  • mcstepp

Warning

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

🔧 golangci-lint (1.64.8)

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


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

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

CodeRabbit Commands (Invoked using PR comments)

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

Other keywords and placeholders

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

CodeRabbit Configuration File (.coderabbit.yaml)

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

Documentation and Community

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

Copy link
Contributor

github-actions bot commented Mar 27, 2025

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/keys-list.tsx (1)

44-45: No navigation reset logic (already noted).

The state navigatingKeyId is set when a link is clicked but not reset later. A past review comment has already flagged this. If navigation fails or silently completes, the spinner could persist and never clear.

🧹 Nitpick comments (2)
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/keys-list.tsx (2)

33-39: Unify naming for keyAuthId and keyspaceId.

Here, you pass keyAuthId: keyspaceId to the hook. While it might work, it could lead to confusion. Consider renaming one or the other for clarity, so that variable names clearly match.


186-264: Consider adding test coverage for table rendering.

Your usage of VirtualTable and the defined skeleton rows, empty state, and load more props is well-structured. Tests verifying pagination, loading states, and row rendering under different conditions will help ensure robust coverage.

Do you want me to provide a sample jest or react-testing-library test suite to cover these scenarios?

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7893a22 and 3016bc7.

📒 Files selected for processing (1)
  • apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/keys-list.tsx (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/keys-list.tsx (8)
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/hooks/use-keys-list-query.ts (1)
  • useKeysListQuery (12-84)
apps/dashboard/lib/trpc/routers/api/keys/query-api-keys/schema.ts (1)
  • KeyDetails (25-25)
apps/dashboard/components/virtual-table/types.ts (1)
  • Column (13-24)
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/components/hidden-value.tsx (1)
  • HiddenValueCell (6-51)
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/components/bar-chart/index.tsx (1)
  • VerificationBarChart (23-184)
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/components/last-used.tsx (1)
  • LastUsedCell (8-57)
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/components/status-cell/index.tsx (1)
  • StatusDisplay (15-143)
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/utils/get-row-class.ts (1)
  • getRowClassName (26-38)
⏰ Context from checks skipped due to timeout of 90000ms (13)
  • GitHub Check: Test Packages / Test ./internal/resend
  • GitHub Check: Test Go API Local / Test (Shard 8/8)
  • GitHub Check: Test Packages / Test ./packages/rbac
  • GitHub Check: Test Go API Local / Test (Shard 3/8)
  • GitHub Check: Test Go API Local / Test (Shard 2/8)
  • GitHub Check: Test Go API Local / Test (Shard 5/8)
  • GitHub Check: Test Go API Local / Test (Shard 7/8)
  • GitHub Check: Test Go API Local / Test (Shard 4/8)
  • GitHub Check: Test Packages / Test ./internal/id
  • GitHub Check: Test Go API Local / Test (Shard 1/8)
  • GitHub Check: Test Agent Local / test_agent_local
  • GitHub Check: Build / Build
  • GitHub Check: Test API / API Test Local
🔇 Additional comments (1)
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/keys-list.tsx (1)

1-31: Looks clean and organized.

Your imports and initial setup appear consistent with Next.js best practices. The "use client"; directive is properly placed to enable client-side rendering. No syntax or functionality issues are apparent in this segment.

* refactor: remove request_id from cursors (#3093)

* refactor: remove requestid from logs cursor

* fix: cursor object

* refactor: remove request_id from ratelimit overview cursor

* refactor: remove request_id from ratelimit logs

* refactor: remove request id from api cursor

* fix: type issue and make query shorter

---------

Co-authored-by: Andreas Thomas <dev@chronark.com>

* feat: errors v2 (#3110)

* feat: /v2/apis/createApi endpoint

* ci: install api dependencies

* feat: errors

* [autofix.ci] apply automated fixes

* revert: breaking changes

* revert: bad copypaste

* fix: bad copypaste

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* feat: use axiom

* fix: don't hide the cool dots

---------

Co-authored-by: Oğuzhan Olguncu <21091016+ogzhanolguncu@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🔭 Outside diff range comments (1)
apps/dashboard/lib/trpc/routers/ratelimit/query-logs/index.ts (1)

14-78: 💡 Verification agent

🧩 Analysis chain

Verify all cursor consumers are updated.

This change simplifies cursor handling, but ensure all consumers of this API are updated to work with the new cursor format.


🏁 Script executed:

#!/bin/bash
# Find all places where ratelimit logs cursor might be used

# Look for places that might use the old cursor structure with requestId
echo "Places potentially using old cursor structure:"
rg "cursor\?\.requestId|nextCursor.*requestId" --type tsx --type ts

Length of output: 200


Cursor Update Verification Required

The initial search encountered an error due to the unrecognized file type for TSX files. Please re-run the following shell script, which adds custom definitions for TS and TSX files, to verify that no references to the old cursor structure (using requestId) exist in the codebase:

Review the output manually to ensure that all consumers of the API use the new cursor format.


🏁 Script executed:

#!/bin/bash
# Add custom file types for TS and TSX, then search for potential usage of the old cursor structure
rg --type-add 'tsx:*.tsx' --type-add 'ts:*.ts' "cursor\\?\\.requestId|nextCursor.*requestId" .

Length of output: 334


Cursor Consumers Must Use the Updated Format

  • The new API in apps/dashboard/lib/trpc/routers/ratelimit/query-logs/index.ts now returns a numeric cursor (nextCursor) instead of the old structure.
  • However, the file apps/engineering/content/contributing/pull-request-checks.mdx still references the previous format (input.cursor?.requestId), which indicates that some consumers of the API are not updated.
  • Please update all consumers—including documentation and any client code that references the old requestId field—to ensure they work with the new cursor format correctly.
🧹 Nitpick comments (42)
apps/workflows/wrangler.toml (1)

7-8: New Compatibility Flag Added

The addition of compatibility_flags = ["nodejs_compat"] correctly introduces the node.js compatibility setting. It is appropriately positioned within the file. Consider adding an inline comment or documentation note explaining the rationale behind using this particular flag for future maintainability.

apps/agent/go.mod (1)

49-49: Dependency Version Downgrade: Verify Compatibility of github.com/ClickHouse/ch-go

The version of github.com/ClickHouse/ch-go has been downgraded from v0.65.0 to v0.64.1. Please verify that this change is intentional and that the older version does not introduce any regressions or compatibility issues in the agent's functionality. It’s advisable to check the dependency's changelog and related documentation to ensure that the downgrade addresses specific problems (e.g., data loss, bugs, or performance concerns) without adversely affecting other functionality.

apps/www/content/blog/zen.mdx (1)

368-373: Ensure Consistent and Clear Error Categorization

The updated error-handling block now uses fault.WithCode(codes.Auth.Authorization.InsufficientPermissions.URN()) instead of the previous tag-based approach. This change brings more structure to error responses and aids in standardized logging and troubleshooting. Please verify that:

  • The URN returned by codes.Auth.Authorization.InsufficientPermissions.URN() aligns with your error catalog.
  • Similar error handling paths elsewhere in the codebase adopt the same pattern to avoid inconsistency.
  • The use of identical messages for both internal and user-facing descriptions (via fault.WithDesc(permissions.Message, permissions.Message)) is intentional; consider providing differentiated details if needed for clarity.
go/pkg/otel/axiom.go (3)

62-86: Consider validating required config fields.

The function doesn't validate that required fields in AxiomConfig are provided before using them.

func InitAxiom(ctx context.Context, config AxiomConfig, shutdowns *shutdown.Shutdowns) error {
+	// Validate required configuration
+	if config.Application == "" {
+		return fmt.Errorf("application name must be provided")
+	}

	logger, err := adapter.New(adapter.SetDataset("apiv2_logs"))
	if err != nil {
		return fmt.Errorf("failed to initialize logging: %w", err)
	}

64-74: Consider making dataset name configurable.

The dataset name "apiv2_logs" is hardcoded. Consider making it part of the AxiomConfig for more flexibility.

type AxiomConfig struct {
	// Application is the name of your application, used to identify the source of telemetry data.
	// This appears in Axiom dashboards and alerts.
	Application string

	// Version is the current version of your application, allowing you to correlate
	// behavior changes with specific releases.
	Version string
+
+	// LogDataset is the name of the Axiom dataset to store logs
+	LogDataset string
+
+	// TraceDataset is the name of the Axiom dataset to store traces
+	TraceDataset string
}

func InitAxiom(ctx context.Context, config AxiomConfig, shutdowns *shutdown.Shutdowns) error {
+	logDataset := "apiv2_logs"
+	if config.LogDataset != "" {
+		logDataset = config.LogDataset
+	}

-	logger, err := adapter.New(adapter.SetDataset("apiv2_logs"))
+	logger, err := adapter.New(adapter.SetDataset(logDataset))

75-84: Consider making trace dataset name configurable.

Similar to the logs dataset, the traces dataset name "apiv2_traces" is hardcoded. Consider making it configurable in AxiomConfig.

func InitAxiom(ctx context.Context, config AxiomConfig, shutdowns *shutdown.Shutdowns) error {
	// ... previous code

+	traceDataset := "apiv2_traces"
+	if config.TraceDataset != "" {
+		traceDataset = config.TraceDataset
+	}

-	traceProvider, err := axiomOtel.TracerProvider(context.Background(), "apiv2_traces", config.Application, config.Version)
+	traceProvider, err := axiomOtel.TracerProvider(context.Background(), traceDataset, config.Application, config.Version)
apps/engineering/content/rfcs/0011-unkey-resource-names.mdx (5)

29-36: URN Component Explanation and Style:
The detailed explanation of each URN component is comprehensive. A minor nitpick: double-check the article usage in “a Unkey resource identifier” (line 30) to ensure it reads naturally—if “Unkey” is pronounced with a vowel sound, “an” might be more appropriate. Also, consider enforcing a consistent hyphenation style for compound adjectives (e.g., “rate-limiting” instead of “ratelimit”) in later sections.

🧰 Tools
🪛 LanguageTool

[misspelling] ~30-~30: Use “an” instead of ‘a’ if the following word starts with a vowel sound, e.g. ‘an article’, ‘an hour’.
Context: ...nkey- Fixed prefix indicating this is a Unkey resource identifier *service` -...

(EN_A_VS_AN)


43-57: URN Examples:
The examples provided in the "Examples" subsection effectively illustrate the use of URNs for different resource types. For enhanced clarity, consider adding a brief inline description for each example to explain the context further.


59-70: Service Namespace Detailing:
The service namespace list is comprehensive and aligns with the product roadmap. As a suggestion, standardize the naming by considering hyphenation for compound modifiers (e.g., “rate-limiting” instead of “ratelimit”) to improve clarity and consistency throughout the document.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~64-~64: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...ation and authorization * ratelimit - Rate limiting service * identity - Identity managem...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


242-253: Appendix A & B - Rate Limiting and Identity Services:
The error codes for the Rate Limiting and Identity services are clear and comprehensive. A minor suggestion is to consider hyphenating “rate-limiting” to enhance readability, as highlighted by static analysis.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~242-~242: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...Resource already exists (conflict) ### Rate Limiting Service (ratelimit) - `err:ratelimit:...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


254-261: Appendix B - Related Work:
The Related Work section effectively references established standards (such as RFC 8141, AWS ARNs, Azure Resource IDs, and Google Cloud Resource Names). For better usability, consider adding hyperlinks to these references so that readers can easily access the source material.

apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/components/hidden-value.tsx (2)

14-15: Consider more explicit masking logic

The comment indicates "Show only first 4 characters, then dots" but the implementation pads the value to 16 characters with dots, which doesn't actually reveal only the first 4 characters. The masking behavior is inconsistent with the code comment.

  // Show only first 4 characters, then dots
- const displayValue = value.padEnd(16, "•");
+ const displayValue = value.substring(0, 4) + "•".repeat(Math.max(0, 12));

40-44: Consider simplifying the nested divs

The nested divs could be simplified without losing the layout. This would make the component more maintainable.

- <div>
-   <CircleLock size="sm-regular" className="text-gray-9" />
- </div>
- <div>{displayValue}</div>
+ <CircleLock size="sm-regular" className="text-gray-9" />
+ <span>{displayValue}</span>
go/pkg/db/handle_err_no_rows.go (1)

8-9: Function looks good but consider adding docs.

This new utility function provides a clear and focused way to check for "not found" errors. Since it's an exported function with no comments, consider adding a Go doc comment to explain its purpose and behavior.

+// IsNotFound returns true if the error indicates a "not found" condition (sql.ErrNoRows).
 func IsNotFound(err error) bool {
 	return errors.Is(err, sql.ErrNoRows)
 }
apps/docs/api-reference/errors/code/BAD_REQUEST.mdx (1)

8-8: Fix grammar issues in the error description.

There are two grammar issues in this sentence:

-You do not have permission to perform this action. In most cases this means the root key you are using, is lacking permissions.
+You do not have permission to perform this action. In most cases, this means the root key you are using is lacking permissions.
🧰 Tools
🪛 LanguageTool

[formatting] ~8-~8: Insert a comma after ‘cases’: “In most cases,”?
Context: ...have permission to perform this action. In most cases this means the root key you are using, ...

(IN_MOST_CASES_COMMA)


[uncategorized] ~8-~8: Possible missing comma found.
Context: ...tion. In most cases this means the root key you are using, is lacking permissions. ...

(AI_HYDRA_LEO_MISSING_COMMA)

go/pkg/codes/unkey_auth.go (1)

44-58: Consider adding usage examples in code comments.

While the error codes are well-defined, including short usage examples in comments could help developers quickly understand typical handling scenarios (e.g., referencing codes.Auth.Authentication.Missing).

go/pkg/urn/urn.go (1)

66-84: Future-proofing resource type prefix validation.

The switch statement for prefix validation is clear. If resource types expand, remember to update this logic accordingly.

go/pkg/fault/wrap.go (1)

84-84: Consistent renaming from tag to code

The same field renaming from tag to code is applied here for consistency with the error handling improvements.

However, note that the code comments (lines 62-66) still reference WithTag(), which should be updated to reflect the new naming.

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

27-32:

❓ Verification inconclusive

Consider security implications of embedding the OpenAPI spec directly in the HTML.

For large OpenAPI specifications or those containing sensitive information, embedding the entire spec directly in the HTML might not be ideal. Consider alternative approaches like loading the spec via a separate API endpoint.


🏁 Script executed:

#!/bin/bash
# Check size of the OpenAPI spec to determine if it's too large for direct embedding
echo "Size of OpenAPI spec (in bytes):"
echo -n "import \"github.com/unkeyed/unkey/go/apps/api/openapi\"; println(len(openapi.Spec))" | go run -

Length of output: 202


Action: Verify security and performance implications of embedding the OpenAPI spec

The OpenAPI spec is being directly embedded in the HTML, which might expose sensitive information or affect performance if the spec is large. The initial script intended to measure the spec’s size did not yield useful output (“go: no go files listed”), indicating that the current method for determining the size and sensitivity of the spec needs manual verification.

  • Manual Verification Needed: Please confirm whether the spec is small and free of sensitive details. If the spec is large or contains sensitive information, consider loading it via a dedicated, secure API endpoint instead.
  • Next Steps Suggestion: Rework the inclusion so that the spec is fetched dynamically, allowing for better control over access and mitigating potential performance bottlenecks or security issues.
apps/docs/api-reference/errors-v2/unkey/data/invalid_input.mdx (3)

60-60: Minor wording improvement suggestion

Consider rephrasing for better clarity and formality.

-3. Look at the `fix` field (if available) for guidance on how to correct the issue
+3. Look at the `fix` field (if available) for guidance on how to resolve the issue
🧰 Tools
🪛 LanguageTool

[style] ~60-~60: Consider using a different verb for a more formal wording.
Context: ...d (if available) for guidance on how to correct the issue 4. Modify your request to com...

(FIX_RESOLVE)


81-81: Remove redundant phrasing

The phrase "outside of" is redundant and can be simplified.

-- **Range violations**: Providing values outside of allowed ranges (too small, too large)
+- **Range violations**: Providing values outside allowed ranges (too small, too large)
🧰 Tools
🪛 LanguageTool

[style] ~81-~81: This phrase is redundant. Consider using “outside”.
Context: ... Range violations: Providing values outside of allowed ranges (too small, too large) -...

(OUTSIDE_OF)


41-52: Secure example API keys in the documentation

The example curl commands should use a clearly fictional placeholder for the API key instead of "unkey_YOUR_API_KEY" to prevent copy-paste errors with real credentials.

-  -H "Authorization: Bearer unkey_YOUR_API_KEY" \
+  -H "Authorization: Bearer unkey_EXAMPLE_KEY_REPLACE_ME" \

Also applies to: 65-76

go/pkg/fault/code.go (1)

19-20: Fix example code indentation

There's a minor formatting issue in the example code comment.

-//	 code, ok := GetCode(wrapped)
+//		code, ok := GetCode(wrapped)
apps/docs/api-reference/errors-v2/unkey/authorization/workspace_disabled.mdx (1)

48-48: Minor grammatical suggestion.

Consider adding the definite article "the" before "workspace administrator" for proper grammar.

-2. **Contact workspace administrator**: If you're not the workspace administrator, contact them to determine why the workspace was disabled
+2. **Contact the workspace administrator**: If you're not the workspace administrator, contact them to determine why the workspace was disabled
🧰 Tools
🪛 LanguageTool

[uncategorized] ~48-~48: You might be missing the article “the” here.
Context: ...key.com/settings/billing) 2. Contact workspace administrator: If you're not the work...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

apps/docs/api-reference/errors-v2/unkey/application/invalid_input.mdx (1)

81-81: Minor wording suggestion.

The phrase "outside of allowed ranges" contains a slight redundancy. Consider simplifying to just "outside allowed ranges" for conciseness.

-  **Range violations**: Providing values outside of allowed ranges (too small, too large)
+  **Range violations**: Providing values outside allowed ranges (too small, too large)
🧰 Tools
🪛 LanguageTool

[style] ~81-~81: This phrase is redundant. Consider using “outside”.
Context: ... Range violations: Providing values outside of allowed ranges (too small, too large) -...

(OUTSIDE_OF)

apps/docs/api-reference/errors-v2/unkey/authorization/forbidden.mdx (2)

45-47: Consider reducing repetitive phrasing.

The static analysis tool detected repetitive use of "trying to" phrases in nearby sentences.

-This error indicates a fundamental restriction rather than a permission issue. The operation you're trying to perform may be:
+This error indicates a fundamental restriction rather than a permission issue. The operation you're attempting may be:

 1. **Not supported by the Unkey platform**: Some operations are simply not available

and

-**Resource state issues**: Trying to modify resources that are in a state that doesn't allow changes
-**Ignoring documentation warnings**: Not reading warnings about restricted operations
-**Testing security boundaries**: Deliberately trying to access protected resources
+**Resource state issues**: Attempting to modify resources that are in a state that doesn't allow changes
+**Ignoring documentation warnings**: Not reading warnings about restricted operations
+**Testing security boundaries**: Deliberately accessing protected resources

Also applies to: 65-67

🧰 Tools
🪛 LanguageTool

[style] ~45-~45: You have already used ‘trying to’ in nearby sentences. Consider using one of the replacements to let your writing stand out.
Context: ... permission issue. The operation you're trying to perform may be: 1. **Not supported by ...

(REP_TRY)


33-41: Authentication example contains placeholder token.

The example includes a placeholder authentication bearer token. Although this is a documentation example, it's good practice to make it clear this is a non-functional example.

 ```bash
 # Attempting to delete a protected system resource
 curl -X POST https://api.unkey.com/v2/apis.deleteApi \
   -H "Content-Type: application/json" \
-  -H "Authorization: Bearer unkey_ADMIN_KEY" \
+  -H "Authorization: Bearer unkey_YOUR_ADMIN_KEY_HERE" \
   -d '{
     "apiId": "api_system_protected"
   }'

</blockquote></details>
<details>
<summary>apps/docs/api-reference/errors-v2/unkey/data/identity_already_exists.mdx (2)</summary><blockquote>

`35-45`: **Consider using placeholder tokens in authentication examples.**

The static analysis tool flagged the authentication headers in the curl examples. While this is a common documentation pattern, consider using more obvious placeholder values like `unkey_YOUR_API_KEY_HERE` to minimize the risk of users copy-pasting examples with credentials.

```diff
-  -H "Authorization: Bearer unkey_YOUR_API_KEY" \
+  -H "Authorization: Bearer unkey_YOUR_API_KEY_HERE" \
🧰 Tools
🪛 Gitleaks (8.21.2)

43-45:

(curl-auth-header)


59-69: Same authentication header concern in this example.

For consistency, consider using the same placeholder pattern in all authentication examples.

-  -H "Authorization: Bearer unkey_YOUR_API_KEY" \
+  -H "Authorization: Bearer unkey_YOUR_API_KEY_HERE" \
🧰 Tools
🪛 Gitleaks (8.21.2)

67-69:

(curl-auth-header)

apps/docs/api-reference/errors-v2/unkey/data/identity_not_found.mdx (1)

35-40: Consider using environment variables in curl examples.

While the use of placeholder values like unkey_YOUR_API_KEY is appropriate for documentation, consider using environment variables in curl examples to promote better security practices.

curl -X POST https://api.unkey.com/v1/identities.getIdentity \
  -H "Content-Type: application/json" \
- -H "Authorization: Bearer unkey_YOUR_API_KEY" \
+ -H "Authorization: Bearer $UNKEY_API_KEY" \
  -d '{
    "identityId": "ident_nonexistent"
  }'
🧰 Tools
🪛 Gitleaks (8.21.2)

35-37:

(curl-auth-header)

apps/docs/api-reference/errors-v2/unkey/data/role_not_found.mdx (1)

35-41: Consider using environment variables in curl examples.

Similar to the other documentation file, consider using environment variables for API keys in examples.

curl -X POST https://api.unkey.com/v1/roles.addPermission \
  -H "Content-Type: application/json" \
- -H "Authorization: Bearer unkey_YOUR_API_KEY" \
+ -H "Authorization: Bearer $UNKEY_API_KEY" \
  -d '{
    "roleId": "role_nonexistent",
    "permissionId": "perm_123abc"
  }'
apps/docs/api-reference/errors-v2/unkey/application/protected_resource.mdx (2)

23-23: Minor grammar improvement suggested

Consider adding an article for improved readability.

-This error occurs when you attempt to modify or delete a resource that is marked as protected in the Unkey system. Protected resources have special status that prevents them from being changed or removed, typically because they are system resources, defaults, or otherwise critical to proper system operation.
+This error occurs when you attempt to modify or delete a resource that is marked as protected in the Unkey system. Protected resources have a special status that prevents them from being changed or removed, typically because they are system resources, defaults, or otherwise critical to proper system operation.
🧰 Tools
🪛 LanguageTool

[uncategorized] ~23-~23: Possible missing article found.
Context: ... Unkey system. Protected resources have special status that prevents them from being ch...

(AI_HYDRA_LEO_MISSING_A)


45-46: Minor stylistic improvement suggested

The phrase "trying to" is used repeatedly. Consider rewording for better readability.

-Since protected resources are deliberately shielded from modification, the solution is usually to work with or around them rather than trying to change them:
+Since protected resources are deliberately shielded from modification, the solution is usually to work with or around them rather than attempting to change them:
🧰 Tools
🪛 LanguageTool

[style] ~45-~45: You have already used ‘trying to’ in nearby sentences. Consider using one of the replacements to let your writing stand out.
Context: ...to work with or around them rather than trying to change them: 1. **Work with the protec...

(REP_TRY)

apps/docs/api-reference/errors-v2/unkey/data/permission_not_found.mdx (1)

23-23: Use of 'a permission' might be grammatically redundant.

You can remove 'a' before "permission" to align with how "permission" is often treated as an uncountable noun. For instance:

-This error occurs when you're trying to perform an operation on a permission that doesn't exist in the Unkey system.
+This error occurs when you're trying to perform an operation on permission that doesn't exist in the Unkey system.

-Referencing a permission that has been deleted
+Referencing permission that has been deleted

-Trying to assign a permission that doesn't exist in the current workspace
+Trying to assign permission that doesn't exist in the current workspace

Also applies to: 27-28

🧰 Tools
🪛 LanguageTool

[grammar] ~23-~23: ‘a’ may be redundant when used with the uncountable noun ‘permission’.
Context: ...ou're trying to perform an operation on a permission that doesn't exist in the Unkey system....

(A_UNCOUNTABLE_NOUN)

internal/clickhouse/src/ratelimits.ts (1)

357-359: Check inclusivity when comparing times.

Here, we filter logs with time < cursorTime for pagination. This is valid for strictly older entries. If we want to include logs that occur exactly at the cursor time or adjust the boundary, we might consider <= or a different comparison. Otherwise, this approach is appropriate for descending order retrieval.

apps/docs/api-reference/errors-v2/overview.mdx (1)

46-46: Consider using a hyphen for clarity in "rate limiting."

Treat "rate-limiting" as a compound adjective describing "errors":

-**limits**: Rate limiting or quota-related errors
+**limits**: Rate-limiting or quota-related errors
🧰 Tools
🪛 LanguageTool

[uncategorized] ~46-~46: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ... operations and resources - limits: Rate limiting or quota-related errors ## Error Respo...

(EN_COMPOUND_ADJECTIVE_INTERNAL)

apps/docs/api-reference/errors-v2/unkey/data/audit_log_not_found.mdx (1)

1-71: Documentation looks good overall, but there's a minor grammar fix to consider.

At line 49, adding a comma will improve readability:

-4. Consider that audit logs might have a retention period after which they're automatically deleted
+4. Consider that audit logs might have a retention period, after which they're automatically deleted
🧰 Tools
🪛 LanguageTool

[uncategorized] ~49-~49: Possible missing comma found.
Context: ... that audit logs might have a retention period after which they're automatically delet...

(AI_HYDRA_LEO_MISSING_COMMA)

🪛 Gitleaks (8.21.2)

43-45:

(curl-auth-header)


67-69:

(curl-auth-header)

go/pkg/codes/generate.go (1)

1-195: Minor unused function.

The toSnakeCase function (lines 184-194) is not referenced anywhere in this file. Consider removing it or using it if needed.

-// toSnakeCase converts a string from PascalCase to snake_case
-func toSnakeCase(s string) string {
-	var result strings.Builder
-	for i, r := range s {
-		if i > 0 && unicode.IsUpper(r) {
-			result.WriteRune('_')
-		}
-		result.WriteRune(unicode.ToLower(r))
-	}
-	return result.String()
-}
apps/docs/api-reference/errors-v2/unkey/application/unexpected_error.mdx (1)

80-81: Consider revising to remove repetition.

The phrases "this error" and "This error" appear consecutively at the end of line 80 and beginning of line 81, creating a repetitive-sounding sequence.

- Always include the `requestId` when contacting support about this error
- This error may indicate a bug in Unkey's systems that needs to be fixed
+ Always include the `requestId` when contacting support
+ This error may indicate a bug in Unkey's systems that needs to be fixed
🧰 Tools
🪛 LanguageTool

[grammar] ~80-~80: This phrase is duplicated. You should probably use “this error” only once.
Context: ...equestId` when contacting support about this error - This error may indicate a bug in Unkey's systems t...

(PHRASE_REPETITION)

go/pkg/urn/resource.go (1)

34-39: Consider adding comments for empty service maps.

Several services (Deploy, Observe, Audit, Secrets, Billing) have empty maps for valid resource types. If this is intentional because these services don't have associated resource types yet, consider adding a comment to clarify this for future developers.

 validResourceTypes := map[Service]map[ResourceType]bool{
     ServiceAuth: {
         ResourceTypeKey: true,
         ResourceTypeAPI: true,
     },
     ServiceRateLimit: {
         ResourceTypeNamespace: true,
     },
     ServiceIdentity: {
         ResourceTypeIdentity: true,
     },
-    ServiceDeploy:  {},
-    ServiceObserve: {},
-    ServiceAudit:   {},
-    ServiceSecrets: {},
-    ServiceBilling: {},
+    ServiceDeploy:  {}, // No resource types defined yet
+    ServiceObserve: {}, // No resource types defined yet
+    ServiceAudit:   {}, // No resource types defined yet
+    ServiceSecrets: {}, // No resource types defined yet
+    ServiceBilling: {}, // No resource types defined yet
 }
go/pkg/urn/service.go (1)

35-36: Consider dynamically generating the list of valid services.

The error message manually lists all valid services. If new services are added in the future, this list would need to be updated in multiple places, which could lead to inconsistencies.

 func (s Service) Validate() error {
-	return assert.True(validServices[s],
-		"invalid service: must be one of [auth, ratelimit, identity, deploy, observe, audit, secrets, billing]")
+	if !validServices[s] {
+		validServicesList := make([]string, 0, len(validServices))
+		for svc := range validServices {
+			validServicesList = append(validServicesList, string(svc))
+		}
+		return assert.True(false, "invalid service: must be one of "+fmt.Sprintf("%v", validServicesList))
+	}
+	return nil
 }

You'll need to add "fmt" to the imports.

go/pkg/codes/constants_gen.go (1)

1-114: Consider adding examples of usage in documentation for these error codes.

While the error constants are well-defined, adding documentation comments showing how to properly use these error codes in application code would be beneficial. This could include examples of error handling patterns, how to convert these URNs to HTTP status codes, or how to include them in error responses.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 3016bc7 and 13d552f.

⛔ Files ignored due to path filters (3)
  • apps/agent/go.sum is excluded by !**/*.sum
  • go/go.sum is excluded by !**/*.sum
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (114)
  • apps/agent/go.mod (1 hunks)
  • apps/dashboard/app/(app)/apis/[apiId]/_overview/components/table/hooks/use-logs-query.ts (0 hunks)
  • apps/dashboard/app/(app)/apis/[apiId]/_overview/components/table/query-logs.schema.ts (1 hunks)
  • apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/components/hidden-value.tsx (1 hunks)
  • apps/dashboard/app/(app)/logs/components/table/hooks/use-logs-query.ts (0 hunks)
  • apps/dashboard/app/(app)/logs/components/table/query-logs.schema.ts (1 hunks)
  • apps/dashboard/app/(app)/ratelimits/[namespaceId]/_overview/components/table/hooks/use-logs-query.ts (0 hunks)
  • apps/dashboard/app/(app)/ratelimits/[namespaceId]/_overview/components/table/query-logs.schema.ts (1 hunks)
  • apps/dashboard/app/(app)/ratelimits/[namespaceId]/logs/components/table/hooks/use-logs-query.ts (0 hunks)
  • apps/dashboard/app/(app)/ratelimits/[namespaceId]/logs/components/table/query-logs.schema.ts (1 hunks)
  • apps/dashboard/lib/trpc/routers/api/keys/query-overview-logs/index.ts (3 hunks)
  • apps/dashboard/lib/trpc/routers/api/keys/query-overview-logs/utils.ts (1 hunks)
  • apps/dashboard/lib/trpc/routers/logs/query-logs/index.ts (3 hunks)
  • apps/dashboard/lib/trpc/routers/logs/query-logs/utils.test.ts (0 hunks)
  • apps/dashboard/lib/trpc/routers/logs/query-logs/utils.ts (1 hunks)
  • apps/dashboard/lib/trpc/routers/ratelimit/query-logs/index.ts (3 hunks)
  • apps/dashboard/lib/trpc/routers/ratelimit/query-logs/utils.ts (1 hunks)
  • apps/dashboard/lib/trpc/routers/ratelimit/query-overview-logs/index.ts (3 hunks)
  • apps/dashboard/lib/trpc/routers/ratelimit/query-overview-logs/utils.ts (1 hunks)
  • apps/docs/api-reference/errors-v2/overview.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/application/assertion_failed.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/application/invalid_input.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/application/protected_resource.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/application/service_unavailable.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/application/unexpected_error.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/authentication/key_not_found.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/authentication/malformed.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/authentication/missing.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/authorization/forbidden.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/authorization/insufficient_permissions.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/authorization/key_disabled.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/authorization/workspace_disabled.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/data/api_not_found.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/data/audit_log_not_found.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/data/identity_already_exists.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/data/identity_not_found.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/data/invalid_input.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/data/key_auth_not_found.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/data/key_not_found.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/data/permission_not_found.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/data/ratelimit_namespace_not_found.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/data/ratelimit_override_not_found.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/data/role_not_found.mdx (1 hunks)
  • apps/docs/api-reference/errors-v2/unkey/data/workspace_not_found.mdx (1 hunks)
  • apps/docs/api-reference/errors/code/BAD_REQUEST.mdx (1 hunks)
  • apps/docs/docs.json (1 hunks)
  • apps/docs/mint.json (0 hunks)
  • apps/docs/package.json (1 hunks)
  • apps/engineering/content/rfcs/0011-unkey-resource-names.mdx (1 hunks)
  • apps/workflows/wrangler.toml (1 hunks)
  • apps/www/content/blog/zen.mdx (2 hunks)
  • go/apps/api/cancel_test.go (1 hunks)
  • go/apps/api/config.go (1 hunks)
  • go/apps/api/routes/reference/handler.go (1 hunks)
  • go/apps/api/routes/register.go (2 hunks)
  • go/apps/api/routes/v2_apis_create_api/401_test.go (1 hunks)
  • go/apps/api/routes/v2_apis_create_api/handler.go (5 hunks)
  • go/apps/api/routes/v2_identities_create_identity/400_test.go (1 hunks)
  • go/apps/api/routes/v2_identities_create_identity/401_test.go (1 hunks)
  • go/apps/api/routes/v2_identities_create_identity/409_test.go (1 hunks)
  • go/apps/api/routes/v2_identities_create_identity/handler.go (6 hunks)
  • go/apps/api/routes/v2_ratelimit_delete_override/400_test.go (2 hunks)
  • go/apps/api/routes/v2_ratelimit_delete_override/404_test.go (3 hunks)
  • go/apps/api/routes/v2_ratelimit_delete_override/handler.go (7 hunks)
  • go/apps/api/routes/v2_ratelimit_get_override/400_test.go (1 hunks)
  • go/apps/api/routes/v2_ratelimit_get_override/401_test.go (1 hunks)
  • go/apps/api/routes/v2_ratelimit_get_override/404_test.go (3 hunks)
  • go/apps/api/routes/v2_ratelimit_get_override/handler.go (5 hunks)
  • go/apps/api/routes/v2_ratelimit_limit/400_test.go (0 hunks)
  • go/apps/api/routes/v2_ratelimit_limit/401_test.go (2 hunks)
  • go/apps/api/routes/v2_ratelimit_limit/404_test.go (1 hunks)
  • go/apps/api/routes/v2_ratelimit_limit/handler.go (4 hunks)
  • go/apps/api/routes/v2_ratelimit_set_override/400_test.go (1 hunks)
  • go/apps/api/routes/v2_ratelimit_set_override/401_test.go (1 hunks)
  • go/apps/api/routes/v2_ratelimit_set_override/404_test.go (2 hunks)
  • go/apps/api/routes/v2_ratelimit_set_override/handler.go (8 hunks)
  • go/apps/api/run.go (1 hunks)
  • go/cmd/api/main.go (3 hunks)
  • go/go.mod (5 hunks)
  • go/internal/services/keys/verify.go (4 hunks)
  • go/internal/services/keys/verify_root_key.go (0 hunks)
  • go/internal/services/ratelimit/service.go (1 hunks)
  • go/pkg/assert/assert.go (14 hunks)
  • go/pkg/codes/codes.go (1 hunks)
  • go/pkg/codes/constants_gen.go (1 hunks)
  • go/pkg/codes/doc.go (1 hunks)
  • go/pkg/codes/generate.go (1 hunks)
  • go/pkg/codes/generate_run.go (1 hunks)
  • go/pkg/codes/nil.go (1 hunks)
  • go/pkg/codes/unkey_application.go (1 hunks)
  • go/pkg/codes/unkey_auth.go (1 hunks)
  • go/pkg/codes/unkey_data.go (1 hunks)
  • go/pkg/db/generate.go (1 hunks)
  • go/pkg/db/handle_err_no_rows.go (1 hunks)
  • go/pkg/fault/code.go (1 hunks)
  • go/pkg/fault/code_test.go (1 hunks)
  • go/pkg/fault/dst_test.go (8 hunks)
  • go/pkg/fault/tag.go (0 hunks)
  • go/pkg/fault/wrap.go (2 hunks)
  • go/pkg/fault/wrap_test.go (5 hunks)
  • go/pkg/fault/wrapped.go (3 hunks)
  • go/pkg/fault/wrapped_test.go (2 hunks)
  • go/pkg/otel/axiom.go (1 hunks)
  • go/pkg/prometheus/server.go (1 hunks)
  • go/pkg/urn/resource.go (1 hunks)
  • go/pkg/urn/service.go (1 hunks)
  • go/pkg/urn/urn.go (1 hunks)
  • go/pkg/zen/auth.go (2 hunks)
  • go/pkg/zen/auth_test.go (6 hunks)
  • go/pkg/zen/middleware_errors.go (3 hunks)
  • go/pkg/zen/middleware_logger.go (1 hunks)
  • internal/clickhouse/src/keys/keys.ts (2 hunks)
  • internal/clickhouse/src/logs.ts (1 hunks)
  • internal/clickhouse/src/ratelimits.ts (3 hunks)
💤 Files with no reviewable changes (9)
  • apps/docs/mint.json
  • go/internal/services/keys/verify_root_key.go
  • apps/dashboard/app/(app)/logs/components/table/hooks/use-logs-query.ts
  • apps/dashboard/app/(app)/ratelimits/[namespaceId]/_overview/components/table/hooks/use-logs-query.ts
  • apps/dashboard/app/(app)/ratelimits/[namespaceId]/logs/components/table/hooks/use-logs-query.ts
  • apps/dashboard/lib/trpc/routers/logs/query-logs/utils.test.ts
  • go/apps/api/routes/v2_ratelimit_limit/400_test.go
  • apps/dashboard/app/(app)/apis/[apiId]/_overview/components/table/hooks/use-logs-query.ts
  • go/pkg/fault/tag.go
✅ Files skipped from review due to trivial changes (4)
  • go/pkg/codes/generate_run.go
  • go/pkg/db/generate.go
  • go/pkg/prometheus/server.go
  • apps/docs/docs.json
🧰 Additional context used
🧬 Code Graph Analysis (28)
go/pkg/codes/nil.go (1)
go/pkg/codes/codes.go (3)
  • System (19-19)
  • SystemNil (23-23)
  • Category (40-40)
go/apps/api/run.go (3)
go/pkg/otel/grafana.go (2)
  • InitGrafana (86-191)
  • Config (27-52)
go/apps/api/config.go (1)
  • Config (7-50)
go/pkg/otel/axiom.go (2)
  • InitAxiom (62-86)
  • AxiomConfig (20-29)
go/pkg/fault/wrapped_test.go (2)
go/pkg/fault/code.go (1)
  • WithCode (37-51)
go/pkg/codes/unkey_auth.go (1)
  • Auth (44-57)
go/apps/api/routes/v2_identities_create_identity/401_test.go (2)
go/pkg/testutil/http.go (1)
  • CallRoute (180-214)
go/apps/api/openapi/gen.go (1)
  • BadRequestErrorResponse (46-49)
apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/components/hidden-value.tsx (1)
internal/icons/src/icons/circle-lock.tsx (1)
  • CircleLock (15-61)
go/apps/api/routes/v2_ratelimit_get_override/401_test.go (1)
go/pkg/testutil/http.go (1)
  • CallRoute (180-214)
go/cmd/api/main.go (3)
go/pkg/zen/validation/validator.go (1)
  • Validator (24-26)
apps/agent/pkg/api/validation/validator.go (1)
  • Validator (22-24)
go/pkg/sim/simulation.go (1)
  • Validator (13-13)
go/apps/api/routes/v2_apis_create_api/401_test.go (1)
go/pkg/assert/assert.go (1)
  • Equal (20-29)
go/apps/api/routes/v2_ratelimit_delete_override/handler.go (6)
go/pkg/db/handle_err_no_rows.go (1)
  • IsNotFound (8-10)
go/pkg/fault/code.go (1)
  • WithCode (37-51)
go/pkg/codes/unkey_data.go (1)
  • Data (87-128)
go/pkg/fault/wrap.go (2)
  • WithDesc (75-91)
  • Wrap (20-37)
go/pkg/codes/unkey_auth.go (1)
  • Auth (44-57)
go/pkg/codes/unkey_application.go (1)
  • App (45-59)
go/pkg/fault/code.go (1)
go/pkg/fault/wrap.go (1)
  • Wrapper (6-6)
go/apps/api/routes/v2_ratelimit_get_override/handler.go (4)
go/pkg/db/handle_err_no_rows.go (1)
  • IsNotFound (8-10)
go/pkg/codes/unkey_data.go (1)
  • Data (87-128)
go/pkg/codes/unkey_auth.go (1)
  • Auth (44-57)
go/pkg/codes/unkey_application.go (1)
  • App (45-59)
go/apps/api/routes/v2_identities_create_identity/handler.go (4)
go/pkg/fault/code.go (1)
  • WithCode (37-51)
go/pkg/codes/unkey_auth.go (1)
  • Auth (44-57)
go/pkg/codes/unkey_application.go (1)
  • App (45-59)
go/pkg/codes/unkey_data.go (1)
  • Data (87-128)
go/pkg/codes/unkey_application.go (1)
go/pkg/codes/codes.go (2)
  • SystemUnkey (29-29)
  • CategoryUnkeyApplication (62-62)
go/internal/services/keys/verify.go (5)
go/pkg/db/handle_err_no_rows.go (1)
  • IsNotFound (8-10)
go/pkg/fault/wrap.go (2)
  • Wrap (20-37)
  • WithDesc (75-91)
go/pkg/fault/code.go (1)
  • WithCode (37-51)
go/pkg/codes/unkey_auth.go (1)
  • Auth (44-57)
go/pkg/codes/unkey_data.go (1)
  • Data (87-128)
go/pkg/zen/middleware_errors.go (4)
go/pkg/fault/code.go (1)
  • GetCode (21-35)
go/pkg/codes/codes.go (1)
  • ParseURN (98-100)
go/pkg/codes/constants_gen.go (23)
  • UnkeyDataErrorsKeyNotFound (43-43)
  • UnkeyDataErrorsWorkspaceNotFound (48-48)
  • UnkeyDataErrorsApiNotFound (53-53)
  • UnkeyDataErrorsPermissionNotFound (58-58)
  • UnkeyDataErrorsRoleNotFound (63-63)
  • UnkeyDataErrorsKeyAuthNotFound (68-68)
  • UnkeyDataErrorsRatelimitNamespaceNotFound (73-73)
  • UnkeyDataErrorsRatelimitOverrideNotFound (78-78)
  • UnkeyDataErrorsIdentityNotFound (83-83)
  • UnkeyDataErrorsAuditLogNotFound (90-90)
  • UnkeyAppErrorsValidationInvalidInput (106-106)
  • UnkeyAuthErrorsAuthenticationMissing (18-18)
  • UnkeyAuthErrorsAuthenticationMalformed (20-20)
  • UnkeyAuthErrorsAuthenticationKeyNotFound (22-22)
  • UnkeyAuthErrorsAuthorizationForbidden (30-30)
  • UnkeyAuthErrorsAuthorizationInsufficientPermissions (28-28)
  • UnkeyDataErrorsIdentityDuplicate (85-85)
  • UnkeyAppErrorsProtectionProtectedResource (113-113)
  • UnkeyAuthErrorsAuthorizationKeyDisabled (32-32)
  • UnkeyAuthErrorsAuthorizationWorkspaceDisabled (34-34)
  • UnkeyAppErrorsInternalUnexpectedError (99-99)
  • UnkeyAppErrorsInternalServiceUnavailable (101-101)
  • UnkeyAppErrorsValidationAssertionFailed (108-108)
go/apps/api/openapi/gen.go (8)
  • NotFoundErrorResponse (107-110)
  • Meta (100-104)
  • BaseError (52-67)
  • BadRequestErrorResponse (46-49)
  • BadRequestErrorDetails (25-43)
  • ForbiddenErrorResponse (76-79)
  • ConflictErrorResponse (70-73)
  • PreconditionFailedErrorResponse (123-126)
go/pkg/fault/code_test.go (1)
go/pkg/fault/code.go (2)
  • WithCode (37-51)
  • GetCode (21-35)
go/apps/api/routes/v2_ratelimit_set_override/401_test.go (2)
go/apps/api/routes/v2_ratelimit_set_override/handler.go (3)
  • New (36-180)
  • Request (25-25)
  • Response (26-26)
go/pkg/testutil/http.go (1)
  • CallRoute (180-214)
go/apps/api/routes/v2_ratelimit_limit/handler.go (3)
go/pkg/db/handle_err_no_rows.go (1)
  • IsNotFound (8-10)
go/pkg/codes/unkey_data.go (1)
  • Data (87-128)
go/pkg/codes/unkey_auth.go (1)
  • Auth (44-57)
go/pkg/codes/generate.go (3)
go/pkg/codes/unkey_auth.go (1)
  • Auth (44-57)
go/pkg/codes/unkey_data.go (1)
  • Data (87-128)
go/pkg/codes/unkey_application.go (1)
  • App (45-59)
go/apps/api/routes/v2_ratelimit_set_override/400_test.go (2)
go/pkg/assert/assert.go (1)
  • Equal (20-29)
go/pkg/system_errors/errors.go (1)
  • Error (36-40)
go/pkg/fault/dst_test.go (3)
go/pkg/fault/code.go (2)
  • WithCode (37-51)
  • GetCode (21-35)
go/pkg/assert/assert.go (1)
  • True (79-88)
go/pkg/system_errors/errors.go (1)
  • Error (36-40)
go/pkg/otel/axiom.go (4)
go/pkg/version/version.go (1)
  • Version (4-4)
go/pkg/shutdown/shutdown.go (2)
  • Shutdowns (48-53)
  • Shutdown (16-16)
go/pkg/otel/logging/slog.go (1)
  • AddHandler (29-31)
go/pkg/otel/tracing/trace.go (1)
  • SetGlobalTraceProvider (36-38)
go/pkg/urn/urn.go (4)
go/pkg/assert/assert.go (3)
  • Equal (20-29)
  • NotEmpty (139-148)
  • True (79-88)
go/pkg/urn/resource.go (4)
  • ResourceTypeKey (13-13)
  • ResourceTypeAPI (14-14)
  • ResourceTypeNamespace (15-15)
  • ResourceTypeIdentity (16-16)
go/pkg/fault/wrap.go (2)
  • Wrap (20-37)
  • WithDesc (75-91)
go/pkg/assert/all.go (1)
  • All (19-26)
go/pkg/codes/unkey_auth.go (1)
go/pkg/codes/codes.go (3)
  • SystemUnkey (29-29)
  • CategoryUnkeyAuthentication (54-54)
  • CategoryUnkeyAuthorization (57-57)
go/apps/api/routes/v2_apis_create_api/handler.go (4)
go/pkg/fault/code.go (1)
  • WithCode (37-51)
go/pkg/codes/unkey_auth.go (1)
  • Auth (44-57)
go/pkg/fault/wrap.go (2)
  • WithDesc (75-91)
  • Wrap (20-37)
go/pkg/codes/unkey_application.go (1)
  • App (45-59)
go/pkg/urn/service.go (1)
go/pkg/assert/assert.go (1)
  • True (79-88)
go/pkg/urn/resource.go (4)
go/pkg/urn/service.go (8)
  • ServiceAuth (11-11)
  • ServiceRateLimit (12-12)
  • ServiceIdentity (13-13)
  • ServiceDeploy (14-14)
  • ServiceObserve (15-15)
  • ServiceAudit (16-16)
  • ServiceSecrets (17-17)
  • ServiceBilling (18-18)
go/pkg/fault/code.go (1)
  • WithCode (37-51)
go/pkg/codes/unkey_application.go (1)
  • App (45-59)
go/pkg/assert/assert.go (1)
  • True (79-88)
go/pkg/codes/unkey_data.go (1)
go/pkg/codes/codes.go (2)
  • SystemUnkey (29-29)
  • CategoryUnkeyData (51-51)
🪛 Gitleaks (8.21.2)
apps/docs/api-reference/errors-v2/unkey/data/identity_already_exists.mdx

43-45:

(curl-auth-header)


67-69:

(curl-auth-header)

apps/docs/api-reference/errors-v2/unkey/data/invalid_input.mdx

35-37:

(curl-auth-header)


55-57:

(curl-auth-header)

apps/docs/api-reference/errors-v2/unkey/application/invalid_input.mdx

35-37:

(curl-auth-header)


55-57:

(curl-auth-header)

apps/docs/api-reference/errors-v2/unkey/data/api_not_found.mdx

43-45:

(curl-auth-header)


67-69:

(curl-auth-header)

apps/docs/api-reference/errors-v2/unkey/authentication/missing.mdx

29-31:

(curl-auth-header)

apps/docs/api-reference/errors-v2/unkey/authorization/forbidden.mdx

29-31:

(curl-auth-header)

apps/docs/api-reference/errors-v2/unkey/data/audit_log_not_found.mdx

43-45:

(curl-auth-header)


67-69:

(curl-auth-header)

apps/docs/api-reference/errors-v2/unkey/data/identity_not_found.mdx

35-37:

(curl-auth-header)


55-57:

(curl-auth-header)

🪛 LanguageTool
apps/docs/api-reference/errors-v2/unkey/data/key_auth_not_found.mdx

[grammar] ~28-~28: The plural noun “Typos” cannot be used with the article “a”. Did you mean “a non-existent record typo” or “non-existent record Typos”?
Context: ...g to update authentication settings for a non-existent record - Typos in identifiers Here's an example of a ...

(A_NNS)

apps/docs/api-reference/errors-v2/unkey/data/invalid_input.mdx

[style] ~60-~60: Consider using a different verb for a more formal wording.
Context: ...d (if available) for guidance on how to correct the issue 4. Modify your request to com...

(FIX_RESOLVE)


[style] ~81-~81: This phrase is redundant. Consider using “outside”.
Context: ... Range violations: Providing values outside of allowed ranges (too small, too large) -...

(OUTSIDE_OF)

apps/docs/api-reference/errors-v2/unkey/authorization/workspace_disabled.mdx

[uncategorized] ~48-~48: You might be missing the article “the” here.
Context: ...key.com/settings/billing) 2. Contact workspace administrator: If you're not the work...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

apps/docs/api-reference/errors-v2/unkey/application/invalid_input.mdx

[style] ~60-~60: Consider using a different verb for a more formal wording.
Context: ...d (if available) for guidance on how to correct the issue 4. Modify your request to com...

(FIX_RESOLVE)


[style] ~81-~81: This phrase is redundant. Consider using “outside”.
Context: ... Range violations: Providing values outside of allowed ranges (too small, too large) -...

(OUTSIDE_OF)

apps/docs/api-reference/errors-v2/unkey/data/permission_not_found.mdx

[grammar] ~23-~23: ‘a’ may be redundant when used with the uncountable noun ‘permission’.
Context: ...ou're trying to perform an operation on a permission that doesn't exist in the Unkey system....

(A_UNCOUNTABLE_NOUN)


[grammar] ~27-~27: ‘a’ may be redundant when used with the uncountable noun ‘permission’.
Context: ...ect permission ID or name - Referencing a permission that has been deleted - Trying to assig...

(A_UNCOUNTABLE_NOUN)


[grammar] ~28-~28: ‘a’ may be redundant when used with the uncountable noun ‘permission’.
Context: ...hat has been deleted - Trying to assign a permission that doesn't exist in the current works...

(A_UNCOUNTABLE_NOUN)

apps/docs/api-reference/errors-v2/unkey/authorization/forbidden.mdx

[style] ~45-~45: You have already used ‘trying to’ in nearby sentences. Consider using one of the replacements to let your writing stand out.
Context: ... permission issue. The operation you're trying to perform may be: 1. **Not supported by ...

(REP_TRY)


[style] ~65-~65: You have already used ‘Trying to’ in nearby sentences. Consider using one of the replacements to let your writing stand out.
Context: ...rrent plan - Resource state issues: Trying to modify resources that are in a state th...

(REP_TRY)


[style] ~67-~67: You have already used ‘trying to’ in nearby sentences. Consider using one of the replacements to let your writing stand out.
Context: ...ing security boundaries**: Deliberately trying to access protected resources - **Outdated...

(REP_TRY)

apps/docs/api-reference/errors-v2/overview.mdx

[uncategorized] ~46-~46: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ... operations and resources - limits: Rate limiting or quota-related errors ## Error Respo...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[duplication] ~70-~70: Possible typo: you repeated a word.
Context: ...- title: Short summary of the error type - type: URL to detailed documentation about ...

(ENGLISH_WORD_REPEAT_RULE)

apps/docs/api-reference/errors-v2/unkey/application/unexpected_error.mdx

[grammar] ~80-~80: This phrase is duplicated. You should probably use “this error” only once.
Context: ...equestId` when contacting support about this error - This error may indicate a bug in Unkey's systems t...

(PHRASE_REPETITION)

apps/docs/api-reference/errors/code/BAD_REQUEST.mdx

[formatting] ~8-~8: Insert a comma after ‘cases’: “In most cases,”?
Context: ...have permission to perform this action. In most cases this means the root key you are using, ...

(IN_MOST_CASES_COMMA)


[uncategorized] ~8-~8: Possible missing comma found.
Context: ...tion. In most cases this means the root key you are using, is lacking permissions. ...

(AI_HYDRA_LEO_MISSING_COMMA)

apps/docs/api-reference/errors-v2/unkey/data/audit_log_not_found.mdx

[uncategorized] ~49-~49: Possible missing comma found.
Context: ... that audit logs might have a retention period after which they're automatically delet...

(AI_HYDRA_LEO_MISSING_COMMA)

apps/engineering/content/rfcs/0011-unkey-resource-names.mdx

[misspelling] ~30-~30: Use “an” instead of ‘a’ if the following word starts with a vowel sound, e.g. ‘an article’, ‘an hour’.
Context: ...nkey- Fixed prefix indicating this is a Unkey resource identifier *service` -...

(EN_A_VS_AN)


[uncategorized] ~64-~64: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...ation and authorization * ratelimit - Rate limiting service * identity - Identity managem...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[uncategorized] ~242-~242: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...Resource already exists (conflict) ### Rate Limiting Service (ratelimit) - `err:ratelimit:...

(EN_COMPOUND_ADJECTIVE_INTERNAL)

apps/docs/api-reference/errors-v2/unkey/application/protected_resource.mdx

[uncategorized] ~23-~23: Possible missing article found.
Context: ... Unkey system. Protected resources have special status that prevents them from being ch...

(AI_HYDRA_LEO_MISSING_A)


[style] ~45-~45: You have already used ‘trying to’ in nearby sentences. Consider using one of the replacements to let your writing stand out.
Context: ...to work with or around them rather than trying to change them: 1. **Work with the protec...

(REP_TRY)

🔇 Additional comments (223)
go/pkg/codes/doc.go (1)

1-16: Well-structured package documentation.

The documentation clearly explains the purpose and design of the new error code system. The URN-like format (err:system:category:specific) provides a consistent and hierarchical approach to error handling, which will benefit both developers and users. This standardization will improve error reporting consistency across Unkey services.

go/pkg/codes/nil.go (1)

1-10: Well-defined error code for nil cases

The introduction of the Nil error code provides a clear default value for cases where no specific error code is applicable. This is a good practice for maintaining consistency in error handling across the codebase. The documentation clearly explains its purpose and usage.

apps/docs/package.json (1)

11-11: Dependency Version Update for Mintlify

The mintlify package in the devDependencies has been updated to ^4.0.482. Please verify that this new version works seamlessly with your mintlify dev command (line 6) and the overall documentation tooling. It may be beneficial to review the release notes for any potential breaking changes or new requirements introduced in this version.

go/internal/services/ratelimit/service.go (2)

232-242: Code refactoring improves clarity and readability

The refactoring of the current window counter retrieval logic is well-executed. Computing the currentKey directly within the conditional block and handling the counter retrieval and error logging immediately afterward creates a more straightforward flow compared to the previous implementation (which used a slice to store keys). The use of max() to update the counter value is also appropriate, ensuring we always have the highest known value.


246-256: Similar improvement in previous window counter handling

This change follows the same pattern as the current window handling - computing the key where it's needed and immediately handling retrieval and errors. The consistent approach between both window types makes the code easier to understand and maintain. The error logging is appropriately detailed, including the key that failed.

go/go.mod (6)

7-7: New Dependency: Axiom-Go Added
The addition of github.com/axiomhq/axiom-go v0.23.0 supports the new API key management feature. Please ensure that its functionality, licensing, and security aspects have been verified in the context of the new feature.


62-62: Replacement Dependency: HTTPSnoop
The inclusion of github.com/felixge/httpsnoop v1.0.4 indicates a replacement for the previously used fsnotify package. Confirm that this change fully meets the intended behavior and does not affect any other components that may have depended on the removed package.


71-71: Dependency Version Upgrade: Mapstructure
Upgrading github.com/go-viper/mapstructure/v2 to version v2.2.1 is a minor version bump. Verify that there are no breaking changes or subtle differences in behavior that could impact the parsing logic elsewhere in the system.


74-74: New Indirect Dependency: Go-Querystring
The addition of github.com/google/go-querystring v1.1.0 as an indirect dependency is noted. Please confirm that its inclusion is necessary for the API key pagination or related functionality, and that it does not unnecessarily bloat the dependency tree.


119-119: Dependency Update: spf13/pflag
Updating github.com/spf13/pflag to v1.0.6 is a straightforward improvement. Ensure that the minor version update does not alter the flag parsing behaviors critical to your application's command-line interface.


130-130: Telemetry Dependency Addition: otelhttp
The addition of go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 can enhance HTTP request tracing. Please verify that this dependency is integrated with your telemetry system and aligns with the monitoring needs of the new API key management feature.

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

27-27:

❓ Verification inconclusive

Consider implications of changing logging level from Info to Debug.

The logging level for request information has been changed from InfoContext to DebugContext. While this change reduces log verbosity (potentially improving performance in high-traffic environments), it may impact observability in production where debug logs are often disabled by default.

Verify that this change was intentional and consider whether:

  1. The function documentation (lines 11-19) should be updated to mention the debug level
  2. Production environments have debug logging enabled, or if this change might hide useful request information

🏁 Script executed:

#!/bin/bash
# Look for logging configuration in the codebase to understand if debug logs are enabled in production
echo "Searching for logging configuration..."
rg -A 5 "SetLevel|LogLevel|log.*level" --type go

Length of output: 6438


Reevaluate Logging Level Change from Info to Debug

  • The log in go/pkg/zen/middleware_logger.go at line 27 now uses DebugContext instead of InfoContext. While this change may reduce log verbosity and potentially improve performance under high load, it risks omitting important request details in production where debug logs are often disabled.
  • Please verify that the change was intentional by ensuring that production environments are configured to enable debug-level logs.
  • Additionally, review the function documentation (lines 11–19) to see if it should be updated to reflect the use of the debug level for request logging.
go/pkg/otel/axiom.go (3)

18-29: LGTM: Well-documented configuration struct.

The AxiomConfig struct has clear documentation explaining each field's purpose and how they're used in Axiom telemetry.


62-74: LGTM: Good error handling and shutdown pattern.

The function properly initializes the Axiom logger, handles errors, and registers shutdown handlers correctly.


75-84: LGTM: Comprehensive trace provider setup.

The function correctly sets up the trace provider with the application and version information, registers it for shutdown, and sets it as the global provider.

go/pkg/fault/dst_test.go (6)

17-18: Imports align with new test assertions and codes usage.
No issues found with these added imports. They correctly pull in require for test assertions and codes for error code handling.


91-92: Refactor from tag-based to URN-based error codes looks good.
The updated function returns a codes.URN in uppercase joined by underscores. This approach is straightforward for generating random codes during testing.

Also applies to: 97-97


103-103: Switching to a slice of codes.URN for error components.
Replacing tags with code is consistent with the new URN-based approach. The slice initialization and population are correct.

Also applies to: 109-111


146-146: Revised function now returns code URNs and updates wrappers accordingly.
The transition to codes.URN is properly reflected in the return signature and the assignment to usedTags. Using random selection for code insertion aligns with the existing random-based test design.

Also applies to: 148-148, 158-161


201-204: Validation of final code matches expected code.
This ensures the last generated code in the chain is correctly retrieved from fault.GetCode. The use of require.True and the subsequent comparison are properly implemented.


224-225: Reproducibility checks for generated error codes.
Comparing code1 and code2 with reflect.DeepEqual is appropriate to ensure that deterministic, seed-based generation remains reproducible across runs.

Also applies to: 231-231

apps/engineering/content/rfcs/0011-unkey-resource-names.mdx (16)

1-7: Front Matter and Metadata:
The front matter is properly structured with the title, description, date, and authors. All metadata appears consistent with RFC documentation standards.


9-17: Background Section Clarity:
The "Background" section clearly outlines the context and motivation behind implementing URNs and structured error codes. The rationale is concisely provided, setting a solid foundation for the subsequent sections.


19-27: URN Structure Definition:
The "Resource Identification: URN Structure" section introduces a clear URN format with an accompanying code snippet. The format is well explained, though you might consider briefly mentioning how each parameter will be validated or used in practice.


37-42: Customer Cloud Deployment Pattern:
The alternative URN pattern for customer cloud deployments is clearly delineated and well-presented. This extension complements the base URN pattern effectively.


72-87: Error Code Format Specification:
The error code namespace and format definition are well articulated, with a clear code block and a detailed breakdown of components. This clarity will contribute to a consistent error handling strategy across services.


88-116: Error Categories Outline:
The structured definition of error categories is comprehensive, covering state, validation, permissions, limits, and configuration issues. This standardization should greatly aid in consistent error reporting.


117-129: Error Code Examples:
The examples for error codes are clear and illustrative. They provide developers with concrete cases that match the predefined format, reinforcing correct usage.


130-139: API Versioning Strategy:
The API versioning strategy is well defined, with a clear differentiation between the current V1 API and the new V2 API that adopts the URN and structured error code systems. This separation offers a clean migration path for existing clients.


141-149: Implementation Focus for V2 API:
The section outlining the V2 API implementation focus is clear and actionable. It succinctly conveys the key enhancements (e.g., URN inclusion, structured error codes, updated documentation) that developers need to implement.


150-157: Documentation and Tooling:
The detailed documentation and tooling strategy—covering migration guides, automatic URN generation, comprehensive documentation, and supportive developer tools—is comprehensive and aligns well with the overall objectives.


158-170: API Response Example - Resource:
The JSON example demonstrating a resource response with an embedded URN is clear and properly formatted. This practical example will be very helpful for developers integrating with the API.


171-184: API Error Response Example:
The error response example is well-structured and clearly shows how the new error codes and messaging are incorporated into the API output. It reinforces the document’s objective of consistent error handling.


186-203: Benefits Section:
The benefits section effectively highlights the technical and developer experience advantages of standardizing URNs and error codes. It makes a strong case for the proposed changes.


204-223: Migration Considerations:
The migration section is thoughtfully laid out, addressing database impact, API changes, and documentation updates. It reassures that schema changes are minimal while providing clear guidance on the migration process.


224-229: Conclusion:
The conclusion succinctly encapsulates the proposed benefits and long-term scalability improvements, reinforcing the document's overall message without unnecessary detail.


230-241: Appendix A - Common Error Codes (Authentication):
The list of common error codes for the Authentication Service is detailed and well-organized. Ensure that the language (and any compound adjectives) follows a consistent style throughout the document.

apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/_components/components/table/components/hidden-value.tsx (3)

1-4: LGTM - Appropriate imports for the component

The imports look correct for the functionality this component provides. The toast for notifications, cn for class name handling, and CircleLock icon for the visual representation of hidden values.


5-13: Component interface is well-defined

The component signature is clear with properly typed props and a logical default value for the title.


17-28: Robust clipboard handling with proper error feedback

The click handler properly prevents event propagation and includes error handling with appropriate user feedback through toast notifications.

apps/dashboard/lib/trpc/routers/logs/query-logs/utils.ts (1)

41-41: Simplification of cursor handling looks good.

The cursor handling has been simplified by removing the cursorRequestId and directly assigning params.cursor to cursorTime. This is consistent with changes in other files that are removing request ID-based pagination.

internal/clickhouse/src/keys/keys.ts (2)

209-211: SQL query comments and ORDER BY clause update is good.

The changes to the ORDER BY clause and the comments explaining the change are clear and well-documented. The simplification to use only time-based pagination improves the code's maintainability.


217-230: Simplification of cursor conditions is appropriate.

The cursor conditions have been updated to use only time-based pagination, removing references to cursorRequestId. This simplification is consistent with the schema changes and aligns with the other changes in the codebase.

go/pkg/codes/unkey_auth.go (1)

1-13: Good structuring of authentication error codes.

This file cleanly delineates errors for missing, malformed, and not-found credentials, improving both readability and maintainability.

go/pkg/urn/urn.go (2)

21-26: Well-structured URN string representation.

The concatenation of each component into a standard format is correct and aligns with URN conventions. No issues noted here.


86-138: Comprehensive parsing with meaningful error messages.

Using assert checks for structure and wrapping errors with fault.Wrap ensures clarity. The inline documentation is thorough, making debugging easier if parsing fails.

go/pkg/codes/unkey_data.go (2)

5-45: Consistent approach for resource-related “NotFound” errors.

Each struct is concise and aligns with the established pattern for typed error handling, enhancing code clarity.


68-129: Centralized data error aggregation is well-structured.

Bundling all resource-specific data errors into UnkeyDataErrors fosters consistent error referencing across the application.

go/pkg/codes/unkey_application.go (1)

1-60: Well-structured error handling implementation.

The new error code system provides a clear hierarchy for application-level errors in the Unkey system. The organization into internal, validation, and protection categories with well-documented error types will make error handling more consistent throughout the application.

go/apps/api/routes/v2_identities_create_identity/409_test.go (1)

45-45: Updated error type URL matches new error handling structure.

The updated error URL is more specific and aligns with the new structured error handling system, providing clearer error documentation references for duplicate identity creation.

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

47-47: Improved error type URLs for namespace not found cases.

The updated error URLs are more descriptive and provide specific documentation references for the different not found scenarios, aligning with the new error handling structure.

Also applies to: 63-63

go/apps/api/config.go (1)

45-45:

❓ Verification inconclusive

OtelEnabled replaced with OtelSink for more flexible configuration.

The change from a boolean flag to a string sink provides more flexibility in OpenTelemetry configuration. However, verify that all code previously using OtelEnabled has been updated to work with OtelSink.


🏁 Script executed:

#!/bin/bash
# Search for any remaining references to OtelEnabled that might need updating
rg -i "OtelEnabled" --type go

Length of output: 29


Action Required: Confirm Complete Update of OtelEnabled References

The configuration change from a boolean flag (OtelEnabled) to a string sink (OtelSink) has been implemented in go/apps/api/config.go (line 45). Although our search using:

rg -i "OtelEnabled" --type go

did not return any references, the absence of output might be due to tool limitations. Please manually verify that no residual usages of OtelEnabled remain elsewhere in the codebase.

  • Location to verify: go/apps/api/config.go (line 45) now correctly defines OtelSink
  • Action: Ensure that all parts of the code which previously relied on OtelEnabled now properly handle the OtelSink string configuration.
go/apps/api/cancel_test.go (1)

43-43: Configuration change to OpenTelemetry setup

The change from OtelEnabled bool to OtelSink string reflects a more flexible configuration approach for OpenTelemetry. Using a string allows specifying different sink targets rather than a simple boolean toggle.

go/pkg/fault/wrap.go (1)

28-28: Consistent renaming from tag to code

This change is part of a broader shift from using tags to structured error codes throughout the error handling framework, which improves consistency.

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

92-92: More specific error type URL

The updated error URL provides more detailed information about the specific error type (ratelimit_namespace_not_found) rather than a generic "not_found" error. This makes debugging and error handling more precise.

However, line 55 still uses the old URL format (https://unkey.com/docs/errors/not_found). Consider updating this for consistency if appropriate.

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

39-49:

✅ Verification successful

New test case for malformed authorization header

Adding a test for malformed authorization headers improves test coverage for error cases.

However, there's a potential inconsistency between the expected response type and status code:

  • Line 46 expects a BadRequestErrorResponse (typically 400)
  • Line 47 checks for http.StatusUnauthorized (401)

These should typically align - either use a 400 status with BadRequestErrorResponse or a 401 status with UnauthorizedErrorResponse.


🏁 Script executed:

#!/bin/bash
# Check how the handler processes malformed authorization headers
rg "malformed.*authorization|authorization.*malformed" -A 5 -B 5

Length of output: 5059


Revised Test Case Review Comment

The new test for the malformed authorization header now correctly uses openapi.UnauthorizedErrorResponse in line with the http.StatusUnauthorized (401) expectation. This resolves the inconsistency noted earlier.

  • File: go/apps/api/routes/v2_identities_create_identity/401_test.go
  • Change: Updated the response type from openapi.BadRequestErrorResponse to openapi.UnauthorizedErrorResponse to align with the 401 status code.
  • Impact: Consistent error handling for malformed authorization headers.
apps/dashboard/app/(app)/ratelimits/[namespaceId]/_overview/components/table/query-logs.schema.ts (1)

33-33: Schema change for cursor pagination looks good.

The simplification of the cursor property from an object to a nullable number aligns with the PR objective of implementing cursor pagination using keyId. This change is consistent with similar modifications across other schema files in the codebase.

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

1-39: OpenAPI reference route implementation looks well-structured.

The implementation creates a clean API reference page using the Scalar library to render the OpenAPI specification. The code sets appropriate headers and follows good practices for route handling.

apps/dashboard/app/(app)/logs/components/table/query-logs.schema.ts (1)

59-59: Schema change for cursor pagination looks good.

The simplification of the cursor property from an object to a nullable number aligns with the PR objective of implementing cursor pagination using keyId. This change is consistent with similar modifications across other schema files in the codebase.

go/pkg/fault/wrapped_test.go (2)

11-11: Good addition of imports for new error code handling.

Adding the import for the codes package is necessary for the transition from tag-based to code-based error handling.


173-173:

❓ Verification inconclusive

Improved error handling with structured codes.

Replacing WithTag("ERROR_TAG") with WithCode(codes.Auth.Authentication.KeyNotFound.URN()) enhances error handling by using structured, specific error codes instead of generic tags. This aligns with the broader effort to standardize error handling across the codebase.


🏁 Script executed:

#!/bin/bash
# Check for other instances of WithTag that might need to be updated
echo "Instances of WithTag still in the codebase:"
rg "WithTag\(" go/pkg/fault --type go

Length of output: 313


Structured error handling improvement – please verify consistency across the codebase

The change in go/pkg/fault/wrapped_test.go:173 correctly replaces a generic tag (WithTag("ERROR_TAG")) with a structured error code (WithCode(codes.Auth.Authentication.KeyNotFound.URN())), which is a clear improvement. However, our search shows that there are remaining instances of WithTag in other parts of the repository (notably in go/pkg/fault/wrap.go and go/pkg/fault/doc.go). These appear in commented code, so please verify whether they should be updated for consistency or are safe to leave as-is.

  • Action items:
    • Confirm that updating the test file aligns with the overall standardized error handling goals.
    • Review the commented instances in go/pkg/fault/wrap.go and go/pkg/fault/doc.go to decide if they require similar treatment.
apps/dashboard/app/(app)/ratelimits/[namespaceId]/logs/components/table/query-logs.schema.ts (1)

40-40: Cursor type has been simplified to a number.

The cursor field has been simplified from a complex object with requestId and time properties to a single nullable number field. This change aligns with the PR objective of implementing cursor-based pagination that uses a single identifier value rather than multiple fields.

While this is a good simplification, ensure that all components consuming this schema are updated to handle the new cursor format correctly.

apps/dashboard/lib/trpc/routers/ratelimit/query-overview-logs/utils.ts (1)

39-39: Simplified cursor handling in transformFilters function.

The cursor handling has been simplified to directly use params.cursor instead of extracting a time property from a cursor object. The cursorRequestId field has been removed completely, which aligns with the cursor simplification changes in other files.

This change is consistent with the schema updates and supports the PR's objective of implementing cursor pagination using a single value.

apps/dashboard/app/(app)/apis/[apiId]/_overview/components/table/query-logs.schema.ts (1)

14-14: Simplified cursor to a nullable number.

Similar to the other schema files, the cursor field has been changed from a complex object with requestId and time properties to a single nullable number. This ensures consistency across the application.

This change matches the pattern applied in other files and aligns with the PR goal of simplifying cursor-based pagination.

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

42-57: Added test for malformed authorization header.

A new test case has been added to verify that the API properly handles malformed authorization headers by returning a 401 Unauthorized status. This improves the robustness of the authorization handling logic.

This is a good addition to the test suite as it covers an important edge case. The test verifies both the status code and that the response body is not nil, ensuring proper error handling.

go/apps/api/routes/v2_ratelimit_set_override/401_test.go (2)

41-41: Improved error reporting for more actionable debug information

The updated error message now includes the raw response body, which makes debugging test failures much easier by showing the actual error response.


45-62: Good addition of test case for malformed authorization header

This test case addresses an important edge case by verifying that malformed authorization headers (without the "Bearer " prefix) are properly rejected with a 401 Unauthorized status. The test follows the established pattern and includes a detailed error message to aid in debugging.

go/pkg/zen/auth.go (4)

6-6: Added dependency on codes package for structured error handling

The import of the codes package aligns with the shift from generic error tags to more specific error codes.


27-27: Enhanced error specificity for missing authentication

The error handling has been improved by using a more specific error code (codes.Auth.Authentication.Missing.URN()) instead of a generic tag. This provides clearer error identification and better documentation references.


32-34: Improved error details for malformed authorization header

The error handling now uses a specific error code for malformed authentication headers, which matches the new test case added in the 401_test.go file. This provides more precise error identification while maintaining the helpful description.


39-39: Consistent error handling for empty token

The error handling for empty tokens now uses the same structured approach with specific error codes, maintaining consistency with the other authentication error cases.

apps/dashboard/lib/trpc/routers/ratelimit/query-logs/utils.ts (1)

37-37: Simplified cursor handling

The change simplifies cursor handling by directly passing the entire cursor object to cursorTime instead of extracting just the time property. This makes the code more straightforward and allows for potential enhancements to cursor structure without modifying this function.

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

96-96: Updated error documentation URL to new format

The error type URL has been updated to the new structured format, pointing to a more specific error documentation page. This is consistent with the move to more granular error codes throughout the codebase.


128-139:

✅ Verification successful

Missing test case for malformed authorization header

While the test for missing authorization header is present, there's no test for malformed authorization headers (like "malformed_header" instead of "Bearer token"). This is inconsistent with the test additions in v2_ratelimit_set_override/401_test.go.

To verify the inconsistency, let's check if other similar test files include malformed header tests:


🏁 Script executed:

#!/bin/bash
# Search for test files that test malformed authorization headers

echo "Searching for test files with malformed authorization header tests..."
rg -A 5 "malformed authorization header" --type go go/apps/api/routes/

Length of output: 2828


Test organization confirmed: Malformed header case is already tested in the appropriate file

The malformed authorization header scenario for the identities create identity route is covered in the corresponding go/apps/api/routes/v2_identities_create_identity/401_test.go file—consistent with the organization seen in other endpoints (e.g., v2_ratelimit_set_override/401_test.go). No additional test is needed in 400_test.go.

go/pkg/fault/wrap_test.go (5)

8-8: Adding codes package enhances error handling

The addition of the codes package import is part of transitioning from custom tags to standardized error codes, which improves error handling consistency across the codebase.


32-32: Field type update for improved error handling

Updating the test struct field from expectedTag Tag to expectedCode codes.URN aligns with the codebase's shift towards structured error codes. This change enhances error specificity and documentation through URN-based error codes.

Also applies to: 41-42


48-53: Updated test case to use structured error codes

The test case has been correctly updated to use WithCode(codes.URN("TEST_TAG")) instead of the previous tag-based approach, maintaining the same test logic while adopting the new error code system.


70-70: Updated assertion for error code validation

The assertion has been properly modified to check wrapped.code instead of wrapped.tag, matching the new error structure.


82-83: Consistent usage of new error code approach

The update to use WithCode(codes.URN("TEST_TAG")) in this test section maintains consistency with the new error handling approach throughout the test file.

go/apps/api/run.go (1)

44-73: Enhanced telemetry configuration with multiple sink support

The switch statement elegantly replaces the previous boolean flag with a more flexible approach that supports multiple telemetry destinations (Grafana and Axiom). This change:

  1. Improves configurability by allowing different telemetry providers
  2. Maintains proper error handling for each initialization
  3. Uses appropriate configuration structures for each provider

The implementation correctly handles the initialization of each telemetry sink with its specific configuration requirements.

apps/dashboard/lib/trpc/routers/api/keys/query-overview-logs/utils.ts (1)

54-54:

✅ Verification successful

Simplified cursor handling for pagination

The change simplifies cursor handling by directly using the entire cursor object rather than extracting specific properties. This approach is more maintainable, but warrants verification to ensure all downstream consumers properly handle the full cursor object.


🏁 Script executed:

#!/bin/bash
# Check for other usages of cursorTime to verify compatibility with this change
rg -A 5 "cursorTime" --type=ts

Length of output: 9712


Cursor Handling for Pagination Verified

The updated code now directly assigns cursorTime: params.cursor ?? null and was found to be used consistently throughout the codebase. Downstream consumers (across logs, keys, and ratelimit query endpoints) already expect this format—as confirmed by the grep results and passing tests using numeric values. Please continue to ensure that any future changes remain aligned with the Zod schema (expecting a number) to maintain compatibility.

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

102-102: Updated error type for more specific error classification

The change from a generic bad request error type to a more specific invalid input error type (unkey/data/invalid_input) improves error specificity and follows better API design principles by providing more precise error categorization.


141-141: Correct HTTP status code for authorization errors

Changing the expected status code from 400 (Bad Request) to 401 (Unauthorized) for malformed authorization headers is semantically correct according to HTTP standards. This improves API consistency and client error handling.

internal/clickhouse/src/logs.ts (1)

145-162:

❓ Verification inconclusive

SQL query simplified to use only cursorTime for pagination

The query has been revised to simplify cursor-based pagination, removing the dependency on cursorRequestId as noted in the schema changes. This aligns with the PR objective of implementing a more reliable cursor pagination mechanism.

The updated query should result in more consistent pagination behavior but ensure that it doesn't affect the completeness of log results when multiple entries share the same timestamp.


🏁 Script executed:

#!/bin/bash
# Check if there are any references to cursorRequestId in the code that might be affected
rg -A 3 "cursorRequestId" --type=typescript

Length of output: 78


Below is a revised review comment. Please run the following shell script to search for any lingering cursorRequestId references in all TypeScript (*.ts) files:

#!/bin/bash
# Searching for all occurrences of "cursorRequestId" in TypeScript source files:
rg "cursorRequestId" -g "*.ts"

If this search returns no results, it confirms that the removal is complete and the pagination now relies solely on cursorTime. This revision should result in more consistent cursor-based pagination without affecting log completeness when multiple entries share the same timestamp.

SQL Query Update – Simplified Cursor Pagination

  • The SQL query in internal/clickhouse/src/logs.ts now uses only cursorTime for pagination.
  • The dependency on cursorRequestId has been removed per the revised schema.
  • Verify that there are no unintended references to cursorRequestId by running the provided script.
go/pkg/fault/wrapped.go (3)

7-8: Added import for standardized error codes

Good addition of the codes package for structured error management.


27-27: Improved error categorization with standardized codes

Replacing the tag field with code codes.URN enhances error management by using standardized URNs instead of simple tags. This is a better approach for structured error handling and documentation.


56-57: Updated initialization for new error code field

The initialization properly sets the code field to an empty string, maintaining the same behavior as before but with the new field structure.

apps/docs/api-reference/errors-v2/unkey/authentication/malformed.mdx (1)

1-87: Excellent comprehensive error documentation

This is a well-structured and thorough documentation for the authentication error. It includes:

  • Clear error description and example response
  • Explanation of what causes the error
  • Common causes and how to fix them
  • Code examples for correct and incorrect usage
  • Common pitfalls to avoid
  • Related errors for further context

The documentation will significantly improve developer experience when troubleshooting authentication issues.

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

45-66: Added test for malformed authorization header

Good addition of a test case for malformed authorization headers. This test ensures the API correctly responds with a 401 status code and the appropriate error information when receiving improperly formatted authorization headers.

The test is thorough in validating error details, including the correct documentation URL, error title, and presence of a request ID. This helps maintain security and usability of the API.

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

37-37: Improved assertion message for better debugging

The enhanced assertion message now includes the request payload and raw response body, which will greatly help with debugging test failures by providing more context.

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

173-173: Updated error type URL to match new error structure

The error type URL has been updated from a generic "bad_request" to the more specific "unkey/data/invalid_input" path, which aligns with the new error handling system documented in the API reference.

apps/docs/api-reference/errors-v2/unkey/data/invalid_input.mdx (1)

1-89: Well-structured error documentation

This new documentation page clearly explains the "invalid_input" error, providing a comprehensive guide with examples, causes, solutions, and common mistakes. The documentation will help API users understand and resolve validation issues effectively.

🧰 Tools
🪛 LanguageTool

[style] ~60-~60: Consider using a different verb for a more formal wording.
Context: ...d (if available) for guidance on how to correct the issue 4. Modify your request to com...

(FIX_RESOLVE)


[style] ~81-~81: This phrase is redundant. Consider using “outside”.
Context: ... Range violations: Providing values outside of allowed ranges (too small, too large) -...

(OUTSIDE_OF)

🪛 Gitleaks (8.21.2)

35-37:

(curl-auth-header)


55-57:

(curl-auth-header)

go/pkg/fault/code.go (2)

1-52: Clean implementation of error code handling

The new code module provides a structured approach to error handling with associated codes, which is a significant improvement over tag-based error handling. The implementation follows Go best practices by:

  1. Properly handling nil errors
  2. Traversing the error chain using standard errors.Unwrap
  3. Providing clear documentation with examples

The WithCode function is particularly useful as it allows for clean error creation with appropriate codes.


27-30:

❓ Verification inconclusive

Consider adding exported type definition for wrapped errors

The function relies on an unexported wrapped type that isn't defined in the visible code. This type should be defined in this file or a related one to maintain clarity and ensure the code compiles.


🏁 Script executed:

#!/bin/bash
# Check if the wrapped type is defined elsewhere in the package
fd -t f -e go . go/pkg/fault | xargs grep -l "type wrapped"

Length of output: 85


Attention: Verify Design Intent for Wrapped Error Type Export

The wrapped type is indeed defined in the repository at go/pkg/fault/wrapped.go, so it isn’t missing. However, since the error-handling code uses a type assertion on the unexported wrapped (i.e. err.(*wrapped)), please confirm whether this internal-only visibility is intentional. If the design requires users to inspect or compare errors externally, you may want to export the type (for example, by renaming it to Wrapped). Otherwise, if it’s meant to remain private, consider updating the review comment for clarity.

  • Location Checked: go/pkg/fault/wrapped.go
  • Suggestion: Evaluate if the wrapped type should be exported (e.g., renamed to Wrapped) for external usage or kept unexported for internal error handling.
go/apps/api/routes/register.go (1)

109-114: New route registered for /reference endpoint.

The new route is registered with a subset of middlewares (withTracing, withMetrics, withLogging, withErrorHandling) but not using the full defaultMiddlewares array that includes validation. This is different from other routes in the file.

Is omitting the validation middleware intentional? If validation is not needed for this endpoint, consider adding a comment explaining why to maintain consistency with the middleware pattern used for other routes.

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

104-104: Updated error type URL to be more specific.

Good improvement! The error URL is now more specific (invalid_input instead of the generic bad_request), which provides better guidance to API consumers.

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

61-61: Updated error type URLs to be more specific.

Great improvement! Error URLs have been updated from generic "not_found" references to specific error types:

  • ratelimit_override_not_found
  • ratelimit_namespace_not_found

This makes error handling more precise and improves the developer experience by pointing to specific documentation.

Also applies to: 76-76, 91-91

apps/docs/api-reference/errors-v2/unkey/authentication/key_not_found.mdx (1)

1-73: Well-structured documentation for key_not_found error.

This is an excellent documentation page for the key not found error. It includes:

  • A clear example of the error response
  • Detailed explanation of what causes this error
  • Common scenarios that trigger it
  • Step-by-step instructions for fixing the issue
  • Common mistakes to watch out for
  • Related errors for cross-reference

The documentation will significantly improve the developer experience when encountering this error.

go/internal/services/keys/verify.go (7)

8-8: Adding codes package for standardized error handling.

Good addition of the codes package which enables more structured error handling throughout the application.


29-35: Improved error handling with standardized errors.

Excellent refactoring from directly checking sql.ErrNoRows to using the abstracted db.IsNotFound(err) function. This change improves code maintainability by:

  1. Centralizing the "not found" logic in one place
  2. Adding specific error codes for better error identification
  3. Providing clearer error messages for both internal logging and user feedback

58-59: Standardized error code for deleted key.

Good replacement of generic error with a specific code for deleted keys. This makes error tracking and debugging easier.


66-67: Improved error code and description for disabled keys.

Appropriate use of KeyDisabled error code with a clearer error message. This provides better context for debugging and improves user experience.


80-86: Enhanced workspace not found error handling.

Good use of structured error handling for the workspace not found case, using the appropriate error code and descriptive messages.


92-93: Added service unavailable error code.

Proper addition of the ServiceUnavailable error code for workspace loading failures, which helps distinguish between different types of failures.


100-101: Standardized error code for disabled workspace.

Consistent application of the error code pattern for workspace disabled errors, which aligns with the overall error handling approach.

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

5-5: Added fmt import for error formatting.

Good addition of the fmt package for error message formatting in the validator function.


98-111: Enhanced OpenTelemetry configuration with validation.

Great improvement to the OpenTelemetry configuration by:

  1. Changing from a boolean to string flag with specific options (grafana/axiom)
  2. Adding validation to ensure only valid values are accepted
  3. Providing clearer usage documentation

This change allows for more flexibility in telemetry configuration while maintaining strict validation.


115-115: Updated usage documentation for OTel sampling rate.

Clear improvement to the documentation to reflect that the sampling rate is only used when the --otel flag is provided.


148-148: Updated config struct field to match new flag type.

Correctly updated the config field from OtelEnabled to OtelSink to match the new string-based approach.

go/pkg/assert/assert.go (2)

7-7: Added codes package for standardized error codes.

Good addition of the codes package for consistent error code handling throughout assertion functions.


26-26: Standardized error handling across all assertion functions.

Excellent refactoring to replace custom error tags with standardized error codes across all assertion functions. This change:

  1. Improves consistency in error handling
  2. Makes errors more identifiable throughout the application
  3. Allows for better error tracking and categorization
  4. Integrates with the broader error handling strategy

The consistent application of codes.App.Validation.AssertionFailed.URN() across all assertion functions will make debugging and error handling more predictable.

Also applies to: 46-46, 65-65, 85-85, 105-105, 125-125, 145-145, 165-165, 191-191, 215-215, 240-240, 264-264, 285-285

apps/docs/api-reference/errors-v2/unkey/authentication/missing.mdx (1)

1-82: Well-structured documentation for authentication error.

Excellent documentation for the "missing authentication" error. The document is well-organized with:

  1. Clear title and description
  2. JSON example showing the exact error format
  3. Detailed explanation of what causes the error
  4. Step-by-step instructions for fixing the issue
  5. Example of a correctly formatted request
  6. Common mistakes to avoid
  7. Links to related error documentation

This documentation will be very helpful for API users troubleshooting authentication issues.

Regarding the static analysis hint: The curl example without authentication headers is intentional since it's demonstrating the error case.

🧰 Tools
🪛 Gitleaks (8.21.2)

29-31:

(curl-auth-header)

go/apps/api/routes/v2_ratelimit_get_override/404_test.go (2)

58-58: Improved error type URL reference.

The error type URL has been updated to use a more specific path that precisely identifies the error type. This change enhances the API's error reporting by providing a more granular and informative error reference.


73-73: Consistent error type URL implementation for namespace errors.

Both namespace error scenarios now correctly reference the specific ratelimit_namespace_not_found error documentation URL, making the error handling more consistent and precise.

Also applies to: 87-87

apps/docs/api-reference/errors-v2/unkey/data/key_auth_not_found.mdx (2)

1-74: Well-structured error documentation.

The documentation for this error code is comprehensive and clearly explains what the error means, scenarios that trigger it, and resolution steps. It follows a consistent pattern with other error documentation files.

🧰 Tools
🪛 LanguageTool

[grammar] ~28-~28: The plural noun “Typos” cannot be used with the article “a”. Did you mean “a non-existent record typo” or “non-existent record Typos”?
Context: ...g to update authentication settings for a non-existent record - Typos in identifiers Here's an example of a ...

(A_NNS)


70-74: Good use of related errors section.

The related errors section effectively links to other relevant error types that users might encounter, creating a cohesive documentation network that helps users navigate through different error scenarios.

apps/docs/api-reference/errors-v2/unkey/authorization/workspace_disabled.mdx (1)

1-69: Comprehensive workspace disabled error documentation.

The documentation clearly explains the conditions under which this error occurs, multiple resolution paths, and common mistakes to avoid. This will help users quickly understand and address workspace-related issues.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~48-~48: You might be missing the article “the” here.
Context: ...key.com/settings/billing) 2. Contact workspace administrator: If you're not the work...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

apps/docs/api-reference/errors-v2/unkey/application/invalid_input.mdx (2)

17-23: Excellent error details implementation.

The inclusion of the errors array with specific validation failure details (location, message, and fix) provides actionable information to API consumers. This is a great practice that will significantly improve the developer experience.


63-76: Helpful example of corrected request.

Providing both the problematic request and its corrected version is excellent practice. This concrete example helps users understand exactly how to fix validation issues they encounter.

apps/dashboard/lib/trpc/routers/logs/query-logs/index.ts (3)

14-14: Schema simplification improves clarity.

The change from a complex object structure to a simple integer for nextCursor makes the schema more straightforward and easier to understand.


50-50: Simplified cursor handling.

The direct assignment of input.cursor to cursorTime streamlines the code by removing the need to unpack an object.


70-70:

❓ Verification inconclusive

Response construction simplified.

The streamlined construction of nextCursor using a direct value assignment is cleaner than creating a complex object.

Verify this approach maintains the same pagination accuracy as the previous implementation:


🏁 Script executed:

#!/bin/bash
# Check for any client-side handling of the nextCursor structure
rg -A 3 "nextCursor" --glob "*.{ts,tsx}" -g "!**/test/**" -g "!**/node_modules/**" | grep -E "nextCursor\.(time|requestId)"

Length of output: 123


Pagination Implementation Cleanup – Please Verify

The simplified assignment of nextCursor as a scalar value directly from logs[logs.length - 1].time makes the code cleaner compared to the earlier object-based approach. However, our automated search for client-side references to properties (such as nextCursor.time or nextCursor.requestId) yielded no output. This could mean that no client code depends on a more complex structure, but it isn’t conclusive.

  • File: apps/dashboard/lib/trpc/routers/logs/query-logs/index.ts (line 70)
  • Snippet:
        nextCursor: logs.length > 0 ? logs[logs.length - 1].time : undefined,
  • Action: Please perform a manual verification to ensure this change maintains the correct pagination accuracy and that no part of the client-side code is expecting additional properties on nextCursor.
go/pkg/zen/auth_test.go (4)

10-10: Added import for structured error codes.

The addition of the codes package import supports the move to more specific error types.


20-20: Enhanced error specificity with URN codes.

Replacing the generic errTag with specific codes.URN types improves error reporting granularity and consistency. The test now validates precise error conditions rather than generic error types.

Also applies to: 32-33, 38-39, 50-51, 56-57


79-88: Improved error verification logic.

The new error checking logic properly extracts and validates error codes using fault.GetCode(err), making the tests more robust. The conditional logic handles both cases where specific codes are expected and where they aren't.


94-94: Better test assertions with require.

Using require.Equal instead of assert.Equal ensures that tests fail immediately when conditions aren't met, preventing false positives from subsequent test steps.

Also applies to: 111-111

apps/docs/api-reference/errors-v2/unkey/authorization/forbidden.mdx (1)

1-74: Well-structured error documentation.

This comprehensive documentation file for the "forbidden" error provides clear information about the error's context, causes, and solutions. The JSON example, explanation, and troubleshooting steps are well-organized and helpful.

🧰 Tools
🪛 LanguageTool

[style] ~45-~45: You have already used ‘trying to’ in nearby sentences. Consider using one of the replacements to let your writing stand out.
Context: ... permission issue. The operation you're trying to perform may be: 1. **Not supported by ...

(REP_TRY)


[style] ~65-~65: You have already used ‘Trying to’ in nearby sentences. Consider using one of the replacements to let your writing stand out.
Context: ...rrent plan - Resource state issues: Trying to modify resources that are in a state th...

(REP_TRY)


[style] ~67-~67: You have already used ‘trying to’ in nearby sentences. Consider using one of the replacements to let your writing stand out.
Context: ...ing security boundaries**: Deliberately trying to access protected resources - **Outdated...

(REP_TRY)

🪛 Gitleaks (8.21.2)

29-31:

(curl-auth-header)

apps/docs/api-reference/errors-v2/unkey/application/assertion_failed.mdx (1)

1-57: Comprehensive documentation for internal error.

This documentation clearly explains that assertion failures are internal system errors (not user errors) and provides appropriate guidance on how to proceed when encountering them. The explanation of causes, troubleshooting steps, and information to include when contacting support is thorough and helpful.

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

18-18: Appropriate addition of the codes package.

Adding the codes package import is necessary for the standardized error code system implementation.


87-92: Good refactoring to use more maintainable error checking.

The change from directly checking errors.Is(err, sql.ErrNoRows) to using the db.IsNotFound(err) helper function improves code maintainability and readability. The error response now uses a standardized error code from the codes package which enhances API consistency.


98-99: Consistent error code standardization.

The error handling has been properly updated to use the standardized error code system with fault.WithCode instead of tags, creating consistency across the API.


128-128: Proper use of standardized authorization error code.

The authorization error now correctly uses the standardized insufficient permissions error code, which will provide more consistent error responses to API consumers.


153-158: Important error handling improvement for override matching.

Added proper error handling for the case when ratelimit override matching fails with a "not found" error. This prevents potential unhandled errors and provides consistent error messaging to clients.

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

10-10: Appropriate addition of the codes package.

Adding the codes package import is necessary for the standardized error code system implementation.


47-52: Good refactoring to use more maintainable error checking.

The change from directly checking SQL errors to using the db.IsNotFound(err) helper function improves code maintainability. The error handling now uses standardized error codes which improves API consistency.


59-61: Improved error message clarity.

The error message has been updated from "wrong workspace, masking as 404" to "namespace was deleted", which provides a clearer and more user-friendly message while maintaining the same error code.


88-90: Proper use of standardized authorization error code.

The authorization error now correctly uses the standardized insufficient permissions error code, which will provide more consistent error responses to API consumers.


99-104: Essential error handling improvement for override finding.

Added proper error handling for the case when finding a ratelimit override fails with a "not found" error. This provides a specific error code and message for this scenario, which improves API consistency and client error handling.


142-143: Proper use of validation error code.

The input validation error now correctly uses the standardized invalid input error code, which provides better error categorization and consistency.

apps/docs/api-reference/errors-v2/unkey/data/key_not_found.mdx (1)

1-74: Well-structured error documentation with comprehensive guidance.

This documentation for the err:unkey:data:key_not_found error code is well-organized and thorough. It includes:

  1. A clear JSON example showing the exact error format
  2. A detailed explanation of what causes this error
  3. Common scenarios that trigger it
  4. An example request that would produce the error
  5. Step-by-step guidance on how to fix the issue
  6. Common mistakes to avoid
  7. Related errors for additional context

The content is user-friendly and provides practical solutions, which will greatly help API consumers understand and resolve this error.

apps/docs/api-reference/errors-v2/unkey/application/service_unavailable.mdx (1)

1-100: Excellent error documentation with robust retry strategy example.

This documentation for the err:unkey:application:service_unavailable error is comprehensive and extremely helpful. Particularly valuable is:

  1. The detailed explanation of various causes for service unavailability
  2. The robust retry strategy example using exponential backoff
  3. The practical Bash script implementation showing how to handle this error

The script provided in lines 55-89 is especially beneficial as it demonstrates a production-ready approach to handling transient service issues. This documentation goes beyond simply explaining the error to providing actionable solutions, which will help developers implement resilient applications against temporary service disruptions.

apps/docs/api-reference/errors-v2/unkey/data/ratelimit_override_not_found.mdx (1)

1-88: Documentation looks comprehensive and well-structured!

The error documentation is clear, follows a consistent format, and provides valuable information for users. It includes all necessary sections: error description, JSON example, explanation, sample request, troubleshooting steps, common mistakes, and related errors.

apps/docs/api-reference/errors-v2/unkey/data/workspace_not_found.mdx (1)

1-71: Documentation is thorough and properly formatted!

The error documentation follows the same high-quality structure as other error docs, with clear explanations and practical examples. All sections are well-organized and provide actionable guidance for users encountering this error.

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

16-16: Added new import for codes package.

The addition of the codes package is part of the migration from tag-based to code-based error handling.


49-50: Updated error handling to use structured error codes.

This change replaces the previous generic fault.WithTag(fault.INTERNAL_SERVER_ERROR) with a more specific fault.WithCode(codes.App.Internal.UnexpectedError.URN()), improving error clarity and consistency.


58-59: Updated error handling for namespace not found.

The error code now uses a specific namespace not found code instead of a generic NOT_FOUND tag, making error identification more precise.


66-69: Updated error handling for namespace not in workspace.

This code properly masks a cross-workspace access attempt as a 404 error using the same error code as when the namespace doesn't exist, which is a good security practice.


95-98: Updated error handling for insufficient permissions.

The error now uses a specific authorization code from the structured error system.


103-106: Updated error handling for database transaction failures.

Now using a more specific service unavailable error code instead of a generic database error tag.


126-129: Updated error handling for database operation failures.

Consistent with other changes, this replaces generic database error tags with specific service unavailable error codes.


157-160: Updated error handling for audit log insertion failures.

Continues the pattern of using specific error codes for database-related errors.


165-168: Updated error handling for transaction commit failures.

Uses the same service unavailable error code consistently with other database operation errors.


198-201: Updated error handling for missing input parameters.

Now uses the invalid input error code instead of a generic bad request tag.

apps/docs/api-reference/errors-v2/unkey/data/identity_already_exists.mdx (1)

1-100: Documentation is well-written and follows the established pattern!

The error documentation is comprehensive, providing clear explanations, examples, and multiple approaches to resolve the issue. The get-or-create pattern example is particularly helpful.

🧰 Tools
🪛 Gitleaks (8.21.2)

43-45:

(curl-auth-header)


67-69:

(curl-auth-header)

apps/docs/api-reference/errors-v2/unkey/data/identity_not_found.mdx (2)

1-84: Well-structured and comprehensive error documentation.

This new documentation file for the identity_not_found error provides excellent guidance with clear examples, common scenarios, and actionable fixes. The structure follows a good pattern: error example, explanation, how to fix, common mistakes, and related errors.

🧰 Tools
🪛 Gitleaks (8.21.2)

35-37:

(curl-auth-header)


55-57:

(curl-auth-header)


61-70:

❓ Verification inconclusive

Ensure API version consistency in examples.

The documentation shows different API versions in the examples. The "identities.createIdentity" endpoint is called with v2 while other examples use v1. Verify that this is intentional and that the versions are correct.


🏁 Script executed:

#!/bin/bash
# Check for endpoint version differences across the docs

echo "Searching for identities.createIdentity endpoint versions:"
rg "identities\.createIdentity" --glob "*.mdx" -A 1 -B 1

Length of output: 2355


Action Required: Confirm API Version Intent

The documentation in the errors-v2 section (apps/docs/api-reference/errors-v2/unkey/data/identity_not_found.mdx) shows the /v2/identities.createIdentity endpoint, while other parts of the docs (e.g., quickstart and create-identity sections) reference /v1/identities.createIdentity. Please verify that using v2 in this error example is intentional. If it is, consider adding a clarifying note to document the distinction; otherwise, update the snippet for consistency.

apps/dashboard/lib/trpc/routers/ratelimit/query-logs/index.ts (3)

14-14: Good simplification of cursor structure.

Changing the nextCursor from an object to a simple number streamlines the pagination implementation.


59-59: Properly updated cursor handling.

The cursor handling has been appropriately simplified to match the type change.


78-78: Simplified nextCursor assignment.

The response now correctly uses just the time value as the cursor, consistent with the schema change.

apps/docs/api-reference/errors-v2/unkey/data/role_not_found.mdx (2)

1-82: Well-structured error documentation with clear examples.

This documentation file for the role_not_found error follows a consistent format with the other error documentation, providing comprehensive information and actionable steps to resolve the issue.


54-57:

❓ Verification inconclusive

Ensure API version consistency in examples.

Verify that all API endpoints are using the correct API versions in your examples. All examples here use v1, but this should be consistent with the actual API versioning scheme.

Also applies to: 62-69


🏁 Script executed:

#!/bin/bash
# Check for endpoint version consistency in role documentation

echo "API versions in role-related endpoints:"
rg "roles\." --glob "*.mdx" -A 2 -B 2 | grep -E "v[0-9]+"

Length of output: 2236


API version consistency: Verify intended version usage across docs

The examples in the error-related docs (e.g., in apps/docs/api-reference/errors-v2/unkey/data/role_not_found.mdx) consistently reference v1 endpoints (e.g., https://api.unkey.com/v1/roles.listRoles). Please confirm that using v1 endpoints is intentional for these error examples. If your API versioning scheme requires a different version (such as v2) for error documentation, please update the examples accordingly.

  • All relevant files (including those in errors-v2 and keys sections) currently use v1.
  • If the error docs are expected to align with a different API version, ensure you update both the request and error examples for consistency.
apps/dashboard/lib/trpc/routers/ratelimit/query-overview-logs/index.ts (4)

14-14: Good simplification of cursor structure.

Simplifying the nextCursor from an object to a number streamlines the pagination implementation.


59-59: Properly updated cursor handling.

The parameter passing for clickhouse query has been correctly updated to match the type change.


80-82: Simplified nextCursor assignment.

The conditional nextCursor assignment has been properly updated to use only the time value.


14-82:

❓ Verification inconclusive

Ensure consistent cursor implementation across the codebase.

The cursor simplification appears to be part of a larger refactoring. Verify that this approach is applied consistently across all pagination implementations.


🏁 Script executed:

#!/bin/bash
# Check for consistent cursor implementation

# Find all nextCursor definitions to see if any still use the complex object structure
echo "Files that might still use the old cursor structure:"
rg "nextCursor:.*{.*requestId" --type ts

# Find other potential consumers of cursor data
echo "Other potential cursor consumers:"
rg "cursor\?.*(time|requestId)" --type ts --type tsx

Length of output: 439


Below is an updated verification script using corrected regex patterns. This script re-checks for any legacy usage of a cursor object (with properties like requestId) and for other cursor consumer references in TypeScript files:

Please run these commands and manually verify that the simplified numeric cursor implementation (as seen in apps/dashboard/lib/trpc/routers/ratelimit/query-overview-logs/index.ts) is applied consistently across the codebase.


🏁 Script executed:

#!/bin/bash
echo "Searching for legacy 'nextCursor' object pattern (old cursor structure):"
rg "nextCursor:.*\\{.*requestId" --type ts

echo ""
echo "Searching for other cursor consumer references in TypeScript files:"
rg -t typescript "cursor\\?.*(time|requestId)"

Length of output: 565


Cursor Implementation Consistency – Please Manually Verify Edge Cases

The simplified numeric cursor implementation in apps/dashboard/lib/trpc/routers/ratelimit/query-overview-logs/index.ts appears to follow the intended refactoring. Automated searches for legacy cursor structures (i.e. patterns using an object with a property like requestId) did not return results. However, due to prior regex errors and file‐type issues encountered during the automated checks, please manually verify that no legacy (complex) cursor usage remains in other pagination implementations.

  • Confirm that no files still implement cursor structures based on objects (with keys such as requestId).
  • Ensure all pagination features consistently use the simplified numeric nextCursor approach.
go/apps/api/routes/v2_identities_create_identity/handler.go (7)

18-18: Appropriate addition of codes package import

This import adds structured error codes to replace generic error tags, improving error reporting specificity.


79-81: Good use of specific error code for insufficient permissions

Using codes.Auth.Authorization.InsufficientPermissions.URN() provides clear context about the nature of the error, making it easier for API consumers to understand and handle the issue.


89-91: Proper error code for metadata marshaling failures

Replacing generic bad request tags with codes.App.Validation.InvalidInput.URN() provides more precise error categorization for metadata processing issues.


97-99: Consistent validation error code for size constraints

Using the same validation error code for metadata size constraints as for marshaling errors maintains consistency in error handling for related validation issues.


108-110: Improved service unavailability error handling

Using codes.App.Internal.ServiceUnavailable.URN() for database transaction failures provides a more accurate classification of the error type.


132-134: Precise error code for duplicate identity conflicts

The transition from a general conflict tag to the specific codes.Data.Identity.Duplicate.URN() makes it clearer to API consumers that the issue relates to an identity that already exists.


218-220: Consistent error handling for database operations

Using the same ServiceUnavailable error code for both audit log insertion and transaction commit failures ensures consistency in how database-related errors are reported.

Also applies to: 226-228

apps/docs/api-reference/errors-v2/unkey/authorization/key_disabled.mdx (1)

1-77: Well-structured documentation for key_disabled error code

The documentation provides clear and comprehensive information about the key_disabled error, including an example JSON response, explanation of what happened, how to fix it, common mistakes, and related errors. This will help developers understand and resolve this error when encountered.

apps/docs/api-reference/errors-v2/unkey/data/api_not_found.mdx (1)

1-82: Comprehensive documentation for api_not_found error

The documentation provides complete information about the api_not_found error, with well-structured sections on what happened, how to fix it, common mistakes, and related errors. The included example requests and responses will be helpful for developers troubleshooting this error.

🧰 Tools
🪛 Gitleaks (8.21.2)

43-45:

(curl-auth-header)


67-69:

(curl-auth-header)

apps/docs/api-reference/errors-v2/unkey/application/protected_resource.mdx (1)

1-22: Well-structured documentation for protected_resource error

The documentation provides clear and comprehensive information about the protected_resource error, including example JSON, explanation, fix solutions, important notes, and related errors. This level of detail will be valuable for developers encountering this error.

Also applies to: 24-44, 47-72

internal/clickhouse/src/ratelimits.ts (3)

398-398: Consistent ordering with cursor filter.

Using ORDER BY fr.time DESC is consistent with time < cursorTime, ensuring logs are returned in descending order as intended. No issues found.


582-582: Fallback ordering logic.

Falling back to "last_request_time DESC" when no sorting rules are specified provides a clear, deterministic default ordering. This approach is sound.


588-601:

❓ Verification inconclusive

Cursor-based pagination logic for ascending and descending sorts.

This code switches between time > cursorTime (for ascending) and time < cursorTime (for descending). Please confirm that client queries set cursorTime and sort direction properly to ensure consistent pagination. You can run this script to find all usage references and verify correctness:


🏁 Script executed:

#!/bin/bash
# Search usage of getRatelimitOverviewLogs to confirm correct parameter usage
rg -A 5 'getRatelimitOverviewLogs'

Length of output: 1302


**Cursor-Based Pagination Validation – Please Verify Client Usage **

The updated pagination logic now correctly toggles between using time > {cursorTime: Nullable(UInt64)} for ascending order and time < {cursorTime: Nullable(UInt64)} for descending order. Our search confirmed that getRatelimitOverviewLogs is used in internal/clickhouse/src/index.ts. However, please ensure that all client queries invoking this API are supplying a valid cursorTime and explicitly setting the sort direction. Additionally, based on earlier feedback regarding pagination tie-breaking (e.g., considerations around including a secondary key like request_id for ascending sorts), double-check that this simplified condition meets your consistency requirements in practice.

  • Action Item: Verify in the client code (e.g., within internal/clickhouse/src/index.ts) that the parameters cursorTime and sort direction are appropriately provided.
  • Additional Consideration: Revisit the pagination strategy for ascending sorts if a secondary ordering (such as by request_id) becomes necessary.

Please review this against actual usage patterns to ensure robustness.

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

24-35: Graceful fallback to 'UnexpectedError' URN.

When no code is found or parsing fails, defaulting to codes.App.Internal.UnexpectedError.URN() ensures unknown issues are handled with a consistent internal error code. This is robust and sane.


36-47: Clear distinction for Not Found errors.

Mapping these “not found” URNs to a 404 status ensures clients receive the correct HTTP response. Referencing the dynamic docs URL in code.DocsURL() further improves traceability.


123-135: Handling duplicate identity with 409 Conflict.

Returning a 409 status for IdentityDuplicate aligns with REST guidelines for conflicts, clarifying that the resource already exists.


181-185: Unified fallback for internal errors.

Handling unrecognized or internal errors in a single 500-response block provides a consistent failure path with essential logging for debugging.

apps/docs/api-reference/errors-v2/unkey/data/ratelimit_namespace_not_found.mdx (1)

1-77: LGTM!

The documentation is clear and appears consistent with the other error docs.

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

16-16: No concerns with the new import.


51-57: Well-handled namespace not found scenario.

Using db.IsNotFound(err) followed by a structured error code is a good approach.


64-64: Workspaces incorrectly accessed are securely masked as 404.

This is a common security best practice.


122-125: Consistent override not found handling.

Aligns with the new structured error code.


137-137: Service unavailable code usage is appropriate.

Tagging DB failures with service_unavailable conforms to the new error structure.

apps/docs/api-reference/errors-v2/unkey/application/unexpected_error.mdx (1)

1-85: LGTM! Comprehensive error documentation.

This error documentation is well-structured with clear examples, causes, and actionable remediation steps. The inclusion of retry logic code examples is particularly helpful for users encountering this error.

🧰 Tools
🪛 LanguageTool

[grammar] ~80-~80: This phrase is duplicated. You should probably use “this error” only once.
Context: ...equestId` when contacting support about this error - This error may indicate a bug in Unkey's systems t...

(PHRASE_REPETITION)

go/pkg/urn/resource.go (1)

1-56: LGTM! Well-structured resource type validation.

The implementation effectively validates resource types against their associated services using a clear mapping structure and robust error handling.

apps/docs/api-reference/errors-v2/unkey/authorization/insufficient_permissions.mdx (1)

1-76: LGTM! Clear and comprehensive error documentation.

This documentation thoroughly explains the insufficient permissions error, providing excellent context with common scenarios, examples, and actionable remediation steps. The "Common Mistakes" section is particularly valuable for users to troubleshoot their issues.

go/pkg/urn/service.go (1)

1-38: LGTM! Efficient service validation implementation.

The service type and validation approach is well-structured, using a map for efficient lookup of valid services.

go/pkg/fault/code_test.go (8)

8-8: Import the codes package for the new error code system.

The import of the github.com/unkeyed/unkey/go/pkg/codes package is needed to support the transition from tag-based error handling to the new URN-based code system.


11-11: Refactored function name and return type to use codes.URN.

The function has been appropriately renamed from TestGetTag to TestGetCode to reflect the change in functionality, with the expected return type updated from Tag to codes.URN.

Also applies to: 15-15


18-21: Updated error case expectations for nil and untagged errors.

The test cases have been properly updated to align with the new code system, where nil and untagged errors now return an empty string instead of "UNTAGGED".

Also applies to: 23-26


28-31: Updated test cases to use codes.URN for tagged errors.

The test cases correctly use the new WithCode function with codes.URN values instead of the previous tag-based approach, maintaining the same test logic while adapting to the new type system.

Also applies to: 34-38


43-45: Updated function call and assertion to use the new GetCode function.

The test now correctly calls GetCode instead of GetTag and compares the result against the expected codes.URN value.


49-53: Refactored TestWithTag to TestWithCode with updated parameter types.

The function has been appropriately renamed from TestWithTag to TestWithCode, with the tag parameter type updated from Tag to codes.URN.


58-59: Updated test parameters and assertions to use codes.URN.

The test cases now correctly use codes.URN values for tags and assertions, maintaining test coverage while transitioning to the new error code system.

Also applies to: 66-67, 71-72


78-80: Updated function call to use WithCode instead of WithTag.

The test now correctly uses the new WithCode function instead of WithTag, reflecting the underlying implementation change.

apps/dashboard/lib/trpc/routers/api/keys/query-overview-logs/index.ts (3)

13-14: Simplified nextCursor schema to use a single number instead of an object.

The nextCursor schema has been simplified from an object with time and requestId properties to just a number, which streamlines the API and reduces complexity.


44-45: Simplified cursor handling in ClickHouse query.

The input.cursor is now passed directly as cursorTime, removing the need for cursorRequestId and simplifying the interface with the ClickHouse API.


96-97: Simplified nextCursor construction in the response.

The nextCursor is now directly set to the time value from the last log entry, which is more straightforward than creating a complex object with time and requestId.

go/pkg/codes/codes.go (8)

1-16: Well-structured package with clear formatting constants.

The new codes package introduces a clean structure for error codes with well-defined constants for formatting. The prefix and separator are clearly documented, which will help maintain consistency across the codebase.


17-37: Comprehensive System type with well-documented constants.

The System type effectively categorizes error sources with clear documentation for each constant. This provides a solid foundation for error classification based on origin or domain.


38-64: Well-organized Category type with logical grouping.

The Category type provides a second level of classification for errors, with constants logically grouped by system. The comments clearly explain the purpose of each category.


65-77: Clear and concise Code struct definition.

The Code struct effectively encapsulates all components of an error code with descriptive field names and thorough documentation explaining the purpose of each field.


78-84: Efficient URN generation method.

The URN method efficiently generates a standardized string representation of error codes using the format constants, which enables consistent error serialization and cross-service communication.


85-92: Helpful DocsURL method for documentation linking.

The DocsURL method provides a valuable feature by constructing URLs to error documentation, which will help users and developers find information about errors and their solutions.


93-101: Simple and effective URN parsing function.

The ParseURN function provides a clean interface for converting URN strings back to Code objects, delegating to ParseCode for the implementation details.


102-116: Robust code parsing with validation.

The ParseCode function effectively parses URN-style strings into Code objects with proper validation to ensure the expected format is followed, returning informative errors when the format is invalid.

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

16-17: Added import for the new codes package.

The import of the github.com/unkeyed/unkey/go/pkg/codes package is necessary to support the transition to the new error code system.


70-74: Updated error handling for insufficient permissions.

The error handling now uses WithCode with a specific URN from the codes package instead of a generic tag, providing more detailed error information.


77-82: Updated error handling for database transaction creation.

The error handling for database failures now uses the appropriate service unavailable code from the codes package, making the error more specific and informative.


100-105: Updated error handling for key authentication creation.

The error handling for key authentication failures now uses the service unavailable code, providing consistent error reporting across the application.


116-121: Updated error handling for API creation.

The error handling for API creation failures now uses the service unavailable code, maintaining consistency with other error handling in the function.


146-151: Updated error handling for audit log insertion.

The error handling for audit log failures now uses the service unavailable code, aligning with the error handling pattern established in this function.


154-159: Updated error handling for transaction commit.

The error handling for transaction commit failures now uses the service unavailable code, completing the consistent error handling approach throughout the function.

go/pkg/codes/constants_gen.go (5)

1-7: Well-structured type definition for error codes.

The URN string type provides a good foundation for type-safe error codes. This approach enables compile-time checks when using these constants in switch statements, which is mentioned in the comment on line 9.


9-34: Authentication and authorization error structure looks comprehensive.

The error codes for authentication and authorization scenarios are well-organized with clear, descriptive comments that explain when each error should be used. The hierarchical structure and consistent naming pattern make it easy to understand the purpose of each constant.


36-91: Data errors are well-categorized by resource type.

This section nicely organizes data-related errors by resource type (Key, Workspace, Api, etc.), making it easy to locate specific error codes. Each resource type has its own set of error scenarios with clear documentation.


92-114: Application error categories provide good coverage for general scenarios.

The application error categories (Internal, Validation, Protection) cover common error scenarios that don't fit into the auth or data categories. The error codes are well-documented and follow the same consistent pattern as the rest of the file.


1-2:

❓ Verification inconclusive

Verify that generate.go is creating reproducible outputs.

Since this is a generated file, ensure that the generate.go script produces consistent output across different environments and runs. This helps maintain consistency in the codebase and avoids unnecessary changes in generated files during builds.


🏁 Script executed:

#!/bin/bash
# Check if generate.go exists and examine its content to understand the generation process

# Look for generate.go in the same directory or parent directories
fd --type f "generate.go" --exec cat {} \; | head -n 30

Length of output: 559


Action Required: Verify Determinism in generate.go Output

  • The generate.go script is present and its initial code shows that it processes source files and uses maps (e.g., commentMap)—which, without careful handling, might introduce non-determinism due to randomized map iteration order.
  • Verify that any non-deterministic elements (such as map ordering) are explicitly sorted so that running generate.go in different environments or at different times consistently produces the same output (aside from the expected timestamp change).
  • Additionally, confirm that the generated timestamp (as seen in the header of go/pkg/codes/constants_gen.go) is handled in a way that doesn’t lead to spurious differences across builds.

Comment on lines 2 to 3
title: INSUFFICIENT_PERMISSIONS
openapi-schema: ErrInsufficientPermissions
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

File path doesn't match the error code.

The file path is BAD_REQUEST.mdx but the error code is now INSUFFICIENT_PERMISSIONS. Consider renaming this file to match the error code for better maintainability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants