Files
trainingstagebuch/backend/cleanupKeysNode.js
Torsten Schulz (local) 5357dac9e1
All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 54s
chore: update file permissions for multiple files and add migration for club fee rules
- Changed file permissions from 644 to 755 for various files in the mobile-app and mobile-app_legacy_rn_expo directories, ensuring executable permissions where necessary.
- Added a new SQL migration script to the backend to introduce missing columns for club billing and invoice settings in the clubs table, maintaining synchronization with the current Sequelize model.
2026-07-17 11:51:24 +02:00

157 lines
5.2 KiB
JavaScript
Executable File

import mysql from 'mysql2/promise';
import dotenv from 'dotenv';
import path from 'path';
import { fileURLToPath } from 'url';
// __dirname für ES-Module
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const report = [];
// Umgebungsvariablen aus dem Root-Verzeichnis laden
const envPath = path.join(__dirname, '..', '.env');
dotenv.config();
report.push('Environment variables loaded');
async function cleanupKeys() {
let connection;
try {
report.push('🔌 Verbinde mit der Datenbank...');
connection = await mysql.createConnection(dbConfig);
// 1. Status vor dem Cleanup
report.push('');
report.push('📊 STATUS VOR DEM CLEANUP:');
const [tablesBefore] = await connection.execute(`
SELECT
TABLE_NAME,
COUNT(*) as key_count
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = ?
GROUP BY TABLE_NAME
ORDER BY key_count DESC
`, [dbConfig.database]);
tablesBefore.forEach(table => {
report.push(` ${table.TABLE_NAME}: ${table.key_count} Keys`);
});
// 2. Alle INDEX der Problem-Tabellen anzeigen
const problemTables = ['member', 'diary_tags', 'season'];
for (const tableName of problemTables) {
report.push('');
report.push(`🔍 INDEX für Tabelle '${tableName}':`);
try {
const [indexes] = await connection.execute(`SHOW INDEX FROM \`${tableName}\``);
if (indexes.length === 0) {
report.push(` Keine INDEX gefunden für Tabelle '${tableName}'`);
continue;
}
indexes.forEach(index => {
report.push(` - ${index.Key_name} (${index.Column_name}) - ${index.Non_unique === 0 ? 'UNIQUE' : 'NON-UNIQUE'}`);
});
// 3. Überflüssige INDEX entfernen (alle außer PRIMARY und UNIQUE)
report.push('');
report.push(`🗑️ Entferne überflüssige INDEX aus '${tableName}':`);
for (const index of indexes) {
// Behalte PRIMARY KEY und UNIQUE constraints
if (index.Key_name === 'PRIMARY' || index.Non_unique === 0) {
report.push(` ✅ Behalte: ${index.Key_name} (${index.Column_name})`);
continue;
}
// Entferne alle anderen INDEX
try {
await connection.execute(`DROP INDEX \`${index.Key_name}\` ON \`${tableName}\``);
report.push(` ❌ Entfernt: ${index.Key_name} (${index.Column_name})`);
} catch (error) {
if (error.code === 'ER_CANT_DROP_FIELD_OR_KEY') {
report.push(` ⚠️ Kann nicht entfernen: ${index.Key_name} (${index.Column_name}) - ${error.message}`);
} else {
report.push(` ❌ Fehler beim Entfernen von ${index.Key_name}: ${error.message}`);
}
}
}
} catch (error) {
report.push(` ⚠️ Fehler beim Zugriff auf Tabelle '${tableName}': ${error.message}`);
}
}
// 4. Status nach dem Cleanup
report.push('');
report.push('📊 STATUS NACH DEM CLEANUP:');
const [tablesAfter] = await connection.execute(`
SELECT
TABLE_NAME,
COUNT(*) as key_count
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = ?
GROUP BY TABLE_NAME
ORDER BY key_count DESC
`, [dbConfig.database]);
tablesAfter.forEach(table => {
const before = tablesBefore.find(t => t.TABLE_NAME === table.TABLE_NAME);
const beforeCount = before ? before.key_count : 0;
const diff = beforeCount - table.key_count;
const status = table.key_count <= 5 ? '✅' : table.key_count <= 10 ? '⚠️' : '❌';
report.push(` ${status} ${table.TABLE_NAME}: ${table.key_count} Keys (${diff > 0 ? `-${diff}` : `+${Math.abs(diff)}`})`);
});
// 5. Gesamtanzahl der Keys
const [totalKeys] = await connection.execute(`
SELECT COUNT(*) as total_keys
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = ?
`, [dbConfig.database]);
report.push('');
report.push(`📈 GESAMTANZAHL KEYS: ${totalKeys[0].total_keys}`);
// 6. Zusammenfassung
report.push('');
report.push('🎯 ZUSAMMENFASSUNG:');
const problemTablesAfter = tablesAfter.filter(t => t.key_count > 10);
if (problemTablesAfter.length === 0) {
report.push(' ✅ Alle Tabellen haben jetzt weniger als 10 Keys!');
} else {
report.push(' ⚠️ Folgende Tabellen haben immer noch zu viele Keys:');
problemTablesAfter.forEach(table => {
report.push(` - ${table.TABLE_NAME}: ${table.key_count} Keys`);
});
}
} catch (error) {
console.error('❌ Fehler beim Cleanup:', error);
} finally {
if (connection) {
await connection.end();
report.push('');
report.push('🔌 Datenbankverbindung geschlossen.');
}
}
}
// Script ausführen
report.push('🚀 Starte intelligentes INDEX-Cleanup...');
cleanupKeys().then(() => {
report.push('');
report.push('✨ Cleanup abgeschlossen!');
process.stdout.write(`${report.join('\n')}\n`);
process.exit(0);
}).catch(error => {
console.error('\n💥 Fehler beim Cleanup:', error);
process.exit(1);
});