# Morning Meeting Planner — Design Spec **Datum:** 2026-04-07 ## Überblick Web-App zur Verteilung von Mitarbeitern auf die Werktage eines Monats für die Moderation des täglichen Morning Meetings. Die Verteilung erfolgt quasi-zufällig mit konfigurierbaren Einschränkungen pro Mitarbeiter und monatsübergreifendem Fairness-Ausgleich. --- ## Architektur **Technologie:** Reines HTML + Vanilla JavaScript + CSS. Keine Frameworks, kein Build-Schritt. Direkt im Browser öffenbar. **Bibliotheken (via CDN):** - `SheetJS` — Excel lesen (.xlsx Import der Mitarbeiterliste) und schreiben (Export des Ergebnisses) **Deployment:** Statische Dateien, kein Server nötig. Für spätere Mehrbenutzer-Nutzung via einfachem Webhosting (z.B. Netlify, GitHub Pages, internes Hosting). **Dateistruktur:** ``` morning-planner/ ├── index.html # Haupt-App ├── app.js # Logik (Algorithmus, Import/Export) ├── style.css # Styling ``` **Erster Start:** Die App startet mit leerem Zustand (keine `.json`-Datei nötig). Mitarbeiter können direkt manuell hinzugefügt oder per Excel importiert werden. Beim ersten "Speichern" wird eine neue `.json`-Datei erstellt. **Datenfluss:** 1. Nutzer lädt optional eine `.json`-Datei → App lädt Mitarbeiterliste, Einschränkungen, Verlauf 2. Nutzer konfiguriert Monat (Feiertage, Betriebsurlaub markieren) und generiert Plan 3. App speichert generierten Plan im internen Verlauf 4. Nutzer exportiert: a) Ergebnis als `.xlsx`, b) App-Stand als `.json` zum Wiederverwenden --- ## Datenmodell Die gespeicherte `.json`-Datei enthält drei Bereiche: ```json { "employees": [ { "id": "uuid", "name": "Max Mustermann", "constraints": { "neverDays": [5], "lowPriorityDays": [5], "onlyDays": [1, 2, 3], "maxPerMonth": 2, "minGapDays": 5, "vacations": [ { "from": "2026-03-01", "to": "2026-03-07" } ] } } ], "calendar": { "holidays": ["2026-01-01", "2026-04-03"], "companyClosures": ["2026-12-24"] }, "history": [ { "date": "2026-03-04", "employeeId": "uuid", "manual": false } ] } ``` **Wochentage:** 1 = Montag, 2 = Dienstag, 3 = Mittwoch, 4 = Donnerstag, 5 = Freitag **Constraint-Typen:** - `neverDays` — Mitarbeiter kann an diesen Wochentagen nie eingeteilt werden - `lowPriorityDays` — Niedrigere Priorität (z.B. Home-Office-Tag) - `onlyDays` — Mitarbeiter kann nur an diesen Wochentagen eingeteilt werden - `maxPerMonth` — Maximale Einsätze pro Monat - `minGapDays` — Mindestabstand in Tagen zwischen zwei Einsätzen - `vacations` — Urlaubszeiträume (von/bis, inklusive) --- ## UI & Screens Die App hat **3 Tabs**: ### Tab 1: Mitarbeiter - Excel-Datei importieren (liest erste Spalte als Namen, erste Zeile = Header wird übersprungen) - Liste aller Mitarbeiter mit Übersicht ihrer Einschränkungen - Pro Mitarbeiter: Einschränkungen bearbeiten (Formular mit allen Constraint-Typen) - Mitarbeiter manuell hinzufügen / entfernen ### Tab 2: Monatsplanung - Monatsauswahl (Monat + Jahr, Bereich: 2026) - Kalenderansicht des Monats: Werktage anzeigen, Wochenenden automatisch grau - Feiertage / Betriebsurlaub per Klick markieren (gesperrt, werden nicht belegt) - Button "Plan generieren" → füllt Kalender mit zugewiesenen Mitarbeiternamen - Manuelles Überschreiben einzelner Tage via Dropdown - Export-Button → `.xlsx` herunterladen **Excel-Export-Format:** - Zeile 1: Mitarbeiternamen - Zeile 2: Datum im Format `dd.mm.yyyy` - Leere Tage (kein Mitarbeiter verfügbar) werden ausgelassen ### Tab 3: Daten - App-Stand als `.json` exportieren ("Speichern") - `.json`-Datei importieren ("Laden") - Verlauf anzeigen (Tabelle: Datum + Mitarbeiter + manuell/automatisch) - Verlauf manuell bereinigen (einzelne Einträge löschen) --- ## Algorithmus **Ziel:** Jeden Werktag des Monats einem verfügbaren Mitarbeiter zuweisen mit fairem monatsübergreifendem Ausgleich. **Ablauf pro Tag (aufsteigend):** 1. **Filtern** — Mitarbeiter ausschließen wenn: - Urlaub an dem Tag - Tag in `neverDays` - `onlyDays` definiert und Tag nicht enthalten - `maxPerMonth` bereits erreicht (im aktuellen Monat) - Letzter Einsatz liegt weniger als `minGapDays` zurück 2. **Score berechnen** für jeden verbleibenden Kandidaten: - Basis-Score = max. Einsätze im Verlauf − eigene Einsätze im Verlauf (weniger Einsätze = höherer Score) - Abzug wenn Tag in `lowPriorityDays`: Score × 0.5 - Zufallskomponente: Score × (0.9 bis 1.1) 3. **Zuweisung** — Kandidat mit höchstem Score bekommt den Tag 4. **Kein Kandidat** → Tag bleibt leer (im Export ausgelassen) **Manuelle Korrekturen** überschreiben den Algorithmus und werden mit `"manual": true` im Verlauf gespeichert. Sie fließen dennoch in den Fairness-Ausgleich ein. --- ## Kalender 2026 Der Kalender für 2026 ist fest eingebaut (keine externe API). Wochenenden werden automatisch erkannt. Gesetzliche Feiertage und Betriebsurlaub werden manuell vom Nutzer im Tool markiert und in der `.json`-Datei gespeichert. --- ## Offene Punkte / Nicht im Scope - Keine Benutzerauthentifizierung (einzelner Nutzer) - Keine automatische Synchronisation zwischen mehreren Nutzern (manueller JSON-Austausch) - Kein Support für Jahre außer 2026 (kann später erweitert werden)