Skip to content

Commit

Permalink
Revert "merged with develop"
Browse files Browse the repository at this point in the history
This reverts commit 3297551.
  • Loading branch information
Aron Petkovski committed Nov 14, 2023
1 parent 3297551 commit cca794c
Showing 1 changed file with 89 additions and 171 deletions.
260 changes: 89 additions & 171 deletions src/server/trpc/router/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { z } from 'zod';

import { env } from '@/env/server.mjs';
import courses, { JSONCourse } from '@data/courses.json';
import courses, { JSONCourse } from '@data/courses.json';

import { courseCache } from './courseCache';
import { DegreeNotFound, DegreeValidationError } from './errors';
Expand Down Expand Up @@ -49,8 +48,13 @@ export const validatorRouter = router({
throw new TRPCError({ code: 'FORBIDDEN' });
}

const coursesFromApi: JSONCourse[] = courses;
const coursesFromApi: JSONCourse[] = courses;
let year = new Date().getFullYear(); // If plan has no semesters, default to current year.
if (planData.semesters.length > 0) {
// If plan has semesters, default to first semester's year.
year = Math.min(...planData.semesters.map((sem) => sem.year));
}

const coursesFromAPI: PlatformCourse[] = await courseCache.getCourses(year);
/* sanitizing data from API db.
* TODO: Fix this later somehow
*/
Expand All @@ -64,15 +68,16 @@ export const validatorRouter = router({
}
>();

for (const course of coursesFromApi) {
for (const course of coursesFromApi) {
for (const course of coursesFromAPI) {
courseMapWithCodeKey.set(`${course.subject_prefix} ${course.course_number}`, {
prereqs: course.prerequisites,
coreqs: course.corequisites,
co_or_pre_requisites: course.co_or_pre_requisites,
});
courseMapWithIdKey.set(course.id, `${course.subject_prefix} ${course.course_number}`);
courseMapWithIdKey.set(course.id, `${course.subject_prefix} ${course.course_number}`);
courseMapWithIdKey.set(
course.internal_course_number,
`${course.subject_prefix} ${course.course_number}`,
);
}

/* Hash to store pre req data.
Expand Down Expand Up @@ -109,8 +114,7 @@ export const validatorRouter = router({
): Array<[Array<string>, number]> => {
const prereqNotMet: Array<[Array<string>, number]> = [];
let count = 0;
if (requirements.options.length === 0) {
if (requirements.options.length === 0) {
if (!requirements || requirements.options.length === 0) {
return [];
}
const temp: [Array<string>, number] = [[], 0];
Expand Down Expand Up @@ -158,8 +162,7 @@ export const validatorRouter = router({
): Array<[Array<string>, number]> => {
const coreqNotMet: Array<[Array<string>, number]> = [];
let count = 0;
if (requirements.options.length === 0) {
if (requirements.options.length === 0) {
if (!requirements || requirements.options.length === 0) {
return [];
}
const temp: [Array<string>, number] = [[], 0];
Expand Down Expand Up @@ -208,8 +211,7 @@ export const validatorRouter = router({
): Array<[Array<string>, number]> => {
const coreqNotMet: Array<[Array<string>, number]> = [];
let count = 0;
if (requirements.options.length === 0) {
if (requirements.options.length === 0) {
if (!requirements || requirements.options.length === 0) {
return [];
}
const temp: [Array<string>, number] = [[], 0];
Expand Down Expand Up @@ -308,166 +310,86 @@ export const validatorRouter = router({
}
}),
// Protected route: ensures session user is same as plan owner
degreeValidator: protectedProcedure.input(z.string().min(1)).query(async ({ ctx, input }) => {
// Fetch current plan
const planData = await ctx.prisma.plan.findUnique({
where: {
id: input,
},
select: {
name: true,
id: true,
userId: true,
semesters: {
include: {
courses: true,
},
degreeValidator: protectedProcedure
.input(z.object({ planId: z.string().min(1), startYear: z.number() }))
.query(async ({ ctx, input: { planId, startYear } }) => {
// Fetch current plan
const planData = await ctx.prisma.plan.findUnique({
where: {
id: planId,
},
transferCredits: true,
},
});
degreeValidator: protectedProcedure.input(z.string().min(1)).query(async ({ ctx, input }) => {
// Fetch current plan
const planData = await ctx.prisma.plan.findUnique({
where: {
id: input,
},
select: {
name: true,
id: true,
userId: true,
semesters: {
include: {
courses: true,
select: {
name: true,
id: true,
userId: true,
semesters: {
include: {
courses: true,
},
},
transferCredits: true,
},
transferCredits: true,
},
});

if (!planData) {
throw new TRPCError({
code: 'NOT_FOUND',
message: 'Plan not found',
});
}
if (!planData) {
throw new TRPCError({
code: 'NOT_FOUND',
message: 'Plan not found',
});
}

if (ctx.session.user.id !== planData.userId) {
throw new TRPCError({ code: 'FORBIDDEN' });
}
if (ctx.session.user.id !== planData.userId) {
throw new TRPCError({ code: 'FORBIDDEN' });
}
if (!planData) {
throw new TRPCError({
code: 'NOT_FOUND',
message: 'Plan not found',
});
}

const { semesters, transferCredits } = planData;
const { semesters, transferCredits } = planData;
if (ctx.session.user.id !== planData.userId) {
throw new TRPCError({ code: 'FORBIDDEN' });
}

// Get degree requirements
const degreeRequirements = await ctx.prisma.degreeRequirements.findFirst({
where: {
plan: { id: planData.id },
},
});
// Get degree requirements
const degreeRequirements = await ctx.prisma.degreeRequirements.findFirst({
where: {
plan: { id: planData.id },
},
});

// Get bypasses
const bypasses = degreeRequirements?.bypasses ?? [];
// Get bypasses
const bypasses = degreeRequirements?.bypasses ?? [];

// Remove invalidCourses
const removeInvalidCoursesFromSemesters = () => {
return semesters.map((sem) => {
const courses = sem.courses
.reduce((acc, curr) => [...acc, curr.code], [] as string[])
.filter((c) => {
const [possiblePrefix, possibleCode] = c.split(' ');
if (Number.isNaN(Number(possibleCode)) || !Number.isNaN(Number(possiblePrefix))) {
return false;
}
return true;
});
return { ...sem, courses };
});
};
// Remove invalidCourses
const removeInvalidCoursesFromSemesters = () => {
return semesters.map((sem) => {
const courses = sem.courses
.reduce((acc, curr) => [...acc, curr.code], [] as string[])
.filter((c) => {
const [possiblePrefix, possibleCode] = c.split(' ');
if (Number.isNaN(Number(possibleCode)) || !Number.isNaN(Number(possiblePrefix))) {
return false;
}
return true;
});
return { ...sem, courses };
const { semesters, transferCredits } = planData;

// Get degree requirements
const degreeRequirements = await ctx.prisma.degreeRequirements.findFirst({
where: {
plan: { id: planData.id },
},
});
};

const semestersWithCourses = removeInvalidCoursesFromSemesters();
const semestersWithCourses = removeInvalidCoursesFromSemesters();
// Get bypasses
const bypasses = degreeRequirements?.bypasses ?? [];

if (!degreeRequirements?.major || degreeRequirements.major === 'undecided') {
return { plan: planData, validation: [], bypasses: [] };
}
if (!degreeRequirements?.major || degreeRequirements.major === 'undecided') {
return { plan: planData, validation: [], bypasses: [] };
}
// Remove invalidCourses
const removeInvalidCoursesFromSemesters = () => {
return semesters.map((sem) => {
const courses = sem.courses
.reduce((acc, curr) => [...acc, curr.code], [] as string[])
.filter((c) => {
const [possiblePrefix, possibleCode] = c.split(' ');
if (Number.isNaN(Number(possibleCode)) || !Number.isNaN(Number(possiblePrefix))) {
return false;
}
return true;
});
return { ...sem, courses };
});
};

// TODO: will we always ignore odd credits such as 'PSY 1---'?
const regex = /([a-z0-9])* ([a-z0-9]){4}$/gi;
const validTransferCredits = transferCredits.filter((credit) => credit.match(regex) !== null);
// TODO: will we always ignore odd credits such as 'PSY 1---'?
const regex = /([a-z0-9])* ([a-z0-9]){4}$/gi;
const validTransferCredits = transferCredits.filter((credit) => credit.match(regex) !== null);

const body = {
courses: [...semestersWithCourses.flatMap((s) => s.courses), ...validTransferCredits],
requirements: {
majors: [degreeRequirements.major],
minors: [],
},
bypasses,
};
const body = {
courses: [...semestersWithCourses.flatMap((s) => s.courses), ...validTransferCredits],
requirements: {
majors: [degreeRequirements.major],
minors: [],
},
bypasses,
};
const semestersWithCourses = removeInvalidCoursesFromSemesters();

if (!degreeRequirements?.major || degreeRequirements.major === 'undecided') {
return { plan: planData, validation: [], bypasses: [] };
}

// TODO: will we always ignore odd credits such as 'PSY 1---'?
const regex = /([a-z0-9])* ([a-z0-9]){4}$/gi;
const validTransferCredits = transferCredits.filter((credit) => credit.match(regex) !== null);

const body = {
courses: [...semestersWithCourses.flatMap((s) => s.courses), ...validTransferCredits],
requirements: {
year: startYear,
majors: [degreeRequirements.major],
minors: [],
},
bypasses,
};

const validationData = await fetch(`${env.NEXT_PUBLIC_VALIDATOR}/validate`, {
method: 'POST',
body: JSON.stringify(body),
headers: {
'content-type': 'application/json',
},
})
.then(async (res) => {
if (!res.ok) {
const errorMsg = await res.json();
throw new Error(`validator fetch failed with status ${res.status}: ${errorMsg.error}.`);
}
return res.json();
})
.catch((err) => {
const errorMessage = `Validator error: ${err.message}`;
console.error('Validator error', err);
const validationData = await fetch(`${env.NEXT_PUBLIC_VALIDATOR}/validate`, {
method: 'POST',
body: JSON.stringify(body),
Expand All @@ -487,18 +409,14 @@ export const validatorRouter = router({
console.error('Validator error', err);
throw new TRPCError({
code: 'INTERNAL_SERVER_ERROR',
cause: err,
message: errorMessage,
cause: err,
message: errorMessage,
message: error.message,
cause: error,
});
});
});
}

return { plan: planData, validation: validationData, bypasses };
}),
return { plan: planData, validation: validationData, bypasses };
}),
const validationData = await res.json();
return { plan: planData, validation: validationData, bypasses };
}),
});

type CourseOptions = {
Expand Down

0 comments on commit cca794c

Please sign in to comment.