-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add course availability by session (#49)
* Refactor CoursePrerequisite model and migrate unstructuredPrerequisite column to ProgramCourse * Make credits column nullable in Program model * Refactor logging missing programs and courses * Add pdf parsable flags to Program model & create a seeder for all parsable programs * create worker to get parsed horaire pdf data * quick cleanup & add endpoint * refactor variable name (CoursePrerequisite to Prerequisite) * wip adding prerequisites * add unstructured prerequisites * add logging rules for worker thread * cleanup * add metrics & enforce logging rules * move prereq logic to service * add unit tests for session utils * doc jobs process * refactor prerequisite * refactor prerequisite * run seeder on prerequisite job * change session and courseInstance model to use combined p_key * add availability column to CourseInstance model * wip availability and update programs seeding logic to run on jobs * wip wip 🚔 * change availability field to an array in CourseInstance model and update related logic * refactor course instance to delete/update old availabilities * enhance error handling & add course prerequisite endpoint * fix * nullish
- Loading branch information
Showing
25 changed files
with
797 additions
and
80 deletions.
There are no files selected for viewing
42 changes: 42 additions & 0 deletions
42
...rations/20241123062121_update_session_and_course_instance_table_primary_key/migration.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/* | ||
Warnings: | ||
- The primary key for the `CourseInstance` table will be changed. If it partially fails, the table could be left without primary key constraint. | ||
- You are about to drop the column `id` on the `CourseInstance` table. All the data in the column will be lost. | ||
- You are about to drop the column `sessionId` on the `CourseInstance` table. All the data in the column will be lost. | ||
- The primary key for the `Session` table will be changed. If it partially fails, the table could be left without primary key constraint. | ||
- You are about to drop the column `id` on the `Session` table. All the data in the column will be lost. | ||
- Added the required column `sessionTrimester` to the `CourseInstance` table without a default value. This is not possible if the table is not empty. | ||
- Added the required column `sessionYear` to the `CourseInstance` table without a default value. This is not possible if the table is not empty. | ||
*/ | ||
-- DropForeignKey | ||
ALTER TABLE "CourseInstance" DROP CONSTRAINT "CourseInstance_sessionId_fkey"; | ||
|
||
-- DropIndex | ||
DROP INDEX "CourseInstance_courseId_sessionId_idx"; | ||
|
||
-- DropIndex | ||
DROP INDEX "CourseInstance_courseId_sessionId_key"; | ||
|
||
-- DropIndex | ||
DROP INDEX "Session_year_trimester_key"; | ||
|
||
-- AlterTable | ||
ALTER TABLE "CourseInstance" DROP CONSTRAINT "CourseInstance_pkey", | ||
DROP COLUMN "id", | ||
DROP COLUMN "sessionId", | ||
ADD COLUMN "sessionTrimester" "Trimester" NOT NULL, | ||
ADD COLUMN "sessionYear" INTEGER NOT NULL, | ||
ADD CONSTRAINT "CourseInstance_pkey" PRIMARY KEY ("courseId", "sessionYear", "sessionTrimester"); | ||
|
||
-- AlterTable | ||
ALTER TABLE "Session" DROP CONSTRAINT "Session_pkey", | ||
DROP COLUMN "id", | ||
ADD CONSTRAINT "Session_pkey" PRIMARY KEY ("year", "trimester"); | ||
|
||
-- CreateIndex | ||
CREATE INDEX "CourseInstance_courseId_sessionYear_sessionTrimester_idx" ON "CourseInstance"("courseId", "sessionYear", "sessionTrimester"); | ||
|
||
-- AddForeignKey | ||
ALTER TABLE "CourseInstance" ADD CONSTRAINT "CourseInstance_sessionYear_sessionTrimester_fkey" FOREIGN KEY ("sessionYear", "sessionTrimester") REFERENCES "Session"("year", "trimester") ON DELETE RESTRICT ON UPDATE CASCADE; |
11 changes: 11 additions & 0 deletions
11
prisma/migrations/20241123063023_add_availability_to_course_instance/migration.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/* | ||
Warnings: | ||
- Added the required column `availability` to the `CourseInstance` table without a default value. This is not possible if the table is not empty. | ||
*/ | ||
-- CreateEnum | ||
CREATE TYPE "Availability" AS ENUM ('JOUR', 'SOIR', 'INTENSIF'); | ||
|
||
-- AlterTable | ||
ALTER TABLE "CourseInstance" ADD COLUMN "availability" "Availability" NOT NULL; |
11 changes: 11 additions & 0 deletions
11
prisma/migrations/20241125080118_change_availability_to_array/migration.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/* | ||
Warnings: | ||
- Changed the column `availability` on the `CourseInstance` table from a scalar field to a list field. If there are non-null values in that column, this step will fail. | ||
*/ | ||
-- Drop the existing column | ||
ALTER TABLE "CourseInstance" DROP COLUMN "availability"; | ||
|
||
-- Add the new column as an array of enums | ||
ALTER TABLE "CourseInstance" ADD COLUMN "availability" "Availability"[] NOT NULL DEFAULT '{}'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { Availability } from '@prisma/client'; | ||
|
||
export class AvailabilityUtil { | ||
public static parseAvailability( | ||
availabilityCode: string, | ||
): Availability[] | null { | ||
const availabilityMap: Record<string, Availability> = { | ||
J: Availability.JOUR, | ||
S: Availability.SOIR, | ||
I: Availability.INTENSIF, | ||
}; | ||
|
||
const availabilities: Availability[] = []; | ||
|
||
for (const char of availabilityCode.toUpperCase()) { | ||
const availability = availabilityMap[char]; | ||
if (availability) { | ||
// Prevent duplicates if the same code appears multiple times | ||
if (!availabilities.includes(availability)) { | ||
availabilities.push(availability); | ||
} | ||
} else { | ||
// Invalid availability code detected | ||
return null; | ||
} | ||
} | ||
|
||
return availabilities; | ||
} | ||
|
||
// Compares two arrays of Availability enums for equality, ignoring order. | ||
public static areAvailabilitiesEqual( | ||
a: Availability[], | ||
b: Availability[], | ||
): boolean { | ||
if (a.length !== b.length) return false; | ||
|
||
const frequencyMapA = AvailabilityUtil.buildFrequencyMap(a); | ||
const frequencyMapB = AvailabilityUtil.buildFrequencyMap(b); | ||
|
||
for (const [availability, count] of frequencyMapA.entries()) { | ||
if (frequencyMapB.get(availability) !== count) { | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
// Builds a frequency map of the Availability enums | ||
private static buildFrequencyMap( | ||
availabilities: Availability[], | ||
): Map<Availability, number> { | ||
const frequencyMap = new Map<Availability, number>(); | ||
for (const availability of availabilities) { | ||
frequencyMap.set(availability, (frequencyMap.get(availability) ?? 0) + 1); | ||
} | ||
return frequencyMap; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.