4.6 KiB
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-_idwird beim Ausliefern an das Frontend in ein einfachesid-Feld (String) umgewandelt; Referenzen zwischen Entitaeten (z. B.assigneeId,projectId) werden als dieser String gespeichert. - Frontend: React + Vite, wird beim Docker-Build in
backend/publicgebaut und vom Backend ausgeliefert.
Lokale Entwicklung (optional)
# 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
- Repository verbinden: Diesen Ordner in ein Git-Repository pushen (GitHub/GitLab/Gitea) und in Coolify als neue Ressource hinzufuegen (New Resource → Application → dein Repo).
- Build-Pack: Docker Compose waehlen. Das mitgelieferte
docker-compose.ymlstartet automatisch zwei Container: die App und MongoDB, inklusive persistentem Volume fuer die Datenbank. - Port: Der App-Container lauscht auf Port
3000(imdocker-compose.ymlgemappt). 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. - Persistenz: Das Volume
jahresplanung-mongo-datasichert die MongoDB-Datendateien. Bei Redeploys bleiben die Daten erhalten, solange das Volume nicht geloescht wird. - 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.