Showing AI reviews for tenant-service
Project AI Score ?
67%
Quality Avg ?
69%
Security Avg ?
64%
Reviews ?
143

Review Result ?

solutionbowl/tenant-service · 0abe9d8f
This commit introduces comprehensive market odds updates for horse racing markets including better initialization, locking mechanisms with Redis, safe update methodology with last-write-wins strategy, and error handling. The changes improve the robustness and concurrency control. However, the security score is moderate because the locking mechanism could benefit from further security best practices like cryptographically strong lock tokens and better error handling. Bug risk is low but not negligible due to the complexity of distributed locks. Business value is high as these changes enable safer, concurrent updates of market odds which likely improve system reliability and user experience.
Quality ?
85%
Security ?
70%
Business Value ?
80%
Maintainability ?
83%
Issues & Suggested Fixes ?
1AI detects the issue
2Shows file, line, or evidence
3Suggests the fix to apply
Locking Value Uses Math.random Which Is No...
Where src/controllers/horseracing/market.controller.js:186
Issue / Evidence locking value uses Math.random which is not cryptographically secure
Suggested Fix use a cryptographically secure random value to generate lock tokens
Locking Expires After 5 Seconds With No Re...
Where src/controllers/horseracing/market.controller.js:187
Issue / Evidence locking expires after 5 seconds with no renew mechanism
Suggested Fix consider implementing lock renewal or verifying lock ownership before releasing to avoid premature lock expiration issues
Duplicate Logic
Where src/controllers/horseracing/market.controller.js:153
Issue / Evidence error handling for create with duplicate key gives 400 response
Suggested Fix consider logging such race conditions for monitoring and debugging
Missing Validation
Where src/controllers/horseracing/market.controller.js:240
Issue / Evidence input validation error messages do not specify expected format
Suggested Fix improve error messages with expected input details for easier client debugging
Lacks Detail
Where commit message
Issue / Evidence lacks detail
Suggested Fix enhance commit message to describe what the fix does specifically and why for improved maintainability and traceability
Code Change Preview · src/controllers/horseracing/market.controller.js ?
Removed / Before Commit
- diff --git a/src/controllers/horseracing/market.controller.js b/src/controllers/horseracing/market.controller.js
- index 7cce12a..6dec8b2 100644
- const Bet = require("../../models/Bet");
- const RacingBet = require("../../models/RacingBet");
- const { emitRaceOdds } = require("../../utils/socketClient");
- 
- 
- /**
-  * Helper function to build the full JSON payload for a race
-  */
- const buildRaceMarketJSON = async (raceId, selectedMarkets = []) => {
-   // Fetch runners from DB
-   const rawHorses = await HorseList.find({ race_id: raceId });
- 
-   console.log("rawHorses", rawHorses);
-   const baseOdds = rawHorses.map(horse => {
-     return {
- runner: {
Added / After Commit
+ diff --git a/src/controllers/horseracing/market.controller.js b/src/controllers/horseracing/market.controller.js
+ index 7cce12a..6dec8b2 100644
+ const Bet = require("../../models/Bet");
+ const RacingBet = require("../../models/RacingBet");
+ const { emitRaceOdds } = require("../../utils/socketClient");
+ const crypto = require("crypto");
+ 
+ const generateMarketId = () => "HR" + crypto.randomBytes(4).toString("hex").toUpperCase();
+ 
+ 
+ const DEFAULT_ODDS_TYPE = "INDIAMANUAL";
+ 
+ const buildRaceMarketJSON = async (raceId, selectedMarkets = []) => {
+   const rawHorses = await HorseList.find({ race_id: raceId }).lean();
+ 
+   if (!rawHorses || rawHorses.length === 0) {
+     throw new Error("No runners found for this race");
+   }
Removed / Before Commit
- diff --git a/src/controllers/horseracing/markettest.js b/src/controllers/horseracing/markettest.js
- new file mode 100644
- index 0000000..9845998
- \ No newline at end of file
Added / After Commit
+ diff --git a/src/controllers/horseracing/markettest.js b/src/controllers/horseracing/markettest.js
+ new file mode 100644
+ index 0000000..9845998
+ /**
+  * Helper function to build the full JSON payload for a race
+  */
+ const buildRaceMarketJSON = async (raceId, selectedMarkets = []) => {
+     // Fetch runners from DB
+     const rawHorses = await HorseList.find({ race_id: raceId });
+ 
+     console.log("rawHorses", rawHorses);
+     const baseOdds = rawHorses.map(horse => {
+         return {
+             runner: {
+                 runnerId: horse._id,
+                 name: horse.horse_name,
+                 gateNo: horse.gate_number,
+                 horse_number: horse.horse_number,
Removed / Before Commit
- diff --git a/src/services/redisService.js b/src/services/redisService.js
- index 0f447ce..23c207a 100644
- return await client.keys("race:*");
- };
- 
- // Optionally connect immediately or expose the connect function
- connectRedis().catch(console.error);
- 
- connectRedis,
- getMarket,
- setMarket,
-   getAllMarketKeys
- };
Added / After Commit
+ diff --git a/src/services/redisService.js b/src/services/redisService.js
+ index 0f447ce..23c207a 100644
+ return await client.keys("race:*");
+ };
+ 
+ const RELEASE_LOCK_LUA = `
+ if redis.call("get", KEYS[1]) == ARGV[1] then
+   return redis.call("del", KEYS[1])
+ else
+   return 0
+ end
+ `;
+ 
+ async function acquireLock(key, value, ttlSec = 5) {
+   if (typeof key !== "string" || !key) {
+     console.warn("acquireLock: invalid key", { keyType: typeof key, key });
+     return false;
+   }
Removed / Before Commit
- diff --git a/src/utils/socketClient.js b/src/utils/socketClient.js
- index 157d463..588267f 100644
- const emitRaceOdds = async (raceId, oddsData, tenantId = null) => {
- const s = getSocket();
- 
-   // 1️⃣ Emit raw odds to everyone (no exposure mixed in)
- s.emit(`raceOdds`, { raceId, oddsData });
- 
-   // 2️⃣ Admin → global exposure (no tenant filter)
- try {
- const globalExposure = await getExposureData({ raceId });
- s.emit("raceExposureAdmin", {
Added / After Commit
+ diff --git a/src/utils/socketClient.js b/src/utils/socketClient.js
+ index 157d463..588267f 100644
+ const emitRaceOdds = async (raceId, oddsData, tenantId = null) => {
+ const s = getSocket();
+ 
+ 
+ s.emit(`raceOdds`, { raceId, oddsData });
+ 
+ 
+ try {
+ const globalExposure = await getExposureData({ raceId });
+ s.emit("raceExposureAdmin", {