Add new images and update documentation for project infrastructure
|
After Width: | Height: | Size: 322 KiB |
|
After Width: | Height: | Size: 292 KiB |
|
After Width: | Height: | Size: 260 KiB |
|
After Width: | Height: | Size: 318 KiB |
|
|
@ -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 |
|
After Width: | Height: | Size: 259 KiB |
|
After Width: | Height: | Size: 353 KiB |
|
After Width: | Height: | Size: 390 KiB |
|
After Width: | Height: | Size: 332 KiB |
|
After Width: | Height: | Size: 521 KiB |
|
|
@ -2,10 +2,10 @@
|
||||||
## 1) Infraestructura (Docker)
|
## 1) Infraestructura (Docker)
|
||||||
|
|
||||||
|
|
||||||
**Por que es importante:**
|
**Por qué es importante:**
|
||||||
- El proyecto depende de Dolibarr y una base de datos real.
|
- El proyecto depende de Dolibarr y una base de datos real.
|
||||||
- Docker permite reproducir el entorno en cualquier maquina.
|
- Docker permite reproducir el entorno en cualquier máquina.
|
||||||
- Sin Dolibarr activo, la API devuelve errores de conexion.
|
- Sin Dolibarr activo, la API devuelve errores de conexión.
|
||||||
|
|
||||||
**Docker Desktop**
|
**Docker Desktop**
|
||||||

|

|
||||||
|
|
@ -16,18 +16,18 @@
|
||||||
**Explicación:**
|
**Explicación:**
|
||||||
- Se levantan 2 servicios: MariaDB y Dolibarr.
|
- Se levantan 2 servicios: MariaDB y Dolibarr.
|
||||||
- Dolibarr expone el puerto `8200` para acceder al ERP.
|
- Dolibarr expone el puerto `8200` para acceder al ERP.
|
||||||
- Las credenciales y modulos se configuran por variables de entorno.
|
- Las credenciales y módulos se configuran por variables de entorno.
|
||||||
- Los volumenes guardan datos persistentes.
|
- 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 app no funciona sin apuntar a la API de Dolibarr.
|
||||||
- La API key se mantiene en servidor y no se expone al cliente.
|
- 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...)**
|
||||||

|

|
||||||
|
|
||||||
**Explicación:**
|
**Explicación:**
|
||||||
|
|
@ -38,11 +38,11 @@
|
||||||
|
|
||||||
## 3) Proxy API (seguridad de la API key)
|
## 3) Proxy API (seguridad de la API key)
|
||||||
|
|
||||||
**Por que es importante:**
|
**Por qué es importante:**
|
||||||
- El frontend nunca habla directamente con Dolibarr.
|
- El frontend nunca habla directamente con Dolibarr.
|
||||||
- El proxy agrega la key en servidor y protege credenciales.
|
- El proxy agrega la key en servidor y protege credenciales.
|
||||||
|
|
||||||
**Metodos GET/POST/PUT/DELETE:**
|
**Métodos GET/POST/PUT/DELETE:**
|
||||||

|

|
||||||
***
|
***
|
||||||
**Ejemplo llamada:**
|
**Ejemplo llamada:**
|
||||||
|
|
@ -52,13 +52,14 @@
|
||||||
**Explicación:**
|
**Explicación:**
|
||||||
- Todas las llamadas pasan por `/api/dolibarr/...`.
|
- Todas las llamadas pasan por `/api/dolibarr/...`.
|
||||||
- Se construye la URL real con `DOLIBARR_API_URL`.
|
- 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
|
## 4) Cliente central de Dolibarr
|
||||||
|
|
||||||
**Por que es importante:**
|
**Por qué es importante:**
|
||||||
- Centraliza todas las llamadas a la API.
|
- Centraliza todas las llamadas a la API.
|
||||||
- Simplifica los métodos de los servicios (proyectos, tareas, usuarios).
|
- Simplifica los métodos de los servicios (proyectos, tareas, usuarios).
|
||||||
|
|
||||||
|
|
@ -68,31 +69,32 @@
|
||||||
**Proxy Fetch:**
|
**Proxy Fetch:**
|
||||||

|

|
||||||
***
|
***
|
||||||
**Decisión segun entorno**
|
**Decisión según entorno**
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
**Explicación:**
|
**Explicación:**
|
||||||
- Si es servidor usa llamada directa.
|
- Si es servidor usa llamada directa.
|
||||||
- Si es cliente usa el proxy interno.
|
- Si es cliente usa el proxy interno.
|
||||||
- Se aplica cache corta (`revalidate: 60`).
|
- Se aplica caché corta (`revalidate: 60`).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 5) Servicios de proyectos (CRUD)
|
## 5) Servicios de proyectos (CRUD)
|
||||||
|
|
||||||
**Que capturar:**
|
**Por qué es importante:**
|
||||||
- Archivo `lib/projectsService.ts`
|
- Toda la lógica de proyectos vive aquí.
|
||||||
- `getProjects`, `createProject`, `updateProject`, `deleteProject`
|
- La UI solo consume estos métodos, no la API directa.
|
||||||
|
|
||||||
**Por que es importante:**
|
**CRUD Proyectos:**
|
||||||
- Toda la logica de proyectos vive aqui.
|

|
||||||
- La UI solo consume estos metodos, no la API directa.
|
***
|
||||||
|
**CRUD Avanzado:**
|
||||||
**Captura sugerida:**
|

|
||||||

|
***
|
||||||
|
**Ejemplo funcionamiento:**
|
||||||
**Guion corto:**
|

|
||||||
|
**Explicación:**
|
||||||
- `getProjects()` obtiene datos y los mapea a formato UI.
|
- `getProjects()` obtiene datos y los mapea a formato UI.
|
||||||
- `createProject()` crea en Dolibarr y devuelve el proyecto completo.
|
- `createProject()` crea en Dolibarr y devuelve el proyecto completo.
|
||||||
- Se controla el flujo de errores en un solo lugar.
|
- Se controla el flujo de errores en un solo lugar.
|
||||||
|
|
@ -101,39 +103,35 @@
|
||||||
|
|
||||||
## 6) Mapeo de datos y estados
|
## 6) Mapeo de datos y estados
|
||||||
|
|
||||||
**Que capturar:**
|
**Por qué es importante:**
|
||||||
- Archivo `types/project.ts`
|
|
||||||
- `ProjectStatus` y `STATUS_CONFIG`
|
|
||||||
- `mapDolibarrProject`
|
|
||||||
|
|
||||||
**Por que es importante:**
|
|
||||||
- Dolibarr devuelve datos crudos, la UI necesita formato amigable.
|
- Dolibarr devuelve datos crudos, la UI necesita formato amigable.
|
||||||
- Se normalizan fechas, presupuesto y progreso.
|
- Se normalizan fechas, presupuesto y progreso.
|
||||||
|
|
||||||
**Captura sugerida:**
|
**Interfaz cruda y de UI para Proyectos:**
|
||||||

|

|
||||||
|
***
|
||||||
|
**Mapeador Proyectos:**
|
||||||
|

|
||||||
|
|
||||||
**Guion corto:**
|
**Explicación:**
|
||||||
- Estados oficiales: 0 Borrador, 1 Activo, 2 Cerrado.
|
- Estados oficiales: 0 Borrador, 1 Activo, 2 Cerrado.
|
||||||
- El mapper convierte campos y define etiquetas visibles.
|
- El mapper convierte campos y define etiquetas visibles.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 7) Autenticacion (login)
|
## 7) Autenticación (login)
|
||||||
|
|
||||||
**Que capturar:**
|
**Por qué es importante:**
|
||||||
- Archivo `lib/authService.ts`
|
- El acceso está protegido por credenciales reales de Dolibarr.
|
||||||
- `login()` (llamada a `/login` de Dolibarr)
|
|
||||||
- `saveAuthData()` (localStorage + cookie)
|
|
||||||
|
|
||||||
**Por que es importante:**
|
|
||||||
- El acceso esta protegido por credenciales reales de Dolibarr.
|
|
||||||
- El token se guarda y permite navegar por la app.
|
- El token se guarda y permite navegar por la app.
|
||||||
|
|
||||||
**Captura sugerida:**
|
**Servicio de autenticación:**
|
||||||

|

|
||||||
|
***
|
||||||
|
**Servicio de autenticación - 2:**
|
||||||
|

|
||||||
|
|
||||||
**Guion corto:**
|
**Explicación:**
|
||||||
- El login pide token a Dolibarr.
|
- El login pide token a Dolibarr.
|
||||||
- Si es correcto, se guarda en localStorage y cookie.
|
- Si es correcto, se guarda en localStorage y cookie.
|
||||||
- Se usa luego para validar sesiones.
|
- Se usa luego para validar sesiones.
|
||||||
|
|
@ -142,106 +140,50 @@
|
||||||
|
|
||||||
## 8) Middleware de acceso
|
## 8) Middleware de acceso
|
||||||
|
|
||||||
**Que capturar:**
|
**Qué capturar:**
|
||||||
- Archivo `middleware.ts`
|
- Archivo `middleware.ts`
|
||||||
- Lectura de cookie `dolibarr_auth_token`
|
- 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.
|
- 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:**
|
||||||

|

|
||||||
|
|
||||||
**Guion corto:**
|
**Explicación:**
|
||||||
- Si no hay token, redirige a login.
|
- Si no hay token, redirige a login.
|
||||||
- Si hay token, permite navegar.
|
- Si hay token, permite navegar.
|
||||||
|
- No valida con Dolibarr en cada request; solo comprueba token local.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 9) Seed de datos (demo reproducible)
|
## 9) Seed de datos (demo reproducible)
|
||||||
|
|
||||||
**Que capturar:**
|
**Por qué es importante:**
|
||||||
- Archivo `scripts/seed-projects-via-api.js`
|
|
||||||
- Bloque de datos de proyectos
|
|
||||||
- Logica de limpieza y cierre de proyectos
|
|
||||||
|
|
||||||
**Por que es importante:**
|
|
||||||
- Permite crear datos realistas en minutos.
|
- 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:**
|
||||||

|

|
||||||
|
|
||||||
**Guion corto:**
|
**Explicación:**
|
||||||
- El seed elimina proyectos previos.
|
- El seed elimina proyectos previos.
|
||||||
- Crea 14 proyectos con tareas.
|
- 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:**
|
**Diagrama visual**
|
||||||
- Archivo `lib/tasksService.ts`
|

|
||||||
- `getTasksByProjectId()` (filtra tareas por proyecto)
|
|
||||||
|
|
||||||
**Por que es importante:**
|
**Explicación:**
|
||||||
- Dolibarr no filtra bien por proyecto y se corrige en el cliente.
|
|
||||||
- Se calcula estadistica de tareas para el dashboard.
|
|
||||||
|
|
||||||
**Captura sugerida:**
|
|
||||||

|
|
||||||
|
|
||||||
**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:**
|
|
||||||

|
|
||||||
|
|
||||||
**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:**
|
|
||||||
- La UI nunca toca la API directamente.
|
- La UI nunca toca la API directamente.
|
||||||
- El proxy y el cliente central simplifican el acceso.
|
- 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.
|
|
||||||
|
|
|
||||||