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"); }, ); }