feat(kalender): Kalender mit Urlauben und Feiertagen fuer alle

Neuer Menuepunkt "Kalender" fuer alle Rollen: genehmigte Urlaube aller
Mitarbeiter, auch in der Zukunft, dazu Feiertage. Monatsansicht (Standard)
und Zeitleiste, filterbar nach Team und Name.

- Eigene Tabelle pulse_calendar_days, gefuellt von lib/calendarSync.js im
  HRworks-Lauf (Fenster bis 400 Tage voraus). Buchungen entstehen weiter
  erst am jeweiligen Tag.
- Nur validatedOk und nur freigegebene Arten (calendar_types, Haken in den
  HRworks-Einstellungen). Krankmeldungen werden dafuer nicht abgefragt.
- GET /api/calendar fuer alle Angemeldeten, ohne Mails und Profilbilder.
- Timer laeuft zusaetzlich um 12:00 Uhr.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
schakal00783
2026-09-25 11:37:26 +02:00
co-authored by Claude Opus 5.5
parent 6ae5a01bda
commit c0eb00faee
21 changed files with 996 additions and 33 deletions
+31 -8
View File
@@ -18,11 +18,11 @@ Erster Login: Benutzer `admin`, Passwort aus `ADMIN_PASSWORD` in `server/.env` (
| Rolle | Startseite | Menü |
| --- | --- | --- |
| Mitarbeiter (`user`) | Buchung | Buchung, Projekte (nur zugewiesene, ohne Beträge) |
| Mitarbeiter (`user`) | Buchung | Buchung, Projekte (nur zugewiesene, ohne Beträge), Kalender |
| Externe (`external`) | Buchung | wie Mitarbeiter – die Rolle trennt nur, wer zum Haus gehört; `is_external` wird automatisch gesetzt |
| Vorgesetzter (`lead`) | Buchung | Dashboard (nur eigenes Team, rekursiv), Buchung, Projekte, Team, Kunden, Reports |
| Vorgesetzter (`lead`) | Buchung | Dashboard (nur eigenes Team, rekursiv), Buchung, Projekte, Kalender, Team, Kunden, Reports |
| Management | Dashboard | wie Vorgesetzter, sieht alles; Einstellungen nur „SSO-Verwaltung“ |
| Administrator | Einstellungen | Dashboard, Projekte, Team, Kunden, Reports, Einstellungen – keine Buchung, taucht in Auswertungen nicht auf |
| Administrator | Einstellungen | Dashboard, Projekte, Kalender, Team, Kunden, Reports, Einstellungen – keine Buchung, taucht in Auswertungen nicht auf |
Die Startseite gilt nach jeder Anmeldung (Passwort und SSO), auch wenn noch eine alte Seite in der Adresse steht; Neuladen bleibt auf der aktuellen Seite. Das Logo oben links führt ebenfalls zur Startseite.
@@ -140,7 +140,7 @@ Team, Dashboard, Reports, Projekt- und Kundenansicht. Ohne Bild bleiben die Init
## Abwesenheiten aus HRworks
Urlaub, Krankheit, Elternzeit und Feiertage stehen in HRworks. Pulse holt sie einmal täglich
Urlaub, Krankheit, Elternzeit und Feiertage stehen in HRworks. Pulse holt sie zweimal täglich
und bucht sie auf das nicht abrechenbare Projekt `PERINCO-2024-001` („Abwesenheiten").
Geschrieben wird nur in Pulse – nach HRworks geht nichts zurück.
@@ -169,9 +169,9 @@ Jede Buchung trägt `pulse_time_entries.hrworks_ref` = `<Abwesenheitsnummer>@<Ta
Ein zweiter Lauf ändert deshalb nichts; was in HRworks storniert oder verschoben wurde,
verschwindet im nächsten Lauf. `DELETE /api/hrworks/entries` entfernt genau diese Buchungen.
**Täglich** läuft `server/src/jobs/hrworks-sync.js` über den systemd-Timer
`perinco-pulse-hrworks.timer` (5:30 Uhr Berliner Zeit, `Persistent=true` holt verpasste Läufe
nach). Ausgang im Journal: `journalctl -u perinco-pulse-hrworks`. Die Unit-Dateien liegen in
**Zweimal täglich** läuft `server/src/jobs/hrworks-sync.js` über den systemd-Timer
`perinco-pulse-hrworks.timer` (5:30 und 12:00 Uhr Berliner Zeit, `Persistent=true` holt verpasste Läufe
nach) – erst die Buchungen, dann der Kalender (siehe unten). Ausgang im Journal: `journalctl -u perinco-pulse-hrworks`. Die Unit-Dateien liegen in
`deploy/`; sie werden nach `/etc/systemd/system/` kopiert und einmal mit
`systemctl enable --now perinco-pulse-hrworks.timer` eingeschaltet.
@@ -180,6 +180,28 @@ nach). Ausgang im Journal: `journalctl -u perinco-pulse-hrworks`. Die Unit-Datei
Billable und Festpreis Sinn. Am Abwesenheitsprojekt wäre er nur ein Ablaufdatum, das irgendwann
Buchungen blockiert; es hat deshalb keinen.
### Kalender
Menüpunkt **Kalender** für alle Rollen: genehmigte Urlaube aller Mitarbeiter – auch die der Zukunft –
und Feiertage. Ansichten **Monat** (Standard, jedes Öffnen) und **Zeitleiste** (eine Zeile je Person,
Überschneidungen auf einen Blick); Filter nach Team (Vorgesetzter samt allen darunter) und Name. Klick auf
einen Tag zeigt rechts, wer weg ist; darunter die Urlaube des Monats als Zeiträume.
Die Buchungen entstehen weiter erst am jeweiligen Tag. Der Kalender hat deshalb eine eigene Tabelle
`pulse_calendar_days` (ein Eintrag je Person und Tag: `vacation` oder `holiday`, halber Tag), gefüllt von
`server/src/lib/calendarSync.js` im selben Timer-Lauf. Fenster: `window_days` zurück bis
`calendar_days_ahead` (400) Tage voraus; jeder Lauf ersetzt das Fenster komplett, ältere Tage bleiben als
Rückblick. Einmalig weiter zurück: `node src/jobs/hrworks-sync.js --calendar-from=2026-01-01`.
„Jetzt übernehmen“ in den Einstellungen füllt den Kalender gleich mit.
| Regel | Umsetzung |
| --- | --- |
| Status | nur `validatedOk` – beantragte Urlaube erscheinen nicht |
| Arten | nur `calendar_types` (Voreinstellung Urlaub `absence:1` und Bildungsurlaub `absence:10`), Haken **Kalender** in *Zuordnung der Arten* |
| Krankheit | wird für den Kalender gar nicht abgefragt; ein Urlaubstag bleibt stehen, auch wenn eine Krankmeldung daran hängt – sonst verriete die Lücke die Krankheit |
| Feiertage | aus HRworks je Person (Standort), mit Namen, sofern HRworks einen liefert |
| API | `GET /api/calendar?from=&to=` (jeder Angemeldete, höchstens 400 Tage): Name, Farbe, Vorgesetzter – keine Mails, keine Profilbilder |
## KI-Assistent
**Einrichtung** (nur Administrator, *Einstellungen → KI-Assistent*): OpenAI-Schlüssel eintragen
@@ -286,7 +308,8 @@ Aus Auftrag und Call-Mitschrift.
| Klick auf einen Mitarbeiter im Zeitreport zeigt dessen Buchungen des Zeitraums als Liste | ✅ | Reports → Zeitreport → Mitarbeiter |
| Kunden: zusätzliche Listenansicht | ✅ | Kunden → Karten/Liste |
| Eigenes Profilbild hochladen | ✅ | Mein Konto, Team → Bearbeiten |
| Abwesenheiten automatisch aus HRworks | ✅ täglich 5:30 Uhr | Einstellungen → Abwesenheiten (HRworks) |
| Abwesenheiten automatisch aus HRworks | ✅ täglich 5:30 und 12:00 Uhr | Einstellungen → Abwesenheiten (HRworks) |
| Kalender mit allen genehmigten Urlauben (auch zukünftig) und Feiertagen, für alle | ✅ Monat / Zeitleiste, Filter Team + Name | Kalender |
| Bestellnummer je Budgettopf, erscheint im Stundennachweis | ✅ | Projekt → Budgettopf |
| Rolle „Externe" mit den Rechten eines Mitarbeiters | ✅ | Team → Bearbeiten |
| Export: Kunde und Projekt nur aus den eigenen Zuweisungen | ✅ | Buchung → Export |