Untitled static subpage: Thursday, 25 June 2026, 19:44

Date: 2026-06-25 00:01 Title: Portal Admin + Monitor DTE — Documentación Técnica Type: page Description: Arquitectura, endpoints y configuración del portal de administración y monitor de servidores KontrolesERP

Portal Admin + Monitor DTE — Documentación Técnica

Visión general

Sistema de monitoreo centralizado para todos los servidores KontrolesERP. Alojado en INROCAR (host.kontroles.com), muestra estado en tiempo real de DTEs, worker, dispositivos y salud de cada servidor.

Browser (admin)
    │
    ├── https://host.kontroles.com/portal   → Portal de acceso (index.html)
    └── https://host.kontroles.com/monitor  → Monitor DTE (monitor.html)
                │
                ├── GET /api/monitor        → KontrolesERP INROCAR
                └── GET https://erp.jaasadecv.com/api/monitor → JAASA

Rutas nginx (server_proxy.conf)

INROCAR — /home/administrador/kontroleserp/nginx-proxy-manager/data/nginx/custom/server_proxy.conf

Ruta Destino
/portal kontrolesapi:80/index.html
/monitor kontrolesapi:80/monitor.html
/gerencia kontrolesapi:80/ia-gerencial.html
/erp-gate kontrolesapi:80/erp-gate.html
/api kontrolesapi:80 (CORS via more_set_headers)
/webui/ erp_app:8888 (protegido por auth_request)

JAASA — /data/nginx/custom/server_proxy.conf (dentro del contenedor nginx_proxy)

Ruta Destino
/gerencia kontrolesapi:80/ia-gerencial.html
/erp-gate kontrolesapi:80/erp-gate.html
/api kontrolesapi:80 (CORS via more_set_headers + proxy_hide_header)
/webui/ erp_app:8888 (protegido por auth_request)

Portal y Monitor no están expuestos en JAASA — se acceden exclusivamente desde INROCAR.


Endpoint /api/monitor

Autenticación: header X-Monitor-Key: <valor>
Método: GET
Sin JWT — ruta pública protegida solo por la clave compartida.

Variables de entorno relevantes

Variable Descripción Default
MONITOR_KEY Clave compartida para el endpoint kontroles_monitor_2024
SERVER_LABEL Nombre del servidor en la respuesta hostname del contenedor
ERP_HOST Host del ERP para ping interno erp_app
ERP_PORT Puerto del ERP 8888

Respuesta JSON

{
  "ok": true,
  "ts": "2026-06-24T...",
  "server": "KontrolesERP INROCAR",
  "schema": "adempiere",
  "db":     { "ok": true },
  "erp_app":{ "ok": true, "ms": 1 },
  "dte": {
    "estados":      { "sent": 7, "error": 1 },
    "atascados":    0,
    "sin_dte":      0,
    "en_error":     [ { "documentno": "...", "emh_msg": "...", "ts": "..." } ],
    "err_recientes":[ { "documentno": "...", "codigo": "023", "mensaje": "...", "ts": "..." } ]
  },
  "worker": [ { "org": "ROCAR", "ambiente": "00", "ultimo_dte": "...", "minutos_sin_actividad": 16 } ],
  "seqs":   [ { "tipodoc": "01", "serie": "DTE", "currentnext": 42 } ],
  "devices":[ { "device_name": "ERP INROCAR", "revoked": "N", "last_seen": "...", "horas_inactivo": 0.3 } ]
}

ok: false cuando: hay facturas en ERROR, DTEs atascados > 10 min, worker inactivo > 60 min con DTEs previos, o DB/ERP inaccesibles.


Endpoints admin de dispositivos /api/devices/admin

Autenticación: header X-Monitor-Key
Sin JWT — accesibles desde el Monitor sin login ERP.

Método Ruta Acción
GET /api/devices/admin Lista todos los dispositivos
POST /api/devices/admin Crea código de activación
DELETE /api/devices/admin/{device_id} Revoca dispositivo

POST body:

{ "device_name": "Laptop Gerencia", "notes": "Responsable: Admin", "ad_client_id": 1000000 }

Respuesta POST:

{ "activation_code": "BQNUJYWD", "device_name": "Laptop Gerencia" }

Tabla adempiere.api_device

CREATE TABLE adempiere.api_device (
    device_id       UUID    PRIMARY KEY DEFAULT gen_random_uuid(),
    ad_client_id    INTEGER NOT NULL,
    device_name     VARCHAR(100) NOT NULL,
    activation_code CHAR(8) NOT NULL,
    code_used       CHAR(1) NOT NULL DEFAULT 'N',
    device_token    UUID    UNIQUE,
    revoked         CHAR(1) NOT NULL DEFAULT 'N',
    created         TIMESTAMP NOT NULL DEFAULT now(),
    last_seen       TIMESTAMP,
    notes           TEXT
);

Existe en cada servidor de forma independiente (adempiere schema en ambos).


Configuración de servidores monitoreados

En monitor.html e index.html, el array SERVERS define qué servidores se consultan:

const SERVERS = [
  {
    label: 'KontrolesERP INROCAR',
    url:   TEST_URL,                      // auto-detectado por hostname
    key:   'kontroles_monitor_2024',
  },
  {
    label: 'KontrolesERP JAASA',
    url:   'https://erp.jaasadecv.com',
    key:   'kontroles_monitor_2024',
  },
];

TEST_URL se resuelve automáticamente: - Desde host.kontroles.comhttps://host.kontroles.com (evita mixed content) - Desde red local → http://192.168.1.99:8090

Para agregar un nuevo servidor basta con añadir una entrada al array y desplegar con ./deploy.sh all.


Despliegue

cd /home/rrodriguez/Develop/apps/kontrolesapi

./deploy.sh           # INROCAR + JAASA
./deploy.sh inrocar   # solo INROCAR
./deploy.sh jaasa     # solo JAASA

Archivos desplegados: .htaccess, api/router.php, config/database.php, todos los módulos PHP, y los HTML estáticos.


CORS — Problema triple-header en JAASA

JAASA usa Nginx Proxy Manager (openresty). NPM agrega sus propios CORS headers a nivel server, PHP agrega los suyos vía header(). La solución en server_proxy.conf:

location /api {
    proxy_hide_header Access-Control-Allow-Origin;
    proxy_hide_header Access-Control-Allow-Methods;
    proxy_hide_header Access-Control-Allow-Headers;

    more_set_headers 'Access-Control-Allow-Origin: *';
    more_set_headers 'Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS';
    more_set_headers 'Access-Control-Allow-Headers: Authorization, Content-Type, X-App-Source, X-Device-Token, X-Monitor-Key';
    ...
}

proxy_hide_header elimina los de PHP; more_set_headers sobreescribe los de NPM.