import * as repo from './repository.js'; import * as activitiesRepo from '../activities/repository.js'; import * as projectsRepo from '../projects/repository.js'; import { canWriteActivity, recalcFromSubtasks } from '../activities/service.js'; import { HttpError } from '../../utils/http.js'; import { logAudit } from '../../utils/audit.js'; async function requireActivityAccess(activityId, currentUser) { const activity = await activitiesRepo.findById(activityId); if (!activity) throw new HttpError(404, 'Actividad no encontrada'); const project = await projectsRepo.findById(activity.project_id); if (!(await canWriteActivity(currentUser, project, activity))) { throw new HttpError(403, 'No tienes permisos sobre esta actividad'); } return activity; } export const listByActivity = (activityId) => repo.findByActivity(activityId); export async function createSubtask(activityId, payload, currentUser) { await requireActivityAccess(activityId, currentUser); if (!payload.name) throw new HttpError(400, 'El nombre es obligatorio'); const subtask = await repo.create(activityId, payload); await logAudit({ userId: currentUser.id, action: 'create', entityType: 'subtask', entityId: subtask.id }); const counts = await repo.countsByActivity(activityId); await recalcFromSubtasks(activityId, counts.done, counts.total); return subtask; } export async function updateSubtask(id, payload, currentUser) { const subtask = await repo.findById(id); if (!subtask) throw new HttpError(404, 'Subtarea no encontrada'); await requireActivityAccess(subtask.activity_id, currentUser); if (!payload.name) throw new HttpError(400, 'El nombre es obligatorio'); const updated = await repo.update(id, payload); await logAudit({ userId: currentUser.id, action: 'update', entityType: 'subtask', entityId: id }); return updated; } export async function setSubtaskDone(id, isDone, currentUser) { const subtask = await repo.findById(id); if (!subtask) throw new HttpError(404, 'Subtarea no encontrada'); await requireActivityAccess(subtask.activity_id, currentUser); const updated = await repo.setDone(id, isDone); await logAudit({ userId: currentUser.id, action: isDone ? 'complete' : 'reopen', entityType: 'subtask', entityId: id }); const counts = await repo.countsByActivity(subtask.activity_id); await recalcFromSubtasks(subtask.activity_id, counts.done, counts.total); return updated; } export async function removeSubtask(id, currentUser) { const subtask = await repo.findById(id); if (!subtask) throw new HttpError(404, 'Subtarea no encontrada'); await requireActivityAccess(subtask.activity_id, currentUser); await repo.remove(id); await logAudit({ userId: currentUser.id, action: 'delete', entityType: 'subtask', entityId: id }); const counts = await repo.countsByActivity(subtask.activity_id); await recalcFromSubtasks(subtask.activity_id, counts.done, counts.total); }