From 7de3cedb15032c7ef21a5ec3106b4465876a7d8d Mon Sep 17 00:00:00 2001 From: Alexander Polynomdivision Date: Wed, 17 Oct 2018 14:40:21 +0200 Subject: [PATCH] refactor: Move the SM2 implementation to the backend --- .../src/algorithms/sm2/index.ts | 0 backend/src/api/user.ts | 33 +++++++++---------- 2 files changed, 16 insertions(+), 17 deletions(-) rename {frontend => backend}/src/algorithms/sm2/index.ts (100%) diff --git a/frontend/src/algorithms/sm2/index.ts b/backend/src/algorithms/sm2/index.ts similarity index 100% rename from frontend/src/algorithms/sm2/index.ts rename to backend/src/algorithms/sm2/index.ts diff --git a/backend/src/api/user.ts b/backend/src/api/user.ts index d334544..2670117 100644 --- a/backend/src/api/user.ts +++ b/backend/src/api/user.ts @@ -8,7 +8,9 @@ import { authRoute } from "../security/token"; import { userFromSession } from "../utils/user"; import { IUser, IUserDBModel } from "../models/user"; -import { ISM2Metadata } from "../models/review"; +import { + ISchedulingData, AnswerType, updateSchedulingData +} from "../algorithms/sm2"; import { LRequest } from "../types/express"; const userRouter = express.Router(); @@ -190,34 +192,31 @@ userRouter.post("/lastReview", async (req: LRequest, res) => { return; } + // NOTE: Oh oh + // Update the user's score based on what they sent us user.score += parseInt(req.body.delta); + // Itterate over all of the vocabulary that needs to have its + // metadata updated. + // Use our SM2 implementation to update the vocabulary and modify our + // copy of the user object, so that we can write the copied (and modified) + // user object back into the database. Object.keys(req.body.sm2).forEach((id: string) => { const vocabId = parseInt(id); const correct: boolean = req.body.sm2[id]; - let vocab_sm2: ISM2Metadata = Object.assign({}, + let vocab_sm2: ISchedulingData = Object.assign({}, user.vocabMetadata[vocabId]); - // TODO: Tuning? - // TODO: Move into another module - const perf = correct ? 3 : 1; - vocab_sm2.easiness += -0.8 + 0.28 * perf + 0.02 * Math.pow(perf, 2); - // Update the consecutive correct answers and the due date - if (correct) { - vocab_sm2.consecutiveCorrectAnswers += 1; - vocab_sm2.nextDueDate = dateInNDays(6 * Math.pow(vocab_sm2.easiness, vocab_sm2.consecutiveCorrectAnswers - 1)); - } else { - vocab_sm2.consecutiveCorrectAnswers = 0; - vocab_sm2.nextDueDate = dateInNDays(1); - } - - user.vocabMetadata[vocabId] = vocab_sm2; + const answer = correct ? AnswerType.CORRECT : AnswerType.WRONG; + user.vocabMetadata[vocabId] = updateSchedulingData(vocab_sm2, answer); }); // Update the last review user.lastReview = req.body.meta; - // TODO: Error handling + // NOTE: Error handling could be implemented here, but we can ensure that + // the user exists, as we just got his username (and entire data) + // from `userFromSession`. await db.collection("users").updateOne({ username: user.username, }, {