Skip to content

Limit bounty eligibility to selected partner tags#4045

Open
devkiran wants to merge 24 commits into
mainfrom
limit-bounties-partner-tags
Open

Limit bounty eligibility to selected partner tags#4045
devkiran wants to merge 24 commits into
mainfrom
limit-bounties-partner-tags

Conversation

@devkiran

@devkiran devkiran commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

Release Notes

  • New Features

    • Added partner tag-based bounty eligibility alongside existing partner group eligibility.
    • Updated bounty add/edit UI to configure groupIds and partnerTagIds via a unified eligibility section.
    • Bounty APIs and embedded/partner flows now include and accept partnerTags.
  • Bug Fixes

    • Strengthened eligibility enforcement across bounty endpoints, uploads, and social-content access using both tags and groups.
  • Chores

    • Updated cron eligibility syncing and webhook/sample payloads to include partnerTags.

@vercel

vercel Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
dub Ready Ready Preview Jun 24, 2026 8:07am

Request Review

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds partner tag-based bounty eligibility alongside the existing partner group mechanism. Introduces BountyPartnerTag, shared eligibility helpers, updates bounty and submission flows, propagates enrollment tag IDs through workflows and embeds, and replaces the inline groups selector with a bounty eligibility form section.

Changes

Partner Tag Bounty Eligibility

Layer / File(s) Summary
Schema and contract updates
apps/web/prisma/schema/bounty.prisma, apps/web/prisma/schema/tag.prisma, apps/web/lib/zod/schemas/bounties.ts, apps/web/lib/zod/schemas/partner-profile.ts, apps/web/lib/types.ts, apps/web/lib/webhook/sample-events/bounty-*.json
Adds the BountyPartnerTag relation model, extends bounty schemas with partnerTagIds and partnerTags, omits partnerTags from PartnerBountySchema, adds partnerTagIds to WorkflowIdentity, and updates bounty sample events.
Shared eligibility helpers
apps/web/lib/bounty/api/bounty-eligibility.ts, apps/web/lib/api/tags/throw-if-invalid-partner-tag-ids.ts
Adds Prisma filtering, in-memory eligibility checks, shared bounty include selection, and partner tag ID validation helpers.
Bounty API queries and writes
apps/web/app/(ee)/api/bounties/route.ts, apps/web/app/(ee)/api/bounties/[bountyId]/route.ts, apps/web/app/(ee)/api/bounties/[bountyId]/submissions/route.ts, apps/web/lib/bounty/api/get-bounties-for-partner.ts, apps/web/lib/bounty/api/get-bounty-with-details.ts
Updates bounty list/create/update/delete flows to derive, validate, persist, and return partner tags, and switches related lookup/query helpers to shared eligibility-aware fetching.
Submission upload and creation eligibility
apps/web/lib/bounty/api/create-bounty-submission.ts, apps/web/lib/bounty/api/get-bounty-submission-upload-url.ts, apps/web/lib/actions/partners/upload-bounty-submission-file.ts
Refactors submission creation and upload URL generation to load partner tags and enforce shared group-and-tag eligibility.
Partner-profile and embed access checks
apps/web/app/(ee)/api/partner-profile/programs/[programId]/bounties/[bountyId]/route.ts, apps/web/app/(ee)/api/partner-profile/programs/[programId]/bounties/[bountyId]/social-content-stats/route.ts, apps/web/app/(ee)/api/partner-profile/programs/[programId]/bounties/route.ts, apps/web/app/(ee)/api/embed/referrals/bounties/[bountyId]/social-content-stats/route.ts
Updates partner-scoped bounty routes to fetch program partner tags, include bounty eligibility relations, and enforce access with shared eligibility checks.
Workflow and cron propagation
apps/web/lib/api/workflows/execute-workflows.ts, apps/web/lib/api/workflows/execute-complete-bounty-workflow.ts, apps/web/lib/bounty/api/trigger-draft-bounty-submissions.ts, apps/web/app/(ee)/api/cron/bounties/create-draft-submissions/route.ts, apps/web/app/(ee)/api/cron/bounties/notify-partners/route.ts
Extends workflow identity with partner tag IDs, updates completion eligibility, rewrites draft-submission fanout around bounty tag eligibility, and filters cron enrollment queries by partner tags.
Enrollment tag propagation
apps/web/lib/embed/referrals/auth.ts, apps/web/app/(ee)/app.dub.co/embed/referrals/get-referrals-embed-data.ts, apps/web/lib/actions/partners/tags/update-program-partner-tags.ts
Propagates enrollment partner tag IDs through embed and referral data paths, and schedules draft-submission creation after partner tag additions.
Bounty eligibility UI
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/bounty-eligibility.tsx, apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/add-edit-bounty-sheet.tsx, apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/use-add-edit-bounty-form.ts, apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/confirm-create-bounty-modal.tsx
Adds the bounty eligibility editor, replaces the inline groups selector, and wires partner tag IDs through the bounty form and confirmation modal typing/payload.

Sequence Diagram(s)

sequenceDiagram
  participant Partner
  participant BountyRoute as Partner bounty route
  participant getProgramEnrollmentOrThrow
  participant getBountyOrThrow
  participant isPartnerEligibleForBounty

  Partner->>BountyRoute: GET bounty details
  BountyRoute->>getProgramEnrollmentOrThrow: include programPartnerTags
  getProgramEnrollmentOrThrow-->>BountyRoute: partnerGroupId + partnerTagIds
  BountyRoute->>getBountyOrThrow: include bountyEligibilityIncludes
  getBountyOrThrow-->>BountyRoute: bountyGroupIds + bountyTagIds
  BountyRoute->>isPartnerEligibleForBounty: evaluate eligibility
  isPartnerEligibleForBounty-->>BountyRoute: true / false
Loading
sequenceDiagram
  participant Trigger as triggerDraftBountySubmissionCreation
  participant Prisma
  participant isPartnerEligibleForBounty
  participant QStash

  Trigger->>Prisma: load eligible bounties + enrollments
  Prisma-->>Trigger: bounty and partner tag data
  loop per bounty
    Trigger->>isPartnerEligibleForBounty: group IDs + tag IDs
    isPartnerEligibleForBounty-->>Trigger: eligible partner IDs
    Trigger->>QStash: publishJSON draft submissions
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • dubinc/dub#3986: Both PRs modify execute-complete-bounty-workflow.ts and adjust bounty execution gating logic.

Suggested reviewers

  • steven-tey
  • pepeladeira

🐇 Tags and groups now hop in sync,
Across the code they link and link.
A bounty checks both paths at once,
And rabbit ears approve the nouns.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the main change: restricting bounty eligibility via partner tags.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch limit-bounties-partner-tags

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@devkiran devkiran marked this pull request as ready for review June 22, 2026 10:01

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (1)
apps/web/lib/api/tags/throw-if-invalid-partner-tag-ids.ts (1)

24-26: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Use a Set for invalid-tag detection to avoid quadratic scans.

The current filter + some check is O(n*m). A Set makes this O(n) and keeps behavior identical.

♻️ Suggested refactor
-    const invalidPartnerTagIds = partnerTagIds?.filter(
-      (partnerTagId) => !partnerTags?.some((tag) => tag.id === partnerTagId),
-    );
+    const validPartnerTagIdSet = new Set(partnerTags.map((tag) => tag.id));
+    const invalidPartnerTagIds = partnerTagIds.filter(
+      (partnerTagId) => !validPartnerTagIdSet.has(partnerTagId),
+    );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/lib/api/tags/throw-if-invalid-partner-tag-ids.ts` around lines 24 -
26, The current implementation of invalidPartnerTagIds has O(n*m) complexity due
to the nested filter and some operations. To optimize this, create a Set from
the valid partnerTags IDs first (by mapping tag.id from the partnerTags array
into a Set), then use that Set in the filter operation to check if each
partnerTagId exists. This changes the complexity to O(n) while maintaining
identical behavior. Replace the filter and some check with a simple Set.has()
lookup.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/web/app/`(ee)/api/cron/bounties/notify-partners/route.ts:
- Around line 16-18: The TODO comment near the top of the route.ts file is vague
and provides no actionable context about what needs to be fixed. Either replace
the comment with a specific, detailed description of what issue needs to be
addressed (including relevant details like function names, expected behavior, or
known problems), or remove the comment entirely if the issue has already been
resolved or is no longer relevant.

In
`@apps/web/app/app.dub.co/`(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/bounty-eligibility.tsx:
- Around line 164-170: The useEffect hook that checks the threshold condition
for `groups` (and similarly for `partnerTags` at line 230) includes `useAsync`
in its dependency array, causing a flip-flop effect. When the threshold is met
and `useAsync` is set to true via `setUseAsync`, this change triggers the effect
again, but now the condition evaluates differently and sets it back to false.
Remove `useAsync` from the dependency array in both effects and instead use a
functional updater pattern with `setUseAsync` that checks the previous state
value to prevent this repeating cycle. Apply this fix to both occurrences: the
one with `groups` and `GROUPS_MAX_PAGE_SIZE` around line 166, and the one with
`partnerTags` and `PARTNER_TAGS_MAX_PAGE_SIZE` around line 230.

In `@apps/web/lib/bounty/api/bounty-eligibility.ts`:
- Around line 75-85: The isPartnerEligibleForBounty function can return null
instead of a boolean because when partnerGroupId is null/falsy, the expression
(partnerGroupId && bountyTagIds.includes(partnerGroupId)) evaluates to null
rather than false. Fix this by explicitly converting the inGroup assignment to
always return a boolean value, either by using the double negation operator (!!)
on the inGroup expression or by ensuring the logical AND operation in the return
statement at line 84 always produces a proper boolean result.

In `@apps/web/lib/bounty/api/get-bounty-submission-upload-url.ts`:
- Around line 16-21: The `ProgramEnrollmentWithPartnerTags` type incorrectly
references `BountyPartnerTag` instead of `ProgramPartnerTag` for the
`programPartnerTags` field. Since `ProgramEnrollment` has a relation to
`ProgramPartnerTag` and the actual data returned from
`getProgramEnrollmentOrThrow` provides `ProgramPartnerTag[]`, change the type
definition to use `ProgramPartnerTag` instead of `BountyPartnerTag` in the Pick
statement. Apply the same fix in the other location mentioned in
`apps/web/lib/embed/referrals/auth.ts` at line 32 to maintain type consistency
across the codebase.

In `@apps/web/ui/partners/tags/partner-tags-multi-select.tsx`:
- Around line 55-65: The useEffect hook in partner-tags-multi-select.tsx is
creating an oscillation loop due to the `!useAsync` condition in the Boolean
expression. The effect sets useAsync to true when partnerTags.length exceeds
PARTNER_TAGS_MAX_PAGE_SIZE, but then immediately toggles it back to false on the
next run because useAsync is now true. Remove the `!useAsync` check from the
condition so that the effect only enables useAsync when the threshold is met
without toggling it back off. The condition should simply be
`Boolean(partnerTags && partnerTags.length >= PARTNER_TAGS_MAX_PAGE_SIZE)`.

---

Nitpick comments:
In `@apps/web/lib/api/tags/throw-if-invalid-partner-tag-ids.ts`:
- Around line 24-26: The current implementation of invalidPartnerTagIds has
O(n*m) complexity due to the nested filter and some operations. To optimize
this, create a Set from the valid partnerTags IDs first (by mapping tag.id from
the partnerTags array into a Set), then use that Set in the filter operation to
check if each partnerTagId exists. This changes the complexity to O(n) while
maintaining identical behavior. Replace the filter and some check with a simple
Set.has() lookup.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1e1f6c78-ed99-42ae-ab4c-b251134211aa

📥 Commits

Reviewing files that changed from the base of the PR and between cbf2171 and f68639d.

📒 Files selected for processing (35)
  • apps/web/app/(ee)/api/bounties/[bountyId]/route.ts
  • apps/web/app/(ee)/api/bounties/[bountyId]/submissions/route.ts
  • apps/web/app/(ee)/api/bounties/route.ts
  • apps/web/app/(ee)/api/cron/bounties/create-draft-submissions/route.ts
  • apps/web/app/(ee)/api/cron/bounties/notify-partners/route.ts
  • apps/web/app/(ee)/api/embed/referrals/bounties/[bountyId]/social-content-stats/route.ts
  • apps/web/app/(ee)/api/partner-profile/programs/[programId]/bounties/[bountyId]/route.ts
  • apps/web/app/(ee)/api/partner-profile/programs/[programId]/bounties/[bountyId]/social-content-stats/route.ts
  • apps/web/app/(ee)/api/partner-profile/programs/[programId]/bounties/route.ts
  • apps/web/app/(ee)/app.dub.co/embed/referrals/get-referrals-embed-data.ts
  • apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/add-edit-bounty-sheet.tsx
  • apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/bounty-eligibility.tsx
  • apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/confirm-create-bounty-modal.tsx
  • apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/use-add-edit-bounty-form.ts
  • apps/web/lib/actions/partners/tags/update-program-partner-tags.ts
  • apps/web/lib/actions/partners/upload-bounty-submission-file.ts
  • apps/web/lib/api/tags/throw-if-invalid-partner-tag-ids.ts
  • apps/web/lib/api/workflows/execute-complete-bounty-workflow.ts
  • apps/web/lib/api/workflows/execute-workflows.ts
  • apps/web/lib/bounty/api/bounty-eligibility.ts
  • apps/web/lib/bounty/api/create-bounty-submission.ts
  • apps/web/lib/bounty/api/get-bounties-by-groups.ts
  • apps/web/lib/bounty/api/get-bounties-for-partner.ts
  • apps/web/lib/bounty/api/get-bounty-submission-upload-url.ts
  • apps/web/lib/bounty/api/get-bounty-with-details.ts
  • apps/web/lib/bounty/api/trigger-draft-bounty-submissions.ts
  • apps/web/lib/embed/referrals/auth.ts
  • apps/web/lib/types.ts
  • apps/web/lib/webhook/sample-events/bounty-created.json
  • apps/web/lib/webhook/sample-events/bounty-updated.json
  • apps/web/lib/zod/schemas/bounties.ts
  • apps/web/lib/zod/schemas/partner-profile.ts
  • apps/web/prisma/schema/bounty.prisma
  • apps/web/prisma/schema/tag.prisma
  • apps/web/ui/partners/tags/partner-tags-multi-select.tsx
💤 Files with no reviewable changes (2)
  • apps/web/lib/bounty/api/get-bounties-by-groups.ts
  • apps/web/app/(ee)/api/bounties/[bountyId]/submissions/route.ts

Comment thread apps/web/app/(ee)/api/cron/bounties/notify-partners/route.ts Outdated
Comment thread apps/web/lib/bounty/api/bounty-eligibility.ts
Comment thread apps/web/lib/bounty/api/get-bounty-submission-upload-url.ts
Comment thread apps/web/ui/partners/tags/partner-tags-multi-select.tsx Outdated
Treat null eligibility selections as empty so PATCH clears existing
restrictions, and refresh the eligibility picker when selections change.
@devkiran

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review. Look for breaking changes and security issues.

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== bounty-eligibility.ts ==="
cat apps/web/lib/bounty/api/bounty-eligibility.ts

echo ""
echo "=== throw-if-invalid-partner-tag-ids.ts ==="
cat apps/web/lib/api/tags/throw-if-invalid-partner-tag-ids.ts

echo ""
echo "=== bounty.prisma ==="
cat apps/web/prisma/schema/bounty.prisma

echo ""
echo "=== get-bounties-for-partner.ts ==="
cat apps/web/lib/bounty/api/get-bounties-for-partner.ts

echo ""
echo "=== trigger-draft-bounty-submissions.ts ==="
cat apps/web/lib/bounty/api/trigger-draft-bounty-submissions.ts

Length of output: 12953


🏁 Script executed:

#!/bin/bash
echo "=== create-draft-submissions cron route ==="
cat apps/web/app/\(ee\)/api/cron/bounties/create-draft-submissions/route.ts

echo ""
echo "=== notify-partners cron route ==="
cat apps/web/app/\(ee\)/api/cron/bounties/notify-partners/route.ts

echo ""
echo "=== bounties route (main) ==="
cat apps/web/app/\(ee\)/api/bounties/route.ts

echo ""
echo "=== bountyId route ==="
cat apps/web/app/\(ee\)/api/bounties/\[bountyId\]/route.ts

echo ""
echo "=== execute-complete-bounty-workflow.ts ==="
cat apps/web/lib/api/workflows/execute-complete-bounty-workflow.ts

Length of output: 45592


🏁 Script executed:

#!/bin/bash
echo "=== create-bounty-submission.ts ==="
cat apps/web/lib/bounty/api/create-bounty-submission.ts

echo ""
echo "=== get-bounty-submission-upload-url.ts ==="
cat apps/web/lib/bounty/api/get-bounty-submission-upload-url.ts

echo ""
echo "=== partner-profile bounties route ==="
cat apps/web/app/\(ee\)/api/partner-profile/programs/\[programId\]/bounties/route.ts

echo ""
echo "=== partner-profile bountyId route ==="
cat apps/web/app/\(ee\)/api/partner-profile/programs/\[programId\]/bounties/\[bountyId\]/route.ts

echo ""
echo "=== bounty-eligibility.tsx ==="
cat apps/web/app/app.dub.co/\(dashboard\)/\[slug\]/\(ee\)/program/bounties/add-edit-bounty/bounty-eligibility.tsx

echo ""
echo "=== bounties schema ==="
cat apps/web/lib/zod/schemas/bounties.ts

echo ""
echo "=== partner-profile schema ==="
cat apps/web/lib/zod/schemas/partner-profile.ts

echo ""
echo "=== Check for Prisma migration files ==="
fd -e sql . apps/web/prisma/migrations --exec echo {} | sort | tail -5

echo ""
echo "=== Check for any callers of getBountiesByGroups ==="
rg "getBountiesByGroups" --type ts -n

echo ""
echo "=== Check for any callers of getBountiesForPartner ==="
rg "getBountiesForPartner" --type ts -n -A3

echo ""
echo "=== update-program-partner-tags.ts ==="
cat apps/web/lib/actions/partners/tags/update-program-partner-tags.ts

echo ""
echo "=== upload-bounty-submission-file.ts ==="
cat apps/web/lib/actions/partners/upload-bounty-submission-file.ts

echo ""
echo "=== sample bounty-created.json ==="
cat apps/web/lib/webhook/sample-events/bounty-created.json

echo ""
echo "=== embed referrals auth ==="
cat apps/web/lib/embed/referrals/auth.ts

Length of output: 64349



@devkiran Here is my focused review for breaking changes and security/correctness issues.


🔴 Security / Correctness

1. defaultGroupId fallback missing in cron routes (silent partner exclusion)

Both create-draft-submissions and notify-partners filter enrollments using:

...(groupIds.length > 0 && {
  groupId: {
    in: groupIds,  // ← misses partners with groupId = null
  },
}),

A partner whose enrollment has groupId = null inherits the program's defaultGroupId. If the bounty targets that default group, these partners are silently excluded from draft submissions and notification emails — even though isPartnerEligibleForBounty would grant them eligibility.

This is handled correctly in trigger-draft-bounty-submissions.ts (which uses enrollment.groupId ?? program.defaultGroupId), but the cron routes do not replicate that fallback.

Fix: Either resolve defaultGroupId in the query (by fetching the program and applying OR logic), or add a Prisma OR condition:

...(groupIds.length > 0 && {
  OR: [
    { groupId: { in: groupIds } },
    { groupId: null, program: { defaultGroupId: { in: groupIds } } },
  ],
}),

🟡 Breaking Changes

2. Missing Prisma migration for BountyPartnerTag

The schema adds a new BountyPartnerTag model and a partnerTags relation on Bounty, but no migration file was found. Deploying without running the migration will cause runtime errors on any code path that touches partnerTags.

Please confirm the migration exists or generate one (prisma migrate dev).

3. getBountiesForPartner signature change

The function's parameter type now requires programPartnerTags: Pick<ProgramPartnerTag, "partnerTagId">[]. All three known call sites (partner-profile/programs/[programId]/bounties/route.ts, the embed path, get-referrals-embed-data.ts) have been updated. No remaining callers found — this is clean.

4. PartnerBountySchema omits partnerTags

PartnerBountySchema now explicitly omits both groups and partnerTags from BountySchema. This is intentional (partners shouldn't see eligibility metadata) but is a schema-level breaking change for any external consumers of that schema type. Confirm this is deliberate.


🔵 Minor Issues

5. Dead variable in execute-complete-bounty-workflow.ts

const { groups, submissions } = bounty; // `groups` is never used below

After the refactor, groups is accessed via bounty.groups for bountyGroupIds but the old destructuring was left behind. Safe to remove.

6. TOCTOU on tag ID validation (low risk)

throwIfInvalidPartnerTagIds and throwIfInvalidGroupIds are called outside the Prisma transaction in both POST and PATCH /api/bounties. A tag deleted between validation and insertion would not be caught. This is an industry-standard trade-off but worth noting.


Summary table:

# Severity Area Description
1 🔴 Correctness Cron routes defaultGroupId fallback missing → silent partner exclusion
2 🟡 Breaking DB No migration for BountyPartnerTag
3 🟡 Breaking API getBountiesForPartner signature change (callers updated ✅)
4 🟡 Breaking Schema PartnerBountySchema drops partnerTags (intentional?)
5 🔵 Minor Workflow Dead groups variable
6 🔵 Minor API TOCTOU on tag validation
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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.

1 participant