# 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 ` 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 `` 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.