diff --git a/src/db-access/applications.ts b/src/db-access/applications.ts index 328a731..9d834c7 100644 --- a/src/db-access/applications.ts +++ b/src/db-access/applications.ts @@ -1,6 +1,7 @@ import { database } from "@/db/setup/query-postgres"; import { applicationsTable, + assistantApplicationsTable, teamApplicationsTable, } from "@/db/tables/applications"; import { type OrmResult, ormError } from "@/src/error/orm-error"; @@ -12,10 +13,12 @@ import type { import type { QueryParameters } from "@/src/request-handling/common"; import type { ApplicationKey, + AssistantApplication, TeamApplication, TeamKey, } from "@/src/response-handling/applications"; import { and, eq, inArray } from "drizzle-orm"; +import type { SemesterKey } from "../response-handling/semesters"; import { newDatabaseTransaction } from "./common"; export const selectTeamApplications = async ( @@ -127,6 +130,73 @@ export const selectTeamApplicationsById = async ( }); }; +export const selectTeamApplicationsBySemester = async ( + semesterId: SemesterKey[], + parameters: QueryParameters, +): Promise> => { + return await newDatabaseTransaction(database, async (tx) => { + const selectResult = await tx + .select({ + id: teamApplicationsTable.id, + applicationParentId: teamApplicationsTable.applicationParentId, + teamId: teamApplicationsTable.teamId, + firstName: applicationsTable.firstName, + lastName: applicationsTable.lastName, + gender: applicationsTable.gender, + email: applicationsTable.email, + fieldOfStudyId: applicationsTable.fieldOfStudyId, + yearOfStudy: applicationsTable.yearOfStudy, + phonenumber: applicationsTable.phonenumber, + motivationText: teamApplicationsTable.motivationText, + biography: teamApplicationsTable.biography, + teamInterest: teamApplicationsTable.teamInterest, + semester: applicationsTable.semester, + submitDate: applicationsTable.submitDate, + }) + .from(teamApplicationsTable) + .where(inArray(applicationsTable.semester, semesterId)) + .innerJoin( + applicationsTable, + eq(teamApplicationsTable.applicationParentId, applicationsTable.id), + ) + .limit(parameters.limit) + .offset(parameters.offset); + + return selectResult; + }); +}; + +export const selectAssistantApplicationsBySemester = async ( + semesterId: SemesterKey[], + parameters: QueryParameters, +): Promise> => { + return await newDatabaseTransaction(database, async (tx) => { + const selectResult = await tx + .select({ + id: assistantApplicationsTable.id, + firstName: applicationsTable.firstName, + lastName: applicationsTable.lastName, + gender: applicationsTable.gender, + email: applicationsTable.email, + fieldOfStudyId: applicationsTable.fieldOfStudyId, + yearOfStudy: applicationsTable.yearOfStudy, + phonenumber: applicationsTable.phonenumber, + semester: applicationsTable.semester, + submitDate: applicationsTable.submitDate, + }) + .from(assistantApplicationsTable) + .where(inArray(applicationsTable.semester, semesterId)) + .innerJoin( + applicationsTable, + eq(assistantApplicationsTable.id, applicationsTable.id), + ) + .limit(parameters.limit) + .offset(parameters.offset); + + return selectResult; + }); +}; + export async function insertTeamApplication( teamApplication: NewTeamApplication & NewApplication, ): Promise> { diff --git a/src/main.ts b/src/main.ts index 8541087..6c11fc8 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,7 +8,10 @@ import { zodErrorHandler, } from "@/src/middleware/error-middleware"; import { logger } from "@/src/middleware/logging-middleware"; -import { teamApplicationRouter } from "@/src/routers/applications"; +import { + assistantApplicationRouter, + teamApplicationRouter, +} from "@/src/routers/applications"; import { expensesRouter } from "@/src/routers/expenses"; import { sponsorsRouter } from "@/src/routers/sponsors"; import { teamsRouter } from "@/src/routers/teams"; @@ -37,6 +40,9 @@ api.use("/sponsors", sponsorsRouter); api.use("/users", usersRouter); api.use("/teamapplications", teamApplicationRouter); + +api.use("/assistantapplications", assistantApplicationRouter); + api.use("/teams", teamsRouter); // Error handling diff --git a/src/response-handling/applications.ts b/src/response-handling/applications.ts index 517a677..9049932 100644 --- a/src/response-handling/applications.ts +++ b/src/response-handling/applications.ts @@ -3,6 +3,7 @@ import type { z } from "zod"; import { applicationsTable, + assistantApplicationsTable, teamApplicationsTable, } from "@/db/tables/applications"; @@ -26,3 +27,13 @@ export type TeamApplicationKey = { applicationParentId: TeamApplication["applicationParentId"]; }; export type TeamKey = TeamApplication["teamId"]; + +export const assistantApplicationSelectSchema = createSelectSchema( + assistantApplicationsTable, +) + .merge(createSelectSchema(applicationsTable)) + .strict() + .readonly(); +export type AssistantApplication = z.infer< + typeof assistantApplicationSelectSchema +>; diff --git a/src/routers/applications.ts b/src/routers/applications.ts index e517927..e883343 100644 --- a/src/routers/applications.ts +++ b/src/routers/applications.ts @@ -1,7 +1,9 @@ import { createTeamApplicationFromAssistantApplication, insertTeamApplication, + selectAssistantApplicationsBySemester, selectTeamApplications, + selectTeamApplicationsBySemester, selectTeamApplicationsByTeamId, } from "@/src/db-access/applications"; import { clientError } from "@/src/error/http-errors"; @@ -16,8 +18,10 @@ import { import { Router, json } from "express"; export const teamApplicationRouter = Router(); +export const assistantApplicationRouter = Router(); teamApplicationRouter.use(json()); +assistantApplicationRouter.use(json()); /** * @openapi @@ -104,6 +108,103 @@ teamApplicationRouter.get("/:teamID/", async (req, res, next) => { res.json(databaseResult.data); }); +/** + * @openapi + * /teamapplications/semester/{semesterID}/: + * get: + * tags: [teamapplications] + * summary: Get teamapplications with semesterid + * description: Get teamapplications with semesterid + * parameters: + * - $ref: "#/components/parameters/offset" + * - $ref: "#/components/parameters/limit" + * responses: + * 200: + * description: Successfull response + * content: + * application/json: + * schema: + * $ref: "#/components/schemas/teamApplication" + */ +teamApplicationRouter.get("/semester/:semesterID/", async (req, res, next) => { + const semesterIdResult = toSerialIdParser.safeParse(req.params.semesterID); + if (!semesterIdResult.success) { + return next( + clientError(400, "Invalid request format", semesterIdResult.error), + ); + } + const queryParametersResult = toListQueryParser.safeParse(req.query); + if (!queryParametersResult.success) { + return next( + clientError(400, "Invalid request format", queryParametersResult.error), + ); + } + const databaseResult = await selectTeamApplicationsBySemester( + [semesterIdResult.data], + queryParametersResult.data, + ); + if (!databaseResult.success) { + return next( + clientError( + 400, + "Failed to retrieve data from the database", + databaseResult.error, + ), + ); + } + res.json(databaseResult.data); +}); + +/** + * @openapi + * /assistantapplications/semester/{semesterId}/: + * get: + * tags: [assistantapplications] + * summary: Get assistantapplications with semesterid + * description: Get assistantapplications with semesterid + * parameters: + * - $ref: "#/components/parameters/offset" + * - $ref: "#/components/parameters/limit" + * responses: + * 200: + * description: Successfull response + * content: + * application/json: + * schema: + * $ref: "#/components/schemas/assistantApplication" + */ +assistantApplicationRouter.get( + "/semester/:semesterID/", + async (req, res, next) => { + const semesterIdResult = toSerialIdParser.safeParse(req.params.semesterID); + if (!semesterIdResult.success) { + return next( + clientError(400, "Invalid request format", semesterIdResult.error), + ); + } + const queryParametersResult = toListQueryParser.safeParse(req.query); + if (!queryParametersResult.success) { + return next( + clientError(400, "Invalid request format", queryParametersResult.error), + ); + } + const databaseResult = await selectAssistantApplicationsBySemester( + [semesterIdResult.data], + queryParametersResult.data, + ); + if (!databaseResult.success) { + return next( + clientError( + 400, + "Failed to retrieve data from the database", + databaseResult.error, + ), + ); + } + res.json(databaseResult.data); + }, +); + /** * @openapi * /teamapplications/: