6066f27ba0
Menu Calendario (Mes/Semana/Dia/Agenda) para agendar reuniones con participantes internos y externos, RSVP, vinculo a proyecto, vencimientos de actividades, invitaciones iCalendar por correo, recurrencia con excepciones, recordatorios in-app y aviso de choques. Migracion 034_meetings.sql. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
16 KiB
16 KiB
ESTADO — project.linkedcorp.net
Ultima actualizacion: 2026-10-27 (v4.4.0 en desarrollo, sin desplegar)
Fase actual: En produccion (https://project.linkedcorp.net, v1.1.0). MVP fase 1 operativo +
autorregistro/aprobacion/SMTP.
Calendario de reuniones (v4.4.0, sin desplegar)
- Menú y API de reuniones, recurrencia, RSVP, vencimientos de actividades, correo iCalendar y
recordatorios in-app implementados en código.
DELETEmarca cancelada toda la serie. - Migración
034_meetings.sqlaplicada en dev (2026-10-27), no en producción. Aplicarla antes de arrancar el backend 4.4.0 en prod. El backend de dev en :4019 sigue con el código anterior hasta reiniciarlo. - Probado en dev con instancia temporal (4099/5197, datos de prueba ya borrados): alta, choque con confirmación, validaciones, expansión semanal, rango máx. 93 días, edición con versión (409), cancelar ocurrencia (EXDATE/RECURRENCE-ID), cancelar serie (METHOD:CANCEL), RSVP solo participante (aviso in-app al organizador), recordatorio in-app a tiempo, UI escritorio/móvil sin errores de consola. Pendiente: probar envío real con SMTP (dev no tiene SMTP → log).
Auditoría de seguridad y calidad (v3.0.0, sin desplegar)
- Se corrigieron controles de roles, alcance de búsqueda y tareas recurrentes, bootstrap concurrente, subida de logo/adjuntos, censura de tokens en logs de la app, revocación JWT, límites de ingesta, correo, paginación y accesibilidad base.
- Migraciones nuevas
028_session_version.sqly029_optimistic_versions.sql: no aplicadas. El backend nuevo requiere ambas antes de arrancar con una base existente. Tras028, los JWT anteriores dejan de funcionar y se debe iniciar sesión otra vez. GET /api/projectsahora devuelve{items,total,page,pageSize}. El frontend de esta versión se adaptó; otros clientes deben hacerlo.POST /api/attachmentsrequiere entidad en query.- Pendiente: vinculación token de inventario a equipo (instaladores actuales comparten token),
medición SQL
EXPLAINcon datos reales. Hallazgo 7: falta verificar los logs del proxy NPM para confirmar la censura de tokens; pendiente operativo, sin tocar NPM. Hallazgo 11: vincular token de inventario a equipo requiere migrar las instalaciones que comparten token; pendiente operativo. No se consultó la BD ni producción durante esta tarea. - Hallazgo 16 completo en código: edición con versión optimista para proyectos, comentarios, actividades, tareas, departamentos, usuarios, los cuatro catálogos, notas, tareas recurrentes, equipos, empresa y SMTP. La migración 029 se amplió; sigue sin aplicar.
Sesiones activas y Mi cuenta (v4.3.0, sin desplegar)
- Migración
033_user_sessions.sqlaplicada en dev (2026-10-26), no en producción. Aplicarla antes de arrancar el backend nuevo; al desplegar, todos inician sesión una vez (JWT sinsid). - Probado en dev contra una instancia temporal (puerto 4099, usuario de prueba ya borrado): listar,
cerrar una/las demás/todas, cambio de clave (mantiene la actual), logout real, token sin
sid, admin vs superadmin. El backend de dev en :4019 sigue con el código anterior hasta reiniciarlo.
Como retomar
Actualizador v3.0.1: el script publica logs/update.status; el panel espera su fin y comprueba
las versiones activas de backend y version.json del frontend antes de activar el Service Worker
y recargar. Pendiente verificar el flujo completo en un despliegue autorizado; no se tocó producción.
- Leer primero el orquestador:
/home/mgonzalez/desarrollo/project-md-templates/leeme_primero.txt. - Leer
AGENTS.md,SPEC.md,PRODUCCION.mdy este archivo. - Backend dev:
cd backend && npm install && npm run dev(puerto 4019). Requierebackend/.env(no versionado — completar con las credenciales de la BD devproject_linkedcorpen192.168.222.20; la clave la tiene el usuario). - Frontend dev:
cd frontend && npm install && npm run dev(puerto 5196, proxy/apial backend). - Login dev:
mgonzalez@linkedcorp.net/ clavemgonzalez(rol Administrador). Login de producción: mismo email, clave fuerte generada porcreate-admin.js(no está en este repo, se entregó al usuario al desplegar). - Produccion: ver
PRODUCCION.mdyDEPLOY_WEB.mdpara topología, comandos y el flujo de deploy de actualizaciones (arquetipo B, dos servicios systemd en192.168.222.3).
Hecho y verificado
Menú Equipos (v2.15.0, 2026-10-19) — EN DESARROLLO, NO DESPLEGADO
- Inventario de TI con agente GLPI oficial; diseño traído de linkedtrack (que sigue aparte, sin
tocar):
docs/ARQUITECTURA-INVENTARIO.md. Backendmodules/devices/(ingest, normalizer, repository, service, routes), migración023aplicada en dev, frontendpages/Equipos/. - Verificado con inventarios sintéticos JSON y XML (alta, actualización, diff, 401 sin token,
handshake
contact). Pendiente: probar con un agente GLPI real (ver "Pendientes" del doc de arquitectura) y ajustarnormalizer.js/handshake según el JSON real. - Antes de producción: migración 023 en
.32,npm install(fast-xml-parser), confirmar que NPM deja pasarPOST /api/inventorydesde la red de los equipos y subir versión/deploy.
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_pctverificado. - 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 enproject-md-templates/UI-UX-WINDOWS.md.- Bug de stacking corregido:
ContentDialogahora usa portal adocument.body(antes quedaba tapado detras de unDetailPopupabierto). 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 aif (!data)— solo bloquean la carga inicial. - Bug de clipping corregido:
ComboBox(yFlyout) se posicionan con portal +position:fixedcalculado desde el trigger — antes un ancestro conoverflow:hidden(Expander, DetailPopup) los recortaba. Regla documentada enUI-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_linkedcorpcreada en192.168.222.32(prod) concrear-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 concreate-admin.js. - Servicios systemd
project-linkedcorp-backend(4019) yproject-linkedcorp-frontend(5196,serve -s dist), ambosenabled+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 enPRODUCCION.md. - Pendiente no bloqueante: limpiar
.mdde/opt/apps/project.linkedcorp.net/source(paso de higiene deDEPLOY_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: rolsuperadmin, columnas de ciclo de vida enusers(status, tokens de verificación/recuperación), tablasystem_settings. El usuario más antiguo (id=1, creado porcreate-admin.jsantes de este feature) se promovió solo asuperadmin. POST /api/auth/register: primer usuario del sistema →superadmincon 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 aadmin/superadmin.admin/superadminaprueban (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únstatus(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) ensystem_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 paraforgot-password, que debe responder genérico siempre). - Bug real corregido:
React.StrictModedisparaba el efecto deVerifyEmailPagedos 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 surequireAuthinterno 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.
- Desplegado a producción el mismo día: migración
002aplicada sobre.32, ambos servicios reconstruidos y reiniciados (PID confirmado), verificado via curl contrahttps://project.linkedcorp.net(login reportasuperadmin,GET /api/settings/smtprespondeconfigured:false). Detalle enPRODUCCION.md→ "Actualización v1.1.0". - Pendiente real: el superadmin de producción debe cargar el SMTP real desde Configuración → Correo (SMTP) — sin eso, nadie externo puede completar el autorregistro en producción (el enlace de verificación solo queda logueado en el servidor, no llega por correo de verdad).
Cambiar clave desde la app (v1.2.0, 2026-09-06)
PUT /api/auth/change-password(exige la clave actual, valida clave nueva ≥ 8 caracteres) + opción "Cambiar clave" en el menú de usuario (popup), para cualquier usuario logueado — independiente de "olvidé mi clave", que es para cuando no se puede iniciar sesión.- Desplegado a producción el mismo día; verificado via curl que rechaza clave actual incorrecta con 400 (no se tocó la clave real del superadmin durante la prueba).
Boton de prueba real en Correo (SMTP) (v1.3.0, 2026-09-06)
- El usuario reportó, con razón, que la pantalla de SMTP no tenía forma de confirmar que la configuración guardada funcionara de verdad (sin botón de prueba ni campo de destinatario) — una omisión básica para una pantalla de config de un servicio externo.
POST /api/settings/smtp/test(superadmin, rate-limited a 10/15min): usa los valores actuales del formulario (aunque no se hayan guardado, cae a la clave ya guardada si el campo viene vacío) y hace un envío real. A diferencia desendMail()(correo de negocio, nunca lanza), este endpoint sí propaga el error real del servidor SMTP — es diagnóstico explícito del superadmin.- Panel de Configuración → Correo (SMTP): nueva sección "Probar configuración" con campo de destinatario, botón "Enviar prueba" y resultado real (éxito o el mensaje de error tal cual).
- Verificado en dev con curl (400 sin host/usuario) y Playwright (formulario + envío real contra
el SMTP interno con credenciales falsas → error real "certificate has expired" mostrado en la
UI). Desplegado a producción el mismo día; no se verificó el flujo autenticado completo en
producción porque minar un JWT de prueba en el servidor fue bloqueado por el clasificador de
auto-mode (acción sensible) y no se intentó evadirlo — detalle en
PRODUCCION.md. - Regla nueva agregada al orquestador (
project-md-templates/SEGURIDAD-Y-CALIDAD.md, sección 1.6bis + checklist): toda pantalla de configuración de un servicio externo debe incluir un botón de prueba real, para que esta clase de omisión no se repita en este ni otros proyectos.
Pendiente (fase 2, sin comprometer lo ya construido)
- Riesgos e Incidencias como modulos propios (hoy:
risk_levelsimple 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 por accion dentro de cada modulo (hoy: acceso por modulo y usuario desde v3.1.0 + roles fijos codificados).
- IA (hecho hasta v4.2.0: config, "Plan con IA", "Nuevo con IA" con duplicados, consumo por usuario, "Informe con IA"). Ideas siguientes: resumen semanal del Panel, detector de riesgos, resumir comentarios en tareas, dividir tareas grandes, responsables por actividad entre miembros.
- 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.jssolo carga catalogos universales (roles/prioridades/estados/tipos) cuandoNODE_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 concreate-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
superadminautomatico; 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 enqs/body-parser, transitivas de Express 4.x (sin fix no-breaking disponible al 2026-09-06). No critico; revisar cuando Express publique el fix.