Files
project.linkedcorp.net/ESTADO.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

135 lines
9.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ESTADO — project.linkedcorp.net
Ultima actualizacion: 2026-09-06
Fase actual: **En produccion** (`https://project.linkedcorp.net`, v1.1.0). MVP fase 1 operativo +
autorregistro/aprobacion/SMTP.
## Como retomar
1. Leer primero el orquestador: `/home/mgonzalez/desarrollo/project-md-templates/leeme_primero.txt`.
2. Leer `AGENTS.md`, `SPEC.md`, `PRODUCCION.md` y este archivo.
3. Backend dev: `cd backend && npm install && npm run dev` (puerto 4019). Requiere `backend/.env`
(no versionado — completar con las credenciales de la BD dev `project_linkedcorp` en
`192.168.222.20`; la clave la tiene el usuario).
4. Frontend dev: `cd frontend && npm install && npm run dev` (puerto 5196, proxy `/api` al backend).
5. Login dev: `mgonzalez@linkedcorp.net` / clave `mgonzalez` (rol Administrador). Login de
**producción**: mismo email, clave fuerte generada por `create-admin.js` (no está en este repo,
se entregó al usuario al desplegar).
6. Produccion: ver `PRODUCCION.md` y `DEPLOY_WEB.md` para topología, comandos y el flujo de deploy
de actualizaciones (arquetipo B, dos servicios systemd en `192.168.222.3`).
## Hecho y verificado
### Fase 1 — MVP en desarrollo (2026-09-03)
- Backend completo: auth (JWT + rate limit), users, departments, catalogs, projects (+members),
activities (+dependencies), subtasks, comments, attachments, notifications, dashboard, audit.
Recalculo automatico de `progress_pct` verificado.
- Frontend completo: identidad Fluent/Windows adaptada a web — NavigationView, ContentDialog,
InfoBar, Toast, Flyout, ListView, ComboBox, Treeview, Tabs, Expander. Paginas: Login, Dashboard,
Proyectos (listado + detalle), Organizacion, Configuracion. i18n es-EC/en-US, tema claro/oscuro.
- Verificacion end-to-end con Playwright sin errores de consola.
### Iteraciones de UI/UX (2026-09-03 al 2026-09-05)
- `DetailPopup`: reemplaza el antipatron "formulario apilado debajo/al costado del listado" en
TODOS los listados de gestion (Proyectos, Actividades, Departamentos, Usuarios, Miembros,
Catalogos) — popup de tamaño fijo por instancia, listado inactivo detras, nunca se cierra con
clic afuera. Regla documentada en `project-md-templates/UI-UX-WINDOWS.md`.
- Bug de stacking corregido: `ContentDialog` ahora usa portal a `document.body` (antes quedaba
tapado detras de un `DetailPopup` abierto). Jerarquia de z-index: Flyout(100) < DetailPopup(200)
< ContentDialog(250) < Toast(300).
- Bug de remount corregido: las guardas `if (loading || !data) return <Cargando/>` desmontaban
TODA la pantalla (y el popup abierto dentro) en cada recarga en segundo plano. Cambiadas a
`if (!data)` — solo bloquean la carga inicial.
- Bug de clipping corregido: `ComboBox` (y `Flyout`) se posicionan con portal + `position:fixed`
calculado desde el trigger — antes un ancestro con `overflow:hidden` (Expander, DetailPopup) los
recortaba. Regla documentada en `UI-UX-WINDOWS.md`.
- "Miembros" del proyecto es su propia pestaña (antes vivia dentro de "Info").
- Logo real de LinkedCorp (`/desarrollo/imgLinkedCorp/logoLinkedCorpTxt(Black).png`) en sidebar y
login, theme-aware, tamaño duplicado respecto a la primera version.
### Deploy a produccion (2026-09-06)
- BD `project_linkedcorp` creada en `192.168.222.32` (prod) con `crear-db-prod.sh`.
- Servidor `192.168.222.3`: `/opt/apps/project.linkedcorp.net/{source,backend,frontend,storage,logs}`.
- Migraciones aplicadas; catalogos sembrados (`seed-db.js`, sin datos de ejemplo en produccion —
ver decision abajo); usuario Administrador inicial creado con `create-admin.js`.
- Servicios systemd `project-linkedcorp-backend` (4019) y `project-linkedcorp-frontend` (5196,
`serve -s dist`), ambos `enabled` + `active`.
- NPM: Proxy Host id 77 → frontend, Custom Location `/api` → backend, SSL Let's Encrypt forzado.
- Verificado end-to-end via curl contra `https://project.linkedcorp.net`: health check, login,
token valido. Detalle completo en `PRODUCCION.md`.
- **Pendiente no bloqueante**: limpiar `.md` de `/opt/apps/project.linkedcorp.net/source` (paso de
higiene de `DEPLOY_WEB.md`) — bloqueado por el clasificador de auto-mode del agente durante el
deploy; requiere ejecutarlo a mano o con autorizacion explicita la proxima vez.
### Autorregistro, aprobación, superadmin y SMTP (2026-09-06)
- Migración `002_registration_and_smtp.sql`: rol `superadmin`, columnas de ciclo de vida en `users`
(`status`, tokens de verificación/recuperación), tabla `system_settings`. El usuario más antiguo
(id=1, creado por `create-admin.js` antes de este feature) se promovió solo a `superadmin`.
- `POST /api/auth/register`: primer usuario del sistema → `superadmin` con sesión directa
(bootstrap); los siguientes → `pending_verification`, correo con enlace de un solo uso (24h).
- `GET /api/auth/verify-email` → `pending_approval` + notificación in-app a `admin`/`superadmin`.
- `admin`/`superadmin` aprueban (`POST /api/users/:id/approve`, eligen rol/departamento) o rechazan
(`POST /api/users/:id/reject`, borra y audita el email) desde Organización → Usuarios (nuevo badge
de estado + acciones de fila).
- `login()` da mensaje específico según `status` (pendiente de verificar / pendiente de aprobar)
en vez del genérico "credenciales inválidas".
- Recuperación de clave (`/olvide-clave` → `/restablecer-clave`): respuesta siempre genérica, token
de 1 hora de un solo uso.
- SMTP configurable desde Configuración → Correo (SMTP), **solo superadmin** (oculto para el resto);
clave cifrada AES-256-GCM (`ENCRYPTION_KEY`) en `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 envío tumbe al que lo llama (crítico para `forgot-password`, que debe responder
genérico siempre).
- Bug real corregido: `React.StrictMode` disparaba el efecto de `VerifyEmailPage` dos veces; la
segunda llamada (token ya consumido) mostraba "enlace inválido" pese a que la verificación había
funcionado. Se agregó una guarda por token ya solicitado.
- Deuda técnica de la v1.0.0 resuelta de paso: se reordenó el montaje de rutas en `app.js` —
`subtasksRoutes` (mount genérico en `/api`) ahora va al final, así ya no intercepta con su
`requireAuth` interno una request sin token dirigida a un router más específico (`/api/settings`,
etc.) registrado después.
- Verificado end-to-end en dev con Playwright: registro → correo logueado (modo dev) → login
rechazado (pendiente de verificar) → verificar correo → login rechazado (pendiente de aprobar) →
aprobar desde Usuarios → login exitoso → recuperar clave → login con clave nueva → panel SMTP
visible solo para superadmin. Sin errores de consola.
- **Pendiente**: desplegar esta versión a producción (migración `002` sobre `.32` + redeploy de
ambos servicios) — ver `DEPLOY_WEB.md`. El superadmin de producción deberá cargar el SMTP real
desde la UI cuando lo tenga; hasta entonces el sistema sigue en modo dev (logueando enlaces).
## Pendiente (fase 2, sin comprometer lo ya construido)
- Riesgos e Incidencias como modulos propios (hoy: `risk_level` simple en el proyecto).
- Solicitudes/requerimientos formales de otras areas.
- Recursos (servidores/licencias/software), Proveedores, Presupuesto y costos.
- Registro de horas trabajadas detallado (bitacora diaria).
- Reportes exportables (PDF/Excel/CSV) y vista ejecutiva separada.
- Permisos configurables por modulo × accion desde la UI (hoy: roles fijos codificados).
- Notificaciones por email/WhatsApp (hoy: solo in-app).
- Job programado para detectar actividades vencidas/por vencer (hoy: solo se notifica al asignar).
- DatePicker: sigue usando `<input type="date">` nativo (simplificacion deliberada del MVP).
- En producción, crear los departamentos/usuarios reales de la empresa desde la UI (arranca limpia
a proposito, ver decision abajo).
## Decisiones clave
- MVP simplificado respecto al listado original de 30 areas — detalle en `SPEC.md`.
- Identidad UI/UX: `UI-UX-WINDOWS.md` (Fluent/Windows 11), no la identidad web estandar del grupo.
- Empresa unica (single-company): no existe tabla `companies`.
- Arquetipo de despliegue B (dos servicios separados).
- Produccion arranca sin datos de ejemplo: `seed-db.js` solo carga catalogos universales
(roles/prioridades/estados/tipos) cuando `NODE_ENV=production`; los departamentos y usuarios de
ejemplo (TI/Finanzas/RRHH/Comercial, admin con clave=usuario) son SOLO de dev. El admin real de
produccion se crea con `create-admin.js` (clave fuerte generada, nunca clave=usuario).
- Autorregistro con doble candado (correo + aprobacion admin) — decision explicita del usuario,
revierte la regla inicial "sin autosuscripcion". El primer usuario del sistema es `superadmin`
automatico; el resto pasa por verificacion + aprobacion. SMTP vive en BD (cifrado), configurable
solo por el superadmin desde la UI, no en `.env`.
## Deuda tecnica
- `npm audit`: 3 vulnerabilidades moderadas en `qs`/`body-parser`, transitivas de Express 4.x (sin
fix no-breaking disponible al 2026-09-06). No critico; revisar cuando Express publique el fix.