Showing AI reviews for tenant-service
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;