feat: Implement even more endpoints
This commit is contained in:
		
							parent
							
								
									fdaa9cb8f3
								
							
						
					
					
						commit
						9ea5078c5c
					
				| @ -1,5 +1,5 @@ | ||||
| # User | ||||
| `column`: users | ||||
| `collection`: users | ||||
| ` | ||||
| { | ||||
|     username: string, | ||||
| @ -13,10 +13,47 @@ | ||||
|     lastReview: { | ||||
|        correct: number, | ||||
|        wrong: number, | ||||
|     } | ||||
|     }, | ||||
|      | ||||
|     lastLevel: string, | ||||
|      | ||||
|     queue: number[], | ||||
| } | ||||
| ` | ||||
| 
 | ||||
| - queue stores IDs of the vocabulary | ||||
| 
 | ||||
| # Vocab | ||||
| `collection`: vocabulary | ||||
| ` | ||||
| { | ||||
|     id: string, | ||||
|     german: string[], | ||||
|     hint: string?, | ||||
|     mnemonic: string?, | ||||
|      | ||||
|     type: VocabType, | ||||
|      | ||||
|     latin: INomenData | IVerbData | IAdjektivData (See frontend models), | ||||
| ` | ||||
| 
 | ||||
| - VocabType -> number? | ||||
| - id == _id? | ||||
| 
 | ||||
| # Levels | ||||
| `collection`: levels | ||||
| ` | ||||
| { | ||||
|     level: number; | ||||
|     name: string; | ||||
|     description: string; | ||||
|      | ||||
|     vocab: number[], | ||||
| } | ||||
| ` | ||||
| 
 | ||||
| - vocab stores the IDs of the vocabulary items from the `vocabulary` collection | ||||
| 
 | ||||
| # Sessions | ||||
| column: sessions | ||||
| 
 | ||||
|  | ||||
| @ -1,17 +1,16 @@ | ||||
| import { Router, Request, Response } from "express"; | ||||
| import { Router, Response } from "express"; | ||||
| import * as bodyparser from "body-parser"; | ||||
| 
 | ||||
| import { authRoute } from "../security/token"; | ||||
| 
 | ||||
| import { LRequest } from "../types/express"; | ||||
| 
 | ||||
| const levelRouter = Router(); | ||||
| levelRouter.use(bodyparser.json()); | ||||
| levelRouter.use(authRoute); | ||||
| 
 | ||||
| levelRouter.get("/:id/vocab", async (req: Request, res: Response) => { | ||||
|     // TODO: Implement
 | ||||
|     console.log("Stub(get): /level/:id/vocab"); | ||||
| 
 | ||||
|     if (!req.params) { | ||||
| levelRouter.get("/:id/vocab", async (req: LRequest, res: Response) => { | ||||
|     if (!req.params || !req.params.id) { | ||||
|         res.send({ | ||||
|             error: "400", | ||||
|             data: { | ||||
| @ -21,20 +20,29 @@ levelRouter.get("/:id/vocab", async (req: Request, res: Response) => { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     const levelId = parseInt(req.params.id); | ||||
|     // TODO: Handle this
 | ||||
|     // if (levelId === NaN) {
 | ||||
|     //     // Something
 | ||||
|     // }
 | ||||
| 
 | ||||
|     // Find the level
 | ||||
|     // TODO: if (level)
 | ||||
|     const { db } = req; | ||||
|     const level = await db.collection("levels").findOne({ | ||||
|         // TODO: This aint safe, boi
 | ||||
|         level: levelId, | ||||
|     }); | ||||
|     console.log(level); | ||||
| 
 | ||||
|     // Fetch all the vocabulary
 | ||||
|     const vocab = await db.collection("vocabulary").find({ id: { $in: level.vocab } }).toArray(); | ||||
|     console.log(vocab); | ||||
| 
 | ||||
|     res.send({ | ||||
|         error: "0", | ||||
|         data: { | ||||
|             vocab: [{ | ||||
|                 german: ["Wein"], | ||||
|                 hint: "Worte auf '-um' sind meistens NeutrUM", | ||||
|                 type: 0, | ||||
|                 latin: { | ||||
|                     grundform: "Vinum", | ||||
|                     genitiv: "Vini", | ||||
|                     genus: "Neutrum" | ||||
|                 }, | ||||
|                 id: 0 | ||||
|             }], | ||||
|             vocab, | ||||
|         } | ||||
|     }); | ||||
| }); | ||||
|  | ||||
| @ -6,14 +6,15 @@ import { authRoute } from "../security/token"; | ||||
| import { userFromSession } from "../utils/user"; | ||||
| 
 | ||||
| import { IUser } from "../models/user"; | ||||
| import { LRequest } from "../types/express"; | ||||
| import { Db } from "mongodb"; | ||||
| 
 | ||||
| const userRouter = express.Router(); | ||||
| userRouter.use(authRoute); | ||||
| userRouter.use(bodyparser.json()); | ||||
| 
 | ||||
| // Return the user object if the user is still authenticated
 | ||||
| userRouter.get("/me", async (req, res) => { | ||||
|     //@ts-ignore
 | ||||
| userRouter.get("/me", async (req: LRequest, res) => { | ||||
|     const { db, token } = req; | ||||
| 
 | ||||
|     const session = await db.collection("sessions").findOne({ token, }); | ||||
| @ -41,10 +42,10 @@ userRouter.get("/me", async (req, res) => { | ||||
| }); | ||||
| 
 | ||||
| // Removes the user's session
 | ||||
| userRouter.get("/logout", async (req, res) => { | ||||
| userRouter.get("/logout", async (req: LRequest, res) => { | ||||
|     // Try to remove the session
 | ||||
|     //@ts-ignore
 | ||||
|     await req.db.collections("sessions").findOneAndDelete({ session: req.get("Token") }); | ||||
|     const { db, token } = req; | ||||
|     await db.collection("sessions").findOneAndDelete({ token, }); | ||||
| 
 | ||||
|     res.send({ | ||||
|         error: "0", | ||||
| @ -84,42 +85,65 @@ userRouter.get("/queue", async (req, res) => { | ||||
| }); | ||||
| 
 | ||||
| // Get ot set the last review results
 | ||||
| userRouter.get("/lastReview", async (req, res) => { | ||||
|     console.log("STUB(get): /user/lastReview"); | ||||
| userRouter.get("/lastReview", async (req: LRequest, res) => { | ||||
|     // TODO: if(user)
 | ||||
|     const { token, db } = req; | ||||
|     const user = await userFromSession(token, db); | ||||
| 
 | ||||
|     // TODO: Stub
 | ||||
|     res.send({ | ||||
|         error: "0", | ||||
|         data: { | ||||
|             correct: 6, | ||||
|             wrong: 2, | ||||
|         }, | ||||
|         data: user.lastReview, | ||||
|     }); | ||||
| }); | ||||
| userRouter.post("/lastReview", async (req, res) => { | ||||
|     console.log("STUB(post): /user/lastReview"); | ||||
| userRouter.post("/lastReview", async (req: LRequest, res) => { | ||||
|     // TODO: Check if we get the correct data
 | ||||
|     // TODO: if(user)
 | ||||
|     const { token, db } = req; | ||||
|     const user = await userFromSession(token, db); | ||||
| 
 | ||||
|     // TODO: Error handling
 | ||||
|     await db.collection("users").updateOne({ | ||||
|         username: user.username, | ||||
|     }, { | ||||
|             $set: { | ||||
|                 lastReview: req.body.meta, | ||||
|             }, | ||||
|         }); | ||||
| 
 | ||||
|     // TODO: Stub
 | ||||
|     res.send({ | ||||
|         error: "0", | ||||
|         data: {}, | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| // Get the next level
 | ||||
| userRouter.get("/nextLevel", async (req, res) => { | ||||
|     console.log("STUB: /user/nextLevel"); | ||||
| // Returns the next level (level + 1) or the current level, if no higher level
 | ||||
| // can be found
 | ||||
| async function getNextLevel(token: string, db: Db): Promise<any> { | ||||
|     // TODO: if(user)
 | ||||
|     const user = await userFromSession(token, db); | ||||
|     const { lastLevel } = user; | ||||
| 
 | ||||
|     // TODO: Stub
 | ||||
|     // Try to find a level, which level is lastLevel + 1
 | ||||
|     const level = await db.collection("levels").findOne({ | ||||
|         level: lastLevel + 1, | ||||
|     }); | ||||
| 
 | ||||
|     if (level) { | ||||
|         return level; | ||||
|     } else { | ||||
|         // TODO: Send different data, so that the Client can say "Hey, no more levels"
 | ||||
|         return await db.collection("levels").findOne({ | ||||
|             level: lastLevel | ||||
|         }); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Get the next level
 | ||||
| userRouter.get("/nextLevel", async (req: LRequest, res) => { | ||||
|     const level = await getNextLevel(req.token, req.db); | ||||
|     res.send({ | ||||
|         error: "0", | ||||
|         data: { | ||||
|             name: "Test level", | ||||
|             desc: "Just a test", | ||||
|             level: 3, | ||||
| 
 | ||||
|             done: false, | ||||
|         }, | ||||
|         data: level, | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| @ -135,16 +159,12 @@ userRouter.post("/level/:id", async (req, res) => { | ||||
| }); | ||||
| 
 | ||||
| // Get the data needed for the dashboard 
 | ||||
| userRouter.get("/dashboard", async (req, res) => { | ||||
|     console.log("SEMI-STUB(post): /user/dashboard"); | ||||
| 
 | ||||
|     //@ts-ignore
 | ||||
| userRouter.get("/dashboard", async (req: LRequest, res) => { | ||||
|     const { db, token } = req; | ||||
| 
 | ||||
|     // Get the user
 | ||||
|     const user = await userFromSession(token, db); | ||||
|     // TODO: if (user)
 | ||||
| 
 | ||||
|     const user = await userFromSession(token, db); | ||||
|     const { classId } = user; | ||||
| 
 | ||||
|     // Fetch the top ten of the class
 | ||||
| @ -162,24 +182,17 @@ userRouter.get("/dashboard", async (req, res) => { | ||||
|         return { | ||||
|             username: user.username, | ||||
|             score: user.score, | ||||
|             // TODO
 | ||||
|             // TODO: Calculate on the client?
 | ||||
|             level: 1, | ||||
|             nr: nr++, | ||||
|         }; | ||||
|     }); | ||||
| 
 | ||||
|     // TODO: Stub
 | ||||
|     const nextLevel = await getNextLevel(token, db); | ||||
|     res.send({ | ||||
|         error: "200", | ||||
|         data: { | ||||
|             // TODO: Get this some way
 | ||||
|             nextLevel: { | ||||
|                 name: "Test level", | ||||
|                 desc: "Just a test", | ||||
|                 level: 3, | ||||
| 
 | ||||
|                 done: false, | ||||
|             }, | ||||
|             nextLevel, | ||||
|             topTen, | ||||
|             lastReview: user.lastReview, | ||||
|         }, | ||||
|  | ||||
| @ -115,4 +115,3 @@ const assert = require('assert'); | ||||
|         console.log("Starting on port 8080"); | ||||
|     }); | ||||
| })(); | ||||
| 
 | ||||
|  | ||||
| @ -11,4 +11,6 @@ export interface IUser { | ||||
|         correct: number; | ||||
|         wrong: number; | ||||
|     }; | ||||
| 
 | ||||
|     lastLevel: number; | ||||
| }; | ||||
|  | ||||
| @ -35,6 +35,7 @@ export async function performLogin(username: string, password: string, db: Db): | ||||
|             classId: user.classId, | ||||
| 
 | ||||
|             lastReview: user.lastReview, | ||||
|             lastLevel: user.lastLevel, | ||||
| 
 | ||||
|             // TODO: Implement
 | ||||
|             score: 4, | ||||
|  | ||||
							
								
								
									
										8
									
								
								backend/src/types/express.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								backend/src/types/express.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| import { Request } from "express"; | ||||
| 
 | ||||
| import { Db } from "mongodb"; | ||||
| 
 | ||||
| export type LRequest = Request & { | ||||
|     db: Db; | ||||
|     token: string; | ||||
| }; | ||||
		Reference in New Issue
	
	Block a user
	 Alexander Polynomdivision
						Alexander Polynomdivision