-
Notifications
You must be signed in to change notification settings - Fork 182
Fix/subscription metadata priceid remove #15
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
base: main
Are you sure you want to change the base?
Fix/subscription metadata priceid remove #15
Conversation
…dated in Polar. Select the latest subscription when querying subscription based on userId.
…. priceId is not updated after a user changes the subscription creating confusion. Changes Summary: Checkout Creation (lines 52-54): - REMOVED: priceId: productPriceId, from the metadata object - RESULT: Metadata now only contains userId when creating Polar checkouts Impact: - Polar subscriptions: Will only store userId in metadata (no priceId) - Convex subscriptions: Will only store userId in metadata (no priceId) - Price tracking: Still works via the polarPriceId field in the subscription record - User linking: Preserved via userId in metadata for webhook processing
@pax2678 is attempting to deploy a commit to the Goshen Labs Team on Vercel. A member of the Team first needs to authorize it. |
WalkthroughThe checkout flow no longer stores priceId in metadata. Subscription queries now sort by createdAt descending and use the latest record. The subscription.updated webhook now persists polarPriceId (from price_id) onto the subscription record. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Backend as Subscriptions API
Client->>Backend: createCheckout()
Note right of Backend: Do not include priceId in metadata
Backend-->>Client: Checkout session created
sequenceDiagram
participant Webhook as Polar Webhook
participant Backend as Subscriptions API
participant DB as Subscriptions DB
Webhook->>Backend: subscription.updated(price_id)
Backend->>DB: Update subscription.polarPriceId = price_id
DB-->>Backend: OK
sequenceDiagram
participant Client
participant Backend as Subscriptions API
participant DB as Subscriptions DB
Client->>Backend: checkUserSubscriptionStatus(...)
Backend->>DB: Query subscriptions ORDER BY createdAt DESC
DB-->>Backend: Latest subscription
Backend-->>Client: Latest status
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ 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. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Explore these optional code suggestions:
|
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: 3
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
convex/subscriptions.ts
(5 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: cubic · AI code reviewer
🔇 Additional comments (3)
convex/subscriptions.ts (3)
187-187
: Whitespace-only change — safe to ignoreNo functional impact.
196-196
: Whitespace-only change — safe to ignoreNo functional impact.
333-345
: Persisting polarPriceId on subscription updates is correctStoring args.body.data.price_id into polarPriceId keeps your subscription record in sync with Polar even when the price changes after creation. This complements the insert path which already sets polarPriceId.
.order("desc") // Order by createdAt in descending order | ||
.first(); |
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.
💡 Verification agent
🧩 Analysis chain
“Order by createdAt” isn’t achieved; current index doesn’t guarantee latest subscription
.withIndex("userId", …).order("desc") will order by the index key (userId) and then by internal doc id, not by createdAt. This can return an arbitrary subscription for the user and lead to incorrect hasActiveSubscription results.
Prefer ordering by a time field that exists on the subscription document and is indexed as a secondary key. Since you already persist startedAt, index on (userId, startedAt) and order desc to get the most recent subscription for the user.
Apply this change in the query to use a compound index:
- .withIndex("userId", (q) => q.eq("userId", user.tokenIdentifier))
- .order("desc") // Order by createdAt in descending order
+ .withIndex("by_userId_startedAt", (q) => q.eq("userId", user.tokenIdentifier))
+ .order("desc") // Latest by startedAt
Add the corresponding index in your Convex schema (example):
// convex/schema.ts
defineTable({
// ... other fields ...
userId: v.string(),
startedAt: v.number(), // already present in your inserts
})
.index("by_userId", ["userId"])
.index("by_userId_startedAt", ["userId", "startedAt"]);
Verification script to confirm the index exists in your schema and to find all places to update:
🏁 Script executed:
#!/bin/bash
# Look for Convex schema and check for the compound index and subscriptions table fields.
fd -a -t f 'schema' | while read -r f; do
echo "== $f ==";
rg -n -C2 -H 'defineTable|subscriptions|index\(|startedAt' "$f";
done
# Find all queries over "subscriptions" using the "userId" index
rg -n -C2 --type=ts '\.query\("subscriptions"\).*?\.withIndex\("userId"' convex
Length of output: 2415
#!/bin/bash
# Confirm the subscription query uses withIndex("userId") and ordering on createdAt
rg -n 'withIndex\("userId"' -C3 --type=ts convex/subscriptions.ts
rg -n 'query\("subscriptions"' -C3 --type=ts convex/subscriptions.ts
#!/bin/bash
# Display the query on subscriptions and its index usage around withIndex("userId")
rg -nP 'query\("subscriptions".*?withIndex\("userId"' -C4 convex/subscriptions.ts
Update subscription query to use a compound index on startedAt and add that index
The current query in convex/subscriptions.ts
is still using:
.withIndex("userId", (q) => q.eq("userId", user.tokenIdentifier))
.order("desc") // Order by createdAt in descending order
.first();
That will sort by the index key (userId) and then by internal document ID—not by your timestamp field—so you won’t reliably get the most recent subscription.
Please make the following critical fixes:
• In convex/subscriptions.ts
(around lines 200–201), change to:
- .withIndex("userId", (q) => q.eq("userId", user.tokenIdentifier))
- .order("desc") // Order by createdAt in descending order
+ .withIndex("by_userId_startedAt", (q) =>
+ q.eq("userId", user.tokenIdentifier)
+ )
+ .order("desc") // Latest by startedAt
.first();
• In your schema file (convex/schema.ts
), add the compound index on startedAt
:
subscriptions: defineTable({
userId: v.optional(v.string()),
// … other fields …
startedAt: v.optional(v.number()),
})
- .index("userId", ["userId"])
+ .index("userId", ["userId"])
+ .index("by_userId_startedAt", ["userId", "startedAt"])
.index("polarId", ["polarId"]),
After deploying these changes, your .order("desc")
will correctly return the subscription with the highest startedAt
for a given user.
🤖 Prompt for AI Agents
In convex/subscriptions.ts around lines 200–201, the query uses
.withIndex("userId", ...) which sorts by userId and internal ID instead of your
timestamp; update the query to use a compound index that includes startedAt
(e.g., .withIndex("userId_startedAt", q => q.eq("userId",
user.tokenIdentifier)).order("desc").first()) so the .order("desc") sorts by
startedAt; then in convex/schema.ts add a compound index declaration for the
subscriptions table that includes userId and startedAt (e.g., an index named
userId_startedAt with keys [userId, startedAt]) and deploy the schema so the
query can use that new index.
.order("desc") // Order by createdAt in descending order | ||
.first(); |
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.
🛠️ Refactor suggestion
Same ordering issue here — switch to a compound (userId, startedAt) index
This query also won’t reliably return the latest subscription for the user. Use the same index and ordering approach as above.
Apply this change:
- .withIndex("userId", (q) => q.eq("userId", user.tokenIdentifier))
- .order("desc") // Order by createdAt in descending order
+ .withIndex("by_userId_startedAt", (q) => q.eq("userId", user.tokenIdentifier))
+ .order("desc") // Latest by startedAt
🤖 Prompt for AI Agents
In convex/subscriptions.ts around lines 237-238, the query currently orders by
createdAt desc which won’t reliably return the user’s latest subscription;
switch to using the compound index on (userId, startedAt) and order by startedAt
descending when querying for a user's latest subscription. Update the query to
filter by userId, use the compound index (userId, startedAt), order by startedAt
in descending order and then take the first result, and ensure the compound
index exists in the schema if not already defined.
.order("desc") // Order by createdAt in descending order | ||
.first(); |
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.
🛠️ Refactor suggestion
Same ordering issue — ensure you truly fetch the latest subscription
Use the (userId, startedAt) compound index and order desc to select the most recent subscription.
Apply this change:
- .withIndex("userId", (q) => q.eq("userId", user.tokenIdentifier))
- .order("desc") // Order by createdAt in descending order
+ .withIndex("by_userId_startedAt", (q) => q.eq("userId", user.tokenIdentifier))
+ .order("desc") // Latest by startedAt
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
.order("desc") // Order by createdAt in descending order | |
.first(); | |
.withIndex("by_userId_startedAt", (q) => q.eq("userId", user.tokenIdentifier)) | |
.order("desc") // Latest by startedAt | |
.first(); |
🤖 Prompt for AI Agents
In convex/subscriptions.ts around lines 265-266, the query currently orders by
createdAt and may not reliably return the latest subscription; change the query
to use the (userId, startedAt) compound index, order by startedAt descending and
keep the single-row fetch (first/limit 1) so it reliably returns the most recent
subscription for the user.
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.
No issues found across 1 file
fix inconsistent priceId value in metadata stored in Polar and Convex. priceId is not updated after a user changes the subscription creating confusion.
Changes Summary:
Checkout Creation (lines 52-54):
REMOVED: priceId: productPriceId, from the metadata object
RESULT: Metadata now only contains userId when creating Polar checkouts
Impact:
Polar subscriptions: Will only store userId in metadata (no priceId)
Convex subscriptions: Will only store userId in metadata (no priceId)
Price tracking: Still works via the polarPriceId field in the subscription record
User linking: Preserved via userId in metadata for webhook processing
Summary by cubic
Removed priceId from Polar/Convex metadata and now rely on polarPriceId stored on the subscription. This fixes stale price references and ensures we always read the latest subscription for a user.
Summary by CodeRabbit
Bug Fixes
Chores