Ir al contenido

Tenants y ambientes

TwiinsHRM es multi-tenant: cada empresa cliente es un tenant con su propio alias (por ejemplo twiins) y su propia base de datos. El alias identifica al tenant en cada petición mediante el header x-tenant-id.

En el portal web el tenant se deriva del subdominio ({alias}.twiinshrm.com). En una app móvil no hay subdominio, así que el alias debe configurarse o seleccionarse antes del login (por ejemplo, pidiendo el código de empresa en la primera pantalla) y persistirse localmente. Si el usuario conoce el dominio de su portal web, el alias puede resolverse automáticamente — ver Resolver el alias desde un dominio.

Ambiente URL base
Producción https://api-v4.twiinshrm.com/prod
Staging / pruebas https://api-v4.twiinshrm.com/dev
Local (desarrollo del backend) http://localhost:3000

Los paths de este manual se anexan a la URL base. Ejemplo en producción:

POST https://api-v4.twiinshrm.com/prod/auth/login
GET https://api-v4.twiinshrm.com/prod/v2/muro/publications

Algunos tenants usan en la web un dominio distinto de su alias canónico (por ejemplo, el portal somos.twiinshrm.com pertenece al tenant twiins). Si la app pide al usuario el dominio que conoce, ese valor no sirve directo como x-tenant-id: primero hay que resolver el alias.

Para eso existe un endpoint público servido por el frontend web. Su URL base no es api-v4.twiinshrm.com — vive bajo /v4 de cualquier dominio de tenant:

Ambiente URL
Producción https://{subdominio}.twiinshrm.com/v4/api/tenant-alias
Staging / pruebas https://{subdominio}.twiinshrmprueba.com/v4/api/tenant-alias

{subdominio} puede ser el mismo valor que ingresó el usuario: si escribió somos, la app llama a somos.twiinshrm.com.

Sin autenticación ni headers especiales (tampoco requiere x-tenant-id). CORS abierto; la respuesta es cacheable por 5 minutos.

Query param Requerido Descripción
domain Subdominio (somos), hostname (somos.twiinshrm.com) o URL completa. El endpoint normaliza mayúsculas, puerto y path. Sin este parámetro responde 400.

Respuesta 200:

{ "domain": "somos", "alias": "twiins" }
Envías domain= Recibes alias Comportamiento
somos twiins Subdominio mapeado a su alias canónico.
somos.twiinshrm.com twiins Extrae el subdominio del hostname y resuelve.
acme acme Sin mapeo: devuelve el mismo subdominio (eco).

Ejemplo:

Ventana de terminal
curl "https://somos.twiinshrm.com/v4/api/tenant-alias?domain=somos"
# → { "domain": "somos", "alias": "twiins" }

Estos endpoints son públicos (solo requieren x-tenant-id) y permiten configurar la app antes de autenticar:

sequenceDiagram
    participant App as App móvil
    participant API as th-core-api

    App->>API: GET /tenancy (x-tenant-id)
    API-->>App: Datos del tenant (valida que el alias existe)
    App->>API: GET /tenancy/parameters/login (x-tenant-id)
    API-->>App: Parámetros de login (SSO, branding)
    App->>App: Decidir pantalla: credenciales o SSO

Información básica del tenant. Úsalo para validar que el alias ingresado por el usuario existe antes de continuar.

Parámetros necesarios antes de autenticar. Los más relevantes para mobile:

Parámetro Valores Uso en la app
Login_SSO 'S' / 'N' Si es 'S', el login es por Keycloak (SSO + PKCE); si no, formulario de credenciales.
Skin_Sistema color hex Color primario de la marca del tenant — úsalo para tematizar la app.

Catálogo completo de parámetros del tenant (requiere contexto de tenant). Aquí viven los flags de configuración que condicionan funcionalidades; cada módulo documenta los suyos.

Autenticado. Devuelve los productos/módulos habilitados para el usuario en ese tenant. Úsalo después del login para decidir qué secciones mostrar en el menú de la app: si un módulo no está habilitado, no debe aparecer.

  1. Pedir/recuperar el alias del tenant (o resolverlo desde el dominio que conoce el usuario) → GET /tenancy para validarlo.
  2. GET /tenancy/parameters/login → decidir login por credenciales o SSO, y aplicar branding.
  3. Autenticar (ver Autenticación).
  4. GET /auth/session + GET /me/tenancy/products → construir el home y el menú según el usuario.