-- =============================================================================
-- Migración:    0006_create_sessions_table
-- Sprint:       1.1 — auth + RBAC + audit
-- Tabla:        sessions
-- Aplica en:    BD de cada tenant (innovium_<slug>)
-- Dependencias: 0001 (users).
--
-- Descripción:
--   Sesiones activas. Una fila por sesión iniciada. La PK es el token
--   de sesión (64 chars, generado con random_bytes(32) → bin2hex).
--   El cliente lo recibe en cookie HttpOnly + Secure + SameSite=Lax.
--
-- TTL del sprint (confirmado por Ricci):
--   - Sin "Recordarme":  expira_en = ahora + 8h (absoluto)
--                        + sliding por inactividad de 4h
--                        (lo que se cumpla primero).
--   - Con "Recordarme":  expira_en = ahora + 30 días
--                        sin sliding (TTL absoluto puro).
--
-- Notas:
--   - ON DELETE CASCADE en user_id: si se borra (físicamente) un user
--     se llevan sus sesiones. Excepción documentada en SCHEMA_SISTEMA.md.
--   - idx_sessions_expira_en: usado por el job de limpieza
--     (DELETE FROM sessions WHERE expira_en < NOW() — Sprint 2.x).
-- =============================================================================

CREATE TABLE sessions (
    id                  VARCHAR(64)     NOT NULL
                        COMMENT 'Token de sesión hex 64 chars (random_bytes(32) → bin2hex). PK.',
    user_id             BIGINT UNSIGNED NOT NULL
                        COMMENT 'FK → users.id (CASCADE). Dueño de la sesión.',
    ip                  VARCHAR(45)     NOT NULL
                        COMMENT 'IPv4 o IPv6 desde donde se inició la sesión.',
    user_agent          VARCHAR(500)    NOT NULL DEFAULT ''
                        COMMENT 'Navegador/dispositivo. Default vacío para evitar branches en código.',
    iniciada_en         DATETIME        NOT NULL DEFAULT CURRENT_TIMESTAMP
                        COMMENT 'UTC del login que creó la sesión. Inmutable.',
    ultima_actividad_en DATETIME        NOT NULL DEFAULT CURRENT_TIMESTAMP
                        COMMENT 'UTC del último request autenticado. Mueve el sliding window.',
    expira_en           DATETIME        NOT NULL
                        COMMENT 'UTC del cap absoluto. La sesión expira al primero que se cumpla (esta o sliding).',
    recordarme          TINYINT(1)      NOT NULL DEFAULT 0
                        COMMENT '1=cap 30 días sin sliding. 0=cap 8h con sliding 4h.',
    PRIMARY KEY (id),
    KEY idx_sessions_user_id (user_id),
    KEY idx_sessions_expira_en (expira_en),
    CONSTRAINT fk_sessions_user
        FOREIGN KEY (user_id) REFERENCES users (id)
        ON DELETE CASCADE ON UPDATE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='Sesiones autenticadas. PK=token. Sesiones en BD (no archivos) para invalidación cross-device.';
