AI Review Center
Commit Review Workspace ?
Select a commit on the left to inspect quality, security, business value, findings, and suggested code changes.
Project AI Score
?
71%
Quality Avg
?
72%
Security Avg
?
74%
Reviews
?
123
Review Result ?
solutionbowl/website · 6cdead7b
The commit introduces a scrolling text feature to the live race watch component and adds multi-race betting logic with compound profit calculation in MultiRaceDetail. The new scrolling animation is visually appealing and the multi-race logic enhances business value by supporting more flexible betting options. However, code quality could improve with better type safety, reduced React state nullability, and clearer division of responsibilities. There is a moderate bug risk as invalid odds handling may result in an unexpected payout of zero, and calculation logic could use more validation. Security considerations are moderate as there is no obvious input sanitization for scrolling text or betting inputs which may lead to XSS or injection risks.
Quality
?
75%
Security
?
60%
Business Value
?
85%
Maintainability
?
75%
Issues & Suggested Fixes
?
1AI detects the issue
2Shows file, line, or evidence
3Suggests the fix to apply
Usestate With Null Value For Scrollingtext
Where
src/components/racing/WatchLive.tsx:13
Issue / Evidence
useState with null value for scrollingText
Suggested Fix
refactor to use empty string or separate boolean to avoid null checks
Inserting Raw Scrollingtext Without Saniti...
Where
src/components/racing/WatchLive.tsx:92
Issue / Evidence
inserting raw scrollingText without sanitization
Suggested Fix
sanitize input to prevent potential XSS
Payout Calculation Returns If Any Odds A...
Where
src/pages/MultiRaceDetail.tsx:262-273
Issue / Evidence
payout calculation returns 0 if any odds are invalid
Suggested Fix
handle invalid or zero odds more gracefully with error feedback
Console.log In Production Code
Where
src/pages/MultiRaceDetail.tsx:283-287
Issue / Evidence
console.log in production code
Suggested Fix
remove or replace with proper logging mechanism
Missing Validation
Where
src/pages/MultiRaceDetail.tsx:159
Issue / Evidence
(implied) no input validation on stakeAmount or slipSelections
Suggested Fix
add validation to avoid invalid state or negative/zero wagers
Lacks Detail
Where
commit message
Issue / Evidence
lacks detail
Suggested Fix
improve commit message to clearly describe the changes and motivation for maintainability
Code Change Preview · src/components/racing/WatchLive.tsx
?
Removed / Before Commit
- diff --git a/src/components/racing/WatchLive.tsx b/src/components/racing/WatchLive.tsx - index c66dbcc..543e588 100644 - const colors = useThemeColors() - const [liveUrl, setLiveUrl] = useState<string | null>(null) - const [videoId, setVideoId] = useState<string | null>(null) - const [loading, setLoading] = useState(true) - const [iframeLoaded, setIframeLoaded] = useState(false) - - - const data = await getRaceDetails(raceId) - const rawUrl = data?.liveUrl - - const { embed, id } = rawUrl - ? convertToEmbedUrl(rawUrl) - - setLiveUrl(embed) - setVideoId(id) - } catch (error) {
Added / After Commit
+ diff --git a/src/components/racing/WatchLive.tsx b/src/components/racing/WatchLive.tsx + index c66dbcc..543e588 100644 + const colors = useThemeColors() + const [liveUrl, setLiveUrl] = useState<string | null>(null) + const [videoId, setVideoId] = useState<string | null>(null) + const [scrollingText, setScrollingText] = useState<string | null>(null) + const [loading, setLoading] = useState(true) + const [iframeLoaded, setIframeLoaded] = useState(false) + + + const data = await getRaceDetails(raceId) + const rawUrl = data?.liveUrl + const rawScrollingText = data?.scrolling_text + + const { embed, id } = rawUrl + ? convertToEmbedUrl(rawUrl) + + setLiveUrl(embed)
Removed / Before Commit
- diff --git a/src/pages/HorseRacingDetails.tsx b/src/pages/HorseRacingDetails.tsx - index e67eef1..7c442f0 100644 - odds: market.odds.map(runner => { - const runnerId = runner.runner?.runnerId || runner.runnerId - - // Find exposure for this specific runner in this market - const runnerExposure = exposureData.find( - exp => exp.marketId === market.marketId && exp.runnerId === runnerId - )
Added / After Commit
+ diff --git a/src/pages/HorseRacingDetails.tsx b/src/pages/HorseRacingDetails.tsx + index e67eef1..7c442f0 100644 + odds: market.odds.map(runner => { + const runnerId = runner.runner?.runnerId || runner.runnerId + + const runnerExposure = exposureData.find( + exp => exp.marketId === market.marketId && exp.runnerId === runnerId + )
Removed / Before Commit
- diff --git a/src/pages/MultiRaceDetail.tsx b/src/pages/MultiRaceDetail.tsx - index 6fcbee9..53b882d 100644 - runner: Runner - } - - const MAX_SELECTIONS = 3 - const ALL_RACES_TAB = "all" - const SILK_COLORS = [ - "#ef4444", - const combinedOdds = slipSelections.length > 0 - ? slipSelections.reduce((total, selection) => total * (selection.runner.backOdd || 0), 1) - : 0 - const potentialPayout = stakeAmount * combinedOdds - const multiBetName = selections.length >= 3 - ? "Triple" - : selections.length === 2 - ? "Double" - : "Straight"
Added / After Commit
+ diff --git a/src/pages/MultiRaceDetail.tsx b/src/pages/MultiRaceDetail.tsx + index 6fcbee9..53b882d 100644 + runner: Runner + } + + // const MAX_SELECTIONS = 3 + const ALL_RACES_TAB = "all" + const SILK_COLORS = [ + "#ef4444", + const combinedOdds = slipSelections.length > 0 + ? slipSelections.reduce((total, selection) => total * (selection.runner.backOdd || 0), 1) + : 0 + + // Calculate potential payout with compound profit logic + const potentialPayout = useMemo(() => { + if (slipSelections.length === 0 || stakeAmount <= 0) { + return 0 + }
Removed / Before Commit
- diff --git a/src/types/racing.ts b/src/types/racing.ts - index 590124d..44fed37 100644 - status: boolean - horses: Horse[] - liveUrl?: string - raceType?: string - betStartBeforeInMin?: number | string | null - winnerSettle?: boolean
Added / After Commit
+ diff --git a/src/types/racing.ts b/src/types/racing.ts + index 590124d..44fed37 100644 + status: boolean + horses: Horse[] + liveUrl?: string + scrolling_text?: string + raceType?: string + betStartBeforeInMin?: number | string | null + winnerSettle?: boolean