Files
AfiS-Aktensystem/README.md
T
Harlekin e0b03ea336
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
Gedankenstriche durch Bindestriche ersetzt
375 Vorkommen in 210 Dateien. Betrifft Kommentare, Oberflaechentexte und die
README; an keiner Stelle Bedeutung, nur Zeichensetzung.
2026-09-04 08:54:52 +02:00

110 lines
4.6 KiB
Markdown

# AfiS-Aktensystem
Fall- und Personalaktenverwaltung für die Abteilung für innere Sicherheit eines
SCP-RP-Servers. Anmeldung und Berechtigungen laufen vollständig über Discord.
Interne Anwendung für eine geschlossene Gruppe von zehn bis fünfzig Personen, selbst
gehostet. Keine Mandantentrennung, keine öffentliche Registrierung.
## Was es kann
- **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
## Zusicherungen
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.
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
```
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.
```bash
corepack enable && pnpm install
docker run -d --name afis-db -e POSTGRES_DB=afis -e POSTGRES_USER=afis \
-e POSTGRES_PASSWORD=afis -p 5434:5432 postgres:16-alpine
cp .env.example .env
# DATABASE_URL und DIRECT_DATABASE_URL auf localhost:5434 zeigen lassen
pnpm --filter @afis/db run build # erzeugt den Prisma-Client
pnpm db:deploy && pnpm db:seed
pnpm dev
```
Prüfen wie die CI:
```bash
pnpm lint && pnpm typecheck && pnpm test
pnpm test:e2e
```
`pnpm test` legt sich eine eigene Datenbank `afis_test` an und lässt die
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
Gehostet als **ein** Dockge-Stack. Die `.env` wird nicht im Repository gepflegt, sondern im
`.env`-Reiter von Dockge.
| | |
|---|---|
| Verwaltung | Dockge, ein Stack namens `afis` unter `/opt/stacks/afis/` |
| 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 |