# Jahresplanung & Kapazitaetsplanung Eine schlanke Web-App zur Jahresplanung mehrerer Projekte mit integrierter Kapazitaetsplanung pro Person. ## Funktionen - **Projekte & Aufgaben**: Projekte in Aufgaben mit Start-/Enddatum, Aufwand (Stunden), Zustaendigkeit, Prioritaet und optionaler Abhaengigkeit zerlegen. - **Team**: Personen mit Wochenkapazitaet (Stunden) und Abwesenheiten (Urlaub, Feiertage) pflegen. - **Zeitachse**: Alle Aufgaben eines Jahres als Balken je Projekt, jahrweise navigierbar. - **Kapazitaet**: Automatische Auslastungsberechnung je Person und Monat. Der Aufwand jeder Aufgabe wird gleichmaessig ueber ihre Werktage verteilt und den betroffenen Monaten anteilig zugerechnet; Abwesenheiten reduzieren die verfuegbare Nettokapazitaet. Ueberlast wird farblich markiert. ## Architektur - **Backend**: Node.js + Express, liefert eine REST-API (`/api/...`) und das gebaute Frontend aus. - **Datenhaltung**: MongoDB (eigener Container, offizieller Node-Treiber `mongodb`). Vier Collections: `people`, `projects`, `tasks`, `absences`. Die Mongo-`_id` wird beim Ausliefern an das Frontend in ein einfaches `id`-Feld (String) umgewandelt; Referenzen zwischen Entitaeten (z. B. `assigneeId`, `projectId`) werden als dieser String gespeichert. - **Frontend**: React + Vite, wird beim Docker-Build in `backend/public` gebaut und vom Backend ausgeliefert. ## Lokale Entwicklung (optional) ```bash # MongoDB lokal starten (z. B. per Docker) docker run -d --name jp-mongo -p 27017:27017 mongo:7 # Backend cd backend npm install MONGODB_URI=mongodb://localhost:27017/jahresplanung npm start # http://localhost:3000 # Frontend (in zweitem Terminal) cd frontend npm install npm run dev # http://localhost:5173, proxied /api zu :3000 ``` ## Deployment in Coolify 1. **Repository verbinden**: Diesen Ordner in ein Git-Repository pushen (GitHub/GitLab/Gitea) und in Coolify als neue Ressource hinzufuegen (New Resource → Application → dein Repo). 2. **Build-Pack**: **Docker Compose** waehlen. Das mitgelieferte `docker-compose.yml` startet automatisch zwei Container: die App und MongoDB, inklusive persistentem Volume fuer die Datenbank. 3. **Port**: Der App-Container lauscht auf Port `3000` (im `docker-compose.yml` gemappt). In Coolify unter "Domains" die gewuenschte Domain/Subdomain zuweisen. Der MongoDB-Container hat bewusst **keinen** nach aussen gemappten Port und ist nur innerhalb des Compose-Netzwerks fuer die App erreichbar. 4. **Persistenz**: Das Volume `jahresplanung-mongo-data` sichert die MongoDB-Datendateien. Bei Redeploys bleiben die Daten erhalten, solange das Volume nicht geloescht wird. 5. **Deploy** klicken. Coolify baut das App-Image und startet beide Container. Die App verbindet sich beim Start einmalig mit MongoDB; falls das noch nicht bereit ist, beendet sich der App-Container mit einer Fehlermeldung im Log und Coolify startet ihn (je nach Restart-Policy) erneut — meist reicht ein manueller Restart des App-Containers, falls er schneller hochkommt als MongoDB. ### Absicherung (optional, empfohlen fuer produktiven Einsatz) Der MongoDB-Container laeuft standardmaessig **ohne Authentifizierung**, ist aber nicht nach aussen exponiert (kein `ports:`-Eintrag), sondern nur innerhalb des internen Compose-Netzwerks erreichbar. Fuer zusaetzliche Absicherung kannst du `MONGO_INITDB_ROOT_USERNAME` / `MONGO_INITDB_ROOT_PASSWORD` beim `mongo`-Service setzen und die `MONGODB_URI` beim App-Service entsprechend um die Zugangsdaten ergaenzen (`mongodb://user:pass@mongo:27017/jahresplanung?authSource=admin`). ### Ohne docker-compose (alternativ) Falls du in Coolify statt "Docker Compose" nur "Dockerfile" als Build-Pack waehlst, musst du MongoDB als separate Coolify-Ressource (oder externen Dienst) anlegen und die Umgebungsvariable `MONGODB_URI` am App-Container manuell auf die MongoDB-Verbindung zeigen lassen. ## Backup `mongodump` / `mongorestore` gegen den Mongo-Container, oder Coolifys eingebaute Backup-Funktion fuer das Volume `jahresplanung-mongo-data` verwenden. ## Datenmodell (Kurzueberblick) | Entitaet | Felder | |---|---| | Person | name, role, weeklyHours, color | | Projekt | name, description, color | | Aufgabe | projectId, name, startDate, endDate, estimatedHours, assigneeId, priority, status, dependsOn | | Abwesenheit | personId, startDate, endDate, note | Die Kapazitaetsberechnung (`GET /api/capacity?from=...&to=...`) aggregiert je Person und Monat: verfuegbare Werktage minus Abwesenheiten × Tageskapazitaet als `capacityHours`, sowie anteilig verteilte `assignedHours` aus allen zugewiesenen Aufgaben.