Agrego carpeta del source sql de la Base de Datos
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
-- ============================================================================
|
||||
-- internal.app_config
|
||||
-- ============================================================================
|
||||
-- Configuración runtime del sistema. Pares clave/valor (ambos TEXT).
|
||||
-- Lee internal.get_config_int y fc_obtener_config.
|
||||
-- ============================================================================
|
||||
|
||||
CREATE TABLE internal.app_config (
|
||||
clave text NOT NULL,
|
||||
valor text NOT NULL,
|
||||
descripcion text,
|
||||
actualizado_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
CONSTRAINT app_config_pkey PRIMARY KEY (clave)
|
||||
);
|
||||
@@ -0,0 +1,72 @@
|
||||
-- ============================================================================
|
||||
-- internal.archivo_exports
|
||||
-- ============================================================================
|
||||
-- Bitácora de control del pipeline mensual de archivado
|
||||
-- (Documentation/PoliticaRetencion.md §5.3). Cada fila registra un intento
|
||||
-- de archivar una entidad para un mes objetivo: su resultado, cuándo
|
||||
-- ocurrió y, si falló, el detalle del error.
|
||||
--
|
||||
-- Cumple tres roles:
|
||||
-- - IDEMPOTENCIA: el unique parcial garantiza que no haya dos archivados
|
||||
-- `ok` para el mismo (anio_mes_target, tipo). Si la corrida mensual se
|
||||
-- repite (reintento, doble disparo del cron), el segundo `ok` choca y
|
||||
-- no se duplica el archivado ni el DELETE posterior.
|
||||
-- - REINTENTO: una fila `fallo` deja registrado el mes pendiente; la
|
||||
-- corrida siguiente puede detectar que ese mes no tiene `ok` y
|
||||
-- reprocesarlo (los meses pendientes tienen prioridad — §5.2).
|
||||
-- - VISIBILIDAD: la vista admin (US-R21) lee esta tabla vía
|
||||
-- public.fc_obtener_estado_archivo.
|
||||
--
|
||||
-- COLUMNAS
|
||||
-- anio_mes_target DATE (día 1 del mes archivado). NULLABLE a propósito:
|
||||
-- durante el primer año de vida del sistema ningún pago
|
||||
-- cumple 12 meses, así que la corrida de pagos archiva
|
||||
-- "nada" y registra `ok` con target NULL (§4.3, US-R17).
|
||||
-- Los NULL son distintos entre sí en el unique parcial,
|
||||
-- de modo que esas corridas vacías no se bloquean entre
|
||||
-- ellas — son no-ops inofensivos.
|
||||
-- tipo 'pagos' | 'agregado_reservas'. Las dos cosas que se
|
||||
-- archivan (§3); cada una lleva su propia fila por mes.
|
||||
-- ejecutado_en timestamptz del intento (default now()).
|
||||
-- resultado 'ok' | 'fallo'.
|
||||
-- detalle_error texto libre del error cuando resultado = 'fallo';
|
||||
-- NULL en los `ok`.
|
||||
--
|
||||
-- AUTORIZACIÓN
|
||||
-- Tabla en el schema `internal`, no alcanzable por roles cliente
|
||||
-- (hardening en 00_schemas.sql). Escribe el pipeline (US-R17); lee la
|
||||
-- fachada public.fc_obtener_estado_archivo (SECURITY DEFINER).
|
||||
--
|
||||
-- DEPENDE DE
|
||||
-- Nada (sin FKs). Nivel 0 en apply.sh.
|
||||
-- ============================================================================
|
||||
|
||||
CREATE TABLE internal.archivo_exports (
|
||||
id integer GENERATED ALWAYS AS IDENTITY (
|
||||
SEQUENCE NAME internal.archivo_exports_id_seq
|
||||
START WITH 1 INCREMENT BY 1
|
||||
NO MINVALUE NO MAXVALUE CACHE 1
|
||||
) NOT NULL,
|
||||
anio_mes_target date,
|
||||
tipo text NOT NULL,
|
||||
ejecutado_en timestamp with time zone DEFAULT now() NOT NULL,
|
||||
resultado text NOT NULL,
|
||||
detalle_error text,
|
||||
CONSTRAINT archivo_exports_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT archivo_exports_tipo_check
|
||||
CHECK (tipo IN ('pagos', 'agregado_reservas')),
|
||||
CONSTRAINT archivo_exports_resultado_check
|
||||
CHECK (resultado IN ('ok', 'fallo'))
|
||||
);
|
||||
|
||||
-- Idempotencia: a lo sumo un `ok` por (mes, tipo). Parcial sobre 'ok' para
|
||||
-- que los reintentos fallidos no cuenten y puedan repetirse hasta lograrlo.
|
||||
CREATE UNIQUE INDEX archivo_exports_ok_unico
|
||||
ON internal.archivo_exports (anio_mes_target, tipo)
|
||||
WHERE resultado = 'ok';
|
||||
|
||||
-- Para listar fallos recientes y barrer pendientes por mes.
|
||||
CREATE INDEX idx_archivo_exports_target_tipo
|
||||
ON internal.archivo_exports (anio_mes_target, tipo, ejecutado_en DESC);
|
||||
|
||||
ALTER TABLE internal.archivo_exports ENABLE ROW LEVEL SECURITY;
|
||||
@@ -0,0 +1,21 @@
|
||||
-- ============================================================================
|
||||
-- internal.permisos
|
||||
-- ============================================================================
|
||||
-- Matriz de autorización. Cada fila es una acción posible del sistema y
|
||||
-- el array de roles que la pueden ejecutar. La consulta canónica está en
|
||||
-- internal.validate_permission.
|
||||
-- ============================================================================
|
||||
|
||||
CREATE TABLE internal.permisos (
|
||||
id integer GENERATED ALWAYS AS IDENTITY (
|
||||
SEQUENCE NAME internal.permisos_id_permiso_seq
|
||||
START WITH 1 INCREMENT BY 1
|
||||
NO MINVALUE NO MAXVALUE CACHE 1
|
||||
) NOT NULL,
|
||||
accion text NOT NULL,
|
||||
roles_permitidos text[] NOT NULL,
|
||||
CONSTRAINT permisos_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT permisos_accion_key UNIQUE (accion)
|
||||
);
|
||||
|
||||
ALTER TABLE internal.permisos ENABLE ROW LEVEL SECURITY;
|
||||
@@ -0,0 +1,31 @@
|
||||
-- ============================================================================
|
||||
-- internal.sesiones
|
||||
-- ============================================================================
|
||||
-- Sesiones activas. Cada usuario tiene a lo sumo una sesión vigente; el
|
||||
-- trigger trg_clean_old_sessions (definido en triggers/auth/) lo garantiza
|
||||
-- al insertar.
|
||||
--
|
||||
-- DEPENDE DE
|
||||
-- public.usuarios
|
||||
-- ============================================================================
|
||||
|
||||
CREATE TABLE internal.sesiones (
|
||||
id uuid DEFAULT gen_random_uuid() NOT NULL,
|
||||
usuario_id uuid NOT NULL,
|
||||
token uuid NOT NULL,
|
||||
expires_at timestamp with time zone NOT NULL,
|
||||
CONSTRAINT sessions_pkey PRIMARY KEY (id),
|
||||
CONSTRAINT sessions_usuario_id_fkey
|
||||
FOREIGN KEY (usuario_id) REFERENCES public.usuarios(id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_sesiones_token
|
||||
ON internal.sesiones USING btree (token);
|
||||
|
||||
CREATE INDEX idx_sesiones_token_expires
|
||||
ON internal.sesiones USING btree (token, expires_at);
|
||||
|
||||
CREATE INDEX idx_sesiones_usuario_expires
|
||||
ON internal.sesiones USING btree (usuario_id, expires_at);
|
||||
|
||||
ALTER TABLE internal.sesiones ENABLE ROW LEVEL SECURITY;
|
||||
Reference in New Issue
Block a user