Skip to content

Conversation

@NathanFlurry
Copy link
Member

No description provided.

@vercel
Copy link

vercel bot commented Nov 30, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
rivet-cloud (staging) Ready Ready Preview Comment Dec 3, 2025 2:02am
rivet-inspector Ready Ready Preview Comment Dec 3, 2025 2:02am
rivetkit-serverless Ready Ready Preview Comment Dec 3, 2025 2:02am
2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
rivet-cloud Ignored Ignored Dec 3, 2025 2:02am
rivet-site Ignored Ignored Preview Dec 3, 2025 2:02am

@vercel vercel bot temporarily deployed to Preview – rivetkit-serverless November 30, 2025 09:47 Inactive
Copy link
Member Author

NathanFlurry commented Nov 30, 2025

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more


How to use the Graphite Merge Queue

Add the label merge-queue to this PR to add it to the merge queue.

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

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

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 30, 2025

More templates

@rivetkit/cloudflare-workers

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/cloudflare-workers@3556

@rivetkit/db

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/db@3556

@rivetkit/framework-base

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/framework-base@3556

@rivetkit/next-js

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/next-js@3556

@rivetkit/react

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/react@3556

rivetkit

pnpm add https://pkg.pr.new/rivet-dev/rivet/rivetkit@3556

@rivetkit/sql-loader

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/sql-loader@3556

@rivetkit/engine-runner

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner@3556

@rivetkit/engine-runner-protocol

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner-protocol@3556

commit: 870352b

@claude
Copy link

claude bot commented Nov 30, 2025

PR Review: Cloud API Token Management Feature

Overview

This PR adds comprehensive Cloud API token management to the frontend, including creation, listing, and revocation of API tokens, along with an improved tokens page for namespace-level tokens.


✅ Strengths

  1. Good Security Practices

    • Tokens are only shown once after creation (create-api-token-frame.tsx:72-95)
    • Clear warning message about copying the token
    • Revoked tokens are visually indicated with opacity
    • Secure token display with masked characters (cloud_api_...XXXX)
  2. Clean Component Structure

    • Well-organized form components with proper validation
    • Good separation of concerns between frames, forms, and data providers
    • Proper use of TypeScript interfaces and types
  3. User Experience

    • Helpful expiration duration options (15m to never)
    • Clear visual feedback for loading states
    • Proper error handling through mutations
    • Empty state messaging

⚠️ Issues & Concerns

Critical: Date Calculation Bug

Location: frontend/src/app/dialogs/create-api-token-frame.tsx:20-51

The convertDurationToExpiresAt function has potential issues with month calculations:

case "m":
    now.setMinutes(now.getMinutes() + value);
    break;

The regex pattern /^(\d+)([mhdy])$/ uses 'm' for minutes, but there's no option for months in EXPIRATION_OPTIONS. This could be confusing if months are added later. Consider:

  • Using 'min' for minutes or 'mo' for months to avoid ambiguity
  • Adding a case for months if needed
  • Adding JSDoc to clarify the format

Date calculation edge cases:

  • setFullYear, setDate, etc. can have unexpected behavior around DST changes and month boundaries
  • Consider using a library like date-fns for more reliable date arithmetic

Type Safety Issue

Location: frontend/src/app/forms/create-api-token-form.tsx:23

expiresIn: z.string().optional(),

The form allows expiresIn to be optional, but there's no validation that it matches the expected format (/^(\d+)([mhdy])$/ or "never"). Consider adding:

expiresIn: z.string().regex(/^(\d+[mhdy]|never)$/, "Invalid duration format").optional(),

Or use a Zod enum:

expiresIn: z.enum(["15m", "1h", "6h", "12h", "1d", "7d", "30d", "90d", "1y", "never"]).optional(),

Missing Error Handling

Location: frontend/src/app/dialogs/api-tokens-frame.tsx:157

The revoke mutation doesn't handle errors. If the API call fails, the user gets no feedback. Add error handling:

const { mutate: revoke, isPending } = useMutation(
    dataProvider.revokeApiTokenMutationOptions({
        onSuccess: async () => {
            await queryClient.invalidateQueries(
                dataProvider.apiTokensQueryOptions(),
            );
        },
        onError: (error) => {
            toast.error("Failed to revoke token");
            console.error(error);
        },
    }),
);

Same issue in create-api-token-frame.tsx:61-69.

Query Invalidation Race Condition

Location: frontend/src/app/dialogs/create-api-token-frame.tsx:63-68

onSuccess: async (data) => {
    setCreatedToken(data.apiToken);
    await queryClient.invalidateQueries(
        dataProvider.apiTokensQueryOptions(),
    );
},

The state update happens before invalidation completes. If the component unmounts or re-renders quickly, the invalidation might not complete. Consider reversing the order or using Promise.all:

onSuccess: async (data) => {
    await queryClient.invalidateQueries(
        dataProvider.apiTokensQueryOptions(),
    );
    setCreatedToken(data.apiToken);
},

Indentation Issue

Location: frontend/src/app/dialogs/api-tokens-frame.tsx:37-38

<Frame.Title className="gap-2 flex items-center">
        <div>Cloud API Tokens</div>

The <div> has extra indentation. Should be:

<Frame.Title className="gap-2 flex items-center">
    <div>Cloud API Tokens</div>

Configuration Change in .env

Location: frontend/.env:3

-VITE_APP_CLOUD_API_URL=http://localhost:43708/api
+VITE_APP_CLOUD_API_URL=http://localhost:3000

This appears to be a local development change that shouldn't be committed. Verify this is intentional or revert it.


🔍 Code Quality Observations

  1. Missing Confirmation Dialog

    • Revoking an API token is a destructive action but has no confirmation dialog
    • Consider adding a confirmation step before revocation
  2. Accessibility

    • The "Revoke" button in ApiTokenRow could use an aria-label with the token name for screen readers
    • Consider adding keyboard shortcuts or focus management in the dialogs
  3. Internationalization

    • Date formatting uses toLocaleDateString() without locale specification
    • Consider passing the user's locale or using a consistent format
  4. Performance

    • The runnerConfigsQueryOptions() has a 5-second refetch interval (publishable-token-code-group.tsx:21)
    • This might be excessive for a static configuration - consider increasing the interval or using a more targeted approach

📝 Minor Suggestions

  1. Extract Magic Strings

    • "cloud_api_..." prefix is hardcoded in api-tokens-frame.tsx:145
    • Consider extracting to a constant
  2. Add TypeScript Const Assertions

    • The EXPIRATION_OPTIONS array could benefit from as const assertion (already done, good!)
  3. Consider Using Relative Dates

    • Instead of absolute expiration dates, showing "Expires in X days" might be more user-friendly

🧪 Test Coverage

Missing:

  • No tests for convertDurationToExpiresAt function
  • No tests for form validation
  • No tests for token creation/revocation flows

Recommend adding:

  • Unit tests for date conversion logic with edge cases
  • Integration tests for the token management flow
  • Tests for error scenarios

🔐 Security Considerations

  1. Token Storage

    • Good: Token only shown once
    • Consider: Adding a note about where users should store tokens securely
  2. Token Revocation

    • Should revoking a token require re-authentication or confirmation?
    • Consider rate limiting token creation to prevent abuse

Summary

This is a solid feature implementation with good UX and security practices. The main concerns are:

  1. Fix the date calculation edge cases (consider using date-fns)
  2. Add proper error handling to all mutations
  3. Add form validation for the expiresIn field
  4. Fix the .env configuration change
  5. Add a confirmation dialog for token revocation
  6. Fix the indentation issue in api-tokens-frame.tsx

The code is well-structured and follows React/TypeScript best practices. Once the issues above are addressed, this will be ready to merge.


Checklist for Author

  • Revert or verify the .env change
  • Add error handling to mutations
  • Add validation to expiresIn field
  • Fix indentation in api-tokens-frame.tsx:38
  • Consider adding date-fns for date calculations
  • Add confirmation dialog for token revocation
  • Add tests for critical logic (date conversion, form validation)
  • Review query invalidation timing

@NathanFlurry NathanFlurry force-pushed the 11-30-feat_frontend_create_api_key branch from 2508523 to ed9dd00 Compare November 30, 2025 23:53
@vercel vercel bot temporarily deployed to Preview – rivetkit-serverless November 30, 2025 23:53 Inactive
@NathanFlurry NathanFlurry changed the base branch from main to graphite-base/3556 December 1, 2025 05:47
@NathanFlurry NathanFlurry force-pushed the 11-30-feat_frontend_create_api_key branch from ed9dd00 to 6e53a16 Compare December 1, 2025 05:47
@vercel vercel bot temporarily deployed to Preview – rivetkit-serverless December 1, 2025 05:47 Inactive
@NathanFlurry NathanFlurry changed the base branch from graphite-base/3556 to 11-30-fix_frontend_do_not_show_tokens_button_if_not_on_namespace_page December 1, 2025 05:47
@NathanFlurry NathanFlurry marked this pull request as ready for review December 1, 2025 05:47
@NathanFlurry NathanFlurry force-pushed the 11-30-feat_frontend_create_api_key branch from 6e53a16 to 9f63d63 Compare December 1, 2025 05:57
@vercel vercel bot temporarily deployed to Preview – rivetkit-serverless December 1, 2025 05:57 Inactive
@graphite-app graphite-app bot force-pushed the 11-30-fix_frontend_do_not_show_tokens_button_if_not_on_namespace_page branch from 6348746 to 179a5c9 Compare December 1, 2025 06:01
@graphite-app graphite-app bot force-pushed the 11-30-feat_frontend_create_api_key branch from 9f63d63 to a9b55b1 Compare December 1, 2025 06:01
@vercel vercel bot temporarily deployed to Preview – rivetkit-serverless December 1, 2025 06:01 Inactive
@NathanFlurry NathanFlurry force-pushed the 11-30-fix_frontend_do_not_show_tokens_button_if_not_on_namespace_page branch from 179a5c9 to 2ac6633 Compare December 1, 2025 13:59
@NathanFlurry NathanFlurry force-pushed the 11-30-feat_frontend_create_api_key branch from a9b55b1 to b2e0ffb Compare December 1, 2025 13:59
@claude
Copy link

claude bot commented Dec 3, 2025

Pull Request Review: Cloud API Token Management

Summary

This PR introduces Cloud API token management functionality to the Rivet frontend, allowing users to create, view, and revoke Cloud API tokens through a new dedicated tokens page. The implementation includes comprehensive UI components, forms, and data providers.

Code Quality Assessment

✅ Strengths

  1. Well-structured components: The separation of concerns is clean with dedicated components for token display, creation, and management.

  2. Good UX patterns:

    • Token visibility controls (show/hide)
    • Single-view security for newly created tokens
    • Clear visual distinction between revoked and active tokens
    • Loading states handled appropriately
  3. Type safety: Good use of TypeScript with proper type definitions throughout.

  4. Code examples: Excellent addition of practical code examples showing how to use the Cloud API tokens.


Issues & Recommendations

🔴 Critical: Security Concern

File: frontend/.env
Line: 2

This change appears to be unintentional development configuration that should not be committed. This could cause issues for other developers or in production builds. Please revert this change.

🟡 High Priority: Date Calculation Bug

File: frontend/src/app/dialogs/create-api-token-frame.tsx
Lines: 20-51

The convertDurationToExpiresAt function has issues:

  1. Date mutation approach is problematic: Directly mutating dates can cause unexpected behavior with DST transitions and edge cases.
  2. Missing validation: No validation for invalid duration formats beyond the regex.

Recommended approach: Use millisecond arithmetic instead of date mutation for more predictable results.

🟡 Medium Priority: Missing Error Handling

File: frontend/src/app/data-providers/cloud-data-provider.tsx

The API token mutation functions lack error handling. Consider adding user-friendly error messages in the UI components when API calls fail.

🟡 Medium Priority: Accessibility Improvements

File: frontend/src/app/dialogs/api-tokens-frame.tsx

  1. The help button lacks an accessible label (add aria-label="Help")
  2. The revoke button should have confirmation to prevent accidental token revocation

Testing Recommendations

  1. Unit tests needed for:

    • convertDurationToExpiresAt function with edge cases (leap years, DST transitions)
    • Form validation logic
  2. Integration tests needed for:

    • Token creation flow
    • Token revocation flow
    • Error handling scenarios
  3. Manual testing checklist:

    • Create token with various expiration durations
    • Verify token is only shown once after creation
    • Revoke a token and verify it shows as revoked
    • Test with network errors
    • Verify accessibility with keyboard navigation

Summary of Required Changes

Must Fix Before Merge

  1. ❌ Revert .env file changes
  2. ❌ Fix date calculation logic in convertDurationToExpiresAt
  3. ❌ Add confirmation dialog for token revocation

Should Fix Before Merge

  1. ⚠️ Add error handling to mutation options
  2. ⚠️ Add accessibility labels to buttons

Nice to Have

  1. 💡 Improve date formatting to include time
  2. 💡 Add unit tests

Overall Assessment

This is a well-structured PR that adds important functionality. The code quality is generally good with clear separation of concerns and good UX patterns. However, there are some critical issues (particularly the .env file change and date calculation bug) that must be addressed before merging.

Recommendation: Request changes for critical and high-priority issues before approval.

@graphite-app
Copy link
Contributor

graphite-app bot commented Dec 3, 2025

Merge activity

  • Dec 3, 8:06 AM UTC: NathanFlurry added this pull request to the Graphite merge queue.
  • Dec 3, 8:07 AM UTC: CI is running for this pull request on a draft pull request (#3582) due to your merge queue CI optimization settings.
  • Dec 3, 8:08 AM UTC: Merged by the Graphite merge queue via draft PR: #3582.

graphite-app bot pushed a commit that referenced this pull request Dec 3, 2025
@graphite-app graphite-app bot closed this Dec 3, 2025
@graphite-app graphite-app bot deleted the 11-30-feat_frontend_create_api_key branch December 3, 2025 08:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants