Erstimport. Fachliche Grundlage ist die EIU-Ablagestruktur des Auftraggebers (2-EIU-Ablagestruktur.xlsx): 1.106 Zeilen, aufbereitet zu 159 Ordnern und 944 Soll-Unterlagen mit Fachbereichsrelevanz, Aufbewahrungsfrist, Medium und Übergabezeitpunkt. Module - Dokumentationsstand: Soll-Ist je Projekt, Fristen aus dem Übergabezeitpunkt und den Projektterminen, Ampel, CSV-Rückexport im Format der Ursprungsdatei - Dokumentenmanagement mit Versionen, Freigabelauf, SHA-256-Prüfsummen - Bautagebuch nach Ril 809.0301, nach Abschluss gesperrt - Meldungen und Mängel (Behinderung, Bedenken, Mangel, AvL, Unfall) - Verträge, Nachträge, Aufmaße, Stundenlohnzettel mit zeilenweiser Anerkennung - Rechnungsprüfung: automatischer Abgleich gegen Vertrag, anerkanntes Aufmaß, bestätigte Stundenzettel und Vorrechnungen; getrennte Bescheinigung sachlich richtig / rechnerisch richtig / Zahlungsfreigabe - Kommunikation mit Projektkanälen, Erwähnungen und E-Mail-Benachrichtigung - Revisionssicheres Protokoll aller Vorgänge Rechte Rollen nach dem Vorgabeprozess Bauüberwachung (PL, BHV, BÜB, FBÜ, kaufmännische Steuerung, Planung, Auftragnehmer, Prüfer, Betreiber), Zuordnung je Projekt. Auftragnehmer sehen ausschließlich Daten der eigenen Firma; diese Schranke hängt allein an der Rolle. Welche Bereiche ihnen überhaupt angezeigt werden, entscheidet der Bauherr je Projekt über Schalter in den Einstellungen. Betrieb Docker Compose mit Anwendung, PostgreSQL und Mailpit. Keine Named Volumes – alle persistenten Daten liegen als Bind-Mount unter data/ im Compose- Verzeichnis, damit ein Backup ein Kopiervorgang bleibt. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
296 lines
15 KiB
Markdown
296 lines
15 KiB
Markdown
# 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:
|
||
<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** | 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)
|