Skip to content
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

fix: breadcrumb cache issue #2215

Merged
merged 42 commits into from
Oct 28, 2024

Conversation

AkshayBandi027
Copy link
Contributor

@AkshayBandi027 AkshayBandi027 commented Oct 5, 2024

What does this PR do?

Fixes: #2193

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?

-Go to dashboard/api/[apiId]/settings

  • Change the name of api, see reflects the breadcrum immediately.

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

Summary by CodeRabbit

  • New Features

    • Enhanced caching mechanisms for various components, improving data retrieval efficiency and cache management.
    • Added search functionality within the glossary terms through the FilterableCommand component.
  • Bug Fixes

    • Improved error handling by redirecting users when a namespace is not found.
  • Documentation

    • Updated template list showcasing the use of Unkey with various frameworks, providing additional resources for developers.

Copy link

changeset-bot bot commented Oct 5, 2024

⚠️ No Changeset found

Latest commit: 7c51d96

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

vercel bot commented Oct 5, 2024

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 Oct 14, 2024 5:18pm

Copy link

vercel bot commented Oct 5, 2024

@AkshayBandi027 is attempting to deploy a commit to the Unkey Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Contributor

coderabbitai bot commented Oct 5, 2024

📝 Walkthrough

Walkthrough

The changes in this pull request focus on enhancing caching mechanisms across various components in the dashboard application. Key modifications include the introduction of a tags object for better cache management, updates to functions like getNamespaceById and getApiById to utilize caching strategies, and the addition of cache revalidation functionality in mutation success callbacks. These changes aim to improve the efficiency and reliability of data retrieval and updates within the application.

Changes

File Change Summary
apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/settings/page.tsx Enhanced caching in AsyncPageBreadcrumb with getNamespaceById function.
apps/dashboard/app/(app)/ratelimits/[namespaceId]/settings/update-namespace-name.tsx Added revalidateTag import and invoked it in onSuccess of updateName mutation.
apps/dashboard/lib/cache.ts Introduced tags constant with methods for generating standardized tag strings.
apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/keys/[keyAuthId]/page.tsx Updated getApiById to include caching options with tags.
apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/page.tsx Modified getApiById with caching options including tags.
apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/settings/page.tsx Updated getApiById to utilize caching with tags.
apps/dashboard/app/(app)/@breadcrumb/authorization/permissions/[permissionId]/page.tsx Enhanced getPermissionById function with caching options and tags.
apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx Updated getWorkspaceByRoleId with caching options and tags.
apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/logs/page.tsx Enhanced caching for getNamespaceById with tags.
apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/overrides/page.tsx Updated getNamespaceById with caching options and tags.
apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/page.tsx Enhanced getNamespaceById with caching options and tags.
apps/dashboard/app/(app)/apis/[apiId]/settings/update-api-name.tsx Added revalidateTag import and invoked it in onSuccess of updateName mutation.
apps/dashboard/app/(app)/authorization/permissions/[permissionId]/client.tsx Updated onSuccess of updatePermission mutation to include revalidateTag.
apps/dashboard/app/(app)/authorization/roles/[roleId]/update-role.tsx Updated onSuccess of updateRole mutation to include revalidateTag.
apps/dashboard/app/(app)/ratelimits/[namespaceId]/page.tsx Modified error handling to redirect instead of returning not found; streamlined interval parsing.
apps/dashboard/app/actions.ts Introduced revalidateMyTag function and exported it as revalidateTag.
apps/www/app/glossary/[slug]/page.tsx Added imports for FilterableCommand and TermsRolodexDesktop, reorganized import statements.
apps/www/app/glossary/client.tsx Added import for Glossary and allGlossaries, reorganized imports.
apps/www/components/glossary/search.tsx Reordered imports and clarified internal logic for FilterableCommand.
apps/www/components/glossary/terms-rolodex-desktop.tsx Reordered imports and maintained existing functionality in TermsRolodexDesktop.
oss.gg/7_create_a_template.md Updated document with new template entries showcasing Unkey implementations.

Assessment against linked issues

Objective Addressed Explanation
Ensure API name updates are reflected immediately (2193)

Possibly related PRs

Suggested labels

:joystick: 150 points

Suggested reviewers

  • mcstepp
  • perkinsjr
  • MichaelUnkey

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • 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 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 Oct 5, 2024

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

🧹 Outside diff range and nitpick comments (11)
apps/dashboard/app/(app)/apis/[apiId]/settings/actions.ts (1)

9-11: LGTM: New function addresses caching issue. Consider minor enhancements.

The revalidateMyTag function effectively addresses the caching issue by allowing specific tags to be invalidated. This aligns well with the PR objectives.

Some suggestions for potential improvements:

  1. Consider adding error handling to catch and log any issues that might occur during tag revalidation.
  2. You might want to return a boolean or some status to indicate success/failure of the operation.

Example:

export async function revalidateMyTag(tag: string): Promise<boolean> {
  try {
    await revalidateTag(tag);
    return true;
  } catch (error) {
    console.error(`Failed to revalidate tag ${tag}:`, error);
    return false;
  }
}

These are optional enhancements and the current implementation is acceptable as is.

apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/page.tsx (1)

23-31: Approve changes with a suggestion for future improvement

The modifications to getNamespaceById effectively address the caching issue described in #2193. By adding a specific cache key and a tag based on the namespace ID, you've enabled more granular cache management. This should resolve the problem of the API name remaining cached after renaming.

Consider adding a comment explaining the caching strategy for future maintainers. Also, keep an eye on the unstable_cache API, as it may change in future Next.js versions. You might want to create a task to review and update this once a stable version is released.

Example comment:

// Cache namespace data with a specific key and tag for granular invalidation
// This allows us to clear the cache for a specific namespace when it's updated
apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/page.tsx (1)

Line range hint 1-65: Consider these improvements for enhanced robustness

The current implementation is good, but consider the following suggestions to further improve robustness and user experience:

  1. Error Handling: Add explicit error handling for database query failures. This could involve wrapping the getApiById call in a try-catch block and rendering an error state in the breadcrumb if the API fetch fails.

  2. Stale-While-Revalidate: Consider implementing a stale-while-revalidate caching strategy. This would allow showing the old API name immediately while fetching the latest data in the background, potentially improving perceived performance.

  3. Typescript Improvements: Consider using more specific types for the api object to ensure type safety throughout the component.

Here's a sketch of how these improvements might look:

import { useEffect } from 'react';
import { revalidateTag } from 'next/cache';

// More specific type for API
type API = {
  id: string;
  name: string;
  workspace: { tenantId: string };
};

// Add error handling and stale-while-revalidate
const getApiById = cache(
  async (apiId: string): Promise<API | null> => {
    try {
      const api = await db.query.apis.findFirst({
        // ... (existing query)
      });
      return api;
    } catch (error) {
      console.error('Failed to fetch API:', error);
      return null;
    }
  },
  ["apiById"],
  { tags: [`api-${props.params.apiId}`], revalidate: 60 } // revalidate every 60 seconds
);

async function AsyncPageBreadcrumb(props: PageProps) {
  const tenantId = getTenantId();
  const api = await getApiById(props.params.apiId);

  useEffect(() => {
    // Trigger background revalidation
    revalidateTag(`api-${props.params.apiId}`);
  }, [props.params.apiId]);

  if (!api) {
    return <BreadcrumbError />;
  }

  if (api.workspace.tenantId !== tenantId) {
    return <BreadcrumbUnauthorized />;
  }

  // ... (rest of the component)
}

These changes would make the component more resilient to errors and provide a smoother user experience.

apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx (2)

28-29: Improved caching mechanism addresses the renaming issue.

The changes to the caching mechanism look good and should resolve the issue where the API name remains cached after renaming. The use of unstable_cache with role-specific tags allows for more granular cache invalidation.

Consider extracting the cache key and tags into constants for better maintainability:

const ROLE_CACHE_KEY = ["roleById"];
const getRoleCacheTag = (roleId: string) => `role-${roleId}`;

const getWorkspaceByRoleId = cache(
  async (roleId: string) =>
    await db.query.roles.findFirst({
      where: (table, { eq }) => eq(table.id, roleId),
    }),
  ROLE_CACHE_KEY,
  { tags: [getRoleCacheTag(props.params.roleId)] },
);

This approach makes it easier to reuse these values consistently across the codebase if needed.


Line range hint 1-62: Summary of review findings

The changes implemented in this file introduce a more granular caching mechanism for roles, which should address the issue of names not updating immediately after renaming. The use of unstable_cache with role-specific tags is a good approach for achieving this.

However, there are a few points that need attention:

  1. Clarification is needed on the alignment between the PR description (which mentions API names) and the actual changes (which are specific to roles).
  2. Consider implementing the suggested refactoring to improve code maintainability.

To ensure that this solution fully addresses the caching issues across the application:

  1. Verify if similar caching mechanisms need to be implemented for other entities (like APIs, if they are separate from roles).
  2. Consider implementing a consistent caching strategy across the application for all entities that require immediate updates after renaming.
  3. If not already in place, consider adding integration tests that specifically check for immediate updates after renaming operations.

These steps will help ensure a robust solution to the caching issues described in the PR objectives.

apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/logs/page.tsx (1)

Line range hint 32-35: Consider enhancing error handling

While the current implementation correctly handles the case where a namespace is not found by returning null, it might be beneficial to provide more informative feedback to the user. Consider the following suggestions:

  1. Instead of returning null, you could render a custom error message in the breadcrumb.
  2. You might want to log this error for debugging purposes.

Here's a potential improvement:

if (!namespace) {
  console.error(`Namespace not found for ID: ${props.params.namespaceId}`);
  return (
    <Breadcrumb>
      <BreadcrumbList>
        <BreadcrumbItem>
          <BreadcrumbLink href="/ratelimits">Ratelimits</BreadcrumbLink>
        </BreadcrumbItem>
        <BreadcrumbSeparator />
        <BreadcrumbItem>
          <BreadcrumbPage>Namespace Not Found</BreadcrumbPage>
        </BreadcrumbItem>
      </BreadcrumbList>
    </Breadcrumb>
  );
}

This change would provide a clearer indication to the user that something went wrong, while also logging the error for easier debugging.

apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/settings/page.tsx (1)

Line range hint 1-7: Suggestion for import optimization

To improve code readability and maintainability, consider grouping related imports together. You can separate third-party imports, local component imports, and utility imports.

Here's a suggested reorganization of the imports:

// React and Next.js imports
import { Suspense } from "react";
import { unstable_cache as cache } from "next/cache";

// Local UI component imports
import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from "@/components/ui/breadcrumb";
import { BreadcrumbSkeleton } from "@/components/dashboard/breadcrumb-skeleton";

// Utility imports
import { db } from "@/lib/db";

This organization makes it easier to understand the dependencies of the component at a glance.

Also applies to: 9-12

apps/dashboard/app/(app)/apis/[apiId]/settings/update-api-name.tsx (1)

49-49: LGTM: revalidateMyTag usage addresses the caching issue.

The addition of revalidateMyTag call after a successful API name update directly addresses the caching issue mentioned in the PR objectives. This should ensure that the API name is immediately updated in the UI after renaming.

For improved clarity, consider adding a brief comment explaining the purpose of this function call:

// Invalidate the cache for this specific API to ensure immediate UI update
revalidateMyTag(`api-${api.id}`);
apps/dashboard/app/(app)/ratelimits/[namespaceId]/settings/update-namespace-name.tsx (2)

2-2: LGTM! Consider moving the import to a shared location.

The import of revalidateMyTag is appropriate for addressing the caching issue mentioned in the PR objectives. It's a good practice to invalidate the cache when updating data.

Consider moving this utility function to a more generic location if it's used across different parts of the application (e.g., both in apis and ratelimits). This would improve code organization and reusability.


49-49: LGTM! Consider adding error handling for revalidation.

The addition of revalidateMyTag in the onSuccess callback effectively addresses the caching issue mentioned in the PR objectives. This ensures that the namespace's tag is revalidated immediately after a successful update, which should resolve the problem of the old name remaining cached.

Consider adding error handling for the revalidateMyTag call. While it's unlikely to fail, it's a good practice to catch and log any potential errors to aid in debugging if issues arise in the future. For example:

try {
  await revalidateMyTag(`namespace-${namespace.id}`);
} catch (error) {
  console.error('Failed to revalidate tag:', error);
  // Optionally, you could show a warning toast to the user
  // toast.warning("Name updated, but you may need to refresh to see changes.");
}
apps/dashboard/app/(app)/authorization/permissions/[permissionId]/client.tsx (1)

51-51: LGTM: Proper cache invalidation implemented.

The addition of revalidateMyTag call in the onSuccess callback is an excellent solution to the caching issue. It ensures that the cache is invalidated immediately after a successful permission update.

For improved clarity, consider extracting the tag string to a constant:

const PERMISSION_TAG = `permission-${permission.id}`;
revalidateMyTag(PERMISSION_TAG);

This makes the code more readable and allows for easier reuse if needed elsewhere in the component.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 2288ebf and 6cd266b.

📒 Files selected for processing (14)
  • apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/keys/[keyAuthId]/page.tsx (1 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/page.tsx (1 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/settings/page.tsx (1 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/authorization/permissions/[permissionId]/page.tsx (1 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx (1 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/logs/page.tsx (1 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/overrides/page.tsx (1 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/page.tsx (1 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/settings/page.tsx (1 hunks)
  • apps/dashboard/app/(app)/apis/[apiId]/settings/actions.ts (1 hunks)
  • apps/dashboard/app/(app)/apis/[apiId]/settings/update-api-name.tsx (2 hunks)
  • apps/dashboard/app/(app)/authorization/permissions/[permissionId]/client.tsx (2 hunks)
  • apps/dashboard/app/(app)/authorization/roles/[roleId]/update-role.tsx (2 hunks)
  • apps/dashboard/app/(app)/ratelimits/[namespaceId]/settings/update-namespace-name.tsx (2 hunks)
🔇 Additional comments (27)
apps/dashboard/app/(app)/apis/[apiId]/settings/actions.ts (2)

3-3: LGTM: Import statement updated correctly.

The addition of revalidateTag to the import statement is appropriate for the new functionality being introduced. This change aligns well with Next.js best practices for server-side actions.


1-11: Verify integration with API renaming process

The changes introduced here provide a solid foundation for addressing the caching issue described in the PR objectives. However, to ensure the complete resolution of the issue, we need to verify that the revalidateMyTag function is called appropriately when an API is renamed.

Could you please provide information on where and how this function is integrated into the API renaming process? This will help ensure that the caching issue is fully resolved as intended.

To assist in this verification, you can run the following script to search for usage of the new function:

This will help us confirm that the function is being used correctly in the context of API renaming.

✅ Verification successful

Sure, I'll adjust the search to use the correct file type identifier for TypeScript.

[/run_scripts]


Verification of revalidateMyTag Integration Confirmed

The revalidateMyTag function is appropriately called within the API renaming logic across the following files:

  • apps/dashboard/app/(app)/authorization/permissions/[permissionId]/client.tsx
  • apps/dashboard/app/(app)/authorization/roles/[roleId]/update-role.tsx
  • apps/dashboard/app/(app)/apis/[apiId]/settings/update-api-name.tsx
  • apps/dashboard/app/(app)/ratelimits/[namespaceId]/settings/update-namespace-name.tsx

This confirms that the caching issue is addressed as intended.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for usage of revalidateMyTag function in the codebase

# Test: Look for calls to revalidateMyTag. Expect: At least one occurrence in API renaming logic.
rg --type typescript -A 5 $'revalidateMyTag'

Length of output: 78


Script:

#!/bin/bash
# Description: Search for usage of revalidateMyTag function in the codebase

# Test: Look for calls to revalidateMyTag. Expect: At least one occurrence in API renaming logic.
rg --type ts -A 5 'revalidateMyTag'

Length of output: 5362

apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/page.tsx (1)

Line range hint 1-62: Solution aligns well with PR objectives

The changes implemented in this file effectively address the caching issue described in #2193. By modifying the caching strategy for getNamespaceById, you've ensured that the breadcrumb will always reflect the most recent API name after renaming.

The use of dynamic rendering (export const dynamic = "force-dynamic";) and edge runtime further supports the goal of providing up-to-date information in the UI. This approach aligns well with the PR objectives and should resolve the issue of outdated API names being displayed in the breadcrumb.

To ensure the changes are working as expected across the codebase, let's verify the usage of getNamespaceById:

This script will help us identify any other places in the codebase where getNamespaceById is used or where direct database queries for ratelimitNamespaces are made. This will ensure that the caching strategy is consistently applied throughout the application.

apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/page.tsx (2)

36-36: Excellent solution to address the caching issue!

The addition of a dynamic tag api-${props.params.apiId} in the caching mechanism is a well-thought-out solution to the reported issue. This change allows for granular cache invalidation on a per-API basis, which should effectively resolve the problem where the API name remained cached in the header after renaming.

By using this approach:

  1. Each API now has its own cache entry, identified by its unique ID.
  2. When an API is renamed, its specific cache entry can be invalidated without affecting others.
  3. The breadcrumb will immediately reflect the new name upon the next render.

This implementation aligns perfectly with the PR objectives and should resolve the issue #2193.


36-36: Verify cache invalidation on API updates

While the caching mechanism has been improved to allow for per-API cache entries, it's crucial to ensure that the cache is properly invalidated when an API is renamed.

To fully resolve the issue:

  1. Confirm that there's a corresponding cache invalidation call using the same tag (api-${apiId}) when an API is updated or renamed.
  2. This invalidation should typically occur in the API update/rename handler.

Could you please run the following script to check for cache invalidation calls?

This will help ensure that the caching solution is complete and the issue is fully resolved.

apps/dashboard/app/(app)/@breadcrumb/authorization/permissions/[permissionId]/page.tsx (3)

Line range hint 1-58: Summary of review findings

The changes introduced in this file improve the caching strategy for permissions, which should help resolve issues with stale data being displayed after updates. However, there are a few points to consider:

  1. The cache key could be more specific by including the permissionId.
  2. We need to verify that proper cache invalidation is implemented across the application.
  3. There's a discrepancy between the PR objectives (which mention API name caching) and the actual changes (which deal with permission caching).

Overall, the changes look promising, but addressing these points will ensure a more robust solution.


23-29: Clarify the relationship between this change and the API name caching issue.

The PR objectives mention addressing a caching issue where the API name remains cached in the header after renaming. However, this component deals with permissions rather than API names. Could you please clarify how this change relates to the API name caching issue mentioned in the PR description?

To better understand the context, please run the following script to find references to API name caching:

#!/bin/bash
# Description: Search for references to API name caching or renaming

# Test: Look for files that mention API name caching or renaming
rg --type typescript -e "API.*name.*cache" -e "API.*rename"

This will help us verify if we're addressing the correct issue in the right place.


23-29: Improved caching strategy, but consider including permissionId in the cache key.

The changes to the getPermissionById function improve the caching strategy by adding a dynamic tag for cache invalidation. This should help resolve the issue of stale data being displayed after updates. However, to further enhance cache isolation, consider including the permissionId in the cache key as well.

Consider modifying the cache key to include the permissionId:

 const getPermissionById = cache(
   async (permissionId: string) =>
     db.query.permissions.findFirst({
       where: (table, { eq }) => eq(table.id, permissionId),
     }),
-  ["permissionById"],
+  [`permissionById-${props.params.permissionId}`],
   { tags: [`permission-${props.params.permissionId}`] },
 );

This change ensures that each permission has its own unique cache entry, preventing potential conflicts between different permissions.

To ensure that cache invalidation is working correctly across the application, please run the following script:

This script will help identify if there are proper cache invalidation calls in place when permissions are updated elsewhere in the application.

apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/keys/[keyAuthId]/page.tsx (2)

36-36: Excellent addition of cache tag to resolve API name caching issue.

The addition of the cache tag api-${props.params.apiId} is a well-implemented solution to address the issue where the API name was not updating correctly after renaming. This change allows for more granular cache invalidation based on the specific API ID, ensuring that the breadcrumb will always display the most up-to-date API name.

This implementation aligns perfectly with the PR objective of fixing the caching issue for API names and should resolve the problem reported in issue #2193.


Line range hint 1-68: Overall, excellent implementation to resolve the API name caching issue.

The changes made in this file effectively address the reported issue #2193 where the API name was not updating correctly in the breadcrumb after renaming. The addition of a cache tag api-${props.params.apiId} to the getApiById function allows for more precise cache invalidation, ensuring that the breadcrumb always displays the most up-to-date API name.

The rest of the file, including the AsyncPageBreadcrumb and PageBreadcrumb components, remains unchanged and follows good React and Next.js practices. The use of Suspense for asynchronous rendering and a skeleton fallback ensures a smooth user experience.

These changes should resolve the caching problem without introducing any new issues or complexity to the codebase.

apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/settings/page.tsx (2)

33-33: Excellent fix for the breadcrumb caching issue!

The addition of a dynamic cache tag api-${props.params.apiId} is a smart solution to the caching problem described in issue #2193. This change ensures that:

  1. Each API has its own unique cache entry.
  2. The cache for a specific API can be invalidated independently when it's renamed.
  3. The breadcrumb will always reflect the most up-to-date API name after a rename operation.

This implementation effectively resolves the issue where the old API name remained cached in the header after renaming.


Line range hint 1-67: Verify impact on API renaming functionality

The caching fix looks great and should resolve the immediate issue. To ensure comprehensive resolution:

  1. Verify that the API renaming functionality properly invalidates this cache when an API is renamed.
  2. Check if there are other components or pages that might need similar caching updates related to API names.

To help with verification, you can run the following script to find other instances where API caching might be used:

This will help identify any other areas of the codebase that might need similar updates or that interact with API renaming.

✅ Verification successful

Cache implementation verified and no issues found.

All instances of API caching and renaming functionalities have been checked and are consistent with the changes made. No additional updates are required.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find other instances of API caching that might need updates

# Search for cache usage related to APIs
rg --type typescript --type javascript -e "cache\(" -e "revalidateTag\(" -e "revalidatePath\(" | grep -i "api"

# Search for API renaming functionality
rg --type typescript --type javascript -e "renameApi" -e "updateApi" -e "api.*name"

Length of output: 262


Script:

#!/bin/bash
# Description: Find other instances of API caching that might need updates

# Search for cache usage related to APIs in TypeScript and JavaScript files
rg -g '*.ts' -g '*.tsx' -g '*.js' -g '*.jsx' -e "cache\(" -e "revalidateTag\(" -e "revalidatePath\(" | grep -i "api"

# Search for API renaming functionality in TypeScript and JavaScript files
rg -g '*.ts' -g '*.tsx' -g '*.js' -g '*.jsx' -e "renameApi" -e "updateApi" -e "api.*name"

Length of output: 6290

apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/logs/page.tsx (3)

23-30: Excellent implementation to resolve the caching issue!

The changes to the getNamespaceById cache function effectively address the caching problem described in issue #2193. Here's why this solution is appropriate:

  1. The cache key ["namespaceById"] provides a specific identifier for this particular cache entry.
  2. The dynamic tag namespace-${props.params.namespaceId} allows for fine-grained cache invalidation on a per-namespace basis.

This implementation ensures that when an API is renamed, the cache for that specific namespace can be invalidated without affecting other namespaces. As a result, the breadcrumb should now correctly display the updated API name immediately after renaming.


Line range hint 1-67: Summary and Conclusion

The changes implemented in this PR effectively address the caching issue described in #2193. The modified getNamespaceById cache function now uses a specific cache key and dynamic tags, which should resolve the problem of outdated API names being displayed in the breadcrumb after renaming.

Key points:

  1. The caching mechanism has been improved without altering the overall component structure.
  2. The changes are backwards compatible and introduce no breaking changes.
  3. The use of Suspense for loading state management is maintained.

Suggestions for further improvement:

  1. Consider enhancing error handling as mentioned in the previous comment.
  2. Verify other instances of unstable_cache usage in the application for consistency.

Overall, this PR successfully achieves its objectives and can be approved after addressing the minor suggestions.


Line range hint 1-67: Overall impact is positive with minimal risk

The changes to the caching mechanism are well-contained and don't affect the overall structure or logic of the AsyncPageBreadcrumb component. This implementation should resolve the caching issue without introducing any breaking changes.

To ensure the fix works as expected across the application:

Run the following script to check for any other instances where unstable_cache is used, which might benefit from a similar update:

This will help identify any other areas of the application that might benefit from similar caching improvements.

apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/settings/page.tsx (2)

Line range hint 1-65: Summary of changes and expected impact

The changes made in this file effectively address the caching issue described in issue #2193. By implementing a more granular caching strategy using Next.js's cache function with specific keys and tags, the API name should now update correctly in the breadcrumb after renaming.

Key points:

  1. The caching strategy now includes a namespace-specific tag, allowing for precise cache invalidation.
  2. The use of dynamic rendering and edge runtime is appropriate for this use case.
  3. The overall structure of the component, including the use of Suspense for loading states, is well-implemented.

These changes should resolve the problem of the API name remaining cached in the header after renaming. However, as suggested earlier, thorough testing of various renaming scenarios is recommended to ensure the fix is comprehensive.

Great work on addressing this issue! The solution is elegant and should improve the user experience by ensuring that the breadcrumb always displays the most up-to-date API name.


23-30: Approve changes with verification suggestion

The modifications to the getNamespaceById function look good and should address the caching issue mentioned in issue #2193. The use of a specific cache key and a dynamic tag based on the namespaceId will ensure that the API name is updated correctly after renaming.

However, to ensure the fix is complete, please verify the following:

  1. Test the renaming process multiple times, especially focusing on scenarios where the issue was previously observed (e.g., after a second rename).
  2. Confirm that the breadcrumb updates immediately after renaming in all cases.

To help verify the fix, you can use the following script to check for any remaining hardcoded or cached namespace names in the codebase:

This script will help identify any other locations in the codebase where namespace names might be cached or hardcoded, ensuring a comprehensive fix.

apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/overrides/page.tsx (3)

23-30: Excellent implementation of granular caching!

The changes to the getNamespaceById function effectively address the caching issue mentioned in the PR objectives. By using the cache function with a tag specific to the namespaceId, you've implemented a more granular caching mechanism. This approach should prevent the old API name from being cached after renaming, as the cache can now be invalidated on a per-namespace basis.

The implementation looks correct and aligns well with the PR objectives. It should resolve the issue where the API name remained cached in the header after renaming.


Line range hint 1-67: Overall assessment: Well-implemented solution

The changes in this file effectively address the caching issue for API names in the breadcrumb component. The implementation:

  1. Uses the cache function from Next.js appropriately.
  2. Implements granular caching with namespace-specific tags.
  3. Maintains the existing component structure and logic.
  4. Follows React and Next.js best practices.

The solution is focused, clean, and should resolve the reported issue without introducing new complexities. Great job on this implementation!


23-30: Suggestion for additional testing and verification

The changes look good and should address the caching issue. To ensure comprehensive testing:

  1. Verify that the breadcrumb updates immediately after renaming an API, as per the PR testing instructions.
  2. Test multiple rename operations in quick succession to confirm that the cache is consistently updated.
  3. Check the behavior across different namespaces to ensure the caching is correctly scoped.
  4. Consider adding automated tests that simulate API renaming and verify the breadcrumb content.

To assist with verification, you can use the following script to check for any hardcoded namespace names in the codebase:

This will help ensure that there are no other places in the code where namespace names might be cached or hardcoded.

apps/dashboard/app/(app)/apis/[apiId]/settings/update-api-name.tsx (2)

20-20: LGTM: Import statement for revalidateMyTag added correctly.

The import of revalidateMyTag from './actions' is properly placed and aligns with the PR objective to address the caching issue for API names.


20-20: Overall assessment: Changes effectively address the caching issue.

The addition of revalidateMyTag import and its usage in the onSuccess callback effectively addresses the reported caching issue (issue #2193) where the API name remained cached after renaming. These minimal changes solve the problem without introducing unnecessary complexity or potential side effects.

The implementation aligns well with the PR objectives and should ensure that the API name updates consistently and accurately upon saving changes, as expected.

Also applies to: 49-49

apps/dashboard/app/(app)/ratelimits/[namespaceId]/settings/update-namespace-name.tsx (1)

Line range hint 1-93: Summary: Changes effectively address the caching issue

The modifications to this file successfully tackle the caching problem described in issue #2193. By introducing the revalidateMyTag function and calling it in the onSuccess callback of the updateName mutation, the code ensures that the API name is updated immediately after a rename operation.

Key points:

  1. The changes are minimal and focused, reducing the risk of introducing new issues.
  2. The implementation aligns well with the PR objectives and the linked issue.
  3. The code maintains good React practices and overall structure.

These changes should resolve the issue where the old API name remained cached in the header after renaming. Users should now see the updated name reflected immediately, improving the user experience and reducing confusion.

To ensure the changes are working as expected across the application, please run the following verification script:

This script will help ensure that the revalidateMyTag function is used consistently and that there are no remaining instances of outdated caching methods.

apps/dashboard/app/(app)/authorization/permissions/[permissionId]/client.tsx (1)

3-3: LGTM: New import aligns with PR objective.

The addition of revalidateMyTag import is appropriate for addressing the caching issue mentioned in the PR objectives. This function will likely be used to invalidate the cache after updating a permission.

apps/dashboard/app/(app)/authorization/roles/[roleId]/update-role.tsx (3)

3-3: LGTM: New import statement added correctly.

The import statement for revalidateMyTag is properly added and follows the correct syntax. This function seems to be related to cache invalidation, which aligns with the PR objective of fixing the caching issue.


Line range hint 1-145: Overall, the changes look good and address the caching issue.

The addition of the revalidateMyTag function and its usage in the onSuccess callback of the updateRole mutation is a targeted solution to the caching problem described in the PR objectives and the linked issue #2193. The rest of the component remains unchanged, which is appropriate given the specific nature of the fix.

To ensure the effectiveness of this solution:

  1. Thoroughly test the renaming functionality, especially with multiple consecutive renames.
  2. Verify that the breadcrumb in the header updates immediately after renaming an API.
  3. Consider adding a unit or integration test to prevent regression of this issue in the future.

63-63: Verify if this change resolves the caching issue completely.

The addition of revalidateMyTag(\role-${role.id}`)in theonSuccess` callback is a good approach to invalidate the cache for the specific role after an update. This change directly addresses the caching issue mentioned in the PR objectives.

However, to ensure this fully resolves the issue described in #2193:

  1. Verify that this change updates the API name in the header immediately after renaming.
  2. Test multiple consecutive renames to confirm the cache is consistently invalidated.

To verify the fix, please run the following commands:

These commands will help ensure that the cache invalidation is consistently applied across the codebase for role-related operations.

Comment on lines 28 to 29
["roleById"],
{ tags: [`role-${props.params.roleId}`] },
Copy link
Contributor

@coderabbitai coderabbitai bot Oct 5, 2024

Choose a reason for hiding this comment

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

💡 Codebase verification

Role-related caching mechanisms not found

The search did not find any role-related caching mechanisms in the codebase. This suggests that the changes might not fully address the PR objectives related to granular caching for roles.

🔗 Analysis chain

Verify alignment between changes and PR objectives

The implemented caching mechanism should address the issue of names not updating immediately after renaming. However, there's a potential discrepancy between the PR description (which mentions API names) and the actual changes (which are specific to roles).

Could you please clarify if:

  1. The term "API" in the PR description is being used to refer to roles?
  2. If not, are there additional changes needed to address API name caching?

To help verify this, you can run the following script to check for any API-related caching mechanisms in the codebase:

This will help ensure that we're addressing all necessary caching issues as described in the PR objectives.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for API-related caching mechanisms

# Test: Search for API-related caching. Expect: Occurrences of API caching if present.
rg --type typescript -i "cache.*api"

# Test: Search for role-related caching. Expect: At least one occurrence (the one we just reviewed).
rg --type typescript -i "cache.*role"

Length of output: 148


Script:

#!/bin/bash
# Description: Search for API-related caching mechanisms in TypeScript files

# Test: Search for API-related caching. Expect: Occurrences of API caching if present.
rg --glob '**/*.ts?(x)' -i "cache.*api"

# Test: Search for role-related caching. Expect: At least one occurrence (the one we just reviewed).
rg --glob '**/*.ts?(x)' -i "cache.*role"

Length of output: 382


Script:

#!/bin/bash
# Description: Verify the presence of TypeScript files and search for caching mechanisms

# Step 1: List all TypeScript files to ensure they exist
echo "Listing all TypeScript files (.ts and .tsx):"
fd --type f --ext ts --ext tsx

# Step 2: Search for API-related caching mechanisms in TypeScript files
echo "Searching for API-related caching mechanisms:"
rg --glob '*.ts' -i "cache.*api" || echo "No API-related caching mechanisms found."

# Step 3: Search for role-related caching mechanisms in TypeScript files
echo "Searching for role-related caching mechanisms:"
rg --glob '*.ts' -i "cache.*role" || echo "No role-related caching mechanisms found."

Length of output: 2732


Script:

#!/bin/bash
# Description: Verify the presence of TypeScript files and search for caching mechanisms

# Step 1: List all TypeScript files to ensure they exist
echo "Listing all TypeScript files (.ts and .tsx):"
fd --type f --extension ts --extension tsx

# Step 2: Search for API-related caching mechanisms in TypeScript files
echo "Searching for API-related caching mechanisms:"
rg --glob '*.ts' -i "cache.*api" || echo "No API-related caching mechanisms found."

# Step 3: Search for role-related caching mechanisms in TypeScript files
echo "Searching for role-related caching mechanisms:"
rg --glob '*.ts' -i "cache.*role" || echo "No role-related caching mechanisms found."

Length of output: 47685

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Suggested change
["roleById"],
{ tags: [`role-${props.params.roleId}`] },
["roleById"],
{ tags: [`role-${props.params.roleId}`] },

please check authorization/permissions/roles/[roleId]/update-role.tsx
we are revalidating the tag!

Copy link
Contributor

Choose a reason for hiding this comment

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

@AkshayBandi027, thank you for pointing that out. I see that in authorization/roles/[roleId]/update-role.tsx, you are revalidating the tag role-${role.id} after updating a role. This ensures that the role-related caching mechanism is properly handled. My apologies for any confusion earlier.


✏️ Learnings added
Learnt from: AkshayBandi027
PR: unkeyed/unkey#2215
File: apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx:28-29
Timestamp: 2024-10-05T17:45:28.776Z
Learning: In `authorization/roles/[roleId]/update-role.tsx`, the tag `role-${role.id}` is revalidated after updating a role to ensure that the caching mechanism is properly handled for roles.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@@ -1,5 +1,6 @@
"use client";

import { revalidateMyTag } from "@/app/(app)/apis/[apiId]/settings/actions";
Copy link
Contributor

@coderabbitai coderabbitai bot Oct 5, 2024

Choose a reason for hiding this comment

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

💡 Codebase verification

Multiple Cache Invalidation Instances Detected

The verification scripts identified numerous instances of revalidateMyTag and various caching mechanisms across the codebase. To ensure comprehensive resolution of the caching issue, please review and verify cache invalidation consistently in the following areas:

  • Authorization Permissions:
    apps/dashboard/app/(app)/authorization/permissions/[permissionId]/client.tsx
    apps/dashboard/app/(app)/authorization/roles/[roleId]/update-role.tsx

  • Ratelimits Settings:
    apps/dashboard/app/(app)/ratelimits/[namespaceId]/settings/update-namespace-name.tsx
    apps/dashboard/app/(app)/ratelimits/[namespaceId]/settings/delete-namespace.tsx

  • API Settings:
    apps/dashboard/app/(app)/apis/[apiId]/settings/update-api-name.tsx
    apps/dashboard/app/(app)/apis/[apiId]/settings/delete-api.tsx

  • Caching Mechanisms:
    internal/metrics/src/index.ts
    packages/cache/src/tiered.ts
    packages/cache/src/swr.ts

Please ensure that cache invalidation is appropriately handled in these and other identified areas to maintain consistent application behavior.

🔗 Analysis chain

Verify the fix resolves the caching issue.

The changes implemented here directly address the caching issue described in the PR objectives and the linked issue #2193. By invalidating the cache after a successful permission update, the API name should now update correctly in the header after a rename operation.

To ensure the fix is comprehensive:

  1. Verify that the cache invalidation works for multiple consecutive renames.
  2. Check if there are any other components or pages that might need similar cache invalidation for consistency.

To help verify the fix, you can run the following script to check for any other potential cache-related issues:

This script will help identify any other areas in the codebase that might benefit from similar cache invalidation techniques.

Also applies to: 51-51


Updated Verification Scripts to Address TypeScript File Recognition Issue

Please run the updated scripts to gather the necessary information for verifying the cache invalidation fix.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for other potential cache-related issues in the codebase.

# Test 1: Look for other usages of updatePermission that might need cache invalidation
echo "Searching for other updatePermission usages:"
rg "updatePermission.*useMutation" --type typescript

# Test 2: Check for other revalidateMyTag usages to ensure consistent implementation
echo "Searching for other revalidateMyTag usages:"
rg "revalidateMyTag" --type typescript

# Test 3: Look for potential caching mechanisms that might need updating
echo "Searching for potential caching mechanisms:"
rg "cache|revalidate|stale" --type typescript

Length of output: 539


Script:

# 
#!/bin/bash
# Description: Search for other potential cache-related issues in the codebase.

# Test 1: Look for other usages of updatePermission that might need cache invalidation
echo "Searching for other updatePermission usages:"
rg "updatePermission.*useMutation" -g "*.ts" -g "*.tsx"

# Test 2: Check for other revalidateMyTag usages to ensure consistent implementation
echo "Searching for other revalidateMyTag usages:"
rg "revalidateMyTag" -g "*.ts" -g "*.tsx"

# Test 3: Look for potential caching mechanisms that might need updating
echo "Searching for potential caching mechanisms:"
rg "cache|revalidate|stale" -g "*.ts" -g "*.tsx"

Length of output: 54580

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should I make specific actions.ts file for dashboard that can be reused across the dashboard ! Leave as it is!

Copy link
Contributor

Choose a reason for hiding this comment

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

@AkshayBandi027, creating a specific actions.ts file that can be reused across the dashboard is a great idea. This approach promotes code reuse and makes the codebase more maintainable. By centralizing common actions, such as revalidateMyTag, you can reduce duplication and ensure consistency across different components.

Here's how you might proceed:

  1. Create a shared actions.ts file:

    • Place it in a common directory within the dashboard app, for example:
      apps/dashboard/app/(app)/actions.ts
  2. Move common action functions into this file:

    • Transfer functions like revalidateMyTag to the new shared actions.ts file.
  3. Update import statements:

    • In files where these actions are used, update the import paths to reference the new shared location:
      // Before
      import { revalidateMyTag } from "@/app/(app)/apis/[apiId]/settings/actions";
      // After
      import { revalidateMyTag } from "@/app/(app)/actions";

By consolidating these actions, you ensure that any updates or fixes to them are reflected throughout the dashboard without the need to modify multiple files. This will also make it easier for other developers to find and use these shared actions.

However, if these actions are only used in specific parts of the dashboard and not elsewhere, you might decide to leave them as they are to keep related code together. It depends on how widely these actions are needed.

Let me know if you have any questions or need further assistance!

@perkinsjr perkinsjr changed the title fix:breadcrum-cache-issue fix: breadcrumb cache issue Oct 5, 2024
Copy link
Collaborator

@chronark chronark left a comment

Choose a reason for hiding this comment

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

I wonder if it's worth it to create a typesafe wrapper for cache tags

The problem right now is that a simple typo in one of the tags can cause really hard to debug problems.

wdyt?


export async function revalidate() {
await revalidatePath("/", "layout");
}

export async function revalidateMyTag(tag: string) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

what's the purpose of this function?
why don't we just import revalidateTag from next/cache in our components?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we can't use revalidateTag in client side, we are creating wrapper around to use it in client side !

Copy link
Collaborator

Choose a reason for hiding this comment

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

aah gotcha, makes sense

but then let's reexport it as the same name, revalidateMyTag looks weird

Copy link
Contributor Author

Choose a reason for hiding this comment

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

"Agreed, a typesafe wrapper for cache tags would help prevent typos and make debugging easier.

Copy link
Contributor Author

@AkshayBandi027 AkshayBandi027 Oct 7, 2024

Choose a reason for hiding this comment

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

aah gotcha, makes sense

but then let's reexport it as the same name, revalidateMyTag looks weird

Ok ! "Should we make any other changes or does everything look fine to you?"

@AkshayBandi027
Copy link
Contributor Author

AkshayBandi027 commented Oct 7, 2024

I wonder if it's worth it to create a typesafe wrapper for cache tags

The problem right now is that a simple typo in one of the tags can cause really hard to debug problems.

wdyt?

@chronark, what do you think of this approach

export const createCacheKeyForSolutions = (slug: string) => challenge-${slug}-solutions; export const createCacheKeyForSharedSolutionsTab = (userId: string) => ${userId}-shared-solutions`;

revalidateTag(createCacheKeyForSolutions(slug));
`
https://github.com/typehero/typehero/blob/main/apps/web/src/app/challenge/%5Bslug%5D/solutions/_components/_actions.ts

In TYPEHERO they these to create cache key to revalidated by tags

@perkinsjr
Copy link
Collaborator

export const createCacheKeyForSolutions = (slug: string) => challenge-${slug}-solutions; export const createCacheKeyForSharedSolutionsTab = (userId: string) => ${userId}-shared-solutions`;

This is fine approach.

I trust that Trashh knows what he is doing.

@chronark
Copy link
Collaborator

chronark commented Oct 7, 2024

I wonder if it's worth it to create a typesafe wrapper for cache tags
The problem right now is that a simple typo in one of the tags can cause really hard to debug problems.
wdyt?

@chronark, what do you think of this approach

export const createCacheKeyForSolutions = (slug: string) => challenge-${slug}-solutions; export const createCacheKeyForSharedSolutionsTab = (userId: string) => ${userId}-shared-solutions`;

revalidateTag(createCacheKeyForSolutions(slug)); ` https://github.com/typehero/typehero/blob/main/apps/web/src/app/challenge/%5Bslug%5D/solutions/_components/_actions.ts

In TYPEHERO they these to create cache key to revalidated by tags

why do you prefer functions over string literals?

type CacheKeyApi = `api-${string}`
type CacheKeyPermission = `permission-${string}`

type CacheKey = CacheKeyApi | CacheKeyPermission | ...

export function revalidate(key CacheKey) {
...
}

@AkshayBandi027
Copy link
Contributor Author

AkshayBandi027 commented Oct 8, 2024

I wonder if it's worth it to create a typesafe wrapper for cache tags

The problem right now is that a simple typo in one of the tags can cause really hard to debug problems.
wdyt?

@chronark, what do you think of this approach
export const createCacheKeyForSolutions = (slug: string) => challenge-${slug}-solutions; export const createCacheKeyForSharedSolutionsTab = (userId: string) => ${userId}-shared-solutions; revalidateTag(createCacheKeyForSolutions(slug)); https://github.com/typehero/typehero/blob/main/apps/web/src/app/challenge/%5Bslug%5D/solutions/_components/_actions.ts
In TYPEHERO they these to create cache key to revalidated by tags

why do you prefer functions over string literals?

type CacheKeyApi = `api-${string}`
type CacheKeyPermission = `permission-${string}`

type CacheKey = CacheKeyApi | CacheKeyPermission | ...

export function revalidate(key CacheKey) {
...
}

why preferred functions because we can use the function while assigning the tag and pass during revalidation in revalidateTag - it can used across and probably there is lesser chance typo and probably easier to debug.

image

-- Creating CacheKey function and passed to revalidateTag
https://github.com/typehero/typehero/blob/main/apps/web/src/app/challenge/_components/bookmark.action.ts
-- reused to assign tag
https://github.com/typehero/typehero/blob/main/apps/web/src/app/(profile)/%5Busername%5D/bookmarks/page.tsx

@chronark
Copy link
Collaborator

chronark commented Oct 10, 2024

fair,

can we group it into a single export though, that'll make it much cleaner to import and use

something like:

export const tags = {
  api: (apiId: string): string => {
    return `api-${apiId}`
  },
}

then you can use it as { tags: [tags.api(apiId) ]}

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

🧹 Outside diff range and nitpick comments (27)
apps/dashboard/lib/cache.ts (1)

1-6: LGTM! Consider these improvements for enhanced robustness and maintainability.

The tags constant is well-structured and provides a clean interface for generating standardized tag strings. The use of arrow functions and template literals makes the code concise and readable. However, there are a few suggestions to further improve the code:

  1. Add input validation to ensure non-empty strings:
export const tags = {
  api: (apiId: string): string => {
    if (!apiId) throw new Error('apiId must not be empty');
    return `api-${apiId}`;
  },
  // Apply similar validation to other methods
};
  1. Consider using an enum or constant for the prefix strings to improve maintainability:
const TAG_PREFIXES = {
  API: 'api',
  PERMISSION: 'permission',
  NAMESPACE: 'namespace',
  ROLE: 'role',
} as const;

export const tags = {
  api: (apiId: string): string => `${TAG_PREFIXES.API}-${apiId}`,
  // Use similar pattern for other methods
};
  1. Add JSDoc comments to explain the purpose and usage of the tags object:
/**
 * Provides methods to generate standardized cache tag strings for various entities.
 * These tags can be used for cache invalidation and management.
 */
export const tags = {
  /**
   * Generates a cache tag for an API.
   * @param apiId - The unique identifier of the API.
   * @returns A formatted cache tag string.
   */
  api: (apiId: string): string => `api-${apiId}`,
  // Add similar comments for other methods
};

These improvements will enhance the robustness and maintainability of the code.

apps/dashboard/components/ui/input.tsx (1)

13-13: LGTM! Consider adjusting the hover opacity for better contrast.

The addition of the hover effect (hover:border-primary/30) enhances the user experience by providing visual feedback. This change is consistent with the existing focus effect and doesn't introduce any functional changes.

Consider adjusting the opacity of the hover effect for better contrast. The current 30% opacity might be subtle; increasing it to 50% could provide a more noticeable effect:

-"flex h-8 w-full rounded-md border border-border bg-background px-3 py-2 text-sm focus:border-primary hover:border-primary/30 placeholder:text-content-subtle focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50",
+"flex h-8 w-full rounded-md border border-border bg-background px-3 py-2 text-sm focus:border-primary hover:border-primary/50 placeholder:text-content-subtle focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50",

This suggestion is purely aesthetic and optional. The current implementation is already an improvement.

.github/ISSUE_TEMPLATE/ossgg_sidequest.yml (1)

4-7: Remove trailing spaces for better YAML formatting.

There are trailing spaces on lines 4 and 7. While this doesn't affect functionality, removing them improves code cleanliness and adheres to YAML best practices.

Apply this diff to remove the trailing spaces:

-labels: 
+labels:
   - "🕹️ oss.gg, player submission"
   - "Needs Approval"
- 
+ 
🧰 Tools
🪛 yamllint

[error] 4-4: trailing spaces

(trailing-spaces)


[error] 7-7: trailing spaces

(trailing-spaces)

oss.gg/3_follow_the_unkey_x_account.md (2)

28-30: Remove angle brackets from the link for consistency.

The link format for this entry is inconsistent with others. Please remove the angle brackets <> around the URL.

Apply this change:

-» Link to Account: <https://x.com/chirag8023>
+» Link to Account: https://x.com/chirag8023

32-53: Markdownlint warnings about bare URLs can be ignored.

The Markdownlint tool is flagging bare URLs in the entries, but these are intentional and part of the specified format for this file. These warnings can be safely ignored.

If you want to suppress these warnings in the future, you can add a .markdownlint.json file to the root of your project with the following content:

{
  "MD034": false
}

This will disable the "no-bare-urls" rule (MD034) for the entire project.

🧰 Tools
🪛 Markdownlint

32-32: null
Bare URL used

(MD034, no-bare-urls)


35-35: null
Bare URL used

(MD034, no-bare-urls)


38-38: null
Bare URL used

(MD034, no-bare-urls)


41-41: null
Bare URL used

(MD034, no-bare-urls)


44-44: null
Bare URL used

(MD034, no-bare-urls)


47-47: null
Bare URL used

(MD034, no-bare-urls)


50-50: null
Bare URL used

(MD034, no-bare-urls)


53-53: null
Bare URL used

(MD034, no-bare-urls)

apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/keys/[keyAuthId]/page.tsx (1)

Inconsistent Cache Tag Usage Detected

The search revealed that multiple TypeScript files use different patterns for cache tags:

  • { tags: [tags.api(props.params.apiId)] }
  • { tags: [api-${props.params.apiId}] }

This inconsistency can lead to cache invalidation issues and complicate maintenance.

Affected Files:

  • apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/settings/page.tsx
  • apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/keys/[keyAuthId]/page.tsx

Recommendation:
Standardize the cache tag usage across the codebase to ensure consistent cache behavior and simplify future maintenance.

🔗 Analysis chain

Line range hint 23-41: LGTM: Improved caching mechanism for API data.

The changes to the getApiById cache configuration should address the issue of API names not updating correctly after renaming. This new approach using tags.api() provides a more robust way to invalidate the cache when the API data changes.

Consider reviewing other parts of the application where similar caching mechanisms are used to ensure consistency across the codebase.

To ensure this change is consistently applied, let's check for other occurrences of cache tag usage:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other cache tag usages
rg --type typescript 'tags: \[(`[^`]+`|tags\.[a-zA-Z]+\([^\)]+\))\]'

Length of output: 105


Script:

#!/bin/bash
# Search for other cache tag usages in TypeScript files
rg 'tags:\s*\[(`[^`]+`|tags\.[a-zA-Z]+\([^\)]+\))\]' --type-add 'ts=*.{ts,tsx}' --type ts

Length of output: 151


Script:

#!/bin/bash
# Search for other cache tag usages in TypeScript files with corrected type definition
rg 'tags:\s*\[(`[^`]+`|tags\.[a-zA-Z]+\([^\)]+\))\]' --type-add 'ts:*.ts,*.tsx' --type ts

Length of output: 1477

🧰 Tools
🪛 Biome

[error] 36-37: Expected an expression for the left hand side of the << operator.

This operator requires a left hand side value

(parse)


[error] 37-37: Expected an expression but instead found '<<'.

Expected an expression here.

(parse)


[error] 37-37: Expected an expression but instead found '<<'.

Expected an expression here.

(parse)


[error] 38-38: expected ... but instead found tags

Remove tags

(parse)


[error] 38-38: expected } but instead found :

Remove :

(parse)


[error] 38-38: Expected a JSX attribute but instead found '.'.

Expected a JSX attribute here.

(parse)


[error] 38-38: Expected a JSX attribute but instead found '('.

Expected a JSX attribute here.

(parse)


[error] 38-38: Expected a JSX attribute but instead found '.'.

Expected a JSX attribute here.

(parse)


[error] 38-38: Expected a JSX attribute but instead found '.'.

Expected a JSX attribute here.

(parse)


[error] 38-38: Expected a JSX attribute but instead found ')]'.

Expected a JSX attribute here.

(parse)


[error] 38-38: Unexpected token. Did you mean {'}'} or &rbrace;?

(parse)


[error] 40-40: expected } but instead found :

Remove :

(parse)


[error] 40-40: Unexpected token. Did you mean {'}'} or &rbrace;?

(parse)


[error] 40-41: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 41-41: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 41-41: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 41-41: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 41-41: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 41-41: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 41-41: Unexpected token. Did you mean {'>'} or &gt;?

(parse)

apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/settings/page.tsx (1)

Line range hint 20-69: Overall improvement in cache management.

The changes to the AsyncPageBreadcrumb component enhance the caching mechanism without altering the main functionality. The use of dynamic tags allows for more granular cache invalidation, which is a positive improvement.

Consider extracting the cache configuration into a separate constant or function to improve readability and maintainability. For example:

const getApiByIdCacheConfig = (apiId: string) => ({
  tags: [tags.api(apiId)],
});

// Usage
const getApiById = cache(
  async (apiId: string) => /* ... */,
  ["apiById"],
  getApiByIdCacheConfig(props.params.apiId)
);

This approach would make it easier to manage cache configurations across different queries if needed in the future.

🧰 Tools
🪛 Biome

[error] 33-34: Expected an expression for the left hand side of the << operator.

This operator requires a left hand side value

(parse)


[error] 34-34: Expected an expression but instead found '<<'.

Expected an expression here.

(parse)


[error] 34-34: Expected an expression but instead found '<<'.

Expected an expression here.

(parse)


[error] 35-35: expected ... but instead found tags

Remove tags

(parse)


[error] 35-35: expected } but instead found :

Remove :

(parse)


[error] 35-35: Expected a JSX attribute but instead found '.'.

Expected a JSX attribute here.

(parse)


[error] 35-35: Expected a JSX attribute but instead found '('.

Expected a JSX attribute here.

(parse)


[error] 35-35: Expected a JSX attribute but instead found '.'.

Expected a JSX attribute here.

(parse)


[error] 35-35: Expected a JSX attribute but instead found '.'.

Expected a JSX attribute here.

(parse)


[error] 35-35: Expected a JSX attribute but instead found ')]'.

Expected a JSX attribute here.

(parse)


[error] 35-35: Unexpected token. Did you mean {'}'} or &rbrace;?

(parse)


[error] 37-37: expected } but instead found :

Remove :

(parse)


[error] 37-37: Unexpected token. Did you mean {'}'} or &rbrace;?

(parse)


[error] 37-38: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 38-38: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 38-38: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 38-38: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 38-38: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 38-38: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 38-38: Unexpected token. Did you mean {'>'} or &gt;?

(parse)

apps/docs/libraries/ts/sdk/keys/verifications.mdx (2)

72-77: RequestExample updated correctly.

The RequestExample has been updated to use the new getVerifications method, which is correct.

Consider adding an additional example using ownerId instead of keyId to demonstrate both ways of using the method. For instance:

const { result, error } = await unkey.keys.getVerifications({ ownerId: "owner_123" });

This would provide a more comprehensive guide for API users.


Line range hint 79-115: ResponseExample updated correctly.

The ResponseExample has been updated to use the new getVerifications method in both the Success and Error scenarios, which is correct.

Consider adding more comments to explain the error handling process. For example, in the Error example:

const { result, error } = await unkey.keys.getVerifications({ keyId: "key_123" });

if (error) {
  console.log(error.message);
  // => "Key not found"
  // Handle the error appropriately, e.g., show an error message to the user
} else {
  // Process the result
  console.log(result.verifications);
}

This would provide more guidance on how to handle different scenarios when using the API.

oss.gg/7_create_a_template.md (3)

3-5: LGTM with a minor suggestion.

The updated instructions provide clearer guidance and specific examples, which is beneficial for contributors. However, there's a minor grammatical improvement that can be made.

Consider adding a comma after "For example" for better readability:

-Create a minimal starter template to showcase how you can use Unkey with a particular framework. For example [Ratelimit your Next.js routes](https://www.unkey.com/templates/ratelimit-nextjs) or [Middleware for golang's echo framework](https://www.unkey.com/templates/echo-middleware).
+Create a minimal starter template to showcase how you can use Unkey with a particular framework. For example, [Ratelimit your Next.js routes](https://www.unkey.com/templates/ratelimit-nextjs) or [Middleware for golang's echo framework](https://www.unkey.com/templates/echo-middleware).
🧰 Tools
🪛 LanguageTool

[typographical] ~4-~4: After the expression ‘for example’ a comma is usually used.
Context: ... Unkey with a particular framework. For example [Ratelimit your Next.js routes](https:/...

(COMMA_FOR_EXAMPLE)


40-40: LGTM with a minor formatting suggestion.

The new entry for October 11, 2024, has been added correctly. However, there's a minor spacing issue in the link text.

To address the Markdownlint warning (MD039), remove the space before the closing bracket in the link text:

-» 11-October-2024 by Prabin Subedi [Starter template for Unkey Route protecttion in  Hono Webframework in Cloudflare workers ](https://github.com/prabincankod/hono-unkey-cflare)
+» 11-October-2024 by Prabin Subedi [Starter template for Unkey Route protecttion in  Hono Webframework in Cloudflare workers](https://github.com/prabincankod/hono-unkey-cflare)
🧰 Tools
🪛 Markdownlint

40-40: null
Spaces inside link text

(MD039, no-space-in-links)


42-42: Suggestion: Maintain chronological order of entries.

The new entry for October 10, 2024, has been added correctly. However, it's currently out of chronological order, which may cause confusion for readers.

Consider reordering the entries to maintain a consistent chronological sequence. This entry should be moved above the October 11, 2024 entry:

» 10-October-2024 by Novin Noori [Protect and Rate Limit Rust + Actix Web API with Unkey](https://github.com/djnovin/unkey-rust-actix)
» 10-October-2024 by Devansh Baghel [Deno Unkey Ratelimit Starter](https://github.com/Devansh-Baghel/deno-unkey-ratelimit-starter)
+» 10-October-2024 by Harsh Bhat [FastAPI Unkey Boilerplate](https://github.com/harshsbhat/unkey-fastapi-boilerplate)
» 11-October-2024 by Prabin Subedi [Starter template for Unkey Route protecttion in  Hono Webframework in Cloudflare workers](https://github.com/prabincankod/hono-unkey-cflare)
-» 10-October-2024 by Harsh Bhat [FastAPI Unkey Boilerplate](https://github.com/harshsbhat/unkey-fastapi-boilerplate)
apps/api/src/routes/v1_identities_createIdentity.error.test.ts (2)

42-74: LGTM: Well-structured test case for duplicate identity

The new test case for handling duplicate identity creation is well-structured and covers an important edge case. It follows the Arrange-Act-Assert pattern and correctly sets up the test environment.

Consider adding a comment explaining the significance of the 412 status code (Precondition Failed) for better clarity:

// 412 Precondition Failed indicates that the server doesn't meet one of the preconditions specified in the request headers
expect(res.status).toEqual(412);

Line range hint 18-41: Consider updating existing tests for consistency

The new test case uses ErrorResponse as the response type, while the existing tests use V1IdentitiesCreateIdentityResponse. For consistency and to ensure all error cases are handled uniformly, consider updating the existing tests to use ErrorResponse as well.

Here's a suggested change for the existing test:

- const res = await h.post<V1IdentitiesCreateIdentityRequest, V1IdentitiesCreateIdentityResponse>(
+ const res = await h.post<V1IdentitiesCreateIdentityRequest, ErrorResponse>(

This change would make the error handling consistent across all test cases.

apps/www/components/changelog/changelog-grid-item.tsx (1)

Line range hint 1-78: Consider performance optimizations for the ChangelogGridItem component.

While the current change is appropriate, here are some suggestions to further improve the component:

  1. Memoization: Consider wrapping the ChangelogGridItem with React.memo() to prevent unnecessary re-renders if the props don't change frequently.

  2. Image optimization: The ImageWithBlur component is used for the changelog image. Ensure that this component is optimized for performance, possibly using next/image with appropriate loading strategies.

  3. Date formatting: The date formatting is done inline. Consider moving this to a utility function or using a library like date-fns for more efficient and consistent date handling.

  4. Prop types: Consider using TypeScript to define more specific types for the changelog prop, which could help catch potential issues earlier in development.

Would you like me to provide code examples for any of these suggestions?

apps/www/app/blog/page.tsx (1)

115-128: Approve with suggestion: Consider refactoring for improved readability

The addition of the conditional rendering for the BlogHero component is a good defensive programming practice. It prevents potential errors that could occur if trying to render the hero section with an empty posts array.

However, to improve readability, consider refactoring the conditional rendering as follows:

if (posts.length > 0) {
  return (
    <div className="w-full px-0 mx-0 rounded-3xl">
      <Link href={`${posts[0].url}`} key={posts[0].url}>
        <BlogHero
          tags={posts[0].tags}
          imageUrl={posts[0].image ?? "/images/blog-images/defaultBlog.png"}
          title={posts[0].title}
          subTitle={posts[0].description}
          author={authors[posts[0].author]}
          publishDate={posts[0].date}
        />
      </Link>
    </div>
  );
}

This approach maintains the original indentation and improves code readability while achieving the same functionality.

apps/dashboard/app/(app)/apis/[apiId]/settings/delete-api.tsx (3)

84-87: LGTM: Improved dialog state management

The new handleDialogOpenChange function enhances code organization by extracting the dialog open state logic. It improves maintainability by combining the state update and form reset into a single function.

Consider adding a comment explaining why the form needs to be reset when the dialog state changes, as this might not be immediately obvious to other developers:

function handleDialogOpenChange(newState: boolean) {
  setOpen(newState);
  // Reset the form when closing the dialog to clear any partial input
  form.reset();
}

Line range hint 66-66: Consider applying typesafe approach to revalidate function

In light of the discussion in the PR comments about creating typesafe wrappers for cache-related functions, consider applying a similar approach to the revalidate function. This could enhance type safety and make the code more robust.

Here's a suggestion for how you might implement this:

  1. Create a new file, e.g., cacheUtils.ts:
export const createCacheKey = <T extends string>(key: T) => () => key;

export const cacheKeys = {
  apis: createCacheKey('apis'),
  // Add other cache keys as needed
};

export const revalidate = async (keys: Array<keyof typeof cacheKeys>) => {
  // Implementation of revalidate function
};
  1. Update the import and usage in this file:
import { revalidate, cacheKeys } from './cacheUtils';

// In the onSuccess callback
await revalidate([cacheKeys.apis]);

This approach would provide type safety for cache keys and make it easier to manage them across the application.


Line range hint 1-190: Summary and Next Steps

The changes in this file improve code organization and maintainability, which is commendable. However, to fully address the PR objectives related to the breadcrumb cache issue, consider the following next steps:

  1. Verify that the breadcrumb updates correctly after API deletion.
  2. Implement a typesafe approach for cache-related functions, including the revalidate function.
  3. Review other components in the API management flow to ensure consistent handling of breadcrumb updates.

These steps will help ensure that the changes align more closely with the PR objectives and the discussions in the comments.

apps/api/src/routes/v1_identities_createIdentity.ts (2)

32-34: Approved: Improved documentation for externalId

The added description for the externalId field is valuable. It clarifies the uniqueness requirement across the workspace and specifies the error type for duplicates.

Consider adding an example of the PRECONDITION_FAILED error response in the OpenAPI schema to further assist API consumers.


Line range hint 162-249: Approved: Comprehensive audit logging with a suggestion

The implementation of audit logging is thorough, covering both identity and ratelimit creation events. The use of c.executionCtx.waitUntil for analytics ingestion is a good practice to avoid blocking the main execution.

Consider extracting the common audit log structure into a separate function to reduce code duplication between the database insertion and analytics ingestion.

apps/www/app/templates/client.tsx (1)

403-408: Improved layout for author information and navigation arrow.

The changes enhance the visual presentation and alignment of the author information and navigation arrow. The use of flexbox with justify-between ensures proper distribution of elements within the container.

Consider replacing the hardcoded h-24 class on the outer div with a more flexible height solution, such as min-h-24, to accommodate varying content lengths:

-<div className="flex flex-row w-full h-24 sm:mb-4 md:mb-0 items-end">
+<div className="flex flex-row w-full min-h-24 sm:mb-4 md:mb-0 items-end">

This change would maintain the minimum height while allowing the container to expand if needed, improving the component's adaptability to different content sizes.

apps/docs/libraries/ts/cache/overview.mdx (4)

Line range hint 653-815: Great addition of store explanations, consider minor improvements.

The new "Stores" section provides comprehensive explanations for various store types, which is very helpful for users. Here are a few suggestions to enhance it further:

  1. Consider adding a brief introduction to the "Stores" section before diving into specific store types.
  2. For consistency, you might want to add code examples for the Upstash Redis and libSQL stores, similar to the Memory and Cloudflare stores.
  3. In the libSQL section, it might be helpful to mention any performance considerations or use cases where this store type excels.

Overall, this addition significantly improves the documentation by providing clear explanations and setup instructions for each store type.


Line range hint 817-937: Well-structured middlewares section, consider minor enhancements.

The "Middlewares" section provides clear explanations for Metrics and Encryption middlewares, which is excellent. To further improve this section:

  1. Consider adding a brief introduction to middlewares and their purpose in the context of the cache library.
  2. For consistency with the "Stores" section, you might want to use the same heading level for "Metrics" and "Encryption" (currently they're one level lower).
  3. In the Encryption section, consider mentioning any performance implications of using encryption, if any.

The code examples and interface definitions are particularly helpful. Great job on providing clear instructions for generating encryption keys and implementing the middlewares.


Line range hint 939-941: Consider expanding the Contributing section.

The addition of a Contributing section is great for encouraging community involvement. To make it more helpful for potential contributors, consider expanding it with the following information:

  1. A link to the project's contribution guidelines or CONTRIBUTING.md file, if available.
  2. Brief instructions on how to set up the development environment.
  3. Information about the project's coding standards or style guide.
  4. Guidelines for submitting pull requests and reporting issues.

Expanding this section can help streamline the contribution process and encourage more developers to get involved.


Line range hint 1-941: Great documentation, consider improving overall structure and consistency.

The documentation provides comprehensive coverage of the cache library's features and concepts. To further enhance its usability:

  1. Consider adding a table of contents at the beginning of the document for easier navigation.
  2. Ensure consistent use of heading levels throughout the document.
  3. Add more cross-references between related sections to help users understand the connections between different concepts.
  4. Consider grouping related code examples in expandable sections to reduce scrolling for users who are familiar with the concepts.

These improvements can make the documentation even more user-friendly and easier to navigate, especially for new users of the library.

apps/api/src/pkg/keys/service.ts (1)

Line range hint 473-479: Potential issue when req.ratelimits is an empty array

In the condition:

if ("default" in data.ratelimits && typeof req.ratelimits === "undefined") {

If req.ratelimits is an empty array ([]), the typeof req.ratelimits will return 'object', and the default ratelimit will not be applied. This may lead to unintended behavior where the default ratelimit is skipped even when no specific ratelimits are provided.

Consider updating the condition to check if req.ratelimits is undefined or has a length of zero:

-if ("default" in data.ratelimits && typeof req.ratelimits === "undefined") {
+if (
+  "default" in data.ratelimits &&
+  (typeof req.ratelimits === "undefined" || req.ratelimits.length === 0)
+) {

This change ensures that the default ratelimit is applied when req.ratelimits is either undefined or an empty array.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between e7906ee and 6a05ff2.

⛔ Files ignored due to path filters (4)
  • apps/www/public/images/templates/deno-oak-ratelimit.png is excluded by !**/*.png
  • apps/www/public/images/templates/python-fastapi.png is excluded by !**/*.png
  • apps/www/public/images/templates/typescript-nestjs.png is excluded by !**/*.png
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (38)
  • .github/ISSUE_TEMPLATE/ossgg_sidequest.yml (1 hunks)
  • apps/api/src/pkg/audit.ts (5 hunks)
  • apps/api/src/pkg/keys/service.ts (1 hunks)
  • apps/api/src/routes/v1_identities_createIdentity.error.test.ts (2 hunks)
  • apps/api/src/routes/v1_identities_createIdentity.ts (3 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/keys/[keyAuthId]/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/settings/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/authorization/permissions/[permissionId]/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/logs/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/overrides/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/settings/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/apis/[apiId]/settings/actions.ts (1 hunks)
  • apps/dashboard/app/(app)/apis/[apiId]/settings/delete-api.tsx (4 hunks)
  • apps/dashboard/app/(app)/apis/[apiId]/settings/update-api-name.tsx (2 hunks)
  • apps/dashboard/app/(app)/audit/[bucket]/page.tsx (1 hunks)
  • apps/dashboard/app/(app)/authorization/permissions/[permissionId]/client.tsx (2 hunks)
  • apps/dashboard/app/(app)/authorization/roles/[roleId]/update-role.tsx (2 hunks)
  • apps/dashboard/app/(app)/ratelimits/[namespaceId]/settings/update-namespace-name.tsx (2 hunks)
  • apps/dashboard/app/(app)/ratelimits/page.tsx (1 hunks)
  • apps/dashboard/app/new/create-workspace.tsx (1 hunks)
  • apps/dashboard/components/ui/input.tsx (1 hunks)
  • apps/dashboard/lib/cache.ts (1 hunks)
  • apps/docs/libraries/ts/cache/overview.mdx (1 hunks)
  • apps/docs/libraries/ts/sdk/keys/verifications.mdx (1 hunks)
  • apps/www/app/blog/page.tsx (1 hunks)
  • apps/www/app/templates/client.tsx (1 hunks)
  • apps/www/app/templates/data.ts (2 hunks)
  • apps/www/components/analytics/analytics-bento.tsx (4 hunks)
  • apps/www/components/blog/blog-list.tsx (1 hunks)
  • apps/www/components/changelog/changelog-grid-item.tsx (1 hunks)
  • apps/www/package.json (1 hunks)
  • oss.gg/3_follow_the_unkey_x_account.md (1 hunks)
  • oss.gg/6_record_onboarding.md (1 hunks)
  • oss.gg/7_create_a_template.md (2 hunks)
  • packages/api/src/openapi.d.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • oss.gg/6_record_onboarding.md
🚧 Files skipped from review as they are similar to previous changes (12)
  • apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/page.tsx
  • apps/dashboard/app/(app)/@breadcrumb/authorization/permissions/[permissionId]/page.tsx
  • apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx
  • apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/logs/page.tsx
  • apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/overrides/page.tsx
  • apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/page.tsx
  • apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/settings/page.tsx
  • apps/dashboard/app/(app)/apis/[apiId]/settings/update-api-name.tsx
  • apps/dashboard/app/(app)/authorization/permissions/[permissionId]/client.tsx
  • apps/dashboard/app/(app)/authorization/roles/[roleId]/update-role.tsx
  • apps/dashboard/app/(app)/ratelimits/[namespaceId]/settings/update-namespace-name.tsx
  • apps/dashboard/app/(app)/ratelimits/page.tsx
🧰 Additional context used
🪛 yamllint
.github/ISSUE_TEMPLATE/ossgg_sidequest.yml

[error] 4-4: trailing spaces

(trailing-spaces)


[error] 7-7: trailing spaces

(trailing-spaces)

🪛 Biome
apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/keys/[keyAuthId]/page.tsx

[error] 37-37: Expected an expression but instead found '<<'.

Expected an expression here.

(parse)


[error] 37-37: Expected an expression but instead found '<<'.

Expected an expression here.

(parse)


[error] 38-38: expected ... but instead found tags

Remove tags

(parse)


[error] 38-38: expected } but instead found :

Remove :

(parse)


[error] 38-38: Expected a JSX attribute but instead found '.'.

Expected a JSX attribute here.

(parse)


[error] 38-38: Expected a JSX attribute but instead found '('.

Expected a JSX attribute here.

(parse)


[error] 38-38: Expected a JSX attribute but instead found '.'.

Expected a JSX attribute here.

(parse)


[error] 38-38: Expected a JSX attribute but instead found '.'.

Expected a JSX attribute here.

(parse)


[error] 38-38: Expected a JSX attribute but instead found ')]'.

Expected a JSX attribute here.

(parse)


[error] 38-38: Unexpected token. Did you mean {'}'} or &rbrace;?

(parse)


[error] 40-40: expected } but instead found :

Remove :

(parse)


[error] 40-40: Unexpected token. Did you mean {'}'} or &rbrace;?

(parse)


[error] 40-41: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 41-41: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 41-41: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 41-41: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 41-41: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 41-41: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 41-41: Unexpected token. Did you mean {'>'} or &gt;?

(parse)

apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/settings/page.tsx

[error] 34-34: Expected an expression but instead found '<<'.

Expected an expression here.

(parse)


[error] 34-34: Expected an expression but instead found '<<'.

Expected an expression here.

(parse)


[error] 35-35: expected ... but instead found tags

Remove tags

(parse)


[error] 35-35: expected } but instead found :

Remove :

(parse)


[error] 35-35: Expected a JSX attribute but instead found '.'.

Expected a JSX attribute here.

(parse)


[error] 35-35: Expected a JSX attribute but instead found '('.

Expected a JSX attribute here.

(parse)


[error] 35-35: Expected a JSX attribute but instead found '.'.

Expected a JSX attribute here.

(parse)


[error] 35-35: Expected a JSX attribute but instead found '.'.

Expected a JSX attribute here.

(parse)


[error] 35-35: Expected a JSX attribute but instead found ')]'.

Expected a JSX attribute here.

(parse)


[error] 35-35: Unexpected token. Did you mean {'}'} or &rbrace;?

(parse)


[error] 37-37: expected } but instead found :

Remove :

(parse)


[error] 37-37: Unexpected token. Did you mean {'}'} or &rbrace;?

(parse)


[error] 37-38: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 38-38: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 38-38: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 38-38: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 38-38: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 38-38: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 38-38: Unexpected token. Did you mean {'>'} or &gt;?

(parse)

apps/dashboard/app/(app)/apis/[apiId]/settings/actions.ts

[error] 5-5: This function is unused.

Unused variables usually are result of incomplete refactoring, typos and other source of bugs.

(lint/correctness/noUnusedVariables)

🪛 Markdownlint
oss.gg/3_follow_the_unkey_x_account.md

32-32: null
Bare URL used

(MD034, no-bare-urls)


35-35: null
Bare URL used

(MD034, no-bare-urls)


38-38: null
Bare URL used

(MD034, no-bare-urls)


41-41: null
Bare URL used

(MD034, no-bare-urls)


44-44: null
Bare URL used

(MD034, no-bare-urls)


47-47: null
Bare URL used

(MD034, no-bare-urls)


50-50: null
Bare URL used

(MD034, no-bare-urls)


53-53: null
Bare URL used

(MD034, no-bare-urls)

oss.gg/7_create_a_template.md

40-40: null
Spaces inside link text

(MD039, no-space-in-links)

🪛 LanguageTool
oss.gg/7_create_a_template.md

[typographical] ~4-~4: After the expression ‘for example’ a comma is usually used.
Context: ... Unkey with a particular framework. For example [Ratelimit your Next.js routes](https:/...

(COMMA_FOR_EXAMPLE)

🔇 Additional comments (59)
apps/dashboard/app/(app)/apis/[apiId]/settings/actions.ts (2)

5-7: Verify the usage and scope of the revalidate function

The revalidate function has been made private by removing the export keyword. However, this change raises a few concerns:

  1. The function is now flagged as unused by the static analysis tool. If this is intentional, consider removing the function entirely. If not, we need to ensure it's properly used within this module.

  2. The function revalidates the entire layout ("/", "layout"), which seems overly broad for API settings changes. Consider narrowing the scope of revalidation to improve performance.

  3. There's a discrepancy between this implementation and the past comments discussing a revalidateMyTag function. It's unclear if this represents a significant change in approach or if further modifications are needed.

To address these concerns, please run the following script:

#!/bin/bash
# Description: Verify the usage of the revalidate function and check for any remnants of revalidateMyTag

# Test 1: Check for usage of revalidate function within the module
echo "Checking for usage of revalidate function:"
rg --type typescript "revalidate\(\)" apps/dashboard/app/\(app\)/apis/\[apiId\]/settings/

# Test 2: Check for any remnants of revalidateMyTag
echo "Checking for remnants of revalidateMyTag:"
rg --type typescript "revalidateMyTag" apps/dashboard/app/

# Test 3: Check for other revalidation functions that might be more specific
echo "Checking for other revalidation functions:"
rg --type typescript "revalidate(Tag|Path)" apps/dashboard/app/

Based on the results, we may need to:

  1. Implement the function's usage if it's intended to be used.
  2. Adjust the revalidation scope to be more specific to API settings.
  3. Clarify the current caching strategy and how it relates to the previous discussions about revalidateMyTag.
🧰 Tools
🪛 Biome

[error] 5-5: This function is unused.

Unused variables usually are result of incomplete refactoring, typos and other source of bugs.

(lint/correctness/noUnusedVariables)


Line range hint 1-8: Verify alignment with PR objectives

The changes in this file appear minimal and don't fully address the PR objectives related to fixing the breadcrumb cache issue. The modifications to the revalidate function don't seem to directly solve the problem of API names remaining cached after renaming.

To ensure we're not missing any relevant changes, please run the following script:

Based on the results, we may need to:

  1. Review additional files that contain relevant changes.
  2. Ensure that the changes in this file are part of a larger solution that addresses the caching issue.
  3. Verify that the PR includes all necessary modifications to fix the breadcrumb cache problem.
🧰 Tools
🪛 Biome

[error] 5-5: This function is unused.

Unused variables usually are result of incomplete refactoring, typos and other source of bugs.

(lint/correctness/noUnusedVariables)

apps/www/components/blog/blog-list.tsx (3)

11-11: Review the overall impact of removing gap classes from list components.

The removal of 'gap-4' and 'gap-6' classes from both BlogList and BlogListNumbered components suggests a deliberate change in the spacing between list items. While this change is consistent across both components, it's important to consider the following:

  1. Does this change align with the PR objectives of fixing the breadcrumb cache issue?
  2. Is this a separate design improvement that should be documented?
  3. Have these changes been tested across different screen sizes to ensure proper responsiveness?

To ensure this change doesn't introduce any unintended side effects, please verify:

  1. The visual appearance of blog lists in various parts of the application.
  2. The responsiveness of these components on different devices.
  3. The consistency with the overall design system.

If this change is unrelated to the main PR objective, consider creating a separate PR for design updates to maintain clear separation of concerns.

Also applies to: 16-16


16-16: Verify the removal of 'gap-6' class and its impact on design.

The 'gap-6' class has been removed from the <ol> element's className. This change is consistent with the removal of 'gap-4' in the BlogList component and will affect the spacing between numbered list items. Please confirm if this change is intentional and aligns with the desired design. Consider the following:

  1. Does this change maintain consistency with other numbered list components in the application?
  2. Has the design team approved this modification?
  3. Are there any responsive design considerations affected by this change?

To help verify the impact and ensure consistency, you can run the following command to check for other occurrences of 'gap-6' in numbered list components:

This will help ensure consistency across the application.

✅ Verification successful

To address the issues with the previous search, please run the following corrected command to locate instances of the 'gap-6' class in ordered lists:


Verified the removal of 'gap-6' class with no remaining instances affecting design.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

rg --type typescript --type tsx 'className=.*gap-6.*(<ol)'

Length of output: 236


Script:

rg 'className=.*gap-6.*<ol' --glob '*.ts' --glob '*.tsx'

Length of output: 58


11-11: Verify the removal of 'gap-4' class and its impact on design.

The 'gap-4' class has been removed from the <ul> element's className. This will affect the spacing between list items. Please confirm if this change is intentional and aligns with the desired design. Consider the following:

  1. Does this change maintain consistency with other list components in the application?
  2. Has the design team approved this modification?
  3. Are there any responsive design considerations affected by this change?

To help verify the impact, you can run the following command to check for other occurrences of 'gap-4' in list components:

This will help ensure consistency across the application.

.github/ISSUE_TEMPLATE/ossgg_sidequest.yml (2)

4-6: Improved label structure for better issue tracking.

The separation of labels into distinct entries enhances clarity and issue management. The addition of the "Needs Approval" label will likely streamline the review process for hackathon submissions.

🧰 Tools
🪛 yamllint

[error] 4-4: trailing spaces

(trailing-spaces)


Line range hint 28-29: Clarify intention for empty validations on description field.

The validations section for the description field is empty, which is inconsistent with other fields in the template. Was this intentional? If not, consider adding the required: true validation to ensure users provide a description of their task.

If you'd like to make the description required, apply this diff:

    validations:
+     required: true
🧰 Tools
🪛 yamllint

[error] 4-4: trailing spaces

(trailing-spaces)


[error] 7-7: trailing spaces

(trailing-spaces)

oss.gg/3_follow_the_unkey_x_account.md (6)

31-33: LGTM!

The entry for Shreenarayan Jaiswal is correctly formatted and consistent with others.

🧰 Tools
🪛 Markdownlint

32-32: null
Bare URL used

(MD034, no-bare-urls)


34-36: LGTM!

The entry for Aritra Sadhukhan is correctly formatted and consistent with others.

🧰 Tools
🪛 Markdownlint

35-35: null
Bare URL used

(MD034, no-bare-urls)


37-39: LGTM!

The entry for Emily M. Ahtunan is correctly formatted and consistent with others.

🧰 Tools
🪛 Markdownlint

38-38: null
Bare URL used

(MD034, no-bare-urls)


40-42: LGTM!

The entry for Devang Rakholiya is correctly formatted and consistent with others.

🧰 Tools
🪛 Markdownlint

41-41: null
Bare URL used

(MD034, no-bare-urls)


49-51: LGTM!

The entry for Kunal Arya is correctly formatted and consistent with others.

🧰 Tools
🪛 Markdownlint

50-50: null
Bare URL used

(MD034, no-bare-urls)


52-54: LGTM!

The entry for Ayan Mondal is correctly formatted and consistent with others.

🧰 Tools
🪛 Markdownlint

53-53: null
Bare URL used

(MD034, no-bare-urls)

apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/keys/[keyAuthId]/page.tsx (1)

1-1: LGTM: New import for cache tags.

The addition of the tags import from "@/lib/cache" is appropriate for the new caching mechanism being introduced.

apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/settings/page.tsx (2)

14-14: LGTM: New import for cache tags.

The addition of the tags import from "@/lib/cache" is appropriate for the updated cache tagging system. This import aligns with the changes made to the caching mechanism.


Line range hint 1-69: Summary: Improved caching mechanism with minor issues to address.

The changes in this file improve the caching mechanism for the AsyncPageBreadcrumb component by introducing dynamic cache tags. This enhancement allows for more precise cache management based on the API ID.

Key points:

  1. The new import for tags is appropriate and necessary for the changes.
  2. There's a merge conflict that needs to be resolved, preferably using the dynamic tag approach.
  3. The overall functionality of the component remains intact, with improvements to cache management.

Next steps:

  1. Resolve the merge conflict.
  2. Consider the suggested refactoring to extract the cache configuration.
  3. Ensure all conflict markers are removed and the code compiles without errors.

After making the necessary changes, please run the following command to ensure the file is free of issues:

biome check apps/dashboard/app/\(app\)/@breadcrumb/apis/[apiId]/settings/page.tsx

This will help catch any remaining linting or formatting issues.

🧰 Tools
🪛 Biome

[error] 33-34: Expected an expression for the left hand side of the << operator.

This operator requires a left hand side value

(parse)


[error] 34-34: Expected an expression but instead found '<<'.

Expected an expression here.

(parse)


[error] 34-34: Expected an expression but instead found '<<'.

Expected an expression here.

(parse)


[error] 35-35: expected ... but instead found tags

Remove tags

(parse)


[error] 35-35: expected } but instead found :

Remove :

(parse)


[error] 35-35: Expected a JSX attribute but instead found '.'.

Expected a JSX attribute here.

(parse)


[error] 35-35: Expected a JSX attribute but instead found '('.

Expected a JSX attribute here.

(parse)


[error] 35-35: Expected a JSX attribute but instead found '.'.

Expected a JSX attribute here.

(parse)


[error] 35-35: Expected a JSX attribute but instead found '.'.

Expected a JSX attribute here.

(parse)


[error] 35-35: Expected a JSX attribute but instead found ')]'.

Expected a JSX attribute here.

(parse)


[error] 35-35: Unexpected token. Did you mean {'}'} or &rbrace;?

(parse)


[error] 37-37: expected } but instead found :

Remove :

(parse)


[error] 37-37: Unexpected token. Did you mean {'}'} or &rbrace;?

(parse)


[error] 37-38: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 38-38: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 38-38: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 38-38: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 38-38: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 38-38: Unexpected token. Did you mean {'>'} or &gt;?

(parse)


[error] 38-38: Unexpected token. Did you mean {'>'} or &gt;?

(parse)

apps/docs/libraries/ts/sdk/keys/verifications.mdx (4)

74-74: Method name updated correctly.

The method name has been updated from unkey.keys.get to unkey.keys.getVerifications. This change is consistent with the summary provided and improves the clarity of the API's purpose.


Line range hint 7-29: Verify completeness of Request parameters.

The Request section appears to be consistent with the new getVerifications method. However, please confirm that no additional parameters are required for this new method. If all parameters are correct and complete, this section can be approved.


Line range hint 32-67: Verify completeness of Response structure.

The Response section appears to be consistent with the expected output of the new getVerifications method. However, please confirm that no additional fields are returned by this new method. If all fields are correct and complete, this section can be approved.


Line range hint 1-115: Overall document review: Consistent and well-updated

The documentation has been successfully updated to reflect the new getVerifications method. The changes are consistent throughout the document, including the request examples and response examples. The structure and content of the document appropriately convey the API's functionality.

To further improve the documentation:

  1. Verify the completeness of the Request and Response sections as suggested in previous comments.
  2. Consider adding more diverse examples in the RequestExample section.
  3. Enhance the ResponseExample section with additional comments for clarity.

Once these minor improvements are addressed, the documentation will provide a comprehensive and clear guide for using the updated API.

oss.gg/7_create_a_template.md (3)

6-12: Improved formatting and clarity of requirements.

The bolding of the "Requirements" heading and the reformatted list improve readability and provide clearer guidelines for contributors. These changes will help ensure that submissions meet the necessary criteria.


13-13: Verify the significant increase in points allocation.

The points allocation has increased from a range of 150-300 to a fixed 750 points. This is a substantial change that may significantly impact the incentive structure of the project.

Could you confirm if this increase is intentional and aligns with the project's goals? If so, consider adding a brief explanation for the change to provide context for contributors.


37-39: LGTM: New contributions added.

The new entries for October 10, 2024, have been added correctly, maintaining consistency with the existing format. This demonstrates continued engagement with the project.

apps/api/src/routes/v1_identities_createIdentity.error.test.ts (2)

1-3: LGTM: New imports are correctly added

The new imports for ErrorResponse, schema, and newId are correctly added and necessary for the new test case. They follow the project's import style.


Line range hint 1-74: Overall, the changes improve test coverage and error handling

The additions to this test file enhance the error handling coverage by introducing a new test case for duplicate identity creation. The new imports and test case are well-structured and follow the project's conventions.

Two suggestions were made to further improve the code:

  1. Adding a comment to explain the 412 status code for better clarity.
  2. Updating the existing tests to use the ErrorResponse type for consistency.

These changes, along with the suggested improvements, will contribute to a more robust and maintainable test suite.

apps/www/package.json (1)

63-63: LGTM! Verify the changelog for @content-collections/core.

The update of @content-collections/core from ^0.6.2 to ^0.7.2 is a minor version bump, which should be backwards compatible. This is a good practice to keep dependencies up-to-date.

To ensure this update doesn't introduce any unexpected changes, please verify the changelog for @content-collections/core between versions 0.6.2 and 0.7.2. Check for any new features or bug fixes that might be relevant to your project.

Would you like me to assist in reviewing the changelog or checking for any potential breaking changes?

apps/www/components/changelog/changelog-grid-item.tsx (1)

58-60: LGTM! Verify visual impact of spacing change.

The removal of the gap-12 class from the flex container will result in a more compact vertical layout for the changelog item. This change aligns with improving the UI as mentioned in the PR objectives.

To ensure the visual change meets the intended design, please:

  1. Compare the rendered changelog items before and after this change.
  2. Verify that the spacing between the MDX content and the share button is visually appropriate.
  3. Check if this change affects the overall readability and visual hierarchy of the changelog items.
apps/dashboard/app/new/create-workspace.tsx (2)

62-62: Excellent responsive design improvements!

The changes to the main container's className enhance the layout's responsiveness:

  1. flex-col md:flex-row ensures a vertical layout on mobile and horizontal on larger screens.
  2. gap-8 md:gap-16 provides appropriate spacing across different device sizes.

These modifications align with best practices for responsive web design, improving the user experience across various devices.


63-63: Good responsive width adjustment for the main content.

The change to the main element's className (w-full md:w-3/4) improves the layout's responsiveness:

  • On small screens, the main content takes full width, maximizing the available space.
  • On medium and larger screens, it occupies 3/4 of the container width, leaving room for the aside content.

This adjustment works well with the parent container's responsive changes, ensuring an optimal layout across different device sizes.

apps/www/app/blog/page.tsx (1)

115-128: Verify relevance to PR objectives

While this change improves the component's robustness, it doesn't seem to directly address the caching issue mentioned in the PR objectives (fixing the breadcrumb cache issue where the API name remains cached in the header after renaming).

Could you please clarify how this change relates to the PR's main objective? If it's an unrelated improvement, consider submitting it as a separate PR to maintain focus on the primary issue being addressed.

apps/dashboard/app/(app)/apis/[apiId]/settings/delete-api.tsx (3)

4-5: LGTM: Import organization improved

The reorganization and addition of imports enhance code readability and organization. The new imports are likely used in the component, and the repositioning of existing imports follows a more logical order.

Also applies to: 22-23, 25-25, 28-29


121-121: LGTM: Improved Dialog component props

The use of handleDialogOpenChange in the onOpenChange prop of the Dialog component improves code readability and maintainability. This change is consistent with the new function added earlier and enhances the overall structure of the component.


Line range hint 66-70: Verify breadcrumb update after API deletion

While this component doesn't directly handle breadcrumb caching, it's part of the API management flow. To ensure consistency with the PR objective of fixing the breadcrumb cache issue, please verify that the breadcrumb is correctly updated after API deletion.

Consider adding a test or manual verification step to ensure that after API deletion and redirection to "/apis", the breadcrumb reflects the change immediately. You can use the following script to check for breadcrumb-related code:

apps/api/src/routes/v1_identities_createIdentity.ts (3)

133-145: Approved: Improved transaction handling and error reporting

The refactored transaction handling code enhances readability while maintaining the same functionality. The error handling for duplicate entries is now more concise and uses a specific UnkeyApiError with the appropriate error code, which improves error reporting.


147-160: Approved: Efficient handling of ratelimits

The implementation of ratelimits creation is well-structured. It efficiently maps the request data to the required format and only performs the database insertion when ratelimits are present. This approach is both performant and maintainable.


252-261: Approved: Robust error handling

The error handling in the catch block is well-implemented. It correctly distinguishes between UnkeyApiError instances and other types of errors, ensuring that specific error information is preserved when available while maintaining consistent error reporting for unexpected issues.

apps/dashboard/app/(app)/audit/[bucket]/page.tsx (1)

85-85: LGTM! Verify impact on log display order.

The change from ordering by ascending id to descending time is a good improvement. It ensures that the most recent logs appear first, which is typically more useful for audit logs.

To ensure this change doesn't negatively impact other parts of the application, please run the following verification script:

✅ Verification successful

Change Verified Successfully

The orderBy modification in apps/dashboard/app/(app)/audit/[bucket]/page.tsx now orders audit logs by time in descending order as intended. No other instances of orderBy using id were found affecting other components.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any other occurrences of audit log ordering that might need to be updated.

# Test: Search for audit log ordering in other files
rg --type typescript --type javascript 'orderBy.*table.(id|time)'

# Test: Check for any components that might be relying on the previous ordering
rg --type typescript --type javascript 'AuditLogTable.*logs'

Length of output: 200


Script:

#!/bin/bash
# Description: Search for any other occurrences of audit log ordering across all TypeScript and JavaScript files.

# Using fd to find all .ts and .tsx files and grep to search for 'orderBy.*table.(id|time)'
fd --extension ts --extension tsx . | xargs grep -H 'orderBy.*table\.\(id\|time\)'

# Description: Check for any components that might be relying on the previous ordering.

# Using fd to find all .ts and .tsx files and grep to search for 'AuditLogTable.*logs'
fd --extension ts --extension tsx . | xargs grep -H 'AuditLogTable.*logs'

Length of output: 438

apps/www/app/templates/data.ts (5)

16-18: LGTM: New frameworks added successfully.

The addition of "Oak", "FastAPI", and "NestJS" to the frameworks array expands the available options for users. These additions are consistent with the existing structure and enhance the functionality of the application.


58-69: LGTM: New "typescript-nestjs" template added correctly.

The new template for NestJS projects using TypeScript is well-structured and includes all required fields. The information provided is consistent and appropriate for the template's purpose.


70-81: LGTM: New "python-fastapi" template added successfully.

The new template for FastAPI projects using Python is well-structured and includes all necessary information. The fields are correctly filled, and the template is consistent with the existing entries.


82-93: LGTM: New "reno-oak-ratelimit" template added correctly.

The new template for Deno API using the Oak framework is well-structured and includes all required fields. The information provided is consistent and appropriate for the template's purpose. The use of TypeScript for a Deno project and the Oak framework is correctly reflected in the language and framework fields.


Line range hint 16-93: Summary: All changes approved and enhance application functionality.

The additions to the frameworks array and the new template entries ("typescript-nestjs", "python-fastapi", and "reno-oak-ratelimit") have been reviewed and approved. These changes expand the options available to developers and are consistent with the existing structure of the file. The new templates provide well-structured and informative entries for NestJS, FastAPI, and Deno with Oak projects, enhancing the overall functionality of the application.

apps/docs/libraries/ts/cache/overview.mdx (1)

Line range hint 1-941: Excellent documentation overall, with room for minor enhancements.

This documentation for the @unkey/cache library is comprehensive, well-structured, and provides valuable information for users. The addition of detailed explanations for different store types and middlewares greatly enhances the usability of the library.

Some final suggestions for improvement:

  1. Consider adding a "Quick Start" section at the beginning of the document to help users get up and running quickly.
  2. Review the document for any typos or grammatical errors (I didn't notice any glaring issues, but a final proofread is always beneficial).
  3. If possible, add links to working examples or a demo application that showcases the library's features.

Overall, this documentation provides an excellent resource for users of the @unkey/cache library. Great job on creating such comprehensive and clear documentation!

apps/www/components/analytics/analytics-bento.tsx (6)

70-75: Improved styling flexibility with conditional classes

The use of the cn utility for conditional class names enhances the component's styling flexibility based on the showApi state. This is a good practice for managing dynamic styles.


77-85: Enhanced layout and responsiveness

The changes to the LightSvg component's className and the addition of a conditional className to the BentoText component improve the layout and responsiveness of the AnalyticsBento component.


201-213: Improved user experience with code snippet copying

The addition of the CopyCodeSnippetButton enhances user experience by providing an easy way to copy code snippets. The styling improvements through updated className props contribute to better visual consistency.


241-246: Enhanced LanguageSwitcher styling and layout

The updates to the className prop of the main container div in the LanguageSwitcher component improve its styling and layout, contributing to better responsiveness and visual consistency with the rest of the UI.


819-826: Improved BentoText component flexibility

The BentoText component now accepts a className prop, which enhances its reusability and flexibility. The use of the cn utility for combining classes is a good practice, allowing for easy customization of the component's styling.


Line range hint 70-826: Overall improvement in component flexibility and user experience

The changes in this file primarily focus on enhancing component flexibility, improving styling and layout, and adding user-friendly features like the code snippet copy button. These updates contribute to a more maintainable and user-friendly UI, with better responsiveness and customization options.

apps/api/src/pkg/audit.ts (6)

44-45: Optimize database performance with batch inserts

Great job introducing auditLogsInserts and auditLogTargetInserts arrays to batch database inserts. This optimization can significantly improve performance by reducing the number of database operations.


52-54: Ensure thread safety by avoiding transactions in read operations

By explicitly avoiding transactions when querying auditLogBucket, you prevent potential race conditions, as noted in the comments. Using db.readonly here is appropriate and enhances the safety of concurrent operations.


92-92: Ensure data integrity when adding to auditLogsInserts

The logic for constructing audit log entries appears correct. Please verify that all optional fields, such as log.description, log.context?.location, and log.actor.meta, are handled appropriately to prevent any undefined values that might cause insertion errors.


110-111: Accurately map resources for auditLogTargetInserts

Transforming log.resources into auditLogTargetInserts is implemented correctly. Ensure that each resource object contains all necessary properties and that optional fields are properly managed to maintain data consistency.


124-126: Batch insert operations enhance efficiency

Using batch inserts for auditLogsInserts and auditLogTargetInserts with (tx ?? db.primary) is an effective way to improve database operation efficiency and ensures that inserts are part of the transaction if one is provided.


79-81: ⚠️ Potential issue

Consider implications of inserting without a transaction

While avoiding transactions here may prevent race conditions, inserting into auditLogBucket without using the provided transaction (tx) might lead to inconsistencies if other operations within the transaction are rolled back. Please verify whether it's acceptable to perform this insert outside of a transaction, or if it should be included within (tx ?? db.primary) to ensure atomicity.

If appropriate, you could adjust the code as follows:

-await db.primary.insert(schema.auditLogBucket).values({
+await (tx ?? db.primary).insert(schema.auditLogBucket).values({
  id: bucketId,
  workspaceId: log.workspaceId,
  name: log.bucket,
  retentionDays: 90,
});
packages/api/src/openapi.d.ts (4)

Line range hint 1-4: Auto-Generated File Notice

This file is auto-generated by openapi-typescript. Please ensure that any changes are made to the source OpenAPI specification, and then regenerate this file to reflect those changes. Avoid manual modifications to prevent inconsistencies.


Line range hint 3650-3661: New Identity Operations Added Successfully

The createIdentity operation has been correctly added with appropriate request bodies and response schemas. The parameters and descriptions are well-documented, and the structure aligns with the existing API conventions.


Line range hint 3662-3687: Definition of getIdentity and listIdentities Operations

The getIdentity and listIdentities operations are properly defined. The query parameters and response structures are consistent and comprehensive, providing necessary details for identity retrieval.


Line range hint 3688-3729: Implementation of updateIdentity and deleteIdentity Operations

The updateIdentity and deleteIdentity operations are well-implemented, with clear request schemas and handling of optional parameters. The response schemas accurately reflect the expected outcomes of these operations.

Comment on lines 46 to 48
» 12-October-2024 by [Saketh Pavan](@Sakethpavan)
» Link to Account: https://x.com/Sakethpavan1

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Correct the X handle to match the URL.

There's a discrepancy between the X handle in the entry (@Sakethpavan) and the one in the URL (Sakethpavan1). Please update the entry to use the correct handle.

Apply this change:

-» 12-October-2024 by [Saketh Pavan](@Sakethpavan)
+» 12-October-2024 by [Saketh Pavan](@Sakethpavan1)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
» 12-October-2024 by [Saketh Pavan](@Sakethpavan)
» Link to Account: https://x.com/Sakethpavan1
» 12-October-2024 by [Saketh Pavan](@Sakethpavan1)
» Link to Account: https://x.com/Sakethpavan1
🧰 Tools
🪛 Markdownlint

47-47: null
Bare URL used

(MD034, no-bare-urls)

oss.gg/3_follow_the_unkey_x_account.md Outdated Show resolved Hide resolved
Comment on lines 62 to 63
<div className="flex flex-col md:flex-row items-start justify-between gap-8 md:gap-16">
<main className="w-full md:w-3/4">
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

Consider further responsive design enhancements

While the current changes significantly improve the layout's responsiveness, consider the following suggestions:

  1. The aside content (AsideContent) is hidden on mobile screens. If this information is crucial for users, consider displaying it differently on smaller screens, perhaps above or below the form.

  2. The form's submit button doesn't have responsive classes. Consider adding responsive width classes to ensure it looks good on all screen sizes, e.g.:

    <Button
      // ... other props
      className="w-full md:w-auto"
    >
      {createWorkspace.isLoading ? <Loading /> : "Create Workspace"}
    </Button>

These additional changes could further enhance the user experience across all device sizes.

Copy link

oss-gg bot commented Oct 28, 2024

Awarding AkshayBandi027: 300 points 🕹️ Well done! Check out your new contribution on oss.gg/AkshayBandi027

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

🧹 Outside diff range and nitpick comments (6)
apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/page.tsx (1)

Line range hint 25-37: Cache tag implementation looks good, but cache key could be improved.

The addition of tags.api() for cache invalidation directly addresses the breadcrumb caching issue. When the API is renamed, this tag will allow proper cache invalidation, ensuring the breadcrumb updates correctly.

However, the cache key "apiById" is still using a string literal, which could benefit from the same type-safe approach discussed in the PR comments.

Consider moving the cache key to the type-safe tags object:

 const getApiById = cache(
   async (apiId: string) =>
     db.query.apis.findFirst({
       where: (table, { eq, and, isNull }) => and(eq(table.id, apiId), isNull(table.deletedAt)),
       with: {
         workspace: true,
       },
     }),
-  ["apiById"],
+  [tags.cacheKeys.apiById],
   { tags: [tags.api(props.params.apiId)] },
 );

This would require adding a new cacheKeys property to your tags object:

// in @/lib/cache.ts
export const tags = {
  api: (id: string) => `api:${id}` as const,
  cacheKeys: {
    apiById: 'apiById' as const,
  },
  // ... other tag generators
} as const;
apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/settings/page.tsx (1)

Line range hint 20-37: Architecture feedback on cache implementation.

The implementation of dynamic cache tags in AsyncPageBreadcrumb is well-structured and addresses the core issue. A few architectural points to consider:

  1. The cache tag is properly scoped to the specific API, which allows for precise invalidation
  2. The implementation aligns with the typesafe approach discussed in the PR comments
  3. The use of unstable_cache with dynamic tags provides a good balance between performance and consistency

For future improvements, consider:

  • Documenting the cache invalidation strategy in the codebase
  • Adding cache-related unit tests to verify invalidation behavior
apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/logs/page.tsx (1)

24-31: LGTM! Cache configuration addresses the renaming issue

The implementation properly uses cache tags to enable granular cache invalidation per namespace, which should resolve the API name caching issue after renaming.

Consider creating a constant for the cache key to prevent typos:

const CACHE_KEYS = {
  NAMESPACE_BY_ID: "namespaceById"
} as const;

// Usage
cache(
  async (namespaceId: string) => ...,
  [CACHE_KEYS.NAMESPACE_BY_ID],
  { tags: [tags.namespace(props.params.namespaceId)] }
);
apps/dashboard/app/(app)/apis/[apiId]/settings/update-api-name.tsx (1)

21-22: Consider using absolute imports for better maintainability.

The relative import path for revalidateTag could be replaced with an absolute import to improve maintainability and readability.

-import { revalidateTag } from "../../../../actions";
+import { revalidateTag } from "@/actions";
apps/www/app/glossary/client.tsx (1)

Line range hint 173-191: Remove commented-out code.

The commented-out code at the bottom of the file should be removed as it's no longer in use. If this code needs to be referenced later, it's better tracked through version control history rather than keeping it as comments in the source code.

-// <Link href={`/glossary/${slug}`} key={slug} className="block">
-//   <Card className="w-full bg-white/5 shadow-[0_0_10px_rgba(255,255,255,0.1)] rounded-xl overflow-hidden relative border-white/20">
-//     <CardHeader>
-// <Frame size="sm">
-//   <div className="p-4 rounded-md space-y-2">
-//     <h3 className="text-sm font-semibold flex items-center text-white">
-//       <Zap className="mr-2 h-5 w-5" /> TL;DR
-//     </h3>
-//     <p className="text-sm text-white/80">{takeaways.tldr}</p>
-//   </div>
-// </Frame>
-//     </CardHeader>
-//     <CardContent>
-//       <h4 className="text-md font-semibold text-white mb-2">{term}</h4>
-//     </CardContent>
-//   </Card>
-// </Link>
apps/www/app/glossary/[slug]/page.tsx (1)

Line range hint 126-140: Consider optimizing terms list rendering.

The allGlossaries array is passed directly to both FilterableCommand and TermsRolodexDesktop components. For large glossaries, this could impact performance. Consider implementing:

  1. Pagination or virtualization for the terms list
  2. Memoization of the mapped terms array

Here's a suggested optimization:

+const memoizedTerms = useMemo(
+  () => allGlossaries.map((term) => ({ slug: term.slug, title: term.title })),
+  [allGlossaries]
+);

<FilterableCommand
  placeholder="Search"
  className="rounded-lg mb-4 border-[.75px] border-white/20 lg:w-[232px]"
-  terms={allGlossaries}
+  terms={memoizedTerms}
/>
<TermsRolodexDesktop
  className="flex-grow hidden lg:block"
-  terms={allGlossaries.map((term) => ({ slug: term.slug, title: term.title }))}
+  terms={memoizedTerms}
/>

Don't forget to add the import:

import { useMemo } from 'react';
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 6a05ff2 and 7c51d96.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (21)
  • apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/keys/[keyAuthId]/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/settings/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/authorization/permissions/[permissionId]/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/logs/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/overrides/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/settings/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/apis/[apiId]/settings/update-api-name.tsx (2 hunks)
  • apps/dashboard/app/(app)/authorization/permissions/[permissionId]/client.tsx (2 hunks)
  • apps/dashboard/app/(app)/authorization/roles/[roleId]/update-role.tsx (3 hunks)
  • apps/dashboard/app/(app)/ratelimits/[namespaceId]/page.tsx (2 hunks)
  • apps/dashboard/app/(app)/ratelimits/[namespaceId]/settings/update-namespace-name.tsx (3 hunks)
  • apps/dashboard/app/actions.ts (1 hunks)
  • apps/dashboard/lib/cache.ts (1 hunks)
  • apps/www/app/glossary/[slug]/page.tsx (1 hunks)
  • apps/www/app/glossary/client.tsx (1 hunks)
  • apps/www/components/glossary/search.tsx (2 hunks)
  • apps/www/components/glossary/terms-rolodex-desktop.tsx (1 hunks)
  • oss.gg/7_create_a_template.md (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/settings/page.tsx
  • apps/dashboard/app/(app)/ratelimits/[namespaceId]/settings/update-namespace-name.tsx
  • apps/dashboard/lib/cache.ts
🧰 Additional context used
📓 Learnings (3)
apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx (2)
Learnt from: AkshayBandi027
PR: unkeyed/unkey#2215
File: apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx:28-29
Timestamp: 2024-10-05T17:45:28.954Z
Learning: In `authorization/roles/[roleId]/update-role.tsx`, the tag `role-${role.id}` is revalidated after updating a role to ensure that the caching mechanism is properly handled for roles.
Learnt from: AkshayBandi027
PR: unkeyed/unkey#2215
File: apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx:28-29
Timestamp: 2024-10-08T15:33:04.290Z
Learning: In `authorization/roles/[roleId]/update-role.tsx`, the tag `role-${role.id}` is revalidated after updating a role to ensure that the caching mechanism is properly handled for roles.
apps/dashboard/app/(app)/authorization/roles/[roleId]/update-role.tsx (2)
Learnt from: AkshayBandi027
PR: unkeyed/unkey#2215
File: apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx:28-29
Timestamp: 2024-10-05T17:45:28.954Z
Learning: In `authorization/roles/[roleId]/update-role.tsx`, the tag `role-${role.id}` is revalidated after updating a role to ensure that the caching mechanism is properly handled for roles.
Learnt from: AkshayBandi027
PR: unkeyed/unkey#2215
File: apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx:28-29
Timestamp: 2024-10-08T15:33:04.290Z
Learning: In `authorization/roles/[roleId]/update-role.tsx`, the tag `role-${role.id}` is revalidated after updating a role to ensure that the caching mechanism is properly handled for roles.
apps/www/components/glossary/search.tsx (2)
Learnt from: p6l-richard
PR: unkeyed/unkey#2085
File: apps/www/components/glossary/search.tsx:16-20
Timestamp: 2024-10-23T16:21:47.395Z
Learning: For the `FilterableCommand` component in `apps/www/components/glossary/search.tsx`, refactoring type definitions into an interface is not necessary at this time.
Learnt from: p6l-richard
PR: unkeyed/unkey#2085
File: apps/www/components/glossary/search.tsx:41-57
Timestamp: 2024-10-23T16:19:42.049Z
Learning: For the `FilterableCommand` component in `apps/www/components/glossary/search.tsx`, adding error handling and loading states to the results list is not necessary.
🪛 Markdownlint
oss.gg/7_create_a_template.md

40-40: null
Spaces inside link text

(MD039, no-space-in-links)

🔇 Additional comments (35)
apps/dashboard/app/actions.ts (2)

2-2: LGTM: Import statement is correctly placed

The import of revalidateTag from next/cache is appropriate for server-side cache invalidation.


12-12: ⚠️ Potential issue

Avoid re-exporting with conflicting name

Re-exporting revalidateMyTag as revalidateTag could lead to confusion and potential conflicts with Next.js's built-in revalidateTag.

Consider one of these alternatives:

-export { revalidateMyTag as revalidateTag };
+// Option 1: Export with a more specific name
+export { revalidateMyTag as revalidateCacheTag };
+
+// Option 2: Keep original name but improve it
+export { revalidateMyTag as revalidateCustomTag };

Let's verify the usage of revalidateTag in the codebase:

apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/page.tsx (3)

11-11: LGTM: Cache tags import added for improved cache management

The addition of the tags import is appropriate for implementing granular cache invalidation.


Line range hint 1-65: Verify comprehensive cache invalidation across related components

While the namespace cache implementation looks good, the original issue mentioned API name caching problems. Let's verify that similar cache invalidation is implemented for API-related components:

#!/bin/bash
# Check for API-related breadcrumb components that might need similar cache invalidation
fd -e tsx -e ts breadcrumb.*api

24-32: 🛠️ Refactor suggestion

Verify cache invalidation strategy and consider type safety improvements

While the cache configuration looks good, consider these suggestions:

  1. Make the cache key more specific to avoid potential collisions:
-    ["namespaceById"],
+    [`namespace:${props.params.namespaceId}`],
  1. Consider implementing type-safe cache keys as discussed in the PR comments to prevent typos and improve maintainability.

Let's verify the cache invalidation behavior:

apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/page.tsx (1)

13-13: LGTM! Good practice using type-safe cache tags.

The addition of the tags import aligns with the discussion about using type-safe cache tags, which will help prevent typos and make cache invalidation more maintainable.

apps/dashboard/app/(app)/@breadcrumb/authorization/roles/[roleId]/page.tsx (2)

11-11: LGTM: Clean import for cache tags.

The addition of the tags import aligns with the caching improvements being implemented.


28-29: Effective cache configuration for role updates.

The implementation looks good with:

  1. Static cache key for general invalidation
  2. Dynamic role-specific tag that integrates with the revalidation in update-role.tsx

This should effectively resolve the issue of stale role names in breadcrumbs after renaming.

Let's verify the complete caching implementation:

✅ Verification successful

Cache configuration properly implemented and verified

The implementation is correctly set up with matching cache invalidation:

  • Cache key "roleById" and role-specific tag are used in breadcrumb component
  • Proper cache invalidation is implemented in update-role.tsx using revalidateTag with the same tag pattern
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the role caching implementation
# Test: Check for proper cache invalidation setup across role-related files

# Look for role tag usage
echo "Checking role tag usage:"
rg --type typescript "tags\.role\("

# Look for role cache revalidation
echo "Checking role cache revalidation:"
rg --type typescript "revalidateTag.*role"

Length of output: 288


Script:

#!/bin/bash
# Description: Verify the role caching implementation with correct file type
# Test: Check for proper cache invalidation setup across role-related files

# Look for role tag usage
echo "Checking role tag usage:"
rg "tags\.role\("

# Look for role cache revalidation
echo "Checking role cache revalidation:"
rg "revalidateTag.*role"

# Look for other role-related cache configurations
echo "Checking other role cache configurations:"
rg "\"roleById\""

Length of output: 731

apps/dashboard/app/(app)/@breadcrumb/authorization/permissions/[permissionId]/page.tsx (2)

11-11: LGTM: Import for cache tags

The addition of the tags import aligns with the new caching strategy discussed in the PR comments.


23-29: Verify cache invalidation behavior

The cache configuration looks good with granular invalidation using permission-specific tags. However:

  1. Please verify that cache invalidation works correctly when permissions are updated elsewhere in the application.
  2. Consider the stability implications of using unstable_cache.

Let's verify the cache invalidation implementation:

✅ Verification successful

Let me gather more information about the update permission implementation and cache invalidation logic.


Let me check one more thing to verify the complete cache invalidation flow by looking at the tag definitions and the update permission mutation implementation.


Let me try one last search with fixed regex to find the tag definitions:


Cache invalidation implementation is correct and complete

The cache configuration and invalidation flow is properly implemented:

  1. The cache tag is correctly defined in lib/cache.ts with a specific format: permission-${permissionId}
  2. The cached query in the page component uses this tag appropriately
  3. The mutation handler in client.tsx properly invalidates the cache using revalidateTag(tags.permission(permission.id)) after successful updates
  4. The cache invalidation is granular and specific to the modified permission
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for proper cache invalidation implementation in mutation handlers

# Test 1: Look for permission update mutations that should trigger cache invalidation
echo "Checking for permission update mutations..."
rg -l "updatePermission|editPermission|modifyPermission" --type ts

# Test 2: Verify these mutations properly use the permission tag for invalidation
echo "Verifying cache invalidation in mutations..."
rg "revalidateTag.*permission" --type ts -A 3

Length of output: 938


Script:

#!/bin/bash
# Check the implementation of permission updates and cache tags

# Look at the permission update implementation
echo "Checking permission update implementation..."
rg -A 10 "updatePermission.*=.*async" --type ts

# Look at the tag definitions and usage
echo "Checking tag definitions..."
rg "tags\.permission" --type ts -B 2 -A 2

# Check for any other cache invalidation mechanisms
echo "Checking for other cache invalidation patterns..."
rg "revalidatePath|revalidateTag" --type ts -B 2 -A 2

Length of output: 8057


Script:

#!/bin/bash
# Check tag definitions and update permission mutation

# Look for tag definitions
echo "Checking cache tag definitions..."
rg -l "tags.*=.*{" --type ts

# Once found, examine the content of these files
echo "Examining tag implementation..."
fd -e ts -x cat {} \; -E "node_modules" -E ".next" | rg -A 10 "tags.*=.*{"

# Check the update permission mutation implementation
echo "Checking update permission mutation..."
cat apps/dashboard/lib/trpc/routers/rbac/updatePermission.ts

Length of output: 3279


Script:

#!/bin/bash
# Search for cache tag definitions with fixed regex

echo "Looking for cache tag definitions..."
rg "export const tags" --type ts -B 2 -A 5

echo "Looking for cache tag imports..."
rg "import.*tags.*from.*cache" --type ts -B 2 -A 2

Length of output: 8155

apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/keys/[keyAuthId]/page.tsx (2)

10-10: LGTM! Good addition of type-safe cache tags.

The import of the tags utility aligns with the team's discussion about improving type safety for cache keys.


37-37: LGTM! Proper implementation of cache tags.

The cache configuration now correctly uses tags.api() for targeted cache invalidation. This change will ensure the breadcrumb updates immediately when the API name changes.

Let's verify the cache tag implementation across the codebase:

✅ Verification successful

Cache tag implementation is consistent across API-related breadcrumb components

The verification shows that tags.api() is consistently used for cache configuration in all API-related breadcrumb components, with no instances of hardcoded API cache tags. The implementation follows the proper pattern for targeted cache invalidation.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify consistent usage of cache tags for API-related caching
# Expected: All API-related cache configurations should use tags.api()

# Check for any hardcoded API cache tags that might bypass the new system
rg -l "tags:\s*\[.*api-.*\]"

# Verify usage of tags.api() in cache configurations
rg "tags:\s*\[.*tags\.api\("

Length of output: 402

apps/dashboard/app/(app)/@breadcrumb/apis/[apiId]/settings/page.tsx (2)

11-11: LGTM: Import of cache tags utility.

The addition of the tags import aligns with the PR's objective to improve cache management.


34-34: Verify cache invalidation behavior.

The implementation uses a dynamic cache tag based on apiId, which should properly invalidate the cache when the API is renamed. This addresses the core issue where the API name wasn't updating in the breadcrumb after renaming.

Let's verify the cache tag implementation:

✅ Verification successful

Based on the results, I can now generate the final response:

Cache invalidation for API renaming is properly implemented

The cache invalidation behavior is correctly implemented:

  • The breadcrumb component uses tags.api(apiId) consistently across API-related pages
  • The API rename operation in update-api-name.tsx correctly calls revalidateTag(tags.api(api.id)) after updating the name
  • The implementation is followed by router.refresh() to ensure UI updates
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify consistent usage of cache tags for API-related operations
# Expected: Find all API-related cache tags to ensure consistent implementation

# Check for other API cache tag usage
echo "Checking API cache tag usage:"
rg "tags\.api\(" -A 2

# Check for API mutation operations that should invalidate cache
echo -e "\nChecking API mutation operations:"
rg "updateApi|renameApi|editApi" -A 5

Length of output: 5182

apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/logs/page.tsx (2)

11-11: LGTM! Import aligns with cache enhancement strategy

The addition of the tags import supports the team's initiative to implement typesafe cache keys.


24-31: Verify consistent cache tag usage and invalidation

Let's ensure the caching implementation is consistent across the codebase and properly invalidated on namespace updates.

✅ Verification successful

Cache implementation is consistent and properly invalidated

The caching implementation for namespaces is well-implemented:

  • All namespace-related pages consistently use the same cache tag pattern tags.namespace(namespaceId)
  • Cache tags are properly defined in a centralized location (apps/dashboard/lib/cache.ts)
  • Cache invalidation is correctly implemented in the namespace update handler (update-namespace-name.tsx) using revalidateTag(tags.namespace(namespace.id))
  • The cache key "namespaceById" is used consistently across all namespace-related pages and doesn't conflict with other cache keys

The current implementation follows best practices for caching and invalidation, ensuring data consistency across the application.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for consistent cache tag usage across files
echo "Checking cache tag usage patterns..."
rg -l "tags.namespace" --type typescript

# Look for cache invalidation on namespace updates
echo "\nChecking namespace update handlers..."
rg -B 5 -A 5 "updateNamespace|updateApi" --type typescript

# Verify no hardcoded "namespaceById" strings that might cause cache conflicts
echo "\nChecking for hardcoded cache keys..."
rg "namespaceById" --type typescript

Length of output: 502


Script:

#!/bin/bash
# Check for consistent cache tag usage across files
echo "Checking cache tag usage patterns..."
rg -l "tags\.namespace"

# Look for cache invalidation on namespace updates
echo -e "\nChecking namespace update handlers..."
rg -B 5 -A 5 "updateNamespace|updateApi"

# Verify no hardcoded "namespaceById" strings that might cause cache conflicts
echo -e "\nChecking for hardcoded cache keys..."
rg "namespaceById"

# Check for other cache implementations with namespace
echo -e "\nChecking other cache implementations..."
rg -B 2 -A 2 "cache\(" 

Length of output: 18046


Script:

#!/bin/bash
# Check for revalidation/cache invalidation in namespace update handler
echo "Checking namespace update implementation..."
rg -B 10 -A 10 "updateNamespaceName = t.procedure"

# Check for cache tag imports and definitions
echo -e "\nChecking cache tag definitions..."
rg -B 5 -A 5 "tags\.namespace|export const tags"

Length of output: 8409

apps/dashboard/app/(app)/@breadcrumb/ratelimits/[namespaceId]/overrides/page.tsx (2)

11-11: LGTM: Import added for cache tags.

The import is correctly placed and necessary for implementing the cache invalidation strategy.


24-31: LGTM: Cache configuration addresses the stale breadcrumb issue.

The implementation correctly uses cache tags to enable granular invalidation of namespace data, which will resolve the issue of stale breadcrumb names after renaming.

Let's verify the cache invalidation implementation:

✅ Verification successful

Cache invalidation is properly implemented for namespace updates

The verification confirms:

  • All breadcrumb pages correctly use the namespace tag for caching
  • The namespace cache is properly invalidated in update-namespace-name.tsx when renaming occurs
  • The implementation ensures breadcrumb names will be refreshed after namespace updates
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify cache invalidation implementation
# Expected: Find mutation that invalidates namespace cache tag when renaming

# Check for cache tag usage
echo "Checking cache tag usage..."
rg "tags\.namespace" -A 3

# Check for cache invalidation on rename
echo "Checking cache invalidation on rename..."
rg "revalidateTag.*namespace" -A 3

Length of output: 2882

apps/www/components/glossary/search.tsx (2)

3-3: LGTM: Import organization is clean and logical.

The imports have been reorganized in a logical order:

  1. Types first
  2. UI components
  3. External libraries
  4. React last

Also applies to: 12-12, 14-14


Line range hint 31-37: Improved code clarity with detailed comments.

The added comments effectively explain the onBlur event handling logic, making the component's behavior more maintainable.

apps/dashboard/app/(app)/apis/[apiId]/settings/update-api-name.tsx (1)

50-52: LGTM! Cache invalidation implementation looks correct.

The implementation properly invalidates the API cache tag before triggering a router refresh, which should resolve the breadcrumb caching issue.

Let's verify the cache tag usage is consistent across the codebase:

✅ Verification successful

Cache tag implementation is consistent and properly used

The verification shows that:

  • The tags.api() pattern is consistently used across the codebase for API-related cache invalidation
  • No hardcoded API cache keys were found
  • Similar tag-based cache invalidation patterns are used for other entities (namespaces, permissions, roles)
  • The revalidation is consistently followed by router.refresh() across all implementations

The implementation in the review is correct and follows the established patterns in the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for consistent usage of API cache tags
# Expected: All API-related cache operations should use the tags.api pattern

# Search for direct API cache tag usage
echo "Checking for API cache tag usage patterns..."
rg "tags\.api\(" -A 2

# Search for potential hardcoded API cache keys that should use tags
echo "Checking for potential hardcoded API cache keys..."
rg "revalidateTag\(['\"]api:" -A 2

Length of output: 1317


Script:

#!/bin/bash
# Let's verify the implementation of the tags system to ensure it's properly typed
# and consistently used across the codebase

# First, find the tags definition file
echo "Looking for tags definition file..."
fd "tags\.(ts|js|tsx|jsx)$"

# Then check its contents
echo -e "\nChecking tags implementation..."
fd "tags\.(ts|js|tsx|jsx)$" -x cat {}

# Also search for any other revalidateTag usage to ensure consistency
echo -e "\nChecking all revalidateTag usage..."
rg "revalidateTag\(" -A 2

Length of output: 1694

oss.gg/7_create_a_template.md (1)

38-43: Content structure follows the required format.

The new entries correctly include:

  • Date in DD-Month-YYYY format
  • Author name
  • Template title with framework information
  • GitHub repository link
🧰 Tools
🪛 Markdownlint

40-40: null
Spaces inside link text

(MD039, no-space-in-links)

apps/www/components/glossary/terms-rolodex-desktop.tsx (1)

3-9: Consider reverting unrelated import reordering changes.

The reordering of imports appears unrelated to the PR's main objective of fixing the breadcrumb cache issue. To maintain focus on the bug fix and avoid unnecessary changes, consider reverting these modifications.

Let's verify if this file is actually involved in the breadcrumb caching logic:

apps/dashboard/app/(app)/authorization/permissions/[permissionId]/client.tsx (2)

3-3: LGTM: Clean import organization for cache management.

The new imports for cache management are well-organized and follow the project's module structure.

Also applies to: 7-7


51-53: Verify cache invalidation coverage across related components.

The cache invalidation implementation looks correct. However, based on the PR objectives and past review comments, we should verify that this change works in conjunction with other components to fully resolve the API name caching issue.

Let's verify the cache invalidation implementation across related components:

✅ Verification successful

Based on the search results, I can now provide a comprehensive verification of the cache invalidation implementation. Let me generate the final response:

Cache invalidation implementation is correctly synchronized across components

The cache invalidation implementation for permissions is properly synchronized with other components in the codebase. Specifically:

  • The permission update correctly uses revalidateTag(tags.permission(permission.id)) which aligns with similar patterns found in other components:
    • APIs: revalidateTag(tags.api(api.id))
    • Roles: revalidateTag(tags.role(role.id))
    • Namespaces: revalidateTag(tags.namespace(namespace.id))

All components follow the same pattern of:

  1. Showing success toast
  2. Revalidating specific entity tag
  3. Refreshing the router

This consistent implementation ensures proper cache invalidation across the application.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify cache invalidation implementation across components
# Look for similar patterns in related files to ensure consistent implementation

echo "Checking cache invalidation patterns in related components:"
rg "revalidateTag.*tags\." -g "*.tsx" -A 2

echo "\nChecking for potential missing cache invalidations in mutation callbacks:"
rg "onSuccess.*\{" -g "*.tsx" -A 5

Length of output: 35392

apps/dashboard/app/(app)/authorization/roles/[roleId]/update-role.tsx (2)

2-2: LGTM: Clean import additions for cache management.

The new imports for revalidateTag and tags are appropriately placed and necessary for implementing proper cache invalidation.

Also applies to: 25-25


63-66: LGTM: Proper cache invalidation implementation.

The cache revalidation is correctly implemented:

  1. Triggers after successful role update
  2. Uses the type-safe tags.role() function
  3. Follows proper order: revalidate -> refresh -> close dialog

Let's verify the cache tag pattern implementation:

✅ Verification successful

Cache revalidation implementation is consistent and correct

The verification confirms:

  • All revalidateTag calls follow the same pattern using type-safe tag functions (e.g., tags.role(), tags.namespace(), tags.permission())
  • No string literals are used for cache tags
  • Cache invalidation is properly followed by router refresh
  • The role-related caching pattern is consistently implemented across the codebase
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify consistent usage of role cache tags across the codebase

# Test 1: Check if the tags.role pattern is used consistently
echo "Checking role cache tag usage patterns..."
rg -A 2 "tags\.role\(" 

# Test 2: Verify no string literals are used for role cache tags
echo "Checking for string literal cache tags..."
rg -A 2 "revalidateTag\(['\"]role-"

Length of output: 829


Script:

#!/bin/bash
# Let's verify the tags utility implementation and usage

# Check the tags utility implementation
echo "Checking tags utility implementation..."
fd "tags\.(ts|js|tsx|jsx)$" --exec cat {}

# Check all revalidateTag usages to ensure consistent pattern
echo "Checking all revalidateTag usages..."
rg -A 2 "revalidateTag\("

# Check if there are any other role-related cache invalidation patterns
echo "Checking other role-related cache patterns..."
rg -i "role.*cache|cache.*role"

Length of output: 1841

apps/www/app/glossary/client.tsx (2)

5-5: LGTM!

The import statements are correctly structured and maintain the same functionality.

Also applies to: 12-12


Line range hint 1-191: Verify relevance of changes to PR objective.

The changes in this file appear to be unrelated to the PR's main objective of fixing the breadcrumb cache issue. Could you clarify why these changes are included in this PR?

apps/www/app/glossary/[slug]/page.tsx (2)

Line range hint 1-276: Verify PR scope and implementation.

While the changes in this file appear to be well-implemented, they seem unrelated to the PR's primary objective of fixing the breadcrumb cache issue described in #2193. The changes focus on adding search functionality and improving the desktop view of glossary terms.

Please clarify:

  1. How these changes relate to the breadcrumb caching issue
  2. Whether the actual cache fix is missing from this PR
  3. If this should be a separate PR for the glossary improvements

4-5: Verify the scope of component additions.

These new component imports (FilterableCommand and TermsRolodexDesktop) appear unrelated to the PR's primary objective of fixing the breadcrumb cache issue. Could you clarify how these changes contribute to resolving the caching problem described in issue #2193?

apps/dashboard/app/(app)/ratelimits/[namespaceId]/page.tsx (4)

22-22: LGTM! Import change aligns with new error handling strategy

The change from notFound to redirect import supports the improved user experience by redirecting users to a valid page instead of showing a 404 error.


52-53: Skip comment as existing review is still valid

A previous review comment already addresses the indentation and unnecessary return statement issues.


Line range hint 108-120: LGTM! Improved data transformation efficiency

The refactoring from separate map operations to a single flatMap is a good improvement that:

  1. Reduces array iterations
  2. Makes the code more concise while maintaining readability
  3. Achieves the same result more efficiently

Line range hint 1-365: Verify if these changes belong in this PR

While the changes in this file are improvements (better error handling and data transformation), they appear to be unrelated to the main PR objective of fixing the breadcrumb cache issue. Consider:

  1. Moving these changes to a separate PR for better traceability
  2. Adding context in the PR description if these changes are indeed related to the cache fix

Let's verify if there are any breadcrumb-related changes in this file:

Comment on lines +8 to +10
export async function revalidateMyTag(slug: string) {
revalidateTag(slug);
}
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

Add error handling and improve function documentation

The function should include error handling and proper documentation to improve maintainability and reliability.

Consider applying these improvements:

-export async function revalidateMyTag(slug: string) {
-  revalidateTag(slug);
-}
+/**
+ * Revalidates cache for a specific tag
+ * @param slug - The cache tag to revalidate
+ * @throws {Error} If the slug is invalid or revalidation fails
+ */
+export async function revalidateMyTag(slug: string) {
+  if (!slug || typeof slug !== 'string') {
+    throw new Error('Invalid cache tag provided');
+  }
+  try {
+    await revalidateTag(slug);
+  } catch (error) {
+    console.error('Failed to revalidate cache tag:', error);
+    throw error;
+  }
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export async function revalidateMyTag(slug: string) {
revalidateTag(slug);
}
/**
* Revalidates cache for a specific tag
* @param slug - The cache tag to revalidate
* @throws {Error} If the slug is invalid or revalidation fails
*/
export async function revalidateMyTag(slug: string) {
if (!slug || typeof slug !== 'string') {
throw new Error('Invalid cache tag provided');
}
try {
await revalidateTag(slug);
} catch (error) {
console.error('Failed to revalidate cache tag:', error);
throw error;
}
}

Comment on lines +24 to +31
const getNamespaceById = cache(
async (namespaceId: string) =>
db.query.ratelimitNamespaces.findFirst({
where: (table, { eq, and, isNull }) =>
and(eq(table.id, namespaceId), isNull(table.deletedAt)),
}),
["namespaceById"],
{ tags: [tags.namespace(props.params.namespaceId)] },
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

Consider implementing type-safe cache keys and tags.

Based on the PR discussion about type safety, consider implementing a type-safe wrapper for cache keys and tags to prevent typos and improve maintainability.

Example implementation:

// lib/cache/keys.ts
export const cacheKeys = {
  namespace: {
    byId: (id: string) => ["namespaceById", id] as const,
  }
} as const;

// lib/cache/tags.ts
export const cacheTags = {
  namespace: (id: string) => `namespace:${id}` as const,
} as const;

// Usage in this file:
cache(
  async (namespaceId: string) => {
    // ... query implementation
  },
  cacheKeys.namespace.byId(props.params.namespaceId),
  { tags: [cacheTags.namespace(props.params.namespaceId)] }
);

Comment on lines +38 to +43
» 10-October-2024 by Novin Noori [Protect and Rate Limit Rust + Actix Web API with Unkey](https://github.com/djnovin/unkey-rust-actix)
» 10-October-2024 by Devansh Baghel [Deno Unkey Ratelimit Starter](https://github.com/Devansh-Baghel/deno-unkey-ratelimit-starter)
» 11-October-2024 by Prabin Subedi [Starter template for Unkey Route protecttion in Hono Webframework in Cloudflare workers ](https://github.com/prabincankod/hono-unkey-cflare)

» 10-October-2024 by Harsh Bhat [FastAPI Unkey Boilerplate](https://github.com/harshsbhat/unkey-fastapi-boilerplate)

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove duplicate template entries.

The following entries appear multiple times in the file:

  • Novin Noori's Rust + Actix Web API template
  • Devansh Baghel's Deno Ratelimit Starter
  • Harsh Bhat's FastAPI Boilerplate
  • Prabin Subedi's Hono Webframework template

Keep only one instance of each entry to maintain clarity and avoid confusion.

🧰 Tools
🪛 Markdownlint

40-40: null
Spaces inside link text

(MD039, no-space-in-links)

» 09-October-2024 by Nazar Poshtarenko [Limit Your API Calls with Unkey Usage-Limited Keys](https://github.com/unrenamed/unkey-rust-rocket.git)

» 10-October-2024 by Novin Noori [Protect and Rate Limit Rust + Actix Web API with Unkey](https://github.com/djnovin/unkey-rust-actix)
» 10-October-2024 by Devansh Baghel [Deno Unkey Ratelimit Starter](https://github.com/Devansh-Baghel/deno-unkey-ratelimit-starter)
» 11-October-2024 by Prabin Subedi [Starter template for Unkey Route protecttion in Hono Webframework in Cloudflare workers ](https://github.com/prabincankod/hono-unkey-cflare)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix formatting and spelling issues.

  1. Remove extra spaces in the link text
  2. Fix the spelling of "protecttion" to "protection"

Apply this diff:

-» 11-October-2024 by Prabin Subedi [Starter template for Unkey Route protecttion in  Hono Webframework in Cloudflare workers ](https://github.com/prabincankod/hono-unkey-cflare)
+» 11-October-2024 by Prabin Subedi [Starter template for Unkey Route protection in Hono Webframework in Cloudflare workers](https://github.com/prabincankod/hono-unkey-cflare)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
» 11-October-2024 by Prabin Subedi [Starter template for Unkey Route protecttion in Hono Webframework in Cloudflare workers ](https://github.com/prabincankod/hono-unkey-cflare)
» 11-October-2024 by Prabin Subedi [Starter template for Unkey Route protection in Hono Webframework in Cloudflare workers](https://github.com/prabincankod/hono-unkey-cflare)
🧰 Tools
🪛 Markdownlint

40-40: null
Spaces inside link text

(MD039, no-space-in-links)

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

Successfully merging this pull request may close these issues.

[🕹️] API Name is cached after renaming