All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 14m40s
124 lines
3.2 KiB
TypeScript
124 lines
3.2 KiB
TypeScript
/**
|
|
* Seed-Skript: Erstellt SymbolTemplate-Einträge aus bestehenden IconAsset (isSystem=true)
|
|
* oder aus dem Dateisystem (public/signaturen/*.svg).
|
|
*
|
|
* Ausführen:
|
|
* npx ts-node prisma/seed-symbol-templates.ts
|
|
* oder als Teil des Deployments via npx prisma db seed
|
|
*
|
|
* Idempotent: bereits existierende Templates werden übersprungen.
|
|
*/
|
|
|
|
import { PrismaClient } from '@prisma/client'
|
|
import { readdirSync, statSync } from 'fs'
|
|
import { join } from 'path'
|
|
|
|
const prisma = new PrismaClient()
|
|
|
|
const SIGNATUREN_DIR = join(process.cwd(), 'public', 'signaturen')
|
|
const PACKAGE_ID = 'feuerwehr-ch'
|
|
const PACKAGE_NAME = 'Feuerwehr Schweiz'
|
|
|
|
/**
|
|
* Versucht Kategorie-Namen aus bestehenden IconAsset / IconCategory abzuleiten.
|
|
* Fallback: "Sonstiges"
|
|
*/
|
|
async function getCategoryMapping(): Promise<Map<string, string>> {
|
|
const mapping = new Map<string, string>()
|
|
|
|
const iconAssets = await (prisma as any).iconAsset.findMany({
|
|
where: { isSystem: true },
|
|
include: { category: { select: { name: true } } },
|
|
})
|
|
|
|
for (const asset of iconAssets) {
|
|
const fileName = asset.fileKey.replace(/^signaturen\//, '').replace(/\.svg$/i, '')
|
|
const categoryName = asset.category?.name || 'Sonstiges'
|
|
mapping.set(fileName.toLowerCase(), categoryName)
|
|
}
|
|
|
|
return mapping
|
|
}
|
|
|
|
/**
|
|
* Liest alle .svg Dateien aus public/signaturen/
|
|
*/
|
|
function getSvgFiles(dir: string): string[] {
|
|
const files: string[] = []
|
|
try {
|
|
const entries = readdirSync(dir)
|
|
for (const entry of entries) {
|
|
const fullPath = join(dir, entry)
|
|
const stat = statSync(fullPath)
|
|
if (stat.isFile() && entry.endsWith('.svg')) {
|
|
files.push(entry)
|
|
}
|
|
}
|
|
} catch (err) {
|
|
console.warn('Could not read signaturen directory:', (err as Error).message)
|
|
}
|
|
return files.sort()
|
|
}
|
|
|
|
async function main() {
|
|
console.log('🌱 Seeding SymbolTemplate...')
|
|
|
|
const categoryMapping = await getCategoryMapping()
|
|
const svgFiles = getSvgFiles(SIGNATUREN_DIR)
|
|
|
|
console.log(`Found ${svgFiles.length} SVG files in public/signaturen/`)
|
|
console.log(`IconAsset mapping covers ${categoryMapping.size} entries`)
|
|
|
|
let created = 0
|
|
let skipped = 0
|
|
|
|
for (let i = 0; i < svgFiles.length; i++) {
|
|
const fileName = svgFiles[i]
|
|
const nameWithoutExt = fileName.replace(/\.svg$/i, '')
|
|
const displayName = nameWithoutExt
|
|
.replace(/_/g, ' ')
|
|
.replace(/-/g, ' ')
|
|
.replace(/([a-z])([A-Z])/g, '$1 $2')
|
|
|
|
const fileKey = `signaturen/${fileName}`
|
|
|
|
// Check if already exists
|
|
const existing = await (prisma as any).symbolTemplate.findFirst({
|
|
where: { svgPath: fileKey },
|
|
})
|
|
|
|
if (existing) {
|
|
skipped++
|
|
continue
|
|
}
|
|
|
|
const categoryName =
|
|
categoryMapping.get(nameWithoutExt.toLowerCase()) || 'Sonstiges'
|
|
|
|
await (prisma as any).symbolTemplate.create({
|
|
data: {
|
|
packageId: PACKAGE_ID,
|
|
packageName: PACKAGE_NAME,
|
|
categoryName,
|
|
name: displayName,
|
|
svgPath: fileKey,
|
|
tags: [nameWithoutExt.toLowerCase(), categoryName.toLowerCase()],
|
|
sortOrder: i,
|
|
},
|
|
})
|
|
|
|
created++
|
|
}
|
|
|
|
console.log(`✅ Done: ${created} created, ${skipped} skipped`)
|
|
}
|
|
|
|
main()
|
|
.catch((e) => {
|
|
console.error(e)
|
|
process.exit(1)
|
|
})
|
|
.finally(async () => {
|
|
await prisma.$disconnect()
|
|
})
|