Benutzerverwaltung mit Rollen/Rechten und Urlaubsplanung

Führt Login mit vier Rollen (Admin, Teamleiter, Mitarbeiter, Beobachter) ein,
über die Teammitglieder eigenen Urlaub inkl. Pflicht-Vertreter eintragen
können. Die Auslastungsberechnung berücksichtigt Urlaub jetzt als reduzierte
Kapazität. Neue Konten vergeben ihr Passwort selbst beim ersten Login.
Migrationsskript für bestehende Mitarbeiter aus der Vorversion inklusive.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-10 22:57:25 +02:00
parent 60a0928d2f
commit 06ea149d41
20 changed files with 1139 additions and 91 deletions
+36
View File
@@ -15,6 +15,7 @@ const schema = fs.readFileSync(path.join(__dirname, 'schema.sql'), 'utf8');
db.exec(schema);
migrateEmployeeName();
seedInitialAdmin();
if (isNew) {
seed();
@@ -41,6 +42,41 @@ function migrateEmployeeName() {
db.exec('ALTER TABLE employees DROP COLUMN name');
}
// Legt beim allerersten Start einen Admin-Zugang für einen BESTEHENDEN Mitarbeiter an,
// dessen employees.email mit ADMIN_EMAIL übereinstimmt. Es wird bewusst kein Passwort
// gesetzt: wie bei allen über die Benutzerverwaltung angelegten Konten wird das
// Passwort erst beim allerersten Login vom Nutzer selbst vergeben (siehe /api/auth/login).
function seedInitialAdmin() {
const userCount = db.prepare('SELECT COUNT(*) AS c FROM users').get().c;
if (userCount > 0) return;
const adminEmail = process.env.ADMIN_EMAIL;
if (!adminEmail) {
console.log(
'Hinweis: ADMIN_EMAIL ist nicht gesetzt, es wurde kein Start-Admin angelegt. ' +
'Bitte ADMIN_EMAIL auf die E-Mail eines bestehenden Mitarbeiters setzen und neu starten, ' +
'oder scripts/reset-admin.js verwenden.'
);
return;
}
const employee = db.prepare('SELECT id FROM employees WHERE email = ?').get(adminEmail);
if (!employee) {
console.log(
`Hinweis: ADMIN_EMAIL (${adminEmail}) passt zu keinem bestehenden Mitarbeiter, ` +
'es wurde kein Start-Admin angelegt.'
);
return;
}
db.prepare('INSERT INTO users (employee_id, email, password_hash, role) VALUES (?, ?, NULL, ?)').run(
employee.id,
adminEmail,
'admin'
);
console.log(`Start-Admin für ${adminEmail} angelegt. Das Passwort wird beim ersten Login vergeben.`);
}
function seed() {
const insertEmployee = db.prepare(
'INSERT INTO employees (first_name, last_name, email, role, weekly_capacity_hours) VALUES (?, ?, ?, ?, ?)'