# Changelog - project.linkedcorp.net ## [2.8.0] - 2026-10-01 ### Added - Buscador en "Contraseñas": filtra las tarjetas mientras escribís, por nombre, usuario, enlace o **notas** — las notas están cifradas, así que se descifran solo en el servidor para comparar contra la búsqueda; el texto nunca viaja de vuelta al navegador salvo que coincida y entres a ver esa entrada puntual. ## [2.7.2] - 2026-10-01 ### Changed - "Contraseñas" pasa de tabla a tarjetas: cada una muestra un ícono (a elección, de un catálogo fijo — sin usar ningún servicio externo de favicon, por privacidad) o la inicial del nombre si no se elige ninguno, junto con el nombre y el enlace. ### Fixed - **Bug real**: editar una credencial sin antes revelar la contraseña la dejaba vacía al guardar (se borraba sin querer). Ahora, si no se escribe una contraseña nueva al editar, se conserva la que ya estaba guardada. ## [2.7.1] - 2026-10-01 ### Changed - "Contraseñas" vuelve a pedir el PIN cada vez que se sale del menú (a otro, o cerrando la pestaña) y se vuelve a entrar — antes quedaba desbloqueado el resto de la sesión del sistema. - Si el menú queda abierto sin atención, sale solo al Panel a los 3 minutos de haberse desbloqueado. ## [2.7.0] - 2026-10-01 ### Added - Nuevo menú "Contraseñas": repositorio personal de credenciales (nombre, enlace, usuario, contraseña, notas), siempre privado — nadie más lo ve, ni un superadmin. - Contraseña y notas cifradas en el servidor (AES-256-GCM, mismo mecanismo ya probado que usa la clave SMTP) — nunca en texto plano en la base de datos. - El menú pide un PIN de 4 dígitos para entrar, aparte de la clave de acceso normal al sistema (que no se toca). El PIN es un candado de acceso, no la clave de cifrado. Se puede cambiar desde el propio menú, o restablecer por correo si se olvida — restablecerlo nunca borra ni afecta las contraseñas ya guardadas, solo cambia el candado. - Generador de contraseñas al crear una entrada nueva. - Queda registrado en el log de auditoría cada vez que se crea, edita, elimina o **revela** una contraseña guardada, y cada desbloqueo del candado. - Compartir una entrada con otro usuario queda para una próxima versión. ## [2.6.1] - 2026-09-30 ### Fixed - **Bug real en el botón "Actualizar" (auto-actualización)**: el paso final reiniciaba backend y frontend con un solo comando (`systemctl restart back front`), pero el permiso sudo sin contraseña solo está autorizado para cada servicio por separado — el reinicio fallaba en silencio (sin romper el resto del proceso) y el backend se quedaba con el código viejo indefinidamente, aunque el panel ya mostrara "actualizado". El frontend sí se veía al día porque no necesita reiniciar el proceso para servir archivos nuevos — por eso el síntoma era confuso (la UI nueva se veía, pero funciones nuevas del backend faltaban). Se separa en dos comandos `sudo systemctl restart` — uno por servicio. ## [2.6.0] - 2026-09-30 ### Changed - Listado de Proyectos: el porcentaje de avance ahora va **dentro** de la barra de progreso (antes iba aparte, a la derecha) y el fondo de la barra pasa a un gris visible sobre el fondo oscuro (antes casi no se notaba). Libera espacio horizontal en la fila. ### Added - Ícono de "compartido" en el listado de Proyectos: aparece solo si el proyecto tiene otros usuarios además del dueño. Al hacer clic muestra con quién está compartido y su permiso (Lectura/Escritura). ## [2.5.0] - 2026-09-25 ### Fixed - **Bug de seguridad real**: cualquier usuario autenticado veía TODOS los proyectos del sistema (listado, detalle, actividades, tareas, comentarios y adjuntos), sin importar si era miembro. Ahora nadie ve un proyecto ajeno a menos que su dueño se lo comparta — los roles de administración (superadmin/admin/it_manager) siguen viendo todo, para poder dar soporte. ### Added - **Compartir proyectos**: solo el dueño del proyecto puede compartirlo (ni un admin del proyecto ni un rol global pueden hacerlo por él). Dos niveles simples: **Lectura** (solo ver) y **Escritura** (crear/editar/eliminar actividades y tareas del proyecto — nunca el proyecto en sí: no puede borrarlo, ni editar sus datos, ni crear proyectos nuevos). - **Papelera de actividades**: eliminar una actividad o tarea ahora es recuperable (antes se borraba físico, sin vuelta atrás) — el dueño del proyecto puede restaurarlas desde un nuevo botón "Papelera de actividades" en la pestaña Actividades. - Panel principal (KPIs, calendario, "mis actividades pendientes"): mismo criterio de visibilidad que el listado de proyectos — ya no cuenta ni muestra información de proyectos ajenos para roles sin acceso total. - Filtro "Usuario" en Proyectos (junto a Estado/Prioridad), visible solo para superadmin/admin/it_manager — filtra el listado por dueño. Se había probado solo en dev; se incluye en esta versión al ir de la mano con el resto de este cambio. ## [2.4.0] - 2026-09-22 ### Fixed - Menú lateral en celular: antes quedaba siempre visible fijo, ocupando gran parte de una pantalla angosta. Ahora arranca oculto, se abre como un panel superpuesto (con fondo oscuro detrás) desde el botón de hamburguesa, y se cierra solo al elegir una opción o tocar afuera. El escritorio no cambia — sigue con el sidebar fijo y el modo compacto de siempre. ## [2.3.0] - 2026-09-22 ### Added - Al iniciar sesión, si sos superadmin y hay una actualización pendiente, aparece un aviso con un acceso directo al panel de Actualizaciones (abre Configuración con ese panel ya desplegado). ## [2.2.4] - 2026-09-22 ### Fixed - El botón "Actualizar" se quedaba visible después de aplicar la actualización, hasta que se refrescaba la pestaña a mano. Ahora, mientras se aplica, el panel consulta el estado cada pocos segundos y en cuanto confirma que ya quedó en la última versión, el botón desaparece solo (sin depender de la recarga automática del service worker). ## [2.2.3] - 2026-09-22 ### Fixed - Al actualizar (ya sea con el botón nuevo o por deploy manual), la pestaña abierta seguía mostrando JS/CSS viejo hasta hacer F5 a mano, aunque el servidor ya tuviera la versión nueva — el service worker tomaba control solo pero no refrescaba la página. Ahora se refresca sola en cuanto el service worker nuevo toma control. ## [2.2.2] - 2026-09-22 ### Fixed - El botón "Actualizar" fallaba en el build del frontend: heredaba `NODE_ENV=production` del backend, y con eso `npm install` salta las dependencias de desarrollo (incluida `vite`), asi que el build nunca corría y el sistema quedaba en la versión vieja sin avisar del error. Se fuerza `--include=dev` en ese paso puntual. ### Changed - Tamaño de los logos de la barra lateral: el de la empresa que usa el sistema (arriba) se duplica; el de LinkedCorp, desarrollador del sistema (abajo), se reduce a la mitad. ## [2.2.1] - 2026-09-22 ### Changed - Marca de versión sin cambios de código: primer uso real del botón "Actualizar" (auto-update) en el servidor de exilaser, ya con el feature habilitado desde la v2.2.0. ## [2.2.0] - 2026-09-22 ### Added - Botón "Actualizar" real en Configuración → Actualizaciones: aplica la actualización sola (backup de BD, `git pull`, migraciones, build, reinicio de servicios) en vez de solo avisar. **Apagado por defecto** — solo aparece en un servidor donde el admin configuró explícitamente `UPDATE_APP_DIR`/`UPDATE_BACKEND_SERVICE`/`UPDATE_FRONTEND_SERVICE` en `backend/.env` y le dio al usuario `deploy` permiso sudo acotado para reiniciar esos dos servicios puntuales. Sin esa configuración, el panel sigue funcionando exactamente igual que antes (solo informa). - Nuevo `scripts/apply-update.sh`: hace el trabajo real, corre desde una copia fuera de `source/` (nunca desde adentro, porque el propio script hace `git reset --hard` sobre `source/` mientras se ejecuta). ## [2.1.0] - 2026-09-22 ### Added - Nuevo espacio de marca en la barra lateral (arriba a la izquierda): si el sistema tiene un logo de empresa configurado (Configuración → Empresa), aparece ahí. El logo "LinkedCorp" de abajo ya no es configurable — es fijo, identifica siempre al desarrollador del sistema, independiente de qué empresa lo use. ## [2.0.2] - 2026-09-22 ### Changed - Instalación nueva en servidor de exilaser (`192.168.0.30`, `project.exilaser.net`): stack completo (backend + frontend + MariaDB local) con todo el contenido de producción de LinkedCorp migrado (proyectos, actividades, tareas, usuarios). Instancia independiente, con su propia `ENCRYPTION_KEY`/`JWT_SECRET` — el SMTP debe reconfigurarse desde Configuración. ## [2.0.1] - 2026-09-17 ### Changed - Version marcada como 2.0.1 (sin cambios de código) para el proceso de instalación en un servidor nuevo (Debian 12) — no representa una ruptura de compatibilidad real, es solo el punto de partida acordado para esa instalación. ## [1.23.0] - 2026-09-17 ### Added - Menú "Notas" nuevo: apuntes rápidos y simples, siempre privados de cada usuario (nadie más los ve). Crear, editar y eliminar, con fecha y hora de creación (y de última edición, si aplica). Sin permisos especiales — cualquier usuario autenticado tiene los suyos. - Nuevo `notes` (tabla) + `GET/POST/PUT/DELETE /api/notes`. ## [1.22.0] - 2026-09-17 ### Added - La app ahora es instalable desde el navegador (PWA): ícono propio, se abre en su propia ventana sin barra del navegador, con `manifest.webmanifest` + service worker (`vite-plugin-pwa`). El service worker precachea solo los assets estáticos del build (JS/CSS/íconos) — las llamadas a `/api` nunca se cachean, siempre van a la red, así los datos nunca quedan desactualizados. Se actualiza solo (`autoUpdate`) en cuanto hay una versión nueva desplegada, sin pedirle nada al usuario. - Íconos nuevos generados a partir del logo actual: `pwa-192x192.png`, `pwa-512x512.png` y una versión "maskable" (con zona de seguridad) para Android. ## [1.21.1] - 2026-09-17 ### Added - Filtro por severidad (Alta/Media/Baja) en el panel "Errores del sistema", además del filtro por origen ya existente. La severidad se asigna sola, sin etiquetar nada a mano: errores de backend y errores de render de React (rompen toda la pantalla) = Alta; errores JS sueltos = Media; promesas rechazadas sin manejar = Baja (suelen ser fallos de red puntuales, no críticos). ## [1.21.0] - 2026-09-17 ### Added - Log de errores para el administrador, panel nuevo en Configuración ("Errores del sistema", solo superadmin): lista errores de backend (excepciones 500 no manejadas, con stack completo, ruta, método y usuario si estaba logueado) y de frontend (errores JS y promesas sin `catch` en el navegador del usuario, capturados automáticamente — antes solo aparecían en la consola del navegador de esa persona, invisibles para cualquier otro). Filtro por origen y botón para limpiar el historial. - Error Boundary de React: si algo rompe el render de la app, ya no queda una pantalla en blanco — se muestra un aviso simple con botón para recargar, y el error queda reportado igual. - Nuevo `error_logs` (tabla + `GET/DELETE /api/error-logs`, solo superadmin) y `POST /api/error-logs` (público, con rate-limit, para que el frontend pueda reportar incluso sin sesión — ej. en la pantalla de login). ## [1.20.0] - 2026-09-17 ### Added - Convertir una actividad en proyecto (menú de tres puntos en el listado de Actividades). Como una tarea siempre necesita una actividad contenedora, se crea un proyecto nuevo y, dentro, una actividad nueva que recibe las tareas — y comentarios/documentos — de la actividad original; se piden ambos nombres (proyecto y actividad, precargados con el nombre actual) antes de confirmar. La actividad original se elimina al final, ya vacía de tareas. Nuevo endpoint `POST /api/activities/:id/convert-to-project`, exige el mismo permiso que crear un proyecto. ## [1.19.0] - 2026-09-16 ### Added - Panel "Actualizaciones" en Configuración (solo superadmin): compara la versión instalada contra el `CHANGELOG.md` de `main` en Gitea y muestra cada versión pendiente con su criticidad (deriva del dígito que cambió — 1ro=Alta, 2do=Media, 3ro=Baja, sin etiquetar nada a mano), una descripción breve, y si trae cambios de base de datos (comparando los archivos de `backend/database/migrations/` locales contra los de `main`). Banner en rojo, siempre visible si hay algo pendiente, avisando que la actualización requiere reiniciar el sistema. No instala nada automáticamente — solo informa; aplicar la actualización sigue siendo manual (SSH), a criterio del administrador de cada instalación. - Nuevo endpoint `GET /api/updater/status` (solo superadmin). Lee el repo de Gitea de forma anónima por HTTPS — no requiere ningún token ni credencial en el server instalado, solo que el repo sea público y el servidor de Gitea permita vista anónima. ## [1.18.0] - 2026-09-16 ### Added - Buscador de Proyectos ahora también busca en actividades y tareas de cualquier proyecto, no solo el nombre/código del proyecto. Los resultados aparecen en un panel bajo el buscador con la ruta completa ("Proyecto - Actividad - Tarea"); al hacer clic navega directo al proyecto y abre la actividad encontrada (la pestaña "Tareas" si el resultado era una tarea). - Buscador de Actividades (dentro de un proyecto) también busca en las tareas de esa actividad, mismo panel de resultados con "Actividad - Tarea". - Nuevo endpoint `GET /api/search?q=...&projectId=` (global o acotado a un proyecto). ## [1.17.0] - 2026-09-16 ### Added - Mover una actividad a otro proyecto (menú de tres puntos en el listado de Actividades): se eligen el proyecto destino y se confirma con un mensaje ("Se moverá la actividad "X" (junto con sus tareas) al proyecto "Y". ¿Deseas continuar?", Aceptar/Cancelar) antes de ejecutar. Tareas, comentarios y adjuntos se mueven solos (referencian la actividad, no el proyecto). Las dependencias existentes se eliminan al mover (solo tienen sentido dentro del mismo proyecto). Nuevo `PUT /api/activities/:id/move`, exige permiso de escritura en ambos proyectos. ## [1.16.4] - 2026-09-16 ### Added - Columna "Actualizado" (fecha y hora) en el listado de Actividades de un proyecto — mismo formato que ya existía en Proyectos. Ordenable por columna igual que el resto; no se cambió el orden por defecto (sigue siendo el orden manual arrastrado con el mouse), así se puede ver la fecha sin perder el reordenamiento manual como vista predeterminada. ## [1.16.3] - 2026-09-16 ### Fixed - Arrastrar tareas para reordenar dejó de funcionar tras el fix del checkbox (v1.15.2): al mover `draggable`/`onDragStart` del icono de agarre directamente sobre el `` (huecos entre sus formas — un SVG solo capta el mousedown sobre lo pintado, no sobre todo su recuadro), el navegador no siempre detectaba el inicio del arrastre. Corregido envolviendo el icono en un `` con área de agarre sólida (mismo patrón ya usado en el listado de Actividades). ## [1.16.2] - 2026-09-16 ### Changed - El contador de la pestaña "Tareas" pasa de mostrar solo las pendientes a "pendientes/total" (ej. "2/3") — Comentarios y Documentos siguen mostrando el total simple. Se actualiza solo al agregar, quitar o marcar/desmarcar tareas. ## [1.16.1] - 2026-09-16 ### Changed - Color del contador en las pestañas (Tareas/Comentarios/Documentos): de azul (accent) a rojo (danger), misma intensidad — pedido explícito del usuario. ## [1.16.0] - 2026-09-16 ### Added - Contador en un circulo junto al nombre de la pestaña, dentro del detalle de una actividad: "Tareas" muestra las tareas pendientes (sin marcar como hechas), "Comentarios" y "Documentos" muestran el total. Se oculta cuando el contador es 0. Soporte agregado al componente `Tabs` reutilizable (`tab.count`), disponible para cualquier otra pantalla que use pestañas. ## [1.15.2] - 2026-09-16 ### Fixed - El checkbox de "hecho" de una tarea (y el renombrado en linea) dejaba de reflejarse tras guardar: `useDragReorder` (hook de arrastrar-para-reordenar, introducido en v1.14.0) resincronizaba su copia local solo cuando cambiaba el CONJUNTO de ids, no cuando se editaba un campo de una tarea ya existente (marcar hecho, renombrar) — la fila se quedaba mostrando el snapshot viejo para siempre. Reportado por el usuario ("no se marca, debe ser por el drag de mover tareas") — tenia razon en que era el drag, aunque la causa real no era la interferencia del arrastre con el click sino esta resincronizacion incompleta. Corregido comparando el contenido completo, no solo los ids. - De paso, separado `draggable`/`onDragStart` (antes en toda la fila) para que vivan SOLO en el icono de agarre (`GripVertical`), nunca en la fila completa: un ancestro `draggable=true` le gana el mousedown a los controles interactivos que tenga adentro en algunos navegadores. No era la causa de este bug puntual, pero es una corrección real y necesaria para que el patrón sea seguro de reutilizar en cualquier lista futura con controles interactivos en la fila. ## [1.15.1] - 2026-09-15 ### Added - `scripts/install.sh`: instalador para desplegar en un servidor nuevo. Verifica requisitos (Node.js, npm, cliente mysql, systemd, espacio, puertos), pregunta dominio/puertos y base de datos (MariaDB local auto-instalada o un servidor existente), genera `backend/.env` con secretos aleatorios, corre migraciones + catálogos, compila el frontend y crea/arranca los servicios systemd. No crea ningún usuario — el primer registro público se vuelve superadministrador solo (bootstrap ya existente). ### Fixed - Migración `006_seed_it_baseline.sql` fallaba (error de foreign key) al correr sobre una base de datos nueva/vacía, porque insertaba proyectos de ejemplo específicos de LinkedCorp asumiendo catálogos y un usuario ya existentes. Encontrado probando el instalador de punta a punta contra una BD recién creada. Ahora detecta si esos prerequisitos no existen (instalación nueva, otra empresa) y queda inerte para siempre ahí, sin afectar el comportamiento ya probado en dev/prod (donde el marcador de "ya aplicado" sigue intacto). ## [1.15.0] - 2026-09-15 ### Added - Marca de la empresa configurable: nombre y logo editables desde Configuración → Empresa (solo superadmin), guardados en `system_settings` (mismo patrón que SMTP, sin tabla nueva). Nuevo endpoint público `GET /api/company` (+ `/logo`) para que login/registro/recuperación de clave puedan mostrar la marca antes de iniciar sesión. Sin configurar, se ve "LinkedCorp" y el logo estático de siempre — no rompe instalaciones existentes. - **Solo desplegado en desarrollo por pedido explícito del usuario** (no se tocó producción esta vez) — queda commiteado para poder retroceder/avanzar por git antes de decidir el despliegue. ## [1.14.1] - 2026-09-15 ### Fixed - El pie del menú lateral mostraba siempre el texto fijo "v0.1.0" en vez de la versión real de la app (se lee ahora de `package.json` del frontend). ### Changed - El logo de LinkedCorp en el menú lateral pasa de la parte superior a la parte inferior izquierda, justo encima del número de versión. ## [1.14.0] - 2026-09-15 ### Added - Arrastrar con el mouse para reordenar: actividades (dentro de un proyecto) y tareas (dentro de una actividad), ambas con el mismo mecanismo — un hook reutilizable (`useDragReorder`, drag & drop nativo, sin librería nueva) usado tanto en `ListView` (opt-in vía `onReorder`, deshabilitado mientras haya un ordenamiento por columna activo) como en el listado de tareas. Orden persistido (`sort_order` en `activities`/`tasks`, migración `012`, posiciones 1..N). ## [1.13.0] - 2026-09-15 ### Added - Eliminar actividad: `DELETE /api/activities/:id` (no existía) + botón "Eliminar" en el listado de actividades, con popup de confirmación. Si la actividad tiene tareas, se bloquea con un mensaje claro ("Esta actividad tiene N tarea(s). Elimina primero las tareas antes de borrar la actividad.") en vez de borrar en cascada silenciosamente. ### Changed - Adjuntos: la lógica de borrar archivo + fila (antes solo inline en el controller) se movió a un nuevo `attachments/service.js` reutilizable, usado tanto por el borrado individual como por el borrado en cascada al eliminar una actividad (evita archivos huérfanos en disco). ## [1.12.5] - 2026-09-14 ### Changed - Listado de Proyectos: columna "Creado" reemplazada por "Actualizado" (fecha y hora), y es ahora el orden por defecto — el proyecto tocado más recientemente aparece primero. ## [1.12.4] - 2026-09-14 ### Added - Botón "Editar" (lápiz) en cada tarea de una actividad — el backend ya soportaba renombrar una tarea (`PUT /api/tasks/:id`), solo faltaba el botón en la UI. Edición en línea (input + guardar con Enter o el ícono, cancelar con Escape o el ícono). ## [1.12.3] - 2026-09-14 ### Added - Fecha del documento en la lista de Documentos (proyecto/actividad) — el dato ya lo devolvía el backend, solo faltaba mostrarlo junto a quién lo subió y el tamaño. ## [1.12.2] - 2026-09-14 ### Fixed - El icono nativo de calendario en campos `type="date"`/`time`/`datetime-local` salía negro sobre fondo oscuro en tema oscuro (invisible). Se agrega `color-scheme: dark` a esos inputs cuando `data-theme="dark"`, para que el navegador dibuje el icono en un tono claro. ## [1.12.1] - 2026-09-11 ### Added - Tareas recurrentes: campo opcional "Hasta" (fecha de fin). Vacío = se repite sin fin (como hasta ahora). Al completar un ciclo cuyo próximo vencimiento supera "Hasta", la tarea se desactiva sola — no requiere acción manual. ## [1.12.0] - 2026-09-11 ### Added - **Tareas recurrentes**: menú propio en la barra lateral, independiente de Proyectos. Cada tarea recurrente tiene periodicidad configurable (cada N días/meses/años), próximo vencimiento, responsable y proyecto de origen opcional. "Completar ciclo" avanza el próximo vencimiento sumando la periodicidad. Recordatorio por correo automático N días antes del vencimiento (configurable, default 7) a una hora del día configurable — un job en el propio proceso del backend revisa cada 15 minutos, sin infraestructura nueva. - Desde la pestaña "Tareas" de una actividad, cada tarea puntual tiene un botón "Convertir en recurrente" que la promueve a una tarea recurrente (la tarea original no se borra). ## [1.11.0] - 2026-09-11 ### Added - Filtros en el listado de Proyectos: Estado, Prioridad (ambos ya soportados por el backend, solo faltaba exponerlos en la UI) y "Solo próximos a vencer" (checkbox, ventana de 7 días — misma definición que el KPI del dashboard). ## [1.10.0] - 2026-09-11 ### Added - Ordenar proyectos por Prioridad ahora usa la severidad real (Baja→Media→Alta→Crítica), no el orden alfabético del texto. El resto de columnas (Nombre, Estado, Creado, etc.) ya se podían ordenar con clic en el encabezado — no era nuevo, solo Prioridad tenía este detalle. ### Changed - "Páginas web y dominios" separada en dos tareas dentro de "Inventario de servicios de tecnología": "Páginas web" y "Dominios". ## [1.9.3] - 2026-09-11 ### Added - Nueva actividad en Infraestructura y redes: "Inventario de servicios de tecnología", con 8 tareas propuestas como checklist inicial (internet corporativo, páginas web/dominios, certificados SSL, correo/SMTP, nube, SaaS de terceros, telefonía/VoIP, respaldos). ## [1.9.2] - 2026-09-11 ### Changed - "Revision periodica de equipos" (Gestión de equipos y activos de TI) renombrada a "Revisión de equipos para verificar obsolescencia y mejoras" — dejaba dudas sobre qué cubría. - Nueva actividad en Infraestructura y redes: "Reponchado de cableado de red y certificación de los puntos". ## [1.9.1] - 2026-09-11 ### Changed - Migración de datos de una sola vez (`006_seed_it_baseline.sql`, con marcador en `system_settings` — nunca se repite en un deploy futuro): reemplaza el proyecto de prueba "Sistema ERP" por 6 proyectos reales de TI (Cumplimiento legal, Correos, Equipos, Credenciales y licencias, Infraestructura y redes, Mejoras a SAGA) con sus actividades, y da de baja la cuenta `pflores@hotmail.es` (autorregistro nunca verificado). Pedido explícito del superadmin. ## [1.9.0] - 2026-09-10 ### Added - Organización → Usuarios: ahora se puede "Rechazar" (eliminar) también a un usuario en `pending_verification` (autorregistro que nunca confirmó su correo) — antes esa acción solo existía para `pending_approval`, así que una cuenta abandonada antes de verificar el correo no tenía ninguna forma de quitarse desde la UI. ## [1.8.1] - 2026-09-10 ### Fixed - "Agregar dependencia" en una actividad no daba ninguna señal cuando no había otra actividad del proyecto disponible para elegir (proyecto con una sola actividad, o ya se agregaron todas) — el combo quedaba vacío, no se seleccionaba nada, y el botón hacía clic sin ningún efecto visible. Reportado como "el botón no hace nada". El mecanismo en sí funcionaba bien (verificado con curl y Playwright con 2+ actividades); ahora, cuando no hay opciones, se muestra un mensaje explicando por qué en vez del selector, y el botón queda deshabilitado si no hay nada seleccionado. ## [1.8.0] - 2026-09-10 ### Changed - Renombrado "Subtareas" a "Tareas" en todo el sistema (Actividad → Tarea, sin nivel "sub" intermedio): tabla `subtasks` → `tasks` (migración `005`, `RENAME TABLE` idempotente), módulo backend `subtasks/` → `tasks/`, rutas `/api/activities/:id/subtasks` → `/api/activities/:id/tasks` y `/api/subtasks/:id` → `/api/tasks/:id`, servicio frontend, pestaña dentro del detalle de actividad, i18n (es-EC/en-US) y documentación (`API.md`, `BASE_DE_DATOS.md`, `AGENTS.md`, `README.md`, `SPEC.md`). Sin cambios de comportamiento, solo nombres. ## [1.7.0] - 2026-09-10 ### Added - Agregar miembro a un proyecto ahora acepta un **correo que todavía no es usuario del sistema** (campo "Invitar por correo" en el popup de Miembros, alternativo a elegir uno existente). Si el correo no pertenece a nadie, se crea una cuenta en estado `invited` y se le manda un correo con un enlace de un solo uso (`/aceptar-invitacion?token=...`, vence en 7 días) para que complete su propio registro (elige nombre y clave); la fila de `project_members` ya queda creada de una vez, así que en cuanto acepta ya aparece como miembro sin pasos adicionales. A diferencia del autorregistro público, no pasa por aprobación de un admin — quien lo agregó a su proyecto ya lo vetó. Nuevos endpoints públicos `GET /api/auth/invite` y `POST /api/auth/accept-invite`. ## [1.6.1] - 2026-09-09 ### Changed - Nuevo ícono/logo de la app derivado del ícono original de LinkedCorp (círculo azul de marca `#1C55FF` con la red de nodos): se agregó una insignia con el acento de la app (`#0078D4`) para identificar visualmente el módulo de Proyectos. Actualizados `logoLinked1.png`, `logoLinkedCorpTxt.png` y `logoLinkedCorpTxtBlack.png` (sidebar y login, temas oscuro/claro). - Favicon nuevo (`favicon.svg` + `favicon.png` + `apple-touch-icon.png`); antes la app no declaraba ninguno. ## [1.6.0] - 2026-09-09 ### Added - Un proyecto puede tener **uno o más administradores del proyecto** (`role_in_project = 'admin'` en `project_members`), sin importar el rol global del usuario — un `collaborator` puede ser administrador de un proyecto puntual. Se otorga/quita desde Miembros: casilla "Agregar como administrador del proyecto" al agregar, y un botón de escudo para promover/degradar a un miembro existente (protegido: nunca toca al `Dueño`). Nuevo `PUT /api/projects/:id/members/:userId/role`. `canWriteProject` ahora reconoce este rol por-proyecto además del comportamiento previo (admin/superadmin/it_manager global, o project_lead miembro). ### Changed - El menú "Configuración" (apariencia, catálogos, SMTP) ahora es **visible y accesible solo para el superadmin** — antes cualquier usuario logueado lo veía y podía entrar (el tema/idioma personal sigue disponible para todos desde los íconos de la barra superior, eso no cambió). Se guarda tanto en el menú lateral como en la ruta directa `/configuracion`. - Escritura de catálogos (`/api/catalogs/*`, usado por la pantalla de Configuración) restringida de `[superadmin, admin]` a solo `superadmin`, para que el backend sea consistente con que `admin` ya no ve ni puede entrar a esa pantalla — la lectura sigue abierta a cualquier usuario (los combos de prioridad/estado en el resto de la app la necesitan). ## [1.5.0] - 2026-09-09 ### Added - Eliminar proyecto: eliminación **lógica** (`deleted_at`/`deleted_by`) disponible para quien puede editar el proyecto (superadmin/admin/it_manager/project_lead dueño o miembro), con popup de confirmación (`ContentDialog`) antes de aplicarla. El proyecto desaparece del listado y del dashboard, pero sigue en la base de datos. - Papelera de proyectos, visible solo para el **superadmin** (botón "Papelera" en Proyectos): lista los proyectos eliminados lógicamente, con acciones "Restaurar" y "Eliminar definitivamente" (esta última con su propia confirmación, más severa — advierte que también borra actividades/comentarios/adjuntos). El borrado físico (`DELETE`) solo puede aplicarse sobre un proyecto que ya pasó por la eliminación lógica (nunca en un solo paso). - Columna "Creado" (fecha) en el listado de proyectos, ordenada por defecto de más nuevo a más antiguo — un proyecto recién creado aparece primero sin tener que buscarlo. `ListView` ahora soporta un orden inicial (`initialSort`) además del ordenamiento por clic en cabecera que ya tenía. ### Fixed - Los KPIs del dashboard (proyectos activos/atrasados/por vencer, avance promedio, actividades pendientes/atrasadas/de hoy, proyectos por estado) ahora excluyen proyectos eliminados lógicamente — antes de este cambio no existía el concepto, así que no aplica como regresión, pero se dejó explícito para que un futuro cambio no los vuelva a incluir por accidente. ## [1.4.0] - 2026-09-09 ### Added - Boton de revelar/ocultar clave (icono de ojo) en todos los campos de contraseña de la app: login, registro, restablecer clave, cambiar clave (usuario logueado), crear usuario y la clave SMTP en Configuración. Nuevo componente reutilizable `PasswordInput`. ### Fixed - El fix de espacios en SMTP del v1.3.0 usaba `trim()`, que solo recorta los bordes. El caso real en producción tenía el espacio a mitad del host (`"mail.linkedcorp." + " " + "net"`), asi que seguia fallando tras el primer fix. Corregido para quitar cualquier espacio, no solo los bordes. ## [1.3.0] - 2026-09-06 ### Added - Configuración → Correo (SMTP): botón "Enviar prueba" con campo de destinatario. Ejecuta un envío real (`POST /api/settings/smtp/test`, solo superadmin, rate-limited) usando los valores actuales del formulario (aunque no se hayan guardado) y muestra el resultado real — éxito o el error tal cual lo devuelve el servidor SMTP — a diferencia de `sendMail()` (correo de negocio), que nunca lanza para no romper flujos como `forgot-password`. ### Fixed - La pantalla de SMTP no tenía forma de verificar que la configuración guardada funcionara de verdad; un error de host/certificado/credenciales solo se detectaba cuando fallaba un correo real de negocio, sin ningún diagnóstico. Regla agregada a `SEGURIDAD-Y-CALIDAD.md` del orquestador: toda config de servicio externo debe incluir una acción de prueba real. ## [1.2.0] - 2026-09-06 ### Added - Cambiar clave desde la app: `PUT /api/auth/change-password` (exige la clave actual) + opción "Cambiar clave" en el menú de usuario (popup), disponible para cualquier usuario logueado. ## [1.1.0] - 2026-09-06 ### Added - Autorregistro público (`/registro`) con verificación de correo (enlace de un solo uso, 24h) y aprobación posterior por Administrador/Superadministrador (`/api/users/:id/approve|reject`). - Recuperación de clave (`/olvide-clave` → `/restablecer-clave`), respuesta siempre genérica. - Rol `superadmin`: el usuario más antiguo del sistema (bootstrap automático al primer registro). - Configuración → Correo (SMTP), solo visible/editable por el superadmin; clave cifrada (AES-256-GCM) en `system_settings`, nunca expuesta por la API. Sin configurar, los correos de verificación/recuperación se loguean en vez de enviarse (modo dev, no rompe el flujo). ### Fixed - Bug real: `React.StrictMode` disparaba dos veces el efecto de `VerifyEmailPage`, y la segunda llamada (token ya consumido) mostraba "enlace inválido" aunque la verificación sí había funcionado. Corregido con una guarda por token ya solicitado. - Reordenado el montaje de rutas del backend: `subtasksRoutes` (mount genérico en `/api`) queda al final, para no interceptar con su `requireAuth` interno una request sin token dirigida a un router más específico registrado después (ver deuda técnica de la v1.0.0). ## [1.0.0] - 2026-09-06 ### Added - Primer despliegue a producción: `https://project.linkedcorp.net` (arquetipo B, dos servicios). - `create-admin.js`: bootstrap del usuario Administrador de producción con clave fuerte generada. ### Changed - `seed-db.js` separa catálogos (universal) de datos de ejemplo (solo entornos no productivos). - Logo real de LinkedCorp (sidebar, login) en vez del placeholder "LC"; tamaño duplicado. - `ComboBox`/`Flyout` se posicionan con portal a `document.body` (ya no se recortan dentro de un `Expander` o `DetailPopup`). - Master-detail de listados unificado en `DetailPopup` (popup de tamaño fijo, no se cierra con clic afuera) en Proyectos, Actividades, Departamentos, Usuarios, Miembros y Catálogos. - "Miembros" del proyecto pasa a ser su propia pestaña (antes vivía dentro de "Info"). ## [0.1.0] - 2026-09-03 ### Added - Estructura inicial del proyecto (backend Express + frontend React/Vite + MariaDB). - Modelo de datos MVP: usuarios/roles, departamentos, proyectos, actividades, subtareas, dependencias, comentarios, adjuntos, notificaciones, auditoría, catálogos. - Identidad UI/UX Fluent/Windows 11 (UI-UX-WINDOWS) adaptada a app web.