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>
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
import { ok, fail, asyncHandler } from '../../utils/http.js';
|
||||
import { HttpError } from '../../utils/http.js';
|
||||
import { logAudit } from '../../utils/audit.js';
|
||||
import { ROLES } from '../../middleware/auth.js';
|
||||
import * as repo from './repository.js';
|
||||
|
||||
const VALID_ENTITY_TYPES = new Set(['project', 'activity']);
|
||||
|
||||
export const getComments = asyncHandler(async (req, res) => {
|
||||
const { entityType, entityId } = req.query;
|
||||
if (!VALID_ENTITY_TYPES.has(entityType) || !entityId) return fail(res, 400, 'entityType y entityId son obligatorios');
|
||||
ok(res, await repo.findByEntity(entityType, Number(entityId)));
|
||||
});
|
||||
|
||||
export const postComment = asyncHandler(async (req, res) => {
|
||||
const { entityType, entityId, message } = req.body || {};
|
||||
if (!VALID_ENTITY_TYPES.has(entityType) || !entityId || !message) {
|
||||
throw new HttpError(400, 'entityType, entityId y message son obligatorios');
|
||||
}
|
||||
if (req.currentUser.roleCode === ROLES.VIEWER) throw new HttpError(403, 'Tu rol es de solo lectura');
|
||||
const comment = await repo.create({ entityType, entityId, userId: req.currentUser.id, message });
|
||||
await logAudit({ userId: req.currentUser.id, action: 'comment', entityType, entityId, detail: { commentId: comment.id } });
|
||||
ok(res, comment, 201);
|
||||
});
|
||||
Reference in New Issue
Block a user