geraete/app/api/users/route.ts
2025-11-26 08:02:48 +01:00

196 lines
4.7 KiB
TypeScript

// 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 },
);
}
}