Skip to content

chore: use scoped server pattern in tiered-usage-gated-subscripiton#2

Merged
BrooksFlannery merged 1 commit into
mainfrom
update-tiered-usage-gated-subscription
Dec 10, 2025
Merged

chore: use scoped server pattern in tiered-usage-gated-subscripiton#2
BrooksFlannery merged 1 commit into
mainfrom
update-tiered-usage-gated-subscription

Conversation

@BrooksFlannery

@BrooksFlannery BrooksFlannery commented Dec 10, 2025

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • Documentation

    • Simplified setup instructions by removing local package linking prerequisites and steps
    • Consolidated environment and installation flow
  • New Features

    • Added authentication to the usage event tracking API
  • Chores

    • Updated package dependency version
    • Removed local package linking workflow scripts

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Dec 10, 2025

Copy link
Copy Markdown

Walkthrough

The changes migrate from a global Flowglad server instance to per-user authentication-based initialization. The route handlers now authenticate users via Next.js session middleware, extract user identifiers, and instantiate user-specific FlowgladServer instances. Package linking via yalc is removed, and dependencies are updated.

Changes

Cohort / File(s) Summary
Documentation & Configuration
README.md, package.json, next-env.d.ts
Removes yalc-based package linking prerequisites and scripts. Simplifies setup to direct project-level bun install. Updates @flowglad/nextjs from 0.12.3 to 0.15.0. Converts side-effect import to triple-slash type reference in next-env.d.ts.
TypeScript Configuration
tsconfig.json
Changes JSX runtime from "react-jsx" to "preserve". Reformats arrays to multi-line layout (no semantic change). Updates path mapping format.
Authentication & Route Handlers
src/app/api/flowglad/[...path]/route.ts, src/app/api/usage-events/route.ts
Integrates user authentication via auth.api.getSession() and headers. Adds per-request user identity extraction. Returns 401 if no authenticated user found. Replaces global server reference with per-user flowglad(userId) initialization.
Flowglad Server Factory
src/lib/flowglad.ts
Replaces fixed flowgladServer instance with flowglad(customerExternalId: string) factory function. Refactors getRequestingCustomer to getCustomerDetails, updating return type to exclude externalId. Integrates session-based authentication directly in factory.

Sequence Diagram

sequenceDiagram
    actor Client
    participant RouteHandler as API Route
    participant Auth as auth.api
    participant Factory as flowglad()
    participant Server as FlowgladServer

    Client->>RouteHandler: HTTP POST/GET /api/flowglad/[...path]
    RouteHandler->>Auth: getSession(headers())
    Auth-->>RouteHandler: session with user info
    
    alt No authenticated user
        RouteHandler-->>Client: 401 Unauthorized
    else User authenticated
        RouteHandler->>Factory: flowglad(userId)
        Factory->>Auth: getSession(headers())
        Auth-->>Factory: session
        Factory->>Server: new FlowgladServer({ getCustomerDetails })
        Server-->>Factory: initialized server instance
        Factory-->>RouteHandler: flowgladServer
        RouteHandler->>Server: execute route operations
        Server-->>RouteHandler: response
        RouteHandler-->>Client: response
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

Areas requiring extra attention:

  • Authentication flow consistency across both route handlers and factory function
  • Compatibility validation with @flowglad/nextjs v0.15.0 (dependency bump from 0.12.3)
  • Error handling paths for missing users and authentication failures in each route
  • Factory function lifecycle and user context isolation in concurrent requests

Poem

🐰 Auth flows swift, per-user and bright,
No linking scripts to slow down the night,
Factory functions spawn fresh with each call,
Flowglad now knows each customer of all! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: refactoring from a fixed FlowgladServer instance to a scoped server pattern using a factory function.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch update-tiered-usage-gated-subscription

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f30e840 and c424890.

⛔ Files ignored due to path filters (1)
  • tiered-usage-gated-subscription/bun.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • tiered-usage-gated-subscription/README.md (4 hunks)
  • tiered-usage-gated-subscription/next-env.d.ts (1 hunks)
  • tiered-usage-gated-subscription/package.json (1 hunks)
  • tiered-usage-gated-subscription/src/app/api/flowglad/[...path]/route.ts (1 hunks)
  • tiered-usage-gated-subscription/src/app/api/usage-events/route.ts (3 hunks)
  • tiered-usage-gated-subscription/src/lib/flowglad.ts (1 hunks)
  • tiered-usage-gated-subscription/tsconfig.json (4 hunks)
🔇 Additional comments (8)
tiered-usage-gated-subscription/tsconfig.json (1)

21-21: LGTM! JSX configuration updated for Next.js 15.

The change from "react-jsx" to "preserve" is correct for Next.js 15, which handles JSX transformation internally. This aligns with the framework's build pipeline.

tiered-usage-gated-subscription/README.md (1)

46-51: LGTM! Simplified setup instructions.

The removal of yarn/yalc linking steps makes the getting started process more straightforward and aligns with the package.json changes that removed the linking scripts.

tiered-usage-gated-subscription/next-env.d.ts (1)

3-3: LGTM! Standard Next.js type reference.

The change from a runtime import to a triple-slash reference directive is the correct approach for Next.js type definitions. This ensures proper compile-time type checking without runtime imports.

tiered-usage-gated-subscription/src/app/api/usage-events/route.ts (2)

59-68: LGTM! Authentication properly implemented.

The session retrieval and user ID extraction correctly handle the Next.js 15 async headers() API and return appropriate 401 responses for unauthenticated requests.


70-71: LGTM! Factory pattern correctly applied.

The per-user Flowglad instance creation using flowglad(userId) aligns with the new factory pattern in flowglad.ts, ensuring each request operates with proper user context.

tiered-usage-gated-subscription/src/app/api/flowglad/[...path]/route.ts (1)

6-18: LGTM! Route handler properly configured with authentication.

The migration to nextRouteHandler with the getCustomerExternalId callback correctly implements per-request authentication. The async headers() call is properly awaited, and error handling appropriately throws when no user is found.

tiered-usage-gated-subscription/src/lib/flowglad.ts (1)

5-23: LGTM! Factory pattern correctly implements per-user Flowglad instances.

The migration from a singleton to a factory function properly enables per-user authentication and billing context. The getCustomerDetails callback correctly retrieves session data and returns customer information in the expected format.

Note: The customerExternalId parameter on line 8 is unused within the getCustomerDetails callback body. While the FlowgladServer API signature requires this callback parameter, the implementation bypasses it by retrieving user details directly from the session instead. This is valid but worth noting—the callback can fetch customer details from any source, not necessarily using the provided externalId.

tiered-usage-gated-subscription/package.json (1)

23-23: Review the Flowglad monorepo changelog and test compatibility before merging.

The version bump from 0.12.3 to 0.15.0 is significant and public release notes are not readily available. Consult the packages/nextjs/CHANGELOG.md in the Flowglad GitHub repository for breaking changes and new features. Additionally, test this version against your codebase to ensure compatibility. No direct CVE exists for @flowglad/nextjs@0.15.0, but be aware of upstream vulnerabilities in Next.js and React (e.g., CVE-2025-66478); ensure your Next.js version is also up-to-date.

Comment on lines 149 to 154
const usageEvent = await flowgladServer.createUsageEvent({
subscriptionId,
priceId,
usageMeterId,
priceSlug,
amount: amountNumber,
transactionId: finalTransactionId,
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Check package.json for @flowglad/nextjs version
fd -t f "package.json" | head -5 | xargs -I {} sh -c 'echo "=== {} ===" && cat {}'

Repository: flowglad/examples

Length of output: 7031


🌐 Web query:

@flowglad/nextjs 0.15.0 createUsageEvent API documentation

💡 Result:

createUsageEvent (FlowgladServer) — summary

  • Purpose: record a metered usage event tied to a customer/subscription/price/usage meter (used for usage-based billing). [1][2]
  • Call (example):
    await flowgladServer.createUsageEvent({
    amount: number,
    priceId: string,
    subscriptionId: string,
    usageMeterId: string,
    transactionId: string, // idempotency key
    usageDate?: number, // ms since epoch (optional)
    properties?: Record<string, unknown> // optional; required for count_distinct_properties meters
    }) . [2]
  • Notes:
    • transactionId prevents duplicate events (idempotency). [2]
    • For "sum" aggregation, amount is the quantity; for "count_distinct_properties" send properties (usually amount = 1) and include the property to dedupe (e.g., userId). [1][2]
    • usageDate defaults to now if omitted; events are aggregated into the customer's current billing period. [1][2]

Sources:

  • Flowglad Usage docs (Usage-based billing — createUsageEvent details). [1]
  • Flowglad Server SDK API reference (createUsageEvent signature + examples). [2]

API mismatch: createUsageEvent requires priceId and usageMeterId, not priceSlug.

The call at lines 149–154 passes priceSlug, but the @flowglad/nextjs 0.15.0 API signature requires priceId and usageMeterId as separate parameters. This will cause a runtime error. Update the call to include the required parameters:

const usageEvent = await flowgladServer.createUsageEvent({
  subscriptionId,
  priceId,
  usageMeterId,
  amount: amountNumber,
  transactionId: finalTransactionId,
});
🤖 Prompt for AI Agents
In tiered-usage-gated-subscription/src/app/api/usage-events/route.ts around
lines 149–154, the call to flowgladServer.createUsageEvent passes priceSlug but
the library expects priceId and usageMeterId; replace priceSlug with the two
required fields (priceId and usageMeterId) in the object passed to
createUsageEvent, ensuring subscriptionId, amount (amountNumber) and
transactionId (finalTransactionId) remain included.

@BrooksFlannery BrooksFlannery changed the title chore: update tiered-usage-gated-subscripiton chore: use scoped server pattern in tiered-usage-gated-subscripiton Dec 10, 2025

@joeysabs joeysabs left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approved!

@BrooksFlannery BrooksFlannery merged commit 8c26ecd into main Dec 10, 2025
2 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Dec 21, 2025
This was referenced Jan 12, 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.

2 participants