dms-kanban: Security-Folgetickets SEC-01 bis SEC-07 aus Review angelegt
Legt 7 Tickets für verifizierte Security-Befunde (Fable 5.1, main, Datei:Zeile-Belege) im neuen Epic "Sicherheit" an: unauthentifizierter Vernichtungs-Rückruf, Mail-Postfach- verwaltung ohne Rollenprüfung, Guard-Lücken bei Trash/Folders/Triggers, Virenscan nicht standardmäßig eingereiht, unbegrenztes Upload-Limit, TENANT_SLUG-Lücke im Modul-Verifier, ALLOW_CALLER_IDENTITY-Auth-Bypass. Alle als Backlog auf board.csv/board.json übernommen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6d024e1d46
commit
d8bf392dbb
9 files changed
+786
-142
No files matched your search
+113
-72
@@ -21,7 +21,7 @@ Fehlgeschlagene Jobs landen nach n Versuchen in der DLQ
|
||||
Job-Status ist abfragbar","Absturz eines Workers führt zu erneuter Zustellung
|
||||
Idempotenz bei Doppelzustellung nachgewiesen
|
||||
DLQ-Eintrag manuell wiederholbar"
|
||||
FDN-07,CI-Pipeline & Testharness,⚙️ Fundament,DevOps,Einfach,2,2,Backlog,"CI-Runner, Unit-/E2E-Testrunner","Automatisierte Pipeline für Lint, Typprüfung, Unit- und E2E-Tests sowie Build-Artefakt. Testdatenbank wird pro Lauf frisch aufgesetzt.",FDN-01,QA-01 QA-02,"Pipeline läuft bei jedem Push
|
||||
FDN-07,CI-Pipeline & Testharness,⚙️ Fundament,DevOps,Einfach,2,2,Fertig,"CI-Runner, Unit-/E2E-Testrunner","Automatisierte Pipeline für Lint, Typprüfung, Unit- und E2E-Tests sowie Build-Artefakt. Testdatenbank wird pro Lauf frisch aufgesetzt.",FDN-01,QA-01 QA-02,"Pipeline läuft bei jedem Push
|
||||
Roter Test blockiert den Merge
|
||||
Testabdeckung wird ausgewiesen
|
||||
CI-Pipeline führt Dependency-/Supply-Chain-Scanning aus (govulncheck für Go-Module, npm audit für JS/TS-Pakete), Build schlägt bei kritischen bekannten Schwachstellen fehl.
|
||||
@@ -30,7 +30,7 @@ Pipeline-Laufzeit unter vereinbartem Grenzwert
|
||||
Artefakt ist reproduzierbar erzeugbar
|
||||
Absichtlich eingeführte bekannte Schwachstelle in einer Testabhängigkeit lässt den Build fehlschlagen.
|
||||
Merge-Versuch eines sicherheitsrelevanten Codepfads ohne Test wird von der Pipeline blockiert."
|
||||
FDN-08,"Logging, Metriken & Fehler-Tracking",⚙️ Fundament,DevOps,Einfach,2,2,Backlog,"Strukturierte Logs, Metrics-Endpoint","Strukturiertes Logging mit Korrelations-ID, technische Metriken und zentrale Fehlererfassung inklusive Alarmierung.",FDN-01,QA-02,"Jede Anfrage besitzt eine Korrelations-ID über alle Schichten
|
||||
FDN-08,"Logging, Metriken & Fehler-Tracking",⚙️ Fundament,DevOps,Einfach,2,2,Fertig,"Strukturierte Logs, Metrics-Endpoint","Strukturiertes Logging mit Korrelations-ID, technische Metriken und zentrale Fehlererfassung inklusive Alarmierung.",FDN-01,QA-02,"Jede Anfrage besitzt eine Korrelations-ID über alle Schichten
|
||||
Metriken für Latenz, Fehlerrate und Queue-Länge vorhanden
|
||||
Unbehandelte Fehler werden zentral gemeldet","Provozierter Fehler erscheint innerhalb einer Minute im Tracking
|
||||
Logs enthalten keine Passwörter oder Tokens
|
||||
@@ -42,259 +42,259 @@ SHA-256 jeder Revision wird auf Klartext berechnet (vor FDN-09-Verschlüsselung)
|
||||
Abbruch bei 50 % und Fortsetzung ergibt identische Prüfsumme
|
||||
Parallel-Upload von 20 Dateien ohne Datenverlust
|
||||
Nach Upload ist file_revisions.checksum_sha256 befüllt und entspricht der SHA-256 des hochgeladenen Klartexts"
|
||||
DOC-02,Dublettenerkennung,🗂️ Dokumentenkern,Backend,Einfach,2,4,Backlog,"SHA-256, Unique-Index","Prüfsumme jeder Datei berechnen, speichern und bei Upload gegen den Bestand prüfen. Nutzer entscheidet über Verwerfen oder bewusstes Duplikat.",DOC-01,SRC-02 SRC-05,"Prüfsumme wird bei jedem Upload persistiert
|
||||
DOC-02,Dublettenerkennung,🗂️ Dokumentenkern,Backend,Einfach,2,4,Fertig,"SHA-256, Unique-Index","Prüfsumme jeder Datei berechnen, speichern und bei Upload gegen den Bestand prüfen. Nutzer entscheidet über Verwerfen oder bewusstes Duplikat.",DOC-01,SRC-02 SRC-05,"Prüfsumme wird bei jedem Upload persistiert
|
||||
Treffer wird dem Nutzer mit Verweis auf das Original gemeldet
|
||||
Bewusstes Duplikat ist möglich und wird markiert","Identische Datei zweimal hochgeladen erzeugt Warnung
|
||||
Datei mit einem geänderten Byte gilt nicht als Duplikat
|
||||
Prüfsummenberechnung bei Großdatei bleibt im Zeitbudget"
|
||||
DOC-03,Drag-and-Drop-Upload-Oberfläche,🗂️ Dokumentenkern,Frontend,Mittel,3,4,Backlog,"Dropzone, Fortschrittsanzeige","Upload-Oberfläche mit Ablagebereich, Mehrfachauswahl, Fortschritt je Datei, Abbrechen und verständlichen Fehlermeldungen.",DOC-01,QA-03,"Mehrere Dateien gleichzeitig per Drag-and-Drop
|
||||
DOC-03,Drag-and-Drop-Upload-Oberfläche,🗂️ Dokumentenkern,Frontend,Mittel,3,4,Fertig,"Dropzone, Fortschrittsanzeige","Upload-Oberfläche mit Ablagebereich, Mehrfachauswahl, Fortschritt je Datei, Abbrechen und verständlichen Fehlermeldungen.",DOC-01,QA-03,"Mehrere Dateien gleichzeitig per Drag-and-Drop
|
||||
Fortschritt und Status je Datei sichtbar
|
||||
Fehlgeschlagene Datei einzeln wiederholbar","Upload per Tastatur und Dateidialog bedienbar
|
||||
Verhalten bei Netzabbruch im Browser geprüft
|
||||
Mobile Ansicht bleibt bedienbar"
|
||||
DOC-04,Vorschau- & Thumbnail-Pipeline,🗂️ Dokumentenkern,Backend,Komplex,5,4,Backlog,"Renderer-Worker, Bildableitungen","Asynchrone Erzeugung von Seiten-Vorschauen und Thumbnails nach dem Upload, mit Cache und Wiederaufbau bei neuer Revision.",DOC-01 FDN-04,DOC-05 QA-10,"Thumbnail steht nach definierter Zeit bereit
|
||||
DOC-04,Vorschau- & Thumbnail-Pipeline,🗂️ Dokumentenkern,Backend,Komplex,5,4,Fertig,"Renderer-Worker, Bildableitungen","Asynchrone Erzeugung von Seiten-Vorschauen und Thumbnails nach dem Upload, mit Cache und Wiederaufbau bei neuer Revision.",DOC-01 FDN-04,DOC-05 QA-10,"Thumbnail steht nach definierter Zeit bereit
|
||||
Vorschau wird gecacht und bei neuer Revision erneuert
|
||||
Fehlerhafte Datei blockiert die Pipeline nicht","Beschädigte PDF-Datei führt zu Fehlerstatus statt Absturz
|
||||
Durchsatztest mit 500 Dokumenten
|
||||
Cache-Invalidierung bei neuer Revision belegt"
|
||||
DOC-05,PDF-Viewer-Komponente,🗂️ Dokumentenkern,Frontend,Komplex,4,5,Backlog,PDF.js im Web-Worker,"Inline-Betrachter mit Seitennavigation, Zoom, Suche im Dokument und Textauswahl – ohne Download-Zwang.",DOC-04,DOC-13 QA-03 VER-04,"PDF wird ohne Download angezeigt
|
||||
DOC-05,PDF-Viewer-Komponente,🗂️ Dokumentenkern,Frontend,Komplex,4,5,Fertig,PDF.js im Web-Worker,"Inline-Betrachter mit Seitennavigation, Zoom, Suche im Dokument und Textauswahl – ohne Download-Zwang.",DOC-04,DOC-13 QA-03 VER-04,"PDF wird ohne Download angezeigt
|
||||
Zoom, Blättern und Textsuche funktionieren
|
||||
Große Dokumente werden seitenweise nachgeladen","300-seitiges PDF öffnet im Zeitbudget
|
||||
Viewer per Tastatur bedienbar
|
||||
Speicherverbrauch im Browser bleibt stabil"
|
||||
DOC-06,Office-zu-PDF-Konverter,🗂️ Dokumentenkern,Backend,Komplex,4,4,Backlog,Headless-Konverter im Worker,"Serverseitige Konvertierung von Text-, Tabellen- und Präsentationsformaten in PDF als Vorschau- und Archivderivat.",FDN-04,QA-03 VER-07,"Gängige Office-Formate werden konvertiert
|
||||
DOC-06,Office-zu-PDF-Konverter,🗂️ Dokumentenkern,Backend,Komplex,4,4,Fertig,Headless-Konverter im Worker,"Serverseitige Konvertierung von Text-, Tabellen- und Präsentationsformaten in PDF als Vorschau- und Archivderivat.",FDN-04,QA-03 VER-07,"Gängige Office-Formate werden konvertiert
|
||||
Konvertierung läuft isoliert mit Zeitlimit
|
||||
Ergebnis wird als Derivat der Revision abgelegt","Layouttreue an Referenzdokumenten geprüft
|
||||
Zeitlimit bei Endlosdokument greift
|
||||
Konverter-Absturz beeinträchtigt andere Jobs nicht"
|
||||
DOC-07,Download & signierte URLs,🗂️ Dokumentenkern,Backend,Einfach,2,4,Backlog,Presigned URLs,"Download von Original und Derivaten über kurzlebige signierte URLs, inklusive korrektem Dateinamen und Berechtigungsprüfung.",DOC-01,DOC-08,"Download liefert Originaldatei unverändert
|
||||
DOC-07,Download & signierte URLs,🗂️ Dokumentenkern,Backend,Einfach,2,4,Fertig,Presigned URLs,"Download von Original und Derivaten über kurzlebige signierte URLs, inklusive korrektem Dateinamen und Berechtigungsprüfung.",DOC-01,DOC-08,"Download liefert Originaldatei unverändert
|
||||
URL läuft nach kurzer Frist ab
|
||||
Ohne Leseberechtigung kein Download","Prüfsumme vor und nach Download identisch
|
||||
Weitergegebene abgelaufene URL wird abgewiesen
|
||||
Sonderzeichen im Dateinamen korrekt übertragen"
|
||||
DOC-08,Massenexport als ZIP,🗂️ Dokumentenkern,Backend,Mittel,3,5,Backlog,"ZIP-Streaming, Export-Job","Auswahl mehrerer Dokumente als Hintergrund-Job zu einem Archiv bündeln, inklusive optionaler Metadaten-Datei und Download-Benachrichtigung.",DOC-07 FDN-04,QA-03 DOC-18,"Export läuft als Job und blockiert die Oberfläche nicht
|
||||
DOC-08,Massenexport als ZIP,🗂️ Dokumentenkern,Backend,Mittel,3,5,Fertig,"ZIP-Streaming, Export-Job","Auswahl mehrerer Dokumente als Hintergrund-Job zu einem Archiv bündeln, inklusive optionaler Metadaten-Datei und Download-Benachrichtigung.",DOC-07 FDN-04,QA-03 DOC-18,"Export läuft als Job und blockiert die Oberfläche nicht
|
||||
Archiv enthält Dokumente und Metadaten-Beilage
|
||||
Nur berechtigte Dokumente landen im Archiv","Export von 1000 Dokumenten ohne Speicherüberlauf
|
||||
Archiv in gängigen Entpackern lesbar
|
||||
Berechtigungsfilter durch Negativtest belegt"
|
||||
DOC-09,Ordner- & Kabinettmodell,🗂️ Dokumentenkern,Backend,Mittel,3,3,Backlog,"Baumstruktur, Materialized Path","Hierarchische Ablage mit Verschieben, Umbenennen und effizienten Teilbaum-Abfragen.",FDN-02,DOC-10 DOC-11 DOC-14,"Beliebig tiefe Hierarchie abbildbar
|
||||
DOC-09,Ordner- & Kabinettmodell,🗂️ Dokumentenkern,Backend,Mittel,3,3,Fertig,"Baumstruktur, Materialized Path","Hierarchische Ablage mit Verschieben, Umbenennen und effizienten Teilbaum-Abfragen.",FDN-02,DOC-10 DOC-11 DOC-14,"Beliebig tiefe Hierarchie abbildbar
|
||||
Verschieben aktualisiert den gesamten Teilbaum
|
||||
Teilbaum-Abfrage bleibt performant","Zyklus beim Verschieben wird verhindert
|
||||
Abfrage bei 10.000 Ordnern im Zeitbudget
|
||||
Umbenennen bricht keine Verweise"
|
||||
DOC-10,Ordner-Navigation & Dokumentenliste,🗂️ Dokumentenkern,Frontend,Mittel,3,4,Backlog,"Baum-Navigation, virtualisierte Liste","Navigationsbaum, Brotkrumenpfad und virtualisierte Dokumentenliste mit Sortierung, Spaltenwahl und Mehrfachauswahl.",DOC-09,QA-03,"Baum und Liste bleiben synchron
|
||||
DOC-10,Ordner-Navigation & Dokumentenliste,🗂️ Dokumentenkern,Frontend,Mittel,3,4,Fertig,"Baum-Navigation, virtualisierte Liste","Navigationsbaum, Brotkrumenpfad und virtualisierte Dokumentenliste mit Sortierung, Spaltenwahl und Mehrfachauswahl.",DOC-09,QA-03,"Baum und Liste bleiben synchron
|
||||
Liste bleibt bei vielen Einträgen flüssig
|
||||
Mehrfachauswahl mit Umschalt- und Strg-Taste","Liste mit 10.000 Zeilen scrollt ruckelfrei
|
||||
Navigation vollständig per Tastatur
|
||||
Zustand bleibt beim Zurücknavigieren erhalten"
|
||||
DOC-11,Soft-Delete & Papierkorb-Logik,🗂️ Dokumentenkern,Backend,Einfach,2,4,Backlog,"Soft-Delete, Aufräum-Job",Löschen setzt einen Papierkorb-Status statt physischer Entfernung. Endgültige Bereinigung erfolgt nach konfigurierbarer Frist.,DOC-09,DOC-12,"Gelöschte Objekte verschwinden aus allen normalen Ansichten
|
||||
DOC-11,Soft-Delete & Papierkorb-Logik,🗂️ Dokumentenkern,Backend,Einfach,2,4,Fertig,"Soft-Delete, Aufräum-Job",Löschen setzt einen Papierkorb-Status statt physischer Entfernung. Endgültige Bereinigung erfolgt nach konfigurierbarer Frist.,DOC-09,DOC-12,"Gelöschte Objekte verschwinden aus allen normalen Ansichten
|
||||
Wiederherstellung stellt Ablageort und Metadaten wieder her
|
||||
Endgültige Löschung entfernt auch die Dateiobjekte","Gelöschtes Dokument taucht in Suche und Liste nicht mehr auf
|
||||
Wiederherstellung nach Ordnerlöschung getestet
|
||||
Aufräum-Job löscht nur abgelaufene Einträge"
|
||||
DOC-12,Papierkorb-Oberfläche,🗂️ Dokumentenkern,Frontend,Einfach,2,5,Backlog,"Listenansicht, Bestätigungsdialog","Ansicht des Papierkorbs mit Restlaufzeit, Einzel- und Massenwiederherstellung sowie bestätigter endgültiger Löschung.",DOC-11,QA-03,"Restlaufzeit je Eintrag sichtbar
|
||||
DOC-12,Papierkorb-Oberfläche,🗂️ Dokumentenkern,Frontend,Einfach,2,5,Fertig,"Listenansicht, Bestätigungsdialog","Ansicht des Papierkorbs mit Restlaufzeit, Einzel- und Massenwiederherstellung sowie bestätigter endgültiger Löschung.",DOC-11,QA-03,"Restlaufzeit je Eintrag sichtbar
|
||||
Wiederherstellung einzeln und in Auswahl möglich
|
||||
Endgültiges Löschen erfordert ausdrückliche Bestätigung","Versehentliches Löschen ohne Bestätigung nicht möglich
|
||||
Massenwiederherstellung mit 100 Objekten geprüft
|
||||
Leerer Papierkorb zeigt verständlichen Hinweis"
|
||||
SRC-01,Suchindex-Infrastruktur,🔍 Suche & OCR,DevOps,Mittel,3,2,Backlog,Manticore Search (BM25),"Suchdienst bereitstellen, Index-Schema mit deutscher Sprachbehandlung definieren und Betriebsparameter festlegen.",FDN-01,SRC-02,"Suchdienst ist reproduzierbar startbar
|
||||
SRC-01,Suchindex-Infrastruktur,🔍 Suche & OCR,DevOps,Mittel,3,2,Fertig,Manticore Search (BM25),"Suchdienst bereitstellen, Index-Schema mit deutscher Sprachbehandlung definieren und Betriebsparameter festlegen.",FDN-01,SRC-02,"Suchdienst ist reproduzierbar startbar
|
||||
Index-Schema mit Feldern und Gewichtung dokumentiert
|
||||
Deutsche Stemming- und Stoppwortbehandlung aktiv","Neuaufbau des Index aus dem Bestand möglich
|
||||
Umlaut- und Kompositasuche liefert Treffer
|
||||
Neustart des Dienstes ohne Datenverlust"
|
||||
SRC-02,Indexierungs-Worker & Synchronisierung,🔍 Suche & OCR,Backend,Komplex,4,5,Backlog,"Queue-Worker, Bulk-Indexing","Änderungen an Dokumenten, Metadaten und OCR-Texten laufend in den Suchindex übertragen, inklusive Voll-Reindexierung.",SRC-01 DOC-01 FDN-04 DOC-02,SRC-03,"Neues Dokument ist zeitnah auffindbar
|
||||
SRC-02,Indexierungs-Worker & Synchronisierung,🔍 Suche & OCR,Backend,Komplex,4,5,Fertig,"Queue-Worker, Bulk-Indexing","Änderungen an Dokumenten, Metadaten und OCR-Texten laufend in den Suchindex übertragen, inklusive Voll-Reindexierung.",SRC-01 DOC-01 FDN-04 DOC-02,SRC-03,"Neues Dokument ist zeitnah auffindbar
|
||||
Änderung und Löschung werden im Index nachgezogen
|
||||
Voll-Reindexierung ohne Ausfall möglich","Konsistenzabgleich Datenbank gegen Index ergibt keine Abweichung
|
||||
Indexierung von 10.000 Dokumenten im Zeitbudget
|
||||
Ausfall des Suchdienstes führt zu Nachholung statt Datenverlust"
|
||||
SRC-03,Such-API mit Ranking,🔍 Suche & OCR,Backend,Mittel,3,6,Backlog,"Suchabfrage, Relevanz-Tuning","Suchschnittstelle mit Paginierung, Sortierung, Treffer-Ausschnitten und Berücksichtigung der Leseberechtigung.",SRC-02,QA-10 SRC-04 SRC-08,"Ergebnisse enthalten Textausschnitte mit Fundstellen
|
||||
SRC-03,Such-API mit Ranking,🔍 Suche & OCR,Backend,Mittel,3,6,Fertig,"Suchabfrage, Relevanz-Tuning","Suchschnittstelle mit Paginierung, Sortierung, Treffer-Ausschnitten und Berücksichtigung der Leseberechtigung.",SRC-02,QA-10 SRC-04 SRC-08,"Ergebnisse enthalten Textausschnitte mit Fundstellen
|
||||
Nur berechtigte Dokumente erscheinen
|
||||
Antwortzeit unter vereinbartem Grenzwert","Referenz-Suchanfragen liefern erwartete Reihenfolge
|
||||
Berechtigungsfilter durch Negativtest belegt
|
||||
Lasttest mit gleichzeitigen Suchanfragen bestanden"
|
||||
SRC-04,Such-Oberfläche mit Hervorhebung,🔍 Suche & OCR,Frontend,Mittel,3,7,Backlog,"Suchfeld, Ergebnisliste","Suchfeld mit Vorschlägen, Ergebnisliste mit hervorgehobenen Fundstellen und Sprung in die Dokumentvorschau.",SRC-03,QA-04 SRC-09,"Fundstellen sind im Ergebnis hervorgehoben
|
||||
SRC-04,Such-Oberfläche mit Hervorhebung,🔍 Suche & OCR,Frontend,Mittel,3,7,Fertig,"Suchfeld, Ergebnisliste","Suchfeld mit Vorschlägen, Ergebnisliste mit hervorgehobenen Fundstellen und Sprung in die Dokumentvorschau.",SRC-03,QA-04 SRC-09,"Fundstellen sind im Ergebnis hervorgehoben
|
||||
Kein Ergebnis liefert hilfreiche Alternativvorschläge
|
||||
Suchzustand ist per URL teilbar","Suche vollständig per Tastatur bedienbar
|
||||
Verhalten bei sehr langem Suchbegriff geprüft
|
||||
Ergebnisliste auf Mobilgerät nutzbar"
|
||||
SRC-05,OCR-Worker,🔍 Suche & OCR,Backend,Komplex,5,5,Backlog,"Tesseract, Bildvorverarbeitung","Texterkennung für Scans und Bilder inklusive Entzerrung, Rauschunterdrückung und Speicherung des Volltexts je Seite.",FDN-04 DOC-01 DOC-02,INT-06 MET-05 SRC-06 SRC-07,"Erkannter Text wird seitenweise gespeichert
|
||||
SRC-05,OCR-Worker,🔍 Suche & OCR,Backend,Komplex,5,5,Fertig,"Tesseract, Bildvorverarbeitung","Texterkennung für Scans und Bilder inklusive Entzerrung, Rauschunterdrückung und Speicherung des Volltexts je Seite.",FDN-04 DOC-01 DOC-02,INT-06 MET-05 SRC-06 SRC-07,"Erkannter Text wird seitenweise gespeichert
|
||||
Bereits durchsuchbare PDFs werden übersprungen
|
||||
Verarbeitung skaliert über mehrere Worker","Erkennungsrate an Referenz-Scanset gemessen und dokumentiert
|
||||
Schiefer Scan wird korrekt entzerrt
|
||||
Sehr großes Dokument läuft nicht in Zeitüberschreitung"
|
||||
SRC-06,PDF/A-Erzeugung mit Textebene,🔍 Suche & OCR,Backend,Mittel,3,6,Backlog,"PDF/A-Konverter, Textlayer",Archivfähiges PDF/A mit unsichtbarer Textebene aus der Texterkennung als zusätzliches Derivat erzeugen.,SRC-05,QA-04,"Erzeugtes PDF ist PDF/A-konform
|
||||
SRC-06,PDF/A-Erzeugung mit Textebene,🔍 Suche & OCR,Backend,Mittel,3,6,Fertig,"PDF/A-Konverter, Textlayer",Archivfähiges PDF/A mit unsichtbarer Textebene aus der Texterkennung als zusätzliches Derivat erzeugen.,SRC-05,QA-04,"Erzeugtes PDF ist PDF/A-konform
|
||||
Text ist im Dokument markier- und durchsuchbar
|
||||
Original bleibt unverändert erhalten","Konformitätsprüfung mit Validierungswerkzeug bestanden
|
||||
Textposition deckt sich mit dem Bild
|
||||
Dateigröße bleibt im vereinbarten Rahmen"
|
||||
SRC-07,Spracherkennung & OCR-Qualitätsbewertung,🔍 Suche & OCR,Backend,Einfach,2,6,Backlog,"Spracherkennung, Konfidenzwerte","Dokumentsprache automatisch bestimmen, passendes Sprachmodell wählen und Konfidenzwerte für eine Nachbearbeitungsliste erfassen.",SRC-05,QA-04,"Sprache wird erkannt und am Dokument gespeichert
|
||||
SRC-07,Spracherkennung & OCR-Qualitätsbewertung,🔍 Suche & OCR,Backend,Einfach,2,6,Fertig,"Spracherkennung, Konfidenzwerte","Dokumentsprache automatisch bestimmen, passendes Sprachmodell wählen und Konfidenzwerte für eine Nachbearbeitungsliste erfassen.",SRC-05,QA-04,"Sprache wird erkannt und am Dokument gespeichert
|
||||
Konfidenzwert je Seite verfügbar
|
||||
Dokumente unter Schwellwert erscheinen in einer Prüfliste","Spracherkennung an gemischtsprachigem Set geprüft
|
||||
Schlechter Scan landet zuverlässig in der Prüfliste
|
||||
Schwellwert ist ohne Neuveröffentlichung konfigurierbar"
|
||||
SRC-08,Facetten- & Filter-API,🔍 Suche & OCR,Backend,Mittel,3,7,Backlog,"Facettierung, Filterausdrücke","Kombinierbare Filter nach Typ, Tag, Datum, Ersteller und benutzerdefinierten Feldern samt Trefferzahlen je Facette.",SRC-03 MET-02,SRC-09 SRC-10,"Mehrere Filter sind gleichzeitig kombinierbar
|
||||
SRC-08,Facetten- & Filter-API,🔍 Suche & OCR,Backend,Mittel,3,7,Fertig,"Facettierung, Filterausdrücke","Kombinierbare Filter nach Typ, Tag, Datum, Ersteller und benutzerdefinierten Feldern samt Trefferzahlen je Facette.",SRC-03 MET-02,SRC-09 SRC-10,"Mehrere Filter sind gleichzeitig kombinierbar
|
||||
Facetten liefern korrekte Trefferzahlen
|
||||
Datums- und Wertebereiche werden unterstützt","Trefferzahlen gegen Datenbankabfrage abgeglichen
|
||||
Filter auf leerem Ergebnis verhält sich stabil
|
||||
Antwortzeit mit fünf aktiven Filtern gemessen"
|
||||
SRC-09,Filter-Panel in der Suche,🔍 Suche & OCR,Frontend,Mittel,3,8,Backlog,"Facetten-UI, Filter-Chips",Seitliches Filterpanel mit aktiven Filtern als entfernbare Chips und Zurücksetzen-Funktion.,SRC-08 SRC-04,QA-04,"Aktive Filter sind jederzeit sichtbar und einzeln entfernbar
|
||||
SRC-09,Filter-Panel in der Suche,🔍 Suche & OCR,Frontend,Mittel,3,8,Fertig,"Facetten-UI, Filter-Chips",Seitliches Filterpanel mit aktiven Filtern als entfernbare Chips und Zurücksetzen-Funktion.,SRC-08 SRC-04,QA-04,"Aktive Filter sind jederzeit sichtbar und einzeln entfernbar
|
||||
Trefferzahl aktualisiert sich unmittelbar
|
||||
Filterzustand steht in der URL","Geteilte URL stellt identischen Filterzustand her
|
||||
Panel auf schmalem Bildschirm bedienbar
|
||||
Zurücksetzen entfernt wirklich alle Filter"
|
||||
SRC-10,Gespeicherte Suchanfragen,🔍 Suche & OCR,Fullstack,Einfach,2,8,Backlog,Persistierte Abfragen,"Suchen benennen, speichern, erneut ausführen und optional mit dem Team teilen.",SRC-08,QA-04,"Suche lässt sich benennen und wiederherstellen
|
||||
SRC-10,Gespeicherte Suchanfragen,🔍 Suche & OCR,Fullstack,Einfach,2,8,Fertig,Persistierte Abfragen,"Suchen benennen, speichern, erneut ausführen und optional mit dem Team teilen.",SRC-08,QA-04,"Suche lässt sich benennen und wiederherstellen
|
||||
Geteilte Suche ist für Berechtigte sichtbar
|
||||
Ergebnis wird beim Aufruf frisch ermittelt","Gespeicherte Suche liefert nach Datenänderung aktuelle Treffer
|
||||
Geteilte Suche zeigt jedem nur erlaubte Dokumente
|
||||
Löschen einer Suche beeinträchtigt andere Nutzer nicht"
|
||||
MET-01,Tag-Modell & Tag-API,🏷️ Metadaten,Backend,Einfach,2,3,Backlog,"Tag-Entität, Zuordnungstabelle","Tags mit Farbe und optionaler Hierarchie, Zuordnung zu Dokumenten sowie Zusammenführen und Umbenennen.",FDN-02,DOC-15 MET-03 MET-05,"Tags sind anlegbar, umbenennbar und zusammenführbar
|
||||
MET-01,Tag-Modell & Tag-API,🏷️ Metadaten,Backend,Einfach,2,3,Fertig,"Tag-Entität, Zuordnungstabelle","Tags mit Farbe und optionaler Hierarchie, Zuordnung zu Dokumenten sowie Zusammenführen und Umbenennen.",FDN-02,DOC-15 MET-03 MET-05,"Tags sind anlegbar, umbenennbar und zusammenführbar
|
||||
Mehrfachzuordnung je Dokument möglich
|
||||
Löschen eines Tags entfernt nur die Zuordnung","Zusammenführen erhält alle Zuordnungen
|
||||
Doppelte Tag-Namen werden verhindert
|
||||
Massenzuweisung an 500 Dokumente geprüft"
|
||||
MET-02,Benutzerdefinierte Metadatenfelder,🏷️ Metadaten,Backend,Komplex,4,3,Backlog,"Feldschema, Validierung","Frei definierbare Felder mit Datentyp, Pflichtkennzeichen, Standardwert und Validierungsregeln.",FDN-02,MET-03 MET-04 SRC-08,"Feldtypen Text, Zahl, Datum, Auswahl und Ja/Nein verfügbar
|
||||
MET-02,Benutzerdefinierte Metadatenfelder,🏷️ Metadaten,Backend,Komplex,4,3,Fertig,"Feldschema, Validierung","Frei definierbare Felder mit Datentyp, Pflichtkennzeichen, Standardwert und Validierungsregeln.",FDN-02,MET-03 MET-04 SRC-08,"Feldtypen Text, Zahl, Datum, Auswahl und Ja/Nein verfügbar
|
||||
Validierung greift beim Speichern
|
||||
Felddefinition ist versioniert änderbar","Ungültiger Wert wird mit klarer Meldung abgewiesen
|
||||
Typänderung eines Feldes mit Bestandsdaten getestet
|
||||
Pflichtfeld blockiert unvollständiges Speichern"
|
||||
MET-03,Metadaten- & Tag-Oberfläche,🏷️ Metadaten,Frontend,Mittel,3,4,Backlog,Dynamische Formulare,"Bearbeitungsbereich am Dokument mit dynamisch erzeugtem Formular, Tag-Eingabe mit Autovervollständigung und Massenbearbeitung.",MET-01 MET-02,QA-05,"Formular passt sich der Felddefinition automatisch an
|
||||
MET-03,Metadaten- & Tag-Oberfläche,🏷️ Metadaten,Frontend,Mittel,3,4,Fertig,Dynamische Formulare,"Bearbeitungsbereich am Dokument mit dynamisch erzeugtem Formular, Tag-Eingabe mit Autovervollständigung und Massenbearbeitung.",MET-01 MET-02,QA-05,"Formular passt sich der Felddefinition automatisch an
|
||||
Tag-Eingabe schlägt bestehende Tags vor
|
||||
Massenbearbeitung für ausgewählte Dokumente möglich","Ungespeicherte Änderungen lösen Warnung aus
|
||||
Formular per Tastatur vollständig ausfüllbar
|
||||
Massenbearbeitung an 200 Dokumenten geprüft"
|
||||
MET-04,Dokumententypen & Vorlagen,🏷️ Metadaten,Backend,Mittel,3,4,Backlog,"Typdefinition, Feldbindung","Dokumententypen wie Rechnung oder Vertrag mit fest zugeordneten Pflichtfeldern, Standard-Tags und Aufbewahrungsvorgabe.",MET-02,QA-05,"Typ bündelt Felder, Tags und Aufbewahrungsvorgabe
|
||||
MET-04,Dokumententypen & Vorlagen,🏷️ Metadaten,Backend,Mittel,3,4,Fertig,"Typdefinition, Feldbindung","Dokumententypen wie Rechnung oder Vertrag mit fest zugeordneten Pflichtfeldern, Standard-Tags und Aufbewahrungsvorgabe.",MET-02,QA-05,"Typ bündelt Felder, Tags und Aufbewahrungsvorgabe
|
||||
Typwechsel überführt vorhandene Werte
|
||||
Typ ist an Ordner vorbelegbar","Typwechsel mit Datenverlustprüfung getestet
|
||||
Pflichtfelder des Typs werden erzwungen
|
||||
Vorbelegung im Ordner greift beim Upload"
|
||||
MET-05,Regelbasierte Auto-Verschlagwortung,🏷️ Metadaten,Backend,Mittel,3,6,Backlog,"Regelwerk, Mustererkennung","Regeln auf Basis von Textmustern, Absender oder Dateiname vergeben automatisch Tags, Typ und Ablageort.",MET-01 SRC-05,INT-04 QA-05,"Regeln sind ohne Eingriff in den Code pflegbar
|
||||
MET-05,Regelbasierte Auto-Verschlagwortung,🏷️ Metadaten,Backend,Mittel,3,6,Fertig,"Regelwerk, Mustererkennung","Regeln auf Basis von Textmustern, Absender oder Dateiname vergeben automatisch Tags, Typ und Ablageort.",MET-01 SRC-05,INT-04 QA-05,"Regeln sind ohne Eingriff in den Code pflegbar
|
||||
Reihenfolge und Priorität der Regeln sind steuerbar
|
||||
Automatische Zuweisung ist als solche erkennbar","Regelwerk an Testkorpus mit erwarteter Trefferquote geprüft
|
||||
Widersprüchliche Regeln führen zu definiertem Ergebnis
|
||||
Regeländerung wirkt ohne Neustart"
|
||||
VER-01,Versionsmodell & Check-in/Check-out,🔄 Versionierung & Audit,Backend,Komplex,4,4,Backlog,"Revisionen, Sperren","Jede Änderung erzeugt eine neue Revision. Ausleihen sperrt das Dokument für andere, Einchecken gibt es mit Kommentar frei.",DOC-01 FDN-02,VER-02 VER-03 VER-07,"Alle Revisionen bleiben abrufbar
|
||||
VER-01,Versionsmodell & Check-in/Check-out,🔄 Versionierung & Audit,Backend,Komplex,4,4,Fertig,"Revisionen, Sperren","Jede Änderung erzeugt eine neue Revision. Ausleihen sperrt das Dokument für andere, Einchecken gibt es mit Kommentar frei.",DOC-01 FDN-02,VER-02 VER-03 VER-07,"Alle Revisionen bleiben abrufbar
|
||||
Sperre verhindert konkurrierende Änderungen
|
||||
Sperre ist durch Administratoren aufhebbar","Zwei gleichzeitige Ausleihversuche – nur einer gewinnt
|
||||
Verwaiste Sperre wird nach Frist automatisch gelöst
|
||||
Alte Revision ist unverändert abrufbar"
|
||||
VER-02,Versionsansicht & Wiederherstellung,🔄 Versionierung & Audit,Frontend,Mittel,3,5,Backlog,"Versionsliste, Wiederherstellen","Liste aller Revisionen mit Autor, Zeitpunkt und Kommentar sowie Wiederherstellung einer früheren Fassung als neue Revision.",VER-01,QA-08,"Revisionen chronologisch mit Metadaten sichtbar
|
||||
VER-02,Versionsansicht & Wiederherstellung,🔄 Versionierung & Audit,Frontend,Mittel,3,5,Fertig,"Versionsliste, Wiederherstellen","Liste aller Revisionen mit Autor, Zeitpunkt und Kommentar sowie Wiederherstellung einer früheren Fassung als neue Revision.",VER-01,QA-08,"Revisionen chronologisch mit Metadaten sichtbar
|
||||
Wiederherstellung erzeugt eine neue Revision statt Überschreiben
|
||||
Jede Revision ist einzeln herunterladbar","Wiederherstellung verändert die Historie nicht
|
||||
Ansicht bei 100 Revisionen bleibt übersichtlich
|
||||
Berechtigung wird je Revision geprüft"
|
||||
VER-03,Änderungshistorie & Diff-Berechnung,🔄 Versionierung & Audit,Backend,Mittel,3,5,Backlog,"Textvergleich, Metadaten-Diff",Unterschiede zwischen zwei Revisionen ermitteln – sowohl im Volltext als auch in Metadaten und Tags.,VER-01,VER-04,"Textunterschiede werden zeilen- oder absatzweise geliefert
|
||||
VER-03,Änderungshistorie & Diff-Berechnung,🔄 Versionierung & Audit,Backend,Mittel,3,5,Fertig,"Textvergleich, Metadaten-Diff",Unterschiede zwischen zwei Revisionen ermitteln – sowohl im Volltext als auch in Metadaten und Tags.,VER-01,VER-04,"Textunterschiede werden zeilen- oder absatzweise geliefert
|
||||
Metadatenänderungen werden als Vorher-Nachher ausgegeben
|
||||
Berechnung ist auch für große Dokumente möglich","Diff an Referenzpaaren gegen erwartetes Ergebnis geprüft
|
||||
Vergleich zweier identischer Revisionen liefert leeres Ergebnis
|
||||
Laufzeit bei 200-seitigem Dokument gemessen"
|
||||
VER-04,Diff-Ansicht,🔄 Versionierung & Audit,Frontend,Mittel,3,6,Backlog,"Gegenüberstellung, Farbmarkierung","Zwei Revisionen nebeneinander mit farblicher Markierung von Hinzufügungen, Löschungen und Metadatenänderungen.",VER-03 DOC-05,QA-08,"Revisionen sind frei zum Vergleich wählbar
|
||||
VER-04,Diff-Ansicht,🔄 Versionierung & Audit,Frontend,Mittel,3,6,Fertig,"Gegenüberstellung, Farbmarkierung","Zwei Revisionen nebeneinander mit farblicher Markierung von Hinzufügungen, Löschungen und Metadatenänderungen.",VER-03 DOC-05,QA-08,"Revisionen sind frei zum Vergleich wählbar
|
||||
Änderungen sind farblich und mit Symbol gekennzeichnet
|
||||
Sprung zur nächsten Änderung möglich","Farbmarkierung ist auch ohne Farbwahrnehmung unterscheidbar
|
||||
Ansicht funktioniert auf schmalem Bildschirm
|
||||
Sehr viele Änderungen bremsen die Ansicht nicht aus"
|
||||
VER-05,Revisionssicherer Audit-Trail,🔄 Versionierung & Audit,Backend,Komplex,4,3,Backlog,"Append-only-Protokoll, Hash-Kette",Unveränderliches Protokoll aller sicherheits- und geschäftsrelevanten Ereignisse mit Verkettung zum Nachweis der Unversehrtheit.,FDN-02,VER-06 VER-08,"Einträge sind ausschließlich anfügbar
|
||||
VER-05,Revisionssicherer Audit-Trail,🔄 Versionierung & Audit,Backend,Komplex,4,3,Fertig,"Append-only-Protokoll, Hash-Kette",Unveränderliches Protokoll aller sicherheits- und geschäftsrelevanten Ereignisse mit Verkettung zum Nachweis der Unversehrtheit.,FDN-02,VER-06 VER-08,"Einträge sind ausschließlich anfügbar
|
||||
Jeder Eintrag enthält Akteur, Zeit, Objekt und Aktion
|
||||
Verkettung erlaubt Integritätsprüfung","Manipulationsversuch wird durch Integritätsprüfung erkannt
|
||||
Vollständigkeit gegen Referenzoperationen abgeglichen
|
||||
Protokollschreiben verlangsamt Kernoperationen nicht spürbar"
|
||||
VER-06,Audit-Log-Ansicht & Export,🔄 Versionierung & Audit,Frontend,Einfach,2,4,Backlog,"Filterbare Tabelle, CSV-Export","Durchsuchbare Protokollansicht mit Filtern nach Zeitraum, Akteur, Objekt und Aktion sowie Export für Prüfer.",VER-05,QA-08,"Filter nach Zeitraum, Akteur und Aktion vorhanden
|
||||
VER-06,Audit-Log-Ansicht & Export,🔄 Versionierung & Audit,Frontend,Einfach,2,4,Fertig,"Filterbare Tabelle, CSV-Export","Durchsuchbare Protokollansicht mit Filtern nach Zeitraum, Akteur, Objekt und Aktion sowie Export für Prüfer.",VER-05,QA-08,"Filter nach Zeitraum, Akteur und Aktion vorhanden
|
||||
Export enthält exakt die gefilterten Einträge
|
||||
Zugriff nur für berechtigte Rollen","Export mit 100.000 Einträgen läuft ohne Abbruch
|
||||
Nicht berechtigter Nutzer erhält keinen Zugriff
|
||||
Exportdatei ist in Tabellenkalkulation korrekt lesbar"
|
||||
VER-07,Digitale Signatur,🔄 Versionierung & Audit,Backend,Komplex,5,5,Backlog,"PAdES, Zertifikate, Zeitstempel","Dokumente digital signieren und vorhandene Signaturen prüfen, inklusive qualifiziertem Zeitstempel.",VER-01 DOC-06,QA-08,"Signatur wird eingebettet und ist extern prüfbar
|
||||
VER-07,Digitale Signatur,🔄 Versionierung & Audit,Backend,Komplex,5,5,Fertig,"PAdES, Zertifikate, Zeitstempel","Dokumente digital signieren und vorhandene Signaturen prüfen, inklusive qualifiziertem Zeitstempel.",VER-01 DOC-06,QA-08,"Signatur wird eingebettet und ist extern prüfbar
|
||||
Prüfergebnis wird am Dokument angezeigt
|
||||
Zeitstempel stammt von einer vertrauenswürdigen Quelle","Signatur mit externem Prüfwerkzeug validiert
|
||||
Nachträgliche Änderung invalidiert die Signatur nachweislich
|
||||
Abgelaufenes Zertifikat wird als solches erkannt"
|
||||
INT-01,REST-API v1 & Schnittstellenbeschreibung,🔌 Integration & API,Backend,Komplex,4,4,Backlog,"REST, OpenAPI","Dokument-spezifische API-Endpunkte (Dokument abrufen/anlegen/durchsuchen usw.) auf dem zentralen Core-REST-Grundgerüst definieren und dokumentieren – keine eigene Router-/Versionierungs-Infrastruktur, die liefert Core API-01.",DOC-01,INT-09 QA-10,"Alle dokument-eigenen Endpunkte sind in der Beschreibung dokumentiert
|
||||
INT-01,REST-API v1 & Schnittstellenbeschreibung,🔌 Integration & API,Backend,Komplex,4,4,Fertig,"REST, OpenAPI","Dokument-spezifische API-Endpunkte (Dokument abrufen/anlegen/durchsuchen usw.) auf dem zentralen Core-REST-Grundgerüst definieren und dokumentieren – keine eigene Router-/Versionierungs-Infrastruktur, die liefert Core API-01.",DOC-01,INT-09 QA-10,"Alle dokument-eigenen Endpunkte sind in der Beschreibung dokumentiert
|
||||
Einheitliches Fehlerformat über alle Endpunkte (geerbt vom Core-REST-Grundgerüst)
|
||||
Endpunkte laufen auf der zentralen, versionierten Core-API auf, keine eigene Versionierung","Vertragstests gegen die Beschreibung laufen in der Pipeline
|
||||
Berechtigungen greifen identisch wie in der Oberfläche
|
||||
Beispielaufrufe aus der Dokumentation funktionieren"
|
||||
INT-03,E-Mail-Abruf über IMAP,🔌 Integration & API,Backend,Komplex,4,4,Backlog,"IMAP-Client, Job-Zeitplan","Überwachte Postfächer regelmäßig abrufen, Nachrichten und Anhänge importieren und verarbeitete Nachrichten markieren.",FDN-04 DOC-01,INT-04,"Mehrere Postfächer parallel überwachbar
|
||||
INT-03,E-Mail-Abruf über IMAP,🔌 Integration & API,Backend,Komplex,4,4,Fertig,"IMAP-Client, Job-Zeitplan","Überwachte Postfächer regelmäßig abrufen, Nachrichten und Anhänge importieren und verarbeitete Nachrichten markieren.",FDN-04 DOC-01,INT-04,"Mehrere Postfächer parallel überwachbar
|
||||
Nachricht und Anhänge werden als Dokumente abgelegt
|
||||
Verarbeitete Nachrichten werden nicht erneut importiert","Verbindungsabbruch führt zu Wiederholung ohne Duplikate
|
||||
Nachricht mit 20 Anhängen korrekt importiert
|
||||
Zugangsdaten liegen ausschließlich verschlüsselt vor"
|
||||
INT-04,E-Mail-Regeln & Anhangverarbeitung,🔌 Integration & API,Backend,Mittel,3,7,Backlog,"Regelwerk, Anhangfilter","Regeln nach Absender, Betreff oder Anhangtyp steuern Ablageort, Typ und Verschlagwortung importierter Nachrichten.",INT-03 MET-05,QA-09,"Regeln greifen auf Absender, Betreff und Anhangtyp zu
|
||||
INT-04,E-Mail-Regeln & Anhangverarbeitung,🔌 Integration & API,Backend,Mittel,3,7,Fertig,"Regelwerk, Anhangfilter","Regeln nach Absender, Betreff oder Anhangtyp steuern Ablageort, Typ und Verschlagwortung importierter Nachrichten.",INT-03 MET-05,QA-09,"Regeln greifen auf Absender, Betreff und Anhangtyp zu
|
||||
Signaturbilder und Werbeanhänge sind ausfilterbar
|
||||
Nachricht bleibt als Kontext am Dokument erhalten","Regelwerk an Testpostfach mit erwarteter Zuordnung geprüft
|
||||
Nachricht ohne passende Regel landet im Klärungskorb
|
||||
Filter verwirft keine relevanten Anhänge"
|
||||
INT-06,Scanner-Anbindung über Hot-Folder,🔌 Integration & API,Backend,Komplex,4,6,Backlog,"Überwachter Ordner, Trennseiten","Überwachtes Verzeichnis für Netzwerkscanner mit Stapeltrennung, automatischer Texterkennung und Ablage.",DOC-01 SRC-05,INT-10 QA-09 INT-14,"Neue Dateien werden automatisch übernommen
|
||||
INT-06,Scanner-Anbindung über Hot-Folder,🔌 Integration & API,Backend,Komplex,4,6,Fertig,"Überwachter Ordner, Trennseiten","Überwachtes Verzeichnis für Netzwerkscanner mit Stapeltrennung, automatischer Texterkennung und Ablage.",DOC-01 SRC-05,INT-10 QA-09 INT-14,"Neue Dateien werden automatisch übernommen
|
||||
Stapel werden anhand von Trennseiten aufgeteilt
|
||||
Fehlerhafte Dateien landen in einem Fehlerordner","Datei wird erst nach vollständigem Schreiben verarbeitet
|
||||
Stapeltrennung an Referenzstapel geprüft
|
||||
Doppelte Einlieferung erzeugt kein Duplikat"
|
||||
UX-01,Responsive Layout & mobile Navigation,📱 UX & Zugänglichkeit,Frontend,Mittel,3,1,Backlog,"Breakpoints, mobile Muster","Alle Kernansichten für kleine Bildschirme optimieren, mit ausklappbarer Navigation und berührungsfreundlichen Zielen.",,UX-05,"Kernabläufe sind auf dem Telefon vollständig durchführbar
|
||||
UX-01,Responsive Layout & mobile Navigation,📱 UX & Zugänglichkeit,Frontend,Mittel,3,1,Fertig,"Breakpoints, mobile Muster","Alle Kernansichten für kleine Bildschirme optimieren, mit ausklappbarer Navigation und berührungsfreundlichen Zielen.",,UX-05,"Kernabläufe sind auf dem Telefon vollständig durchführbar
|
||||
Keine horizontale Scrollleiste bei 360 Pixel Breite
|
||||
Bedienelemente sind ausreichend groß","Test auf drei realen Geräteklassen
|
||||
Upload und Suche auf Mobilgerät durchgeführt
|
||||
Querformat geprüft"
|
||||
UX-02,Dunkles Erscheinungsbild & Theming,📱 UX & Zugänglichkeit,Frontend,Einfach,2,1,Backlog,"Theme-Tokens, Systempräferenz",Umschaltbares helles und dunkles Erscheinungsbild mit Speicherung der Wahl und Berücksichtigung der Systemeinstellung.,,UX-05,"Umschaltung wirkt ohne Neuladen
|
||||
UX-02,Dunkles Erscheinungsbild & Theming,📱 UX & Zugänglichkeit,Frontend,Einfach,2,1,Fertig,"Theme-Tokens, Systempräferenz",Umschaltbares helles und dunkles Erscheinungsbild mit Speicherung der Wahl und Berücksichtigung der Systemeinstellung.,,UX-05,"Umschaltung wirkt ohne Neuladen
|
||||
Wahl bleibt über Sitzungen erhalten
|
||||
Systemeinstellung wird als Voreinstellung übernommen","Kontrastprüfung in beiden Varianten bestanden
|
||||
Kein Aufblitzen des falschen Erscheinungsbilds beim Laden
|
||||
Diagramme und Vorschauen bleiben lesbar"
|
||||
UX-03,Mehrsprachigkeits-Infrastruktur,📱 UX & Zugänglichkeit,Frontend,Mittel,3,1,Backlog,"i18n-Bibliothek, Sprachdateien","Alle Texte auslagern, Sprachumschaltung sowie lokale Formate für Datum, Zahl und Währung bereitstellen.",,UX-04,"Keine fest verdrahteten Texte mehr in Komponenten
|
||||
UX-03,Mehrsprachigkeits-Infrastruktur,📱 UX & Zugänglichkeit,Frontend,Mittel,3,1,Fertig,"i18n-Bibliothek, Sprachdateien","Alle Texte auslagern, Sprachumschaltung sowie lokale Formate für Datum, Zahl und Währung bereitstellen.",,UX-04,"Keine fest verdrahteten Texte mehr in Komponenten
|
||||
Sprachwechsel wirkt ohne Neuladen
|
||||
Datums- und Zahlenformate folgen der Sprache","Automatische Prüfung findet keine unübersetzten Texte
|
||||
Fehlender Schlüssel führt zu sichtbarem Hinweis statt leerem Feld
|
||||
Serverseitig gerenderte Seite zeigt die richtige Sprache"
|
||||
UX-04,Übersetzungen Deutsch und Englisch,📱 UX & Zugänglichkeit,Frontend,Einfach,2,2,Backlog,"Sprachdateien, Terminologieliste",Vollständige Übersetzung der Oberfläche in beide Sprachen inklusive abgestimmter Fachbegriffe.,UX-03,QA-11,"Beide Sprachdateien sind vollständig
|
||||
UX-04,Übersetzungen Deutsch und Englisch,📱 UX & Zugänglichkeit,Frontend,Einfach,2,2,Fertig,"Sprachdateien, Terminologieliste",Vollständige Übersetzung der Oberfläche in beide Sprachen inklusive abgestimmter Fachbegriffe.,UX-03,QA-11,"Beide Sprachdateien sind vollständig
|
||||
Fachbegriffe folgen einer abgestimmten Liste
|
||||
Fehlermeldungen sind ebenfalls übersetzt","Abdeckungsprüfung beider Sprachdateien bei 100 Prozent
|
||||
Sichtprüfung auf abgeschnittene Texte in beiden Sprachen
|
||||
Fachliche Gegenlesung dokumentiert"
|
||||
UX-05,Barrierefreiheit nach WCAG 2.1 AA,📱 UX & Zugänglichkeit,Frontend,Komplex,4,2,Backlog,"ARIA, Fokussteuerung","Semantik, Fokusführung, Tastaturbedienung, Beschriftungen und Kontraste über alle Ansichten hinweg herstellen.",UX-01 UX-02,QA-11,"Alle Abläufe ohne Maus bedienbar
|
||||
UX-05,Barrierefreiheit nach WCAG 2.1 AA,📱 UX & Zugänglichkeit,Frontend,Komplex,4,2,Fertig,"ARIA, Fokussteuerung","Semantik, Fokusführung, Tastaturbedienung, Beschriftungen und Kontraste über alle Ansichten hinweg herstellen.",UX-01 UX-02,QA-11,"Alle Abläufe ohne Maus bedienbar
|
||||
Sichtbare Fokusmarkierung überall vorhanden
|
||||
Formularfelder besitzen zugeordnete Beschriftungen","Automatisierte Prüfung meldet keine kritischen Verstöße
|
||||
Vollständiger Durchlauf mit Bildschirmleser dokumentiert
|
||||
Fokusfalle in Dialogen geprüft"
|
||||
QA-01,Teststrategie & Testdatenbestand,✅ Prüfungen & Qualitätssicherung,QA,Einfach,2,3,Backlog,"Teststrategie, anonymisierte Testdaten","Festlegen, was auf welcher Ebene geprüft wird, und einen realistischen, anonymisierten Testdatenbestand mit Referenzdokumenten aufbauen.",FDN-07,QA-03 QA-04 QA-05 QA-07 QA-10,"Testpyramide und Abdeckungsziele sind schriftlich festgelegt
|
||||
QA-01,Teststrategie & Testdatenbestand,✅ Prüfungen & Qualitätssicherung,QA,Einfach,2,3,Fertig,"Teststrategie, anonymisierte Testdaten","Festlegen, was auf welcher Ebene geprüft wird, und einen realistischen, anonymisierten Testdatenbestand mit Referenzdokumenten aufbauen.",FDN-07,QA-03 QA-04 QA-05 QA-07 QA-10,"Testpyramide und Abdeckungsziele sind schriftlich festgelegt
|
||||
Referenzkorpus mit Scans, PDFs und Office-Dateien liegt vor
|
||||
Testdaten enthalten keine echten Personendaten
|
||||
Pflichttests für sicherheitsrelevanten Code (Tenant-Scoping, Zugriffsprüfung, Auth-nahe Logik) sind als verbindliches Merge-Gate verankert – kein Merge auf solchen Code ohne Test, analog Core QA-01","Testdatenbestand ist per Befehl reproduzierbar
|
||||
Referenzkorpus deckt alle unterstützten Formate ab
|
||||
Strategie im Team abgenommen"
|
||||
QA-02,Prüfgate Fundament,✅ Prüfungen & Qualitätssicherung,QA,Einfach,2,4,Backlog,"Integrationstests, Betriebsprüfung","Abnahme der Grundlage: Datenmodell, Storage, Queue, Auth, Pipeline und Observability greifen zuverlässig ineinander.",FDN-02 FDN-03 FDN-04 FDN-07 FDN-08 FDN-09,QA-12,"Alle Fundament-Tickets erfüllen ihre Prüfungen
|
||||
QA-02,Prüfgate Fundament,✅ Prüfungen & Qualitätssicherung,QA,Einfach,2,4,Fertig,"Integrationstests, Betriebsprüfung","Abnahme der Grundlage: Datenmodell, Storage, Queue, Auth, Pipeline und Observability greifen zuverlässig ineinander.",FDN-02 FDN-03 FDN-04 FDN-07 FDN-08 FDN-09,QA-12,"Alle Fundament-Tickets erfüllen ihre Prüfungen
|
||||
Ein Durchstich vom Login bis zum abgelegten Objekt funktioniert
|
||||
Keine offenen kritischen Befunde
|
||||
Verschlüsselung at rest (FDN-09) ist wirksam und die Schlüsselverwaltung geprüft","Neuaufsetzen der Umgebung von null erfolgreich
|
||||
Ausfall eines Dienstes führt zu sauberem Fehlerbild
|
||||
Prüfbericht abgelegt und freigegeben"
|
||||
QA-03,Prüfgate Dokumentenkern,✅ Prüfungen & Qualitätssicherung,QA,Mittel,3,6,Backlog,"E2E-Tests, Datenintegrität","Vollständige Prüfung des Lebenszyklus: hochladen, ansehen, ablegen, herunterladen, löschen, wiederherstellen.",DOC-03 DOC-05 DOC-06 DOC-08 DOC-10 DOC-12 QA-01 DOC-13 DOC-14 DOC-15,QA-12,"Kompletter Lebenszyklus als automatisierter Test vorhanden
|
||||
QA-03,Prüfgate Dokumentenkern,✅ Prüfungen & Qualitätssicherung,QA,Mittel,3,6,Fertig,"E2E-Tests, Datenintegrität","Vollständige Prüfung des Lebenszyklus: hochladen, ansehen, ablegen, herunterladen, löschen, wiederherstellen.",DOC-03 DOC-05 DOC-06 DOC-08 DOC-10 DOC-12 QA-01 DOC-13 DOC-14 DOC-15,QA-12,"Kompletter Lebenszyklus als automatisierter Test vorhanden
|
||||
Keine Datenveränderung zwischen Upload und Download
|
||||
Alle Ticket-Prüfungen des Epics bestanden","Prüfsummenvergleich über den gesamten Lebenszyklus
|
||||
Abbruchszenarien in jedem Schritt getestet
|
||||
Referenzkorpus vollständig durchlaufen"
|
||||
QA-04,Prüfgate Suche & Texterkennung,✅ Prüfungen & Qualitätssicherung,QA,Mittel,3,9,Backlog,Relevanz- und Erkennungsmessung,"Messen und dokumentieren von Erkennungsgüte, Trefferqualität und Konsistenz zwischen Datenbank und Suchindex.",SRC-04 SRC-06 SRC-07 SRC-09 SRC-10 QA-01,QA-12 QA-06,"Erkennungsrate am Referenzkorpus erreicht den Zielwert
|
||||
QA-04,Prüfgate Suche & Texterkennung,✅ Prüfungen & Qualitätssicherung,QA,Mittel,3,9,Fertig,Relevanz- und Erkennungsmessung,"Messen und dokumentieren von Erkennungsgüte, Trefferqualität und Konsistenz zwischen Datenbank und Suchindex.",SRC-04 SRC-06 SRC-07 SRC-09 SRC-10 QA-01,QA-12 QA-06,"Erkennungsrate am Referenzkorpus erreicht den Zielwert
|
||||
Relevanz an definierten Suchanfragen erfüllt die Erwartung
|
||||
Index und Datenbank sind nachweislich konsistent","Messprotokoll mit Zielwerten und Ergebnissen abgelegt
|
||||
Voll-Reindexierung ohne Trefferverlust geprüft
|
||||
Berechtigungsfilter in der Suche negativ getestet"
|
||||
QA-05,Prüfgate Metadaten & Klassifizierung,✅ Prüfungen & Qualitätssicherung,QA,Einfach,2,7,Backlog,Datenqualitätstests,"Prüfen von Feldvalidierung, Typwechseln, Massenbearbeitung und Güte der automatischen Zuordnung.",MET-03 MET-04 QA-01 MET-05,QA-12,"Validierungsregeln greifen in allen Eingabewegen
|
||||
QA-05,Prüfgate Metadaten & Klassifizierung,✅ Prüfungen & Qualitätssicherung,QA,Einfach,2,7,Fertig,Datenqualitätstests,"Prüfen von Feldvalidierung, Typwechseln, Massenbearbeitung und Güte der automatischen Zuordnung.",MET-03 MET-04 QA-01 MET-05,QA-12,"Validierungsregeln greifen in allen Eingabewegen
|
||||
Automatische Vorschläge erreichen die Zielgenauigkeit
|
||||
Massenbearbeitung erzeugt keine inkonsistenten Daten","Genauigkeit der Klassifizierung dokumentiert
|
||||
Typwechsel mit Bestandsdaten ohne Verlust
|
||||
Validierung auch über die Schnittstelle wirksam"
|
||||
QA-06,Sicherheits- & Berechtigungsprüfung,✅ Prüfungen & Qualitätssicherung,QA,Komplex,4,10,Backlog,"Penetrationstest, Rollenmatrix",Systematische Prüfung aller Zugriffspfade gegen die Rollenmatrix sowie Test auf gängige Sicherheitslücken.,QA-04 SRC-11,QA-12,"Jede Rolle wurde gegen jeden Endpunkt geprüft
|
||||
QA-06,Sicherheits- & Berechtigungsprüfung,✅ Prüfungen & Qualitätssicherung,QA,Komplex,4,10,Fertig,"Penetrationstest, Rollenmatrix",Systematische Prüfung aller Zugriffspfade gegen die Rollenmatrix sowie Test auf gängige Sicherheitslücken.,QA-04 SRC-11,QA-12,"Jede Rolle wurde gegen jeden Endpunkt geprüft
|
||||
Keine unbefugte Rechteausweitung möglich
|
||||
Befunde sind behoben oder bewusst akzeptiert","Zugriff auf fremdes Objekt per ID schlägt fehl
|
||||
Prüfung auf Einschleusung, Sitzungsübernahme und unsichere Weiterleitung
|
||||
Sicherheitsbericht abgelegt und freigegeben"
|
||||
QA-07,Prüfgate Workflow & Benachrichtigung,✅ Prüfungen & Qualitätssicherung,QA,Mittel,3,4,Backlog,"Prozesstests, Zeitraffer","Durchspielen aller Prozesspfade inklusive Ablehnung, Vertretung, Eskalation und Fristablauf.",QA-01,QA-12,"Alle Prozesspfade sind mindestens einmal durchlaufen
|
||||
QA-07,Prüfgate Workflow & Benachrichtigung,✅ Prüfungen & Qualitätssicherung,QA,Mittel,3,4,Fertig,"Prozesstests, Zeitraffer","Durchspielen aller Prozesspfade inklusive Ablehnung, Vertretung, Eskalation und Fristablauf.",QA-01,QA-12,"Alle Prozesspfade sind mindestens einmal durchlaufen
|
||||
Fristen und Eskalationen lösen korrekt aus
|
||||
Keine Benachrichtigung geht verloren oder wird doppelt versandt","Zeitraffer-Test über simulierte Fristen
|
||||
Parallelentscheidungen erzeugen keinen Fehlzustand
|
||||
Zustellprotokoll gegen erwartete Ereignisse abgeglichen"
|
||||
QA-08,Revisionssicherheits-Prüfung,✅ Prüfungen & Qualitätssicherung,QA,Mittel,3,7,Backlog,"Integritätsprüfung, Signaturvalidierung","Nachweis, dass Versionen, Protokoll und Signaturen unveränderlich, vollständig und extern prüfbar sind.",VER-02 VER-04 VER-06 VER-07,QA-12,"Historie ist lückenlos und nicht manipulierbar
|
||||
QA-08,Revisionssicherheits-Prüfung,✅ Prüfungen & Qualitätssicherung,QA,Mittel,3,7,Fertig,"Integritätsprüfung, Signaturvalidierung","Nachweis, dass Versionen, Protokoll und Signaturen unveränderlich, vollständig und extern prüfbar sind.",VER-02 VER-04 VER-06 VER-07,QA-12,"Historie ist lückenlos und nicht manipulierbar
|
||||
Signaturen sind mit externen Werkzeugen prüfbar
|
||||
Jede relevante Aktion erscheint im Protokoll","Manipulationsversuch wird erkannt und protokolliert
|
||||
Stichprobe von Aktionen im Protokoll wiedergefunden
|
||||
Prüfbericht für die Revision erstellt"
|
||||
QA-09,Schnittstellen-Vertragstests,✅ Prüfungen & Qualitätssicherung,QA,Mittel,3,8,Backlog,"Vertragstests, Testempfänger","Automatisierte Prüfung, dass die Schnittstelle ihrer Beschreibung entspricht und Importwege zuverlässig arbeiten.",INT-04 INT-06 INT-08 INT-09 INT-10 INT-11 INT-12 INT-13,QA-12,"Vertragstests laufen in der Pipeline
|
||||
QA-09,Schnittstellen-Vertragstests,✅ Prüfungen & Qualitätssicherung,QA,Mittel,3,8,Fertig,"Vertragstests, Testempfänger","Automatisierte Prüfung, dass die Schnittstelle ihrer Beschreibung entspricht und Importwege zuverlässig arbeiten.",INT-04 INT-06 INT-08 INT-09 INT-10 INT-11 INT-12 INT-13,QA-12,"Vertragstests laufen in der Pipeline
|
||||
Import über E-Mail und Hot-Folder verliert keine Dokumente
|
||||
Webhook-Zustellung ist nachweisbar","Abweichung zwischen Beschreibung und Verhalten bricht die Pipeline
|
||||
Dauerlauf-Import über 24 Stunden ohne Verlust
|
||||
@@ -304,7 +304,7 @@ Engpässe sind identifiziert und dokumentiert
|
||||
System erholt sich nach Lastspitze selbstständig","Dauerlast über mehrere Stunden ohne Speicherwachstum
|
||||
Verhalten bei Überlast ist definiert statt zufällig
|
||||
Messprotokoll mit Zielwertvergleich abgelegt"
|
||||
QA-11,Barrierefreiheits-Audit,✅ Prüfungen & Qualitätssicherung,QA,Mittel,3,3,Backlog,"Prüfwerkzeuge, Bildschirmleser",Unabhängige Prüfung aller Ansichten gegen WCAG 2.1 AA mit Werkzeugen und manuellem Durchlauf.,UX-04 UX-05,QA-12,"Keine kritischen Verstöße offen
|
||||
QA-11,Barrierefreiheits-Audit,✅ Prüfungen & Qualitätssicherung,QA,Mittel,3,3,Fertig,"Prüfwerkzeuge, Bildschirmleser",Unabhängige Prüfung aller Ansichten gegen WCAG 2.1 AA mit Werkzeugen und manuellem Durchlauf.,UX-04 UX-05,QA-12,"Keine kritischen Verstöße offen
|
||||
Manueller Bildschirmleser-Durchlauf dokumentiert
|
||||
Restbefunde sind mit Frist eingeplant","Automatisierte Prüfung über alle Hauptseiten
|
||||
Vollständiger Ablauf ohne Maus durchgeführt
|
||||
@@ -319,53 +319,53 @@ KEK wird ausschließlich über Core API-10 bezogen, nie im Code oder in der Date
|
||||
Schlüsselrotation des KEK ist ohne Neuverschlüsselung aller Objekte möglich (nur DEK-Wrapper wird neu verpackt)","Round-Trip Encrypt/Decrypt liefert identischen Klartext
|
||||
Manipulierter Chiffretext wird bei Decrypt erkannt und abgelehnt (GCM-Auth-Tag)
|
||||
KEK-Rotation getestet, alte Objekte weiterhin lesbar"
|
||||
DOC-13,Akten-/Vorgangsanzeige im Dokumentkontext,🗂️ Dokumentenkern,Frontend,Einfach,2,6,Backlog,"Next.js/React/TS, externe REST-API","In der Dokument-Detailansicht anzeigen, ob das Dokument zu einer Akte gehört, inkl. Vermerke und offener Wiedervorlage – ruft dafür ausschließlich die externe Workflow-Board-API auf (VOR-04), speichert selbst keine Akte-Daten in DMS.",DOC-05,QA-03,"Dokument-Detailansicht zeigt Akte-Zugehörigkeit, Vermerke und offene Wiedervorlagen an, falls vorhanden
|
||||
DOC-13,Akten-/Vorgangsanzeige im Dokumentkontext,🗂️ Dokumentenkern,Frontend,Einfach,2,6,Fertig,"Next.js/React/TS, externe REST-API","In der Dokument-Detailansicht anzeigen, ob das Dokument zu einer Akte gehört, inkl. Vermerke und offener Wiedervorlage – ruft dafür ausschließlich die externe Workflow-Board-API auf (VOR-04), speichert selbst keine Akte-Daten in DMS.",DOC-05,QA-03,"Dokument-Detailansicht zeigt Akte-Zugehörigkeit, Vermerke und offene Wiedervorlagen an, falls vorhanden
|
||||
Kein eigenes Akte-Datenmodell in DMS, ausschließlich Anzeige über die externe API
|
||||
Fehlerfall (Workflow-Board nicht erreichbar) blockiert die Dokumentanzeige selbst nicht, zeigt nur den Akte-Bereich als „vorübergehend nicht verfügbar“","Dokument mit verknüpfter Akte zeigt Akte-Informationen korrekt an
|
||||
Dokument ohne Akte-Verknüpfung zeigt Bereich nicht/leer an, kein Fehler
|
||||
Simulierter Ausfall der Workflow-API blockiert die übrige Dokumentanzeige nicht"
|
||||
INT-08,Watch-Folder-Import (Consume-Ordner),🔌 Integration & API,Backend,Mittel,3,4,Backlog,"Überwachter Ordner, Dateisystem-Events/Polling","Dateisystem-Ordner, der automatisch überwacht wird — jede dort abgelegte Datei wird ohne API-Aufruf importiert. Ergänzt DOC-01 (Upload-API), ersetzt sie nicht.",DOC-01,QA-09 INT-14,"Datei im überwachten Ordner wird automatisch erkannt und importiert, ohne manuellen Trigger
|
||||
INT-08,Watch-Folder-Import (Consume-Ordner),🔌 Integration & API,Backend,Mittel,3,4,Fertig,"Überwachter Ordner, Dateisystem-Events/Polling","Dateisystem-Ordner, der automatisch überwacht wird — jede dort abgelegte Datei wird ohne API-Aufruf importiert. Ergänzt DOC-01 (Upload-API), ersetzt sie nicht.",DOC-01,QA-09 INT-14,"Datei im überwachten Ordner wird automatisch erkannt und importiert, ohne manuellen Trigger
|
||||
Importierte Datei durchläuft denselben Pipeline-Weg wie ein API-Upload (Hash/Dedup/Verschlüsselung/OCR/Index)
|
||||
Fehlerhafte/nicht lesbare Datei landet in einem Fehler-Unterordner statt den Import-Prozess zu blockieren","Testdatei im Ordner abgelegt, erscheint automatisch als Dokument
|
||||
Pipeline-Schritte (Hash, Dedup-Gate, Verschlüsselung) im Test nachweislich durchlaufen
|
||||
Absichtlich beschädigte Datei landet im Fehler-Unterordner, blockiert restlichen Ordner nicht"
|
||||
INT-09,CMIS-kompatible Schnittstelle (optional),🔌 Integration & API,Backend,Komplex,4,5,Backlog,CMIS 1.1 (AtomPub oder Browser-Binding),"CMIS-Standardschnittstelle als optionale zusätzliche API neben der eigenen REST-API — ermöglicht Drittwerkzeugen direkten Zugriff auf DMS-Inhalte, ohne NEXARCH-spezifische Integration schreiben zu müssen.",INT-01,QA-09 INT-15,"CMIS-Basisoperationen (Objekt lesen, Ordner navigieren, Dokument hochladen) funktionieren gegen einen CMIS-Standard-Client
|
||||
INT-09,CMIS-kompatible Schnittstelle (optional),🔌 Integration & API,Backend,Komplex,4,5,Fertig,CMIS 1.1 (AtomPub oder Browser-Binding),"CMIS-Standardschnittstelle als optionale zusätzliche API neben der eigenen REST-API — ermöglicht Drittwerkzeugen direkten Zugriff auf DMS-Inhalte, ohne NEXARCH-spezifische Integration schreiben zu müssen.",INT-01,QA-09 INT-15,"CMIS-Basisoperationen (Objekt lesen, Ordner navigieren, Dokument hochladen) funktionieren gegen einen CMIS-Standard-Client
|
||||
CMIS-Zugriff respektiert dieselben Rechte/Mandantengrenzen wie die eigene REST-API
|
||||
Optional aktivierbar, kein Zwangsbestandteil","Test mit einem CMIS-Referenzclient gegen die Schnittstelle
|
||||
Berechtigungsprüfung im Test über CMIS-Pfad identisch zur REST-API
|
||||
Deaktivierung blockiert CMIS-Zugriff vollständig, REST-API bleibt unberührt"
|
||||
INT-10,Scanner-Stapelverarbeitung mit Trennseiten-/Barcode-Erkennung,🔌 Integration & API,Backend,Mittel,3,7,Backlog,"Leerseiten-Erkennung, Barcode-Decoding (z. B. ZBar/ZXing)","Erkennung von Trennseiten (leere Seite oder Barcode-Seite) in einem Multi-Dokument-Scan-Stapel, der über INT-06 (Hot-Folder) eingeht — trennt automatisch in einzelne Dokumente statt eine große Datei anzulegen.",INT-06,QA-09,"Leere Trennseite wird erkannt und trennt den Stapel in einzelne Dokumente
|
||||
INT-10,Scanner-Stapelverarbeitung mit Trennseiten-/Barcode-Erkennung,🔌 Integration & API,Backend,Mittel,3,7,Fertig,"Leerseiten-Erkennung, Barcode-Decoding (z. B. ZBar/ZXing)","Erkennung von Trennseiten (leere Seite oder Barcode-Seite) in einem Multi-Dokument-Scan-Stapel, der über INT-06 (Hot-Folder) eingeht — trennt automatisch in einzelne Dokumente statt eine große Datei anzulegen.",INT-06,QA-09,"Leere Trennseite wird erkannt und trennt den Stapel in einzelne Dokumente
|
||||
Barcode-Trennseite wird erkannt, Barcode-Wert kann optional als Metadatenfeld übernommen werden
|
||||
Stapel ohne Trennseiten wird als ein einzelnes Dokument behandelt, kein Fehlverhalten","Test-Stapel mit Leerseiten-Trennung ergibt korrekte Anzahl Einzeldokumente
|
||||
Test-Stapel mit Barcode-Trennseiten ordnet Barcode-Werte korrekt zu
|
||||
Stapel ohne Trennseiten bleibt ein Dokument"
|
||||
DOC-14,Dokument-Zusammenführen & -Aufteilen,🗂️ Dokumentenkern,Backend,Mittel,3,4,Backlog,"PDF-Seitenmanipulation, Versionshistorie, Transaktionale Dokument-Operationen","Nachträgliches Zusammenführen mehrerer Dokumente zu einem (z.B. fälschlich getrennt gescannt) und Aufteilen eines mehrseitigen Dokuments in mehrere eigenständige Dokumente (z.B. Stapel-Scan ohne Trennseiten-Erkennung, siehe INT-10) – beides als nachträgliche Korrektur nach dem Import, nicht nur zum Importzeitpunkt.",DOC-01 DOC-09,QA-03,"Mehrere Dokumente lassen sich zu einem zusammenführen, Ursprungsdokumente bleiben in der Versionshistorie nachvollziehbar
|
||||
DOC-14,Dokument-Zusammenführen & -Aufteilen,🗂️ Dokumentenkern,Backend,Mittel,3,4,Fertig,"PDF-Seitenmanipulation, Versionshistorie, Transaktionale Dokument-Operationen","Nachträgliches Zusammenführen mehrerer Dokumente zu einem (z.B. fälschlich getrennt gescannt) und Aufteilen eines mehrseitigen Dokuments in mehrere eigenständige Dokumente (z.B. Stapel-Scan ohne Trennseiten-Erkennung, siehe INT-10) – beides als nachträgliche Korrektur nach dem Import, nicht nur zum Importzeitpunkt.",DOC-01 DOC-09,QA-03,"Mehrere Dokumente lassen sich zu einem zusammenführen, Ursprungsdokumente bleiben in der Versionshistorie nachvollziehbar
|
||||
Ein mehrseitiges Dokument lässt sich an beliebigen Seitengrenzen in mehrere eigenständige Dokumente aufteilen, jedes mit eigenen Metadaten
|
||||
Beide Operationen respektieren bestehende Aufbewahrungssperren (Archive-Retention) – eine Kachel mit aktiver Löschsperre kann nicht durch Zusammenführen/Aufteilen umgangen werden","Test: drei Dokumente zusammengeführt, Ursprünge in Historie auffindbar
|
||||
Test: fünfseitiges Dokument an zwei Stellen geteilt, drei korrekte Einzeldokumente entstehen
|
||||
Test: Zusammenführen/Aufteilen eines Dokuments mit aktiver Löschsperre wird abgelehnt oder erfordert Freigabe, nicht stillschweigend erlaubt"
|
||||
DOC-15,Massenbearbeitung von Metadaten,🗂️ Dokumentenkern,Backend,Mittel,3,4,Backlog,"Massenoperation über Dokumentauswahl, transaktionale Verarbeitung","Mehrere ausgewählte Dokumente gleichzeitig mit Tags/Metadatenfeldern/Dokumenttyp bearbeiten (hinzufügen, entfernen, ersetzen) statt Dokument für Dokument – Vorbild paperless-ngx Bulk-Edit.",DOC-01 MET-01,QA-03,"Tag/Metadatenfeld kann über eine Auswahl mehrerer Dokumente gleichzeitig hinzugefügt oder entfernt werden
|
||||
DOC-15,Massenbearbeitung von Metadaten,🗂️ Dokumentenkern,Backend,Mittel,3,4,Fertig,"Massenoperation über Dokumentauswahl, transaktionale Verarbeitung","Mehrere ausgewählte Dokumente gleichzeitig mit Tags/Metadatenfeldern/Dokumenttyp bearbeiten (hinzufügen, entfernen, ersetzen) statt Dokument für Dokument – Vorbild paperless-ngx Bulk-Edit.",DOC-01 MET-01,QA-03,"Tag/Metadatenfeld kann über eine Auswahl mehrerer Dokumente gleichzeitig hinzugefügt oder entfernt werden
|
||||
Vorgang ist transaktional nachvollziehbar (Versionshistorie/Audit zeigt die Massenänderung, nicht stillschweigend)
|
||||
Vorgang respektiert bestehende Aufbewahrungssperren – ein gesperrtes Dokument in der Auswahl wird übersprungen mit klarer Rückmeldung, nicht die ganze Operation blockiert oder die Sperre umgangen","Test: Tag auf 10 ausgewählte Dokumente gleichzeitig angewendet, alle korrekt aktualisiert
|
||||
Audit-Log zeigt Massenänderung nachvollziehbar
|
||||
Test mit einem gesperrten Dokument in der Auswahl: dieses wird übersprungen, Rest wird bearbeitet, klare Rückmeldung welches übersprungen wurde"
|
||||
INT-11,Archive-Anbindung: Objekttyp-Registrierung & Retention-Abfrage,🔌 Integration & API,Backend,Mittel,3,4,Backlog,"HTTP-Client gegen Archive-Modul-Adapter-Schnittstelle, Aufbewahrungsklassen-Mapping","Dokument-Objekttyp und dessen Aufbewahrungsklasse bei NEXARCH Archive registrieren und vor jeder Löschung/Änderung eine Aufbewahrungssperre (Legal Hold) abfragen, statt eigene Retention-Logik im DMS zu bauen.",DOC-01,QA-09 INT-16,"Dokument-Objekttyp inkl. Aufbewahrungsklasse wird beim Start automatisch bei Archive registriert
|
||||
INT-11,Archive-Anbindung: Objekttyp-Registrierung & Retention-Abfrage,🔌 Integration & API,Backend,Mittel,3,4,Fertig,"HTTP-Client gegen Archive-Modul-Adapter-Schnittstelle, Aufbewahrungsklassen-Mapping","Dokument-Objekttyp und dessen Aufbewahrungsklasse bei NEXARCH Archive registrieren und vor jeder Löschung/Änderung eine Aufbewahrungssperre (Legal Hold) abfragen, statt eigene Retention-Logik im DMS zu bauen.",DOC-01,QA-09 INT-16,"Dokument-Objekttyp inkl. Aufbewahrungsklasse wird beim Start automatisch bei Archive registriert
|
||||
Vor Löschung oder Hard-Overwrite eines Dokuments wird eine Sperr-Abfrage an Archive gestellt
|
||||
Ist das Dokument gesperrt (Legal Hold), wird die Löschung abgelehnt und die Ablehnung im Audit-Log vermerkt
|
||||
Ist Archive nicht erreichbar, wird die Löschung sicherheitshalber verweigert (fail closed), nicht stillschweigend durchgeführt","Registrierung gegen eine echte Archive-Testinstanz durchgeführt, Objekttyp erscheint dort
|
||||
Test: gesperrtes Dokument kann nicht gelöscht werden, Ablehnung ist im Audit-Log sichtbar
|
||||
Test: Archive-Endpunkt absichtlich nicht erreichbar – Löschung wird verweigert, kein Fallback auf ungeprüfte Löschung"
|
||||
INT-12,AI-Anbindung: Objekttyp-Registrierung (Kopplung AI GOV-01),🔌 Integration & API,Backend,Mittel,2,4,Backlog,"HTTP-Client gegen AI-Modul-Adapter-Schnittstelle, Feld-Mapping","Dokument-Objekttyp und dessen KI-relevante Felder (Volltext, Metadaten) bei NEXARCH AI registrieren, damit Klassifizierung, Extraktion und semantische Suche für Dokumente optional nutzbar werden, ohne eigene KI-Logik im DMS zu bauen.",DOC-01,QA-09 INT-16,"Dokument-Objekttyp inkl. KI-relevanter Felder wird beim Start automatisch bei AI registriert
|
||||
INT-12,AI-Anbindung: Objekttyp-Registrierung (Kopplung AI GOV-01),🔌 Integration & API,Backend,Mittel,2,4,Fertig,"HTTP-Client gegen AI-Modul-Adapter-Schnittstelle, Feld-Mapping","Dokument-Objekttyp und dessen KI-relevante Felder (Volltext, Metadaten) bei NEXARCH AI registrieren, damit Klassifizierung, Extraktion und semantische Suche für Dokumente optional nutzbar werden, ohne eigene KI-Logik im DMS zu bauen.",DOC-01,QA-09 INT-16,"Dokument-Objekttyp inkl. KI-relevanter Felder wird beim Start automatisch bei AI registriert
|
||||
Registrierung ist optional: ist AI-Modul nicht aktiviert (Core LIC-02), startet das DMS unverändert ohne Fehler
|
||||
Registrierungsfehler blockieren niemals den regulären DMS-Betrieb (fail open bei Registrierung, nicht bei Löschung)","Registrierung gegen eine echte AI-Testinstanz durchgeführt, Objekttyp erscheint dort
|
||||
Test: AI-Modul deaktiviert – DMS startet und läuft unverändert, keine Fehlermeldung im Normalbetrieb
|
||||
Test: AI-Endpunkt nicht erreichbar bei Registrierung – DMS-Start wird dadurch nicht blockiert"
|
||||
INT-13,Workflow-Anbindung: Objekttyp- & Auslöser-Registrierung (Kopplung Workflow ENG-02),🔌 Integration & API,Backend,Mittel,3,4,Backlog,"HTTP-Client gegen Workflow-Modul-Adapter-Schnittstelle, Ereignis-Publisher","Dokument-Objekttyp und Auslöser-Ereignisse (Dokument angelegt, Status geändert, Frist erreicht) bei NEXARCH Workflow registrieren und beim Eintreten publizieren, damit Genehmigungsprozesse und Aufgaben ohne eigene Workflow-Logik im DMS ausgelöst werden können.",DOC-01,QA-09 INT-16,"Dokument-Objekttyp inkl. verfügbarer Auslöser-Ereignisse wird beim Start automatisch bei Workflow registriert
|
||||
INT-13,Workflow-Anbindung: Objekttyp- & Auslöser-Registrierung (Kopplung Workflow ENG-02),🔌 Integration & API,Backend,Mittel,3,4,Fertig,"HTTP-Client gegen Workflow-Modul-Adapter-Schnittstelle, Ereignis-Publisher","Dokument-Objekttyp und Auslöser-Ereignisse (Dokument angelegt, Status geändert, Frist erreicht) bei NEXARCH Workflow registrieren und beim Eintreten publizieren, damit Genehmigungsprozesse und Aufgaben ohne eigene Workflow-Logik im DMS ausgelöst werden können.",DOC-01,QA-09 INT-16,"Dokument-Objekttyp inkl. verfügbarer Auslöser-Ereignisse wird beim Start automatisch bei Workflow registriert
|
||||
Ereignis 'Dokument angelegt' wird beim Anlegen eines Dokuments tatsächlich an Workflow publiziert
|
||||
Fehlschlagende Zustellung eines Ereignisses blockiert nicht die auslösende DMS-Aktion (asynchron, nicht im Request-Pfad)","Registrierung gegen eine echte Workflow-Testinstanz durchgeführt, Objekttyp und Ereignisse erscheinen dort
|
||||
Test: Dokument angelegt – Ereignis kommt nachweislich bei Workflow an
|
||||
Test: Workflow-Endpunkt zum Zustellzeitpunkt nicht erreichbar – Dokumentanlage im DMS bleibt trotzdem erfolgreich, Ereignis wird nachgeliefert oder sichtbar verworfen (nicht stillschweigend verloren)"
|
||||
SRC-11,Feld-Whitelist-Query-Builder für Suchindex-Zugriff,🔍 Suche & OCR,Backend,Einfach,1,3,Backlog,"Statisches Enum/Switch für Feldnamen, getesteter Query-Builder","Zentraler, getesteter Query-Builder mit Feld-Whitelist für den dynamischen Zugriff auf den DMS-Suchindex – Spalten-/Tabellennamen ausschließlich aus statischen Konstanten, nie aus Nutzereingabe oder generischem String-Zusammenbau (`fmt.Sprintf`), auch nicht hinter einer einfachen Whitelist-Funktion.",SRC-01,QA-06,"Spalten-/Feldnamen für dynamische Query-Teile stammen ausschließlich aus statischen Konstanten bzw. einem geschlossenen Enum/Switch-Typ, nie aus Nutzereingabe oder generischem String-Zusammenbau
|
||||
SRC-11,Feld-Whitelist-Query-Builder für Suchindex-Zugriff,🔍 Suche & OCR,Backend,Einfach,1,3,Fertig,"Statisches Enum/Switch für Feldnamen, getesteter Query-Builder","Zentraler, getesteter Query-Builder mit Feld-Whitelist für den dynamischen Zugriff auf den DMS-Suchindex – Spalten-/Tabellennamen ausschließlich aus statischen Konstanten, nie aus Nutzereingabe oder generischem String-Zusammenbau (`fmt.Sprintf`), auch nicht hinter einer einfachen Whitelist-Funktion.",SRC-01,QA-06,"Spalten-/Feldnamen für dynamische Query-Teile stammen ausschließlich aus statischen Konstanten bzw. einem geschlossenen Enum/Switch-Typ, nie aus Nutzereingabe oder generischem String-Zusammenbau
|
||||
Whitelist ist nicht die einzige Absicherung – der Query-Builder selbst lässt keine anderen Werte durch, auch nicht bei einem Fehler in der Whitelist-Prüfung
|
||||
Entscheidung dokumentiert: DMS-eigene Implementierung, keine geteilte Utility mit dem jeweils anderen Board – konsistent mit der bereits getroffenen Entscheidung, Suche/OCR nicht zu zentralisieren","Versuch, ein nicht in der Whitelist enthaltenes Feld anzufragen, wird abgewiesen statt stillschweigend ignoriert
|
||||
Code-Review bestätigt: kein dynamischer Spalten-/Tabellenname wird per String-Zusammenbau erzeugt"
|
||||
@@ -374,43 +374,84 @@ DMS empfängt den Vernichtungs-Rückruf, führt die Löschung durch und antworte
|
||||
Eine fehlgeschlagene Registrierung (Archive nicht erreichbar/Nicht-2xx) führt zu einem Requeue über FDN-04, nicht zu einem Absturz oder stillem Verwerfen","Registrierung real gegen einen Test-RET-05-Endpunkt durchgeführt und verifiziert
|
||||
Vernichtungs-Rückruf gegen einen echten Testfall ausgelöst, DMS-Löschung nachweislich erfolgt, 2xx-Antwort gesendet
|
||||
Simulierter Nicht-2xx-Fehler bei der Registrierung führt nachweislich zu einem Requeue-Eintrag in der Jobqueue, kein Absturz"
|
||||
INT-14,Tenant-Zuordnung & Zugriffsschutz für Hot-Folder/Scanner-Verzeichnisse,🔌 Integration & API,Backend,Mittel,2,12,Backlog,"Dateisystem-Zugriffsrechte, Verzeichnisstruktur je Tenant, Go","INT-06 (Netzwerkscanner-Ordner) und INT-08 (Hot-Folder) importieren Dateien ohne API-Aufruf und damit ohne Anwendungs-Auth-Kontext. Ohne klare Zuordnung, welches Verzeichnis zu welchem Mandanten gehört, und ohne Zugriffsschutz auf Dateisystemebene kann eine falsch konfigurierte Freigabe Dokumente dem falschen Tenant zuordnen oder Dritten Schreibzugriff erlauben. Je Tenant ein eigenes, klar benanntes Verzeichnis mit dediziertem Dateisystem-Benutzer/Gruppenrechten einführen, Import-Routine prüft beim Einlesen explizit die Tenant-Zuordnung des Quellverzeichnisses gegen die Registry (Core TEN-01), bevor ein Dokument angelegt wird.",INT-06 INT-08,,"Jedes Hot-Folder-/Scanner-Verzeichnis ist genau einem Tenant fest zugeordnet, verankert in der Core-Registry
|
||||
INT-14,Tenant-Zuordnung & Zugriffsschutz für Hot-Folder/Scanner-Verzeichnisse,🔌 Integration & API,Backend,Mittel,2,12,Fertig,"Dateisystem-Zugriffsrechte, Verzeichnisstruktur je Tenant, Go","INT-06 (Netzwerkscanner-Ordner) und INT-08 (Hot-Folder) importieren Dateien ohne API-Aufruf und damit ohne Anwendungs-Auth-Kontext. Ohne klare Zuordnung, welches Verzeichnis zu welchem Mandanten gehört, und ohne Zugriffsschutz auf Dateisystemebene kann eine falsch konfigurierte Freigabe Dokumente dem falschen Tenant zuordnen oder Dritten Schreibzugriff erlauben. Je Tenant ein eigenes, klar benanntes Verzeichnis mit dediziertem Dateisystem-Benutzer/Gruppenrechten einführen, Import-Routine prüft beim Einlesen explizit die Tenant-Zuordnung des Quellverzeichnisses gegen die Registry (Core TEN-01), bevor ein Dokument angelegt wird.",INT-06 INT-08,,"Jedes Hot-Folder-/Scanner-Verzeichnis ist genau einem Tenant fest zugeordnet, verankert in der Core-Registry
|
||||
Die Import-Routine lehnt einen Import ab und protokolliert dies, wenn die Verzeichnis-Tenant-Zuordnung nicht auflösbar oder inkonsistent ist
|
||||
Dateisystemrechte beschränken Schreibzugriff auf das Verzeichnis auf die vorgesehenen Quellen (Scanner/Sync-Tool), dokumentiert in der Betriebsanleitung","Test: Import aus einem korrekt zugeordneten Verzeichnis legt Dokument beim richtigen Tenant an
|
||||
Test: Import aus einem nicht zugeordneten/fehlkonfigurierten Verzeichnis wird abgelehnt und protokolliert
|
||||
Prüft Dateisystemrechte des Verzeichnisses gegen die Betriebsanleitung"
|
||||
INT-15,CMIS-Schnittstelle: Auth-/Tenant-Scoping-Parität zur REST-API,🔌 Integration & API,Backend,Mittel,2,12,Backlog,"CMIS, gemeinsame Auth-Middleware, Go","INT-09 stellt eine CMIS-Standardschnittstelle für Drittwerkzeuge bereit, ohne festzulegen, ob diese dieselbe Authentifizierung und Tenant-Scoping-Durchsetzung wie die REST-API verwendet. Eine zweite, schwächer geprüfte API-Fläche würde die gesamte Zugriffskontrolle umgehbar machen. CMIS auf dieselbe Auth-Middleware und Tenant-Kontext-Ermittlung wie die REST-API (INT-01) verpflichten – keine eigene, parallele Auth-Implementierung.",INT-09,,"CMIS-Endpunkte verwenden dieselbe Auth-Middleware wie die REST-API, keine eigene Login-/Token-Prüfung
|
||||
INT-15,CMIS-Schnittstelle: Auth-/Tenant-Scoping-Parität zur REST-API,🔌 Integration & API,Backend,Mittel,2,12,Fertig,"CMIS, gemeinsame Auth-Middleware, Go","INT-09 stellt eine CMIS-Standardschnittstelle für Drittwerkzeuge bereit, ohne festzulegen, ob diese dieselbe Authentifizierung und Tenant-Scoping-Durchsetzung wie die REST-API verwendet. Eine zweite, schwächer geprüfte API-Fläche würde die gesamte Zugriffskontrolle umgehbar machen. CMIS auf dieselbe Auth-Middleware und Tenant-Kontext-Ermittlung wie die REST-API (INT-01) verpflichten – keine eigene, parallele Auth-Implementierung.",INT-09,,"CMIS-Endpunkte verwenden dieselbe Auth-Middleware wie die REST-API, keine eigene Login-/Token-Prüfung
|
||||
Ein über CMIS authentifizierter Aufruf ist auf denselben Tenant beschränkt wie über die REST-API mit denselben Credentials
|
||||
Ein automatisierter Test vergleicht Zugriffsergebnisse für dieselbe Anfrage über REST und CMIS und erwartet identisches Autorisierungsverhalten","Test: Zugriff auf ein fremdes Tenant-Dokument über CMIS wird identisch zur REST-API abgelehnt
|
||||
Test: abgelaufenes/widerrufenes Token wird von CMIS genauso abgelehnt wie von der REST-API (Kopplung an Core IAM-17)
|
||||
Code-Review-Gate: CMIS-Handler dürfen keine eigene Auth-Logik enthalten, nur die gemeinsame Middleware referenzieren"
|
||||
INT-16,Nutzer-Tenant-Kontext in Modul-Rückkanälen (Archive/AI/Workflow),🔌 Integration & API,Backend,Mittel,2,12,Backlog,"Service-Credentials (Core API-02), Tenant-Kontext-Weiterreichung, Go","INT-11/12/13 registrieren DMS-Objekttypen und Ereignisse bei Archive, AI und Workflow über Service-Credentials. Rückkanal-Aufrufe (z. B. DOC-13 → Workflow VOR-04) dürfen dabei niemals nur im Kontext des Service-Accounts laufen, sondern müssen den ursprünglichen Nutzer-Tenant-Kontext durchreichen – sonst könnte ein Nutzer über den Umweg eines anderen Moduls Daten eines fremden Mandanten sehen, obwohl DMS selbst korrekt mandantengetrennt ist. Tenant-ID des anfragenden Nutzers explizit als Pflichtparameter in jedem Rückkanal-Aufruf verankern und serverseitig gegen den Service-Credential-Scope validieren.",INT-11 INT-12 INT-13,,"Jeder Rückkanal-Aufruf an Archive/AI/Workflow trägt den Tenant-Kontext des ursprünglich anfragenden Nutzers als Pflichtparameter
|
||||
INT-16,Nutzer-Tenant-Kontext in Modul-Rückkanälen (Archive/AI/Workflow),🔌 Integration & API,Backend,Mittel,2,12,Fertig,"Service-Credentials (Core API-02), Tenant-Kontext-Weiterreichung, Go","INT-11/12/13 registrieren DMS-Objekttypen und Ereignisse bei Archive, AI und Workflow über Service-Credentials. Rückkanal-Aufrufe (z. B. DOC-13 → Workflow VOR-04) dürfen dabei niemals nur im Kontext des Service-Accounts laufen, sondern müssen den ursprünglichen Nutzer-Tenant-Kontext durchreichen – sonst könnte ein Nutzer über den Umweg eines anderen Moduls Daten eines fremden Mandanten sehen, obwohl DMS selbst korrekt mandantengetrennt ist. Tenant-ID des anfragenden Nutzers explizit als Pflichtparameter in jedem Rückkanal-Aufruf verankern und serverseitig gegen den Service-Credential-Scope validieren.",INT-11 INT-12 INT-13,,"Jeder Rückkanal-Aufruf an Archive/AI/Workflow trägt den Tenant-Kontext des ursprünglich anfragenden Nutzers als Pflichtparameter
|
||||
Das aufgerufene Modul validiert, dass der übergebene Tenant-Kontext zum Tenant des Zielobjekts passt, unabhängig vom Service-Credential-Scope
|
||||
Ein manipulierter/falscher Tenant-Kontext im Aufruf wird abgelehnt und protokolliert","Test: Rückkanal-Aufruf mit korrektem Nutzer-Tenant-Kontext liefert erwartete Daten
|
||||
Test: Rückkanal-Aufruf mit manipuliertem Tenant-Kontext (fremder Tenant) wird abgelehnt
|
||||
Integrationstest über DOC-13 → Workflow VOR-04 mit zwei verschiedenen Tenants, prüft Isolation"
|
||||
DOC-17,Malware-Scan vor Ablage,🗂️ Dokumentenkern,Backend,Mittel,2,12,Backlog,"Virenscanner-Anbindung (z. B. ClamAV), Go, Postgres-Jobqueue","DOC-01 validiert Größe und MIME-Typ beim Upload, prüft aber nicht auf schädliche Inhalte (Viren, aktive Inhalte in Office-Dokumenten/Makros). Virenscan als verpflichtenden Verarbeitungsschritt vor endgültiger Ablage ergänzen – Upload bleibt in Quarantäne-Status, bis der Scan abgeschlossen ist; bei Fund wird das Dokument abgelehnt und der Vorfall protokolliert.",DOC-01,,"Jede hochgeladene Datei durchläuft einen Virenscan, bevor sie als reguläres Dokument sichtbar/abrufbar wird
|
||||
DOC-17,Malware-Scan vor Ablage,🗂️ Dokumentenkern,Backend,Mittel,2,12,Fertig,"Virenscanner-Anbindung (z. B. ClamAV), Go, Postgres-Jobqueue","DOC-01 validiert Größe und MIME-Typ beim Upload, prüft aber nicht auf schädliche Inhalte (Viren, aktive Inhalte in Office-Dokumenten/Makros). Virenscan als verpflichtenden Verarbeitungsschritt vor endgültiger Ablage ergänzen – Upload bleibt in Quarantäne-Status, bis der Scan abgeschlossen ist; bei Fund wird das Dokument abgelehnt und der Vorfall protokolliert.",DOC-01,,"Jede hochgeladene Datei durchläuft einen Virenscan, bevor sie als reguläres Dokument sichtbar/abrufbar wird
|
||||
Ein positiver Scan-Fund führt zur Ablehnung des Dokuments und einem Audit-Event, nicht zu stiller Ablage
|
||||
Der Scan-Status ist für den hochladenden Nutzer sichtbar (in Bearbeitung/freigegeben/abgelehnt)","Test mit EICAR-Testdatei: wird zuverlässig erkannt und abgelehnt
|
||||
Test mit sauberer Datei: durchläuft Scan und wird normal verfügbar
|
||||
Lasttest: Scan-Queue verarbeitet mehrere gleichzeitige Uploads ohne Verlust der Reihenfolge/Nachvollziehbarkeit"
|
||||
FDN-10,Signierte URLs: Scope-Bindung & kurze Ablaufzeit,⚙️ Fundament,Backend,Einfach,1,12,Backlog,"Storage-Adapter (S3-kompatibel), signierte URLs, Go","FDN-03 stellt signierte URLs für den Storage-Zugriff bereit, ohne deren Scope und Ablaufzeit explizit festzulegen. Jede signierte URL muss fest an genau ein Objekt gebunden sein (nicht an ein Präfix/Verzeichnis) und eine kurze, konfigurierbare Ablaufzeit haben (Minuten, nicht Stunden). Nach Ablauf oder nach Löschung/Versionswechsel des Objekts muss die URL ungültig sein.",FDN-03,,"Eine signierte URL gewährt ausschließlich Zugriff auf genau das Objekt, für das sie ausgestellt wurde
|
||||
FDN-10,Signierte URLs: Scope-Bindung & kurze Ablaufzeit,⚙️ Fundament,Backend,Einfach,1,12,Fertig,"Storage-Adapter (S3-kompatibel), signierte URLs, Go","FDN-03 stellt signierte URLs für den Storage-Zugriff bereit, ohne deren Scope und Ablaufzeit explizit festzulegen. Jede signierte URL muss fest an genau ein Objekt gebunden sein (nicht an ein Präfix/Verzeichnis) und eine kurze, konfigurierbare Ablaufzeit haben (Minuten, nicht Stunden). Nach Ablauf oder nach Löschung/Versionswechsel des Objekts muss die URL ungültig sein.",FDN-03,,"Eine signierte URL gewährt ausschließlich Zugriff auf genau das Objekt, für das sie ausgestellt wurde
|
||||
Ablaufzeit ist konfigurierbar und im Standardfall im Minutenbereich, hart durchgesetzt vom Storage-Adapter
|
||||
Nach Ablauf liefert ein Zugriffsversuch über die URL einen Fehler, kein stilles Fallback auf öffentlichen Zugriff","Test: signierte URL für Objekt A liefert bei Zugriffsversuch auf Objekt B einen Fehler
|
||||
Test: abgelaufene URL wird abgelehnt
|
||||
Test: URL für ein zwischenzeitlich gelöschtes Objekt wird abgelehnt"
|
||||
FDN-11,Ressourcenlimits für asynchrone Verarbeitungsjobs,⚙️ Fundament,Backend,Mittel,2,12,Backlog,"Postgres-Jobqueue, Worker-Goroutinen, Ressourcenlimits (Zeit/Speicher/Seitenzahl)","FDN-04 verarbeitet OCR/Konvertierung/Indexierung/Exporte mit Wiederholungslogik, Backoff und Dead-Letter-Queue, ohne Obergrenzen pro Einzeljob festzulegen. Eine sehr große oder speziell präparierte Datei (z. B. sehr viele Seiten, Zip-Bomb-artige Kompression bei Konvertierung) kann einen Worker dauerhaft blockieren und damit die Verarbeitung für andere Mandanten verzögern. Harte Obergrenzen je Job definieren (max. Verarbeitungszeit, max. Speicherverbrauch, max. Seiten-/Dateigröße) – bei Überschreitung wird der Job abgebrochen, in die Dead-Letter-Queue verschoben und der Nutzer informiert, statt den Worker zu blockieren.",FDN-04,,"Jeder Verarbeitungsjob hat konfigurierbare Obergrenzen für Zeit, Speicher und Eingabegröße/Seitenzahl
|
||||
FDN-11,Ressourcenlimits für asynchrone Verarbeitungsjobs,⚙️ Fundament,Backend,Mittel,2,12,Fertig,"Postgres-Jobqueue, Worker-Goroutinen, Ressourcenlimits (Zeit/Speicher/Seitenzahl)","FDN-04 verarbeitet OCR/Konvertierung/Indexierung/Exporte mit Wiederholungslogik, Backoff und Dead-Letter-Queue, ohne Obergrenzen pro Einzeljob festzulegen. Eine sehr große oder speziell präparierte Datei (z. B. sehr viele Seiten, Zip-Bomb-artige Kompression bei Konvertierung) kann einen Worker dauerhaft blockieren und damit die Verarbeitung für andere Mandanten verzögern. Harte Obergrenzen je Job definieren (max. Verarbeitungszeit, max. Speicherverbrauch, max. Seiten-/Dateigröße) – bei Überschreitung wird der Job abgebrochen, in die Dead-Letter-Queue verschoben und der Nutzer informiert, statt den Worker zu blockieren.",FDN-04,,"Jeder Verarbeitungsjob hat konfigurierbare Obergrenzen für Zeit, Speicher und Eingabegröße/Seitenzahl
|
||||
Eine Überschreitung führt zum kontrollierten Abbruch des Jobs (Dead-Letter-Queue), nicht zur Blockade des Workers
|
||||
Andere, gleichzeitig laufende Jobs (auch anderer Mandanten) bleiben von einem überschreitenden Job unbeeinflusst","Test mit einer Datei, die absichtlich die Seiten-/Größenobergrenze überschreitet: Job wird kontrolliert abgebrochen
|
||||
Lasttest: ein überschreitender Job blockiert nicht die Verarbeitung paralleler, regulärer Jobs
|
||||
Test der Nutzerbenachrichtigung bei abgebrochenem Job"
|
||||
VER-08,Technische Durchsetzung Append-only für das Versionierungs-/Ereignisprotokoll,🔄 Versionierung & Audit,Backend,Einfach,2,12,Backlog,"PostgreSQL (REVOKE/Trigger), Go","VER-05 konzipiert ein unveränderliches, verkettetes Protokoll aller sicherheits- und geschäftsrelevanten Ereignisse, setzt „unveränderlich“ aber nur konventionell um. Analog zu Core `AUD-07` technisch erzwingen: der Anwendungs-Datenbankrolle werden UPDATE-/DELETE-Rechte auf die Protokolltabelle entzogen (nur INSERT/SELECT), ergänzt um einen Datenbank-Trigger, der jeden Änderungsversuch ablehnt und selbst protokolliert.",VER-05,,"Die vom DMS-Prozess verwendete Datenbankrolle kann Protokolleinträge nachweislich weder verändern noch löschen
|
||||
VER-08,Technische Durchsetzung Append-only für das Versionierungs-/Ereignisprotokoll,🔄 Versionierung & Audit,Backend,Einfach,2,12,Fertig,"PostgreSQL (REVOKE/Trigger), Go","VER-05 konzipiert ein unveränderliches, verkettetes Protokoll aller sicherheits- und geschäftsrelevanten Ereignisse, setzt „unveränderlich“ aber nur konventionell um. Analog zu Core `AUD-07` technisch erzwingen: der Anwendungs-Datenbankrolle werden UPDATE-/DELETE-Rechte auf die Protokolltabelle entzogen (nur INSERT/SELECT), ergänzt um einen Datenbank-Trigger, der jeden Änderungsversuch ablehnt und selbst protokolliert.",VER-05,,"Die vom DMS-Prozess verwendete Datenbankrolle kann Protokolleinträge nachweislich weder verändern noch löschen
|
||||
Ein Änderungsversuch wird von der Datenbank abgelehnt und selbst protokolliert
|
||||
Die Verkettung (Unversehrtheitsnachweis) aus VER-05 bleibt vollständig nutzbar","Testet UPDATE/DELETE gegen die Protokolltabelle mit der Anwendungsrolle, erwartet Rechteverweigerung
|
||||
Prüft, dass der Ablehnungsversuch selbst sichtbar protokolliert wird
|
||||
Regressionstest: Verkettungsprüfung (Unversehrtheitsnachweis) funktioniert nach der Rechteänderung weiterhin"
|
||||
DOC-18,Obergrenze für Gesamtgröße/Anzahl bei Archiv-Bündelung,🗂️ Dokumentenkern,Backend,Einfach,1,13,Backlog,"Postgres-Jobqueue, Ressourcenlimits, Go","DOC-08 bündelt mehrere ausgewählte Dokumente als Hintergrund-Job zu einem Archiv, ohne Obergrenze für Gesamtgröße oder Anzahl der Dokumente je Anfrage. Eine übermäßig große Auswahl kann sonst den Bündelungs-Job unverhältnismäßig lange laufen lassen und Ressourcen auf Kosten anderer Mandanten binden. Harte, konfigurierbare Obergrenze für maximale Gesamtgröße und maximale Dokumentanzahl je Bündelungs-Anfrage einführen – bei Überschreitung wird die Anfrage mit klarer Fehlermeldung abgelehnt, bevor der Job gestartet wird.",DOC-08,,"Eine Bündelungs-Anfrage mit konfigurierbar zu großer Gesamtgröße oder Dokumentanzahl wird vor Jobstart abgelehnt, mit klarer Fehlermeldung an den Nutzer
|
||||
DOC-18,Obergrenze für Gesamtgröße/Anzahl bei Archiv-Bündelung,🗂️ Dokumentenkern,Backend,Einfach,1,13,Fertig,"Postgres-Jobqueue, Ressourcenlimits, Go","DOC-08 bündelt mehrere ausgewählte Dokumente als Hintergrund-Job zu einem Archiv, ohne Obergrenze für Gesamtgröße oder Anzahl der Dokumente je Anfrage. Eine übermäßig große Auswahl kann sonst den Bündelungs-Job unverhältnismäßig lange laufen lassen und Ressourcen auf Kosten anderer Mandanten binden. Harte, konfigurierbare Obergrenze für maximale Gesamtgröße und maximale Dokumentanzahl je Bündelungs-Anfrage einführen – bei Überschreitung wird die Anfrage mit klarer Fehlermeldung abgelehnt, bevor der Job gestartet wird.",DOC-08,,"Eine Bündelungs-Anfrage mit konfigurierbar zu großer Gesamtgröße oder Dokumentanzahl wird vor Jobstart abgelehnt, mit klarer Fehlermeldung an den Nutzer
|
||||
Innerhalb der Obergrenze funktioniert die Bündelung aus DOC-08 unverändert
|
||||
Die Obergrenzen sind konfigurierbar, nicht hart im Code verankert","Test: Anfrage mit Auswahl oberhalb der konfigurierten Obergrenze wird abgelehnt, kein Job wird gestartet
|
||||
Test: Anfrage innerhalb der Obergrenze wird normal verarbeitet
|
||||
Regressionstest bestehender DOC-08-Funktionalität nach Einführung der Prüfung"
|
||||
SEC-01,Unauthentifizierter Vernichtungs-Rückruf löscht Dokumente physisch,🔒 Sicherheit,Backend,Komplex,3,13,Backlog,"Service-Token-Pflicht, Legal-Hold-Check, Body-Limit","Der Vernichtungs-Rückruf des Retention-Dienstes ist im Standardbetrieb fail-open: ohne Bearer-Token werden Dokumente physisch gelöscht, Legal Hold wird nicht geprüft, der Audit-Akteur wird falsch protokolliert.",,,"RequireServiceToken serverseitig fest auf true erzwungen
|
||||
Aufruf ohne gültiges Bearer-Token wird mit 401/403 abgelehnt
|
||||
Legal-Hold-Status wird vor physischer Löschung geprüft
|
||||
Request-Body ist auf eine feste Obergrenze begrenzt
|
||||
Audit-Eintrag protokolliert den tatsächlichen Service-Akteur","Angriffsnachstellung ohne Bearer-Token: vor Fix löschend, nach Fix abgelehnt
|
||||
Aufruf gegen Objekt mit aktivem Legal Hold wird abgelehnt
|
||||
Request-Body oberhalb der Obergrenze wird abgelehnt
|
||||
Audit-Log nach legitimem Aufruf enthält korrekten Service-Akteur"
|
||||
SEC-02,Mail-Postfachverwaltung ohne Rollenprüfung ermöglicht Credential-Exfiltration,🔒 Sicherheit,Backend,Komplex,3,13,Backlog,"Rollenprüfung Admin-only, Passwortbindung bei Host-Änderung","Die Mail-Postfachverwaltung erlaubt jeder authentifizierten Identität Host/Port-Änderungen ohne Passwortbestätigung, wodurch gespeicherte IMAP-Zugangsdaten an einen angreifereigenen Server exfiltriert werden können; ImportUserID ist zusätzlich frei wählbar.",,,"needsGuard für mail-accounts auf true gesetzt, nur Admin-Rolle
|
||||
Host/Port-Änderung verlangt erneute Passworteingabe
|
||||
ImportUserID wird serverseitig auf den authentifizierten Actor fixiert
|
||||
Automatisierter Test belegt Ablehnung von Host-Änderung ohne Passwort","Angriffsnachstellung: Host-Änderung mit leerem Passwort auf fremden IMAP-Server, vor/nach Fix dokumentiert
|
||||
Angriffsnachstellung: Import mit fremdem ImportUserID, vor/nach Fix dokumentiert
|
||||
Regressionstest: legitime Host-Änderung mit Passwort funktioniert weiterhin"
|
||||
SEC-03,Guard-Lücken: Papierkorb/Ordnerbaum/Trigger-Webhooks ohne Zugriffsprüfung,🔒 Sicherheit,Backend,Mittel,2,13,Backlog,"needsGuard-Korrektur, eigentümerbezogene Filterung","GET /trash, /folders und /triggers liefern mandanten-/nutzerübergreifend Daten aus, da needsGuard für diese Routen auf false steht.",,,"needsGuard für GET /folders/*, /trash, /triggers auf true
|
||||
GET /trash liefert nur eigene Papierkorb-Einträge
|
||||
folderapi liefert nur sichtbaren Teilbaum
|
||||
triggerapi liefert webhook_url nur bei Berechtigung","Angriffsnachstellung GET /trash fremder Nutzer, vor/nach Fix dokumentiert
|
||||
Gleiche Nachstellung für /folders und /triggers
|
||||
Regressionstest: eigene Daten weiterhin vollständig sichtbar"
|
||||
SEC-04,Virenscan standardmäßig nicht in die Verarbeitungs-Pipeline eingereiht,🔒 Sicherheit,Backend,Mittel,2,13,Backlog,"enqueueTypes-Default, Sichtbarkeitsfilter umkehren","malwarescan.scan ist nicht in enqueueTypes enthalten; Dokumente ohne jemals ausgeführten Scan sind sofort sichtbar, da nur explizit unclean markierte Dokumente ausgeblendet werden.",,,"malwarescan.scan standardmäßig in enqueueTypes
|
||||
Sichtbarkeit nur bei explizitem status = clean
|
||||
Bestehende ungescannte Dokumente werden per Nachlauf erfasst","Angriffsnachstellung: Upload bei deaktiviertem Scan-Worker, vor/nach Fix dokumentiert
|
||||
Regressionstest: clean-Dokument bleibt sichtbar
|
||||
Regressionstest: unclean-Dokument bleibt gesperrt"
|
||||
SEC-05,"Upload-Limit standardmäßig unbegrenzt, Client-MIME ungeprüft, authentifizierter OOM",🔒 Sicherheit,Backend,Mittel,3,13,Backlog,"Upload-Limit-Default, Server-MIME-Sniffing, Streaming-Verschlüsselung","Upload-Limit 0 gilt als unbegrenzt, MIME-Typ wird vom Client übernommen, und die Verschlüsselung liest die komplette Datei ins RAM — ein authentifizierter Nutzer kann per großem Upload einen RAM-OOM auslösen.",,,"Standard-Upload-Limit ist fester Wert > 0
|
||||
MIME-Typ wird serverseitig gesnifft und abgeglichen
|
||||
Verschlüsselungspfad verarbeitet den Stream statt vollständigem RAM-Puffer
|
||||
Request-Body ist hart begrenzt","Angriffsnachstellung: großer Upload, RAM-Verbrauch vor/nach Fix gemessen und dokumentiert
|
||||
Angriffsnachstellung: falsch deklarierter Content-Type wird per Sniffing erkannt
|
||||
Regressionstest: reguläre Uploads funktionieren weiterhin"
|
||||
SEC-06,Modul-Verifier akzeptiert fremde Tenants wenn TENANT_SLUG leer,🔒 Sicherheit,Backend,Einfach,1,13,Backlog,TENANT_SLUG-Pflicht beim Dienststart,"Ist TENANT_SLUG beim Dienststart leer, wird die Tenant-Prüfung im Modul-Verifier übersprungen und Tokens für jeden Tenant akzeptiert.",,,"Dienststart verweigert bei fehlendem/leerem TENANT_SLUG
|
||||
verifier.go prüft Tenant immer, keine Ausnahme bei leerem Wert
|
||||
Token für fremden Tenant wird in jedem Fall abgelehnt","Angriffsnachstellung: Start ohne TENANT_SLUG, fremdes Token, vor/nach Fix dokumentiert
|
||||
Regressionstest: korrekter Start mit eigenem Token funktioniert
|
||||
Test: fremdes Token bei korrektem TENANT_SLUG weiterhin abgelehnt"
|
||||
SEC-07,NEXARCH_DMS_APP_ALLOW_CALLER_IDENTITY umgeht komplette Authentifizierung,🔒 Sicherheit,Backend,Mittel,2,13,Backlog,Produktionssperre für Übergangs-Flag,"Das Flag ALLOW_CALLER_IDENTITY erlaubt Admin-Zugriff per Query-Parameter ohne echte Authentifizierung und ist nur per Deployment-Checkliste, nicht technisch, auf Host 131 beschränkt.",,,"Flag wirkt nur bei explizit markierter Nicht-Produktionsumgebung
|
||||
Bei Produktion oder fehlender Markierung wird das Flag ignoriert
|
||||
Deployment-Checkliste enthält Entfernungsschritt vor Produktivbetrieb","Angriffsnachstellung: Flag ohne Nicht-Produktions-Markierung, vor/nach Fix dokumentiert
|
||||
Regressionstest: Flag mit korrekter Markierung funktioniert für Host 131 weiterhin
|
||||
Test: Flag ohne jede Umgebungsvariable wird ignoriert"
|
||||
|
+279
-70
@@ -57,6 +57,13 @@
|
||||
"emoji": "✅",
|
||||
"color": "#22C55E",
|
||||
"description": "Teststrategie und verbindliche Prüfgates je Ausbaustufe. Ein Gate schließt eine Ausbaustufe ab."
|
||||
},
|
||||
{
|
||||
"key": "SEC",
|
||||
"name": "Sicherheit",
|
||||
"emoji": "🔒",
|
||||
"color": "#DC2626",
|
||||
"description": "Befunde aus Security-Reviews und deren Behebung."
|
||||
}
|
||||
],
|
||||
"waves": [
|
||||
@@ -580,7 +587,7 @@
|
||||
"Absichtlich eingeführte bekannte Schwachstelle in einer Testabhängigkeit lässt den Build fehlschlagen.",
|
||||
"Merge-Versuch eines sicherheitsrelevanten Codepfads ohne Test wird von der Pipeline blockiert."
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Fundament",
|
||||
"epicEmoji": "⚙️",
|
||||
"wave": 2,
|
||||
@@ -613,7 +620,7 @@
|
||||
"Logs enthalten keine Passwörter oder Tokens",
|
||||
"Alarm-Schwelle einmal ausgelöst und quittiert"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Fundament",
|
||||
"epicEmoji": "⚙️",
|
||||
"wave": 2,
|
||||
@@ -701,7 +708,7 @@
|
||||
"Datei mit einem geänderten Byte gilt nicht als Duplikat",
|
||||
"Prüfsummenberechnung bei Großdatei bleibt im Zeitbudget"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Dokumentenkern",
|
||||
"epicEmoji": "🗂️",
|
||||
"wave": 4,
|
||||
@@ -736,7 +743,7 @@
|
||||
"Verhalten bei Netzabbruch im Browser geprüft",
|
||||
"Mobile Ansicht bleibt bedienbar"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Dokumentenkern",
|
||||
"epicEmoji": "🗂️",
|
||||
"wave": 4,
|
||||
@@ -771,7 +778,7 @@
|
||||
"Durchsatztest mit 500 Dokumenten",
|
||||
"Cache-Invalidierung bei neuer Revision belegt"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Dokumentenkern",
|
||||
"epicEmoji": "🗂️",
|
||||
"wave": 4,
|
||||
@@ -806,7 +813,7 @@
|
||||
"Viewer per Tastatur bedienbar",
|
||||
"Speicherverbrauch im Browser bleibt stabil"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Dokumentenkern",
|
||||
"epicEmoji": "🗂️",
|
||||
"wave": 5,
|
||||
@@ -842,7 +849,7 @@
|
||||
"Zeitlimit bei Endlosdokument greift",
|
||||
"Konverter-Absturz beeinträchtigt andere Jobs nicht"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Dokumentenkern",
|
||||
"epicEmoji": "🗂️",
|
||||
"wave": 4,
|
||||
@@ -877,7 +884,7 @@
|
||||
"Weitergegebene abgelaufene URL wird abgewiesen",
|
||||
"Sonderzeichen im Dateinamen korrekt übertragen"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Dokumentenkern",
|
||||
"epicEmoji": "🗂️",
|
||||
"wave": 4,
|
||||
@@ -912,7 +919,7 @@
|
||||
"Archiv in gängigen Entpackern lesbar",
|
||||
"Berechtigungsfilter durch Negativtest belegt"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Dokumentenkern",
|
||||
"epicEmoji": "🗂️",
|
||||
"wave": 5,
|
||||
@@ -947,7 +954,7 @@
|
||||
"Abfrage bei 10.000 Ordnern im Zeitbudget",
|
||||
"Umbenennen bricht keine Verweise"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Dokumentenkern",
|
||||
"epicEmoji": "🗂️",
|
||||
"wave": 3,
|
||||
@@ -983,7 +990,7 @@
|
||||
"Navigation vollständig per Tastatur",
|
||||
"Zustand bleibt beim Zurücknavigieren erhalten"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Dokumentenkern",
|
||||
"epicEmoji": "🗂️",
|
||||
"wave": 4,
|
||||
@@ -1017,7 +1024,7 @@
|
||||
"Wiederherstellung nach Ordnerlöschung getestet",
|
||||
"Aufräum-Job löscht nur abgelaufene Einträge"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Dokumentenkern",
|
||||
"epicEmoji": "🗂️",
|
||||
"wave": 4,
|
||||
@@ -1051,7 +1058,7 @@
|
||||
"Massenwiederherstellung mit 100 Objekten geprüft",
|
||||
"Leerer Papierkorb zeigt verständlichen Hinweis"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Dokumentenkern",
|
||||
"epicEmoji": "🗂️",
|
||||
"wave": 5,
|
||||
@@ -1085,7 +1092,7 @@
|
||||
"Umlaut- und Kompositasuche liefert Treffer",
|
||||
"Neustart des Dienstes ohne Datenverlust"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Suche & OCR",
|
||||
"epicEmoji": "🔍",
|
||||
"wave": 2,
|
||||
@@ -1122,7 +1129,7 @@
|
||||
"Indexierung von 10.000 Dokumenten im Zeitbudget",
|
||||
"Ausfall des Suchdienstes führt zu Nachholung statt Datenverlust"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Suche & OCR",
|
||||
"epicEmoji": "🔍",
|
||||
"wave": 5,
|
||||
@@ -1156,7 +1163,7 @@
|
||||
"Berechtigungsfilter durch Negativtest belegt",
|
||||
"Lasttest mit gleichzeitigen Suchanfragen bestanden"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Suche & OCR",
|
||||
"epicEmoji": "🔍",
|
||||
"wave": 6,
|
||||
@@ -1192,7 +1199,7 @@
|
||||
"Verhalten bei sehr langem Suchbegriff geprüft",
|
||||
"Ergebnisliste auf Mobilgerät nutzbar"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Suche & OCR",
|
||||
"epicEmoji": "🔍",
|
||||
"wave": 7,
|
||||
@@ -1229,7 +1236,7 @@
|
||||
"Schiefer Scan wird korrekt entzerrt",
|
||||
"Sehr großes Dokument läuft nicht in Zeitüberschreitung"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Suche & OCR",
|
||||
"epicEmoji": "🔍",
|
||||
"wave": 5,
|
||||
@@ -1266,7 +1273,7 @@
|
||||
"Textposition deckt sich mit dem Bild",
|
||||
"Dateigröße bleibt im vereinbarten Rahmen"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Suche & OCR",
|
||||
"epicEmoji": "🔍",
|
||||
"wave": 6,
|
||||
@@ -1300,7 +1307,7 @@
|
||||
"Schlechter Scan landet zuverlässig in der Prüfliste",
|
||||
"Schwellwert ist ohne Neuveröffentlichung konfigurierbar"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Suche & OCR",
|
||||
"epicEmoji": "🔍",
|
||||
"wave": 6,
|
||||
@@ -1335,7 +1342,7 @@
|
||||
"Filter auf leerem Ergebnis verhält sich stabil",
|
||||
"Antwortzeit mit fünf aktiven Filtern gemessen"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Suche & OCR",
|
||||
"epicEmoji": "🔍",
|
||||
"wave": 7,
|
||||
@@ -1371,7 +1378,7 @@
|
||||
"Panel auf schmalem Bildschirm bedienbar",
|
||||
"Zurücksetzen entfernt wirklich alle Filter"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Suche & OCR",
|
||||
"epicEmoji": "🔍",
|
||||
"wave": 8,
|
||||
@@ -1405,7 +1412,7 @@
|
||||
"Geteilte Suche zeigt jedem nur erlaubte Dokumente",
|
||||
"Löschen einer Suche beeinträchtigt andere Nutzer nicht"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Suche & OCR",
|
||||
"epicEmoji": "🔍",
|
||||
"wave": 8,
|
||||
@@ -1439,7 +1446,7 @@
|
||||
"Doppelte Tag-Namen werden verhindert",
|
||||
"Massenzuweisung an 500 Dokumente geprüft"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Metadaten",
|
||||
"epicEmoji": "🏷️",
|
||||
"wave": 3,
|
||||
@@ -1475,7 +1482,7 @@
|
||||
"Typänderung eines Feldes mit Bestandsdaten getestet",
|
||||
"Pflichtfeld blockiert unvollständiges Speichern"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Metadaten",
|
||||
"epicEmoji": "🏷️",
|
||||
"wave": 3,
|
||||
@@ -1513,7 +1520,7 @@
|
||||
"Formular per Tastatur vollständig ausfüllbar",
|
||||
"Massenbearbeitung an 200 Dokumenten geprüft"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Metadaten",
|
||||
"epicEmoji": "🏷️",
|
||||
"wave": 4,
|
||||
@@ -1547,7 +1554,7 @@
|
||||
"Pflichtfelder des Typs werden erzwungen",
|
||||
"Vorbelegung im Ordner greift beim Upload"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Metadaten",
|
||||
"epicEmoji": "🏷️",
|
||||
"wave": 4,
|
||||
@@ -1582,7 +1589,7 @@
|
||||
"Widersprüchliche Regeln führen zu definiertem Ergebnis",
|
||||
"Regeländerung wirkt ohne Neustart"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Metadaten",
|
||||
"epicEmoji": "🏷️",
|
||||
"wave": 6,
|
||||
@@ -1618,7 +1625,7 @@
|
||||
"Verwaiste Sperre wird nach Frist automatisch gelöst",
|
||||
"Alte Revision ist unverändert abrufbar"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Versionierung & Audit",
|
||||
"epicEmoji": "🔄",
|
||||
"wave": 4,
|
||||
@@ -1654,7 +1661,7 @@
|
||||
"Ansicht bei 100 Revisionen bleibt übersichtlich",
|
||||
"Berechtigung wird je Revision geprüft"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Versionierung & Audit",
|
||||
"epicEmoji": "🔄",
|
||||
"wave": 5,
|
||||
@@ -1688,7 +1695,7 @@
|
||||
"Vergleich zweier identischer Revisionen liefert leeres Ergebnis",
|
||||
"Laufzeit bei 200-seitigem Dokument gemessen"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Versionierung & Audit",
|
||||
"epicEmoji": "🔄",
|
||||
"wave": 5,
|
||||
@@ -1723,7 +1730,7 @@
|
||||
"Ansicht funktioniert auf schmalem Bildschirm",
|
||||
"Sehr viele Änderungen bremsen die Ansicht nicht aus"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Versionierung & Audit",
|
||||
"epicEmoji": "🔄",
|
||||
"wave": 6,
|
||||
@@ -1757,7 +1764,7 @@
|
||||
"Vollständigkeit gegen Referenzoperationen abgeglichen",
|
||||
"Protokollschreiben verlangsamt Kernoperationen nicht spürbar"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Versionierung & Audit",
|
||||
"epicEmoji": "🔄",
|
||||
"wave": 3,
|
||||
@@ -1792,7 +1799,7 @@
|
||||
"Nicht berechtigter Nutzer erhält keinen Zugriff",
|
||||
"Exportdatei ist in Tabellenkalkulation korrekt lesbar"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Versionierung & Audit",
|
||||
"epicEmoji": "🔄",
|
||||
"wave": 4,
|
||||
@@ -1827,7 +1834,7 @@
|
||||
"Nachträgliche Änderung invalidiert die Signatur nachweislich",
|
||||
"Abgelaufenes Zertifikat wird als solches erkannt"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Versionierung & Audit",
|
||||
"epicEmoji": "🔄",
|
||||
"wave": 5,
|
||||
@@ -1861,7 +1868,7 @@
|
||||
"Berechtigungen greifen identisch wie in der Oberfläche",
|
||||
"Beispielaufrufe aus der Dokumentation funktionieren"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Integration & API",
|
||||
"epicEmoji": "🔌",
|
||||
"wave": 4,
|
||||
@@ -1897,7 +1904,7 @@
|
||||
"Nachricht mit 20 Anhängen korrekt importiert",
|
||||
"Zugangsdaten liegen ausschließlich verschlüsselt vor"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Integration & API",
|
||||
"epicEmoji": "🔌",
|
||||
"wave": 4,
|
||||
@@ -1932,7 +1939,7 @@
|
||||
"Nachricht ohne passende Regel landet im Klärungskorb",
|
||||
"Filter verwirft keine relevanten Anhänge"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Integration & API",
|
||||
"epicEmoji": "🔌",
|
||||
"wave": 7,
|
||||
@@ -1967,7 +1974,7 @@
|
||||
"Stapeltrennung an Referenzstapel geprüft",
|
||||
"Doppelte Einlieferung erzeugt kein Duplikat"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Integration & API",
|
||||
"epicEmoji": "🔌",
|
||||
"wave": 6,
|
||||
@@ -2001,7 +2008,7 @@
|
||||
"Upload und Suche auf Mobilgerät durchgeführt",
|
||||
"Querformat geprüft"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "UX & Zugänglichkeit",
|
||||
"epicEmoji": "📱",
|
||||
"wave": 1,
|
||||
@@ -2033,7 +2040,7 @@
|
||||
"Kein Aufblitzen des falschen Erscheinungsbilds beim Laden",
|
||||
"Diagramme und Vorschauen bleiben lesbar"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "UX & Zugänglichkeit",
|
||||
"epicEmoji": "📱",
|
||||
"wave": 1,
|
||||
@@ -2065,7 +2072,7 @@
|
||||
"Fehlender Schlüssel führt zu sichtbarem Hinweis statt leerem Feld",
|
||||
"Serverseitig gerenderte Seite zeigt die richtige Sprache"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "UX & Zugänglichkeit",
|
||||
"epicEmoji": "📱",
|
||||
"wave": 1,
|
||||
@@ -2099,7 +2106,7 @@
|
||||
"Sichtprüfung auf abgeschnittene Texte in beiden Sprachen",
|
||||
"Fachliche Gegenlesung dokumentiert"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "UX & Zugänglichkeit",
|
||||
"epicEmoji": "📱",
|
||||
"wave": 2,
|
||||
@@ -2134,7 +2141,7 @@
|
||||
"Vollständiger Durchlauf mit Bildschirmleser dokumentiert",
|
||||
"Fokusfalle in Dialogen geprüft"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "UX & Zugänglichkeit",
|
||||
"epicEmoji": "📱",
|
||||
"wave": 2,
|
||||
@@ -2167,7 +2174,7 @@
|
||||
"Referenzkorpus deckt alle unterstützten Formate ab",
|
||||
"Strategie im Team abgenommen"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Prüfungen & Qualitätssicherung",
|
||||
"epicEmoji": "✅",
|
||||
"wave": 3,
|
||||
@@ -2209,7 +2216,7 @@
|
||||
"Ausfall eines Dienstes führt zu sauberem Fehlerbild",
|
||||
"Prüfbericht abgelegt und freigegeben"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Prüfungen & Qualitätssicherung",
|
||||
"epicEmoji": "✅",
|
||||
"wave": 4,
|
||||
@@ -2256,7 +2263,7 @@
|
||||
"Abbruchszenarien in jedem Schritt getestet",
|
||||
"Referenzkorpus vollständig durchlaufen"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Prüfungen & Qualitätssicherung",
|
||||
"epicEmoji": "✅",
|
||||
"wave": 6,
|
||||
@@ -2298,7 +2305,7 @@
|
||||
"Voll-Reindexierung ohne Trefferverlust geprüft",
|
||||
"Berechtigungsfilter in der Suche negativ getestet"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Prüfungen & Qualitätssicherung",
|
||||
"epicEmoji": "✅",
|
||||
"wave": 9,
|
||||
@@ -2339,7 +2346,7 @@
|
||||
"Typwechsel mit Bestandsdaten ohne Verlust",
|
||||
"Validierung auch über die Schnittstelle wirksam"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Prüfungen & Qualitätssicherung",
|
||||
"epicEmoji": "✅",
|
||||
"wave": 7,
|
||||
@@ -2377,7 +2384,7 @@
|
||||
"Prüfung auf Einschleusung, Sitzungsübernahme und unsichere Weiterleitung",
|
||||
"Sicherheitsbericht abgelegt und freigegeben"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Prüfungen & Qualitätssicherung",
|
||||
"epicEmoji": "✅",
|
||||
"wave": 10,
|
||||
@@ -2454,7 +2461,7 @@
|
||||
"Stichprobe von Aktionen im Protokoll wiedergefunden",
|
||||
"Prüfbericht für die Revision erstellt"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Prüfungen & Qualitätssicherung",
|
||||
"epicEmoji": "✅",
|
||||
"wave": 7,
|
||||
@@ -2498,7 +2505,7 @@
|
||||
"Dauerlauf-Import über 24 Stunden ohne Verlust",
|
||||
"Wiederholungsverhalten bei Ausfall belegt"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Prüfungen & Qualitätssicherung",
|
||||
"epicEmoji": "✅",
|
||||
"wave": 8,
|
||||
@@ -2571,7 +2578,7 @@
|
||||
"Vollständiger Ablauf ohne Maus durchgeführt",
|
||||
"Auditbericht abgelegt"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Prüfungen & Qualitätssicherung",
|
||||
"epicEmoji": "✅",
|
||||
"wave": 3,
|
||||
@@ -2679,7 +2686,7 @@
|
||||
"Dokument ohne Akte-Verknüpfung zeigt Bereich nicht/leer an, kein Fehler",
|
||||
"Simulierter Ausfall der Workflow-API blockiert die übrige Dokumentanzeige nicht"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Dokumentenkern",
|
||||
"epicEmoji": "🗂️",
|
||||
"wave": 6,
|
||||
@@ -2711,7 +2718,7 @@
|
||||
"Pipeline-Schritte (Hash, Dedup-Gate, Verschlüsselung) im Test nachweislich durchlaufen",
|
||||
"Absichtlich beschädigte Datei landet im Fehler-Unterordner, blockiert restlichen Ordner nicht"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Integration & API",
|
||||
"epicEmoji": "🔌",
|
||||
"wave": 4,
|
||||
@@ -2744,7 +2751,7 @@
|
||||
"Berechtigungsprüfung im Test über CMIS-Pfad identisch zur REST-API",
|
||||
"Deaktivierung blockiert CMIS-Zugriff vollständig, REST-API bleibt unberührt"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Integration & API",
|
||||
"epicEmoji": "🔌",
|
||||
"wave": 5,
|
||||
@@ -2777,7 +2784,7 @@
|
||||
"Test-Stapel mit Barcode-Trennseiten ordnet Barcode-Werte korrekt zu",
|
||||
"Stapel ohne Trennseiten bleibt ein Dokument"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Integration & API",
|
||||
"epicEmoji": "🔌",
|
||||
"wave": 7,
|
||||
@@ -2810,7 +2817,7 @@
|
||||
"Test: fünfseitiges Dokument an zwei Stellen geteilt, drei korrekte Einzeldokumente entstehen",
|
||||
"Test: Zusammenführen/Aufteilen eines Dokuments mit aktiver Löschsperre wird abgelehnt oder erfordert Freigabe, nicht stillschweigend erlaubt"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Dokumentenkern",
|
||||
"epicEmoji": "🗂️",
|
||||
"wave": 4,
|
||||
@@ -2845,7 +2852,7 @@
|
||||
"Audit-Log zeigt Massenänderung nachvollziehbar",
|
||||
"Test mit einem gesperrten Dokument in der Auswahl: dieses wird übersprungen, Rest wird bearbeitet, klare Rückmeldung welches übersprungen wurde"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Dokumentenkern",
|
||||
"epicEmoji": "🗂️",
|
||||
"wave": 4,
|
||||
@@ -2878,7 +2885,7 @@
|
||||
"Test: gesperrtes Dokument kann nicht gelöscht werden, Ablehnung ist im Audit-Log sichtbar",
|
||||
"Test: Archive-Endpunkt absichtlich nicht erreichbar – Löschung wird verweigert, kein Fallback auf ungeprüfte Löschung"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Integration & API",
|
||||
"epicEmoji": "🔌",
|
||||
"wave": 4,
|
||||
@@ -2944,7 +2951,7 @@
|
||||
"Test: Dokument angelegt – Ereignis kommt nachweislich bei Workflow an",
|
||||
"Test: Workflow-Endpunkt zum Zustellzeitpunkt nicht erreichbar – Dokumentanlage im DMS bleibt trotzdem erfolgreich, Ereignis wird nachgeliefert oder sichtbar verworfen (nicht stillschweigend verloren)"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Integration & API",
|
||||
"epicEmoji": "🔌",
|
||||
"wave": 4,
|
||||
@@ -2976,7 +2983,7 @@
|
||||
"Versuch, ein nicht in der Whitelist enthaltenes Feld anzufragen, wird abgewiesen statt stillschweigend ignoriert",
|
||||
"Code-Review bestätigt: kein dynamischer Spalten-/Tabellenname wird per String-Zusammenbau erzeugt"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Suche & OCR",
|
||||
"epicEmoji": "🔍",
|
||||
"wave": 3,
|
||||
@@ -3041,7 +3048,7 @@
|
||||
"Test: Import aus einem nicht zugeordneten/fehlkonfigurierten Verzeichnis wird abgelehnt und protokolliert",
|
||||
"Prüft Dateisystemrechte des Verzeichnisses gegen die Betriebsanleitung"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Integration & API",
|
||||
"epicEmoji": "🔌",
|
||||
"wave": 12,
|
||||
@@ -3071,7 +3078,7 @@
|
||||
"Test: abgelaufenes/widerrufenes Token wird von CMIS genauso abgelehnt wie von der REST-API (Kopplung an Core IAM-17)",
|
||||
"Code-Review-Gate: CMIS-Handler dürfen keine eigene Auth-Logik enthalten, nur die gemeinsame Middleware referenzieren"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Integration & API",
|
||||
"epicEmoji": "🔌",
|
||||
"wave": 12,
|
||||
@@ -3103,7 +3110,7 @@
|
||||
"Test: Rückkanal-Aufruf mit manipuliertem Tenant-Kontext (fremder Tenant) wird abgelehnt",
|
||||
"Integrationstest über DOC-13 → Workflow VOR-04 mit zwei verschiedenen Tenants, prüft Isolation"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Integration & API",
|
||||
"epicEmoji": "🔌",
|
||||
"wave": 12,
|
||||
@@ -3133,7 +3140,7 @@
|
||||
"Test mit sauberer Datei: durchläuft Scan und wird normal verfügbar",
|
||||
"Lasttest: Scan-Queue verarbeitet mehrere gleichzeitige Uploads ohne Verlust der Reihenfolge/Nachvollziehbarkeit"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Dokumentenkern",
|
||||
"epicEmoji": "🗂️",
|
||||
"wave": 12,
|
||||
@@ -3163,7 +3170,7 @@
|
||||
"Test: abgelaufene URL wird abgelehnt",
|
||||
"Test: URL für ein zwischenzeitlich gelöschtes Objekt wird abgelehnt"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Fundament",
|
||||
"epicEmoji": "⚙️",
|
||||
"wave": 12,
|
||||
@@ -3193,7 +3200,7 @@
|
||||
"Lasttest: ein überschreitender Job blockiert nicht die Verarbeitung paralleler, regulärer Jobs",
|
||||
"Test der Nutzerbenachrichtigung bei abgebrochenem Job"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Fundament",
|
||||
"epicEmoji": "⚙️",
|
||||
"wave": 12,
|
||||
@@ -3223,7 +3230,7 @@
|
||||
"Prüft, dass der Ablehnungsversuch selbst sichtbar protokolliert wird",
|
||||
"Regressionstest: Verkettungsprüfung (Unversehrtheitsnachweis) funktioniert nach der Rechteänderung weiterhin"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Versionierung & Audit",
|
||||
"epicEmoji": "🔄",
|
||||
"wave": 12,
|
||||
@@ -3253,12 +3260,214 @@
|
||||
"Test: Anfrage innerhalb der Obergrenze wird normal verarbeitet",
|
||||
"Regressionstest bestehender DOC-08-Funktionalität nach Einführung der Prüfung"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"status": "Fertig",
|
||||
"epicName": "Dokumentenkern",
|
||||
"epicEmoji": "🗂️",
|
||||
"wave": 13,
|
||||
"unlocks": [],
|
||||
"prompt": "# DOC-18 – Obergrenze für Gesamtgröße/Anzahl bei Archiv-Bündelung\n\n**Epic:** 🗂️ Dokumentenkern | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 1 Personentage | **Welle:** 13\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH DMS (Dokumentenkern, Suche & OCR, Metadaten, Versionierung, Integration/API), das sich an paperless-ngx, Alfresco, Docspell und ecoDMS orientiert und bekannte Fehler aus archivdms (siehe known-issues-archivdms.md) bewusst vermeidet.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nDOC-08 bündelt mehrere ausgewählte Dokumente als Hintergrund-Job zu einem Archiv, ohne Obergrenze für Gesamtgröße oder Anzahl der Dokumente je Anfrage. Eine übermäßig große Auswahl kann sonst den Bündelungs-Job unverhältnismäßig lange laufen lassen und Ressourcen auf Kosten anderer Mandanten binden. Harte, konfigurierbare Obergrenze für maximale Gesamtgröße und maximale Dokumentanzahl je Bündelungs-Anfrage einführen – bei Überschreitung wird die Anfrage mit klarer Fehlermeldung abgelehnt, bevor der Job gestartet wird.\n\n**Technische Grundlage:** Postgres-Jobqueue, Ressourcenlimits, Go\n\n## Produkt-DNA für diesen Bereich\n**Übernehmen:**\n- Docspell: klare Verarbeitungsgrenzen statt unbegrenzter Best-Effort-Verarbeitung.\n\n**Bewusst vermeiden:**\n- archivdms (bekannte Fehlerklasse ähnlich) – Ressourcenerschöpfung durch unbegrenzte Einzeljobs war in Altsystemen eine wiederkehrende Betriebsstörung.: harte, konfigurierbare Obergrenzen von Anfang an statt nachträglicher Begrenzung nach Vorfall.\n\n## Ausgangslage\nSetzt auf folgenden bereits fertigen Kacheln auf: DOC-08.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Eine Bündelungs-Anfrage mit konfigurierbar zu großer Gesamtgröße oder Dokumentanzahl wird vor Jobstart abgelehnt, mit klarer Fehlermeldung an den Nutzer\n2. Innerhalb der Obergrenze funktioniert die Bündelung aus DOC-08 unverändert\n3. Die Obergrenzen sind konfigurierbar, nicht hart im Code verankert\n\n## Prüfungen vor der Abnahme\nFühre jede Prüfung tatsächlich durch und halte das Ergebnis schriftlich fest. Nicht durchgeführte Prüfungen zählen als offen:\n1. Test: Anfrage mit Auswahl oberhalb der konfigurierten Obergrenze wird abgelehnt, kein Job wird gestartet\n2. Test: Anfrage innerhalb der Obergrenze wird normal verarbeitet\n3. Regressionstest bestehender DOC-08-Funktionalität nach Einführung der Prüfung\n\n## Bekannte Fehler vermeiden\n\nThreat-Model-Finding (DMS-Board, 2026-09-12, Finding #9): unbegrenzte Bündelungs-Anfragen sind ein kleiner, aber realer Denial-of-Service-Vektor gegen den gemeinsamen Job-Worker-Pool.\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `DOC-08` Massenexport als ZIP\n\n## Arbeitsweise\n1. Lies zuerst den bestehenden Code der Vorbedingungen und halte dich an die dort etablierten Muster.\n2. Setze die kleinste Lösung um, die alle Akzeptanzkriterien erfüllt. Kein Umbau angrenzender Bereiche.\n3. Schreibe zu jedem Akzeptanzkriterium mindestens einen automatisierten Test.\n4. Führe alle Prüfungen aus und dokumentiere Zielwert und Ergebnis.\n5. Deutschsprachige Oberflächentexte, englischsprachige Bezeichner im Code.\n6. Keine Zugangsdaten, Schlüssel oder Verbindungszeichenfolgen im Code – ausschließlich über Umgebungsvariablen.\n\n## Abschluss\n- Commit-Nachricht: `DOC-18: obergrenze-f-r-gesamtgr-e-anzahl-bei-archiv-b-ndelung`\n- Branch: `feature/doc-18-obergrenze-f-r-gesamtgr-e-anzahl-bei-archiv-b-ndelung`\n- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy.\n- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten.\n"
|
||||
},
|
||||
{
|
||||
"code": "SEC-01",
|
||||
"title": "Unauthentifizierter Vernichtungs-Rückruf löscht Dokumente physisch",
|
||||
"epic": "SEC",
|
||||
"featureIds": [],
|
||||
"role": "Backend",
|
||||
"complexity": "Komplex",
|
||||
"estimateDays": 3,
|
||||
"tech": "Service-Token-Pflicht, Legal-Hold-Check, Body-Limit",
|
||||
"description": "Der Vernichtungs-Rückruf des Retention-Dienstes ist im Standardbetrieb fail-open: ohne Bearer-Token werden Dokumente physisch gelöscht, Legal Hold wird nicht geprüft, der Audit-Akteur wird falsch protokolliert.",
|
||||
"dependsOn": [],
|
||||
"akzeptanz": [
|
||||
"RequireServiceToken serverseitig fest auf true erzwungen",
|
||||
"Aufruf ohne gültiges Bearer-Token wird mit 401/403 abgelehnt",
|
||||
"Legal-Hold-Status wird vor physischer Löschung geprüft",
|
||||
"Request-Body ist auf eine feste Obergrenze begrenzt",
|
||||
"Audit-Eintrag protokolliert den tatsächlichen Service-Akteur"
|
||||
],
|
||||
"pruefungen": [
|
||||
"Angriffsnachstellung ohne Bearer-Token: vor Fix löschend, nach Fix abgelehnt",
|
||||
"Aufruf gegen Objekt mit aktivem Legal Hold wird abgelehnt",
|
||||
"Request-Body oberhalb der Obergrenze wird abgelehnt",
|
||||
"Audit-Log nach legitimem Aufruf enthält korrekten Service-Akteur"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"epicName": "Sicherheit",
|
||||
"epicEmoji": "🔒",
|
||||
"wave": 13,
|
||||
"unlocks": [],
|
||||
"prompt": "# SEC-01 – Unauthentifizierter Vernichtungs-Rückruf löscht Dokumente physisch\n\n**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Komplex | **Aufwand:** 3 Personentage | **Welle:** 13\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH DMS (Dokumentenkern, Suche & OCR, Metadaten, Versionierung, Integration/API), das sich an paperless-ngx, Alfresco, Docspell und ecoDMS orientiert und bekannte Fehler aus archivdms (siehe known-issues-archivdms.md) bewusst vermeidet.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nSecurity-Review (main, Fable 5.1) hat einen Befund mit hohem Schweregrad gefunden: `dms/internal/retentiondestroy/retentiondestroy.go:117-131` liefert `\"\",0,\"\",\"\"` zurück statt den Aufruf abzulehnen, wenn `!RequireServiceToken` und kein Verifier konfiguriert oder kein Bearer-Token mitgesendet wurde. `dms/cmd/app/api.go:320-329` setzt `RequireServiceToken: Getenv(...) == \"true\"` — der Standardwert ist `false`, die Route ist damit im Standardbetrieb fail-open und laut OpenAPI-Doku zusätzlich mit `security: []` markiert. Einzige verbleibende Hürde ist der Header `X-Nexarch-Tenant`, der nur gegen die Instanz-Slug geprüft wird; dieser Slug ist aber z. B. im öffentlichen CMIS-`repositoryId` sichtbar (`cmis/handler.go:150`). Ein Aufruf mit `{\"object_type\":\"dms_document\",\"object_reference\":\"<uuid>\",...}` löst `storageSvc.Delete` aller Revisionen plus `deleted_at`-Setzung aus (Zeile 205-212) — ohne Legal-Hold-Prüfung, mit Audit-Akteur fälschlich protokolliert als \"archive-retention\". Zusätzlich liest `json.NewDecoder(r.Body)` ohne Größenlimit auf einem Streaming-Server.\n\n**Technische Grundlage:** `internal/retentiondestroy/retentiondestroy.go`, `cmd/app/api.go` (Service-Token-Konfiguration), `internal/audittrail` (Akteursfeld), bestehende Legal-Hold-Prüfung aus dem Papierkorb-/Löschpfad\n\n## Produkt-DNA für diesen Bereich\n**Übernehmen:**\n- Alfresco: Vernichtung nach Aufbewahrungsfrist ist ein geschützter, auditierbarer Verwaltungsvorgang, kein offener Endpunkt.\n\n**Bewusst vermeiden:**\n- Fail-open-Sicherheitslogik: ein nicht gesetztes Konfigurationsflag darf niemals eine Schutzfunktion abschalten.\n- Falsch zugeordnete Audit-Akteure, die einen Angriff als reguläre Systemaktion tarnen.\n\n## Ausgangslage\n`RequireServiceToken` ist aktuell optional und standardmäßig `false` (`cmd/app/api.go:320-329`). Der Legal-Hold-Check existiert bereits im regulären Löschpfad, wird im Vernichtungs-Rückruf aber nicht aufgerufen.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. `RequireServiceToken` ist serverseitig fest auf `true` erzwungen (kein Umgebungsschalter kann den Bearer-Token-Zwang mehr abschalten)\n2. Ein Aufruf ohne gültiges, konfiguriertes Bearer-Token wird mit `401`/`403` abgelehnt, unabhängig von `X-Nexarch-Tenant`\n3. Vor physischer Löschung wird der Legal-Hold-Status des Objekts geprüft; bei aktivem Legal Hold wird die Vernichtung abgelehnt und protokolliert\n4. Der Request-Body ist auf eine feste Obergrenze begrenzt (z. B. per `http.MaxBytesReader`), überlange Anfragen werden mit Fehler abgelehnt statt unbegrenzt gepuffert\n5. Der Audit-Eintrag für eine über diesen Endpunkt ausgelöste Löschung protokolliert den tatsächlichen Aufrufkontext (Service-Identität des Tokens), nicht pauschal \"archive-retention\"\n\n## Prüfungen vor der Abnahme\nFühre jede Prüfung tatsächlich durch und halte das Ergebnis schriftlich fest. Nicht durchgeführte Prüfungen zählen als offen:\n1. Angriffsnachstellung: Aufruf des Endpunkts ohne Bearer-Token, nur mit öffentlich bekanntem `X-Nexarch-Tenant`-Wert und gültiger Dokument-Referenz — vor dem Fix erfolgreich löschend, nach dem Fix mit `401`/`403` abgelehnt (beide Ergebnisse dokumentieren)\n2. Aufruf mit gültigem Token gegen ein Objekt mit aktivem Legal Hold — Vernichtung wird abgelehnt\n3. Aufruf mit Request-Body oberhalb der konfigurierten Obergrenze — wird mit Fehler abgelehnt, kein unbegrenzter RAM-Verbrauch\n4. Audit-Log nach einem erfolgreichen, legitimen Vernichtungsaufruf enthält den korrekten Service-Akteur\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `SEC-06` TENANT_SLUG-Pflicht beim Dienststart (verwandter, aber eigenständiger Befund im Modul-Verifier)\n- Generelles Rate-Limiting auf Service-Endpunkten\n\n## Arbeitsweise\n1. Lies zuerst den bestehenden Code der Vorbedingungen und halte dich an die dort etablierten Muster.\n2. Setze die kleinste Lösung um, die alle Akzeptanzkriterien erfüllt. Kein Umbau angrenzender Bereiche.\n3. Schreibe zu jedem Akzeptanzkriterium mindestens einen automatisierten Test.\n4. Führe alle Prüfungen aus und dokumentiere Zielwert und Ergebnis.\n5. Deutschsprachige OberfLine truncated
|
||||
},
|
||||
{
|
||||
"code": "SEC-02",
|
||||
"title": "Mail-Postfachverwaltung ohne Rollenprüfung ermöglicht Credential-Exfiltration",
|
||||
"epic": "SEC",
|
||||
"featureIds": [],
|
||||
"role": "Backend",
|
||||
"complexity": "Komplex",
|
||||
"estimateDays": 3,
|
||||
"tech": "Rollenprüfung Admin-only, Passwortbindung bei Host-Änderung",
|
||||
"description": "Die Mail-Postfachverwaltung erlaubt jeder authentifizierten Identität Host/Port-Änderungen ohne Passwortbestätigung, wodurch gespeicherte IMAP-Zugangsdaten an einen angreifereigenen Server exfiltriert werden können; ImportUserID ist zusätzlich frei wählbar.",
|
||||
"dependsOn": [],
|
||||
"akzeptanz": [
|
||||
"needsGuard für mail-accounts auf true gesetzt, nur Admin-Rolle",
|
||||
"Host/Port-Änderung verlangt erneute Passworteingabe",
|
||||
"ImportUserID wird serverseitig auf den authentifizierten Actor fixiert",
|
||||
"Automatisierter Test belegt Ablehnung von Host-Änderung ohne Passwort"
|
||||
],
|
||||
"pruefungen": [
|
||||
"Angriffsnachstellung: Host-Änderung mit leerem Passwort auf fremden IMAP-Server, vor/nach Fix dokumentiert",
|
||||
"Angriffsnachstellung: Import mit fremdem ImportUserID, vor/nach Fix dokumentiert",
|
||||
"Regressionstest: legitime Host-Änderung mit Passwort funktioniert weiterhin"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"epicName": "Sicherheit",
|
||||
"epicEmoji": "🔒",
|
||||
"wave": 13,
|
||||
"unlocks": [],
|
||||
"prompt": "# SEC-02 – Mail-Postfachverwaltung ohne Rollenprüfung ermöglicht Credential-Exfiltration\n\n**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Komplex | **Aufwand:** 3 Personentage | **Welle:** 13\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH DMS (Dokumentenkern, Suche & OCR, Metadaten, Versionierung, Integration/API), das sich an paperless-ngx, Alfresco, Docspell und ecoDMS orientiert und bekannte Fehler aus archivdms (siehe known-issues-archivdms.md) bewusst vermeidet.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nSecurity-Review (main, Fable 5.1) hat einen Befund mit hohem Schweregrad gefunden: `dms/internal/mailimportapi/handler.go:61-75` (`requireActor`) akzeptiert jede authentifizierte Identität für die Mail-Postfachverwaltung, ohne Rollenprüfung. `dms/internal/authz/authz.go:149-170` setzt `needsGuard` für `mail-accounts` auf `false`. `dms/internal/mailimport/manage.go:80-93` erlaubt bei einem Update mit leerem Passwort, dass `password_ciphertext` erhalten bleibt, während `host`/`port` geändert werden — der Worker (`importer.go:83-87`, `imap.go:69`) sendet dann `LOGIN user password` an einen vom Angreifer kontrollierten IMAP-Server und exfiltriert damit das gespeicherte Postfach-Passwort im Klartext. Zusätzlich ist `ImportUserID` in `handler.go:148-152,175-179` frei wählbar — importierte Dokumente bekommen dadurch einen beliebigen `created_by`, von dem die Eigentümer-RBAC abhängt. `POLICY_URL` ist im Standardbetrieb nicht gesetzt, Policy-Enforcement also optional.\n\n**Technische Grundlage:** `internal/mailimportapi/handler.go`, `internal/authz/authz.go`, `internal/mailimport/manage.go`, `internal/mailimport/importer.go`, `internal/mailimport/imap.go`\n\n## Produkt-DNA für diesen Bereich\n**Übernehmen:**\n- Docspell: Mail-Import als vertrauenswürdige, klar abgegrenzte Admin-Funktion, nicht als allgemein zugänglicher Endpunkt.\n\n**Bewusst vermeiden:**\n- Implizite Rechteausweitung über \"irgendwie authentifiziert reicht\".\n- Konfigurationsänderungen, die ein gespeichertes Secret an ein neues, unverifiziertes Ziel senden, ohne erneute Bestätigung.\n\n## Ausgangslage\nMail-Postfachverwaltung läuft aktuell ohne Admin-Beschränkung und ohne Bindung von Host/Port-Änderung an eine erneute Passwortbestätigung.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. `needsGuard` ist für `mail-accounts` auf `true` gesetzt; nur Rollen mit Admin-Berechtigung für Postfachverwaltung können Postfächer anlegen/ändern/löschen\n2. Eine Änderung von `host` oder `port` an einem bestehenden Postfach verlangt zwingend eine erneute Passworteingabe (kein Update von Host/Port bei leer gelassenem Passwortfeld unter Beibehaltung des alten `password_ciphertext`)\n3. `ImportUserID` wird beim Import serverseitig auf den tatsächlich authentifizierten Actor fixiert und ist nicht mehr frei im Request wählbar\n4. Automatisierter Test belegt: Request mit geänderter `host`/leerem Passwort auf bestehendes Postfach wird abgelehnt\n\n## Prüfungen vor der Abnahme\nFühre jede Prüfung tatsächlich durch und halte das Ergebnis schriftlich fest. Nicht durchgeführte Prüfungen zählen als offen:\n1. Angriffsnachstellung: authentifizierter, nicht-administrativer Nutzer ändert `host` eines fremden Postfachs auf einen selbst kontrollierten IMAP-Server mit leerem Passwortfeld — vor dem Fix erfolgreich (Gegenstelle empfängt `LOGIN` mit Klartext-Passwort, per Testserver nachweisen), nach dem Fix mit `403` abgelehnt (beide Ergebnisse dokumentieren)\n2. Angriffsnachstellung: Import-Aufruf mit fremdem `ImportUserID` — vor dem Fix wird das importierte Dokument dem fremden Nutzer zugeordnet, nach dem Fix dem tatsächlichen Actor\n3. Regressionstest: legitime Host-Änderung mit korrekt mitgesendetem Passwort funktioniert weiterhin\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `SEC-03` generelle Guard-Lücken bei anderen Routen\n- Verpflichtendes `POLICY_URL`-Enforcement systemweit (eigenständiger, größerer Befund)\n\n## Arbeitsweise\n1. Lies zuerst den bestehenden Code der Vorbedingungen und halte dich an die dort etablierten Muster.\n2. Setze die kleinste Lösung um, die alle Akzeptanzkriterien erfüllt. Kein Umbau angrenzender Bereiche.\n3. Schreibe zu jedem Akzeptanzkriterium mindestens einen automatisierten Test.\n4. Führe alle Prüfungen aus und dokumentiere Zielwert und Ergebnis.\n5. Deutschsprachige Oberflächentexte, englischsprachige Bezeichner im Code.\n6. Keine Zugangsdaten, Schlüssel oder Verbindungszeichenfolgen im Code – ausschließlich über Umgebungsvariablen.\n\n## Abschluss\n- Commit-Nachricht: `SEC-02: mail-postfachverwaltung-rollenpruefung`\n- Branch: `feature/sec-02-mail-postfachverwaltung-rollLine truncated
|
||||
},
|
||||
{
|
||||
"code": "SEC-03",
|
||||
"title": "Guard-Lücken: Papierkorb/Ordnerbaum/Trigger-Webhooks ohne Zugriffsprüfung",
|
||||
"epic": "SEC",
|
||||
"featureIds": [],
|
||||
"role": "Backend",
|
||||
"complexity": "Mittel",
|
||||
"estimateDays": 2,
|
||||
"tech": "needsGuard-Korrektur, eigentümerbezogene Filterung",
|
||||
"description": "GET /trash, /folders und /triggers liefern mandanten-/nutzerübergreifend Daten aus, da needsGuard für diese Routen auf false steht.",
|
||||
"dependsOn": [],
|
||||
"akzeptanz": [
|
||||
"needsGuard für GET /folders/*, /trash, /triggers auf true",
|
||||
"GET /trash liefert nur eigene Papierkorb-Einträge",
|
||||
"folderapi liefert nur sichtbaren Teilbaum",
|
||||
"triggerapi liefert webhook_url nur bei Berechtigung"
|
||||
],
|
||||
"pruefungen": [
|
||||
"Angriffsnachstellung GET /trash fremder Nutzer, vor/nach Fix dokumentiert",
|
||||
"Gleiche Nachstellung für /folders und /triggers",
|
||||
"Regressionstest: eigene Daten weiterhin vollständig sichtbar"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"epicName": "Sicherheit",
|
||||
"epicEmoji": "🔒",
|
||||
"wave": 13,
|
||||
"unlocks": [],
|
||||
"prompt": "# SEC-03 – Guard-Lücken: Papierkorb/Ordnerbaum/Trigger-Webhooks ohne Zugriffsprüfung\n\n**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 13\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH DMS (Dokumentenkern, Suche & OCR, Metadaten, Versionierung, Integration/API), das sich an paperless-ngx, Alfresco, Docspell und ecoDMS orientiert und bekannte Fehler aus archivdms (siehe known-issues-archivdms.md) bewusst vermeidet.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nSecurity-Review (main, Fable 5.1) hat einen Befund mit mittlerem Schweregrad gefunden: `dms/internal/authz/authz.go:149-170` setzt `needsGuard` auf `false` für `GET /folders/*`, `GET /trash` und `GET /triggers`. Konkret liefert `GET /trash` (`trashapi/handler.go:88-107`) den Papierkorb aller Nutzer ungefiltert, `folderapi/handler.go:84-87` liefert den gesamten Ordnerbaum, und `triggerapi/handler.go:114-126` liefert `webhook_url` aller Trigger aus — alle drei ohne Policy-URL-Prüfung erreichbar, sobald die Identität nur authentifiziert ist.\n\n**Technische Grundlage:** `internal/authz/authz.go`, `internal/trashapi/handler.go`, `internal/folderapi/handler.go`, `internal/triggerapi/handler.go`\n\n## Produkt-DNA für diesen Bereich\n**Übernehmen:**\n- Alfresco: jede Lese-Route ist eigentümer-/mandantenbezogen gefiltert, nie ein globaler Dump.\n\n**Bewusst vermeiden:**\n- \"Nur GET, also unkritisch\" als Begründung für fehlende Zugriffsprüfung — Lesezugriffe auf fremde Daten sind ein Datenschutzvorfall.\n\n## Ausgangslage\n`needsGuard` ist für die drei genannten Routen aktuell `false`; die Handler selbst filtern nicht nach Eigentümer oder Mandant.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. `needsGuard` ist für `GET /folders/*`, `GET /trash` und `GET /triggers` auf `true` gesetzt\n2. `GET /trash` liefert ausschließlich Papierkorb-Einträge des aufrufenden Nutzers bzw. seines Mandanten, nicht aller Nutzer\n3. `folderapi` liefert nur den für den aufrufenden Nutzer sichtbaren Teilbaum\n4. `triggerapi` liefert `webhook_url` nur an Nutzer mit entsprechender Berechtigung auf den jeweiligen Trigger\n\n## Prüfungen vor der Abnahme\nFühre jede Prüfung tatsächlich durch und halte das Ergebnis schriftlich fest. Nicht durchgeführte Prüfungen zählen als offen:\n1. Angriffsnachstellung: Aufruf von `GET /trash` durch Nutzer A mit Papierkorb-Einträgen von Nutzer B — vor dem Fix sichtbar, nach dem Fix nicht mehr sichtbar (beide Ergebnisse dokumentieren)\n2. Gleiche Nachstellung für `GET /folders` (fremder Ordnerbaum) und `GET /triggers` (fremde `webhook_url`)\n3. Regressionstest: legitimer Nutzer sieht weiterhin seine eigenen Papierkorb-/Ordner-/Trigger-Daten vollständig\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `SEC-02` Rollenprüfung Mail-Postfachverwaltung (eigenständiger Befund, andere Route)\n- Systemweites `POLICY_URL`-Pflicht-Enforcement\n\n## Arbeitsweise\n1. Lies zuerst den bestehenden Code der Vorbedingungen und halte dich an die dort etablierten Muster.\n2. Setze die kleinste Lösung um, die alle Akzeptanzkriterien erfüllt. Kein Umbau angrenzender Bereiche.\n3. Schreibe zu jedem Akzeptanzkriterium mindestens einen automatisierten Test.\n4. Führe alle Prüfungen aus und dokumentiere Zielwert und Ergebnis.\n5. Deutschsprachige Oberflächentexte, englischsprachige Bezeichner im Code.\n6. Keine Zugangsdaten, Schlüssel oder Verbindungszeichenfolgen im Code – ausschließlich über Umgebungsvariablen.\n\n## Abschluss\n- Commit-Nachricht: `SEC-03: guard-luecken-trash-folders-triggers`\n- Branch: `feature/sec-03-guard-luecken-trash-folders-triggers`\n- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy.\n- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten.\n"
|
||||
},
|
||||
{
|
||||
"code": "SEC-04",
|
||||
"title": "Virenscan standardmäßig nicht in die Verarbeitungs-Pipeline eingereiht",
|
||||
"epic": "SEC",
|
||||
"featureIds": [],
|
||||
"role": "Backend",
|
||||
"complexity": "Mittel",
|
||||
"estimateDays": 2,
|
||||
"tech": "enqueueTypes-Default, Sichtbarkeitsfilter umkehren",
|
||||
"description": "malwarescan.scan ist nicht in enqueueTypes enthalten; Dokumente ohne jemals ausgeführten Scan sind sofort sichtbar, da nur explizit unclean markierte Dokumente ausgeblendet werden.",
|
||||
"dependsOn": [],
|
||||
"akzeptanz": [
|
||||
"malwarescan.scan standardmäßig in enqueueTypes",
|
||||
"Sichtbarkeit nur bei explizitem status = clean",
|
||||
"Bestehende ungescannte Dokumente werden per Nachlauf erfasst"
|
||||
],
|
||||
"pruefungen": [
|
||||
"Angriffsnachstellung: Upload bei deaktiviertem Scan-Worker, vor/nach Fix dokumentiert",
|
||||
"Regressionstest: clean-Dokument bleibt sichtbar",
|
||||
"Regressionstest: unclean-Dokument bleibt gesperrt"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"epicName": "Sicherheit",
|
||||
"epicEmoji": "🔒",
|
||||
"wave": 13,
|
||||
"unlocks": [],
|
||||
"prompt": "# SEC-04 – Virenscan standardmäßig nicht in die Verarbeitungs-Pipeline eingereiht\n\n**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 13\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH DMS (Dokumentenkern, Suche & OCR, Metadaten, Versionierung, Integration/API), das sich an paperless-ngx, Alfresco, Docspell und ecoDMS orientiert und bekannte Fehler aus archivdms (siehe known-issues-archivdms.md) bewusst vermeidet.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nSecurity-Review (main, Fable 5.1) hat einen Befund mit mittlerem Schweregrad gefunden: `dms/cmd/app/api.go:72-83` enthält `malwarescan.scan` nicht standardmäßig in `enqueueTypes`. Die Sichtbarkeitsfilter (`documentapi/handler.go:64`, `downloadapi.go:73`) blenden nur Dokumente mit `status <> 'clean'` aus — ein Dokument, für das nie eine Scan-Zeile erzeugt wurde, hat keinen solchen Status und ist damit sofort sichtbar und herunterladbar, obwohl es nie gescannt wurde.\n\n**Technische Grundlage:** `cmd/app/api.go` (`enqueueTypes`), `internal/documentapi/handler.go`, `internal/downloadapi.go`, `internal/malwarescan`\n\n## Produkt-DNA für diesen Bereich\n**Übernehmen:**\n- ecoDMS/Alfresco: Malware-Scan ist Teil der Standard-Pipeline, kein optionales Add-on, das man manuell aktivieren muss.\n\n**Bewusst vermeiden:**\n- Sichtbarkeitslogik nach dem Muster \"alles außer explizit als schädlich markiert\" — das macht ein fehlender Scan-Lauf zur versehentlichen Freigabe statt zur Sperre.\n\n## Ausgangslage\n`enqueueTypes` in `cmd/app/api.go:72-83` listet die beim Start registrierten Hintergrundaufgaben; `malwarescan.scan` fehlt dort im Standardbetrieb.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. `malwarescan.scan` ist standardmäßig in `enqueueTypes` enthalten und wird für jeden Upload automatisch eingereiht\n2. Die Sichtbarkeitslogik ist umgekehrt: ein Dokument ist nur sichtbar/herunterladbar, wenn explizit `status = 'clean'` gesetzt ist; ein Dokument ohne Scan-Ergebnis gilt als nicht freigegeben\n3. Bestehende Dokumente ohne Scan-Ergebnis werden durch eine Migration/Nachlauf-Aufgabe erfasst, statt dauerhaft unsichtbar oder dauerhaft sichtbar zu bleiben\n\n## Prüfungen vor der Abnahme\nFühre jede Prüfung tatsächlich durch und halte das Ergebnis schriftlich fest. Nicht durchgeführte Prüfungen zählen als offen:\n1. Angriffsnachstellung: Upload eines Dokuments bei deaktiviertem/verzögertem Scan-Worker — vor dem Fix sofort sichtbar und herunterladbar ohne Scan-Ergebnis, nach dem Fix gesperrt bis `status = 'clean'` vorliegt (beide Ergebnisse dokumentieren)\n2. Regressionstest: ein tatsächlich als `clean` markiertes Dokument bleibt sichtbar und herunterladbar\n3. Regressionstest: ein als `infected`/unclean markiertes Dokument bleibt gesperrt\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `SEC-05` Upload-Limit und MIME-Sniffing (eigenständiger, verwandter Befund im Upload-Pfad)\n- Auswahl/Betrieb der eingesetzten Scan-Engine (bereits in `internal/malwarescan` vorhanden)\n\n## Arbeitsweise\n1. Lies zuerst den bestehenden Code der Vorbedingungen und halte dich an die dort etablierten Muster.\n2. Setze die kleinste Lösung um, die alle Akzeptanzkriterien erfüllt. Kein Umbau angrenzender Bereiche.\n3. Schreibe zu jedem Akzeptanzkriterium mindestens einen automatisierten Test.\n4. Führe alle Prüfungen aus und dokumentiere Zielwert und Ergebnis.\n5. Deutschsprachige Oberflächentexte, englischsprachige Bezeichner im Code.\n6. Keine Zugangsdaten, Schlüssel oder Verbindungszeichenfolgen im Code – ausschließlich über Umgebungsvariablen.\n\n## Abschluss\n- Commit-Nachricht: `SEC-04: virenscan-standardmaessig-eingereiht`\n- Branch: `feature/sec-04-virenscan-standardmaessig-eingereiht`\n- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy.\n- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten.\n"
|
||||
},
|
||||
{
|
||||
"code": "SEC-05",
|
||||
"title": "Upload-Limit standardmäßig unbegrenzt, Client-MIME ungeprüft, authentifizierter OOM",
|
||||
"epic": "SEC",
|
||||
"featureIds": [],
|
||||
"role": "Backend",
|
||||
"complexity": "Mittel",
|
||||
"estimateDays": 3,
|
||||
"tech": "Upload-Limit-Default, Server-MIME-Sniffing, Streaming-Verschlüsselung",
|
||||
"description": "Upload-Limit 0 gilt als unbegrenzt, MIME-Typ wird vom Client übernommen, und die Verschlüsselung liest die komplette Datei ins RAM — ein authentifizierter Nutzer kann per großem Upload einen RAM-OOM auslösen.",
|
||||
"dependsOn": [],
|
||||
"akzeptanz": [
|
||||
"Standard-Upload-Limit ist fester Wert > 0",
|
||||
"MIME-Typ wird serverseitig gesnifft und abgeglichen",
|
||||
"Verschlüsselungspfad verarbeitet den Stream statt vollständigem RAM-Puffer",
|
||||
"Request-Body ist hart begrenzt"
|
||||
],
|
||||
"pruefungen": [
|
||||
"Angriffsnachstellung: großer Upload, RAM-Verbrauch vor/nach Fix gemessen und dokumentiert",
|
||||
"Angriffsnachstellung: falsch deklarierter Content-Type wird per Sniffing erkannt",
|
||||
"Regressionstest: reguläre Uploads funktionieren weiterhin"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"epicName": "Sicherheit",
|
||||
"epicEmoji": "🔒",
|
||||
"wave": 13,
|
||||
"unlocks": [],
|
||||
"prompt": "# SEC-05 – Upload-Limit standardmäßig unbegrenzt, Client-MIME ungeprüft, authentifizierter OOM\n\n**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 13\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH DMS (Dokumentenkern, Suche & OCR, Metadaten, Versionierung, Integration/API), das sich an paperless-ngx, Alfresco, Docspell und ecoDMS orientiert und bekannte Fehler aus archivdms (siehe known-issues-archivdms.md) bewusst vermeidet.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nSecurity-Review (main, Fable 5.1) hat einen Befund mit mittlerem Schweregrad gefunden: `dms/internal/upload/validate.go:42-71` behandelt ein konfiguriertes Limit von `0` als \"unbegrenzt\" — das ist der Standardwert in `cmd/app/api.go:62-71`. Der MIME-Typ wird dabei vom Client übernommen statt serverseitig gesnifft. `upload/service.go:244` ruft über `crypto/envelope.go:116` `io.ReadAll` auf und liest die gesamte Datei ins RAM; der Streaming-Server hat kein Body-Limit, wodurch ein authentifizierter Nutzer per großem Upload einen Denial-of-Service durch RAM-Erschöpfung auslösen kann. `versioningapi/handler.go:166-170` liefert außerdem die vom Client angegebene MIME-Art `inline` aus, ohne eigenes Sniffing (CSP mildert dies etwas ab, ersetzt aber keine serverseitige Prüfung).\n\n**Technische Grundlage:** `internal/upload/validate.go`, `cmd/app/api.go` (Upload-Limit-Konfiguration), `internal/upload/service.go`, `internal/crypto/envelope.go`, `internal/versioningapi/handler.go`\n\n## Produkt-DNA für diesen Bereich\n**Übernehmen:**\n- paperless-ngx: Upload-Größenlimit und Typprüfung sind Standardverhalten, nicht optional nachzurüsten.\n\n**Bewusst vermeiden:**\n- \"0 bedeutet unbegrenzt\" als Default für ein Sicherheitslimit.\n- Vertrauen auf vom Client gelieferte Metadaten (MIME-Typ) für sicherheitsrelevante Entscheidungen.\n\n## Ausgangslage\nUpload-Limit ist aktuell per Default `0` (unbegrenzt), MIME-Erkennung erfolgt nicht serverseitig, Verschlüsselung liest die komplette Datei ins RAM.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Das Standard-Upload-Limit ist ein konkreter, sinnvoller Wert größer `0` (kein Umgebungsschalter kann es implizit auf \"unbegrenzt\" zurücksetzen)\n2. Der MIME-Typ wird serverseitig per Sniffing (z. B. Magic-Bytes) bestimmt und mit der vom Client behaupteten Angabe abgeglichen; bei Widerspruch greift die serverseitig erkannte Art\n3. Der Verschlüsselungspfad (`crypto/envelope.go`) verarbeitet den Upload-Stream, statt die gesamte Datei vorab vollständig ins RAM zu laden\n4. Der HTTP-Request-Body ist serverseitig hart begrenzt (z. B. `http.MaxBytesReader`), unabhängig vom Upload-Limit der Fachlogik\n\n## Prüfungen vor der Abnahme\nFühre jede Prüfung tatsächlich durch und halte das Ergebnis schriftlich fest. Nicht durchgeführte Prüfungen zählen als offen:\n1. Angriffsnachstellung: authentifizierter Upload einer sehr großen Datei (deutlich über dem neuen Limit) — vor dem Fix unbegrenzter RAM-Anstieg messbar, nach dem Fix frühzeitige Ablehnung mit konstantem RAM-Verbrauch (beide Ergebnisse dokumentieren, z. B. per Speicherprofil)\n2. Angriffsnachstellung: Upload mit falsch deklariertem `Content-Type` (z. B. ausführbarer Inhalt als `image/png` deklariert) — serverseitige Erkennung weicht ab und greift korrekt\n3. Regressionstest: reguläre Uploads innerhalb des Limits mit korrektem MIME-Typ funktionieren weiterhin unverändert\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `SEC-04` Virenscan-Pipeline (verwandter, aber eigenständiger Befund)\n- Konfigurierbarkeit des Limits pro Mandant (falls künftig gewünscht, hier nur ein sinnvoller fester Default)\n\n## Arbeitsweise\n1. Lies zuerst den bestehenden Code der Vorbedingungen und halte dich an die dort etablierten Muster.\n2. Setze die kleinste Lösung um, die alle Akzeptanzkriterien erfüllt. Kein Umbau angrenzender Bereiche.\n3. Schreibe zu jedem Akzeptanzkriterium mindestens einen automatisierten Test.\n4. Führe alle Prüfungen aus und dokumentiere Zielwert und Ergebnis.\n5. Deutschsprachige Oberflächentexte, englischsprachige Bezeichner im Code.\n6. Keine Zugangsdaten, Schlüssel oder Verbindungszeichenfolgen im Code – ausschließlich über Umgebungsvariablen.\n\n## Abschluss\n- Commit-Nachricht: `SEC-05: upload-limit-mime-sniffing-streaming`\n- Branch: `feature/sec-05-upload-limit-mime-sniffing-streaming`\n- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy.\n- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten.\n"
|
||||
},
|
||||
{
|
||||
"code": "SEC-06",
|
||||
"title": "Modul-Verifier akzeptiert fremde Tenants wenn TENANT_SLUG leer",
|
||||
"epic": "SEC",
|
||||
"featureIds": [],
|
||||
"role": "Backend",
|
||||
"complexity": "Einfach",
|
||||
"estimateDays": 1,
|
||||
"tech": "TENANT_SLUG-Pflicht beim Dienststart",
|
||||
"description": "Ist TENANT_SLUG beim Dienststart leer, wird die Tenant-Prüfung im Modul-Verifier übersprungen und Tokens für jeden Tenant akzeptiert.",
|
||||
"dependsOn": [],
|
||||
"akzeptanz": [
|
||||
"Dienststart verweigert bei fehlendem/leerem TENANT_SLUG",
|
||||
"verifier.go prüft Tenant immer, keine Ausnahme bei leerem Wert",
|
||||
"Token für fremden Tenant wird in jedem Fall abgelehnt"
|
||||
],
|
||||
"pruefungen": [
|
||||
"Angriffsnachstellung: Start ohne TENANT_SLUG, fremdes Token, vor/nach Fix dokumentiert",
|
||||
"Regressionstest: korrekter Start mit eigenem Token funktioniert",
|
||||
"Test: fremdes Token bei korrektem TENANT_SLUG weiterhin abgelehnt"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"epicName": "Sicherheit",
|
||||
"epicEmoji": "🔒",
|
||||
"wave": 13,
|
||||
"unlocks": [],
|
||||
"prompt": "# SEC-06 – Modul-Verifier akzeptiert fremde Tenants wenn TENANT_SLUG leer\n\n**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 1 Personentag | **Welle:** 13\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH DMS (Dokumentenkern, Suche & OCR, Metadaten, Versionierung, Integration/API), das sich an paperless-ngx, Alfresco, Docspell und ecoDMS orientiert und bekannte Fehler aus archivdms (siehe known-issues-archivdms.md) bewusst vermeidet.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nSecurity-Review (main, Fable 5.1) hat einen Befund mit mittlerem Schweregrad gefunden: `dms/internal/moduleauth/verifier.go:204` prüft `if v.tenant != \"\" && …` — ist `v.tenant` leer, weil `TENANT_SLUG` beim Dienststart nicht gesetzt wurde (`cmd/app/api.go:300-314` erzwingt das nicht), wird die Tenant-Prüfung faktisch übersprungen. Der Verifier akzeptiert dann Tokens für jeden beliebigen Tenant.\n\n**Technische Grundlage:** `internal/moduleauth/verifier.go`, `cmd/app/api.go` (Startkonfiguration)\n\n## Produkt-DNA für diesen Bereich\n**Übernehmen:**\n- Fail-closed-Prinzip bei fehlender Mandanten-Konfiguration: lieber Dienststart verweigern als mandantenübergreifend akzeptieren.\n\n**Bewusst vermeiden:**\n- Sicherheitsprüfungen, die bei leerem/fehlendem Konfigurationswert übersprungen statt verweigert werden.\n\n## Ausgangslage\n`TENANT_SLUG` ist aktuell optional beim Dienststart; bei fehlendem Wert läuft der Dienst trotzdem hoch und akzeptiert Tokens ohne Tenant-Bindung.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Der Dienst verweigert den Start mit einer klaren Fehlermeldung, wenn `TENANT_SLUG` nicht gesetzt oder leer ist\n2. `verifier.go` prüft den Tenant immer (keine Bedingung mehr, die die Prüfung bei leerem `v.tenant` überspringt)\n3. Ein Token für einen anderen Tenant wird in jedem Fall abgelehnt, unabhängig vom Startzustand\n\n## Prüfungen vor der Abnahme\nFühre jede Prüfung tatsächlich durch und halte das Ergebnis schriftlich fest. Nicht durchgeführte Prüfungen zählen als offen:\n1. Angriffsnachstellung: Dienststart ohne `TENANT_SLUG`, anschließend Aufruf mit einem für einen fremden Tenant ausgestellten Token — vor dem Fix akzeptiert, nach dem Fix verweigert bereits der Dienststart (beide Ergebnisse dokumentieren)\n2. Regressionstest: Dienststart mit korrekt gesetztem `TENANT_SLUG` und gültigem, zum eigenen Tenant passendem Token funktioniert weiterhin\n3. Test: Token für fremden Tenant bei korrekt gesetztem `TENANT_SLUG` wird abgelehnt (bereits vorher der Fall, als Regressionsnachweis mitlaufen lassen)\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `SEC-01` Vernichtungs-Rückruf (nutzt ebenfalls Tenant-Header, aber eigenständiger Befund)\n- `SEC-07` `ALLOW_CALLER_IDENTITY`-Flag (verwandter, aber eigenständiger Auth-Bypass-Befund)\n\n## Arbeitsweise\n1. Lies zuerst den bestehenden Code der Vorbedingungen und halte dich an die dort etablierten Muster.\n2. Setze die kleinste Lösung um, die alle Akzeptanzkriterien erfüllt. Kein Umbau angrenzender Bereiche.\n3. Schreibe zu jedem Akzeptanzkriterium mindestens einen automatisierten Test.\n4. Führe alle Prüfungen aus und dokumentiere Zielwert und Ergebnis.\n5. Deutschsprachige Oberflächentexte, englischsprachige Bezeichner im Code.\n6. Keine Zugangsdaten, Schlüssel oder Verbindungszeichenfolgen im Code – ausschließlich über Umgebungsvariablen.\n\n## Abschluss\n- Commit-Nachricht: `SEC-06: tenant-slug-pflicht-beim-dienststart`\n- Branch: `feature/sec-06-tenant-slug-pflicht-beim-dienststart`\n- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy.\n- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten.\n"
|
||||
},
|
||||
{
|
||||
"code": "SEC-07",
|
||||
"title": "NEXARCH_DMS_APP_ALLOW_CALLER_IDENTITY umgeht komplette Authentifizierung",
|
||||
"epic": "SEC",
|
||||
"featureIds": [],
|
||||
"role": "Backend",
|
||||
"complexity": "Mittel",
|
||||
"estimateDays": 2,
|
||||
"tech": "Produktionssperre für Übergangs-Flag",
|
||||
"description": "Das Flag ALLOW_CALLER_IDENTITY erlaubt Admin-Zugriff per Query-Parameter ohne echte Authentifizierung und ist nur per Deployment-Checkliste, nicht technisch, auf Host 131 beschränkt.",
|
||||
"dependsOn": [],
|
||||
"akzeptanz": [
|
||||
"Flag wirkt nur bei explizit markierter Nicht-Produktionsumgebung",
|
||||
"Bei Produktion oder fehlender Markierung wird das Flag ignoriert",
|
||||
"Deployment-Checkliste enthält Entfernungsschritt vor Produktivbetrieb"
|
||||
],
|
||||
"pruefungen": [
|
||||
"Angriffsnachstellung: Flag ohne Nicht-Produktions-Markierung, vor/nach Fix dokumentiert",
|
||||
"Regressionstest: Flag mit korrekter Markierung funktioniert für Host 131 weiterhin",
|
||||
"Test: Flag ohne jede Umgebungsvariable wird ignoriert"
|
||||
],
|
||||
"status": "Backlog",
|
||||
"epicName": "Sicherheit",
|
||||
"epicEmoji": "🔒",
|
||||
"wave": 13,
|
||||
"unlocks": [],
|
||||
"prompt": "# SEC-07 – NEXARCH_DMS_APP_ALLOW_CALLER_IDENTITY umgeht komplette Authentifizierung\n\n**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 13\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH DMS (Dokumentenkern, Suche & OCR, Metadaten, Versionierung, Integration/API), das sich an paperless-ngx, Alfresco, Docspell und ecoDMS orientiert und bekannte Fehler aus archivdms (siehe known-issues-archivdms.md) bewusst vermeidet.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nSecurity-Review (main, Fable 5.1) hat einen Befund mit mittlerem Schweregrad gefunden: `dms/internal/moduleauth/middleware.go:46-50` und `policyclient.go:174-176` erlauben über das Flag `NEXARCH_DMS_APP_ALLOW_CALLER_IDENTITY=true` Admin-Zugriff über einen reinen Query-Parameter, komplett ohne echte Authentifizierung. Laut `DEPLOYMENT-131-CHECKLISTE.md:40` ist dies \"übergangsweise\" für Host 131 vorgesehen; ein übersehenes Flag in einer produktionsnahen Umgebung wäre ein vollständiger Auth-Bypass.\n\n**Technische Grundlage:** `internal/moduleauth/middleware.go`, `internal/moduleauth/policyclient.go`, `DEPLOYMENT-131-CHECKLISTE.md`\n\n## Produkt-DNA für diesen Bereich\n**Übernehmen:**\n- Übergangslösungen für Testumgebungen dürfen existieren, müssen aber technisch auf diese Umgebung beschränkt sein, nicht nur dokumentarisch.\n\n**Bewusst vermeiden:**\n- Ein reines Deployment-Checklisten-Item als einzige Absicherung gegen einen vollständigen Auth-Bypass in Produktion.\n\n## Ausgangslage\nDas Flag ist aktuell rein konfigurationsbasiert und ohne zusätzliche Laufzeit-Schranke wirksam, sobald gesetzt — unabhängig von der tatsächlichen Umgebung, in der der Dienst läuft.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Das Flag wirkt nur, wenn zusätzlich ein expliziter Umgebungs-/Hostname-Check bestätigt, dass es sich um eine als Nicht-Produktion markierte Umgebung handelt (z. B. über eine separate, eindeutig benannte Umgebungsvariable wie `NEXARCH_ENV=development`)\n2. Ist die Umgebung als Produktion markiert oder die Markierung fehlt, wird das Flag ignoriert und die reguläre Authentifizierung bleibt zwingend\n3. `DEPLOYMENT-131-CHECKLISTE.md` enthält einen expliziten Schritt, das Flag vor Produktivbetrieb zu entfernen bzw. die Nicht-Produktions-Markierung zu prüfen\n\n## Prüfungen vor der Abnahme\nFühre jede Prüfung tatsächlich durch und halte das Ergebnis schriftlich fest. Nicht durchgeführte Prüfungen zählen als offen:\n1. Angriffsnachstellung: Flag gesetzt, aber Umgebung nicht als Nicht-Produktion markiert — Aufruf mit reinem Query-Parameter-Identitätsvortäuschung — vor dem Fix erfolgreich als Admin, nach dem Fix mit regulärer Authentifizierungspflicht abgelehnt (beide Ergebnisse dokumentieren)\n2. Regressionstest: Flag gesetzt UND Umgebung korrekt als Nicht-Produktion markiert — Übergangsverhalten für Host 131 funktioniert weiterhin wie vorgesehen\n3. Test: Flag gesetzt, Umgebungsvariable fehlt komplett — Flag wird ignoriert\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `SEC-06` TENANT_SLUG-Pflicht (verwandter, aber eigenständiger Befund im selben Modul)\n- Vollständige Ablösung der Übergangslösung für Host 131 (eigenständiges, größeres Vorhaben)\n\n## Arbeitsweise\n1. Lies zuerst den bestehenden Code der Vorbedingungen und halte dich an die dort etablierten Muster.\n2. Setze die kleinste Lösung um, die alle Akzeptanzkriterien erfüllt. Kein Umbau angrenzender Bereiche.\n3. Schreibe zu jedem Akzeptanzkriterium mindestens einen automatisierten Test.\n4. Führe alle Prüfungen aus und dokumentiere Zielwert und Ergebnis.\n5. Deutschsprachige Oberflächentexte, englischsprachige Bezeichner im Code.\n6. Keine Zugangsdaten, Schlüssel oder Verbindungszeichenfolgen im Code – ausschließlich über Umgebungsvariablen.\n\n## Abschluss\n- Commit-Nachricht: `SEC-07: allow-caller-identity-produktionssperre`\n- Branch: `feature/sec-07-allow-caller-identity-produktionssperre`\n- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy.\n- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten.\n"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
# SEC-01 – Unauthentifizierter Vernichtungs-Rückruf löscht Dokumente physisch
|
||||
|
||||
**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Komplex | **Aufwand:** 3 Personentage | **Welle:** 13
|
||||
|
||||
---
|
||||
|
||||
## Rolle
|
||||
Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH DMS (Dokumentenkern, Suche & OCR, Metadaten, Versionierung, Integration/API), das sich an paperless-ngx, Alfresco, Docspell und ecoDMS orientiert und bekannte Fehler aus archivdms (siehe known-issues-archivdms.md) bewusst vermeidet.
|
||||
Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.
|
||||
|
||||
## Auftrag
|
||||
Security-Review (main, Fable 5.1) hat einen Befund mit hohem Schweregrad gefunden: `dms/internal/retentiondestroy/retentiondestroy.go:117-131` liefert `"",0,"",""` zurück statt den Aufruf abzulehnen, wenn `!RequireServiceToken` und kein Verifier konfiguriert oder kein Bearer-Token mitgesendet wurde. `dms/cmd/app/api.go:320-329` setzt `RequireServiceToken: Getenv(...) == "true"` — der Standardwert ist `false`, die Route ist damit im Standardbetrieb fail-open und laut OpenAPI-Doku zusätzlich mit `security: []` markiert. Einzige verbleibende Hürde ist der Header `X-Nexarch-Tenant`, der nur gegen die Instanz-Slug geprüft wird; dieser Slug ist aber z. B. im öffentlichen CMIS-`repositoryId` sichtbar (`cmis/handler.go:150`). Ein Aufruf mit `{"object_type":"dms_document","object_reference":"<uuid>",...}` löst `storageSvc.Delete` aller Revisionen plus `deleted_at`-Setzung aus (Zeile 205-212) — ohne Legal-Hold-Prüfung, mit Audit-Akteur fälschlich protokolliert als "archive-retention". Zusätzlich liest `json.NewDecoder(r.Body)` ohne Größenlimit auf einem Streaming-Server.
|
||||
|
||||
**Technische Grundlage:** `internal/retentiondestroy/retentiondestroy.go`, `cmd/app/api.go` (Service-Token-Konfiguration), `internal/audittrail` (Akteursfeld), bestehende Legal-Hold-Prüfung aus dem Papierkorb-/Löschpfad
|
||||
|
||||
## Produkt-DNA für diesen Bereich
|
||||
**Übernehmen:**
|
||||
- Alfresco: Vernichtung nach Aufbewahrungsfrist ist ein geschützter, auditierbarer Verwaltungsvorgang, kein offener Endpunkt.
|
||||
|
||||
**Bewusst vermeiden:**
|
||||
- Fail-open-Sicherheitslogik: ein nicht gesetztes Konfigurationsflag darf niemals eine Schutzfunktion abschalten.
|
||||
- Falsch zugeordnete Audit-Akteure, die einen Angriff als reguläre Systemaktion tarnen.
|
||||
|
||||
## Ausgangslage
|
||||
`RequireServiceToken` ist aktuell optional und standardmäßig `false` (`cmd/app/api.go:320-329`). Der Legal-Hold-Check existiert bereits im regulären Löschpfad, wird im Vernichtungs-Rückruf aber nicht aufgerufen.
|
||||
|
||||
## Akzeptanzkriterien
|
||||
Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:
|
||||
1. `RequireServiceToken` ist serverseitig fest auf `true` erzwungen (kein Umgebungsschalter kann den Bearer-Token-Zwang mehr abschalten)
|
||||
2. Ein Aufruf ohne gültiges, konfiguriertes Bearer-Token wird mit `401`/`403` abgelehnt, unabhängig von `X-Nexarch-Tenant`
|
||||
3. Vor physischer Löschung wird der Legal-Hold-Status des Objekts geprüft; bei aktivem Legal Hold wird die Vernichtung abgelehnt und protokolliert
|
||||
4. Der Request-Body ist auf eine feste Obergrenze begrenzt (z. B. per `http.MaxBytesReader`), überlange Anfragen werden mit Fehler abgelehnt statt unbegrenzt gepuffert
|
||||
5. Der Audit-Eintrag für eine über diesen Endpunkt ausgelöste Löschung protokolliert den tatsächlichen Aufrufkontext (Service-Identität des Tokens), nicht pauschal "archive-retention"
|
||||
|
||||
## Prüfungen vor der Abnahme
|
||||
Führe jede Prüfung tatsächlich durch und halte das Ergebnis schriftlich fest. Nicht durchgeführte Prüfungen zählen als offen:
|
||||
1. Angriffsnachstellung: Aufruf des Endpunkts ohne Bearer-Token, nur mit öffentlich bekanntem `X-Nexarch-Tenant`-Wert und gültiger Dokument-Referenz — vor dem Fix erfolgreich löschend, nach dem Fix mit `401`/`403` abgelehnt (beide Ergebnisse dokumentieren)
|
||||
2. Aufruf mit gültigem Token gegen ein Objekt mit aktivem Legal Hold — Vernichtung wird abgelehnt
|
||||
3. Aufruf mit Request-Body oberhalb der konfigurierten Obergrenze — wird mit Fehler abgelehnt, kein unbegrenzter RAM-Verbrauch
|
||||
4. Audit-Log nach einem erfolgreichen, legitimen Vernichtungsaufruf enthält den korrekten Service-Akteur
|
||||
|
||||
## Nicht Bestandteil dieser Kachel
|
||||
Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:
|
||||
- `SEC-06` TENANT_SLUG-Pflicht beim Dienststart (verwandter, aber eigenständiger Befund im Modul-Verifier)
|
||||
- Generelles Rate-Limiting auf Service-Endpunkten
|
||||
|
||||
## Arbeitsweise
|
||||
1. Lies zuerst den bestehenden Code der Vorbedingungen und halte dich an die dort etablierten Muster.
|
||||
2. Setze die kleinste Lösung um, die alle Akzeptanzkriterien erfüllt. Kein Umbau angrenzender Bereiche.
|
||||
3. Schreibe zu jedem Akzeptanzkriterium mindestens einen automatisierten Test.
|
||||
4. Führe alle Prüfungen aus und dokumentiere Zielwert und Ergebnis.
|
||||
5. Deutschsprachige Oberflächentexte, englischsprachige Bezeichner im Code.
|
||||
6. Keine Zugangsdaten, Schlüssel oder Verbindungszeichenfolgen im Code – ausschließlich über Umgebungsvariablen.
|
||||
|
||||
## Abschluss
|
||||
- Commit-Nachricht: `SEC-01: unauthentifizierter-vernichtungs-rueckruf-abgesichert`
|
||||
- Branch: `feature/sec-01-unauthentifizierter-vernichtungs-rueckruf-abgesichert`
|
||||
- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy.
|
||||
- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten.
|
||||
@@ -0,0 +1,57 @@
|
||||
# SEC-02 – Mail-Postfachverwaltung ohne Rollenprüfung ermöglicht Credential-Exfiltration
|
||||
|
||||
**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Komplex | **Aufwand:** 3 Personentage | **Welle:** 13
|
||||
|
||||
---
|
||||
|
||||
## Rolle
|
||||
Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH DMS (Dokumentenkern, Suche & OCR, Metadaten, Versionierung, Integration/API), das sich an paperless-ngx, Alfresco, Docspell und ecoDMS orientiert und bekannte Fehler aus archivdms (siehe known-issues-archivdms.md) bewusst vermeidet.
|
||||
Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.
|
||||
|
||||
## Auftrag
|
||||
Security-Review (main, Fable 5.1) hat einen Befund mit hohem Schweregrad gefunden: `dms/internal/mailimportapi/handler.go:61-75` (`requireActor`) akzeptiert jede authentifizierte Identität für die Mail-Postfachverwaltung, ohne Rollenprüfung. `dms/internal/authz/authz.go:149-170` setzt `needsGuard` für `mail-accounts` auf `false`. `dms/internal/mailimport/manage.go:80-93` erlaubt bei einem Update mit leerem Passwort, dass `password_ciphertext` erhalten bleibt, während `host`/`port` geändert werden — der Worker (`importer.go:83-87`, `imap.go:69`) sendet dann `LOGIN user password` an einen vom Angreifer kontrollierten IMAP-Server und exfiltriert damit das gespeicherte Postfach-Passwort im Klartext. Zusätzlich ist `ImportUserID` in `handler.go:148-152,175-179` frei wählbar — importierte Dokumente bekommen dadurch einen beliebigen `created_by`, von dem die Eigentümer-RBAC abhängt. `POLICY_URL` ist im Standardbetrieb nicht gesetzt, Policy-Enforcement also optional.
|
||||
|
||||
**Technische Grundlage:** `internal/mailimportapi/handler.go`, `internal/authz/authz.go`, `internal/mailimport/manage.go`, `internal/mailimport/importer.go`, `internal/mailimport/imap.go`
|
||||
|
||||
## Produkt-DNA für diesen Bereich
|
||||
**Übernehmen:**
|
||||
- Docspell: Mail-Import als vertrauenswürdige, klar abgegrenzte Admin-Funktion, nicht als allgemein zugänglicher Endpunkt.
|
||||
|
||||
**Bewusst vermeiden:**
|
||||
- Implizite Rechteausweitung über "irgendwie authentifiziert reicht".
|
||||
- Konfigurationsänderungen, die ein gespeichertes Secret an ein neues, unverifiziertes Ziel senden, ohne erneute Bestätigung.
|
||||
|
||||
## Ausgangslage
|
||||
Mail-Postfachverwaltung läuft aktuell ohne Admin-Beschränkung und ohne Bindung von Host/Port-Änderung an eine erneute Passwortbestätigung.
|
||||
|
||||
## Akzeptanzkriterien
|
||||
Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:
|
||||
1. `needsGuard` ist für `mail-accounts` auf `true` gesetzt; nur Rollen mit Admin-Berechtigung für Postfachverwaltung können Postfächer anlegen/ändern/löschen
|
||||
2. Eine Änderung von `host` oder `port` an einem bestehenden Postfach verlangt zwingend eine erneute Passworteingabe (kein Update von Host/Port bei leer gelassenem Passwortfeld unter Beibehaltung des alten `password_ciphertext`)
|
||||
3. `ImportUserID` wird beim Import serverseitig auf den tatsächlich authentifizierten Actor fixiert und ist nicht mehr frei im Request wählbar
|
||||
4. Automatisierter Test belegt: Request mit geänderter `host`/leerem Passwort auf bestehendes Postfach wird abgelehnt
|
||||
|
||||
## Prüfungen vor der Abnahme
|
||||
Führe jede Prüfung tatsächlich durch und halte das Ergebnis schriftlich fest. Nicht durchgeführte Prüfungen zählen als offen:
|
||||
1. Angriffsnachstellung: authentifizierter, nicht-administrativer Nutzer ändert `host` eines fremden Postfachs auf einen selbst kontrollierten IMAP-Server mit leerem Passwortfeld — vor dem Fix erfolgreich (Gegenstelle empfängt `LOGIN` mit Klartext-Passwort, per Testserver nachweisen), nach dem Fix mit `403` abgelehnt (beide Ergebnisse dokumentieren)
|
||||
2. Angriffsnachstellung: Import-Aufruf mit fremdem `ImportUserID` — vor dem Fix wird das importierte Dokument dem fremden Nutzer zugeordnet, nach dem Fix dem tatsächlichen Actor
|
||||
3. Regressionstest: legitime Host-Änderung mit korrekt mitgesendetem Passwort funktioniert weiterhin
|
||||
|
||||
## Nicht Bestandteil dieser Kachel
|
||||
Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:
|
||||
- `SEC-03` generelle Guard-Lücken bei anderen Routen
|
||||
- Verpflichtendes `POLICY_URL`-Enforcement systemweit (eigenständiger, größerer Befund)
|
||||
|
||||
## Arbeitsweise
|
||||
1. Lies zuerst den bestehenden Code der Vorbedingungen und halte dich an die dort etablierten Muster.
|
||||
2. Setze die kleinste Lösung um, die alle Akzeptanzkriterien erfüllt. Kein Umbau angrenzender Bereiche.
|
||||
3. Schreibe zu jedem Akzeptanzkriterium mindestens einen automatisierten Test.
|
||||
4. Führe alle Prüfungen aus und dokumentiere Zielwert und Ergebnis.
|
||||
5. Deutschsprachige Oberflächentexte, englischsprachige Bezeichner im Code.
|
||||
6. Keine Zugangsdaten, Schlüssel oder Verbindungszeichenfolgen im Code – ausschließlich über Umgebungsvariablen.
|
||||
|
||||
## Abschluss
|
||||
- Commit-Nachricht: `SEC-02: mail-postfachverwaltung-rollenpruefung`
|
||||
- Branch: `feature/sec-02-mail-postfachverwaltung-rollenpruefung`
|
||||
- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy.
|
||||
- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten.
|
||||
@@ -0,0 +1,56 @@
|
||||
# SEC-03 – Guard-Lücken: Papierkorb/Ordnerbaum/Trigger-Webhooks ohne Zugriffsprüfung
|
||||
|
||||
**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 13
|
||||
|
||||
---
|
||||
|
||||
## Rolle
|
||||
Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH DMS (Dokumentenkern, Suche & OCR, Metadaten, Versionierung, Integration/API), das sich an paperless-ngx, Alfresco, Docspell und ecoDMS orientiert und bekannte Fehler aus archivdms (siehe known-issues-archivdms.md) bewusst vermeidet.
|
||||
Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.
|
||||
|
||||
## Auftrag
|
||||
Security-Review (main, Fable 5.1) hat einen Befund mit mittlerem Schweregrad gefunden: `dms/internal/authz/authz.go:149-170` setzt `needsGuard` auf `false` für `GET /folders/*`, `GET /trash` und `GET /triggers`. Konkret liefert `GET /trash` (`trashapi/handler.go:88-107`) den Papierkorb aller Nutzer ungefiltert, `folderapi/handler.go:84-87` liefert den gesamten Ordnerbaum, und `triggerapi/handler.go:114-126` liefert `webhook_url` aller Trigger aus — alle drei ohne Policy-URL-Prüfung erreichbar, sobald die Identität nur authentifiziert ist.
|
||||
|
||||
**Technische Grundlage:** `internal/authz/authz.go`, `internal/trashapi/handler.go`, `internal/folderapi/handler.go`, `internal/triggerapi/handler.go`
|
||||
|
||||
## Produkt-DNA für diesen Bereich
|
||||
**Übernehmen:**
|
||||
- Alfresco: jede Lese-Route ist eigentümer-/mandantenbezogen gefiltert, nie ein globaler Dump.
|
||||
|
||||
**Bewusst vermeiden:**
|
||||
- "Nur GET, also unkritisch" als Begründung für fehlende Zugriffsprüfung — Lesezugriffe auf fremde Daten sind ein Datenschutzvorfall.
|
||||
|
||||
## Ausgangslage
|
||||
`needsGuard` ist für die drei genannten Routen aktuell `false`; die Handler selbst filtern nicht nach Eigentümer oder Mandant.
|
||||
|
||||
## Akzeptanzkriterien
|
||||
Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:
|
||||
1. `needsGuard` ist für `GET /folders/*`, `GET /trash` und `GET /triggers` auf `true` gesetzt
|
||||
2. `GET /trash` liefert ausschließlich Papierkorb-Einträge des aufrufenden Nutzers bzw. seines Mandanten, nicht aller Nutzer
|
||||
3. `folderapi` liefert nur den für den aufrufenden Nutzer sichtbaren Teilbaum
|
||||
4. `triggerapi` liefert `webhook_url` nur an Nutzer mit entsprechender Berechtigung auf den jeweiligen Trigger
|
||||
|
||||
## Prüfungen vor der Abnahme
|
||||
Führe jede Prüfung tatsächlich durch und halte das Ergebnis schriftlich fest. Nicht durchgeführte Prüfungen zählen als offen:
|
||||
1. Angriffsnachstellung: Aufruf von `GET /trash` durch Nutzer A mit Papierkorb-Einträgen von Nutzer B — vor dem Fix sichtbar, nach dem Fix nicht mehr sichtbar (beide Ergebnisse dokumentieren)
|
||||
2. Gleiche Nachstellung für `GET /folders` (fremder Ordnerbaum) und `GET /triggers` (fremde `webhook_url`)
|
||||
3. Regressionstest: legitimer Nutzer sieht weiterhin seine eigenen Papierkorb-/Ordner-/Trigger-Daten vollständig
|
||||
|
||||
## Nicht Bestandteil dieser Kachel
|
||||
Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:
|
||||
- `SEC-02` Rollenprüfung Mail-Postfachverwaltung (eigenständiger Befund, andere Route)
|
||||
- Systemweites `POLICY_URL`-Pflicht-Enforcement
|
||||
|
||||
## Arbeitsweise
|
||||
1. Lies zuerst den bestehenden Code der Vorbedingungen und halte dich an die dort etablierten Muster.
|
||||
2. Setze die kleinste Lösung um, die alle Akzeptanzkriterien erfüllt. Kein Umbau angrenzender Bereiche.
|
||||
3. Schreibe zu jedem Akzeptanzkriterium mindestens einen automatisierten Test.
|
||||
4. Führe alle Prüfungen aus und dokumentiere Zielwert und Ergebnis.
|
||||
5. Deutschsprachige Oberflächentexte, englischsprachige Bezeichner im Code.
|
||||
6. Keine Zugangsdaten, Schlüssel oder Verbindungszeichenfolgen im Code – ausschließlich über Umgebungsvariablen.
|
||||
|
||||
## Abschluss
|
||||
- Commit-Nachricht: `SEC-03: guard-luecken-trash-folders-triggers`
|
||||
- Branch: `feature/sec-03-guard-luecken-trash-folders-triggers`
|
||||
- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy.
|
||||
- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten.
|
||||
@@ -0,0 +1,55 @@
|
||||
# SEC-04 – Virenscan standardmäßig nicht in die Verarbeitungs-Pipeline eingereiht
|
||||
|
||||
**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 13
|
||||
|
||||
---
|
||||
|
||||
## Rolle
|
||||
Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH DMS (Dokumentenkern, Suche & OCR, Metadaten, Versionierung, Integration/API), das sich an paperless-ngx, Alfresco, Docspell und ecoDMS orientiert und bekannte Fehler aus archivdms (siehe known-issues-archivdms.md) bewusst vermeidet.
|
||||
Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.
|
||||
|
||||
## Auftrag
|
||||
Security-Review (main, Fable 5.1) hat einen Befund mit mittlerem Schweregrad gefunden: `dms/cmd/app/api.go:72-83` enthält `malwarescan.scan` nicht standardmäßig in `enqueueTypes`. Die Sichtbarkeitsfilter (`documentapi/handler.go:64`, `downloadapi.go:73`) blenden nur Dokumente mit `status <> 'clean'` aus — ein Dokument, für das nie eine Scan-Zeile erzeugt wurde, hat keinen solchen Status und ist damit sofort sichtbar und herunterladbar, obwohl es nie gescannt wurde.
|
||||
|
||||
**Technische Grundlage:** `cmd/app/api.go` (`enqueueTypes`), `internal/documentapi/handler.go`, `internal/downloadapi.go`, `internal/malwarescan`
|
||||
|
||||
## Produkt-DNA für diesen Bereich
|
||||
**Übernehmen:**
|
||||
- ecoDMS/Alfresco: Malware-Scan ist Teil der Standard-Pipeline, kein optionales Add-on, das man manuell aktivieren muss.
|
||||
|
||||
**Bewusst vermeiden:**
|
||||
- Sichtbarkeitslogik nach dem Muster "alles außer explizit als schädlich markiert" — das macht ein fehlender Scan-Lauf zur versehentlichen Freigabe statt zur Sperre.
|
||||
|
||||
## Ausgangslage
|
||||
`enqueueTypes` in `cmd/app/api.go:72-83` listet die beim Start registrierten Hintergrundaufgaben; `malwarescan.scan` fehlt dort im Standardbetrieb.
|
||||
|
||||
## Akzeptanzkriterien
|
||||
Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:
|
||||
1. `malwarescan.scan` ist standardmäßig in `enqueueTypes` enthalten und wird für jeden Upload automatisch eingereiht
|
||||
2. Die Sichtbarkeitslogik ist umgekehrt: ein Dokument ist nur sichtbar/herunterladbar, wenn explizit `status = 'clean'` gesetzt ist; ein Dokument ohne Scan-Ergebnis gilt als nicht freigegeben
|
||||
3. Bestehende Dokumente ohne Scan-Ergebnis werden durch eine Migration/Nachlauf-Aufgabe erfasst, statt dauerhaft unsichtbar oder dauerhaft sichtbar zu bleiben
|
||||
|
||||
## Prüfungen vor der Abnahme
|
||||
Führe jede Prüfung tatsächlich durch und halte das Ergebnis schriftlich fest. Nicht durchgeführte Prüfungen zählen als offen:
|
||||
1. Angriffsnachstellung: Upload eines Dokuments bei deaktiviertem/verzögertem Scan-Worker — vor dem Fix sofort sichtbar und herunterladbar ohne Scan-Ergebnis, nach dem Fix gesperrt bis `status = 'clean'` vorliegt (beide Ergebnisse dokumentieren)
|
||||
2. Regressionstest: ein tatsächlich als `clean` markiertes Dokument bleibt sichtbar und herunterladbar
|
||||
3. Regressionstest: ein als `infected`/unclean markiertes Dokument bleibt gesperrt
|
||||
|
||||
## Nicht Bestandteil dieser Kachel
|
||||
Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:
|
||||
- `SEC-05` Upload-Limit und MIME-Sniffing (eigenständiger, verwandter Befund im Upload-Pfad)
|
||||
- Auswahl/Betrieb der eingesetzten Scan-Engine (bereits in `internal/malwarescan` vorhanden)
|
||||
|
||||
## Arbeitsweise
|
||||
1. Lies zuerst den bestehenden Code der Vorbedingungen und halte dich an die dort etablierten Muster.
|
||||
2. Setze die kleinste Lösung um, die alle Akzeptanzkriterien erfüllt. Kein Umbau angrenzender Bereiche.
|
||||
3. Schreibe zu jedem Akzeptanzkriterium mindestens einen automatisierten Test.
|
||||
4. Führe alle Prüfungen aus und dokumentiere Zielwert und Ergebnis.
|
||||
5. Deutschsprachige Oberflächentexte, englischsprachige Bezeichner im Code.
|
||||
6. Keine Zugangsdaten, Schlüssel oder Verbindungszeichenfolgen im Code – ausschließlich über Umgebungsvariablen.
|
||||
|
||||
## Abschluss
|
||||
- Commit-Nachricht: `SEC-04: virenscan-standardmaessig-eingereiht`
|
||||
- Branch: `feature/sec-04-virenscan-standardmaessig-eingereiht`
|
||||
- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy.
|
||||
- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten.
|
||||
@@ -0,0 +1,57 @@
|
||||
# SEC-05 – Upload-Limit standardmäßig unbegrenzt, Client-MIME ungeprüft, authentifizierter OOM
|
||||
|
||||
**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 13
|
||||
|
||||
---
|
||||
|
||||
## Rolle
|
||||
Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH DMS (Dokumentenkern, Suche & OCR, Metadaten, Versionierung, Integration/API), das sich an paperless-ngx, Alfresco, Docspell und ecoDMS orientiert und bekannte Fehler aus archivdms (siehe known-issues-archivdms.md) bewusst vermeidet.
|
||||
Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.
|
||||
|
||||
## Auftrag
|
||||
Security-Review (main, Fable 5.1) hat einen Befund mit mittlerem Schweregrad gefunden: `dms/internal/upload/validate.go:42-71` behandelt ein konfiguriertes Limit von `0` als "unbegrenzt" — das ist der Standardwert in `cmd/app/api.go:62-71`. Der MIME-Typ wird dabei vom Client übernommen statt serverseitig gesnifft. `upload/service.go:244` ruft über `crypto/envelope.go:116` `io.ReadAll` auf und liest die gesamte Datei ins RAM; der Streaming-Server hat kein Body-Limit, wodurch ein authentifizierter Nutzer per großem Upload einen Denial-of-Service durch RAM-Erschöpfung auslösen kann. `versioningapi/handler.go:166-170` liefert außerdem die vom Client angegebene MIME-Art `inline` aus, ohne eigenes Sniffing (CSP mildert dies etwas ab, ersetzt aber keine serverseitige Prüfung).
|
||||
|
||||
**Technische Grundlage:** `internal/upload/validate.go`, `cmd/app/api.go` (Upload-Limit-Konfiguration), `internal/upload/service.go`, `internal/crypto/envelope.go`, `internal/versioningapi/handler.go`
|
||||
|
||||
## Produkt-DNA für diesen Bereich
|
||||
**Übernehmen:**
|
||||
- paperless-ngx: Upload-Größenlimit und Typprüfung sind Standardverhalten, nicht optional nachzurüsten.
|
||||
|
||||
**Bewusst vermeiden:**
|
||||
- "0 bedeutet unbegrenzt" als Default für ein Sicherheitslimit.
|
||||
- Vertrauen auf vom Client gelieferte Metadaten (MIME-Typ) für sicherheitsrelevante Entscheidungen.
|
||||
|
||||
## Ausgangslage
|
||||
Upload-Limit ist aktuell per Default `0` (unbegrenzt), MIME-Erkennung erfolgt nicht serverseitig, Verschlüsselung liest die komplette Datei ins RAM.
|
||||
|
||||
## Akzeptanzkriterien
|
||||
Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:
|
||||
1. Das Standard-Upload-Limit ist ein konkreter, sinnvoller Wert größer `0` (kein Umgebungsschalter kann es implizit auf "unbegrenzt" zurücksetzen)
|
||||
2. Der MIME-Typ wird serverseitig per Sniffing (z. B. Magic-Bytes) bestimmt und mit der vom Client behaupteten Angabe abgeglichen; bei Widerspruch greift die serverseitig erkannte Art
|
||||
3. Der Verschlüsselungspfad (`crypto/envelope.go`) verarbeitet den Upload-Stream, statt die gesamte Datei vorab vollständig ins RAM zu laden
|
||||
4. Der HTTP-Request-Body ist serverseitig hart begrenzt (z. B. `http.MaxBytesReader`), unabhängig vom Upload-Limit der Fachlogik
|
||||
|
||||
## Prüfungen vor der Abnahme
|
||||
Führe jede Prüfung tatsächlich durch und halte das Ergebnis schriftlich fest. Nicht durchgeführte Prüfungen zählen als offen:
|
||||
1. Angriffsnachstellung: authentifizierter Upload einer sehr großen Datei (deutlich über dem neuen Limit) — vor dem Fix unbegrenzter RAM-Anstieg messbar, nach dem Fix frühzeitige Ablehnung mit konstantem RAM-Verbrauch (beide Ergebnisse dokumentieren, z. B. per Speicherprofil)
|
||||
2. Angriffsnachstellung: Upload mit falsch deklariertem `Content-Type` (z. B. ausführbarer Inhalt als `image/png` deklariert) — serverseitige Erkennung weicht ab und greift korrekt
|
||||
3. Regressionstest: reguläre Uploads innerhalb des Limits mit korrektem MIME-Typ funktionieren weiterhin unverändert
|
||||
|
||||
## Nicht Bestandteil dieser Kachel
|
||||
Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:
|
||||
- `SEC-04` Virenscan-Pipeline (verwandter, aber eigenständiger Befund)
|
||||
- Konfigurierbarkeit des Limits pro Mandant (falls künftig gewünscht, hier nur ein sinnvoller fester Default)
|
||||
|
||||
## Arbeitsweise
|
||||
1. Lies zuerst den bestehenden Code der Vorbedingungen und halte dich an die dort etablierten Muster.
|
||||
2. Setze die kleinste Lösung um, die alle Akzeptanzkriterien erfüllt. Kein Umbau angrenzender Bereiche.
|
||||
3. Schreibe zu jedem Akzeptanzkriterium mindestens einen automatisierten Test.
|
||||
4. Führe alle Prüfungen aus und dokumentiere Zielwert und Ergebnis.
|
||||
5. Deutschsprachige Oberflächentexte, englischsprachige Bezeichner im Code.
|
||||
6. Keine Zugangsdaten, Schlüssel oder Verbindungszeichenfolgen im Code – ausschließlich über Umgebungsvariablen.
|
||||
|
||||
## Abschluss
|
||||
- Commit-Nachricht: `SEC-05: upload-limit-mime-sniffing-streaming`
|
||||
- Branch: `feature/sec-05-upload-limit-mime-sniffing-streaming`
|
||||
- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy.
|
||||
- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten.
|
||||
@@ -0,0 +1,55 @@
|
||||
# SEC-06 – Modul-Verifier akzeptiert fremde Tenants wenn TENANT_SLUG leer
|
||||
|
||||
**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 1 Personentag | **Welle:** 13
|
||||
|
||||
---
|
||||
|
||||
## Rolle
|
||||
Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH DMS (Dokumentenkern, Suche & OCR, Metadaten, Versionierung, Integration/API), das sich an paperless-ngx, Alfresco, Docspell und ecoDMS orientiert und bekannte Fehler aus archivdms (siehe known-issues-archivdms.md) bewusst vermeidet.
|
||||
Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.
|
||||
|
||||
## Auftrag
|
||||
Security-Review (main, Fable 5.1) hat einen Befund mit mittlerem Schweregrad gefunden: `dms/internal/moduleauth/verifier.go:204` prüft `if v.tenant != "" && …` — ist `v.tenant` leer, weil `TENANT_SLUG` beim Dienststart nicht gesetzt wurde (`cmd/app/api.go:300-314` erzwingt das nicht), wird die Tenant-Prüfung faktisch übersprungen. Der Verifier akzeptiert dann Tokens für jeden beliebigen Tenant.
|
||||
|
||||
**Technische Grundlage:** `internal/moduleauth/verifier.go`, `cmd/app/api.go` (Startkonfiguration)
|
||||
|
||||
## Produkt-DNA für diesen Bereich
|
||||
**Übernehmen:**
|
||||
- Fail-closed-Prinzip bei fehlender Mandanten-Konfiguration: lieber Dienststart verweigern als mandantenübergreifend akzeptieren.
|
||||
|
||||
**Bewusst vermeiden:**
|
||||
- Sicherheitsprüfungen, die bei leerem/fehlendem Konfigurationswert übersprungen statt verweigert werden.
|
||||
|
||||
## Ausgangslage
|
||||
`TENANT_SLUG` ist aktuell optional beim Dienststart; bei fehlendem Wert läuft der Dienst trotzdem hoch und akzeptiert Tokens ohne Tenant-Bindung.
|
||||
|
||||
## Akzeptanzkriterien
|
||||
Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:
|
||||
1. Der Dienst verweigert den Start mit einer klaren Fehlermeldung, wenn `TENANT_SLUG` nicht gesetzt oder leer ist
|
||||
2. `verifier.go` prüft den Tenant immer (keine Bedingung mehr, die die Prüfung bei leerem `v.tenant` überspringt)
|
||||
3. Ein Token für einen anderen Tenant wird in jedem Fall abgelehnt, unabhängig vom Startzustand
|
||||
|
||||
## Prüfungen vor der Abnahme
|
||||
Führe jede Prüfung tatsächlich durch und halte das Ergebnis schriftlich fest. Nicht durchgeführte Prüfungen zählen als offen:
|
||||
1. Angriffsnachstellung: Dienststart ohne `TENANT_SLUG`, anschließend Aufruf mit einem für einen fremden Tenant ausgestellten Token — vor dem Fix akzeptiert, nach dem Fix verweigert bereits der Dienststart (beide Ergebnisse dokumentieren)
|
||||
2. Regressionstest: Dienststart mit korrekt gesetztem `TENANT_SLUG` und gültigem, zum eigenen Tenant passendem Token funktioniert weiterhin
|
||||
3. Test: Token für fremden Tenant bei korrekt gesetztem `TENANT_SLUG` wird abgelehnt (bereits vorher der Fall, als Regressionsnachweis mitlaufen lassen)
|
||||
|
||||
## Nicht Bestandteil dieser Kachel
|
||||
Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:
|
||||
- `SEC-01` Vernichtungs-Rückruf (nutzt ebenfalls Tenant-Header, aber eigenständiger Befund)
|
||||
- `SEC-07` `ALLOW_CALLER_IDENTITY`-Flag (verwandter, aber eigenständiger Auth-Bypass-Befund)
|
||||
|
||||
## Arbeitsweise
|
||||
1. Lies zuerst den bestehenden Code der Vorbedingungen und halte dich an die dort etablierten Muster.
|
||||
2. Setze die kleinste Lösung um, die alle Akzeptanzkriterien erfüllt. Kein Umbau angrenzender Bereiche.
|
||||
3. Schreibe zu jedem Akzeptanzkriterium mindestens einen automatisierten Test.
|
||||
4. Führe alle Prüfungen aus und dokumentiere Zielwert und Ergebnis.
|
||||
5. Deutschsprachige Oberflächentexte, englischsprachige Bezeichner im Code.
|
||||
6. Keine Zugangsdaten, Schlüssel oder Verbindungszeichenfolgen im Code – ausschließlich über Umgebungsvariablen.
|
||||
|
||||
## Abschluss
|
||||
- Commit-Nachricht: `SEC-06: tenant-slug-pflicht-beim-dienststart`
|
||||
- Branch: `feature/sec-06-tenant-slug-pflicht-beim-dienststart`
|
||||
- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy.
|
||||
- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten.
|
||||
@@ -0,0 +1,55 @@
|
||||
# SEC-07 – NEXARCH_DMS_APP_ALLOW_CALLER_IDENTITY umgeht komplette Authentifizierung
|
||||
|
||||
**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 13
|
||||
|
||||
---
|
||||
|
||||
## Rolle
|
||||
Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH DMS (Dokumentenkern, Suche & OCR, Metadaten, Versionierung, Integration/API), das sich an paperless-ngx, Alfresco, Docspell und ecoDMS orientiert und bekannte Fehler aus archivdms (siehe known-issues-archivdms.md) bewusst vermeidet.
|
||||
Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.
|
||||
|
||||
## Auftrag
|
||||
Security-Review (main, Fable 5.1) hat einen Befund mit mittlerem Schweregrad gefunden: `dms/internal/moduleauth/middleware.go:46-50` und `policyclient.go:174-176` erlauben über das Flag `NEXARCH_DMS_APP_ALLOW_CALLER_IDENTITY=true` Admin-Zugriff über einen reinen Query-Parameter, komplett ohne echte Authentifizierung. Laut `DEPLOYMENT-131-CHECKLISTE.md:40` ist dies "übergangsweise" für Host 131 vorgesehen; ein übersehenes Flag in einer produktionsnahen Umgebung wäre ein vollständiger Auth-Bypass.
|
||||
|
||||
**Technische Grundlage:** `internal/moduleauth/middleware.go`, `internal/moduleauth/policyclient.go`, `DEPLOYMENT-131-CHECKLISTE.md`
|
||||
|
||||
## Produkt-DNA für diesen Bereich
|
||||
**Übernehmen:**
|
||||
- Übergangslösungen für Testumgebungen dürfen existieren, müssen aber technisch auf diese Umgebung beschränkt sein, nicht nur dokumentarisch.
|
||||
|
||||
**Bewusst vermeiden:**
|
||||
- Ein reines Deployment-Checklisten-Item als einzige Absicherung gegen einen vollständigen Auth-Bypass in Produktion.
|
||||
|
||||
## Ausgangslage
|
||||
Das Flag ist aktuell rein konfigurationsbasiert und ohne zusätzliche Laufzeit-Schranke wirksam, sobald gesetzt — unabhängig von der tatsächlichen Umgebung, in der der Dienst läuft.
|
||||
|
||||
## Akzeptanzkriterien
|
||||
Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:
|
||||
1. Das Flag wirkt nur, wenn zusätzlich ein expliziter Umgebungs-/Hostname-Check bestätigt, dass es sich um eine als Nicht-Produktion markierte Umgebung handelt (z. B. über eine separate, eindeutig benannte Umgebungsvariable wie `NEXARCH_ENV=development`)
|
||||
2. Ist die Umgebung als Produktion markiert oder die Markierung fehlt, wird das Flag ignoriert und die reguläre Authentifizierung bleibt zwingend
|
||||
3. `DEPLOYMENT-131-CHECKLISTE.md` enthält einen expliziten Schritt, das Flag vor Produktivbetrieb zu entfernen bzw. die Nicht-Produktions-Markierung zu prüfen
|
||||
|
||||
## Prüfungen vor der Abnahme
|
||||
Führe jede Prüfung tatsächlich durch und halte das Ergebnis schriftlich fest. Nicht durchgeführte Prüfungen zählen als offen:
|
||||
1. Angriffsnachstellung: Flag gesetzt, aber Umgebung nicht als Nicht-Produktion markiert — Aufruf mit reinem Query-Parameter-Identitätsvortäuschung — vor dem Fix erfolgreich als Admin, nach dem Fix mit regulärer Authentifizierungspflicht abgelehnt (beide Ergebnisse dokumentieren)
|
||||
2. Regressionstest: Flag gesetzt UND Umgebung korrekt als Nicht-Produktion markiert — Übergangsverhalten für Host 131 funktioniert weiterhin wie vorgesehen
|
||||
3. Test: Flag gesetzt, Umgebungsvariable fehlt komplett — Flag wird ignoriert
|
||||
|
||||
## Nicht Bestandteil dieser Kachel
|
||||
Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:
|
||||
- `SEC-06` TENANT_SLUG-Pflicht (verwandter, aber eigenständiger Befund im selben Modul)
|
||||
- Vollständige Ablösung der Übergangslösung für Host 131 (eigenständiges, größeres Vorhaben)
|
||||
|
||||
## Arbeitsweise
|
||||
1. Lies zuerst den bestehenden Code der Vorbedingungen und halte dich an die dort etablierten Muster.
|
||||
2. Setze die kleinste Lösung um, die alle Akzeptanzkriterien erfüllt. Kein Umbau angrenzender Bereiche.
|
||||
3. Schreibe zu jedem Akzeptanzkriterium mindestens einen automatisierten Test.
|
||||
4. Führe alle Prüfungen aus und dokumentiere Zielwert und Ergebnis.
|
||||
5. Deutschsprachige Oberflächentexte, englischsprachige Bezeichner im Code.
|
||||
6. Keine Zugangsdaten, Schlüssel oder Verbindungszeichenfolgen im Code – ausschließlich über Umgebungsvariablen.
|
||||
|
||||
## Abschluss
|
||||
- Commit-Nachricht: `SEC-07: allow-caller-identity-produktionssperre`
|
||||
- Branch: `feature/sec-07-allow-caller-identity-produktionssperre`
|
||||
- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy.
|
||||
- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten.
|
||||
Reference in new issue
Block a user