Files
AfiS-Aktensystem/TASKS.md
T
HarlekinandClaude Opus 5 70bcfdc4d8 Zwei Freigaben, Aktenzeichen-Muster und Einzeldokument-Export festgelegt
Aus den echten Dokumenten der Abteilung, die bisher als Google Docs geführt
wurden.

Die Dokumente tragen zwei Angaben nebeneinander, "Foundation-Freigabe" und
"Interne Freigabe". Den Zugriff steuert allein die interne Freigabe; die
Foundation-Freigabe wird ein gewöhnliches Vorlagenfeld. Mit zwei sperrenden
Achsen bekäme jede Sichtbarkeitsprüfung, jede Trefferzahl und jeder
Negativtest eine zweite Dimension — Sichtbarkeit wird an genau einer Stelle
entschieden, sonst ist sie nicht mehr nachweisbar.

Das Aktenzeichen der Abteilung lautet AKT-PA-2026-62843, das Glossar schrieb
AfiS-2026-0042 vor. Das Muster gehört zur Vorlage, nicht ins Programm:
Präfix und Stellenzahl je Fallart, Nummernkreis je Präfix und Jahr.

docs/08 kannte nur den Export einer ganzen Akte. Dokumente wie der
Sonderarbeitsvertrag hängen aber an einer Person, nicht an einer Ermittlung,
und brauchen einen eigenen Weg: Deckblatt, Dokument, Fußzeile, kein Verlauf.
Stufe des Abrufers, Wasserzeichen und Protokollierung gelten dort genauso.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 23:21:38 +02:00

6.8 KiB

Bauplan

Phasen in Reihenfolge abarbeiten. Am Ende jeder Phase muss pnpm lint && pnpm typecheck && pnpm test durchlaufen und die Anwendung startbar sein.

Phase 0 — Gerüst

  • Next.js 15 mit TypeScript strict, Tailwind, pnpm-Workspace mit web/ und worker/
  • Prisma, Postgres im Compose, erste Migration
  • Design-Tokens aus docs/10-design-system.md als CSS-Variablen, IBM Plex selbst gehostet
  • lib/i18n/de.ts mit den ersten Texten, Konvention: keine deutschen Strings im JSX
  • Vitest und Playwright eingerichtet, ein rauchender Test je Ebene
  • .env.example gefüllt, compose.yaml aus docs/11-betrieb.md als Dockge-Stack lauffähig (zunächst nur web, db, pgbouncer)
  • Dockerfiles für web, worker und pdf, GitHub-Actions-Workflow schiebt die Images in die GitHub Container Registry
  • /api/health prüft Datenbank, Discord-Gateway und ClamAV, wird vom Healthcheck genutzt

Phase 1 — Anmeldung und Rechte

Das ist der schwierigste Teil. Wenn er steht, ist der Rest Formularbau.

  • Auth.js mit Discord-Provider, Scope identify, state und PKCE
  • Bot-Client mit Bot-Token, Guild-Mitgliedschaftsprüfung im Callback
  • Eigene Session in der Datenbank, Cookie-Einstellungen wie in docs/03-auth-und-rechte.md
  • worker/: discord.js am Gateway, Ereignisse plus Voll-Abgleich alle 5 Minuten
  • pg_notify bei Rollenänderung, Cache-Invalidierung in der Web-App
  • EffectivePermissions mit prozesslokalem Cache
  • BOOTSTRAP_ADMIN_IDS als Notfallzugang
  • Adminseite Rollen-Mapping: Tabelle der Discord-Rollen, Stufe per Auswahl, Rechte per Kästchen, Vorschau „Was sieht Stufe 2?"
  • Sessions werden bei Rollenverlust oder Serveraustritt beendet
  • Zwischenstand: eingeloggte Seite zeigt Name, Rollen, errechnete Stufe und Rechte
  • Negativtests aus docs/03-auth-und-rechte.md grün, soweit sie ohne Akten prüfbar sind. Die vier zu nachträglichen Änderungen an Verlaufseinträgen gehören zu Phase 2
  • entry.edit_own, entry.edit_any, entry.retract und case.edit_closed als Rechte angelegt, im Auslieferungszustand keiner Rolle zugeordnet

Phase 2 — Akten

  • Datenmodell für Case, CaseSection, CaseEntry, Beteiligte, Ausschlüsse
  • lib/access/ mit Where-Fragmenten, überall verwendet, nirgends Nachfilterung
  • Aktenzeichen-Vergabe kollisionsfrei über CaseCounter
  • Fallliste mit Filtern, cursorbasiert, loading.tsx mit Skelett
  • Aktenansicht: Kopfdaten sofort, Verlauf in eigener Suspense-Grenze (Chat: Phase 6)
  • Vermerk anlegen, optimistisch, mit clientseitiger UUIDv7
  • Statusübergänge mit Rechteprüfung und automatischem Systemeintrag
  • Schreibgrenzen nach docs/03-auth-und-rechte.md: keine Akte über der eigenen Stufe anlegen, Ändern nur mit Lesezugriff, Klassifizierung nachträglich änderbar bis zur eigenen Stufe. Kein Löschen von Akten, nur ARCHIVED und SEALED
  • Umklassifizierung erzeugt SYSTEM-Eintrag und AuditLog mit alter und neuer Stufe
  • Negativtests dazu: Stufe 2 kann keine Stufe-4-Akte anlegen, nicht ändern, nicht hochstufen, auch nicht über einen direkten Aufruf der Server Action
  • Audit-Log für alle schreibenden Aktionen und Lesezugriffe ab Stufe 3
  • Nachträgliche Änderungen an Verlaufseinträgen nach docs/05-akten-und-vorlagen.md: CaseEntryVersion, Karenzzeit, Pflichtbegründung, bearbeitet · vN mit Diff-Historie
  • Zurückziehen mit Grabstein und Pflichtbegründung, kein hartes Löschen
  • Postgres-Regeln gegen DELETE auf CaseEntry und CaseEntryVersion
  • Änderungsübersicht als Reiter an der Akte
  • Adminseite für AppSetting: Änderungsrichtlinie, Karenzzeit, Markierungsverhalten

Phase 3 — Vorlagen und Abschnitte

  • CaseTemplate mit Feldtypen aus docs/05-akten-und-vorlagen.md
  • Aktenzeichen-Muster je Vorlage: Präfix und Stellenzahl, Nummernkreis je Präfix und Jahr
  • Feld „Foundation-Freigabe" als gewöhnliches Vorlagenfeld, ohne Wirkung auf den Zugriff
  • Vorlagen-Editor im Adminbereich, versioniert, mit Vorschau
  • Abschnitte rendern und bearbeiten, Autosave lokal alle 2 Sekunden
  • Versionierung mit Diff-Ansicht
  • Konflikterkennung über mitgesendete Version, 409 mit Vergleichsansicht
  • minClearance pro Feld, serverseitige Ersetzung durch Platzhalter
  • Schwärzungs-Auszeichnung im Freitext, Parser in lib/redaction.ts
  • Seed mit vier Startvorlagen

Phase 4 — Personalakten und Verknüpfungen

  • PersonnelFile, auch für Personen ohne Discord-Konto
  • Dokumente an der Personalakte aus Vorlagen, z. B. Sonderarbeitsvertrag
  • Beteiligte einer Akte mit Rolle
  • Rückverweise auf der Personalakte, durch die Sichtbarkeitsprüfung gefiltert
  • Verknüpfungen zwischen Akten
  • Test: Stufe-1-Nutzer sieht auf einer Personalakte keinen Hinweis auf Stufe-3-Fälle

Phase 5 — Dateien

  • Upload-Endpunkt mit Quarantäne, Limits, Kontingent
  • Typprüfung über Magic Bytes, Whitelist
  • ClamAV-Container angebunden
  • Neu-Kodierung mit sharp und qpdf, Vorschaubild und Blurhash
  • Auslieferung über /api/files/[id] mit Rechteprüfung und harten Headern
  • Upload-UI: lokale Vorschau, Fortschrittsbalken, Zustand „Wird geprüft"
  • SSE-Ereignis attachment.scanned aktualisiert die Anzeige

Phase 6 — Chat und Echtzeit

  • SSE-Endpunkt mit LISTEN/NOTIFY, Heartbeat, Reconnect mit Last-Event-ID
  • Aktenchat mit Antworten, Reaktionen, Bearbeiten, Zurückziehen
  • Optimistisches Senden mit Dedupe über Client-ID
  • Aktenzeichen-Erkennung mit serverseitig aufgelöster Vorschaukarte
  • Ungelesen-Markierung und Trennlinie
  • Freie Kanäle mit eigener Mindeststufe
  • „Als Vermerk übernehmen"
  • Discord-Benachrichtigungen über den Worker, ohne Inhalte

Phase 7 — Suche

  • search_vector mit Trigger und Gewichtung, GIN-Index
  • Suchseite mit Filtern, Debounce, AbortController, gedimmte alte Treffer
  • Sichtbarkeitsprüfung in derselben Abfrage, auch für Facettenzähler
  • Kommandopalette auf Strg+K
  • Gespeicherte Ansichten

Phase 8 — Export

  • Druckansicht /faelle/[caseNumber]/druck mit @media print
  • Playwright-Container erzeugt PDF, Ergebnis gecacht
  • Schwärzung und Wasserzeichen im Export
  • Freigabeverfahren ab Stufe 3
  • Einzeldokument als PDF, ohne Verlauf, Aussehen aus der Vorlage
  • ZIP-Sammelexport und JSON-Vollexport für Admins

Phase 9 — Schliff

  • Dashboard: meine Fälle, Fristen, ungelesene Chats, letzte Aktivität
  • Beobachtungsliste
  • Helles Thema
  • Mobile Ansicht durchgehen, besonders Akte und Chat
  • Web-Vitals-Erfassung und Anzeige im Adminbereich
  • Bundle-Analyse, Budget aus docs/09-performance-und-ux.md einhalten
  • Backup-Wiederherstellung einmal von Hand testen