diff --git a/server/src/router/v1/club.ts b/server/src/router/v1/club.ts index 8315335..5e06a59 100644 --- a/server/src/router/v1/club.ts +++ b/server/src/router/v1/club.ts @@ -1,37 +1,41 @@ -import { OpenAPIHono, createRoute } from "@hono/zod-openapi"; -import { z } from "zod"; -import * as HttpStatusCodes from "stoker/http-status-codes"; - -import type { Context } from "@/lib/context"; -import { db } from "@/db/db"; -import { clubLinks, landingSpotlights } from "@/db/schema"; -import type { ClubLink, LandingSpotlight } from "@/db/schema"; -import { clubLinkSchema, landingSpotlightSchema } from "@/util/zod"; -import { eq } from "drizzle-orm"; +import { OpenAPIHono, createRoute } from '@hono/zod-openapi'; +import { z } from 'zod'; +import * as HttpStatusCodes from 'stoker/http-status-codes'; + +import type { Context } from '@/lib/context'; +import { db } from '@/db/db'; +import { clubLinks, landingQuestions, landingSpotlights } from '@/db/schema'; +import type { ClubLink, LandingQuestion, LandingSpotlight } from '@/db/schema'; +import { + clubLinkSchema, + landingQuestionSchema, + landingSpotlightSchema, +} from '@/util/zod'; +import { eq } from 'drizzle-orm'; import { authMiddleWare, forbiddenRequest, unauthorizedRequest, -} from "@/middlewares/auth-middleware"; +} from '@/middlewares/auth-middleware'; const clubRouter = new OpenAPIHono(); clubRouter.openapi( createRoute({ - method: "get", - path: "/links", - tags: ["club"], - summary: "List all club links", + method: 'get', + path: '/links', + tags: ['club'], + summary: 'List all club links', responses: { [HttpStatusCodes.OK]: { content: { - "application/json": { + 'application/json': { schema: z.object({ links: clubLinkSchema, }), }, }, - description: "Successful response", + description: 'Successful response', }, }, }), @@ -43,15 +47,15 @@ clubRouter.openapi( clubRouter.openapi( createRoute({ - method: "put", - path: "/links", - tags: ["club"], - summary: "Update club link", - middleware: [authMiddleWare("admin")], + method: 'put', + path: '/links', + tags: ['club'], + summary: 'Update club link', + middleware: [authMiddleWare('admin')], request: { body: { content: { - "application/json": { + 'application/json': { schema: clubLinkSchema.omit({ id: true }), }, }, @@ -59,56 +63,56 @@ clubRouter.openapi( }, responses: { [HttpStatusCodes.NO_CONTENT]: { - description: "No content", + description: 'No content', }, [HttpStatusCodes.CONFLICT]: { content: { - "application/json": { + 'application/json': { schema: z.object({ error: z.string(), }), }, }, - description: "Conflict", + description: 'Conflict', }, ...unauthorizedRequest, ...forbiddenRequest, }, }), async (c) => { - const param = c.req.valid("json"); + const body = c.req.valid('json'); const newMajor = await db .update(clubLinks) - .set(param) + .set(body) .where(eq(clubLinks.id, 1)) .returning(); if (newMajor.length === 0) { return c.json( - { error: "Club link not updated" }, + { error: 'Club link not updated' }, HttpStatusCodes.CONFLICT, ); } - return c.text("", HttpStatusCodes.NO_CONTENT); + return c.text('', HttpStatusCodes.NO_CONTENT); }, ); clubRouter.openapi( createRoute({ - method: "get", - path: "/spotlights", - tags: ["club"], - summary: "List all spotlights", + method: 'get', + path: '/spotlights', + tags: ['club'], + summary: 'List all spotlights', responses: { [HttpStatusCodes.OK]: { content: { - "application/json": { + 'application/json': { schema: z.object({ spotlights: z.array(landingSpotlightSchema), }), }, }, - description: "Successful response", + description: 'Successful response', }, }, }), @@ -122,15 +126,15 @@ clubRouter.openapi( clubRouter.openapi( createRoute({ - method: "post", - path: "/spotlights", - tags: ["club"], - summary: "Update club spotlight", - middleware: [authMiddleWare("admin")], + method: 'post', + path: '/spotlights', + tags: ['club'], + summary: 'Create club spotlight', + middleware: [authMiddleWare('admin')], request: { body: { content: { - "application/json": { + 'application/json': { schema: landingSpotlightSchema.omit({ id: true }), }, }, @@ -139,35 +143,38 @@ clubRouter.openapi( responses: { [HttpStatusCodes.CREATED]: { content: { - "application/json": { + 'application/json': { schema: z.object({ spotlight: landingSpotlightSchema, }), }, }, - description: "Create spotlight", + description: 'Create spotlight', }, [HttpStatusCodes.CONFLICT]: { content: { - "application/json": { + 'application/json': { schema: z.object({ error: z.string(), }), }, }, - description: "Conflict", + description: 'Conflict', }, ...unauthorizedRequest, ...forbiddenRequest, }, }), async (c) => { - const param = c.req.valid("json"); + const body = c.req.valid('json'); - const newSpotlight = await db.insert(landingSpotlights).values(param).returning(); + const newSpotlight = await db + .insert(landingSpotlights) + .values(body) + .returning(); if (newSpotlight.length === 0) { return c.json( - { error: "Spotlight not created" }, + { error: 'Spotlight not created' }, HttpStatusCodes.CONFLICT, ); } @@ -177,18 +184,18 @@ clubRouter.openapi( clubRouter.openapi( createRoute({ - method: "put", - path: "/spotlights/{spotlightID}", - tags: ["club"], - summary: "Update club spotlight", - middleware: [authMiddleWare("admin")], + method: 'put', + path: '/spotlights/{spotlightID}', + tags: ['club'], + summary: 'Update club spotlight', + middleware: [authMiddleWare('admin')], request: { params: z.object({ spotlightID: z.string(), }), body: { content: { - "application/json": { + 'application/json': { schema: landingSpotlightSchema.omit({ id: true }), }, }, @@ -196,38 +203,179 @@ clubRouter.openapi( }, responses: { [HttpStatusCodes.NO_CONTENT]: { - description: "No content", + description: 'No content', }, [HttpStatusCodes.CONFLICT]: { content: { - "application/json": { + 'application/json': { schema: z.object({ error: z.string(), }), }, }, - description: "Conflict", + description: 'Conflict', }, ...unauthorizedRequest, ...forbiddenRequest, }, }), async (c) => { - const { spotlightID } = c.req.valid("param"); - const param = c.req.valid("json"); + const { spotlightID } = c.req.valid('param'); + const body = c.req.valid('json'); const newSpotlight = await db .update(landingSpotlights) - .set(param) + .set(body) .where(eq(landingSpotlights.id, parseInt(spotlightID))) .returning(); if (newSpotlight.length === 0) { return c.json( - { error: "Spotlight not updated" }, + { error: 'Spotlight not updated' }, + HttpStatusCodes.CONFLICT, + ); + } + return c.text('', HttpStatusCodes.NO_CONTENT); + }, +); + +clubRouter.openapi( + createRoute({ + method: 'get', + path: '/questions', + tags: ['club'], + summary: 'List all questions', + responses: { + [HttpStatusCodes.OK]: { + content: { + 'application/json': { + schema: z.object({ + questions: z.array(landingQuestionSchema), + }), + }, + }, + description: 'Successful response', + }, + }, + }), + async (c) => { + const questions: LandingQuestion[] = await db + .select() + .from(landingQuestions); + return c.json({ questions }, HttpStatusCodes.OK); + }, +); + +clubRouter.openapi( + createRoute({ + method: 'post', + path: '/questions', + tags: ['club'], + summary: 'Create club question', + middleware: [authMiddleWare('admin')], + request: { + body: { + content: { + 'application/json': { + schema: landingQuestionSchema.omit({ id: true }), + }, + }, + }, + }, + responses: { + [HttpStatusCodes.CREATED]: { + content: { + 'application/json': { + schema: z.object({ + question: landingQuestionSchema, + }), + }, + }, + description: 'Create question', + }, + [HttpStatusCodes.CONFLICT]: { + content: { + 'application/json': { + schema: z.object({ + error: z.string(), + }), + }, + }, + description: 'Conflict', + }, + ...unauthorizedRequest, + ...forbiddenRequest, + }, + }), + async (c) => { + const body = c.req.valid('json'); + + const newQuestion = await db + .insert(landingQuestions) + .values(body) + .returning(); + if (newQuestion.length === 0) { + return c.json( + { error: 'Question not created' }, + HttpStatusCodes.CONFLICT, + ); + } + return c.json({ question: newQuestion[0] }, HttpStatusCodes.CREATED); + }, +); + +clubRouter.openapi( + createRoute({ + method: 'put', + path: '/questions/{questionID}', + tags: ['club'], + summary: 'Update club question', + middleware: [authMiddleWare('admin')], + request: { + params: z.object({ + questionID: z.string(), + }), + body: { + content: { + 'application/json': { + schema: landingQuestionSchema.omit({ id: true }), + }, + }, + }, + }, + responses: { + [HttpStatusCodes.NO_CONTENT]: { + description: 'No content', + }, + [HttpStatusCodes.CONFLICT]: { + content: { + 'application/json': { + schema: z.object({ + error: z.string(), + }), + }, + }, + description: 'Conflict', + }, + ...unauthorizedRequest, + ...forbiddenRequest, + }, + }), + async (c) => { + const { questionID } = c.req.valid('param'); + const body = c.req.valid('json'); + + const newQuestion = await db + .update(landingQuestions) + .set(body) + .where(eq(landingQuestions.id, parseInt(questionID))) + .returning(); + if (newQuestion.length === 0) { + return c.json( + { error: 'Question not updated' }, HttpStatusCodes.CONFLICT, ); } - return c.text("", HttpStatusCodes.NO_CONTENT); + return c.text('', HttpStatusCodes.NO_CONTENT); }, );