Files
project.linkedcorp.net/backend/src/modules/departments/service.js
T
Milton Gonzalez 1d22adc42e chore: estructura inicial del MVP
Backend (Express + MariaDB) y frontend (React + Vite, identidad Fluent/Windows) con el
nucleo funcional: seguridad, organizacion, proyectos, actividades, subtareas, dependencias,
dashboard, calendario, gantt, comentarios, adjuntos, notificaciones in-app y catalogos.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 08:37:58 -05:00

44 lines
1.7 KiB
JavaScript

import * as repo from './repository.js';
import { HttpError } from '../../utils/http.js';
import { logAudit } from '../../utils/audit.js';
function toTree(flat) {
const byId = new Map(flat.map((d) => [d.id, { ...d, children: [] }]));
const roots = [];
for (const dept of byId.values()) {
if (dept.parent_id && byId.has(dept.parent_id)) {
byId.get(dept.parent_id).children.push(dept);
} else {
roots.push(dept);
}
}
return roots;
}
export async function listTree() {
const flat = await repo.findAllFlat();
return toTree(flat);
}
export async function createDepartment(payload, actorId) {
if (!payload.name) throw new HttpError(400, 'El nombre es obligatorio');
const dept = await repo.create(payload);
await logAudit({ userId: actorId, action: 'create', entityType: 'department', entityId: dept.id });
return dept;
}
export async function updateDepartment(id, payload, actorId) {
if (!payload.name) throw new HttpError(400, 'El nombre es obligatorio');
if (Number(payload.parentId) === Number(id)) throw new HttpError(400, 'Un departamento no puede ser su propio padre');
const dept = await repo.update(id, payload);
await logAudit({ userId: actorId, action: 'update', entityType: 'department', entityId: id });
return dept;
}
export async function deleteDepartment(id, actorId) {
if (await repo.hasChildren(id)) throw new HttpError(400, 'Tiene sub-departamentos; reasignalos antes de eliminar');
if (await repo.hasUsers(id)) throw new HttpError(400, 'Tiene usuarios asignados; reasignalos antes de eliminar');
await repo.remove(id);
await logAudit({ userId: actorId, action: 'delete', entityType: 'department', entityId: id });
}