157 lines
6.3 KiB
TypeScript
157 lines
6.3 KiB
TypeScript
import { PrismaClient, Role } from '@prisma/client'
|
|
import bcrypt from 'bcryptjs'
|
|
|
|
const prisma = new PrismaClient()
|
|
|
|
async function main() {
|
|
console.log('🌱 Starting seed...')
|
|
|
|
// Create default users
|
|
const adminPassword = await bcrypt.hash('admin123', 12)
|
|
const editorPassword = await bcrypt.hash('editor123', 12)
|
|
const viewerPassword = await bcrypt.hash('viewer123', 12)
|
|
|
|
const admin = await prisma.user.upsert({
|
|
where: { email: 'admin@lageplan.local' },
|
|
update: {},
|
|
create: {
|
|
email: 'admin@lageplan.local',
|
|
name: 'Administrator',
|
|
password: adminPassword,
|
|
role: Role.ADMIN,
|
|
},
|
|
})
|
|
|
|
const editor = await prisma.user.upsert({
|
|
where: { email: 'editor@lageplan.local' },
|
|
update: {},
|
|
create: {
|
|
email: 'editor@lageplan.local',
|
|
name: 'Einsatzleiter',
|
|
password: editorPassword,
|
|
role: Role.EDITOR,
|
|
},
|
|
})
|
|
|
|
const viewer = await prisma.user.upsert({
|
|
where: { email: 'viewer@lageplan.local' },
|
|
update: {},
|
|
create: {
|
|
email: 'viewer@lageplan.local',
|
|
name: 'Beobachter',
|
|
password: viewerPassword,
|
|
role: Role.VIEWER,
|
|
},
|
|
})
|
|
|
|
console.log('✅ Users created:', { admin: admin.email, editor: editor.email, viewer: viewer.email })
|
|
|
|
// Create icon categories
|
|
const categories = [
|
|
{ name: 'Feuer', description: 'Brand- und Feuersymbole', sortOrder: 1 },
|
|
{ name: 'Wasser', description: 'Wasser- und Überflutungssymbole', sortOrder: 2 },
|
|
{ name: 'Gefahrstoffe', description: 'Chemie- und Gefahrstoffsymbole', sortOrder: 3 },
|
|
{ name: 'Verkehr', description: 'Verkehrs- und Unfallsymbole', sortOrder: 4 },
|
|
{ name: 'Personen', description: 'Personen- und Rettungssymbole', sortOrder: 5 },
|
|
{ name: 'Fahrzeuge', description: 'Einsatzfahrzeuge und Geräte', sortOrder: 6 },
|
|
{ name: 'Infrastruktur', description: 'Gebäude und Infrastruktursymbole', sortOrder: 7 },
|
|
{ name: 'Taktik', description: 'Taktische Zeichen und Symbole', sortOrder: 8 },
|
|
{ name: 'Eigene', description: 'Benutzerdefinierte Symbole', sortOrder: 99 },
|
|
]
|
|
|
|
for (const cat of categories) {
|
|
await prisma.iconCategory.upsert({
|
|
where: { name: cat.name },
|
|
update: { description: cat.description, sortOrder: cat.sortOrder },
|
|
create: cat,
|
|
})
|
|
}
|
|
|
|
console.log('✅ Icon categories created:', categories.length)
|
|
|
|
// Get category IDs for system icons
|
|
const feuerCat = await prisma.iconCategory.findUnique({ where: { name: 'Feuer' } })
|
|
const wasserCat = await prisma.iconCategory.findUnique({ where: { name: 'Wasser' } })
|
|
const gefahrstoffeCat = await prisma.iconCategory.findUnique({ where: { name: 'Gefahrstoffe' } })
|
|
const verkehrCat = await prisma.iconCategory.findUnique({ where: { name: 'Verkehr' } })
|
|
const personenCat = await prisma.iconCategory.findUnique({ where: { name: 'Personen' } })
|
|
const fahrzeugeCat = await prisma.iconCategory.findUnique({ where: { name: 'Fahrzeuge' } })
|
|
const infrastrukturCat = await prisma.iconCategory.findUnique({ where: { name: 'Infrastruktur' } })
|
|
const taktikCat = await prisma.iconCategory.findUnique({ where: { name: 'Taktik' } })
|
|
|
|
// Create system icons (these use inline SVG data URIs - in production, upload to MinIO)
|
|
const systemIcons = [
|
|
{ name: 'Brand', categoryId: feuerCat!.id, fileKey: 'system/fire.svg' },
|
|
{ name: 'Rauch', categoryId: feuerCat!.id, fileKey: 'system/smoke.svg' },
|
|
{ name: 'Explosion', categoryId: feuerCat!.id, fileKey: 'system/explosion.svg' },
|
|
{ name: 'Brandstelle', categoryId: feuerCat!.id, fileKey: 'system/fire-location.svg' },
|
|
{ name: 'Überflutung', categoryId: wasserCat!.id, fileKey: 'system/flood.svg' },
|
|
{ name: 'Wasserschaden', categoryId: wasserCat!.id, fileKey: 'system/water-damage.svg' },
|
|
{ name: 'Hydrant', categoryId: wasserCat!.id, fileKey: 'system/hydrant.svg' },
|
|
{ name: 'Gefahrstoff', categoryId: gefahrstoffeCat!.id, fileKey: 'system/hazmat.svg' },
|
|
{ name: 'Radioaktiv', categoryId: gefahrstoffeCat!.id, fileKey: 'system/radioactive.svg' },
|
|
{ name: 'Giftig', categoryId: gefahrstoffeCat!.id, fileKey: 'system/toxic.svg' },
|
|
{ name: 'Unfall', categoryId: verkehrCat!.id, fileKey: 'system/accident.svg' },
|
|
{ name: 'Strassensperre', categoryId: verkehrCat!.id, fileKey: 'system/road-block.svg' },
|
|
{ name: 'Verletzte Person', categoryId: personenCat!.id, fileKey: 'system/injured.svg' },
|
|
{ name: 'Vermisste Person', categoryId: personenCat!.id, fileKey: 'system/missing.svg' },
|
|
{ name: 'Sammelplatz', categoryId: personenCat!.id, fileKey: 'system/assembly-point.svg' },
|
|
{ name: 'Löschfahrzeug', categoryId: fahrzeugeCat!.id, fileKey: 'system/fire-truck.svg' },
|
|
{ name: 'Rettungswagen', categoryId: fahrzeugeCat!.id, fileKey: 'system/ambulance.svg' },
|
|
{ name: 'Kommandoposten', categoryId: taktikCat!.id, fileKey: 'system/command-post.svg' },
|
|
{ name: 'Einsatzleitung', categoryId: taktikCat!.id, fileKey: 'system/incident-command.svg' },
|
|
{ name: 'Absperrung', categoryId: taktikCat!.id, fileKey: 'system/barrier.svg' },
|
|
{ name: 'Gebäude', categoryId: infrastrukturCat!.id, fileKey: 'system/building.svg' },
|
|
{ name: 'Eingang', categoryId: infrastrukturCat!.id, fileKey: 'system/entrance.svg' },
|
|
]
|
|
|
|
for (const icon of systemIcons) {
|
|
const existing = await prisma.iconAsset.findFirst({
|
|
where: { fileKey: icon.fileKey },
|
|
})
|
|
if (!existing) {
|
|
await prisma.iconAsset.create({
|
|
data: {
|
|
name: icon.name,
|
|
categoryId: icon.categoryId,
|
|
fileKey: icon.fileKey,
|
|
mimeType: 'image/svg+xml',
|
|
isSystem: true,
|
|
width: 48,
|
|
height: 48,
|
|
},
|
|
})
|
|
}
|
|
}
|
|
|
|
console.log('✅ System icons created:', systemIcons.length)
|
|
|
|
// Create a demo project
|
|
const demoProject = await prisma.project.upsert({
|
|
where: { id: 'demo-project-001' },
|
|
update: {},
|
|
create: {
|
|
id: 'demo-project-001',
|
|
title: 'Demo Einsatz - Wohnungsbrand',
|
|
location: 'Musterstrasse 42, 8000 Zürich',
|
|
description: 'Beispiel-Einsatz zur Demonstration der Funktionen',
|
|
ownerId: editor.id,
|
|
mapCenter: { lng: 8.5417, lat: 47.3769 },
|
|
mapZoom: 17,
|
|
},
|
|
})
|
|
|
|
console.log('✅ Demo project created:', demoProject.title)
|
|
|
|
console.log('🎉 Seed completed successfully!')
|
|
}
|
|
|
|
main()
|
|
.catch((e) => {
|
|
console.error('❌ Seed failed:', e)
|
|
process.exit(1)
|
|
})
|
|
.finally(async () => {
|
|
await prisma.$disconnect()
|
|
})
|