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:
@@ -2,7 +2,7 @@ import { NextResponse } from "next/server";
|
||||
|
||||
import { createAuditLog } from "@/lib/audit-log";
|
||||
import { parseCsv } from "@/lib/backup-csv";
|
||||
import { canManageUsers } from "@/lib/domain";
|
||||
import { canManageUsers, DEFAULT_APPROVAL_THRESHOLD, getLegacyApprovalPreference, normalizeApprovalPermissions } from "@/lib/domain";
|
||||
import prisma from "@/lib/prisma";
|
||||
import { getCurrentViewer } from "@/lib/session";
|
||||
|
||||
@@ -28,6 +28,21 @@ function toNumber(value: string | undefined) {
|
||||
return Number.isFinite(parsed) ? parsed : null;
|
||||
}
|
||||
|
||||
function toApprovalPermissions(
|
||||
value: string | undefined,
|
||||
role: "ADMIN" | "FINANCE" | "MEMBER",
|
||||
approvalPreference: "CHAIR_A" | "CHAIR_B" | "FINANCE" | null
|
||||
) {
|
||||
const explicitPermissions = value
|
||||
? value
|
||||
.split("|")
|
||||
.map((entry) => entry.trim())
|
||||
.filter((entry) => entry.length > 0) as ("CHAIR_A" | "CHAIR_B" | "FINANCE")[]
|
||||
: [];
|
||||
|
||||
return normalizeApprovalPermissions(role, explicitPermissions, approvalPreference);
|
||||
}
|
||||
|
||||
export async function POST(request: Request) {
|
||||
const viewer = await getCurrentViewer();
|
||||
|
||||
@@ -71,6 +86,7 @@ export async function POST(request: Request) {
|
||||
);
|
||||
}
|
||||
|
||||
const settingsRows = rawEntries.filter((entry) => entry.recordType === "settings");
|
||||
const periodRows = rawEntries.filter((entry) => entry.recordType === "period");
|
||||
const groupRows = rawEntries.filter((entry) => entry.recordType === "workingGroup");
|
||||
const budgetRows = rawEntries.filter((entry) => entry.recordType === "budget");
|
||||
@@ -87,6 +103,16 @@ export async function POST(request: Request) {
|
||||
await tx.user.deleteMany();
|
||||
await tx.workingGroup.deleteMany();
|
||||
await tx.accountingPeriod.deleteMany();
|
||||
await tx.appSettings.deleteMany();
|
||||
|
||||
const settingsRow = settingsRows[0];
|
||||
await tx.appSettings.create({
|
||||
data: {
|
||||
id: settingsRow?.id || "global",
|
||||
approvalThreshold: toNumber(settingsRow?.approvalThreshold) ?? DEFAULT_APPROVAL_THRESHOLD,
|
||||
createdAt: toDate(settingsRow?.createdAt) ?? new Date()
|
||||
}
|
||||
});
|
||||
|
||||
for (const row of periodRows) {
|
||||
const startsAt = toDate(row.periodStartsAt);
|
||||
@@ -119,6 +145,10 @@ export async function POST(request: Request) {
|
||||
}
|
||||
|
||||
for (const row of userRows) {
|
||||
const role = row.role as "ADMIN" | "FINANCE" | "MEMBER";
|
||||
const approvalPreference = toNullable(row.approvalPreference) as "CHAIR_A" | "CHAIR_B" | "FINANCE" | null;
|
||||
const approvalPermissions = toApprovalPermissions(row.approvalPermissions, role, approvalPreference);
|
||||
|
||||
await tx.user.create({
|
||||
data: {
|
||||
id: row.id,
|
||||
@@ -126,8 +156,9 @@ export async function POST(request: Request) {
|
||||
username: row.username,
|
||||
email: toNullable(row.email),
|
||||
passwordHash: row.passwordHash,
|
||||
role: row.role as "ADMIN" | "FINANCE" | "MEMBER",
|
||||
approvalPreference: toNullable(row.approvalPreference) as "CHAIR_A" | "CHAIR_B" | "FINANCE" | null,
|
||||
role,
|
||||
approvalPreference: getLegacyApprovalPreference(approvalPermissions),
|
||||
approvalPermissions,
|
||||
workingGroupId: toNullable(row.workingGroupId),
|
||||
createdAt: toDate(row.createdAt) ?? new Date()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user