Cómo encajan las piezas
Esta página describe lo que es común a todos los módulos: el mapa de puertos, el orden de arranque, cómo se resuelven los permisos y cómo se comunican entre sí. El detalle de cada pieza está en Módulos.
Mapa de puertos
| Puerto | Módulo | Arranca por defecto |
|---|---|---|
3306 | Base de datos MariaDB | sí (sólo en 127.0.0.1) |
3000 | API de Zertipower | sí |
3002 | API de energía en tiempo real | sí |
4201 | Panel de Administración | sí |
4202 | Calculadora | sí |
8080 | Documentación | sí |
3001 | API del Contador | no — perfil smart-meter |
4200 | Contador / Smart Meter | no — perfil smart-meter |
Orden de arranque
El orden importa: base de datos → APIs → frontends. Las APIs abortan si no pueden conectar con la base.
Esto no hay que orquestarlo a mano: el docker-compose.yml declara la dependencia
con condition: service_healthy, de modo que las APIs esperan a que MariaDB
acepte conexiones de verdad, no sólo a que el contenedor exista.
Quién habla con quién
- El Panel y la Calculadora hablan sólo con la API de Zertipower.
- El Contador habla con tres: la API de Zertipower, su propia API y la de tiempo real. Es la fuente de confusión más habitual del sistema.
- La API de tiempo real y la API de Zertipower comparten la base
zertipower-dev. La API del Contador usa la suya,zertiair.
Los frontends se compilan con http://localhost:3000, no con
http://backend:3000. El código se ejecuta en el navegador del usuario, que no
sabe resolver los nombres de la red interna de Docker.
Autenticación y permisos
La API de Zertipower emite tokens JWT en /auth/login. El campo role del token
determina el acceso:
- Si el rol es
ADMIN, se concede acceso inmediato sin consultar la tabla de permisos. - Para cualquier otro rol se consulta
role_permission, y si no hay una fila que case (resource+action), se deniega.
Por eso el usuario del seed mínimo funciona sin sembrar permisos: su rol se llama
exactamente ADMIN.
La comprobación es name === "ADMIN". Si el rol se llama admin, Admin o
ADMINISTRADOR, el usuario pierde todos los privilegios.
Una sola clave para tres servicios
JWT_SECRET lo comparten la API de Zertipower, la del Contador y la de tiempo
real, y debe ser idéntico en las tres: unas firman los tokens que otras
verifican. En la API de Zertipower, además, esa misma clave cifra datos guardados
y deriva carteras — ver API de Zertipower.
CORS
La API de Zertipower arranca con CORS permisivo, que refleja cualquier origen. Los tres frontends pueden hablar con ella sin configuración adicional.
Las variables FRONTEND_URL y COMPTADOR_FRONTEND_URL no controlan CORS: se
usan para redirecciones (OAuth, recuperación de contraseña). Por eso la
Calculadora funciona en el 4202 aunque no tenga ninguna variable asociada.
Servicios externos
Lo que el sistema no puede resolver por sí mismo:
| Servicio | Para qué | Estado |
|---|---|---|
| Google OAuth | Acceso con Google | Requiere un cliente propio en Google Cloud |
Zertiauth (auth.zertifier.com) | Identidad del Contador y del Panel | Dependencia de Zertifier, pendiente de eliminar |
| Datadis | Consumos horarios reales | Credenciales por punto de suministro |
| Predicción solar | Producción esperada | Sustituye a Wattabit, que cesó su actividad |
| PVGIS | Radiación solar | Comisión Europea, sin credenciales |
| Nodos RPC | Gobernanza sobre Gnosis | Públicos |
| Stripe | Facturación | Credenciales propias |