-- =============================================================================
-- NewFARAH · Schéma complet de production
-- Généré le : 2026-07-07
--
-- DÉPLOIEMENT CIBLE :
--   Base de données  : newmyfarah
--   Utilisateur DB   : newmyfarah
--   Application      : https://newmyfarah.polycliniquefarah.com
--   Admin plateforme : https://newmyfarahadmin.polycliniquefarah.com
--
-- Les tables admin (platform_admins, etablissements, modules…) et les tables
-- tenant (patients, medecins, rendez_vous…) coexistent dans la même base.
--
-- PROCÉDURE D'IMPORT :
--   1. Se connecter avec un compte MySQL ayant le droit CREATE.
--   2. Exécuter :  mysql -u root -p < newfarah_production_schema.sql
--   3. Créer un administrateur plateforme (cf. section en fin de fichier).
--   4. Déclarer l'établissement dans la table etablissements.
--
-- Compatibilité : MySQL 8.0+ / MariaDB 10.5+, moteur InnoDB, utf8mb4.
-- =============================================================================

SET CHARACTER SET utf8mb4;
SET collation_connection = utf8mb4_unicode_ci;
SET foreign_key_checks = 0;
SET sql_mode = 'NO_ENGINE_SUBSTITUTION';

-- =============================================================================
-- CRÉATION DE LA BASE ET DE L'UTILISATEUR
-- =============================================================================

CREATE DATABASE IF NOT EXISTS `newmyfarah`
  CHARACTER SET utf8mb4
  COLLATE utf8mb4_unicode_ci;

-- Créer l'utilisateur applicatif (adapter le mot de passe avant l'import) :
CREATE USER IF NOT EXISTS 'newmyfarah'@'localhost' IDENTIFIED BY 'heDOjKuyFWIGls4N';
GRANT ALL PRIVILEGES ON `newmyfarah`.* TO 'newmyfarah'@'localhost';
FLUSH PRIVILEGES;

USE `newmyfarah`;

-- Table de suivi des migrations (partagée admin + tenant dans cette base)
CREATE TABLE IF NOT EXISTS schema_migrations (
    migration  VARCHAR(255) NOT NULL PRIMARY KEY,
    applied_at DATETIME     NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- =============================================================================
-- TABLES ADMINISTRATIVES
-- platform_admins, etablissements, modules, etablissement_module,
-- etablissement_menu_items, admin_audit_logs
-- =============================================================================

-- [0001_create_platform_admins.sql]
CREATE TABLE platform_admins (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  nom VARCHAR(100) NOT NULL,
  email VARCHAR(255) NOT NULL,
  mot_de_passe_hash VARCHAR(255) NOT NULL,
  actif TINYINT(1) NOT NULL DEFAULT 1,
  derniere_connexion_at DATETIME NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  UNIQUE KEY uniq_platform_admins_email (email)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0001_create_platform_admins.sql', NOW());

-- [0002_create_etablissements.sql]
CREATE TABLE etablissements (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  nom VARCHAR(150) NOT NULL,
  slug VARCHAR(100) NOT NULL,
  sous_domaine VARCHAR(150) NOT NULL,
  db_host VARCHAR(150) NOT NULL,
  db_port SMALLINT UNSIGNED NOT NULL DEFAULT 3306,
  db_name VARCHAR(100) NOT NULL,
  db_username VARCHAR(100) NOT NULL,
  db_password_chiffre TEXT NOT NULL,
  statut ENUM('actif','suspendu','en_provisionnement') NOT NULL DEFAULT 'en_provisionnement',
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  UNIQUE KEY uniq_etablissements_slug (slug),
  UNIQUE KEY uniq_etablissements_sous_domaine (sous_domaine)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0002_create_etablissements.sql', NOW());

-- [0003_create_modules.sql]
CREATE TABLE modules (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  code VARCHAR(60) NOT NULL,
  libelle VARCHAR(150) NOT NULL,
  description TEXT NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  UNIQUE KEY uniq_modules_code (code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0003_create_modules.sql', NOW());

-- [0004_create_etablissement_module.sql]
CREATE TABLE etablissement_module (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  etablissement_id INT UNSIGNED NOT NULL,
  module_id INT UNSIGNED NOT NULL,
  actif TINYINT(1) NOT NULL DEFAULT 0,
  active_at DATETIME NULL,
  UNIQUE KEY uniq_etablissement_module (etablissement_id, module_id),
  CONSTRAINT fk_etablissement_module_etablissement FOREIGN KEY (etablissement_id) REFERENCES etablissements (id) ON DELETE CASCADE,
  CONSTRAINT fk_etablissement_module_module FOREIGN KEY (module_id) REFERENCES modules (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0004_create_etablissement_module.sql', NOW());

-- [0005_add_etablissement_branding.sql]
-- Personnalisation par établissement : logo affiché dans app.newfarah,
-- couleur principale (surcharge des variables CSS --nf-primary*), et
-- emplacement du menu (barre latérale ou barre horizontale).
ALTER TABLE etablissements
  ADD COLUMN logo_path VARCHAR(255) NULL AFTER nom,
  ADD COLUMN couleur_principale VARCHAR(7) NOT NULL DEFAULT '#007F82' AFTER logo_path,
  ADD COLUMN menu_position ENUM('sidebar','topbar') NOT NULL DEFAULT 'sidebar' AFTER couleur_principale;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0005_add_etablissement_branding.sql', NOW());

-- [0006_add_platform_admins_session_token.sql]
-- Empêche la double connexion simultanée d'un même compte (task.txt) : un
-- jeton unique est régénéré à chaque login et comparé à chaque requête
-- authentifiée ; toute session encore active ailleurs portant l'ancien
-- jeton est ainsi invalidée.
ALTER TABLE platform_admins
  ADD COLUMN session_token VARCHAR(64) NULL AFTER mot_de_passe_hash;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0006_add_platform_admins_session_token.sql', NOW());

-- [0007_create_etablissement_menu_items.sql]
-- Organisation du menu (sidebar/topbar) d'un établissement : masquer/afficher
-- un module, son ordre d'affichage, et les sous-pages activées sous lui
-- (ex. Rendez-vous > Agenda). module_code/sous_page_cle référencent des
-- identifiants stables définis dans config/sous_pages.php, pas une FK
-- numérique — pas de table de catalogue séparée à maintenir.
CREATE TABLE etablissement_menu_items (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  etablissement_id INT UNSIGNED NOT NULL,
  module_code VARCHAR(60) NOT NULL,
  sous_page_cle VARCHAR(60) NULL,
  visible TINYINT(1) NOT NULL DEFAULT 1,
  ordre SMALLINT NOT NULL DEFAULT 0,
  UNIQUE KEY uniq_etablissement_menu_item (etablissement_id, module_code, sous_page_cle),
  CONSTRAINT fk_etablissement_menu_item_etablissement FOREIGN KEY (etablissement_id) REFERENCES etablissements (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0007_create_etablissement_menu_items.sql', NOW());

-- [0008_etablissement_menu_items_tree.sql]
-- Évolution de l'organisation du menu (task.txt) : passage d'une simple
-- liste plate (module + sous-page connue, visible/ordre) à un arbre complet
-- glissable-déposable où l'admin peut aussi créer des groupes personnalisés
-- (libellé + icône) et y ranger des modules/sous-pages. parent_id ne peut
-- référencer qu'un nœud de type 'groupe' (vérifié en application, pas en
-- base) ; un nœud sans parent_id est affiché au premier niveau du menu.
-- Séparé en plusieurs ALTER : combiner DROP INDEX + ADD COLUMN + ADD FOREIGN
-- KEY auto-référencée dans un seul ALTER provoque une erreur 1025 ("Foreign
-- key constraint is incorrectly formed") sur ce moteur MySQL/MariaDB.
-- L'index unique existant est la seule colonne couvrant etablissement_id
-- pour la FK fk_etablissement_menu_item_etablissement : lui ajouter un index
-- de remplacement avant de le supprimer, sinon MySQL refuse (errno 1553).
ALTER TABLE etablissement_menu_items
  ADD INDEX idx_etablissement_menu_item_etablissement (etablissement_id);

ALTER TABLE etablissement_menu_items
  DROP INDEX uniq_etablissement_menu_item;

ALTER TABLE etablissement_menu_items
  MODIFY COLUMN module_code VARCHAR(60) NULL,
  ADD COLUMN parent_id INT UNSIGNED NULL AFTER etablissement_id,
  ADD COLUMN type ENUM('module', 'sous_page', 'groupe') NOT NULL DEFAULT 'module' AFTER parent_id,
  ADD COLUMN libelle VARCHAR(150) NULL AFTER sous_page_cle,
  ADD COLUMN icone VARCHAR(60) NULL AFTER libelle;

ALTER TABLE etablissement_menu_items
  ADD CONSTRAINT fk_etablissement_menu_item_parent FOREIGN KEY (parent_id) REFERENCES etablissement_menu_items (id) ON DELETE CASCADE;

-- Les lignes pré-existantes (ancien schéma plat) ont toutes reçu le type par
-- défaut 'module' lors de l'ADD COLUMN ci-dessus, y compris celles qui
-- représentaient en réalité une sous-page connue (sous_page_cle renseigné).
UPDATE etablissement_menu_items SET type = 'sous_page' WHERE sous_page_cle IS NOT NULL AND type = 'module';

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0008_etablissement_menu_items_tree.sql', NOW());

-- [0009_create_admin_audit_logs.sql]
-- Journal d'audit des actions de la plateforme admin.newfarah (création
-- d'établissement, gestion des modules, gestion des comptes administrateurs,
-- connexion/déconnexion) — jusqu'ici aucune trace de ces actions n'existait,
-- contrairement aux modules métier tenant déjà couverts par audit_logs.
CREATE TABLE admin_audit_logs (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  admin_id INT UNSIGNED NULL,
  admin_nom VARCHAR(200) NULL,
  action ENUM('creation', 'modification', 'suppression', 'connexion', 'deconnexion') NOT NULL,
  module VARCHAR(60) NOT NULL,
  entite_id INT UNSIGNED NULL,
  description VARCHAR(255) NOT NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_admin_audit_logs_module (module),
  KEY idx_admin_audit_logs_cree_at (cree_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0009_create_admin_audit_logs.sql', NOW());

-- [0010_add_logo_white_path.sql]
-- Logo blanc utilisé dans les menus/navigation (topbar, sidebar) en
-- complément du logo principal (logo_path) utilisé sur les factures et reçus.
ALTER TABLE etablissements
  ADD COLUMN logo_white_path VARCHAR(255) NULL AFTER logo_path;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0010_add_logo_white_path.sql', NOW());


-- =============================================================================
-- TABLES MÉTIER (TENANT)
-- roles, users, patients, medecins, specialites, rendez_vous, planning_medecin,
-- factures, demandes_laboratoire, demandes_imagerie, machines_imagerie,
-- examens_imagerie, assurances, ententes, categories_entente, hospitalisation,
-- chambres, lits, etages, conges, feries, buanderie, cms, audit_logs…
-- =============================================================================

-- [0001_create_roles.sql]
CREATE TABLE roles (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  code VARCHAR(60) NOT NULL,
  libelle VARCHAR(150) NOT NULL,
  est_administrateur TINYINT(1) NOT NULL DEFAULT 0,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  UNIQUE KEY uniq_roles_code (code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0001_create_roles.sql', NOW());

-- [0002_create_users.sql]
CREATE TABLE users (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  role_id INT UNSIGNED NOT NULL,
  nom VARCHAR(100) NOT NULL,
  prenom VARCHAR(100) NOT NULL,
  email VARCHAR(255) NOT NULL,
  mot_de_passe_hash VARCHAR(255) NOT NULL,
  actif TINYINT(1) NOT NULL DEFAULT 1,
  derniere_connexion_at DATETIME NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  supprime_at DATETIME NULL,
  UNIQUE KEY uniq_users_email (email),
  CONSTRAINT fk_users_role FOREIGN KEY (role_id) REFERENCES roles (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0002_create_users.sql', NOW());

-- [0003_create_role_module_permission.sql]
CREATE TABLE role_module_permission (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  role_id INT UNSIGNED NOT NULL,
  module_code VARCHAR(60) NOT NULL,
  peut_voir TINYINT(1) NOT NULL DEFAULT 0,
  peut_creer TINYINT(1) NOT NULL DEFAULT 0,
  peut_modifier TINYINT(1) NOT NULL DEFAULT 0,
  peut_supprimer TINYINT(1) NOT NULL DEFAULT 0,
  UNIQUE KEY uniq_role_module (role_id, module_code),
  CONSTRAINT fk_role_module_permission_role FOREIGN KEY (role_id) REFERENCES roles (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0003_create_role_module_permission.sql', NOW());

-- [0004_create_specialites.sql]
CREATE TABLE specialites (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  libelle VARCHAR(150) NOT NULL,
  actif TINYINT(1) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0004_create_specialites.sql', NOW());

-- [0005_create_medecins.sql]
CREATE TABLE medecins (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  specialite_id INT UNSIGNED NULL,
  nom VARCHAR(100) NOT NULL,
  prenom VARCHAR(100) NOT NULL,
  telephone VARCHAR(30) NULL,
  email VARCHAR(255) NULL,
  actif TINYINT(1) NOT NULL DEFAULT 1,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT fk_medecins_specialite FOREIGN KEY (specialite_id) REFERENCES specialites (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0005_create_medecins.sql', NOW());

-- [0006_create_patients.sql]
CREATE TABLE patients (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  ipp VARCHAR(50) NOT NULL,
  nom VARCHAR(100) NOT NULL,
  prenom VARCHAR(100) NOT NULL,
  telephone VARCHAR(30) NOT NULL,
  date_naissance DATE NULL,
  sexe ENUM('M','F') NULL,
  email VARCHAR(255) NULL,
  assurance VARCHAR(150) NULL,
  couverture_assurance VARCHAR(150) NULL,
  mot_de_passe_hash VARCHAR(255) NULL,
  photo_path VARCHAR(255) NULL,
  carte_assurance_path VARCHAR(255) NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  supprime_at DATETIME NULL,
  UNIQUE KEY uniq_patients_ipp (ipp),
  KEY idx_patients_telephone (telephone),
  KEY idx_patients_nom_prenom (nom, prenom),
  KEY idx_patients_supprime_at (supprime_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0006_create_patients.sql', NOW());

-- [0007_create_patient_coordonnees.sql]
CREATE TABLE patient_coordonnees (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  patient_id INT UNSIGNED NOT NULL,
  pays_residence VARCHAR(100) NULL,
  ville_residence VARCHAR(100) NULL,
  quartier_residence VARCHAR(100) NULL,
  adresse VARCHAR(255) NULL,
  code_otp VARCHAR(10) NULL,
  code_otp_expire_at DATETIME NULL,
  UNIQUE KEY uniq_patient_coordonnees_patient (patient_id),
  CONSTRAINT fk_patient_coordonnees_patient FOREIGN KEY (patient_id) REFERENCES patients (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0007_create_patient_coordonnees.sql', NOW());

-- [0008_create_rendez_vous.sql]
CREATE TABLE rendez_vous (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  patient_id INT UNSIGNED NOT NULL,
  medecin_id INT UNSIGNED NOT NULL,
  specialite_id INT UNSIGNED NULL,
  date_rdv DATE NOT NULL,
  creneau_debut TIME NOT NULL,
  creneau_fin TIME NOT NULL,
  type_consultation VARCHAR(60) NULL,
  statut ENUM('en_attente','confirme','honore','absent','annule') NOT NULL DEFAULT 'en_attente',
  paiement_effectue TINYINT(1) NOT NULL DEFAULT 0,
  note TEXT NULL,
  sms_envoye TINYINT(1) NOT NULL DEFAULT 0,
  cree_par INT UNSIGNED NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_rendez_vous_date_medecin (date_rdv, medecin_id),
  KEY idx_rendez_vous_patient (patient_id),
  KEY idx_rendez_vous_statut (statut),
  CONSTRAINT fk_rendez_vous_patient FOREIGN KEY (patient_id) REFERENCES patients (id),
  CONSTRAINT fk_rendez_vous_medecin FOREIGN KEY (medecin_id) REFERENCES medecins (id),
  CONSTRAINT fk_rendez_vous_specialite FOREIGN KEY (specialite_id) REFERENCES specialites (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0008_create_rendez_vous.sql', NOW());

-- [0009_create_planning_medecin.sql]
CREATE TABLE planning_medecin (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  medecin_id INT UNSIGNED NOT NULL,
  jour_semaine TINYINT UNSIGNED NOT NULL COMMENT '1=lundi ... 7=dimanche',
  heure_debut TIME NOT NULL,
  heure_fin TIME NOT NULL,
  duree_creneau_minutes SMALLINT UNSIGNED NOT NULL DEFAULT 15,
  KEY idx_planning_medecin_jour (medecin_id, jour_semaine),
  CONSTRAINT fk_planning_medecin_medecin FOREIGN KEY (medecin_id) REFERENCES medecins (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0009_create_planning_medecin.sql', NOW());

-- [0010_add_patients_listing_index.sql]
-- Trouvé par test de charge (50 000 lignes) : la liste paginée par défaut
-- (WHERE supprime_at IS NULL ORDER BY nom, prenom) déclenchait un filesort
-- sur ~25 000 lignes avant chaque LIMIT/OFFSET (~186ms sur une page profonde).
-- Cet index composite couvre le filtre ET le tri en une seule passe.
ALTER TABLE patients ADD INDEX idx_patients_listing (supprime_at, nom, prenom);

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0010_add_patients_listing_index.sql', NOW());

-- [0011_add_rendez_vous_listing_index.sql]
-- Trouvé par test de charge (30 000 lignes) : la liste de rendez-vous sans
-- filtre déclenchait un filesort complet (aucun index utilisé, ~120ms par page).
ALTER TABLE rendez_vous ADD INDEX idx_rendez_vous_listing (date_rdv, creneau_debut);

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0011_add_rendez_vous_listing_index.sql', NOW());

-- [0012_create_factures.sql]
CREATE TABLE factures (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  patient_id INT UNSIGNED NOT NULL,
  rendez_vous_id INT UNSIGNED NULL,
  montant DECIMAL(10,2) NOT NULL,
  montant_paye DECIMAL(10,2) NOT NULL DEFAULT 0,
  mode_paiement VARCHAR(30) NULL,
  statut ENUM('en_attente','payee','annulee') NOT NULL DEFAULT 'en_attente',
  description VARCHAR(255) NULL,
  cree_par INT UNSIGNED NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_factures_patient (patient_id),
  KEY idx_factures_statut (statut),
  CONSTRAINT fk_factures_patient FOREIGN KEY (patient_id) REFERENCES patients (id),
  CONSTRAINT fk_factures_rendez_vous FOREIGN KEY (rendez_vous_id) REFERENCES rendez_vous (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0012_create_factures.sql', NOW());

-- [0013_create_examens.sql]
CREATE TABLE examens (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  libelle VARCHAR(150) NOT NULL,
  prix DECIMAL(10,2) NULL,
  actif TINYINT(1) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0013_create_examens.sql', NOW());

-- [0014_create_demandes_laboratoire.sql]
-- Pas de planning/créneau ni de détection de conflit ici (contrairement à
-- rendez_vous) : un laboratoire n'est pas contraint à "un patient à la fois"
-- comme un médecin, donc cette contrainte de ressource ne s'applique pas.
CREATE TABLE demandes_laboratoire (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  patient_id INT UNSIGNED NOT NULL,
  examen_id INT UNSIGNED NOT NULL,
  date_demande DATE NOT NULL,
  statut ENUM('en_attente','preleve','resultat_disponible','annule') NOT NULL DEFAULT 'en_attente',
  resultat_path VARCHAR(255) NULL,
  note VARCHAR(255) NULL,
  cree_par INT UNSIGNED NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_demandes_laboratoire_patient (patient_id),
  KEY idx_demandes_laboratoire_statut (statut, date_demande),
  CONSTRAINT fk_demandes_laboratoire_patient FOREIGN KEY (patient_id) REFERENCES patients (id),
  CONSTRAINT fk_demandes_laboratoire_examen FOREIGN KEY (examen_id) REFERENCES examens (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0014_create_demandes_laboratoire.sql', NOW());

-- [0015_create_etages.sql]
CREATE TABLE etages (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  libelle VARCHAR(100) NOT NULL,
  actif TINYINT(1) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0015_create_etages.sql', NOW());

-- [0016_create_chambres.sql]
CREATE TABLE chambres (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  etage_id INT UNSIGNED NULL,
  numero VARCHAR(20) NOT NULL,
  type ENUM('standard','vip','conciergerie') NOT NULL DEFAULT 'standard',
  prix_jour DECIMAL(10,2) NULL,
  statut ENUM('libre','occupee','maintenance') NOT NULL DEFAULT 'libre',
  UNIQUE KEY uniq_chambres_numero (numero),
  KEY idx_chambres_statut (statut),
  CONSTRAINT fk_chambres_etage FOREIGN KEY (etage_id) REFERENCES etages (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0016_create_chambres.sql', NOW());

-- [0017_create_hospitalisations.sql]
CREATE TABLE hospitalisations (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  patient_id INT UNSIGNED NOT NULL,
  chambre_id INT UNSIGNED NOT NULL,
  date_admission DATETIME NOT NULL,
  date_sortie DATETIME NULL,
  motif VARCHAR(255) NULL,
  statut ENUM('en_cours','terminee') NOT NULL DEFAULT 'en_cours',
  cree_par INT UNSIGNED NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_hospitalisations_patient_statut (patient_id, statut),
  KEY idx_hospitalisations_chambre_statut (chambre_id, statut),
  CONSTRAINT fk_hospitalisations_patient FOREIGN KEY (patient_id) REFERENCES patients (id),
  CONSTRAINT fk_hospitalisations_chambre FOREIGN KEY (chambre_id) REFERENCES chambres (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0017_create_hospitalisations.sql', NOW());

-- [0018_create_assurances.sql]
CREATE TABLE assurances (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  nom VARCHAR(150) NOT NULL,
  actif TINYINT(1) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0018_create_assurances.sql', NOW());

-- [0019_create_ententes.sql]
CREATE TABLE ententes (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  patient_id INT UNSIGNED NOT NULL,
  assurance_id INT UNSIGNED NOT NULL,
  montant_demande DECIMAL(10,2) NOT NULL,
  pourcentage_couverture DECIMAL(5,2) NULL,
  numero_entente VARCHAR(100) NULL,
  statut ENUM('en_attente','approuvee','rejetee') NOT NULL DEFAULT 'en_attente',
  document_path VARCHAR(255) NULL,
  motif_rejet VARCHAR(255) NULL,
  cree_par INT UNSIGNED NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_ententes_patient (patient_id),
  KEY idx_ententes_statut (statut, cree_at),
  CONSTRAINT fk_ententes_patient FOREIGN KEY (patient_id) REFERENCES patients (id),
  CONSTRAINT fk_ententes_assurance FOREIGN KEY (assurance_id) REFERENCES assurances (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0019_create_ententes.sql', NOW());

-- [0020_create_machines_imagerie.sql]
CREATE TABLE machines_imagerie (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  libelle VARCHAR(150) NOT NULL,
  type ENUM('radiologie','scanner','irm','echographie') NOT NULL DEFAULT 'radiologie',
  actif TINYINT(1) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0020_create_machines_imagerie.sql', NOW());

-- [0021_create_examens_imagerie.sql]
CREATE TABLE examens_imagerie (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  machine_id INT UNSIGNED NOT NULL,
  libelle VARCHAR(150) NOT NULL,
  prix DECIMAL(10,2) NULL,
  actif TINYINT(1) NOT NULL DEFAULT 1,
  CONSTRAINT fk_examens_imagerie_machine FOREIGN KEY (machine_id) REFERENCES machines_imagerie (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0021_create_examens_imagerie.sql', NOW());

-- [0022_create_demandes_imagerie.sql]
-- accession_number : identifiant unique transmis aux machines d'imagerie via
-- HL7 (champ standard ACC# des messages ORM/ORU) pour relier une demande au
-- compte-rendu renvoyé par la modalité.
CREATE TABLE demandes_imagerie (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  patient_id INT UNSIGNED NOT NULL,
  examen_imagerie_id INT UNSIGNED NOT NULL,
  medecin_prescripteur_id INT UNSIGNED NULL,
  accession_number VARCHAR(30) NOT NULL,
  date_demande DATE NOT NULL,
  statut ENUM('demandee','en_cours','compte_rendu_disponible','annulee') NOT NULL DEFAULT 'demandee',
  compte_rendu_path VARCHAR(255) NULL,
  note VARCHAR(255) NULL,
  cree_par INT UNSIGNED NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  UNIQUE KEY uniq_demandes_imagerie_accession (accession_number),
  KEY idx_demandes_imagerie_patient (patient_id),
  KEY idx_demandes_imagerie_statut (statut, date_demande),
  CONSTRAINT fk_demandes_imagerie_patient FOREIGN KEY (patient_id) REFERENCES patients (id),
  CONSTRAINT fk_demandes_imagerie_examen FOREIGN KEY (examen_imagerie_id) REFERENCES examens_imagerie (id),
  CONSTRAINT fk_demandes_imagerie_medecin FOREIGN KEY (medecin_prescripteur_id) REFERENCES medecins (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0022_create_demandes_imagerie.sql', NOW());

-- [0023_create_categories_actualites.sql]
CREATE TABLE categories_actualites (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  libelle VARCHAR(100) NOT NULL,
  actif TINYINT(1) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0023_create_categories_actualites.sql', NOW());

-- [0024_create_actualites.sql]
CREATE TABLE actualites (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  categorie_id INT UNSIGNED NULL,
  titre VARCHAR(200) NOT NULL,
  contenu TEXT NOT NULL,
  image_path VARCHAR(255) NULL,
  statut ENUM('brouillon','publie') NOT NULL DEFAULT 'brouillon',
  publie_at DATETIME NULL,
  cree_par INT UNSIGNED NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_actualites_statut (statut, cree_at),
  CONSTRAINT fk_actualites_categorie FOREIGN KEY (categorie_id) REFERENCES categories_actualites (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0024_create_actualites.sql', NOW());

-- [0025_create_faq.sql]
CREATE TABLE faq (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  question VARCHAR(255) NOT NULL,
  reponse TEXT NOT NULL,
  ordre INT NOT NULL DEFAULT 0,
  actif TINYINT(1) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0025_create_faq.sql', NOW());

-- [0026_create_articles_buanderie.sql]
CREATE TABLE articles_buanderie (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  libelle VARCHAR(100) NOT NULL,
  actif TINYINT(1) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0026_create_articles_buanderie.sql', NOW());

-- [0027_create_mouvements_buanderie.sql]
-- Un mouvement représente un cycle complet : linge sale envoyé (sortie) puis
-- linge propre retourné (entree), suivi en quantité plutôt qu'à l'unité par
-- code-barres (simplification volontaire par rapport au legacy).
CREATE TABLE mouvements_buanderie (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  article_id INT UNSIGNED NOT NULL,
  quantite INT UNSIGNED NOT NULL,
  service_origine VARCHAR(150) NOT NULL,
  date_sortie DATE NOT NULL,
  date_retour DATE NULL,
  statut ENUM('en_circulation','retourne') NOT NULL DEFAULT 'en_circulation',
  note VARCHAR(255) NULL,
  cree_par INT UNSIGNED NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_mouvements_buanderie_statut (statut, date_sortie),
  CONSTRAINT fk_mouvements_buanderie_article FOREIGN KEY (article_id) REFERENCES articles_buanderie (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0027_create_mouvements_buanderie.sql', NOW());

-- [0028_create_paiements.sql]
-- Journal horodaté de chaque encaissement (auparavant, factures.montant_paye
-- n'était qu'un total cumulé sans trace de quand chaque paiement a eu lieu,
-- ce qui empêchait un vrai audit de caisse ou un graphique de revenus par jour).
CREATE TABLE paiements (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  facture_id INT UNSIGNED NOT NULL,
  montant DECIMAL(10,2) NOT NULL,
  mode_paiement VARCHAR(30) NOT NULL,
  cree_par INT UNSIGNED NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_paiements_facture (facture_id),
  KEY idx_paiements_cree_at (cree_at),
  CONSTRAINT fk_paiements_facture FOREIGN KEY (facture_id) REFERENCES factures (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0028_create_paiements.sql', NOW());

-- [0029_add_index_medecins_listing.sql]
-- Liste des médecins triée par nom/prénom : sans cet index, MySQL fait un
-- filesort sur la table entière dès quelques milliers de lignes (mesuré par
-- test de charge avec 5000 médecins).
CREATE INDEX idx_medecins_listing ON medecins (nom, prenom);

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0029_add_index_medecins_listing.sql', NOW());

-- [0030_add_index_users_listing.sql]
-- Même problème que pour patients (cf. idx_patients_listing) : la liste des
-- utilisateurs actifs triée par nom/prénom déclenche un filesort sur gros
-- volume sans index composite couvrant le filtre supprime_at IS NULL.
CREATE INDEX idx_users_listing ON users (supprime_at, nom, prenom);

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0030_add_index_users_listing.sql', NOW());

-- [0031_add_index_factures_listing.sql]
-- Mesuré par test de charge (50000 factures) : la liste paginée, triée par
-- date de création décroissante, déclenche un filesort que l'index existant
-- sur statut seul (idx_factures_statut) ne couvre pas.
-- idx_factures_cree_at sert le cas non filtré ; idx_factures_statut_cree_at
-- sert le cas filtré par statut (remplace idx_factures_statut, devenu redondant).
CREATE INDEX idx_factures_cree_at ON factures (cree_at);
CREATE INDEX idx_factures_statut_cree_at ON factures (statut, cree_at);
DROP INDEX idx_factures_statut ON factures;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0031_add_index_factures_listing.sql', NOW());

-- [0032_alter_chambres_numero_width.sql]
-- VARCHAR(20) était trop court pour les numéros générés par la migration
-- legacy ("Libellé (legacy #123)", utilisé pour garantir l'unicité face à de
-- vrais doublons de libelle_chambre dans my_farah.sql, ex. plusieurs "CH").
ALTER TABLE chambres MODIFY numero VARCHAR(60) NOT NULL;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0032_alter_chambres_numero_width.sql', NOW());

-- [0033_add_patients_statut_assure.sql]
-- Champs manquants au formulaire patient (task.txt) : statut régulier/VIP et
-- indicateur explicite "assuré" (jusqu'ici déduit implicitement de la
-- présence du champ libre `assurance`, désormais une vraie case à cocher).
ALTER TABLE patients
  ADD COLUMN statut ENUM('regulier','vip') NOT NULL DEFAULT 'regulier' AFTER prenom,
  ADD COLUMN assure TINYINT(1) NOT NULL DEFAULT 0 AFTER sexe;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0033_add_patients_statut_assure.sql', NOW());

-- [0034_medecins_statut_consultation_photo.sql]
-- Champs manquants au formulaire médecin (task.txt) : montant et durée de
-- consultation, photo, et un vrai statut à 3 états (remplace le booléen actif
-- qui ne permettait pas de distinguer bloqué / en congé). supprime_at permet
-- un "supprimer" sans casser l'intégrité référentielle avec les rendez-vous
-- et plannings existants (même schéma de suppression douce que `patients`).
ALTER TABLE medecins
  ADD COLUMN photo_path VARCHAR(255) NULL AFTER prenom,
  ADD COLUMN montant_consultation DECIMAL(10,2) NULL AFTER email,
  ADD COLUMN temps_consultation_minutes SMALLINT UNSIGNED NULL DEFAULT 15 AFTER montant_consultation,
  ADD COLUMN statut ENUM('actif','bloque','en_conge') NOT NULL DEFAULT 'actif' AFTER temps_consultation_minutes,
  ADD COLUMN supprime_at DATETIME NULL AFTER cree_at;

UPDATE medecins SET statut = IF(actif = 1, 'actif', 'bloque');

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0034_medecins_statut_consultation_photo.sql', NOW());

-- [0035_create_medecin_specialite.sql]
-- Un médecin peut avoir plusieurs spécialités (task.txt) : table pivot,
-- backfillée depuis l'ancienne colonne medecins.specialite_id (conservée
-- pour compatibilité — elle représente désormais la spécialité "principale").
CREATE TABLE medecin_specialite (
  medecin_id INT UNSIGNED NOT NULL,
  specialite_id INT UNSIGNED NOT NULL,
  PRIMARY KEY (medecin_id, specialite_id),
  CONSTRAINT fk_medecin_specialite_medecin FOREIGN KEY (medecin_id) REFERENCES medecins (id) ON DELETE CASCADE,
  CONSTRAINT fk_medecin_specialite_specialite FOREIGN KEY (specialite_id) REFERENCES specialites (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO medecin_specialite (medecin_id, specialite_id)
SELECT id, specialite_id FROM medecins WHERE specialite_id IS NOT NULL;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0035_create_medecin_specialite.sql', NOW());

-- [0036_create_salles.sql]
-- Salles de consultation (distinctes des chambres d'hospitalisation),
-- nécessaires au filtre "Salles" de la liste de travail (task.txt).
CREATE TABLE salles (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  libelle VARCHAR(100) NOT NULL,
  actif TINYINT(1) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0036_create_salles.sql', NOW());

-- [0037_add_specialite_salle_to_planning_and_rdv.sql]
-- Planning par spécialité (un médecin peut avoir plusieurs plannings selon
-- sa spécialité du moment, task.txt) + salle de consultation associée,
-- propagée au rendez-vous au moment de la réservation.
ALTER TABLE planning_medecin
  ADD COLUMN specialite_id INT UNSIGNED NULL AFTER medecin_id,
  ADD COLUMN salle_id INT UNSIGNED NULL AFTER duree_creneau_minutes,
  ADD CONSTRAINT fk_planning_medecin_specialite FOREIGN KEY (specialite_id) REFERENCES specialites (id),
  ADD CONSTRAINT fk_planning_medecin_salle FOREIGN KEY (salle_id) REFERENCES salles (id);

ALTER TABLE rendez_vous
  ADD COLUMN salle_id INT UNSIGNED NULL AFTER specialite_id,
  ADD COLUMN type_rdv ENUM('sur_place','en_ligne') NOT NULL DEFAULT 'sur_place' AFTER salle_id,
  ADD CONSTRAINT fk_rendez_vous_salle FOREIGN KEY (salle_id) REFERENCES salles (id);

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0037_add_specialite_salle_to_planning_and_rdv.sql', NOW());

-- [0038_add_users_session_token.sql]
-- Empêche la double connexion simultanée d'un même compte (task.txt) : un
-- jeton unique est régénéré à chaque login et comparé à chaque requête
-- authentifiée ; toute session encore active ailleurs portant l'ancien
-- jeton est ainsi invalidée.
ALTER TABLE users
  ADD COLUMN session_token VARCHAR(64) NULL AFTER mot_de_passe_hash;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0038_add_users_session_token.sql', NOW());

-- [0039_add_patients_assurance_id_dossier_medical.sql]
-- task.txt : champ assurance en menu déroulant (référentiel assurances déjà
-- utilisé par le module Ententes) + section "données complémentaires" et
-- section "dossier médical" structurées sur la fiche patient. L'ancienne
-- colonne `assurance` (texte libre) est conservée (pas de perte de données
-- existantes) mais n'est plus utilisée par l'application — assurance_id la
-- remplace pour les nouvelles saisies.
ALTER TABLE patients
  ADD COLUMN assurance_id INT UNSIGNED NULL AFTER assurance,
  ADD COLUMN taille_cm SMALLINT UNSIGNED NULL AFTER couverture_assurance,
  ADD COLUMN poids_kg DECIMAL(5,2) UNSIGNED NULL AFTER taille_cm,
  ADD COLUMN groupe_sanguin ENUM('A+','A-','B+','B-','AB+','AB-','O+','O-') NULL AFTER poids_kg,
  ADD COLUMN antecedents TEXT NULL AFTER groupe_sanguin,
  ADD COLUMN allergies TEXT NULL AFTER antecedents,
  ADD COLUMN traitements_en_cours TEXT NULL AFTER allergies,
  ADD COLUMN notes_medicales TEXT NULL AFTER traitements_en_cours,
  ADD CONSTRAINT fk_patients_assurance FOREIGN KEY (assurance_id) REFERENCES assurances (id);

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0039_add_patients_assurance_id_dossier_medical.sql', NOW());

-- [0040_add_medecins_conge_details.sql]
-- task.txt : type de congé + période (début/fin) du médecin, pour permettre
-- le retour automatique au statut actif une fois la date de fin dépassée
-- (voir MedecinRepository::releaseExpiredConges()).
ALTER TABLE medecins
  ADD COLUMN type_conge VARCHAR(60) NULL AFTER statut,
  ADD COLUMN conge_debut DATE NULL AFTER type_conge,
  ADD COLUMN conge_fin DATE NULL AFTER conge_debut;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0040_add_medecins_conge_details.sql', NOW());

-- [0041_add_rendez_vous_accueil_annulation.sql]
-- task.txt : détails du rendez-vous — motif d'annulation, et suivi
-- d'accueil (heure d'arrivée, heure de prise en charge, validation de présence).
-- Ajoute aussi supprime_at : "aucune suppression ne doit etre effectuée" —
-- remplace le vrai DELETE de RendezVousRepository::delete() par le même
-- mécanisme de suppression douce déjà utilisé pour patients/medecins.
ALTER TABLE rendez_vous
  ADD COLUMN motif_annulation TEXT NULL AFTER statut,
  ADD COLUMN heure_arrivee TIME NULL AFTER motif_annulation,
  ADD COLUMN heure_prise_en_charge TIME NULL AFTER heure_arrivee,
  ADD COLUMN presence_validee TINYINT(1) NOT NULL DEFAULT 0 AFTER heure_prise_en_charge,
  ADD COLUMN supprime_at DATETIME NULL AFTER cree_at;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0041_add_rendez_vous_accueil_annulation.sql', NOW());

-- [0042_create_audit_logs.sql]
-- task.txt : journal d'audit de toutes les actions (création, modification,
-- suppression) effectuées par les utilisateurs connectés, sur tous les
-- modules — user_nom est dénormalisé (recopié au moment de l'action) pour
-- que le journal reste lisible même si le compte est ensuite désactivé/supprimé.
CREATE TABLE audit_logs (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  user_id INT UNSIGNED NULL,
  user_nom VARCHAR(200) NULL,
  action ENUM('creation', 'modification', 'suppression') NOT NULL,
  module VARCHAR(60) NOT NULL,
  entite_id INT UNSIGNED NULL,
  description VARCHAR(255) NOT NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_audit_logs_module (module),
  KEY idx_audit_logs_cree_at (cree_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0042_create_audit_logs.sql', NOW());

-- [0043_add_users_doit_changer_mot_de_passe.sql]
ALTER TABLE users
    ADD COLUMN doit_changer_mot_de_passe TINYINT(1) NOT NULL DEFAULT 0 AFTER mot_de_passe_hash;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0043_add_users_doit_changer_mot_de_passe.sql', NOW());

-- [0044_seed_roles_types_utilisateur.sql]
INSERT IGNORE INTO roles (code, libelle, est_administrateur) VALUES
    ('medecin', 'Médecin', 0),
    ('conciergerie', 'Conciergerie', 0),
    ('secretaire', 'Secrétaire', 0),
    ('comptabilite', 'Comptabilité', 0),
    ('qualite', 'Qualité', 0),
    ('standard', 'Standard', 0),
    ('laboratoire', 'Laboratoire', 0),
    ('radiologie', 'Radiologie', 0);

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0044_seed_roles_types_utilisateur.sql', NOW());

-- [0045_create_feries.sql]
CREATE TABLE feries (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    nom VARCHAR(150) NOT NULL,
    frequence ENUM('unique_cette_annee', 'unique_variable', 'recurrent_fixe') NOT NULL DEFAULT 'recurrent_fixe',
    date_ferie DATE NOT NULL,
    actif TINYINT(1) NOT NULL DEFAULT 1,
    supprime_at DATETIME NULL,
    cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    KEY idx_feries_date (date_ferie)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0045_create_feries.sql', NOW());

-- [0046_create_bilans.sql]
CREATE TABLE categories_bilan (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    libelle VARCHAR(150) NOT NULL,
    actif TINYINT(1) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE bilans (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    categorie_id INT UNSIGNED NULL,
    titre VARCHAR(200) NOT NULL,
    description_1 TEXT NULL,
    description_2 TEXT NULL,
    description_3 TEXT NULL,
    actif TINYINT(1) NOT NULL DEFAULT 1,
    supprime_at DATETIME NULL,
    cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT fk_bilans_categorie FOREIGN KEY (categorie_id) REFERENCES categories_bilan (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0046_create_bilans.sql', NOW());

-- [0047_add_assurances_categorie_lien.sql]
CREATE TABLE categories_assurance (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    libelle VARCHAR(150) NOT NULL,
    actif TINYINT(1) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

ALTER TABLE assurances
    ADD COLUMN categorie_assurance_id INT UNSIGNED NULL AFTER nom,
    ADD COLUMN lien VARCHAR(255) NULL AFTER categorie_assurance_id,
    ADD CONSTRAINT fk_assurances_categorie FOREIGN KEY (categorie_assurance_id) REFERENCES categories_assurance (id);

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0047_add_assurances_categorie_lien.sql', NOW());

-- [0048_create_hospitalisation_lits_services.sql]
CREATE TABLE services_hospitalisation (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    libelle VARCHAR(150) NOT NULL,
    actif TINYINT(1) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE types_lit (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    libelle VARCHAR(150) NOT NULL,
    actif TINYINT(1) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE lits (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    chambre_id INT UNSIGNED NOT NULL,
    type_lit_id INT UNSIGNED NULL,
    libelle VARCHAR(100) NOT NULL,
    prix DECIMAL(10,2) NULL,
    montant DECIMAL(10,2) NULL,
    statut ENUM('libre', 'occupe') NOT NULL DEFAULT 'libre',
    description TEXT NULL,
    supprime_at DATETIME NULL,
    cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT fk_lits_chambre FOREIGN KEY (chambre_id) REFERENCES chambres (id),
    CONSTRAINT fk_lits_type FOREIGN KEY (type_lit_id) REFERENCES types_lit (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

ALTER TABLE chambres
    ADD COLUMN description TEXT NULL AFTER prix_jour;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0048_create_hospitalisation_lits_services.sql', NOW());

-- [0049_add_hospitalisations_admission_sortie_details.sql]
ALTER TABLE hospitalisations
    ADD COLUMN service_hospitalisation_id INT UNSIGNED NULL AFTER chambre_id,
    ADD COLUMN specialite_id INT UNSIGNED NULL AFTER service_hospitalisation_id,
    ADD COLUMN medecin_prescripteur_id INT UNSIGNED NULL AFTER specialite_id,
    ADD COLUMN lit_accompagnateur_id INT UNSIGNED NULL AFTER medecin_prescripteur_id,
    ADD COLUMN fiche_admission_path VARCHAR(255) NULL AFTER motif,
    ADD COLUMN date_entree DATE NULL AFTER fiche_admission_path,
    ADD COLUMN heure_entree TIME NULL AFTER date_entree,
    ADD COLUMN notes_sortie TEXT NULL AFTER date_sortie,
    ADD COLUMN reponse_appel VARCHAR(100) NULL AFTER notes_sortie,
    ADD COLUMN details_reponse_appel TEXT NULL AFTER reponse_appel,
    ADD COLUMN date_heure_appel DATETIME NULL AFTER details_reponse_appel,
    ADD COLUMN nouveau_rdv_souhaite TINYINT(1) NOT NULL DEFAULT 0 AFTER date_heure_appel,
    ADD COLUMN prochain_rendez_vous_date DATE NULL AFTER nouveau_rdv_souhaite,
    ADD CONSTRAINT fk_hospitalisations_service FOREIGN KEY (service_hospitalisation_id) REFERENCES services_hospitalisation (id),
    ADD CONSTRAINT fk_hospitalisations_specialite FOREIGN KEY (specialite_id) REFERENCES specialites (id),
    ADD CONSTRAINT fk_hospitalisations_medecin FOREIGN KEY (medecin_prescripteur_id) REFERENCES medecins (id),
    ADD CONSTRAINT fk_hospitalisations_lit FOREIGN KEY (lit_accompagnateur_id) REFERENCES lits (id);

ALTER TABLE factures
    ADD COLUMN hospitalisation_id INT UNSIGNED NULL AFTER rendez_vous_id,
    ADD CONSTRAINT fk_factures_hospitalisation FOREIGN KEY (hospitalisation_id) REFERENCES hospitalisations (id);

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0049_add_hospitalisations_admission_sortie_details.sql', NOW());

-- [0050_create_medecins_prescripteurs_types_machine.sql]
CREATE TABLE medecins_prescripteurs (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    nom VARCHAR(100) NOT NULL,
    prenom VARCHAR(100) NOT NULL,
    etablissement VARCHAR(150) NULL,
    specialite_id INT UNSIGNED NULL,
    telephone VARCHAR(30) NULL,
    photo_path VARCHAR(255) NULL,
    actif TINYINT(1) NOT NULL DEFAULT 1,
    supprime_at DATETIME NULL,
    cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT fk_medecins_prescripteurs_specialite FOREIGN KEY (specialite_id) REFERENCES specialites (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE types_machine_imagerie (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    libelle VARCHAR(150) NOT NULL,
    actif TINYINT(1) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO types_machine_imagerie (libelle) VALUES ('Radiologie'), ('Scanner'), ('IRM'), ('Échographie');

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0050_create_medecins_prescripteurs_types_machine.sql', NOW());

-- [0051_enrich_machines_examens_imagerie.sql]
ALTER TABLE machines_imagerie
    ADD COLUMN type_machine_id INT UNSIGNED NULL AFTER type,
    ADD COLUMN description TEXT NULL,
    ADD COLUMN aetitle VARCHAR(60) NULL,
    ADD COLUMN modele VARCHAR(100) NULL,
    ADD COLUMN numero_serie VARCHAR(100) NULL,
    ADD COLUMN code_machine VARCHAR(60) NULL,
    ADD COLUMN photo_path VARCHAR(255) NULL,
    ADD COLUMN couleur VARCHAR(20) NULL,
    ADD COLUMN heure_ouverture TIME NOT NULL DEFAULT '08:00:00',
    ADD COLUMN heure_fermeture TIME NOT NULL DEFAULT '18:00:00';

UPDATE machines_imagerie SET type_machine_id = CASE type
    WHEN 'radiologie' THEN (SELECT id FROM types_machine_imagerie WHERE libelle = 'Radiologie')
    WHEN 'scanner' THEN (SELECT id FROM types_machine_imagerie WHERE libelle = 'Scanner')
    WHEN 'irm' THEN (SELECT id FROM types_machine_imagerie WHERE libelle = 'IRM')
    WHEN 'echographie' THEN (SELECT id FROM types_machine_imagerie WHERE libelle = 'Échographie')
    ELSE NULL
END;

ALTER TABLE machines_imagerie
    DROP COLUMN type,
    ADD CONSTRAINT fk_machines_imagerie_type FOREIGN KEY (type_machine_id) REFERENCES types_machine_imagerie (id);

ALTER TABLE examens_imagerie
    ADD COLUMN code_procedure VARCHAR(60) NULL,
    ADD COLUMN modalite_procedure VARCHAR(60) NULL,
    ADD COLUMN duree_minutes SMALLINT UNSIGNED NOT NULL DEFAULT 15,
    ADD COLUMN temps_interpretation_minutes SMALLINT UNSIGNED NULL,
    ADD COLUMN preparation_avant TEXT NULL;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0051_enrich_machines_examens_imagerie.sql', NOW());

-- [0052_enrich_demandes_imagerie_ententes.sql]
ALTER TABLE demandes_imagerie
    ADD COLUMN medecin_prescripteur_externe_id INT UNSIGNED NULL AFTER medecin_prescripteur_id,
    ADD COLUMN provenance VARCHAR(100) NULL,
    ADD COLUMN type_passage VARCHAR(60) NOT NULL DEFAULT 'nouveau_rdv',
    ADD COLUMN photo_bulletin_path VARCHAR(255) NULL,
    ADD COLUMN renseignement_clinique TEXT NULL,
    ADD COLUMN mode ENUM('rendez_vous', 'insertion', 'rattrapage') NOT NULL DEFAULT 'rendez_vous',
    ADD COLUMN creneau_debut TIME NULL,
    ADD COLUMN creneau_fin TIME NULL,
    ADD CONSTRAINT fk_demandes_imagerie_medecin_externe FOREIGN KEY (medecin_prescripteur_externe_id) REFERENCES medecins_prescripteurs (id);

ALTER TABLE ententes
    ADD COLUMN demande_imagerie_id INT UNSIGNED NULL AFTER assurance_id,
    ADD CONSTRAINT fk_ententes_demande_imagerie FOREIGN KEY (demande_imagerie_id) REFERENCES demandes_imagerie (id);

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0052_enrich_demandes_imagerie_ententes.sql', NOW());

-- [0053_seed_default_role_permissions.sql]
-- Les rôles "métier" seedés en 0044 (conciergerie, secretaire, comptabilite,
-- qualite, standard, laboratoire, radiologie, medecin) étaient créés sans
-- aucune permission : un utilisateur affecté à l'un d'eux n'avait accès à
-- rien tant qu'un administrateur ne configurait pas chaque module à la main.
-- INSERT IGNORE : n'écrase jamais une permission déjà personnalisée par un
-- administrateur entre-temps (clé unique role_id+module_code).

INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'rendezvous', 1, 1, 1, 0 FROM roles WHERE code = 'medecin';
INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'medecins', 1, 0, 0, 0 FROM roles WHERE code = 'medecin';
INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'patients', 1, 0, 0, 0 FROM roles WHERE code = 'medecin';
INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'laboratoire', 1, 0, 0, 0 FROM roles WHERE code = 'medecin';
INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'imagerie', 1, 0, 0, 0 FROM roles WHERE code = 'medecin';

INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'patients', 1, 1, 1, 0 FROM roles WHERE code = 'secretaire';
INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'rendezvous', 1, 1, 1, 0 FROM roles WHERE code = 'secretaire';
INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'facturation', 1, 1, 0, 0 FROM roles WHERE code = 'secretaire';
INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'feries', 1, 0, 0, 0 FROM roles WHERE code = 'secretaire';

INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'facturation', 1, 1, 1, 0 FROM roles WHERE code = 'comptabilite';
INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'ententes', 1, 1, 1, 0 FROM roles WHERE code = 'comptabilite';
INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'patients', 1, 0, 0, 0 FROM roles WHERE code = 'comptabilite';

INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'patients', 1, 0, 0, 0 FROM roles WHERE code = 'qualite';
INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'rendezvous', 1, 0, 0, 0 FROM roles WHERE code = 'qualite';
INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'hospitalisation', 1, 0, 0, 0 FROM roles WHERE code = 'qualite';
INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'laboratoire', 1, 0, 0, 0 FROM roles WHERE code = 'qualite';
INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'imagerie', 1, 0, 0, 0 FROM roles WHERE code = 'qualite';

INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'patients', 1, 0, 0, 0 FROM roles WHERE code = 'standard';
INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'rendezvous', 1, 0, 0, 0 FROM roles WHERE code = 'standard';

INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'laboratoire', 1, 1, 1, 0 FROM roles WHERE code = 'laboratoire';
INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'patients', 1, 0, 0, 0 FROM roles WHERE code = 'laboratoire';

INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'imagerie', 1, 1, 1, 0 FROM roles WHERE code = 'radiologie';
INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'patients', 1, 0, 0, 0 FROM roles WHERE code = 'radiologie';

INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'hospitalisation', 1, 1, 1, 0 FROM roles WHERE code = 'conciergerie';
INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'patients', 1, 0, 0, 0 FROM roles WHERE code = 'conciergerie';
INSERT IGNORE INTO role_module_permission (role_id, module_code, peut_voir, peut_creer, peut_modifier, peut_supprimer)
SELECT id, 'buanderie', 1, 1, 1, 0 FROM roles WHERE code = 'conciergerie';

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0053_seed_default_role_permissions.sql', NOW());

-- [0054_add_mouvements_buanderie_hospitalisation.sql]
ALTER TABLE mouvements_buanderie
    ADD COLUMN hospitalisation_id INT UNSIGNED NULL AFTER service_origine,
    ADD CONSTRAINT fk_mouvements_buanderie_hospitalisation FOREIGN KEY (hospitalisation_id) REFERENCES hospitalisations (id);

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0054_add_mouvements_buanderie_hospitalisation.sql', NOW());

-- [0055_widen_audit_logs_action.sql]
-- Élargit audit_logs.action pour couvrir la connexion/déconnexion des
-- utilisateurs tenant, jusqu'ici absentes du journal (seules les actions
-- création/modification/suppression sur les modules métier y étaient
-- consignées).
ALTER TABLE audit_logs
  MODIFY action ENUM('creation', 'modification', 'suppression', 'connexion', 'deconnexion') NOT NULL;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0055_widen_audit_logs_action.sql', NOW());

-- [0056_add_factures_demande_imagerie_laboratoire.sql]
-- Lien optionnel entre une facture et la demande d'imagerie/laboratoire qui
-- l'a générée automatiquement (examen avec un prix renseigné au catalogue),
-- sur le même modèle que factures.hospitalisation_id (0049).
ALTER TABLE factures
    ADD COLUMN demande_imagerie_id INT UNSIGNED NULL AFTER hospitalisation_id,
    ADD COLUMN demande_laboratoire_id INT UNSIGNED NULL AFTER demande_imagerie_id,
    ADD CONSTRAINT fk_factures_demande_imagerie FOREIGN KEY (demande_imagerie_id) REFERENCES demandes_imagerie (id),
    ADD CONSTRAINT fk_factures_demande_laboratoire FOREIGN KEY (demande_laboratoire_id) REFERENCES demandes_laboratoire (id);

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0056_add_factures_demande_imagerie_laboratoire.sql', NOW());

-- [0057_create_types_consultation.sql]
-- Catalogue des types de consultation (nom, prix, temps de consultation),
-- utilisé par le planning des médecins pour déterminer automatiquement la
-- durée des créneaux de rendez-vous (task.txt : "les créneaux horaires se
-- calculeront en fonction du temps de consultation du type de consultation").
CREATE TABLE types_consultation (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  nom VARCHAR(150) NOT NULL,
  prix DECIMAL(10,2) NULL,
  temps_consultation_minutes SMALLINT UNSIGNED NOT NULL DEFAULT 15,
  actif TINYINT(1) NOT NULL DEFAULT 1,
  supprime_at DATETIME NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0057_create_types_consultation.sql', NOW());

-- [0058_add_type_consultation_to_planning_medecin.sql]
-- Lien optionnel entre une plage de planning et son type de consultation
-- (catalogue types_consultation) : sa durée pilote désormais le découpage
-- des créneaux de cette plage (remplace la saisie manuelle de
-- duree_creneau_minutes dans le formulaire "Nouveau planning").
ALTER TABLE planning_medecin
  ADD COLUMN type_consultation_id INT UNSIGNED NULL AFTER salle_id,
  ADD CONSTRAINT fk_planning_medecin_type_consultation FOREIGN KEY (type_consultation_id) REFERENCES types_consultation (id);

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0058_add_type_consultation_to_planning_medecin.sql', NOW());

-- [0059_add_type_consultation_to_medecin_specialite.sql]
-- Chaque spécialité d'un médecin a son propre type de consultation
-- (nom, temps, prix) — saisi directement dans le formulaire médecin,
-- task.txt : "Chaque spécialité a son type de consultation" /
-- "Le type de consultation doit être ajouté au formulaire de médecin".
ALTER TABLE medecin_specialite
  ADD COLUMN type_consultation_nom VARCHAR(150) NULL,
  ADD COLUMN temps_consultation_minutes SMALLINT UNSIGNED NULL,
  ADD COLUMN prix_consultation DECIMAL(10,2) NULL;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0059_add_type_consultation_to_medecin_specialite.sql', NOW());

-- [0060_medecin_specialite_plusieurs_types_consultation.sql]
-- Une spécialité d'un médecin peut désormais avoir PLUSIEURS types de
-- consultation (task.txt : "ajouter un bouton ... pour pouvoir ajouter
-- plusieurs type de consultation pour la spécialité cochée"), remplaçant
-- les 3 colonnes uniques ajoutées précédemment sur medecin_specialite.
ALTER TABLE medecin_specialite
  DROP COLUMN type_consultation_nom,
  DROP COLUMN temps_consultation_minutes,
  DROP COLUMN prix_consultation;

CREATE TABLE medecin_specialite_type_consultation (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  medecin_id INT UNSIGNED NOT NULL,
  specialite_id INT UNSIGNED NOT NULL,
  nom VARCHAR(150) NOT NULL,
  temps_consultation_minutes SMALLINT UNSIGNED NOT NULL DEFAULT 15,
  prix_consultation DECIMAL(10,2) NULL,
  KEY idx_mstc_medecin_specialite (medecin_id, specialite_id),
  CONSTRAINT fk_mstc_medecin_specialite FOREIGN KEY (medecin_id, specialite_id) REFERENCES medecin_specialite (medecin_id, specialite_id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- planning_medecin.type_consultation_id pointait vers le catalogue partagé
-- abandonné (types_consultation) ; il pointe désormais vers une ligne de
-- medecin_specialite_type_consultation (le type propre à la spécialité
-- choisie pour cette plage).
ALTER TABLE planning_medecin
  DROP FOREIGN KEY fk_planning_medecin_type_consultation,
  DROP COLUMN type_consultation_id;

ALTER TABLE planning_medecin
  ADD COLUMN type_consultation_id INT UNSIGNED NULL AFTER salle_id,
  ADD CONSTRAINT fk_planning_medecin_type_consultation FOREIGN KEY (type_consultation_id) REFERENCES medecin_specialite_type_consultation (id);

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0060_medecin_specialite_plusieurs_types_consultation.sql', NOW());

-- [0061_add_supprime_at_catalogues.sql]
-- Ajoute la suppression douce (supprime_at) aux catalogues qui n'en
-- disposaient pas encore, pour permettre une icône "Supprimer" cohérente
-- avec le reste de l'application (jamais de DELETE physique).
ALTER TABLE specialites ADD COLUMN supprime_at DATETIME NULL;
ALTER TABLE salles ADD COLUMN supprime_at DATETIME NULL;
ALTER TABLE machines_imagerie ADD COLUMN supprime_at DATETIME NULL;
ALTER TABLE examens_imagerie ADD COLUMN supprime_at DATETIME NULL;
ALTER TABLE types_machine_imagerie ADD COLUMN supprime_at DATETIME NULL;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0061_add_supprime_at_catalogues.sql', NOW());

-- [0062_create_conges.sql]
-- Historique des congés des médecins : jusqu'ici, un congé n'existait que
-- comme 4 colonnes sur medecins (statut/type_conge/conge_debut/conge_fin),
-- écrasées dès qu'il se terminait — aucun historique. La colonne `actif`
-- indique le congé actuellement reflété sur la fiche du médecin (au plus un
-- par médecin), pour resynchroniser proprement modification/suppression.
CREATE TABLE conges (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  medecin_id INT UNSIGNED NOT NULL,
  type_conge VARCHAR(30) NOT NULL,
  conge_debut DATE NOT NULL,
  conge_fin DATE NOT NULL,
  actif TINYINT(1) NOT NULL DEFAULT 1,
  supprime_at DATETIME NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_conges_medecin (medecin_id),
  CONSTRAINT fk_conges_medecin FOREIGN KEY (medecin_id) REFERENCES medecins (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- Préserve le congé actuellement en cours d'un médecin (s'il y en a un) dans
-- le nouvel historique, pour ne rien perdre au moment du déploiement.
INSERT INTO conges (medecin_id, type_conge, conge_debut, conge_fin, actif)
SELECT id, type_conge, conge_debut, conge_fin, 1
FROM medecins
WHERE statut = 'en_conge' AND conge_debut IS NOT NULL AND conge_fin IS NOT NULL;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0062_create_conges.sql', NOW());

-- [0063_add_type_consultation_id_to_rendez_vous.sql]
-- Le formulaire "Nouveau rendez-vous" choisissait jusqu'ici un type de
-- consultation en texte libre, sans lien avec le planning du médecin
-- (durée/prix). On ajoute une FK vers le type propre au (médecin,
-- spécialité) sélectionné, qui pilote désormais la durée des créneaux.
ALTER TABLE rendez_vous
  ADD COLUMN type_consultation_id INT UNSIGNED NULL AFTER specialite_id,
  ADD CONSTRAINT fk_rendez_vous_type_consultation FOREIGN KEY (type_consultation_id) REFERENCES medecin_specialite_type_consultation (id);

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0063_add_type_consultation_id_to_rendez_vous.sql', NOW());

-- [0064_add_medecin_id_to_users.sql]
-- task.txt (Espace Médecin) : un compte ayant le rôle "medecin" est désormais
-- rattaché à une fiche medecins précise, pour qu'une fois connecté il ne
-- voie que sa propre journée/ses propres patients au lieu d'un menu
-- déroulant où le staff choisit le médecin à consulter.
ALTER TABLE users
  ADD COLUMN medecin_id INT UNSIGNED NULL AFTER role_id,
  ADD CONSTRAINT fk_users_medecin FOREIGN KEY (medecin_id) REFERENCES medecins (id);

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0064_add_medecin_id_to_users.sql', NOW());

-- [0065_add_priorite_heure_fin_consultation_rendez_vous.sql]
-- task.txt (Espace Médecin) :
--  - "priorite" alimente la carte de rendez-vous (niveau de priorité) et le
--    compteur "rendez-vous urgents" du tableau de bord du jour ;
--  - "heure_fin_consultation" (combinée à heure_prise_en_charge, déjà
--    existant) permet de calculer la durée réelle de consultation, pour le
--    "temps moyen de consultation" et l'heure estimée de fin de journée.
ALTER TABLE rendez_vous
  ADD COLUMN priorite ENUM('normal','urgent') NOT NULL DEFAULT 'normal' AFTER type_rdv,
  ADD COLUMN heure_fin_consultation TIME NULL AFTER heure_prise_en_charge;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0065_add_priorite_heure_fin_consultation_rendez_vous.sql', NOW());

-- [0066_add_lien_teleconsultation_rendez_vous.sql]
-- task.txt (Espace Médecin, section 12 — téléconsultation) : pas de
-- visioconférence intégrée (hors périmètre, nécessite une vraie
-- intégration vidéo), seulement un lien externe collé manuellement par le
-- staff à la prise du rendez-vous (ex. Zoom, Google Meet, Jitsi).
ALTER TABLE rendez_vous
  ADD COLUMN lien_teleconsultation VARCHAR(255) NULL AFTER heure_fin_consultation;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0066_add_lien_teleconsultation_rendez_vous.sql', NOW());

-- [0067_create_dossier_medical_tables.sql]
-- task.txt (Espace Médecin, sections 5/6/9/10) : dossier médical enrichi et
-- actions rapides depuis un rendez-vous — notes de consultation,
-- ordonnances, certificats médicaux, documents patient, vaccinations.
-- Contenu en texte libre (pas de base de médicaments/interactions, hors
-- périmètre) ; suppression douce uniquement sur documents_patient (les
-- autres sont des actes médicaux, jamais retirés une fois consignés).

CREATE TABLE notes_consultation (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  rendez_vous_id INT UNSIGNED NOT NULL,
  medecin_id INT UNSIGNED NOT NULL,
  patient_id INT UNSIGNED NOT NULL,
  motif TEXT NULL,
  diagnostic TEXT NULL,
  observations TEXT NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_notes_consultation_patient (patient_id),
  KEY idx_notes_consultation_medecin (medecin_id),
  CONSTRAINT fk_notes_consultation_rendez_vous FOREIGN KEY (rendez_vous_id) REFERENCES rendez_vous (id),
  CONSTRAINT fk_notes_consultation_medecin FOREIGN KEY (medecin_id) REFERENCES medecins (id),
  CONSTRAINT fk_notes_consultation_patient FOREIGN KEY (patient_id) REFERENCES patients (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE ordonnances (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  rendez_vous_id INT UNSIGNED NOT NULL,
  medecin_id INT UNSIGNED NOT NULL,
  patient_id INT UNSIGNED NOT NULL,
  contenu TEXT NOT NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_ordonnances_patient (patient_id),
  KEY idx_ordonnances_medecin (medecin_id),
  CONSTRAINT fk_ordonnances_rendez_vous FOREIGN KEY (rendez_vous_id) REFERENCES rendez_vous (id),
  CONSTRAINT fk_ordonnances_medecin FOREIGN KEY (medecin_id) REFERENCES medecins (id),
  CONSTRAINT fk_ordonnances_patient FOREIGN KEY (patient_id) REFERENCES patients (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE certificats_medicaux (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  rendez_vous_id INT UNSIGNED NOT NULL,
  medecin_id INT UNSIGNED NOT NULL,
  patient_id INT UNSIGNED NOT NULL,
  type VARCHAR(100) NOT NULL,
  contenu TEXT NOT NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_certificats_medicaux_patient (patient_id),
  KEY idx_certificats_medicaux_medecin (medecin_id),
  CONSTRAINT fk_certificats_medicaux_rendez_vous FOREIGN KEY (rendez_vous_id) REFERENCES rendez_vous (id),
  CONSTRAINT fk_certificats_medicaux_medecin FOREIGN KEY (medecin_id) REFERENCES medecins (id),
  CONSTRAINT fk_certificats_medicaux_patient FOREIGN KEY (patient_id) REFERENCES patients (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE documents_patient (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  patient_id INT UNSIGNED NOT NULL,
  rendez_vous_id INT UNSIGNED NULL,
  type ENUM('carte_identite','carte_assurance','ordonnance','bilan','irm','scanner','echographie','photo_medicale','consentement','autre') NOT NULL DEFAULT 'autre',
  fichier_path VARCHAR(255) NOT NULL,
  libelle VARCHAR(150) NULL,
  cree_par INT UNSIGNED NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  supprime_at DATETIME NULL,
  KEY idx_documents_patient_patient (patient_id),
  CONSTRAINT fk_documents_patient_patient FOREIGN KEY (patient_id) REFERENCES patients (id),
  CONSTRAINT fk_documents_patient_rendez_vous FOREIGN KEY (rendez_vous_id) REFERENCES rendez_vous (id),
  CONSTRAINT fk_documents_patient_cree_par FOREIGN KEY (cree_par) REFERENCES users (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE vaccinations (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  patient_id INT UNSIGNED NOT NULL,
  nom_vaccin VARCHAR(150) NOT NULL,
  date_administration DATE NOT NULL,
  rappel_prevu DATE NULL,
  cree_par INT UNSIGNED NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_vaccinations_patient (patient_id),
  KEY idx_vaccinations_rappel (rappel_prevu),
  CONSTRAINT fk_vaccinations_patient FOREIGN KEY (patient_id) REFERENCES patients (id),
  CONSTRAINT fk_vaccinations_cree_par FOREIGN KEY (cree_par) REFERENCES users (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0067_create_dossier_medical_tables.sql', NOW());

-- [0068_create_domaines_laboratoire_valeurs_reference.sql]
-- task.txt (Laboratoire enrichi, section 5 — domaines/catégories d'analyses
-- + section 7 — valeurs de référence et résultats critiques).
CREATE TABLE domaines_laboratoire (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  libelle VARCHAR(100) NOT NULL,
  actif TINYINT(1) NOT NULL DEFAULT 1,
  supprime_at DATETIME NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO domaines_laboratoire (libelle) VALUES
  ('Hématologie'), ('Biochimie'), ('Immunologie'), ('Sérologie'), ('Bactériologie'),
  ('Virologie'), ('Parasitologie'), ('Mycologie'), ('Toxicologie'), ('Anatomopathologie');

ALTER TABLE examens
  ADD COLUMN domaine_laboratoire_id INT UNSIGNED NULL AFTER libelle,
  ADD CONSTRAINT fk_examens_domaine FOREIGN KEY (domaine_laboratoire_id) REFERENCES domaines_laboratoire (id);

CREATE TABLE valeurs_reference_examen (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  examen_id INT UNSIGNED NOT NULL,
  sexe ENUM('M','F','tous') NOT NULL DEFAULT 'tous',
  age_min_annees SMALLINT UNSIGNED NULL,
  age_max_annees SMALLINT UNSIGNED NULL,
  valeur_min DECIMAL(10,3) NULL,
  valeur_max DECIMAL(10,3) NULL,
  unite VARCHAR(30) NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_valeurs_reference_examen (examen_id),
  CONSTRAINT fk_valeurs_reference_examen FOREIGN KEY (examen_id) REFERENCES examens (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

ALTER TABLE demandes_laboratoire
  ADD COLUMN resultat_valeur DECIMAL(10,3) NULL AFTER resultat_path,
  ADD COLUMN resultat_unite VARCHAR(30) NULL AFTER resultat_valeur,
  ADD COLUMN resultat_commentaire TEXT NULL AFTER resultat_unite;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0068_create_domaines_laboratoire_valeurs_reference.sql', NOW());

-- [0069_laboratoire_statuts_validation_biologique.sql]
-- task.txt (Laboratoire enrichi, section 4/8) : statuts intermédiaires
-- (reçu, en analyse, validation biologique) avant le résultat disponible,
-- et trace de la signature électronique du biologiste.
ALTER TABLE demandes_laboratoire
  MODIFY COLUMN statut ENUM('en_attente','preleve','recu','en_analyse','validation_biologique','resultat_disponible','annule')
    NOT NULL DEFAULT 'en_attente';

CREATE TABLE validations_biologiques (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  demande_laboratoire_id INT UNSIGNED NOT NULL,
  valide_par INT UNSIGNED NULL,
  commentaire TEXT NULL,
  signe_le DATETIME NOT NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_validations_biologiques_demande (demande_laboratoire_id),
  CONSTRAINT fk_validations_biologiques_demande FOREIGN KEY (demande_laboratoire_id) REFERENCES demandes_laboratoire (id),
  CONSTRAINT fk_validations_biologiques_user FOREIGN KEY (valide_par) REFERENCES users (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0069_laboratoire_statuts_validation_biologique.sql', NOW());

-- [0070_create_stock_laboratoire.sql]
CREATE TABLE stock_laboratoire (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  libelle VARCHAR(150) NOT NULL,
  type ENUM('reactif','tube','kit','controle','consommable') NOT NULL,
  quantite_actuelle INT NOT NULL DEFAULT 0,
  seuil_alerte INT NOT NULL DEFAULT 0,
  unite VARCHAR(30) NULL,
  date_peremption DATE NULL,
  actif TINYINT(1) NOT NULL DEFAULT 1,
  supprime_at DATETIME NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE mouvements_stock_laboratoire (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  stock_id INT UNSIGNED NOT NULL,
  type ENUM('entree','sortie') NOT NULL,
  quantite INT NOT NULL,
  motif VARCHAR(255) NULL,
  cree_par INT UNSIGNED NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_mouvements_stock_laboratoire_stock (stock_id),
  CONSTRAINT fk_mouvements_stock_laboratoire_stock FOREIGN KEY (stock_id) REFERENCES stock_laboratoire (id),
  CONSTRAINT fk_mouvements_stock_laboratoire_cree_par FOREIGN KEY (cree_par) REFERENCES users (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0070_create_stock_laboratoire.sql', NOW());

-- [0071_add_nombre_reprises_demandes_laboratoire.sql]
ALTER TABLE demandes_laboratoire
  ADD COLUMN nombre_reprises INT UNSIGNED NOT NULL DEFAULT 0;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0071_add_nombre_reprises_demandes_laboratoire.sql', NOW());

-- [0072_imagerie_statuts_compte_rendu.sql]
ALTER TABLE demandes_imagerie
  ADD COLUMN statut_compte_rendu ENUM('aucun','brouillon','signe','envoye') NOT NULL DEFAULT 'aucun',
  ADD COLUMN radiologue_id INT UNSIGNED NULL,
  ADD COLUMN compte_rendu_signe_le DATETIME NULL,
  ADD COLUMN compte_rendu_contenu TEXT NULL,
  ADD CONSTRAINT fk_demandes_imagerie_radiologue FOREIGN KEY (radiologue_id) REFERENCES medecins (id);

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0072_imagerie_statuts_compte_rendu.sql', NOW());

-- [0073_create_modeles_compte_rendu.sql]
CREATE TABLE modeles_compte_rendu (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  examen_imagerie_id INT UNSIGNED NULL,
  libelle VARCHAR(150) NOT NULL,
  contenu TEXT NOT NULL,
  actif TINYINT(1) NOT NULL DEFAULT 1,
  supprime_at DATETIME NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT fk_modeles_compte_rendu_examen FOREIGN KEY (examen_imagerie_id) REFERENCES examens_imagerie (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0073_create_modeles_compte_rendu.sql', NOW());

-- [0074_create_maintenances_machine_imagerie.sql]
ALTER TABLE machines_imagerie
  ADD COLUMN statut ENUM('disponible','en_maintenance','en_panne') NOT NULL DEFAULT 'disponible';

CREATE TABLE maintenances_machine_imagerie (
  id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  machine_id INT UNSIGNED NOT NULL,
  type ENUM('preventive','corrective') NOT NULL,
  description TEXT NULL,
  date_intervention DATE NOT NULL,
  prochaine_echeance DATE NULL,
  technicien VARCHAR(150) NULL,
  cree_par INT UNSIGNED NULL,
  cree_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_maintenances_machine_imagerie_machine (machine_id),
  CONSTRAINT fk_maintenances_machine_imagerie_machine FOREIGN KEY (machine_id) REFERENCES machines_imagerie (id),
  CONSTRAINT fk_maintenances_machine_imagerie_cree_par FOREIGN KEY (cree_par) REFERENCES users (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0074_create_maintenances_machine_imagerie.sql', NOW());

-- [0075_add_mode_rendez_vous.sql]
ALTER TABLE rendez_vous
  ADD COLUMN mode ENUM('standard','insertion','rattrapage') NOT NULL DEFAULT 'standard' AFTER type_rdv;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0075_add_mode_rendez_vous.sql', NOW());

-- [0076_add_supprime_at_demandes_imagerie.sql]
ALTER TABLE demandes_imagerie
  ADD COLUMN supprime_at DATETIME NULL;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0076_add_supprime_at_demandes_imagerie.sql', NOW());

-- [0077_add_factures_remise_assurance.sql]
-- Réduction assurance sur une facture : montant_original conserve la valeur
-- initiale avant remise (permet de recalculer si le % change), remise_assurance_pct
-- stocke le % appliqué, remise_assurance_montant stocke le montant déduit.
-- montant est mis à jour à (montant_original - remise_assurance_montant) lors
-- de l'application, de sorte que la logique de paiement existante reste inchangée.
ALTER TABLE factures
    ADD COLUMN montant_original DECIMAL(10,2) NULL AFTER montant,
    ADD COLUMN remise_assurance_pct DECIMAL(5,2) NULL AFTER montant_original,
    ADD COLUMN remise_assurance_montant DECIMAL(10,2) NOT NULL DEFAULT 0 AFTER remise_assurance_pct;

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0077_add_factures_remise_assurance.sql', NOW());

-- [0078_add_rendez_vous_statuts_workflow.sql]
-- Ajout des statuts intermédiaires de workflow : présent (patient arrivé),
-- en_cours (consultation démarrée), termine (consultation terminée).
-- honore/absent/annule restent intacts pour la rétrocompatibilité.
ALTER TABLE rendez_vous
  MODIFY COLUMN statut
    ENUM('en_attente','confirme','present','en_cours','termine','honore','absent','annule')
    NOT NULL DEFAULT 'en_attente';

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0078_add_rendez_vous_statuts_workflow.sql', NOW());

-- [0079_create_categories_entente_enrich_ententes.sql]
-- Catégories d'entente configurables (Imagerie, Rendez-vous, Laboratoire,
-- Hospitalisation…) et enrichissement de la table ententes pour supporter
-- le nouveau formulaire de prise en charge assurance.

CREATE TABLE categories_entente (
  id   INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  libelle VARCHAR(100) NOT NULL,
  actif   TINYINT(1)   NOT NULL DEFAULT 1,
  cree_at DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY idx_categories_entente_actif (actif)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO categories_entente (libelle) VALUES
  ('Imagerie'),
  ('Rendez-vous'),
  ('Laboratoire'),
  ('Hospitalisation');

ALTER TABLE ententes
  ADD COLUMN categorie_entente_id INT UNSIGNED NULL        AFTER demande_imagerie_id,
  ADD COLUMN type_entente         ENUM('nouvelle_facture','nouvelle_entente') NOT NULL DEFAULT 'nouvelle_entente' AFTER categorie_entente_id,
  ADD COLUMN type_rdv             ENUM('rdv','tout_venant') NULL              AFTER type_entente,
  ADD COLUMN specialite_id        INT UNSIGNED NULL        AFTER type_rdv,
  ADD COLUMN machine_id           INT UNSIGNED NULL        AFTER specialite_id,
  ADD COLUMN examen_imagerie_id   INT UNSIGNED NULL        AFTER machine_id,
  ADD COLUMN examen_labo_id       INT UNSIGNED NULL        AFTER examen_imagerie_id,
  ADD COLUMN departement          VARCHAR(100) NULL        AFTER examen_labo_id,
  ADD COLUMN note                 TEXT NULL                AFTER departement,
  ADD COLUMN bulletin_path        VARCHAR(255) NULL        AFTER note,
  ADD CONSTRAINT fk_ententes_categorie_entente FOREIGN KEY (categorie_entente_id) REFERENCES categories_entente (id),
  ADD CONSTRAINT fk_ententes_specialite        FOREIGN KEY (specialite_id)        REFERENCES specialites (id),
  ADD CONSTRAINT fk_ententes_machine           FOREIGN KEY (machine_id)           REFERENCES machines_imagerie (id),
  ADD CONSTRAINT fk_ententes_examen_imagerie   FOREIGN KEY (examen_imagerie_id)   REFERENCES examens_imagerie (id),
  ADD CONSTRAINT fk_ententes_examen_labo       FOREIGN KEY (examen_labo_id)       REFERENCES examens (id);

INSERT IGNORE INTO schema_migrations (migration, applied_at) VALUES ('0079_create_categories_entente_enrich_ententes.sql', NOW());


SET foreign_key_checks = 1;

-- =============================================================================
-- ÉTAPES POST-IMPORT
-- =============================================================================
--
-- 1. CRÉER L'ADMINISTRATEUR PLATEFORME
--    Remplacer <bcrypt_hash> par un hash bcrypt du mot de passe choisi.
--    (générer avec : php -r "echo password_hash('monmotdepasse', PASSWORD_BCRYPT);")
--
--    INSERT INTO platform_admins (nom, prenom, email, password_hash)
--    VALUES ('Nom', 'Prénom', 'admin@polycliniquefarah.com', '<bcrypt_hash>');
--
-- 2. DÉCLARER L'ÉTABLISSEMENT
--    Remplacer <password_chiffre> par la valeur chiffrée produite par l'application.
--
--    INSERT INTO etablissements
--      (nom, slug, sous_domaine, db_host, db_port, db_name, db_username,
--       db_password_chiffre, statut, couleur_principale, menu_position)
--    VALUES
--      ('Polyclinique Farah', 'polyclinique-farah',
--       'newmyfarah.polycliniquefarah.com',
--       '127.0.0.1', 3306, 'newmyfarah', 'newmyfarah',
--       '<password_chiffre>', 'actif', '#007F82', 'sidebar');
--
-- 3. CONFIGURER .env
--    APP_URL=https://newmyfarah.polycliniquefarah.com
--    ADMIN_URL=https://newmyfarahadmin.polycliniquefarah.com
--    ADMIN_DB_NAME=newmyfarah
--    ADMIN_DB_USER=newmyfarah
--    ADMIN_DB_PASS=<mot_de_passe>
--    ADMIN_DB_HOST=127.0.0.1
--
-- =============================================================================
