Files
admin 06ea149d41 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>
2026-07-10 22:57:25 +02:00

76 lines
3.0 KiB
JavaScript

// Einmalig beim Umstieg von der alten Version (ohne Login) auf die neue Version
// (mit Benutzerverwaltung) auszuführen: legt für jeden bestehenden Mitarbeiter
// mit hinterlegter E-Mail, der noch KEIN Benutzerkonto hat, automatisch eines an
// (Rolle 'mitarbeiter', ohne Passwort — wie bei der Benutzerverwaltung üblich wird
// das Passwort beim ersten Login vom jeweiligen Mitarbeiter selbst vergeben).
//
// Bestehende Projekte, Aufgaben, Zuweisungen und Teams werden dabei nicht
// verändert — die Tabellen werden vom Server ohnehin additiv angelegt
// (server/schema.sql, CREATE TABLE IF NOT EXISTS). Dieses Skript kümmert sich
// ausschließlich darum, dass alle bestehenden Teammitglieder auch einen Login
// bekommen, statt sie einzeln über die Benutzerverwaltung anlegen zu müssen.
//
// Aufruf:
// node scripts/migrate-team-accounts.js
// docker exec <container> node scripts/migrate-team-accounts.js (im laufenden Container)
//
// Rolle abweichend vom Default vergeben (z. B. alle als Teamleiter anlegen):
// node scripts/migrate-team-accounts.js --role teamleiter
const db = require('../db');
function readArg(name) {
const idx = process.argv.indexOf(`--${name}`);
return idx !== -1 ? process.argv[idx + 1] : undefined;
}
const role = readArg('role') || 'mitarbeiter';
const VALID_ROLES = ['admin', 'teamleiter', 'mitarbeiter', 'beobachter'];
if (!VALID_ROLES.includes(role)) {
console.error(`Ungültige Rolle "${role}". Erlaubt: ${VALID_ROLES.join(', ')}`);
process.exit(1);
}
const employees = db.prepare('SELECT id, first_name, last_name, email FROM employees ORDER BY last_name, first_name').all();
const existingUsers = db.prepare('SELECT employee_id, email FROM users').all();
const employeeIdsWithAccount = new Set(existingUsers.map((u) => u.employee_id));
const emailsInUse = new Set(existingUsers.map((u) => u.email));
const insert = db.prepare(
'INSERT INTO users (employee_id, email, password_hash, role) VALUES (?, ?, NULL, ?)'
);
let created = 0;
let skippedNoEmail = 0;
let skippedExisting = 0;
let skippedEmailConflict = 0;
for (const e of employees) {
const name = `${e.first_name} ${e.last_name}`;
if (employeeIdsWithAccount.has(e.id)) {
skippedExisting += 1;
continue;
}
if (!e.email) {
console.log(`Übersprungen (keine E-Mail hinterlegt): ${name}`);
skippedNoEmail += 1;
continue;
}
if (emailsInUse.has(e.email)) {
console.log(`Übersprungen (E-Mail bereits von einem anderen Konto verwendet): ${name} <${e.email}>`);
skippedEmailConflict += 1;
continue;
}
insert.run(e.id, e.email, role);
emailsInUse.add(e.email);
created += 1;
console.log(`Konto angelegt: ${name} <${e.email}> (Rolle: ${role})`);
}
console.log('----------------------------------------------------------------');
console.log(`Fertig. Neu angelegt: ${created}, bereits vorhanden: ${skippedExisting}, ` +
`ohne E-Mail übersprungen: ${skippedNoEmail}, E-Mail-Konflikt übersprungen: ${skippedEmailConflict}.`);
console.log('Alle neu angelegten Konten vergeben ihr Passwort selbst beim ersten Login.');