Add isSoftDelete prop to deleteDiscountCodes - #4112
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThe PR adds disabled-at support for discount codes across cleanup, attribution, and display, and changes duplicate-code creation to reference the existing partner and show a custom toast for the new error response. ChangesDiscount code disable state
Duplicate discount-code feedback
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 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.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/web/lib/discounts/delete-discount-code.ts (1)
48-50: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winStale comment for the soft-delete branch.
This comment states orphaned codes "still get deleted locally above," but that's only true when
isSoftDeleteisfalse. WhenisSoftDeleteistrue, the block at Lines 33-46 is skipped entirely, so orphaned codes are not deleted locally in that path either. Worth updating the comment to reflect the conditional behavior.🤖 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/discounts/delete-discount-code.ts` around lines 48 - 50, Update the stale orphaned-code comment in deleteDiscountCode to match the conditional flow controlled by isSoftDelete. The current wording in the delete-discount-code cleanup branch implies orphaned codes are always deleted locally above, but that only happens in the non-soft-delete path. Revise the comment near the provider cleanup logic so it clearly states that orphaned codes are skipped for external-provider cleanup, and local deletion may have already occurred only when the isSoftDelete branch was not taken.
🤖 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.
Outside diff comments:
In `@apps/web/lib/discounts/delete-discount-code.ts`:
- Around line 48-50: Update the stale orphaned-code comment in
deleteDiscountCode to match the conditional flow controlled by isSoftDelete. The
current wording in the delete-discount-code cleanup branch implies orphaned
codes are always deleted locally above, but that only happens in the
non-soft-delete path. Revise the comment near the provider cleanup logic so it
clearly states that orphaned codes are skipped for external-provider cleanup,
and local deletion may have already occurred only when the isSoftDelete branch
was not taken.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: e95cfb7b-dd8a-43de-be9e-fac5dae3a783
📒 Files selected for processing (4)
apps/web/app/(ee)/api/cron/discount-codes/disable/route.tsapps/web/app/(ee)/api/cron/partners/ban/route.tsapps/web/app/(ee)/api/cron/partners/deactivate/route.tsapps/web/lib/discounts/delete-discount-code.ts
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
apps/web/ui/modals/add-discount-code-modal.tsx (1)
91-114: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoffFragile substring match on error copy for the "already in use" branch.
Branching on
error.includes("already in use")couples the modal to the exact backend message text. The backend already returns a structuredcode: "conflict"(perapps/web/app/(ee)/api/discount-codes/route.ts); if the wording changes later, this branch silently falls through totoast.error(error)without any error surfaced during development.Consider threading the structured error code through
useApiMutation/onError(if available) rather than matching on message substrings, similar to howERROR_MAPkeys are prefix-matched.🤖 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/ui/modals/add-discount-code-modal.tsx` around lines 91 - 114, The “already in use” toast branch in add-discount-code-modal is relying on a brittle error substring instead of the structured backend code. Update the onError handling in add-discount-code-modal and the useApiMutation error flow so this case is driven by the returned code (for example the existing conflict code used by ERROR_MAP) rather than error.includes("already in use"). Keep the same CustomToast behavior, but route it through the structured error object so changes in backend wording do not break the modal.
🤖 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/discount-codes/route.ts:
- Around line 108-113: The conflict message in the discount code route hardcodes
the production app URL, which breaks self-hosted or custom-domain deployments.
Update the `duplicateByCode` error in `route.ts` to build the partner link using
the shared app-domain constant from `@dub/utils` (for example the same pattern
used in `options.ts`) instead of `https://app.dub.co`, so the generated URL
respects `NEXT_PUBLIC_APP_DOMAIN`.
In `@apps/web/ui/modals/add-discount-code-modal.tsx`:
- Around line 21-22: The duplicate discount-code handling in
add-discount-code-modal should use the structured conflict code instead of
checking error text. Update the logic in AddDiscountCodeModal’s submit/error
path to branch on the API error code for the “already exists” case, and reserve
the text-based fallback only for unexpected errors so the duplicate-code toast
is shown reliably.
---
Nitpick comments:
In `@apps/web/ui/modals/add-discount-code-modal.tsx`:
- Around line 91-114: The “already in use” toast branch in
add-discount-code-modal is relying on a brittle error substring instead of the
structured backend code. Update the onError handling in add-discount-code-modal
and the useApiMutation error flow so this case is driven by the returned code
(for example the existing conflict code used by ERROR_MAP) rather than
error.includes("already in use"). Keep the same CustomToast behavior, but route
it through the structured error object so changes in backend wording do not
break the modal.
🪄 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: 2d5797c2-6d27-4766-946d-cb9f56c77ea1
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (4)
apps/web/app/(ee)/api/discount-codes/route.tsapps/web/package.jsonapps/web/ui/modals/add-discount-code-modal.tsxapps/web/ui/shared/custom-toast.tsx
|
@coderabbitai final review, any breaking changes? |
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
apps/web/ui/partners/discounts/discount-code-badge.tsx (1)
51-62: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winTooltip copy references a scenario (deactivation) that doesn't currently produce this state.
Per the cross-file wiring,
disabledAtis only ever set by the ban flow (isSoftDelete: true); the deactivate flow hard-deletes the row instead. This tooltip's "banned or deactivated" phrasing is therefore inaccurate today. See the related comment onapps/web/lib/zod/schemas/discount.tsfor the root-cause discussion.🤖 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/ui/partners/discounts/discount-code-badge.tsx` around lines 51 - 62, The Disabled tooltip copy in discount-code-badge should match the actual state transition wired through disabledAt and the ban flow, since the deactivate path hard-deletes instead of setting this flag. Update the Tooltip content in the discount-code-badge component to remove the “deactivated” reference and keep the message aligned with the existing disabled state behavior; use the StatusBadge/Tooltip block in discount-code-badge.tsx as the target.
🤖 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/lib/zod/schemas/discount.ts`:
- Around line 65-70: The `disabledAt` schema description in `discount.ts` is
inaccurate because it implies the timestamp is set for both banning and
deactivation, but only banning actually soft-deletes and sets `disabledAt`;
deactivation hard-deletes the row. Update the
`z.coerce.date().nullish().describe(...)` text to reflect only the cases where
`disabledAt` is populated, and make the same wording change in the
`discount-code-badge.tsx` tooltip copy so both descriptions stay consistent.
---
Duplicate comments:
In `@apps/web/ui/partners/discounts/discount-code-badge.tsx`:
- Around line 51-62: The Disabled tooltip copy in discount-code-badge should
match the actual state transition wired through disabledAt and the ban flow,
since the deactivate path hard-deletes instead of setting this flag. Update the
Tooltip content in the discount-code-badge component to remove the “deactivated”
reference and keep the message aligned with the existing disabled state
behavior; use the StatusBadge/Tooltip block in discount-code-badge.tsx as the
target.
🪄 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: 8f7fcdc7-8752-45cb-a087-241da24752e4
📒 Files selected for processing (6)
apps/web/app/(ee)/api/stripe/integration/webhook/utils/attribute-via-promotion-code-id.tsapps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/partners/[partnerId]/links/page.tsxapps/web/lib/discounts/delete-discount-code.tsapps/web/lib/zod/schemas/discount.tsapps/web/prisma/schema/discount.prismaapps/web/ui/partners/discounts/discount-code-badge.tsx
🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
fd delete-discount-code.ts
echo "---"
cat -n apps/web/lib/discounts/delete-discount-code.ts
echo "---ban route---"
cat -n "apps/web/app/(ee)/api/cron/partners/ban/route.ts" | sed -n '1,200p'
echo "---deactivate route---"
cat -n "apps/web/app/(ee)/api/cron/partners/deactivate/route.ts" | sed -n '1,200p'
echo "---disable route---"
cat -n "apps/web/app/(ee)/api/cron/discount-codes/disable/route.ts"
echo "---rg other usages---"
rg -n 'deleteDiscountCodes' --type=ts -C2Length of output: 16484 🏁 Script executed: #!/bin/bash
rg -n 'deleteDiscountCodes\(' --type=ts -C2 || true
echo "---enqueueBatchJobs / job endpoint usage for delete route---"
fd -a 'route.ts' apps/web/app/\(ee\)/api/cron/discount-codes
echo "---check old delete route still exists---"
fd -a . apps/web/app/\(ee\)/api/cron/discount-codesLength of output: 432 🏁 Script executed: #!/bin/bash
rg -n "deleteDiscountCodes(" -F -C3 apps/web || true
echo "---find dir---"
find apps/web/app -iname "*discount-codes*" -type d
echo "---list cron discount-codes dir---"
ls -la "apps/web/app/(ee)/api/cron/discount-codes" 2>/dev/nullLength of output: 5424 🏁 Script executed: #!/bin/bash
git log --oneline -1
git diff --stat origin/main... -- apps/web/app/\(ee\)/api/cron/discount-codes 2>/dev/null || true
echo "---search old endpoint path references---"
rg -n "cron/discount-codes/delete" apps/web || true
echo "---check discount-codes create route for context---"
cat -n "apps/web/app/(ee)/api/cron/discount-codes/create/route.ts" 2>/dev/null | head -50Length of output: 2430 🏁 Script executed: #!/bin/bash
rg -n "disabledAt" apps/web/prisma 2>/dev/null || rg -n "disabledAt" packages/prisma 2>/dev/null || fd schema.prismaLength of output: 700 🤖 web_search executed:
Length of output: 9856 Now I have enough context to answer.
Cron route rename
Overall: no breaking changes for consumers of ✅ Action performedReview finished.
|
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/app/`(ee)/api/cron/partners/deactivate/route.ts:
- Line 61: The deactivate flow currently calls deleteDiscountCodes with
isSoftDelete set to true, which matches the ban path instead of the intended
hard-delete behavior. Update the discount-code cleanup in deactivate/route.ts so
the deleteDiscountCodes call uses the hard-delete option expected for partner
deactivation, and verify the ban route remains the soft-delete path for the
contrasting behavior.
🪄 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: cf33893a-1ddc-42d2-bab7-62068d889383
📒 Files selected for processing (6)
apps/web/app/(ee)/api/cron/partners/deactivate/route.tsapps/web/app/(ee)/api/discount-codes/route.tsapps/web/app/(ee)/api/partner-profile/programs/[programId]/links/route.tsapps/web/app/(ee)/partners.dub.co/(dashboard)/programs/[programSlug]/(enrolled)/links/partner-link-card.tsxapps/web/lib/zod/schemas/partner-profile.tsapps/web/ui/partners/discounts/discount-code-badge.tsx
✅ Files skipped from review due to trivial changes (1)
- apps/web/app/(ee)/api/partner-profile/programs/[programId]/links/route.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- apps/web/app/(ee)/api/discount-codes/route.ts
Summary by CodeRabbit
disabledAtsupport across the discount code lifecycle, schemas, and API responses, so disabled codes display and behave correctly.sonnerdependency version.