From 80f4a3c1f49af241170a7c57d24f2952e05e36ec Mon Sep 17 00:00:00 2001 From: Anderson Herrera <43342146+andersonhg19@users.noreply.github.com> Date: Mon, 21 Sep 2026 22:53:45 -0500 Subject: [PATCH 01/14] feat: complete physical data model with business constraints (HU-001..HU-004) --- docs/database/schema.sql | 696 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 662 insertions(+), 34 deletions(-) diff --git a/docs/database/schema.sql b/docs/database/schema.sql index e34dfe0..0fa6594 100644 --- a/docs/database/schema.sql +++ b/docs/database/schema.sql @@ -1,12 +1,80 @@ --- ============================================================= --- Modelo físico inicial — Sprint 1 (Plataforma de Reservas) --- PostgreSQL 15+ (Supabase). Generado a partir del mapeo JPA --- (hibernate ddl-auto=update en local; validate en la nube). --- Las credenciales viven en auth.users (Supabase); aquí solo --- perfiles de negocio y soporte de autenticación. --- ============================================================= - --- Perfil de cliente (HU-001). id = auth.users.id +-- ===================================================================== +-- Plataforma de Reservas de Servicios — modelo físico +-- Sprint 1 · Bases de Datos · CodeF@ctory 2026-II +-- +-- PostgreSQL 15+ (probado en 16). Compatible con Supabase. +-- Contra una base vacía crea las 19 tablas sin errores. +-- +-- También corre contra una base que ya tenga `clients` y +-- `login_attempts` del mapeo JPA: esas dos se saltan, y sus +-- restricciones se añaden con bloques DO porque +-- `create table if not exists` no las agrega si la tabla ya existe. +-- +-- Lo que este esquema NO garantiza está al final del archivo. +-- ===================================================================== + +-- En Supabase las extensiones van en el esquema `extensions`; +-- en un Postgres normal ese esquema no existe y cae al search_path. +do $$ +begin + create extension if not exists btree_gist with schema extensions; +exception when others then + create extension if not exists btree_gist; +end $$; + +-- PostgreSQL trae tstzrange y daterange, pero no un rango de `time`. +do $$ +begin + create type timerange as range (subtype = time); +exception when duplicate_object then null; +end $$; + + +-- ===================================================================== +-- Catálogos +-- Separados para eliminar dependencias transitivas (3FN). +-- ===================================================================== + +create table if not exists cities ( + id uuid primary key default gen_random_uuid(), + name varchar(120) not null, + region varchar(120) not null, -- departamento: hay municipios homónimos + constraint uk_cities_name_region unique (name, region), + constraint ck_cities_name check (length(btrim(name)) > 0) +); + +create table if not exists organization_categories ( + id uuid primary key default gen_random_uuid(), + name varchar(80) not null, + constraint uk_organization_categories_name unique (name), + constraint ck_organization_categories_name check (length(btrim(name)) > 0) +); + +create table if not exists currencies ( + id uuid primary key default gen_random_uuid(), + code char(3) not null, + name varchar(60) not null, + active boolean not null default true, -- la baja es lógica: hay servicios que la referencian + constraint uk_currencies_code unique (code), + constraint uk_currencies_name unique (name), + constraint ck_currencies_code check (code ~ '^[A-Z]{3}$') -- ISO 4217 +); + + +-- ===================================================================== +-- Identidad +-- Las credenciales viven en auth.users de Supabase, que este script no +-- crea. Por eso clients.id, organization_members.user_id y +-- account_status_changes.changed_by no tienen clave foránea declarada. +-- +-- El perfil del personal de una organización tampoco vive aquí: de un +-- miembro sólo guardamos la membresía y el rol, y sus datos personales +-- quedan en auth.users. Duplicarlos en una tabla propia repetiría lo +-- que clients ya modela para el cliente final. +-- ===================================================================== + +-- clients: ya implementada por el equipo (ClientEntity). +-- No se altera ninguna columna ni ningún tipo. create table if not exists clients ( id uuid not null, full_name varchar(120) not null, @@ -15,43 +83,603 @@ create table if not exists clients ( email varchar(160) not null, phone varchar(20) not null, city varchar(80) not null, - notification_channel varchar(20) not null, -- EMAIL | SMS | WHATSAPP - status varchar(30) not null, -- PENDING_VERIFICATION | ACTIVE | SUSPENDED + notification_channel varchar(20) not null, + status varchar(30) not null, created_at timestamp(6) not null, updated_at timestamp(6) not null, - primary key (id), - constraint uk_clients_email unique (email), - constraint uk_clients_document unique (document) + constraint pk_clients primary key (id) ); --- Intentos de login para la política de bloqueo (HU-021) +-- Las restricciones van aparte: si la tabla ya existía, el +-- `create table if not exists` de arriba no habría añadido ninguna. +do $$ +begin + alter table clients add constraint uk_clients_email unique (email); +exception when duplicate_table or duplicate_object then null; end $$; +do $$ +begin + alter table clients add constraint uk_clients_document unique (document); +exception when duplicate_table or duplicate_object then null; end $$; +do $$ +begin + alter table clients add constraint ck_clients_status + check (status in ('PENDING_VERIFICATION', 'ACTIVE', 'SUSPENDED')); +exception when duplicate_object then null; end $$; +do $$ +begin + alter table clients add constraint ck_clients_notification_channel + check (notification_channel in ('EMAIL', 'SMS', 'WHATSAPP')); +exception when duplicate_object then null; end $$; +do $$ +begin + -- HU-001: no se permite autorregistro de menores de 18 años + alter table clients add constraint ck_clients_adult + check (birth_date <= current_date - interval '18 years'); +exception when duplicate_object then null; end $$; +do $$ +begin + -- HU-001: "rechazo por formato inválido de correo o teléfono" + alter table clients add constraint ck_clients_email_formato + check (email ~* '^[^@[:space:]]+@[^@[:space:]]+\.[a-z]{2,}$'); +exception when duplicate_object then null; end $$; +do $$ +begin + alter table clients add constraint ck_clients_phone_formato + check (phone ~ '^\+?[0-9]{7,15}$'); +exception when duplicate_object then null; end $$; + +-- El unique del equipo distingue mayúsculas, así que Ana@x.com y +-- ana@x.com entran como dos cuentas. Este índice lo cierra sin +-- quitarles nada. +create unique index if not exists ux_clients_email_lower on clients (lower(email)); + +-- login_attempts: ya implementada por el equipo. Soporta el bloqueo por +-- cuenta de HU-021, que GoTrue no cubre porque sólo limita por IP. create table if not exists login_attempts ( - id bigint generated by default as identity, + id bigint generated by default as identity, email varchar(160) not null, success boolean not null, attempted_at timestamp(6) not null, - primary key (id) + constraint pk_login_attempts primary key (id) +); + + +-- ===================================================================== +-- Organización (HU-002, HU-003) +-- ===================================================================== + +create table if not exists organizations ( + id uuid primary key default gen_random_uuid(), + category_id uuid not null, + name varchar(160) not null, + nit varchar(20) not null, + contact_email varchar(160) not null, + contact_phone varchar(20) not null, + timezone varchar(60) not null default 'America/Bogota', + status varchar(30) not null default 'PENDING_APPROVAL', + approved_at timestamptz, + created_at timestamptz not null default now(), + updated_at timestamptz not null default now(), + + constraint uk_organizations_nit unique (nit), -- HU-002: NIT único + + constraint fk_organizations_category foreign key (category_id) references organization_categories (id) on delete restrict, + + constraint ck_organizations_status check (status in ('PENDING_APPROVAL', 'ACTIVE', 'SUSPENDED', 'REJECTED')), + constraint ck_organizations_name check (length(btrim(name)) > 0), + constraint ck_organizations_nit check (length(btrim(nit)) > 0), + constraint ck_organizations_email check (contact_email ~* '^[^@[:space:]]+@[^@[:space:]]+\.[a-z]{2,}$'), + -- Sólo ACTIVE y SUSPENDED pueden tener fecha de aprobación, y ACTIVE + -- la exige: no hay organización activa sin registro de quién la aprobó + constraint ck_organizations_approved check ( + (status = 'ACTIVE' and approved_at is not null) or + (status in ('PENDING_APPROVAL','REJECTED') and approved_at is null) or + (status = 'SUSPENDED')) +); + +create table if not exists organization_members ( + id uuid primary key default gen_random_uuid(), + organization_id uuid not null, + user_id uuid not null, + role varchar(30) not null, + created_at timestamptz not null default now(), + -- La PK sustituta se conserva porque así la diseñó el equipo; la clave + -- natural queda como UNIQUE, que preserva igual la dependencia funcional. + constraint uk_organization_members unique (organization_id, user_id), + constraint fk_organization_members_org foreign key (organization_id) references organizations (id) on delete cascade, + constraint ck_organization_members_role check (role in ('OWNER', 'MANAGER', 'STAFF')) +); + +-- Política versionada. HU-002 pide que los cambios apliquen sólo a las +-- reservas nuevas, así que en vez de copiar los parámetros en cada +-- reserva, cada reserva apunta a la versión que regía al crearse. +create table if not exists organization_policies ( + id uuid primary key default gen_random_uuid(), + organization_id uuid not null, + version integer not null, + booking_notice_minutes_min integer not null, + booking_notice_minutes_max integer not null, + free_cancellation_window_minutes integer not null, + effective_from timestamptz not null default now(), + replaced_at timestamptz, + + constraint uk_organization_policies_version unique (organization_id, version), + constraint uk_organization_policies_id_org unique (id, organization_id), -- clave alterna para CF compuesta + constraint fk_organization_policies_org foreign key (organization_id) references organizations (id) on delete restrict, + + constraint ck_organization_policies_version check (version > 0), + constraint ck_organization_policies_notice check (booking_notice_minutes_min >= 0 + and booking_notice_minutes_max >= 0 + and booking_notice_minutes_min <= booking_notice_minutes_max), + constraint ck_organization_policies_cancel check (free_cancellation_window_minutes >= 0), + constraint ck_organization_policies_vigencia check (replaced_at is null or replaced_at > effective_from), + -- Dos versiones no pueden regir a la vez, ni siquiera históricamente + constraint ex_organization_policies_solape exclude using gist ( + organization_id with =, + tstzrange(effective_from, replaced_at) with && + ) +); + +create table if not exists locations ( + id uuid primary key default gen_random_uuid(), + organization_id uuid not null, + name varchar(120) not null, + address varchar(200) not null, + city_id uuid not null, + -- Nulo = hereda la zona horaria de la organización. Al ser un + -- override explícito, NO existe la dependencia city_id -> timezone + -- que sacaría a esta tabla de 3FN. + timezone varchar(60), + status varchar(20) not null default 'ACTIVE', + created_at timestamptz not null default now(), + updated_at timestamptz not null default now(), + + constraint uk_locations_org_name unique (organization_id, name), + constraint uk_locations_id_org unique (id, organization_id), -- clave alterna para CF compuesta + constraint fk_locations_org foreign key (organization_id) references organizations (id) on delete restrict, + constraint fk_locations_city foreign key (city_id) references cities (id) on delete restrict, + constraint ck_locations_status check (status in ('ACTIVE', 'INACTIVE')), + constraint ck_locations_name check (length(btrim(name)) > 0) ); -create index if not exists ix_login_attempts_email_time - on login_attempts (email, attempted_at); --- ============================================================= --- Restricciones de integridad adicionales sobre lo generado --- por Hibernate (se aplican una vez creado el esquema): --- ============================================================= +-- ===================================================================== +-- Servicios (HU-004) +-- ===================================================================== + +create table if not exists services ( + id uuid primary key default gen_random_uuid(), + organization_id uuid not null, + name varchar(120) not null, + description varchar(500), + duration_minutes integer not null, + preparation_minutes integer not null default 0, + cleanup_minutes integer not null default 0, + price numeric(12,2) not null, + currency_id uuid not null, + customer_capacity integer not null default 1, + status varchar(20) not null default 'ACTIVE', + created_at timestamptz not null default now(), + updated_at timestamptz not null default now(), + + constraint uk_services_org_name unique (organization_id, name), -- HU-004: nombre único por proveedor + constraint uk_services_id_org unique (id, organization_id), -- clave alterna para CF compuesta + constraint fk_services_org foreign key (organization_id) references organizations (id) on delete restrict, + constraint fk_services_currency foreign key (currency_id) references currencies (id) on delete restrict, + + constraint ck_services_duration check (duration_minutes > 0), + constraint ck_services_prep check (preparation_minutes >= 0 and cleanup_minutes >= 0), + constraint ck_services_price check (price >= 0), + constraint ck_services_capacity check (customer_capacity >= 1), -- 1 = individual, >1 = grupal + constraint ck_services_status check (status in ('ACTIVE', 'INACTIVE')), + constraint ck_services_name check (length(btrim(name)) > 0) +); + +-- Sedes donde se presta cada servicio (HU-004). organization_id se +-- arrastra para que las CF compuestas impidan publicar un servicio de +-- una organización en la sede de otra. +create table if not exists service_locations ( + service_id uuid not null, + location_id uuid not null, + organization_id uuid not null, + constraint pk_service_locations primary key (service_id, location_id), + constraint fk_service_locations_svc foreign key (service_id, organization_id) references services (id, organization_id) on delete cascade, + constraint fk_service_locations_loc foreign key (location_id, organization_id) references locations (id, organization_id) on delete cascade +); + +create table if not exists resource_types ( + id uuid primary key default gen_random_uuid(), + organization_id uuid not null, + name varchar(80) not null, + description varchar(300), + created_at timestamptz not null default now(), + constraint uk_resource_types_org_name unique (organization_id, name), + constraint uk_resource_types_id_org unique (id, organization_id), + constraint fk_resource_types_org foreign key (organization_id) references organizations (id) on delete restrict +); + +create table if not exists service_resource_requirements ( + id uuid primary key default gen_random_uuid(), + service_id uuid not null, + resource_type_id uuid not null, + organization_id uuid not null, + quantity_required integer not null default 1, + constraint uk_service_resource_req unique (service_id, resource_type_id), + constraint fk_service_resource_req_svc foreign key (service_id, organization_id) references services (id, organization_id) on delete cascade, + constraint fk_service_resource_req_type foreign key (resource_type_id, organization_id) references resource_types (id, organization_id) on delete restrict, + constraint ck_service_resource_req_qty check (quantity_required > 0) +); + + +-- ===================================================================== +-- Recursos y agenda +-- El diagrama del equipo llegaba hasta el tipo de recurso. Sin la +-- instancia concreta no hay control de disponibilidad. +-- ===================================================================== + +create table if not exists resources ( + id uuid primary key default gen_random_uuid(), + resource_type_id uuid not null, + location_id uuid not null, + name varchar(120) not null, + status varchar(20) not null default 'ACTIVE', + created_at timestamptz not null default now(), + updated_at timestamptz not null default now(), + constraint uk_resources_location_name unique (location_id, name), + constraint uk_resources_id_location unique (id, location_id), -- clave alterna para CF compuesta + constraint fk_resources_type foreign key (resource_type_id) references resource_types (id) on delete restrict, + constraint fk_resources_location foreign key (location_id) references locations (id) on delete restrict, + constraint ck_resources_status check (status in ('ACTIVE', 'INACTIVE')) +); + +-- Franja semanal recurrente. resource_id nulo = toda la sede. +create table if not exists schedules ( + id uuid primary key default gen_random_uuid(), + location_id uuid not null, + resource_id uuid, + day_of_week smallint not null, + start_time time not null, + end_time time not null, + active boolean not null default true, + created_at timestamptz not null default now(), + + -- Sin esta clave la misma franja entra N veces e infla el + -- denominador de los reportes de ocupación. El nulls not distinct + -- hace falta para las franjas de sede completa. + constraint uk_schedules_franja unique nulls not distinct + (location_id, resource_id, day_of_week, start_time, end_time), + + constraint fk_schedules_location foreign key (location_id) references locations (id) on delete cascade, + -- El recurso tiene que estar en esa sede. Con match simple, si + -- resource_id es nulo la CF no se verifica. + constraint fk_schedules_resource foreign key (resource_id, location_id) references resources (id, location_id) on delete cascade, + + constraint ck_schedules_dow check (day_of_week between 1 and 7), -- ISO: 1 = lunes + constraint ck_schedules_rango check (end_time > start_time), + + -- Dos franjas activas del mismo recurso no se pueden solapar + constraint ex_schedules_solape exclude using gist ( + location_id with =, + coalesce(resource_id, '00000000-0000-0000-0000-000000000000'::uuid) with =, + day_of_week with =, + timerange(start_time, end_time) with && + ) where (active) +); + + +-- ===================================================================== +-- Reservas +-- ===================================================================== + +create table if not exists bookings ( + id uuid primary key default gen_random_uuid(), + client_id uuid not null, + organization_id uuid not null, + service_id uuid not null, + location_id uuid not null, + policy_id uuid not null, + -- Sesión a la que pertenece la reserva. En un servicio individual + -- cada reserva es su propia sesión; en uno grupal, varias reservas + -- comparten sesión y por tanto comparten recurso (ver booking_resources). + session_id uuid not null, + starts_at timestamptz not null, + ends_at timestamptz not null, + attendees integer not null default 1, + total_price numeric(12,2) not null, + status varchar(20) not null default 'RESERVED', + cancelled_at timestamptz, + created_at timestamptz not null default now(), + updated_at timestamptz not null default now(), + + -- Destino de la CF compuesta de booking_resources: es lo que hace + -- que el motor mantenga sincronizada la copia del rango. + constraint uk_bookings_snapshot unique (id, starts_at, ends_at, status), + + constraint fk_bookings_client foreign key (client_id) references clients (id) on delete restrict, + + -- El servicio tiene que prestarse en esa sede (HU-004) + constraint fk_bookings_service_location + foreign key (service_id, location_id) references service_locations (service_id, location_id) on delete restrict, + -- y servicio, sede y política tienen que ser de la misma organización + constraint fk_bookings_service_org foreign key (service_id, organization_id) references services (id, organization_id) on delete restrict, + constraint fk_bookings_location_org foreign key (location_id, organization_id) references locations (id, organization_id) on delete restrict, + constraint fk_bookings_policy_org foreign key (policy_id, organization_id) references organization_policies (id, organization_id) on delete restrict, + + constraint ck_bookings_rango check (ends_at > starts_at), + constraint ck_bookings_attendees check (attendees > 0), + constraint ck_bookings_price check (total_price >= 0), + constraint ck_bookings_status check (status in ('RESERVED', 'CONFIRMED', 'CANCELLED', 'COMPLETED', 'NO_SHOW')), + constraint ck_bookings_cancel check (status <> 'CANCELLED' or cancelled_at is not null) +); + +-- Recursos ocupados por una reserva. +-- +-- starts_at, ends_at y status se repiten desde bookings a propósito. +-- PostgreSQL no evalúa un EXCLUDE a través de un join, así que para +-- impedir el doble uso de un recurso el rango tiene que estar en la +-- misma tabla que resource_id. Es una violación de 2FN asumida. +-- +-- La copia no puede desviarse: la CF compuesta contra la clave alterna +-- de bookings la mantiene el motor, con on update cascade. +create table if not exists booking_resources ( + booking_id uuid not null, + resource_id uuid not null, + location_id uuid not null, + session_id uuid not null, + starts_at timestamptz not null, + ends_at timestamptz not null, + status varchar(20) not null, + + constraint pk_booking_resources primary key (booking_id, resource_id), + + -- La copia la garantiza el motor, no la aplicación. + constraint fk_booking_resources_bkg + foreign key (booking_id, starts_at, ends_at, status) + references bookings (id, starts_at, ends_at, status) + on update cascade on delete cascade, + + -- El recurso tiene que estar en la sede de la reserva + constraint fk_booking_resources_res + foreign key (resource_id, location_id) references resources (id, location_id) on delete restrict, + + constraint ck_booking_resources_rango check (ends_at > starts_at), + constraint ck_booking_resources_status check (status in ('RESERVED', 'CONFIRMED', 'CANCELLED', 'COMPLETED', 'NO_SHOW')), + + -- Un recurso no puede estar en dos sesiones distintas que se + -- solapen. El session_id with <> es lo que permite los servicios + -- grupales: varias reservas de la misma sesión comparten el recurso + -- sin chocar. Las canceladas no bloquean. + constraint ex_booking_resources_solape exclude using gist ( + resource_id with =, + session_id with <>, + tstzrange(starts_at, ends_at) with && + ) where (status in ('RESERVED', 'CONFIRMED')) +); + +-- Traza de cambios de estado de una reserva. Con on delete restrict, +-- porque un historial que desaparece con lo que traza no sirve. +create table if not exists booking_status_changes ( + id uuid primary key default gen_random_uuid(), + booking_id uuid not null, + from_status varchar(20), + to_status varchar(20) not null, + reason varchar(300), + changed_by uuid, + changed_at timestamptz not null default now(), + constraint fk_booking_status_changes foreign key (booking_id) references bookings (id) on delete restrict, + constraint ck_bsc_from check (from_status is null or from_status in ('RESERVED','CONFIRMED','CANCELLED','COMPLETED','NO_SHOW')), + constraint ck_bsc_to check (to_status in ('RESERVED','CONFIRMED','CANCELLED','COMPLETED','NO_SHOW')), + -- Cancelar exige motivo, y un motivo en blanco no es un motivo + constraint ck_bsc_reason check (to_status <> 'CANCELLED' or length(btrim(coalesce(reason,''))) > 0) +); + +-- HU-003 exige motivo al aprobar, suspender o reactivar, e informe de +-- reservas afectadas al suspender. Eso es sobre cuentas, no sobre +-- reservas, así que necesita su propia tabla. +create table if not exists account_status_changes ( + id uuid primary key default gen_random_uuid(), + subject_type varchar(20) not null, + client_id uuid, + organization_id uuid, + from_status varchar(30), + to_status varchar(30) not null, + reason varchar(500) not null, -- SIEMPRE obligatorio + affected_bookings integer not null default 0, + changed_by uuid, + changed_at timestamptz not null default now(), + constraint fk_account_status_changes_cli foreign key (client_id) references clients (id) on delete cascade, + constraint fk_account_status_changes_org foreign key (organization_id) references organizations (id) on delete cascade, + constraint ck_account_status_changes_subject check ( + (subject_type = 'CLIENT' and client_id is not null and organization_id is null) or + (subject_type = 'ORGANIZATION' and organization_id is not null and client_id is null)), + constraint ck_account_status_changes_reason check (length(btrim(reason)) > 0), + constraint ck_account_status_changes_count check (affected_bookings >= 0) +); + + +-- ===================================================================== +-- Reglas que no se pueden expresar con una restricción declarativa +-- Comparan entre tablas, y PostgreSQL no admite subconsultas en un +-- check. Van en triggers para que la garantía siga viviendo en la base. +-- ===================================================================== + +create or replace function fn_set_updated_at() returns trigger +language plpgsql as $$ +begin + new.updated_at := now(); + return new; +end $$; + +-- Tres reglas: un proveedor pendiente no es reservable (HU-002), un +-- cliente sin verificar no confirma (HU-001) y no se supera el aforo. +create or replace function fn_bookings_reglas() returns trigger +language plpgsql as $$ +declare + v_cliente varchar(30); + v_org varchar(30); + v_servicio varchar(20); + v_cupo integer; + v_ocupado integer; +begin + select status into v_cliente from clients where id = new.client_id; + select status into v_org from organizations where id = new.organization_id; + select status, customer_capacity into v_servicio, v_cupo + from services where id = new.service_id; + + if v_org <> 'ACTIVE' then + raise exception 'HU-002: el proveedor está en estado %, no es reservable', v_org; + end if; + + if v_servicio <> 'ACTIVE' and new.status in ('RESERVED','CONFIRMED') then + raise exception 'HU-004: el servicio está inactivo, no admite reservas nuevas'; + end if; + + if new.status = 'CONFIRMED' and v_cliente <> 'ACTIVE' then + raise exception 'HU-001: sólo un cliente verificado puede confirmar una reserva (estado %)', v_cliente; + end if; + + -- Aforo de la sesión + select coalesce(sum(attendees), 0) into v_ocupado + from bookings + where session_id = new.session_id + and status in ('RESERVED','CONFIRMED') + and id <> new.id; + + if v_ocupado + new.attendees > v_cupo and new.status in ('RESERVED','CONFIRMED') then + raise exception 'HU-004: aforo superado: % ocupados + % solicitados > cupo %', + v_ocupado, new.attendees, v_cupo; + end if; + + return new; +end $$; + +-- HU-003: cambiar el estado de una cuenta exige dejar el motivo. +create or replace function fn_exige_motivo_cuenta() returns trigger +language plpgsql as $$ +begin + if new.status is distinct from old.status + and not exists ( + select 1 from account_status_changes a + where a.to_status = new.status + and (a.organization_id = new.id or a.client_id = new.id) + and a.changed_at >= now() - interval '1 second') then + raise exception + 'HU-003: cambiar el estado a % exige registrar el motivo en account_status_changes', new.status; + end if; + return new; +end $$; + +drop trigger if exists tg_organizations_motivo on organizations; +drop trigger if exists tg_clients_motivo on clients; +drop trigger if exists tg_organizations_updated_at on organizations; +drop trigger if exists tg_locations_updated_at on locations; +drop trigger if exists tg_services_updated_at on services; +drop trigger if exists tg_resources_updated_at on resources; +drop trigger if exists tg_bookings_updated_at on bookings; +drop trigger if exists tg_bookings_reglas on bookings; + +create trigger tg_organizations_updated_at before update on organizations for each row execute function fn_set_updated_at(); +create trigger tg_locations_updated_at before update on locations for each row execute function fn_set_updated_at(); +create trigger tg_services_updated_at before update on services for each row execute function fn_set_updated_at(); +create trigger tg_resources_updated_at before update on resources for each row execute function fn_set_updated_at(); +create trigger tg_bookings_updated_at before update on bookings for each row execute function fn_set_updated_at(); +create trigger tg_bookings_reglas before insert or update on bookings for each row execute function fn_bookings_reglas(); + +-- HU-003: no se puede cambiar el estado de una cuenta sin dejar el motivo +create trigger tg_organizations_motivo after update of status on organizations + for each row execute function fn_exige_motivo_cuenta(); +create trigger tg_clients_motivo after update of status on clients + for each row execute function fn_exige_motivo_cuenta(); + + +-- ===================================================================== +-- Índices +-- PostgreSQL indexa las PK y las unique, pero no las claves foráneas. +-- Aquí sólo van las FK cuya columna no es ya el prefijo de una unique: +-- un índice sobre organization_id sobra si existe +-- unique (organization_id, name). +-- ===================================================================== + +-- Una sola política vigente por organización +create unique index if not exists ux_organization_policies_vigente + on organization_policies (organization_id) where replaced_at is null; + +-- FK no cubiertas por el prefijo de una UNIQUE +create index if not exists ix_organization_members_user on organization_members (user_id); +create index if not exists ix_locations_city on locations (city_id); +create index if not exists ix_services_currency on services (currency_id); +create index if not exists ix_service_locations_location on service_locations (location_id); +create index if not exists ix_service_resource_req_type on service_resource_requirements (resource_type_id); +create index if not exists ix_resources_type on resources (resource_type_id); +create index if not exists ix_schedules_resource on schedules (resource_id); +create index if not exists ix_bookings_service on bookings (service_id); +create index if not exists ix_bookings_policy on bookings (policy_id); +create index if not exists ix_bookings_session on bookings (session_id); +-- El GiST parcial no ve las canceladas; este sí +create index if not exists ix_booking_resources_resource on booking_resources (resource_id); +create index if not exists ix_bsc_booking on booking_status_changes (booking_id); +create index if not exists ix_asc_org on account_status_changes (organization_id, changed_at desc); +create index if not exists ix_asc_client on account_status_changes (client_id, changed_at desc); + +-- Consultas frecuentes +create index if not exists ix_login_attempts_email_time on login_attempts (email, attempted_at); +create index if not exists ix_login_attempts_email_lower on login_attempts (lower(email), attempted_at); +create index if not exists ix_bookings_client_starts on bookings (client_id, starts_at desc); +create index if not exists ix_bookings_location_starts on bookings (location_id, starts_at); +create index if not exists ix_schedules_location_dow on schedules (location_id, day_of_week) where active; +create index if not exists ix_organizations_status on organizations (status); + + +-- ===================================================================== +-- Comentarios de catálogo +-- ===================================================================== -alter table clients drop constraint if exists ck_clients_status; -alter table clients add constraint ck_clients_status - check (status in ('PENDING_VERIFICATION', 'ACTIVE', 'SUSPENDED')); +comment on table cities is 'Catálogo de ciudades. Evita repetir la ciudad como texto en perfiles y sedes'; +comment on table organization_categories is 'Catálogo de categorías de negocio (HU-003 filtra por categoría)'; +comment on table currencies is 'Monedas en código ISO 4217. La baja es lógica (active), nunca física'; +comment on table clients is 'Sprint 1 · IMPLEMENTADO. Perfil de cliente (HU-001); id = auth.users.id de Supabase'; +comment on table login_attempts is 'Sprint 1 · IMPLEMENTADO. Intentos de login para el bloqueo por cuenta (HU-021)'; +comment on table organizations is 'Negocio proveedor (HU-002). Queda PENDING_APPROVAL hasta que un administrador lo valide'; +comment on table organization_members is 'Relación N:M entre personas y organizaciones, con el rol de cada quien'; +comment on table organization_policies is 'Reglas de operación VERSIONADAS (HU-002). Cada cambio crea una versión; las reservas conservan la suya'; +comment on table locations is 'Sedes de una organización. HU-002 exige al menos una para publicar servicios'; +comment on table services is 'Servicios ofertados (HU-004). customer_capacity = 1 individual, > 1 grupal'; +comment on table service_locations is 'En qué sedes se presta cada servicio (HU-004)'; +comment on table resource_types is 'Tipos de recurso NO consumibles: sala, silla de barbero, hidrolavadora, especialista'; +comment on table service_resource_requirements is 'Cuántos recursos de cada tipo exige un servicio para poder ejecutarse'; +comment on table resources is 'Instancia concreta de un tipo de recurso, en una sede. Es lo que realmente se ocupa'; +comment on table schedules is 'Franjas semanales de disponibilidad. resource_id nulo = aplica a toda la sede'; +comment on table bookings is 'Reserva. policy_id congela las condiciones vigentes al crearla (HU-002)'; +comment on table booking_resources is 'Recursos ocupados. El EXCLUDE impide que un recurso sirva a dos sesiones solapadas'; +comment on table booking_status_changes is 'Historia de estados de una RESERVA, con motivo obligatorio al cancelar'; +comment on table account_status_changes is 'Historia de estados de CUENTAS: aprobar, suspender y reactivar exigen motivo (HU-003)'; -alter table clients drop constraint if exists ck_clients_notification_channel; -alter table clients add constraint ck_clients_notification_channel - check (notification_channel in ('EMAIL', 'SMS', 'WHATSAPP')); +comment on column clients.city is 'Texto libre, heredado del mapeo JPA. El catálogo cities sí se usa en locations'; +comment on column locations.timezone is 'Nulo = hereda la de la organización. Es un override explícito, no una copia de la ciudad'; +comment on column services.customer_capacity is 'Cupo por sesión. 1 = individual; mayor que 1 = grupal (HU-004)'; +comment on column services.preparation_minutes is 'Minutos de alistamiento antes de prestar el servicio'; +comment on column services.cleanup_minutes is 'Minutos de limpieza después de prestar el servicio'; +comment on column organization_policies.version is 'Se incrementa en 1 cada vez que la organización cambia sus parámetros'; +comment on column organization_policies.replaced_at is 'Nulo mientras la política esté vigente. Sólo puede haber una vigente por organización'; +comment on column bookings.session_id is 'Sesión del servicio. Individual: una por reserva. Grupal: compartida, y por eso comparten recurso'; +comment on column bookings.total_price is 'Precio pactado al reservar. NO es copia de services.price: ese puede cambiar después, así que no hay dependencia funcional'; +comment on column booking_resources.starts_at is 'Copia del rango de la reserva, mantenida por el motor vía CF compuesta con on update cascade'; +comment on column schedules.day_of_week is 'Día ISO: 1 = lunes … 7 = domingo'; -alter table clients drop constraint if exists ck_clients_adult; -alter table clients add constraint ck_clients_adult - check (birth_date <= current_date - interval '18 years'); -comment on table clients is 'Perfil de cliente (HU-001); id = auth.users.id de Supabase'; -comment on table login_attempts is 'Auditoría de intentos de login para bloqueo temporal (HU-021)'; +-- ===================================================================== +-- Lo que este esquema NO garantiza +-- +-- · Que una reserva ocupe los recursos que su servicio exige. +-- service_resource_requirements dice cuántos hacen falta, pero nada +-- obliga a insertar las filas en booking_resources. +-- · Que una organización activa tenga al menos una sede, ni que un +-- servicio activo declare sedes y tipos de recurso. Son +-- cardinalidades mínimas entre tablas. +-- · Contraseñas, MFA, sesiones y enlaces de un solo uso de HU-021: +-- viven en Supabase Auth, fuera de este esquema. +-- · El rol de administrador de plataforma. organization_members.role +-- modela roles dentro de una organización, no el rol global. +-- · Excepciones de agenda como festivos o mantenimientos. +-- · Que timezone sea una zona real de la IANA. +-- ===================================================================== From 5ed85ce468ce3496724bf7d62f6495767ba1dbd2 Mon Sep 17 00:00:00 2001 From: Anderson Herrera <43342146+andersonhg19@users.noreply.github.com> Date: Mon, 21 Sep 2026 22:53:45 -0500 Subject: [PATCH 02/14] feat: seed data, executable key queries and integrity checks --- docs/database/consultas-clave.sql | 251 +++++++++++++++++++++++++++ docs/database/pruebas-integridad.sql | 154 ++++++++++++++++ docs/database/seed.sql | 175 +++++++++++++++++++ 3 files changed, 580 insertions(+) create mode 100644 docs/database/consultas-clave.sql create mode 100644 docs/database/pruebas-integridad.sql create mode 100644 docs/database/seed.sql diff --git a/docs/database/consultas-clave.sql b/docs/database/consultas-clave.sql new file mode 100644 index 0000000..c27c932 --- /dev/null +++ b/docs/database/consultas-clave.sql @@ -0,0 +1,251 @@ +-- ===================================================================== +-- Consultas clave del negocio +-- Sprint 1 · Bases de Datos · CodeF@ctory 2026-II +-- +-- Once preguntas. Todas corren sobre las tablas de schema.sql y todas +-- devuelven filas con los datos de seed.sql. +-- +-- Uso: psql -f schema.sql -f seed.sql -f consultas-clave.sql +-- ===================================================================== + + +-- 1. ¿Qué servicios puede reservar un cliente en Medellín, en qué sede +-- y a qué precio? Es la consulta del catálogo público, y aplica la +-- regla de HU-002: un proveedor pendiente no es visible. +\echo '=== 1. Catálogo de servicios reservables en Medellín ===' +select o.name as organizacion, + s.name as servicio, + l.name as sede, + s.duration_minutes as minutos, + s.price, + cur.code as moneda, + s.customer_capacity as cupo +from services s + inner join organizations o on o.id = s.organization_id + inner join service_locations sl on sl.service_id = s.id + inner join locations l on l.id = sl.location_id + inner join cities c on c.id = l.city_id + inner join currencies cur on cur.id = s.currency_id +where c.name = 'Medellín' + and s.status = 'ACTIVE' + and l.status = 'ACTIVE' + and o.status = 'ACTIVE' +order by o.name, s.name; + + +-- 2. ¿Cuál es la ocupación por sede y semana? Es el reporte de uso que +-- pide el enunciado del caso. +\echo '=== 2. Ocupación e ingresos por sede y semana ===' +select l.name as sede, + date_trunc('week', b.starts_at)::date as semana, + count(*) as reservas, + sum(b.attendees) as asistentes, + sum(b.total_price) as ingresos +from bookings b + inner join locations l on l.id = b.location_id +where b.status in ('CONFIRMED', 'COMPLETED') +group by l.name, date_trunc('week', b.starts_at) +order by semana, sede; + + +-- 3. ¿Qué servicios no puede prestar una sede porque no tiene recursos +-- suficientes? Detecta servicios publicados que en la práctica no se +-- pueden ejecutar ahí. +\echo '=== 3. Servicios publicados en una sede sin recursos suficientes ===' +select o.name as organizacion, + s.name as servicio, + l.name as sede, + rt.name as tipo_de_recurso, + srr.quantity_required as requiere, + count(r.id) as disponibles +from services s + inner join organizations o on o.id = s.organization_id + inner join service_locations sl on sl.service_id = s.id + inner join locations l on l.id = sl.location_id + inner join service_resource_requirements srr on srr.service_id = s.id + inner join resource_types rt on rt.id = srr.resource_type_id + left join resources r on r.resource_type_id = rt.id + and r.location_id = l.id + and r.status = 'ACTIVE' +group by o.name, s.name, l.name, rt.name, srr.quantity_required +having count(r.id) < srr.quantity_required +order by o.name, s.name, l.name; + + +-- 4. ¿Cuáles son los servicios más reservados de cada organización? +-- Con rank() y no row_number() para que los empates compartan puesto. +\echo '=== 4. Servicios más reservados por organización (con empates) ===' +select organizacion, servicio, reservas, posicion +from ( + select o.name as organizacion, + s.name as servicio, + count(b.id) as reservas, + rank() over (partition by o.id order by count(b.id) desc) as posicion + from services s + inner join organizations o on o.id = s.organization_id + left join bookings b on b.service_id = s.id + and b.status in ('CONFIRMED', 'COMPLETED') + group by o.id, o.name, s.name +) ranking +where posicion <= 3 +order by organizacion, posicion, servicio; + + +-- 5. Si se suspende un proveedor, ¿qué reservas futuras quedan +-- afectadas? HU-003 pide ese informe antes de confirmar la suspensión. +\echo '=== 5. Informe de reservas afectadas por suspender un proveedor ===' +select b.id as reserva, + c.full_name as cliente, + c.email, + c.phone, + s.name as servicio, + l.name as sede, + b.starts_at, + b.status +from bookings b + inner join services s on s.id = b.service_id + inner join clients c on c.id = b.client_id + inner join locations l on l.id = b.location_id +where s.organization_id = (select id from organizations where nit = '900123456-1') + and b.starts_at >= now() + and b.status in ('RESERVED', 'CONFIRMED') +order by b.starts_at; + + +-- 6. ¿Qué agenda tiene cada recurso pasado mañana y cuánta carga lleva? +-- El left join es lo que deja ver también los recursos libres. +\echo '=== 6. Agenda y carga de cada recurso para pasado mañana ===' +select l.name as sede, + r.name as recurso, + sch.start_time as abre, + sch.end_time as cierra, + count(br.booking_id) as reservas_vivas +from schedules sch + inner join resources r on r.id = sch.resource_id + inner join locations l on l.id = r.location_id + left join booking_resources br on br.resource_id = r.id + and br.status in ('RESERVED', 'CONFIRMED') + and br.starts_at::date = (now() + interval '2 days')::date +where sch.day_of_week = extract(isodow from now() + interval '2 days') + and sch.active +group by l.name, r.name, sch.start_time, sch.end_time +order by l.name, r.name; + + +-- 7. ¿Qué proveedores llevan más tiempo esperando aprobación? Es la cola +-- de trabajo del administrador (HU-003). +\echo '=== 7. Cola de proveedores pendientes de aprobación ===' +select o.name as organizacion, + o.nit, + oc.name as categoria, + o.contact_email, + o.created_at::date as solicitado_el, + current_date - o.created_at::date as dias_esperando +from organizations o + inner join organization_categories oc on oc.id = o.category_id +where o.status = 'PENDING_APPROVAL' +order by dias_esperando desc, o.name; + + +-- 8. ¿Está bloqueada una cuenta por intentos fallidos? La política es +-- cinco fallos en quince minutos (HU-021). +\echo '=== 8. Cuentas bloqueadas por intentos fallidos ===' +select email, + count(*) as fallos_recientes, + max(attempted_at) as ultimo_intento, + count(*) >= 5 as bloqueada +from login_attempts +where success = false + and attempted_at > localtimestamp - interval '15 minutes' +group by email +order by fallos_recientes desc; + + +-- 9. ¿Qué clientes llevan más de 24 horas sin verificar el correo? Es la +-- lista a la que hay que reenviarles el enlace (HU-001). +\echo '=== 9. Clientes sin verificar hace más de 24 h ===' +select id, + full_name, + email, + city, + created_at, + localtimestamp - created_at as lleva_esperando +from clients +where status = 'PENDING_VERIFICATION' + and created_at < localtimestamp - interval '24 hours' +order by created_at; + + +-- 10. ¿Qué condiciones de cancelación rigen para cada reserva? Como cada +-- reserva apunta a la versión de política que regía al crearse, dos +-- reservas del mismo negocio salen con ventanas distintas. Es la +-- prueba de que la regla de HU-002 está resuelta en el modelo. +\echo '=== 10. Condiciones congeladas en cada reserva ===' +select o.name as organizacion, + b.starts_at, + b.status, + op.version as version_politica, + op.free_cancellation_window_minutes as minutos_cancelacion_gratis, + case when op.replaced_at is null + then 'vigente' + else 'histórica' end as estado_de_la_politica +from bookings b + inner join organization_policies op on op.id = b.policy_id + inner join organizations o on o.id = op.organization_id +order by o.name, b.starts_at; + + +-- 11. ¿El correo, el documento o el NIT ya están registrados? Es la +-- validación previa al registro, en una sola ida a la base. +\echo '=== 11. Validación de unicidad antes de registrar ===' +select exists (select 1 from clients where lower(email) = lower('laura@example.com')) as correo_ya_registrado, + exists (select 1 from clients where document = '1020334455') as documento_ya_registrado, + exists (select 1 from organizations where nit = '900123456-1') as nit_ya_registrado; + + +-- 12. ¿Qué clientes se registraron y nunca han reservado? Subconsulta +-- correlacionada con el operador de existencia. +\echo '=== 12. Clientes que nunca han reservado ===' +select c.id, c.full_name, c.email, c.city, c.status +from clients c +where not exists (select 1 + from bookings b + where b.client_id = c.id) +order by c.full_name; + + +-- 13. ¿Qué servicios se prestan en la Sede Poblado pero no en Envigado? +-- Operador de diferencia del álgebra relacional. +\echo '=== 13. Servicios de una sede que la otra no ofrece (diferencia) ===' +select s.name as servicio +from service_locations sl + inner join services s on s.id = sl.service_id + inner join locations l on l.id = sl.location_id +where l.name = 'Sede Poblado' +except +select s.name +from service_locations sl + inner join services s on s.id = sl.service_id + inner join locations l on l.id = sl.location_id +where l.name = 'Sede Envigado' +order by servicio; + + +-- 14. ¿Qué sedes ofrecen TODOS los servicios activos de su organización? +-- Es el operador de división del álgebra relacional, expresado con +-- la doble negación: no existe un servicio activo de la organización +-- que no se preste en esa sede. +\echo '=== 14. Sedes que ofrecen todos los servicios activos de su organización (división) ===' +select o.name as organizacion, l.name as sede +from locations l + inner join organizations o on o.id = l.organization_id +where l.status = 'ACTIVE' + and not exists (select 1 + from services s + where s.organization_id = l.organization_id + and s.status = 'ACTIVE' + and not exists (select 1 + from service_locations sl + where sl.service_id = s.id + and sl.location_id = l.id)) +order by o.name, l.name; diff --git a/docs/database/pruebas-integridad.sql b/docs/database/pruebas-integridad.sql new file mode 100644 index 0000000..6d79d40 --- /dev/null +++ b/docs/database/pruebas-integridad.sql @@ -0,0 +1,154 @@ +-- ===================================================================== +-- Las reglas de integridad en acción +-- Sprint 1 · Bases de Datos · CodeF@ctory 2026-II +-- +-- Las restricciones declaradas en el CREATE TABLE las hace cumplir el +-- motor, no la aplicación. Cada instrucción de este archivo viola una +-- regla de negocio a propósito, y todas deben ser rechazadas. +-- +-- Uso: psql -f schema.sql -f seed.sql -f pruebas-integridad.sql +-- Se ejecuta SIN ON_ERROR_STOP para que se vean los dieciocho rechazos. +-- ===================================================================== + +\set ON_ERROR_STOP off + + +\echo '' +\echo '--- 1. Clave candidata: el NIT ya está registrado (HU-002) ---' +insert into organizations (category_id, name, nit, contact_email, contact_phone) +values ('22222222-0000-0000-0000-000000000001', 'Otra Clínica', '900123456-1', 'x@y.com', '6040000000'); + + +\echo '' +\echo '--- 2. Restricción de dominio: anticipación mínima mayor que la máxima (HU-002) ---' +insert into organization_policies (organization_id, version, booking_notice_minutes_min, + booking_notice_minutes_max, free_cancellation_window_minutes) +values ('66666666-0000-0000-0000-000000000002', 2, 5000, 100, 60); + + +\echo '' +\echo '--- 3. Dos políticas vigentes a la vez en la misma organización (HU-002) ---' +insert into organization_policies (organization_id, version, booking_notice_minutes_min, + booking_notice_minutes_max, free_cancellation_window_minutes) +values ('66666666-0000-0000-0000-000000000001', 3, 60, 1000, 60); + + +\echo '' +\echo '--- 4. Una organización activa sin fecha de aprobación (HU-002) ---' +insert into organizations (category_id, name, nit, contact_email, contact_phone, status) +values ('22222222-0000-0000-0000-000000000001', 'Sin Aprobar', '903000000-9', 'a@b.com', '6040000001', 'ACTIVE'); + + +\echo '' +\echo '--- 5. Clave candidata: nombre de servicio repetido en el mismo proveedor (HU-004) ---' +insert into services (organization_id, name, duration_minutes, price, currency_id) +values ('66666666-0000-0000-0000-000000000001', 'Corte clásico', 30, 35000, + '33333333-0000-0000-0000-000000000001'); + + +\echo '' +\echo '--- 6. Restricción de dominio: un servicio con cupo cero (HU-004) ---' +insert into services (organization_id, name, duration_minutes, price, currency_id, customer_capacity) +values ('66666666-0000-0000-0000-000000000001', 'Servicio sin cupo', 30, 1000, + '33333333-0000-0000-0000-000000000001', 0); + + +\echo '' +\echo '--- 7. Integridad referencial: reservar un servicio en una sede donde no se presta (HU-004) ---' +insert into bookings (client_id, organization_id, service_id, location_id, policy_id, session_id, + starts_at, ends_at, total_price) +values ('44444444-0000-0000-0000-000000000001', '66666666-0000-0000-0000-000000000001', + 'aaaa0000-0000-0000-0000-000000000002', '88888888-0000-0000-0000-000000000002', + '77777777-0000-0000-0000-000000000002', gen_random_uuid(), + now() + interval '9 days', now() + interval '9 days' + interval '45 minutes', 45000); + + +\echo '' +\echo '--- 8. Integridad referencial: mezclar organizaciones en una misma reserva ---' +insert into bookings (client_id, organization_id, service_id, location_id, policy_id, session_id, + starts_at, ends_at, total_price) +values ('44444444-0000-0000-0000-000000000001', '66666666-0000-0000-0000-000000000001', + 'aaaa0000-0000-0000-0000-000000000001', '88888888-0000-0000-0000-000000000001', + '77777777-0000-0000-0000-000000000003', gen_random_uuid(), + now() + interval '9 days', now() + interval '9 days' + interval '30 minutes', 35000); + + +\echo '' +\echo '--- 9. Un cliente sin verificar confirma una reserva (HU-001) ---' +insert into bookings (client_id, organization_id, service_id, location_id, policy_id, session_id, + starts_at, ends_at, total_price, status) +values ('44444444-0000-0000-0000-000000000005', '66666666-0000-0000-0000-000000000001', + 'aaaa0000-0000-0000-0000-000000000001', '88888888-0000-0000-0000-000000000001', + '77777777-0000-0000-0000-000000000002', gen_random_uuid(), + now() + interval '9 days', now() + interval '9 days' + interval '30 minutes', 35000, 'CONFIRMED'); + + +\echo '' +\echo '--- 10. Aforo: más asistentes que el cupo del servicio (HU-004) ---' +insert into bookings (client_id, organization_id, service_id, location_id, policy_id, session_id, + starts_at, ends_at, attendees, total_price) +values ('44444444-0000-0000-0000-000000000001', '66666666-0000-0000-0000-000000000001', + 'aaaa0000-0000-0000-0000-000000000001', '88888888-0000-0000-0000-000000000001', + '77777777-0000-0000-0000-000000000002', gen_random_uuid(), + now() + interval '9 days', now() + interval '9 days' + interval '30 minutes', 500, 35000); + + +\echo '' +\echo '--- 11. Sobreocupación: otra sesión usando el mismo recurso en franja solapada ---' +insert into booking_resources (booking_id, resource_id, location_id, session_id, starts_at, ends_at, status) +select 'dddd0000-0000-0000-0000-000000000002', 'cccc0000-0000-0000-0000-000000000005', + '88888888-0000-0000-0000-000000000001', gen_random_uuid(), starts_at, ends_at, status +from bookings +where id = 'dddd0000-0000-0000-0000-000000000003'; + + +\echo '' +\echo '--- 12. Desincronizar la ocupación del estado de su reserva ---' +update booking_resources +set status = 'CANCELLED' +where booking_id = 'dddd0000-0000-0000-0000-000000000001'; + + +\echo '' +\echo '--- 13. Franja de agenda solapada con otra del mismo recurso ---' +insert into schedules (location_id, resource_id, day_of_week, start_time, end_time) +values ('88888888-0000-0000-0000-000000000001', 'cccc0000-0000-0000-0000-000000000001', 1, '07:00', '23:00'); + + +\echo '' +\echo '--- 14. Borrar una reserva que tiene historial de auditoría (HU-003) ---' +delete from bookings where id = 'dddd0000-0000-0000-0000-000000000001'; + + +\echo '' +\echo '--- 15. Suspender una organización sin registrar el motivo (HU-003) ---' +update organizations set status = 'SUSPENDED' where id = '66666666-0000-0000-0000-000000000001'; + + +\echo '' +\echo '--- 16. Obligatoriedad y dominio: cliente con correo inválido (HU-001) ---' +insert into clients values (gen_random_uuid(), 'Correo Malo', '8888', '1990-01-01', + 'no-es-un-correo', '3009998877', 'Medellín', 'EMAIL', 'ACTIVE', + localtimestamp, localtimestamp); + + +\echo '' +\echo '--- 17. Clave candidata: el mismo correo con otra capitalización (HU-001) ---' +insert into clients values (gen_random_uuid(), 'Clon', '9999', '1990-01-01', + 'MARIANA@example.com', '3009998877', 'Medellín', 'EMAIL', 'ACTIVE', + localtimestamp, localtimestamp); + + +\echo '' +\echo '--- 18. Restricción de dominio: autorregistro de un menor de edad (HU-001) ---' +insert into clients values (gen_random_uuid(), 'Menor de Edad', '7777', current_date - interval '10 years', + 'menor@example.com', '3001112233', 'Medellín', 'EMAIL', 'ACTIVE', + localtimestamp, localtimestamp); + + +\echo '' +\echo '=====================================================================' +\echo ' Las dieciocho instrucciones anteriores debieron ser rechazadas.' +\echo ' Si alguna dice INSERT, UPDATE o DELETE en vez de ERROR, hay una' +\echo ' regla de negocio que la base no está garantizando.' +\echo '=====================================================================' diff --git a/docs/database/seed.sql b/docs/database/seed.sql new file mode 100644 index 0000000..542b683 --- /dev/null +++ b/docs/database/seed.sql @@ -0,0 +1,175 @@ +-- ===================================================================== +-- Datos de prueba — Plataforma de Reservas de Servicios +-- CodeF@ctory 2026-II · Sprint 1 · Bases de Datos +-- +-- Se ejecuta DESPUÉS de schema.sql. Carga un escenario pequeño pero +-- completo, pensado para que TODAS las consultas clave devuelvan +-- filas: una consulta que devuelve vacío no demuestra nada. +-- +-- Es re-ejecutable: empieza vaciando las tablas. +-- ===================================================================== + +truncate table account_status_changes, booking_status_changes, booking_resources, + bookings, schedules, resources, service_resource_requirements, + service_locations, services, resource_types, locations, + organization_policies, organization_members, organizations, + login_attempts, clients, + currencies, organization_categories, cities + restart identity cascade; + +-- ---------- catálogos ---------- +insert into cities (id, name, region) values + ('11111111-0000-0000-0000-000000000001', 'Medellín', 'Antioquia'), + ('11111111-0000-0000-0000-000000000002', 'Envigado', 'Antioquia'), + ('11111111-0000-0000-0000-000000000003', 'Bogotá', 'Cundinamarca'); + +insert into organization_categories (id, name) values + ('22222222-0000-0000-0000-000000000001', 'Salud'), + ('22222222-0000-0000-0000-000000000002', 'Belleza'), + ('22222222-0000-0000-0000-000000000003', 'Deporte'); + +insert into currencies (id, code, name) values + ('33333333-0000-0000-0000-000000000001', 'COP', 'Peso colombiano'), + ('33333333-0000-0000-0000-000000000002', 'USD', 'Dólar estadounidense'); + +-- ---------- clientes (Sprint 1, tabla ya implementada) ---------- +-- created_at / updated_at son timestamp(6) sin default: los pone el +-- auditor de Spring Data. Aquí se cargan explícitamente. +insert into clients (id, full_name, document, birth_date, email, phone, city, notification_channel, status, created_at, updated_at) values + ('44444444-0000-0000-0000-000000000001', 'Mariana Ospina', '1017245801', '1999-04-12', 'mariana@example.com', '3001112233', 'Medellín', 'EMAIL', 'ACTIVE', now() - interval '90 days', now() - interval '90 days'), + ('44444444-0000-0000-0000-000000000002', 'Laura Restrepo', '1020334455', '2001-09-30', 'laura@example.com', '3002223344', 'Envigado', 'WHATSAPP', 'ACTIVE', now() - interval '45 days', now() - interval '45 days'), + ('44444444-0000-0000-0000-000000000003', 'Camilo Zapata', '1015667788', '1995-01-20', 'camilo@example.com', '3003334455', 'Medellín', 'SMS', 'ACTIVE', now() - interval '20 days', now() - interval '20 days'), + ('44444444-0000-0000-0000-000000000004', 'Sara Betancur', '1011223344', '1997-07-07', 'sara@example.com', '3005556677', 'Medellín', 'EMAIL', 'ACTIVE', now() - interval '15 days', now() - interval '15 days'), + -- Lleva más de 24 h sin verificar: aparece en la consulta de re-engagement + ('44444444-0000-0000-0000-000000000005', 'Daniela Ochoa', '1019887766', '2003-06-05', 'daniela@example.com', '3004445566', 'Bogotá', 'EMAIL', 'PENDING_VERIFICATION', now() - interval '3 days', now() - interval '3 days'); + +-- ---------- intentos de login (HU-021): Laura está bloqueada ---------- +insert into login_attempts (email, success, attempted_at) values + ('laura@example.com', false, now() - interval '4 minutes'), + ('laura@example.com', false, now() - interval '3 minutes'), + ('laura@example.com', false, now() - interval '2 minutes'), + ('laura@example.com', false, now() - interval '1 minutes'), + ('laura@example.com', false, now() - interval '30 seconds'), + ('mariana@example.com', true, now() - interval '10 minutes'); + +-- ---------- organizaciones ---------- +insert into organizations (id, category_id, name, nit, contact_email, contact_phone, timezone, status, approved_at, created_at, updated_at) values + ('66666666-0000-0000-0000-000000000001', '22222222-0000-0000-0000-000000000002', 'Barbería El Poblado', '900123456-1', 'contacto@barberia.com', '6041112233', 'America/Bogota', 'ACTIVE', now() - interval '60 days', now() - interval '65 days', now() - interval '10 days'), + ('66666666-0000-0000-0000-000000000002', '22222222-0000-0000-0000-000000000001', 'Clínica Dental Sur', '901234567-2', 'citas@dentalsur.com', '6042223344', 'America/Bogota', 'ACTIVE', now() - interval '30 days', now() - interval '35 days', now() - interval '30 days'), + -- Pendiente hace 45 días: no es visible NI reservable (HU-002), + -- y encabeza la cola de pendientes del administrador (HU-003) + ('66666666-0000-0000-0000-000000000003', '22222222-0000-0000-0000-000000000003', 'Cancha Sintética 10', '902345678-3', 'reservas@cancha10.com', '6043334455', 'America/Bogota', 'PENDING_APPROVAL', null, now() - interval '45 days', now() - interval '45 days'); + +insert into organization_members (organization_id, user_id, role) values + ('66666666-0000-0000-0000-000000000001', '99999999-0000-0000-0000-000000000001', 'OWNER'), + ('66666666-0000-0000-0000-000000000002', '99999999-0000-0000-0000-000000000002', 'OWNER'), + ('66666666-0000-0000-0000-000000000001', '99999999-0000-0000-0000-000000000002', 'STAFF'); + +-- HU-003: la aprobación dejó su motivo registrado +insert into account_status_changes (subject_type, organization_id, from_status, to_status, reason, changed_by, changed_at) values + ('ORGANIZATION', '66666666-0000-0000-0000-000000000001', 'PENDING_APPROVAL', 'ACTIVE', 'Documentación y RUT verificados', '99999999-0000-0000-0000-000000000001', now() - interval '60 days'), + ('ORGANIZATION', '66666666-0000-0000-0000-000000000002', 'PENDING_APPROVAL', 'ACTIVE', 'Habilitación sanitaria vigente', '99999999-0000-0000-0000-000000000001', now() - interval '30 days'); + +-- Política versionada: la v1 fue reemplazada por la v2 (HU-002) +insert into organization_policies (id, organization_id, version, booking_notice_minutes_min, booking_notice_minutes_max, free_cancellation_window_minutes, effective_from, replaced_at) values + ('77777777-0000-0000-0000-000000000001', '66666666-0000-0000-0000-000000000001', 1, 60, 20160, 1440, now() - interval '60 days', now() - interval '10 days'), + ('77777777-0000-0000-0000-000000000002', '66666666-0000-0000-0000-000000000001', 2, 120, 43200, 720, now() - interval '10 days', null), + ('77777777-0000-0000-0000-000000000003', '66666666-0000-0000-0000-000000000002', 1, 30, 10080, 2880, now() - interval '30 days', null); + +insert into locations (id, organization_id, name, address, city_id, timezone, status) values + ('88888888-0000-0000-0000-000000000001', '66666666-0000-0000-0000-000000000001', 'Sede Poblado', 'Cra 43A # 5-15', '11111111-0000-0000-0000-000000000001', null, 'ACTIVE'), + ('88888888-0000-0000-0000-000000000002', '66666666-0000-0000-0000-000000000001', 'Sede Envigado', 'Cll 37 Sur # 41-20', '11111111-0000-0000-0000-000000000002', null, 'ACTIVE'), + ('88888888-0000-0000-0000-000000000003', '66666666-0000-0000-0000-000000000002', 'Sede Principal', 'Cra 48 # 20-10', '11111111-0000-0000-0000-000000000001', null, 'ACTIVE'); + +-- ---------- servicios ---------- +insert into services (id, organization_id, name, description, duration_minutes, preparation_minutes, cleanup_minutes, price, currency_id, customer_capacity, status) values + ('aaaa0000-0000-0000-0000-000000000001', '66666666-0000-0000-0000-000000000001', 'Corte clásico', 'Corte de cabello tradicional', 30, 5, 5, 35000.00, '33333333-0000-0000-0000-000000000001', 1, 'ACTIVE'), + ('aaaa0000-0000-0000-0000-000000000002', '66666666-0000-0000-0000-000000000001', 'Barba y afeitado', 'Perfilado y afeitado con navaja', 45, 5, 10, 45000.00, '33333333-0000-0000-0000-000000000001', 1, 'ACTIVE'), + -- GRUPAL: cupo 8. Varias reservas comparten sesión y comparten el salón. + ('aaaa0000-0000-0000-0000-000000000003', '66666666-0000-0000-0000-000000000001', 'Taller de barbería', 'Taller grupal para aprendices', 120, 15, 15, 180000.00, '33333333-0000-0000-0000-000000000001', 8, 'ACTIVE'), + ('aaaa0000-0000-0000-0000-000000000004', '66666666-0000-0000-0000-000000000002', 'Limpieza dental', 'Profilaxis y control', 40, 10, 10, 90000.00, '33333333-0000-0000-0000-000000000001', 1, 'ACTIVE'), + -- Desactivado, no borrado, porque tiene reservas históricas (HU-004) + ('aaaa0000-0000-0000-0000-000000000005', '66666666-0000-0000-0000-000000000002', 'Blanqueamiento', 'Blanqueamiento en consultorio', 60, 10, 10, 250000.00, '33333333-0000-0000-0000-000000000001', 1, 'INACTIVE'); + +insert into service_locations (service_id, location_id, organization_id) values + ('aaaa0000-0000-0000-0000-000000000001', '88888888-0000-0000-0000-000000000001', '66666666-0000-0000-0000-000000000001'), + ('aaaa0000-0000-0000-0000-000000000001', '88888888-0000-0000-0000-000000000002', '66666666-0000-0000-0000-000000000001'), + ('aaaa0000-0000-0000-0000-000000000002', '88888888-0000-0000-0000-000000000001', '66666666-0000-0000-0000-000000000001'), + ('aaaa0000-0000-0000-0000-000000000003', '88888888-0000-0000-0000-000000000001', '66666666-0000-0000-0000-000000000001'), + -- El taller también se publicó en Envigado, pero esa sede sólo tiene 1 silla + -- y el taller exige 4: la consulta 3 lo detecta como capacidad insuficiente + ('aaaa0000-0000-0000-0000-000000000003', '88888888-0000-0000-0000-000000000002', '66666666-0000-0000-0000-000000000001'), + ('aaaa0000-0000-0000-0000-000000000004', '88888888-0000-0000-0000-000000000003', '66666666-0000-0000-0000-000000000002'), + ('aaaa0000-0000-0000-0000-000000000005', '88888888-0000-0000-0000-000000000003', '66666666-0000-0000-0000-000000000002'); + +-- ---------- recursos ---------- +insert into resource_types (id, organization_id, name, description) values + ('bbbb0000-0000-0000-0000-000000000001', '66666666-0000-0000-0000-000000000001', 'Silla de barbero', 'Puesto de atención'), + ('bbbb0000-0000-0000-0000-000000000002', '66666666-0000-0000-0000-000000000001', 'Sala de taller', 'Espacio para grupos'), + ('bbbb0000-0000-0000-0000-000000000003', '66666666-0000-0000-0000-000000000002', 'Unidad dental', 'Sillón odontológico'); + +insert into service_resource_requirements (service_id, resource_type_id, organization_id, quantity_required) values + ('aaaa0000-0000-0000-0000-000000000001', 'bbbb0000-0000-0000-0000-000000000001', '66666666-0000-0000-0000-000000000001', 1), + ('aaaa0000-0000-0000-0000-000000000002', 'bbbb0000-0000-0000-0000-000000000001', '66666666-0000-0000-0000-000000000001', 1), + ('aaaa0000-0000-0000-0000-000000000003', 'bbbb0000-0000-0000-0000-000000000002', '66666666-0000-0000-0000-000000000001', 1), + ('aaaa0000-0000-0000-0000-000000000003', 'bbbb0000-0000-0000-0000-000000000001', '66666666-0000-0000-0000-000000000001', 4), + ('aaaa0000-0000-0000-0000-000000000004', 'bbbb0000-0000-0000-0000-000000000003', '66666666-0000-0000-0000-000000000002', 1), + ('aaaa0000-0000-0000-0000-000000000005', 'bbbb0000-0000-0000-0000-000000000003', '66666666-0000-0000-0000-000000000002', 1); + +insert into resources (id, resource_type_id, location_id, name, status) values + ('cccc0000-0000-0000-0000-000000000001', 'bbbb0000-0000-0000-0000-000000000001', '88888888-0000-0000-0000-000000000001', 'Silla 1', 'ACTIVE'), + ('cccc0000-0000-0000-0000-000000000002', 'bbbb0000-0000-0000-0000-000000000001', '88888888-0000-0000-0000-000000000001', 'Silla 2', 'ACTIVE'), + ('cccc0000-0000-0000-0000-000000000003', 'bbbb0000-0000-0000-0000-000000000001', '88888888-0000-0000-0000-000000000001', 'Silla 3', 'ACTIVE'), + ('cccc0000-0000-0000-0000-000000000004', 'bbbb0000-0000-0000-0000-000000000001', '88888888-0000-0000-0000-000000000001', 'Silla 4', 'ACTIVE'), + ('cccc0000-0000-0000-0000-000000000005', 'bbbb0000-0000-0000-0000-000000000002', '88888888-0000-0000-0000-000000000001', 'Salón principal', 'ACTIVE'), + ('cccc0000-0000-0000-0000-000000000006', 'bbbb0000-0000-0000-0000-000000000001', '88888888-0000-0000-0000-000000000002', 'Silla única', 'ACTIVE'), + ('cccc0000-0000-0000-0000-000000000007', 'bbbb0000-0000-0000-0000-000000000003', '88888888-0000-0000-0000-000000000003', 'Unidad A', 'ACTIVE'), + ('cccc0000-0000-0000-0000-000000000008', 'bbbb0000-0000-0000-0000-000000000003', '88888888-0000-0000-0000-000000000003', 'Unidad B', 'INACTIVE'); + +-- ---------- agenda: lunes a viernes 8:00-18:00, sábado 8:00-13:00 ---------- +insert into schedules (location_id, resource_id, day_of_week, start_time, end_time, active) +select r.location_id, r.id, d.dow, time '08:00', + case when d.dow = 6 then time '13:00' else time '18:00' end, true +from resources r +cross join (select generate_series(1, 6) as dow) d +where r.status = 'ACTIVE'; + +-- ---------- reservas ---------- +-- session_id: en servicios individuales coincide con el id de la reserva; +-- en el taller grupal DOS reservas comparten la misma sesión ffff...0001 +-- y por tanto comparten el salón sin chocar con el EXCLUDE. +insert into bookings (id, client_id, organization_id, service_id, location_id, policy_id, session_id, starts_at, ends_at, attendees, total_price, status, cancelled_at) values + ('dddd0000-0000-0000-0000-000000000001', '44444444-0000-0000-0000-000000000001', '66666666-0000-0000-0000-000000000001', 'aaaa0000-0000-0000-0000-000000000001', '88888888-0000-0000-0000-000000000001', '77777777-0000-0000-0000-000000000002', 'dddd0000-0000-0000-0000-000000000001', now() + interval '2 days', now() + interval '2 days' + interval '30 minutes', 1, 35000.00, 'CONFIRMED', null), + ('dddd0000-0000-0000-0000-000000000002', '44444444-0000-0000-0000-000000000002', '66666666-0000-0000-0000-000000000001', 'aaaa0000-0000-0000-0000-000000000002', '88888888-0000-0000-0000-000000000001', '77777777-0000-0000-0000-000000000002', 'dddd0000-0000-0000-0000-000000000002', now() + interval '3 days', now() + interval '3 days' + interval '45 minutes', 1, 45000.00, 'RESERVED', null), + -- GRUPAL, sesión compartida: Camilo con 6 plazas... + ('dddd0000-0000-0000-0000-000000000003', '44444444-0000-0000-0000-000000000003', '66666666-0000-0000-0000-000000000001', 'aaaa0000-0000-0000-0000-000000000003', '88888888-0000-0000-0000-000000000001', '77777777-0000-0000-0000-000000000002', 'ffff0000-0000-0000-0000-000000000001', now() + interval '5 days', now() + interval '5 days' + interval '120 minutes', 6, 180000.00, 'CONFIRMED', null), + -- ...y Sara con 2 más en el MISMO taller: 6 + 2 = 8 = cupo exacto + ('dddd0000-0000-0000-0000-000000000008', '44444444-0000-0000-0000-000000000004', '66666666-0000-0000-0000-000000000001', 'aaaa0000-0000-0000-0000-000000000003', '88888888-0000-0000-0000-000000000001', '77777777-0000-0000-0000-000000000002', 'ffff0000-0000-0000-0000-000000000001', now() + interval '5 days', now() + interval '5 days' + interval '120 minutes', 2, 60000.00, 'CONFIRMED', null), + ('dddd0000-0000-0000-0000-000000000004', '44444444-0000-0000-0000-000000000001', '66666666-0000-0000-0000-000000000002', 'aaaa0000-0000-0000-0000-000000000004', '88888888-0000-0000-0000-000000000003', '77777777-0000-0000-0000-000000000003', 'dddd0000-0000-0000-0000-000000000004', now() + interval '1 days', now() + interval '1 days' + interval '40 minutes', 1, 90000.00, 'CONFIRMED', null), + -- Histórica: por eso 'Blanqueamiento' se desactiva, no se borra (HU-004) + ('dddd0000-0000-0000-0000-000000000005', '44444444-0000-0000-0000-000000000002', '66666666-0000-0000-0000-000000000002', 'aaaa0000-0000-0000-0000-000000000005', '88888888-0000-0000-0000-000000000003', '77777777-0000-0000-0000-000000000003', 'dddd0000-0000-0000-0000-000000000005', now() - interval '20 days', now() - interval '20 days' + interval '60 minutes', 1, 250000.00, 'COMPLETED', null), + -- Cancelada: ocupa la misma silla y franja que la reserva 1 y NO choca + ('dddd0000-0000-0000-0000-000000000006', '44444444-0000-0000-0000-000000000003', '66666666-0000-0000-0000-000000000001', 'aaaa0000-0000-0000-0000-000000000001', '88888888-0000-0000-0000-000000000001', '77777777-0000-0000-0000-000000000002', 'dddd0000-0000-0000-0000-000000000006', now() + interval '2 days', now() + interval '2 days' + interval '30 minutes', 1, 35000.00, 'CANCELLED', now() - interval '1 days'), + -- CLAVE PARA HU-002: creada cuando regía la política v1 de la barbería. + -- Conserva 1440 minutos de cancelación gratis aunque la v2 los bajó a 720. + ('dddd0000-0000-0000-0000-000000000007', '44444444-0000-0000-0000-000000000001', '66666666-0000-0000-0000-000000000001', 'aaaa0000-0000-0000-0000-000000000002', '88888888-0000-0000-0000-000000000001', '77777777-0000-0000-0000-000000000001', 'dddd0000-0000-0000-0000-000000000007', now() - interval '25 days', now() - interval '25 days' + interval '45 minutes', 1, 40000.00, 'COMPLETED', null); + +insert into booking_resources (booking_id, resource_id, location_id, session_id, starts_at, ends_at, status) +select b.id, a.resource_id, b.location_id, b.session_id, b.starts_at, b.ends_at, b.status +from bookings b +join (values + ('dddd0000-0000-0000-0000-000000000001'::uuid, 'cccc0000-0000-0000-0000-000000000001'::uuid), + ('dddd0000-0000-0000-0000-000000000002'::uuid, 'cccc0000-0000-0000-0000-000000000002'::uuid), + -- las dos reservas del taller ocupan EL MISMO salón, misma sesión + ('dddd0000-0000-0000-0000-000000000003'::uuid, 'cccc0000-0000-0000-0000-000000000005'::uuid), + ('dddd0000-0000-0000-0000-000000000008'::uuid, 'cccc0000-0000-0000-0000-000000000005'::uuid), + ('dddd0000-0000-0000-0000-000000000004'::uuid, 'cccc0000-0000-0000-0000-000000000007'::uuid), + ('dddd0000-0000-0000-0000-000000000005'::uuid, 'cccc0000-0000-0000-0000-000000000007'::uuid), + ('dddd0000-0000-0000-0000-000000000006'::uuid, 'cccc0000-0000-0000-0000-000000000001'::uuid), + ('dddd0000-0000-0000-0000-000000000007'::uuid, 'cccc0000-0000-0000-0000-000000000002'::uuid) +) as a(booking_id, resource_id) on a.booking_id = b.id; + +insert into booking_status_changes (booking_id, from_status, to_status, reason, changed_by) values + ('dddd0000-0000-0000-0000-000000000001', 'RESERVED', 'CONFIRMED', null, '99999999-0000-0000-0000-000000000001'), + ('dddd0000-0000-0000-0000-000000000005', 'CONFIRMED', 'COMPLETED', null, '99999999-0000-0000-0000-000000000002'), + ('dddd0000-0000-0000-0000-000000000006', 'RESERVED', 'CANCELLED', 'El cliente solicitó la cancelación', '44444444-0000-0000-0000-000000000003'); From b5867d3302d6afc4f607666280eeebee9c9a5e88 Mon Sep 17 00:00:00 2001 From: Anderson Herrera <43342146+andersonhg19@users.noreply.github.com> Date: Mon, 21 Sep 2026 22:53:46 -0500 Subject: [PATCH 03/14] feat: verify database artifacts on pull request with GitHub Actions --- .github/workflows/database.yml | 88 ++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 .github/workflows/database.yml diff --git a/.github/workflows/database.yml b/.github/workflows/database.yml new file mode 100644 index 0000000..6b0df48 --- /dev/null +++ b/.github/workflows/database.yml @@ -0,0 +1,88 @@ +name: database + +# Comprobación automática del modelo de datos. +# El caso exige "integrar mediante pull request, revisión por pares y +# comprobaciones automáticas obligatorias". Este workflow cubre la parte +# de base de datos: levanta un PostgreSQL vacío y verifica que el DDL +# ejecute, que los datos de prueba carguen, que las consultas clave +# devuelvan filas y que las restricciones rechacen lo que deben rechazar. +# +# Sólo se dispara cuando cambia algo bajo docs/database/, para no +# interferir con los cambios de código Java. + +on: + push: + branches: [main] + paths: ['docs/database/**', '.github/workflows/database.yml'] + pull_request: + paths: ['docs/database/**', '.github/workflows/database.yml'] + workflow_dispatch: + +jobs: + esquema: + name: Esquema, datos y restricciones + runs-on: ubuntu-latest + + services: + postgres: + image: postgres:16 + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: reservas + ports: ['5432:5432'] + options: >- + --health-cmd pg_isready + --health-interval 5s + --health-timeout 5s + --health-retries 10 + + env: + PGPASSWORD: postgres + PSQL: psql -h localhost -U postgres -d reservas + + steps: + - uses: actions/checkout@v4 + + - name: Instalar cliente de PostgreSQL + run: sudo apt-get update && sudo apt-get install -y postgresql-client + + - name: El DDL ejecuta contra una base vacía + run: $PSQL -v ON_ERROR_STOP=1 -q -f docs/database/schema.sql + + - name: Se crearon las 19 tablas + run: | + n=$($PSQL -tAc "select count(*) from information_schema.tables where table_schema='public'") + echo "tablas creadas: $n" + test "$n" -eq 19 + + - name: El DDL es idempotente + run: $PSQL -v ON_ERROR_STOP=1 -q -f docs/database/schema.sql + + - name: Los datos de prueba cargan + run: $PSQL -v ON_ERROR_STOP=1 -q -f docs/database/seed.sql + + - name: Las consultas clave devuelven filas + run: | + salida=$($PSQL -v ON_ERROR_STOP=1 -f docs/database/consultas-clave.sql) + echo "$salida" + n=$(echo "$salida" | grep -cE '^\([0-9]+ row') + echo "consultas con resultado: $n" + test "$n" -eq 14 + + - name: Las restricciones rechazan lo que deben rechazar + run: | + salida=$($PSQL -f docs/database/pruebas-integridad.sql 2>&1) + echo "$salida" + rechazos=$(echo "$salida" | grep -cE '^ERROR:') + coladas=$(echo "$salida" | grep -cE '^(INSERT|UPDATE|DELETE)') + echo "rechazos: $rechazos · instrucciones que pasaron: $coladas" + test "$rechazos" -eq 18 + test "$coladas" -eq 0 + + - name: La seguridad de fila queda habilitada + run: | + $PSQL -v ON_ERROR_STOP=1 -q -f docs/database/rls.sql + n=$($PSQL -tAc "select count(*) from pg_class where relnamespace='public'::regnamespace and relkind='r' and relrowsecurity") + echo "tablas con RLS: $n" + test "$n" -eq 19 From 98033879e4bf9c0e6e25e4419b4f40ad22e9b575 Mon Sep 17 00:00:00 2001 From: Anderson Herrera <43342146+andersonhg19@users.noreply.github.com> Date: Mon, 21 Sep 2026 22:53:46 -0500 Subject: [PATCH 04/14] fix: extend row level security to every business table (ADR-0002 policy) --- docs/database/rls.sql | 79 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 16 deletions(-) diff --git a/docs/database/rls.sql b/docs/database/rls.sql index 2610ef7..bb42d9a 100644 --- a/docs/database/rls.sql +++ b/docs/database/rls.sql @@ -1,29 +1,76 @@ -- ============================================================= --- Seguridad Supabase — Sprint 1 --- Ejecutar DESPUÉS de que Hibernate cree las tablas (ddl-auto) --- o junto con schema.sql en un proyecto nuevo. +-- Seguridad Supabase — Row Level Security +-- Ejecutar DESPUÉS de crear las tablas (schema.sql o ddl-auto). -- -- Contexto: el anon key de Supabase es público y PostgREST -- expone el esquema `public`. Sin RLS, cualquier persona con --- el anon key podría leer clients/login_attempts vía Data API. --- El backend se conecta por JDBC como dueño de las tablas --- (rol postgres), que bypasea RLS, por lo que la aplicación --- sigue funcionando igual. +-- el anon key podría leer las tablas vía Data API. El backend +-- se conecta por JDBC como dueño de las tablas (rol postgres), +-- que bypasea RLS, por lo que la aplicación sigue funcionando +-- igual. +-- +-- La política del ADR-0002 es RLS en TODAS las tablas de +-- negocio, así que este script cubre las diecinueve. Con RLS +-- habilitado y sin políticas, el modo por defecto es denegar. +-- +-- Los bloques DO permiten ejecutarlo también contra un +-- PostgreSQL local, donde los roles `anon` y `authenticated` +-- no existen: allí basta con habilitar RLS y omitir el REVOKE. -- ============================================================= -alter table if exists clients enable row level security; -alter table if exists login_attempts enable row level security; +do $$ +declare + t text; + tablas text[] := array[ + 'cities', 'organization_categories', 'currencies', + 'clients', 'login_attempts', + 'organizations', 'organization_members', 'organization_policies', 'locations', + 'services', 'service_locations', 'resource_types', + 'service_resource_requirements', 'resources', 'schedules', + 'bookings', 'booking_resources', 'booking_status_changes', + 'account_status_changes' + ]; + hay_roles boolean := exists (select 1 from pg_roles where rolname = 'anon'); +begin + foreach t in array tablas loop + if to_regclass('public.' || t) is not null then + execute format('alter table public.%I enable row level security', t); + if hay_roles then + execute format('revoke all on public.%I from anon, authenticated', t); + end if; + end if; + end loop; + + if hay_roles then + raise notice 'RLS habilitado y acceso Data API revocado en % tablas', array_length(tablas, 1); + else + raise notice 'RLS habilitado en % tablas. Los roles anon/authenticated no existen en esta base (PostgreSQL local): se omite el REVOKE', array_length(tablas, 1); + end if; +end $$; + + +-- Catálogos de lectura pública (opcional, Sprint 2+). +-- Ciudades, categorías y monedas no son datos sensibles: si el +-- frontend los necesita para poblar listas desplegables sin pasar +-- por el backend, se otorgan con una política de solo lectura. +-- +-- grant select on cities, organization_categories, currencies to anon, authenticated; +-- create policy "cities_select_all" on cities for select to anon, authenticated using (true); --- Negar explícitamente el acceso Data API a los roles públicos. --- Con RLS habilitado y sin políticas, tampoco ven filas. -revoke all on clients from anon, authenticated; -revoke all on login_attempts from anon, authenticated; --- Opcional (Sprint 2+): si se desea que un cliente autenticado --- lea SU propio perfil directamente vía PostgREST, otorgar y --- crear política de propiedad (nunca user_metadata en políticas): +-- Propiedad del propio perfil (opcional, Sprint 2+). +-- Para que un cliente autenticado lea SU perfil vía PostgREST. +-- Nunca usar user_metadata en una política: es editable por el usuario. -- -- grant select on clients to authenticated; -- create policy "clients_select_own" on clients -- for select to authenticated -- using ( (select auth.uid()) = id ); + + +-- Reservas del propio cliente (opcional, Sprint 2+). +-- +-- grant select on bookings to authenticated; +-- create policy "bookings_select_own" on bookings +-- for select to authenticated +-- using ( (select auth.uid()) = client_id ); From 165c7400c64ba48200baf11b26f437e4db406a32 Mon Sep 17 00:00:00 2001 From: Anderson Herrera <43342146+andersonhg19@users.noreply.github.com> Date: Mon, 21 Sep 2026 22:53:46 -0500 Subject: [PATCH 05/14] docs: rewrite logical model and key queries for the complete schema --- docs/database/consultas-clave.md | 267 ++++-- docs/database/diagrama-er.drawio | 1430 ++++++++++++++++++++++++++++++ docs/database/er-catalogo.png | Bin 0 -> 133262 bytes docs/database/er-identidad.png | Bin 0 -> 124972 bytes docs/database/er-reservas.png | Bin 0 -> 122689 bytes docs/database/modelo-logico.md | 309 ++++--- 6 files changed, 1803 insertions(+), 203 deletions(-) create mode 100644 docs/database/diagrama-er.drawio create mode 100644 docs/database/er-catalogo.png create mode 100644 docs/database/er-identidad.png create mode 100644 docs/database/er-reservas.png diff --git a/docs/database/consultas-clave.md b/docs/database/consultas-clave.md index d40475e..90f1c85 100644 --- a/docs/database/consultas-clave.md +++ b/docs/database/consultas-clave.md @@ -1,116 +1,237 @@ # Consultas clave — Plataforma de Reservas -Preguntas de negocio del caso traducidas a SQL. Las consultas 1-5 operan sobre -el modelo físico del Sprint 1; las 6-9 son del modelo lógico completo y se -habilitarán cuando existan las tablas de proveedores/servicios/reservas. +Preguntas de negocio del caso traducidas a SQL. Todas se ejecutan sobre las +tablas que crea `schema.sql` y todas devuelven filas con los datos de +`seed.sql`. La versión ejecutable de corrido, con separadores, está en +`consultas-clave.sql`; el workflow `database.yml` la corre en cada pull request +y falla si alguna deja de devolver resultado. -## Sprint 1 (implementadas sobre el esquema actual) +### 1. ¿Qué servicios puede reservar un cliente en Medellín, en qué sede y a qué precio? (catálogo público) -### 1. ¿El correo o el documento ya están registrados? (unicidad HU-001) +Aplica la regla de HU-002: un proveedor pendiente de aprobación no es visible. ```sql -select exists(select 1 from clients where lower(email) = lower(:email)) as email_taken, - exists(select 1 from clients where upper(document) = upper(:doc)) as document_taken; +select o.name as organizacion, s.name as servicio, l.name as sede, + s.duration_minutes as minutos, s.price, cur.code as moneda, + s.customer_capacity as cupo +from services s + inner join organizations o on o.id = s.organization_id + inner join service_locations sl on sl.service_id = s.id + inner join locations l on l.id = sl.location_id + inner join cities c on c.id = l.city_id + inner join currencies cur on cur.id = s.currency_id +where c.name = 'Medellín' + and s.status = 'ACTIVE' + and l.status = 'ACTIVE' + and o.status = 'ACTIVE' +order by o.name, s.name; ``` -### 2. ¿Qué clientes llevan más de 24 h pendientes de verificación? (re-engagement) +### 2. ¿Cuál es la ocupación por sede y semana: reservas, asistentes e ingresos? (reporte de uso) ```sql -select id, full_name, email, city, created_at -from clients -where status = 'PENDING_VERIFICATION' - and created_at < now() - interval '24 hours' -order by created_at; +select l.name as sede, date_trunc('week', b.starts_at)::date as semana, + count(*) as reservas, sum(b.attendees) as asistentes, + sum(b.total_price) as ingresos +from bookings b + inner join locations l on l.id = b.location_id +where b.status in ('CONFIRMED', 'COMPLETED') +group by l.name, date_trunc('week', b.starts_at) +order by semana, sede; ``` -### 3. ¿Está bloqueada una cuenta por intentos fallidos? (HU-021) +### 3. ¿Qué servicios no puede prestar una sede por falta de recursos? (capacidad instalada) + +Detecta servicios publicados en una sede que en la práctica no se pueden +ejecutar ahí. ```sql -select count(*) as recent_failures -from login_attempts -where lower(email) = lower(:email) - and success = false - and attempted_at > now() - interval '15 minutes'; --- bloqueada si recent_failures >= 5 +select o.name as organizacion, s.name as servicio, l.name as sede, + rt.name as tipo_de_recurso, srr.quantity_required as requiere, + count(r.id) as disponibles +from services s + inner join organizations o on o.id = s.organization_id + inner join service_locations sl on sl.service_id = s.id + inner join locations l on l.id = sl.location_id + inner join service_resource_requirements srr on srr.service_id = s.id + inner join resource_types rt on rt.id = srr.resource_type_id + left join resources r on r.resource_type_id = rt.id + and r.location_id = l.id + and r.status = 'ACTIVE' +group by o.name, s.name, l.name, rt.name, srr.quantity_required +having count(r.id) < srr.quantity_required +order by o.name, s.name, l.name; +``` + +### 4. ¿Cuáles son los servicios más reservados de cada organización? (con empates) + +Con `rank()` y no `row_number()`, para que dos servicios empatados compartan +posición. + +```sql +select organizacion, servicio, reservas, posicion +from ( + select o.name as organizacion, s.name as servicio, count(b.id) as reservas, + rank() over (partition by o.id order by count(b.id) desc) as posicion + from services s + inner join organizations o on o.id = s.organization_id + left join bookings b on b.service_id = s.id + and b.status in ('CONFIRMED', 'COMPLETED') + group by o.id, o.name, s.name +) ranking +where posicion <= 3 +order by organizacion, posicion, servicio; ``` -### 4. Historial de intentos de login de un correo (auditoría de seguridad) +### 5. Si se suspende un proveedor, ¿qué reservas futuras quedan afectadas? (HU-003) + +Es el informe que HU-003 exige antes de confirmar la suspensión. ```sql -select email, success, attempted_at +select b.id as reserva, c.full_name as cliente, c.email, c.phone, + s.name as servicio, l.name as sede, b.starts_at, b.status +from bookings b + inner join services s on s.id = b.service_id + inner join clients c on c.id = b.client_id + inner join locations l on l.id = b.location_id +where s.organization_id = (select id from organizations where nit = :nit) + and b.starts_at >= now() + and b.status in ('RESERVED', 'CONFIRMED') +order by b.starts_at; +``` + +### 6. ¿Qué agenda tiene cada recurso y cuánta carga lleva encima? (disponibilidad) + +El `left join` es lo que deja ver también los recursos completamente libres. + +```sql +select l.name as sede, r.name as recurso, sch.start_time as abre, + sch.end_time as cierra, count(br.booking_id) as reservas_vivas +from schedules sch + inner join resources r on r.id = sch.resource_id + inner join locations l on l.id = r.location_id + left join booking_resources br on br.resource_id = r.id + and br.status in ('RESERVED', 'CONFIRMED') + and br.starts_at::date = :dia +where sch.day_of_week = extract(isodow from date :dia) + and sch.active +group by l.name, r.name, sch.start_time, sch.end_time +order by l.name, r.name; +``` + +### 7. ¿Qué proveedores llevan más tiempo esperando aprobación? (cola del administrador) + +```sql +select o.name as organizacion, o.nit, oc.name as categoria, o.contact_email, + o.created_at::date as solicitado_el, + current_date - o.created_at::date as dias_esperando +from organizations o + inner join organization_categories oc on oc.id = o.category_id +where o.status = 'PENDING_APPROVAL' +order by dias_esperando desc, o.name; +``` + +### 8. ¿Está bloqueada una cuenta por intentos fallidos? (HU-021) + +El umbral y la ventana son los de `LoginLockPolicy`: cinco fallos en quince +minutos. + +```sql +select email, count(*) as fallos_recientes, max(attempted_at) as ultimo_intento, + count(*) >= 5 as bloqueada from login_attempts -where lower(email) = lower(:email) -order by attempted_at desc -limit 50; +where success = false + and attempted_at > localtimestamp - interval '15 minutes' +group by email +order by fallos_recientes desc; ``` -### 5. ¿Cuántos clientes hay por ciudad y canal de notificación? (crecimiento) +### 9. ¿Qué clientes llevan más de 24 h pendientes de verificación? (re-engagement) ```sql -select city, notification_channel, count(*) as clients, - count(*) filter (where status = 'ACTIVE') as active_clients +select id, full_name, email, city, created_at, + localtimestamp - created_at as lleva_esperando from clients -group by city, notification_channel -order by clients desc; +where status = 'PENDING_VERIFICATION' + and created_at < localtimestamp - interval '24 hours' +order by created_at; ``` -## Sprints 2+ (sobre el modelo lógico completo) +### 10. ¿Qué condiciones de cancelación rigen para cada reserva? (HU-002) -### 6. Reservas futuras de un cliente (historial y próximas citas) +Es la prueba de que la regla está resuelta en el modelo. Dos reservas de la +misma organización salen con ventanas distintas, porque cada una apunta a la +versión de política que regía cuando se creó. ```sql -select b.id, s.name as service, l.name as location, b.starts_at, b.status +select o.name as organizacion, b.starts_at, b.status, + op.version as version_politica, + op.free_cancellation_window_minutes as minutos_cancelacion_gratis, + case when op.replaced_at is null then 'vigente' else 'histórica' end + as estado_de_la_politica from bookings b -join services s on s.id = b.service_id -join locations l on l.id = b.location_id -where b.client_id = :clientId - and b.starts_at >= now() -order by b.starts_at; + inner join organization_policies op on op.id = b.policy_id + inner join organizations o on o.id = op.organization_id +order by o.name, b.starts_at; ``` -### 7. ¿Qué reservas afecta la suspensión de un proveedor? (HU-003) +### 11. ¿El correo, el documento o el NIT ya están registrados? (unicidad HU-001 y HU-002) + +Las tres validaciones previas al registro en una sola ida a la base. ```sql -select b.id, c.full_name, c.email, s.name, b.starts_at -from bookings b -join clients c on c.id = b.client_id -join services s on s.id = b.service_id -where s.provider_id = :providerId - and b.starts_at >= now() - and b.status in ('RESERVED', 'CONFIRMED'); +select exists (select 1 from clients where lower(email) = lower(:email)) as correo_ya_registrado, + exists (select 1 from clients where document = :documento) as documento_ya_registrado, + exists (select 1 from organizations where nit = :nit) as nit_ya_registrado; ``` -### 8. Ocupación de un servicio en una sede y semana (reporte HU de reportes) +### 12. ¿Qué clientes se registraron y nunca han reservado? (subconsulta correlacionada) ```sql -select date_trunc('day', b.starts_at) as day, - count(*) as bookings, - sum(b.attendees) as attendees, - sum(b.total_price) as revenue -from bookings b -where b.service_id = :serviceId - and b.location_id = :locationId - and b.starts_at >= :weekStart and b.starts_at < :weekStart + interval '7 days' - and b.status in ('CONFIRMED', 'COMPLETED') -group by 1 -order by 1; +select c.id, c.full_name, c.email, c.city, c.status +from clients c +where not exists (select 1 from bookings b where b.client_id = c.id) +order by c.full_name; +``` + +### 13. ¿Qué servicios se prestan en una sede y no en otra? (operador de diferencia) + +```sql +select s.name as servicio +from service_locations sl + inner join services s on s.id = sl.service_id + inner join locations l on l.id = sl.location_id +where l.name = 'Sede Poblado' +except +select s.name +from service_locations sl + inner join services s on s.id = sl.service_id + inner join locations l on l.id = sl.location_id +where l.name = 'Sede Envigado' +order by servicio; ``` -### 9. Disponibilidad real de un recurso en un día (control de disponibilidad) +### 14. ¿Qué sedes ofrecen todos los servicios activos de su organización? (división relacional) + +El operador de división expresado con la doble negación: no existe un servicio +activo de la organización que no se preste en esa sede. ```sql -select st.start_time, st.end_time, - coalesce(sum(b.attendees) filter (where b.status in ('RESERVED','CONFIRMED')), 0) as booked -from schedule_templates st -left join bookings b - on b.resource_id = st.resource_id - and b.starts_at::date = :day - and b.starts_at::time >= st.start_time - and b.starts_at::time < st.end_time -where st.location_id = :locationId - and st.resource_id = :resourceId - and st.day_of_week = extract(isodow from date :day) - and st.active -group by st.id -order by st.start_time; +select o.name as organizacion, l.name as sede +from locations l + inner join organizations o on o.id = l.organization_id +where l.status = 'ACTIVE' + and not exists (select 1 + from services s + where s.organization_id = l.organization_id + and s.status = 'ACTIVE' + and not exists (select 1 + from service_locations sl + where sl.service_id = s.id + and sl.location_id = l.id)) +order by o.name, l.name; ``` + +Ver `schema.sql` (modelo físico), `modelo-logico.md` (entidades y +normalización), `seed.sql` (los datos sobre los que corren estas consultas) y +`consultas-clave.sql` (la versión ejecutable). diff --git a/docs/database/diagrama-er.drawio b/docs/database/diagrama-er.drawio new file mode 100644 index 0000000..2bcbd2e --- /dev/null +++ b/docs/database/diagrama-er.drawio @@ -0,0 +1,1430 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/database/er-catalogo.png b/docs/database/er-catalogo.png new file mode 100644 index 0000000000000000000000000000000000000000..199c70168fe2da2c8bee89128cbc735c7cd9bf0a GIT binary patch literal 133262 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 literal 0 HcmV?d00001 diff --git a/docs/database/er-identidad.png b/docs/database/er-identidad.png new file mode 100644 index 0000000000000000000000000000000000000000..4b5f2070ccc04a3b742944505e4c6063dbf7b45e GIT binary patch literal 124972 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