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

Skip to content

Conversation

@marcusljf
Copy link
Collaborator

@marcusljf marcusljf commented Oct 31, 2025

On the backend there was an 1000 character limit but we weren't enforcing it on the form and/or displaying it to the partners when they are submitting. This would create submission loops with no error message.

Current
CleanShot 2025-10-31 at 13 46 43@2x

Updated
CleanShot 2025-10-31 at 13 39 39@2x

Summary by CodeRabbit

  • New Features
    • Added a 1000-character limit to bounty submission descriptions with a live character counter displaying remaining characters.
    • Enhanced validation to prevent exceeding the description character limit.

On the backend there was an 1000 character limit but we weren't enforcing it on the form and/or displaying it to the partners when they are submitting. This would create submission loops with no error message.

This has been added now
@vercel
Copy link
Contributor

vercel bot commented Oct 31, 2025

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

Project Deployment Preview Updated (UTC)
dub Ready Ready Preview Oct 31, 2025 8:52pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 31, 2025

Walkthrough

A new constant MAX_BOUNTY_SUBMISSION_DESCRIPTION_LENGTH (value: 1000) is extracted into the bounties schema file, then imported and applied across server-side validation and client-side UI components to enforce consistent description length limits with live character feedback.

Changes

Cohort / File(s) Summary
Schema constant definition
apps/web/lib/zod/schemas/bounties.ts
Added MAX_BOUNTY_SUBMISSION_DESCRIPTION_LENGTH constant with value 1000 to centralize bounty submission description length constraint.
Server action validation
apps/web/lib/actions/partners/create-bounty-submission.ts
Imported MAX_BOUNTY_SUBMISSION_DESCRIPTION_LENGTH and replaced hard-coded max(1000) with max(MAX_BOUNTY_SUBMISSION_DESCRIPTION_LENGTH) in the bounty submission schema.
Client-side UI enforcement
apps/web/ui/partners/bounties/claim-bounty-modal.tsx
Imported MAX_BOUNTY_SUBMISSION_DESCRIPTION_LENGTH and applied it to textarea maxLength attribute, updated onChange handler to prevent exceeding the limit, and added a live character counter display.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~5 minutes

  • Simple constant extraction and consistent application across three files
  • No complex logic changes or structural modifications
  • Straightforward repetitive pattern (extract magic number β†’ import β†’ apply)

Possibly related PRs

  • Bounties updatesΒ #2786: Modifies bounty-related schema definitions in the same schemas file, potential overlap with bounties schema structure.

Suggested reviewers

  • steven-tey

Poem

🐰 A number once scattered, now gathered as one,
Constants corralled where the validation is done,
From schema to UI, the limit's now clear,
Bounty submissions bounded with counter cheer! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 "Bounty submission character limit" accurately and directly describes the primary change across all modified files. The PR introduces a 1000-character limit enforcement at the frontend level by extracting a constant, applying it to the textarea input, preventing submission of oversized text, and displaying a character counter to users. The title is specific and clear about what feature is being added, avoiding vague terminology while remaining concise and scannable for someone reviewing the commit history. It correctly reflects the main objective of enforcing the backend's limit at the frontend and improving user experience with visual feedback.
✨ 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 bounty-character-limit

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: 0

🧹 Nitpick comments (2)
apps/web/ui/partners/bounties/claim-bounty-modal.tsx (2)

588-593: Consider simplifying the onChange handler.

Since the maxLength attribute (line 586) already prevents the textarea from accepting input beyond the limit, the length check in the onChange handler is redundant. The browser will automatically enforce maxLength for both typing and paste operations.

You can simplify this to:

-                        onChange={(e) => {
-                          const value = e.target.value;
-                          if (value.length <= MAX_BOUNTY_SUBMISSION_DESCRIPTION_LENGTH) {
-                            setDescription(value);
-                          }
-                        }}
+                        onChange={(e) => setDescription(e.target.value)}

However, keeping the explicit check provides defense-in-depth and doesn't cause any issues, so this is entirely optional.


595-601: Character counter provides helpful feedback.

The live character counter successfully addresses the PR objective by showing partners the limit during submission. The implementation works correctly.

For improved clarity, consider one of these formats:

Option 1: Show current / max instead of remaining / max

                       <div className="mt-1 text-left">
                         <span className="text-xs text-neutral-500">
-                          {MAX_BOUNTY_SUBMISSION_DESCRIPTION_LENGTH -
-                            description.length}{" "}
-                          / {MAX_BOUNTY_SUBMISSION_DESCRIPTION_LENGTH}
+                          {description.length} / {MAX_BOUNTY_SUBMISSION_DESCRIPTION_LENGTH} characters
                         </span>
                       </div>

Option 2: Add "remaining" label to current format

                       <div className="mt-1 text-left">
                         <span className="text-xs text-neutral-500">
                           {MAX_BOUNTY_SUBMISSION_DESCRIPTION_LENGTH -
-                            description.length}{" "}
-                          / {MAX_BOUNTY_SUBMISSION_DESCRIPTION_LENGTH}
+                            description.length} characters remaining
                         </span>
                       </div>
πŸ“œ Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 3b1a260 and 11f4c55.

πŸ“’ Files selected for processing (3)
  • apps/web/lib/actions/partners/create-bounty-submission.ts (2 hunks)
  • apps/web/lib/zod/schemas/bounties.ts (1 hunks)
  • apps/web/ui/partners/bounties/claim-bounty-modal.tsx (2 hunks)
🧰 Additional context used
🧠 Learnings (5)
πŸ““ Common learnings
Learnt from: devkiran
Repo: dubinc/dub PR: 2736
File: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/[bountyId]/bounty-info.tsx:45-56
Timestamp: 2025-08-25T17:39:38.965Z
Learning: In the bounty system, each partner can only submit to the same bounty once. This means totalSubmissions (pending + approved + rejected) equals the number of unique partners who have submitted, making UI text like "X of Y partners completed" accurate when using totalSubmissions.
Learnt from: devkiran
Repo: dubinc/dub PR: 2833
File: apps/web/lib/actions/partners/approve-bounty-submission.ts:53-61
Timestamp: 2025-09-12T17:31:10.548Z
Learning: In approve-bounty-submission.ts, the logic `bounty.rewardAmount ?? rewardAmount` is intentional. Bounties with preset reward amounts should use those fixed amounts, and the rewardAmount override parameter is only used when bounty.rewardAmount is null/undefined (for custom reward bounties). This follows the design pattern where bounties are either "flat rate" (fixed amount) or "custom" (variable amount set during approval).
πŸ“š Learning: 2025-09-12T17:31:10.548Z
Learnt from: devkiran
Repo: dubinc/dub PR: 2833
File: apps/web/lib/actions/partners/approve-bounty-submission.ts:53-61
Timestamp: 2025-09-12T17:31:10.548Z
Learning: In approve-bounty-submission.ts, the logic `bounty.rewardAmount ?? rewardAmount` is intentional. Bounties with preset reward amounts should use those fixed amounts, and the rewardAmount override parameter is only used when bounty.rewardAmount is null/undefined (for custom reward bounties). This follows the design pattern where bounties are either "flat rate" (fixed amount) or "custom" (variable amount set during approval).

Applied to files:

  • apps/web/lib/zod/schemas/bounties.ts
  • apps/web/lib/actions/partners/create-bounty-submission.ts
  • apps/web/ui/partners/bounties/claim-bounty-modal.tsx
πŸ“š Learning: 2025-08-26T14:32:33.851Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2736
File: apps/web/lib/actions/partners/create-bounty-submission.ts:105-112
Timestamp: 2025-08-26T14:32:33.851Z
Learning: Non-performance bounties are required to have submissionRequirements. In create-bounty-submission.ts, it's appropriate to let the parsing fail if submissionRequirements is null for non-performance bounties, as this indicates a data integrity issue that should be caught.

Applied to files:

  • apps/web/lib/zod/schemas/bounties.ts
  • apps/web/lib/actions/partners/create-bounty-submission.ts
  • apps/web/ui/partners/bounties/claim-bounty-modal.tsx
πŸ“š Learning: 2025-08-25T17:39:38.965Z
Learnt from: devkiran
Repo: dubinc/dub PR: 2736
File: apps/web/app/app.dub.co/(dashboard)/[slug]/(ee)/program/bounties/[bountyId]/bounty-info.tsx:45-56
Timestamp: 2025-08-25T17:39:38.965Z
Learning: In the bounty system, each partner can only submit to the same bounty once. This means totalSubmissions (pending + approved + rejected) equals the number of unique partners who have submitted, making UI text like "X of Y partners completed" accurate when using totalSubmissions.

Applied to files:

  • apps/web/lib/zod/schemas/bounties.ts
  • apps/web/ui/partners/bounties/claim-bounty-modal.tsx
πŸ“š Learning: 2025-08-26T14:20:23.943Z
Learnt from: TWilson023
Repo: dubinc/dub PR: 2736
File: apps/web/app/api/workspaces/[idOrSlug]/notification-preferences/route.ts:13-14
Timestamp: 2025-08-26T14:20:23.943Z
Learning: The updateNotificationPreference action in apps/web/lib/actions/update-notification-preference.ts already handles all notification preference types dynamically, including newBountySubmitted, through its schema validation using the notificationTypes enum and Prisma's dynamic field update pattern.

Applied to files:

  • apps/web/lib/actions/partners/create-bounty-submission.ts
🧬 Code graph analysis (2)
apps/web/lib/actions/partners/create-bounty-submission.ts (1)
apps/web/lib/zod/schemas/bounties.ts (1)
  • MAX_BOUNTY_SUBMISSION_DESCRIPTION_LENGTH (23-23)
apps/web/ui/partners/bounties/claim-bounty-modal.tsx (1)
apps/web/lib/zod/schemas/bounties.ts (1)
  • MAX_BOUNTY_SUBMISSION_DESCRIPTION_LENGTH (23-23)
⏰ 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/lib/zod/schemas/bounties.ts (1)

23-23: LGTM! Constant extraction improves maintainability.

The new constant is well-placed alongside similar constants and provides a single source of truth for the description character limit across the codebase.

apps/web/lib/actions/partners/create-bounty-submission.ts (1)

8-8: LGTM! Backend validation now uses the centralized constant.

The schema correctly imports and applies the constant, ensuring consistent validation with the frontend. This prevents the submission loop issue described in the PR objectives.

Also applies to: 31-35

apps/web/ui/partners/bounties/claim-bounty-modal.tsx (1)

586-586: LGTM! Character limit enforcement added to textarea.

The maxLength attribute correctly applies the constant, providing immediate feedback by preventing users from exceeding the limit during input.

@steven-tey steven-tey merged commit 0446f41 into main Oct 31, 2025
9 checks passed
@steven-tey steven-tey deleted the bounty-character-limit branch October 31, 2025 22:42
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.

3 participants