-
-
Notifications
You must be signed in to change notification settings - Fork 19
Add payment system #3094
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add payment system #3094
Conversation
remember to add webhooks endpoint for Polar (Ref: https://docs.polar.sh/integrate/webhooks/delivery)
Warning Rate limit exceeded@vhpx has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 10 minutes and 46 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (3)
WalkthroughThis update introduces a comprehensive billing and subscription management system for workspaces. It adds new database tables and types for subscriptions, implements backend API routes for payments, webhooks, and usage synchronization, and provides frontend UI components and pages for billing management. Supporting utilities, localization, and configuration files are also updated or added. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant WebApp
participant Supabase
participant PolarAPI
User->>WebApp: Navigates to Billing Page
WebApp->>Supabase: Fetch workspace subscription
WebApp->>PolarAPI: Fetch product listings
WebApp->>Supabase: Check if user is workspace creator
WebApp-->>User: Render Billing UI with plans, status, upgrade options
User->>WebApp: Selects Upgrade Plan
WebApp->>PolarAPI: Create checkout session (via API route)
PolarAPI-->>WebApp: Return checkout URL
WebApp-->>User: Redirect to Polar checkout
PolarAPI->>WebApp: Webhook (subscription active/canceled)
WebApp->>Supabase: Upsert subscription data
WebApp->>PolarAPI: Report usage (seat count)
Suggested labels
Poem
✨ Finishing Touches
🧪 Generate Unit Tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
How to use the Graphite Merge QueueAdd either label to this PR to merge it via 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Summary of Changes
Hello @phatgg221, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request introduces the foundational structure for billing and payment processing within the application. It adds a dedicated billing page in the workspace dashboard, sets up integrations with Polar and DodoPayments SDKs, and includes initial API routes for handling checkouts and webhooks. The changes provide a user interface to view plan details, explore upgrade options, and see payment history, along with a success page for completed transactions.
Highlights
- Billing Page Implementation: Introduced a new
/billing
page within the workspace dashboard, including a client-side component (billing-client.tsx
) to display current plan details, upgrade options, and payment method information using mock data. - Payment Gateway Integration Setup: Added dependencies and initial setup for integrating with Polar and DodoPayments SDKs, including dedicated files (
src/lib/polar.ts
,src/lib/payment.ts
) for client initialization. - Checkout and Webhook Routes: Created new API routes (
/api/[wsId]/[productId]/payment
and/api/webhooks
) intended for initiating payment checkouts via Polar and handling webhook events (like subscription status changes). - Billing Success Page: Added a new
/billing/success
page to provide a confirmation and summary after a successful payment, using mock data. - UI and Navigation Updates: Added 'Billing' translation keys for English and Vietnamese and included a 'Billing' link with an icon in the main dashboard sidebar navigation.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command>
or @gemini-code-assist <command>
. Below is a summary of the supported commands.
Feature | Command | Description |
---|---|---|
Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/
folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configureGemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces payment methods with UI components, checkout integration, and API routes. The review identified areas needing attention: placeholder logic, hardcoded configurations, a commented-out payment processing route, and unacknowledged webhook handlers. Addressing these issues is essential for deployment.
…ces from @polar-sh to new payment structure
…mer email and adjust payment package exports
…r consistency and clarity
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thanks @phatgg221.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 12
🔭 Outside diff range comments (1)
apps/web/src/app/api/cron/sync-usage/route.ts (1)
1-79
: Entire route is commented-out – ship either working code or delete the fileA source file that only contains commented code ships dead weight, confuses the reader, and may be stripped by tree-shaking in unpredictable ways. Either:
- Restore the implementation so
export async function GET()
is actually exported; or- Delete the file until the cron endpoint is ready.
Keeping placeholder code in
main
undermines maintainability and violates KISS.
♻️ Duplicate comments (12)
apps/web/src/lib/polar.ts (1)
3-6
: Parameterize server environment & secure token
Avoid hardcodingserver: 'sandbox'
and silent empty-token fallback. Use env vars to control both, e.g.:export const api = new Polar({ - accessToken: process.env.NEXT_PUBLIC_POLAR_ACCESS_TOKEN || '', - server: 'sandbox', + accessToken: process.env.NEXT_PUBLIC_POLAR_ACCESS_TOKEN ?? (() => { throw new Error('NEXT_PUBLIC_POLAR_ACCESS_TOKEN is not set'); })(), + server: process.env.POLAR_SERVER === 'production' ? 'production' : 'sandbox', });apps/web/src/lib/payment.ts (1)
3-6
: Make environment and API key handling robust
Hardcodingenvironment: 'test_mode'
and defaulting to''
hides configuration issues. Consider:export const dodopayments = new DodoPayment({ - bearerToken: process.env.DODO_API_KEY || '', - environment: 'test_mode', + bearerToken: process.env.DODO_API_KEY ?? (() => { throw new Error('DODO_API_KEY is not set'); })(), + environment: process.env.DODO_ENVIRONMENT === 'live' ? 'live_mode' : 'test_mode', });apps/web/src/app/api/[wsId]/[productId]/payment/route.ts (1)
17-24
: Hard-codedsuccessUrl
will break in non-local environmentsSame concern flagged earlier – still unresolved.
apps/web/src/app/[locale]/(dashboard)/[wsId]/billing/data-polar-checkout.tsx (1)
20-33
: Hard-coded test email still present
ThecustomerEmail
prop is ignored and the checkout URL embedst@test.com
.This has been flagged before; please switch to the real value or omit the param.
-const testEmail = 't@test.com'; -const checkoutUrl = `/api/${wsId}/${productId}/payment?productId=${productId}&customerEmail=${testEmail}`; +const checkoutUrl = `/api/${wsId}/${productId}/payment?productId=${productId}` + + (customerEmail ? `&customerEmail=${encodeURIComponent(customerEmail)}` : '');apps/web/src/app/[locale]/(dashboard)/[wsId]/billing/page.tsx (1)
132-151
: Static payment history is placeholder data
paymentHistory
is hard-coded; production users will always see the same three invoices. Fetch real invoice data from Polar or Supabase, or clearly mark the section as demo-only.apps/web/src/app/[locale]/(dashboard)/[wsId]/billing/success/page.tsx (1)
170-181
: “Download Receipt” button is non-functionalThe button renders but has no
onClick
orhref
. Either hook it to the actual invoice PDF URL or remove it until implemented.apps/web/src/app/[locale]/(dashboard)/[wsId]/billing/billing-client.tsx (4)
104-112
: Using array index as React key risks remountsKeys must be stable; use the feature string itself.
-{currentPlan.features?.map((feature, index) => ( - <li key={index} …> +{currentPlan.features?.map((feature) => ( + <li key={feature} …>
187-192
: Same index-key issue in upgrade plan features
208-213
: Hard-coded customer email in checkout linkRe-use the real user email or omit the parameter to avoid PII leaks and test artefacts.
145-151
: “Update payment method” button is a stubReplace the placeholder with a dialog / redirect to your payment portal.
apps/web/src/app/api/webhooks/route.ts (2)
13-14
: Webhook secret must be mandatoryDefaulting to
''
silently disables signature verification.
Throw ifPOLAR_WEBHOOK_SECRET
is missing, as suggested in the previous review.
100-108
: Missing success response yields 500After completing all work the handler falls out without returning anything, so the framework responds with 500.
Add an explicit 200:- console.log(`Webhook: Subscription active for workspace ${ws_id}.`); + console.log(`Webhook: Subscription active for workspace ${ws_id}.`); + return new Response('Subscription processed', { status: 200 });
🧹 Nitpick comments (12)
apps/web/.env.example (1)
43-47
: Add trailing newline and reorder Payment env vars
Lint tools expect a blank line at EOF. Also, for clarity, consider listing public variables before secrets:- POLAR_WEBHOOK_SECRET=YOUR_POLAR_WEBHOOK_SECRET - NEXT_PUBLIC_POLAR_ACCESS_TOKEN=YOUR_NEXT_PUBLIC_POLAR_ACCESS_TOKEN + NEXT_PUBLIC_POLAR_ACCESS_TOKEN=YOUR_NEXT_PUBLIC_POLAR_ACCESS_TOKEN + POLAR_WEBHOOK_SECRET=YOUR_POLAR_WEBHOOK_SECRET
- Add an empty line after the last entry.
apps/web/src/lib/polar.ts (1)
3-6
: Add tests for Polar client instantiation
Codecov indicates these lines lack coverage. Please add unit tests to verifyapi
is created with the correct token and server fallback. I can help generate example tests if needed.apps/web/src/lib/payment.ts (1)
3-6
: Cover DodoPayment instantiation with tests
The new client setup isn't covered by existing tests (codecov flagged). Add tests to assert proper environment selection and error handling for missing API key.apps/web/src/lib/logger.ts (1)
2-8
: Consider formalising structured logging & widen log levelsInline
console.*
calls work, but they quickly get messy once log volume grows.
A thin wrapper around a battle-tested lib (pino, winston) would give you:• JSON output → easier CloudWatch / Stackdriver parsing
• Additional log levels (debug
,warn
) and child-logger contexts
• Automatic error stack serialisationYou can still re-export the same
info
/error
API to keep call-sites unchanged.packages/payment/eslint.config.mjs (1)
18-20
: Why disableno-redeclare
globally?
no-redeclare
guards against accidental shadowing. If the rule is noisy for generated overloads you can disable it per-file with ESLint directives instead of blanket deactivation.apps/web/src/app/api/cron/sync-usage/route.ts (1)
8-12
:authorization
header comparison is brittleif (authHeader !== `Bearer ${CRON_SECRET}`) { … }This fails for trivial formatting differences (extra spaces, different case). Prefer a constant-time comparison after splitting the scheme and token:
- if (authHeader !== `Bearer ${CRON_SECRET}`) { + const token = authHeader?.split(' ')[1] ?? ''; + if (!crypto.timingSafeEqual(Buffer.from(token), Buffer.from(CRON_SECRET ?? ''))) {Also guard against missing
CRON_SECRET
at boot time.apps/web/src/app/[locale]/(dashboard)/[wsId]/billing/data-polar-checkout.tsx (1)
35-41
: Prefernext/link
over raw<a>
for internal navigationUsing
<a>
forces a full page reload and loses Next.js routing benefits. Wrap the anchor withLink
or useasChild
from your UI lib.-import React from 'react'; … -<a href={checkoutUrl} …> +import Link from 'next/link'; +<Link href={checkoutUrl} data-polar-checkout data-polar-checkout-theme={theme} className={className}> {children} -</a> +</Link>apps/web/src/types/api-types.ts (1)
12-17
: Enum casing may not match provider
'Day' | 'Week' | 'Month' | 'Year'
differs from common lowercase (day
,week
, …).
Ensure it mirrors the actual API, otherwise decoding will fail.apps/db/supabase/migrations/20250616064232_add_workspace_subscriptions.sql (1)
70-85
: Unused helper function
check_ws_creator(ws_id)
is defined but not used in any policy. Either reference it in the INSERT policy or remove to avoid dead code.packages/types/src/supabase.ts (3)
7920-7920
: Enum duplication risk – keep Constant list in lock-step with DB enum
subscription_status
is now declared twice: once in the autogeneratedEnums
section (l. 7920) and again insideConstants.public.Enums
(l. 8074).
The two sources must always match; forgetting to re-run the code-gen after an enum change silently desynchronises theConstants
helper.Automate the
Constants
generation or remove the hand-rolled list to avoid divergence.Also applies to: 8074-8074
7406-7408
:check_ws_creator
exposes security-critical logic – confirm return typeThe Postgres function returns a boolean but gives no clue whether it throws on missing records or simply returns
false
.
Upstream callers should treatfalse
as “not owner” rather than an error condition and add their own 404 / 403 handling.
8058-8103
: Do not hand-edit generated type fileChanges in this file are normally produced by
supabase gen types
.
Manual edits (especially toConstants
) will be lost on the next generation run and may introduce subtle type drift.
Prefer keeping bespoke helpers in a separate module (e.g.,supabaseConstants.ts
) and import them where needed.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
bun.lock
is excluded by!**/*.lock
📒 Files selected for processing (25)
apps/db/supabase/migrations/20250616064232_add_workspace_subscriptions.sql
(1 hunks)apps/web/.env.example
(1 hunks)apps/web/messages/en.json
(1 hunks)apps/web/messages/vi.json
(1 hunks)apps/web/package.json
(1 hunks)apps/web/src/app/[locale]/(dashboard)/[wsId]/billing/billing-client.tsx
(1 hunks)apps/web/src/app/[locale]/(dashboard)/[wsId]/billing/data-polar-checkout.tsx
(1 hunks)apps/web/src/app/[locale]/(dashboard)/[wsId]/billing/page.tsx
(1 hunks)apps/web/src/app/[locale]/(dashboard)/[wsId]/billing/success/page.tsx
(1 hunks)apps/web/src/app/[locale]/(dashboard)/[wsId]/layout.tsx
(2 hunks)apps/web/src/app/api/[wsId]/[productId]/payment/route.ts
(1 hunks)apps/web/src/app/api/cron/sync-usage/route.ts
(1 hunks)apps/web/src/app/api/webhooks/route.ts
(1 hunks)apps/web/src/lib/logger.ts
(1 hunks)apps/web/src/lib/payment.ts
(1 hunks)apps/web/src/lib/polar.ts
(1 hunks)apps/web/src/types/api-types.ts
(1 hunks)packages/payment/eslint.config.mjs
(1 hunks)packages/payment/package.json
(1 hunks)packages/payment/src/polar/checkout/embed.ts
(1 hunks)packages/payment/src/polar/index.ts
(1 hunks)packages/payment/src/polar/next/index.ts
(1 hunks)packages/payment/tsconfig.json
(1 hunks)packages/types/src/supabase.ts
(22 hunks)turbo.json
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/web/src/app/api/[wsId]/[productId]/payment/route.ts (1)
apps/web/src/lib/polar.ts (1)
api
(3-6)
🪛 dotenv-linter (3.3.0)
apps/web/.env.example
[warning] 43-43: [UnorderedKey] The NEXT_PUBLIC_PROXY_API_KEY key should go before the PROXY_API_KEY key
[warning] 47-47: [EndingBlankLine] No blank line at the end of the file
[warning] 47-47: [UnorderedKey] The NEXT_PUBLIC_POLAR_ACCESS_TOKEN key should go before the POLAR_WEBHOOK_SECRET key
🪛 GitHub Check: codecov/patch
apps/web/src/lib/polar.ts
[warning] 3-6: apps/web/src/lib/polar.ts#L3-L6
Added lines #L3 - L6 were not covered by tests
apps/web/src/lib/logger.ts
[warning] 2-8: apps/web/src/lib/logger.ts#L2-L8
Added lines #L2 - L8 were not covered by tests
apps/web/src/app/[locale]/(dashboard)/[wsId]/layout.tsx
[warning] 38-38: apps/web/src/app/[locale]/(dashboard)/[wsId]/layout.tsx#L38
Added line #L38 was not covered by tests
[warning] 380-386: apps/web/src/app/[locale]/(dashboard)/[wsId]/layout.tsx#L380-L386
Added lines #L380 - L386 were not covered by tests
apps/web/src/app/api/[wsId]/[productId]/payment/route.ts
[warning] 2-27: apps/web/src/app/api/[wsId]/[productId]/payment/route.ts#L2-L27
Added lines #L2 - L27 were not covered by tests
apps/web/src/app/[locale]/(dashboard)/[wsId]/billing/page.tsx
[warning] 2-258: apps/web/src/app/[locale]/(dashboard)/[wsId]/billing/page.tsx#L2-L258
Added lines #L2 - L258 were not covered by tests
apps/web/src/lib/payment.ts
[warning] 3-6: apps/web/src/lib/payment.ts#L3-L6
Added lines #L3 - L6 were not covered by tests
apps/web/src/app/[locale]/(dashboard)/[wsId]/billing/data-polar-checkout.tsx
[warning] 2-47: apps/web/src/app/[locale]/(dashboard)/[wsId]/billing/data-polar-checkout.tsx#L2-L47
Added lines #L2 - L47 were not covered by tests
apps/web/src/app/[locale]/(dashboard)/[wsId]/billing/success/page.tsx
[warning] 2-212: apps/web/src/app/[locale]/(dashboard)/[wsId]/billing/success/page.tsx#L2-L212
Added lines #L2 - L212 were not covered by tests
apps/web/src/app/[locale]/(dashboard)/[wsId]/billing/billing-client.tsx
[warning] 2-237: apps/web/src/app/[locale]/(dashboard)/[wsId]/billing/billing-client.tsx#L2-L237
Added lines #L2 - L237 were not covered by tests
apps/web/src/app/api/webhooks/route.ts
[warning] 2-3: apps/web/src/app/api/webhooks/route.ts#L2-L3
Added lines #L2 - L3 were not covered by tests
[warning] 7-10: apps/web/src/app/api/webhooks/route.ts#L7-L10
Added lines #L7 - L10 were not covered by tests
[warning] 12-13: apps/web/src/app/api/webhooks/route.ts#L12-L13
Added lines #L12 - L13 were not covered by tests
[warning] 15-18: apps/web/src/app/api/webhooks/route.ts#L15-L18
Added lines #L15 - L18 were not covered by tests
[warning] 21-24: apps/web/src/app/api/webhooks/route.ts#L21-L24
Added lines #L21 - L24 were not covered by tests
[warning] 26-29: apps/web/src/app/api/webhooks/route.ts#L26-L29
Added lines #L26 - L29 were not covered by tests
[warning] 31-31: apps/web/src/app/api/webhooks/route.ts#L31
Added line #L31 was not covered by tests
[warning] 33-40: apps/web/src/app/api/webhooks/route.ts#L33-L40
Added lines #L33 - L40 were not covered by tests
[warning] 43-46: apps/web/src/app/api/webhooks/route.ts#L43-L46
Added lines #L43 - L46 were not covered by tests
[warning] 48-54: apps/web/src/app/api/webhooks/route.ts#L48-L54
Added lines #L48 - L54 were not covered by tests
[warning] 56-60: apps/web/src/app/api/webhooks/route.ts#L56-L60
Added lines #L56 - L60 were not covered by tests
[warning] 62-68: apps/web/src/app/api/webhooks/route.ts#L62-L68
Added lines #L62 - L68 were not covered by tests
[warning] 71-71: apps/web/src/app/api/webhooks/route.ts#L71
Added line #L71 was not covered by tests
[warning] 73-76: apps/web/src/app/api/webhooks/route.ts#L73-L76
Added lines #L73 - L76 were not covered by tests
[warning] 78-79: apps/web/src/app/api/webhooks/route.ts#L78-L79
Added lines #L78 - L79 were not covered by tests
[warning] 81-95: apps/web/src/app/api/webhooks/route.ts#L81-L95
Added lines #L81 - L95 were not covered by tests
[warning] 97-98: apps/web/src/app/api/webhooks/route.ts#L97-L98
Added lines #L97 - L98 were not covered by tests
[warning] 100-109: apps/web/src/app/api/webhooks/route.ts#L100-L109
Added lines #L100 - L109 were not covered by tests
[warning] 111-111: apps/web/src/app/api/webhooks/route.ts#L111
Added line #L111 was not covered by tests
[warning] 113-116: apps/web/src/app/api/webhooks/route.ts#L113-L116
Added lines #L113 - L116 were not covered by tests
🔇 Additional comments (15)
packages/payment/src/polar/checkout/embed.ts (1)
1-1
: Simple Re-export Facade
This module cleanly re-exports everything from@polar-sh/checkout/embed
, providing a centralized entrypoint.apps/web/package.json (1)
48-48
: Add@tuturuuu/payment
Workspace Dependency
Including the new payment package aligns with the billing integration. Make sure the lockfile is updated to reflect this addition.apps/web/messages/en.json (1)
557-557
: Add translation key for billing sidebar tab.The
"billing": "Billing"
entry undersidebar_tabs
correctly introduces the new sidebar label for the billing feature and follows existing naming conventions.turbo.json (2)
16-18
: AI summary inconsistency: Google env vars removal not reflected.The AI-generated summary states that Google-related environment variables were removed, but they still exist on lines 16–18. Please confirm if those should indeed be dropped or retained.
Also applies to: 40-40
Likely an incorrect or invalid review comment.
40-40
: Add POLAR_WEBHOOK_SECRET to globalEnvIntroduces the new webhook secret for Polar integration. Ensure corresponding updates are made in
.env.example
, CI/CD settings, and project documentation.packages/payment/src/polar/next/index.ts (1)
1-1
: Proxy export for@polar-sh/nextjs
This re-export simplifies import paths across the monorepo. Verify that
@polar-sh/nextjs
is declared in the package’sdependencies
and that thefiles
/exports
field inpackage.json
includes this path.apps/web/messages/vi.json (2)
568-568
: Approve insertion of the new sidebar billing tab.
The"billing": "Thanh toán"
entry correctly maps the new billing route in the workspace sidebar. JSON remains valid and consistent with feature rollout.
615-615
: Approve translation in settings-tabs.
Adding"billing": "Thanh toán"
undersettings-tabs
aligns with the sidebar label and ensures consistency across the Vietnamese UI.packages/payment/src/polar/index.ts (1)
1-1
: Re-export Polar SDK via proxy module
This proxy correctly exposes the full@polar-sh/sdk
surface. Ensure that consumers tree-shake unused exports to keep bundle size optimal.packages/payment/tsconfig.json (1)
1-11
: TSConfig setup is correct
The config extends the shared React library settings, setsbaseUrl
, path alias for@tuturuuu/payment/*
, and correctly includes/excludes directories. No changes needed.packages/payment/package.json (1)
13-18
: Pinning very new versions – verify they are published & semver-safeAll dependencies are set to caret ranges on recent versions. Run CI with
npm ci
and ensure:
- versions actually exist on npm,
- no peer-dependency conflicts surface.
apps/web/src/app/[locale]/(dashboard)/[wsId]/layout.tsx (1)
38-38
: Stale import ordering comment resolved – looks goodReceipt icon is correctly imported next to other icons.
apps/web/src/app/api/webhooks/route.ts (1)
81-88
: Verify customer identifier path
payload.data.customer.id
may bepayload.data.customerId
depending on Polar’s schema.
Please double-check to avoid undefined errors.apps/web/src/types/api-types.ts (1)
1-5
: Confirm library mismatchTypes are pulled from
dodopayments/*
, whereas runtime code relies on@tuturuuu/payment
.
If Polar replaces Dodo, consider removing these legacy imports to avoid type drift.packages/types/src/supabase.ts (1)
6162-6211
: ```shell
#!/bin/bashList all workspace_* table definitions in the Supabase types file
grep -R "^[[:space:]]workspace_[a-z_]:" -n packages/types/src/supabase.ts
</details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
apps/db/supabase/migrations/20250616064232_add_workspace_subscriptions.sql
Outdated
Show resolved
Hide resolved
apps/db/supabase/migrations/20250616064232_add_workspace_subscriptions.sql
Show resolved
Hide resolved
apps/db/supabase/migrations/20250616064232_add_workspace_subscriptions.sql
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (1)
packages/types/src/supabase.ts (1)
1-8103
: Generated file – avoid manual tweaksJust a reminder: this file is generated by
supabase gen types
.
Any manual edits (e.g. the relationship note above) must be fixed in the SQL schema / migration so the next code-gen run keeps them; otherwise they’ll be overwritten.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
apps/db/supabase/migrations/20250616064232_add_workspace_subscriptions.sql
(1 hunks)apps/db/supabase/migrations/20250616135112_add_platform_services.sql
(1 hunks)packages/types/src/supabase.ts
(23 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- apps/db/supabase/migrations/20250616064232_add_workspace_subscriptions.sql
⏰ Context from checks skipped due to timeout of 90000ms (8)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Deploy-Preview
- GitHub Check: Deploy-Preview
- GitHub Check: Deploy-Preview
- GitHub Check: Deploy-Preview
- GitHub Check: Deploy-Preview
- GitHub Check: Run tests and collect coverage
- GitHub Check: Verify generated types
🔇 Additional comments (3)
packages/types/src/supabase.ts (3)
4513-4534
: Non-nullableservices
column – double-check upstream writes
users.services
is now typed as a non-nullableplatform_service[]
inRow
, but remains optional inInsert
/Update
.
If any caller still explicitly sendsnull
(rather than omitting the property and relying on the defaultarray[]
), the runtime insert/update will now fail at the DB layer.- services?: Database['public']['Enums']['platform_service'][]; + // keep optional but forbid null to surface early + services?: NonNullable< + Database['public']['Enums']['platform_service'][] + >;Run your integration tests (or grep for
services: null
) to make sure no payloads violate the new constraint.
Otherwise this change looks correct.
7905-7920
: Enum added correctly – LGTMThe new
subscription_status
enum is declared in both the union type and theConstants
helper array; nothing else to flag here.
7402-7405
: Confirmcheck_ws_creator
RPC is deployedTypes are in place, but make sure the new
check_ws_creator(ws_id uuid)
function is actually created andSECURITY DEFINER
/ RLS-safe in the migration, otherwise clients will get 404/permission errors.
Summary by CodeRabbit
New Features
Localization
Chores
Documentation