-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Add deletion of bounty submissions in bulkDeletePartners #3248
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?
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughOptimized bulk partner deletion logic by caching programEnrollmentIds array and reusing it across multiple Prisma queries. Added new deletion steps for messages and bounty submissions associated with program enrollments, improving code reusability and scope of deletions. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
apps/web/lib/api/partners/bulk-delete-partners.ts (1)
105-127: Consider batching messages and bounty submissions deletions for consistency.While the new deletions correctly clean up messages and bounty submissions, they don't use batching unlike the commissions deletion (lines 68-92). For consistency and to future-proof against potential scalability issues with large datasets, consider applying the same batching pattern used for commissions.
🔎 Example batching pattern for messages and bounty submissions
Apply batching similar to commissions:
- // Delete the messages - const deletedMessages = await prisma.message.deleteMany({ - where: { - programEnrollment: { - id: { - in: programEnrollmentIds, - }, - }, - }, - }); - console.log(`Deleted ${deletedMessages.count} messages`); + // Delete the messages + while (true) { + const messagesToDelete = await prisma.message.findMany({ + where: { + programEnrollment: { + id: { + in: programEnrollmentIds, + }, + }, + }, + take: BATCH_SIZE, + }); + + if (messagesToDelete.length === 0) { + break; + } + + const deletedMessages = await prisma.message.deleteMany({ + where: { + id: { + in: messagesToDelete.map((message) => message.id), + }, + }, + }); + console.log(`Deleted ${deletedMessages.count} messages`); + } - // Delete the bounty submissions - const deletedBountySubmissions = await prisma.bountySubmission.deleteMany({ - where: { - programEnrollment: { - id: { - in: programEnrollmentIds, - }, - }, - }, - }); - console.log(`Deleted ${deletedBountySubmissions.count} bounty submissions`); + // Delete the bounty submissions + while (true) { + const bountySubmissionsToDelete = await prisma.bountySubmission.findMany({ + where: { + programEnrollment: { + id: { + in: programEnrollmentIds, + }, + }, + }, + take: BATCH_SIZE, + }); + + if (bountySubmissionsToDelete.length === 0) { + break; + } + + const deletedBountySubmissions = await prisma.bountySubmission.deleteMany({ + where: { + id: { + in: bountySubmissionsToDelete.map((bs) => bs.id), + }, + }, + }); + console.log(`Deleted ${deletedBountySubmissions.count} bounty submissions`); + }
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/web/lib/api/partners/bulk-delete-partners.ts(4 hunks)
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: TWilson023
Repo: dubinc/dub PR: 3098
File: apps/web/lib/actions/partners/message-program.ts:49-58
Timestamp: 2025-11-12T22:23:10.414Z
Learning: In apps/web/lib/actions/partners/message-program.ts, when checking if a partner can continue messaging after messaging is disabled, the code intentionally requires `senderPartnerId: null` (program-initiated messages) to prevent partners from continuing to send junk messages. Only conversations started by the program should continue after messaging is disabled, as a spam prevention mechanism.
Learnt from: TWilson023
Repo: dubinc/dub PR: 2872
File: apps/web/lib/actions/partners/update-partner-profile.ts:97-104
Timestamp: 2025-09-24T15:57:55.285Z
Learning: In the Dub codebase, the team prefers to maintain consistency with existing patterns for database operations, even if there are theoretical improvements available. The deleteMany: {} pattern for relation updates is an accepted approach that the team considers low-risk.
📚 Learning: 2025-12-03T09:19:48.164Z
Learnt from: devkiran
Repo: dubinc/dub PR: 3175
File: apps/web/lib/actions/partners/bulk-reject-partner-applications.ts:14-21
Timestamp: 2025-12-03T09:19:48.164Z
Learning: In apps/web/lib/actions/partners/bulk-reject-partner-applications.ts, the bulkRejectPartnerApplicationsAction does not need explicit plan capability checks for fraud operations (when reportFraud is true) because the authorization is handled automatically by the underlying fraud operation functions (resolveFraudGroups, createFraudEvents) or through other automated mechanisms in the system.
Applied to files:
apps/web/lib/api/partners/bulk-delete-partners.ts
📚 Learning: 2025-11-12T22:23:10.414Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 3098
File: apps/web/lib/actions/partners/message-program.ts:49-58
Timestamp: 2025-11-12T22:23:10.414Z
Learning: In apps/web/lib/actions/partners/message-program.ts, when checking if a partner can continue messaging after messaging is disabled, the code intentionally requires `senderPartnerId: null` (program-initiated messages) to prevent partners from continuing to send junk messages. Only conversations started by the program should continue after messaging is disabled, as a spam prevention mechanism.
Applied to files:
apps/web/lib/api/partners/bulk-delete-partners.ts
📚 Learning: 2025-09-17T17:44:03.965Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2857
File: apps/web/lib/actions/partners/update-program.ts:96-0
Timestamp: 2025-09-17T17:44:03.965Z
Learning: In apps/web/lib/actions/partners/update-program.ts, the team prefers to keep the messagingEnabledAt update logic simple by allowing client-provided timestamps rather than implementing server-controlled timestamp logic to avoid added complexity.
Applied to files:
apps/web/lib/api/partners/bulk-delete-partners.ts
📚 Learning: 2025-06-06T07:59:03.120Z
Learnt from: devkiran
Repo: dubinc/dub PR: 2177
File: apps/web/lib/api/links/bulk-create-links.ts:66-84
Timestamp: 2025-06-06T07:59:03.120Z
Learning: In apps/web/lib/api/links/bulk-create-links.ts, the team accepts the risk of potential undefined results from links.find() operations when building invalidLinks arrays, because existing links are fetched from the database based on the input links, so matches are expected to always exist.
Applied to files:
apps/web/lib/api/partners/bulk-delete-partners.ts
⏰ 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: build
🔇 Additional comments (2)
apps/web/lib/api/partners/bulk-delete-partners.ts (2)
29-29: LGTM! Good optimization.Caching the program enrollment IDs avoids repeated mapping operations and improves code readability.
73-73: LGTM! Consistent use of cached IDs.The consistent use of
programEnrollmentIdsacross all queries improves maintainability and eliminates duplicate mapping operations.Also applies to: 98-98, 143-143
| // Delete the messages | ||
| const deletedMessages = await prisma.message.deleteMany({ | ||
| where: { | ||
| programEnrollment: { | ||
| id: { | ||
| in: programEnrollments.map((pe) => pe.id), | ||
| in: programEnrollmentIds, | ||
| }, | ||
| }, | ||
| }, | ||
| }); | ||
| console.log(`Deleted ${deletedMessages.count} messages`); | ||
|
|
||
| // Delete the bounty submissions | ||
| const deletedBountySubmissions = await prisma.bountySubmission.deleteMany({ | ||
| where: { | ||
| programEnrollment: { | ||
| id: { | ||
| in: programEnrollmentIds, | ||
| }, | ||
| }, | ||
| }, | ||
| }); | ||
| console.log(`Deleted ${deletedBountySubmissions.count} bounty submissions`); |
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.
🧩 Analysis chain
🏁 Script executed:
cat -n apps/web/lib/api/partners/bulk-delete-partners.ts | head -150Repository: dubinc/dub
Length of output: 4791
🏁 Script executed:
fd -e prismaRepository: dubinc/dub
Length of output: 1223
🏁 Script executed:
rg -n 'programEnrollment' --type ts -B 2 -A 2 | head -100Repository: dubinc/dub
Length of output: 6732
🏁 Script executed:
rg -n 'programEnrollment' packages/prisma/schema/ -A 3 -B 1Repository: dubinc/dub
Length of output: 4613
🏁 Script executed:
# Also search for models that might reference programEnrollment indirectly or through relations
rg -n 'ProgramEnrollment' packages/prisma/schema/ --type prismaRepository: dubinc/dub
Length of output: 84
🏁 Script executed:
# Check if DiscountCode is being deleted elsewhere or has cascade rules
rg -n 'discountCode\|DiscountCode' apps/web/lib/api/partners/bulk-delete-partners.tsRepository: dubinc/dub
Length of output: 36
🏁 Script executed:
# Check full DiscountCode schema definition
cat -n packages/prisma/schema/discount.prismaRepository: dubinc/dub
Length of output: 1909
🏁 Script executed:
# Check FraudCheck schema to confirm cascade behavior
cat -n packages/prisma/schema/fraud.prismaRepository: dubinc/dub
Length of output: 3311
DiscountCode records must be deleted to prevent orphaned foreign keys.
The deletions are incomplete. The code deletes links (line 56-65), but DiscountCode has a required foreign key to Link without cascading deletion. This will leave orphaned DiscountCode records after links are deleted. Additionally, DiscountCode references programEnrollment optionally, which is also being deleted. Add explicit deletion of DiscountCode records that reference the programs being cleaned up.
🤖 Prompt for AI Agents
In apps/web/lib/api/partners/bulk-delete-partners.ts around lines 105 to 127,
you must also remove DiscountCode records to avoid FK constraint/orphan issues:
add explicit deleteMany calls for DiscountCode that target records referencing
the programEnrollmentIds (and any linkIds you remove) before deleting
Links/ProgramEnrollments; in practice run prisma.discountCode.deleteMany({
where: { OR: [{ programEnrollmentId: { in: programEnrollmentIds } }, { linkId: {
in: linkIds } }] } }) (or separate deletes) prior to deleting links/enrollments
so required foreign keys are not left orphaned.
Summary by CodeRabbit
Bug Fixes
Chores
✏️ Tip: You can customize this high-level summary in your review settings.