Skip to content

initial membership implementation#1223

Merged
yujonglee merged 12 commits intomainfrom
final-membership-and-billing
Jul 28, 2025
Merged

initial membership implementation#1223
yujonglee merged 12 commits intomainfrom
final-membership-and-billing

Conversation

@yujonglee
Copy link
Contributor

No description provided.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 27, 2025

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

This change removes the entire "membership" plugin and all its related code, configuration, and dependencies from the project. It deletes the plugin's source files, TypeScript bindings, permission schemas, and documentation, and eliminates references to the plugin in the workspace, application, and capability configuration files. The "keygen" crate and its API client are also removed. Additionally, it replaces the membership plugin with the tauri-plugin-keygen plugin in the desktop app, updates navigation handling to use typed route objects with explicit path and search parameters, removes the /app/plans route and related UI, and introduces new billing and license management UI and hooks.

Changes

Cohort / File(s) Change Summary
Membership Plugin Source and Assets
plugins/membership/src/*, plugins/membership/js/bindings.gen.ts, plugins/membership/package.json, plugins/membership/build.rs, plugins/membership/.gitignore, plugins/membership/tsconfig.json
Entire membership plugin deleted, including all Rust source files, TypeScript bindings, build scripts, package metadata, and ignore/config files.
Membership Plugin Permissions and Schemas
plugins/membership/permissions/*
All permission configuration files, autogenerated command permissions, documentation, and JSON schema for the plugin are deleted.
Keygen Crate
crates/keygen/Cargo.toml, crates/keygen/src/*
Entire keygen crate, including its Cargo manifest and all Rust source files for the Keygen API client and license management, is deleted.
Desktop Application References
apps/desktop/src-tauri/Cargo.toml, apps/desktop/package.json, apps/desktop/src-tauri/capabilities/default.json, apps/desktop/src-tauri/src/lib.rs
Removes all references to the membership plugin from the desktop app's dependencies, capability permissions, and plugin initialization; adds the tauri-plugin-keygen plugin with environment variable configuration for keys.
Workspace Reference
Cargo.toml
Removes the membership plugin from the workspace dependency list.
Navigation and Routing Updates
plugins/windows/js/bindings.gen.ts, plugins/windows/src/commands.rs, plugins/windows/src/ext.rs, plugins/windows/src/events.rs, plugins/tray/src/ext.rs, apps/desktop/src-tauri/src/deeplink.rs, apps/desktop/src/components/finder/views/contact-view.tsx, apps/desktop/src/components/finder/views/table-view.tsx, apps/desktop/src/components/human-profile/past-notes.tsx, apps/desktop/src/components/left-sidebar/events-list.tsx, apps/desktop/src/components/left-sidebar/notes-list.tsx, apps/desktop/src/components/workspace-calendar/event-card.tsx, apps/desktop/src/components/workspace-calendar/note-card.tsx
Navigation commands updated to use typed route objects with explicit path and search parameters instead of raw string URLs; the Navigate type extended to include optional search parameters; related code in plugins and desktop components adapted accordingly. The /app/plans route and all references to it are removed from the route tree and UI.
Billing and License UI and Hooks
apps/desktop/src/components/settings/views/billing.tsx, apps/desktop/src/hooks/use-billing.ts, apps/desktop/src/hooks/use-license.ts, apps/desktop/src/components/license.tsx, apps/desktop/src/components/left-sidebar/top-area/settings-button.tsx, apps/desktop/src/routes/app.settings.tsx, apps/desktop/src/routes/app.tsx, apps/desktop/src/components/toast/model-select.tsx
Introduces new billing and license management UI components and hooks; replaces static plans UI with dynamic license and billing state; adds license refresh provider wrapping app; updates settings to include billing tab; enhances settings button to reflect license status and navigate to billing.
Localization and Miscellaneous UI Updates
apps/desktop/src/locales/en/messages.po, apps/desktop/src/locales/ko/messages.po, apps/desktop/src/components/settings/components/tab-icon.tsx, apps/desktop/src/components/settings/components/types.ts, apps/desktop/src/components/toolbar/index.tsx, apps/desktop/src/routes/__root.tsx, packages/ui/src/hooks/use-mobile.tsx
Adjusts localization metadata; replaces "lab" tab with "billing" tab in settings; removes toolbar handling for /app/plans; disables react-scan initially; minor import and hook usage refinements.

Sequence Diagram(s)

sequenceDiagram
    participant Developer
    participant Workspace
    participant DesktopApp
    participant MembershipPlugin
    participant KeygenCrate
    participant WindowsPlugin
    participant TrayPlugin

    Developer->>Workspace: Remove membership plugin from workspace dependencies
    Developer->>MembershipPlugin: Delete all source, config, permissions, and documentation files
    Developer->>KeygenCrate: Delete entire keygen crate source and manifest
    Developer->>DesktopApp: Remove membership plugin references, add tauri-plugin-keygen with env config
    Developer->>WindowsPlugin: Update navigation command to use Navigate struct with path and search
    Developer->>TrayPlugin: Update navigation command to use Navigate struct with path and search
    Developer->>DesktopApp: Update navigation in components to use typed route objects with explicit path and search
    Developer->>DesktopApp: Remove /app/plans route and all related UI and types
    Developer->>DesktopApp: Add billing and license UI components and hooks
    Developer->>DesktopApp: Wrap app with LicenseRefreshProvider for periodic license refresh
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related PRs


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f89557a and e184f5c.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • apps/desktop/src/locales/en/messages.po (33 hunks)
  • apps/desktop/src/locales/ko/messages.po (33 hunks)
  • apps/desktop/src/routes/app.tsx (2 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch final-membership-and-billing

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

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

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

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

CodeRabbit Commands (Invoked using PR comments)

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

Other keywords and placeholders

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

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

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

🔭 Outside diff range comments (1)
apps/desktop/src-tauri/src/deeplink.rs (1)

131-143: Test assertion error for register query.

The test expects 2 destinations (line 135) but then asserts the URL is "/app/register?..." (lines 140-141). Based on the parse_register_query function, the first destination should have URL "/app", not the full register URL.

Fix the test assertion:

-        assert_eq!(
-            dest.url,
-            "/app/register?base_url=http://localhost:3000&api_key=123"
-        );
+        assert_eq!(dest.url, "/app");
🧹 Nitpick comments (2)
apps/desktop/src/components/toast/model-select.tsx (1)

20-26: Consider making the timeout configurable.

The hardcoded 500ms delay might be fragile. Consider extracting this as a constant or making it configurable if timing coordination issues arise.

+const NAVIGATION_DELAY_MS = 500;
+
 const handleClick = () => {
   const url = { to: "/app/settings", search: { tab: "ai" } } as const satisfies LinkProps;

   windowsCommands.windowShow({ type: "settings" }).then(() => {
     setTimeout(() => {
       windowsCommands.windowEmitNavigate({ type: "settings" }, {
         path: url.to,
         search: url.search,
       });
-    }, 500);
+    }, NAVIGATION_DELAY_MS);
   });
apps/desktop/src/components/workspace-calendar/note-card.tsx (1)

70-70: Consider using route building utilities instead of string replacement.

The manual string replacement url.to.replace("$id", id) is fragile and could fail if the route template changes or contains multiple parameter placeholders.

Consider using the router's built-in route building utilities if available, or at least make the replacement more robust:

-        path: url.to.replace("$id", id),
+        path: url.to.replace(/\$id/g, id), // Use regex for more precise replacement

Or better yet, if the router provides route building utilities:

// If available in @tanstack/react-router
path: buildPath(url.to, { id }),
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3502bb6 and 2c35272.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (34)
  • .github/workflows/desktop_cd.yaml (1 hunks)
  • apps/desktop/src-tauri/src/deeplink.rs (5 hunks)
  • apps/desktop/src-tauri/src/lib.rs (1 hunks)
  • apps/desktop/src/components/finder/views/contact-view.tsx (3 hunks)
  • apps/desktop/src/components/finder/views/table-view.tsx (2 hunks)
  • apps/desktop/src/components/human-profile/past-notes.tsx (2 hunks)
  • apps/desktop/src/components/left-sidebar/events-list.tsx (2 hunks)
  • apps/desktop/src/components/left-sidebar/notes-list.tsx (2 hunks)
  • apps/desktop/src/components/left-sidebar/top-area/settings-button.tsx (5 hunks)
  • apps/desktop/src/components/license.tsx (1 hunks)
  • apps/desktop/src/components/settings/components/tab-icon.tsx (2 hunks)
  • apps/desktop/src/components/settings/components/types.ts (3 hunks)
  • apps/desktop/src/components/settings/views/billing.tsx (1 hunks)
  • apps/desktop/src/components/toast/model-select.tsx (3 hunks)
  • apps/desktop/src/components/toolbar/index.tsx (1 hunks)
  • apps/desktop/src/components/workspace-calendar/event-card.tsx (2 hunks)
  • apps/desktop/src/components/workspace-calendar/note-card.tsx (2 hunks)
  • apps/desktop/src/hooks/use-billing.ts (1 hunks)
  • apps/desktop/src/hooks/use-license.ts (1 hunks)
  • apps/desktop/src/locales/en/messages.po (28 hunks)
  • apps/desktop/src/locales/ko/messages.po (28 hunks)
  • apps/desktop/src/routeTree.gen.ts (0 hunks)
  • apps/desktop/src/routes/__root.tsx (2 hunks)
  • apps/desktop/src/routes/app.plans.tsx (0 hunks)
  • apps/desktop/src/routes/app.settings.tsx (2 hunks)
  • apps/desktop/src/routes/app.tsx (2 hunks)
  • packages/ui/src/hooks/use-mobile.tsx (1 hunks)
  • plugins/tray/Cargo.toml (1 hunks)
  • plugins/tray/src/ext.rs (2 hunks)
  • plugins/windows/Cargo.toml (1 hunks)
  • plugins/windows/js/bindings.gen.ts (2 hunks)
  • plugins/windows/src/commands.rs (2 hunks)
  • plugins/windows/src/events.rs (1 hunks)
  • plugins/windows/src/ext.rs (3 hunks)
💤 Files with no reviewable changes (2)
  • apps/desktop/src/routes/app.plans.tsx
  • apps/desktop/src/routeTree.gen.ts
✅ Files skipped from review due to trivial changes (4)
  • plugins/windows/Cargo.toml
  • packages/ui/src/hooks/use-mobile.tsx
  • plugins/tray/Cargo.toml
  • apps/desktop/src/locales/ko/messages.po
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/desktop/src-tauri/src/lib.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,ts,tsx,rs}

⚙️ CodeRabbit Configuration File

**/*.{js,ts,tsx,rs}: 1. No error handling.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".

Files:

  • apps/desktop/src/routes/app.settings.tsx
  • apps/desktop/src/components/human-profile/past-notes.tsx
  • apps/desktop/src/components/settings/components/tab-icon.tsx
  • apps/desktop/src/routes/app.tsx
  • apps/desktop/src/components/left-sidebar/notes-list.tsx
  • plugins/windows/src/events.rs
  • apps/desktop/src/components/workspace-calendar/note-card.tsx
  • apps/desktop/src/components/left-sidebar/events-list.tsx
  • apps/desktop/src/components/toast/model-select.tsx
  • apps/desktop/src/components/license.tsx
  • plugins/windows/src/commands.rs
  • apps/desktop/src/components/finder/views/contact-view.tsx
  • apps/desktop/src/components/settings/components/types.ts
  • apps/desktop/src/components/workspace-calendar/event-card.tsx
  • apps/desktop/src/routes/__root.tsx
  • apps/desktop/src/hooks/use-billing.ts
  • plugins/windows/js/bindings.gen.ts
  • plugins/tray/src/ext.rs
  • apps/desktop/src-tauri/src/deeplink.rs
  • apps/desktop/src/hooks/use-license.ts
  • apps/desktop/src/components/finder/views/table-view.tsx
  • apps/desktop/src/components/left-sidebar/top-area/settings-button.tsx
  • apps/desktop/src/components/toolbar/index.tsx
  • apps/desktop/src/components/settings/views/billing.tsx
  • plugins/windows/src/ext.rs
🧬 Code Graph Analysis (6)
apps/desktop/src/routes/app.settings.tsx (1)
apps/desktop/src/components/settings/views/billing.tsx (1)
  • Billing (15-26)
plugins/windows/src/events.rs (1)
plugins/windows/js/bindings.gen.ts (1)
  • Navigate (77-77)
apps/desktop/src/components/license.tsx (1)
apps/desktop/src/hooks/use-license.ts (1)
  • useLicense (7-99)
plugins/windows/src/commands.rs (2)
plugins/windows/js/bindings.gen.ts (3)
  • events (57-65)
  • HyprWindow (73-73)
  • Navigate (77-77)
plugins/windows/src/events.rs (2)
  • window (11-11)
  • window (31-31)
apps/desktop/src/routes/__root.tsx (1)
plugins/windows/src/ext.rs (1)
  • navigate (106-128)
plugins/tray/src/ext.rs (1)
plugins/windows/js/bindings.gen.ts (2)
  • HyprWindow (73-73)
  • Navigate (77-77)
🔇 Additional comments (54)
.github/workflows/desktop_cd.yaml (1)

107-108: LGTM: Proper handling of Keygen credentials for build process.

The addition of Keygen environment variables follows best practices for injecting secrets during the build process and supports the migration from the membership plugin to the keygen plugin.

apps/desktop/src/routes/app.settings.tsx (2)

12-12: LGTM: Billing component import follows established pattern.

The import is correctly added alongside other settings view components.


145-145: LGTM: Billing tab rendering follows established pattern.

The conditional rendering for the billing tab is consistent with how other tabs are handled in this component.

apps/desktop/src/routes/__root.tsx (2)

57-57: LGTM: Navigation event handling updated for structured navigation.

The change properly handles the new navigation event structure with explicit path and search parameters, using appropriate optional chaining for the search parameter.


67-67: LGTM: React-scan disabled appropriately.

Disabling react-scan is a reasonable configuration choice, likely for performance or debugging considerations.

apps/desktop/src/components/human-profile/past-notes.tsx (2)

3-3: LGTM: Type-only import for LinkProps is appropriate.

Using type-only imports when only types are needed is a best practice that helps with build optimization.


46-49: LGTM: Navigation call updated for structured navigation.

The change properly uses the new navigation event structure with explicit path and search properties. Setting search to null is appropriate when no search parameters are needed.

apps/desktop/src/components/settings/components/tab-icon.tsx (2)

6-6: LGTM: CreditCardIcon import added appropriately.

The import is correctly placed with other icon imports and is semantically appropriate for a billing tab.


33-34: LGTM: Billing tab icon implementation follows established pattern.

The billing tab case follows the same pattern as other tab icons and uses a semantically appropriate credit card icon.

apps/desktop/src/components/toolbar/index.tsx (1)

5-5: Clean removal of unused plans-related import.

The removal of DefaultToolbar from the imports aligns with the elimination of the /app/plans route and related functionality. The remaining toolbar logic is preserved correctly.

plugins/windows/src/events.rs (2)

55-57: Good addition of Deserialize trait for bidirectional serialization.

Adding serde::Deserialize to the common event derives enables proper deserialization of events, which is essential for the updated navigation event handling.


65-65: Excellent structured approach to navigation parameters.

The addition of the optional search field with type Option<serde_json::Map<String, serde_json::Value>> provides a clean, typed way to handle search parameters instead of encoding them in URL strings. This improves type safety and makes navigation events more structured.

apps/desktop/src/components/left-sidebar/events-list.tsx (2)

3-3: Good addition of LinkProps type for navigation safety.

Adding the LinkProps import enables type-safe navigation object construction, improving code reliability.


131-137: Excellent refactoring to structured navigation events.

The change from URL string construction to a typed object with explicit to and search properties, combined with the satisfies LinkProps constraint, provides better type safety. The updated windowEmitNavigate call with separate path and search parameters aligns well with the plugin API changes.

apps/desktop/src/routes/app.tsx (2)

10-10: Good addition of license management provider.

The import of LicenseRefreshProvider supports the new keygen-based license management system replacing the previous membership plugin.


57-116: Proper integration of license refresh provider.

Wrapping the entire provider hierarchy with LicenseRefreshProvider at the outermost level ensures license state and refresh logic are globally available throughout the application. The existing provider structure is preserved correctly.

apps/desktop/src/components/left-sidebar/notes-list.tsx (2)

4-4: Consistent addition of LinkProps type for navigation safety.

Adding the LinkProps import maintains consistency with the navigation refactoring across the application and enables type-safe route construction.


239-245: Well-executed navigation refactoring.

The structured approach using a typed object with satisfies LinkProps and separate path/search parameters in the windowEmitNavigate call is consistent with the broader navigation improvements. This enhances type safety while maintaining the same functionality.

plugins/windows/src/commands.rs (1)

104-106: LGTM: Navigation parameter refactor improves type safety.

The change from path: String to event: events::Navigate provides better structure and type safety for navigation events, allowing for both path and search parameters.

apps/desktop/src/components/toast/model-select.tsx (1)

16-29: LGTM: Good refactor improving code organization.

Extracting the inline handler into a named function improves readability and follows the new structured navigation pattern correctly.

apps/desktop/src/components/license.tsx (1)

5-26: LGTM: Well-implemented license refresh provider.

The component correctly implements periodic license refreshing with proper cleanup, guards against unnecessary refreshes, and follows React best practices with a complete dependency array.

apps/desktop/src/components/settings/components/types.ts (3)

2-12: LGTM: Icon imports align with usage.

The new icon imports (BlocksIcon, CreditCard) are properly used in the TABS array.


22-23: LGTM: Tab type updated correctly.

The Tab type properly reflects the removal of "lab" and addition of "billing" tabs.


32-35: LGTM: TABS array updated consistently.

The array correctly reflects the tab changes and uses appropriate icons for each tab.

apps/desktop/src/components/workspace-calendar/note-card.tsx (1)

67-73: Navigation refactor follows established pattern.

The change correctly implements the new structured navigation approach with separate path and search parameters.

apps/desktop/src/components/finder/views/contact-view.tsx (2)

14-14: Import added to support typed navigation.

The LinkProps import enables the use of typed route objects in the navigation refactor, improving type safety over raw string URLs.


114-123: Navigation refactored to use structured route objects.

The navigation logic has been successfully updated to use typed LinkProps objects with explicit path and search parameters, replacing the previous string-based approach. This improves type safety and aligns with the broader navigation system refactor.

The parameter replacement logic (path.to.replace("$id", path.params.id)) correctly handles the route template substitution.

apps/desktop/src/locales/en/messages.po (1)

1-1471: Translation file updated to reflect code changes.

The updates to line number references and obsolete entries correctly reflect the removal of the membership plugin and plans route functionality. This is standard maintenance for localization files when features are removed.

plugins/tray/src/ext.rs (2)

114-128: Tray start navigation updated to use structured Navigate object.

The navigation logic correctly uses the new Navigate struct with proper JSON serialization for the search parameters. The record: true parameter is correctly passed through the search field.


164-173: App new navigation updated to use structured Navigate object.

The navigation logic properly uses the Navigate struct with search: None for the simple new note creation flow, maintaining consistency with the navigation system refactor.

apps/desktop/src-tauri/src/deeplink.rs (3)

87-108: License deeplink parsing implemented correctly.

The parse_license_query function properly handles license deeplinks by creating two destinations: the main window and a settings window targeting the billing tab with the license key. This aligns well with the new billing and license management system.


121-124: LicenseQuery struct properly defined.

The struct correctly captures the required key parameter for license activation deeplinks.


145-155: License deeplink test implemented correctly.

The test properly verifies that license deeplinks return 2 destinations with the main window targeting "/app".

apps/desktop/src/components/workspace-calendar/event-card.tsx (2)

3-3: LinkProps import added for typed navigation.

The import enables the use of typed route objects, improving type safety in the navigation refactor.


64-85: Navigation logic refactored to use structured route objects.

Both navigation scenarios (existing session and new session creation) have been properly updated to use typed LinkProps objects:

  1. Existing session navigation correctly uses route templates with parameter substitution
  2. New session navigation properly passes the calendarEventId through the search parameters

The implementation maintains the same functionality while improving type safety and consistency with the navigation system refactor.

apps/desktop/src/hooks/use-billing.ts (3)

3-13: LGTM!

The environment-based server URL configuration and function signature with optional nullable parameters are well-structured.


40-53: LGTM!

The query implementation correctly uses conditional enabling and appropriate refetch configuration without explicit error handling.


69-70: LGTM!

The return statement correctly exposes all billing utilities.

apps/desktop/src/hooks/use-license.ts (4)

1-6: LGTM!

The imports and constants are well-structured, and the comment appropriately explains the "why" by referencing the plugin source.


10-20: LGTM!

The query implementation correctly filters for valid licenses and uses appropriate refetch intervals without explicit error handling.


92-99: LGTM!

The return statement correctly exposes all license management utilities.


61-76: Remove console statements and error handling according to coding guidelines.

Remove the console.log and onError handler as per coding guidelines.

  const activateLicense = useMutation({
    mutationFn: async (key: string) => {
      const license = await keygen.validateCheckoutKey({
        key,
        entitlements: [],
        ttlSeconds: 60 * 60 * 24 * 7, // 7 days
        ttlForever: false,
      });
-      console.log("Activated license", license);
      return license;
    },
-    onError: console.error,
    onSuccess: (license) => {
      queryClient.setQueryData(LICENSE_QUERY_KEY, license);
    },
  });

Likely an incorrect or invalid review comment.

plugins/windows/js/bindings.gen.ts (2)

34-36: LGTM!

The command signature change from path: string to event: Navigate aligns with the structured navigation refactoring across the codebase.


73-77: LGTM!

The type definitions correctly reflect the removal of the "plans" window variant and the addition of structured navigation with optional search parameters. The JsonValue type properly supports nested JSON-compatible values.

apps/desktop/src/components/finder/views/table-view.tsx (4)

1-1: LGTM!

The LinkProps import is correctly added to support the typed navigation refactoring.


112-118: LGTM!

The navigation refactoring correctly uses typed LinkProps and structured Navigate objects. The manual path parameter replacement is consistent with the current routing implementation.


124-130: LGTM!

The navigation logic for existing event sessions correctly follows the same typed pattern as the session navigation.


132-148: LGTM!

The navigation logic for new event sessions correctly uses the search parameters feature, properly passing the calendarEventId through the structured Navigate object.

apps/desktop/src/components/left-sidebar/top-area/settings-button.tsx (3)

2-27: LGTM!

The imports and license integration are well-implemented. The isPro calculation correctly derives from license validity.


47-60: LGTM!

The navigation refactoring correctly routes to the billing tab within the settings window using the new structured navigation pattern. The setTimeout delay ensures the window is ready before navigation.


123-155: LGTM!

The DropdownHeader component correctly implements dynamic Pro/Free plan display with appropriate conditional styling, icons, and interactive behavior.

plugins/windows/src/ext.rs (1)

95-104: Good architectural improvement using typed events.

The change from string-based path to structured events::Navigate event improves type safety and removes the complexity of URL manipulation. The simplified implementation is cleaner and less error-prone.

apps/desktop/src/components/settings/views/billing.tsx (2)

105-105: Verify the hardcoded "Save 20%" claim.

The savings percentage is hardcoded. Ensure this aligns with actual pricing from the backend to avoid misleading users.


159-234: Well-implemented Pro section with good UX.

The implementation properly handles various subscription states, formats pricing information clearly, and follows security best practices by masking the license key.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2c35272 and c68a667.

📒 Files selected for processing (7)
  • apps/desktop/src/components/right-panel/hooks/useChatLogic.ts (3 hunks)
  • apps/desktop/src/components/settings/components/types.ts (3 hunks)
  • apps/desktop/src/components/settings/views/billing.tsx (1 hunks)
  • apps/desktop/src/components/settings/views/templates.tsx (2 hunks)
  • apps/desktop/src/locales/en/messages.po (28 hunks)
  • apps/desktop/src/locales/ko/messages.po (28 hunks)
  • apps/desktop/src/routes/app.settings.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • apps/desktop/src/locales/ko/messages.po
  • apps/desktop/src/routes/app.settings.tsx
  • apps/desktop/src/components/settings/components/types.ts
  • apps/desktop/src/locales/en/messages.po
  • apps/desktop/src/components/settings/views/billing.tsx
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,ts,tsx,rs}

⚙️ CodeRabbit Configuration File

**/*.{js,ts,tsx,rs}: 1. No error handling.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".

Files:

  • apps/desktop/src/components/right-panel/hooks/useChatLogic.ts
  • apps/desktop/src/components/settings/views/templates.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: ci
  • GitHub Check: ci (macos, macos-latest)
  • GitHub Check: ci (windows, windows-latest)
🔇 Additional comments (5)
apps/desktop/src/components/settings/views/templates.tsx (2)

8-8: LGTM: Import is properly used.

The useLicense hook import is correctly added and utilized in the component.


20-21: LGTM: Hook usage is correct.

The destructuring of userId and getLicense follows proper React patterns and both values are utilized in the license enforcement logic.

apps/desktop/src/components/right-panel/hooks/useChatLogic.ts (3)

1-1: LGTM: Imports are properly used.

Both message and useLicense imports are correctly added and utilized in the license enforcement logic.

Also applies to: 4-4


47-47: LGTM: Hook usage follows React patterns.

The getLicense destructuring from useLicense is correctly implemented and used in the license validation.


141-153: LGTM: License enforcement logic is correctly implemented.

The implementation properly:

  • Checks both message count (≥2) and license validity
  • Sends analytics events only when the limit is reached
  • Provides clear user feedback with appropriate dialog
  • Uses early return to prevent further execution

The logic correctly enforces the 2-message limit for free users.

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

♻️ Duplicate comments (2)
apps/desktop/src/components/settings/views/billing.tsx (2)

154-161: Email validation has been properly implemented.

The checkout button now correctly uses zod email validation (z.string().email().safeParse(email).success) to ensure only valid emails can proceed to checkout. This addresses the previous concern about accepting any non-empty email value.


196-202: License key validation has been properly implemented.

The activation button now correctly validates that the license key is not empty using !licenseKey.trim(), preventing unnecessary API calls with empty license keys. This addresses the previous concern about allowing empty license key activation.

🧹 Nitpick comments (1)
apps/desktop/src/components/settings/views/billing.tsx (1)

29-55: Consider eliminating duplicate license check.

The FreeSection component duplicates the license validity check that's already performed in the parent Billing component. Consider passing isPro as a prop to avoid redundant API calls and logic duplication.

-function FreeSection() {
-  const { getLicense } = useLicense();
-  const isPro = getLicense.data?.valid === true;
+function FreeSection({ isPro }: { isPro: boolean }) {

Then update the parent component:

-        {isPro ? <ProSection /> : <FreeSection />}
+        {isPro ? <ProSection /> : <FreeSection isPro={isPro} />}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c68a667 and 3aaef1f.

📒 Files selected for processing (4)
  • apps/desktop/src/components/settings/views/billing.tsx (1 hunks)
  • apps/desktop/src/components/settings/views/templates.tsx (2 hunks)
  • apps/desktop/src/locales/en/messages.po (33 hunks)
  • apps/desktop/src/locales/ko/messages.po (33 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • apps/desktop/src/locales/ko/messages.po
  • apps/desktop/src/locales/en/messages.po
  • apps/desktop/src/components/settings/views/templates.tsx
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,ts,tsx,rs}

⚙️ CodeRabbit Configuration File

**/*.{js,ts,tsx,rs}: 1. No error handling.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".

Files:

  • apps/desktop/src/components/settings/views/billing.tsx
🔇 Additional comments (3)
apps/desktop/src/components/settings/views/billing.tsx (3)

1-27: LGTM! Clean component structure and proper hook usage.

The main Billing component follows React best practices with clean imports, proper hook usage, and clear conditional rendering logic based on license validity.


284-313: LGTM! Well-designed reusable component.

The SectionContainer component promotes good code reuse with a clean API, proper TypeScript typing, and consistent layout structure. Good separation of concerns.


261-261: Add null safety for license key masking.

The license key masking could fail if l.getLicense.data?.key is undefined, as replace would be called on undefined.

-            value={l.getLicense.data?.key?.replace(/./g, "•") || ""}
+            value={l.getLicense.data?.key ? l.getLicense.data.key.replace(/./g, "•") : ""}

Likely an incorrect or invalid review comment.

@yujonglee yujonglee merged commit f354fef into main Jul 28, 2025
7 of 8 checks passed
@yujonglee yujonglee deleted the final-membership-and-billing branch July 28, 2025 00:39
@coderabbitai coderabbitai bot mentioned this pull request Aug 11, 2025
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.

1 participant