Files
project.linkedcorp.net/AGENTS.md
T
Milton Gonzalez 7557dffc52 feat: autorregistro con verificacion de correo + aprobacion, superadmin y SMTP
- POST /api/auth/register: primer usuario del sistema -> superadmin con sesion
  directa (bootstrap, sin correo ni aprobacion); los siguientes quedan
  pending_verification y reciben un correo con enlace de un solo uso (24h).
- GET /api/auth/verify-email: pasa a pending_approval y notifica in-app a los
  admin/superadmin activos.
- admin/superadmin aprueban (POST /api/users/:id/approve, eligen rol y
  departamento) o rechazan (POST /api/users/:id/reject, borra y audita el
  email) desde Organizacion -> Usuarios (nuevo badge de estado + acciones).
- login() da mensaje especifico segun el status de la cuenta en vez del
  generico "credenciales invalidas".
- Recuperacion de clave (forgot/reset-password): respuesta siempre generica,
  token de 1 hora de un solo uso.
- Nuevo modulo settings: SMTP configurable SOLO por superadmin desde
  Configuracion -> Correo (SMTP); clave cifrada AES-256-GCM (ENCRYPTION_KEY)
  en la tabla system_settings, nunca expuesta por la API. sendMail() degrada
  a modo dev (loguea en vez de enviar) si no hay SMTP configurado, y nunca
  deja que un fallo de envio tumbe al que lo llama.
- Migracion 002_registration_and_smtp.sql: rol superadmin, columnas de ciclo
  de vida en users (status, tokens), tabla system_settings, y promueve al
  usuario mas antiguo del sistema a superadmin.
- Fix: React.StrictMode disparaba el efecto de VerifyEmailPage dos veces; la
  segunda llamada (token ya consumido) mostraba "enlace invalido" pese a que
  la verificacion ya habia funcionado. Se agrega una guarda por token.
- Fix (deuda tecnica v1.0.0): se reordena el montaje de rutas en app.js —
  subtasksRoutes (mount generico en /api) va al final, para no interceptar
  con su requireAuth interno una request sin token dirigida a un router mas
  especifico registrado despues.
- Documentacion actualizada: AGENTS.md, SPEC.md, API.md, BASE_DE_DATOS.md,
  CONFIGURACION.md, ESTADO.md, CHANGELOG.md. Version 1.1.0.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-05 23:28:46 -05:00

8.2 KiB
Raw Blame History

AGENTS.md - project.linkedcorp.net

⚠️ ANTES DE ACTUAR, lee el orquestador del grupo: /home/mgonzalez/desarrollo/project-md-templates/leeme_primero.txt Reglas globales (infra, secretos, UI/UX, Android, Git, versionado). Este archivo es solo el contexto especifico del proyecto.

⛔ AISLAMIENTO: SOLO ESTE PROYECTO

Regla dura del grupo (detalle en el orquestador, seccion "REGLA DE AISLAMIENTO ENTRE PROYECTOS"):

  • Se trabaja SOLO sobre este proyecto. Los otros proyectos del grupo NO se tocan NI se leen.
  • Leer otro proyecto: unicamente si el usuario lo pide TEXTUALMENTE en ese pedido.
  • Modificar otro proyecto: NUNCA, ni aunque el usuario lo nombre.
  • Recursos compartidos (puertos, NPM, systemd, BD, DNS): verificar en la fuente real que esten libres antes de ocuparlos; solo crear objetos nuevos de ESTE proyecto.

Proposito

Contexto especifico del proyecto para el asistente de IA. No repite las reglas globales del grupo, que estan en el orquestador leeme_primero.txt.

Identidad del proyecto

  • Nombre: project.linkedcorp.net
  • Tipo: fullstack (gestión y seguimiento de proyectos/actividades TI)
  • Estado: development
  • Ruta raiz: /home/mgonzalez/desarrollo/project.linkedcorp.net

Stack real del proyecto

Frontend

  • React + Vite
  • UI: CSS propio por tokens (sin Tailwind) siguiendo la identidad docs/UI-UX-WINDOWS.md (Fluent/Windows 11)
  • Iconos: lucide-react

Backend

  • Node.js + Express
  • API base: /api

Base de datos

  • Motor: MariaDB
  • Base principal: project_linkedcorp
  • Host dev: 192.168.222.20 / Host prod: 192.168.222.32 (NO mezclar)
  • La base ya existe: sí (creada en dev el 2026-09-03 con crear-db-dev.sh)

Arquetipo de despliegue

B — Dos servicios separados (frontend y backend como procesos independientes).

  • systemd: project-linkedcorp-frontend y project-linkedcorp-backend (a crear en el primer deploy).
  • NPM: Proxy Host al frontend + Custom Location /api al backend.
  • Puertos (registrados en PORTS_INVENTORY.md del grupo): frontend 5196, backend 4019.

Identidad UI/UX — DECISIÓN DE ESTE PROYECTO (no es la identidad estándar del grupo)

Este proyecto usa UI-UX-WINDOWS.md / UI-UX-WINDOWS.html (Fluent Design / Windows 11: NavigationView, clic derecho, Master-Detail, ContentDialog/InfoBar/Flyout/Toast) en vez de UI-UX-LINKEDCORP.md (identidad web estándar del grupo). Fue decisión explícita del usuario al arrancar el proyecto. Copia ajustada en docs/UI-UX-WINDOWS.md.

Adaptación web (no es una app empaquetada, corre en pestaña de navegador):

  • SÍ: tokens de color, tipografía, NavigationView, ListView+clic derecho, Master-Detail, ContentDialog, InfoBar, Toast, Flyout, ComboBox/DatePicker propios, Expander, Treeview.
  • NO: barra de título falsa con minimizar/maximizar/cerrar (no hay ventana de SO que controlar).
  • Igual obligatorio: idioma es-EC/en-US + tema claro/oscuro + apariencia de botones, todo persistido.
  • Set de íconos: Lucide (única opción usada en este proyecto).

Estructura acordada

  • frontend/
  • backend/
  • docs/

Modulos principales (MVP — ver SPEC.md para el detalle y lo diferido a fase 2)

  • Seguridad (usuarios, roles fijos, sesión, auditoría)
  • Organización (departamentos con sub-áreas, usuarios)
  • Proyectos (con miembros)
  • Actividades + Subtareas + dependencias simples
  • Dashboard (KPIs)
  • Calendario y Gantt de solo lectura
  • Comentarios y adjuntos
  • Notificaciones in-app
  • Configuración (catálogos: estados, prioridades, tipos de proyecto)

Restricciones tecnicas

  • No romper estructura existente.
  • Mantener frontend y backend separados (arquetipo B).
  • Variables de entorno, nunca secretos en código.
  • Empresa asumida como única (single-company): no hay tabla companies en el MVP.
  • Permisos por rol codificados en backend (backend/src/middleware/auth.js), no configurables por UI en el MVP — ver tabla de roles en SPEC.md.

Arquitectura esperada

Backend

  • routes -> controller -> service -> repository -> db
  • Un directorio por módulo en backend/src/modules/<modulo>/

Frontend

  • src/components (UI base Windows: NavigationView, ContentDialog, InfoBar, Toast, Flyout, ListView, ComboBox, DatePicker, Treeview, Field, Button)
  • src/pages (Login, Dashboard, Organizacion, Proyectos, Configuracion)
  • src/services (cliente API por módulo)
  • src/context (auth, ui: tema/idioma/dialog/toast)
  • src/i18n

Seguridad (proyecto con auth/usuarios)

  • Permisos validados SIEMPRE en el backend, nunca solo en el frontend.
  • Autorregistro con doble candado (decisión posterior al MVP inicial, ver SPEC.md): el usuario se crea a sí mismo pero queda pending_verification → confirma su correo (token de un solo uso, 24h) → pending_approval → un admin/superadmin aprueba (elige rol/departamento) o rechaza (se borra). Solo el usuario más antiguo del sistema es superadmin automático (bootstrap, sin correo ni aprobación — no hay quién lo apruebe). El admin sigue pudiendo crear usuarios directamente (ya activos, sin pasar por este flujo) desde Organización → Usuarios.
  • 401 → el frontend limpia sesión, redirige a login y muestra aviso (ContentDialog).
  • Cierre de sesión por expiración de JWT.
  • Auditoría en BD (audit_log): usuario, acción, entidad, fecha/hora, detalle.
  • Credenciales/secretos solo en .env (nunca en código); .env.example sí se versiona. Excepción: el SMTP del sistema NO vive en .env — lo carga el superadmin desde Configuración → Correo (SMTP), queda en system_settings con la clave cifrada (AES-256-GCM, ENCRYPTION_KEY).
  • Cifrado: bcrypt para contraseñas; AES-256-GCM (backend/src/utils/crypto.js) para secretos de terceros guardados en BD (hoy: la clave SMTP).
  • Revalidar is_active del usuario en cada request (un JWT firmado no basta); el login además revisa status (pending_verification/pending_approval dan un mensaje especifico, no login).
  • SQL siempre parametrizado. Uploads: validar MIME/tamaño, ruta de archivo generada por el servidor.
  • forgot-password responde SIEMPRE genérico (exista o no el correo); el envío de correo nunca debe poder tumbar ni cambiar la respuesta de un endpoint (sendMail atrapa sus propios errores).
  • Sin SMTP configurado, el sistema degrada a modo dev: los correos de verificación/recuperación se loguean en la consola del backend en vez de enviarse (nunca rompe el flujo).

Regla de UX para pantallas

  • No mezclar listado y formulario de creación en la vista inicial de un módulo.
  • Primero el listado; botón "Nuevo" abre creación.
  • Detalle abre en modo lectura; "Editar" habilita campos; "Cancelar" vuelve a lectura sin guardar; guardar solo si hubo cambios reales.
  • Secciones de una misma entidad (Proyecto: Info/Actividades/Gantt/Calendario/Comentarios/Documentos) van en pestañas reales, nunca apiladas ni navegando a otra pantalla.

Flujos criticos

  1. Login → Dashboard con KPIs del usuario.
  2. Crear proyecto → asignar miembros → crear actividades → crear subtareas → avance se recalcula solo.
  3. Actividad vencida o por vencer → notificación in-app al responsable.

Entorno operativo

  • Desarrollo: npm run dev en backend/ (puerto 4019) y frontend/ (puerto 5196, proxy /api).
  • Producción: operativo en https://project.linkedcorp.net (servidor 192.168.222.3, arquetipo B, ver PRODUCCION.md y DEPLOY_WEB.md).
  • Docker por defecto: no.

Regla de versionado

  • Versionado X.Y.Z (ver VERSIONADO.md).
  • Antes de producción, validar si corresponde subir versión.
  • Toda versión nueva se refleja en VERSION y CHANGELOG.md.

Documentacion relacionada

  • README.md, SPEC.md, BASE_DE_DATOS.md, CONFIGURACION.md, API.md, VERSIONADO.md
  • PRODUCCION.md, DEPLOY_WEB.md (topología y flujo de deploy — arquetipo B, en producción)
  • docs/UI-UX-WINDOWS.md, docs/SEGURIDAD-Y-CALIDAD.md
  • ESTADO.md (handoff — leer siempre al retomar el proyecto)

Pendientes para quedar listo

  • Fase 2: riesgos/incidencias como módulos propios, solicitudes formales, recursos/proveedores, presupuesto y costos, registro de horas detallado, reportes exportables (PDF/Excel/CSV), permisos configurables por módulo×acción, notificaciones por email.
  • Limpiar .md del source en producción (find ... -iname '*.md' -delete) — pendiente, ver ESTADO.md.