Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@steven-tey
Copy link
Collaborator

@steven-tey steven-tey commented Dec 12, 2025

Summary by CodeRabbit

  • New Features
    • Automated background cleanup that removes applications rejected over 30 days old.
  • UI
    • Clarified messaging on program pages: rejected applicants are told they can re-apply after 30 days; reach-out link shown appropriately for banned status.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link
Contributor

vercel bot commented Dec 12, 2025

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

Project Deployment Review Updated (UTC)
dub Ready Ready Preview Dec 12, 2025 8:46pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 12, 2025

Walkthrough

Adds a POST cron route that verifies Qstash signatures and deletes "rejected" program enrollments older than 30 days; updates UI to tell rejected applicants they can re-apply in 30 days and simplifies when the support "Reach out" link is shown.

Changes

Cohort / File(s) Summary
Cleanup Cron Endpoint
apps/web/app/(ee)/api/cron/cleanup/rejected-applications/route.ts
New POST handler exporting dynamic = "force-dynamic". Verifies Qstash signature using raw request body, deletes programEnrollment records with status: "rejected" older than 30 days via Prisma, logs deletion count, and returns { status: "OK" } or an error via handleAndReturnErrorResponse.
Unapproved Program UI
apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/unapproved-program-page.tsx
Adjusted rejected status description to include "You can re-apply in 30 days." and changed conditional so the "Reach out" link is shown only for status === "banned".
Program Card UI
apps/web/ui/partners/program-card.tsx
Added explicit rejected handling to show status description plus "You can re-apply in 30 days." Simplified rendering so statusDescription (when present) always shows the description and the "Reach out" link together.

Sequence Diagram(s)

sequenceDiagram
  participant Qstash
  participant NextAPI as Next.js Route
  participant Verifier as verifyQstashSignature
  participant PrismaDB as Prisma
  participant Logger
  Qstash->>NextAPI: POST (signed payload)
  NextAPI->>Verifier: verify(raw body, headers)
  alt signature valid
    NextAPI->>PrismaDB: deleteMany where status="rejected" AND createdAt < now()-30d
    PrismaDB-->>NextAPI: { count: N }
    NextAPI->>Logger: log deletion count N
    NextAPI-->>Qstash: 200 { status: "OK" }
  else signature invalid or error
    NextAPI->>Logger: log error
    NextAPI-->>Qstash: error response (handled via handleAndReturnErrorResponse)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Verify raw body retrieval and Qstash signature verification correctness.
  • Check Prisma date comparison for 30-day cutoff and timezone handling.
  • Review error handling pathway and logging.
  • Confirm UI conditional changes are consistent across components and i18n/text contents.

Possibly related PRs

Suggested reviewers

  • devkiran

Poem

🐰 I twitch my nose and tidy tracks,

old rejects find gentle shacks,
thirty suns, then try once more,
we sweep the past, clear out the drawer,
hop back soon — the door's not barred 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding support for re-applying to programs after a 30-day waiting period, which is reflected across all modified files.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch program-reapply

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3e36194 and 3db320c.

📒 Files selected for processing (1)
  • apps/web/app/(ee)/api/cron/cleanup/rejected-applications/route.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/app/(ee)/api/cron/cleanup/rejected-applications/route.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

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 and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/unapproved-program-page.tsx (1)

35-39: Rejected copy is clear; consider making “30 days” source-of-truth driven (e.g., constant/shared helper) to avoid divergence across surfaces.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8c318d2 and 3e36194.

📒 Files selected for processing (3)
  • apps/web/app/(ee)/api/cron/cleanup/rejected-applications/route.ts (1 hunks)
  • apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/unapproved-program-page.tsx (2 hunks)
  • apps/web/ui/partners/program-card.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-12-09T12:54:41.818Z
Learnt from: devkiran
Repo: dubinc/dub PR: 3207
File: apps/web/lib/cron/with-cron.ts:27-56
Timestamp: 2025-12-09T12:54:41.818Z
Learning: In `apps/web/lib/cron/with-cron.ts`, the `withCron` wrapper extracts the request body once and provides it to handlers via the `rawBody` parameter. Handlers should use this `rawBody` string parameter (e.g., `JSON.parse(rawBody)`) rather than reading from the Request object via `req.json()` or `req.text()`.

Applied to files:

  • apps/web/app/(ee)/api/cron/cleanup/rejected-applications/route.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/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/unapproved-program-page.tsx
📚 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/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/unapproved-program-page.tsx
📚 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/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/unapproved-program-page.tsx
  • apps/web/ui/partners/program-card.tsx
📚 Learning: 2025-05-29T04:45:18.504Z
Learnt from: devkiran
Repo: dubinc/dub PR: 2448
File: packages/email/src/templates/partner-program-summary.tsx:0-0
Timestamp: 2025-05-29T04:45:18.504Z
Learning: In the PartnerProgramSummary email template (packages/email/src/templates/partner-program-summary.tsx), the stat titles are hardcoded constants ("Clicks", "Leads", "Sales", "Earnings") that will always match the ICONS object keys after toLowerCase() conversion, so icon lookup failures are not possible.

Applied to files:

  • apps/web/ui/partners/program-card.tsx
🧬 Code graph analysis (1)
apps/web/app/(ee)/api/cron/cleanup/rejected-applications/route.ts (2)
packages/prisma/index.ts (1)
  • prisma (3-9)
apps/web/lib/api/errors.ts (1)
  • handleAndReturnErrorResponse (162-165)
⏰ 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 (3)
apps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/unapproved-program-page.tsx (1)

89-100: Confirm intended removal of “Reach out…” for rejected status (now banned-only). If rejected users should still be able to appeal/ask questions, this change blocks that path on this page.

apps/web/ui/partners/program-card.tsx (1)

60-75: Rejected branch no longer includes “Reach out…”—verify this is intentional; currently only banned/deactivated show the link, while rejected shows only the 30-day guidance.

apps/web/app/(ee)/api/cron/cleanup/rejected-applications/route.ts (1)

12-20: No changes needed. The handler correctly reads the request body once and passes the raw body to verifyQstashSignature for signature verification. This follows the established pattern used by the vast majority of cron handlers in the codebase. The withCron wrapper is an alternative pattern available for new handlers, but is not required for existing implementations like this one.

Likely an incorrect or invalid review comment.

@steven-tey steven-tey merged commit 10535b6 into main Dec 12, 2025
7 of 8 checks passed
@steven-tey steven-tey deleted the program-reapply branch December 12, 2025 20:54
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