# BauDoc Bahn Webbasierte, mehrbenutzerfähige Baustellen- und Dokumentenverwaltung für Eisenbahninfrastruktur-Projekte (EIU). Fachliche Grundlage ist die **EIU-Ablagestruktur** des Auftraggebers – 159 Ordner und 944 Soll-Unterlagen mit Fachbereichsrelevanz, Aufbewahrungsfrist, Medium und Übergabezeitpunkt. > Die Ursprungsdatei `2-EIU-Ablagestruktur.xlsx` ist als Unterlage des Auftraggebers > **nicht Teil dieses Repositories**. Der daraus aufbereitete Katalog liegt in > `app/prisma/data/ablagestruktur.json` und wird beim Start eingespielt. ## Schnellstart ```bash cp .env.example .env # AUTH_SECRET setzen: openssl rand -base64 48 docker compose up -d --build ``` | Dienst | Adresse | Zweck | |---|---|---| | Anwendung | http://localhost:3400 | Weboberfläche | | Mailpit | http://localhost:8025 | fängt im Testbetrieb alle E-Mails ab | | PostgreSQL | localhost:5433 | Datenbank | Beim ersten Start werden Schema, Ablagestruktur-Katalog und ein vollständig durchgespieltes Demo-Projekt angelegt. **Demo-Zugänge** (Kennwort jeweils `baudoc2026`): | E-Mail | Rolle | |---|---| | `admin@baudoc.local` | Administration | | `m.kruse@infrago.local` | Projektleitung (PL) | | `t.albrecht@infrago.local` | Bauherrenvertretung (BHV) | | `j.hoffmann@infrago.local` | Bauüberwacher Bahn (BÜB) | | `s.linnemann@infrago.local` | Fachbauüberwacherin (FBÜ) | | `r.pauls@infrago.local` | Kaufmännische Steuerung | | `d.wegener@bahnplan.local` | Planung | | `bauleitung@nordbahn.local` | Auftragnehmer | > Der interessanteste Einstieg: als **j.hoffmann** anmelden → Projekt öffnen → > *Rechnungsprüfung* → Abschlagsrechnung `2026-AR-0431`. ## Technik Bewusst schmal gehalten – vier bewegliche Teile, keine Fremddienste: - **Next.js 16 / React 19 / TypeScript** – Oberfläche und Server-Logik in einem Prozess - **PostgreSQL 16 + Prisma** – Datenhaltung - **Eigene Session-Authentifizierung** (bcrypt, HttpOnly-Cookie) statt zusätzlichem Auth-Dienst - **Nodemailer** gegen ein beliebiges SMTP-Relais; im Testbetrieb Mailpit ### Persistenz ohne Named Volumes Alle persistenten Daten liegen als Bind-Mount direkt im Compose-Verzeichnis: ``` data/postgres/ Datenbankdateien data/files/ hochgeladene Dokumente, als normale Dateien lesbar: ///. data/mail/ Mailpit-Postfach (nur Testbetrieb) ``` Ein Backup ist damit `tar czf backup.tgz data/`, ein Umzug ein Kopiervorgang. Die Ablage bleibt auch ohne die Anwendung lesbar; jede Datei trägt ihre SHA-256-Prüfsumme in der Datenbank, nachträgliche Veränderungen sind erkennbar. ## Module | Modul | Inhalt | |---|---| | **Dokumentationsstand** | Die Excel als lebendes Cockpit: Soll-Ist je Projekt, gefiltert auf die Fachbereiche, Fristen aus dem Übergabezeitpunkt, Ampel, Verantwortliche, CSV-Rückexport | | **Dokumente (DMS)** | Versionierung, Prüf-/Freigabeworkflow, Vertraulichkeitsstufen, Volltext- und Metadatensuche, Zuordnung zur Ablagestruktur | | **Bautagebuch** | Tageseinträge nach Ril 809.0301: Wetter, Betra/Sperrpause, Personal- und Gerätestunden, besondere Vorkommnisse; nach Abschluss gesperrt | | **Meldungen & Mängel** | Behinderungs-, Bedenken-, Mängelanzeige, Mehrkosten/AvL, Unfall – mit Fristen und Nachverfolgung | | **Verträge & Nachträge** | LV-Positionen, Nachtragsstatus und Stellungnahme der Bauüberwachung, Auftragsvolumen | | **Stunden & Aufmaß** | Auftragnehmer reicht ein, Bauüberwachung erkennt **zeilenweise** an – das ist die Messlatte der Rechnungsprüfung | | **Rechnungsprüfung** | Automatischer Abgleich gegen Vertrag, Aufmaß, Stundenzettel und Vorrechnungen; getrennte Bescheinigung *sachlich richtig* / *rechnerisch richtig* / Zahlungsfreigabe | | **Kommunikation** | Projektkanäle statt E-Mail-Pingpong, `@Nachname`-Erwähnungen, E-Mail-Benachrichtigung je nach Profileinstellung | | **Verwaltung** | Benutzer, Firmen, revisionssicheres Protokoll aller Vorgänge | ### Rechnungsprüfung – geprüfte Befunde `src/lib/rechnungspruefung.ts` prüft je Rechnungsposition und auf Rechnungsebene: - kein Vertragsbezug / unbekannte OZ - Einheitspreis weicht vom Vertrag ab - Menge ohne bzw. über anerkanntem Aufmaß (inkl. Anrechnung der Vorrechnungen) - Stunden ohne Zettel, über anerkannten Stunden, abweichender Stundensatz, unbelegter Zuschlag, nicht bestätigter Zettel - Doppelabrechnung eines Stundenlohnzettels - Nachtragsleistung ohne beauftragten Nachtrag - Rechenfehler in Zeile, Umsatzsteuer und Brutto - kumulierte Abrechnung über der Auftragssumme inkl. Nachträge - Hinweis bei Mengenmehrung > 110 % (§ 2 Abs. 3 VOB/B) Ergebnis ist ein Prüfbericht mit vorgeschlagener Kürzung. Die Entscheidung trifft weiterhin ein Mensch; jeder Schritt wird protokolliert. ## Rollen und Berechtigungen ### Das Grundprinzip: zwei Seiten, nicht Hierarchie Die Rollen bilden **nicht** ab, wer wem vorgesetzt ist, sondern auf welcher Seite des Bauvertrags jemand steht. Das ist die Trennlinie, an der alle Rechte hängen: | | | |---|---| | **Auftraggeberseite (AG)** – der Bauherr, also das EIU | vergibt, überwacht, prüft, gibt frei. Sieht alles. Rollen: `PROJEKTLEITER`, `BAUHERRENVERTRETER`, `BAUUEBERWACHER`, `FACHBAUUEBERWACHER`, `KAUFMANN` | | **Auftragnehmerseite (AN)** – die Baufirma | liefert, meldet, rechnet ab. Sieht ausschließlich die eigenen Daten. Rolle: `AUFTRAGNEHMER` | | **Zuarbeitende und Mitlesende** | `PLANER`, `PRUEFER`, `BETREIBER`, `LESER` | Wichtig für das Verständnis der Demo: `bauleitung@nordbahn.local` ist die **Bauleitung der Baufirma**, also Auftragnehmerseite. Wer die Baustelle für den Bauherrn führt, ist in der Bahnwelt nicht der „Bauleiter“, sondern der **Bauüberwacher Bahn (BÜB)** – `j.hoffmann@infrago.local`. ### Die einzelnen Rollen | Rolle | Wer das ist | Darf im Kern | |---|---|---| | `ADMIN` | IT-Administration | alles, zusätzlich Benutzerverwaltung und Protokoll | | `PROJEKTLEITER` (PL) | Projektleitung beim EIU | Projekt anlegen und steuern, Rollen vergeben, Zahlungen freigeben | | `BAUHERRENVERTRETER` (BHV) | Bauherrenvertretung vor Ort | Bautagebuch gegenzeichnen, freigeben, Zahlungen freigeben | | `BAUUEBERWACHER` (BÜB) | Bauüberwacher Bahn | Bautagebuch führen, Stunden und Aufmaße anerkennen, **sachlich richtig** bescheinigen | | `FACHBAUUEBERWACHER` (FBÜ) | Fachbauüberwachung | wie BÜB, aber beschränkt auf die zugewiesenen Fachbereiche; **keine** sachliche Bescheinigung | | `KAUFMANN` | kaufmännische Projektsteuerung | Verträge und Nachträge pflegen, **rechnerisch richtig** bescheinigen | | `PLANER` | Planungsbüro | Planunterlagen in die Ablagestruktur einstellen | | `AUFTRAGNEHMER` (AN) | Bauleitung der Baufirma | Stundenzettel und Aufmaße einreichen, Behinderungs- und Bedenkenanzeigen stellen, Unterlagen einstellen | | `PRUEFER` | Gutachter, Prüfingenieur, TÜV | Fachunterlagen lesen, Prüfvermerke und Meldungen erfassen | | `BETREIBER` | Anlagenbetreiber / Instandhaltung | Betreiberakte (Teil II) lesen | | `LESER` | Mitlesende ohne Aufgabe | nur lesen | Die Zuordnung erfolgt **je Projekt**. Dieselbe Person kann in Projekt A Bauüberwacher und in Projekt B nur Leser sein. Bei Fachbauüberwachern wird zusätzlich je Fachbereich eingegrenzt. ### Vollständige Matrix Quelle ist `app/src/lib/rbac.ts`; die Tabelle ist von dort erzeugt. Spalte AN zeigt das Rollenrecht; ein `(○)` bedeutet: greift zusätzlich nur, wenn der passende Projektschalter gesetzt ist (siehe Abschnitt *Je Projekt einstellbar*). | Recht | ADM | PL | BHV | BÜB | FBÜ | KFM | PLA | AN | PRF | BTR | LES | |---|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:| | Projekt anlegen | × | × | | | | | | | | | | | Projekt bearbeiten | × | × | × | | | | | | | | | | Rollen im Projekt vergeben | × | × | | | | | | | | | | | Projekteinstellungen ändern | × | × | × | | | | | | | | | | Dokumente lesen | × | × | × | × | × | × | × | × | × | × | × | | Dokumente einstellen | × | × | × | × | × | × | × | (○) | | | | | Dokumente freigeben | × | × | × | × | × | | | | | | | | Dokumente löschen | × | × | | | | | | | | | | | Interne Unterlagen sehen | × | × | × | × | × | × | | | | | | | Dokumentationsstand einsehen | × | × | × | × | × | × | × | (○) | × | × | × | | Dokumentationsstand steuern | × | × | × | × | | | | | | | | | Bautagebuch lesen | × | × | × | × | × | × | | (○) | × | | × | | Bautagebuch führen | × | | | × | × | | | | | | | | Bautagebuch gegenzeichnen | × | × | × | | | | | | | | | | Meldung anlegen | × | × | × | × | × | | | × | × | | | | Meldung bearbeiten | × | × | × | × | × | | | | | | | | Meldung schließen | × | × | | × | | | | | | | | | Verträge lesen | × | × | × | × | | × | | (○) | | | | | Verträge bearbeiten | × | × | | | | × | | | | | | | Nachtrag prüfen | × | × | | × | | | | | | | | | Stundenzettel einreichen | × | | | | | | | × | | | | | Stundenzettel anerkennen | × | | | × | × | | | | | | | | Aufmaß einreichen | × | | | | | | | × | | | | | Aufmaß anerkennen | × | | | × | × | | | | | | | | Rechnung erfassen | × | | | | | × | | × | | | | | Rechnung einsehen | × | × | × | × | | × | | (○) | | | | | **sachlich richtig** | × | | | × | | | | | | | | | **rechnerisch richtig** | × | | | | | × | | | | | | | Zahlung freigeben | × | × | × | | | | | | | | | | Nachrichten schreiben | × | × | × | × | × | × | × | × | × | × | | | Kanal anlegen | × | × | × | × | | | | | | | | | Benutzerverwaltung | × | | | | | | | | | | | | Firmenstamm | × | × | | | | | | | | | | | Protokoll einsehen | × | | | | | | | | | | | ### Je Projekt einstellbar Was Auftragnehmer sehen dürfen, ist **keine Entscheidung im Code**, sondern eine des Bauherrn – einstellbar beim Anlegen und jederzeit unter *Projekt → Einstellungen* (nur Projektleitung und Bauherrenvertretung): | Schalter | Voreinstellung | Wirkung | |---|:-:|---| | Eigenen Vertrag einsehen | **an** | Reiter „Verträge & Nachträge“ mit dem eigenen LV und den eigenen Nachträgen samt Stellungnahme der Bauüberwachung | | Stand der eigenen Rechnungen verfolgen | **an** | Reiter „Rechnungsprüfung“ mit Prüfstand und Befunden zu den eigenen Rechnungen | | Bautagebuch lesen | aus | Leserecht auf das Bautagebuch des Bauherrn | | Dokumentationsstand einsehen | aus | Soll-Ist der Ablagestruktur – sinnvoll, wenn die Baufirma selbst zuliefert | | Unterlagen einstellen | **an** | Nachweise und Protokolle direkt hochladen statt per E-Mail | | Bescheinigung trotz kritischer Befunde | **an** | Erlaubt „sachlich richtig“ bei offenen Prüfbefunden – nur mit Begründung, protokolliert. Abgeschaltet müssen erst alle Befunde geklärt sein. | **Diese Schalter steuern ausschließlich die Sichtbarkeit von Bereichen, niemals den Datenumfang.** Ein Auftragnehmer sieht in jedem Fall nur Verträge, Aufmaße, Stundenzettel und Rechnungen der eigenen Firma. Diese Schranke hängt allein an der Rolle (`isExternalOnly()` in `src/lib/rbac.ts`) und ist durch keine Einstellung aufhebbar; die Datenbankabfragen filtern zusätzlich auf `companyId`. Bewusst nicht geschaltet: Der Reiter **Beteiligte** zeigt allen Projektbeteiligten, welche Firmen und Personen mitwirken. Das entspricht Position B.I 0 der Ablagestruktur, die genau diese Liste als aufzubewahrende Unterlage fordert. ### Projekt anlegen Projektleitung und Administration legen Projekte unter *Projekte → Projekt anlegen* an. Aus **Bauherrenseite** und **Fachbereichen** ergibt sich, welche der 944 Soll-Unterlagen einschlägig sind – das Formular zeigt die Zahl live mit, bevor gespeichert wird. Aus den **Terminen** werden Meilensteine und die Fristen der Soll-Unterlagen berechnet. Zur Orientierung, wie stark die Fachbereichsauswahl wirkt (Bauherrenseite Fahrweg): | Auswahl | Soll-Unterlagen | |---|--:| | nur Oberbau | 367 | | Oberbau + LST | 425 | | alle 9 Fachbereiche | 737 | | Personenbahnhöfe, alle 7 Fachbereiche | 510 | Werden Termine oder Fachbereiche später geändert, zieht *Einstellungen → Speichern und Soll-Katalog nachziehen* fehlende Positionen nach und rechnet die Fristen aller noch offenen Positionen neu. Einmal angelegte Positionen werden nie gelöscht – nicht mehr zutreffende setzt man einzeln auf „entfällt“, dann bleibt der Grund dokumentiert. ### Absichtliche Sperren Diese Einschränkungen sind keine Lücken, sondern Zweck der Sache: - **Sachlich und rechnerisch richtig kann nie dieselbe Person bescheinigen.** Die Prüfung ist zusätzlich zeitlich gekoppelt: erst BÜB, dann kaufmännische Steuerung, dann Freigabe. - **Der Bauüberwacher kann keine Zahlung freigeben** – er bescheinigt nur, dass die Leistung erbracht ist. Die Freigabe liegt bei PL oder BHV. - **Der Fachbauüberwacher kann nicht sachlich bescheinigen** – er arbeitet dem BÜB zu. - **Auftragnehmer sehen nur die eigene Firma.** Verträge, Stunden, Aufmaße und Rechnungen anderer Baufirmen sind für sie nicht vorhanden, ebenso wenig als intern oder vertraulich gekennzeichnete Unterlagen. - **Wer nicht im Projekt eingetragen ist, sieht das Projekt nicht** – auch nicht in der Liste. Sperren, die auf einer bewussten Handlung beruhen, werden protokolliert: etwa die sachliche Bescheinigung trotz kritischer Prüfbefunde, die nur mit Begründung möglich ist. ## Bekannte Lücken im Rollenmodell Keine offenen Punkte. Die drei zuvor dokumentierten Lücken sind geschlossen: 1. **Projektanlage** – Oberfläche vorhanden (`/projekte/neu`), Recht `projekt.anlegen` wird geprüft, inklusive Mitgliederverwaltung unter *Einstellungen*. 2. **Auftragnehmer und eigener Vertrag** – über den Projektschalter *Eigenen Vertrag einsehen* steuerbar, voreingestellt an. 3. **Auftragnehmer und eigene Rechnungen** – über den Projektschalter *Stand der eigenen Rechnungen verfolgen* steuerbar, voreingestellt an. Bei der Umsetzung fielen zwei weitere Stellen auf, an denen Auftragnehmern Daten fremder Firmen angezeigt wurden; beide sind behoben: - die Projekt-Übersichtsseite listete alle Verträge und Gesamtsummen des Projekts, - das Erfassungsformular für Meldungen bot alle Firmen und Vertragsnummern zur Auswahl an. Geprüft wird das durch einen Suchlauf über alle ausgelieferten Seiten – inklusive des eingebetteten React-Payloads – auf Vertragsnummer, Firmenname, Kreditorennummer und LV-Kurztexte einer Fremdfirma. ## Entwicklung ohne Docker ```bash cd app npm install cp ../.env.example .env # DATABASE_URL auf localhost:5433 zeigen lassen npx prisma db push npx tsx prisma/seed.ts npm run dev # http://localhost:3000 ``` ## Betrieb - `AUTH_SECRET` vor dem Produktivbetrieb zwingend ersetzen. - `SMTP_*` auf ein echtes Relais richten und den `mail`-Dienst entfernen. - Die Anwendung terminiert kein TLS – hinter einen Reverse Proxy stellen. - `MAX_UPLOAD_MB` steuert die Obergrenze je Datei (Standard 200 MB). - Backup: `docker compose stop && tar czf backup-$(date +%F).tgz data/` ## Offene Punkte für die nächste Ausbaustufe Bewusst noch nicht umgesetzt, weil dafür Rücksprache mit dem Auftraggeber nötig ist: - Anbindung an vorhandene DB-Systeme (eBTB, DB-GIS, SAP-Kreditorenstamm, iTWO/GAEB) - Import von LV und Rechnungen als GAEB/X-Rechnung statt manueller Erfassung - Volltextindizierung von PDF-Inhalten (OCR) - Anmeldung über das Unternehmensverzeichnis (LDAP/SSO) - Mobile Erfassung vor Ort inkl. Fotodokumentation mit Geo-Bezug - Automatische Fristenmails als Tageszusammenfassung (Cron)