# Arquitectura de NexoCaja

## Vista general

NexoCaja utiliza una arquitectura web local de tres capas. El navegador presenta la interfaz; el servidor Node.js aplica autenticación, permisos y validaciones; SQLite conserva cuentas y datos financieros. Los cálculos de proyección se ejecutan en el servidor mediante funciones puras que también se prueban de forma independiente.

```text
Navegador
  public/index.html
  public/app.js
  public/styles.css
  public/spreadsheet.js
        |
        | HTTP y JSON en la red local
        v
Servidor Node.js
  src/server.js
  src/auth.js
  src/finance.js
        |
        v
SQLite
  data/nexocaja.sqlite
  data-demo/nexocaja.sqlite
```

## Tecnologías

- Node.js 22.13 o superior, sin banderas experimentales adicionales para `node:sqlite`.
- Módulo HTTP nativo de Node.js.
- `node:sqlite` con `DatabaseSync`.
- HTML, CSS y JavaScript sin framework de interfaz.
- XLSX generado y leído en el navegador por `public/spreadsheet.js`.
- Manifest web para instalación desde Safari u otro navegador compatible.

## Estructura principal

| Ruta | Responsabilidad |
| --- | --- |
| `public/index.html` | Documento inicial, metadatos y manifest |
| `public/app.js` | Estado de interfaz, vistas, formularios y llamadas API |
| `public/styles.css` | Diseño responsive, animaciones y tooltips flotantes |
| `public/spreadsheet.js` | Lectura y generación de XLSX y CSV |
| `src/server.js` | Servidor, API, validación, permisos y archivos estáticos |
| `src/auth.js` | Derivación de contraseñas, sesiones y cookies |
| `src/db.js` | Esquema SQLite, migraciones simples y datos iniciales |
| `src/finance.js` | Crédito, amortización, impuestos y proyección anual |
| `src/demo.js` | Cuentas y datos sintéticos usados solo por los iniciadores locales; se excluye del paquete de hosting |
| `test` | Pruebas de API, modo demo y reglas financieras |
| `documentacion` | Contexto, decisiones, manual y bitácora compartida |

## API principal

| Grupo | Rutas representativas | Acceso |
| --- | --- | --- |
| Salud e inicio | `/api/health`, `/api/setup/status`, `/api/setup`, `/api/login`, `/api/logout`, `/api/session` | Público o sesión |
| Cuenta | `/api/account/password` | Cualquier cuenta autenticada |
| Recorrido guiado | `/api/tour`, `/api/tour/complete` | Cualquier cuenta autenticada |
| Configuración del recorrido | `/api/admin/tour` | Solo Administrador |
| Administración | `/api/admin/summary`, `/api/admin/users`, `/api/admin/audit` | Maestra y gestor |
| Importación de usuarios | `/api/admin/users/import` | Maestra y gestor con límites de rol |
| Datos financieros | `/api/financial/data`, `/api/financial/projection` | Usuario financiero |
| Movimientos | `/api/financial/transactions` y ruta de importación | Usuario financiero |
| Plan | `/api/financial/profile`, `/api/financial/months` | Usuario financiero |
| Créditos | `/api/financial/loans` | Usuario financiero |

## Autenticación y privacidad

Las contraseñas se derivan con `scrypt` y una sal aleatoria. La sesión se identifica mediante una cookie `HttpOnly` con política `SameSite=Strict`; el servidor guarda únicamente el hash del token. Las cuentas inactivas no pueden usar una sesión vigente.

Los endpoints financieros exigen el rol `usuario` y filtran por el identificador de la sesión. Las rutas administrativas no devuelven movimientos, categorías, importes ni proyecciones. El gestor solo recibe cuentas normales.

## Ejecución local

El servidor escucha en `127.0.0.1` de forma predeterminada. Los iniciadores de iPhone y iPad cambian temporalmente el host a `0.0.0.0` para permitir acceso desde la misma red Wi-Fi. Este modo debe usarse solo en una red de confianza.

El puerto predeterminado del servidor es `4173`. Los iniciadores demo usan `4174` y la carpeta `data-demo`.

## Flujo de una operación financiera

1. El usuario introduce datos en la interfaz.
2. `public/app.js` valida el formulario básico y envía JSON.
3. `src/server.js` comprueba sesión, rol, rangos y propiedad del dato.
4. `src/db.js` persiste la modificación en SQLite.
5. `src/finance.js` recalcula la proyección completa cuando se solicita.
6. La interfaz actualiza tarjetas, tablas y gráficos.

## Archivos base del frontend

La capa cliente de NexoCaja está construida íntegramente con estándares web nativos (HTML5, CSS3, ES Modules), sin dependencias externas de librerías ni compiladores:

| Archivo base | Rol y contenido |
| --- | --- |
| `public/index.html` | Contenedor principal de la SPA. Define el viewport responsive, enlaces al manifest PWA, íconos para iOS/Android, estilos globales, contenedor `#app` y zona flotante `#toast-region`. |
| `public/app.js` | Núcleo de la aplicación cliente. Centraliza el estado (`state`), enrutador por hash, generador de componentes de interfaz, recorrido guiado versionado por rol, renderizado de gráficos SVG interactivos con inspección por clic, validación de formularios y comunicación asíncrona con `/api`. |
| `public/styles.css` | Sistema de diseño visual y animaciones. Contiene las variables de color institucional (Gerepro/MYPEs), foco y globo responsive del recorrido, tipografía fluida con `clamp()`, transiciones suaves con curvas cúbicas bezier, diseño adaptable a escritorio/móvil y compatibilidad con `prefers-reduced-motion`. |
| `public/spreadsheet.js` | Motor cliente para hojas de cálculo. Procesa y exporta archivos XLSX y CSV mediante lectura y ensamblado de estructuras ZIP/XML directamente en el navegador, permitiendo importación y exportación sin recargar el servidor. |
| `public/manifest.json` | Manifiesto de aplicación web (PWA) que permite instalar NexoCaja como aplicación nativa en iPad, iPhone, Android y equipos de escritorio en modo `standalone`. |

## Transición de ejecución local a servidor de producción

NexoCaja fue concebido para operar de forma transparente tanto en una estación de trabajo local como en un servidor institucional en la nube:

1. **Rutas relativas desacopladas**: Toda la comunicación del frontend hacia el backend se realiza mediante `/api/...`. No existen URLs absolutas fijadas a `localhost`, lo que permite servir la aplicación desde cualquier dominio (`https://nexocaja.pe`) o subdominio sin modificar el código fuente del cliente.
2. **Proxy inverso y terminación HTTPS**: En servidor se recomienda desplegar tras un proxy inverso (Nginx o Caddy). El proxy gestiona los certificados TLS (Let's Encrypt), la compresión de estáticos y redirige el tráfico al proceso Node.js (por defecto en `127.0.0.1:4173`).
3. **Cookies de sesión en producción**: En entorno HTTPS, la cookie de sesión admite la bandera `Secure` junto a `HttpOnly` y `SameSite=Strict`, garantizando protección frente a robo de tokens o ataques CSRF.
4. **Concurrencia y persistencia de SQLite**: Para despliegues con múltiples usuarios concurrentes en servidor, SQLite opera en modo WAL (`PRAGMA journal_mode = WAL;`), lo que permite que múltiples lectores no bloqueen a los escritores y facilita respaldos en caliente sin detener el servicio.
5. **Supervisión de procesos**: El servicio Node.js se supervisa mediante `systemd` o `PM2`, asegurando reinicios automáticos tras actualizaciones o reinicios del servidor.
6. **Paquete por lista permitida**: `npm run build:host` copia únicamente `app.js`, `package.json`, `public/`, los cuatro módulos `src/` de producción, una carpeta de datos vacía y la guía operativa a `dist/NexoCaja-hosting`; no arrastra bases locales, el módulo demo, credenciales, pruebas ni archivos internos.
7. **Despliegue en subdominio**: el paquete supone que la URL de la aplicación es la raíz del subdominio y que el panel redirige HTTPS hacia un proceso Node.js persistente. No es un plugin de WordPress ni una aplicación PHP.

## Restricciones técnicas conocidas

- La aplicación local está optimizada para una estación de trabajo y carga de piloto o taller.
- SQLite simplifica enormemente la instalación y portabilidad; al migrar a un servidor centralizado con alta concurrencia de cientos de usuarios simultáneos, se debe evaluar la activación de WAL y políticas de respaldo automatizado diario.
- No existe todavía un servicio SMTP externo para recuperación automática de acceso por correo; los gestores locales pueden restablecer credenciales desde su panel.
- Las tasas tributarias son configurables en el plan y deben ser validadas por los responsables contables de cada MYPE según su régimen fiscal específico (RER, MYPE Tributario o General).
