Der Discord-Server hat drei Sorten Rollen, die Dokumente kannten nur eine: Zugehörigkeit (AfiS, Personalabteilung) als Türsteher, Rangrollen für die Rechte, Zugangsrollen für die Freigabestufe. Das bestehende RoleMapping trägt das fast, es fehlt nur der Türsteher. Die beiden Felder dafür kommen mit Phase 1, die Struktur ist in docs/13-entscheidungen.md festgehalten. Die Freigabestufen heißen jetzt wie die Zugangsrollen: Unclassified, Restricted Access, Confidential Access, Sensitive Access, Critical Operations, Executive Oversight. Fachbegriffe der Domäne bleiben englisch, auch in einer deutschen Oberfläche. Die Bezeichnungen sind damit Daten in ClearanceLevelConfig, nicht mehr Oberflächentext in lib/i18n/de.ts: sie sind im Adminbereich änderbar, und was der Leiter ändern kann, gehört nicht in eine Übersetzungsdatei. StampMark bekommt den Namen hereingereicht. Vier neue Tests prüfen den Zustand, den der Seed herstellt, gegen die Datenbank statt gegen eine Konstante im Code. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
95 lines
4.9 KiB
Markdown
95 lines
4.9 KiB
Markdown
# 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.
|
|
- **Fachbegriffe der Domäne bleiben englisch**, so wie sie auf dem Discord heißen:
|
|
Rollennamen, Dienstgrade und die Bezeichnungen der Freigabestufen (`Sensitive Access`,
|
|
nicht `Geheim`). Die Oberfläche ist deutsch, die Begriffe darin sind es nicht. Nicht
|
|
eindeutschen. Diese Namen sind Daten, keine Oberflächentexte: sie stehen in der
|
|
Datenbank und sind im Adminbereich änderbar, nicht in `lib/i18n/de.ts`.
|
|
|
|
## 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.
|