node-mongo-demo
node.js and mongodb demo
git clone https://9o.is/git/node-mongo-demo.git
commit 1f9a189f0ebee382381d24f5fcd88c77d19c3a7f parent dfa4a2b8c2aeee1de31eed0581de866beda84d5d Author: Jul <jul@9o.is> Date: Mon, 27 Jan 2025 08:45:12 -0500 fix buggy edge cases Diffstat:
| M | backend/src/api/lucky7-bets-create.js | | | 14 | +++++++++++--- |
| M | backend/src/models/lucky7-session.js | | | 2 | +- |
| M | backend/src/services/lucky7-session.js | | | 31 | ++++++++++++++++++++++++++++--- |
3 files changed, 40 insertions(+), 7 deletions(-)
diff --git a/backend/src/api/lucky7-bets-create.js b/backend/src/api/lucky7-bets-create.js @@ -1,5 +1,5 @@ import { randomInt } from "crypto"; -import lucky7Session, { nextGameTime } from "../services/lucky7-session.js"; +import lucky7Session, { nextGameTime, findLucky7SessionByUserId } from "../services/lucky7-session.js"; import Lucky7Bet from "../models/lucky7-bet.js"; const roll = () => [randomInt(1,7), randomInt(1,7)]; @@ -18,13 +18,21 @@ const lucky7BetsCreate = async (req, res) => { } try { - const session = await lucky7Session(userId); + const session = await findLucky7SessionByUserId(userId); + + if (!session) { + return res.status(400).json({ code: "SESSION_EXPIRED", message: "Session has expired" }) + } if (session.nextGameInSeconds <= 5) { return res.status(400).json({ code: "TIMER", message: '5 seconds or less remaining for next dice roll' }) } - const rollAt = nextGameTime(session.createdAt); + const rollAt = session.nextGameTime; + + if (!rollAt) { + return res.status(400).json({ code: "SESSION_EXPIRING", message: "No more games for current session" }); + } const existingBet = await Lucky7Bet.findOne({ userId, diff --git a/backend/src/models/lucky7-session.js b/backend/src/models/lucky7-session.js @@ -1,6 +1,6 @@ import mongoose from "mongoose"; -const EXPIRES_IN_SECONDS = 86400; // 1 day +export const EXPIRES_IN_SECONDS = 86400; // 1 day const lucky7SessionSchema = mongoose.Schema({ userId: { type: 'ObjectId', ref: 'User', required: true, unique: true }, diff --git a/backend/src/services/lucky7-session.js b/backend/src/services/lucky7-session.js @@ -1,4 +1,4 @@ -import Lucky7Session from "../models/lucky7-session.js"; +import Lucky7Session, { EXPIRES_IN_SECONDS } from "../models/lucky7-session.js"; export const dateDifferenceInSeconds = (date1, date2) => { return Math.floor((date2 - date1) / 1000); @@ -10,7 +10,11 @@ export const nextGameTime = (startDateTime) => { const difference = currentSeconds - startSeconds; const nextChunk = Math.ceil(difference / 15) * 15; - return new Date((startSeconds + nextChunk) * 1000); + const result = new Date((startSeconds + nextChunk) * 1000); + const expiration = new Date(startDateTime.getTime() + (EXPIRES_IN_SECONDS * 1000)); + + if (result > expiration) return undefined; + return result; }; const lucky7Session = async (userId) => { @@ -22,12 +26,33 @@ const lucky7Session = async (userId) => { }); const { _id, createdAt } = session.toObject(); + const next = nextGameTime(createdAt); + + return { + id: _id, + createdAt, + nextGameTime: next, + nextGameInSeconds: next ? dateDifferenceInSeconds(new Date(), next) : undefined, + }; +}; + +export const findLucky7SessionByUserId = async userId => { + const session = await Lucky7Session.findOne({ + userId, + }); + + if (!session) return undefined; + + const { _id, createdAt } = session.toObject(); + const next = nextGameTime(createdAt); return { id: _id, createdAt, - nextGameInSeconds: dateDifferenceInSeconds(new Date(), nextGameTime(createdAt)), + nextGameTime: next, + nextGameInSeconds: next ? dateDifferenceInSeconds(new Date(), next) : undefined, }; + }; export default lucky7Session;