Files
Lageplan/prisma/recover-symbols.js

218 lines
7.2 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Recovery-Skript für gelöschte Symbole
*
* ACHTUNG: Dieses Skript kann die Symbole in der Sidebar wiederherstellen,
* aber BESTEHENDE ZEICHNUNGEN (Features) bleiben broken, weil die alten
* iconId-UUIDs in den Feature-Properties für immer verloren sind.
*
* Ausführung:
* node prisma/recover-symbols.js
*
* Umgebung:
* DATABASE_URL muss gesetzt sein (oder .env.docker geladen werden)
*/
const { PrismaClient } = require('@prisma/client')
const fs = require('fs')
const path = require('path')
const prisma = new PrismaClient()
const SVG_DIR = path.join(__dirname, '..', 'public', 'signaturen')
// Kategorie-Definitionen (wie im Original-Seed)
const catDefs = [
{
name: 'Wasser',
description: 'Wasser, Hydranten, Leitungen',
sortOrder: 2,
patterns: ['Wasser', 'Hydrant', 'Reservoir', 'Druckleitung', 'Druckleistung', 'Transportleitung',
'Oberflurhydrant', 'Unterflurhydrant', 'Innenhydrant', 'Wasserloeschposten', 'Wasserversorgung',
'Moeglicher_Wasserbezugsort', 'Stehendes_Gewaesser', 'Schieber'],
},
{
name: 'Feuer',
description: 'Brand, Feuerwehr, Entwicklung',
sortOrder: 3,
patterns: ['Feuer', 'Brandherd', 'Entwicklungsgrenze', 'Horizontale_Entwicklung', 'Vertikale'],
},
{
name: 'Gefahr / Stoffe',
description: 'Chemie, Gas, Biologie, Strom',
sortOrder: 4,
patterns: ['Chemie', 'Chemikalien', 'Biologische', 'Gas', 'Elektrizitaet', 'Gefaehrliche',
'Explosion', 'Gefahr_durch_Loeschen'],
},
{
name: 'Technik / Gebäude',
description: 'Lifte, Türen, Treppen, Tableaus',
sortOrder: 5,
patterns: ['Lift', 'Treppe', 'Eingang', 'Tableau', 'Entrauchung', 'Sprinkler', 'Kamin',
'Brandmeldezentrale', 'Brandschutztueren', 'Elektrotableau', 'Fernsignaltableau',
'Luefter', 'Decke_eingestuerzt', 'AnzahlGeschosse'],
},
{
name: 'Gebäude / Schäden',
description: 'Gebäude, Zerstörung, Schäden',
sortOrder: 6,
patterns: ['Beschaedigung', 'Teilzerstoerung', 'Totalzerstoerung', 'Bruecke'],
},
{
name: 'Einsatzführung',
description: 'Führung, Organisation, Kommunikation',
sortOrder: 7,
patterns: ['Einsatzleiter', 'ADL', 'KP_', 'Kontrollstelle', 'Informationszentrum',
'Medienkontaktstelle', 'Sanitaet', 'Sanitaetshilfsstelle', 'Totensammelstelle',
'Materialdepot', 'Schluesseldepot', 'Sammelstelle', 'Sammelplatz', 'Beobachtungsposten'],
},
{
name: 'Fahrzeuge / Geräte',
description: 'Feuerwehrfahrzeuge, Leitern, Geräte',
sortOrder: 8,
patterns: ['TLF', 'HRF', 'Anhaengeleiter', 'Leiter', 'Sprungretter', 'Kleinloeschgeraet',
'SWHP', 'MS_de'],
},
{
name: 'Kommunikation / Sonstiges',
description: 'Funk, Wind, Massstab, etc.',
sortOrder: 9,
patterns: ['Funk', 'Windrichtung', 'Nordrichtung', 'Massstab', 'Helikopter', 'Armee',
'Zivilschutz', 'Rettungen', 'Unfall', 'Rutschgebiet', 'Ueberschwemmung',
'Abschnitt', 'Absperrung', 'Achtung', 'Anmarsch'],
},
]
function findCategory(filename) {
const base = filename.replace(/\.svg$/i, '')
for (const cat of catDefs) {
for (const p of cat.patterns) {
if (base.toLowerCase().includes(p.toLowerCase())) return cat.name
}
}
return 'Sonstiges'
}
async function recover() {
console.log('🚨 SYMBOL RECOVERY STARTED')
console.log('')
console.log('⚠️ WARNUNG: Bestehende Zeichnungen bleiben broken!')
console.log(' Die alten iconId-UUIDs in den Feature-Properties sind verloren.')
console.log(' Benutzer müssen Symbole in Zeichnungen manuell neu setzen.')
console.log('')
// ─── 1. Lade SVG-Dateien ───
if (!fs.existsSync(SVG_DIR)) {
console.error('❌ SVG-Verzeichnis nicht gefunden:', SVG_DIR)
process.exit(1)
}
const files = fs.readdirSync(SVG_DIR).filter(f => f.endsWith('.svg'))
console.log(`📁 ${files.length} SVG-Dateien gefunden`)
// ─── 2. Erstelle Icon-Categories ───
console.log('\n📂 Erstelle Icon-Categories...')
const categoryMap = {}
for (const def of catDefs) {
const cat = await prisma.iconCategory.upsert({
where: { name: def.name },
update: {},
create: {
name: def.name,
description: def.description,
sortOrder: def.sortOrder,
isGlobal: true,
},
})
categoryMap[def.name] = cat.id
console.log(`${cat.name}`)
}
// Sonstiges-Kategorie
const sonstiges = await prisma.iconCategory.upsert({
where: { name: 'Sonstiges' },
update: {},
create: { name: 'Sonstiges', sortOrder: 99, isGlobal: true },
})
categoryMap['Sonstiges'] = sonstiges.id
// ─── 3. Erstelle IconAssets ───
console.log('\n🖼 Erstelle IconAssets...')
const iconMap = {} // fileKey -> icon.id
for (const file of files) {
const filePath = path.join(SVG_DIR, file)
const stats = fs.statSync(filePath)
const fileKey = `lageplan-icons/symbols/${file}`
const name = file.replace(/\.svg$/i, '').replace(/_/g, ' ')
const catName = findCategory(file)
const categoryId = categoryMap[catName]
const icon = await prisma.iconAsset.upsert({
where: { fileKey },
update: {
name,
mimeType: 'image/svg+xml',
isSystem: true,
isActive: true,
iconType: 'STANDARD',
categoryId,
},
create: {
name,
fileKey,
mimeType: 'image/svg+xml',
isSystem: true,
isActive: true,
iconType: 'STANDARD',
categoryId,
},
})
iconMap[fileKey] = icon.id
}
console.log(`${files.length} IconAssets erstellt/aktualisiert`)
// ─── 4. Aktiviere alle Icons für alle Tenants ───
console.log('\n🏢 Aktiviere Symbole für alle Tenants...')
const tenants = await prisma.tenant.findMany({ select: { id: true, name: true } })
let tsCount = 0
for (const tenant of tenants) {
for (const [fileKey, iconId] of Object.entries(iconMap)) {
await prisma.tenantSymbol.upsert({
where: {
tenantId_iconId: {
tenantId: tenant.id,
iconId: iconId,
},
},
update: { isActive: true },
create: {
tenantId: tenant.id,
iconId: iconId,
isActive: true,
},
})
tsCount++
}
console.log(`${tenant.name}: ${Object.keys(iconMap).length} Symbole aktiviert`)
}
// ─── 5. Zeichnungen (Features) — Hinweis ───
console.log('\n⚠ FEATURES / ZEICHNUNGEN:')
const featureCount = await prisma.feature.count({ where: { type: 'symbol' } })
console.log(` ${featureCount} Symbol-Features in der Datenbank gefunden.`)
console.log(` Diese zeigen auf GELÖSCHTE iconId-UUIDs und bleiben BROKEN.`)
console.log(` Es gibt KEINE Möglichkeit, die alten UUIDs wiederherzustellen.`)
console.log(` Benutzer müssen Symbole in ihren Zeichnungen manuell neu setzen.`)
console.log('\n✅ RECOVERY ABGESCHLOSSEN')
console.log(' - Symbole sind jetzt in der Sidebar verfügbar')
console.log(' - Admin → Symbol-Manager zeigt alle Symbole an')
console.log(' - Zeichnungen müssen manuell repariert werden')
}
recover()
.then(async () => { await prisma.$disconnect() })
.catch(async (e) => {
console.error('Recovery error:', e)
await prisma.$disconnect()
process.exit(1)
})