import { NextRequest, NextResponse } from 'next/server' import { prisma } from '@/lib/db' import { uploadFile } from '@/lib/minio' import { getSession, isAdmin } from '@/lib/auth' import { v4 as uuidv4 } from 'uuid' const ALLOWED_TYPES = ['image/png', 'image/svg+xml', 'image/jpeg', 'image/webp'] const MAX_SIZE = 5 * 1024 * 1024 // 5MB export async function POST(req: NextRequest) { try { const user = await getSession() if (!user || (user.role !== 'SERVER_ADMIN' && user.role !== 'TENANT_ADMIN')) { return NextResponse.json({ error: 'Nicht autorisiert' }, { status: 403 }) } const formData = await req.formData() const file = formData.get('file') as File | null const categoryId = formData.get('categoryId') as string const iconType = (formData.get('iconType') as string) || 'STANDARD' const name = formData.get('name') as string if (!file || !categoryId || !name) { return NextResponse.json( { error: 'Datei, Kategorie und Name sind erforderlich' }, { status: 400 } ) } if (!ALLOWED_TYPES.includes(file.type)) { return NextResponse.json( { error: 'Nur PNG, SVG, JPEG und WebP Dateien erlaubt' }, { status: 400 } ) } if (file.size > MAX_SIZE) { return NextResponse.json( { error: 'Datei zu groß (max. 5MB)' }, { status: 400 } ) } // Check category exists const category = await (prisma as any).iconCategory.findUnique({ where: { id: categoryId }, }) if (!category) { return NextResponse.json( { error: 'Kategorie nicht gefunden' }, { status: 404 } ) } // Generate safe filename const ext = file.name.split('.').pop()?.toLowerCase() || 'png' const isTenantAdmin = user.role === 'TENANT_ADMIN' const prefix = isTenantAdmin ? `tenant-${user.tenantId}/icons` : 'icons' const safeFileName = `${uuidv4()}.${ext}` const fileKey = `${prefix}/${safeFileName}` // Upload to MinIO const buffer = Buffer.from(await file.arrayBuffer()) await uploadFile(fileKey, buffer, file.type) // Save to DB const icon = await (prisma as any).iconAsset.create({ data: { name: name.trim(), categoryId, iconType: iconType as any, fileKey, mimeType: file.type, isSystem: !isTenantAdmin, // true für Server Admin, false für Tenant Admin tenantId: isTenantAdmin ? user.tenantId : null, ownerId: user.id, }, include: { category: true, }, }) return NextResponse.json({ icon }, { status: 201 }) } catch (error) { console.error('Error uploading icon:', error) return NextResponse.json({ error: 'Upload fehlgeschlagen' }, { status: 500 }) } }