README erklärt das Projekt, Zusicherungen unter Nummern
Prüfung / Lint, Typen, Tests (push) Canceled after 0s
Prüfung / Images bauen (pdf) (push) Canceled after 0s
Prüfung / Images bauen (web) (push) Canceled after 0s
Prüfung / Images bauen (worker) (push) Canceled after 0s
Images / bauen (pdf, docker/pdf.Dockerfile) (push) Canceled after 0s
Images / bauen (web, docker/web.Dockerfile) (push) Canceled after 0s
Images / bauen (worker, docker/worker.Dockerfile) (push) Canceled after 0s

Die README beschrieb das Vorgehen statt der Anwendung. Sie erklärt jetzt, was
das System kann, wie es aufgebaut ist und wie man es lokal und im Betrieb
fährt.

Dazu tragen die acht Zusicherungen dort ihre Nummern — Berechtigungsprüfung in
der Abfrage, kein DELETE im Verlauf, Protokollpflicht ab Stufe 3, Magic Bytes
statt Dateiendungen, Skelette statt Spinner, Existenz als Information, keine
Geheimnisse im Repository, keine Einmal-Container. Achtzehn Dateien verwiesen
für ebendiese Regeln auf eine Datei, die nicht mehr mitverfolgt wird; sie
zeigen jetzt auf die README.

Arbeitsunterlagen bleiben auf der Platte, werden aber nicht mehr verfolgt. Die
Ausschlussregel steht in .git/info/exclude statt in .gitignore, damit sie nicht
selbst im Repository steht.
This commit is contained in:
Harlekin
2026-09-04 08:42:07 +02:00
parent d7fdbb54f4
commit 319ef6a997
20 changed files with 80 additions and 48 deletions
+59 -28
View File
@@ -1,45 +1,71 @@
# AfiS-Aktensystem
Fallakten-, Personalakten- und Ermittlungsverwaltung für die Abteilung für innere Sicherheit
eines SCP-RP-Servers. Anmeldung und Berechtigungen laufen vollständig über Discord.
Fall- und Personalaktenverwaltung für die Abteilung für innere Sicherheit eines
SCP-RP-Servers. Anmeldung und Berechtigungen laufen vollständig über Discord.
## Los geht's
Interne Anwendung für eine geschlossene Gruppe von zehn bis fünfzig Personen, selbst
gehostet. Keine Mandantentrennung, keine öffentliche Registrierung.
1. Ordner in ein leeres Git-Repository legen
2. Discord-Application anlegen, Bot einladen, **Server Members Intent aktivieren**
3. Claude Code im Projektordner starten
## Was es kann
Gehostet wird als **ein Dockge-Stack** auf dem Homeserver. Die fertige `compose.yaml` und die
Einrichtungsschritte stehen in `docs/11-betrieb.md`. Die `.env` wird nicht im Repository
gepflegt, sondern im `.env`-Reiter von Dockge; `.env.example` ist nur die Vorlage.
- **Fallakten** mit Kopfdaten, Abschnitten nach Vorlage und einem Verlauf, der nur wächst
- **Personalakten**, überwiegend für Externe, mit Aktenblatt zum Ausdrucken
- **Abteilungen** als Ebene darüber: was zu ihnen aktenkundig ist, ergibt sich aus ihren
Mitgliedern
- **Dokumente** nach Vorlage, an einer Fall- oder Personalakte
- **Fünfstufige Klassifizierung** mit feldgenauer Schwärzung
- **Volltextsuche** je Freigabestufe, Kommandopalette auf Strg+K
- **Chat** in jeder Akte, mit Übernahme einer Nachricht als Vermerk
- **Export** als PDF mit Wasserzeichen, jeder Abruf protokolliert
- **Zugriffsprotokoll** über jede schreibende Aktion und jeden Lesezugriff ab Stufe 3
Claude Code liest `CLAUDE.md` von selbst. Die Fachdokumente liegen in `docs/`, der Bauplan
in `TASKS.md`.
## Zusicherungen
## Erste Anweisung an Claude Code
Acht Regeln, die im Code und wo möglich in der Datenbank durchgesetzt sind. Sie sind der
Grund, warum das System so gebaut ist, wie es gebaut ist — Codekommentare verweisen unter
ihrer Nummer hierher.
> Lies CLAUDE.md und alle Dateien in docs/. Fass in fünf Sätzen zusammen, was gebaut wird,
> und nenn mir alles, was in den Dokumenten widersprüchlich oder unklar ist, bevor du
> anfängst. Baue noch nichts.
Danach Phase für Phase aus `TASKS.md`. Siehe `docs/12-arbeiten-mit-claude-code.md`.
1. **Berechtigungsprüfung immer serverseitig und immer in der Datenbankabfrage.** Niemals
alle Datensätze laden und danach filtern.
2. **Verlaufseinträge dürfen nachträglich geändert werden, aber niemals unsichtbar.** Jede
Änderung erzeugt eine Version, jede Zurücknahme lässt einen Grabstein stehen, beides ist
für alle sichtbar, die den Eintrag sehen dürfen. Es gibt kein `DELETE` — das steht als
Regel in der Datenbank, nicht nur in der Anwendung.
3. **Jede schreibende Aktion und jeder Lesezugriff ab Stufe 3 erzeugt einen
Protokolleintrag.**
4. **Keine Dateiendungen als Typprüfung.** Immer Magic Bytes. Kein SVG, kein HTML, keine
Archive.
5. **Keine Blockade-Spinner.** Jede Ansicht hat ein Skelett, jede Änderung eine sofortige
Rückmeldung.
6. **Existenz ist auch eine Information.** Akten oberhalb der Sichtstufe tauchen weder in
Listen noch in Trefferzahlen noch in Rückverweisen auf. Kein Zugriff heisst 404, nicht 403.
7. **Keine Geheimnisse im Repository.** Alles über `.env`, Vorlage in `.env.example`.
8. **Keine Einmal-Container.** Der Betrieb läuft über Dockge, das beendete Container nicht
dauerhaft anzeigt. Migrationen gehören ins Startkommando von `web`, wiederkehrende
Aufgaben in Dauerläufer mit eigenem Cron. Jeder Dienst braucht einen Healthcheck, weil
das in Dockge die Statusanzeige ist.
## Aufbau
```
CLAUDE.md Projektanweisung, wird automatisch gelesen
TASKS.md Bauplan in neun Phasen
docs/ Fachdokumente, dazu 13-entscheidungen.md
compose.yaml Der Dockge-Stack
.env.example Vorlage für den .env-Reiter in Dockge
web/ Next.js 15, App Router
worker/ discord.js, Rollen-Abgleich
pdf/ Playwright, PDF-Erzeugung
web/ Next.js 15, App Router, React 19
worker/ discord.js, gleicht Rollen und Mitgliedschaft ab
pdf/ Playwright, erzeugt die PDF-Ausdrucke
packages/db/ Prisma-Schema, Migrationen, Seed
docker/ Dockerfiles für web, worker und pdf
compose.yaml Der Dockge-Stack
.env.example Vorlage für den .env-Reiter in Dockge
```
Stack: Next.js 15 mit React 19 und TypeScript, Auth.js v5 mit Discord-Provider, Prisma auf
PostgreSQL 16, Tailwind ohne Komponentenbibliothek. ClamAV und Playwright laufen als eigene
Container.
## Einrichten
Discord-Application anlegen, Bot auf den Server einladen und **Server Members Intent
aktivieren** — ohne das liefert der Bot keine Rollen.
## Lokal entwickeln
Node 22 und pnpm 9.
@@ -66,9 +92,13 @@ pnpm test:e2e
```
`pnpm test` legt sich eine eigene Datenbank `afis_test` an und lässt die
Entwicklungsdatenbank in Ruhe. Grund in `docs/13-entscheidungen.md`.
Entwicklungsdatenbank in Ruhe: Verlaufseinträge und Protokollzeilen sind nach Regel 2 nicht
löschbar, was ein Test dort anlegt, bliebe für immer stehen.
## Betrieb kurz gefasst
## Betrieb
Gehostet als **ein** Dockge-Stack. Die `.env` wird nicht im Repository gepflegt, sondern im
`.env`-Reiter von Dockge.
| | |
|---|---|
@@ -76,3 +106,4 @@ Entwicklungsdatenbank in Ruhe. Grund in `docs/13-entscheidungen.md`.
| Erreichbarkeit | Cloudflare Tunnel, kein offener Port am Router |
| Aktualisieren | Dockge → Stack → Update, Migration läuft automatisch mit |
| Backup | zwei Dauerläufer mit Cron: nächtlicher Dump plus restic offsite |
| Wiederherstellung | `scripts/restore-test.sh` spielt einen Dump in eine Wegwerf-Datenbank und vergleicht Zeilenzahlen, Regeln und Trigger |