Files
helpdesk-texnet/backend/src/controllers/users.controller.ts
pettrop e4f63a135e Initial commit: Helpdesk application setup
- Backend: Node.js/TypeScript with Prisma ORM
- Frontend: Vite + TypeScript
- Project configuration and documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 08:53:22 +01:00

273 lines
7.2 KiB
TypeScript

import { Response } from 'express';
import bcrypt from 'bcryptjs';
import prisma from '../config/database';
import { successResponse, errorResponse, paginatedResponse, parseQueryInt, getParam, getQueryString } from '../utils/helpers';
import { AuthRequest } from '../middleware/auth.middleware';
// Jednoduchý zoznam aktívnych používateľov (pre select/dropdown)
// Podporuje server-side vyhľadávanie pre lepší výkon pri veľkom počte používateľov
export const getUsersSimple = async (req: AuthRequest, res: Response): Promise<void> => {
try {
const search = getQueryString(req, 'search');
const limit = parseQueryInt(req.query.limit, 50); // Default 50, max 100
const actualLimit = Math.min(limit, 100);
const where = {
active: true,
...(search && {
OR: [
{ name: { contains: search, mode: 'insensitive' as const } },
{ email: { contains: search, mode: 'insensitive' as const } },
],
}),
};
const users = await prisma.user.findMany({
where,
take: actualLimit,
orderBy: { name: 'asc' },
select: {
id: true,
name: true,
email: true,
},
});
successResponse(res, users);
} catch (error) {
console.error('Error fetching users simple:', error);
errorResponse(res, 'Chyba pri načítaní používateľov.', 500);
}
};
export const getUsers = async (req: AuthRequest, res: Response): Promise<void> => {
try {
const page = parseQueryInt(req.query.page, 1);
const limit = parseQueryInt(req.query.limit, 20);
const skip = (page - 1) * limit;
const search = getQueryString(req, 'search');
const active = getQueryString(req, 'active');
const roleId = getQueryString(req, 'roleId');
const where = {
...(active !== undefined && { active: active === 'true' }),
...(roleId && { roleId }),
...(search && {
OR: [
{ name: { contains: search, mode: 'insensitive' as const } },
{ email: { contains: search, mode: 'insensitive' as const } },
],
}),
};
const [users, total] = await Promise.all([
prisma.user.findMany({
where,
skip,
take: limit,
orderBy: { createdAt: 'desc' },
select: {
id: true,
email: true,
name: true,
active: true,
createdAt: true,
updatedAt: true,
role: {
select: {
id: true,
code: true,
name: true,
},
},
},
}),
prisma.user.count({ where }),
]);
paginatedResponse(res, users, total, page, limit);
} catch (error) {
console.error('Error fetching users:', error);
errorResponse(res, 'Chyba pri načítaní používateľov.', 500);
}
};
export const getUser = async (req: AuthRequest, res: Response): Promise<void> => {
try {
const id = getParam(req, 'id');
const user = await prisma.user.findUnique({
where: { id },
select: {
id: true,
email: true,
name: true,
active: true,
createdAt: true,
updatedAt: true,
role: {
select: {
id: true,
code: true,
name: true,
permissions: true,
},
},
},
});
if (!user) {
errorResponse(res, 'Používateľ nebol nájdený.', 404);
return;
}
successResponse(res, user);
} catch (error) {
console.error('Error fetching user:', error);
errorResponse(res, 'Chyba pri načítaní používateľa.', 500);
}
};
export const updateUser = async (req: AuthRequest, res: Response): Promise<void> => {
try {
const id = getParam(req, 'id');
const { email, name, active, password } = req.body;
const existingUser = await prisma.user.findUnique({ where: { id } });
if (!existingUser) {
errorResponse(res, 'Používateľ nebol nájdený.', 404);
return;
}
// Check email uniqueness if changing
if (email && email !== existingUser.email) {
const emailExists = await prisma.user.findUnique({ where: { email } });
if (emailExists) {
errorResponse(res, 'Email je už používaný.', 409);
return;
}
}
const updateData: Record<string, unknown> = {};
if (email) updateData.email = email;
if (name) updateData.name = name;
if (active !== undefined) updateData.active = active;
if (password) updateData.password = await bcrypt.hash(password, 10);
const user = await prisma.user.update({
where: { id },
data: updateData,
select: {
id: true,
email: true,
name: true,
active: true,
role: {
select: {
id: true,
code: true,
name: true,
},
},
},
});
if (req.logActivity) {
await req.logActivity('UPDATE', 'User', id, updateData);
}
successResponse(res, user, 'Používateľ bol aktualizovaný.');
} catch (error) {
console.error('Error updating user:', error);
errorResponse(res, 'Chyba pri aktualizácii používateľa.', 500);
}
};
export const deleteUser = async (req: AuthRequest, res: Response): Promise<void> => {
try {
const id = getParam(req, 'id');
// Prevent self-deletion
if (req.user?.userId === id) {
errorResponse(res, 'Nemôžete vymazať vlastný účet.', 400);
return;
}
const user = await prisma.user.findUnique({ where: { id } });
if (!user) {
errorResponse(res, 'Používateľ nebol nájdený.', 404);
return;
}
// Soft delete - just deactivate
await prisma.user.update({
where: { id },
data: { active: false },
});
if (req.logActivity) {
await req.logActivity('DELETE', 'User', id);
}
successResponse(res, null, 'Používateľ bol deaktivovaný.');
} catch (error) {
console.error('Error deleting user:', error);
errorResponse(res, 'Chyba pri mazaní používateľa.', 500);
}
};
export const updateUserRole = async (req: AuthRequest, res: Response): Promise<void> => {
try {
const id = getParam(req, 'id');
const { roleId } = req.body;
// Prevent changing own role
if (req.user?.userId === id) {
errorResponse(res, 'Nemôžete zmeniť vlastnú rolu.', 400);
return;
}
const user = await prisma.user.findUnique({ where: { id } });
if (!user) {
errorResponse(res, 'Používateľ nebol nájdený.', 404);
return;
}
const role = await prisma.userRole.findUnique({ where: { id: roleId } });
if (!role) {
errorResponse(res, 'Rola neexistuje.', 404);
return;
}
const updatedUser = await prisma.user.update({
where: { id },
data: { roleId },
select: {
id: true,
email: true,
name: true,
role: {
select: {
id: true,
code: true,
name: true,
},
},
},
});
if (req.logActivity) {
await req.logActivity('UPDATE', 'User', id, { roleId, roleName: role.name });
}
successResponse(res, updatedUser, 'Rola používateľa bola zmenená.');
} catch (error) {
console.error('Error updating user role:', error);
errorResponse(res, 'Chyba pri zmene roly.', 500);
}
};