import { FastifyInstance } from 'fastify'; import { requirePermission } from '../../middleware/auth'; import { logAudit } from '../../services/audit'; import { success, error, parseId } from '../../utils/response'; import { parsePagination, buildPaginationMeta } from '../../utils/pagination'; import { parseBody } from '../../schemas/common'; import { CreateUserSchema, UpdateUserSchema } from '../../schemas/users.schema'; import { listUsers, getUser, createUser, updateUser, deleteUser } from '../../services/users.service'; export default async function usersRoutes(fastify: FastifyInstance): Promise { // GET /api/admin/users fastify.get('/', { preHandler: requirePermission('users.view') }, async (request, reply) => { const params = parsePagination(request.query as Record); const result = await listUsers(params); return reply.send({ success: true, data: result.users, pagination: buildPaginationMeta(result.total, result.page, result.limit), }); }); // GET /api/admin/users/:id fastify.get<{ Params: { id: string } }>('/:id', { preHandler: requirePermission('users.view') }, async (request, reply) => { const id = parseId(request.params.id, reply); if (id === null) return; const user = await getUser(id); if (!user) return error(reply, 'Uživatel nenalezen', 404); return success(reply, user); }); // POST /api/admin/users fastify.post('/', { preHandler: requirePermission('users.create') }, async (request, reply) => { const parsed = parseBody(CreateUserSchema, request.body); if ('error' in parsed) return error(reply, parsed.error, 400); const body = parsed.data; const result = await createUser({ username: body.username, email: body.email, password: body.password, first_name: body.first_name, last_name: body.last_name, role_id: body.role_id, is_active: body.is_active, }); if ('error' in result) return error(reply, result.error!, result.status!); await logAudit({ request, authData: request.authData, action: 'create', entityType: 'user', entityId: result.user.id, description: `Vytvořen uživatel ${result.user.username}`, }); return success(reply, { id: result.user.id }, 201, 'Uživatel byl vytvořen'); }); // PUT /api/admin/users/:id fastify.put<{ Params: { id: string } }>('/:id', { preHandler: requirePermission('users.edit') }, async (request, reply) => { const id = parseId(request.params.id, reply); if (id === null) return; const parsed = parseBody(UpdateUserSchema, request.body); if ('error' in parsed) return error(reply, parsed.error, 400); const userData = { ...parsed.data, role_id: parsed.data.role_id != null ? Number(parsed.data.role_id) : parsed.data.role_id as number | null | undefined, }; const result = await updateUser(id, userData); if ('error' in result) return error(reply, result.error!, result.status!); await logAudit({ request, authData: request.authData, action: 'update', entityType: 'user', entityId: id, description: `Upraven uživatel ${result.username}`, }); return success(reply, { id }, 200, 'Uživatel byl uložen'); }); // DELETE /api/admin/users/:id fastify.delete<{ Params: { id: string } }>('/:id', { preHandler: requirePermission('users.delete') }, async (request, reply) => { const id = parseId(request.params.id, reply); if (id === null) return; const result = await deleteUser(id, request.authData?.userId); if ('error' in result) return error(reply, result.error!, result.status!); await logAudit({ request, authData: request.authData, action: 'delete', entityType: 'user', entityId: id, description: `Smazán uživatel ${result.username}`, }); return success(reply, null, 200, 'Uživatel smazán'); }); }