- Configuration complète Stripe pour les 3 environnements (DEV/REC/PROD) * DEV: Clés TEST Pierre (mode test) * REC: Clés TEST Client (mode test) * PROD: Clés LIVE Client (mode live) - Ajout de la gestion des bases de données immeubles/bâtiments * Configuration buildings_database pour DEV/REC/PROD * Service BuildingService pour enrichissement des adresses - Optimisations pages et améliorations ergonomie - Mises à jour des dépendances Composer - Nettoyage des fichiers obsolètes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
283 lines
11 KiB
PHP
283 lines
11 KiB
PHP
<?php
|
||
/**
|
||
* Script de vérification de la cohérence des structures
|
||
* avant migration entre geosector (source) et geo_app (cible)
|
||
*
|
||
* Ce script compare les colonnes de chaque table migrée
|
||
* et identifie les incohérences potentielles
|
||
*
|
||
* Usage: php scripts/php/verify_migration_structure.php
|
||
*/
|
||
|
||
require_once dirname(__DIR__) . '/config.php';
|
||
|
||
// Couleurs pour le terminal
|
||
define('COLOR_GREEN', "\033[0;32m");
|
||
define('COLOR_RED', "\033[0;31m");
|
||
define('COLOR_YELLOW', "\033[1;33m");
|
||
define('COLOR_BLUE', "\033[0;34m");
|
||
define('COLOR_RESET', "\033[0m");
|
||
|
||
// Fonction pour afficher des messages colorés
|
||
function printColor($message, $color = COLOR_RESET) {
|
||
echo $color . $message . COLOR_RESET . PHP_EOL;
|
||
}
|
||
|
||
// Fonction pour obtenir les colonnes d'une table
|
||
function getTableColumns($pdo, $tableName) {
|
||
try {
|
||
$stmt = $pdo->query("DESCRIBE `$tableName`");
|
||
$columns = [];
|
||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||
$columns[$row['Field']] = [
|
||
'type' => $row['Type'],
|
||
'null' => $row['Null'],
|
||
'key' => $row['Key'],
|
||
'default' => $row['Default'],
|
||
'extra' => $row['Extra']
|
||
];
|
||
}
|
||
return $columns;
|
||
} catch (PDOException $e) {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
// Mappings de colonnes connus
|
||
$columnMappings = [
|
||
// Mappings globaux
|
||
'global' => [
|
||
'rowid' => 'id',
|
||
'active' => 'chk_active',
|
||
'date_creat' => 'created_at',
|
||
'date_modif' => 'updated_at',
|
||
],
|
||
// Mappings spécifiques par table
|
||
'users_entites' => [
|
||
'table_target' => 'entites',
|
||
'mappings' => [
|
||
'libelle' => 'encrypted_name',
|
||
'tel1' => 'encrypted_phone',
|
||
'tel2' => 'encrypted_mobile',
|
||
'email' => 'encrypted_email',
|
||
'iban' => 'encrypted_iban',
|
||
'bic' => 'encrypted_bic',
|
||
'cp' => 'code_postal',
|
||
]
|
||
],
|
||
'users' => [
|
||
'mappings' => [
|
||
'libelle' => 'encrypted_name',
|
||
'username' => 'encrypted_user_name',
|
||
'userpswd' => 'user_pass_hash',
|
||
'userpass' => 'user_pass_hash',
|
||
'prenom' => 'first_name',
|
||
'nom_tournee' => 'sect_name',
|
||
'telephone' => 'encrypted_phone',
|
||
'mobile' => 'encrypted_mobile',
|
||
'email' => 'encrypted_email',
|
||
'alert_email' => 'chk_alert_email',
|
||
]
|
||
],
|
||
'ope_pass' => [
|
||
'mappings' => [
|
||
'date_eve' => 'passed_at',
|
||
'libelle' => 'encrypted_name',
|
||
'email' => 'encrypted_email',
|
||
'phone' => 'encrypted_phone',
|
||
'recu' => 'nom_recu',
|
||
]
|
||
],
|
||
'medias' => [
|
||
'mappings' => [
|
||
'support_rowid' => 'support_id',
|
||
]
|
||
],
|
||
'x_villes' => [
|
||
'mappings' => [
|
||
'cp' => 'code_postal',
|
||
]
|
||
],
|
||
];
|
||
|
||
// Tables à vérifier (source => cible)
|
||
$tablesToVerify = [
|
||
'x_devises' => 'x_devises',
|
||
'x_entites_types' => 'x_entites_types',
|
||
'x_types_passages' => 'x_types_passages',
|
||
'x_types_reglements' => 'x_types_reglements',
|
||
'x_users_roles' => 'x_users_roles',
|
||
'x_pays' => 'x_pays',
|
||
'x_regions' => 'x_regions',
|
||
'x_departements' => 'x_departements',
|
||
'x_villes' => 'x_villes',
|
||
'users_entites' => 'entites',
|
||
'users' => 'users',
|
||
'operations' => 'operations',
|
||
'ope_users' => 'ope_users',
|
||
'ope_users_sectors' => 'ope_users_sectors',
|
||
'ope_pass' => 'ope_pass',
|
||
'ope_pass_histo' => 'ope_pass_histo',
|
||
'medias' => 'medias',
|
||
'sectors_adresses' => 'sectors_adresses',
|
||
];
|
||
|
||
try {
|
||
printColor("\n╔══════════════════════════════════════════════════════════════╗", COLOR_BLUE);
|
||
printColor("║ VÉRIFICATION DES STRUCTURES DE MIGRATION ║", COLOR_BLUE);
|
||
printColor("╚══════════════════════════════════════════════════════════════╝", COLOR_BLUE);
|
||
|
||
// Connexion aux bases de données
|
||
printColor("\n[INFO] Connexion aux bases de données...", COLOR_BLUE);
|
||
$sourceDb = getSourceConnection();
|
||
$targetDb = getTargetConnection();
|
||
printColor("[OK] Connexions établies", COLOR_GREEN);
|
||
|
||
$totalIssues = 0;
|
||
$totalWarnings = 0;
|
||
$totalTables = count($tablesToVerify);
|
||
|
||
foreach ($tablesToVerify as $sourceTable => $targetTable) {
|
||
printColor("\n" . str_repeat("─", 70), COLOR_BLUE);
|
||
printColor("📊 Table: $sourceTable → $targetTable", COLOR_BLUE);
|
||
printColor(str_repeat("─", 70), COLOR_BLUE);
|
||
|
||
// Récupérer les colonnes
|
||
$sourceCols = getTableColumns($sourceDb, $sourceTable);
|
||
$targetCols = getTableColumns($targetDb, $targetTable);
|
||
|
||
if ($sourceCols === null) {
|
||
printColor("❌ ERREUR: Table source '$sourceTable' introuvable", COLOR_RED);
|
||
$totalIssues++;
|
||
continue;
|
||
}
|
||
|
||
if ($targetCols === null) {
|
||
printColor("❌ ERREUR: Table cible '$targetTable' introuvable", COLOR_RED);
|
||
$totalIssues++;
|
||
continue;
|
||
}
|
||
|
||
// Récupérer les mappings pour cette table
|
||
$tableMappings = $columnMappings['global'];
|
||
if (isset($columnMappings[$sourceTable]['mappings'])) {
|
||
$tableMappings = array_merge($tableMappings, $columnMappings[$sourceTable]['mappings']);
|
||
}
|
||
|
||
// Vérifier chaque colonne source
|
||
$unmappedSourceCols = [];
|
||
$mappedCols = 0;
|
||
|
||
foreach ($sourceCols as $sourceCol => $sourceInfo) {
|
||
// Chercher la colonne cible
|
||
$targetCol = $tableMappings[$sourceCol] ?? $sourceCol;
|
||
|
||
if (isset($targetCols[$targetCol])) {
|
||
$mappedCols++;
|
||
// Colonne existe et mappée correctement
|
||
} else {
|
||
// Vérifier si c'est une colonne qui doit être ignorée
|
||
$ignoredCols = ['dir0', 'dir1', 'dir2', 'type_fichier', 'position', 'hauteur', 'largeur',
|
||
'niveaugris', 'lieudit', 'chk_habitat_vide', 'lot_nb_passages', 'departement',
|
||
'fk_user', 'chk_api_adresse', 'num_adherent', 'libelle_naissance', 'josh',
|
||
'email_secondaire', 'infos', 'ltt', 'lng', 'sector', 'dept_naissance',
|
||
'commune_naissance', 'anciennete', 'fk_categorie', 'fk_sous_categorie',
|
||
'adresse_1', 'adresse_2', 'cp', 'ville', 'matricule', 'fk_grade',
|
||
'chk_adherent_ud', 'chk_adherent_ur', 'chk_adherent_fns', 'chk_archive',
|
||
'chk_double_affectation', 'date_creat', 'appname', 'http_host', 'tva_intra',
|
||
'rcs', 'siret', 'ape', 'couleur', 'prefecture', 'fk_titre_gerant',
|
||
'gerant_prenom', 'gerant_nom', 'site_url', 'gerant_signature',
|
||
'tampon_signature', 'banque_libelle', 'banque_adresse', 'banque_cp',
|
||
'banque_ville', 'genbase', 'groupebase', 'userbase', 'passbase', 'demo',
|
||
'lib_vert', 'lib_verts', 'lib_orange', 'lib_oranges', 'lib_rouge', 'lib_rouges',
|
||
'lib_bleu', 'lib_bleus', 'icon_siege', 'icon_siege_color', 'btn_width',
|
||
'nbmembres', 'nbconnex'];
|
||
|
||
if (in_array($sourceCol, $ignoredCols)) {
|
||
// Colonne volontairement non migrée
|
||
continue;
|
||
}
|
||
|
||
$unmappedSourceCols[] = $sourceCol;
|
||
}
|
||
}
|
||
|
||
// Vérifier les nouvelles colonnes dans la cible
|
||
$newTargetCols = [];
|
||
foreach ($targetCols as $targetCol => $targetInfo) {
|
||
// Vérifier si cette colonne existe dans la source
|
||
$sourceCol = array_search($targetCol, $tableMappings);
|
||
if ($sourceCol === false) {
|
||
$sourceCol = $targetCol; // Même nom
|
||
}
|
||
|
||
if (!isset($sourceCols[$sourceCol])) {
|
||
// Vérifier si c'est une colonne attendue (timestamp auto, etc.)
|
||
$autoColumns = ['created_at', 'updated_at', 'id'];
|
||
if (!in_array($targetCol, $autoColumns)) {
|
||
$newTargetCols[] = $targetCol;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Affichage des résultats
|
||
printColor("✓ Colonnes source mappées: $mappedCols/" . count($sourceCols), COLOR_GREEN);
|
||
|
||
if (!empty($unmappedSourceCols)) {
|
||
printColor("⚠ Colonnes source NON mappées:", COLOR_YELLOW);
|
||
foreach ($unmappedSourceCols as $col) {
|
||
printColor(" - $col ({$sourceCols[$col]['type']})", COLOR_YELLOW);
|
||
}
|
||
$totalWarnings += count($unmappedSourceCols);
|
||
}
|
||
|
||
if (!empty($newTargetCols)) {
|
||
printColor("ℹ Nouvelles colonnes dans cible (seront NULL/défaut):", COLOR_YELLOW);
|
||
foreach ($newTargetCols as $col) {
|
||
$defaultValue = $targetCols[$col]['default'] ?? 'NULL';
|
||
$nullable = $targetCols[$col]['null'] === 'YES' ? '(nullable)' : '(NOT NULL)';
|
||
printColor(" - $col ({$targetCols[$col]['type']}) = $defaultValue $nullable", COLOR_YELLOW);
|
||
}
|
||
$totalWarnings += count($newTargetCols);
|
||
}
|
||
|
||
if (empty($unmappedSourceCols) && empty($newTargetCols)) {
|
||
printColor("✓ Aucun problème détecté", COLOR_GREEN);
|
||
}
|
||
}
|
||
|
||
// Résumé final
|
||
printColor("\n" . str_repeat("═", 70), COLOR_BLUE);
|
||
printColor("📈 RÉSUMÉ DE LA VÉRIFICATION", COLOR_BLUE);
|
||
printColor(str_repeat("═", 70), COLOR_BLUE);
|
||
printColor("Tables vérifiées: $totalTables", COLOR_BLUE);
|
||
|
||
if ($totalIssues > 0) {
|
||
printColor("❌ Erreurs critiques: $totalIssues", COLOR_RED);
|
||
} else {
|
||
printColor("✓ Aucune erreur critique", COLOR_GREEN);
|
||
}
|
||
|
||
if ($totalWarnings > 0) {
|
||
printColor("⚠ Avertissements: $totalWarnings", COLOR_YELLOW);
|
||
printColor(" (colonnes non mappées ou nouvelles colonnes)", COLOR_YELLOW);
|
||
} else {
|
||
printColor("✓ Aucun avertissement", COLOR_GREEN);
|
||
}
|
||
|
||
printColor("\n💡 Recommandations:", COLOR_BLUE);
|
||
printColor(" - Vérifiez que les colonnes non mappées sont intentionnelles", COLOR_RESET);
|
||
printColor(" - Les nouvelles colonnes cible utiliseront leurs valeurs par défaut", COLOR_RESET);
|
||
printColor(" - Consultez README-migration.md pour plus de détails", COLOR_RESET);
|
||
|
||
// Fermer le tunnel SSH
|
||
closeSshTunnel();
|
||
|
||
printColor("\n✓ Vérification terminée\n", COLOR_GREEN);
|
||
|
||
} catch (Exception $e) {
|
||
printColor("\n❌ ERREUR CRITIQUE: " . $e->getMessage(), COLOR_RED);
|
||
closeSshTunnel();
|
||
exit(1);
|
||
}
|