fix: allow decimal values in quotes and compensation fields
updates the submission drawer and listing builder to accept decimal numbers up to 4 decimal places for quotes and compensation fields. changes the database schema from int to float for ask, minRewardAsk, and maxRewardAsk fields. removes the integer constraint from zod validation and rewrites the token input component to properly handle decimal input with formatting.
closes #1250
Summary by CodeRabbit
-
New Features
- Added decimal value support for reward amounts and submissions, enabling more granular pricing control
- Improved input component with automatic decimal formatting, precision control, and enhanced focus/blur handling for intuitive data entry
- Updated form validation to accept decimal numbers for submission amounts
βοΈ Tip: You can customize this high-level summary in your review settings.
@7ttp is attempting to deploy a commit to the Superteam Team on Vercel.
A member of the Team first needs to authorize it.
Walkthrough
This PR enables decimal number support across the application stack by converting database schema numeric fields from integers to floats, updating the token input component to handle and format decimal values, and relaxing validation rules to accept non-integer numbers with decimal precision.
Changes
| Cohort / File(s) | Summary |
|---|---|
Database Schema Migration prisma/schema.prisma |
Changed maxRewardAsk, minRewardAsk in Bounties and BountiesTemplates models, and ask in Submission model from Int? to Float? to support decimal compensation and quote values. |
Decimal Input Component src/components/ui/token-input.tsx |
Introduced controlled input state with decimal handling, added formatting helpers and MAX_DECIMALS constant, switched from numeric to text input with inputMode="decimal", and implemented focus/blur logic to format and validate decimal values. Made component props readonly. |
Validation Schema src/features/listings/utils/submissionFormSchema.ts |
Updated ask field validation from int() to allow any non-negative decimal number, removing integer constraint while preserving min(0) bound. |
Estimated code review effort
π― 3 (Moderate) | β±οΈ ~20 minutes
-
Schema migration implications: Review whether existing data in
maxRewardAsk,minRewardAsk, andaskfields requires migration strategies or data transformation before/after the schema change. -
Decimal precision & formatting: Verify that the
MAX_DECIMALSconstant,formatNumber, andlimitDecimalshelpers correctly enforce decimal places across all use cases and that theinputMode="decimal"behavior is consistent across browsers. -
Validation logic: Confirm that removing the
int()constraint insubmissionFormSchema.tsaligns with backend validation and that decimal values persist correctly through the submission flow.
Possibly related PRs
- SuperteamDAO/earn#1048: Modifies token input components to add decimal support with decimal formatting and validation logic.
-
SuperteamDAO/earn#1062: Updates numeric types for
minRewardAsk,maxRewardAsk, andSubmission.askfields; directly related to schema changes in this PR.
Poem
π° Hops of joy, decimals bloom,
No more rounding gloom!
Floats replace the stony Int,
Precision now our mint.
Quotes and asks now dance with grace,
Decimals find their place. β¨
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 (4 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | β Passed | Check skipped - CodeRabbitβs high-level summary is enabled. |
| Title check | β Passed | The title accurately and concisely captures the main objective of the changes: enabling decimal value support in compensation and quote fields. |
| Linked Issues check | β Passed | The PR fully addresses all coding requirements from issue #1250: database schema updated to Float, validation logic modified to accept decimals, token input component rewritten to handle decimal formatting up to 4 places. |
| Out of Scope Changes check | β Passed | All changes directly support the objective of enabling decimal values in compensation/quote fields; no extraneous modifications detected across schema, validation, and UI components. |
β¨ Finishing touches
- [ ] π Generate docstrings
π§ͺ Generate unit tests (beta)
- [ ] Create PR with unit tests
- [ ] Post copyable unit tests in a comment
π 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 ce715672f063ffdc4f523d44d1a24e352181a36a and 59ba9b78ffe8b9f10dd24b8b87b5c4baf16d97d9.
π Files selected for processing (3)
-
prisma/schema.prisma(3 hunks) -
src/components/ui/token-input.tsx(3 hunks) -
src/features/listings/utils/submissionFormSchema.ts(1 hunks)
π§° Additional context used
π Path-based instructions (8)
**/*
π CodeRabbit inference engine (.cursor/rules/naming-conventions.mdc)
Use kebab-case for file names (e.g.,
my-component.ts)
Files:
-
prisma/schema.prisma -
src/components/ui/token-input.tsx -
src/features/listings/utils/submissionFormSchema.ts
**/*.{ts,tsx}
π CodeRabbit inference engine (.cursor/rules/any-inside-generic-functions.mdc)
**/*.{ts,tsx}: When building generic functions in TypeScript where the return type depends on the input type parameter, useanytype assertion when TypeScript cannot match runtime logic to type logic (e.g., conditional return types) Outside of generic functions, useanytype extremely sparingly
**/*.{ts,tsx}: Proactively use discriminated unions to model data that can be in one of a few different shapes, such as when sending events between environments Use switch statements to handle the results of discriminated unions Use discriminated unions to prevent the 'bag of optionals' problem when describing state with multiple mutually exclusive conditions (e.g., fetching state with status, data, and error fields)
**/*.{ts,tsx}: Do not introduce new enums into the codebase. Retain existing enums. If you require enum-like behaviour, use anas constobject instead of enums Understand that numeric enums produce reverse mappings, resulting in double the keys compared to the number of members defined
**/*.{ts,tsx}: Use import type whenever you are importing a type Prefer top-levelimport typeover inlineimport { type ... }syntax
**/*.{ts,tsx}: Prefer interfaces when modelling inheritance in TypeScript Avoid using the&(intersection) operator in TypeScript; only use it whereinterface extendsis not possible due to performance concerns
**/*.{ts,tsx}: Use UpperCamelCase (PascalCase) for classes, types, and interfaces (e.g.,MyClass,MyInterface) Inside generic types, functions or classes, prefix type parameters withT(e.g.,TKey,TValue)Be aware that with
noUncheckedIndexedAccessenabled intsconfig.json, indexing into objects and arrays returnsType | undefinedinstead of justType. Ensure null/undefined checks are performed when accessing object properties or array elements.Use
property: Type | undefinedinstead ofproperty?: Typefor TypeScript type definitions to force explicit property passing and prevent bugs from...
Files:
-
src/components/ui/token-input.tsx -
src/features/listings/utils/submissionFormSchema.ts
**/*.{js,jsx,ts,tsx}
π CodeRabbit inference engine (.cursor/rules/default-exports.mdc)
Do not use default exports unless explicitly required by the framework. Use named exports instead (e.g.,
export function myFunction()rather thanexport default function myFunction())Import motion components from 'motion/react' instead of 'framer-motion'
**/*.{js,jsx,ts,tsx}: PostHog event names should follow the 'action_location' convention with lowercase words separated by underscores (e.g., 'getting started_sponsor resources', 'login_navbar') Be specific when naming PostHog events: the location should clearly identify the UI section (e.g., sponsor resources, navbar, sidebar, banner) Use action verbs in PostHog event names to describe what the user is doing (e.g., getting started, rate card, view profile, open) Keep PostHog event names concise using short, descriptive phrases Implement PostHog event tracking using posthog.capture('action_location') for link clicks, button clicks, and programmatic events
**/*.{js,jsx,ts,tsx}: Use updater functions (functional form) for state updates when multiple updates occur sequentially or when the new state depends on the previous state value Avoid using stale state values in asynchronous operations; always use the updater function pattern (e.g.,setPending(p => p + 1)) instead of direct state references (e.g.,setPending(pending + 1)) Include all reactive values (props, state variables, and component-scoped variables) used inside a useEffect in its dependency array Never suppress the exhaustive-deps linter warning; instead, refactor the Effect to fix the underlying dependency issue using updater functions, Effect Events, or moving logic outside the Effect Use useEffectEvent (when available) to read non-reactive values inside Effects without triggering re-runs when those values change Calculate derived values during rendering instead of using Effects for computations; reserve Effects for synchronizing with external systems Handle event-driven logic directly in event handlers rather than using Effects with condit...
Files:
-
src/components/ui/token-input.tsx -
src/features/listings/utils/submissionFormSchema.ts
**/*.{ts,tsx,js,jsx}
π CodeRabbit inference engine (.cursor/rules/jsdoc-comments.mdc)
**/*.{ts,tsx,js,jsx}: Use JSDoc comments to annotate functions and types Be concise in JSDoc comments, and only provide JSDoc comments if the function's behaviour is not self-evident Use the JSDoc inline@linktag to link to other functions and types within the same file
Files:
-
src/components/ui/token-input.tsx -
src/features/listings/utils/submissionFormSchema.ts
**/*.{js,ts,jsx,tsx}
π CodeRabbit inference engine (.cursor/rules/naming-conventions.mdc)
**/*.{js,ts,jsx,tsx}: Use camelCase for variables and function names (e.g.,myVariable,myFunction()) Use ALL_CAPS for constants and enum values (e.g.,MAX_COUNT,Color.RED)
Files:
-
src/components/ui/token-input.tsx -
src/features/listings/utils/submissionFormSchema.ts
**/*.tsx
π CodeRabbit inference engine (.cursor/rules/return-types.mdc)
React components returning JSX do not require explicit return type declarations
Files:
-
src/components/ui/token-input.tsx
**/*.{tsx,ts}
π CodeRabbit inference engine (.cursor/rules/we-might-not-need-an-effect.mdc)
**/*.{tsx,ts}: Avoid using Effects for data transformations during rendering; calculate values directly during render instead of using useState and useEffect Use useMemo instead of Effects for caching expensive calculations Use the key prop to reset component state when props change, rather than using Effects with setState Calculate derived state during render based on props rather than adjusting state in Effects Place event-specific logic in event handlers rather than Effects Avoid chains of Effects that trigger state updates; calculate all derived state at once in event handlers or during render Show notifications and post-render feedback in event handlers rather than Effects When fetching data in Effects, implement proper cleanup to prevent race conditions by ignoring stale responses Use custom Hooks to encapsulate data fetching and subscription logic instead of implementing Effects directly in components Use Effects only for synchronizing with external systems such as browser APIs, third-party libraries, WebSocket connections, or non-React UI widgets
Files:
-
src/components/ui/token-input.tsx -
src/features/listings/utils/submissionFormSchema.ts
**/*.ts
π CodeRabbit inference engine (.cursor/rules/return-types.mdc)
Declare return types for top-level module functions in TypeScript (exception: React components returning JSX)
Files:
-
src/features/listings/utils/submissionFormSchema.ts
𧬠Code graph analysis (1)
src/components/ui/token-input.tsx (3)
src/components/ui/input.tsx (1)
Input(19-19)src/utils/ogHelpers.ts (1)
formatNumber(37-37)src/constants/tokenList.ts (1)
tokenList(11-488)
π Additional comments (6)
src/features/listings/utils/submissionFormSchema.ts (1)
34-34: LGTM! Validation correctly updated to support decimal values.Removing the
.int()constraint allows the validation to accept decimal numbers while maintaining the non-negative constraint. This aligns with the database schema change fromInt?toFloat?and the UI component's decimal handling.prisma/schema.prisma (1)
57-58: LGTM! Schema changes correctly support decimal values.Converting
Int?toFloat?forask,minRewardAsk, andmaxRewardAskfields enables decimal precision across the Bounties, BountiesTemplates, and Submission models. The changes are consistent and align with the PR objectives.Note that these schema changes will require a database migration to convert existing integer columns to floating-point columns.
Also applies to: 137-138, 342-342
src/components/ui/token-input.tsx (4)
1-1: LGTM! Well-structured controlled input implementation.The addition of
useCallback,useEffect, and local state (inputValue,isFocused) provides proper controlled input behavior for decimal handling. TheMAX_DECIMALS = 4constant correctly enforces the precision requirement, and marking props asreadonlyfollows the project's immutability guidelines.Also applies to: 8-8, 16-21
23-44: LGTM! Helper functions handle decimal formatting correctly.The
formatNumberfunction properly handles edge cases (null, undefined, NaN) and usestoLocaleStringfor user-friendly display. ThelimitDecimalsfunction correctly enforces the 4-decimal limit while preserving trailing decimal points during input. Both are appropriately memoized withuseCallback.
46-90: Verify the rounding onChange behavior in handleBlur.The input handling logic is well-implemented with proper validation and decimal limiting. However, lines 84-86 trigger an
onChangecallback when the value is rounded on blur. This means the parent component may receive an unexpected update during the blur event.While this ensures precision consistency, verify that upstream components handle this onChange call correctly, especially in forms with validation or submission logic that might not expect value changes during blur events.
30-34: LGTM! useEffect and input configuration are correct.The
useEffectproperly syncs the display value only when not focused, preventing interference with active editing. The token icon lookup is streamlined, and theInputcomponent configuration usingtype="text"withinputMode="decimal"follows best practices for mobile decimal input. The CSS to hide spinner buttons is redundant for text inputs but harmless.Also applies to: 92-94, 115-124
[!TIP]
π Customizable high-level summaries are now available in beta!
You can now customize how CodeRabbit generates the high-level summary in your pull requests β including its content, structure, tone, and formatting.
- Provide your own instructions using the
high_level_summary_instructionssetting.- Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
- Use
high_level_summary_in_walkthroughto move the summary from the description to the walkthrough section.Example instruction:
"Divide the high-level summary into five sections:
- π Description β Summarize the main change in 50β60 words, explaining what was done.
- π References β List relevant issues, discussions, documentation, or related PRs.
- π¦ Dependencies & Requirements β Mention any new/updated dependencies, environment variable changes, or configuration updates.
- π Contributor Summary β Include a Markdown table showing contributions:
| Contributor | Lines Added | Lines Removed | Files Changed |- βοΈ Additional Notes β Add any extra reviewer context. Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."
Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.
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 @coderabbitai help to get the list of available commands and usage tips.
@JayeshVP24 please review this, when u get a moment!
hey this issue is no longer open, thank you for your contribution though. appreciate it!