1- import { Request , Response } from ' express' ;
1+ import { Request , Response } from " express" ;
22
3- import { supabase } from ' ../db/setupDb' ; // Supabase instance for database interactions
4- import asyncHandler from ' ../middleware/asyncHandler' ; // Middleware to handle async route handlers
3+ import { supabase } from " ../db/setupDb" ; // Supabase instance for database interactions
4+ import asyncHandler from " ../middleware/asyncHandler" ; // Middleware to handle async route handlers
55
66// Interface to define the structure of an Offering
77export interface Offering {
@@ -27,29 +27,29 @@ export function createOffering(overrides: Partial<Offering> = {}): Offering {
2727 return {
2828 id : overrides . id ?? - 1 ,
2929 course_id : overrides . course_id ?? - 1 ,
30- meeting_section : overrides . meeting_section ?? ' No Section' ,
31- offering : overrides . offering ?? ' No Offering' ,
32- day : overrides . day ?? ' N/A' ,
33- start : overrides . start ?? ' 00:00:00' ,
34- end : overrides . end ?? ' 00:00:00' ,
35- location : overrides . location ?? ' No Room' ,
30+ meeting_section : overrides . meeting_section ?? " No Section" ,
31+ offering : overrides . offering ?? " No Offering" ,
32+ day : overrides . day ?? " N/A" ,
33+ start : overrides . start ?? " 00:00:00" ,
34+ end : overrides . end ?? " 00:00:00" ,
35+ location : overrides . location ?? " No Room" ,
3636 current : overrides . current ?? - 1 ,
3737 max : overrides . max ?? - 1 ,
3838 is_waitlisted : overrides . is_waitlisted ?? false ,
39- delivery_mode : overrides . delivery_mode ?? ' N/A' ,
40- instructor : overrides . instructor ?? ' N/A' ,
41- notes : overrides . notes ?? ' N/A' ,
42- code : overrides . code ?? ' N/A' ,
39+ delivery_mode : overrides . delivery_mode ?? " N/A" ,
40+ instructor : overrides . instructor ?? " N/A" ,
41+ notes : overrides . notes ?? " N/A" ,
42+ code : overrides . code ?? " N/A" ,
4343 } ;
4444}
4545
4646// Enum to define different types of restrictions for offerings
4747export enum RestrictionType {
48- RestrictBefore = ' Restrict Before' ,
49- RestrictAfter = ' Restrict After' ,
50- RestrictBetween = ' Restrict Between' ,
51- RestrictDay = ' Restrict Day' ,
52- RestrictDaysOff = ' Days Off' ,
48+ RestrictBefore = " Restrict Before" ,
49+ RestrictAfter = " Restrict After" ,
50+ RestrictBetween = " Restrict Between" ,
51+ RestrictDay = " Restrict Day" ,
52+ RestrictDaysOff = " Days Off" ,
5353}
5454
5555// Interface for the restriction object
@@ -70,18 +70,17 @@ export interface OfferingList {
7070
7171export interface CategorizedOfferingList {
7272 course_id : number ;
73- category : ' LEC' | ' TUT' | ' PRA'
73+ category : " LEC" | " TUT" | " PRA" ;
7474 offerings : Offering [ ] ;
7575}
7676
77-
7877// Function to fetch offerings from the database for a given course and semester
7978export async function getOfferings ( course_id : number , semester : string ) {
80- let { data : offeringData , error : offeringError } =
81- await supabase . schema ( ' course' )
82- . from ( ' offerings' )
83- . select (
84- `
79+ let { data : offeringData , error : offeringError } = await supabase
80+ . schema ( " course" )
81+ . from ( " offerings" )
82+ . select (
83+ `
8584 id,
8685 course_id,
8786 meeting_section,
@@ -98,19 +97,19 @@ export async function getOfferings(course_id: number, semester: string) {
9897 notes,
9998 code
10099 ` ,
101- )
102- . eq ( ' course_id' , course_id )
103- . eq ( ' offering' , semester ) ;
100+ )
101+ . eq ( " course_id" , course_id )
102+ . eq ( " offering" , semester ) ;
104103
105104 return offeringData ;
106105}
107106
108107// Utility function to filter valid offerings based on the provided filter
109108// function
110109export const filterValidOfferings = (
111- offerings : Offering [ ] ,
112- f : ( x : Offering ) => boolean ,
113- ) : Offering [ ] => {
110+ offerings : Offering [ ] ,
111+ f : ( x : Offering ) => boolean ,
112+ ) : Offering [ ] => {
114113 return offerings . filter ( f ) ;
115114} ;
116115
@@ -119,18 +118,16 @@ export async function getMaxDays(restrictions: Restriction[]) {
119118 for ( const restriction of restrictions ) {
120119 if ( restriction . disabled ) continue ;
121120 if ( restriction . type == RestrictionType . RestrictDaysOff ) {
122- return 5 -
123- restriction
124- . numDays ; // Subtract the restricted days from the total days
121+ return 5 - restriction . numDays ; // Subtract the restricted days from the total days
125122 }
126123 }
127- return 5 ; // Default to 5 days if no restrictions
124+ return 5 ; // Default to 5 days if no restrictions
128125}
129126
130127// Function to check if an offering satisfies the restrictions
131128export function isValidOffering (
132- offering : Offering ,
133- restrictions : Restriction [ ] ,
129+ offering : Offering ,
130+ restrictions : Restriction [ ] ,
134131) {
135132 for ( const restriction of restrictions ) {
136133 if ( restriction . disabled ) continue ;
@@ -142,15 +139,17 @@ export function isValidOffering(
142139 break ;
143140
144141 case RestrictionType . RestrictAfter :
145- console . log ( ' ====' ) ;
142+ console . log ( " ====" ) ;
146143 console . log ( offering . end ) ;
147144 console . log ( restriction . endTime ) ;
148145 if ( offering . end > restriction . startTime ) return false ;
149146 break ;
150147
151148 case RestrictionType . RestrictBetween :
152- if ( offering . start < restriction . endTime &&
153- restriction . startTime < offering . end ) {
149+ if (
150+ offering . start < restriction . endTime &&
151+ restriction . startTime < offering . end
152+ ) {
154153 return false ;
155154 }
156155 break ;
@@ -169,12 +168,11 @@ export function isValidOffering(
169168
170169// Function to get valid offerings by filtering them based on the restrictions
171170export async function getValidOfferings (
172- offerings : Offering [ ] ,
173- restrictions : Restriction [ ] ,
171+ offerings : Offering [ ] ,
172+ restrictions : Restriction [ ] ,
174173) {
175- return filterValidOfferings (
176- offerings ,
177- ( x ) => isValidOffering ( x , restrictions ) ,
174+ return filterValidOfferings ( offerings , ( x ) =>
175+ isValidOffering ( x , restrictions ) ,
178176 ) ;
179177}
180178
@@ -184,25 +182,25 @@ export async function categorizeValidOfferings(offerings: OfferingList[]) {
184182 for ( const offering of offerings ) {
185183 const lectures : CategorizedOfferingList = {
186184 course_id : offering . course_id ,
187- category : ' LEC' ,
188- offerings : [ ]
185+ category : " LEC" ,
186+ offerings : [ ] ,
189187 } ;
190188 const tutorials : CategorizedOfferingList = {
191189 course_id : offering . course_id ,
192- category : ' TUT' ,
193- offerings : [ ]
190+ category : " TUT" ,
191+ offerings : [ ] ,
194192 } ;
195193 const practicals : CategorizedOfferingList = {
196194 course_id : offering . course_id ,
197- category : ' PRA' ,
198- offerings : [ ]
199- }
195+ category : " PRA" ,
196+ offerings : [ ] ,
197+ } ;
200198
201199 for ( const entry of offering . offerings ) {
202200 const meeting_section = entry . meeting_section ;
203- if ( meeting_section . startsWith ( ' PRA' ) ) {
201+ if ( meeting_section . startsWith ( " PRA" ) ) {
204202 practicals . offerings . push ( entry ) ;
205- } else if ( meeting_section . startsWith ( ' TUT' ) ) {
203+ } else if ( meeting_section . startsWith ( " TUT" ) ) {
206204 tutorials . offerings . push ( entry ) ;
207205 } else {
208206 lectures . offerings . push ( entry ) ;
@@ -224,12 +222,12 @@ export async function canInsert(toInsert: Offering, curList: Offering[]) {
224222 for ( const offering of curList ) {
225223 if ( offering . day == toInsert . day ) {
226224 if ( offering . start < toInsert . end && toInsert . start < offering . end ) {
227- return false ; // Check if the time overlaps
225+ return false ; // Check if the time overlaps
228226 }
229227 }
230228 }
231229
232- return true ; // No conflict found
230+ return true ; // No conflict found
233231}
234232
235233// Function to generate a frequency table of days from a list of offerings
@@ -245,12 +243,12 @@ export function getFrequencyTable(arr: Offering[]): Map<string, number> {
245243
246244// Function to generate all valid schedules based on offerings and restrictions
247245export async function getValidSchedules (
248- validSchedules : Offering [ ] [ ] ,
249- courseOfferingsList : CategorizedOfferingList [ ] ,
250- curList : Offering [ ] ,
251- cur : number ,
252- len : number ,
253- maxdays : number ,
246+ validSchedules : Offering [ ] [ ] ,
247+ courseOfferingsList : CategorizedOfferingList [ ] ,
248+ curList : Offering [ ] ,
249+ cur : number ,
250+ len : number ,
251+ maxdays : number ,
254252) {
255253 // Base case: if all courses have been considered
256254 if ( cur == len ) {
@@ -259,7 +257,7 @@ export async function getValidSchedules(
259257 // If the number of unique days is within the allowed limit, add the current
260258 // schedule to the list
261259 if ( freq . size <= maxdays ) {
262- validSchedules . push ( [ ...curList ] ) ; // Push a copy of the current list
260+ validSchedules . push ( [ ...curList ] ) ; // Push a copy of the current list
263261 }
264262 return ;
265263 }
@@ -269,16 +267,16 @@ export async function getValidSchedules(
269267 // Recursively attempt to add offerings for the current course
270268 for ( const offering of offeringsForCourse . offerings ) {
271269 if ( await canInsert ( offering , curList ) ) {
272- curList . push ( offering ) ; // Add offering to the current list
270+ curList . push ( offering ) ; // Add offering to the current list
273271
274272 // Recursively generate schedules for the next course
275273 await getValidSchedules (
276- validSchedules ,
277- courseOfferingsList ,
278- curList ,
279- cur + 1 ,
280- len ,
281- maxdays ,
274+ validSchedules ,
275+ courseOfferingsList ,
276+ curList ,
277+ cur + 1 ,
278+ len ,
279+ maxdays ,
282280 ) ;
283281
284282 // Backtrack: remove the last offering if no valid schedule was found
@@ -292,22 +290,22 @@ export default {
292290 generateTimetable : asyncHandler ( async ( req : Request , res : Response ) => {
293291 try {
294292 // Extract event details and course information from the request
295- const { name, date, semester, search, courses, restrictions} = req . body ;
293+ const { name, date, semester, search, courses, restrictions } = req . body ;
296294 const courseOfferingsList : OfferingList [ ] = [ ] ;
297295 const validCourseOfferingsList : OfferingList [ ] = [ ] ;
298296 const maxdays = await getMaxDays ( restrictions ) ;
299297
300298 // Fetch offerings for each course
301299 for ( const course of courses ) {
302- const { id } = course ;
300+ const { id } = course ;
303301 courseOfferingsList . push ( {
304302 course_id : id ,
305303 offerings : ( await getOfferings ( id , semester ) ) ?? [ ] ,
306304 } ) ;
307305 }
308306
309307 // Filter out invalid offerings based on the restrictions
310- for ( const { course_id, offerings} of courseOfferingsList ) {
308+ for ( const { course_id, offerings } of courseOfferingsList ) {
311309 validCourseOfferingsList . push ( {
312310 course_id : course_id ,
313311 offerings : await getValidOfferings ( offerings ?? [ ] , restrictions ) ,
@@ -319,36 +317,36 @@ export default {
319317 (course) => console.log(JSON.stringify(course, null, 2)),
320318 );*/
321319
322- const categorizedOfferings =
323- await categorizeValidOfferings ( validCourseOfferingsList ) ;
320+ const categorizedOfferings = await categorizeValidOfferings (
321+ validCourseOfferingsList ,
322+ ) ;
324323 // console.log(typeof categorizedOfferings);
325324 // console.log(JSON.stringify(categorizedOfferings, null, 2));
326325
327-
328326 const validSchedules : Offering [ ] [ ] = [ ] ;
329327
330328 // Generate valid schedules for the given courses and restrictions
331329 await getValidSchedules (
332- validSchedules ,
333- categorizedOfferings ,
334- [ ] ,
335- 0 ,
336- categorizedOfferings . length ,
337- maxdays ,
330+ validSchedules ,
331+ categorizedOfferings ,
332+ [ ] ,
333+ 0 ,
334+ categorizedOfferings . length ,
335+ maxdays ,
338336 ) ;
339337
340338 // Return error if no valid schedules are found
341339 if ( validSchedules . length === 0 ) {
342- return res . status ( 404 ) . json ( { error : ' No valid schedules found.' } ) ;
340+ return res . status ( 404 ) . json ( { error : " No valid schedules found." } ) ;
343341 }
344342
345343 // Return the valid schedules
346- return res . status ( 200 ) . json ( { validSchedules} ) ;
344+ return res . status ( 200 ) . json ( { validSchedules } ) ;
347345 } catch ( error ) {
348346 // Catch any error and return the error message
349347 const errorMessage =
350- error instanceof Error ? error . message : ' An unknown error occurred' ;
351- return res . status ( 500 ) . send ( { error : errorMessage } ) ;
348+ error instanceof Error ? error . message : " An unknown error occurred" ;
349+ return res . status ( 500 ) . send ( { error : errorMessage } ) ;
352350 }
353351 } ) ,
354352} ;
0 commit comments