// app/api/users/route.ts import { NextRequest, NextResponse } from 'next/server'; import { prisma } from '@/lib/prisma'; import type { User, UserGroup } from '@/generated/prisma/client'; type GroupWithUsers = UserGroup & { users: User[] }; // GET bleibt wie gehabt export async function GET() { try { const [groupsRaw, ungrouped] = await Promise.all([ prisma.userGroup.findMany({ orderBy: { name: 'asc' }, include: { users: { orderBy: [{ lastName: 'asc' }, { firstName: 'asc' }], }, }, }), prisma.user.findMany({ where: { groupId: null }, orderBy: [{ lastName: 'asc' }, { firstName: 'asc' }], }), ]); const groups = groupsRaw as GroupWithUsers[]; const allGroups = groups.map((g) => ({ id: g.id, name: g.name })); return NextResponse.json( { groups, ungrouped, allGroups, }, { status: 200 }, ); } catch (err) { console.error('[GET /api/users]', err); return NextResponse.json( { error: 'Interner Serverfehler beim Laden der User.' }, { status: 500 }, ); } } // 🔹 POST: Single + Bulk export async function POST(req: NextRequest) { try { const body = await req.json(); // 🔹 BULK: { users: [...] } if (Array.isArray((body as any)?.users)) { type UserPayload = { nwkennung: string; email?: string | null; arbeitsname: string; firstName: string; lastName: string; groupId?: string | null; }; const users = (body as any).users as UserPayload[]; let createdCount = 0; let skippedCount = 0; const errors: { nwkennung: string; error: string }[] = []; for (const u of users) { const { nwkennung, email, arbeitsname, firstName, lastName, groupId, } = u; if (!nwkennung || !lastName || !firstName || !arbeitsname) { skippedCount++; errors.push({ nwkennung: nwkennung ?? '', error: 'nwkennung, lastName, firstName und arbeitsname sind Pflichtfelder.', }); continue; } const normalizedNwkennung = nwkennung.trim().toLowerCase(); try { await prisma.user.upsert({ where: { nwkennung: normalizedNwkennung }, update: { lastName, firstName, arbeitsname, groupId: groupId ?? null, email: email ?? undefined, }, create: { nwkennung: normalizedNwkennung, lastName, firstName, arbeitsname, groupId: groupId ?? null, email: email ?? null, }, }); createdCount++; } catch (err) { console.error( '[POST /api/users] Fehler bei Bulk-Upsert:', err, ); skippedCount++; errors.push({ nwkennung: normalizedNwkennung, error: 'Datenbankfehler beim Upsert.', }); } } return NextResponse.json( { success: true, createdCount, skippedCount, errors, }, { status: 200 }, ); } // 🔹 SINGLE: wie bisher (z.B. für manuelle Anlage) const single = body as { nwkennung?: string | null; email?: string | null; arbeitsname: string; firstName: string; lastName: string; groupId?: string | null; }; const { nwkennung, email, arbeitsname, firstName, lastName, groupId, } = single; if (!nwkennung || !lastName || !firstName || !arbeitsname) { return NextResponse.json( { error: 'nwkennung, lastName, firstName und arbeitsname sind Pflichtfelder.', }, { status: 400 }, ); } const normalizedNwkennung = nwkennung.trim().toLowerCase(); const user = await prisma.user.upsert({ where: { nwkennung: normalizedNwkennung }, update: { lastName, firstName, arbeitsname, groupId: groupId ?? null, email: email ?? undefined, }, create: { nwkennung: normalizedNwkennung, lastName, firstName, arbeitsname, groupId: groupId ?? null, email: email ?? null, }, }); return NextResponse.json( { success: true, user }, { status: 201 }, ); } catch (err) { console.error('[POST /api/users]', err); return NextResponse.json( { error: 'Interner Serverfehler beim CSV-Import.' }, { status: 500 }, ); } }