Beteiligten-Zuordnung verlagert: p.assign ist jetzt ein Stammdatum und nur noch in den Projekteinstellungen editierbar (planCycleAssign()). Wochenbericht und Projektboard zeigen sie nur noch an, mit Verweis dorthin (springZuEinstellungen()). cycleAssign() ist damit entfallen. Neu "TODOs aus Protokoll": ein externes Besprechungsprotokoll als PDF wird per KI eingelesen und daraus in einem zweiten KI-Schritt Aufgaben abgeleitet. Eigener Bereich in der Aufgaben-/GANTT-Leiste, bewusst unabhaengig von den gespeicherten Protokollen - nichts davon wird abgelegt. Drei Schritte in einem Dialog mit fester Fusszeile; die Vorschlagsliste als kompakte, aufklappbare Zeilen, weil ein echter Import leicht 20 Vorschlaege liefert. Sichtbarkeit je Aufgabe im GANTT: neue Spalte plan_todos.show_in_gantt (Vorgabe 1, idempotente Migration) und eine Checkbox im Aufgaben-Dialog. Eine terminierte Aufgabe kann damit gezielt aus dem Terminplan herausgehalten werden, bleibt sonst aber eine vollwertige Aufgabe. plan-build-gantt.js und plan-drag.js pruefen dieselbe Bedingung, damit Zeilenzahl und Umsortierung nicht auseinanderlaufen. KI-Timeout dritte Stufe: ein abweichender, aber entfernter Endpunkt (Drittanbieter-Proxy) bekommt 2 Minuten statt der 45 Sekunden der echten Anbieter-API. Gemessen: die Punkte-Erkennung eines realen Protokolls brauchte dort 39 Sekunden, lag also stets knapp unter dem alten Limit und brach bei jeder Schwankung ab. Bewegung: Hover- und Klick-Rueckmeldung als Token-Satz in :root, angewandt auf die anklickbaren Zeilen, Schalter und Dialoge. Die Akzentleiste ist ein inset-Schatten statt eines positionierten Elements, damit Drag-and-Drop unberuehrt bleibt; prefers-reduced-motion war bisher gar nicht vorhanden und kippt jetzt einfach die Tokens. Plan Checker: optionaler Projektabgleich des Plankopfs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Projektübersicht
Werkzeug für ein Ingenieurbüro der technischen Gebäudeausrüstung (TGA), um Projekte über wöchentliche Sitzungen hinweg zu verfolgen: Leistungsphasen nach HOAI, Termine, Personaleinsatz, die wöchentliche Teambesprechung und die Dokumentenfreigabe. Single-Page-App ohne Build-Schritt: Vanilla JS/HTML/CSS im Frontend, Node.js/Express im Backend, Daten in SQLite.
Technologie
- Frontend: klassische, unmodulare
<script>-Dateien unterpublic/js/— alle Funktionen liegen global aufwindow, kein Bundler, kein Framework. Eine HTML-Datei,public/App.html, bildet die gesamte Oberfläche ab (Seitenleiste + alle Bereiche inklusive des Projektbereichs eines einzelnen Projekts). - Backend: Node.js (≥ 22.13, wegen
node:sqlite) + Express, alles in einer einzigenserver.js. - Datenbank: SQLite über das eingebaute
node:sqlite-Modul (WAL-Modus, vollständig relational, keine Einzeldatei je Woche), Datei untersessions/projektuebersicht.db. - Kein Linter, kein Formatter, keine Testsuite. Verifikation läuft manuell: Server starten, Bereich im Browser ausprobieren, SQLite-Datei prüfen.
Starten
Lokal (Node.js ≥ 22.13)
npm install
npm start
Erreichbar unter http://localhost:3003. Anderer Port:
PORT=3004 npm start
Mit Docker
docker compose up --build
docker-compose.yml liegt im Projektstamm, baut aus Docker/Dockerfile
(node:22-alpine), mappt Port 3003 und bindet ./sessions in den
Container nach /app/sessions — die Datenbank und alle Uploads bleiben damit
auf dem Host erhalten. TZ=Europe/Berlin ist gesetzt, weil mehrere
Datumsvergleiche im Server von der lokalen Zeitzone abhängen.
Erste Anmeldung
Die gesamte Anwendung verlangt eine Anmeldung. Ist die users-Tabelle beim
ersten Start leer, legt der Server automatisch ein Admin-Konto
(admin) mit einem zufälligen Passwort an, gibt es einmalig auf der Konsole
aus und schreibt es zusätzlich nach sessions/INITIAL_ADMIN_PASSWORD.txt
(liegt außerhalb von public/, wird also nie ausgeliefert). Das Konto muss
sein Passwort beim ersten Login ändern.
Bereiche der Anwendung
Seitenleiste, in dieser Reihenfolge:
- Meine Aufgaben — Dashboard und Startansicht nach dem Login: offene persönliche Aufgaben, Termine der eigenen Projekte, ausstehende Datei-Freigaben, Abwesenheiten von Kollegen.
- Projekte — die eine Projektliste (Board), gruppiert, per Drag-and-Drop sortierbar.
- Wochenbericht — die Tagesordnung der wöchentlichen Teambesprechung, je Gewerk (ELT/HLS/ARCH) gefiltert: jedes Projekt dieses Gewerks wird angesehen, mit Vergleich zur Vorwoche, Anwesenheitserfassung und PDF-Export.
- Auslastung — Personalauslastung in tatsächlichen Wochenstunden, aufgeteilt nach Projekten (Lastband).
- Projektbeteiligte — schreibgeschützte Übersicht der aktiven Benutzerkonten; Teammitglieder pflegt ausschließlich ein Administrator (Admin → Benutzerverwaltung).
- Planung — ein von einem konkreten Projekt unabhängiger Terminplan-Sandkasten, z. B. um einen Zeitplan vorab durchzurechnen.
- Einstellungen — das eigene Konto: Stammdaten, E-Mail, Passwort, eigene KI-Zugangsdaten für die Protokoll-Erkennung (siehe unten).
- Admin (nur Administratoren) — Benutzerverwaltung, Honorar-Vorgaben, Auslastungs-Schwellen, Sitzungsverwaltung, Feiertage, Aufgaben-Vorlagen, Betrieb & Sicherheit, Datenbank-Backup/-Import.
Projektbereich
Aus der Projektliste heraus öffnet sich zu einem Projekt ein eigener Bereich mit sieben Abschnitten: Dashboard, Terminplan (GANTT mit Aufgaben und Meilensteinen), Aufgaben, Leistung (erbrachter Leistungswert je Phase), Dateien, Protokolle (Besprechungsprotokolle) und Einstellungen (Projektstammdaten, Honorar, beauftragte Leistungsphasen).
Datenhaltung
- Vollständig relationales SQLite-Schema statt eines JSON-Dokuments je Woche; Projekt- und Personen-IDs bleiben über Neustarts stabil.
- Eine Sitzung ("KW XX / YYYY") entspricht einer Kalenderwoche. Der Wechsel in eine neue Sitzung läuft automatisch im Hintergrund (stündliche Prüfung) — es gibt keine "Neue Sitzung"-Schaltfläche mehr.
- Der Server legt bei jedem Start automatisch einen Zeitstempel-Snapshot
unter
sessions/backups/an und behält nur die neuesten (Anzahl einstellbar unter Admin → Betrieb & Sicherheit). Ein Admin kann zusätzlich jederzeit ein Backup herunterladen oder eine Sicherung zurückspielen. - Hochgeladene Dateien (Freigabe-Workflow, importierte Protokolle) liegen
unter
sessions/uploads/<uuid>.<endung>, referenziert über die Datenbank.
Authentifizierung & Rollen
Echte serverseitige Sitzungen (Cookie, scrypt-gehashte Passwörter) — kein
clientseitiger Passwortschutz. Zwei Rollen: admin und member; nur
wirklich destruktive bzw. administrative Aktionen (Benutzerverwaltung,
Sitzung löschen/entsperren, DB-Import/-Backup) sind serverseitig auf Admins
beschränkt. Zu viele Fehlversuche sperren ein Konto vorübergehend.
Besonderheiten
- Keine Abteilungstrennung mehr: Alle Sitzungen, Projekte und Personen
liegen in einer gemeinsamen Liste.
ELT/HLS/ARCHbezeichnen heute nur noch die Fachrichtung eines Benutzerkontos bzw. die Gewerke eines Projekts. - Protokoll-Import kann ein hochgeladenes PDF/Word-Dokument KI-gestützt (eigener OpenAI- oder Claude-Schlüssel je Konto, auch ein lokal laufendes Modell möglich) in Besprechungspunkte umwandeln und fällt ohne Schlüssel oder bei einem Fehler automatisch auf eine Text-Heuristik zurück.
- Der PDF-Export lädt
pdfmakevoncdnjs.cloudflare.com— benötigt Internetzugang. - Feiertage werden serverseitig berechnet (keine externe Abhängigkeit), die KI-gestützte Protokoll-Erkennung braucht dagegen Internetzugang bzw. ein erreichbares lokales Modell.
Weiterführende Dokumentation
CLAUDE.md im Projektstamm enthält die ausführliche technische
Dokumentation: Server-API, vollständiges Datenmodell, Architekturentscheidungen
und ihre Begründung. Ausgangspunkt für tiefere Änderungen am Code.