Files
duffyduckandClaude Opus 5 84eb93c59f Rolleneditor: eigene Rollen neben den Standardrollen
Rechte sind jetzt die Grundgröße, eine Rolle ist ein benanntes Bündel davon.
Die elf Standardrollen stehen weiterhin im Code und sind unveränderlich –
Prüfvermerke und Bescheinigungen berufen sich auf sie. Daneben lassen sich
eigene Rollen anlegen.

Rolleneditor unter Verwaltung > Rollen & Rechte
- Rolle aus einer Standardrolle als Vorlage ableiten oder von Grund auf anlegen
- Rechte nach Modul gruppiert ankreuzen, mit Sammelschaltern je Gruppe
- Seite des Bauvertrags festlegen (Auftraggeber / Auftragnehmer / Zuarbeit) –
  bestimmt die Datensicht, unabhängig von der Rechteliste
- bearbeiten, stilllegen, löschen; die Rechtematrix zeigt eigene Rollen mit an

Grenzen
- Administrationsrechte sind nicht über eine Rolle vergebbar, sonst ließe sich
  über eine selbst gebaute Rolle die Benutzerverwaltung erreichen
- eine Rolle ohne jedes Recht wird abgelehnt
- eine vergebene Rolle lässt sich weder stilllegen noch löschen
- die Vier-Augen-Trennung bleibt unabhängig von der Rolle bestehen

Umbau der Rechteauswertung
- Rechte werden an genau einer Stelle ermittelt: rechteImProjekt() führt
  Standardrollen und eigene Rollen zu einer Rechtelage zusammen, die Seiten und
  Server Actions über rechte.darf() bzw. rechte.pruefe() befragen
- die Firmenschranke hängt nun an der Seite des Bauvertrags, die jede Rolle
  mitbringt, statt an einer festen Liste privilegierter Standardrollen
- ProjectMember trägt wahlweise eine Standardrolle oder eine eigene Rolle

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 14:13:38 +02:00

20 KiB
Raw Permalink Blame History

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

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

Kennwörter liegen als bcrypt-Hash (Kostenfaktor 11). Sitzungen sind serverseitig in der Datenbank hinterlegt und lassen sich dadurch gezielt beenden beim Sperren eines Zugangs, beim Zurücksetzen eines Kennworts und bei jeder Kennwortänderung.

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:
                 <Projektnummer>/<Jahr>/<Hash-Präfix>/<Hash>.<ext>
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 Zugänge anlegen und sperren, Kennwörter zurücksetzen, Firmenstamm, Rollenlegende, revisionssicheres Protokoll

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. In der Anwendung zeigt Verwaltung → Rollen & Rechte dieselbe Matrix, dort um die eigenen Rollen ergänzt.

Ausgewertet werden Rechte an genau einer Stelle: rechteImProjekt() führt Standardrollen und eigene Rollen zu einer Rechtelage zusammen, die jede Seite und jede Server Action über rechte.darf(...) bzw. rechte.pruefe(...) befragt.

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 Seite des Bauvertrags, die jede Rolle mitbringt (Rechtelage.nurEigeneFirma 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.

Benutzerverwaltung

Unter Verwaltung (nur für Zugänge mit Administrationsrecht), in vier Reitern:

Reiter Inhalt
Benutzer Zugänge anlegen, bearbeiten, sperren und entsperren, Kennwort zurücksetzen
Firmen Firmenstamm mit Art, Anschrift, Kreditorennummer und USt-IdNr.
Rollen & Rechte Rolleneditor für eigene Rollen, Legende aller Rollen und die vollständige Rechtematrix
Protokoll Alle Vorgänge mit Filter nach Aktion und Person

Kennwörter. Beim Anlegen wird ein Startkennwort erzeugt und genau einmal angezeigt (auf Wunsch zusätzlich per E-Mail versandt). Es ist nirgends im Klartext gespeichert. Wer sich damit anmeldet, landet unmittelbar auf der Profilseite und muss ein eigenes Kennwort vergeben; bis dahin weist ein Streifen im Kopfbereich darauf hin. Ein Zurücksetzen durch die Administration beendet zugleich alle laufenden Sitzungen.

Zugänge werden gesperrt, nicht gelöscht. Bautagebucheinträge, Prüfvermerke und die Bescheinigungen sachlich richtig und rechnerisch richtig müssen auch nach Jahren einer Person zuordenbar bleiben bei bis zu 38 Jahren Aufbewahrung nach Bauschlussmeldung ist das keine Nebensache. Sperren beendet sofort alle Sitzungen.

Aussperrschutz. Der eigene Zugang kann weder gesperrt noch der eigenen Administration entzogen werden, und es muss stets mindestens ein aktiver Administrationszugang bestehen. Firmen mit bestehenden Verträgen lassen sich nicht stilllegen.

Projektrollen werden nicht hier vergeben, sondern im jeweiligen Projekt unter Einstellungen → Beteiligte. Das Administrationsrecht ist davon unabhängig und wirkt projektübergreifend entsprechend sparsam vergeben.

Eigene Rollen

Die elf Standardrollen sind Teil des Programms sie bilden den Vorgabeprozess ab und lassen sich weder ändern noch löschen. Prüfvermerke und Bescheinigungen berufen sich auf sie; ein nachträglich verändertes Rollenverständnis würde die Nachvollziehbarkeit alter Vorgänge zerstören.

Zusätzliche Rollen entstehen unter Verwaltung → Rollen & Rechte → Rolle anlegen:

  1. Vorlage wählen (optional) übernimmt Rechte und Seite einer Standardrolle als Ausgangspunkt. Ohne Vorlage beginnt man bei null.
  2. Seite des Bauvertrags festlegen Auftraggeberseite (sieht das ganze Projekt) oder Auftragnehmerseite bzw. Zuarbeit (sieht ausschließlich die eigene Firma). Das ist die folgenreichste Angabe: Sie bestimmt die Datensicht, nicht die Rechteliste.
  3. Rechte ankreuzen gruppiert nach Modul, mit Sammelschaltern je Gruppe.

Typischer Anlass: eine Bauüberwachung, die das Bautagebuch führt und Stunden anerkennt, aber die sachliche Richtigkeit nicht bescheinigen soll. Vorlage Bauüberwacher Bahn wählen, das Recht sachlich richtig bescheinigen abwählen, fertig.

Eigene Rollen werden im Projekt unter Einstellungen → Beteiligte genauso vergeben wie Standardrollen und erscheinen in allen Rechteübersichten mit dem Vermerk „eigene Rolle".

Grenzen, die auch der Rolleneditor nicht überschreitet:

  • Administrationsrechte (Benutzerverwaltung, Firmenstamm, Protokoll) lassen sich nicht über eine Rolle vergeben sonst käme man über eine selbst gebaute Rolle an die Benutzerverwaltung und damit an jede andere Schranke. Sie werden ausschließlich am Zugang gesetzt.
  • Eine Rolle ohne jedes Recht wird abgelehnt.
  • Eine Rolle, die noch vergeben ist, lässt sich weder stilllegen noch löschen.
  • Die Vier-Augen-Trennung bleibt: Wer sachlich richtig bescheinigt hat, kann dieselbe Rechnung nicht rechnerisch richtig bescheinigen unabhängig von der Rolle.

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

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)