From 06ea149d41886eecfd856d911025e8e945c58f4b Mon Sep 17 00:00:00 2001 From: orejudo Date: Fri, 10 Jul 2026 22:57:25 +0200 Subject: [PATCH] Benutzerverwaltung mit Rollen/Rechten und Urlaubsplanung MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- README.md | 109 +++++++- client/src/App.vue | 89 ++++--- client/src/EmployeesPanel.vue | 11 +- client/src/LoginPanel.vue | 38 +++ client/src/ProjectsPanel.vue | 27 +- client/src/TeamsPanel.vue | 10 +- client/src/UsersPanel.vue | 87 +++++++ client/src/UtilizationPanel.vue | 6 +- client/src/VacationPanel.vue | 146 +++++++++++ client/src/api.js | 39 ++- client/src/store.js | 86 ++++++- docker-compose.yml | 2 + server/auth.js | 52 ++++ server/db.js | 36 +++ server/index.js | 328 ++++++++++++++++++++++-- server/package-lock.json | 10 + server/package.json | 1 + server/schema.sql | 26 ++ server/scripts/migrate-team-accounts.js | 75 ++++++ server/scripts/reset-admin.js | 52 ++++ 20 files changed, 1139 insertions(+), 91 deletions(-) create mode 100644 client/src/LoginPanel.vue create mode 100644 client/src/UsersPanel.vue create mode 100644 client/src/VacationPanel.vue create mode 100644 server/auth.js create mode 100644 server/scripts/migrate-team-accounts.js create mode 100644 server/scripts/reset-admin.js diff --git a/README.md b/README.md index 84ced29..db6c479 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,56 @@ # Ressourcenplanung -Leichtgewichtige App zur Planung von Projekten, Aufgaben, Mitarbeitern und Teams – -mit Zeitplan (Gantt), Auslastungs-Heatmap und Team-Verwaltung. Daten liegen in SQLite. +Leichtgewichtige App zur Planung von Projekten, Aufgaben, Mitarbeitern, Teams und +Urlaub – mit Zeitplan (Gantt), Auslastungs-Heatmap, Team-Verwaltung und Login mit +Rollen/Rechten. Daten liegen in SQLite. + +**Breaking Change:** Seit Einführung der Benutzerverwaltung erfordert jeder +API-Zugriff eine angemeldete Sitzung (`/health` bleibt für den Docker-Healthcheck +offen). + +## Rollen & Rechte + +| Rolle | Rechte | +|---|---| +| Admin | lesend + schreibend auf alles, inkl. Benutzerverwaltung | +| Teamleiter | schreibend auf Mitarbeiter/Teams/Projekte/Aufgaben und eigenen Urlaub; lesend auf Urlaub anderer | +| Mitarbeiter | schreibend nur auf eigenen Urlaub (mit Vertreterpflicht) und den Status eigener zugewiesener Aufgaben; sonst lesend | +| Beobachter | nur lesend, sieht ausschließlich Zeitplan/Auslastung/Urlaub | + +**Passwort-Vergabe:** Neue Benutzerkonten (auch der Start-Admin) werden ohne +Passwort angelegt. Beim allerersten Login wird das eingegebene Passwort als +neues Passwort übernommen. + +**Urlaubsvertretung:** Jeder Urlaubseintrag benötigt einen Vertreter aus der +Mitarbeiterliste. Eine Person darf nicht gleichzeitig (überlappender Zeitraum) +als Vertreter für zwei Urlaube *innerhalb derselben Berechtigungsrolle* der +jeweils antragstellenden Person eingetragen sein. ## Aufbau ``` ressourcenplanung/ ├── server/ Node/Express + SQLite (better-sqlite3) -│ ├── schema.sql Tabellen & Beziehungen -│ ├── db.js DB-Init + Beispieldaten -│ └── index.js REST-API (CRUD + Auslastungsberechnung) +│ ├── schema.sql Tabellen & Beziehungen (inkl. users, sessions, vacations) +│ ├── db.js DB-Init, Beispieldaten, Start-Admin-Bootstrap +│ ├── auth.js Passwort-Hashing, Sessions, requireAuth/requireRole +│ ├── index.js REST-API (CRUD + Auslastungsberechnung) +│ └── scripts/ +│ ├── reset-admin.js Admin-Zugang anlegen/zurücksetzen (CLI) +│ └── migrate-team-accounts.js Login-Konten für bestehende Mitarbeiter anlegen (CLI) └── client/ Vue 3 + Vite └── src/ - ├── App.vue Tab-Navigation + ├── App.vue Login-Gate + rollenbasierte Tab-Navigation + ├── LoginPanel.vue Login (Erstanmeldung vergibt Passwort) ├── SchedulePanel.vue Gantt-Zeitplan - ├── UtilizationPanel.vue Auslastungs-Heatmap + ├── UtilizationPanel.vue Auslastungs-Heatmap (urlaubsbereinigt) + ├── VacationPanel.vue Urlaubsplanung inkl. Vertreterregelung ├── ProjectsPanel.vue Projekte/Aufgaben inkl. Zuweisungen ├── EmployeesPanel.vue Mitarbeiter ├── TeamsPanel.vue Teams (n:m-Mitgliedschaft) + ├── UsersPanel.vue Benutzerverwaltung (nur Admin) ├── store.js Reaktiver State + CRUD gegen die API - ├── api.js API-Client + ├── api.js API-Client + Token-Handling └── helpers.js Datum-/Gantt-/Farbberechnung ``` @@ -35,6 +65,14 @@ npm install npm run dev # startet auf http://localhost:8080 ``` Beim ersten Start wird `server/data/data.db` angelegt und mit Beispieldaten befüllt. +Mit der Umgebungsvariable `ADMIN_EMAIL` (muss zur `email` eines bestehenden +Mitarbeiters passen) wird zusätzlich automatisch ein Start-Admin-Konto angelegt, +z. B.: +```bash +ADMIN_EMAIL=tom.fischer@example.com npm run dev +``` +Ohne `ADMIN_EMAIL` wird kein Admin-Konto erzeugt — dann per +`node scripts/reset-admin.js --employee-id ` nachholen (siehe unten). **2) Frontend** ```bash @@ -57,7 +95,52 @@ docker compose up --build ``` Danach ist die App unter http://localhost:8090 erreichbar. Die SQLite-Datenbank -liegt im Docker-Volume `data`. +liegt im Docker-Volume `data`. `ADMIN_EMAIL` vor dem ersten Start setzen (z. B. +in einer `.env`-Datei neben `docker-compose.yml`), damit ein Start-Admin für +einen bestehenden Mitarbeiter angelegt wird. + +## Umstieg von der alten Version (ohne Login) + +Bestehende Projekte, Aufgaben, Zuweisungen, Teams und Mitarbeiter bleiben beim +Update unverändert erhalten — alle neuen Tabellen (`users`, `sessions`, +`vacations`) werden vom Server additiv angelegt (`CREATE TABLE IF NOT EXISTS`). + +Damit nicht jedes bestehende Teammitglied einzeln über die Benutzerverwaltung +angelegt werden muss, legt folgendes Skript für alle Mitarbeiter mit +hinterlegter E-Mail automatisch ein Login-Konto an (Rolle `mitarbeiter`, +Passwort wird wie gewohnt beim ersten Login vergeben): + +```bash +# lokal +node server/scripts/migrate-team-accounts.js + +# im laufenden Container (Docker/Coolify) +docker exec node scripts/migrate-team-accounts.js +``` + +Mitarbeiter ohne hinterlegte E-Mail werden übersprungen (Ausgabe zeigt wer) und +müssen die E-Mail zunächst im Mitarbeiter-Tab nachtragen. Mit `--role +teamleiter` (oder `admin`/`beobachter`) lässt sich eine andere Standardrolle als +`mitarbeiter` vergeben; einzelne Rollen danach jederzeit über die +Benutzerverwaltung anpassen. Empfohlene Reihenfolge beim Umstieg: zuerst +`ADMIN_EMAIL` setzen bzw. `reset-admin.js` für den ersten Admin ausführen, dann +`migrate-team-accounts.js` für den Rest des Teams. + +## Admin-Zugang anlegen/zurücksetzen + +Falls kein `ADMIN_EMAIL` gesetzt war oder das Passwort verloren ging: + +```bash +# lokal +node server/scripts/reset-admin.js --employee-id 3 + +# im laufenden Container (Docker/Coolify) +docker exec node scripts/reset-admin.js --employee-id 3 +``` + +Ohne `--password` wird das Konto (neu) angelegt/verknüpft; das Passwort wird +beim nächsten Login vergeben. Mit `--password` wird sofort ein Passwort gesetzt +(Notfall-Wiederherstellung). ## Deployment in Coolify @@ -82,5 +165,11 @@ liegt im Docker-Volume `data`. dafür verwendet werden. 5. **Healthcheck**: Das Image bringt einen `HEALTHCHECK` gegen `/health` mit; Coolify nutzt ihn automatisch, um den Container-Status anzuzeigen. -6. **Deploy** klicken. Beim allerersten Start legt der Server automatisch +6. **Umgebungsvariable**: `ADMIN_EMAIL` in Coolify unter den + Environment-Variablen der Ressource setzen (E-Mail eines bestehenden + Mitarbeiters) — damit wird beim ersten Start automatisch ein Start-Admin + angelegt, der sein Passwort beim ersten Login selbst vergibt. Ohne + `ADMIN_EMAIL` bleibt die App ohne Admin-Konto; dann `reset-admin.js` per + `docker exec` nachholen (siehe oben). +7. **Deploy** klicken. Beim allerersten Start legt der Server automatisch `data.db` an und befüllt sie mit Beispieldaten. diff --git a/client/src/App.vue b/client/src/App.vue index a3a9003..a012abd 100644 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -1,47 +1,72 @@ diff --git a/client/src/EmployeesPanel.vue b/client/src/EmployeesPanel.vue index 733aab2..3392056 100644 --- a/client/src/EmployeesPanel.vue +++ b/client/src/EmployeesPanel.vue @@ -1,7 +1,9 @@