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:
179
prisma/seed.ts
179
prisma/seed.ts
@@ -3,6 +3,21 @@ import bcrypt from "bcryptjs";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
const APPROVAL_THRESHOLD = 50;
|
||||
|
||||
async function upsertAppSettings() {
|
||||
await prisma.appSettings.upsert({
|
||||
where: { id: "global" },
|
||||
update: {
|
||||
approvalThreshold: APPROVAL_THRESHOLD
|
||||
},
|
||||
create: {
|
||||
id: "global",
|
||||
approvalThreshold: APPROVAL_THRESHOLD
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function upsertCurrentPeriod() {
|
||||
const year = new Date().getFullYear();
|
||||
const startsAt = new Date(Date.UTC(year, 0, 1));
|
||||
@@ -36,9 +51,7 @@ async function upsertWorkingGroup(name: string) {
|
||||
return prisma.workingGroup.upsert({
|
||||
where: { name },
|
||||
update: {},
|
||||
create: {
|
||||
name
|
||||
}
|
||||
create: { name }
|
||||
});
|
||||
}
|
||||
|
||||
@@ -71,8 +84,44 @@ async function upsertBudget(
|
||||
});
|
||||
}
|
||||
|
||||
async function upsertUser(input: {
|
||||
username: string;
|
||||
role: Role;
|
||||
passwordHash: string;
|
||||
workingGroupId?: string | null;
|
||||
approvalPermissions: ApprovalType[];
|
||||
}) {
|
||||
const approvalPreference = input.approvalPermissions[0] ?? null;
|
||||
|
||||
await prisma.user.upsert({
|
||||
where: { username: input.username },
|
||||
update: {
|
||||
name: input.username,
|
||||
username: input.username,
|
||||
email: null,
|
||||
passwordHash: input.passwordHash,
|
||||
role: input.role,
|
||||
approvalPreference,
|
||||
approvalPermissions: input.approvalPermissions,
|
||||
workingGroupId: input.workingGroupId ?? null
|
||||
},
|
||||
create: {
|
||||
name: input.username,
|
||||
username: input.username,
|
||||
email: null,
|
||||
passwordHash: input.passwordHash,
|
||||
role: input.role,
|
||||
approvalPreference,
|
||||
approvalPermissions: input.approvalPermissions,
|
||||
workingGroupId: input.workingGroupId ?? null
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const passwordHash = await bcrypt.hash("demo123!", 12);
|
||||
|
||||
await upsertAppSettings();
|
||||
const currentPeriod = await upsertCurrentPeriod();
|
||||
|
||||
const deko = await upsertWorkingGroup("AG Deko");
|
||||
@@ -83,109 +132,41 @@ async function main() {
|
||||
await upsertBudget(awareness.id, currentPeriod.id, "Awareness Hauptbudget", 800, "#68A35D");
|
||||
const technikBudget = await upsertBudget(technik.id, currentPeriod.id, "Technik Infrastruktur", 1500, "#5677F6");
|
||||
|
||||
await prisma.user.upsert({
|
||||
where: { username: "vorstand-a" },
|
||||
update: {
|
||||
name: "Admin 1",
|
||||
username: "vorstand-a",
|
||||
email: null,
|
||||
passwordHash,
|
||||
role: Role.ADMIN,
|
||||
approvalPreference: ApprovalType.CHAIR_A,
|
||||
workingGroupId: null
|
||||
},
|
||||
create: {
|
||||
name: "Admin 1",
|
||||
username: "vorstand-a",
|
||||
email: null,
|
||||
passwordHash,
|
||||
role: Role.ADMIN,
|
||||
approvalPreference: ApprovalType.CHAIR_A
|
||||
}
|
||||
await upsertUser({
|
||||
username: "vorstand-a",
|
||||
role: Role.ADMIN,
|
||||
passwordHash,
|
||||
approvalPermissions: [ApprovalType.CHAIR_A]
|
||||
});
|
||||
|
||||
await prisma.user.upsert({
|
||||
where: { username: "vorstand-b" },
|
||||
update: {
|
||||
name: "Admin 2",
|
||||
username: "vorstand-b",
|
||||
email: null,
|
||||
passwordHash,
|
||||
role: Role.ADMIN,
|
||||
approvalPreference: ApprovalType.CHAIR_B,
|
||||
workingGroupId: null
|
||||
},
|
||||
create: {
|
||||
name: "Admin 2",
|
||||
username: "vorstand-b",
|
||||
email: null,
|
||||
passwordHash,
|
||||
role: Role.ADMIN,
|
||||
approvalPreference: ApprovalType.CHAIR_B
|
||||
}
|
||||
await upsertUser({
|
||||
username: "vorstand-b",
|
||||
role: Role.ADMIN,
|
||||
passwordHash,
|
||||
approvalPermissions: [ApprovalType.CHAIR_B]
|
||||
});
|
||||
|
||||
await prisma.user.upsert({
|
||||
where: { username: "finanzen" },
|
||||
update: {
|
||||
name: "Finanz-AG",
|
||||
username: "finanzen",
|
||||
email: null,
|
||||
passwordHash,
|
||||
role: Role.FINANCE,
|
||||
approvalPreference: ApprovalType.FINANCE,
|
||||
workingGroupId: null
|
||||
},
|
||||
create: {
|
||||
name: "Finanz-AG",
|
||||
username: "finanzen",
|
||||
email: null,
|
||||
passwordHash,
|
||||
role: Role.FINANCE,
|
||||
approvalPreference: ApprovalType.FINANCE
|
||||
}
|
||||
await upsertUser({
|
||||
username: "finanzen",
|
||||
role: Role.FINANCE,
|
||||
passwordHash,
|
||||
approvalPermissions: [ApprovalType.FINANCE]
|
||||
});
|
||||
|
||||
await prisma.user.upsert({
|
||||
where: { username: "deko" },
|
||||
update: {
|
||||
name: "Deko Mitglied",
|
||||
username: "deko",
|
||||
email: null,
|
||||
passwordHash,
|
||||
role: Role.MEMBER,
|
||||
approvalPreference: null,
|
||||
workingGroupId: deko.id
|
||||
},
|
||||
create: {
|
||||
name: "Deko Mitglied",
|
||||
username: "deko",
|
||||
email: null,
|
||||
passwordHash,
|
||||
role: Role.MEMBER,
|
||||
workingGroupId: deko.id
|
||||
}
|
||||
await upsertUser({
|
||||
username: "deko",
|
||||
role: Role.MEMBER,
|
||||
passwordHash,
|
||||
workingGroupId: deko.id,
|
||||
approvalPermissions: []
|
||||
});
|
||||
|
||||
await prisma.user.upsert({
|
||||
where: { username: "technik" },
|
||||
update: {
|
||||
name: "Technik Mitglied",
|
||||
username: "technik",
|
||||
email: null,
|
||||
passwordHash,
|
||||
role: Role.MEMBER,
|
||||
approvalPreference: null,
|
||||
workingGroupId: technik.id
|
||||
},
|
||||
create: {
|
||||
name: "Technik Mitglied",
|
||||
username: "technik",
|
||||
email: null,
|
||||
passwordHash,
|
||||
role: Role.MEMBER,
|
||||
workingGroupId: technik.id
|
||||
}
|
||||
await upsertUser({
|
||||
username: "technik",
|
||||
role: Role.MEMBER,
|
||||
passwordHash,
|
||||
workingGroupId: technik.id,
|
||||
approvalPermissions: []
|
||||
});
|
||||
|
||||
const existingExpense = await prisma.expense.findFirst({
|
||||
@@ -247,4 +228,4 @@ main()
|
||||
console.error(error);
|
||||
await prisma.$disconnect();
|
||||
process.exit(1);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user