hotfix(1.4.2): admin empty + legacy symbol migration
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 20m44s
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 20m44s
This commit is contained in:
@@ -3,6 +3,12 @@
|
||||
Alle nennenswerten Änderungen an diesem Projekt werden in dieser Datei dokumentiert.
|
||||
Das Format basiert auf [Keep a Changelog](https://keepachangelog.com/de/1.0.0/).
|
||||
|
||||
## [1.4.2] – 2026-05-20 — Hotfix: Admin leer & Legacy-Symbole
|
||||
|
||||
### Behoben
|
||||
- **Admin Symbol-Manager**: Liest jetzt korrekt `categories` statt `groups` aus der API-Response von `/api/tenant/symbols?grouped=true`.
|
||||
- **Datenmigration (Step 18)**: Neue Migration in `prisma/migrate.js` migriert bestehende `tenantSymbols` automatisch: setzt fehlende `name`, `svgPath`, `categoryId` (Default-Kategorie „Meine Symbole“) und `migratedFromIconId`. Behebt „Leichen“ mit broken images.
|
||||
|
||||
## [1.4.1] – 2026-05-20 — Hotfix: Production 500 & Null-Crash
|
||||
|
||||
### Behoben
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "lageplan",
|
||||
"version": "1.4.1",
|
||||
"version": "1.4.2",
|
||||
"description": "Feuerwehr Lageplan - Krokier-App für Einsatzdokumentation",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -344,6 +344,62 @@ async function migrate() {
|
||||
console.log(' Unique constraint drop skipped:', e.message)
|
||||
}
|
||||
|
||||
// ─── Step 18: Migrate legacy tenantSymbols (name, svgPath, categoryId, migratedFromIconId) ───
|
||||
console.log(' [18] Migrating legacy tenantSymbols data...')
|
||||
try {
|
||||
const tenantsWithSymbols = await prisma.$queryRawUnsafe(`
|
||||
SELECT "tenantId", COUNT(id) as cnt FROM tenant_symbols GROUP BY "tenantId"
|
||||
`)
|
||||
let catsCreated = 0
|
||||
let symsMigrated = 0
|
||||
for (const row of tenantsWithSymbols) {
|
||||
const tenantId = row.tenantId
|
||||
// Create default category if none exists for this tenant
|
||||
let defaultCat = await prisma.$queryRawUnsafe(`
|
||||
SELECT id FROM tenant_categories WHERE "tenantId" = '${tenantId}' AND name = 'Meine Symbole' LIMIT 1
|
||||
`)
|
||||
if (!defaultCat || !defaultCat.length) {
|
||||
const newCatId = crypto.randomUUID()
|
||||
await prisma.$executeRawUnsafe(`
|
||||
INSERT INTO tenant_categories (id, "tenantId", name, "sortOrder", "createdAt", "updatedAt")
|
||||
VALUES ('${newCatId}', '${tenantId}', 'Meine Symbole', 0, NOW(), NOW())
|
||||
`)
|
||||
defaultCat = [{ id: newCatId }]
|
||||
catsCreated++
|
||||
}
|
||||
const catId = defaultCat[0].id
|
||||
|
||||
// Migrate symbols: set name, svgPath, categoryId, migratedFromIconId where null
|
||||
await prisma.$executeRawUnsafe(`
|
||||
UPDATE tenant_symbols ts
|
||||
SET
|
||||
name = COALESCE(ts.name, ts."customName", ia.name, 'Unbenannt'),
|
||||
"svgPath" = COALESCE(ts."svgPath", ia."fileKey"),
|
||||
"categoryId" = COALESCE(ts."categoryId", '${catId}'),
|
||||
"migratedFromIconId" = COALESCE(ts."migratedFromIconId", ts."iconId"),
|
||||
"updatedAt" = NOW()
|
||||
FROM icon_assets ia
|
||||
WHERE ts."tenantId" = '${tenantId}'
|
||||
AND ia.id = ts."iconId"
|
||||
AND (ts.name IS NULL OR ts."svgPath" IS NULL OR ts."categoryId" IS NULL OR ts."migratedFromIconId" IS NULL)
|
||||
`)
|
||||
// Also handle symbols where iconId is already null (orphaned) — at least set category & name
|
||||
await prisma.$executeRawUnsafe(`
|
||||
UPDATE tenant_symbols
|
||||
SET
|
||||
name = COALESCE(name, "customName", 'Unbenannt'),
|
||||
"categoryId" = COALESCE("categoryId", '${catId}'),
|
||||
"updatedAt" = NOW()
|
||||
WHERE "tenantId" = '${tenantId}'
|
||||
AND (name IS NULL OR "categoryId" IS NULL)
|
||||
`)
|
||||
symsMigrated++
|
||||
}
|
||||
console.log(` ✅ ${catsCreated} default categories created, ${symsMigrated} tenants processed`)
|
||||
} catch (e) {
|
||||
console.log(' Legacy migration skipped:', e.message)
|
||||
}
|
||||
|
||||
console.log('✅ Database migrations complete')
|
||||
}
|
||||
|
||||
|
||||
@@ -121,8 +121,10 @@ export function SymbolManager() {
|
||||
}
|
||||
if (symRes.ok) {
|
||||
const s = await symRes.json()
|
||||
setSymbolGroups(s.groups || [])
|
||||
setFlatSymbols(s.symbols || [])
|
||||
setSymbolGroups(s.categories || [])
|
||||
// Flatten all symbols from categories for ungrouped / category-management views
|
||||
const all = (s.categories || []).flatMap((c: any) => c.symbols || [])
|
||||
setFlatSymbols(all)
|
||||
}
|
||||
if (tplRes.ok) {
|
||||
const t = await tplRes.json()
|
||||
|
||||
Reference in New Issue
Block a user