Gerege Nexus¶
Production · Capa 3 — Base de plataforma ·
Repositorio: open-gerege-nexus · nexus.gerege.mn
Una plataforma unificada de servicios, operaciones y sistemas. Una plataforma modular que reúne sobre una misma base los servicios, las operaciones, los sistemas y los datos de organizaciones públicas y privadas. Código abierto, licencia Apache 2.0.
Nexus significa punto de conexión: donde se encuentran organizaciones, servicios, flujos de trabajo, sistemas, usuarios y datos. La plataforma en sí no apunta a ningún sector concreto: son los módulos que corren sobre ella los que definen las necesidades de cada organización.
El modelo del ecosistema está cambiando
Gerege Nexus es la base sucesora de la Template Platform. El modelo anterior era «una plantilla → un fork por producto»; el nuevo es «un upstream (Nexus) → un fork por marca, actualizado fusionando desde upstream». La transición está en curso: las plataformas existentes siguen en producción. Véase Arquitectura por capas.
La diferencia esencial: una aplicación es un módulo¶
En el modelo anterior, un producto nuevo significaba un repositorio nuevo, un despliegue nuevo y una base de datos nueva. En Nexus, un producto nuevo suele ser un módulo nuevo: una aplicación compilada en el mismo binario que cada inquilino puede activar o desactivar.
| Modelo Template (anterior) | Modelo Nexus (nuevo) | |
|---|---|---|
| Producto nuevo | Forkear la plantilla | Escribir un módulo y añadirlo al catálogo |
| Distribución | Un despliegue por repositorio | Por inquilino, mediante la tienda de aplicaciones |
| Código compartido | Paquetes open-gerege-core + @gerege/ui-core |
Un único upstream; los forks aguas abajo fusionan desde él |
| Llamadas entre módulos | HTTP (cuando los repositorios están separados) | Llamadas Go dentro del proceso |
| Activar / desactivar | Requiere un despliegue | Lo decide un administrador en app_installations |
Monolito modular¶
Los módulos de negocio implementan el contrato Go Module y se compilan en un
solo binario. Qué aplicaciones están activas para un inquilino dado lo decide
dinámicamente la tabla app_installations en PostgreSQL.
- Sin saltos de red adicionales: los módulos se llaman entre sí dentro del proceso, de modo que no aparecen ni la latencia de los microservicios ni la complejidad de orquestarlos.
- Resolución de dependencias por DAG: las dependencias se resuelven de forma recursiva sobre un grafo dirigido acíclico, con detección de ciclos y validación semver.
- Sincronización del catálogo:
catalog/apps.jsones la única fuente de verdad; la tablaappsse refresca desde él en cada arranque. Añadir una aplicación no exige SQL escrito a mano. - Control de acceso por aplicación: una ruta de una aplicación no instalada
responde
403 Forbidden.
¿Por qué no microservicios?
Las fronteras entre módulos las garantizan interfaces de Go, no la red. Se conserva la garantía de la frontera y se evitan a la vez la latencia de red, las transacciones distribuidas y el coste operativo de muchos despliegues.
Los módulos que vienen con la plataforma¶
| Módulo | ID | Ruta | Propósito |
|---|---|---|---|
| Contacts | io.example.contacts |
/contacts |
Directorio de contactos, autocompletado desde XYP |
| Products | io.example.products |
/products |
Productos, precios, SKU por inquilino |
| Inventory | io.example.inventory |
/inventory |
Almacenes, existencias, registro de movimientos de solo adición |
| Billing & e-Barimt | io.example.billing |
/billing |
Facturas, IVA del 10 %, recibos e-Barimt |
| Digital Documents | io.example.documents |
/documents |
Documentos electrónicos y flujos de aprobación |
| Developer Portal | io.example.developer_portal |
/developer/apps |
Registro de aplicaciones cliente OAuth2 |
| Firma electrónica de PDF | io.example.esign |
/esign |
Firma con validez jurídica mediante eID Mongolia (PIN2) |
| Servicios públicos | io.example.gov_services |
/gov |
Flujo de servicio configurable, jerarquía y SLA |
Flujo configurable de servicio público¶
El módulo gov_services convierte una sola base de código en una capacidad
de prestación de servicios que cada inquilino —y cada servicio dentro de un
inquilino— configura por sí mismo. Elegir entre tres modos no implica ningún
cambio de código:
| Modo | Significado |
|---|---|
LOCAL |
La unidad receptora atiende la solicitud ella misma |
DELEGATE |
Se traslada a una unidad inferior mientras la superior supervisa y verifica |
HYBRID |
Una regla de enrutamiento decide solicitud por solicitud |
El principio rector: el código decide qué es posible; la configuración decide qué se ofrece. La tabla canónica de transiciones vive en el código; una versión publicada puede estrecharla, nunca ampliarla. Por eso un inquilino mal configurado no puede alcanzar un estado imposible.
Otras garantías:
- El estado lo calcula el servidor: el cliente envía una acción, nunca un estado.
- Que una unidad inferior termine su trabajo no cierra la solicitud: cuando
un paso exige verificación, la finalización queda en
AWAITING_VERIFICATION. - El retraso se deriva (
due_at < now()) y jamás se escribe sobre el estado de negocio. - El aislamiento por inquilino y unidad vive en el esquema: cada clave ajena
es compuesta e incluye
tenant_id, de modo que una fila no puede apuntar a otro inquilino ni aunque el código de aplicación tenga un fallo. - Ingesta idempotente: una solicitud entrante se identifica por
(tenant_id, source_system, external_request_id); un reintento idéntico devuelve"created": false, y una repetición con contenido sustancialmente distinto se rechaza con409. - La notificación saliente pasa por un outbox: un endpoint remoto nunca puede revertir ni bloquear una transición.
Firma electrónica — eID Mongolia (PIN2)¶
El módulo esign se conecta a la firma remota cualificada de eID Mongolia
como parte confiante:
- se calcula el hash del PDF → eID envía ese resumen al teléfono del ciudadano,
- el ciudadano lo aprueba con el PIN2,
- el propio doc-signer de eID incrusta el PKCS#7 junto con los datos OCSP y CRL y compone un PDF firmado en PAdES.
La clave privada de firma nunca llega a la plataforma. El nivel de
certificado es QUALIFIED por defecto: aceptar ADVANCED degradaría en silencio
cada documento que la plataforma produce.
Firmar en nombre de una organización
Los derechos de representación se leen en vivo del registro nacional, no de un certificado, porque un directivo que dimitió ayer sigue teniendo el certificado de ayer.
También se incluyen: registro de firmas (filtros, paginación, exportación CSV), firma por lotes, colocación del sello con vista previa A4, conexión con HSM y política de firma. Un inquilino puede exigir firmas eID cualificadas y desactivar por completo la vía HSM, incluso para quienes llaman directamente a la API.
Autenticación e integración con el Estado¶
- Su propio proveedor OAuth2 / OIDC:
/.well-known/openid-configuration,/oauth2/token,/oauth2/introspect,/oauth2/revoke, conauthorization_code,client_credentialsyrefresh_token. - eID y DAN: los cuatro canales oficiales — firma digital PKI, Mobile OTP, SSO bancario y verificación facial biométrica.
- XYP: registro civil (
WS100101) y verificación de personas jurídicas (WS100201). - Los tokens de sesión son opacos, de 256 bits, y en la base solo se guarda su resumen SHA-256. El cierre de sesión los revoca de verdad.
El modo mock no se ejecuta en producción
Los modos mock de E-ID / DAN / XYP existen solo para desarrollo. Con
ENVIRONMENT=production se apagan automáticamente, de forma que nadie puede
entrar con datos ciudadanos inventados.
IA y resiliencia¶
IA: un asistente Gemini anclado en el estado real de la base de datos del
inquilino (/api/v1/ai/chat, /stt, /tts, /translate), con prompts y base de
conocimiento gestionados por el administrador, más un previsor de demanda de
inventario.
Resiliencia cloud-native (inspirada en go-zero):
| Componente | Función |
|---|---|
| Adaptive circuit breaker | Ratio de fallos sobre ventana deslizante, al estilo SRE de Google |
| Adaptive load shedding | 503 + Retry-After cuando se supera la concurrencia |
| Singleflight coalescing | Fusiona consultas duplicadas y evita el desplome de la caché |
| Exponential backoff retry | Reintenta fallos transitorios con espera exponencial |
Política lingüística¶
Mongol más los seis idiomas oficiales de la ONU = siete en total. El mongol es la fuente. La documentación existe en los siete, pero el software se entrega en mongol e inglés, y los cinco restantes se activan en Configuración → Apariencia. Es el mismo principio que la política i18n de este sitio.
Marcas derivadas¶
Nexus es el upstream; cada marca deriva de él y se actualiza fusionando.
| Marca | Repositorio | Dominio | En qué difiere |
|---|---|---|---|
| Gerege Nexus | open-gerege-nexus |
nexus.gerege.mn |
Upstream, despliegue de referencia |
| Gerege SSO | sso-gerege-nexus |
— | Fork centrado en la capa de inicio de sesión, derechos y acceso |
| Eduge.mn | eduge-mn-nexus |
eduge.mn |
Marca del sector educativo; incorpora un overlay de compilación en el host cuando no se puede tirar de GHCR |
Dos cosas llamadas Gerege SSO
sso-gerege-nexus es el fork nuevo construido sobre Nexus;
sso.gerege.mn en producción sigue ejecutando el
código anterior sso-gerege-mn. No hay que confundirlos: hasta que
la transición concluya, rige el comportamiento descrito en la página
Gerege SSO.
Despliegue¶
Un push a main dispara GitHub Actions: construir y
enviar las imágenes de backend y frontend a GHCR → copiar
docker-compose.prod.yml al servidor → descargar las imágenes → conmutar la API
y el frontend solo cuando las migraciones han terminado → comprobar /health
y /ready. El despliegue arranca únicamente después de que la CI haya pasado
de verdad.
El servidor no necesita nada más que Docker: ni fuentes, ni Go, ni Node.
PUBLIC_ORIGIN define tres cosas a la vez
CORS, el issuer OIDC y el callback de eID se derivan de una sola variable. Cambiarla mueve a la vez el DNS, el certificado TLS y todo cliente que dependa del issuer. Al cambiar de dominio, use la lista de comprobación de Autenticación y autorización.
Stack¶
| Capa | Elección |
|---|---|
| Backend | Go 1.25 · router chi · pgx (sin ORM, SQL escrito a mano) |
| Frontend | Next.js 15 App Router |
| Base de datos | PostgreSQL 16 — esquema compartido, aislado por tenant_id |
| Migraciones | goose (backend/db/migrations/); DDL en tiempo de ejecución prohibido |
| Observabilidad | Prometheus (/metrics) · OpenTelemetry |
| Contenedores | Docker Compose · GHCR |
Para el panorama de todo el ecosistema, véase Stack tecnológico.
Documentación detallada¶
La documentación a nivel de implementación vive en el repositorio, en siete idiomas:
| Documento | Contenido |
|---|---|
README.md |
Visión general de la plataforma (7 idiomas) |
docs/ARCHITECTURE_SPECIFICATION.md |
Capas y decisiones de arquitectura (MN/EN) |
docs/MODULE_AUTHORING_GUIDE.md |
Cómo escribir un nuevo módulo de aplicación |
docs/GOV_SERVICES_WORKFLOW.md |
El modelo completo del flujo de servicio público |
docs/DOCUMENTS_SIGNING.md |
La ceremonia de firma y su contrato |
docs/TRANSLATION_GUIDE.md |
La guía de traducción a siete idiomas |
CHANGELOG.md |
Cambios por versión |