-- ============================================================
-- MÓDULO: tenant_unidades_administrativas
-- Versión estándar: 2026-06-24
-- ============================================================
CREATE TABLE administrative_units (
id UUID STORAGE PLAIN DEFAULT gen_random_uuid() NOT NULL,
tenant_id UUID STORAGE PLAIN NOT NULL,
code VARCHAR(20) NOT NULL, -- Inmutable tras creación
name_short VARCHAR(100) NOT NULL,
name_long VARCHAR(300),
unit_function TEXT, -- Descripción de responsabilidades (sin límite)
origin_id INTEGER STORAGE PLAIN NOT NULL, -- FK → origins.id
state_id VARCHAR(100) NOT NULL, -- 'active' | 'inactive' | 'archived'
created_at TIMESTAMP WITH TIME ZONE STORAGE PLAIN DEFAULT now() NOT NULL,
updated_at TIMESTAMP WITH TIME ZONE STORAGE PLAIN DEFAULT now() NOT NULL,
created_by UUID STORAGE PLAIN NOT NULL,
updated_by UUID STORAGE PLAIN NOT NULL,
archived_at TIMESTAMP WITH TIME ZONE STORAGE PLAIN,
archived_by UUID STORAGE PLAIN,
CONSTRAINT administrative_units_pkey PRIMARY KEY (id),
CONSTRAINT administrative_units_tenant_code_key UNIQUE (tenant_id, code),
CONSTRAINT administrative_units_state_check CHECK (state_id IN ('active', 'inactive', 'archived')),
CONSTRAINT administrative_units_tenant_fkey FOREIGN KEY (tenant_id) REFERENCES tenants(id),
CONSTRAINT administrative_units_origin_fkey FOREIGN KEY (origin_id) REFERENCES origins(id),
CONSTRAINT administrative_units_created_fkey FOREIGN KEY (created_by) REFERENCES users(id),
CONSTRAINT administrative_units_updated_fkey FOREIGN KEY (updated_by) REFERENCES users(id),
CONSTRAINT administrative_units_archived_fkey FOREIGN KEY (archived_by) REFERENCES users(id)
);
-- Índices
CREATE INDEX idx_au_tenant ON administrative_units(tenant_id);
CREATE INDEX idx_au_state ON administrative_units(state_id);
CREATE INDEX idx_au_origin ON administrative_units(origin_id);
CREATE INDEX idx_au_active ON administrative_units(tenant_id) WHERE archived_at IS NULL;
-- ============================================================
-- REGISTRO SENTINEL (insertado automáticamente al aprovisionar tenant)
-- ============================================================
-- INSERT INTO administrative_units
-- (tenant_id, code, name_short, name_long, origin_id, state_id, created_by, updated_by)
-- VALUES
-- (, '0', 'No aplica', 'Sin unidad administrativa asignada',
-- 1, 'active', , );
--
-- El sentinel NO se muestra en la UI de gestión.
-- Es el valor por defecto en FKs de tablas transaccionales cuando
-- una transacción no tiene unidad administrativa asignada.
-- ============================================================
-- REGLAS DE NEGOCIO
-- ============================================================
-- RN-001: code es inmutable tras creación (422 IMMUTABLE_FIELD si se intenta cambiar)
-- RN-002: No existe DELETE físico — soft delete vía archived_at + archived_by
-- RN-003: state_id inicial siempre 'active'
-- RN-004: origin_id lo asigna el backend; nunca en el body del request
-- RN-005: El registro sentinel (code='0') es de solo lectura — ni editable ni archivable
-- RN-006: unit_function es TEXT nullable — sin límite de caracteres impuesto por la UI
-- ============================================================
-- DATOS DE EJEMPLO — INSTITUCIÓN EDUCATIVA PÚBLICA
-- ============================================================
-- ('0', 'No aplica', 'Sin unidad administrativa asignada', NULL)
-- ('DIR', 'Dirección General', 'Unidad de Dirección General (Rectoría)', '...')
-- ('SEC', 'Secretaría Académica', 'Unidad de Secretaría Académica y General', '...')
-- ('FIN', 'Financiera y Presup.', 'Unidad Financiera y de Presupuesto', '...')
-- ('COOR', 'Coordinación', 'Unidad de Coordinación Acad. y Convivencia', '...')
-- ('SRV', 'Servicios Generales', 'Unidad de Servicios Generales y Almacén', '...')
-- ('BIE', 'Bienestar Inst.', 'Unidad de Bienestar Institucional', '...')
-- ============================================================