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
?
67%
Quality Avg
?
69%
Security Avg
?
64%
Reviews
?
143
Review Result ?
solutionbowl/tenant-service · 55844243
The commit adds two new API endpoints: one to toggle multi-bet capability for a race and another to fetch multi-bet-eligible races with WINNER market odds. The implementations include input validation (checking object IDs and boolean types), error handling, and proper querying with population and filtering of data. The functionality provides clear business value by enabling and retrieving multi-bet races with relevant market information. However, there are areas to improve quality, security, and robustness such as better input sanitization, clearer validation messages, and adding authorization checks for modifying data.
Quality
?
75%
Security
?
60%
Business Value
?
80%
Maintainability
?
78%
Issues & Suggested Fixes
?
1AI detects the issue
2Shows file, line, or evidence
3Suggests the fix to apply
Missing Validation
Where
src/controllers/horseracing/race.controller.js:178
Issue / Evidence
input validation for race ID
Suggested Fix
add explicit null/undefined checks before checking ObjectId validity to reduce unexpected errors
Missing Validation
Where
src/controllers/horseracing/race.controller.js:182
Issue / Evidence
input validation for allow_multi_bet
Suggested Fix
explicitly check for presence of allow_multi_bet in body to avoid potential undefined usage
Security Issue
Where
src/controllers/horseracing/race.controller.js:172
Issue / Evidence
missing authorization/authentication
Suggested Fix
add authorization checks to restrict who can toggle multi-bet setting to improve security
Missing Validation
Where
src/controllers/horseracing/website.controller.js:21
Issue / Evidence
input validation for event_id
Suggested Fix
add explicit null/undefined check and sanitize input to prevent injection or unexpected failures
Querying Racemarket
Where
src/controllers/horseracing/website.controller.js:49
Issue / Evidence
querying RaceMarket
Suggested Fix
add a filter or explicit check to only fetch 'WINNER' market type to reduce data volume and improve performance
Unclear And Typo 'Toggel'
Where
commit message
Issue / Evidence
unclear and typo 'toggel'
Suggested Fix
improve commit message clarity and fix typo to enhance codebase maintainability
Code Change Preview · src/controllers/horseracing/race.controller.js
?
Removed / Before Commit
- diff --git a/src/controllers/horseracing/race.controller.js b/src/controllers/horseracing/race.controller.js - index 235f5b3..aef8d5d 100644 - res.status(500).json({ message: "Server error" }); - } - };
Added / After Commit
+ diff --git a/src/controllers/horseracing/race.controller.js b/src/controllers/horseracing/race.controller.js + index 235f5b3..aef8d5d 100644 + res.status(500).json({ message: "Server error" }); + } + }; + + exports.toggleMultiBet = async (req, res) => { + try { + const { id } = req.params; + const { allow_multi_bet } = req.body; + + if (!mongoose.Types.ObjectId.isValid(id)) { + return res.status(400).json({ message: "Invalid race ID" }); + } + + if (typeof allow_multi_bet !== "boolean") { + return res.status(400).json({ message: "allow_multi_bet must be boolean" }); + }
Removed / Before Commit
- diff --git a/src/controllers/horseracing/website.controller.js b/src/controllers/horseracing/website.controller.js - new file mode 100644 - index 0000000..22d0670
Added / After Commit
+ diff --git a/src/controllers/horseracing/website.controller.js b/src/controllers/horseracing/website.controller.js + new file mode 100644 + index 0000000..22d0670 + const HorseRace = require("../../models/HorseRace"); + const RaceMarket = require("../../models/RaceMarket"); + const mongoose = require("mongoose"); + + /** + * Get multi-bet eligible races with WINNER market odds + * GET /api/website/multi-bet-races + */ + exports.getMultiBetRaces = async (req, res) => { + try { + const { event_id } = req.query; + + // Build query + const query = { + allow_multi_bet: true,
Removed / Before Commit
- diff --git a/src/controllers/runnerScrapingController.js b/src/controllers/runnerScrapingController.js - index a1d7e9d..28a0d41 100644 - } - - /** - * Extract all races with their runners from the page - */ - async function extractAllRacesData(url) { - try { - const { data: html } = await axios.get(url, { - headers: { - // console.log("Page URL:", pageUrl); - // console.log("Race ID:", raceId); - - // Step 1: Get race name from database using race ID - if (!mongoose.Types.ObjectId.isValid(raceId)) { - return res.status(400).json({ - // console.log("Race Found in DB:", raceData.race_name);
Added / After Commit
+ diff --git a/src/controllers/runnerScrapingController.js b/src/controllers/runnerScrapingController.js + index a1d7e9d..28a0d41 100644 + } + + /** + * Detect website type from URL + */ + function detectWebsite(url) { + if (url.includes("racebuzz")) { + return "racebuzz"; + } else if (url.includes("indiarace.com")) { + return "indiarace"; + } + return "unknown"; + } + + /** + * Extract all races from IndiaRace.com
Removed / Before Commit
- diff --git a/src/models/HorseRace.js b/src/models/HorseRace.js - index 5d0ad36..e2cbc69 100644 - winnerSettle: { type: Boolean, default: false }, - insurance_bet: { type: Boolean, default: false }, - fancySettle: { type: Boolean, default: false }, - winDeductionPercent: { type: Number, default: 0 }, - placeDeductionPercent: { type: Number, default: 0 }, - fancyDeductionPercent: { type: Number, default: 0 },
Added / After Commit
+ diff --git a/src/models/HorseRace.js b/src/models/HorseRace.js + index 5d0ad36..e2cbc69 100644 + winnerSettle: { type: Boolean, default: false }, + insurance_bet: { type: Boolean, default: false }, + fancySettle: { type: Boolean, default: false }, + allow_multi_bet: { type: Boolean, default: false }, + winDeductionPercent: { type: Number, default: 0 }, + placeDeductionPercent: { type: Number, default: 0 }, + fancyDeductionPercent: { type: Number, default: 0 },
Removed / Before Commit
- diff --git a/src/routes/horseracing.routes.js b/src/routes/horseracing.routes.js - index f850b51..cfbf275 100644 - const marketController = require("../controllers/horseracing/market.controller"); - const resultController = require("../controllers/horseracing/result.controller"); - const reportController = require("../controllers/horseracing/report.controller"); - - // Platform Routes - router.get("/platform/tenants", authMiddleware, roleMiddleware("PLATFORM_ADMIN"), platformController.getPlatformTenants); - router.post("/races", authMiddleware, roleMiddleware("PLATFORM_ADMIN"), raceController.createRace); - router.put("/races/:id", authMiddleware, roleMiddleware("PLATFORM_ADMIN"), raceController.updateRace); - router.delete("/races/:id", authMiddleware, roleMiddleware("PLATFORM_ADMIN"), raceController.deleteRace); - - // Market Routes - router.post("/races/:raceId/markets/init", authMiddleware, roleMiddleware("PLATFORM_ADMIN"), marketController.initMarket); - router.get("/reports/race-agent-bets", authMiddleware, roleMiddleware("PLATFORM_ADMIN"), reportController.getRaceAgentsBets); - router.post("/reports/exposure", authMiddleware, roleMiddleware("PLATFORM_ADMIN", "OWNER"), reportController.getExposure); - - module.exports = router;
Added / After Commit
+ diff --git a/src/routes/horseracing.routes.js b/src/routes/horseracing.routes.js + index f850b51..cfbf275 100644 + const marketController = require("../controllers/horseracing/market.controller"); + const resultController = require("../controllers/horseracing/result.controller"); + const reportController = require("../controllers/horseracing/report.controller"); + const websiteController = require("../controllers/horseracing/website.controller"); + + // Platform Routes + router.get("/platform/tenants", authMiddleware, roleMiddleware("PLATFORM_ADMIN"), platformController.getPlatformTenants); + router.post("/races", authMiddleware, roleMiddleware("PLATFORM_ADMIN"), raceController.createRace); + router.put("/races/:id", authMiddleware, roleMiddleware("PLATFORM_ADMIN"), raceController.updateRace); + router.delete("/races/:id", authMiddleware, roleMiddleware("PLATFORM_ADMIN"), raceController.deleteRace); + router.put("/races/:id/toggle-multi-bet", authMiddleware, roleMiddleware("PLATFORM_ADMIN"), raceController.toggleMultiBet); + + // Market Routes + router.post("/races/:raceId/markets/init", authMiddleware, roleMiddleware("PLATFORM_ADMIN"), marketController.initMarket); + router.get("/reports/race-agent-bets", authMiddleware, roleMiddleware("PLATFORM_ADMIN"), reportController.getRaceAgentsBets); + router.post("/reports/exposure", authMiddleware, roleMiddleware("PLATFORM_ADMIN", "OWNER"), reportController.getExposure);
Removed / Before Commit
- diff --git a/src/routes/runnerScrapingRoutes.js b/src/routes/runnerScrapingRoutes.js - index 916c06a..57677b0 100644 - */ - router.post("/all-races", runnerScrapingController.getAllRacesFromPage); - - module.exports = router;
Added / After Commit
+ diff --git a/src/routes/runnerScrapingRoutes.js b/src/routes/runnerScrapingRoutes.js + index 916c06a..57677b0 100644 + */ + router.post("/all-races", runnerScrapingController.getAllRacesFromPage); + + /** + * @route POST /api/runner-scraping/debug + * @desc Debug HTML structure (for development) + * @body { pageUrl: string } + */ + router.post("/debug", runnerScrapingController.debugHtmlStructure); + + module.exports = router;