Skip to content

fix: harmonize account settings between browser and desktop app#3308

Closed
devin-ai-integration[bot] wants to merge 3 commits intomainfrom
devin/1769092814-fix-account-settings-discrepancy
Closed

fix: harmonize account settings between browser and desktop app#3308
devin-ai-integration[bot] wants to merge 3 commits intomainfrom
devin/1769092814-fix-account-settings-discrepancy

Conversation

@devin-ai-integration
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot commented Jan 22, 2026

Summary

Fixes two related billing display issues:

  1. Desktop showing "PRO" for trial users: The desktop app only checked for hyprnote_pro entitlement without distinguishing subscription status. Now it reads subscription_status from JWT claims to show "TRIAL (ends [date])" for trialing users.

  2. Web showing "Trial" for paid Pro users: The syncAfterSuccess function was returning the first subscription found (sorted by creation date) regardless of status, which could return a canceled or old trialing subscription. Now it explicitly prioritizes active subscriptions over trialing.

Changes:

  • Add subscription_status and trial_end claims to JWT via a new Supabase auth hook migration
  • Update desktop billing context to extract and expose subscription status from JWT
  • Update desktop account settings UI to show "TRIAL (ends [date])" for trialing users
  • Fix web billing sync to prioritize active subscriptions over trialing ones
  • Define SubscriptionStatus type locally in desktop billing.tsx (also exported from @hypr/supabase)

Updates since last revision

  • Fixed web billing: syncAfterSuccess now searches for active subscriptions first, then falls back to trialing, instead of blindly taking the first subscription returned by Stripe API

Review & Testing Checklist for Human

  • Verify SQL migration syntax — The (s.trial_end #>> '{}')::bigint extraction from jsonb should be tested in staging first; malformed or missing trial_end values could cause the auth hook to error, breaking login for all users
  • Test with user who has multiple subscriptions — The web billing change removes limit: 1 from the Stripe API call. Verify it correctly finds the active subscription among multiple (canceled, trialing, active). This is the highest-risk behavioral change on the web side.
  • Test desktop with trial user — Verify desktop shows "TRIAL (ends [date])" with correct end date derived from the JWT trial_end claim (Unix seconds → JS milliseconds conversion)
  • Test desktop with paid Pro user — Verify paid users still see "PRO" (not "TRIAL")
  • Test web with paid Pro user — Verify the web account page shows "Pro" (not "Trial") for users with active subscriptions

Recommended test plan:

  1. Deploy migration to staging
  2. Test with a user who has an active (paid) subscription — verify both web and desktop show "Pro"
  3. Test with a user who has a trialing subscription — verify web shows "Trial" and desktop shows "TRIAL (ends [date])"
  4. If possible, test with a user who has both a canceled subscription and an active one — verify the active one is displayed

Notes

  • The migration creates a new RLS policy on stripe.subscriptions for supabase_auth_admin — required for the auth hook to query subscription data
  • Trial end timestamp is stored in seconds (Unix timestamp) and converted to milliseconds for JavaScript Date
  • The SubscriptionStatus type is duplicated between packages/supabase/src/jwt.ts and apps/desktop/src/billing.tsx to avoid adding a new package dependency to the desktop app — these could drift if one is updated without the other
  • Web billing change removes limit: 1 from Stripe API call to allow searching through all subscriptions for the active one

Link to Devin run: https://app.devin.ai/sessions/1b9ae9acc87349e393883ca54ed961c6
Requested by: @ComputelessComputer

- Add subscription_status and trial_end claims to JWT via auth hook
- Update desktop billing context to extract and expose subscription status
- Update account settings UI to show 'TRIAL' for trialing users instead of 'PRO'
- Add trial end date display when available
- Export SubscriptionStatus type from @hypr/supabase package

This fixes the discrepancy where browser showed 'Trial' but desktop showed 'PRO'
for users on trial subscriptions.

Co-Authored-By: john@hyprnote.com <john@hyprnote.com>
@devin-ai-integration
Copy link
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI' or '@devin'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@netlify
Copy link

netlify bot commented Jan 22, 2026

Deploy Preview for howto-fix-macos-audio-selection canceled.

Name Link
🔨 Latest commit 072432c
🔍 Latest deploy log https://app.netlify.com/projects/howto-fix-macos-audio-selection/deploys/69723d9bf5850600088d160e

@netlify
Copy link

netlify bot commented Jan 22, 2026

Deploy Preview for hyprnote ready!

Name Link
🔨 Latest commit 072432c
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote/deploys/69723d9c9c941d00081272ce
😎 Deploy Preview https://deploy-preview-3308--hyprnote.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link

netlify bot commented Jan 22, 2026

Deploy Preview for hyprnote-storybook canceled.

Name Link
🔨 Latest commit 072432c
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote-storybook/deploys/69723d9b892e9200088c1453

devin-ai-integration bot and others added 2 commits January 22, 2026 14:45
… @hypr/supabase

The desktop app doesn't have @hypr/supabase as a dependency, so we define
the SubscriptionStatus type locally to avoid the 'Cannot find module' error.

Co-Authored-By: john@hyprnote.com <john@hyprnote.com>
The syncAfterSuccess function was returning the first subscription found
(sorted by creation date) regardless of status. This could return a
canceled or old trialing subscription instead of the active one.

Now it explicitly searches for 'active' subscriptions first, then falls
back to 'trialing' if no active subscription exists. This ensures paid
Pro users see 'Pro' instead of 'Trial' in their web account settings.

Co-Authored-By: john@hyprnote.com <john@hyprnote.com>
@yujonglee yujonglee closed this Jan 23, 2026
@yujonglee yujonglee deleted the devin/1769092814-fix-account-settings-discrepancy branch January 23, 2026 10:38
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