diff --git a/scripts/fix-i18n-direct.js b/scripts/fix-i18n-direct.js new file mode 100644 index 0000000..c249fff --- /dev/null +++ b/scripts/fix-i18n-direct.js @@ -0,0 +1,148 @@ +#!/usr/bin/env node + +// Direkter Fix für i18n-Daten in SQLite +// Arbeitet direkt mit der Datenbank, umgeht Prisma (da es die Daten nicht lesen kann) + +const fs = require('fs'); +const path = require('path'); +const { execSync } = require('child_process'); + +const DB_PATH = process.env.DATABASE_URL?.replace('file:', '') || '/app/data/prod.db'; + +if (!fs.existsSync(DB_PATH)) { + console.error(`❌ Datenbank nicht gefunden: ${DB_PATH}`); + process.exit(1); +} + +console.log(`🔧 Fixe i18n-Daten in: ${DB_PATH}`); + +// SQLite-Befehle zum Fixen +const sqlCommands = ` +-- Backup erstellen +.backup ${DB_PATH}.backup + +-- Temporäre Tabellen für Genres +BEGIN TRANSACTION; + +-- Prüfe und fixe Genre.name (wenn String statt JSON) +UPDATE Genre +SET name = json_object('de', name, 'en', name) +WHERE typeof(name) = 'text' AND name NOT LIKE '{%'; + +-- Prüfe und fixe Genre.subtitle +UPDATE Genre +SET subtitle = json_object('de', subtitle, 'en', subtitle) +WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%'; + +-- Prüfe und fixe Special.name +UPDATE Special +SET name = json_object('de', name, 'en', name) +WHERE typeof(name) = 'text' AND name NOT LIKE '{%'; + +-- Prüfe und fixe Special.subtitle +UPDATE Special +SET subtitle = json_object('de', subtitle, 'en', subtitle) +WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%'; + +-- Prüfe und fixe News.title +UPDATE News +SET title = json_object('de', title, 'en', title) +WHERE typeof(title) = 'text' AND title NOT LIKE '{%'; + +-- Prüfe und fixe News.content +UPDATE News +SET content = json_object('de', content, 'en', content) +WHERE typeof(content) = 'text' AND content NOT LIKE '{%'; + +COMMIT; + +-- Zeige Statistiken +SELECT 'Genres gefixt:', COUNT(*) FROM Genre WHERE typeof(name) = 'text'; +SELECT 'Specials gefixt:', COUNT(*) FROM Special WHERE typeof(name) = 'text'; +SELECT 'News gefixt:', COUNT(*) FROM News WHERE typeof(title) = 'text'; +`; + +// Führe SQL-Befehle aus +try { + console.log('📝 Führe SQL-Updates aus...'); + + // Installiere sqlite3 falls nicht vorhanden (im Container sollte es nicht da sein) + // Wir verwenden stattdessen einen Node.js-Ansatz + + // Einfacher: Nutze Prisma's direkten DB-Zugriff + const Database = require('better-sqlite3'); + const db = new Database(DB_PATH); + + // Prüfe Schema + console.log('📊 Prüfe Datenbank-Schema...'); + const tables = db.prepare("SELECT name FROM sqlite_master WHERE type='table'").all(); + console.log(` Gefundene Tabellen: ${tables.map(t => t.name).join(', ')}`); + + // Fix Genre.name + console.log('🔧 Fixe Genre.name...'); + const genreResult = db.prepare(` + UPDATE Genre + SET name = json_object('de', name, 'en', name) + WHERE typeof(name) = 'text' AND name NOT LIKE '{%' + `).run(); + console.log(` ✅ ${genreResult.changes} Genres aktualisiert`); + + // Fix Genre.subtitle + const genreSubtitleResult = db.prepare(` + UPDATE Genre + SET subtitle = json_object('de', subtitle, 'en', subtitle) + WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%' + `).run(); + console.log(` ✅ ${genreSubtitleResult.changes} Genre-Subtitles aktualisiert`); + + // Fix Special.name + console.log('🔧 Fixe Special.name...'); + const specialResult = db.prepare(` + UPDATE Special + SET name = json_object('de', name, 'en', name) + WHERE typeof(name) = 'text' AND name NOT LIKE '{%' + `).run(); + console.log(` ✅ ${specialResult.changes} Specials aktualisiert`); + + // Fix Special.subtitle + const specialSubtitleResult = db.prepare(` + UPDATE Special + SET subtitle = json_object('de', subtitle, 'en', subtitle) + WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%' + `).run(); + console.log(` ✅ ${specialSubtitleResult.changes} Special-Subtitles aktualisiert`); + + // Fix News.title + console.log('🔧 Fixe News.title...'); + const newsTitleResult = db.prepare(` + UPDATE News + SET title = json_object('de', title, 'en', title) + WHERE typeof(title) = 'text' AND title NOT LIKE '{%' + `).run(); + console.log(` ✅ ${newsTitleResult.changes} News-Titles aktualisiert`); + + // Fix News.content + const newsContentResult = db.prepare(` + UPDATE News + SET content = json_object('de', content, 'en', content) + WHERE typeof(content) = 'text' AND content NOT LIKE '{%' + `).run(); + console.log(` ✅ ${newsContentResult.changes} News-Contents aktualisiert`); + + db.close(); + + console.log('✅ Alle i18n-Daten wurden gefixt!'); + console.log('🔄 Bitte starte den Container neu: docker compose restart hoerdle'); + +} catch (error) { + console.error('❌ Fehler:', error.message); + if (error.message.includes('better-sqlite3')) { + console.error('\n💡 better-sqlite3 ist nicht installiert. Verwende stattdessen:'); + console.error(' docker exec hoerdle sh -c "cd /app && node -e \\"'); + console.error(' const fs=require(\\"fs\\");'); + console.error(' const {PrismaClient}=require(\\"@prisma/client\\");'); + console.error(' // ... alternativer Ansatz'); + } + process.exit(1); +} + diff --git a/scripts/fix-i18n-local.sh b/scripts/fix-i18n-local.sh new file mode 100755 index 0000000..2bd201b --- /dev/null +++ b/scripts/fix-i18n-local.sh @@ -0,0 +1,97 @@ +#!/bin/bash +# Fix für i18n-Daten: Kopiert DB lokal, fixt sie, kopiert zurück + +set -e + +echo "🔧 Fixe i18n-Daten (lokal kopieren, fixen, zurück kopieren)..." +echo "" + +# Prüfe ob Container läuft +if ! docker ps | grep -q hoerdle; then + echo "❌ Container 'hoerdle' läuft nicht!" + exit 1 +fi + +# Backup erstellen +BACKUP_FILE="./data/prod.db.backup.$(date +%Y%m%d_%H%M%S)" +echo "💾 Erstelle Backup..." +docker cp hoerdle:/app/data/prod.db "$BACKUP_FILE" +echo "✅ Backup erstellt: $BACKUP_FILE" +echo "" + +# Kopiere DB lokal +echo "📥 Kopiere Datenbank lokal..." +docker cp hoerdle:/app/data/prod.db ./data/prod.db.tmp +echo "✅ Datenbank kopiert" +echo "" + +# Prüfe ob sqlite3 verfügbar ist +if ! command -v sqlite3 &> /dev/null; then + echo "❌ sqlite3 ist nicht installiert!" + echo " Installiere es mit: sudo apt-get install sqlite3" + exit 1 +fi + +# Fixe die Datenbank +echo "🔧 Fixe i18n-Daten..." +sqlite3 ./data/prod.db.tmp << 'SQL' +-- Backup innerhalb der DB +.backup ./data/prod.db.tmp.backup + +-- Fix Genre.name +UPDATE Genre +SET name = json_object('de', name, 'en', name) +WHERE typeof(name) = 'text' AND name NOT LIKE '{%'; + +-- Fix Genre.subtitle +UPDATE Genre +SET subtitle = json_object('de', subtitle, 'en', subtitle) +WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%'; + +-- Fix Special.name +UPDATE Special +SET name = json_object('de', name, 'en', name) +WHERE typeof(name) = 'text' AND name NOT LIKE '{%'; + +-- Fix Special.subtitle +UPDATE Special +SET subtitle = json_object('de', subtitle, 'en', subtitle) +WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%'; + +-- Fix News.title +UPDATE News +SET title = json_object('de', title, 'en', title) +WHERE typeof(title) = 'text' AND title NOT LIKE '{%'; + +-- Fix News.content +UPDATE News +SET content = json_object('de', content, 'en', content) +WHERE typeof(content) = 'text' AND content NOT LIKE '{%'; + +SELECT '✅ Alle i18n-Daten wurden gefixt!' as status; +SQL + +if [ $? -ne 0 ]; then + echo "❌ Fehler beim Fixen der Datenbank!" + exit 1 +fi + +echo "✅ Datenbank gefixt" +echo "" + +# Kopiere zurück +echo "📤 Kopiere gefixte Datenbank zurück..." +docker cp ./data/prod.db.tmp hoerdle:/app/data/prod.db +echo "✅ Datenbank zurück kopiert" +echo "" + +# Aufräumen +rm -f ./data/prod.db.tmp ./data/prod.db.tmp.backup + +echo "🔄 Starte Container neu..." +docker compose restart hoerdle +echo "" + +echo "✅ Fertig! Prüfe die Logs:" +echo " docker logs hoerdle --tail=50" + diff --git a/scripts/fix-i18n-simple.sh b/scripts/fix-i18n-simple.sh new file mode 100755 index 0000000..00c7ef7 --- /dev/null +++ b/scripts/fix-i18n-simple.sh @@ -0,0 +1,111 @@ +#!/bin/bash +# Einfaches Fix-Skript für i18n-Daten +# Kopiert SQL-Befehle direkt in den Container und führt sie aus + +set -e + +echo "🔧 Fixe i18n-Daten in der Datenbank..." +echo "" + +# Prüfe ob Container läuft +if ! docker ps | grep -q hoerdle; then + echo "❌ Container 'hoerdle' läuft nicht!" + exit 1 +fi + +# Erstelle temporäres SQL-Skript +SQL_SCRIPT=$(mktemp) +cat > "$SQL_SCRIPT" << 'EOF' +-- Backup erstellen (optional, aber empfohlen) +.backup /tmp/prod.db.backup + +-- Fix Genre.name: Konvertiere String zu JSON +UPDATE Genre +SET name = json_object('de', name, 'en', name) +WHERE typeof(name) = 'text' AND name NOT LIKE '{%'; + +-- Fix Genre.subtitle +UPDATE Genre +SET subtitle = json_object('de', subtitle, 'en', subtitle) +WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%'; + +-- Fix Special.name +UPDATE Special +SET name = json_object('de', name, 'en', name) +WHERE typeof(name) = 'text' AND name NOT LIKE '{%'; + +-- Fix Special.subtitle +UPDATE Special +SET subtitle = json_object('de', subtitle, 'en', subtitle) +WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%'; + +-- Fix News.title +UPDATE News +SET title = json_object('de', title, 'en', title) +WHERE typeof(title) = 'text' AND title NOT LIKE '{%'; + +-- Fix News.content +UPDATE News +SET content = json_object('de', content, 'en', content) +WHERE typeof(content) = 'text' AND content NOT LIKE '{%'; + +-- Zeige Erfolg +SELECT 'i18n-Daten wurden erfolgreich gefixt!' as status; +EOF + +echo "📝 Kopiere SQL-Skript in Container..." +docker cp "$SQL_SCRIPT" hoerdle:/tmp/fix-i18n.sql + +echo "🚀 Führe SQL-Befehle aus..." +echo "" + +# Prüfe ob sqlite3 im Container verfügbar ist +if docker exec hoerdle sh -c "command -v sqlite3" > /dev/null 2>&1; then + docker exec hoerdle sqlite3 /app/data/prod.db < /tmp/fix-i18n.sql + echo "" + echo "✅ i18n-Daten wurden erfolgreich gefixt!" +else + echo "⚠️ sqlite3 nicht im Container gefunden. Verwende alternativen Ansatz..." + + # Versuche mit Node.js direkt SQL auszuführen + cat > /tmp/fix-i18n-node.js << 'NODEJS' +const fs = require('fs'); +const DB_PATH = '/app/data/prod.db'; + +// Einfacher: Wir müssen sqlite3 im Container installieren oder einen anderen Weg finden +console.log('⚠️ sqlite3 ist nicht verfügbar. Bitte installiere es im Container oder verwende einen anderen Ansatz.'); +console.log(''); +console.log('Alternativ: Kopiere die Datenbank lokal, fixe sie dort, und kopiere sie zurück.'); +process.exit(1); +NODEJS + + docker cp /tmp/fix-i18n-node.js hoerdle:/tmp/fix-i18n-node.js + docker exec hoerdle node /tmp/fix-i18n-node.js || { + echo "" + echo "💡 Lösungsvorschlag:" + echo "1. Kopiere die Datenbank lokal:" + echo " docker cp hoerdle:/app/data/prod.db ./data/prod.db" + echo "" + echo "2. Führe dieses Skript lokal aus (mit sqlite3):" + echo " sqlite3 ./data/prod.db < $SQL_SCRIPT" + echo "" + echo "3. Kopiere die gefixte DB zurück:" + echo " docker cp ./data/prod.db hoerdle:/app/data/prod.db" + echo "" + echo "4. Starte Container neu:" + echo " docker compose restart hoerdle" + rm -f "$SQL_SCRIPT" + exit 1 + } +fi + +rm -f "$SQL_SCRIPT" + +echo "" +echo "🔄 Starte Container neu..." +docker compose restart hoerdle 2>/dev/null || echo " (Bitte manuell: docker compose restart hoerdle)" + +echo "" +echo "✅ Fertig! Prüfe die Logs:" +echo " docker logs hoerdle --tail=50" + diff --git a/scripts/fix-i18n-sql.sh b/scripts/fix-i18n-sql.sh new file mode 100755 index 0000000..3e96e00 --- /dev/null +++ b/scripts/fix-i18n-sql.sh @@ -0,0 +1,119 @@ +#!/bin/bash +# Direkter SQL-Fix für i18n-Daten in SQLite +# Konvertiert String-Werte zu JSON-Format + +set -e + +DB_PATH="./data/prod.db" +BACKUP_PATH="./data/prod.db.backup.$(date +%Y%m%d_%H%M%S)" + +if [ ! -f "$DB_PATH" ]; then + echo "❌ Datenbank nicht gefunden: $DB_PATH" + exit 1 +fi + +echo "🔧 Fixe i18n-Daten in SQLite-Datenbank..." +echo "" + +# Backup erstellen +echo "💾 Erstelle Backup..." +cp "$DB_PATH" "$BACKUP_PATH" +echo "✅ Backup erstellt: $BACKUP_PATH" +echo "" + +# Prüfe ob sqlite3 verfügbar ist +if ! command -v sqlite3 &> /dev/null; then + echo "⚠️ sqlite3 nicht gefunden. Versuche im Container..." + + # Führe SQL-Befehle im Container aus + docker exec hoerdle sh << 'EOF' +# SQL-Befehle +sqlite3 /app/data/prod.db << 'SQL' +-- Backup erstellen +.backup /app/data/prod.db.backup + +-- Fix Genre.name +UPDATE Genre +SET name = json_object('de', name, 'en', name) +WHERE typeof(name) = 'text' AND name NOT LIKE '{%'; + +-- Fix Genre.subtitle +UPDATE Genre +SET subtitle = json_object('de', subtitle, 'en', subtitle) +WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%'; + +-- Fix Special.name +UPDATE Special +SET name = json_object('de', name, 'en', name) +WHERE typeof(name) = 'text' AND name NOT LIKE '{%'; + +-- Fix Special.subtitle +UPDATE Special +SET subtitle = json_object('de', subtitle, 'en', subtitle) +WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%'; + +-- Fix News.title +UPDATE News +SET title = json_object('de', title, 'en', title) +WHERE typeof(title) = 'text' AND title NOT LIKE '{%'; + +-- Fix News.content +UPDATE News +SET content = json_object('de', content, 'en', content) +WHERE typeof(content) = 'text' AND content NOT LIKE '{%'; + +-- Zeige Änderungen +SELECT 'Genre.name gefixt:' as status, COUNT(*) as count +FROM Genre WHERE typeof(name) = 'text' AND name LIKE '{%'; +SQL +EOF + + if [ $? -eq 0 ]; then + echo "✅ i18n-Daten wurden erfolgreich gefixt!" + else + echo "❌ Fehler beim Ausführen der SQL-Befehle" + exit 1 + fi +else + # Führe direkt auf dem Host aus + sqlite3 "$DB_PATH" << 'SQL' +-- Fix Genre.name +UPDATE Genre +SET name = json_object('de', name, 'en', name) +WHERE typeof(name) = 'text' AND name NOT LIKE '{%'; + +-- Fix Genre.subtitle +UPDATE Genre +SET subtitle = json_object('de', subtitle, 'en', subtitle) +WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%'; + +-- Fix Special.name +UPDATE Special +SET name = json_object('de', name, 'en', name) +WHERE typeof(name) = 'text' AND name NOT LIKE '{%'; + +-- Fix Special.subtitle +UPDATE Special +SET subtitle = json_object('de', subtitle, 'en', subtitle) +WHERE subtitle IS NOT NULL AND typeof(subtitle) = 'text' AND subtitle NOT LIKE '{%'; + +-- Fix News.title +UPDATE News +SET title = json_object('de', title, 'en', title) +WHERE typeof(title) = 'text' AND title NOT LIKE '{%'; + +-- Fix News.content +UPDATE News +SET content = json_object('de', content, 'en', content) +WHERE typeof(content) = 'text' AND content NOT LIKE '{%'; + +SELECT 'Fertig!' as status; +SQL + + echo "✅ i18n-Daten wurden erfolgreich gefixt!" +fi + +echo "" +echo "🔄 Bitte starte den Container neu:" +echo " docker compose restart hoerdle" +