Skip to content

Feat/reviewpr#3

Merged
HelixY2J merged 5 commits intomainfrom
feat/reviewpr
Feb 17, 2026
Merged

Feat/reviewpr#3
HelixY2J merged 5 commits intomainfrom
feat/reviewpr

Conversation

@HelixY2J
Copy link
Owner

No description provided.

@HelixY2J
Copy link
Owner Author

The Council have reviewed your vibecode, this is what they are saying:

This pull request introduces significant new features centered around subscription management, usage tracking, and a dedicated UI for viewing AI-generated code reviews. It integrates with Polar for billing and enforces resource limits based on user tiers.


1. Walkthrough

Here's a file-by-file explanation of the changes:

  • app/api/webhooks/github/route.ts

    • Change: Corrected the extraction of the pull request number from the GitHub webhook payload. It was previously body.Number and has been updated to body.pull_request.number.
    • Purpose: Fixes a bug where the prNumber was not being correctly parsed from the GitHub pull_request event, preventing AI reviews from being triggered.
    • Change: Added .then() and .catch() blocks to the reviewPullRequest call for improved logging of success or failure outcomes.
  • app/dashboard/reviews/page.tsx (New File)

    • Purpose: Introduces a new client-side page for users to view their AI-generated code reviews.
    • Functionality:
      • Fetches reviews using @tanstack/react-query (useQuery with getReviews action).
      • Implements client-side search functionality filtering by PR title, repository name, or PR number.
      • Provides status filters ("All", "Completed", "Pending").
      • Displays a stats bar showing total, completed, and pending reviews.
      • Renders each review as a Card component, showing PR number, status (with icon and color-coded badge), title, repository full name, a link to view on GitHub, a truncated AI review summary, and creation date.
      • Includes loading and empty states for a better user experience.
    • Dependencies: Uses Shadcn UI components (Card, Button, Badge, Input, etc.) and lucide-react icons for presentation.
  • app/dashboard/subscription/page.tsx (New File)

    • Purpose: Adds a new client-side page for users to manage their subscription plans and view usage.
    • Functionality:
      • Fetches subscription data and user-specific limits (getSubscriptionData) using @tanstack/react-query.
      • Displays the user's current subscription tier (Free or Pro) and status.
      • Shows usage statistics for repositories and reviews per repository, with progress bars for limited tiers.
      • Provides options to "Sync Subscription" (to refresh data from Polar), "Upgrade to Pro" (initiates a Polar checkout session), and "Manage Subscription" (redirects to Polar customer portal).
      • Highlights the current plan and outlines features for both Free and Pro tiers.
      • Handles success messages from checkout redirects.
    • Dependencies: Uses Shadcn UI components and @phosphor-icons/react for icons. Integrates with checkout and customer.portal functions from better-auth/react (which are now Polar-aware).
  • components/ui/app-sidebar.tsx

    • Change: Updated the navigation link for "Subscriptions" from /dashboard/subscriptions to /dashboard/subscription to match the new page's route.
    • Purpose: Ensures the sidebar navigation correctly points to the new subscription management page.
  • lib/auth-client.ts

    • Change: Imported polarClient from @polar-sh/better-auth and added it as a plugin to createAuthClient.
    • Purpose: Configures the client-side authentication library (better-auth) to integrate with Polar for subscription-related actions (like checkout and customer portal).
  • lib/auth.ts

    • Change: Integrated the polar plugin into the betterAuth configuration.
    • Purpose: This is the core server-side integration with Polar. It sets up:
      • createCustomerOnSignUp: Automatically creates a Polar customer when a user signs up.
      • checkout: Configures products (e.g., "Code-council" with a specific productId) and success URLs for purchasing subscriptions.
      • portal: Configures the return URL for the customer portal.
      • usage: Enables usage reporting (though not directly used in this PR, but part of the plugin).
      • webhooks: Configures a webhook listener with a secret and handlers for various subscription events:
        • onSubscriptionActive: Updates user.subscriptionTier to "PRO" and subscriptionStatus to "ACTIVE".
        • onSubscriptionCanceled: Updates user.subscriptionStatus to "CANCELED".
        • onSubscriptionRevoked: Updates user.subscriptionTier to "FREE" and subscriptionStatus to "EXPIRED".
        • onOrderPaid: Currently an empty handler (placeholder).
        • onCustomerCreated: Updates user.polarCustomerID in the database.
    • Change: Added scope: ["repo"] to the GitHub social provider configuration.
    • Purpose: Ensures the application requests repo scope when authenticating with GitHub, which is necessary for actions like creating webhooks or fetching repository contents.
  • modules/ai/action/index.ts

    • Change: Added checks for subscription limits before initiating an AI review.
    • Purpose:
      • Calls canCreateReview from modules/payment/lib/subscription to determine if the user has reached their review limit for the specific repository based on their tier. If limits are exceeded, it throws an error.
      • Calls incrementReviewCount after queuing the review to update the user's usage record.
    • Impact: Enforces the new subscription-based review limits.
  • modules/ai/lib/rag.ts

    • Change: Updated the embedding model used for RAG from text-embedding-04 to gemini-embedding-001.
    • Change: Added import "dotenv/config";.
    • Purpose: Potentially improves the quality of embeddings and thus the AI's context retrieval. The dotenv import ensures environment variables are loaded.
  • modules/auth/components/logout.tsx

    • Change: Replaced router.push("/login") with window.location.href = "/login" in the signOut onSuccess callback.
    • Purpose: Forces a hard page reload after logout, which is often preferred in Next.js to ensure all client-side state (including React Query caches, Apollo caches, etc.) is fully cleared.
  • modules/payment/config/polar.ts (New File)

    • Purpose: Centralizes the configuration for the Polar SDK client.
    • Functionality: Exports a polarClient instance initialized with POLAR_API_KEY and set to use the "sandbox" server.
  • modules/payment/lib/subscription.ts (New File)

    • Purpose: Contains all the business logic for managing subscription tiers, tracking usage, and enforcing limits.
    • Key Functions/Types:
      • SubscriptionTier, SubscriptionStatus, UserLimits types.
      • TIER_LIMITS: Defines limits for "FREE" (7 repos, 7 reviews/repo) and "PRO" (unlimited) tiers.
      • getUserTier: Retrieves a user's current subscription tier from the database.
      • getUserUsage: Fetches or initializes a UserUsage record for a user.
      • canConnectRepository, canCreateReview: Logic to check if a user is allowed to perform these actions based on their tier and current usage.
      • incrementRepositoryCount, decrementRepositoryCount, incrementReviewCount: Functions to update the usage statistics in the database.
      • getRemainingLimits: Calculates and returns a detailed breakdown of a user's current limits and usage.
      • updateUserTier, updatePolarCustomerId: Database operations to update user's subscription details and Polar customer ID.
  • modules/repository/actions/index.ts

    • Change: Added checks for subscription limits when connecting a repository.
    • Purpose:
      • Calls canConnectRepository to check if the user is allowed to connect more repositories based on their tier. If limits are exceeded, it throws an error.
      • Calls incrementRepositoryCount after successfully connecting a repository to update usage.
    • Impact: Enforces the new subscription-based repository limits.
  • modules/review/actions/index.ts (New File)

    • Purpose: Provides a server action (getReviews) to fetch AI reviews for the currently authenticated user.
    • Functionality: Retrieves reviews from Prisma, including associated repository data, ordered by creation date, and limited to 50 results.
  • package-lock.json, package.json

    • Change: Added new dependencies like @polar-sh/better-auth, @polar-sh/sdk, and @phosphor-icons/react (though @phosphor-icons/react was already present in package.json, its usage has been introduced).
    • Purpose: Supports the new subscription and UI features.
  • prisma/migrations/20260215125548_user_usage_added/migration.sql (New Migration)

    • Change: Adds subscriptionStatus (TEXT, nullable) and subscriptionTier (TEXT, default 'free') columns to the user table.
    • Change: Creates a new user_usage table to store userId (unique), repositoryCount (integer, default 0), and reviewCounts (JSONB, default '{}').
    • Purpose: Provides the database schema for tracking user subscription status, tier, and resource usage.
  • prisma/migrations/20260215164256_updated_polar_id/migration.sql (New Migration)

    • Change: Adds polarCustomerID (TEXT, unique, nullable) and polarSubscriptionId (TEXT, unique, nullable) columns to the user table.
    • Purpose: Stores unique identifiers from Polar to link users to their Polar customer and subscription records.
  • prisma/schema.prisma

    • Change: Updated the User model to include userUsage UserUsage?, subscriptionTier String @default("free"), subscriptionStatus String?, polarCustomerID String? @unique, and polarSubscriptionId String? @unique.
    • Change: Defined the new UserUsage model with fields: id, userId, user (relation), repositoryCount, reviewCounts (Json type), createdAt, updatedAt.
    • Purpose: Reflects the database schema changes for subscription and usage tracking.

2. Summary

This pull request significantly enhances the application by integrating a robust subscription and usage tracking system using Polar. It introduces a UserUsage model in the database to track repository and review counts per user, enforces these limits based on subscription tiers (Free and Pro), and provides new dashboard pages for users to view their AI reviews and manage their subscriptions. Key elements include server-side Polar webhook handlers for automated subscription status updates, client-side actions for checkout and portal management, and UI improvements for displaying review history and usage limits. A critical bug in GitHub webhook parsing has also been fixed, and the AI embedding model updated.


3. Strengths

  1. Comprehensive Subscription Integration: The use of Polar and its better-auth plugin provides a well-structured and scalable approach to managing subscriptions, including webhooks for automatic status synchronization. This is a robust solution for monetization.
  2. Clear Usage Tracking and Enforcement: The UserUsage model and the canConnectRepository, canCreateReview, and increment*Count functions ensure that resource limits are clearly defined, tracked, and enforced consistently across the application.
  3. Improved User Experience with Dashboards: The new ReviewsPage and SubscriptionPage significantly enhance the user experience by providing dedicated, user-friendly interfaces for viewing past AI reviews and managing subscription plans/usage. The use of Shadcn UI and relevant icons contributes to a professional look and feel.
  4. Robust Error Handling: The reviewPullRequest action's try-catch block, which records failed reviews to the database, is a good practice for debugging, monitoring, and providing feedback to users in case of issues.
  5. Critical Bug Fix: The correction of prNumber extraction in the GitHub webhook is essential for the core functionality of triggering AI reviews.
  6. Good Separation of Concerns: The new modules/payment/lib/subscription.ts file encapsulates all subscription-related business logic, promoting modularity and maintainability. Similarly, modules/review/actions/index.ts cleanly handles review data fetching.
  7. Enhanced Security on Logout: Using window.location.href = "/login" for logout ensures that all client-side state is completely cleared, reducing the risk of stale data or unintended access after a user logs out.
  8. Modern AI Embedding Model: Updating to gemini-embedding-001 for RAG is a forward-looking change that could improve the quality and relevance of context retrieval for AI reviews.

4. Issues

  1. Hardcoded Polar Product Configuration:
    • app/dashboard/subscription/page.tsx: The productId ("500d00ba-f6bf-43b9-8cb3-b492aa9b5842") and slug ("Pro") for the Pro plan are hardcoded directly in the component.
    • lib/auth.ts: The same productId is hardcoded, but the slug is "Code-council". There's a mismatch in the slug between client-side and server-side configurations. This can lead to confusion or breakages if the product configuration changes in Polar.
  2. Inconsistent Error Message Tone: The error messages for exceeding limits, such as "Peasant, You've reached the maximum number of reviews allowed in FREE tier", are informal and might not align with a professional brand voice.
  3. Incomplete "View Full Review" Feature: On app/dashboard/reviews/page.tsx, the "View Full Review →" button is present but currently only has variant="ghost" and no explicit onClick handler or href to navigate to a detailed review page or open a modal. This leaves the user flow incomplete.
  4. Fixed-Length Review Summary Truncation: In app/dashboard/reviews/page.tsx, review.review.substring(0, 300) truncates the AI review summary at a fixed character count. This can lead to cut-off words, broken markdown, or awkward display.
  5. Unused Import: In modules/repository/actions/index.ts, decrementRepositoryCount is imported but not used.
  6. dotenv/config Import in modules/ai/lib/rag.ts: Importing dotenv/config directly in a Next.js component/module (modules/ai/lib/rag.ts) is generally unnecessary and can sometimes cause issues. Next.js handles environment variable loading automatically from .env files.
  7. Prisma Json Type Flexibility: While Json for reviewCounts in UserUsage offers flexibility for dynamic keys, it sacrifices some type safety and schema validation at the database level compared to a more structured approach if the shape of reviewCounts is strictly Record<string, number>.
  8. Potential Client-Side Performance Bottleneck for Reviews: For users with a very large number of reviews (e.g., thousands), fetching take: 50 reviews is good, but client-side filtering and searching of potentially many reviews in useMemo in ReviewsPage could become slow.
  9. Empty onOrderPaid Webhook Handler: The onOrderPaid handler in lib/auth.ts is currently an empty function. While it might be a placeholder, it's worth considering what actions should be performed here (e.g., logging, sending a confirmation email).

5. Suggestions

  1. Centralize Product Configuration:
    • Create a dedicated configuration file (e.g., config/polar.ts or config/plans.ts) to define Polar product IDs, slugs, and possibly plan features.
    • Example:
      // config/plans.ts
      export const PRO_PLAN_CONFIG = {
          productId: "500d00ba-f6bf-43b9-8cb3-b492aa9b5842",
          slug: "Code-council", // Ensure this matches Polar
      };
      // Use this object in both lib/auth.ts and app/dashboard/subscription/page.tsx
    • This ensures consistency and easier management if product details change.
  2. Standardize Error Messages:
    • Rewrite error messages like "Peasant, You've reached..." to be more professional, user-friendly, and consistent with the brand's voice.
    • Example: "You've reached the maximum number of {item} allowed in the Free tier. Upgrade to Pro for unlimited access."
  3. Implement a Full Review Detail View:
    • Create a dedicated page (e.g., app/dashboard/reviews/[id]/page.tsx) or a modal component to display the entire AI review content.
    • The "View Full Review →" button should link to this detail page (e.g., href="/dashboard/reviews/${review.id}") or trigger the modal.
  4. Improve Review Summary Truncation:
    • Instead of a simple substring, consider a helper function that truncates text gracefully, ideally at a word boundary, and optionally strips markdown to provide a clean plain-text summary. Libraries like remark or string-truncator could assist here.
  5. Remove Unused Import:
    • Delete the decrementRepositoryCount import from modules/repository/actions/index.ts if there are no immediate plans to use it for a "disconnect repository" feature.
  6. Remove Redundant dotenv Import:
    • Remove import "dotenv/config"; from modules/ai/lib/rag.ts. Next.js automatically loads environment variables.
  7. Consider Prisma Enums for Status/Tier:
    • For subscriptionTier and subscriptionStatus in prisma/schema.prisma, using Prisma enum types instead of String would provide better type safety and data integrity, ensuring only predefined values are stored.
    • Example:
      enum SubscriptionTier {
        FREE
        PRO
      }
      enum SubscriptionStatus {
        ACTIVE
        CANCELED
        EXPIRED
      }
      model User {
        // ...
        subscriptionTier SubscriptionTier @default(FREE)
        subscriptionStatus SubscriptionStatus?
        // ...
      }
  8. Future: Server-Side Filtering/Pagination for Reviews:
    • If the application anticipates users having thousands of reviews, client-side filtering (useMemo) might become a performance bottleneck. Consider implementing server-side filtering, searching, and pagination within the getReviews action to offload this processing and improve responsiveness.
  9. Clarify reviewCounts Structure:
    • Add JSDoc comments to UserUsage and reviewCounts in modules/payment/lib/subscription.ts and prisma/schema.prisma to explicitly state that reviewCounts is expected to be a Record<string, number> (mapping repositoryId to reviewCount).
  10. Implement onOrderPaid Logic:
    • Define what actions should occur when onOrderPaid webhook is received, even if it's just logging to an internal system or triggering an email. This ensures no payment events are silently ignored.
  11. PR Description: In future PRs, provide a concise but informative description of the changes, their purpose, and any potential impacts. This helps reviewers understand the context without diving deep into the code immediately.

@HelixY2J HelixY2J merged commit 3220835 into main Feb 17, 2026
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