From 5860deb0e4a222d1464646b6564dc57f137975a4 Mon Sep 17 00:00:00 2001 From: Srejoye Date: Wed, 17 Jun 2026 19:24:38 +0530 Subject: [PATCH 1/4] fix(event): remove all ny casts, use typed authenticate and Prisma narrowing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace 3× equest.server as any / (app as any).authenticate preHandler boilerplate with pp.authenticate — already declared on FastifyInstance in src/types/fastify.d.ts, consistent with follow.ts / team.ts pattern - Replace 3× (request.user as any).id with equest.user.id — covered by the FastifyJWT augmentation (user: { id: string; username: string }) - Replace 2× catch (error: any) with catch (error: unknown) + instanceof Prisma.PrismaClientKnownRequestError narrowing before .code access (P2002 join-duplicate → 409, P2025 leave-not-found → 404) - Replace (error as Error).message with getErrorMessage(error) from the shared error utility already used in follow.ts / connect.ts - Update event.test.ts: construct Prisma error mocks with ew Prisma.PrismaClientKnownRequestError(...) so instanceof narrowing resolves correctly in tests; import Prisma alongside PrismaClient --- apps/backend/src/__tests__/event.test.ts | 13 +- apps/backend/src/routes/event.ts | 423 ++++++++++++----------- 2 files changed, 219 insertions(+), 217 deletions(-) diff --git a/apps/backend/src/__tests__/event.test.ts b/apps/backend/src/__tests__/event.test.ts index 44806af1..7ee75680 100644 --- a/apps/backend/src/__tests__/event.test.ts +++ b/apps/backend/src/__tests__/event.test.ts @@ -1,8 +1,9 @@ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import Fastify, { FastifyInstance } from 'fastify'; -import { PrismaClient } from '@prisma/client'; +import { PrismaClient, Prisma } from '@prisma/client'; import { eventRoutes } from '../routes/event'; + // ─── Shared mock data ──────────────────────────────────────────────────────── const MOCK_USER_ID = 'user-uuid-001'; @@ -355,9 +356,8 @@ describe('Events API', () => { it('409 — returns 409 when user already joined the event', async () => { prismaMock.event.findUnique.mockResolvedValue(MOCK_EVENT); // Prisma unique constraint error - const uniqueError = Object.assign(new Error('Unique constraint'), { - code: 'P2002', - }); + const uniqueError = new Prisma.PrismaClientKnownRequestError( + 'Unique constraint failed', { code: 'P2002', clientVersion: '6.0.0' }, ); prismaMock.eventAttendee.create.mockRejectedValue(uniqueError); const res = await app.inject({ @@ -440,9 +440,8 @@ describe('Events API', () => { it('404 — returns 404 when user was never an attendee (P2025)', async () => { prismaMock.event.findUnique.mockResolvedValue(MOCK_EVENT); // Prisma record-not-found error - const notFoundError = Object.assign(new Error('Record not found'), { - code: 'P2025', - }); + const notFoundError = new Prisma.PrismaClientKnownRequestError( + 'Record not found', { code: 'P2025', clientVersion: '6.0.0' }, ); prismaMock.eventAttendee.delete.mockRejectedValue(notFoundError); const res = await app.inject({ diff --git a/apps/backend/src/routes/event.ts b/apps/backend/src/routes/event.ts index 4d4ee2d9..d3d0d3e0 100644 --- a/apps/backend/src/routes/event.ts +++ b/apps/backend/src/routes/event.ts @@ -1,8 +1,8 @@ import type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify'; -import { createEventSchema, joinEventSchema} from '../validations/event.validation'; - -import {generateUniqueSlug} from '../utils/slug' - +import { Prisma } from '@prisma/client'; +import { createEventSchema, joinEventSchema } from '../validations/event.validation'; +import { generateUniqueSlug } from '../utils/slug'; +import { getErrorMessage } from '../utils/error.util'; type EventDetails = { id: string; @@ -15,8 +15,8 @@ type EventDetails = { startDate: Date; endDate: Date; createdAt: Date; - attendeesCount: number -} + attendeesCount: number; +}; type AttendeePublicProfile = { id: string; @@ -27,17 +27,16 @@ type AttendeePublicProfile = { company: string | null; avatarUrl: string | null; accentColor: string; -} - +}; type PaginatedAttendeesResponse = { attendees: AttendeePublicProfile[]; pagination: { page: number; limit: number; - total: number; + total: number; }; -} +}; type EventWithAttendees = { _count: { @@ -55,231 +54,235 @@ type EventWithAttendees = { accentColor: string; }; }[]; -} +}; -export async function eventRoutes(app:FastifyInstance) { - app.post('/', { preHandler: [async (request, reply) => { - const server = request.server as any; - if (typeof server?.authenticate === 'function') { await server.authenticate(request, reply); return } - if (typeof (app as any).authenticate === 'function') { await (app as any).authenticate(request, reply); return } - try { await request.jwtVerify() } catch (e) { reply.status(401).send({ error: 'Unauthorized' }) } - }] }, async (request: FastifyRequest<{ - Body: { - name: string, - description?: string, - startDate: string, - location: string, - endDate: string, - isPublic?: boolean - }}>, reply: FastifyReply) => { - const userId = (request.user as any).id; - const parsed = createEventSchema.safeParse(request.body); - if(!parsed.success){ - return reply.status(400).send({error: 'Bad request'}) - } - - const {name, description, startDate, endDate, isPublic ,location} = parsed.data +export async function eventRoutes(app: FastifyInstance) { + app.post( + '/', + { preHandler: [app.authenticate] }, + async ( + request: FastifyRequest<{ + Body: { + name: string; + description?: string; + startDate: string; + location: string; + endDate: string; + isPublic?: boolean; + }; + }>, + reply: FastifyReply, + ) => { + const userId = request.user.id; + const parsed = createEventSchema.safeParse(request.body); + if (!parsed.success) { + return reply.status(400).send({ error: 'Bad request' }); + } - let finalSlug = await generateUniqueSlug(name, async(slug) => { - const existing = await app.prisma.event.findUnique({where: {slug : slug}}) - - return !!existing - }) + const { name, description, startDate, endDate, isPublic, location } = parsed.data; - const startDateObj = new Date(startDate); - const endDateObj = new Date(endDate); + let finalSlug = await generateUniqueSlug(name, async (slug) => { + const existing = await app.prisma.event.findUnique({ where: { slug } }); + return !!existing; + }); - try { - const newEvent = await app.prisma.event.create({ - data: { - name, - description, - slug: finalSlug, - location: location, - startDate: startDateObj, - endDate: endDateObj, - isPublic: isPublic ?? true, - organizerId: userId - } - }) + const startDateObj = new Date(startDate); + const endDateObj = new Date(endDate); - return reply.status(201).send(newEvent); - } catch (error) { - app.log.error('Failed to create event'); - return reply.status(500).send({error: 'Failed to create event'}) - } - - }) + try { + const newEvent = await app.prisma.event.create({ + data: { + name, + description, + slug: finalSlug, + location, + startDate: startDateObj, + endDate: endDateObj, + isPublic: isPublic ?? true, + organizerId: userId, + }, + }); + return reply.status(201).send(newEvent); + } catch (error: unknown) { + app.log.error('Failed to create event'); + return reply.status(500).send({ error: 'Failed to create event' }); + } + }, + ); - //Returns event details and attendees count - app.get('/:slug', async(request: FastifyRequest<{Params: {slug: string}}>, reply: FastifyReply) => { - const paramsSlug = request.params.slug; - const details = await app.prisma.event.findUnique({ - where: { - slug: paramsSlug, - }, - include: { - _count: { - select: { - attendees: true - } + // Returns event details and attendees count + app.get( + '/:slug', + async ( + request: FastifyRequest<{ Params: { slug: string } }>, + reply: FastifyReply, + ) => { + const paramsSlug = request.params.slug; + const details = await app.prisma.event.findUnique({ + where: { slug: paramsSlug }, + include: { + _count: { select: { attendees: true } }, + organizer: { select: { username: true, displayName: true } }, }, - organizer: { - select: { - username: true, - displayName: true - } - } + }); + + if (!details) { + return reply.status(404).send({ error: 'Event not found' }); } - }) - if(!details){ - return reply.status(404).send({error: 'Event not found'}) - } - const response: EventDetails = { - id: details.id, - name: details.name, - slug: details.slug, - description: details.description, - location: details.location, - organizerUsername: details.organizer.username, - organizerDisplayName: details.organizer.displayName, - startDate: details.startDate, - endDate: details.endDate, - createdAt: details.createdAt, - attendeesCount: details._count.attendees - } - - return response; - }) + const response: EventDetails = { + id: details.id, + name: details.name, + slug: details.slug, + description: details.description, + location: details.location, + organizerUsername: details.organizer.username, + organizerDisplayName: details.organizer.displayName, + startDate: details.startDate, + endDate: details.endDate, + createdAt: details.createdAt, + attendeesCount: details._count.attendees, + }; - app.post('/:slug/join', { preHandler: [async (request, reply) => { const server = request.server as any; if (typeof server?.authenticate === 'function') { await server.authenticate(request, reply); return } if (typeof (app as any).authenticate === 'function') { await (app as any).authenticate(request, reply); return } try { await request.jwtVerify() } catch (e) { reply.status(401).send({ error: 'Unauthorized' }) } }] }, async(request: FastifyRequest<{Params: {slug: string}}>, reply: FastifyReply) => { - const userId = (request.user as any).id; - const paramsSlug = request.params.slug; + return response; + }, + ); - const event = await app.prisma.event.findUnique({ - where: { - slug: paramsSlug - } - }) + app.post( + '/:slug/join', + { preHandler: [app.authenticate] }, + async ( + request: FastifyRequest<{ Params: { slug: string } }>, + reply: FastifyReply, + ) => { + const userId = request.user.id; + const paramsSlug = request.params.slug; - if(!event){ - return reply.status(404).send({error: 'Event not found'}) - } + const event = await app.prisma.event.findUnique({ where: { slug: paramsSlug } }); + if (!event) { + return reply.status(404).send({ error: 'Event not found' }); + } - try { - await app.prisma.eventAttendee.create({ - data: { - eventId: event.id, - userId: userId, - joinedAt: new Date() + try { + await app.prisma.eventAttendee.create({ + data: { + eventId: event.id, + userId, + joinedAt: new Date(), + }, + }); + return reply.status(201).send({ message: 'User joined successfully' }); + } catch (error: unknown) { + if ( + error instanceof Prisma.PrismaClientKnownRequestError && + error.code === 'P2002' + ) { + return reply.status(409).send({ error: 'Already joined' }); } - }) - - return reply.status(201).send({message: 'User joined successfully'}) - } catch (error:any) { - if(error.code === "P2002" ){ - return reply.status(409).send({error: 'Already joined'}) + app.log.error(getErrorMessage(error)); + return reply.status(500).send({ error: 'Failed to join' }); } - app.log.error((error as Error).message); - return reply.status(500).send({error: 'Failed to join'}) - } + }, + ); - }) + app.delete( + '/:slug/leave', + { preHandler: [app.authenticate] }, + async ( + request: FastifyRequest<{ Params: { slug: string } }>, + reply: FastifyReply, + ) => { + const userId = request.user.id; + const paramsSlug = request.params.slug; - app.delete('/:slug/leave', { preHandler: [async (request, reply) => { const server = request.server as any; if (typeof server?.authenticate === 'function') { await server.authenticate(request, reply); return } if (typeof (app as any).authenticate === 'function') { await (app as any).authenticate(request, reply); return } try { await request.jwtVerify() } catch (e) { reply.status(401).send({ error: 'Unauthorized' }) } }] }, async(request: FastifyRequest<{Params: {slug: string}}>, reply: FastifyReply) => { - const userId = (request.user as any).id; - const paramsSlug = request.params.slug; - - const event = await app.prisma.event.findUnique({ - where: { - slug: paramsSlug + const event = await app.prisma.event.findUnique({ where: { slug: paramsSlug } }); + if (!event) { + return reply.status(404).send({ error: 'Event not found' }); } - }) - - if(!event){ - return reply.status(404).send({error: 'Event not found'}) - } - try { - await app.prisma.eventAttendee.delete({ - where: { - userId_eventId: { - userId: userId, - eventId: event.id - } + try { + await app.prisma.eventAttendee.delete({ + where: { + userId_eventId: { userId, eventId: event.id }, + }, + }); + return reply.status(204).send({ message: 'User left' }); + } catch (error: unknown) { + if ( + error instanceof Prisma.PrismaClientKnownRequestError && + error.code === 'P2025' + ) { + return reply.status(404).send({ error: 'User not found' }); } - }) - return reply.status(204).send({message: 'User left'}) - } catch (error:any) { - if(error.code === 'P2025'){ - return reply.status(404).send({error: 'User not found'}) + app.log.error(getErrorMessage(error)); + return reply.status(500).send({ error: 'Failed to leave' }); } - app.log.error((error as Error).message) - return reply.status(500).send({error: 'Failed to leave'}) - } - }) + }, + ); - app.get('/:slug/attendees', async(request: FastifyRequest<{Params: {slug: string}, Querystring: {page?:string; limit?: string}}>, reply: FastifyReply) => { - const paramsSlug = request.params.slug; - const page = Math.max(1, Number(request.query.page) || 1); - const limit = Math.min(50, Number(request.query.limit) || 10); - const skip = (page - 1) * limit - const event = await app.prisma.event.findUnique({ - where: { - slug: paramsSlug - }, - include: { - _count: { - select: { attendees: true } + app.get( + '/:slug/attendees', + async ( + request: FastifyRequest<{ + Params: { slug: string }; + Querystring: { page?: string; limit?: string }; + }>, + reply: FastifyReply, + ) => { + const paramsSlug = request.params.slug; + const page = Math.max(1, Number(request.query.page) || 1); + const limit = Math.min(50, Number(request.query.limit) || 10); + const skip = (page - 1) * limit; + + const event = (await app.prisma.event.findUnique({ + where: { slug: paramsSlug }, + include: { + _count: { select: { attendees: true } }, + attendees: { + include: { + user: { + select: { + id: true, + username: true, + displayName: true, + bio: true, + pronouns: true, + company: true, + avatarUrl: true, + accentColor: true, + }, + }, + }, + skip, + take: limit, + orderBy: { joinedAt: 'desc' }, + }, }, - attendees : { - include: { - user: { - select: { - id: true, - username: true, - displayName:true, - bio: true, - pronouns: true, - company: true, - avatarUrl: true, - accentColor: true - } - } - }, - skip, - take: limit, - orderBy: {joinedAt: 'desc'} - } - }, - })as EventWithAttendees | null; + })) as EventWithAttendees | null; - if(!event){ - return reply.status(404).send({error: 'Event not found'}) - } + if (!event) { + return reply.status(404).send({ error: 'Event not found' }); + } - - const attendees = event.attendees.map((attendee: EventWithAttendees['attendees'][number]) => ({ - id: attendee.user.id, - username: attendee.user.username, - displayName: attendee.user.displayName, - bio: attendee.user.bio, - pronouns: attendee.user.pronouns, - company: attendee.user.company, - avatarUrl: attendee.user.avatarUrl, - accentColor: attendee.user.accentColor, - })); + const attendees = event.attendees.map( + (attendee: EventWithAttendees['attendees'][number]) => ({ + id: attendee.user.id, + username: attendee.user.username, + displayName: attendee.user.displayName, + bio: attendee.user.bio, + pronouns: attendee.user.pronouns, + company: attendee.user.company, + avatarUrl: attendee.user.avatarUrl, + accentColor: attendee.user.accentColor, + }), + ); - const response: PaginatedAttendeesResponse = { - attendees, - pagination: { - page, - limit, - total : event._count.attendees, - } - } + const response: PaginatedAttendeesResponse = { + attendees, + pagination: { page, limit, total: event._count.attendees }, + }; - return response; - }) + return response; + }, + ); } \ No newline at end of file From ceb4d0ee1e2ce1cfea10ab011587ed03313c364e Mon Sep 17 00:00:00 2001 From: Srejoye Date: Wed, 17 Jun 2026 19:33:34 +0530 Subject: [PATCH 2/4] fixed --- apps/backend/src/__tests__/event.test.ts | 8 +- apps/backend/src/routes/event.ts | 129 ++++++++++------------- 2 files changed, 62 insertions(+), 75 deletions(-) diff --git a/apps/backend/src/__tests__/event.test.ts b/apps/backend/src/__tests__/event.test.ts index 7ee75680..1f765c9c 100644 --- a/apps/backend/src/__tests__/event.test.ts +++ b/apps/backend/src/__tests__/event.test.ts @@ -357,7 +357,9 @@ describe('Events API', () => { prismaMock.event.findUnique.mockResolvedValue(MOCK_EVENT); // Prisma unique constraint error const uniqueError = new Prisma.PrismaClientKnownRequestError( - 'Unique constraint failed', { code: 'P2002', clientVersion: '6.0.0' }, ); + 'Unique constraint failed', + { code: 'P2002', clientVersion: '6.0.0' }, + ); prismaMock.eventAttendee.create.mockRejectedValue(uniqueError); const res = await app.inject({ @@ -441,7 +443,9 @@ describe('Events API', () => { prismaMock.event.findUnique.mockResolvedValue(MOCK_EVENT); // Prisma record-not-found error const notFoundError = new Prisma.PrismaClientKnownRequestError( - 'Record not found', { code: 'P2025', clientVersion: '6.0.0' }, ); + 'Record not found', + { code: 'P2025', clientVersion: '6.0.0' }, + ); prismaMock.eventAttendee.delete.mockRejectedValue(notFoundError); const res = await app.inject({ diff --git a/apps/backend/src/routes/event.ts b/apps/backend/src/routes/event.ts index d3d0d3e0..c722b689 100644 --- a/apps/backend/src/routes/event.ts +++ b/apps/backend/src/routes/event.ts @@ -4,6 +4,7 @@ import { createEventSchema, joinEventSchema } from '../validations/event.validat import { generateUniqueSlug } from '../utils/slug'; import { getErrorMessage } from '../utils/error.util'; + type EventDetails = { id: string; name: string; @@ -57,66 +58,57 @@ type EventWithAttendees = { }; export async function eventRoutes(app: FastifyInstance) { - app.post( - '/', - { preHandler: [app.authenticate] }, - async ( - request: FastifyRequest<{ - Body: { - name: string; - description?: string; - startDate: string; - location: string; - endDate: string; - isPublic?: boolean; - }; - }>, - reply: FastifyReply, - ) => { - const userId = request.user.id; - const parsed = createEventSchema.safeParse(request.body); - if (!parsed.success) { - return reply.status(400).send({ error: 'Bad request' }); - } + app.post<{ + Body: { + name: string; + description?: string; + startDate: string; + location: string; + endDate: string; + isPublic?: boolean; + }; + }>('/', { preHandler: [async (request, reply) => { await app.authenticate(request, reply); }] }, + async (request, reply) => { + const userId = request.user.id; + const parsed = createEventSchema.safeParse(request.body); + if (!parsed.success) { + return reply.status(400).send({ error: 'Bad request' }); + } - const { name, description, startDate, endDate, isPublic, location } = parsed.data; + const { name, description, startDate, endDate, isPublic, location } = parsed.data; - let finalSlug = await generateUniqueSlug(name, async (slug) => { - const existing = await app.prisma.event.findUnique({ where: { slug } }); - return !!existing; - }); + const finalSlug = await generateUniqueSlug(name, async (slug) => { + const existing = await app.prisma.event.findUnique({ where: { slug } }); + return !!existing; + }); - const startDateObj = new Date(startDate); - const endDateObj = new Date(endDate); + const startDateObj = new Date(startDate); + const endDateObj = new Date(endDate); - try { - const newEvent = await app.prisma.event.create({ - data: { - name, - description, - slug: finalSlug, - location, - startDate: startDateObj, - endDate: endDateObj, - isPublic: isPublic ?? true, - organizerId: userId, - }, - }); - return reply.status(201).send(newEvent); - } catch (error: unknown) { - app.log.error('Failed to create event'); - return reply.status(500).send({ error: 'Failed to create event' }); - } - }, - ); + try { + const newEvent = await app.prisma.event.create({ + data: { + name, + description, + slug: finalSlug, + location, + startDate: startDateObj, + endDate: endDateObj, + isPublic: isPublic ?? true, + organizerId: userId, + }, + }); + return reply.status(201).send(newEvent); + } catch (error: unknown) { + app.log.error('Failed to create event'); + return reply.status(500).send({ error: 'Failed to create event' }); + } + }); // Returns event details and attendees count - app.get( + app.get<{ Params: { slug: string } }>( '/:slug', - async ( - request: FastifyRequest<{ Params: { slug: string } }>, - reply: FastifyReply, - ) => { + async (request, reply) => { const paramsSlug = request.params.slug; const details = await app.prisma.event.findUnique({ where: { slug: paramsSlug }, @@ -148,13 +140,10 @@ export async function eventRoutes(app: FastifyInstance) { }, ); - app.post( + app.post<{ Params: { slug: string } }>( '/:slug/join', - { preHandler: [app.authenticate] }, - async ( - request: FastifyRequest<{ Params: { slug: string } }>, - reply: FastifyReply, - ) => { + { preHandler: [async (request, reply) => { await app.authenticate(request, reply); }] }, + async (request, reply) => { const userId = request.user.id; const paramsSlug = request.params.slug; @@ -185,13 +174,10 @@ export async function eventRoutes(app: FastifyInstance) { }, ); - app.delete( + app.delete<{ Params: { slug: string } }>( '/:slug/leave', - { preHandler: [app.authenticate] }, - async ( - request: FastifyRequest<{ Params: { slug: string } }>, - reply: FastifyReply, - ) => { + { preHandler: [async (request, reply) => { await app.authenticate(request, reply); }] }, + async (request, reply) => { const userId = request.user.id; const paramsSlug = request.params.slug; @@ -220,15 +206,12 @@ export async function eventRoutes(app: FastifyInstance) { }, ); - app.get( + app.get<{ + Params: { slug: string }; + Querystring: { page?: string; limit?: string }; + }>( '/:slug/attendees', - async ( - request: FastifyRequest<{ - Params: { slug: string }; - Querystring: { page?: string; limit?: string }; - }>, - reply: FastifyReply, - ) => { + async (request, reply) => { const paramsSlug = request.params.slug; const page = Math.max(1, Number(request.query.page) || 1); const limit = Math.min(50, Number(request.query.limit) || 10); From e417fbd674ba2307ad8639e7ad790a37f8e4f36d Mon Sep 17 00:00:00 2001 From: Srejoye Date: Wed, 17 Jun 2026 19:40:02 +0530 Subject: [PATCH 3/4] fixed again --- apps/backend/src/__tests__/event.test.ts | 8 ++++---- apps/backend/src/routes/event.ts | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/apps/backend/src/__tests__/event.test.ts b/apps/backend/src/__tests__/event.test.ts index 1f765c9c..e3bc8f20 100644 --- a/apps/backend/src/__tests__/event.test.ts +++ b/apps/backend/src/__tests__/event.test.ts @@ -357,8 +357,8 @@ describe('Events API', () => { prismaMock.event.findUnique.mockResolvedValue(MOCK_EVENT); // Prisma unique constraint error const uniqueError = new Prisma.PrismaClientKnownRequestError( - 'Unique constraint failed', - { code: 'P2002', clientVersion: '6.0.0' }, + 'Unique constraint failed', + { code: 'P2002', clientVersion: '6.0.0' }, ); prismaMock.eventAttendee.create.mockRejectedValue(uniqueError); @@ -443,8 +443,8 @@ describe('Events API', () => { prismaMock.event.findUnique.mockResolvedValue(MOCK_EVENT); // Prisma record-not-found error const notFoundError = new Prisma.PrismaClientKnownRequestError( - 'Record not found', - { code: 'P2025', clientVersion: '6.0.0' }, + 'Record not found', + { code: 'P2025', clientVersion: '6.0.0' }, ); prismaMock.eventAttendee.delete.mockRejectedValue(notFoundError); diff --git a/apps/backend/src/routes/event.ts b/apps/backend/src/routes/event.ts index c722b689..34d29cfc 100644 --- a/apps/backend/src/routes/event.ts +++ b/apps/backend/src/routes/event.ts @@ -4,7 +4,6 @@ import { createEventSchema, joinEventSchema } from '../validations/event.validat import { generateUniqueSlug } from '../utils/slug'; import { getErrorMessage } from '../utils/error.util'; - type EventDetails = { id: string; name: string; @@ -115,7 +114,7 @@ export async function eventRoutes(app: FastifyInstance) { include: { _count: { select: { attendees: true } }, organizer: { select: { username: true, displayName: true } }, - }, + }, }); if (!details) { @@ -240,7 +239,7 @@ export async function eventRoutes(app: FastifyInstance) { take: limit, orderBy: { joinedAt: 'desc' }, }, - }, + }, })) as EventWithAttendees | null; if (!event) { @@ -248,7 +247,8 @@ export async function eventRoutes(app: FastifyInstance) { } const attendees = event.attendees.map( - (attendee: EventWithAttendees['attendees'][number]) => ({ + (attendee: EventWithAttendees['attendees'][number]) => ( + { id: attendee.user.id, username: attendee.user.username, displayName: attendee.user.displayName, @@ -257,7 +257,7 @@ export async function eventRoutes(app: FastifyInstance) { company: attendee.user.company, avatarUrl: attendee.user.avatarUrl, accentColor: attendee.user.accentColor, - }), + }), ); const response: PaginatedAttendeesResponse = { From adbb1985d73bd2feb63dc10f05a2d2f2ed643feb Mon Sep 17 00:00:00 2001 From: Srejoye Date: Wed, 17 Jun 2026 23:02:05 +0530 Subject: [PATCH 4/4] fix: resolve lint issues in event routes and tests --- apps/backend/src/__tests__/event.test.ts | 17 ++++++++++++----- apps/backend/src/routes/event.ts | 14 +++++++++----- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/apps/backend/src/__tests__/event.test.ts b/apps/backend/src/__tests__/event.test.ts index e3bc8f20..8c4ae4b0 100644 --- a/apps/backend/src/__tests__/event.test.ts +++ b/apps/backend/src/__tests__/event.test.ts @@ -1,6 +1,7 @@ +import { type PrismaClient, Prisma } from '@prisma/client'; +import Fastify, { type FastifyInstance } from 'fastify'; import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; -import Fastify, { FastifyInstance } from 'fastify'; -import { PrismaClient, Prisma } from '@prisma/client'; + import { eventRoutes } from '../routes/event'; @@ -65,7 +66,7 @@ const prismaMock = { // // This mirrors the real app setup without touching a real DB or real JWT keys. -let mockJwtVerify = vi.fn(); +const mockJwtVerify = vi.fn(); async function buildApp(): Promise { const app = Fastify({ logger: false }); @@ -98,7 +99,7 @@ async function createEvent( app: FastifyInstance, body: Record, authenticated = true, -) { +): Promise>> { return app.inject({ method: 'POST', url: '/api/events', @@ -479,7 +480,13 @@ describe('Events API', () => { /** Builds a raw EventAttendee row as Prisma returns it (with nested user) */ function makeAttendeeRow( profile: typeof MOCK_USER_PROFILE | typeof MOCK_OTHER_USER_PROFILE, - ) { + ): { + id: string; + userId: string; + eventId: string; + joinedAt: Date; + user: typeof profile; + } { return { id: `attendee-${profile.id}`, userId: profile.id, diff --git a/apps/backend/src/routes/event.ts b/apps/backend/src/routes/event.ts index 34d29cfc..6ac3db30 100644 --- a/apps/backend/src/routes/event.ts +++ b/apps/backend/src/routes/event.ts @@ -1,8 +1,10 @@ -import type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify'; import { Prisma } from '@prisma/client'; -import { createEventSchema, joinEventSchema } from '../validations/event.validation'; -import { generateUniqueSlug } from '../utils/slug'; + import { getErrorMessage } from '../utils/error.util'; +import { generateUniqueSlug } from '../utils/slug'; +import { createEventSchema } from '../validations/event.validation'; + +import type { FastifyInstance } from 'fastify'; type EventDetails = { id: string; @@ -56,7 +58,9 @@ type EventWithAttendees = { }[]; }; -export async function eventRoutes(app: FastifyInstance) { +export async function eventRoutes( + app: FastifyInstance, +): Promise { app.post<{ Body: { name: string; @@ -98,7 +102,7 @@ export async function eventRoutes(app: FastifyInstance) { }, }); return reply.status(201).send(newEvent); - } catch (error: unknown) { + } catch { app.log.error('Failed to create event'); return reply.status(500).send({ error: 'Failed to create event' }); }