CLAUDE.md und README.md verweisen auf docs/, die Dateien lagen aber im Wurzelverzeichnis. Verschoben. docs/13-entscheidungen.md hält fest, wo die Dokumente sich widersprechen und wie es aufgelöst wurde. Der wichtigste Punkt: 04-datenmodell.md verlangt eine Regel, die jedes UPDATE auf CaseEntryVersion verwirft, 05-akten-und-vorlagen.md verlangt, dass eine Umklassifizierung rückwirkend auf alle Versionen wirkt. Beides zusammen geht nicht. Aufgelöst über einen Trigger, der die Tabelle anhängend hält, aber das Anheben von minClearance zulässt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
4.5 KiB
4.5 KiB
AfiS-Aktensystem
Interne Web-Anwendung für die Abteilung für innere Sicherheit (AfiS) eines SCP-RP-Servers. Verwaltet Fallakten, Personalakten und Ermittlungen mit einem mehrstufigen Klassifizierungssystem. Anmeldung und Berechtigungen laufen vollständig über Discord.
Dies ist ein Rollenspiel-Werkzeug für eine geschlossene Gruppe von etwa 10 bis 50 Personen, selbst gehostet auf einem Homeserver. Kein Multi-Tenant, keine öffentliche Registrierung.
Stack
- Next.js 15, App Router, React 19, TypeScript strict
- Auth.js v5 (Discord Provider)
- Prisma + PostgreSQL 16
- Tailwind CSS, keine Komponentenbibliothek (siehe
docs/10-design-system.md) - Separater Node-Dienst
worker/mit discord.js für Rollen-Abgleich - ClamAV und Playwright als eigene Container
- Betrieb als ein Dockge-Stack, siehe
docs/11-betrieb.md. Kein Reverse Proxy im Stack, TLS und Kompression macht der Cloudflare Tunnel.
Dokumentation
Vor dem Bau eines Bereichs immer das passende Dokument lesen:
| Datei | Inhalt |
|---|---|
docs/01-produkt.md |
Domäne, Glossar, Rollen der Nutzer |
docs/02-architektur.md |
Dienste, Datenflüsse, Verzeichnisstruktur |
docs/03-auth-und-rechte.md |
Discord-Login, Rollen-Mapping, Zugriffsprüfung |
docs/04-datenmodell.md |
Prisma-Schema, Indizes, Migrationen |
docs/05-akten-und-vorlagen.md |
Aktenaufbau, Vorlagen, Versionierung, Schwärzung |
docs/06-chat-und-realtime.md |
Aktenchat, SSE, Benachrichtigungen |
docs/07-dateien-und-sicherheit.md |
Upload-Prüfkette, Auslieferung |
docs/08-suche-und-export.md |
Volltextsuche, PDF-Export |
docs/09-performance-und-ux.md |
Ladezustände, optimistische Updates, Latenzbudgets |
docs/10-design-system.md |
Farben, Typografie, Komponentenregeln |
docs/11-betrieb.md |
Dockge-Stack, compose.yaml, Backups |
docs/13-entscheidungen.md |
Aufgelöste Widersprüche der Dokumente, getroffene Festlegungen |
TASKS.md enthält die Bauphasen. Arbeite sie in Reihenfolge ab und hake ab, was fertig ist.
Harte Regeln
- Berechtigungsprüfung immer serverseitig und immer in der Datenbankabfrage.
Niemals alle Datensätze laden und danach filtern. Siehe
docs/03-auth-und-rechte.md. - 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. Welche Änderungen erlaubt sind, steuert die Änderungsrichtlinie indocs/05-akten-und-vorlagen.md. - Jede schreibende Aktion und jeder Lesezugriff auf Stufe 3+ erzeugt einen Audit-Eintrag.
- Keine Dateiendungen als Typprüfung. Immer Magic Bytes. Kein SVG, kein HTML, keine Archive.
- Keine Blockade-Spinner. Jede Ansicht hat ein Skelett, jede Mutation eine sofortige
Reaktion. Siehe
docs/09-performance-und-ux.md, das ist keine Kür. - Existenz ist auch eine Information. Akten oberhalb der Sichtstufe des Nutzers tauchen weder in Listen noch in Trefferzahlen noch in Rückverweisen auf.
- Keine Secrets im Repo. Alles über
.env, Vorlage in.env.example. - Keine Einmal-Container und keine Init-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.
Sprachkonvention
- Code, Datenbank, API: Englisch.
Case,CaseEntry,PersonnelFile,ClearanceLevel. - Oberfläche und Dokumentation: Deutsch. Alle UI-Texte zentral in
lib/i18n/de.ts, nie hart im JSX. Das Glossar indocs/01-produkt.mdlegt die Übersetzungen fest.
Kommandos
pnpm dev # Next.js Dev-Server
pnpm worker:dev # Discord-Sync-Worker
pnpm db:migrate # Prisma Migration anwenden
pnpm db:seed # Testdaten inkl. Vorlagen
pnpm db:studio # Prisma Studio
pnpm test # Vitest
pnpm test:e2e # Playwright
pnpm lint && pnpm typecheck
pnpm build # Standalone-Build für das Container-Image
Arbeitsweise
- Kleine Commits pro abgeschlossener Aufgabe aus
TASKS.md. - Für jede Zugriffsregel einen Test, der den negativen Fall prüft: Nutzer ohne Freigabe sieht nichts, findet nichts, bekommt 404 statt 403.
- Bei Unklarheiten in der Fachlichkeit nicht raten, sondern nachfragen.
- Nach jeder Phase
pnpm lint && pnpm typecheck && pnpm testlaufen lassen.