Exam generation rework, batch user tables, fastapi endpoint switch

This commit is contained in:
Carlos-Mesquita
2024-11-04 23:29:14 +00:00
parent a2bc997e8f
commit 15c9c4d4bd
148 changed files with 11348 additions and 3901 deletions

View File

@@ -1,57 +0,0 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type {NextApiRequest, NextApiResponse} from "next";
import {withIronSessionApiRoute} from "iron-session/next";
import {sessionOptions} from "@/lib/session";
import {Difficulty, Exam} from "@/interfaces/exam";
import {Module} from "@/interfaces";
import axios from "axios";
export default withIronSessionApiRoute(handler, sessionOptions);
async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === "GET") return get(req, res);
if (req.method === "POST") return post(req, res);
return res.status(404).json({ok: false});
}
async function get(req: NextApiRequest, res: NextApiResponse) {
if (!req.session.user) return res.status(401).json({ok: false});
const {endpoint, topic, exercises, difficulty} = req.query as {
module: Module;
endpoint: string;
topic?: string;
exercises?: string[] | string;
difficulty?: Difficulty;
};
const url = `${process.env.BACKEND_URL}/${endpoint}`;
const params = new URLSearchParams();
if (topic) params.append("topic", topic);
if (exercises) (typeof exercises === "string" ? [exercises] : exercises).forEach((exercise) => params.append("exercises", exercise));
if (difficulty) params.append("difficulty", difficulty);
const result = await axios.get(`${url}${params.toString().length > 0 ? `?${params.toString()}` : ""}`, {
headers: {Authorization: `Bearer ${process.env.BACKEND_JWT}`},
});
res.status(200).json(result.data);
}
async function post(req: NextApiRequest, res: NextApiResponse) {
if (!req.session.user) return res.status(401).json({ok: false});
const {endpoint, topic, exercises} = req.query as {module: Module; endpoint: string[]; topic?: string; exercises?: string[]};
const url = `${process.env.BACKEND_URL}/${endpoint.join("/")}`;
const result = await axios.post(
`${url}${topic && exercises ? `?topic=${topic.toLowerCase()}&exercises=${exercises.join("&exercises=")}` : ""}`,
req.body,
{
headers: {Authorization: `Bearer ${process.env.BACKEND_JWT}`},
},
);
res.status(200).json(result.data);
}

View File

@@ -0,0 +1,79 @@
export const config = {
api: {
bodyParser: false
}
};
import type { NextApiRequest, NextApiResponse } from "next";
import { withIronSessionApiRoute } from "iron-session/next";
import { sessionOptions } from "@/lib/session";
import axios from "axios";
import formidable from 'formidable';
import FormData from 'form-data';
import { readFileSync } from 'fs';
export default withIronSessionApiRoute(handler, sessionOptions);
async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === "POST") return post(req, res);
return res.status(404).json({ ok: false });
}
async function post(req: NextApiRequest, res: NextApiResponse) {
if (!req.session.user) return res.status(401).json({ ok: false });
try {
const form = formidable({
multiples: true,
});
const [_, files] = await form.parse(req);
const formData = new FormData();
if (files.exercises?.[0]) {
const file = files.exercises[0];
const buffer = readFileSync(file.filepath);
formData.append('exercises', buffer, {
filename: file.originalFilename!,
contentType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
knownLength: buffer.length
});
}
if (files.solutions?.[0]) {
const file = files.solutions[0];
const buffer = readFileSync(file.filepath);
formData.append('solutions', buffer, {
filename: file.originalFilename!,
contentType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
knownLength: buffer.length
});
}
const result = await axios.post(
`${process.env.BACKEND_URL}/${req.query.module}/import`,
formData,
{
headers: {
Authorization: `Bearer ${process.env.BACKEND_JWT}`,
...formData.getHeaders()
}
}
);
return res.status(200).json(result.data);
} catch (error) {
console.error(error);
return res.status(500).json({
error: 'Upload failed',
details: error instanceof Error ? error.message : 'Unknown error'
});
}
}

View File

@@ -0,0 +1,47 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { withIronSessionApiRoute } from "iron-session/next";
import { sessionOptions } from "@/lib/session";
import axios from "axios";
import queryToURLSearchParams from "@/utils/query.to.url.params";
export default withIronSessionApiRoute(handler, sessionOptions);
async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === "GET") return get(req, res);
if (req.method === "POST") return post(req, res);
return res.status(404).json({ ok: false });
}
async function get(req: NextApiRequest, res: NextApiResponse) {
if (!req.session.user) return res.status(401).json({ ok: false });
const queryParams = queryToURLSearchParams(req);
const endpoint = queryParams.getAll('module').join("/");
queryParams.delete('module');
const result = await axios.get(`${process.env.BACKEND_URL}/${endpoint}${queryParams.size > 0 ? `?${queryParams.toString()}` : ""}`, {
headers: { Authorization: `Bearer ${process.env.BACKEND_JWT}` },
});
res.status(200).json(result.data);
}
async function post(req: NextApiRequest, res: NextApiResponse) {
if (!req.session.user) return res.status(401).json({ ok: false });
const queryParams = queryToURLSearchParams(req);
let endpoint = queryParams.getAll('module').join("/");
if (endpoint.startsWith("level")) {
endpoint = "level"
}
const result = await axios.post(`${process.env.BACKEND_URL}/${endpoint}`,
req.body,
{
headers: { Authorization: `Bearer ${process.env.BACKEND_JWT}` },
},
);
res.status(200).json(result.data);
}

View File

@@ -1,8 +1,8 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type {NextApiRequest, NextApiResponse} from "next";
import {withIronSessionApiRoute} from "iron-session/next";
import {sessionOptions} from "@/lib/session";
import axios from "axios";
import queryToURLSearchParams from "@/utils/query.to.url.params";
export default withIronSessionApiRoute(handler, sessionOptions);
@@ -12,16 +12,19 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
return res.status(404).json({ok: false});
}
async function post(req: NextApiRequest, res: NextApiResponse) {
if (!req.session.user) return res.status(401).json({ok: false});
const body = req.body;
const params = new URLSearchParams();
const queryParams = queryToURLSearchParams(req);
const endpoint = queryParams.getAll('module').join("/");
Object.keys(body).forEach((key) => params.append(key, body[key]));
const result = await axios.get(`${process.env.BACKEND_URL}/custom_level?${params.toString()}`, {
headers: {Authorization: `Bearer ${process.env.BACKEND_JWT}`},
});
const result = await axios.post(`${process.env.BACKEND_URL}/${endpoint}`,
req.body,
{
headers: {Authorization: `Bearer ${process.env.BACKEND_JWT}`},
},
);
res.status(200).json(result.data);
}
}