chore: use scoped server pattern in tiered-usage-gated-subscripiton#2
Conversation
WalkthroughThe 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
Sequence DiagramsequenceDiagram
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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20–30 minutes Areas requiring extra attention:
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
tiered-usage-gated-subscription/bun.lockis 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 inflowglad.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
nextRouteHandlerwith thegetCustomerExternalIdcallback correctly implements per-request authentication. The asyncheaders()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
getCustomerDetailscallback correctly retrieves session data and returns customer information in the expected format.Note: The
customerExternalIdparameter on line 8 is unused within thegetCustomerDetailscallback 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 providedexternalId.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.mdin 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.
| const usageEvent = await flowgladServer.createUsageEvent({ | ||
| subscriptionId, | ||
| priceId, | ||
| usageMeterId, | ||
| priceSlug, | ||
| amount: amountNumber, | ||
| transactionId: finalTransactionId, | ||
| }); |
There was a problem hiding this comment.
🧩 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.
Summary by CodeRabbit
Documentation
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.