149 lines
5.2 KiB
Markdown
149 lines
5.2 KiB
Markdown
# 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)
|