From 579a68cf53717e3e96f7ae2af0f60eb5e4ef74d1 Mon Sep 17 00:00:00 2001 From: patrick Date: Fri, 6 Nov 2026 23:12:17 +0100 Subject: [PATCH] archive-kanban: Board in main uebernehmen Stand von chore/ai-kanban-security-folgetickets. Die Historie dieses Branches hat keinen gemeinsamen Vorfahren mit main, daher als Snapshot. _shared enthaelt CSS/JS der Kanban-Ansicht (identisch in allen Board-Branches). Co-Authored-By: Claude Sonnet 5.5 --- _shared/kanban.css | 40 + _shared/kanban.js | 152 +++ archive-kanban/README.md | 92 ++ archive-kanban/board.csv | 247 ++++ archive-kanban/board.json | 1813 ++++++++++++++++++++++++++++++ archive-kanban/kanban.html | 50 + archive-kanban/tickets/ANA-01.md | 61 + archive-kanban/tickets/ANA-02.md | 60 + archive-kanban/tickets/ANA-03.md | 60 + archive-kanban/tickets/BAK-01.md | 62 + archive-kanban/tickets/BAK-02.md | 62 + archive-kanban/tickets/BAK-03.md | 68 ++ archive-kanban/tickets/BAK-04.md | 62 + archive-kanban/tickets/BAK-05.md | 63 ++ archive-kanban/tickets/BAK-06.md | 62 + archive-kanban/tickets/BAK-07.md | 65 ++ archive-kanban/tickets/BAK-09.md | 59 + archive-kanban/tickets/BAK-10.md | 58 + archive-kanban/tickets/CMP-01.md | 62 + archive-kanban/tickets/CMP-02.md | 62 + archive-kanban/tickets/CMP-03.md | 62 + archive-kanban/tickets/CMP-04.md | 62 + archive-kanban/tickets/CMP-05.md | 63 ++ archive-kanban/tickets/CMP-06.md | 66 ++ archive-kanban/tickets/CMP-07.md | 70 ++ archive-kanban/tickets/CMP-08.md | 45 + archive-kanban/tickets/QA-01.md | 61 + archive-kanban/tickets/QA-02.md | 64 ++ archive-kanban/tickets/QA-03.md | 66 ++ archive-kanban/tickets/QA-04.md | 64 ++ archive-kanban/tickets/QA-05.md | 68 ++ archive-kanban/tickets/QA-06.md | 60 + archive-kanban/tickets/QA-07.md | 60 + archive-kanban/tickets/RET-01.md | 65 ++ archive-kanban/tickets/RET-02.md | 64 ++ archive-kanban/tickets/RET-03.md | 63 ++ archive-kanban/tickets/RET-04.md | 62 + archive-kanban/tickets/RET-05.md | 63 ++ archive-kanban/tickets/RET-06.md | 62 + archive-kanban/tickets/RET-07.md | 64 ++ archive-kanban/tickets/RET-11.md | 58 + archive-kanban/tickets/RET-12.md | 58 + archive-kanban/tickets/RET-13.md | 56 + archive-kanban/tickets/RET-14.md | 65 ++ archive-kanban/tickets/RET-15.md | 44 + archive-kanban/tickets/RET-16.md | 34 + archive-kanban/tickets/SEC-01.md | 52 + archive-kanban/tickets/SEC-02.md | 49 + archive-kanban/tickets/SEC-03.md | 50 + archive-kanban/tickets/SEC-04.md | 51 + archive-kanban/tickets/SEC-05.md | 52 + archive-kanban/tickets/SEC-06.md | 51 + 52 files changed, 5134 insertions(+) create mode 100644 _shared/kanban.css create mode 100644 _shared/kanban.js create mode 100644 archive-kanban/README.md create mode 100644 archive-kanban/board.csv create mode 100644 archive-kanban/board.json create mode 100644 archive-kanban/kanban.html create mode 100644 archive-kanban/tickets/ANA-01.md create mode 100644 archive-kanban/tickets/ANA-02.md create mode 100644 archive-kanban/tickets/ANA-03.md create mode 100644 archive-kanban/tickets/BAK-01.md create mode 100644 archive-kanban/tickets/BAK-02.md create mode 100644 archive-kanban/tickets/BAK-03.md create mode 100644 archive-kanban/tickets/BAK-04.md create mode 100644 archive-kanban/tickets/BAK-05.md create mode 100644 archive-kanban/tickets/BAK-06.md create mode 100644 archive-kanban/tickets/BAK-07.md create mode 100644 archive-kanban/tickets/BAK-09.md create mode 100644 archive-kanban/tickets/BAK-10.md create mode 100644 archive-kanban/tickets/CMP-01.md create mode 100644 archive-kanban/tickets/CMP-02.md create mode 100644 archive-kanban/tickets/CMP-03.md create mode 100644 archive-kanban/tickets/CMP-04.md create mode 100644 archive-kanban/tickets/CMP-05.md create mode 100644 archive-kanban/tickets/CMP-06.md create mode 100644 archive-kanban/tickets/CMP-07.md create mode 100644 archive-kanban/tickets/CMP-08.md create mode 100644 archive-kanban/tickets/QA-01.md create mode 100644 archive-kanban/tickets/QA-02.md create mode 100644 archive-kanban/tickets/QA-03.md create mode 100644 archive-kanban/tickets/QA-04.md create mode 100644 archive-kanban/tickets/QA-05.md create mode 100644 archive-kanban/tickets/QA-06.md create mode 100644 archive-kanban/tickets/QA-07.md create mode 100644 archive-kanban/tickets/RET-01.md create mode 100644 archive-kanban/tickets/RET-02.md create mode 100644 archive-kanban/tickets/RET-03.md create mode 100644 archive-kanban/tickets/RET-04.md create mode 100644 archive-kanban/tickets/RET-05.md create mode 100644 archive-kanban/tickets/RET-06.md create mode 100644 archive-kanban/tickets/RET-07.md create mode 100644 archive-kanban/tickets/RET-11.md create mode 100644 archive-kanban/tickets/RET-12.md create mode 100644 archive-kanban/tickets/RET-13.md create mode 100644 archive-kanban/tickets/RET-14.md create mode 100644 archive-kanban/tickets/RET-15.md create mode 100644 archive-kanban/tickets/RET-16.md create mode 100644 archive-kanban/tickets/SEC-01.md create mode 100644 archive-kanban/tickets/SEC-02.md create mode 100644 archive-kanban/tickets/SEC-03.md create mode 100644 archive-kanban/tickets/SEC-04.md create mode 100644 archive-kanban/tickets/SEC-05.md create mode 100644 archive-kanban/tickets/SEC-06.md diff --git a/_shared/kanban.css b/_shared/kanban.css new file mode 100644 index 00000000..82ee3beb --- /dev/null +++ b/_shared/kanban.css @@ -0,0 +1,40 @@ +:root { + --bg: #0B0F17; --card: #131A26; --card2: #18212F; --border: #253044; + --fg: #E6EDF7; --muted: #93A1B8; --primary: #3B82F6; + } + * { box-sizing: border-box; } + body { margin: 0; background: var(--bg); color: var(--fg); font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; } + header { position: sticky; top: 0; z-index: 20; background: rgba(11,15,23,.92); backdrop-filter: blur(8px); border-bottom: 1px solid var(--border); padding: 14px 20px; } + .row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; } + h1 { font-size: 17px; margin: 0 14px 0 0; letter-spacing: -.01em; } + .sub { color: var(--muted); font-size: 12px; } + input, select, button { background: var(--card2); color: var(--fg); border: 1px solid var(--border); border-radius: 8px; padding: 7px 10px; font-size: 12px; font-family: inherit; } + input:focus, select:focus { outline: 1px solid var(--primary); } + button { cursor: pointer; } + button:hover { border-color: var(--primary); } + button.primary { background: rgba(59,130,246,.14); color: #93BBFB; border-color: rgba(59,130,246,.3); } + .stats { display: flex; gap: 14px; font-size: 11px; color: var(--muted); margin-top: 8px; flex-wrap: wrap; } + .stats b { color: var(--fg); } + .board { display: grid; grid-template-columns: repeat(5, minmax(240px, 1fr)); gap: 12px; padding: 16px 20px 40px; align-items: start; overflow-x: auto; } + .col { background: var(--card); border: 1px solid var(--border); border-radius: 12px; min-height: 160px; padding: 10px; } + .col.over { border-color: var(--primary); background: #16203042; } + .col h2 { font-size: 12px; margin: 2px 4px 10px; display: flex; justify-content: space-between; align-items: center; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); } + .count { background: var(--card2); border: 1px solid var(--border); border-radius: 999px; padding: 1px 7px; font-size: 10px; color: var(--fg); } + .card { background: var(--card2); border: 1px solid var(--border); border-radius: 10px; padding: 10px; margin-bottom: 8px; cursor: grab; } + .card:hover { border-color: #3a4a66; } + .card.dragging { opacity: .45; } + .card .code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 10px; color: var(--muted); } + .card .title { font-size: 13px; margin: 4px 0 7px; line-height: 1.35; } + .tag { display: inline-block; font-size: 10px; padding: 2px 7px; border-radius: 999px; background: #202b3d; color: var(--muted); margin-right: 4px; margin-top: 3px; } + .tag.blocked { background: rgba(245,158,11,.15); color: #FBBF24; } + .tag.ready { background: rgba(34,197,94,.15); color: #4ADE80; } + .tag.wave { background: rgba(59,130,246,.14); color: #93BBFB; } + dialog { background: var(--card); color: var(--fg); border: 1px solid var(--border); border-radius: 14px; max-width: 860px; width: 94%; padding: 0; } + dialog::backdrop { background: rgba(0,0,0,.72); } + .dlg-head { padding: 18px 20px; border-bottom: 1px solid var(--border); display: flex; justify-content: space-between; gap: 12px; align-items: flex-start; } + .dlg-body { padding: 18px 20px 24px; max-height: 66vh; overflow: auto; } + pre { background: #0E1420; border: 1px solid var(--border); border-radius: 10px; padding: 14px; font-size: 11px; line-height: 1.6; white-space: pre-wrap; word-break: break-word; color: #C7D3E5; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; } + h3 { font-size: 12px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); margin: 18px 0 8px; } + ul { margin: 0; padding-left: 18px; font-size: 13px; color: #C7D3E5; line-height: 1.6; } + .chip { font-family: ui-monospace, Menlo, monospace; font-size: 11px; border: 1px solid var(--border); border-radius: 6px; padding: 2px 6px; margin: 0 4px 4px 0; display: inline-block; color: var(--muted); } + .empty { color: #55627a; font-size: 11px; text-align: center; padding: 14px 0; } diff --git a/_shared/kanban.js b/_shared/kanban.js new file mode 100644 index 00000000..33fe51ac --- /dev/null +++ b/_shared/kanban.js @@ -0,0 +1,152 @@ +(function () { + var DATA = JSON.parse(document.getElementById('data').textContent); + var COLUMNS = ['Backlog', 'Bereit', 'In Arbeit', 'Prüfung', 'Fertig']; + var KEY = 'kanban-status-v1:' + location.pathname; + var state = {}; + try { state = JSON.parse(localStorage.getItem(KEY) || '{}') || {}; } catch (e) { state = {}; } + var onlyReady = false; + + function statusOf(t) { return state[t.code] || t.status || 'Backlog'; } + function isDone(code) { return statusOf(byCode[code] || { code: code }) === 'Fertig'; } + var byCode = {}; + DATA.tickets.forEach(function (t) { byCode[t.code] = t; }); + + function ready(t) { return (t.dependsOn || []).every(function (d) { return isDone(d); }); } + + function save() { localStorage.setItem(KEY, JSON.stringify(state)); } + + // Filter befüllen + var fEpic = document.getElementById('fEpic'), fRole = document.getElementById('fRole'), fWave = document.getElementById('fWave'); + DATA.epics.forEach(function (e) { var o = document.createElement('option'); o.value = e.key; o.textContent = e.emoji + ' ' + e.name; fEpic.appendChild(o); }); + Array.from(new Set(DATA.tickets.map(function (t) { return t.role; }))).sort().forEach(function (r) { var o = document.createElement('option'); o.value = r; o.textContent = r; fRole.appendChild(o); }); + var maxWave = Math.max.apply(null, DATA.tickets.map(function (t) { return t.wave; })); + for (var w = 1; w <= maxWave; w++) { var o = document.createElement('option'); o.value = String(w); o.textContent = 'Welle ' + w; fWave.appendChild(o); } + + function visible() { + var q = document.getElementById('q').value.trim().toLowerCase(); + return DATA.tickets.filter(function (t) { + if (fEpic.value && t.epic !== fEpic.value) return false; + if (fRole.value && t.role !== fRole.value) return false; + if (fWave.value && String(t.wave) !== fWave.value) return false; + if (onlyReady && (!ready(t) || statusOf(t) === 'Fertig')) return false; + if (q) { + var hay = (t.code + ' ' + t.title + ' ' + t.tech + ' ' + t.description).toLowerCase(); + if (hay.indexOf(q) === -1) return false; + } + return true; + }); + } + + function render() { + var board = document.getElementById('board'); + board.innerHTML = ''; + var list = visible(); + COLUMNS.forEach(function (col) { + var el = document.createElement('div'); + el.className = 'col'; + el.dataset.col = col; + var items = list.filter(function (t) { return statusOf(t) === col; }); + var h = document.createElement('h2'); + h.innerHTML = '' + col + '' + items.length + ''; + el.appendChild(h); + if (!items.length) { var e = document.createElement('div'); e.className = 'empty'; e.textContent = '– leer –'; el.appendChild(e); } + items.forEach(function (t) { el.appendChild(card(t)); }); + el.addEventListener('dragover', function (ev) { ev.preventDefault(); el.classList.add('over'); }); + el.addEventListener('dragleave', function () { el.classList.remove('over'); }); + el.addEventListener('drop', function (ev) { + ev.preventDefault(); el.classList.remove('over'); + var code = ev.dataTransfer.getData('text/plain'); + if (!code) return; + state[code] = col; save(); render(); + }); + board.appendChild(el); + }); + stats(list); + } + + function card(t) { + var d = document.createElement('div'); + d.className = 'card'; + d.draggable = true; + var blocked = !ready(t); + d.innerHTML = '
' + t.code + ' · ' + t.estimateDays + ' PT
' + + '
' + esc(t.title) + '
' + + 'Welle ' + t.wave + '' + + '' + t.role + '' + + '' + t.complexity + '' + + (blocked ? 'wartet auf ' + t.dependsOn.filter(function (c) { return !isDone(c); }).join(', ') + '' : 'startbar'); + d.addEventListener('dragstart', function (ev) { ev.dataTransfer.setData('text/plain', t.code); d.classList.add('dragging'); }); + d.addEventListener('dragend', function () { d.classList.remove('dragging'); }); + d.addEventListener('click', function () { openDlg(t); }); + return d; + } + + function esc(s) { return String(s).replace(/[&<>]/g, function (c) { return { '&': '&', '<': '<', '>': '>' }[c]; }); } + + function stats(list) { + var done = DATA.tickets.filter(function (t) { return statusOf(t) === 'Fertig'; }); + var donePT = done.reduce(function (a, t) { return a + t.estimateDays; }, 0); + var readyNow = DATA.tickets.filter(function (t) { return ready(t) && statusOf(t) !== 'Fertig'; }).length; + document.getElementById('stats').innerHTML = + '' + DATA.tickets.length + ' Kacheln' + + 'sichtbar: ' + list.length + '' + + 'fertig: ' + done.length + ' (' + donePT + ' von ' + DATA.totalDays + ' PT)' + + 'jetzt startbar: ' + readyNow + '' + + 'Wellen: ' + maxWave + ''; + } + + var dlg = document.getElementById('dlg'); + var current = null; + function openDlg(t) { + current = t; + document.getElementById('dCode').textContent = t.code + ' · ' + t.epicName; + document.getElementById('dTitle').textContent = t.title; + document.getElementById('dMeta').innerHTML = + 'Welle ' + t.wave + '' + t.role + '' + t.complexity + '' + t.estimateDays + ' PT' + statusOf(t) + ''; + document.getElementById('dDesc').textContent = t.description; + chips('dDeps', t.dependsOn); + chips('dNext', t.unlocks); + items('dAcc', t.akzeptanz); + items('dChk', t.pruefungen); + document.getElementById('dPrompt').textContent = t.prompt; + dlg.showModal(); + } + function chips(id, arr) { + var el = document.getElementById(id); + el.innerHTML = (arr && arr.length) ? arr.map(function (c) { return '' + c + (byCode[c] ? ' – ' + esc(byCode[c].title) : '') + ''; }).join('') : 'keine'; + } + function items(id, arr) { + document.getElementById(id).innerHTML = (arr || []).map(function (a) { return '
  • ' + esc(a) + '
  • '; }).join(''); + } + document.getElementById('closeBtn').onclick = function () { dlg.close(); }; + document.getElementById('copyBtn').onclick = function () { + if (!current) return; + var btn = this; + navigator.clipboard.writeText(current.prompt).then(function () { + btn.textContent = 'Kopiert ✓'; + setTimeout(function () { btn.textContent = 'Prompt kopieren'; }, 1800); + }); + }; + + document.getElementById('q').addEventListener('input', render); + [fEpic, fRole, fWave].forEach(function (s) { s.addEventListener('change', render); }); + document.getElementById('onlyReady').onclick = function () { + onlyReady = !onlyReady; + this.style.borderColor = onlyReady ? 'var(--primary)' : 'var(--border)'; + this.textContent = onlyReady ? 'Filter: nur startbare' : 'Nur startbare'; + render(); + }; + document.getElementById('resetBtn').onclick = function () { + if (confirm('Alle lokalen Statusänderungen verwerfen?')) { state = {}; save(); render(); } + }; + document.getElementById('exportBtn').onclick = function () { + var rows = [['Code', 'Titel', 'Status']].concat(DATA.tickets.map(function (t) { return [t.code, t.title, statusOf(t)]; })); + var csv = rows.map(function (r) { return r.map(function (c) { return '"' + String(c).replace(/"/g, '""') + '"'; }).join(','); }).join('\n'); + var a = document.createElement('a'); + a.href = URL.createObjectURL(new Blob(['\ufeff' + csv], { type: 'text/csv;charset=utf-8' })); + a.download = 'kanban-stand.csv'; + a.click(); + }; + + render(); +})(); diff --git a/archive-kanban/README.md b/archive-kanban/README.md new file mode 100644 index 00000000..6c71eba2 --- /dev/null +++ b/archive-kanban/README.md @@ -0,0 +1,92 @@ +# Archive-Kanban – lokal abarbeiten + +40 Arbeitskacheln · 5 Epics · 93 Personentage · 7 Wellen (inkl. Welle 7: Threat-Model-Nachtrag 2026-09-12 — RET-11, RET-12, BAK-09, BAK-10). + +Hinweis: Dieses Board ist die alleinige Quelle für Aufbewahrung/WORM/Compliance/Backup. DMS-Board und Mail-Board referenzieren dieses Board extern in der Ausgangslage betroffener Tickets, statt eigene Retention-Logik zu implementieren. +Stand: 2026-08-26 + +## Weg 1 – Sofort loslegen (empfohlen) + +`kanban.html` per Doppelklick im Browser öffnen. Kein Server, kein Internet, keine Installation. + +- Kacheln per Drag & Drop zwischen Backlog → Bereit → In Arbeit → Prüfung → Fertig ziehen +- Der Stand wird im Browser gespeichert (localStorage) und bleibt nach dem Schließen erhalten +- Filter nach Epic, Rolle, Welle, Volltext sowie „Nur startbare“ (alle Vorgänger auf Fertig) +- Klick auf eine Kachel öffnet Details inkl. vollem Bau-Prompt und „Prompt kopieren“ +- „Stand sichern“ exportiert den aktuellen Status als CSV + +Hinweis: Der Stand hängt an Browser und Profil. Für Teamarbeit Weg 2 oder 3 nutzen. + +## Weg 2 – Import in ein vorhandenes Werkzeug + +`board.csv` (UTF-8 mit BOM, Komma-getrennt) importieren: + +| Werkzeug | Weg | +| --- | --- | +| Trello | Board → Menü → Mehr → CSV importieren (Power-Up) | +| Jira | Einstellungen → System → Externes Importieren → CSV, Spalte „Status“ auf den Workflow mappen | +| GitHub Projects | Projekt → … → Import, oder per `gh` CLI aus `board.json` | +| Notion | Datenbank → … → Merge with CSV | +| Linear / Asana / ClickUp | jeweils CSV-Import, Spalten wie oben zuordnen | + +Spalten: Code, Titel, Epic, Rolle, Komplexitaet, Aufwand_PT, Welle, Status, Technik, +Beschreibung, Haengt_ab_von, Schaltet_frei, Akzeptanzkriterien, Pruefungen. + +## Weg 3 – Dateibasiert in der Entwicklungsumgebung + +Der Ordner `tickets/` enthält für jede Kachel eine Markdown-Datei (`RET-01.md` …). +Jede Datei ist ein vollständiger Bau-Prompt – Auftrag, Produkt-DNA, Ausgangslage, +Akzeptanzkriterien, Prüfungen und Abschlussregeln. + +- **Obsidian**: Ordner als Vault öffnen, Community-Plugin „Kanban“ installieren, Spalten anlegen und die Notizen einsortieren. +- **VS Code**: Ordner öffnen, Erweiterung „Todo Tree“ oder „Markdown Kanban“ nutzen. +- **Coding-Assistent**: Dateiöffnen, Inhalt kopieren, als Auftrag übergeben. Ein Prompt = eine Kachel = ein Branch. + +## Weg 4 – Eigenes Board im Netzwerk (Team) + +Selbst gehostet, jeweils mit CSV-Import: + +```bash +# Focalboard +docker run -d -p 8000:8000 --name focalboard mattermost/focalboard + +# Planka +docker run -d -p 3010:1337 --name planka ghcr.io/plankanban/planka:latest + +# Vikunja +docker run -d -p 3456:3456 --name vikunja vikunja/vikunja +``` + +Danach `board.csv` importieren. + +## Reihenfolge der Arbeit + +Die Wellen geben an, was parallel laufen darf. Eine Kachel ist startbar, +sobald alle Kacheln unter „Hängt ab von“ auf Fertig stehen. + +- **Welle 1** (5 Kacheln): RET-01, CMP-04, BAK-01, BAK-02, QA-01 +- **Welle 2** (8 Kacheln): RET-02, RET-04, RET-05, CMP-01, CMP-02, BAK-03, BAK-05, BAK-07 +- **Welle 3** (9 Kacheln): RET-03, RET-06, RET-07, CMP-03, CMP-05, BAK-04, BAK-06, ANA-01, QA-06 +- **Welle 4** (5 Kacheln): CMP-06, ANA-02, ANA-03, QA-02, QA-04 +- **Welle 5** (1 Kachel): QA-03 +- **Welle 6** (1 Kachel): QA-05 + +Kritischer Pfad (16 PT): RET-01 → RET-02 → RET-03 → CMP-06 → QA-03 → QA-05 + +## Produkt-DNA + +### Übernehmen +- **Alfresco**: Retention Policies mit Stichtagsberechnung, revisionssichere Ablage und Aufbewahrungssperre (Legal Hold). +- **Alfresco**: Vier-Augen-Prinzip bei Freigaben, insbesondere bei Löschungen. +- **ecoDMS**: Revisionssicherheit als Grundhaltung – unveränderliches Protokoll, nachvollziehbare Vernichtung. +- **restic/Borg**: Inkrementelle, deduplizierende Sicherung mit eingebauter Verifikation und routinemäßigem Restore-Test. + +### Vermeiden +- **Alfresco – schwergewichtige Plattform mit hohem Ressourcenbedarf und trägem Betrieb.**: Schlanker Go-Dienst mit Postgres-Jobqueue statt Java-Anwendungsserver und zusätzlicher Message-Queue-Infrastruktur. + +## Arbeitsregeln + +Je Kachel ein eigener Branch, schrittweise committen, Branch pushen, dann anhalten. +Kein Merge und kein Deploy ohne ausdrückliche Freigabe. + +Code-Struktur: Hauptdateien/Entry-Points klein halten, Fachlogik in eigene Module/Dateien auslagern. Vor dem Anlegen einer neuen Funktions-/Modul-Datei prüfen, ob dieselbe Funktionalität nicht schon in einem anderen Modul (auch modulübergreifend, z. B. Core) existiert — keine doppelten Funktionsdateien, ein Modul/Board referenziert das andere extern statt Code zu kopieren (gleiches Prinzip wie bei den Konsolidierungen IAM/Archive/Workflow/AI/API/UI-Shell, siehe nexarch-state.json). diff --git a/archive-kanban/board.csv b/archive-kanban/board.csv new file mode 100644 index 00000000..4d412059 --- /dev/null +++ b/archive-kanban/board.csv @@ -0,0 +1,247 @@ +Code,Titel,Epic,Rolle,Komplexitaet,Aufwand_PT,Welle,Status,Technik,Beschreibung,Haengt_ab_von,Schaltet_frei,Akzeptanzkriterien,Pruefungen +RET-01,Generisches Retention-Objektmodell,⏳ Retention & WORM,Backend,Mittel,3,1,Fertig,"PostgreSQL, pgx/v5, SQL-Migrationen (kein ORM)","Generisches Datenmodell für aufbewahrungspflichtige Objekte anlegen: Objekttyp, Objekt-Referenz (modulübergreifend über Adapter), Aufbewahrungsklasse, Status. Migrationen versioniert und rückrollbar.",,RET-02 RET-04 RET-05 CMP-01 CMP-02,"Objektmodell bildet beliebige Objekttypen aus DMS und Mail ab, ohne modulspezifische Spalten +Aufbewahrungsklasse ist je Objekt eindeutig zugeordnet und historisierbar +Migration läuft gegen leere Datenbank durch und ist rückrollbar","Migration vorwärts und rückwärts getestet +Testobjekt aus fiktivem DMS- und Mail-Adapter beide korrekt abgebildet +Tenant-Isolation der Kern-Tabellen durch Negativtest belegt" +RET-02,Aufbewahrungsfristen-Engine,⏳ Retention & WORM,Backend,Mittel,3,2,Fertig,"PostgreSQL, Postgres-Jobqueue (geplante Jobs statt Redis)","Fristenmodell je Aufbewahrungsklasse mit Stichtagsberechnung (Beginn, Dauer, Ablaufdatum) und periodischem Job, der ablaufende Objekte ermittelt.",RET-01,RET-03 RET-06 RET-07,"Frist wird je Aufbewahrungsklasse konfiguriert und auf jedes zugeordnete Objekt angewendet +Stichtag wird korrekt aus Beginn- und Dauerangabe berechnet, inklusive Kalenderfällen (Schaltjahr, Monatsende) +Periodischer Job liefert Liste ablaufender Objekte je Tenant","Fristberechnung an Referenzdaten mit bekannten Ablaufdaten geprüft +Job liefert bei leerem Bestand ein leeres, nicht fehlerhaftes Ergebnis +Mehrfachausführung des Jobs erzeugt keine doppelten Einträge" +RET-03,Löschworkflow & Aufbewahrungssperre (Legal Hold),⏳ Retention & WORM,Backend,Mittel,3,3,Fertig,"PostgreSQL, transaktionaler Zustandswechsel","Löschworkflow für abgelaufene Objekte: Freigabe, Vernichtung, Protokolleintrag. Aufbewahrungssperre (Legal Hold) verhindert jede Löschung unabhängig vom Fristablauf.",RET-02,CMP-06 QA-02 CMP-07 QA-07,"Ablauf der Frist löst einen Freigabeprozess aus, keine automatische Sofortlöschung +Aufbewahrungssperre verhindert Löschung auch bei abgelaufener Frist, mit Begründungspflicht beim Setzen +Jede Vernichtung erzeugt einen unveränderlichen Protokolleintrag mit Zeitpunkt und ausführender Person","Objekt mit aktiver Sperre widersteht einem direkten Löschversuch +Protokolleintrag nach Vernichtung ist nachträglich nicht änderbar (DB-Constraint oder Trigger) +Aufheben einer Sperre ist selbst protokolliert" +RET-04,WORM-Speicher-Garantie (Append-only),⏳ Retention & WORM,Backend,Mittel,3,2,Fertig,"Objekt-Storage-Anbindung, Append-only-Schreibpfad","Speicherpfad für archivierte Objektinhalte, der nach dem Schreiben keine Änderung und kein Überschreiben mehr zulässt (Write Once, Read Many).",RET-01,QA-02 RET-11,"Einmal geschriebener Objektinhalt kann nicht überschrieben werden +Loeschung ist ausschliesslich ueber den kontrollierten Loeschworkflow moeglich, nicht ueber die Go-API dieses Pakets (keine Delete-Funktion) - struktureller Schutz auf Anwendungsebene, kein absoluter Schutz gegen root-OS-Zugriff +Prüfsumme je Objekt wird beim Schreiben erzeugt und bei jedem Lesezugriff verglichen","Direkter Überschreibversuch am Speicherpfad wird abgewiesen +Prüfsummenabgleich erkennt eine manipulierte Testdatei zuverlässig +Loeschung ist ueber die Go-API des Pakets technisch unmoeglich (keine Delete-Funktion vorhanden), nicht nur per Konvention verboten" +RET-05,Modul-Adapter-Schnittstelle (DMS/Mail registrieren Objekttypen),⏳ Retention & WORM,Backend,Mittel,3,2,Fertig,"REST-Schnittstelle, Registrierungs-API","Schnittstelle, über die DMS und Mail ihre Objekttypen (Dokument, Mail, Anhang) und die zugehörige Aufbewahrungsklasse bei Archive registrieren, statt eigene Retention-Logik zu bauen.",RET-01,CMP-03 ANA-01 CMP-07 QA-07 RET-12,"Modul kann einen Objekttyp mit Aufbewahrungsklasse und Rückruf-Adresse für Löschbestätigung registrieren +Archive ruft das registrierte Modul beim Vernichten des Objekts zurück, statt selbst Modul-Interna zu kennen +Registrierung ist idempotent und mandantenfähig","Zwei fiktive Module (DMS, Mail) parallel registriert ohne Kollision +Rückruf bei Vernichtung erfolgreich gegen einen Testendpunkt ausgeführt +Erneute Registrierung desselben Objekttyps ändert nichts am bestehenden Zustand" +RET-06,Aufbewahrungsfristen-Konfigurationsoberfläche,⏳ Retention & WORM,Frontend,Mittel,3,3,Fertig,Next.js/React/TypeScript,"Next.js/React-Oberflaeche zur Pflege von Aufbewahrungsklassen und Fristen je Objekttyp und Tenant, inklusive Vorschauliste bald ablaufender Objekte. Backend-API bereits fertig (RET-06-API), RBAC-Provisorium darin durch RET-08 auf echtes RBAC-06 migriert - dieses Ticket ist reiner Frontend-Scope.",RET-02 RET-06-API RET-08,QA-02,"Aufbewahrungsklasse mit Frist lässt sich anlegen, ändern und deaktivieren +Vorschauliste zeigt in den nächsten 30 Tagen ablaufende Objekte +Änderungen an Fristen sind nur berechtigten Rollen zugänglich","Änderung einer Frist wirkt sich nur auf künftige Berechnungen aus, nicht rückwirkend auf bereits protokollierte Vernichtungen +Nicht berechtigte Rolle erhält keinen Zugriff auf die Konfiguration +Vorschauliste stimmt mit dem Ergebnis des periodischen Jobs überein" +RET-07,Fristablauf-Benachrichtigungen,⏳ Retention & WORM,Backend,Einfach,2,3,Fertig,Kopplung an Core CFG-02 (Benachrichtigungs-Dispatcher),"Benachrichtigung verantwortlicher Personen vor Ablauf einer Aufbewahrungsfrist, konfigurierbarer Vorlauf je Aufbewahrungsklasse. Der eigentliche Versand läuft ausschließlich über den zentralen Core-Benachrichtigungs-Dispatcher (CFG-02), erreichbar über den HTTP-Wrapper CFG-05 (Archive kann internal/notifyprefs nicht direkt importieren) – Archive erzeugt nur das Ereignis, versendet keine E-Mail selbst. Empfaenger ist eine konfigurierte zustaendige Rolle (Tenant-Admin), kein Objekt-Owner — RET-01 fuehrt bewusst keine Owner-Beziehung.",RET-02 CFG-05,QA-02,"Benachrichtigung wird im konfigurierten Vorlauf vor Fristablauf als Ereignis an Core CFG-02 (ueber CFG-05) uebergeben, adressiert an eine konfigurierte zustaendige Rolle (Tenant-Admin), nicht selbst versendet +Mehrfachversand derselben Benachrichtigung wird verhindert +Benachrichtigung lässt sich je Aufbewahrungsklasse ein- und ausschalten","Testfrist mit kurzem Vorlauf löst genau eine Benachrichtigung aus +Deaktivierte Benachrichtigung verschickt nachweislich nichts +Fehlgeschlagener Versand wird protokolliert und nicht stillschweigend verworfen" +CMP-01,GoBD-Verfahrensdokumentation,⚖️ Compliance & eDiscovery,Backend,Mittel,3,2,Fertig,"PDF-Export, versionierte Dokumentvorlage","Exportierbare Verfahrensdokumentation gemäß GoBD: Beschreibung der Aufbewahrungs-, Zugriffs- und Löschverfahren, automatisch aus der aktuellen Konfiguration erzeugt.",RET-01,CMP-05 QA-03,"Dokumentation wird automatisiert aus der aktuellen Retention-Konfiguration erzeugt, nicht manuell gepflegt +Export liegt als versioniertes PDF mit Erzeugungsdatum vor +Änderung an Aufbewahrungsklassen spiegelt sich in der nächsten Erzeugung wider","Erzeugtes Dokument enthält alle aktiven Aufbewahrungsklassen mit Fristen +Zwei aufeinanderfolgende Exporte ohne Konfigurationsänderung sind inhaltlich identisch +Export einer zweiten Person als GoBD-tauglich nachvollzogen" +CMP-02,DSGVO-/Datenschutz-Berichte,⚖️ Compliance & eDiscovery,Backend,Mittel,3,2,Fertig,PDF/CSV-Export,"Berichte für Auskunftsersuchen, Verarbeitungsübersichten und Zugriffsnachweise je betroffener Person und Tenant.",RET-01,CMP-05 CMP-07,"Auskunftsbericht listet alle gespeicherten Objekte einer betroffenen Person mit Aufbewahrungsklasse +Verarbeitungsübersicht zeigt Zweck und Rechtsgrundlage je Objekttyp +Export ist mandantenscharf und enthält keine Daten anderer Tenants","Auskunftsbericht für Testperson mit bekanntem Datenbestand stimmt mit erwarteter Liste überein +Bericht für einen Tenant enthält keine Objekte eines anderen Tenants +Export lässt sich als CSV weiterverarbeiten" +CMP-03,eDiscovery-Suche & Export (modulübergreifend),⚖️ Compliance & eDiscovery,Backend,Komplex,4,3,Fertig,"Modulübergreifende Such-API, ZIP-Export mit Prüfsummen","Suche über registrierte Objekttypen aus DMS und Mail hinweg für Rechtsverfahren, mit vollständigem, prüfsummengesichertem Export der Treffer.",RET-05,QA-03,"Suche liefert Treffer aus mehreren registrierten Modulen in einer gemeinsamen Ergebnisliste +Export enthält Originalobjekte, Metadaten und eine Prüfsummenliste je Datei +Suchlauf und Export werden als eigener Vorgang protokolliert (wer, wann, welche Kriterien)","Testsuche über zwei fiktive Module liefert erwartete kombinierte Trefferzahl +Prüfsumme jeder exportierten Datei stimmt nach Entpacken überein +Protokolleintrag zum Suchlauf ist nachträglich nicht veränderbar" +CMP-04,Audit-Trail-Kopplung an Core-Audit-Log,⚖️ Compliance & eDiscovery,Backend,Einfach,2,1,Fertig,REST-Anbindung an NEXARCH Core Audit-Log,"Alle sicherheitsrelevanten Vorgänge in Archive (Fristsetzung, Sperre, Löschung, Export) werden an das zentrale Audit-Log in NEXARCH Core gemeldet, statt ein eigenes Protokoll zu führen.",AUD-01,QA-03,"Jeder sicherheitsrelevante Vorgang erzeugt einen Eintrag im zentralen Audit-Log +Eintrag enthält Tenant, handelnde Person, Vorgang und Zeitstempel +Ausfall des Audit-Log-Dienstes blockiert nicht den Fachvorgang, wird aber sichtbar nachgemeldet","Testvorgänge (Sperre setzen, Löschung, Export) erzeugen je einen nachvollziehbaren Audit-Eintrag +Simulierter Ausfall des Audit-Dienstes verhindert nicht die Fachfunktion +Nachmeldung nach Ausfallende ist vollständig, keine Lücke im Protokoll" +CMP-05,Compliance-Berichts-Oberfläche,⚖️ Compliance & eDiscovery,Frontend,Mittel,3,3,Fertig,Next.js/React/TypeScript,"Oberfläche zum Anfordern, Einsehen und Herunterladen von GoBD-Verfahrensdokumentation und DSGVO-Berichten je Tenant.",CMP-01 CMP-02,QA-03,"Berichte lassen sich mit wenigen Klicks anfordern und herunterladen +Nur berechtigte Rollen sehen Berichte anderer Personen ein +Historie angeforderter Berichte ist je Tenant einsehbar","Anforderung eines Berichts löst den zugehörigen Backend-Export korrekt aus +Nicht berechtigte Rolle erhält keinen Zugriff auf fremde Berichte +Downloadlink eines abgelaufenen Berichts wird abgewiesen" +CMP-06,Vier-Augen-Freigabe für Löschungen,⚖️ Compliance & eDiscovery,Backend,Mittel,3,4,Fertig,"PostgreSQL mit FOR UPDATE-Lock, Timing-safe Vergleich","Löschung abgelaufener Objekte erfordert eine zweite, unabhängige Bestätigung durch eine andere Person, bevor der Löschworkflow ausgeführt wird.",RET-03,QA-03 CMP-07,"Löschung wird erst nach zweiter Bestätigung durch eine von der anfordernden Person verschiedene Rolle ausgeführt +Gleichzeitige Bestätigungsversuche führen nicht zu doppelter Ausführung +Löschbestätigung wird mit einem geheimen, zeitlich begrenzten Bestätigungs-Token abgesichert","Zwei parallele Bestätigungsanfragen auf dasselbe Objekt: genau eine Löschung wird ausgeführt (Lock-Test) +Bestätigung durch dieselbe Person wie die Anforderung wird abgewiesen +Vergleich des Bestätigungs-Tokens erfolgt zeitkonstant und ist gegen Timing-Angriffe getestet" +BAK-01,Datenbank-Backup-Strategie,💾 Backup & Wiederherstellung,Backend,Mittel,3,1,Fertig,"PostgreSQL (pg_dump/pg_basebackup), inkrementelle Sicherung","Automatisierte, inkrementelle Sicherung der PostgreSQL-Datenbank mit Aufbewahrung mehrerer Generationen und Verifikation jeder Sicherung.",,BAK-03 BAK-05 BAK-07 BAK-09,"Vollsicherung und inkrementelle Sicherung laufen automatisiert nach Zeitplan +Jede Sicherung wird nach Abschluss auf Lesbarkeit verifiziert, nicht nur auf Erstellung geprüft +Mehrere Sicherungsgenerationen werden nach konfigurierbarer Regel vorgehalten und alte automatisch entfernt","Sicherung gegen Testdatenbank erfolgreich erstellt und verifiziert +Verifikation erkennt eine absichtlich beschädigte Sicherungsdatei +Rotationsregel entfernt nachweislich nur die ältesten Generationen" +BAK-02,Objekt-Storage-Backup/Snapshots,💾 Backup & Wiederherstellung,Backend,Mittel,3,1,Fertig,"Objekt-Storage-Snapshots, inkrementell und deduplizierend","Automatisierte, deduplizierende Sicherung der im Objekt-Storage abgelegten Dateiinhalte, angelehnt an das restic/Borg-Sicherungskonzept.",,BAK-03 BAK-05 BAK-07 BAK-09,"Sicherung erfasst neue und geänderte Objekte inkrementell, ohne unveränderte Objekte erneut zu übertragen +Sicherung ist deduplizierend, identische Inhalte werden nur einmal gespeichert +Jede Sicherung lässt sich einzeln auf Vollständigkeit prüfen","Zweiter Sicherungslauf nach unverändertem Bestand überträgt keine Daten erneut +Zwei identische Testdateien belegen nachweislich nur einmal Speicherplatz +Vollständigkeitsprüfung erkennt ein fehlendes Objekt in der Sicherung" +BAK-03,Restore-Verfahren,💾 Backup & Wiederherstellung,Backend,Mittel,3,2,Fertig,Atomarer Restore über temporäres Verzeichnis,"Dokumentiertes, wiederholbares Verfahren zur Wiederherstellung von Datenbank und Objekt-Storage aus einer Sicherung, für Notfall wie für Einzelobjekt-Restore.",BAK-01 BAK-02,BAK-04 BAK-06,"Restore stellt Datenbank und Objekt-Storage aus einer gewählten Sicherungsgeneration wieder her +Restore in ein nicht-leeres Zielverzeichnis beschädigt den bestehenden Inhalt nicht, solange der Vorgang nicht bestätigt wird +Restore-Vorgang wird protokolliert (Quelle, Zeitpunkt, Ergebnis)","Restore auf leerem System vollständig und erfolgreich durchgeführt +Restore auf nicht-leeres Zielverzeichnis lässt bei Abbruch den ursprünglichen Inhalt unverändert +Protokolleintrag zum Restore ist vollständig und nachvollziehbar" +BAK-04,Tenant-Backup & -Restore (einzelner Mandant),💾 Backup & Wiederherstellung,Backend,Mittel,3,3,Fertig,Tenant-scharfer Export/Import auf Basis von BAK-03,"Sicherung und Wiederherstellung der Daten eines einzelnen Mandanten, ohne andere Mandanten zu berühren – etwa für Mandanten-Umzug oder isolierte Notfallwiederherstellung.",BAK-03,QA-04,"Sicherung eines Tenants enthält ausschließlich dessen Daten aus Datenbank und Objekt-Storage +Wiederherstellung eines Tenants verändert keine Daten anderer Tenants +Tenant-Sicherung lässt sich unabhängig vom Gesamt-Backup planen und ausführen","Sicherung von Tenant A enthält keine Datensätze von Tenant B (Stichprobe) +Wiederherstellung von Tenant A in eine Testumgebung verändert Tenant B dort nicht +Tenant-Sicherung und -Restore vollständig protokolliert" +BAK-05,Reconciliation (Konsistenzprüfung Storage vs. DB),💾 Backup & Wiederherstellung,Backend,Mittel,3,2,Fertig,"Geplanter Abgleichs-Job, Postgres-Jobqueue","Periodische Prüfung, ob jeder in der Datenbank referenzierte Objekt-Storage-Eintrag tatsächlich existiert und umgekehrt, mit Bericht über Abweichungen.",BAK-01 BAK-02,QA-04,"Job erkennt Datenbankeinträge ohne zugehöriges Objekt im Storage +Job erkennt Objekte im Storage ohne zugehörigen Datenbankeintrag +Abweichungen werden berichtet, nicht automatisch stillschweigend behoben","Absichtlich entferntes Storage-Objekt wird vom Job als Abweichung erkannt +Absichtlich verwaister Datenbankeintrag wird vom Job als Abweichung erkannt +Lauf ohne Abweichungen liefert einen leeren, eindeutig als sauber erkennbaren Bericht" +BAK-06,Restore-Testverfahren,💾 Backup & Wiederherstellung,Backend,Einfach,2,3,Fertig,"Automatisierter, periodischer Restore-Test in Testumgebung","Regelmäßiger, automatisierter Testlauf des Restore-Verfahrens gegen eine isolierte Testumgebung, mit Ergebnisprotokoll als Nachweis der Wiederherstellbarkeit.",BAK-03,QA-04 BAK-10,"Testlauf führt einen vollständigen Restore in eine isolierte Testumgebung durch +Ergebnis (erfolgreich/fehlgeschlagen) wird mit Zeitstempel protokolliert +Fehlgeschlagener Testlauf löst eine sichtbare Warnung aus","Geplanter Testlauf gegen aktuelle Sicherung erfolgreich durchgeführt und protokolliert +Absichtlich beschädigte Sicherung lässt den Testlauf sichtbar fehlschlagen +Protokollhistorie zeigt mehrere zurückliegende Testläufe nachvollziehbar an" +ANA-01,Kennzahlen-Aggregation (modulübergreifend),📊 Kennzahlen & Reporting,Backend,Mittel,3,3,Fertig,Aggregations-Job über registrierte Module,"Zentraler Dienst, der Kennzahlen (Objektbestand, Aufbewahrungsstatus, Löschvorgänge, Speichervolumen) aus allen über RET-05 registrierten Modulen aggregiert.",RET-05,ANA-02 ANA-03 QA-05,"Kennzahlen werden je Tenant und Modul sowie modulübergreifend aggregiert +Aggregation läuft periodisch und liefert konsistente Werte über einen Zeitverlauf +Neues registriertes Modul wird ohne Codeänderung in die Aggregation einbezogen","Aggregation über zwei fiktive Module liefert korrekte Summen- und Einzelwerte +Wiederholte Aggregation ohne Datenänderung liefert stabile Ergebnisse +Neu registriertes drittes Testmodul erscheint automatisch in der nächsten Aggregation" +ANA-02,Auswertungs-Dashboard,📊 Kennzahlen & Reporting,Frontend,Mittel,3,4,Fertig,Next.js/React/TypeScript,"Dashboard zur Visualisierung der aggregierten Kennzahlen mit Filtern nach Tenant, Modul und Zeitraum.",ANA-01,QA-05,"Dashboard zeigt Bestands-, Aufbewahrungs- und Löschkennzahlen je Tenant +Filter nach Modul und Zeitraum funktionieren kombinierbar +Dashboard lädt auch bei großem Datenbestand in angemessener Zeit","Filterkombination liefert dieselben Werte wie eine direkte Abfrage der Aggregation +Dashboard mit synthetisch großem Testbestand bleibt bedienbar +Rollen ohne Berechtigung sehen keine Kennzahlen fremder Tenants" +ANA-03,Lizenz-/Nutzungs-Reports,📊 Kennzahlen & Reporting,Backend,Einfach,2,4,Fertig,CSV/PDF-Export,"Bericht über Nutzung und Lizenzrelevantes je Tenant (Speichervolumen, aktive Objekte, Nutzeranzahl-Bezug), abgestimmt mit dem Lizenzmodell aus NEXARCH Core.",ANA-01,QA-05,"Bericht zeigt lizenzrelevante Nutzungswerte je Tenant für einen wählbaren Zeitraum +Werte stimmen mit der zugrunde liegenden Kennzahlen-Aggregation überein +Export ist als CSV und PDF verfügbar","Bericht für Testzeitraum stimmt mit manuell nachgerechneten Werten überein +Export in beiden Formaten enthält identische Kernwerte +Bericht für Tenant ohne Aktivität liefert nachvollziehbar leere/Null-Werte statt Fehler" +QA-01,Teststrategie Archive,✅ Prüfungen & Qualitätssicherung,Backend,Einfach,2,1,Fertig,"Testplan-Dokument, Testdatensatz-Konzept","Teststrategie für das Archive-Board festlegen: Testebenen, Referenzdatensatz für Retention/WORM/Backup, Verantwortlichkeiten je Prüfgate.",,,"Teststrategie benennt Testebenen (Unit, Integration, Wiederherstellungstest) und deren Verantwortliche +Referenzdatensatz für Retention- und Backup-Tests ist definiert und wiederverwendbar +Strategie ist als Dokument abgelegt und von zweiter Person gegengelesen +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","Referenzdatensatz lässt sich reproduzierbar in einer Testumgebung aufsetzen +Zweite Person bestätigt schriftlich die Nachvollziehbarkeit der Strategie +Strategie deckt erkennbar alle folgenden Prüfgates ab (Abgleich mit QA-02 bis QA-05)" +QA-02,Prüfgate Retention & WORM,✅ Prüfungen & Qualitätssicherung,Backend,Einfach,2,4,Fertig,Abnahmeprotokoll,"Prüfgate für Fristenengine, Löschworkflow, Aufbewahrungssperre und WORM-Garantie vor Freigabe der Retention-Funktionen.",RET-04 RET-03 RET-06 RET-07,QA-05,"Alle Akzeptanzkriterien von RET-03 und RET-04 sind gegen den Referenzdatensatz nachgewiesen +Versuch, eine gesperrte oder WORM-geschützte Ablage zu umgehen, scheitert nachweislich +Protokoll mit Zielwert, Messwert und Bewertung ist abgelegt","Löschversuch an gesperrtem Objekt schlägt fehl (Wiederholung des RET-03-Tests unter Prüfgate-Bedingungen) +Überschreibversuch am WORM-Speicher schlägt fehl (Wiederholung des RET-04-Tests unter Prüfgate-Bedingungen) +Offene Restrisiken sind schriftlich benannt" +QA-03,Prüfgate Compliance & eDiscovery,✅ Prüfungen & Qualitätssicherung,Backend,Einfach,2,5,Fertig,Abnahmeprotokoll,Prüfgate für eDiscovery-Export und Vier-Augen-Freigabe vor Freigabe der Compliance-Funktionen.,CMP-03 CMP-06 CMP-07 CMP-01 CMP-04 CMP-05,QA-05,"eDiscovery-Export wird gegen den Referenzdatensatz erneut durchgeführt und geprüft +Vier-Augen-Freigabe wird mit zwei unabhängigen Testrollen erneut nachgewiesen +Protokoll mit Zielwert, Messwert und Bewertung ist abgelegt","Export-Prüfsummen stimmen bei wiederholtem Testlauf erneut überein +Löschversuch durch dieselbe Person ohne zweite Bestätigung scheitert erneut +Offene Restrisiken sind schriftlich benannt" +QA-04,Prüfgate Backup & Restore,✅ Prüfungen & Qualitätssicherung,Backend,Einfach,2,4,Fertig,"Abnahmeprotokoll, realer Wiederherstellungstest","Prüfgate für Backup-Strategie und Restore-Verfahren vor Freigabe der Backup-Funktionen, inklusive einem real durchgeführten Wiederherstellungstest.",BAK-06 BAK-04 BAK-05 BAK-07,QA-05,"Restore wird real auf ein leeres Testsystem durchgeführt und dokumentiert +Reconciliation nach Restore zeigt keine Abweichungen zwischen Storage und Datenbank +Protokoll mit Zielwert, Messwert und Bewertung ist abgelegt","Realer Restore-Testlauf erfolgreich und protokolliert +Reconciliation nach dem Testlauf liefert einen sauberen Bericht +Offene Restrisiken sind schriftlich benannt" +QA-05,Abnahme- & Compliance-Prüfung Archive,✅ Prüfungen & Qualitätssicherung,Backend,Einfach,2,6,Fertig,Abnahmeprotokoll,"Gesamtabnahme des Archive-Boards vor Freigabe: Retention/WORM, Compliance/eDiscovery und Backup/Restore müssen alle bestanden sein.",QA-02 QA-03 QA-04 QA-06 QA-07 ANA-01 ANA-02 ANA-03 BAK-08,,"Alle drei fachlichen Prüfgates (QA-02, QA-03, QA-04) sind bestanden +Gesamtprotokoll fasst alle drei Prüfgates mit Ergebnis zusammen +Abnahmeprotokoll ist unterzeichnet","Zusammenfassung aller drei Prüfgates gegen die jeweiligen Einzelprotokolle abgeglichen +Offene Restrisiken aus allen drei Gates sind konsolidiert und schriftlich benannt +Freigabeentscheidung ist dokumentiert" +QA-06,Schnittstellen-Vertragstests,✅ Prüfungen & Qualitätssicherung,Backend,Mittel,3,3,Fertig,"Vertragstests (Consumer-Driven Contracts), CI-Pipeline","Vertragstests für die Modul-Adapter-Schnittstelle (RET-05), über die DMS und Mail Objekte bei der Retention-Engine registrieren – Breaking Changes müssen automatisiert erkannt werden, bevor sie ein konsumierendes Modul stillschweigend bricht.",RET-05,QA-05,"Vertragstests decken RET-05 vollständig ab +Absichtlich brechender Schema-Wechsel lässt Tests fehlschlagen +Tests laufen automatisiert in der CI","Testlauf gegen aktuellen Stand grün +Simulierte Breaking Change erkannt +CI-Integration nachgewiesen" +BAK-07,Aufbewahrungsfrist für Backup-Snapshots,💾 Backup & Wiederherstellung,Backend,Mittel,3,2,Fertig,"PostgreSQL, Postgres-Jobqueue (geplante Jobs statt Redis)","Eigene, von der Dokumenten-Retention (RET-02) unabhängige Aufbewahrungsfrist für Backup-Snapshots selbst – nach restic/Borg-Vorbild eine Prune-Policy (z. B. tägliche Snapshots 14 Tage, wöchentliche 3 Monate, monatliche 1 Jahr – konkrete Staffelung als Konfiguration, nicht hart codiert), damit Backups nicht unbegrenzt wachsen, aber auch nicht zu früh gelöscht werden.",BAK-01 BAK-02,QA-04,"Backup-Snapshots folgen einer konfigurierbaren Prune-Policy (Staffelung nach Alter), unabhängig von RET-02 +Snapshot-Löschung nach Ablauf der Frist läuft automatisiert +Eine gültige, nicht abgelaufene Aufbewahrungssperre auf einem Dokument (RET-03/CMP-06) verhindert nicht das Pruning älterer Backup-Snapshots, solange mindestens ein aktueller Snapshot das Dokument noch enthält","Prune-Test mit simulierten Snapshots über mehrere Altersstufen ergibt korrekte Staffelung +Automatisierte Löschung abgelaufener Snapshots im Test nachgewiesen +Legal-Hold-Test bestätigt, dass Pruning nicht mit Dokumenten-Retention kollidiert" +CMP-07,"DSGVO-Löschantrag (Recht auf Löschung, Art. 17)",⚖️ Compliance & eDiscovery,Backend,Mittel,4,4,Fertig,"PostgreSQL, transaktionaler Zustandswechsel, Modul-Adapter-Schnittstelle (RET-05)","Workflow für den Löschantrag einer betroffenen Person (Art. 17 DSGVO): modulübergreifende Suche (CMP-02), Löschung ohne Aufbewahrungspflicht, begründete Ablehnung mit Aufbewahrungspflicht, Freigabe über CMP-06, vollständiges Protokoll je Objekt.",RET-03 RET-05 CMP-02 CMP-06,QA-03,"Löschantrag findet über die Suche aus CMP-02 alle Objekte einer betroffenen Person, mandantenscharf +Jedes gefundene Objekt wird EINZELN entschieden: Löschung oder Ablehnung mit Begründung – niemals eine pauschale Sammelentscheidung +Tatsächliche Löschung durchläuft denselben Vier-Augen-Freigabeprozess wie jede andere Löschung (CMP-06), keine zweite Implementierung +Ergebnis des Löschantrags (je Objekt: gelöscht/abgelehnt+Grund) ist vollständig und dauerhaft protokolliert","Löschantrag für eine Testperson mit gemischtem Datenbestand liefert exakt eine Löschung und eine begründete Ablehnung +Aufbewahrungssperre (Legal Hold) verhindert die Löschung auch bei bereits abgelaufener regulärer Frist +Löschantrag für einen Tenant führt nachweislich zu keiner Aktion an Objekten eines anderen Tenants" +QA-07,Last- & Leistungstest,✅ Prüfungen & Qualitätssicherung,Backend,Mittel,3,6,Fertig,"Lastgenerator, Messprotokoll","Lasttest für Archive unter realistischer Last aus DMS und Mail gleichzeitig – insbesondere Retention-Prüfpfad (RET-03), Modul-Adapter-Registrierung (RET-05) und WORM-Schreibpfad unter Last.",RET-05 RET-03,QA-05,"Definierte Ziel-Latenz für die Retention-/Legal-Hold-Abfrage unter Last eingehalten +WORM-Schreibpfad bleibt unter simulierter Last aus zwei gleichzeitig zugreifenden Modulen (DMS und Mail) korrekt und ohne Datenverlust +Modul-Adapter-Registrierung (RET-05) verkraftet gleichzeitige Registrierung mehrerer Objekttypen ohne Race Condition","Lasttest mit simulierten parallelen Anfragen aus DMS und Mail durchgeführt, Ergebnis dokumentiert +WORM-Schreibpfad unter Last auf Datenverlust/Race Conditions geprüft +Gleichzeitige Registrierung mehrerer Objekttypen bei RET-05 getestet" +BAK-08,Checksum-basierte Objekt-Integritätsprüfung (Scrub-Job),💾 Backup & Wiederherstellung,Backend,Mittel,3,4,Fertig,"Postgres-Jobqueue (FDN-04), SHA-256-Stream-Prüfung, Meldung über Core OPS-05","Periodischer Job, der Stichproben gespeicherter Objekte herunterlädt, deren SHA-256 neu berechnet und mit der in file_revisions.checksum_sha256 (FDN-02) hinterlegten Prüfsumme vergleicht. Ergänzt BAK-05 (reine Existenzprüfung) um Inhalts-Integrität – deckt stille Korruption und Bit-Rot insbesondere auf extern eingebundenem, nicht selbst überwachtem S3-Storage auf.",BAK-05 FDN-04 FDN-09 OPS-05,,"Job zieht periodisch eine konfigurierbare Stichprobe gespeicherter Objekte, lädt sie, berechnet SHA-256 neu und vergleicht mit file_revisions.checksum_sha256 – Abweichung gilt als Befund +Sampling priorisiert alte, unveränderte Objekte (GoBD-Relevanz: still vergammelnde Bytes, die niemand mehr anfasst, fallen sonst erst beim Restore auf); Neu-Schreibvorgänge sind bereits beim Schreiben verifiziert und werden nicht bevorzugt geprüft +Befund wird gemeldet, nicht automatisch repariert – Meldung läuft über Core OPS-05 (Alerting) mit Objekt-Referenz, erwarteter vs. tatsächlicher Prüfsumme und Zeitpunkt +Job läuft über die Postgres-Jobqueue (FDN-04) mit konfigurierbarer Kadenz und Stichprobengröße; Lauf ist idempotent und unterbrechbar ohne inkonsistenten Zustand +Stichprobengröße und Kadenz sind je Betriebsstufe konfigurierbar, damit ein vollständiger Durchlauf über den Bestand in einem dokumentierten Zeitraum abgeschlossen wird (kein täglicher Voll-Download aller Objekte) +Der Job erkennt Abweichungen nur bei Objekten, die gelesen und erneut geprüft werden können. Er ersetzt keine storage-seitige WORM-/Versionierungsstrategie und keine Zugriffs-/Audit-Logs des Storage-Providers (siehe STORAGE-KONZEPT.md Abschnitt 6.1) — bei extern eingebundenem, nicht-kompatiblem Kunden-Storage (Betriebsmodus 3, ohne Versioning/Object Lock/Audit-Logs) bleibt eine Lücke, die BAK-08 technisch nicht schließen kann.","Testobjekt mit absichtlich manipuliertem Byte im Storage wird als Abweichung erkannt und gemeldet (Alert-Eingang über OPS-05 nachgewiesen) +Unverändertes Testobjekt erzeugt keinen Befund (kein False-Positive) +Verschlüsseltes Testobjekt (über FDN-09) wird korrekt gelesen und geprüft – der Job nutzt denselben Decrypt-Pfad wie reguläre Lesezugriffe, vergleicht also Klartext-Prüfsumme, nicht Chiffretext +Test gegen ein simuliertes externes S3-Ziel (nicht selbst überwacht): Korruption dort wird erkannt – genau der Fall, der sonst unsichtbar bleibt +Sampling-Statistik dokumentiert: Anteil alter vs. neuer Objekte in der Stichprobe entspricht der konfigurierten Priorisierung" +RET-06-API,Aufbewahrungsfristen-Konfigurations-Backend,⏳ Retention & WORM,Backend,Mittel,2,3,Fertig,"Go/net/http, PostgreSQL, provisorischer Rollen-Check (kein RBAC-02-HTTP-Wrapper vorhanden)","Backend-API fuer RET-06: Aufbewahrungsklassen anlegen/aendern/deaktivieren, Vorschauliste ablaufender Objekte. Aus RET-06 herausgeloest (Board-Entscheidung: Backend zuerst, Next.js-Frontend als eigenes Folgeticket), damit kein Pseudo-Frontend-Protokoll entsteht.",RET-02,RET-06,"Aufbewahrungsklasse mit Frist lässt sich per API anlegen, ändern und deaktivieren +API liefert Vorschauliste bald ablaufender Objekte, identisch zum periodischen Job +Änderungen an Fristen sind nur mit gültiger Rollen-Kennung zugänglich (provisorischer Check, echter RBAC-02-HTTP-Wrapper folgt als Core-Ticket)","Änderung einer Frist wirkt sich nur auf künftige Berechnungen aus, nicht rückwirkend +Fehlende/falsche Rollen-Kennung erhält 403, gültige Kennung 200 (Negativ- und Positivtest) +Vorschauliste stimmt mit dem Ergebnis des periodischen Jobs überein" +RET-08,RET-06-API auf RBAC-06 migrieren (Provisorium abbauen),⏳ Retention & WORM,Backend,Klein,1,4,Fertig,"Go, HTTP-Client","internal/retentionapi.RequireRole (Header-basiertes Provisorium aus RET-06-API) durch einen echten Aufruf von Core RBAC-06 (POST /authorize, service-token-authentifiziert) ersetzen. Baut das seit RET-06-API dokumentierte Provisorium ab, jetzt da RBAC-06 real existiert und deployed ist.",RBAC-06 RET-06-API,RET-06,"Der RBAC-Check in retentionapi nutzt ausschliesslich RBAC-06 (HTTP), nicht mehr das lokale Header-Provisorium +Bestehende Endpunkte (POST /retention-classes, POST /retention-classes/{class}/deactivate) verhalten sich funktional unveraendert (gleiche AC wie RET-06-API) +Fehlerfall: RBAC-06 nicht erreichbar oder verweigert -> Zugriff wird abgelehnt (fail closed), nicht stillschweigend erlaubt","403-Nachweis erfolgt gegen echte Policy-Rules ueber RBAC-06, nicht mehr nur gegen einen Header-Wert +Bestehende RET-06-API-Tests (Preview stimmt mit periodischem Job ueberein, Deaktivierung wirkt) laufen weiterhin gruen nach der Migration +Ausfall/Nichterreichbarkeit von RBAC-06 fuehrt zu einer Ablehnung (kein Fallback auf offenen Zugriff)" +RET-09,Modul-Adapter-Dienst starten (RET-05 als laufender HTTP-Endpunkt),⏳ Retention & WORM,Backend,Klein,1,5,Fertig,"Go, HTTP","archive/internal/moduleadapter.RegisterHandler (RET-05) existiert als fertiger Go-Handler, laeuft aber nirgends als Dienst. RET-09 startet ihn als eigenstaendigen HTTP-Dienst (main.go + systemd), OHNE neue Archive-Logik - reines Wiring, analog RBAC-06/CFG-05 fuer andere Module.",RET-05,DOC-16 ARC-11,"moduleadapter.RegisterHandler laeuft als eigenstaendiger, ueber systemd verwalteter HTTP-Dienst +Ein externer Client (anderes Modul) kann real POST /register gegen den laufenden Dienst aufrufen +Keine neue Autorisierungs- oder Registrierungslogik - reiner Start des bestehenden Handlers","Dienst startet und bleibt stabil (systemctl status aktiv) +Realer POST /register von einem externen Testclient gegen den laufenden Dienst liefert die erwartete Registrierung (idempotent, wie in RET-05 getestet) +Code-Review: keine Aenderung an moduleadapter.go/handler.go selbst, nur main.go+systemd neu" +RET-10,CORS für RET-06-API (Frontend-Zugriff aus dem Browser),⏳ Retention & WORM,Backend,Klein,1,5,Fertig,"Go, HTTP-Middleware (CORS)","retention-api (RET-06-API) setzt keine CORS-Header - ein echter Browser blockiert den Fetch von RET-06 (Next.js-Frontend, anderer Origin) zum Backend. Real per Sichtpruefung des laufenden RET-06-Frontends gefunden (curl umgeht CORS, Go-/Vitest-Tests pruefen nicht browserseitig), nicht durch die urspruenglichen RET-06/RET-06-API-Pruefungen erfasst.",RET-06-API,,"retention-api setzt Access-Control-Allow-Origin fuer den konfigurierten Frontend-Origin (Umgebungsvariable, kein Wildcard in Produktion) +Preflight-Anfragen (OPTIONS) werden korrekt beantwortet fuer POST/GET-Endpunkte +RET-06-Frontend kann alle vier Endpunkte real aus einem Browser-Kontext (nicht nur curl) erreichen","Realer Browser-Fetch (nicht curl) vom RET-06-Frontend gegen retention-api gelingt, Same-Origin-Policy nicht mehr blockierend +OPTIONS-Preflight liefert korrekte CORS-Header fuer POST /retention-classes +Fetch von einem NICHT konfigurierten Origin wird weiterhin blockiert (kein Wildcard-Leck)" +RET-11,Storage-seitige WORM-Durchsetzung (Object-Lock statt nur Anwendungslogik),⏳ Retention & WORM,Backend,Mittel,2,7,Fertig,"S3 Object Lock / Compliance-Mode, PostgreSQL, Go","RET-04 verhindert Änderung/Überschreiben archivierter Objektinhalte nach dem Schreiben, aber ohne explizite Festlegung, ob dies nur durch Anwendungscode (übersprungen bei direktem Storage-Zugriff) oder durch eine Storage-seitige Garantie (z. B. S3 Object Lock im Compliance-Mode) erzwungen wird. WORM-Objekte über die Object-Lock-Funktion des Storage-Backends selbst sperren, sodass auch ein Zugriff mit vollen Storage-Zugangsdaten unterhalb der Anwendung keine Änderung/Löschung vor Fristablauf erlaubt.",RET-04,,"Jedes WORM-Objekt wird beim Schreiben mit einer Storage-seitigen Object-Lock-Sperre bis zum Ablauf der Aufbewahrungsfrist versehen +Ein Löschversuch mit direkten Storage-Zugangsdaten (unterhalb der Anwendung) schlägt vor Fristablauf fehl, nachweislich durch das Storage-Backend selbst und nicht nur durch Anwendungscode +Nach Fristablauf und regulärer Freigabe (RET-03) ist das Objekt normal löschbar","Test: direkter Löschversuch über die Storage-API (nicht über die NEXARCH-Anwendung) auf ein gesperrtes Objekt schlägt fehl +Test: nach Fristablauf und Freigabe durch RET-03 ist die Löschung über den regulären Workflow möglich +Konfigurationsprüfung: Object-Lock/Compliance-Mode ist für den produktiven Bucket aktiviert, dokumentiert in der Betriebsanleitung" +RET-12,Unabhängige Tenant-Validierung bei Objekttyp-Registrierung durch DMS/Mail,⏳ Retention & WORM,Backend,Mittel,2,7,Fertig,"Service-Credentials (Core API-02), Tenant-Registry-Abgleich (Core TEN-01), Go","RET-05 nimmt Objekttyp- und Aufbewahrungsklassen-Registrierungen von DMS und Mail entgegen. Ohne unabhängige Prüfung würde Archive dem vom registrierenden Modul mitgelieferten Tenant-Kontext blind vertrauen. Jede Registrierung muss den mitgelieferten Tenant-Kontext gegen die Core-Registry (TEN-01) validieren, unabhängig vom Service-Credential-Scope des aufrufenden Moduls – Archive verlässt sich nicht allein auf die Angabe von DMS/Mail.",RET-05,,"Jede Objekttyp-/Aufbewahrungsklassen-Registrierung aus DMS/Mail wird gegen die Core-Registry auf Tenant-Gültigkeit geprüft, bevor sie übernommen wird +Eine Registrierung mit einem nicht existierenden oder falschem Tenant-Kontext wird abgelehnt und protokolliert +Bestehende, korrekte Registrierungsabläufe aus RET-05 funktionieren unverändert","Test: Registrierung mit gültigem, existierendem Tenant-Kontext wird übernommen +Test: Registrierung mit manipuliertem/fremdem Tenant-Kontext wird abgelehnt +Regressionstest: normaler DMS-/Mail-Registrierungsablauf bleibt funktionsfähig" +BAK-09,Envelope-Encryption für Backup-Snapshots (Datenbank & Objekt-Storage),💾 Backup & Wiederherstellung,Backend,Mittel,2,7,Fertig,"Envelope-Encryption (Tenant-KEK aus Core API-10), restic/Borg-artige Sicherung","BAK-01/BAK-02 sichern Datenbank und Objekt-Storage-Inhalte, ohne festzulegen, ob die Sicherungen selbst verschlüsselt sind. Archivierte Objekte sind live über die Tenant-KEK-Hierarchie (Core API-10) verschlüsselt – Backups dürfen kein schwächer geschütztes Abbild derselben Daten sein. Backup-Snapshots über denselben Tenant-KEK verschlüsseln wie die Live-Daten, sodass ein kompromittiertes Backup-Ziel ohne den jeweiligen Tenant-KEK keine verwertbaren Klartextdaten liefert.",BAK-01 BAK-02,,"Backup-Snapshots von Datenbank und Objekt-Storage sind mit dem Tenant-KEK des jeweiligen Mandanten verschlüsselt +Ein Zugriff auf das Backup-Ziel ohne den jeweiligen Tenant-KEK liefert keine verwertbaren Klartextdaten +Wiederherstellung (BAK-03/BAK-04) funktioniert unverändert unter Verwendung des korrekten Tenant-KEK","Test: Backup-Datei ohne Tenant-KEK ist nicht auswertbar (Stichprobe auf Klartext-Reste) +Restore-Test mit korrektem Tenant-KEK stellt die Daten vollständig wieder her +Test: Restore mit falschem/fremdem Tenant-KEK schlägt fehl, statt fremde Daten zu liefern" +BAK-10,Schutzniveau der Restore-Testumgebung (DSGVO-konform),💾 Backup & Wiederherstellung,Backend,Einfach,1,7,Fertig,"Isolierte Testumgebung, Zugriffskontrolle, Betriebsdokument","BAK-06 testet das Restore-Verfahren regelmäßig automatisiert gegen eine isolierte Testumgebung – diese enthält dabei zwangsläufig echte (wiederhergestellte) Mandantendaten. Ohne festgelegtes Schutzniveau könnte die Testumgebung schwächer abgesichert sein als die Produktivumgebung und so zu einem leichteren Angriffsziel für dieselben Daten werden. Schutzniveau der Testumgebung verbindlich festlegen (gleiche Zugriffskontrolle, Netzwerksegmentierung und Löschfrist nach Testlauf wie produktiv) und dokumentieren.",BAK-06,,"Die Restore-Testumgebung unterliegt derselben Zugriffskontrolle und Netzwerksegmentierung wie die Produktivumgebung +Wiederhergestellte Testdaten werden nach Abschluss des Testlaufs und Protokollierung des Ergebnisses gelöscht, nicht dauerhaft vorgehalten +Das Schutzniveau ist im Betriebsdokument zu BAK-06 explizit festgehalten","Prüft Zugriffskontrolle/Netzwerksegmentierung der Testumgebung gegen die Produktivumgebung +Prüft, dass nach einem Testlauf keine wiederhergestellten Daten über die dokumentierte Frist hinaus verbleiben +Prüft, dass das Betriebsdokument das Schutzniveau explizit benennt" +RET-15,Echter End-zu-Ende-Nachweis Storage-Object-Lock auf chattr-fähigem Host,⏳ Retention & WORM,Backend,Einfach,1,9,Backlog,,,,,chattr-faehiger Host/Alternative identifiziert; Loeschversuch auf storage-gesperrtes Objekt schlaegt nachweislich fehl; Ergebnis als Nachtrag zu RET-11 dokumentiert,Test auf identifiziertem Host durchgefuehrt; falls kein Host verfuegbar begruendete Dokumentation +RET-16,STORAGE-KONZEPT.md: Widerspruch ZFS als WORM-Backend klären,⏳ Retention & WORM,Backend,Einfach,0.5,9,Backlog,,,,,Ausnahmevermerk ZFS fuer WORM-Basisverzeichnis ergaenzt; Verweis auf RET-11-Pruefprotokoll; keine sonstigen Aenderungen,Dokument-Review; Diff-Pruefung +CMP-08,Ende-zu-Ende-Nachweis eDiscovery-Adapter (reale Drittmodul-Integration),⚖️ Compliance & eDiscovery,Backend,Mittel,2,9,Backlog,,,,,eDiscovery-Export gegen echte DMS-/Mail-Testinstanzen; Treffer korrekt und pruefsummengesichert; Nachtrag zu QA-03 dokumentiert,Echter Testlauf dokumentiert; Pruefsummen identisch; offene Restrisiken benannt +SEC-01,"Rolle muss aus verifizierter Identität kommen, nicht aus Client-Header",🔒 Sicherheit,Backend,Hoch,3,10,Backlog,"Go, bestehende Authentifizierungs-Infrastruktur (Session/JWT), Next.js (Frontend-Teil)",Rolle wird in retentionapi/kennzahlenapi/complianceapi aus X-User-Role-Header statt verifizierter Identität gelesen (K3); NEXT_PUBLIC_USER_ROLE im Frontend muss entfernt werden.,,SEC-02,"authz.go liest Rolle ausschliesslich aus verifizierter Identitaet (Session/JWT), X-User-Role wird ignoriert/abgelehnt +NEXT_PUBLIC_USER_ROLE aus compliance-reports und retention-admin Frontend entfernt +requested_by speichert nachvollziehbare Nutzeridentitaet statt nur Rollenname +CORS laesst Rollen-Header-basierte Cross-Origin-Zugriffe nicht mehr zu","Angriff mit gefaelschtem X-User-Role Header real nachgestellt und als blockiert nachgewiesen +Legitimer Aufruf mit echter Rolle aus verifizierter Session funktioniert weiterhin +Audit-Log enthaelt tatsaechliche Nutzeridentitaet +Frontend-Build enthaelt NEXT_PUBLIC_USER_ROLE nachweislich nicht mehr" +SEC-02,Tenant-Validierung in kennzahlenapi fehlt (Cross-Tenant-Leseleck),🔒 Sicherheit,Backend,Niedrig,1,10,Backlog,"Go, bestehendes InstanceTenant-Validierungsmuster aus legalholdapi.go","kennzahlenapi/handler.go:45 validiert den Query-Tenant nicht gegen InstanceTenant (H11), ermoeglicht Cross-Tenant-Lesen von Kennzahlen.",,,"handler.go validiert tenant Query-Parameter gegen InstanceTenant nach Muster aus legalholdapi.go +Abweichung fuehrt zu Ablehnung (403), kein stillschweigendes Ignorieren +Bestehende legitime Aufrufe funktionieren unveraendert","Angriff mit fremdem tenant Query-Parameter real nachgestellt und als blockiert nachgewiesen +Legitimer Aufruf mit eigenem tenant liefert weiterhin korrekte Daten +Musterkonsistenz mit legalholdapi.go dokumentiert" +SEC-03,TOCTOU Legal Hold vs. Destroy; Destroy ausserhalb der aeusseren Transaktion,🔒 Sicherheit,Backend,Mittel,2,10,Backlog,"PostgreSQL, pgx/v5, atomare UPDATE-Bedingungen, Transaktionssteuerung","deletionworkflow.go prueft Legal Hold in separatem Query vor dem Loesch-UPDATE (TOCTOU, M1); deletionapproval.go ruft Destroy ausserhalb der aeusseren Transaktion auf.",,,"Legal-Hold-Pruefung ist Teil derselben atomaren UPDATE-Anweisung wie die Statusaenderung +Destroy() laeuft innerhalb derselben Transaktion wie die Antragsfinalisierung +Kein Codepfad mehr, in dem physische Vernichtung und DB-Zustand auseinanderlaufen","TOCTOU-Fenster real nachgestellt (Legal Hold zwischen Pruefung und Update gesetzt) und als blockiert nachgewiesen +Simulierter Fehler nach Destroy() vor Commit nachgestellt, Konsistenz nachgewiesen +Regulaerer Loeschvorgang ohne Hold und ohne Fehler funktioniert weiterhin" +SEC-04,"wormstore: Release/Destroy ohne Legal-Hold-Pruefung, Reihenfolge-Problem",🔒 Sicherheit,Backend,Mittel,2,10,Backlog,"Go, Dateisystemoperationen, Zwei-Phasen-Commit-Muster, Pfad-Validierung","wormstore.go prueft bei Release/Destroy keinen Legal Hold, physische Operation erfolgt vor DB-Commit (M2); filepath.Join ohne Traversal-Check auf key.",,,"Release/Destroy pruefen vor Ausfuehrung aktiven Legal Hold und verweigern bei Treffer +Physische Operation erfolgt erst nach erfolgreichem DB-Commit bzw. Zwei-Phasen-Commit-Muster verhindert inkonsistenten Zwischenzustand +key wird gegen Pfad-Traversal validiert","Release/Destroy mit aktivem Legal Hold real nachgestellt und als blockiert nachgewiesen +Simulierter Absturz zwischen physischer Operation und Commit nachgestellt, kein inkonsistenter Zustand +Traversal-Angriff mit ../ Segmenten real nachgestellt und als blockiert nachgewiesen +Regulaerer Release/Destroy ohne Hold und ohne Traversal funktioniert weiterhin" +SEC-05,"moduleadapter /register: fehlende Tenant-Bindung, optionale Authentifizierung",🔒 Sicherheit,Backend,Mittel,2,10,Backlog,"PostgreSQL, SQL-Migrationen (kein ORM), Go, bestehende Authentifizierungs-Middleware","UNIQUE(module_name, object_type) ohne Tenant-Spalte (M3) erlaubt Cross-Tenant-Kollision bei Registrierung; ALLOW_UNAUTHENTICATED=true schaltet Auth fuer /register und /legal-hold komplett ab.",,,"UNIQUE-Constraint umfasst Tenant-Spalte, zwei Mandanten koennen denselben module_name/object_type unabhaengig registrieren +Migration ueberfuehrt bestehende Registrierungen korrekt, ist rueckrollbar +ALLOW_UNAUTHENTICATED hat in keiner produktionsnahen Konfiguration Standardwert true +/register und /legal-hold verlangen bei deaktiviertem Schalter gueltige Authentifizierung","Cross-Tenant-Kollision bei Registrierung real nachgestellt, nach Fix bestehen beide Registrierungen unabhaengig +Migration vorwaerts und rueckwaerts gegen Datenbank mit bestehenden Testregistrierungen getestet +Aufruf ohne Authentifizierung bei deaktiviertem Schalter real nachgestellt und als blockiert nachgewiesen +Bestehende authentifizierte Registrierungsablaeufe funktionieren weiterhin" +SEC-06,Append-only-Luecken bei mehreren Archive-Tabellen,🔒 Sicherheit,Backend,Mittel,2,10,Backlog,"PostgreSQL, SQL-Migrationen, bestehendes REVOKE/Trigger-Muster aus RET-11/AUD-07","legal_holds hat ON DELETE CASCADE, retention_class_assignments/dsgvo_decision_log/deletion_requests/worm_objects haben trotz Append-only-Anspruch kein DB-seitiges REVOKE/Trigger (M4).",,,"legal_holds verwendet ON DELETE RESTRICT oder eigene Historisierung statt CASCADE +Betroffene vier Tabellen erhalten REVOKE UPDATE/DELETE von App-Rolle plus Trigger mit RAISE WARNING nach RET-11/AUD-07-Muster +Bestehender Code mit UPDATE/DELETE auf worm_objects auf Insert-only-Logik umgestellt","Direkter UPDATE/DELETE-Versuch auf allen vier Tabellen real nachgestellt und als blockiert/protokolliert nachgewiesen +Loeschen eines Objekts mit aktivem Legal Hold real nachgestellt, Kaskaden-Verlust des Hold-Nachweises verhindert +Migration vorwaerts und rueckwaerts gegen Datenbank mit Testdaten getestet +Umgestellter Anwendungscode fuer worm_objects mit regulaerem Statuswechsel-Testfall erfolgreich durchlaufen" diff --git a/archive-kanban/board.json b/archive-kanban/board.json new file mode 100644 index 00000000..83541a24 --- /dev/null +++ b/archive-kanban/board.json @@ -0,0 +1,1813 @@ +{ + "erzeugtAm": "2026-08-26", + "totalDays": 93, + "epics": [ + { + "key": "RET", + "name": "Retention & WORM", + "emoji": "⏳", + "color": "#B45309", + "description": "Aufbewahrungsfristen, Legal Hold, WORM-Speicher und Modul-Adapter-Schnittstelle für DMS/Mail." + }, + { + "key": "CMP", + "name": "Compliance & eDiscovery", + "emoji": "⚖️", + "color": "#7C3AED", + "description": "GoBD-Verfahrensdokumentation, DSGVO-Berichte, eDiscovery-Export und Vier-Augen-Freigaben." + }, + { + "key": "BAK", + "name": "Backup & Wiederherstellung", + "emoji": "💾", + "color": "#0369A1", + "description": "Datenbank- und Objekt-Storage-Sicherung, Restore-Verfahren und Konsistenzprüfung." + }, + { + "key": "ANA", + "name": "Kennzahlen & Reporting", + "emoji": "📊", + "color": "#A855F7", + "description": "Modulübergreifende Kennzahlen-Aggregation, Auswertungs-Dashboard und Lizenz-/Nutzungs-Reports." + }, + { + "key": "QA", + "name": "Prüfungen & Qualitätssicherung", + "emoji": "✅", + "color": "#16A34A", + "description": "Teststrategie und verbindliche Prüfgates für Retention, Compliance und Backup." + }, + { + "key": "SEC", + "name": "Sicherheit", + "emoji": "🔒", + "color": "#DC2626", + "description": "Security-Review-Folgetickets: RBAC-Härtung, Tenant-Isolation, Legal-Hold-Atomizität, Append-only-Absicherung." + } + ], + "waves": [ + { + "welle": 1, + "codes": [ + "RET-01", + "CMP-04", + "BAK-01", + "BAK-02", + "QA-01" + ] + }, + { + "welle": 2, + "codes": [ + "RET-02", + "RET-04", + "RET-05", + "CMP-01", + "CMP-02", + "BAK-03", + "BAK-05", + "BAK-07" + ] + }, + { + "welle": 3, + "codes": [ + "RET-03", + "RET-06", + "RET-07", + "CMP-03", + "CMP-05", + "BAK-04", + "BAK-06", + "ANA-01", + "QA-06" + ] + }, + { + "welle": 4, + "codes": [ + "CMP-06", + "ANA-02", + "ANA-03", + "QA-02", + "QA-04", + "CMP-07" + ] + }, + { + "welle": 5, + "codes": [ + "QA-03" + ] + }, + { + "welle": 6, + "codes": [ + "QA-05", + "QA-07" + ] + }, + { + "welle": 7, + "codes": [ + "RET-11", + "RET-12", + "BAK-09", + "BAK-10" + ] + } + ], + "kritischerPfad": { + "path": [ + "RET-01", + "RET-02", + "RET-03", + "CMP-06", + "QA-03", + "QA-05" + ], + "days": 16 + }, + "produktDna": { + "uebernehmen": [ + { + "produkt": "Alfresco", + "staerke": "Retention Policies mit Stichtagsberechnung, revisionssichere Ablage und Aufbewahrungssperre (Legal Hold)." + }, + { + "produkt": "Alfresco", + "staerke": "Vier-Augen-Prinzip bei Freigaben, insbesondere bei Löschungen." + }, + { + "produkt": "ecoDMS", + "staerke": "Revisionssicherheit als Grundhaltung: unveränderliches Protokoll, nachvollziehbare Vernichtung." + }, + { + "produkt": "restic/Borg", + "staerke": "Inkrementelle, deduplizierende Sicherung mit eingebauter Verifikation und routinemäßigem Restore-Test." + } + ], + "vermeiden": [ + { + "produkt": "Alfresco – schwergewichtige Plattform mit hohem Ressourcenbedarf und trägem Betrieb.", + "ansatz": "Schlanker Go-Dienst mit Postgres-Jobqueue statt Java-Anwendungsserver und zusätzlicher Message-Queue-Infrastruktur." + } + ] + }, + "epicDna": { + "RET": { + "leitsatz": "Aufbewahrung mit dem Ernst von Alfrescos Retention Policies, aber ohne dessen Ressourcen-Overhead.", + "uebernehmen": [ + "Alfresco: Retention Policies mit Stichtagsberechnung je Objekttyp und automatischem Ablauf.", + "ecoDMS: Revisionssicherheit als Grundhaltung – einmal archiviert, nicht mehr veränderbar.", + "Alfresco: Aufbewahrungssperre (Legal Hold), die jede Löschregel überstimmt." + ], + "vermeiden": [ + "Alfresco – hoher Ressourcen-Overhead der Plattform: schlanker Go-Dienst statt schwergewichtiger Anwendungsserver.", + "Keine modulspezifische Retention-Logik in DMS oder Mail – ein zentraler Adapter für alle Objekttypen." + ] + }, + "CMP": { + "leitsatz": "Nachweisführung wie ecoDMS, Vier-Augen-Prinzip wie Alfresco, aber schlank umgesetzt.", + "uebernehmen": [ + "Alfresco: Vier-Augen-Prinzip bei Freigaben – Löschung nur mit zweiter, unabhängiger Bestätigung.", + "ecoDMS: Nachvollziehbare Vernichtung mit lückenlosem Protokoll.", + "GoBD-konforme Verfahrensdokumentation als exportierbares Dokument, nicht als Prosa-Anhang." + ], + "vermeiden": [ + "Alfresco – Freigabeprozesse mit hoher Konfigurationslast: feste, einfache Vier-Augen-Regel statt konfigurierbarer Workflow-Engine.", + "Keine Berichte, die nur manuell zusammengestellt werden können – jeder Bericht ist ein Exportknopf." + ] + }, + "BAK": { + "leitsatz": "Sicherung nach dem Vorbild von restic/Borg: inkrementell, deduplizierend, verifizierbar.", + "uebernehmen": [ + "restic/Borg: Inkrementelle, deduplizierende Sicherung mit Verifikation jeder Sicherung.", + "restic/Borg: Wiederherstellung ist Routine, nicht Ausnahmefall – regelmäßig getestet.", + "Reconciliation zwischen Objekt-Storage und Datenbank als eigenständige, planbare Prüfung." + ], + "vermeiden": [ + "Keine Sicherung ohne belegten Wiederherstellungstest – eine ungeprüfte Sicherung zählt nicht als Sicherung.", + "Kein Restore, der ein nicht-leeres Zielverzeichnis direkt überschreibt, ohne Atomarität zu garantieren." + ] + }, + "ANA": { + "leitsatz": "Kennzahlen modulübergreifend an einer Stelle, nicht in jedem Modul einzeln nachgebaut.", + "uebernehmen": [ + "Ein Aggregationsdienst für Kennzahlen aus DMS, Mail und Archive statt Silo-Reports je Modul.", + "Dashboard mit Facetten und Filtern statt starrer Report-Vorlagen." + ], + "vermeiden": [ + "Keine Kennzahlenlogik, die doppelt in DMS und Mail gepflegt werden muss." + ] + }, + "QA": { + "leitsatz": "Prüfen heißt messen. Behauptungen ohne Messprotokoll gelten nicht als erledigt.", + "uebernehmen": [ + "Fester Prüfplan je Ausbaustufe mit abgelegtem, nachlesbarem Protokoll.", + "Nachgewiesene Wiederherstellbarkeit als Freigabevoraussetzung." + ], + "vermeiden": [ + "Keine Freigabe auf Zuruf.", + "Keine Prüfung nur auf dem Entwicklungsrechner mit synthetischen Testdaten." + ] + } + }, + "tickets": [ + { + "code": "RET-01", + "title": "Generisches Retention-Objektmodell", + "epic": "RET", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 3, + "tech": "PostgreSQL, pgx/v5, SQL-Migrationen (kein ORM)", + "description": "Generisches Datenmodell für aufbewahrungspflichtige Objekte anlegen: Objekttyp, Objekt-Referenz (modulübergreifend über Adapter), Aufbewahrungsklasse, Status. Migrationen versioniert und rückrollbar.", + "dependsOn": [], + "akzeptanz": [ + "Objektmodell bildet beliebige Objekttypen aus DMS und Mail ab, ohne modulspezifische Spalten", + "Aufbewahrungsklasse ist je Objekt eindeutig zugeordnet und historisierbar", + "Migration läuft gegen leere Datenbank durch und ist rückrollbar" + ], + "pruefungen": [ + "Migration vorwärts und rückwärts getestet", + "Testobjekt aus fiktivem DMS- und Mail-Adapter beide korrekt abgebildet", + "Tenant-Isolation der Kern-Tabellen durch Negativtest belegt" + ], + "status": "Fertig", + "epicName": "Retention & WORM", + "epicEmoji": "⏳", + "wave": 1, + "unlocks": [ + "RET-02", + "RET-04", + "RET-05", + "CMP-01", + "CMP-02" + ], + "prompt": "# RET-01 – Generisches Retention-Objektmodell\n\n**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 1\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nGenerisches Datenmodell für aufbewahrungspflichtige Objekte anlegen: Objekttyp, Objekt-Referenz (modulübergreifend über Adapter), Aufbewahrungsklasse, Status. Migrationen versioniert und rückrollbar.\n\n**Technische Grundlage:** PostgreSQL, pgx/v5, SQL-Migrationen (kein ORM)\n\n## Produkt-DNA für diesen Bereich\n> Aufbewahrung mit dem Ernst von Alfrescos Retention Policies, aber ohne dessen Ressourcen-Overhead.\n\n**Übernehmen:**\n- Alfresco: Retention Policies mit Stichtagsberechnung je Objekttyp und automatischem Ablauf.\n- ecoDMS: Revisionssicherheit als Grundhaltung – einmal archiviert, nicht mehr veränderbar.\n- Alfresco: Aufbewahrungssperre (Legal Hold), die jede Löschregel überstimmt.\n\n**Bewusst vermeiden:**\n- Alfresco – hoher Ressourcen-Overhead der Plattform: schlanker Go-Dienst statt schwergewichtiger Anwendungsserver.\n- Keine modulspezifische Retention-Logik in DMS oder Mail – ein zentraler Adapter für alle Objekttypen.\n\n**Für genau diese Kachel:** Das generische Objektmodell ist die Grundvoraussetzung, damit DMS und Mail keine eigene Retention-Logik bauen müssen.\n\n## Ausgangslage\nDiese Kachel hat keine Vorbedingungen und ist sofort startbar.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Objektmodell bildet beliebige Objekttypen aus DMS und Mail ab, ohne modulspezifische Spalten\n2. Aufbewahrungsklasse ist je Objekt eindeutig zugeordnet und historisierbar\n3. Migration läuft gegen leere Datenbank durch und ist rückrollbar\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. Migration vorwärts und rückwärts getestet\n2. Testobjekt aus fiktivem DMS- und Mail-Adapter beide korrekt abgebildet\n3. Tenant-Isolation der Kern-Tabellen durch Negativtest belegt\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `RET-02` Aufbewahrungsfristen-Engine\n- `RET-04` WORM-Speicher-Garantie (Append-only)\n- `RET-05` Modul-Adapter-Schnittstelle (DMS/Mail registrieren Objekttypen)\n- `CMP-01` GoBD-Verfahrensdokumentation\n- `CMP-02` DSGVO-/Datenschutz-Berichte\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: `RET-01: generisches-retention-objektmodell`\n- Branch: `feature/ret-01-generisches-retention-objektmodell`\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": "RET-02", + "title": "Aufbewahrungsfristen-Engine", + "epic": "RET", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 3, + "tech": "PostgreSQL, Postgres-Jobqueue (geplante Jobs statt Redis)", + "description": "Fristenmodell je Aufbewahrungsklasse mit Stichtagsberechnung (Beginn, Dauer, Ablaufdatum) und periodischem Job, der ablaufende Objekte ermittelt.", + "dependsOn": [ + "RET-01" + ], + "akzeptanz": [ + "Frist wird je Aufbewahrungsklasse konfiguriert und auf jedes zugeordnete Objekt angewendet", + "Stichtag wird korrekt aus Beginn- und Dauerangabe berechnet, inklusive Kalenderfällen (Schaltjahr, Monatsende)", + "Periodischer Job liefert Liste ablaufender Objekte je Tenant" + ], + "pruefungen": [ + "Fristberechnung an Referenzdaten mit bekannten Ablaufdaten geprüft", + "Job liefert bei leerem Bestand ein leeres, nicht fehlerhaftes Ergebnis", + "Mehrfachausführung des Jobs erzeugt keine doppelten Einträge" + ], + "status": "Fertig", + "epicName": "Retention & WORM", + "epicEmoji": "⏳", + "wave": 2, + "unlocks": [ + "RET-03", + "RET-06", + "RET-07" + ], + "prompt": "# RET-02 – Aufbewahrungsfristen-Engine\n\n**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 2\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nFristenmodell je Aufbewahrungsklasse mit Stichtagsberechnung (Beginn, Dauer, Ablaufdatum) und periodischem Job, der ablaufende Objekte ermittelt.\n\n**Technische Grundlage:** PostgreSQL, Postgres-Jobqueue (geplante Jobs statt Redis)\n\n## Produkt-DNA für diesen Bereich\n> Aufbewahrung mit dem Ernst von Alfrescos Retention Policies, aber ohne dessen Ressourcen-Overhead.\n\n**Übernehmen:**\n- Alfresco: Retention Policies mit Stichtagsberechnung je Objekttyp und automatischem Ablauf.\n- ecoDMS: Revisionssicherheit als Grundhaltung – einmal archiviert, nicht mehr veränderbar.\n- Alfresco: Aufbewahrungssperre (Legal Hold), die jede Löschregel überstimmt.\n\n**Bewusst vermeiden:**\n- Alfresco – hoher Ressourcen-Overhead der Plattform: schlanker Go-Dienst statt schwergewichtiger Anwendungsserver.\n- Keine modulspezifische Retention-Logik in DMS oder Mail – ein zentraler Adapter für alle Objekttypen.\n\n**Für genau diese Kachel:** Die Fristenberechnung ist der Kern jeder Aufbewahrungssteuerung – ohne verlässlichen Stichtag ist jede weitere Kachel wertlos.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `RET-01` Generisches Retention-Objektmodell – Generisches Datenmodell für aufbewahrungspflichtige Objekte anlegen: Objekttyp, Objekt-Referenz (modulübergreifend über Adapter), Aufbewahrungsklasse, Status. Migrationen versioniert und rückrollbar.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Frist wird je Aufbewahrungsklasse konfiguriert und auf jedes zugeordnete Objekt angewendet\n2. Stichtag wird korrekt aus Beginn- und Dauerangabe berechnet, inklusive Kalenderfällen (Schaltjahr, Monatsende)\n3. Periodischer Job liefert Liste ablaufender Objekte je Tenant\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. Fristberechnung an Referenzdaten mit bekannten Ablaufdaten geprüft\n2. Job liefert bei leerem Bestand ein leeres, nicht fehlerhaftes Ergebnis\n3. Mehrfachausführung des Jobs erzeugt keine doppelten Einträge\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `RET-03` Löschworkflow & Aufbewahrungssperre (Legal Hold)\n- `RET-06` Aufbewahrungsfristen-Konfigurationsoberfläche\n- `RET-07` Fristablauf-Benachrichtigungen\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: `RET-02: aufbewahrungsfristen-engine`\n- Branch: `feature/ret-02-aufbewahrungsfristen-engine`\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": "RET-03", + "title": "Löschworkflow & Aufbewahrungssperre (Legal Hold)", + "epic": "RET", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 3, + "tech": "PostgreSQL, transaktionaler Zustandswechsel", + "description": "Löschworkflow für abgelaufene Objekte: Freigabe, Vernichtung, Protokolleintrag. Aufbewahrungssperre (Legal Hold) verhindert jede Löschung unabhängig vom Fristablauf.", + "dependsOn": [ + "RET-02" + ], + "akzeptanz": [ + "Ablauf der Frist löst einen Freigabeprozess aus, keine automatische Sofortlöschung", + "Aufbewahrungssperre verhindert Löschung auch bei abgelaufener Frist, mit Begründungspflicht beim Setzen", + "Jede Vernichtung erzeugt einen unveränderlichen Protokolleintrag mit Zeitpunkt und ausführender Person" + ], + "pruefungen": [ + "Objekt mit aktiver Sperre widersteht einem direkten Löschversuch", + "Protokolleintrag nach Vernichtung ist nachträglich nicht änderbar (DB-Constraint oder Trigger)", + "Aufheben einer Sperre ist selbst protokolliert" + ], + "status": "Fertig", + "epicName": "Retention & WORM", + "epicEmoji": "⏳", + "wave": 3, + "unlocks": [ + "CMP-06", + "QA-02", + "CMP-07", + "QA-07" + ], + "prompt": "# RET-03 – Löschworkflow & Aufbewahrungssperre (Legal Hold)\n\n**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 3\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nLöschworkflow für abgelaufene Objekte: Freigabe, Vernichtung, Protokolleintrag. Aufbewahrungssperre (Legal Hold) verhindert jede Löschung unabhängig vom Fristablauf.\n\n**Technische Grundlage:** PostgreSQL, transaktionaler Zustandswechsel\n\n## Produkt-DNA für diesen Bereich\n> Aufbewahrung mit dem Ernst von Alfrescos Retention Policies, aber ohne dessen Ressourcen-Overhead.\n\n**Übernehmen:**\n- Alfresco: Retention Policies mit Stichtagsberechnung je Objekttyp und automatischem Ablauf.\n- ecoDMS: Revisionssicherheit als Grundhaltung – einmal archiviert, nicht mehr veränderbar.\n- Alfresco: Aufbewahrungssperre (Legal Hold), die jede Löschregel überstimmt.\n\n**Bewusst vermeiden:**\n- Alfresco – hoher Ressourcen-Overhead der Plattform: schlanker Go-Dienst statt schwergewichtiger Anwendungsserver.\n- Keine modulspezifische Retention-Logik in DMS oder Mail – ein zentraler Adapter für alle Objekttypen.\n\n**Für genau diese Kachel:** Die Aufbewahrungssperre ist die Notbremse für laufende Verfahren – sie muss stärker sein als jede Fristregel.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `RET-02` Aufbewahrungsfristen-Engine – Fristenmodell je Aufbewahrungsklasse mit Stichtagsberechnung (Beginn, Dauer, Ablaufdatum) und periodischem Job, der ablaufende Objekte ermittelt.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Ablauf der Frist löst einen Freigabeprozess aus, keine automatische Sofortlöschung\n2. Aufbewahrungssperre verhindert Löschung auch bei abgelaufener Frist, mit Begründungspflicht beim Setzen\n3. Jede Vernichtung erzeugt einen unveränderlichen Protokolleintrag mit Zeitpunkt und ausführender Person\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. Objekt mit aktiver Sperre widersteht einem direkten Löschversuch\n2. Protokolleintrag nach Vernichtung ist nachträglich nicht änderbar (DB-Constraint oder Trigger)\n3. Aufheben einer Sperre ist selbst protokolliert\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `CMP-06` Vier-Augen-Freigabe für Löschungen\n- `QA-02` Prüfgate Retention & WORM\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: `RET-03: löschworkflow-und-aufbewahrungssperre-legal-hold`\n- Branch: `feature/ret-03-löschworkflow-und-aufbewahrungssperre-legal-hold`\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": "RET-04", + "title": "WORM-Speicher-Garantie (Append-only)", + "epic": "RET", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 3, + "tech": "Objekt-Storage-Anbindung, Append-only-Schreibpfad", + "description": "Speicherpfad für archivierte Objektinhalte, der nach dem Schreiben keine Änderung und kein Überschreiben mehr zulässt (Write Once, Read Many).", + "dependsOn": [ + "RET-01" + ], + "akzeptanz": [ + "Einmal geschriebener Objektinhalt kann nicht überschrieben werden", + "Loeschung ist ausschliesslich ueber den kontrollierten Loeschworkflow moeglich, nicht ueber die Go-API dieses Pakets (keine Delete-Funktion) - struktureller Schutz auf Anwendungsebene, kein absoluter Schutz gegen root-OS-Zugriff", + "Prüfsumme je Objekt wird beim Schreiben erzeugt und bei jedem Lesezugriff verglichen" + ], + "pruefungen": [ + "Direkter Überschreibversuch am Speicherpfad wird abgewiesen", + "Prüfsummenabgleich erkennt eine manipulierte Testdatei zuverlässig", + "Loeschung ist ueber die Go-API des Pakets technisch unmoeglich (keine Delete-Funktion vorhanden), nicht nur per Konvention verboten" + ], + "status": "Fertig", + "epicName": "Retention & WORM", + "epicEmoji": "⏳", + "wave": 2, + "unlocks": [ + "QA-02", + "RET-11" + ], + "prompt": "# RET-04 – WORM-Speicher-Garantie (Append-only)\n\n**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 2\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nSpeicherpfad für archivierte Objektinhalte, der nach dem Schreiben keine Änderung und kein Überschreiben mehr zulässt (Write Once, Read Many).\n\n**Technische Grundlage:** Objekt-Storage-Anbindung, Append-only-Schreibpfad\n\n## Produkt-DNA für diesen Bereich\n> Aufbewahrung mit dem Ernst von Alfrescos Retention Policies, aber ohne dessen Ressourcen-Overhead.\n\n**Übernehmen:**\n- Alfresco: Retention Policies mit Stichtagsberechnung je Objekttyp und automatischem Ablauf.\n- ecoDMS: Revisionssicherheit als Grundhaltung – einmal archiviert, nicht mehr veränderbar.\n- Alfresco: Aufbewahrungssperre (Legal Hold), die jede Löschregel überstimmt.\n\n**Bewusst vermeiden:**\n- Alfresco – hoher Ressourcen-Overhead der Plattform: schlanker Go-Dienst statt schwergewichtiger Anwendungsserver.\n- Keine modulspezifische Retention-Logik in DMS oder Mail – ein zentraler Adapter für alle Objekttypen.\n\n**Für genau diese Kachel:** WORM ist das technische Rückgrat der Revisionssicherheit – ohne echte Append-only-Garantie bleibt jede Prüfung Theater.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `RET-01` Generisches Retention-Objektmodell – Generisches Datenmodell für aufbewahrungspflichtige Objekte anlegen: Objekttyp, Objekt-Referenz (modulübergreifend über Adapter), Aufbewahrungsklasse, Status. Migrationen versioniert und rückrollbar.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Einmal geschriebener Objektinhalt kann nicht überschrieben werden\n2. Löschung ist ausschließlich über den kontrollierten Löschworkflow möglich, niemals direkt am Speicher\n3. Prüfsumme je Objekt wird beim Schreiben erzeugt und bei jedem Lesezugriff verglichen\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. Direkter Überschreibversuch am Speicherpfad wird abgewiesen\n2. Prüfsummenabgleich erkennt eine manipulierte Testdatei zuverlässig\n3. Löschung außerhalb des Workflows ist technisch unterbunden, nicht nur per Konvention\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `QA-02` Prüfgate Retention & WORM\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: `RET-04: worm-speicher-garantie-append-only`\n- Branch: `feature/ret-04-worm-speicher-garantie-append-only`\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": "RET-05", + "title": "Modul-Adapter-Schnittstelle (DMS/Mail registrieren Objekttypen)", + "epic": "RET", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 3, + "tech": "REST-Schnittstelle, Registrierungs-API", + "description": "Schnittstelle, über die DMS und Mail ihre Objekttypen (Dokument, Mail, Anhang) und die zugehörige Aufbewahrungsklasse bei Archive registrieren, statt eigene Retention-Logik zu bauen.", + "dependsOn": [ + "RET-01" + ], + "akzeptanz": [ + "Modul kann einen Objekttyp mit Aufbewahrungsklasse und Rückruf-Adresse für Löschbestätigung registrieren", + "Archive ruft das registrierte Modul beim Vernichten des Objekts zurück, statt selbst Modul-Interna zu kennen", + "Registrierung ist idempotent und mandantenfähig" + ], + "pruefungen": [ + "Zwei fiktive Module (DMS, Mail) parallel registriert ohne Kollision", + "Rückruf bei Vernichtung erfolgreich gegen einen Testendpunkt ausgeführt", + "Erneute Registrierung desselben Objekttyps ändert nichts am bestehenden Zustand" + ], + "status": "Fertig", + "epicName": "Retention & WORM", + "epicEmoji": "⏳", + "wave": 2, + "unlocks": [ + "CMP-03", + "ANA-01", + "CMP-07", + "QA-07", + "RET-12" + ], + "prompt": "# RET-05 – Modul-Adapter-Schnittstelle (DMS/Mail registrieren Objekttypen)\n\n**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 2\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nSchnittstelle, über die DMS und Mail ihre Objekttypen (Dokument, Mail, Anhang) und die zugehörige Aufbewahrungsklasse bei Archive registrieren, statt eigene Retention-Logik zu bauen.\n\n**Technische Grundlage:** REST-Schnittstelle, Registrierungs-API\n\n## Produkt-DNA für diesen Bereich\n> Aufbewahrung mit dem Ernst von Alfrescos Retention Policies, aber ohne dessen Ressourcen-Overhead.\n\n**Übernehmen:**\n- Alfresco: Retention Policies mit Stichtagsberechnung je Objekttyp und automatischem Ablauf.\n- ecoDMS: Revisionssicherheit als Grundhaltung – einmal archiviert, nicht mehr veränderbar.\n- Alfresco: Aufbewahrungssperre (Legal Hold), die jede Löschregel überstimmt.\n\n**Bewusst vermeiden:**\n- Alfresco – hoher Ressourcen-Overhead der Plattform: schlanker Go-Dienst statt schwergewichtiger Anwendungsserver.\n- Keine modulspezifische Retention-Logik in DMS oder Mail – ein zentraler Adapter für alle Objekttypen.\n\n**Für genau diese Kachel:** Diese Schnittstelle ist der eigentliche Zweck des Boards: DMS und Mail bauen keine eigene Retention-Logik, sondern registrieren sich hier.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `RET-01` Generisches Retention-Objektmodell – Generisches Datenmodell für aufbewahrungspflichtige Objekte anlegen: Objekttyp, Objekt-Referenz (modulübergreifend über Adapter), Aufbewahrungsklasse, Status. Migrationen versioniert und rückrollbar.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Modul kann einen Objekttyp mit Aufbewahrungsklasse und Rückruf-Adresse für Löschbestätigung registrieren\n2. Archive ruft das registrierte Modul beim Vernichten des Objekts zurück, statt selbst Modul-Interna zu kennen\n3. Registrierung ist idempotent und mandantenfähig\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. Zwei fiktive Module (DMS, Mail) parallel registriert ohne Kollision\n2. Rückruf bei Vernichtung erfolgreich gegen einen Testendpunkt ausgeführt\n3. Erneute Registrierung desselben Objekttyps ändert nichts am bestehenden Zustand\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `CMP-03` eDiscovery-Suche & Export (modulübergreifend)\n- `ANA-01` Kennzahlen-Aggregation (modulübergreifend)\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: `RET-05: modul-adapter-schnittstelle-dms-mail-registrieren-objekttypen`\n- Branch: `feature/ret-05-modul-adapter-schnittstelle-dms-mail-registrieren-objekttypen`\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": "RET-06", + "title": "Aufbewahrungsfristen-Konfigurationsoberfläche", + "epic": "RET", + "featureIds": [], + "role": "Frontend", + "complexity": "Mittel", + "estimateDays": 3, + "tech": "Next.js/React/TypeScript", + "description": "Next.js/React-Oberflaeche zur Pflege von Aufbewahrungsklassen und Fristen je Objekttyp und Tenant, inklusive Vorschauliste bald ablaufender Objekte. Backend-API bereits fertig (RET-06-API), RBAC-Provisorium darin durch RET-08 auf echtes RBAC-06 migriert - dieses Ticket ist reiner Frontend-Scope.", + "dependsOn": [ + "RET-02", + "RET-06-API", + "RET-08" + ], + "akzeptanz": [ + "Aufbewahrungsklasse mit Frist lässt sich anlegen, ändern und deaktivieren", + "Vorschauliste zeigt in den nächsten 30 Tagen ablaufende Objekte", + "Änderungen an Fristen sind nur berechtigten Rollen zugänglich" + ], + "pruefungen": [ + "Änderung einer Frist wirkt sich nur auf künftige Berechnungen aus, nicht rückwirkend auf bereits protokollierte Vernichtungen", + "Nicht berechtigte Rolle erhält keinen Zugriff auf die Konfiguration", + "Vorschauliste stimmt mit dem Ergebnis des periodischen Jobs überein" + ], + "status": "Fertig", + "epicName": "Retention & WORM", + "epicEmoji": "⏳", + "wave": 3, + "unlocks": [ + "QA-02" + ], + "prompt": "# RET-06 – Aufbewahrungsfristen-Konfigurationsoberfläche\n\n**Epic:** ⏳ Retention & WORM | **Rolle:** Frontend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 3\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Frontend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nOberfläche und Bedienbarkeit. Ruft ausschließlich vorhandene Schnittstellen auf, keine eigene Geschäftslogik.\n\n## Auftrag\nOberfläche zur Pflege von Aufbewahrungsklassen und Fristen je Objekttyp und Tenant, inklusive Vorschauliste bald ablaufender Objekte.\n\n**Technische Grundlage:** Next.js/React/TypeScript\n\n## Produkt-DNA für diesen Bereich\n> Aufbewahrung mit dem Ernst von Alfrescos Retention Policies, aber ohne dessen Ressourcen-Overhead.\n\n**Übernehmen:**\n- Alfresco: Retention Policies mit Stichtagsberechnung je Objekttyp und automatischem Ablauf.\n- ecoDMS: Revisionssicherheit als Grundhaltung – einmal archiviert, nicht mehr veränderbar.\n- Alfresco: Aufbewahrungssperre (Legal Hold), die jede Löschregel überstimmt.\n\n**Bewusst vermeiden:**\n- Alfresco – hoher Ressourcen-Overhead der Plattform: schlanker Go-Dienst statt schwergewichtiger Anwendungsserver.\n- Keine modulspezifische Retention-Logik in DMS oder Mail – ein zentraler Adapter für alle Objekttypen.\n\n**Für genau diese Kachel:** Ohne Konfigurationsoberfläche bleibt die Fristenengine ein Verwaltungsobjekt für Entwickler statt für Fachanwender.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `RET-02` Aufbewahrungsfristen-Engine – Fristenmodell je Aufbewahrungsklasse mit Stichtagsberechnung (Beginn, Dauer, Ablaufdatum) und periodischem Job, der ablaufende Objekte ermittelt.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Aufbewahrungsklasse mit Frist lässt sich anlegen, ändern und deaktivieren\n2. Vorschauliste zeigt in den nächsten 30 Tagen ablaufende Objekte\n3. Änderungen an Fristen sind nur berechtigten Rollen zugänglich\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. Änderung einer Frist wirkt sich nur auf künftige Berechnungen aus, nicht rückwirkend auf bereits protokollierte Vernichtungen\n2. Nicht berechtigte Rolle erhält keinen Zugriff auf die Konfiguration\n3. Vorschauliste stimmt mit dem Ergebnis des periodischen Jobs überein\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- Alles, was nicht in den Akzeptanzkriterien steht. Keine vorauseilende Umsetzung späterer Anforderungen.\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: `RET-06: aufbewahrungsfristen-konfigurationsoberfläche`\n- Branch: `feature/ret-06-aufbewahrungsfristen-konfigurationsoberfläche`\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": "RET-07", + "title": "Fristablauf-Benachrichtigungen", + "epic": "RET", + "featureIds": [], + "role": "Backend", + "complexity": "Einfach", + "estimateDays": 2, + "tech": "Kopplung an Core CFG-02 (Benachrichtigungs-Dispatcher)", + "description": "Benachrichtigung verantwortlicher Personen vor Ablauf einer Aufbewahrungsfrist, konfigurierbarer Vorlauf je Aufbewahrungsklasse. Der eigentliche Versand läuft ausschließlich über den zentralen Core-Benachrichtigungs-Dispatcher (CFG-02), erreichbar über den HTTP-Wrapper CFG-05 (Archive kann internal/notifyprefs nicht direkt importieren) – Archive erzeugt nur das Ereignis, versendet keine E-Mail selbst. Empfaenger ist eine konfigurierte zustaendige Rolle (Tenant-Admin), kein Objekt-Owner — RET-01 fuehrt bewusst keine Owner-Beziehung.", + "dependsOn": [ + "RET-02", + "CFG-05" + ], + "akzeptanz": [ + "Benachrichtigung wird im konfigurierten Vorlauf vor Fristablauf als Ereignis an Core CFG-02 (ueber CFG-05) uebergeben, adressiert an eine konfigurierte zustaendige Rolle (Tenant-Admin), nicht selbst versendet", + "Mehrfachversand derselben Benachrichtigung wird verhindert", + "Benachrichtigung lässt sich je Aufbewahrungsklasse ein- und ausschalten" + ], + "pruefungen": [ + "Testfrist mit kurzem Vorlauf löst genau eine Benachrichtigung aus", + "Deaktivierte Benachrichtigung verschickt nachweislich nichts", + "Fehlgeschlagener Versand wird protokolliert und nicht stillschweigend verworfen" + ], + "status": "Fertig", + "epicName": "Retention & WORM", + "epicEmoji": "⏳", + "wave": 3, + "unlocks": [ + "QA-02" + ], + "prompt": "# RET-07 – Fristablauf-Benachrichtigungen\n\n**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 2 Personentage | **Welle:** 3\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nBenachrichtigung verantwortlicher Personen vor Ablauf einer Aufbewahrungsfrist, konfigurierbarer Vorlauf je Aufbewahrungsklasse. Der eigentliche Versand läuft ausschließlich über den zentralen Core-Benachrichtigungs-Dispatcher (CFG-02) – Archive erzeugt nur das Ereignis, versendet keine E-Mail selbst.\n\n**Technische Grundlage:** Kopplung an Core CFG-02 (Benachrichtigungs-Dispatcher)\n\n## Produkt-DNA für diesen Bereich\n> Aufbewahrung mit dem Ernst von Alfrescos Retention Policies, aber ohne dessen Ressourcen-Overhead.\n\n**Übernehmen:**\n- Alfresco: Retention Policies mit Stichtagsberechnung je Objekttyp und automatischem Ablauf.\n- ecoDMS: Revisionssicherheit als Grundhaltung – einmal archiviert, nicht mehr veränderbar.\n- Alfresco: Aufbewahrungssperre (Legal Hold), die jede Löschregel überstimmt.\n\n**Bewusst vermeiden:**\n- Alfresco – hoher Ressourcen-Overhead der Plattform: schlanker Go-Dienst statt schwergewichtiger Anwendungsserver.\n- Keine modulspezifische Retention-Logik in DMS oder Mail – ein zentraler Adapter für alle Objekttypen.\n\n**Für genau diese Kachel:** Ohne Vorwarnung verkommt jede Fristenengine zur stillen Uhr, die niemand rechtzeitig liest.\n\n## Ausgangslage\nSetzt voraus (externes Core-Board, siehe /home/sysops/Dokumente/Scripte/nexarch/core-kanban/): `CFG-02` Benachrichtigungs-Dispatcher – zentraler Versandweg für alle Module, kein eigener E-Mail-Versand je Modul.\n\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `RET-02` Aufbewahrungsfristen-Engine – Fristenmodell je Aufbewahrungsklasse mit Stichtagsberechnung (Beginn, Dauer, Ablaufdatum) und periodischem Job, der ablaufende Objekte ermittelt.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Benachrichtigung wird im konfigurierten Vorlauf vor Fristablauf als Ereignis an Core CFG-02 übergeben, nicht selbst versendet\n2. Mehrfachversand derselben Benachrichtigung wird verhindert\n3. Benachrichtigung lässt sich je Aufbewahrungsklasse ein- und ausschalten\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. Testfrist mit kurzem Vorlauf löst genau eine Benachrichtigung aus\n2. Deaktivierte Benachrichtigung verschickt nachweislich nichts\n3. Fehlgeschlagener Versand wird protokolliert und nicht stillschweigend verworfen\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- Alles, was nicht in den Akzeptanzkriterien steht. Keine vorauseilende Umsetzung späterer Anforderungen.\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: `RET-07: fristablauf-benachrichtigungen`\n- Branch: `feature/ret-07-fristablauf-benachrichtigungen`\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": "CMP-01", + "title": "GoBD-Verfahrensdokumentation", + "epic": "CMP", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 3, + "tech": "PDF-Export, versionierte Dokumentvorlage", + "description": "Exportierbare Verfahrensdokumentation gemäß GoBD: Beschreibung der Aufbewahrungs-, Zugriffs- und Löschverfahren, automatisch aus der aktuellen Konfiguration erzeugt.", + "dependsOn": [ + "RET-01" + ], + "akzeptanz": [ + "Dokumentation wird automatisiert aus der aktuellen Retention-Konfiguration erzeugt, nicht manuell gepflegt", + "Export liegt als versioniertes PDF mit Erzeugungsdatum vor", + "Änderung an Aufbewahrungsklassen spiegelt sich in der nächsten Erzeugung wider" + ], + "pruefungen": [ + "Erzeugtes Dokument enthält alle aktiven Aufbewahrungsklassen mit Fristen", + "Zwei aufeinanderfolgende Exporte ohne Konfigurationsänderung sind inhaltlich identisch", + "Export einer zweiten Person als GoBD-tauglich nachvollzogen" + ], + "status": "Fertig", + "epicName": "Compliance & eDiscovery", + "epicEmoji": "⚖️", + "wave": 2, + "unlocks": [ + "CMP-05", + "QA-03" + ], + "prompt": "# CMP-01 – GoBD-Verfahrensdokumentation\n\n**Epic:** ⚖️ Compliance & eDiscovery | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 2\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nExportierbare Verfahrensdokumentation gemäß GoBD: Beschreibung der Aufbewahrungs-, Zugriffs- und Löschverfahren, automatisch aus der aktuellen Konfiguration erzeugt.\n\n**Technische Grundlage:** PDF-Export, versionierte Dokumentvorlage\n\n## Produkt-DNA für diesen Bereich\n> Nachweisführung wie ecoDMS, Vier-Augen-Prinzip wie Alfresco, aber schlank umgesetzt.\n\n**Übernehmen:**\n- Alfresco: Vier-Augen-Prinzip bei Freigaben – Löschung nur mit zweiter, unabhängiger Bestätigung.\n- ecoDMS: Nachvollziehbare Vernichtung mit lückenlosem Protokoll.\n- GoBD-konforme Verfahrensdokumentation als exportierbares Dokument, nicht als Prosa-Anhang.\n\n**Bewusst vermeiden:**\n- Alfresco – Freigabeprozesse mit hoher Konfigurationslast: feste, einfache Vier-Augen-Regel statt konfigurierbarer Workflow-Engine.\n- Keine Berichte, die nur manuell zusammengestellt werden können – jeder Bericht ist ein Exportknopf.\n\n**Für genau diese Kachel:** GoBD verlangt eine nachvollziehbare Verfahrensdokumentation – die hier automatisch statt manuell aktuell gehalten wird.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `RET-01` Generisches Retention-Objektmodell – Generisches Datenmodell für aufbewahrungspflichtige Objekte anlegen: Objekttyp, Objekt-Referenz (modulübergreifend über Adapter), Aufbewahrungsklasse, Status. Migrationen versioniert und rückrollbar.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Dokumentation wird automatisiert aus der aktuellen Retention-Konfiguration erzeugt, nicht manuell gepflegt\n2. Export liegt als versioniertes PDF mit Erzeugungsdatum vor\n3. Änderung an Aufbewahrungsklassen spiegelt sich in der nächsten Erzeugung wider\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. Erzeugtes Dokument enthält alle aktiven Aufbewahrungsklassen mit Fristen\n2. Zwei aufeinanderfolgende Exporte ohne Konfigurationsänderung sind inhaltlich identisch\n3. Export einer zweiten Person als GoBD-tauglich nachvollzogen\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `CMP-05` Compliance-Berichts-Oberfläche\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: `CMP-01: gobd-verfahrensdokumentation`\n- Branch: `feature/cmp-01-gobd-verfahrensdokumentation`\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": "CMP-02", + "title": "DSGVO-/Datenschutz-Berichte", + "epic": "CMP", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 3, + "tech": "PDF/CSV-Export", + "description": "Berichte für Auskunftsersuchen, Verarbeitungsübersichten und Zugriffsnachweise je betroffener Person und Tenant.", + "dependsOn": [ + "RET-01" + ], + "akzeptanz": [ + "Auskunftsbericht listet alle gespeicherten Objekte einer betroffenen Person mit Aufbewahrungsklasse", + "Verarbeitungsübersicht zeigt Zweck und Rechtsgrundlage je Objekttyp", + "Export ist mandantenscharf und enthält keine Daten anderer Tenants" + ], + "pruefungen": [ + "Auskunftsbericht für Testperson mit bekanntem Datenbestand stimmt mit erwarteter Liste überein", + "Bericht für einen Tenant enthält keine Objekte eines anderen Tenants", + "Export lässt sich als CSV weiterverarbeiten" + ], + "status": "Fertig", + "epicName": "Compliance & eDiscovery", + "epicEmoji": "⚖️", + "wave": 2, + "unlocks": [ + "CMP-05", + "CMP-07" + ], + "prompt": "# CMP-02 – DSGVO-/Datenschutz-Berichte\n\n**Epic:** ⚖️ Compliance & eDiscovery | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 2\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nBerichte für Auskunftsersuchen, Verarbeitungsübersichten und Zugriffsnachweise je betroffener Person und Tenant.\n\n**Technische Grundlage:** PDF/CSV-Export\n\n## Produkt-DNA für diesen Bereich\n> Nachweisführung wie ecoDMS, Vier-Augen-Prinzip wie Alfresco, aber schlank umgesetzt.\n\n**Übernehmen:**\n- Alfresco: Vier-Augen-Prinzip bei Freigaben – Löschung nur mit zweiter, unabhängiger Bestätigung.\n- ecoDMS: Nachvollziehbare Vernichtung mit lückenlosem Protokoll.\n- GoBD-konforme Verfahrensdokumentation als exportierbares Dokument, nicht als Prosa-Anhang.\n\n**Bewusst vermeiden:**\n- Alfresco – Freigabeprozesse mit hoher Konfigurationslast: feste, einfache Vier-Augen-Regel statt konfigurierbarer Workflow-Engine.\n- Keine Berichte, die nur manuell zusammengestellt werden können – jeder Bericht ist ein Exportknopf.\n\n**Für genau diese Kachel:** Auskunftsersuchen unter Fristdruck sind der Härtetest – ohne fertigen Bericht wird jede Anfrage zur manuellen Notoperation.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `RET-01` Generisches Retention-Objektmodell – Generisches Datenmodell für aufbewahrungspflichtige Objekte anlegen: Objekttyp, Objekt-Referenz (modulübergreifend über Adapter), Aufbewahrungsklasse, Status. Migrationen versioniert und rückrollbar.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Auskunftsbericht listet alle gespeicherten Objekte einer betroffenen Person mit Aufbewahrungsklasse\n2. Verarbeitungsübersicht zeigt Zweck und Rechtsgrundlage je Objekttyp\n3. Export ist mandantenscharf und enthält keine Daten anderer Tenants\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. Auskunftsbericht für Testperson mit bekanntem Datenbestand stimmt mit erwarteter Liste überein\n2. Bericht für einen Tenant enthält keine Objekte eines anderen Tenants\n3. Export lässt sich als CSV weiterverarbeiten\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `CMP-05` Compliance-Berichts-Oberfläche\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: `CMP-02: dsgvo-datenschutz-berichte`\n- Branch: `feature/cmp-02-dsgvo-datenschutz-berichte`\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": "CMP-03", + "title": "eDiscovery-Suche & Export (modulübergreifend)", + "epic": "CMP", + "featureIds": [], + "role": "Backend", + "complexity": "Komplex", + "estimateDays": 4, + "tech": "Modulübergreifende Such-API, ZIP-Export mit Prüfsummen", + "description": "Suche über registrierte Objekttypen aus DMS und Mail hinweg für Rechtsverfahren, mit vollständigem, prüfsummengesichertem Export der Treffer.", + "dependsOn": [ + "RET-05" + ], + "akzeptanz": [ + "Suche liefert Treffer aus mehreren registrierten Modulen in einer gemeinsamen Ergebnisliste", + "Export enthält Originalobjekte, Metadaten und eine Prüfsummenliste je Datei", + "Suchlauf und Export werden als eigener Vorgang protokolliert (wer, wann, welche Kriterien)" + ], + "pruefungen": [ + "Testsuche über zwei fiktive Module liefert erwartete kombinierte Trefferzahl", + "Prüfsumme jeder exportierten Datei stimmt nach Entpacken überein", + "Protokolleintrag zum Suchlauf ist nachträglich nicht veränderbar" + ], + "status": "Fertig", + "epicName": "Compliance & eDiscovery", + "epicEmoji": "⚖️", + "wave": 3, + "unlocks": [ + "QA-03" + ], + "prompt": "# CMP-03 – eDiscovery-Suche & Export (modulübergreifend)\n\n**Epic:** ⚖️ Compliance & eDiscovery | **Rolle:** Backend | **Komplexität:** Komplex | **Aufwand:** 4 Personentage | **Welle:** 3\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nSuche über registrierte Objekttypen aus DMS und Mail hinweg für Rechtsverfahren, mit vollständigem, prüfsummengesichertem Export der Treffer.\n\n**Technische Grundlage:** Modulübergreifende Such-API, ZIP-Export mit Prüfsummen\n\n## Produkt-DNA für diesen Bereich\n> Nachweisführung wie ecoDMS, Vier-Augen-Prinzip wie Alfresco, aber schlank umgesetzt.\n\n**Übernehmen:**\n- Alfresco: Vier-Augen-Prinzip bei Freigaben – Löschung nur mit zweiter, unabhängiger Bestätigung.\n- ecoDMS: Nachvollziehbare Vernichtung mit lückenlosem Protokoll.\n- GoBD-konforme Verfahrensdokumentation als exportierbares Dokument, nicht als Prosa-Anhang.\n\n**Bewusst vermeiden:**\n- Alfresco – Freigabeprozesse mit hoher Konfigurationslast: feste, einfache Vier-Augen-Regel statt konfigurierbarer Workflow-Engine.\n- Keine Berichte, die nur manuell zusammengestellt werden können – jeder Bericht ist ein Exportknopf.\n\n**Für genau diese Kachel:** eDiscovery ist der Beweis, dass die Modul-Adapter-Schnittstelle trägt: eine Suche, viele Module, ein rechtssicherer Export.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `RET-05` Modul-Adapter-Schnittstelle (DMS/Mail registrieren Objekttypen) – Schnittstelle, über die DMS und Mail ihre Objekttypen (Dokument, Mail, Anhang) und die zugehörige Aufbewahrungsklasse bei Archive registrieren, statt eigene Retention-Logik zu bauen.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Suche liefert Treffer aus mehreren registrierten Modulen in einer gemeinsamen Ergebnisliste\n2. Export enthält Originalobjekte, Metadaten und eine Prüfsummenliste je Datei\n3. Suchlauf und Export werden als eigener Vorgang protokolliert (wer, wann, welche Kriterien)\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. Testsuche über zwei fiktive Module liefert erwartete kombinierte Trefferzahl\n2. Prüfsumme jeder exportierten Datei stimmt nach Entpacken überein\n3. Protokolleintrag zum Suchlauf ist nachträglich nicht veränderbar\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `QA-03` Prüfgate Compliance & eDiscovery\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: `CMP-03: ediscovery-suche-und-export-modulübergreifend`\n- Branch: `feature/cmp-03-ediscovery-suche-und-export-modulübergreifend`\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": "CMP-04", + "title": "Audit-Trail-Kopplung an Core-Audit-Log", + "epic": "CMP", + "featureIds": [], + "role": "Backend", + "complexity": "Einfach", + "estimateDays": 2, + "tech": "REST-Anbindung an NEXARCH Core Audit-Log", + "description": "Alle sicherheitsrelevanten Vorgänge in Archive (Fristsetzung, Sperre, Löschung, Export) werden an das zentrale Audit-Log in NEXARCH Core gemeldet, statt ein eigenes Protokoll zu führen.", + "dependsOn": [ + "AUD-01" + ], + "akzeptanz": [ + "Jeder sicherheitsrelevante Vorgang erzeugt einen Eintrag im zentralen Audit-Log", + "Eintrag enthält Tenant, handelnde Person, Vorgang und Zeitstempel", + "Ausfall des Audit-Log-Dienstes blockiert nicht den Fachvorgang, wird aber sichtbar nachgemeldet" + ], + "pruefungen": [ + "Testvorgänge (Sperre setzen, Löschung, Export) erzeugen je einen nachvollziehbaren Audit-Eintrag", + "Simulierter Ausfall des Audit-Dienstes verhindert nicht die Fachfunktion", + "Nachmeldung nach Ausfallende ist vollständig, keine Lücke im Protokoll" + ], + "status": "Fertig", + "epicName": "Compliance & eDiscovery", + "epicEmoji": "⚖️", + "wave": 1, + "unlocks": [ + "QA-03" + ], + "prompt": "# CMP-04 – Audit-Trail-Kopplung an Core-Audit-Log\n\n**Epic:** ⚖️ Compliance & eDiscovery | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 2 Personentage | **Welle:** 1\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nAlle sicherheitsrelevanten Vorgänge in Archive (Fristsetzung, Sperre, Löschung, Export) werden an das zentrale Audit-Log in NEXARCH Core gemeldet, statt ein eigenes Protokoll zu führen.\n\n**Technische Grundlage:** REST-Anbindung an NEXARCH Core Audit-Log\n\n## Produkt-DNA für diesen Bereich\n> Nachweisführung wie ecoDMS, Vier-Augen-Prinzip wie Alfresco, aber schlank umgesetzt.\n\n**Übernehmen:**\n- Alfresco: Vier-Augen-Prinzip bei Freigaben – Löschung nur mit zweiter, unabhängiger Bestätigung.\n- ecoDMS: Nachvollziehbare Vernichtung mit lückenlosem Protokoll.\n- GoBD-konforme Verfahrensdokumentation als exportierbares Dokument, nicht als Prosa-Anhang.\n\n**Bewusst vermeiden:**\n- Alfresco – Freigabeprozesse mit hoher Konfigurationslast: feste, einfache Vier-Augen-Regel statt konfigurierbarer Workflow-Engine.\n- Keine Berichte, die nur manuell zusammengestellt werden können – jeder Bericht ist ein Exportknopf.\n\n**Für genau diese Kachel:** Ein zentrales Audit-Log statt eines eigenen – Archive dupliziert keine Protokoll-Infrastruktur, die es in Core bereits gibt.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- Core `AUD-01` Zentrales Audit-Log-Modell – Zentrales Audit-Log-Datenmodell für sicherheits- und compliancerelevante Ereignisse (wer, was, wann, an welchem Tenant) als eigenständiges Modell getrennt vom Anwendungs-Log.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Jeder sicherheitsrelevante Vorgang erzeugt einen Eintrag im zentralen Audit-Log\n2. Eintrag enthält Tenant, handelnde Person, Vorgang und Zeitstempel\n3. Ausfall des Audit-Log-Dienstes blockiert nicht den Fachvorgang, wird aber sichtbar nachgemeldet\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. Testvorgänge (Sperre setzen, Löschung, Export) erzeugen je einen nachvollziehbaren Audit-Eintrag\n2. Simulierter Ausfall des Audit-Dienstes verhindert nicht die Fachfunktion\n3. Nachmeldung nach Ausfallende ist vollständig, keine Lücke im Protokoll\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- Alles, was nicht in den Akzeptanzkriterien steht. Keine vorauseilende Umsetzung späterer Anforderungen.\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: `CMP-04: audit-trail-kopplung-an-core-audit-log`\n- Branch: `feature/cmp-04-audit-trail-kopplung-an-core-audit-log`\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": "CMP-05", + "title": "Compliance-Berichts-Oberfläche", + "epic": "CMP", + "featureIds": [], + "role": "Frontend", + "complexity": "Mittel", + "estimateDays": 3, + "tech": "Next.js/React/TypeScript", + "description": "Oberfläche zum Anfordern, Einsehen und Herunterladen von GoBD-Verfahrensdokumentation und DSGVO-Berichten je Tenant.", + "dependsOn": [ + "CMP-01", + "CMP-02" + ], + "akzeptanz": [ + "Berichte lassen sich mit wenigen Klicks anfordern und herunterladen", + "Nur berechtigte Rollen sehen Berichte anderer Personen ein", + "Historie angeforderter Berichte ist je Tenant einsehbar" + ], + "pruefungen": [ + "Anforderung eines Berichts löst den zugehörigen Backend-Export korrekt aus", + "Nicht berechtigte Rolle erhält keinen Zugriff auf fremde Berichte", + "Downloadlink eines abgelaufenen Berichts wird abgewiesen" + ], + "status": "Fertig", + "epicName": "Compliance & eDiscovery", + "epicEmoji": "⚖️", + "wave": 3, + "unlocks": [ + "QA-03" + ], + "prompt": "# CMP-05 – Compliance-Berichts-Oberfläche\n\n**Epic:** ⚖️ Compliance & eDiscovery | **Rolle:** Frontend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 3\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Frontend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nOberfläche und Bedienbarkeit. Ruft ausschließlich vorhandene Schnittstellen auf, keine eigene Geschäftslogik.\n\n## Auftrag\nOberfläche zum Anfordern, Einsehen und Herunterladen von GoBD-Verfahrensdokumentation und DSGVO-Berichten je Tenant.\n\n**Technische Grundlage:** Next.js/React/TypeScript\n\n## Produkt-DNA für diesen Bereich\n> Nachweisführung wie ecoDMS, Vier-Augen-Prinzip wie Alfresco, aber schlank umgesetzt.\n\n**Übernehmen:**\n- Alfresco: Vier-Augen-Prinzip bei Freigaben – Löschung nur mit zweiter, unabhängiger Bestätigung.\n- ecoDMS: Nachvollziehbare Vernichtung mit lückenlosem Protokoll.\n- GoBD-konforme Verfahrensdokumentation als exportierbares Dokument, nicht als Prosa-Anhang.\n\n**Bewusst vermeiden:**\n- Alfresco – Freigabeprozesse mit hoher Konfigurationslast: feste, einfache Vier-Augen-Regel statt konfigurierbarer Workflow-Engine.\n- Keine Berichte, die nur manuell zusammengestellt werden können – jeder Bericht ist ein Exportknopf.\n\n**Für genau diese Kachel:** Ohne Oberfläche bleiben GoBD- und DSGVO-Berichte Kommandozeilen-Werkzeug für Entwickler statt Alltagswerkzeug für Prüfer.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `CMP-01` GoBD-Verfahrensdokumentation – Exportierbare Verfahrensdokumentation gemäß GoBD: Beschreibung der Aufbewahrungs-, Zugriffs- und Löschverfahren, automatisch aus der aktuellen Konfiguration erzeugt.\n- `CMP-02` DSGVO-/Datenschutz-Berichte – Berichte für Auskunftsersuchen, Verarbeitungsübersichten und Zugriffsnachweise je betroffener Person und Tenant.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Berichte lassen sich mit wenigen Klicks anfordern und herunterladen\n2. Nur berechtigte Rollen sehen Berichte anderer Personen ein\n3. Historie angeforderter Berichte ist je Tenant einsehbar\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. Anforderung eines Berichts löst den zugehörigen Backend-Export korrekt aus\n2. Nicht berechtigte Rolle erhält keinen Zugriff auf fremde Berichte\n3. Downloadlink eines abgelaufenen Berichts wird abgewiesen\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- Alles, was nicht in den Akzeptanzkriterien steht. Keine vorauseilende Umsetzung späterer Anforderungen.\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: `CMP-05: compliance-berichts-oberfläche`\n- Branch: `feature/cmp-05-compliance-berichts-oberfläche`\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": "CMP-06", + "title": "Vier-Augen-Freigabe für Löschungen", + "epic": "CMP", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 3, + "tech": "PostgreSQL mit FOR UPDATE-Lock, Timing-safe Vergleich", + "description": "Löschung abgelaufener Objekte erfordert eine zweite, unabhängige Bestätigung durch eine andere Person, bevor der Löschworkflow ausgeführt wird.", + "dependsOn": [ + "RET-03" + ], + "akzeptanz": [ + "Löschung wird erst nach zweiter Bestätigung durch eine von der anfordernden Person verschiedene Rolle ausgeführt", + "Gleichzeitige Bestätigungsversuche führen nicht zu doppelter Ausführung", + "Löschbestätigung wird mit einem geheimen, zeitlich begrenzten Bestätigungs-Token abgesichert" + ], + "pruefungen": [ + "Zwei parallele Bestätigungsanfragen auf dasselbe Objekt: genau eine Löschung wird ausgeführt (Lock-Test)", + "Bestätigung durch dieselbe Person wie die Anforderung wird abgewiesen", + "Vergleich des Bestätigungs-Tokens erfolgt zeitkonstant und ist gegen Timing-Angriffe getestet" + ], + "status": "Fertig", + "epicName": "Compliance & eDiscovery", + "epicEmoji": "⚖️", + "wave": 4, + "unlocks": [ + "QA-03", + "CMP-07" + ], + "prompt": "# CMP-06 – Vier-Augen-Freigabe für Löschungen\n\n**Epic:** ⚖️ Compliance & eDiscovery | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 4\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nLöschung abgelaufener Objekte erfordert eine zweite, unabhängige Bestätigung durch eine andere Person, bevor der Löschworkflow ausgeführt wird.\n\n**Technische Grundlage:** PostgreSQL mit FOR UPDATE-Lock, Timing-safe Vergleich\n\n## Produkt-DNA für diesen Bereich\n> Nachweisführung wie ecoDMS, Vier-Augen-Prinzip wie Alfresco, aber schlank umgesetzt.\n\n**Übernehmen:**\n- Alfresco: Vier-Augen-Prinzip bei Freigaben – Löschung nur mit zweiter, unabhängiger Bestätigung.\n- ecoDMS: Nachvollziehbare Vernichtung mit lückenlosem Protokoll.\n- GoBD-konforme Verfahrensdokumentation als exportierbares Dokument, nicht als Prosa-Anhang.\n\n**Bewusst vermeiden:**\n- Alfresco – Freigabeprozesse mit hoher Konfigurationslast: feste, einfache Vier-Augen-Regel statt konfigurierbarer Workflow-Engine.\n- Keine Berichte, die nur manuell zusammengestellt werden können – jeder Bericht ist ein Exportknopf.\n\n**Für genau diese Kachel:** Vorbild: das Vier-Augen-Muster mit FOR UPDATE-Lock und zeitkonstantem Vergleich aus archivdms hat sich bewährt und wird hier als Standardlösung übernommen, statt es erneut zu erfinden.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `RET-03` Löschworkflow & Aufbewahrungssperre (Legal Hold) – Löschworkflow für abgelaufene Objekte: Freigabe, Vernichtung, Protokolleintrag. Aufbewahrungssperre (Legal Hold) verhindert jede Löschung unabhängig vom Fristablauf.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Löschung wird erst nach zweiter Bestätigung durch eine von der anfordernden Person verschiedene Rolle ausgeführt\n2. Gleichzeitige Bestätigungsversuche führen nicht zu doppelter Ausführung\n3. Löschbestätigung wird mit einem geheimen, zeitlich begrenzten Bestätigungs-Token abgesichert\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. Zwei parallele Bestätigungsanfragen auf dasselbe Objekt: genau eine Löschung wird ausgeführt (Lock-Test)\n2. Bestätigung durch dieselbe Person wie die Anforderung wird abgewiesen\n3. Vergleich des Bestätigungs-Tokens erfolgt zeitkonstant und ist gegen Timing-Angriffe getestet\n\n## Vorbild aus bestehendem System\n\nEin bereits produktives Schwestersystem hat das Vier-Augen-Prinzip bei Löschbestätigung mit einem `FOR UPDATE`-Lock auf dem betroffenen Datensatz und einem zeitkonstanten (timing-safe) Vergleich des Bestätigungs-Tokens umgesetzt. Beides hat sich bewährt und wird hier als Vorbild übernommen: der Lock verhindert doppelte gleichzeitige Ausführung, der zeitkonstante Vergleich verhindert das Erraten des Tokens über Zeitmessung.\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `QA-03` Prüfgate Compliance & eDiscovery\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: `CMP-06: vier-augen-freigabe-für-löschungen`\n- Branch: `feature/cmp-06-vier-augen-freigabe-für-löschungen`\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": "BAK-01", + "title": "Datenbank-Backup-Strategie", + "epic": "BAK", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 3, + "tech": "PostgreSQL (pg_dump/pg_basebackup), inkrementelle Sicherung", + "description": "Automatisierte, inkrementelle Sicherung der PostgreSQL-Datenbank mit Aufbewahrung mehrerer Generationen und Verifikation jeder Sicherung.", + "dependsOn": [], + "akzeptanz": [ + "Vollsicherung und inkrementelle Sicherung laufen automatisiert nach Zeitplan", + "Jede Sicherung wird nach Abschluss auf Lesbarkeit verifiziert, nicht nur auf Erstellung geprüft", + "Mehrere Sicherungsgenerationen werden nach konfigurierbarer Regel vorgehalten und alte automatisch entfernt" + ], + "pruefungen": [ + "Sicherung gegen Testdatenbank erfolgreich erstellt und verifiziert", + "Verifikation erkennt eine absichtlich beschädigte Sicherungsdatei", + "Rotationsregel entfernt nachweislich nur die ältesten Generationen" + ], + "status": "Fertig", + "epicName": "Backup & Wiederherstellung", + "epicEmoji": "💾", + "wave": 1, + "unlocks": [ + "BAK-03", + "BAK-05", + "BAK-07", + "BAK-09" + ], + "prompt": "# BAK-01 – Datenbank-Backup-Strategie\n\n**Epic:** 💾 Backup & Wiederherstellung | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 1\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nAutomatisierte, inkrementelle Sicherung der PostgreSQL-Datenbank mit Aufbewahrung mehrerer Generationen und Verifikation jeder Sicherung.\n\n**Technische Grundlage:** PostgreSQL (pg_dump/pg_basebackup), inkrementelle Sicherung\n\n## Produkt-DNA für diesen Bereich\n> Sicherung nach dem Vorbild von restic/Borg: inkrementell, deduplizierend, verifizierbar.\n\n**Übernehmen:**\n- restic/Borg: Inkrementelle, deduplizierende Sicherung mit Verifikation jeder Sicherung.\n- restic/Borg: Wiederherstellung ist Routine, nicht Ausnahmefall – regelmäßig getestet.\n- Reconciliation zwischen Objekt-Storage und Datenbank als eigenständige, planbare Prüfung.\n\n**Bewusst vermeiden:**\n- Keine Sicherung ohne belegten Wiederherstellungstest – eine ungeprüfte Sicherung zählt nicht als Sicherung.\n- Kein Restore, der ein nicht-leeres Zielverzeichnis direkt überschreibt, ohne Atomarität zu garantieren.\n\n**Für genau diese Kachel:** Ohne verifizierte Sicherung ist jede spätere Wiederherstellung reine Hoffnung – die Verifikation ist deshalb Pflichtbestandteil, nicht Kür.\n\n## Ausgangslage\nDiese Kachel hat keine Vorbedingungen und ist sofort startbar.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Vollsicherung und inkrementelle Sicherung laufen automatisiert nach Zeitplan\n2. Jede Sicherung wird nach Abschluss auf Lesbarkeit verifiziert, nicht nur auf Erstellung geprüft\n3. Mehrere Sicherungsgenerationen werden nach konfigurierbarer Regel vorgehalten und alte automatisch entfernt\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. Sicherung gegen Testdatenbank erfolgreich erstellt und verifiziert\n2. Verifikation erkennt eine absichtlich beschädigte Sicherungsdatei\n3. Rotationsregel entfernt nachweislich nur die ältesten Generationen\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `BAK-03` Restore-Verfahren\n- `BAK-05` Reconciliation (Konsistenzprüfung Storage vs. DB)\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: `BAK-01: datenbank-backup-strategie`\n- Branch: `feature/bak-01-datenbank-backup-strategie`\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": "BAK-02", + "title": "Objekt-Storage-Backup/Snapshots", + "epic": "BAK", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 3, + "tech": "Objekt-Storage-Snapshots, inkrementell und deduplizierend", + "description": "Automatisierte, deduplizierende Sicherung der im Objekt-Storage abgelegten Dateiinhalte, angelehnt an das restic/Borg-Sicherungskonzept.", + "dependsOn": [], + "akzeptanz": [ + "Sicherung erfasst neue und geänderte Objekte inkrementell, ohne unveränderte Objekte erneut zu übertragen", + "Sicherung ist deduplizierend, identische Inhalte werden nur einmal gespeichert", + "Jede Sicherung lässt sich einzeln auf Vollständigkeit prüfen" + ], + "pruefungen": [ + "Zweiter Sicherungslauf nach unverändertem Bestand überträgt keine Daten erneut", + "Zwei identische Testdateien belegen nachweislich nur einmal Speicherplatz", + "Vollständigkeitsprüfung erkennt ein fehlendes Objekt in der Sicherung" + ], + "status": "Fertig", + "epicName": "Backup & Wiederherstellung", + "epicEmoji": "💾", + "wave": 1, + "unlocks": [ + "BAK-03", + "BAK-05", + "BAK-07", + "BAK-09" + ], + "prompt": "# BAK-02 – Objekt-Storage-Backup/Snapshots\n\n**Epic:** 💾 Backup & Wiederherstellung | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 1\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nAutomatisierte, deduplizierende Sicherung der im Objekt-Storage abgelegten Dateiinhalte, angelehnt an das restic/Borg-Sicherungskonzept.\n\n**Technische Grundlage:** Objekt-Storage-Snapshots, inkrementell und deduplizierend\n\n## Produkt-DNA für diesen Bereich\n> Sicherung nach dem Vorbild von restic/Borg: inkrementell, deduplizierend, verifizierbar.\n\n**Übernehmen:**\n- restic/Borg: Inkrementelle, deduplizierende Sicherung mit Verifikation jeder Sicherung.\n- restic/Borg: Wiederherstellung ist Routine, nicht Ausnahmefall – regelmäßig getestet.\n- Reconciliation zwischen Objekt-Storage und Datenbank als eigenständige, planbare Prüfung.\n\n**Bewusst vermeiden:**\n- Keine Sicherung ohne belegten Wiederherstellungstest – eine ungeprüfte Sicherung zählt nicht als Sicherung.\n- Kein Restore, der ein nicht-leeres Zielverzeichnis direkt überschreibt, ohne Atomarität zu garantieren.\n\n**Für genau diese Kachel:** Inkrementell und deduplizierend wie restic/Borg – Sicherungsvolumen und -dauer bleiben auch bei großen Beständen beherrschbar.\n\n## Ausgangslage\nDiese Kachel hat keine Vorbedingungen und ist sofort startbar.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Sicherung erfasst neue und geänderte Objekte inkrementell, ohne unveränderte Objekte erneut zu übertragen\n2. Sicherung ist deduplizierend, identische Inhalte werden nur einmal gespeichert\n3. Jede Sicherung lässt sich einzeln auf Vollständigkeit 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. Zweiter Sicherungslauf nach unverändertem Bestand überträgt keine Daten erneut\n2. Zwei identische Testdateien belegen nachweislich nur einmal Speicherplatz\n3. Vollständigkeitsprüfung erkennt ein fehlendes Objekt in der Sicherung\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `BAK-03` Restore-Verfahren\n- `BAK-05` Reconciliation (Konsistenzprüfung Storage vs. DB)\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: `BAK-02: objekt-storage-backup-snapshots`\n- Branch: `feature/bak-02-objekt-storage-backup-snapshots`\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": "BAK-03", + "title": "Restore-Verfahren", + "epic": "BAK", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 3, + "tech": "Atomarer Restore über temporäres Verzeichnis", + "description": "Dokumentiertes, wiederholbares Verfahren zur Wiederherstellung von Datenbank und Objekt-Storage aus einer Sicherung, für Notfall wie für Einzelobjekt-Restore.", + "dependsOn": [ + "BAK-01", + "BAK-02" + ], + "akzeptanz": [ + "Restore stellt Datenbank und Objekt-Storage aus einer gewählten Sicherungsgeneration wieder her", + "Restore in ein nicht-leeres Zielverzeichnis beschädigt den bestehenden Inhalt nicht, solange der Vorgang nicht bestätigt wird", + "Restore-Vorgang wird protokolliert (Quelle, Zeitpunkt, Ergebnis)" + ], + "pruefungen": [ + "Restore auf leerem System vollständig und erfolgreich durchgeführt", + "Restore auf nicht-leeres Zielverzeichnis lässt bei Abbruch den ursprünglichen Inhalt unverändert", + "Protokolleintrag zum Restore ist vollständig und nachvollziehbar" + ], + "status": "Fertig", + "epicName": "Backup & Wiederherstellung", + "epicEmoji": "💾", + "wave": 2, + "unlocks": [ + "BAK-04", + "BAK-06" + ], + "prompt": "# BAK-03 – Restore-Verfahren\n\n**Epic:** 💾 Backup & Wiederherstellung | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 2\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nDokumentiertes, wiederholbares Verfahren zur Wiederherstellung von Datenbank und Objekt-Storage aus einer Sicherung, für Notfall wie für Einzelobjekt-Restore.\n\n**Technische Grundlage:** Atomarer Restore über temporäres Verzeichnis\n\n## Produkt-DNA für diesen Bereich\n> Sicherung nach dem Vorbild von restic/Borg: inkrementell, deduplizierend, verifizierbar.\n\n**Übernehmen:**\n- restic/Borg: Inkrementelle, deduplizierende Sicherung mit Verifikation jeder Sicherung.\n- restic/Borg: Wiederherstellung ist Routine, nicht Ausnahmefall – regelmäßig getestet.\n- Reconciliation zwischen Objekt-Storage und Datenbank als eigenständige, planbare Prüfung.\n\n**Bewusst vermeiden:**\n- Keine Sicherung ohne belegten Wiederherstellungstest – eine ungeprüfte Sicherung zählt nicht als Sicherung.\n- Kein Restore, der ein nicht-leeres Zielverzeichnis direkt überschreibt, ohne Atomarität zu garantieren.\n\n**Für genau diese Kachel:** Restore ist das eigentliche Produkt einer Sicherung – eine Sicherung ohne funktionierenden Restore ist wertlos.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `BAK-01` Datenbank-Backup-Strategie – Automatisierte, inkrementelle Sicherung der PostgreSQL-Datenbank mit Aufbewahrung mehrerer Generationen und Verifikation jeder Sicherung.\n- `BAK-02` Objekt-Storage-Backup/Snapshots – Automatisierte, deduplizierende Sicherung der im Objekt-Storage abgelegten Dateiinhalte, angelehnt an das restic/Borg-Sicherungskonzept.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Restore stellt Datenbank und Objekt-Storage aus einer gewählten Sicherungsgeneration wieder her\n2. Restore in ein nicht-leeres Zielverzeichnis beschädigt den bestehenden Inhalt nicht, solange der Vorgang nicht bestätigt wird\n3. Restore-Vorgang wird protokolliert (Quelle, Zeitpunkt, Ergebnis)\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. Restore auf leerem System vollständig und erfolgreich durchgeführt\n2. Restore auf nicht-leeres Zielverzeichnis lässt bei Abbruch den ursprünglichen Inhalt unverändert\n3. Protokolleintrag zum Restore ist vollständig und nachvollziehbar\n\n## Bekannte Fehler vermeiden\n\nAus einem bereits produktiven Schwestersystem bekannt: Restore in ein nicht-leeres Zielverzeichnis kann den bestehenden Inhalt beschädigen, wenn nicht atomar vorgegangen wird (`cmd_backup.go:206`, Bug-Klasse „-force restore where destination isn't empty“). Restore deshalb immer in ein leeres temporäres Verzeichnis schreiben und erst danach per atomarem Swap (z. B. Verzeichnis-Rename) an die Zielstelle bringen. Niemals direkt in ein belegtes Zielverzeichnis hineinschreiben.\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `BAK-04` Tenant-Backup & -Restore (einzelner Mandant)\n- `BAK-06` Restore-Testverfahren\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: `BAK-03: restore-verfahren`\n- Branch: `feature/bak-03-restore-verfahren`\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": "BAK-04", + "title": "Tenant-Backup & -Restore (einzelner Mandant)", + "epic": "BAK", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 3, + "tech": "Tenant-scharfer Export/Import auf Basis von BAK-03", + "description": "Sicherung und Wiederherstellung der Daten eines einzelnen Mandanten, ohne andere Mandanten zu berühren – etwa für Mandanten-Umzug oder isolierte Notfallwiederherstellung.", + "dependsOn": [ + "BAK-03" + ], + "akzeptanz": [ + "Sicherung eines Tenants enthält ausschließlich dessen Daten aus Datenbank und Objekt-Storage", + "Wiederherstellung eines Tenants verändert keine Daten anderer Tenants", + "Tenant-Sicherung lässt sich unabhängig vom Gesamt-Backup planen und ausführen" + ], + "pruefungen": [ + "Sicherung von Tenant A enthält keine Datensätze von Tenant B (Stichprobe)", + "Wiederherstellung von Tenant A in eine Testumgebung verändert Tenant B dort nicht", + "Tenant-Sicherung und -Restore vollständig protokolliert" + ], + "status": "Fertig", + "epicName": "Backup & Wiederherstellung", + "epicEmoji": "💾", + "wave": 3, + "unlocks": [ + "QA-04" + ], + "prompt": "# BAK-04 – Tenant-Backup & -Restore (einzelner Mandant)\n\n**Epic:** 💾 Backup & Wiederherstellung | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 3\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nSicherung und Wiederherstellung der Daten eines einzelnen Mandanten, ohne andere Mandanten zu berühren – etwa für Mandanten-Umzug oder isolierte Notfallwiederherstellung.\n\n**Technische Grundlage:** Tenant-scharfer Export/Import auf Basis von BAK-03\n\n## Produkt-DNA für diesen Bereich\n> Sicherung nach dem Vorbild von restic/Borg: inkrementell, deduplizierend, verifizierbar.\n\n**Übernehmen:**\n- restic/Borg: Inkrementelle, deduplizierende Sicherung mit Verifikation jeder Sicherung.\n- restic/Borg: Wiederherstellung ist Routine, nicht Ausnahmefall – regelmäßig getestet.\n- Reconciliation zwischen Objekt-Storage und Datenbank als eigenständige, planbare Prüfung.\n\n**Bewusst vermeiden:**\n- Keine Sicherung ohne belegten Wiederherstellungstest – eine ungeprüfte Sicherung zählt nicht als Sicherung.\n- Kein Restore, der ein nicht-leeres Zielverzeichnis direkt überschreibt, ohne Atomarität zu garantieren.\n\n**Für genau diese Kachel:** Ein Mandant will manchmal umziehen oder isoliert wiederhergestellt werden, ohne dass alle anderen Mandanten betroffen sind.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `BAK-03` Restore-Verfahren – Dokumentiertes, wiederholbares Verfahren zur Wiederherstellung von Datenbank und Objekt-Storage aus einer Sicherung, für Notfall wie für Einzelobjekt-Restore.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Sicherung eines Tenants enthält ausschließlich dessen Daten aus Datenbank und Objekt-Storage\n2. Wiederherstellung eines Tenants verändert keine Daten anderer Tenants\n3. Tenant-Sicherung lässt sich unabhängig vom Gesamt-Backup planen und ausführen\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. Sicherung von Tenant A enthält keine Datensätze von Tenant B (Stichprobe)\n2. Wiederherstellung von Tenant A in eine Testumgebung verändert Tenant B dort nicht\n3. Tenant-Sicherung und -Restore vollständig protokolliert\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- Alles, was nicht in den Akzeptanzkriterien steht. Keine vorauseilende Umsetzung späterer Anforderungen.\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: `BAK-04: tenant-backup-und-restore-einzelner-mandant`\n- Branch: `feature/bak-04-tenant-backup-und-restore-einzelner-mandant`\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": "BAK-05", + "title": "Reconciliation (Konsistenzprüfung Storage vs. DB)", + "epic": "BAK", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 3, + "tech": "Geplanter Abgleichs-Job, Postgres-Jobqueue", + "description": "Periodische Prüfung, ob jeder in der Datenbank referenzierte Objekt-Storage-Eintrag tatsächlich existiert und umgekehrt, mit Bericht über Abweichungen.", + "dependsOn": [ + "BAK-01", + "BAK-02" + ], + "akzeptanz": [ + "Job erkennt Datenbankeinträge ohne zugehöriges Objekt im Storage", + "Job erkennt Objekte im Storage ohne zugehörigen Datenbankeintrag", + "Abweichungen werden berichtet, nicht automatisch stillschweigend behoben" + ], + "pruefungen": [ + "Absichtlich entferntes Storage-Objekt wird vom Job als Abweichung erkannt", + "Absichtlich verwaister Datenbankeintrag wird vom Job als Abweichung erkannt", + "Lauf ohne Abweichungen liefert einen leeren, eindeutig als sauber erkennbaren Bericht" + ], + "status": "Fertig", + "epicName": "Backup & Wiederherstellung", + "epicEmoji": "💾", + "wave": 2, + "unlocks": [ + "QA-04" + ], + "prompt": "# BAK-05 – Reconciliation (Konsistenzprüfung Storage vs. DB)\n\n**Epic:** 💾 Backup & Wiederherstellung | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 2\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nPeriodische Prüfung, ob jeder in der Datenbank referenzierte Objekt-Storage-Eintrag tatsächlich existiert und umgekehrt, mit Bericht über Abweichungen.\n\n**Technische Grundlage:** Geplanter Abgleichs-Job, Postgres-Jobqueue\n\n## Produkt-DNA für diesen Bereich\n> Sicherung nach dem Vorbild von restic/Borg: inkrementell, deduplizierend, verifizierbar.\n\n**Übernehmen:**\n- restic/Borg: Inkrementelle, deduplizierende Sicherung mit Verifikation jeder Sicherung.\n- restic/Borg: Wiederherstellung ist Routine, nicht Ausnahmefall – regelmäßig getestet.\n- Reconciliation zwischen Objekt-Storage und Datenbank als eigenständige, planbare Prüfung.\n\n**Bewusst vermeiden:**\n- Keine Sicherung ohne belegten Wiederherstellungstest – eine ungeprüfte Sicherung zählt nicht als Sicherung.\n- Kein Restore, der ein nicht-leeres Zielverzeichnis direkt überschreibt, ohne Atomarität zu garantieren.\n\n**Für genau diese Kachel:** Sicherung und Datenbank laufen über Jahre leicht auseinander – Reconciliation macht diesen stillen Drift sichtbar, bevor ein Restore daran scheitert.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `BAK-01` Datenbank-Backup-Strategie – Automatisierte, inkrementelle Sicherung der PostgreSQL-Datenbank mit Aufbewahrung mehrerer Generationen und Verifikation jeder Sicherung.\n- `BAK-02` Objekt-Storage-Backup/Snapshots – Automatisierte, deduplizierende Sicherung der im Objekt-Storage abgelegten Dateiinhalte, angelehnt an das restic/Borg-Sicherungskonzept.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Job erkennt Datenbankeinträge ohne zugehöriges Objekt im Storage\n2. Job erkennt Objekte im Storage ohne zugehörigen Datenbankeintrag\n3. Abweichungen werden berichtet, nicht automatisch stillschweigend behoben\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. Absichtlich entferntes Storage-Objekt wird vom Job als Abweichung erkannt\n2. Absichtlich verwaister Datenbankeintrag wird vom Job als Abweichung erkannt\n3. Lauf ohne Abweichungen liefert einen leeren, eindeutig als sauber erkennbaren Bericht\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- Alles, was nicht in den Akzeptanzkriterien steht. Keine vorauseilende Umsetzung späterer Anforderungen.\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: `BAK-05: reconciliation-konsistenzprüfung-storage-vs-db`\n- Branch: `feature/bak-05-reconciliation-konsistenzprüfung-storage-vs-db`\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": "BAK-06", + "title": "Restore-Testverfahren", + "epic": "BAK", + "featureIds": [], + "role": "Backend", + "complexity": "Einfach", + "estimateDays": 2, + "tech": "Automatisierter, periodischer Restore-Test in Testumgebung", + "description": "Regelmäßiger, automatisierter Testlauf des Restore-Verfahrens gegen eine isolierte Testumgebung, mit Ergebnisprotokoll als Nachweis der Wiederherstellbarkeit.", + "dependsOn": [ + "BAK-03" + ], + "akzeptanz": [ + "Testlauf führt einen vollständigen Restore in eine isolierte Testumgebung durch", + "Ergebnis (erfolgreich/fehlgeschlagen) wird mit Zeitstempel protokolliert", + "Fehlgeschlagener Testlauf löst eine sichtbare Warnung aus" + ], + "pruefungen": [ + "Geplanter Testlauf gegen aktuelle Sicherung erfolgreich durchgeführt und protokolliert", + "Absichtlich beschädigte Sicherung lässt den Testlauf sichtbar fehlschlagen", + "Protokollhistorie zeigt mehrere zurückliegende Testläufe nachvollziehbar an" + ], + "status": "Fertig", + "epicName": "Backup & Wiederherstellung", + "epicEmoji": "💾", + "wave": 3, + "unlocks": [ + "QA-04", + "BAK-10" + ], + "prompt": "# BAK-06 – Restore-Testverfahren\n\n**Epic:** 💾 Backup & Wiederherstellung | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 2 Personentage | **Welle:** 3\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nRegelmäßiger, automatisierter Testlauf des Restore-Verfahrens gegen eine isolierte Testumgebung, mit Ergebnisprotokoll als Nachweis der Wiederherstellbarkeit.\n\n**Technische Grundlage:** Automatisierter, periodischer Restore-Test in Testumgebung\n\n## Produkt-DNA für diesen Bereich\n> Sicherung nach dem Vorbild von restic/Borg: inkrementell, deduplizierend, verifizierbar.\n\n**Übernehmen:**\n- restic/Borg: Inkrementelle, deduplizierende Sicherung mit Verifikation jeder Sicherung.\n- restic/Borg: Wiederherstellung ist Routine, nicht Ausnahmefall – regelmäßig getestet.\n- Reconciliation zwischen Objekt-Storage und Datenbank als eigenständige, planbare Prüfung.\n\n**Bewusst vermeiden:**\n- Keine Sicherung ohne belegten Wiederherstellungstest – eine ungeprüfte Sicherung zählt nicht als Sicherung.\n- Kein Restore, der ein nicht-leeres Zielverzeichnis direkt überschreibt, ohne Atomarität zu garantieren.\n\n**Für genau diese Kachel:** Eine Sicherung gilt erst als geprüft, wenn ihr Restore regelmäßig und automatisiert getestet wird – nicht nur einmal beim Einrichten.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `BAK-03` Restore-Verfahren – Dokumentiertes, wiederholbares Verfahren zur Wiederherstellung von Datenbank und Objekt-Storage aus einer Sicherung, für Notfall wie für Einzelobjekt-Restore.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Testlauf führt einen vollständigen Restore in eine isolierte Testumgebung durch\n2. Ergebnis (erfolgreich/fehlgeschlagen) wird mit Zeitstempel protokolliert\n3. Fehlgeschlagener Testlauf löst eine sichtbare Warnung aus\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. Geplanter Testlauf gegen aktuelle Sicherung erfolgreich durchgeführt und protokolliert\n2. Absichtlich beschädigte Sicherung lässt den Testlauf sichtbar fehlschlagen\n3. Protokollhistorie zeigt mehrere zurückliegende Testläufe nachvollziehbar an\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `QA-04` Prüfgate Backup & Restore\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: `BAK-06: restore-testverfahren`\n- Branch: `feature/bak-06-restore-testverfahren`\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": "ANA-01", + "title": "Kennzahlen-Aggregation (modulübergreifend)", + "epic": "ANA", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 3, + "tech": "Aggregations-Job über registrierte Module", + "description": "Zentraler Dienst, der Kennzahlen (Objektbestand, Aufbewahrungsstatus, Löschvorgänge, Speichervolumen) aus allen über RET-05 registrierten Modulen aggregiert.", + "dependsOn": [ + "RET-05" + ], + "akzeptanz": [ + "Kennzahlen werden je Tenant und Modul sowie modulübergreifend aggregiert", + "Aggregation läuft periodisch und liefert konsistente Werte über einen Zeitverlauf", + "Neues registriertes Modul wird ohne Codeänderung in die Aggregation einbezogen" + ], + "pruefungen": [ + "Aggregation über zwei fiktive Module liefert korrekte Summen- und Einzelwerte", + "Wiederholte Aggregation ohne Datenänderung liefert stabile Ergebnisse", + "Neu registriertes drittes Testmodul erscheint automatisch in der nächsten Aggregation" + ], + "status": "Fertig", + "epicName": "Kennzahlen & Reporting", + "epicEmoji": "📊", + "wave": 3, + "unlocks": [ + "ANA-02", + "ANA-03", + "QA-05" + ], + "prompt": "# ANA-01 – Kennzahlen-Aggregation (modulübergreifend)\n\n**Epic:** 📊 Kennzahlen & Reporting | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 3\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nZentraler Dienst, der Kennzahlen (Objektbestand, Aufbewahrungsstatus, Löschvorgänge, Speichervolumen) aus allen über RET-05 registrierten Modulen aggregiert.\n\n**Technische Grundlage:** Aggregations-Job über registrierte Module\n\n## Produkt-DNA für diesen Bereich\n> Kennzahlen modulübergreifend an einer Stelle, nicht in jedem Modul einzeln nachgebaut.\n\n**Übernehmen:**\n- Ein Aggregationsdienst für Kennzahlen aus DMS, Mail und Archive statt Silo-Reports je Modul.\n- Dashboard mit Facetten und Filtern statt starrer Report-Vorlagen.\n\n**Bewusst vermeiden:**\n- Keine Kennzahlenlogik, die doppelt in DMS und Mail gepflegt werden muss.\n\n**Für genau diese Kachel:** Eine Aggregationsstelle für alle Module – DMS und Mail bauen keine eigene Kennzahlenlogik mehr.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `RET-05` Modul-Adapter-Schnittstelle (DMS/Mail registrieren Objekttypen) – Schnittstelle, über die DMS und Mail ihre Objekttypen (Dokument, Mail, Anhang) und die zugehörige Aufbewahrungsklasse bei Archive registrieren, statt eigene Retention-Logik zu bauen.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Kennzahlen werden je Tenant und Modul sowie modulübergreifend aggregiert\n2. Aggregation läuft periodisch und liefert konsistente Werte über einen Zeitverlauf\n3. Neues registriertes Modul wird ohne Codeänderung in die Aggregation einbezogen\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. Aggregation über zwei fiktive Module liefert korrekte Summen- und Einzelwerte\n2. Wiederholte Aggregation ohne Datenänderung liefert stabile Ergebnisse\n3. Neu registriertes drittes Testmodul erscheint automatisch in der nächsten Aggregation\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `ANA-02` Auswertungs-Dashboard\n- `ANA-03` Lizenz-/Nutzungs-Reports\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: `ANA-01: kennzahlen-aggregation-modulübergreifend`\n- Branch: `feature/ana-01-kennzahlen-aggregation-modulübergreifend`\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": "ANA-02", + "title": "Auswertungs-Dashboard", + "epic": "ANA", + "featureIds": [], + "role": "Frontend", + "complexity": "Mittel", + "estimateDays": 3, + "tech": "Next.js/React/TypeScript", + "description": "Dashboard zur Visualisierung der aggregierten Kennzahlen mit Filtern nach Tenant, Modul und Zeitraum.", + "dependsOn": [ + "ANA-01" + ], + "akzeptanz": [ + "Dashboard zeigt Bestands-, Aufbewahrungs- und Löschkennzahlen je Tenant", + "Filter nach Modul und Zeitraum funktionieren kombinierbar", + "Dashboard lädt auch bei großem Datenbestand in angemessener Zeit" + ], + "pruefungen": [ + "Filterkombination liefert dieselben Werte wie eine direkte Abfrage der Aggregation", + "Dashboard mit synthetisch großem Testbestand bleibt bedienbar", + "Rollen ohne Berechtigung sehen keine Kennzahlen fremder Tenants" + ], + "status": "Fertig", + "epicName": "Kennzahlen & Reporting", + "epicEmoji": "📊", + "wave": 4, + "unlocks": [ + "QA-05" + ], + "prompt": "# ANA-02 – Auswertungs-Dashboard\n\n**Epic:** 📊 Kennzahlen & Reporting | **Rolle:** Frontend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 4\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Frontend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nOberfläche und Bedienbarkeit. Ruft ausschließlich vorhandene Schnittstellen auf, keine eigene Geschäftslogik.\n\n## Auftrag\nDashboard zur Visualisierung der aggregierten Kennzahlen mit Filtern nach Tenant, Modul und Zeitraum.\n\n**Technische Grundlage:** Next.js/React/TypeScript\n\n## Produkt-DNA für diesen Bereich\n> Kennzahlen modulübergreifend an einer Stelle, nicht in jedem Modul einzeln nachgebaut.\n\n**Übernehmen:**\n- Ein Aggregationsdienst für Kennzahlen aus DMS, Mail und Archive statt Silo-Reports je Modul.\n- Dashboard mit Facetten und Filtern statt starrer Report-Vorlagen.\n\n**Bewusst vermeiden:**\n- Keine Kennzahlenlogik, die doppelt in DMS und Mail gepflegt werden muss.\n\n**Für genau diese Kachel:** Kennzahlen ohne Dashboard bleiben Rohdaten – erst die Visualisierung macht sie für Fachanwender nutzbar.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `ANA-01` Kennzahlen-Aggregation (modulübergreifend) – Zentraler Dienst, der Kennzahlen (Objektbestand, Aufbewahrungsstatus, Löschvorgänge, Speichervolumen) aus allen über RET-05 registrierten Modulen aggregiert.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Dashboard zeigt Bestands-, Aufbewahrungs- und Löschkennzahlen je Tenant\n2. Filter nach Modul und Zeitraum funktionieren kombinierbar\n3. Dashboard lädt auch bei großem Datenbestand in angemessener Zeit\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. Filterkombination liefert dieselben Werte wie eine direkte Abfrage der Aggregation\n2. Dashboard mit synthetisch großem Testbestand bleibt bedienbar\n3. Rollen ohne Berechtigung sehen keine Kennzahlen fremder Tenants\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- Alles, was nicht in den Akzeptanzkriterien steht. Keine vorauseilende Umsetzung späterer Anforderungen.\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: `ANA-02: auswertungs-dashboard`\n- Branch: `feature/ana-02-auswertungs-dashboard`\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": "ANA-03", + "title": "Lizenz-/Nutzungs-Reports", + "epic": "ANA", + "featureIds": [], + "role": "Backend", + "complexity": "Einfach", + "estimateDays": 2, + "tech": "CSV/PDF-Export", + "description": "Bericht über Nutzung und Lizenzrelevantes je Tenant (Speichervolumen, aktive Objekte, Nutzeranzahl-Bezug), abgestimmt mit dem Lizenzmodell aus NEXARCH Core.", + "dependsOn": [ + "ANA-01" + ], + "akzeptanz": [ + "Bericht zeigt lizenzrelevante Nutzungswerte je Tenant für einen wählbaren Zeitraum", + "Werte stimmen mit der zugrunde liegenden Kennzahlen-Aggregation überein", + "Export ist als CSV und PDF verfügbar" + ], + "pruefungen": [ + "Bericht für Testzeitraum stimmt mit manuell nachgerechneten Werten überein", + "Export in beiden Formaten enthält identische Kernwerte", + "Bericht für Tenant ohne Aktivität liefert nachvollziehbar leere/Null-Werte statt Fehler" + ], + "status": "Fertig", + "epicName": "Kennzahlen & Reporting", + "epicEmoji": "📊", + "wave": 4, + "unlocks": [ + "QA-05" + ], + "prompt": "# ANA-03 – Lizenz-/Nutzungs-Reports\n\n**Epic:** 📊 Kennzahlen & Reporting | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 2 Personentage | **Welle:** 4\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nBericht über Nutzung und Lizenzrelevantes je Tenant (Speichervolumen, aktive Objekte, Nutzeranzahl-Bezug), abgestimmt mit dem Lizenzmodell aus NEXARCH Core.\n\n**Technische Grundlage:** CSV/PDF-Export\n\n## Produkt-DNA für diesen Bereich\n> Kennzahlen modulübergreifend an einer Stelle, nicht in jedem Modul einzeln nachgebaut.\n\n**Übernehmen:**\n- Ein Aggregationsdienst für Kennzahlen aus DMS, Mail und Archive statt Silo-Reports je Modul.\n- Dashboard mit Facetten und Filtern statt starrer Report-Vorlagen.\n\n**Bewusst vermeiden:**\n- Keine Kennzahlenlogik, die doppelt in DMS und Mail gepflegt werden muss.\n\n**Für genau diese Kachel:** Lizenzrelevante Nutzungswerte gehören sauber belegt vorzuliegen, statt bei Bedarf händisch aus Rohdaten geschätzt zu werden.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `ANA-01` Kennzahlen-Aggregation (modulübergreifend) – Zentraler Dienst, der Kennzahlen (Objektbestand, Aufbewahrungsstatus, Löschvorgänge, Speichervolumen) aus allen über RET-05 registrierten Modulen aggregiert.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Bericht zeigt lizenzrelevante Nutzungswerte je Tenant für einen wählbaren Zeitraum\n2. Werte stimmen mit der zugrunde liegenden Kennzahlen-Aggregation überein\n3. Export ist als CSV und PDF verfügbar\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. Bericht für Testzeitraum stimmt mit manuell nachgerechneten Werten überein\n2. Export in beiden Formaten enthält identische Kernwerte\n3. Bericht für Tenant ohne Aktivität liefert nachvollziehbar leere/Null-Werte statt Fehler\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- Alles, was nicht in den Akzeptanzkriterien steht. Keine vorauseilende Umsetzung späterer Anforderungen.\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: `ANA-03: lizenz-nutzungs-reports`\n- Branch: `feature/ana-03-lizenz-nutzungs-reports`\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": "QA-01", + "title": "Teststrategie Archive", + "epic": "QA", + "featureIds": [], + "role": "Backend", + "complexity": "Einfach", + "estimateDays": 2, + "tech": "Testplan-Dokument, Testdatensatz-Konzept", + "description": "Teststrategie für das Archive-Board festlegen: Testebenen, Referenzdatensatz für Retention/WORM/Backup, Verantwortlichkeiten je Prüfgate.", + "dependsOn": [], + "akzeptanz": [ + "Teststrategie benennt Testebenen (Unit, Integration, Wiederherstellungstest) und deren Verantwortliche", + "Referenzdatensatz für Retention- und Backup-Tests ist definiert und wiederverwendbar", + "Strategie ist als Dokument abgelegt und von zweiter Person gegengelesen", + "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" + ], + "pruefungen": [ + "Referenzdatensatz lässt sich reproduzierbar in einer Testumgebung aufsetzen", + "Zweite Person bestätigt schriftlich die Nachvollziehbarkeit der Strategie", + "Strategie deckt erkennbar alle folgenden Prüfgates ab (Abgleich mit QA-02 bis QA-05)" + ], + "status": "Fertig", + "epicName": "Prüfungen & Qualitätssicherung", + "epicEmoji": "✅", + "wave": 1, + "unlocks": [], + "prompt": "# QA-01 – Teststrategie Archive\n\n**Epic:** ✅ Prüfungen & Qualitätssicherung | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 2 Personentage | **Welle:** 1\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nTeststrategie für das Archive-Board festlegen: Testebenen, Referenzdatensatz für Retention/WORM/Backup, Verantwortlichkeiten je Prüfgate.\n\n**Technische Grundlage:** Testplan-Dokument, Testdatensatz-Konzept\n\n## Produkt-DNA für diesen Bereich\n> Prüfen heißt messen. Behauptungen ohne Messprotokoll gelten nicht als erledigt.\n\n**Übernehmen:**\n- Fester Prüfplan je Ausbaustufe mit abgelegtem, nachlesbarem Protokoll.\n- Nachgewiesene Wiederherstellbarkeit als Freigabevoraussetzung.\n\n**Bewusst vermeiden:**\n- Keine Freigabe auf Zuruf.\n- Keine Prüfung nur auf dem Entwicklungsrechner mit synthetischen Testdaten.\n\n**Für genau diese Kachel:** Ohne gemeinsame Teststrategie prüft jedes Prüfgate nach eigenem Gutdünken – das Fundament für vergleichbare Prüfergebnisse.\n\n## Ausgangslage\nDiese Kachel hat keine Vorbedingungen und ist sofort startbar.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Teststrategie benennt Testebenen (Unit, Integration, Wiederherstellungstest) und deren Verantwortliche\n2. Referenzdatensatz für Retention- und Backup-Tests ist definiert und wiederverwendbar\n3. Strategie ist als Dokument abgelegt und von zweiter Person gegengelesen\n\n4. 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\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. Referenzdatensatz lässt sich reproduzierbar in einer Testumgebung aufsetzen\n2. Zweite Person bestätigt schriftlich die Nachvollziehbarkeit der Strategie\n3. Strategie deckt erkennbar alle folgenden Prüfgates ab (Abgleich mit QA-02 bis QA-06)\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- Alles, was nicht in den Akzeptanzkriterien steht. Keine vorauseilende Umsetzung späterer Anforderungen.\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: `QA-01: teststrategie-archive`\n- Branch: `feature/qa-01-teststrategie-archive`\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": "QA-02", + "title": "Prüfgate Retention & WORM", + "epic": "QA", + "featureIds": [], + "role": "Backend", + "complexity": "Einfach", + "estimateDays": 2, + "tech": "Abnahmeprotokoll", + "description": "Prüfgate für Fristenengine, Löschworkflow, Aufbewahrungssperre und WORM-Garantie vor Freigabe der Retention-Funktionen.", + "dependsOn": [ + "RET-04", + "RET-03", + "RET-06", + "RET-07" + ], + "akzeptanz": [ + "Alle Akzeptanzkriterien von RET-03 und RET-04 sind gegen den Referenzdatensatz nachgewiesen", + "Versuch, eine gesperrte oder WORM-geschützte Ablage zu umgehen, scheitert nachweislich", + "Protokoll mit Zielwert, Messwert und Bewertung ist abgelegt" + ], + "pruefungen": [ + "Löschversuch an gesperrtem Objekt schlägt fehl (Wiederholung des RET-03-Tests unter Prüfgate-Bedingungen)", + "Überschreibversuch am WORM-Speicher schlägt fehl (Wiederholung des RET-04-Tests unter Prüfgate-Bedingungen)", + "Offene Restrisiken sind schriftlich benannt" + ], + "status": "Fertig", + "epicName": "Prüfungen & Qualitätssicherung", + "epicEmoji": "✅", + "wave": 4, + "unlocks": [ + "QA-05" + ], + "prompt": "# QA-02 – Prüfgate Retention & WORM\n\n**Epic:** ✅ Prüfungen & Qualitätssicherung | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 2 Personentage | **Welle:** 4\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nPrüfgate für Fristenengine, Löschworkflow, Aufbewahrungssperre und WORM-Garantie vor Freigabe der Retention-Funktionen.\n\n**Technische Grundlage:** Abnahmeprotokoll\n\n## Produkt-DNA für diesen Bereich\n> Prüfen heißt messen. Behauptungen ohne Messprotokoll gelten nicht als erledigt.\n\n**Übernehmen:**\n- Fester Prüfplan je Ausbaustufe mit abgelegtem, nachlesbarem Protokoll.\n- Nachgewiesene Wiederherstellbarkeit als Freigabevoraussetzung.\n\n**Bewusst vermeiden:**\n- Keine Freigabe auf Zuruf.\n- Keine Prüfung nur auf dem Entwicklungsrechner mit synthetischen Testdaten.\n\n**Für genau diese Kachel:** Ein eigenes Gate für Retention und WORM, weil hier die Kernversprechen des gesamten Boards stehen und Wiederholungen unter Prüfbedingungen zählen.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `RET-04` WORM-Speicher-Garantie (Append-only) – Speicherpfad für archivierte Objektinhalte, der nach dem Schreiben keine Änderung und kein Überschreiben mehr zulässt (Write Once, Read Many).\n- `RET-03` Löschworkflow & Aufbewahrungssperre (Legal Hold) – Löschworkflow für abgelaufene Objekte: Freigabe, Vernichtung, Protokolleintrag. Aufbewahrungssperre (Legal Hold) verhindert jede Löschung unabhängig vom Fristablauf.\n- `RET-06` Aufbewahrungsfristen-Konfigurationsoberfläche – Oberfläche zur Pflege von Aufbewahrungsklassen und Fristen je Objekttyp und Tenant, inklusive Vorschauliste bald ablaufender Objekte.\n- `RET-07` Fristablauf-Benachrichtigungen – Benachrichtigung verantwortlicher Personen vor Ablauf einer Aufbewahrungsfrist, konfigurierbarer Vorlauf je Aufbewahrungsklasse. Der eigentliche Versand läuft ausschließlich über den zentralen Core-Benachrichtigungs-Dispatcher (CFG-02) – Archive erzeugt nur das Ereignis, versendet keine E-Mail selbst.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Alle Akzeptanzkriterien von RET-03 und RET-04 sind gegen den Referenzdatensatz nachgewiesen\n2. Versuch, eine gesperrte oder WORM-geschützte Ablage zu umgehen, scheitert nachweislich\n3. Protokoll mit Zielwert, Messwert und Bewertung ist abgelegt\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. Löschversuch an gesperrtem Objekt schlägt fehl (Wiederholung des RET-03-Tests unter Prüfgate-Bedingungen)\n2. Überschreibversuch am WORM-Speicher schlägt fehl (Wiederholung des RET-04-Tests unter Prüfgate-Bedingungen)\n3. Offene Restrisiken sind schriftlich benannt\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `QA-05` Abnahme- & Compliance-Prüfung Archive\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: `QA-02: prüfgate-retention-und-worm`\n- Branch: `feature/qa-02-prüfgate-retention-und-worm`\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": "QA-03", + "title": "Prüfgate Compliance & eDiscovery", + "epic": "QA", + "featureIds": [], + "role": "Backend", + "complexity": "Einfach", + "estimateDays": 2, + "tech": "Abnahmeprotokoll", + "description": "Prüfgate für eDiscovery-Export und Vier-Augen-Freigabe vor Freigabe der Compliance-Funktionen.", + "dependsOn": [ + "CMP-03", + "CMP-06", + "CMP-07", + "CMP-01", + "CMP-04", + "CMP-05" + ], + "akzeptanz": [ + "eDiscovery-Export wird gegen den Referenzdatensatz erneut durchgeführt und geprüft", + "Vier-Augen-Freigabe wird mit zwei unabhängigen Testrollen erneut nachgewiesen", + "Protokoll mit Zielwert, Messwert und Bewertung ist abgelegt" + ], + "pruefungen": [ + "Export-Prüfsummen stimmen bei wiederholtem Testlauf erneut überein", + "Löschversuch durch dieselbe Person ohne zweite Bestätigung scheitert erneut", + "Offene Restrisiken sind schriftlich benannt" + ], + "status": "Fertig", + "epicName": "Prüfungen & Qualitätssicherung", + "epicEmoji": "✅", + "wave": 5, + "unlocks": [ + "QA-05" + ], + "prompt": "# QA-03 – Prüfgate Compliance & eDiscovery\n\n**Epic:** ✅ Prüfungen & Qualitätssicherung | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 2 Personentage | **Welle:** 5\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nPrüfgate für eDiscovery-Export und Vier-Augen-Freigabe vor Freigabe der Compliance-Funktionen.\n\n**Technische Grundlage:** Abnahmeprotokoll\n\n## Produkt-DNA für diesen Bereich\n> Prüfen heißt messen. Behauptungen ohne Messprotokoll gelten nicht als erledigt.\n\n**Übernehmen:**\n- Fester Prüfplan je Ausbaustufe mit abgelegtem, nachlesbarem Protokoll.\n- Nachgewiesene Wiederherstellbarkeit als Freigabevoraussetzung.\n\n**Bewusst vermeiden:**\n- Keine Freigabe auf Zuruf.\n- Keine Prüfung nur auf dem Entwicklungsrechner mit synthetischen Testdaten.\n\n**Für genau diese Kachel:** Compliance-Funktionen entscheiden im Ernstfall vor Gericht oder Aufsichtsbehörde – ein eigenes Gate stellt das vor Freigabe sicher.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `CMP-03` eDiscovery-Suche & Export (modulübergreifend) – Suche über registrierte Objekttypen aus DMS und Mail hinweg für Rechtsverfahren, mit vollständigem, prüfsummengesichertem Export der Treffer.\n- `CMP-06` Vier-Augen-Freigabe für Löschungen – Löschung abgelaufener Objekte erfordert eine zweite, unabhängige Bestätigung durch eine andere Person, bevor der Löschworkflow ausgeführt wird.\n- `CMP-07` DSGVO-Löschantrag (Recht auf Löschung, Art. 17) – Workflow für den Löschantrag einer betroffenen Person (Art. 17 DSGVO): modulübergreifende Suche (CMP-02), Löschung ohne Aufbewahrungspflicht, begründete Ablehnung mit Aufbewahrungspflicht, Freigabe über CMP-06, vollständiges Protokoll je Objekt.\n- `CMP-01` GoBD-Verfahrensdokumentation – Exportierbare Verfahrensdokumentation gemäß GoBD: Beschreibung der Aufbewahrungs-, Zugriffs- und Löschverfahren, automatisch aus der aktuellen Konfiguration erzeugt.\n- `CMP-04` Audit-Trail-Kopplung an Core-Audit-Log – Alle sicherheitsrelevanten Vorgänge in Archive (Fristsetzung, Sperre, Löschung, Export) werden an das zentrale Audit-Log in NEXARCH Core gemeldet, statt ein eigenes Protokoll zu führen.\n- `CMP-05` Compliance-Berichts-Oberfläche – Oberfläche zum Anfordern, Einsehen und Herunterladen von GoBD-Verfahrensdokumentation und DSGVO-Berichten je Tenant.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. eDiscovery-Export wird gegen den Referenzdatensatz erneut durchgeführt und geprüft\n2. Vier-Augen-Freigabe wird mit zwei unabhängigen Testrollen erneut nachgewiesen\n3. Protokoll mit Zielwert, Messwert und Bewertung ist abgelegt\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. Export-Prüfsummen stimmen bei wiederholtem Testlauf erneut überein\n2. Löschversuch durch dieselbe Person ohne zweite Bestätigung scheitert erneut\n3. Offene Restrisiken sind schriftlich benannt\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `QA-05` Abnahme- & Compliance-Prüfung Archive\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: `QA-03: prüfgate-compliance-und-ediscovery`\n- Branch: `feature/qa-03-prüfgate-compliance-und-ediscovery`\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": "QA-04", + "title": "Prüfgate Backup & Restore", + "epic": "QA", + "featureIds": [], + "role": "Backend", + "complexity": "Einfach", + "estimateDays": 2, + "tech": "Abnahmeprotokoll, realer Wiederherstellungstest", + "description": "Prüfgate für Backup-Strategie und Restore-Verfahren vor Freigabe der Backup-Funktionen, inklusive einem real durchgeführten Wiederherstellungstest.", + "dependsOn": [ + "BAK-06", + "BAK-04", + "BAK-05", + "BAK-07" + ], + "akzeptanz": [ + "Restore wird real auf ein leeres Testsystem durchgeführt und dokumentiert", + "Reconciliation nach Restore zeigt keine Abweichungen zwischen Storage und Datenbank", + "Protokoll mit Zielwert, Messwert und Bewertung ist abgelegt" + ], + "pruefungen": [ + "Realer Restore-Testlauf erfolgreich und protokolliert", + "Reconciliation nach dem Testlauf liefert einen sauberen Bericht", + "Offene Restrisiken sind schriftlich benannt" + ], + "status": "Fertig", + "epicName": "Prüfungen & Qualitätssicherung", + "epicEmoji": "✅", + "wave": 4, + "unlocks": [ + "QA-05" + ], + "prompt": "# QA-04 – Prüfgate Backup & Restore\n\n**Epic:** ✅ Prüfungen & Qualitätssicherung | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 2 Personentage | **Welle:** 4\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nPrüfgate für Backup-Strategie und Restore-Verfahren vor Freigabe der Backup-Funktionen, inklusive einem real durchgeführten Wiederherstellungstest.\n\n**Technische Grundlage:** Abnahmeprotokoll, realer Wiederherstellungstest\n\n## Produkt-DNA für diesen Bereich\n> Prüfen heißt messen. Behauptungen ohne Messprotokoll gelten nicht als erledigt.\n\n**Übernehmen:**\n- Fester Prüfplan je Ausbaustufe mit abgelegtem, nachlesbarem Protokoll.\n- Nachgewiesene Wiederherstellbarkeit als Freigabevoraussetzung.\n\n**Bewusst vermeiden:**\n- Keine Freigabe auf Zuruf.\n- Keine Prüfung nur auf dem Entwicklungsrechner mit synthetischen Testdaten.\n\n**Für genau diese Kachel:** Backup ohne real durchgeführten Restore-Test ist eine unbelegte Behauptung – dieses Gate erzwingt den Beleg.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `BAK-06` Restore-Testverfahren – Regelmäßiger, automatisierter Testlauf des Restore-Verfahrens gegen eine isolierte Testumgebung, mit Ergebnisprotokoll als Nachweis der Wiederherstellbarkeit.\n- `BAK-04` Tenant-Backup & -Restore (einzelner Mandant) – Sicherung und Wiederherstellung der Daten eines einzelnen Mandanten, ohne andere Mandanten zu berühren – etwa für Mandanten-Umzug oder isolierte Notfallwiederherstellung.\n- `BAK-05` Reconciliation (Konsistenzprüfung Storage vs. DB) – Periodische Prüfung, ob jeder in der Datenbank referenzierte Objekt-Storage-Eintrag tatsächlich existiert und umgekehrt, mit Bericht über Abweichungen.\n- `BAK-07` Aufbewahrungsfrist für Backup-Snapshots – Eigene, von der Dokumenten-Retention (RET-02) unabhängige Aufbewahrungsfrist für Backup-Snapshots selbst – nach restic/Borg-Vorbild eine Prune-Policy (z. B. tägliche Snapshots 14 Tage, wöchentliche 3 Monate, monatliche 1 Jahr – konkrete Staffelung als Konfiguration, nicht hart codiert), damit Backups nicht unbegrenzt wachsen, aber auch nicht zu früh gelöscht werden.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Restore wird real auf ein leeres Testsystem durchgeführt und dokumentiert\n2. Reconciliation nach Restore zeigt keine Abweichungen zwischen Storage und Datenbank\n3. Protokoll mit Zielwert, Messwert und Bewertung ist abgelegt\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. Realer Restore-Testlauf erfolgreich und protokolliert\n2. Reconciliation nach dem Testlauf liefert einen sauberen Bericht\n3. Offene Restrisiken sind schriftlich benannt\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `QA-05` Abnahme- & Compliance-Prüfung Archive\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: `QA-04: prüfgate-backup-und-restore`\n- Branch: `feature/qa-04-prüfgate-backup-und-restore`\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": "QA-05", + "title": "Abnahme- & Compliance-Prüfung Archive", + "epic": "QA", + "featureIds": [], + "role": "Backend", + "complexity": "Einfach", + "estimateDays": 2, + "tech": "Abnahmeprotokoll", + "description": "Gesamtabnahme des Archive-Boards vor Freigabe: Retention/WORM, Compliance/eDiscovery und Backup/Restore müssen alle bestanden sein.", + "dependsOn": [ + "QA-02", + "QA-03", + "QA-04", + "QA-06", + "QA-07", + "ANA-01", + "ANA-02", + "ANA-03", + "BAK-08" + ], + "akzeptanz": [ + "Alle drei fachlichen Prüfgates (QA-02, QA-03, QA-04) sind bestanden", + "Gesamtprotokoll fasst alle drei Prüfgates mit Ergebnis zusammen", + "Abnahmeprotokoll ist unterzeichnet" + ], + "pruefungen": [ + "Zusammenfassung aller drei Prüfgates gegen die jeweiligen Einzelprotokolle abgeglichen", + "Offene Restrisiken aus allen drei Gates sind konsolidiert und schriftlich benannt", + "Freigabeentscheidung ist dokumentiert" + ], + "status": "Fertig", + "epicName": "Prüfungen & Qualitätssicherung", + "epicEmoji": "✅", + "wave": 6, + "unlocks": [], + "prompt": "# QA-05 – Abnahme- & Compliance-Prüfung Archive\n\n**Epic:** ✅ Prüfungen & Qualitätssicherung | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 2 Personentage | **Welle:** 6\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nGesamtabnahme des Archive-Boards vor Freigabe: Retention/WORM, Compliance/eDiscovery und Backup/Restore müssen alle bestanden sein.\n\n**Technische Grundlage:** Abnahmeprotokoll\n\n## Produkt-DNA für diesen Bereich\n> Prüfen heißt messen. Behauptungen ohne Messprotokoll gelten nicht als erledigt.\n\n**Übernehmen:**\n- Fester Prüfplan je Ausbaustufe mit abgelegtem, nachlesbarem Protokoll.\n- Nachgewiesene Wiederherstellbarkeit als Freigabevoraussetzung.\n\n**Bewusst vermeiden:**\n- Keine Freigabe auf Zuruf.\n- Keine Prüfung nur auf dem Entwicklungsrechner mit synthetischen Testdaten.\n\n**Für genau diese Kachel:** Erst wenn Retention, Compliance und Backup einzeln bestanden sind, ist Archive insgesamt freigabefähig – diese Kachel bündelt den Nachweis.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `QA-02` Prüfgate Retention & WORM – Prüfgate für Fristenengine, Löschworkflow, Aufbewahrungssperre und WORM-Garantie vor Freigabe der Retention-Funktionen.\n- `QA-03` Prüfgate Compliance & eDiscovery – Prüfgate für eDiscovery-Export und Vier-Augen-Freigabe vor Freigabe der Compliance-Funktionen.\n- `QA-04` Prüfgate Backup & Restore – Prüfgate für Backup-Strategie und Restore-Verfahren vor Freigabe der Backup-Funktionen, inklusive einem real durchgeführten Wiederherstellungstest.\n- `QA-06` Schnittstellen-Vertragstests – Vertragstests für die Modul-Adapter-Schnittstelle (RET-05), über die DMS und Mail Objekte bei der Retention-Engine registrieren – Breaking Changes müssen automatisiert erkannt werden, bevor sie ein konsumierendes Modul stillschweigend bricht.\n- `QA-07` Last- & Leistungstest – Lasttest für Archive unter realistischer Last aus DMS und Mail gleichzeitig – insbesondere Retention-Prüfpfad (RET-03), Modul-Adapter-Registrierung (RET-05) und WORM-Schreibpfad unter Last.\n- `ANA-01` Kennzahlen-Aggregation (modulübergreifend) – Zentraler Dienst, der Kennzahlen (Objektbestand, Aufbewahrungsstatus, Löschvorgänge, Speichervolumen) aus allen über RET-05 registrierten Modulen aggregiert.\n- `ANA-02` Auswertungs-Dashboard – Dashboard zur Visualisierung der aggregierten Kennzahlen mit Filtern nach Tenant, Modul und Zeitraum.\n- `ANA-03` Lizenz-/Nutzungs-Reports – Bericht über Nutzung und Lizenzrelevantes je Tenant (Speichervolumen, aktive Objekte, Nutzeranzahl-Bezug), abgestimmt mit dem Lizenzmodell aus NEXARCH Core.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Alle drei fachlichen Prüfgates (QA-02, QA-03, QA-04) sind bestanden\n2. Gesamtprotokoll fasst alle drei Prüfgates mit Ergebnis zusammen\n3. Abnahmeprotokoll ist unterzeichnet\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. Zusammenfassung aller drei Prüfgates gegen die jeweiligen Einzelprotokolle abgeglichen\n2. Offene Restrisiken aus allen drei Gates sind konsolidiert und schriftlich benannt\n3. Freigabeentscheidung ist dokumentiert\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- Alles, was nicht in den Akzeptanzkriterien steht. Keine vorauseilende Umsetzung späterer Anforderungen.\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: `QA-05: abnahme-und-compliance-prüfung-archive`\n- Branch: `feature/qa-05-abnahme-und-compliance-prüfung-archive`\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": "QA-06", + "title": "Schnittstellen-Vertragstests", + "epic": "QA", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 3, + "tech": "Vertragstests (Consumer-Driven Contracts), CI-Pipeline", + "description": "Vertragstests für die Modul-Adapter-Schnittstelle (RET-05), über die DMS und Mail Objekte bei der Retention-Engine registrieren – Breaking Changes müssen automatisiert erkannt werden, bevor sie ein konsumierendes Modul stillschweigend bricht.", + "dependsOn": [ + "RET-05" + ], + "akzeptanz": [ + "Vertragstests decken RET-05 vollständig ab", + "Absichtlich brechender Schema-Wechsel lässt Tests fehlschlagen", + "Tests laufen automatisiert in der CI" + ], + "pruefungen": [ + "Testlauf gegen aktuellen Stand grün", + "Simulierte Breaking Change erkannt", + "CI-Integration nachgewiesen" + ], + "status": "Fertig", + "epicName": "Prüfungen & Qualitätssicherung", + "epicEmoji": "✅", + "wave": 3, + "unlocks": [ + "QA-05" + ], + "prompt": "# QA-06 – Schnittstellen-Vertragstests\n\n**Epic:** ✅ Prüfungen & Qualitätssicherung | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 3\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nVertragstests für die Modul-Adapter-Schnittstelle (RET-05), über die DMS und Mail Objekte bei der Retention-Engine registrieren – Breaking Changes müssen automatisiert erkannt werden, bevor sie ein konsumierendes Modul stillschweigend bricht.\n\n**Technische Grundlage:** Vertragstests (Consumer-Driven Contracts), CI-Pipeline\n\n## Produkt-DNA für diesen Bereich\n> Prüfen heißt messen. Behauptungen ohne Messprotokoll gelten nicht als erledigt.\n\n**Übernehmen:**\n- Fester Vertragskorpus je Schnittstelle, an dem Kompatibilität wiederholbar geprüft wird.\n- Nachgewiesene Erkennung von Breaking Changes als Freigabevoraussetzung, wie es verbindliche Schnittstellenverträge verlangen.\n\n**Bewusst vermeiden:**\n- Keine Freigabe auf Zuruf. Jedes Prüfgate hinterlässt ein abgelegtes, nachlesbares Protokoll.\n- Keine Prüfung nur auf dem Entwicklungsrechner mit einer Handvoll Beispielaufrufen.\n\n**Für genau diese Kachel:** Die Modul-Adapter-Schnittstelle ist der eigentliche Zweck des Boards – ein unbemerkter Bruch trifft DMS und Mail gleichermaßen und muss automatisiert auffallen, bevor er ausgeliefert wird.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `RET-05` Modul-Adapter-Schnittstelle (DMS/Mail registrieren Objekttypen) – Schnittstelle, über die DMS und Mail ihre Objekttypen (Dokument, Mail, Anhang) und die zugehörige Aufbewahrungsklasse bei Archive registrieren, statt eigene Retention-Logik zu bauen.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Vertragstests decken RET-05 vollständig ab\n2. Absichtlich brechender Schema-Wechsel lässt Tests fehlschlagen\n3. Tests laufen automatisiert in der CI\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. Testlauf gegen aktuellen Stand grün\n2. Simulierte Breaking Change erkannt\n3. CI-Integration nachgewiesen\n\n## Nicht Bestandteil dieser Kachel\n- Alles, was nicht in den Akzeptanzkriterien steht. Keine vorauseilende Umsetzung späterer Anforderungen.\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: `QA-06: schnittstellen-vertragstests`\n- Branch: `feature/qa-06-schnittstellen-vertragstests`\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": "BAK-07", + "title": "Aufbewahrungsfrist für Backup-Snapshots", + "epic": "BAK", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 3, + "tech": "PostgreSQL, Postgres-Jobqueue (geplante Jobs statt Redis)", + "description": "Eigene, von der Dokumenten-Retention (RET-02) unabhängige Aufbewahrungsfrist für Backup-Snapshots selbst – nach restic/Borg-Vorbild eine Prune-Policy (z. B. tägliche Snapshots 14 Tage, wöchentliche 3 Monate, monatliche 1 Jahr – konkrete Staffelung als Konfiguration, nicht hart codiert), damit Backups nicht unbegrenzt wachsen, aber auch nicht zu früh gelöscht werden.", + "dependsOn": [ + "BAK-01", + "BAK-02" + ], + "akzeptanz": [ + "Backup-Snapshots folgen einer konfigurierbaren Prune-Policy (Staffelung nach Alter), unabhängig von RET-02", + "Snapshot-Löschung nach Ablauf der Frist läuft automatisiert", + "Eine gültige, nicht abgelaufene Aufbewahrungssperre auf einem Dokument (RET-03/CMP-06) verhindert nicht das Pruning älterer Backup-Snapshots, solange mindestens ein aktueller Snapshot das Dokument noch enthält" + ], + "pruefungen": [ + "Prune-Test mit simulierten Snapshots über mehrere Altersstufen ergibt korrekte Staffelung", + "Automatisierte Löschung abgelaufener Snapshots im Test nachgewiesen", + "Legal-Hold-Test bestätigt, dass Pruning nicht mit Dokumenten-Retention kollidiert" + ], + "status": "Fertig", + "epicName": "Backup & Wiederherstellung", + "epicEmoji": "💾", + "wave": 2, + "unlocks": [ + "QA-04" + ], + "prompt": "# BAK-07 – Aufbewahrungsfrist für Backup-Snapshots\n\n**Epic:** 💾 Backup & Wiederherstellung | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 2\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nEigene, von der Dokumenten-Retention (RET-02) unabhängige Aufbewahrungsfrist für Backup-Snapshots selbst – nach restic/Borg-Vorbild eine Prune-Policy (z. B. tägliche Snapshots 14 Tage, wöchentliche 3 Monate, monatliche 1 Jahr – konkrete Staffelung als Konfiguration, nicht hart codiert), damit Backups nicht unbegrenzt wachsen, aber auch nicht zu früh gelöscht werden.\n\n**Technische Grundlage:** PostgreSQL, Postgres-Jobqueue (geplante Jobs statt Redis)\n\n## Produkt-DNA für diesen Bereich\n> Sicherung nach dem Vorbild von restic/Borg: inkrementell, deduplizierend, verifizierbar.\n\n**Übernehmen:**\n- restic/Borg: Inkrementelle, deduplizierende Sicherung mit Verifikation jeder Sicherung.\n- restic/Borg: eigene, konfigurierbare Prune-Policy für die Aufbewahrung der Sicherungen selbst (Staffelung nach Alter).\n- Reconciliation zwischen Objekt-Storage und Datenbank als eigenständige, planbare Prüfung.\n\n**Bewusst vermeiden:**\n- Backup-Aufbewahrung mit der Dokumenten-Retention (RET-02) zu verwechseln ist ein Kategorienfehler – ein Dokument kann 10 Jahre aufbewahrungspflichtig sein, während die tägliche Backup-Kopie davon nur 14 Tage vorgehalten werden muss, weil die nächste Kopie sie ohnehin ersetzt. Beide Fristen sind unabhängig konfigurierbar, nicht gekoppelt.\n- Kein Pruning, das den letzten verbliebenen Snapshot eines noch unter Aufbewahrungssperre (Legal Hold) stehenden Dokuments entfernt, solange kein aktuellerer Snapshot dieses Dokument enthält.\n\n**Für genau diese Kachel:** Ohne eigene Prune-Policy wachsen Backups unbegrenzt oder werden willkürlich gelöscht – die Frist für die Sicherung selbst ist eine andere Frist als die für das gesicherte Dokument.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `BAK-01` Datenbank-Backup-Strategie – Automatisierte, inkrementelle Sicherung der PostgreSQL-Datenbank mit Aufbewahrung mehrerer Generationen und Verifikation jeder Sicherung.\n- `BAK-02` Objekt-Storage-Backup/Snapshots – Automatisierte, deduplizierende Sicherung der im Objekt-Storage abgelegten Dateiinhalte.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Backup-Snapshots folgen einer konfigurierbaren Prune-Policy (Staffelung nach Alter), unabhängig von RET-02\n2. Snapshot-Löschung nach Ablauf der Frist läuft automatisiert\n3. Eine gültige, nicht abgelaufene Aufbewahrungssperre auf einem Dokument (RET-03/CMP-06) verhindert nicht das Pruning älterer Backup-Snapshots, solange mindestens ein aktueller Snapshot das Dokument noch enthält\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. Prune-Test mit simulierten Snapshots über mehrere Altersstufen ergibt korrekte Staffelung\n2. Automatisierte Löschung abgelaufener Snapshots im Test nachgewiesen\n3. Legal-Hold-Test bestätigt, dass Pruning nicht mit Dokumenten-Retention kollidiert\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `RET-02` Aufbewahrungsfristen-Engine (Dokumenten-Retention)\n- `RET-03` Löschworkflow & Aufbewahrungssperre (Legal Hold)\n- `BAK-03` Restore-Verfahren\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: `BAK-07: aufbewahrungsfrist-fuer-backup-snapshots`\n- Branch: `feature/bak-07-aufbewahrungsfrist-fuer-backup-snapshots`\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": "CMP-07", + "title": "DSGVO-Löschantrag (Recht auf Löschung, Art. 17)", + "epic": "CMP", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 4, + "tech": "PostgreSQL, transaktionaler Zustandswechsel, Modul-Adapter-Schnittstelle (RET-05)", + "description": "Workflow für den Löschantrag einer betroffenen Person (Art. 17 DSGVO): modulübergreifende Suche (CMP-02), Löschung ohne Aufbewahrungspflicht, begründete Ablehnung mit Aufbewahrungspflicht, Freigabe über CMP-06, vollständiges Protokoll je Objekt.", + "dependsOn": [ + "RET-03", + "RET-05", + "CMP-02", + "CMP-06" + ], + "akzeptanz": [ + "Löschantrag findet über die Suche aus CMP-02 alle Objekte einer betroffenen Person, mandantenscharf", + "Jedes gefundene Objekt wird EINZELN entschieden: Löschung oder Ablehnung mit Begründung – niemals eine pauschale Sammelentscheidung", + "Tatsächliche Löschung durchläuft denselben Vier-Augen-Freigabeprozess wie jede andere Löschung (CMP-06), keine zweite Implementierung", + "Ergebnis des Löschantrags (je Objekt: gelöscht/abgelehnt+Grund) ist vollständig und dauerhaft protokolliert" + ], + "pruefungen": [ + "Löschantrag für eine Testperson mit gemischtem Datenbestand liefert exakt eine Löschung und eine begründete Ablehnung", + "Aufbewahrungssperre (Legal Hold) verhindert die Löschung auch bei bereits abgelaufener regulärer Frist", + "Löschantrag für einen Tenant führt nachweislich zu keiner Aktion an Objekten eines anderen Tenants" + ], + "status": "Fertig", + "epicName": "Compliance & eDiscovery", + "epicEmoji": "⚖️", + "wave": 4, + "unlocks": [ + "QA-03" + ], + "prompt": "# CMP-07 – DSGVO-Löschantrag (Recht auf Löschung, Art. 17)\n\n**Epic:** ⚖️ Compliance & eDiscovery | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 4 Personentage | **Welle:** 4\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nWorkflow für den Löschantrag einer betroffenen Person (Art. 17 DSGVO): modulübergreifende Suche nach allen zu dieser Person gespeicherten Objekten (wiederverwendet die Auskunfts-Suche aus `CMP-02`), Löschung jedes Objekts OHNE aktive Aufbewahrungspflicht (`RET-03` hat Vorrang), nachvollziehbare Ablehnung mit Begründung für jedes Objekt MIT Aufbewahrungspflicht, vollständiges Protokoll der Entscheidung je Objekt. Tatsächliche Vernichtung läuft über denselben Vier-Augen-Freigabeprozess wie jede andere Löschung (`CMP-06`), keine zweite Lösch-Implementierung.\n\n**Technische Grundlage:** PostgreSQL, transaktionaler Zustandswechsel, Wiederverwendung der Modul-Adapter-Schnittstelle (`RET-05`)\n\n## Produkt-DNA für diesen Bereich\n> Nachweisführung wie ecoDMS, Vier-Augen-Prinzip wie Alfresco, aber schlank umgesetzt.\n\n**Übernehmen:**\n- Alfresco: Vier-Augen-Prinzip bei Freigaben – Löschung nur mit zweiter, unabhängiger Bestätigung.\n- ecoDMS: Nachvollziehbare Vernichtung mit lückenlosem Protokoll.\n- GoBD-konforme Verfahrensdokumentation als exportierbares Dokument, nicht als Prosa-Anhang.\n\n**Bewusst vermeiden:**\n- Ein Vorgänger-Projekt (archivmail) hat den DSGVO-Löschantrag ursprünglich als eigenständigen, von der übrigen Löschlogik getrennten Sonderpfad gebaut: ein Löschantrag ruft hier stattdessen denselben Löschworkflow (`RET-03`/`CMP-06`) auf wie jede andere Löschung – kein Duplikat der Aufbewahrungs-/Vier-Augen-Prüfung.\n- Keine stille Teillöschung: ein Löschantrag mit gemischtem Ergebnis (teils gelöscht, teils wegen Aufbewahrungspflicht abgelehnt) macht das Ergebnis je Objekt einzeln nachvollziehbar, statt eine pauschale Sammelantwort zu liefern.\n\n**Für genau diese Kachel:** Ein Löschantrag unter Fristdruck (DSGVO kennt hierfür i.d.R. eine Monatsfrist) ist der Härtetest für das Zusammenspiel von Aufbewahrungspflicht und Löschrecht – beides muss automatisiert und nachvollziehbar entschieden werden, nicht manuell pro Fall.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `RET-03` Löschworkflow & Aufbewahrungssperre (Legal Hold) – Aufbewahrungssperre verhindert jede Löschung unabhängig vom Fristablauf.\n- `RET-05` Modul-Adapter-Schnittstelle (DMS/Mail registrieren Objekttypen) – Rückruf-Mechanismus, über den Archive ein Modul beim Vernichten eines Objekts anspricht.\n- `CMP-02` DSGVO-/Datenschutz-Berichte – modulübergreifende Suche nach allen Objekten einer betroffenen Person.\n- `CMP-06` Vier-Augen-Freigabe für Löschungen – zweite, unabhängige Bestätigung vor tatsächlicher Vernichtung.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Löschantrag findet über die Suche aus `CMP-02` alle Objekte einer betroffenen Person, mandantenscharf\n2. Jedes gefundene Objekt wird EINZELN entschieden: Löschung (keine Aufbewahrungspflicht) oder Ablehnung mit Begründung (aktive Aufbewahrungspflicht/Legal Hold aus `RET-03`) – niemals eine pauschale Sammelentscheidung\n3. Tatsächliche Löschung durchläuft denselben Vier-Augen-Freigabeprozess wie jede andere Löschung (`CMP-06`), keine zweite Implementierung\n4. Ergebnis des Löschantrags (je Objekt: gelöscht/abgelehnt+Grund) ist vollständig und dauerhaft protokolliert\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. Löschantrag für eine Testperson mit gemischtem Datenbestand (ein Objekt ohne, ein Objekt mit aktiver Aufbewahrungspflicht) liefert exakt eine Löschung und eine begründete Ablehnung\n2. Aufbewahrungssperre (Legal Hold) verhindert die Löschung nachweislich auch dann, wenn die reguläre Aufbewahrungsfrist bereits abgelaufen wäre\n3. Löschantrag für einen Tenant führt nachweislich zu keiner Aktion an Objekten eines anderen Tenants\n\n## Bekannte Fehler vermeiden\narchivmail (Vorgängerprojekt) implementierte den DSGVO-Löschantrag ursprünglich als eigenständigen Workflow parallel zur regulären Aufbewahrungs-/Löschlogik – zwei Stellen, die dieselbe Aufbewahrungsregel auswerten, laufen bei Änderungen an einer Stelle auseinander. Diese Kachel ruft stattdessen ausschließlich `RET-03` (Aufbewahrungsprüfung) und `CMP-06` (Freigabe) auf, statt eine zweite Prüf-/Freigabelogik zu bauen.\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- Die Suche nach Objekten einer Person selbst (`CMP-02`)\n- Die eigentliche Aufbewahrungsprüfung (`RET-03`) und Freigabe (`CMP-06`)\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: `CMP-07: dsgvo-loeschantrag-recht-auf-loeschung`\n- Branch: `feature/cmp-07-dsgvo-loeschantrag-recht-auf-loeschung`\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": "QA-07", + "title": "Last- & Leistungstest", + "epic": "QA", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 3, + "tech": "Lastgenerator, Messprotokoll", + "description": "Lasttest für Archive unter realistischer Last aus DMS und Mail gleichzeitig – insbesondere Retention-Prüfpfad (RET-03), Modul-Adapter-Registrierung (RET-05) und WORM-Schreibpfad unter Last.", + "dependsOn": [ + "RET-05", + "RET-03" + ], + "akzeptanz": [ + "Definierte Ziel-Latenz für die Retention-/Legal-Hold-Abfrage unter Last eingehalten", + "WORM-Schreibpfad bleibt unter simulierter Last aus zwei gleichzeitig zugreifenden Modulen (DMS und Mail) korrekt und ohne Datenverlust", + "Modul-Adapter-Registrierung (RET-05) verkraftet gleichzeitige Registrierung mehrerer Objekttypen ohne Race Condition" + ], + "pruefungen": [ + "Lasttest mit simulierten parallelen Anfragen aus DMS und Mail durchgeführt, Ergebnis dokumentiert", + "WORM-Schreibpfad unter Last auf Datenverlust/Race Conditions geprüft", + "Gleichzeitige Registrierung mehrerer Objekttypen bei RET-05 getestet" + ], + "status": "Fertig", + "epicName": "Prüfungen & Qualitätssicherung", + "epicEmoji": "✅", + "wave": 6, + "unlocks": [ + "QA-05" + ], + "prompt": "# QA-07 – Last- & Leistungstest\n\n**Epic:** ✅ Prüfungen & Qualitätssicherung | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 6\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nLasttest für Archive unter realistischer Last aus DMS und Mail gleichzeitig – insbesondere Retention-Prüfpfad (RET-03), Modul-Adapter-Registrierung (RET-05) und WORM-Schreibpfad unter Last.\n\n**Technische Grundlage:** Lastgenerator, Messprotokoll\n\n## Produkt-DNA für diesen Bereich\n> Prüfen heißt messen. Behauptungen ohne Messprotokoll gelten nicht als erledigt.\n\n**Übernehmen:**\n- Nachgewiesene Prüfergebnisse als Freigabevoraussetzung, wie in allen anderen Boards.\n\n**Bewusst vermeiden:**\n- Keine Freigabe auf Zuruf. Jedes Prüfgate hinterlässt ein abgelegtes, nachlesbares Protokoll.\n\n**Für genau diese Kachel:** Archive wird von zwei Modulen gleichzeitig angesprochen (DMS und Mail) – ohne Lasttest bleibt unklar, ob der Retention-Prüfpfad das verkraftet.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `RET-05` Modul-Adapter-Schnittstelle (DMS/Mail registrieren Objekttypen) – Schnittstelle, über die DMS und Mail ihre Objekttypen (Dokument, Mail, Anhang) und die zugehörige Aufbewahrungsklasse bei Archive registrieren, statt eigene Retention-Logik zu bauen.\n- `RET-03` Löschworkflow & Aufbewahrungssperre (Legal Hold) – Löschworkflow für abgelaufene Objekte: Freigabe, Vernichtung, Protokolleintrag. Aufbewahrungssperre (Legal Hold) verhindert jede Löschung unabhängig vom Fristablauf.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Definierte Ziel-Latenz für die Retention-/Legal-Hold-Abfrage unter Last eingehalten\n2. WORM-Schreibpfad bleibt unter simulierter Last aus zwei gleichzeitig zugreifenden Modulen (DMS und Mail) korrekt und ohne Datenverlust\n3. Modul-Adapter-Registrierung (RET-05) verkraftet gleichzeitige Registrierung mehrerer Objekttypen ohne Race Condition\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. Lasttest mit simulierten parallelen Anfragen aus DMS und Mail durchgeführt, Ergebnis dokumentiert\n2. WORM-Schreibpfad unter Last auf Datenverlust/Race Conditions geprüft\n3. Gleichzeitige Registrierung mehrerer Objekttypen bei RET-05 getestet\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- (keine direkt abhängigen Kacheln bekannt)\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: `QA-07: last leistungstest`\n- Branch: `feature/qa-07-last-leistungstest`\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": "BAK-08", + "title": "Checksum-basierte Objekt-Integritätsprüfung (Scrub-Job)", + "epic": "BAK", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 3, + "tech": "Postgres-Jobqueue (FDN-04), SHA-256-Stream-Prüfung, Meldung über Core OPS-05", + "description": "Periodischer Job, der Stichproben gespeicherter Objekte herunterlädt, deren SHA-256 neu berechnet und mit der in file_revisions.checksum_sha256 (FDN-02) hinterlegten Prüfsumme vergleicht. Ergänzt BAK-05 (reine Existenzprüfung) um Inhalts-Integrität – deckt stille Korruption und Bit-Rot insbesondere auf extern eingebundenem, nicht selbst überwachtem S3-Storage auf.", + "dependsOn": [ + "BAK-05", + "FDN-04", + "FDN-09", + "OPS-05" + ], + "akzeptanz": [ + "Job zieht periodisch eine konfigurierbare Stichprobe gespeicherter Objekte, lädt sie, berechnet SHA-256 neu und vergleicht mit file_revisions.checksum_sha256 – Abweichung gilt als Befund", + "Sampling priorisiert alte, unveränderte Objekte (GoBD-Relevanz: still vergammelnde Bytes, die niemand mehr anfasst, fallen sonst erst beim Restore auf); Neu-Schreibvorgänge sind bereits beim Schreiben verifiziert und werden nicht bevorzugt geprüft", + "Befund wird gemeldet, nicht automatisch repariert – Meldung läuft über Core OPS-05 (Alerting) mit Objekt-Referenz, erwarteter vs. tatsächlicher Prüfsumme und Zeitpunkt", + "Job läuft über die Postgres-Jobqueue (FDN-04) mit konfigurierbarer Kadenz und Stichprobengröße; Lauf ist idempotent und unterbrechbar ohne inkonsistenten Zustand", + "Stichprobengröße und Kadenz sind je Betriebsstufe konfigurierbar, damit ein vollständiger Durchlauf über den Bestand in einem dokumentierten Zeitraum abgeschlossen wird (kein täglicher Voll-Download aller Objekte)", + "Der Job erkennt Abweichungen nur bei Objekten, die gelesen und erneut geprüft werden können. Er ersetzt keine storage-seitige WORM-/Versionierungsstrategie und keine Zugriffs-/Audit-Logs des Storage-Providers (siehe STORAGE-KONZEPT.md Abschnitt 6.1) — bei extern eingebundenem, nicht-kompatiblem Kunden-Storage (Betriebsmodus 3, ohne Versioning/Object Lock/Audit-Logs) bleibt eine Lücke, die BAK-08 technisch nicht schließen kann." + ], + "pruefungen": [ + "Testobjekt mit absichtlich manipuliertem Byte im Storage wird als Abweichung erkannt und gemeldet (Alert-Eingang über OPS-05 nachgewiesen)", + "Unverändertes Testobjekt erzeugt keinen Befund (kein False-Positive)", + "Verschlüsseltes Testobjekt (über FDN-09) wird korrekt gelesen und geprüft – der Job nutzt denselben Decrypt-Pfad wie reguläre Lesezugriffe, vergleicht also Klartext-Prüfsumme, nicht Chiffretext", + "Test gegen ein simuliertes externes S3-Ziel (nicht selbst überwacht): Korruption dort wird erkannt – genau der Fall, der sonst unsichtbar bleibt", + "Sampling-Statistik dokumentiert: Anteil alter vs. neuer Objekte in der Stichprobe entspricht der konfigurierten Priorisierung" + ], + "status": "Fertig", + "epicName": "Backup & Wiederherstellung", + "epicEmoji": "💾", + "wave": 4, + "unlocks": [], + "prompt": "# BAK-08 – Checksum-basierte Objekt-Integritätsprüfung (Scrub-Job)\n\n**Epic:** 💾 Backup & Wiederherstellung | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 4\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nPeriodischer Job, der Stichproben gespeicherter Objekte herunterlädt, deren SHA-256 neu berechnet und mit der in file_revisions.checksum_sha256 (DMS FDN-02) hinterlegten Prüfsumme vergleicht. Ergänzt BAK-05 (reine Existenzprüfung) um Inhalts-Integrität – deckt stille Korruption und Bit-Rot insbesondere auf extern eingebundenem, nicht selbst überwachtem S3-Storage auf.\n\n**Technische Grundlage:** Postgres-Jobqueue (DMS FDN-04), SHA-256-Stream-Prüfung, Meldung über Core OPS-05\n\n## Produkt-DNA für diesen Bereich\n> Sicherung nach dem Vorbild von restic/Borg: inkrementell, deduplizierend, verifizierbar.\n\n**Übernehmen:**\n- restic/Borg: Inkrementelle, deduplizierende Sicherung mit Verifikation jeder Sicherung.\n- restic/Borg: Wiederherstellung ist Routine, nicht Ausnahmefall – regelmäßig getestet.\n- Reconciliation zwischen Objekt-Storage und Datenbank als eigenständige, planbare Prüfung (BAK-05) – dieselbe Trennschärfe gilt hier für Inhalts- statt Existenzprüfung.\n\n**Bewusst vermeiden:**\n- Keine Sicherung ohne belegten Wiederherstellungstest – eine ungeprüfte Sicherung zählt nicht als Sicherung.\n- Kein automatisches „Reparieren\" eines Befunds – eine echte Korruption oder ein Angriff darf nicht stillschweigend überschrieben werden.\n\n**Für genau diese Kachel:** Bei einem vom Kunden selbst eingebundenen, extern gehosteten S3-Bucket überwachen wir weder Hardware noch Betreiber – nur die eigene, wiederholte Prüfsummen-Verifikation macht stille Korruption dort überhaupt sichtbar, bevor ein Restore daran scheitert.\n\n## Ausgangslage\nDie folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren:\n- `BAK-05` Reconciliation (Konsistenzprüfung Storage vs. DB) – reine Existenzprüfung (Objekt vorhanden ja/nein), keine Inhaltsprüfung. BAK-08 ergänzt das um Inhalts-Integrität, dupliziert die Existenzprüfung nicht.\n\nSetzt voraus (externes DMS-Board, siehe /home/sysops/Dokumente/Scripte/nexarch/dms-kanban/): `FDN-04` Job-Queue & Worker-Runtime (Postgres-Jobqueue, auf der dieser Scrub-Job läuft), `FDN-09` Verschlüsselung at rest & Schlüsselverwaltung (der Scrub muss über denselben Decrypt-Pfad wie reguläre Lesezugriffe lesen und Klartext-Prüfsummen vergleichen – ein Hash-Vergleich gegen Chiffretext vor FDN-09 würde jedes Objekt fälschlich als korrupt melden), sowie `DOC-01` Upload-API & Chunk-Handling (befüllt file_revisions.checksum_sha256 im Schreibpfad – ohne diese Befüllung liefe BAK-08 gegen ein leeres Prüfsummenfeld).\n\nSetzt voraus (externes Core-Board, siehe /home/sysops/Dokumente/Scripte/nexarch/core-kanban/): `OPS-05` Alerting bei Schwellwert-Überschreitung (Meldeweg für gefundene Abweichungen).\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Job zieht periodisch eine konfigurierbare Stichprobe gespeicherter Objekte, lädt sie, berechnet SHA-256 neu und vergleicht mit file_revisions.checksum_sha256 – Abweichung gilt als Befund\n2. Sampling priorisiert alte, unveränderte Objekte (GoBD-Relevanz: still vergammelnde Bytes, die niemand mehr anfasst, fallen sonst erst beim Restore auf); Neu-Schreibvorgänge sind bereits beim Schreiben verifiziert und werden nicht bevorzugt geprüft\n3. Befund wird gemeldet, nicht automatisch repariert – Meldung läuft über Core OPS-05 (Alerting) mit Objekt-Referenz, erwarteter vs. tatsächlicher Prüfsumme und Zeitpunkt\n4. Job läuft über die Postgres-Jobqueue (FDN-04) mit konfigurierbarer Kadenz und Stichprobengröße; Lauf ist idempotent und unterbrechbar ohne inkonsistenten Zustand\n5. Stichprobengröße und Kadenz sind je Betriebsstufe konfigurierbar, damit ein vollständiger Durchlauf über den Bestand in einem dokumentierten Zeitraum abgeschlossen wird (kein täglicher Voll-Download aller Objekte)\n6. Der Job erkennt Abweichungen nur bei Objekten, die gelesen und erneut geprüft werden können. Er ersetzt keine storage-seitige WORM-/Versionierungsstrategie und keine Zugriffs-/Audit-Logs des Storage-Providers (siehe STORAGE-KONZEPT.md Abschnitt 6.1) — bei extern eingebundenem, nicht-kompatiblem Kunden-Storage (Betriebsmodus 3, ohne Versioning/Object Lock/Audit-Logs) bleibt eine Lücke, die BAK-08 technisch nicht schließen kann.\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. Testobjekt mit absichtlich manipuliertem Byte im Storage wird als Abweichung erkannt und gemeldet (Alert-Eingang über OPS-05 nachgewiesen)\n2. Unverändertes Testobjekt erzeugt keinen Befund (kein False-Positive)\n3. Verschlüsseltes Testobjekt (über FDN-09) wird korrekt gelesen und geprüft – der Job nutzt denselben Decrypt-Pfad wie reguläre Lesezugriffe, vergleicht also Klartext-Prüfsumme, nicht Chiffretext\n4. Test gegen ein simuliertes externes S3-Ziel (nicht selbst überwacht): Korruption dort wird erkannt – genau der Fall, der sonst unsichtbar bleibt\n5. Sampling-Statistik dokumentiert: Anteil alter vs. neuer Objekte in der Stichprobe entspricht der konfigurierten Priorisierung\n\n## Bekannte Fehler vermeiden\n- Existenzprüfung (BAK-05) und Inhalts-Integrität sind zwei verschiedene Fehlerklassen – nicht in BAK-05 hineinstopfen, dessen Scope bleibt bewusst auf Existenz begrenzt. Abweichungen melden statt still reparieren: ein Scrub, der selbst „repariert\", kann eine echte Korruption (oder einen Angriff) unter den Teppich kehren; die Entscheidung über Quelle der Wiederherstellung (Backup-Restore via BAK-03, Neu-Upload, Legal-Hold-Fall) gehört zu einem Menschen.\n- Achtung Verschlüsselungsfalle: Die hinterlegte Prüfsumme bezieht sich auf Klartext (berechnet vor FDN-09 im Upload-Pfad). Der Scrub muss denselben Decrypt-Pfad wie DOC-01-Lesevorgänge nutzen – ein Hash-Vergleich direkt gegen den Chiffretext würde jedes Objekt fälschlich als korrupt melden.\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- Befüllen von file_revisions.checksum_sha256 selbst (gehört in den Upload-Pfad `DOC-01`/`DOC-02`)\n- Existenzprüfung Storage ↔ DB (`BAK-05`)\n- Wiederherstellung aus Backup nach Befund (`BAK-03`)\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: `BAK-08: checksum-basierte-objekt-integritaetspruefung-scrub-job`\n- Branch: `feature/bak-08-checksum-basierte-objekt-integritaetspruefung-scrub-job`\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": "RET-06-API", + "title": "Aufbewahrungsfristen-Konfigurations-Backend", + "epic": "RET", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 2, + "tech": "Go/net/http, PostgreSQL, provisorischer Rollen-Check (kein RBAC-02-HTTP-Wrapper vorhanden)", + "description": "Backend-API fuer RET-06: Aufbewahrungsklassen anlegen/aendern/deaktivieren, Vorschauliste ablaufender Objekte. Aus RET-06 herausgeloest (Board-Entscheidung: Backend zuerst, Next.js-Frontend als eigenes Folgeticket), damit kein Pseudo-Frontend-Protokoll entsteht.", + "dependsOn": [ + "RET-02" + ], + "akzeptanz": [ + "Aufbewahrungsklasse mit Frist lässt sich per API anlegen, ändern und deaktivieren", + "API liefert Vorschauliste bald ablaufender Objekte, identisch zum periodischen Job", + "Änderungen an Fristen sind nur mit gültiger Rollen-Kennung zugänglich (provisorischer Check, echter RBAC-02-HTTP-Wrapper folgt als Core-Ticket)" + ], + "pruefungen": [ + "Änderung einer Frist wirkt sich nur auf künftige Berechnungen aus, nicht rückwirkend", + "Fehlende/falsche Rollen-Kennung erhält 403, gültige Kennung 200 (Negativ- und Positivtest)", + "Vorschauliste stimmt mit dem Ergebnis des periodischen Jobs überein" + ], + "status": "Fertig", + "epicName": "Retention & WORM", + "epicEmoji": "⏳", + "wave": 3, + "unlocks": [ + "RET-06" + ], + "prompt": "Siehe archive/docs/RET-06-API-PRUEFPROTOKOLL.md fuer vollstaendige Umsetzung und Pruefungen." + }, + { + "code": "RET-08", + "title": "RET-06-API auf RBAC-06 migrieren (Provisorium abbauen)", + "epic": "RET", + "featureIds": [], + "role": "Backend", + "complexity": "Klein", + "estimateDays": 1, + "tech": "Go, HTTP-Client", + "description": "internal/retentionapi.RequireRole (Header-basiertes Provisorium aus RET-06-API) durch einen echten Aufruf von Core RBAC-06 (POST /authorize, service-token-authentifiziert) ersetzen. Baut das seit RET-06-API dokumentierte Provisorium ab, jetzt da RBAC-06 real existiert und deployed ist.", + "dependsOn": [ + "RBAC-06", + "RET-06-API" + ], + "akzeptanz": [ + "Der RBAC-Check in retentionapi nutzt ausschliesslich RBAC-06 (HTTP), nicht mehr das lokale Header-Provisorium", + "Bestehende Endpunkte (POST /retention-classes, POST /retention-classes/{class}/deactivate) verhalten sich funktional unveraendert (gleiche AC wie RET-06-API)", + "Fehlerfall: RBAC-06 nicht erreichbar oder verweigert -> Zugriff wird abgelehnt (fail closed), nicht stillschweigend erlaubt" + ], + "pruefungen": [ + "403-Nachweis erfolgt gegen echte Policy-Rules ueber RBAC-06, nicht mehr nur gegen einen Header-Wert", + "Bestehende RET-06-API-Tests (Preview stimmt mit periodischem Job ueberein, Deaktivierung wirkt) laufen weiterhin gruen nach der Migration", + "Ausfall/Nichterreichbarkeit von RBAC-06 fuehrt zu einer Ablehnung (kein Fallback auf offenen Zugriff)" + ], + "status": "Fertig", + "epicName": "Retention & WORM", + "epicEmoji": "⏳", + "wave": 4, + "unlocks": [ + "RET-06" + ], + "prompt": "# RET-08 – RET-06-API auf RBAC-06 migrieren (Provisorium abbauen)\n\n**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexitaet:** Klein | **Aufwand:** 1 Personentag | **Welle:** 4\n\n---\n\n## Auftrag\nDas in RET-06-API dokumentierte Provisorium (internal/retentionapi.RequireRole, Header-basierter Rollen-Check) durch einen echten HTTP-Aufruf von Core RBAC-06 (POST /authorize) ersetzen. RBAC-06 ist fertig und deployed (127.0.0.1:8093 auf 131), service-token-authentifiziert.\n\n## Ausgangslage\n- RET-06-API (fertig): internal/retentionapi.RequireRole als bewusst dokumentiertes Provisorium, siehe archive/docs/RET-06-API-PRUEFPROTOKOLL.md.\n- RBAC-06 (fertig): internal/policyapi.Mount, POST /authorize, service-token-check, siehe docs/RBAC-06-PRUEFPROTOKOLL.md, Abschnitt \"Bezug zu Archive RET-06-API\".\n\n## Akzeptanzkriterien\n1. Der RBAC-Check in retentionapi nutzt ausschliesslich RBAC-06 (HTTP), nicht mehr das lokale Header-Provisorium\n2. Bestehende Endpunkte verhalten sich funktional unveraendert\n3. Fehlerfall: RBAC-06 nicht erreichbar oder verweigert -> Zugriff wird abgelehnt (fail closed)\n\n## Pruefungen vor der Abnahme\n1. 403-Nachweis gegen echte Policy-Rules ueber RBAC-06\n2. Bestehende RET-06-API-Tests laufen weiterhin gruen\n3. Ausfall von RBAC-06 fuehrt zu Ablehnung, kein Fallback auf offenen Zugriff\n\n## Arbeitsweise\nKleinste Loesung, kein Umbau angrenzender Bereiche. Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy.\n\n## Abschluss\n- Commit-Nachricht: RET-08: ret-06-api auf rbac-06 migrieren\n- Branch: feature/ret-08-ret-06-api-auf-rbac-06-migrieren\n" + }, + { + "code": "RET-09", + "title": "Modul-Adapter-Dienst starten (RET-05 als laufender HTTP-Endpunkt)", + "epic": "RET", + "featureIds": [], + "role": "Backend", + "complexity": "Klein", + "estimateDays": 1, + "tech": "Go, HTTP", + "description": "archive/internal/moduleadapter.RegisterHandler (RET-05) existiert als fertiger Go-Handler, laeuft aber nirgends als Dienst. RET-09 startet ihn als eigenstaendigen HTTP-Dienst (main.go + systemd), OHNE neue Archive-Logik - reines Wiring, analog RBAC-06/CFG-05 fuer andere Module.", + "dependsOn": [ + "RET-05" + ], + "akzeptanz": [ + "moduleadapter.RegisterHandler laeuft als eigenstaendiger, ueber systemd verwalteter HTTP-Dienst", + "Ein externer Client (anderes Modul) kann real POST /register gegen den laufenden Dienst aufrufen", + "Keine neue Autorisierungs- oder Registrierungslogik - reiner Start des bestehenden Handlers" + ], + "pruefungen": [ + "Dienst startet und bleibt stabil (systemctl status aktiv)", + "Realer POST /register von einem externen Testclient gegen den laufenden Dienst liefert die erwartete Registrierung (idempotent, wie in RET-05 getestet)", + "Code-Review: keine Aenderung an moduleadapter.go/handler.go selbst, nur main.go+systemd neu" + ], + "status": "Fertig", + "epicName": "Retention & WORM", + "epicEmoji": "⏳", + "wave": 5, + "unlocks": [ + "DOC-16", + "ARC-11" + ], + "prompt": "# RET-09 – Modul-Adapter-Dienst starten (RET-05 als laufender HTTP-Endpunkt)\n\n**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexitaet:** Klein | **Aufwand:** 1 Personentag | **Welle:** 5\n\n---\n\n## Auftrag\narchive/internal/moduleadapter.RegisterHandler (RET-05, fertig) als eigenstaendigen HTTP-Dienst starten. Reines Wiring - keine neue Archive-Logik, keine Aenderung an moduleadapter.go/handler.go.\n\n## Ausgangslage\nRET-05 (fertig): archive/internal/moduleadapter.Register/RegisterHandler, reiner Go-Handler ohne main.go, der ihn tatsaechlich auf einem Port startet - identisches Muster wie RBAC-02 vor RBAC-06 und CFG-02 vor CFG-05.\n\n## Akzeptanzkriterien\n1. RegisterHandler laeuft als eigenstaendiger, systemd-verwalteter Dienst\n2. Externer Client kann real POST /register aufrufen\n3. Keine neue Logik - reiner Start des bestehenden Handlers\n\n## Pruefungen vor der Abnahme\n1. Dienst aktiv und stabil\n2. Realer POST /register von externem Testclient liefert erwartete Registrierung\n3. Code-Review bestaetigt: keine Aenderung an moduleadapter.go/handler.go\n\n## Arbeitsweise\nKleinste Loesung, kein Umbau angrenzender Bereiche. Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy... (Deploy hier ausnahmsweise Teil der Pruefung, siehe RBAC-06/CFG-05-Praezedenz: Dienst MUSS real laufen fuer die Pflichtpruefungen.)\n\n## Abschluss\n- Commit-Nachricht: RET-09: modul-adapter-dienst-starten\n- Branch: feature/ret-09-modul-adapter-dienst-starten\n" + }, + { + "code": "RET-10", + "title": "CORS für RET-06-API (Frontend-Zugriff aus dem Browser)", + "epic": "RET", + "featureIds": [], + "role": "Backend", + "complexity": "Klein", + "estimateDays": 1, + "tech": "Go, HTTP-Middleware (CORS)", + "description": "retention-api (RET-06-API) setzt keine CORS-Header - ein echter Browser blockiert den Fetch von RET-06 (Next.js-Frontend, anderer Origin) zum Backend. Real per Sichtpruefung des laufenden RET-06-Frontends gefunden (curl umgeht CORS, Go-/Vitest-Tests pruefen nicht browserseitig), nicht durch die urspruenglichen RET-06/RET-06-API-Pruefungen erfasst.", + "dependsOn": [ + "RET-06-API" + ], + "akzeptanz": [ + "retention-api setzt Access-Control-Allow-Origin fuer den konfigurierten Frontend-Origin (Umgebungsvariable, kein Wildcard in Produktion)", + "Preflight-Anfragen (OPTIONS) werden korrekt beantwortet fuer POST/GET-Endpunkte", + "RET-06-Frontend kann alle vier Endpunkte real aus einem Browser-Kontext (nicht nur curl) erreichen" + ], + "pruefungen": [ + "Realer Browser-Fetch (nicht curl) vom RET-06-Frontend gegen retention-api gelingt, Same-Origin-Policy nicht mehr blockierend", + "OPTIONS-Preflight liefert korrekte CORS-Header fuer POST /retention-classes", + "Fetch von einem NICHT konfigurierten Origin wird weiterhin blockiert (kein Wildcard-Leck)" + ], + "status": "Fertig", + "epicName": "Retention & WORM", + "epicEmoji": "⏳", + "wave": 5, + "unlocks": [], + "prompt": "# RET-10 – CORS für RET-06-API (Frontend-Zugriff aus dem Browser)\n\n**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexitaet:** Klein | **Aufwand:** 1 Personentag | **Welle:** 5\n\n---\n\n## Auftrag\nretention-api (RET-06-API) fehlen CORS-Header - ein echter Browser blockiert Fetches vom RET-06-Next.js-Frontend (anderer Origin/Port). CORS-Middleware ergaenzen, RET-06-API selbst NICHT sonst veraendern (kein Umbau einer fertigen Kachel ueber CORS hinaus).\n\n## Ausgangslage\nRET-06-API (fertig), RET-06 (fertig, eigenstaendige Next.js-App). Bei einer Sichtpruefung des laufenden RET-06-Frontends gegen das laufende Backend wurde festgestellt: curl funktioniert (keine CORS-Durchsetzung), ein echter Browser wuerde den Fetch jedoch blockieren (kein Access-Control-Allow-Origin-Header in der Antwort). Weder die Go-Tests (serverseitig) noch die Vitest-Tests (Node-Fetch, keine Browser-CORS-Durchsetzung) haben das erfasst.\n\n## Akzeptanzkriterien\n1. Access-Control-Allow-Origin fuer konfigurierten Frontend-Origin (kein Wildcard in Produktion)\n2. OPTIONS-Preflight korrekt beantwortet fuer POST/GET\n3. RET-06-Frontend erreicht alle vier Endpunkte real aus einem Browser-Kontext\n\n## Pruefungen vor der Abnahme\n1. Realer Browser-Fetch (nicht nur curl) gelingt\n2. OPTIONS-Preflight liefert korrekte Header fuer POST /retention-classes\n3. Fetch von nicht konfiguriertem Origin bleibt blockiert\n\n## Arbeitsweise\nKleinste Loesung, kein Umbau angrenzender Bereiche. Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy.\n\n## Abschluss\n- Commit-Nachricht: RET-10: cors-fuer-ret-06-api\n- Branch: feature/ret-10-cors-fuer-ret-06-api\n" + }, + { + "code": "RET-11", + "title": "Storage-seitige WORM-Durchsetzung (Object-Lock statt nur Anwendungslogik)", + "epic": "RET", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 2, + "tech": "S3 Object Lock / Compliance-Mode, PostgreSQL, Go", + "description": "RET-04 verhindert Änderung/Überschreiben archivierter Objektinhalte nach dem Schreiben, aber ohne explizite Festlegung, ob dies nur durch Anwendungscode (übersprungen bei direktem Storage-Zugriff) oder durch eine Storage-seitige Garantie (z. B. S3 Object Lock im Compliance-Mode) erzwungen wird. WORM-Objekte über die Object-Lock-Funktion des Storage-Backends selbst sperren, sodass auch ein Zugriff mit vollen Storage-Zugangsdaten unterhalb der Anwendung keine Änderung/Löschung vor Fristablauf erlaubt.", + "dependsOn": [ + "RET-04" + ], + "akzeptanz": [ + "Jedes WORM-Objekt wird beim Schreiben mit einer Storage-seitigen Object-Lock-Sperre bis zum Ablauf der Aufbewahrungsfrist versehen", + "Ein Löschversuch mit direkten Storage-Zugangsdaten (unterhalb der Anwendung) schlägt vor Fristablauf fehl, nachweislich durch das Storage-Backend selbst und nicht nur durch Anwendungscode", + "Nach Fristablauf und regulärer Freigabe (RET-03) ist das Objekt normal löschbar" + ], + "pruefungen": [ + "Test: direkter Löschversuch über die Storage-API (nicht über die NEXARCH-Anwendung) auf ein gesperrtes Objekt schlägt fehl", + "Test: nach Fristablauf und Freigabe durch RET-03 ist die Löschung über den regulären Workflow möglich", + "Konfigurationsprüfung: Object-Lock/Compliance-Mode ist für den produktiven Bucket aktiviert, dokumentiert in der Betriebsanleitung" + ], + "status": "Fertig", + "epicName": "Retention & WORM", + "epicEmoji": "⏳", + "wave": 7, + "unlocks": [], + "prompt": "# RET-11 – Storage-seitige WORM-Durchsetzung (Object-Lock statt nur Anwendungslogik)\n\n**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 7\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (Retention & WORM, Compliance & eDiscovery, Backup & Wiederherstellung, Kennzahlen), das sich an Alfresco, ecoDMS und restic/Borg orientiert.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nRET-04 verhindert Änderung/Überschreiben archivierter Objektinhalte nach dem Schreiben, aber ohne explizite Festlegung, ob dies nur durch Anwendungscode (übersprungen bei direktem Storage-Zugriff) oder durch eine Storage-seitige Garantie (z. B. S3 Object Lock im Compliance-Mode) erzwungen wird. WORM-Objekte über die Object-Lock-Funktion des Storage-Backends selbst sperren, sodass auch ein Zugriff mit vollen Storage-Zugangsdaten unterhalb der Anwendung keine Änderung/Löschung vor Fristablauf erlaubt.\n\n**Technische Grundlage:** S3 Object Lock / Compliance-Mode, PostgreSQL, Go\n\n## Produkt-DNA für diesen Bereich\n**Übernehmen:**\n- restic/Borg: Unveränderlichkeit als Eigenschaft des Speichers, nicht nur der aufrufenden Anwendung.\n\n**Bewusst vermeiden:**\n- Alfresco – in älteren Konfigurationen teils nur anwendungsseitige Lösch-Sperre ohne Storage-Garantie.: WORM ist eine Storage-Backend-Garantie (Object Lock), die Anwendungslogik ist die zweite, nicht die einzige Verteidigungslinie.\n\n## Ausgangslage\nSetzt auf folgenden bereits fertigen Kacheln auf: RET-04.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Jedes WORM-Objekt wird beim Schreiben mit einer Storage-seitigen Object-Lock-Sperre bis zum Ablauf der Aufbewahrungsfrist versehen\n2. Ein Löschversuch mit direkten Storage-Zugangsdaten (unterhalb der Anwendung) schlägt vor Fristablauf fehl, nachweislich durch das Storage-Backend selbst und nicht nur durch Anwendungscode\n3. Nach Fristablauf und regulärer Freigabe (RET-03) ist das Objekt normal löschbar\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: direkter Löschversuch über die Storage-API (nicht über die NEXARCH-Anwendung) auf ein gesperrtes Objekt schlägt fehl\n2. Test: nach Fristablauf und Freigabe durch RET-03 ist die Löschung über den regulären Workflow möglich\n3. Konfigurationsprüfung: Object-Lock/Compliance-Mode ist für den produktiven Bucket aktiviert, dokumentiert in der Betriebsanleitung\n\n## Bekannte Fehler vermeiden\n\nThreat-Model-Finding (Archive-Board, 2026-09-12): reine Anwendungslogik gegen Überschreiben schützt nicht gegen einen Akteur mit direktem Storage-Zugriff (kompromittierte Zugangsdaten, Fehlkonfiguration) — GoBD/WORM-Anforderungen verlangen eine tatsächlich technische, nicht nur anwendungsseitige Garantie.\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `RET-04` WORM-Speicher-Garantie (Append-only)\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: `RET-11: storage-seitige-worm-durchsetzung-object-lock-statt-nur-anwendungslogik`\n- Branch: `feature/ret-11-storage-seitige-worm-durchsetzung-object-lock-statt-nur-anwendungslogik`\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": "RET-12", + "title": "Unabhängige Tenant-Validierung bei Objekttyp-Registrierung durch DMS/Mail", + "epic": "RET", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 2, + "tech": "Service-Credentials (Core API-02), Tenant-Registry-Abgleich (Core TEN-01), Go", + "description": "RET-05 nimmt Objekttyp- und Aufbewahrungsklassen-Registrierungen von DMS und Mail entgegen. Ohne unabhängige Prüfung würde Archive dem vom registrierenden Modul mitgelieferten Tenant-Kontext blind vertrauen. Jede Registrierung muss den mitgelieferten Tenant-Kontext gegen die Core-Registry (TEN-01) validieren, unabhängig vom Service-Credential-Scope des aufrufenden Moduls – Archive verlässt sich nicht allein auf die Angabe von DMS/Mail.", + "dependsOn": [ + "RET-05" + ], + "akzeptanz": [ + "Jede Objekttyp-/Aufbewahrungsklassen-Registrierung aus DMS/Mail wird gegen die Core-Registry auf Tenant-Gültigkeit geprüft, bevor sie übernommen wird", + "Eine Registrierung mit einem nicht existierenden oder falschem Tenant-Kontext wird abgelehnt und protokolliert", + "Bestehende, korrekte Registrierungsabläufe aus RET-05 funktionieren unverändert" + ], + "pruefungen": [ + "Test: Registrierung mit gültigem, existierendem Tenant-Kontext wird übernommen", + "Test: Registrierung mit manipuliertem/fremdem Tenant-Kontext wird abgelehnt", + "Regressionstest: normaler DMS-/Mail-Registrierungsablauf bleibt funktionsfähig" + ], + "status": "Fertig", + "epicName": "Retention & WORM", + "epicEmoji": "⏳", + "wave": 7, + "unlocks": [], + "prompt": "# RET-12 – Unabhängige Tenant-Validierung bei Objekttyp-Registrierung durch DMS/Mail\n\n**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 7\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (Retention & WORM, Compliance & eDiscovery, Backup & Wiederherstellung, Kennzahlen), das sich an Alfresco, ecoDMS und restic/Borg orientiert.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nRET-05 nimmt Objekttyp- und Aufbewahrungsklassen-Registrierungen von DMS und Mail entgegen. Ohne unabhängige Prüfung würde Archive dem vom registrierenden Modul mitgelieferten Tenant-Kontext blind vertrauen. Jede Registrierung muss den mitgelieferten Tenant-Kontext gegen die Core-Registry (TEN-01) validieren, unabhängig vom Service-Credential-Scope des aufrufenden Moduls – Archive verlässt sich nicht allein auf die Angabe von DMS/Mail.\n\n**Technische Grundlage:** Service-Credentials (Core API-02), Tenant-Registry-Abgleich (Core TEN-01), Go\n\n## Produkt-DNA für diesen Bereich\n**Übernehmen:**\n- Casbin: Autorisierungsentscheidung bleibt zentral und unabhängig von der meldenden Quelle.\n\n**Bewusst vermeiden:**\n- Keycloak – Vertrauen in vom Client mitgelieferte Claims ohne serverseitige Gegenprüfung führte zu Eskalationsfällen.: Archive verifiziert den Tenant-Kontext jeder eingehenden Registrierung selbst gegen die Core-Registry, statt der Angabe des meldenden Moduls zu vertrauen.\n\n## Ausgangslage\nSetzt auf folgenden bereits fertigen Kacheln auf: RET-05.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Jede Objekttyp-/Aufbewahrungsklassen-Registrierung aus DMS/Mail wird gegen die Core-Registry auf Tenant-Gültigkeit geprüft, bevor sie übernommen wird\n2. Eine Registrierung mit einem nicht existierenden oder falschem Tenant-Kontext wird abgelehnt und protokolliert\n3. Bestehende, korrekte Registrierungsabläufe aus RET-05 funktionieren unverändert\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: Registrierung mit gültigem, existierendem Tenant-Kontext wird übernommen\n2. Test: Registrierung mit manipuliertem/fremdem Tenant-Kontext wird abgelehnt\n3. Regressionstest: normaler DMS-/Mail-Registrierungsablauf bleibt funktionsfähig\n\n## Bekannte Fehler vermeiden\n\nThreat-Model-Finding (Archive-Board, 2026-09-12): Archive ist die Senke für Retention-Registrierungen aus zwei anderen Modulen — ohne eigene Validierung würde ein Fehler oder eine Kompromittierung in DMS/Mail unmittelbar auf die Compliance-kritische Retention-Zuordnung in Archive durchschlagen.\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `RET-05` Modul-Adapter-Schnittstelle (DMS/Mail registrieren Objekttypen)\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: `RET-12: unabh-ngige-tenant-validierung-bei-objekttyp-registrierung-durch-dms-mail`\n- Branch: `feature/ret-12-unabh-ngige-tenant-validierung-bei-objekttyp-registrierung-durch-dms-mail`\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": "BAK-09", + "title": "Envelope-Encryption für Backup-Snapshots (Datenbank & Objekt-Storage)", + "epic": "BAK", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 2, + "tech": "Envelope-Encryption (Tenant-KEK aus Core API-10), restic/Borg-artige Sicherung", + "description": "BAK-01/BAK-02 sichern Datenbank und Objekt-Storage-Inhalte, ohne festzulegen, ob die Sicherungen selbst verschlüsselt sind. Archivierte Objekte sind live über die Tenant-KEK-Hierarchie (Core API-10) verschlüsselt – Backups dürfen kein schwächer geschütztes Abbild derselben Daten sein. Backup-Snapshots über denselben Tenant-KEK verschlüsseln wie die Live-Daten, sodass ein kompromittiertes Backup-Ziel ohne den jeweiligen Tenant-KEK keine verwertbaren Klartextdaten liefert.", + "dependsOn": [ + "BAK-01", + "BAK-02" + ], + "akzeptanz": [ + "Backup-Snapshots von Datenbank und Objekt-Storage sind mit dem Tenant-KEK des jeweiligen Mandanten verschlüsselt", + "Ein Zugriff auf das Backup-Ziel ohne den jeweiligen Tenant-KEK liefert keine verwertbaren Klartextdaten", + "Wiederherstellung (BAK-03/BAK-04) funktioniert unverändert unter Verwendung des korrekten Tenant-KEK" + ], + "pruefungen": [ + "Test: Backup-Datei ohne Tenant-KEK ist nicht auswertbar (Stichprobe auf Klartext-Reste)", + "Restore-Test mit korrektem Tenant-KEK stellt die Daten vollständig wieder her", + "Test: Restore mit falschem/fremdem Tenant-KEK schlägt fehl, statt fremde Daten zu liefern" + ], + "status": "Fertig", + "epicName": "Backup & Wiederherstellung", + "epicEmoji": "💾", + "wave": 7, + "unlocks": [], + "prompt": "# BAK-09 – Envelope-Encryption für Backup-Snapshots (Datenbank & Objekt-Storage)\n\n**Epic:** 💾 Backup & Wiederherstellung | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 7\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (Retention & WORM, Compliance & eDiscovery, Backup & Wiederherstellung, Kennzahlen), das sich an Alfresco, ecoDMS und restic/Borg orientiert.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nBAK-01/BAK-02 sichern Datenbank und Objekt-Storage-Inhalte, ohne festzulegen, ob die Sicherungen selbst verschlüsselt sind. Archivierte Objekte sind live über die Tenant-KEK-Hierarchie (Core API-10) verschlüsselt – Backups dürfen kein schwächer geschütztes Abbild derselben Daten sein. Backup-Snapshots über denselben Tenant-KEK verschlüsseln wie die Live-Daten, sodass ein kompromittiertes Backup-Ziel ohne den jeweiligen Tenant-KEK keine verwertbaren Klartextdaten liefert.\n\n**Technische Grundlage:** Envelope-Encryption (Tenant-KEK aus Core API-10), restic/Borg-artige Sicherung\n\n## Produkt-DNA für diesen Bereich\n**Übernehmen:**\n- restic/Borg: clientseitige Verschlüsselung vor dem Verlassen des Quellsystems als Standard, nicht als Zusatzoption.\n\n**Bewusst vermeiden:**\n- restic/Borg (Fehlkonfiguration in der Praxis) – unverschlüsseltes Backup-Repository bei falscher Einrichtung.: Verschlüsselung ist über die bestehende Tenant-KEK-Hierarchie erzwungen, keine separate, optionale Backup-Passphrase.\n\n## Ausgangslage\nSetzt auf folgenden bereits fertigen Kacheln auf: BAK-01, BAK-02.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Backup-Snapshots von Datenbank und Objekt-Storage sind mit dem Tenant-KEK des jeweiligen Mandanten verschlüsselt\n2. Ein Zugriff auf das Backup-Ziel ohne den jeweiligen Tenant-KEK liefert keine verwertbaren Klartextdaten\n3. Wiederherstellung (BAK-03/BAK-04) funktioniert unverändert unter Verwendung des korrekten Tenant-KEK\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: Backup-Datei ohne Tenant-KEK ist nicht auswertbar (Stichprobe auf Klartext-Reste)\n2. Restore-Test mit korrektem Tenant-KEK stellt die Daten vollständig wieder her\n3. Test: Restore mit falschem/fremdem Tenant-KEK schlägt fehl, statt fremde Daten zu liefern\n\n## Bekannte Fehler vermeiden\n\nThreat-Model-Finding (Archive-Board, 2026-09-12): ein unverschlüsseltes oder schwächer geschütztes Backup wäre ein einfacherer Angriffspfad auf dieselben Daten als das gut geschützte Live-System.\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `BAK-01` Datenbank-Backup-Strategie\n- `BAK-02` Objekt-Storage-Backup/Snapshots\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: `BAK-09: envelope-encryption-f-r-backup-snapshots-datenbank-objekt-storage`\n- Branch: `feature/bak-09-envelope-encryption-f-r-backup-snapshots-datenbank-objekt-storage`\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": "BAK-10", + "title": "Schutzniveau der Restore-Testumgebung (DSGVO-konform)", + "epic": "BAK", + "featureIds": [], + "role": "Backend", + "complexity": "Einfach", + "estimateDays": 1, + "tech": "Isolierte Testumgebung, Zugriffskontrolle, Betriebsdokument", + "description": "BAK-06 testet das Restore-Verfahren regelmäßig automatisiert gegen eine isolierte Testumgebung – diese enthält dabei zwangsläufig echte (wiederhergestellte) Mandantendaten. Ohne festgelegtes Schutzniveau könnte die Testumgebung schwächer abgesichert sein als die Produktivumgebung und so zu einem leichteren Angriffsziel für dieselben Daten werden. Schutzniveau der Testumgebung verbindlich festlegen (gleiche Zugriffskontrolle, Netzwerksegmentierung und Löschfrist nach Testlauf wie produktiv) und dokumentieren.", + "dependsOn": [ + "BAK-06" + ], + "akzeptanz": [ + "Die Restore-Testumgebung unterliegt derselben Zugriffskontrolle und Netzwerksegmentierung wie die Produktivumgebung", + "Wiederhergestellte Testdaten werden nach Abschluss des Testlaufs und Protokollierung des Ergebnisses gelöscht, nicht dauerhaft vorgehalten", + "Das Schutzniveau ist im Betriebsdokument zu BAK-06 explizit festgehalten" + ], + "pruefungen": [ + "Prüft Zugriffskontrolle/Netzwerksegmentierung der Testumgebung gegen die Produktivumgebung", + "Prüft, dass nach einem Testlauf keine wiederhergestellten Daten über die dokumentierte Frist hinaus verbleiben", + "Prüft, dass das Betriebsdokument das Schutzniveau explizit benennt" + ], + "status": "Fertig", + "epicName": "Backup & Wiederherstellung", + "epicEmoji": "💾", + "wave": 7, + "unlocks": [], + "prompt": "# BAK-10 – Schutzniveau der Restore-Testumgebung (DSGVO-konform)\n\n**Epic:** 💾 Backup & Wiederherstellung | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 1 Personentage | **Welle:** 7\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (Retention & WORM, Compliance & eDiscovery, Backup & Wiederherstellung, Kennzahlen), das sich an Alfresco, ecoDMS und restic/Borg orientiert.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nBAK-06 testet das Restore-Verfahren regelmäßig automatisiert gegen eine isolierte Testumgebung – diese enthält dabei zwangsläufig echte (wiederhergestellte) Mandantendaten. Ohne festgelegtes Schutzniveau könnte die Testumgebung schwächer abgesichert sein als die Produktivumgebung und so zu einem leichteren Angriffsziel für dieselben Daten werden. Schutzniveau der Testumgebung verbindlich festlegen (gleiche Zugriffskontrolle, Netzwerksegmentierung und Löschfrist nach Testlauf wie produktiv) und dokumentieren.\n\n**Technische Grundlage:** Isolierte Testumgebung, Zugriffskontrolle, Betriebsdokument\n\n## Produkt-DNA für diesen Bereich\n**Übernehmen:**\n- Betriebsdisziplin: Testdaten mit Personenbezug erhalten dasselbe Schutzniveau wie Produktivdaten, keine Ausnahme für Testumgebungen.\n\n**Bewusst vermeiden:**\n- verbreitetes Anti-Muster in Testumgebungen: Produktivdaten in schwächer gesicherte Staging-/Test-Umgebungen kopiert, dort länger als nötig aufbewahrt.: Restore-Testumgebung wird nach jedem Testlauf zurückgesetzt/gelöscht, Zugriffskontrolle identisch zu produktiv.\n\n## Ausgangslage\nSetzt auf folgenden bereits fertigen Kacheln auf: BAK-06.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Die Restore-Testumgebung unterliegt derselben Zugriffskontrolle und Netzwerksegmentierung wie die Produktivumgebung\n2. Wiederhergestellte Testdaten werden nach Abschluss des Testlaufs und Protokollierung des Ergebnisses gelöscht, nicht dauerhaft vorgehalten\n3. Das Schutzniveau ist im Betriebsdokument zu BAK-06 explizit festgehalten\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. Prüft Zugriffskontrolle/Netzwerksegmentierung der Testumgebung gegen die Produktivumgebung\n2. Prüft, dass nach einem Testlauf keine wiederhergestellten Daten über die dokumentierte Frist hinaus verbleiben\n3. Prüft, dass das Betriebsdokument das Schutzniveau explizit benennt\n\n## Bekannte Fehler vermeiden\n\nThreat-Model-Finding (Archive-Board, 2026-09-12): eine schwächer geschützte Testumgebung mit echten wiederhergestellten Mandantendaten würde den durch Modell C und Envelope-Encryption erreichten Schutz umgehen, ohne dass dies wie ein klassischer Sicherheitsvorfall aussieht.\n\n## Nicht Bestandteil dieser Kachel\nDiese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor:\n- `BAK-06` Restore-Testverfahren\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: `BAK-10: schutzniveau-der-restore-testumgebung-dsgvo-konform`\n- Branch: `feature/bak-10-schutzniveau-der-restore-testumgebung-dsgvo-konform`\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": "RET-15", + "title": "Echter End-zu-Ende-Nachweis Storage-Object-Lock auf chattr-fähigem Host", + "epic": "RET", + "featureIds": [], + "role": "Backend", + "complexity": "Einfach", + "estimateDays": 1, + "tech": "chattr-faehiger Host/Alternative", + "description": "Echter Ende-zu-Ende-Nachweis fuer RET-11 Storage-Object-Lock auf einem Host, auf dem chattr +i tatsaechlich wirkt (bisher auf Host 131/204 nicht moeglich, LXC/ZFS-Grenze).", + "dependsOn": [ + "RET-11", + "QA-02", + "QA-07", + "QA-05" + ], + "akzeptanz": [ + "chattr-faehiger Host/Alternative identifiziert", + "Loeschversuch schlaegt nachweislich fehl", + "Nachtrag zu RET-11 dokumentiert" + ], + "pruefungen": [ + "Test auf identifiziertem Host", + "Dokumentation falls kein Host verfuegbar" + ], + "status": "Backlog", + "epicName": "Retention & WORM", + "epicEmoji": "⏳", + "wave": 9, + "unlocks": [], + "prompt": "# RET-15 – Echter End-zu-Ende-Nachweis Storage-Object-Lock auf chattr-fähigem Host\n\n**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 1 Personentag | **Welle:** 9\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (Retention & WORM, Compliance & eDiscovery, Backup & Wiederherstellung, Kennzahlen), das sich an Alfresco, ecoDMS und restic/Borg orientiert.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nRET-11 implementiert Storage-Object-Lock über `chattr +i`. Auf beiden bisher geprüften Hosts (131, 204) scheitert `chattr +i` strukturell mit `EPERM`, weil beide unprivilegierte LXC-Container auf ZFS-Root sind (RET-11-PRUEFPROTOKOLL.md, bestätigt erneut in QA-02/QA-07/QA-05, Archive-Board). Der erfolgreiche Pfad (chattr-fähiger, privilegierter Host bzw. chattr-fähiges Dateisystem) wurde in diesem Projekt bislang auf keinem Host real bestätigt. `wormstore.Store.Put` ist fail-closed: schlägt `chattr +i` fehl, wird der Schreibvorgang verworfen — das ist technisch sicher (kein stiller Integritätsverlust), aber die eigentliche WORM-Garantie (Akzeptanzkriterium 1/2 aus RET-11) ist bislang nur per Code-Analyse, nicht per echtem End-zu-Ende-Test belegt.\n\n**Technische Grundlage:** chattr-fähiger Host oder chattr-fähiges Dateisystem (z. B. ext4 statt ZFS), oder eine der in der Untersuchung (siehe Nachtrag-Dokument, falls vorhanden) geprüften Alternativen.\n\n## Ausgangslage\nSetzt auf folgenden bereits fertigen Kacheln auf: RET-11, QA-02, QA-07, QA-05 (alle Archive-Board). Prüfe vor Beginn, ob zwischenzeitlich ein Nachtrag-Dokument zur chattr-Untersuchung existiert (`archive/docs/RET-11-NACHTRAG-CHATTR-UNTERSUCHUNG.md` oder ähnlich benannt) und baue darauf auf, statt die Untersuchung zu wiederholen.\n\n## Akzeptanzkriterien\n1. Ein Host oder eine Umgebung mit tatsächlich wirksamem `chattr +i` (oder einer als gleichwertig befundenen Alternative) ist identifiziert und dokumentiert\n2. Auf diesem Host/dieser Umgebung schlägt ein direkter Löschversuch auf ein storage-gesperrtes WORM-Objekt nachweislich fehl (echter Test, kein SKIP)\n3. Ergebnis ist im bestehenden RET-11-Prüfprotokoll als Nachtrag ergänzt, nicht als neues Parallel-Protokoll\n\n## Prüfungen vor der Abnahme\n1. Test auf dem identifizierten Host real ausgeführt, Ergebnis dokumentiert\n2. Falls kein chattr-fähiger Host verfügbar ist: begründete Dokumentation, dass dies weiterhin offen bleibt und welche Bedingung (z. B. privilegierter Produktions-Host) die Prüfung ermöglichen würde\n\n## Nicht Bestandteil dieser Kachel\n- Erneute Grundsatzuntersuchung aller Alternativen (bereits erfolgt, siehe Ausgangslage)\n- Produktiv-Rollout\n\n## Arbeitsweise\n1. Lies zuerst RET-11-PRUEFPROTOKOLL.md und ein eventuell vorhandenes Nachtrag-Dokument vollständig.\n2. Setze die kleinste Lösung um, die alle Akzeptanzkriterien erfüllt.\n3. Schreibe zu jedem Akzeptanzkriterium mindestens einen automatisierten Test, falls ein geeigneter Host verfügbar ist.\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: `RET-15: echter-ende-zu-ende-nachweis-storage-object-lock-chattr-faehiger-host`\n- Branch: `feature/ret-15-echter-ende-zu-ende-nachweis-storage-object-lock-chattr-faehiger-host`\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": "RET-16", + "title": "STORAGE-KONZEPT.md: Widerspruch ZFS als WORM-Backend klären", + "epic": "RET", + "featureIds": [], + "role": "Backend", + "complexity": "Einfach", + "estimateDays": 0.5, + "tech": "Dokumentation", + "description": "Ausnahmevermerk in STORAGE-KONZEPT.md: ZFS fuer WORM-Basisverzeichnis ungeeignet (chattr+i-Grenze), Verweis auf RET-11.", + "dependsOn": [ + "RET-11" + ], + "akzeptanz": [ + "Ausnahmevermerk ergaenzt", + "Verweis auf RET-11", + "keine sonstigen Aenderungen" + ], + "pruefungen": [ + "Dokument-Review", + "Diff-Pruefung" + ], + "status": "Backlog", + "epicName": "Retention & WORM", + "epicEmoji": "⏳", + "wave": 9, + "unlocks": [], + "prompt": "# RET-16 – STORAGE-KONZEPT.md: Widerspruch ZFS als WORM-Backend klären\n\n**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 0,5 Personentage | **Welle:** 9\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (Retention & WORM, Compliance & eDiscovery, Backup & Wiederherstellung, Kennzahlen), das sich an Alfresco, ecoDMS und restic/Borg orientiert.\n\n## Auftrag\n`STORAGE-KONZEPT.md` (Abschnitt 2) listet ZFS als gleichwertige Stufe-1-Backend-Option. `RET-11-PRUEFPROTOKOLL.md` (Prüfung 3) sieht das WORM-Basisverzeichnis ausdrücklich NICHT auf ZFS vor, weil `chattr +i` auf ZFS strukturell nicht funktioniert (bestätigt auf Host 131 und 204, siehe QA-02/QA-05/QA-07-Nachträge Archive-Board). Dieser Widerspruch zwischen Betriebsdokumentation und tatsächlicher technischer Einschränkung muss aufgelöst werden, bevor eine produktive Stufe-1-Inbetriebnahme auf ZFS-Basis erfolgt.\n\n## Akzeptanzkriterien\n1. `STORAGE-KONZEPT.md` Abschnitt 2 enthält einen expliziten Ausnahmevermerk: ZFS ist für das WORM-Basisverzeichnis (Archive-Modul) nicht geeignet, sofern keine alternative Durchsetzung (siehe RET-15) nachgewiesen ist\n2. Verweis auf RET-11-PRUEFPROTOKOLL.md als Quelle des Befundes ist im Dokument ergänzt\n3. Keine andere inhaltliche Aussage von STORAGE-KONZEPT.md wird verändert\n\n## Prüfungen vor der Abnahme\n1. Dokument-Review: Ausnahmevermerk ist vorhanden, eindeutig und widerspricht keiner anderen Stelle im Dokument\n2. Diff-Prüfung: keine ungewollten Änderungen außerhalb des betroffenen Abschnitts\n\n## Nicht Bestandteil dieser Kachel\n- Technische Lösung des chattr-Problems selbst (siehe RET-15)\n- Änderungen an anderen Konzeptdokumenten\n\n## Arbeitsweise\n1. Lies `STORAGE-KONZEPT.md` Abschnitt 2 und `RET-11-PRUEFPROTOKOLL.md` vollständig.\n2. Kleinste Änderung: nur den Ausnahmevermerk ergänzen, keine Umformulierung des übrigen Textes.\n3. Deutschsprachiger Text.\n\n## Abschluss\n- Commit-Nachricht: `RET-16: storage-konzept-widerspruch-zfs-als-worm-backend-klaeren`\n- Branch: `feature/ret-16-storage-konzept-widerspruch-zfs-als-worm-backend-klaeren`\n- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy.\n" + }, + { + "code": "CMP-08", + "title": "Ende-zu-Ende-Nachweis eDiscovery-Adapter (reale Drittmodul-Integration)", + "epic": "CMP", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 2, + "tech": "reale DMS-/Mail-Testinstanzen, RET-05", + "description": "Echter Ende-zu-Ende-Testlauf eDiscovery-Export gegen laufende DMS-/Mail-Testinstanzen statt nur Referenzdatensatz.", + "dependsOn": [ + "CMP-03", + "QA-03", + "RET-05" + ], + "akzeptanz": [ + "Export gegen echte DMS-/Mail-Instanzen", + "Treffer korrekt und pruefsummengesichert", + "Nachtrag zu QA-03 dokumentiert" + ], + "pruefungen": [ + "Echter Testlauf dokumentiert", + "Pruefsummen identisch", + "offene Restrisiken benannt" + ], + "status": "Backlog", + "epicName": "Compliance & eDiscovery", + "epicEmoji": "⚖️", + "wave": 9, + "unlocks": [], + "prompt": "# CMP-08 – Ende-zu-Ende-Nachweis eDiscovery-Adapter (reale Drittmodul-Integration)\n\n**Epic:** ⚖️ Compliance & eDiscovery | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 9\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (Retention & WORM, Compliance & eDiscovery, Backup & Wiederherstellung, Kennzahlen), das sich an Alfresco, ecoDMS und restic/Borg orientiert.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nQA-03 (Archive-Board, Prüfgate Compliance & eDiscovery) hat den eDiscovery-Export gegen den Referenzdatensatz real geprüft, aber den eDiscovery-Adapter zu DMS/Mail (die tatsächlichen Quellmodule der durchsuchten Objekte) nur fiktiv getestet (siehe QA-03-PRUEFPROTOKOLL.md, offene Restrisiken). Diese Kachel schließt die Lücke: ein echter Ende-zu-Ende-Testlauf, bei dem der eDiscovery-Export tatsächlich gegen laufende DMS- und Mail-Instanzen (nicht nur gegen Referenzdatensatz-Fixtures) durchgeführt wird.\n\n**Technische Grundlage:** reale DMS-/Mail-Testinstanzen auf Host 204, bestehender Modul-Adapter-Mechanismus (RET-05)\n\n## Ausgangslage\nSetzt auf folgenden bereits fertigen Kacheln auf: `CMP-03` eDiscovery-Suche & Export, `QA-03` Prüfgate Compliance & eDiscovery (Archive-Board), `RET-05` Modul-Adapter-Schnittstelle.\n\n## Akzeptanzkriterien\n1. eDiscovery-Export wird gegen echte, über RET-05 registrierte DMS- und Mail-Testinstanzen durchgeführt (nicht nur gegen Referenzdatensatz-Fixtures)\n2. Treffer aus beiden Modulen sind im Export korrekt vorhanden und prüfsummengesichert\n3. Ergebnis ist als Nachtrag zu QA-03-PRUEFPROTOKOLL.md dokumentiert\n\n## Prüfungen vor der Abnahme\n1. Echter Testlauf gegen laufende DMS- und Mail-Instanz durchgeführt, Ergebnis dokumentiert\n2. Export-Prüfsummen bei wiederholtem Testlauf identisch\n3. Offene Restrisiken (falls neue gefunden) schriftlich benannt\n\n## Nicht Bestandteil dieser Kachel\n- Neue eDiscovery-Funktionalität (nur End-zu-Ende-Nachweis des bestehenden Adapters)\n- RBAC-Rollenberechtigung der Vier-Augen-Freigabe (separates, bereits in QA-03 benanntes offenes Risiko)\n\n## Arbeitsweise\n1. Lies zuerst CMP-03, QA-03-PRUEFPROTOKOLL.md und RET-05 vollständig.\n2. Setze die kleinste Lösung um, die alle Akzeptanzkriterien erfüllt.\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: `CMP-08: ende-zu-ende-nachweis-ediscovery-adapter-reale-drittmodul-integration`\n- Branch: `feature/cmp-08-ende-zu-ende-nachweis-ediscovery-adapter-reale-drittmodul-integration`\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": "Rolle muss aus verifizierter Identität kommen, nicht aus Client-Header", + "epic": "SEC", + "featureIds": [], + "role": "Backend", + "complexity": "Hoch", + "estimateDays": 3, + "tech": "Go, bestehende Authentifizierungs-Infrastruktur (Session/JWT), Next.js (Frontend-Teil)", + "description": "Rolle wird in retentionapi/kennzahlenapi/complianceapi aus X-User-Role-Header statt verifizierter Identität gelesen (K3); NEXT_PUBLIC_USER_ROLE im Frontend muss entfernt werden.", + "dependsOn": [], + "akzeptanz": [ + "authz.go liest Rolle ausschliesslich aus verifizierter Identitaet (Session/JWT), X-User-Role wird ignoriert/abgelehnt", + "NEXT_PUBLIC_USER_ROLE aus compliance-reports und retention-admin Frontend entfernt", + "requested_by speichert nachvollziehbare Nutzeridentitaet statt nur Rollenname", + "CORS laesst Rollen-Header-basierte Cross-Origin-Zugriffe nicht mehr zu" + ], + "pruefungen": [ + "Angriff mit gefaelschtem X-User-Role Header real nachgestellt und als blockiert nachgewiesen", + "Legitimer Aufruf mit echter Rolle aus verifizierter Session funktioniert weiterhin", + "Audit-Log enthaelt tatsaechliche Nutzeridentitaet", + "Frontend-Build enthaelt NEXT_PUBLIC_USER_ROLE nachweislich nicht mehr" + ], + "status": "Backlog", + "epicName": "Sicherheit", + "epicEmoji": "🔒", + "wave": 10, + "unlocks": [ + "SEC-02" + ], + "prompt": "# SEC-01 – Rolle muss aus verifizierter Identität kommen, nicht aus Client-Header\n\n**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Hoch | **Aufwand:** 3 Personentage | **Welle:** 10\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nSecurity-Review (main-Branch, Fable 5.1) hat einen kritischen Befund (K3) bestätigt: `archive/internal/retentionapi/authz.go:26-33` liest die Rolle per `role := r.Header.Get(\"X-User-Role\")` direkt aus einem Client-Header und übergibt sie unverändert an `client.Authorize(ctx, role, permission)`. Geprüft wird nur \"darf Rolle X diese Aktion\", nicht \"hat der Aufrufer wirklich Rolle X\" – der Header ist durch jeden Aufrufer frei wählbar. Betroffen sind außerdem `kennzahlenapi/handler.go:30-31` und `complianceapi/handler.go:39-45`, die dasselbe Muster übernehmen. Das Frontend verstärkt den Missstand: `web/compliance-reports/lib/api.ts:22-26` und `web/retention-admin/lib/api.ts:22` senden `NEXT_PUBLIC_USER_ROLE` – eine öffentliche Build-Variable, die im Browser sichtbar und durch jeden Nutzer änderbar ist – direkt als Header, und CORS ist dafür offen konfiguriert (`retentionapi/cors.go:19`).\n\n**Angriffsszenario:** `curl -H 'X-User-Role: archive_admin' -d '{\"report_type\":\"dsgvo\",\"data_subject_ref\":\"\"}' POST /compliance/reports` erzeugt für jede beliebige Person einen DSGVO-Auskunftsbericht als CSV samt Download-Token, ohne dass der Aufrufer tatsächlich die Rolle `archive_admin` besitzt. Ebenso verkürzt `POST /retention-classes` mit demselben gefälschten Header Aufbewahrungsfristen und ermöglicht vorzeitige Löschbarkeit archivierter Objekte. `requested_by` wird dabei nur als Rollenname gespeichert (`complianceapi/handler.go:77`), sodass das Audit-Log nicht personenbezogen ist und der tatsächliche Angreifer nicht rekonstruierbar bleibt.\n\n**Technische Grundlage:** Go, bestehende Authentifizierungs-Infrastruktur (Session/JWT) der Plattform, Next.js (Frontend-Teil)\n\n## Ausgangslage\n`RET-01` Generisches Retention-Objektmodell, `CMP-02` DSGVO-/Datenschutz-Berichte und `RET-05` Modul-Adapter-Schnittstelle sind bereits fertiggestellt und betroffen; diese Kachel ändert ihre Autorisierungsschicht, nicht ihre fachliche Logik.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. `authz.go` liest die Rolle ausschließlich aus einer serverseitig verifizierten Identität (Session- oder JWT-Claim), niemals aus einem vom Client gesetzten Header; `X-User-Role` wird in retention-api, kennzahlenapi und complianceapi vollständig ignoriert bzw. abgelehnt\n2. `NEXT_PUBLIC_USER_ROLE` ist aus `web/compliance-reports/lib/api.ts` und `web/retention-admin/lib/api.ts` entfernt; die Rolle wird serverseitig aus der Session abgeleitet, nicht vom Client mitgesendet\n3. `requested_by` in `complianceapi/handler.go:77` speichert eine nachvollziehbare, personenbezogene Identität (z. B. User-ID aus der verifizierten Identität), nicht nur den Rollennamen\n4. CORS-Konfiguration in `retentionapi/cors.go:19` lässt Rollen-Header-basierte Cross-Origin-Zugriffe nicht mehr zu\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. Angriff real nachgestellt: `curl -H 'X-User-Role: archive_admin' ...` gegen `/compliance/reports` und `/retention-classes` mit einer Sitzung ohne diese Rolle ausgeführt – Ergebnis vor Fix: Bericht/Änderung wird erzeugt; Ergebnis nach Fix: Anfrage wird mit 401/403 abgelehnt\n2. Legitimer Aufruf mit echter `archive_admin`-Rolle aus verifizierter Session funktioniert weiterhin unverändert\n3. Audit-Log-Eintrag nach einem legitimen DSGVO-Bericht enthält die tatsächliche Nutzeridentität, nicht nur \"archive_admin\"\n4. Frontend-Build enthält `NEXT_PUBLIC_USER_ROLE` nachweislich nicht mehr (Grep im Build-Output)\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` Tenant-Validierung in kennzahlenapi\n- Aufbau eines neuen zentralen Identity-Providers (setzt vorhandene Session/JWT-Infrastruktur voraus, baut sie nicht neu)\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, einschließlich eines Negativtests, der den beschriebenen Angriff nachstellt und als blockiert nachweist.\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-01: rolle-aus-verifizierter-identitaet-statt-client-header`\n- Branch: `feature/sec-01-rolle-aus-verifizierter-identitaet-statt-client-header`\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-02", + "title": "Tenant-Validierung in kennzahlenapi fehlt (Cross-Tenant-Leseleck)", + "epic": "SEC", + "featureIds": [], + "role": "Backend", + "complexity": "Niedrig", + "estimateDays": 1, + "tech": "Go, bestehendes InstanceTenant-Validierungsmuster aus legalholdapi.go", + "description": "kennzahlenapi/handler.go:45 validiert den Query-Tenant nicht gegen InstanceTenant (H11), ermoeglicht Cross-Tenant-Lesen von Kennzahlen.", + "dependsOn": [], + "akzeptanz": [ + "handler.go validiert tenant Query-Parameter gegen InstanceTenant nach Muster aus legalholdapi.go", + "Abweichung fuehrt zu Ablehnung (403), kein stillschweigendes Ignorieren", + "Bestehende legitime Aufrufe funktionieren unveraendert" + ], + "pruefungen": [ + "Angriff mit fremdem tenant Query-Parameter real nachgestellt und als blockiert nachgewiesen", + "Legitimer Aufruf mit eigenem tenant liefert weiterhin korrekte Daten", + "Musterkonsistenz mit legalholdapi.go dokumentiert" + ], + "status": "Backlog", + "epicName": "Sicherheit", + "epicEmoji": "🔒", + "wave": 10, + "unlocks": [], + "prompt": "# SEC-02 – Tenant-Validierung in kennzahlenapi fehlt (Cross-Tenant-Leseleck)\n\n**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Niedrig | **Aufwand:** 1 Personentag | **Welle:** 10\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco, ecoDMS und restic/Borg orientiert.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nSecurity-Review (main-Branch, Fable 5.1) hat einen hohen Befund (H11) bestätigt: `archive/internal/kennzahlenapi/handler.go:45` liest `tenant := r.URL.Query().Get(\"tenant\")` und verwendet ihn direkt für die Datenabfrage – anders als `legalholdapi.go:82` fehlt hier der Vergleich mit `InstanceTenant`. `archive_metrics_snapshots` ist tenant-gespalten (Migration 0011) und wird aus `module_registrations.tenant_slug` befüllt. Ohne die Validierung kann jeder Aufrufer mit gültigem Zugriff auf die kennzahlen-api über `?tenant=` die Kennzahlen jedes beliebigen Mandanten lesen; in Kombination mit `SEC-01` (gefälschte Rolle) verschärft sich das Risiko zusätzlich.\n\n**Angriffsszenario:** `GET /kennzahlen?tenant=` liefert die `archive_metrics_snapshots` eines fremden Mandanten aus, obwohl der Aufrufer nur für den eigenen Mandanten berechtigt ist.\n\n**Technische Grundlage:** Go, bestehendes `InstanceTenant`-Validierungsmuster aus `legalholdapi.go:82`\n\n## Ausgangslage\n`RET-01` Generisches Retention-Objektmodell und die Kennzahlen-Aggregation (Migration 0011) sind bereits fertiggestellt. Diese Kachel übernimmt ausschließlich das bestehende Validierungsmuster aus `legalholdapi.go`.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. `kennzahlenapi/handler.go:45` validiert den Query-Parameter `tenant` gegen `InstanceTenant` nach demselben Muster wie `legalholdapi.go:82`\n2. Eine Abweichung zwischen angefragtem `tenant` und `InstanceTenant` führt zu einer Ablehnung der Anfrage (403), nicht zu stillschweigendem Ignorieren oder Filtern\n3. Bestehende legitime Aufrufe ohne abweichenden `tenant`-Parameter funktionieren unverändert\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. Angriff real nachgestellt: `GET /kennzahlen?tenant=` mit einer Sitzung eines anderen Mandanten ausgeführt – Ergebnis vor Fix: fremde Kennzahlen werden ausgeliefert; Ergebnis nach Fix: Anfrage wird mit 403 abgelehnt\n2. Legitimer Aufruf mit eigenem `tenant`-Parameter liefert weiterhin korrekte Daten\n3. Vergleich des neuen Codes mit `legalholdapi.go:82` auf Musterkonsistenz dokumentiert\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` Rolle muss aus verifizierter Identität kommen (behebt das zugrundeliegende RBAC-Problem, nicht Teil dieser Kachel)\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, einschließlich eines Negativtests, der den beschriebenen Angriff nachstellt und als blockiert nachweist.\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: tenant-validierung-kennzahlenapi`\n- Branch: `feature/sec-02-tenant-validierung-kennzahlenapi`\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-03", + "title": "TOCTOU Legal Hold vs. Destroy; Destroy ausserhalb der aeusseren Transaktion", + "epic": "SEC", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 2, + "tech": "PostgreSQL, pgx/v5, atomare UPDATE-Bedingungen, Transaktionssteuerung", + "description": "deletionworkflow.go prueft Legal Hold in separatem Query vor dem Loesch-UPDATE (TOCTOU, M1); deletionapproval.go ruft Destroy ausserhalb der aeusseren Transaktion auf.", + "dependsOn": [], + "akzeptanz": [ + "Legal-Hold-Pruefung ist Teil derselben atomaren UPDATE-Anweisung wie die Statusaenderung", + "Destroy() laeuft innerhalb derselben Transaktion wie die Antragsfinalisierung", + "Kein Codepfad mehr, in dem physische Vernichtung und DB-Zustand auseinanderlaufen" + ], + "pruefungen": [ + "TOCTOU-Fenster real nachgestellt (Legal Hold zwischen Pruefung und Update gesetzt) und als blockiert nachgewiesen", + "Simulierter Fehler nach Destroy() vor Commit nachgestellt, Konsistenz nachgewiesen", + "Regulaerer Loeschvorgang ohne Hold und ohne Fehler funktioniert weiterhin" + ], + "status": "Backlog", + "epicName": "Sicherheit", + "epicEmoji": "🔒", + "wave": 10, + "unlocks": [], + "prompt": "# SEC-03 – TOCTOU Legal Hold vs. Destroy; Destroy außerhalb der äußeren Transaktion\n\n**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 10\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco, ecoDMS und restic/Borg orientiert.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nSecurity-Review (main-Branch, Fable 5.1) hat einen mittleren Befund (M1) bestätigt: In `archive/internal/deletionworkflow/deletionworkflow.go:143-162` wird `IsOnLegalHold` als separater Query ausgeführt, bevor ein zweiter Schritt `UPDATE retention_objects SET status='deleted' WHERE id=$1 AND status='expired'` ausgeführt wird – ohne `AND NOT EXISTS (legal_holds...)` in derselben Anweisung. Ein zwischen den beiden Schritten gesetzter Legal Hold (klassisches TOCTOU-Zeitfenster) verhindert die Löschung nicht mehr. Zusätzlich ruft `archive/internal/deletionapproval/deletionapproval.go:112-118` `Destroy(ctx, pool, …)` mit dem rohen Connection-Pool statt mit einer Transaktion auf – das Objekt wird physisch vernichtet, selbst wenn der äußere Löschantrag danach nicht committet wird (z. B. bei einem nachfolgenden Fehler in der Antragsfinalisierung).\n\n**Angriffsszenario / Fehlerszenario:** Ein Objekt wird zur Löschung freigegeben; unmittelbar danach wird (z. B. durch eDiscovery oder einen Rechtsstreit) ein Legal Hold gesetzt. Da die Prüfung nicht atomar mit der Löschung verknüpft ist, wird das Objekt trotz aktivem Legal Hold gelöscht. Zusätzlich kann ein Fehler nach `Destroy()`, aber vor Commit des äußeren Löschantrags dazu führen, dass die physische Vernichtung bereits stattgefunden hat, während der Datenbankzustand den Löschantrag als nicht abgeschlossen zeigt – ein inkonsistenter, nicht revidierbarer Zustand.\n\n**Technische Grundlage:** PostgreSQL, pgx/v5, atomare UPDATE-Bedingungen, Transaktionssteuerung\n\n## Ausgangslage\n`RET-04` WORM-Speicher-Garantie und das Legal-Hold-Datenmodell (`legal_holds`-Tabelle) sind bereits fertiggestellt. Diese Kachel ändert ausschließlich die Reihenfolge und Atomizität bestehender Löschlogik.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Die Legal-Hold-Prüfung ist Teil derselben atomaren `UPDATE`-Anweisung wie die Statusänderung auf `deleted` (z. B. `AND NOT EXISTS (SELECT 1 FROM legal_holds ...)` in derselben Anweisung), sodass ein zwischen Prüfung und Update gesetzter Legal Hold die Löschung zuverlässig verhindert\n2. `Destroy(ctx, pool, …)` in `deletionapproval.go:112-118` wird innerhalb derselben Transaktion ausgeführt wie die Antragsfinalisierung; schlägt die Finalisierung fehl, wird die Destroy-Wirkung nicht wirksam (Rollback) bzw. die physische Löschung erfolgt erst nach erfolgreichem Commit\n3. Es gibt keinen Codepfad mehr, auf dem ein Objekt physisch vernichtet wird, während der zugehörige DB-Zustand den Löschantrag noch als offen/nicht abgeschlossen zeigt\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. TOCTOU real nachgestellt: Legal Hold wird exakt im Zeitfenster zwischen Prüfung und Update gesetzt (z. B. über parallele Testroutine oder gezielte Verzögerung) – Ergebnis vor Fix: Löschung erfolgt trotz Hold; Ergebnis nach Fix: Löschung wird blockiert\n2. Simulierter Fehler nach `Destroy()` und vor Commit der äußeren Transaktion nachgestellt – Ergebnis nach Fix: entweder Destroy wird nicht wirksam oder der DB-Zustand bleibt konsistent mit der physischen Löschung\n3. Regulärer Löschvorgang ohne Legal Hold und ohne Fehler funktioniert 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` wormstore Release/Destroy ohne Legal-Hold-Prüfung (eigenständiger Befund in anderer Schicht)\n- `SEC-06` Append-only-Lücken inkl. `legal_holds`-Kaskade (DB-seitige Schutzschicht, nicht Teil dieser Kachel)\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, einschließlich eines Tests, der das TOCTOU-Fenster real nachstellt und als blockiert nachweist.\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: toctou-legal-hold-destroy-atomar`\n- Branch: `feature/sec-03-toctou-legal-hold-destroy-atomar`\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": "wormstore: Release/Destroy ohne Legal-Hold-Pruefung, Reihenfolge-Problem", + "epic": "SEC", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 2, + "tech": "Go, Dateisystemoperationen, Zwei-Phasen-Commit-Muster, Pfad-Validierung", + "description": "wormstore.go prueft bei Release/Destroy keinen Legal Hold, physische Operation erfolgt vor DB-Commit (M2); filepath.Join ohne Traversal-Check auf key.", + "dependsOn": [], + "akzeptanz": [ + "Release/Destroy pruefen vor Ausfuehrung aktiven Legal Hold und verweigern bei Treffer", + "Physische Operation erfolgt erst nach erfolgreichem DB-Commit bzw. Zwei-Phasen-Commit-Muster verhindert inkonsistenten Zwischenzustand", + "key wird gegen Pfad-Traversal validiert" + ], + "pruefungen": [ + "Release/Destroy mit aktivem Legal Hold real nachgestellt und als blockiert nachgewiesen", + "Simulierter Absturz zwischen physischer Operation und Commit nachgestellt, kein inkonsistenter Zustand", + "Traversal-Angriff mit ../ Segmenten real nachgestellt und als blockiert nachgewiesen", + "Regulaerer Release/Destroy ohne Hold und ohne Traversal funktioniert weiterhin" + ], + "status": "Backlog", + "epicName": "Sicherheit", + "epicEmoji": "🔒", + "wave": 10, + "unlocks": [], + "prompt": "# SEC-04 – wormstore: Release/Destroy ohne Legal-Hold-Prüfung, Reihenfolge-Problem\n\n**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 10\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco, ecoDMS und restic/Borg orientiert.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nSecurity-Review (main-Branch, Fable 5.1) hat einen mittleren Befund (M2) bestätigt: `archive/internal/wormstore/wormstore.go:152-208` prüft bei Release/Destroy keinen Legal Hold. Zusätzlich erfolgt die physische Operation (`chattr -i`/`os.Remove`, Zeile 177/203) vor dem DB-Commit (Zeile 183/206) – bei einem Absturz zwischen beiden Schritten ist die Datei bereits physisch weg, während der DB-Zustand sie noch als vorhanden ausweist, was einen nicht mehr rekonstruierbaren Widerspruch zwischen Storage und Datenbank erzeugt. Weiterhin verwendet `:72-73` `filepath.Join(baseDir, key)` ohne Traversal-Check auf `key`; aktuell gibt es keinen produktiven Aufrufer mit nutzerkontrolliertem `key`, das Risiko ist aber latent und soll nicht erst bei Einführung eines solchen Aufrufers behoben werden müssen.\n\n**Angriffsszenario / Fehlerszenario:** Ein WORM-Objekt mit aktivem Legal Hold wird über den `wormstore`-Layer direkt released/destroyed, ohne dass dieser Layer den Hold prüft (Umgehung der Prüfung aus `deletionworkflow`, falls `wormstore` auf einem anderen Pfad aufgerufen wird). Bei einem Prozessabsturz zwischen physischer Löschung und DB-Commit entsteht ein WORM-Objekt, das laut Datenbank noch existiert, physisch aber bereits vernichtet ist – ein Verstoß gegen die Nachweispflicht der Revisionssicherheit. Ein künftiger Aufrufer mit nutzerkontrolliertem `key` könnte zusätzlich mittels Pfad-Traversal (`../../`) auf Dateien außerhalb von `baseDir` zugreifen.\n\n**Technische Grundlage:** Go, Dateisystemoperationen, Zwei-Phasen-Commit-Muster, Pfad-Validierung\n\n## Ausgangslage\n`RET-04` WORM-Speicher-Garantie (Append-only) ist bereits fertiggestellt. Diese Kachel ändert ausschließlich die Reihenfolge und Absicherung bestehender Release/Destroy-Operationen in `wormstore`.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Release und Destroy in `wormstore.go` prüfen vor jeder Ausführung einen aktiven Legal Hold und verweigern die Operation bei Treffer\n2. Die physische Löschung/Freigabe (`chattr -i`/`os.Remove`) erfolgt erst nach erfolgreichem DB-Commit, oder es wird ein Zwei-Phasen-Commit-Muster verwendet, das einen Absturz zwischen beiden Schritten konsistent auflöst (kein Zustand, in dem physisch bereits gelöscht, aber DB-Status noch \"vorhanden\" ist)\n3. `filepath.Join(baseDir, key)` in `:72-73` validiert `key` gegen Pfad-Traversal (z. B. Ablehnung von `..`-Segmenten oder Pfaden, die außerhalb von `baseDir` aufgelöst werden)\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. Angriff real nachgestellt: Release/Destroy eines Objekts mit aktivem Legal Hold direkt über `wormstore` aufgerufen – Ergebnis vor Fix: Operation wird durchgeführt; Ergebnis nach Fix: Operation wird verweigert\n2. Simulierter Absturz zwischen physischer Operation und DB-Commit nachgestellt – Ergebnis nach Fix: kein inkonsistenter Zwischenzustand mehr erreichbar, oder Zustand ist beim nächsten Start automatisch erkennbar/korrigierbar\n3. Traversal-Angriff real nachgestellt: `key` mit `../`-Segmenten übergeben – Ergebnis vor Fix: Zugriff außerhalb `baseDir` möglich; Ergebnis nach Fix: Anfrage wird abgelehnt\n4. Regulärer Release/Destroy ohne Legal Hold und ohne Traversal-Versuch funktioniert 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-03` TOCTOU Legal Hold vs. Destroy im `deletionworkflow` (höhere Schicht, eigenständiger Befund)\n- Einführung eines neuen Aufrufers mit nutzerkontrolliertem `key` (nicht Teil dieser Kachel, nur die Absicherung dagegen)\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, einschließlich eines Negativtests, der den beschriebenen Angriff nachstellt und als blockiert nachweist.\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: wormstore-legal-hold-reihenfolge-traversal`\n- Branch: `feature/sec-04-wormstore-legal-hold-reihenfolge-traversal`\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": "moduleadapter /register: fehlende Tenant-Bindung, optionale Authentifizierung", + "epic": "SEC", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 2, + "tech": "PostgreSQL, SQL-Migrationen (kein ORM), Go, bestehende Authentifizierungs-Middleware", + "description": "UNIQUE(module_name, object_type) ohne Tenant-Spalte (M3) erlaubt Cross-Tenant-Kollision bei Registrierung; ALLOW_UNAUTHENTICATED=true schaltet Auth fuer /register und /legal-hold komplett ab.", + "dependsOn": [], + "akzeptanz": [ + "UNIQUE-Constraint umfasst Tenant-Spalte, zwei Mandanten koennen denselben module_name/object_type unabhaengig registrieren", + "Migration ueberfuehrt bestehende Registrierungen korrekt, ist rueckrollbar", + "ALLOW_UNAUTHENTICATED hat in keiner produktionsnahen Konfiguration Standardwert true", + "/register und /legal-hold verlangen bei deaktiviertem Schalter gueltige Authentifizierung" + ], + "pruefungen": [ + "Cross-Tenant-Kollision bei Registrierung real nachgestellt, nach Fix bestehen beide Registrierungen unabhaengig", + "Migration vorwaerts und rueckwaerts gegen Datenbank mit bestehenden Testregistrierungen getestet", + "Aufruf ohne Authentifizierung bei deaktiviertem Schalter real nachgestellt und als blockiert nachgewiesen", + "Bestehende authentifizierte Registrierungsablaeufe funktionieren weiterhin" + ], + "status": "Backlog", + "epicName": "Sicherheit", + "epicEmoji": "🔒", + "wave": 10, + "unlocks": [], + "prompt": "# SEC-05 – moduleadapter /register: fehlende Tenant-Bindung, optionale Authentifizierung\n\n**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 10\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco, ecoDMS und restic/Borg orientiert.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nSecurity-Review (main-Branch, Fable 5.1) hat einen mittleren Befund (M3) bestätigt: In `archive/internal/moduleadapter/handler.go:83-95` und `moduleadapter.go:52-66` fehlt bei der Registrierung von Modul-Adaptern die Tenant-Bindung – Migration `0003:14` definiert `UNIQUE(module_name, object_type)` ohne Tenant-Spalte, sodass das erste registrierende Modul die `callback_url` tenant-übergreifend \"gewinnt\" und spätere Registrierungen anderer Mandanten für denselben `module_name`/`object_type` entweder fehlschlagen oder die bestehende Zuordnung überschreiben. Zusätzlich schaltet `cmd/moduleadapter-api/main.go:47` mit `ALLOW_UNAUTHENTICATED=true` die Authentifizierung für `/register` und `/legal-hold` komplett ab; es ist ungeklärt, ob/wo dieser Schalter im Produktivbetrieb tatsächlich gesetzt ist.\n\n**Angriffsszenario:** Mandant A registriert zuerst einen Adapter für `module_name=\"dms\"`, `object_type=\"document\"` mit eigener `callback_url`. Mandant B registriert denselben `module_name`/`object_type` – ohne Tenant-Spalte im UNIQUE-Constraint kollidiert die Registrierung mit der von Mandant A, wodurch entweder Mandant Bs Registrierung fehlschlägt oder (abhängig vom Upsert-Verhalten) Mandant As `callback_url` durch Mandant Bs überschrieben wird. Letzteres würde bedeuten, dass WORM-/Legal-Hold-Callbacks für Mandant As Objekte künftig an Mandant Bs Endpunkt gehen. Ist `ALLOW_UNAUTHENTICATED=true` in einer produktionsnahen Umgebung gesetzt, kann zudem jeder unauthentifizierte Aufrufer `/register` und `/legal-hold` ansprechen.\n\n**Technische Grundlage:** PostgreSQL, SQL-Migrationen (kein ORM), Go, bestehende Authentifizierungs-Middleware\n\n## Ausgangslage\n`RET-05` Modul-Adapter-Schnittstelle (DMS/Mail registrieren Objekttypen) ist bereits fertiggestellt und wird hier um die Tenant-Bindung und verbindliche Authentifizierung ergänzt.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. Der UNIQUE-Constraint auf der Modul-Registrierungstabelle umfasst eine Tenant-Spalte (`UNIQUE(tenant, module_name, object_type)` oder äquivalent), sodass zwei Mandanten denselben `module_name`/`object_type` unabhängig voneinander registrieren können\n2. Eine Migration überführt bestehende Registrierungen korrekt in das neue Schema, ist rückrollbar und läuft gegen eine Datenbank mit vorhandenen Testregistrierungen durch\n3. `ALLOW_UNAUTHENTICATED` hat in keiner produktionsnahen Konfiguration (sofern im Deployment-Code auffindbar) einen Standardwert `true`; der Schalter ist klar als \"nur für isolierte Testumgebungen\" dokumentiert und per Default `false`\n4. `/register` und `/legal-hold` verlangen bei `ALLOW_UNAUTHENTICATED=false` (bzw. ohne den Schalter) eine gültige Authentifizierung\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. Angriff real nachgestellt: zwei Mandanten registrieren denselben `module_name`/`object_type` – Ergebnis vor Fix: Kollision/Überschreiben nachgewiesen; Ergebnis nach Fix: beide Registrierungen bestehen unabhängig nebeneinander\n2. Migration vorwärts und rückwärts gegen Datenbank mit bestehenden Testregistrierungen getestet\n3. Aufruf von `/register` ohne Authentifizierung bei `ALLOW_UNAUTHENTICATED=false` real nachgestellt – Ergebnis: Anfrage wird mit 401 abgelehnt\n4. Bestehende, korrekt authentifizierte Registrierungsabläufe 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-01` Rolle muss aus verifizierter Identität kommen (eigenständiger RBAC-Befund, andere Komponente)\n- Prüfung/Anpassung konkreter Produktions-Deployment-Konfigurationen außerhalb dieses Repos\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, einschließlich eines Negativtests, der den beschriebenen Angriff nachstellt und als blockiert nachweist.\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: moduleadapter-tenant-bindung-pflicht-authentifizierung`\n- Branch: `feature/sec-05-moduleadapter-tenant-bindung-pflicht-authentifizierung`\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": "Append-only-Luecken bei mehreren Archive-Tabellen", + "epic": "SEC", + "featureIds": [], + "role": "Backend", + "complexity": "Mittel", + "estimateDays": 2, + "tech": "PostgreSQL, SQL-Migrationen, bestehendes REVOKE/Trigger-Muster aus RET-11/AUD-07", + "description": "legal_holds hat ON DELETE CASCADE, retention_class_assignments/dsgvo_decision_log/deletion_requests/worm_objects haben trotz Append-only-Anspruch kein DB-seitiges REVOKE/Trigger (M4).", + "dependsOn": [], + "akzeptanz": [ + "legal_holds verwendet ON DELETE RESTRICT oder eigene Historisierung statt CASCADE", + "Betroffene vier Tabellen erhalten REVOKE UPDATE/DELETE von App-Rolle plus Trigger mit RAISE WARNING nach RET-11/AUD-07-Muster", + "Bestehender Code mit UPDATE/DELETE auf worm_objects auf Insert-only-Logik umgestellt" + ], + "pruefungen": [ + "Direkter UPDATE/DELETE-Versuch auf allen vier Tabellen real nachgestellt und als blockiert/protokolliert nachgewiesen", + "Loeschen eines Objekts mit aktivem Legal Hold real nachgestellt, Kaskaden-Verlust des Hold-Nachweises verhindert", + "Migration vorwaerts und rueckwaerts gegen Datenbank mit Testdaten getestet", + "Umgestellter Anwendungscode fuer worm_objects mit regulaerem Statuswechsel-Testfall erfolgreich durchlaufen" + ], + "status": "Backlog", + "epicName": "Sicherheit", + "epicEmoji": "🔒", + "wave": 10, + "unlocks": [], + "prompt": "# SEC-06 – Append-only-Lücken bei mehreren Archive-Tabellen\n\n**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 10\n\n---\n\n## Rolle\nDu bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco, ecoDMS und restic/Borg orientiert.\nServerseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche.\n\n## Auftrag\nSecurity-Review (main-Branch, Fable 5.1) hat einen mittleren Befund (M4) bestätigt: Mehrere Tabellen mit Append-only-Anspruch sind DB-seitig nicht dagegen abgesichert. `legal_holds` hat `ON DELETE CASCADE`, was der Append-only-Absicht direkt widerspricht (löscht man das referenzierte Objekt, verschwindet der Legal-Hold-Nachweis mit). `retention_class_assignments`, `dsgvo_decision_log`, `deletion_requests` und `worm_objects` haben trotz \"append-only\"-Anspruch kein DB-seitiges REVOKE/Trigger gegen UPDATE/DELETE – der Code selbst führt auf `worm_objects` UPDATE/DELETE aus, was zeigt, dass die Absicherung bislang rein konventionell (nicht technisch erzwungen) ist. `RET-11`/`AUD-07` haben für vergleichbare Tabellen bereits das etablierte Muster (REVOKE UPDATE/DELETE von der App-Rolle + Trigger mit RAISE WARNING) umgesetzt – dieses Muster fehlt hier.\n\n**Angriffsszenario:** Ein Angreifer mit Datenbankzugriff (z. B. über eine kompromittierte Anwendungsrolle oder eine SQL-Injection in einer anderen Komponente) kann ohne DB-seitige Sperre Einträge in `dsgvo_decision_log`, `deletion_requests` oder `worm_objects` nachträglich verändern oder löschen, um eine vorgenommene Löschentscheidung oder einen WORM-Nachweis zu vertuschen. Das Löschen eines referenzierten Objekts entfernt per `ON DELETE CASCADE` automatisch den zugehörigen `legal_holds`-Eintrag, wodurch ein zuvor bestehender Aufbewahrungssperren-Nachweis rückwirkend verschwindet.\n\n**Technische Grundlage:** PostgreSQL, SQL-Migrationen, bestehendes REVOKE/Trigger-Muster aus `RET-11`/`AUD-07`\n\n## Ausgangslage\n`RET-11` und `AUD-07` haben das REVOKE/Trigger-Muster für vergleichbare Tabellen bereits etabliert und fertiggestellt. Diese Kachel wendet dasselbe Muster auf die restlichen betroffenen Tabellen an.\n\n## Akzeptanzkriterien\nDie Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind:\n1. `legal_holds` verwendet statt `ON DELETE CASCADE` entweder `ON DELETE RESTRICT` oder eine eigene Historisierung, sodass das Löschen eines referenzierten Objekts den Legal-Hold-Nachweis nicht mitentfernt\n2. `retention_class_assignments`, `dsgvo_decision_log`, `deletion_requests` und `worm_objects` erhalten nach dem Muster aus `RET-11`/`AUD-07` ein REVOKE von UPDATE/DELETE für die Anwendungsrolle sowie einen Trigger, der versuchte UPDATE/DELETE-Zugriffe mit `RAISE WARNING` protokolliert und verweigert\n3. Bestehender Code, der aktuell UPDATE/DELETE auf `worm_objects` ausführt, ist auf Insert-only-/Statuswechsel-per-neuem-Datensatz-Logik umgestellt, sodass er mit der neuen DB-Sperre kompatibel ist\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. Angriff real nachgestellt: direkter UPDATE/DELETE-Versuch auf jede der vier Tabellen mit der Anwendungsrolle ausgeführt – Ergebnis vor Fix: Änderung gelingt; Ergebnis nach Fix: Zugriff wird verweigert und als Warnung protokolliert\n2. Löschen eines Objekts mit aktivem Legal Hold real nachgestellt – Ergebnis vor Fix: `legal_holds`-Eintrag verschwindet per Kaskade; Ergebnis nach Fix: Löschung wird verweigert (RESTRICT) oder Hold bleibt historisiert bestehen\n3. Migration vorwärts und rückwärts gegen Datenbank mit bestehenden Testdaten in allen vier Tabellen getestet\n4. Umgestellter Anwendungscode für `worm_objects` mit regulärem Statuswechsel-Testfall erfolgreich durchlaufen\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` TOCTOU Legal Hold vs. Destroy (eigenständiger Befund in der Anwendungslogik, nicht Teil dieser DB-seitigen Absicherung)\n- `SEC-04` wormstore Release/Destroy (Dateisystem-Schicht, nicht Teil dieser Kachel)\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, einschließlich eines Negativtests, der den beschriebenen Angriff nachstellt und als blockiert nachweist.\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: append-only-absicherung-archive-tabellen`\n- Branch: `feature/sec-06-append-only-absicherung-archive-tabellen`\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" + } + ] +} \ No newline at end of file diff --git a/archive-kanban/kanban.html b/archive-kanban/kanban.html new file mode 100644 index 00000000..35ac5429 --- /dev/null +++ b/archive-kanban/kanban.html @@ -0,0 +1,50 @@ + + + + + +Archive Kanban – lokal + + + +
    +
    +

    Archive Kanban – lokal, offline, ohne Server

    + + + + + + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +

    +

    Baut auf

    +

    Schaltet frei

    +

    Akzeptanzkriterien

      +

      Prüfungen vor der Abnahme

        +

        Bau-Prompt

        
        +  
        +
        + + + + + diff --git a/archive-kanban/tickets/ANA-01.md b/archive-kanban/tickets/ANA-01.md new file mode 100644 index 00000000..667530b3 --- /dev/null +++ b/archive-kanban/tickets/ANA-01.md @@ -0,0 +1,61 @@ +# ANA-01 – Kennzahlen-Aggregation (modulübergreifend) + +**Epic:** 📊 Kennzahlen & Reporting | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 3 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Zentraler Dienst, der Kennzahlen (Objektbestand, Aufbewahrungsstatus, Löschvorgänge, Speichervolumen) aus allen über RET-05 registrierten Modulen aggregiert. + +**Technische Grundlage:** Aggregations-Job über registrierte Module + +## Produkt-DNA für diesen Bereich +> Kennzahlen modulübergreifend an einer Stelle, nicht in jedem Modul einzeln nachgebaut. + +**Übernehmen:** +- Ein Aggregationsdienst für Kennzahlen aus DMS, Mail und Archive statt Silo-Reports je Modul. +- Dashboard mit Facetten und Filtern statt starrer Report-Vorlagen. + +**Bewusst vermeiden:** +- Keine Kennzahlenlogik, die doppelt in DMS und Mail gepflegt werden muss. + +**Für genau diese Kachel:** Eine Aggregationsstelle für alle Module – DMS und Mail bauen keine eigene Kennzahlenlogik mehr. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `RET-05` Modul-Adapter-Schnittstelle (DMS/Mail registrieren Objekttypen) – Schnittstelle, über die DMS und Mail ihre Objekttypen (Dokument, Mail, Anhang) und die zugehörige Aufbewahrungsklasse bei Archive registrieren, statt eigene Retention-Logik zu bauen. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Kennzahlen werden je Tenant und Modul sowie modulübergreifend aggregiert +2. Aggregation läuft periodisch und liefert konsistente Werte über einen Zeitverlauf +3. Neues registriertes Modul wird ohne Codeänderung in die Aggregation einbezogen + +## 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. Aggregation über zwei fiktive Module liefert korrekte Summen- und Einzelwerte +2. Wiederholte Aggregation ohne Datenänderung liefert stabile Ergebnisse +3. Neu registriertes drittes Testmodul erscheint automatisch in der nächsten Aggregation + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `ANA-02` Auswertungs-Dashboard +- `ANA-03` Lizenz-/Nutzungs-Reports + +## 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: `ANA-01: kennzahlen-aggregation-modulübergreifend` +- Branch: `feature/ana-01-kennzahlen-aggregation-modulübergreifend` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/ANA-02.md b/archive-kanban/tickets/ANA-02.md new file mode 100644 index 00000000..d56b1355 --- /dev/null +++ b/archive-kanban/tickets/ANA-02.md @@ -0,0 +1,60 @@ +# ANA-02 – Auswertungs-Dashboard + +**Epic:** 📊 Kennzahlen & Reporting | **Rolle:** Frontend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 4 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Frontend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Oberfläche und Bedienbarkeit. Ruft ausschließlich vorhandene Schnittstellen auf, keine eigene Geschäftslogik. + +## Auftrag +Dashboard zur Visualisierung der aggregierten Kennzahlen mit Filtern nach Tenant, Modul und Zeitraum. + +**Technische Grundlage:** Next.js/React/TypeScript + +## Produkt-DNA für diesen Bereich +> Kennzahlen modulübergreifend an einer Stelle, nicht in jedem Modul einzeln nachgebaut. + +**Übernehmen:** +- Ein Aggregationsdienst für Kennzahlen aus DMS, Mail und Archive statt Silo-Reports je Modul. +- Dashboard mit Facetten und Filtern statt starrer Report-Vorlagen. + +**Bewusst vermeiden:** +- Keine Kennzahlenlogik, die doppelt in DMS und Mail gepflegt werden muss. + +**Für genau diese Kachel:** Kennzahlen ohne Dashboard bleiben Rohdaten – erst die Visualisierung macht sie für Fachanwender nutzbar. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `ANA-01` Kennzahlen-Aggregation (modulübergreifend) – Zentraler Dienst, der Kennzahlen (Objektbestand, Aufbewahrungsstatus, Löschvorgänge, Speichervolumen) aus allen über RET-05 registrierten Modulen aggregiert. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Dashboard zeigt Bestands-, Aufbewahrungs- und Löschkennzahlen je Tenant +2. Filter nach Modul und Zeitraum funktionieren kombinierbar +3. Dashboard lädt auch bei großem Datenbestand in angemessener Zeit + +## 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. Filterkombination liefert dieselben Werte wie eine direkte Abfrage der Aggregation +2. Dashboard mit synthetisch großem Testbestand bleibt bedienbar +3. Rollen ohne Berechtigung sehen keine Kennzahlen fremder Tenants + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- Alles, was nicht in den Akzeptanzkriterien steht. Keine vorauseilende Umsetzung späterer Anforderungen. + +## 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: `ANA-02: auswertungs-dashboard` +- Branch: `feature/ana-02-auswertungs-dashboard` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/ANA-03.md b/archive-kanban/tickets/ANA-03.md new file mode 100644 index 00000000..fcd784f2 --- /dev/null +++ b/archive-kanban/tickets/ANA-03.md @@ -0,0 +1,60 @@ +# ANA-03 – Lizenz-/Nutzungs-Reports + +**Epic:** 📊 Kennzahlen & Reporting | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 2 Personentage | **Welle:** 4 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Bericht über Nutzung und Lizenzrelevantes je Tenant (Speichervolumen, aktive Objekte, Nutzeranzahl-Bezug), abgestimmt mit dem Lizenzmodell aus NEXARCH Core. + +**Technische Grundlage:** CSV/PDF-Export + +## Produkt-DNA für diesen Bereich +> Kennzahlen modulübergreifend an einer Stelle, nicht in jedem Modul einzeln nachgebaut. + +**Übernehmen:** +- Ein Aggregationsdienst für Kennzahlen aus DMS, Mail und Archive statt Silo-Reports je Modul. +- Dashboard mit Facetten und Filtern statt starrer Report-Vorlagen. + +**Bewusst vermeiden:** +- Keine Kennzahlenlogik, die doppelt in DMS und Mail gepflegt werden muss. + +**Für genau diese Kachel:** Lizenzrelevante Nutzungswerte gehören sauber belegt vorzuliegen, statt bei Bedarf händisch aus Rohdaten geschätzt zu werden. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `ANA-01` Kennzahlen-Aggregation (modulübergreifend) – Zentraler Dienst, der Kennzahlen (Objektbestand, Aufbewahrungsstatus, Löschvorgänge, Speichervolumen) aus allen über RET-05 registrierten Modulen aggregiert. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Bericht zeigt lizenzrelevante Nutzungswerte je Tenant für einen wählbaren Zeitraum +2. Werte stimmen mit der zugrunde liegenden Kennzahlen-Aggregation überein +3. Export ist als CSV und PDF verfügbar + +## 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. Bericht für Testzeitraum stimmt mit manuell nachgerechneten Werten überein +2. Export in beiden Formaten enthält identische Kernwerte +3. Bericht für Tenant ohne Aktivität liefert nachvollziehbar leere/Null-Werte statt Fehler + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- Alles, was nicht in den Akzeptanzkriterien steht. Keine vorauseilende Umsetzung späterer Anforderungen. + +## 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: `ANA-03: lizenz-nutzungs-reports` +- Branch: `feature/ana-03-lizenz-nutzungs-reports` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/BAK-01.md b/archive-kanban/tickets/BAK-01.md new file mode 100644 index 00000000..1d6cf7c3 --- /dev/null +++ b/archive-kanban/tickets/BAK-01.md @@ -0,0 +1,62 @@ +# BAK-01 – Datenbank-Backup-Strategie + +**Epic:** 💾 Backup & Wiederherstellung | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 1 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Automatisierte, inkrementelle Sicherung der PostgreSQL-Datenbank mit Aufbewahrung mehrerer Generationen und Verifikation jeder Sicherung. + +**Technische Grundlage:** PostgreSQL (pg_dump/pg_basebackup), inkrementelle Sicherung + +## Produkt-DNA für diesen Bereich +> Sicherung nach dem Vorbild von restic/Borg: inkrementell, deduplizierend, verifizierbar. + +**Übernehmen:** +- restic/Borg: Inkrementelle, deduplizierende Sicherung mit Verifikation jeder Sicherung. +- restic/Borg: Wiederherstellung ist Routine, nicht Ausnahmefall – regelmäßig getestet. +- Reconciliation zwischen Objekt-Storage und Datenbank als eigenständige, planbare Prüfung. + +**Bewusst vermeiden:** +- Keine Sicherung ohne belegten Wiederherstellungstest – eine ungeprüfte Sicherung zählt nicht als Sicherung. +- Kein Restore, der ein nicht-leeres Zielverzeichnis direkt überschreibt, ohne Atomarität zu garantieren. + +**Für genau diese Kachel:** Ohne verifizierte Sicherung ist jede spätere Wiederherstellung reine Hoffnung – die Verifikation ist deshalb Pflichtbestandteil, nicht Kür. + +## Ausgangslage +Diese Kachel hat keine Vorbedingungen und ist sofort startbar. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Vollsicherung und inkrementelle Sicherung laufen automatisiert nach Zeitplan +2. Jede Sicherung wird nach Abschluss auf Lesbarkeit verifiziert, nicht nur auf Erstellung geprüft +3. Mehrere Sicherungsgenerationen werden nach konfigurierbarer Regel vorgehalten und alte automatisch entfernt + +## 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. Sicherung gegen Testdatenbank erfolgreich erstellt und verifiziert +2. Verifikation erkennt eine absichtlich beschädigte Sicherungsdatei +3. Rotationsregel entfernt nachweislich nur die ältesten Generationen + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `BAK-03` Restore-Verfahren +- `BAK-05` Reconciliation (Konsistenzprüfung Storage vs. DB) + +## 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: `BAK-01: datenbank-backup-strategie` +- Branch: `feature/bak-01-datenbank-backup-strategie` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/BAK-02.md b/archive-kanban/tickets/BAK-02.md new file mode 100644 index 00000000..3df76e56 --- /dev/null +++ b/archive-kanban/tickets/BAK-02.md @@ -0,0 +1,62 @@ +# BAK-02 – Objekt-Storage-Backup/Snapshots + +**Epic:** 💾 Backup & Wiederherstellung | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 1 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Automatisierte, deduplizierende Sicherung der im Objekt-Storage abgelegten Dateiinhalte, angelehnt an das restic/Borg-Sicherungskonzept. + +**Technische Grundlage:** Objekt-Storage-Snapshots, inkrementell und deduplizierend + +## Produkt-DNA für diesen Bereich +> Sicherung nach dem Vorbild von restic/Borg: inkrementell, deduplizierend, verifizierbar. + +**Übernehmen:** +- restic/Borg: Inkrementelle, deduplizierende Sicherung mit Verifikation jeder Sicherung. +- restic/Borg: Wiederherstellung ist Routine, nicht Ausnahmefall – regelmäßig getestet. +- Reconciliation zwischen Objekt-Storage und Datenbank als eigenständige, planbare Prüfung. + +**Bewusst vermeiden:** +- Keine Sicherung ohne belegten Wiederherstellungstest – eine ungeprüfte Sicherung zählt nicht als Sicherung. +- Kein Restore, der ein nicht-leeres Zielverzeichnis direkt überschreibt, ohne Atomarität zu garantieren. + +**Für genau diese Kachel:** Inkrementell und deduplizierend wie restic/Borg – Sicherungsvolumen und -dauer bleiben auch bei großen Beständen beherrschbar. + +## Ausgangslage +Diese Kachel hat keine Vorbedingungen und ist sofort startbar. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Sicherung erfasst neue und geänderte Objekte inkrementell, ohne unveränderte Objekte erneut zu übertragen +2. Sicherung ist deduplizierend, identische Inhalte werden nur einmal gespeichert +3. Jede Sicherung lässt sich einzeln auf Vollständigkeit 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. Zweiter Sicherungslauf nach unverändertem Bestand überträgt keine Daten erneut +2. Zwei identische Testdateien belegen nachweislich nur einmal Speicherplatz +3. Vollständigkeitsprüfung erkennt ein fehlendes Objekt in der Sicherung + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `BAK-03` Restore-Verfahren +- `BAK-05` Reconciliation (Konsistenzprüfung Storage vs. DB) + +## 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: `BAK-02: objekt-storage-backup-snapshots` +- Branch: `feature/bak-02-objekt-storage-backup-snapshots` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/BAK-03.md b/archive-kanban/tickets/BAK-03.md new file mode 100644 index 00000000..ebde7eae --- /dev/null +++ b/archive-kanban/tickets/BAK-03.md @@ -0,0 +1,68 @@ +# BAK-03 – Restore-Verfahren + +**Epic:** 💾 Backup & Wiederherstellung | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 2 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Dokumentiertes, wiederholbares Verfahren zur Wiederherstellung von Datenbank und Objekt-Storage aus einer Sicherung, für Notfall wie für Einzelobjekt-Restore. + +**Technische Grundlage:** Atomarer Restore über temporäres Verzeichnis + +## Produkt-DNA für diesen Bereich +> Sicherung nach dem Vorbild von restic/Borg: inkrementell, deduplizierend, verifizierbar. + +**Übernehmen:** +- restic/Borg: Inkrementelle, deduplizierende Sicherung mit Verifikation jeder Sicherung. +- restic/Borg: Wiederherstellung ist Routine, nicht Ausnahmefall – regelmäßig getestet. +- Reconciliation zwischen Objekt-Storage und Datenbank als eigenständige, planbare Prüfung. + +**Bewusst vermeiden:** +- Keine Sicherung ohne belegten Wiederherstellungstest – eine ungeprüfte Sicherung zählt nicht als Sicherung. +- Kein Restore, der ein nicht-leeres Zielverzeichnis direkt überschreibt, ohne Atomarität zu garantieren. + +**Für genau diese Kachel:** Restore ist das eigentliche Produkt einer Sicherung – eine Sicherung ohne funktionierenden Restore ist wertlos. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `BAK-01` Datenbank-Backup-Strategie – Automatisierte, inkrementelle Sicherung der PostgreSQL-Datenbank mit Aufbewahrung mehrerer Generationen und Verifikation jeder Sicherung. +- `BAK-02` Objekt-Storage-Backup/Snapshots – Automatisierte, deduplizierende Sicherung der im Objekt-Storage abgelegten Dateiinhalte, angelehnt an das restic/Borg-Sicherungskonzept. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Restore stellt Datenbank und Objekt-Storage aus einer gewählten Sicherungsgeneration wieder her +2. Restore in ein nicht-leeres Zielverzeichnis beschädigt den bestehenden Inhalt nicht, solange der Vorgang nicht bestätigt wird +3. Restore-Vorgang wird protokolliert (Quelle, Zeitpunkt, Ergebnis) + +## 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. Restore auf leerem System vollständig und erfolgreich durchgeführt +2. Restore auf nicht-leeres Zielverzeichnis lässt bei Abbruch den ursprünglichen Inhalt unverändert +3. Protokolleintrag zum Restore ist vollständig und nachvollziehbar + +## Bekannte Fehler vermeiden + +Aus einem bereits produktiven Schwestersystem bekannt: Restore in ein nicht-leeres Zielverzeichnis kann den bestehenden Inhalt beschädigen, wenn nicht atomar vorgegangen wird (`cmd_backup.go:206`, Bug-Klasse „-force restore where destination isn't empty“). Restore deshalb immer in ein leeres temporäres Verzeichnis schreiben und erst danach per atomarem Swap (z. B. Verzeichnis-Rename) an die Zielstelle bringen. Niemals direkt in ein belegtes Zielverzeichnis hineinschreiben. + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `BAK-04` Tenant-Backup & -Restore (einzelner Mandant) +- `BAK-06` Restore-Testverfahren + +## 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: `BAK-03: restore-verfahren` +- Branch: `feature/bak-03-restore-verfahren` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/BAK-04.md b/archive-kanban/tickets/BAK-04.md new file mode 100644 index 00000000..ff937bbd --- /dev/null +++ b/archive-kanban/tickets/BAK-04.md @@ -0,0 +1,62 @@ +# BAK-04 – Tenant-Backup & -Restore (einzelner Mandant) + +**Epic:** 💾 Backup & Wiederherstellung | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 3 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Sicherung und Wiederherstellung der Daten eines einzelnen Mandanten, ohne andere Mandanten zu berühren – etwa für Mandanten-Umzug oder isolierte Notfallwiederherstellung. + +**Technische Grundlage:** Tenant-scharfer Export/Import auf Basis von BAK-03 + +## Produkt-DNA für diesen Bereich +> Sicherung nach dem Vorbild von restic/Borg: inkrementell, deduplizierend, verifizierbar. + +**Übernehmen:** +- restic/Borg: Inkrementelle, deduplizierende Sicherung mit Verifikation jeder Sicherung. +- restic/Borg: Wiederherstellung ist Routine, nicht Ausnahmefall – regelmäßig getestet. +- Reconciliation zwischen Objekt-Storage und Datenbank als eigenständige, planbare Prüfung. + +**Bewusst vermeiden:** +- Keine Sicherung ohne belegten Wiederherstellungstest – eine ungeprüfte Sicherung zählt nicht als Sicherung. +- Kein Restore, der ein nicht-leeres Zielverzeichnis direkt überschreibt, ohne Atomarität zu garantieren. + +**Für genau diese Kachel:** Ein Mandant will manchmal umziehen oder isoliert wiederhergestellt werden, ohne dass alle anderen Mandanten betroffen sind. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `BAK-03` Restore-Verfahren – Dokumentiertes, wiederholbares Verfahren zur Wiederherstellung von Datenbank und Objekt-Storage aus einer Sicherung, für Notfall wie für Einzelobjekt-Restore. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Sicherung eines Tenants enthält ausschließlich dessen Daten aus Datenbank und Objekt-Storage +2. Wiederherstellung eines Tenants verändert keine Daten anderer Tenants +3. Tenant-Sicherung lässt sich unabhängig vom Gesamt-Backup planen und ausführen + +## 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. Sicherung von Tenant A enthält keine Datensätze von Tenant B (Stichprobe) +2. Wiederherstellung von Tenant A in eine Testumgebung verändert Tenant B dort nicht +3. Tenant-Sicherung und -Restore vollständig protokolliert + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- Alles, was nicht in den Akzeptanzkriterien steht. Keine vorauseilende Umsetzung späterer Anforderungen. + +## 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: `BAK-04: tenant-backup-und-restore-einzelner-mandant` +- Branch: `feature/bak-04-tenant-backup-und-restore-einzelner-mandant` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/BAK-05.md b/archive-kanban/tickets/BAK-05.md new file mode 100644 index 00000000..bdffc64f --- /dev/null +++ b/archive-kanban/tickets/BAK-05.md @@ -0,0 +1,63 @@ +# BAK-05 – Reconciliation (Konsistenzprüfung Storage vs. DB) + +**Epic:** 💾 Backup & Wiederherstellung | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 2 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Periodische Prüfung, ob jeder in der Datenbank referenzierte Objekt-Storage-Eintrag tatsächlich existiert und umgekehrt, mit Bericht über Abweichungen. + +**Technische Grundlage:** Geplanter Abgleichs-Job, Postgres-Jobqueue + +## Produkt-DNA für diesen Bereich +> Sicherung nach dem Vorbild von restic/Borg: inkrementell, deduplizierend, verifizierbar. + +**Übernehmen:** +- restic/Borg: Inkrementelle, deduplizierende Sicherung mit Verifikation jeder Sicherung. +- restic/Borg: Wiederherstellung ist Routine, nicht Ausnahmefall – regelmäßig getestet. +- Reconciliation zwischen Objekt-Storage und Datenbank als eigenständige, planbare Prüfung. + +**Bewusst vermeiden:** +- Keine Sicherung ohne belegten Wiederherstellungstest – eine ungeprüfte Sicherung zählt nicht als Sicherung. +- Kein Restore, der ein nicht-leeres Zielverzeichnis direkt überschreibt, ohne Atomarität zu garantieren. + +**Für genau diese Kachel:** Sicherung und Datenbank laufen über Jahre leicht auseinander – Reconciliation macht diesen stillen Drift sichtbar, bevor ein Restore daran scheitert. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `BAK-01` Datenbank-Backup-Strategie – Automatisierte, inkrementelle Sicherung der PostgreSQL-Datenbank mit Aufbewahrung mehrerer Generationen und Verifikation jeder Sicherung. +- `BAK-02` Objekt-Storage-Backup/Snapshots – Automatisierte, deduplizierende Sicherung der im Objekt-Storage abgelegten Dateiinhalte, angelehnt an das restic/Borg-Sicherungskonzept. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Job erkennt Datenbankeinträge ohne zugehöriges Objekt im Storage +2. Job erkennt Objekte im Storage ohne zugehörigen Datenbankeintrag +3. Abweichungen werden berichtet, nicht automatisch stillschweigend behoben + +## 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. Absichtlich entferntes Storage-Objekt wird vom Job als Abweichung erkannt +2. Absichtlich verwaister Datenbankeintrag wird vom Job als Abweichung erkannt +3. Lauf ohne Abweichungen liefert einen leeren, eindeutig als sauber erkennbaren Bericht + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- Alles, was nicht in den Akzeptanzkriterien steht. Keine vorauseilende Umsetzung späterer Anforderungen. + +## 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: `BAK-05: reconciliation-konsistenzprüfung-storage-vs-db` +- Branch: `feature/bak-05-reconciliation-konsistenzprüfung-storage-vs-db` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/BAK-06.md b/archive-kanban/tickets/BAK-06.md new file mode 100644 index 00000000..6cf1b8a8 --- /dev/null +++ b/archive-kanban/tickets/BAK-06.md @@ -0,0 +1,62 @@ +# BAK-06 – Restore-Testverfahren + +**Epic:** 💾 Backup & Wiederherstellung | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 2 Personentage | **Welle:** 3 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Regelmäßiger, automatisierter Testlauf des Restore-Verfahrens gegen eine isolierte Testumgebung, mit Ergebnisprotokoll als Nachweis der Wiederherstellbarkeit. + +**Technische Grundlage:** Automatisierter, periodischer Restore-Test in Testumgebung + +## Produkt-DNA für diesen Bereich +> Sicherung nach dem Vorbild von restic/Borg: inkrementell, deduplizierend, verifizierbar. + +**Übernehmen:** +- restic/Borg: Inkrementelle, deduplizierende Sicherung mit Verifikation jeder Sicherung. +- restic/Borg: Wiederherstellung ist Routine, nicht Ausnahmefall – regelmäßig getestet. +- Reconciliation zwischen Objekt-Storage und Datenbank als eigenständige, planbare Prüfung. + +**Bewusst vermeiden:** +- Keine Sicherung ohne belegten Wiederherstellungstest – eine ungeprüfte Sicherung zählt nicht als Sicherung. +- Kein Restore, der ein nicht-leeres Zielverzeichnis direkt überschreibt, ohne Atomarität zu garantieren. + +**Für genau diese Kachel:** Eine Sicherung gilt erst als geprüft, wenn ihr Restore regelmäßig und automatisiert getestet wird – nicht nur einmal beim Einrichten. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `BAK-03` Restore-Verfahren – Dokumentiertes, wiederholbares Verfahren zur Wiederherstellung von Datenbank und Objekt-Storage aus einer Sicherung, für Notfall wie für Einzelobjekt-Restore. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Testlauf führt einen vollständigen Restore in eine isolierte Testumgebung durch +2. Ergebnis (erfolgreich/fehlgeschlagen) wird mit Zeitstempel protokolliert +3. Fehlgeschlagener Testlauf löst eine sichtbare Warnung aus + +## 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. Geplanter Testlauf gegen aktuelle Sicherung erfolgreich durchgeführt und protokolliert +2. Absichtlich beschädigte Sicherung lässt den Testlauf sichtbar fehlschlagen +3. Protokollhistorie zeigt mehrere zurückliegende Testläufe nachvollziehbar an + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `QA-04` Prüfgate Backup & Restore + +## 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: `BAK-06: restore-testverfahren` +- Branch: `feature/bak-06-restore-testverfahren` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/BAK-07.md b/archive-kanban/tickets/BAK-07.md new file mode 100644 index 00000000..b77b6e1a --- /dev/null +++ b/archive-kanban/tickets/BAK-07.md @@ -0,0 +1,65 @@ +# BAK-07 – Aufbewahrungsfrist für Backup-Snapshots + +**Epic:** 💾 Backup & Wiederherstellung | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 2 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Eigene, von der Dokumenten-Retention (RET-02) unabhängige Aufbewahrungsfrist für Backup-Snapshots selbst – nach restic/Borg-Vorbild eine Prune-Policy (z. B. tägliche Snapshots 14 Tage, wöchentliche 3 Monate, monatliche 1 Jahr – konkrete Staffelung als Konfiguration, nicht hart codiert), damit Backups nicht unbegrenzt wachsen, aber auch nicht zu früh gelöscht werden. + +**Technische Grundlage:** PostgreSQL, Postgres-Jobqueue (geplante Jobs statt Redis) + +## Produkt-DNA für diesen Bereich +> Sicherung nach dem Vorbild von restic/Borg: inkrementell, deduplizierend, verifizierbar. + +**Übernehmen:** +- restic/Borg: Inkrementelle, deduplizierende Sicherung mit Verifikation jeder Sicherung. +- restic/Borg: eigene, konfigurierbare Prune-Policy für die Aufbewahrung der Sicherungen selbst (Staffelung nach Alter). +- Reconciliation zwischen Objekt-Storage und Datenbank als eigenständige, planbare Prüfung. + +**Bewusst vermeiden:** +- Backup-Aufbewahrung mit der Dokumenten-Retention (RET-02) zu verwechseln ist ein Kategorienfehler – ein Dokument kann 10 Jahre aufbewahrungspflichtig sein, während die tägliche Backup-Kopie davon nur 14 Tage vorgehalten werden muss, weil die nächste Kopie sie ohnehin ersetzt. Beide Fristen sind unabhängig konfigurierbar, nicht gekoppelt. +- Kein Pruning, das den letzten verbliebenen Snapshot eines noch unter Aufbewahrungssperre (Legal Hold) stehenden Dokuments entfernt, solange kein aktuellerer Snapshot dieses Dokument enthält. + +**Für genau diese Kachel:** Ohne eigene Prune-Policy wachsen Backups unbegrenzt oder werden willkürlich gelöscht – die Frist für die Sicherung selbst ist eine andere Frist als die für das gesicherte Dokument. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `BAK-01` Datenbank-Backup-Strategie – Automatisierte, inkrementelle Sicherung der PostgreSQL-Datenbank mit Aufbewahrung mehrerer Generationen und Verifikation jeder Sicherung. +- `BAK-02` Objekt-Storage-Backup/Snapshots – Automatisierte, deduplizierende Sicherung der im Objekt-Storage abgelegten Dateiinhalte. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Backup-Snapshots folgen einer konfigurierbaren Prune-Policy (Staffelung nach Alter), unabhängig von RET-02 +2. Snapshot-Löschung nach Ablauf der Frist läuft automatisiert +3. Eine gültige, nicht abgelaufene Aufbewahrungssperre auf einem Dokument (RET-03/CMP-06) verhindert nicht das Pruning älterer Backup-Snapshots, solange mindestens ein aktueller Snapshot das Dokument noch enthält + +## 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. Prune-Test mit simulierten Snapshots über mehrere Altersstufen ergibt korrekte Staffelung +2. Automatisierte Löschung abgelaufener Snapshots im Test nachgewiesen +3. Legal-Hold-Test bestätigt, dass Pruning nicht mit Dokumenten-Retention kollidiert + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `RET-02` Aufbewahrungsfristen-Engine (Dokumenten-Retention) +- `RET-03` Löschworkflow & Aufbewahrungssperre (Legal Hold) +- `BAK-03` Restore-Verfahren + +## 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: `BAK-07: aufbewahrungsfrist-fuer-backup-snapshots` +- Branch: `feature/bak-07-aufbewahrungsfrist-fuer-backup-snapshots` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/BAK-09.md b/archive-kanban/tickets/BAK-09.md new file mode 100644 index 00000000..a67d54be --- /dev/null +++ b/archive-kanban/tickets/BAK-09.md @@ -0,0 +1,59 @@ +# BAK-09 – Envelope-Encryption für Backup-Snapshots (Datenbank & Objekt-Storage) + +**Epic:** 💾 Backup & Wiederherstellung | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 7 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (Retention & WORM, Compliance & eDiscovery, Backup & Wiederherstellung, Kennzahlen), das sich an Alfresco, ecoDMS und restic/Borg orientiert. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +BAK-01/BAK-02 sichern Datenbank und Objekt-Storage-Inhalte, ohne festzulegen, ob die Sicherungen selbst verschlüsselt sind. Archivierte Objekte sind live über die Tenant-KEK-Hierarchie (Core API-10) verschlüsselt – Backups dürfen kein schwächer geschütztes Abbild derselben Daten sein. Backup-Snapshots über denselben Tenant-KEK verschlüsseln wie die Live-Daten, sodass ein kompromittiertes Backup-Ziel ohne den jeweiligen Tenant-KEK keine verwertbaren Klartextdaten liefert. + +**Technische Grundlage:** Envelope-Encryption (Tenant-KEK aus Core API-10), restic/Borg-artige Sicherung + +## Produkt-DNA für diesen Bereich +**Übernehmen:** +- restic/Borg: clientseitige Verschlüsselung vor dem Verlassen des Quellsystems als Standard, nicht als Zusatzoption. + +**Bewusst vermeiden:** +- restic/Borg (Fehlkonfiguration in der Praxis) – unverschlüsseltes Backup-Repository bei falscher Einrichtung.: Verschlüsselung ist über die bestehende Tenant-KEK-Hierarchie erzwungen, keine separate, optionale Backup-Passphrase. + +## Ausgangslage +Setzt auf folgenden bereits fertigen Kacheln auf: BAK-01, BAK-02. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Backup-Snapshots von Datenbank und Objekt-Storage sind mit dem Tenant-KEK des jeweiligen Mandanten verschlüsselt +2. Ein Zugriff auf das Backup-Ziel ohne den jeweiligen Tenant-KEK liefert keine verwertbaren Klartextdaten +3. Wiederherstellung (BAK-03/BAK-04) funktioniert unverändert unter Verwendung des korrekten Tenant-KEK + +## 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. Test: Backup-Datei ohne Tenant-KEK ist nicht auswertbar (Stichprobe auf Klartext-Reste) +2. Restore-Test mit korrektem Tenant-KEK stellt die Daten vollständig wieder her +3. Test: Restore mit falschem/fremdem Tenant-KEK schlägt fehl, statt fremde Daten zu liefern + +## Bekannte Fehler vermeiden + +Threat-Model-Finding (Archive-Board, 2026-09-12): ein unverschlüsseltes oder schwächer geschütztes Backup wäre ein einfacherer Angriffspfad auf dieselben Daten als das gut geschützte Live-System. + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `BAK-01` Datenbank-Backup-Strategie +- `BAK-02` Objekt-Storage-Backup/Snapshots + +## 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: `BAK-09: envelope-encryption-f-r-backup-snapshots-datenbank-objekt-storage` +- Branch: `feature/bak-09-envelope-encryption-f-r-backup-snapshots-datenbank-objekt-storage` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/BAK-10.md b/archive-kanban/tickets/BAK-10.md new file mode 100644 index 00000000..76132c3f --- /dev/null +++ b/archive-kanban/tickets/BAK-10.md @@ -0,0 +1,58 @@ +# BAK-10 – Schutzniveau der Restore-Testumgebung (DSGVO-konform) + +**Epic:** 💾 Backup & Wiederherstellung | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 1 Personentage | **Welle:** 7 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (Retention & WORM, Compliance & eDiscovery, Backup & Wiederherstellung, Kennzahlen), das sich an Alfresco, ecoDMS und restic/Borg orientiert. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +BAK-06 testet das Restore-Verfahren regelmäßig automatisiert gegen eine isolierte Testumgebung – diese enthält dabei zwangsläufig echte (wiederhergestellte) Mandantendaten. Ohne festgelegtes Schutzniveau könnte die Testumgebung schwächer abgesichert sein als die Produktivumgebung und so zu einem leichteren Angriffsziel für dieselben Daten werden. Schutzniveau der Testumgebung verbindlich festlegen (gleiche Zugriffskontrolle, Netzwerksegmentierung und Löschfrist nach Testlauf wie produktiv) und dokumentieren. + +**Technische Grundlage:** Isolierte Testumgebung, Zugriffskontrolle, Betriebsdokument + +## Produkt-DNA für diesen Bereich +**Übernehmen:** +- Betriebsdisziplin: Testdaten mit Personenbezug erhalten dasselbe Schutzniveau wie Produktivdaten, keine Ausnahme für Testumgebungen. + +**Bewusst vermeiden:** +- verbreitetes Anti-Muster in Testumgebungen: Produktivdaten in schwächer gesicherte Staging-/Test-Umgebungen kopiert, dort länger als nötig aufbewahrt.: Restore-Testumgebung wird nach jedem Testlauf zurückgesetzt/gelöscht, Zugriffskontrolle identisch zu produktiv. + +## Ausgangslage +Setzt auf folgenden bereits fertigen Kacheln auf: BAK-06. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Die Restore-Testumgebung unterliegt derselben Zugriffskontrolle und Netzwerksegmentierung wie die Produktivumgebung +2. Wiederhergestellte Testdaten werden nach Abschluss des Testlaufs und Protokollierung des Ergebnisses gelöscht, nicht dauerhaft vorgehalten +3. Das Schutzniveau ist im Betriebsdokument zu BAK-06 explizit festgehalten + +## 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. Prüft Zugriffskontrolle/Netzwerksegmentierung der Testumgebung gegen die Produktivumgebung +2. Prüft, dass nach einem Testlauf keine wiederhergestellten Daten über die dokumentierte Frist hinaus verbleiben +3. Prüft, dass das Betriebsdokument das Schutzniveau explizit benennt + +## Bekannte Fehler vermeiden + +Threat-Model-Finding (Archive-Board, 2026-09-12): eine schwächer geschützte Testumgebung mit echten wiederhergestellten Mandantendaten würde den durch Modell C und Envelope-Encryption erreichten Schutz umgehen, ohne dass dies wie ein klassischer Sicherheitsvorfall aussieht. + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `BAK-06` Restore-Testverfahren + +## 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: `BAK-10: schutzniveau-der-restore-testumgebung-dsgvo-konform` +- Branch: `feature/bak-10-schutzniveau-der-restore-testumgebung-dsgvo-konform` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/CMP-01.md b/archive-kanban/tickets/CMP-01.md new file mode 100644 index 00000000..838de1c2 --- /dev/null +++ b/archive-kanban/tickets/CMP-01.md @@ -0,0 +1,62 @@ +# CMP-01 – GoBD-Verfahrensdokumentation + +**Epic:** ⚖️ Compliance & eDiscovery | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 2 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Exportierbare Verfahrensdokumentation gemäß GoBD: Beschreibung der Aufbewahrungs-, Zugriffs- und Löschverfahren, automatisch aus der aktuellen Konfiguration erzeugt. + +**Technische Grundlage:** PDF-Export, versionierte Dokumentvorlage + +## Produkt-DNA für diesen Bereich +> Nachweisführung wie ecoDMS, Vier-Augen-Prinzip wie Alfresco, aber schlank umgesetzt. + +**Übernehmen:** +- Alfresco: Vier-Augen-Prinzip bei Freigaben – Löschung nur mit zweiter, unabhängiger Bestätigung. +- ecoDMS: Nachvollziehbare Vernichtung mit lückenlosem Protokoll. +- GoBD-konforme Verfahrensdokumentation als exportierbares Dokument, nicht als Prosa-Anhang. + +**Bewusst vermeiden:** +- Alfresco – Freigabeprozesse mit hoher Konfigurationslast: feste, einfache Vier-Augen-Regel statt konfigurierbarer Workflow-Engine. +- Keine Berichte, die nur manuell zusammengestellt werden können – jeder Bericht ist ein Exportknopf. + +**Für genau diese Kachel:** GoBD verlangt eine nachvollziehbare Verfahrensdokumentation – die hier automatisch statt manuell aktuell gehalten wird. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `RET-01` Generisches Retention-Objektmodell – Generisches Datenmodell für aufbewahrungspflichtige Objekte anlegen: Objekttyp, Objekt-Referenz (modulübergreifend über Adapter), Aufbewahrungsklasse, Status. Migrationen versioniert und rückrollbar. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Dokumentation wird automatisiert aus der aktuellen Retention-Konfiguration erzeugt, nicht manuell gepflegt +2. Export liegt als versioniertes PDF mit Erzeugungsdatum vor +3. Änderung an Aufbewahrungsklassen spiegelt sich in der nächsten Erzeugung wider + +## 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. Erzeugtes Dokument enthält alle aktiven Aufbewahrungsklassen mit Fristen +2. Zwei aufeinanderfolgende Exporte ohne Konfigurationsänderung sind inhaltlich identisch +3. Export einer zweiten Person als GoBD-tauglich nachvollzogen + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `CMP-05` Compliance-Berichts-Oberfläche + +## 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: `CMP-01: gobd-verfahrensdokumentation` +- Branch: `feature/cmp-01-gobd-verfahrensdokumentation` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/CMP-02.md b/archive-kanban/tickets/CMP-02.md new file mode 100644 index 00000000..1ad2397c --- /dev/null +++ b/archive-kanban/tickets/CMP-02.md @@ -0,0 +1,62 @@ +# CMP-02 – DSGVO-/Datenschutz-Berichte + +**Epic:** ⚖️ Compliance & eDiscovery | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 2 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Berichte für Auskunftsersuchen, Verarbeitungsübersichten und Zugriffsnachweise je betroffener Person und Tenant. + +**Technische Grundlage:** PDF/CSV-Export + +## Produkt-DNA für diesen Bereich +> Nachweisführung wie ecoDMS, Vier-Augen-Prinzip wie Alfresco, aber schlank umgesetzt. + +**Übernehmen:** +- Alfresco: Vier-Augen-Prinzip bei Freigaben – Löschung nur mit zweiter, unabhängiger Bestätigung. +- ecoDMS: Nachvollziehbare Vernichtung mit lückenlosem Protokoll. +- GoBD-konforme Verfahrensdokumentation als exportierbares Dokument, nicht als Prosa-Anhang. + +**Bewusst vermeiden:** +- Alfresco – Freigabeprozesse mit hoher Konfigurationslast: feste, einfache Vier-Augen-Regel statt konfigurierbarer Workflow-Engine. +- Keine Berichte, die nur manuell zusammengestellt werden können – jeder Bericht ist ein Exportknopf. + +**Für genau diese Kachel:** Auskunftsersuchen unter Fristdruck sind der Härtetest – ohne fertigen Bericht wird jede Anfrage zur manuellen Notoperation. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `RET-01` Generisches Retention-Objektmodell – Generisches Datenmodell für aufbewahrungspflichtige Objekte anlegen: Objekttyp, Objekt-Referenz (modulübergreifend über Adapter), Aufbewahrungsklasse, Status. Migrationen versioniert und rückrollbar. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Auskunftsbericht listet alle gespeicherten Objekte einer betroffenen Person mit Aufbewahrungsklasse +2. Verarbeitungsübersicht zeigt Zweck und Rechtsgrundlage je Objekttyp +3. Export ist mandantenscharf und enthält keine Daten anderer Tenants + +## 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. Auskunftsbericht für Testperson mit bekanntem Datenbestand stimmt mit erwarteter Liste überein +2. Bericht für einen Tenant enthält keine Objekte eines anderen Tenants +3. Export lässt sich als CSV weiterverarbeiten + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `CMP-05` Compliance-Berichts-Oberfläche + +## 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: `CMP-02: dsgvo-datenschutz-berichte` +- Branch: `feature/cmp-02-dsgvo-datenschutz-berichte` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/CMP-03.md b/archive-kanban/tickets/CMP-03.md new file mode 100644 index 00000000..fd2b1fdf --- /dev/null +++ b/archive-kanban/tickets/CMP-03.md @@ -0,0 +1,62 @@ +# CMP-03 – eDiscovery-Suche & Export (modulübergreifend) + +**Epic:** ⚖️ Compliance & eDiscovery | **Rolle:** Backend | **Komplexität:** Komplex | **Aufwand:** 4 Personentage | **Welle:** 3 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Suche über registrierte Objekttypen aus DMS und Mail hinweg für Rechtsverfahren, mit vollständigem, prüfsummengesichertem Export der Treffer. + +**Technische Grundlage:** Modulübergreifende Such-API, ZIP-Export mit Prüfsummen + +## Produkt-DNA für diesen Bereich +> Nachweisführung wie ecoDMS, Vier-Augen-Prinzip wie Alfresco, aber schlank umgesetzt. + +**Übernehmen:** +- Alfresco: Vier-Augen-Prinzip bei Freigaben – Löschung nur mit zweiter, unabhängiger Bestätigung. +- ecoDMS: Nachvollziehbare Vernichtung mit lückenlosem Protokoll. +- GoBD-konforme Verfahrensdokumentation als exportierbares Dokument, nicht als Prosa-Anhang. + +**Bewusst vermeiden:** +- Alfresco – Freigabeprozesse mit hoher Konfigurationslast: feste, einfache Vier-Augen-Regel statt konfigurierbarer Workflow-Engine. +- Keine Berichte, die nur manuell zusammengestellt werden können – jeder Bericht ist ein Exportknopf. + +**Für genau diese Kachel:** eDiscovery ist der Beweis, dass die Modul-Adapter-Schnittstelle trägt: eine Suche, viele Module, ein rechtssicherer Export. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `RET-05` Modul-Adapter-Schnittstelle (DMS/Mail registrieren Objekttypen) – Schnittstelle, über die DMS und Mail ihre Objekttypen (Dokument, Mail, Anhang) und die zugehörige Aufbewahrungsklasse bei Archive registrieren, statt eigene Retention-Logik zu bauen. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Suche liefert Treffer aus mehreren registrierten Modulen in einer gemeinsamen Ergebnisliste +2. Export enthält Originalobjekte, Metadaten und eine Prüfsummenliste je Datei +3. Suchlauf und Export werden als eigener Vorgang protokolliert (wer, wann, welche Kriterien) + +## 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. Testsuche über zwei fiktive Module liefert erwartete kombinierte Trefferzahl +2. Prüfsumme jeder exportierten Datei stimmt nach Entpacken überein +3. Protokolleintrag zum Suchlauf ist nachträglich nicht veränderbar + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `QA-03` Prüfgate Compliance & eDiscovery + +## 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: `CMP-03: ediscovery-suche-und-export-modulübergreifend` +- Branch: `feature/cmp-03-ediscovery-suche-und-export-modulübergreifend` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/CMP-04.md b/archive-kanban/tickets/CMP-04.md new file mode 100644 index 00000000..3279b894 --- /dev/null +++ b/archive-kanban/tickets/CMP-04.md @@ -0,0 +1,62 @@ +# CMP-04 – Audit-Trail-Kopplung an Core-Audit-Log + +**Epic:** ⚖️ Compliance & eDiscovery | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 2 Personentage | **Welle:** 1 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Alle sicherheitsrelevanten Vorgänge in Archive (Fristsetzung, Sperre, Löschung, Export) werden an das zentrale Audit-Log in NEXARCH Core gemeldet, statt ein eigenes Protokoll zu führen. + +**Technische Grundlage:** REST-Anbindung an NEXARCH Core Audit-Log + +## Produkt-DNA für diesen Bereich +> Nachweisführung wie ecoDMS, Vier-Augen-Prinzip wie Alfresco, aber schlank umgesetzt. + +**Übernehmen:** +- Alfresco: Vier-Augen-Prinzip bei Freigaben – Löschung nur mit zweiter, unabhängiger Bestätigung. +- ecoDMS: Nachvollziehbare Vernichtung mit lückenlosem Protokoll. +- GoBD-konforme Verfahrensdokumentation als exportierbares Dokument, nicht als Prosa-Anhang. + +**Bewusst vermeiden:** +- Alfresco – Freigabeprozesse mit hoher Konfigurationslast: feste, einfache Vier-Augen-Regel statt konfigurierbarer Workflow-Engine. +- Keine Berichte, die nur manuell zusammengestellt werden können – jeder Bericht ist ein Exportknopf. + +**Für genau diese Kachel:** Ein zentrales Audit-Log statt eines eigenen – Archive dupliziert keine Protokoll-Infrastruktur, die es in Core bereits gibt. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- Core `AUD-01` Zentrales Audit-Log-Modell – Zentrales Audit-Log-Datenmodell für sicherheits- und compliancerelevante Ereignisse (wer, was, wann, an welchem Tenant) als eigenständiges Modell getrennt vom Anwendungs-Log. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Jeder sicherheitsrelevante Vorgang erzeugt einen Eintrag im zentralen Audit-Log +2. Eintrag enthält Tenant, handelnde Person, Vorgang und Zeitstempel +3. Ausfall des Audit-Log-Dienstes blockiert nicht den Fachvorgang, wird aber sichtbar nachgemeldet + +## 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. Testvorgänge (Sperre setzen, Löschung, Export) erzeugen je einen nachvollziehbaren Audit-Eintrag +2. Simulierter Ausfall des Audit-Dienstes verhindert nicht die Fachfunktion +3. Nachmeldung nach Ausfallende ist vollständig, keine Lücke im Protokoll + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- Alles, was nicht in den Akzeptanzkriterien steht. Keine vorauseilende Umsetzung späterer Anforderungen. + +## 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: `CMP-04: audit-trail-kopplung-an-core-audit-log` +- Branch: `feature/cmp-04-audit-trail-kopplung-an-core-audit-log` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/CMP-05.md b/archive-kanban/tickets/CMP-05.md new file mode 100644 index 00000000..a3169860 --- /dev/null +++ b/archive-kanban/tickets/CMP-05.md @@ -0,0 +1,63 @@ +# CMP-05 – Compliance-Berichts-Oberfläche + +**Epic:** ⚖️ Compliance & eDiscovery | **Rolle:** Frontend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 3 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Frontend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Oberfläche und Bedienbarkeit. Ruft ausschließlich vorhandene Schnittstellen auf, keine eigene Geschäftslogik. + +## Auftrag +Oberfläche zum Anfordern, Einsehen und Herunterladen von GoBD-Verfahrensdokumentation und DSGVO-Berichten je Tenant. + +**Technische Grundlage:** Next.js/React/TypeScript + +## Produkt-DNA für diesen Bereich +> Nachweisführung wie ecoDMS, Vier-Augen-Prinzip wie Alfresco, aber schlank umgesetzt. + +**Übernehmen:** +- Alfresco: Vier-Augen-Prinzip bei Freigaben – Löschung nur mit zweiter, unabhängiger Bestätigung. +- ecoDMS: Nachvollziehbare Vernichtung mit lückenlosem Protokoll. +- GoBD-konforme Verfahrensdokumentation als exportierbares Dokument, nicht als Prosa-Anhang. + +**Bewusst vermeiden:** +- Alfresco – Freigabeprozesse mit hoher Konfigurationslast: feste, einfache Vier-Augen-Regel statt konfigurierbarer Workflow-Engine. +- Keine Berichte, die nur manuell zusammengestellt werden können – jeder Bericht ist ein Exportknopf. + +**Für genau diese Kachel:** Ohne Oberfläche bleiben GoBD- und DSGVO-Berichte Kommandozeilen-Werkzeug für Entwickler statt Alltagswerkzeug für Prüfer. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `CMP-01` GoBD-Verfahrensdokumentation – Exportierbare Verfahrensdokumentation gemäß GoBD: Beschreibung der Aufbewahrungs-, Zugriffs- und Löschverfahren, automatisch aus der aktuellen Konfiguration erzeugt. +- `CMP-02` DSGVO-/Datenschutz-Berichte – Berichte für Auskunftsersuchen, Verarbeitungsübersichten und Zugriffsnachweise je betroffener Person und Tenant. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Berichte lassen sich mit wenigen Klicks anfordern und herunterladen +2. Nur berechtigte Rollen sehen Berichte anderer Personen ein +3. Historie angeforderter Berichte ist je Tenant einsehbar + +## 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. Anforderung eines Berichts löst den zugehörigen Backend-Export korrekt aus +2. Nicht berechtigte Rolle erhält keinen Zugriff auf fremde Berichte +3. Downloadlink eines abgelaufenen Berichts wird abgewiesen + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- Alles, was nicht in den Akzeptanzkriterien steht. Keine vorauseilende Umsetzung späterer Anforderungen. + +## 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: `CMP-05: compliance-berichts-oberfläche` +- Branch: `feature/cmp-05-compliance-berichts-oberfläche` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/CMP-06.md b/archive-kanban/tickets/CMP-06.md new file mode 100644 index 00000000..8ff6f09e --- /dev/null +++ b/archive-kanban/tickets/CMP-06.md @@ -0,0 +1,66 @@ +# CMP-06 – Vier-Augen-Freigabe für Löschungen + +**Epic:** ⚖️ Compliance & eDiscovery | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 4 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Löschung abgelaufener Objekte erfordert eine zweite, unabhängige Bestätigung durch eine andere Person, bevor der Löschworkflow ausgeführt wird. + +**Technische Grundlage:** PostgreSQL mit FOR UPDATE-Lock, Timing-safe Vergleich + +## Produkt-DNA für diesen Bereich +> Nachweisführung wie ecoDMS, Vier-Augen-Prinzip wie Alfresco, aber schlank umgesetzt. + +**Übernehmen:** +- Alfresco: Vier-Augen-Prinzip bei Freigaben – Löschung nur mit zweiter, unabhängiger Bestätigung. +- ecoDMS: Nachvollziehbare Vernichtung mit lückenlosem Protokoll. +- GoBD-konforme Verfahrensdokumentation als exportierbares Dokument, nicht als Prosa-Anhang. + +**Bewusst vermeiden:** +- Alfresco – Freigabeprozesse mit hoher Konfigurationslast: feste, einfache Vier-Augen-Regel statt konfigurierbarer Workflow-Engine. +- Keine Berichte, die nur manuell zusammengestellt werden können – jeder Bericht ist ein Exportknopf. + +**Für genau diese Kachel:** Vorbild: das Vier-Augen-Muster mit FOR UPDATE-Lock und zeitkonstantem Vergleich aus archivdms hat sich bewährt und wird hier als Standardlösung übernommen, statt es erneut zu erfinden. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `RET-03` Löschworkflow & Aufbewahrungssperre (Legal Hold) – Löschworkflow für abgelaufene Objekte: Freigabe, Vernichtung, Protokolleintrag. Aufbewahrungssperre (Legal Hold) verhindert jede Löschung unabhängig vom Fristablauf. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Löschung wird erst nach zweiter Bestätigung durch eine von der anfordernden Person verschiedene Rolle ausgeführt +2. Gleichzeitige Bestätigungsversuche führen nicht zu doppelter Ausführung +3. Löschbestätigung wird mit einem geheimen, zeitlich begrenzten Bestätigungs-Token abgesichert + +## 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. Zwei parallele Bestätigungsanfragen auf dasselbe Objekt: genau eine Löschung wird ausgeführt (Lock-Test) +2. Bestätigung durch dieselbe Person wie die Anforderung wird abgewiesen +3. Vergleich des Bestätigungs-Tokens erfolgt zeitkonstant und ist gegen Timing-Angriffe getestet + +## Vorbild aus bestehendem System + +Ein bereits produktives Schwestersystem hat das Vier-Augen-Prinzip bei Löschbestätigung mit einem `FOR UPDATE`-Lock auf dem betroffenen Datensatz und einem zeitkonstanten (timing-safe) Vergleich des Bestätigungs-Tokens umgesetzt. Beides hat sich bewährt und wird hier als Vorbild übernommen: der Lock verhindert doppelte gleichzeitige Ausführung, der zeitkonstante Vergleich verhindert das Erraten des Tokens über Zeitmessung. + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `QA-03` Prüfgate Compliance & eDiscovery + +## 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: `CMP-06: vier-augen-freigabe-für-löschungen` +- Branch: `feature/cmp-06-vier-augen-freigabe-für-löschungen` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/CMP-07.md b/archive-kanban/tickets/CMP-07.md new file mode 100644 index 00000000..e6353a09 --- /dev/null +++ b/archive-kanban/tickets/CMP-07.md @@ -0,0 +1,70 @@ +# CMP-07 – DSGVO-Löschantrag (Recht auf Löschung, Art. 17) + +**Epic:** ⚖️ Compliance & eDiscovery | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 4 Personentage | **Welle:** 4 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Workflow für den Löschantrag einer betroffenen Person (Art. 17 DSGVO): modulübergreifende Suche nach allen zu dieser Person gespeicherten Objekten (wiederverwendet die Auskunfts-Suche aus `CMP-02`), Löschung jedes Objekts OHNE aktive Aufbewahrungspflicht (`RET-03` hat Vorrang), nachvollziehbare Ablehnung mit Begründung für jedes Objekt MIT Aufbewahrungspflicht, vollständiges Protokoll der Entscheidung je Objekt. Tatsächliche Vernichtung läuft über denselben Vier-Augen-Freigabeprozess wie jede andere Löschung (`CMP-06`), keine zweite Lösch-Implementierung. + +**Technische Grundlage:** PostgreSQL, transaktionaler Zustandswechsel, Wiederverwendung der Modul-Adapter-Schnittstelle (`RET-05`) + +## Produkt-DNA für diesen Bereich +> Nachweisführung wie ecoDMS, Vier-Augen-Prinzip wie Alfresco, aber schlank umgesetzt. + +**Übernehmen:** +- Alfresco: Vier-Augen-Prinzip bei Freigaben – Löschung nur mit zweiter, unabhängiger Bestätigung. +- ecoDMS: Nachvollziehbare Vernichtung mit lückenlosem Protokoll. +- GoBD-konforme Verfahrensdokumentation als exportierbares Dokument, nicht als Prosa-Anhang. + +**Bewusst vermeiden:** +- Ein Vorgänger-Projekt (archivmail) hat den DSGVO-Löschantrag ursprünglich als eigenständigen, von der übrigen Löschlogik getrennten Sonderpfad gebaut: ein Löschantrag ruft hier stattdessen denselben Löschworkflow (`RET-03`/`CMP-06`) auf wie jede andere Löschung – kein Duplikat der Aufbewahrungs-/Vier-Augen-Prüfung. +- Keine stille Teillöschung: ein Löschantrag mit gemischtem Ergebnis (teils gelöscht, teils wegen Aufbewahrungspflicht abgelehnt) macht das Ergebnis je Objekt einzeln nachvollziehbar, statt eine pauschale Sammelantwort zu liefern. + +**Für genau diese Kachel:** Ein Löschantrag unter Fristdruck (DSGVO kennt hierfür i.d.R. eine Monatsfrist) ist der Härtetest für das Zusammenspiel von Aufbewahrungspflicht und Löschrecht – beides muss automatisiert und nachvollziehbar entschieden werden, nicht manuell pro Fall. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `RET-03` Löschworkflow & Aufbewahrungssperre (Legal Hold) – Aufbewahrungssperre verhindert jede Löschung unabhängig vom Fristablauf. +- `RET-05` Modul-Adapter-Schnittstelle (DMS/Mail registrieren Objekttypen) – Rückruf-Mechanismus, über den Archive ein Modul beim Vernichten eines Objekts anspricht. +- `CMP-02` DSGVO-/Datenschutz-Berichte – modulübergreifende Suche nach allen Objekten einer betroffenen Person. +- `CMP-06` Vier-Augen-Freigabe für Löschungen – zweite, unabhängige Bestätigung vor tatsächlicher Vernichtung. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Löschantrag findet über die Suche aus `CMP-02` alle Objekte einer betroffenen Person, mandantenscharf +2. Jedes gefundene Objekt wird EINZELN entschieden: Löschung (keine Aufbewahrungspflicht) oder Ablehnung mit Begründung (aktive Aufbewahrungspflicht/Legal Hold aus `RET-03`) – niemals eine pauschale Sammelentscheidung +3. Tatsächliche Löschung durchläuft denselben Vier-Augen-Freigabeprozess wie jede andere Löschung (`CMP-06`), keine zweite Implementierung +4. Ergebnis des Löschantrags (je Objekt: gelöscht/abgelehnt+Grund) ist vollständig und dauerhaft protokolliert + +## 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. Löschantrag für eine Testperson mit gemischtem Datenbestand (ein Objekt ohne, ein Objekt mit aktiver Aufbewahrungspflicht) liefert exakt eine Löschung und eine begründete Ablehnung +2. Aufbewahrungssperre (Legal Hold) verhindert die Löschung nachweislich auch dann, wenn die reguläre Aufbewahrungsfrist bereits abgelaufen wäre +3. Löschantrag für einen Tenant führt nachweislich zu keiner Aktion an Objekten eines anderen Tenants + +## Bekannte Fehler vermeiden +archivmail (Vorgängerprojekt) implementierte den DSGVO-Löschantrag ursprünglich als eigenständigen Workflow parallel zur regulären Aufbewahrungs-/Löschlogik – zwei Stellen, die dieselbe Aufbewahrungsregel auswerten, laufen bei Änderungen an einer Stelle auseinander. Diese Kachel ruft stattdessen ausschließlich `RET-03` (Aufbewahrungsprüfung) und `CMP-06` (Freigabe) auf, statt eine zweite Prüf-/Freigabelogik zu bauen. + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- Die Suche nach Objekten einer Person selbst (`CMP-02`) +- Die eigentliche Aufbewahrungsprüfung (`RET-03`) und Freigabe (`CMP-06`) + +## 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: `CMP-07: dsgvo-loeschantrag-recht-auf-loeschung` +- Branch: `feature/cmp-07-dsgvo-loeschantrag-recht-auf-loeschung` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/CMP-08.md b/archive-kanban/tickets/CMP-08.md new file mode 100644 index 00000000..00777825 --- /dev/null +++ b/archive-kanban/tickets/CMP-08.md @@ -0,0 +1,45 @@ +# CMP-08 – Ende-zu-Ende-Nachweis eDiscovery-Adapter (reale Drittmodul-Integration) + +**Epic:** ⚖️ Compliance & eDiscovery | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 9 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (Retention & WORM, Compliance & eDiscovery, Backup & Wiederherstellung, Kennzahlen), das sich an Alfresco, ecoDMS und restic/Borg orientiert. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +QA-03 (Archive-Board, Prüfgate Compliance & eDiscovery) hat den eDiscovery-Export gegen den Referenzdatensatz real geprüft, aber den eDiscovery-Adapter zu DMS/Mail (die tatsächlichen Quellmodule der durchsuchten Objekte) nur fiktiv getestet (siehe QA-03-PRUEFPROTOKOLL.md, offene Restrisiken). Diese Kachel schließt die Lücke: ein echter Ende-zu-Ende-Testlauf, bei dem der eDiscovery-Export tatsächlich gegen laufende DMS- und Mail-Instanzen (nicht nur gegen Referenzdatensatz-Fixtures) durchgeführt wird. + +**Technische Grundlage:** reale DMS-/Mail-Testinstanzen auf Host 204, bestehender Modul-Adapter-Mechanismus (RET-05) + +## Ausgangslage +Setzt auf folgenden bereits fertigen Kacheln auf: `CMP-03` eDiscovery-Suche & Export, `QA-03` Prüfgate Compliance & eDiscovery (Archive-Board), `RET-05` Modul-Adapter-Schnittstelle. + +## Akzeptanzkriterien +1. eDiscovery-Export wird gegen echte, über RET-05 registrierte DMS- und Mail-Testinstanzen durchgeführt (nicht nur gegen Referenzdatensatz-Fixtures) +2. Treffer aus beiden Modulen sind im Export korrekt vorhanden und prüfsummengesichert +3. Ergebnis ist als Nachtrag zu QA-03-PRUEFPROTOKOLL.md dokumentiert + +## Prüfungen vor der Abnahme +1. Echter Testlauf gegen laufende DMS- und Mail-Instanz durchgeführt, Ergebnis dokumentiert +2. Export-Prüfsummen bei wiederholtem Testlauf identisch +3. Offene Restrisiken (falls neue gefunden) schriftlich benannt + +## Nicht Bestandteil dieser Kachel +- Neue eDiscovery-Funktionalität (nur End-zu-Ende-Nachweis des bestehenden Adapters) +- RBAC-Rollenberechtigung der Vier-Augen-Freigabe (separates, bereits in QA-03 benanntes offenes Risiko) + +## Arbeitsweise +1. Lies zuerst CMP-03, QA-03-PRUEFPROTOKOLL.md und RET-05 vollständig. +2. Setze die kleinste Lösung um, die alle Akzeptanzkriterien erfüllt. +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: `CMP-08: ende-zu-ende-nachweis-ediscovery-adapter-reale-drittmodul-integration` +- Branch: `feature/cmp-08-ende-zu-ende-nachweis-ediscovery-adapter-reale-drittmodul-integration` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/QA-01.md b/archive-kanban/tickets/QA-01.md new file mode 100644 index 00000000..a172d406 --- /dev/null +++ b/archive-kanban/tickets/QA-01.md @@ -0,0 +1,61 @@ +# QA-01 – Teststrategie Archive + +**Epic:** ✅ Prüfungen & Qualitätssicherung | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 2 Personentage | **Welle:** 1 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Teststrategie für das Archive-Board festlegen: Testebenen, Referenzdatensatz für Retention/WORM/Backup, Verantwortlichkeiten je Prüfgate. + +**Technische Grundlage:** Testplan-Dokument, Testdatensatz-Konzept + +## Produkt-DNA für diesen Bereich +> Prüfen heißt messen. Behauptungen ohne Messprotokoll gelten nicht als erledigt. + +**Übernehmen:** +- Fester Prüfplan je Ausbaustufe mit abgelegtem, nachlesbarem Protokoll. +- Nachgewiesene Wiederherstellbarkeit als Freigabevoraussetzung. + +**Bewusst vermeiden:** +- Keine Freigabe auf Zuruf. +- Keine Prüfung nur auf dem Entwicklungsrechner mit synthetischen Testdaten. + +**Für genau diese Kachel:** Ohne gemeinsame Teststrategie prüft jedes Prüfgate nach eigenem Gutdünken – das Fundament für vergleichbare Prüfergebnisse. + +## Ausgangslage +Diese Kachel hat keine Vorbedingungen und ist sofort startbar. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Teststrategie benennt Testebenen (Unit, Integration, Wiederherstellungstest) und deren Verantwortliche +2. Referenzdatensatz für Retention- und Backup-Tests ist definiert und wiederverwendbar +3. Strategie ist als Dokument abgelegt und von zweiter Person gegengelesen + +4. 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 +## 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. Referenzdatensatz lässt sich reproduzierbar in einer Testumgebung aufsetzen +2. Zweite Person bestätigt schriftlich die Nachvollziehbarkeit der Strategie +3. Strategie deckt erkennbar alle folgenden Prüfgates ab (Abgleich mit QA-02 bis QA-06) + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- Alles, was nicht in den Akzeptanzkriterien steht. Keine vorauseilende Umsetzung späterer Anforderungen. + +## 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: `QA-01: teststrategie-archive` +- Branch: `feature/qa-01-teststrategie-archive` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/QA-02.md b/archive-kanban/tickets/QA-02.md new file mode 100644 index 00000000..8cb6997e --- /dev/null +++ b/archive-kanban/tickets/QA-02.md @@ -0,0 +1,64 @@ +# QA-02 – Prüfgate Retention & WORM + +**Epic:** ✅ Prüfungen & Qualitätssicherung | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 2 Personentage | **Welle:** 4 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Prüfgate für Fristenengine, Löschworkflow, Aufbewahrungssperre und WORM-Garantie vor Freigabe der Retention-Funktionen. + +**Technische Grundlage:** Abnahmeprotokoll + +## Produkt-DNA für diesen Bereich +> Prüfen heißt messen. Behauptungen ohne Messprotokoll gelten nicht als erledigt. + +**Übernehmen:** +- Fester Prüfplan je Ausbaustufe mit abgelegtem, nachlesbarem Protokoll. +- Nachgewiesene Wiederherstellbarkeit als Freigabevoraussetzung. + +**Bewusst vermeiden:** +- Keine Freigabe auf Zuruf. +- Keine Prüfung nur auf dem Entwicklungsrechner mit synthetischen Testdaten. + +**Für genau diese Kachel:** Ein eigenes Gate für Retention und WORM, weil hier die Kernversprechen des gesamten Boards stehen und Wiederholungen unter Prüfbedingungen zählen. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `RET-04` WORM-Speicher-Garantie (Append-only) – Speicherpfad für archivierte Objektinhalte, der nach dem Schreiben keine Änderung und kein Überschreiben mehr zulässt (Write Once, Read Many). +- `RET-03` Löschworkflow & Aufbewahrungssperre (Legal Hold) – Löschworkflow für abgelaufene Objekte: Freigabe, Vernichtung, Protokolleintrag. Aufbewahrungssperre (Legal Hold) verhindert jede Löschung unabhängig vom Fristablauf. +- `RET-06` Aufbewahrungsfristen-Konfigurationsoberfläche – Oberfläche zur Pflege von Aufbewahrungsklassen und Fristen je Objekttyp und Tenant, inklusive Vorschauliste bald ablaufender Objekte. +- `RET-07` Fristablauf-Benachrichtigungen – Benachrichtigung verantwortlicher Personen vor Ablauf einer Aufbewahrungsfrist, konfigurierbarer Vorlauf je Aufbewahrungsklasse. Der eigentliche Versand läuft ausschließlich über den zentralen Core-Benachrichtigungs-Dispatcher (CFG-02) – Archive erzeugt nur das Ereignis, versendet keine E-Mail selbst. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Alle Akzeptanzkriterien von RET-03 und RET-04 sind gegen den Referenzdatensatz nachgewiesen +2. Versuch, eine gesperrte oder WORM-geschützte Ablage zu umgehen, scheitert nachweislich +3. Protokoll mit Zielwert, Messwert und Bewertung ist abgelegt + +## 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. Löschversuch an gesperrtem Objekt schlägt fehl (Wiederholung des RET-03-Tests unter Prüfgate-Bedingungen) +2. Überschreibversuch am WORM-Speicher schlägt fehl (Wiederholung des RET-04-Tests unter Prüfgate-Bedingungen) +3. Offene Restrisiken sind schriftlich benannt + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `QA-05` Abnahme- & Compliance-Prüfung Archive + +## 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: `QA-02: prüfgate-retention-und-worm` +- Branch: `feature/qa-02-prüfgate-retention-und-worm` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/QA-03.md b/archive-kanban/tickets/QA-03.md new file mode 100644 index 00000000..9d1ce9d5 --- /dev/null +++ b/archive-kanban/tickets/QA-03.md @@ -0,0 +1,66 @@ +# QA-03 – Prüfgate Compliance & eDiscovery + +**Epic:** ✅ Prüfungen & Qualitätssicherung | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 2 Personentage | **Welle:** 5 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Prüfgate für eDiscovery-Export und Vier-Augen-Freigabe vor Freigabe der Compliance-Funktionen. + +**Technische Grundlage:** Abnahmeprotokoll + +## Produkt-DNA für diesen Bereich +> Prüfen heißt messen. Behauptungen ohne Messprotokoll gelten nicht als erledigt. + +**Übernehmen:** +- Fester Prüfplan je Ausbaustufe mit abgelegtem, nachlesbarem Protokoll. +- Nachgewiesene Wiederherstellbarkeit als Freigabevoraussetzung. + +**Bewusst vermeiden:** +- Keine Freigabe auf Zuruf. +- Keine Prüfung nur auf dem Entwicklungsrechner mit synthetischen Testdaten. + +**Für genau diese Kachel:** Compliance-Funktionen entscheiden im Ernstfall vor Gericht oder Aufsichtsbehörde – ein eigenes Gate stellt das vor Freigabe sicher. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `CMP-03` eDiscovery-Suche & Export (modulübergreifend) – Suche über registrierte Objekttypen aus DMS und Mail hinweg für Rechtsverfahren, mit vollständigem, prüfsummengesichertem Export der Treffer. +- `CMP-06` Vier-Augen-Freigabe für Löschungen – Löschung abgelaufener Objekte erfordert eine zweite, unabhängige Bestätigung durch eine andere Person, bevor der Löschworkflow ausgeführt wird. +- `CMP-07` DSGVO-Löschantrag (Recht auf Löschung, Art. 17) – Workflow für den Löschantrag einer betroffenen Person (Art. 17 DSGVO): modulübergreifende Suche (CMP-02), Löschung ohne Aufbewahrungspflicht, begründete Ablehnung mit Aufbewahrungspflicht, Freigabe über CMP-06, vollständiges Protokoll je Objekt. +- `CMP-01` GoBD-Verfahrensdokumentation – Exportierbare Verfahrensdokumentation gemäß GoBD: Beschreibung der Aufbewahrungs-, Zugriffs- und Löschverfahren, automatisch aus der aktuellen Konfiguration erzeugt. +- `CMP-04` Audit-Trail-Kopplung an Core-Audit-Log – Alle sicherheitsrelevanten Vorgänge in Archive (Fristsetzung, Sperre, Löschung, Export) werden an das zentrale Audit-Log in NEXARCH Core gemeldet, statt ein eigenes Protokoll zu führen. +- `CMP-05` Compliance-Berichts-Oberfläche – Oberfläche zum Anfordern, Einsehen und Herunterladen von GoBD-Verfahrensdokumentation und DSGVO-Berichten je Tenant. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. eDiscovery-Export wird gegen den Referenzdatensatz erneut durchgeführt und geprüft +2. Vier-Augen-Freigabe wird mit zwei unabhängigen Testrollen erneut nachgewiesen +3. Protokoll mit Zielwert, Messwert und Bewertung ist abgelegt + +## 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. Export-Prüfsummen stimmen bei wiederholtem Testlauf erneut überein +2. Löschversuch durch dieselbe Person ohne zweite Bestätigung scheitert erneut +3. Offene Restrisiken sind schriftlich benannt + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `QA-05` Abnahme- & Compliance-Prüfung Archive + +## 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: `QA-03: prüfgate-compliance-und-ediscovery` +- Branch: `feature/qa-03-prüfgate-compliance-und-ediscovery` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/QA-04.md b/archive-kanban/tickets/QA-04.md new file mode 100644 index 00000000..a02b3f7b --- /dev/null +++ b/archive-kanban/tickets/QA-04.md @@ -0,0 +1,64 @@ +# QA-04 – Prüfgate Backup & Restore + +**Epic:** ✅ Prüfungen & Qualitätssicherung | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 2 Personentage | **Welle:** 4 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Prüfgate für Backup-Strategie und Restore-Verfahren vor Freigabe der Backup-Funktionen, inklusive einem real durchgeführten Wiederherstellungstest. + +**Technische Grundlage:** Abnahmeprotokoll, realer Wiederherstellungstest + +## Produkt-DNA für diesen Bereich +> Prüfen heißt messen. Behauptungen ohne Messprotokoll gelten nicht als erledigt. + +**Übernehmen:** +- Fester Prüfplan je Ausbaustufe mit abgelegtem, nachlesbarem Protokoll. +- Nachgewiesene Wiederherstellbarkeit als Freigabevoraussetzung. + +**Bewusst vermeiden:** +- Keine Freigabe auf Zuruf. +- Keine Prüfung nur auf dem Entwicklungsrechner mit synthetischen Testdaten. + +**Für genau diese Kachel:** Backup ohne real durchgeführten Restore-Test ist eine unbelegte Behauptung – dieses Gate erzwingt den Beleg. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `BAK-06` Restore-Testverfahren – Regelmäßiger, automatisierter Testlauf des Restore-Verfahrens gegen eine isolierte Testumgebung, mit Ergebnisprotokoll als Nachweis der Wiederherstellbarkeit. +- `BAK-04` Tenant-Backup & -Restore (einzelner Mandant) – Sicherung und Wiederherstellung der Daten eines einzelnen Mandanten, ohne andere Mandanten zu berühren – etwa für Mandanten-Umzug oder isolierte Notfallwiederherstellung. +- `BAK-05` Reconciliation (Konsistenzprüfung Storage vs. DB) – Periodische Prüfung, ob jeder in der Datenbank referenzierte Objekt-Storage-Eintrag tatsächlich existiert und umgekehrt, mit Bericht über Abweichungen. +- `BAK-07` Aufbewahrungsfrist für Backup-Snapshots – Eigene, von der Dokumenten-Retention (RET-02) unabhängige Aufbewahrungsfrist für Backup-Snapshots selbst – nach restic/Borg-Vorbild eine Prune-Policy (z. B. tägliche Snapshots 14 Tage, wöchentliche 3 Monate, monatliche 1 Jahr – konkrete Staffelung als Konfiguration, nicht hart codiert), damit Backups nicht unbegrenzt wachsen, aber auch nicht zu früh gelöscht werden. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Restore wird real auf ein leeres Testsystem durchgeführt und dokumentiert +2. Reconciliation nach Restore zeigt keine Abweichungen zwischen Storage und Datenbank +3. Protokoll mit Zielwert, Messwert und Bewertung ist abgelegt + +## 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. Realer Restore-Testlauf erfolgreich und protokolliert +2. Reconciliation nach dem Testlauf liefert einen sauberen Bericht +3. Offene Restrisiken sind schriftlich benannt + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `QA-05` Abnahme- & Compliance-Prüfung Archive + +## 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: `QA-04: prüfgate-backup-und-restore` +- Branch: `feature/qa-04-prüfgate-backup-und-restore` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/QA-05.md b/archive-kanban/tickets/QA-05.md new file mode 100644 index 00000000..4e66ddc9 --- /dev/null +++ b/archive-kanban/tickets/QA-05.md @@ -0,0 +1,68 @@ +# QA-05 – Abnahme- & Compliance-Prüfung Archive + +**Epic:** ✅ Prüfungen & Qualitätssicherung | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 2 Personentage | **Welle:** 6 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Gesamtabnahme des Archive-Boards vor Freigabe: Retention/WORM, Compliance/eDiscovery und Backup/Restore müssen alle bestanden sein. + +**Technische Grundlage:** Abnahmeprotokoll + +## Produkt-DNA für diesen Bereich +> Prüfen heißt messen. Behauptungen ohne Messprotokoll gelten nicht als erledigt. + +**Übernehmen:** +- Fester Prüfplan je Ausbaustufe mit abgelegtem, nachlesbarem Protokoll. +- Nachgewiesene Wiederherstellbarkeit als Freigabevoraussetzung. + +**Bewusst vermeiden:** +- Keine Freigabe auf Zuruf. +- Keine Prüfung nur auf dem Entwicklungsrechner mit synthetischen Testdaten. + +**Für genau diese Kachel:** Erst wenn Retention, Compliance und Backup einzeln bestanden sind, ist Archive insgesamt freigabefähig – diese Kachel bündelt den Nachweis. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `QA-02` Prüfgate Retention & WORM – Prüfgate für Fristenengine, Löschworkflow, Aufbewahrungssperre und WORM-Garantie vor Freigabe der Retention-Funktionen. +- `QA-03` Prüfgate Compliance & eDiscovery – Prüfgate für eDiscovery-Export und Vier-Augen-Freigabe vor Freigabe der Compliance-Funktionen. +- `QA-04` Prüfgate Backup & Restore – Prüfgate für Backup-Strategie und Restore-Verfahren vor Freigabe der Backup-Funktionen, inklusive einem real durchgeführten Wiederherstellungstest. +- `QA-06` Schnittstellen-Vertragstests – Vertragstests für die Modul-Adapter-Schnittstelle (RET-05), über die DMS und Mail Objekte bei der Retention-Engine registrieren – Breaking Changes müssen automatisiert erkannt werden, bevor sie ein konsumierendes Modul stillschweigend bricht. +- `QA-07` Last- & Leistungstest – Lasttest für Archive unter realistischer Last aus DMS und Mail gleichzeitig – insbesondere Retention-Prüfpfad (RET-03), Modul-Adapter-Registrierung (RET-05) und WORM-Schreibpfad unter Last. +- `ANA-01` Kennzahlen-Aggregation (modulübergreifend) – Zentraler Dienst, der Kennzahlen (Objektbestand, Aufbewahrungsstatus, Löschvorgänge, Speichervolumen) aus allen über RET-05 registrierten Modulen aggregiert. +- `ANA-02` Auswertungs-Dashboard – Dashboard zur Visualisierung der aggregierten Kennzahlen mit Filtern nach Tenant, Modul und Zeitraum. +- `ANA-03` Lizenz-/Nutzungs-Reports – Bericht über Nutzung und Lizenzrelevantes je Tenant (Speichervolumen, aktive Objekte, Nutzeranzahl-Bezug), abgestimmt mit dem Lizenzmodell aus NEXARCH Core. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Alle drei fachlichen Prüfgates (QA-02, QA-03, QA-04) sind bestanden +2. Gesamtprotokoll fasst alle drei Prüfgates mit Ergebnis zusammen +3. Abnahmeprotokoll ist unterzeichnet + +## 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. Zusammenfassung aller drei Prüfgates gegen die jeweiligen Einzelprotokolle abgeglichen +2. Offene Restrisiken aus allen drei Gates sind konsolidiert und schriftlich benannt +3. Freigabeentscheidung ist dokumentiert + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- Alles, was nicht in den Akzeptanzkriterien steht. Keine vorauseilende Umsetzung späterer Anforderungen. + +## 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: `QA-05: abnahme-und-compliance-prüfung-archive` +- Branch: `feature/qa-05-abnahme-und-compliance-prüfung-archive` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/QA-06.md b/archive-kanban/tickets/QA-06.md new file mode 100644 index 00000000..bd4b23f8 --- /dev/null +++ b/archive-kanban/tickets/QA-06.md @@ -0,0 +1,60 @@ +# QA-06 – Schnittstellen-Vertragstests + +**Epic:** ✅ Prüfungen & Qualitätssicherung | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 3 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Vertragstests für die Modul-Adapter-Schnittstelle (RET-05), über die DMS und Mail Objekte bei der Retention-Engine registrieren – Breaking Changes müssen automatisiert erkannt werden, bevor sie ein konsumierendes Modul stillschweigend bricht. + +**Technische Grundlage:** Vertragstests (Consumer-Driven Contracts), CI-Pipeline + +## Produkt-DNA für diesen Bereich +> Prüfen heißt messen. Behauptungen ohne Messprotokoll gelten nicht als erledigt. + +**Übernehmen:** +- Fester Vertragskorpus je Schnittstelle, an dem Kompatibilität wiederholbar geprüft wird. +- Nachgewiesene Erkennung von Breaking Changes als Freigabevoraussetzung, wie es verbindliche Schnittstellenverträge verlangen. + +**Bewusst vermeiden:** +- Keine Freigabe auf Zuruf. Jedes Prüfgate hinterlässt ein abgelegtes, nachlesbares Protokoll. +- Keine Prüfung nur auf dem Entwicklungsrechner mit einer Handvoll Beispielaufrufen. + +**Für genau diese Kachel:** Die Modul-Adapter-Schnittstelle ist der eigentliche Zweck des Boards – ein unbemerkter Bruch trifft DMS und Mail gleichermaßen und muss automatisiert auffallen, bevor er ausgeliefert wird. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `RET-05` Modul-Adapter-Schnittstelle (DMS/Mail registrieren Objekttypen) – Schnittstelle, über die DMS und Mail ihre Objekttypen (Dokument, Mail, Anhang) und die zugehörige Aufbewahrungsklasse bei Archive registrieren, statt eigene Retention-Logik zu bauen. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Vertragstests decken RET-05 vollständig ab +2. Absichtlich brechender Schema-Wechsel lässt Tests fehlschlagen +3. Tests laufen automatisiert in der CI + +## 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. Testlauf gegen aktuellen Stand grün +2. Simulierte Breaking Change erkannt +3. CI-Integration nachgewiesen + +## Nicht Bestandteil dieser Kachel +- Alles, was nicht in den Akzeptanzkriterien steht. Keine vorauseilende Umsetzung späterer Anforderungen. + +## 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: `QA-06: schnittstellen-vertragstests` +- Branch: `feature/qa-06-schnittstellen-vertragstests` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/QA-07.md b/archive-kanban/tickets/QA-07.md new file mode 100644 index 00000000..1944b700 --- /dev/null +++ b/archive-kanban/tickets/QA-07.md @@ -0,0 +1,60 @@ +# QA-07 – Last- & Leistungstest + +**Epic:** ✅ Prüfungen & Qualitätssicherung | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 6 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Lasttest für Archive unter realistischer Last aus DMS und Mail gleichzeitig – insbesondere Retention-Prüfpfad (RET-03), Modul-Adapter-Registrierung (RET-05) und WORM-Schreibpfad unter Last. + +**Technische Grundlage:** Lastgenerator, Messprotokoll + +## Produkt-DNA für diesen Bereich +> Prüfen heißt messen. Behauptungen ohne Messprotokoll gelten nicht als erledigt. + +**Übernehmen:** +- Nachgewiesene Prüfergebnisse als Freigabevoraussetzung, wie in allen anderen Boards. + +**Bewusst vermeiden:** +- Keine Freigabe auf Zuruf. Jedes Prüfgate hinterlässt ein abgelegtes, nachlesbares Protokoll. + +**Für genau diese Kachel:** Archive wird von zwei Modulen gleichzeitig angesprochen (DMS und Mail) – ohne Lasttest bleibt unklar, ob der Retention-Prüfpfad das verkraftet. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `RET-05` Modul-Adapter-Schnittstelle (DMS/Mail registrieren Objekttypen) – Schnittstelle, über die DMS und Mail ihre Objekttypen (Dokument, Mail, Anhang) und die zugehörige Aufbewahrungsklasse bei Archive registrieren, statt eigene Retention-Logik zu bauen. +- `RET-03` Löschworkflow & Aufbewahrungssperre (Legal Hold) – Löschworkflow für abgelaufene Objekte: Freigabe, Vernichtung, Protokolleintrag. Aufbewahrungssperre (Legal Hold) verhindert jede Löschung unabhängig vom Fristablauf. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Definierte Ziel-Latenz für die Retention-/Legal-Hold-Abfrage unter Last eingehalten +2. WORM-Schreibpfad bleibt unter simulierter Last aus zwei gleichzeitig zugreifenden Modulen (DMS und Mail) korrekt und ohne Datenverlust +3. Modul-Adapter-Registrierung (RET-05) verkraftet gleichzeitige Registrierung mehrerer Objekttypen ohne Race Condition + +## 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. Lasttest mit simulierten parallelen Anfragen aus DMS und Mail durchgeführt, Ergebnis dokumentiert +2. WORM-Schreibpfad unter Last auf Datenverlust/Race Conditions geprüft +3. Gleichzeitige Registrierung mehrerer Objekttypen bei RET-05 getestet + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- (keine direkt abhängigen Kacheln bekannt) + +## 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: `QA-07: last leistungstest` +- Branch: `feature/qa-07-last-leistungstest` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/RET-01.md b/archive-kanban/tickets/RET-01.md new file mode 100644 index 00000000..097abaf3 --- /dev/null +++ b/archive-kanban/tickets/RET-01.md @@ -0,0 +1,65 @@ +# RET-01 – Generisches Retention-Objektmodell + +**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 1 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Generisches Datenmodell für aufbewahrungspflichtige Objekte anlegen: Objekttyp, Objekt-Referenz (modulübergreifend über Adapter), Aufbewahrungsklasse, Status. Migrationen versioniert und rückrollbar. + +**Technische Grundlage:** PostgreSQL, pgx/v5, SQL-Migrationen (kein ORM) + +## Produkt-DNA für diesen Bereich +> Aufbewahrung mit dem Ernst von Alfrescos Retention Policies, aber ohne dessen Ressourcen-Overhead. + +**Übernehmen:** +- Alfresco: Retention Policies mit Stichtagsberechnung je Objekttyp und automatischem Ablauf. +- ecoDMS: Revisionssicherheit als Grundhaltung – einmal archiviert, nicht mehr veränderbar. +- Alfresco: Aufbewahrungssperre (Legal Hold), die jede Löschregel überstimmt. + +**Bewusst vermeiden:** +- Alfresco – hoher Ressourcen-Overhead der Plattform: schlanker Go-Dienst statt schwergewichtiger Anwendungsserver. +- Keine modulspezifische Retention-Logik in DMS oder Mail – ein zentraler Adapter für alle Objekttypen. + +**Für genau diese Kachel:** Das generische Objektmodell ist die Grundvoraussetzung, damit DMS und Mail keine eigene Retention-Logik bauen müssen. + +## Ausgangslage +Diese Kachel hat keine Vorbedingungen und ist sofort startbar. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Objektmodell bildet beliebige Objekttypen aus DMS und Mail ab, ohne modulspezifische Spalten +2. Aufbewahrungsklasse ist je Objekt eindeutig zugeordnet und historisierbar +3. Migration läuft gegen leere Datenbank durch und ist rückrollbar + +## 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. Migration vorwärts und rückwärts getestet +2. Testobjekt aus fiktivem DMS- und Mail-Adapter beide korrekt abgebildet +3. Tenant-Isolation der Kern-Tabellen durch Negativtest belegt + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `RET-02` Aufbewahrungsfristen-Engine +- `RET-04` WORM-Speicher-Garantie (Append-only) +- `RET-05` Modul-Adapter-Schnittstelle (DMS/Mail registrieren Objekttypen) +- `CMP-01` GoBD-Verfahrensdokumentation +- `CMP-02` DSGVO-/Datenschutz-Berichte + +## 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: `RET-01: generisches-retention-objektmodell` +- Branch: `feature/ret-01-generisches-retention-objektmodell` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/RET-02.md b/archive-kanban/tickets/RET-02.md new file mode 100644 index 00000000..71746d8a --- /dev/null +++ b/archive-kanban/tickets/RET-02.md @@ -0,0 +1,64 @@ +# RET-02 – Aufbewahrungsfristen-Engine + +**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 2 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Fristenmodell je Aufbewahrungsklasse mit Stichtagsberechnung (Beginn, Dauer, Ablaufdatum) und periodischem Job, der ablaufende Objekte ermittelt. + +**Technische Grundlage:** PostgreSQL, Postgres-Jobqueue (geplante Jobs statt Redis) + +## Produkt-DNA für diesen Bereich +> Aufbewahrung mit dem Ernst von Alfrescos Retention Policies, aber ohne dessen Ressourcen-Overhead. + +**Übernehmen:** +- Alfresco: Retention Policies mit Stichtagsberechnung je Objekttyp und automatischem Ablauf. +- ecoDMS: Revisionssicherheit als Grundhaltung – einmal archiviert, nicht mehr veränderbar. +- Alfresco: Aufbewahrungssperre (Legal Hold), die jede Löschregel überstimmt. + +**Bewusst vermeiden:** +- Alfresco – hoher Ressourcen-Overhead der Plattform: schlanker Go-Dienst statt schwergewichtiger Anwendungsserver. +- Keine modulspezifische Retention-Logik in DMS oder Mail – ein zentraler Adapter für alle Objekttypen. + +**Für genau diese Kachel:** Die Fristenberechnung ist der Kern jeder Aufbewahrungssteuerung – ohne verlässlichen Stichtag ist jede weitere Kachel wertlos. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `RET-01` Generisches Retention-Objektmodell – Generisches Datenmodell für aufbewahrungspflichtige Objekte anlegen: Objekttyp, Objekt-Referenz (modulübergreifend über Adapter), Aufbewahrungsklasse, Status. Migrationen versioniert und rückrollbar. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Frist wird je Aufbewahrungsklasse konfiguriert und auf jedes zugeordnete Objekt angewendet +2. Stichtag wird korrekt aus Beginn- und Dauerangabe berechnet, inklusive Kalenderfällen (Schaltjahr, Monatsende) +3. Periodischer Job liefert Liste ablaufender Objekte je Tenant + +## 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. Fristberechnung an Referenzdaten mit bekannten Ablaufdaten geprüft +2. Job liefert bei leerem Bestand ein leeres, nicht fehlerhaftes Ergebnis +3. Mehrfachausführung des Jobs erzeugt keine doppelten Einträge + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `RET-03` Löschworkflow & Aufbewahrungssperre (Legal Hold) +- `RET-06` Aufbewahrungsfristen-Konfigurationsoberfläche +- `RET-07` Fristablauf-Benachrichtigungen + +## 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: `RET-02: aufbewahrungsfristen-engine` +- Branch: `feature/ret-02-aufbewahrungsfristen-engine` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/RET-03.md b/archive-kanban/tickets/RET-03.md new file mode 100644 index 00000000..cd53981e --- /dev/null +++ b/archive-kanban/tickets/RET-03.md @@ -0,0 +1,63 @@ +# RET-03 – Löschworkflow & Aufbewahrungssperre (Legal Hold) + +**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 3 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Löschworkflow für abgelaufene Objekte: Freigabe, Vernichtung, Protokolleintrag. Aufbewahrungssperre (Legal Hold) verhindert jede Löschung unabhängig vom Fristablauf. + +**Technische Grundlage:** PostgreSQL, transaktionaler Zustandswechsel + +## Produkt-DNA für diesen Bereich +> Aufbewahrung mit dem Ernst von Alfrescos Retention Policies, aber ohne dessen Ressourcen-Overhead. + +**Übernehmen:** +- Alfresco: Retention Policies mit Stichtagsberechnung je Objekttyp und automatischem Ablauf. +- ecoDMS: Revisionssicherheit als Grundhaltung – einmal archiviert, nicht mehr veränderbar. +- Alfresco: Aufbewahrungssperre (Legal Hold), die jede Löschregel überstimmt. + +**Bewusst vermeiden:** +- Alfresco – hoher Ressourcen-Overhead der Plattform: schlanker Go-Dienst statt schwergewichtiger Anwendungsserver. +- Keine modulspezifische Retention-Logik in DMS oder Mail – ein zentraler Adapter für alle Objekttypen. + +**Für genau diese Kachel:** Die Aufbewahrungssperre ist die Notbremse für laufende Verfahren – sie muss stärker sein als jede Fristregel. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `RET-02` Aufbewahrungsfristen-Engine – Fristenmodell je Aufbewahrungsklasse mit Stichtagsberechnung (Beginn, Dauer, Ablaufdatum) und periodischem Job, der ablaufende Objekte ermittelt. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Ablauf der Frist löst einen Freigabeprozess aus, keine automatische Sofortlöschung +2. Aufbewahrungssperre verhindert Löschung auch bei abgelaufener Frist, mit Begründungspflicht beim Setzen +3. Jede Vernichtung erzeugt einen unveränderlichen Protokolleintrag mit Zeitpunkt und ausführender Person + +## 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. Objekt mit aktiver Sperre widersteht einem direkten Löschversuch +2. Protokolleintrag nach Vernichtung ist nachträglich nicht änderbar (DB-Constraint oder Trigger) +3. Aufheben einer Sperre ist selbst protokolliert + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `CMP-06` Vier-Augen-Freigabe für Löschungen +- `QA-02` Prüfgate Retention & WORM + +## 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: `RET-03: löschworkflow-und-aufbewahrungssperre-legal-hold` +- Branch: `feature/ret-03-löschworkflow-und-aufbewahrungssperre-legal-hold` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/RET-04.md b/archive-kanban/tickets/RET-04.md new file mode 100644 index 00000000..46ccd84d --- /dev/null +++ b/archive-kanban/tickets/RET-04.md @@ -0,0 +1,62 @@ +# RET-04 – WORM-Speicher-Garantie (Append-only) + +**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 2 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Speicherpfad für archivierte Objektinhalte, der nach dem Schreiben keine Änderung und kein Überschreiben mehr zulässt (Write Once, Read Many). + +**Technische Grundlage:** Objekt-Storage-Anbindung, Append-only-Schreibpfad + +## Produkt-DNA für diesen Bereich +> Aufbewahrung mit dem Ernst von Alfrescos Retention Policies, aber ohne dessen Ressourcen-Overhead. + +**Übernehmen:** +- Alfresco: Retention Policies mit Stichtagsberechnung je Objekttyp und automatischem Ablauf. +- ecoDMS: Revisionssicherheit als Grundhaltung – einmal archiviert, nicht mehr veränderbar. +- Alfresco: Aufbewahrungssperre (Legal Hold), die jede Löschregel überstimmt. + +**Bewusst vermeiden:** +- Alfresco – hoher Ressourcen-Overhead der Plattform: schlanker Go-Dienst statt schwergewichtiger Anwendungsserver. +- Keine modulspezifische Retention-Logik in DMS oder Mail – ein zentraler Adapter für alle Objekttypen. + +**Für genau diese Kachel:** WORM ist das technische Rückgrat der Revisionssicherheit – ohne echte Append-only-Garantie bleibt jede Prüfung Theater. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `RET-01` Generisches Retention-Objektmodell – Generisches Datenmodell für aufbewahrungspflichtige Objekte anlegen: Objekttyp, Objekt-Referenz (modulübergreifend über Adapter), Aufbewahrungsklasse, Status. Migrationen versioniert und rückrollbar. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Einmal geschriebener Objektinhalt kann nicht überschrieben werden +2. Löschung ist ausschließlich über den kontrollierten Löschworkflow möglich, niemals direkt am Speicher +3. Prüfsumme je Objekt wird beim Schreiben erzeugt und bei jedem Lesezugriff verglichen + +## 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. Direkter Überschreibversuch am Speicherpfad wird abgewiesen +2. Prüfsummenabgleich erkennt eine manipulierte Testdatei zuverlässig +3. Löschung außerhalb des Workflows ist technisch unterbunden, nicht nur per Konvention + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `QA-02` Prüfgate Retention & WORM + +## 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: `RET-04: worm-speicher-garantie-append-only` +- Branch: `feature/ret-04-worm-speicher-garantie-append-only` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/RET-05.md b/archive-kanban/tickets/RET-05.md new file mode 100644 index 00000000..3012db6b --- /dev/null +++ b/archive-kanban/tickets/RET-05.md @@ -0,0 +1,63 @@ +# RET-05 – Modul-Adapter-Schnittstelle (DMS/Mail registrieren Objekttypen) + +**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 2 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Schnittstelle, über die DMS und Mail ihre Objekttypen (Dokument, Mail, Anhang) und die zugehörige Aufbewahrungsklasse bei Archive registrieren, statt eigene Retention-Logik zu bauen. + +**Technische Grundlage:** REST-Schnittstelle, Registrierungs-API + +## Produkt-DNA für diesen Bereich +> Aufbewahrung mit dem Ernst von Alfrescos Retention Policies, aber ohne dessen Ressourcen-Overhead. + +**Übernehmen:** +- Alfresco: Retention Policies mit Stichtagsberechnung je Objekttyp und automatischem Ablauf. +- ecoDMS: Revisionssicherheit als Grundhaltung – einmal archiviert, nicht mehr veränderbar. +- Alfresco: Aufbewahrungssperre (Legal Hold), die jede Löschregel überstimmt. + +**Bewusst vermeiden:** +- Alfresco – hoher Ressourcen-Overhead der Plattform: schlanker Go-Dienst statt schwergewichtiger Anwendungsserver. +- Keine modulspezifische Retention-Logik in DMS oder Mail – ein zentraler Adapter für alle Objekttypen. + +**Für genau diese Kachel:** Diese Schnittstelle ist der eigentliche Zweck des Boards: DMS und Mail bauen keine eigene Retention-Logik, sondern registrieren sich hier. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `RET-01` Generisches Retention-Objektmodell – Generisches Datenmodell für aufbewahrungspflichtige Objekte anlegen: Objekttyp, Objekt-Referenz (modulübergreifend über Adapter), Aufbewahrungsklasse, Status. Migrationen versioniert und rückrollbar. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Modul kann einen Objekttyp mit Aufbewahrungsklasse und Rückruf-Adresse für Löschbestätigung registrieren +2. Archive ruft das registrierte Modul beim Vernichten des Objekts zurück, statt selbst Modul-Interna zu kennen +3. Registrierung ist idempotent und mandantenfähig + +## 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. Zwei fiktive Module (DMS, Mail) parallel registriert ohne Kollision +2. Rückruf bei Vernichtung erfolgreich gegen einen Testendpunkt ausgeführt +3. Erneute Registrierung desselben Objekttyps ändert nichts am bestehenden Zustand + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `CMP-03` eDiscovery-Suche & Export (modulübergreifend) +- `ANA-01` Kennzahlen-Aggregation (modulübergreifend) + +## 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: `RET-05: modul-adapter-schnittstelle-dms-mail-registrieren-objekttypen` +- Branch: `feature/ret-05-modul-adapter-schnittstelle-dms-mail-registrieren-objekttypen` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/RET-06.md b/archive-kanban/tickets/RET-06.md new file mode 100644 index 00000000..044cb5aa --- /dev/null +++ b/archive-kanban/tickets/RET-06.md @@ -0,0 +1,62 @@ +# RET-06 – Aufbewahrungsfristen-Konfigurationsoberfläche + +**Epic:** ⏳ Retention & WORM | **Rolle:** Frontend | **Komplexität:** Mittel | **Aufwand:** 3 Personentage | **Welle:** 3 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Frontend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Oberfläche und Bedienbarkeit. Ruft ausschließlich vorhandene Schnittstellen auf, keine eigene Geschäftslogik. + +## Auftrag +Oberfläche zur Pflege von Aufbewahrungsklassen und Fristen je Objekttyp und Tenant, inklusive Vorschauliste bald ablaufender Objekte. + +**Technische Grundlage:** Next.js/React/TypeScript + +## Produkt-DNA für diesen Bereich +> Aufbewahrung mit dem Ernst von Alfrescos Retention Policies, aber ohne dessen Ressourcen-Overhead. + +**Übernehmen:** +- Alfresco: Retention Policies mit Stichtagsberechnung je Objekttyp und automatischem Ablauf. +- ecoDMS: Revisionssicherheit als Grundhaltung – einmal archiviert, nicht mehr veränderbar. +- Alfresco: Aufbewahrungssperre (Legal Hold), die jede Löschregel überstimmt. + +**Bewusst vermeiden:** +- Alfresco – hoher Ressourcen-Overhead der Plattform: schlanker Go-Dienst statt schwergewichtiger Anwendungsserver. +- Keine modulspezifische Retention-Logik in DMS oder Mail – ein zentraler Adapter für alle Objekttypen. + +**Für genau diese Kachel:** Ohne Konfigurationsoberfläche bleibt die Fristenengine ein Verwaltungsobjekt für Entwickler statt für Fachanwender. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `RET-02` Aufbewahrungsfristen-Engine – Fristenmodell je Aufbewahrungsklasse mit Stichtagsberechnung (Beginn, Dauer, Ablaufdatum) und periodischem Job, der ablaufende Objekte ermittelt. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Aufbewahrungsklasse mit Frist lässt sich anlegen, ändern und deaktivieren +2. Vorschauliste zeigt in den nächsten 30 Tagen ablaufende Objekte +3. Änderungen an Fristen sind nur berechtigten Rollen zugänglich + +## 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. Änderung einer Frist wirkt sich nur auf künftige Berechnungen aus, nicht rückwirkend auf bereits protokollierte Vernichtungen +2. Nicht berechtigte Rolle erhält keinen Zugriff auf die Konfiguration +3. Vorschauliste stimmt mit dem Ergebnis des periodischen Jobs überein + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- Alles, was nicht in den Akzeptanzkriterien steht. Keine vorauseilende Umsetzung späterer Anforderungen. + +## 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: `RET-06: aufbewahrungsfristen-konfigurationsoberfläche` +- Branch: `feature/ret-06-aufbewahrungsfristen-konfigurationsoberfläche` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/RET-07.md b/archive-kanban/tickets/RET-07.md new file mode 100644 index 00000000..b46b9e56 --- /dev/null +++ b/archive-kanban/tickets/RET-07.md @@ -0,0 +1,64 @@ +# RET-07 – Fristablauf-Benachrichtigungen + +**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 2 Personentage | **Welle:** 3 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Benachrichtigung verantwortlicher Personen vor Ablauf einer Aufbewahrungsfrist, konfigurierbarer Vorlauf je Aufbewahrungsklasse. Der eigentliche Versand läuft ausschließlich über den zentralen Core-Benachrichtigungs-Dispatcher (CFG-02) – Archive erzeugt nur das Ereignis, versendet keine E-Mail selbst. + +**Technische Grundlage:** Kopplung an Core CFG-02 (Benachrichtigungs-Dispatcher) + +## Produkt-DNA für diesen Bereich +> Aufbewahrung mit dem Ernst von Alfrescos Retention Policies, aber ohne dessen Ressourcen-Overhead. + +**Übernehmen:** +- Alfresco: Retention Policies mit Stichtagsberechnung je Objekttyp und automatischem Ablauf. +- ecoDMS: Revisionssicherheit als Grundhaltung – einmal archiviert, nicht mehr veränderbar. +- Alfresco: Aufbewahrungssperre (Legal Hold), die jede Löschregel überstimmt. + +**Bewusst vermeiden:** +- Alfresco – hoher Ressourcen-Overhead der Plattform: schlanker Go-Dienst statt schwergewichtiger Anwendungsserver. +- Keine modulspezifische Retention-Logik in DMS oder Mail – ein zentraler Adapter für alle Objekttypen. + +**Für genau diese Kachel:** Ohne Vorwarnung verkommt jede Fristenengine zur stillen Uhr, die niemand rechtzeitig liest. + +## Ausgangslage +Setzt voraus (externes Core-Board, siehe /home/sysops/Dokumente/Scripte/nexarch/core-kanban/): `CFG-02` Benachrichtigungs-Dispatcher – zentraler Versandweg für alle Module, kein eigener E-Mail-Versand je Modul. + +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `RET-02` Aufbewahrungsfristen-Engine – Fristenmodell je Aufbewahrungsklasse mit Stichtagsberechnung (Beginn, Dauer, Ablaufdatum) und periodischem Job, der ablaufende Objekte ermittelt. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Benachrichtigung wird im konfigurierten Vorlauf vor Fristablauf als Ereignis an Core CFG-02 übergeben, nicht selbst versendet +2. Mehrfachversand derselben Benachrichtigung wird verhindert +3. Benachrichtigung lässt sich je Aufbewahrungsklasse ein- und ausschalten + +## 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. Testfrist mit kurzem Vorlauf löst genau eine Benachrichtigung aus +2. Deaktivierte Benachrichtigung verschickt nachweislich nichts +3. Fehlgeschlagener Versand wird protokolliert und nicht stillschweigend verworfen + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- Alles, was nicht in den Akzeptanzkriterien steht. Keine vorauseilende Umsetzung späterer Anforderungen. + +## 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: `RET-07: fristablauf-benachrichtigungen` +- Branch: `feature/ret-07-fristablauf-benachrichtigungen` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/RET-11.md b/archive-kanban/tickets/RET-11.md new file mode 100644 index 00000000..c58761af --- /dev/null +++ b/archive-kanban/tickets/RET-11.md @@ -0,0 +1,58 @@ +# RET-11 – Storage-seitige WORM-Durchsetzung (Object-Lock statt nur Anwendungslogik) + +**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 7 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (Retention & WORM, Compliance & eDiscovery, Backup & Wiederherstellung, Kennzahlen), das sich an Alfresco, ecoDMS und restic/Borg orientiert. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +RET-04 verhindert Änderung/Überschreiben archivierter Objektinhalte nach dem Schreiben, aber ohne explizite Festlegung, ob dies nur durch Anwendungscode (übersprungen bei direktem Storage-Zugriff) oder durch eine Storage-seitige Garantie (z. B. S3 Object Lock im Compliance-Mode) erzwungen wird. WORM-Objekte über die Object-Lock-Funktion des Storage-Backends selbst sperren, sodass auch ein Zugriff mit vollen Storage-Zugangsdaten unterhalb der Anwendung keine Änderung/Löschung vor Fristablauf erlaubt. + +**Technische Grundlage:** S3 Object Lock / Compliance-Mode, PostgreSQL, Go + +## Produkt-DNA für diesen Bereich +**Übernehmen:** +- restic/Borg: Unveränderlichkeit als Eigenschaft des Speichers, nicht nur der aufrufenden Anwendung. + +**Bewusst vermeiden:** +- Alfresco – in älteren Konfigurationen teils nur anwendungsseitige Lösch-Sperre ohne Storage-Garantie.: WORM ist eine Storage-Backend-Garantie (Object Lock), die Anwendungslogik ist die zweite, nicht die einzige Verteidigungslinie. + +## Ausgangslage +Setzt auf folgenden bereits fertigen Kacheln auf: RET-04. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Jedes WORM-Objekt wird beim Schreiben mit einer Storage-seitigen Object-Lock-Sperre bis zum Ablauf der Aufbewahrungsfrist versehen +2. Ein Löschversuch mit direkten Storage-Zugangsdaten (unterhalb der Anwendung) schlägt vor Fristablauf fehl, nachweislich durch das Storage-Backend selbst und nicht nur durch Anwendungscode +3. Nach Fristablauf und regulärer Freigabe (RET-03) ist das Objekt normal löschbar + +## 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. Test: direkter Löschversuch über die Storage-API (nicht über die NEXARCH-Anwendung) auf ein gesperrtes Objekt schlägt fehl +2. Test: nach Fristablauf und Freigabe durch RET-03 ist die Löschung über den regulären Workflow möglich +3. Konfigurationsprüfung: Object-Lock/Compliance-Mode ist für den produktiven Bucket aktiviert, dokumentiert in der Betriebsanleitung + +## Bekannte Fehler vermeiden + +Threat-Model-Finding (Archive-Board, 2026-09-12): reine Anwendungslogik gegen Überschreiben schützt nicht gegen einen Akteur mit direktem Storage-Zugriff (kompromittierte Zugangsdaten, Fehlkonfiguration) — GoBD/WORM-Anforderungen verlangen eine tatsächlich technische, nicht nur anwendungsseitige Garantie. + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `RET-04` WORM-Speicher-Garantie (Append-only) + +## 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: `RET-11: storage-seitige-worm-durchsetzung-object-lock-statt-nur-anwendungslogik` +- Branch: `feature/ret-11-storage-seitige-worm-durchsetzung-object-lock-statt-nur-anwendungslogik` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/RET-12.md b/archive-kanban/tickets/RET-12.md new file mode 100644 index 00000000..52058571 --- /dev/null +++ b/archive-kanban/tickets/RET-12.md @@ -0,0 +1,58 @@ +# RET-12 – Unabhängige Tenant-Validierung bei Objekttyp-Registrierung durch DMS/Mail + +**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 7 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (Retention & WORM, Compliance & eDiscovery, Backup & Wiederherstellung, Kennzahlen), das sich an Alfresco, ecoDMS und restic/Borg orientiert. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +RET-05 nimmt Objekttyp- und Aufbewahrungsklassen-Registrierungen von DMS und Mail entgegen. Ohne unabhängige Prüfung würde Archive dem vom registrierenden Modul mitgelieferten Tenant-Kontext blind vertrauen. Jede Registrierung muss den mitgelieferten Tenant-Kontext gegen die Core-Registry (TEN-01) validieren, unabhängig vom Service-Credential-Scope des aufrufenden Moduls – Archive verlässt sich nicht allein auf die Angabe von DMS/Mail. + +**Technische Grundlage:** Service-Credentials (Core API-02), Tenant-Registry-Abgleich (Core TEN-01), Go + +## Produkt-DNA für diesen Bereich +**Übernehmen:** +- Casbin: Autorisierungsentscheidung bleibt zentral und unabhängig von der meldenden Quelle. + +**Bewusst vermeiden:** +- Keycloak – Vertrauen in vom Client mitgelieferte Claims ohne serverseitige Gegenprüfung führte zu Eskalationsfällen.: Archive verifiziert den Tenant-Kontext jeder eingehenden Registrierung selbst gegen die Core-Registry, statt der Angabe des meldenden Moduls zu vertrauen. + +## Ausgangslage +Setzt auf folgenden bereits fertigen Kacheln auf: RET-05. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Jede Objekttyp-/Aufbewahrungsklassen-Registrierung aus DMS/Mail wird gegen die Core-Registry auf Tenant-Gültigkeit geprüft, bevor sie übernommen wird +2. Eine Registrierung mit einem nicht existierenden oder falschem Tenant-Kontext wird abgelehnt und protokolliert +3. Bestehende, korrekte Registrierungsabläufe aus RET-05 funktionieren unverändert + +## 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. Test: Registrierung mit gültigem, existierendem Tenant-Kontext wird übernommen +2. Test: Registrierung mit manipuliertem/fremdem Tenant-Kontext wird abgelehnt +3. Regressionstest: normaler DMS-/Mail-Registrierungsablauf bleibt funktionsfähig + +## Bekannte Fehler vermeiden + +Threat-Model-Finding (Archive-Board, 2026-09-12): Archive ist die Senke für Retention-Registrierungen aus zwei anderen Modulen — ohne eigene Validierung würde ein Fehler oder eine Kompromittierung in DMS/Mail unmittelbar auf die Compliance-kritische Retention-Zuordnung in Archive durchschlagen. + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `RET-05` Modul-Adapter-Schnittstelle (DMS/Mail registrieren Objekttypen) + +## 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: `RET-12: unabh-ngige-tenant-validierung-bei-objekttyp-registrierung-durch-dms-mail` +- Branch: `feature/ret-12-unabh-ngige-tenant-validierung-bei-objekttyp-registrierung-durch-dms-mail` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/RET-13.md b/archive-kanban/tickets/RET-13.md new file mode 100644 index 00000000..e0bbe235 --- /dev/null +++ b/archive-kanban/tickets/RET-13.md @@ -0,0 +1,56 @@ +# RET-13 – Legal-Hold-Abfrage-Endpunkt für Module + +**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 8 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (Retention & WORM, Compliance & eDiscovery, Backup & Wiederherstellung, Kennzahlen), das sich an Alfresco, ecoDMS und restic/Borg orientiert. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +RET-03 hält Aufbewahrungssperren (Legal Hold) in `legal_holds`, aber nur als Go-Funktion (`deletionworkflow.IsOnLegalHold`). Module, die Objekte endgültig löschen (DMS: Papierkorb-Leerung, Ablauf der Papierkorbfrist), können die Sperre bisher nicht abfragen. Archive stellt dafür einen schreibgeschützten HTTP-Endpunkt bereit, den das DMS (INT-11, `retentionclient.CheckLegalHold`) bereits als Vertrag annimmt. + +**Technische Grundlage:** `GET /legal-hold?object_type=&object_reference=`, Antwort `200 {"on_hold": bool, "reason": string}`; Tenant-Registry-Abgleich (RET-12), Go + +## Produkt-DNA für diesen Bereich +**Übernehmen:** +- Alfresco/ecoDMS: Die Sperre wirkt vor jeder Löschung, unabhängig davon, welches Modul löscht. + +**Bewusst vermeiden:** +- Ein Aufrufer, der bei Unklarheit „nicht gesperrt“ annimmt. Archive liefert nur, was in der Datenbank steht. Alles Unklare (Fehler, Fremdmandant, fehlende Konfiguration) ist ein Fehlerstatus, nie `on_hold: false`. +- Vertrauen in den vom Modul mitgelieferten Tenant-Kontext (RET-12): Archive prüft ihn selbst und bindet ihn an die Instanz. + +## Ausgangslage +Setzt auf folgenden bereits fertigen Kacheln auf: RET-03, RET-05, RET-12. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. `GET /legal-hold` liefert für ein registriertes Objekt mit aktiver Sperre `on_hold: true` samt Grund, ohne aktive Sperre (nie gesperrt oder aufgehoben) `on_hold: false` +2. Ein fehlender oder fremder Tenant-Kontext, ein unbekannter Tenant, ein nicht erreichbares Tenant-Register und ein Datenbankfehler führen zu einem Fehlerstatus (400/403/503), nie zu `on_hold: false` +3. Die Abfrage ist rein lesend und mandantengetrennt: Sie liest ausschließlich die Datenbank der Instanz und ändert keine Sperre + +## 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. Test gegen echte Datenbank: gesperrtes, freigegebenes, nie gesperrtes und unbekanntes Objekt liefern die erwartete Antwort +2. Test: fremder Tenant, manipulierter Tenant-Header, Registry-Ausfall und Datenbankausfall werden nie als „nicht gesperrt“ beantwortet +3. Vertragstest: der DMS-`retentionclient` fragt den echten Archive-Handler ab (lokaler Lauf gegen Wegwerf-Datenbank) + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `RET-03` Setzen und Aufheben von Sperren +- Dienst-zu-Dienst-Authentifizierung über Core-Modul-Tokens (Core-Board): Archive prüft optional ein Service-Token, bis Core es verbindlich ausliefert + +## 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: `RET-13: legal-hold-abfrage-endpunkt` +- Branch: `feature/ret-13-legal-hold-abfrage-endpunkt` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/RET-14.md b/archive-kanban/tickets/RET-14.md new file mode 100644 index 00000000..39070dd6 --- /dev/null +++ b/archive-kanban/tickets/RET-14.md @@ -0,0 +1,65 @@ +# RET-14 – Dienstauthentifizierung und Rückruf-URL-Prüfung im Archive-Adapter + +**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 14 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (Retention & WORM, Compliance & eDiscovery, Backup & Wiederherstellung, Kennzahlen), das sich an Alfresco, ecoDMS und restic/Borg orientiert. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +`POST /register` (RET-05) hat keine Dienstauthentifizierung und prüft `callback_url` nicht; `/legal-hold` (RET-13) behandelt das Service-Token als optional und vergleicht es längenabhängig (Befunde F-08, F-23). Beide Endpunkte verlangen ein Service-Token (fail closed, Übergangsschalter mit Warnlog), `callback_url` wird gegen Schema, Adresse und Policy geprüft, und Rückrufe folgen keinen Weiterleitungen. + +**Technische Grundlage:** `archive/internal/svcauth` (Hash-Vergleich in konstanter Zeit), `archive/internal/moduleadapter` (`RegisterConfig`, `CallbackPolicy`, `NewCallbackClient`), `NEXARCH_MODULEADAPTER_SERVICE_TOKEN`, `_ALLOW_UNAUTHENTICATED`, `_CALLBACK_ALLOW_HTTP`, `_CALLBACK_ALLOWED_TARGETS` + +## Produkt-DNA für diesen Bereich +> Wer Rückrufe registrieren darf, muss sich ausweisen, und Archive ruft nur Ziele an, die es anrufen darf. + +**Übernehmen:** +- Service-Token und Mandantenbindung nach RET-13. + +**Bewusst vermeiden:** +- Keine Rückrufe an Loopback, private Netze oder Link-Local (Cloud-Metadaten) ohne ausdrückliche Freigabe. +- Keine Prüfung nur bei der Registrierung: DNS-Rebinding wird beim Verbindungsaufbau erneut geprüft. + +## Ausgangslage +Die folgenden Arbeitspakete sind bereits fertiggestellt und dürfen vorausgesetzt werden. Baue auf ihnen auf, statt Funktionalität zu duplizieren: +- `QA-15` Sicherheitsprüfung Gesamtprojekt – Befundbericht `docs/SICHERHEITSPRUEFUNG-GESAMTPROJEKT.md`, hier: F-08 (mittel), F-23 (niedrig). +- `RET-05` Modul-Adapter, `RET-12` Tenant-Prüfung, `RET-13` Sperrabfrage. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. `/register` und `/legal-hold` verlangen `X-Service-Token` (Vergleich über SHA-256 in konstanter Zeit); ohne konfiguriertes Token antworten beide 503, außer `NEXARCH_MODULEADAPTER_ALLOW_UNAUTHENTICATED=true` +2. `callback_url` wird nur mit https (http per Konfiguration), ohne Benutzerangabe, mit gültigem Port und nur zu erlaubten Zielen registriert; Link-Local, unspezifizierte, Multicast- und Broadcast-Adressen sind nie erlaubt, Loopback und private Netze nur über die Allowlist +3. Rückrufe und Kennzahlen-Abrufe nutzen einen Client mit Zeitlimit ohne Weiterleitungen, der die Zieladresse beim Verbindungsaufbau prüft und direkt anwählt + +## 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. SSRF-Negativfälle: 127.0.0.1, ::1, 169.254.169.254, 10.x, file://, Rechnername mit Rebinding auf Loopback, Weiterleitung auf interne Ziele +2. Vertragstest DMS↔Archive (`scripts/legalhold-contract-test.sh`) mit und ohne Token sowie fail-closed ohne Konfiguration +3. Archive-Tests (`moduleadapter`, `legalholdapi`, `contracttest`, `kennzahlen`) und Build der Module auf dem Entwicklungshost + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- Ratenbegrenzung (Core-Gateway) +- Registrierung mehrerer Ziele je Objekttyp + +## 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 +- Status: umgesetzt in Branch `feature/qa-15-phase2b-sicherheitsbehebung` (PR gegen `integration/gesamtprojekt`), Protokoll `docs/QA-15-PHASE2B-PRUEFPROTOKOLL.md` +- Commit-Nachricht: `RET-14: dienstauthentifizierung und rueckruf-url-pruefung` +- Branch: `feature/qa-15-phase2b-sicherheitsbehebung` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. + +--- +## Status-Notiz (2026-09-23) +F-08/F-23 (Dienstauthentifizierung POST /register, callback_url-Prüfung) sind bereits in PR #121 (QA-15 Phase 2b/2c, docs/QA-15-PHASE2C-PRUEFPROTOKOLL.md bzw. der Vorlauf-Fix in sec-fix-b) umgesetzt: Service-Token Pflicht (fail closed, Übergangsschalter), callback_url-Validierung gegen SSRF, keine Weiterleitungen. Ob RET-13s längenabhängiger Vergleich (Teil dieses Tickets) ebenfalls schon per Konstantzeitvergleich läuft, ist noch zu verifizieren — kleiner Restpunkt, kein eigener Branch nötig, siehe Folge-QA. diff --git a/archive-kanban/tickets/RET-15.md b/archive-kanban/tickets/RET-15.md new file mode 100644 index 00000000..77004b55 --- /dev/null +++ b/archive-kanban/tickets/RET-15.md @@ -0,0 +1,44 @@ +# RET-15 – Echter End-zu-Ende-Nachweis Storage-Object-Lock auf chattr-fähigem Host + +**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 1 Personentag | **Welle:** 9 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (Retention & WORM, Compliance & eDiscovery, Backup & Wiederherstellung, Kennzahlen), das sich an Alfresco, ecoDMS und restic/Borg orientiert. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +RET-11 implementiert Storage-Object-Lock über `chattr +i`. Auf beiden bisher geprüften Hosts (131, 204) scheitert `chattr +i` strukturell mit `EPERM` — die Untersuchung in `RET-11-NACHTRAG-CHATTR-UNTERSUCHUNG.md` hat die Ursache geklärt: **nicht das Dateisystem (ZFS)**, sondern dass beide Hosts **unprivilegierte LXC-Container** sind. `CAP_LINUX_IMMUTABLE` wird im Kernel bewusst nicht namespace-bewusst geprüft (per rohem ioctl bestätigt, nicht nur am `chattr`-Binary), 8 Alternativen wurden geprüft und als unzureichend befunden (einzige strukturell gleichwertige Alternative: echtes S3/MinIO-Object-Lock-Backend, Architekturwechsel). Der erfolgreiche Pfad (ein tatsächlich privilegierter Host/Container) wurde in diesem Projekt bislang nirgends real bestätigt. `wormstore.Store.Put` ist fail-closed: schlägt `chattr +i` fehl, wird der Schreibvorgang verworfen — das ist technisch sicher (kein stiller Integritätsverlust), aber die eigentliche WORM-Garantie (Akzeptanzkriterium 1/2 aus RET-11) ist bislang nur per Code-/Kernel-Analyse, nicht per echtem End-zu-Ende-Test auf einem funktionierenden Host belegt. + +**Technische Grundlage:** ein tatsächlich privilegierter Host/Container (`CAP_LINUX_IMMUTABLE` im Host-Namespace), unabhängig vom Dateisystem — oder das in RET-11-NACHTRAG-CHATTR-UNTERSUCHUNG.md als einzige gleichwertige Alternative genannte externe Object-Lock-Backend (S3/MinIO Compliance-Mode), falls ein privilegierter Host nicht verfügbar gemacht werden kann. + +## Ausgangslage +Setzt auf folgenden bereits fertigen Kacheln auf: RET-11, QA-02, QA-07, QA-05 (alle Archive-Board). Lies vor Beginn `archive/docs/RET-11-NACHTRAG-CHATTR-UNTERSUCHUNG.md` vollständig (PR #312) — die Ursachenanalyse und alle 8 geprüften Alternativen sind dort bereits dokumentiert, nicht wiederholen. + +## Akzeptanzkriterien +1. Ein Host oder eine Umgebung mit tatsächlich wirksamem `chattr +i` (oder einer als gleichwertig befundenen Alternative) ist identifiziert und dokumentiert +2. Auf diesem Host/dieser Umgebung schlägt ein direkter Löschversuch auf ein storage-gesperrtes WORM-Objekt nachweislich fehl (echter Test, kein SKIP) +3. Ergebnis ist im bestehenden RET-11-Prüfprotokoll als Nachtrag ergänzt, nicht als neues Parallel-Protokoll + +## Prüfungen vor der Abnahme +1. Test auf dem identifizierten Host real ausgeführt, Ergebnis dokumentiert +2. Falls kein chattr-fähiger Host verfügbar ist: begründete Dokumentation, dass dies weiterhin offen bleibt und welche Bedingung (z. B. privilegierter Produktions-Host) die Prüfung ermöglichen würde + +## Nicht Bestandteil dieser Kachel +- Erneute Grundsatzuntersuchung aller Alternativen (bereits erfolgt, siehe Ausgangslage) +- Produktiv-Rollout + +## Arbeitsweise +1. Lies zuerst RET-11-PRUEFPROTOKOLL.md und ein eventuell vorhandenes Nachtrag-Dokument vollständig. +2. Setze die kleinste Lösung um, die alle Akzeptanzkriterien erfüllt. +3. Schreibe zu jedem Akzeptanzkriterium mindestens einen automatisierten Test, falls ein geeigneter Host verfügbar ist. +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: `RET-15: echter-ende-zu-ende-nachweis-storage-object-lock-chattr-faehiger-host` +- Branch: `feature/ret-15-echter-ende-zu-ende-nachweis-storage-object-lock-chattr-faehiger-host` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/RET-16.md b/archive-kanban/tickets/RET-16.md new file mode 100644 index 00000000..e4266bb7 --- /dev/null +++ b/archive-kanban/tickets/RET-16.md @@ -0,0 +1,34 @@ +# RET-16 – STORAGE-KONZEPT.md: Voraussetzung für Storage-Object-Lock (unprivilegierter Container statt ZFS) klären + +**Epic:** ⏳ Retention & WORM | **Rolle:** Backend | **Komplexität:** Einfach | **Aufwand:** 0,5 Personentage | **Welle:** 9 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (Retention & WORM, Compliance & eDiscovery, Backup & Wiederherstellung, Kennzahlen), das sich an Alfresco, ecoDMS und restic/Borg orientiert. + +## Auftrag +`STORAGE-KONZEPT.md` (Abschnitt 2) listet ZFS als gleichwertige Stufe-1-Backend-Option, ohne auf eine Einschränkung bei Storage-Object-Lock hinzuweisen. `RET-11-PRUEFPROTOKOLL.md` samt Nachtrag (`RET-11-NACHTRAG-CHATTR-UNTERSUCHUNG.md`) hat die tatsächliche Ursache geklärt: **nicht ZFS** verhindert `chattr +i`, sondern dass Host 131/204 **unprivilegierte LXC-Container** sind — `CAP_LINUX_IMMUTABLE` wird im Kernel bewusst nicht namespace-bewusst geprüft (Kernel-Design-Entscheidung, Patch dafür 2014 abgelehnt). Das Problem träte identisch auf ext4/XFS/Btrfs auf, solange der Container unprivilegiert ist. Dieser Zusammenhang muss in der Betriebsdokumentation korrekt stehen, bevor eine produktive Stufe-1-Inbetriebnahme erfolgt — sonst wird fälschlich am Dateisystem statt an der Container-Privilegierung gesucht. + +## Akzeptanzkriterien +1. `STORAGE-KONZEPT.md` Abschnitt 2 enthält einen expliziten Hinweis: Storage-Object-Lock (`chattr +i`, RET-11) setzt einen privilegierten Host/Container voraus (oder ein alternatives, von RET-15 nachgewiesenes Verfahren) — unabhängig vom gewählten Dateisystem (ZFS, ext4, XFS, Btrfs) +2. Verweis auf RET-11-PRUEFPROTOKOLL.md und dessen Nachtrag als Quelle des Befundes ist im Dokument ergänzt +3. Keine andere inhaltliche Aussage von STORAGE-KONZEPT.md wird verändert + +## Prüfungen vor der Abnahme +1. Dokument-Review: Hinweis ist vorhanden, eindeutig, nennt die richtige Ursache (Container-Privilegierung, nicht Dateisystem) und widerspricht keiner anderen Stelle im Dokument +2. Diff-Prüfung: keine ungewollten Änderungen außerhalb des betroffenen Abschnitts + +## Nicht Bestandteil dieser Kachel +- Technische Lösung des chattr-Problems selbst (siehe RET-15) +- Änderungen an anderen Konzeptdokumenten + +## Arbeitsweise +1. Lies `STORAGE-KONZEPT.md` Abschnitt 2 und `RET-11-PRUEFPROTOKOLL.md` vollständig. +2. Kleinste Änderung: nur den Ausnahmevermerk ergänzen, keine Umformulierung des übrigen Textes. +3. Deutschsprachiger Text. + +## Abschluss +- Commit-Nachricht: `RET-16: storage-konzept-widerspruch-zfs-als-worm-backend-klaeren` +- Branch: `feature/ret-16-storage-konzept-widerspruch-zfs-als-worm-backend-klaeren` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. diff --git a/archive-kanban/tickets/SEC-01.md b/archive-kanban/tickets/SEC-01.md new file mode 100644 index 00000000..6c939627 --- /dev/null +++ b/archive-kanban/tickets/SEC-01.md @@ -0,0 +1,52 @@ +# SEC-01 – Rolle muss aus verifizierter Identität kommen, nicht aus Client-Header + +**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Hoch | **Aufwand:** 3 Personentage | **Welle:** 10 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco (Retention Policies, revisionssichere Ablage, Vier-Augen-Prinzip), ecoDMS (Revisionssicherheit, nachvollziehbare Vernichtung) und restic/Borg (inkrementelle, deduplizierende, verifizierbare Sicherung) orientiert und deren bekannte Schwächen bewusst vermeidet – insbesondere den Ressourcen-Overhead von Alfresco. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Security-Review (main-Branch, Fable 5.1) hat einen kritischen Befund (K3) bestätigt: `archive/internal/retentionapi/authz.go:26-33` liest die Rolle per `role := r.Header.Get("X-User-Role")` direkt aus einem Client-Header und übergibt sie unverändert an `client.Authorize(ctx, role, permission)`. Geprüft wird nur "darf Rolle X diese Aktion", nicht "hat der Aufrufer wirklich Rolle X" – der Header ist durch jeden Aufrufer frei wählbar. Betroffen sind außerdem `kennzahlenapi/handler.go:30-31` und `complianceapi/handler.go:39-45`, die dasselbe Muster übernehmen. Das Frontend verstärkt den Missstand: `web/compliance-reports/lib/api.ts:22-26` und `web/retention-admin/lib/api.ts:22` senden `NEXT_PUBLIC_USER_ROLE` – eine öffentliche Build-Variable, die im Browser sichtbar und durch jeden Nutzer änderbar ist – direkt als Header, und CORS ist dafür offen konfiguriert (`retentionapi/cors.go:19`). + +**Angriffsszenario:** `curl -H 'X-User-Role: archive_admin' -d '{"report_type":"dsgvo","data_subject_ref":""}' POST /compliance/reports` erzeugt für jede beliebige Person einen DSGVO-Auskunftsbericht als CSV samt Download-Token, ohne dass der Aufrufer tatsächlich die Rolle `archive_admin` besitzt. Ebenso verkürzt `POST /retention-classes` mit demselben gefälschten Header Aufbewahrungsfristen und ermöglicht vorzeitige Löschbarkeit archivierter Objekte. `requested_by` wird dabei nur als Rollenname gespeichert (`complianceapi/handler.go:77`), sodass das Audit-Log nicht personenbezogen ist und der tatsächliche Angreifer nicht rekonstruierbar bleibt. + +**Technische Grundlage:** Go, bestehende Authentifizierungs-Infrastruktur (Session/JWT) der Plattform, Next.js (Frontend-Teil) + +## Ausgangslage +`RET-01` Generisches Retention-Objektmodell, `CMP-02` DSGVO-/Datenschutz-Berichte und `RET-05` Modul-Adapter-Schnittstelle sind bereits fertiggestellt und betroffen; diese Kachel ändert ihre Autorisierungsschicht, nicht ihre fachliche Logik. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. `authz.go` liest die Rolle ausschließlich aus einer serverseitig verifizierten Identität (Session- oder JWT-Claim), niemals aus einem vom Client gesetzten Header; `X-User-Role` wird in retention-api, kennzahlenapi und complianceapi vollständig ignoriert bzw. abgelehnt +2. `NEXT_PUBLIC_USER_ROLE` ist aus `web/compliance-reports/lib/api.ts` und `web/retention-admin/lib/api.ts` entfernt; die Rolle wird serverseitig aus der Session abgeleitet, nicht vom Client mitgesendet +3. `requested_by` in `complianceapi/handler.go:77` speichert eine nachvollziehbare, personenbezogene Identität (z. B. User-ID aus der verifizierten Identität), nicht nur den Rollennamen +4. CORS-Konfiguration in `retentionapi/cors.go:19` lässt Rollen-Header-basierte Cross-Origin-Zugriffe nicht mehr zu + +## 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. Angriff real nachgestellt: `curl -H 'X-User-Role: archive_admin' ...` gegen `/compliance/reports` und `/retention-classes` mit einer Sitzung ohne diese Rolle ausgeführt – Ergebnis vor Fix: Bericht/Änderung wird erzeugt; Ergebnis nach Fix: Anfrage wird mit 401/403 abgelehnt +2. Legitimer Aufruf mit echter `archive_admin`-Rolle aus verifizierter Session funktioniert weiterhin unverändert +3. Audit-Log-Eintrag nach einem legitimen DSGVO-Bericht enthält die tatsächliche Nutzeridentität, nicht nur "archive_admin" +4. Frontend-Build enthält `NEXT_PUBLIC_USER_ROLE` nachweislich nicht mehr (Grep im Build-Output) + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `SEC-02` Tenant-Validierung in kennzahlenapi +- Aufbau eines neuen zentralen Identity-Providers (setzt vorhandene Session/JWT-Infrastruktur voraus, baut sie nicht neu) + +## 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, einschließlich eines Negativtests, der den beschriebenen Angriff nachstellt und als blockiert nachweist. +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: rolle-aus-verifizierter-identitaet-statt-client-header` +- Branch: `feature/sec-01-rolle-aus-verifizierter-identitaet-statt-client-header` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/SEC-02.md b/archive-kanban/tickets/SEC-02.md new file mode 100644 index 00000000..d3422339 --- /dev/null +++ b/archive-kanban/tickets/SEC-02.md @@ -0,0 +1,49 @@ +# SEC-02 – Tenant-Validierung in kennzahlenapi fehlt (Cross-Tenant-Leseleck) + +**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Niedrig | **Aufwand:** 1 Personentag | **Welle:** 10 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco, ecoDMS und restic/Borg orientiert. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Security-Review (main-Branch, Fable 5.1) hat einen hohen Befund (H11) bestätigt: `archive/internal/kennzahlenapi/handler.go:45` liest `tenant := r.URL.Query().Get("tenant")` und verwendet ihn direkt für die Datenabfrage – anders als `legalholdapi.go:82` fehlt hier der Vergleich mit `InstanceTenant`. `archive_metrics_snapshots` ist tenant-gespalten (Migration 0011) und wird aus `module_registrations.tenant_slug` befüllt. Ohne die Validierung kann jeder Aufrufer mit gültigem Zugriff auf die kennzahlen-api über `?tenant=` die Kennzahlen jedes beliebigen Mandanten lesen; in Kombination mit `SEC-01` (gefälschte Rolle) verschärft sich das Risiko zusätzlich. + +**Angriffsszenario:** `GET /kennzahlen?tenant=` liefert die `archive_metrics_snapshots` eines fremden Mandanten aus, obwohl der Aufrufer nur für den eigenen Mandanten berechtigt ist. + +**Technische Grundlage:** Go, bestehendes `InstanceTenant`-Validierungsmuster aus `legalholdapi.go:82` + +## Ausgangslage +`RET-01` Generisches Retention-Objektmodell und die Kennzahlen-Aggregation (Migration 0011) sind bereits fertiggestellt. Diese Kachel übernimmt ausschließlich das bestehende Validierungsmuster aus `legalholdapi.go`. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. `kennzahlenapi/handler.go:45` validiert den Query-Parameter `tenant` gegen `InstanceTenant` nach demselben Muster wie `legalholdapi.go:82` +2. Eine Abweichung zwischen angefragtem `tenant` und `InstanceTenant` führt zu einer Ablehnung der Anfrage (403), nicht zu stillschweigendem Ignorieren oder Filtern +3. Bestehende legitime Aufrufe ohne abweichenden `tenant`-Parameter funktionieren unverändert + +## 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. Angriff real nachgestellt: `GET /kennzahlen?tenant=` mit einer Sitzung eines anderen Mandanten ausgeführt – Ergebnis vor Fix: fremde Kennzahlen werden ausgeliefert; Ergebnis nach Fix: Anfrage wird mit 403 abgelehnt +2. Legitimer Aufruf mit eigenem `tenant`-Parameter liefert weiterhin korrekte Daten +3. Vergleich des neuen Codes mit `legalholdapi.go:82` auf Musterkonsistenz dokumentiert + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `SEC-01` Rolle muss aus verifizierter Identität kommen (behebt das zugrundeliegende RBAC-Problem, nicht Teil dieser Kachel) + +## 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, einschließlich eines Negativtests, der den beschriebenen Angriff nachstellt und als blockiert nachweist. +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: tenant-validierung-kennzahlenapi` +- Branch: `feature/sec-02-tenant-validierung-kennzahlenapi` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/SEC-03.md b/archive-kanban/tickets/SEC-03.md new file mode 100644 index 00000000..2901788a --- /dev/null +++ b/archive-kanban/tickets/SEC-03.md @@ -0,0 +1,50 @@ +# SEC-03 – TOCTOU Legal Hold vs. Destroy; Destroy außerhalb der äußeren Transaktion + +**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 10 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco, ecoDMS und restic/Borg orientiert. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Security-Review (main-Branch, Fable 5.1) hat einen mittleren Befund (M1) bestätigt: In `archive/internal/deletionworkflow/deletionworkflow.go:143-162` wird `IsOnLegalHold` als separater Query ausgeführt, bevor ein zweiter Schritt `UPDATE retention_objects SET status='deleted' WHERE id=$1 AND status='expired'` ausgeführt wird – ohne `AND NOT EXISTS (legal_holds...)` in derselben Anweisung. Ein zwischen den beiden Schritten gesetzter Legal Hold (klassisches TOCTOU-Zeitfenster) verhindert die Löschung nicht mehr. Zusätzlich ruft `archive/internal/deletionapproval/deletionapproval.go:112-118` `Destroy(ctx, pool, …)` mit dem rohen Connection-Pool statt mit einer Transaktion auf – das Objekt wird physisch vernichtet, selbst wenn der äußere Löschantrag danach nicht committet wird (z. B. bei einem nachfolgenden Fehler in der Antragsfinalisierung). + +**Angriffsszenario / Fehlerszenario:** Ein Objekt wird zur Löschung freigegeben; unmittelbar danach wird (z. B. durch eDiscovery oder einen Rechtsstreit) ein Legal Hold gesetzt. Da die Prüfung nicht atomar mit der Löschung verknüpft ist, wird das Objekt trotz aktivem Legal Hold gelöscht. Zusätzlich kann ein Fehler nach `Destroy()`, aber vor Commit des äußeren Löschantrags dazu führen, dass die physische Vernichtung bereits stattgefunden hat, während der Datenbankzustand den Löschantrag als nicht abgeschlossen zeigt – ein inkonsistenter, nicht revidierbarer Zustand. + +**Technische Grundlage:** PostgreSQL, pgx/v5, atomare UPDATE-Bedingungen, Transaktionssteuerung + +## Ausgangslage +`RET-04` WORM-Speicher-Garantie und das Legal-Hold-Datenmodell (`legal_holds`-Tabelle) sind bereits fertiggestellt. Diese Kachel ändert ausschließlich die Reihenfolge und Atomizität bestehender Löschlogik. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Die Legal-Hold-Prüfung ist Teil derselben atomaren `UPDATE`-Anweisung wie die Statusänderung auf `deleted` (z. B. `AND NOT EXISTS (SELECT 1 FROM legal_holds ...)` in derselben Anweisung), sodass ein zwischen Prüfung und Update gesetzter Legal Hold die Löschung zuverlässig verhindert +2. `Destroy(ctx, pool, …)` in `deletionapproval.go:112-118` wird innerhalb derselben Transaktion ausgeführt wie die Antragsfinalisierung; schlägt die Finalisierung fehl, wird die Destroy-Wirkung nicht wirksam (Rollback) bzw. die physische Löschung erfolgt erst nach erfolgreichem Commit +3. Es gibt keinen Codepfad mehr, auf dem ein Objekt physisch vernichtet wird, während der zugehörige DB-Zustand den Löschantrag noch als offen/nicht abgeschlossen zeigt + +## 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. TOCTOU real nachgestellt: Legal Hold wird exakt im Zeitfenster zwischen Prüfung und Update gesetzt (z. B. über parallele Testroutine oder gezielte Verzögerung) – Ergebnis vor Fix: Löschung erfolgt trotz Hold; Ergebnis nach Fix: Löschung wird blockiert +2. Simulierter Fehler nach `Destroy()` und vor Commit der äußeren Transaktion nachgestellt – Ergebnis nach Fix: entweder Destroy wird nicht wirksam oder der DB-Zustand bleibt konsistent mit der physischen Löschung +3. Regulärer Löschvorgang ohne Legal Hold und ohne Fehler funktioniert 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` wormstore Release/Destroy ohne Legal-Hold-Prüfung (eigenständiger Befund in anderer Schicht) +- `SEC-06` Append-only-Lücken inkl. `legal_holds`-Kaskade (DB-seitige Schutzschicht, nicht Teil dieser Kachel) + +## 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, einschließlich eines Tests, der das TOCTOU-Fenster real nachstellt und als blockiert nachweist. +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: toctou-legal-hold-destroy-atomar` +- Branch: `feature/sec-03-toctou-legal-hold-destroy-atomar` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/SEC-04.md b/archive-kanban/tickets/SEC-04.md new file mode 100644 index 00000000..02bc110e --- /dev/null +++ b/archive-kanban/tickets/SEC-04.md @@ -0,0 +1,51 @@ +# SEC-04 – wormstore: Release/Destroy ohne Legal-Hold-Prüfung, Reihenfolge-Problem + +**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 10 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco, ecoDMS und restic/Borg orientiert. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Security-Review (main-Branch, Fable 5.1) hat einen mittleren Befund (M2) bestätigt: `archive/internal/wormstore/wormstore.go:152-208` prüft bei Release/Destroy keinen Legal Hold. Zusätzlich erfolgt die physische Operation (`chattr -i`/`os.Remove`, Zeile 177/203) vor dem DB-Commit (Zeile 183/206) – bei einem Absturz zwischen beiden Schritten ist die Datei bereits physisch weg, während der DB-Zustand sie noch als vorhanden ausweist, was einen nicht mehr rekonstruierbaren Widerspruch zwischen Storage und Datenbank erzeugt. Weiterhin verwendet `:72-73` `filepath.Join(baseDir, key)` ohne Traversal-Check auf `key`; aktuell gibt es keinen produktiven Aufrufer mit nutzerkontrolliertem `key`, das Risiko ist aber latent und soll nicht erst bei Einführung eines solchen Aufrufers behoben werden müssen. + +**Angriffsszenario / Fehlerszenario:** Ein WORM-Objekt mit aktivem Legal Hold wird über den `wormstore`-Layer direkt released/destroyed, ohne dass dieser Layer den Hold prüft (Umgehung der Prüfung aus `deletionworkflow`, falls `wormstore` auf einem anderen Pfad aufgerufen wird). Bei einem Prozessabsturz zwischen physischer Löschung und DB-Commit entsteht ein WORM-Objekt, das laut Datenbank noch existiert, physisch aber bereits vernichtet ist – ein Verstoß gegen die Nachweispflicht der Revisionssicherheit. Ein künftiger Aufrufer mit nutzerkontrolliertem `key` könnte zusätzlich mittels Pfad-Traversal (`../../`) auf Dateien außerhalb von `baseDir` zugreifen. + +**Technische Grundlage:** Go, Dateisystemoperationen, Zwei-Phasen-Commit-Muster, Pfad-Validierung + +## Ausgangslage +`RET-04` WORM-Speicher-Garantie (Append-only) ist bereits fertiggestellt. Diese Kachel ändert ausschließlich die Reihenfolge und Absicherung bestehender Release/Destroy-Operationen in `wormstore`. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Release und Destroy in `wormstore.go` prüfen vor jeder Ausführung einen aktiven Legal Hold und verweigern die Operation bei Treffer +2. Die physische Löschung/Freigabe (`chattr -i`/`os.Remove`) erfolgt erst nach erfolgreichem DB-Commit, oder es wird ein Zwei-Phasen-Commit-Muster verwendet, das einen Absturz zwischen beiden Schritten konsistent auflöst (kein Zustand, in dem physisch bereits gelöscht, aber DB-Status noch "vorhanden" ist) +3. `filepath.Join(baseDir, key)` in `:72-73` validiert `key` gegen Pfad-Traversal (z. B. Ablehnung von `..`-Segmenten oder Pfaden, die außerhalb von `baseDir` aufgelöst werden) + +## 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. Angriff real nachgestellt: Release/Destroy eines Objekts mit aktivem Legal Hold direkt über `wormstore` aufgerufen – Ergebnis vor Fix: Operation wird durchgeführt; Ergebnis nach Fix: Operation wird verweigert +2. Simulierter Absturz zwischen physischer Operation und DB-Commit nachgestellt – Ergebnis nach Fix: kein inkonsistenter Zwischenzustand mehr erreichbar, oder Zustand ist beim nächsten Start automatisch erkennbar/korrigierbar +3. Traversal-Angriff real nachgestellt: `key` mit `../`-Segmenten übergeben – Ergebnis vor Fix: Zugriff außerhalb `baseDir` möglich; Ergebnis nach Fix: Anfrage wird abgelehnt +4. Regulärer Release/Destroy ohne Legal Hold und ohne Traversal-Versuch funktioniert 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-03` TOCTOU Legal Hold vs. Destroy im `deletionworkflow` (höhere Schicht, eigenständiger Befund) +- Einführung eines neuen Aufrufers mit nutzerkontrolliertem `key` (nicht Teil dieser Kachel, nur die Absicherung dagegen) + +## 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, einschließlich eines Negativtests, der den beschriebenen Angriff nachstellt und als blockiert nachweist. +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: wormstore-legal-hold-reihenfolge-traversal` +- Branch: `feature/sec-04-wormstore-legal-hold-reihenfolge-traversal` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/SEC-05.md b/archive-kanban/tickets/SEC-05.md new file mode 100644 index 00000000..e3e9f7fd --- /dev/null +++ b/archive-kanban/tickets/SEC-05.md @@ -0,0 +1,52 @@ +# SEC-05 – moduleadapter /register: fehlende Tenant-Bindung, optionale Authentifizierung + +**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 10 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco, ecoDMS und restic/Borg orientiert. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Security-Review (main-Branch, Fable 5.1) hat einen mittleren Befund (M3) bestätigt: In `archive/internal/moduleadapter/handler.go:83-95` und `moduleadapter.go:52-66` fehlt bei der Registrierung von Modul-Adaptern die Tenant-Bindung – Migration `0003:14` definiert `UNIQUE(module_name, object_type)` ohne Tenant-Spalte, sodass das erste registrierende Modul die `callback_url` tenant-übergreifend "gewinnt" und spätere Registrierungen anderer Mandanten für denselben `module_name`/`object_type` entweder fehlschlagen oder die bestehende Zuordnung überschreiben. Zusätzlich schaltet `cmd/moduleadapter-api/main.go:47` mit `ALLOW_UNAUTHENTICATED=true` die Authentifizierung für `/register` und `/legal-hold` komplett ab; es ist ungeklärt, ob/wo dieser Schalter im Produktivbetrieb tatsächlich gesetzt ist. + +**Angriffsszenario:** Mandant A registriert zuerst einen Adapter für `module_name="dms"`, `object_type="document"` mit eigener `callback_url`. Mandant B registriert denselben `module_name`/`object_type` – ohne Tenant-Spalte im UNIQUE-Constraint kollidiert die Registrierung mit der von Mandant A, wodurch entweder Mandant Bs Registrierung fehlschlägt oder (abhängig vom Upsert-Verhalten) Mandant As `callback_url` durch Mandant Bs überschrieben wird. Letzteres würde bedeuten, dass WORM-/Legal-Hold-Callbacks für Mandant As Objekte künftig an Mandant Bs Endpunkt gehen. Ist `ALLOW_UNAUTHENTICATED=true` in einer produktionsnahen Umgebung gesetzt, kann zudem jeder unauthentifizierte Aufrufer `/register` und `/legal-hold` ansprechen. + +**Technische Grundlage:** PostgreSQL, SQL-Migrationen (kein ORM), Go, bestehende Authentifizierungs-Middleware + +## Ausgangslage +`RET-05` Modul-Adapter-Schnittstelle (DMS/Mail registrieren Objekttypen) ist bereits fertiggestellt und wird hier um die Tenant-Bindung und verbindliche Authentifizierung ergänzt. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. Der UNIQUE-Constraint auf der Modul-Registrierungstabelle umfasst eine Tenant-Spalte (`UNIQUE(tenant, module_name, object_type)` oder äquivalent), sodass zwei Mandanten denselben `module_name`/`object_type` unabhängig voneinander registrieren können +2. Eine Migration überführt bestehende Registrierungen korrekt in das neue Schema, ist rückrollbar und läuft gegen eine Datenbank mit vorhandenen Testregistrierungen durch +3. `ALLOW_UNAUTHENTICATED` hat in keiner produktionsnahen Konfiguration (sofern im Deployment-Code auffindbar) einen Standardwert `true`; der Schalter ist klar als "nur für isolierte Testumgebungen" dokumentiert und per Default `false` +4. `/register` und `/legal-hold` verlangen bei `ALLOW_UNAUTHENTICATED=false` (bzw. ohne den Schalter) eine gültige Authentifizierung + +## 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. Angriff real nachgestellt: zwei Mandanten registrieren denselben `module_name`/`object_type` – Ergebnis vor Fix: Kollision/Überschreiben nachgewiesen; Ergebnis nach Fix: beide Registrierungen bestehen unabhängig nebeneinander +2. Migration vorwärts und rückwärts gegen Datenbank mit bestehenden Testregistrierungen getestet +3. Aufruf von `/register` ohne Authentifizierung bei `ALLOW_UNAUTHENTICATED=false` real nachgestellt – Ergebnis: Anfrage wird mit 401 abgelehnt +4. Bestehende, korrekt authentifizierte Registrierungsabläufe 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-01` Rolle muss aus verifizierter Identität kommen (eigenständiger RBAC-Befund, andere Komponente) +- Prüfung/Anpassung konkreter Produktions-Deployment-Konfigurationen außerhalb dieses Repos + +## 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, einschließlich eines Negativtests, der den beschriebenen Angriff nachstellt und als blockiert nachweist. +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: moduleadapter-tenant-bindung-pflicht-authentifizierung` +- Branch: `feature/sec-05-moduleadapter-tenant-bindung-pflicht-authentifizierung` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. diff --git a/archive-kanban/tickets/SEC-06.md b/archive-kanban/tickets/SEC-06.md new file mode 100644 index 00000000..8fa2ab9c --- /dev/null +++ b/archive-kanban/tickets/SEC-06.md @@ -0,0 +1,51 @@ +# SEC-06 – Append-only-Lücken bei mehreren Archive-Tabellen + +**Epic:** 🔒 Sicherheit | **Rolle:** Backend | **Komplexität:** Mittel | **Aufwand:** 2 Personentage | **Welle:** 10 + +--- + +## Rolle +Du bist erfahrene Entwicklerin im Bereich Backend und baust NEXARCH Archive (zentrales, modulübergreifendes Modul für Aufbewahrung, WORM, Compliance und Backup), das sich an Alfresco, ecoDMS und restic/Borg orientiert. +Serverseitige Logik, Datenzugriff und Schnittstelle. Keine Geschäftslogik in der Oberfläche. + +## Auftrag +Security-Review (main-Branch, Fable 5.1) hat einen mittleren Befund (M4) bestätigt: Mehrere Tabellen mit Append-only-Anspruch sind DB-seitig nicht dagegen abgesichert. `legal_holds` hat `ON DELETE CASCADE`, was der Append-only-Absicht direkt widerspricht (löscht man das referenzierte Objekt, verschwindet der Legal-Hold-Nachweis mit). `retention_class_assignments`, `dsgvo_decision_log`, `deletion_requests` und `worm_objects` haben trotz "append-only"-Anspruch kein DB-seitiges REVOKE/Trigger gegen UPDATE/DELETE – der Code selbst führt auf `worm_objects` UPDATE/DELETE aus, was zeigt, dass die Absicherung bislang rein konventionell (nicht technisch erzwungen) ist. `RET-11`/`AUD-07` haben für vergleichbare Tabellen bereits das etablierte Muster (REVOKE UPDATE/DELETE von der App-Rolle + Trigger mit RAISE WARNING) umgesetzt – dieses Muster fehlt hier. + +**Angriffsszenario:** Ein Angreifer mit Datenbankzugriff (z. B. über eine kompromittierte Anwendungsrolle oder eine SQL-Injection in einer anderen Komponente) kann ohne DB-seitige Sperre Einträge in `dsgvo_decision_log`, `deletion_requests` oder `worm_objects` nachträglich verändern oder löschen, um eine vorgenommene Löschentscheidung oder einen WORM-Nachweis zu vertuschen. Das Löschen eines referenzierten Objekts entfernt per `ON DELETE CASCADE` automatisch den zugehörigen `legal_holds`-Eintrag, wodurch ein zuvor bestehender Aufbewahrungssperren-Nachweis rückwirkend verschwindet. + +**Technische Grundlage:** PostgreSQL, SQL-Migrationen, bestehendes REVOKE/Trigger-Muster aus `RET-11`/`AUD-07` + +## Ausgangslage +`RET-11` und `AUD-07` haben das REVOKE/Trigger-Muster für vergleichbare Tabellen bereits etabliert und fertiggestellt. Diese Kachel wendet dasselbe Muster auf die restlichen betroffenen Tabellen an. + +## Akzeptanzkriterien +Die Kachel gilt erst als umgesetzt, wenn alle Punkte erfüllt sind: +1. `legal_holds` verwendet statt `ON DELETE CASCADE` entweder `ON DELETE RESTRICT` oder eine eigene Historisierung, sodass das Löschen eines referenzierten Objekts den Legal-Hold-Nachweis nicht mitentfernt +2. `retention_class_assignments`, `dsgvo_decision_log`, `deletion_requests` und `worm_objects` erhalten nach dem Muster aus `RET-11`/`AUD-07` ein REVOKE von UPDATE/DELETE für die Anwendungsrolle sowie einen Trigger, der versuchte UPDATE/DELETE-Zugriffe mit `RAISE WARNING` protokolliert und verweigert +3. Bestehender Code, der aktuell UPDATE/DELETE auf `worm_objects` ausführt, ist auf Insert-only-/Statuswechsel-per-neuem-Datensatz-Logik umgestellt, sodass er mit der neuen DB-Sperre kompatibel ist + +## 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. Angriff real nachgestellt: direkter UPDATE/DELETE-Versuch auf jede der vier Tabellen mit der Anwendungsrolle ausgeführt – Ergebnis vor Fix: Änderung gelingt; Ergebnis nach Fix: Zugriff wird verweigert und als Warnung protokolliert +2. Löschen eines Objekts mit aktivem Legal Hold real nachgestellt – Ergebnis vor Fix: `legal_holds`-Eintrag verschwindet per Kaskade; Ergebnis nach Fix: Löschung wird verweigert (RESTRICT) oder Hold bleibt historisiert bestehen +3. Migration vorwärts und rückwärts gegen Datenbank mit bestehenden Testdaten in allen vier Tabellen getestet +4. Umgestellter Anwendungscode für `worm_objects` mit regulärem Statuswechsel-Testfall erfolgreich durchlaufen + +## Nicht Bestandteil dieser Kachel +Diese Punkte gehören ausdrücklich in andere Kacheln. Bereite höchstens die Schnittstelle dafür vor: +- `SEC-03` TOCTOU Legal Hold vs. Destroy (eigenständiger Befund in der Anwendungslogik, nicht Teil dieser DB-seitigen Absicherung) +- `SEC-04` wormstore Release/Destroy (Dateisystem-Schicht, nicht Teil dieser Kachel) + +## 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, einschließlich eines Negativtests, der den beschriebenen Angriff nachstellt und als blockiert nachweist. +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: append-only-absicherung-archive-tabellen` +- Branch: `feature/sec-06-append-only-absicherung-archive-tabellen` +- Schrittweise committen, Branch pushen, dann anhalten. Kein Merge, kein Deploy. +- In der Beschreibung des Pull Request die durchgeführten Prüfungen mit Ergebnis auflisten. -- 2.47.3