In der Nutzerverwaltung kannst du jetzt pro Konto die Rolle, die AG-Zuordnung und die Freigaberollen bearbeiten. Die feste 3er-Freigabelogik bleibt Vorstand A / Vorstand B / Finanz-AG, aber jetzt legst du über die Nutzer fest, wer diese Schritte autorisieren darf. Zusätzlich gibt es unter Nutzer anlegen eine eigene Insel für die Freigabe-Schwelle, und diese Schwelle wird jetzt auch wirklich überall verwendet: in der Erfassungslogik, in den Budgetkarten, im CSV-Backup/-Import und im Audit-Restore. Die Hauptänderungen sitzen in dashboard-shell.tsx, budget-column.tsx, route.ts, schema.prisma und route.ts.
All checks were successful
CI / build-and-deploy (push) Successful in 1m22s
All checks were successful
CI / build-and-deploy (push) Successful in 1m22s
Den Zeitraum-Bereich habe ich dabei gleich mit aufgeräumt: die Auswahl des aktuellen Haushalts ist breiter und sauberer angeordnet, und die Desktop-Nutzerverwaltung ist jetzt wirklich links Anlegen + Schwelle und rechts die Nutzerliste. Seed und Backup/Restore kennen die neuen Felder ebenfalls in seed.ts, route.ts und route.ts.
This commit is contained in:
@@ -53,6 +53,17 @@ function asNumber(value: unknown, label: string) {
|
||||
return value;
|
||||
}
|
||||
|
||||
function asApprovalPermissions(value: unknown) {
|
||||
if (!Array.isArray(value)) {
|
||||
return [] as ("CHAIR_A" | "CHAIR_B" | "FINANCE")[];
|
||||
}
|
||||
|
||||
return value.filter(
|
||||
(entry): entry is "CHAIR_A" | "CHAIR_B" | "FINANCE" =>
|
||||
entry === "CHAIR_A" || entry === "CHAIR_B" || entry === "FINANCE"
|
||||
);
|
||||
}
|
||||
|
||||
export async function POST(_: Request, { params }: Context) {
|
||||
const viewer = await getCurrentViewer();
|
||||
|
||||
@@ -306,6 +317,25 @@ export async function POST(_: Request, { params }: Context) {
|
||||
break;
|
||||
}
|
||||
|
||||
case "settings.update": {
|
||||
const previous = asRecord(rollback.previous, "App-Einstellungen");
|
||||
|
||||
await tx.appSettings.upsert({
|
||||
where: {
|
||||
id: asString(previous.id, "Einstellungs-ID")
|
||||
},
|
||||
update: {
|
||||
approvalThreshold: asNumber(previous.approvalThreshold, "Freigabe-Schwelle")
|
||||
},
|
||||
create: {
|
||||
id: asString(previous.id, "Einstellungs-ID"),
|
||||
approvalThreshold: asNumber(previous.approvalThreshold, "Freigabe-Schwelle"),
|
||||
createdAt: asDate(previous.createdAt, "Einstellungen erstellt am") ?? new Date()
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case "user.create": {
|
||||
const created = asRecord(rollback.created, "Nutzer");
|
||||
const userId = asString(created.id, "Nutzer-ID");
|
||||
@@ -364,6 +394,7 @@ export async function POST(_: Request, { params }: Context) {
|
||||
passwordHash: asString(deleted.passwordHash, "Passworthash"),
|
||||
role: asString(deleted.role, "Rolle") as "ADMIN" | "FINANCE" | "MEMBER",
|
||||
approvalPreference: asNullableString(deleted.approvalPreference) as "CHAIR_A" | "CHAIR_B" | "FINANCE" | null,
|
||||
approvalPermissions: asApprovalPermissions(deleted.approvalPermissions),
|
||||
workingGroupId: asNullableString(deleted.workingGroupId),
|
||||
createdAt: asDate(deleted.createdAt, "Nutzer erstellt am") ?? new Date()
|
||||
}
|
||||
@@ -371,6 +402,27 @@ export async function POST(_: Request, { params }: Context) {
|
||||
break;
|
||||
}
|
||||
|
||||
case "user.update": {
|
||||
const previous = asRecord(rollback.previous, "Nutzer");
|
||||
const role = asString(previous.role, "Rolle") as "ADMIN" | "FINANCE" | "MEMBER";
|
||||
|
||||
await tx.user.update({
|
||||
where: {
|
||||
id: asString(previous.id, "Nutzer-ID")
|
||||
},
|
||||
data: {
|
||||
name: asString(previous.name, "Anzeigename"),
|
||||
username: asString(previous.username, "Login-Name"),
|
||||
email: asNullableString(previous.email),
|
||||
role,
|
||||
approvalPreference: asNullableString(previous.approvalPreference) as "CHAIR_A" | "CHAIR_B" | "FINANCE" | null,
|
||||
approvalPermissions: asApprovalPermissions(previous.approvalPermissions),
|
||||
workingGroupId: asNullableString(previous.workingGroupId)
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case "user.passwordReset": {
|
||||
await tx.user.update({
|
||||
where: {
|
||||
|
||||
Reference in New Issue
Block a user