diff --git a/backend/src/routes/visitors.routes.ts b/backend/src/routes/visitors.routes.ts index 1fe2472..2f77304 100644 --- a/backend/src/routes/visitors.routes.ts +++ b/backend/src/routes/visitors.routes.ts @@ -28,14 +28,8 @@ const checkInSchema = z.object({ }); export async function visitorRoutes(fastify: FastifyInstance) { - // Auth middleware - fastify.addHook('onRequest', async (request) => { - try { - await request.jwtVerify(); - } catch (err) { - throw err; - } - }); + // Note: Most visitor routes are public to support the Kiosk mode. + // Specific admin routes (Revoke, Report) are protected inside their handlers. /** * GET /visitors @@ -320,6 +314,54 @@ export async function visitorRoutes(fastify: FastifyInstance) { } }); + /** + * POST /visitors/:id/revoke + * Revoke visitor access immediately + */ + fastify.post('/:id/revoke', { + handler: async (request, reply) => { + try { + await request.jwtVerify(); + const { id } = request.params as any; + const { notes } = request.body as any; + const userId = (request.user as any)?.id; + + const log = await prisma.visitorLog.findFirst({ + where: { + visitorId: id, + status: 'CHECKED_IN', + exitTime: null + } + }); + + if (!log) { + return reply.status(400).send({ error: 'Visitor not currently checked in' }); + } + + const updatedLog = await prisma.visitorLog.update({ + where: { id: log.id }, + data: { + status: 'REVOKED', + exitTime: new Date(), + notes: `ACCESS REVOKED by User ${userId}. ${notes || ''}`.trim() + }, + include: { + visitor: true + } + }); + + return { + success: true, + message: 'Access revoked successfully', + log: updatedLog + }; + } catch (error) { + fastify.log.error(error); + return reply.status(500).send({ error: 'Failed to revoke access' }); + } + } + }); + /** * GET /visitors/report * Generate visitor report for compliance @@ -327,6 +369,7 @@ export async function visitorRoutes(fastify: FastifyInstance) { fastify.get('/report', { handler: async (request, reply) => { try { + await request.jwtVerify(); const { startDate, endDate, type } = request.query as any; const where: any = {