import {MODULES} from "@/constants/ielts"; import {app} from "@/firebase"; import {Module} from "@/interfaces"; import {Stat, User} from "@/interfaces/user"; import {sessionOptions} from "@/lib/session"; import {calculateBandScore} from "@/utils/score"; import {groupByModule, groupBySession} from "@/utils/stats"; import { MODULE_ARRAY } from "@/utils/moduleUtils"; import client from "@/lib/mongodb"; import {withIronSessionApiRoute} from "iron-session/next"; import {groupBy} from "lodash"; import {NextApiRequest, NextApiResponse} from "next"; import { requestUser } from "@/utils/api"; const db = client.db(process.env.MONGODB_DB); export default withIronSessionApiRoute(update, sessionOptions); async function update(req: NextApiRequest, res: NextApiResponse) { const user = await requestUser(req, res) if (user) { const docUser = await db.collection("users").findOne({ id: user.id }); if (!docUser) { res.status(401).json(undefined); return; } const stats = await db.collection("stats").find({ user: user.id }).toArray(); const groupedStats = groupBySession(stats); const sessionLevels: {[key in Module]: {correct: number; total: number}}[] = Object.keys(groupedStats).map((key) => { const sessionStats = groupedStats[key].map((stat) => ({module: stat.module, correct: stat.score.correct, total: stat.score.total})); const sessionLevels = { reading: { correct: 0, total: 0, }, listening: { correct: 0, total: 0, }, writing: { correct: 0, total: 0, }, speaking: { correct: 0, total: 0, }, level: { correct: 0, total: 0, }, }; MODULE_ARRAY.forEach((module: Module) => { const moduleStats = sessionStats.filter((x) => x.module === module); if (moduleStats.length === 0) return; const moduleScore = moduleStats.reduce( (accumulator, current) => ({correct: accumulator.correct + current.correct, total: accumulator.total + current.total}), {correct: 0, total: 0}, ); sessionLevels[module] = moduleScore; }); return sessionLevels; }); const readingLevel = sessionLevels .map((x) => x.reading) .filter((x) => x.total > 0) .reduce((acc, cur) => ({total: acc.total + cur.total, correct: acc.correct + cur.correct}), {total: 0, correct: 0}); const listeningLevel = sessionLevels .map((x) => x.listening) .filter((x) => x.total > 0) .reduce((acc, cur) => ({total: acc.total + cur.total, correct: acc.correct + cur.correct}), {total: 0, correct: 0}); const writingLevel = sessionLevels .map((x) => x.writing) .filter((x) => x.total > 0) .reduce((acc, cur) => ({total: acc.total + cur.total, correct: acc.correct + cur.correct}), {total: 0, correct: 0}); const speakingLevel = sessionLevels .map((x) => x.speaking) .filter((x) => x.total > 0) .reduce((acc, cur) => ({total: acc.total + cur.total, correct: acc.correct + cur.correct}), {total: 0, correct: 0}); const levelLevel = sessionLevels .map((x) => x.level) .filter((x) => x.total > 0) .reduce((acc, cur) => ({total: acc.total + cur.total, correct: acc.correct + cur.correct}), {total: 0, correct: 0}); const levels = { reading: calculateBandScore(readingLevel.correct, readingLevel.total, "reading", user.focus), listening: calculateBandScore(listeningLevel.correct, listeningLevel.total, "listening", user.focus), writing: calculateBandScore(writingLevel.correct, writingLevel.total, "writing", user.focus), speaking: calculateBandScore(speakingLevel.correct, speakingLevel.total, "speaking", user.focus), level: calculateBandScore(levelLevel.correct, levelLevel.total, "level", user.focus), }; await db.collection("users").updateOne( { id: user.id}, { $set: {levels} } ); res.status(200).json({ok: true}); } else { res.status(401).json(undefined); } }