196 lines
4.7 KiB
TypeScript
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 },
|
|
);
|
|
}
|
|
}
|