Rotatory anlegen: Morning-Meeting-Moderation auslosen und nach Nextcloud schreiben
Express-App mit JSON-Speicher unter VCH_DATA_DIR, Monatskalender mit Fotos, Personen mit Rollen und Teilzeit-Freitagen, Abwesenheiten, Feiertage je Bundesland, faire Zufallsauslosung mit Fixieren und Neu-Auslosen. Nextcloud: CalDAV-Discovery, Zielkalender wählbar, Termine je Werktag schreiben und aktualisieren, Abwesenheiten aus Kalender importieren, Personen samt Fotos aus dem Systemadressbuch übernehmen. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
commit
95756778d8
26 files changed
+4697
No files matched your search
@@ -0,0 +1,114 @@
|
||||
# Rotatory
|
||||
|
||||
Rotatory plant die Moderation des werktäglichen Morning Meetings: Pro Tag werden ein
|
||||
**Hauptmoderator** und ein **Nebenmoderator** aus der Belegschaft fair und zufällig
|
||||
ausgelost. Die Monatsansicht zeigt auf jedem Tag die Fotos der beiden Personen. Der fertige
|
||||
Plan lässt sich per Knopfdruck als Termine in einen Nextcloud-Kalender schreiben.
|
||||
|
||||
## Funktionen
|
||||
|
||||
- Personen mit Vor- und Nachname, optionaler E-Mail, Foto (Upload, wird im Browser auf
|
||||
320 px zugeschnitten) und Rolle: Hauptmoderation / Nebenmoderation / beides / keins
|
||||
(Nicht-Moderator). Feste freie Wochentage für Teilzeitkräfte. Inaktive Personen bleiben
|
||||
angelegt, werden aber nicht ausgelost.
|
||||
- Personenimport aus Nextcloud: alle Konten aus dem Systemadressbuch zur Auswahl, Profilbilder
|
||||
werden übernommen.
|
||||
- Abwesenheiten (Urlaub, geplante Krankheit, Frei, Sonstiges) je Person mit Zeitraum – manuell
|
||||
oder importiert aus einem Nextcloud-Kalender mit Terminen wie „Vorname Nachname (Urlaub)",
|
||||
„… (krank)", „… (frei)". Wiederholungen werden aufgelöst, Namen den Personen zugeordnet,
|
||||
nicht zuordenbare Namen aufgelistet.
|
||||
- Feiertage: gesetzliche Feiertage je Bundesland auf Knopfdruck erzeugen, dazu eigene
|
||||
betriebsfreie Tage. An diesen Tagen wird nicht geplant.
|
||||
- Auslosung für beliebige Monatsbereiche. Regeln: nur Mo–Fr, keine Feiertage, keine
|
||||
Abwesenden, niemand an zwei Werktagen hintereinander (wenn vermeidbar), Einsätze
|
||||
gleichmäßig verteilt (Fairness-Fenster berücksichtigt auch vergangene Einsätze), Rollen
|
||||
werden abgewechselt, dieselbe Paarung wiederholt sich ungern.
|
||||
- Einzelne Tage manuell setzen, fixieren (überlebt jede Neuauslosung), neu auslosen oder
|
||||
als „Kein Meeting" markieren.
|
||||
- Einsatzstatistik je Monat.
|
||||
- Export als ICS-Datei oder direkt per CalDAV in einen Nextcloud-Kalender: wahlweise ein
|
||||
vorhandener (auch geteilter) Kalender oder ein neu angelegter. Wiederholtes Schreiben
|
||||
aktualisiert bestehende Termine und löscht entfallene; fremde Termine im Zeitraum können auf
|
||||
Wunsch mit entfernt werden.
|
||||
|
||||
## Installation
|
||||
|
||||
Voraussetzung: Node.js 20 oder neuer.
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
## Starten
|
||||
|
||||
```bash
|
||||
npm run dev # Entwicklung, startet bei Änderungen neu
|
||||
npm start # Produktion
|
||||
```
|
||||
|
||||
Die App lauscht auf `PORT` (Vorgabe 3000) und speichert alle Daten unter `VCH_DATA_DIR`
|
||||
(Vorgabe `./data`): eine JSON-Datei plus die Fotos. Ein Datenbankserver ist nicht nötig.
|
||||
Eine `.env` im Projektstamm wird beim Start gelesen (bereits gesetzte Variablen gewinnen).
|
||||
Beim ersten Start werden die gesetzlichen Feiertage für dieses und nächstes Jahr angelegt;
|
||||
Vorgaben: Bayern, Meeting 09:30 Uhr, 15 Minuten.
|
||||
|
||||
## Konfiguration
|
||||
|
||||
Alle Variablen sind optional, siehe `.env.example`:
|
||||
|
||||
| Variable | Bedeutung |
|
||||
|---|---|
|
||||
| `NEXTCLOUD_URL` | Basis-URL der Nextcloud, z. B. `https://cloud.example.de` |
|
||||
| `NEXTCLOUD_USER` | Anmeldename, E-Mail-Adresse geht auch; die Benutzer-ID wird per CalDAV-Discovery ermittelt |
|
||||
| `NEXTCLOUD_APP_PASSWORD` | App-Passwort (Nextcloud → Einstellungen → Sicherheit → Geräte & Sitzungen) |
|
||||
| `NEXTCLOUD_CALENDAR` | ID des eigenen Kalenders, falls kein vorhandener Zielkalender gewählt wird (Vorgabe `morning-meeting`) |
|
||||
| `NEXTCLOUD_INSECURE_TLS` | `true`, wenn die Nextcloud ein selbstsigniertes Zertifikat nutzt |
|
||||
| `APP_PASSWORD` | Wenn gesetzt, schützt HTTP Basic Auth die ganze App (Benutzername beliebig) |
|
||||
|
||||
Ohne Nextcloud-Variablen läuft die App vollständig, nur der Button „Go – schreiben" ist
|
||||
deaktiviert; der ICS-Download bleibt verfügbar.
|
||||
|
||||
## Nextcloud
|
||||
|
||||
1. Umgebungsvariablen setzen und App neu starten.
|
||||
2. **Personen** → „Aus Nextcloud importieren …": Konten auswählen, Fotos kommen mit.
|
||||
3. **Abwesenheiten** → Quellkalender (z. B. „Urlaub/Krankheit") und Zeitraum wählen,
|
||||
importieren. Vor jeder Auslosung wiederholen, damit neue Urlaube berücksichtigt sind.
|
||||
4. **Kalender** → „Auslosen …" für die kommenden Monate.
|
||||
5. **Kalender** → „Nextcloud …": Zielkalender wählen (ein vorhandener geteilter Kalender wird
|
||||
vorgeschlagen), **Verbindung testen**, Zeitraum wählen und **Go – schreiben**. Je Werktag
|
||||
entsteht ein Termin „Morning Meeting: Haupt / Neben" zur eingestellten Uhrzeit.
|
||||
|
||||
Termine tragen eine stabile UID je Tag (`rotatory-<datum>@<host>`), daher aktualisiert ein
|
||||
erneutes Schreiben statt zu duplizieren. Termine anderer Herkunft im Zeitraum werden gezählt
|
||||
und nur auf ausdrücklichen Wunsch (Häkchen) entfernt.
|
||||
|
||||
Mit der Einstellung „Moderatoren als Teilnehmer eintragen" werden die beiden Personen (bei
|
||||
hinterlegter E-Mail) als Teilnehmer eingetragen; Nextcloud verschickt dann Einladungen.
|
||||
|
||||
## Tests und Prüfung
|
||||
|
||||
```bash
|
||||
npm test # Auslosung, Feiertage, ICS, iCal/vCard-Parser, CalDAV-Client (mit simulierter Nextcloud)
|
||||
npm run lint # Syntaxprüfung aller Quelldateien
|
||||
```
|
||||
|
||||
## Aufbau
|
||||
|
||||
```
|
||||
server/
|
||||
index.js Express-App, REST-API, statische Dateien
|
||||
store.js JSON-Speicher (atomar) und Fotoablage
|
||||
scheduler.js Auslosungslogik (rein, testbar)
|
||||
holidays.js Gesetzliche Feiertage je Bundesland
|
||||
ics.js iCalendar-Erzeugung
|
||||
nextcloud.js CalDAV/CardDAV-Client (Discovery, PROPFIND, MKCALENDAR, REPORT, PUT, DELETE)
|
||||
ical.js iCalendar- und vCard-Leser, Namenszuordnung
|
||||
env.js .env-Leser
|
||||
public/
|
||||
index.html, app.js, style.css Oberfläche ohne Framework, relative Pfade
|
||||
test/ node:test
|
||||
```
|
||||
|
||||
Abhängigkeiten: nur `express`. Fotos werden im Browser per Canvas verkleinert, `fetch` und
|
||||
`crypto` kommen aus Node.
|
||||
Reference in new issue
Block a user