# 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 1. **Berechtigungsprüfung immer serverseitig und immer in der Datenbankabfrage.** Niemals alle Datensätze laden und danach filtern. Siehe `docs/03-auth-und-rechte.md`. 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`. Welche Änderungen erlaubt sind, steuert die Änderungsrichtlinie in `docs/05-akten-und-vorlagen.md`. 3. **Jede schreibende Aktion und jeder Lesezugriff auf Stufe 3+ erzeugt einen Audit-Eintrag.** 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 Mutation eine sofortige Reaktion. Siehe `docs/09-performance-und-ux.md`, das ist keine Kür. 6. **Existenz ist auch eine Information.** Akten oberhalb der Sichtstufe des Nutzers tauchen weder in Listen noch in Trefferzahlen noch in Rückverweisen auf. 7. Keine Secrets im Repo. Alles über `.env`, Vorlage in `.env.example`. 8. **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 in `docs/01-produkt.md` legt die Übersetzungen fest. ## Kommandos ```bash 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 test` laufen lassen.