feat: eliminar proyecto (logico), papelera para superadmin y orden por creacion

- DELETE /api/projects/🆔 eliminacion logica (deleted_at/deleted_by), mismo
  permiso que editar el proyecto. Popup de confirmacion antes de aplicarla.
- Papelera (GET /api/projects?trash=true, POST /:id/restore, DELETE
  /:id/permanent) restringida al superadmin; el borrado fisico exige que el
  proyecto ya este en la papelera y arrastra actividades/comentarios/adjuntos
  por ON DELETE CASCADE.
- Dashboard (KPIs, actividades pendientes/calendario, proyectos por estado)
  excluye proyectos eliminados logicamente.
- Columna "Creado" en el listado de proyectos, ordenado por defecto de mas
  nuevo a mas antiguo (ListView admite initialSort ademas del orden por clic
  en cabecera que ya tenia).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Milton Gonzalez
2026-09-09 09:26:35 -05:00
parent dd7caf51c7
commit 5a25ed066d
16 changed files with 247 additions and 33 deletions
+7 -1
View File
@@ -1,6 +1,9 @@
import { Router } from 'express';
import { requireAuth } from '../../middleware/auth.js';
import { getProjects, getProject, postProject, putProject, postMember, deleteMember } from './controller.js';
import {
getProjects, getProject, postProject, putProject, deleteProject, postProjectRestore,
deleteProjectPermanent, postMember, deleteMember,
} from './controller.js';
import { getGantt } from '../dashboard/controller.js';
import { getActivitiesByProject, postActivity } from '../activities/controller.js';
@@ -11,6 +14,9 @@ router.get('/', getProjects);
router.post('/', postProject);
router.get('/:id', getProject);
router.put('/:id', putProject);
router.delete('/:id', deleteProject);
router.post('/:id/restore', postProjectRestore);
router.delete('/:id/permanent', deleteProjectPermanent);
router.get('/:id/gantt', getGantt);
router.post('/:id/members', postMember);
router.delete('/:id/members/:userId', deleteMember);