🇪🇸 Español

erDiagram
    usuarios {
        INT id_usuario PK
        VARCHAR correo "UK"
        VARCHAR hash_contrasena
        ENUM rol "ADMIN, SECRETARIA, PROFESIONAL, PACIENTE"
        VARCHAR dni
        VARCHAR nombres 
        VARCHAR apellidos 
        VARCHAR telefono
        VARCHAR direccion
        VARCHAR url_imagen_dni "Opcional"
        DATETIME fecha_registro
        DATETIME fecha_baja "Opcional"
    }

    obras_sociales {
        INT id_obra_social PK
        VARCHAR nombre "UK"
        DATETIME fecha_baja "Opcional"
    }

    paciente_obra_social {
        INT id_usuario PK, FK
        INT id_obra_social PK, FK
        VARCHAR numero_afiliado
    }

    especialidades {
        INT id_especialidad PK
        VARCHAR nombre "UK"
        DATETIME fecha_baja "Opcional"
    }

    profesional_especialidad {
        VARCHAR matricula PK
        INT id_usuario FK
        INT id_especialidad FK
    }

    sedes {
        INT id_sede PK
        VARCHAR nombre
        VARCHAR direccion
        VARCHAR telefono "Opcional"
        DATETIME fecha_baja "Opcional"
    }

    clasificaciones {
        INT id_clasificacion PK
        VARCHAR nombre "UK"
    }

    agendas {
        INT id_agenda PK
        VARCHAR matricula_profesional FK
        INT id_sede FK
        INT id_clasificacion FK
        INT duracion_turno_minutos
        INT max_sobreturnos_dia
        INT max_sobreturnos_turno
        BOOLEAN esta_pausada
        DATETIME fecha_baja "Opcional"
    }

    configuracion_agendas {
        INT id_configuracion PK
        INT id_agenda FK
        ENUM dia_semana
        VARCHAR hora_inicio
        VARCHAR hora_fin
        DATE valida_desde
        DATE valida_hasta
    }
    
    bloqueos_agenda {
        INT id_bloqueo PK
        INT id_agenda FK "Opcional"
        DATE fecha_inicio
        DATE fecha_fin
        TEXT motivo
    }

    turnos {
        INT id_turno PK
        INT id_agenda FK
        INT id_paciente FK "Opcional"
        DATETIME fecha_hora_inicio
        ENUM estado "LIBRE, PROPUESTO, RESERVADO, CANCELADO, AUSENTE, PRESENTE, EN_CURSO, ATENDIDO"
        BOOLEAN es_sobreturno
        TEXT motivo_consulta "Opcional"
    }
    
    lista_espera {
        INT id_lista_espera PK
        INT id_paciente FK
        INT id_especialidad FK "Opcional"
        INT id_profesional FK "Opcional"
        DATETIME fecha_solicitud
    }

    %% Relaciones
    usuarios ||--o{ paciente_obra_social : "tiene cobertura"
    obras_sociales ||--o{ paciente_obra_social : "cubre a"
    
    usuarios ||--o{ profesional_especialidad : "tiene credenciales"
    especialidades ||--o{ profesional_especialidad : "pertenece a"
    
    profesional_especialidad ||--o{ agendas : "administra"
    sedes ||--o{ agendas : "aloja"
    clasificaciones ||--o{ agendas : "categoriza"
    
    agendas ||--|{ configuracion_agendas : "configurada por"
    agendas ||--o{ bloqueos_agenda : "tiene bloqueos"
    agendas ||--o{ turnos : "genera"
    
    usuarios ||--o{ turnos : "solicita"
    usuarios ||--o{ lista_espera : "espera por"
    especialidades ||--o{ lista_espera : "para especialidad"
    usuarios ||--o{ lista_espera : "con profesional"

🇬🇧 Inglés

erDiagram
    users {
        INT user_id PK
        VARCHAR email "UK"
        VARCHAR password_hash
        ENUM role "ADMIN, SECRETARY, PROFESSIONAL, PATIENT"
        VARCHAR national_id
        VARCHAR first_names 
        VARCHAR last_names 
        VARCHAR phone
        VARCHAR address
        VARCHAR national_id_image_url "Nullable"
        DATETIME registered_at
        DATETIME deleted_at "Nullable"
    }
    %% Note: users has UNIQUE(national_id, role)

    health_insurances {
        INT insurance_id PK
        VARCHAR name "UK"
        DATETIME deleted_at "Nullable"
    }

    patient_health_insurance {
        INT user_id PK, FK
        INT insurance_id PK, FK
        VARCHAR member_number
    }

    specialties {
        INT specialty_id PK
        VARCHAR name "UK"
        DATETIME deleted_at "Nullable"
    }

    professional_specialty {
        VARCHAR license_number PK
        INT user_id FK
        INT specialty_id FK
    }

    locations {
        INT location_id PK
        VARCHAR name
        VARCHAR address
        VARCHAR phone "Nullable"
        DATETIME deleted_at "Nullable"
    }

    classifications {
        INT classification_id PK
        VARCHAR name "UK"
    }

    schedules {
        INT schedule_id PK
        VARCHAR professional_license FK
        INT location_id FK
        INT classification_id FK
        INT slot_duration_minutes
        INT max_overbooks_per_day
        INT max_overbooks_per_slot
        BOOLEAN is_paused
        DATETIME deleted_at "Nullable"
    }

    schedule_configs {
        INT config_id PK
        INT schedule_id FK
        ENUM day_of_week
        VARCHAR start_time
        VARCHAR end_time
        DATE valid_from
        DATE valid_until
    }
    
    schedule_blocks {
        INT block_id PK
        INT schedule_id FK "Nullable"
        DATE start_date
        DATE end_date
        TEXT reason
    }

    slots {
        INT slot_id PK
        INT schedule_id FK
        INT patient_id FK "Nullable"
        DATETIME starts_at
        ENUM status "FREE, PROPOSED, BOOKED, CANCELLED, NO_SHOW, ARRIVED, IN_PROGRESS, FULFILLED"
        BOOLEAN is_overbook
        TEXT consultation_reason "Nullable"
    }
    
    waiting_list {
        INT waitlist_id PK
        INT patient_id FK
        INT specialty_id FK "Nullable"
        INT professional_id FK "Nullable"
        DATETIME request_date
    }
    %% Note: waiting_list has UNIQUE(patient_id, professional_id, specialty_id)

    %% Relationships
    users ||--o{ patient_health_insurance : "has coverage"
    health_insurances ||--o{ patient_health_insurance : "insures"
    
    users ||--o{ professional_specialty : "has credentials"
    specialties ||--o{ professional_specialty : "belongs to"
    
    professional_specialty ||--o{ schedules : "manages"
    locations ||--o{ schedules : "hosts"
    classifications ||--o{ schedules : "categorizes"
    
    schedules ||--|{ schedule_configs : "configured by"
    schedules ||--o{ schedule_blocks : "has specific blocks"
    schedules ||--o{ slots : "generates"
    
    users ||--o{ slots : "requests"
    users ||--o{ waiting_list : "waits for"
    specialties ||--o{ waiting_list : "for specialty"
    users ||--o{ waiting_list : "with professional"