-- ============================================================ -- Schema tabelle – Gestione Corrieri -- Allineato alle API: /utenti, /clienti, /consegne -- ============================================================ USE corrieri; -- ------------------------------------------------------------ -- Tabella utenti (API: GET/POST/PUT/DELETE /operatori) -- ------------------------------------------------------------ CREATE TABLE IF NOT EXISTS utente ( UtenteID INT UNSIGNED NOT NULL AUTO_INCREMENT, Nome VARCHAR(100) NOT NULL, Cognome VARCHAR(100) NOT NULL, Email VARCHAR(255) NOT NULL, PasswordHash VARCHAR(255) NOT NULL COMMENT 'Password salvata come hash (es. bcrypt)', Ruolo ENUM("Amministratore", "Operatore") NOT NULL DEFAULT "Operatore", created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (UtenteID), UNIQUE KEY uk_utente_email (Email) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- ------------------------------------------------------------ -- Tabella cliente (API: GET/POST/PUT/DELETE /clienti) -- ------------------------------------------------------------ CREATE TABLE IF NOT EXISTS cliente ( ClienteID INT UNSIGNED NOT NULL AUTO_INCREMENT, Nome VARCHAR(100) NOT NULL, Cognome VARCHAR(100) NOT NULL, Via VARCHAR(100) NOT NULL, Comune VARCHAR(100) NOT NULL, Provincia VARCHAR(2) NOT NULL, Telefono VARCHAR(30) NOT NULL, Email VARCHAR(255) NOT NULL, Note TEXT, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (ClienteID), UNIQUE KEY uk_cliente_email (Email) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- ---------------------------------------------------------------- -- Tabella consegna (API: GET/POST/PUT/DELETE /consegna) -- DataRitiro = giorno in cui il corriere ritira dal cliente. -- DataConsegna = giorno in cui il corriere consegna al cliente. -- Sono eventi indipendenti (nessun vincolo di ordine); almeno una delle due -- date deve essere valorizzata. Se presente, la data non può essere retroattiva. -- ---------------------------------------------------------------- CREATE TABLE IF NOT EXISTS consegna ( ConsegnaID INT UNSIGNED NOT NULL AUTO_INCREMENT, ClienteID INT UNSIGNED NOT NULL, DataRitiro DATE NULL, DataConsegna DATE NULL, Stato ENUM('da ritirare', 'in deposito', 'in consegna', 'in giacenza') NOT NULL DEFAULT 'in deposito', ChiaveConsegna VARCHAR(8) NOT NULL, PRIMARY KEY (ConsegnaID), UNIQUE KEY uk_chiaveConsegna (ChiaveConsegna), KEY idx_DataConsegna (DataConsegna), CONSTRAINT fk_consegna_cliente FOREIGN KEY (ClienteID) REFERENCES cliente (ClienteID) ON UPDATE CASCADE ON DELETE RESTRICT, CONSTRAINT chk_consegna_almeno_una_data CHECK (DataRitiro IS NOT NULL OR DataConsegna IS NOT NULL) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- ---------------------------------------------------------------- -- Trigger retroattività date (DataRitiro e DataConsegna >= oggi) -- CURDATE() non è ammesso nei CHECK: validazione dinamica nei trigger. -- ---------------------------------------------------------------- DROP TRIGGER IF EXISTS trg_consegna_no_retroattivita_insert; DROP TRIGGER IF EXISTS trg_consegna_no_retroattivita_update; DELIMITER $$ CREATE TRIGGER trg_consegna_no_retroattivita_insert BEFORE INSERT ON consegna FOR EACH ROW BEGIN IF NEW.DataRitiro IS NOT NULL AND NEW.DataRitiro < CURDATE() THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'DataRitiro non può essere anteriore alla data odierna'; END IF; IF NEW.DataConsegna IS NOT NULL AND NEW.DataConsegna < CURDATE() THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'DataConsegna non può essere anteriore alla data odierna'; END IF; END$$ CREATE TRIGGER trg_consegna_no_retroattivita_update BEFORE UPDATE ON consegna FOR EACH ROW BEGIN IF NEW.DataRitiro IS NOT NULL AND (OLD.DataRitiro IS NULL OR NEW.DataRitiro <> OLD.DataRitiro) AND NEW.DataRitiro < CURDATE() THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'DataRitiro non può essere anteriore alla data odierna'; END IF; IF NEW.DataConsegna IS NOT NULL AND (OLD.DataConsegna IS NULL OR NEW.DataConsegna <> OLD.DataConsegna) AND NEW.DataConsegna < CURDATE() THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'DataConsegna non può essere anteriore alla data odierna'; END IF; END$$ DELIMITER ;