-- ============================================================================
-- Migration 034 - Portale fornitore: utenti, OTP/magic-link, sessioni revocabili
-- ----------------------------------------------------------------------------
-- PROPOSTA DI DESIGN (NON ancora applicata). Da eseguire su host MySQL.
--
-- Login passwordless del fornitore per compilare le campagne questionario:
--   supplier_users    = referenti del fornitore abilitati al portale
--   supplier_otp      = codici OTP + magic token (hash), tentativi, scadenza
--   supplier_sessions = sessioni con jti, revocabili (revoked_at)
--
-- Tutto NO-PASSWORD: l'accesso avviene via OTP/magic-link consegnato all'email.
-- Sicurezza: lockout persistente su supplier_otp.attempts; sessione revocabile.
--
-- CREATE TABLE IF NOT EXISTS (idempotente). DELIMITER -> usare "source".
--   mysql -h localhost nis2_agile_db -e "source docs/sql/034_supplier_portal_auth.sql"
-- ============================================================================

-- 1. Utenti del fornitore (referenti abilitati al portale)
CREATE TABLE IF NOT EXISTS supplier_users (
    id              INT NOT NULL AUTO_INCREMENT,
    supplier_id     INT NOT NULL,
    organization_id INT NOT NULL COMMENT 'Denormalizzato: org committente proprietaria del fornitore',
    email           VARCHAR(255) NOT NULL,
    full_name       VARCHAR(255) NULL,
    role            ENUM('contact','compliance','signer') NOT NULL DEFAULT 'contact',
    is_active       TINYINT(1) NOT NULL DEFAULT 1,
    last_login_at   DATETIME NULL,
    created_at      DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at      DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    UNIQUE KEY uq_supuser_supplier_email (supplier_id, email),
    KEY idx_supuser_org (organization_id),
    KEY idx_supuser_email (email),
    CONSTRAINT fk_supuser_supplier FOREIGN KEY (supplier_id)     REFERENCES suppliers(id) ON DELETE CASCADE,
    CONSTRAINT fk_supuser_org      FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='Referenti del fornitore abilitati al portale (login passwordless)';

-- 2. OTP + magic-link (hash, tentativi, scadenza)
CREATE TABLE IF NOT EXISTS supplier_otp (
    id               INT NOT NULL AUTO_INCREMENT,
    supplier_user_id INT NOT NULL,
    otp_hash         CHAR(64) NULL COMMENT 'SHA-256 del codice OTP numerico',
    magic_token_hash CHAR(64) NULL COMMENT 'SHA-256 del magic-link token',
    purpose          ENUM('login','questionnaire') NOT NULL DEFAULT 'login',
    attempts         INT NOT NULL DEFAULT 0 COMMENT 'Tentativi di verifica falliti (lockout persistente)',
    max_attempts     INT NOT NULL DEFAULT 5,
    locked_until     DATETIME NULL COMMENT 'Lockout temporaneo dopo max_attempts',
    consumed_at      DATETIME NULL COMMENT 'Quando usato (single-use)',
    expires_at       DATETIME NOT NULL,
    ip_created       VARCHAR(45) NULL,
    created_at       DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    KEY idx_sotp_user (supplier_user_id),
    KEY idx_sotp_expires (expires_at),
    KEY idx_sotp_magic (magic_token_hash),
    CONSTRAINT fk_sotp_user FOREIGN KEY (supplier_user_id) REFERENCES supplier_users(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='OTP e magic-link per autenticazione passwordless del fornitore';

-- 3. Sessioni revocabili (jti, scadenza, revoca)
CREATE TABLE IF NOT EXISTS supplier_sessions (
    id               INT NOT NULL AUTO_INCREMENT,
    supplier_user_id INT NOT NULL,
    organization_id  INT NOT NULL COMMENT 'Denormalizzato per filtri/audit',
    jti              CHAR(36) NOT NULL COMMENT 'JWT ID (UUID) della sessione',
    ip_address       VARCHAR(45) NULL,
    user_agent       VARCHAR(500) NULL,
    expires_at       DATETIME NOT NULL,
    revoked_at       DATETIME NULL COMMENT 'NOT NULL => sessione revocata',
    created_at       DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    UNIQUE KEY uq_ssess_jti (jti),
    KEY idx_ssess_user (supplier_user_id),
    KEY idx_ssess_org (organization_id),
    KEY idx_ssess_expires (expires_at),
    CONSTRAINT fk_ssess_user FOREIGN KEY (supplier_user_id) REFERENCES supplier_users(id) ON DELETE CASCADE,
    CONSTRAINT fk_ssess_org  FOREIGN KEY (organization_id)  REFERENCES organizations(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='Sessioni portale fornitore, revocabili via revoked_at';

-- ROLLBACK (manuale, ordine inverso per le FK):
-- DROP TABLE IF EXISTS supplier_sessions;
-- DROP TABLE IF EXISTS supplier_otp;
-- DROP TABLE IF EXISTS supplier_users;
