FEAT: Dynamic bounty start date#4187
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR adds absolute and enrollment-relative bounty timing, centralizes partner eligibility and effective-period calculations, and updates bounty APIs, cron workflows, submission flows, dashboard/embed interfaces, Slack output, webhooks, and tests. ChangesBounty timing and eligibility
Estimated code review effort: 5 (Critical) | ~90 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 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.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/add-edit-bounty-sheet.tsx (1)
283-303: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winSubmission window ignores
endsAfterDaysend dates. The gating and validation here only look atendsAt, so bounties that end viaendsAfterDaysstay disabled and hit the “An end date is required…” path even though they have an effective end date. If those bounties should support submission windows, use the resolved end date here instead.🤖 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/app/app.dub.co/`(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/add-edit-bounty-sheet.tsx around lines 283 - 303, Update the submission-window gating and validation around the Switch and its tooltip to use the resolved effective end date, including bounties configured with endsAfterDays, instead of checking endsAt directly. Preserve the existing allowedSubmissions > 1 restriction and ensure valid resolved end dates do not trigger the “end date required” state.
🤖 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/bounties/route.ts:
- Around line 114-141: The partner-scoped branch in the bounty mapping flow must
use the shared visibility rules instead of only checking startsAt and endsAt.
Update the logic around getEffectiveBountyPeriod and isPartnerEligibleForBounty
to exclude archived bounties and enforce the relative-bounty partnerJoinedAt
versus bounty.createdAt rule, while preserving the existing time-window
filtering and output mapping.
In
`@apps/web/app/app.dub.co/`(dashboard)/[slug]/(ee)/program/bounties/bounty-card.tsx:
- Around line 73-106: Replace every font-regular utility with font-normal in the
bounty card rows around BountyRewardDescription, dateRangeLabel,
partnerAudienceLabel, and eligible group rendering. Apply the same change to the
partner-audience row in confirm-create-bounty-modal.tsx; update both affected
files at the specified sites.
In `@apps/web/lib/types.ts`:
- Around line 868-876: Keep programEnrollment optional in WorkflowContext so
executeWorkflows callers providing only trigger and identity remain valid.
Update the WorkflowContext declaration around programEnrollment without making
the resolved enrollment data required at the caller boundary.
---
Outside diff comments:
In
`@apps/web/app/app.dub.co/`(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/add-edit-bounty-sheet.tsx:
- Around line 283-303: Update the submission-window gating and validation around
the Switch and its tooltip to use the resolved effective end date, including
bounties configured with endsAfterDays, instead of checking endsAt directly.
Preserve the existing allowedSubmissions > 1 restriction and ensure valid
resolved end dates do not trigger the “end date required” state.
🪄 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: ba58c53e-7f82-467a-bbea-437d7f136abe
📒 Files selected for processing (56)
apps/web/app/(ee)/api/bounties/[bountyId]/route.tsapps/web/app/(ee)/api/bounties/[bountyId]/submissions/route.tsapps/web/app/(ee)/api/bounties/[bountyId]/sync-social-metrics/route.tsapps/web/app/(ee)/api/bounties/route.tsapps/web/app/(ee)/api/cron/bounties/create-draft-submissions/route.tsapps/web/app/(ee)/api/cron/bounties/notify-partners/route.tsapps/web/app/(ee)/api/cron/bounties/queue-sync-social-metrics/route.tsapps/web/app/(ee)/api/cron/bounties/sync-social-metrics/route.tsapps/web/app/(ee)/api/embed/referrals/bounties/[bountyId]/social-content-stats/route.tsapps/web/app/(ee)/api/embed/referrals/bounties/[bountyId]/submissions/route.tsapps/web/app/(ee)/api/partner-profile/programs/[programId]/bounties/[bountyId]/route.tsapps/web/app/(ee)/api/partner-profile/programs/[programId]/bounties/[bountyId]/social-content-stats/route.tsapps/web/app/(ee)/api/partner-profile/programs/[programId]/bounties/route.tsapps/web/app/(ee)/app.dub.co/embed/referrals/bounties/submission-fields.tsxapps/web/app/(ee)/app.dub.co/embed/referrals/bounties/submission-form.tsxapps/web/app/(ee)/app.dub.co/embed/referrals/get-referrals-embed-data.tsapps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/[bountyId]/bounty-info.tsxapps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/add-edit-bounty-sheet.tsxapps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/bounty-criteria.tsxapps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/bounty-duration.tsxapps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/confirm-create-bounty-modal.tsxapps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/add-edit-bounty/use-add-edit-bounty-form.tsapps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/bounty-card.tsxapps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/groups/[groupSlug]/settings/group-move-rules.tsxapps/web/lib/actions/partners/accept-program-invite.tsapps/web/lib/actions/partners/bulk-approve-partners.tsapps/web/lib/api/groups/move-partners-to-group.tsapps/web/lib/api/partners/applications/approve-partner.tsapps/web/lib/api/partners/create-and-enroll-partner.tsapps/web/lib/api/workflows/execute-complete-bounty-workflow.tsapps/web/lib/api/workflows/execute-workflows.tsapps/web/lib/bounty/api/bounty-availability.tsapps/web/lib/bounty/api/create-bounty-submission.tsapps/web/lib/bounty/api/get-bounties-for-partner.tsapps/web/lib/bounty/api/get-bounty-submission-upload-url.tsapps/web/lib/bounty/api/get-bounty-with-details.tsapps/web/lib/bounty/api/get-group-bounty-summaries.tsapps/web/lib/bounty/api/trigger-draft-bounty-submissions.tsapps/web/lib/bounty/api/validate-bounty.tsapps/web/lib/bounty/bounty-period.tsapps/web/lib/firstpromoter/import-partners.tsapps/web/lib/integrations/slack/transform.tsapps/web/lib/partnerstack/import-partners.tsapps/web/lib/rewardful/import-partners.tsapps/web/lib/tapfiliate/import-partners.tsapps/web/lib/tolt/import-partners.tsapps/web/lib/types.tsapps/web/lib/webhook/sample-events/bounty-created.jsonapps/web/lib/webhook/sample-events/bounty-updated.jsonapps/web/lib/zod/schemas/bounties.tsapps/web/lib/zod/schemas/partner-profile.tsapps/web/prisma/schema/bounty.prismaapps/web/prisma/schema/program.prismaapps/web/scripts/migrations/backfill-group-joined-at.tsapps/web/tests/bounties/index.test.tsapps/web/tests/webhooks/index.test.ts
💤 Files with no reviewable changes (1)
- apps/web/app/(ee)/api/bounties/[bountyId]/submissions/route.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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/tests/bounties/index.test.ts`:
- Around line 624-638: Move the onTestFinished cleanup registration to
immediately after the successful bounty creation POST, before the PATCH request
and assertions; keep it targeting the created bounty’s id so cleanup runs even
when later test steps fail.
🪄 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: 9483f6a8-0918-4c4d-8b93-f3d489d98c3b
📒 Files selected for processing (1)
apps/web/tests/bounties/index.test.ts
| const { status: patchStatus, data: updated } = await http.patch<Bounty>({ | ||
| path: `/bounties/${bounty.id}`, | ||
| body: { endsAfterDays: 180 }, | ||
| }); | ||
|
|
||
| expect(patchStatus).toEqual(200); | ||
| expect(updated).toMatchObject({ | ||
| startMode: BountyStartMode.relative, | ||
| startsAt: null, | ||
| endsAfterDays: 180, | ||
| }); | ||
|
|
||
| onTestFinished(async () => { | ||
| await h.deleteBounty(bounty.id); | ||
| }); |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
Register cleanup immediately after creation.
If the PATCH call or either assertion fails, onTestFinished is never registered and the created bounty remains in the E2E environment. Register it directly after the successful POST.
Proposed fix
expect(bounty).toMatchObject({
startMode: BountyStartMode.relative,
startsAt: null,
endsAt: null,
endsAfterDays: 30,
});
+ onTestFinished(async () => {
+ await h.deleteBounty(bounty.id);
+ });
+
const { status: patchStatus, data: updated } = await http.patch<Bounty>({
path: `/bounties/${bounty.id}`,
body: { endsAfterDays: 180 },
});
-
- onTestFinished(async () => {
- await h.deleteBounty(bounty.id);
- });📝 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.
| const { status: patchStatus, data: updated } = await http.patch<Bounty>({ | |
| path: `/bounties/${bounty.id}`, | |
| body: { endsAfterDays: 180 }, | |
| }); | |
| expect(patchStatus).toEqual(200); | |
| expect(updated).toMatchObject({ | |
| startMode: BountyStartMode.relative, | |
| startsAt: null, | |
| endsAfterDays: 180, | |
| }); | |
| onTestFinished(async () => { | |
| await h.deleteBounty(bounty.id); | |
| }); | |
| const { status: patchStatus, data: updated } = await http.patch<Bounty>({ | |
| path: `/bounties/${bounty.id}`, | |
| body: { endsAfterDays: 180 }, | |
| }); | |
| expect(patchStatus).toEqual(200); | |
| expect(updated).toMatchObject({ | |
| startMode: BountyStartMode.relative, | |
| startsAt: null, | |
| endsAfterDays: 180, | |
| }); | |
| onTestFinished(async () => { | |
| await h.deleteBounty(bounty.id); | |
| }); |
🤖 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/tests/bounties/index.test.ts` around lines 624 - 638, Move the
onTestFinished cleanup registration to immediately after the successful bounty
creation POST, before the PATCH request and assertions; keep it targeting the
created bounty’s id so cleanup runs even when later test steps fail.
Summary by CodeRabbit