Add new images and update documentation for project infrastructure

This commit is contained in:
Levi Planelles 2026-05-14 12:03:15 +02:00
parent 1cd5cc6483
commit 5cb90100b7
11 changed files with 183 additions and 121 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 KiB

View File

@ -0,0 +1,120 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1080 320" width="100%" height="100%">
<defs>
<!-- Filtro para sombra suave y profesional -->
<filter id="soft-shadow" x="-20%" y="-20%" width="140%" height="140%">
<feDropShadow dx="0" dy="4" stdDeviation="10" flood-color="#0f172a" flood-opacity="0.05" />
</filter>
<!-- Punta de flecha para el flujo de datos -->
<marker id="arrowhead" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto">
<path d="M 0 1 L 9 5 L 0 9 z" fill="#94a3b8" />
</marker>
</defs>
<!-- Fondo base (opcional, asegura que se vea bien en fondos oscuros) -->
<rect width="1080" height="320" fill="#ffffff" rx="16" />
<style>
/* Estilos globales */
.box { fill: #ffffff; stroke: #e2e8f0; stroke-width: 2px; rx: 16px; ry: 16px; filter: url(#soft-shadow); }
.box:hover { stroke: #3b82f6; }
.icon-bg { fill: #eff6ff; }
.icon { fill: none; stroke: #2563eb; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.arrow { stroke: #94a3b8; stroke-width: 3.5; fill: none; marker-end: url(#arrowhead); }
/* Tipografía moderna y limpia */
text { font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; }
.title { font-size: 16px; font-weight: 600; fill: #1e293b; text-anchor: middle; }
.subtitle { font-size: 14px; font-weight: 400; fill: #64748b; text-anchor: middle; }
.subtitle-path { font-size: 12px; font-weight: 500; fill: #3b82f6; text-anchor: middle; }
.footer-bg { fill: #f8fafc; stroke: #f1f5f9; stroke-width: 1px; rx: 8px; }
.footer-text { font-size: 15px; font-weight: 500; fill: #475569; text-anchor: middle; }
</style>
<!-- ========================================== -->
<!-- 1. UI (Next.js) -->
<!-- ========================================== -->
<g transform="translate(50, 60)">
<rect width="200" height="150" class="box" />
<circle cx="100" cy="55" r="28" class="icon-bg" />
<!-- Icono Navegador -->
<g transform="translate(86, 41)">
<rect x="2" y="4" width="24" height="20" rx="3" ry="3" class="icon" />
<line x1="2" y1="11" x2="26" y2="11" class="icon" />
<circle cx="6" cy="7.5" r="1.5" fill="#2563eb" stroke="none" />
<circle cx="11" cy="7.5" r="1.5" fill="#2563eb" stroke="none" />
</g>
<text x="100" y="115" class="title">UI (Next.js)</text>
<text x="100" y="135" class="subtitle">Frontend / Dashboard</text>
</g>
<!-- Flecha 1 -->
<line x1="250" y1="135" x2="306" y2="135" class="arrow" />
<!-- ========================================== -->
<!-- 2. API Proxy -->
<!-- ========================================== -->
<g transform="translate(310, 60)">
<rect width="200" height="150" class="box" />
<circle cx="100" cy="55" r="28" class="icon-bg" />
<!-- Icono Escudo -->
<g transform="translate(86, 41)">
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" class="icon" />
</g>
<text x="100" y="108" class="title">API Proxy</text>
<text x="100" y="126" class="subtitle-path">/api/dolibarr/...</text>
<text x="100" y="144" class="subtitle">Protege API key</text>
</g>
<!-- Flecha 2 -->
<line x1="510" y1="135" x2="566" y2="135" class="arrow" />
<!-- ========================================== -->
<!-- 3. Dolibarr (ERP) -->
<!-- ========================================== -->
<g transform="translate(570, 60)">
<rect width="200" height="150" class="box" />
<circle cx="100" cy="55" r="28" class="icon-bg" />
<!-- Icono Servidor -->
<g transform="translate(86, 41)">
<rect x="2" y="3" width="24" height="10" rx="2" ry="2" class="icon" />
<rect x="2" y="15" width="24" height="10" rx="2" ry="2" class="icon" />
<line x1="6" y1="8" x2="6.01" y2="8" stroke-width="3" stroke="#2563eb" stroke-linecap="round" />
<line x1="6" y1="20" x2="6.01" y2="20" stroke-width="3" stroke="#2563eb" stroke-linecap="round" />
</g>
<text x="100" y="115" class="title">Dolibarr</text>
<text x="100" y="135" class="subtitle">ERP / API REST</text>
</g>
<!-- Flecha 3 -->
<line x1="770" y1="135" x2="826" y2="135" class="arrow" />
<!-- ========================================== -->
<!-- 4. MariaDB -->
<!-- ========================================== -->
<g transform="translate(830, 60)">
<rect width="200" height="150" class="box" />
<circle cx="100" cy="55" r="28" class="icon-bg" />
<!-- Icono Base de Datos -->
<g transform="translate(86, 41)">
<ellipse cx="14" cy="6" rx="10" ry="4" class="icon" />
<path d="M24 13c0 2.2-4.5 4-10 4S4 15.2 4 13" class="icon" />
<path d="M4 6v14c0 2.2 4.5 4 10 4s10-1.8 10-4V6" class="icon" />
</g>
<text x="100" y="115" class="title">MariaDB</text>
<text x="100" y="135" class="subtitle">Datos persistentes</text>
</g>
<!-- ========================================== -->
<!-- Texto Explicativo Inferior -->
<!-- ========================================== -->
<g transform="translate(50, 245)">
<rect width="980" height="44" class="footer-bg" />
<text x="490" y="27" class="footer-text">
La UI nunca toca directamente el ERP; pasa por el proxy que añade la API key.
</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 332 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 521 KiB

View File

@ -2,10 +2,10 @@
## 1) Infraestructura (Docker)
**Por que es importante:**
**Por qué es importante:**
- El proyecto depende de Dolibarr y una base de datos real.
- Docker permite reproducir el entorno en cualquier maquina.
- Sin Dolibarr activo, la API devuelve errores de conexion.
- Docker permite reproducir el entorno en cualquier máquina.
- Sin Dolibarr activo, la API devuelve errores de conexión.
**Docker Desktop**
![Docker Desktop](capturas/servicios-levantados.png)
@ -16,18 +16,18 @@
**Explicación:**
- Se levantan 2 servicios: MariaDB y Dolibarr.
- Dolibarr expone el puerto `8200` para acceder al ERP.
- Las credenciales y modulos se configuran por variables de entorno.
- Los volumenes guardan datos persistentes.
- Las credenciales y módulos se configuran por variables de entorno.
- Los volúmenes guardan datos persistentes.
---
## 2) Variables de entorno (configuracion)
## 2) Variables de entorno (configuración)
**Por que es importante:**
**Por qué es importante:**
- La app no funciona sin apuntar a la API de Dolibarr.
- La API key se mantiene en servidor y no se expone al cliente.
**Env local(api borrada por temas de segurdad...)**
**Env local (API borrada por temas de seguridad...)**
![Env Local](capturas/env-local.png)
**Explicación:**
@ -38,11 +38,11 @@
## 3) Proxy API (seguridad de la API key)
**Por que es importante:**
**Por qué es importante:**
- El frontend nunca habla directamente con Dolibarr.
- El proxy agrega la key en servidor y protege credenciales.
**Metodos GET/POST/PUT/DELETE:**
**Métodos GET/POST/PUT/DELETE:**
![Route.ts](capturas/route.png)
***
**Ejemplo llamada:**
@ -52,13 +52,14 @@
**Explicación:**
- Todas las llamadas pasan por `/api/dolibarr/...`.
- Se construye la URL real con `DOLIBARR_API_URL`.
- Se reenvian los metodos HTTP y se manejan errores.
- Se reenvían los métodos HTTP y se manejan errores.
- La API key nunca se expone al navegador; se inyecta en servidor.
---
## 4) Cliente central de Dolibarr
**Por que es importante:**
**Por qué es importante:**
- Centraliza todas las llamadas a la API.
- Simplifica los métodos de los servicios (proyectos, tareas, usuarios).
@ -68,31 +69,32 @@
**Proxy Fetch:**
![Proxy Fetch](capturas/proxy-fetch.png)
***
**Decisión segun entorno**
**Decisión según entorno**
![Decisión según entorno](capturas/decision.png)
**Explicación:**
- Si es servidor usa llamada directa.
- Si es cliente usa el proxy interno.
- Se aplica cache corta (`revalidate: 60`).
- Se aplica caché corta (`revalidate: 60`).
---
## 5) Servicios de proyectos (CRUD)
**Que capturar:**
- Archivo `lib/projectsService.ts`
- `getProjects`, `createProject`, `updateProject`, `deleteProject`
**Por qué es importante:**
- Toda la lógica de proyectos vive aquí.
- La UI solo consume estos métodos, no la API directa.
**Por que es importante:**
- Toda la logica de proyectos vive aqui.
- La UI solo consume estos metodos, no la API directa.
**Captura sugerida:**
![Projects Service](capturas/05-projects-service.png)
**Guion corto:**
**CRUD Proyectos:**
![CRUD Projects Service](capturas/crud-proyectos.png)
***
**CRUD Avanzado:**
![CRUD Advanced Service](capturas/crud-avanzado.png)
***
**Ejemplo funcionamiento:**
![GET Endpoint example](capturas/ejemplo-endpoint-getprojects.png)
**Explicación:**
- `getProjects()` obtiene datos y los mapea a formato UI.
- `createProject()` crea en Dolibarr y devuelve el proyecto completo.
- Se controla el flujo de errores en un solo lugar.
@ -101,39 +103,35 @@
## 6) Mapeo de datos y estados
**Que capturar:**
- Archivo `types/project.ts`
- `ProjectStatus` y `STATUS_CONFIG`
- `mapDolibarrProject`
**Por que es importante:**
**Por qué es importante:**
- Dolibarr devuelve datos crudos, la UI necesita formato amigable.
- Se normalizan fechas, presupuesto y progreso.
**Captura sugerida:**
![Project Types](capturas/06-project-types.png)
**Interfaz cruda y de UI para Proyectos:**
![Interfaces proyectos](capturas/interfaces-proyectos.png)
***
**Mapeador Proyectos:**
![Mapeador Proyectos](capturas/mapeador-proyectos.png)
**Guion corto:**
**Explicación:**
- Estados oficiales: 0 Borrador, 1 Activo, 2 Cerrado.
- El mapper convierte campos y define etiquetas visibles.
---
## 7) Autenticacion (login)
## 7) Autenticación (login)
**Que capturar:**
- Archivo `lib/authService.ts`
- `login()` (llamada a `/login` de Dolibarr)
- `saveAuthData()` (localStorage + cookie)
**Por que es importante:**
- El acceso esta protegido por credenciales reales de Dolibarr.
**Por qué es importante:**
- El acceso está protegido por credenciales reales de Dolibarr.
- El token se guarda y permite navegar por la app.
**Captura sugerida:**
![Auth Service](capturas/07-auth-service.png)
**Servicio de autenticación:**
![Auth Service](capturas/auth-service.png)
***
**Servicio de autenticación - 2:**
![Auth Service 2](capturas/auth-service-2.png)
**Guion corto:**
**Explicación:**
- El login pide token a Dolibarr.
- Si es correcto, se guarda en localStorage y cookie.
- Se usa luego para validar sesiones.
@ -142,106 +140,50 @@
## 8) Middleware de acceso
**Que capturar:**
**Qué capturar:**
- Archivo `middleware.ts`
- Lectura de cookie `dolibarr_auth_token`
- Redireccion a `/login`
- Redirección a `/login`
**Por que es importante:**
**Por qué es importante:**
- Protege rutas privadas cuando no hay token.
- Bloquea acceso directo a la app sin autenticacion.
- Bloquea acceso directo a la app sin autenticación.
**Captura sugerida:**
![Middleware](capturas/08-middleware.png)
**Middleware:**
![Middleware](capturas/middleware.png)
**Guion corto:**
**Explicación:**
- Si no hay token, redirige a login.
- Si hay token, permite navegar.
- No valida con Dolibarr en cada request; solo comprueba token local.
---
## 9) Seed de datos (demo reproducible)
**Que capturar:**
- Archivo `scripts/seed-projects-via-api.js`
- Bloque de datos de proyectos
- Logica de limpieza y cierre de proyectos
**Por que es importante:**
**Por qué es importante:**
- Permite crear datos realistas en minutos.
- La demo es consistente para la presentacion.
- La demo es consistente para la presentación.
**Captura sugerida:**
![Seed Script](capturas/09-seed.png)
**Seed script:**
![Seed Script](capturas/seed.png)
**Guion corto:**
**Explicación:**
- El seed elimina proyectos previos.
- Crea 14 proyectos con tareas.
- Los que estan al 100% se cierran (status 2).
- Los que están al 100% se cierran (status 2).
- Se ejecuta con `npm run seed`.
---
## 10) Servicio de tareas
## 10) Conexión entre piezas (flujo resumido)
**Que capturar:**
- Archivo `lib/tasksService.ts`
- `getTasksByProjectId()` (filtra tareas por proyecto)
**Diagrama visual**
![Diagrama de Flujo Principal](capturas/diagrama.svg)
**Por que es importante:**
- Dolibarr no filtra bien por proyecto y se corrige en el cliente.
- Se calcula estadistica de tareas para el dashboard.
**Captura sugerida:**
![Tasks Service](capturas/10-tasks-service.png)
**Guion corto:**
- Se piden todas las tareas y se filtra por `fk_project`.
- Se calcula progreso y estadisticas de tareas.
---
## 11) Manejo de errores y cache
**Que capturar:**
- `lib/dolibarrClient.ts` (bloque de `revalidate: 60`)
- `app/api/dolibarr/[...path]/route.ts` (log de errores)
**Por que es importante:**
- Explica por que a veces se ven datos antiguos.
- Muestra que los errores se controlan en el proxy.
**Captura sugerida:**
![Cache and Errors](capturas/11-cache.png)
**Guion corto:**
- Se usa cache corta para no saturar Dolibarr.
- Si Dolibarr esta apagado, la API responde con error.
---
## 12) Conexion entre piezas (flujo resumido)
**Que capturar:**
- Un diagrama o esquema simple (puede ser dibujado) mostrando:
UI -> Proxy -> Dolibarr -> DB
**Guion corto:**
**Explicación:**
- La UI nunca toca la API directamente.
- El proxy y el cliente central simplifican el acceso.
- Dolibarr sigue siendo la fuente unica de verdad.
- Dolibarr sigue siendo la fuente única de verdad.
---
## Anexo opcional: comandos utiles
Puedes anadir al final un mini bloque con comandos para mostrar que sabes levantar el entorno:
```bash
docker-compose up -d
npm run dev
npm run seed
```
---
Fin de las notas. Aqui solo pegas capturas y ajustas el texto que uses en la presentacion.