Especificación Técnica: mae_entidades¶
Esquema: core.identidad
Base de Datos: core
Servicio: svc-identidad
Tabla Legacy Origen: — (nueva, patrón party)
Propósito: Raíz polimórfica de la que "heredan" personas naturales (mae_personas) y jurídicas (mae_personas_juridicas). mae_usuarios referencia una entidad sin importar el subtipo.
1. Justificación y Mejoras de Arquitectura¶
- Patrón party: un usuario puede representar a una persona natural (cédula) o a una persona jurídica externa (RUC);
mae_usuariosnecesita un único FK (entidad_id) y no debe condicionar en código. - Herencia por tabla (joined table inheritance): el
idnace aquí y la fila hija copia el mismo UUID; las hijas no tienenDEFAULT gen_random_uuid(). tipo_entidades el discriminador (PERSONA_NATURAL/PERSONA_JURIDICA).- Tabla global (sin
empresa_idni RLS): igual quemae_personas, la identidad no pertenece a una sola empresa. - Sin columnas de auditoría propias: el estado (
is_activo) y la auditoría viven en cada subtipo (mae_personas,mae_personas_juridicas).
2. Definiciones de Implementación¶
Table core.identidad.mae_entidades {
id uuid [pk, default: `gen_random_uuid()`]
tipo_entidad varchar(20) [not null, note: 'PERSONA_NATURAL | PERSONA_JURIDICA']
Note: 'CHECK chk_mae_entidades_tipo: tipo_entidad IN (PERSONA_NATURAL, PERSONA_JURIDICA)'
}
CREATE TABLE IF NOT EXISTS core.identidad.mae_entidades (
id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
tipo_entidad VARCHAR(20) NOT NULL,
CONSTRAINT chk_mae_entidades_tipo
CHECK (tipo_entidad IN ('PERSONA_NATURAL', 'PERSONA_JURIDICA'))
);
-- Comentarios
COMMENT ON COLUMN core.identidad.mae_entidades.tipo_entidad IS 'Discriminador (PERSONA_NATURAL/PERSONA_JURIDICA)';
class MaeEntidad(Base):
__tablename__ = 'mae_entidades'
__table_args__ = (
CheckConstraint(
"tipo_entidad IN ('PERSONA_NATURAL', 'PERSONA_JURIDICA')",
name='chk_mae_entidades_tipo',
),
{"schema": 'identidad'},
)
id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True),
primary_key=True,
server_default=text("gen_random_uuid()"),
)
tipo_entidad: Mapped[str] = mapped_column(
String(20),
nullable=False,
comment='Discriminador (PERSONA_NATURAL/PERSONA_JURIDICA)',
)
__mapper_args__ = {
"polymorphic_on": tipo_entidad,
"with_polymorphic": "*",
}
@property
def nombre_mostrar(self) -> str:
raise NotImplementedError
"""Pertenece a la migración 0005_entidades de svc-identidad.
revision: 0005_entidades
down_revision: 0004_usuarios
create table identidad.mae_entidades
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
def upgrade() -> None:
op.create_table(
'mae_entidades',
sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True, server_default=sa.text("gen_random_uuid()")),
sa.Column("tipo_entidad", sa.String(length=20), nullable=False),
sa.CheckConstraint(
"tipo_entidad IN ('PERSONA_NATURAL', 'PERSONA_JURIDICA')",
name="chk_mae_entidades_tipo",
),
schema='identidad',
)
def downgrade() -> None:
op.drop_table('mae_entidades', schema='identidad')