diff --git a/openapi/config.ts b/openapi/config.ts index 3ee5199..e78bdea 100644 --- a/openapi/config.ts +++ b/openapi/config.ts @@ -20,6 +20,7 @@ import { teamApplicationSelectSchema } from "@/src/response-handling/application import { expensesSelectSchema } from "@/src/response-handling/expenses"; import { sponsorsSelectSchema } from "@/src/response-handling/sponsors"; +import { teamsRequestParser } from "@/src/request-handling/teams"; import { assistantUserSelectSchema, teamUserSelectSchema, @@ -84,6 +85,7 @@ const openapiDocument = createDocument({ datePeriod: datePeriodParser, teamApplication: teamApplicationSelectSchema, teamApplicationRequest: teamApplicationParser, + teams: teamsRequestParser, }, parameters: { id: serialIdParser.openapi({ param: { in: "path", name: "id" } }), diff --git a/src/db-access/teams.ts b/src/db-access/teams.ts index 8990d1c..3ce46a8 100644 --- a/src/db-access/teams.ts +++ b/src/db-access/teams.ts @@ -35,3 +35,17 @@ export const selectActiveTeams = async ( return teams; }); }; +export const selectInActiveTeams = async ( + parameters: QueryParameters, +): Promise> => { + return await newDatabaseTransaction(database, async (tx) => { + const teams = await tx + .select() + .from(teamsTable) + .where(eq(teamsTable.active, false)) + .limit(parameters.limit) + .offset(parameters.offset); + + return teams; + }); +}; diff --git a/src/request-handling/teams.ts b/src/request-handling/teams.ts new file mode 100644 index 0000000..2406a94 --- /dev/null +++ b/src/request-handling/teams.ts @@ -0,0 +1,31 @@ +import { expensesTable } from "@/db/tables/expenses"; +import { timeStringParser } from "@/lib/time-parsers"; +import { serialIdParser } from "@/src/request-handling/common"; +import { createInsertSchema } from "drizzle-zod"; +import { z } from "zod"; + +export const teamsRequestParser = z + .object({ + departmentId: serialIdParser.describe("Id of corresponding department"), + name: z.string().min(1).describe("Name of team"), + email: z.string().email().describe("Email of team"), + description: z.string().min(1).describe("Description of team"), + shortDescription: z.string().min(1).describe("Short description of team"), + acceptApplication: z + .boolean() + .describe("Whether the team is accepting applications or not"), + active: z.boolean().describe("Whether the team is active or not"), + deadline: timeStringParser.describe("Deadline for applying to the team"), + }) + .strict(); + +export const teamsRequestToInsertParser = teamsRequestParser + .extend({ + name: teamsRequestParser.shape.name.trim(), + email: teamsRequestParser.shape.email.trim().toLowerCase(), + description: teamsRequestParser.shape.description.trim(), + shortDescription: teamsRequestParser.shape.shortDescription.trim(), + }) + .pipe(createInsertSchema(expensesTable).strict().readonly()); + +export type NewTeam = z.infer; diff --git a/src/routers/teams.ts b/src/routers/teams.ts index e1ca51f..6f3127c 100644 --- a/src/routers/teams.ts +++ b/src/routers/teams.ts @@ -1,4 +1,8 @@ -import { selectActiveTeams, selectTeamsById } from "@/src/db-access/teams"; +import { + selectActiveTeams, + selectInActiveTeams, + selectTeamsById, +} from "@/src/db-access/teams"; import { clientError } from "@/src/error/http-errors"; import { listQueryParser, @@ -48,6 +52,42 @@ teamsRouter.get("/active", async (req, res, next) => { } res.json(results.data); }); + +/** + * @openapi + * /teams/inactive/: + * get: + * tags: [teams] + * summary: Get all inactive teams + * description: Return all inactive teams + * parameters: + * - $ref: "#/components/parameters/offset" + * - $ref: "#/components/parameters/limit" + * responses: + * 200: + * description: Successfull response + * content: + * application/json: + * schema: + * $ref: "#/components/schemas/teams" + */ +teamsRouter.get("/inactive", async (req, res, next) => { + const queryParametersResult = toListQueryParser.safeParse(req.query); + if (!queryParametersResult.success) { + return next( + clientError(400, "Invalid request format", queryParametersResult.error), + ); + } + + const results = await selectInActiveTeams(queryParametersResult.data); + if (!results.success) { + return next( + clientError(400, "Invalid request format", queryParametersResult.error), + ); + } + res.json(results.data); +}); + /** * @openapi * /teams/{teamId}/: