refactor: renombra Subtareas a Tareas en todo el sistema
Actividad -> Tarea, sin nivel "sub" intermedio (no hay una entidad "Tarea" de la que estas fueran sub-, asi que el prefijo sobraba). Tabla subtasks -> tasks (RENAME TABLE idempotente en la migracion 005; 001_initial.sql tambien actualizado para que una instalacion nueva cree la tabla ya con el nombre final, sin pasar por el nombre viejo). Modulo backend, rutas, servicio frontend, pestaña del detalle de actividad, i18n y documentacion actualizados. Sin cambios de comportamiento, solo nombres. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import * as repo from './repository.js';
|
||||
import * as activitiesRepo from '../activities/repository.js';
|
||||
import * as projectsRepo from '../projects/repository.js';
|
||||
import { canWriteActivity, recalcFromTasks } 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 createTask(activityId, payload, currentUser) {
|
||||
await requireActivityAccess(activityId, currentUser);
|
||||
if (!payload.name) throw new HttpError(400, 'El nombre es obligatorio');
|
||||
const task = await repo.create(activityId, payload);
|
||||
await logAudit({ userId: currentUser.id, action: 'create', entityType: 'task', entityId: task.id });
|
||||
const counts = await repo.countsByActivity(activityId);
|
||||
await recalcFromTasks(activityId, counts.done, counts.total);
|
||||
return task;
|
||||
}
|
||||
|
||||
export async function updateTask(id, payload, currentUser) {
|
||||
const task = await repo.findById(id);
|
||||
if (!task) throw new HttpError(404, 'Tarea no encontrada');
|
||||
await requireActivityAccess(task.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: 'task', entityId: id });
|
||||
return updated;
|
||||
}
|
||||
|
||||
export async function setTaskDone(id, isDone, currentUser) {
|
||||
const task = await repo.findById(id);
|
||||
if (!task) throw new HttpError(404, 'Tarea no encontrada');
|
||||
await requireActivityAccess(task.activity_id, currentUser);
|
||||
const updated = await repo.setDone(id, isDone);
|
||||
await logAudit({ userId: currentUser.id, action: isDone ? 'complete' : 'reopen', entityType: 'task', entityId: id });
|
||||
const counts = await repo.countsByActivity(task.activity_id);
|
||||
await recalcFromTasks(task.activity_id, counts.done, counts.total);
|
||||
return updated;
|
||||
}
|
||||
|
||||
export async function removeTask(id, currentUser) {
|
||||
const task = await repo.findById(id);
|
||||
if (!task) throw new HttpError(404, 'Tarea no encontrada');
|
||||
await requireActivityAccess(task.activity_id, currentUser);
|
||||
await repo.remove(id);
|
||||
await logAudit({ userId: currentUser.id, action: 'delete', entityType: 'task', entityId: id });
|
||||
const counts = await repo.countsByActivity(task.activity_id);
|
||||
await recalcFromTasks(task.activity_id, counts.done, counts.total);
|
||||
}
|
||||
Reference in New Issue
Block a user