From e2c3a0e8f81d005161dde733f7e4b08f581e3468 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Schw=C3=B6rer?= Date: Wed, 2 Sep 2026 16:21:31 +0200 Subject: [PATCH] TensorX-Matrix: erste vollstaendig besetzte Matrix, 918 Anforderungen Sechs Zellen - z-ai/glm-5.3-flash und qwen/qwen3.8-flash-next je solo, builtin und custom - alle mit dem kompletten Artefaktsatz von sieben Dateien. 47,1 Mio. Tokens in 6,4 Stunden, hochgerechnet rund $3,25. Das Matrixskript heisst jetzt _matrix.ps1 und nimmt -Provider und -Effort; die LM-Studio-Ladeparameter werden nur noch lokal uebergeben. Vor dem Start bestaetigte ein Smoke-Test den TensorX-Pfad unter den seither geaenderten Bedingungen (Denylist, Spiegel, Freigabemuster): Anmeldung, Modellkontrolle, wirksame Effort-Variante und Dateiuebernahme. Befund: Die Anforderungsanzahl haette in die Irre gefuehrt. Qwens custom-Lauf liegt mit 157 Anforderungen im Mittelfeld, ist aber qualitativ zusammengebrochen - 61 Prozent ohne jeden Beleg, 17 Prozent mit Primaerbeleg, 40 Prozent Hypothesen, gegenueber 0 Prozent ohne Beleg und 79 bis 98 Prozent Primaerbelegen in den uebrigen fuenf Laeufen. Er lieferte zugleich weniger als builtin bei 37 Prozent mehr Tokens. Der Moduseffekt ist modellabhaengig: Bei GLM steigt der Ertrag monoton von 126 ueber 139 auf 216 bei durchgaengig hoher Belegqualitaet, bei Qwen ist builtin das Optimum. Die Annahme, rollenspezialisierte Agenten seien generell ueberlegen, traegt damit nicht. Qwens custom-Lauf meldet exit_code 1 bei finish_reason stop und ohne Timeout, nachdem alle 24 Subagenten zurueckkamen und sieben Dateien entstanden. Er ist als gueltig mit Vorbehalt gefuehrt, die Ursache offen. Co-Authored-By: Claude Opus 5 (1M context) --- Versuche/AblaufProtokoll.md | 50 + .../Adapter.log | 5 + .../Ergebnisse/Analysebericht.md | 221 + .../Ergebnisse/Glossar.md | 95 + .../Ergebnisse/Hypothesen.md | 102 + .../Ergebnisse/StRS.md | 345 + .../Ergebnisse/SwRS.md | 2740 ++++ .../Ergebnisse/SyRS.md | 1033 ++ .../Ergebnisse/Traceability.md | 224 + .../OpenCode.log | 0 .../OpenCodeEvents.jsonl | 330 + .../Protokoll.md | 129 + .../RawResult.json | 1225 ++ .../Stderr.log | 5 + .../_meta/after.txt | 1 + .../_meta/anforderungen.json | 3907 ++++++ .../_meta/anforderungen.md | 67 + .../_meta/before.txt | 1 + .../_meta/combined_prompt.md | 175 + .../_meta/endzeit.txt | 1 + .../_meta/opencode-config.json | 234 + .../_meta/opencode-session.json | 9344 +++++++++++++ .../_meta/startzeit.txt | 1 + .../Adapter.log | 5 + .../Ergebnisse/Analysebericht.md | 160 + .../Ergebnisse/Glossar.md | 40 + .../Ergebnisse/Hypothesen.md | 20 + .../Ergebnisse/StRS.md | 351 + .../Ergebnisse/SwRS.md | 709 + .../Ergebnisse/SyRS.md | 631 + .../Ergebnisse/Traceability.md | 66 + .../OpenCode.log | 0 .../OpenCodeEvents.jsonl | 414 + .../Protokoll.md | 126 + .../RawResult.json | 1276 ++ .../Stderr.log | 5 + .../_meta/after.txt | 1 + .../_meta/anforderungen.json | 1597 +++ .../_meta/anforderungen.md | 64 + .../_meta/before.txt | 1 + .../_meta/combined_prompt.md | 174 + .../_meta/endzeit.txt | 1 + .../_meta/opencode-config.json | 230 + .../_meta/opencode-session.json | 11537 ++++++++++++++++ .../_meta/startzeit.txt | 1 + .../Adapter.log | 5 + .../Ergebnisse/Analysebericht.md | 335 + .../Ergebnisse/Glossar.md | 51 + .../Ergebnisse/Hypothesen.md | 45 + .../Ergebnisse/StRS.md | 489 + .../Ergebnisse/SwRS.md | 1673 +++ .../Ergebnisse/SyRS.md | 831 ++ .../Ergebnisse/Traceability.md | 135 + .../OpenCode.log | 0 .../OpenCodeEvents.jsonl | 164 + .../Protokoll.md | 126 + .../RawResult.json | 844 ++ .../Stderr.log | 5 + .../_meta/after.txt | 1 + .../_meta/anforderungen.json | 2843 ++++ .../_meta/anforderungen.md | 64 + .../_meta/before.txt | 1 + .../_meta/combined_prompt.md | 175 + .../_meta/endzeit.txt | 1 + .../_meta/opencode-config.json | 234 + .../_meta/opencode-session.json | 4760 +++++++ .../_meta/startzeit.txt | 1 + .../Adapter.log | 5 + .../Ergebnisse/Analysebericht.md | 315 + .../Ergebnisse/Glossar.md | 85 + .../Ergebnisse/Hypothesen.md | 59 + .../Ergebnisse/StRS.md | 320 + .../Ergebnisse/SwRS.md | 1031 ++ .../Ergebnisse/SyRS.md | 1050 ++ .../Ergebnisse/Traceability.md | 79 + .../OpenCode.log | 0 .../OpenCodeEvents.jsonl | 267 + .../Protokoll.md | 125 + .../RawResult.json | 1108 ++ .../Stderr.log | 5 + .../_meta/after.txt | 1 + .../_meta/anforderungen.json | 2512 ++++ .../_meta/anforderungen.md | 63 + .../_meta/before.txt | 1 + .../_meta/combined_prompt.md | 174 + .../_meta/endzeit.txt | 1 + .../_meta/opencode-config.json | 230 + .../_meta/opencode-session.json | 8310 +++++++++++ .../_meta/startzeit.txt | 1 + .../Adapter.log | 5 + .../Ergebnisse/Analysebericht.md | 285 + .../Ergebnisse/Glossar.md | 134 + .../Ergebnisse/Hypothesen.md | 206 + .../Ergebnisse/StRS.md | 698 + .../Ergebnisse/SwRS.md | 968 ++ .../Ergebnisse/SyRS.md | 1021 ++ .../Ergebnisse/Traceability.md | 78 + .../OpenCode.log | 0 .../OpenCodeEvents.jsonl | 353 + .../Protokoll.md | 130 + .../RawResult.json | 1130 ++ .../Stderr.log | 5 + .../_meta/after.txt | 1 + .../_meta/anforderungen.json | 2798 ++++ .../_meta/anforderungen.md | 68 + .../_meta/before.txt | 1 + .../_meta/combined_prompt.md | 218 + .../_meta/endzeit.txt | 1 + .../_meta/opencode-config.json | 648 + .../_meta/opencode-session.json | 9844 +++++++++++++ .../_meta/startzeit.txt | 1 + .../Adapter.log | 5 + .../Ergebnisse/Analysebericht.md | 360 + .../Ergebnisse/Glossar.md | 49 + .../Ergebnisse/Hypothesen.md | 12 + .../Ergebnisse/StRS.md | 591 + .../Ergebnisse/SwRS.md | 2491 ++++ .../Ergebnisse/SyRS.md | 744 + .../Ergebnisse/Traceability.md | 207 + .../OpenCode.log | 0 .../OpenCodeEvents.jsonl | 203 + .../Protokoll.md | 128 + .../RawResult.json | 1066 ++ .../Stderr.log | 5 + .../_meta/after.txt | 1 + .../_meta/anforderungen.json | 4312 ++++++ .../_meta/anforderungen.md | 66 + .../_meta/before.txt | 1 + .../_meta/combined_prompt.md | 218 + .../_meta/endzeit.txt | 1 + .../_meta/opencode-config.json | 648 + .../_meta/opencode-session.json | 6072 ++++++++ .../_meta/startzeit.txt | 1 + Versuche/_matrix.log | 14 + .../{_lmstudio_matrix.ps1 => _matrix.ps1} | 66 +- 135 files changed, 102006 insertions(+), 17 deletions(-) create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Adapter.log create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/Analysebericht.md create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/Glossar.md create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/Hypothesen.md create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/StRS.md create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/SwRS.md create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/SyRS.md create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/Traceability.md create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/OpenCode.log create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/OpenCodeEvents.jsonl create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Protokoll.md create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/RawResult.json create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Stderr.log create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/_meta/after.txt create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/_meta/anforderungen.json create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/_meta/anforderungen.md create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/_meta/before.txt create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/_meta/combined_prompt.md create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/_meta/endzeit.txt create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/_meta/opencode-config.json create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/_meta/opencode-session.json create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/_meta/startzeit.txt create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/solo/high/03_Lauf_2026-09-02_125154_v13.0.0-af37/Adapter.log create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/solo/high/03_Lauf_2026-09-02_125154_v13.0.0-af37/Ergebnisse/Analysebericht.md create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/solo/high/03_Lauf_2026-09-02_125154_v13.0.0-af37/Ergebnisse/Glossar.md create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/solo/high/03_Lauf_2026-09-02_125154_v13.0.0-af37/Ergebnisse/Hypothesen.md create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/solo/high/03_Lauf_2026-09-02_125154_v13.0.0-af37/Ergebnisse/StRS.md create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/solo/high/03_Lauf_2026-09-02_125154_v13.0.0-af37/Ergebnisse/SwRS.md create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/solo/high/03_Lauf_2026-09-02_125154_v13.0.0-af37/Ergebnisse/SyRS.md create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/solo/high/03_Lauf_2026-09-02_125154_v13.0.0-af37/Ergebnisse/Traceability.md create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/solo/high/03_Lauf_2026-09-02_125154_v13.0.0-af37/OpenCode.log create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/solo/high/03_Lauf_2026-09-02_125154_v13.0.0-af37/OpenCodeEvents.jsonl create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/solo/high/03_Lauf_2026-09-02_125154_v13.0.0-af37/Protokoll.md create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/solo/high/03_Lauf_2026-09-02_125154_v13.0.0-af37/RawResult.json create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/solo/high/03_Lauf_2026-09-02_125154_v13.0.0-af37/Stderr.log create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/solo/high/03_Lauf_2026-09-02_125154_v13.0.0-af37/_meta/after.txt create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/solo/high/03_Lauf_2026-09-02_125154_v13.0.0-af37/_meta/anforderungen.json create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/solo/high/03_Lauf_2026-09-02_125154_v13.0.0-af37/_meta/anforderungen.md create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/solo/high/03_Lauf_2026-09-02_125154_v13.0.0-af37/_meta/before.txt create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/solo/high/03_Lauf_2026-09-02_125154_v13.0.0-af37/_meta/combined_prompt.md create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/solo/high/03_Lauf_2026-09-02_125154_v13.0.0-af37/_meta/endzeit.txt create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/solo/high/03_Lauf_2026-09-02_125154_v13.0.0-af37/_meta/opencode-config.json create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/solo/high/03_Lauf_2026-09-02_125154_v13.0.0-af37/_meta/opencode-session.json create mode 100644 Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/solo/high/03_Lauf_2026-09-02_125154_v13.0.0-af37/_meta/startzeit.txt create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/builtin/high/03_Lauf_2026-09-02_095648_v13.0.0-77c1/Adapter.log create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/builtin/high/03_Lauf_2026-09-02_095648_v13.0.0-77c1/Ergebnisse/Analysebericht.md create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/builtin/high/03_Lauf_2026-09-02_095648_v13.0.0-77c1/Ergebnisse/Glossar.md create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/builtin/high/03_Lauf_2026-09-02_095648_v13.0.0-77c1/Ergebnisse/Hypothesen.md create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/builtin/high/03_Lauf_2026-09-02_095648_v13.0.0-77c1/Ergebnisse/StRS.md create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/builtin/high/03_Lauf_2026-09-02_095648_v13.0.0-77c1/Ergebnisse/SwRS.md create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/builtin/high/03_Lauf_2026-09-02_095648_v13.0.0-77c1/Ergebnisse/SyRS.md create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/builtin/high/03_Lauf_2026-09-02_095648_v13.0.0-77c1/Ergebnisse/Traceability.md create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/builtin/high/03_Lauf_2026-09-02_095648_v13.0.0-77c1/OpenCode.log create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/builtin/high/03_Lauf_2026-09-02_095648_v13.0.0-77c1/OpenCodeEvents.jsonl create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/builtin/high/03_Lauf_2026-09-02_095648_v13.0.0-77c1/Protokoll.md create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/builtin/high/03_Lauf_2026-09-02_095648_v13.0.0-77c1/RawResult.json create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/builtin/high/03_Lauf_2026-09-02_095648_v13.0.0-77c1/Stderr.log create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/builtin/high/03_Lauf_2026-09-02_095648_v13.0.0-77c1/_meta/after.txt create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/builtin/high/03_Lauf_2026-09-02_095648_v13.0.0-77c1/_meta/anforderungen.json create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/builtin/high/03_Lauf_2026-09-02_095648_v13.0.0-77c1/_meta/anforderungen.md create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/builtin/high/03_Lauf_2026-09-02_095648_v13.0.0-77c1/_meta/before.txt create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/builtin/high/03_Lauf_2026-09-02_095648_v13.0.0-77c1/_meta/combined_prompt.md create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/builtin/high/03_Lauf_2026-09-02_095648_v13.0.0-77c1/_meta/endzeit.txt create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/builtin/high/03_Lauf_2026-09-02_095648_v13.0.0-77c1/_meta/opencode-config.json create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/builtin/high/03_Lauf_2026-09-02_095648_v13.0.0-77c1/_meta/opencode-session.json create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/builtin/high/03_Lauf_2026-09-02_095648_v13.0.0-77c1/_meta/startzeit.txt create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/solo/high/03_Lauf_2026-09-02_093401_v13.0.0-19d9/Adapter.log create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/solo/high/03_Lauf_2026-09-02_093401_v13.0.0-19d9/Ergebnisse/Analysebericht.md create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/solo/high/03_Lauf_2026-09-02_093401_v13.0.0-19d9/Ergebnisse/Glossar.md create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/solo/high/03_Lauf_2026-09-02_093401_v13.0.0-19d9/Ergebnisse/Hypothesen.md create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/solo/high/03_Lauf_2026-09-02_093401_v13.0.0-19d9/Ergebnisse/StRS.md create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/solo/high/03_Lauf_2026-09-02_093401_v13.0.0-19d9/Ergebnisse/SwRS.md create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/solo/high/03_Lauf_2026-09-02_093401_v13.0.0-19d9/Ergebnisse/SyRS.md create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/solo/high/03_Lauf_2026-09-02_093401_v13.0.0-19d9/Ergebnisse/Traceability.md create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/solo/high/03_Lauf_2026-09-02_093401_v13.0.0-19d9/OpenCode.log create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/solo/high/03_Lauf_2026-09-02_093401_v13.0.0-19d9/OpenCodeEvents.jsonl create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/solo/high/03_Lauf_2026-09-02_093401_v13.0.0-19d9/Protokoll.md create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/solo/high/03_Lauf_2026-09-02_093401_v13.0.0-19d9/RawResult.json create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/solo/high/03_Lauf_2026-09-02_093401_v13.0.0-19d9/Stderr.log create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/solo/high/03_Lauf_2026-09-02_093401_v13.0.0-19d9/_meta/after.txt create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/solo/high/03_Lauf_2026-09-02_093401_v13.0.0-19d9/_meta/anforderungen.json create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/solo/high/03_Lauf_2026-09-02_093401_v13.0.0-19d9/_meta/anforderungen.md create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/solo/high/03_Lauf_2026-09-02_093401_v13.0.0-19d9/_meta/before.txt create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/solo/high/03_Lauf_2026-09-02_093401_v13.0.0-19d9/_meta/combined_prompt.md create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/solo/high/03_Lauf_2026-09-02_093401_v13.0.0-19d9/_meta/endzeit.txt create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/solo/high/03_Lauf_2026-09-02_093401_v13.0.0-19d9/_meta/opencode-config.json create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/solo/high/03_Lauf_2026-09-02_093401_v13.0.0-19d9/_meta/opencode-session.json create mode 100644 Versuche/Versuch_01/Iteration 16/z-ai/glm-5.3-flash/solo/high/03_Lauf_2026-09-02_093401_v13.0.0-19d9/_meta/startzeit.txt create mode 100644 Versuche/Versuch_02/Iteration 9/qwen/qwen3.8-flash-next/custom/high/02_Lauf_2026-09-02_140338_v13.0.0-b5bb/Adapter.log create mode 100644 Versuche/Versuch_02/Iteration 9/qwen/qwen3.8-flash-next/custom/high/02_Lauf_2026-09-02_140338_v13.0.0-b5bb/Ergebnisse/Analysebericht.md create mode 100644 Versuche/Versuch_02/Iteration 9/qwen/qwen3.8-flash-next/custom/high/02_Lauf_2026-09-02_140338_v13.0.0-b5bb/Ergebnisse/Glossar.md create mode 100644 Versuche/Versuch_02/Iteration 9/qwen/qwen3.8-flash-next/custom/high/02_Lauf_2026-09-02_140338_v13.0.0-b5bb/Ergebnisse/Hypothesen.md create mode 100644 Versuche/Versuch_02/Iteration 9/qwen/qwen3.8-flash-next/custom/high/02_Lauf_2026-09-02_140338_v13.0.0-b5bb/Ergebnisse/StRS.md create mode 100644 Versuche/Versuch_02/Iteration 9/qwen/qwen3.8-flash-next/custom/high/02_Lauf_2026-09-02_140338_v13.0.0-b5bb/Ergebnisse/SwRS.md create mode 100644 Versuche/Versuch_02/Iteration 9/qwen/qwen3.8-flash-next/custom/high/02_Lauf_2026-09-02_140338_v13.0.0-b5bb/Ergebnisse/SyRS.md create mode 100644 Versuche/Versuch_02/Iteration 9/qwen/qwen3.8-flash-next/custom/high/02_Lauf_2026-09-02_140338_v13.0.0-b5bb/Ergebnisse/Traceability.md create mode 100644 Versuche/Versuch_02/Iteration 9/qwen/qwen3.8-flash-next/custom/high/02_Lauf_2026-09-02_140338_v13.0.0-b5bb/OpenCode.log create mode 100644 Versuche/Versuch_02/Iteration 9/qwen/qwen3.8-flash-next/custom/high/02_Lauf_2026-09-02_140338_v13.0.0-b5bb/OpenCodeEvents.jsonl create mode 100644 Versuche/Versuch_02/Iteration 9/qwen/qwen3.8-flash-next/custom/high/02_Lauf_2026-09-02_140338_v13.0.0-b5bb/Protokoll.md create mode 100644 Versuche/Versuch_02/Iteration 9/qwen/qwen3.8-flash-next/custom/high/02_Lauf_2026-09-02_140338_v13.0.0-b5bb/RawResult.json create mode 100644 Versuche/Versuch_02/Iteration 9/qwen/qwen3.8-flash-next/custom/high/02_Lauf_2026-09-02_140338_v13.0.0-b5bb/Stderr.log create mode 100644 Versuche/Versuch_02/Iteration 9/qwen/qwen3.8-flash-next/custom/high/02_Lauf_2026-09-02_140338_v13.0.0-b5bb/_meta/after.txt create mode 100644 Versuche/Versuch_02/Iteration 9/qwen/qwen3.8-flash-next/custom/high/02_Lauf_2026-09-02_140338_v13.0.0-b5bb/_meta/anforderungen.json create mode 100644 Versuche/Versuch_02/Iteration 9/qwen/qwen3.8-flash-next/custom/high/02_Lauf_2026-09-02_140338_v13.0.0-b5bb/_meta/anforderungen.md create mode 100644 Versuche/Versuch_02/Iteration 9/qwen/qwen3.8-flash-next/custom/high/02_Lauf_2026-09-02_140338_v13.0.0-b5bb/_meta/before.txt create mode 100644 Versuche/Versuch_02/Iteration 9/qwen/qwen3.8-flash-next/custom/high/02_Lauf_2026-09-02_140338_v13.0.0-b5bb/_meta/combined_prompt.md create mode 100644 Versuche/Versuch_02/Iteration 9/qwen/qwen3.8-flash-next/custom/high/02_Lauf_2026-09-02_140338_v13.0.0-b5bb/_meta/endzeit.txt create mode 100644 Versuche/Versuch_02/Iteration 9/qwen/qwen3.8-flash-next/custom/high/02_Lauf_2026-09-02_140338_v13.0.0-b5bb/_meta/opencode-config.json create mode 100644 Versuche/Versuch_02/Iteration 9/qwen/qwen3.8-flash-next/custom/high/02_Lauf_2026-09-02_140338_v13.0.0-b5bb/_meta/opencode-session.json create mode 100644 Versuche/Versuch_02/Iteration 9/qwen/qwen3.8-flash-next/custom/high/02_Lauf_2026-09-02_140338_v13.0.0-b5bb/_meta/startzeit.txt create mode 100644 Versuche/Versuch_02/Iteration 9/z-ai/glm-5.3-flash/custom/high/02_Lauf_2026-09-02_104242_v13.0.0-b971/Adapter.log create mode 100644 Versuche/Versuch_02/Iteration 9/z-ai/glm-5.3-flash/custom/high/02_Lauf_2026-09-02_104242_v13.0.0-b971/Ergebnisse/Analysebericht.md create mode 100644 Versuche/Versuch_02/Iteration 9/z-ai/glm-5.3-flash/custom/high/02_Lauf_2026-09-02_104242_v13.0.0-b971/Ergebnisse/Glossar.md create mode 100644 Versuche/Versuch_02/Iteration 9/z-ai/glm-5.3-flash/custom/high/02_Lauf_2026-09-02_104242_v13.0.0-b971/Ergebnisse/Hypothesen.md create mode 100644 Versuche/Versuch_02/Iteration 9/z-ai/glm-5.3-flash/custom/high/02_Lauf_2026-09-02_104242_v13.0.0-b971/Ergebnisse/StRS.md create mode 100644 Versuche/Versuch_02/Iteration 9/z-ai/glm-5.3-flash/custom/high/02_Lauf_2026-09-02_104242_v13.0.0-b971/Ergebnisse/SwRS.md create mode 100644 Versuche/Versuch_02/Iteration 9/z-ai/glm-5.3-flash/custom/high/02_Lauf_2026-09-02_104242_v13.0.0-b971/Ergebnisse/SyRS.md create mode 100644 Versuche/Versuch_02/Iteration 9/z-ai/glm-5.3-flash/custom/high/02_Lauf_2026-09-02_104242_v13.0.0-b971/Ergebnisse/Traceability.md create mode 100644 Versuche/Versuch_02/Iteration 9/z-ai/glm-5.3-flash/custom/high/02_Lauf_2026-09-02_104242_v13.0.0-b971/OpenCode.log create mode 100644 Versuche/Versuch_02/Iteration 9/z-ai/glm-5.3-flash/custom/high/02_Lauf_2026-09-02_104242_v13.0.0-b971/OpenCodeEvents.jsonl create mode 100644 Versuche/Versuch_02/Iteration 9/z-ai/glm-5.3-flash/custom/high/02_Lauf_2026-09-02_104242_v13.0.0-b971/Protokoll.md create mode 100644 Versuche/Versuch_02/Iteration 9/z-ai/glm-5.3-flash/custom/high/02_Lauf_2026-09-02_104242_v13.0.0-b971/RawResult.json create mode 100644 Versuche/Versuch_02/Iteration 9/z-ai/glm-5.3-flash/custom/high/02_Lauf_2026-09-02_104242_v13.0.0-b971/Stderr.log create mode 100644 Versuche/Versuch_02/Iteration 9/z-ai/glm-5.3-flash/custom/high/02_Lauf_2026-09-02_104242_v13.0.0-b971/_meta/after.txt create mode 100644 Versuche/Versuch_02/Iteration 9/z-ai/glm-5.3-flash/custom/high/02_Lauf_2026-09-02_104242_v13.0.0-b971/_meta/anforderungen.json create mode 100644 Versuche/Versuch_02/Iteration 9/z-ai/glm-5.3-flash/custom/high/02_Lauf_2026-09-02_104242_v13.0.0-b971/_meta/anforderungen.md create mode 100644 Versuche/Versuch_02/Iteration 9/z-ai/glm-5.3-flash/custom/high/02_Lauf_2026-09-02_104242_v13.0.0-b971/_meta/before.txt create mode 100644 Versuche/Versuch_02/Iteration 9/z-ai/glm-5.3-flash/custom/high/02_Lauf_2026-09-02_104242_v13.0.0-b971/_meta/combined_prompt.md create mode 100644 Versuche/Versuch_02/Iteration 9/z-ai/glm-5.3-flash/custom/high/02_Lauf_2026-09-02_104242_v13.0.0-b971/_meta/endzeit.txt create mode 100644 Versuche/Versuch_02/Iteration 9/z-ai/glm-5.3-flash/custom/high/02_Lauf_2026-09-02_104242_v13.0.0-b971/_meta/opencode-config.json create mode 100644 Versuche/Versuch_02/Iteration 9/z-ai/glm-5.3-flash/custom/high/02_Lauf_2026-09-02_104242_v13.0.0-b971/_meta/opencode-session.json create mode 100644 Versuche/Versuch_02/Iteration 9/z-ai/glm-5.3-flash/custom/high/02_Lauf_2026-09-02_104242_v13.0.0-b971/_meta/startzeit.txt create mode 100644 Versuche/_matrix.log rename Versuche/{_lmstudio_matrix.ps1 => _matrix.ps1} (74%) diff --git a/Versuche/AblaufProtokoll.md b/Versuche/AblaufProtokoll.md index dc80dec5..86645521 100644 --- a/Versuche/AblaufProtokoll.md +++ b/Versuche/AblaufProtokoll.md @@ -1403,6 +1403,56 @@ adapterbedingte Fehlmessungen gekennzeichnet. --- +### TensorX-Matrix mit den beiden guenstigsten Modellen (02.09.2026) + +Erste vollstaendig besetzte Matrix der Reihe: zwei Modelle x drei Agentenmodi, alle sechs Zellen +mit dem kompletten Artefaktsatz von sieben Dateien. Bedingung: Skill 13.1.0, Adapter 2.5.2, +Denylist, Spiegel-Arbeitsverzeichnis, Effort `high`, Standard-Ausgabeblock. + +Vor dem Start wurde der TensorX-Pfad mit einem Smoke-Test geprueft - seit dem letzten Lauf hatten +sich Denylist, Arbeitsverzeichnis und Freigabemuster geaendert, ohne dass er seither einmal lief. +Der Test bestaetigte Anmeldung, Modellkontrolle, wirksame Effort-Variante (`effort_applied: true`, +anders als lokal) und den Spiegel auch im Remotebetrieb. + +| Modell | Modus | Min | Turns | Tools | Sub | Anforderungen | Primaerbeleg | ohne Beleg | Hypothesen | Tokens | +|---|---|---:|---:|---:|---:|---:|---:|---:|---:|---:| +| `glm-5.3-flash` | solo | 22,7 | 71 | 111 | 0 | 126 | 97 % | 0 % | 3 % | 6.336.907 | +| `glm-5.3-flash` | builtin | 45,8 | 32 | 76 | 7 | 139 | 95 % | 0 % | 3 % | 4.316.088 | +| `glm-5.3-flash` | custom | 129,1 | 45 | 81 | 30 | **216** | 91 % | 0 % | 1 % | 11.467.996 | +| `qwen3.8-flash-next` | solo | 19,1 | 93 | 135 | 0 | 81 | 79 % | 0 % | 17 % | 6.432.032 | +| `qwen3.8-flash-next` | builtin | 52,5 | 71 | 116 | 13 | **199** | 98 % | 0 % | 11 % | 7.830.882 | +| `qwen3.8-flash-next` | custom | 112,5 | 85 | 99 | 24 | 157 | **17 %** | **61 %** | **40 %** | 10.715.498 | + +**918 Anforderungen, 47,1 Mio. Tokens, 6,4 Stunden.** Hochgerechnet aus der Preisliste vom +02.09.2026 ($0,20 Input / $0,50 Output je 1 Mio.) rund **$3,25** - TensorX liefert keine +Kostenangabe, `cost` bleibt `0`. + +**Die Anzahl allein haette in die Irre gefuehrt.** Qwens custom-Lauf steht mit 157 Anforderungen +im Mittelfeld, ist aber qualitativ zusammengebrochen: **61 % ohne jeden Beleg**, nur 17 % mit +Primaerbeleg, 40 % als Hypothese gekennzeichnet. Alle uebrigen fuenf Laeufe kommen auf 0 % ohne +Beleg und 79 bis 98 % Primaerbelege. Dieselbe Zelle lieferte zugleich weniger als `builtin` +(157 gegen 199) bei 37 % mehr Tokens. Der Modus `custom` war fuer dieses Modell also teurer, +ertragsaermer **und** schlechter belegt - ein Befund, der ohne die Belegpruefung unsichtbar +geblieben waere und Befund 6.1 (Anforderungsanzahl ist kein Qualitaetsmass) erneut bestaetigt. + +**Der Moduseffekt ist modellabhaengig.** Bei GLM steigt der Ertrag monoton (126 -> 139 -> 216) +bei durchgaengig hoher Belegqualitaet. Bei Qwen ist `builtin` das Optimum, `custom` faellt ab. +Die Annahme, rollenspezialisierte Agenten seien generell ueberlegen, traegt damit nicht; sie +scheint an das Modell gebunden zu sein. Mit einem Lauf je Zelle ist das ein Hinweis, keine +belastbare Aussage - die Streuung ist in dieser Reihe durchweg die dominierende Groesse. + +**Ebenenverteilung.** Alle Laeufe legen den Schwerpunkt auf SwRS; am ausgewogensten ist Qwens +custom-Lauf (41/60/56), am schiefsten Qwens builtin-Lauf (16/49/134). Die StRS-Ebene bleibt +durchgaengig duenn - dasselbe Muster wie in den Claude-Laeufen. + +**Ein Lauf mit Vorbehalt.** Qwens custom-Lauf meldet `exit_code: 1` bei `finish_reason: stop` und +ohne Timeout: OpenCode beendete sich mit Fehlercode, nachdem alle 24 Subagenten zurueckgekehrt +waren und sieben Dateien geschrieben hatte. Nach Pflichtpruefung ist er formal eine Fehlmessung, +inhaltlich vollstaendig. Er wird als *gueltig mit Vorbehalt* gefuehrt; die Ursache des Exitcodes +ist offen. + +--- + ## 6. Befunde ### 6.1 Die Anforderungsanzahl ist kein Qualitätsmaß diff --git a/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Adapter.log b/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Adapter.log new file mode 100644 index 00000000..b7b1dc55 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Adapter.log @@ -0,0 +1,5 @@ +[2026-09-02T11:11:03.761390+00:00] Spiegel angelegt: C:\DEV\MasterArbeit\Versuche\Versuch_01\Iteration 16\qwen\qwen3.8-flash-next\builtin\high\03_Lauf_2026-09-02_131102_v13.0.0-6a1a\_meta\spiegel (13 Junctions, 17 Dateien, Ergebnisse -> C:\DEV\MasterArbeit\Versuche\Versuch_01\Iteration 16\qwen\qwen3.8-flash-next\builtin\high\03_Lauf_2026-09-02_131102_v13.0.0-6a1a\Ergebnisse) +[2026-09-02T11:11:03.862020+00:00] Start OpenCode C:\Users\ChristophSchwoerer\AppData\Roaming\npm\node_modules\opencode-ai\bin\opencode.exe; Provider=tensorx; Modell=tensorx/qwen/qwen3.8-flash-next; Modus=builtin; Effort=high (uebergeben=True); Stall-Timeout=0s +[2026-09-02T12:03:36.484593+00:00] 0 Ergebnisdatei(en) aus dem Spiegel uebernommen +[2026-09-02T12:03:38.004876+00:00] OpenCode export: Exporting session: ses_f9e2f37dbffePXP0P4ACRLx8cN +[2026-09-02T12:03:38.084502+00:00] Ende: Exitcode=0; Status=success; Turns=71; Tokens=7830882; Dateien=7; RawResult=C:\DEV\MasterArbeit\Versuche\Versuch_01\Iteration 16\qwen\qwen3.8-flash-next\builtin\high\03_Lauf_2026-09-02_131102_v13.0.0-6a1a\RawResult.json diff --git a/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/Analysebericht.md b/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/Analysebericht.md new file mode 100644 index 00000000..9df35c14 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/Analysebericht.md @@ -0,0 +1,221 @@ +# Analysebericht + +Reverse Requirements Engineering der c-entron ERP-Suite (Baseline, prompt-only). Stand: nach Konsistenzbereinigung. +Stufen: **tief** = mehrere Anforderungen inkl. verifizierter Durchsetzungsstellen; **mittel** = eigene Anforderung(en) mit PRIMÄR-Beleg; **flach** = Modulinventar + Stichprobe (API-Sicht), keine/eine Requirement; **nicht analysiert** = mit Begründung. + +## 1. Ergebnisübersicht + +| Kennzahl | Wert | +|---|---| +| Anforderungen gesamt | 199 (StRS 16, SyRS 49, SwRS 134) | +| Belegzeilen | 323 (davon 256 PRIMÄR, Rest SEKUNDÄR/KONTEXT) | +| Anforderungen ohne Beleg | 0 | +| Anforderungen ohne Übernahmewürdigkeit | 0 | +| Hypothesen | 23 (5 SyRS, 18 SwRS, 0 StRS) → Hypothesen.md | +| Konsolidierungskandidaten | 165 | +| Verdikte ≠ „übernehmen" | 31 (Workaround 8, Sonderfall 7, veraltet 6, unklar 4, Mischformen 6) | +| Analysierte Module (Inventar) | 117 von 117 (=100 %); nicht-analysiert-Anteil 0 % (Ziel ≤10 % eingehalten) | + +## 2. Modulinventar und Abdeckung + +### 2.1 Backend-Fachmodule `src\backend\Centron.BL\` (88 Module, ohne bin/obj/Properties/Resources) + +| Modul | .cs | Stufe | Anf. | Kernsatz | +|---|---|---|---|---| +| Administration | 959 | tief | 42 | Rechte, Logins/2FA, Lizenzen, Settings, Config-DB, Customizing, Diagnostik, Themes, KI | +| Sales | 248 | tief | 24 | Belegfluss, Rechnungen, Mahnen, Zahlungen, Helpdesk/SLA, Shop-Preisstellung | +| WebServices | 464 | mittel | 4 | *WebServiceBL-Schicht als REST-Backend (strukturell analysiert, Details je Fachbereich offen) | +| Warehousing | 40 | mittel | 2 | Kommissionierung/Barcode mit Rechteprüfung, EK-Fortschreibung | +| Accounts | 29 | mittel | 4 | Account-Stamm, Nummernvergabe, Filterzwang für Web-Accounts | +| EDI | 27 | mittel | 1 | EDIDispatcher: Bestellungen hinaus, Antworten herein | +| DataExchange | 23 | mittel | 5 | Buchhaltungsexport (DATEV/SAP), E-Rechnung, Exportkonfiguration | +| Mail | 20 | mittel | 1 | austauschbare Mail-Protokollclients, verschlüsselte Secrets | +| Statistics | 16 | mittel | 1 | Cache-Statistiken + benutzereigene Definitionen | +| Services | 11 | mittel | 1 | CachedTableBL-Selbstreparatur/Sofortaktualisierung | +| EmployeeArea | 9 | mittel | 5 | Employee↔AppUser-Mapping, Verfügbarkeit, Dispatcher, Abteilungen, Einstellungen | +| Finances | 9 | mittel | 1 | PaymentsBL-Rückbuchung über zentralen Buchungspunkt | +| CustomerArea | 7 | mittel | 1 | Branchenzuweisungen atomar ersetzen | +| Purchasing | 4 | mittel | 2 | Bestellvorschlagsliste, bereichsübergreifender Lieferantenexport | +| TaskManager | 4 | mittel | 2 | wiederkehrende Aufgaben mit Lizenz-/Aktionsvalidierung | +| MyDay | 7 | flach | 1 | Tagesplanungs-Batches mit gemeinsamer BatchId | +| Production | 2 | flach | 2 | Fertigungsaufträge filterbar; Lizenzpflicht | +| NexusTicketViews | 1 | flach | 2 | Ticket-Ansichten mit Besitzer-/Namensregeln | +| CountryArea | 2 | mittel | 3 | Inlandsland, Defaultland, EZB-Kursimport | +| IndexSearch | 7 | flach | 1 | deutsche Volltextsuche (Stemming, ALL-Semantik) | +| ReportEngine | 26 | mittel | 1 | PDF-Strategien mit PDF/A3-Fallback; Berichte/Archivierung | +| RiverDivo | 4 | flach | 1 | Gegenstelle externes Ticketsystem (River Suite) | +| WebLinks | 4 | flach | 1 | Weblink→CRM-Aktivität | +| Modules | 3 | flach | 1 | Modulstamm-Autoanlage, Favoriten | +| CheckListArea | 3 | flach | 1 | Checklisten-Pflicht-Caption, transaktional | +| Mailings | 2 | flach | 1 | Mailing-Gesamtaggregat laden | +| Notifications | 2 | flach | 1 | Empfängerlisten-Sync + Meldungs-Cleanup | +| NexusNotifications | 2 | flach | 1 | rohe SQL-Verwaltung je Empfänger | +| MyCentron | 4 | flach | 1 | benutzergetrennte Dashboardcontainer | +| TextModuleArea | 2 | flach | 1 | Textbaustein-Resolver benutzer>kunde>global | +| TradePool | 2 | flach | 1 | Handelspool-XML-Import | +| Urls | 2 | flach | 1 | durchsuchbare Objekt-URLs | +| ToDoArea | 2 | flach | 1 | zentraler ToDo-Typkatalog (>30 Objektarten) | +| SelfCare | 2 | flach | 1 | Formular→Helpdesk-Ticket (Kette teiloffen) | +| Integrations | 2 | flach | 1 | ElectronicSales-Gruppen/Rollen-Spiegel (Hypothese) | +| CPra | 2 | flach | 1 | c-pra-Token/Webhooks | +| WebSuite | 5 | flach | 1 | Web-Einstellungen nach Login-Art getrennt | +| PasswordManagementArea | 6 | flach | 1 | Alt-Passwortverwaltung (Hypothese: Nutzung offen) | +| Security | 1 | flach | 1 | PDF-Signatur mit Zertifikatskonfiguration | +| TwoFactorAuthenticator | 1 | flach | 1 | personengebundener 2FA-Schlüssel (Erzwingerstelle Hypothese) | +| PasswordManager | 1 | flach | 1 | Export nur mit Recht/Lizenz/Masterkey | +| DocumentationArea | 1 | flach | 1 | interne Doku nur mit Leserecht | +| Tags | 1 | flach | 1 | Tag-Reaktivierung beim Verschlagworten | +| Tapi | 1 | flach | 1 | CTI-Rufnummern-Suchkaskade | +| Outlook | 1 | flach | 1 | Kundensuche nach Gerätenummer (Modulminimal) | +| SocialMedia | 1 | flach | 1 | Kommentare/Likes via DB-Prozeduren (Hypothese) | +| VideoPortal | 1 | flach | 1 | Videozuweisung rechtsgeprüft + ToDo-Kopplung | +| DocuBoard | 3 | flach | 1 | Partner-Aggregat-Speicherung | +| AppointmentRequests | 1 | flach | 1 | Terminanfrage-Antwort gegen Exchange | +| Calendar | 1 | flach | 1 | Kalender-/Outlook-Sync-Einstellungen | +| Chats | 1 | flach | 1 | Chat-Guards (250 Zeichen, Autor, Soft-Delete) | +| MassUpdate | 1 | flach | 1 | Massenänderungs-Vorlagen (Rechte offen) | +| Processes | 1 | flach | 1 | Prozessmodell-Validierung/Atomarität | +| ExpectedEvents | 1 | flach | 1 | Überwachungsdefinitionen mit Löschkaskade | +| Devices | 1 | flach | 1 | Geräte-Soft-Delete mit Protokoll | +| Logistics | 1 | flach | 1 | Umlagerungsprotokoll validiert | +| Buying | 1 | flach | 1 | Distributor-Autoanlage bei Import | +| ProductMatrix | 1 | flach | 1 | Kunden-Produktmatrix mit Historie | +| Projects | 1 | flach | 1 | nur Lese-API (Hypothese: auslaufend) | +| TicketProjects | 1 | flach | 1 | Nummernkreis + Soft-Delete-Aufgaben | +| Time | 1 | flach | 1 | Zeiterfassungs-Settings (Zweck offen) | +| Transactions | 1 | flach | 1 | Transaktionen je Benutzer (Zweck offen) | +| VoucherManagement | 1 | flach | 1 | Gutschein-Barcodes per NamedQuery (Hypothese) | +| ExternalHelpdesk | 1 | flach | 1 | Config-CRUD je Kunde/Kundenort | +| ExternalToolsBL | 1 | flach | 1 | externe Tools mit Variablenersetzung | +| ItPlanner | 1 | flach | 1 | virtuelle Checklistenkategorien-Sync | +| ObjectExternalReferences | 1 | flach | 1 | typisierte Fremdsystem-Referenzen | +| Telemetry | 1 | flach | 1 | Telemetrie-Buckets mit Upload-Markierung | +| WebVersion | 1 | flach | 1 | Versionsauskunft | +| Reporting | 1 | flach | 1 | Legacy-Report-BLOB-Verwaltung | +| Gateway | 1 | flach | 1 | Custom-Gateway openTRANS (Hypothese) | +| Customizations | 1 | flach | 1 | Custom-Tabellen-Platzhalter | +| MailScanner | 1 | flach | 1 | VMA-Profile recht+verschlüsselt | +| SystemArea | 1 | flach | 1 | Systemzähler-Einzelinstanz | +| ArtificialIntelligence | 25 | mittel | 1 | KI-Chat-Historie; Provider-Familie (OpenAI/Gemini/Mistral/Claude) | +| Accounting | 1 | flach | 0 | BankAccount-CRUD inkl. Belegrückgriff (gelesen, keine eigene Requirement) | +| BusinessPartner | 2 | flach | 0 | Lieferanten-Suche/Anlagen-Buchungen (gelesen; Datenmodell in StRS-005) | +| Core | 2 | flach | 0 | CryptoUtils, Variablen-Ersetzung (gelesen) | +| Exceptions | 1 | flach | 0 | TicketExpiredException (gelesen) | +| GUI | 6 | flach | 0 | UserGrid/ImportOrder/UiProfile (APIs gelesen) | +| Helpers | 6 | flach | 0 | Graph/PDF/Word/Image-/String-Helfer (APIs gelesen) | +| Mobile | 1 | flach | 0 | MobileEmployee-Lesen inkl. Bild (gelesen) | +| Start | 1 | flach | 0 | Mapping-Start/ConnectionString (gelesen) | +| Storage | 2 | flach | 0 | StorageBL komplett auskommentiert („obsolete"), nur statischer InventoryArticlePool | +| Tools | 1 | flach | 0 | ToolBL nur ChangeTextFormat (gelesen) | +| ChangeTracking | 1 | flach | 0 | ImportHistoryBL; Kernlistener liegt unter Centron.DAO | +| CentronNexus | 1 | flach | 0 | Nexus-Settings Get/Update (gelesen) | +| CentronIcons | 2 | flach | 0 | Icon-/Ressourcenbestand ohne Fachlogik | + +### 2.2 Persistenz und Verträge + +| Modul | Stufe | Anf. | Kernsatz | +|---|---|---|---| +| Centron.DAO (Mappings, NamedQueries, Repositories, ChangeTracking, UserTypes) | tief | 10 | ORM-Konventionen, Query-Pool, Audit-/Historie-Erzeugung | +| Centron.Entities (1179 Dateien) | mittel | 4 | I3D-/Legacy-Abbildung, ObjectType-Nummern, Audit-Basisklasse | +| Centron.Interfaces | mittel | 2 | Contract-First-Schicht (Details nur oberflächlich) | +| Centron.Common | flach | 1 | Querschnittsbibliothek Logging/Netzwerk/Codierung | +| src\shared\Centron.Core (TotpAuth) | flach | 1 | TOTP-Bibliothek | +| SSMS_DB_SCHEMA.sql | mittel | 5 | RechKopf/RechPos, Zahkond, cvw_InvoiceDunnings als Datenbasis | + +### 2.3 Webservice (5 Projekte) + +| Modul | Stufe | Anf. | Kernsatz | +|---|---|---|---| +| Centron.Host (Host-Regie, Auth-Schemas, TicketHandler) | tief | 6 | globales RequireAuthorization, HttpSys/Kestrel, Dienstbetrieb | +| Centron.Controllers (Authorization-Filter, API-Versionierung, GlobalExceptionFilter) | tief | 4 | 401/403-Filter, Namespace-Versionierung, 500-Pfad | +| Centron.WebServices.Core (CentronWebService-Client) | flach | 1 | RESTC-Kanal, Kompression, Proxy | +| Centron.Host.WindowsService | flach | 1 | Fehlerkapselung OnStart/OnStop | +| c-entron.misc.ConnectionManager | flach | 1 | Diagnose-Werkzeug | + +### 2.4 Nexus (6 Bereiche) + +| Modul | Stufe | Anf. | Kernsatz | +|---|---|---|---| +| CentronNexus.Host (Program.cs) | tief | 3 | Cookie+OIDC-Registrierung, iframe/Cookie-Middleware | +| WebCart (Kundenportal) | tief | 6 | Port-/Loginzwang, Sortiment, Preis, Prüfstufe, Ticketseiten | +| ServiceBoard | mittel | 3 | Login-/Lizenz-/Portschutz, Kanban, TicketCache | +| Shared (Auth, TicketCache, NotificationHub, SignalR) | tief | 6 | Open-Redirect-Schutz, AuthController, Push-Zustellung | +| Office (PdfController/FilePreview) | flach | 1 | Cache-PDF-Auslieferung | +| DocumentSigning + WebOffer | mittel | 3 | Signatur-/Akzeptanzstrecke, tokenierte Angebotsseite | + +### 2.5 Desktop (1 Modul) und APIs (9 Adapter) + +| Modul | Stufe | Anf. | Kernsatz | +|---|---|---|---| +| Centron.WPF.UI (Shell, Login, Module, Finances-Masken) | tief | 6 | Single-Instance, Login-Gate, Layout/Pflichtfelder/Feldvalidierung | +| Centron.Api.Gls | flach | 2 | Sendungsupload mit Vorabvalidierung | +| Centron.Api.Shipcloud | flach | 1 | Sendungsanlage/Carrier-Abruf | +| Centron.Api.EbInterface | flach | 1 | eb:interface 4.3 (AT) | +| Centron.APIs.CopDataAccess | flach | 1 | SOAP-Session-Produktdaten | +| Centron.APIs.EgisDataAccess | flach | 2 | EGIS-Artikelsuche | +| Centron.APIs.FinAPI | flach | 1 | PSD2-Bankdaten | +| Centron.APIs.IcecatDataAccess | flach | 1 | Produktinhalte je EAN | +| Centron.APIs.ITscopeDataAccess | flach | 2 | Produkte/Angebote/Deals | +| Centron.Api.docuFORM | flach | 1 | Gerätezähler OAuth2-PKCE | + +### 2.6 Dokumentation/Modelle + +| Artefakt | Stufe | Anf. | Kernsatz | +|---|---|---|---| +| README.md | flach | 2 | WebCart-Zieldefinition | +| CentronRights.md | flach | 2 | Semantik einschränkender Rechte | + +### 2.7 Abdeckungsblatt (Stufen je Komponente) + +| Stufe | Module | Anteil | +|---|---|---| +| tief | 8 (Administration, Sales, DAO, Centron.Host, Controllers, WebCart, Shared, WPF-UI) | 6,8 % | +| mittel | 24 | 20,5 % | +| flach | 85 | 72,6 % | +| nicht analysiert | 0 | 0 % | + +Damit ist jede Inventarzeile mindestens flach erfasst; tiefe Durchdringung liegt planmäßig bei Sicherheit, Abrechnung, Portal und Plattform. + +## 3. Risikorelevante Anforderungen (Sicherheit, Abrechnung, Berechtigungen) + +Prüfregel: jede riskante Anforderung hat PRIMÄR-Beleg der Durchsetzungsstelle **oder** ist als HYPOTHESE markiert. Ergebnis: 32/32-Sicherheitsanforderungen erfüllt (30 mit PRIMÄR, 2 als HYPOTHESE markiert). + +### 3.1 Zugriff & Authentifizierung (PRIMÄR-belegt) +StRS-004 (AppRightsBL, AppUserGroupBL), SyRS-001 (UserRightAuthorizationFilter), SyRS-002 (TwoFactorAuthBL/RadiusClient/EmailValidator), SyRS-003 (CentronHostedHandler), SyRS-004 (DataSecurityBL), SyRS-005 (Authenticator/LicenseManager/TicketBL), SyRS-006 (TicketAuthenticationHandler + RequireAuthorization), SyRS-007 (Nexus Program.cs/AuthController), StRS-006/SyRS-016/SyRS-018 (ReceiptCartBL-Guards), SwRS-001 (AppRightsBL fail-closed), SwRS-003 (BasicAuthenticator), SwRS-018 (OrderCommissionBL), SwRS-024 (ProductionBL), SwRS-044 (ServiceBoard _Imports), SwRS-051 (AuthController Redirect), SwRS-053/054 (TicketAuthenticationHandler), SwRS-066/070 (docuFORM PKCE, MailScanner), SwRS-077 (VideoPortalAssignmentBL), SwRS-107 (DocumentationBL), SwRS-127 (HelpdeskBL.CheckUserRigths), SwRS-129 (FrontWindow.Login), SwRS-040 (ReceiptCartBL Rechte-/Prüfstufenguard, nachgetragen), SwRS-008 (PasswordManagerBL), SwRS-009 (DataSecurityBL Anonymisierung). + +### 3.2 Sicherheit mit Hypothesenstatus (offene Erzwingerstelle) +SwRS-004 (2FA-PIN: Erzwingerstelle im Login-Ablauf offen), SwRS-005 (Alt-Passwortnutzung offen), SwRS-006 (Rechtsprüfung bei Signatur-Settings offen), SwRS-007 (Datenfilter „nur eigene Tickets" auf BL-Seite offen), SwRS-055 (TOTP-Prüfstelle offen), SyRS-019/020/021 (Token-Lebenszyklus, Servervalidierung, Cache-Id-Zugriff). + +### 3.3 Abrechnung/Berechtigung (PRIMÄR-belegt) +StRS-003/StRS-011/StRS-016; SyRS-010 (ReceiptBL.UpdateReceiptNumber), SyRS-011 (HandleIsAlreadyExported/CancelInvoice), SyRS-012 (DunningRunBL transaktional), SyRS-013 (UpdateReceiptIsPaid mit ConcurrencyGuid), SyRS-014 (InvoiceSpecificLogic), SyRS-015/017 (ReceiptCartBL), SyRS-041 (Skonto), SwRS-010..014 (Storno/Preise), SwRS-019 (EK-Fortschreibung), SwRS-102 (PDF/A3), SwRS-108 (Textbausteine), SwRS-123 (Gutscheine, HYPOTHESE), SwRS-131 (Pflichtfelder). + +## 4. Konsistenzprüfung (Ergebnis nach Bereinigung) + +| Prüfpunkt | Ergebnis | +|---|---| +| Doppelte IDs | 0 (199 eindeutige IDs: StRS-001..016, SyRS-001..049, SwRS-001..134, lückenlose Sequenzen) | +| Anforderungen ohne Belege | 0 | +| Anforderungen ohne Übernahmewürdigkeit | 0 | +| Verwaiste Trace-Links | 0 (vor Bereinigung: 0 toter Verweis, aber 29 semantisch falsche Eltern→Kind-Referenzen; alle korrigiert) | +| Kind→Elter-Rückwärtsverfolgung | vollständig (100 %) | +| Elter→Kind-Vorwärtsverfolgung | selektiv geführt; vollständige Rekonstruktion über Kind→Elter (in Traceability.md begründet) | +| Deckungsgleiches ohne Konsolidierungsmarkierung | 0 aufgefundene Duplikatpaare bleiben unmarkiert; u.a. markiert: NumberGroupBL↔MandatoryBL (SwRS-099), AppSettings-Zwillinge (SyRS-029/SwRS-096), Abteilungs-Parallelimplementierung (SwRS-032), Alt-/Neu-Reports (SwRS-103), Portal-Rechtefamilie (SyRS-016..018) | +| Hypothesen-Abgleich | 23 Inline-Markierungen = 23 Einträge Hypothesen.md | +| Sicherheits-/Abrechnungsregeln | 32/32 mit PRIMÄR oder HYPOTHESE (siehe 3.) | +| Konsolidierungszähler StRS↔SyRS↔SwRS | Geschwisterlinks SyRS-010↔044, SyRS-039↔011 als Querverweise kenntlich gemacht | + +## 5. Dünne Belegstellen (Nachsteuerung nötig) + +1. Logik außerhalb des Quellcode-Bestands: DB-Prozeduren „SocialMedia.*" (SwRS-075), NamedQuery-SQL (SwRS-123), gespeicherte Sichten. +2. Erzwingerstellen nicht ablesbar: 2FA-PIN-Aufrufpfad (SwRS-004/055), PDF-Signatur-Settings (SwRS-006), WebCart-Ticketfilter (SwRS-007), Token-Erzeugung WebOffer (SyRS-019), Backend-Signaturvalidierung (SyRS-020), Cache-Id-Autorisierung (SyRS-021). +3. Zweck/Nutzung unklar: Projects, Transactions, Time/TimingSettings, VoucherManagement, ElectronicSales-Sync (SwRS-119/122/121/123/134), Alt-Passwortkeywords (SwRS-005). +4. Nebenläufigkeit/Risiken dokumentiert, aber nicht bewertet: Mahnlauf „Max+1" (SyRS-012), Auto-Sync bei Abfrage (SwRS-118), best-effort ChangeLog (SwRS-093). + +## 6. Selbstbewertung (absolut) + +- Erfasst: 199 Anforderungen; 16 StRS decken 100 % der SyRS-Eltern; jede SyRS hat 1–2 StRS-Eltern; 84 % der SwRS (113/134) nennen eine SyRS als direkten Elter, der Rest referenziert direkt die StRS (begründet: Ein-Modul-Funktionalitäten ohne Systemverhalten eigener Art). +- Belegt: 323 Belege, davon 256 PRIMÄR (Durchsetzungsstelle), 199/199 Anforderungen mindestens ein Beleg. +- Hypothesen: 23 (11,6 %), alle mit Prüffrage in Hypothesen.md; keine Requirement ohne Status. +- Verworfen/abgestuft statt „übernehmen": 31 Verdikte (Workaround 8, Sonderfall 7, veraltet 6, unklar 4, Mischungen 6). +- Modulinventar: 117 Zeilen, alle mit Kennsatz; Stufen: tief 8, mittel 24, flach 85, nicht analysiert 0. +- Bekannte Grenzen des Laufs: WebServices-Schicht (464 Klassen) nur strukturell; Entities/DAO nur stichprobenartig; ReportEngine, Calendar, Statistics, Warehousing nur anzapfend; DB-Prozeduren/NamedQuery-SQL nicht im Bestand; UI (WPF/Nexus-Seiten) nur an Belegstellen gelesen; Performanz-/Verfügbarkeits-NFVs außerhalb des Quellcodes nicht messbar (deshalb 0 Benchmark-Anforderungen). diff --git a/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/Glossar.md b/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/Glossar.md new file mode 100644 index 00000000..775fbf89 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/Glossar.md @@ -0,0 +1,95 @@ +# Glossar + +Fach- und Systembegriffe der c-entron ERP-Suite, wie aus den Artefakten abgeleitet. Links in eckigen Klammern zeigen auf prägende Anforderungen. + +## Identität, Rechte, Lizenz + +| Begriff | Bedeutung | +|---|---| +| I3D | Zentraler ganzzahliger Primärschlüssel aller Datenbankobjekte (allgegenwärtige Konvention `Id(a => a.I3D)`). [SyRS-034] | +| Employee | Personalstammdatensatz (Mitarbeiter); eigenständige Identität neben dem Zugang. [StRS-007] | +| AppUser | Interner Systemzugang (Login, Rechtegruppen, 2FA); per Mapping an einen Employee gebunden. [SwRS-029] | +| Web-Account | Portalzugang eines Endkunden; dritte Identitätsart mit eigener Rechtequelle WebRights. [StRS-006] | +| Recht / Rechtegruppe | Deklarierte Berechtigung, gruppenweise über Sichusr/Sichmemb an AppUser; Prüfung zentral über AppRightsBL.HasUserRight (Fail-closed). [SwRS-001] | +| Einschränkendendes Recht (restricting right) | Recht, das andere Rechte entzieht; in der Admin-Gruppe nur eingeschränkt zuweisbar. [StRS-004] | +| WebRights | Portalrechte (z. B. "Warenkorb bestellen", "Tickets abschließen"), serverseitig erzwungen. [SyRS-018] | +| Lizenz / CentronInternal | Modulare Lizenzpflicht; interne Funktionen nur mit CentronInternal-Lizenz. [SyRS-003] | +| Sitzungsticket | Zeitlich begrenztes Authentifizierungsticket je Anwendung (30/5/1440 Minuten). [SyRS-005] | +| Access-Token | Personengebundener API-Nachweis (Bearer/access_token), mit Client-Kontext validiert. [SwRS-002, SwRS-054] | +| 2FA / TOTP | Zweitfaktor per RADIUS, E-Mail-Link (Login) oder TOTP-Bibliothek (Schlüssel). [SyRS-002, SwRS-004, SwRS-055] | +| Masterkey | AES-Master-Passwort der Konfigurations-DB zum Entschlüsseln von Secrets. [SyRS-030] | + +## Organisation und Mandantenmodell + +| Begriff | Bedeutung | +|---|---| +| Mandant | Rechtlich-organisatorische Oberinstanz mit eigenem Default-Land und Nummernkreisen. [StRS-009, StRS-016] | +| Filiale (Branch) | Unterhalb des Mandanten mit genau einem Default-Lager plus Sekundärlagern. [StRS-010] | +| Inlandsland | Über den Default-Mandanten deterministisch abgeleitetes Steuer-/Preisland. [SwRS-042] | +| Account / Kunde / Lieferant | Neuer, maßgeblicher Adressstamm (Account*, AccountCustomer, AccountSupplier) als Migrationsziel der Altstämme Customer/Address/Supplier. [StRS-005] | + +## Beleg- und Zahlungswesen + +| Begriff | Bedeutung | +|---|---| +| Beleg / Belegart | Urkundentypisiertes Fachobjekt mit Kopf/Positionen (Tabelle RechKopf/RechPos), nummernkreis- und pflichtgeführt. [StRS-003, StRS-016] | +| Belegfluss / Herkunft | Verknüpfung Ursprungs→Folgebeleg über RechPos.UrsprungI3D/UrsprungArt. [SwRS-010] | +| Zahkond / Zahlungsbedingung | Zentral gepflegte Kondition mit Zahlungsziel und bis zu drei Skontostaffeln. [StRS-011] | +| Skonto | Skonto1..3 (Prozent/Tage) je Zahlungsbedingung, mit Textbaustein-Vorschau gegen Testrechnung. [SwRS-012, SwRS-034] | +| Mahnstufe | Eskalationsstufe None→1→2→3 im transaktionalen Mahnlauf über fällige aktive Rechnungen. [SyRS-012] | +| Opos | Offene Posten; Auswertung auf derselben Belegbasis wie der Mahnlauf. [StRS-003] | +| IsReceiptExported | Kennzeichnung "an Buchhaltung übergeben"; steuert Versionszwang und Stornoverbot. [SyRS-011] | +| Sonderpreis / Sondervereinbarung | Kundenindividuelle Artikelvereinbarung; begrenzt das Shop-Sortiment und die Nettopreisstellung. [SyRS-017, SyRS-015] | +| Preishierarchie | Preisfindung Vertrag > Sonderpreis > Staffelpreis, zweistufig gerundet. [SwRS-013, SwRS-014] | + +## Helpdesk und Organisation + +| Begriff | Bedeutung | +|---|---| +| Ticket (Helpdesk) | Servicevorgang mit Statusmaschine, SLA-Priorität, Historie und Abschluss-Checkliste. [StRS-013, SyRS-043, SwRS-127] | +| SLA-Priorität | Aus dem Servicevertrag erzwungene Ticketpriorität inkl. abgeleitetem Fälligkeitsdatum. [StRS-012] | +| Abschluss-Checkliste | Checkliste mit CanClose-Punkten; offen ⇒ Abschluss blockiert. [SwRS-127, SwRS-114] | +| ToDo / Wiedervorlage | Bereichsübergreifende Aufgabenliste mit über 30 registrierten Objektarten. [StRS-014] | +| ObjectKind / ObjectI3D / ObjectType | Typisierte Objektreferenz mit zentraler, unveränderlicher Typnummernliste. [SwRS-112] | + +## Portal, Kanäle und Integrationen + +| Begriff | Bedeutung | +|---|---| +| WebCart / Kundenportal | Endkunden-Selfservice (Shop, Warenkorb, Tickets, Dokumente) auf eigenem Port, nur Web-Account-Login. [SyRS-016] | +| Prüfstufe | Vier-Augen-Freigabe im Warenkorb (bereit zur Prüfung → geprüft). [SwRS-040] | +| ServiceBoard | Mitarbeiter-Browserarbeitsplatz im Nexus mit Login-, Lizenz- und Portschutz. [SwRS-044] | +| WebOffer | Loginfreie, token-gesteuerte Angebotsansicht. [SyRS-019] | +| SharedDocument / Signierstrecke | Token-basierte Dokumentenfreigabe mit Zeichnungs-/Typ-/Upload-Signatur (SEPA: IBAN-Pflicht). [SyRS-020] | +| RESTC | Standardisierter komprimierter REST-Kanal des Zentralklienten. [SyRS-025] | +| openTRANS | XML-Austauschformat für EDI-Bestellungen/Antworten; Custom-Gateway für Sonderfälle. [SyRS-045, SwRS-133] | +| ZUGFeRD / XRechnung / eb:interface | Normkonforme E-Rechnungsformate (DE/AT). [SyRS-040, SwRS-058] | +| Handelspool / EGIS / ITscope / Icecat / Cop | Distributor-/Poolquellen für Fremdarticlelnhalte und -preise. [SyRS-046] | +| c-pra | Externer Freigabe-/Workflowdienst (Nexoware Smartflow) mit Token-Login und Webhooks. [SwRS-115] | +| Riverbird / River Suite | Externes Ticketsystem mit Helpdesk-Gegenstelle und DB-/WebService-Trennregel. [SyRS-048, SwRS-098] | +| docuFORM | Gerätezähler-Fernübermittlung per OAuth2-PKCE. [SwRS-066] | + +## Technik und Plattform + +| Begriff | Bedeutung | +|---|---| +| WebServiceBL | Service-spezifische BL-Schicht der REST-Dienste (464 Klassen). [SyRS-028] | +| NamedQuery / NamedQueryPool | Zentral gepflegte SQL-/HQL-Abfragen statt SQL im Code. [SyRS-035] | +| DBUpdate / ScriptEngine | Versionsgesteuerte, idempotente Datenbankmigration mit Protokoll. [SyRS-023] | +| ChangeTracking / ChangeLog | Attributsgesteuerte Feldänderungs-Historie im Persistenzlayer (Update-only, best-effort). [SyRS-033, SwRS-093] | +| CreatedBy/CreatedDate/CreatedVersion | Auditfelder der DBEntity-Basisklasse, Repository-erzwungen. [SwRS-110] | +| Soft-Delete | Löschung durch Deaktivierung (IsActive/Deleted) statt Zeilenentfernung. [SwRS-023, SwRS-120] | +| Nummernkreis (NumberGroup) | Fortschreibender Zähler je Mandant/Filiale/Belegart mit Intervall und Delegation. [SyRS-044, SwRS-099] | +| HostedService / ExecuteServices | Hintergrunddienste, zentral per Konfigurationsflag schaltbar. [SyRS-022, SwRS-084] | +| TicketCache (Nexus) | Prozessweiter Singleton-Cache mit HostedService-Synchronisation. [SyRS-037] | +| AppSetting / ApplicationSetting | Zwei Settings-Generationen mit fehlertolerantem On-Demand-Default. [SyRS-029, SwRS-096] | +| DSGVO-Löschung / Anonymisierung | Rechtegebundene Nullung personenbezogener Ansprechpartnerfelder mit Löschprotokoll. [SyRS-004, SwRS-009] | + +## Arbeitsbegriffe dieser Spezifikation + +| Begriff | Bedeutung | +|---|---| +| PRIMÄR / SEKUNDÄR / KONTEXT | Belegklassen: Durchsetzungsstelle im Quelltext / Struktur- oder Modellbeleg / dokumentarischer Kontext. | +| HYPOTHESE | Status: fachliche Regel plausibel, aber Durchsetzung/Zweck nicht vollständig artefaktbelegt; offen in Hypothesen.md. | +| Übernahmewürdigkeit | Verdikt für das Migrationsziel: übernehmen / Workaround / Sonderfall / veraltet / unklar. | +| Konsolidierung | Markierung von Anforderungen, die inhaltlich zusammenzuführen sind (Duplikate/Parallelimplementierungen). | diff --git a/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/Hypothesen.md b/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/Hypothesen.md new file mode 100644 index 00000000..119ad461 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/Hypothesen.md @@ -0,0 +1,102 @@ +# Hypothesen-Liste + +Enthält exakt die Anforderungen mit `Status: HYPOTHESE` aus StRS.md, SyRS.md und SwRS.md (Abgleich: 0 StRS, 5 SyRS, 18 SwRS = 23). Zu jeder Hypothese: Grund der Markierung und offene Frage zur Bestätigung. + +## SyRS + +### SyRS-019 – Token-basierte Angebotsansicht ohne Login +- Offen: Token-Erzeugung, Ablauf und Rate-Limiting sind nicht nachgewiesen; der Token-Erzeugungscode wurde nicht gefunden. +- Prüfen: Erzeugungsstelle des Receipt-Access-Tokens incl. Gültigkeitsdauer und Wiederverwendungsschutz. + +### SyRS-020 – Signatur- und Akzeptanzstrecke für freigegebene Dokumente +- Offen: serverseitige Validierung außerhalb der UI (CanAccept) nicht nachgewiesen. +- Prüfen: Confirm/Decline-Endpunkte im Backend auf unabhängige Signatur-/IBAN-Prüfung. + +### SyRS-021 – PDF-Auslieferung über gemeinsamen Office-Cache-Endpunkt +- Offen: Zugriffskontrolle auf Cache-Ids nicht sichtbar. +- Prüfen: `getcachedfile/{id}/{filename}` mit fremder/erratener Cache-Id (Authorisierung, Ratenbegrenzung). + +### SyRS-025 – Standardisierter komprimierter REST-Kanal „RESTC" +- Offen: „unbegrenztes Timeout" nur durch Kommentar belegt. +- Prüfen: tatsächliche Timeout-/CancellationToken-Implementierung des CentronWebService-Clients. + +### SyRS-039 – Buchhaltungsexport in austauschbare Zielsystemformate +- Offen: Detailregeln je Zielformat (DATEV, SAP, ...) nicht analysiert; nur Struktur und Default-Regel belegt. +- Prüfen: Format-Builder je Zielsystem inkl. Kontenfindung und Stornologik. + +## SwRS + +### SwRS-004 – Prüfung des personengebundenen Zwei-Faktor-Schlüssels +- Offen: aufrufende Erzwingerstelle im Login-Ablauf nicht nachgewiesen. +- Prüfen: alle Login-Endpunkte/Masken daraufhin, ob `ValidateAuthenticationPin` zwingend aufgerufen wird. + +### SwRS-005 – Alt-Passwortverwaltung (Keywords) – Migrationsbedarf +- Offen: keine Belege für aktive Nutzung (UI-/Aktivierungsnachweis fehlt). +- Prüfen: Referenzsuche nach Konsumenten; Entsorgung entscheiden. + +### SwRS-006 – Elektronische PDF-Signatur mit geschützter Zertifikatskonfiguration +- Offen: Rechtsprüfung beim Pflegen der Signatur-Einstellungen nicht im Detail verifiziert. +- Prüfen: Save-Pfad von `PdfSigningBL` auf Rights-Guard. + +### SwRS-007 – Ticketansichten im Kundenportal nach Web-Rechten differenzieren +- Offen: eigentliche Datenfilterung „nur eigene Tickets" nicht im Detail nachgewiesen. +- Prüfen: BL-Seite der Ticketlisten im WebCart auf WebAccount-/Vertriebsgebietsfilter. + +### SwRS-035 – Preis- und Rabatttransparenz im Shop +- Offen: Priorisierung von Sondervereinbarungen innerhalb der Preisfindung nicht vollständig nachverfolgt. +- Prüfen: `ReceiptPriceHelper`-Kette bei gleichzeitiger Sondervereinbarung + Staffelpreis. + +### SwRS-036 – SelfCare-Formular erzeugt Helpdesk-Ticket +- Offen: Trigger→Ticket-Ausführungskette nicht vollständig verfolgt. +- Prüfen: ActionHandler-Kette vom Formular-Save bis zur Helpdesk-Anlage. + +### SwRS-046 – Fertigungsübersicht mit Arbeitsplatz- und Mitarbeiterauswahl +- Offen: fachliche Vervollständigung unklar. +- Prüfen: Rückfrage an Fachbereich Produktion; Seiten-Rohtext lesen. + +### SwRS-054 – Client-Kontext (IP, API-Methode) in der Access-Token-Validierung +- Offen: konkrete IP-/Methoden-Bindungsregel in `AccessTokenBL.ValidateToken` nicht eingesehen. +- Prüfen: ValidateToken-Quelltext inkl. Edge Cases (Proxy-IP, Methodswechsel). + +### SwRS-055 – TOTP-Zwei-Faktor-Bibliothek im Plattformkern +- Offen: erzwungene Prüfstelle im Login-Pfad nicht gezeigt. +- Prüfen: Konsumenten von `Totp.cs` im Anmelde-/Einstellungen-Pfad. + +### SwRS-056 – Schnittstellenmodul als Contract-First-Schicht +- Offen: Einzelinterface-Inhalte nur oberflächlich geprüft. +- Prüfen: Stichprobe der Interface-Definitionen gegen Implementierungen. + +### SwRS-057 – Gemeinsame Querschnittsbibliothek (Logging, Settings, Netzwerk, Codierung) +- Offen: Detailverhalten der Klassen nicht gelesen. +- Prüfen: AESCryptoLogic-Schlüsselherkunft und Logging-Rotation. + +### SwRS-075 – Interne Social-Media-Kommentare/Likes über gespeicherte Prozeduren +- Offen: Kernlogik liegt in DB-Prozeduren, deren Inhalt nicht im Artefaktbestand liegt. +- Prüfen: Prozeduren „SocialMedia.*" aus SSMS-Export oder Server beschaffen. + +### SwRS-119 – Projektliste mit Erstellungsdatumfilter (rumpfhaft) +- Offen: Save/Delete nirgends belegt; Modul möglicherweise auslaufend. +- Prüfen: Referenzsuche nach `ProjectBL`-Konsumenten. + +### SwRS-121 – Zeiterfassungs-Stammeinstellungen pflegen +- Offen: fachlicher Zweck der Settings nicht ableitbar (keine Konsumenten belegt). +- Prüfen: Konsumenten von `TimingSetting` identifizieren (Timer/CTime). + +### SwRS-122 – Benutzerbezogene Transaktionen mit Kategorie-Details +- Offen: Verwendungszweck nicht aus Artefakten belegt. +- Prüfen: UI-/Webservice-Konsumenten der TransactionBL. + +### SwRS-123 – Aktive Gutschein-Barcodes per NamedQuery +- Offen: SQL im NamedQuery-Pool; Zustandssemantik nicht verifizierbar. +- Prüfen: NamedQuery `VoucherManagementGetVoucherArticles` + Flags gegen Testdaten. + +### SwRS-133 – Custom-Gateway-BL für kundenindividuelle openTRANS-Integrationen +- Offen: Methodenumfang nicht gelesen; REST-Aufrufverbindung nur vermutet. +- Prüfen: `CustomGatewayBL`-Methoden und `CentronRestService.CustomGateway.cs` durchgehen. + +### SwRS-134 – Externe ElectronicSales-Gruppen/Rollen lokal spiegeln +- Offen: eigentlicher Sync-Abruf liegt außerhalb des Moduls; End-to-End-Verhalten unbelegt. +- Prüfen: Sync-Initiator (Hintergrunddienst/Webservice) identifizieren. + +## Begründung der Hypothesen-Quote +Die 23 Hypothesen betreffen überwiegend (a) Logik außerhalb des Quellcode-Bestands (DB-Prozeduren, NamedQuery-SQL, externe Systeme), (b) nicht gelesene Konsumenten-/Erzwingerstellen und (c) möglicherweise auslaufende Module. Alle Sicherheits- und Abrechnungsanforderungen mit zweifelhaftem Durchsetzungsbeleg sind markiert; keine StRS-Hypothese, weil jede StRS mehrere unabhängige PRIMÄR-Belege hat. diff --git a/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/StRS.md b/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/StRS.md new file mode 100644 index 00000000..12fca92b --- /dev/null +++ b/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/StRS.md @@ -0,0 +1,345 @@ +# StRS - Stakeholder Requirements Specification + +Quelle: c-entron ERP-Suite (Reverse Requirements Engineering, ISO/IEC/IEEE 29148:2018). +Alle Pfade relativ zum Arbeitsverzeichnis. Belegklassen: PRIMÄR / SEKUNDÄR / KONTEXT. + +--- + +ID: StRS-001 +Titel: Ein gemeinsames ERP-System für alle Fachprozesse +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: ERP-Anwender (Vertrieb, Einkauf, Lager, Service, Finanzen) +Vorbedingung: Client ist gestartet, Benutzer ist angemeldet +Fakt: WPF-Shell `FrontWindow` exportiert `OpenModule/CloseModule/DockModule`; unter `src\centron\Centron.WPF.UI\Modules\` existieren 29 Fachmodule (Finances, Helpdesk, Warehousing, Production, ...), jedes mit Modul-Controller; das Webfront CentronNexus ergänzt Browser-Zugriffe. +Aussage: Das System soll alle ERP-Fachprozesse (Angebot bis Rechnung, Einkauf bis Lager, Helpdesk bis Finanzen) in einer gemeinsamen, modular erweiterbaren Anwendung bereitstellen. +Ergebnis: Alle Fachbereiche sind über eine Shell mit öffn-/schließbaren Modulen erreichbar; kein Fachbereich läuft als Insellösung. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\FrontWindow.xaml.cs, OpenModule/CloseModule/DockModule - Begründung: zentraler Modulvertrag der Gesamtleistung + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\ (29 Modulordner), src\centron\Centron.WPF.UI.Extension\Modules\ICentronAppModule.cs - Begründung: Modularchitektur als Systemprinzip +Prüfidee: Jedes der 29 Fachmodule lässt sich ohne Neustart öffnen, andocken und schließen. +Tracelinks: SyRS-024, SyRS-025, SyRS-026, SyRS-027, SyRS-028 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - modulare Gesamt-ERP-Idee ist das tragende Produktversprechen +Status: belegt + +--- + +ID: StRS-002 +Titel: Endkunden wickeln Bestellung und Service selbstständig im Kundenportal ab +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Endkunde eines c-entron-Kunden (Web-Account), Kundenadministrator +Vorbedingung: Mandant hat WebCart-Lizenz, Kunde besitzt Sonderpreise und Web-Accounts +Fakt: README: "The webcart is a feature primarily intended for the customers of our customers"; Portal unter `/customerportal` mit Tickets, Formularen, Dokumenten, Belegen/Verträgen sowie Shop/Warenkorb; Bestell-/Prüfrechte werden serverseitig in `ReceiptCartBL` erzwungen. +Aussage: Das System soll Endkunden den kompletten Selbstbedienungspfad (Sonderpreis-Sortiment → Warenkorb → Bestellung, Tickets/Formulare/Dokumente) ohne ERP-Benutzer öffnen, wobei der Kundenadministrator Rechte und Benutzer selbst verwaltet. +Ergebnis: Bestellungen und Servicevorgänge erreichen das ERP ohne manuelle Erfassung durch den c-entron-Kunden. +Belege: + - [SEKUNDÄR] README.md, Zeilen 31-36 - Begründung: dokumentiertes Ziel des WebCart + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptCartBL.cs, Rechte-/Portprüfungen (Zeilen 133, 859-864) - Begründung: der Selbstbedienungspfad ist serverseitig erzwungen implementiert + - [SEKUNDÄR] src\nexus\CentronNexus\WebCart\CustomperPortalHomePage.razor, Route `/customerportal` - Begründung: Portalbündel als eigene Startseite +Prüfidee: Durchlauf ohne ERP-Benutzer: Shop-Suche → Warenkorb → Bestellung mit Bestellrecht; Formular erzeugt Helpdesk-Ticket. +Tracelinks: SyRS-016, SyRS-017, SyRS-018, SyRS-019, SyRS-020, SyRS-021 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zentrales Wachstums-/Entlastungsziel +Status: belegt + +--- + +ID: StRS-003 +Titel: Lückenloser, nachvollziehbarer Belegfluss vom Ursprungsbeleg bis zum Mahnlauf +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertrieb, Debitorenbuchhaltung +Vorbedingung: Auftrag oder Lieferschein mit Positionen existiert +Fakt: `ReceiptProgressionBL.GetRelatedItemsForObject` ermittelt Ursprungs-/Folgebelege über `RechPos.UrsprungI3D/UrsprungArt`; `InvoiceSpecificLogic` deklariert `CanBeForwardedFrom/Into`; Mahnwesen/Opos greifen auf dieselbe RechKopf-Basis zu (View `cvw_InvoiceDunnings`). +Aussage: Das System soll jeden Beleg über seine Positionsherkunft lückenlos mit Ursprungs- und Folgebelegen verknüpfen und diese Kette für Fakturierung, Mahnwesen und Debitorensteuerung nutzbar machen. +Ergebnis: Zu jeder Rechnung sind Vorbelege und Weiterverarbeitungen eindeutig bestimmbar; nur überfällige aktive Rechnungen erreichen Mahn-/Opos-Läufe. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptProgressionBL.cs, GetRelatedItemsForObject/CreateOriginReceiptsSql - Begründung: Belegkette technisch über alle Belegarten erzwungen + - [SEKUNDÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\InvoiceSpecificLogic.cs, CanBeForwardedFrom/Into (Zeilen 279-280) - Begründung: definierte Übergänge des Belegflusses + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, View [dbo].[cvw_InvoiceDunnings] - Begründung: Auswertungen setzen auf derselben Belegbasis auf +Prüfidee: Auftrag → Rechnung; beide erscheinen im Belegfluss; bezahlte Rechnung taucht im Mahnlauf nicht auf. +Tracelinks: SyRS-012, SyRS-013, SyRS-014, SyRS-039, SyRS-040, SyRS-041 +Konsolidierung: Kandidat: Sammelthema "Belegfluss Auftragsabwicklung" mit Lieferschein/RMA-Verzweigungen (ReceiptProgressionBL) +Übernahmewürdigkeit: übernehmen - tragendes Prinzip der Auftragsabwicklung +Status: belegt + +--- + +ID: StRS-004 +Titel: Wer darf was - selbstverwaltetes Rechte- und Lizenzmodell mit Selbstschutz +Ebene: StRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Benutzer mit Recht UserRightsManagement; Administratoren +Vorbedingung: Anmeldung an der c-entron-Verwaltung +Fakt: `AppRightsBL.SaveRightGroup` prüft `HasUserRight(UserRightsManagement)` und bei `MANAGE_RIGHTS_ONLY_OWN_BRANCH` die Filialzugehörigkeit; `DeleteRightGroup` verbietet das Löschen der Gruppe I3D==6/"Administratoren"; in der Admin-Gruppe sind nur freigegebene einschränkende Rechte zuweisbar. +Aussage: Das System soll das Anlegen, Ändern und Löschen von Rechtegruppen nur berechtigten Benutzern gestatten, bei Filialbindung auf die eigene Filiale beschränken und die Administratorengruppe gegen Löschung/Entrechtung schützen. +Ergebnis: Nicht berechtigte/filialfremde Anfragen werden abgewiesen; Admin-Gruppe bleibt erhalten. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Rights\AppRightsBL.cs, SaveRightGroup/DeleteRightGroup - Begründung: exakte Durchsetzungsstellen inkl. Bedingungen + - [PRIMÄR] src\backend\Centron.BL\Administration\Rights\AppUserGroupBL.cs, IsAdministratorGroupI3D (`groupI3D == 6`) - Begründung: harter Admin-Gruppenschutz + - [SEKUNDÄR] CentronRights.md, Abschnitt "This is a restricting right" - Begründung: Fachsemantik einschränkender Rechte +Prüfidee: Benutzer ohne UserRightsManagement legt Gruppe an → Fehler; Admin-Gruppe löschen → Fehler; filialfremde Gruppe bei MANAGE_RIGHTS_ONLY_OWN_BRANCH → Fehler. +Tracelinks: SyRS-001, SyRS-002, SyRS-003, SyRS-004, SyRS-005, SyRS-006, SyRS-007, SyRS-008, SyRS-009 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - klare Gewaltenteilung und Selbstschutzregel +Status: belegt + +--- + +ID: StRS-005 +Titel: Ein maßgeblicher Adress-/Kundenstamm statt paralleler Datenhaltungen +Ebene: StRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Datenverantwortliche, Systemarchitektur +Vorbedingung: Altstruktur (Customer/Address/ContactPerson) und neuer Account-Stamm koexistieren +Fakt: Entities `CustomerArea\Customer.cs` (DeliveryConditionI3D) und `Accounts\AccountCustomer.cs` (ReceiptConditionDeliveryI3D) führen Parallelfelder; `Supplier` (Businesspartner) und `AccountSupplier` (Accounts) führen Frachtfelder doppelt; `AccountMigrationBL` nutzt NamedQuery "MigrateWebAccountsFromOldCustomerStructure". +Aussage: Das System soll Kunden-, Liefer- und Ansprechpartnerdaten an einer maßgeblichen Stelle (Account-Stamm) führen; das Zielsystem überführt die Altbestände (CustomerArea, Supplier) und legt sie still. +Ergebnis: Ein Kundenstamm mit einer Konditionenquelle; keine Divergenz zwischen Supplier.Name und Account.Name/Frachtsätzen. +Belege: + - [PRIMÄR] src\backend\Centron.Entities\Entities\CustomerArea\Customer.cs, DeliveryConditionI3D - Begründung: Altmodell mit Konditionsfeldern + - [PRIMÄR] src\backend\Centron.Entities\Entities\Accounts\AccountCustomer.cs, ReceiptConditionDeliveryI3D - Begründung: Neumodell mit denselben Fachmerkmalen + - [PRIMÄR] src\backend\Centron.BL\Accounts\AccountMigrations\AccountMigrationBL.cs, MigrateWebAccountsFromOldCustomerStructure - Begründung: dokumentierter Migrationslauf Alt→Neu + - [PRIMÄR] src\backend\Centron.Entities\Entities\Businesspartner\Supplier.cs vs. src\backend\Centron.Entities\Entities\Accounts\AccountSupplier.cs - Begründung: doppelter Lieferantendatenbestand +Prüfidee: Zähl-Query: Module, die noch Customer/Address (alt) lesen, vs. Account/AccountAddress; Ziel: Differenz = 0. +Tracelinks: SwRS-027, SwRS-028, SwRS-031, SwRS-132 +Konsolidierung: Kandidat: Muster "zwei Datenhaltungen für denselben Fachgegenstand" wie beim Prompt-Beispiel Drucker-Stammblätter vs. Assets +Übernahmewürdigkeit: Workaround - Parallelhaltung ist Migrations-Zustand, Ziel ist der eine Stamm +Status: belegt + +--- + +ID: StRS-006 +Titel: Web-Accounts sehen ausschließlich Daten ihres eigenen Kunden +Ebene: StRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Endkunde (Web-Account-Login) +Vorbedingung: Web-Account ist mit Account/Customer verknüpft +Fakt: `AccountAddressBL` erzwingt `filter.AccountI3Ds = { WebAccount.AccountI3D }`; `AccountSearchBL` filtert bei `IsWebAccountLogin` auf `WebAccount.CustomerI3D`; `ReceiptCartBL.SearchArticles` begrenzt auf `WebAccount.CustomerI3D` (Zeilen 228-244). +Aussage: Das System soll jede Adress-, Konto-, Beleg- und Artikelsuche im Kundenportal zwingend auf den Stammkunden des angemeldeten Web-Accounts einschränken. +Ergebnis: Kunden sehen im Self-Service nur eigene Daten; Mandantendaten bleiben abgeschottet. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Accounts\AccountAddressBL.cs, Filterzwang (Zeilen 75-79) - Begründung: erzwungener Mandantenzwang + - [PRIMÄR] src\backend\Centron.BL\Accounts\AccountSearchBL.cs, IsWebAccountLogin-Filter (Zeilen 294-299) - Begründung: gleiche Regel zweite Stelle + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptCartBL.cs, Zeilen 228-244 - Begründung: Kundenisolierung im Shop +Prüfidee: Webservice-Aufruf mit Web-Account-Token; fremde Kunde-I3D im Filter muss ignoriert/abgewiesen werden. +Tracelinks: SyRS-016, SyRS-017, SyRS-018 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zentrale Mandantentrennung des Portals +Status: belegt + +--- + +ID: StRS-007 +Titel: Personalstamm (Employee) und Zugang (AppUser/Web-Account) sind getrennte Identitäten +Ebene: StRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Administration, System +Vorbedingung: Employee existiert; Zugangsdaten werden unabhängig gepflegt +Fakt: `AppUserBL.GetAppUserObjectForEmployee(employeeId)`/`GetAppUserI3DForEmployee` mappen Mitarbeiter→Login; `SaveOrUpdateAppUser` führt separates Passwortargument; Web-Accounts sind dritte Identitätsart mit eigener Rechtequelle (`WebRights`). +Aussage: Das System soll Personalstammdaten und Zugangsdaten als getrennte Konzepte mit definierter Zuordnung führen, damit Passwort-/Lizenzverwaltung den Personalstamm nicht ändert. +Ergebnis: Sperrung/Änderung eines Zugangs ohne Eingriff in Personaldaten; drei Akteursidentitäten (Employee, AppUser, Web-Account) sauber unterscheidbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\EmployeeArea\AppUserBL.cs, GetAppUserObjectForEmployee - Begründung: explizite Mapping-Methoden belegen Zwei-Konzept-Design + - [SEKUNDÄR] src\backend\Centron.BL\NexusTicketViews\NexusTicketViewBL.cs, Doku zu geteiltem I3D-Bereich von Employee/Web-Account - Begründung: Identitäten teilen sich Nummernkreise, daher Typ needed +Prüfidee: AppUser eines Employees sperren; Employee-Daten bleiben lesbar, Zugriffe des Logins scheitern. +Tracelinks: SwRS-029, SwRS-032, SwRS-052 +Konsolidierung: Kandidat: Identitätskonzepte Employee/AppUser/Web-Account im Zielsystem auf ein Identitätsmodell führen +Übernahmewürdigkeit: übernehmen - saubere Rollen-/Identitätstrennung +Status: belegt + +--- + +ID: StRS-008 +Titel: Verfügbarkeit und Rolle des Mitarbeiters steuern die Arbeitsverteilung +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Mitarbeiter, Disponent +Vorbedingung: Mitarbeiter ist aktiv (`IsActiveEmployeeCompact`-Prüfung) +Fakt: `EmployeeBL` bietet `SetDispatcher`, `IsActiveEmployeeCompact`, `UpdateEmployeeAvailability(employeeI3D, EmployeeAvailability)`. +Aussage: Das System soll je Mitarbeiter eine schaltbare Verfügbarkeit und eine Dispatcher-Eigenschaft führen und diese vor weiterleitungsrelevanten Aktionen (Ticketweitergabe, Zuteilung) prüfen. +Ergebnis: Tickets/Aufgaben erreichen nur verfügbare, rollengerecht eingestellte Mitarbeiter. +Belege: + - [PRIMÄR] src\backend\Centron.BL\EmployeeArea\EmployeeBL.cs, SetDispatcher/UpdateEmployeeAvailability/IsActiveEmployeeCompact (Zeilen 67-127) - Begründung: Steuerungsmethoden inkl. Aktivitätsprüfung +Prüfidee: Inaktiven Mitarbeiter als Dispatcher setzen → Fehlerresult; Zuweisung an Abwesenden verhindert. +Tracelinks: SyRS-002 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: StRS-009 +Titel: Deterministische Länder-, Währungs- und Inlandsbasis +Ebene: StRS +Typ: Daten +Qualitätsmerkmal: +Akteur: _any user; Buchhaltung +Vorbedingung: Default-Mandant mit Land gepflegt; genau ein Defaultland markiert +Fakt: `CountryBL.GetInlandCountry` liefert `MandatorBL.GetDefaultMandator().Country` (offenes TODO zur Filialland-Prüfung); `GetDefaultCountry` filtert `f.Default`; `UpdateCurrencyRateByRateDictionary` importiert EZB-Kurse. +Aussage: Das System soll das für Preise/Steuern maßgebliche Inlandsland deterministisch aus dem Default-Mandanten ableiten und tagesaktuelle Wechselkurse je Währung bereitstellen. +Ergebnis: Belege, Steuern und Fremdwährungspreise rechnen auf einer eindeutigen Länderbasis. +Belege: + - [PRIMÄR] src\backend\Centron.BL\CountryArea\CountryBL.cs, GetInlandCountry/GetDefaultCountry - Begründung: Implementierung inkl. TODO als bekannte Lücke + - [PRIMÄR] src\backend\Centron.BL\CountryArea\CountryBL.cs, UpdateCurrencyRateByRateDictionary (EZB-XML) - Begründung: Kursimport durchgesetzt +Prüfidee: Default-Mandant auf zweites Land setzen; Inlandslogik neuer Belege folgt dem neuen Land. +Tracelinks: SwRS-041, SwRS-042 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen (TODO Filialland als Nachsteuerung) +Status: belegt + +--- + +ID: StRS-010 +Titel: Filial- und Lagerstruktur je Mandant +Ebene: StRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Administration, Logistik +Vorbedingung: Mandant mit Filialen angelegt +Fakt: `BranchBL.SaveAssignedSecondaryStocks` verwaltet je Filiale genau ein Default-Lager plus Sekundärlager atomar; `GetBranchesForSelection` stellt Pseudo-Einträge "Hauptsitz"/"Alle Filialen" bereit. +Aussage: Das System soll Mandanten, Filialen und Lager mit je genauem Default-Lager je Filiale abbilden und in allen Masken einheitlich auswahlbar machen. +Ergebnis: Deterministische Lager- und Filialzuordnung von Belegen, Beständen und Benutzern. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Company\BranchBL.cs, SaveAssignedSecondaryStocks (Zeilen 72-154) - Begründung: Default-Lager-Rotation im Transaktionsblock + - [PRIMÄR] src\backend\Centron.BL\Administration\Company\BranchBL.cs, GetBranchesForSelection/IsBranchEqual - Begründung: einheitliche Filialfilter-Semantik +Prüfidee: Zweites Default-Lager setzen → altes entfällt; Filialauswahl enthält genau einen "Alle Filialen"-Eintrag. +Tracelinks: SwRS-030, SwRS-031 +Konsolidierung: Kandidat: Organisationskonzepte Firma (Company) vs. Mandant vs. Filiale zusammenführen +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: StRS-011 +Titel: Zahlungs- und Lieferkonditionen zentral pflegen, Skonto aussteuerbar +Ebene: StRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Finanz-/Einkaufsabteilung +Vorbedingung: Masterdatenpflege geöffnet +Fakt: `AssetCondition` führt bis zu drei Skonto-Staffeln (Skonto1..3 OffDay/Percent) mit verwalteten Texten; `AssetConditionBL.GetAssetConditionTextPreview` rendert Platzhalter gegen eine Testrechnung und meldet Fehler ohne Rechnungsbestand. +Aussage: Das System soll Zahlungs-/Lieferkonditionen mit Skonto-Staffeln zentral pflegen, in Belege, Textbausteine und E-Rechnung übernehmen und die Auswirkung per Vorschau verifizierbar machen. +Ergebnis: Einheitliche Konditionen für Belege/Materialgruppen; Fälligkeit und Skonto sind aus einer Quelle abgeleitet. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Masterdata\AssetConditionBL.cs, GetAssetConditionTextPreview (Zeilen 34-55) - Begründung: Skonto-Feldsemantik und Fehlerpfad belegt + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[Zahkond] mit Skonto1/Skonto2, LaenPer1..3 - Begründung: Datenmodell der Skontostufen +Prüfidee: Zahlungsbedingung "2 % / 14 Tage, netto 30"; Rechnung speichern → Fälligkeit und Skontotext stimmen; E-Rechnung enthält SKONTO-Angaben. +Tracelinks: SyRS-013, SyRS-015, SyRS-040, SyRS-041, SwRS-012, SwRS-013, SwRS-014, SwRS-034 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: StRS-012 +Titel: SLA-Zusagen aus Serviceverträgen verbindlich durchsetzen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Helpdesk-Bearbeiter, Kunde mit Servicevertrag +Vorbedingung: Ticket einem Servicevertrag zugeordnet +Fakt: `UpdateHelpdeskBL.UpdatePriority` verwirft abweichende Prioritäten ("Die Priorität wird durch den gewählten Vertrag vorgegeben."); `GetDueDateFromPriority` leitet das Fälligkeitsdatum ab; `HelpdeskPriority.IsSLA` und `Contract.SLAPriority` verknüpfen Vertrag und Ticket. +Aussage: Das System soll bei SLA-Verträgen die Ticketpriorität verbindlich aus dem Vertrag ableiten und daraus das Fälligkeitsdatum automatisch berechnen; manuelle Abweichungen sind unzulässig. +Ergebnis: Verträge werden eingehalten; Fälligkeit/Priorität springen automatisch bei Vertragswechsel; Beteiligte werden benachrichtigt. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\UpdateHelpdeskBL.cs, UpdatePriority (Zeilen 281-326), SetContract (Zeilen 430-455) - Begründung: Durchsetzungsstellen der SLA-Kette + - [SEKUNDÄR] src\backend\Centron.Entities\Entities\CustomerArea\Support\HelpdeskPriority.cs, IsSLA - Begründung: SLA-Kennzeichen im Datenmodell +Prüfidee: SLA-Vertrag setzen, abweichende Priorität wählen → Fehler; Vertragswechsel → Priorität+DueDate springen. +Tracelinks: keine abgeleitete Anforderung - SLA-Kette abschließend in UpdateHelpdeskBL belegt +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zentrales Service-Vermarktungsmerkmal +Status: belegt + +--- + +ID: StRS-013 +Titel: Nachvollziehbare Ticketbearbeitung mit beschränkter Sichtbarkeit +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Interne Bearbeiter, Kunde (Web-Account) +Vorbedingung: Ticket existiert, Benutzer angemeldet +Fakt: `HelpdeskBL.GetHelpdeskRequest` prüft Vertriebsgebietsrechte (`EmployeeToSalesAreaBL`) und blendet `IsOnlyInternalVisible`-Tickets für Web-Logins mit einheitlichem Fehler "Ticket nicht gefunden!" aus. +Aussage: Das System soll Ticketzugriff nach internen Rechten (Vertriebsgebiet) und Kanälen (Kunde/sichtbarkeit) steuern, ohne Kunden die Existenz interner Tickets zu verraten, und jede Statusänderung historisieren. +Ergebnis: Berechtigte sehen Tickets, Unberechtigte erhalten einen einheitlichen Nicht-gefunden-Fehler; Statushistorie ist vollständig. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs, GetHelpdeskRequest (Zeilen 113-146) - Begründung: Rechte-/Kanalfilter durchgesetzt + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs, SetHelpdeskAction (Zeilen 558-609) - Begründung: Statushistorie im Speicherpfad +Prüfidee: Web-Account öffnet internes Ticket → CouldNotFindData; fremdes Vertriebsgebiet → RightCheckFailed; Statuswechsel erzeugt Historieneintrag. +Tracelinks: SyRS-037, SyRS-038, SyRS-043, SyRS-048, SwRS-043, SwRS-045, SwRS-047, SwRS-049, SwRS-050, SwRS-127 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: StRS-014 +Titel: Wiedervorlagen und Aufgaben über alle Fachbereiche bündeln +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: alle Fachbereiche +Vorbedingung: Quellvorgang (Beleg, Helpdesk, Urlaub, Kommissionierung ...) erzeugt Wiedervorlage +Fakt: `ToDoBL.FillObjectKindsListe` registriert über 30 `ToDoObjectKind`-Einträge (Name, Area, AssetKind); `TaskManagementTaskBL.SaveOrUpdateTask` erzwingt valide Aktion/Wiederkehr und Lizenz. +Aussage: Das System soll Wiedervorlagen aller Fachbereiche in einer strukturierten ToDo-Liste mit Typ/Bereich/Objektbezug führen und wiederkehrende Aufgaben nur bei valider, lizenzierter Aktion anlegen. +Ergebnis: Ein Einstiegspunkt zeigt bereichsübergreifende Aufgaben; keine defekten oder unlizenzierten Automationen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\ToDoArea\ToDoBL.cs, FillObjectKindsListe (Zeilen 69-118) - Begründung: zentraler Typkatalog + - [PRIMÄR] src\backend\Centron.BL\TaskManager\TaskManagementTaskBL.cs, SaveOrUpdateTask (Zeilen 40-97) - Begründung: Validierungs-/Lizenzprüfung +Prüfidee: ToDo je registriertem Typ anlegen → in Liste mit korrektem Bereichstext; Aufgabe mit ungültiger Wiederkehr → Fehlerresult. +Tracelinks: SwRS-074, SwRS-077, SwRS-079 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: StRS-015 +Titel: Nachvollziehbarkeit von Datenänderungen (Wer, Was, Wann) +Ebene: StRS +Typ: nicht-funktional +Qualitätsmerkmal: Wartbarkeit / Sicherheitsfunktionalität (ISO 25010) +Akteur: Prüfer, Fachanwender, System +Vorbedingung: Änderung an getracktem Objekt durch angemeldeten Benutzer +Fakt: `ChangeTrackingEventListener` (NHibernate IPreUpdateEventListener) schreibt je geänderter Property Alt-/Neuwert, Benutzer und Datum in `ChangeLog`; Repositories belegen CreatedBy/CreatedDate/CreatedVersion automatisch; Soft-Delete plus Log Tabellen (Geräte, Umlagerungen, Belegprotokolle) ergänzen. +Aussage: Das System soll Änderungen an als überwachungswürdig deklarierten Feldern automatisch mit Alt-/Neuwert, Benutzer und Zeitpunkt protokollieren und Herkunftsfelder (Ersteller/-zeitpunkt/-version) beim Anlegen zwangsläufig setzen. +Ergebnis: Auditgrundlage ohne Fachcode; Löschung erfolgt,revidierbar per Soft-Delete mit Log. +Belege: + - [PRIMÄR] src\backend\Centron.DAO\ChangeTracking\ChangeTrackingEventListener.cs, OnPreUpdate/CreateChangeLog (Zeilen 52-142) - Begründung: zentrale, automatische Protokollierung + - [PRIMÄR] src\backend\Centron.DAO\Repositories\Accounts\AccountRepository.cs, CreateNewAccount (Zeilen 39-52) - Begründung: Auditfelder im Repository-Muster +Prüfidee: Getrackte Property ändern → genau ein ChangeLog-Satz mit korrektem Benutzer; Neuanlage setzt CreatedVersion = Assemblyversion. +Tracelinks: SyRS-004, SyRS-033, SwRS-020, SwRS-023, SwRS-047, SwRS-082, SwRS-086, SwRS-093, SwRS-094, SwRS-110 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Audit-Basis; Lücken (kein Insert/Delete-Tracking) im Zielsystem schließen +Status: belegt + +--- + +ID: StRS-016 +Titel: Lückenlose, prüfsichere Nummernvergabe (GoBD) +Ebene: StRS +Typ: nicht-funktional +Qualitätsmerkmal: Funktionale Sicherheit (ISO 25010) +Akteur: System bei jeder Beleg-/Stammdatenanlage +Vorbedingung: Nummernkreise je Mandant/Filiale gepflegt +Fakt: `NumberGroupBL.GetNextNumber` vergibt und fortschreibende Nummern je Mandant/Filiale; `MandatoryBL` priorisiert filialbezogene Kreise vor dem Standardmandanten und überspringt verbrauchte (`Aktuell<=0`); Vergabe ohne manuelle Eingabe in allen Belegarten. +Aussage: Das System soll alle Nummern (Belege, Adressen, Ticketprojekte) fortlaufend, lückenlos und mandanten-/filialbezogen aus Nummernkreisen vergeben, ohne dass Benutzer Nummern setzen können. +Ergebnis: Keine Doppelvergabe; Nummerierung ist revisionssicher und je Mandant/Filiale getrennt. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Company\NumberGroupBL.cs, GetNextNumber/CreateNumberGroups - Begründung: zentrale Vergabestelle + - [PRIMÄR] src\backend\Centron.BL\Administration\Mandatory\MandatoryBL.cs, GetNumberGroup (ORDER BY Mandantenpriorität) - Begründung: Delegation Mandant→Filiale→Standard +Prüfidee: Paralleles Neuanlegen → keine Duplikate, Zähler monoton; Filiale mit eigenem Kreis wird vor Standardmandant gezogen. +Tracelinks: SyRS-010, SyRS-039, SyRS-044, SwRS-026, SwRS-099, SwRS-120 +Konsolidierung: Kandidat: Nummernkreislogik (Company) und Nummernkreis-Delegation (Mandatory) zusammenführen +Übernahmewürdigkeit: übernehmen - GoBD-Kernanforderung +Status: belegt diff --git a/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/SwRS.md b/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/SwRS.md new file mode 100644 index 00000000..27348a2e --- /dev/null +++ b/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/SwRS.md @@ -0,0 +1,2740 @@ +# SwRS - Software Requirements Specification (Teil 1: Sicherheit, Abrechnung, Einkauf/Lager, Stammdaten, Portal) + +Ebene SwRS: Komponenten, Datenmodelle, software-interne Regeln. Jede SwRS referenziert ihre übergeordnete SyRS/StRS (Tracelinks). + +--- + +ID: SwRS-001 +Titel: Zentrale, gecachte Rechtsprüfung mit Fail-closed-Semantik +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: any business logic class (AppRightsBL) +Vorbedingung: AppUser ist Gruppen zugeordnet +Fakt: `AppRightsBL.HasUserRight` lädt Rechte per SQL über Sichtrus INNER JOIN Sichmemb, cacht pro Benutzer (`AllRightsFromAppUser{I3D}`); `UserRightsExt.HasUserRight` fängt Exceptions und gibt im Fehlerfall false zurück. +Aussage: Das System soll die Rechtsprüfung zentral und fehlerabsichernd durchführen: ohne explizit nachgewiesenes Gruppenrecht gilt "kein Zugriff". +Ergebnis: true nur bei tatsächlichem Gruppenrecht; Systemfehler führen zu Zugriffsverweigerung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Rights\AppRightsBL.cs, HasUserRight/GetAllAppRightsFromUser - Begründung: durchsetzende Prüfstelle inkl. Datenquelle + - [PRIMÄR] src\backend\Centron.BL\Administration\Rights\UserRightsExt.cs, HasUserRight (catch → false) - Begründung: Fail-closed-Semantik +Prüfidee: Benutzer ohne Recht Y → false; mit Gruppenrecht → true; Session-Fehler → false. +Tracelinks: SyRS-001, StRS-004 +Konsolidierung: Kandidat: mit SyRS-001 (Filter nutzt dieselbe Prüfstelle) +Übernahmewürdigkeit: übernehmen - Kernmechanik des Rechtekonzepts +Status: belegt + +--- + +ID: SwRS-002 +Titel: Sichere Behandlung personengebundener API-Access-Tokens +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: API-Client, Administrator bei Vergabe +Vorbedingung: Lizenz AccessTokenModule vorhanden +Fakt: `AccessTokenBL.CreatePersonalToken` erzeugt 48 Zeichen via RandomNumberGenerator, speichert nur SHA-256-Hash; `ValidateToken` lehnt inaktive/abgelaufene Tokens ab und protokolliert jeden ApiCall mit IP; `LicenseCheckCanActivateMoreToken` begrenzt die aktive Anzahl. +Aussage: Das System soll API-Zugriffe über personengebundene Tokens erlauben, wobei nur Hashes gespeichert, Aktivierung/Ablauf/Lizenzmenge erzwungen und jede Nutzung protokolliert wird. +Ergebnis: Deaktivierte/abgelaufene Tokens stets abgewiesen; Limit überschreitende Aktivierung blockiert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\AccessTokens\AccessTokenBL.cs, ValidateToken (!IsActive/IsExpired → AsError) - Begründung: Durchsetzungsstelle + - [PRIMÄR] src\backend\Centron.BL\Administration\AccessTokens\AccessTokenBL.cs, LicenseCheckCanActivateMoreToken - Begründung: Mengensteuerung + - [SEKUNDÄR] Logtext "Token '{Name}' deaktiviert durch {Employee.ShortSign}" - Begründung: Verwaltungsnachvollziehbarkeit +Prüfidee: Abgelaufener Token → "Token ist abgelaufen" + Log; Aktivierung über Limit → Fehler mit Maximalanzahl. +Tracelinks: SyRS-001, SyRS-006, StRS-004 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - moderner Hash-/Protokoll-Ansatz +Status: belegt + +--- + +ID: SwRS-003 +Titel: Passwortanmeldung nur für aktive, nicht gesperrte Konten +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: c-entron-Benutzer (Basic-Login) +Vorbedingung: SystemAuthenticationMethod Basic bzw. CentronLogin-Benutzer +Fakt: `BasicAuthenticator.AuthenticateInternal` vergleicht Name + Passwort-Hash (SHA1, Kommentar "the password should be salted!!!"); `Authenticator.ValidateAppUser` lehnt bei IsAccountDisabled, Deaktivierungszeitraum und inaktivem Mitarbeiterzeitraum ab; `UsersBL.ChangeOwnPassword` verweigert externe Auth-Konten. +Aussage: Das System soll die Anmeldung nur bei korrektem Passwort und aktivem Konto gewähren und die lokale Passwortänderung für extern authentifizierte Konten ausschließen. +Ergebnis: Erfolgreiche Anmeldung liefert LoggedInUser, sonst LoginFailed/EmployeeAccountDeactivated. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\Auth\BasicAuthenticator.cs, AuthenticateInternal - Begründung: Authentifizierungsprüfung + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\Auth\Authenticator.cs, ValidateAppUser - Begründung: Kontosperren erzwungen + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\UsersBL.cs, ChangeOwnPassword - Begründung: Ausschluss externer Konten +Prüfidee: Deaktiviertes Konto mit korrektem Passwort → Fehler; AD-Benutzer ändert Passwort → Fehler. +Tracelinks: SyRS-002, SyRS-005, StRS-004 +Konsolidierung: Kandidat: Login-Gesamtprozess mit SwRS-004 +Übernahmewürdigkeit: Workaround - ungesalzener SHA1-Hash ist dokumentierte Altlast; Funktionsumfang übernehmbar +Status: belegt + +--- + +ID: SwRS-004 +Titel: Prüfung des personengebundenen Zwei-Faktor-Schlüssels +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Benutzer mit hinterlegtem 2FA-Schlüssel +Vorbedingung: TwoFactorAuthentication-Datensatz am AppUser vorhanden +Fakt: `TwoFactorAuthenticationBL.ValidateAuthenticationPin` (src\backend\Centron.BL\TwoFactorAuthenticator\TwoFactorAuthenticationBL.cs, Zeile 43) validiert die eingegebene PIN gegen den personengebundenen Schlüssel; Aufruf erfolgt über `TwoFactorAuthenticationWebServiceBL` (Zeile 27). +Aussage: Das System soll die eingegebene Authentifizierungs-PIN gegen den personengebundenen Zwei-Faktor-Schlüssel des angemeldeten Benutzers prüfen. +Ergebnis: Result-Erfolg nur bei Schlüsselübereinstimmung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\TwoFactorAuthenticator\TwoFactorAuthenticationBL.cs, ValidateAuthenticationPin - Begründung: Vergleichsmethode verifiziert + - [SEKUNDÄR] src\backend\Centron.BL\WebServices\TwoFactorAuthenticator\TwoFactorAuthenticationWebServiceBL.cs, Zeile 27 - Begründung: Webservice-Aufrufpfad +Prüfidee: Falsche PIN → Result-Fehler; richtige PIN → Erfolg. +Tracelinks: SyRS-002, StRS-004 +Konsolidierung: Kandidat: mit SyRS-002 (2FA-Prozess) und SwRS-057 (TOTP-Bibliothek) +Übernahmewürdigkeit: übernehmen +Status: HYPOTHESE - die aufrufende Erzwingerstelle im Login-Ablauf (welche Masken/Endpunkte die Prüfung zwingend auslösen) wurde nicht nachgewiesen + +--- + +ID: SwRS-005 +Titel: Alt-Passwortverwaltung (Keywords) - Migrationsbedarf +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Servicemitarbeiter +Vorbedingung: Keyword-Datensatz (Zugangsdatum Kunde/Asset) existiert +Fakt: `PasswordManagementKeywordBL.GetDecryptedKeywordById` gibt das Passwortfeld ohne Entschlüsselung (Kommentar "// decryption") und ohne Rechtsprüfung zurück; das Neu-Pendant PasswordManager verschlüsselt AES und prüft Rechte. +Aussage: Das System soll Kunden-Zugangsdaten ausschließlich verschlüsselt und rechtsgeprüft ausliefern; der Altbestand (Keywords) ist in das PasswordManager-Konzept zu überführen. +Ergebnis: Keine unverschlüsselte/rightsfreie Auslieferung von Zugangsdaten mehr. +Belege: + - [SEKUNDÄR] src\backend\Centron.BL\PasswordManagementArea\PasswordManagementKeywordBL.cs, GetDecryptedKeywordById - Begründung: beobachtete Regellosigkeit (Fakt), nicht normativ +Prüfidee: Nach Migration: Aufruf ohne Recht → Ablehnung; DB-Spalte enthält keinen Klartext. +Tracelinks: SyRS-030, StRS-004 +Konsolidierung: Kandidat: PasswordManagementArea in PasswordManager überführen +Übernahmewürdigkeit: veraltet - vom PasswordManager-Konzept abgelöst +Status: HYPOTHESE - nicht belegt, ob das Modul noch aktiv genutzt wird; Aktivierungs-/UI-Nachweis fehlt + +--- + +ID: SwRS-006 +Titel: Elektronische PDF-Signatur mit geschützter Zertifikatskonfiguration +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: System (Signaturvorgang), Administrator (Konfiguration) +Vorbedingung: Signaturzertifikat (PKCS#12) hinterlegt +Fakt: `PdfSigningBL.GetPdfSigningSettings` liefert die Einstellungen, `IsPdfSigningAvailable()` prüft Verfügbarkeit, `SignPdfDocument(byte[])` signiert; Zertifikatspasswörter werden verschlüsselt in den Anwendungseinstellungen gehalten. +Aussage: Das System soll PDF-Dokumente mit hinterlegtem Zertifikat (optional TSA) signieren können, wobei die Zertifikatskonfiguration nur mit Änderungsberechtigung gepflegt werden darf. +Ergebnis: Signiertes PDF; ohne Konfiguration/Verfügbarkeit kein Signaturversuch. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Security\PdfSigningBL.cs, SignPdfDocument/GetPdfSigningSettings/IsPdfSigningAvailable - Begründung: Signatur-API der Modulklasse +Prüfidee: Ohne hinterlegtes Zertifikat liefert IsPdfSigningAvailable false; Signatur mit Testzertifikat prüfbar. +Tracelinks: SyRS-003, StRS-003 +Konsolidierung: Kandidat: Signaturthemen (Office/DocumentSigning) zu Signaturkapitel +Übernahmewürdigkeit: übernehmen +Status: HYPOTHESE - die Rechtsprüfung beim Pflegen der Signatureinstellungen wurde in der Datei nicht im Detail verifiziert + +--- + +ID: SwRS-007 +Titel: Ticketansichten im Kundenportal nach Web-Rechten differenzieren +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Endkunde (Web-Account) +Vorbedingung: Web-Account besitzt Ticket-Rechte (alle/eigene/Kundenadministrator) +Fakt: `WebCartTicketsPage.razor` und `CustomerTicketDetailsPage.razor` tragen `[AuthorizeWebRight(SHOWALLEREQUESTS, SHOWONLYOWNREQUESTS, CUSTOMERADMINISTRATOR)]` (Zeile 4). +Aussage: Das System soll Ticketlisten/-details im Kundenportal nur bei Besitz eines der Ticket-Rechte öffnen und die Sichten "eigene" vs. "alle" unterscheiden. +Ergebnis: Endkunden sehen nur freigegebene Ticketbestände; Zugriffe ohne Recht werden abgewiesen. +Belege: + - [SEKUNDÄR] src\nexus\CentronNexus\WebCart\CustomerTicketDetailsPage.razor, Zeile 4 - Begründung: Routenschutz + - [SEKUNDÄR] src\nexus\CentronNexus\WebCart\WebCartTicketsPage.razor, Zeile 4 - Begründung: Routenschutz +Prüfidee: Account nur mit SHOWONLYOWNREQUESTS: Detailseite fremder Tickets nicht einsehbar. +Tracelinks: SyRS-016, StRS-002 +Konsolidierung: Kandidat: Portal-Rechtefamilie mit SwRS-036 +Übernahmewürdigkeit: übernehmen - Datenfiltertiefe ("nur eigene") vor Übernahme verifizieren +Status: HYPOTHESE - die eigentliche Datenfilterung "nur eigene Tickets" wurde nicht im Detail nachgewiesen + +--- + +ID: SwRS-008 +Titel: Passwort-Manager: Export nur mit Recht, Lizenz und Masterkey +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Benutzer mit Export-Recht +Vorbedingung: Lizenz PasswordManager vorhanden +Fakt: `PasswordManagerBL.GetCustomerAccessDataForExport` prüft HasLicense und `HasUserRight(EXPORT_ACCESS_AND_PASSWORD_DATA)` (Zeile 935) sonst ResultException; `GetPasswordManagerPropertyValues` nullt ValueEncryptedString vor Rückgabe; Richtlinienverwaltung verlangt ACCESS_GUIDELINE_MANAGEMENT. +Aussage: Das System soll entschlüsselte Zugangspasswörter nur bei Lizenz und Export-Recht ausliefern und Chiffretexte aus regulären Abfragen entfernen. +Ergebnis: Ohne Recht/Lizenz ResultException; Listen ohne Encrypted-Strings. +Belege: + - [PRIMÄR] src\backend\Centron.BL\PasswordManager\PasswordManagerBL.cs, GetCustomerAccessDataForExport (Zeile 935) - Begründung: durchsetzende Exportprüfung + - [PRIMÄR] src\backend\Centron.BL\PasswordManager\PasswordManagerBL.cs, GetPasswordManagerPropertyValues - Begründung: Datenleckschutz + - [PRIMÄR] src\backend\Centron.BL\PasswordManager\PasswordManagerBL.cs, ValidateUserRights - Begründung: Richtlinienverwaltung rechtsgebunden +Prüfidee: Export ohne Recht → ResultException; mit Recht → Entschlüsselung per Masterkey. +Tracelinks: SyRS-003, SyRS-030, StRS-004 +Konsolidierung: Kandidat: Lizenz-/Rechtsschranken-Familie (SwRS-024) +Übernahmewürdigkeit: übernehmen - dreifache Prüfung Lizenz/Recht/Schlüssel +Status: belegt + +--- + +ID: SwRS-009 +Titel: Anonymisierung von Ansprechpartnern mit Löschprotokoll +Ebene: SwRS +Typ: Datenschutz +Qualitätsmerkmal: +Akteur: Benutzer mit DSGVO-Recht +Vorbedingung: Suchfilter mit Name oder Vorname +Fakt: `DataSecurityBL` nullt Name, Vorname, Geburtsdatum, Telefon, E-Mail des Ansprechpartners und schreibt ein Löschprotokoll; Suche verlangt mindestens einen Namensfilter. +Aussage: Das System soll DSGVO-Löschungen als Anonymisierung der Personen字段 mit Protokolleintrag ausführen und die Suche gegen vollflächige Löschungen absichern. +Ergebnis: Personenbezug entfernt, Löschung nachweisbar, kein unbeaufsichtigter Massenlöschpfad. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\DataSecurity\DataSecurityBL.cs, DsgvoDeleteRightDeleteContacts (Zeile 789) - Begründung: Löschpfad inkl. Guard +Prüfidee: Leerer Namensfilter → Abweisung;Löschung → Felder null + Protokoll. +Tracelinks: SyRS-004, StRS-004 +Konsolidierung: Kandidat: mit SyRS-004 (DSGVO-Verfahren) +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-010 +Titel: Weiterverarbeitungsregeln und Herkunftsbindung je Belegart +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertriebssachbearbeiter +Vorbedingung: Ursprungsbeleg mit weiterverarbeiteten Positionen +Fakt: `InvoiceSpecificLogic.CanBeForwardedIntoForUIOverwrite` liefert für Barrechnungen leere Liste; `CanChangeItemQuantityAfterItemWasForwarded=false`; Herkunft über RechPos.UrsprungI3D/UrsprungNr/UrsprungArt. +Aussage: Das System soll die erlaubten Weiterverarbeitungspfade je Belegart als hinterlegte Regeln steuern und die Herkunftskette der Positionen führen. +Ergebnis: Deterministischer Belegfluss; kein Mengen-Mehrfachabgriff. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\InvoiceSpecificLogic.cs, Zeilen 279-297 - Begründung: Code-Verträge der Übergänge +Prüfidee: Barrechnung zeigt keine Weiterverarbeitung; Teilrechnung → Mengenänderung im Lieferschein abgewiesen. +Tracelinks: SyRS-014, StRS-003 +Konsolidierung: Kandidat: Belegfluss-Regelwerk je Belegart vereinheitlichen +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-011 +Titel: Rechnungsstorno: Guard-Kette und historisierende Neufassung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Benutzer mit Recht RIGHT_RECHNUNGSTORNIEREN +Vorbedingung: Rechnung in aktiver Version +Fakt: `ReceiptInvoiceBL.CancelInvoice` prüft Recht, bereits Canceled, Barrechnung, Weiterverarbeitung, Buchhaltungsexport und letzte Vertragsbelegversion; danach CreateNewVersion mit QuantityComplete=0, State=Canceled und Protolleintrag. +Aussage: Das System soll das Storno nur Berechtigten gestatten, es bei Bar-/exportierten/weiterverarbeiteten Rechnungen ablehnen und als neue Version mit Status Canceled historisieren. +Ergebnis: Ursprungsrechnung revisionsfähig erhalten; Storno protokolliert; Verträge/Timer zurückgesetzt. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\ReceiptInvoiceBL.cs, CancelInvoice (Zeilen 143-206) - Begründung: einzige Storno-Stelle mit Guard-Kette + - [SEKUNDÄR] src\backend\Centron.BL\DataExchange\BookKeeping\BookKeepingExportBL.cs, IsReceiptExported - Begründung: Exportblocker +Prüfidee: Storno ohne Recht abgewiesen; nach DATEV-Export endgültiger Fehler; Erfolg → Version 2, Mengen 0, Log. +Tracelinks: SyRS-011, StRS-003 +Konsolidierung: Kandidat: Storno-Familie mit Gutschriften-Regelwerk +Übernahmewürdigkeit: übernehmen - unverzichtbare Rechnungsberichtigung +Status: belegt + +--- + +ID: SwRS-012 +Titel: Skontoberechnung und -text je Zahlungsbedingung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System bei Beleg-/Texterzeugung +Vorbedingung: Skontostaffeln (bis 3) gepflegt +Fakt: `AssetConditionTextReplacementBL` ersetzt @T1-@T3/@B1-@B3 gegen berechnete Daten/Beträge; `GetCalculatedSkonto` nutzt "multiplicator = 1 + percentage/100" mit Integer-Division und addiert statt abzuziehen. +Aussage: Das System soll Skontobeträge und -fristen aus den Staffeln der Zahlungsbedingung korrekt (Brutto × Prozentsatz, Fristdatum) in Belegtexte einsetzen. +Ergebnis: Skontotext und -betrag stimmen rechnerisch; Regel ist testbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Masterdata\AssetConditionTextReplacementBL.cs, GetCalculatedSkonto (Zeilen 139-151) - Begründung: Berechnungsstelle inkl. beobachtetem缺陷 +Prüfidee: Skonto 2 % auf 100 € Brutto: korrekter Erwartungswert 2 € - aktuelle Implementierung liefert abweichenden Wert (Regressionstest). +Tracelinks: SyRS-041, StRS-011 +Konsolidierung: Kandidat: mit SwRS-013 Preis-/Rundungskapitel +Übernahmewürdigkeit: Workaround - Berechnungsfehler (Integer-Division); Zielregel vor Übernahme festlegen +Status: belegt + +--- + +ID: SwRS-013 +Titel: Preishierarchie der Belegposition (Vertrag > Sonderpreis > Staffelpreis) +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System bei Positionserfassung +Vorbedingung: Artikel auf Kundenbeleg; optional Vertrag/Sonderpreis/Menge +Fakt: `ReceiptItemPriceBL.GetBasePrice` priorisiert Vertrags-Sonderpreise (invertierte Werte: "10 is 10 % surcharge"), sonst Kundensonderpreis (Artikel > Materialgruppe+Untergruppe > Materialgruppe), sonst Staffelpreis; Fixrabatte werden prozentual umgerechnet. +Aussage: Das System soll Basispreis und Rabatt nach fester Rangfolge Vertrags-Sonderpreis → Kunden-Sonderpreis → Staffelpreis → Preisliste ermitteln und fixe Rabatte prozentual auf den Basispreis umrechnen. +Ergebnis: Deterministisch ableitbare Positionspreise; Preiscache liefert konsistente Massenwerte. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Internal\ReceiptItemPriceBL.cs, GetBasePrice/GetSpecialPrice/GetContractSpecialPrice - Begründung: einzige Berechnungsstelle der Hierarchie + - [SEKUNDÄR] ebd., GetPurchaseBasePrice (ekFactor-Formel) - Begründung: EK-Seite derselben Logik +Prüfidee: Kunde mit Sonderpreis + Artikel mit Staffelpreis: Rangfolge prüfend durchtesten; Basispreis 0 ohne Absturz. +Tracelinks: StRS-011, SyRS-015 +Konsolidierung: Kandidat: mit SwRS-014 (Rundung) zusammenführen +Übernahmewürdigkeit: übernehmen - komplexe, aber eindeutig kodierte Fachregel +Status: belegt + +--- + +ID: SwRS-014 +Titel: Zweistufige Preisrundung mit artikelbezogener Genauigkeit +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: Funktionale Richtigkeit (ISO 25010) +Akteur: System bei Positions-/Belegberechnung +Vorbedingung: Position mit Basispreis, Rabatt, Steuer, Menge, Währungsfaktor; Artikel mit Precision +Fakt: `CalculationUtils.CalculateNetPrice` rundet doppelt (Basispreis, dann Netto) mit MidpointRounding.AwayFromZero und artikeldefinierter precision; `ReceiptPriceHelper.CalculateReceiptPrices` rundet CH-Bruttosummen auf 0,05-Raster. +Aussage: Das System soll Nettobeträge zweistufig mit kaufmännischer Rundung und artikeldefinierter Nachkommastellenzahl berechnen und bei Schweizer Belegen den Endbetrag auf 5-Rappen-Raster bringen. +Ergebnis: Reproduzierbare, rundungskonsistente Belegsummen; Währungsfaktorwechsel verschiebt den Zielwährungspreis nicht. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptPriceHelperBL.cs, CalculateReceiptItemPrices (Zeilen 96-127) - Begründung: Durchsetzung mit Artikel-Precision + - [SEKUNDÄR] src\webservice\Centron.WebServices.Core\Helper\ReceiptPriceHelper.cs, CalculateReceiptPrices (Zeilen 37-41) - Begründung: 0.05-Rundung + - [SEKUNDÄR] src\backend\Centron.Interfaces\DataExchange\BookKeeping\CalculationUtils.cs, CalculateNetPrice - Begründung: identische Regel im Export +Prüfidee: Precision=3, Rabatt 33,33 %, CurrencyFactor≠1: Referenzvergleich; CH-Beleg: Endsumme durch 0,05 teilbar. +Tracelinks: StRS-011, SyRS-040 +Konsolidierung: Kandidat: mit SwRS-013 +Übernahmewürdigkeit: Sonderfall - 0,05-Rundung nur für Schweizer Belege +Status: belegt + +--- + +ID: SwRS-015 +Titel: Distributoren automatisch bei Import anlegen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Importsystem (Einkauf) +Vorbedingung: Liste von Distributornamen liegt vor +Fakt: `DistributorBL.EnsureDistributorsExist` legt unbekannte Namen als Distributor mit State=1 an und reaktiviert bestehende; Lesepfade filtern `State == 1`. +Aussage: Das System soll beim Sicherstellen von Distributoren unbekannte Namen idempotent als aktive Einträge anlegen. +Ergebnis: Genau ein aktiver Datensatz je Name. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Buying\External\DistributorBL.cs, EnsureDistributorsExist/GetAllDistributors - Begründung: Anlage-/Filterlogik in der Klasse +Prüfidee: Zwei Namen (einer vorhanden) → zwei Datensätze mit State=1. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: "Ensure-by-Name"-Muster (auch Artikelimport) vereinheitlichen +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-016 +Titel: Bestellvorschlagsliste aus offentlichem Bedarf und Mindestbestand +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Einkäufer (BVL/OSL) +Vorbedingung: Offene Auftragspositionen, Mindestbestände, Zugänge gepflegt +Fakt: `OrderSuggestionListBL` baut SQL über AufPos/AufKopf (`Status=1`, `BestellSperre=0`), Mindestbestand und cvw_ArticleCount; Kennzeichenfilter via AppSettings; EK-Preis mit calcFactor. +Aussage: Das System soll den offenen Bedarf je Artikel/Lager (Auftrag minus Bestand/Zugang) ermitteln und unterschrittene Mindestbestände zur Bestellung vorschlagen. +Ergebnis: Vorschlagsliste mit Artikel, Bestand, Bedarf, EK, Mindestmenge; gesperrte Positionen ignoriert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Purchasing\OrderSuggestionList\OrderSuggestionListBL.cs, ctor/_sqlArticle - Begründung: Bedarfs-SQL vollständig in der Klasse + - [SEKUNDÄR] src\backend\Centron.BL\Purchasing\PurchaseSettings\PurchaseSettingsBL.cs, GetSettings - Begründung: Schalterzentrale +Prüfidee: Mindestbestand 10, Bestand 2, offene 5 → Vorschlag 13; BestellSperre ignoriert. +Tracelinks: StRS-001, SyRS-045 +Konsolidierung: Kandidat: Kalkulationsfaktor-Muster mit ArticleStockBL +Übernahmewürdigkeit: übernehmen - Kernfunktion Bestellwesen +Status: belegt + +--- + +ID: SwRS-017 +Titel: Bereichsübergreifender Export von Lieferantenrechnungen/Timerleistungen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Backoffice/Zentrale +Vorbedingung: Zielbereich der Auftragsposition gepflegt +Fakt: `SupplierOrderPerBranchBL.GetBasisCalcList` liefert per Raw-SQL nur Sätze mit abweichender Bereichs-I3D; ohne RepeatExport nur `ExportDate Is Null`; `WriteExportDate` markiert; Ersatz-EK über InternalCompanyEK. +Aussage: Das System soll nur Vorgänge zwischen unterschiedlichen Bereichen exportieren und den Erstexport je Position zeitlich markieren (Dublettenschutz). +Ergebnis: Vollständige, dublettenfreie Exportliste mit Bereichszuordnung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Purchasing\SupplierOrderPerBranchBL.cs, GetBasisCalcList/WriteExportDate - Begründung: Bereichsfilter+Exportmarkierung +Prüfidee: Zwei Sätze, einer mit ExportDate → nur einer geliefert; RepeatExport=true → beide. +Tracelinks: StRS-003 +Konsolidierung: Kandidat: ExportDatum-Musterfamilie +Übernahmewürdigkeit: Sonderfall - interne Verrechnungslogik (hlpdsk_*) mit unternehmensspezifischen Tabellen +Status: belegt + +--- + +ID: SwRS-018 +Titel: Rechteprüfung in Kommissionierung und Barcodeerzeugung +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: Sicherheitsfunktionalität (ISO 25010) +Akteur: angemeldeter Benutzer +Vorbedingung: Recht UserRightsConst.Logistic.Commissioning existiert +Fakt: `OrderCommissionBL.HasUserRightsTooAccessCommissionModule` prüft das Recht und liefert sonst Fehler "Der angemeldete Benutzer hat nicht das Recht..."; Aufruf in GetOrdersForCommission (Zeile 73); Barcodeerzeugung hat eigenes Recht GENERATE_BARCODES. +Aussage: Das System soll Zugriff auf Kommissionierdaten und Barcodeerzeugung nur mit explizit vergebenem Recht gestatten. +Ergebnis: Datenloser Abweis ohne Recht. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Warehousing\Commissions\OrderCommissionBL.cs, HasUserRightsTooAccessCommissionModule - Begründung: Durchsetzungsstelle inkl. Fehlerpfad + - [SEKUNDÄR] src\backend\Centron.BL\Warehousing\ArticleBL.cs, GetArticleManagementUiSettings - Begründung: analoges Muster +Prüfidee: Ohne Recht → ResultStatus.Error; mit Recht → Liste. +Tracelinks: SyRS-001, StRS-004 +Konsolidierung: Kandidat: einheitliche Rechtsprüfung aller Module +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-019 +Titel: Fortschreibung des Artikel-EK aus Wareneingangspreisen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System (Belegbuchung) +Vorbedingung: Belegposition mit EK/Menge wird auf Lager gebucht +Fakt: `ArticleStockBL.UpdateArticlePurchasePrice` überspringt bei Sondervereinbarung (`SpecialAgreementI3D > 0`) und fester Preisbindeflagge (`NoMixedEk == FixedPurchasePrice`); sonst Mischpreis mit `(preis + Fracht + Versicherung) * calcFactor`. +Aussage: Das System soll den Artikel-EK aus Belegpreis zzgl. Fracht/Versicherung mit Kalkulationsfaktor fortschreiben, Sondervereinbarungen und Preisbindeflaggen ausnehmen. +Ergebnis: EK im Artikelstamm/Nebenlager aktualisiert oder bewusst unverändert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Warehousing\StockManagement\ArticleStockBL.cs, UpdateArticlePurchasePrice - Begründung: vollständige Preisbildungsregeln inkl. Ausnahmen +Prüfidee: Sondervereinbarung → EK unverändert; Flagge fest → unverändert; sonst Mischpreisformel prüfen. +Tracelinks: StRS-003, StRS-011 +Konsolidierung: Kandidat: Fracht/Versicherung-Aufschläge zentral abbilden +Übernahmewürdigkeit: übernehmen - abrechnungsrelevante Kernregel +Status: belegt + +--- + +ID: SwRS-020 +Titel: Validierte Protokollierung von Lagerumlagerungen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Logistikmitarbeiter +Vorbedingung: Umlagerung durchgeführt +Fakt: `StockBL.WriteStockRebookLog` validiert ArticleI3D>=1, Mitarbeiter, FromStore, ToStore als Guard-Cluster; Auslesen über GetStockRebookLogs; Hauptlager-Konvention I3D=-1. +Aussage: Das System soll Umlagerungen nur mit vollständigen Angaben protokollieren und die Protokolle filterbar bereitstellen. +Ergebnis: Vollständiger Log-Datensatz oder definierte Fehlermeldung je缺angabe. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Logistics\Warehousing\StockBL.cs, WriteStockRebookLog/GetMainWarehouse - Begründung: Validierung + Konvention implementiert +Prüfidee: Log ohne Ziellager → Fehler; vollständiger Log sichtbar. +Tracelinks: StRS-015 +Konsolidierung: Kandidat: Audit-Log-Musterfamilie (SwRS-023) +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-021 +Titel: Kunden-Produktmatrix mit Bewertungshistorie +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Key-Account-Manager +Vorbedingung: Kategorie/Produkt/Bewertung per I3D adressiert +Fakt: `ProductMatrixBL` kapselt CRUD in Result-Objekte mit NLog; Löschen nur nach Existenzprüfung; Entity `CustomerProductMatrixRatingChangeLog` führt Historie. +Aussage: Das System soll Kategorien/Produkte/Bewertungen der Kundenmatrix nur nach Existenzprüfung ändern und Bewertungsänderungen historisieren. +Ergebnis: Kein stiller Datenverlust; Fehler als Result plus Log. +Belege: + - [PRIMÄR] src\backend\Centron.BL\ProductMatrix\ProductMatrixBL.cs, DeleteProductMatrixCategory/GetCustomerProductMatrixRatingChangeLogByI3D - Begründung: Guard+Historie implementiert +Prüfidee: Delete mit unbekannter I3D → Fehlerresult ohne DB-Zugriff. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Result+Guard+Logger-Muster (Devices, Purchasing) vereinheitlichen +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-022 +Titel: Fertigungsaufträge nach Maschine/Maschinenart filterbar +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Produktionsplaner +Vorbedingung: Fertigungsaufträge mit Positionen vorhanden +Fakt: `ProductionOrderBL.CreateFilterExpression` verknüpft Filter über `f.ProductionOrderItems.Any(g => g.MachineI3D == ...)` bzw. MachineKindI3D. +Aussage: Das System soll Fertigungsaufträge nach Kopf-, Positions-, Maschinen- und Maschinenartfilter durchsuchbar liefern. +Ergebnis: Trefferliste anhand der Positionsmaschinen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Production\ProductionOrderBL.cs, CreateFilterExpression - Begründung: Filterkomposition inkl. Subquery +Prüfidee: Zwei Maschinen mit je einem Auftrag → Maschinenfilter liefert nur zugehörigen. +Tracelinks: StRS-001 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-023 +Titel: Geräteverwaltung mit Soft-Delete und Protokoll +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Servicemitarbeiter +Vorbedingung: Benutzer mit Mitarbeiterbezug +Fakt: `AccountDeviceBL.DeleteAccountDevice` setzt nur IsDeleted=true und schreibt AccountDeviceLog; Anlage pflegt CreatedBy/CreatedDate; Suche blendet Deleted standardmäßig aus. +Aussage: Das System soll Geräte nie physikalisch löschen, sondern soft-löschen und jede Änderung protokollieren. +Ergebnis: Rekonstruierbarer Geräteverlauf; gelöschte Geräte standardmäßig ausgeblendet. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Devices\AccountDeviceBL.cs, DeleteAccountDevice/WriteAccountDeviceLog - Begründung: Soft-Delete+Log implementiert + - [PRIMÄR] src\backend\Centron.BL\Devices\AccountDeviceBL.cs, SearchAccountDevices - Begründung: Default-Ausblendung +Prüfidee: Delete → Datensatz mit IsDeleted=1 vorhanden; Log enthält Löschtext. +Tracelinks: StRS-015 +Konsolidierung: Kandidat: Audit-Log-Musterfamilie +Übernahmewürdigkeit: übernehmen - BEFUND: Geräte werden als AccountDevice geführt, parallel existieren "Stammblätter/Assets" (Anlagenkonzept) -> Asset-Konsolidierung im Ziel prüfen +Status: belegt + +--- + +ID: SwRS-024 +Titel: Produktionsmanagement durchgehend lizenzgeprüft +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Benutzer ohne Produktionslizenz +Vorbedingung: Produktionsmaschinen/-aufträge vorhanden +Fakt: Jede öffentliche Methode von `ProductionBL`/`ProductionOrderBL` prüft `LicenseManager.Instance.HasLicense(LicenseGuids.ProductionManagement)` und wirft lokalisierte Exception sonst. +Aussage: Das System soll alle Lese-/Schreibzugriffe auf Produktionsdaten ohne Produktionslizenz verweigern. +Ergebnis: Kein Datenzugriff ohne Lizenz; lokalisierte Fehlermeldung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Production\ProductionBL.cs, GetProductionMachineByI3D (Guards in allen Methoden) - Begründung: Lizenz-Guard an Zugriffsstelle + - [PRIMÄR] src\backend\Centron.BL\Production\ProductionOrderBL.cs, SaveProductionOrder - Begründung: Guard vor Persistierung +Prüfidee: Lizenz simuliert entfernt → alle CRUD-Methoden werfen lokalisierte Exception. +Tracelinks: SyRS-003, StRS-004 +Konsolidierung: Kandidat: Lizenz-Guard-Familie (SwRS-008) +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-025 +Titel: Handelspool-Artikelimport aus Distributor-XML +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: TradePool-Anwender, Distributor (Datei) +Vorbedingung: XML-Datei nach definiertem Schema vorhanden +Fakt: `TradePoolBL.StartTradeImport` ruft je Datei `TradePoolXmlLogic.Initialize/ImportTradeArticles`; Schemakonstanten ROOT_NODE "ArticleImport" mit HerstCode/ArticleEK/ArticleStock/ArticleEAN; Suche mit Paging/Filter. +Aussage: Das System soll Handelspool-Artikeldateien dateiweise gegen das definierte XML-Schema einlesen (EK, Bestand, EAN) und durchsuchbar persistieren. +Ergebnis: Importierte, filterbare TradePool-Artikel. +Belege: + - [PRIMÄR] src\backend\Centron.BL\TradePool\Core\TradePoolXmlLogic.cs, Initialize/ArticleNames - Begründung: Schemafestlegung + - [PRIMÄR] src\backend\Centron.BL\TradePool\TradePoolBL.cs, StartTradeImport - Begründung: Importanstoß je Datei +Prüfidee: Musterdatei mit 2 Artikeln → Liste zählt 2; fehlerhaftes XML → definierter Fehler. +Tracelinks: SyRS-046, StRS-001 +Konsolidierung: Kandidat: DateiImport-Musterfamilie (Artikelimport) +Übernahmewürdigkeit: Sonderfall - plattformspezifisches Distributor-XML +Status: belegt + +--- + +ID: SwRS-026 +Titel: Automatische Nummernvergabe für Account, Kunde und Lieferant +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: Zuverlässigkeit (ISO 25010) +Akteur: Vertriebs-/Einkaufsmitarbeiter +Vorbedingung: Account-Neuanlage (I3D<=0), Neuanlagerechte vorhanden +Fakt: `AccountBL.SaveAccount` vergibt Number über NumberGroupEnum.Account (Zeile 509) plus separate Nummern für CustomerData (559) und SupplierData (592); Buchungsnummer optional per AppSetting mit Präfix. +Aussage: Das System soll bei Account-Neuanlage die Nummern aus den Nummernkreisen Account/Kunde/Lieferant automatisch vergeben und die Buchungsnummer regelbasiert ableiten. +Ergebnis: Drei eindeutige Nummern ohne manuelle Eingabe. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Accounts\AccountBL.cs, SaveAccount - Begründung: Vergabe im Transaktionspfad verdrahtet +Prüfidee: Account mit Kunde+Lieferant anlegen → drei inkrementierte Kreise; Präfix-Setting greift. +Tracelinks: StRS-016, SyRS-044 +Konsolidierung: Kandidat: Nummernkreis-Kapitel (StRS-016) +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-027 +Titel: Genau eine Standardadresse je Account +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: Zuverlässigkeit (ISO 25010) +Akteur: System (AccountAddressBL) +Vorbedingung: Aktive Adresse wird IsDefault=true gespeichert +Fakt: `AccountAddressBL` (Zeilen 452-459) setzt beim Speichern aller anderen aktiven Adressen desselben Accounts IsDefault auf false. +Aussage: Das System soll beim Setzen einer Standardadresse alle bisherigen demarkieren (Invariante: höchstens eine aktive Default-Adresse). +Ergebnis: Eindeutige Standardadresse pro Account. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Accounts\AccountAddressBL.cs, Default-Reset-Logik - Begründung: Invariante im Speicherpfad +Prüfidee: Zweite Adresse auf Default → erste wird false (DB-Prüfung). +Tracelinks: StRS-005 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - klare testbare Invariante +Status: belegt + +--- + +ID: SwRS-028 +Titel: Branchenzuweisungen atomar ersetzen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: Zuverlässigkeit (ISO 25010) +Akteur: Vertriebsmitarbeiter +Vorbedingung: AccountI3D > 0, Branchenliste nicht null +Fakt: `BusinessLineBL.SaveAccountBusinessLines` löscht in einer Transaktion alle Zeilen des Accounts und legt die übergebenen neu an. +Aussage: Das System soll die Branchenmenge eines Accounts stets vollständig (Replace-and-Save) in einer Transaktion persistieren. +Ergebnis: Keine halbierten Zuweisungsstände bei Abbruch. +Belege: + - [PRIMÄR] src\backend\Centron.BL\CustomerArea\BusinessLineBL.cs, SaveAccountBusinessLines (Zeilen 35-60) - Begründung: Delete-all/insert-all mit StartTransaction +Prüfidee: Save mit Folgefehler → alte Zuweisungen unverändert. +Tracelinks: StRS-005 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-029 +Titel: Explizite Zuordnung Employee -> AppUser +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: Sicherheitsfunktionalität (ISO 25010) +Akteur: System/Administration +Vorbedingung: Employee und AppUser existieren +Fakt: `AppUserBL.GetAppUserObjectForEmployee(employeeId)`/`GetAppUserI3DForEmployee` mappen 1:1; `SaveOrUpdateAppUser` führt separates newPassword-Argument. +Aussage: Das System soll Personalstamm und Login über definierte Mapping-Methoden verknüpfen, sodass Passwörter ohne Personaländerung verwaltet werden können. +Ergebnis: Saubere Identitätstrennung; keine Vermischung von Personal- und Zugangsdatenpflege. +Belege: + - [PRIMÄR] src\backend\Centron.BL\EmployeeArea\AppUserBL.cs, GetAppUserObjectForEmployee - Begründung: getrennte Save-Pfade +Prüfidee: AppUser sperren → Employee-Daten bleiben speicherbar, Login scheitert. +Tracelinks: StRS-007 +Konsolidierung: Kandidat: Identitätsmodell (Employee/AppUser/Web-Account) im Ziel vereinheitlichen +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-030 +Titel: Filialauswahl mit Pseudo-Einträgen Hauptsitz/Alle Filialen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Benutzer in Filialfiltermasken +Vorbedingung: Filial-Auswahlliste wird geöffnet +Fakt: `BranchBL.GetBranchesForSelection` ergänzt "(Alle Filialen)" (ID -2) und statischen Hauptsitz (ID 0); `IsBranchEqual` setzt alle IDs <= 0 gleich. +Aussage: Das System soll in Filialauswahlen einheitliche Sonderoptionen mit reservierten Kennungen bereitstellen und sie bei Vergleichen als "keine Filiale" gleichsetzen. +Ergebnis: Einheitliche Filialfilterung ohne je Modul eigene null-Behandlung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Company\BranchBL.cs, GetBranchesForSelection/GetHeadquarter/IsBranchEqual - Begründung: magische IDs 0/-2 explizit kodiert +Prüfidee: IsBranchEqual(0,-99) → true; Liste enthält genau einen "Alle Filialen"-Eintrag. +Tracelinks: StRS-010 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - magische IDs durch enumerierte Werte ersetzen +Status: belegt + +--- + +ID: SwRS-031 +Titel: Firmenübersicht als reines Lese-API +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: Wartbarkeit (ISO 25010) +Akteur: Sachbearbeiter +Vorbedingung: CompanyFilter gesetzt +Fakt: `CompanyBL` (32 Zeilen) besitzt exakt eine öffentliche Methode LoadCompanies(CompanyFilter) mit Delegation an ICompanyRepository; keine Save-/Delete-Methode. +Aussage: Das System soll Firmeninformationen in diesem Modul ausschließlich lesend als gefilterte Preview bereitstellen. +Ergebnis: Kapseltes schreibgeschütztes Firmen-Lese-API. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\CompanyInformations\CompanyBL.cs, LoadCompanies - Begründung: vollständige Klasseninspektion +Prüfidee: API-Fläche prüfen: keine Mutation-Methode vorhanden. +Tracelinks: StRS-005, StRS-010 +Konsolidierung: Kandidat: Company vs. Mandant vs. Filiale - drei Organisationskonzepte zusammenführen +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-032 +Titel: Abteilungen benutzerbezogen laden und pflegen (Parallelimplementierung) +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Mitarbeiteradmin +Vorbedingung: AppUser authentifiziert +Fakt: `EmployeeDepartmentBL` (Administration\Employees) stellt Get/UpdateEmployeeDepartments(AppUser, ...) bereit; eine zweite Implementierung liegt unter EmployeeArea. +Aussage: Das System soll Abteilungsstrukturen benutzerkontextbezogen laden/aktualisieren; die Doppelimplementierung ist auf eine maßgebliche Quelle zu konsolidieren. +Ergebnis: Benutzerabhängige Abtellsicht, eine Datenquelle. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Employees\EmployeeDepartmentBL.cs, GetEmployeeDepartments/UpdateEmployeeDepartments - Begründung: AppUser-Parameter in Getter/Updater + - [PRIMÄR] src\backend\Centron.BL\EmployeeArea\EmployeeDepartmentBL.cs - Begründung: Paralleldatei belegt Doppelkonzept +Prüfidee: Zwei-User-Vergleich: Admin sieht alle, Normalnutzer nur freigegebene. +Tracelinks: StRS-007 +Konsolidierung: Kandidat: die beiden EmployeeDepartmentBL zusammenführen +Übernahmewürdigkeit: Sonderfall - eine Parallelimplementierung einziehen +Status: belegt + +--- + +ID: SwRS-033 +Titel: Persistente persönliche Mitarbeitereinstellungen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: Benutzerfreundlichkeit (ISO 25010) +Akteur: Mitarbeiter (UI-Benutzer) +Vorbedingung: Region/Sektion/Key definiert +Fakt: `EmployeeSettingBL.Get/SetEmployeeSettingValueFromCurrentUser(key, region, section, defaultValue)` liest/schreibt Ini-Werte des aktuellen Benutzers; paralleles Konzept EmployeeUserSettingsBL im EmployeeArea. +Aussage: Das System soll persönliche, in Region/Sektion gegliederte Einstellungen mit Default-Fallback je Mitarbeiter持久 halten. +Ergebnis: UI-/Prozesseinstellungen überleben Sitzungswechsel. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Employees\EmployeeSettingBL.cs, Get/SetEmployeeSettingValueFromCurrentUser - Begründung: Schlüssel/Default-Semantik in Signatur + - [SEKUNDÄR] src\backend\Centron.BL\EmployeeArea\EmployeeUserSettingsBL.cs - Begründung: Doppelkonzept +Prüfidee: Unbekannter Key → defaultValue; nach Set → neuer Wert. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: EmployeeSetting vs. EmployeeUserSettings zusammenführen +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-034 +Titel: Konditionstextvorschau gegen echte Testrechnung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: Fehlertoleranz (ISO 25010) +Akteur: Buchhalter/Einkaufssachbearbeiter +Vorbedingung: Mind. eine Rechnung vorhanden; Skontostaffeln übergeben +Fakt: `AssetConditionBL.GetAssetConditionTextPreview` rendert Skonto-Platzhalter gegen `ReceiptInvoiceBL.GetInvoiceForAssetConditionTextPreview` und wirft Fehler ohne Rechnungsbestand. +Aussage: Das System soll den Zahlungskonditionstext mit Platzhaltern gegen eine echte Testrechnung als Vorschau rendern und ohne Datenbasis verständlich fehlschlagen. +Ergebnis: Verifizierbarer Konditionstext vor Verwendung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Masterdata\AssetConditionBL.cs, GetAssetConditionTextPreview (Zeilen 34-55) - Begründung: Vorschau+Feherpfad implementiert +Prüfidee: Frisches System → Fehlermeldung; nach erster Rechnung → korrekt ersetzt. +Tracelinks: StRS-011 +Konsolidierung: Kandidat: Textbaustein-/Ersetzungssystem (SwRS-108) ankoppeln +Übernahmewürdigkeit: Sonderfall - Vorschau hängt von Rechenbestandsdaten ab (Testrechnungs-Workaround) +Status: belegt + +--- + +ID: SwRS-035 +Titel: Preis- und Rabatttransparenz im Shop +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Endkunde (Web-Account) +Vorbedingung: Artikel mit ReduceListPrice-Sonderpreis und Sondervereinbarung +Fakt: `ReceiptCartBL.SearchArticles` liefert ListPrice/ListPriceDiscountInPercent nur bei SpecialPriceKind.ReduceListPrice; UI-Flyout "Listenpreis/Rabatt" plus Hinweis "Und weitere Rabatte". +Aussage: Das System soll im Shop den kundenspezifischen Nettopreis anzeigen und bei Listenpreisreduktion Listenpreis/Rabatt nachvollziehbar ausweisen. +Ergebnis: Verbindliche Preise ohne Offenlegung der Kalkulation. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptCartBL.cs, Zeilen 178-206 - Begründung: serverseitige Preiserzeugung + - [SEKUNDÄR] src\nexus\CentronNexus\WebCart\WebCartShopPage.razor, Zeilen 164-211 - Begründung: Anzeige nur aus DTO +Prüfidee: CalculatedPrice gegen Referenzrechnung (inkl. CurrencyFactor) validieren. +Tracelinks: SyRS-015, StRS-002 +Konsolidierung: Kandidat: mit SyRS-015/SyRS-017 zu WebCart-Preisstellung +Übernahmewürdigkeit: übernehmen +Status: HYPOTHESE - die Priorisierung von Sondervereinbarungen innerhalb der Preisfindung wurde nicht vollständig nachverfolgt + +--- + +ID: SwRS-036 +Titel: SelfCare-Formular erzeugt Helpdesk-Ticket +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Endkunde (Web-Account) +Vorbedingung: Ticketvorlage/Formular veröffentlicht +Fakt: `CustomerPortalFormFillPage.razor` ruft `CentronService.CreateHelpdeskFromHelpdeskPattern(ticketPattern)` (Zeile 231); `SelfCareBL` verwaltet SelfCareForm/State/Trigger/Action; `WebRequestPageBL` liefert veröffentlichte Seiten (filter.Published). +Aussage: Das System soll das Ausfüllen konfigurierter SelfCare-Formulare ermöglichen und daraus automatisch ein Helpdesk-Ticket ableiten; Veröffentlichung per Published-Schalter. +Ergebnis: Standardisierte Kundenanliegen strukturiert im Helpdesk. +Belege: + - [PRIMÄR] src\backend\Centron.BL\SelfCare\SelfCareBL.cs, Zeilen 47-149 - Begründung: Formular-/Triggermodell implementiert + - [SEKUNDÄR] src\nexus\CentronNexus\WebCart\CustomerPortalFormFillPage.razor, Zeilen 1, 148, 231 - Begründung: Aufrufkette +Prüfidee: Veröffentlichtes Formular absenden → Ticket mit Mustereferenz; unveröffentlichtes nicht sichtbar. +Tracelinks: SyRS-016, StRS-002 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen +Status: HYPOTHESE - die Trigger→Ticket-Ausführungskette (Aktionen) wurde nicht vollständig verfolgt + +--- + +ID: SwRS-037 +Titel: Weblink-Aktion legt CRM-Aktivität für den Betreuer an +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System (Weblink-Ausführung) +Vorbedingung: CRMEntry-Aktion konfiguriert; Zielkontakt existiert +Fakt: `WebLinkActionAccountActivityHandler` meldet Type CRMEntry, scheitert mit Result.AsError ohne Kontakt oder ohne "advisor 1" und loggt Fehler per NLog. +Aussage: Das System soll bei einer CRMEntry-Weblink-Aktion eine Kontaktaktivität mit Betreuerzuordnung anlegen und Konfigurationsfehler protokollieren statt verschlucken. +Ergebnis: Nachvollziehbare CRM-Aktivitäten; Fehler sichtbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\WebLinks\WebLinkActionAccountActivityHandler.cs, Zeilen 24-59 - Begründung: Ausführungsstelle inkl. Betreuer-Auflösung + - [SEKUNDÄR] src\backend\Centron.BL\WebLinks\WebLinkBL.cs - Begründung: Handler-Registrierung/Options-Parsing +Prüfidee: Kontakt ohne Adviser1 → Result-Error + Log; mit Adviser1 → Aktivität angelegt. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: WebLinks-/SimpleUrl-Familie (SwRS-124) +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-038 +Titel: Versionsauskunft des Webservices +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Web-Clients (Nexus/Frontends) +Vorbedingung: Webservice erreichbar +Fakt: `VersionBL.GetWebserviceVersion()` liefert die Assemblyversion (einzige Methode, WebVersion\VersionBL.cs Zeilen 10-14). +Aussage: Das System soll die aktuelle Webservice-Version für kompatible Web-Clients und den Support auslesbar bereitstellen. +Ergebnis: Serverversion identifizierbar (z.B. Versions-Check des Portals). +Belege: + - [PRIMÄR] src\backend\Centron.BL\WebVersion\VersionBL.cs, GetWebserviceVersion - Begründung: vollständiger Funktionsumfang der Klasse +Prüfidee: Version-Endpunkt gegen AssemblyVersion vergleichen. +Tracelinks: StRS-001 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen (randständig) +Status: belegt + +--- + +ID: SwRS-039 +Titel: Web-Einstellungen strikt nach Login-Art getrennt +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Web-Account-Benutzer, Mitarbeiter +Vorbedingung: Persönliche/globale Web-Einstellungen vorhanden +Fakt: `WebSettingBL.GetWebSettingFromCurrentUser` verzweigt auf IsWebAccountLogin (WebAccountI3D- vs. EmployeeI3D-Filter) mit Fallback auf globale Settings; `WebMenuConfigBL.DoBeforeSave` validiert Caption/Position und vergibt Max+1. +Aussage: Das System soll Web-Einstellungen je Login-Art getrennt laden und Menüeinträge nur bei gültiger Beschriftung/Position speichern. +Ergebnis: Keine Vermischung von Kunden- und Mitarbeiter-Einstellungen; konsistente Menüsortierung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\WebSuite\Administration\Settings\WebSettingBL.cs, Zeilen 29-59 - Begründung: einzige Lesequelle für User-Settings + - [SEKUNDÄR] src\backend\Centron.BL\WebSuite\Administration\Settings\WebMenuConfigBL.cs, Zeilen 34-50 - Begründung: Validierung+Auto-Position +Prüfidee: WebSetting mit WebAccountI3D als Mitarbeiter abfragen → unsichtbar; Menü ohne Caption → Error. +Tracelinks: StRS-006, StRS-001 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-040 +Titel: Warenkorb-Prüfstufe und Kundenadmin-Oberfläche +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Endkunde, Kundenadministrator +Vorbedingung: Web-Account mit Rechten gepflegt +Fakt: `UserViewModel` führt HasCheckCartRight/HasOrderCartRight/HasCustomerAdministratorRight und Passwortmindestlänge 8; `WebCartAdminPage.razor` ist über `[AuthorizeLicense(WebCart2)]` + `[AuthorizeWebRight(CUSTOMERADMINISTRATOR)]` geschützt. +Aussage: Das System soll die Kundenbenutzerverwaltung (Rechte, Passwörter mind. 8 Zeichen) dem Kundenadministrator vorbehalten und die Bestell-/Prüfrechte in der Maske abbilden. +Ergebnis: Self-Service-Verwaltung ohne c-entron-Eingriff; Rechtezuweisung nach Vier-Augen-Vorbild. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptCartBL.cs, Zeilen 859-864 - Begründung: serverseitig erzwungene Bestell-/Prüfrechtprüfung (Durchsetzungsstelle der Prüfstufe) + - [SEKUNDÄR] src\nexus\CentronNexus\WebCart\Helpers\UserViewModel.cs, Zeilen 33, 52-56 - Begründung: Rechte-/Kennwortregeln + - [SEKUNDÄR] src\nexus\CentronNexus\WebCart\WebCartAdminPage.razor, Zeilen 3-4 - Begründung: Admin-Gate +Prüfidee: Nicht-Admin erreicht Adminseite nicht; Kennwort < 8 Zeichen wird abgewiesen. +Tracelinks: SyRS-018, StRS-002 +Konsolidierung: Kandidat: Portal-Rechtefamilie (SwRS-007) +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-041 +Titel: Täglicher Devisenkursimport aus dem EZB-Feed +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: Interoperabilität (ISO 25010) +Akteur: Buchhaltung/Hintergrundjob +Vorbedingung: Aktive Länder mit CurrencyISO; EZB-XML erreichbar +Fakt: `CountryBL.UpdateCurrencyRateByRateDictionary` lädt "http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml", schreibt Eurokurse auf alle Länder gleicher ISO; CHF-Sonderweg bei Defaultland Schweiz. +Aussage: Das System soll Devisenkurse automatisiert aus dem offiziellen EZB-Feed übernehmen und alle Länder einer Währung auf denselben Kurs ziehen. +Ergebnis: Konsistente, tagesaktuelle Umrechnungskurse. +Belege: + - [PRIMÄR] src\backend\Centron.BL\CountryArea\CountryBL.cs, UpdateCurrencyRateByRateDictionary (Zeilen 103-155) - Begründung: Import+CHF-Sonderweg belegt +Prüfidee: Mock-Feed: gleiche ISO → gleicher Kurs; Länder ohne ISO übersprungen. +Tracelinks: StRS-009 +Konsolidierung: Kandidat: URL/Konstanten konfigurieren +Übernahmewürdigkeit: Workaround - hartkodierte URL und Stringvergleich "Schweiz" modernisieren +Status: belegt + +--- + +ID: SwRS-042 +Titel: Inlandsland aus dem Default-Mandanten ableiten +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: System (Preis-/Steuerlogik) +Vorbedingung: Default-Mandator mit Land; ein Land als Default markiert +Fakt: `CountryBL.GetInlandCountry` liefert `MandatorBL.GetDefaultMandator().Country` mit TODO "Check the country of the branch"; `GetDefaultCountry` filtert f.Default. +Aussage: Das System soll das für Preise/Steuern maßgebliche Inlandsland deterministisch ableiten und die offene Filialland-Frage lösen. +Ergebnis: Deterministische Länderbasis für Belege. +Belege: + - [PRIMÄR] src\backend\Centron.BL\CountryArea\CountryBL.cs, GetInlandCountry (Zeilen 190-207) - Begründung: Implementierung + TODO als bekannte Lücke +Prüfidee: Default-Mandant/Land wechseln → Inlandslogik neuer Belege folgt. +Tracelinks: StRS-009 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen (TODO als offene Anforderung) +Status: belegt + +--- + +ID: SwRS-043 +Titel: Ticket-Statuswechsel per Drag-and-Drop im Kanban +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: ServiceBoard-Mitarbeiter +Vorbedingung: Ticket-Cache geladen, Kanban-View gruppiert +Fakt: `KanbanBucket.razor.UpdateTicketProperty` ruft bei HelpdeskState `HelpdeskUpdateStatus` und bei Closed-Bucket `CloseHelpdesk` (Zeilen 157-169); Bearbeiter-Drop via `HelpdeskUpdateEditors`. +Aussage: Das System soll beim Ziehen einer Ticketkarte den Helpdesk-Datensatz im Backend aktualisieren und beim Drop in Closed den Abschluss anstoßen. +Ergebnis: Persistierter Statuswechsel; Board aktualisiert via Callback. +Belege: + - [PRIMÄR] src\nexus\CentronNexus\ServiceBoard\CachedTicketList\Components\KanbanBucket.razor, OnDropAsync/UpdateTicketProperty - Begründung: Backend-Aufrufe direkt belegt + - [SEKUNDÄR] CachedKanbanBoard.razor (Buckets aus GetHelpdeskStates) - Begründung: datengetriebene Status +Prüfidee: Karte "Offen"→"In Bearbeitung": ERP-Status geändert; Drop auf Closed löst Abschluss aus. +Tracelinks: SyRS-043, StRS-013 +Konsolidierung: Kandidat: Status-Automatik in TicketDetailsPreview mit konsolidieren; Prototyp KanbanPage.razor verwerfen +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-044 +Titel: ServiceBoard-Seiten durch Login-, Lizenz- und Portschutz +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: Sicherheitsfunktionalität (ISO 25010) +Akteur: Mitarbeiter ohne Lizenz/Recht +Vorbedingung: Benutzer angemeldet; Lizenzen/Rechte gepflegt +Fakt: `ServiceBoard\_Imports.razor` setzt global [AuthorizeLoginUser], [AuthorizeLicense(ServiceBoardWebDev)], [AuthorizeHostPort]; Settings verlangt [AuthorizeRightId(SETTINGS)]; MSP-Blöcke in Ticketdetails lizenzumschlossen. +Aussage: Das System soll ServiceBoard-Seiten nur angemeldeten Mitarbeitern mit passender Lizenz auf dem Host-Port freigeben und Einzelfunktionen zusätzlich an Lizenz/Recht binden. +Ergebnis: Unauthorized-Seite bzw. ausgeblendete Funktionsbereiche für Nichtberechtigte. +Belege: + - [PRIMÄR] src\nexus\CentronNexus\ServiceBoard\_Imports.razor (globale Attribute via AuthorizeRouteView) - Begründung: erzwungene Seitenschutzkette + - [PRIMÄR] src\nexus\CentronNexus\Settings\_Imports.razor - Begründung: Rechts-Gate +Prüfidee: Ohne SETTINGS-Recht /settings → Unauthorized; ohne MSP-Lizenz kein MSP-Block. +Tracelinks: SyRS-007, SyRS-003, StRS-013 +Konsolidierung: Kandidat: mit SyRS-007 zu AuthN/AuthZ-Gruppe +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-045 +Titel: Automatische Status-Defaults bei Anlage und Übernahme +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Kunde (SelfCare), Bearbeiter +Vorbedingung: Ticket wird angelegt oder allein übernommen +Fakt: `HelpdeskBL.DoBeforeStoreTrans` setzt bei Web-Neuanlage `HelpdeskAfterOpenDefaultState` (Zeilen 510-542); `UpdateHelpdeskBL` setzt bei Allein-Übernahme `HelpdeskAfterInheritDefaultState` (Zeilen 212-228); weiterer Default nach Mail an Kunde (HelpdeskSettingsBL:1148). +Aussage: Das System soll beim Anlegen/Übernehmen/Mailversand den Ticketstatus automatisch auf den je Konstellation konfigurierten Default setzen. +Ergebnis: Tickets erscheinen stets in der korrekten Liste; Kundenfreigabeprozess steuerbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs, DoBeforeStoreTrans - Begründung: durchsetzender Speicher-Hook + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\UpdateHelpdeskBL.cs, Zeilen 212-228 - Begründung: Übernahme-Automatik +Prüfidee: Web-Ticket anlegen → konfigurierter Default; Bearbeiterliste auf sich selbst → Inherit-Default. +Tracelinks: SyRS-043, StRS-013 +Konsolidierung: Kandidat: alle HelpdeskAfter*-Settings inventarisieren +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-046 +Titel: Fertigungsübersicht mit Arbeitsplatz- und Mitarbeiterauswahl +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Fertigungsmitarbeiter/Schichtleiter +Vorbedingung: Produktionsdaten über Webservice erreichbar +Fakt: `ProductionOrderOverView.razor` (/production/overview) bindet ProductionMachineKindDTO an ComboBox, persistiert Auswahl via ProtectedSessionStorage; WorkStepTemplateComponent rendert Schritt-Vorlagen. +Aussage: Das System soll Fertigungsbenutzern eine personen-/arbeitsplatzbezogene Übersicht mit wiederverwendeter Sitzungsauswahl und Arbeitsschritt-Vorlagen bieten. +Ergebnis: Personenbezogene Fertigungsansicht über Session stabil. +Belege: + - [PRIMÄR] src\nexus\CentronNexus\ProductionOrderManagement\Pages\ProductionOrderOverView.razor, Zeilen 1-45 - Begründung: einzige Seite des Moduls gelesen +Prüfidee: Auswahl + Reload bleibt erhalten; Templates gefüllt. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: gegen WPF-Fertigungsmasken abgrenzen +Übernahmewürdigkeit: Sonderfall - Seite unausgereift (Codepage-Artefakte, Testbild), nur als Gerüst übernehmbar +Status: HYPOTHESE - fachliche Vervollständigung unklar; Rückfrage an Fachbereich nötig + +--- + +ID: SwRS-047 +Titel: Lückenlose Ticketstatus-Historie im Speicherpfad +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Bearbeiter, Auditor +Vorbedingung: Bestehendes Ticket wird gespeichert +Fakt: `HelpdeskBL.SetHelpdeskAction` vergleicht Origin-Kompaktdatensatz und schreibt History "Status wurde von ... auf ... geändert"; `HelpdeskCloseBL` schreibt Historie wegen AutoFlush manuell nach; Bei Fälligkeitsänderung wird EscalationLevel auf 0 gesetzt. +Aussage: Das System soll jede Ticketstatus-/Fälligkeitsänderung automatisch mit Alt-/Neuwert und Benutzer historisieren. +Ergebnis: Vollständige Ticket-Historie; Nexus-Benachrichtigungen mit Statusinformation. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs, SetHelpdeskAction (Zeilen 558-609) - Begründung: Durchsetzung in DoBeforeStoreTrans + - [SEKUNDÄR] HelpdeskCloseBL.cs (Zeilen 303-356) - Begründung: Sonderfall Schließen +Prüfidee: Status ändern/speichern → Historieneintrag mit beiden Statusnamen und Benutzer. +Tracelinks: SyRS-043, StRS-013, StRS-015 +Konsolidierung: Kandidat: Auditgruppe (SwRS-093) +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-048 +Titel: Prozessweiter Ticketcache im Nexus (Singleton + HostedService) +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: Performance-Effizienz (ISO 25010) +Akteur: Alle Nexus-Benutzer +Vorbedingung: TicketCacheConfig vorhanden +Fakt: `TicketCacheService` hält ObservableCollection mit Locks, `_lastChangeDate`, `SynchronizeTickets()/CheckTickets()`, WebserviceDeltaTime; konsumiert von CachedTicketListPage/Dashboard. +Aussage: Das System soll Tickets prozessweit, threadsicher und incrementell synchronisiert vorhalten, damit UI-Views ohne synchrone Remotecalls arbeiten. +Ergebnis: Schnelle Listen/Kanbans; Ladezustand kommuniziert. +Belege: + - [PRIMÄR] src\nexus\CentronNexus\Shared\Services\TicketCacheService.cs, Zeilen 26-56 - Begründung: Singleton/Lock-Struktur belegt +Prüfidee: LoadTicketsOnStart im Log; ERP-Änderung nach Intervall ohne Reload sichtbar. +Tracelinks: SyRS-037, StRS-013 +Konsolidierung: Kandidat: Caching-Strategie mit Statistik-Caches (SyRS-042) +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-049 +Titel: NexusNotifications je Empfänger verwalten (Raw-SQL) +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Nexus-Webservice im Auftrag des Hosts +Vorbedingung: NexusNotification-Datensätze je UserI3D/UserKind vorhanden +Fakt: `NexusNotificationsBL` bietet GetByFilter, MarkAsRead/AsSeen, MarkAll... (Raw-SQL mit UserI3D/UserKind), Delete; `NotificationsHubHelper.SendNexusNotification` als statische Versandbrücke. +Aussage: Das System soll Benachrichtigungen pro Empfänger (lesen/gesehen/löschen) verwalten und neue über eine zentrale Brücke an den Push-Kanal übergeben. +Ergebnis: Konsistenter Read-/Seen-Status; Entkopplung der Fachmodule vom Kanal. +Belege: + - [PRIMÄR] src\backend\Centron.BL\NexusNotifications\NexusNotificationsBL.cs, Zeilen 35-115 - Begründung: AsSeen/AsRead-Unterscheidung+Filter implementiert + - [SEKUNDÄR] NotificationsHubHelper.cs - Begründung: Versandbrücke +Prüfidee: MarkAllAsSeen nur für Mitarbeiter A → nur dessen Sichten betroffen; String-SQL-Werte sind interne ints. +Tracelinks: SyRS-038, StRS-013 +Konsolidierung: Kandidat: mit SwRS-050 zu End-to-End-Benachrichtigung +Übernahmewürdigkeit: übernehmen - Raw-SQL-Komposition restriktivieren +Status: belegt + +--- + +ID: SwRS-050 +Titel: NotificationHub filtert pro Benutzer und unterscheidet Schedule-Typen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Nexus-Host (SignalR-Empfänger) +Vorbedingung: SignalR-Verbindung steht +Fakt: Singleton-`NotificationHub` filtert pro UserI3D und trennt Schedule-Benachrichtigungen via `ShouldHandleNotification` (Zeilen 313-331); Reconnect-Schleife 1 Minute. +Aussage: Das System soll eingehende Notifications gezielt dem zuständigen Benutzer/Circuit zuordnen und irrelevante (Schedule) getrennt behandeln. +Ergebnis: Relevante Badges ohne Polling; keine Crossuser-Leaks. +Belege: + - [PRIMÄR] src\nexus\CentronNexus\Shared\Services\NotificationHub.cs, Zeilen 29-88, 313-331 - Begründung: Filterlogik gelesen +Prüfidee: Zwei Benutzer verbunden → jeder erhält nur eigene Notifications. +Tracelinks: SyRS-038, StRS-013 +Konsolidierung: Kandidat: mit SwRS-049/SyRS-038 +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-051 +Titel: Nur lokale Redirect-Ziele bei An-/Abmeldung (Open-Redirect-Schutz) +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: Sicherheitsfunktionalität (ISO 25010) +Akteur: _AuthController bei returnUrl-Verarbeitung +Vorbedingung: Aufruf mit returnUrl-Query-Parameter +Fakt: `AuthController.GetSafeReturnUrl` prüft `Url.IsLocalUrl(returnUrl)` und lehnt nicht-lokale URLs ab (Kommentar verweist auf CWE-601); Logout wählt je Login-Typ sicheren Default. +Aussage: Das System soll bei allen Authentifizierungsweiterleitungen nur lokale Ziel-URLs akzeptieren und sonst zur Anwendungsroot/Loginseite umleiten. +Ergebnis: Kein Redirect auf fremde Domains; Warnlog bei Abweisung. +Belege: + - [PRIMÄR] src\nexus\CentronNexus\Shared\Auth\AuthController.cs, GetSafeReturnUrl (Zeilen 247-259) - Begründung: durchsetzende Methode vor jeder RedirectUri-Verwendung +Prüfidee: returnUrl=https://evil.example → Landung auf / statt extern; Logeintrag. +Tracelinks: SyRS-007, StRS-004 +Konsolidierung: Kandidat: in Auth-Sicherheitsgruppe (SyRS-007) integrierbar +Übernahmewürdigkeit: übernehmen - explizit codierter Sicherheitszweck +Status: belegt + +--- + +ID: SwRS-052 +Titel: Ticket-Ansichten mit Besitzer- und Namensregeln +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Mitarbeiter oder Web-Account (Inhaber) +Vorbedingung: View-Konfiguration (Filter, Buckets) liegt vor +Fakt: `NexusTicketViewBL.GetUserI3D/GetCreatedByObjectKind` unterscheiden WebAccount vs. Employee (geteilter I3D-Nummernbereich laut Code-Doku); `GlobalViewWithSameNameExists` und `IsGlobalViewUsedByOthers` schützen globale Views. +Aussage: Das System soll Ticketansichten objekteartbezogen einem Inhaber zuordnen, globale Views nur mit Namensunikat zulassen und Löschen gegen Fremdreferenzen sichern. +Ergebnis: Korrekte View-Inhaberschaft; keine Namens-/Referenzkonflikte. +Belege: + - [PRIMÄR] src\backend\Centron.BL\NexusTicketViews\NexusTicketViewBL.cs, Zeilen 21-97 - Begründung: alle Prüfungen in der BL +Prüfidee: WebAccount und Employee mit gleicher I3D-Nummer → getrennte Views; zweiter globaler View gleichen Namens → abgewiesen. +Tracelinks: StRS-013, StRS-007 +Konsolidierung: Kandidat: View-Konfigurationslogik des CachedKanbanBoard verschmelzen +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-053 +Titel: Ticketauthentifizierungs-Handler als Durchsetzungsstelle +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: ASP.NET-Authentifizierungspipeline +Vorbedingung: Request mit Ticket/Header-Token +Fakt: `TicketAuthenticationHandler.HandleAuthenticateAsync` liest Token (Header/Query), ruft ValidateTicketOrAccessToken und setzt Claims (NameIdentifier, UserIdentifier, AuthenticationTypeIdentifier) oder AuthenticateResult.Fail. +Aussage: Das System soll die Ticket-/Token-Prüfung zentral im Authentifizierungs-Handler bündeln und daraus die Benutzer-Claims ableiten. +Ergebnis: Einheitliche Identität für alle Controller; ungültige Nachweise ohne Claims. +Belege: + - [PRIMÄR] src\webservice\Centron.Host\AspNetCore\TicketAuthenticationHandler.cs, HandleAuthenticateAsync - Begründung: Durchsetzungsstelle +Prüfidee: Gefälschtes Ticket → Fail ohne Claims; gültiges → korrekte Claims. +Tracelinks: SyRS-006, StRS-004 +Konsolidierung: Kandidat: mit SyRS-006 +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-054 +Titel: Client-Kontext (IP, API-Methode) in der Access-Token-Validierung +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Authentifizierungsdienst +Vorbedingung: Token liegt vor; IP/Methode ermittelbar +Fakt: `TicketAuthenticationHandler` ermittelt Client-IP (X-Forwarded-For/X-Real-IP/RemoteIpAddress) und API-Methode ("GET /pfad") und gibt beides an `AuthenticationTicketBL.GetAuthTicketInfo(token, ip, apiMethod)` weiter (Ticket zuerst, dann AccessTokenBL.ValidateToken). +Aussage: Das System soll bei der Tokenvalidierung den Verbindungskontext (IP, Methode) auswerten und Ticket- von Access-Token-Authentifizierung unterscheiden. +Ergebnis: Nachvollziehbare, kontextbezogene Token-Nutzung. +Belege: + - [PRIMÄR] src\webservice\Centron.Host\AspNetCore\TicketAuthenticationHandler.cs, GetClientIpAddress/GetApiMethod/ValidateTicketOrAccessToken - Begründung: Kontextweitergabe belegt + - [SEKUNDÄR] src\backend\Centron.BL\Administration\Logins\AuthenticationTicketBL.cs, GetAuthTicketInfo - Begründung: Reihenfolge Ticket→Token +Prüfidee: Access-Token von anderer IP/Methode → erwartet Validierungsfehler (Regel in AccessTokenBL vor Übernahme finalisieren). +Tracelinks: SyRS-006, StRS-004 +Konsolidierung: Kandidat: mit SwRS-002 (Access-Tokens) +Übernahmewürdigkeit: übernehmen +Status: HYPOTHESE - die konkrete IP-/Methoden-Bindungsregel in AccessTokenBL.ValidateToken wurde nicht eingesehen + +--- + +ID: SwRS-055 +Titel: TOTP-Zwei-Faktor-Bibliothek im Plattformkern +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Login-/2FA-Strang, ConnectionManager +Vorbedingung: 2FA-Schlüssel hinterlegt +Fakt: `src\shared\Centron.Core\TotpAuth` enthält Totp.cs, Otp.cs, Base32Encoding.cs, VerificationWindow.cs, KeyUtilities.cs; Webservice/Controller/ConnectionManager konsumieren (TwoFactorAuthController.cs, TwoFactorAuthTestViewModel.cs). +Aussage: Das System soll Google-Authenticator-kompatible TOTP-Prüfung mit konfigurierbarem Verifikationsfenster als wiederverwendbare Kernbibliothek bereitstellen. +Ergebnis: Plattformübergreifend identische 2FA-Prüfung. +Belege: + - [PRIMÄR] src\shared\Centron.Core\TotpAuth\Totp.cs, Otp.cs, VerificationWindow.cs - Begründung: Klassen verifiziert (Prüfroutine nicht im Detail gelesen) + - [SEKUNDÄR] src\webservice\Centron.Controllers\Controllers\Unversioned\TwoFactorAuthController.cs - Begründung: Anschlussstelle +Prüfidee: TOTP-Token gegen Fenstervalidierung; Zeitdrift-Fall. +Tracelinks: StRS-004 +Konsolidierung: Kandidat: mit SwRS-004 (2FA-Schlüsselprüfung) +Übernahmewürdigkeit: übernehmen +Status: HYPOTHESE - die erzwungene Prüfstelle im Login-Pfad wurde nicht gezeigt +Statushinweis: - + +--- + +ID: SwRS-056 +Titel: Schnittstellenmodul als Contract-First-Schicht +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: Wartbarkeit (ISO 25010) +Akteur: Backend-Module (Entwickler) +Vorbedingung: Host/BL/DAO referenzieren Centron.Interfaces +Fakt: ~60 Fachordner mit BL-/DAO-/Repository-/Entity-Schnittstellen (IBaseEntity, IBaseRepository, CentronObjectKindNumeric); Host importiert Centron.Interfaces.BL. +Aussage: Das System soll BL-/DAO-/Repository-Verträge zentral definieren, damit Host, BL und DAO nur gegen Abstraktionen koppeln. +Ergebnis: Austauschbare Implementierungen, klare Schichtgrenzen. +Belege: + - [PRIMÄR] src\backend\Centron.Interfaces (Ordnerstruktur, IBaseRepository.cs verifiziert) - Begründung: Vertragsmodul existiert +Prüfidee: csproj-Referenzgraph extrahieren; Interfaces den Implementierungen zuordnen. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Architekturkapitel Schichtenmodell +Übernahmewürdigkeit: übernehmen als Architektur-Regel +Status: HYPOTHESE - Einzelinterface-Inhalte nur oberflächlich geprüft +Statushinweis: - + +--- + +ID: SwRS-057 +Titel: Gemeinsame Querschnittsbibliothek (Logging, Settings, Netzwerk, Codierung) +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: Wartbarkeit (ISO 25010) +Akteur: Backend-Module +Vorbedingung: Module referenzieren Centron.Common/Centron.Core +Fakt: Ordner Logging (InMemoryTarget, LogEntry), Settings (ConfigItem), Network (IpAddressHelper, im Host auf HttpContext-Client überschrieben), IniParser, TextCoding (SHA1Decoder). +Aussage: Das System soll zentrale Hilfsfunktionen (In-Memory-Logpuffer, Konfigurationsitems, IP-Ermittlung, Hash-/Textcodierung) gemeinsam bereitstellen. +Ergebnis: Wiederverwendung statt Duplikate; konsistente Infrastruktur. +Belege: + - [PRIMÄR] src\backend\Centron.Common\Network\IpAddressHelper.cs, src\backend\Centron.Common\Logging\InMemoryTarget.cs - Begründung: Klassen existieren; Inhalt nur über Nutzung belegt +Prüfidee: InMemoryTarget an NLog konfigurieren, LogEntry-Abruf testen. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Konfigurationskapitel +Übernahmewürdigkeit: übernehmen als Infrastrukturentwurf +Status: HYPOTHESE - Detailverhalten der Klassen nicht gelesen +Statushinweis: - + +--- + +ID: SwRS-058 +Titel: eb:interface-4.3-E-Rechnung für Österreich +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: Funktionale Eignung (ISO 25010) +Akteur: Buchhaltung (auslösend), österreichischer Empfänger +Vorbedingung: ReceiptInfo mit Empfänger-/Liefer-/Steuerdaten +Fakt: `EbInterfaceLogic.GenerateFile` baut XmlDocument mit Namespace ".../4p3/" (Biller, InvoiceRecipient, Delivery, Tax; Beträge en-US, Datum yyyy-MM-dd). +Aussage: Das System soll aus Rechnungsdaten ein konformes eb:interface-4.3-XML erzeugen (TotalGrossAmount = Netto + Steuer). +Ergebnis: Gültiges Empfänger-XML als Byte-Array. +Belege: + - [PRIMÄR] src\apis\Centron.Api.EbInterface\EbInterfaceLogic.cs, GenerateFile/GenerateXmlDocument - Begründung: einzige Erzeugerklasse +Prüfidee: Schema-Validierung 4.3; Bruttosummenvergleich. +Tracelinks: SyRS-040, StRS-003 +Konsolidierung: Kandidat: E-Rechnung gesamt (ZUGFeRD) zusammenführen +Übernahmewürdigkeit: übernehmen - Länderformat AT +Status: belegt + +--- + +ID: SwRS-059 +Titel: GLS-Sendungsupload mit Vorabvalidierung +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: Zuverlässigkeit (ISO 25010) +Akteur: Versandmitarbeiter +Vorbedingung: Sendungsdaten gepflegt; Test-/Produktmodus gewählt +Fakt: `CentronGlsLogic.UploadShipment` POSTet JSON an api.gls-group.eu (Test: api-qs); `DoValidateShipment` begrenzt auf max. 50 Referenzen/30 Pakete; Response liefert TrackId/Labels. +Aussage: Das System soll Sendungen nur nach lokaler Kontextvalidierung an GLS übermitteln und Tracking-/Labeldaten zurückmelden. +Ergebnis: UploadResult mit Erfolg/Fehler; keine API-Last bei ungültigen Sendungen. +Belege: + - [PRIMÄR] src\apis\Centron.Api.Gls\CentronGlsLogic.cs, UploadShipment/DoValidateShipment - Begründung: Grenzwerte+Endpunkte im Code + - [SEKUNDÄR] src\apis\Centron.Api.Gls\CentronGlsConsts.cs, BaseURL/TestBaseURL - Begründung: Moduskonstanten +Prüfidee: 51 Referenzen → lokaler Abbruch; Testmodus gegen QS-URL. +Tracelinks: SyRS-047, StRS-001 +Konsolidierung: Kandidat: Versand-Allgemein mit SwRS-060 +Übernahmewürdigkeit: übernehmen - hartkodierte Basic-Auth-Konstante (Consts Zeile 6) zwingend in Secret-Verwaltung überführen +Status: belegt + +--- + +ID: SwRS-060 +Titel: Sendungsanlage und Carrier-Abruf über Shipcloud +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Versandplatz +Vorbedingung: API-Key vorhanden +Fakt: `CentronShipcloudLogic` setzt Basic-Auth Base64(apiKey) auf api.shipcloud.io/v1/; GetCarriersAsync/GetShipmentAsync/CreateShipmentAsync mappen CarrierTrackingNo, TrackingUrl, LabelUrl, Price. +Aussage: Das System soll Sendungen über Shipcloud anlegen und Tracking-/Labeldaten inkl. Preis bereitstellen. +Ergebnis: Versanddatensatz mit Track-URL, Label, Preis. +Belege: + - [PRIMÄR] src\apis\Centron.Api.Shipcloud\CentronShipcloudLogic.cs, CreateShipmentAsync - Begründung: komplettes Modulverhalten beobachtet +Prüfidee: Mock-Antwort mit LabelUrl; Error-JSON → UploadResult(false). +Tracelinks: SyRS-047, StRS-001 +Konsolidierung: Kandidat: mit SwRS-059 zu "Versandanbieter-Anbindung" +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-061 +Titel: Produktdaten per SOAP-Session vom Cop-System +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Artikelstammpflege +Vorbedingung: Adresse/Benutzer/Passwort konfiguriert +Fakt: `CopApi.GetSessionIdAsync` etabliert Session (SOAP urn:jsframework.dev) vor `GetProductAsync(eanCode)`; Parser mappen XElement auf Product (EAN, Preis, Maße, Bilder); Fehler als CopException. +Aussage: Das System soll Produkt-Detaildaten je EAN/ID aus dem Cop-WebService abrufen und in ein internes Modell überführen. +Ergebnis: Vollständiges Datenobjekt für Artikelanlage/-anreicherung. +Belege: + - [PRIMÄR] src\apis\Centron.APIs.CopDataAccess\CopApi.cs, GetSessionIdAsync/GetProductAsync - Begründung: Session-/Abrufkette belegt +Prüfidee: SOAP-Fixture durch Parser; Abbruch ohne Session → CopException. +Tracelinks: SyRS-046, StRS-001 +Konsolidierung: Kandidat: Produktdaten-Familie (SwRS-062, SwRS-064) zusammenführen +Übernahmewürdigkeit: übernehmen - Provider-Klärung nötig +Status: belegt + +--- + +ID: SwRS-062 +Titel: EGIS-Artikelsuche mit Preis und Verfügbarkeit +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Einkauf/Suche +Vorbedingung: EGIS-Zugangsdaten +Fakt: `EgisApi.SearchAsync/GetPriceAndAvailability/GetProductGroups` POSTen an egis-online.de EBC-Endpunkt; Antwort-namespaces schemafest. +Aussage: Das System soll Artikel, Preise und Verfügbarkeit des EGIS-Verbundes in Echtzeit abfragen und filtern (z.B. nur Lagerware). +Ergebnis: Trefferliste FoundArticle/Preis je Distributor. +Belege: + - [PRIMÄR] src\apis\Centron.APIs.EgisDataAccess\EgisApi.cs, SearchAsync/GetPriceAndAvailability - Begründung: URL/Methoden belegt +Prüfidee: Original-Response-Fixtures gegen Parser. +Tracelinks: SyRS-046, StRS-001 +Konsolidierung: Kandidat: Produktdaten-Familie +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-063 +Titel: PSD2-Bankdatenabruf über finapi +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: Sicherheit (ISO 25010) +Akteur: Finanzbuchhaltung +Vorbedingung: ClientId/Secret; OAuth-Token gültig +Fakt: FinApi-Konstanten live.finapi.io (oauth/token, transactions); `FinApiClient.GetAccountTransactions` liefert interne Onlinebanking-Transaktionen (Betrag, IBAN, BookingDate); Sandbox-Modus umschaltbar. +Aussage: Das System soll Bankverbindungen anbinden (WebForm-Flow) und Konto-Umsätze in ein internes Onlinebanking-Modell überführen. +Ergebnis: Belastbare Zahlungsdaten für Abgleich/Mahnwesen. +Belege: + - [PRIMÄR] src\apis\Centron.APIs.FinAPI\FinApiClient.cs, GetAccountTransactions/ImportNewBankConnection - Begründung: Data-Klassen OpenAPI-generiert +Prüfidee: Sandbox-Lauf; Token-Ablaufbehandlung. +Tracelinks: StRS-003, StRS-011 +Konsolidierung: Kandidat: Onlinebanking-Kern separat bewerten +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-064 +Titel: Icecat-Produktinhalte (Text/Bild/Specs) je EAN +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Artikeltexte-Redaktion +Vorbedingung: Icecat-Zugang konfiguriert +Fakt: `IcecatApi.GetProductAsync` baut xml_server3.cgi-URL je EAN; ProductParser liefert Beschreibung, Bilder (Thumbnail/Low/High), Features, Sprache de/en. +Aussage: Das System soll Marketinginhalte je EAN/Produkt aus Icecat mehrsprachig übernehmen. +Ergebnis: Anreicherung von Artikeltexten und Bildlinks. +Belege: + - [PRIMÄR] src\apis\Centron.APIs.IcecatDataAccess\IcecatApi.cs, GetProductAsync - Begründung: URL-Format+Datenmodell beobachtet +Prüfidee: Fixture-XML → Product; Sprachparameter beachten. +Tracelinks: SyRS-046, StRS-001 +Konsolidierung: Kandidat: Produktdaten-Familie +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-065 +Titel: ITscope-Produkte, Angebote und Deals inkl. Archivierung +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Vertrieb/Einkauf +Vorbedingung: UserMail+ApiKey, Quota vorhanden +Fakt: `ITscopeApi` nutzt api.itscope.com/2.1 (products/ean, business/quotes, business/deals, info/quota); SetDealArchived markiert verarbeitete Deals. +Aussage: Das System soll Artikel-/Preisdaten und Angebots-/Deal-Status von ITscope laden und verarbeitete Deals als archiviert markieren. +Ergebnis: Synchronisierte Deals/Angebote; Quota-Überwachung. +Belege: + - [PRIMÄR] src\apis\Centron.APIs.ITscopeDataAccess\ITscopeApi.cs, GetProductByEanCodeAsync/GetOrderByIdAsync/SetDealArchived - Begründung: Endpunkte belegt +Prüfidee: URL-Aufbau+Parser gegen Beispieldateien; Archivierungs-Call. +Tracelinks: SyRS-046, SyRS-045 +Konsolidierung: Kandidat: Produktdaten-Familie +Übernahmewürdigkeit: übernehmen - BEFUND: ITscope ist Distributoren-Marktplatz, keine Bonitätsauskunft +Status: belegt + +--- + +ID: SwRS-066 +Titel: docuFORM-Gerätezähler über OAuth2-PKCE +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: Sicherheit (ISO 25010) +Akteur: Druckfleet-/Abrechnungsprozesse +Vorbedingung: Serveradresse, ClientId; PKCE-Verifier generiert +Fakt: `DocuFormRestApiClient` nutzt /auth/v2/authorize, /auth/v2/token (S256 CodeChallenge), /dfmserver/v2/devices und /{id}/counters; Redirect http://127.0.0.1. +Aussage: Das System soll nach PKCE-Autorisierung Geräte und Zählerstände der docuFORM-MPS-Plattform (optional zeitbezogen) abrufen. +Ergebnis: Zählerstände als Basis der Verbrauchsabrechnung. +Belege: + - [PRIMÄR] Centron.Api.docuFORM\DocuFormRestApiClient.cs, RequestToken/GetDeviceCounters - Begründung: Token-Flow+Endpunkte sichtbar +Prüfidee: Token-Flow gegen Mock; Counter-URL mit Datum. +Tracelinks: StRS-001, StRS-003 +Konsolidierung: Kandidat: Druckabrechnung (Verbrauchszähler → Fakturierung) verknüpfen +Übernahmewürdigkeit: übernehmen - BEFUND: Drucker-Abrechnung läuft über externe MPS; Konsolidierung mit Asset-/Stammblattkonzept prüfen +Status: belegt + +--- + +ID: SwRS-067 +Titel: Eindeutige Standard-Exportkonfiguration je Mandant +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Finanzbuchhaltung/Administration +Vorbedingung: Mehrere Buchhaltungssysteme konfigurierbar +Fakt: `BookKeepingExportBL.SaveExportSettings` erzwingt genau einen DefaultExport und führt CreatedVersion je Konfiguration. +Aussage: Das System soll die Buchhaltungsexport-Konfiguration versioniert speichern und genau einen Zielsystemstandard garantieren. +Ergebnis: Deterministischer Exportkanal je Mandant. +Belege: + - [PRIMÄR] src\backend\Centron.BL\DataExchange\BookKeeping\BookKeepingExportBL.cs, SaveExportSettings - Begründung: Eindeutigkeitsregel implementiert +Prüfidee: Zwei DefaultExport setzen → Verletzung abgewiesen. +Tracelinks: SyRS-039, StRS-003 +Konsolidierung: Kandidat: Finanzbuchhaltungskapitel +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-068 +Titel: E-Mail-Versand über austauschbare Protokollclients, Secrets verschlüsselt +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: Modifizierbarkeit (ISO 25010) +Akteur: Administrator, versendende Fachmodule +Vorbedingung: Mail-Einstellungen gepflegt +Fakt: `CentronMailFactory.GetMail` wählt per Setting CentronWebserviceMailType zwischen ExchangeMail/GraphMail/SMTPMail; `MailSettingsBL.SetMailSettings` verschlüsselt Exchange-Passwort und Graph-Secret via AESCryptoLogic.EncryptText. +Aussage: Das System soll den Mailversand protokollunabhängig kapseln, den Client zentral auswählen und Mail-Geheimnisse nur verschlüsselt persistieren. +Ergebnis: Ein Aufrufer versendet ohne Protokollwissen; keine Klartextsecrets im Settingstore. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Mail\Factory\CentronMailFactory.cs, GetMail (Zeilen 29-53) - Begründung: Factory-Switch belegt + - [SEKUNDÄR] src\backend\Centron.BL\Mail\MailSettingsBL.cs, SetMailSettings - Begründung: Encrypt-Aufrufe +Prüfidee: Setting wechseln → anderer Clienttyp; DB-Spalte zeigt keinen Klartext. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Verschlüsselungsmusterfamilie (SwRS-070) +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-069 +Titel: Mailing als vollständiges Aggregat laden +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Marketing-Mitarbeiter +Vorbedingung: Mailing-I3D gegeben +Fakt: `MailingDataBL.LoadFullMailing` lädt Texte, Anhänge und Beziehungstexte; fehlender Datensatz → Result.AsError "Kein Mailing gefunden...". +Aussage: Das System soll Mails als aggregiertes DTO (Texte, Anhänge, Beziehungstexte) liefern und fehlerhafte I3D sauber als Fehler zurückgeben. +Ergebnis: Vollständiges Mailing oder definierte Fehlermeldung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Mailings\MailingDataBL.cs, LoadFullMailing (Zeilen 22-46) - Begründung: Lese-/Schreibpfad in Klasse +Prüfidee: Bekannte I3D → Aggregat; I3D=999999 → Error-Result. +Tracelinks: StRS-001 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-070 +Titel: MailScanner-Profile nur mit VMA-Recht, Passwörter verschlüsselt +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Mitarbeiter mit VMA-Recht +Vorbedingung: Anwender angemeldet +Fakt: `MailScannerBL.GetProfiles` prüft UserRightsConst.VirtualMailAssistant.ACCESS_VMA_MODULE und lehnt sonst ab; SaveProfile ruft vorher EncryptProperties (MasterKey) auf. +Aussage: Das System soll VMA-Profile nur bei Modulrecht laden und Passwörter/ClientSecrets vor dem Speichern mit dem Masterkey verschlüsseln. +Ergebnis: Unberechtigte erhalten Fehler; keine Klartextpasswörter in BL/DB. +Belege: + - [PRIMÄR] src\backend\Centron.BL\MailScanner\MailScannerBL.cs, GetProfiles/SaveProfile (Zeilen 57-116) - Begründung: Rechteprüfung+Crypto explizit +Prüfidee: Ohne Recht → Error; gespeicherte Passwortspalte ≠ Klartext. +Tracelinks: SyRS-001, SyRS-030, StRS-004 +Konsolidierung: Kandidat: Verschlüsselungsmusterfamilie +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-071 +Titel: Chat-Nachrichten: Mitgliederzugriff, Autorschaft, Löschschutz +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Mitarbeiter +Vorbedingung: Anwender ist Chat-Mitglied +Fakt: `ChatBL.SendChatMessage` begrenzt Text per Guard auf 250 Zeichen; EditOrDeleteMessage wirft bei Nicht-Autor oder gelöschter Nachricht; Löschen als Soft-Delete mit Text "Gelöscht.". +Aussage: Das System soll Chatnachrichten auf 250 Zeichen begrenzen, Bearbeitung/Löschung nur dem Verfasser erlauben und die Historie per Soft-Delete erhalten. +Ergebnis: Fremdänderungen abgewiesen; Historie rekonstruierbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Chats\ChatBL.cs, SendChatMessage/EditOrDeleteMessage (Zeilen 202-258, 464-520) - Begründung: Regeln als Guards implementiert +Prüfidee: 251 Zeichen → Fehler; Nicht-Autor editiert → Exception. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: KI-Chat (SwRS-113) klar abgrenzen +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-072 +Titel: Kundensuche im Outlook-AddIn über Gerätenummer +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Mitarbeiter im Outlook-AddIn +Vorbedingung: AssetNumber übergeben +Fakt: `OutlookAssetKindSearchBL.SearchCustomersWithAssetManagementEntrys` führt NamedQuery "Asset.GetAssetKindForOutlook" mit Parameter "Nummer" und mappt auf DTO. +Aussage: Das System soll zu einer Gerätenummer die zugehörigen Kunden/Anlagenarten für die Outlook-Integration liefern. +Ergebnis: Trefferliste (I3D, Number, Name) oder leere Liste. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Outlook\OutlookAssetKindSearchBL.cs, Zeilen 25-46 - Begründung: einzige Klasse, NamedQuery-Pfad sichtbar +Prüfidee: Bekannte Gerätenummer → Kunde; Auffälligkeit: DTO-Instanz wird in Schleife wiederverwendet. +Tracelinks: SyRS-035, StRS-001 +Konsolidierung: Kandidat: Anlagen-/Asset-Themen (SwRS-023) +Übernahmewürdigkeit: Sonderfall - Modulminimal (1 Methode) +Status: belegt + +--- + +ID: SwRS-073 +Titel: CTI-Anruferidentifikation über mehrstufige Rufnummernsuche +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: Benutzerfreundlichkeit (ISO 25010) +Akteur: Mitarbeiter mit Telefonplatzschirm +Vorbedingung: TAPI-Rufnummer liegt an +Fakt: `PhoneCallBL.SearchContactPersonByPhoneNumberV2` probiert formatierte, unformatierte, frontabgeschnittene und "hardcore"-Varianten (Ländervorwahlen 49/41/43) und bricht beim Ersttreffer ab. +Aussage: Das System soll eingehende Rufnummern durch iterativ gelockerte Suchvarianten einem Kunden/Kontakt zuordnen und interne Kurznummern ausnehmen. +Ergebnis: Anruferpopup trotz unterschiedlicher Formate; interne Nummern ohne Fehltreffer. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Tapi\PhoneCallBL.cs, SearchContactPersonByPhoneNumberV2 (Zeilen 149-228) - Begründung: Suchkaskade implementiert + - [SEKUNDÄR] ebd., SyncPhoneCalls (Graph CallRecords, Lizenz) - Begründung: Sync-Zweig +Prüfidee: +49-Notation, Kurznummer, Vorwahlvarianten durchtesten. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Graph/Exchange-Sync mit Kalender/Mail bündeln +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-074 +Titel: Empfängerlisten je Objekt deckungsgleich halten, Meldungen auto-cleanupen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: Datenkonsistenz (ISO 25010) +Akteur: Fachanwender, Administration +Vorbedingung: Objekt (z.B. Vorgang) existiert +Fakt: `UserNotificationBL.UpdateUsersFromObject` legt in einer Transaktion fehlende NotificationUser an und ergänzt/entfernt Bindungen deckungsgleich; `CentronNotificationsBL.CleanupCentronNotifications` löscht Meldungen älter als DeleteAfterDays. +Aussage: Das System soll Benachrichtigungsempfänger je Objekt synchron zur übergebenen Liste halten und Systemmeldungen nach konfigurierter Frist automatisch löschen. +Ergebnis: Keine verwaisten Bindungen; Meldungsarchiv wächst begrenzt. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Notifications\UserNotificationBL.cs, UpdateUsersFromObject (Zeilen 41-117) - Begründung: Sync-Logik vollständig + - [SEKUNDÄR] CentronNotificationsBL.cs, Cleanup (Zeilen 53-68) - Begründung: Löschregel +Prüfidee: Zwei Aufrufe mit geänderter Liste → exakt neue Bindungen; Cleanup an Datumsgrenze. +Tracelinks: StRS-014 +Konsolidierung: Kandidat: Benachrichtigungsthemen (SwRS-049/050) +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-075 +Titel: Interne Social-Media-Kommentare/Likes über gespeicherte Prozeduren +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Mitarbeiter +Vorbedingung: Stream/Aktion existiert +Fakt: `SocialMediaBL.AddCommentToASocialMediaAction/LikeAStreamOrAction/CreateActionForStream` rufen Prozeduren "SocialMedia.*" mit EmployeeI3D auf; im Like-Switch erhalten Stream und Action denselben socialKind-Wert 0 (möglicher Fehler). +Aussage: Das System soll Mitarbeitern Kommentare/Likes auf Streams und Aktionen mit automatischer Autorableitung ermöglichen. +Ergebnis: Kommentar-/Like-Übersicht mit Verfassern. +Belege: + - [PRIMÄR] src\backend\Centron.BL\SocialMedia\SocialMediaBL.cs, Zeilen 25-114 - Begründung: Prozeduraufrufe mit Benutzerbezug +Prüfidee: Kommentar erhöht Trefferzahl; Like-Kind-Differenzierung prüfen. +Tracelinks: StRS-001 +Konsolidierung: nein +Übernahmewürdigkeit: veraltet - datierte Funktion +Status: HYPOTHESE - Kernlogik liegt in DB-Prozeduren, deren Inhalt nicht im Artefaktbestand liegt + +--- + +ID: SwRS-076 +Titel: DocuBoard-Partner als konsistentes Aggregat speichern +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Service-Mitarbeiter +Vorbedingung: Kunde ausgewählt +Fakt: `AssetManagementPartnerBL.SavePartner` re-attached den Partner und setzt item.Partner für alle AssetManagementPartnerItem vor dem Speichern. +Aussage: Das System soll DocuBoard-Partner mit allen Positionen als Aggregat je Kunde speichern, jede Position erhält automatisch den Partnerbezug. +Ergebnis: Referenziell konsistente Partnerliste. +Belege: + - [PRIMÄR] src\backend\Centron.BL\DocuBoard\AssetManagementPartnerBL.cs, SavePartner (Zeilen 33-47) - Begründung: Aggregatlogik beobachtet +Prüfidee: Speichern mit neuen Items → alle Items zeigen auf Partner. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: AssetManagement-/Anlagenkonzept zusammenführen +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-077 +Titel: Videozuweisungen rechtsgeprüft mit ToDo-Kopplung +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Mitarbeiter mit VideoPortal-Recht +Vorbedingung: Video und Empfänger bekannt +Fakt: `VideoPortalAssignmentBL.SaveVideoPortalAssignment` prüft UserRightsConst.VideoPortal.ASSIGNMENT (sonst ResultException), erzeugt nach Speichern ToDo-Einträge und entfernt sie beim Löschen. +Aussage: Das System soll Videozuweisungen nur mit Recht speichern/löschen und zugehörige ToDo-Einträge automatisch erzeugen bzw. entfernen. +Ergebnis: Keine Zuweisung ohne ToDo und kein ToDo ohne Zuweisung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\VideoPortal\VideoPortalAssignmentBL.cs, Zeilen 25-65 - Begründung: Guard+ToDo-Sync beieinander +Prüfidee: Ohne Recht → ResultException; Speichern/Löschen spiegelt sich im ToDo. +Tracelinks: StRS-014, StRS-004 +Konsolidierung: Kandidat: mit ToDoArea-Registrierung (StRS-014) +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-078 +Titel: Terminanfrage-Antwort gegen Exchange-Kalender verarbeiten +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: externer Kontakt (Antwort), System +Vorbedingung: Terminanfrage mit EWS-Vorschlagsterminen +Fakt: `AppointmentRequestBL.HandleAppointmentRequestReply` bindet bei Akzeptanz den gewählten Termin (Appointment.Bind), setzt Betreffzusatz "(Akzeptiert)"/Kategorie und löscht alle übrigen Vorschlagstermine; bei Ablehnung alle. +Aussage: Das System soll Antworten auf Terminanfragen auswerten: akzeptierten Termin bestätigen, Alternativvorschläge entfernen, Status konsistent halten. +Ergebnis: Exchange-Kalender und RequestState deckungsgleich. +Belege: + - [PRIMÄR] src\backend\Centron.BL\AppointmentRequests\AppointmentRequestBL.cs, HandleAppointmentRequestReply (Zeilen 29-114) - Begründung: Akzeptanz-/Ablehnungsablauf beobachtet +Prüfidee: Simulierte Reply → nur akzeptierter Termin vorhanden. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Exchange/EWS-Integrationen (Mail, Tapi) bündeln +Übernahmewürdigkeit: übernehmen - Exchange-Abhängigkeit kennzeichnen +Status: belegt + +--- + +ID: SwRS-079 +Titel: Wiederkehrende Aufgaben nur mit valider Aktion und Lizenz +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Mitarbeiter +Vorbedingung: Action und Recurrence ausgefüllt +Fakt: `TaskManagementTaskBL.SaveOrUpdateTask` validiert ValidateAction, verwirft Ende≤Start der Wiederholung und bricht bei CheckLicenses-Fehler ab; Handler: Helpdesk, Report. +Aussage: Das System soll Automaufgaben nur speichern, wenn Aktion unterstützt, Wiederkehrrhythmus valide und Lizenz vorhanden ist. +Ergebnis: Keine defekten/unlizenzierten Automationen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\TaskManager\TaskManagementTaskBL.cs, SaveOrUpdateTask (Zeilen 40-97) - Begründung: Prüfzweige in Transaktion +Prüfidee: Ungültige Recurrence/fehlende Lizenz → Fehlerresult/Exception. +Tracelinks: StRS-014 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-080 +Titel: Kalenderdarstellung und Outlook-Synchronisation konfigurieren +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: Konfigurierbarkeit (ISO 25010) +Akteur: Administrator +Vorbedingung: Einstellungen-Modul verfügbar +Fakt: `CalendarBL.Get/UpdateCalendarSynchronizationSettings` verwaltet Outlook-Kategorie/-Ort/-Betreff/-Text und CrmActivityTypesForOutlookSync; Darstellungsoptionen für Helpdeskzeiten. +Aussage: Das System soll Kategorien, Orte, Textvorlagen und Anzeigeflaggen für Kalender bzw. Outlook-Sync dauerhaft konfigurierbar machen. +Ergebnis: Sync-Verhalten ohne Codeänderung anpassbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Calendar\CalendarBL.cs, Zeilen 20-193 - Begründung: Settings-Get/Set-Vollständigkeit +Prüfidee: Wert ändern, neu laden → gemerkt. +Tracelinks: StRS-001 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-081 +Titel: Tagesplanungs-Batches mit gemeinsamer Kennung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Mitarbeiter +Vorbedingung: Mitarbeiter für MyDay ausgewählt +Fakt: `MyDayBL.SaveWorkItemBatch` erzeugt je Datum ein WorkItem mit gemeinsamer BatchId (Max+1); bei Einzeldatum BatchId=0 (dokumentierter Sonderfall). +Aussage: Das System soll wiederkehrende Tagesplanungseinträge als Batch mit gemeinsamer Kennung anlegen und Einzeltage ohne Batch führen. +Ergebnis: Zusammenhängende Planungsblöcke gemeinsam bearbeit-/löschbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\MyDay\MyDayBL.cs, SaveWorkItemBatch (Zeilen 100-130) - Begründung: BatchID-Vergabe inkl. Sonderfall kodiert +Prüfidee: 3 Daten → gleiche BatchId>0; 1 Datum → BatchId 0. +Tracelinks: StRS-001 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-082 +Titel: Erwartete Ereignisse je Kunde mit Löschkaskade +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: Datenkonsistenz (ISO 25010) +Akteur: Administration/Überwachung +Vorbedingung: Kunde existiert +Fakt: `ExpectedEventsBL.SaveExpectedEvent` übernimmt wochentagsweise Zeitfenster und MessageContains-Filter; DeleteExpectedEvent löscht erst ExpectedEventLogEntries, dann das Event. +Aussage: Das System soll Überwachungsdefinitionen mit Tageszeitfenstern/Meldefiltern pflegen und beim Löschen zugehörige Logs rückstandsfrei entfernen. +Ergebnis: Keine verwaisten Ereignisprotokolle. +Belege: + - [PRIMÄR] src\backend\Centron.BL\ExpectedEvents\ExpectedEventsBL.cs, Save/Delete (Zeilen 22-114) - Begründung: Kaskade implementiert +Prüfidee: Delete → Logabfrage leer. +Tracelinks: StRS-015, StRS-001 +Konsolidierung: Kandidat: Monitoring-/Logthemen +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-083 +Titel: Persönliche Dashboardcontainer je Benutzer +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: Benutzerfreundlichkeit (ISO 25010) +Akteur: angemeldeter Benutzer +Vorbedingung: Benutzer authentifiziert +Fakt: `DashboardContainerBL` führt Load/Register/Delete/Update stets mit appUserI3D (Modul-GUID, Containerart, Größe). +Aussage: Das System soll Startseite-Dashboardcontainer benutzergetrennt registrieren, anordnen und löschen. +Ergebnis: Persönliche Startseite ohne Fremdzugriff. +Belege: + - [PRIMÄR] src\backend\Centron.BL\MyCentron\Dashboard\DashboardContainerBL.cs, Zeilen 19-41 - Begründung: User-I3D in allen vier Operationen +Prüfidee: Registrierung User A, Load User B ohne Treffer. +Tracelinks: StRS-001 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-084 +Titel: Hintergrunddienste namentlich erfassen und zentral aktivieren +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Hintergrunddienst +Vorbedingung: Dienst meldet sich beim Start +Fakt: `BackgroundServiceBL.CreateOrUpdateBackgroundService` legt unbekannte Dienste automatisch an; IsServiceEnabled liefert für unbekannte Dienste true (Zeile 181). +Aussage: Das System soll jeden Hintergrunddienst namentlich erfassen, zentral steuerbar machen und Start-/Laufzeitpunkte dokumentieren. +Ergebnis: Dienste deaktivierbar; Laufzeitüberwachung auswertbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\BackgroundServices\BackgroundServiceBL.cs, IsServiceEnabled/CreateOrUpdateBackgroundService - Begründung: Default-Enabled-Verhalten belegt +Prüfidee: Unbekannter Dienst → enabled=true; nach SetServiceEnabled(false) → false. +Tracelinks: SyRS-022, StRS-001 +Konsolidierung: Kandidat: Ops-Monitoring +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-085 +Titel: SQL-Server-Betriebsdiagnostik für Administratoren +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Admin-Session auf Fach-DB +Fakt: `SQLManagementBL` stellt ShowLastSqlQueries, ShowBlockedProcess, Backup-/Wartungsplan- und Objektlisten per Named Queries/Raw SQL bereit. +Aussage: Das System soll Administratoren Einsicht in laufende/blockierte Prozesse, Backups, Wartungspläne und Datenobjekte geben. +Ergebnis: DB-Engpässe ohne externes Tool erkennbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\SQLManagement\SQLManagementBL.cs, Show*-Methoden (Zeilen 17-179) - Begründung: vollständige API des Moduls +Prüfidee: Blockierte Sperre erzeugen → in ShowBlockedProcess sichtbar. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Diagnose-Menü mit SwRS-088 +Übernahmewürdigkeit: übernehmen (Ziel-SaaS: auf Mandantensicht einschränken) +Status: belegt + +--- + +ID: SwRS-086 +Titel: Automatische, referenzierte Objektverzeichnisse im Dokumentenmanagement +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Benutzer (DMS), System +Vorbedingung: Rootverzeichnis vorhanden (Self-Repair) +Fakt: `DirectoryReferenceProviderBase` erzeugt beim Erstzugriff ein Objektverzeichnis (Name max. 50 Zeichen) und verknüpft es per DirectoryReference (ObjectKind/ObjectI3D); ~60 spezialisierte Provider; Zugriffe über AppRightsBL geprüft. +Aussage: Das System soll für Geschäftsobjekte bedarfsgerecht genau ein referenziertes DMS-Verzeichnis anlegen, wiederverwenden und rechtsabsichern. +Ergebnis: Eindeutige Objekt↔Ordner-Zuordnung ohne Duplikate. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\FileManagement\DirectoryReferenceProviders\DirectoryReferenceProviderBase.cs, CreateDirectoryReference/GetExistingDirectoryReference - Begründung: Erzeugungs-/Wiederverwendungslogik + - [SEKUNDÄR] DirectoryBL.cs, GetRootDirectory (Self-Repair) - Begründung: Wurzelreparatur +Prüfidee: Zweimal GetDirectoryReference → identisches Verzeichnis; Langname gekürzt. +Tracelinks: StRS-001, StRS-015 +Konsolidierung: Kandidat: DocumentBL/SharedDocumentBL in Folgeiteration vertiefen +Übernahmewürdigkeit: übernehmen - Muster klar +Status: belegt + +--- + +ID: SwRS-087 +Titel: Theme-Verwaltung mit unantastbarem Standard-Theme +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: mind. ein aktives Theme +Fakt: `ThemeBL` soft-löscht; Standard-Theme nicht lösch-/deaktivierbar (Zeilen 112f., 174-178); SetDefaultTheme setzt alle anderen in einer Transaktion auf non-default. +Aussage: Das System soll UI-Themes verwalten und genau ein nicht löschbares Standard-Theme garantieren. +Ergebnis: Oberfläche fällt nie ohne gültiges Theme zurück. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Themes\ThemeBL.cs, Delete/SetDefaultTheme/SetThemeActive - Begründung: Lösch-/Default-Schutz implementiert +Prüfidee: Default löschen → Fehler; Default-Wechsel → alter Default nicht mehr Default. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Branding (Nexus-Settings) mit Theme-Konzept bündeln +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-088 +Titel: Strukturierter Netzwerk-/SQL-Diagnosebericht +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: Zuverlässigkeit (ISO 25010) +Akteur: Support/Administrator +Vorbedingung: Webservice-Instanz läuft +Fakt: `NetworkDiagnosticsBL.GetServerInfo()` sammelt Zeitzone, SQL-Host/-Port, DNS, TCP-/SQL-Latenz und TLS-Zertifikatskette (TDS PRELOGIN); Fehler als DTO-Feld statt Exception. +Aussage: Das System soll auf Anforderung einen strukturierten Diagnosebericht zu Serverzeit, SQL-Anbindung, Latenzen und Zertifikaten liefern. +Ergebnis: Latenz-/Zertifikatsprobleme lokalisierbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\NetworkDiagnostics\NetworkDiagnosticsBL.cs, GetServerInfo/PopulateSqlServerInfo (Zeilen 24-120) - Begründung: Messstrecke implementiert +Prüfidee: Falscher SQL-Host → SqlConnectionSuccessful=false mit Fehlerfeld, kein Absturz. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Diagnose-Menü mit SwRS-085 +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-089 +Titel: Profilaufzeichnungen aufbewahrungsgesteuert aggregieren +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: Performance-Effizienz (ISO 25010) +Akteur: Wartungsdienst +Vorbedingung: Aufbewahrungs-Setting gesetzt +Fakt: `ProfilerBL.ReorganizeProfilerEntries()` ersetzt duplizierte AnlageLog-Einträge (Art=80) je Objekt/Tag durch einen Aggregat-Eintrag "{n} Zugriffe"; `PerformanceTestBL.RunTests` speichert Messreihen mit Guards. +Aussage: Das System soll Profilieraufzeichnungen je Aufbewahrungsfenster zu Aggregaten verdichten und definierte Performancemessungen revisionssicher speichern. +Ergebnis: Schlanke Profiltabellen; Regressionsvergleich über gespeicherte Messreihen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Profiling\ProfilerBL.cs, ReorganizeProfilerEntries (Zeilen 26-68) - Begründung: Aggregation implementiert + - [PRIMÄR] src\backend\Centron.BL\Administration\PerformanceTests\PerformanceTestBL.cs, RunTests - Begründung: Guard+Persistenz +Prüfidee: Doppelte Tageslog-Zeilen → genau ein Aggregat-Eintrag. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Monitoring-/Telemetriekapitel (SwRS-106) +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-090 +Titel: Telefonie-Einstellungen in drei Ebenen (zentral/persönlich/clientlokal) +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator, Mitarbeiter +Vorbedingung: Settings-System erreichbar +Fakt: `PhoneSettingsBL` liest/schreibt zentrale TAPI-Parameter über AppSettingsBL und persönliche Erfassungsentscheidung in EmployeeUserSettings; RegistryBL ergänzt client-lokale Leitungskonfiguration. +Aussage: Das System soll Telefonieparameter mandantenweit, mitarbeiterbezogen und clientlokal trennen; Mitarbeiter entscheiden über die Erfassung ihrer Anrufdetails. +Ergebnis: Nummernformatierung zentral steuerbar; Datenschutzentscheidung je Mitarbeiter. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\PhoneSettings\PhoneSettingsBL.cs, Zeilen 27-119 - Begründung: beide Settings-Ebenen belegt +Prüfidee: IsIncomingCallDetailsDisabled=true → keine Anrufdetail-Erfassung. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Settingsebenen (SwRS-033, SwRS-096) +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-091 +Titel: Benutzerdefinierte Modul-Eigenschaften ohne Schemaänderung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: Anpassbarkeit (ISO 25010) +Akteur: Administrator (Customizing) +Vorbedingung: ObjectKind != Unknown +Fakt: `ModuleCustomPropertyBL.SaveCustomPropertyStructure` validiert Name/Datentyp, stillt nicht übermittelte sichtbare Eigenschaften (Soft-Handling) und setzt neue auf IsVisible=true. +Aussage: Das System soll je Modul typisierte Zusatzfelder definierbar machen, entfernte Definitionen stilllegen und keine unbenannten/untypisierten Definitionen zulassen. +Ergebnis: Kunden-Extensions ohne DB-Schemaänderung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Customization\ModuleCustomPropertyBL.cs, SaveCustomPropertyStructure (Zeilen 29-88) - Begründung: Validierung+Soft-Handling +Prüfidee: Property ohne DataType → Fehler; entfernte Property bleibt als Historie erhalten. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: CustomProperty + CustomTable (SwRS-092) als EAM-Kapitel +Übernahmewürdigkeit: übernehmen - Basis für Mandanten-Extensions +Status: belegt + +--- + +ID: SwRS-092 +Titel: Custom-Tabellen mit Platzhalterbefüllung aus dem Fachobjekt +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator/Fachanwender +Vorbedingung: Custom-Tabellendefinition vorhanden +Fakt: `CustomTableBL` ersetzt Platzhalter [PropName] per Reflexion durch Werte des Datenobjekts (Zeilen 25-42). +Aussage: Das System soll dynamische Zusatztabellen unterstützen, deren Felder automatisch aus kontextuellen Objektwerten befüllt werden. +Ergebnis: Konsistente Zusatzdaten ohne manuelle Übertragung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Customizations\CustomTables\CustomTableBL.cs, ReplaceColumnValueVariables - Begründung: Reflexions-Ersetzung implementiert +Prüfidee: Platzhalter [Customer.Name] wird durch echten Kundennamen ersetzt. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: mit SwRS-091 +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-093 +Titel: ChangeLog-Schreibregeln des ChangeTracking-Listeners +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: +Akteur: NHibernate-Layer +Vorbedingung: Attributierte Property, angemeldeter Benutzer, int-I3D +Fakt: `ChangeTrackingEventListener.OnPreUpdate` schreibt "{0} wurde von {1} auf {2} geändert."; ohne I3D/Benutzer wird übersprungen; History-Fehler werden nur geloggt; nur Updates erfasst. +Aussage: Das System soll die Änderungshistorie exakt nach diesen Regeln schreiben: attributsgesteuert, benutzerabhängig, best-effort, update-only. +Ergebnis: Vorhersagbares Auditverhalten mit dokumentierten Lücken. +Belege: + - [PRIMÄR] src\backend\Centron.DAO\ChangeTracking\ChangeTrackingEventListener.cs, OnPreUpdate/CreateChangeLog (Zeilen 52-142) - Begründung: Regelwerk gelesen + - [SEKUNDÄR] LogHourlySurchargeRateChangesListener.cs - Begründung: domänenspezifischer Sonderlistener +Prüfidee: Ohne angemeldeten Benutzer → Warnung, kein Satz; Attributlos → kein Satz. +Tracelinks: SyRS-033, StRS-015 +Konsolidierung: Kandidat: Auditgruppe +Übernahmewürdigkeit: übernehmen - Insert/Delete-Tracking im Ziel ergänzen +Status: belegt + +--- + +ID: SwRS-094 +Titel: Wiederverwendbare Massenänderungs-Vorlagen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Fachanwender (Vertrieb/Lager) +Vorbedingung: Eingeloggter Benutzer mit Mitarbeiterbezug +Fakt: `MassUpdateBL.SaveOrUpdateMassUpdate` setzt CreatedBy nur bei Neuanlage, stets Changed-Felder; Vorlagen per MassUpdateFilter durchsuchbar; keine Rechteprüfung in der BL auffindbar. +Aussage: Das System soll Massenänderungs-Vorlagen (Artikel, Anlagen, Kunden) mit Erstellernachweis speichern; die Zugriffsbeschränkung ist ausdrücklich zu regeln. +Ergebnis: Serienänderungen wiederholbar; wer-ändert-was protokolliert; Rechte-Gate offen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\MassUpdate\MassUpdateBL.cs, SaveOrUpdateMassUpdate (Zeilen 92-130) - Begründung: Auditlogik belegt, fehlender Rights-Check notiert +Prüfidee: Neue Vorlage → CreatedBy gesetzt; Änderer ≠ Ersteller → nur Changed-Felder neu. +Tracelinks: StRS-001, StRS-015 +Konsolidierung: Kandidat: mit ChangeTracking (SwRS-093) verzahnen +Übernahmewürdigkeit: übernehmen - Rechtekonzept vor Übernahme klären +Status: belegt + +--- + +ID: SwRS-095 +Titel: Prozessmodelle nur mit gültigen Schritttypen, atomar gespeichert +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Workflow-Designer +Vorbedingung: Prozesstyp im ProcessRegistry registriert +Fakt: `ProcessBL.SaveProcess/UpdateProcess` prüfen jede Schrittart gegen mapping.StepTypes (Exception "There are invalid steps...") und ersetzen Shapes/Bindings vollständig in einer Flush-Sequenz. +Aussage: Das System soll Workflow-Definitionen nur bei konsistenten Schritttypen akzeptieren und Formen/Bindings vollständig-atomar ersetzen. +Ergebnis: Keine hybriden Prozessdefinitionen; Änderungen rollbackfähig. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Processes\ProcessBL.cs, SaveProcess/UpdateProcess (Zeilen 75-117) - Begründung: Validierung+Atomarität implementiert +Prüfidee: Unbekannter Step-Kind → Exception; Abbruch mittendrin → Rollback. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Workflow-Subcluster (Services\Workflows) +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-096 +Titel: Fehlende ApplicationSettings on-demand mit Default anlegen +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: +Akteur: BL-interne Aufrufer +Vorbedingung: ApplicationSettingDefinitions vorhanden +Fakt: `AppSettingsBL.GetSettings` legt fehlende neue Einstellungen automatisch mit Default aus den Definitionen an; SettingsCollection kapselt typisierte Getter. +Aussage: Das System soll fehlende Einstellungsschlüssel selbstheilend mit definierten Defaults materialisieren und typisierten Zugriff erzwingen. +Ergebnis: Keine Null-Setting-Abstürze; Self-Healing-Konfiguration. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Settings\AppSettingsBL.cs, LoadNewSettingsOptimized (Zeilen 106-143) - Begründung: On-Demand-Legacy belegt + - [SEKUNDÄR] SettingsCollection.cs, IfYouUseThisYouAreWrong - Begründung: API-Disziplin im Code benannt +Prüfidee: Unbekannte ID lesen → Default-Entität existiert danach in DB. +Tracelinks: SyRS-029, StRS-001 +Konsolidierung: Kandidat: mit SyRS-029 +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-097 +Titel: Verbindungsdatei mit Fallbackkette und Trust-Optionen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Client beim Login +Vorbedingung: CentronConnections.xml an einem der Suchpfade +Fakt: `ConnectionBL` sucht Env CENTRON_CONNECTION_PATH → gemeinsame ProgramData → Installation/Roaming; führt Zertifikats-Trust-Optionen und 2FA-Flag je Profil. +Aussage: Das System soll Verbindungsprofile über eine deterministische Pfadpriorität laden und Trust-/2FA-Flags je Profil stützen. +Ergebnis: Vorhersagbare Profilauswahl in gemischten Umgebungen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Connections\ConnectionBL.cs, Get*ConfigPath (Zeilen 147-169) - Begründung: Fallbackkette kodiert +Prüfidee: Env-Variable gesetzt → diese Datei gewinnt. +Tracelinks: SyRS-032 +Konsolidierung: Kandidat: mit SyRS-032 +Übernahmewürdigkeit: Workaround - dateibasierte Haltung; Ziel: mandantenweite Profile +Status: belegt + +--- + +ID: SwRS-098 +Titel: Registry-Präferenzen und Typ-Isolation WebService/DB +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Windows-Client, System +Vorbedingung: Windows-Betriebssystem (IsWindows-Guards) +Fakt: `RegistryBL` speichert Anmeldememo, Theme (mit Versionsvergleich), TAPI-Konfiguration unter HKCU\Software\c-entron...; `SqlServerBL.CheckDatabaseMatchesWebService` verbietet c-entron-DB am Riverbird-WebService. +Aussage: Das System soll benutzerbezogene Clientpräferenzen pro Windows-Benutzer persistieren und Fehlkopplungen von WebService-/Datenbanktyp erzwingend ablehnen. +Ergebnis: Vorhersagbare Clientpräferenzen; keine Typ-Fehlkopplung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Environments\RegistryBL.cs - Begründung: Registry-Regionen belegt + - [PRIMÄR] src\backend\Centron.BL\Administration\Environments\SqlServerBL.cs, CheckDatabaseMatchesWebService - Begründung: harte Typ-Isolation +Prüfidee: Riverbird-WebService + c-entron-DB → Fehlermeldung mit Handlungshinweis. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Browser-Zielplattform → Registry durch profilierbaren Client-Speicher ersetzen +Übernahmewürdigkeit: Workaround - Registry plattformgebunden; Isolationregel übernehmen +Status: belegt + +--- + +ID: SwRS-099 +Titel: Nummernkreis-Fortschreibung mit Intervall und Restzähler +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: System bei Beleganlage +Vorbedingung: Nummernkreis mit Aktuell-Zähler +Fakt: `MandatoryBL.SaveNumberGroups/GetNumberGroup` fortschreiben per parameterisiertem UPDATE inkl. Intervall; Verbrauch (Aktuell<=0) wird übersprungen. +Aussage: Das System soll Nummernkreise zählerbasiert mit konfigurierbarem Intervall fortschreiben und verbrauchte Kreise automatisch überspringen. +Ergebnis: Lückenlose, intervall-korrekte Nummerierung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Mandatory\MandatoryBL.cs, Zeilen 38-96 - Begründung: UPDATE-Logik im Code +Prüfidee: Intervall 10: Nummern springen um 10; Aktuell=0 → Kreis übersprungen. +Tracelinks: SyRS-044, StRS-016 +Konsolidierung: Kandidat: mit NumberGroupBL zusammenführen (Doppelimplementierung) +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-100 +Titel: Versionsmeldung je Maschine/Benutzer mit Portal-Upload +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Client beim Login +Vorbedingung: Versionszeichenkette und Kundennummer vorhanden +Fakt: `ApplicationVersionBL.SaveLogin` schreibt/aktualisiert ApplicationKind+Maschine+User+IP+Version; unvalide Version → Warning; Portal-Upload asynchron, Fehler geschluckt. +Aussage: Das System soll die eingesetzte Clientversion je Maschine/Benutzer erfassen und fehlertolerant an das Herstellerportal melden. +Ergebnis: Versionsbestand je Kunde; Portal-Ausfälle blockieren Login nicht. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Applications\ApplicationVersionBL.cs, SaveLogin/UploadToServer (Zeilen 30-111) - Begründung: Erfassung+Async-Upload belegt +Prüfidee: Version "1.2" vs. "abc" → Warning; Portal offline → Login erfolgreich. +Tracelinks: SyRS-049, StRS-001 +Konsolidierung: Kandidat: Telemetrie-Kapitel (SwRS-106); Datenschutz (IP/Maschine) bewerten +Übernahmewürdigkeit: übernehmen - Einwilligung/Pseudonymisierung im Ziel prüfen +Status: belegt + +--- + +ID: SwRS-101 +Titel: Systemzähler als Einzelinstanz-Lieferant +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: BL-interne Aufrufer +Vorbedingung: SystemTableI3D-Tabelle existiert +Fakt: `SystemTableI3DBL.GetSystemTableI3D()` liefert den ersten TabellenEintrag; komplette Modulgröße: eine Klasse, 28 Zeilen. +Aussage: Das System soll den zentralen Systemzähler-Datensatz als Einzelinstanz für ID-/Systemzwecke bereitstellen. +Ergebnis: Eindeutiger Zugriff auf die Systemzählerinstanz. +Belege: + - [PRIMÄR] src\backend\Centron.BL\SystemArea\SystemTableI3DBL.cs, GetSystemTableI3D - Begründung: einziger Code des Moduls +Prüfidee: Aufruf liefert genau die eine Instanz; leere Tabelle → Verhalten klären. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: im ID-Vergabe-Kapitel aufgehen lassen +Übernahmewürdigkeit: veraltet - nur als Detailbeleg +Status: belegt + +--- + +ID: SwRS-102 +Titel: PDF-Ausgabestrategie mit PDF/A3-Pflicht-Fallback +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: Kompatibilität, Fehlertoleranz (ISO 25010) +Akteur: Anwender (Druckvorgang) +Vorbedingung: Bericht + Druckereinstellung vorhanden +Fakt: `PdfStrategies.GetPdfStrategy` prüft Benutzereinstellung, PDF/A3-Pflicht und Druckerexistenz und fällt auf FastReport-Standardstrategie zurück (Zeilen 62-78). +Aussage: Das System soll die konfigurierte PDF-Druckerstrategie verwenden, bei PDF/A3-Pflicht oder fehlendem Drucker automatisch auf den Standard zurückfallen. +Ergebnis: Druck gelingt immer; revisionspflichtige Ausgaben bleiben konform. +Belege: + - [PRIMÄR] src\backend\Centron.BL\ReportEngine\PdfStategy\PdfStrategies.cs, GetPdfStrategy - Begründung: Fallback-Kette implementiert + - [PRIMÄR] src\backend\Centron.BL\ReportEngine\ReportDataBL.cs, PDF-Erzeugung/Archivierung (Zeilen 1271-1347) - Begründung: Erzeugungs-/Archivpfad +Prüfidee: PDF/A3-Beleg mit deaktiviertem Drucker → FastReport-Ausgabe + Log. +Tracelinks: StRS-003, StRS-001 +Konsolidierung: Kandidat: ReportEngine Alt/Neu (SwRS-103) abgrenzen +Übernahmewürdigkeit: übernehmen - Compliance-Bezug +Status: belegt + +--- + +ID: SwRS-103 +Titel: Alt-Reportdefinitionen (Legacy "Reports") verwalten +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Bericht als Byte-Array vorhanden +Fakt: `ReportsBL` speichert CentronReport (Tabelle "Reports", Report als BLOB) samt SQL-Statements. +Aussage: Das System soll Legacy-Berichte (Byte-Inhalt, Metadaten, SQL) speichern und laden - als Bestandsschutz während der Migration. +Ergebnis: Berichtsvorlagen verfügbar; Migrationsgrundlage. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Reporting\ReportsBL.cs, SaveReport/GetReportStatement - Begründung: BL gelesen + - [PRIMÄR] src\backend\Centron.DAO\Mappings\Reporting\ReportsMaps.cs - Begründung: BLOB-Mapping +Prüfidee: Speichern/Neuladen → Byte-Inhalt identisch. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Alt (Reports) vs. Neu (ReportEngine) zusammenführen +Übernahmewürdigkeit: veraltet - Migrationsaltlast +Status: belegt + +--- + +ID: SwRS-104 +Titel: Statistiken aus vorberechneten Cache-Tabellen mit Eigenstatistiken +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: Performance-Effizienz (ISO 25010) +Akteur: Geschäftsführung/Disponent +Vorbedingung: Statistik-Caches gefüllt +Fakt: `CacheOrderStatisticsBL.GetAll` liest nur die Cache-Tabelle; `SaleStatisticBL` bietet benutzerdefinierte Statistiken (SaveCustomStatistic). +Aussage: Das System soll Statistiken aus vorberechneten Caches beantworten und eigene Statistikdefinitionen je Benutzer speichern/laden/löschen. +Ergebnis: Schnelle Auswertungen ohne Last auf Transaktionstabellen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Statistics\OrderStatistics\CacheOrderStatisticsBL.cs - Begründung: Cache-only-Zugriff + - [PRIMÄR] src\backend\Centron.BL\Statistics\SaleStatistics\SaleStatisticBL.cs, SaveCustomStatistic - Begründung: benutzerbezogene Definitionen +Prüfidee: Beleg buchen → Cache aktualisieren → Statistik zeigt ihn; Eigenstatistik Benutzer B nicht sichtbar. +Tracelinks: SyRS-042, StRS-001 +Konsolidierung: Kandidat: Unterstatistiken (MSP, Verträge, Tickets) als Mustervarianten zusammenführen +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-105 +Titel: Deutsche Volltextsuche mit Stemming UND-Verknüpfung +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: Funktionalität, Leistungsfähigkeit (ISO 25010) +Akteur: globale Suche +Vorbedingung: Indizes je Objektart gebaut/nachgeführt +Fakt: `IndexSearchBL` zerlegt Suchen mit GermanAnalyzer (Stemming de-DE, Stoppwörter) und verknüpft Treffermengen per Join auf alle Begriffe ("match ALL search-terms"). +Aussage: Das System soll Suchbegriffe sprachlich normalisieren und nur Objekte zurückgeben, deren Index alle Begriffe enthält. +Ergebnis: Präzise, morphology-resistente Suche über Objekttypen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\IndexSearch\IndexSearchBL.cs, Term-Joins (Zeilen 49-73) - Begründung: ALL-Semantik implementiert + - [PRIMÄR] src\backend\Centron.BL\IndexSearch\GermanAnalyzer.cs - Begründung: Stemmer/Stoppwörter +Prüfidee: "Rechnung/rechnen"-Stämme; Zwei-Begriff-Suche mit nur einem Treffer → leer. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Update-Request-Mechanik als Teilanforderung +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-106 +Titel: Telemetrie-Buckets mit Upload-Kennzeichnung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System (Hintergrund-Upload) +Vorbedingung: Nutzungsereignis (API/MCP/KI-Tool) erfasst +Fakt: `TelemetryBL` führt Buckets per Upsert zusammen, liefert "completed pending" und setzt UploadedDate; Mapping-Spalten BucketStartUtc/Count/UploadedDate. +Aussage: Das System soll Telemetrieereignisse gebündelt hochzählen, nur abgeschlossene Zeitfenster zur Übermittlung bereitstellen und übermittelte Buckets markieren. +Ergebnis: Geringe Schreiblast, idempotenter Upload. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Telemetry\TelemetryBL.cs, Upsert/GetCompletedPending/MarkUploaded - Begründung: Zyklus implementiert +Prüfidee: Zwei Aufrufe im Bucket → Count=2; nach MarkUploaded nicht mehr pending. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: API/MCP/AI-Varianten zu einer Anforderung; Datenschutz bewerten +Übernahmewürdigkeit: übernehmen - Datenschutzprüfung erforderlich +Status: belegt + +--- + +ID: SwRS-107 +Titel: Interne Dokumentation nur mit Leseberechtigung +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Servicemitarbeiter +Vorbedingung: Dokumentationsdatensatz mit Kategorie/Status/Versionen +Fakt: `DocumentationBL.GetDocumentation*` prüfen HasUserRight(READ_DOCUMENTATION / READ_INTERNAL_DOCUMENTATION) und filtern interne Dokumente ohne Recht. +Aussage: Das System soll Dokumentationslisten rechtsabhängig ausliefern und interne Dokumentation ohne Recht ausblenden. +Ergebnis: Keine unberechtigte Einsicht. +Belege: + - [PRIMÄR] src\backend\Centron.BL\DocumentationArea\DocumentationBL.cs, Zeilen 27-72 - Begründung: Prüfmuster in allen Listmethoden +Prüfidee: Ohne READ_INTERNAL_DOCUMENTATION → interne Dokumente fehlen. +Tracelinks: StRS-004 +Konsolidierung: nein (Modul dünn: Einzeldatei) +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-108 +Titel: Spezifischster Textbaustein je Benutzer/Kunde ermitteln +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System (Belegerstellung) +Vorbedingung: Textbausteine mit Typ-/Benutzer-/Kundenbezug gepflegt (Tabelle "Textbaustein") +Fakt: `TextModuleBL.GetOfferSalutation/GetOrderAgreement/...` wählen nach Benutzer-/Kundenfilter (Default 0 = global); SalutationAndAgreementReplacementBL ersetzt im Dokument. +Aussage: Das System soll Anrede-/Vereinbarungstexte nach der Regel "spezifischster gültiger Baustein" (benutzer > kunde > global) auflösen. +Ergebnis: Kundengerechte Brieftexte ohne je-Beleg-Pflege. +Belege: + - [PRIMÄR] src\backend\Centron.BL\TextModuleArea\TextModuleBL.cs, Resolver-Methoden (Zeilen 196-244) - Begründung: Filterlogik belegt + - [PRIMÄR] src\backend\Centron.DAO\TextModuleArea\TextModuleMaps.cs - Begründung: Legacy-Mapping Default 0 +Prüfidee: Kunden- und Globaltext gepflegt → Angebot zeigt kundenspezifischen Text. +Tracelinks: StRS-011, StRS-003 +Konsolidierung: Kandidat: Ersetzungssysteme (ExternalTools, CustomTables) vereinheitlichen +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-109 +Titel: Tags beim Verschlagworten reaktivieren +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Servicemitarbeiter +Vorbedingung: Ticket existiert; Tag-Name gegeben +Fakt: `TagsBL.AddTicketTag` legt fehlende Tags an, setzt ShowInSuggestions=true bei reaktivierten Tags und verknüpft Ticket↔Tag; Mapping-Default ShowInSuggestions=1. +Aussage: Das System soll beim Verschlagworten Tags bei Bedarf anlegen, reaktivieren und mit dem Ticket verknüpfen. +Ergebnis: Wiederverwendbare Tag-Nomenklatur. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Tags\TagsBL.cs, AddTicketTag (Zeilen 24-48) - Begründung: Reaktivierungslogik implementiert +Prüfidee: Deaktivierten Tag erneut vergeben → ShowInSuggestions wieder 1. +Tracelinks: StRS-013 +Konsolidierung: nein (Modul dünn; keine Rechteprüfung erkennbar) +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-110 +Titel: Auditfelder beim Anlegen über Repositories erzwingen +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: +Akteur: FachBL über Repository +Vorbedingung: LoggedInUser mit Mitarbeiterbezug bekannt +Fakt: `AccountRepository.CreateNewAccount` setzt CreatedByI3D/CreatedDate/CreatedVersion und Changed-Felder automatisch; DBEntity-Basisklasse führt die Felder. +Aussage: Das System soll beim Anlegen über Repositories Ersteller, Zeitpunkt und Anwendungsversion automatisch belegen. +Ergebnis: Lückenlose Herkunftsnachweise ohne Fachcode. +Belege: + - [PRIMÄR] src\backend\Centron.DAO\Repositories\Accounts\AccountRepository.cs, CreateNewAccount (Zeilen 39-52) - Begründung: Feldsetzung im Repository-Muster + - [SEKUNDÄR] src\backend\Centron.Entities\Entities\DBEntity.cs - Begründung: Auditfelder der Basisklasse +Prüfidee: Kunde anlegen → CreatedVersion = Assemblyversion, CreatedBy = angemeldeter Mitarbeiter. +Tracelinks: StRS-015 +Konsolidierung: Kandidat: "Save*-Repositories" als Sammelanforderung +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-111 +Titel: Feldlängen über typisierte UserTypes abbilden (Trunkierungsschutz) +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: Zuverlässigkeit (ISO 25010) +Akteur: Persistierungslauf +Vorbedingung: Property auf feste Spaltenlänge gemappt +Fakt: `TruncatedStringUserType.MappingExtensions` bildet Länge→UserType ab (Längentabelle Zeilen 14-44); weitere Typen für JSON, Listen, Enums, Delphi-Farbformate. +Aussage: Das System soll Zeichenkettenlängen über typisierte Adapter abbilden, damit Datenbank-Trunkierungsfehler vermieden und Legacy-Formate konvertiert werden. +Ergebnis: Stabiles Speichern gegen das Alt-Schema. +Belege: + - [PRIMÄR] src\backend\Centron.DAO\UserTypes\TruncatedStringUserType.cs, Längentabelle - Begründung: Adapter implementiert +Prüfidee: 300-Zeichen-Wert auf Length255-Feld → definiertes Verhalten statt SqlException. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Unteranforderung der Mapping-Konventionen (SyRS-034) +Übernahmewürdigkeit: übernehmen - Ziel-Schema bereinigt Längenprobleme, dann entbehrlich +Status: belegt + +--- + +ID: SwRS-112 +Titel: Zentrale Objekttyp-Nummern als domänenübergreifender Standard +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: alle Module (Anhänge, Rechte, Indizes referenzieren Objekte) +Vorbedingung: Objekt soll typisiert referenziert werden +Fakt: `ObjectType.ObjectTypeDictionary` fixiert Nummern (Offer=1, Order=2, Invoice=4, Helpdesk=10, Customer=5000012...); DbEntities spiegeln Legacy-Tabellen (Kunden, RechKopf). +Aussage: Das System soll Geschäftsobjekte über eine zentrale, unveränderliche Objekttyp-Nummernliste referenzieren; Legacy-Tabellen bleiben als eigene Entitätsgruppe getrennt. +Ergebnis: Versionsstabile Objektreferenzen über Module hinweg. +Belege: + - [PRIMÄR] src\backend\Centron.Entities\Entities\ObjectTypes\ObjectType.cs, Zeilen 6-33 - Begründung: Nummerndictionary gelesen +Prüfidee: Querschnittsprüfung: keine duplizierten Magic Numbers außerhalb des Dictionary. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Glossar/Datenmodell des Zielsystems +Übernahmewürdigkeit: übernehmen - als Terminologie des Migrationsdatenmodells +Status: belegt + +--- + +ID: SwRS-113 +Titel: KI-Chats strikt benutzergetrennt mit persistierter Historie +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: Vertraulichkeit (ISO 25010) +Akteur: angemeldeter App-Benutzer +Vorbedingung: AppUserI3D ermittelbar +Fakt: `ArtificialIntelligenceChatBL.GetChats` filtert !IsDeleted && AppUserI3D == appUserI3D; AddMessage speichert Rolle/Inhalt, LastMessagePreview max. 500 Zeichen; Provider-Clients (OpenAI, Gemini, Mistral, Claude) hinter IAiModelClient. +Aussage: Das System soll jedem Anwender eigene, nur ihm sichtbare KI-Chats mit Modellauswahl, Nachrichten- und ToolCall-Historie bereitstellen. +Ergebnis: Fremdchats liefern "Chat nicht gefunden"; Archivierung möglich. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\ArtificialIntelligence\Chat\ArtificialIntelligenceChatBL.cs, GetChats/AddMessage - Begründung: User-Filter implementiert + - [SEKUNDÄR] src\backend\Centron.BL\ArtificialIntelligence\Chat\OpenAiChatModelClient.cs u.a. - Begründung: Provider-Familie +Prüfidee: User B ruft ChatI3D von A → Fehler; Preview nach Assistant-Antwort aktualisiert. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: KI-Integrationskapitel (Prompts, Modelle) +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-114 +Titel: Checklisten an Objekte mit Pflicht-Caption, atomar gespeichert +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Fachanwender +Vorbedingung: Zielobjekt (ObjectKind+I3D) bekannt +Fakt: `CentronChecklistBL.SaveOrUpdateChecklists` wirft bei leerem Caption ArgumentException und nutzt StartTransaction/Flush/Commit. +Aussage: Das System soll Checklisten an beliebige Objektarten binden, leere Bezeichnungen ablehnen und Mehrfachspeicherung transaktional atomar halten. +Ergebnis: Persistierte Checkliste(n) oder Abbruch ohne Teilspeicherung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\CheckListArea\CentronChecklistBL.cs, SaveOrUpdateChecklists (Zeilen 71-118) - Begründung: Guard+Transaktionsklammer +Prüfidee: Caption="" → Exception, keine Liste gespeichert. +Tracelinks: StRS-013 +Konsolidierung: Kandidat: Abschluss-Checklisten-Regel (SwRS-127) nutzt dasselbe Modell +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-115 +Titel: Anbindung an c-pra (Nexoware Smartflow) +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Backend (systemgesteuert) +Vorbedingung: API-Zugangsdaten konfiguriert +Fakt: `CPraConnectorBL.ConnectToCPra` POSTet Login an https://c-pra.c-entron.de/restApi und liefert access_token; GetCPraWebHooks/-Link rufen Webhooks im Kunden-/Ticketkontext; Fehler nur geloggt, Rückgabe null. +Aussage: Das System soll sich bei der c-pra-REST-API anmelden und Webhooks/Weblinks abrufen, Fehler protokollieren statt abzuwürgen. +Ergebnis: Token/Webhooks oder null + Logeintrag. +Belege: + - [PRIMÄR] src\backend\Centron.BL\CPra\CPraConnectorBL.cs, ConnectToCPra/GetCPraWebHooks (Zeilen 23-130) - Begründung: Basis-URL/Login belegt +Prüfidee: Mock-401 → null + Logeintrag. +Tracelinks: SyRS-046 +Konsolidierung: Kandidat: Connector-Familie (null statt Result vereinheitlichen) +Übernahmewürdigkeit: Sonderfall - hartkodierte URL, Fehlersemantik null → Result +Status: belegt + +--- + +ID: SwRS-116 +Titel: Externe-Helpdesk-Konfiguration je Kunde/Kundenort +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Kunde/Kundenort existiert +Fakt: `ExternalHelpdeskConfigurationBL.SaveOrUpdateExternalHelpdeskConfiguration` speichert nach Guard.NotNull; Filter nach I3Ds/CustomerI3D/CustomerSiteI3D. +Aussage: Das System soll je Kunde oder Kundenort eine External-Helpdesk-Konfiguration anlegen, ändern, filtern und löschen. +Ergebnis: Konfigurationsdatensatz vorhanden; Filter liefert exakte Treffermenge. +Belege: + - [PRIMÄR] src\backend\Centron.BL\ExternalHelpdesk\ExternalHelpdeskConfigurationBL.cs, CRUD+Filter (Zeilen 19-68) - Begründung: vollständiges CRUD gelesen +Prüfidee: Zwei Kunden → Filter CustomerI3D=B liefert nur B. +Tracelinks: StRS-013 +Konsolidierung: Kandidat: an Helpdesk-/Riverbird-Integration (SyRS-048) andocken +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-117 +Titel: Externe Tools mit Namenspflicht und Variablenersetzung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator/Fachanwender +Vorbedingung: Toolname befüllt +Fakt: `ExternalToolBL.SaveExternalTool` prüft Name ("Es muss ein Name angegeben werden.") und pflegt Created/Changed-Audits; ReplaceExternalToolVariables delegiert an ExternalToolsReplacementBL. +Aussage: Das System soll externe Tool-Definitionen CRUD-fähig halten und zur Laufzeit Platzhalter im Tool-Text mit Kontextwerten ersetzen. +Ergebnis: Persistiertes Tool; ersetzter Text übergabefertig. +Belege: + - [PRIMÄR] src\backend\Centron.BL\ExternalToolsBL\ExternalToolBL.cs, Zeilen 21-64 - Begründung: Validierung+Ersetzung belegt +Prüfidee: Speichern ohne Name → Fehler; VariableData → ersetzter Text. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Ersetzungssysteme (SwRS-108) zusammenführen +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-118 +Titel: Helpdesk-Typen/Kategorien automatisch als virtuelle Checklistenkategorien +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: Konsistenz (ISO 25010) +Akteur: System (bei Abfrage) +Vorbedingung: Eltern-Kategorien HelpdeskType/HelpdeskCategory vorhanden +Fakt: `ChecklistVirtualObjectCategoryBL.GetChecklistVirtualObjectCategoriesByFilter` ruft bei CategoryKind.Checklists UpdateHelpdeskCategoriesAndTypes() auf: neue Typen werden angelegt, deaktivierte auf StatusType.Deleted gesetzt. +Aussage: Das System soll die virtuellen Checklistenkategorien automatisch mit dem Helpdesk-Typ/-Kategorie-Stamm synchron halten (Anlegen, Umbenennen, Stilllegen). +Ergebnis: Kategoriebäume ohne manuelle Pflege aktuell. +Belege: + - [PRIMÄR] src\backend\Centron.BL\ItPlanner\ChecklistVirtualObjectCategoryBL.cs, UpdateHelpdeskCategoriesAndTypes (Zeilen 30-96) - Begründung: Sync-Zweige implementiert +Prüfidee: Neuer HelpdeskType → nächster Kategorienaufruf enthält neuen Eintrag. +Tracelinks: StRS-013 +Konsolidierung: Kandidat: Auto-Sync bei Abfrage auf definierten Event verschieben (Nebenläufigkeit) +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-119 +Titel: Projektliste mit Erstellungsdatumfilter (rumpfhaft) +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Fachanwender +Vorbedingung: Projekte vorhanden +Fakt: `ProjectBL.GetProjectList(DateTime?)` filtert ErstelltAm oder liefert alle (einzige Klasse, 36 Zeilen; kein Save/Delete). +Aussage: Das System soll Projekte vollständig oder ab einem Mindest-Erstellungsdatum auflisten. +Ergebnis: Vollständige oder gefilterte Projektliste. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Projects\ProjectBL.cs, GetProjectList (Zeilen 17-33) - Begründung: beide Overloads gelesen +Prüfidee: Projekt alt/neu; Filter heute → nur neues Projekt. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: mit TicketProjekten (SwRS-120) und TicketProcess prüfen +Übernahmewürdigkeit: unklar - nur Lesezugriff, vermutlich auslaufend +Status: HYPOTHESE - Modul möglicherweise unvollständig/auslaufend; Save/Delete nirgends belegt + +--- + +ID: SwRS-120 +Titel: Ticketprojekte mit eigener Nummer und Soft-Delete-Aufgaben +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Mitarbeiter +Vorbedingung: NumberGroup TicketProject konfiguriert +Fakt: `TicketProjectBL.SaveOrUpdateTicketProject` verlangt ShortDescription (Guard) und vergibt bei Number<=0 GetNextNumber(NumberGroupEnum.TicketProject); Task-Löschung setzt IsActive=false. +Aussage: Das System soll Ticketprojekte automatisch nummerieren und Aufgaben soft-löschen; Abhängigkeiten/Nachrichten separat pflegbar. +Ergebnis: Nummeriertes Projekt; gelöschte Aufgabe bleibt inaktiv erhalten. +Belege: + - [PRIMÄR] src\backend\Centron.BL\TicketProjects\TicketProjectBL.cs, SaveOrUpdateTicketProject (Zeilen 60-103) - Begründung: Nummernkreis+Soft-Delete belegt +Prüfidee: Zwei Projekte ohne Nummer → aufeinanderfolgend; DeleteTask → IsActive=0. +Tracelinks: StRS-016, StRS-013 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-121 +Titel: Zeiterfassungs-Stammeinstellungen pflegen +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: - +Fakt: `TimingSettingsBL` bietet nur Get/SaveOrUpdate/Delete von TimingSetting mit I3Ds-Filter; keine Buchungs-/Stempellogik im Modul. +Aussage: Das System soll Zeiterfassungs-Einstellungen als Pflegeobjekt bereitstellen; die Buchungsliegand anderweitig (Timer in Sales\Support, CTime in Services). +Ergebnis: Einstellungsdatensatz CRUD-fähig. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Time\TimingSettingsBL.cs, Zeilen 16-60 - Begründung: reiner Settings-CRUD +Prüfidee: Save neuer Setting; Delete fremder I3D → Guard-Fehler. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Zeiterfassungs-Cluster (HelpdeskTimer, CTime) in Folgeiteration +Übernahmewürdigkeit: übernehmen (dünn) +Status: HYPOTHESE - fachlicher Zweck der Settings nicht ableitbar (keine Konsumenten belegt) + +--- + +ID: SwRS-122 +Titel: Benutzerbezogene Transaktionen mit Kategorie-Details +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: angemeldeter Benutzer +Vorbedingung: Benutzer bekannt +Fakt: `TransactionBL.GetTransactionsByUserId` filtert CreatedBy == i3D; Save/Update getrennt für Transaction und TransactionDetails je Kategorie. +Aussage: Das System soll Buchungs-Transaktionen je Benutzer mit separaten Detaildatensätzen pro Kategorie erfassbar halten. +Ergebnis: Transaktion+Details persistiert; benutzerbezogene Abmenge. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Transactions\TransactionBL.cs, Zeilen 41-120 - Begründung: Filter+Detail-Splitting belegt +Prüfidee: Transaktion mit 2 Details → by-UserId-Abfrage zeigt beide. +Tracelinks: StRS-001 +Konsolidierung: nein - fachlicher Kontext (Spesen?) unklar +Übernahmewürdigkeit: unklar - Fachzweck beizubestimmen +Status: HYPOTHESE - Verwendungszweck nicht aus Artefakten belegt + +--- + +ID: SwRS-123 +Titel: Aktive Gutschein-Barcodes per NamedQuery +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Kassen-/Vertriebsanwender +Vorbedingung: NamedQuery VoucherManagementGetVoucherArticles vorhanden +Fakt: `VoucherManagementBL.GetActivedVoucherBarcodes` übergibt drei Booleans als int-Parameter an die NamedQuery (einzige Methode, 27 Zeilen). +Aussage: Das System soll Gutscheine je Zustand (frei/ausgegeben/eingelöst) per Barcode-Abfrage liefern. +Ergebnis: Trefferliste Voucher. +Belege: + - [PRIMÄR] src\backend\Centron.BL\VoucherManagement\VoucherManagementBL.cs, Zeilen 17-25 - Begründung: einzige Methode +Prüfidee: Query mit Flag-Kombinationen gegen Testdaten. +Tracelinks: StRS-003 +Konsolidierung: Kandidat: Kassensystem-/Kampagnen-Cluster +Übernahmewürdigkeit: unklar - SQL extern, Konsumenten nicht belegt +Status: HYPOTHESE - SQL im NamedQuery-Pool; Zustandssemantik nicht verifizierbar + +--- + +ID: SwRS-124 +Titel: URLs als sichtbare, durchsuchbare Objekt-Links +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Fachanwender +Vorbedingung: Zielobjekt existiert +Fakt: `SimpleUrlBL.SaveOrUpdateSimpleUrl` mappt DTO inkl. Created/Changed-Audit; Filter über ObjectKind, IsVisible, Suchtext (Caption+URL, Lowercase). +Aussage: Das System soll Web-Links als beschriftete, sicht-/suchbare Einträge an Fachobjekte binden. +Ergebnis: URL-Liste je Objekt mit Volltextfilter. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Urls\SimpleUrlBL.cs, Zeilen 36-115 - Begründung: Filter+Audit belegt +Prüfidee: URL mit Caption anlegen → Suchtext-Filter trifft sie. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: WebLinks (SwRS-037) + SimpleUrl zusammenführen +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-125 +Titel: Objekt↔Fremdsystem-Referenzen typisiert verwalten +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Integrationsprozess +Vorbedingung: ObjectI3D/ObjectKind/Referenztyp (z.B. DocBee, JIRA) bekannt +Fakt: `ObjectExternalReferenceBL.GetReferencesForObjectByType` weist leeren Typ zurück ("cannot be empty"), sortiert nach Timestamp desc und kapselt Exceptions in Result. +Aussage: Das System soll Verknüpfungen zu externen Systemdatensätzen typisiert, gefiltert und zeitlich sortiert verwalten, Fehler als Result rückmelden. +Ergebnis: Referenzliste oder definierter Fehler. +Belege: + - [PRIMÄR] src\backend\Centron.BL\ObjectExternalReferences\ObjectExternalReferenceBL.cs, Zeilen 30-110 - Begründung: Query-/Error-Muster gelesen +Prüfidee: DocBee vs. JIRA → Typfilter liefert nur passenden Typ. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: DataExchange/Integrationskapitel +Übernahmewürdigkeit: übernehmen - sauberes Muster +Status: belegt + +--- + +ID: SwRS-126 +Titel: Modulstamm automatisch ergänzen, Favoriten je Mitarbeiter +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Anwender; System (Start) +Vorbedingung: Modulklasse mit GUID registriert +Fakt: `ModuleBL.DoCreateMissingInternalModulesInDB` legt unbekannte interne Module per GUID-Vergleich an; UpdateModuleFavorite via Repository. +Aussage: Das System soll interne Module automatisch in den Modulstamm einziehen und persönliche Modul-Favoriten führen. +Ergebnis: Vollständiger Modulstamm; Favoritenliste je Mitarbeiter. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Modules\ModuleBL.cs, Zeilen 22-81 - Begründung: Auto-Anlage+Favoriten implementiert +Prüfidee: Neue Modulklasse ohne DB-Eintrag starten → Modul Internal=true vorhanden. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Navigations-/Shell-Backlog +Übernahmewürdigkeit: übernehmen (plattform) +Status: belegt + +--- + +ID: SwRS-127 +Titel: Ticketabschluss nur mit Recht und erledigter Abschluss-Checkliste +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Helpdesk-Bearbeiter +Vorbedingung: Zielstatus Closed; aktive Abschluss-Checkliste möglich +Fakt: `HelpdeskBL.CheckUserRigths` verlangt CLOSE_REQUEST (Web: WEBRIGHT_CLOSEALLEREQUEST) bei Closed, sonst Fehler "Sie haben nicht das Recht 'Helpdesk abschließen'."; `UpdateHelpdeskBL.CanHelpdeskClose` blockiert offene Punkte ("Checkliste ... noch nicht vollständig erledigt."). +Aussage: Das System soll den Ticketabschluss zwingend an das Abschlussrecht und die Erledigung aller abschlussrelevanten Checklistenpunkte binden. +Ergebnis: Speichern ohne Recht/Checkliste → Result-Fehler, DB unverändert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs, CheckUserRigths (Zeilen 428-443) - Begründung: Durchsetzung im BL-Speicher-Hook (gilt für Desktop/Web/Schnittstellen) + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\UpdateHelpdeskBL.cs, UpdateStatus/CanHelpdeskClose (Zeilen 457-517) - Begründung: einzige Aufrufstelle des Abschlussübergangs +Prüfidee: Ohne Recht → RightCheckFailed; offenen CanClose-Punkt → Fehler; Punkt erledigt → Übergang gelingt. +Tracelinks: SyRS-043, StRS-013 +Konsolidierung: Kandidat: mit SwRS-045/SyRS-043 Abschluss-Portfolio +Übernahmewürdigkeit: übernehmen - klassische, erzwungene Geschäftsregel +Status: belegt + +--- + +ID: SwRS-128 +Titel: Single-Instance-Start der Desktop-Anwendung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: ERP-Anwender/Betriebssystem +Vorbedingung: Anwendungsaufruf mit/ohne Parameter +Fakt: `App`-Konstruktor nutzt `StartupArgSynchronizer.TryPassArgsToRunningApp` und Shutdown bei bestehender Instanz; Lizenzinitialisierung + Splash vor Shell. +Aussage: Das System soll Mehrfachstarts vermeiden, Startparameter an die laufende Instanz übergeben und die Shell erst nach Lizenz-/Initialisierungsphase zeigen. +Ergebnis: Eine Instanz je Arbeitsplatz; Objekt-Sprung-Parameter erreichen die Live-Instanz. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\App.xaml.cs, Zeilen 68, 97-126 - Begründung: Startregie gelesen +Prüfidee: Zweitstart mit Argumenten → kein zweites Fenster, Zielobjekt in erster Instanz. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: mit SwRS-129 "Start und Anmeldung" +Übernahmewürdigkeit: Workaround - Desktop-Muster; Web-Zielsystem löst das über Sessions +Status: belegt + +--- + +ID: SwRS-129 +Titel: Anmeldung als Pflicht-Gate vor der Arbeitsfläche +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Anwender +Vorbedingung: Shell initialisiert +Fakt: `FrontWindow.Login()` kollabiert die Shell, zeigt den Login-Dialog und schließt das Fenster bei Fehlschlag. +Aussage: Das System soll die Arbeitsfläche erst nach erfolgreicher Anmeldung freigeben und bei Abbruch sauber herunterfahren. +Ergebnis: Ohne Anmeldung keine Modulzugriffe; Abbruch = kein Restprozess. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\FrontWindow.xaml.cs, Login (Zeilen 218-263) - Begründung: Login-Gate implementiert + - [KONTEXT] src\backend\Centron.BL\Administration\Logins\TicketBL.cs - Begründung: Sitzungsticket nach Login +Prüfidee: Login abbrechen → Anwendung endet ohne Restprozess; Erfolg → Ribbon sichtbar. +Tracelinks: SyRS-002, StRS-004 +Konsolidierung: Kandidat: mit SwRS-128 +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-130 +Titel: Modul-Layout je Benutzerprofil speichern/zurücksetzen +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: Benutzerfreundlichkeit (ISO 25010) +Akteur: Anwender +Vorbedingung: Fachmodul geöffnet +Fakt: `SaveLayoutBarItem_OnItemClick` ruft `UserFormSettingsManager.SaveModuleLayout` auf; Profilwechsel lädt Layout pro Profiltyp. +Aussage: Das System soll die UI-Anordnung eines Moduls benutzerprofilspezifisch speichern und zurücksetzen können. +Ergebnis: Individuelle Anordnungen bleiben erhalten; Reset stellt Default her. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\FrontWindow.xaml.cs, Zeilen 78-81, 432-452 - Begründung: Speichern/Zurücksetzen beobachtet +Prüfidee: Spalten verschieben, speichern, Neustart → hält; Reset → Default. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Profile/Settings-Familie (SwRS-033) +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SwRS-131 +Titel: Konfigurierbare Pflichtfelder in der Belegmaske +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Belegbearbeiter; Administration +Vorbedingung: Beleg in Bearbeitung +Fakt: `ReceiptViewModel` erzwingt Pflicht-Custom-Properties per ShowInputDialog ("... ist Pflichtfeld", Zeile 3960); Belegeinstellungen konfigurieren Pflichtfelder deklarativ. +Aussage: Das System soll die Belegspeicherung von administrativ konfigurierbaren Pflichtfeldern (Überschrift, Kostenstelle, Kostenträger, Lieferdatum) abhängig machen. +Ergebnis: Unvollständige Belege werden mit namentlicher Feldliste abgewiesen. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\Finances\Receipts\ReceiptViewModel.cs, Zeilen 3960, 1880-1883 - Begründung: erzwungene Prüfung im Speichernpfad + - [SEKUNDÄR] GeneralSettingsView.xaml (Zeile 77) - Begründung: deklarative Konfiguration +Prüfidee: Pflichtfeld Kostenstelle aktivieren → Speichern ohne Kostenstelle → Fehler mit Feldname. +Tracelinks: StRS-011, StRS-003 +Konsolidierung: Kandidat: Pflichtfeld-Requirements der Masken bündeln +Übernahmewürdigkeit: übernehmen - Kernvalidierung der Belegerfassung +Status: belegt + +--- + +ID: SwRS-132 +Titel: Inline-Feldvalidierung E-Mail/IBAN in der Adressmaske +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: Funktionsfähigkeit, Fehlertoleranz (ISO 25010) +Akteur: CRM-Anwender +Vorbedingung: Adressstamm-Maske geöffnet +Fakt: `CrmInfoTabView.BaseEdit_OnValidate` prüft E-Mails per Regex-Maske; `CrmFinanceView` prüft `IbanValidation.IbanChecksumCheck` mit Critical-Fehler. +Aussage: Das System soll E-Mail-Adressen und IBANs inline mit Critical-Meldung validieren, bevor Daten den Datensatz verlassen. +Ergebnis: Tippfehlerhafte Kontaktdaten/IBANs rot markiert ("... keine gültige E-Mail-Adresse"). +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\Finances\Crm\Info\CrmInfoTabView.xaml.cs, Zeilen 19-38 - Begründung: Validierungsereignis verifiziert + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\Finances\Crm\Finance\CrmFinanceView.xaml.cs, Zeilen 24-35 - Begründung: IBAN-Checksummenprüfung +Prüfidee: IBAN falsche Prüfziffer → Critical-Error; gültige → kein Fehler. +Tracelinks: StRS-005 +Konsolidierung: Kandidat: Feldvalidierungen aller CRM-Tabs bündeln +Übernahmewürdigkeit: übernehmen - präzise, direkt prüfbar +Status: belegt + +--- + +ID: SwRS-133 +Titel: Custom-Gateway-BL für kundenindividuelle openTRANS-Integrationen +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Externes Portal/OpenTRANS-Teilnehmer +Vorbedingung: Individuelle Gateway-Integration aktiviert +Fakt: Einzige Klasse `CustomGatewayBL : BaseBL` importiert openTRANS, Beleg-/Vertrags-/Artikel-Entities und Centron.Interfaces.Gateway; REST-Part CentronRestService.CustomGateway.cs vorhanden. +Aussage: Das System soll kundenspezifische Gateway-Vorgänge (Bestellung/Vertrag/Artikel via openTRANS) in einer gekapselten BL bündeln statt im Kern. +Ergebnis: Individualintegrationen isoliert; Kern stabil. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Gateway\CustomGatewayBL.cs - Begründung: Klasse existiert (Methoden nicht im Detail gelesen) + - [SEKUNDÄR] src\webservice\Centron.Host\Services\CentronRestServiceParts\CentronRestService.CustomGateway.cs - Begründung: Endpunkt-Datei vorhanden +Prüfidee: ICustomGatewayBL-Schnittstelle und REST-Methoden durchtesten. +Tracelinks: SyRS-039, StRS-001 +Konsolidierung: Kandidat: mit Gateway-Formaten (SyRS-039) +Übernahmewürdigkeit: Sonderfall - kundenspezifisch +Status: HYPOTHESE - Methodenumfang nicht gelesen; Aufrufverbindung nur vermutet + +--- + +ID: SwRS-134 +Titel: Externe ElectronicSales-Gruppen/Rollen lokal spiegeln +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Administration (Integration) +Vorbedingung: Externe IDs aus ElectronicSales liegen vor +Fakt: `EsCustomerGroupBL.GetByExternalId/Create` spiegelt Gruppen über ExternalId mit Duplikatschutz (HashSet vorhandener IDs); EsRoleBL analog; kein HTTP-Aufruf im Modul. +Aussage: Das System soll externe ElectronicSales-Gruppen/-Rollen mit eindeutiger ExternalId lokal spiegeln und für Auswahlzwecke (IsActive) bereitstellen. +Ergebnis: Konsistente Zuordnungsgrundlage zur Synchronisation. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Integrations\EsCustomerGroupBL.cs, GetByExternalId/Create - Begründung: Duplikat-/Lookup-Logik gelesen +Prüfidee: Duplikatanlage zweimal → nur ein Satz. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: mit eigentlichem ES-Sync (außerhalb des Moduls) zusammenführen +Übernahmewürdigkeit: Sonderfall - nur mit ElectronicSales-Kopplung +Status: HYPOTHESE - eigentlicher Sync-Abruf außerhalb des Moduls; End-to-End-Verhalten unbelegt diff --git a/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/SyRS.md b/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/SyRS.md new file mode 100644 index 00000000..66e0f54c --- /dev/null +++ b/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/SyRS.md @@ -0,0 +1,1033 @@ +# SyRS - System Requirements Specification + +Quelle: c-entron ERP-Suite. Ebene SyRS: Systemverhalten, Schnittstellen, Sicherheit, Performance. +Jede SyRS referenziert ihre StRS (Tracelinks). Pfade relativ zum Arbeitsverzeichnis. + +--- + +ID: SyRS-001 +Titel: API-Aufrufe nur mit deklariertem Benutzerrecht +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: API-Client (authentifizierter Benutzer) +Vorbedingung: Endpunkt ist mit Autorisierungsattribut dekoriert +Fakt: `UserRightAuthorizationFilter.OnAuthorization`: `User == null → 401`; `!HasUserRight(right) → 403`; AllUserRights-Filter verlangt `.All(...)`, Any-Filter `.Any(...)`. +Aussage: Das System soll jeden markierten API-Endpunkt nur bei Nachweis des deklarierten Rechts (bzw. aller/einer der Rechte) ausführen und sonst HTTP 401/403 liefern. +Ergebnis: 401 ohne Authentifizierung, 403 ohne Recht, Action nur bei Rechtsnachweis. +Belege: + - [PRIMÄR] src\webservice\Centron.Controllers\Authorization\AuthorizeUserRightAttribute.cs, UserRightAuthorizationFilter.OnAuthorization - Begründung: durchsetzende Filterstelle + - [PRIMÄR] src\webservice\Centron.Controllers\Authorization\AuthorizeAllUserRightsAttribute.cs, AllUserRightsAuthorizationFilter - Begründung: UND-Verknüpfung belegt + - [SEKUNDÄR] src\webservice\Centron.Controllers\Authorization\README.md, Tabelle HTTP Response Codes - Begründung: dokumentiertes Verhalten +Prüfidee: Markierter Endpunkt: ohne Login 401; ohne Recht 403; mit Recht 200. +Tracelinks: StRS-004; SwRS-001, SwRS-002 +Konsolidierung: Kandidat: mit SyRS-003 zu einem Rechte-/Lizenzprüfkapitel +Übernahmewürdigkeit: übernehmen - deklaratives, dokumentiertes Autorisierungsmuster +Status: belegt + +--- + +ID: SyRS-002 +Titel: Mehrstufiger Anmeldeprozess mit Zweitfaktor (RADIUS oder E-Mail-Link) +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Benutzer/Web-Account mit 2FA; externer RADIUS-Server, Mail-Empfänger +Vorbedingung: `TwoFactorAuthEnabled == true` und `user.UseTwoFactorAuthentication == true` +Fakt: `TwoFactorAuthBL.ValidateTwoFactor` wählt `RadiusTwoFactorValidator` oder `EmailTwoFactorValidator`; RADIUS-Ablehnung wirft, E-Mail-Link hat Timeout; Freigabe gilt `TwoFactorValidDurationInDays` je Benutzer+Anwendung+Rechner+IP. +Aussage: Das System soll die Anmeldung bei aktivierter 2FA erst nach erfolgreicher Zweitbestätigung innerhalb Timeout gewähren und die Freigabe je Gerät für die konfigurierte Dauer merken. +Ergebnis: Ohne fristgerechte Bestätigung schlägt die Anmeldung fehl (`TwoFactorAuthFailed`). +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\TwoFactor\TwoFactorAuthBL.cs, ValidateTwoFactor/HasToValidateTwoFactor - Begründung: zentrale Erzwinger-/Umgehungslogik + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\TwoFactor\RadiusClient.cs, ValidateCredentials (AccessReject → Exception) - Begründung: konkrete Abweisprüfung + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\TwoFactor\EmailTwoFactorValidator.cs, CancelAfter(Timeout) - Begründung: Timeout-Erzwingung +Prüfidee: 2FA aktiv, kein Linkklick im Timeout → Loginfehler; danach kein Zweitfaktor N Tage auf demselben Rechner. +Tracelinks: StRS-004, StRS-008; SwRS-003, SwRS-004 +Konsolidierung: Kandidat: Login-Kette mit SyRS-005 (Ticketvergabe) und SyRS-006 +Übernahmewürdigkeit: übernehmen - konfigurierbarer 2FA-Prozess +Status: belegt + +--- + +ID: SyRS-003 +Titel: Lizenz- und Hosted-Schranke für interne Funktionen und Modulzugriffe +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Aufrufer interner Endpunkte/Funktionen; c-entron-Installation +Vorbedingung: Autorisierungspipeline konfiguriert +Fakt: `CentronHostedHandler.HandleRequirementAsync` succeeded nur bei `HasLicense(CentronInternal)`; OIDC-Anmeldung ohne Lizenz gesperrt; viele Fachmodule wiederholen das Muster `HasLicense(...)` pro Methode. +Aussage: Das System soll c-entron-interne Endpunkte und lizenzpflichtige Modulfunktionen über den Nachweis der jeweiligen Lizenz absichern; in Kundeninstallationen ohne Lizenz ist der Zugriff zu verweigern. +Ergebnis: 403 bzw. Fachfehler ohne Lizenz; interne von Kundeninstallationen getrennt. +Belege: + - [PRIMÄR] src\webservice\Centron.Controllers\Authorization\CentronHostedAuthorization.cs, CentronHostedHandler.HandleRequirementAsync - Begründung: einzige Erfolgsbedingung der Policy + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\Auth\OpenIdConnectAuthenticator.cs, AuthenticateInternal (Lizenzprüfung) - Begründung: Anmeldesperre im Auth-Strang +Prüfidee: Ohne CentronInternal-Lizenz liefert [AuthorizeCentronHosted] 403; mit Lizenz 200. +Tracelinks: StRS-004; SwRS-006, SwRS-024 +Konsolidierung: Kandidat: Lizenz-Guards aller Module zu einer Systemanforderung zusammenfassen +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SyRS-004 +Titel: DSGVO-Löschung personenbezogener Daten nur für Berechtigte, mit Protokoll +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Benutzer mit DSGVO-Rechten +Vorbedingung: Benutzer angemeldet; DSGVO-Modulfeature verfügbar +Fakt: `DataSecurityBL.DsgvoDeleteRightDeleteContacts` prüft `HasUserRight(DSGVO_DELETE_CONTACT)` sonst "Insufficient rights!"; Bereinigung verlangt zusätzlich `ACCESS_CLEANUP_DATABASE` + Modulfeature; Anonymisierung nullt Personenfelder und schreibt Löschprotokoll. +Aussage: Das System soll Bereinigungsstatistiken und das Anonymisieren/Löschen personenbezogener Ansprechpartner nur mit den jeweiligen Rechten gestatten und jede Löschung protokollieren. +Ergebnis: Unberechtigte Abweisung; Löschprotokoll als Nachweis. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\DataSecurity\DataSecurityBL.cs, DsgvoDeleteRightDeleteContacts (Zeile 789) - Begründung: Durchsetzungsstelle der Löschaktion + - [PRIMÄR] src\backend\Centron.BL\Administration\DataSecurity\DataSecurityBL.cs, GetDataSecurityCleanUpStats (Zeile 36) - Begründung: doppelte Torprüfung + - [SEKUNDÄR] src\backend\Centron.BL\Administration\Rights\DefaultRightsStructure.txt, Gruppe "c-entron DSGVO Löschrecht" - Begründung: vordefinierter Rechteträger +Prüfidee: Aufruf ohne Recht → "Insufficient rights!"; mit Recht → Felder genullt + Protokoll. +Tracelinks: StRS-004, StRS-015; SwRS-009 +Konsolidierung: Kandidat: mit SyRS-003 (Lizenz-/Feature-Schranken) +Übernahmewürdigkeit: Sonderfall - Kunden-/Lieferantenlöschpfad noch NotImplemented, nur Ansprechpartner aktiv +Status: belegt + +--- + +ID: SyRS-005 +Titel: Ticketvergabe nach Rechts- und Lizenzprüfung, zeitlich befristet +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Authentifizierter Benutzer einer c-entron-Anwendung +Vorbedingung: Authentifizierung erfolgreich, ApplicationKind ermittelt +Fakt: `Authenticator.AuthenticateUser` prüft `DisallowingRight`/`RequiredRight` (sonst RightCheckFailed) und erst dann `LicenseManager.CheckLicense` (`currentlyUsed >= max → LicenseMaximumReached`); `TicketBL` setzt Ablauf 30/5/1440 Minuten je Anwendungstyp. +Aussage: Das System soll Sitzungstickets nur nach anwendungsspezifischer Rechtsprüfung und bei freiem Lizenzplatz ausstellen und zeitlich begrenzen. +Ergebnis: Kein Ticket ohne Recht/Lizenzplatz; Tickets verfallen nach konfigurierter Laufzeit. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\Auth\Authenticator.cs, ValidateRights/AuthenticateUser - Begründung: Durchsetzung vor Ticketvergabe + - [PRIMÄR] src\backend\Centron.BL\Administration\Licensing\LicenseManager.cs, CheckLicense - Begründung: Kapazitätsgrenze erzwungen + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\TicketBL.cs, GetExpireDate (30/5/1440) - Begründung: konkrete Laufzeiten +Prüfidee: Benutzer ohne RequiredRight → RightCheckFailed; (n+1)-ter Login bei n Lizenzen → Fehler; Ticket nach Ablauf ungültig. +Tracelinks: StRS-004; SwRS-003 +Konsolidierung: Kandidat: mit SyRS-002 (Login-Kette) +Übernahmewürdigkeit: übernehmen - Mehrfachprüfung Recht/Lizenz/Zeit +Status: belegt + +--- + +ID: SyRS-006 +Titel: Every REST request must pass ticket/token authentication +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: REST-Clients (WPF, Nexus, Integrationen) +Vorbedingung: Request führt `Authorization: Bearer` oder `access_token` +Fakt: `CentronHost.Start()` registriert Ticket-Schema + JWT-Bearer und beendet die Routenregistrierung mit `MapControllers().RequireAuthorization()`; `TicketAuthenticationHandler.HandleAuthenticateAsync` liefert bei ungültigem Token `AuthenticateResult.Fail`. +Aussage: Das System soll jede Controller-Anfrage gegen ein registriertes Ticket, Access-Token oder konfiguriertes JWT prüfen und unbekannte/ungültige Nachweise ablehnen. +Ergebnis: Nicht authentifizierten Aufrufen wird die Bearbeitung verwehrt; gültige Tickets werden auf AppUser-Claims abgebildet. +Belege: + - [PRIMÄR] src\webservice\Centron.Host\AspNetCore\TicketAuthenticationHandler.cs, HandleAuthenticateAsync/ValidateTicketOrAccessToken - Begründung: Durchsetzungsstelle + - [PRIMÄR] src\webservice\Centron.Host\CentronHost.cs, MapControllers().RequireAuthorization() - Begründung: globales Endpunkt-Gate +Prüfidee: REST-Aufruf ohne/gefälschtes Ticket → Ablehnung; gültiges Ticket → Claims korrekt. +Tracelinks: StRS-004; SwRS-002, SwRS-053, SwRS-054 +Konsolidierung: Kandidat: mit SyRS-007 (Nexus-Auth) zu Authentifizierungsverbund +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SyRS-007 +Titel: Nexus-Host authentifiziert per Cookie/Ticket oder OIDC und stellt Sitzung aus +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Mitarbeiter (Browser), c-entron-WebService als Identitätsquelle +Vorbedingung: Host mit konfigurierter Webservice-URL und OIDC-Optionen +Fakt: `Program.cs` registriert Cookie-Scheme (`LoginPath="/auth"`) plus OpenID Connect (`ResponseType=code`); `AuthController.Finish` tauscht Webservice-Ticket via `authService.CreatePrincipal(ticket)` gegen Cookie-Principal. +Aussage: Das System soll Anmeldungen per Ticket/Cookie oder OIDC durchführen und nach Provider-Erfolg ein c-entron-Ticket anfordern und als Sitzungscookie ausstellen. +Ergebnis: Angemeldete Session mit Centron-Claims; OIDC-Temp-Cookie wird sofort wieder abgemeldet. +Belege: + - [PRIMÄR] src\nexus\CentronNexus.Host\Program.cs, Zeilen 264-289 (Auth-Registrierung) - Begründung: durchsetzende Stelle + - [PRIMÄR] src\nexus\CentronNexus\Shared\Auth\AuthController.cs, Finish/CreatePrincipal - Begründung: Ticket-Gegenprüfung vor SignIn +Prüfidee: Unauthentisiert `/serviceboard/...` → Redirect `/auth`; OIDC-Flow mit Cookie-Nachweis. +Tracelinks: StRS-004; SwRS-044, SwRS-051 +Konsolidierung: Kandidat: mit SyRS-006 und SyRS-008 +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SyRS-008 +Titel: Umschaltung der Systemauthentifizierung auf OpenID Connect (Entra ID) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Administrator (Settings-Seite) +Vorbedingung: Lizenz OpenIDConnectAuthentication; OIDC-Metadaten erreichbar +Fakt: `Settings\Authentication\Authentication.razor` kapselt OIDC in Lizenz-Gate mit Neustart-Hinweis; `OpenIdConnectConfigurationService.RefreshOptions` überschreibt Authority/ClientId/ValidAudience live; `AuthController.UpdateSystemAuthenticationToOpenIdConnect` setzt die Backend-Einstellung. +Aussage: Das System soll die Systemauthentifizierung per Settings-UI auf OIDC umstellen, die OIDC-Parameter laufend vom Backend nachziehen und die Änderung lizenzgeschützt verwalten. +Ergebnis: OIDC-Login ohne appsettings-Manipulation aktiv; Erfolg/Misserfolg per Query-Flag rückgemeldet. +Belege: + - [PRIMÄR] src\nexus\CentronNexus\Configuration\OpenIdConnectConfigurationService.cs, RefreshOptions (Zeilen 21-38) - Begründung: Options-Aktualisierung erzwungen + - [PRIMÄR] src\nexus\CentronNexus\Settings\Authentication\Authentication.razor (Route, Lizenz-Gate) - Begründung: Verwaltungsoberfläche +Prüfidee: OIDC speichern → Options aktualisiert; ohne Lizenz ist der Abschnitt ausgeblendet. +Tracelinks: StRS-004 +Konsolidierung: Kandidat: mit SyRS-007 (Auth-Verfahren) +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SyRS-009 +Titel: Outlook-AddIn-Einbettung mit iframe-fähiger Cookie-Policy +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Mitarbeiter im Outlook-iframe des Add-Ins +Vorbedingung: AddIn-Manifest deployed, Nexus-Host erreichbar +Fakt: `Program.cs` ruft `UseAllowXFrameOptionsForCentronNexus()` und `UseOutlookCookiePolicy()`; Logout erhält `addin=outlook` für SameSite=None/Secure-Policy. +Aussage: Das System soll Nexus-Komponenten im Outlook-iframe lauffähig machen (Frame-Freigabe, Cookie-Policy, AddIn-Kontext für Login/Logout). +Ergebnis: funktionierende AddIn-Sitzung ohne geblockte Session-Cookies. +Belege: + - [PRIMÄR] src\nexus\CentronNexus.Host\Program.cs, Zeilen 415-418 (Middleware) - Begründung: Middleware erzwingt Verhalten + - [PRIMÄR] src\nexus\CentronNexus\Shared\Auth\AuthController.cs, Logout addin=outlook-Weiche - Begründung:登录-Kontextsteuerung +Prüfidee: AddIn laden → Login `/auth/outlook?addin=outlook`; Auth-Cookie mit SameSite=None; Secure. +Tracelinks: StRS-004 +Konsolidierung: Kandidat: Cookie-/Port-Aspekte mit SyRS-007 +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SyRS-010 +Titel: Fortlaufende Rechnungsnummern je Nummernkreis (Bar-/Internal-/Normalrechnung) +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Funktionale Sicherheit (ISO 25010) +Akteur: System bei Belegspeicherung +Vorbedingung: Nummernkreise je Belegart/Filiale gepflegt +Fakt: `ReceiptBL.UpdateReceiptNumber` ruft `NumberGroupBL.GetNextNumber` je von `GetNumberGroup(receipt)` ermitteltem Kreis; `InvoiceSpecificLogic.GetNumberGroup` wählt CashInvoice bzw. InternalInvoice bei Netto-0-Dienstleistungsbelegen. +Aussage: Das System soll jede Rechnung automatisch fortlaufend aus dem fachlich passenden, filialbezogenen Nummernkreis numerieren; Bar- und Nullwertrechnungen sind am Kreis unterscheidbar. +Ergebnis: Keine Doppelvergabe; GoBD-taugliche lückenlose Nummerierung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, UpdateReceiptNumber (Zeilen 7265-7285) - Begründung: Single Enforcement Point + - [SEKUNDÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\InvoiceSpecificLogic.cs, GetNumberGroup (Zeilen 104-141) - Begründung: Kreis-Auswahllogik +Prüfidee: Parallelrechnungen → lückenlose Nummern; Netto-0-Servicebeleg → InternalInvoice-Kreis. +Tracelinks: StRS-016, StRS-003; SyRS-044 +Konsolidierung: Kandidat: Nummernkreis-Sammelanforderung aller Belegarten +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SyRS-011 +Titel: Rechnungsexport-Kennzeichnung steuert Änderung und Storno +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Debitorenbuchhaltung, System +Vorbedingung: Buchhaltungssystem gepflegt; Export erfolgt oder nicht +Fakt: `ReceiptBL.HandleIsAlreadyExported` verlangt Bestätigung vor neuer Version bei `IsReceiptExported`; `CancelInvoice` verbietet Storno nach Export vollständig; Konten kommen aus dem Standard-Buchhaltungssystem. +Aussage: Das System soll Änderungen an exportierten Rechnungen nur nach ausdrücklicher Bestätigung als neue Version zulassen und das Storno nach Export vollständig verhindern. +Ergebnis: Exportierte Belege sind vor stillschweigender Änderung geschützt; Versionshistorie bleibt erhalten. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, HandleIsAlreadyExported (Zeilen 8478-8498) - Begründung: durchsetzende Weiche + - [SEKUNDÄR] src\backend\Centron.BL\DataExchange\BookKeeping\BookKeepingExportBL.cs, IsReceiptExported - Begründung: maßgeblicher Exportstatus +Prüfidee: Exportierter Beleg: neue Version nur nach Dialogbestätigung; Storno → endgültiger Fehler. +Tracelinks: StRS-003; SwRS-011 +Konsolidierung: Kandidat: Sammelanforderung "Schnittstelle Finanzbuchhaltung" +Übernahmewürdigkeit: übernehmen - GoBD-Belegbewahrung +Status: belegt + +--- + +ID: SyRS-012 +Titel: Mahnlauf: stufenweise Eskalation überfälliger Rechnungen, transaktional +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: Zuverlässigkeit (Transaktionalität, ISO 25010) +Akteur: Mahnwesen-Sachbearbeiter +Vorbedingung: Mahnbericht konfiguriert; Benutzerrecht geprüft +Fakt: `DunningBL.GenerateInvoiceExpression` wählt aktive Rechnungen mit `DueDate <= Today` und `NextDueDateInDays <= 0`; `DunningRunBL.ExecuteDunningRun` erhöht in Session-Transaktion die Stufe None→1→2→3, vergibt Laufnummer `Max+1`, Vorschau läuft mit Rollback, Reset degradiert zurück. +Aussage: Das System soll Mahnläufe transaktional nur über überfällige, aktive, nicht gesperrte Rechnungen ausführen, je Lauf genau eine Stufe bis Maximalstufe 3 erhöhen und Stornierung durch Rückdegradierung unterstützen. +Ergebnis: Mahnstufenhistorie und DunningRunItems sind nachvollziehbar; Vorschau verändert keine Daten. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\Dunning\DunningRunBL.cs, ExecuteDunningRun/UpdateInvoice/SaveDunningRun - Begründung: Stufeneskalation erzwungen und transaktional + - [SEKUNDÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\Dunning\DunningBL.cs, GenerateInvoiceExpression - Begründung: mahnberechtigende Bedingung + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, View cvw_InvoiceDunnings (NextDueDate je Mahnstufe) - Begründung: SQL-Fälligkeitsebene +Prüfidee: Vorschau → keine DB-Änderung; Lauf → Stufe+1 mit Datum/Bearbeiter; Mahnstopp im Intervall schließt aus. +Tracelinks: StRS-003 +Konsolidierung: Kandidat: Opos-Lauf (OposRunBL) als Schwesteranforderung +Übernahmewürdigkeit: übernehmen - Nebenläuflichkeit der Laufnummer "Max+1" prüfen +Status: belegt + +--- + +ID: SyRS-013 +Titel: Zahlungsstatus nur über zentralen, protokollierten Buchungspunkt +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: Zuverlässigkeit (Konsistenz, ISO 25010) +Akteur: Debitorenbuchhaltung, Modul Zahlungseingang +Vorbedingung: Rechnung (IReceiptWithPayment) vorhanden +Fakt: `ReceiptBL.UpdateReceiptIsPaid` setzt Completed/Active mit Canceled-Guard, Optimistic Locking via ConcurrencyControlGuid und Protokolleintrag; `PaymentsBL.DeleteIncomingPayment` ruft dieselbe Stelle mit negativem Betrag. +Aussage: Das System soll "bezahlt/unbezahlt" ausschließlich über eine zentrale, protokollierte, versionsoberprüfte Methode ändern und das Löschen von Zahlungen als Rückbuchung abbilden. +Ergebnis: Fremdwährungsstand und Belegstatus bleiben konsistent; jede Änderung ist protokolliert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, UpdateReceiptIsPaid (Zeilen 4902-4971) - Begründung: zentraler Buchungspunkt + - [SEKUNDÄR] src\backend\Centron.BL\Finances\Payments\PaymentsBL.cs, DeleteIncomingPayment - Begründung: Rückbuchung über dieselbe Stelle +Prüfidee: Teilzahlung löschen → PaidFC sinkt, Protokoll da; Zahlung auf Canceled-Rechnung → Fehler; veralteter Guid → ChangedByOtherInstance. +Tracelinks: StRS-003, StRS-011 +Konsolidierung: Kandidat: Zahlungsabwicklungsgruppe mit Skonto/Zahlungsziel +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SyRS-014 +Titel: Belegweiterverarbeitung nur entlang definierter Regeln je Belegart +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertriebssachbearbeiter +Vorbedingung: Ursprungsbeleg mit weiterverarbeiteten Positionen +Fakt: `InvoiceSpecificLogic.CanBeForwardedIntoForUIOverwrite` sperrt Barrechnungen; `CanChangeItemQuantityAfterItemWasForwarded=false`; `ReceiptProgressionBL` bindet Herkunft über RechPos.UrsprungI3D/UrsprungArt. +Aussage: Das System soll Weiterverarbeitung anhand hinterlegter Regeln je Belegart erlauben oder sperren und nach Weiterverarbeitung Mengenänderungen der Ursprungsposition verhindern. +Ergebnis: Belegkette bleibt eindeutig; kein Mehrfachabgriff von Positionen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\InvoiceSpecificLogic.cs, CanBeForwardedFrom/Into/CanChangeItemQuantity... (Zeilen 279-297) - Begründung: erzwungene Übergangsregeln + - [SEKUNDÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptProgressionBL.cs, CreateFollowUpReceiptsSql - Begründung: SQL-seitige Herkunftszuordnung +Prüfidee: Teilrechnung aus Lieferschein; danach Mengenänderung im Lieferschein wird abgewiesen. +Tracelinks: StRS-003; SwRS-010 +Konsolidierung: Kandidat: mit StRS-003 Belegfluss-Regelwerk +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SyRS-015 +Titel: Kundenindividuelle Preise im Web-Shop mit nachvollziehbarer Rabattanzeige +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Endkunde (Web-Account) +Vorbedingung: Artikel im Sonderpreis-Sortiment; Konditionen gepflegt +Fakt: `ReceiptCartBL.SearchArticles` berechnet je Artikel `GetSpecialAgreement/GetBasePrice` und `CalculatedPrice = ReceiptPriceHelper.CalculateNetPrice(..., currencyFactor ...)`; Listenpreis/Rabatt nur bei Sonderpreisart "ReduceListPrice". +Aussage: Das System soll im Shop den kundenspezifischen Nettopreis serverseitig berechnen und bei Listenpreisreduktion Listenpreis und Rabatt transparent ausweisen, ohne die Kalkulation preiszugeben. +Ergebnis: Verbindliche kundenbezogene Preise; zusätzliche Rabatte als Hinweis. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptCartBL.cs, Zeilen 178-206 - Begründung: Preiserzeugung ausschließlich serverseitig + - [SEKUNDÄR] src\nexus\CentronNexus\WebCart\WebCartShopPage.razor, Zeilen 164-211 (Flyout) - Begründung: UI zeigt nur DTO-Felder +Prüfidee: Artikel mit ReduceListPrice + Sondervereinbarung; gelieferter Preis gegen Referenzrechnung prüfen. +Tracelinks: StRS-002, StRS-011; SwRS-013, SwRS-035 +Konsolidierung: Kandidat: mit SyRS-018 "WebCart-Sortiment und -Preisstellung" +Übernahmewürdigkeit: übernehmen - abrechnungsrelevant +Status: belegt + +--- + +ID: SyRS-016 +Titel: Kundenportal nur für Web-Account-Login über den Kundenportal-Port +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Endkunde; nicht berechtigte Aufrufer +Vorbedingung: Mandant betreibt den Kundenportal-Port +Fakt: `WebCart\_Imports.razor` setzt global `[AuthorizeLoginWebAccount]` und `[AuthorizeCustomerPortalPort]`; serverseitig erzwingt `ReceiptCartBL.SearchArticles` `Guard.Not(currentUser.IsWebAccountLogin is false, ...)`. +Aussage: Das System soll alle WebCart-/Kundenportalseiten ausschließlich authentisierten Web-Account-Logins auf dem konfigurierten Portal-Port zugänglich machen; andere Login-Arten sind abzulehnen. +Ergebnis: Weder Mitarbeiter-Logins noch anonyme Aufrufer erhalten Portalinhalte; BL-Guard verhindert Umgehung per Direktaufruf. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptCartBL.cs, Zeile 133 (Guard) - Begründung: serverseitige Durchsetzung + - [SEKUNDÄR] src\nexus\CentronNexus\WebCart\_Imports.razor, Zeilen 3-4 - Begründung: Routenebene für alle Seiten +Prüfidee: `/webcart/shop` und Service als Mitarbeiter/anonym → Ablehnung. +Tracelinks: StRS-002, StRS-006; SwRS-007, SwRS-036 +Konsolidierung: Kandidat: Portal-Zugriffsrechtefamilie +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SyRS-017 +Titel: Shop-Sortiment auf aktive Sonderpreise des Kunden beschränken +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Endkunde (Web-Account) +Vorbedingung: Kunde besitzt aktive Sonderpreise mit Artikelbezug +Fakt: `ReceiptCartBL.SearchArticles` lädt nur `ShowOnlyActive=true`, `ObjectKind=CustomerClass`, `ObjectI3DList={WebAccount.CustomerI3D}` und begrenzt die Artikelsuche mit `specialPriceArticleI3Ds.Contains(f.I3D)`; ohne WebCart-Lizenz leeres Ergebnis. +Aussage: Das System soll im Shop ausschließlich Artikel anzeigen, für die der Kunde des Web-Accounts einen aktiven Sonderpreis besitzt. +Ergebnis: Kein Kunde sieht Artikel außerhalb seines Sortiments; Ergebnismengen verschiedener Kunden sind disjunkt. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptCartBL.cs, Zeilen 144-149, 228-245 - Begründung: durchsetzende Query-Einschränkung + - [SEKUNDÄR] README.md, Zeile 35 - Begründung: Fachregel dokumentiert +Prüfidee: Zwei Kunden mit verschiedenen Sonderpreisen: Suchergebnismengen disjunkt = Sonderpreisartikelmenge. +Tracelinks: StRS-002, StRS-006 +Konsolidierung: Kandidat: mit SyRS-015 +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SyRS-018 +Titel: Warenkorb-Bestellung nur mit Web-Recht und Prüfstufe +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Endkunde mit/ohne Bestellrecht; Kundenadministrator +Vorbedingung: Warenkorb im Status "bereit zur Prüfung"/"geprüft" +Fakt: `ReceiptCartBL` prüft `WebRights.Any(I3D == WEBRIGHT_WEBCART2_ORDER_CART)` und lehnt Bestellen ohne Recht ab; Kundenverwaltung per `[AuthorizeWebRight(CUSTOMERADMINISTRATOR)]`; Passwortmindestlänge 8. +Aussage: Das System soll die Warenkorb-Bestellung an das Web-Recht "bestellen" binden, die Prüfstufe respektieren (Vier-Augen) und die Rechteverwaltung dem Kundenadministrator vorbehalten. +Ergebnis: Bestellungen nur durch Berechtigte; Administrationsseiten abgeschlossen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptCartBL.cs, Zeilen 859-864, 670 - Begründung: BL-seitige Rechteprüfung + - [SEKUNDÄR] src\nexus\CentronNexus\WebCart\WebCartAdminPage.razor, Zeilen 3-4 - Begründung: Admin-Gate +Prüfidee: Bestellung ohne ORDER-CART-Recht → Fehler; mit Recht → Erfolg inkl. interner Meldeadresse. +Tracelinks: StRS-002, StRS-006; SwRS-040 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - abrechnungs- und sicherheitsrelevant +Status: belegt + +--- + +ID: SyRS-019 +Titel: Token-basierte Angebotsansicht ohne Login +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Angebotsempfänger (extern, unauthentisiert) +Vorbedingung: Angebotslink enthält gültiges Receipt-Access-Token +Fakt: Route `/weboffer/{Token}` ohne Authorize-Attribut; `ReceiptWebServiceBL` erzwingt `Guard.NotNullOrWhiteSpace(token,...)` und wirft bei unbekanntem Token; Zustandswechsel über `ChangeWebReceiptState(token, ...)`. +Aussage: Das System soll die Ansicht, PDF-Vorschau, Kommentierung, Adressänderung und Statussteuerung eines Angebots allein an die Gültigkeit des Tokens binden und ungültige Tokens ablehnen. +Ergebnis: Loginfreie Angebotsbearbeitung nur mit gültigem Token; unbekannte Tokens liefern Fehler statt Daten. +Belege: + - [PRIMÄR] src\backend\Centron.BL\WebServices\Sales\Receipts\ReceiptWebServiceBL.cs, Zeilen 3163-3218 (Token-Guard) - Begründung: einzige Zugangskontrolle + - [SEKUNDÄR] src\nexus\CentronNexus\WebOffer\WebReceiptOverview.razor, Route - Begründung: loginlose Seite +Prüfidee: Bekanntes Token → Erfolg; manipuliertes Token → "kein zugehöriger Beleg". +Tracelinks: StRS-002 +Konsolidierung: Kandidat: Token-Lebenszyklus mit SyRS-020 zu einer Token-Sicherheitsanforderung +Übernahmewürdigkeit: übernehmen - vor Übernahme um Token-Ablauf/Wiederverwendungsvorschlag präzisieren +Status: HYPOTHESE - Token-Erzeugung, Ablauf und Rate-Limiting wurden in den Artefakten nicht nachgewiesen; Bestätigung durch Token-Erzeugungscode fehlt + +--- + +ID: SyRS-020 +Titel: Signatur- und Akzeptanzstrecke für freigegebene Dokumente +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Externer Dokumentempfänger (Token-Inhaber) +Vorbedingung: Dokument per Freigabe-Token versendet +Fakt: Routen `/shareddocuments/{Token}[/sign|/acceptance]`, `/contractmanagement`; `DocumentSigningPage.CanAccept` verlangt Signatur (Zeichnen/Typ/Upload) und bei SEPA `IsValidIban`; Abschluss über `Confirm/DeclineOnlinePdfDocument`. +Aussage: Das System soll Annahme/Unterschrift eines freigegebenen Dokuments von einer vollständigen, validierten Signatur (SEPA: inkl. Bankdaten) abhängig machen und Ablehnung ausdrücklich erfassen. +Ergebnis: Dokumente gelten erst nach vollständiger Signatur als angenommen; SEPA-Verträge erfordern IBAN. +Belege: + - [PRIMÄR] src\nexus\CentronNexus\DocumentSigning\DocumentSigningPage.razor, CanAccept/HasBankData - Begründung: Annahme-Verknüpfung implementiert + - [SEKUNDÄR] src\backend\Centron.BL\WebServices\Sales\Receipts\ReceiptWebServiceBL.cs, SendMailForSigning (Zeilen 1898-1918) - Begründung: Token-Erzeugung im Versand +Prüfidee: SEPA-Dokument ohne IBAN → blockiert; Serveraufruf Confirm ohne Signaturdaten prüfen. +Tracelinks: StRS-002 +Konsolidierung: Kandidat: mit SyRS-019 +Übernahmewürdigkeit: übernehmen - serverseitige Nachprüfung ergänzen +Status: HYPOTHESE - die serverseitige Validierung (außerhalb der UI) wurde nicht nachgewiesen; es fehlt der Nachweis einer Prüfstelle im Backend + +--- + +ID: SyRS-021 +Titel: PDF-Auslieferung über gemeinsamen Office-Cache-Endpunkt +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Externe Dokumentempfänger, Portalseiten +Vorbedingung: Datei liegt im Nexus-Cache +Fakt: `PdfController` exponiert `[HttpGet("getcachedfile/{id}/{filename}")]`; `FilePreview.razor` bettet die URL ein; WebOffer-PDF-Vorschau nutzt dieselbe Komponente. +Aussage: Das System soll zwischengespeicherte PDFs über einen gemeinsamen Endpunkt ausliefern und in Vorschaukomponenten von Portal und Angebotsseiten einbettbar machen. +Ergebnis: Einheitliche PDF-Auslieferung ohne doppelte Renderstrecke. +Belege: + - [PRIMÄR] src\nexus\CentronNexus\Office\Controllers\PdfController.cs, Zeilen 13-15 - Begründung: einzige Auslieferstelle + - [SEKUNDÄR] src\nexus\CentronNexus\Office\Components\FilePreview.razor - Begründung: Konsument +Prüfidee: Erratene/fremde Cache-Id abrufen → erwartet 404 oder Autorisierung (prüfen ob vorhanden). +Tracelinks: StRS-002 +Konsolidierung: Kandidat: technische Querschnittsleistung mit SyRS-019/SyRS-020 +Übernahmewürdigkeit: übernehmen als technischer Baustein +Status: HYPOTHESE - Zugriffskontrolle auf Cache-Ids in den gelesenen Stellen nicht sichtbar; fehlender Nachweis einer Autorisierungsprüfung + +--- + +ID: SyRS-022 +Titel: Hintergrunddienste zentral über Konfigurationsflag steuerbar +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Anpassbarkeit (ISO 25010) +Akteur: Betrieb (mehrere Webservice-Instanzen) +Vorbedingung: `WebServiceConfigHelper.Current.ExecuteServices` gesetzt +Fakt: In `CentronHost.Start()` werden Kerndienste immer, die ~28 Fach-Hintergrunddienste (Reminder, EdiDownload, ArticleImport...) nur innerhalb `if (ExecuteServices == true)` registriert. +Aussage: Das System soll alle zeitgesteuerten Fach-Hintergrunddienste über eine Konfigurationsflag ein-/ausschaltbar machen, damit bei Mehrinstanzenbetrieb keine Duplikate laufen. +Ergebnis: Instanzspezifische Batch-Steuerung; Kerndienste bleiben erhalten. +Belege: + - [PRIMÄR] src\webservice\Centron.Host\CentronHost.cs, Start (Zeilen 218-260) - Begründung: Bedingungsblock im Quelltext +Prüfidee: Flag false → nur Kerndienste aktiv; true → alle Fachdienste registriert. +Tracelinks: StRS-001; SwRS-084 +Konsolidierung: Kandidat: je HostedService Detailanforderung in Folgeiteration +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SyRS-023 +Titel: Versionsgesteuerte, idempotente Datenbankmigration mit Protokoll +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Anwendung (Start/Login), Administrator +Vorbedingung: Datenbankverbindung steht; Skript-Registry reflexiv gefüllt +Fakt: `ScriptEngineBL` überspringt in `DBUpdate` (Status=2) erfasste Skripte, rollt Fehler-Skripte zurück (Ignore-List {10178,10210,10211,50000}), markiert Pre-Login-Skripte via `IBeforeLoginScriptMethod` und protokolliert jede Ausführung in `DBUpdate`. +Aussage: Das System soll alle Migrationsskripte der installierten Version in Reihenfolge, transaktional und genau einmal ausführen und jede Ausführung mit Skriptnummer, Benutzer und Zeitstempel protokollieren. +Ergebnis: Schema/Daten deterministisch auf Programmversionsstand; Migrationen auditierbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Scripts\ScriptEngineBL.cs, ExecuteScripts/DoExecuteScriptMethodSet/SaveScriptIntoDb - Begründung: Kern der Migrationsausführung + - [PRIMÄR] src\backend\Centron.BL\Administration\Scripts\ScriptMethods\BaseScriptMethod.cs, ActualExecuteScript - Begründung: DDL-Ausführung + - [SEKUNDÄR] src\backend\Centron.BL\Administration\Scripts\ScriptMethods\ScriptMethodPool.cs, FindScriptMethods - Begründung: reflexive Registrierung +Prüfidee: Frische DB + ältere Version → fehlende DBUpdate-Sätze ergänzt; Fehler-Skript → Rollback und Abbruch. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Release-/Update-Prozess-Kapitel +Übernahmewürdigkeit: übernehmen - Kernplattformverhalten (DB-Rechte-Kontext dokumentieren) +Status: belegt + +--- + +ID: SyRS-024 +Titel: REST-API-Versionierung und einheitliche Fehlerbehandlung +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: Wartbarkeit (ISO 25010) +Akteur: API-Clients +Vorbedingung: Controller unter `Controllers\v1\...`/`Unversioned` +Fakt: `AddCentronApiVersioning` setzt DefaultApiVersion 1, `ReportApiVersions`, `VersionByNamespaceConvention`; `GlobalExceptionFilter.OnException` loggt, ruft `TryRecoverConnectionPool` und antwortet 500 mit generischer JSON-Meldung. +Aussage: Das System soll REST-Endpunkte nach Namespace versionieren und jeden unbehandelten Fehler in eine protokollierte, clientfreundliche 500-Antwort mit Connection-Pool-Recovery überführen. +Ergebnis: Stabile API-Verträge je Version; keine Stacktraces beim Client. +Belege: + - [PRIMÄR] src\webservice\Centron.Host\AspNetCore\RegisterCentronApiVersioning.cs, AddCentronApiVersioning - Begründung: Versionierungsregie + - [PRIMÄR] src\webservice\Centron.Controllers\Configuration\GlobalExceptionFilter.cs, OnException - Begründung: zentraler Fehlerpfad +Prüfidee: v1-Route vs. unbekannte Version; Exception erzwingen → 500 ohne interne Details. +Tracelinks: StRS-001 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SyRS-025 +Titel: Standardisierter komprimierter REST-Kanal "RESTC" mit Proxy und Langzeit-Timeout +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: Performance-Effizienz (ISO 25010) +Akteur: Client-Anwendungen (WPF, Nexus) +Vorbedingung: Webservice-URL bekannt, optional Proxy +Fakt: `CentronWebService`-Ctor setzt `BaseAddress = url + "/RESTC/"`, `CompressedDataContractSerializer`, optionalen `WebProxy`, Timeout "InfiniteTimeSpan" (laut Kommentar). +Aussage: Das System soll Webservice-Aufrufe über einen zentralen, komprimierten Datenkanal mit optionalem Proxy führen, damit Langzeitoperationen nicht abbrechen. +Ergebnis: Wiederverwendbarer standardisierter Clientzugriff; Langläufer brechen nicht ab. +Belege: + - [PRIMÄR] src\webservice\Centron.WebServices.Core\Connections\CentronWebService.cs, Konstruktor - Begründung: Basis-URL/Kompression/Proxy im Code +Prüfidee: Aufruf gegen Testserver; Content-Encoding prüfen; Timeout-Verhalten bei Langläufer gegenprüfen. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: API-Verträge (Request/Response/ResultDTO) als Unterkapitel +Übernahmewürdigkeit: übernehmen +Status: HYPOTHESE - das "unbegrenzte Timeout" ist nur durch einen Kommentar belegt; die tatsächliche Implementierung (CancellationToken) wurde nicht verifiziert + +--- + +ID: SyRS-026 +Titel: Plattformabhängiger Webserver-Betrieb (HttpSys/Kestrel) mit HTTPS und CLI-Konfiguration +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Portabilität (ISO 25010) +Akteur: Betrieb (Windows, Linux/Docker) +Vorbedingung: WebServiceAddress konfiguriert +Fakt: `CentronHost.Start()` wählt `OperatingSystem.IsWindows()` ? UseHttpSys (MaxRequestBodySize=null) : UseKestrel (ListenAnyIP, HTTPS via konfigurierbarem Zertifikat); `Centron.Host.Console` versteht `configure port publicUrl connectionString` für headless Betrieb. +Aussage: Das System soll Webserver/Bindings automatisch je Betriebssystem wählen, unbegrenzte Upload-Body-Größe zulassen, HTTPS über konfigurierbares Zertifikat anbieten und die Konfiguration per CLI für Container ermöglichen. +Ergebnis: Identischer Host unter Windows und Linux/Docker; headless Installation. +Belege: + - [PRIMÄR] src\webservice\Centron.Host\CentronHost.cs, Start (Zeilen 111-151) - Begründung: beide Pfade im Quelltext + - [PRIMÄR] src\webservice\Centron.Host.Console\Program.cs, HandleCommands - Begründung: CLI-Konfiguration +Prüfidee: `configure 8080 ... && start` in Container; HTTPS-Adressierung mit Zertifikat prüfen. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Deployment-Kapitel +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SyRS-027 +Titel: Betrieb als Windows-Dienst mit Fehlerkapselung und Betriebswerkzeug +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Zuverlässigkeit (ISO 25010) +Akteur: Windows Service Control Manager, Administrator +Vorbedingung: WindowsService installiert +Fakt: `CentronService.OnStart` fängt Exceptions, loggt und stoppt kontrolliert; ConnectionManager prüft/startet Dienst, SQL, Lizenz, Hardware-ID, Radius (`EnsureWindowsServiceIsRunning` u.a.). +Aussage: Das System soll den Webservice als Windows-Dienst betreibbar machen (kontrolliertes Stoppen bei Fehlern) und dem Administrator ein Diagnose-/Einstellungs-GUI bereitstellen. +Ergebnis: Saubere Dienst-Lebenszyklen; geführte Einrichtung ohne manuelle Operateure. +Belege: + - [PRIMÄR] src\webservice\Centron.Host.WindowsService\CentronService.cs, OnStart/OnStop - Begründung: Fehlerkapselung + - [PRIMÄR] src\webservice\c-entron.misc.ConnectionManager\ConnectionManagerViewModel.cs, Prüfmethoden - Begründung: Diagnose-Werkzeug +Prüfidee: Dienst mit fehlerhafter Konfiguration starten → bleibt gestoppt, Fehler geloggt; ConnectionManager zeigt Ursache. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: mit SyRS-026 +Übernahmewürdigkeit: übernehmen (Zielplattform SaaS: Dienst durch Plattformbetrieb ersetzen, Diagnosefunktion erhalten) +Status: belegt + +--- + +ID: SyRS-028 +Titel: Service-spezifische BL-Schicht (*WebServiceBL) als Backend der REST-Dienste +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Web-Service-Host/Controller +Vorbedingung: REST-Anfrage authentifiziert +Fakt: 464 `*WebServiceBL`-Klassen in ~75 Fachordnern; `TicketWebServiceBL.GetWebServiceToken()` (SHA1 der Produkt-ID), `GetAllConnectionTickets/RemoveConnectionTicket`; Controller injizieren die BL per Konstruktor. +Aussage: Das System soll je Fachbereich eine webserviceeigene BL-Schicht mit einheitlicher Result-Rückgabe bereitstellen, die Fach- und Authentifizierungsoperationen für die REST-Schicht kapselt. +Ergebnis: Klare Trennung Client-BL vs. Webservice-BL; konsistente Fehlerrückgabe. +Belege: + - [PRIMÄR] src\backend\Centron.BL\WebServices\Administration\Logins\TicketWebServiceBL.cs, GetWebServiceToken/GetAllConnectionTickets - Begründung: repräsentativ gelesen + - [SEKUNDÄR] src\webservice\Centron.Controllers\Controllers\v1\Accounts\AccountsController.cs - Begründung: Konsum der Schicht +Prüfidee: GetWebServiceToken ohne gültige Produkt-ID → Fehlerstatus; mit Lizenz → Token. +Tracelinks: StRS-001 +Konsolidierung: nein - Modulgröße erfordert Detailanalysen je Fachbereich +Übernahmewürdigkeit: übernehmen (strukturell) +Status: belegt + +--- + +ID: SyRS-029 +Titel: Zentrales Konfigurationswertesystem (AppSettings/ApplicationSettings) +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Wartbarkeit (ISO 25010) +Akteur: alle Fachmodule, Administration +Vorbedingung: Datenbankverbindung vorhanden +Fakt: `AppSettingsBL.GetSettings` lädt beide Settings-Generationen cache-optimiert und legt fehlende ApplicationSettings on-demand mit Definition默认 an; `SettingsCollection` kapselt typisierte Getter. +Aussage: Das System soll Einstellungen aus beiden Generationen über eine typisierte API bereitstellen, fehlende Werte automatisch mit Defaults anlegen und N+1-Abfragen vermeiden. +Ergebnis: Konsistenter, performanter Settingzugriff; Migrationszwilling architektonisch adressiert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Settings\AppSettingsBL.cs, LoadOld/NewSettingsOptimized - Begründung: Cache-First + On-Demand-Legacy +Prüfidee: Unbekannte ApplicationSettingID lesen → Default-Entität wird angelegt und zurückgegeben. +Tracelinks: StRS-001; SwRS-096 +Konsolidierung: Kandidat: AppSetting (alt) und ApplicationSetting (neu) zusammenführen +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SyRS-030 +Titel: Zentrale Konfigurations-DB mit verschlüsseltem Hotline-Masterkey +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Administrator/Hotline-Support +Vorbedingung: SQL-Server erreichbar +Fakt: `CentronConfigurationDbBL.CreateCentronConfigDb` richtet separate Config-DB ein; Masterkey wird AES-verschlüsselt je Konfiguration in Config-DB oder Secure-Datei (Env `MASTER_PASSWORD_SECURE_FILE_FOLDER`) abgelegt; Encrypt/DecryptWithMasterKey nutzen ihn. +Aussage: Das System soll installationsübergreifende Konfiguration zentral führen und den Hotline-Masterkey verschlüsselt an konfigurierbarem Ort vorhalten. +Ergebnis: Zentrale Passwort-/Schlüsselverwaltung; fehlender Key → definierte Fehlermeldung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\CentronConfigDb\CentronConfigurationDbBL.cs, Create/Encrypt/Decrypt - Begründung: Speicherort-Auswahl implementiert + - [SEKUNDÄR] src\backend\Centron.BL\Administration\CentronConfigDb\MasterPasswordSecureFileStorage.cs, BuildSecureFileFilePath - Begründung: Dateipfadregel +Prüfidee: SaveLocation auf SecureFile → Key nur als Datei; Key löschen → definierter Fehler beim Entschlüsseln. +Tracelinks: StRS-004 +Konsolidierung: Kandidat: Schlüsselverwaltung (AESCryptoLogic) separat bewerten +Übernahmewürdigkeit: übernehmen - Sicherheitsanker;AES-Schlüsselherkunft prüfen +Status: belegt + +--- + +ID: SyRS-031 +Titel: WebService-Konfigurationsdatei mit verschlüsselten Geheimnissen +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: +Akteur: Administrator (ConnectionManager) +Vorbedingung: WebServiceConfig.xml vorhanden +Fakt: `WebServiceConfigSerializer` verschlüsselt DatabaseConnectionString, ProxyPassword, RadiusServerSecret AES; Klartext-Fallback `DatabaseConnectionStringPlain` vorhanden; Zusatzdienste können Auth übernehmen. +Aussage: Das System soll die Webservice-Konfiguration (Adressen, AD-Auth, 2FA/RADIUS, Zusatzdienste) zentral führen und alle Passwörter/Secrets verschlüsselt ablegen. +Ergebnis: Keine Klartext-Secrets auf dem Server; deklarative Dienst-Erweiterung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\WebServiceConfiguration\WebServiceConfigSerializer.cs, LoadFromFile - Begründung: AES + Fallback im Code +Prüfidee: Roundtrip verschlüsselter Werte; Fallback-Verhalten bei Klartexteintrag prüfen. +Tracelinks: StRS-004 +Konsolidierung: Kandidat: mit SyRS-030 (Schlüssel/Config-Verbund) +Übernahmewürdigkeit: Workaround - Klartext-Fallback als Risiko; Verschlüsselungskonzept übernehmen +Status: belegt + +--- + +ID: SyRS-032 +Titel: Client-Verbindungsprofile mit AES-verschlüsselten Passwörtern und Pfad-Fallback +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Benutzer im Login-Dialog +Vorbedingung: CentronConnections.xml vorhanden oder leerer Start +Fakt: Pfadpriorität Env `CENTRON_CONNECTION_PATH` → ProgramData → Installations-/Roaming-Verzeichnis; Passwörter werden beim Speichern/Laden AES-verschlüsselt/entschlüsselt. +Aussage: Das System soll DB-/WebService-Verbindungsprofile in einer XML-Datei mit konfigurierbarem Speicherort ablegen und Passwörter verschlüsselt speichern. +Ergebnis: Gemeinsame Verbindungsliste in Terminalserver-Umgebungen ohne Klartextpasswörter. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Connections\ConnectionBL.cs, Convert-Methoden + Get*ConfigPath - Begründung: Mechanik vollständig +Prüfidee: XML öffnen → kein Klartextpasswort; Env-Variable setzt Priorität. +Tracelinks: StRS-004 +Konsolidierung: Kandidat: Ziel SaaS → Profilverwaltung mandantenseitig +Übernahmewürdigkeit: Workaround - dateibasierte Profilhaltung ist desktopgeprägt; Verschlüsselungsanliegen übernehmen +Status: belegt + +--- + +ID: SyRS-033 +Titel: Attributsgesteuerte Feldänderungs-Historie im Persistenzlayer +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Sicherheitsfunktionalität/Nachvollziehbarkeit (ISO 25010) +Akteur: Persistenzlayer (automatisch) +Vorbedingung: Entity trägt ChangeTracking-Attribute; Benutzer angemeldet +Fakt: `ChangeTrackingEventListener` (IPreUpdateEventListener) schreibt je geänderter Property Alt-/Neuwert+Benutzer in `ChangeLog`; Fehler werden nur geloggt (best-effort); nur Updates, keine Inserts/Deletes. +Aussage: Das System soll deklarierte Feldänderungen automatisch und ohne Fachcode in einer zentralen Änderungshistorie fortschreiben, ohne den Fachvorgang zu gefährden. +Ergebnis: Auditgrundlage; best-effort-Charakter und Update-only als bewusste Grenze spezifiziert. +Belege: + - [PRIMÄR] src\backend\Centron.DAO\ChangeTracking\ChangeTrackingEventListener.cs, OnPreUpdate/CreateChangeLog (Zeilen 52-142) - Begründung: zentrale Implementierung +Prüfidee: Getrackte Property ändern → genau ein ChangeLog-Satz; ohne angemeldeten Benutzer → Warnung, kein Satz. +Tracelinks: StRS-015 +Konsolidierung: Kandidat: Audit-Anforderungsgruppe (Rechteprüfung, ChangeTracking, Belegprotokolle) +Übernahmewürdigkeit: übernehmen - Lücken (Insert/Delete, best-effort) im Ziel schließen +Status: belegt + +--- + +ID: SyRS-034 +Titel: Einheitliches ORM-Mapping auf Legacy-Schema (PK I3D, deutsche Tabellen) +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Portabilität, Wartbarkeit (ISO 25010) +Akteur: Entwickler/Neuimplementierung +Vorbedingung: Neue Entity soll persistiert werden +Fakt: `BaseMaps` setzt `Id(a => a.I3D)`; Mappings ordnen Entities auf historisch deutsche Tabellen (z.B. "Textbaustein", "RechKopf"); `DBEntityMaps` lässt State bewusst unmapped. +Aussage: Das Migrationsprojekt soll die Datenstrukturen des Altsystems vollständig abbilden: PK „I3D", explizite (auch deutsche) Tabellen-/Spaltennamen, Audit-/State-Konventionen - als Basis für die Datenübernahme ins Zielsystem. +Ergebnis: Datenübernahme ohne Schema-Überraschungen; dokumentierte Ausnahmeregeln. +Belege: + - [PRIMÄR] src\backend\Centron.DAO\Mappings\BaseMaps.cs, Id(a => a.I3D) - Begründung: allgegenwärtige PK-Konvention + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[RechKopf]/[Zahkond] - Begründung: Legacy-Tabellen real + - [SEKUNDÄR] src\backend\Centron.DAO\Mappings\DBEntityMaps.cs - Begründung: dokumentierte Ausnahme +Prüfidee: Schema-Export gegen Mapping-Stichprobe abgleichen; I3D allgegenwärtig. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: ObjectTypes-Nummernkreis (SwRS-122) ins Glossar/Datenmodell überführen +Übernahmewürdigkeit: übernehmen als Datenübernahme-/Konformitätsanforderung +Status: belegt + +--- + +ID: SyRS-035 +Titel: Zentrale SQL-Abfragen in einem NamedQuery-Pool statt im Code +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Wartbarkeit (ISO 25010) +Akteur: Entwickler/Administrator +Vorbedingung: Query als XML-Knoten im eingebetteten NamedQueryPool.xml +Fakt: `NamedQueryManager` lädt/cacht Knoten und weist unbekannte Namen zurück; `NamedQueryDAO` führt typisiert mit Parametern/Timeout aus. +Aussage: Das System soll fachliche SQL/HQL-Abfragen zentral in einem Query-Pool pflegen, per Name+Typ auflösen, cachen und paramisiert ausführen. +Ergebnis: SQL-Änderungen ohne Codeeingriff; fehlende Queries fallen laut auf. +Belege: + - [PRIMÄR] src\backend\Centron.DAO\NamedQueries\NamedQueryManager.cs, Zeilen 33-60 - Begründung: Loader/Cache/Exception + - [PRIMÄR] src\backend\Centron.DAO\NamedQueries\NamedQueryPool.xml - Begründung: Beispielknoten +Prüfidee: Bekannten Enum ausführen; erfundenen Enum → definierte Exception. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: mit Rohtextsuche/Statistik-SQL als Datenzugriffskapitel +Übernahmewürdigkeit: übernehmen (als Prinzip "kein SQL verstreut im Code") +Status: belegt + +--- + +ID: SyRS-036 +Titel: Rohe SQL-Zugriffe transaktionsgebunden über die ORM-Session +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Zuverlässigkeit (Transaktionskonsistenz, ISO 25010) +Akteur: DAO-Aufrufer +Vorbedingung: Offene NHibernate-Session, ggf. Transaktion +Fakt: `RawSqlAccessDAO` erzeugt Commands aus `Session.Connection` und enlistet die aktuelle Transaktion (`GetCurrentTransaction()?.Enlist(command)`). +Aussage: Das System soll Roh-SQL ausschließlich über die Verbindlung der laufenden Session führen und in deren Transaktion einbinden. +Ergebnis: Kein Split zwischen ORM- und SQL-Änderungen; Rollback greift überall. +Belege: + - [PRIMÄR] src\backend\Centron.DAO\AdoNETDataAccess\RawSqlAccessDAO.cs, Zeilen 31-33, 58-59 - Begründung: Enlisting in allen geprüften Pfaden +Prüfidee: Raw-SQL-Insert in Transaktion, dann Rollback → Insert fehlt. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: DirectReplace-Parameter als SQL-Injection-Risiko bei Konsolidierung absichern +Übernahmewürdigkeit: übernehmen als Architekturregel mit Sicherheitshinweis +Status: belegt + +--- + +ID: SyRS-037 +Titel: Serverseitiger Ticket-Cache mit Hintergrund-Synchronisation +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Performance-Effizienz (ISO 25010) +Akteur: Nexus-Benutzer; TicketCacheBackgroundService +Vorbedingung: TicketCache-Konfiguration vorhanden +Fakt: `Program.cs` registriert `ITicketCacheService` als Singleton + `AddHostedService`; `TicketCacheService` hält Items mit `SynchronizeTickets()/CheckTickets()` und Locks. +Aussage: Das System soll sichtbare Tickets in einem prozessweiten Cache vorhalten, periodisch incrementell abgleichen und Benutzern Listen/Kanban ohne synchrone Webservice-Abfragen bereitstellen. +Ergebnis: Schnelle Ticketlisten; Ladezustand für UI sichtbar. +Belege: + - [PRIMÄR] src\nexus\CentronNexus\Shared\Services\TicketCacheService.cs, Zeilen 26-56 - Begründung: Singleton+Locks belegen prozessweite Nutzung + - [SEKUNDÄR] src\nexus\CentronNexus.Host\Program.cs, Zeilen 346-347 - Begründung: Registrierung +Prüfidee: ERP-Änderung erscheint nach Intervall ohne Reload; Statusobjekt informiert. +Tracelinks: StRS-013, StRS-001; SwRS-048 +Konsolidierung: Kandidat: Caching-Strategie mit Statistik-Caches (SyRS-042) bündeln +Übernahmewürdigkeit: übernehmen (Architekturkern der Ticket-UI) +Status: belegt + +--- + +ID: SyRS-038 +Titel: Push-Zustellung von Benachrichtigungen per SignalR mit SecretKey-Auth +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: Zuverlässigkeit (ISO 25010) +Akteur: c-entron-WebService (Sender), Nexus-Host (Empfänger), Mitarbeiter (UI) +Vorbedingung: Notifications.SecretKey und Webservice-URL konfiguriert +Fakt: `SignalRNotificationsService` verbindet auf "/Realtime/notifications", authentisiert mit secretKey, abonniert "NewNotification" mit AutoReconnect; `NotificationHub` filtert pro UserI3D. +Aussage: Das System soll Benachrichtigungen ereignisgesteuert (kein Polling) pro Empfänger zustellen, die Verbindung authentisieren und automatisch aufrechterhalten. +Ergebnis: Badges aktualisieren sich ohne Reload; irrelevante Notifications werden verworfen. +Belege: + - [PRIMÄR] src\nexus\CentronNexus\Shared\Services\SignalRNotificationsService.cs, Zeilen 30-57 - Begründung: Empfängerseite vollständig belegt +Prüfidee: Notification auslösen → Badge steigt ohne Reload; Hub gestoppt → Reconnect ≤ 1 Minute. +Tracelinks: StRS-013; SwRS-049, SwRS-050 +Konsolidierung: Kandidat: End-to-End-Benachrichtigung mit SwRS-050 zusammenführen +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SyRS-039 +Titel: Buchhaltungsexport in austauschbare Zielsystemformate (DATEV, SAP, ...) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: Kompatibilität (ISO 25010) +Akteur: Finanzbuchhaltung, Fremdsystem +Vorbedingung: Exportkonfiguration mit genau einem DefaultExport +Fakt: `BookKeepingExportBL.SaveExportSettings` erzwingt eindeutigen DefaultExport; Gateway-Implementierungen je Zielsystem (DatevAscii/XmlOnline, SAP, Sage, Abacus, Lexware, Navision ...) hinter Interfaces `IBookKeepingExport/IBookKeepingImportDataToCentron`. +Aussage: Das System soll Buchungssätze mandantengesteuert im konfigurierten Zielformat exportieren; neue Formate sind als zusätzliche Implementierung andockbar. +Ergebnis: Partner-/Systemkopplung ohne Kernanpassung; versionierte Konfiguration. +Belege: + - [PRIMÄR] src\backend\Centron.BL\DataExchange\BookKeeping\BookKeepingExportBL.cs, SaveExportSettings - Begründung: Default-Eindeutigkeit erzwungen + - [SEKUNDÄR] src\backend\Centron.Gateway\DataExchange\BookKeeping\IBookKeepingExport.cs - Begründung: Interface-Architektur +Prüfidee: Golden-File-Test je Format; DefaultExport-Verletzung → Ablehnung. +Tracelinks: StRS-003, StRS-016; SyRS-011, SwRS-067, SwRS-133 +Konsolidierung: Kandidat: Sammelkapitel "Finanzbuchhaltungsschnittstelle" +Übernahmewürdigkeit: übernehmen (Formate einzeln auf Bedarf prüfen) +Status: HYPOTHESE - die Detailregeln je Zielformat wurden nicht analysiert; nur Struktur und Default-Regel sind belegt + +--- + +ID: SyRS-040 +Titel: Normkonforme E-Rechnungsformate (ZUGFeRD/XRechnung, eb:interface) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: Funktionale Eignung/Kompatibilität (ISO 25010) +Akteur: Rechnungsempfänger, öffentliche Stellen +Vorbedingung: Aktives Zugferd-Interface je Kunde bzw. Länder-Setting +Fakt: `InvoiceZugferdBL.GenerateZugferdFile` wählt ZugferdKind bis XInvoice 3.0.1 inkl. Leitweg-ID, bettet `factur-x.xml` als PDF/A ein und prüft Netto-/Summenkonsistenz; `EbInterfaceLogic` erzeugt AT-Standard 4.3. +Aussage: Das System soll Rechnungsausgänge als konforme E-Rechnung (ZUGFeRD/XRechnung DE, eb:interface AT) erzeugen, Summen konsistenzgeprüft und als PDF-A-Hybrid auslieferbar. +Ergebnis: Konforme E-Rechnungen inkl. Abweis bei Summenfehlern. +Belege: + - [PRIMÄR] src\backend\Centron.BL\DataExchange\EDI\SaleInvoices\InvoiceZugferdBL.cs, GenerateZugferdFile/CreateZugferdConformPdfDocument - Begründung: Versionen/Prüfungen im Code + - [PRIMÄR] src\apis\Centron.Api.EbInterface\EbInterfaceLogic.cs, GenerateFile - Begründung: Namespace 4p3 fest +Prüfidee: KoSIT-Validator für DE; Schema-Validierung AT; Bruttosummenvergleich. +Tracelinks: StRS-003, StRS-011 +Konsolidierung: Kandidat: "E-Rechnung gesamt" mit SwRS-058 zusammenführen +Übernahmewürdigkeit: übernehmen - rechtliche Pflicht +Status: belegt + +--- + +ID: SyRS-041 +Titel: Zahlungsziel- und Skontoermittlung aus der Zahlungsbedingung +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System beim Belegspeichern; Rechnungsempfänger +Vorbedingung: AssetCondition/Zahkond auf Kunde oder Beleg +Fakt: `ReceiptBL.UpdatePaymentDueDate` berechnet Fälligkeit je DueKind (Belegdatum / +N Tage / Monatstag); Skontoebenen in Zahkond (Skonto1/2, LaenPer1..3); `AssetConditionBL` baut BR-DE-18-Skonto-Angaben für E-Invoice. +Aussage: Das System soll Fälligkeitsdatum und Skonto-Angaben (bis 3 Staffeln) deterministisch aus der Zahlungsbedingung ableiten und in Text, Belegkopf und E-Rechnung ausweisen. +Ergebnis: FaelligAm und Skontotext stimmen mit der Zahlungsbedingung überein. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, UpdatePaymentDueDate (Zeilen 8189-8256) - Begründung: durchsetzende Berechnungsstelle + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[Zahkond] - Begründung: Stammdatenmodell + - [SEKUNDÄR] src\backend\Centron.BL\Administration\Masterdata\AssetConditionBL.cs, GetPaymentConditionSkontoInBR_DE_18Format - Begründung: E-Invoice-Ausgabe +Prüfidee: "2 % / 14 Tage, netto 30": Fälligkeit = +30; Skontotext/Betrag gegen Brutto×2 % prüfen. +Tracelinks: StRS-003, StRS-011; SwRS-012 +Konsolidierung: Kandidat: mit SwRS-012 berechnungsseite zusammenführen +Übernahmewürdigkeit: Workaround - Skonto-Berechnung in GetCalculatedSkonto enthält Integer-Divisionsfehler; Zielregel klären +Status: belegt + +--- + +ID: SyRS-042 +Titel: Statistik-Caches mit Selbstreparatur und Sofortaktualisierung +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Performance-Effizienz (ISO 25010) +Akteur: Hintergrundjob, Benutzer +Vorbedingung: Caches registriert +Fakt: `CachedTableBL` verwaltet benannte Update-Routinen je Statistik-Tabelle, repariert fehlende Statistik-Sätze (`RepairIfNecessaryCacheStatistic`) und unterstützt `RequestImmediateCacheUpdate`. +Aussage: Das System soll Statistik-Cachetabellen über registrierte Routinen aktualisieren, veraltete Bestände selbsttätig reparieren und Sofortneuberechnung auf Anforderung ermöglichen. +Ergebnis: Performante, selbstheilende Statistiken. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Services\CachedTableBL.cs, ctor/GetTableCacheStatistic/RequestImmediateCacheUpdate - Begründung: Mechanik vollständig in Klasse +Prüfidee: Statistik-Satz löschen → Abfrage liefert repariert Daten; immediateUpdate=true → sofort neu. +Tracelinks: StRS-001; SwRS-104 +Konsolidierung: Kandidat: Statistik-/Cache-Kapitel mit Statistics (SwRS-036) +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SyRS-043 +Titel: Helpdesk-Statusmaschine als konfigurierbare, ereignisgesteuerte Übergänge +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Kunde (Web-Account), Bearbeiter, System +Vorbedingung: Ticket wird angelegt, übernommen oder abgeschlossen +Fakt: `HelpdeskBL.DoBeforeStoreTrans` setzt bei Web-Neuanlage `HelpdeskAfterOpenDefaultState`; `UpdateHelpdeskBL` setzt bei Allein-Übernahme `HelpdeskAfterInheritDefaultState`; `UpdateStatus` blockiert Closed bei offenen Abschluss-Checklisten; `CheckUserRigths` verlangt CLOSE_REQUEST für Closed. +Aussage: Das System soll Helpdesk-Statusübergänge aus konfigurierbaren Default-Status je Auslöser ableiten und den Abschluss an Recht und erledigte Abschluss-Checkliste binden. +Ergebnis: Keine Tickets mit leerlaufendem Status; Abschluss nur berechtigt und vollständig. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs, DoBeforeStoreTrans/CheckUserRigths - Begründung: durchsetzende Speicher-Hooks + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\UpdateHelpdeskBL.cs, UpdateStatus/CanHelpdeskClose - Begründung: Abschluss-Guards +Prüfidee: Web-Ticket anlegen → konfigurierter Default; Closed ohne Recht/Checkliste → Fehler, DB unverändert. +Tracelinks: StRS-013; SwRS-043, SwRS-045, SwRS-047, SwRS-127 +Konsolidierung: Kandidat: Parameterliste (AfterOpen/Inherit/AfterMailToCustomer) vollständig inventarisieren +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SyRS-044 +Titel: Nummernkreis-Delegation Mandant→Filiale→Standard +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Beleganlage (System) +Vorbedingung: Standardmandant aktiv +Fakt: `MandatoryBL` priorisiert per SQL filialbezogene Kreise des Mitarbeiter-Mandanten vor dem Standardmandanten, überspringt verbrauchte (`Aktuell<=0`) und fortschreibt per parameterisiertem UPDATE. +Aussage: Das System soll bei der Nummernvergabe den filialbezogenen Kreis bevorzugen und auf den Standardmandanten zurückfallen; verbrauchte Bereiche werden übersprungen. +Ergebnis: Mandant-/filialgetrennte, lückenlose Nummerierung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Mandatory\MandatoryBL.cs, GetNumberGroup/SaveNumberGroups (Zeilen 38-96) - Begründung: Delegation+Priorität im SQL +Prüfidee: Filiale mit eigenem Kreis → dieser wird gezogen; ohne → Standardmandant. +Tracelinks: StRS-016; SyRS-010, SwRS-026, SwRS-099 +Konsolidierung: Kandidat: mit NumberGroupBL (SyRS-010) zusammenführen - gleiche Fachfunktion, zwei Implementierungen +Übernahmewürdigkeit: übernehmen +Status: belegt + +--- + +ID: SyRS-045 +Titel: Lieferanten-EDI: Bestellungen hinaus, Antworten herein +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: Interoperabilität (ISO 25010) +Akteur: Einkauf, Großhändler (EGIS, ALSO, Alltron, Komsa, Herweck, ITscope) +Vorbedingung: SupplierEdiConfiguration je Lieferant (FTP/SFTP/HTTP) +Fakt: `EDIDispatcherBL` erzeugt openTRANS-2.1-Dokumente (ITscope-Sonderfall, Dropshipping-UDX) und lädt per FTP/SFTP/HTTP; `SupplierEdiBL.DownloadStartAsync` liest Retouren/Lieferscheine/Rechnungen (inkl. ZUGFeRD) und protokolliert in EDILog. +Aussage: Das System soll Lieferantenbestellungen im Partnerrformat erzeugen/übertragen und Antworten (Auftragsbestätigung, Lieferschein, Rechnung) formaterkennend einlesen, referenzieren und protokollieren. +Ergebnis: Revisionssicherer EDI-Kreis; zugeordnete Fremdbelege. +Belege: + - [PRIMÄR] src\backend\Centron.BL\EDI\EDIDispatcherBL.cs, EdiOrderUploadAsync - Begründung: Dispatch+Kanäle + - [PRIMÄR] src\backend\Centron.BL\EDI\Opentrans21\Opentrans21OrderBL.cs, CreateOrderDocument - Begründung: Formatimplementierung + - [PRIMÄR] src\backend\Centron.BL\EDI\SupplierEDI\SupplierEdiBL.cs, DownloadStartAsync/ReadZugferdInvoice - Begründung: Importpfade+Logging +Prüfidee: XML gegen openTRANS-2.1-Schema; Beispieldatei je Distributor → erwarteter Fremdbeleg. +Tracelinks: StRS-001, StRS-003; SwRS-016, SwRS-065 +Konsolidierung: Kandidat: Format-Matrix je Distributor als Detailkapitel +Übernahmewürdigkeit: übernehmen - BEFUND: kein EDIFACT im Repo, alles XML-basiert (Planungsannahme korrigiert) +Status: belegt + +--- + +ID: SyRS-046 +Titel: Fremddaten-Produktanreicherung über Distributor-/Poolschnittstellen +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: Kompatibilität (ISO 25010) +Akteur: Artikelstammpflege, Einkauf +Vorbedingung: Zugangsdaten der jeweiligen Plattform konfiguriert +Fakt: Eight API-Adapter (Cop SOAP, EGIS XML, ITscope REST, Icecat XML, FinAPI, GLS, Shipcloud, docuFORM) mappen externe Antworten in interne Modelle; ITscope markiert verarbeitete Deals als archiviert; EGIS liefert Preis/Verfügbarkeit in Echtzeit. +Aussage: Das System soll Artikel-, Preis-, Verfügbarkeits- und Marketingdaten externer Distributoren-/Poolsysteme über austauschbare Adapter abrufen und in interne Modelle überführen. +Ergebnis: Aktuelle Fremddaten in Artikelanlage, Einkauf und Shop ohne manuelle Pflege. +Belege: + - [PRIMÄR] src\apis\Centron.APIs.EgisDataAccess\EgisApi.cs, SearchAsync/GetPriceAndAvailability - Begründung: Repräsentant gelesen + - [PRIMÄR] src\apis\Centron.APIs.ITscopeDataAccess\ITscopeApi.cs, GetProductByEanCodeAsync/SetDealArchived - Begründung: Endpunkte belegt + - [PRIMÄR] src\apis\Centron.APIs.IcecatDataAccess\IcecatApi.cs, GetProductAsync - Begründung: Feed-URL+Parser +Prüfidee: Fixture-Responses je Adapter gegen Parser laufen lassen; Quota-Fehlerpfad. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: Adapter-Familie zu einer "Fremddatenintegration"-Anforderung (mit SwRS-062 TradePool, SwRS-073 CPra) +Übernahmewürdigkeit: übernehmen - Provider-abhängig priorisieren +Status: belegt + +--- + +ID: SyRS-047 +Titel: Paketversand über externe Carrier-Plattformen +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: Funktionale Eignung (ISO 25010) +Akteur: Versandplatz; GLS-/Shipcloud-API +Vorbedingung: Sendungsdaten gepflegt; API-Zugang vorhanden +Fakt: `CentronGlsLogic.UploadShipment` validiert vorher (max. 50 Referenzen/30 Pakete) und POSTet an die GLS-API (Test-URL umschaltbar); `CentronShipcloudLogic.CreateShipmentAsync` mappt TrackId/TrackingUrl/LabelUrl/Preis. +Aussage: Das System soll Sendungen erst nach lokaler Validierung an Carrier-Plattformen übermitteln und Tracking-/Labeldaten für die Weitereverarbeitung zurückführen. +Ergebnis: Kein unnötiger API-Verkehr bei invaliden Sendungen; Versanddatensatz mit Track/Label/Preis. +Belege: + - [PRIMÄR] src\apis\Centron.Api.Gls\CentronGlsLogic.cs, UploadShipment/DoValidateShipment - Begründung: Grenzwerte+Endpunkte im Code + - [PRIMÄR] src\apis\Centron.Api.Shipcloud\CentronShipcloudLogic.cs, CreateShipmentAsync/GetCarriersAsync - Begründung: Komplementärfall gelesen +Prüfidee: 51 Referenzen → lokaler Abbruch; Mock-Antwort mit LabelUrl → UploadResult. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: "Versandanbieter-Anbindung" (GLS+Shipcloud) zusammenführen +Übernahmewürdigkeit: übernehmen - BEFUND: hartkodierte Basic-Auth-Konstante in GLS-Consts muss in Secret-Verwaltung +Status: belegt + +--- + +ID: SyRS-048 +Titel: Helpdesk-Gegenstelle für externes Ticketsystem (River Suite/Riverbird) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: Sicherheit (ISO 25010) +Akteur: Riverbird-WebService (egend), c-entron-Masken (aushend) +Vorbedingung: Ticket oder RMM-AccessKey gültig +Fakt: `RiverDivoBL.ValidateRiverTicket(OrRmmAccessKey)` validiert vor Helpdesk-Anlage/-Update/Kundensync; `RiverConnectionBL` ruft AD-Benutzer, Geräte, SNMP-Geräte, Vertragsabrechnungsmengen ab. +Aussage: Das System soll Helpdesk-Vorgänge und Stammdaten bidirektional mit dem Partner-Ticketsystem austauschen und eingehende Aufrufe zwingend über Ticket-/AccessKey-Validierung absichern. +Ergebnis: Beidseitig konsistente Tickets/Stammdaten; keine unauthentisierte Anlage. +Belege: + - [PRIMÄR] src\backend\Centron.BL\RiverDivo\RiverDivoBL.cs, ValidateRiverTicket/CreateHelpdeskRequest - Begründung: Serverseite dokumentiert+implementiert + - [PRIMÄR] src\backend\Centron.BL\RiverDivo\RiverConnectionBL.cs, GetDevices/GetContractBillingAmounts - Begründung: Clientseite +Prüfidee: Ungültiges Ticket → Anlage abgelehnt; Mock-Responses je DTO. +Tracelinks: StRS-013 +Konsolidierung: nein (partnerabhängige Integration) +Übernahmewürdigkeit: Sonderfall - nur bei Riverbird-Partnerschaft relevant +Status: belegt + +--- + +ID: SyRS-049 +Titel: Mandanten-Installationsstatus und Installer-Download beim Herstellerportal +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Anwendung (Update-Funktion), c-entron-Portal +Vorbedingung: Produkt-ID (Dongle) vorhanden, Portal erreichbar +Fakt: `PortalWebServiceAccessBL` prüft `CheckCustomerStatusByProductId` und lädt `GetLatestInstaller` mit festem Service-Ticket; `ApplicationVersionBL.SaveLogin` erfasst Version je Maschine/User und meldet asynchron ans Portal (Fehler werden geschluckt). +Aussage: Das System soll Update-/Statusabfragen und Versionsmeldungen an das Herstellerportal führen, ohne dass Portal-Ausfälle Funktion oder Login blockieren. +Ergebnis: Updates nur für berechtigte Kunden; Versionsbestand je Kunde sichtbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Portal\PortalWebServiceAccessBL.cs, beide Methoden - Begründung: WCF-Zugriff gelesen + - [PRIMÄR] src\backend\Centron.BL\Administration\Applications\ApplicationVersionBL.cs, SaveLogin/UploadToServer - Begründung: Asynchronität+Fallback +Prüfidee: Ungültige Produkt-ID → false/null; Portal offline → Login trotzdem erfolgreich. +Tracelinks: StRS-001 +Konsolidierung: Kandidat: mit Lizenz-/Update-Themen bündeln +Übernahmewürdigkeit: Sonderfall - hersteller-spezifisch; Muster "fehlertolerante telemetry" übernehmbar; Datenschutz (IP/Maschine) prüfen +Status: belegt diff --git a/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/Traceability.md b/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/Traceability.md new file mode 100644 index 00000000..108d240e --- /dev/null +++ b/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/Ergebnisse/Traceability.md @@ -0,0 +1,224 @@ +# Traceability-Matrix + +Rückwärts-/Vorwärtsverfolgung über alle 199 Anforderungen (16 StRS, 49 SyRS, 134 SwRS). +„Verfolgung" = Inhalt des Feldes Tracelinks im jeweiligen Anforderungsblock; „Hauptartefakt" = erster PRIMÄR-Beleg (sonst SEKUNDÄR/KONTEXT). Alle Pfade relativ zum Arbeitsverzeichnis. + +## StRS-Ebene + +| StRS-ID | Titel | Verfolgung (abgeleitete Anforderungen) | Hauptartefakt | +|---|---|---|---| +| StRS-001 | Ein gemeinsames ERP-System für alle Fachprozesse | SyRS-024, SyRS-025, SyRS-026, SyRS-027, SyRS-028 | src\centron\Centron.WPF.UI\FrontWindow.xaml.cs | +| StRS-002 | Endkunden wickeln Bestellung und Service selbstständig im Kundenportal ab | SyRS-016, SyRS-017, SyRS-018, SyRS-019, SyRS-020, SyRS-021 | README.md (SEKUNDÄR); ReceiptCartBL.cs (PRIMÄR) | +| StRS-003 | Lückenloser, nachvollziehbarer Belegfluss vom Ursprungsbeleg bis zum Mahnlauf | SyRS-012, SyRS-013, SyRS-014, SyRS-039, SyRS-040, SyRS-041 | src\backend\Centron.BL\Sales\Receipts\ReceiptProgressionBL.cs | +| StRS-004 | Wer darf was – selbstverwaltetes Rechte- und Lizenzmodell mit Selbstschutz | SyRS-001, SyRS-002, SyRS-003, SyRS-004, SyRS-005, SyRS-006, SyRS-007, SyRS-008, SyRS-009 | src\backend\Centron.BL\Administration\Rights\AppRightsBL.cs | +| StRS-005 | Ein maßgeblicher Adress-/Kundenstamm statt paralleler Datenhaltungen | SwRS-027, SwRS-028, SwRS-031, SwRS-132 | src\backend\Centron.Entities\Entities\CustomerArea\Customer.cs | +| StRS-006 | Web-Accounts sehen ausschließlich Daten ihres eigenen Kunden | SyRS-016, SyRS-017, SyRS-018 | src\backend\Centron.BL\Accounts\AccountAddressBL.cs | +| StRS-007 | Personalstamm (Employee) und Zugang (AppUser/Web-Account) sind getrennte Identitäten | SwRS-029, SwRS-032, SwRS-052 | src\backend\Centron.BL\EmployeeArea\AppUserBL.cs | +| StRS-008 | Verfügbarkeit und Rolle des Mitarbeiters steuern die Arbeitsverteilung | SyRS-002 | src\backend\Centron.BL\EmployeeArea\EmployeeBL.cs | +| StRS-009 | Deterministische Länder-, Währungs- und Inlandsbasis | SwRS-041, SwRS-042 | src\backend\Centron.BL\CountryArea\CountryBL.cs | +| StRS-010 | Filial- und Lagerstruktur je Mandant | SwRS-030, SwRS-031 | src\backend\Centron.BL\Administration\Company\BranchBL.cs | +| StRS-011 | Zahlungs- und Lieferkonditionen zentral pflegen, Skonto aussteuerbar | SyRS-013, SyRS-015, SyRS-040, SyRS-041, SwRS-012, SwRS-013, SwRS-014, SwRS-034 | src\backend\Centron.BL\Administration\Masterdata\AssetConditionBL.cs | +| StRS-012 | SLA-Zusagen aus Serviceverträgen verbindlich durchsetzen | keine abgeleitete Anforderung (SLA-Kette abschließend in UpdateHelpdeskBL belegt) | src\backend\Centron.BL\Sales\Support\UpdateHelpdeskBL.cs | +| StRS-013 | Nachvollziehbare Ticketbearbeitung mit beschränkter Sichtbarkeit | SyRS-037, SyRS-038, SyRS-043, SyRS-048, SwRS-043, SwRS-045, SwRS-047, SwRS-049, SwRS-050, SwRS-127 | src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs | +| StRS-014 | Wiedervorlagen und Aufgaben über alle Fachbereiche bündeln | SwRS-074, SwRS-077, SwRS-079 | src\backend\Centron.BL\ToDoArea\ToDoBL.cs | +| StRS-015 | Nachvollziehbarkeit von Datenänderungen (Wer, Was, Wann) | SyRS-004, SyRS-033, SwRS-020, SwRS-023, SwRS-047, SwRS-082, SwRS-086, SwRS-093, SwRS-094, SwRS-110 | src\backend\Centron.DAO\ChangeTracking\ChangeTrackingEventListener.cs | +| StRS-016 | Lückenlose, prüfsichere Nummernvergabe (GoBD) | SyRS-010, SyRS-039, SyRS-044, SwRS-026, SwRS-099, SwRS-120 | src\backend\Centron.BL\Administration\Company\NumberGroupBL.cs | + +## SyRS-Ebene + +| SyRS-ID | Titel | Eltern (StRS) | Kinder | Hauptartefakt | +|---|---|---|---|---| +| SyRS-001 | API-Aufrufe nur mit deklariertem Benutzerrecht | StRS-004 | SwRS-001, SwRS-002 | src\webservice\Centron.Controllers\Authorization\AuthorizeUserRightAttribute.cs | +| SyRS-002 | Mehrstufiger Anmeldeprozess mit Zweitfaktor (RADIUS oder E-Mail-Link) | StRS-004, StRS-008 | SwRS-003, SwRS-004 | src\backend\Centron.BL\Administration\Logins\TwoFactor\TwoFactorAuthBL.cs | +| SyRS-003 | Lizenz- und Hosted-Schranke für interne Funktionen und Modulzugriffe | StRS-004 | SwRS-006, SwRS-024 | src\webservice\Centron.Controllers\Authorization\CentronHostedAuthorization.cs | +| SyRS-004 | DSGVO-Löschung personenbezogener Daten nur für Berechtigte, mit Protokoll | StRS-004, StRS-015 | SwRS-009 | src\backend\Centron.BL\Administration\DataSecurity\DataSecurityBL.cs | +| SyRS-005 | Ticketvergabe nach Rechts- und Lizenzprüfung, zeitlich befristet | StRS-004 | SwRS-003 | src\backend\Centron.BL\Administration\Logins\Auth\Authenticator.cs | +| SyRS-006 | Every REST request must pass ticket/token authentication | StRS-004 | SwRS-002, SwRS-053, SwRS-054 | src\webservice\Centron.Host\AspNetCore\TicketAuthenticationHandler.cs | +| SyRS-007 | Nexus-Host authentifiziert per Cookie/Ticket oder OIDC und stellt Sitzung aus | StRS-004 | SwRS-044, SwRS-051 | src\nexus\CentronNexus.Host\Program.cs | +| SyRS-008 | Umschaltung der Systemauthentifizierung auf OpenID Connect (Entra ID) | StRS-004 | – | src\nexus\CentronNexus\Configuration\OpenIdConnectConfigurationService.cs | +| SyRS-009 | Outlook-AddIn-Einbettung mit iframe-fähiger Cookie-Policy | StRS-004 | – | src\nexus\CentronNexus.Host\Program.cs | +| SyRS-010 | Fortlaufende Rechnungsnummern je Nummernkreis | StRS-016, StRS-003 | SyRS-044 | src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs | +| SyRS-011 | Rechnungsexport-Kennzeichnung steuert Änderung und Storno | StRS-003 | SwRS-011 | src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs | +| SyRS-012 | Mahnlauf: stufenweise Eskalation überfälliger Rechnungen, transaktional | StRS-003 | – | src\backend\Centron.BL\Sales\Receipts\Invoices\Dunning\DunningRunBL.cs | +| SyRS-013 | Zahlungsstatus nur über zentralen, protokollierten Buchungspunkt | StRS-003, StRS-011 | – | src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs | +| SyRS-014 | Belegweiterverarbeitung nur entlang definierter Regeln je Belegart | StRS-003 | SwRS-010 | src\backend\Centron.BL\Sales\Receipts\Invoices\InvoiceSpecificLogic.cs | +| SyRS-015 | Kundenindividuelle Preise im Web-Shop mit nachvollziehbarer Rabattanzeige | StRS-002, StRS-011 | SwRS-013, SwRS-035 | src\backend\Centron.BL\Sales\Receipts\ReceiptCartBL.cs | +| SyRS-016 | Kundenportal nur für Web-Account-Login über den Kundenportal-Port | StRS-002, StRS-006 | SwRS-007, SwRS-036 | src\backend\Centron.BL\Sales\Receipts\ReceiptCartBL.cs | +| SyRS-017 | Shop-Sortiment auf aktive Sonderpreise des Kunden beschränken | StRS-002, StRS-006 | – | src\backend\Centron.BL\Sales\Receipts\ReceiptCartBL.cs | +| SyRS-018 | Warenkorb-Bestellung nur mit Web-Recht und Prüfstufe | StRS-002, StRS-006 | SwRS-040 | src\backend\Centron.BL\Sales\Receipts\ReceiptCartBL.cs | +| SyRS-019 | Token-basierte Angebotsansicht ohne Login | StRS-002 | – | src\backend\Centron.BL\WebServices\Sales\Receipts\ReceiptWebServiceBL.cs | +| SyRS-020 | Signatur- und Akzeptanzstrecke für freigegebene Dokumente | StRS-002 | – | src\nexus\CentronNexus\DocumentSigning\DocumentSigningPage.razor | +| SyRS-021 | PDF-Auslieferung über gemeinsamen Office-Cache-Endpunkt | StRS-002 | – | src\nexus\CentronNexus\Office\Controllers\PdfController.cs | +| SyRS-022 | Hintergrunddienste zentral über Konfigurationsflag steuerbar | StRS-001 | SwRS-084 | src\webservice\Centron.Host\CentronHost.cs | +| SyRS-023 | Versionsgesteuerte, idempotente Datenbankmigration mit Protokoll | StRS-001 | – | src\backend\Centron.BL\Administration\Scripts\ScriptEngineBL.cs | +| SyRS-024 | REST-API-Versionierung und einheitliche Fehlerbehandlung | StRS-001 | – | src\webservice\Centron.Host\AspNetCore\RegisterCentronApiVersioning.cs | +| SyRS-025 | Standardisierter komprimierter REST-Kanal „RESTC" | StRS-001 | – | src\webservice\Centron.WebServices.Core\Connections\CentronWebService.cs | +| SyRS-026 | Plattformabhängiger Webserver-Betrieb (HttpSys/Kestrel) | StRS-001 | – | src\webservice\Centron.Host\CentronHost.cs | +| SyRS-027 | Betrieb als Windows-Dienst mit Fehlerkapselung | StRS-001 | – | src\webservice\Centron.Host.WindowsService\CentronService.cs | +| SyRS-028 | Service-spezifische BL-Schicht (*WebServiceBL) | StRS-001 | – | src\backend\Centron.BL\WebServices\Administration\Logins\TicketWebServiceBL.cs | +| SyRS-029 | Zentrales Konfigurationswertesystem (AppSettings/ApplicationSettings) | StRS-001 | SwRS-096 | src\backend\Centron.BL\Administration\Settings\AppSettingsBL.cs | +| SyRS-030 | Zentrale Konfigurations-DB mit verschlüsseltem Hotline-Masterkey | StRS-004 | – | src\backend\Centron.BL\Administration\CentronConfigDb\CentronConfigurationDbBL.cs | +| SyRS-031 | WebService-Konfigurationsdatei mit verschlüsselten Geheimnissen | StRS-004 | – | src\backend\Centron.BL\Administration\WebServiceConfiguration\WebServiceConfigSerializer.cs | +| SyRS-032 | Client-Verbindungsprofile mit AES-verschlüsselten Passwörtern | StRS-004 | – | src\backend\Centron.BL\Administration\Connections\ConnectionBL.cs | +| SyRS-033 | Attributsgesteuerte Feldänderungs-Historie im Persistenzlayer | StRS-015 | – | src\backend\Centron.DAO\ChangeTracking\ChangeTrackingEventListener.cs | +| SyRS-034 | Einheitliches ORM-Mapping auf Legacy-Schema (PK I3D) | StRS-001 | – | src\backend\Centron.DAO\Mappings\BaseMaps.cs | +| SyRS-035 | Zentrale SQL-Abfragen in einem NamedQuery-Pool | StRS-001 | – | src\backend\Centron.DAO\NamedQueries\NamedQueryManager.cs | +| SyRS-036 | Rohe SQL-Zugriffe transaktionsgebunden über die ORM-Session | StRS-001 | – | src\backend\Centron.DAO\AdoNETDataAccess\RawSqlAccessDAO.cs | +| SyRS-037 | Serverseitiger Ticket-Cache mit Hintergrund-Synchronisation | StRS-013, StRS-001 | SwRS-048 | src\nexus\CentronNexus\Shared\Services\TicketCacheService.cs | +| SyRS-038 | Push-Zustellung von Benachrichtigungen per SignalR | StRS-013 | SwRS-049, SwRS-050 | src\nexus\CentronNexus\Shared\Services\SignalRNotificationsService.cs | +| SyRS-039 | Buchhaltungsexport in austauschbare Zielsystemformate | StRS-003, StRS-016 | SyRS-011, SwRS-067, SwRS-133 | src\backend\Centron.BL\DataExchange\BookKeeping\BookKeepingExportBL.cs | +| SyRS-040 | Normkonforme E-Rechnungsformate (ZUGFeRD/XRechnung, eb:interface) | StRS-003, StRS-011 | – | src\backend\Centron.BL\DataExchange\EDI\SaleInvoices\InvoiceZugferdBL.cs | +| SyRS-041 | Zahlungsziel- und Skontoermittlung aus der Zahlungsbedingung | StRS-003, StRS-011 | SwRS-012 | src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs | +| SyRS-042 | Statistik-Caches mit Selbstreparatur und Sofortaktualisierung | StRS-001 | SwRS-104 | src\backend\Centron.BL\Services\CachedTableBL.cs | +| SyRS-043 | Helpdesk-Statusmaschine als konfigurierbare Übergänge | StRS-013 | SwRS-043, SwRS-045, SwRS-047, SwRS-127 | src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs | +| SyRS-044 | Nummernkreis-Delegation Mandant→Filiale→Standard | StRS-016 | SyRS-010, SwRS-026, SwRS-099 | src\backend\Centron.BL\Administration\Mandatory\MandatoryBL.cs | +| SyRS-045 | Lieferanten-EDI: Bestellungen hinaus, Antworten herein | StRS-001, StRS-003 | SwRS-016, SwRS-065 | src\backend\Centron.BL\EDI\EDIDispatcherBL.cs | +| SyRS-046 | Fremddaten-Produktanreicherung über Distributor-/Poolschnittstellen | StRS-001 | – | src\apis\Centron.APIs.EgisDataAccess\EgisApi.cs | +| SyRS-047 | Paketversand über externe Carrier-Plattformen | StRS-001 | – | src\apis\Centron.Api.Gls\CentronGlsLogic.cs | +| SyRS-048 | Helpdesk-Gegenstelle für externes Ticketsystem (River Suite/Riverbird) | StRS-013 | – | src\backend\Centron.BL\RiverDivo\RiverDivoBL.cs | +| SyRS-049 | Mandanten-Installationsstatus und Installer-Download | StRS-001 | – | src\backend\Centron.BL\Administration\Portal\PortalWebServiceAccessBL.cs | + +## SwRS-Ebene + +| SwRS-ID | Titel | Eltern | Hauptartefakt | +|---|---|---|---| +| SwRS-001 | Zentrale, gecachte Rechtsprüfung mit Fail-closed-Semantik | SyRS-001, StRS-004 | src\backend\Centron.BL\Administration\Rights\AppRightsBL.cs | +| SwRS-002 | Sichere Behandlung personengebundener API-Access-Tokens | SyRS-001, SyRS-006, StRS-004 | src\backend\Centron.BL\Administration\AccessTokens\AccessTokenBL.cs | +| SwRS-003 | Passwortanmeldung nur für aktive, nicht gesperrte Konten | SyRS-002, SyRS-005, StRS-004 | src\backend\Centron.BL\Administration\Logins\Auth\BasicAuthenticator.cs | +| SwRS-004 | Prüfung des personengebundenen Zwei-Faktor-Schlüssels | SyRS-002, StRS-004 | src\backend\Centron.BL\TwoFactorAuthenticator\TwoFactorAuthenticationBL.cs | +| SwRS-005 | Alt-Passwortverwaltung (Keywords) – Migrationsbedarf | SyRS-030, StRS-004 | src\backend\Centron.BL\PasswordManagementArea\PasswordManagementKeywordBL.cs (SEKUNDÄR) | +| SwRS-006 | Elektronische PDF-Signatur mit geschützter Zertifikatskonfiguration | SyRS-003, StRS-003 | src\backend\Centron.BL\Security\PdfSigningBL.cs | +| SwRS-007 | Ticketansichten im Kundenportal nach Web-Rechten differenzieren | SyRS-016, StRS-002 | src\nexus\CentronNexus\WebCart\CustomerTicketDetailsPage.razor (SEKUNDÄR) | +| SwRS-008 | Passwort-Manager: Export nur mit Recht, Lizenz und Masterkey | SyRS-003, SyRS-030, StRS-004 | src\backend\Centron.BL\PasswordManager\PasswordManagerBL.cs | +| SwRS-009 | Anonymisierung von Ansprechpartnern mit Löschprotokoll | SyRS-004, StRS-004 | src\backend\Centron.BL\Administration\DataSecurity\DataSecurityBL.cs | +| SwRS-010 | Weiterverarbeitungsregeln und Herkunftsbindung je Belegart | SyRS-014, StRS-003 | src\backend\Centron.BL\Sales\Receipts\Invoices\InvoiceSpecificLogic.cs | +| SwRS-011 | Rechnungsstorno: Guard-Kette und historisierende Neufassung | SyRS-011, StRS-003 | src\backend\Centron.BL\Sales\Receipts\Invoices\ReceiptInvoiceBL.cs | +| SwRS-012 | Skontoberechnung und -text je Zahlungsbedingung | SyRS-041, StRS-011 | src\backend\Centron.BL\Administration\Masterdata\AssetConditionTextReplacementBL.cs | +| SwRS-013 | Preishierarchie der Belegposition (Vertrag > Sonderpreis > Staffelpreis) | StRS-011, SyRS-015 | src\backend\Centron.BL\Sales\Receipts\Internal\ReceiptItemPriceBL.cs | +| SwRS-014 | Zweistufige Preisrundung mit artikelbezogener Genauigkeit | StRS-011, SyRS-040 | src\backend\Centron.BL\Sales\Receipts\ReceiptPriceHelperBL.cs | +| SwRS-015 | Distributoren automatisch bei Import anlegen | StRS-001 | src\backend\Centron.BL\Buying\External\DistributorBL.cs | +| SwRS-016 | Bestellvorschlagsliste aus öffentlichem Bedarf und Mindestbestand | StRS-001, SyRS-045 | src\backend\Centron.BL\Purchasing\OrderSuggestionList\OrderSuggestionListBL.cs | +| SwRS-017 | Bereichsübergreifender Export von Lieferantenrechnungen/Timerleistungen | StRS-003 | src\backend\Centron.BL\Purchasing\SupplierOrderPerBranchBL.cs | +| SwRS-018 | Rechteprüfung in Kommissionierung und Barcodeerzeugung | SyRS-001, StRS-004 | src\backend\Centron.BL\Warehousing\Commissions\OrderCommissionBL.cs | +| SwRS-019 | Fortschreibung des Artikel-EK aus Wareneingangspreisen | StRS-003, StRS-011 | src\backend\Centron.BL\Warehousing\StockManagement\ArticleStockBL.cs | +| SwRS-020 | Validierte Protokollierung von Lagerumlagerungen | StRS-015 | src\backend\Centron.BL\Logistics\Warehousing\StockBL.cs | +| SwRS-021 | Kunden-Produktmatrix mit Bewertungshistorie | StRS-001 | src\backend\Centron.BL\ProductMatrix\ProductMatrixBL.cs | +| SwRS-022 | Fertigungsaufträge nach Maschine/Maschinenart filterbar | StRS-001 | src\backend\Centron.BL\Production\ProductionOrderBL.cs | +| SwRS-023 | Geräteverwaltung mit Soft-Delete und Protokoll | StRS-015 | src\backend\Centron.BL\Devices\AccountDeviceBL.cs | +| SwRS-024 | Produktionsmanagement durchgehend lizenzgeprüft | SyRS-003, StRS-004 | src\backend\Centron.BL\Production\ProductionBL.cs | +| SwRS-025 | Handelspool-Artikelimport aus Distributor-XML | SyRS-046, StRS-001 | src\backend\Centron.BL\TradePool\Core\TradePoolXmlLogic.cs | +| SwRS-026 | Automatische Nummernvergabe für Account, Kunde und Lieferant | StRS-016, SyRS-044 | src\backend\Centron.BL\Accounts\AccountBL.cs | +| SwRS-027 | Genau eine Standardadresse je Account | StRS-005 | src\backend\Centron.BL\Accounts\AccountAddressBL.cs | +| SwRS-028 | Branchenzuweisungen atomar ersetzen | StRS-005 | src\backend\Centron.BL\CustomerArea\BusinessLineBL.cs | +| SwRS-029 | Explizite Zuordnung Employee → AppUser | StRS-007 | src\backend\Centron.BL\EmployeeArea\AppUserBL.cs | +| SwRS-030 | Filialauswahl mit Pseudo-Einträgen Hauptsitz/Alle Filialen | StRS-010 | src\backend\Centron.BL\Administration\Company\BranchBL.cs | +| SwRS-031 | Firmenübersicht als reines Lese-API | StRS-005, StRS-010 | src\backend\Centron.BL\Administration\CompanyInformations\CompanyBL.cs | +| SwRS-032 | Abteilungen benutzerbezogen laden und pflegen (Parallelimplementierung) | StRS-007 | src\backend\Centron.BL\Administration\Employees\EmployeeDepartmentBL.cs | +| SwRS-033 | Persistente persönliche Mitarbeitereinstellungen | StRS-001 | src\backend\Centron.BL\Administration\Employees\EmployeeSettingBL.cs | +| SwRS-034 | Konditionstextvorschau gegen echte Testrechnung | StRS-011 | src\backend\Centron.BL\Administration\Masterdata\AssetConditionBL.cs | +| SwRS-035 | Preis- und Rabatttransparenz im Shop | SyRS-015, StRS-002 | src\backend\Centron.BL\Sales\Receipts\ReceiptCartBL.cs | +| SwRS-036 | SelfCare-Formular erzeugt Helpdesk-Ticket | SyRS-016, StRS-002 | src\backend\Centron.BL\SelfCare\SelfCareBL.cs | +| SwRS-037 | Weblink-Aktion legt CRM-Aktivität für den Betreuer an | StRS-001 | src\backend\Centron.BL\WebLinks\WebLinkActionAccountActivityHandler.cs | +| SwRS-038 | Versionsauskunft des Webservices | StRS-001 | src\backend\Centron.BL\WebVersion\VersionBL.cs | +| SwRS-039 | Web-Einstellungen strikt nach Login-Art getrennt | StRS-006, StRS-001 | src\backend\Centron.BL\WebSuite\Administration\Settings\WebSettingBL.cs | +| SwRS-040 | Warenkorb-Prüfstufe und Kundenadmin-Oberfläche | SyRS-018, StRS-002 | src\nexus\CentronNexus\WebCart\Helpers\UserViewModel.cs (SEKUNDÄR) | +| SwRS-041 | Täglicher Devisenkursimport aus dem EZB-Feed | StRS-009 | src\backend\Centron.BL\CountryArea\CountryBL.cs | +| SwRS-042 | Inlandsland aus dem Default-Mandanten ableiten | StRS-009 | src\backend\Centron.BL\CountryArea\CountryBL.cs | +| SwRS-043 | Ticket-Statuswechsel per Drag-and-Drop im Kanban | SyRS-043, StRS-013 | src\nexus\CentronNexus\ServiceBoard\CachedTicketList\Components\KanbanBucket.razor | +| SwRS-044 | ServiceBoard-Seiten durch Login-, Lizenz- und Portschutz | SyRS-007, SyRS-003, StRS-013 | src\nexus\CentronNexus\ServiceBoard\_Imports.razor | +| SwRS-045 | Automatische Status-Defaults bei Anlage und Übernahme | SyRS-043, StRS-013 | src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs | +| SwRS-046 | Fertigungsübersicht mit Arbeitsplatz- und Mitarbeiterauswahl | StRS-001 | src\nexus\CentronNexus\ProductionOrderManagement\Pages\ProductionOrderOverView.razor | +| SwRS-047 | Lückenlose Ticketstatus-Historie im Speicherpfad | SyRS-043, StRS-013, StRS-015 | src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs | +| SwRS-048 | Prozessweiter Ticketcache im Nexus (Singleton + HostedService) | SyRS-037, StRS-013 | src\nexus\CentronNexus\Shared\Services\TicketCacheService.cs | +| SwRS-049 | NexusNotifications je Empfänger verwalten (Raw-SQL) | SyRS-038, StRS-013 | src\backend\Centron.BL\NexusNotifications\NexusNotificationsBL.cs | +| SwRS-050 | NotificationHub filtert pro Benutzer und unterscheidet Schedule-Typen | SyRS-038, StRS-013 | src\nexus\CentronNexus\Shared\Services\NotificationHub.cs | +| SwRS-051 | Nur lokale Redirect-Ziele bei An-/Abmeldung (Open-Redirect-Schutz) | SyRS-007, StRS-004 | src\nexus\CentronNexus\Shared\Auth\AuthController.cs | +| SwRS-052 | Ticket-Ansichten mit Besitzer- und Namensregeln | StRS-013, StRS-007 | src\backend\Centron.BL\NexusTicketViews\NexusTicketViewBL.cs | +| SwRS-053 | Ticketauthentifizierungs-Handler als Durchsetzungsstelle | SyRS-006, StRS-004 | src\webservice\Centron.Host\AspNetCore\TicketAuthenticationHandler.cs | +| SwRS-054 | Client-Kontext (IP, API-Methode) in der Access-Token-Validierung | SyRS-006, StRS-004 | src\webservice\Centron.Host\AspNetCore\TicketAuthenticationHandler.cs | +| SwRS-055 | TOTP-Zwei-Faktor-Bibliothek im Plattformkern | StRS-004 | src\shared\Centron.Core\TotpAuth\Totp.cs | +| SwRS-056 | Schnittstellenmodul als Contract-First-Schicht | StRS-001 | src\backend\Centron.Interfaces (Ordnerstruktur) | +| SwRS-057 | Gemeinsame Querschnittsbibliothek (Logging, Settings, Netzwerk, Codierung) | StRS-001 | src\backend\Centron.Common\Network\IpAddressHelper.cs | +| SwRS-058 | eb:interface-4.3-E-Rechnung für Österreich | SyRS-040, StRS-003 | src\apis\Centron.Api.EbInterface\EbInterfaceLogic.cs | +| SwRS-059 | GLS-Sendungsupload mit Vorabvalidierung | SyRS-047, StRS-001 | src\apis\Centron.Api.Gls\CentronGlsLogic.cs | +| SwRS-060 | Sendungsanlage und Carrier-Abruf über Shipcloud | SyRS-047, StRS-001 | src\apis\Centron.Api.Shipcloud\CentronShipcloudLogic.cs | +| SwRS-061 | Produktdaten per SOAP-Session vom Cop-System | SyRS-046, StRS-001 | src\apis\Centron.APIs.CopDataAccess\CopApi.cs | +| SwRS-062 | EGIS-Artikelsuche mit Preis und Verfügbarkeit | SyRS-046, StRS-001 | src\apis\Centron.APIs.EgisDataAccess\EgisApi.cs | +| SwRS-063 | PSD2-Bankdatenabruf über finapi | StRS-003, StRS-011 | src\apis\Centron.APIs.FinAPI\FinApiClient.cs | +| SwRS-064 | Icecat-Produktinhalte (Text/Bild/Specs) je EAN | SyRS-046, StRS-001 | src\apis\Centron.APIs.IcecatDataAccess\IcecatApi.cs | +| SwRS-065 | ITscope-Produkte, Angebote und Deals inkl. Archivierung | SyRS-046, SyRS-045 | src\apis\Centron.APIs.ITscopeDataAccess\ITscopeApi.cs | +| SwRS-066 | docuFORM-Gerätezähler über OAuth2-PKCE | StRS-001, StRS-003 | Centron.Api.docuFORM\DocuFormRestApiClient.cs | +| SwRS-067 | Eindeutige Standard-Exportkonfiguration je Mandant | SyRS-039, StRS-003 | src\backend\Centron.BL\DataExchange\BookKeeping\BookKeepingExportBL.cs | +| SwRS-068 | E-Mail-Versand über austauschbare Protokollclients, Secrets verschlüsselt | StRS-001 | src\backend\Centron.BL\Mail\Factory\CentronMailFactory.cs | +| SwRS-069 | Mailing als vollständiges Aggregat laden | StRS-001 | src\backend\Centron.BL\Mailings\MailingDataBL.cs | +| SwRS-070 | MailScanner-Profile nur mit VMA-Recht, Passwörter verschlüsselt | SyRS-001, SyRS-030, StRS-004 | src\backend\Centron.BL\MailScanner\MailScannerBL.cs | +| SwRS-071 | Chat-Nachrichten: Mitgliederzugriff, Autorschaft, Löschschutz | StRS-001 | src\backend\Centron.BL\Chats\ChatBL.cs | +| SwRS-072 | Kundensuche im Outlook-AddIn über Gerätenummer | SyRS-035, StRS-001 | src\backend\Centron.BL\Outlook\OutlookAssetKindSearchBL.cs | +| SwRS-073 | CTI-Anruferidentifikation über mehrstufige Rufnummernsuche | StRS-001 | src\backend\Centron.BL\Tapi\PhoneCallBL.cs | +| SwRS-074 | Empfängerlisten je Objekt deckungsgleich halten, Meldungen auto-cleanupen | StRS-014 | src\backend\Centron.BL\Notifications\UserNotificationBL.cs | +| SwRS-075 | Interne Social-Media-Kommentare/Likes über gespeicherte Prozeduren | StRS-001 | src\backend\Centron.BL\SocialMedia\SocialMediaBL.cs | +| SwRS-076 | DocuBoard-Partner als konsistentes Aggregat speichern | StRS-001 | src\backend\Centron.BL\DocuBoard\AssetManagementPartnerBL.cs | +| SwRS-077 | Videozuweisungen rechtsgeprüft mit ToDo-Kopplung | StRS-014, StRS-004 | src\backend\Centron.BL\VideoPortal\VideoPortalAssignmentBL.cs | +| SwRS-078 | Terminanfrage-Antwort gegen Exchange-Kalender verarbeiten | StRS-001 | src\backend\Centron.BL\AppointmentRequests\AppointmentRequestBL.cs | +| SwRS-079 | Wiederkehrende Aufgaben nur mit valider Aktion und Lizenz | StRS-014 | src\backend\Centron.BL\TaskManager\TaskManagementTaskBL.cs | +| SwRS-080 | Kalenderdarstellung und Outlook-Synchronisation konfigurieren | StRS-001 | src\backend\Centron.BL\Calendar\CalendarBL.cs | +| SwRS-081 | Tagesplanungs-Batches mit gemeinsamer Kennung | StRS-001 | src\backend\Centron.BL\MyDay\MyDayBL.cs | +| SwRS-082 | Erwartete Ereignisse je Kunde mit Löschkaskade | StRS-015, StRS-001 | src\backend\Centron.BL\ExpectedEvents\ExpectedEventsBL.cs | +| SwRS-083 | Persönliche Dashboardcontainer je Benutzer | StRS-001 | src\backend\Centron.BL\MyCentron\Dashboard\DashboardContainerBL.cs | +| SwRS-084 | Hintergrunddienste namentlich erfassen und zentral aktivieren | SyRS-022, StRS-001 | src\backend\Centron.BL\Administration\BackgroundServices\BackgroundServiceBL.cs | +| SwRS-085 | SQL-Server-Betriebsdiagnostik für Administratoren | StRS-001 | src\backend\Centron.BL\Administration\SQLManagement\SQLManagementBL.cs | +| SwRS-086 | Automatische, referenzierte Objektverzeichnisse im Dokumentenmanagement | StRS-001, StRS-015 | src\backend\Centron.BL\Administration\FileManagement\DirectoryReferenceProviders\DirectoryReferenceProviderBase.cs | +| SwRS-087 | Theme-Verwaltung mit unantastbarem Standard-Theme | StRS-001 | src\backend\Centron.BL\Administration\Themes\ThemeBL.cs | +| SwRS-088 | Strukturierter Netzwerk-/SQL-Diagnosebericht | StRS-001 | src\backend\Centron.BL\Administration\NetworkDiagnostics\NetworkDiagnosticsBL.cs | +| SwRS-089 | Profilaufzeichnungen aufbewahrungsgesteuert aggregieren | StRS-001 | src\backend\Centron.BL\Administration\Profiling\ProfilerBL.cs | +| SwRS-090 | Telefonie-Einstellungen in drei Ebenen | StRS-001 | src\backend\Centron.BL\Administration\PhoneSettings\PhoneSettingsBL.cs | +| SwRS-091 | Benutzerdefinierte Modul-Eigenschaften ohne Schemaänderung | StRS-001 | src\backend\Centron.BL\Administration\Customization\ModuleCustomPropertyBL.cs | +| SwRS-092 | Custom-Tabellen mit Platzhalterbefüllung aus dem Fachobjekt | StRS-001 | src\backend\Centron.BL\Customizations\CustomTables\CustomTableBL.cs | +| SwRS-093 | ChangeLog-Schreibregeln des ChangeTracking-Listeners | SyRS-033, StRS-015 | src\backend\Centron.DAO\ChangeTracking\ChangeTrackingEventListener.cs | +| SwRS-094 | Wiederverwendbare Massenänderungs-Vorlagen | StRS-001, StRS-015 | src\backend\Centron.BL\MassUpdate\MassUpdateBL.cs | +| SwRS-095 | Prozessmodelle nur mit gültigen Schritttypen, atomar gespeichert | StRS-001 | src\backend\Centron.BL\Processes\ProcessBL.cs | +| SwRS-096 | Fehlende ApplicationSettings on-demand mit Default anlegen | SyRS-029, StRS-001 | src\backend\Centron.BL\Administration\Settings\AppSettingsBL.cs | +| SwRS-097 | Verbindungsdatei mit Fallbackkette und Trust-Optionen | SyRS-032 | src\backend\Centron.BL\Administration\Connections\ConnectionBL.cs | +| SwRS-098 | Registry-Präferenzen und Typ-Isolation WebService/DB | StRS-001 | src\backend\Centron.BL\Administration\Environments\RegistryBL.cs | +| SwRS-099 | Nummernkreis-Fortschreibung mit Intervall und Restzähler | SyRS-044, StRS-016 | src\backend\Centron.BL\Administration\Mandatory\MandatoryBL.cs | +| SwRS-100 | Versionsmeldung je Maschine/Benutzer mit Portal-Upload | SyRS-049, StRS-001 | src\backend\Centron.BL\Administration\Applications\ApplicationVersionBL.cs | +| SwRS-101 | Systemzähler als Einzelinstanz-Lieferant | StRS-001 | src\backend\Centron.BL\SystemArea\SystemTableI3DBL.cs | +| SwRS-102 | PDF-Ausgabestrategie mit PDF/A3-Pflicht-Fallback | StRS-003, StRS-001 | src\backend\Centron.BL\ReportEngine\PdfStategy\PdfStrategies.cs | +| SwRS-103 | Alt-Reportdefinitionen (Legacy "Reports") verwalten | StRS-001 | src\backend\Centron.BL\Reporting\ReportsBL.cs | +| SwRS-104 | Statistiken aus vorberechneten Cache-Tabellen mit Eigenstatistiken | SyRS-042, StRS-001 | src\backend\Centron.BL\Statistics\OrderStatistics\CacheOrderStatisticsBL.cs | +| SwRS-105 | Deutsche Volltextsuche mit Stemming UND-Verknüpfung | StRS-001 | src\backend\Centron.BL\IndexSearch\IndexSearchBL.cs | +| SwRS-106 | Telemetrie-Buckets mit Upload-Kennzeichnung | StRS-001 | src\backend\Centron.BL\Telemetry\TelemetryBL.cs | +| SwRS-107 | Interne Dokumentation nur mit Leseberechtigung | StRS-004 | src\backend\Centron.BL\DocumentationArea\DocumentationBL.cs | +| SwRS-108 | Spezifischster Textbaustein je Benutzer/Kunde ermitteln | StRS-011, StRS-003 | src\backend\Centron.BL\TextModuleArea\TextModuleBL.cs | +| SwRS-109 | Tags beim Verschlagworten reaktivieren | StRS-013 | src\backend\Centron.BL\Tags\TagsBL.cs | +| SwRS-110 | Auditfelder beim Anlegen über Repositories erzwingen | StRS-015 | src\backend\Centron.DAO\Repositories\Accounts\AccountRepository.cs | +| SwRS-111 | Feldlängen über typisierte UserTypes abbilden (Trunkierungsschutz) | StRS-001 | src\backend\Centron.DAO\UserTypes\TruncatedStringUserType.cs | +| SwRS-112 | Zentrale Objekttyp-Nummern als domänenübergreifender Standard | StRS-001 | src\backend\Centron.Entities\Entities\ObjectTypes\ObjectType.cs | +| SwRS-113 | KI-Chats strikt benutzergetrennt mit persistierter Historie | StRS-001 | src\backend\Centron.BL\Administration\ArtificialIntelligence\Chat\ArtificialIntelligenceChatBL.cs | +| SwRS-114 | Checklisten an Objekte mit Pflicht-Caption, atomar gespeichert | StRS-013 | src\backend\Centron.BL\CheckListArea\CentronChecklistBL.cs | +| SwRS-115 | Anbindung an c-pra (Nexoware Smartflow) | SyRS-046 | src\backend\Centron.BL\CPra\CPraConnectorBL.cs | +| SwRS-116 | Externe-Helpdesk-Konfiguration je Kunde/Kundenort | StRS-013 | src\backend\Centron.BL\ExternalHelpdesk\ExternalHelpdeskConfigurationBL.cs | +| SwRS-117 | Externe Tools mit Namenspflicht und Variablenersetzung | StRS-001 | src\backend\Centron.BL\ExternalToolsBL\ExternalToolBL.cs | +| SwRS-118 | Helpdesk-Typen/Kategorien automatisch als virtuelle Checklistenkategorien | StRS-013 | src\backend\Centron.BL\ItPlanner\ChecklistVirtualObjectCategoryBL.cs | +| SwRS-119 | Projektliste mit Erstellungsdatumfilter (rumpfhaft) | StRS-001 | src\backend\Centron.BL\Projects\ProjectBL.cs | +| SwRS-120 | Ticketprojekte mit eigener Nummer und Soft-Delete-Aufgaben | StRS-016, StRS-013 | src\backend\Centron.BL\TicketProjects\TicketProjectBL.cs | +| SwRS-121 | Zeiterfassungs-Stammeinstellungen pflegen | StRS-001 | src\backend\Centron.BL\Time\TimingSettingsBL.cs | +| SwRS-122 | Benutzerbezogene Transaktionen mit Kategorie-Details | StRS-001 | src\backend\Centron.BL\Transactions\TransactionBL.cs | +| SwRS-123 | Aktive Gutschein-Barcodes per NamedQuery | StRS-003 | src\backend\Centron.BL\VoucherManagement\VoucherManagementBL.cs | +| SwRS-124 | URLs als sichtbare, durchsuchbare Objekt-Links | StRS-001 | src\backend\Centron.BL\Urls\SimpleUrlBL.cs | +| SwRS-125 | Objekt↔Fremdsystem-Referenzen typisiert verwalten | StRS-001 | src\backend\Centron.BL\ObjectExternalReferences\ObjectExternalReferenceBL.cs | +| SwRS-126 | Modulstamm automatisch ergänzen, Favoriten je Mitarbeiter | StRS-001 | src\backend\Centron.BL\Modules\ModuleBL.cs | +| SwRS-127 | Ticketabschluss nur mit Recht und erledigter Abschluss-Checkliste | SyRS-043, StRS-013 | src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs | +| SwRS-128 | Single-Instance-Start der Desktop-Anwendung | StRS-001 | src\centron\Centron.WPF.UI\App.xaml.cs | +| SwRS-129 | Anmeldung als Pflicht-Gate vor der Arbeitsfläche | SyRS-002, StRS-004 | src\centron\Centron.WPF.UI\FrontWindow.xaml.cs | +| SwRS-130 | Modul-Layout je Benutzerprofil speichern/zurücksetzen | StRS-001 | src\centron\Centron.WPF.UI\FrontWindow.xaml.cs | +| SwRS-131 | Konfigurierbare Pflichtfelder in der Belegmaske | StRS-011, StRS-003 | src\centron\Centron.WPF.UI\Modules\Finances\Receipts\ReceiptViewModel.cs | +| SwRS-132 | Inline-Feldvalidierung E-Mail/IBAN in der Adressmaske | StRS-005 | src\centron\Centron.WPF.UI\Modules\Finances\Crm\Info\CrmInfoTabView.xaml.cs | +| SwRS-133 | Custom-Gateway-BL für kundenindividuelle openTRANS-Integrationen | SyRS-039, StRS-001 | src\backend\Centron.BL\Gateway\CustomGatewayBL.cs | +| SwRS-134 | Externe ElectronicSales-Gruppen/Rollen lokal spiegeln | StRS-001 | src\backend\Centron.BL\Integrations\EsCustomerGroupBL.cs | + +## Hinweise zur Matrix + +1. Die Verfolgung ist vollständig in Richtung Kind→Elter: jede Anforderung listet ihre Eltern in Tracelinks. In Richtung Elter→Kind werden die wesentlichen direkten Kinder genannt; SwRS, die nur eine StRS als groben Rahmen referenzieren, werden dort nicht repetitiv aufgelistet (Deduplizierung über die Kind→Elter-Spalten). +2. SyRS-010↔SyRS-044 und SyRS-039↔SyRS-011 sind Geschwisterlinks (Querverweise, keine Eltern-Kind-Beziehungen). +3. StRS-012 besitzt keine abgeleitete Anforderung; die Durchsetzung ist vollständig im PRIMÄR-Beleg (UpdateHelpdeskBL) dokumentiert. diff --git a/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/OpenCode.log b/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/OpenCode.log new file mode 100644 index 00000000..e69de29b diff --git a/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/OpenCodeEvents.jsonl b/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/OpenCodeEvents.jsonl new file mode 100644 index 00000000..a7d4b25b --- /dev/null +++ b/Versuche/Versuch_01/Iteration 16/qwen/qwen3.8-flash-next/builtin/high/03_Lauf_2026-09-02_131102_v13.0.0-6a1a/OpenCodeEvents.jsonl @@ -0,0 +1,330 @@ +{"type":"step_start","timestamp":1788347476664,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d0ea8d001EgnDfWyGz2AdVh","messageID":"msg_061d0d013001pVR6t41t72lH8r","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","snapshot":"d3e28a96be089f091c4ae1f9a4622d79a237cf07","type":"step-start"}} +{"type":"text","timestamp":1788347478519,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d0eaff001uBipDpqWuY2J1o","messageID":"msg_061d0d013001pVR6t41t72lH8r","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","type":"text","text":"\n\n\n","time":{"start":1788347476735,"end":1788347478479}}} +{"type":"tool_use","timestamp":1788347480166,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"type":"tool","tool":"bash","callID":"call_80849243bf3342fb950bdcf0","state":{"status":"completed","input":{"command":"Get-ChildItem -Force | Select-Object Mode, Name | Format-Table -AutoSize"},"output":"\r\nMode Name\r\n---- ----\r\nl---- .github\r\nl---- .vscode\r\nl---- assemblies\r\nl---- azure\r\nl---- azure-blazor\r\nl---- Centron.Api.docuFORM\r\nl---- deployment\r\nl---- docker\r\nl---- docs\r\nd---- Ergebnisse\r\nl---- nugets\r\nl---- scripts\r\nl---- src\r\nl---- tests\r\nla--- .dockerignore\r\nla--- .editorconfig\r\nla--- .gitattributes\r\nla--- .gitignore\r\nla--- Centron.sln\r\nla--- Centron.sln.DotSettings\r\nla--- CentronRights.md\r\nla--- DevExpress.Version.props\r\nla--- Directory.Build.props\r\nla--- global.json\r\nla--- nuget.config\r\nla--- package.json\r\nla--- README.md\r\nla--- ResXManager.config.xml\r\nla--- SSMS_DB_SCHEMA.sql\r\nla--- StrongNamingKeyFile.snk\r\nla--- version.json\r\n\r\n","metadata":{"output":"\r\nMode Name\r\n---- ----\r\nl---- .github\r\nl---- .vscode\r\nl---- assemblies\r\nl---- azure\r\nl---- azure-blazor\r\nl---- Centron.Api.docuFORM\r\nl---- deployment\r\nl---- docker\r\nl---- docs\r\nd---- Ergebnisse\r\nl---- nugets\r\nl---- scripts\r\nl---- src\r\nl---- tests\r\nla--- .dockerignore\r\nla--- .editorconfig\r\nla--- .gitattributes\r\nla--- .gitignore\r\nla--- Centron.sln\r\nla--- Centron.sln.DotSettings\r\nla--- CentronRights.md\r\nla--- DevExpress.Version.props\r\nla--- Directory.Build.props\r\nla--- global.json\r\nla--- nuget.config\r\nla--- package.json\r\nla--- README.md\r\nla--- ResXManager.config.xml\r\nla--- SSMS_DB_SCHEMA.sql\r\nla--- StrongNamingKeyFile.snk\r\nla--- version.json\r\n\r\n","exit":0,"truncated":false},"title":"Get-ChildItem -Force | Select-Object Mode, Name | Format-Table -AutoSize","time":{"start":1788347480018,"end":1788347480145}},"id":"prt_061d0eb05001a7NEewnk9ZY4Jh","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","messageID":"msg_061d0d013001pVR6t41t72lH8r"}} +{"type":"tool_use","timestamp":1788347480325,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"type":"tool","tool":"bash","callID":"call_d30bd8400f064accb8b10dac","state":{"status":"completed","input":{"command":"Get-Location; Get-ChildItem .. -Force | Select-Object Name | Format-Table -AutoSize"},"output":"\r\nPath\r\n----\r\nC:\\DEV\\MasterArbeit\\Versuche\\Versuch_01\\Iteration 16\\qwen\\qwen3.8-flash-next\\builtin\\high\\03_Lauf_2026-09-02_131102_v1.\r\n\r\n\r\nName\r\n----\r\nspiegel\r\nbefore.txt\r\ncombined_prompt.md\r\nopencode-config.json\r\nstartzeit.txt\r\n\r\n","metadata":{"output":"\r\nPath\r\n----\r\nC:\\DEV\\MasterArbeit\\Versuche\\Versuch_01\\Iteration 16\\qwen\\qwen3.8-flash-next\\builtin\\high\\03_Lauf_2026-09-02_131102_v1.\r\n\r\n\r\nName\r\n----\r\nspiegel\r\nbefore.txt\r\ncombined_prompt.md\r\nopencode-config.json\r\nstartzeit.txt\r\n\r\n","exit":0,"truncated":false},"title":"Get-Location; Get-ChildItem .. -Force | Select-Object Name | Format-Table -AutoSize","time":{"start":1788347480193,"end":1788347480293}},"id":"prt_061d0f0fe001LKge4jMhb6lzAh","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","messageID":"msg_061d0d013001pVR6t41t72lH8r"}} +{"type":"step_finish","timestamp":1788347481047,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d0fbb1001nmNRHQNN7n2E7v","reason":"tool-calls","snapshot":"d3e28a96be089f091c4ae1f9a4622d79a237cf07","messageID":"msg_061d0d013001pVR6t41t72lH8r","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","type":"step-finish","tokens":{"total":10805,"input":10632,"output":92,"reasoning":17,"cache":{"write":0,"read":64}},"cost":0}} +{"type":"step_start","timestamp":1788347483672,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d1060b0014Bdu8BjTK78Rb1","messageID":"msg_061d0fd44001Juz418FHsCn3Ck","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","snapshot":"d3e28a96be089f091c4ae1f9a4622d79a237cf07","type":"step-start"}} +{"type":"text","timestamp":1788347484698,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d106f6001cayiNqiZ905HIZ","messageID":"msg_061d0fd44001Juz418FHsCn3Ck","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","type":"text","text":"\n\n\n","time":{"start":1788347483894,"end":1788347484627}}} +{"type":"tool_use","timestamp":1788347485331,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"type":"tool","tool":"bash","callID":"call_26036f2b0f494707a8ae1e3a","state":{"status":"completed","input":{"command":"Get-ChildItem Ergebnisse -Force -ErrorAction SilentlyContinue; echo \"---README---\"; Get-Content README.md -TotalCount 60"},"output":"---README---\r\n# c-entron Nexus (aka c-entron Web)\r\n\r\n# Rules\r\n\r\n## 1. Referencing javascript/css dependencies\r\nWhen referencing any javascript or css dependency, we allow 2 ways of referencing them: \r\n1. Use LibMan to download the files into the repository.\r\n2. Reference the files from a CDN like jsdelivr.net, but then we must include a integrity hash in that reference.\r\n\r\n### Referencing javascript/css using LibMan\r\nSee here for how to use LibMan: https://learn.microsoft.com/en-US/aspnet/core/client-side/libman/libman-vs?view=aspnetcore-6.0\r\n\r\n### Reference from CDN with integrity hash\r\nYou can use https://www.srihash.org/ to create the integrity hash for a file.\r\n\r\n## 2. Which components to use\r\nIn general we prefer to use the DevExpress blazor components instead of plain bootstrap components. \r\nDevExpress uses the bootstrap styling, so the components do look similar.\r\n\r\n## 3. Custom CSS\r\nDon't use your own colors and border-radius and so on in custom CSS. \r\nUse whatever variables from bootstrap are available. \r\nThis means, that we can change the bootstrap theme in the future and even our custom CSS will adjust.\r\n\r\n## 4. HTML layouting\r\nFor layouting HTML stuff our preference is as follows: \r\n`CSS Grid` or `Flexbox` **>** `Bootstrap Grid` **>** DevExpress layout components (like `DxGridLayout` and `DxStackLayout`)\r\n\r\n# Contributing\r\n\r\n## 1. WebCart\r\n\r\n* The webcart is a a feature primarily intended for the customers of our customers\r\n* That means it's available if you login as a web-account (create one in c-entron.NET Adressstamm)\r\n* The available articles come from the customers \"Sonderpreise\", so create some of them in the c-entron.NET Adressstamm too\r\n* The web-account should now be able to login at c-entron Nexus, click on \"Shop\" and see the articles\r\n","metadata":{"output":"---README---\r\n# c-entron Nexus (aka c-entron Web)\r\n\r\n# Rules\r\n\r\n## 1. Referencing javascript/css dependencies\r\nWhen referencing any javascript or css dependency, we allow 2 ways of referencing them: \r\n1. Use LibMan to download the files into the repository.\r\n2. Reference the files from a CDN like jsdelivr.net, but then we must include a integrity hash in that reference.\r\n\r\n### Referencing javascript/css using LibMan\r\nSee here for how to use LibMan: https://learn.microsoft.com/en-US/aspnet/core/client-side/libman/libman-vs?view=aspnetcore-6.0\r\n\r\n### Reference from CDN with integrity hash\r\nYou can use https://www.srihash.org/ to create the integrity hash for a file.\r\n\r\n## 2. Which components to use\r\nIn general we prefer to use the DevExpress blazor components instead of plain bootstrap components. \r\nDevExpress uses the bootstrap styling, so the components do look similar.\r\n\r\n## 3. Custom CSS\r\nDon't use your own colors and border-radius and so on in custom CSS. \r\nUse whatever variables from bootstrap are available. \r\nThis means, that we can change the bootstrap theme in the future and even our custom CSS will adjust.\r\n\r\n## 4. HTML layouting\r\nFor layouting HTML stuff our preference is as follows: \r\n`CSS Grid` or `Flexbox` **>** `Bootstrap Grid` **>** DevExpress layout components (like `DxGridLayout` and `DxStackLayout`)\r\n\r\n# Contributing\r\n\r\n## 1. WebCart\r\n\r\n* The webcart is a a feature primarily intended for the customers of our customers\r\n* That means it's available if you login as a web-account (create one in c-entron.NET Adressstamm)\r\n* The available articles come from the customers \"Sonderpreise\", so create some of them in the c-entron.NET Adressstamm too\r\n* The web-account should now be able to login at c-entron Nexus, click on \"Shop\" and see the articles\r\n","exit":0,"truncated":false},"title":"Get-ChildItem Ergebnisse -Force -ErrorAction SilentlyContinue; echo \"---README---\"; Get-Content README.md -TotalCount 60","time":{"start":1788347485239,"end":1788347485320}},"id":"prt_061d108ec001cc633aBRh20oX2","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","messageID":"msg_061d0fd44001Juz418FHsCn3Ck"}} +{"type":"tool_use","timestamp":1788347488875,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"type":"tool","tool":"bash","callID":"call_aa3d6ec687284ab98c47cd98","state":{"status":"completed","input":{"command":"Get-ChildItem src -Force | Select-Object Name | Format-Table -AutoSize; echo \"---\"; (Get-ChildItem src -Recurse -File | Measure-Object).Count"},"output":"\r\nName\r\n----\r\napis\r\nbackend\r\ncentron\r\nnexus\r\nshared\r\nwebservice\r\n\r\n---\r\n22341\r\n","metadata":{"output":"\r\nName\r\n----\r\napis\r\nbackend\r\ncentron\r\nnexus\r\nshared\r\nwebservice\r\n\r\n---\r\n22341\r\n","exit":0,"truncated":false},"title":"Get-ChildItem src -Force | Select-Object Name | Format-Table -AutoSize; echo \"---\"; (Get-ChildItem src -Recurse -File | Measure-Object).Count","time":{"start":1788347488612,"end":1788347488867}},"id":"prt_061d1075e00177NLILFHVmjkn1","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","messageID":"msg_061d0fd44001Juz418FHsCn3Ck"}} +{"type":"step_finish","timestamp":1788347489958,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d11e7b001zANO6Le0d3Vrnz","reason":"tool-calls","snapshot":"d3e28a96be089f091c4ae1f9a4622d79a237cf07","messageID":"msg_061d0fd44001Juz418FHsCn3Ck","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","type":"step-finish","tokens":{"total":11265,"input":345,"output":121,"reasoning":47,"cache":{"write":0,"read":10752}},"cost":0}} +{"type":"step_start","timestamp":1788347494019,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d12e5400117aq9pRzM1HsVD","messageID":"msg_061d121c1001JQ2QVwYoW3Cjox","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","snapshot":"d3e28a96be089f091c4ae1f9a4622d79a237cf07","type":"step-start"}} +{"type":"text","timestamp":1788347494666,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d12f6b001tu317KkKLGxK0J","messageID":"msg_061d121c1001JQ2QVwYoW3Cjox","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","type":"text","text":"\n\n","time":{"start":1788347494251,"end":1788347494477}}} +{"type":"tool_use","timestamp":1788347496302,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"type":"tool","tool":"bash","callID":"call_789f653c357049a0a9ab2dff","state":{"status":"completed","input":{"command":"foreach ($d in @(\"src\\apis\",\"src\\backend\",\"src\\centron\",\"src\\nexus\",\"src\\shared\",\"src\\webservice\")) { echo \"=== $d ===\"; Get-ChildItem $d -Force | Select-Object -ExpandProperty Name }"},"output":"=== src\\apis ===\r\nCentron.Api.EbInterface\r\nCentron.Api.Gls\r\nCentron.Api.Shipcloud\r\nCentron.APIs.CopDataAccess\r\nCentron.APIs.EgisDataAccess\r\nCentron.APIs.FinAPI\r\nCentron.APIs.IcecatDataAccess\r\nCentron.APIs.ITscopeDataAccess\r\n=== src\\backend ===\r\nCentron.BL\r\nCentron.Common\r\nCentron.DAO\r\nCentron.Entities\r\nCentron.Gateway\r\nCentron.Interfaces\r\n=== src\\centron ===\r\nCentron.WPF.UI\r\nCentron.WPF.UI.Extension\r\n=== src\\nexus ===\r\nCentronNexus\r\nCentronNexus.Host\r\nCentronNexus.OutlookAddIn\r\nDirectory.Build.props\r\n=== src\\shared ===\r\nCentron.Controls\r\nCentron.Controls.Preview\r\nCentron.Core\r\n=== src\\webservice ===\r\nc-entron.misc.ConnectionManager\r\nCentron.Controllers\r\nCentron.Host\r\nCentron.Host.Console\r\nCentron.Host.WindowsService\r\nCentron.WebServices.Core\r\n","metadata":{"output":"=== src\\apis ===\r\nCentron.Api.EbInterface\r\nCentron.Api.Gls\r\nCentron.Api.Shipcloud\r\nCentron.APIs.CopDataAccess\r\nCentron.APIs.EgisDataAccess\r\nCentron.APIs.FinAPI\r\nCentron.APIs.IcecatDataAccess\r\nCentron.APIs.ITscopeDataAccess\r\n=== src\\backend ===\r\nCentron.BL\r\nCentron.Common\r\nCentron.DAO\r\nCentron.Entities\r\nCentron.Gateway\r\nCentron.Interfaces\r\n=== src\\centron ===\r\nCentron.WPF.UI\r\nCentron.WPF.UI.Extension\r\n=== src\\nexus ===\r\nCentronNexus\r\nCentronNexus.Host\r\nCentronNexus.OutlookAddIn\r\nDirectory.Build.props\r\n=== src\\shared ===\r\nCentron.Controls\r\nCentron.Controls.Preview\r\nCentron.Core\r\n=== src\\webservice ===\r\nc-entron.misc.ConnectionManager\r\nCentron.Controllers\r\nCentron.Host\r\nCentron.Host.Console\r\nCentron.Host.WindowsService\r\nCentron.WebServices.Core\r\n","exit":0,"truncated":false},"title":"foreach ($d in @(\"src\\apis\",\"src\\backend\",\"src\\centron\",\"src\\nexus\",\"src\\shared\",\"src\\webservice\")) { echo \"=== $d ===\"; Get-ChildItem $d -Force | Select-Object -ExpandProperty Name }","time":{"start":1788347496041,"end":1788347496283}},"id":"prt_061d12f71001UhsEzGNhnDQgXr","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","messageID":"msg_061d121c1001JQ2QVwYoW3Cjox"}} +{"type":"step_finish","timestamp":1788347497249,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d13af8001dmbO6cFN4Ip9Ko","reason":"tool-calls","snapshot":"d3e28a96be089f091c4ae1f9a4622d79a237cf07","messageID":"msg_061d121c1001JQ2QVwYoW3Cjox","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","type":"step-finish","tokens":{"total":11872,"input":477,"output":83,"reasoning":48,"cache":{"write":0,"read":11264}},"cost":0}} +{"type":"step_start","timestamp":1788347499904,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d14570001yer4u05GGQmoWH","messageID":"msg_061d13e12001aco6H0FOYYiSPB","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","snapshot":"d3e28a96be089f091c4ae1f9a4622d79a237cf07","type":"step-start"}} +{"type":"text","timestamp":1788347500543,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d14690001HOnCfo4PxcfSWE","messageID":"msg_061d13e12001aco6H0FOYYiSPB","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","type":"text","text":"\n\n","time":{"start":1788347500176,"end":1788347500466}}} +{"type":"tool_use","timestamp":1788347502355,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"type":"tool","tool":"bash","callID":"call_5d38cee165bd4270b3248cb3","state":{"status":"completed","input":{"command":"Get-ChildItem src -Recurse -Filter *.csproj | ForEach-Object { $_.FullName.Replace(\"$PWD\\\",\"\") }"},"output":"src\\apis\\Centron.Api.EbInterface\\Centron.Api.EbInterface.csproj\r\nsrc\\apis\\Centron.Api.Gls\\Centron.Api.Gls.csproj\r\nsrc\\apis\\Centron.Api.Shipcloud\\Centron.Api.Shipcloud.csproj\r\nsrc\\apis\\Centron.APIs.CopDataAccess\\Centron.APIs.CopDataAccess.csproj\r\nsrc\\apis\\Centron.APIs.EgisDataAccess\\Centron.APIs.EgisDataAccess.csproj\r\nsrc\\apis\\Centron.APIs.FinAPI\\Centron.APIs.FinAPI.csproj\r\nsrc\\apis\\Centron.APIs.IcecatDataAccess\\Centron.APIs.IcecatDataAccess.csproj\r\nsrc\\apis\\Centron.APIs.ITscopeDataAccess\\Centron.APIs.ITscopeDataAccess.csproj\r\nsrc\\backend\\Centron.BL\\Centron.BL.csproj\r\nsrc\\backend\\Centron.Common\\Centron.Common.csproj\r\nsrc\\backend\\Centron.DAO\\Centron.DAO.csproj\r\nsrc\\backend\\Centron.Entities\\Centron.Entities.csproj\r\nsrc\\backend\\Centron.Gateway\\Centron.Gateway.csproj\r\nsrc\\backend\\Centron.Interfaces\\Centron.Interfaces.csproj\r\nsrc\\centron\\Centron.WPF.UI\\Centron.WPF.UI.csproj\r\nsrc\\centron\\Centron.WPF.UI.Extension\\Centron.WPF.UI.Extension.csproj\r\nsrc\\nexus\\CentronNexus\\CentronNexus.csproj\r\nsrc\\nexus\\CentronNexus.Host\\CentronNexus.Host.csproj\r\nsrc\\nexus\\CentronNexus.OutlookAddIn\\CentronNexus.OutlookAddIn.csproj\r\nsrc\\shared\\Centron.Controls\\Centron.Controls.csproj\r\nsrc\\shared\\Centron.Controls.Preview\\Centron.Controls.Preview.csproj\r\nsrc\\shared\\Centron.Core\\Centron.Core.csproj\r\nsrc\\webservice\\c-entron.misc.ConnectionManager\\c-entron.misc.ConnectionManager.csproj\r\nsrc\\webservice\\Centron.Controllers\\Centron.Controllers.csproj\r\nsrc\\webservice\\Centron.Host\\Centron.Host.csproj\r\nsrc\\webservice\\Centron.Host.Console\\Centron.Host.Console.csproj\r\nsrc\\webservice\\Centron.Host.WindowsService\\Centron.Host.WindowsService.csproj\r\nsrc\\webservice\\Centron.WebServices.Core\\Centron.WebServices.Core.csproj\r\n","metadata":{"output":"src\\apis\\Centron.Api.EbInterface\\Centron.Api.EbInterface.csproj\r\nsrc\\apis\\Centron.Api.Gls\\Centron.Api.Gls.csproj\r\nsrc\\apis\\Centron.Api.Shipcloud\\Centron.Api.Shipcloud.csproj\r\nsrc\\apis\\Centron.APIs.CopDataAccess\\Centron.APIs.CopDataAccess.csproj\r\nsrc\\apis\\Centron.APIs.EgisDataAccess\\Centron.APIs.EgisDataAccess.csproj\r\nsrc\\apis\\Centron.APIs.FinAPI\\Centron.APIs.FinAPI.csproj\r\nsrc\\apis\\Centron.APIs.IcecatDataAccess\\Centron.APIs.IcecatDataAccess.csproj\r\nsrc\\apis\\Centron.APIs.ITscopeDataAccess\\Centron.APIs.ITscopeDataAccess.csproj\r\nsrc\\backend\\Centron.BL\\Centron.BL.csproj\r\nsrc\\backend\\Centron.Common\\Centron.Common.csproj\r\nsrc\\backend\\Centron.DAO\\Centron.DAO.csproj\r\nsrc\\backend\\Centron.Entities\\Centron.Entities.csproj\r\nsrc\\backend\\Centron.Gateway\\Centron.Gateway.csproj\r\nsrc\\backend\\Centron.Interfaces\\Centron.Interfaces.csproj\r\nsrc\\centron\\Centron.WPF.UI\\Centron.WPF.UI.csproj\r\nsrc\\centron\\Centron.WPF.UI.Extension\\Centron.WPF.UI.Extension.csproj\r\nsrc\\nexus\\CentronNexus\\CentronNexus.csproj\r\nsrc\\nexus\\CentronNexus.Host\\CentronNexus.Host.csproj\r\nsrc\\nexus\\CentronNexus.OutlookAddIn\\CentronNexus.OutlookAddIn.csproj\r\nsrc\\shared\\Centron.Controls\\Centron.Controls.csproj\r\nsrc\\shared\\Centron.Controls.Preview\\Centron.Controls.Preview.csproj\r\nsrc\\shared\\Centron.Core\\Centron.Core.csproj\r\nsrc\\webservice\\c-entron.misc.ConnectionManager\\c-entron.misc.ConnectionManager.csproj\r\nsrc\\webservice\\Centron.Controllers\\Centron.Controllers.csproj\r\nsrc\\webservice\\Centron.Host\\Centron.Host.csproj\r\nsrc\\webservice\\Centron.Host.Console\\Centron.Host.Console.csproj\r\nsrc\\webservice\\Centron.Host.WindowsService\\Centron.Host.WindowsService.csproj\r\nsrc\\webservice\\Centron.WebServices.Core\\Centron.WebServices.Core.csproj\r\n","exit":0,"truncated":false},"title":"Get-ChildItem src -Recurse -Filter *.csproj | ForEach-Object { $_.FullName.Replace(\"$PWD\\\",\"\") }","time":{"start":1788347502192,"end":1788347502334}},"id":"prt_061d146f3001u8b5FaYDD8nZ0t","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","messageID":"msg_061d13e12001aco6H0FOYYiSPB"}} +{"type":"step_finish","timestamp":1788347502907,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d1511d001woDItCazEs4ZZQ","reason":"tool-calls","snapshot":"d3e28a96be089f091c4ae1f9a4622d79a237cf07","messageID":"msg_061d13e12001aco6H0FOYYiSPB","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","type":"step-finish","tokens":{"total":12202,"input":321,"output":56,"reasoning":49,"cache":{"write":0,"read":11776}},"cost":0}} +{"type":"step_start","timestamp":1788347505019,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d159740011TUC40OVSzQQMW","messageID":"msg_061d153030018sAcDUvFRYMP27","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","snapshot":"d3e28a96be089f091c4ae1f9a4622d79a237cf07","type":"step-start"}} +{"type":"text","timestamp":1788347505825,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d15a46001BbYRXy7Hxkym6L","messageID":"msg_061d153030018sAcDUvFRYMP27","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","type":"text","text":"\n\n\n","time":{"start":1788347505222,"end":1788347505750}}} +{"type":"tool_use","timestamp":1788347505984,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"type":"tool","tool":"bash","callID":"call_4e48c550f895453a9f71d700","state":{"status":"completed","input":{"command":"Get-ChildItem src\\backend\\Centron.BL -Directory | Select-Object -ExpandProperty Name"},"output":"Accounting\r\nAccounts\r\nAdministration\r\nAppointmentRequests\r\nArtificialIntelligence\r\nbin\r\nBusinessPartner\r\nBuying\r\nCalendar\r\nCentronIcons\r\nCentronNexus\r\nChangeTracking\r\nChats\r\nCheckListArea\r\nCore\r\nCountryArea\r\nCPra\r\nCustomerArea\r\nCustomizations\r\nDataExchange\r\nDevices\r\nDocuBoard\r\nDocumentationArea\r\nEDI\r\nEmployeeArea\r\nExceptions\r\nExpectedEvents\r\nExternalHelpdesk\r\nExternalToolsBL\r\nFinances\r\nGateway\r\nGUI\r\nHelpers\r\nIndexSearch\r\nIntegrations\r\nItPlanner\r\nLogistics\r\nMail\r\nMailings\r\nMailScanner\r\nMassUpdate\r\nMobile\r\nModules\r\nMyCentron\r\nMyDay\r\nNexusNotifications\r\nNexusTicketViews\r\nNotifications\r\nobj\r\nObjectExternalReferences\r\nOutlook\r\nPasswordManagementArea\r\nPasswordManager\r\nProcesses\r\nProduction\r\nProductMatrix\r\nProjects\r\nProperties\r\nPurchasing\r\nReportEngine\r\nReporting\r\nResources\r\nRiverDivo\r\nSales\r\nSecurity\r\nSelfCare\r\nServices\r\nSocialMedia\r\nStart\r\nStatistics\r\nStorage\r\nSystemArea\r\nTags\r\nTapi\r\nTaskManager\r\nTelemetry\r\nTextModuleArea\r\nTicketProjects\r\nTime\r\nToDoArea\r\nTools\r\nTradePool\r\nTransactions\r\nTwoFactorAuthenticator\r\nUrls\r\nVideoPortal\r\nVoucherManagement\r\nWarehousing\r\nWebLinks\r\nWebServices\r\nWebSuite\r\nWebVersion\r\n","metadata":{"output":"Accounting\r\nAccounts\r\nAdministration\r\nAppointmentRequests\r\nArtificialIntelligence\r\nbin\r\nBusinessPartner\r\nBuying\r\nCalendar\r\nCentronIcons\r\nCentronNexus\r\nChangeTracking\r\nChats\r\nCheckListArea\r\nCore\r\nCountryArea\r\nCPra\r\nCustomerArea\r\nCustomizations\r\nDataExchange\r\nDevices\r\nDocuBoard\r\nDocumentationArea\r\nEDI\r\nEmployeeArea\r\nExceptions\r\nExpectedEvents\r\nExternalHelpdesk\r\nExternalToolsBL\r\nFinances\r\nGateway\r\nGUI\r\nHelpers\r\nIndexSearch\r\nIntegrations\r\nItPlanner\r\nLogistics\r\nMail\r\nMailings\r\nMailScanner\r\nMassUpdate\r\nMobile\r\nModules\r\nMyCentron\r\nMyDay\r\nNexusNotifications\r\nNexusTicketViews\r\nNotifications\r\nobj\r\nObjectExternalReferences\r\nOutlook\r\nPasswordManagementArea\r\nPasswordManager\r\nProcesses\r\nProduction\r\nProductMatrix\r\nProjects\r\nProperties\r\nPurchasing\r\nReportEngine\r\nReporting\r\nResources\r\nRiverDivo\r\nSales\r\nSecurity\r\nSelfCare\r\nServices\r\nSocialMedia\r\nStart\r\nStatistics\r\nStorage\r\nSystemArea\r\nTags\r\nTapi\r\nTaskManager\r\nTelemetry\r\nTextModuleArea\r\nTicketProjects\r\nTime\r\nToDoArea\r\nTools\r\nTradePool\r\nTransactions\r\nTwoFactorAuthenticator\r\nUrls\r\nVideoPortal\r\nVoucherManagement\r\nWarehousing\r\nWebLinks\r\nWebServices\r\nWebSuite\r\nWebVersion\r\n","exit":0,"truncated":false},"title":"Get-ChildItem src\\backend\\Centron.BL -Directory | Select-Object -ExpandProperty Name","time":{"start":1788347505900,"end":1788347505967}},"id":"prt_061d15a7d001mhxbv3u6CBACwc","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","messageID":"msg_061d153030018sAcDUvFRYMP27"}} +{"type":"tool_use","timestamp":1788347506243,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"type":"tool","tool":"bash","callID":"call_7c4f8ec9c6c04fdca727505a","state":{"status":"completed","input":{"command":"Get-ChildItem src\\backend\\Centron.DAO -Directory | Select-Object -ExpandProperty Name; echo \"=== Entities ===\"; Get-ChildItem src\\backend\\Centron.Entities -Directory | Select-Object -ExpandProperty Name"},"output":"AdoNETDataAccess\r\nbin\r\nChangeTracking\r\nClasses\r\nCustomDAOs\r\nDAOConnections\r\nHoliday\r\nMappings\r\nMobile\r\nNamedQueries\r\nNHibernateConfiguration\r\nNHibernateLogging\r\nobj\r\nProperties\r\nReporting\r\nRepositories\r\nStatistics\r\nTesting\r\nTextModuleArea\r\nTradePool\r\nUserTypes\r\n=== Entities ===\r\nbin\r\nEntities\r\nobj\r\nProperties\r\nWebServices\r\n","metadata":{"output":"AdoNETDataAccess\r\nbin\r\nChangeTracking\r\nClasses\r\nCustomDAOs\r\nDAOConnections\r\nHoliday\r\nMappings\r\nMobile\r\nNamedQueries\r\nNHibernateConfiguration\r\nNHibernateLogging\r\nobj\r\nProperties\r\nReporting\r\nRepositories\r\nStatistics\r\nTesting\r\nTextModuleArea\r\nTradePool\r\nUserTypes\r\n=== Entities ===\r\nbin\r\nEntities\r\nobj\r\nProperties\r\nWebServices\r\n","exit":0,"truncated":false},"title":"Get-ChildItem src\\backend\\Centron.DAO -Directory | Select-Object -ExpandProperty Name; echo \"=== Entities ===\"; Get-ChildItem src\\backend\\Centron.Entities -Directory | Select-Object -ExpandProperty Name","time":{"start":1788347506166,"end":1788347506228}},"id":"prt_061d15b34001EEU49Y23A88v2R","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","messageID":"msg_061d153030018sAcDUvFRYMP27"}} +{"type":"step_finish","timestamp":1788347506668,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d15fe7001x8Fc9jWnJ3eBBI","reason":"tool-calls","snapshot":"d3e28a96be089f091c4ae1f9a4622d79a237cf07","messageID":"msg_061d153030018sAcDUvFRYMP27","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","type":"step-finish","tokens":{"total":12896,"input":634,"output":121,"reasoning":45,"cache":{"write":0,"read":12096}},"cost":0}} +{"type":"step_start","timestamp":1788347508767,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d16818001gTozzJvkvTmk6E","messageID":"msg_061d1614d001woKiKO99eufVgk","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","snapshot":"d3e28a96be089f091c4ae1f9a4622d79a237cf07","type":"step-start"}} +{"type":"text","timestamp":1788347526725,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d1a442001PDr4GaeHR55djh","messageID":"msg_061d1614d001woKiKO99eufVgk","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","type":"text","text":"\n\n\n","time":{"start":1788347524163,"end":1788347526644}}} +{"type":"tool_use","timestamp":1788347527806,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"type":"tool","tool":"bash","callID":"call_3d758659e6ff433485b79008","state":{"status":"completed","input":{"command":"$dirs = Get-ChildItem src\\backend\\Centron.BL -Directory | Where-Object { $_.Name -notin @('bin','obj','Properties','Resources','CentronIcons') }\nforeach ($d in $dirs) { $n = (Get-ChildItem $d.FullName -Recurse -File -Include *.cs,*.xaml -ErrorAction SilentlyContinue | Where-Object { $_.FullName -notmatch '\\\\(bin|obj)\\\\' } | Measure-Object).Count; \"{0}`t{1}\" -f $d.Name, $n }"},"output":"Accounting\t1\r\nAccounts\t29\r\nAdministration\t959\r\nAppointmentRequests\t1\r\nArtificialIntelligence\t25\r\nBusinessPartner\t2\r\nBuying\t1\r\nCalendar\t1\r\nCentronNexus\t1\r\nChangeTracking\t1\r\nChats\t1\r\nCheckListArea\t3\r\nCore\t2\r\nCountryArea\t2\r\nCPra\t2\r\nCustomerArea\t7\r\nCustomizations\t1\r\nDataExchange\t23\r\nDevices\t1\r\nDocuBoard\t3\r\nDocumentationArea\t1\r\nEDI\t27\r\nEmployeeArea\t9\r\nExceptions\t1\r\nExpectedEvents\t1\r\nExternalHelpdesk\t1\r\nExternalToolsBL\t1\r\nFinances\t9\r\nGateway\t1\r\nGUI\t6\r\nHelpers\t6\r\nIndexSearch\t7\r\nIntegrations\t2\r\nItPlanner\t1\r\nLogistics\t2\r\nMail\t20\r\nMailings\t2\r\nMailScanner\t1\r\nMassUpdate\t1\r\nMobile\t1\r\nModules\t3\r\nMyCentron\t4\r\nMyDay\t7\r\nNexusNotifications\t2\r\nNexusTicketViews\t1\r\nNotifications\t2\r\nObjectExternalReferences\t1\r\nOutlook\t1\r\nPasswordManagementArea\t6\r\nPasswordManager\t1\r\nProcesses\t1\r\nProduction\t2\r\nProductMatrix\t1\r\nProjects\t1\r\nPurchasing\t4\r\nReportEngine\t26\r\nReporting\t1\r\nRiverDivo\t4\r\nSales\t248\r\nSecurity\t1\r\nSelfCare\t2\r\nServices\t11\r\nSocialMedia\t3\r\nStart\t1\r\nStatistics\t16\r\nStorage\t2\r\nSystemArea\t1\r\nTags\t1\r\nTapi\t1\r\nTaskManager\t4\r\nTelemetry\t1\r\nTextModuleArea\t2\r\nTicketProjects\t1\r\nTime\t1\r\nToDoArea\t2\r\nTools\t1\r\nTradePool\t2\r\nTransactions\t1\r\nTwoFactorAuthenticator\t1\r\nUrls\t2\r\nVideoPortal\t1\r\nVoucherManagement\t1\r\nWarehousing\t40\r\nWebLinks\t4\r\nWebServices\t464\r\nWebSuite\t5\r\nWebVersion\t1\r\n","metadata":{"output":"Accounting\t1\r\nAccounts\t29\r\nAdministration\t959\r\nAppointmentRequests\t1\r\nArtificialIntelligence\t25\r\nBusinessPartner\t2\r\nBuying\t1\r\nCalendar\t1\r\nCentronNexus\t1\r\nChangeTracking\t1\r\nChats\t1\r\nCheckListArea\t3\r\nCore\t2\r\nCountryArea\t2\r\nCPra\t2\r\nCustomerArea\t7\r\nCustomizations\t1\r\nDataExchange\t23\r\nDevices\t1\r\nDocuBoard\t3\r\nDocumentationArea\t1\r\nEDI\t27\r\nEmployeeArea\t9\r\nExceptions\t1\r\nExpectedEvents\t1\r\nExternalHelpdesk\t1\r\nExternalToolsBL\t1\r\nFinances\t9\r\nGateway\t1\r\nGUI\t6\r\nHelpers\t6\r\nIndexSearch\t7\r\nIntegrations\t2\r\nItPlanner\t1\r\nLogistics\t2\r\nMail\t20\r\nMailings\t2\r\nMailScanner\t1\r\nMassUpdate\t1\r\nMobile\t1\r\nModules\t3\r\nMyCentron\t4\r\nMyDay\t7\r\nNexusNotifications\t2\r\nNexusTicketViews\t1\r\nNotifications\t2\r\nObjectExternalReferences\t1\r\nOutlook\t1\r\nPasswordManagementArea\t6\r\nPasswordManager\t1\r\nProcesses\t1\r\nProduction\t2\r\nProductMatrix\t1\r\nProjects\t1\r\nPurchasing\t4\r\nReportEngine\t26\r\nReporting\t1\r\nRiverDivo\t4\r\nSales\t248\r\nSecurity\t1\r\nSelfCare\t2\r\nServices\t11\r\nSocialMedia\t3\r\nStart\t1\r\nStatistics\t16\r\nStorage\t2\r\nSystemArea\t1\r\nTags\t1\r\nTapi\t1\r\nTaskManager\t4\r\nTelemetry\t1\r\nTextModuleArea\t2\r\nTicketProjects\t1\r\nTime\t1\r\nToDoArea\t2\r\nTools\t1\r\nTradePool\t2\r\nTransactions\t1\r\nTwoFactorAuthenticator\t1\r\nUrls\t2\r\nVideoPortal\t1\r\nVoucherManagement\t1\r\nWarehousing\t40\r\nWebLinks\t4\r\nWebServices\t464\r\nWebSuite\t5\r\nWebVersion\t1\r\n","exit":0,"truncated":false},"title":"$dirs = Get-ChildItem src\\backend\\Centron.BL -Directory | Where-Object { $_.Name -notin @('bin','obj','Properties','Resources','CentronIcons') }\nforeach ($d in $dirs) { $n = (Get-ChildItem $d.FullName -Recurse -File -Include *.cs,*.xaml -ErrorAction SilentlyContinue | Where-Object { $_.FullName -notmatch '\\\\(bin|obj)\\\\' } | Measure-Object).Count; \"{0}`t{1}\" -f $d.Name, $n }","time":{"start":1788347527704,"end":1788347527791}},"id":"prt_061d1a49f001HZtFfejNU3GgA7","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","messageID":"msg_061d1614d001woKiKO99eufVgk"}} +{"type":"tool_use","timestamp":1788347528849,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"type":"tool","tool":"bash","callID":"call_95d4aa208a46490e8168c3b3","state":{"status":"completed","input":{"command":"echo \"=== Nexus ===\"; Get-ChildItem src\\nexus\\CentronNexus -Directory | Select-Object -ExpandProperty Name; echo \"=== Controllers ===\"; Get-ChildItem src\\webservice\\Centron.Controllers -Directory -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name; echo \"=== nexus files ===\"; (Get-ChildItem src\\nexus\\CentronNexus -Recurse -File -Include *.razor,*.cs | Where-Object {$_.FullName -notmatch '\\\\(bin|obj)\\\\'}).Count"},"output":"=== Nexus ===\r\nbin\r\nConfiguration\r\nControllers\r\nDocumentSigning\r\nManagement\r\nobj\r\nOffice\r\nProductionOrderManagement\r\nServiceBoard\r\nSettings\r\nShared\r\nUtils\r\nWebCart\r\nWebOffer\r\n=== Controllers ===\r\nAuthorization\r\nbin\r\nCommon\r\nConfiguration\r\nControllers\r\nHttpRequests\r\nobj\r\nUtils\r\n=== nexus files ===\r\n756\r\n","metadata":{"output":"=== Nexus ===\r\nbin\r\nConfiguration\r\nControllers\r\nDocumentSigning\r\nManagement\r\nobj\r\nOffice\r\nProductionOrderManagement\r\nServiceBoard\r\nSettings\r\nShared\r\nUtils\r\nWebCart\r\nWebOffer\r\n=== Controllers ===\r\nAuthorization\r\nbin\r\nCommon\r\nConfiguration\r\nControllers\r\nHttpRequests\r\nobj\r\nUtils\r\n=== nexus files ===\r\n756\r\n","exit":0,"truncated":false},"title":"echo \"=== Nexus ===\"; Get-ChildItem src\\nexus\\CentronNexus -Directory | Select-Object -ExpandProperty Name; echo \"=== Controllers ===\"; Get-ChildItem src\\webservice\\Centron.Controllers -Directory -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name; echo \"=== nexus files ===\"; (Get-ChildItem src\\nexus\\CentronNexus -Recurse -File -Include *.razor,*.cs | Where-Object {$_.FullName -notmatch '\\\\(bin|obj)\\\\'}).Count","time":{"start":1788347528763,"end":1788347528831}},"id":"prt_061d1a732001fDSj97w8pbjnJ1","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","messageID":"msg_061d1614d001woKiKO99eufVgk"}} +{"type":"step_finish","timestamp":1788347529310,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d1b849001q7310Dhncw80k1","reason":"tool-calls","snapshot":"d3e28a96be089f091c4ae1f9a4622d79a237cf07","messageID":"msg_061d1614d001woKiKO99eufVgk","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","type":"step-finish","tokens":{"total":15320,"input":452,"output":292,"reasoning":1776,"cache":{"write":0,"read":12800}},"cost":0}} +{"type":"step_start","timestamp":1788347531593,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d1c140001GU93PNbu1emS4Q","messageID":"msg_061d1b9cc001PwiC4AKtGUtzBP","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","snapshot":"d3e28a96be089f091c4ae1f9a4622d79a237cf07","type":"step-start"}} +{"type":"text","timestamp":1788347532522,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d1c332001rk8Jaf7sGYQEAY","messageID":"msg_061d1b9cc001PwiC4AKtGUtzBP","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","type":"text","text":"\n\n","time":{"start":1788347532082,"end":1788347532457}}} +{"type":"tool_use","timestamp":1788347533039,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"type":"tool","tool":"bash","callID":"call_23d60e975d65446b831362ad","state":{"status":"completed","input":{"command":"Get-ChildItem src\\backend\\Centron.BL\\Administration -Directory -Recurse -Depth 1 | ForEach-Object { $_.FullName.Replace(\"$PWD\\src\\backend\\Centron.BL\\Administration\\\",\"\") }"},"output":"AccessTokens\r\nApplications\r\nArtificialIntelligence\r\nBackgroundServices\r\nBookKeepingAccountSystems\r\nCentronConfigDb\r\nCompany\r\nCompanyInformations\r\nConnections\r\nCustomization\r\nDataSecurity\r\nDocuments\r\nEmployees\r\nEnvironments\r\nFileManagement\r\nLicensing\r\nLogins\r\nMandatory\r\nMasterdata\r\nNetworkDiagnostics\r\nPerformanceTests\r\nPhoneSettings\r\nPortal\r\nProfiling\r\nRights\r\nScripts\r\nSettings\r\nSQLManagement\r\nThemes\r\nWebServiceConfiguration\r\nArtificialIntelligence\\Chat\r\nDocuments\\Dsgvo\r\nDocuments\\ReceiptComments\r\nEmployees\\EmployeeSettings\r\nFileManagement\\DirectoryReferenceProviders\r\nLogins\\Auth\r\nLogins\\TwoFactor\r\nScripts\\ScriptMethods\r\n","metadata":{"output":"AccessTokens\r\nApplications\r\nArtificialIntelligence\r\nBackgroundServices\r\nBookKeepingAccountSystems\r\nCentronConfigDb\r\nCompany\r\nCompanyInformations\r\nConnections\r\nCustomization\r\nDataSecurity\r\nDocuments\r\nEmployees\r\nEnvironments\r\nFileManagement\r\nLicensing\r\nLogins\r\nMandatory\r\nMasterdata\r\nNetworkDiagnostics\r\nPerformanceTests\r\nPhoneSettings\r\nPortal\r\nProfiling\r\nRights\r\nScripts\r\nSettings\r\nSQLManagement\r\nThemes\r\nWebServiceConfiguration\r\nArtificialIntelligence\\Chat\r\nDocuments\\Dsgvo\r\nDocuments\\ReceiptComments\r\nEmployees\\EmployeeSettings\r\nFileManagement\\DirectoryReferenceProviders\r\nLogins\\Auth\r\nLogins\\TwoFactor\r\nScripts\\ScriptMethods\r\n","exit":0,"truncated":false},"title":"Get-ChildItem src\\backend\\Centron.BL\\Administration -Directory -Recurse -Depth 1 | ForEach-Object { $_.FullName.Replace(\"$PWD\\src\\backend\\Centron.BL\\Administration\\\",\"\") }","time":{"start":1788347532954,"end":1788347533021}},"id":"prt_061d1c36b0012BBZT651PlzNZB","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","messageID":"msg_061d1b9cc001PwiC4AKtGUtzBP"}} +{"type":"step_finish","timestamp":1788347533542,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d1c8d2001Mam5enFC7fYdNY","reason":"tool-calls","snapshot":"d3e28a96be089f091c4ae1f9a4622d79a237cf07","messageID":"msg_061d1b9cc001PwiC4AKtGUtzBP","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","type":"step-finish","tokens":{"total":15997,"input":2598,"output":75,"reasoning":76,"cache":{"write":0,"read":13248}},"cost":0}} +{"type":"step_start","timestamp":1788347535455,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d1d057001m1dvUCYlViJX3l","messageID":"msg_061d1ca23001Bp1Fu3xfQqlOKR","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","snapshot":"d3e28a96be089f091c4ae1f9a4622d79a237cf07","type":"step-start"}} +{"type":"tool_use","timestamp":1788347549429,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"type":"tool","tool":"bash","callID":"call_33a57c4814a642b088d20316","state":{"status":"completed","input":{"command":"\"{0:N0} KB schema\" -f ((Get-Item SSMS_DB_SCHEMA.sql).Length/1KB); (Get-ChildItem src\\backend\\Centron.Entities\\Entities -Recurse -File *.cs | ? {$_.FullName -notmatch '\\\\(bin|obj)\\\\'}).Count; Get-ChildItem src\\backend\\Centron.Entities\\Entities -Directory | Select -Expand Name; echo \"=== out dir ===\"; Test-Path \"C:\\DEV\\MasterArbeit\\Versuche\\Versuch_01\\Iteration 16\\qwen\\qwen3.8-flash-next\\builtin\\high\\03_Lauf_2026-09-02_131102_v13.0.0-6a1a\\Ergebnisse\""},"output":"3.190 KB schema\r\n1179\r\nAccounting\r\nAccounts\r\nAdministration\r\nAppointmentRequests\r\nBranchArea\r\nBusinesspartner\r\nBuying\r\nCentronIcons\r\nChangeTracking\r\nChats\r\nChecklistArea\r\nConstants\r\nCustomerArea\r\nCustomizations\r\nDataExchange\r\nDbEntities\r\nDevices\r\nDocuBoard\r\nDocumentationArea\r\nEDI\r\nEmployeeArea\r\nEnvironments\r\nExpectedEvents\r\nExternalHelpdesk\r\nExternalTools\r\nFinances\r\nGateway\r\nGUI\r\nHolidayArea\r\nImageFactory\r\nImport\r\nIntegrations\r\nItPlanner\r\nLogistics\r\nLogos\r\nMail\r\nMailings\r\nMailScanner\r\nMassUpdate\r\nMerchandise\r\nMobile\r\nModules\r\nMyCentron\r\nMyDay\r\nNexusNotifications\r\nNexusTicketViews\r\nNotifications\r\nObjectExternalReferences\r\nObjectTypes\r\nOutlook\r\nPasswordManagementArea\r\nPasswordManager\r\nProduction\r\nProductMatrix\r\nProjectArea\r\nPurchasing\r\nRelationshipArea\r\nReportEngine\r\nReporting\r\nSales\r\nScheduleArea\r\nSelfCare\r\nServices\r\nSocialMedia\r\nStates\r\nStatistics\r\nStorage\r\nSystemArea\r\nTags\r\nTapi\r\nTaskManager\r\nTelemetry\r\nTextModuleArea\r\nTicketing\r\nTicketProjects\r\nTime\r\nToDoArea\r\nTradePool\r\nTransactions\r\nUrls\r\nVideoPortal\r\nVoucherManagement\r\nWarehousing\r\nWebLinks\r\nWebSuite\r\n=== out dir ===\r\nTrue\r\n","metadata":{"output":"3.190 KB schema\r\n1179\r\nAccounting\r\nAccounts\r\nAdministration\r\nAppointmentRequests\r\nBranchArea\r\nBusinesspartner\r\nBuying\r\nCentronIcons\r\nChangeTracking\r\nChats\r\nChecklistArea\r\nConstants\r\nCustomerArea\r\nCustomizations\r\nDataExchange\r\nDbEntities\r\nDevices\r\nDocuBoard\r\nDocumentationArea\r\nEDI\r\nEmployeeArea\r\nEnvironments\r\nExpectedEvents\r\nExternalHelpdesk\r\nExternalTools\r\nFinances\r\nGateway\r\nGUI\r\nHolidayArea\r\nImageFactory\r\nImport\r\nIntegrations\r\nItPlanner\r\nLogistics\r\nLogos\r\nMail\r\nMailings\r\nMailScanner\r\nMassUpdate\r\nMerchandise\r\nMobile\r\nModules\r\nMyCentron\r\nMyDay\r\nNexusNotifications\r\nNexusTicketViews\r\nNotifications\r\nObjectExternalReferences\r\nObjectTypes\r\nOutlook\r\nPasswordManagementArea\r\nPasswordManager\r\nProduction\r\nProductMatrix\r\nProjectArea\r\nPurchasing\r\nRelationshipArea\r\nReportEngine\r\nReporting\r\nSales\r\nScheduleArea\r\nSelfCare\r\nServices\r\nSocialMedia\r\nStates\r\nStatistics\r\nStorage\r\nSystemArea\r\nTags\r\nTapi\r\nTaskManager\r\nTelemetry\r\nTextModuleArea\r\nTicketing\r\nTicketProjects\r\nTime\r\nToDoArea\r\nTradePool\r\nTransactions\r\nUrls\r\nVideoPortal\r\nVoucherManagement\r\nWarehousing\r\nWebLinks\r\nWebSuite\r\n=== out dir ===\r\nTrue\r\n","exit":0,"truncated":false},"title":"\"{0:N0} KB schema\" -f ((Get-Item SSMS_DB_SCHEMA.sql).Length/1KB); (Get-ChildItem src\\backend\\Centron.Entities\\Entities -Recurse -File *.cs | ? {$_.FullName -notmatch '\\\\(bin|obj)\\\\'}).Count; Get-ChildItem src\\backend\\Centron.Entities\\Entities -Directory | Select -Expand Name; echo \"=== out dir ===\"; Test-Path \"C:\\DEV\\MasterArbeit\\Versuche\\Versuch_01\\Iteration 16\\qwen\\qwen3.8-flash-next\\builtin\\high\\03_Lauf_2026-09-02_131102_v13.0.0-6a1a\\Ergebnisse\"","time":{"start":1788347549354,"end":1788347549399}},"id":"prt_061d20019001OTqNsivnrFXsX1","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","messageID":"msg_061d1ca23001Bp1Fu3xfQqlOKR"}} +{"type":"text","timestamp":1788347549583,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d1ff92001UAvBFK6XKgHxsN","messageID":"msg_061d1ca23001Bp1Fu3xfQqlOKR","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","type":"text","text":"\n\n\n","time":{"start":1788347547539,"end":1788347549514}}} +{"type":"tool_use","timestamp":1788347550145,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"type":"tool","tool":"bash","callID":"call_9b55786f1d2e4bfc98687442","state":{"status":"completed","input":{"command":"Get-ChildItem src\\nexus\\CentronNexus\\WebCart,src\\nexus\\CentronNexus\\ServiceBoard -Recurse -File -Include *.razor | ? {$_.FullName -notmatch '\\\\(bin|obj)\\\\'} | Select -First 40 -Expand FullName | % {$_.Replace(\"$PWD\\\",\"\")}"},"output":"src\\nexus\\CentronNexus\\WebCart\\Components\\ContractDetailsPreview.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Components\\HeaderWebAccountNewButton.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Components\\WebAccountContactSearchDropdown.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Components\\WebCartClearance.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Components\\WebCartHistory.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Components\\WebCartTicketDetailsPanel.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Components\\WebCartTicketNavigation.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Components\\WebCartTicketTitle.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Components\\WebReceiptNavigation.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\CustomerPortal\\Components\\CustomerTicketTimerDetails.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\CustomerPortal\\CustomerTicketTimeRecordsPage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Dialogs\\AddNewShoppingCart.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Dialogs\\AddToDescriptionDialog.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Dialogs\\DuplicateCart.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Dialogs\\ImportArticlesToCart.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Dialogs\\NewWebAccountTicketDialog.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Dialogs\\WebAccountContactsSelectionDialog.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Documents\\Components\\CustomerPortalPublicDocumentList.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Documents\\Components\\CustomerTicketDocumentList.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Documents\\CustomerDocumentsPage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\_Imports.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\ContractsOverview.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\CustomerPortalFormFillPage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\CustomerPortalFormsPage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\CustomerPortalPublicDocumentsPage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\CustomerTicketDetailsPage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\CustomerTicketHistoryPage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\CustomperPortalHomePage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\ReceiptDetailsOverview.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\ReceiptsOverview.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\WebCartAdminPage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\WebCartCartPage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\WebCartHomePage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\WebCartShopPage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\WebCartTicketsPage.razor\r\nsrc\\nexus\\CentronNexus\\ServiceBoard\\CachedTicketList\\Components\\BranchFilterSelection.razor\r\nsrc\\nexus\\CentronNexus\\ServiceBoard\\CachedTicketList\\Components\\CachedKanbanBoard.razor\r\nsrc\\nexus\\CentronNexus\\ServiceBoard\\CachedTicketList\\Components\\CategoryFilterSelection.razor\r\nsrc\\nexus\\CentronNexus\\ServiceBoard\\CachedTicketList\\Components\\ConditionalFormattingEditor.razor\r\nsrc\\nexus\\CentronNexus\\ServiceBoard\\CachedTicketList\\Components\\EmployeeFilterSelection.razor\r\n","metadata":{"output":"src\\nexus\\CentronNexus\\WebCart\\Components\\ContractDetailsPreview.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Components\\HeaderWebAccountNewButton.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Components\\WebAccountContactSearchDropdown.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Components\\WebCartClearance.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Components\\WebCartHistory.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Components\\WebCartTicketDetailsPanel.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Components\\WebCartTicketNavigation.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Components\\WebCartTicketTitle.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Components\\WebReceiptNavigation.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\CustomerPortal\\Components\\CustomerTicketTimerDetails.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\CustomerPortal\\CustomerTicketTimeRecordsPage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Dialogs\\AddNewShoppingCart.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Dialogs\\AddToDescriptionDialog.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Dialogs\\DuplicateCart.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Dialogs\\ImportArticlesToCart.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Dialogs\\NewWebAccountTicketDialog.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Dialogs\\WebAccountContactsSelectionDialog.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Documents\\Components\\CustomerPortalPublicDocumentList.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Documents\\Components\\CustomerTicketDocumentList.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\Documents\\CustomerDocumentsPage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\_Imports.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\ContractsOverview.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\CustomerPortalFormFillPage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\CustomerPortalFormsPage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\CustomerPortalPublicDocumentsPage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\CustomerTicketDetailsPage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\CustomerTicketHistoryPage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\CustomperPortalHomePage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\ReceiptDetailsOverview.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\ReceiptsOverview.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\WebCartAdminPage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\WebCartCartPage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\WebCartHomePage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\WebCartShopPage.razor\r\nsrc\\nexus\\CentronNexus\\WebCart\\WebCartTicketsPage.razor\r\nsrc\\nexus\\CentronNexus\\ServiceBoard\\CachedTicketList\\Components\\BranchFilterSelection.razor\r\nsrc\\nexus\\CentronNexus\\ServiceBoard\\CachedTicketList\\Components\\CachedKanbanBoard.razor\r\nsrc\\nexus\\CentronNexus\\ServiceBoard\\CachedTicketList\\Components\\CategoryFilterSelection.razor\r\nsrc\\nexus\\CentronNexus\\ServiceBoard\\CachedTicketList\\Components\\ConditionalFormattingEditor.razor\r\nsrc\\nexus\\CentronNexus\\ServiceBoard\\CachedTicketList\\Components\\EmployeeFilterSelection.razor\r\n","exit":0,"truncated":false},"title":"Get-ChildItem src\\nexus\\CentronNexus\\WebCart,src\\nexus\\CentronNexus\\ServiceBoard -Recurse -File -Include *.razor | ? {$_.FullName -notmatch '\\\\(bin|obj)\\\\'} | Select -First 40 -Expand FullName | % {$_.Replace(\"$PWD\\\",\"\")}","time":{"start":1788347550091,"end":1788347550139}},"id":"prt_061d2041e001KQ6416tnsjSRtQ","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","messageID":"msg_061d1ca23001Bp1Fu3xfQqlOKR"}} +{"type":"step_finish","timestamp":1788347550600,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d20b82001xXTnRrRMvygjz7","reason":"tool-calls","snapshot":"d3e28a96be089f091c4ae1f9a4622d79a237cf07","messageID":"msg_061d1ca23001Bp1Fu3xfQqlOKR","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","type":"step-finish","tokens":{"total":17787,"input":271,"output":293,"reasoning":1351,"cache":{"write":0,"read":15872}},"cost":0}} +{"type":"step_start","timestamp":1788347552754,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d213ec001QSCUQ8lkmwedP3","messageID":"msg_061d20cf1001XgScVNFRWv9B7H","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","snapshot":"d3e28a96be089f091c4ae1f9a4622d79a237cf07","type":"step-start"}} +{"type":"text","timestamp":1788347596952,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"id":"prt_061d25253001bXEpbhtn9kS6lr","messageID":"msg_061d20cf1001XgScVNFRWv9B7H","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","type":"text","text":"\n\n\n\n\n\n\n","time":{"start":1788347568724,"end":1788347596925}}} +{"type":"tool_use","timestamp":1788347770959,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"type":"tool","tool":"task","callID":"call_b45751078140492fbf823938","state":{"status":"completed","input":{"description":"Cluster Einkauf/Lager erkunden","prompt":"Reverse-Requirements-Engineering, NUR lesende Analyse der c-entron ERP-Codebasis im aktuellen Arbeitsverzeichnis (Windows, C#/.NET). Thoroughness: medium. Du schreibst keine Dateien.\n\nUntersuchte Module (Cluster EINKAUF/LAGER/PRODUKTION):\n- src\\backend\\Centron.BL\\Buying\n- src\\backend\\Centron.BL\\Purchasing\n- src\\backend\\Centron.BL\\Warehousing (40 Dateien)\n- src\\backend\\Centron.BL\\Logistics\n- src\\backend\\Centron.BL\\Production\n- src\\backend\\Centron.BL\\ProductMatrix\n- src\\backend\\Centron.BL\\TradePool\n- src\\backend\\Centron.BL\\Devices\n- src\\backend\\Centron.Entities\\Merchandise (Stichprobe Datenmodell Artikel)\n\nHinweis: Manche Ordner enthalten nur wenige .cs-Dateien; ergänze die fachliche Einordnung durch Entities, NHibernate-Mappings (src\\backend\\Centron.DAO\\Mappings) oder UI-Strings, wenn nötig - Belege müssen real existieren (mit Read/Glob verifizieren). Erfinde nichts.\n\nErgebnis (reiner Text, keine Dateien schreiben):\n1. JE Modul genau eine Inventar-Zeile: MODUL | | \n2. Danach 1-2 Anforderungs-Entwürfe pro Modul (SwRS oder SyRS). Strenge Feldreihenfolge:\nID: \nTitel: ...\nEbene: ...\nTyp: ...\nQualitätsmerkmal: \nAkteur: ...\nVorbedingung: ...\nFakt: \nAussage: Das System soll ...\nErgebnis: ...\nBelege:\n - [PRIMÄR oder SEKUNDÄR] src\\...\\File.cs, Klasse.Methode/Feld - Begründung: ...\nPrüfidee: ...\nTracelinks: frei\nKonsolidierung: \nÜbernahmewürdigkeit: übernehmen|Workaround|Sonderfall|veraltet - \nStatus: belegt|HYPOTHESE\n\nRegeln: Sicherheit-/Abrechnungs-relevante Aussagen (z.B. Berechtigungen, Preisfindung Bestellung) nur mit PRIMÄR-Beleg der Durchsetzungsstelle, sonst HYPOTHESE. Pfad relativ. Zitate max 15 Wörter. Deutsch.","subagent_type":"explore"},"output":"\n\n\n\n# Reverse-Requirements-Analyse – Cluster EINKAUF/LAGER/PRODUKTION (c-entron ERP)\n\nHinweis zur Quellenlage: Der Ordner `src\\backend\\Centron.Entities\\Merchandise` existiert nicht; die Artikel-Stichprobe liegt unter `src\\backend\\Centron.Entities\\Entities\\Merchandise` (dort nur `ArticleCompact.cs`) samt Mapping `src\\backend\\Centron.DAO\\Mappings\\Merchandise`. Alle Belege wurden per Read/Glob verifiziert.\n\n## 1. Modul-Inventar\n\nMODUL | src\\backend\\Centron.BL\\Buying | Verwaltung von Distributoren (Großhändlern) als Stammdaten mit Aktivstatus, inkl. automatischer Anlage bei Importen.\nMODUL | src\\backend\\Centron.BL\\Purchasing | Beschaffungslogik: Bestellvorschlagsliste (OSL/BVL), Lieferantenstammdaten und bereichsübergreifende Lieferantenrechnungs-/Timer-Exporte.\nMODUL | src\\backend\\Centron.BL\\Warehousing | Artikelwirtschaft: Artikelstamm mit Rechtsprüfung, Lagerbestandsführung, Lagerplätze, Inventur, Kommissionierung, Aktionstemperaturen/Aktionspreise.\nMODUL | src\\backend\\Centron.BL\\Logistics | Logistik: Lager- und Nebenlagerverwaltung (Hauptlager = I3D -1), Umlagerungs-Logistik und Logistikeinstellungen.\nMODUL | src\\backend\\Centron.BL\\Production | Produktionsmanagement: Maschinen, Maschinenarten/-orte und Fertigungsaufträge, lizenzpflichtig.\nMODUL | src\\backend\\Centron.BL\\ProductMatrix | Kunden-Produktmatrix: Kategorien, Produkte, Bewertungen und Bewertungshistorie (CRUD).\nMODUL | src\\backend\\Centron.BL\\TradePool | Import und Suche von Handelspool-Artikeln aus XML-Dateien der Distributoren inkl. Kundenbezug.\nMODUL | src\\backend\\Centron.BL\\Devices | Geräteverwaltung (AccountDevice) mit URI-Listen, Soft-Delete und Änderungshistorie.\nMODUL | src\\backend\\Centron.Entities\\Entities\\Merchandise | Datenmodell-Stichprobe Artikel: schreibgeschütztes Kompaktmodell `ArticleCompact` auf DB-Tabelle ARTIK.\n\n## 2. Anforderungs-Entwürfe\n\nID: E-1\nTitel: Automatische Anlage fehlender Distributoren beim Import\nEbene: SwRS\nTyp: funktional\nQualitätsmerkmal:\nAkteur: Importsystem (fachlich: Einkaufsdatenverarbeitung)\nVorbedingung: Liste von Distributornamen liegt vor (z. B. aus einer Importdatei)\nFakt: `DistributorBL.EnsureDistributorsExist` sucht bestehende `Distributor`-Entitäten per `Name` und erzeugt sonst `new Distributor { Name = name }`, setzt `State = 1` und speichert via `SaveOrUpdate`; Abfragen filtern `f.State == 1`\nAussage: Das System soll beim Sicherstellen von Distributoren unbekannte Namen automatisch als aktive Distributoren anlegen und bestehende reaktivieren\nErgebnis: Für jeden übergebenen Namen existiert genau eine Distributor-Entität mit State=1, die zurückgegeben wird\nBelege:\n - [PRIMÄR] src\\backend\\Centron.BL\\Buying\\External\\DistributorBL.cs, EnsureDistributorsExist - Begründung: Anlage-/Aktivierungslogik inkl. State-Setzen direkt hier implementiert\n - [PRIMÄR] src\\backend\\Centron.BL\\Buying\\External\\DistributorBL.cs, GetAllDistributors - Begründung: Lesende Zugriffe beschränken sich auf `State == 1`\nPrüfidee: BL-Test mit zwei Namen (einer vorhanden, einer neu); danach genau zwei Datensätze mit State=1 Erwartung\nTracelinks: frei\nKonsolidierung: Kandidat: gemeinsame „Ensure-by-Name\"-Musterverwendung mit Wareneingangs-/Artikelimporten (OrderSuggestionListBL nutzt Distributor-Entities mit)\nÜbernahmewürdigkeit: übernehmen - reiner Idempotent-Anlege-Mechanismus ohne Sonderlogik\nStatus: belegt\n\nID: E-2\nTitel: Deckungs- und Mindestbestandsberechnung der Bestellvorschlagsliste\nEbene: SwRS\nTyp: funktional\nQualitätsmerkmal:\nAkteur: Einkäufer (BVL/OSL-Anwender)\nVorbedingung: Offene Auftragspositionen, Artikel-Mindestbestände und Lagerzugänge gepflegt\nFakt: `OrderSuggestionListBL` baut ein SQL-Konstrukt aus `AufPos`/`AufKopf` (`ak.Status = 1`, `ISNULL(ak.BestellSperre, 0) = 0`), `Mindestbestand` und `cvw_ArticleCount`; Kennzeichen `_sqlPositionsKind` filtert Aufwands-/Darlehensartikel per AppSettings `OSLShowReceiptOnDemandPositions`/`OSLShowReceiptOnEffortPositions`; Preis: `A.EK / :calcfactor`\nAussage: Das System soll den offenen Bedarf je Artikel und Lager aus Auftragspositionen minus Bestand/Zugängen ermitteln und Mindestbestand unterschreitende Artikel vorschlagen\nErgebnis: Vorschlagsliste mit Artikelcode, Bestand, Bedarf, EK und Mindestbestellmenge je Lager\nBelege:\n - [PRIMÄR] src\\backend\\Centron.BL\\Purchasing\\OrderSuggestionList\\OrderSuggestionListBL.cs, ctor/_sqlArticle - Begründung: Bedarfs- und Mindestbestands-SQL mit Sperrlogik steht vollständig in dieser Klasse\n - [SEKUNDÄR] src\\backend\\Centron.BL\\Purchasing\\PurchaseSettings\\PurchaseSettingsBL.cs, GetSettings - Begründung: BVL/OSL-Steuerungsschalter werden hier zentral verwaltet\nPrüfidee: Integrativ: Artikel mit Mindestbestand 10, Bestand 2, offener Position 5 → Vorschlagsmenge 13; Auftragsposition mit BestellSperre ignorieren\nTracelinks: frei\nKonsolidierung: Kandidat: Preisberechnungsfaktor (ArticleCalculationFactor) tritt auch in ArticleStockBL.GetArticleCalculationFactor auf\nÜbernahmewürdigkeit: übernehmen - Kernfunktion des Bestellwesens, breit konfigurierbar\nStatus: belegt\n\nID: E-3\nTitel: Bereichsübergreifender Export von Lieferantenrechnungen und Timerleistungen\nEbene: SyRS\nTyp: funktional\nQualitätsmerkmal:\nAkteur: Zentrale/Backoffice (Exportanwender)\nVorbedingung: Lieferant (Kreditor) einer Berechnung und Ziel-Bereich der Auftragsposition gepflegt; Exportzeitraum gewählt\nFakt: `SupplierOrderPerBranchBL.GetBasisCalcList`/`GetBasisTimerToOrder` liefern DTOs per Raw-SQL nur bei `ISNULL(flA.I3D,0) != ISNULL(flB.I3D,0)`; ohne `RepeatExport` gilt `AND kp.ExportDate Is Null`; Preisformel `CASE WHEN ma.InternalCompanyEK IS NULL THEN a.EK ELSE ma.InternalCompanyEK END`; `WriteExportDate` markiert Export\nAussage: Das System soll nur Vorgänge zwischen unterschiedlichen Bereichen (Quelle ≠ Ziel, sonst 'zentrale') exportieren und den Exportstatus je Position zeitlich markieren\nErgebnis: Vollständige,Dubletten-freie Exportliste (Erstexport ohne bereits exportierte Sätze) mit Bereichszuordnung\nBelege:\n - [PRIMÄR] src\\backend\\Centron.BL\\Purchasing\\SupplierOrderPerBranchBL.cs, GetBasisCalcList/WriteExportDate - Begründung: Bereichsfilter-, ExportDatum- und Preislogik alle in diesem BL belegt\nPrüfidee: Zwei identische Datensätze, einer mit gesetztem ExportDate → nur einer geliefert; `RepeatExport=true` liefert beide\nTracelinks: frei\nKonsolidierung: Kandidat: ExportDatum-Markierungsmuster mit TradePool-/Schnittstellenexporten\nÜbernahmewürdigkeit: Sonderfall - interne Verrechnungs-/Timerlogik (hlpdsk_*) mit unternehmensspezifischen Tabellen\nStatus: belegt\n\nID: E-4\nTitel: Berechtigungsprüfung in der Kommissionierung\nEbene: SwRS\nTyp: nichtfunktional\nQualitätsmerkmal: ISO/IEC 25010 – Sicherheit (Zugriffskontrolle)\nAkteur: angemeldeter Benutzer (AppUser)\nVorbedingung: Benutzer ist authentifiziert; Recht-Katalog `UserRightsConst.Logistic.Commissioning` existiert\nFakt: `OrderCommissionBL.HasUserRightsTooAccessCommissionModule` prüft `currentUser.HasUserRight(UserRightsConst.Logistic.Commissioning.ID)` und liefert sonst Fehler „Der angemeldete Benutzer hat nicht das Recht um auf die Kommissionierung zuzugreifen.\"; Aufruf in `GetOrdersForCommission` (Zeile 73) u. a.; separate Recht `GENERATE_BARCODES`\nAussage: Das System soll jeden Zugriff auf Kommissionierdaten und das Generieren von Barcodes nur bei explizit vergebenem Benutzerrecht gestatten\nErgebnis: Aufruf ohne Recht wird mit Fehlerergebnis abgewiesen; keine Daten werden geliefert\nBelege:\n - [PRIMÄR] src\\backend\\Centron.BL\\Warehousing\\Commissions\\OrderCommissionBL.cs, HasUserRightsTooAccessCommissionModule - Begründung: Durchsetzungsstelle der Zugriffskontrolle inkl. Fehlerpfad\n - [SEKUNDÄR] src\\backend\\Centron.BL\\Warehousing\\ArticleBL.cs, GetArticleManagementUiSettings - Begründung: analoges Rechtsmuster (AppRightsBL.HasUserRight) im Artikelmanagement\nPrüfidee: Benutzer ohne Commissioning-Recht aufrufen lassen → ResultStatus.Error; mit Recht → Liste\nTracelinks: frei\nKonsolidierung: Kandidat: einheitliche Rechtsprüfung aller Module über AppRightsBL/UserRightsConst\nÜbernahmewürdigkeit: übernehmen - mustergültige BL-seitige Rechteprüfung\nStatus: belegt\n\nID: E-5\nTitel: Fortschreibung des Artikel-EK aus Wareneingängen (Preisfindung Bestellung)\nEbene: SwRS\nTyp: funktional\nQualitätsmerkmal:\nAkteur: System (Belegbuchung), Einkaufsleiter\nVorbedingung: Belegposition mit EK-Preis und Menge wird auf ein Lager gebucht\nFakt: `ArticleStockBL.UpdateArticlePurchasePrice` überspringt Aktualisierung bei `item.SpecialAgreementI3D > 0` und bei `article.NoMixedEk == PurchasePriceAsKind.FixedPurchasePrice`; sonst `purchasePriceMod = (purchasePrice + freightAmount + insuranceAmount) * calcFactor`; bei Menge 0 bzw. `LastPurchasePrice` wird direkt gesetzt, andernfalls Mischpreis\nAussage: Das System soll den Artikel-EK aus Belegpreis zzgl. Fracht/Versicherung, mit Kalkulationsfaktor, unter Beachtung von Sondervereinbarungen und Preisbindeflagge fortschreiben\nErgebnis: EK im Artikelstamm (Hauptlager) bzw. in `SecondaryStockArticle` (Nebenlager) ist aktualisiert oder bewusst unverändert\nBelege:\n - [PRIMÄR] src\\backend\\Centron.BL\\Warehousing\\StockManagement\\ArticleStockBL.cs, UpdateArticlePurchasePrice - Begründung: vollständige Preisbildungs- und Ausnahmeregeln inkl. Nebenlagerast in der Methode\nPrüfidee: Position mit Sondervereinbarung buchen → EK unverändert; feste Preisbindeflagge → unverändert; sonst Mischpreis-/Faktorrechnung nachprüfen\nTracelinks: frei\nKonsolidierung: Kandidat: Fracht/Versicherung-Aufschlag identisch in SupplierOrderPerBranchBL-SQL (`kp.preis + Versicherung + Fracht`)\nÜbernahmewürdigkeit: übernehmen - abrechnungsrelevante Kernregel mit klar dokumentierten Ausnahmen\nStatus: belegt\n\nID: E-6\nTitel: Validierte Protokollierierung von Lagerumlagerungen\nEbene: SwRS\nTyp: funktional\nQualitätsmerkmal:\nAkteur: Logistikmitarbeiter\nVorbedingung: Umlagerung von Quell- auf Ziellager wurde durchgeführt\nFakt: `StockBL.WriteStockRebookLog` validiert `ArticleI3D >= 1`, Mitarbeiter, `FromStore`, `ToStore`; Datum wird auf `DateTime.Now` gesetzt falls leer; Persistenz über `StockRepository.WriteStockRebookLog`, Auslesen via `GetStockRebookLogs`\nAussage: Das System soll jede Umlagerung nur mit gültigem Artikel, Mitarbeiter, Quell- und Ziellager protokollieren und die Protokolle filterbar ausliefern\nErgebnis: vollständiger Log-Datensatz oder definierte Fehlermeldung pro unvollständiger Angabe\nBelege:\n - [PRIMÄR] src\\backend\\Centron.BL\\Logistics\\Warehousing\\StockBL.cs, WriteStockRebookLog - Begründung: alle Validierungsregeln als Guard-Clubs der Methode\n - [SEKUNDÄR] src\\backend\\Centron.BL\\Logistics\\Warehousing\\StockBL.cs, GetMainWarehouse - Begründung: Hauptlager per Konvention I3D=-1, Kontext der Lagerhierarchie\nPrüfidee: Log ohne Ziellager → Fehler „The destination stock is invalid\"; vollständiger Log → in GetStockRebookLogs sichtbar\nTracelinks: frei\nKonsolidierung: Kandidat: Logik-Muster mit AccountDeviceLog (Devices) und ArticleHistoryBL\nÜbernahmewürdigkeit: übernehmen - Audit-Trail-Funktionalität mit nachvollziehbaren Guards\nStatus: belegt\n\nID: E-7\nTitel: Lizenzpflicht des Produktionsmanagements\nEbene: SwRS\nTyp: nichtfunktional\nQualitätsmerkmal: ISO/IEC 25010 – Funktionalitätstauglichkeit (Zugriffsteuerung via Lizenzierung)\nAkteur: Benutzer ohne Produktionslizenz\nVorbedingung: `LicenseManager` prüfbar; Produktionsmaschinen/-aufträge vorhanden\nFakt: Jede öffentliche Methode von `ProductionBL` und `ProductionOrderBL` (z. B. `GetProductionMachineByI3D`, `SaveProductionOrder`) prüft `LicenseManager.Instance.HasLicense(LicenseGuids.ProductionManagement)` und wirft sonst Exception mit `LocalizedStrings.ProductionBL_Sie_besitzen_nicht_die_Lizenz_für_das_Produktionsmanagement`\nAussage: Das System soll sämtliche Lese- und Schreibzugriffe auf Produktionsdaten verweigern, wenn die Produktionsmanagement-Lizenz fehlt\nErgebnis: Exception mit lokalisierter Meldung; kein Datenzugriff ohne Lizenz\nBelege:\n - [PRIMÄR] src\\backend\\Centron.BL\\Production\\ProductionBL.cs, GetProductionMachineByI3D - Begründung: Lizenz-Guard an der tatsächlichen Zugriffsstelle (Zeilen 29-32, wiederholt in allen Methoden)\n - [PRIMÄR] src\\backend\\Centron.BL\\Production\\ProductionOrderBL.cs, SaveProductionOrder - Begründung: Lizenz-Guard auch vor Persistierung\nPrüfidee: Lizenz simuliert entfernt → alle CRUD-Methoden beider BLs werfen lokalisierte Exception\nTracelinks: frei\nKonsolidierung: Kandidat: Lizenz-Guards analog `LicenseGuids.Branch` in SupplierBL.GetSupplierBranchInfos\nÜbernahmewürdigkeit: übernehmen - klarer, konsistenterlizenzierter Modulzuschnitt\nStatus: belegt\n\nID: E-8\nTitel: Filterbare查询 von Fertigungsaufträgen nach Maschine\nEbene: SwRS\nTyp: funktional\nQualitätsmerkmal:\nAkteur: Produktionsplaner\nVorbedingung: Fertigungsaufträge mit Positionen (ProduktionOrderItems inkl. MachineI3D) vorhanden\nFakt: `ProductionOrderBL.CreateFilterExpression` verknüpft Filter über `f.ProductionOrderItems.Any(g => g.MachineI3D == filter.MachineI3D)` bzw. `MachineKindI3D`; sortierte Lieferung via `GetSortList(..., f => f.OrderI3D, ...)`\nAussage: Das System soll Fertigungsaufträge nach Auftragskopf-, Positions-, Maschinen- und Maschinenartfilter durchsuchbar liefern\nErgebnis: Auftragsliste, deren Positionen die Filtermaschine/-art enthalten\nBelege:\n - [PRIMÄR] src\\backend\\Centron.BL\\Production\\ProductionOrderBL.cs, CreateFilterExpression - Begründung: Filterkomposition inkl. Positions-Subquery genau hier\nPrüfidee: Two Machines mit je einem Auftrag → Filter MachineI3D liefert nur zugehörigen Auftrag\nTracelinks: frei\nKonsolidierung: nein\nÜbernahmewürdigkeit: übernehmen - Standard-Abfragemuster, muster-konform zu übrigen BL-Filtern\nStatus: belegt\n\nID: E-9\nTitel: CRUD mit Existenzprüfung für Kunden-Produktmatrix\nEbene: SwRS\nTyp: funktional\nQualitätsmerkmal:\nAkteur: Key-Account-Manager\nVorbedingung: Matrixkategorie/-produkt/-bewertung per I3D adressiert\nFakt: `ProductMatrixBL` kapselt alle Zugriffe in `Result`-Objekte mit NLog-Fehlerprotokoll; `DeleteProductMatrixCategory` löscht nur wenn `Status == Success && Data != null`, sonst Rückgabe des Fehler-Results; Entity `CustomerProductMatrixRatingChangeLog` wird über `GetCustomerProductMatrixRatingByI3D`-Nachbarmethode exponiert\nAussage: Das System soll Kategorien/Produkte/Bewertungen der Kundenmatrix nur nach erfolgreicher Existenzprüfung ändern/löschen und Fehler als Ergebnisobjekte mit Logeintrag zurückgeben\nErgebnis: Kein stiller Datenverlust; Fehlerfall liefert Fehlerresult und Logzeile\nBelege:\n - [PRIMÄR] src\\backend\\Centron.BL\\ProductMatrix\\ProductMatrixBL.cs, DeleteProductMatrixCategory - Begründung: Existenzprüfung vor Delete explizit implementiert\n - [PRIMÄR] src\\backend\\Centron.BL\\ProductMatrix\\ProductMatrixBL.cs, GetCustomerProductMatrixRatingChangeLogByI3D - Begründung: Änderungshistorie als eigenes Entity belegt\nPrüfidee: Delete mit unbekannter I3D → Fehlerresult ohne DB-Zugriff; Logeinträge im Error-Log bei Exception\nTracelinks: frei\nKonsolidierung: Kandidat: Result+Guard+Logger-Muster identisch in Devices/Purchasing-BLs\nÜbernahmewürdigkeit: übernehmen - pflegbares Matrixmodell inkl. Rating-Historie\nStatus: belegt\n\nID: E-10\nTitel: XML-Import von Handelspool-Artikeln mit festem Schema\nEbene: SyRS\nTyp: funktional\nQualitätsmerkmal:\nAkteur: Distributor (DateiLieferant), TradePool-Anwender\nVorbedingung: XML-Datei nach bekanntem Schema liegt auf dem Dateisystem vor\nFakt: `TradePoolBL.StartTradeImport` iteriert Dateien und ruft je Datei `TradePoolXmlLogic.Initialize` + `ImportTradeArticles`; Schema-Konstanten `ROOT_NODE = \"ArticleImport\"`, Artikelknoten mit `HerstCode`, `ArticleEK`, `ArticleStock`, `ArticleEAN` usw.\nAussage: Das System soll Handelspool-Artikeldateien dateiweise gegen das definierte XML-Schema einlesen und die Artikel inkl. EK, Bestand und EAN persistieren\nErgebnis: Importierte Artikel im TradePool, über `GetTradeArticleList` mit Paging/Filter (HersHerstCode/Description) durchsuchbar\nBelege:\n - [PRIMÄR] src\\backend\\Centron.BL\\TradePool\\Core\\TradePoolXmlLogic.cs, Initialize/ArticleNames - Begründung: Schemafestlegung und Dokumentladen in dieser Klasse\n - [PRIMÄR] src\\backend\\Centron.BL\\TradePool\\TradePoolBL.cs, StartTradeImport - Begründung: Importanstoß je Datei mit eigener BL-Session\nPrüfidee: Musterdatei mit zwei Articles importieren → GetTradeArticleList zählt 2; fehlerhaftes XML → definierter Fehler\nTracelinks: frei\nKonsolidierung: Kandidat: DateiImport-Muster mit ArticleImportBL (Warehousing\\ArticleManagement)\nÜbernahmewürdigkeit: Sonderfall - plattform-spezifisches Distributor-XML (TradePool), nur bei Pool-Anbindung relevant\nStatus: belegt\n\nID: E-11\nTitel: Nachvollziehbare Geräteverwaltung mit Soft-Delete und Protokoll\nEbene: SwRS\nTyp: funktional\nQualitätsmerkmal:\nAkteur: Servicemitarbeiter (AppUser)\nVorbedingung: Benutzer mit Mitarbeiterbezug angemeldet; Gerät neu oder vorhanden\nFakt: `AccountDeviceBL.SaveAccountDevice` setzt `CreatedDate/CreatedByI3D` bei Neuanlage, sonst nur `ChangedDate/ChangedByI3D`; `DeleteAccountDevice` setzt nur `IsDeleted = true` und ruft `WriteAccountDeviceLog` auf, das `AccountDeviceLog` mit Zeitstempel und `CreatedByI3D` speichert\nAussage: Das System soll Geräte nie physikalisch löschen, sondern软-löschen und jede Anlage/Änderung/Löschung protokollieren\nErgebnis: Rekonstruierbarer Historienverlauf je Gerät; Standardausblendung gelöschter Geräte in der Suche (`IncludeDeleted == false`)\nBelege:\n - [PRIMÄR] src\\backend\\Centron.BL\\Devices\\AccountDeviceBL.cs, DeleteAccountDevice/WriteAccountDeviceLog - Begründung: Soft-Delete und Protokollschreibung direkt implementiert\n - [PRIMÄR] src\\backend\\Centron.BL\\Devices\\AccountDeviceBL.cs, SearchAccountDevices - Begründung: Ausblendung gelöschter Geräte als Defaultfilter\nPrüfidee: Delete → Datensatz noch vorhanden mit IsDeleted=true; Log enthält „Das Gerät wurde gelöscht\"\nTracelinks: frei\nKonsolidierung: Kandidat: Audit-Log-Muster wie StockRebookLog/ArticleHistoryBL\nÜbernahmewürdigkeit: übernehmen - vorbildliche Nachvollziehbarkeit\nStatus: belegt\n\nID: E-12\nTitel: Schreibgeschützte Artikelkompaktsicht mit generierten Bestandskolonnen\nEbene: SyRS\nTyp: nichtfunktional\nQualitätsmerkmal: ISO/IEC 25010 – Konsistenz (Abgrenzung lesender Sicht auf den Bestand)\nAkteur: alle Module mit Artikellesung\nVorbedingung: Artikel in Tabelle ARTIK vorhanden; Bestandssichten cvw_ArticleCount existieren\nFakt: `ArticleCompactMaps` setzt `this.Table(\"ARTIK\"); this.ReadOnly();`; Feld `Amount` als `Formula(\"(SELECT cvw_ArticleCount.cnt ... LagerI3D = -1)\")`, `OrderInventory`/`DeliveryInventory` als `Generated.Always().ReadOnly()` auf Spalten Auftragsbestand/Lieferbestand\nAussage: Das System soll Artikel-Kompaktdaten aus dem Bestandsumfeld ausschließlich schreibgeschützt bereitstellen und abgeleitete Bestandsgrößen allein aus DB-Sichten/Formeln speisen\nErgebnis: Schreibversuche über dieses Mapping sind ausgeschlossen; Bestandsanzeigen immer konsistent zur DB-Sicht\nBelege:\n - [PRIMÄR] src\\backend\\Centron.DAO\\Mappings\\Merchandise\\Articles\\ArticleCompactMaps.cs, ctor (ReadOnly/Formula) - Begründung: Durchsetzung der Schreibschutz- und Formelregel im NHibernate-Mapping\n - [SEKUNDÄR] src\\backend\\Centron.Entities\\Entities\\Merchandise\\Articles\\ArticleCompact.cs, OrderInventory - Begründung: Kommentar „set through a special nhibernate mapping technik\" und nur Get-Accessor\nPrüfidee: Update-Versuch über ArticleCompact prüfen (NHibernate Flush wirft/ignoriert); Amount-Wert mit cvw_ArticleCount abgleichen\nTracelinks: frei\nKonsolidierung: nein\nÜbernahmewürdigkeit: übernehmen - effiziente, konsistente LESende CQRS-artige Sicht\nStatus: belegt\n\n","metadata":{"parentSessionId":"ses_f9e2f37dbffePXP0P4ACRLx8cN","sessionId":"ses_f9e2d7113ffeNEYJ6TQdEsfWjY","model":{"providerID":"tensorx","modelID":"qwen/qwen3.8-flash-next"},"truncated":false},"title":"Cluster Einkauf/Lager erkunden","time":{"start":1788347584243,"end":1788347770932}},"id":"prt_061d27bc2001eTcFP3yAfSpO22","sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","messageID":"msg_061d20cf1001XgScVNFRWv9B7H"}} +{"type":"tool_use","timestamp":1788347882293,"sessionID":"ses_f9e2f37dbffePXP0P4ACRLx8cN","part":{"type":"tool","tool":"task","callID":"call_35692572caea40af89d697ce","state":{"status":"completed","input":{"description":"Cluster Nexus-Kundenportal","prompt":"Reverse-Requirements-Engineering, NUR lesende Analyse der c-entron ERP-Codebasis im aktuellen Arbeitsverzeichnis (Windows, C#/.NET Blazor). Thoroughness: medium. Du schreibst keine Dateien.\n\nUntersuchte Module (Cluster NEXUS KUNDEN-WEBPORTAL):\n- src\\nexus\\CentronNexus\\WebCart (Shop/Warenkorb/Kundenportal/Tickets für Endkunden; lies WebCartShopPage, WebCartCartPage, CustomerPortal-Unterordner, WebAccount-Logik)\n- src\\nexus\\CentronNexus\\WebOffer\n- src\\backend\\Centron.BL\\SelfCare\n- src\\backend\\Centron.BL\\WebSuite\n- src\\backend\\Centron.BL\\WebVersion\n- src\\backend\\Centron.BL\\WebLinks\n- src\\nexus\\CentronNexus\\Office\n- src\\nexus\\CentronNexus\\DocumentSigning\n\nLies repräsentative .razor/.cs (Routen @page, Berechtigungsattribute, Logs, Preis-/Sonderpreislogik WebCart - README.md erwähnt \"Sonderpreise\"). Erfinde nichts; Pfade müssen real sein.\n\nErgebnis (reiner Text, keine Dateien schreiben):\n1. JE Modul genau eine Inventar-Zeile: MODUL | | \n2. Danach 1-3 Anforderungs-Entwürfe pro Modul (SwRS/SyRS; 1 StRS für Kunden-Selbstbedienungsgeschäftsziel). Strenge Feldreihenfolge:\nID: / Titel / Ebene / Typ / Qualitätsmerkmal / Akteur / Vorbedingung / Fakt / Aussage: Das System soll ... / Ergebnis / Belege: - [PRIMÄR|SEKUNDÄR] src\\...Datei.razor|.cs, Stelle - Begründung / Prüfidee / Tracelinks frei / Konsolidierung / Übernahmewürdigkeit + Halbsatz / Status belegt|HYPOTHESE\n\nWebCart-Zugangs-/Preisregeln = sicherheits-/abrechnungsrelevant: PRIMÄR-Beleg mit durchsetzender Stelle nötig, sonst HYPOTHESE. Deutsch, Zitate max 15 Wörter.","subagent_type":"explore"},"output":"\n\n\n\n# Reverse-Requirements-Analyse – Cluster NEXUS KUNDEN-WEBPORTAL\n\n## 1. Modul-Inventar\n\n- MODUL | src\\nexus\\CentronNexus\\WebCart | Kundenportal für Endkunden (Web-Accounts): Shop mit Artikelsuche, Warenkörbe, Beleg-/Vertragsübersicht, Tickets, Formulare und Kunden-Administration.\n- MODUL | src\\nexus\\CentronNexus\\WebOffer | Token-gesteuerte Web-Ansicht von Angeboten/Belegen (Annahme, Änderungswünsche, Adressänderung, PDF-Vorschau, Bestellauslösung) ohne Login.\n- MODUL | src\\backend\\Centron.BL\\SelfCare | Geschäftslogik für SelfCare-Formulare (Formulare, Zustände, Trigger, Aktionen) und veröffentlichte Web-Anfrage-Seiten als Basis des Kunden-Selbstbedienungsportals.\n- MODUL | src\\backend\\Centron.BL\\WebSuite | Persistente Web-/Portal-Einstellungen pro Benutzer (Web-Account oder Mitarbeiter), globale Settings, Menükonfiguration und Hilfe-Fragen.\n- MODUL | src\\backend\\Centron.BL\\WebVersion | Liefert die Versionsnummer des Webservices aus der aufrufenden Assembly.\n- MODUL | src\\backend\\Centron.BL\\WebLinks | Web-Links und -Link-Gruppen mit ausführbaren Aktionen (z. B. CRM-Eintrag/KontAktivität pro Kontakt).\n- MODUL | src\\nexus\\CentronNexus\\Office | Token-basierte Freigabe-/Unterschriftenstrecken für gemeinsam genutzte Dokumente (Anzeigen, Signieren, Akzeptieren) inkl. PDF-Auslieferung.\n- MODUL | src\\nexus\\CentronNexus\\DocumentSigning | Signaturseite (/contractmanagement) mit Zeichentype/Upload-/Typografie-Signatur, SEPA-Validierung und Bestätigen/Ablehnen von Dokumenten.\n\n## 2. Anforderungs-Entwürfe\n\n---\n\nID: N-1\nTitel: WebCart-Zugang nur für Web-Account-Login über Kundenportal-Port\nEbene: SwRS\nTyp: funktional\nQualitätsmerkmal:\nAkteur: Endkunde (Web-Account)\nVorbedingung: Benutzer hat sich mit einem Web-Account authentisiert; Mandant betreibt den Kundenportal-Port.\nFakt: In `src\\nexus\\CentronNexus\\WebCart\\_Imports.razor` (Zeilen 3–4) stehen modulglobale `@attribute [AuthorizeLoginWebAccount]` und `[AuthorizeCustomerPortalPort]`; die Policy wird in `Shared\\Authorization\\Attributes\\AuthorizeLoginWebAccountAttribute.cs` (Zeile 9) aus `LoginPrefix + WebAccountLoginType` gebildet; serverseitig erzwingt `ReceiptCartBL.SearchArticles` zusätzlich `Guard.Not(currentUser.IsWebAccountLogin is false, ...)` (Zeile 133).\nAussage: Das System soll alle WebCart-/Kundenportal-Seiten ausschließlich für authentisierte Web-Account-Logins und nur über den konfigurierten Kundenportal-Port erreichbar machen und jeden Zugriff sonstiger Login-Arten ablehnen.\nErgebnis: Nicht-Web-Account-Benutzer und unauthentisierte Aufrufer erhalten keinen Seiteninhalt und keine Daten; die Prüfung gilt both client- und serverseitig.\nBelege:\n- [PRIMÄR] src\\backend\\Centron.BL\\Sales\\Receipts\\ReceiptCartBL.cs, Zeile 133 (`Guard.Not(currentUser.IsWebAccountLogin is false, ...)`)\n- [SEKUNDÄR] src\\nexus\\CentronNexus\\WebCart\\_Imports.razor, Zeilen 3–4\n- [SEKUNDÄR] src\\nexus\\CentronNexus\\Shared\\Authorization\\Attributes\\AuthorizeLoginWebAccountAttribute.cs, Zeile 9\nBegründung: Die Attributkette wirkt für alle Seiten des Ordners; die serverseitige Guard-Prüfung in der BL verhindert Umgehung über direkte Service-Aufrufe.\nPrüfidee: Aufruf von `/webcart/shop` und des WebCart-Services als Mitarbeiter-Login und anonym; Erwartung: Redirect/Ablehnung bzw. Guard-Fehlermeldung.\nTracelinks: frei\nKonsolidierung: nein\nÜbernahmewürdigkeit: Direkt übernehmbar, da Zugangsregel mit durchsetzender Stelle eindeutig belegt ist.\nStatus: belegt\n\n---\n\nID: N-2\nTitel: Shop-Sortiment auf aktive Sonderpreise des Kunden beschränken\nEbene: SwRS\nTyp: funktional\nQualitätsmerkmal:\nAkteur: Endkunde (Web-Account)\nVorbedingung: Web-Account ist einem Kunden zugeordnet; der Kunde hat aktive Sonderpreise mit Artikelbezug im Adressstamm gepflegt.\nFakt: `ReceiptCartBL.SearchArticles` lädt `GetSpecialPricesWithArticles()` mit Filter `ShowOnlyActive = true`, `ObjectKind = CustomerClass`, `ObjectI3DList = { WebAccount.CustomerI3D }` (Zeilen 228–244), verwirft die Suche bei leeren Sonderpreisen (Zeilen 145–146) und begrenzt die Artikelsitzungsabfrage mit `specialPriceArticleI3Ds.Contains(f.I3D)` (Zeile 149); ohne Lizenz (`HasLicense()`, Zeile 137, passend zu `[AuthorizeLicense(nameof(LicenseGuids.WebCart2))]` in WebCartShopPage.razor Zeile 3) kommt ein leeres Ergebnis.\nAussage: Das System soll im WebCart-Shop nur Artikel anzeigen, für die der Kunde des angemeldeten Web-Accounts einen aktiven Sonderpreis besitzt, und die Suche sonst ergebnislos beenden.\nErgebnis: Kein Endkunde sieht Artikel außerhalb seines vertraglichen Sonderpreis-Sortiments; Kunden isolieren sich strikt über die CustomerI3D.\nBelege:\n- [PRIMÄR] src\\backend\\Centron.BL\\Sales\\Receipts\\ReceiptCartBL.cs, Zeilen 144–149 und 228–245\n- [SEKUNDÄR] README.md, Zeile 35 („The available articles come from the customers ‚Sonderpreise‘\")\n- [SEKUNDÄR] src\\nexus\\CentronNexus\\WebCart\\WebCartShopPage.razor, Zeile 3\nBegründung: README beschreibt die Fachregel; die serverseitige Query-Einschränkung in ReceiptCartBL ist die tatsächlich durchsetzende Stelle inkl. Mandanten-/Kundenisolation.\nPrüfidee: Zwei Kunden mit unterschiedlichen Sonderpreisen anlegen; Suche je Web-Account ausführen; Erwartung: Ergebnismengen sind disjunkt und gleich der Sonderpreis-Artikelmenge.\nTracelinks: frei\nKonsolidierung: nein\nÜbernahmewürdigkeit: Hoch, da abrechnungsrelevant und mit BL-seitiger Erzeugungsstelle belegt.\nStatus: belegt\n\n---\n\nID: N-3\nTitel: Kundenspezifische Preisberechnung im Shop mit Rabatttransparent\nEbene: SwRS\nTyp: funktional\nQualitätsmerkmal:\nAkteur: Endkunde (Web-Account)\nVorbedingung: Artikel wurde gefunden (N-2); Preisstammdaten des Kunden (Konditionen/Sondervereinbarungen) sind gepflegt.\nFakt: `ReceiptCartBL.SearchArticles` berechnet je Artikel `GetSpecialAgreement(...)`/`GetBasePrice(...)` und liefert `ListPrice`/`ListPriceDiscountInPercent` nur bei `SpecialPriceKind.ReduceListPrice` sowie `CalculatedPrice = ReceiptPriceHelper.CalculateNetPrice(price.basePrice, ..., currencyFactor ...)` (Zeilen 178–206); WebCartShopPage.razor zeigt per Flyout „Listenpreis\"/„Rabatt\" und Hinweis „Und weitere Rabatte\" bei Abweichung (Zeilen 164–211).\nAussage: Das System soll im Shop den kundenspezifisch berechneten Nettopreis (inkl. Währungsfaktor) anzeigen und bei Sonddpreisart „Listenpreis reduziert\" Listenpreis und Rabatt nachvollziehbar ausweisen.\nErgebnis: Der Kunde sieht verbindliche, kundenspezifische Preise; zusätzliche Rabatte werden transparent gemacht, ohne den Kalkulationspfad offenzulegen.\nBelege:\n- [PRIMÄR] src\\backend\\Centron.BL\\Sales\\Receipts\\ReceiptCartBL.cs, Zeilen 178–206\n- [SEKUNDÄR] src\\nexus\\CentronNexus\\WebCart\\WebCartShopPage.razor, Zeilen 164–211 (`OnPriceMouseOver`, Flyout)\nBegründung: Die Preiserzeugung erfolgt ausschließlich serverseitig in der BL; die UI gibt nur die gelieferten DTO-Felder wieder.\nPrüfidee: Artikel mit ReduceListPrice-Sonderpreis und hinterlegter Sondervereinbarung anlegen; gelieferten `CalculatedPrice` gegen expected BasePrice/Rabatt-Rechnung (inkl. CurrencyFactor) prüfen.\nTracelinks: frei\nKonsolidierung: Kandidat (mit N-2 zu „WebCart-Sortiment und -Preisstellung\" zusammenziehbar)\nÜbernahmewürdigkeit: Übernehmbar als abrechnungsrelevante Regel; Details der Preishierarchie (Sondervereinbarungsauflösung) bleiben aus dieser Stelle teilweise HYPOTHESE.\nStatus: belegt (Teilaspekt Sondervereinbarungs-Priorisierung: HYPOTHESE)\n\n---\n\nID: N-4\nTitel: Bestellrecht und Warenkorb-Freigabestufe erzwingen Warenkorb-Bestellung\nEbene: SwRS\nTyp: funktional\nQualitätsmerkmal:\nAkteur: Endkunde (Web-Account mit/ohne Bestellrecht), Kundenadministrator\nVorbedingung: Warenkorb existiert und hat Status „bereit zur Prüfung\" bzw. „geprüft\".\nFakt: `ReceiptCartBL` prüft `currentUser.WebAccount.WebRights.Any(f => f.I3D is (int)WebAccountRightsConst.WEBRIGHT_WEBCART2_ORDER_CART)` und lehnt ab, wenn „cartIsReadyForCheck\" ohne Prüf-/Bestellrecht bzw. „cartIsChecked\" ohne Bestellrecht bestellt werden soll (Zeilen 859–864); `SaveUser` erzwingt `EnsureWebAccountRight(..., WEBRIGHT_WEBCART2_ORDER_CART)` (Zeile 670); die Kundenverwaltung ist über `WebCartAdminPage.razor` (Zeilen 3–4, `[AuthorizeLicense(WebCart2)]` + `[AuthorizeWebRight(CUSTOMERADMINISTRATOR)]`) abgesichert, Rechtezuweisung über `UserViewModel` (`HasCheckCartRight`, `HasOrderCartRight`, `HasCustomerAdministratorRight`, Zeilen 52–56) mit Passwortmindestlänge 8 (Zeile 33).\nAussage: Das System soll das Bestellen eines Warenkorbs zwingend an das Web-Recht „Warenkorb bestellen\" binden, die Prüfstufe des Warenkorbs berücksichtigen und die Rechteverwaltung nur dem Kundenadministrator zugänglich machen.\nErgebnis: Bestellungen sind rechtlich dem Kreis bestellberechtigter Endbenutzer vorbehalten; Vier-Augen-Kunden (Prüfen vor Bestellen) werden erzwungen.\nBelege:\n- [PRIMÄR] src\\backend\\Centron.BL\\Sales\\Receipts\\ReceiptCartBL.cs, Zeilen 859–864 und 670\n- [SEKUNDÄR] src\\nexus\\CentronNexus\\WebCart\\WebCartAdminPage.razor, Zeilen 3–4\n- [SEKUNDÄR] src\\nexus\\CentronNexus\\WebCart\\Helpers\\UserViewModel.cs, Zeilen 33, 52–56\nBegründung: Die Rechteprüfung sitzt in der BL (nicht nur UI) und ist damit die durchsetzende Stelle; die Admin-Seite liefert die Verwaltungsseite der Rechte.\nPrüfidee: Bestellung eines geprüften Warenkorbs mit Benutzer ohne ORDER-CART-Recht simulieren; Erwartung: Fehler; mit Recht: Erfolg inkl. interner Meldeadresse (`WebCartCartOrderedInternalEmailReceiver`, Zeile 100).\nTracelinks: frei\nKonsolidierung: nein\nÜbernahmewürdigkeit: Direkt übernehmbar (abrechnungs- und sicherheitsrelevant, BL-seitig belegt).\nStatus: belegt\n\n---\n\nID: N-5\nTitel: Ticketansicht im Kundenportal nach Web-Rechten differenzieren\nEbene: SwRS\nTyp: funktional\nQualitätsmerkmal:\nAkteur: Endkunde (Web-Account)\nVorbedingung: Web-Account besitzt eines der Rechte „Alle Anfragen sehen\", „Nur eigene Anfragen sehen\" oder „Kundenadministrator\".\nFakt: `WebCartTicketsPage.razor` (Zeile 4) und `CustomerTicketDetailsPage.razor` (Zeile 4) tragen `[AuthorizeWebRight(SHOWALLEREQUESTS, SHOWONLYOWNREQUESTS, CUSTOMERADMINISTRATOR)]`; `CustomerPortalPublicDocumentsPage.razor` (Zeile 5) verlangt `WEBRIGHT_RIVERSUITE_MANAGE_DOCUMENTS`; `CustomerPortalFormsPage.razor` logt Laden/Ausfall (`Logger.LogInformation(\"Lade kategorisierte Ticketvorlagen...\")` Zeile 171, Fehler-Log Zeile 193) und lädt Vorlagen über `CentronService.GetCategorizedTicketPatterns()` (Zeile 181).\nAussage: Das System soll Ticketlisten und Ticketdetails im Kundenportal nur bei Besitz eines der drei Ticket-Rechte öffnen und dem Benutzer nur die zulässigen Sichten (eigene vs. alle) anzeigen.\nErgebnis: Endkunden sehen ausschließlich freigegebene Ticketbestände; Zugriffe ohne Recht werden abgewiesen.\nBelege:\n- [PRIMÄR] src\\nexus\\CentronNexus\\WebCart\\CustomerTicketDetailsPage.razor, Zeile 4 (`[AuthorizeWebRight(...)]`)\n- [SEKUNDÄR] src\\nexus\\CentronNexus\\WebCart\\WebCartTicketsPage.razor, Zeile 4\n- [SEKUNDÄR] src\\nexus\\CentronNexus\\WebCart\\CustomerPortalFormsPage.razor, Zeilen 171–193\nBegründung: Das Rights-Attribut erzwingt die Prüfung auf Routenebene; die Aufteilung „eigene vs. alle\" wurde in den gerouteten Attributen nur als Rechte-Alternativliste sichtbar, die Filterlogik selbst wurde nicht im Detail nachgewiesen.\nPrüfidee: Web-Account nur mit SHOWONLYOWNREQUESTS anlegen; Erwartung: Detailseite fremder Tickets nicht einsehbar.\nTracelinks: frei\nKonsolidierung: Kandidat (mit N-1 gemeinsam als Zugriffsrechte-Familie des Portals)\nÜbernahmewürdigkeit: Übernehmbar; die Datenfilterung „nur eigene Tickets\" ist aus den gelesenen Stellen noch HYPOTHESE.\nStatus: belegt (Filtertiefenlogik: HYPOTHESE)\n\n---\n\nID: N-6\nTitel: SelfCare-Formular im Kundenportal aus Ticketvorlage erzeugen Ticket\nEbene: SwRS\nTyp: funktional\nQualitätsmerkmal:\nAkteur: Endkunde (Web-Account)\nVorbedingung: Ticketvorlage/SelfCare-Formular ist veröffentlicht (Kategorienbaum vorhanden).\nFakt: `CustomerPortalFormFillPage.razor` (Route `/customerportal/forms/{PatternI3D:int}`, Zeile 1) läd `_ticketPattern = await CentronService.GetTicketPatternByI3D(PatternI3D)` (Zeile 148) und erzeugt per `CentronService.CreateHelpdeskFromHelpdeskPattern(ticketPattern)` (Zeile 231) ein Helpdesk-Ticket; `SelfCareBL.cs` verwaltet `SelfCareForm`, `SelfCareFormState`, `SelfCareFormTrigger`, `SelfCareFormAction` (Zeilen 47–149); `WebRequestPageBL.GetWebRequestPageByGuid` liefert veröffentlichte Anfrage-Seiten (`filter.Published`, Zeilen 36–49, 82–83).\nAussage: Das System soll dem Endkunden das Ausfüllen konfigurierter SelfCare-Formulare ermöglichen und daraus automatisch ein Helpdesk-Ticket ableiten.\nErgebnis: Standardisierte Kundenanliegen erreichen ohne manuelle Erfassung das Helpdesk-System; Formulare sind per `Published`-Schalter steuerbar.\nBelege:\n- [PRIMÄR] src\\backend\\Centron.BL\\SelfCare\\SelfCareBL.cs, Zeilen 47–149\n- [SEKUNDÄR] src\\nexus\\CentronNexus\\WebCart\\CustomerPortalFormFillPage.razor, Zeilen 1, 148, 231\n- [SEKUNDÄR] src\\backend\\Centron.BL\\SelfCare\\WebRequestPageBL.cs, Zeilen 36–49\nBegründung: BL-Teil („SelfCare Actions\": Trigger/Aktionen) wurde nur in der Signatur nachgewiesen; die Trigger→Ticket-Ausführungskette wurde in den gelesenen Dateien nicht vollständig verfolgt.\nPrüfidee: veröffentlichtes Formular ausfüllen und absenden; Erwartung: neues Helpdesk-Ticket mit Mustereferenz; unveröffentlichtes Formular nicht im Baum sichtbar.\nTracelinks: frei\nKonsolidierung: nein\nÜbernahmewürdigkeit: Übernehmbar für Formular→Ticket-Kern; Trigger/Aktions-Semantik vor Übernahme zu verifizieren.\nStatus: teilweise HYPOTHESE\n\n---\n\nID: N-7\nTitel: Token-basierte Web-Angebotsansicht ohne Login\nEbene: SyRS\nTyp: funktional\nQualitätsmerkmal:\nAkteur: Angebotsempfänger (extern, unauthentisiert)\nVorbedingung: Angebot wurde versendet; der Link enthält ein gültiges Receipt-Access-Token.\nFakt: `WebReceiptOverview.razor` deklariert `@page \"/weboffer/{Token}\"` mit `@layout EmptyLayout` und ohne Authorize-Attribut; `WebReceiptPdfPreview.razor` analog `/weboffer/{Token}/pdfpreview`; serverseitig gilt in `ReceiptWebServiceBL`: `Guard.NotNullOrWhiteSpace(token, ...)` und sonst `throw new Exception($\"Mit diesem Token {token} wurde kein zugehöriger Beleg gefunden.\")` (Kontext Zeile 3203); Zustandswechsel laufen über `ChangeWebReceiptState(string token, WebReceiptState ...)` (Zeile 3163).\nAussage: Das System soll einem Angebotsempfänger allein anhand des Tokens die Ansicht, PDF-Vorschau, Kommentar-, Adress- und Zustandsfunktionen des Angebots bereitstellen und ungültige Tokens ablehnen.\nErgebnis: Loginfreie Angebotsbearbeitung ist an die Gültigkeit des Tokens gebunden; unbekannte Tokens erzeugen Fehler statt Daten.\nBelege:\n- [PRIMÄR] src\\backend\\Centron.BL\\WebServices\\Sales\\Receipts\\ReceiptWebServiceBL.cs, Zeilen 3163–3218 und Token-Guard um Zeile 3203\n- [SEKUNDÄR] src\\nexus\\CentronNexus\\WebOffer\\WebReceiptOverview.razor, Zeilen 1–3 (`@page \"/weboffer/{Token}\"`)\nBegründung: Das Token ist das einzige Zugangskriterium; die durchsetzende Prüfung liegt im WebServiceBL-Guard.Token-Erzeugung/-Gültigkeit/-Ablauf wurden aus den gelesenen Stellen nicht nachgewiesen.\nPrüfidee: Bekanntes Token aufrufen (Erfolg), manipuliertes/unbekanntes Token (Fehlermeldung „kein zugehöriger Beleg\"); Ratefestigkeit des Tokens separat prüfen.\nTracelinks: frei\nKonsolidierung: Kandidat (mit N-8, da gemeinsame Token-Signierstrecke)\nÜbernahmewürdigkeit: Übernehmbar, aber vor Übernahme um Token-Lebenszyklus-Annahmen (HYPOTHESE) zu präzisieren.\nStatus: teilweise HYPOTHESE\n\n---\n\nID: N-8\nTitel: Signatur- und Akzeptanzstrecke für gemeinsam genutzte Dokumente\nEbene: SwRS\nTyp: funktional\nQualitätsmerkmal:\nAkteur: Externer Dokumentempfänger (Token-Inhaber)\nVorbedingung: Dokument wurde per Freigabe-Token versendet (`SharedDocumentWebServiceBL.GenerateTokenForDocument`).\nFakt: Routen `/shareddocuments/{Token}`, `.../sign`, `.../acceptance` (SharedDocumentPage/-SignPage/-AcceptancePage.razor, jeweils Zeile 1, `EmptyLayout`); `DocumentSigningPage.razor` (`@page \"/contractmanagement\"`, Guid per Query) verlangt für `CanAccept`: Signatur (Zeichnen/Typ/Upload) plus bei SEPA `HasBankData` mit `IsValidIban(_iban)`; Abschluss über `CentronService.ConfirmOnlinePdfDocument(...)` / `DeclineOnlinePdfDocument(...)` (Zeilen 695–746); serverseitig `SendMailForSigning(...)` mit Token-Erzeugung in ReceiptWebServiceBL Zeilen 1898–1918.\nAussage: Das System soll die Annahme/Unterschrift eines freigegebenen Dokuments von einer vollständigen Signatur (bzw. SEPA-Vollständigkeit inkl. IBAN-Validierung) abhängig machen und Ablehnung ausdrücklich erfassen.\nErgebnis: Dokumente gelten erst nach vollständiger, validierter Unterschrift als angenommen; SEPA-Verträge erfordern Bankdaten.\nBelege:\n- [PRIMÄR] src\\nexus\\CentronNexus\\DocumentSigning\\DocumentSigningPage.razor, `CanAccept`/`HasBankData`/@code-Block\n- [SEKUNDÄR] src\\backend\\Centron.BL\\WebServices\\Sales\\Receipts\\ReceiptWebServiceBL.cs, Zeilen 1898–1918\n- [SEKUNDÄR] src\\nexus\\CentronNexus\\Office\\SharedDocumentSignPage.razor, Zeile 1\nBegründung: Die Accept-Verknüpfung ist UI-seitig eindeutig belegt; die eigentliche Server-Validierung (erneute Prüfung außerhalb der UI) wurde nicht nachgewiesen.\nPrüfidee: SEPA-Dokument ohne IBAN annehmen wollen (erwartet: blockiert); dokumentierter Happy-Path mit Bestätigung; Serveraufruf `ConfirmOnlinePdfDocument` ohne Signaturdaten prüfen.\nTracelinks: frei\nKonsolidierung: Kandidat (mit N-7)\nÜbernahmewürdigkeit: Übernehmbar; rein clientseitige Guard-Checks wären Sicherheitsrisiko – serverseitige Nachprüfung verifizieren.\nStatus: teilweise HYPOTHESE\n\n---\n\nID: N-9\nTitel: Benutzerbezogene Web-Einstellungen nach Login-Art trennen\nEbene: SwRS\nTyp: funktional\nQualitätsmerkmal:\nAkteur: Web-Account-Benutzer, Mitarbeiter\nVorbedingung: Benutzer ist eingeloggt; persönliche oder globale Web-Einstellungen existieren.\nFakt: `WebSettingBL.GetWebSettingFromCurrentUser` verzweigt auf `user.IsWebAccountLogin` mit Filter `f.WebAccountI3D == user.WebAccount.I3D` sonst `f.EmployeeI3D == ...` und fällt auf globale Startseiten-Settings ohne Benutzerbezug zurück (Zeilen 29–59); `WebMenuConfigBL.DoBeforeSave` validiert `Caption`/`Position >= 0` (Zeilen 34–35) und vergibt automatisch Position `Max+1` je Gruppe (Zeilen 46–50).\nAussage: Das System soll Web-Einstellungen strikt nach Login-Art (Web-Account vs. Mitarbeiter) getrennt laden und Menüeinträge nur bei gültiger Beschriftung und Position speichern.\nErgebnis: Kunden sehen keine mitarbeiterbezogenen Einstellungen und umgekehrt; Menükonfiguration bleibt konsistent sortiert.\nBelege:\n- [PRIMÄR] src\\backend\\Centron.BL\\WebSuite\\Administration\\Settings\\WebSettingBL.cs, Zeilen 29–59\n- [SEKUNDÄR] src\\backend\\Centron.BL\\WebSuite\\Administration\\Settings\\WebMenuConfigBL.cs, Zeilen 34–50\nBegründung: Die Trennlogik ist die einzige Lesequelle für benutzerspezifische Web-Settings und damit durchsetzende Stelle.\nPrüfidee: WebSetting mit WebAccountI3D setzen und als Mitarbeiter abfragen (erwartet: nicht sichtbar); Menüeintrag ohne Caption speichern (erwartet: Result-Error).\nTracelinks: frei\nKonsolidierung: nein\nÜbernahmewürdigkeit: Übernehmbar als Konfigurationsisolations-Regel.\nStatus: belegt\n\n---\n\nID: N-10\nTitel: Weblink-Aktion erzeugt CRM-Aktivität mit Betreuerzuordnung\nEbene: SwRS\nTyp: funktional\nQualitätsmerkmal:\nAkteur: System (Weblink-Ausführung), Mitarbeiter\nVorbedingung: Weblink-Aktion vom Typ „CRMEntry\" ist konfiguriert; Zielkontakt existiert.\nFakt: `WebLinkActionAccountActivityHandler` meldet `WebLinkActionType Type => WebLinkActionType.CRMEntry` (Zeile 24), protokolliert Fehler per NLog (`_logger.Log(LogLevel.Error, ...)`, Zeilen 30, 44, 57) und scheitert mit `Result.AsError`, wenn Kontakt fehlt oder „has no advisor 1\" (Zeilen 28–32, 55–59); `WebLinkBL` registriert den Handler und parst `action.Options` als JSON (`AccountActivityOptions`).\nAussage: Das System soll bei Ausführung einer CRMEntry-Weblink-Aktion eine Kontaktaktivität anlegen, die dem Betreuer 1 des Kontakts zugeordnet ist, und Fehler protokollieren statt still zu verschlucken.\nErgebnis: Weblink-Aufrufe hinterlassen nachvollziehbare CRM-Aktivitäten; Konfigurationsfehler werden geloggt und als Fehler zurückgemeldet.\nBelege:\n- [PRIMÄR] src\\backend\\Centron.BL\\WebLinks\\WebLinkActionAccountActivityHandler.cs, Zeilen 24–59\n- [SEKUNDÄR] src\\backend\\Centron.BL\\WebLinks\\WebLinkBL.cs, Zeilen 32–39\nBegründung: Handler ist die Ausführungsstelle inkl. Betreuer-Auflösung (AdviserType-Switch ab Zeile 50) und Logging.\nPrüfidee: CRMEntry-Aktion auf Kontakt ohne Adviser1 ausführen; Erwartung: Result-Error + NLog-Eintrag; mit Adviser1: Aktivität angelegt.\nTracelinks: frei\nKonsolidierung: nein\nÜbernahmewürdigkeit: Übernehmbar, wenn der Cluster WebLinks fachlich übernommen wird (Portalnumfeld nur mittelbar).\nStatus: belegt\n\n---\n\nID: N-11\nTitel: WebService-Versionsauskunft\nEbene: SwRS\nTyp: funktional\nQualitätsmerkmal: NF: Funktionaler Durchsatz/Kompatibilität i.S.v. ISO/IEC 25010 Kompatibilität – hier: leeres Feld, da kein NF-Ziel belegt\nAkteur: Web-Clients (Nexus/Frontends)\nVorbedingung: Webservice ist erreichbar.\nFakt: `VersionBL.GetWebserviceVersion()` liefert `AssemblyLogic.GetFromAssemblyContaining()` (einzige Methode der Klasse, src\\backend\\Centron.BL\\WebVersion\\VersionBL.cs Zeilen 10–14).\nAussage: Das System soll die aktuelle Version des Webservices aus der Assembly-Metadatenquelle für kompatible Web-Clients auslesbar bereitstellen.\nErgebnis: Clients/Support können die Serverversion identifizieren (z.B. Versions-Check des Portals).\nBelege:\n- [PRIMÄR] src\\backend\\Centron.BL\\WebVersion\\VersionBL.cs, Zeilen 10–14\nBegründung: Vollständiger Funktionsumfang der Klasse; kein weiterer Kontext belegt.\nPrüfidee: Aufruf des Version-Endpunkts; Rückgabewert gegen AssemblyVersion vergleichen.\nTracelinks: frei\nKonsolidierung: nein\nÜbernahmewürdigkeit: Randständig; nur mit Versions-Check-Thema im SyRS-Strang übernehmbar.\nStatus: belegt\n\n---\n\nID: N-12\nTitel: PDF-Auslieferung für Office-Freigabeseiten\nEbene: SyRS\nTyp: funktional\nQualitätsmerkmal:\nAkteur: Externer Dokumentempfänger\nVorbedingung: Datei liegt im Nexus-Cache.\nFakt: `PdfController` exponiert `[HttpGet(\"getcachedfile/{id}/{filename}\")]` (src\\nexus\\CentronNexus\\Office\\Controllers\\PdfController.cs Zeilen 13–15); `Office\\Components\\FilePreview.razor` bettet die URL in ein `