e02ea9ad93
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
7.9 KiB
7.9 KiB
Produccion - project.linkedcorp.net
Estado actual
- Version actual:
1.2.0 - Estado:
operativo - Ultima validacion:
2026-09-06
Servidor
- Host:
192.168.222.3 - SSH:
deploy@192.168.222.3 -p 2203(llave~/.ssh/id_ed25519, sudo NOPASSWD) - Ruta base:
/opt/apps/project.linkedcorp.net/
Runtime
- Frontend:
/opt/apps/project.linkedcorp.net/frontend/(dist/ + node_modules propio conserve) - Backend:
/opt/apps/project.linkedcorp.net/backend/(node_modules +.envde produccion) - Source (checkout de Gitea, WorkingDirectory de ambos servicios):
/opt/apps/project.linkedcorp.net/source/ - Storage:
/opt/apps/project.linkedcorp.net/storage/(adjuntos —STORAGE_ROOTen.env) - Logs:
/opt/apps/project.linkedcorp.net/logs/ - APKs Android publicados: no aplica
Servicios
- Frontend:
project-linkedcorp-frontend(node node_modules/.bin/serve -s dist -l 5196, WorkingDirectorysource/frontend... revisar nota abajo) - Backend:
project-linkedcorp-backend(node src/server.js, WorkingDirectorysource/backend,EnvironmentFile=backend/.env)
Nota real: el servicio frontend corre con
WorkingDirectory=/opt/apps/project.linkedcorp.net/frontend(nosource/frontend) sirviendofrontend/dist/con elserveinstalado ahi mismo (node_modules minimo, solo el paqueteserve). Eldist/se copia desdesource/frontend/disten cada deploy.
Puertos internos
- Frontend:
127.0.0.1:5196 - Backend:
127.0.0.1:4019
Base de datos
- Host pruebas/desarrollo:
192.168.222.20 - Host produccion real:
192.168.222.32 - Base:
project_linkedcorp - Usuario app:
project_linkedcorp(permitido solo desde192.168.222.3) - Regla dura: produccion web siempre usa
192.168.222.32 - Regla dura: pruebas y desarrollo siempre usan
192.168.222.20 - Antes de cada deploy, validar el
DB_HOSTactivo en runtime (backend/.envde produccion)
NPM (Nginx Proxy Manager)
- Dominio:
project.linkedcorp.net, SSL Let's Encrypt (auto-renovacion), Force SSL activo. - Proxy Host (id 77) ->
192.168.222.3:5196(frontend). - Custom Location
/api->192.168.222.3:4019(backend).
Estado confirmado (2026-09-06)
- Migraciones aplicadas (
001_initial.sql) sobreproject_linkedcorpen.32. - Catalogos base sembrados (roles, prioridades, estados de proyecto/actividad, tipos de proyecto). Sin datos de ejemplo (departamentos/usuario dev) — produccion arranca limpia.
- Usuario Administrador inicial creado con
create-admin.js(clave fuerte generada, entregada una sola vez fuera de este repo). El admin debe crear ahi mismo los demas usuarios/departamentos. - Login, dashboard y flujo proyecto->actividad verificados via curl contra
https://project.linkedcorp.net(backend + frontend + SSL + BD produccion, todo real). - Pendiente (no bloqueante): limpiar archivos
.mdde/opt/apps/project.linkedcorp.net/source(paso de higiene del checklist deDEPLOY_WEB.md, no se ejecuto por restriccion del entorno del agente — pendiente de accion manual o autorizacion explicita).
Actualizacion v1.1.0 (2026-09-06) — autorregistro/aprobacion/superadmin/SMTP
- Migracion
002_registration_and_smtp.sqlaplicada sobre.32: rolsuperadmin, columnas de ciclo de vida enusers, tablasystem_settings.mgonzalez@linkedcorp.net(id=1) quedo promovido asuperadminautomaticamente. ENCRYPTION_KEYgenerado y agregado al.envde produccion (cifra la clave SMTP en BD).- Ambos servicios reconstruidos (backend con
nodemailernuevo, frontend recompilado) y reiniciados; PID confirmado distinto en los dos. - Verificado end-to-end contra
https://project.linkedcorp.net: login reportaroleCode: superadmin,GET /api/settings/smtprespondeconfigured:false(sin SMTP real todavia). - Pendiente: el superadmin debe cargar el SMTP real desde Configuracion → Correo (SMTP) cuando
lo tenga. Hasta entonces, un registro/recuperacion de clave real en produccion queda logueado en
journalctl -u project-linkedcorp-backenden vez de enviarse por correo — nadie externo puede completar el autorregistro sin que un admin le pase el enlace manualmente desde el log.
Actualizacion v1.2.0 (2026-09-06) — cambiar clave desde la app
PUT /api/auth/change-password(exige clave actual) + opcion "Cambiar clave" en el menu de usuario. Redeploy sin cambios de dependencias ni de esquema; PID confirmado en ambos servicios.- Verificado en produccion via curl (rechaza clave actual incorrecta con 400; no se cambio la clave real del superadmin durante la prueba).
Actualizacion v1.3.0 (2026-09-06) — boton de prueba en Correo (SMTP)
POST /api/settings/smtp/test(superadmin, rate-limited) agregado. Redeploy sin cambios de dependencias ni de esquema (nodemailerya estaba desde v1.1.0); PID confirmado distinto en ambos servicios tras el restart.- Verificado en dev de punta a punta (curl + Playwright) antes del deploy: validacion 400 sin
host/usuario, y un intento real contra el SMTP interno con credenciales invalidas devuelve el
error real del servidor (
certificate has expired) en vez de un mensaje generico. - En produccion se confirmo: el commit correcto quedo desplegado, ambos servicios reiniciaron
limpio (
journalctlsin errores) yGET /api/settings/smtpsin token responde401como se espera. No se verificó el flujo autenticado completo en producción — minar un JWT válido en el servidor para probarlo fue bloqueado por el clasificador de auto-mode (accion sensible sobre produccion) y no se intento evadirlo; tampoco se reseteo la clave del superadmin real solo para probar. Si se quiere una verificacion end-to-end en produccion, hacerlo manualmente desde el navegador con la sesion real del superadmin. - Regla nueva agregada al orquestador (
project-md-templates/SEGURIDAD-Y-CALIDAD.md, seccion 1.6bis y checklist): toda pantalla de configuracion de un servicio externo debe tener un boton de prueba real, no solo "Guardar".
Fix rapido (2026-09-06) — espacio colado en el host SMTP
- El superadmin probó el SMTP real en producción y el boton de prueba (recien desplegado)
funciono como debia: reporto
getaddrinfo ENOTFOUND mail.linkedcorp.net. La causa real era un espacio de mas tecleado en el campo host, guardado literalmente como"mail.linkedcorp. net"ensystem_settings(confirmado por hexdump del valor en la BD de produccion). - Fix:
updateSmtpConfig/testSmtpConfigahora hacentrim()de host/usuario/remitente/destino antes de guardar o probar, para que un espacio accidental no vuelva a romper la resolucion DNS en silencio. Desplegado (solo backend, sin build de frontend ni migracion; PID confirmado). - El valor ya guardado en produccion sigue teniendo el espacio (no se corrigio a mano en la BD: el UPDATE directo sobre la BD de produccion fue bloqueado por el clasificador de auto-mode del agente, y no se intento evadirlo). Accion pendiente del superadmin: volver a guardar el host desde Configuracion -> Correo (SMTP) (con el fix ya desplegado, un espacio de mas ya no rompe nada) y repetir la prueba.
- Correccion (mismo dia): el primer fix usaba
trim(), que solo quita espacios al borde. El espacio real estaba a MITAD del host ("mail.linkedcorp." + " " + "net"), asi quetrim()no lo tocaba y el superadmin siguio viendo el mismoENOTFOUNDtras reintentar. Corregido para quitar CUALQUIER espacio (replace(/\s+/g,'')) de host/usuario/remitente/destino, no solo los de los bordes. Redesplegado (solo backend, PID confirmado, logs limpios).
Comandos utiles
sudo systemctl status project-linkedcorp-backend
sudo systemctl status project-linkedcorp-frontend
sudo journalctl -u project-linkedcorp-backend -n 100 --no-pager
sudo journalctl -u project-linkedcorp-frontend -n 100 --no-pager
Notas
- No dejar secretos en el repo (
.envde produccion vive solo enbackend/.envdel servidor). - No reemplazar
storage/nilogs/durante un deploy. - Documentar cambios de version y estado real en este archivo y en
CHANGELOG.md.