4. Clientes, organizaciones y niveles de acceso
Multi-tenant en iDempiere no es una capa de infraestructura (como una base de datos por cliente): es un modelo de datos. Entender Cliente, Organización, Nivel de acceso y Rol es necesario antes de tocar cualquier tabla, porque decide qué datos son “de todo el servidor”, cuáles son “de una empresa” y cuáles son “de una sucursal de esa empresa” — y esa decisión no se puede cambiar después sin migrar datos.
System vs. tenant
Sección titulada «System vs. tenant»AD_Client_ID = 0es el tenant System: no es una empresa, es el nivel donde vive todo lo que es igual para todo el servidor — la definición del Diccionario de Aplicación en sí (AD_Table,AD_Window,AD_Process…), la configuración global (AD_SysConfig), y en FINORA LVE los datos normativos que aplican a cualquier tenant (la tabla de Unidad Tributaria, los conceptos de ISLR, ver Tutorial 8).- Cualquier otro
AD_Client_IDes un tenant real: una empresa instalada en ese servidor (DC GEEKS es el tenant piloto de FINORA,AD_Client_ID 1000000). Un tenant no ve ni puede escribir los datos de otro — el propio modeloPOrechaza un intento de mezclar clientes (finora-erp-experience/idempiere/API_MAP.md, §6.2 documenta el error real “Cross tenant PO writing” cuando un plugin intenta guardar, sin querer, un registro de otro cliente).
Organización: una empresa tiene varias
Sección titulada «Organización: una empresa tiene varias»Dentro de un AD_Client, la Organización (AD_Org) es la subdivisión operativa: sucursales,
almacenes, centros de costo, unidades de negocio. AD_Org_ID = 0 significa “toda la organización” (un
dato visible desde cualquier organización del cliente, como el catálogo de productos suele ser).
Casi toda tabla transaccional lleva ambas columnas, AD_Client_ID y AD_Org_ID — es la base con
la que el motor de seguridad filtra qué ve cada persona.
Nivel de acceso de una tabla (AccessLevel)
Sección titulada «Nivel de acceso de una tabla (AccessLevel)»Cada AD_Table declara a qué nivel viven sus filas — esto no es por fila individual, es una
propiedad de la tabla entera:
| AccessLevel | Significado | Ejemplo en FINORA LVE |
|---|---|---|
1 (System only) | Solo en el tenant 0 | Definiciones del Diccionario mismo |
4 (Client only) | Una fila por tenant, sin organización | — |
3 (Client+Org) | Configuración y transacciones normales de un tenant | FVE_ControlNoRange, FVE_InvoiceWithholding (finora-lve/docs/ARCHITECTURE.md, §3.2) |
6 (System+Client) | Filas de System que un tenant puede leer, y agregar las suyas propias | Datos normativos: FVE_TaxUnit, FVE_ISLRConcept |
7 (All) | System, Client u Org, con precedencia entre ellas | FVE_Config: fila System = valor de producto, fila de tenant en organización 0, fila de organización — se resuelve organización → tenant → System → valor por defecto del código (finora-lve/decisions/ADR.md, ADR-LVE-013) |
Elegir mal el AccessLevel de una tabla nueva es difícil de corregir después (cambia qué filas
“existen” para cada tenant), así que FINORA LVE lo decide explícitamente para cada tabla que agrega,
nunca lo deja en el valor por defecto sin pensarlo.
Roles: qué puede hacer cada persona
Sección titulada «Roles: qué puede hacer cada persona»El Rol (AD_Role) es la unidad de permisos: qué ventanas, qué columnas, qué organizaciones y qué
acciones de documento puede usar una persona con ese rol. Una persona (AD_User) puede tener varios
roles y elige uno al iniciar sesión (junto con el cliente, la organización y el almacén — el primer
paso de cualquier tutorial de Guías de usuario). Los
permisos por rol se aplican tanto en ZK como en REST, porque ambos consultan el mismo
MRole — con una salvedad documentada: por defecto, cualquier rol autenticado puede
leer casi cualquier tabla por REST salvo que exista una exclusión explícita en
AD_Table_Access (MRole.isTableAccess, citado en
finora-erp-experience/idempiere/API_MAP.md, §7.2: “role can always read” a menos que se configure
lo contrario). Esto es una decisión de diseño del core a tener en cuenta al dar acceso de integración
por REST, no un error.
Cómo se ve esto en FINORA LVE
Sección titulada «Cómo se ve esto en FINORA LVE»El perfil fiscal de un tenant (FVE_TaxpayerProfile) se define por organización, con vigencia por
fecha: una empresa puede ser agente de retención de IVA en una sucursal y no en otra, o dejar de serlo
a partir de una fecha sin perder el historial de lo que ya declaró (finora-lve/docs/ARCHITECTURE.md,
§5.2). Esto solo es posible porque el modelo Cliente/Organización ya existía en el core: FINORA no
tuvo que inventar un concepto de “sucursal” propio, lo reutilizó.
Fuentes
Sección titulada «Fuentes»finora-lve/docs/ARCHITECTURE.md, §1 y §3.2 (restricción de REST en System, tabla de AccessLevel)finora-lve/decisions/ADR.md, ADR-LVE-013 (FVE_Config y el orden de resolución por nivel)finora-erp-experience/idempiere/API_MAP.md, §6.2 y §7.2 (Cross tenant PO writing, lectura por rol)- What is iDempiere? — iDempiere Developer