import { ok, fail, asyncHandler } from '../../utils/http.js'; import * as repo from './repository.js'; import { listByProject } from '../activities/service.js'; import { dueStatus } from '../../utils/dates.js'; import { ROLES } from '../../middleware/auth.js'; const FULL_ACCESS_ROLES = [ROLES.SUPERADMIN, ROLES.ADMIN, ROLES.IT_MANAGER]; // Mismo criterio que projects/service.js#listProjects: los roles de administracion ven todo el // panel; el resto solo cuenta/lista lo de proyectos donde es miembro. function memberFilterFor(currentUser) { return FULL_ACCESS_ROLES.includes(currentUser.roleCode) ? null : currentUser.id; } export const getSummary = asyncHandler(async (req, res) => { const memberUserId = memberFilterFor(req.currentUser); const [kpis, byStatus, overdueProjects, activeProjects, dueSoonProjects, pendingActivities, overdueActivities, todayActivities] = await Promise.all([ repo.summary(memberUserId), repo.projectsByStatus(memberUserId), repo.overdueProjectsList(memberUserId), repo.activeProjectsList(memberUserId), repo.dueSoonProjectsList(memberUserId), repo.pendingActivitiesList(memberUserId, 'all'), repo.pendingActivitiesList(memberUserId, 'overdue'), repo.pendingActivitiesList(memberUserId, 'today'), ]); const withProjectDue = (p) => ({ ...p, dueStatus: dueStatus(p.estimated_end_date) }); const withActivityDue = (a) => ({ ...a, dueStatus: dueStatus(a.due_date) }); ok(res, { kpis, projectsByStatus: byStatus, // Detalle de cada tarjeta del Panel (popup al hacer clic). overdueProjects: overdueProjects.map((p) => ({ ...p, dueStatus: 'overdue' })), activeProjects: activeProjects.map(withProjectDue), dueSoonProjects: dueSoonProjects.map(withProjectDue), pendingActivities: pendingActivities.map(withActivityDue), overdueActivities: overdueActivities.map((a) => ({ ...a, dueStatus: 'overdue' })), todayActivities: todayActivities.map(withActivityDue), }); }); export const getCalendar = asyncHandler(async (req, res) => { const month = req.query.month; // formato YYYY-MM if (!month || !/^\d{4}-\d{2}$/.test(month)) return fail(res, 400, 'Parametro month invalido (YYYY-MM)'); const start = `${month}-01`; const [year, m] = month.split('-').map(Number); const end = new Date(year, m, 0).toISOString().slice(0, 10); const items = await repo.calendarActivities(start, end, memberFilterFor(req.currentUser)); ok(res, items.map((a) => ({ ...a, dueStatus: dueStatus(a.due_date, a.status_is_closed) }))); }); export const getGantt = asyncHandler(async (req, res) => { const activities = await listByProject(Number(req.params.id), req.currentUser); ok(res, activities.map((a) => ({ id: a.id, code: a.code, name: a.name, startDate: a.start_date, dueDate: a.due_date, progressPct: a.progress_pct, isMilestone: !!a.is_milestone, responsibleName: a.responsible_name, }))); });