f96391d360
- Un proyecto puede tener uno o mas administradores (role_in_project= 'admin' en project_members), independiente del rol global del usuario. Nuevo PUT /api/projects/:id/members/:userId/role; canWriteProject lo reconoce ademas del comportamiento previo (admin/superadmin/it_manager global, o project_lead miembro). UI: casilla al agregar miembro + boton de escudo para promover/degradar (nunca toca al Dueño). - Menu "Configuracion" (apariencia, catalogos, SMTP) visible y accesible solo para el superadmin: oculto en el nav y con guarda en la ruta /configuracion para quien la teclee directo. Escritura de catalogos restringida de [superadmin, admin] a solo superadmin para que el backend sea consistente con la UI. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
5.5 KiB
5.5 KiB
API - project.linkedcorp.net
Base URL
- Desarrollo:
http://localhost:4019/api - Producción:
https://project.linkedcorp.net/api
Autenticacion
- Tipo: Bearer JWT (
Authorization: Bearer <token>), emitido por/api/auth/login. - El backend revalida
is_activedel usuario en cada request (no solo la firma del JWT).
Formato de respuesta
{
"success": true,
"data": {},
"error": null
}
Endpoints principales
Auth
POST /api/auth/login—{ email, password }→{ token, user }. Si el usuario no estaactive(pending_verification/pending_approval) ois_active=0,403con mensaje especifico.POST /api/auth/register— público.{ name, email, password }→ si es el primer usuario del sistema:{ bootstrap: true, token, user }(superadmin, sesion directa); si no:{ bootstrap: false }y se envia (o loguea, sin SMTP) un correo de verificación.GET /api/auth/verify-email?token=...— público. Pasa el usuario apending_approvaly notifica in-app a losadmin/superadminactivos.POST /api/auth/forgot-password— público.{ email }→ respuesta siempre genérica.POST /api/auth/reset-password— público.{ token, password }.PUT /api/auth/change-password— autenticado.{ currentPassword, newPassword }, exige la clave actual (distinto dereset-password, que usa un token de correo sin sesión).POST /api/auth/logoutGET /api/auth/me— usuario actual
Usuarios (/api/users) — lectura para cualquier autenticado; escritura solo Administrador/Superadministrador
GET /api/users·POST /api/users·PUT /api/users/:id·PATCH /api/users/:id/activePOST /api/users/:id/approve—{ roleId?, departmentId? }, solo sobre usuariospending_approvalPOST /api/users/:id/reject— borra al usuariopending_approval(se audita el email antes)
Departamentos (/api/departments)
GET /api/departments(árbol) ·POST /api/departments·PUT /api/departments/:id·DELETE /api/departments/:id
Proyectos (/api/projects)
GET /api/projects(filtros: estado, responsable, prioridad;trash=true= papelera, solo superadmin) ·POST /api/projectsGET /api/projects/:id·PUT /api/projects/:idDELETE /api/projects/:id— eliminación lógica (deleted_at/deleted_by), mismo permiso que editar el proyecto.POST /api/projects/:id/restoreyDELETE /api/projects/:id/permanent(borrado físico, irreversible, arrastra actividades/comentarios/adjuntos) — ambos solo superadmin;permanentexige que el proyecto ya esté en la papelera (400 si no).POST /api/projects/:id/members(roleInProjectopcional:'admin'= administrador del proyecto) ·PUT /api/projects/:id/members/:userId/role({ admin: true|false }, otorga o quita el rol de administrador de ese proyecto — un proyecto puede tener uno o más administradores, sin importar el rol global del usuario; nunca toca alowner) ·DELETE /api/projects/:id/members/:userId
Actividades (/api/activities)
GET /api/projects/:projectId/activities·POST /api/projects/:projectId/activitiesGET /api/activities/:id·PUT /api/activities/:idPOST /api/activities/:id/dependencies·DELETE /api/activities/:id/dependencies/:dependsOnId
Subtareas (/api/activities/:activityId/subtasks)
GET·POST·PUT /api/subtasks/:id·PATCH /api/subtasks/:id/done·DELETE /api/subtasks/:id
Comentarios (/api/comments)
GET /api/comments?entityType=project&entityId=1·POST /api/comments
Adjuntos (/api/attachments)
GET /api/attachments?entityType=activity&entityId=1·POST /api/attachments(multipart)GET /api/attachments/:id/download·DELETE /api/attachments/:id
Notificaciones (/api/notifications)
GET /api/notifications·PATCH /api/notifications/:id/read·PATCH /api/notifications/read-all
Dashboard (/api/dashboard)
GET /api/dashboard/summary— KPIs (activos, atrasados, pendientes/vencidas/hoy, avance promedio)GET /api/dashboard/calendar?month=2026-09— actividades por fecha límiteGET /api/projects/:id/gantt— actividades con fechas/avance para el Gantt
Catálogos (/api/catalogs) — lectura general, escritura solo Superadministrador
GET/POST/PUT/DELETE /api/catalogs/project-statusesGET/POST/PUT/DELETE /api/catalogs/activity-statusesGET/POST/PUT/DELETE /api/catalogs/prioritiesGET/POST/PUT/DELETE /api/catalogs/project-types
Auditoría (/api/audit) — solo Superadministrador / Administrador / Jefe de TI
GET /api/audit?entityType=project&entityId=1
Configuración SMTP (/api/settings) — solo Superadministrador
GET /api/settings/smtp—{ host, port, user, from, configured }(nunca la clave)PUT /api/settings/smtp—{ host, port, user, from, pass? }(passvacío = no cambiarla)POST /api/settings/smtp/test—{ host, port, user, from, pass?, to }(passvacío = usa la guardada). Envía un correo real con los valores del formulario (aunque no se hayan guardado) y responde{ sent: true }o400con el error real del servidor SMTP. Rate-limited (10/15min).
Errores esperados
400validación401no autenticado / token inválido o expirado403sin permisos para la acción (según rol)404no encontrado (incluye cuando el recurso existe pero no pertenece al usuario/alcance)500error interno (sanitizado, sin detalle de stack en producción)