From ea1f3caff7fc302f3e11d5529d015049ecf4495a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20Schw=C3=B6rer?= Date: Thu, 27 Aug 2026 19:22:37 +0200 Subject: [PATCH] more runs before cline --- Versuche/AblaufProtokoll.md | 114 +- .../Ergebnisse/Analysebericht.md | 615 ++ .../Ergebnisse/Glossar.md | 211 + .../Ergebnisse/Hypothesen.md | 24 + .../Ergebnisse/StRS.md | 1201 ++++ .../Ergebnisse/SwRS.md | 5552 +++++++++++++++++ .../Ergebnisse/SyRS.md | 2893 +++++++++ .../Ergebnisse/Traceability.md | 324 + .../RawResult.json | 1 + .../Stderr.log | 0 .../_meta/before.txt | 1 + .../_meta/combined_prompt.md | 178 + .../_meta/endzeit.txt | 1 + .../_meta/startzeit.txt | 1 + .../Ergebnisse/Analysebericht.md | 606 ++ .../Ergebnisse/Glossar.md | 70 + .../Ergebnisse/Hypothesen.md | 30 + .../Ergebnisse/StRS.md | 778 +++ .../Ergebnisse/SwRS.md | 1784 ++++++ .../Ergebnisse/SyRS.md | 3708 +++++++++++ .../Ergebnisse/Traceability.md | 199 + .../Protokoll.md | 165 + .../RawResult.json | 1 + .../Stderr.log | 0 .../_meta/after.txt | 0 .../_meta/anforderungen.json | 5034 +++++++++++++++ .../_meta/anforderungen.md | 65 + .../_meta/before.txt | 1 + .../_meta/combined_prompt.md | 177 + .../_meta/endzeit.txt | 1 + .../_meta/startzeit.txt | 1 + .../RawResult.json | 1 + .../Stderr.log | 0 .../_meta/before.txt | 1 + .../_meta/combined_prompt.md | 178 + .../_meta/endzeit.txt | 1 + .../_meta/startzeit.txt | 1 + .../RawResult.json | 1 + .../Stderr.log | 0 .../_meta/before.txt | 1 + .../_meta/combined_prompt.md | 178 + .../_meta/endzeit.txt | 1 + .../_meta/startzeit.txt | 1 + .../Ergebnisse/Analysebericht.md | 327 + .../Ergebnisse/Glossar.md | 32 + .../Ergebnisse/Hypothesen.md | 15 + .../Ergebnisse/StRS.md | 2398 +++++++ .../Ergebnisse/SwRS.md | 166 + .../Ergebnisse/SyRS.md | 207 + .../Ergebnisse/Traceability.md | 139 + .../Protokoll.md | 165 + .../RawResult.json | 1 + .../Stderr.log | 0 .../_meta/after.txt | 0 .../_meta/anforderungen.json | 2616 ++++++++ .../_meta/anforderungen.md | 65 + .../_meta/before.txt | 1 + .../_meta/combined_prompt.md | 177 + .../_meta/endzeit.txt | 1 + .../_meta/startzeit.txt | 1 + 60 files changed, 30406 insertions(+), 5 deletions(-) create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/Analysebericht.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/Glossar.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/Hypothesen.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/StRS.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/SwRS.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/SyRS.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/Traceability.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/RawResult.json create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Stderr.log create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/_meta/before.txt create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/_meta/combined_prompt.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/_meta/endzeit.txt create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/_meta/startzeit.txt create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/Analysebericht.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/Glossar.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/Hypothesen.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/StRS.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/SwRS.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/SyRS.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/Traceability.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Protokoll.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/RawResult.json create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Stderr.log create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/_meta/after.txt create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/_meta/anforderungen.json create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/_meta/anforderungen.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/_meta/before.txt create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/_meta/combined_prompt.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/_meta/endzeit.txt create mode 100644 Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/_meta/startzeit.txt create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_110958_v7.0.0-7499/RawResult.json create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_110958_v7.0.0-7499/Stderr.log create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_110958_v7.0.0-7499/_meta/before.txt create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_110958_v7.0.0-7499/_meta/combined_prompt.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_110958_v7.0.0-7499/_meta/endzeit.txt create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_110958_v7.0.0-7499/_meta/startzeit.txt create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_124836_v7.0.0-cf3c/RawResult.json create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_124836_v7.0.0-cf3c/Stderr.log create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_124836_v7.0.0-cf3c/_meta/before.txt create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_124836_v7.0.0-cf3c/_meta/combined_prompt.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_124836_v7.0.0-cf3c/_meta/endzeit.txt create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_124836_v7.0.0-cf3c/_meta/startzeit.txt create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/Analysebericht.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/Glossar.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/Hypothesen.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/StRS.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/SwRS.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/SyRS.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/Traceability.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Protokoll.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/RawResult.json create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Stderr.log create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/after.txt create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/anforderungen.json create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/anforderungen.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/before.txt create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/combined_prompt.md create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/endzeit.txt create mode 100644 Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/startzeit.txt diff --git a/Versuche/AblaufProtokoll.md b/Versuche/AblaufProtokoll.md index c4ef0695..c324983a 100644 --- a/Versuche/AblaufProtokoll.md +++ b/Versuche/AblaufProtokoll.md @@ -30,7 +30,7 @@ gleichen Bedingungen streuen. --- -## 2. Chronologie in sieben Phasen +## 2. Chronologie in acht Phasen ### Phase 1 – Erster Lauf und die Entdeckung der Werkzeugkonfiguration (12:29–13:00) @@ -473,6 +473,99 @@ herstellbar; für V3 sind die Serverversionen nicht gepinnt, und der Zustand des – Datenbankstand, Mandant, Datenart – ist als Teil des Untersuchungsgegenstands je Lauf zu erfassen. +### Phase 8 – Rastererweiterung, Kontingentgrenzen und der Wechsel auf serielle Läufe (26.–27.08.) + +Iteration 3 belegte zu Beginn dieser Phase erst **4 von 12 Zellen** des aufgespannten Rasters aus +drei Modellen, zwei Agentenmodi und zwei Effort-Stufen. Ziel war, je einen Lauf für die fehlenden +Kombinationen zu erheben. + +**Der erste Anlauf scheiterte vollständig – an der Parallelität.** Vier gleichzeitig gestartete +Läufe (19:59) liefen sämtlich in HTTP 429, „You've hit your session limit". Zusammen hatten sie +bis dahin **297,4 Mio. Tokens** verbraucht, davon allein 204,4 Mio. in `opus-5/builtin/high`. Drei +der vier hatten Teilergebnisse erzeugt, bevor das Kontingent riss – zwischen einer und drei von +sieben Dateien; sie sind als Fehlmessungen mit Teilbestand protokolliert und gehen in keinen +Vergleich ein. + +Daraus folgte die Umstellung auf **strikt serielle Läufe**. Sie hat einen messtechnischen +Nebeneffekt, der über die Kontingentfrage hinausreicht: Seit dem seriellen Lauf `d6f9` waren +sämtliche Wanduhrzeiten entweder durch Parallelbetrieb oder durch Kontingent-Wartezeiten +verzerrt. Serielle Läufe machen die Laufzeit wieder zu einer verwertbaren Messgröße. + +**Zwei neue Zellen sind seriell entstanden und gültig:** + +| Zelle | Anf. | StRS/SyRS/SwRS | Primärbeleg | Belege/Anf. | Tokens | Wanduhr | +|---|---:|---|---:|---:|---:|---:| +| `opus-5/solo/high` | 363 | 62/132/169 | **99,7 %** | **2,0** | 38,1 Mio. | 26 min | +| `fable-5/solo/high` | 241 | 33/50/158 | 98,3 % | 1,0 | 30,6 Mio. | 7:03 h\* | + +\*Kontingent-Wartezeit, siehe unten. + +**Befund: Die Belegdichte folgt dem Modell, nicht dem Effort.** In Phase 7 war die verdoppelte +Belegdichte – Median 2,0 statt 1,0 – dem `max`-Effort zugeschrieben worden, weil alle 44 +vorherigen `high`-Läufe bei Median 1,0 lagen. `opus-5/solo/high` erreicht Median **2,0 auf +`high`**. Die 44 Läufe mit Median 1,0 liefen sämtlich auf Sonnet, die `max`-Läufe auf Opus – die +beiden Variablen waren konfundiert. Nach jetzigem Stand: + +| Modell | `high` | `max` | +|---|---:|---:| +| Sonnet | 1,0 | – | +| Fable | 1,0 | – | +| Opus | **2,0** | **2,0–3,0** | + +Der Effort bleibt für den **Verbrauch** wirksam (38,1 Mio. auf `high` gegenüber 67,5–116,2 Mio. +auf `max`), für die Belegdichte ist das Modell die stärkere Größe. + +**Befund: Die Fable-Modellverletzung ist reproduziert – und abgegrenzt.** Der Lauf +`fable-5/builtin/high` wies erneut `claude-opus-5[1m]` in `modelUsage` aus, wie schon in +Iteration 1 unter anderer Prompt-Version und anderem Snapshot. Der Lauf `fable-5/solo/high` +dagegen ist sauber: ausschließlich `claude-fable-5` plus Haiku. Damit steht fest: **Nicht Fable +ist die Ursache, sondern Fable in Kombination mit Delegation.** Sonnet und Opus werden an die +Subagenten durchgereicht, Fable nicht; die CLI fällt dann auf die Sitzungsvorgabe +`model: opus[1m]` aus `~/.claude/settings.json` zurück. + +**`opus-5/builtin/high` ist zum dritten Mal gescheitert.** Über drei Anläufe zusammen +**790,7 Mio. Tokens ohne ein einziges verwertbares Artefakt**: + +| Lauf | Abbruch | Subagenten | Tokens | +|---|---|---:|---:| +| `116d` | 600-s-Zeitlimit für Hintergrund-Subagenten | 20 (10 verschachtelt) | 193,4 | +| `9d9e` | Kontingent (429) | 34 (24 verschachtelt) | 392,9 | +| `45dd` | Kontingent (429) | 24 | 204,4 | + +Jedes Mal dasselbe Muster: Opus zerlegt die Aufgabe in 20 bis 34 Subagenten, beendet seinen +eigenen Turn nach einem einzigen Turn und überlässt die Arbeit den Hintergrundagenten. Die +Korrektur des Zeitlimits (`CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS=0`) beseitigte die erste Ursache; +die Delegationsbreite riss dann das Kontingent. **Die Zelle ist mit dieser Prompt-Version und +diesem Modell nicht messbar** – drei reproduzierbare Ausfälle sind als Grenzbefund über die +Delegation aussagekräftiger als ein vierter Versuch. + +**Ein dritter Verzerrungsmechanismus der Zeitmessung.** `fable-5/solo/high` brauchte 7:03:44 +Wanduhrzeit, ohne parallel zu laufen. Die Abstände zwischen den Werkzeugaufrufen zeigen den +Grund: Lücken von 4:00 h und zweimal rund 2 h. Bei erschöpftem Kontingent **bricht die CLI nicht +ab, sondern wartet auf das nächste Reset-Fenster** und arbeitet dann weiter. `duration_ms` bildet +diese Wartezeit mit ab. Neben Parallelbetrieb und Abbruch ist das die dritte Ursache unbrauchbarer +Zeitangaben – und die einzige, die von außen wie ein hängender Prozess aussieht. Tokenverbrauch, +Anforderungszahl und Belegkennzahlen sind davon nicht betroffen. + +**Verbrauchsbilanz der Reihe.** Über beide Tage: 42 abgeschlossene Läufe, **2.294,7 Mio. Tokens**, +davon am 26.08. allein 1.703,6 Mio. mit fünf Fehlmessungen. Rund 880 Mio. Tokens – gut ein Drittel +des Gesamtverbrauchs – entfielen auf Läufe ohne verwertbares Ergebnis. + +**Codex-Lauf verworfen.** Der Lauf `Iteration 5/gpt-5.6-sol/solo/high/…-54dd` stand seit +13,5 Stunden ohne Fortschritt und ohne `RawResult.json`; die Arbeitskopie lag zudem mit 352 MB im +Laufverzeichnis statt im System-Temp-Verzeichnis, wie Skill 6.0.0 es vorsieht. Prozesse beendet, +Lauf gelöscht. Der Neustart steht aus: Die Codex-CLI ist inzwischen auf **0.150.0-alpha.8**, der +Referenzstand des Adapters ist **0.149.0-alpha.4.3**. Der Skill verlangt bei geändertem +JSONL-Schema einen Smoke-Test des Normalisierers **vor** dem Messlauf – sonst endet ein +mehrstündiger Lauf mit nicht parsbaren Rohdaten. + +**Serielle Kette gestartet (27.08., 08:12).** Sechs offene Zellen, günstigste zuerst, damit bei +einem Kontingentabbruch möglichst viele belegt sind: `fable/solo/max`, `sonnet/solo/max`, +`fable/builtin/high`, `sonnet/builtin/max`, `fable/builtin/max`, `opus/builtin/max`. Die Kette +wartet bei einem 429 einmal 70 Minuten und wiederholt dieselbe Zelle; beim zweiten 429 bricht sie +ab. Ein leeres Ergebnisverzeichnis trotz Erfolgsmeldung wird als Fehlmessung protokolliert, ohne +die Kette zu stoppen. + --- ## 3. Entwicklung des Prompts @@ -740,10 +833,21 @@ zeigt, dass der Effort allein Verbrauch **und** Belegdichte erheblich anhebt. Vo isoliert wäre die Frage erst durch einen Opus-`high`-Block unter denselben Bedingungen – gleicher Snapshot, gleiche Prompt-Version. -**Nicht messbar in der bisherigen Anlage:** Die Zelle `claude-opus-5 / builtin / high` ist -zweimal gescheitert (Zeitlimit, Session-Kontingent) und hat dabei 586 Mio. Tokens ohne Ergebnis -verbraucht. Vor einer Wiederholung ist zu entscheiden, ob die Kombination Opus + Delegation + -Prompt-Version 02 überhaupt sinnvoll messbar ist. +**Nicht messbar:** Die Zelle `claude-opus-5 / builtin / high` ist **dreimal** gescheitert +(einmal Zeitlimit, zweimal Session-Kontingent) und hat dabei 790,7 Mio. Tokens ohne ein Artefakt +verbraucht. Sie wird als nicht messbare Kombination dokumentiert statt ein viertes Mal versucht. +Ein weiterer Anlauf wäre nur mit gedrosselter Nebenläufigkeit +(`CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS`) sinnvoll – das wäre allerdings eine geänderte +Werkzeugkonfiguration und nicht mehr mit den Sonnet-`builtin`-Läufen vergleichbar. + +**Bedingungsverletzt statt unbelegt:** Die Zelle `claude-fable-5 / builtin / *` ist messbar, aber +die Modellbedingung ist dort nicht herstellbar – die Subagenten laufen auf `claude-opus-5[1m]`. +Läufe dieser Zelle sind für Modellvergleiche unbrauchbar und nur als Beleg für die +Durchreichungsgrenze zu verwenden. + +**Kontingent als Versuchsgrenze:** Rund ein Drittel des Gesamtverbrauchs von 2.294,7 Mio. Tokens +entfiel auf Läufe ohne verwertbares Ergebnis, überwiegend durch Parallelbetrieb an der +Kontingentgrenze. Seit dem 27.08. wird strikt seriell gefahren. **Offen für Versuch 2 und 3:** Bei Delegation ist die Modellbedingung über `--model` allein nicht herstellbar (zwei dokumentierte Fälle). `extract-subagenten.py` ist noch nicht gegen diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/Analysebericht.md b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/Analysebericht.md new file mode 100644 index 00000000..097a6a45 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/Analysebericht.md @@ -0,0 +1,615 @@ +# Analysebericht + +**Untersuchungsgegenstand:** c-entron ERP-Suite (Arbeitsverzeichnis `C:\DEV\MasterArbeit\QuellCode\CentronERP`) +**Analyseart:** statische Analyse, keine Ausführung. Codebasis wurde ausschließlich gelesen. +**Datum:** 2026-08-27 + +## Architekturüberblick (Befund aus Schritt 0) + +Die Codebasis umfasst eine Mehrschicht-Anwendung: + +| Schicht | Pfad | Umfang (Dateien) | Technik | +|---|---|---|---| +| Windows-Client (Fat Client) | `src\centron\Centron.WPF.UI` | ~4.726 .cs + XAML | WPF, DevExpress, Ribbon | +| Web-Client „c-entron Nexus" | `src\nexus\CentronNexus` | ~756 (.cs/.razor, 460 .razor) | ASP.NET Core Blazor | +| Geschäftslogik | `src\backend\Centron.BL` | ~85 Fachbereiche | C#/.NET | +| Datenzugriff | `src\backend\Centron.DAO` | ~1.129 | ADO.NET/SQL | +| Entitäten | `src\backend\Centron.Entities` | ~1.183 | POCO/DTO | +| Webservice (REST + Legacy) | `src\webservice` | ~2.528 (Core) + Controller | ASP.NET Core, JWT | +| Externe API-Adapter | `src\apis`, `Centron.Api.docuFORM` | 9 Projekte | REST-Clients | +| Datenbankschema | `SSMS_DB_SCHEMA.sql` | 1.535 `CREATE TABLE` | MSSQL | +| Deployment | `docker`, `azure`, `deployment`, `scripts` | — | Docker/Azure DevOps | + +## Schritt 0 — Modulinventar + +Das Inventar ist die Bezugsgröße für die Abdeckungstabelle. Es wurde vor der ersten Anforderung erstellt und wird später ergänzt, aber nicht gekürzt. Gruppierung: A1–A12 = Analyse-Cluster. + +| Nr. | Modul / Komponente | Pfad (Hauptfundort) | Fachliche Aufgabe (ein Satz) | Cluster | +|---|---|---|---|---| +| M01 | Rechteverwaltung / UserRights | `src\backend\Centron.BL\Security`, `src\centron\...\Modules\Administration\RightsManagement`, `CentronRights.md` | Definition und Durchsetzung feingranularer Benutzerrechte inkl. einschränkender Rechte (nur eigene, nur eigene Filiale). | A1 | +| M02 | Authentifizierung Webservice (JWT) | `src\webservice\Centron.Controllers\JwtAuthController.cs`, `Authorize*Attribute.cs` | Anmeldung und Autorisierung externer Zugriffe über JWT-Token und Rechte-Attribute. | A1 | +| M03 | Zwei-Faktor-Authentifizierung | `src\backend\Centron.BL\TwoFactorAuthenticator`, `TwoFactorAuthController.cs` | Zweiter Faktor bei der Anmeldung. | A1 | +| M04 | Passwortmanager | `src\centron\...\Modules\PasswordManager`, `Centron.BL\PasswordManagementArea` | Verwaltung von Zugangsdaten (z. B. Kundenpasswörter) im ERP. | A1 | +| M05 | DSGVO-Funktionen | `src\centron\...\Modules\Administration\DSGVO` | Datenschutzfunktionen (Anonymisierung/Auskunft) für personenbezogene Daten. | A1 | +| M06 | Verträge (Service/Leasing) | `Centron.BL\Finances`, `...\Modules\Finances\Contracts` | Verwaltung wiederkehrend abzurechnender Service-, Wartungs- und Leasingverträge. | A2 | +| M07 | Automatisierte Abrechnung | `...\Modules\Finances\AutomatedBilling`, `FlatrateBilling`, `TimerBilling` | Periodische Erzeugung von Abrechnungsbelegen aus Verträgen, Flatrates und Zeitbuchungen. | A2 | +| M08 | Mahnwesen | `...\Modules\Finances\Dunning` | Mahnläufe über offene Posten mit Mahnstufen. | A2 | +| M09 | Offene Posten (OPOS) / Zahlungen | `...\Modules\Finances\Opos`, `Payments` | Verwaltung offener Posten und Zahlungszuordnung. | A2 | +| M10 | Onlinebanking / FinAPI | `...\Modules\OnlineBanking`, `src\apis\Centron.APIs.FinAPI` | Abruf von Kontoumsätzen und Abgleich mit offenen Posten. | A2 | +| M11 | Zahler & Kostenstellen | `...\Modules\PayersAndCostCenter` | Abweichende Rechnungsempfänger (Zahler) und Kostenstellenzuordnung. | A2 | +| M12 | Buchhaltungsexport (DATEV u. a.) | `...\Modules\DataExchange\BookKeeping`, `DatevOnline2020`, `PaymentTransactions` | Übergabe von Buchungsdaten und Zahlungsverkehr an Finanzbuchhaltungssysteme. | A2 | +| M13 | Gerätezähler (Click-Abrechnung) | `...\Modules\Finances\DeviceClickCounter` | Erfassung von Zählerständen (z. B. Druckerklicks) als Abrechnungsgrundlage. | A2 | +| M14 | SEPA | `...\Modules\Administration\SepaContract` | SEPA-Mandate/Lastschrift-Grundlagen. | A2 | +| M15 | Belegwesen Verkauf (Angebot→Rechnung) | `Centron.BL\Sales` (248 Dateien), `...\Modules\Sales` | Angebots-, Auftrags-, Lieferschein- und Rechnungserstellung mit Belegkette. | A3 | +| M16 | Sonderpreise / Preisfindung | `Centron.BL\Sales`, Adressstamm-Sonderpreise | Kunden- bzw. vertragsspezifische Preisfindung. | A3 | +| M17 | Produktmatrix | `Centron.BL\ProductMatrix`, `...\Modules\Sales\ProductMatrix` | Matrixbasierte Produkt-/Konditionszuordnung im Vertrieb. | A3 | +| M18 | Mailing/Kampagnen Vertrieb | `...\Modules\Sales\Mailing`, `Centron.BL\Mailings` | Serienmails/Kampagnen an Kundenselektionen. | A3 | +| M19 | E-Rechnung (XRechnung/ZUGFeRD/ebInterface) | `docs\guides\development\xrechnung.md`, `src\apis\Centron.Api.EbInterface`, `ZugferdImportController.cs` | Erzeugung und Import strukturierter elektronischer Rechnungen. | A3 | +| M20 | Belegkonditionen | `...\Modules\Administration\ReceiptConditions` | Konfigurierbare Zu-/Abschlagskonditionen auf Belegen. | A3 | +| M21 | Artikelstamm & Lager | `Centron.BL\Warehousing` (40), `...\Modules\Warehousing` | Artikelverwaltung, Einheiten, Materialgruppen, Lagerbestände, Inventur. | A4 | +| M22 | Kommissionierung | `...\Modules\Warehousing\Commissioning`, `Commissions` | Zusammenstellung von Lieferungen aus Lagerbeständen. | A4 | +| M23 | Barcode | `...\Modules\Warehousing\BarcodeManagement` | Barcodegestützte Lagerprozesse. | A4 | +| M24 | Einkauf & Bestellvorschlag | `Centron.BL\Buying`, `Centron.BL\Purchasing`, `...\Modules\Purchasing` | Lieferantenbestellungen inkl. Bestellvorschlagsliste und Wareneingang. | A4 | +| M25 | EDI (Lieferanten) | `Centron.BL\EDI` (27), `...\Modules\Purchasing\EDIManagement` | Elektronischer Belegaustausch mit Lieferanten/Distributoren. | A4 | +| M26 | Versand / Logistik | `...\Modules\Logistic`, `src\apis\Centron.Api.Gls`, `Centron.Api.Shipcloud` | Versandarten, Paketlabel und Sendungsverfolgung über GLS/Shipcloud. | A4 | +| M27 | RMA / Retouren | `...\Modules\Rma`, `Centron.BL` | Abwicklung von Rücksendungen an Kunden (SendBack) und Lieferanten (SendForth). | A4 | +| M28 | Produktdaten-Anbindungen (Icecat, ITscope, COP, EGIS) | `src\apis\Centron.APIs.*DataAccess` | Import von Artikelstammdaten und Konditionen externer Kataloge/Distributoren. | A4 | +| M29 | TradePool | `Centron.BL\TradePool` | Austausch/Handel von Artikeln über einen Händlerpool. | A4 | +| M30 | Helpdesk / Ticketsystem | `Centron.BL\Helpers`, `...\Modules\Helpdesk`, `Centron.BL\ExternalHelpdesk` | Ticketverwaltung mit Kategorien, Status, Zuweisung, Eskalation. | A5 | +| M31 | Zeiterfassung auf Tickets | `Centron.BL\Time`, `...\Modules\Helpdesk` (EDIT_TIME-Rechte) | Erfassung und Abrechnung von Arbeitszeiten auf Tickets. | A5 | +| M32 | Checklisten | `Centron.BL\CheckListArea`, `...\Modules\Helpdesk\CentronChecklist` | Strukturierte Abarbeitungslisten an Tickets. | A5 | +| M33 | Expected Events | `Centron.BL\ExpectedEvents`, `...\Modules\Helpdesk\ExpectedEvents` | Überwachung erwarteter Ereignisse (z. B. Backup-Meldungen) mit Alarmierung. | A5 | +| M34 | SelfCare-Formulare | `Centron.BL\SelfCare`, `SelfCareFormsController.cs` | Endkunden-Formulare zur Selbstauskunft/Ticketanlage. | A5 | +| M35 | Aufgabenverwaltung (TaskManager) | `Centron.BL\TaskManager`, `...\Modules\Helpdesk\TaskManagement` | Aufgaben mit Fälligkeit und Verantwortlichen, auch ticketbezogen. | A5 | +| M36 | Umfragen (Survey) | `...\Modules\Survey` | Erstellung und Auswertung von Kundenumfragen. | A5 | +| M37 | Ticket-Projekte | `Centron.BL\TicketProjects` | Bündelung von Tickets zu Projekten. | A5 | +| M38 | Adress-/Kundenstamm | `Centron.BL\BusinessPartner`, `CustomerArea`, `Accounts` | Verwaltung von Kunden, Lieferanten, Ansprechpartnern und Web-Accounts. | A6 | +| M39 | Mitarbeiterstamm | `Centron.BL\EmployeeArea`, `...\Administration\EmployeeManagement` | Mitarbeiterdaten, Abteilungen, Filialen. | A6 | +| M40 | Geräte / Assets / Stammblätter | `Centron.BL\Devices`, `Centron.BL\ItPlanner` | Verwaltung von Kundengeräten (Drucker-Stammblätter, IT-Assets) inkl. Historie. | A6 | +| M41 | Länder/Regionen | `Centron.BL\CountryArea` | Länderstammdaten inkl. steuerlicher Zuordnung. | A6 | +| M42 | Tags & Custom Properties | `Centron.BL\Tags`, `Centron.BL\Customizations`, `...\Global\CustomProperties` | Freie Verschlagwortung und kundenindividuelle Zusatzfelder. | A6 | +| M43 | Objekt-Externreferenzen | `Centron.BL\ObjectExternalReferences` | Verknüpfung von ERP-Objekten mit IDs externer Systeme. | A6 | +| M44 | Mail (Versand/Empfang) | `Centron.BL\Mail` (20), `MailScanner` | Mailversand/-empfang, Vorlagen, automatische Zuordnung eingehender Mails. | A7 | +| M45 | Mail-Vorlagen | `...\Administration\MailTemplates`, `docs\guides\development\create-mail-templates.md` | Platzhalterbasierte Mailvorlagen für Systemmails. | A7 | +| M46 | Kalender / Termine | `Centron.BL\Calendar`, `AppointmentRequests`, `...\Modules\Calendar` | Terminverwaltung inkl. Terminanfragen, Exchange-Sync. | A7 | +| M47 | Outlook-/Exchange-Integration | `Centron.BL\Outlook`, `src\nexus\CentronNexus.OutlookAddIn`, `docs\features\exchange-sync-bugprotokoll.md` | Synchronisation von Mails/Terminen mit Outlook/Exchange. | A7 | +| M48 | Telefonie (TAPI) | `Centron.BL\Tapi`, `...\MyCentron\Telephony` | Anrufsignalisierung und Wahlhilfe am Arbeitsplatz. | A7 | +| M49 | Chats | `Centron.BL\Chats` | Interner Chat. | A7 | +| M50 | Benachrichtigungen | `Centron.BL\Notifications`, `NexusNotifications` | Systembenachrichtigungen an Benutzer (Client und Web). | A7 | +| M51 | MyCentron / MyDay / ToDo | `Centron.BL\MyCentron`, `MyDay`, `ToDoArea`, `...\Modules\MyCentron` | Persönliche Startseite mit Tagesübersicht, Aufgaben, Wiedervorlagen. | A7 | +| M52 | Social Media / VideoPortal | `Centron.BL\SocialMedia`, `VideoPortal` | Anbindung Social-Media-Kanäle und internes Videoportal. | A7 | +| M53 | Nexus WebCart (Shop) | `src\nexus\CentronNexus\WebCart` | Webshop für Endkunden auf Basis der Sonderpreise. | A8 | +| M54 | Nexus WebOffer | `src\nexus\CentronNexus\WebOffer` | Online-Angebotsansicht/-annahme durch Kunden. | A8 | +| M55 | Nexus ServiceBoard | `src\nexus\CentronNexus\ServiceBoard` | Web-Ticketboard für Servicevorgänge. | A8 | +| M56 | Nexus DocumentSigning | `src\nexus\CentronNexus\DocumentSigning` | Digitale Unterschrift von Dokumenten (Signaturpad) im Browser. | A8 | +| M57 | Nexus Produktionsaufträge | `src\nexus\CentronNexus\ProductionOrderManagement` | Web-Sicht auf Fertigungsaufträge. | A8 | +| M58 | REST-API (Centron.Controllers) | `src\webservice\Centron.Controllers` | REST-Endpunkte für Kunden, Aufträge, Tickets usw. mit Rechteprüfung. | A8 | +| M59 | Legacy-Webservices | `src\webservice\Centron.WebServices.Core` (2.528 Dateien) | Umfangreiche Service-Schicht für Client-Server-Kommunikation. | A8 | +| M60 | ConnectionManager / Hosts | `src\webservice\c-entron.misc.ConnectionManager`, `Centron.Host*` | Hosting der Dienste (Konsole, Windows-Dienst) und Verbindungsverwaltung. | A8 | +| M61 | Mobile | `Centron.BL\Mobile` | Unterstützung mobiler Zugriffe. | A8 | +| M62 | DocSync / docuFORM | `...\Modules\DataExchange\DocSync`, `DocuForm`, `Centron.Api.docuFORM` | Dokumenten-/Datenaustausch mit docuFORM (Geräte-/Zählerdaten). | A9 | +| M63 | RMM-Connectors | `...\Modules\DataExchange\Rmm`, `RmmController.cs` | Anbindung von Remote-Monitoring-Systemen (Geräte-/Alarmdaten). | A9 | +| M64 | TelekomDive | `Centron.BL`? `...\Modules\TelekomDive`, `DataExchange\TelekomDive` | Anbindung Telekom-DIVE-Portal (Aufträge/Provisionen). | A9 | +| M65 | Datenimport/-export generisch | `...\Modules\DataExchange\DataImport`, `DataExport`, `Connectors` | Konfigurierbarer Im-/Export von Stammdaten und Belegen. | A9 | +| M66 | Integrations / RiverDivo / CPra | `Centron.BL\Integrations`, `RiverDivo`, `CPra` | Weitere Drittsystem-Anbindungen. | A9 | +| M67 | Gateway | `src\backend\Centron.Gateway` | Vermittlungsschicht zwischen Client und Diensten. | A9 | +| M68 | Produktion / Fertigungsaufträge | `Centron.BL\Production`, `...\Modules\Production` | Fertigungsaufträge und Maschinenverwaltung. | A10 | +| M69 | Projektmanagement | `Centron.BL\Projects`, `...\Modules\ProjectManagement` | Projekte mit Budgets/Auswertung. | A10 | +| M70 | Projektpreisimport | `...\Modules\ProjectPriceImport` | Import projektspezifischer Preise mit Differenzprüfung. | A10 | +| M71 | PLM (Product Lifecycle) | `...\Modules\PLM`, `...\Finances\ProductLifecycleManagement` | Lebenszyklusverwaltung von Produkten/Geräten. | A10 | +| M72 | QM | `...\Modules\QM` | Qualitätsmanagement-Funktionen. | A10 | +| M73 | Statistiken / Management-Info | `Centron.BL\Statistics` (16), `...\Modules\Statistics` | Vertriebs-, MSP- und Mitarbeiterauswertungen. | A10 | +| M74 | Reporting / ReportEngine | `Centron.BL\ReportEngine` (26), `...\Modules\Reports`, `...\Administration\ReportServer` | Berichtserzeugung (Belegdruck, Listen) über Reportvorlagen. | A10 | +| M75 | Massenupdates | `Centron.BL\MassUpdate`, `...\Modules\Massenupdates` | Massenänderungen an Stammdaten/Verträgen. | A10 | +| M76 | Dashboard | `Centron.BL\DocuBoard`, `...\Modules\Dashboard`, `Statistics\Dashboard` | Konfigurierbare Kennzahlen-Dashboards. | A10 | +| M77 | Persistenzschicht / DB-Schema | `Centron.DAO`, `Centron.Entities`, `SSMS_DB_SCHEMA.sql` (1.535 Tabellen) | Datenzugriff und relationales Schema. | A11 | +| M78 | Volltextsuche (IndexSearch) | `Centron.BL\IndexSearch` | Indexgestützte übergreifende Suche. | A11 | +| M79 | Änderungsverfolgung (ChangeTracking) | `Centron.BL\ChangeTracking` | Protokollierung von Datenänderungen. | A11 | +| M80 | Dateiablage (Storage) | `Centron.BL\Storage`, `...\CentronFileSystem` | Ablage von Dokumenten/Dateien zu ERP-Objekten. | A11 | +| M81 | Lokalisierung | `...\Centron.WPF.UI\Localization`, `ResXManager.config.xml` | Mehrsprachige Oberflächentexte (ResX). | A11 | +| M82 | Logging / Telemetrie | `nlog.config`, `Centron.BL\Telemetry`, `...\Administration\LogViewer` | Technisches Logging und Telemetrie inkl. Log-Ansicht. | A11 | +| M83 | KI-Funktionen | `Centron.BL\ArtificialIntelligence` (25), `...\Modules\ArtificialIntelligence` | OpenAI-gestützte Funktionen (Chat, Angebotstexte, Textbewertung). | A11 | +| M84 | UI-Framework / Controls / GUI-Profile | `src\shared\Centron.Controls` (742), `...\Modules\Gui\Profiles` | Wiederverwendbare UI-Steuerelemente und benutzerspezifische Oberflächenprofile. | A11 | +| M85 | Externe Tools | `Centron.BL\ExternalToolsBL`, `...\Modules\ExternalTool` | Einbindung externer Programme mit Variablenübergabe. | A11 | +| M86 | Mandantenverwaltung | `...\Administration\MandatorManagement` | Verwaltung mehrerer Mandanten. | A12 | +| M87 | Einstellungsverwaltung | `...\Administration\Settings`, `docs\guides\development\settings-management.md`, `CentronConfigDb` | Zentrale, hierarchische Systemeinstellungen. | A12 | +| M88 | Textbausteine | `Centron.BL\TextModuleArea`, `...\Administration\TextBlockManagement` | Wiederverwendbare Textbausteine für Belege/Mails. | A12 | +| M89 | Hintergrunddienste | `docs\Background Service\DataQualityService.md`, `Centron.BL\Services`, `...\Administration\Services` | Zeitgesteuerte Serverdienste (u. a. Datenqualität, Eskalation). | A12 | +| M90 | Eskalationsregeln | `...\Administration\EscalationsSettings` | Konfigurierbare Eskalationen (z. B. Ticketfälligkeit). | A12 | +| M91 | PDF-Export/-Signierung | `...\Administration\PdfExport`, `PdfSigning` | PDF-Erzeugung und qualifizierte Signatur von Belegen. | A12 | +| M92 | Deployment / Betrieb | `docker`, `azure`, `deployment`, `scripts`, `Centron.Host.WindowsService` | Build-, Container- und Releaseprozesse; Betrieb als Windows-Dienst/Container. | A12 | +| M93 | Stundenzuschlagssätze | `...\Administration\HourlySurchargeRates` | Zuschlagsregeln auf Arbeitszeiten. | A12 | +| M94 | Update-Benachrichtigung | `...\Administration\UpdateAvailableNotificationSettings` | Hinweis auf verfügbare Programmversionen. | A12 | +| M95 | Gutscheinverwaltung | `Centron.BL\VoucherManagement` | Verwaltung von Gutscheinen. | A2 | +| M96 | Web-Links/URLs | `Centron.BL\Urls`, `WebLinks` | Verwaltung von Weblinks zu ERP-Objekten. | A8 | + +*Das Inventar wurde vor der ersten Anforderung erstellt und im Laufe der Analyse ergänzt (nicht gekürzt); die Abdeckungstabelle unten führt jede Zeile mit Analysetiefe und Anforderungszahl.* + +### Inventar-Korrekturen aus der Analyse + +Die Detailanalyse hat die Ein-Satz-Beschreibungen bzw. Pfade folgender Module korrigiert oder präzisiert (das ursprüngliche Inventar bleibt oben unverändert stehen; maßgeblich sind die Korrekturen): + +| Nr. | Korrektur (Kurzfassung) | +|---|---| +| M01 | `Centron.BL\Security` enthält nur `PdfSigningBL.cs`; die Rechte-BL liegt in `Centron.BL\Administration\Rights` (AppRightsBL), die Rechtekonstanten in `Centron.WebServices.Core\EntitiesWrongPlace\Administration\Rights\UserRightsConst.cs`. | +| M03 | `Centron.BL\TwoFactorAuthenticator` enthält nur die TOTP-PIN-Prüfung für den Passwortmanager; die Login-2FA (RADIUS/E-Mail-Link) liegt in `Centron.BL\Administration\Logins\TwoFactor`. | +| M04 | Der Passwortmanager existiert doppelt: `PasswordManagementArea` (Alt) und `PasswordManager` (aktuell, AES-verschlüsselt, Siegel). | +| M06 | Enthält zwei parallele Auswertungsmodule: `ContractEvaluation2` und `ContractEvaluationOld` (Altimplementierung). | +| M11 | Verwaltet Kostenstellen (CostCenter) und Kostenträger (CostObject, UI „Payers") — nicht „Zahler" im Sinne abweichender Rechnungsempfänger. | +| M15/M19/M20 | ZUGFeRD-Import liegt unter `Centron.Controllers\Controllers\v1\Receipts\`; E-Rechnungs-Generatoren in `Centron.BL\DataExchange\EDI\SaleInvoices\`; Konditions-Durchsetzung in `Centron.BL\Sales\Receipts\ReceiptBL.cs`. | +| M27 | RMA-BL liegt in `Centron.BL\CustomerArea\RmaBL.cs`; umfasst Kundenretouren, Lieferantenrücksendungen (SendBack) und Vorab-/Ersatzlieferungen (SendForth). | +| M31 | Ticket-Zeiterfassung liegt in `Centron.BL\Sales\Support` (HelpdeskTimerBL u. a.), nicht in `Centron.BL\Time` (dort nur TimingSettingsBL). | +| M33 | Expected Events = kundenbezogene Überwachung erwarteter externer Ereignisse (z. B. Backup-Meldungen) mit Zeitfenstern und Textmustern; Auswertungskomponente liegt außerhalb der Codebasis. | +| M36 | Umfrage-BL liegt in `Centron.BL\Accounts\Survey\SurveyProcessBL.cs`; Kopplung an Ticketabschluss über `HelpdeskCloseBL.AddSurvey()`. | +| M39 | EmployeeManagement-UI liegt im WPF-Client und in `Centron.Controls`; BL in `Centron.BL\EmployeeArea`. | +| M40 | „Stammblätter" = `MasterDataList` unter `Centron.BL\Sales\CustomerAssets\Contracts\ClickContracts`; `ItPlanner` enthält nur Checklisten-Kategorien. Kundengeräte liegen in **drei** Datenhaltungen (Stammblätter, `AccountDevices`, AssetManagement-/River-Sync). | +| M42 | Custom-Property-Logik liegt in `Centron.BL\Administration\Customization`; `Centron.BL\Customizations\CustomTables` ist nur ein Report-Hilfsdienst. | +| M47 | `Centron.BL\Outlook` enthält nur eine Asset-Suche für das Add-in; Exchange-Funktionalität liegt im Blazor-Add-in, `Centron.BL\Mail\Exchange` (EWS) und der Kalender-Synchronisation. | +| M50 | Zwei getrennte Benachrichtigungssysteme: `Notifications` (System-/Adminprotokoll, externe Empfänger) und `NexusNotifications` (persönliche Mitarbeiter-Benachrichtigungen mit SignalR-Push). | +| M52 | VideoPortal = rechtegeschützte Video-Zuweisung mit ToDo-Kopplung; SocialMedia = interner Aktivitäten-Stream auf Stored-Procedure-Basis. | +| M53 | WebCart umfasst das gesamte Endkunden-Portal (Belege/Verträge, Tickets, Formulare, Dokumente, Zeitnachweise), nicht nur den Warenkorb. | +| M56 | DocumentSigning (Route `/contractmanagement`) signiert beliebige PDF-Dokumente inkl. SEPA-Mandate über einmalige GUID-Links. | +| M61 | „Mobile" ist ein 37-zeiliger Alt-Lesezugriff auf `NewMobileEmployee`/`NewMobileContactPerson`, kein Mobile-Backend. | +| M62 | docuFORM = OAuth2-Import von Druckgeräte-Seitenzählern für die Click-Abrechnung; DocSync = davon unabhängige Dokumentbereitstellung je Objektart. | +| M66 | „CPra" = Konnektor zum Dienst Nexoware Smartflow; EsCustomerGroups/EsRoles = lokale Caches von ElectronicSales-Webshop-Stammdaten. | +| M69 | ProjectManagement = internes Projekt-/Auslastungsboard, hart codiert auf die Abteilung „Software-Entwicklung"; `Centron.BL\Projects` ist trivialer Altbestand. | +| M71 | Keine Doppelimplementierung: `Modules\Finances\ProductLifecycleManagement` ist nur der Einstellungsdialog des PLM-Moduls. | +| M76 | `Modules\Dashboard` = Modul-Startübersicht (Kacheln), kein Kennzahlen-Dashboard; `Centron.BL\DocuBoard` = Asset-Management-Stammlisten. | +| M79 | Das eigentliche ChangeTracking liegt in `Centron.DAO\ChangeTracking` und `ChangeLogBL`; `Centron.BL\ChangeTracking` enthält nur Import-Historie. | +| M80 | `Centron.BL\Storage` ist seit 2014 vollständig auskommentierte, obsolete Inventur-Altlogik; die Dateiablage liegt clientseitig in `CentronFileSystem` (Backend: FileManagement). | +| M86 | Mandantenverwaltung = Firmenstammdaten/Filialen in EINER Datenbank; keine Mandantentrennung im SaaS-Sinn (kein getrennter Datenraum). | +| M89 | Der Host betreibt ca. 35 über die Tabelle `BackgroundServices` einzeln aktivierbare Hintergrunddienste auf der Basisklasse `ManagedBackgroundService`. | +| M95 | Gutscheinmodul = belegbasierte Statusauswertung (frei/ausgegeben/eingelöst) über `GutscheinZuRechnung`; Ausgabe/Einlösung erfolgt im Belegwesen. | + +## Vorgehen im Lauf + +Die Analyse folgte den Schritten 0–6 der RRE-Methodenkette: (0) Modulinventar vor der ersten Anforderung, (0b) Mindestabdeckung je Modul, (0c) Vertiefung nach Risiko (Sicherheit, Abrechnung/Fakturierung, Berechtigungen zuerst), (2) Artefakterhebung, (3) technische Analyse, (4) semantische Interpretation, (5) Formalisierung, (6) Traceability. Die 96 Inventarmodule wurden in 12 Analyse-Cluster (A1–A12) aufgeteilt und parallel durch Analyse-Subagenten bearbeitet; jeder Cluster erhielt einen eigenen ID-Nummernkreis (A1=1xx … A12=12xx). Alle PRIMÄR-Belege wurden im Quelltext bzw. im SQL-Schema tatsächlich gelesen; die Codebasis wurde ausschließlich lesend verarbeitet. + +## Abdeckungstabelle + +Jede Zeile des Modulinventars mit Analysetiefe und Anzahl der daraus erzeugten Anforderungen. Anforderungszahlen enthalten teilweise anteilige Zuordnungen (eine Anforderung kann mehrere Module eines Clusters tragen); Bezugsgröße ist die Abdeckungsangabe des jeweiligen Cluster-Agenten. **Kein Modul ist ohne Anforderung** (Mindestabdeckung erfüllt); kein Modul musste als `nicht analysiert` eingestuft werden. + +| Nr. | Modul | Tiefe | Anzahl Anforderungen | Bemerkung | +|---|---|---|---|---| +| M01 | Rechteverwaltung/UserRights | tief | 9 | HasUserRight-Kern, Datenmodell, Gruppenverwaltung, Audit-Log | +| M02 | Authentifizierung Webservice (JWT) | tief | 6 | JwtAuthController, Authorize-Attribute, AuthenticatorFactory | +| M03 | Zwei-Faktor-Authentifizierung | tief | 4 | beide 2FA-Subsysteme analysiert | +| M04 | Passwortmanager | tief | 7 | inkl. Alt-Implementierung (Hypothese SwRS-119) | +| M05 | DSGVO-Funktionen | mittel | 5 | Kontaktlöschung/Cleanup/AVV belegt; Komplettlöschung nicht implementiert | +| M06 | Verträge (Service/Leasing) | tief | 6 | ContractBL vollständig; Auswertungsmodule nur Controller-Ebene | +| M07 | Automatisierte Abrechnung | tief | 7 | AutomaticFacturaBL (2.900 Zeilen) und TimerBillingBL gelesen | +| M08 | Mahnwesen | tief | 6 | DunningBL/DunningRunBL vollständig | +| M09 | OPOS/Zahlungen | tief | 4 | OposBL/PaymentsBL/IncomingPaymentBL vollständig | +| M10 | Onlinebanking/FinAPI | tief | 7 | Matching-Heuristiken; Rechte-Durchsetzung als Hypothese (SwRS-248) | +| M11 | Zahler & Kostenstellen | mittel | 1 | Belegzuordnungslogik nicht vertieft | +| M12 | Buchhaltungsexport (DATEV u. a.) | mittel | 4 | Formatauswahl/Exportflags; Formatgeneratoren nicht im Detail | +| M13 | Gerätezähler (Click-Abrechnung) | tief | 2 | DeviceClickCounterBL vollständig | +| M14 | SEPA | tief | 3 | Online-Signaturprozess mit Statusmaschine | +| M15 | Belegwesen Verkauf | tief | 24 | Belegkette, Storno, Festschreibung, Nummernkreise, MwSt; ReceiptBL (11.441 Zeilen) auszugsweise | +| M16 | Sonderpreise/Preisfindung | tief | 5 | Preisfindungshierarchie, Mindestpreis-Override | +| M17 | Produktmatrix | mittel | 3 | BL + Schema vollständig, UI überflogen | +| M18 | Mailing/Kampagnen | mittel | 4 | Versandpfad nicht vertieft (Hypothese SwRS-350) | +| M19 | E-Rechnung (XRechnung/ZUGFeRD/ebInterface) | mittel | 4 | Formatwahl/Leitweg-ID belegt; XML-Feldmapping nicht Feld für Feld | +| M20 | Belegkonditionen | mittel | 2 | Durchsetzung am Beleg belegt | +| M21 | Artikelstamm & Lager | tief | 14 | Rechte, Bestandsermittlung, gleitender EK, Inventur | +| M22 | Kommissionierung | mittel | 3 | zwei parallele Implementierungen festgestellt | +| M23 | Barcode/Seriennummern | tief | 4 | Statusmodell, Eindeutigkeit, Ausbuchung | +| M24 | Einkauf & Bestellvorschlag | mittel | 3 | Bestellvorschlags-SQL tief; TravelExpense nur gesichtet | +| M25 | EDI (Lieferanten) | mittel | 3 | Formatdispatcher belegt; Distributor-Parser nicht vertieft | +| M26 | Versand/Logistik | mittel | 4 | GLS-Limits und Shipcloud-Broker belegt | +| M27 | RMA/Retouren | mittel | 3 | Statusmaschine SaveRma tief | +| M28 | Produktdaten-Anbindungen | flach | 2 | Icecat/ITscope/EGIS gelesen; CopDataAccess nicht analysiert | +| M29 | TradePool | flach | 1 | fachlicher Zweck unklar (Hypothese SwRS-451) | +| M30 | Helpdesk/Ticketsystem | tief | 12 | Statusmodell, Rechte, Fälligkeit, Eskalation, Abschluss | +| M31 | Zeiterfassung auf Tickets | tief | 8 | serverseitige Rechte belegt; MOVE-Recht nur clientseitig | +| M32 | Checklisten | mittel | 2 | kein hartes Abschluss-Gate gefunden | +| M33 | Expected Events | mittel | 2 | Auswertungskomponente außerhalb der Codebasis (Hypothese SwRS-545) | +| M34 | SelfCare | mittel | 3 | GUID-/Ablauflogik belegt | +| M35 | TaskManager | mittel | 2 | Wiederholungsregeln, Handler, Lizenzprüfung | +| M36 | Umfragen | mittel | 2 | Antwort-Erfassung (ServiceBoard) nicht analysiert | +| M37 | Ticket-Projekte | flach | 1 | CRUD/Nummernkreis belegt | +| M38 | Adress-/Kundenstamm | tief | 12 | AccountBL/WebAccountBL gelesen | +| M39 | Mitarbeiterstamm | mittel | 5 | EmployeeBL/AppUserBL gelesen | +| M40 | Geräte/Assets/Stammblätter | tief | 7 | Drei-Datenhaltungen-Befund dokumentiert | +| M41 | Länder/Regionen | mittel | 2 | CountryBL/FederalStateBL vollständig | +| M42 | Tags & Custom Properties | tief | 3 | Pflichtfeldprüfung nur clientseitig | +| M43 | Objekt-Externreferenzen | tief | 1 | Detailregeln in SyRS-612; Tabelle fehlt im SQL-Dump | +| M44 | Mail (Versand/Empfang), MailScanner | tief | 8 | Absender-Whitelist, VMA-Verschlüsselung | +| M45 | Mail-Vorlagen | tief | 3 | Fallback-Hierarchie belegt | +| M46 | Kalender/Termine | mittel | 4 | CalendarBL/AppointmentRequestBL vollständig | +| M47 | Outlook/Exchange | mittel | 2 | Sync teils über Doku (KONTEXT) erfasst | +| M48 | Telefonie (TAPI) | tief | 4 | PhoneCallBL/PhoneSettingsBL gelesen | +| M49 | Chats | tief | 2 | Mitgliedschafts-Expressions belegt | +| M50 | Benachrichtigungen | mittel | 3 | zwei Systeme (Konsolidierungskandidat) | +| M51 | MyCentron/MyDay/ToDo | tief | 6 | Rechteprüfungen FREMDTODOLISTE belegt | +| M52 | Social Media / VideoPortal | mittel | 3 | SocialMedia-Logik in Stored Procedures (Hypothese SwRS-748) | +| M53 | Nexus WebCart | tief | 5 | Freigabewesen bis in die BL verfolgt | +| M54 | Nexus WebOffer | mittel | 2 | Token-Flow und Zustandsmodell | +| M55 | Nexus ServiceBoard | mittel | 3 | CloseTicket/Auth vertieft; Kanban/Scheduler strukturell | +| M56 | Nexus DocumentSigning | mittel | 2 | Signaturseite und DsgvoBL vollständig | +| M57 | Nexus Produktionsaufträge | mittel | 2 | Auth-Lücke als Hypothese (SwRS-848) | +| M58 | REST-API (Centron.Controllers) | tief | 10 | alle Authorization-Klassen und Filter gelesen | +| M59 | Legacy-Webservices | flach | 2 | 2.530 Dateien, vereinbarungsgemäß nur strukturell | +| M60 | ConnectionManager/Hosts | mittel | 2 | beide Host-Einstiege gelesen | +| M61 | Mobile | tief | 1 | Modul vollständig (37 Zeilen), Altbestand | +| M62 | DocSync/docuFORM | mittel | 4 | Tokenfluss und Importablauf gelesen | +| M63 | RMM-Connectors | tief | 8 | RmmController/RiverDivoBL/DocBee-BLs vollständig | +| M64 | TelekomDive | mittel | 3 | Export-ViewModel und BL gelesen | +| M65 | Datenimport/-export generisch | flach | 2 | Kontenimport belegt; InvoiceUpload ist leerer Stub | +| M66 | Integrations/RiverDivo/CPra | mittel | 5 | EsRoleBL nur Kopf geprüft | +| M67 | Gateway | flach | 2 | Struktur inventarisiert, Adapter nicht im Detail | +| M68 | Produktion | tief | 4 | Statusmodell, Logkatalog, Schema | +| M69 | Projektmanagement | mittel | 2 | interner Sonderfall (hart codierte Abteilung) | +| M70 | Projektpreisimport | mittel | 1 | Import-/Differenzlogik gelesen | +| M71 | PLM | tief | 3 | Konsolidierungsfrage geklärt (keine Doppelimplementierung) | +| M72 | QM | mittel | 2 | Durchsetzung in ReceiptBL/CustomerAssetBL | +| M73 | Statistiken | tief | 6 | Rechte-/Abrechnungslogik (MSP) im Fokus | +| M74 | Reporting/ReportEngine | tief | 5 | doppelte Berichts-Datenhaltung belegt | +| M75 | Massenupdates | tief | 3 | alle vier Start-Pfade gesichtet | +| M76 | Dashboard/DocuBoard | mittel | 2 | drei DocuBoard-BLs vollständig | +| M77 | Persistenzschicht/DB-Schema | tief | 6 | Transaktionen, Listener, Konventionen, Constraints | +| M78 | Volltextsuche (IndexSearch) | tief | 4 | alle Kerndateien + Schema | +| M79 | ChangeTracking | mittel | 4 | Attribut-Mechanismus ungenutzt (Befund) | +| M80 | Dateiablage | mittel | 2 | BL\Storage als obsolet eingestuft; Server-BL als Hypothese (SyRS-1119) | +| M81 | Lokalisierung | mittel | 2 | LocalizationHelper vollständig | +| M82 | Logging/Telemetrie | tief | 4 | TelemetryBL vollständig; Schema-Drift festgestellt | +| M83 | KI-Funktionen | mittel | 3 | SSRF-Schutz und Schlüssel-Verschlüsselung belegt | +| M84 | UI-Framework/GUI-Profile | mittel | 2 | Controls strukturell; Profil-Rechtelogik tief | +| M85 | Externe Tools | mittel | 2 | BL vollständig | +| M86 | Mandantenverwaltung | tief | 6 | serverseitige Rechteprüfung offen (Hypothese SwRS-1233) | +| M87 | Einstellungsverwaltung | tief | 5 | beide Settings-Tabellen (Stammdat/ApplicationSettings) | +| M88 | Textbausteine | mittel | 3 | TextModuleBL vollständig | +| M89 | Hintergrunddienste | tief | 4 | ~35 Dienste auf gemeinsamer Basisklasse | +| M90 | Eskalationsregeln | mittel | 2 | Kernberechnung DoEscalation nicht gelesen | +| M91 | PDF-Export/-Signierung | tief | 5 | PdfSigningBL vollständig | +| M92 | Deployment/Betrieb | mittel | 2 | Docker/Compose/Windows-Dienst gelesen | +| M93 | Stundenzuschlagssätze | mittel | 2 | serverseitige BL nicht gelesen | +| M94 | Update-Benachrichtigung | mittel | 2 | Versions- und Zielgruppenlogik gelesen | +| M95 | Gutscheinverwaltung | mittel | 1 | NamedQuery vollständig analysiert | +| M96 | Web-Links/URLs | mittel | 1 | SimpleUrl vs. WebLink (Konsolidierungskandidat) | + +**Zusammenfassung der Analysetiefe:** 42 Module tief, 48 Module mittel, 6 Module flach (M28, M29, M37, M59, M65, M67), 0 Module nicht analysiert. Zusätzlich wurden Querschnittsthemen ohne eigene Inventarzeile erfasst (Login/Sessions, Architektur-Schichtung, Heartbeat, Teststrategie, Profiling, SqlManagers). + +## Konsistenzcheck über das gesamte Anforderungs-Set + +Der Check wurde skriptgestützt über alle 413 Anforderungsblöcke (StRS.md, SyRS.md, SwRS.md) ausgeführt. + +| Prüfung | Ergebnis | +|---|---| +| Anforderungen gesamt | **413** (50 StRS, 122 SyRS, 241 SwRS) | +| Doppelte oder mehrfach vergebene IDs | **keine** (413 eindeutige IDs; Hinweis: SwRS-240 wurde nicht vergeben — dokumentierte Lücke im Nummernkreis A2, kein fehlender Inhalt) | +| Anforderungen ohne Beleg | **keine** (jede Anforderung führt mindestens einen klassifizierten Beleg mit Begründung) | +| Anforderungen ohne Prüfidee | **keine** | +| Anforderungen ohne Angabe zur Übernahmewürdigkeit | **keine** | +| Tracelinks auf nicht existierende IDs | **keine** (alle referenzierten IDs existieren) | +| Anforderungen ohne Tracelinks | **keine** | +| Nicht-funktionale Anforderungen ohne ISO-25010-`Qualitätsmerkmal` | **keine** (21 nicht-funktionale Anforderungen, alle mit Merkmal) | +| Status-Verteilung | 397 `belegt`, 16 `HYPOTHESE` (3,9 %) | +| Abgleich `Hypothesen.md` gegen Inline-Markierungen | **deckungsgleich**: beide Seiten nennen exakt dieselben 16 IDs (SyRS-110, SyRS-1119; SwRS-119, 248, 350, 354, 451, 545, 637, 740, 748, 848, 947, 1043, 1147, 1233); `Hypothesen.md` enthält keine zusätzlichen freien Fragen | +| Konsolidierungskandidaten | 44 Anforderungen (10,7 %) mit `Konsolidierung: Kandidat` | +| Risikoanforderungen (Sicherheit, Abrechnung/Fakturierung, Berechtigungen) | **198**; jede trägt entweder mindestens einen `PRIMÄR`-Beleg mit durchsetzender Stelle oder ist als `HYPOTHESE` gekennzeichnet — **0 Verstöße** gegen die risikobasierte Priorisierung (skriptgeprüft) | +| Inhaltlich deckungsgleiche Anforderungen ohne Konsolidierungsmarkierung | keine gefunden; die bekannten Doppelimplementierungen (siehe Konsolidierungsübersicht) sind in den betroffenen Anforderungen als Kandidat markiert. Restrisiko: clusterübergreifende Dubletten wurden über die Meta-Abgleiche geprüft, eine paarweise Volltextprüfung aller 413 Anforderungen fand nicht statt | + +### Konsolidierungsübersicht (fachlich gleichartige Konzepte in getrennten Implementierungen) + +Wichtigste clusterübergreifend bestätigte bzw. vermutete Konsolidierungsfälle für das Zielsystem: + +1. **Kundengeräte in drei Datenhaltungen** (bestätigt): „Stammblätter" `MasterDataList` (Drucker mit Klickzählern), `AccountDevices` (sonstige Hardware), AssetManagement-/River-Sync-Geräte — der im Auftrag genannte Fall, um eine dritte Datenhaltung erweitert. +2. **Zwei Berechtigungssysteme**: `Sichrech`/`Sichtrus`/`Sichmemb` (AppUser) vs. `WebRights`/`WebAccountsRights` (WebAccounts); dazu doppelter API-Zugriffsschutz (REST-Attributfilter vs. Legacy-`AuthenticateInterceptor`). +3. **Zwei 2FA-Subsysteme** (Login-2FA RADIUS/E-Mail vs. TOTP-PIN des Passwortmanagers) und **zwei Passwortmanager-Implementierungen** (alt/neu). +4. **Zahlungsausgleich doppelt**: IncomingPayments vs. OnlineBanking-Zuordnungen, beide über `UpdateReceiptIsPaid`; **Kostenstellen doppelt**: `Warehousing.CostCenter` vs. `Accounts.CustomerCostCenter`. +5. **Vertragsauswertung doppelt** (ContractEvaluation2 vs. „_old"); **Berichts-Datenhaltung doppelt** (`dbo.Reports` vs. `dbo.ReportData`); **Einstellungs-Datenhaltung doppelt** (`Stammdat` vs. `ApplicationSettings`). +6. **Drei E-Rechnungs-Generatoren** (ZUGFeRD/XInvoice, ebInterface, Gateway `ZUGFeRD21_Extended`); **Beleg-Summenlogik doppelt** (`ReceiptPriceHelper` vs. `CalculationUtils`). +7. **Lager/Logistik intern**: Inventur alt/neu, Kommissionierung (`CommissioningBL` vs. `OrderCommissionBL`), `BarCode` vs. `BarCode2`, GLS-Direktanbindung vs. Shipcloud-Broker, RMA-Alt-Tabellen; **duale Bestandsermittlung** (Seriennummernzählung vs. Mengenfeld, Regel doppelt in SQL und C#). +8. **Kommunikation**: zwei Benachrichtigungssysteme (`Notifications` vs. `NexusNotifications`), zwei Kalender-Sync-Pfade (EWS vs. Graph), zwei Anrufjournal-Befüllungen (TAPI vs. Teams-CallRecords), Mail-Body-Aufbau doppelt (`FillMailBodyOld`/`New`). +9. **Externe Referenzen dreifach** (generische `ObjectExternalReference`, `RiverbirdCustomerReference`, `EsCustomerGroup.ExternalId`); **„externes Ereignis → Ticket" dreifach** (RiverDivo, DocBee-Timer, DocBee-Creation). +10. **Weitere**: `SimpleUrl` vs. `WebLink`, `NewMobileEmployee` vs. Mitarbeiterstamm, zwei tokenbasierte Dokumentsignatur-Pfade (DocumentSigning vs. Office/SharedDocument), Adress-Doppelhaltung neu (`AccountAddresses`) vs. alt (`Anschrif`/`Address`), Entitäten `Mandator`/`Mandatory` auf derselben Tabelle `Mandant`, TicketProjects neben allgemeinem Projektmodul, Rechte-Doku doppelt (`CentronRights.md` vs. `Sichrech.Beschreibung`). + +## Liste aller risikorelevanten Anforderungen + +Alle 198 Anforderungen zu Sicherheit, Abrechnung/Fakturierung und Berechtigungen mit ihrer Belegsituation (skriptgeprüft: jede Zeile hat `PRIMÄR = ja` oder `Status = HYPOTHESE`). Vollständige Titel und Belege in StRS.md/SyRS.md/SwRS.md. + +### A1 — Sicherheit, Identität, Berechtigungen (37) + +| ID | Titel | PRIMÄR | Status | +|---|---|---|---| +| StRS-101 | Rollenbasierte Zugriffskontrolle für alle Fachfunktionen | ja | belegt | +| StRS-102 | Gesicherte Anmeldung für interne Benutzer und Kunden | ja | belegt | +| StRS-103 | Schutz und Nachvollziehbarkeit von Kundenzugangsdaten | ja | belegt | +| StRS-104 | DSGVO-konforme Löschung und Bereinigung personenbezogener Daten | ja | belegt | +| SyRS-101 | Durchgängige Berechtigungsprüfung an allen Systemschnittstellen | ja | belegt | +| SyRS-102 | Administrierbarkeit des Rechtesystems mit Protokollierung | ja | belegt | +| SyRS-103 | Sitzungsverwaltung über Tickets mit begrenzter Lebensdauer | ja | belegt | +| SyRS-104 | Konfigurierbare Authentifizierungsverfahren mit benutzerbezogenem Fallback | ja | belegt | +| SyRS-105 | Zwei-Faktor-Authentifizierung systemweit zuschaltbar | ja | belegt | +| SyRS-106 | Getrennte Identitäten AppUser/WebAccount | ja | belegt | +| SyRS-107 | Kontodeaktivierung verhindert Anmeldung | ja | belegt | +| SyRS-108 | Passwortmanager mit Lizenz-, Richtlinien- und Protokollpflicht | ja | belegt | +| SyRS-109 | DSGVO-Funktionen nur mit dediziertem Recht | ja | belegt | +| SyRS-110 | Serverseitige Durchsetzung aller UI-Rechte | nein | HYPOTHESE | +| SwRS-101 | Benutzerrechtsprüfung über Gruppenmitgliedschaft | ja | belegt | +| SwRS-102 | Rechte-Datenmodell und zentrale Rechtekonstanten | ja | belegt | +| SwRS-103 | Rechtegruppenverwaltung mit Admin-Gruppen-Schutz | ja | belegt | +| SwRS-104 | Protokollierung aller Rechteänderungen | ja | belegt | +| SwRS-105 | REST-Autorisierung über Rechte-Attribute (401/403) | ja | belegt | +| SwRS-106 | JWT-/OIDC-Login mit Subject-Zuordnung | ja | belegt | +| SwRS-107 | Basic-Auth über SHA1-Passworthash | ja | belegt | +| SwRS-108 | Abweisung deaktivierter Konten | ja | belegt | +| SwRS-109 | Ticket-Lebensdauer und Verlängerung | ja | belegt | +| SwRS-110 | Passwortänderung mit Ist-Passwort-Prüfung und Mindestlänge | ja | belegt | +| SwRS-111 | Web-Account-Login mit Aktivitätskette | ja | belegt | +| SwRS-112 | Entscheidungslogik Zwei-Faktor-Bestätigung | ja | belegt | +| SwRS-113 | E-Mail-Link-Zweitfaktor mit Einmalcode | ja | belegt | +| SwRS-114 | TOTP-PIN-Prüfung für Passwortmanager | ja | belegt | +| SwRS-115 | Passwortmanager-Rechteprüfungen | ja | belegt | +| SwRS-116 | Export von Zugangsdaten nur mit Exportrecht | ja | belegt | +| SwRS-117 | AES-Verschlüsselung mit Masterkey und Fallback-Schlüssel | ja | belegt | +| SwRS-118 | Siegelbruch mit Recht, Kommentar, Protokoll, Mail | ja | belegt | +| SwRS-119 | Alt-Passwortverwaltung ohne wirksame Verschlüsselung | teilweise | HYPOTHESE | +| SwRS-120 | DSGVO-Kontaktlöschung mit Löschprotokoll | ja | belegt | +| SwRS-121 | DSGVO-Datenbereinigung und Modulzugang | ja | belegt | +| SwRS-122 | AVV-Verwaltung mit eigenen Rechten | ja | belegt | +| SwRS-1233 | Serverseitige Rechteprüfung beim Speichern von Mandantenstammdaten (A12) | nein | HYPOTHESE | + +### A2 — Finanzen & Abrechnung (44) + +| ID | Titel | PRIMÄR | Status | +|---|---|---|---| +| StRS-201 | Wiederkehrende vertragsbasierte Abrechnung | ja | belegt | +| StRS-202 | Forderungsmanagement und Zahlungsabgleich | ja | belegt | +| StRS-203 | Ordnungsgemäße Übergabe an die Finanzbuchhaltung | ja | belegt | +| StRS-204 | Digitale SEPA-Mandatsverwaltung | ja | belegt | +| StRS-205 | Zugriffsschutz auf Finanzfunktionen | ja | belegt | +| SyRS-206 | Abrechnungsintervalle und Zeitraumfortschreibung | ja | belegt | +| SyRS-207 | Verknüpfung Rechnung–Vertrag und Kontingentbuchung | ja | belegt | +| SyRS-208 | Vertragslebenszyklus | ja | belegt | +| SyRS-209 | Click-/Zählerabrechnung | ja | belegt | +| SyRS-210 | Abrechnung von Ticketzeiten | ja | belegt | +| SyRS-211 | Mahn- und OPOS-Läufe mit Versand | ja | belegt | +| SyRS-212 | OPOS-/Mahnübersicht mit Salden | ja | belegt | +| SyRS-213 | Zahlungseingänge und Rechnungsausgleich | ja | belegt | +| SyRS-214 | Bankauszugsimport und Zahlungsabgleich | ja | belegt | +| SyRS-215 | Externe Schnittstelle finAPI | ja | belegt | +| SyRS-216 | Multiformat-Buchhaltungsexport | ja | belegt | +| SyRS-217 | SEPA-Mandat-Onlineprozess | ja | belegt | +| SyRS-218 | Serverseitige Rechte-/Lizenzprüfung | ja | belegt | +| SwRS-230 | Vertragsende-Berechnung | ja | belegt | +| SwRS-231 | Automatischer Vertragsabschluss | ja | belegt | +| SwRS-232 | Kontingentrest-Formel | ja | belegt | +| SwRS-233 | Abrechnungstermin/Normierung | ja | belegt | +| SwRS-234 | Kontingentbuchung abweichende Intervalle | ja | belegt | +| SwRS-235 | Vertragsauswahl Abrechnungslauf | ja | belegt | +| SwRS-236 | Folge-ToDo nach Abrechnung | ja | belegt | +| SwRS-237 | Mahnstufen-Statusmaschine | ja | belegt | +| SwRS-238 | Mahnlauf-Protokoll | ja | belegt | +| SwRS-239 | Mahnreife (Sperre/Fälligkeit) | ja | belegt | +| SwRS-241 | Versandvoraussetzungen Mahn-E-Mail | ja | belegt | +| SwRS-242 | Zahlungseingang löschen (Rechte/Rückrechnung) | ja | belegt | +| SwRS-243 | OPOS-Saldenformel | ja | belegt | +| SwRS-244 | Duplikaterkennung Umsatzimport | ja | belegt | +| SwRS-245 | Abschlussstatus mit Toleranz | ja | belegt | +| SwRS-246 | Matching-Heuristiken | ja | belegt | +| SwRS-247 | Buchung/Chargeback/Storno | ja | belegt | +| SwRS-248 | Kontoauszugs-Rechte serverseitig | nein | HYPOTHESE | +| SwRS-249 | Export-Doppelschutz | ja | belegt | +| SwRS-250 | Steuer-Mapping Export | ja | belegt | +| SwRS-251 | Zählerhistorie/Monotonie | ja | belegt | +| SwRS-252 | SEPA-Mandatsdaten | ja | belegt | +| SwRS-253 | Kostenstellen/Kostenträger Soft-Delete | ja | belegt | +| SwRS-254 | Editierschutz Ticketzeiten | ja | belegt | +| SwRS-255 | Gutschein-Lebenszyklus | ja | belegt | +| SwRS-1246 | Validierung/Log der Stundenzuschlagssätze (A12) | ja | belegt | + +### A3 — Vertrieb & Belegwesen (22) + +| ID | Titel | PRIMÄR | Status | +|---|---|---|---| +| StRS-302 | Korrekte und revisionssichere Fakturierung | ja | belegt | +| SyRS-312 | Belegnummernvergabe aus konfigurierbaren Nummernkreisen | ja | belegt | +| SyRS-313 | Mehrwertsteuerberechnung je Steuersatz mit definierter Rundung | ja | belegt | +| SyRS-314 | Revisionssichere Rechnung: Storno und Festschreibung | ja | belegt | +| SyRS-315 | Berechtigungsprüfung im Belegwesen | ja | belegt | +| SyRS-316 | Forderungsüberwachung: Mahnwesen und Kreditlimit | ja | belegt | +| SyRS-317 | Automatische Preisfindung mit Schutz des Mindestpreises | ja | belegt | +| SyRS-318 | E-Rechnungs-Export und -Import | ja | belegt | +| SwRS-334 | Nebenläufigkeitssichere Nummernvergabe | ja | belegt | +| SwRS-336 | MwSt-Splitting und Rundungsregeln | ja | belegt | +| SwRS-337 | MwSt-Pflichtprüfungen beim Belegspeichern | ja | belegt | +| SwRS-338 | Stornoregeln für Rechnungen | ja | belegt | +| SwRS-339 | Rechnungsfestschreibung mit Protokollierung | ja | belegt | +| SwRS-340 | Belegart-spezifische Rechteprüfungen inkl. Filialbindung | ja | belegt | +| SwRS-341 | Mahnstufen-Statusmaschine und Neuanlagesperre | ja | belegt | +| SwRS-342 | Kreditlimitprüfung beim Speichern | ja | belegt | +| SwRS-347 | Mindestpreis-Übersteuerung nur durch berechtigten Benutzer | ja | belegt | +| SwRS-350 | Werbesperre beim Mailingversand | nein | HYPOTHESE | +| SwRS-351 | E-Rechnungs-Formatauswahl und Dateierzeugung | ja | belegt | +| SwRS-352 | Authentifizierter ZUGFeRD-Parse-Endpunkt | ja | belegt | +| SwRS-353 | Konditionstexte am Beleg (Zahlungskonditionen) | ja | belegt | +| SwRS-354 | Manueller Storno für Nicht-Rechnungsbelege | nein | HYPOTHESE | + +### A4 — Artikel, Lager, Einkauf, Logistik (7) + +| ID | Titel | PRIMÄR | Status | +|---|---|---|---| +| SyRS-411 | Berechtigungsmodell für Artikelpflege und Lagerbuchungen | ja | belegt | +| SyRS-412 | Lückenlose Protokollierung aller Bestandsänderungen | ja | belegt | +| SyRS-419 | Berechtigungsgeschützte Kommissionierung mit Mengenrückmeldung | ja | belegt | +| SwRS-430 | Feingranulare Rechteprüfung beim Artikelspeichern | ja | belegt | +| SwRS-432 | Gleitender Einkaufspreis bei Wareneingang | ja | belegt | +| SwRS-433 | Lagerumbuchung nur mit Recht TRANSFER_STOCK | ja | belegt | +| SwRS-439 | Zugriffsschutz des Kommissioniermoduls | ja | belegt | + +### A5 — Helpdesk & Service (15) + +| ID | Titel | PRIMÄR | Status | +|---|---|---|---| +| StRS-502 | Abrechnungsfähige und rechtssichere Zeiterfassung auf Tickets | ja | belegt | +| SyRS-512 | Berechtigungsgeprüfte Ticketbearbeitung (intern und Web-Accounts) | ja | belegt | +| SyRS-513 | Fälligkeitsberechnung aus Priorität, geschütztes Fälligkeitsdatum | ja | belegt | +| SyRS-515 | Rechte- und Sperrkonzept der Ticket-Zeiterfassung | ja | belegt | +| SyRS-516 | Kundenunterschrift auf erbrachten Zeiten | ja | belegt | +| SyRS-517 | Automatische Ticketerzeugung durch den TaskManager | ja | belegt | +| SyRS-518 | Zeitlich begrenzte SelfCare-Formularlinks | ja | belegt | +| SwRS-533 | Serverseitige Rechteprüfung beim Ticket-Speichern | ja | belegt | +| SwRS-534 | Rechteprüfung für Portal-Web-Accounts mit Eigentümerbindung | ja | belegt | +| SwRS-538 | Zeiten speichern nur mit EDIT_TIME, Eigenzeiten-Beschränkung, Belegsperre | ja | belegt | +| SwRS-539 | Zeiten löschen mit DELETE_HELPDESK_TIMER, Belegsperre, Historie | ja | belegt | +| SwRS-541 | Unterschrift entfernen nur mit DELETE_HELPDESK_SIGNATURE | ja | belegt | +| SwRS-542 | Zeiten verschieben mit mehrstufiger Prüfkette (MOVE-Recht nur clientseitig) | ja | belegt | +| SwRS-546 | SelfCare-Webformulare: GUID, Ablauf, Formulardefinitionen | ja | belegt | +| SwRS-547 | TaskManager: Wiederholungsregeln, Handler-Dispatch, automatische Tickets | ja | belegt | + +### A6 — Stammdaten & Assets (10) + +| ID | Titel | PRIMÄR | Status | +|---|---|---|---| +| SyRS-605 | Berechtigungsprüfung aller Geschäftspartner-Operationen | ja | belegt | +| SyRS-607 | Systemweit eindeutige Benutzer-Logins über Kontoarten hinweg | ja | belegt | +| SyRS-608 | Geschützte Mitarbeiterverwaltung mit automatischer Personalakte | ja | belegt | +| SwRS-620 | Operationsbezogene Rechteprüfung in AccountBL inkl. Betreuer-Einschränkung | ja | belegt | +| SwRS-624 | Feldbezogene Rechte für Adresssprache/-währung mit Wertrücksetzung | ja | belegt | +| SwRS-625 | Ansprechpartnerpflege mit rollenabhängigen Rechten | ja | belegt | +| SwRS-627 | Dublettenprüfung von Logins und OpenID-Kennungen | ja | belegt | +| SwRS-628 | Mitarbeiterspeicherung mit Rechteprüfung und Personalakten-Ordnern | ja | belegt | +| SwRS-631 | Seriennummernwechsel am Stammblatt nur ohne aktive Klickzähler | ja | belegt | +| SwRS-637 | Berechtigungsprüfung der Kundengeräteverwaltung (Negativbefund) | nein | HYPOTHESE | + +### A7 — Kommunikation & Organisation (9) + +| ID | Titel | PRIMÄR | Status | +|---|---|---|---| +| SyRS-712 | Freischaltung von Absenderadressen beim Mailversand | ja | belegt | +| SyRS-714 | Virtual Mail Assistant: Zugriffsschutz, verschlüsselte Zugangsdaten | ja | belegt | +| SyRS-719 | Tagesabschluss- und Aufgabenverwaltung (Berechtigungslogik) | ja | belegt | +| SwRS-738 | MailScanner-Profile: Rechteprüfung und Master-Key-Verschlüsselung | ja | belegt | +| SwRS-742 | Teams-CallRecords-Sync (Lizenzprüfung) | ja | belegt | +| SwRS-743 | Chat: mitgliedschaftsbasierte Zugriffskontrolle | ja | belegt | +| SwRS-744 | NexusNotification-Massenoperationen nur auf eigene Einträge | ja | belegt | +| SwRS-745 | ToDo-Fremdzugriffs-Rechte | ja | belegt | +| SwRS-747 | VideoPortal-Zuweisung nur mit Recht | ja | belegt | + +### A8 — Web-Client Nexus & Service-Schnittstellen (20) + +| ID | Titel | PRIMÄR | Status | +|---|---|---|---| +| StRS-803 | Abgesicherte Service-Schnittstellen für Clients und Integrationen | ja | belegt | +| SyRS-811 | Policy-basierter Zugriffsschutz (LoginType, Rechte, Lizenz, Port) in Nexus | ja | belegt | +| SyRS-812 | Mehrstufiges Freigabewesen für Warenkörbe im WebCart | ja | belegt | +| SyRS-813 | Token-basierte Angebotsannahme (WebOffer) | ja | belegt | +| SyRS-814 | Online-Signatur von Dokumenten über einmaligen GUID-Link | ja | belegt | +| SyRS-815 | Sichtbarkeitsbeschränkung von Portal-Tickets auf den eigenen Kunden | ja | belegt | +| SyRS-817 | REST-API: JWT-Authentifizierung, Benutzerrechte, 401/403-Semantik | ja | belegt | +| SyRS-818 | Legacy-API: Pflicht-Authentifizierung per Ticket oder Access-Token | ja | belegt | +| SwRS-831 | UserRight-Autorisierungsfilter (Einzel-, Any-, All-Semantik) | ja | belegt | +| SwRS-832 | Hosted-only-Endpunkte über Lizenz CentronInternal | ja | belegt | +| SwRS-833 | JwtAuthController: OpenID-Connect-Login und Kontoverknüpfung | ja | belegt | +| SwRS-834 | 2FA-Code-Validierung über anonymen Bestätigungslink | ja | belegt | +| SwRS-835 | Rechteprüfung WEBACCOUNT_MANAGEMENT in der WebAccount-BL | ja | belegt | +| SwRS-836 | Interceptor-basierte Ticket-/Access-Token-Prüfung mit Sperren | ja | belegt | +| SwRS-839 | ClaimsService: Rechte/Web-Rechte/Lizenzen als Rollen-Claims | ja | belegt | +| SwRS-840 | PortHandler: getrennte Ports für Host- und Kundenportal-Bereich | ja | belegt | +| SwRS-841 | ReceiptCart-Guards: Lizenz, Web-Account-Recht, Kartenzugriff | ja | belegt | +| SwRS-842 | OrdererApproveCart: Pflichtfelder, Statuswechsel, Auftragserzeugung | ja | belegt | +| SwRS-845 | HelpdeskSearchBL: Expression-Filter für Web-Account-Logins | ja | belegt | +| SwRS-848 | Produktionsübersicht ohne deklarativen Autorisierungsschutz (Negativbefund) | nein | HYPOTHESE | + +### A9 — Datenaustausch & Integrationen (10) + +| ID | Titel | PRIMÄR | Status | +|---|---|---|---| +| SyRS-911 | Zugriffsschutz der RMM-REST-Schnittstelle per Zugriffsschlüssel | ja | belegt | +| SyRS-912 | Integrations-Zugangsdaten nur mit Admin-Recht, verschlüsselte Ablage | ja | belegt | +| SyRS-918 | Kundenisolation beim Datenabruf über Web-Zugänge | ja | belegt | +| SwRS-931 | Zeitkonstante Prüfung des RMM-Zugriffsschlüssels | ja | belegt | +| SwRS-932 | RMM-Einstellungen: Rechteprüfung und AES-Verschlüsselung | ja | belegt | +| SwRS-936 | Idempotente DocBee-Zeitbuchungsübernahme mit Abrechnungssteuerung | ja | belegt | +| SwRS-937 | DocBee-Konnektor: Aktivierung über Lizenz/Recht | ja | belegt | +| SwRS-938 | docuFORM-Zugangsdaten mit Masterkey-Verschlüsselung | ja | belegt | +| SwRS-939 | Gerätezähler-Import von docuFORM (abrechnungsrelevant) | ja | belegt | +| SwRS-947 | Berechtigungsschutz Pflege Integrationsstammdaten (Negativbefund) | nein | HYPOTHESE | + +### A10 — Produktion, Projekte, Statistik, Reporting (11) + +| ID | Titel | PRIMÄR | Status | +|---|---|---|---| +| SyRS-1010 | Lizenzgate für alle Produktionsfunktionen | ja | belegt | +| SyRS-1012 | Rechtebasierter Zugriff auf Statistiken und Kennzahlen | ja | belegt | +| SyRS-1014 | Ad-hoc-SQL-Ausführung nur mit Administrationsrecht | ja | belegt | +| SyRS-1017 | MSP-Nutzungsimport und Vertragsabgleich (Abrechnung) | ja | belegt | +| SwRS-1037 | Verkaufsstatistik: Rechte, Filiallimitierung, Web-Account-Schutz | ja | belegt | +| SwRS-1038 | Management-Info-Kennzahlen mit Filialbeschränkung | ja | belegt | +| SwRS-1039 | MSP-Import: Schemata, Duplikatschutz, verschlüsselte Zugangsdaten | ja | belegt | +| SwRS-1040 | MSP-Evaluation: Vertragsanpassung mit Historie | ja | belegt | +| SwRS-1041 | ReportEngine-Abfrageausführung mit Variablenersetzung | ja | belegt | +| SwRS-1044 | Beleg-Massenpreisupdate (Abrechnungsschutzregeln) | ja | belegt | +| SwRS-1045 | Artikel-/Kontenmassenupdate mit Logs | ja | belegt | + +### A11 — Plattform & Querschnitt (7) + +| ID | Titel | PRIMÄR | Status | +|---|---|---|---| +| SyRS-1113 | Verbindungs- und Lizenzüberwachung per Heartbeat | ja | belegt | +| SyRS-1118 | Konfigurierbare KI-Provider-Anbindung mit abgesicherten Endpunkten | ja | belegt | +| SyRS-1121 | Arbeitsplatz-Anpassung über GUI-Profile und externe Tools | ja | belegt | +| SwRS-1134 | Protokollierung von Stundensatz-Zuschlagsänderungen | ja | belegt | +| SwRS-1141 | Validierung der KI-Endpunkt-URLs (SSRF-Schutz) | ja | belegt | +| SwRS-1142 | Verschlüsselte Ablage der KI-API-Schlüssel | ja | belegt | +| SwRS-1145 | Rechteprüfung für globale GUI-Profile | ja | belegt | + +### A12 — Administration & Betrieb (6) + +*SwRS-1233 ist oben unter A1, SwRS-1246 unter A2 gelistet (thematische Zuordnung).* + +| ID | Titel | PRIMÄR | Status | +|---|---|---|---| +| SyRS-1216 | PDF-Signierung als Systemdienst | ja | belegt | +| SyRS-1218 | Stundenzuschlagsmodelle für die Vertragsabrechnung | ja | belegt | +| SwRS-1234 | Mandantenspezifischer KI-Systemprompt nur mit Recht und Lizenz | ja | belegt | +| SwRS-1242 | Rechteprüfung/Verschlüsselung der PDF-Signierungseinstellungen | ja | belegt | +| SwRS-1243 | PDF-Signaturvorgang PKCS#7/SHA256/TSA | ja | belegt | +| SwRS-1245 | Serverseitige Rechteprüfung für Ad-hoc-SQL im SQL-Manager | ja | belegt | + +## Selbstbewertung + +### Mengengerüst und Abdeckung + +- **Analysetiefe über das Inventar (96 Module):** 42 tief, 48 mittel, 6 flach (M28 Produktdaten-APIs, M29 TradePool, M37 Ticket-Projekte, M59 Legacy-Webservices, M65 generischer Datenim-/-export, M67 Gateway), **0 nicht analysiert**. +- **Mindestabdeckung erreicht:** Ja — jedes der 96 Inventarmodule hat mindestens eine Anforderung; kein Modul benötigte die Ausweichkennzeichnung `nicht analysiert`. +- **Anforderungen:** 413 gesamt (50 StRS, 122 SyRS, 241 SwRS), davon 16 Hypothesen (3,9 %), 21 nicht-funktionale mit ISO-25010-Merkmal, 198 risikorelevante (alle regelkonform belegt oder als Hypothese gekennzeichnet), 44 Konsolidierungskandidaten. +- **Belegbasis:** Alle PRIMÄR-Belege wurden im Quelltext bzw. SQL-Schema gelesen; für risikorelevante Anforderungen benennt der PRIMÄR-Beleg durchgängig die durchsetzende Stelle (Datei, Klasse, Methode, konkrete Prüfung). + +### Wo der Beleg dünn war + +- **Negativbefunde als Hypothesen:** Mehrere sicherheitsrelevante Hypothesen beruhen auf der Abwesenheit einer Prüfung (SwRS-637 AccountDeviceBL ohne Rechteprüfung, SwRS-848 `/production/overview` ohne Authorize-Policy, SwRS-947 Integrationsstammdaten, SwRS-1233 Mandantenspeicherung, SwRS-248 Kontoauszugs-Rechte). Abwesenheit ist statisch schwer beweisbar (die Prüfung könnte an nicht gesichteter Stelle liegen) — Verifikation durch Fachexperten bzw. Laufzeittest nötig. +- **Nur clientseitig belegte Regeln:** Pflichtfelder der Custom Properties (SwRS-636), MOVE_HELPDESK_TIMER (SwRS-542), Stundenzuschlags-Validierung (SwRS-1246), KI-Systemprompt-Recht (SwRS-1234) — die Regel existiert, ihre serverseitige Durchsetzung ist offen. +- **Nicht einsehbare Logik:** SocialMedia (Stored Procedures, SwRS-748), Expected-Events-Auswertung (außerhalb der Codebasis, SwRS-545), Reportserver-Ausführungsdienst (SwRS-1043). +- **Sehr große Einzeldateien nur auszugsweise:** `ReceiptBL.cs` (11.441 Zeilen), `InvoiceZugferdBL` (>2.000 Zeilen, kein Feld-für-Feld-Abgleich gegen EN 16931), `ContractEvaluationBL` (1.493 Zeilen), `OrderBalanceBL` (FlatrateBilling-Kern), DATEV-Formatgeneratoren. +- **Nur strukturell erfasst:** M59 Legacy-Webservices (~2.500 Dateien, exemplarisch WebAccount/ReceiptCart/Helpdesk vertieft), `Centron.Controls` (742+ Dateien), Gateway-Adapter. + +### Sicherheits- und Qualitätsbefunde für die Neuimplementierung (Auswahl) + +1. Passworthashing als ungesalzenes SHA1 über Codepage-1252-Bytes (`BasicAuthenticator`, TODO im Code) — im Zielsystem durch moderne KDF ersetzen; identischer Pfad für AppUser und WebAccounts. +2. Hartkodierte Geheimnisse: AES-Fallback-Schlüssel (`AESCryptoLogic`), finAPI-OAuth-Client-Credentials im Quellcode — Geheimnisverwaltung zwingend. +3. SQL-String-Konkatenation in ReportEngine (`ReportDataBL.ExecuteQuery`) und NexusNotifications — parametrisieren. +4. DSGVO-Komplettlöschung für Kunden/Lieferanten/Accounts wirft `NotImplementedException` (nur Kontaktpersonen-Löschung produktiv). +5. Keine gesichtete zentrale Schreibsperre für festgeschriebene Rechnungen (`IsFixed`) im SaveReceipt-Pfad; `RechKopf` ohne Unique-Index auf der Belegnummer — im Zielsystem als harte Invarianten spezifizieren. +6. `CanCloseHelpdesk()` liefert konstant `true` (kein Abschluss-Gate für offene Checklisten/RMA, nur TODO-Kommentar). +7. Schema-Drift: Telemetrie-Tabellen sowie `MasterDataList`/`ObjectExternalReferences` fehlen im Dump `SSMS_DB_SCHEMA.sql` — Schemaquelle und Migrationsskripte abgleichen. +8. Keine datenraumtrennende Mehrmandantenfähigkeit (eine DB, Mandant = Firmenstammsatz) — zentrale Architekturentscheidung für SaaS. + +### Empfehlungen für Folge-Iterationen + +1. **Verifikation der 16 Hypothesen**, vorrangig der fünf sicherheitsrelevanten Negativbefunde (Laufzeittest bzw. gezielte Suche nach der durchsetzenden Stelle). +2. **Systematischer Abgleich clientseitig geprüfter Rechte gegen serverseitige Durchsetzung** (SyRS-110): CentronRights.md-Rechteliste gegen alle WebServiceBL-Speicherpfade. +3. **Abrechnungskern vertiefen:** Positionsbildung des Abrechnungslaufs (VertragPos/VertragArtikel), OrderBalanceBL (Flatrate), Sammelrechnungen, DATEV-Formatdetails, Anzahlungsrechnungen, Provisionslogik. +4. **Legacy-Webservices (M59) flächig erfassen** — dort liegen vermutlich weitere fachliche Regeln und Rechteprüfungen; ebenso ServiceBoard-Zeiterfassung (Abrechnungsrelevanz) und Office/SharedDocument-Signaturpfad. +5. **E-Rechnung Feld-für-Feld** gegen EN 16931 prüfen (InvoiceZugferdBL, ebInterface, Gateway) — zugleich Konsolidierungsentscheidung für einen Generator. +6. **EDI-Distributor-Parser, EscalationBL.DoEscalation, AccountSearchBL, Alt-Migrationen (Anschrif→AccountAddresses)** sowie die ScriptMethods-SQL-Migrationsskripte als Quelle zusätzlicher DB-Regeln. +7. **Lizenzverwaltung (LicenseManager/LicenseGuids)** als eigenes Querschnittsthema erheben. + +### Methodische Anmerkungen + +- Die Anforderungszahlen je Modul in der Abdeckungstabelle enthalten anteilige Zuordnungen; die Summe über die Tabelle ist daher nicht identisch mit der Gesamtzahl 413. +- SwRS-240 wurde nicht vergeben (dokumentierte Nummernkreislücke, kein Inhaltsverlust). +- Die Hypothesenquote (3,9 %) liegt bewusst über null: Alle Aussagen ohne eindeutige Artefaktgrundlage wurden als Hypothese abgegrenzt statt behauptet; zusätzlich benennt die Selbstbewertung offene Punkte, die keiner Anforderung zugeordnet sind (nur hier, nicht in `Hypothesen.md`). +- Änderungshistorie (Commits) wurde nicht als Belegquelle herangezogen; KONTEXT-Belege stammen aus `docs\`, `CentronRights.md` und Code-Kommentaren (inkl. Ticketnummern, z. B. 168245/164153 beim MSP-Abgleich). diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/Glossar.md b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/Glossar.md new file mode 100644 index 00000000..5b813c51 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/Glossar.md @@ -0,0 +1,211 @@ +# Glossar + +**System:** c-entron ERP-Suite | **Datum:** 2026-08-27 + +Domänenbegriffe, wie sie in StRS/SyRS/SwRS verwendet werden. Technische Bezeichner (Klassen, Tabellen, Spalten) stehen in Backticks. + +| Begriff | Definition | +|---------|------------| +| 2FA | Zwei-Faktor-Authentifizierung; beim Login per RADIUS-Server oder E-Mail-Bestätigungslink. | +| Absender-Whitelist | Menge der zum Versand freigeschalteten Absenderadressen (Systemadressen + eigene Mitarbeiteradresse + `ApplicationSettingID.AllowedEmails`). | +| Access-Key (RMM) | Statischer, AES-verschlüsselt gespeicherter Schlüssel im Header `X-RMM-Access-Key` zur Autorisierung der RMM-REST-Schnittstelle. | +| Access-Token | Persistenter API-Schlüssel als Alternative zum Sitzungsticket (`AccessTokensController`, `AccessTokenWebServiceBL`), mit Zugriffsprotokoll (`AccessTokenLog`). | +| Account | Zentraler Geschäftspartner-Datensatz (Tabelle `Accounts`), der über Rollen gleichzeitig Kunde, Lieferant, Kontakt u. a. sein kann. | +| AccountDevice | Datenhaltung für sonstige Kundengeräte/Hardware (Tabelle `AccountDevices`) mit Soft-Delete, Log und Ticketverknüpfung. | +| AccountType / `AccountTypeToAccount` | Rollenzuordnung eines Accounts; verknüpft Account mit Kunden- (`AccountCustomers`) bzw. Lieferantendaten (`AccountSuppliers`). | +| `AESCryptoLogic` | c-entron-Hilfsklasse zur symmetrischen Verschlüsselung gespeicherter Geheimnisse (teils mit zentralem Masterkey aus der Konfigurations-DB). | +| Anrede / Abrede | Einleitungstext (`AN_*`) bzw. Schlusstext (`AB_*`) eines Belegs. | +| `ApplicationSettings` | Aktuelle Tabelle für typisierte Anwendungseinstellungen mit fester numerischer ID (Enum `ApplicationSettingID`). | +| AppUser | Internes ERP-Benutzerkonto eines Mitarbeiters (Mitarbeiterkonto) für die Anwendung, persistiert in Tabelle `Sichbenu`. | +| Artikel | Stammdatensatz eines Produkts/einer Dienstleistung (Tabelle `ARTIK`), identifiziert durch I3D und fachlich durch Artikelcode. | +| AssetManagement-Gerät | Extern (DocuBoard/River, AD/SNMP-Monitoring) synchronisierte Gerätedaten mit eigener Objektart `AssetManagementDeviceClass` (5101330). | +| AssetReason (QM-Grund) | Je Belegart gepflegter Rückgabe-/Reklamationsgrund mit Pflichtkennzeichen (`IsMandatory`). | +| AuthentificationKind | Pro Benutzer gespeichertes Anmeldeverfahren (CentronLogin/WindowsAuth/OpenIdConnectAuth), Spalte in `Sichbenu`. | +| AVV | Auftragsverarbeitungsvertrag (DSGVO Art. 28); im DSGVO-Modul als Vorlage und je Kunde als `OrderProcessingContract` verwaltet. | +| Barbeleg / Barrechnung (`IsCashAsset`) | Bar abgewickelter Beleg mit bruttobasierter Steuerrundung und eigenem Nummernkreis; vom Storno ausgeschlossen. | +| BatchId | Gruppenkennung mehrtägiger MyDay-Serieneinträge; 0 = Einzeltag. | +| Beleg | Geschäftsdokument der Verkaufs-/Einkaufskette (Angebot, Auftrag, Lieferschein, Rechnung, Gutschrift, Abholschein u. a.), technisch `IReceiptBase` mit Kopf und Positionen. | +| Belegart | Typ eines Belegs (`CentronObjectKindNumeric`, z. B. OrderClass, InvoiceClass); steuert Rechte, Nummernkreis und Weiterverarbeitungsziele über SpecificLogics. | +| Belegkette / Weiterverarbeitung (Forwarding) | Erzeugen eines Folgebelegs aus einem oder mehreren Quellbelegen mit Datenübernahme; Herkunft wird beidseitig gespeichert. | +| Belegkondition (`AssetCondition`) | Zahlungs-, Liefer- oder sonstige Kondition mit länderspezifischen Texten, Fälligkeitsart und Mindestbetrag. | +| Belegstatus Aktiv (`ReceiptState.Active`) | Einziger Belegzustand, in dem Massenänderungen an Belegpreisen zulässig sind. | +| Belegversion | Historisierte Ausprägung eines Belegs; Änderungen erzeugen Version+1, Vorversionen bleiben erhalten. | +| Belegzuordnung (`IsAssignedToAsset`) | Verweis einer Zeit auf eine Auftrags-, Lieferschein- oder Rechnungsposition (`AufPosI3D`/`LiefPosI3D`/`RechPosI3D`); macht die Zeit unveränderlich. | +| Bestellvorschlag | Automatisch berechnete Vorschlagsliste zu bestellender Mengen aus Auftragsbedarf, Mindestbestand, Bestand und Zulauf. | +| Betreuer (Adviser) | Bis zu sechs am Account hinterlegte Mitarbeiter (`Adviser1I3D`..`Adviser6I3D`), die für den Kunden verantwortlich sind. | +| BL / DAO / ILogic | Schichten: Business Logic (Entities/NHibernate), Data Access (Sessions/Mappings), clientseitige Logik-Schnittstelle mit BL- (Direkt-DB) und WS- (WebService) Implementierung. | +| CentronHosted | Autorisierungs-Policy, die Endpunkte auf von c-entron gehostete Installationen (Lizenz CentronInternal) beschränkt. | +| `CentronObjectKindNumeric` (ObjectKind) | Systemweite numerische Objektart-Enumeration/-Kennung (z. B. Account, HelpdeskClass, MasterDataListClass=25, AssetManagementDeviceClass=5101330) zur generischen Adressierung von Geschäftsobjekten. | +| ChangeLog | Generische Änderungshistorientabelle, adressiert über ObjectKind (Objektart) + ObjectI3D. | +| Chargeback | Rücklastschrift; negative Zuordnung, die auch geschlossene Rechnungen wieder öffnen darf. | +| Checkliste (`CentronChecklist`) | Hierarchische Aufgabenliste mit Punktzuständen (u. a. Open), generisch über ObjectKind/ObjectI3D an Objekte wie Tickets gebunden. | +| Check-out / Check-in | Exklusives Sperren eines Dokuments der Dateiablage zur Bearbeitung (mit Arbeitsstation) und Rückgabe als neue Version. | +| Click-Vertrag | Vertrag, der Gerätezählerstände (z. B. Druckseiten) als Differenzmenge abrechnet (`ContractExtraKind.ClickDevice`). | +| ConnectionManager | WPF-Werkzeug zur Pflege der `WebServiceConfig.xml` (DB-Verbindung, Proxy, AD, Zertifikate, Secret Key). | +| DataQualityService | Hintergrunddienst, der Datenbereinigungs- und Reparaturaufgaben in isolierten Einzelschritten ausführt. | +| DetachedFromOrigin | Kennzeichen einer Vertragsposition, dass die Verknüpfung zum erzeugenden Ursprungsauftrag gelöst wurde (verhindert Rückwirkungen bei Mengenänderungen). | +| Direktlieferung | Lieferung vom Distributor direkt an den Endkunden ohne eigenen Lagerdurchlauf (`AufPos.Direktlieferung`). | +| D!VE-Profil | Gespeicherte Exportvorgaben (Mandant, Rahmenvertrag, feste Zahlungs-/Rabatt-/USt-Werte) für den D!VE-Export (Entität `TelekomDiveProfile`). | +| DocBee | Externes Service-Management-/Vorgangssystem; angebunden über Webhooks und die DocBee-Konnektor-BLs. | +| DocSync | Mechanismus zur Bereitstellung von c-entron-Dokumenten/Verzeichnissen an eine externe Synchronisation, gefiltert nach Objektarten. | +| docuFORM | Fleet-/Print-Management-Server; liefert Druckgeräte und Seitenzähler über eine OAuth2-geschützte REST-API. | +| EAV | Entity-Attribute-Value: generisches Speichermuster mit typisierten Wertspalten je Attribut. | +| ebInterface | Österreichisches E-Rechnungsformat (hier Version 4.3). | +| EDI | Electronic Data Interchange — strukturierter elektronischer Belegaustausch mit Lieferanten/Distributoren (Bestellung, Bestellbestätigung, Lieferschein, Rechnung). | +| ElectronicSales (ES) | Webshop-System; dessen Kundengruppen/Rollen werden als lokale Caches (`EsCustomerGroup`/`EsRole`) geführt. | +| Empfänger-Bitmaske | Kodierung der Eskalationsempfänger einer Stufe als Summe von Empfänger-IDs in einer Integer-Spalte (`StageNReceivers`). | +| Eskalation | Zeitgesteuerte, bis zu dreistufige E-Mail-Benachrichtigung bei überfälligen Vorgängen (Tabellen `eskalationen`/`eskalationTypen`); die erreichte Stufe wird in `hlpdsk_requests.EscalationLevel` geführt. | +| Eskalationstyp | Konfigurierbares dreistufiges Regelwerk für die automatische Eskalation überfälliger Vorgänge, je Objektart bzw. Ticketpriorität: Wartestunden/Fristen je Stufe (`Hour1`-`3`), Geschäftszeitfenster, Sa/So-Flags und Empfängerkreise je Stufe. | +| EWS | Exchange Web Services; klassische Microsoft-Exchange-API, im System für Kalender- und Mailzugriff genutzt. | +| Expected Event | Definition eines je Wochentag erwarteten externen Ereignisses (z. B. Backup-Meldung) mit Textmustern zur Erfolgs-/Warn-/Fehlerklassifikation und Logeinträgen mit Ticketbezug. | +| Externes Tool | Konfigurierbares Fremdprogramm (Pfad + Argumente) mit @@Platzhalter@@-Ersetzung aus dem Fachkontext. | +| Externreferenz (`ObjectExternalReference`) | Generische Verknüpfung eines c-entron-Objekts (ObjectI3D + ObjectKind) mit einem Objekt eines Fremdsystems (ExternalReferenceType + ExternalReferenceID), z. B. DocBee. | +| Fälligkeit (`DueDate`/`FaelligAm`) | Aus der Ticketpriorität (Reaktionszeit in Stunden, Bürozeiten, Sa/So-Regeln) berechneter Zieltermin für die Ticketbearbeitung. | +| Festschreibung (`IsFixed`) | Unveränderlichkeits-Kennzeichen einer Rechnung (`RechKopf.IsFixed`=1), gesetzt mit Protokolleintrag. | +| FiBu-Export | Übergabe von Buchungs-/Stammdaten an Finanzbuchhaltungssysteme (DATEV, Abacus, Sage u. a.). | +| Filialbeschränkung | Rechtegesteuerte Einschränkung von Auswertungen auf die Filiale (Branch) des angemeldeten Mitarbeiters. | +| Filiale (Branch) | Standort/Niederlassung (organisatorische Einheit) eines Mandanten (Tabelle `Filiale`, `BranchDTO`); genau eine Filiale je Mandant ist Standard. `BranchI3D` bindet Rechtegruppen und restriktive Rechte an Standorte; „nur eigene Filiale"-Rechte binden den Belegzugriff an die Filiale des Benutzers. | +| finAPI | Externer Kontozugriffs-/PSD2-Dienst (live/sandbox.finapi.io), angebunden über REST v2 und WebForm. | +| Firmengruppe (`CompanyGroup`) | Konzernklammer über Konten; kann Preisliste, Sonderpreise und Leitweg-ID für Belege vorgeben. | +| Freigabewesen | Mehrstufiger Genehmigungsworkflow des Warenkorbs (Prüfer → Besteller) über die Zustandsmaschine `ReceiptCartState`. | +| Fremd-Todoliste | Recht (RIGHT_FREMDTODOLISTE), die ToDo-Listen anderer Mitarbeiter einzusehen; RIGHT_FREMDTODOLISTEVERWERFEN erlaubt das Verwerfen fremder ToDos. | +| Fremdware | Im RMA angenommener Artikel ohne eigenen Verkaufsbeleg; wird in ein RMA-Kundenlager (`StockKind.RmaCustomer`) eingebucht. | +| Gateway | Projekt `Centron.Gateway`: Sammlung von Formatadaptern (EDI, FiBu, SEPA, OpenTrans, ZUGFeRD, FinTS). | +| Gläubiger-ID (`SepaIdentificationNumber`) | SEPA-Gläubigeridentifikationsnummer des Mandanten (Mandator). | +| Gleitender EK | Mengen-gewichteter Durchschnitts-Einkaufspreis, der bei jedem Wareneingang fortgeschrieben wird (Alternative: Fest-EK, letzter EK; `ARTIK`-Feld `NoMixedEk`). | +| Globaler Zuschlag | Das per Einstellung `GlobalHourlySurchargeRateI3D` als systemweiter Standard markierte Zuschlagsmodell; nicht deaktivierbar. | +| Gruppen-Settings-Klasse | Serverseitige Klasse, die fachlich zusammengehörige Einstellungen gebündelt lädt, typisiert bereitstellt und speichert (z. B. `PdfSigningSettings`). | +| GUI-Profil | Gespeichertes Oberflächen-Layout (`CentronUiProfiles`), privat je Benutzer oder global (`IsGlobal`) für alle. | +| Gutschein (Voucher) | Barcode eines Gutscheinartikels; Status frei/ausgegeben/eingelöst über `GutscheinZuRechnung` abgeleitet. | +| Hauptlager | Implizites Basislager eines Artikels; im Code als Lager-I3D -1 geführt, Bestand in `ARTIK.Menge`. | +| Hauptposition (`IsMainItem`) | Die genau eine Position eines Stammblatts, die das Hauptgerät (Menge 1) repräsentiert. | +| Heartbeat | Zyklischer Client-Server-Ping (5 Minuten) zur Validierung von Sitzung und Lizenz. | +| Helpdesk-Status (`HelpdeskState`) | Frei konfigurierbarer Datensatz in `hlpdsk_status`, der die Lebenszyklusphase eines Tickets angibt; ein per AppSetting bestimmter Status gilt als „Abgeschlossen". | +| Helpdesk-Timer (Zeit) | Erfasste Arbeitszeit/Zeitbuchung eines Mitarbeiters auf einem Ticket (Tabelle `hlpdsk_timer`) mit Berechenbar-Flag (`Calculable`, steuert die Fakturierbarkeit) und optionaler Beleg-Zuordnung; Basis der Leistungsabrechnung. | +| Herstellercode (`ManufactorCode`/`ManufacturerCode`) | Artikelnummer des Herstellers; Zuordnungsschlüssel beim Preislistenimport. | +| Heuristik / MatchingRate | Herkunftskennzeichen und Güte einer automatischen Umsatz-Beleg-Zuordnung. | +| Hintergrunddienst (`ManagedBackgroundService`) | Im Webservice-Host laufender periodischer Job, dessen Aktivierung und Laufzeiten über die Tabelle `BackgroundServices` gesteuert/protokolliert werden. | +| I3D | „ID 3develop": systemweiter technischer Primärschlüssel (int IDENTITY) nahezu aller c-entron-Tabellen und -Entitäten; Fremdschlüsselspalten tragen das Suffix I3D. Wird auch als fester ID-Wert von Rechten verwendet. | +| Interne Rechnung | Rechnung nur mit Dienstleistungspositionen zum Gesamtwert 0,00, nummeriert aus eigenem Nummernkreis (InternalInvoice). | +| Inventur | Stichtagsbezogene Bestandszählung je Lager mit anschließender Buchbestandskorrektur; Voll- (Komplett-) oder Teilinventur. | +| Kalkulationsfaktor | Mandantenweiter Faktor (AppSetting `ArticleCalculationFactor`), mit dem Einkaufspreise bei Bewertung/Anzeige multipliziert bzw. dividiert werden. | +| Klickzähler / Seitenzähler (`DeviceClickCounter`) | Zähler eines Stammblatt-Geräts (z. B. Seitenzähler von Druckgeräten); Grundlage der verbrauchsbasierten Abrechnung von Click-/Managed-Print-Verträgen. | +| Kommissionierung | Zusammenstellen der Auftragspositionen im Lager mit Rückmeldung gepickter Mengen (`QuantityPicked`). | +| Kontenrahmen (`BookKeepingAccountSystems`) | Zuordnung Erlös-/Aufwandskonten zu Steuersätzen für den Export. | +| Kontingentrest-Mitnahme (`KontingentRestMitnehmen`) | Option, nicht verbrauchte Kontingente in die Folgeperiode zu übertragen. | +| Kontingentvertrag | Vertrag mit gebuchtem Leistungsvolumen (z. B. Stunden); Verbrauch wird gegen Buchungen (`VertragRechKopfZuordnung`) gerechnet. | +| Kontoauszug (`OnlineBankingAccountTransaction`) | Importierter Bankumsatz einer Onlinebanking-Konfiguration (FinTS/finAPI/Spreadsheet). | +| Kostenstelle / Kostenträger (`CostCenter`/`CostObject`) | Controlling-Stammdaten zur Belegzuordnung; Soft-Delete über State-Feld. | +| Kreditlimit | Kundenindividuelle Obergrenze des offenen Belegvolumens (netto/brutto); Überschreitung erfordert Bestätigung. | +| Kundensonderpreis (`KundenSonderpreise`) | Kunden-/warengruppenbezogene Preisregel mit Gültigkeitszeitraum und Preisbasis (`SpecialPriceKind`). | +| `Laenkenn` | Ländertabelle (Legacy-Name) mit Währung (`KursZuEur`), Vorwahl, MwSt-Art, Erlöskonten, Standardland-Kennzeichen. | +| Leitweg-ID | Adressierungskennung öffentlicher Auftraggeber in Deutschland; am Kunden bzw. dessen Firmengruppe gepflegt. | +| Löschprotokoll | Bei DSGVO-Löschung erzeugtes Textprotokoll („c-entron Löschprotokoll") aller entfernten personenbezogenen Angaben. | +| Mahnlauf | Ein Ausführungsvorgang des Mahnwesens; protokolliert je Rechnung in Tabelle `Mahnlauf` unter fortlaufender MahnLaufNr. | +| Mahnsperre (DunningStop) | Kennzeichen/Zeitraum auf Kunde oder Rechnung, das die Aufnahme in Mahnvorschläge verhindert. | +| Mahnstufe (DunningLevel) | Eskalationsstufe einer überfälligen Rechnung (je nach Sicht 0–3 bzw. 1–3), gespeichert in `RechKopf.Mahnstufe` mit Datum und Bearbeiter je Stufe. | +| Mailing | Kampagnenbezogener Massenversand (E-Mail/SMS) mit personalisierten Empfängertexten und Versandkennzeichen. | +| MailTemplateReference | Eindeutige Identifikation einer Mail-Vorlage über ObjectKind, SubObjectKind, ObjectI3D und TemplatePrio (Tabelle `MailVorlagen`). | +| Mandant (Mandator) | Rechtlich/organisatorisch eigenständige Firma innerhalb einer c-entron-Installation mit eigenen Stammdaten (Anschrift, Bankverbindungen, USt-ID, Logos) und Belegnummernkreisen (Tabelle `Mandant`, Entität Mandator); zugleich die eigene Firma des Systemhauses als Absender-Stammdaten für Belege. Getrennte Datenhaltung je Firma (MandantID in `Sichbenu`), wobei alle Mandanten eine Datenbank teilen; nicht zu verwechseln mit SaaS-Mandantentrennung. | +| Mandatsreferenz (`AuthorizationNumber`) | Eindeutige Kennung des SEPA-Mandats an der Bankverbindung. | +| Maschinenart (`ProductionMachineKind`) | Klassifikation von Produktionsmaschinen; trägt wiederverwendbare Arbeitsschrittbeschreibungen (`ProductionMachineKindStepsDescription`). | +| Massenupdate-Vorlage (`MassUpdateTemplate`) | Benannter Massenänderungslauf mit Einzelpositionen (Items) je Zielobjekt, Ausführungsstatus und Fehlergrund. | +| Masterkey / Masterschlüssel | Zentraler mandantenweiter symmetrischer Schlüssel aus der Konfigurations-DB (`CentronConfigurationDbBL`; „Hotline-Masterkey") zur AES-Ver-/Entschlüsselung gespeicherter Geheimnisse, z. B. der Zugangsdaten des Passwortmanagers sowie der Postfach-Passwörter und Client-Secrets der VMA-Profile. | +| MCP-Tool | Werkzeug des Model-Context-Protocol-KI-Assistenten, dessen Nutzung telemetrisch gezählt wird (`McpToolUsageTelemetry`). | +| Microsoft Graph | Moderne Microsoft-365-API; alternativer Mail-Transport (GraphMail) und Quelle der Teams-Anrufdaten (CallRecords). | +| Mindestpreis (`MinPrice`) | Artikeluntergrenze für den Netto-VK; Unterschreitung erfordert Recht ALLOW_IGNORE_MINIMUM_PRICE. | +| Mitarbeiter (Employee) | Personalstammsatz (Tabelle `Personal`) mit Kürzel (`ShortSign`), Filiale (`BranchI3D`) und Personalakten-Ordnern. | +| MSP | Managed-Service-Provider — Systemhaus, das IT-Betrieb für Kunden übernimmt; Zielgruppe von c-entron. | +| MSP-Collector | Konfigurierte Importschnittstelle zu einem Managed-Service-Lieferanten (z. B. Veeam, Octopus, ArrowSphere), die Nutzungs-/Abrechnungsdaten abholt. | +| MSP-Evaluation | Positionsweiser Abgleich importierter Lieferantenabrechnungen mit Kundenvertragspositionen inklusive Übernahmeentscheidung (Menge/Preis/ignorieren). | +| Nebenlager | Zusätzliches, in `Warehouses` definiertes Lager; Artikelbestand je Nebenlager in `NebenlagerArtikel`. | +| Nexoware Smartflow (CPra) | Externer Formular-/Workflow-Dienst; c-entron erzeugt vorbefüllte Webhook-Links. | +| NexusNotification | Persönliche Benachrichtigung im Nexus-Web-Client mit getrennten Zuständen `IsSeen` (Badge) und `IsRead` (gelesen), gepusht über SignalR-Hub. | +| Normierung (`RechnungNormieren`) | Tagesanteilige Berechnung angebrochener erster/letzter Abrechnungsperioden auf Kalendermonat/-quartal/-jahr. | +| Nummernkreis (`NumberGroup`) | Zentraler konfigurierbarer Zähler für fortlaufende Nummern (Tabelle `Nummernkreis`), je Belegart/Mandant/Filiale zur Vergabe eindeutiger Belegnummern sowie für Account-, Kunden- und Lieferantennummern (via `NumberGroupBL.GetNextNumber`). | +| OnlinePdfDocument | Per GUID adressiertes, einmalig signierbares PDF-Dokument (`DsgvoBL`); nach Bestätigung gelöscht. | +| OpenTRANS 2.1 | XML-Standardformat für Geschäftsbelege; Standardformat des Bestellversands. | +| OPOS | Offene-Posten-Liste: aktive Rechnungen abzüglich Zahlungen und verrechneter Gutschriften je Kunde; Versandform „Kontoauszug". | +| Pauschalabrechnung (FlatRate) | Auftragbasierte Pauschalfaktura; zugehörige Zeiten sind von der Einzelzeitabrechnung ausgeschlossen (`IsFlatRateItem`). | +| PDF/A | ISO-Normfamilie für Langzeitarchivierung von PDF; im System als Konformitätsstufen PDF/A-1a bis PDF/A-3b sowie PDF/X wählbar. | +| Personalakte | Automatisch angelegte Dokumenten-Ordnerstruktur je Mitarbeiter (Zertifikate, Verträge, Gesprächsnotizen usw.). | +| PLM (`ProductLifecycleInformation`) | Product Lifecycle Management — Lebenszyklusdatensatz einer verkauften Lizenz/eines Abos (Quelle meist Rechnungsposition) mit Laufzeit (`StartDate`/`EndDate`), Kunde und Angebotsstatus; das Verwerfen des zugehörigen ToDos deaktiviert die Lizenz und wird protokolliert. | +| `PORTRECH` / `PORTWARE` | Flag-Tabellen für bereits an die FiBu exportierte Kunden- bzw. Lieferantenbelege. | +| Preisliste (VK1–VK4) | Vier Verkaufspreisfelder je Artikel; `Customer.PriceList` wählt den anzuwendenden VK. | +| Produktfamilie (`ProductFamily`/`-Group`) | Fachliche Gruppierung von Artikeln im PLM zur Zuordnung von Lebenszyklusdaten. | +| Produktionsauftrag (`ProductionOrder`) | Fertigungsauftrag, der zwingend auf einen Verkaufsauftrag (`OrderI3D`/`OrderNumber`) verweist und Arbeitsschritte (`ProductionOrderItems`) bündelt. | +| Produktionsschritt / Werkschritt (`ProductionOrderItem`) | Einzelner Arbeitsschritt eines Produktionsauftrags mit Maschinenart/Maschine, Soll-/Ist-Menge und Zustand (`ProductionOrderItemState`: Offen/OpenNotStarted, In Bearbeitung, Beendet/Finished). | +| Produktmatrix | Bewertungsraster Kunde × Produkt mit 4 Potenzialstufen und Änderungshistorie. | +| QmNotification | Dreistufiger Benachrichtigungsmodus je Belegart: keine / Nachfrage / immer. | +| Recht | Einzelberechtigung mit fester I3D (Tabelle `Sichrech`), im Code über `UserRightsConst` referenziert. | +| Rechtegruppe | Gruppe (Tabelle `Sichgrup`), der Rechte (`Sichtrus`) und Benutzer (`Sichmemb`) zugeordnet werden. | +| ReportEngine / ReportData | Neuere Berichtsverwaltung auf FastReport-Basis (XML im DB-Feld `Report`) mit Gruppen (`ReportGroup`, GUID je Belegart) und Abfragen (`ReportDataQuery`). | +| Reports (Alt-Tabelle) | Legacy-Berichtsspeicher (`dbo.Reports`, deutsche Spalten) mit eigener BL — Parallelbestand zur ReportEngine. | +| Restriktives Recht | Recht, das Befugnisse einschränkt statt erweitert (z. B. MANAGE_RIGHTS_ONLY_OWN_BRANCH, „nur eigene"-Rechte). | +| Result / `Result` | Einheitliches Rückgabemuster der Logikschicht mit Status (Success/Error), Meldung und Nutzdaten statt Exceptions. | +| Richtlinie (Guideline) | Passwortmanager-Regelwerk, das je Kunde und Mitarbeiter feingranulare Zugriffsrechte (Bitflags) auf Zugangsdaten definiert. | +| Riverbird / RiverDivo | RMM-Produkt bzw. dessen c-entron-Anbindung (Namespace `RiverDivo`); Legacy-Zugang per Ticket, neuer Zugang per RMM-Access-Key. | +| RMA | Return Merchandise Authorization — Retourenvorgang mit Statushistorie je reklamiertem Artikel. | +| RMM | Remote Monitoring & Management — Fernüberwachungs-/Verwaltungssystem eines Managed-Service-Providers (hier v. a. Riverbird). | +| SelfCare-Formular / WebForm | Konfigurierbares Kundenformular, das über einen GUID-Link mit Ablaufdatum extern (ServiceBoard-Web) ausgefüllt wird. | +| SendBack | RMA-Rücksendung defekter Ware an den Lieferanten (`RmaSendBack`). | +| SendForth | RMA-Vorab-/Ersatzlieferung an den Kunden (`RmaSendForth`). | +| SEPA-Mandat (`SepaContract`) | Lastschriftmandat mit Status Draft/Accepted/Declined/LinkExpired und Online-Unterschriftsprozess; als Signaturdokument mit Pflicht-Bankdaten (Bankname, IBAN, BIC) über die DocumentSigning-Seite erteilt. | +| Seriennummer / Barcode | Einzelstück-Identifikation eines Artikels (Tabelle `Barcode`, Entitäten `BarCode`/`BarCode2`) mit eigenem Statuslebenszyklus (`BarcodeState`). | +| Seriennummernpflicht (`ScanBarcode`) | Artikelkennzeichen (`ARTIK.BarcodeScanen`), das die Bestandsführung auf Seriennummernzählung umstellt. | +| ServiceBoard (SBO) | Web-Frontend der Suite; je nach Sicht browserbasierter Mitarbeiter-Arbeitsbereich für Tickets, Planung und Zeiterfassung (Lizenz ServiceBoardWebDev) sowie Zugangspunkt für Kunden-/Technikerzugriffe (Formulare, Umfragen, Tickets); Basis-URL in den Einstellungen. | +| SETTINGS-Recht | Benutzerrecht `UserRightsConst.Administration.SETTINGS`; Voraussetzung für die Pflege von Integrations-/Systemeinstellungen. | +| Siegel / Siegelbruch | Schutzmechanismus des Passwortmanagers: versiegelte Zugangsdaten dürfen nur mit SealBreak-Recht, Begründung, Protokoll und E-Mail-Meldung geöffnet werden. | +| SimpleUrl / WebLink | Zwei getrennte Datenhaltungen für objektbezogene URLs; WebLinks besitzen zusätzlich Gruppen und ausführbare Aktionen (`WebLinkAction`). | +| Skonto-Ausschluss (`NoEarlyPaymentDiscountAllowed`) | Positionskennzeichen, das die Position aus der Skontobasis herausnimmt (NotDiscountable-Summen). | +| Soft-Delete | Logisches Löschen per Kennzeichen statt physischem Entfernen des Datensatzes; je nach Modul über Statusfeld (State=0) oder über `IsDeleted`/`DeletedByI3D`/`DeletedDate`. | +| Sondervereinbarung (SpecialAgreement, Projektpreis) | Kunden-, projekt- oder auftragsbezogenes Preisabkommen: verkaufsseitig eine Preisliste mit eigenen EK/VK bzw. prozentualen Reduktionen, Artikelpositionen und zugeordneten Kunden; einkaufsseitig eine auftrags-/projektbezogene Einkaufspreisabsprache (`SondervereinbarungI3D`) mit Gültigkeitsdatum, die vom Standard-EK-Verfahren ausgenommen ist. | +| Staffelpreis (`ArticleVolumePrices`) | Mengenabhängige EK/VK-Preise eines Artikels. | +| Stammblatt (MasterDataList) | Gerätedatensatz des Kunden für abrechnungsrelevante Geräte (v. a. Drucker/Kopierer) mit Hauptposition, Seriennummer, Klickzählern und Click-Vertragszuordnung; Träger der Gerätezähler; UI-Bezeichnung der Objektart `MasterDataListClass` (25). | +| `Stammdat` | Legacy-Einstellungstabelle (Zugriff über Enum `AppSettingsConst`); für neue Einstellungen gesperrt. | +| Standardmandant | Der genau eine Mandant mit `Default`=true; er kann nicht gelöscht/deaktiviert werden und dient als Fallback (z. B. für Logos). | +| Stemming | Rückführung von Wörtern auf ihre Stammform (`GermanAnalyzer`, angelehnt an Lucene.NET GermanStemmer). | +| Storno | Aufhebung einer Rechnung als neue Belegversion mit Status „storniert" und genullten Mengen; nur mit Recht RIGHT_RECHNUNGSTORNIEREN. | +| Stundenzuschlagsmodell (`HourlySurchargeRate`) | Satz von Zeitfenstern mit prozentualen Zuschlägen je Wochentag/Feiertag, der Verträgen zur Abrechnung von Arbeitszeiten zugeordnet wird. | +| Sync-Mitglied | Mitarbeiter, dessen Teams-Anrufe beim Graph-CallRecords-Sync in das Anrufjournal übernommen werden. | +| Tag | Normalisiertes (lowercase, getrimmt) freies Schlagwort (Tabelle `Tags`), Objekten z. B. Tickets über `TicketTags` zugeordnet. | +| Tagesabschluss (`MyDayFinalizedDay`) | Verbindliche Bestätigung eines Mitarbeiters, dass sein Arbeitstag in MyDay vollständig erfasst ist; fehlende Abschlüsse lösen Erinnerungen und Teamleiter-Eskalation aus. | +| TAPI | Telephony API; Windows-Telefonie-Schnittstelle, über die der Client Anrufe meldet, die als `PhoneCall` protokolliert werden. | +| TaskManager-Aufgabe | Wiederkehrende Aufgabe (`TaskManagementTask`) mit Wiederholungsregel (Recurrence) und Aktion, z. B. automatischer Ticketanlage (`TaskManagementHelpdeskAction`). | +| Teilkommission | Kommissionierung einer Teilmenge eines Auftrags (`PartialCommissionOrder`). | +| Telekom D!VE | Telekom-Partnerportal/Marktplatz; c-entron exportiert Angebote als D!VE-XML. | +| Telemetrie-Bucket | Zeitfenster (`BucketStartUtc`), auf das Nutzungsereignisse aggregiert werden; gespeichert wird nur ein Zähler je Schlüsselkombination. | +| Terminanfrage (`AppointmentRequest`) | Vorgang, bei dem einem Kunden mehrere Terminvorschläge (`AppointmentProposal`) angeboten werden; Antwort erfolgt über eine Guid und schaltet den `RequestState` weiter. | +| Textbaustein (TextModule) | Wiederverwendbarer Anrede- oder Schlusstext je Belegart/Helpdesk-Kontext mit @@-Platzhaltern; Auflösung kundenspezifisch vor benutzerspezifisch vor global. | +| Ticket (Authentifizierung) | Serverseitig gespeichertes/verwaltetes Sitzungs-Token mit Ablaufdatum, ausgestellt nach erfolgreicher Anmeldung (`TicketBL`); wird bei jedem Legacy-Aufruf validiert und verlängert. Nicht zu verwechseln mit dem Helpdesk-Ticket. | +| Ticket (Helpdesk-Fall) | Kundenbezogener Service-/Support-Vorgang in Tabelle `hlpdsk_requests` (Entität `Helpdesk`/`HelpdeskCompact`), auch im ServiceBoard/Kundenportal sichtbar; „Ticket" und „Helpdesk(-Fall)" werden in der Codebasis synonym verwendet. | +| Ticket-Projekt | Bündelung von Tickets mit eigenem Nummernkreis, Aufgaben, Abhängigkeiten, Nachrichten und Logs (`TicketProject`; `hlpdsk_requests.ProjectHelpdeskI3D`). | +| TimerBilling | Abrechnung erfasster Helpdesk-Zeiten (HelpdeskTimer) über Aufträge/Rechnungen. | +| ToDo / Wiedervorlage | Aus Geschäftsobjekten (Belege, Verträge, Tickets, PLM-Lizenzen, Geburtstage, Videozuweisungen) erzeugter Aufgabeneintrag mit Read-/Discarded-Status. | +| Toleranzfrist (`DaysToTolerate`) | Konfigurierte Anzahl Tage, innerhalb derer ablaufende Lizenzen Wiedervorlagen (ToDos) erzeugen. | +| TOTP-PIN | Zeitbasiertes Einmalpasswort (Google-Authenticator-Verfahren) gegen den in `Sichbenu.TwoFactorAuthKey` hinterlegten Schlüssel. | +| TradePool | Separater, per XML befüllter Katalog von Handelsartikeln (`TradeArticles`) mit Klassenhierarchie; Nutzung unklar. | +| TSA | Time Stamping Authority; Zeitstempeldienst (RFC 3161), der Signaturen einen beglaubigten Zeitpunkt hinzufügt. | +| Umfrage-Instanz | Antwortleere Kopie einer Umfragevorlage (`SurveyProcessTemplate`) mit Status Open, Objektbezug und verschlüsseltem Zugriffslink. | +| UniqueId (`MyDayWorkItem`) | Fachlicher Eindeutigkeitsschlüssel (Type + ObjectI3D bzw. Type + I3D) zur Deduplizierung automatisch erzeugter Zeiteinträge. | +| Update-Benachrichtigungsart (`UpdateAvailableNotificationKind`) | Einstellung, die die Zielgruppe von Update-Hinweisen festlegt (keine, Administratoren, ausgewählte Mitarbeiter, alle). | +| Verknüpfungsnummer (`ConnectionNumber`) | Fortlaufende Nummer, die mehrere Tickets zu einer Gruppe (`HelpdeskConnections`) bündelt. | +| Vertragssonderpreis (`ContractSpecialPrice`) | Preisregel aus einem Vertrag; hat Vorrang vor Kundensonderpreisen. | +| VMA (Virtual Mail Assistant) | Mail-Eingangs-Scanner (MailScanner), der Postfächer über Profile abruft und eingehende Mails Workflows zuführt; lizenz- (MailScannerNET) und rechtegeschützt (ACCESS_VMA_MODULE). | +| Volltextindex | Datenbanktabelle `ObjectFulltextIndex` mit gestemmten Termen je Objekt; Suche = UND-Verknüpfung von Präfixtreffern. | +| Vorab-/Nachberechnung (Billingadvance/Billingarrear) | Abrechnung vor Beginn bzw. nach Ende des Leistungszeitraums. | +| Vorgang (DocBee) | Ticket-Äquivalent in DocBee; referenziert über `ObjectExternalReference` mit Typ „DocBee". | +| Vorlagen-Fallback | Auflösungsreihenfolge einer Mail-Vorlage: Kunde (Account) → Mitarbeiter → Filiale (Branch) → global → Systemstandard. | +| Warenkorb (`ReceiptCart`) | Web-Warenkorb, technisch ein ReceiptOffer (`AngKopf`) mit `IsCart`=true und CartState (`ReceiptCartState`). | +| Web-Account (WebAccount) | Externes Portal-Konto/Kundenlogin (Self-Service-/Webportal, ServiceBoard) eines Kunden-/Account-Ansprechpartners, persistiert in Tabelle `WebAccounts`; eigener Login-Typ „Webaccount" mit eigenem Rechtesystem (WEBRIGHT_*, Enum `WebAccountRightsConst`), abgegrenzt vom internen Mitarbeiter-Login (AppUser); besitzt keinen Mitarbeiterkontext und unterliegt Kundenisolation (darf nur Daten des eigenen Kunden sehen). | +| Web-Receipt / Web-Angebot | Per Token im Browser bereitgestellter Beleg (Angebot) mit eigenem Zustandsmodell `WebReceiptState` (Annahme/Ablehnung/Änderungswünsche). | +| Web-Recht | Berechtigung eines Web-Accounts (Enum `WebAccountRightsConst`, z. B. WEBRIGHT_WEBCART2_CHECK_CART); unabhängig von den Mitarbeiterrechten (`UserRightsConst`, int-I3Ds). | +| Werbesperre (`AdvertisingNotAllowed`) | Kennzeichen am Konto, dass keine Werbung zugesendet werden darf. | +| XRechnung / XInvoice | Deutsche EN-16931-konforme E-Rechnungs-XML-Ausprägung; erfordert BuyerReference (Leitweg-ID) für B2G. | +| Zeit-Signatur | Grafische Kundenunterschrift zu genau einer Zeit (Tabelle `hlpdsk_timer_signature`); Flag `IsSigned` am Timer. | +| Zugangsdaten (Access Data) | Im Passwortmanager verwaltete Benutzername/Passwort-Kombinationen für Kundensysteme (Hotline-Custom-Items mit Custom-Properties). | +| ZUGFeRD | Hybrides E-Rechnungsformat: E-Rechnungs-XML eingebettet in PDF/A; Versionen 1.0 bis 3.0.1 (XInvoice) im System wählbar; im EDI-Rechnungsimport unterstützt. | +| Zulauf | Bereits bestellte, noch nicht gelieferte Menge (Intake) je Artikel/Lager. | +| Zuordnung (`TransactionAssignment`) | Verknüpfung Bankumsatz ↔ Beleg mit zugewiesenem Betrag, Heuristik und Buchungsflags. | +| Zusatzfeld (`ModuleCustomProperty`) | Konfigurierbares kundenindividuelles Feld je Objektart mit Datentyp, Pflicht- (`IsMandatory`) und Versiegelungskennzeichen (`Sealable`); Werte in EAV-Tabelle `ModuleCustomPropertyValues`. | +| Zwischenrechnung | Codierter Zuordnungstyp in `VertragRechKopfZuordnung` für abweichende Kontingentintervalle (`DifferContingentInterval`: none/headMinor/interimMinor/headMajor/interimMajor). | diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/Hypothesen.md b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/Hypothesen.md new file mode 100644 index 00000000..a1fa1bc1 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/Hypothesen.md @@ -0,0 +1,24 @@ +# Hypothesen + +**System:** c-entron ERP-Suite | **Datum:** 2026-08-27 + +Diese Datei enthält genau die Anforderungen mit `[HYPOTHESE]`-Markierung (`Status: HYPOTHESE`) aus StRS.md, SyRS.md und SwRS.md — deckungsgleich mit den Inline-Markierungen. Je Eintrag die offene Frage, deren Beantwortung die Hypothese bestätigen oder verwerfen würde. + +| ID | Ebene | Titel | Offene Frage (fehlende Information) | +|----|-------|-------|-------------------------------------| +| SyRS-110 | SyRS | Serverseitige Durchsetzung aller im WPF-Client geprüften Rechte | Existiert für jedes clientseitig geprüfte Recht (insb. UI-Sichtbarkeitsrechte wie EDIT_GLOBAL_PROFILES) eine korrespondierende serverseitige Prüfung in BL oder Webservice? | +| SyRS-1119 | SyRS | Zentrale Dateiablage mit Versionierung und Sperrmechanismus | Die serverseitige Durchsetzung (Ablehnung eines zweiten Check-outs, Versionszählung) in der Dokumenten-BL (FileManagement) wurde nicht gelesen; belegt ist nur der Client-Vertrag (ICentronFileSystemConnector). | +| SwRS-119 | SwRS | Alt-Passwortverwaltung (PasswordManagementArea) mit Zugriffsprotokoll, aber ohne wirksame Verschlüsselung | Wird PasswordManagementKeyword.Password von einem anderen (Alt-)Client verschlüsselt befüllt, oder liegen die Werte im Klartext vor? Warum wird beim Lesezugriff der ActionType "Create" geloggt? | +| SwRS-248 | SwRS | Serverseitige Durchsetzung der Kontoauszugs-Rechte (20800147–20800151) | Existiert eine hier nicht gefundene serverseitige Prüfung (z. B. in einer Webservice-Fassade/Modulfreischaltung), oder sind die Rechte 20800147–20800151 tatsächlich nur UI-wirksam? | +| SwRS-350 | SwRS | Durchsetzung der Werbesperre beim Mailingversand | Gibt es im Versandpfad (Mail-Dispatcher/UI-Auswahl) eine erzwungene Filterung auf Werbesperre, oder verlässt sich das System allein auf die manuelle Filterwahl der Empfängerselektion? | +| SwRS-354 | SwRS | Manueller Statuswechsel auf „storniert" für Nicht-Rechnungsbelege | Über welchen UI-/BL-Pfad werden Angebote/Aufträge/Lieferscheine storniert, und welche Prüfungen (Rechte, Bestandsrückbuchung, Folgebelege) werden dabei erzwungen? | +| SwRS-451 | SwRS | TradePool-Artikelimport aus XML-Dateien | Wird der TradePool produktiv noch genutzt und was ist der fachliche Zweck (kundenübergreifende Handelsbörse vs. interner Katalog)? Kein aufrufendes UI-Modul im Cluster gefunden. | +| SwRS-545 | SwRS | Automatische Auswertung eingehender Meldungen gegen Expected Events | Welche Komponente (vermutlich ein externer Dienst oder RiverDivo-Integration) wertet eingehende Meldungen gegen die MessageContains*-Muster aus und erzeugt ExpectedEventLogEntries bzw. Tickets? | +| SwRS-637 | SwRS | Berechtigungsprüfung der Kundengeräteverwaltung | Wird der Zugriff auf die Geräteverwaltung an anderer Stelle (WPF-Client-Menürechte, API-Gateway, Lizenz) durchgesetzt, oder ist die Operation tatsächlich ungeschützt? | +| SwRS-740 | SwRS | Getrennte Persistenz von Betreff-Schalter und Betreff-Text der Outlook-Termine | Ist die Nutzung von HolidayRequestedEmailSubject als Bool-Schalter beabsichtigte Wiederverwendung eines freien Schlüssels oder ein Copy-Paste-Fehler, und liest ein anderes Modul denselben Schlüssel mit Urlaubs-Semantik? | +| SwRS-748 | SwRS | Social-Media-Interaktionen über Datenbankprozeduren | Welche Regeln (Berechtigung, Dubletten, Benachrichtigung) implementieren die Stored Procedures AddCommentToASocialMediaAction/LikeAStreamOrAction, und ist socialKind = 0 für Actions ein Fehler? | +| SwRS-848 | SwRS | Fehlender Seitenschutz der Produktionsübersicht | Existiert an anderer Stelle (Middleware, Host-Konfiguration, Reverse Proxy) ein Schutz der Route /production/overview, oder ist die Seite tatsächlich anonym erreichbar? | +| SwRS-947 | SwRS | Berechtigungsschutz für die Pflege von Integrationsstammdaten (D!VE-Profile, ES-Kundengruppen) | Greift für v1/telekom-dive und v1/integrations/es-* eine globale Autorisierung (z. B. Authentifizierungspflicht in Centron.Host/Middleware) oder genügt heute jede gültige Anmeldung für Schreibzugriffe? | +| SwRS-1043 | SwRS | Reportserver: automatisierter Reportversand per E-Mail über Aufgaben | Wo (welcher Dienst/Serverprozess) führt die geplanten Aufgaben aus und mit welcher Render-/Mail-Logik — der ausführende Code wurde im Cluster nicht gefunden. | +| SwRS-1147 | SwRS | Doppelte Entitätsklassen für den Firmenmandanten (Tabelle Mandant) | Ist „Mandant" ausschließlich Belegabsender (eigene Firma) ohne datenraumtrennende Mehrmandantenfähigkeit, und wird die Alt-Tabelle MandantenStammdat noch verwendet? | +| SwRS-1233 | SwRS | Serverseitige Rechteprüfung beim Speichern von Mandantenstammdaten | Prüft die aufrufende REST-Schicht (CentronRestService) oder MandatorBL.SaveMandatory das Recht Administration.MANDATORY serverseitig, oder verlässt sich das System allein auf die Client-UI? | diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/StRS.md b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/StRS.md new file mode 100644 index 00000000..ec622131 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/StRS.md @@ -0,0 +1,1201 @@ +# Stakeholder Requirements Specification (StRS) + +**System:** c-entron ERP-Suite — Reverse Requirements Engineering aus der Codebasis +**Norm:** ISO/IEC/IEEE 29148:2018 | **Datum:** 2026-08-27 + +Fachliche Sicht: Akteure, Geschäftsziele und übergreifende Stakeholder-Anforderungen. Jede Anforderung folgt dem Blockformat des Laufs (Fakt = belegte Beobachtung, Aussage = fachliche Interpretation). Anforderungen mit `Status: HYPOTHESE` sind zusätzlich in `Hypothesen.md` gelistet. Die Kapitel entsprechen den Analyse-Clustern A1–A12 (siehe `Analysebericht.md`). + +## A1 — Sicherheit, Identität, Berechtigungen: Stakeholder-Anforderungen (StRS) + +### StRS-101: Rollenbasierte Zugriffskontrolle für alle Fachfunktionen + +``` +ID: StRS-101 +Titel: Rollenbasierte Zugriffskontrolle für alle Fachfunktionen +Ebene: StRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Administrator, Mitarbeiter (interner ERP-Benutzer) +Vorbedingung: Benutzerkonten und Rechtegruppen sind angelegt. +Fakt: Alle Fachmodule (Kunden, Aufträge, Helpdesk, Passwortmanager, DSGVO usw.) prüfen Berechtigungen gegen ein zentrales Rechtesystem: Rechte (Tabelle Sichrech) werden Gruppen (Sichtrus) zugeordnet, Benutzer werden Gruppen zugewiesen (Sichmemb); die Prüfung erfolgt zentral über AppRightsBL.HasUserRight. +Aussage: Das System soll den Zugriff auf Fachfunktionen ausschließlich über ein zentrales, gruppenbasiertes Berechtigungsmodell steuern, in dem Administratoren Rechte an Gruppen und Gruppen an Benutzer vergeben. +Ergebnis: Ein Benutzer kann nur die Funktionen ausführen, für die eine seiner Gruppen das entsprechende Recht besitzt. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Rights\AppRightsBL.cs, Methode HasUserRight(int appUserI3D, int rightID) mit SQL "SELECT st.Recht ... FROM dbo.Sichtrus st INNER JOIN dbo.Sichmemb sm ON sm.Gruppe = st.Gruppe WHERE sm.Benutzer = :UserI3D" - Begründung: zentrale durchsetzende Prüfstelle des gruppenbasierten Rechtemodells. + - [SEKUNDÄR] docs\guides\development\check-userrights.md ("Rights and groups can be managed in the Rechteverwaltung module") - Begründung: dokumentiert das Modell als verbindliches Entwicklungsmuster. + - [KONTEXT] CentronRights.md (Repo-Wurzel) - Begründung: fachliche Beschreibung der Rechte inkl. restriktiver Rechte ("restricting right"). +Prüfidee: Benutzer ohne Recht X einer Funktion zuordnen und Aufruf der Funktion über UI und API testen; Erwartung: Zugriff verweigert; nach Gruppenzuweisung mit Recht X: Zugriff möglich. +Tracelinks: SyRS-101, SyRS-102, SyRS-110 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - etabliertes, zentrales RBAC-Modell ist tragfähige Basis für eine SaaS-Neuimplementierung. +Status: belegt +``` + +### StRS-102: Gesicherte Anmeldung für interne Benutzer und Kunden + +``` +ID: StRS-102 +Titel: Gesicherte Anmeldung für interne Benutzer und Kunden +Ebene: StRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Mitarbeiter, Kunde (Webportal-Nutzer), Administrator +Vorbedingung: Benutzerkonto (AppUser/Sichbenu) bzw. Web-Account (WebAccounts) existiert. +Fakt: Die Anmeldung erfolgt über eine Authenticator-Fabrik mit den Verfahren Benutzername/Passwort (Basic), Active Directory (LDAP), OpenID Connect (JWT) und Web-Account; optional wird eine Zwei-Faktor-Authentifizierung (RADIUS oder E-Mail-Link) erzwungen; deaktivierte Konten werden abgewiesen. +Aussage: Das System soll Mitarbeiter und Kunden vor jedem Zugriff authentifizieren und dabei konfigurierbare Verfahren (lokales Passwort, Verzeichnisdienst, OpenID Connect) sowie optionale Zwei-Faktor-Authentifizierung unterstützen. +Ergebnis: Nur authentifizierte, aktive Konten erhalten eine Sitzung (Ticket); fehlgeschlagene Anmeldungen werden abgewiesen und protokolliert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\Auth\AuthenticatorFactory.cs, GetMainAuthenticator(...) (Switch über BasicAuthObject/WebAccountAuthObject/OpenIdConnectAuthObject) - Begründung: durchsetzende Stelle für die Auswahl und Zulassung der Anmeldeverfahren. + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\Auth\Authenticator.cs, ValidateAppUser(...) (Abweisung deaktivierter Konten mit Fehlermeldung "MitarbeiterKontoWurdeDeaktiviert") - Begründung: erzwingt, dass nur aktive Konten angemeldet werden. +Prüfidee: Anmeldeversuche mit falschem Passwort, deaktiviertem Konto und ohne 2FA-Bestätigung durchführen; Erwartung: jeweils Abweisung mit spezifischer Fehlermeldung; erfolgreicher Login liefert Ticket. +Tracelinks: SyRS-103, SyRS-104, SyRS-105, SyRS-106, SyRS-107 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Mehrverfahren-Authentifizierung inkl. OIDC ist für SaaS unmittelbar relevant; das SHA1-Passwortverfahren selbst ist abzulösen (siehe SwRS-106). +Status: belegt +``` + +### StRS-103: Schutz und Nachvollziehbarkeit von Kundenzugangsdaten (Passwortmanager) + +``` +ID: StRS-103 +Titel: Schutz und Nachvollziehbarkeit von Kundenzugangsdaten (Passwortmanager) +Ebene: StRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Systemhaus-Mitarbeiter (Techniker), Passwortmanager-Verantwortlicher, Kunde +Vorbedingung: Lizenz "Passwort-Manager" vorhanden; Zugangsdaten zu Kundensystemen sind erfasst. +Fakt: Kundenzugangsdaten (Benutzername/Passwort für Kundensysteme) werden AES-verschlüsselt gespeichert, ihr Zugriff wird über Richtlinien (Guidelines) mit feingranularen Rechten (u. a. Siegelbruch, Sichtbarkeit, Export) gesteuert und jede sicherheitsrelevante Aktion wird protokolliert (PasswordManagerLog); Siegelbruch löst zusätzlich eine E-Mail-Benachrichtigung aus. +Aussage: Das System soll Zugangsdaten zu Kundensystemen verschlüsselt verwalten, den Zugriff über kunden- und mitarbeiterspezifische Richtlinien beschränken und jeden Zugriff bzw. jede Offenlegung revisionssicher protokollieren. +Ergebnis: Zugangsdaten sind nur für berechtigte Mitarbeiter einsehbar; Offenlegungen (Siegelbruch, Export) sind nachvollziehbar dokumentiert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\PasswordManager\PasswordManagerBL.cs, GetCustomerAccessDataForExport(...): "if (_appRightsBL.HasUserRight(loggedInUser.UserI3D.Value, UserRightsConst.PasswordManager.EXPORT_ACCESS_AND_PASSWORD_DATA) == false) throw new ResultException(...)" - Begründung: durchsetzende Rechteprüfung vor Offenlegung von Passwörtern. + - [PRIMÄR] src\backend\Centron.BL\PasswordManager\PasswordManagerBL.cs (Zeile ~700): "propertyValue.ValueEncryptedString = new AESCryptoLogic().EncryptText(customerHotline.Password, masterKeyResult.Data)" - Begründung: belegt die verschlüsselte Speicherung. +Prüfidee: Mitarbeiter ohne Export-Recht ruft den Zugangsdaten-Export auf (Erwartung: Fehler "Recht 'Passwort-Manager Export'"); Siegelbruch durchführen und prüfen, dass Log-Eintrag und Benachrichtigungs-E-Mail entstehen. +Tracelinks: SyRS-108 +Konsolidierung: Kandidat: Alt-Implementierung PasswordManagementArea (SwRS-117) bildet dieselbe fachliche Funktion (Kundenpasswort-Verwaltung) in getrennter Datenhaltung ab. +Übernahmewürdigkeit: übernehmen - Richtlinien-/Siegelmodell mit Protokollierung ist fachlich wertvoll; Schlüsselverwaltung muss in SaaS neu konzipiert werden. +Status: belegt +``` + +### StRS-104: DSGVO-konforme Löschung und Bereinigung personenbezogener Daten + +``` +ID: StRS-104 +Titel: DSGVO-konforme Löschung und Bereinigung personenbezogener Daten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Datenschutzbeauftragter / berechtigter Administrator, betroffene Person (Kontakt) +Vorbedingung: Löschbegehren einer betroffenen Person liegt vor oder Aufbewahrungsfristen sind abgelaufen; Benutzer besitzt das DSGVO-Recht. +Fakt: Das DSGVO-Modul bietet die rechtegeschützte Löschung von Kontaktpersonendaten (feldweises Entfernen personenbezogener Daten mit Erstellung eines Löschprotokolls "c-entron Löschprotokoll") und eine Datenbank-Bereinigungsfunktion; zusätzlich werden Auftragsverarbeitungsverträge (AVV) verwaltet. +Aussage: Das System soll auf Anforderung personenbezogene Daten von Kontaktpersonen unwiederbringlich entfernen, die Durchführung in einem Löschprotokoll dokumentieren und die Funktion auf dedizierte Berechtigungen beschränken. +Ergebnis: Personenbezogene Felder sind geleert bzw. durch den Hinweis "DSGVO: Auf Anfrage gelöscht." ersetzt; ein Löschprotokoll dokumentiert, welche Datenarten entfernt wurden. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\DataSecurity\DataSecurityBL.cs, DsgvoDeleteRightDeleteContacts(...): "if (!currentUser.HasUserRight(UserRightsConst.DsgvoModule.DSGVO_DELETE_CONTACT)) ..." und DoDeleteContactPerson(...) (feldweises Nullen von Name, Vorname, Geburtstag, Telefonnummern, E-Mail mit Protokollzeilen) - Begründung: durchsetzende Rechteprüfung und tatsächliche Löschlogik. + - [SEKUNDÄR] src\backend\Centron.BL\Administration\DataSecurity\DataSecurityBL.cs, Konstante DsgvoDeletedContactMessage = "DSGVO: Auf Anfrage gelöscht." - Begründung: fachlicher Nachweis des Löschvermerks. +Prüfidee: Kontaktperson über das DSGVO-Modul löschen; Erwartung: personenbezogene Felder sind leer, Löschprotokoll listet die entfernten Werte, Benutzer ohne DSGVO_DELETE_CONTACT erhält eine Fehlermeldung. +Tracelinks: SyRS-109 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - gesetzliche Pflicht (DSGVO Art. 17); Lösch-Implementierungen für Kunden/Lieferanten/Accounts sind unvollständig und müssen in der Neuimplementierung vervollständigt werden. +Status: belegt +``` + +## A2 — Finanzen & Abrechnung: Stakeholder-Anforderungen (StRS) + +### StRS-201: Wiederkehrende vertragsbasierte Abrechnung + +``` +ID: StRS-201 +Titel: Wiederkehrende vertragsbasierte Abrechnung +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Faktura-Sachbearbeiter, Vertragsverwalter (Systemhaus/MSP) +Vorbedingung: Aktive Service-, Leasing-, Kontingent- oder Click-Verträge mit Kunden existieren. +Fakt: Die Codebasis enthält einen vollständigen automatisierten Abrechnungskern (AutomaticFacturaBL) mit Intervallarten Daily/Monthly/Quarterly/Yearly (BillingIntervalKinds), Vor-/Nachberechnung (BillingKinds.Billingadvance/Billingarrear), Kontingent- und Zählerabrechnung sowie Vertragskopf-Datenmodell (VertragKopf mit AbrechnungIntervallArt/-Dauer, AutoAbrechnung, AbrechnungBeginn). +Aussage: Das System soll wiederkehrende Leistungen (Wartung, Service, Leasing, Stundenkontingente, Geräte-Clicks, Ticketzeiten) auf Basis von Kundenverträgen periodengerecht und weitgehend automatisiert in Rechnungen überführen. +Ergebnis: Für jeden fälligen Vertrag entsteht im Abrechnungslauf eine korrekte, dem Abrechnungszeitraum zugeordnete Rechnung; keine Leistung wird doppelt oder gar nicht berechnet. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\CustomerAssets\AutomaticFactura\AutomaticFacturaBL.Contracts.cs, Methoden ContractForBilling/SetNextBillingDate/NextDate (Z. 1474–1627) - Begründung: durchgesetzte Fälligkeits- und Zeitraumlogik der automatischen Abrechnung. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, Tabelle VertragKopf (AbrechnungIntervallDauer, AbrechnungIntervallArt, AutoAbrechnung, AbrechnungBeginn, LetzteRechnungDatum) - Begründung: Datenmodell trägt die wiederkehrende Abrechnung als Kernkonzept. +Prüfidee: Vertrag mit monatlichem Intervall und Beginn 15.01. anlegen; Abrechnungslauf ausführen und prüfen, dass genau ein Abrechnungszeitraum 15.01.–14.02. fakturiert wird. +Tracelinks: SyRS-206, SyRS-207, SyRS-208, SyRS-209, SyRS-210 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kerngeschäftsprozess eines Systemhaus-ERP; für SaaS-Neuimplementierung zentral. +Status: belegt +``` + +### StRS-202: Forderungsmanagement und Zahlungsabgleich + +``` +ID: StRS-202 +Titel: Forderungsmanagement und Zahlungsabgleich +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung/Controlling +Vorbedingung: Rechnungen mit Fälligkeit und offenen Beträgen existieren. +Fakt: Die Codebasis enthält Mahnwesen mit drei Mahnstufen (DunningBL/DunningRunBL), OPOS-Übersicht (OposBL/OposRunBL, Sicht auf offene Rechnungen und Gutschriften), Zahlungseingänge (PaymentsBL, IncomingPayment) und Bankauszugsabgleich (OnlineBankingAccountTransactionsBL) inkl. automatischer Zuordnung von Umsätzen zu Rechnungen. +Aussage: Das System soll offene Forderungen überwachen, Zahlungseingänge (manuell und über Bankauszüge) den Rechnungen zuordnen und säumige Kunden gestuft mahnen, um Liquidität und Forderungsbestand zu sichern. +Ergebnis: Offene Posten, Mahnstatus und Zahlstatus jeder Rechnung sind jederzeit konsistent nachvollziehbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\Dunning\DunningRunBL.cs, ExecuteDunningRunInternal/UpdateInvoice (Z. 200–275) - Begründung: durchgesetzte Mahnstufen-Progression beim Mahnlauf. + - [PRIMÄR] src\backend\Centron.BL\Finances\OnlineBanking\OnlineBankingAccountTransactionsBL.cs, BookAmountToAssignedInvoice (Z. 1042–1086) - Begründung: durchgesetzte Aktualisierung des Zahlstatus (PaidFC, IsPaid) aus Bankumsätzen. +Prüfidee: Überfällige Rechnung erzeugen, Mahnlauf ausführen (Stufe 1), Bankumsatz mit Rechnungsnummer importieren und prüfen, dass die Rechnung als bezahlt ausgeglichen und aus der Mahnliste entfernt wird. +Tracelinks: SyRS-211, SyRS-212, SyRS-213, SyRS-214 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - gesetzlich/kaufmännisch notwendiger Prozess. +Status: belegt +``` + +### StRS-203: Ordnungsgemäße Übergabe an die Finanzbuchhaltung + +``` +ID: StRS-203 +Titel: Ordnungsgemäße Übergabe an die Finanzbuchhaltung +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung, Steuerberater, externes FiBu-System (z. B. DATEV) +Vorbedingung: Abgeschlossene Belege (Rechnungen, Gutschriften, Kassenbuch) liegen vor. +Fakt: BookKeepingExportBL unterstützt 13 Zielsysteme (u. a. DATEV ASCII, DATEV XML Online, Lexware, Sage, Navision, SAP, Abacus, Addison), exportiert Stammdaten und Buchungsdaten und markiert exportierte Belege in den Tabellen PORTRECH/PORTWARE. +Aussage: Das System soll Debitoren-/Kreditorenstammdaten und Belegbuchungsdaten in den Formaten gängiger Finanzbuchhaltungssysteme exportieren und Doppelübergaben verhindern. +Ergebnis: Die FiBu erhält vollständige, nur einmal übergebene Buchungsdaten mit korrekten Steuerkennzeichen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\DataExchange\BookKeeping\BookKeepingExportBL.cs, InvokeExportClass (Z. 1574–1607) und IsReceiptExported (Z. 209–226, Lookup PORTRECH/PORTWARE) - Begründung: durchgesetzte Formatauswahl und Export-Doppelschutz. +Prüfidee: Rechnung exportieren, zweiten Export desselben Zeitraums starten und prüfen, dass die Rechnung als „bereits übertragen" ausgefiltert ist. +Tracelinks: SyRS-216 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - FiBu-Anbindung ist Pflicht; Anzahl der Zielformate für Neuimplementierung nach Marktrelevanz priorisieren. +Status: belegt +``` + +### StRS-204: Digitale SEPA-Mandatsverwaltung + +``` +ID: StRS-204 +Titel: Digitale SEPA-Mandatsverwaltung +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung, Kunde (Unterzeichner), Vertriebsmitarbeiter +Vorbedingung: Kunde soll per SEPA-Lastschrift zahlen; Mandat liegt noch nicht vor. +Fakt: SepaContractOnlinePdfDocumentHandler implementiert einen Online-Unterschriftsprozess (Word-Vorlage → PDF/A-3b mit Signaturbild, Link mit GUID, Statuswechsel Accepted/Declined/LinkExpired, Bestätigungs-/Ablehnungsmails, automatische Anlage/Aktualisierung der Bankverbindung inkl. Mandatsreferenz). +Aussage: Das System soll SEPA-Lastschriftmandate digital erzeugen, dem Kunden zur Online-Unterschrift bereitstellen, den Mandatsstatus verwalten und bei Annahme die Bankverbindung mit Mandatsreferenz und Gläubiger-ID hinterlegen. +Ergebnis: Ein rechtsgültig unterschriebenes Mandats-PDF ist am Kunden archiviert; die Bankverbindung ist für den Zahlungsverkehr nutzbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Documents\Dsgvo\SepaContractOnlinePdfDocumentHandler.cs, Confirm (Z. 78–178: State=SepaContractState.Accepted, BankAccount-Anlage, AuthorizationNumber-Default) - Begründung: durchgesetzter Mandats-Workflow. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, Tabelle SepaContracts (State tinyint NOT NULL, BankAccountI3D, TestMode, DeclineReason) - Begründung: Datenmodell des Mandatsprozesses. +Prüfidee: Mandat versenden, online unterschreiben und prüfen: Status=Accepted, PDF im Kundenverzeichnis, Bankverbindung mit AuthorizationDate=heute und gefüllter Mandatsreferenz. +Tracelinks: SyRS-217 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - moderner, papierloser Prozess; direkt SaaS-tauglich. +Status: belegt +``` + +### StRS-205: Zugriffsschutz auf Finanzfunktionen + +``` +ID: StRS-205 +Titel: Zugriffsschutz auf Finanzfunktionen +Ebene: StRS +Typ: Sicherheit +Qualitätsmerkmal: Sicherheit +Akteur: Administrator, alle Benutzer der Finanzmodule +Vorbedingung: Benutzern sind Rechte (UserRights) und dem Mandanten Lizenzen zugewiesen. +Fakt: Finanzfunktionen sind an dedizierte Rechte gebunden (UserRightsConst.Controlling.Finances: Dunning=10971, INCOMING_PAYMENT_TRANSACTIONS=10980, OUTGOING_PAYMENT_TRANSACTIONS=10981, OnlineBanking.VIEW_BANKSTATEMENT=20800147 u. a.) und teils an Lizenzen (LicenseGuids.Dunning, OnlineBanking_FinApi, DatevOnline). +Aussage: Das System soll Einsicht in und Bearbeitung von Finanzdaten (Mahnwesen, Zahlungen, Kontoauszüge, FiBu-Export) nur Benutzern mit den jeweiligen Rechten und nur bei vorhandener Lizenz erlauben. +Ergebnis: Unberechtigte Zugriffe auf Finanzdaten werden mit Fehlermeldung abgewiesen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\Dunning\DunningBL.cs, ThrowIfUserHasInsufficentRights (Z. 1059–1067: `if (result.Contains(UserRightsConst.Controlling.Finances.Dunning) == false) throw ...`) - Begründung: serverseitig durchgesetzte Rechteprüfung. + - [PRIMÄR] src\backend\Centron.BL\Finances\Payments\PaymentsBL.cs, DeleteIncomingPayment (Z. 43–44: `HasUserRight(...INCOMING_PAYMENT_TRANSACTIONS) == false → Result.AsError(..., RightCheckFailed)`) - Begründung: Rechteprüfung vor destruktiver Zahlungsoperation. + - [KONTEXT] CentronRights.md (Repo-Wurzel) - Begründung: dokumentiert das Rechtekonzept. +Prüfidee: Benutzer ohne Recht 10971 ruft die Mahnliste über den Webservice ab; erwartet: Exception/Fehler, keine Daten. +Tracelinks: SyRS-218 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Rechtemodell fachlich übernehmen; technisch in der Neuimplementierung durchgängig serverseitig erzwingen. +Status: belegt +``` + +## A3 — Vertrieb & Belegwesen: StRS (Stakeholder-Anforderungen) + +### StRS-301: Durchgängige Verkaufs-Belegkette ohne Neuerfassung + +``` +ID: StRS-301 +Titel: Durchgängige Verkaufs-Belegkette ohne Neuerfassung +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertriebsmitarbeiter, Innendienst +Vorbedingung: Kundenstammdaten und Artikelstamm vorhanden; Benutzer besitzt Belegrechte. +Fakt: Die Codebasis implementiert eine Weiterverarbeitung (Forwarding) von Belegen entlang Angebot → Auftrag → Lieferschein/Rechnung → Gutschrift mit belegartspezifischen Zielmatrizen (CanBeForwardedInto) und Übernahme von Positionen, Empfänger-, Währungs- und Filialdaten in den Folgebeleg. +Aussage: Das System soll den Vertriebsprozess als durchgängige Belegkette abbilden, in der aus einem bestehenden Beleg der jeweils fachlich zulässige Folgebeleg erzeugt wird, ohne dass Positionen und Kopfdaten erneut erfasst werden müssen. +Ergebnis: Folgebelege entstehen aus Vorgängerbelegen; die Herkunft (Belegkette) bleibt nachvollziehbar (GetReceiptForwardedFrom/-Into). +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, Methode ForwardReceipt() (Zeile 1548 ff.) - Begründung: implementiert die Erzeugung des Folgebelegs inkl. Validierung und Datenübernahme und erzwingt die Zulässigkeitsmatrix. + - [SEKUNDÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, Methoden GetReceiptForwardedFrom()/GetReceiptForwardedInto() (Zeilen 729/748) - Begründung: Herkunfts-/Verwendungsnachweis der Belegkette. +Prüfidee: Angebot mit 3 Positionen anlegen, in Auftrag, dann Lieferschein, dann Rechnung weiterverarbeiten; prüfen, dass Positionen/Empfänger übernommen werden und die Kette in beiden Richtungen abfragbar ist. +Tracelinks: SyRS-310, SyRS-311, SyRS-312 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kernprozess jedes ERP-Vertriebs; für SaaS-Neuimplementierung unverzichtbar. +Status: belegt +``` + +### StRS-302: Korrekte und revisionssichere Fakturierung + +``` +ID: StRS-302 +Titel: Korrekte und revisionssichere Fakturierung +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung, Vertriebsleitung, Betriebsprüfer (extern) +Vorbedingung: Rechnungen werden aus der Belegkette oder direkt erzeugt. +Fakt: Die Codebasis erzwingt: MwSt-Berechnung je Steuersatzgruppe mit definierter Rundung, eindeutige Belegnummern aus Nummernkreisen, Rechnungsfestschreibung (IsFixed), Storno nur als neue Belegversion mit dediziertem Benutzerrecht und Protokolleintrag sowie Sperren gegen Storno exportierter/weiterverarbeiteter Rechnungen. +Aussage: Das System soll Rechnungen rechnerisch korrekt (MwSt, Rundung), eindeutig nummeriert und revisionssicher führen: Änderungen nur als neue Version, Storno nur berechtigt und protokolliert, festgeschriebene Rechnungen unveränderlich. +Ergebnis: Nachvollziehbare, unveränderliche Rechnungshistorie als Grundlage für FiBu-Export und Prüfungen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\ReceiptInvoiceBL.cs, Methode CancelInvoice() (Zeile 143 ff.): `if (currentUser.HasUserRight(UserRightsConst.RIGHT_RECHNUNGSTORNIEREN) == false) return ...AsError(...)` sowie Sperrprüfungen auf bereits storniert/exportiert/weiterverarbeitet - Begründung: durchsetzende Stelle der Storno-Regeln. + - [PRIMÄR] src\webservice\Centron.WebServices.Core\Helper\ReceiptPriceHelper.cs, Methode CalculateReceiptVatPrices() (Zeile 61 ff., Rundung `Math.Round(..., 2, MidpointRounding.AwayFromZero)` je Steuersatzgruppe) - Begründung: durchgesetzte MwSt-Berechnungsregel. + - [SEKUNDÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptLogBL.cs (Zeile 124: Logtext „Die Rechnung ... wurde ... storniert.") - Begründung: Protokollierung des Stornos. +Prüfidee: Rechnung festschreiben und anschließend Storno/Änderung versuchen (muss abgelehnt werden); Storno ohne Recht RIGHT_RECHNUNGSTORNIEREN versuchen (Fehlermeldung); MwSt-Summen einer Rechnung mit gemischten Steuersätzen gegen Handrechnung prüfen. +Tracelinks: SyRS-312, SyRS-313, SyRS-314, SyRS-315, SyRS-316, SyRS-321 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - gesetzliche/kaufmännische Kernanforderung (GoBD-nahe Mechanik). +Status: belegt +``` + +### StRS-303: Kundenindividuelle Preisfindung + +``` +ID: StRS-303 +Titel: Kundenindividuelle Preisfindung +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertriebsmitarbeiter, Vertriebsleitung, Kunde (mittelbar) +Vorbedingung: Artikel mit Verkaufspreisen (VK1–VK4), EK und optional Mindestpreis; Kunde mit Preisliste, Sonderpreisen, Sondervereinbarungen oder Verträgen. +Fakt: ReceiptItemPriceBL.GetBasePrice() ermittelt den Positionspreis nach einer festen Hierarchie: Vertragssonderpreise vor Kundensonderpreisen (Artikel vor Warengruppe/Unterwarengruppe) vor Staffelpreisen; Basis ist der Preislisten-VK des Kunden; Mindestpreise werden beim Speichern erzwungen. +Aussage: Das System soll Verkaufspreise automatisch und deterministisch aus Kundenpreisliste, Sonderpreisen, Sondervereinbarungen, Vertragskonditionen und Staffelpreisen ermitteln und Mindestverkaufspreise schützen. +Ergebnis: Reproduzierbarer, kundenspezifischer Preis je Belegposition; Verkauf unter Mindestpreis nur nach autorisierter Freigabe. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Internal\ReceiptItemPriceBL.cs, Methode GetBasePrice() (Zeile 154 ff., switch über ContractSpecialPriceKind/SpecialPriceKind) - Begründung: implementierte Preisfindungshierarchie. + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, Methode CheckArticleMinPrices() (Zeile 9036 ff., Recht ALLOW_IGNORE_MINIMUM_PRICE) - Begründung: durchgesetzte Mindestpreisregel. +Prüfidee: Kunde mit Preisliste 2, Artikelsonderpreis und Vertragssonderpreis anlegen; erwarteter Preis = Vertragssonderpreis; Sonderpreis-Gültigkeit ablaufen lassen → Rückfall auf Preisliste. +Tracelinks: SyRS-317 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zentrale vertriebliche Differenzierung, im IT-Handel (Projektpreise) unverzichtbar. +Status: belegt +``` + +### StRS-304: Elektronischer Rechnungsaustausch (XRechnung/ZUGFeRD/ebInterface) + +``` +ID: StRS-304 +Titel: Elektronischer Rechnungsaustausch (XRechnung/ZUGFeRD/ebInterface) +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Buchhaltung, öffentliche Auftraggeber (Leitweg-ID), Lieferanten, Behörden (AT) +Vorbedingung: Rechnung oder Gutschrift existiert; Kundenstamm enthält ggf. Leitweg-ID. +Fakt: Die Codebasis erzeugt strukturierte E-Rechnungen in mehreren Formaten (ZUGFeRD 1.0, XRechnung/XInvoice-Versionen bis 3.0.1, ebInterface 4.3) und bettet das XML in PDF/A ein; eingehende ZUGFeRD-Dateien werden über einen REST-Endpunkt geparst. +Aussage: Das System soll Ausgangsrechnungen in den gesetzlich bzw. je Kunde geforderten E-Rechnungsformaten ausgeben (inkl. XRechnung mit Leitweg-ID für öffentliche Auftraggeber und ebInterface für Österreich) und eingehende ZUGFeRD-Rechnungen strukturiert einlesen können. +Ergebnis: Format-konforme E-Rechnungsdateien pro Rechnung; importierbare Lieferantenrechnungsdaten. +Belege: + - [PRIMÄR] src\backend\Centron.BL\DataExchange\EDI\SaleInvoices\InvoiceZugferdBL.cs, Methoden GetZugferFormat()/GenerateZugferdFile() (Zeilen 85/124) - Begründung: durchgesetzte Formatwahl- und Erzeugungslogik. + - [PRIMÄR] src\apis\Centron.Api.EbInterface\EbInterfaceLogic.cs, Methode GenerateFile() (Zeile 22, Namespace http://www.ebinterface.at/schema/4p3/) - Begründung: ebInterface-4.3-Erzeugung. + - [KONTEXT] docs\guides\development\xrechnung.md - Begründung: Entwicklerdoku zu ZUGFeRD/XRechnung-Spezifikationen. +Prüfidee: Rechnung eines Kunden mit Leitweg-ID exportieren; erzeugtes XML gegen KOSIT-Validator prüfen (BuyerReference = Leitweg-ID, DocumentType XInvoice); ZUGFeRD-PDF importieren und Positionsdaten vergleichen. +Tracelinks: SyRS-318 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - E-Rechnungspflicht (B2G, ab 2025 B2B in DE) macht die Funktion zwingend; Eigenimplementierung ggf. durch Bibliothek ersetzen (siehe docs-Hinweis). +Status: belegt +``` + +### StRS-305: Vertriebsunterstützung durch Kampagnen-Mailings und Kundenprodukt-Matrix + +``` +ID: StRS-305 +Titel: Vertriebsunterstützung durch Kampagnen-Mailings und Kundenprodukt-Matrix +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Marketing, Vertriebsleitung, Vertriebsmitarbeiter +Vorbedingung: Kundenstamm mit Ansprechpartnern; definierte Produktkategorien. +Fakt: Die Codebasis enthält ein Mailing-Modul (MailingData mit Empfängertexten, Anhängen, Kampagnenbezug, Versandstatus je Empfänger) und eine Produktmatrix, die je Kunde und Produkt eine Potenzialbewertung mit Änderungshistorie (Mitarbeiter, Zeitstempel, Begründung) speichert. +Aussage: Das System soll den Vertrieb mit Kampagnen-Mailings (Empfängerauswahl, personalisierte Texte, Anhänge, Versandnachweis) und einer Kunden-Produkt-Potenzialmatrix (Bewertung je Kunde/Produkt mit nachvollziehbarer Änderungshistorie) unterstützen. +Ergebnis: Auswertbare Kampagnen und Cross-/Upselling-Potenziale je Kunde. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Mailings\MailingDataBL.cs, Methoden LoadFullMailing()/SaveMailingData() (Zeilen 22/74) - Begründung: implementiertes Mailing-Datenmodell inkl. Versandstatus. + - [PRIMÄR] src\backend\Centron.BL\ProductMatrix\ProductMatrixBL.cs, Methode GetProductMatrixCustomerProductRating() (Zeile 165, legt Default-Bewertung „Nothing" an) - Begründung: implementierte Bewertungslogik der Produktmatrix. +Prüfidee: Mailing mit 2 Empfängern und Anhang anlegen, versenden, Versandstatus (Send) je Empfänger prüfen; Produktbewertung eines Kunden ändern und ChangeLog-Eintrag (Mitarbeiter/Zeit/Begründung) verifizieren. +Tracelinks: SyRS-319, SyRS-320 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kampagnen-/Potenzialfunktionen sind fachlich gewollt; technische Umsetzung (Mail-Versand) sollte in SaaS neu konzipiert werden. +Status: belegt +``` + +## Cluster A4 — StRS (Artikel, Lager, Einkauf, Logistik, RMA) + +### StRS-401: Zentrale Artikelstamm- und Bestandsführung über mehrere Läger + +``` +ID: StRS-401 +Titel: Zentrale Artikelstamm- und Bestandsführung über mehrere Läger +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Lagerleitung, Einkauf, Vertrieb +Vorbedingung: Mandant mit mindestens einem Hauptlager; optional Nebenläger +Fakt: Die Codebasis führt Artikel in der Tabelle ARTIK mit Bestandsfeldern (Menge, Mindestbestand, Zulauf) und je Nebenlager in NebenlagerArtikel (Bestand, Zulauf, Mindestbestand, eigener EK); Bestände werden wahlweise über Mengenfelder oder durch Zählung von Seriennummern (View cvw_ArticleCount/cvw_BarcodeCount) ermittelt. +Aussage: Das System soll einen zentralen Artikelstamm mit Bestandsführung je Lager (Hauptlager und beliebige Nebenläger) bereitstellen, einschließlich seriennummerngenauer Bestandsführung für seriennummernpflichtige Artikel. +Ergebnis: Für jeden Artikel ist je Lager ein aktueller, nachvollziehbarer Bestand abrufbar. +Belege: + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[ARTIK] (Spalten Menge, Mindestbestand, Zulauf) und CREATE TABLE [dbo].[NebenlagerArtikel] (Bestand, Zulauf, Mindestbestand) - Begründung: Datenmodell erzwingt Bestandsführung je Artikel und je Nebenlager. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE VIEW [dbo].[cvw_ArticleCount] - Begründung: zentrale, im gesamten System verwendete Bestandsermittlung über Haupt- und Nebenläger. + - [SEKUNDÄR] src\backend\Centron.BL\Warehousing\StockManagement\ArticleStockBL.cs, GetArticleStockInfos/UpdateArticleStock - Begründung: BL-Schicht kapselt die Bestandsabfrage und -fortschreibung. +Prüfidee: Artikel in zwei Lägern anlegen, Zu-/Abbuchungen ausführen und prüfen, dass die Bestände je Lager getrennt und korrekt fortgeschrieben werden. +Tracelinks: SyRS-410, SyRS-411, SyRS-412, SyRS-413 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kernfunktion jedes Warenwirtschaftssystems. +Status: belegt +``` + +### StRS-402: Bedarfsgerechte Beschaffung mit elektronischer Lieferantenanbindung + +``` +ID: StRS-402 +Titel: Bedarfsgerechte Beschaffung mit elektronischer Lieferantenanbindung +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Einkäufer, Lieferant/Distributor (externes System) +Vorbedingung: Artikel mit Mindestbeständen bzw. offene Auftragspositionen; konfigurierte Lieferanten-EDI-Zugänge +Fakt: Die Codebasis berechnet Bestellvorschläge aus Mindestbestand, Auftragsbedarf, Bestand und Zulauf (OrderSuggestionListBL) und versendet Bestellungen in mehreren Distributorenformaten (OpenTRANS 2.1, ALSO, KOMSA, Alltron u. a.) elektronisch; Lieferanten-Belege (Bestellbestätigung, Lieferschein, Rechnung inkl. ZUGFeRD) werden importiert; Produktdaten kommen aus externen Katalogen (Icecat, ITscope, EGIS, TradePool). +Aussage: Das System soll den Einkauf durch automatisch berechnete Bestellvorschläge, elektronischen Bestellversand an Distributoren und automatisierten Import von Lieferantenbelegen und Produktdaten unterstützen. +Ergebnis: Beschaffungsbedarfe werden vollständig erkannt und weitgehend medienbruchfrei bei Lieferanten bestellt und rückgemeldet. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Purchasing\OrderSuggestionList\OrderSuggestionListBL.cs, Konstruktor (_sqlArticle, Z. 87-242) - Begründung: implementierte Bedarfsformel (Mindestbestand + Auftragsmengen − Bestand − Zulauf) trägt die Bestellvorschlagsfunktion. + - [PRIMÄR] src\backend\Centron.BL\EDI\EDIDispatcherBL.cs, CreateEDISuggestionOrderAsync (Z. 56-109) - Begründung: erzeugt formatabhängige Bestelldokumente je Distributor. + - [SEKUNDÄR] src\backend\Centron.BL\EDI\Zugferd\ZugferdParseBL.cs, ParseZugferdFile - Begründung: Import elektronischer Lieferantenrechnungen. +Prüfidee: Artikel unter Mindestbestand bringen, Bestellvorschlag prüfen, Bestellung per EDI erzeugen und Formatauswahl je Lieferantenkonfiguration verifizieren. +Tracelinks: SyRS-414, SyRS-415, SyRS-418 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zentrale Beschaffungsprozesse; einzelne Distributorformate auf Aktualität prüfen. +Status: belegt +``` + +### StRS-403: Kommissionierung und Versandabwicklung mit Trackingnachweis + +``` +ID: StRS-403 +Titel: Kommissionierung und Versandabwicklung mit Trackingnachweis +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Lagermitarbeiter (Kommissionierer), Versanddienstleister (GLS, Shipcloud) +Vorbedingung: Freigegebene Aufträge mit lagergeführten Positionen +Fakt: Die Codebasis stellt eine berechtigungsgeschützte Kommissionierung mit Rückmeldung gepickter Mengen (OrderCommissionBL) sowie Versandschnittstellen zu GLS und Shipcloud bereit, die Sendungen anmelden, Labels liefern und Trackingnummern in den Lieferschein zurückschreiben. +Aussage: Das System soll Aufträge kommissionierbar machen (inkl. Seriennummernzuordnung) und Sendungen elektronisch bei Versanddienstleistern anmelden, wobei Trackingnummer und Versandlabel dem Lieferschein zugeordnet werden. +Ergebnis: Jede versendete Lieferung besitzt gepickte Mengen, Label und Trackingnachweis. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Warehousing\Commissions\OrderCommissionBL.cs, ExecuteCommissionForOrders (Z. 169-200) - Begründung: schreibt gepickte Mengen (QuantityPicked) auf Auftragspositionen zurück. + - [PRIMÄR] src\apis\Centron.Api.Gls\CentronGlsLogic.cs, UploadShipment (Z. 15-58) - Begründung: Sendungsanmeldung mit Rückgabe von TrackingId, TrackingUrl und Labels. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\Finances\Receipts\DeliveryServices\GLS\GlsViewModel.cs, CreateNewReceiptVersionAsync (setzt deliveryList.TrackingNumber) - Begründung: Trackingnummer wird am Lieferschein persistiert. +Prüfidee: Auftrag kommissionieren, GLS-Testversand auslösen und prüfen, dass Trackingnummer am Lieferschein steht und das Label erzeugt wird. +Tracelinks: SyRS-416, SyRS-419 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Versand-/Kommissionierprozess ist Kerngeschäft; Carrier-Anbindungen modernisieren. +Status: belegt +``` + +### StRS-404: RMA-Abwicklung für Kunden- und Lieferantenretouren + +``` +ID: StRS-404 +Titel: RMA-Abwicklung für Kunden- und Lieferantenretouren +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Service-/RMA-Sachbearbeiter, Kunde, Lieferant +Vorbedingung: Reklamierter Artikel mit Bezug zu Helpdesk-Vorgang bzw. Beleg +Fakt: Die Codebasis bildet RMA-Vorgänge mit Artikelhistorie und Statusübergängen ab (RmaBL.SaveRma), inkl. Rücksendung an Lieferanten (RmaSendBack), Vorabaustausch/Rücklieferung an Kunden (RmaSendForth), Verschrottung, Fremdwaren-Einbuchung in ein RMA-Kundenlager und Lager-/Seriennummern-Umbuchungen. +Aussage: Das System soll Retouren (RMA) über den gesamten Lebenszyklus verwalten: Annahme, Statusverfolgung je Artikel, Rücksendung an Lieferanten, Ersatzlieferung an Kunden, Verschrottung und die zugehörigen Lagerbuchungen. +Ergebnis: Jeder RMA-Artikel hat eine lückenlose Statushistorie; Bestände und Seriennummern sind konsistent zum RMA-Stand. +Belege: + - [PRIMÄR] src\backend\Centron.BL\CustomerArea\RmaBL.cs, SaveRma (Z. 347-521) - Begründung: implementiert Statusübergänge, Storno, Lieferscheinabschluss und Lagerumbuchung in einer Transaktion. + - [PRIMÄR] src\backend\Centron.BL\CustomerArea\RmaBL.cs, GetNewRmaSendBack (Z. 750 ff.) - Begründung: Anlage von Lieferantenrücksendungen mit Rückgabefrist (+7 Tage). + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, Tabellen RmaArticle, RmaArticleHistory, RmaSendBack, RmaSendForth - Begründung: Datenmodell des RMA-Lebenszyklus. +Prüfidee: RMA mit einem seriennummernpflichtigen Artikel anlegen, Rücksendung an Lieferanten und Ersatzlieferung durchspielen; Historie und Lagerbestand je Schritt prüfen. +Tracelinks: SyRS-417 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - vollwertiger Retourenprozess; Detailregeln (z. B. feste 7-Tage-Frist) konfigurierbar machen. +Status: belegt +``` + +## Cluster A5 — Helpdesk & Service — StRS + +### StRS-501: Zentrale Ticketbearbeitung mit Statusmodell, Fälligkeiten und Eskalation + +``` +ID: StRS-501 +Titel: Zentrale Ticketbearbeitung mit Statusmodell, Fälligkeiten und Eskalation +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Service-Mitarbeiter, Service-Leitung, Kunde (mittelbar) +Vorbedingung: Kundenstammdaten vorhanden; Helpdesk-Modul lizenziert +Fakt: Die Codebasis enthält ein vollständiges Ticketsystem (Tabelle hlpdsk_requests mit Status, FaelligAm, AbgeschlossenAm, EscalationLevel; HelpdeskBL, HelpdeskCloseBL, EscalationBL), in dem Tickets einen konfigurierbaren Status, eine aus der Priorität berechnete Fälligkeit und eine mehrstufige Eskalation besitzen. +Aussage: Das System soll Service-Anfragen (Tickets) mit Kundenbezug zentral erfassen, über einen konfigurierbaren Statuslebenszyklus bis zum Abschluss führen und Terminüberschreitungen über Fälligkeiten und Eskalationsstufen sichtbar machen. +Ergebnis: Jede Kundenanfrage ist als Ticket mit Status, verantwortlicher Person, Fälligkeit und Eskalationsstand nachvollziehbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs, Klasse HelpdeskBL, Save()/DoBeforeSave()/GetDueDateFromPriority() - Begründung: Durchgesetzte Speicher-, Pflichtfeld- und Fälligkeitslogik für Tickets. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[hlpdsk_requests] (Spalten Status, FaelligAm, AbgeschlossenAm, EscalationLevel, VerantwortlicherI3D) - Begründung: Persistentes Datenmodell trägt Status-, Fälligkeits- und Eskalationsinformationen. + - [KONTEXT] CentronRights.md, Abschnitt Helpdesk-Rechte - Begründung: Dokumentiert die fachlichen Rollen und Aktionen rund um Tickets. +Prüfidee: Ticket anlegen, Priorität mit Fälligkeitsregel wählen, Status bis "Abgeschlossen" durchlaufen; prüfen, dass Fälligkeit berechnet, Statuswechsel historisiert und Eskalationsstand geführt wird. +Tracelinks: SyRS-511, SyRS-512, SyRS-513, SyRS-514, SyRS-520 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kernprozess des Service-Geschäfts, tragfähig für eine Web-Neuimplementierung. +Status: belegt +``` + +### StRS-502: Abrechnungsfähige und rechtssichere Zeiterfassung auf Tickets + +``` +ID: StRS-502 +Titel: Abrechnungsfähige und rechtssichere Zeiterfassung auf Tickets +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Service-Techniker, Abrechnung/Faktura, Kunde (Unterschriftsleistender) +Vorbedingung: Ticket existiert; Mitarbeiter ist angemeldet +Fakt: Zeiten (hlpdsk_timer) werden pro Ticket und Mitarbeiter erfasst, sind als "Berechenbar" markierbar, können in Belege (Auftrag/Lieferschein/Rechnung) übernommen werden und tragen eine Kundenunterschrift (hlpdsk_timer_signature, IsSigned); Bearbeitung/Löschung/Verschiebung ist über dedizierte Benutzerrechte geschützt. +Aussage: Das System soll Arbeitszeiten auf Tickets so erfassen, dass sie gegenüber dem Kunden per Unterschrift bestätigt, gegen nachträgliche Manipulation durch Berechtigungen geschützt und in die Fakturierung überführbar sind. +Ergebnis: Erfasste Zeiten sind abrechenbar, signierbar und nach Belegzuordnung unveränderlich. +Belege: + - [PRIMÄR] src\backend\Centron.BL\WebServices\Sales\Support\HelpdeskTimerWebServiceBL.cs, ThrowIfUserDoesntHaveRightToChangeHelpdeskTimers(): "if (hasEditTimeRight == false) throw new ResultException(...RightCheckFailed)" - Begründung: Durchsetzende Rechteprüfung für das Bearbeiten von Zeiten. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[hlpdsk_timer] (Spalten Berechenbar, RechPosI3D, LiefPosI3D, AufPosI3D, IsSigned) und [dbo].[hlpdsk_timer_signature] (TimeSignature NOT NULL) - Begründung: Datenmodell verknüpft Zeit, Abrechnung und Unterschrift. + - [KONTEXT] CentronRights.md, Abschnitte 7-9 (EDIT_TIME, OWN_TIME_EDIT, DELETE_HELPDESK_SIGNATURE, MOVE_HELPDESK_TIMER, DELETE_HELPDESK_TIMER) - Begründung: Fachliche Beschreibung der Schutzrechte. +Prüfidee: Zeit erfassen, signieren, einem Beleg zuordnen; danach versuchen zu ändern/löschen/verschieben — alle Aktionen müssen abgewiesen werden. +Tracelinks: SyRS-515, SyRS-516 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - abrechnungs- und beweisrelevanter Kernprozess. +Status: belegt +``` + +### StRS-503: Automatisierung wiederkehrender Service-Aufgaben + +``` +ID: StRS-503 +Titel: Automatisierung wiederkehrender Service-Aufgaben +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Service-Leitung (Konfiguration), System (Ausführung) +Vorbedingung: Lizenz für automatische Tickets; konfigurierte Aufgaben +Fakt: Der TaskManager (TaskManagementTaskBL, TaskManagementHelpdeskActionHandler) erzeugt Tickets nach Wiederholungsregeln (RecurrenceCalculator); Expected Events definieren erwartete Systemereignisse je Wochentag mit Erfolgs-/Warn-/Fehlermustern und protokollieren Log-Einträge mit Ticketbezug (HelpdeskI3D); Erstellvorlagen (HelpdeskCreationTemplateBL) standardisieren Ticketanlage aus Belegen. +Aussage: Das System soll wiederkehrende Service-Aufgaben (z. B. Wartungstickets) automatisch nach konfigurierbaren Zeitregeln erzeugen und erwartete externe Ereignisse überwachen, sodass ausbleibende oder fehlerhafte Ereignisse als Service-Vorgang sichtbar werden. +Ergebnis: Wiederkehrende Aufgaben entstehen ohne manuelle Anlage; Abweichungen erwarteter Ereignisse sind protokolliert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\TaskManager\ActionHandler\TaskManagementHelpdeskActionHandler.cs, Execute() - Begründung: Erzeugt automatisch ein Helpdesk-Ticket inkl. Fälligkeit aus Priorität und DueDateOffset. + - [PRIMÄR] src\backend\Centron.BL\ExpectedEvents\ExpectedEventsBL.cs, SaveExpectedEvent()/SaveExpectedEventLogEntry() - Begründung: Persistiert die Überwachungsdefinitionen und deren Ereignis-Logs mit HelpdeskI3D. + - [KONTEXT] docs\features\automatic-helpdesk-creation-templates.md - Begründung: Beschreibt das Vorlagensystem für automatische Ticketerstellung aus Aufträgen. +Prüfidee: Wiederkehrende Aufgabe (wöchentlich) mit Helpdesk-Aktion konfigurieren; prüfen, dass zum Stichtag ein Ticket mit korrekter Fälligkeit entsteht. +Tracelinks: SyRS-517 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - reduziert manuellen Aufwand; für MSP-/Wartungsgeschäft zentral. +Status: belegt +``` + +### StRS-504: Kunden-Selbstbedienung und Feedback (SelfCare, Umfragen) + +``` +ID: StRS-504 +Titel: Kunden-Selbstbedienung und Feedback (SelfCare, Umfragen) +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Kunde/Endanwender, Service-Mitarbeiter (Versand), System (ServiceBoard-Web) +Vorbedingung: SBO-/ServiceBoard-URL konfiguriert; Kundenkontakt mit E-Mail +Fakt: SelfCareBL versendet Webformulare als GUID-basierte Links mit Ablaufdatum an Kunden; SurveyProcessBL instanziiert Umfragen aus Vorlagen und versendet verschlüsselte Umfrage-Links; HelpdeskCloseBL.AddSurvey() hängt beim Ticketabschluss optional eine Umfrage an die Abschlussmail. +Aussage: Das System soll Kunden über personalisierte, zeitlich begrenzte Web-Links in Serviceprozesse einbinden (Formulare ausfüllen, Zufriedenheit rückmelden), ohne dass ein Login im ERP notwendig ist. +Ergebnis: Kunden können Formulare/Umfragen über sichere Links bearbeiten; Ergebnisse fließen zum Ticket bzw. Konto zurück. +Belege: + - [PRIMÄR] src\backend\Centron.BL\SelfCare\SelfCareBL.cs, GetWebFormByGuid(): Ablaufprüfung "if (DateTime.Now > expirationDate) return Result.AsError(\"Link has expired\")" - Begründung: Durchgesetzte zeitliche Begrenzung des Kundenzugriffs. + - [PRIMÄR] src\backend\Centron.BL\Accounts\Survey\SurveyProcessBL.cs, GetSurveyfromTemplate(): CryptoControl.EncryptToString(surveyI3D) im Link, Status=SurveyStatus.Open - Begründung: Instanziierung und geschützte Verlinkung der Umfrage. + - [SEKUNDÄR] src\backend\Centron.BL\Sales\Support\HelpdeskCloseBL.cs, AddSurvey() - Begründung: Kopplung Umfrage an Ticketabschluss (Konfig-Schalter ValueAttachmentForHelpdesk). +Prüfidee: Webformular versenden, Link nach Ablauffrist öffnen — Zugriff muss verweigert werden; Ticket schließen mit aktivierter Umfrageoption — Mail enthält Umfrage-Link. +Tracelinks: SyRS-518, SyRS-519 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Selbstbedienung ist für eine SaaS-Neuimplementierung strategisch zentral. +Status: belegt +``` + +## Cluster A6 — Stammdaten & Assets — StRS + +### StRS-601: Zentraler Geschäftspartnerstamm mit rollenbasiertem Zugriff + +``` +ID: StRS-601 +Titel: Zentraler Geschäftspartnerstamm mit rollenbasiertem Zugriff +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertriebsmitarbeiter, Einkäufer, Innendienst +Vorbedingung: Benutzer ist am System angemeldet und besitzt Kunden-/Lieferantenrechte +Fakt: Ein Account (Tabelle Accounts) trägt über AccountTypeToAccounts gleichzeitig Kunden- (AccountCustomers), Lieferanten- (AccountSuppliers) und weitere Rollen; Adressen (AccountAddresses) und Ansprechpartner (AccountAddressContacts) hängen am Account; jede CRUD-Operation prüft Benutzerrechte (AccountBL.ValidateUserRights). +Aussage: Das System soll Kunden, Lieferanten und Interessenten als einen gemeinsamen Geschäftspartner (Account) mit mehreren gleichzeitigen Rollen, Adressen und Ansprechpartnern führen, wobei der Zugriff je Rolle über Benutzerrechte gesteuert wird. +Ergebnis: Ein Geschäftspartner existiert genau einmal und kann zugleich Kunde und Lieferant sein; unautorisierte Zugriffe werden abgewiesen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Accounts\AccountBL.cs, AccountBL.SaveAccount / ValidateUserRights (Prüfung CREATE_CUSTOMER, RIGHT_LIEFERANTANLEGEN je nach CustomerData/SupplierData) - Begründung: erzwingt Rollenmodell und Rechteprüfung beim Speichern. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[Accounts] / [AccountCustomers] / [AccountSuppliers], Mapping AccountTypeToAccounts (src\backend\Centron.DAO\Mappings\Accounts\AccountTypeToAccountMaps.cs) - Begründung: Datenmodell belegt einen Account mit mehreren Rollen-Satellitentabellen. +Prüfidee: Einen Account mit Kunden- und Lieferantenrolle anlegen; prüfen, dass beide Rollen an demselben Accounts-Datensatz hängen und ohne CREATE_CUSTOMER-Recht die Anlage abgewiesen wird. +Tracelinks: SyRS-605, SyRS-606 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - einheitlicher Partnerstamm mit Rollen ist tragfähiges Zielbild für die Web-Neuimplementierung. +Status: belegt +``` + +### StRS-602: Verwaltung von Mitarbeitern und Benutzerkonten + +``` +ID: StRS-602 +Titel: Verwaltung von Mitarbeitern und Benutzerkonten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Personalverantwortlicher, Administrator +Vorbedingung: Benutzer besitzt Personalverwaltungsrechte +Fakt: Mitarbeiter (Tabelle Personal, Entity Employee) und interne Benutzerkonten (AppUser) sowie kundenseitige Web-Zugänge (WebAccounts) werden getrennt geführt; Logins werden übergreifend auf Eindeutigkeit geprüft; Mitarbeiterpflege verlangt ADMINISTRATE_ALL_EMPLOYEES. +Aussage: Das System soll Mitarbeiterstammdaten und die zugehörigen Benutzerkonten (interne AppUser, kundenseitige WebAccounts) verwalten, wobei Logins systemweit eindeutig sind und die Pflege nur berechtigten Rollen möglich ist. +Ergebnis: Jeder Mitarbeiter hat höchstens ein eindeutiges Benutzerkonto; Personaldaten sind nur mit Personalrecht änderbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\EmployeeArea\EmployeeBL.cs, SaveOrUpdateEmployee: `if(loggedInUser.User.HasUserRight(UserRightsConst.Administration.EmployeeManagement.ADMINISTRATE_ALL_EMPLOYEES) == false) return ... AsError(...)` - Begründung: durchsetzende Rechteprüfung der Mitarbeiterpflege. + - [PRIMÄR] src\backend\Centron.BL\EmployeeArea\AppUserBL.cs, SaveOrUpdateAppUser (Dublettenprüfung Name gegen AppUser und WebAccount) - Begründung: erzwingt eindeutige Logins über beide Kontoarten. +Prüfidee: Anlage eines AppUsers mit bereits vergebenem WebAccount-Benutzernamen muss mit Fehlermeldung abgewiesen werden; Speichern eines Mitarbeiters ohne Personalrecht muss scheitern. +Tracelinks: SyRS-607, SyRS-608 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Trennung Mitarbeiter/Benutzerkonto mit gemeinsamem Login-Namensraum ist fachlich sinnvoll. +Status: belegt +``` + +### StRS-603: Einheitliche Verwaltung von Kundengeräten und Assets + +``` +ID: StRS-603 +Titel: Einheitliche Verwaltung von Kundengeräten und Assets +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Servicetechniker, Vertragsverwalter, Support +Vorbedingung: Kunde ist im System angelegt +Fakt: Geräte beim Kunden werden in mindestens drei getrennten Datenhaltungen geführt: „Stammblätter" (MasterDataList, Drucker/Kopierer mit Klickzählern für Click-Verträge), AccountDevices (sonstige Kundengeräte mit Seriennummer/Hersteller/Standort) sowie extern synchronisierte Asset-Management-Geräte (CentronObjectKindNumeric.AssetManagementDeviceClass, DocuBoard/River). +Aussage: Das System soll alle beim Kunden eingesetzten Geräte (Drucker mit Zählerabrechnung ebenso wie sonstige Hardware) mit Seriennummer, Historie und Ticket-/Vertragsbezug verwalten; in einer Neuimplementierung sollen die heute getrennten Datenhaltungen zu einem Gerätestamm konsolidiert werden. +Ergebnis: Für Support und Vertragsabrechnung ist je Gerät eine eindeutige, historisierte Datenbasis verfügbar. +Belege: + - [PRIMÄR] src\backend\Centron.Entities\Entities\Sales\Receipts\MasterDataLists\MasterDataList.cs (SerialNumber, CounterDevice, ContractI3D) und src\backend\Centron.Entities\Entities\Devices\AccountDevice.cs (SerialNumber, Manufacturer, Location) - Begründung: zwei parallele Entitäten für denselben Gegenstand „Gerät beim Kunden". + - [SEKUNDÄR] src\backend\Centron.Interfaces\CentronObjectKindNumeric.cs, MasterDataListClass = 25 → UI-Text "Stammblatt"; AssetManagementDeviceClass = 5101330 - Begründung: benennt die getrennten Objektarten fachlich. +Prüfidee: Für einen Kunden je ein Stammblatt und ein AccountDevice anlegen; prüfen, dass beide getrennt gespeichert werden (Tabellen MasterDataList vs. AccountDevices) und keine gemeinsame Sicht existiert. +Tracelinks: SyRS-609, SyRS-610 +Konsolidierung: Kandidat: MasterDataList (Stammblätter/Drucker) vs. AccountDevices (sonstige Hardware) vs. AssetManagement-/River-Geräte (DocuBoard, SelfCareWebserviceBL) — drei Datenhaltungen für den Gegenstand „Kundengerät". +Übernahmewürdigkeit: übernehmen - Funktion ist zentral; die getrennten Implementierungen sind der bekannte Konsolidierungsfall. +Status: belegt +``` + +### StRS-604: Erweiterbare Stamm- und Referenzdaten + +``` +ID: StRS-604 +Titel: Erweiterbare Stamm- und Referenzdaten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator, Fachanwender, externe Systeme +Vorbedingung: keine +Fakt: Objekte können ohne Schemaänderung um konfigurierbare Zusatzfelder (ModuleCustomProperties inkl. IsMandatory, Sealable, verschlüsselte Werte) und Schlagworte (Tags) erweitert werden; Objekte lassen sich über ObjectExternalReferences mit Fremdsystemen (z. B. DocBee) verknüpfen; Länder (Laenkenn) mit Währung, Vorwahl, MwSt-Konten dienen als zentrale Referenzdaten. +Aussage: Das System soll Stammdatenobjekte kundenindividuell um Zusatzfelder und Tags erweitern können, Verknüpfungen zu externen Systemen je Objekt führen und zentrale Länder-/Regionsreferenzdaten (inkl. Währungen) bereitstellen. +Ergebnis: Fachliche Erweiterungen und Fremdsystem-Verknüpfungen sind ohne Programmänderung möglich. +Belege: + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[ModuleCustomProperties] (Spalten DataType, IsMandatory, Sealable, ValueMask) und [ModuleCustomPropertyValues] (typisierte Value*-Spalten inkl. ValueEncryptedString) - Begründung: generisches EAV-Datenmodell für Zusatzfelder. + - [PRIMÄR] src\backend\Centron.BL\ObjectExternalReferences\ObjectExternalReferenceBL.cs, CreateReference (Eindeutigkeits- und Pflichtfeldprüfung) - Begründung: durchgesetzte Verknüpfungslogik zu Fremdsystemen. +Prüfidee: Zusatzfeld vom Typ „verschlüsselter Text" für Objektart Kunde definieren, Wert erfassen und prüfen, dass er in ModuleCustomPropertyValues.ValueEncryptedString landet; doppelte Externreferenz muss abgewiesen werden. +Tracelinks: SyRS-611, SyRS-612, SyRS-613 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Erweiterbarkeit ist ein Kernmerkmal für SaaS-Mandantenfähigkeit. +Status: belegt +``` + +## Cluster A7 — Kommunikation & persönliche Organisation — StRS + +### StRS-701: Geschäftskommunikation per E-Mail aus dem ERP + +``` +ID: StRS-701 +Titel: Geschäftskommunikation per E-Mail aus dem ERP +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Mitarbeiter (Vertrieb, Helpdesk, Buchhaltung), Administrator +Vorbedingung: Mandant hat Mailversand konfiguriert (SMTP, Exchange/EWS oder Microsoft Graph) +Fakt: Die Codebasis enthält einen vollständigen Mailversand-Stack (CentronMailFactory mit drei Transportprotokollen, Vorlagen, Signaturen, Absender-Whitelist, Domain-Blacklist) sowie einen Mail-Eingangs-Scanner (MailScannerBL / "Virtual Mail Assistant"), der eingehende Mails Workflows zuführt. +Aussage: Das System soll geschäftliche E-Mail-Kommunikation (Angebote, Rechnungen, Helpdesk, Eskalationen) direkt aus dem ERP heraus versenden und eingehende E-Mails automatisiert Geschäftsprozessen zuordnen können, ohne dass Mitarbeiter einen externen Mail-Client benötigen. +Ergebnis: E-Mails werden im Namen konfigurierter Firmen-Absenderadressen versendet und protokolliert; eingehende Mails lösen Workflows aus. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Mail\Factory\CentronMailFactory.cs, GetMail(): switch über CentronWebserviceMailType (Exchange/Graph/SMTP) - Begründung: zeigt, dass Mailversand ein zentraler, kanalunabhängiger Systemdienst ist. + - [SEKUNDÄR] src\backend\Centron.BL\Mail\MailSettingsBL.cs, GetMailSettings(): dedizierte Absenderadressen je Geschäftsprozess (InvoiceAndCreditVouchersSenderEmailAddress, HelpdeskSenderEmailAddress, OfferSenderEmailAddress, OrderSenderEmailAddress) - Begründung: belegt die fachliche Breite des Mailversands über die Geschäftsbereiche. +Prüfidee: Angebot per Mail versenden bei jeweils konfiguriertem SMTP-, EWS- und Graph-Kanal; Mail kommt mit korrekter Absenderadresse an. +Tracelinks: SyRS-711, SyRS-712, SyRS-713, SyRS-714 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kern der Kundenkommunikation, für SaaS-Neuimplementierung unverzichtbar. +Status: belegt +``` + +### StRS-702: Kalender- und Outlook/Exchange-Integration + +``` +ID: StRS-702 +Titel: Kalender- und Outlook/Exchange-Integration +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Mitarbeiter (Außendienst, Helpdesk), Kunde (als Termin-Empfänger) +Vorbedingung: Exchange-/Graph-Zugangsdaten sind hinterlegt +Fakt: Das System pflegt Termine in Exchange-Postfächern (EwsCalendarAccess: CreateAppointment/UpdateAppointment/DeleteAppointment mit SendInvitationsMode), wickelt Terminvereinbarungen mit Kunden über Terminvorschläge ab (AppointmentRequestBL) und synchronisiert Nexus-/Helpdesk-Zeiten mit Outlook (dokumentiert in docs\features\exchange-sync-bugprotokoll.md). +Aussage: Das System soll Termine und geplante Zeiten der Mitarbeiter bidirektional mit Outlook/Exchange synchronisieren und Terminvereinbarungen mit Kunden inklusive Einladungsversand unterstützen. +Ergebnis: ERP-Termine erscheinen im Outlook-Kalender der Mitarbeiter; akzeptierte Kundentermine erzeugen Exchange-Einladungen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Mail\Exchange\EwsHelper\EwsCalendarAccess.cs, CreateAppointment()/UpdateAppointment(): appointment.Save(SendInvitationsMode.SendToAllAndSaveCopy) - Begründung: durchgesetzte Terminanlage inkl. Einladungsversand im Exchange-Kalender. + - [KONTEXT] docs\features\exchange-sync-bugprotokoll.md (Tickets 164020, 163184 u. a. zu SyncOldSchedule()/UpdateScheduleByGraph()) - Begründung: dokumentiert die produktive bidirektionale Synchronisation und ihre Fallstricke. +Prüfidee: Termin im ERP anlegen und prüfen, dass er im Outlook-Kalender des Mitarbeiters erscheint; Termin in Outlook verschieben und Rücksynchronisation prüfen. +Tracelinks: SyRS-715, SyRS-716 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kalenderintegration ist zentrales Arbeitsmittel; Transportweg (EWS vs. Graph) ist bei Neuimplementierung zu vereinheitlichen. +Status: belegt +``` + +### StRS-703: Persönliche Arbeitsorganisation und Benachrichtigung + +``` +ID: StRS-703 +Titel: Persönliche Arbeitsorganisation und Benachrichtigung +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Mitarbeiter, Teamleiter, Administrator +Vorbedingung: Mitarbeiter ist angemeldet +Fakt: Die Module MyDay (Tageszeiterfassung mit Tagesabschluss MyDayFinalizedDay), ToDoArea (objektbezogene Wiedervorlagen zu Belegen, Verträgen, Tickets, Geburtstagen), QuickNotes und Notifications/NexusNotifications (gelesen/gesehen-Status, Ticket-Zuweisungsmeldungen) bilden eine persönliche Arbeitsvorratssteuerung. +Aussage: Das System soll jedem Mitarbeiter eine persönliche Tages- und Aufgabenorganisation bereitstellen: erfasste Arbeitszeiten mit verbindlichem Tagesabschluss, automatisch erzeugte Wiedervorlagen (ToDos) aus Geschäftsobjekten sowie Benachrichtigungen über für ihn relevante Ereignisse. +Ergebnis: Mitarbeiter sehen ihren Arbeitsvorrat; Teamleiter werden über fehlende Tagesabschlüsse informiert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\MyDay\MyDayNotificationsBL.cs, GetDayNotFinalizedNotifications()/GenerateTeamLeaderNotifications(): Ermittlung von Mitarbeitern ohne MyDayFinalizedDay und Erzeugung von Erinnerungen inkl. Teamleiter-Eskalation - Begründung: durchgesetzter Prozess des verbindlichen Tagesabschlusses. + - [PRIMÄR] src\backend\Centron.BL\ToDoArea\ToDoBL.cs, HandleReceiptToDoEntries()/CreateBirthdayTodo()/HandleVideoPortalAssignmentEntries(): automatische ToDo-Erzeugung aus Geschäftsobjekten - Begründung: belegt objektgetriebene Wiedervorlagen. +Prüfidee: Mitarbeiter schließt einen Tag nicht ab; am Folgearbeitstag entsteht eine Erinnerung an ihn und (konfigurationsabhängig) an den Teamleiter. +Tracelinks: SyRS-718, SyRS-719 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Tagesabschluss und ToDo-Steuerung sind abrechnungsrelevant (Zeiterfassung) und produktiv genutzt. +Status: belegt +``` + +### StRS-704: Telefonie-Integration und interne Team-Kommunikation + +``` +ID: StRS-704 +Titel: Telefonie-Integration und interne Team-Kommunikation +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Mitarbeiter (Innendienst), Administrator +Vorbedingung: TAPI-/Teams-Telefonie bzw. Chat-Funktion ist eingerichtet +Fakt: PhoneCallBL protokolliert Anrufe (ein-/ausgehend, Dauer, intern/extern), identifiziert Anrufer über mehrstufige Rufnummernsuche in Kontakten/Konten und synchronisiert Teams-Anrufe über Microsoft Graph (lizenzpflichtig); ChatBL bietet objektbezogene Mitarbeiter-Chats (z. B. zu Tickets/Belegen); SocialMediaBL bietet Streams mit Likes/Kommentaren/Abonnements. +Aussage: Das System soll eingehende und ausgehende Telefonate automatisch protokollieren und den Anrufer dem richtigen Kunden/Ansprechpartner zuordnen sowie interne Kommunikation der Mitarbeiter (Chats zu Geschäftsobjekten, Aktivitäten-Streams) im ERP abbilden. +Ergebnis: Anrufjournal mit Kundenzuordnung; nachvollziehbare interne Abstimmung direkt am Geschäftsobjekt. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Tapi\PhoneCallBL.cs, SearchContactPersonByPhoneNumberV2(): mehrstufige Suche (formatiert, unformatiert, trunkiert, Länderpräfix entfernt) nach Ansprechpartnern zur Rufnummer - Begründung: durchgesetzte Anruferidentifikation als Kern des Telefonie-Moduls. + - [PRIMÄR] src\backend\Centron.BL\Chats\ChatBL.cs, CreateChat(): Chats werden mit ObjectKind/ObjectI3D an Geschäftsobjekte (Helpdesk, Belege) gebunden - Begründung: belegt objektbezogene interne Kommunikation. +Prüfidee: Simulierter eingehender Anruf mit bekannter Kundennummer öffnet den passenden Kundenkontakt; Chat zu einem Ticket ist nur für Mitglieder sichtbar. +Tracelinks: SyRS-717, SyRS-718 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Anruferidentifikation ist produktiv wertvoll; Social-Media-Stream-Teil ist gesondert auf Nutzung zu prüfen (siehe SwRS-748). +Status: belegt +``` + +## A8 — Web-Client Nexus & Service-Schnittstellen — StRS + +### StRS-801: Kunden-Selbstbedienungsportal (WebCart/Kundenportal) + +``` +ID: StRS-801 +Titel: Kunden-Selbstbedienungsportal für Endkunden +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Web-Account (Endkunde eines c-entron-Kunden), Kundenadministrator +Vorbedingung: Für den Kunden wurde im Adressstamm ein Web-Account angelegt; Lizenz WebCart2 vorhanden +Fakt: Das Nexus-Modul WebCart stellt unter /webcart und /customerportal Seiten für Shop, Warenkorb, Belege (Angebote/Rechnungen/Lieferscheine/Verträge), Tickets, Formulare und Dokumente bereit; laut README ist der WebCart "primarily intended for the customers of our customers" mit Login als Web-Account. +Aussage: Das System soll Endkunden der c-entron-Anwender ein Web-Portal bieten, in dem sie mit einem Web-Account Artikel bestellen, eigene Belege und Verträge einsehen, Support-Tickets verfolgen und Formulare ausfüllen können. +Ergebnis: Endkunden erledigen Bestellungen und Serviceanliegen selbstständig ohne Telefon/E-Mail-Umweg. +Belege: + - [PRIMÄR] src\nexus\CentronNexus\WebCart\_Imports.razor - Zeilen "@attribute [AuthorizeLoginWebAccount]" und "@attribute [AuthorizeCustomerPortalPort]" - Begründung: Alle WebCart-Seiten sind ausschließlich für den Login-Typ Web-Account freigeschaltet, was den Endkunden-Fokus des Portals technisch durchsetzt. + - [SEKUNDÄR] src\nexus\CentronNexus\WebCart\WebCartShopPage.razor, ReceiptsOverview.razor, WebCartTicketsPage.razor, CustomerPortalFormsPage.razor - @page-Routen /webcart/... und /customerportal/... - Begründung: Zeigt den fachlichen Funktionsumfang des Portals (Shop, Belege, Tickets, Formulare). + - [KONTEXT] README.md, Abschnitt "1. WebCart" - "feature primarily intended for the customers of our customers" - Begründung: Dokumentiert den Stakeholder-Zweck. +Prüfidee: Login mit Web-Account: Shop, Belege, Tickets und Formulare sind erreichbar; Login mit Mitarbeiter-User: WebCart-Seiten werden verweigert. +Tracelinks: SyRS-811, SyRS-812, SyRS-813, SyRS-814, SyRS-815 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kernstück einer SaaS-Neuimplementierung (Kundenportal ist strategisch zentral). +Status: belegt +``` + +### StRS-802: Web-gestützte Service- und Produktionssteuerung für Mitarbeiter + +``` +ID: StRS-802 +Titel: Web-Arbeitsplatz für Servicemitarbeiter und Produktion (ServiceBoard) +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Servicemitarbeiter (Techniker, Disponent), Produktionsmitarbeiter +Vorbedingung: Mitarbeiter-Login (User) und Lizenz ServiceBoardWebDev +Fakt: Das Nexus-Modul ServiceBoard umfasst u. a. TicketList, Kanban, Scheduler, Timerecords, Stopwatches, CloseTicket, MyDay, Statistics; ProductionOrderManagement stellt eine Werkschritt-Übersicht pro Arbeitsplatz/Maschine bereit. +Aussage: Das System soll Servicemitarbeitern einen browserbasierten Arbeitsplatz bieten, um Tickets zu bearbeiten, zu planen und abzuschließen, Zeiten zu erfassen sowie Produktionsaufträge (Werkschritte) am Arbeitsplatz zu bearbeiten. +Ergebnis: Ticket- und Produktionsbearbeitung ist ohne den Windows-Client c-entron.NET im Browser möglich. +Belege: + - [PRIMÄR] src\nexus\CentronNexus\ServiceBoard\_Imports.razor - "@attribute [AuthorizeLoginUser]", "@attribute [AuthorizeLicense(nameof(LicenseGuids.ServiceBoardWebDev))]", "@attribute [AuthorizeHostPort]" - Begründung: Setzt durch, dass das ServiceBoard ein lizenzierter Mitarbeiter-Arbeitsbereich ist. + - [SEKUNDÄR] src\nexus\CentronNexus\ServiceBoard\ (Ordner CloseTicket, Kanban, Scheduler, Stopwatches, Timerecords, MyDay u. a.) - Begründung: Funktionsumfang des Mitarbeiter-Arbeitsplatzes. + - [SEKUNDÄR] src\nexus\CentronNexus\ProductionOrderManagement\Pages\ProductionOrderOverView.razor - Route "/production/overview", Auswahl Arbeitsplatz/Maschine, Werkschritt-Liste - Begründung: Produktionssicht für Werker. +Prüfidee: Mitarbeiter mit ServiceBoard-Lizenz öffnet /serviceboard-Seiten und schließt ein Ticket; ohne Lizenz wird der Zugriff verweigert. +Tracelinks: SyRS-811, SyRS-816 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - webbasierter Servicearbeitsplatz ist Zielbild der Neuimplementierung. +Status: belegt +``` + +### StRS-803: Sichere programmatische Schnittstellen (REST-API, Legacy-Webservices, Mobile) + +``` +ID: StRS-803 +Titel: Abgesicherte Service-Schnittstellen für Clients und Integrationen +Ebene: StRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: API-Clients (c-entron.NET, Nexus, Mobile-Apps, Drittintegrationen wie DocBee/RMM/Shipcloud) +Vorbedingung: Web-Service (Centron.Host) läuft und ist per HTTP(S) erreichbar +Fakt: Der Web-Service exponiert eine versionierte REST-API (Centron.Controllers, Route "v{version}") und eine flache Legacy-API (CentronRestService, POST-Methoden mit [Authenticate]); jeder Zugriff erfordert Authentifizierung (JWT/Bearer, Centron-Ticket oder Access-Token) und Rechteprüfungen (Authorize*-Attribute bzw. BL-Prüfungen). +Aussage: Das System soll alle Geschäftsfunktionen über zentral abgesicherte Service-Schnittstellen bereitstellen, bei denen jede Anfrage authentifiziert und gegen Benutzerrechte bzw. Lizenzen autorisiert wird. +Ergebnis: Kein API-Zugriff auf Geschäftsdaten ohne gültige Authentifizierung und ausreichende Berechtigung. +Belege: + - [PRIMÄR] src\webservice\Centron.Controllers\Authorization\AuthorizeUserRightAttribute.cs - UserRightAuthorizationFilter.OnAuthorization: "if (currentUser == null) { context.Result = new UnauthorizedResult(); return; } if (!_requiredRightId.HasValue || !currentUser.HasUserRight(_requiredRightId.Value)) context.Result = new ForbidResult();" - Begründung: Durchsetzende Stelle der rechtebasierten API-Autorisierung. + - [PRIMÄR] src\webservice\Centron.Host\AspNetCore\WcfBridge\Interception\Interceptors\AuthenticateInterceptor.cs - InterceptExecution/ValidateTicketAndSetReturnValue: ohne gültiges Ticket/Access-Token wird "Invalid ticket or access token." zurückgegeben, Invocation.Proceed() unterbleibt - Begründung: Durchsetzende Stelle für die Legacy-API. + - [KONTEXT] docs\guides\services\add-webservice-methods.md - Vorgabe [Authenticate]-Attribut je Webservice-Methode - Begründung: Dokumentiertes Sicherheitsmuster. +Prüfidee: Aufruf eines v1-Endpunkts ohne Token → 401; mit Token ohne Recht → 403; Legacy-Methode ohne Ticket → Response mit Status InvalidTicket. +Tracelinks: SyRS-817, SyRS-818, SyRS-819 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Autorisierungsmodell (Rechte/Lizenzen je Endpunkt) ist zu übernehmen; die doppelte API-Landschaft selbst ist zu konsolidieren. +Status: belegt +``` + +### StRS-804: Betreibbarkeit und Konfiguration des Web-Service + +``` +ID: StRS-804 +Titel: Flexibler Betrieb des Web-Service (Windows, Konsole, Linux) +Ebene: StRS +Typ: nicht-funktional +Qualitätsmerkmal: Übertragbarkeit +Akteur: Systemadministrator des c-entron-Kunden +Vorbedingung: Datenbankserver erreichbar; WebServiceConfig.xml vorhanden +Fakt: Der identische CentronHost wird als Windows-Dienst (Centron.Host.WindowsService), als Konsolenanwendung (Centron.Host.Console, auch unter Linux) gestartet; der ConnectionManager (WPF-Tool) erzeugt/pflegt die Konfiguration (DB-Verbindung, Adressen, Proxy, Active Directory, Zertifikate). +Aussage: Das System soll den Web-Service in mehreren Hosting-Varianten (Windows-Dienst, Konsole, Linux) mit einer zentralen, werkzeuggestützt gepflegten Konfiguration betreibbar machen. +Ergebnis: Administratoren können den Web-Service auf Windows- und Linux-Servern installieren, konfigurieren und mit HTTPS betreiben. +Belege: + - [PRIMÄR] src\webservice\Centron.Host.WindowsService\CentronService.cs - OnStart/OnStop rufen CentronHost.Instance.Start()/Stop() - Begründung: Windows-Dienst-Hülle um denselben Host. + - [PRIMÄR] src\webservice\Centron.Host.Console\Program.cs - args [] oder ["start"] → CentronHost.Instance.Start() - Begründung: Konsolen-Hülle um denselben Host (Linux-fähig). + - [SEKUNDÄR] src\webservice\c-entron.misc.ConnectionManager\ConnectionManagerViewModel.cs - DoSaveConfigAsync setzt ConfigHelper.Config.DatabaseConnectionString via SqlHelper.GetConnectionString(...) - Begründung: Werkzeuggestützte Konfigurationspflege. + - [KONTEXT] docs\guides\services\web-service-on-linux.md - Anleitung inkl. WebServiceCertificateFilePath/WebServiceCertificatePassword in WebServiceConfig.xml - Begründung: Dokumentierter Linux-/HTTPS-Betrieb. +Prüfidee: Start des Host über Konsole und als Windows-Dienst mit derselben WebServiceConfig.xml; Web-Service ist in beiden Fällen per HTTP(S) erreichbar. +Tracelinks: SyRS-820 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - On-Premise-Hosting-Varianten entfallen in einer SaaS-Zielarchitektur weitgehend; Konfigurationsbedarf bleibt (Mandanten-Provisionierung). +Status: belegt +``` + +## Cluster A9 — Datenaustausch & Integrationen — StRS + +### StRS-901: Anbindung von RMM- und Service-Management-Systemen + +``` +ID: StRS-901 +Titel: Anbindung von RMM- und Service-Management-Systemen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Managed-Service-Provider (MSP, Systemhaus als c-entron-Betreiber), externe RMM-/Service-Systeme (Riverbird, DocBee) +Vorbedingung: Der Betreiber nutzt ein externes RMM- (Remote Monitoring & Management) oder Service-Management-System parallel zu c-entron. +Fakt: Es existiert eine dedizierte REST-Schnittstelle (RmmController, Route "v1/rmm") mit Endpunkten für Ticketanlage/-abschluss, Ticketvorlagen, Dokumente, Kundensynchronisation und Gerätedaten; DocBee-Konnektoren synchronisieren Tickets und Zeitbuchungen (DocBeeTicketTimerBL, DocBeeTicketCreationBL). +Aussage: Das System soll externen RMM- und Service-Management-Systemen ermöglichen, Tickets, Zeitbuchungen, Geräte, Dokumente und Kundendaten bidirektional mit c-entron auszutauschen, sodass Servicevorgänge nur einmal erfasst werden müssen. +Ergebnis: Tickets, Zeiten und Geräte aus dem Fremdsystem sind in c-entron vorhanden und abrechenbar; Stammdaten aus c-entron stehen im Fremdsystem zur Verfügung. +Belege: + - [PRIMÄR] src\webservice\Centron.Controllers\Controllers\v1\Integrations\RmmController.cs - Klasse RmmController mit Endpunkten helpdesks/create, customers/sync, devices, documents - Begründung: implementierte Austausch-Schnittstelle für RMM-Systeme. + - [PRIMÄR] src\backend\Centron.BL\DataExchange\Connectors\DocBeeTicketTimerBL.cs - Methode SaveDocBeeTicketTimer - Begründung: Übernahme von Zeitbuchungen aus DocBee inkl. Ticketanlage. + - [KONTEXT] src\backend\Centron.BL\RiverDivo\RiverDivoBL.cs - Klassenkommentar "implements the web-service methods, that the Riverbird Web-Service calls" - Begründung: benennt Riverbird als konkretes RMM-Gegenstück. +Prüfidee: Ein per RMM-Schnittstelle angelegtes Ticket erscheint im c-entron-Helpdesk mit Herkunftskennzeichen und kann dort abgerechnet werden. +Tracelinks: SyRS-911, SyRS-912, SyRS-913, SyRS-918 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kernfunktion für das MSP-Geschäftsmodell der Zielgruppe. +Status: belegt +``` + +### StRS-902: Elektronischer Beleg- und Katalogaustausch mit Handelspartnern + +``` +ID: StRS-902 +Titel: Elektronischer Beleg- und Katalogaustausch mit Handelspartnern +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Einkauf/Vertrieb des Systemhauses, Distributoren (Also, Alltron, Komsa, Herweck, EGIS), Buchhaltungssysteme (DATEV, Abacus, Sage u. a.), Telekom-Marktplatz D!VE +Vorbedingung: Geschäftsbeziehung zu einem Distributor, einer Steuerkanzlei/FiBu oder dem Telekom-Partnerprogramm besteht. +Fakt: Das Gateway-Projekt enthält je Distributor eigene EDI-Nachrichtenklassen (Order, OrderResponse, Delivery, Invoice), je FiBu-System eigene Export-/Importklassen sowie SEPA- (pain.008), OpenTrans- und ZUGFeRD-Formate; der TelekomDive-Export erzeugt ein Angebots-XML. +Aussage: Das System soll Belege (Bestellungen, Auftragsbestätigungen, Lieferscheine, Rechnungen, Buchungssätze, Zahlungen, Angebote) in den Formaten der jeweiligen Handels-, Buchhaltungs- und Marktplatzpartner elektronisch exportieren und importieren können. +Ergebnis: Belegdaten fließen ohne manuelle Doppelerfassung zwischen c-entron und den Partnersystemen. +Belege: + - [PRIMÄR] src\backend\Centron.Gateway\EDI_Also\Order\xmlOrder240.cs, EDI_Alltron\AlltronOrder.cs, EDI_Komsa\Order\KomsaOrder.cs - Begründung: distributorspezifische EDI-Nachrichtenimplementierungen. + - [PRIMÄR] src\backend\Centron.Gateway\DataExchange\BookKeeping\DatevAscii\BookKeepingExportDatevAscii.cs und weitere Export-Klassen unter DataExchange\BookKeeping\* - Begründung: FiBu-Formatadapter pro Zielsystem. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\TelekomDive\TelekomDiveExportViewModel.cs - Methode ExportToXml (Elemente offer_recipient, partner_name, customer_name) - Begründung: Marktplatz-Angebotsexport Telekom D!VE. +Prüfidee: Für einen Testauftrag lässt sich je aktiviertem Partnerformat eine formatkonforme Datei erzeugen, die vom Partnersystem (Schemavalidierung) akzeptiert wird. +Tracelinks: SyRS-915, SyRS-916 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - gesetzliche und marktseitige Notwendigkeit (E-Rechnung, EDI); einzelne Alt-Formate sind je Partner zu prüfen. +Status: belegt +``` + +### StRS-903: Verbrauchsdatenübernahme für die Vertragsabrechnung + +``` +ID: StRS-903 +Titel: Verbrauchsdatenübernahme für die Vertragsabrechnung +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Faktura-Verantwortlicher des Systemhauses, docuFORM-Server (Managed Print Services), Riverbird-RMM +Vorbedingung: Kundenverträge werden nutzungsabhängig abgerechnet (Seitenzähler von Druckgeräten, Anzahl überwachter Server/Workstations). +Fakt: Der Klickzähler-Import lädt über die docuFORM-API Gerätezählerstände (GetAllDevices/GetDeviceCounters) in das Finanzmodul DeviceClickCounter; RiverConnectionBL.GetContractBillingAmounts fragt beim Riverbird-Service Abrechnungsmengen je Vertragsartikel (Server-/Workstation-Zahlen) ab. +Aussage: Das System soll abrechnungsrelevante Verbrauchsdaten (Gerätezählerstände, überwachte Gerätemengen) automatisiert aus den angebundenen Fremdsystemen übernehmen, damit nutzungsabhängige Verträge korrekt fakturiert werden. +Ergebnis: Verbrauchsmengen liegen periodengerecht in c-entron vor und fließen in die Vertragsabrechnung ein. +Belege: + - [PRIMÄR] src\backend\Centron.BL\RiverDivo\RiverConnectionBL.cs - Methode GetContractBillingAmounts (Aufruf "CentronDivo/GetContractBillingAmounts" mit ServerCount/WorkstationCount je ContractArticleReference) - Begründung: Abruf der Abrechnungsmengen aus dem RMM. + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\Finances\DeviceClickCounter\DocuFormApiImport\DocuFormApiImportViewModel.cs - Methode DownloadDeviceCounters - Begründung: Import der Seitenzähler in das Abrechnungsmodul. +Prüfidee: Nach einem Importlauf entsprechen die in c-entron gespeicherten Zählerstände den vom docuFORM-Testserver gelieferten Werten; die Vertragsabrechnung verwendet die importierten Mengen. +Tracelinks: SyRS-914 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zentral für wiederkehrende Erlöse (MPS-/MSP-Verträge). +Status: belegt +``` + +### StRS-904: Stammdatenimport und Datenbereitstellung für Drittsysteme + +``` +ID: StRS-904 +Titel: Stammdatenimport und Datenbereitstellung für Drittsysteme +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator/Anwender des Systemhauses, Quellsysteme (Excel, Active Directory), Drittsysteme (Dokumentenablage via DocSync, Webshop ElectronicSales) +Vorbedingung: Stammdaten liegen in Fremdformaten vor oder sollen Drittsystemen bereitgestellt werden. +Fakt: Es existieren Import-Assistenten für Konten (Kunden/Lieferanten/Kontakte) und Artikel inkl. Validierung (Pflichtfelder, IBAN-Prüfsumme), eine DocSync-Konfiguration je Objektart sowie ein Cache für ElectronicSales-Kundengruppen (EsCustomerGroup mit ExternalId). +Aussage: Das System soll Stammdaten strukturiert und validiert importieren sowie ausgewählte Daten (Dokumente, Kundengruppen-Referenzen) für Drittsysteme bereitstellen bzw. mit ihnen abgleichen. +Ergebnis: Stammdaten sind ohne fehlerhafte Datensätze übernommen; Drittsysteme arbeiten mit konsistenten Referenzdaten. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\DataExchange\DataImport\AccountImport\CentronImportManager.cs - Methode ImportAsync - Begründung: generischer Kontenimport aus Dateien. + - [PRIMÄR] src\backend\Centron.BL\Integrations\EsCustomerGroupBL.cs - Methoden Create/Update/Delete - Begründung: Pflege des ES-Kundengruppen-Caches für den Webshop-Abgleich. + - [SEKUNDÄR] src\backend\Centron.BL\Administration\FileManagement\DirectoryBL.cs - Methode GetDocSyncSettings (ApplicationSettingID.DocSyncActiveCentronObjectKinds) - Begründung: konfigurierbare Dokumentbereitstellung je Objektart. +Prüfidee: Ein Excel-Import mit teils fehlerhaften Zeilen übernimmt nur valide Datensätze und weist Fehler (z. B. ungültige IBAN) aus. +Tracelinks: SyRS-913, SyRS-917 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Onboarding- und Integrationsgrundfunktion. +Status: belegt +``` + +## A10 — StRS (Produktion, Projekte, PLM, QM, Statistik, Reporting) + +### StRS-1001: Produktionsaufträge planen und überwachen + +``` +ID: StRS-1001 +Titel: Produktionsaufträge planen und überwachen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Produktionsleiter, Fertigungsmitarbeiter +Vorbedingung: Kundenauftrag mit zu fertigenden Artikeln vorhanden; Lizenz "Produktionsmanagement" erworben +Fakt: Das Modul Produktion verwaltet ProductionOrder (verknüpft mit OrderI3D/OrderItemI3D des Verkaufsauftrags), ProductionOrderItem (Arbeitsschritte mit Maschine, Menge, Status) und ProductionOrderLog; sämtliche BL-Methoden sind über LicenseManager.HasLicense(LicenseGuids.ProductionManagement) abgesichert. +Aussage: Das System soll dem Produktionsverantwortlichen ermöglichen, aus Verkaufsaufträgen Produktionsaufträge mit Arbeitsschritten, Maschinenzuordnung und Terminen anzulegen, deren Fortschritt zu verfolgen und alle Änderungen nachvollziehbar zu machen; die Funktion ist ein lizenzpflichtiges Zusatzmodul. +Ergebnis: Produktionsaufträge mit Arbeitsschritten, Status und lückenlosem Änderungsprotokoll je Auftrag. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Production\ProductionOrderBL.cs, ProductionOrderBL.SaveProductionOrder / GetProductionOrdersByFilter mit Lizenzprüfung `if (LicenseManager.Instance.HasLicense(LicenseGuids.ProductionManagement) == false) throw ...` - Begründung: durchgesetzte Kernfunktion inkl. Lizenzgate. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, Tabellen ProductionOrders (OrderI3D NOT NULL, OrderNumber NOT NULL, PlannedFinishDate), ProductionOrderItems, ProductionOrderLogs - Begründung: Datenmodell trägt die Auftrag-Arbeitsschritt-Protokoll-Struktur. +Prüfidee: Ohne Produktionslizenz wird jede Produktionsfunktion mit Fehlermeldung abgewiesen; mit Lizenz kann ein Produktionsauftrag zu einem Verkaufsauftrag angelegt und sein Fortschritt eingesehen werden. +Tracelinks: SyRS-1010, SyRS-1011 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zentrale Fachfunktion für fertigende Kunden; Lizenz-/Feature-Gating auch im SaaS-Modell sinnvoll. +Status: belegt +``` + +### StRS-1002: Führungsinformationen, Statistiken und Reporting mit Zugriffsschutz + +``` +ID: StRS-1002 +Titel: Führungsinformationen, Statistiken und Reporting mit Zugriffsschutz +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Geschäftsführung, Controlling, Vertriebsleitung, Projektleiter +Vorbedingung: Bewegungsdaten (Belege, Tickets, Zeiten) vorhanden; Benutzer mit entsprechenden Rechten +Fakt: Statistik-BLs (SaleStatisticBL, ManagementInfoBL, CacheSalesStatisticsBL) prüfen Benutzerrechte (SALES_STATISTIC, MANAGEMENT_INFO) und schränken auf eigene Filiale ein; die ReportEngine verwaltet FastReport-Berichte zentral; Übersichtsmodule (Statistik-Dashboard, Projektmanagement-Board, Modul-Dashboard) stellen Kennzahlen und Arbeitsvorräte dar. +Aussage: Das System soll Führungs- und Fachanwendern Auswertungen (Umsatz-, Auftrags-, Ticket-, Mitarbeiterstatistiken), Management-Kennzahlen, Projekt-/Auslastungsübersichten und druckbare Berichte bereitstellen und den Zugriff dabei konsequent über Benutzerrechte und Filialzugehörigkeit beschränken. +Ergebnis: Berechtigte Anwender erhalten Kennzahlen und Berichte; unberechtigte Zugriffe werden mit Fehlermeldung abgelehnt. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Statistics\SaleStatistics\SaleStatisticBL.cs, GetSalesArticleStatistic: `if (!(_appRightsBL.HasUserRight(..., UserRightsConst.Controlling.Analytics.SALES_STATISTIC) || ...)) return AsError("Benutzer hat nicht die passenden Rechte.", DefaultMessageCodes.RightCheckFailed)` - Begründung: durchgesetzter Zugriffsschutz auf Auswertungen. + - [SEKUNDÄR] src\backend\Centron.BL\ReportEngine\ReportDataBL.cs, GetReportForPrinting / ConvertReportToPdfStream - Begründung: zentrale Berichtserzeugung als zweite Säule der Informationsversorgung. +Prüfidee: Benutzer ohne SALES_STATISTIC-Recht erhält bei Abruf der Verkaufsstatistik einen RightCheckFailed-Fehler; Benutzer mit Recht erhält Daten. +Tracelinks: SyRS-1012, SyRS-1013, SyRS-1014 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kernnutzen eines ERP; Rechte-/Mandantenschutz ist für SaaS zwingend. +Status: belegt +``` + +### StRS-1003: Kontrollierte Massenänderungen und Datenimporte + +``` +ID: StRS-1003 +Titel: Kontrollierte Massenänderungen und Datenimporte +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertriebsinnendienst, Stammdatenpfleger, Einkauf +Vorbedingung: Zu ändernde Objekte (Artikel, Belege, Konten, Sonderpreisvereinbarungen) vorhanden +Fakt: MassUpdateBL führt Preis- und Datenänderungen über MassUpdateTemplate/MassUpdateTemplateItems mit Ausführungsstatus, Fehlermeldung und Logeinträgen je Objekt aus; der Projektpreisimport liest Excel-Preislisten in Sonderpreisvereinbarungen ein und weist fehlerhafte Zeilen in einer Fehlerliste aus; QM-Rückgabegründe erzwingen Begründungen bei Belegrückläufern. +Aussage: Das System soll massenhafte Änderungen an Preisen und Stammdaten sowie Datenimporte nur über kontrollierte, wiederaufsetzbare Verfahren zulassen, die jede Einzeländerung protokollieren, Fehler je Datensatz ausweisen und Qualitätsregeln (z. B. Pflichtbegründungen) durchsetzen. +Ergebnis: Nachvollziehbare Massenänderungen mit Erfolgs-/Fehlerstatus je Objekt; fehlerhafte Datensätze blockieren nicht den Gesamtlauf. +Belege: + - [PRIMÄR] src\backend\Centron.BL\MassUpdate\MassUpdateBL.cs, StartReceiptPriceUpdate: je Item `item.IsExecuted`, `item.FailureMessage`, ReceiptLog-Eintrag `ReceiptLogKind.DataUpdater`; nur `receipt.State is ReceiptState.Active` wird geändert - Begründung: durchgesetzter kontrollierter Massenprozess mit Protokoll. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\ProjectPriceImport\ProjectPriceImportViewModel.cs, ErrorList-Einträge ("Zellinhalt ist nicht numerisch", "Kein Herstellercode gefunden") - Begründung: Fehlerausweis je Datensatz beim Import. +Prüfidee: Massenupdate über 10 Belege, davon 1 inaktiv: 9 werden geändert und geloggt, der inaktive erhält FailureMessage "Beleg ist nicht aktiv."; Template bleibt aktiv, bis alle Items ausgeführt sind. +Tracelinks: SyRS-1015, SyRS-1016 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Massenpflege ist im Systemhausgeschäft (viele Verträge/Preise) unverzichtbar. +Status: belegt +``` + +### StRS-1004: Lizenz- und Vertragslebenszyklus überwachen und abrechnen + +``` +ID: StRS-1004 +Titel: Lizenz- und Vertragslebenszyklus überwachen und abrechnen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertrieb (Renewals), Vertragsabrechnung, MSP-Einkauf +Vorbedingung: Verkaufte Lizenzen/Abos in Rechnungen bzw. laufende Verträge vorhanden; MSP-Lieferantenkonten eingerichtet +Fakt: PLM sammelt ProductLifecycleInformation aus Rechnungen (mit StartDate/EndDate) und erzeugt bei nahendem Ablauf Wiedervorlagen (ToDo) und Angebote; MspCollectorsBL importiert Lieferanten-Nutzungsabrechnungen (Veeam, Octopus, ArrowSphere) und gleicht sie positionsweise mit Kundenverträgen ab (Menge/Preis anpassen oder ignorieren, mit Historie). +Aussage: Das System soll den Lebenszyklus verkaufter Lizenzen und Abonnements überwachen (Ablaufdaten, Verlängerungsangebote, Erinnerungen) und eingekaufte MSP-Nutzungsmengen mit den abzurechnenden Kundenverträgen abgleichen, sodass Verlängerungen nicht verpasst und Verträge mengen- und preisrichtig abgerechnet werden. +Ergebnis: Wiedervorlagen/Angebote vor Lizenzablauf; Verträge, deren Mengen/Preise dem tatsächlichen Lieferantenverbrauch entsprechen; jede Abgleichsentscheidung historisiert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Warehousing\ArticleManagement\ProductFamilyBL.cs, ImportProductLifecycleInformations: `if (item.SourceType == (int)ProductLifecycleInformationSource.Invoice && item.StartDate >= DateTime.Now.AddDays(-plmSettings.DaysToTolerate)) toDoBL.HandlePLMToDoEntries(...)` - Begründung: durchgesetzte Lebenszyklus-Überwachung. + - [PRIMÄR] src\backend\Centron.BL\Statistics\MspCollectors\MspCollectorsBL.cs, UpdateMspContractItem: setzt je nach MspEvaluationDecision QuantityComplete/PurchaseBasePrice der Vertragsposition und speichert MspEvaluationHistory - Begründung: durchgesetzter Abrechnungsabgleich. +Prüfidee: Import einer Rechnung mit Lizenz-Enddatum in der Toleranzfrist erzeugt einen PLM-ToDo-Eintrag; eine MSP-Rechnungsposition mit abweichender Menge führt nach Entscheidung "ChangeQuantity" zur angepassten Vertragsposition plus Historieneintrag. +Tracelinks: SyRS-1017, SyRS-1018 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kern des MSP-/Abo-Geschäftsmodells der Zielkunden (Systemhäuser). +Status: belegt +``` + +## A11 — Plattform & Querschnitt: StRS + +### StRS-1101: Einheitliche, wartbare technische Plattform + +``` +ID: StRS-1101 +Titel: Einheitliche, wartbare technische Plattform +Ebene: StRS +Typ: nicht-funktional +Qualitätsmerkmal: Wartbarkeit +Akteur: Produktverantwortlicher / Entwicklungsteam c-entron +Vorbedingung: ERP-Suite wird über Jahrzehnte weiterentwickelt (Delphi-Altbestand, WinForms, WPF, Web). +Fakt: docs\getting-started\general-structure.md definiert eine verbindliche Schichtung UI → ViewModel → ILogic (BLLogic/WSLogic) → WebServiceBL → BL → Datenbank sowie das Result-Fehlermuster; .editorconfig erzwingt Namens- und Encoding-Konventionen (UTF-8 BOM). +Aussage: Das System soll auf einer einheitlichen, dokumentierten Schichtenarchitektur mit durchgängigen Codier-, Namens- und Datenbankkonventionen beruhen, damit alle Fachmodule gleichartig implementiert, getestet und gewartet werden können. +Ergebnis: Neue Module folgen demselben Aufbau (ILogic/BL/WS, Result); Abweichungen sind als Altlast erkennbar. +Belege: + - [KONTEXT] docs\getting-started\general-structure.md ("Every module MUST implement both data access methods", Schichtentabelle) - Begründung: dokumentiert die verbindliche Architektur- und Namenskonvention. + - [PRIMÄR] .editorconfig (root=true; [*.{cs,xaml}] charset = utf-8-bom; dotnet_naming_rule.private_or_internal_field...severity = warning) - Begründung: werkzeuggestützt durchgesetzte Wartbarkeitskonvention. +Prüfidee: Stichprobe von 10 Modulen: je ein I{X}Logic-, BL{X}Logic-, WS{X}Logic-Typ vorhanden; Build erzeugt Naming-Warnungen bei Konventionsverstoß. +Tracelinks: SyRS-1110, SyRS-1111, SyRS-1112 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Schichtung und Konventionsdisziplin sind für eine Web-/SaaS-Neuimplementierung direkt übertragbar (Technologie wechselt, Prinzip bleibt). +Status: belegt +``` + +### StRS-1102: Nachvollziehbarkeit von Änderungen und Systemverhalten + +``` +ID: StRS-1102 +Titel: Nachvollziehbarkeit von Änderungen und Systemverhalten +Ebene: StRS +Typ: nicht-funktional +Qualitätsmerkmal: Zuverlässigkeit (Nachvollziehbarkeit/Auditierbarkeit) +Akteur: Administrator / Support / Systemhaus-Anwender +Vorbedingung: Produktivbetrieb beim Kunden; Support muss Fehlverhalten und Datenänderungen rekonstruieren können. +Fakt: Die Plattform enthält vier getrennte Nachvollziehbarkeitsmechanismen: NLog-Dateilogging (nlog.config), feldbezogene Änderungshistorie (ChangeLog-Tabelle + NHibernate-Listener), Nutzungstelemetrie (TelemetryBL) und einen Live-LogViewer im Client. +Aussage: Das System soll Datenänderungen, Fehler und Nutzung so protokollieren, dass Support und Administration Vorgänge im Nachhinein rekonstruieren können, ohne den laufenden Betrieb zu stören. +Ergebnis: Änderungs-, Fehler- und Nutzungshistorie sind pro Objekt bzw. pro Arbeitsplatz abrufbar. +Belege: + - [PRIMÄR] src\backend\Centron.DAO\DAOFactory.cs, InitializeAsyncInternal (AppendListeners(ListenerType.PreUpdate, new ChangeTrackingEventListener(), ...)) - Begründung: Änderungsprotokollierung ist zentral in der Persistenzschicht verankert. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\nlog.config (csvTarget, minLevel WARN) - Begründung: konfigurierte Betriebsprotokollierung des Clients. +Prüfidee: Ein Feldwert eines protokollierten Objekts ändern und prüfen, dass ChangeLog-Eintrag, Logdatei und LogViewer den Vorgang zeigen. +Tracelinks: SyRS-1114, SyRS-1115, SyRS-1116 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Audit-/Betriebstransparenz ist im SaaS-Betrieb noch wichtiger (zentraler Betrieb, DSGVO-Nachweise). +Status: belegt +``` + +### StRS-1103: Schnelles Auffinden von Informationen und KI-Assistenz + +``` +ID: StRS-1103 +Titel: Schnelles Auffinden von Informationen und KI-Assistenz +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Sachbearbeiter (Helpdesk, Vertrieb) / Systemhaus-Anwender +Vorbedingung: Große Datenbestände (Tickets, Kunden) mit Freitextinhalten. +Fakt: Es existiert eine eigene datenbankgestützte Volltextsuche (IndexSearchBL mit deutschem Stemmer) über Tickets und Accounts sowie ein KI-Subsystem (Centron.BL\ArtificialIntelligence) mit Chat, Textbewertung, Angebots-Editor und mehreren Provider-Anbindungen. +Aussage: Das System soll Anwendern das schnelle Wiederfinden von Geschäftsobjekten über Freitextsuche ermöglichen und wiederkehrende Text-/Klassifikationsaufgaben durch konfigurierbare KI-Dienste unterstützen. +Ergebnis: Suchtreffer über alle indizierten Objektarten; KI-Antworten (Chat, Textbewertung, Ticket-Kategorisierung) auf Basis der vom Kunden konfigurierten Provider. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskSearchBL.cs:511 (new IndexSearchBL(this.Session).SearchIndexQueryable(filter.SearchText, CentronObjectKindNumeric.HelpdeskClass)) - Begründung: Volltextsuche ist produktiv in die Ticketsuche eingebunden. + - [SEKUNDÄR] src\backend\Centron.BL\ArtificialIntelligence\ApiClientFactory.cs (Provider-Switch OpenAI/Ionos/ClaudeCode/MistralAi/GoogleAiStudio/...) - Begründung: zeigt die Breite der KI-Assistenzfunktionen. +Prüfidee: Ticket mit markantem Begriff anlegen, Index aktualisieren, Suche nach Wortstamm liefert das Ticket; KI-Chat mit konfiguriertem Provider liefert Antwort. +Tracelinks: SyRS-1117, SyRS-1118 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Suche und KI-Assistenz sind strategische Funktionen; Implementierung (eigene Indextabellen) kann im Web-Stack durch Suchdienst ersetzt werden. +Status: belegt +``` + +### StRS-1104: Anpassbarer, deutschsprachiger Arbeitsplatz + +``` +ID: StRS-1104 +Titel: Anpassbarer, deutschsprachiger Arbeitsplatz +Ebene: StRS +Typ: nicht-funktional +Qualitätsmerkmal: Benutzbarkeit +Akteur: Endanwender / Administrator +Vorbedingung: Heterogene Anwenderrollen in deutschen Systemhäusern; unterschiedliche Arbeitsabläufe je Arbeitsplatz. +Fakt: Die Plattform bietet GUI-Profile (CentronUiProfiles, privat/global), zweisprachige Ressourcen (LocalizedStrings.resx deutsch, LocalizedStrings.en.resx englisch), eine zentrale Dateiablage im Client und frei konfigurierbare externe Tools mit Variablenersetzung; die Doku schreibt Deutsch als führende UI-Sprache vor. +Aussage: Das System soll dem Anwender eine deutschsprachige (optional englische), pro Benutzer und global anpassbare Arbeitsumgebung bieten, einschließlich dokumentenbezogener Dateiablage und Einbindung externer Programme. +Ergebnis: Anwender arbeiten mit persönlichen bzw. firmenweiten Oberflächenprofilen in ihrer Sprache und erreichen Dokumente und Fremdwerkzeuge aus dem ERP heraus. +Belege: + - [KONTEXT] docs\getting-started\general-structure.md, Abschnitt "German-First Language Policy" - Begründung: dokumentierte Sprachanforderung. + - [PRIMÄR] src\backend\Centron.BL\GUI\Profiles\UiProfileBL.cs, SaveProfile (Persistenz CentronUiProfile inkl. IsGlobal-Rechteprüfung) - Begründung: durchgesetzte Profilverwaltung. +Prüfidee: Sprache auf Englisch umstellen (Neustart), UI-Texte erscheinen englisch; privates GUI-Profil anlegen und nach Neuanmeldung wiederfinden. +Tracelinks: SyRS-1119, SyRS-1120, SyRS-1121, SyRS-1113 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Personalisierung und Deutsch-First sind Marktanforderungen; Registry-basierte Sprachpersistierung ist im Web durch Benutzerprofil zu ersetzen. +Status: belegt +``` + +## Cluster A12 — Administration, Konfiguration & Betrieb — StRS + +### StRS-1201: Verwaltung mehrerer Mandanten und Filialen + +``` +ID: StRS-1201 +Titel: Verwaltung mehrerer Mandanten und Filialen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator / Geschäftsleitung +Vorbedingung: ERP-System ist installiert; Benutzer besitzt Administrationsrechte +Fakt: Das WPF-Modul MandatorManagement verwaltet Mandanten (Firmenstammdaten inkl. bis zu 4 Bankverbindungen, Steuernummern, SEPA-Gläubiger-ID, 8 Logos) und je Mandant beliebig viele Filialen; die Tabelle Mandant enthält zusätzlich Belegnummernkreise (AngeNr, RechNr, Lieferscheinnummer ...). +Aussage: Das System soll die Verwaltung mehrerer Mandanten (rechtlich eigenständige Firmen mit eigenen Stammdaten, Bankverbindungen und Belegnummernkreisen) sowie deren Filialen innerhalb einer Installation ermöglichen, damit ein IT-Systemhaus mehrere Gesellschaften mit einem System abwickeln kann. +Ergebnis: Belege, Zahlungsläufe und Drucke verwenden die Stammdaten des jeweils zuständigen Mandanten bzw. der Filiale. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\Administration\MandatorManagement\MandatorManagementViewModel.cs (LoadMandatorsAsync, SaveMandatorAsync, NewBranch) - Begründung: implementiert Anlage/Pflege von Mandanten und Filialen inkl. Persistenz über IMandatorManagementLogic/IBranchLogic. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[Mandant] (Zeile 23808: Spalten Mandant, IBAN1..., AngeNr, RechNr, Lieferscheinnummer, Status) - Begründung: Datenmodell trägt Firmenstammdaten, Bankdaten und Nummernkreise je Mandant. + - [SEKUNDÄR] src\backend\Centron.BL\WebServices\Administration\Company\MandatorWebServiceBL.cs (CreateNumberGroups) - Begründung: je Mandant/Filiale werden eigene Nummernkreise erzeugt. +Prüfidee: Zweiten Mandanten anlegen, Filiale zuordnen; prüfen, dass Belege des zweiten Mandanten dessen Stammdaten/Nummernkreis verwenden. +Tracelinks: SyRS-1211 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kernanforderung für Mehrfirmenbetrieb, in einer SaaS-Lösung als Mandanten-/Organisationsmodell neu zu konzipieren. +Status: belegt +``` + +### StRS-1202: Zentrale Konfigurierbarkeit des Systems + +``` +ID: StRS-1202 +Titel: Zentrale Konfigurierbarkeit des Systems +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Benutzer besitzt das Administrationsrecht für Einstellungen +Fakt: Ein zentrales Einstellungsmodul (SettingsAppModuleController, Kategorie Administration) bündelt sämtliche Teil-Einstellungsseiten (PDF-Export, Eskalationen, Textbausteine, Zuschlagssätze, Benachrichtigungen, Dienste u. a.); Einstellungen werden serverseitig in den Tabellen Stammdat und ApplicationSettings gehalten. +Aussage: Das System soll Administratoren eine zentrale, nach Themen gegliederte Oberfläche bieten, über die alle fachlichen und technischen Systemeinstellungen gepflegt und persistiert werden. +Ergebnis: Geänderte Einstellungen wirken systemweit für alle Clients ohne Neuinstallation. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\Administration\Settings\SettingsAppModuleController.cs (ModuleName "Einstellungen", MainCategory = CentronModuleCategory.Administration, CreateModuleInstance sammelt ICentronAppModuleSettingController) - Begründung: zentrale Container-Oberfläche für alle Einstellungsseiten. + - [KONTEXT] docs\guides\development\settings-management.md - Begründung: beschreibt die verbindliche Architektur der Einstellungsverwaltung (Stammdat legacy, ApplicationSettings aktuell, Zugriff nur über Gruppen-Settings-Klassen). +Prüfidee: Einstellung (z. B. PDF-Export-Konformität) im Settings-Modul ändern; prüfen, dass ein zweiter Client den neuen Wert über die API erhält. +Tracelinks: SyRS-1212, SyRS-1213, SyRS-1215, SyRS-1218, SyRS-1219 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zentrale Settings-Verwaltung ist für eine Web-Neuimplementierung direkt zu übernehmen (eine Tabelle statt zwei, siehe SwRS-1236). +Status: belegt +``` + +### StRS-1203: Automatisierter und überwachbarer Systembetrieb + +``` +ID: StRS-1203 +Titel: Automatisierter und überwachbarer Systembetrieb +Ebene: StRS +Typ: nicht-funktional +Qualitätsmerkmal: Zuverlässigkeit +Akteur: Systembetreiber / Administrator +Vorbedingung: Webservice-Host (Container, Konsole oder Windows-Dienst) läuft +Fakt: Der Host Centron.Host startet ca. 35 Hintergrunddienste (HostedServices), die über die DB-Tabelle BackgroundServices (IsEnabled, StartTime, LastRunTime) einzeln aktivierbar und überwachbar sind; Fehler werden geloggt und führen zu exponentiellem Backoff statt Dienstabbruch. +Aussage: Das System soll wiederkehrende Aufgaben (Datenqualität, Eskalationen, Benachrichtigungen, Indizes, Bereinigungen) automatisiert im Hintergrund ausführen und dem Betreiber die Steuerung und Laufzeitüberwachung jedes Dienstes ermöglichen. +Ergebnis: Wartungs- und Automatisierungsaufgaben laufen ohne Benutzereingriff; Ausfälle einzelner Aufgaben beeinträchtigen weder andere Aufgaben noch den Host. +Belege: + - [PRIMÄR] src\webservice\Centron.Host\AspNetCore\HostedServices\ManagedBackgroundService.cs (ExecuteAsync: GetIsEnabledCached, UpdateStartTime/UpdateLastRunTime, GetDelayWithBackoff) - Begründung: durchgesetzte zentrale Steuerung, Protokollierung und Fehlerrobustheit aller Hintergrunddienste. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[BackgroundServices] (Zeile 31733: ServiceName, IsEnabled, LastRunTime, StartTime) - Begründung: Datenmodell für Aktivierung und Überwachung. + - [KONTEXT] docs\Background Service\DataQualityService.md - Begründung: dokumentiert Zweck und Regeln der Hintergrundverarbeitung. +Prüfidee: Einen Dienst per IsEnabled=0 deaktivieren; prüfen, dass er nicht mehr ausgeführt wird und LastRunTime unverändert bleibt; DB-Ausfall simulieren und Backoff-Verhalten im Log prüfen. +Tracelinks: SyRS-1214, SyRS-1217 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Muster (DB-gesteuerte Job-Aktivierung, Laufzeit-Tracking) ist für eine SaaS-Architektur als Job-Scheduler-Anforderung zu übernehmen. +Status: belegt +``` + +### StRS-1204: Konforme und beweiskräftige PDF-Dokumentenausgabe + +``` +ID: StRS-1204 +Titel: Konforme und beweiskräftige PDF-Dokumentenausgabe +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator / Empfänger von Belegen (Kunde, Behörde) +Vorbedingung: Zertifikat (PFX) und ggf. Zeitstempeldienst sind konfiguriert +Fakt: Das System bietet konfigurierbare PDF-Konformitätsstufen (PDF/A-1a bis PDF/X-4) für den Export und eine serverseitige digitale Signierung von PDF-Dokumenten mit PKCS#7/SHA256 und optionalem TSA-Zeitstempel. +Aussage: Das System soll ausgehende PDF-Dokumente in archivierungs- und austauschkonformen Formaten erzeugen und auf Wunsch digital signieren können, damit Belege revisionssicher und beweiskräftig zugestellt werden. +Ergebnis: Erzeugte PDFs entsprechen der konfigurierten Norm und tragen bei aktivierter Signierung eine prüfbare digitale Signatur. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Security\PdfSigningBL.cs (SignPdfDocument: Pkcs7Signer mit HashAlgorithmType.SHA256, TsaClient, PdfSignatureBuilder.ApplicationName = "c-entron.NET") - Begründung: durchgesetzter Signaturvorgang. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\Administration\PdfExport\PdfExportSettingsViewModel.cs (InitializeDropdownLists: "PDF/A-1a" ... "Pdf/X-4", RGB/CMYK) - Begründung: konfigurierbare Konformitätsstufen im Admin-UI. +Prüfidee: PDF mit konfiguriertem Zertifikat signieren; Signatur und Zeitstempel in einem PDF-Validator prüfen; Export mit PDF/A-3b erzeugen und gegen veraPDF validieren. +Tracelinks: SyRS-1216 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - gesetzliche/vertragliche Anforderungen (E-Rechnung, Archivierung) bestehen fort. +Status: belegt +``` diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/SwRS.md b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/SwRS.md new file mode 100644 index 00000000..a9a789ce --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/SwRS.md @@ -0,0 +1,5552 @@ +# Software Requirements Specification (SwRS) + +**System:** c-entron ERP-Suite — Reverse Requirements Engineering aus der Codebasis +**Norm:** ISO/IEC/IEEE 29148:2018 | **Datum:** 2026-08-27 + +Softwaresicht: Komponenten, Datenmodelle und software-interne Regeln. Jede Anforderung folgt dem Blockformat des Laufs (Fakt = belegte Beobachtung, Aussage = fachliche Interpretation). Anforderungen mit `Status: HYPOTHESE` sind zusätzlich in `Hypothesen.md` gelistet. Die Kapitel entsprechen den Analyse-Clustern A1–A12 (siehe `Analysebericht.md`). + +## A1 — Sicherheit, Identität, Berechtigungen: Software-Anforderungen (SwRS) + +### SwRS-101: Benutzerrechtsprüfung über Gruppenmitgliedschaft mit Session-Cache + +``` +ID: SwRS-101 +Titel: Benutzerrechtsprüfung über Gruppenmitgliedschaft mit Session-Cache +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: AppRightsBL (Centron.BL) +Vorbedingung: Benutzer (AppUser) existiert; Rechte sind Gruppen zugeordnet. +Fakt: HasUserRight(appUserI3D, rightID) lädt alle Recht-IDs des Benutzers per SQL "SELECT st.Recht AS ID FROM dbo.Sichtrus st INNER JOIN dbo.Sichmemb sm ON sm.Gruppe = st.Gruppe WHERE sm.Benutzer = :UserI3D", cached das Ergebnis pro Benutzer im Session-Cache ("AllRightsFromAppUser{appUserI3D}") und prüft per Contains(rightID); HasUserRightWithDefaultMessage liefert bei Fehlen die Meldung "Benutzer hat nicht die passenden Rechte.". +Aussage: Das System soll ein Benutzerrecht als vorhanden werten, genau wenn mindestens eine Gruppe des Benutzers das Recht besitzt, und die Rechtemenge pro Sitzung zwischenspeichern. +Ergebnis: Rechteentscheidung als boolescher Wert; einheitliche Fehlermeldung bei fehlendem Recht. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Rights\AppRightsBL.cs, HasUserRight/GetAllAppRightsFromUser (SQL Sichtrus⋈Sichmemb) und HasUserRightWithDefaultMessage - Begründung: exakte durchsetzende Prüfbedingung. + - [SEKUNDÄR] src\backend\Centron.BL\Administration\Rights\UserRightsExt.cs, Erweiterungsmethode AppUser.HasUserRight(...) (Delegation an AppRightsBL; catch → false) - Begründung: Standard-Aufrufmuster in der gesamten BL. +Prüfidee: Benutzer in Gruppe mit Recht 10310 aufnehmen → HasUserRight(user,10310) == true; aus Gruppe entfernen (neue Session) → false. Cache-Verhalten: Rechteänderung wirkt erst in neuer Session. +Tracelinks: SyRS-101 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kernmechanismus; Cache-Invalidierung ist im Zielsystem explizit zu spezifizieren. +Status: belegt +``` + +### SwRS-102: Rechte-Datenmodell und zentrale Rechtekonstanten + +``` +ID: SwRS-102 +Titel: Rechte-Datenmodell und zentrale Rechtekonstanten +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Datenbank, Entwickler (Skript-Mechanismus) +Vorbedingung: — +Fakt: Rechte sind in dbo.Sichrech (I3D, Text, OwnerRecht als Hierarchie-Elternrecht, NumChildren, Beschreibung, Obsolete) definiert; Gruppen in dbo.Sichgrup; Gruppenmitgliedschaft in dbo.Sichmemb (Gruppe, Benutzer); Recht-zu-Gruppe in dbo.Sichtrus (Gruppe, Recht). Recht-IDs sind im Code als Konstanten in UserRightsConst hinterlegt (neue .NET-Rechte ab 20800000, "NEXT ID" wird in der Datei gepflegt); neue Rechte werden per Migrationsskript ScriptHelpers.AddRightIfNotExists in Sichrech angelegt. +Aussage: Das System soll Rechte als hierarchisch strukturierte Stammdaten führen, jede Rechteprüfung ausschließlich über zentrale, symbolische Rechtekonstanten referenzieren und neue Rechte versioniert per Migration anlegen. +Ergebnis: Konsistente Rechte-IDs zwischen Datenbank und Code; nachvollziehbare Rechte-Historie über Skripte. +Belege: + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE dbo.Sichrech / dbo.Sichgrup / dbo.Sichmemb / dbo.Sichtrus (Zeilen ~51189–51280) - Begründung: Datenmodell mit PKs und Spalten OwnerRecht/NumChildren (Hierarchie). + - [PRIMÄR] src\webservice\Centron.WebServices.Core\EntitiesWrongPlace\Administration\Rights\UserRightsConst.cs, Klasse UserRightsConst (Kommentar "NEW .NET MODULE RIGHTS START AT 20800000 / NEXT ID: 20800174") - Begründung: zentrale Konstantenverwaltung. + - [KONTEXT] docs\guides\development\add-a-new-right.md (ScriptHelpers.AddRightIfNotExists, Sichrech-Spaltenbeschreibung) - Begründung: dokumentierter Anlageprozess. +Prüfidee: Für ein neues Recht prüfen: Konstante in UserRightsConst, Migrations-Skript, Sichrech-Eintrag mit OwnerRecht und Beschreibung vorhanden und ID-konsistent. +Tracelinks: SyRS-102, SyRS-101 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Hierarchie und symbolische Konstanten übernehmen; Delphi-Altspalten (FormName/FormCont) sind veraltet. +Status: belegt +``` + +### SwRS-103: Rechtegruppenverwaltung mit Admin-Gruppen-Schutz und Filialbeschränkung + +``` +ID: SwRS-103 +Titel: Rechtegruppenverwaltung mit Admin-Gruppen-Schutz und Filialbeschränkung +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: AppRightsBL, Modul Rechteverwaltung (WPF) +Vorbedingung: Angemeldeter Benutzer mit bzw. ohne UserRightsManagement-Rechte. +Fakt: SaveRightGroup/CopyRightGroup verlangen UserRightsConst.Administration.UserRightsManagement.ID; das restriktive Recht MANAGE_RIGHTS_ONLY_OWN_BRANCH beschränkt Anlage/Kopie/Löschung auf Gruppen der eigenen Filiale (Vergleich user.Employee.BranchI3D != group.BranchI3D); DeleteRightGroup verweigert das Löschen der Administratorengruppe ("if (group.I3D == 6 || group.Name.Equals(\"Administratoren\", ...)) return Result.AsError(\"Die Adminstratoren Gruppe darf nicht gelöscht werden\")"); an der Admin-Gruppe sind nur die per GetAssignableAdminRightI3Ds() definierten Rechte veränderbar; Admin-Erkennung erfolgt über Gruppennamen "Administratoren" (UserRightsExt.IsAdmin). +Aussage: Das System soll die Verwaltung von Rechtegruppen auf Inhaber des Rechteverwaltungs-Rechts beschränken, filialgebundene Administratoren auf Gruppen der eigenen Filiale begrenzen und die Administratorengruppe gegen Löschung und unzulässige Rechteänderungen schützen. +Ergebnis: Unberechtigte oder filialfremde Gruppenoperationen und das Löschen der Admin-Gruppe werden mit Fehlermeldung abgelehnt. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Rights\AppRightsBL.cs, SaveRightGroup(...), DeleteRightGroup(...), CopyRightGroup(...) (Zeilen ~348–460) mit den zitierten Prüfungen - Begründung: durchsetzende Bedingungen inkl. Admin-Gruppen-Schutz. + - [PRIMÄR] src\backend\Centron.BL\Administration\Rights\AppRightsBL.cs, AssignGroupToRight(...) mit GetAssignableAdminRightI3Ds()-Whitelist für die Admin-Gruppe - Begründung: Schutz des Admin-Rechtebestands. + - [SEKUNDÄR] src\backend\Centron.BL\Administration\Rights\UserRightsExt.cs, IsAdmin(...) (Gruppenname == UserRightsConst.ADMIN_ACCOUNT "Administratoren") - Begründung: Admin-Sonderrolle über Gruppennamen. +Prüfidee: Löschversuch der Gruppe "Administratoren" (Erwartung: Fehlertext); Benutzer mit MANAGE_RIGHTS_ONLY_OWN_BRANCH legt Gruppe für fremde Filiale an (Erwartung: Fehler). +Tracelinks: SyRS-102 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - Identifikation der Admin-Gruppe über festen Namen/I3D 6 ist fragil; fachliche Regel (geschützte Systemrolle) übernehmen, technisch über stabiles Kennzeichen neu umsetzen. +Status: belegt +``` + +### SwRS-104: Protokollierung aller Rechteänderungen (AppRightLog) + +``` +ID: SwRS-104 +Titel: Protokollierung aller Rechteänderungen (AppRightLog) +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: AppRightsBL, RightsLogViewModel (WPF) +Vorbedingung: Rechteänderung wird durch berechtigten Benutzer ausgeführt. +Fakt: Rechte-/Gruppenoperationen schreiben Protokolleinträge: AddRightToRightGroup → WriteAddRightToGroupLog ("Recht \"X\" an die Gruppe \"Y\" vergeben"), analog RemoveRightFromRightGroup, AddUserToRightGroup, RemoveUserFromRightGroup, DeleteRightGroup, CopyRightGroup, SaveRightGroup (Neuanlage); die Einträge sind als AppRightLog-Entitäten gespeichert und über GetAllAppRightLogs() abrufbar (Anzeige im Rechteverwaltungs-Modul, RightsLogViewModel.cs). +Aussage: Das System soll jede Änderung an Rechtegruppen (Rechtevergabe/-entzug, Benutzerzuordnung, Gruppenanlage/-kopie/-löschung) mit Aktionsart, betroffenem Objekt, Beschreibung und ausführendem Benutzer protokollieren und zur Anzeige bereitstellen. +Ergebnis: Lückenloses, einsehbares Änderungsprotokoll der Rechteverwaltung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Rights\AppRightsBL.cs, WriteAddRightToGroupLog(...) → WriteBaseLog(AppRightLogKind.AddRightToGroup, objectText, description, appUser, flushChanges) sowie die Aufrufe in AddRightToRightGroup/RemoveRightFromRightGroup/... (Zeilen 187, 204, 226, 246, 370, 401, 459) - Begründung: durchsetzende Protokollschreibung bei jeder Änderung. + - [SEKUNDÄR] src\backend\Centron.Entities\Entities\Administration\AppRightLog.cs und src\centron\Centron.WPF.UI\Modules\Administration\RightsManagement\RightsLogViewModel.cs - Begründung: Entität und Anzeige des Protokolls. +Prüfidee: Recht an Gruppe vergeben und wieder entziehen; Erwartung: zwei AppRightLog-Einträge mit korrekter Beschreibung, Benutzer und Zeitstempel. +Tracelinks: SyRS-102 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Audit-Trail für Berechtigungsänderungen ist compliance-relevant. +Status: belegt +``` + +### SwRS-105: REST-Autorisierung über deklarative Rechte-Attribute (401/403) + +``` +ID: SwRS-105 +Titel: REST-Autorisierung über deklarative Rechte-Attribute (401/403) +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Centron.Controllers (ASP.NET Core), API-Client +Vorbedingung: HTTP-Request an einen mit Autorisierungs-Attribut versehenen Endpunkt. +Fakt: AuthorizeUserRightAttribute (sowie AuthorizeAnyUserRightAttribute/AuthorizeAllUserRightsAttribute) kapseln einen IAuthorizationFilter: ohne authentifizierten Benutzer (GetCurrent() == null) wird UnauthorizedResult (401) gesetzt, mit Benutzer ohne Recht ForbidResult (403); der Benutzer wird über das Token (ClaimTypes.NameIdentifier) via UserWebServiceBL.GetLoggedInUserByToken aufgelöst (unterstützt ConnectionTickets und Access Tokens). +Aussage: Das System soll Web-API-Endpunkte deklarativ mit erforderlichen Benutzerrechten annotieren und Anfragen ohne Authentifizierung mit 401, ohne ausreichendes Recht mit 403 beantworten. +Ergebnis: Standardisierte, pro Endpunkt deklarierte Autorisierung mit korrekten HTTP-Statuscodes. +Belege: + - [PRIMÄR] src\webservice\Centron.Controllers\Authorization\AuthorizeUserRightAttribute.cs, UserRightAuthorizationFilter.OnAuthorization: "if (currentUser == null) { context.Result = new UnauthorizedResult(); return; } if (!_requiredRightId.HasValue || !currentUser.HasUserRight(_requiredRightId.Value)) context.Result = new ForbidResult();" - Begründung: exakte durchsetzende Bedingung mit Statuscodes. + - [PRIMÄR] src\webservice\Centron.Controllers\Utils\ApiUserUtils.cs, GetCurrent(...) (Token → GetLoggedInUserByToken) - Begründung: Benutzerauflösung als Basis der Prüfung. + - [KONTEXT] src\webservice\Centron.Controllers\Authorization\README.md - Begründung: dokumentierte Nutzungsmuster (Any/All-Varianten). +Prüfidee: Annotierten Endpunkt ohne Token (Erwartung 401), mit Token ohne Recht (403), mit Recht (200) aufrufen. +Tracelinks: SyRS-101 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - deklaratives Autorisierungsmuster ist direkt SaaS-tauglich. +Status: belegt +``` + +### SwRS-106: JWT-/OpenID-Connect-Login mit Subject-basierter Benutzerzuordnung + +``` +ID: SwRS-106 +Titel: JWT-/OpenID-Connect-Login mit Subject-basierter Benutzerzuordnung +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: JwtAuthController, OpenIdConnectAuthenticator, externer Identity Provider +Vorbedingung: JWT-Authentifizierung ist lizenziert (LicenseGuids.OpenIDConnectAuthentication) und aktiviert (JwtSettings.Enabled); Client sendet gültiges Bearer-JWT. +Fakt: POST /jwt/login ([Authorize(JwtBearer)]) prüft Webservice-Token und Application-GUID, verlangt eine authentifizierte ClaimsIdentity und erzeugt über AuthenticatorFactory/OpenIdConnectAuthenticator ein Ticket; der Benutzer wird über den Subject-Claim gesucht ("Session.GetGenericDAO().GetEntity(where => where.OpenIdConnectSubjectIdentifier == Auth.SubjectIdentifier)") und mit ValidateAppUser geprüft; ohne Lizenz oder Subject-Claim wird der Login abgelehnt; POST /jwt/connect_accounts verknüpft nach erneuter JWT-Prüfung das OIDC-Konto mit dem per Ticket angemeldeten AppUser. +Aussage: Das System soll die Anmeldung per OpenID-Connect-JWT unterstützen, den lokalen Benutzer eindeutig über den gespeicherten Subject Identifier zuordnen, bei fehlender Lizenz/Konfiguration ablehnen und eine Selbst-Verknüpfung von OIDC-Konto und ERP-Benutzer anbieten. +Ergebnis: Erfolgreicher OIDC-Login liefert ein c-entron-Ticket; unbekannte Subjects oder deaktivierte Konten werden abgewiesen. +Belege: + - [PRIMÄR] src\webservice\Centron.Controllers\Controllers\Unversioned\JwtAuthController.cs, LoginWithBearer(...) / ConnectAccounts(...) (Attribut [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)], Ticket nur bei Success) - Begründung: durchsetzender API-Fluss. + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\Auth\OpenIdConnectAuthenticator.cs, AuthenticateInternal(): Lizenzprüfung, Subject-Prüfung, AppUser-Lookup über OpenIdConnectSubjectIdentifier, ValidateAppUser - Begründung: exakte Zuordnungs- und Ablehnungsbedingungen. +Prüfidee: Login mit JWT eines nicht verknüpften Subjects (Erwartung: Fehler); nach connect_accounts mit gültigem Ticket: Login liefert Ticket. +Tracelinks: SyRS-104, SyRS-103 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - SSO-Anbindung ist zentraler Baustein der SaaS-Architektur. +Status: belegt +``` + +### SwRS-107: Basic-Authentifizierung über SHA1-Passworthash (unsalted) + +``` +ID: SwRS-107 +Titel: Basic-Authentifizierung über SHA1-Passworthash (unsalted) +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: BasicAuthenticator, Tabelle Sichbenu +Vorbedingung: Benutzername und Passwort werden übergeben; Systemmethode erlaubt Basic-Login. +Fakt: Das übergebene Passwort wird mit SHA1 über die Windows-1252-Byte-Repräsentation gehasht (SHA1Decoder.GetDecodedSHA1String, Hex lowercase) und direkt mit AppUser.Password (Spalte Sichbenu.Kennwort, varchar(60)) verglichen; im Code steht der Kommentar "// TODO the password should be salted!!!"; leere Credentials werden vorab abgewiesen. +Aussage: Das System soll Benutzerpasswörter niemals im Klartext speichern und die Anmeldung über den Vergleich eines Passworthashes durchführen. (Ist-Verfahren: ungesalzenes SHA1 über Codepage-1252-Bytes.) +Ergebnis: Anmeldung nur bei übereinstimmendem Hash; kein Klartextpasswort in der Datenbank. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\Auth\BasicAuthenticator.cs, AuthenticateInternal(): "var decodedPassword = SHA1Decoder.GetDecodedSHA1String(Auth.Password...); var user = Session.GetGenericDAO().GetEntity(where => where.Name == Auth.UserName && where.Password == decodedPassword);" inkl. TODO-Kommentar - Begründung: durchsetzende Vergleichslogik. + - [PRIMÄR] src\backend\Centron.Common\TextCoding\SHA1Decoder.cs, GetDecodedSHA1String (Encoding.GetEncoding(1252), SHA1.Create, Hex lowercase) - Begründung: exaktes Hash-Verfahren. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, Sichbenu.Kennwort varchar(60) - Begründung: Speicherformat (SHA1-Hex = 40 Zeichen passt in 60). +Prüfidee: Datenbankfeld Kennwort eines Testbenutzers inspizieren (Erwartung: 40-stelliger Hex-Hash); Login mit korrektem/falschem Passwort testen. +Tracelinks: SyRS-104 +Konsolidierung: nein +Übernahmewürdigkeit: veraltet - ungesalzenes SHA1 ist kryptografisch gebrochen; im Zielsystem durch moderne KDF (z. B. Argon2/bcrypt) ersetzen; fachliche Regel (Hash statt Klartext) bleibt. +Status: belegt +``` + +### SwRS-108: Abweisung deaktivierter Konten mit Zeitfenstern und Mitarbeiterstatus + +``` +ID: SwRS-108 +Titel: Abweisung deaktivierter Konten mit Zeitfenstern und Mitarbeiterstatus +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Authenticator.ValidateAppUser (alle Login-Verfahren) +Vorbedingung: Benutzer wurde per Credentials/AD/OIDC gefunden. +Fakt: ValidateAppUser lehnt ab, wenn (a) kein Benutzer gefunden wurde ("Anmeldung ist fehlgeschlagen..."), (b) IsAccountDisabled gesetzt ist, (c) DateTime.Today im Intervall AccountDisabledFromDate/AccountDisabledToDate liegt (beide Grenzen einzeln oder kombiniert), oder (d) der verknüpfte Mitarbeiter laut EmployeeBL.IsActiveEmployeeCompact (Ein-/Austrittsdatum) nicht aktiv ist; in den Fällen b–d lautet die Meldung "Mitarbeiterkonto wurde deaktiviert". +Aussage: Das System soll bei jeder Anmeldung prüfen, ob das Konto manuell deaktiviert ist, in einem Deaktivierungszeitraum liegt oder der zugehörige Mitarbeiter ausgeschieden ist, und in diesen Fällen die Anmeldung mit einer nicht benutzerdifferenzierenden Fehlermeldung ablehnen. +Ergebnis: Kein Sitzungsaufbau für deaktivierte/ausgeschiedene Konten. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\Auth\Authenticator.cs, ValidateAppUser(...) (Zeilen 157–218, Datumslogik fromHasValue/toHasValue, IsActiveEmployeeCompact) - Begründung: vollständige durchsetzende Bedingungskette. +Prüfidee: Vier Testfälle (unbekannter Benutzer, Checkbox-Deaktivierung, laufender Zeitraum, ausgetretener Mitarbeiter) — Erwartung: jeweils Ablehnung; Randfall: Zeitraum endet gestern → Anmeldung möglich. +Tracelinks: SyRS-107 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - inklusive der Tagesgranularität (DateTime.Today) als fachliche Festlegung. +Status: belegt +``` + +### SwRS-109: Ticket-Lebensdauer, Wiederverwendung und Verlängerungsoptimierung + +``` +ID: SwRS-109 +Titel: Ticket-Lebensdauer, Wiederverwendung und Verlängerungsoptimierung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: TicketBL, TicketRepository +Vorbedingung: Erfolgreiche Authentifizierung bzw. API-Aufruf mit bestehendem Ticket. +Fakt: Ticketablauf je ApplicationKind.ExpirationKind: Default 30 min, MonitoringConnector 5 min, OneDay 1440 min, FromSettings aus AppSettingsConst.TicketReleaseTime (mindestens 30 min via Math.Max); GetExistingTicket verlängert das Ablaufdatum nur, wenn die Verlängerung ≥ 5 Minuten Unterschied ergibt (dokumentierte Optimierung); die Ticket-ID wird mit Salt erzeugt (CryptoUtils.CreateSalt(32) + SHA1-basiertes CreatePasswordHash über die Geräte-ID); abgelaufene Tickets löscht DeleteExpiredTickets. +Aussage: Das System soll Sitzungs-Tickets mit anwendungsartabhängiger Lebensdauer ausstellen, pro Benutzer/Gerät wiederverwenden, bei Nutzung gleitend verlängern (mit Mindestabstand zur Reduktion von Schreiblast) und abgelaufene Tickets entfernen. +Ergebnis: Kontrollierte Sitzungsdauer; keine unbegrenzt gültigen Tickets. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\TicketBL.cs, GetExpireDate(...) (switch über ExpirationKind mit den Konstanten 30/5/1440), RefreshTicketExpireDate(...) ("if ((newExpireDate - ticket.ExpiryDate).TotalMinutes < 5) return Result.AsSuccess();"), GetTicketSalt(...) - Begründung: exakte Ablauf- und Verlängerungsregeln. +Prüfidee: Tickets für Default- und OneDay-Anwendung erzeugen und ExpiryDate vergleichen (30 min vs. 24 h); zwei API-Aufrufe im Abstand < 5 min → ExpiryDate unverändert. +Tracelinks: SyRS-103 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Timeout-Werte als konfigurierbare Fachparameter übernehmen; Implementierung im Zielsystem über Standard-Session-/Token-Mechanik. +Status: belegt +``` + +### SwRS-110: Passwortänderung mit Ist-Passwort-Prüfung und Mindestlänge + +``` +ID: SwRS-110 +Titel: Passwortänderung mit Ist-Passwort-Prüfung und Mindestlänge +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: UsersBL, angemeldeter Benutzer (AppUser oder WebAccount) +Vorbedingung: Benutzer ist angemeldet und ruft die Passwortänderung auf. +Fakt: ChangeOwnPassword verlangt das aktuelle Passwort und vergleicht dessen SHA1-Hash mit dem gespeicherten Wert (für WebAccount wie AppUser); UpdatePassword prüft per IsValidAppUserPassword die benutzerindividuelle Mindestlänge (AppUser.PasswordMinLength, Spalte Sichbenu.KennLaenMin; Fehler "Das Passwort ist zu kurz"), weist unveränderte Passwörter mit Warnung ab und setzt LastPasswordChangedDate (Spalte LetzKennAend). +Aussage: Das System soll die eigene Passwortänderung nur nach erfolgreicher Verifikation des aktuellen Passworts zulassen, eine konfigurierbare Mindestpasswortlänge pro Benutzer erzwingen und den Zeitpunkt der letzten Änderung speichern. +Ergebnis: Neues Passwort ist nur mit korrektem Alt-Passwort und ausreichender Länge setzbar; Änderungsdatum dokumentiert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\UsersBL.cs, ChangeOwnPassword(...) (Hash-Vergleich Zeilen 65–93), UpdatePassword(...) (Zeilen 101–115: IsValidAppUserPassword, LastPasswordChangedDate = DateTime.Now), IsValidAppUserPassword(...) ("newPassword?.Length < appUser.PasswordMinLength && appUser.PasswordMinLength > 0") - Begründung: vollständige durchsetzende Regeln. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, Sichbenu-Spalten KennLaenMin, KennAendNachTagen, LetzKennAend - Begründung: Datenmodell inkl. Hinweis auf Passwort-Ablaufregel (KennAendNachTagen). +Prüfidee: Passwortänderung mit falschem Alt-Passwort (Erwartung: Fehler), mit zu kurzem neuen Passwort (Fehler "zu kurz"), mit identischem Passwort (Warnung), gültiger Fall (LetzKennAend aktualisiert). +Tracelinks: SyRS-104 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Regeln übernehmen; ob KennAendNachTagen (Passwort-Ablauf) noch durchgesetzt wird, wäre gesondert zu prüfen. +Status: belegt +``` + +### SwRS-111: Web-Account-Login mit Aktivitätskette und Login-Metadaten + +``` +ID: SwRS-111 +Titel: Web-Account-Login mit Aktivitätskette und Login-Metadaten +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: WebAccountBL, WebAccountAuthenticator +Vorbedingung: Kundenportal-Login mit Benutzername/Passwort (WebLoginType.Customer). +Fakt: LoginWithWebAccount sucht den Account mit Status == 1, case-insensitivem Benutzernamen und SHA1-Passworthash; anschließend wird die Verknüpfungskette geprüft: aktive Kontaktperson (State == 1) mit aktiver Adresse und aktivem, nicht gesperrtem Kunden (IsCustomerActiveAndNotLocked) bzw. für Account-Kontakte IsAccountActiveAndNotLocked; bei Erfolg werden LastLoginIP und LastLoginDate persistiert; der WebAccountAuthenticator bindet die Sitzung an einen technischen AppUser (GetAppUserForWebaccounts) und überspringt die Anwendungs-Rechteprüfung (ValidateRights → Success); 2FA wird auch für Web-Accounts unterstützt (WebAccounts.UseTwoFactorAuthentication). +Aussage: Das System soll Portal-Anmeldungen nur für aktive Web-Accounts zulassen, deren gesamte Verknüpfungskette (Kontaktperson, Adresse, Kunde/Account) aktiv und nicht gesperrt ist, und je Anmeldung IP-Adresse und Zeitpunkt speichern. +Ergebnis: Portalzugang folgt dem Kundenstatus; Login-Metadaten sind nachvollziehbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\WebAccountBL.cs, LoginWithWebAccount(...) (Zeilen 54–105: Statusfilter, Kettenprüfungen, LastLoginIP/LastLoginDate) - Begründung: vollständige durchsetzende Loginlogik. + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\Auth\WebAccountAuthenticator.cs, AuthenticateInternal(...) und ValidateRights(...)-Override - Begründung: Einbettung in das Ticket-/2FA-System. +Prüfidee: Kunden sperren und Portal-Login testen (Erwartung: Ablehnung); erfolgreichen Login prüfen: LastLoginIP/LastLoginDate aktualisiert. +Tracelinks: SyRS-106 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Statuskette ist fachlich korrekt; SHA1-Hashing wie SwRS-107 abzulösen. +Status: belegt +``` + +### SwRS-112: Entscheidungslogik für erforderliche Zwei-Faktor-Bestätigung + +``` +ID: SwRS-112 +Titel: Entscheidungslogik für erforderliche Zwei-Faktor-Bestätigung +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: TwoFactorAuthBL +Vorbedingung: Login-Versuch eines Benutzers; TwoFactorAuthEnabled in der Webservice-Konfiguration. +Fakt: HasToValidateTwoFactor liefert false bei deaktivierter Benutzer-2FA; sonst true, wenn 2FA erzwungen wird, die Gültigkeitsdauer (user.TwoFactorValidDurationInDays ?? WebServiceConfig-Default) ≤ 0 ist, noch nie bestätigt wurde oder lastLogin.Date + Dauer < jetzt (Tagesgranularität, dokumentiert im Kommentar); erfolgreiche Bestätigungen werden je Benutzerart (AppUser/WebAccount), Anwendung, Maschinenname und IP-Adresse als TwoFactorAuthLastLogin gespeichert (RememberLogin). +Aussage: Das System soll die Notwendigkeit einer erneuten Zwei-Faktor-Bestätigung pro Benutzer, Anwendung, Gerät und IP-Adresse anhand einer konfigurierbaren Gültigkeitsdauer in Tagen (0 = immer) bestimmen und erfolgreiche Bestätigungen entsprechend vermerken. +Ergebnis: 2FA wird nur bei Bedarf verlangt; Gerätewechsel oder IP-Wechsel erfordert erneute Bestätigung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\TwoFactor\TwoFactorAuthBL.cs, HasToValidateTwoFactor(...) (Zeilen 82–135, u. a. "var twoFactorAuthIsValidUntil = lastTwoFactorAuth.Value.Date.AddDays(twoFactorIsValidDuration)") und RememberLogin/GetLastLogin (Schlüssel UserKind/UserI3D/ApplicationName/MachineName/IpAddress) - Begründung: exakte Entscheidungs- und Speicherlogik. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, Sichbenu/WebAccounts: Spalten UseTwoFactorAuthentication, TwoFactorValidDurationInDays, LastTwoFactorValidatedAt - Begründung: Datenmodell der 2FA-Einstellungen. +Prüfidee: Dauer = 1 Tag: Login am Tag 1 (2FA nötig), zweiter Login am selben Tag (nicht nötig), Login am Folgetag (wieder nötig); Wechsel der IP → erneut nötig. +Tracelinks: SyRS-105 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - gerätebezogenes 2FA-Gedächtnis ist gute UX; IP-Bindung im SaaS-Kontext überdenken (NAT/Mobilfunk). +Status: belegt +``` + +### SwRS-113: E-Mail-Link-Zweitfaktor mit Einmalcode und Bestätigungsendpunkt + +``` +ID: SwRS-113 +Titel: E-Mail-Link-Zweitfaktor mit Einmalcode und Bestätigungsendpunkt +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: EmailTwoFactorValidator, TwoFactorAuthController, Mail-Server, Benutzer +Vorbedingung: TwoFactorAuthType = EmailLink; Benutzer hat eine hinterlegte E-Mail-Adresse. +Fakt: Beim Login wird ein Einmalcode (Guid.NewGuid "N") erzeugt, in einem In-Memory-ConcurrentDictionary gehalten und als Link "/2fa/validate?code=" per E-Mail versendet; der Login-Thread wartet auf die Bestätigung und schlägt bei Timeout mit MessageCode Canceled fehl; GET /2fa/validate ([AllowAnonymous]) löst über TrySetCodeAsValidated den wartenden Login aus und entfernt den Code (Einmalverwendung); bei deaktivierter EmailLink-2FA antwortet der Endpunkt mit einem Hinweistext. +Aussage: Das System soll als zweiten Faktor einen per E-Mail zugestellten Einmal-Bestätigungslink unterstützen, dessen Code nur einmal und nur innerhalb des Anmeldezeitfensters gültig ist. +Ergebnis: Anmeldung wird erst nach Klick auf den Link abgeschlossen; nicht bestätigte Anmeldungen laufen ab. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\TwoFactor\EmailTwoFactorValidator.cs, ValidateCredentials(...) (Code-Erzeugung, TaskCompletionSource, TryRemove im finally) und TrySetCodeAsValidated(...) (TryRemove = Einmalverwendung) - Begründung: durchsetzender Code-Lebenszyklus. + - [PRIMÄR] src\webservice\Centron.Controllers\Controllers\Unversioned\TwoFactorAuthController.cs, ValidateTwoFactorCode(...) ("Ungültiger Code. Bitte melden Sie sich erneut an." / "Anmeldung erfolgreich!") - Begründung: Bestätigungsendpunkt. +Prüfidee: Login starten, Link zweimal aufrufen: erster Aufruf "Anmeldung erfolgreich!", zweiter "Ungültiger Code"; Login ohne Klick → Timeout-Fehler. +Tracelinks: SyRS-105 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - In-Memory-Codehaltung funktioniert nur bei einem einzelnen Webservice-Prozess; fachliches Verfahren übernehmen, Zustand im Zielsystem persistent/verteilt halten. +Status: belegt +``` + +### SwRS-114: TOTP-PIN-Prüfung (Google Authenticator) für sensible Passwortmanager-Zugriffe + +``` +ID: SwRS-114 +Titel: TOTP-PIN-Prüfung (Google Authenticator) für sensible Passwortmanager-Zugriffe +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: TwoFactorAuthenticationBL, Benutzer mit Authenticator-App +Vorbedingung: Dem AppUser ist ein TwoFactorAuthKey hinterlegt (Sichbenu.TwoFactorAuthKey, gepflegt über die Personalverwaltung). +Fakt: ValidateAuthenticationPin lädt den benutzerbezogenen Schlüssel (NamedQuery PasswordManager.GetAppUserTwoFactorAuthKey) und prüft die eingegebene PIN mit Centron.Core.GoogleAuthenticator.TwoFactorAuthenticator.ValidatePin; ohne hinterlegten Schlüssel: "Ihrem Benutzer ist kein Zwei-Faktor Schlüssel in der Personalverwaltung hinterlegt!", bei falscher PIN: "Die eingegebene PIN ist ungültig!"; die zugehörigen Richtlinienrechte enthalten das Bitflag PasswordManagerGuidelineRights.TwoFactorAuthentification. +Aussage: Das System soll für besonders geschützte Passwortmanager-Zugriffe eine zusätzliche TOTP-PIN-Prüfung (Authenticator-App) gegen einen pro Benutzer hinterlegten Schlüssel anbieten. +Ergebnis: Zugriff auf entsprechend geschützte Zugangsdaten nur nach gültiger, zeitbasierter PIN. +Belege: + - [PRIMÄR] src\backend\Centron.BL\TwoFactorAuthenticator\TwoFactorAuthenticationBL.cs, ValidateAuthenticationPin(...) ("return Centron.Core.GoogleAuthenticator.TwoFactorAuthenticator.ValidatePin(appUserTwoFactorAuthKeyResult.Data, authenticationPin) ? Result.AsSuccess() : Result.AsError(...)") - Begründung: durchsetzende PIN-Prüfung. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, Sichbenu.TwoFactorAuthKey nvarchar(200); src\backend\Centron.BL\PasswordManager\PasswordManagerBL.cs Bitflag TwoFactorAuthentification - Begründung: Schlüsselablage und Verknüpfung mit Richtlinienrechten. +Prüfidee: Benutzer ohne Schlüssel ruft PIN-Prüfung auf (Erwartung: Hinweis auf fehlenden Schlüssel); mit Schlüssel: korrekte TOTP-PIN akzeptiert, abgelaufene/falsche PIN abgelehnt. +Tracelinks: SyRS-105, SyRS-108 +Konsolidierung: Kandidat: zweites 2FA-Subsystem neben Login-2FA (RADIUS/E-Mail-Link, SwRS-112/113) — gleiches fachliches Konzept in getrennter Implementierung. +Übernahmewürdigkeit: übernehmen - TOTP als Step-up-Authentifizierung für sensible Aktionen; im Zielsystem mit Login-2FA vereinheitlichen. +Status: belegt +``` + +### SwRS-115: Passwortmanager-Rechteprüfungen (Lizenz, Modulrechte, Richtlinien-Bitflags) + +``` +ID: SwRS-115 +Titel: Passwortmanager-Rechteprüfungen (Lizenz, Modulrechte, Richtlinien-Bitflags) +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: PasswordManagerBL, AccessManagement-UI (Centron.Controls) +Vorbedingung: Lizenz "Passwort-Manager"; Benutzer und Kunde sind Richtlinien zugeordnet. +Fakt: Richtlinien-Verwaltungsmethoden (Get/Save/Delete PasswordManagerGuideline) prüfen die Lizenz und das Recht ACCESS_GUIDELINE_MANAGEMENT (ValidateUserRights über AppRightsBL.CheckRightsFromUser mit ACCESS_GUIDELINE_MANAGEMENT/ACCESS_AREA_MANAGEMENT); pro Kunde/Mitarbeiter liefert GetPasswordManagerCustomersEmployeesRights Bitflag-Rechte (SealBreak, SealingAllowed, AccessDataEditable, AccessDataVisible, VPNAccessesEditable, TwoFactorAuthentification, Notification, AccessDataDeletable); die UI aktiviert Funktionen (z. B. Siegelbruch-Command) nur bei gesetztem Flag. +Aussage: Das System soll Passwortmanager-Funktionen dreistufig absichern: Lizenz, Modulrechte (Richtlinien-/Bereichsverwaltung) und je Kunde/Mitarbeiter zugewiesene Richtlinienrechte für einzelne Aktionen auf Zugangsdaten. +Ergebnis: Jede Passwortmanager-Aktion ist nur mit passender Lizenz-, Modul- und Richtlinienberechtigung ausführbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\PasswordManager\PasswordManagerBL.cs, GetPasswordManagerGuideline/GetPasswordManagerGuidelines/SavePasswordManagerGuideline (Lizenz + "userRights.Contains(UserRightsConst.PasswordManager.ACCESS_GUIDELINE_MANAGEMENT)") sowie ValidateUserRights(...) (Zeilen 761–782) - Begründung: durchsetzende Prüfungen. + - [PRIMÄR] src\backend\Centron.BL\PasswordManager\PasswordManagerBL.cs, GetPasswordManagerCustomersEmployeesRights(...) (Bitflag-Aufbau aus NamedQuery GetEmployeesRightsForCustomers) - Begründung: feingranulare Rechtequelle. + - [SEKUNDÄR] src\shared\Centron.Controls\PasswordManager\AccessManagementViewModel.cs, "this.SealBreakPropertyValueCommand = new AsyncCommand(this.SealBreakPropertyValue, () => this.GuidelineRightSealBreak);" - Begründung: UI-Durchgriff der Richtlinienrechte. +Prüfidee: Mitarbeiter ohne SealBreak-Flag: Siegelbruch-Button inaktiv und BL-Aufruf abgelehnt; ohne ACCESS_GUIDELINE_MANAGEMENT: Richtlinienliste liefert Fehlertext. +Tracelinks: SyRS-108 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - dreistufiges Modell ist der fachliche Kern des Moduls. +Status: belegt +``` + +### SwRS-116: Export von Zugangs- und Passwortdaten nur mit dediziertem Exportrecht + +``` +ID: SwRS-116 +Titel: Export von Zugangs- und Passwortdaten nur mit dediziertem Exportrecht +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: PasswordManagerBL, PasswordManagerConnector (WPF) +Vorbedingung: Lizenz vorhanden; Benutzer will Kundenzugangsdaten exportieren. +Fakt: GetAllCustomerAccountsWithAccessData und GetCustomerAccessDataForExport werfen ohne das Recht UserRightsConst.PasswordManager.EXPORT_ACCESS_AND_PASSWORD_DATA (20800135) eine ResultException "Sie besitzen nicht das Recht 'Passwort-Manager Export' um Zugänge und Passwörter zu exportieren" (MessageCode RightCheckFailed); der Export entschlüsselt die Daten mit dem Hotline-Masterkey ("Export all data decrypted"); die WPF-Seite blendet den Export über dieselbe Rechtskonstante ein. +Aussage: Das System soll den entschlüsselten Massenexport von Kundenzugangsdaten ausschließlich Benutzern mit dem dedizierten Exportrecht ermöglichen. +Ergebnis: Exportfunktion ohne Recht: serverseitige Exception; mit Recht: entschlüsselter Export. +Belege: + - [PRIMÄR] src\backend\Centron.BL\PasswordManager\PasswordManagerBL.cs, Zeilen 897–899 und 933–935 (Lizenz- und Rechteprüfung mit throw new ResultException(...)) - Begründung: durchsetzende Prüfungen unmittelbar vor der Offenlegung. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\PasswordManager\PasswordManagerConnector.cs, Zeile 412 (hasRights über CurrentUserAppRights) - Begründung: UI-seitige Spiegelung. +Prüfidee: Export ohne Recht per direktem BL-/API-Aufruf (Erwartung: ResultException RightCheckFailed); mit Recht: Exportdatei enthält entschlüsselte Zugangsdaten. +Tracelinks: SyRS-108 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Hochrisiko-Funktion braucht auch künftig ein eigenes Recht plus Protokollierung des Exports. +Status: belegt +``` + +### SwRS-117: AES-Verschlüsselung der Zugangsdaten mit Masterkey und fest kodiertem Fallback-Schlüssel + +``` +ID: SwRS-117 +Titel: AES-Verschlüsselung der Zugangsdaten mit Masterkey und fest kodiertem Fallback-Schlüssel +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: AESCryptoLogic, CentronConfigurationDbBL (Masterkey), PasswordManagerBL +Vorbedingung: Hotline-Masterkey ist in der Konfigurationsdatenbank hinterlegt. +Fakt: Passwörter der Kundenzugangsdaten werden als ModuleCustomPropertyValue.ValueEncryptedString mit AES verschlüsselt gespeichert ("new AESCryptoLogic().EncryptText(customerHotline.Password, masterKeyResult.Data)") und beim Lesen/Export mit demselben Masterkey entschlüsselt; AESCryptoLogic leitet Schlüssel und IV aus dem übergebenen Secret ab und verwendet bei fehlendem Secret den fest im Code hinterlegten Fallback-Schlüssel SECURITY_KEY = "lugE!35Djn"; beim Laden der Property-Werte für die Anzeige wird ValueEncryptedString zunächst genullt und der Klartext nur über gesonderte, geloggte Abrufe geliefert. +Aussage: Das System soll Passwörter von Kundenzugangsdaten ausschließlich symmetrisch verschlüsselt (AES) mit einem zentral verwalteten Masterkey speichern und Klartexte nur auf explizite, berechtigte Anforderung entschlüsseln. +Ergebnis: In der Datenbank liegen nur Chiffrate; Entschlüsselung erfordert den Masterkey. +Belege: + - [PRIMÄR] src\backend\Centron.BL\PasswordManager\PasswordManagerBL.cs, Zeilen ~700 (EncryptText beim Import), 949 (GetHotlineMasterKey für Export), 1052/1179 (DecryptText) sowie Zeilen 520–529 (Nullen von ValueEncryptedString vor Rückgabe der Liste) - Begründung: durchsetzender Verschlüsselungs-/Offenlegungsfluss. + - [PRIMÄR] src\backend\Centron.Common\TextCoding\AESCryptoLogic.cs, EncryptText/DecryptText/GetKeyAndIV inkl. "private const string SECURITY_KEY = @\"lugE!35Djn\";" - Begründung: exaktes Kryptoverfahren inkl. Fallback-Schlüssel. +Prüfidee: DB-Inhalt von ValueEncryptedString prüfen (Base64-Chiffrat, kein Klartext); Entschlüsselung mit falschem Masterkey liefert leeren String. +Tracelinks: SyRS-108 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - Verschlüsselung übernehmen, aber: fest kodierter Fallback-Schlüssel und aus dem Secret deterministisch abgeleiteter IV sind Schwächen; im Zielsystem KMS/Envelope-Encryption mit Zufalls-IV verwenden. +Status: belegt +``` + +### SwRS-118: Siegelbruch nur mit Recht, Pflichtkommentar, Protokoll und Benachrichtigung + +``` +ID: SwRS-118 +Titel: Siegelbruch nur mit Recht, Pflichtkommentar, Protokoll und Benachrichtigung +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: AccessManagementViewModel (Centron.Controls), PasswordManagerBL, Mail-System +Vorbedingung: Zugangsdatum ist versiegelt; Benutzer besitzt das Richtlinienrecht SealBreak. +Fakt: Der Siegelbruch-Command ist nur bei GuidelineRightSealBreak ausführbar; die Durchführung erzeugt einen Protokolleintrag PasswordManagerLogActionKind.SealBreak mit Begründungskommentar und versendet eine E-Mail "Siegel gebrochen" mit Kunde, Zeitpunkt, ausführendem Benutzer und Grund; Logeinträge werden über SavePasswordManagerLog persistiert; Siegelinformationen (SealBreaker) werden je Property-Wert geführt. +Aussage: Das System soll das Aufbrechen versiegelter Zugangsdaten nur Benutzern mit Siegelbruch-Recht erlauben, eine Begründung verlangen und den Vorgang protokollieren sowie aktiv per E-Mail melden. +Ergebnis: Jeder Siegelbruch ist begründet, protokolliert und den Verantwortlichen gemeldet. +Belege: + - [PRIMÄR] src\shared\Centron.Controls\PasswordManager\AccessManagementViewModel.cs, SealBreakPropertyValueCommand (canExecute () => this.GuidelineRightSealBreak), SealBreakPropertyValue() (NewLogEntry(PasswordManagerLogActionKind.SealBreak, ..., logCommentViewModel.Comment)) und Mailversand (Subject "Siegel gebrochen", Body mit Datum/Benutzer/Grund) - Begründung: durchsetzender Ablauf inkl. Rechteprüfung. + - [PRIMÄR] src\backend\Centron.BL\PasswordManager\PasswordManagerBL.cs, SavePasswordManagerLog(...) und GetPasswordManagerPropertyValueSealInformations(...) (SealBreaker-Flag) - Begründung: Persistenz von Log und Siegelstatus. +Prüfidee: Siegelbruch ohne Recht (Command deaktiviert / BL-Fehler), mit Recht: Log-Eintrag "Siegel gebrochen" mit Kommentar und versendete Mail nachweisen. +Tracelinks: SyRS-108 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Vier-Augen-taugliches Offenlegungs-Verfahren; Benachrichtigungsempfänger konfigurierbar machen. +Status: belegt +``` + +### SwRS-119: [HYPOTHESE] Alt-Passwortverwaltung (PasswordManagementArea) mit Zugriffsprotokoll, aber ohne wirksame Verschlüsselung + +``` +ID: SwRS-119 +Titel: [HYPOTHESE] Alt-Passwortverwaltung (PasswordManagementArea) mit Zugriffsprotokoll, aber ohne wirksame Verschlüsselung +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: PasswordManagementBL / PasswordManagementKeywordBL / PasswordManagementAccessLogBL +Vorbedingung: Alt-Datenbestand in Tabellen PasswordManagement/PasswordManagementKeyword. +Fakt: Die ältere Passwortverwaltung speichert Zugangsdaten in PasswordManagementKeyword (Spalten Username, Salt, Password); GetDecryptedKeywordById gibt trotz Kommentar "// decryption" das Feld keyword.Password unverändert zurück und schreibt dabei einen Access-Log-Eintrag (allerdings mit ActionType Create); AddNewKeyword legt Datensätze mit Salt = "" und Password = "" an; jede Aktion wird in PasswordManagementAccessLog/PasswordManagementLog protokolliert. +Aussage: Das System soll (Ist-Verhalten) Zugriffe auf Alt-Zugangsdaten protokollieren; die Passwortwerte werden dabei mutmaßlich unverschlüsselt gespeichert und ausgegeben. +Ergebnis: Zugriffe sind protokolliert; Vertraulichkeit der Alt-Passwörter ist nicht durch Verschlüsselung gesichert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\PasswordManagementArea\PasswordManagementKeywordBL.cs, GetDecryptedKeywordById(...) (Rückgabe keyword.Password ohne Entschlüsselung; SavePasswordManagementAccessLog(..., PasswordManagementActionTypeEnum.Create, user)) und AddNewKeyword(...) (Salt = "", Password = "") - Begründung: zeigt fehlende Entschlüsselungslogik; für die Verschlüsselungs-Aussage fehlt jedoch die schreibende Gegenstelle. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, Tabellen PasswordManagement, PasswordManagementKeyword (Salt/Password nvarchar(128)), PasswordManagementAccessLog - Begründung: Datenmodell mit ungenutztem Salt-Feld. +Prüfidee: Produktionsnahen Datenbestand prüfen: Enthält PasswordManagementKeyword.Password Klartexte? Wo werden Password/Salt befüllt (Delphi-Altclient?)? +Tracelinks: SyRS-108 +Konsolidierung: Kandidat: PasswordManagementArea (Alt) vs. PasswordManager mit ModuleCustomPropertyValue/AES (Neu) — dieselbe fachliche Funktion "Kundenpasswörter verwalten" in zwei Datenhaltungen. +Übernahmewürdigkeit: veraltet - durch den neuen Passwortmanager abgelöst; Alt-Daten sind zu migrieren und verschlüsselt abzulegen. +Status: HYPOTHESE +Offene Frage: Wird PasswordManagementKeyword.Password von einem anderen (Alt-)Client verschlüsselt befüllt, oder liegen die Werte im Klartext vor? Warum wird beim Lesezugriff der ActionType "Create" geloggt? +``` + +### SwRS-120: DSGVO-Kontaktlöschung mit feldweisem Entfernen und Löschprotokoll + +``` +ID: SwRS-120 +Titel: DSGVO-Kontaktlöschung mit feldweisem Entfernen und Löschprotokoll +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: DataSecurityBL, DSGVO-Modul (WPF) +Vorbedingung: Benutzer besitzt DSGVO_DELETE_CONTACT; zu löschende Kontaktpersonen sind ausgewählt. +Fakt: DsgvoDeleteRightDeleteContacts prüft das Recht und ruft je nach Objektart DoDeleteContactPerson/DoDeleteContactManagementContactPerson/DoDeleteAccountAddressContact; DoDeleteContactPerson entfernt feldweise personenbezogene Daten (Anrede, Name, Vorname, Geburtsdatum nur wenn Jahr > 1920, Beruf, Tel1–Tel5, Fax, E-Mail, Bild, Active Directory SID, Webseite ...), löscht verknüpfte Web-Zugänge, Aktivitäten, Beziehungen und Social-Network-Einträge und schreibt jede entfernte Angabe in ein Löschprotokoll (StringBuilder "c-entron Löschprotokoll", Kopf mit Durchführendem und Zeitpunkt); Kunden-/Lieferanten-/Account-Komplettlöschung wirft NotImplementedException ("not ready for use", SQL nur auskommentiert). +Aussage: Das System soll bei einer DSGVO-Löschung alle personenbezogenen Felder einer Kontaktperson und deren verknüpfte personenbezogene Objekte entfernen und jede entfernte Angabe in einem Löschprotokoll dokumentieren. +Ergebnis: Kontaktdatensatz ohne personenbezogene Inhalte; vollständiges Löschprotokoll je Vorgang. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\DataSecurity\DataSecurityBL.cs, DsgvoDeleteRightDeleteContacts(...) (Rechteprüfung Zeile 789) und DoDeleteContactPerson(...) (Zeilen 1125–1300: feldweises Nullen mit DoAppendDeleteProtocol, DoDeleteContactPersonWebAccounts/Activities/RelationShips/SocialNetworks) - Begründung: vollständige durchsetzende Löschlogik. + - [SEKUNDÄR] Konstante DsgvoDeletedContactMessageWithEmployeeInfo ("DSGVO: Auf Anfrage gelöscht. (Durchgeführt von {0} am {1:d} ...)") - Begründung: dokumentierter Löschvermerk. +Prüfidee: Kontaktperson mit gefüllten Feldern löschen; Erwartung: Felder leer, Löschprotokoll listet alle vorherigen Werte, Web-Zugänge der Person entfernt; Kundenlöschung: NotImplementedException. +Tracelinks: SyRS-109 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kontaktlöschung produktiv; Kunden-/Lieferanten-/Account-Löschung ist unfertig und im Zielsystem vollständig zu implementieren. +Status: belegt +``` + +### SwRS-121: DSGVO-Datenbereinigung und Modulzugang nur mit dedizierten Rechten + +``` +ID: SwRS-121 +Titel: DSGVO-Datenbereinigung und Modulzugang nur mit dedizierten Rechten +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: DataSecurityBL, ModuleRegistration (WPF) +Vorbedingung: DSGVO-Modul verfügbar (ModuleFeatures.IsDsgvoDatabaseCleanupAvailable). +Fakt: GetDataSecurityCleanUpStats und DataSecurityExecuteCleanUp verlangen beide currentUser.HasUserRight(UserRightsConst.DsgvoModule.ACCESS_CLEANUP_DATABASE) und die Modul-Verfügbarkeit; die Bereinigung umfasst u. a. alte Tätigkeiten (dbo.Taetigkeiten mit Datumsfilter) und gelöschte Kunden; der Modulzugang im Client verlangt ACCESS_DSGVO_MODULE (20800022); die Rechtekonstanten der DsgvoModule-Gruppe sind ID 20800021, ACCESS_DSGVO_MODULE 20800022, DSGVO_DELETE_CONTACT 20800023, ACCESS_CLEANUP_DATABASE 20800024. +Aussage: Das System soll die massenhafte Datenbereinigung (Aufbewahrungs-/Löschläufe) und den Zugang zum DSGVO-Modul jeweils an eigene Benutzerrechte binden. +Ergebnis: Bereinigungsläufe nur durch berechtigte Benutzer; Modul für andere unsichtbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\DataSecurity\DataSecurityBL.cs, Zeilen 34–36 und 64–66 ("if (!currentUser.HasUserRight(UserRightsConst.DsgvoModule.ACCESS_CLEANUP_DATABASE) || !ModuleFeatures.IsDsgvoDatabaseCleanupAvailable)") - Begründung: durchsetzende Doppelbedingung. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\ModuleRegistration.cs, Zeile 461 (ACCESS_DSGVO_MODULE) und src\webservice\Centron.WebServices.Core\...\UserRightsConst.cs, Klasse DsgvoModule (Zeilen 2735–2742) - Begründung: Modul-Gate und Rechtekonstanten. +Prüfidee: Bereinigungsstatistik ohne ACCESS_CLEANUP_DATABASE aufrufen (Erwartung: Fehler-Result); DSGVO-Modul ohne ACCESS_DSGVO_MODULE (Erwartung: Modul nicht sichtbar). +Tracelinks: SyRS-109 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Trennung von Modulzugang, Löschrecht und Bereinigungsrecht beibehalten. +Status: belegt +``` + +### SwRS-122: Verwaltung von Auftragsverarbeitungsverträgen (AVV) mit eigenen Rechten + +``` +ID: SwRS-122 +Titel: Verwaltung von Auftragsverarbeitungsverträgen (AVV) mit eigenen Rechten +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: DsgvoBL, DSGVO-Modul (OrderProcessingContractSettings-Views) +Vorbedingung: Benutzer mit AVV-Verwaltungsrechten; AVV-Vorlagen sind gepflegt. +Fakt: SaveAccountOrderProcessingContract verlangt UserRightsConst.Sales.Customer.CustomerCommon.ORDER_PROCESSING_CONTRACTS_MANAGEMENT, DeleteAccountOrderProcesingContract verlangt DELETE_ORDER_PROCESSING_CONTRACTS; das Modul verwaltet AVV-Vorlagen (OrderProcessingContractTemplate), Online-PDF-Dokumente mit Bestätigen/Ablehnen inkl. Unterschrift (ConfirmOnlinePdfDocument mit signature/signedDocument, DeclineOnlinePdfDocument mit Grund) und den Vertragsstatus je Kunde (GetCustomerAccountOrderContractState). +Aussage: Das System soll Auftragsverarbeitungsverträge als Vorlagen verwalten, Kunden online zur Bestätigung (inkl. elektronischer Unterschrift) oder Ablehnung bereitstellen und Anlage/Löschung der Kundenverträge an eigene Rechte binden. +Ergebnis: AVV-Lebenszyklus (Vorlage → Versand → signierte Bestätigung/Ablehnung → Status) ist abgebildet und rechtegeschützt. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Documents\Dsgvo\DsgvoBL.cs, Zeile 243 ("if (user.HasUserRight(UserRightsConst.Sales.Customer.CustomerCommon.ORDER_PROCESSING_CONTRACTS_MANAGEMENT) == false)") und Zeile 318 (DELETE_ORDER_PROCESSING_CONTRACTS) - Begründung: durchsetzende Rechteprüfungen. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\Administration\DSGVO\OrderProcessingContractSettingsView.xaml / -ViewModel - Begründung: Verwaltungs-UI im DSGVO-Modul. +Prüfidee: AVV ohne Verwaltungsrecht speichern (Erwartung: Fehler); Online-Dokument bestätigen und prüfen, dass Unterschrift und signiertes PDF gespeichert sowie Status aktualisiert wird. +Tracelinks: SyRS-109 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - digitaler AVV-Prozess ist für SaaS-Betrieb unmittelbar erforderlich. +Status: belegt +``` + +## A2 — Finanzen & Abrechnung: Software-Anforderungen (SwRS) + +### SwRS-230: Vertragsende-Berechnung mit Kündigungsfristen + +``` +ID: SwRS-230 +Titel: Vertragsende-Berechnung mit zweistufigen Kündigungsfristen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: ContractBL.RefreshContractEndeDate (Systemuser-Kontext) +Vorbedingung: VertragKopf.Status=1 mit Beginn, LaufzeitArt, LaufzeitDauer. +Fakt: Erstes Ende = GetNewDate(Beginn, LaufzeitArt, LaufzeitDauer); ohne AutoVerlaengerung ist dies das Ende; mit AutoVerlaengerung wird geprüft, ob die Kündigungsfrist 1 (KuendigungsFristArt1/-Dauer1, rückwärts gerechnet) noch nicht verstrichen ist, sonst wird iterativ (max. 100) um Verlaengerung Monate mit Kündigungsfrist 2 verlängert; ein KuendigungsDatum > 01.01.2000 begrenzt das Ende; Verträge mit unvollständigen Stammdaten werden übersprungen statt den Lauf abzubrechen; Monatsende-Logik: bei Beginn am Monatsletzten bleibt das Ende am Monatsletzten (GetNewMonthDate). +Aussage: Das System soll das wirksame Vertragsende aus Laufzeit, automatischer Verlängerung, zwei Kündigungsfristen und einem gesetzten Kündigungsdatum berechnen, wobei Monatsend-Konstellationen (30./31./Februar) korrekt behandelt werden. +Ergebnis: VertragKopf.Ende ist deterministisch; Änderung erzeugt ReceiptLog-Eintrag „Vertragsende wurde von Webservice auf '…' gesetzt". +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\CustomerAssets\Contracts\ContractBL.cs, RefreshContractEndeDate (Z. 1067–1177) und GetNewMonthDate/GetNewDate (Z. 1033–1065) - Begründung: vollständige Berechnungs- und Sonderfalllogik. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, VertragKopf (KuendigungsFristArt1/2, KuendigungsFristDauer1/2, AutoVerlaengerung, Verlaengerung, KuendigungsDatum, Ende) - Begründung: tragendes Datenmodell. +Prüfidee: Vertrag Beginn 31.01., Laufzeit 1 Monat: Ende muss 28./29.02. sein; mit Autoverlängerung und Frist 1 überschritten: Ende = erste Verlängerungsperiode. +Tracelinks: SyRS-208 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - fachlich zwingend; Iterationsdeckel 100 als expliziten Grenzwert spezifizieren. +Status: belegt +``` + +### SwRS-231: Automatischer Vertragsabschluss nur nach vollständiger Abrechnung + +``` +ID: SwRS-231 +Titel: Automatischer Vertragsabschluss nur nach vollständiger Abrechnung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: ContractBL.CloseContract (Automation) +Vorbedingung: Setting AutomaticallyCloseExpiredContracts=true; Vertrag State=Active, CalculationKind=Auto. +Fakt: Ein Vertrag wird nur auf ReceiptState.Completed gesetzt, wenn (a) bei AutomatedProlongation: LastBookingTo >= ContractTermination und referenceDate > ContractTermination, (b) sonst: LastBookingTo >= ContractEnd und referenceDate > ContractEnd; der Abschluss erfolgt via SaveReceipt in eigener Session mit ReceiptLog-Eintrag „Vertrag wurde per Automation am … abgeschlossen."; Fehler je Vertrag werden geloggt und übersprungen. +Aussage: Das System soll abgelaufene Verträge nur dann automatisch abschließen, wenn der letzte abgerechnete Zeitraum das Vertrags-/Kündigungsende erreicht und das Ende kalendarisch überschritten ist; die Funktion soll konfigurativ abschaltbar sein und jeden Abschluss protokollieren. +Ergebnis: Kein Umsatzverlust durch vorzeitigen Abschluss unabgerechneter Verträge. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\CustomerAssets\Contracts\ContractBL.cs, CloseContract (Z. 1243–1316, Bedingungen Z. 1266–1289) - Begründung: exakte Abschlussbedingung im Code. +Prüfidee: Vertrag Ende 31.03., abgerechnet bis 28.02.: darf am 01.04. NICHT schließen; nach Abrechnung bis 31.03. schließt er beim nächsten Lauf. +Tracelinks: SyRS-208 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Schutzregel gegen Abrechnungslücken. +Status: belegt +``` + +### SwRS-232: Kontingentrest-Formel + +``` +ID: SwRS-232 +Titel: Kontingentrest-Berechnung Rest = Gebucht + Übernommen − Verbraucht +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: ContractBL.GetContingentRest, Vertragsmonitoring +Vorbedingung: Kontingentvertrag (VertragKopf.KontingentVertrag=1) mit Buchungen. +Fakt: GetContingentRest lädt per NamedQuery nqContingentState die Werte Booked/TakeOver/Used/Reserved und berechnet Rest = Booked + TakeOver − Used; die View ContractContingentBooked filtert auf KontingentWert<>0, Zwischenrechnung<4 und Status>0 und berechnet RestValue über die Funktion cfn_RestValue nur bei KontingentRestMitnehmen. +Aussage: Das System soll den verfügbaren Kontingentrest eines Vertrags als Summe gebuchter und übernommener Kontingente abzüglich des Verbrauchs berechnen; Restmitnahme in Folgeperioden soll nur bei aktiviertem „Rest mitnehmen" gelten. +Ergebnis: Konsistenter Kontingentstand in Monitoring und Abrechnung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\CustomerAssets\Contracts\ContractBL.cs, GetContingentRest (Z. 60–83, Rest-Formel Z. 80) - Begründung: implementierte Formel. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, View ContractContingentBooked (WHERE KontingentWert<>0 AND Zwischenrechnung<4 AND Status>0; RestValue via cfn_RestValue) - Begründung: DB-seitige Filter- und Restlogik. +Prüfidee: Kontingent 10 h buchen, 3 h verbrauchen, 2 h Übernahme: Rest muss 9 h betragen. +Tracelinks: SyRS-207 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kernformel der Kontingentverträge. +Status: belegt +``` + +### SwRS-233: Abrechnungstermin- und Normierungslogik + +``` +ID: SwRS-233 +Titel: Folgetermin-Berechnung mit Monatsend-Sonderfällen und Perioden-Normierung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: AutomaticFacturaBL (NextDate, SetInvoiceTo, *NormalizeCoefficient) +Vorbedingung: Vertrag mit IsNormalize (RechnungNormieren) und Abrechnungsbeginn ungleich Periodenerstem. +Fakt: NextDate behandelt explizit: Beginn am Tag >28 (Offset vom Monatsende), Februar/Schaltjahr, Quartalsausrichtung auf 1.1./1.4./1.7./1.10.; SetInvoiceTo berechnet für die erste (angebrochene) Periode einen Normierungskoeffizienten (MonthNormalizeCoefficient = Resttage/Monatstage + Monatsdifferenz; analog Quartal/Jahr /3 bzw. /12), sofern nicht VollerBetragBeiNormierung (IsFullNormalizeAmount) gesetzt ist; bei Vertragsende innerhalb der Periode wird anteilig gekürzt (partBilling). +Aussage: Das System soll angebrochene erste und letzte Abrechnungsperioden tagesanteilig normieren (es sei denn, der volle Betrag ist konfiguriert) und Folgetermine auch bei Monatsend-/Februar-Konstellationen stabil fortschreiben. +Ergebnis: Anteilige Rechnungsbeträge (InvoiceIntervalCount als Bruchteil) für Rumpfperioden. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\CustomerAssets\AutomaticFactura\AutomaticFacturaBL.Contracts.cs, MonthNormalizeCoefficient/QuarterNormalizeCoefficient/YearNormalizeCoefficient (Z. 1375–1407), SetInvoiceTo (Z. 1408–1471), NextDate (Z. 1474–1583) - Begründung: vollständige implementierte Regel. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, VertragKopf.RechnungNormieren, VollerBetragBeiNormierung - Begründung: Konfigurationsfelder der Normierung. +Prüfidee: Monatsvertrag ab 16.01. (Monat mit 31 Tagen): erster Intervallfaktor muss 16/31 ≈ 0,516 betragen; mit VollerBetragBeiNormierung=1 dagegen 1,0. +Tracelinks: SyRS-206 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - komplexeste, fehlerträchtigste Kernregel des Clusters; testgetrieben nachbauen. +Status: belegt +``` + +### SwRS-234: Kontingentbuchung bei abweichendem Kontingentintervall + +``` +ID: SwRS-234 +Titel: Kontingentbuchung bei vom Abrechnungsintervall abweichendem Kontingentintervall +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: AutomaticFacturaBL.StoreBookedContingent/AddInterimContingent +Vorbedingung: Kontingentvertrag mit DifferContingentIntervalDuration ≠ Abrechnungsintervall. +Fakt: Ist das Kontingentintervall kleiner als das Abrechnungsintervall (und nicht Overbooking+RestTake), wird die Zuordnung als Zwischenrechnung (DifferContingentInterval.headMinorToContract) mit KontingentWert=0 gespeichert und AddInterimContingent legt je Teilintervall eigene VertragRechKopfZuordnung-Sätze mit anteiligen GebuchtVon/GebuchtBis an (erste Teilperiode tagesanteilig gekürzt); ist es größer, wird ab dem letzten gebuchten Kontingentdatum in Intervallschritten bis über InvoiceTo gebucht (headMajorToContract) bzw. ohne Buchung (interimMajorToContract); Restmitnahme wird deaktiviert, wenn die Kontingentart wechselt; bei manueller/Bedarfsabrechnung wird NachBerechnung=2 (bzw. 1 bei bereits gebuchtem Zeitraum) gesetzt. +Aussage: Das System soll Kontingente auch dann periodengerecht buchen, wenn Kontingent- und Abrechnungsintervall auseinanderfallen, einschließlich anteiliger erster Teilperiode, Nachberechnungskennzeichen und Deaktivierung der Restmitnahme bei Kontingentartwechsel. +Ergebnis: Kontingentstände stimmen unabhängig von Intervallkombinationen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\CustomerAssets\AutomaticFactura\AutomaticFacturaBL.Contracts.cs, StoreBookedContingent (Z. 1098–1245) und AddInterimContingent (Z. 1036–1091) - Begründung: durchgesetzte Buchungsregeln inkl. aller Fallunterscheidungen. +Prüfidee: Vertrag jährlich abgerechnet, Kontingentintervall monatlich, ohne Overbooking: es müssen 12 Teil-Zuordnungen mit Zwischenrechnung=headMinorToContract entstehen. +Tracelinks: SyRS-207, SyRS-206 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - fachlich notwendig, aber Kandidat für Vereinfachung/klarere Zustandscodes (Zwischenrechnung 0–4 sind implizit). +Status: belegt +``` + +### SwRS-235: Vertragsauswahl des Abrechnungslaufs + +``` +ID: SwRS-235 +Titel: Vertragsauswahl des Abrechnungslaufs mit Ausschluss leerer Rechnungen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: AutomaticFacturaBL.SearchBillingContracts/GetActiveContracts +Vorbedingung: Abrechnungslauf mit Filter (Stichtag, Kunden, Vertragsarten, Filialen, Berechnungsart) gestartet. +Fakt: GetActiveContracts selektiert nur State=1-Verträge nach CalculationKind (Auto/Manuell/Bedarf als Bitmaske), Laufzeitfenster und ExtraKind (Easy/ClickDevice/Contingent); SearchBillingContracts entfernt danach dynamische Bedarfsverträge ohne fällige Sonderartikel und Verträge ohne Positionen/Artikelreferenzen („leere RE vermeiden") und markiert Warnzustände (WithEmptyPos, WithBarcode=SN-pflichtig, WithPartibleArticle bei gebrochenem Intervallfaktor, NoDeliverable). +Aussage: Das System soll im Abrechnungslauf nur abrechnungsreife Verträge anbieten, Verträge ohne fakturierbare Positionen ausschließen und Konfliktzustände (fehlende Stückzahl, Seriennummernpflicht, teilbare Artikel bei anteiliger Periode, nicht lieferbare Artikel) je Vertrag kennzeichnen. +Ergebnis: Keine leeren Rechnungen; Anwender sieht Warnkennzeichen vor der Fakturierung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\CustomerAssets\AutomaticFactura\AutomaticFacturaBL.Contracts.cs, GetActiveContracts (Z. 820–845) und SearchBillingContracts (Z. 847–970, „leere RE vermeiden" Z. 886–893) - Begründung: implementierte Selektion und Ausschlüsse. +Prüfidee: Vertrag ohne Positionen in Lauf aufnehmen; er darf nicht in der Ergebnisliste erscheinen. +Tracelinks: SyRS-206, SyRS-207 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Schutz vor Leerrechnungen ist fachliche Kernregel. +Status: belegt +``` + +### SwRS-236: Folge-ToDo nach Abrechnung + +``` +ID: SwRS-236 +Titel: Automatisches Wiedervorlage-ToDo nach jeder Vertragsabrechnung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: AutomaticFacturaBL.StoreInvoiceToContract, ToDoBL +Vorbedingung: Auto-Vertrag wurde abgerechnet; Vertragsende noch nicht erreicht. +Fakt: Nach der Abrechnung wird für Auto-Verträge ein ToDo (ToDoType.ContractBill) mit Termin = InvoiceTo (bei Nachberechnung = NextDate), begrenzt auf den letzten Vertragstag und vorverlegt um BillingToDoOffset Tage, gespeichert; bei manueller/Bedarfsabrechnung wird das ContractBill-ToDo gelöscht; ist der Vertrag vollständig abgerechnet (InvoiceTo >= LastDay), entsteht kein neues ToDo. +Aussage: Das System soll nach jeder automatischen Vertragsabrechnung die nächste Abrechnungsfälligkeit als Wiedervorlage (mit konfigurierbarem Vorlauf) erzeugen und bei Vertragsende bzw. manueller Abrechnung keine/obsolete Wiedervorlagen führen. +Ergebnis: Kein Vertrag wird bei der nächsten Fälligkeit vergessen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\CustomerAssets\AutomaticFactura\AutomaticFacturaBL.Contracts.cs, StoreInvoiceToContract (Z. 1310–1336) - Begründung: ToDo-Erzeugung inkl. Terminformel `toDoTermin.AddDays(1 - billingParam.BillingToDoOffset)`. +Prüfidee: Vertrag mit Offset 5 Tage abrechnen (InvoiceTo=31.03., Vorabberechnung): ToDo-Termin muss 27.03. der Folgeperiode sein. +Tracelinks: SyRS-206, SyRS-208 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - in SaaS-Version eher als Scheduler/Job statt ToDo umsetzbar. +Status: belegt +``` + +### SwRS-237: Mahnstufen-Statusmaschine mit Audit-Feldern + +``` +ID: SwRS-237 +Titel: Mahnstufen-Statusmaschine 0→1→2→3 mit Datum/Bearbeiter je Stufe und Rücksetzung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: DunningRunBL.UpdateInvoice/ResetDunningRun +Vorbedingung: Rechnung im Mahnlauf ausgewählt; Benutzer hat Mahnwesen-Recht. +Fakt: UpdateInvoice erhöht DunningLevel strikt sequenziell (None→Level1→Level2→Level3, sonst ArgumentOutOfRangeException) und setzt je Stufe DunningLevelXDate=Now und DunningLevelXEmployee; ResetDunningRun setzt in einer Transaktion die jeweils höchste Stufe samt Datum/Bearbeiter zurück (Level1→None …), markiert die Mahnlaufpositionen als DunningRunState.Deleted mit DeletedDate/DeletedByEmployeeI3D. +Aussage: Das System soll Mahnstufen ausschließlich sequenziell erhöhen (maximal Stufe 3), je Stufe Zeitpunkt und Bearbeiter revisionssicher speichern und einen kompletten Mahnlauf transaktional rückgängig machen können, ohne die Historie zu löschen. +Ergebnis: Nachvollziehbare Mahnhistorie; kein Stufensprung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\Dunning\DunningRunBL.cs, UpdateInvoice (Z. 248–275) und ResetDunningRun (Z. 495–554) - Begründung: Statusmaschine und Rückabwicklung im Code. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, RechKopf-Spalten Mahnung1–3Datum/BearbeiterI3D, Mahnstufe (Z. 3268–3276) - Begründung: persistente Audit-Felder. +Prüfidee: Rechnung auf Stufe 3 mahnen und vierten Lauf versuchen: Exception; Reset des Laufs: Stufe sinkt auf 2, Mahnlauf-Items State=Deleted. +Tracelinks: SyRS-211 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kern des Mahnwesens. +Status: belegt +``` + +### SwRS-238: Mahnlauf-Protokoll mit fortlaufender Laufnummer + +``` +ID: SwRS-238 +Titel: Mahnlauf-Protokoll (Mahnlauf) mit fortlaufender Laufnummer und Transaktionsklammer +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: DunningRunBL.SaveDunningRun/ExecuteDunningRun +Vorbedingung: Mahnlauf für einen Kunden wird ausgeführt. +Fakt: Je Rechnung entsteht ein DunningRunItem (Tabelle Mahnlauf) mit Datum, EditorI3D, DunningSendType, OldDunningLevel/NewDunningLevel, State=Active und DunningRunNumber = max(vorhandene)+1; der gesamte Lauf (Stufenerhöhung + Protokoll + Reporterzeugung) läuft in einer Transaktion mit Rollback bei Fehler; die Vorschau (GetPreviewForDunningRun) nutzt dieselbe Logik, wird aber immer zurückgerollt. +Aussage: Das System soll jeden Mahnlauf unter einer fortlaufenden Laufnummer mit alter/neuer Stufe, Versandart und Bearbeiter protokollieren, den Lauf atomar ausführen und eine seiteneffektfreie Vorschau anbieten. +Ergebnis: Vollständige, gruppierbare Mahnlaufhistorie; keine halb ausgeführten Läufe. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\Dunning\DunningRunBL.cs, SaveDunningRun/GenerateNextDunningRunNumber (Z. 277–315), ExecuteDunningRun (Transaktion, Z. 179–198), GetPreviewForDunningRun (Rollback, Z. 162–177) - Begründung: Protokoll-, Nummern- und Transaktionslogik. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, Tabelle Mahnlauf und View cvw_DunningRunItems (Z. 20016–20064) - Begründung: persistentes Protokollschema. +Prüfidee: Zwei Mahnläufe nacheinander ausführen: Laufnummern n und n+1; Vorschau erzeugen: keine DB-Änderung. +Tracelinks: SyRS-211 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Atomarität und Vorschau als Muster übernehmen. +Status: belegt +``` + +### SwRS-239: Mahnreife — Mahnsperre und nächste Fälligkeit + +``` +ID: SwRS-239 +Titel: Mahnreife: zeitraumbezogene Mahnsperre und stufenabhängige Folgefälligkeit +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: DunningBL (GetDunningStopActive), View cvw_InvoiceDunning +Vorbedingung: Rechnung/Kunde mit Mahnsperre-Feldern; Rechnung fällig. +Fakt: Die Mahnsperre gilt: bei Beginn+Ende, wenn heute dazwischen liegt; nur Beginn: ab Beginn; nur Ende: bis Ende; ohne Daten: boolesches DunningStop-Flag (Kunde und Rechnung getrennt setzbar via UpdateDunningStopAndInfo, nur für InvoiceClass/CustomerClass). Die nächste Mahnfälligkeit wird in cvw_InvoiceDunning per Mahnstufe aus kundenindividuellen Fristen (KunLief.MahnungNachTagen/2/3) oder globalen Defaults (Stammdat I3D 243/244/245) auf FaelligAm bzw. MahnungXDatum aufgeschlagen (NextDueDateInDays); DunningLevel ist NULL, solange FaelligAm in der Zukunft liegt. +Aussage: Das System soll Rechnungen nur mahnen, wenn keine (zeitraumbezogene) Mahnsperre auf Kunde oder Rechnung aktiv ist und die stufenabhängige Karenzfrist (kundenindividuell, sonst global) abgelaufen ist. +Ergebnis: Mahnvorschläge enthalten nur mahnreife Rechnungen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\Dunning\DunningBL.cs, GetDunningStopActive (Z. 170–182) und UpdateDunningStopAndInfo (Z. 392–436) - Begründung: durchgesetzte Sperrlogik. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, cvw_InvoiceDunning CROSS APPLY NextDueDate-Berechnung (Stammdat 243–245, MahnungNachTagen) - Begründung: SQL-seitige Fälligkeitsregel. +Prüfidee: Kunde mit MahnungNachTagen2=14: nach Mahnstufe 1 darf die Rechnung erst 14 Tage nach Mahnung1Datum wieder vorgeschlagen werden; Mahnsperre 01.–31.08. blendet sie im August aus. +Tracelinks: SyRS-211, SyRS-212 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Fristen-Kaskade (individuell vor global) beibehalten. +Status: belegt +``` + +### SwRS-241: Versandvoraussetzungen für Mahn-E-Mails + +``` +ID: SwRS-241 +Titel: Versandvoraussetzungen: Ansprechpartner mit E-Mail und Textbaustein-Variablen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: DunningRunBL.GenerateMail, MailTemplateBL +Vorbedingung: Mahnlauf mit SendType=Mail. +Fakt: GenerateMail wirft eine Exception, wenn kein Ansprechpartner ermittelbar ist oder dessen Email1 leer ist; der Mailtext entsteht aus Mailvorlagen (MailTemplateReferences.Dunning.ToCustomer bzw. OPOS.ToCustomer) mit Variablenersetzung (@@RechnungenListe@@, @@MaximumMahnstufe@@ mit useNextHigherValue, @@GutschriftenSumme@@ …); der abweichende Mahn-Ansprechpartner (DunningLetterRecipientPersonI3D, DunningLetterKind Mail/Fax/Druck, UseDivergentInvoiceAddressAsDunningAddress) wird am Kunden gepflegt. +Aussage: Das System soll Mahn-E-Mails nur an einen hinterlegten Mahn-Ansprechpartner mit E-Mail-Adresse versenden, den Mailinhalt aus Vorlagen mit Beleg- und Stufenvariablen erzeugen und dabei die künftige (nächsthöhere) Mahnstufe ausweisen. +Ergebnis: Keine Mahnläufe mit unzustellbaren Mails; konsistente Mahntexte. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\Dunning\DunningRunBL.cs, GenerateMail (Z. 406–451: Exceptions bei fehlendem Kontakt/E-Mail) - Begründung: erzwungene Versandvoraussetzung. + - [SEKUNDÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\Dunning\DunningBL.cs, GetCustomerEmailVariables (Z. 485–783) und UpdateDunningSettingsForCustomer (Z. 341–390) - Begründung: Variablenkatalog und Ansprechpartner-Pflege. +Prüfidee: Mahnlauf per Mail für Kunde ohne E-Mail am Kontakt: Lauf bricht mit sprechender Fehlermeldung ab. +Tracelinks: SyRS-211 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Variablenkatalog dokumentieren und übernehmen. +Status: belegt +``` + +### SwRS-242: Zahlungseingang löschen mit Rechteprüfung und Rückrechnung + +``` +ID: SwRS-242 +Titel: Zahlungseingang löschen: Rechteprüfung, Filterpflicht, Rückrechnung +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: Sicherheit +Akteur: PaymentsBL.DeleteIncomingPayment +Vorbedingung: Zahlungseingänge zu Rechnungen existieren. +Fakt: Ohne Recht 10980 → Result.AsError("Sie haben nicht das Recht 'Zahlungseingang.", RightCheckFailed); ein leerer Filter (weder Rechnungsnummern noch I3Ds) wird per Guard abgewiesen („Empty Filters are not allowed for deleting IncomingPayments"); sofern DontChangeInvoice=false, wird je betroffener Rechnung die Summe der gelöschten Zahlungen mit UpdateReceiptIsPaid (Betrag × −1 × CurrencyFactor, Log „Zahlungseingang gelöscht") zurückgebucht, erst danach wird gelöscht. +Aussage: Das System soll das Löschen von Zahlungseingängen nur mit Recht Zahlungseingang, nur mit explizitem Filter und mit automatischer Rückrechnung des Rechnungs-Zahlstatus erlauben. +Ergebnis: Keine Massenlöschung ohne Filter; Zahlstatus bleibt konsistent. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Finances\Payments\PaymentsBL.cs, DeleteIncomingPayment (Z. 38–78) und CreateFilterExpression (Z. 159–187, Guard) - Begründung: alle drei Schutzregeln im Code. +Prüfidee: Löschaufruf ohne Recht → RightCheckFailed; mit leerem Filter → Guard-Fehler; mit Filter → PayedGrossAmount der Rechnung sinkt um den Zahlungsbetrag. +Tracelinks: SyRS-213, SyRS-218 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Schutzregeln vollständig übernehmen. +Status: belegt +``` + +### SwRS-243: OPOS-Saldenformel inkl. Gutschriftenverrechnung + +``` +ID: SwRS-243 +Titel: OPOS-Saldenformel: offener Betrag = Brutto − Zahlungen − verrechnete Gutschriften +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: DunningBL/OposOverview, View cvw_InvoiceDunning +Vorbedingung: Rechnung mit Teilzahlungen und aus ihr erzeugten Gutschriften. +Fakt: Alle Statistik-Summen verwenden GrossPriceComplete − PayedGrossAmount − CreditVoucherGrossAmount; die View berechnet CreditVoucherGrossAmount aus CreditVoucherItems mit OriginKind=4 (aus Rechnung erzeugt) und PayedGrossAmount als Payed/CurrencyFactor − Gutschriften; die Kundensummen-Filter (AllNonZero/OverZero/LowerOrEqualToZero) müssen laut Code-Kommentar mit DunningCustomerViewModel.SumAmount und OposCustomerViewModel.SumAmount konsistent gehalten werden. +Aussage: Das System soll offene Posten je Rechnung als Bruttobetrag abzüglich Zahlungen und abzüglich der aus der Rechnung erzeugten Gutschriften berechnen und Kunden nach Summensaldo (≠0, >0, ≤0) filtern können. +Ergebnis: OPOS-Salden entsprechen kaufmännischer Erwartung inkl. Gutschriften. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\Dunning\DunningBL.cs, CalculateDunningStatistics (Z. 205–236) und GenerateCustomerExpression Summenfilter (Z. 246–262) - Begründung: implementierte Formel und Filter. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, cvw_InvoiceDunning (PayedGrossAmount-/CreditVoucherGrossAmount-Ausdrücke, Subselect auf CreditVoucherItems OriginKind=4) - Begründung: DB-seitige Herleitung. +Prüfidee: Rechnung 1190 €, Zahlung 500 €, Gutschrift aus Rechnung 190 €: offener Betrag 500 €; Kunde erscheint im Filter OverZero. +Tracelinks: SyRS-212 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Formel zentralisieren statt (wie heute) an drei Stellen synchron halten. +Status: belegt +``` + +### SwRS-244: Duplikaterkennung beim Umsatzimport + +``` +ID: SwRS-244 +Titel: Duplikaterkennung beim Import von Kontoumsätzen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: OnlineBankingAccountTransactionsBL.SaveOnlineBankingAccountTransactions +Vorbedingung: Umsatzimport (FinTS/finAPI/Spreadsheet) liefert neue Datensätze. +Fakt: Ein neuer Umsatz (I3D<=0) wird verworfen, wenn bereits ein Umsatz mit gleicher OnlineBankingConfigurationI3D, BookingDate, Amount, AccountIBAN und Description existiert; der Vorgang liefert eine Warnung (DefaultMessageCodes.DuplicateRecords) mit den Duplikatdaten, die übrigen Datensätze werden gespeichert. +Aussage: Das System soll beim Umsatzimport Duplikate über das Tupel (Konfiguration, Buchungsdatum, Betrag, IBAN, Verwendungszweck) erkennen, nicht erneut speichern und den Anwender per Warnung informieren. +Ergebnis: Kein doppelter Zahlungsabgleich durch Mehrfachimport. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Finances\OnlineBanking\OnlineBankingAccountTransactionsBL.cs, SaveOnlineBankingAccountTransactions (Z. 294–340) - Begründung: implementierte Duplikatbedingung. +Prüfidee: Dieselbe CSV zweimal importieren: zweiter Import speichert 0 Datensätze und liefert Duplikat-Warnungen. +Tracelinks: SyRS-214 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kriterium ggf. um Ende-zu-Ende-Referenz erweitern. +Status: belegt +``` + +### SwRS-245: Abschlussstatus von Umsätzen mit Zahlungstoleranz + +``` +ID: SwRS-245 +Titel: Umsatz-Abschlussstatus mit 0,10-Toleranz und manueller Übersteuerung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: OnlineBankingAccountTransactionsBL.CheckForCompleted +Vorbedingung: Umsatz mit gebuchten Zuordnungen (TransactionAssignments). +Fakt: IsCompleted wird true, wenn |Summe der gebuchten AssignedAmounts − Umsatzbetrag| ≤ 0,1 (gerundet auf 2 Stellen); Zustände ManuallyCompleted/ManuallyOpened übersteuern die Berechnung; ohne gebuchte Zuordnung bleibt der Umsatz offen. +Aussage: Das System soll einen Kontoumsatz automatisch als erledigt kennzeichnen, wenn die gebuchten Zuordnungen den Umsatzbetrag bis auf eine Toleranz von 0,10 abdecken, und manuelle Erledigt-/Offen-Markierungen respektieren. +Ergebnis: Offene-Umsätze-Liste zeigt nur tatsächlich unerledigte Zahlungen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Finances\OnlineBanking\OnlineBankingAccountTransactionsBL.cs, CheckForCompleted (Z. 342–360, Kommentar "allowed payment tollerance") - Begründung: Toleranzregel im Code. +Prüfidee: Umsatz 100,00 mit gebuchter Zuordnung 99,95: IsCompleted=true; mit 99,80: false. +Tracelinks: SyRS-214 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Toleranzwert konfigurierbar machen. +Status: belegt +``` + +### SwRS-246: Matching-Heuristiken des Zahlungsabgleichs + +``` +ID: SwRS-246 +Titel: Gestufte Matching-Heuristiken (Rechnungsnummer, IBAN, Sender, Betrag, Teilmengensumme) +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: OnlineBankingAccountTransactionsBL.AutoCompleteSingleAccountTransaciton +Vorbedingung: Offene Umsätze und offene Rechnungen vorhanden. +Fakt: Stufe 1 sucht Rechnungsnummern im Verwendungszweck per Regex, deren Ziffernlänge aus dem Rechnungs-Nummernkreis (NumberGroup RangeFrom/Current) abgeleitet wird; Stufe 2 sucht den Kunden über IBAN-Gleichheit mit hinterlegten Bankverbindungen, sonst über den Sendernamen; Stufe 3 matcht offene Rechnungen des Kunden nach Betrag (exakt, dann ±0,50), sonst Teilmengen-Summensuche über maximal 20 Belege; Ergebnisse erhalten Heuristik-Kennung und MatchingRate, manuell gesetzte und gebuchte Zuordnungen bleiben erhalten, Beträge werden absteigend nach Trefferqualität verteilt (AssignAmounts). +Aussage: Das System soll Kontoumsätze mehrstufig automatisch zuordnen (Rechnungsnummern → IBAN/Sender → Betrags-/Kombinationsmatching), jede Zuordnung mit Heuristik und Trefferquote kennzeichnen und manuelle bzw. gebuchte Zuordnungen nie automatisch überschreiben. +Ergebnis: Hohe automatische Trefferquote mit nachvollziehbarer Herkunft jedes Vorschlags. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Finances\OnlineBanking\OnlineBankingAccountTransactionsBL.cs, SearchReceiptInvoicesByDescription (Z. 622–662, Regex aus Nummernkreislänge), SearchCustomerBySenderAndIBAN (Z. 691–719), SearchReceiptInvoicesByCustomerAndAmount/FindReceiptCombination (Z. 721–780), AddSearchResultsToAccountTransaction (Z. 782–843) - Begründung: vollständige Heuristikkette. +Prüfidee: Umsatz „RG 123456" über Summe zweier Rechnungen: Heuristik MatchedSummedInvoicesAmountExactly; manuelle Zuordnung setzen, Auto-Lauf wiederholen: manuelle bleibt bestehen. +Tracelinks: SyRS-214 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Heuristiken und 20-Belege-Grenze (Performance) explizit spezifizieren. +Status: belegt +``` + +### SwRS-247: Buchung, Chargeback und Storno von Umsatzzuordnungen + +``` +ID: SwRS-247 +Titel: Buchung auf Rechnung inkl. Chargeback-Wiedereröffnung, Gutschrift-Schließung und Storno +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: OnlineBankingAccountTransactionsBL.BookAmountToAssignedInvoice/CloseCreditVoucher/UndoBookingForAccountTransaciton +Vorbedingung: Umsatzzuordnung mit AssignedAmount existiert, IsBooked=false. +Fakt: Buchung erhöht PaidFC der Rechnung um AssignedAmount und setzt isPaid, wenn newPaidFC >= ReceiptDemandedGrossAmount oder CloseReceiptAfterBooking; negative Beträge (Chargeback) dürfen auch geschlossene Rechnungen ändern (Log-Suffix „(Chargeback)"); zugehörige Gutschriften können mitgeschlossen werden (CloseRelatedCreditVouchers über CreditVoucherItems.OriginReceiptItemI3D); Storno kehrt Betrag, Flags (IsBooked, BookedDate, BookedBy…) und Gutschriftstatus um; jeder Vorgang erzeugt ReceiptLog-Einträge („Zahlungseingang: Bankauszüge" / „Annullierung …"). +Aussage: Das System soll Zuordnungsbeträge auf Rechnungen buchen und stornieren können, Rücklastschriften als negative Buchung auf auch bereits geschlossene Rechnungen zulassen, verbundene Gutschriften optional mitschließen und jeden Schritt im Belegprotokoll dokumentieren. +Ergebnis: Zahlstatus, Gutschriftstatus und Protokoll bleiben in allen Richtungen konsistent. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Finances\OnlineBanking\OnlineBankingAccountTransactionsBL.cs, BookAmountToAssignedInvoice (Z. 1042–1086), CloseCreditVoucher/CloseRelatedCreditVouchers (Z. 923–1001), UndoBookingForAccountTransaciton (Z. 1003–1040) - Begründung: durchgesetzte Buchungs-/Stornoregeln. +Prüfidee: Rechnung vollständig buchen (isPaid=true), Chargeback −Betrag buchen: Rechnung wieder offen; Storno der Zahlung: PaidFC und Flags wie zuvor. +Tracelinks: SyRS-214, SyRS-213 +Konsolidierung: Kandidat: IncomingPayments (SwRS-242) — Zahlungsausgleich existiert doppelt (Zahlungseingangs-Datensätze vs. Bankauszugs-Zuordnungen), beide schreiben über UpdateReceiptIsPaid. +Übernahmewürdigkeit: übernehmen - Chargeback-Sonderregel unbedingt erhalten. +Status: belegt +``` + +### SwRS-248: [HYPOTHESE] Serverseitige Durchsetzung der Kontoauszugs-Rechte + +``` +ID: SwRS-248 +Titel: [HYPOTHESE] Serverseitige Durchsetzung der Kontoauszugs-Rechte (20800147–20800151) +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: Sicherheit +Akteur: OnlineBanking-Modul, AppRightsBL +Vorbedingung: Benutzer ohne Recht VIEW_BANKSTATEMENT/DELETE_BANKSTATEMENT etc. ruft Onlinebanking-Funktionen auf. +Fakt: Die Rechte „Kontoauszüge (anzeigen/löschen/Zuordnung ändern/manuell importieren)" werden per ScriptMethod11560 angelegt (mit TODO-Kommentar „add support for the rights"); in OnlineBankingAccountTransactionsBL wurde keine Prüfung dieser Rechte gefunden; die einzige gefundene Prüfung (CheckForUnknownIbanViewModel.CheckUserRightsAsync) läuft clientseitig gegen CentronCache und betrifft das Bankverbindungs-Anlage-Recht, mit bloßem Hinweisdialog. +Aussage: Das System soll die Kontoauszugs-Rechte serverseitig vor jeder Lese-, Lösch-, Zuordnungs- und Importoperation durchsetzen. (Im Bestand vermutlich nur client-/menüseitig wirksam.) +Ergebnis: Zugriff auf Bankdaten ist auch über direkte Webservice-Aufrufe rechtegeschützt. +Belege: + - [SEKUNDÄR] src\backend\Centron.BL\Administration\Scripts\ScriptMethods\Scripts\ScriptMethod11560.cs (Rechteanlage inkl. „//TODO add support for the rights") - Begründung: Rechte existieren, Durchsetzung als offen markiert. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\OnlineBanking\AccountTransactions\CheckForUnknownIban\CheckForUnknownIbanViewModel.cs, CheckUserRightsAsync (Z. 83–101) - Begründung: gefundene Prüfung ist rein clientseitig und nicht blockierend. +Prüfidee: Benutzer ohne VIEW_BANKSTATEMENT ruft GetOnlineBankingAccountTransactionsByFilter über den Webservice auf; liefert er Daten, ist die Lücke bestätigt. +Tracelinks: SyRS-214, SyRS-218 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Anforderung übernehmen und in der Neuimplementierung zwingend serverseitig umsetzen. +Status: HYPOTHESE +Offene Frage: Existiert eine hier nicht gefundene serverseitige Prüfung (z. B. in einer Webservice-Fassade/Modulfreischaltung), oder sind die Rechte 20800147–20800151 tatsächlich nur UI-wirksam? +``` + +### SwRS-249: Export-Doppelschutz über Portierungsflags + +``` +ID: SwRS-249 +Titel: Export-Doppelschutz über Portierungsflags PORTRECH/PORTWARE +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: BookKeepingExportBL.IsReceiptExported, Exportläufe +Vorbedingung: FiBu-Export wurde für Belege ausgeführt. +Fakt: Kundenbelege werden in PORTRECH, Lieferantenbelege in PORTWARE (jeweils AssetKind + AssetI3D) als exportiert markiert; IsReceiptExported prüft je Belegart gegen die passende Tabelle; die Ladefilter der Exportsichten unterscheiden „transferred" (bereits übertragen) von neuen Datensätzen. +Aussage: Das System soll jeden übergebenen Beleg dauerhaft als exportiert kennzeichnen und Folgeexporte standardmäßig auf noch nicht übertragene Belege beschränken. +Ergebnis: Keine doppelten Buchungen in der FiBu. +Belege: + - [PRIMÄR] src\backend\Centron.BL\DataExchange\BookKeeping\BookKeepingExportBL.cs, IsReceiptExported (Z. 209–226, Kommentare „Lookup in table: PORTRECH/PORTWARE") - Begründung: implementierter Doppelschutz. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, Tabellen PORTRECH (Z. 21673) und PORTWARE (Z. 21698) - Begründung: persistente Flags. +Prüfidee: Rechnung exportieren; IsReceiptExported(InvoiceClass, I3D) muss true liefern und die Rechnung im nächsten „nicht übertragen"-Lauf fehlen. +Tracelinks: SyRS-216 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kennzeichnung um Exportlauf-ID/Zeitstempel erweitern. +Status: belegt +``` + +### SwRS-250: Steuer-Mapping im Buchungsdatenexport + +``` +ID: SwRS-250 +Titel: Steuer-Mapping im Buchungsdatenexport (deaktivierte USt, Kontenrahmen, Zollfälle) +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: BookKeepingExportBL.GetReceiptsBookingdataExportFile +Vorbedingung: Exportkonfiguration mit/ohne ExportTaxThroughAccountSystems; Belege teils ExclusiveOfVAT. +Fakt: Bei ExclusiveOfVAT-Belegen werden Steuersatz/Steuercode/Steuerkonto aus der Default-USt für deaktivierte USt des Landes gesetzt (kundenseitig RevenueAccount, lieferantenseitig ExpenseAccount bzw. PurchaseTaxCode), sonst auf 0/leer; bei ExportTaxThroughAccountSystems wird der Steuercode aus dem BookKeeping-Kontenrahmen je Erlöskonto ermittelt, differenziert nach NeedsCustomClearance (Zoll); Schweizer Rundung (CommercialRoundCH) wird als Setting durchgereicht. +Aussage: Das System soll beim Buchungsdatenexport Steuerkennzeichen und Steuerkonten regelbasiert bestimmen: für steuerbefreite Belege über die Länder-Default-USt, optional über den Kontenrahmen (inkl. Zoll-Differenzierung), und länder­spezifische Rundung berücksichtigen. +Ergebnis: FiBu-Import ohne manuelle Steuerkorrekturen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\DataExchange\BookKeeping\BookKeepingExportBL.cs, GetReceiptsBookingdataExportFile (Z. 443–544, insb. Z. 487–535) - Begründung: vollständige Mapping-Fallunterscheidung. +Prüfidee: Beleg ExclusiveOfVAT exportieren: Positionen tragen TaxCode/TaxAccount der Default-USt des Landes; mit Kontenrahmen-Option: Steuercode folgt dem Erlöskonto. +Tracelinks: SyRS-216 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Regeln sind steuerlich relevant und müssen 1:1 nachvollziehbar bleiben. +Status: belegt +``` + +### SwRS-251: Zählerhistorie mit Monotonieprüfung und Startwerten + +``` +ID: SwRS-251 +Titel: Gerätezähler: Historie mit Alt-/Neuwert, Monotonieprüfung und Startwert-Sonderfall +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: DeviceClickCounterBL +Vorbedingung: Gerätezähler (DeviceClickCounter) existiert; neuer Zählerstand wird erfasst/importiert. +Fakt: Beim automatischen Update wird ein importierter Wert abgelehnt, wenn der aktuelle Zähler höher ist („old counter value is higher as the new one"); jede Änderung erzeugt DeviceClickCounterHistory mit OldState/Newstate, NewStateDate, EditedBy, Reason, IsAutomaticallyImported bzw. IsStartValue; UpdateDeviceClickCounterValues aktualisiert bei Startwert am selben Datum den bestehenden Starteintrag (Reason wird angehängt) und schreibt CurrentCounter nur, wenn der neue Eintrag der zeitlich jüngste ist; nachträglich kann eine Vertragszuordnung auf Alt-Historie (ContractHeaderI3D=0) propagiert werden. +Aussage: Das System soll Zählerstände nur monoton steigend automatisch übernehmen, jede Änderung mit Alt-/Neuwert, Datum, Bearbeiter und Grund historisieren, Startwerte als eigene Einträge führen und den aktuellen Zähler nur aus dem jüngsten Eintrag ableiten. +Ergebnis: Belastbare Zählerhistorie als Abrechnungsgrundlage der Click-Verträge. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\CustomerAssets\Contracts\ClickContracts\DeviceClickCounterBL.cs, GetAndUpdateDeviceClickCounter (Z. 234–270, Monotonieprüfung Z. 250–254) und UpdateDeviceClickCounterValues (Z. 536–599) - Begründung: durchgesetzte Historien- und Monotonieregeln. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, Tabellen DeviceClickCounterImported/DeviceClickCounterImportHistory/DeviceClickCounterTypeMappings (Z. 37035 ff.) - Begründung: Import-/Mappingschema. +Prüfidee: Import 5000 auf Zähler mit CurrentCounter=6000: Ablehnung; manuelle Korrektur mit Grund: Historieneintrag mit OldState=6000. +Tracelinks: SyRS-209 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Monotonieregel zentral; Teil des Codes (Mapping via GetMappingCouterKind) ist tot/deaktiviert und sollte bereinigt spezifiziert werden. +Status: belegt +``` + +### SwRS-252: SEPA-Mandatsdaten — Mandatsreferenz, IBAN-Normierung, Bankverbindungsanlage + +``` +ID: SwRS-252 +Titel: SEPA-Mandatsdaten: Mandatsreferenz-Default, IBAN-Normierung, Bankverbindungsanlage bei Annahme +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: SepaContractOnlinePdfDocumentHandler.Confirm +Vorbedingung: Kunde bestätigt das Mandat online (ggf. mit im Formular erfasster Bankverbindung). +Fakt: Bei Annahme wird die verknüpfte Bankverbindung aktualisiert (Bankname/BIC/IBAN-Overrides, IBAN ohne Leerzeichen gespeichert, ValidFrom=AuthorizationDate=heute) oder — wenn keine verknüpft ist und Bankdaten vorliegen — neu angelegt (Status=1, ObjectI3D=Kunde); fehlt die AuthorizationNumber (Mandatsreferenz), wird sie mit der Objekt-/Kundennummer vorbelegt; die Gläubiger-ID stammt aus Mandator.SepaIdentificationNumber; Dokumentvariablen umfassen @@Mandatsreferenz@@, @@Gläubigeridentifikationsnummer@@, @@Iban@@, @@Bic@@. +Aussage: Das System soll bei Mandatsannahme die Bankverbindung des Kunden konsistent anlegen/aktualisieren (normierte IBAN, Autorisierungsdatum), eine Mandatsreferenz sicherstellen und Gläubiger-ID sowie Mandatsreferenz in das Mandatsdokument einsetzen. +Ergebnis: Lastschriftfähige Bankverbindung mit vollständigen SEPA-Pflichtangaben. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Documents\Dsgvo\SepaContractOnlinePdfDocumentHandler.cs, Confirm (Z. 133–175: BankAccount-Update/-Anlage, `iban?.Replace(" ", "")`, AuthorizationNumber-Default) und GetVariables (Z. 453–490) - Begründung: durchgesetzte Datenregeln. +Prüfidee: Mandat mit IBAN „DE12 3456 …" bestätigen: gespeicherte IBAN ohne Leerzeichen, AuthorizationDate=heute, AuthorizationNumber gefüllt. +Tracelinks: SyRS-217 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Mandatsreferenz-Default (Kundennummer) prüfen: für SEPA muss die Referenz je Mandat eindeutig sein; ggf. Sonderfall des Bestands. +Status: belegt +``` + +### SwRS-253: Kostenstellen und Kostenträger mit Soft-Delete + +``` +ID: SwRS-253 +Titel: Kostenstellen-/Kostenträgerverwaltung mit Soft-Delete und Wiederherstellung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Modul PayersAndCostCenter, CostCenterBL (Warehousing), CustomerCostCenterBL (Accounts) +Vorbedingung: Benutzer öffnet die Kostenstellen-/Kostenträgerverwaltung. +Fakt: Das Modul verwaltet CostCenter und CostObject (UI: „Payers") mit Anlegen, Ändern, Löschen, Anzeige gelöschter Einträge und Wiederherstellen; Löschen setzt State=0 statt physischem Delete (CustomerCostCenterBL.DeleteCustomerCostCenter setzt entity.State=0; Listen filtern State==1); daneben existiert eine zweite, kundenbezogene Kostenstellen-Implementierung CustomerCostCenter. +Aussage: Das System soll Kostenstellen und Kostenträger als Stammdaten mit Soft-Delete (deaktivieren statt löschen) und Wiederherstellung verwalten, sodass historische Belegzuordnungen erhalten bleiben. +Ergebnis: Keine verwaisten Kostenstellenbezüge auf Belegen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Accounts\CustomerCostCenterBL.cs, DeleteCustomerCostCenter (Z. 42–54: State=0) und GetCustomerCostCenterByAccount (Filter State==1) - Begründung: durchgesetztes Soft-Delete. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\PayersAndCostCenter\PayersAndCostCenterAppModuleControllerViewModel.cs (Commands Delete/Restore/ShowDeleted, Z. 55–83) - Begründung: UI-Funktionen inkl. Wiederherstellung. +Prüfidee: Kostenstelle löschen: verschwindet aus aktiver Liste, erscheint unter „gelöschte anzeigen" und ist wiederherstellbar; Belege behalten die Zuordnung. +Tracelinks: SyRS-216, SyRS-207 +Konsolidierung: Kandidat: Centron.BL\Warehousing\CostCenterBL (Tabelle CostCenter) vs. Centron.BL\Accounts\CustomerCostCenterBL (Tabelle CustomerCostCenter) — zwei Datenhaltungen für das Konzept „Kostenstelle" (global vs. kundenbezogen). +Übernahmewürdigkeit: übernehmen - fachlich übernehmen, Datenhaltung konsolidieren. +Status: belegt +``` + +### SwRS-254: Editierschutz abrechnungsrelevanter Zeiten + +``` +ID: SwRS-254 +Titel: Editierschutz für Ticketzeiten: Rechte, Plausibilität, Belegbindung +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: Sicherheit +Akteur: TimerBillingBL.SaveTimer, HelpdeskTimerWebServiceBL +Vorbedingung: Benutzer ändert eine bestehende Helpdesk-Zeit in der Zeitenabrechnung. +Fakt: Vor jeder Änderung wird geprüft: Web-Accounts sind gesperrt; Recht EDIT_TIME erforderlich; mit OWN_TIME_EDIT dürfen nur eigene Zeiten geändert werden (Abgleich über Ersteller bzw. Mitarbeiterartikel); Stop < Start wird mit Fehlermeldung „…negative Dauer…" abgelehnt; Zeiten, die bereits einem Lieferschein, einer Rechnung oder einem Auftrag zugeordnet sind, sind nicht speicherbar (ThrowIfInvalidHelpdeskTimer); beim Splitten wird das Recht am Originaltimer geprüft. +Aussage: Das System soll Änderungen an abrechnungsrelevanten Zeiten nur berechtigten internen Benutzern erlauben, negative Zeitdauern ablehnen und bereits fakturierte/belegte Zeiten unveränderlich halten. +Ergebnis: Abgerechnete Zeiten sind revisionssicher. +Belege: + - [PRIMÄR] src\backend\Centron.BL\WebServices\Sales\Support\HelpdeskTimerWebServiceBL.cs, ThrowIfUserDoesntHaveRightToChangeHelpdeskTimers (Z. 348–376) und ThrowIfInvalidHelpdeskTimer (Z. 327–346) - Begründung: alle Schutzregeln als throw-Bedingungen. + - [PRIMÄR] src\backend\Centron.BL\Sales\CustomerAssets\TimerBilling\TimerBillingBL.cs, SaveTimer (Z. 473–483: Rechtsprüfung + `if (timer.Stop < timer.Start) throw ...`) - Begründung: Aufruf der Prüfung im Abrechnungskontext. +Prüfidee: Zeit mit Rechnungszuordnung ändern: Fehler „…einer Rechnung zugeordnet"; Benutzer mit OWN_TIME_EDIT ändert fremde Zeit: RightCheckFailed. +Tracelinks: SyRS-210, SyRS-218 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - vollständige Regelkette übernehmen. +Status: belegt +``` + +### SwRS-255: Gutschein-Lebenszyklus über Rechnungspositionen + +``` +ID: SwRS-255 +Titel: Gutschein-Lebenszyklus frei → ausgegeben → eingelöst über Rechnungspositionen +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: VoucherManagementBL, Kassen-/Rechnungsprozess +Vorbedingung: Gutscheinartikel (Warengruppe aus Stammdat I3D 1473) mit Barcodes existieren. +Fakt: Die Gutscheinliste wird über die NamedQuery VoucherManagementGetVoucherArticles ermittelt: Ausgabe = Verknüpfung GutscheinZuRechnung.AktivierungRechPosI3D → RechPos/RechKopf (liefert Ausgabedatum, Rechnungsnummer, Preis), Einlösung = EingeloestRechPosI3D; Filter unterscheiden frei (keine Aktivierung/Einlösung), ausgegeben, eingelöst. +Aussage: Das System soll den Status jedes Gutschein-Barcodes (frei, ausgegeben, eingelöst) ausschließlich aus den verknüpften Rechnungspositionen von Ausgabe- und Einlösungsbeleg ableiten und filterbar auswerten. +Ergebnis: Gutscheinbestand und -verbindlichkeiten sind belegbasiert nachvollziehbar. +Belege: + - [PRIMÄR] src\backend\Centron.DAO\NamedQueries\NamedQueryPool.xml, NamedQuery „VoucherManagementGetVoucherArticles" (Z. 680–709: Joins auf GutscheinZuRechnung/RechPos/RechKopf, Filterbedingungen) - Begründung: implementierte Statusableitung. + - [SEKUNDÄR] src\backend\Centron.BL\VoucherManagement\VoucherManagementBL.cs, GetActivedVoucherBarcodes (Z. 17–25) - Begründung: fachliche Filterschnittstelle (frei/ausgegeben/eingelöst). +Prüfidee: Gutschein verkaufen (Aktivierungs-Rechnungsposition): Status „ausgegeben" mit Rechnungsnummer; später einlösen: Status „eingelöst". +Tracelinks: SyRS-211, SyRS-216 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Modul ist reine Auswertung; Verkaufs-/Einlöselogik liegt im Belegwesen und ist dort zu spezifizieren. +Status: belegt +``` + +## A3 — Vertrieb & Belegwesen: SwRS (Software-Anforderungen) + +### SwRS-330: Beleg-Statusdomäne als Enum ReceiptState + +``` +ID: SwRS-330 +Titel: Beleg-Statusdomäne als Enum ReceiptState +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente Centron.Interfaces (ReceiptState); alle Beleg-BLs +Vorbedingung: — +Fakt: Das Enum ReceiptState definiert genau Active=1 („offen"), Completed=2 („abgeschlossen"), Canceled=3 („storniert"); RechKopf.Status persistiert den Wert (int, mit Clustered Index ixRechKopf_Status). +Aussage: Das System soll den Belegstatus als geschlossene Wertemenge {offen=1, abgeschlossen=2, storniert=3} modellieren und persistieren. +Ergebnis: Einheitliche Statuswerte über alle Belegarten; performante Statusfilterung. +Belege: + - [PRIMÄR] src\backend\Centron.Interfaces\Sales\Receipts\ReceiptState.cs (Enum mit Description-Attributen) - Begründung: Typdefinition erzwingt Wertemenge. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, dbo.RechKopf Spalte [Status] [int] und Index ixRechKopf_Status (Zeile 3395) - Begründung: Persistenz und Indexierung. +Prüfidee: Unit-Test: GetReceiptStateString() liefert für jeden Enumwert den deutschen Text; ungültiger Wert wirft ArgumentOutOfRangeException. +Tracelinks: SyRS-311 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - minimales, klares Statusmodell. +Status: belegt +``` + +### SwRS-331: Weiterverarbeitungsmatrix je Belegart in den SpecificLogics + +``` +ID: SwRS-331 +Titel: Weiterverarbeitungsmatrix je Belegart in den SpecificLogics +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponenten OfferSpecificLogic, OrderSpecificLogic, DeliveryListSpecificLogic, InvoiceSpecificLogic, CreditVoucherSpecificLogic +Vorbedingung: Quellbeleg mit bekannter Belegart. +Fakt: CanBeForwardedInto() liefert je Belegart eine feste Zielmenge: Angebot→{Auftrag, Lieferschein, Rechnung}; Auftrag→{Lieferschein, Rechnung, Vertrag}; Lieferschein→{Abholschein, Rechnung}; Rechnung→{Gutschrift}; Gutschrift→{} (leer). +Aussage: Das System soll die zulässigen Folgebelegarten je Belegart als feste, zentral definierte Matrix bereitstellen (Angebot→Auftrag/Lieferschein/Rechnung, Auftrag→Lieferschein/Rechnung/Vertrag, Lieferschein→Abholschein/Rechnung, Rechnung→Gutschrift, Gutschrift→keine). +Ergebnis: Eindeutige, testbare Belegkettenregeln. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Offers\OfferSpecificLogic.cs Zeile 314, Orders\OrderSpecificLogic.cs Zeile 257, DeliveryLists\DeliveryListSpecificLogic.cs Zeile 258, Invoices\InvoiceSpecificLogic.cs Zeile 280, CreditVouchers\CreditVoucherSpecificLogic.cs Zeile 268 (jeweils Methode CanBeForwardedInto()) - Begründung: die Arrays sind die durchgesetzte Matrix. +Prüfidee: Für jede Belegart CanBeForwardedInto() aufrufen und gegen die dokumentierte Matrix vergleichen; ForwardReceipt auf nicht enthaltene Zielart → Fehler. +Tracelinks: SyRS-310 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Matrix als Konfiguration/Policy in Neuimplementierung abbilden. +Status: belegt +``` + +### SwRS-332: Validierungen bei der Belegweiterverarbeitung + +``` +ID: SwRS-332 +Titel: Validierungen bei der Belegweiterverarbeitung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente ReceiptBL.ValidateReceiptForwarding +Vorbedingung: ForwardReceipt wurde mit ≥1 Quellbeleg aufgerufen. +Fakt: ValidateReceiptForwarding() lehnt ab bzw. fordert Bestätigung: Mischung von Kunden- und Lieferantenbelegen (Fehler), Quellbelege unterschiedlicher Kunden (Fehler „Die Belege sind von unterschiedlichen Kunden."), unterschiedliche Empfänger/Adressen/Ansprechpartner (Dialog), Lieferschein zu Auftrag mit Anzahlungsrechnungen (Warn-Dialog), Positionen mit unkonvertierten „Neu"/„Extern"-Artikeln bei Ziel Rechnung/Lieferschein/Gutschrift (Warn-Dialog). +Aussage: Das System soll bei der Weiterverarbeitung mehrere Quellbelege nur bei gleichem Kunden und gleicher Belegsphäre (Kunde vs. Lieferant) zusammenführen und definierte Risikofälle (abweichende Empfänger, Anzahlungskontext, unkonvertierte Artikel) vor dem Erzeugen des Folgebelegs zur Bestätigung vorlegen. +Ergebnis: Kein fachlich inkonsistenter Sammel-Folgebeleg. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, Methode ValidateReceiptForwarding() (Zeile 2462 ff.; Prüfungen und Meldungstexte wie zitiert) - Begründung: durchsetzende Validierungskaskade. +Prüfidee: Zwei Lieferscheine verschiedener Kunden gemeinsam in Rechnung weiterverarbeiten → Fehler; Lieferschein aus Auftrag mit Anzahlungsrechnung → Warnhinweis erscheint. +Tracelinks: SyRS-310 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Prüfkaskade fachlich begründet. +Status: belegt +``` + +### SwRS-333: Datenübernahme und Neunummerierung beim Erzeugen des Folgebelegs + +``` +ID: SwRS-333 +Titel: Datenübernahme und Neunummerierung beim Erzeugen des Folgebelegs +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente ReceiptBL.ForwardReceipt +Vorbedingung: Weiterverarbeitung validiert (SwRS-332). +Fakt: ForwardReceipt() übernimmt vom ersten Quellbeleg Kunde/Adresse/Ansprechpartner, Empfänger (nur wenn kein alternativer Empfänger verwendet wurde bzw. AlwaysTakeReceiverFromOriginReceipt), ExclusiveOfVAT, Währung (CurrencyI3D/-Factor/-String), Land und — bei genau einem Quellbeleg — Filiale/BranchOrigin; anschließend wird über UpdateReceiptNumber() eine Nummer aus dem Nummernkreis der Ziel-Belegart gezogen. +Aussage: Das System soll beim Erzeugen eines Folgebelegs die identitäts- und steuerrelevanten Kopfdaten des Quellbelegs übernehmen (Kunde, Empfängerlogik, Währung, Steuerbefreiung, Land, Filiale) und dem Folgebeleg eine neue Nummer aus dem Nummernkreis der Zielbelegart zuweisen. +Ergebnis: Folgebeleg mit konsistenten Kopfdaten und eigener Belegnummer. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, ForwardReceipt() Zeilen 1576–1650 (Kopfdatenübernahme; `this.UpdateReceiptNumber(createReceiptResult.Data.Receipt, updateDatabase: false)` Zeile 1643) - Begründung: implementierte Übernahme- und Nummernlogik. +Prüfidee: Auftrag in Fremdwährung weiterverarbeiten → Rechnung trägt gleiche Währung/Faktor, aber neue Nummer aus dem Rechnungs-Nummernkreis. +Tracelinks: SyRS-310, SyRS-312 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Übernahmeregeln explizit dokumentieren (Empfängerlogik ist subtil, siehe Quellcode-Kommentare). +Status: belegt +``` + +### SwRS-334: Nebenläufigkeitssichere Nummernvergabe mit Kollisionsvermeidung + +``` +ID: SwRS-334 +Titel: Nebenläufigkeitssichere Nummernvergabe mit Kollisionsvermeidung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente NumberGroupBL +Vorbedingung: NumberGroup-Datensatz (Tabelle Nummernkreis) für die Belegart existiert. +Fakt: GetNextNumber() liest den Nummernkreis frisch (Session.Refresh), berechnet Kandidat = Aktuell + Intervall, überspringt per COUNT(*)-Abfrage bereits in der Zieltabelle vorhandene Nummern (FindNextNumber) und schreibt Current per bedingtem UPDATE (`WHERE I3D = ... AND Current = `); schlägt das UPDATE fehl (0 Zeilen), wird der Vorgang wiederholt; Sonderfälle Kunde/Lieferant prüfen zusätzlich Kunden-/Kreditor-Tabelle. +Aussage: Das System soll die nächste Belegnummer atomar reservieren (optimistische Konkurrenzkontrolle mit Wiederholung) und dabei bereits verwendete Nummern der Zieltabelle überspringen. +Ergebnis: Keine doppelt vergebenen Belegnummern, auch bei parallelen Speichervorgängen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Company\NumberGroupBL.cs, Methoden GetNextNumber() (Zeilen 62–92, while(true) + rowCountChanged==1) und FindNextNumber() (Zeilen 94–134) - Begründung: die Schleife mit bedingtem UPDATE ist die durchsetzende Konkurrenzsicherung. +Prüfidee: Lasttest: 100 parallele Nummernanforderungen für denselben Kreis → 100 unterschiedliche Nummern; manuell belegte Nummer im Zielbereich wird übersprungen. +Tracelinks: SyRS-312 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - Ziel erreichbar, aber COUNT(*)-Polling und String-SQL sind Behelf; in SaaS durch sequenzbasierte, transaktionale Vergabe ersetzen. +Status: belegt +``` + +### SwRS-335: Eigener Nummernkreis „Interne Rechnung" für 0,00-€-Dienstleistungsrechnungen + +``` +ID: SwRS-335 +Titel: Eigener Nummernkreis „Interne Rechnung" für 0,00-€-Dienstleistungsrechnungen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente InvoiceSpecificLogic.GetNumberGroup +Vorbedingung: Rechnung wird gespeichert; Nummernkreis InternalInvoice ist mit Startwert gepflegt. +Fakt: GetNumberGroup() wählt: Barrechnung → CashInvoice; keine Artikelpositionen → Invoice; bestehen alle Artikelpositionen aus Dienstleistungsartikeln und ist der Netto-Gesamtpreis 0, wird — sofern der Kreis InternalInvoice konfiguriert ist (Current > 0) — der Kreis InternalInvoice verwendet; sonst Invoice. Die Nummer wird deshalb erst nach den positionsverändernden Update-Schritten gezogen (Kommentar „The new number group for 0,00 invoices is dependent on the positions"). +Aussage: Das System soll Rechnungen, die ausschließlich Dienstleistungspositionen mit Gesamtwert 0,00 enthalten, aus einem separaten Nummernkreis „Interne Rechnung" nummerieren, sofern dieser konfiguriert ist. +Ergebnis: Interne Nullrechnungen verbrauchen keine offiziellen Rechnungsnummern. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\InvoiceSpecificLogic.cs, Methode GetNumberGroup() (Zeilen 104–140) - Begründung: vollständige Auswahllogik im Code. + - [SEKUNDÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, SaveReceipt-Kommentar zur Positionsabhängigkeit der Nummernvergabe (UPDATE REGION 1) - Begründung: Ablaufreihenfolge. +Prüfidee: Rechnung nur mit Dienstleistungsartikel, Preis 0 speichern → Nummer aus Kreis InternalInvoice; gleiche Rechnung mit Preis > 0 → Kreis Invoice. +Tracelinks: SyRS-312 +Konsolidierung: nein +Übernahmewürdigkeit: Sonderfall - betriebsspezifische Konvention (interne Verrechnung); Übernahme nur bei Bedarf. +Status: belegt +``` + +### SwRS-336: MwSt-Splitting und Rundungsregeln der Belegsummen + +``` +ID: SwRS-336 +Titel: MwSt-Splitting und Rundungsregeln der Belegsummen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente ReceiptPriceHelper (statisch), ReceiptPriceHelperBL +Vorbedingung: Beleg mit Positionen (Kind Article/CustomerDiscount, PositionKind Default/Cargo, nicht expandierte Stücklisten). +Fakt: Je Position: Einzel-Netto = Round(BasePrice×Währungsfaktor, precision, AwayFromZero) × (100−Rabatt)/100, erneut gerundet; precision = −1 unterdrückt Einzelpreisrundung; Positionssumme = Round(Netto × (Menge−verarbeitete Menge), 2, AwayFromZero); Steuer je Position = Netto × Steuersatz/100 (Barbeleg: brutto-basiert und je Position auf 2 NK gerundet); Belegsteuer = Round(Summe der Positionssteuern je Steuersatzgruppe, 2, AwayFromZero); bei aktivem CH-Schalter wird die Steuersumme so korrigiert, dass Brutto auf 0,05 endet; skonto-ausgeschlossene Positionen werden als NotDiscountable-Summen separat geführt. +Aussage: Das System soll Belegsummen positionsweise mit konfigurierbarer Preisgenauigkeit berechnen, die Mehrwertsteuer je Steuersatzgruppe auf 2 Nachkommastellen (AwayFromZero) runden, für Barbelege die Steuer bruttobasiert je Position runden und optional Schweizer 5-Rappen-Rundung auf den Bruttobetrag anwenden. +Ergebnis: Rechnerisch reproduzierbare Beleg-, Steuer- und Skontobasis-Summen. +Belege: + - [PRIMÄR] src\webservice\Centron.WebServices.Core\Helper\ReceiptPriceHelper.cs, Methoden CalculateNetPrice()/CalculateNetTotalPrice()/CalculateTaxPrice()/CalculateTaxPriceTotal()/CalculateReceiptVatPrices()/CalculateReceiptPrices() (Zeilen 20–256) - Begründung: alle Rundungs- und Summierungsregeln. + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptPriceHelperBL.cs, Zeile 40 (AppSettingsConst.CommercialRoundCH) - Begründung: Aktivierung der CH-Rundung. +Prüfidee: Testfälle: precision=2 vs. −1; Barbeleg vs. Zielrechnung mit identischen Positionen (unterschiedliche Steuerrundung); CH-Rundung: Brutto 100,02 → 100,00, Steuer entsprechend reduziert. +Tracelinks: SyRS-313 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Regeln vollständig; Positionsfilter (Cargo, Expanded) mitdokumentieren. +Status: belegt +``` + +### SwRS-337: MwSt-Pflichtprüfungen beim Belegspeichern + +``` +ID: SwRS-337 +Titel: MwSt-Pflichtprüfungen beim Belegspeichern +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente ReceiptBL.SaveReceipt (Prüfkaskade) +Vorbedingung: Beleg wird gespeichert. +Fakt: CheckIfAllArticlePositionsHaveVatRate() bricht das Speichern ab, wenn eine Artikel-/Rabattposition keinen MwSt-Verweis (VATI3D null/≤0) hat; CheckIfExclusiveOfVatInInland() verbietet steuerfreie Inlandsbelege ohne Umsatzsteuer-Ident-Nr., wenn die CRM-Einstellung IsVATNumberForEUMemberStatedsMandatory aktiv ist („Bei Kunden ohne Umsatzsteuer-Ident-Nr muss die Mehrwertsteuer im Inland ausgewiesen werden."). +Aussage: Das System soll Belege nur speichern, wenn jede Artikelposition einen Mehrwertsteuersatz trägt, und steuerbefreite Belege an Inlandskunden nur bei vorhandener USt-IdNr. zulassen (konfigurationsabhängig). +Ergebnis: Keine Belege mit unvollständigen oder unzulässigen Steuerangaben. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, Methoden CheckIfAllArticlePositionsHaveVatRate() und CheckIfExclusiveOfVatInInland() (SaveReceipt-Prüfkaskade, Aufrufe Zeilen 3721 ff.) - Begründung: abbruchwirksame Validierungen. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, dbo.RechPos Spalten [MwstSatz], [MwstI3D] (Zeilen 12151/12169) - Begründung: Steuerfelder je Position. +Prüfidee: Position ohne MwSt-Zuordnung speichern → Fehlermeldung mit Artikelcode; ExclusiveOfVAT-Beleg an Inlandskunde ohne UStID bei aktiver Einstellung → Ablehnung. +Tracelinks: SyRS-313 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - steuerrechtlich notwendige Validierungen. +Status: belegt +``` + +### SwRS-338: Stornoregeln für Rechnungen + +``` +ID: SwRS-338 +Titel: Stornoregeln für Rechnungen +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente ReceiptInvoiceBL.CancelInvoice; Benutzer mit Storno-Recht +Vorbedingung: Rechnung existiert und ist nicht festgeschrieben-exportiert. +Fakt: CancelInvoice() prüft in dieser Reihenfolge: Rechnung existiert; Benutzerrecht RIGHT_RECHNUNGSTORNIEREN (Konstante 20400101); nicht bereits storniert; keine Barrechnung; nicht weiterverarbeitet (GetReceiptForwardedInto leer); nicht FiBu-exportiert (BookKeepingExportBL.IsReceiptExported); bei Vertragsrechnungen nur die zuletzt erstellte. Der Storno erzeugt eine neue Version, setzt QuantityComplete=0 und löscht Barcodes aller Artikel-/Rabattpositionen, setzt State=Canceled, schreibt einen ReceiptLog-Eintrag und setzt Vertrag/Timer in derselben Transaktion zurück. +Aussage: Das System soll Rechnungsstornos nur für berechtigte Benutzer und nur für noch nicht stornierte, nicht bar bezahlte, nicht weiterverarbeitete und nicht exportierte Rechnungen zulassen; der Storno erfolgt als neue Belegversion mit genullten Mengen, Statuswechsel auf „storniert", Protokolleintrag und Rücksetzung abhängiger Objekte (Vertrag, Timer) in einer Transaktion. +Ergebnis: Konsistenter, berechtigter, protokollierter Rechnungsstorno. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\ReceiptInvoiceBL.cs, Methode CancelInvoice() (Zeilen 143–206; Rechteprüfung `currentUser.HasUserRight(UserRightsConst.RIGHT_RECHNUNGSTORNIEREN) == false` Zeile 154) - Begründung: alle Regeln sind hier durchgesetzt. + - [SEKUNDÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptLogBL.cs Zeile 124 (Storno-Logtext) - Begründung: Protokollierung. + - [KONTEXT] src\webservice\Centron.WebServices.Core\EntitiesWrongPlace\Administration\Rights\UserRightsConst.cs Zeile 590 (RIGHT_RECHNUNGSTORNIEREN = 20400101) - Begründung: Rechtekonstante. +Prüfidee: Jede Sperrbedingung einzeln herstellen und CancelInvoice aufrufen → jeweilige Fehlermeldung; Erfolgsfall: neue Version mit State=Canceled, Mengen 0, Logeintrag vorhanden. +Tracelinks: SyRS-314 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Regelwerk vollständig; Fehlermeldungen als Fachregeln übernehmen. +Status: belegt +``` + +### SwRS-339: Rechnungsfestschreibung mit Protokollierung + +``` +ID: SwRS-339 +Titel: Rechnungsfestschreibung mit Protokollierung +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente ReceiptInvoiceBL.FixInvoice; Buchhaltung +Vorbedingung: Rechnung ist noch nicht festgeschrieben (CheckIfInvoiceIsFixed). +Fakt: FixInvoice() prüft den IsFixed-Status, setzt in einer Transaktion per SQL `UPDATE RechKopf SET IsFixed = 1 WHERE I3D = @I3D` und schreibt einen ReceiptLog-Eintrag (ReceiptLogKind.FixedState) mit Zeitpunkt und Mitarbeiter („Die Rechnung wurde am ... von ... festgeschrieben."); RechKopf.IsFixed ist NOT NULL (bit). +Aussage: Das System soll Rechnungen einmalig festschreiben können; die Festschreibung ist idempotent abgesichert (erneutes Festschreiben wird abgelehnt), transaktional und wird mit Benutzer und Zeitpunkt protokolliert. +Ergebnis: Festgeschriebene Rechnungen sind als unveränderlich gekennzeichnet und der Vorgang ist auditierbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\ReceiptInvoiceBL.cs, Methoden FixInvoice() (Zeilen 86–141) und CheckIfInvoiceIsFixed() (Zeile 273) - Begründung: durchgesetzte Festschreibelogik. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, dbo.RechKopf [IsFixed] [bit] NOT NULL (Zeile 3374) - Begründung: Persistenz des Kennzeichens. +Prüfidee: Rechnung zweimal festschreiben → zweiter Aufruf liefert Fehler; ReceiptLog enthält FixedState-Eintrag mit Mitarbeiter. +Tracelinks: SyRS-314 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - notwendig für GoBD-konforme Neuimplementierung; Schreibschutz nach Festschreibung sollte dort zusätzlich zentral erzwungen werden (siehe Selbstbewertung). +Status: belegt +``` + +### SwRS-340: Belegart-spezifische Rechteprüfungen inkl. Filialbindung und Web-Login-Sperre + +``` +ID: SwRS-340 +Titel: Belegart-spezifische Rechteprüfungen inkl. Filialbindung und Web-Login-Sperre +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponenten ReceiptBL, *SpecificLogic, AppRightsBL +Vorbedingung: Benutzerkontext (AppUser/LoggedInUser) vorhanden. +Fakt: Jede SpecificLogic implementiert HasRightToCreateANewReceipt/…OnlyOwnBranch/HasRightToEditReceipt/…OnlyOwnBranch/HasRightToViewReceipt gegen belegartspezifische Konstanten (z. B. Offer.CREATE_NEW_OFFER, Offer.EDIT_OFFER_ONLY_OWN_BRANCH, Invoice.SHOW_INVOICES); ReceiptBL.CanUserEditReceipt() lehnt ohne Recht mit DefaultMessageCodes.RightCheckFailed ab und vergleicht bei „nur eigene Filiale" BranchI3D des Benutzers mit dem des Belegs (BranchBL.IsBranchEqual); CanUserViewReceipt() blockt Web-Account-Logins generell („Web-Benutzer haben keine Berechtigung Belege einzusehen."); zusätzlich existieren Feld-Rechte wie HasRightToChangePurchasePrice/HasRightToChangeSellPrice. +Aussage: Das System soll je Belegart getrennte Rechte für Anlegen, Bearbeiten und Ansehen prüfen, „nur eigene Filiale"-Varianten über den Filialvergleich durchsetzen, Web-Logins vom Belegzugriff ausschließen und sensible Feldänderungen (EK-/VK-Preis) an eigene Rechte binden. +Ergebnis: Serverseitig erzwungene, feingranulare Zugriffskontrolle im Belegwesen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, Methoden CanUserEditReceipt() (Zeile 10273 ff.), CanUserViewReceipt() (Zeile 10297 ff., Web-Login-Sperre), CanUserCreateReceiptsInBranch() (Zeile 10251 ff.) - Begründung: zentrale durchsetzende Prüfungen mit konkreten Bedingungen. + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Offers\OfferSpecificLogic.cs Zeilen 480–501 und Invoices\InvoiceSpecificLogic.cs Zeilen 521–541 (Rechtekonstanten UserRightsConst.Sales.Customer.CustomerCommon.*) - Begründung: belegartspezifische Rechtezuordnung. + - [KONTEXT] CentronRights.md - Begründung: Rechtekatalog. +Prüfidee: Matrix-Test: je Belegart × Recht (create/edit/view, ±OnlyOwnBranch) mit passendem/fehlendem Recht; Web-Account-Login versucht Belegabruf → RightCheckFailed. +Tracelinks: SyRS-315 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Rechtestruktur 1:1 als Rollen-/Scope-Modell übertragbar. +Status: belegt +``` + +### SwRS-341: Mahnstufen-Statusmaschine und Neuanlagesperre ab Mahnstufe + +``` +ID: SwRS-341 +Titel: Mahnstufen-Statusmaschine und Neuanlagesperre ab Mahnstufe +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponenten DunningRunBL, ReceiptBL, OrderSpecificLogic +Vorbedingung: Fällige, offene Rechnung bzw. Neuanlage eines Kundenbelegs. +Fakt: ExecuteDunningRun() erhöht je Rechnung die Mahnstufe strikt sequenziell None→Level1→Level2→Level3 und setzt dabei DunningLevelXDate und DunningLevelXEmployee; ResetDunningRun() kann einen Lauf zurücksetzen. Bei der Belegneuanlage liefert BlockNewReceiptsDunningLevel() den kundenindividuellen Sperrwert (CustomerDetail.OrderLockAfterDunning), und CanUserCreateNewReceiptsAtCustomerOrSupplier() lehnt ab, wenn die aktuelle Mahnstufe des Kunden ≥ Sperrwert ist. +Aussage: Das System soll Mahnstufen je Rechnung nur einstufig aufsteigend mit Datum und Bearbeiter fortschreiben und die Neuanlage von Kundenbelegen ab der kundenindividuell konfigurierten Mahnstufe verweigern. +Ergebnis: Kontrollierte Eskalation; automatische Auftragssperre säumiger Kunden. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\Dunning\DunningRunBL.cs (Zeilen 253–268, switch DunningLevel) - Begründung: Statusmaschine. + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, CanUserCreateNewReceiptsAtCustomerOrSupplier() (Zeilen 10205–10216, `dunningLevel >= blockOnLevel` → Fehler) und src\backend\Centron.BL\Sales\Receipts\Orders\OrderSpecificLogic.cs, BlockNewReceiptsDunningLevel() (Zeile 687, OrderLockAfterDunning) - Begründung: durchgesetzte Sperre. +Prüfidee: Kunde mit OrderLockAfterDunning=2: bei Mahnstufe 1 Auftrag anlegbar, bei Stufe 2 Fehler; Mahnlauf zweimal ausführen → Stufen 1 und 2 mit korrekten Datums-/Bearbeiterfeldern. +Tracelinks: SyRS-316 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - dreistufiges Mahnwesen ist Marktstandard; Stufenanzahl ggf. konfigurierbar machen. +Status: belegt +``` + +### SwRS-342: Kreditlimitprüfung über alle offenen Belege beim Speichern + +``` +ID: SwRS-342 +Titel: Kreditlimitprüfung über alle offenen Belege beim Speichern +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente ReceiptBL.CheckIfCustomerLimitIsReached +Vorbedingung: Kundenbeleg wird gespeichert; Kunde hat CreditLimit > 0 und CreditLimitCalculationKind ∈ {netto, brutto}. +Fakt: Die Prüfung summiert den Limitverbrauch aller Belegarten, die an der Limitrechnung teilnehmen (SpecificLogics.TakesPlaceInLimitCalculation/GetUsedLimitAmount), zieht den Verbrauch der Vorversion ab, vergleicht den Beleg gegen das freie Limit und zeigt bei Überschreitung einen Dialog mit Limit, Überschreitungsbetrag und Verbrauch je Belegart; mit SaveAlthoughCustomerLimitExceeded kann bestätigt gespeichert werden; CreditLimitCalculationKind==2 deaktiviert die Prüfung. +Aussage: Das System soll beim Speichern von Kundenbelegen den kumulierten Limitverbrauch (netto oder brutto, konfigurierbar je Kunde) gegen das Kreditlimit prüfen und Überschreitungen nur nach expliziter Bestätigung zulassen. +Ergebnis: Transparente Kreditlimit-Warnung mit Übersteuerungsmöglichkeit. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, Methode CheckIfCustomerLimitIsReached() (vollständige Berechnungs- und Dialoglogik inkl. `limitUsedInThisReceipt > limitAvailable`) - Begründung: durchgesetzte Limitprüfung. +Prüfidee: Kunde mit Limit 1.000 netto und offenem Auftrag über 800: Rechnung über 300 speichern → Dialog mit Überschreitung 100; Bestätigung speichert. +Tracelinks: SyRS-316 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Warn- statt Hartsperre ist bewusste Fachentscheidung (dokumentieren). +Status: belegt +``` + +### SwRS-343: Versionierung von Belegen mit Sperr- und Konsistenzprüfungen + +``` +ID: SwRS-343 +Titel: Versionierung von Belegen mit Sperr- und Konsistenzprüfungen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente ReceiptBL.CreateNewVersion +Vorbedingung: Beleg existiert; Benutzer hat Bearbeitungsrecht (SwRS-340). +Fakt: CreateNewVersion() prüft Bearbeitungsrecht (CanUserEditReceipt), erwirbt einen Bearbeitungs-Lock (TryLockReceipt; fremde Locks nur mit explizitem Override lösbar), verweigert das Zurückspringen auf ältere Versionen, wenn in der aktuellen Version aktive Seriennummern existieren oder die aktuelle Version bereits weiterverarbeitet wurde, und inkrementiert die Versionsnummer (Version+1); Währungsfaktor, Bearbeiter und Ansprechpartner werden aktualisiert. +Aussage: Das System soll Beleg-Änderungen ausschließlich als neue Version unter exklusiver Bearbeitungssperre zulassen und das Wiederherstellen älterer Versionen verweigern, solange aktive Seriennummern bestehen oder der Beleg bereits weiterverarbeitet wurde. +Ergebnis: Widerspruchsfreie Versionshistorie; keine konkurrierenden Änderungen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, Methode CreateNewVersion() (Zeilen 3068–3160; Meldungen „...Seriennummern aktiv." / „...bereits weiterverarbeitet.") - Begründung: alle Prüfungen im Code sichtbar. +Prüfidee: Beleg von zweitem Benutzer sperren lassen und CreateNewVersion aufrufen → Lock-Meldung; Version n−1 wiederherstellen, während Version n weiterverarbeitet wurde → Ablehnung. +Tracelinks: SyRS-311 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Pessimistisches Locking in SaaS ggf. durch optimistische Verfahren ersetzen, Regeln bleiben gültig. +Status: belegt +``` + +### SwRS-344: Automatischer Belegabschluss anhand der Restmengenregel + +``` +ID: SwRS-344 +Titel: Automatischer Belegabschluss anhand der Restmengenregel +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente AutomaticallyCloseReceiptHelperBL +Vorbedingung: Beleg wird gespeichert oder ein Ursprungsbeleg wird durch Weiterverarbeitung aktualisiert. +Fakt: Eine Position gilt als erledigt, wenn Restmenge (QuantityComplete−QuantityProcessed, gerundet auf 7 NK) ≤ 0 ist oder die Position Kundenrabatt, Fracht-/Versicherungs-Sonderposition, Kontingent-Bilanzposition oder Rundungsausgleichsartikel ist; sind alle Positionen erledigt und der Beleg „offen", wird er automatisch „abgeschlossen"; hat ein abgeschlossener Beleg wieder Restmengen, wird er automatisch geöffnet; belegartspezifische Logiken können die Automatik abschalten oder ersetzen (CanBeAutomaticallyClosed/CustomAutomaticallyCloseReceiptLogic). +Aussage: Das System soll Belege automatisch abschließen, sobald alle relevanten Positionen vollständig verarbeitet sind (Sonderpositionen zählen stets als erledigt; auch negative Restmengen schließen), und bei erneut offenen Restmengen automatisch wieder öffnen. +Ergebnis: Statusführung ohne manuelle Pflege; korrekte Anzeige offener Belege. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Internal\AutomaticallyCloseReceiptHelperBL.cs, Methoden ItemIsFinished()/TryAutomaticallyCloseReceipt()/TryAutomaticallyOpenReceipt() (Zeilen 36–103) - Begründung: vollständige Regeldefinition. +Prüfidee: Auftrag mit 2 Positionen teilweise liefern → offen; Rest liefern → automatisch abgeschlossen; Folgebeleg stornieren/Menge reduzieren → wieder offen. +Tracelinks: SyRS-311 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - inkl. dokumentiertem Sonderfall negativer Mengen (Kommentar SKA 2023-01-03). +Status: belegt +``` + +### SwRS-345: Preisfindungshierarchie in GetBasePrice inkl. Preislisten VK1–VK4 + +``` +ID: SwRS-345 +Titel: Preisfindungshierarchie in GetBasePrice inkl. Preislisten VK1–VK4 +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente ReceiptItemPriceBL +Vorbedingung: Artikel mit VK1–VK4/EK; optional Kunde, Vertrag, Sondervereinbarung, Menge. +Fakt: GetBasePrice() startet mit dem Preislisten-VK (GetSellPriceForCustomer: Customer.PriceList 0→VK1 … 3→VK4; bei Firmengruppen-Kunden zählt die Preisliste des Gruppenkunden, ermittelt über UseSettingsFromCompanyGroupForReceipts); dann in fester Reihenfolge: prozentualer Sondervereinbarungs-Rabatt (EKVKReduction), Vertragssonderpreis (ContractSpecialPriceKind × fix/prozentual, Vorzeichen invertiert), sonst Kundensonderpreis, sonst Staffelpreis (ArticleVolumePricesBL nach Menge, sofern UseVolumePrice für den Vertrag erlaubt); Fixrabatte werden am Ende in Prozentrabatt umgerechnet (Division nur bei basePrice≠0); der EK kommt aus GetPurchaseBasePrice() (Sondervereinbarungs-EK, Lager-EK bei aktivem Nebenlager-EK-Setting, Staffel-EK, EK-Reduktionsfaktor, Währungsfaktor). +Aussage: Das System soll den Positions-Verkaufspreis deterministisch aus Kundenpreisliste (VK1–VK4, Firmengruppenlogik) und der Prioritätsfolge Vertragssonderpreis → Kundensonderpreis → Staffelpreis ableiten und den Einkaufspreis analog (Sondervereinbarung, Lager, Staffel, Währung) bestimmen. +Ergebnis: Reproduzierbarer VK/EK je Position als Basis für Marge und Mindestpreisprüfung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Internal\ReceiptItemPriceBL.cs, Methoden GetBasePrice() (Zeile 154 ff.), GetSellPriceForCustomer() (Zeilen 468–497, switch priceList) und GetPurchaseBasePrice() (Zeile 307 ff.) - Begründung: vollständige Ableitungslogik. + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, Methode GetCompanyGroupCustomerI3DForReceiptData() (SQL auf Accounts.UseSettingsFromCompanyGroupForReceipts) - Begründung: Firmengruppenregel. +Prüfidee: Testmatrix: Kunde Preisliste 3 ohne Sonderpreise → VK4; plus Vertragssonderpreis fix → Fixpreis; plus Staffelmenge ohne Sonderpreis → Staffel-VK der Preisliste. +Tracelinks: SyRS-317 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Hierarchie explizit als Preisfindungs-Pipeline spezifizieren. +Status: belegt +``` + +### SwRS-346: Auflösung von Kundensonderpreisen (Priorität und Gültigkeit) + +``` +ID: SwRS-346 +Titel: Auflösung von Kundensonderpreisen (Priorität und Gültigkeit) +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente ReceiptItemPriceBL.GetSpecialPrice; Tabelle KundenSonderpreise +Vorbedingung: Kunde mit gepflegten Sonderpreisen (Adressstamm). +Fakt: GetSpecialPrice() filtert Sonderpreise auf Gültigkeit (GiltVon/GiltBis, tagesgenau) und wählt mit Priorität: 1) Artikel-Sonderpreis, 2) Warengruppe+Unterwarengruppe, 3) nur Warengruppe; die Preisbasis (Spalte Basis → SpecialPriceKind) unterscheidet Aufschlag auf EK, Abschlag von EVP, Fixpreis, Abschlag vom VK, Abschlag vom Listenpreis (Spalte Aufschlag = PricePremium); externe Artikel sind ausgenommen; Sonderpreise können auf eine Sondervereinbarung (ProjektpreisI3D) verweisen. +Aussage: Das System soll Kundensonderpreise mit tagesgenauem Gültigkeitszeitraum führen und bei der Preisfindung in der Priorität Artikel vor Warengruppe/Unterwarengruppe vor Warengruppe auflösen, mit fünf definierten Preisbasen. +Ergebnis: Vorhersagbare Sonderpreis-Auflösung je Position. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Internal\ReceiptItemPriceBL.cs, Methode GetSpecialPrice() (Zeilen 588–640, drei Prioritätsstufen + ValidFrom/ValidTo-Filter) - Begründung: durchgesetzte Auflösungsregel. + - [SEKUNDÄR] src\backend\Centron.DAO\Mappings\CustomerArea\CustomerDetails\CustomerSpecialPriceMaps.cs (Tabelle „KundenSonderpreise", Spalten GiltVon/GiltBis/Aufschlag/Basis/ProjektpreisI3D) - Begründung: Datenmodell. + - [SEKUNDÄR] src\backend\Centron.Interfaces\Accounts\SpecialPrices\SpecialPriceKind.cs (5 Kinds inkl. Description) - Begründung: Preisbasen. +Prüfidee: Kunde mit WG-Sonderpreis und Artikel-Sonderpreis für denselben Artikel → Artikelpreis gewinnt; ValidTo gestern → Sonderpreis wird ignoriert. +Tracelinks: SyRS-317 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - inkl. Hinweis im Code, dass neue Kinds auch in Tabelle VertragBepreisungArt und ReceiptItemPriceBL nachzuziehen sind (Kopplungsrisiko in Neuimplementierung auflösen). +Status: belegt +``` + +### SwRS-347: Mindestpreis-Übersteuerung nur durch berechtigten (Zweit-)Benutzer + +``` +ID: SwRS-347 +Titel: Mindestpreis-Übersteuerung nur durch berechtigten (Zweit-)Benutzer +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente ReceiptBL.CheckArticleMinPrices; Vertriebsmitarbeiter; freigebender Benutzer +Vorbedingung: Kundenbeleg mit Artikelposition unter Artikel-Mindestpreis wird gespeichert; Speichernder hat das Recht ALLOW_IGNORE_MINIMUM_PRICE nicht. +Fakt: Positionen unter MinPrice führen zu einem Dialog; Optionen: Preise auf Mindestpreis anheben (ChangeBasePrice(item, minPrice)) oder Freigabe durch Benutzername/Passwort eines anderen Benutzers, der per AuthenticatorFactory re-authentifiziert wird und selbst ALLOW_IGNORE_MINIMUM_PRICE besitzen muss; fehlgeschlagener Login oder fehlendes Recht verhindern das Speichern unter Mindestpreis; Besitzer des Rechts sind von der Prüfung ausgenommen; Sonderartikel (Spezial-Artikelcodes) sind ausgenommen. +Aussage: Das System soll das Speichern von Positionen unter dem Artikel-Mindestpreis nur zulassen, wenn der speichernde oder ein sich zusätzlich authentifizierender Benutzer das Recht zur Mindestpreis-Übersteuerung besitzt; andernfalls sollen die Preise auf den Mindestpreis angehoben oder das Speichern verweigert werden. +Ergebnis: Margen-Schutz mit auditierbarem (geloggtem) Vier-Augen-Override. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, Methode CheckArticleMinPrices() (Zeilen 9036–9130; Rechteprüfungen Zeilen 9043 und 9113, Logger-Ausgaben bei Verletzung) - Begründung: durchsetzende Stelle inkl. Re-Authentifizierung. +Prüfidee: Position 10 % unter MinPrice speichern: a) ohne Eingaben → Dialog; b) Zweitbenutzer ohne Recht → Ablehnung; c) Zweitbenutzer mit Recht → Speichern; d) Option „anheben" → BasePrice = MinPrice. +Tracelinks: SyRS-317 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - fachlich übernehmen; technischer Passwort-Redialog ist laut Code-TODO nicht Azure-AD-kompatibel und muss neu gelöst werden (z. B. Freigabe-Workflow). +Status: belegt +``` + +### SwRS-348: Produktmatrix-Datenmodell mit Default-Initialisierung und ChangeLog + +``` +ID: SwRS-348 +Titel: Produktmatrix-Datenmodell mit Default-Initialisierung und ChangeLog +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente ProductMatrixBL; Tabellen CustomerProductMatrix* +Vorbedingung: Kategorien/Produkte gepflegt. +Fakt: Datenmodell: CustomerProductMatrixCategories (Name, SortPosition) 1:n CustomerProductMatrixProducts 1:n CustomerProductMatrixRating (CustomerNumber, ProduktI3D, RatingValue NOT NULL DEFAULT 0) 1:n CustomerProductMatrixRatingChangeLogs (EmployeeI3D NOT NULL, Timestamp NOT NULL, RatingValue, Reason nvarchar(1000)); GetProductMatrixCustomerProductRating() legt fehlende Bewertungen mit Wert Nothing an; AddNotExistingProductRatingToAllCustomers() initialisiert massenhaft per Named Query. +Aussage: Das System soll die Produktmatrix als Kategorie→Produkt→Kundenbewertung-Struktur persistieren, fehlende Bewertungen automatisch mit „Nichts klassifiziert" (0) anlegen und jede Bewertungsänderung als ChangeLog-Datensatz mit Mitarbeiter, Zeitstempel und optionaler Begründung speichern. +Ergebnis: Lückenlose Matrix mit auditierbarer Historie. +Belege: + - [PRIMÄR] SSMS_DB_SCHEMA.sql, Tabellen CustomerProductMatrixCategories/Products/Rating/RatingChangeLogs (Zeilen 36483–36546, NOT-NULL-Constraints, DEFAULT 0) - Begründung: erzwungenes Datenmodell. + - [PRIMÄR] src\backend\Centron.BL\ProductMatrix\ProductMatrixBL.cs, Methoden GetProductMatrixCustomerProductRating() (Zeile 165) und AddNotExistingProductRatingToAllCustomers() (Zeile 195) - Begründung: Initialisierungslogik. +Prüfidee: Rating eines neuen Kunden abfragen → Datensatz mit Wert 0 entsteht; Ratingänderung ohne EmployeeI3D → DB-Constraint-Fehler. +Tracelinks: SyRS-320 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Anmerkung: kein Unique-Constraint auf (CustomerNumber, ProduktI3D) im Schema; in Neuimplementierung ergänzen. +Status: belegt +``` + +### SwRS-349: Mailing-Datenmodell mit Empfängertexten, Anhängen und Versionsfilter + +``` +ID: SwRS-349 +Titel: Mailing-Datenmodell mit Empfängertexten, Anhängen und Versionsfilter +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente MailingDataBL; Tabellen MailingData/MailingTexts/MailingAttachments/MailingDataToRelationshipKind +Vorbedingung: — +Fakt: SaveMailingData() setzt beim Speichern zwingend Version=2; Lesezugriffe (GetAllMailingData, Filter-Expressions) berücksichtigen nur Mailings mit Version==2 und gesetztem MailingDataSourceKind; ein Mailing aggregiert Empfängertexte (EMail, Variables, Send, SurveyI3D), Anhänge (Attachment, Name, Typ) und beziehungsartspezifische Betreff/Body-Varianten (MailTemplateRelationshipKindI3D); Kopf enthält u. a. CampaignI3D, SmsGateway, ActivityOption, HelpdeskOption, NoMailSend. +Aussage: Das System soll Mailings als Aggregat aus Kopf, Empfängertexten (mit individuellen Variablenwerten und Versandkennzeichen), Anhängen und beziehungsartspezifischen Textvarianten speichern und Altdaten der Vorgängerversion (Version≠2) aus der aktiven Verarbeitung ausschließen. +Ergebnis: Vollständige, versionsbereinigte Kampagnendatenbasis. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Mailings\MailingDataBL.cs, Methoden SaveMailingData() (Zeile 74 ff., `mailing.Version = 2`), GetAllMailingData() (Zeile 48 ff., Filter) und LoadFullMailing() (Zeile 22 ff., Aggregat) - Begründung: implementierte Invarianten und Struktur. +Prüfidee: Mailing speichern und mit direktem DB-Update Version=1 setzen → erscheint nicht mehr in GetAllMailingData; FullMailingDTO enthält Texte/Anhänge/RelationshipKinds vollständig. +Tracelinks: SyRS-319 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Version-1-Altbestand ist veraltet und muss nicht migriert werden (Filterlogik belegt Ablösung). +Status: belegt +``` + +### SwRS-350: [HYPOTHESE] Durchsetzung der Werbesperre beim Mailingversand + +``` +ID: SwRS-350 +Titel: [HYPOTHESE] Durchsetzung der Werbesperre beim Mailingversand +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente Mailing-Empfängerauswahl (AccountSearchBL); Marketing +Vorbedingung: Kunde/Konto mit gesetzter Werbesperre (Accounts.AdvertisingNotAllowed bzw. Kunden.werbesperre=1). +Fakt: Das Kontodatenmodell führt eine Werbesperre (Kunden.werbesperre, Accounts.AdvertisingNotAllowed inkl. AdvertisingNotAllowedInfo); die erweiterte Kontensuche kann danach filtern (AccountSearchBL, SQL-Filter `AdvertisingNotAllowed = 1/0` und Kombination mit IsMailingAtEmail1Active). Eine harte Prüfung im Mailing-Versandpfad (MailingDataBL/MailingDataWebServiceBL), die Empfänger mit Werbesperre automatisch ausschließt, wurde nicht gefunden. +Aussage: Das System soll Kontakte mit gesetzter Werbesperre beim Mailingversand automatisch ausschließen. (Derzeit nur als Filteroption der Empfängerauswahl belegt, nicht als erzwungene Sperre im Versandpfad.) +Ergebnis: Keine Werbesendungen an gesperrte Kontakte (DSGVO/UWG-Konformität). +Belege: + - [SEKUNDÄR] src\backend\Centron.BL\Accounts\AccountSearchBL.cs (Zeilen 993–1011, SQL-Filter auf AdvertisingNotAllowed und IsMailingAtEmail1Active) - Begründung: Filtermöglichkeit vorhanden. + - [SEKUNDÄR] src\backend\Centron.DAO\Mappings\CustomerArea\CustomerMaps.cs Zeile 66 (`Map(k => k.AdvertsingBan).Column("werbesperre")`) - Begründung: Datenfeld der Werbesperre. +Prüfidee: Mailing an Empfängerliste inkl. eines Kontos mit Werbesperre versenden; prüfen, ob das gesperrte Konto einen MailingTexts-Eintrag mit Send=true erhält. +Tracelinks: SyRS-319 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - in der Neuimplementierung als harte, zentrale Versandsperre umsetzen (Compliance). +Status: HYPOTHESE +Offene Frage: Gibt es im Versandpfad (Mail-Dispatcher/UI-Auswahl) eine erzwungene Filterung auf Werbesperre, oder verlässt sich das System allein auf die manuelle Filterwahl der Empfängerselektion? +``` + +### SwRS-351: E-Rechnungs-Formatauswahl, Leitweg-ID-Steuerung und Dateierzeugung + +``` +ID: SwRS-351 +Titel: E-Rechnungs-Formatauswahl, Leitweg-ID-Steuerung und Dateierzeugung +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Komponente InvoiceZugferdBL; Buchhaltung +Vorbedingung: Rechnung oder Gutschrift; Einstellungen ReceiptInvoiceSettings (ActiveZugferdInterface) bzw. kundenindividuelles ExportZUGFeRD-Flag; optional Leitweg-ID am Kunden bzw. dessen Firmengruppe. +Fakt: GetZugferFormat(): kundenspezifisch deaktiviert → Warnung; Standardformat aus Einstellungen (Default XInvoice 3.0.1); kundenspezifisch aktiviert → neueste aktive XRechnung-Version. GenerateZugferdFile(): nur Rechnung/Gutschrift (sonst Exception), Dateiart XInvoice bei vorhandener Leitweg-ID sonst Comfort, Leitweg-ID wird als BuyerReference geschrieben (Fallback BuyerPurchaseNumber), UTF-8-BOM wird entfernt; CreateZugferdConformPdfDocument() bettet das XML mit versionsabhängigem Konformitätslevel (Basic/EN16931/XRechnung) ins PDF ein; GetLeitwegID() bevorzugt die Leitweg-ID der Firmengruppe. +Aussage: Das System soll das E-Rechnungsformat aus globaler Einstellung und kundenindividueller Übersteuerung bestimmen, bei Kunden mit Leitweg-ID automatisch XRechnung mit BuyerReference=Leitweg-ID erzeugen, nur Rechnungen und Gutschriften zulassen und das XML BOM-frei sowie als PDF-Einbettung mit korrektem Konformitätslevel ausgeben. +Ergebnis: Formatrichtige E-Rechnungsdateien je Kunde ohne manuelle Formatwahl. +Belege: + - [PRIMÄR] src\backend\Centron.BL\DataExchange\EDI\SaleInvoices\InvoiceZugferdBL.cs, Methoden GetZugferFormat() (Zeile 85), GenerateZugferdFile() (Zeilen 124–166, ZugferdFileKind-Wahl Zeile 153, BOM-Strip Zeile 164) und CreateZugferdConformPdfDocument() (Zeilen 167–212) - Begründung: durchgesetzte Format- und Erzeugungsregeln. + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, Methode GetLeitwegID() (Zeile 3417 ff., Firmengruppen-Vorrang) - Begründung: Leitweg-ID-Ermittlung. +Prüfidee: Kunde mit Leitweg-ID der Firmengruppe: Export → BuyerReference = Gruppen-Leitweg-ID, Dateiart XInvoice; Kunde mit ExportZUGFeRD=false → Warnstatus, keine XRechnung. +Tracelinks: SyRS-318 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Regeln übernehmen, Generator durch gepflegte Bibliothek ersetzen. +Status: belegt +``` + +### SwRS-352: Authentifizierter REST-Endpunkt zum Parsen von ZUGFeRD-Dateien + +``` +ID: SwRS-352 +Titel: Authentifizierter REST-Endpunkt zum Parsen von ZUGFeRD-Dateien +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Komponente ZugferdImportController; WPF-Client (ZugferdImport-Modul, Lieferantenrechnungen) +Vorbedingung: API-Benutzer authentifiziert; ZUGFeRD-Datei als Byte-Array (PDF oder XML). +Fakt: Der Controller ist mit [Authorize] annotiert (Route v{version}/ZugferdImport, POST parse), validiert auf nicht-leere Datei und delegiert an ReceiptItemWebServiceBL.ParseZugferdFile(); Fehler werden als 400 mit Meldung zurückgegeben, Erfolg liefert ZugferdInvoiceDTO (Kopf- und Positionsdaten). +Aussage: Das System soll das Parsen eingehender ZUGFeRD-Dateien als versionierten, authentifizierungspflichtigen REST-Dienst bereitstellen, der leere Eingaben und Parse-Fehler mit HTTP 400 beantwortet und andernfalls die extrahierten Rechnungsdaten strukturiert zurückgibt. +Ergebnis: Strukturierte Übernahme von Lieferanten-E-Rechnungen in den Belegimport. +Belege: + - [PRIMÄR] src\webservice\Centron.Controllers\Controllers\v1\Receipts\ZugferdImportController.cs (Attribute [Authorize]/[Route], Methode ParseZugferdFile mit BadRequest-Pfaden) - Begründung: durchgesetzter Zugriffsschutz und Fehlerkontrakt. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\Finances\Receipts\Suppliers\ZugferdImport\ZugferdImportViewModel.cs - Begründung: konsumierendes UI-Modul (Lieferantenrechnungs-Import). +Prüfidee: POST ohne Token → 401; POST mit leerem Body → 400 „File data is required."; gültige ZUGFeRD-PDF → DTO mit Positionen. +Tracelinks: SyRS-318 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - klarer Schnittstellenvertrag. +Status: belegt +``` + +### SwRS-353: Konditionstexte am Beleg: Länderauswahl, Default-Kondition, Mindestbetrag + +``` +ID: SwRS-353 +Titel: Konditionstexte am Beleg: Länderauswahl, Default-Kondition, Mindestbetrag +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente ReceiptBL (Konditionslogik), AssetConditionBL, AssetConditionTextReplacementBL +Vorbedingung: Beleg mit Land (CountryI3D) und zugeordneter Zahlungs-/Liefer-/Belegkondition. +Fakt: GetReceiptConditionText() lädt den Konditionstext passend zum Belegland (GetAssetConditionText(conditionI3D, CountryI3D)) und ersetzt Platzhalter mit Belegwerten (ReplaceAssetConditionText, inkl. Belegsummen); fehlt die Konditionszuordnung, zieht GetReceiptConditionOrDefaultFromSetting() die Default-Kondition aus den App-Einstellungen; bei Lieferanten-Zahlungskonditionen löst NetPrice < MinimumAmount einen Bestätigungsdialog aus; fehlende Zahlungskondition führt zum Speicherabbruch („Der Beleg hat keine Zahlungskondition."). +Aussage: Das System soll Konditionstexte landesspezifisch am Beleg materialisieren (mit Platzhalterersetzung aus Belegdaten), fehlende Zuordnungen über konfigurierte Default-Konditionen auffüllen, Belege ohne Zahlungskondition abweisen und Mindestbeträge von Zahlungskonditionen prüfen. +Ergebnis: Vollständige, landesrichtige Konditionsangaben auf jedem Beleg. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, Methoden GetReceiptConditionText() (Zeile 8500), GetReceiptConditionOrDefaultFromSetting() (Zeile 8515) und Prüfungen in UpdateConditionTextsAndCheckMinPrices()/CheckReceiptCurrency-Umfeld (Zeilen 8890–9018, Meldungen „Der Beleg hat keine Zahlungskondition." / Mindestpreis-Dialog) - Begründung: durchgesetzte Konditionslogik. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, dbo.RechKopf Spalten [ZahlKond] varchar(4000), [ZahlKondID], [LieferBedID], [LieferbedingungsText] - Begründung: materialisierte Konditionstexte am Beleg. +Prüfidee: Beleg ohne Zahlungskondition speichern → Abbruch; Beleg für AT-Kunde → AT-Text; Konditionstext enthält ersetzte Beträge. +Tracelinks: SyRS-321 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Materialisierung der Texte am Beleg (Snapshot) bewusst beibehalten (Beleg bleibt historisch korrekt). +Status: belegt +``` + +### SwRS-354: [HYPOTHESE] Manueller Statuswechsel auf „storniert" für Nicht-Rechnungsbelege + +``` +ID: SwRS-354 +Titel: [HYPOTHESE] Manueller Statuswechsel auf „storniert" für Nicht-Rechnungsbelege +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertriebsmitarbeiter; Komponente ReceiptBL.SaveReceipt +Vorbedingung: Angebot/Auftrag/Lieferschein ist offen. +Fakt: Eine dedizierte Storno-Methode existiert nur für Rechnungen (ReceiptInvoiceBL.CancelInvoice) und Kundenanlagen (InvoiceBL.CancelInvoice); für andere Belegarten wird ReceiptState.Canceled im Code nur gelesen (z. B. Filter `OtherReceiptState != ReceiptState.Canceled`, Einfüge-Sperre stornierter Belege mit Ticket-Zeiten in ReceiptItemBL Zeile 2954). Ein durchsetzender, geprüfter Storno-Workflow (Rechteprüfung, Mengenrückbuchung) für Angebote/Aufträge/Lieferscheine wurde nicht gefunden; der Statuswechsel scheint über den normalen SaveReceipt-Pfad (CheckCloseReceipt/manuelle Statusänderung) zu erfolgen. +Aussage: Das System soll für Angebote, Aufträge und Lieferscheine einen Statuswechsel auf „storniert" ermöglichen; hierfür gelten mutmaßlich keine besonderen Rechte- oder Konsistenzprüfungen wie beim Rechnungsstorno. +Ergebnis: Stornierte Nicht-Rechnungsbelege werden aus Folgeprozessen (Weiterverarbeitung, Einfügen) ausgeschlossen. +Belege: + - [SEKUNDÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptItemBL.cs Zeile 2954 (Fehlermeldung „Das Einfügen eines stornierten Belegs ... ist nicht möglich.") - Begründung: stornierte Belege werden systemseitig ausgeschlossen. + - [SEKUNDÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs Zeile 9946 (`.Where(f => f.OtherReceiptState != ReceiptState.Canceled)`) - Begründung: Filterung stornierter Belege in der Belegkette. +Prüfidee: Im WPF-Client Auftrag manuell auf „storniert" setzen und prüfen, welche Validierungen/Rechte greifen und ob reservierte Bestände/Seriennummern zurückgebucht werden. +Tracelinks: SyRS-311, SyRS-314 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - uneinheitliches Storno-Konzept; in Neuimplementierung einheitlichen Storno-Workflow je Belegart definieren. +Status: HYPOTHESE +Offene Frage: Über welchen UI-/BL-Pfad werden Angebote/Aufträge/Lieferscheine storniert, und welche Prüfungen (Rechte, Bestandsrückbuchung, Folgebelege) werden dabei erzwungen? +``` + +## Cluster A4 — SwRS (Artikel, Lager, Einkauf, Logistik, RMA) + +### SwRS-430: Feingranulare Rechteprüfung beim Artikelspeichern + +``` +ID: SwRS-430 +Titel: Feingranulare Rechteprüfung beim Artikelspeichern +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: ArticleBL (Komponente), angemeldeter Benutzer +Vorbedingung: SaveArticle wird mit LoggedInUser aufgerufen +Fakt: CheckUserRightBeforeSave prüft CREATE_NEW_ARTICLE (20400023) für Neuanlage, STORE_ARTICLE (20400022) für Änderung, CHANGE_ARTICLE_PRICE (20400024) bei geänderten Preisfeldern (Price1-4, EVP, ListPrice, MinPrice, RawEk1/2, per IsDirtyProperty erkannt) und CHANGE_SERIALNUMBER_REQUIRED_FLAG (20400318) bei geändertem ScanBarcode; CheckSpecialUserRightBeforeSave setzt ohne EDIT_MaterialGroup bzw. mit NOT_CHANGEABLE_ARTICLE_PROPERTIES geänderte Felder (Warengruppe, Einheit, Precision, Mindestbestellmenge, VPE u. a.) stillschweigend auf den Originalwert zurück. +Aussage: Das System soll beim Speichern eines Artikels Neuanlage, Änderung, Preisänderung und Änderung der Seriennummernpflicht jeweils gegen ein eigenes Benutzerrecht prüfen und geschützte Einzelfelder ohne entsprechendes Recht unverändert lassen. +Ergebnis: Ohne Recht wird das Speichern abgewiesen bzw. das geschützte Feld auf den Ursprungswert zurückgesetzt. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Warehousing\ArticleBL.cs, CheckUserRightBeforeSave (Z. 991-1056): u. a. "Sie haben kein Recht Preise zu verändern" bei fehlendem CHANGE_ARTICLE_PRICE - Begründung: durchsetzende Prüfung mit konkreter Bedingung. + - [PRIMÄR] src\backend\Centron.BL\Warehousing\ArticleBL.cs, CheckSpecialUserRightBeforeSave (Z. 1058-1110): GetOriginalEntityProperty-Rücksetzung - Begründung: Feldschutz ohne Fehlermeldung ist implementierte Regel. + - [SEKUNDÄR] src\webservice\Centron.WebServices.Core\EntitiesWrongPlace\Administration\Rights\UserRightsConst.cs (Z. 1744-1756) - Begründung: Rechtekonstanten mit IDs. +Prüfidee: Benutzer ohne CHANGE_SERIALNUMBER_REQUIRED_FLAG ändert ScanBarcode: Fehler; Benutzer ohne EDIT_MaterialGroup ändert Warengruppe: Speichern gelingt, Warengruppe bleibt unverändert. +Tracelinks: SyRS-411 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - stilles Zurücksetzen sollte in der Neuimplementierung durch eine explizite Meldung ersetzt werden (Workaround-Charakter des stillen Reverts). +Status: belegt +``` + +### SwRS-431: Artikelcode-Eindeutigkeit, Längenbegrenzung und Konfliktkontrolle + +``` +ID: SwRS-431 +Titel: Artikelcode-Eindeutigkeit, Längenbegrenzung und Konfliktkontrolle +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: ArticleBL +Vorbedingung: SaveArticle für neuen oder geänderten Artikel +Fakt: Bei Neuanlage wird geprüft, dass kein Artikel mit gleichem ArticleCode existiert ("Der Artikelcode '...' ist bereits vorhanden."); ArticleCode > 60 Zeichen wird abgewiesen; bei bestehenden Artikeln wird über IsDirtyProperty(ChangedDate) eine zwischenzeitliche Fremdänderung erkannt ("Artikel wurde von einer anderen Instanz geändert.", MessageCode ChangedByOtherInstance); optional wird der Artikelcode aus einem Nummernkreis generiert (GenerateArticleCodeByNumberRange bei AppSetting GenerateArticleCodeForNewArticle=1). +Aussage: Das System soll Artikelcodes eindeutig und maximal 60 Zeichen lang halten, auf Wunsch automatisch aus einem Nummernkreis vergeben und konkurrierende Änderungen am selben Artikel per optimistischer Sperre erkennen. +Ergebnis: Kein Duplikat-Artikelcode; verlorene Updates werden verhindert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Warehousing\ArticleBL.cs, SaveArticle (Z. 784-802): Eindeutigkeits- und Längenprüfung - Begründung: durchgesetzte Validierungen. + - [PRIMÄR] src\backend\Centron.BL\Warehousing\ArticleBL.cs, CheckUserRightBeforeSave (Z. 1025-1028): ChangedDate-Dirty-Check - Begründung: Konfliktkontrolle vor der Rechteprüfung. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, [dbo].[ARTIK].[Artikelcode] varchar(60) - Begründung: Längenlimit im Schema. +Prüfidee: Zweiten Artikel mit identischem Artikelcode anlegen: Fehlermeldung; parallel geöffneten Artikel in zwei Sitzungen speichern: zweite Sitzung erhält Konfliktmeldung. +Tracelinks: SyRS-411 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Eindeutigkeit als DB-Unique-Constraint absichern (fehlt im Schema, Prüfung nur in BL). +Status: belegt +``` + +### SwRS-432: Gleitender Einkaufspreis bei Wareneingang + +``` +ID: SwRS-432 +Titel: Gleitender Einkaufspreis bei Wareneingang +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: ArticleStockBL (Komponente), Wareneingangsbuchung +Vorbedingung: Lagerzugang mit Einkaufspreis; Artikel ohne Sondervereinbarung (SpecialAgreementI3D <= 0) +Fakt: UpdateArticlePurchasePrice berechnet den neuen EK abhängig von Artikel.NoMixedEk: FixedPurchasePrice = keine Änderung; LastPurchasePrice = letzter Zugangs-EK; sonst gewichteter Mischpreis ((alterEK*alteMenge + Zugangswert)/neueMenge); Fracht- und Versicherungsanteile werden auf den Zugangs-EK aufgeschlagen und mit dem Artikel-Kalkulationsfaktor multipliziert; Rundung erfolgt auf Artikel.Precision (MidpointRounding.AwayFromZero); bei eigenem Lager-EK wird der EK des Nebenlagers (SecondaryStockArticle.PurchasePrice) fortgeschrieben. +Aussage: Das System soll beim Wareneingang den Artikel-Einkaufspreis nach konfigurierbarem Verfahren (Festpreis, letzter EK, gleitender Durchschnitts-EK) fortschreiben, inklusive Fracht-/Versicherungsanteilen, Kalkulationsfaktor und artikelindividueller Rundungspräzision, getrennt je Lager mit eigenem EK. +Ergebnis: Der Artikel-EK spiegelt die gewählte Bewertungsmethode wider; Positionen mit Sondervereinbarung verändern den Stamm-EK nicht. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Warehousing\StockManagement\ArticleStockBL.cs, UpdateArticlePurchasePrice (Z. 74-149): vollständige Berechnungslogik inkl. NoMixedEk-Weiche und Formel newPurchasePrice = ((oldPurchasePrice*oldQuantity)+additionalAmount)/quantity - Begründung: durchgesetzte Bewertungsregel (abrechnungsrelevant). + - [SEKUNDÄR] src\backend\Centron.BL\Warehousing\ArticleBL.cs, UpdateArticlePurchasePriceThroughStockBooking (Z. 3602 ff.) - Begründung: Persistierung des neuen EK inkl. Logging. +Prüfidee: Artikel (Misch-EK) mit Bestand 10 zu EK 100; Zugang 10 Stück zu 200: neuer EK muss 150 sein; gleicher Zugang mit Sondervereinbarung: EK bleibt 100. +Tracelinks: SyRS-411, SyRS-412 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - betriebswirtschaftlich zentrale Bewertungslogik. +Status: belegt +``` + +### SwRS-433: Lagerumbuchung nur mit Recht TRANSFER_STOCK + +``` +ID: SwRS-433 +Titel: Lagerumbuchung nur mit Recht TRANSFER_STOCK +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: SecondStockArticleBL, Lagermitarbeiter +Vorbedingung: Umbuchung zwischen Hauptlager (-1) und/oder Nebenlägern +Fakt: RebookStockArticle prüft via AppRightsBL.CheckRightsFromUser das Recht UserRightsConst.Purchase.StockList.TRANSFER_STOCK (20400060) und bricht sonst mit "Fehlende Rechte um Lagerbuchungen durchzuführen." (DefaultMessageCodes.RightCheckFailed) ab; Quelle/Ziel werden auf Gültigkeit geprüft (I3D > 0 oder -1), Menge 0 ergibt eine Warnung. +Aussage: Das System soll Lagerumbuchungen zwischen Lägern nur Benutzern mit dem Recht "Lagerumbuchung" erlauben und ungültige Quell-/Ziellager sowie Nullmengen abweisen. +Ergebnis: Unberechtigte oder unplausible Umbuchungen finden nicht statt. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Warehousing\SecondStockArticleBL.cs, RebookStockArticle (Z. 101-130): Rechteprüfung TRANSFER_STOCK mit Fehlerrückgabe - Begründung: durchsetzende Stelle mit konkreter Bedingung. + - [SEKUNDÄR] src\webservice\Centron.WebServices.Core\EntitiesWrongPlace\Administration\Rights\UserRightsConst.cs, Z. 1748: TRANSFER_STOCK = 20400060 // Lagerumbuchung - Begründung: Rechtekonstante. +Prüfidee: Benutzer ohne TRANSFER_STOCK stößt Umbuchung an: Fehlermeldung, Bestände beider Läger unverändert. +Tracelinks: SyRS-411 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - notwendige Zugriffskontrolle auf Bestandsbewegungen. +Status: belegt +``` + +### SwRS-434: Protokollierte manuelle Lagerzu- und -abbuchung + +``` +ID: SwRS-434 +Titel: Protokollierte manuelle Lagerzu- und -abbuchung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: SecondStockArticleBL +Vorbedingung: Manuelle Buchung auf Hauptlager (-1) oder Nebenlager mit Kommentar +Fakt: StockBookOrBookout bucht über BookToStock/BookFromStock und schreibt je Buchung einen ARTIKlog-Eintrag "Lagerzubuchung/Lagerabbuchung - - " mit altem und neuem Bestand und Differenzmenge; fehlt der Nebenlager-Artikeldatensatz, wird er automatisch angelegt (AddArticle); BookFromStock liefert Fehler "Secondary stock not found", wenn kein Nebenlagerbestandssatz existiert. +Aussage: Das System soll manuelle Bestandsbuchungen je Lager ausführen, fehlende Nebenlager-Bestandssätze bei Zubuchung automatisch anlegen und jede Buchung mit Kommentar, Alt-/Neubestand und Verursacher protokollieren. +Ergebnis: Jede manuelle Buchung ist im Artikellog nachvollziehbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Warehousing\SecondStockArticleBL.cs, StockBookOrBookout (Z. 133-214) - Begründung: Buchung + Protokoll in einem Pfad. + - [PRIMÄR] src\backend\Centron.BL\Warehousing\SecondStockArticleBL.cs, BookFromStock (Z. 601-632) - Begründung: Bestandsfortschreibung mit Validierung. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[ARTIKlog] - Begründung: Zieltabelle des Protokolls. +Prüfidee: Abbuchung von einem Nebenlager ohne Bestandssatz: Fehler; Zubuchung auf dasselbe Lager: Bestandssatz wird angelegt, ARTIKlog-Eintrag vorhanden. +Tracelinks: SyRS-412 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Standard-Lagerfunktion. +Status: belegt +``` + +### SwRS-435: Bestandszählung seriennummernpflichtiger Artikel über Barcode-Status + +``` +ID: SwRS-435 +Titel: Bestandszählung seriennummernpflichtiger Artikel über Barcode-Status +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Datenbank (Views), alle bestandslesenden Komponenten +Vorbedingung: Artikel mit ARTIK.BarcodeScanen=1 und aktiviertem Systemschalter Stammdat I3D=1490 +Fakt: cvw_BarcodeCount zählt Barcodes mit Status in (1,2,8) (InStock, InOrder, InRequest) je Artikel/Lager; cvw_ArticleCount ersetzt für solche Artikel das Mengenfeld durch diese Zählung; die Statusmenge entspricht BarcodeStateExtensions.IsInStock im Code. +Aussage: Das System soll für seriennummernpflichtige Artikel genau die Seriennummern in den Zustanden "Offen/im Lager", "in Auftrag" und "in Helpdesk-Anfrage" als Lagerbestand zählen. +Ergebnis: Bestand = Anzahl zählrelevanter Seriennummern; alle anderen Status (Lieferschein, Rechnung, ausgebucht, verschrottet ...) zählen nicht. +Belege: + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE VIEW [dbo].[cvw_BarcodeCount]: WHERE b.Status in (1,2,8) - Begründung: durchgesetzte Zählregel. + - [PRIMÄR] src\backend\Centron.Interfaces\Warehousing\BarcodeState.cs, BarcodeStateExtensions.IsInStock (InStock, InOrder, InRequest) - Begründung: identische Regel in der Codeschicht. +Prüfidee: Seriennummer von InStock auf InDeliveryList setzen: cvw_ArticleCount muss um 1 sinken. +Tracelinks: SyRS-410 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - präzise Definition des zählrelevanten Bestands; doppelte Regelpflege (SQL + C#) vermeiden. +Status: belegt +``` + +### SwRS-436: Nebenlager-Datenmodell mit berechneten Auftrags-/Lieferbeständen + +``` +ID: SwRS-436 +Titel: Nebenlager-Datenmodell mit berechneten Auftrags-/Lieferbeständen +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Datenbank, StockManagement-Komponenten +Vorbedingung: Artikel ist einem Nebenlager zugeordnet +Fakt: NebenlagerArtikel führt je Artikel/Nebenlager Bestand, Zulauf, Mindestbestand, Reparaturbestand, Lagerort/-platz, eigenen EK (EigenerEK, EK, RohEK1/2) und Lagerwert; LieferBestand und AuftragsBestand sind berechnete Spalten über die Funktionen cfn_LieferBestand/cfn_AuftragsBestand; Warehouses kennzeichnet Läger mit IsActive, WarehouseKind und IsOwnPurchasePriceActive. +Aussage: Das System soll je Nebenlager eigene Bestands-, Dispositions- (Mindestbestand, Zulauf) und Bewertungsdaten (eigener EK) führen und reservierte Auftrags- sowie Liefermengen je Lager automatisch berechnet bereitstellen. +Ergebnis: Dispositions- und Bewertungsentscheidungen sind je Lager unabhängig möglich. +Belege: + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[NebenlagerArtikel] (Z. 10037 ff.) inkl. berechneter Spalten [LieferBestand]/[AuftragsBestand] AS dbo.cfn_* - Begründung: Constraint/Struktur erzwingt das Modell. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[Warehouses] (IsOwnPurchasePriceActive, WarehouseKind, IsActive) - Begründung: Lagerkonfiguration. +Prüfidee: Auftragsposition auf Nebenlager anlegen; AuftragsBestand des NebenlagerArtikel muss sich ohne manuelle Buchung erhöhen. +Tracelinks: SyRS-410 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - fachliches Modell übernehmen; berechnete DB-Spalten durch Services ersetzen. +Status: belegt +``` + +### SwRS-437: Inventur-Statusmaschine mit Abschlusssperre + +``` +ID: SwRS-437 +Titel: Inventur-Statusmaschine mit Abschlusssperre +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: InventoryNewBL +Vorbedingung: Inventur existiert (Inventory2) +Fakt: CloseInventory verweigert das Schließen bereits geschlossener Inventuren ("Inventur '...' wurde schon abgeschlossen.") und überführt Open→Closed bzw. OpenWithoutBC→ClosedWithoutBC; SaveInventory verlangt einen Namen; ChangeInventoryGroup verweigert Umgruppierung in bereits abgeschlossene Läger. +Aussage: Das System soll Inventuren als Statusobjekte (offen/geschlossen, mit/ohne Seriennummernerfassung) führen, doppeltes Schließen verhindern und Änderungen an abgeschlossenen Lägern ablehnen. +Ergebnis: Abgeschlossene Inventuren und Läger sind unveränderlich. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Warehousing\InventoryManagement\InventoryNewBL.cs, CloseInventory (Z. 312-324) - Begründung: Statusübergänge und Doppelabschluss-Sperre. + - [PRIMÄR] src\backend\Centron.BL\Warehousing\InventoryManagement\InventoryNewBL.cs, ChangeInventoryGroup (Z. 331-338): InventoryClosedStorage-Prüfung - Begründung: Sperre je Lager. +Prüfidee: Inventur schließen und erneut schließen: zweiter Aufruf liefert Fehlermeldung. +Tracelinks: SyRS-413 +Konsolidierung: Kandidat: InventoryBL/Inventory vs. InventoryNewBL/Inventory2 (zwei Datenhaltungen für die Inventur). +Übernahmewürdigkeit: übernehmen - Statusmodell übernehmen, Doppelimplementierung auflösen. +Status: belegt +``` + +### SwRS-438: Bestands- und Seriennummernkorrektur beim Inventur-Lagerabschluss + +``` +ID: SwRS-438 +Titel: Bestands- und Seriennummernkorrektur beim Inventur-Lagerabschluss +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: InventoryBL +Vorbedingung: Inventurzählung eines Lagers abgeschlossen; Aufruf CloseStorages +Fakt: CloseStorages setzt in einer Transaktion je gezähltem Artikel den Lagerbestand auf die Zählmenge (UpdateArticleStock), legt fehlende SecondaryStockArticle an, korrigiert Barcode-Status (LostAtStocktaking→InStock bei Wiederfund; nicht gescannte Seriennummern→LostAtStocktaking), zählt Seriennummern in Lieferschein/Wareneingang nicht als Bestand (AmountAfter--), schreibt InventoryArticleCheck (AmountBefore/AmountAfter, EK), Artikellog und einen Inventurlog-Eintrag (" hat am eine Komplett-/Teilinventur für das Lager durchgeführt.") und markiert das Lager als abgeschlossen (InventoryClosedStorage); bei Fehler Rollback. +Aussage: Das System soll beim Abschluss eines Inventurlagers Buchbestände transaktional auf die Zählmengen setzen, Seriennummernstatus konsistent nachführen und Vorher-/Nachher-Differenzen sowie den Abschluss selbst protokollieren. +Ergebnis: Buchbestand = Zählbestand; alle Korrekturen dokumentiert; Lager gegen weitere Inventurbuchungen gesperrt. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Warehousing\InventoryManagement\InventoryBL.cs, CloseStorages (Z. 797-944) - Begründung: vollständige Korrektur- und Protokolllogik in Transaktionsklammer. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[InventoryLogs] - Begründung: persistierter Inventurverlauf. +Prüfidee: Lager mit Buchbestand 10, Zählung 8 abschließen: Bestand 8, InventoryArticleCheck 10→8, Artikellog- und Inventurlog-Einträge vorhanden. +Tracelinks: SyRS-413, SyRS-412 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kern der Inventurabwicklung. +Status: belegt +``` + +### SwRS-439: Zugriffsschutz des Kommissioniermoduls + +``` +ID: SwRS-439 +Titel: Zugriffsschutz des Kommissioniermoduls +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: OrderCommissionBL +Vorbedingung: Aufruf einer Kommissionier-Operation durch einen AppUser +Fakt: GetOrdersForCommission, GetOrderItemsForCommission und ExecuteCommissionForOrders rufen HasUserRightsTooAccessCommissionModule auf: if (currentUser.HasUserRight(UserRightsConst.Logistic.Commissioning.ID)) → Erfolg, sonst Result.AsError("Der angemeldete Benutzer hat nicht das Recht um auf die Kommissionierung zuzugreifen."); die SN-Generierung prüft zusätzlich GENERATE_BARCODES (20400179). +Aussage: Das System soll sämtliche Kommissionier-Operationen (Lesen und Ausführen) nur Benutzern mit dem Kommissionierrecht erlauben und die Seriennummern-Generierung zusätzlich absichern. +Ergebnis: Unberechtigte Benutzer erhalten weder Kommissionierdaten noch können sie Pick-Mengen buchen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Warehousing\Commissions\OrderCommissionBL.cs, HasUserRightsTooAccessCommissionModule (Z. 429-434) und HasUserRightTooGenerateNewBarcodesInCommissionModule (Z. 436-441) - Begründung: durchsetzende Prüfungen mit konkreter Bedingung. + - [SEKUNDÄR] src\webservice\Centron.WebServices.Core\EntitiesWrongPlace\Administration\Rights\UserRightsConst.cs, Commissioning.ID=101010, GENERATE_BARCODES=20400179 - Begründung: Rechtekonstanten. +Prüfidee: Aufruf GetOrdersForCommission ohne Recht 101010: Fehler-Result, keine Daten. +Tracelinks: SyRS-419, SyRS-411 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - notwendiger Modulzugriffsschutz. +Status: belegt +``` + +### SwRS-440: Kommissionsausführung mit optimistischer Sperre und Teilkommissionen + +``` +ID: SwRS-440 +Titel: Kommissionsausführung mit optimistischer Sperre und Teilkommissionen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: OrderCommissionBL, PartialCommissionOrderBL +Vorbedingung: Kommissionierliste mit gepickten Mengen je Auftragsposition +Fakt: ExecuteCommissionForOrders schreibt je Auftrag die gepickten Mengen über ReceiptBL.UpdateReceiptQuantityPicked unter Übergabe des ConcurrencyControlGuid zurück und bricht bei Fehler ab; anschließend werden Teilkommissionen aktualisiert (UpdatePartialCommissionOrderItemsByCommissionOrderInfo), deren Fehlschlag als Warnung gemeldet wird; das Anlegen/Löschen von Teilkommissionen ist eigenberechtigt (CREATE_/DELETE_PARTIAL_COMMISSION_FOR_ORDER). +Aussage: Das System soll gepickte Mengen positionsgenau am Auftrag speichern, dabei parallele Auftragsänderungen über eine Versionskennung erkennen und Teilkommissionen konsistent nachführen. +Ergebnis: QuantityPicked ist konsistent zum Auftragsstand; Versionskonflikte führen zum Abbruch statt zu Überschreiben. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Warehousing\Commissions\OrderCommissionBL.cs, ExecuteCommissionForOrders (Z. 169-200) - Begründung: Rückschreiblogik mit ConcurrencyControlGuid. + - [SEKUNDÄR] src\backend\Centron.BL\Warehousing\Commissions\PartialCommissionOrderBL.cs - Begründung: Teilkommissionsverwaltung. +Prüfidee: Auftrag nach dem Laden der Kommissionierliste ändern; ExecuteCommissionForOrders muss mit Konflikt abbrechen. +Tracelinks: SyRS-419 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - verhindert Pick-Verluste bei paralleler Bearbeitung. +Status: belegt +``` + +### SwRS-441: Konfigurierbare Eindeutigkeit von Seriennummern + +``` +ID: SwRS-441 +Titel: Konfigurierbare Eindeutigkeit von Seriennummern +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: BarcodeBL +Vorbedingung: Anlage einer neuen Seriennummer zu einem Artikel +Fakt: ValidateNewBarcode prüft gegen bestehende Barcodes (Status nicht ManuallyBookedOut/Deactivated): Standard = global eindeutig; AppSetting DifferentArticleCanHaveSameSerialNumber beschränkt die Prüfung auf denselben Artikel; AppSetting SameArticleCanHaveSameSerialNumber deaktiviert die Prüfung vollständig; Gutschein-Barcodes (ValidateNewVoucherBarcode) sind immer global eindeutig. +Aussage: Das System soll neue Seriennummern standardmäßig systemweit eindeutig halten (aktive Seriennummern), wobei per Konfiguration Duplikate über Artikelgrenzen bzw. generell zugelassen werden können; Gutschein-Codes bleiben stets eindeutig. +Ergebnis: Duplikate entstehen nur in explizit konfigurierten Ausnahmen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Warehousing\BarcodeBL.cs, ValidateNewBarcode (Z. 171-191): Expression mit Statusausschluss und Settings-Weichen - Begründung: durchgesetzte Eindeutigkeitsregel. + - [SEKUNDÄR] AppSettingsConst.SameArticleCanHaveSameSerialNumber / DifferentArticleCanHaveSameSerialNumber - Begründung: Konfigurationsschalter. +Prüfidee: Ohne Sonderkonfiguration dieselbe Seriennummer für zwei Artikel anlegen: zweite Anlage wird abgelehnt; nach Ausbuchen der ersten (ManuallyBookedOut) ist die Neuanlage erlaubt. +Tracelinks: SyRS-410 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Konfigurierbarkeit deckt Branchenfälle (z. B. Chargen) ab. +Status: belegt +``` + +### SwRS-442: Seriennummern-Ausbuchung nur aus Status "Offen" mit Folgebereinigung + +``` +ID: SwRS-442 +Titel: Seriennummern-Ausbuchung nur aus Status "Offen" mit Folgebereinigung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: BarcodeBL +Vorbedingung: Auswahl von Seriennummern zur manuellen Ausbuchung +Fakt: CheckOutBarCodes bucht nur Seriennummern mit State == BarcodeState.InStock aus (→ ManuallyBookedOut); andere werden mit "Status muss Offen sein" abgewiesen ("Es können nur Seriennummern mit dem Status 'Offen' ausgebucht werden."); aktive Positionszuordnungen (BarcodeToPosition2.Active) werden deaktiviert, je Seriennummer werden Artikellog (SerialNumberChargeOff) und Barcode-Historie geschrieben und optional der Lagerbestand je betroffenem Lager reduziert (BookFromStock, gruppiert je Lager). +Aussage: Das System soll die manuelle Ausbuchung von Seriennummern auf den Status "Offen" beschränken und beim Ausbuchen Zuordnungen deaktivieren, Historie/Log schreiben und optional den Bestand mitkorrigieren. +Ergebnis: Keine Ausbuchung belegter Seriennummern; Bestand und Historie bleiben konsistent. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Warehousing\BarcodeBL.cs, CheckOutBarCodes (Z. 788-895) - Begründung: Statusprüfung, Statuswechsel, Folgebereinigung in einem Ablauf. + - [SEKUNDÄR] src\backend\Centron.Interfaces\Warehousing\BarcodeState.cs - Begründung: Statuswerte des Lebenszyklus (InStock=1 ... ManuallyBookedOut=20). +Prüfidee: Seriennummer im Status InDeliveryList ausbuchen: Warnung "Status muss Offen sein", Status unverändert. +Tracelinks: SyRS-410, SyRS-412 +Konsolidierung: Kandidat (vermutet): Entitäten BarCode und BarCode2 (zwei Datenzugriffsschichten auf dieselbe Tabelle Barcode). +Übernahmewürdigkeit: übernehmen - Statusdisziplin ist Voraussetzung seriennummerngenauer Bestände. +Status: belegt +``` + +### SwRS-443: Automatische Seriennummerngenerierung mit wöchentlichem Zählerneustart + +``` +ID: SwRS-443 +Titel: Automatische Seriennummerngenerierung mit wöchentlichem Zählerneustart +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: BarcodeBL +Vorbedingung: Systemseitige Vergabe von Seriennummern (z. B. Kommissionierung, Wareneingang) +Fakt: GetSystemSNID verwaltet einen systemweiten Seriennummernzähler in SystemTableI3D; bei Kalenderwochenwechsel wird der Zähler auf 10000 zurückgesetzt und die Woche gespeichert ("Every Calendar week the serialnumber has to start with 10000"); CreateAutomaticNewSerialNumbers erzeugt fortlaufende Seriennummern mit konfigurierbarem Präfix (AppSetting SerialNumberAutoGenerationPrefix) ausgehend von der letzten generierten Nummer und bucht optional den Bestand mit (adjustStockInventory). +Aussage: Das System soll Seriennummern automatisch fortlaufend vergeben, wahlweise mit konfigurierbarem Präfix, wobei der wochenbasierte Systemzähler je Kalenderwoche bei 10000 neu beginnt. +Ergebnis: Automatisch vergebene Seriennummern sind eindeutig und rekonstruierbar (Woche + Laufnummer). +Belege: + - [PRIMÄR] src\backend\Centron.BL\Warehousing\BarcodeBL.cs, GetSystemSNID (Z. 213-241) - Begründung: implementierter Wochenreset. + - [PRIMÄR] src\backend\Centron.BL\Warehousing\BarcodeBL.cs, CreateAutomaticNewSerialNumbers (Z. 897 ff.) - Begründung: Präfix- und Fortlauflogik. +Prüfidee: Zwei Generierungen in verschiedenen Kalenderwochen simulieren; zweite Woche muss wieder bei 10000 beginnen. +Tracelinks: SyRS-410 +Konsolidierung: nein +Übernahmewürdigkeit: Sonderfall - wochenbasierter Neustart wirkt historisch gewachsen; Nummernschema in der Neuimplementierung fachlich neu festlegen. +Status: belegt +``` + +### SwRS-444: Bestellvorschlagsberechnung mit Ausschluss- und Sonderregeln + +``` +ID: SwRS-444 +Titel: Bestellvorschlagsberechnung mit Ausschluss- und Sonderregeln +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: OrderSuggestionListBL +Vorbedingung: Bestellvorschlagsliste wird aufgerufen (GetOrderSuggestionArticle/-Order/-WH) +Fakt: Der Vorschlag berücksichtigt nur lagergeführte Artikel (Abbuchung='J' oder IsObligatoryBooking=1), keine Stücklisten (StkListe=0), keine Aufträge mit BestellSperre, keine Mietportal-Artikel; Direktlieferungen und Sondervereinbarungspositionen laufen über einen separaten SQL-Zweig (_sqlSpec) mit Gültigkeitsprüfung der Sondervereinbarung (GueltigBis, Zusatz "(nicht mehr gültig)"); einbezogene Positionsarten (nach Aufwand/Bedarf) sind per AppSettings schaltbar; nur Zeilen mit ToBooking > 0 werden vorgeschlagen; EK wird durch den Kalkulationsfaktor bereinigt und bei lagerindividuellem EK (NLA.EigenerEK=1) der Lager-EK verwendet. +Aussage: Das System soll bei der Vorschlagsberechnung nicht bestellrelevante Konstellationen (Stücklisten, gesperrte Aufträge, Mietartikel) ausschließen, Direktlieferungen und Sondervereinbarungen getrennt mit Preisgültigkeit ausweisen und den maßgeblichen Einkaufspreis lagerbezogen ermitteln. +Ergebnis: Die Vorschlagsliste enthält nur tatsächlich zu bestellende Mengen mit korrektem Bezugspreis. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Purchasing\OrderSuggestionList\OrderSuggestionListBL.cs, _sqlArticle/_sqlSpec (Z. 87-263) - Begründung: alle Filter- und Preisregeln im ausgeführten SQL. + - [SEKUNDÄR] src\backend\Centron.BL\Purchasing\OrderSuggestionList\OrderSuggestionListBL.cs, GetOrderSuggestionWH (Z. 735-766): Where(f => f.ToBooking > 0) - Begründung: nur positive Bestellmengen. +Prüfidee: Stücklistenartikel mit Unterdeckung: erscheint nicht; Auftragsposition mit abgelaufener Sondervereinbarung: erscheint mit Kennzeichnung "(nicht mehr gültig)" und Artikel-EK. +Tracelinks: SyRS-414 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Regeln fachlich übernehmen; SQL-Implementierung neu strukturieren. +Status: belegt +``` + +### SwRS-445: Formatdispatcher für ausgehende EDI-Bestellungen + +``` +ID: SwRS-445 +Titel: Formatdispatcher für ausgehende EDI-Bestellungen +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: EDIDispatcherBL +Vorbedingung: Bestellung mit Lieferant und optionaler SupplierEdiConfiguration +Fakt: CreateEDISuggestionOrderAsync erzeugt ohne Konfiguration oder für ITScope ein OpenTRANS-2.1-Dokument; sonst wird per EdiDataType verzweigt (Also, AlsoCH, Komsa, Alltron, OpenTrans21, Herweck); unbekannte Typen liefern "Unbekannte EdiDataTyp (...)"; der Upload erfolgt zielabhängig (EGIS-HTTP, ITscope-HTTP, Concerto, generischer FTP/HTTP-Upload) und wird in MultiDistributorEDILog protokolliert. +Aussage: Das System soll ausgehende Bestellungen anhand der Lieferantenkonfiguration in das jeweilige Distributorformat übersetzen, unbekannte Formate ablehnen und den Versandweg (HTTP/FTP) samt Protokollierung formatspezifisch wählen. +Ergebnis: Jeder EDI-fähige Lieferant erhält Bestellungen in seinem erwarteten Format. +Belege: + - [PRIMÄR] src\backend\Centron.BL\EDI\EDIDispatcherBL.cs, CreateEDISuggestionOrderAsync (Z. 56-187): switch (ediConfigurations.EdiDataType) mit Default-Fehler - Begründung: durchgesetzte Formatweiche. + - [SEKUNDÄR] src\backend\Centron.BL\EDI\SupplierEDI\SupplierEdiBL.Also.cs / .Komsa.cs / .Alltron.cs / .Opentrans.cs - Begründung: formatspezifische Implementierungen. +Prüfidee: Lieferantenkonfiguration mit ungültigem EdiDataType: Ergebnis ist Fehler-Result mit Formatmeldung, kein Versand. +Tracelinks: SyRS-415 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Plugin-artige Formatarchitektur beibehalten. +Status: belegt +``` + +### SwRS-446: Zuordnung importierter EDI-Rechnungspositionen inkl. Fracht/Versicherung + +``` +ID: SwRS-446 +Titel: Zuordnung importierter EDI-Rechnungspositionen inkl. Fracht/Versicherung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: SupplierEdiBL, Einkäufer (Zuordnungsdialog) +Vorbedingung: Importierter EDI-Beleg (Bestellbestätigung oder Rechnung) mit Positionen +Fakt: SaveReceiptItemAssignments persistiert transaktional die Zuordnung EDI-Position→Bestellposition mit Menge (AppliedQuantity) und Artikelart (CentronArticleKind, u. a. Freight/Insurance), setzt NeedsUserValidation=false und synchronisiert Zuordnungen (löschen/anlegen/aktualisieren); GetFreightArticleCodesForSupplier/GetInsuranceArticleCodesForSupplier lernen aus historischen Zuordnungen die Fracht-/Versicherungs-Artikelcodes je Lieferant; SaveEDIInvoiceItemBarcodes speichert die vom Lieferanten gemeldeten Seriennummern je Rechnungsposition. +Aussage: Das System soll importierte EDI-Belegpositionen den Bestellpositionen mengengenau zuordnen, Fracht- und Versicherungspositionen als solche klassifizieren (mit lieferantenbezogenem Vorschlag aus Historie) und mitgelieferte Seriennummern übernehmen. +Ergebnis: EDI-Belege sind vollständig und wiederverwendbar den Bestellungen zugeordnet. +Belege: + - [PRIMÄR] src\backend\Centron.BL\EDI\SupplierEDI\SupplierEdiBL.cs, SaveReceiptItemAssignments (Z. 504-578) - Begründung: durchgesetzte Zuordnungslogik. + - [PRIMÄR] src\backend\Centron.BL\EDI\SupplierEDI\SupplierEdiBL.cs, GetFreightArticleCodesForSupplier (Z. 85-102) - Begründung: Klassifikationslernen aus EDIInvoiceItemsToOrder mit EDICentronArticleKind.Freight. + - [SEKUNDÄR] src\backend\Centron.BL\EDI\SupplierEDI\SupplierEdiBL.cs, SaveEDIInvoiceItemBarcodes (Z. 582-602) - Begründung: SN-Übernahme aus der Lieferantenrechnung. +Prüfidee: Rechnung mit Frachtposition importieren, als Fracht zuordnen; beim nächsten Import desselben Lieferanten muss der Frachtartikelcode automatisch vorgeschlagen werden. +Tracelinks: SyRS-415 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - reduziert manuellen Abgleichaufwand deutlich. +Status: belegt +``` + +### SwRS-447: GLS-Sendungsvalidierung und Labelverarbeitung + +``` +ID: SwRS-447 +Titel: GLS-Sendungsvalidierung und Labelverarbeitung +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Centron.Api.Gls, Versandmitarbeiter +Vorbedingung: Lieferschein soll als GLS-Sendung angemeldet werden +Fakt: DoValidateShipment verlangt ShipperId und ShipmentDate und begrenzt auf max. 50 Referenzen und 30 Pakete; UploadShipment sendet die Sendung als JSON an die GLS-REST-API (Test-/Produktivbasis-URL, Credentials), extrahiert TrackingId aus der Location-URL und liefert Base64-Labels; die UI speichert Labels als Datei "Lieferschein Label" und schreibt die Trackingnummer in eine neue Lieferscheinversion. +Aussage: Das System soll GLS-Sendungen vor Übertragung fachlich validieren, nach erfolgreicher Anmeldung Trackingnummer und Labels übernehmen und beides dem Lieferschein zuordnen. +Ergebnis: Fehlerhafte Sendungen werden lokal abgefangen; gültige Sendungen sind mit Label und Tracking versehen. +Belege: + - [PRIMÄR] src\apis\Centron.Api.Gls\CentronGlsLogic.cs, DoValidateShipment (Z. 60-91) und UploadShipment (Z. 15-58) - Begründung: Validierung und Ergebnisverarbeitung. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\Finances\Receipts\DeliveryServices\GLS\GlsViewModel.cs, DoSaveLabels/CreateNewReceiptVersionAsync - Begründung: Persistierung von Label und Trackingnummer. +Prüfidee: Sendung ohne ShipperId anmelden: lokale Fehlermeldung "Keine SenderID eingetragen", kein API-Aufruf. +Tracelinks: SyRS-416 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Limits stammen aus der GLS-API und müssen erhalten bleiben; WebRequest-Technik veraltet. +Status: belegt +``` + +### SwRS-448: Shipcloud-Sendungserstellung als Carrier-Broker + +``` +ID: SwRS-448 +Titel: Shipcloud-Sendungserstellung als Carrier-Broker +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Centron.Api.Shipcloud +Vorbedingung: Shipcloud-API-Key konfiguriert (Basic-Auth aus Base64-kodiertem Key) +Fakt: CentronShipcloudLogic ruft die Carrier-Liste ab (GetCarriersAsync) und erstellt Sendungen (CreateShipmentAsync); die Antwort liefert CarrierTrackingNo, TrackingUrl, LabelUrl und Preis; Fehlerantworten der API werden als UploadResult mit Meldung zurückgegeben; Paketvorlagen werden in ShipcloudPackageTemplateBL verwaltet. +Aussage: Das System soll Sendungen alternativ über den Versandbroker Shipcloud (mehrere Carrier über eine Schnittstelle) anmelden und Trackingnummer, Tracking-/Label-URL und Versandpreis übernehmen. +Ergebnis: Versand über beliebige, von Shipcloud unterstützte Carrier ohne Einzelanbindung. +Belege: + - [PRIMÄR] src\apis\Centron.Api.Shipcloud\CentronShipcloudLogic.cs, CreateShipmentAsync (Z. 66-106) - Begründung: implementierte Sendungserstellung mit Ergebnisdaten. + - [SEKUNDÄR] src\backend\Centron.BL\Sales\Receipts\ShipcloudPackageTemplateBL.cs - Begründung: Paketvorlagenverwaltung für den Versanddialog. +Prüfidee: Testsendung über Shipcloud-Sandbox erstellen; UploadResult muss Trackingnummer und Label-URL enthalten. +Tracelinks: SyRS-416 +Konsolidierung: Kandidat: GLS-Direktanbindung (Centron.Api.Gls) und Shipcloud-Broker implementieren dieselbe fachliche Funktion "Sendung anmelden". +Übernahmewürdigkeit: übernehmen - Broker-Ansatz als Zielarchitektur; GLS-Direktanbindung dann verzichtbar. +Status: belegt +``` + +### SwRS-449: Transaktionale RMA-Statusverarbeitung mit Beleg- und Lagerfolgen + +``` +ID: SwRS-449 +Titel: Transaktionale RMA-Statusverarbeitung mit Beleg- und Lagerfolgen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: RmaBL +Vorbedingung: RMA mit Helpdesk-Bezug; Artikel mit Statushistorie +Fakt: SaveRma verarbeitet in einer Transaktion (mit temporär deaktivierten Artik-Triggern): Löschen/Wiederherstellen von RMA-Artikeln (RmaClosedState Deleted/Open, Gesamtstatus folgt den Artikeln), Stornos von Historieneinträgen (bei SendForth wird der Tauschartikel entfernt), Abschluss der Vorab-/Rücklieferung bei Rechnungsstellung, Schließen zugehöriger Lieferscheine (LiefKopf.Status=2, DurchRMAGeschlossen=1), Seriennummern-Umbuchung bei Rechnungsbezug (RebookBarcode), Lagerumbuchung bei geändertem Ziel-Lager (RebookArticleStock), Verschrottung (ArticleScapped) und Fremdware-Einbuchung in das Lager der Art StockKind.RmaCustomer; für jeden neuen RMA-Artikel wird ein Open-Historieneintrag erzeugt. +Aussage: Das System soll alle Statusänderungen eines RMA (inkl. Storno, Verschrottung, Löschen, Rechnungsstellung) in einer Transaktion verarbeiten und die daraus folgenden Beleg-, Seriennummern- und Lageraktionen automatisch und konsistent auslösen. +Ergebnis: Nach jedem Speichern sind RMA-Status, Historie, Belege und Bestände widerspruchsfrei. +Belege: + - [PRIMÄR] src\backend\Centron.BL\CustomerArea\RmaBL.cs, SaveRma (Z. 347-521) - Begründung: gesamte Folgelogik in Session.WithTransaction. + - [SEKUNDÄR] src\backend\Centron.BL\Warehousing\SecondStockArticleBL.cs, UpdateSecondaryStockRma (Z. 712 ff.) - Begründung: RMA-spezifische Bestandsfortschreibung. +Prüfidee: RMA-Artikel stornieren, der bereits versendet war (SendForth): Tauschartikel/Tausch-SN müssen entfernt und die Historie als storniert markiert sein. +Tracelinks: SyRS-417 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Trigger-Deaktivierung (DisableAllTriggersOnTable "Artik") ist ein Workaround und in der Neuimplementierung zu vermeiden. +Status: belegt +``` + +### SwRS-450: Produktdatenanreicherung von Belegpositionen per EAN (Icecat) + +``` +ID: SwRS-450 +Titel: Produktdatenanreicherung von Belegpositionen per EAN (Icecat) +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: IcecatImportService (UI-Service), IcecatApi +Vorbedingung: Icecat-Zugangsdaten konfiguriert (sonst wird der Service nicht instanziiert, TryCreate liefert null); Belegposition mit EAN +Fakt: IcecatImportService.GetArticleAsync ruft per EAN (Position oder Artikel) das deutsche Icecat-Produkt ab und übernimmt Langtext, Bild, Kurztext und Eigenschaftsliste in ImportableArticleInfos; ITScopeImportService und weitere Dienste implementieren dieselbe IImportService-Schnittstelle. +Aussage: Das System soll Produktbeschreibungen, Bilder und Merkmale zu einer Belegposition anhand der EAN aus dem Icecat-Katalog abrufen und zur Übernahme anbieten; weitere Katalogquellen sollen über dieselbe Import-Schnittstelle austauschbar sein. +Ergebnis: Belegpositionen können ohne manuelle Texterfassung mit Katalogdaten angereichert werden. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\Finances\Receipts\ContentImport\Services\IceCatImportService.cs, GetArticleAsync (Z. 33-66) und TryCreate (Z. 20-27) - Begründung: implementierter Abruf und Zugangsvoraussetzung. + - [SEKUNDÄR] src\apis\Centron.APIs.IcecatDataAccess\IcecatApi.cs, GetProductAsync(eanCode, language) - Begründung: API-Schicht des Abrufs. +Prüfidee: Position mit bekannter EAN anreichern: Text, Bild und Eigenschaften werden befüllt; ohne Zugangsdaten erscheint die Quelle nicht in der Auswahl. +Tracelinks: SyRS-418 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - IImportService-Abstraktion als Vorbild für die Neuimplementierung. +Status: belegt +``` + +### SwRS-451: [HYPOTHESE] TradePool-Artikelimport aus XML-Dateien + +``` +ID: SwRS-451 +Titel: [HYPOTHESE] TradePool-Artikelimport aus XML-Dateien +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: TradePoolBL, TradePoolXmlLogic +Vorbedingung: XML-Importdateien mit Handelsartikeln liegen vor +Fakt: TradePoolBL.StartTradeImport initialisiert je Datei eine TradePoolXmlLogic und importiert Handelsartikel (ImportTradeArticles) in die TradePool-Entitäten (TradeArticles, TradeArticleDetails, TradeArticleCustomer, TradeDistributor); Abfragen filtern nach Herstellercode, Beschreibung und Klassenhierarchie (Class/Subclass1/Subclass2) mit Paging. +Aussage: Das System soll Handelsartikel aus XML-Dateien in einen separaten "TradePool"-Katalog importieren und dort nach Herstellercode, Beschreibung und Warenklassen durchsuchbar machen, mutmaßlich als gemeinsamer Gebrauchtwaren-/Handelsbörsen-Pool mehrerer c-entron-Kunden. +Ergebnis: Importierte TradePool-Artikel sind mit Details und Kundenzuordnung recherchierbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\TradePool\TradePoolBL.cs, StartTradeImport (Z. 28-36) und GetTradeArticleList (Z. 76-100) - Begründung: Import- und Suchimplementierung. + - [SEKUNDÄR] src\backend\Centron.BL\TradePool\Core\TradePoolXmlLogic (Verwendung in StartTradeImport) - Begründung: XML-Parsing-Schicht. +Prüfidee: Beispiel-XML importieren und prüfen, dass TradeArticles inkl. Details angelegt und über die Klassenfilter auffindbar sind. +Tracelinks: SyRS-418 +Konsolidierung: nein +Übernahmewürdigkeit: veraltet - keine erkennbare Anbindung an aktuelle Module; vor Übernahme fachliche Relevanz klären. +Status: HYPOTHESE +Offene Frage: Wird der TradePool produktiv noch genutzt und was ist der fachliche Zweck (Kunden-übergreifende Handelsbörse vs. interner Katalog)? Kein aufrufendes UI-Modul im Cluster gefunden. +``` + +## Cluster A5 — Helpdesk & Service — SwRS + +### SwRS-531: Status-Stammdaten mit Icon-Normalisierung und Löschschutz + +``` +ID: SwRS-531 +Titel: Status-Stammdaten mit Icon-Normalisierung und Löschschutz +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente HelpdeskStatusBL +Vorbedingung: Status wird gespeichert oder gelöscht +Fakt: SaveHelpdeskStatus() skaliert hochgeladene Status-Icons auf 16x16 und konvertiert sie nach BMP ("c-entron delphi can not work with jpg"); DeleteHelpdeskStatus() zählt Verwendungen in HelpdeskCompact.HelpdeskStateI3D und TaskManagementHelpdeskAction.State und verweigert das Löschen bei Verwendung mit einer Meldung, die die Anzahl betroffener Tickets/Tasks nennt. +Aussage: Das System soll Status-Icons beim Speichern auf 16x16 Pixel im BMP-Format normalisieren und einen Status nur löschen, wenn er weder von Tickets noch von TaskManager-Aktionen referenziert wird. +Ergebnis: Konsistente Status-Stammdaten ohne verwaiste Referenzen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskStatusBL.cs, SaveHelpdeskStatus(): ResizeImage(16, 16).ConvertImageToBMPFormat() - Begründung: Durchgesetzte Icon-Normalisierung. + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskStatusBL.cs, DeleteHelpdeskStatus(): helpdeskCount/taskCount-Prüfung, Result.AsError("Der Status '...' kann nicht gelöscht werden!...", InvalidDeleteRequest) - Begründung: Durchgesetzter Löschschutz. +Prüfidee: Status mit 512x512-JPG speichern — persistiertes Icon ist 16x16 BMP; Status in Verwendung löschen — Fehler mit Verwendungszählung. +Tracelinks: SyRS-511 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - BMP-Konvertierung ist ein Delphi-Altlast-Behelf; Löschschutz ist zu übernehmen. +Status: belegt +``` + +### SwRS-532: Ticketabschluss setzt Abschlussstatus, löscht ToDos und historisiert + +``` +ID: SwRS-532 +Titel: Ticketabschluss setzt Abschlussstatus, löscht ToDos und historisiert +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente HelpdeskCloseBL +Vorbedingung: Ticket ist offen; Abschluss wird ausgelöst +Fakt: CloseHelpdeskWithNotification()/CloseHelpdeskForNotificationMethods() setzt in einer Transaktion HelpdeskState = GetClosedHelpdeskState(), ClosedAt = DateTime.Now, löscht die Ticket-ToDos (DeleteHelpdeskToDos), speichert über HelpdeskBL.Save() (inkl. Rechteprüfung) und erzeugt Historieneinträge "Status wurde geändert" und "Ticket abgeschlossen" sowie Benachrichtigungen; anschließend werden optional externe und interne Abschlussmails (mit Servicebericht) versendet. Wird ein Ticket in einem anderen als dem Abschlussstatus gespeichert, wird ClosedAt = null zurückgesetzt (CheckUserRigths). +Aussage: Das System soll den Ticketabschluss als atomaren Vorgang ausführen (Abschlussstatus + Abschlusszeitpunkt + Entfernen offener ToDos + Historie) und bei Wiedereröffnung den Abschlusszeitpunkt zurücksetzen. +Ergebnis: Abgeschlossene Tickets sind konsistent mit Zeitstempel und Historie; halbfertige Abschlüsse werden zurückgerollt. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskCloseBL.cs, CloseHelpdeskForNotificationMethods(): StartTransaction/RollbackTransaction, HelpdeskState=closedState, ClosedAt=DateTime.Now, DeleteHelpdeskToDos(), CreateHistory("Beendet", ...) - Begründung: Durchgesetzter Abschlussablauf. + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs, CheckUserRigths(): "else { entity.ClosedAt = null; }" - Begründung: Rücksetzen des Abschlusszeitpunkts bei Nicht-Abschlussstatus. +Prüfidee: Ticket mit offenen ToDos abschließen — ToDos entfernt, ClosedAt gesetzt, zwei Historieneinträge; Ticket wieder in offenen Status setzen — ClosedAt ist null. +Tracelinks: SyRS-511, SyRS-512 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - transaktionaler Abschluss ist fachlich notwendig. +Status: belegt +``` + +### SwRS-533: Serverseitige Rechteprüfung beim Ticket-Speichern (interne Benutzer) + +``` +ID: SwRS-533 +Titel: Serverseitige Rechteprüfung beim Ticket-Speichern (interne Benutzer) +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente HelpdeskBL.CheckUserRigths +Vorbedingung: Interner Benutzer speichert ein Ticket +Fakt: CheckUserRigths() prüft: neu → ADD_NEW_HELPDESK; Änderung → EDIT_HELPDESK; Zielstatus = Abschlussstatus → CLOSE_REQUEST; geändertes Fälligkeitsdatum → MATURITY_CHANGE (IsDueDateChanged); bei ASSIGN_HELPDESK_ONLY_TO_OWN_DEPARTMENTS und geänderter ResponsiblePerson muss die verantwortliche Person einer Abteilung des Benutzers angehören; jeweils Result.AsError(..., RightCheckFailed). +Aussage: Das System soll beim Speichern eines Tickets die Operationen Anlegen, Bearbeiten, Abschließen, Fälligkeitsänderung und Verantwortlichen-Zuweisung einzeln gegen die Benutzerrechte prüfen und bei Verstoß den gesamten Speichervorgang ablehnen. +Ergebnis: Feingranulare, serverseitig durchgesetzte Ticketrechte. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs, CheckUserRigths() (Zeilen ~418-466): HasUserRight-Prüfungen ADD_NEW_HELPDESK/EDIT_HELPDESK/CLOSE_REQUEST/MATURITY_CHANGE/ASSIGN_HELPDESK_ONLY_TO_OWN_DEPARTMENTS mit Result.AsError(..., DefaultMessageCodes.RightCheckFailed) - Begründung: Durchsetzende Stelle mit konkreten Bedingungen. + - [KONTEXT] CentronRights.md, Abschnitte 4-6 - Begründung: Fachliche Rechtebeschreibung. +Prüfidee: Je Recht einen Benutzer ohne dieses Recht die jeweilige Operation ausführen lassen — jede Operation muss mit RightCheckFailed scheitern. +Tracelinks: SyRS-512, SyRS-513 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - direkt auf Web-API-Guards übertragbar. +Status: belegt +``` + +### SwRS-534: Rechteprüfung für Portal-Web-Accounts mit Eigentümerbindung + +``` +ID: SwRS-534 +Titel: Rechteprüfung für Portal-Web-Accounts mit Eigentümerbindung +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente HelpdeskBL.CheckWebRights; WebAccount (Kundenportal/SelfCare) +Vorbedingung: Web-Account speichert ein Ticket +Fakt: CheckWebRights() verlangt für Neuanlage WEBRIGHT_CREATEREQUEST; für Änderungen WEBRIGHT_EDITALLREQUESTS oder (WEBRIGHT_EDITONLYOWNREQUESTS und entity.ContactPerson.I3D == webAccount.AddressContactI3D); für den Abschluss WEBRIGHT_CLOSEALLEREQUESTS. Zeiterfassungs-Endpunkte lehnen Web-Account-Logins vollständig ab ("Web-Account Zugriff nicht erlaubt."). +Aussage: Das System soll Portal-Accounts nur die per Web-Recht erlaubten Ticketoperationen gestatten und bei eingeschränktem Bearbeitungsrecht die Bearbeitung auf Tickets des eigenen Ansprechpartners begrenzen; Zeiten dürfen von Portal-Accounts nicht bearbeitet werden. +Ergebnis: Kundenzugriff ist auf eigene Vorgänge begrenzt; interne Abrechnungsdaten sind für Portalnutzer unzugänglich. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs, CheckWebRights(): WEBRIGHT_-Prüfungen inkl. Kontaktpersonen-Abgleich - Begründung: Durchsetzende Portalrechte. + - [PRIMÄR] src\backend\Centron.BL\WebServices\Sales\Support\HelpdeskTimerWebServiceBL.cs, ThrowIfUserDoesntHaveRightToChangeHelpdeskTimers(): "if (loggedInUser.IsWebAccountLogin || !loggedInUser.UserI3D.HasValue) throw new ResultException(\"Web-Account Zugriff nicht erlaubt.\")" - Begründung: Vollständiger Ausschluss der Portalnutzer von Zeiten. +Prüfidee: Web-Account mit EDITONLYOWNREQUESTS bearbeitet Ticket mit fremdem Ansprechpartner — Ablehnung; Web-Account ruft Timer-Speichern auf — Ablehnung. +Tracelinks: SyRS-512 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Mandanten-/Kundenabgrenzung für SaaS essenziell. +Status: belegt +``` + +### SwRS-535: Konfigurierbare Pflichtfelder beim Ticket-Speichern + +``` +ID: SwRS-535 +Titel: Konfigurierbare Pflichtfelder beim Ticket-Speichern +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente HelpdeskBL.DoValidateMandatoryFields +Vorbedingung: Ticket wird ohne ignoreMandatoryFields gespeichert +Fakt: DoValidateMandatoryFields() verlangt immer einen Kunden ("Kein Kunde ausgewählt") und je nach AppSettings HelpdeskPriorityFieldIsRequired/HelpdeskTypeFieldIsRequired/HelpdeskMaincategoryFieldIsRequired zusätzlich Priorität, Typ und Hauptkategorie; Sammel-Fehlermeldung mit MessageCode MandatoryFieldsNotFilled; Sondertickets (IsSpecialHelpdesk) sind von den konfigurierbaren Pflichtfeldern ausgenommen; beim Abschluss kann die Prüfung explizit übersteuert werden (ignoreMandatoryFieldsOnClose). +Aussage: Das System soll beim Speichern eines Tickets den Kunden als feste Pflichtangabe und Priorität, Typ und Hauptkategorie als konfigurierbare Pflichtangaben validieren und alle Verstöße gesammelt zurückmelden. +Ergebnis: Unvollständige Tickets werden mit vollständiger Fehlerliste abgewiesen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs, DoValidateMandatoryFields() (Zeilen ~658-702) - Begründung: Durchgesetzte Pflichtfeldregeln inkl. Konfig-Schalter. + - [SEKUNDÄR] src\backend\Centron.BL\Sales\Support\HelpdeskCloseBL.cs, CloseHelpdesk(..., bool ignoreMandatoryFieldsOnClose) - Begründung: Übersteuerungspfad beim Abschluss. +Prüfidee: Alle drei Pflichtfeld-Settings aktivieren, Ticket ohne Priorität/Typ/Hauptkategorie speichern — eine Fehlermeldung mit drei Zeilen. +Tracelinks: SyRS-511, SyRS-512 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - konfigurierbare Pflichtfelder sind ein verbreitetes Kundenbedürfnis. +Status: belegt +``` + +### SwRS-536: Fälligkeitsalgorithmus aus Priorität mit Bürozeiten und Wochenendregeln + +``` +ID: SwRS-536 +Titel: Fälligkeitsalgorithmus aus Priorität mit Bürozeiten und Wochenendregeln +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente HelpdeskBL.GetDueDateFromPriority +Vorbedingung: HelpdeskPriority mit DueDateDelayInHours, optional OfficeHourFrom/To, EscalationSa/So +Fakt: Der Algorithmus addiert DueDateDelayInHours iterativ: liegt der Zielzeitpunkt nach OfficeHourTo, wird der Rest auf den Folgetag ab OfficeHourFrom übertragen; Samstage/Sonntage werden übersprungen, wenn EscalationSa/EscalationSo = false; ohne Priorität ist die Fälligkeit gleich dem Erstellzeitpunkt. Aufrufer: Ticketanlage (DoUpdateDefaultHelpdeskFields, nur wenn DueDate leer) und TaskManager-Ticketerzeugung (+ helpdeskAction.DueDateOffset in Ticks). +Aussage: Das System soll die Fälligkeit als Erstellzeitpunkt plus Reaktionszeit in Arbeitsstunden berechnen, wobei Reststunden über Bürozeitgrenzen in den nächsten Arbeitstag übertragen und arbeitsfreie Wochenendtage übersprungen werden. +Ergebnis: Deterministische, SLA-konforme Fälligkeitsberechnung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs, GetDueDateFromPriority(HelpdeskPriority, DateTime) (Zeilen ~786-827): while(hoursToAdd > 0)-Schleife mit OfficeHourFrom/To und EscalationSa/So-Behandlung - Begründung: Vollständige Berechnungslogik. + - [SEKUNDÄR] src\backend\Centron.BL\TaskManager\ActionHandler\TaskManagementHelpdeskActionHandler.cs, Execute(): "DueDate = new HelpdeskBL(session).GetDueDateFromPriority(...); ... newHelpdesk.DueDate += TimeSpan.FromTicks(helpdeskAction.DueDateOffset)" - Begründung: Wiederverwendung inkl. Offset. +Prüfidee: Priorität 10h, Bürozeit 8-17, EscalationSa/So=false: Anlage Do 15:00 — erwartete Fälligkeit Mo im Bürozeitfenster; Unit-Test über Tages- und Wochenendgrenzen. +Tracelinks: SyRS-513 +Konsolidierung: Kandidat: EscalationBL.ShouldEscalated() implementiert eine zweite, eigenständige Arbeitszeit-/Wochenendrechnung (WorkTimeFrom/To, SetNextEscDay) für dasselbe Konzept "Zeitfenster in Arbeitszeit". +Übernahmewürdigkeit: übernehmen - Algorithmus übernehmen, aber mit der Eskalationszeitrechnung zusammenführen. +Status: belegt +``` + +### SwRS-537: Eskalationsstufen-Berechnung und -Versand mit Persistierung der Stufe + +``` +ID: SwRS-537 +Titel: Eskalationsstufen-Berechnung und -Versand mit Persistierung der Stufe +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente EscalationBL (periodischer Lauf) +Vorbedingung: Eskalationseintrag (eskalationen, ObArt=2, status < 2) mit aktivem Eskalationstyp; bei Tickets Zuordnung über Priorität (et.TicketPriorityI3D = hr.Prioritaet) und offenen Status (IsNull(hs.Status,0) = 0) +Fakt: CheckEskalationStage() ermittelt die nächste fällige Stufe (1-3) aus WaitHourEsc1-3 und bereits gesetzten Eskalation1-3On; ShouldEscalated() rechnet den nächsten Eskalationszeitpunkt in Geschäftszeit (WorkTimeFrom/To, Sa/So-Flags) und vergleicht gegen das Lauf-Datum; nach erfolgreichem Mailversand (SendMail über SendMailWebserviceBL) setzt UpdateEscalations() Eskalation{Stage}AM=GetDate() und UpdateTicket() hlpdsk_requests.EscalationLevel={Stage}; Empfänger je Stufe per Flag-Enum (Editor/Supervisor/Adviser/Manager), bei abwesendem Bearbeiter (p.Status=2) dessen Vertretung (PersonalVertretung); Mailinhalt aus Mailvorlage (MailTemplateReferences.Escalation.Ticket) mit Variablenersetzung. +Aussage: Das System soll je Eskalationseintrag die fällige Eskalationsstufe zeitfensterbasiert bestimmen, die Benachrichtigung an den stufenspezifischen Empfängerkreis (inkl. Vertreterregelung) über Mailvorlagen versenden und erst nach erfolgreichem Versand Stufenzeitpunkt und Ticket-Eskalationslevel fortschreiben. +Ergebnis: Keine Doppel-Eskalation; Eskalationsstand am Ticket entspricht den tatsächlich versendeten Benachrichtigungen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\Escalation\EscalationBL.cs, CheckEskalationStage()/ShouldEscalated() - Begründung: Stufen- und Zeitfensterlogik. + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\Escalation\EscalationBL.cs, SendMail(): "if (result.Status == ResultStatus.Success) { UpdateEscalations(escItem); if (escItem.TdlKind == ToDoType.Helpdesk) UpdateTicket(escItem); }" - Begründung: Persistierung nur nach Versanderfolg. + - [SEKUNDÄR] src\backend\Centron.BL\Sales\Support\Escalation\EscalationBL.cs, _sTicketSql (JOIN hlpdsk_status "IsNull(hs.Status,0) = 0", PersonalVertretung-JOIN) - Begründung: Nur offene Tickets, Vertretungslogik. +Prüfidee: TestEscalation() mit Testempfänger ausführen (Protokoll je Prüfschritt); produktiver Lauf: nach Mailerfolg sind Eskalation1Am und EscalationLevel gesetzt, bei Mailfehler unverändert. +Tracelinks: SyRS-514 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - fachlich übernehmen, technisch als String-SQL/RTF-Konstrukt neu zu implementieren. +Status: belegt +``` + +### SwRS-538: Zeiten speichern nur mit EDIT_TIME, eigene Zeiten-Beschränkung und Belegsperre + +``` +ID: SwRS-538 +Titel: Zeiten speichern nur mit EDIT_TIME, eigene Zeiten-Beschränkung und Belegsperre +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente HelpdeskTimerWebServiceBL.SaveHelpdeskTimerInternal +Vorbedingung: Bestehende Zeit (timerI3D > 0) wird geändert; Neuanlage ist stets erlaubt +Fakt: ThrowIfUserDoesntHaveRightToChangeHelpdeskTimers() wirft ohne EDIT_TIME eine ResultException (RightCheckFailed); mit OWN_TIME_EDIT und abweichendem Ersteller (inkl. Auflösung über EmployeeArticle.AppUser) wird "Zeiten anderer Mitarbeiter" abgelehnt; ThrowIfInvalidHelpdeskTimer() verhindert das Speichern von Zeiten mit Beleg-Zuordnung (IsAssignedToDeliveryList/Invoice/Order; Spalten LiefPosI3D/RechPosI3D/AufPosI3D) und validiert HelpdeskI3D != 0 sowie Start/Stop-Jahr > 1980. +Aussage: Das System soll Änderungen an bestehenden Zeiten nur Benutzern mit Zeitbearbeitungsrecht erlauben, bei eingeschränktem Recht nur an eigenen Zeiten, und Zeiten nach Belegzuordnung sowie mit unplausiblen Zeitstempeln vom Speichern ausschließen. +Ergebnis: Abgerechnete und fremde Zeiten sind vor Änderung geschützt. +Belege: + - [PRIMÄR] src\backend\Centron.BL\WebServices\Sales\Support\HelpdeskTimerWebServiceBL.cs, ThrowIfUserDoesntHaveRightToChangeHelpdeskTimers() (Zeilen ~348-381): HasUserRight(EDIT_TIME)/HasUserRight(OWN_TIME_EDIT)-Prüfungen mit ResultException(RightCheckFailed) - Begründung: Durchsetzende Rechteprüfung. + - [PRIMÄR] src\backend\Centron.BL\WebServices\Sales\Support\HelpdeskTimerWebServiceBL.cs, ThrowIfInvalidHelpdeskTimer(): ArgumentExceptions für Beleg-Zuordnungen und Plausibilität - Begründung: Durchgesetzte Sperr- und Plausibilitätsregeln. + - [SEKUNDÄR] src\backend\Centron.Entities\Entities\Sales\Support\HelpdeskTimerArea\HelpdeskTimer.cs, IsAssignedToAsset => IsAssignedToOrder || IsAssignedToDeliveryList || IsAssignedToInvoice - Begründung: Definition der Belegsperre. +Prüfidee: Benutzer ohne EDIT_TIME ändert bestehende Zeit — Exception RightCheckFailed; Zeit mit RechPosI3D speichern — Ablehnung mit Rechnungs-Meldung; Neuanlage ohne EDIT_TIME — erlaubt. +Tracelinks: SyRS-515 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Hinweis: Neuanlage ist bewusst rechtefrei ("Creation of new times is always allowed"), fachlich zu bestätigen. +Status: belegt +``` + +### SwRS-539: Zeiten löschen mit DELETE_HELPDESK_TIMER, Belegsperre und Historie + +``` +ID: SwRS-539 +Titel: Zeiten löschen mit DELETE_HELPDESK_TIMER, Belegsperre und Historie +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente HelpdeskTimerBL.DeleteHelpdeskTimer +Vorbedingung: Zeit existiert; Löschanforderung durch angemeldeten Benutzer +Fakt: DeleteHelpdeskTimer() verweigert ohne DELETE_HELPDESK_TIMER ("Benutzer hat nicht das Recht um Zeiten zu löschen.", RightCheckFailed) und bei Belegzuordnung ("Die Helpdesk Zeit wurde einem Beleg zugewiesen. Löschen ist nicht möglich."); vor dem Löschen wird ein Historieneintrag HELPDESK_TIMER_DELETED mit Zeitraum, Artikel und Kürzel des Löschenden geschrieben; zugehörige MyDay-WorkItems, externe Referenzen und Kalendereinträge werden mitbereinigt. +Aussage: Das System soll das Löschen einer Zeit nur mit dediziertem Löschrecht und nur ohne Belegzuordnung erlauben und jede Löschung mit Inhalt und Verursacher in der Tickethistorie dokumentieren. +Ergebnis: Nachvollziehbare, berechtigte Löschungen; abgerechnete Zeiten bleiben erhalten. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskTimerBL.cs, DeleteHelpdeskTimer() (Zeilen ~554-602): HasUserRight(DELETE_HELPDESK_TIMER)-Prüfung, IsAssignedToAsset-Sperre, CreateHistory(HELPDESK_TIMER_DELETED, ...) - Begründung: Durchsetzende Stelle mit allen Bedingungen. + - [KONTEXT] CentronRights.md, Abschnitt 9 "Helpdeskzeiten löschen" - Begründung: Fachliche Rechtedefinition. +Prüfidee: Löschversuch ohne Recht und mit Belegzuordnung — beide abgelehnt; erfolgreiche Löschung erzeugt Historieneintrag mit Start/Stop. +Tracelinks: SyRS-515 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Manipulationsschutz der Abrechnungsbasis. +Status: belegt +``` + +### SwRS-540: Signieren von Zeiten: Einmaligkeit, Planungsausschluss, Historie + +``` +ID: SwRS-540 +Titel: Signieren von Zeiten: Einmaligkeit, Planungsausschluss, Historie +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente HelpdeskTimerSignatureBL; REST-Endpunkt POST HelpdeskTimers/sign-timers +Vorbedingung: Ticket mit nicht geplanten, noch unsignierten Zeiten; Signaturbild vorhanden +Fakt: SignMultipleTimers() überspringt Zeiten fremder Tickets (timer.Helpdesk.I3D != helpdeskI3D), geplante Zeiten (IsPlanned) und bereits signierte Zeiten (HelpdeskSignatureExists), setzt IsSigned=true, speichert die Signatur als HelpdeskTimerSignatureCompact und schreibt pro Timer ein Signatur-Log sowie einen HelpdeskHistory-Eintrag "Zeiten unterschrieben" (Level Important); AddSignature() validiert TimerI3D und Signaturbild und legt bei existierender Signatur keine zweite an. +Aussage: Das System soll Zeiten eines Tickets sammelbar signieren, wobei je Zeit höchstens eine Unterschrift existiert, geplante Zeiten nicht signierbar sind und jeder Signaturvorgang protokolliert wird. +Ergebnis: Eindeutiger, historisierter Unterschriftsstatus je Zeit. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskTimerSignatureBL.cs, SignMultipleTimers(): continue-Bedingungen (Helpdesk-Zugehörigkeit, IsPlanned, HelpdeskSignatureExists), IsSigned=true, HelpdeskHistory - Begründung: Durchgesetzte Signierregeln. + - [SEKUNDÄR] src\webservice\Centron.Controllers\Controllers\v1\Tickets\HelpdeskTimersController.cs, SignTimers(): Validierung TimerI3Ds/SignatureData, Rückgabe signedCount - Begründung: API-Schnittstelle des Signiervorgangs. +Prüfidee: 3 Zeiten signieren (1 geplant, 1 bereits signiert) — signedCount == 1; erneuter Aufruf — signedCount == 0. +Tracelinks: SyRS-516 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kernfunktion des mobilen Servicenachweises. +Status: belegt +``` + +### SwRS-541: Entfernen einer Zeit-Unterschrift nur mit DELETE_HELPDESK_SIGNATURE + +``` +ID: SwRS-541 +Titel: Entfernen einer Zeit-Unterschrift nur mit DELETE_HELPDESK_SIGNATURE +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente HelpdeskTimerSignatureBL.RemoveSignatureFromTime +Vorbedingung: Signierte Zeit existiert +Fakt: RemoveSignatureFromTime() prüft per AppRightsBL.CheckRightsFromUser das Recht DELETE_HELPDESK_SIGNATURE und bricht ohne Recht mit "Sie besitzen nicht das Recht um Unterschriften zu löschen (Unterschrift aus Zeit löschen)" (RightCheckFailed) ab; mit Recht wird IsSigned=false gesetzt, der Signaturdatensatz gelöscht und ein Removed-Signature-Log geschrieben. +Aussage: Das System soll das Entfernen einer Kundenunterschrift von einer Zeit ausschließlich Benutzern mit dem dedizierten Signatur-Löschrecht erlauben und den Vorgang protokollieren. +Ergebnis: Unterschriften können nicht unbefugt entfernt werden; jede Entfernung ist nachvollziehbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskTimerSignatureBL.cs, RemoveSignatureFromTime() (Zeilen ~179-206): "if (checkRightsResult.Contains(UserRightsConst.Sales.Customer.Helpdesk.DELETE_HELPDESK_SIGNATURE) == false) return Result.AsError(...)" - Begründung: Durchsetzende Rechteprüfung mit konkreter Bedingung. + - [KONTEXT] CentronRights.md, Abschnitt 7.2 - Begründung: Fachliche Rechtedefinition. +Prüfidee: Entfernen ohne Recht — Fehler RightCheckFailed, Signatur bleibt; mit Recht — Signatur gelöscht, IsSigned=false, Log vorhanden. +Tracelinks: SyRS-516 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Schutz des Leistungsnachweises. +Status: belegt +``` + +### SwRS-542: Verschieben von Zeiten zwischen Tickets mit mehrstufiger Prüfkette + +``` +ID: SwRS-542 +Titel: Verschieben von Zeiten zwischen Tickets mit mehrstufiger Prüfkette +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente HelpdeskTimerWebServiceBL; WPF-Client TicketDetailViewModel; REST-Endpunkte HelpdeskTimers/check-can-be-moved, /check-can-move-to-target, /move-timer +Vorbedingung: Zeit existiert; Zielticket gewählt +Fakt: CheckTimerCanBeMoved() lehnt bereits abgerechnete Zeiten ab ("Die Zeit wurde bereits abgerechnet und kann somit nicht mehr verändert und verschoben werden.", IsAssignedToAsset über AufPosI3D/LiefPosI3D/RechPosI3D); CheckCanMoveToTargetTicket() prüft gebuchte Artikel und Kundenkompatibilität; beim Verschieben werden Sonderartikel entfernt und Vertrag/ArticleWorkItem/Gerät nur auf explizite Anforderung übernommen (AdoptContract/AdoptArticleWorkItem/AdoptDevice); das Benutzerrecht MOVE_HELPDESK_TIMER wird im WPF-Client geprüft (CurrentUserAppRights, Meldung "Der eingeloggte Nutzer darf Zeiten nicht verschieben"). +Aussage: Das System soll das Verschieben einer Zeit auf ein anderes Ticket nur für nicht abgerechnete Zeiten, nach Kompatibilitätsprüfung mit dem Zielticket und nur für Benutzer mit Verschieberecht erlauben; nicht übertragbare Zuordnungen (Sonderartikel) sollen beim Verschieben entfernt werden. +Ergebnis: Zeiten wandern nur kontrolliert und ohne inkonsistente Artikel-/Vertragszuordnung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\WebServices\Sales\Support\HelpdeskTimerWebServiceBL.cs, CheckTimerCanBeMoved() (Zeile ~591) und MoveTimerToTicket() (Zeile ~709, RemoveSpecialArticlesFromTimer) - Begründung: Durchsetzende Abrechnungs- und Kompatibilitätsprüfungen im Server. + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\Helpdesk\TicketDetails\TicketDetailViewModel.cs, Zeile ~3727: "if (CentronCache.Instance.CurrentUserAppRights.Any(f => f.I3D == UserRightsConst.Sales.Customer.Helpdesk.MOVE_HELPDESK_TIMER) == false) disallowedReason = ..." - Begründung: Durchsetzende Rechteprüfung (allerdings nur clientseitig, siehe Selbstbewertung). + - [KONTEXT] CentronRights.md, Abschnitt 8 "Helpdeskzeiten verschieben" - Begründung: Fachliche Rechtedefinition. +Prüfidee: Abgerechnete Zeit verschieben — Ablehnung in Check 1; Zeit mit gebuchten Artikeln auf Ticket eines anderen Kunden — Ablehnung/Warnung in Check 2; Benutzer ohne MOVE_HELPDESK_TIMER — UI verweigert die Aktion. Neuimplementierung: Rechteprüfung zusätzlich serverseitig verankern. +Tracelinks: SyRS-515 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Prüfkette übernehmen; MOVE-Recht muss in der Web-Version serverseitig durchgesetzt werden (im REST-Pfad nicht gefunden). +Status: belegt +``` + +### SwRS-543: Checklisten: Pflichttitel, Soft-Delete und hierarchische Punkte + +``` +ID: SwRS-543 +Titel: Checklisten: Pflichttitel, Soft-Delete und hierarchische Punkte +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente CentronChecklistBL +Vorbedingung: Checkliste wird gespeichert, gelöscht oder ausgewertet +Fakt: SaveOrUpdateCentronChecklist() wirft ohne Caption eine ArgumentException; DeleteCentronChecklist() löscht nicht physisch, sondern setzt IsActive=false; Checklistenpunkte sind hierarchisch (ChecklistItems mit Unterpunkten, Flatten-Auswertung) mit Zustand (CentronChecklistItemState.Open/...); Checklisten sind über ObjectKind/ObjectI3D generisch an Objekte (u. a. Tickets) gebunden und über CustomerMappings kundenspezifisch zuordenbar. +Aussage: Das System soll Checklisten mit Pflichttitel, hierarchischen Punkten mit Bearbeitungszustand und generischem Objektbezug verwalten und beim Löschen deaktivieren statt physisch entfernen. +Ergebnis: Checklistenhistorie bleibt erhalten; unvollständige Checklisten sind auswertbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\CheckListArea\CentronChecklistBL.cs, SaveOrUpdateCentronChecklist(): throw new ArgumentException("The Property Caption is null or has no value...") und DeleteCentronChecklist(): "checklistItem.IsActive = false" - Begründung: Durchgesetzte Pflicht- und Soft-Delete-Regeln. + - [PRIMÄR] src\backend\Centron.BL\CheckListArea\CentronChecklistBL.cs, ObjectHasOpenChecklists(): Flatten(...).Any(State == CentronChecklistItemState.Open) - Begründung: Auswertung des Bearbeitungszustands. +Prüfidee: Checkliste ohne Titel speichern — Fehler; Checkliste löschen — Datensatz bleibt mit IsActive=false erhalten. +Tracelinks: SyRS-520 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - generisches Checklistenmodul ist wiederverwendbar. +Status: belegt +``` + +### SwRS-544: Expected-Events-Definitionen mit Wochentagsfenstern und Musterklassifikation + +``` +ID: SwRS-544 +Titel: Expected-Events-Definitionen mit Wochentagsfenstern und Musterklassifikation +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente ExpectedEventsBL; Administrator (Pflege) +Vorbedingung: Account (Kunde) vorhanden +Fakt: ExpectedEvents speichern je Wochentag Ausführungsfenster (ExecuteMondayFrom/To ... ExecuteSundayFrom/To), Intervalle (TimeBetween*) und Erwartungswerte (ExpectedIncome*), dazu Auslöserart (EventTriggerKind), Aktiv-Flag und Textmuster zur Klassifikation eingehender Meldungen (MessageContainsSuccess/Warning/Error mit zugehörigen ExpectedEventType*-Ergebnistypen); Log-Einträge (ExpectedEventLogEntries) referenzieren AccountI3D, ExpectedEventI3D, EventType (u. a. CompletedWithErrors), MailId, Datei und HelpdeskI3D; beim Löschen einer Definition werden die zugehörigen Logs mitgelöscht. +Aussage: Das System soll je Kunde erwartete wiederkehrende Ereignisse (z. B. Backup-Meldungen) mit Wochentags-Zeitfenstern und Erfolgs-/Warn-/Fehler-Textmustern definieren und eingetroffene bzw. ausgebliebene Ereignisse als klassifizierte Logeinträge mit optionalem Ticketbezug persistieren. +Ergebnis: Ereignisüberwachung ist datenseitig vollständig definiert und mit Tickets verknüpfbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\ExpectedEvents\ExpectedEventsBL.cs, SaveExpectedEvent() (vollständige Feldübernahme inkl. MessageContainsSuccess/Warning/Error) und DeleteExpectedEvent() (kaskadierendes Log-Löschen) - Begründung: Durchgesetztes Datenmodell und Lebenszyklus. + - [SEKUNDÄR] src\backend\Centron.BL\ExpectedEvents\ExpectedEventsBL.cs, CreateLogsFilterExpression(): OnlyWithErrors → EventType == ExpectedEventType.CompletedWithErrors; Projektion mit HelpdeskI3D - Begründung: Klassifikation und Ticketbezug der Logs. +Prüfidee: Expected Event mit Mo-Fenster und Fehler-Muster anlegen, Logeintrag mit EventType CompletedWithErrors erzeugen und über Filter OnlyWithErrors abrufen. +Tracelinks: SyRS-517 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Monitoring-Datenmodell für MSP-Szenarien. +Status: belegt +``` + +### SwRS-545: [HYPOTHESE] Automatische Auswertung eingehender Meldungen gegen Expected Events + +``` +ID: SwRS-545 +Titel: [HYPOTHESE] Automatische Auswertung eingehender Meldungen gegen Expected Events +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System (Mail-/Ereignisverarbeitung) +Vorbedingung: Aktive Expected-Event-Definition; eingehende Meldung (z. B. E-Mail) +Fakt: Das Datenmodell enthält Auswertungsfelder (MessageContains*, EventTriggerKind, EventTriggerdBy, MailId in den Logs) und die Reporting-Oberfläche zeigt Konten mit Logs; eine serverseitige Komponente, die eingehende Mails gegen die Muster prüft und Logeinträge/Tickets automatisch erzeugt, wurde in der analysierten Codebasis (Centron.BL, Webservice) nicht gefunden — die Suche nach Verwendungen von MessageContainsError/IsEventMessageContains trifft nur Mapping und BL-CRUD. +Aussage: Das System soll eingehende Meldungen automatisch gegen die Expected-Event-Muster prüfen, klassifizierte Logeinträge erzeugen und bei ausbleibenden oder fehlerhaften Ereignissen einen Servicevorgang (Ticket) anstoßen. +Ergebnis: Abweichungen werden ohne manuelle Prüfung erkannt. +Belege: + - [SEKUNDÄR] src\backend\Centron.DAO\Mappings\ExpectedEvents\ExpectedEventsMaps.cs (Mapping der MessageContains*-Felder) - Begründung: Auswertungsfelder existieren persistent, was auf eine automatisierte Auswertung hindeutet. + - [KONTEXT] src\centron\Centron.WPF.UI\Modules\Helpdesk\ExpectedEventsReporting\ViewModels\ExpectedEventsReportingViewModel.cs - Begründung: Reporting über Konten mit Ereignis-Logs setzt eine befüllende Instanz voraus. +Prüfidee: Klären, welcher Dienst (z. B. RiverDivo/MailScanner/externer Agent) die Logs erzeugt; danach End-to-End-Test: Fehlermail einliefern — Logeintrag CompletedWithErrors und ggf. Ticket entsteht. +Tracelinks: SyRS-517 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Auswertung muss in der Neuimplementierung serverseitig vorhanden sein. +Status: HYPOTHESE +Offene Frage: Welche Komponente (vermutlich ein externer Dienst oder RiverDivo-Integration) wertet eingehende Meldungen gegen die MessageContains*-Muster aus und erzeugt ExpectedEventLogEntries bzw. Tickets? +``` + +### SwRS-546: SelfCare-Webformulare: GUID-Adressierung, Ablauf und Formulardefinitionen + +``` +ID: SwRS-546 +Titel: SelfCare-Webformulare: GUID-Adressierung, Ablauf und Formulardefinitionen +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente SelfCareBL; REST-Endpunkt SelfCareFormsController +Vorbedingung: SelfCare-Formulare (SelfCareForm mit Feldern, Zuständen, Triggern, Aktionen, Skripten) konfiguriert +Fakt: SelfCareBL verwaltet SelfCareForm/-State/-Trigger/-Action/-Field/-Script als CRUD; SaveWebForm() vergibt bei leerer Guid eine neue und baut SBOUrl "{baseUrl}/webform/{Guid}"; GetWebFormByGuid() liefert "Not found" bei unbekannter Guid und "Link has expired" nach CreatedAt + WebFormLinkExpirationInMinutes (Default 7 Tage); der Webservice-Endpunkt POST v1/SelfCareForms/webform-history erfordert [Authorize] und einen ermittelbaren Benutzer. +Aussage: Das System soll SelfCare-Formulare als konfigurierbare Definitionen (Felder, Zustände, Trigger, Aktionen, Skripte) verwalten und deren externe Bereitstellung ausschließlich über zeitlich begrenzte GUID-Links abwickeln; interne Historisierungsaufrufe sollen authentifiziert sein. +Ergebnis: Kontrollierter, ablaufender Externzugriff auf Formulare; Formularhistorie nur mit Authentifizierung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\SelfCare\SelfCareBL.cs, GetWebFormByGuid()/SaveWebForm() (Guid-Erzeugung, Ablaufprüfung) - Begründung: Durchgesetzte Zugriffsregeln. + - [PRIMÄR] src\webservice\Centron.Controllers\Controllers\v1\SelfCare\SelfCareFormsController.cs, [Authorize]-Attribut und "if (loggedInUser == null) return Unauthorized(...)" - Begründung: Durchgesetzte Authentifizierung des History-Endpunkts. +Prüfidee: Unbekannte GUID abrufen — "Not found"; abgelaufene GUID — "Link has expired"; webform-history ohne Token — 401. +Tracelinks: SyRS-518 +Konsolidierung: Kandidat (vermutet): WebRequestPageBL (src\backend\Centron.BL\SelfCare\WebRequestPageBL.cs) als älterer, paralleler Web-Anfrage-Mechanismus neben den SelfCareForm-WebForms. +Übernahmewürdigkeit: übernehmen - tokenbasierter Formularzugriff ist SaaS-tauglich. +Status: belegt +``` + +### SwRS-547: TaskManager: Wiederholungsregeln, Handler-Dispatch und automatische Tickets + +``` +ID: SwRS-547 +Titel: TaskManager: Wiederholungsregeln, Handler-Dispatch und automatische Tickets +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponenten TaskManagementTaskBL, TaskManagementHelpdeskActionHandler +Vorbedingung: TaskManagementTask mit Recurrence und Aktion (Helpdesk oder Report) gespeichert +Fakt: SaveOrUpdateTask() validiert "Recurrence EndTime is before it's StartTime."; ExecuteTask() sucht den ITaskManagementActionHandler zum Aktionstyp (sonst InvalidOperationException) und schreibt nach Ausführung NextExecutionDate über RecurrenceCalculator (täglich mit DayInterval, wöchentlich mit Pflicht-Wochentagen, monatlich/jährlich inkl. n-ter Wochentag); der Helpdesk-Handler prüft Lizenz ServiceBoardWebDev und Recht ADD_NEW_HELPDESK, erzeugt das Ticket mit CreatedFromObjectKind=TaskManagementClass, DueDate aus Priorität plus DueDateOffset (Ticks) und verwirft Kontaktpersonen, die nicht zum Aktionskunden gehören (Fallback auf Standardkontakt); RepairMissingHelpdeskTickets() kann verwaiste Ausführungen nacherzeugen. +Aussage: Das System soll wiederkehrende Aufgaben mit validierten Wiederholungsregeln ausführen, je Aktionstyp über registrierte Handler dispatchen und automatische Tickets nur bei gültiger Lizenz und Anlage-Recht erzeugen; erzeugte Tickets sollen ihre Herkunft (Task) referenzieren. +Ergebnis: Planbare, reparierbare und rechtskonforme automatische Ticketerzeugung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\TaskManager\ActionHandler\TaskManagementHelpdeskActionHandler.cs, Execute(): Lizenz-/Rechteprüfung, CreatedFromObjectKind=CentronObjectKindNumeric.TaskManagementClass, DueDateOffset-Addition, Kontaktpersonen-Kundenprüfung - Begründung: Durchsetzende Erzeugungsregeln. + - [PRIMÄR] src\backend\Centron.BL\TaskManager\TaskManagementTaskBL.cs, SaveOrUpdateTask()-Validierung, ExecuteTask() Handler-Dispatch, RecurrenceCalculator ("Weekly recurrence must have at least one weekday selected.") - Begründung: Durchgesetzte Wiederholungs- und Ausführungslogik. +Prüfidee: Wöchentliche Regel ohne Wochentag speichern — Fehler; Task ausführen — Ticket mit CreatedFromObjectI3D=Task-I3D und DueDate inkl. Offset; NextExecutionDate liegt auf dem nächsten Regel-Termin. +Tracelinks: SyRS-517 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Herkunftsreferenz und Reparaturlauf sind gute Muster. +Status: belegt +``` + +### SwRS-548: Umfrage-Instanzen aus Vorlagen mit zurückgesetzten Antworten und Sub-Umfragen + +``` +ID: SwRS-548 +Titel: Umfrage-Instanzen aus Vorlagen mit zurückgesetzten Antworten und Sub-Umfragen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente SurveyProcessBL +Vorbedingung: Umfragevorlage (SurveyProcessTemplate) mit Schritten/Bindings vorhanden +Fakt: GetSurveyfromTemplate() erzeugt eine Kopie der Vorlage (I3D=0, IsCopy=true, TemplateI3D=Vorlage), setzt Status=SurveyStatus.Open, Empfänger-/Objektbezug (ContactPersonI3D, ObjectKind, ObjectI3D, RespondentName) und löscht per ReseteAllAnswer() alle Antworten der Schritte; enthaltene Subprozess-Schritte (WorkflowShapeKind.SurveyProcessSubprocess) werden rekursiv als eigene Instanzen kopiert und im Schritt neu referenziert; der Versandlink enthält die verschlüsselte Instanz-ID (CryptoControl.EncryptToString) auf die SBO-URL. +Aussage: Das System soll Umfragen ausschließlich als antwortleere Instanzkopien von Vorlagen (inkl. rekursiver Teil-Umfragen) mit Objekt- und Empfängerbezug erzeugen und über verschlüsselte Links bereitstellen; die Vorlage selbst bleibt unverändert. +Ergebnis: Vorlagen sind wiederverwendbar; jede Antwort gehört eindeutig zu einer Instanz. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Accounts\Survey\SurveyProcessBL.cs, GetSurveyfromTemplate()/CreateSubSurveys()/ReseteAllAnswer() - Begründung: Durchgesetzte Instanziierungs-, Rekursions- und Rücksetzregeln. +Prüfidee: Vorlage mit Sub-Umfrage instanziieren — zwei neue Instanzen mit Status Open, TemplateI3D gesetzt, alle Antworten leer; Vorlage unverändert. +Tracelinks: SyRS-519 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - sauberes Template/Instanz-Muster. +Status: belegt +``` + +### SwRS-549: Ticket-Projekte mit Nummernkreis, Aufgaben, Abhängigkeiten und Logs + +``` +ID: SwRS-549 +Titel: Ticket-Projekte mit Nummernkreis, Aufgaben, Abhängigkeiten und Logs +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente TicketProjectBL +Vorbedingung: Angemeldeter Benutzer legt ein Ticket-Projekt an +Fakt: SaveOrUpdateTicketProject() erzwingt eine Kurzbeschreibung (Guard.NotNullOrWhiteSpace(ShortDescription)), setzt fehlendes PlannedStartDate auf das Tagesdatum und vergibt bei Number <= 0 die nächste Nummer aus dem Nummernkreis NumberGroupEnum.TicketProject; Projekte besitzen Abhängigkeiten (TicketProjectDependency), Aufgaben (TicketProjectTask, Löschen = IsActive=false), Nachrichten und Logs; Tickets referenzieren ihr Projekt über hlpdsk_requests.ProjectHelpdeskI3D bzw. ParentHelpdeskI3D. +Aussage: Das System soll Tickets zu Projekten mit eigenem Nummernkreis, geplantem Startdatum, Aufgaben, Abhängigkeiten, Nachrichten und Protokoll bündeln; Projektaufgaben sollen deaktiviert statt gelöscht werden. +Ergebnis: Zusammenhängende Servicevorhaben sind als Projektstruktur mit Historie abbildbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\TicketProjects\TicketProjectBL.cs, SaveOrUpdateTicketProject() (Guard, PlannedStartDate-Default, GetNextNumber(NumberGroupEnum.TicketProject)) und DeleteTicketProjectTask() (IsActive=false) - Begründung: Durchgesetzte Anlage- und Lebenszyklusregeln. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, [dbo].[hlpdsk_requests] Spalten ProjectHelpdeskI3D, ParentHelpdeskI3D - Begründung: Ticket-Projekt-Verknüpfung im Datenmodell. +Prüfidee: Projekt ohne Kurzbeschreibung speichern — Fehler; zwei Projekte anlegen — fortlaufende Nummern; Aufgabe löschen — Datensatz bleibt mit IsActive=false. +Tracelinks: SyRS-511 +Konsolidierung: Kandidat (vermutet): TicketProjects vs. allgemeines Projektmodul (src\backend\Centron.BL\Projects) — zwei Projektdatenhaltungen für das Konzept "Projekt". +Übernahmewürdigkeit: übernehmen - fachlich sinnvoll, Konsolidierung mit Projektmodul prüfen. +Status: belegt +``` + +### SwRS-550: Ticket-Verknüpfungsnummern mit racesicherer Gruppenanlage + +``` +ID: SwRS-550 +Titel: Ticket-Verknüpfungsnummern mit racesicherer Gruppenanlage +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: Zuverlässigkeit +Akteur: Komponente HelpdeskConnectionNumberBL +Vorbedingung: Mehrere Tickets sollen als zusammengehörig markiert werden +Fakt: GetNextHelpdeskConnectionNumber() vergibt Max(ConnectionNumber)+1; UpdateConnectionNumberForHelpdesks() setzt die Nummer transaktional auf alle gewählten Tickets inkl. ChangedDate/ChangedBy, legt den Gruppendatensatz HelpdeskConnections racesicher per "INSERT ... WHERE NOT EXISTS (... WITH (HOLDLOCK, UPDLOCK))" an (Unique-Verletzung 2627/2601 wird als bereits vorhandener Datensatz toleriert) und räumt leere Vorgänger-Gruppen auf (DeleteEmptyHelpdeskConnections); RemoveConnectionNumberFromHelpdesks() setzt die Nummer auf 0 und bereinigt leere Gruppen. +Aussage: Das System soll Tickets über eine fortlaufende Verknüpfungsnummer gruppieren, die Gruppenzuordnung transaktional und nebenläufigkeitssicher pflegen und verwaiste Gruppen automatisch entfernen. +Ergebnis: Konsistente Ticketgruppen auch bei parallelen Zugriffen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskConnectionNumberBL.cs, UpdateConnectionNumberForHelpdesks()/EnsureHelpdeskConnection() (HOLDLOCK/UPDLOCK-Upsert, WithTransaction) - Begründung: Durchgesetzte Konsistenz- und Nebenläufigkeitsregeln. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, [dbo].[hlpdsk_requests] Spalte Verknuepfungsnummer - Begründung: Persistenz der Gruppenzuordnung am Ticket. +Prüfidee: Zwei parallele Zuordnungen derselben neuen Nummer — genau ein HelpdeskConnections-Datensatz entsteht; Entfernen aller Tickets einer Gruppe — Gruppendatensatz wird gelöscht. +Tracelinks: SyRS-511 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Muster für nebenläufigkeitssichere Upserts. +Status: belegt +``` + +## Cluster A6 — Stammdaten & Assets — SwRS + +### SwRS-620: Operationsbezogene Rechteprüfung in AccountBL inkl. Betreuer-Einschränkung + +``` +ID: SwRS-620 +Titel: Operationsbezogene Rechteprüfung in AccountBL inkl. Betreuer-Einschränkung +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente Centron.BL AccountBL +Vorbedingung: Aufruf GetAccount/SaveAccount/DeleteAccount durch angemeldeten AppUser +Fakt: ValidateUserRights prüft per AppRightsBL.CheckRightsFromUser die Konstanten CREATE_CUSTOMER (20400092), EDIT_CUSTOMER, DELETE_CUSTOMER, SEARCH_CUSTOMER, UNLOCK_CUSTOMER, RIGHT_LIEFERANTANLEGEN, RIGHT_LIEFERANTAENDERN; GetAccount weist zusätzlich Benutzer mit Recht SHOW_ONLY_OWN_CUSTOMER (20400339) ab, wenn der Mitarbeiter in keinem der Felder Adviser1I3D..Adviser6I3D des Accounts steht ("Nur Accounts für die man Verantworlich ist können geladen werden"). +Aussage: Die Software soll je Account-Operation die passende Rechtekonstante prüfen und bei gesetztem Einschränkungsrecht SHOW_ONLY_OWN_CUSTOMER nur Accounts liefern, bei denen der anfragende Mitarbeiter als einer von bis zu sechs Betreuern hinterlegt ist. +Ergebnis: Zugriff scheitert mit RightCheckFailed bzw. Fehlermeldung, wenn Recht fehlt oder Betreuerbindung verletzt ist. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Accounts\AccountBL.cs, GetAccount: Vergleich Adviser1I3D..Adviser6I3D gegen employeI3D und `if (this._appRightsBL.HasUserRight(..., SHOW_ONLY_OWN_CUSTOMER)) return Result.AsError(...)` - Begründung: durchsetzende Betreuer-Einschränkung. + - [PRIMÄR] src\backend\Centron.BL\Accounts\AccountBL.cs, ValidateUserRights(int, ...) mit den genannten UserRightsConst-Prüfungen - Begründung: durchsetzende Operationsrechte. + - [KONTEXT] src\webservice\Centron.WebServices.Core\EntitiesWrongPlace\Administration\Rights\UserRightsConst.cs (CREATE_CUSTOMER=20400092, SHOW_ONLY_OWN_CUSTOMER=20400339) - Begründung: Rechte-IDs. +Prüfidee: Benutzer mit SHOW_ONLY_OWN_CUSTOMER lädt fremden Account → Fehler; als Adviser2 eingetragen → Erfolg. +Tracelinks: SyRS-605 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Betreuerprinzip ist gängige Vertriebsanforderung. +Status: belegt +``` + +### SwRS-621: Initialisierung neuer Accounts mit Standardadresse, Nummern und Einstellungen + +``` +ID: SwRS-621 +Titel: Initialisierung neuer Accounts mit Standardadresse, Nummern und Einstellungen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente AccountBL.GetNewAccount / SaveAccount +Vorbedingung: Neuanlage (I3D <= 0) mit gültigem Accounttyp +Fakt: GetNewAccount erzeugt den Account mit Nummer aus NumberGroupEnum.Account, genau einer Default-Adresse (IsDefault=true, AddressKind=1 „Rechnungs-/Lieferadresse"), Kundennummer aus NumberGroupEnum.Customer bzw. Lieferantennummer aus NumberGroupEnum.Supplier; die Buchhaltungsnummer wird abhängig von AppSettingsConst.AccountsBookKeepingNumberEqualsCustomerNumber/-SupplierNumber aus der Nummer plus optionalem Präfix abgeleitet; Kundendefaults (Preisliste, Bestellnummernpflicht, InvoiceDeliveryKind, Sperr-Mahnstufe) kommen aus CustomerSettings/AppSettings. +Aussage: Die Software soll neue Geschäftspartner mit genau einer Standardadresse vom Typ Rechnungs-/Lieferadresse, automatisch vergebenen Account-/Kunden-/Lieferantennummern und aus zentralen Einstellungen abgeleiteten Vorgabewerten (u. a. Buchhaltungsnummer mit optionalem Präfix, Standard-Preisliste, Bestellnummernpflicht) initialisieren. +Ergebnis: Neuer Account ist ohne manuelle Nacharbeit buchhaltungs- und belegfähig. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Accounts\AccountBL.cs, GetNewAccount (defaultAddress.Data.IsDefault = true; AddressKind = 1; NumberGroupBL.GetNextNumber(...); BookKeepingNumber-Ableitung inkl. Präfix) - Begründung: implementierte Initialisierungslogik. + - [SEKUNDÄR] src\backend\Centron.BL\Administration\Settings\AppSettingsConst.cs, Konstanten AccountsBookKeepingNumberEqualsCustomerNumber/-Prefix - Begründung: Konfigurationsschalter der Ableitung. +Prüfidee: Setting "Buchhaltungsnummer = Kundennummer" mit Präfix "D" aktivieren, Kunde anlegen → BookKeepingNumber == "D"+Kundennummer. +Tracelinks: SyRS-606 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Vorgabewerte reduzieren Erfassungsfehler. +Status: belegt +``` + +### SwRS-622: Datenbankseitige Eindeutigkeit der Geschäftspartnernummern + +``` +ID: SwRS-622 +Titel: Datenbankseitige Eindeutigkeit der Geschäftspartnernummern +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: SQL-Server-Datenbank +Vorbedingung: Insert/Update auf Accounts, AccountCustomers, AccountSuppliers +Fakt: Unique-Indizes/Constraints IX_Accounts_Number (Accounts.Number), IX_AccountCustomers_UniqueNumber (AccountCustomers.Number), IX_AccountSuppliers_UniqueNumber (AccountSuppliers.Number) existieren im Schema. +Aussage: Die Software soll Account-, Kunden- und Lieferantennummern zusätzlich zur Anwendungslogik durch eindeutige Datenbankindizes gegen Duplikate absichern. +Ergebnis: Ein Insert mit bereits vergebener Nummer schlägt auf DB-Ebene fehl. +Belege: + - [PRIMÄR] SSMS_DB_SCHEMA.sql, `CREATE UNIQUE NONCLUSTERED INDEX [IX_Accounts_Number] ON [dbo].[Accounts]`; `CONSTRAINT [IX_AccountCustomers_UniqueNumber] UNIQUE NONCLUSTERED`; `CONSTRAINT [IX_AccountSuppliers_UniqueNumber] UNIQUE NONCLUSTERED` - Begründung: DB-Constraints sind die durchsetzende Stelle. +Prüfidee: Direkter SQL-Insert eines zweiten AccountCustomers mit gleicher Number → Unique-Key-Verletzung. +Tracelinks: SyRS-606 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Dublettenprävention auf Persistenzebene ist Pflicht. +Status: belegt +``` + +### SwRS-623: Löschschutz für Accounts mit offenen Vorgängen + +``` +ID: SwRS-623 +Titel: Löschschutz für Accounts mit offenen Vorgängen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente AccountBL.DeleteAccount +Vorbedingung: Benutzer mit DELETE_CUSTOMER löst Löschung aus; Account besitzt Kundennummer +Fakt: DeleteAccount prüft nacheinander offene Posten (AccountStatisticBL.GetAccountUnpaidInvoiceOverview, ObjectKind InvoiceClass), aktive Helpdesks (HelpdeskSearchBL.GetActiveHelpdesksFromCustomer) und nicht geschlossene Verträge (ReceiptSearcher mit ContractClass, IncludeClosedReceipts=false) und bricht jeweils mit InvalidDeleteRequest ab; erst danach erfolgt _accountRepository.DeleteAccount. +Aussage: Die Software soll die Löschung eines Accounts genau dann verweigern, wenn zu seiner Kundennummer offene Posten, aktive Tickets oder nicht geschlossene Verträge existieren, und den Grund in der Fehlermeldung benennen. +Ergebnis: Referenzielle und buchhalterische Konsistenz bleibt erhalten. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Accounts\AccountBL.cs, DeleteAccount: drei Abbruchprüfungen mit Fehlern "Account kann nicht gelöscht werden da noch offene Posten/Heldesks/Verträge vorhanden sind." (DefaultMessageCodes.InvalidDeleteRequest) - Begründung: durchsetzende Prüfkette vor Löschung. +Prüfidee: Account mit aktivem Ticket löschen → Fehler; Ticket schließen, erneut löschen → Erfolg. +Tracelinks: SyRS-606 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - fachlich zwingender Integritätsschutz. +Status: belegt +``` + +### SwRS-624: Feldbezogene Rechte für Adresssprache und -währung mit Wertrücksetzung + +``` +ID: SwRS-624 +Titel: Feldbezogene Rechte für Adresssprache und -währung mit Wertrücksetzung +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente AccountAddressBL +Vorbedingung: Speichern einer bestehenden Adresse (I3D != 0) +Fakt: CheckSpecialUserRightForAddressLanguageBeforeSave/-CurrencyBeforeSave prüfen EDIT_CUSTOMER_ADDRESS_LANGUAGE bzw. EDIT_CUSTOMER_ADDRESS_CURRENCY; fehlt das Recht, wird eine geänderte LanguageI3D/CurrencyI3D per IsDirtyProperty erkannt und via GetOriginalEntityProperty auf den ursprünglichen Wert zurückgesetzt; AccountSaveAddress erlaubt bei fehlendem allgemeinen Editierrecht dennoch das isolierte Speichern von Sprache/Währung, wenn genau diese Spezialrechte vorhanden sind. +Aussage: Die Software soll die Felder Sprache und Währung einer Kundenadresse nur mit den jeweiligen Spezialrechten änderbar machen; ohne Recht sollen unerlaubte Feldänderungen still auf den Originalwert zurückgesetzt werden, während Benutzer, die nur diese Spezialrechte besitzen, ausschließlich diese Felder ändern können. +Ergebnis: Feldgenaue Autorisierung ohne Abbruch des gesamten Speichervorgangs. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Accounts\AccountAddressBL.cs, CheckSpecialUserRightForAddressLanguageBeforeSave: `if (this.Session.GetSession().IsDirtyProperty(address, nameof(address.LanguageI3D))) { address.LanguageI3D = (int)...GetOriginalEntityProperty(...); }` (analog Currency) - Begründung: durchsetzende Rücksetzlogik. + - [PRIMÄR] ebd., AccountSaveAddress: Sonderpfad bei RightCheckFailed mit Evict/Reload und selektiver Übernahme von LanguageI3D/CurrencyI3D - Begründung: isolierter Feld-Speicherpfad. +Prüfidee: Benutzer ohne Spezialrecht ändert Sprache und Straße → Straße gespeichert, Sprache unverändert; Benutzer nur mit Sprachrecht ändert Sprache → gespeichert. +Tracelinks: SyRS-605 +Konsolidierung: nein +Übernahmewürdigkeit: Sonderfall - feldgenaue Rechte übernehmen, stilles Zurücksetzen sollte in der Neuimplementierung durch explizite Fehlermeldung ersetzt werden. +Status: belegt +``` + +### SwRS-625: Ansprechpartnerpflege mit rollenabhängigen Rechten und Abteilungsnormalisierung + +``` +ID: SwRS-625 +Titel: Ansprechpartnerpflege mit rollenabhängigen Rechten und Abteilungsnormalisierung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente AccountAddressContactBL +Vorbedingung: Speichern eines Ansprechpartners zu einer Account-Adresse +Fakt: AccountSaveAddressContact prüft je nachdem, ob der Account Kunde oder Lieferant ist, getrennte Anlage-/Änderungsrechte (Fehler "Fehlendes Recht um Lieferantenansprechpartner/Kundenansprechpartner zu erstellen/bearbeiten"); UpdateDepartmentI3DAndDepartmentText normalisiert die Abteilung: DepartmentI3D hat Vorrang, freier DepartmentText wird gegen ContactDepartments aufgelöst und ist nur bei gesetztem AppSetting CanEnterCustomContactPersonDepartment als Freitext zulässig, sonst werden beide Felder geleert; Telefonnummern werden zusätzlich in die TAPI-Tabelle (TAPINummern) gespiegelt. +Aussage: Die Software soll Ansprechpartner nur mit dem zur Partnerrolle (Kunde/Lieferant) passenden Recht anlegen bzw. ändern lassen, Abteilungsangaben gegen den Abteilungskatalog normalisieren (Freitext nur per Konfigurationsschalter) und Telefonnummern für die Telefonie-Integration redundant fortschreiben. +Ergebnis: Konsistente Ansprechpartnerdaten mit auflösbarer Abteilung und TAPI-Anbindung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Accounts\AccountAddressContactBL.cs, AccountSaveAddressContact + ValidateUserRights (rollenspezifische Fehlermeldungen) - Begründung: durchsetzende Rechteprüfung. + - [PRIMÄR] ebd., UpdateDepartmentI3DAndDepartmentText (Priorität I3D → Text → leer; AppSetting CanEnterCustomContactPersonDepartment) - Begründung: implementierte Normalisierungsregel. +Prüfidee: Ansprechpartner mit unbekanntem Abteilungstext bei deaktiviertem Freitext-Setting speichern → DepartmentI3D und DepartmentText sind leer. +Tracelinks: SyRS-605 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Normalisierung ja; TAPI-Doppelhaltung als Altlast prüfen (Workaround-Charakter). +Status: belegt +``` + +### SwRS-626: Geokodierungsstatus von Account-Adressen + +``` +ID: SwRS-626 +Titel: Geokodierungsstatus von Account-Adressen +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente AccountAddressBL, Geokodierungs-Job +Vorbedingung: Adressen ohne GeoInfo vorhanden +Fakt: GetNotImportedGeoInfoList liefert alle AccountAddresses mit GeoInfo == null und GeoInfoUpdateFailed == false; SaveGeoCoding persistiert das Geokodierungsergebnis; GeocodingUpdateWithGeoInfoUpdateFailed markiert fehlgeschlagene Adressen dauerhaft mit GeoInfoUpdateFailed = true. +Aussage: Die Software soll je Adresse einen Geokodierungsstatus führen: noch nicht kodierte Adressen für einen Kodierungslauf bereitstellen, erfolgreiche Ergebnisse (GeoInfo) speichern und dauerhaft fehlgeschlagene Adressen kennzeichnen, damit sie nicht erneut verarbeitet werden. +Ergebnis: Adressen sind für Karten-/Routenfunktionen georeferenziert; Fehlversuche werden nicht wiederholt. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Accounts\AccountAddressBL.cs, GetNotImportedGeoInfoList (Filter GeoInfo == null && GeoInfoUpdateFailed == false), SaveGeoCoding, GeocodingUpdateWithGeoInfoUpdateFailed (entity.GeoInfoUpdateFailed = true) - Begründung: vollständiger persistierter Statuszyklus. +Prüfidee: Adresse als fehlgeschlagen markieren → sie erscheint nicht mehr in GetNotImportedGeoInfoList. +Tracelinks: SyRS-606 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Statusmodell sinnvoll; aufrufender Geokodierungsdienst ist außerhalb des BL zu klären. +Status: belegt +``` + +### SwRS-627: Dublettenprüfung von Logins und OpenID-Kennungen + +``` +ID: SwRS-627 +Titel: Dublettenprüfung von Logins und OpenID-Kennungen +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponenten AppUserBL und WebAccountBL +Vorbedingung: Speichern eines AppUsers bzw. WebAccounts mit (geändertem) Benutzernamen +Fakt: AppUserBL.SaveOrUpdateAppUser vergleicht Name case-insensitiv/getrimmt gegen alle anderen AppUser und gegen WebAccounts (Fehlermeldung nennt WebAccount, Kundenname und Kundennummer) und prüft OpenIdConnectSubjectIdentifier auf Eindeutigkeit; WebAccountBL.CheckDuplicateUsername prüft bei Anlage und Namensänderung gegen WebAccounts und AppUser. +Aussage: Die Software soll beim Speichern von Benutzerkonten den Login-Namen normalisiert (lowercase, getrimmt) gegen beide Kontotabellen (AppUser, WebAccounts) sowie die OpenID-Connect-Subjektkennung gegen alle Benutzer prüfen und bei Treffern das Speichern mit benennender Fehlermeldung ablehnen. +Ergebnis: Kein doppelter Login, keine mehrfach zugeordnete SSO-Kennung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\EmployeeArea\AppUserBL.cs, SaveOrUpdateAppUser (Zeilen 160-186: AppUser-Check "The user login (...) is already in use", WebAccount-Check, OpenIdConnectSubjectIdentifier-Check "Die Benutzerkennung '...' ist bereits in Gebrauch ...") - Begründung: alle drei Prüfungen an der Speicherstelle. + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\WebAccountBL.cs, CheckDuplicateUsername (Zeilen 637-650) - Begründung: Gegenprüfung beim WebAccount-Speichern. +Prüfidee: AppUser "Anna" existiert; WebAccount "anna" anlegen → Fehler "... bereits an Mitarbeiter ... vergeben." +Tracelinks: SyRS-607 +Konsolidierung: Kandidat: dieselbe Dublettenlogik ist doppelt implementiert (AppUserBL und WebAccountBL) statt zentralisiert. +Übernahmewürdigkeit: übernehmen - fachlich; technisch in einen gemeinsamen Dienst konsolidieren. +Status: belegt +``` + +### SwRS-628: Mitarbeiterspeicherung mit Rechteprüfung und Personalakten-Ordnern + +``` +ID: SwRS-628 +Titel: Mitarbeiterspeicherung mit Rechteprüfung und Personalakten-Ordnern +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente EmployeeBL.SaveOrUpdateEmployee +Vorbedingung: LoggedInUser speichert Employee (Tabelle Personal) +Fakt: Die Methode bricht ohne ADMINISTRATE_ALL_EMPLOYEES (20400053) ab; fehlende Ordner-Referenzen (RootDirI3D, CertificateDirI3D, ContractDirI3D, ConversationNoteDirI3D, JobApplicationDirI3D, MiscDirI3D, QMDirI3D, SkillDirI3D) werden durch DirectoryBL.CreateDirectory unterhalb des per AppSettingsConst.EmployeeRootDirectory konfigurierten Wurzelordners angelegt (Ordnername = ShortSign des Mitarbeiters); anschließend wird ein Probezeit-ToDo (ToDoBL.SaveEmployeeToDo → TaskTrialPeriodI3D) erzeugt. +Aussage: Die Software soll das Speichern von Mitarbeitern nur mit dem Recht "alle Mitarbeiter administrieren" zulassen, dabei fehlende Personalakten-Ordner (Zertifikate, Verträge, Gesprächsnotizen, Bewerbungsunterlagen, Sonstige Dokumente, Qualitätsmanagement, Skills) automatisch unter dem konfigurierten Mitarbeiter-Wurzelverzeichnis anlegen und eine Probezeit-Aufgabe verknüpfen. +Ergebnis: Vollständige, einheitliche Personalakte je Mitarbeiter. +Belege: + - [PRIMÄR] src\backend\Centron.BL\EmployeeArea\EmployeeBL.cs, SaveOrUpdateEmployee (Zeilen 128-255): Rechteprüfung, acht CreateDirectory-Blöcke, SaveEmployeeToDo/TaskTrialPeriodI3D - Begründung: durchsetzende Stelle mit konkreter Bedingung. + - [SEKUNDÄR] src\backend\Centron.DAO\Mappings\EmployeeArea\EmployeeBaseMaps.cs, Table("Personal") - Begründung: Tabellenzuordnung des Mitarbeiterstamms. +Prüfidee: Neuen Mitarbeiter speichern → unter dem Mitarbeiterordner existieren die sieben Standardunterordner; ohne Recht → Fehler. +Tracelinks: SyRS-608 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Ordnerliste in der Neuimplementierung konfigurierbar gestalten. +Status: belegt +``` + +### SwRS-629: Zeitgesteuerte Deaktivierung von Benutzerkonten + +``` +ID: SwRS-629 +Titel: Zeitgesteuerte Deaktivierung von Benutzerkonten +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente AppUserBL.GetActiveAppUsers +Vorbedingung: Benutzerkonten mit Sperrkennzeichen bzw. Sperrzeitraum vorhanden +Fakt: GetActiveAppUsers liefert nur AppUser mit IsAccountDisabled == false, deren Sperrzeitraum (AccountDisabledFromDate/AccountDisabledToDate) das heutige Datum nicht einschließt, und deren Employee.IsActive true ist. +Aussage: Die Software soll Benutzerkonten sowohl dauerhaft (Kennzeichen) als auch für einen definierten Zeitraum (Von-/Bis-Datum) deaktivieren können; als aktiv gelten nur Konten aktiver Mitarbeiter außerhalb eines laufenden Sperrzeitraums. +Ergebnis: Zeitlich befristete Abwesenheits-/Austrittssperren ohne Datenlöschung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\EmployeeArea\AppUserBL.cs, GetActiveAppUsers (Zeilen 38-55): Datumsvergleiche DateTime.Today gegen AccountDisabledFromDate/ToDate und Filter f.Employee.IsActive - Begründung: implementierte Aktivitätsregel. +Prüfidee: Konto mit Sperrzeitraum über heute abfragen → nicht in Aktivliste; Sperrzeitraum in der Zukunft → in Aktivliste. +Tracelinks: SyRS-607 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Standardanforderung an Benutzerverwaltung. +Status: belegt +``` + +### SwRS-630: Integritätsregeln und Lebenszyklus des Stammblatts + +``` +ID: SwRS-630 +Titel: Integritätsregeln und Lebenszyklus des Stammblatts +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente MasterDataListBL +Vorbedingung: Speichern, Schließen oder Reaktivieren eines Stammblatts (MasterDataList) +Fakt: SaveMasterDataList erzwingt genau eine Hauptposition (IsMainItem) mit Quantity == 1, setzt Number = I3D, legt per EnsureMasterDataListDirectoryExists einen Dokumentordner an (Fehler, wenn kein Kunde zugeordnet: "Stammblatt ist keinem Kunden zugeordnet") und schreibt Änderungsmeldungen als ReceiptLog (ReceiptLogKind.MasterDatalist); CloseMasterDataList setzt IsActive = false nur, wenn kein zugeordneter Vertrag im Status ReceiptState.Active existiert; ReactivateMasterDataList setzt IsActive = true. +Aussage: Die Software soll je Stammblatt genau eine Hauptgeräteposition mit Menge 1 erzwingen, das Stammblatt einem Kunden und einem Dokumentordner zuordnen, alle Änderungen protokollieren und das Schließen nur zulassen, wenn kein aktiver Vertrag auf das Stammblatt verweist; geschlossene Stammblätter sollen reaktivierbar sein. +Ergebnis: Stammblätter bleiben als Abrechnungsobjekte konsistent und historisiert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\CustomerAssets\Contracts\ClickContracts\MasterDataListBL.cs, SaveMasterDataList (drei Hauptpositions-Prüfungen, Zeilen 94-101; ReceiptLog-Erzeugung Zeilen 136-143) und CloseMasterDataList (Vertragsprüfung ReceiptState.Active, Zeilen 157-164) - Begründung: durchsetzende Validierungs- und Statuslogik. +Prüfidee: Stammblatt mit zwei Hauptpositionen speichern → Fehler "Es darf nur eine Hauptposition geben."; Stammblatt eines aktiven Vertrags schließen → Fehler. +Tracelinks: SyRS-609 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - abrechnungsrelevante Kernregeln. +Status: belegt +``` + +### SwRS-631: Seriennummernwechsel am Stammblatt nur ohne aktive Klickzähler + +``` +ID: SwRS-631 +Titel: Seriennummernwechsel am Stammblatt nur ohne aktive Klickzähler +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente MasterDataListBL (RemoveMainDeviceSerialNumber, SwapMainDeviceSerialNumber) +Vorbedingung: Stammblatt mit Hauptgeräte-Seriennummer vorhanden +Fakt: RemoveMainDeviceSerialNumber verweigert die Entfernung, wenn HasActiveCountersOnSerialNumber (DeviceClickCounter-Abfrage) aktive Zähler auf der Seriennummer findet ("Seriennummer kann nicht entfernt werden, weil noch aktive Zähler hängen. Bitte die Seriennummer tauschen."); SwapMainDeviceSerialNumber prüft Existenz der neuen Seriennummer, Ungleichheit zur alten und hängt Zähler um; jede Änderung wird als Historieneintrag geschrieben (Stammblatt-Historie). +Aussage: Die Software soll die Hauptgeräte-Seriennummer eines Stammblatts nur entfernen lassen, wenn keine aktiven Klickzähler daran hängen, und beim Tausch der Seriennummer die Zählerbindung auf das neue Gerät übertragen sowie den Wechsel in der Stammblatt-Historie dokumentieren. +Ergebnis: Zählerstände und Abrechnung bleiben beim Gerätetausch lückenlos. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\CustomerAssets\Contracts\ClickContracts\MasterDataListBL.cs, RemoveMainDeviceSerialNumber (Zeilen 283-305, Prüfung HasActiveCountersOnSerialNumber) und SwapMainDeviceSerialNumber (Zeilen 336-387, Prüfungen neue/alte Seriennummer, DeviceClickCounter-Umzug) - Begründung: durchsetzende Bedingungen der Zählerbindung. +Prüfidee: Seriennummer mit aktivem Zähler entfernen → Fehler DependencyCheckFailed; Tausch auf neue Seriennummer → Zähler zeigen auf neue SerialNumberI3D, Historieneintrag existiert. +Tracelinks: SyRS-609 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - schützt die verbrauchsbasierte Fakturierung. +Status: belegt +``` + +### SwRS-632: Soft-Delete und lückenlose Protokollierung von Kundengeräten + +``` +ID: SwRS-632 +Titel: Soft-Delete und lückenlose Protokollierung von Kundengeräten +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente AccountDeviceBL +Vorbedingung: AccountDevice wird angelegt, geändert oder gelöscht +Fakt: SaveAccountDevice setzt Created*/Changed*-Felder auf currentUser.Employee.I3D/DateTime.Now und schreibt AccountDeviceLog ("Das Gerät wurde erstellt/aktualisiert von "); DeleteAccountDevice setzt IsDeleted=true, DeletedDate, DeletedByI3D und protokolliert "Das Gerät wurde gelöscht"; SearchAccountDevices filtert IsDeleted, sofern IncludeDeleted nicht gesetzt ist. +Aussage: Die Software soll Kundengeräte niemals physisch löschen, sondern mit Benutzer und Zeitstempel als gelöscht markieren, jede Anlage/Änderung/Löschung in einem Gerätelog festhalten und gelöschte Geräte standardmäßig aus Suchergebnissen ausblenden. +Ergebnis: Vollständige Gerätehistorie; versehentliche Löschungen sind nachvollziehbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Devices\AccountDeviceBL.cs, SaveAccountDevice/DeleteAccountDevice/WriteAccountDeviceLog/SearchAccountDevices (IsDeleted-Filter Zeile 126-129) - Begründung: implementierter Soft-Delete- und Logmechanismus. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[AccountDeviceLogs] (AccountDeviceI3D, Message, Timestamp, CreatedByI3D) - Begründung: persistentes Logschema. +Prüfidee: Gerät löschen → Datensatz bleibt mit IsDeleted=1 erhalten, Logeintrag vorhanden, Standard-Suche liefert es nicht mehr. +Tracelinks: SyRS-610 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Soft-Delete-Muster für Neuimplementierung fortführen. +Status: belegt +``` + +### SwRS-633: Getrennte Datenhaltungen für Kundengeräte (Konsolidierungsfall) + +``` +ID: SwRS-633 +Titel: Getrennte Datenhaltungen für Kundengeräte (Konsolidierungsfall) +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponenten MasterDataListBL, AccountDeviceBL, SelfCare/River-Anbindung +Vorbedingung: Geräte werden je nach Herkunft/Zweck erfasst +Fakt: Drucker/Kopierer mit Klickabrechnung liegen in Tabelle MasterDataList (Entity MasterDataList, Felder SerialNumber, CounterDevice, ContractI3D); sonstige Kundenhardware liegt in Tabelle AccountDevices (Entity AccountDevice, Felder SerialNumber, Model, Manufacturer, Location); extern per Monitoring/AD synchronisierte Geräte werden über RiverConnectionBL/DocuBoard mit eigener Objektart AssetManagementDeviceClass (5101330) und eigenen Entities (AssetManagementPartnerItem u. a.) geführt; es existiert keine gemeinsame Tabelle oder Sicht. +Aussage: Die Software führt heute drei getrennte Datenhaltungen für den Gegenstand „Gerät beim Kunden"; eine Neuimplementierung soll diese zu einem einheitlichen Gerätestamm mit Spezialisierung (zählerbehaftet/abrechnungsrelevant, manuell erfasst, extern synchronisiert) konsolidieren. +Ergebnis: Ein Gerät existiert künftig genau einmal mit klarer Herkunfts- und Abrechnungskennzeichnung. +Belege: + - [PRIMÄR] src\backend\Centron.Entities\Entities\Sales\Receipts\MasterDataLists\MasterDataList.cs und src\backend\Centron.Entities\Entities\Devices\AccountDevice.cs (überlappende Felder SerialNumber, Kundenbezug) - Begründung: zwei Entitäten/Tabellen für denselben Gegenstand. + - [SEKUNDÄR] src\backend\Centron.BL\WebServices\SelfCare\SelfCareWebserviceBL.cs (Zeilen 2217-2296, RiverConnectionBL.GetDevices/GetSNMPDevices mit ObjectKind AssetManagementDeviceClass) und src\backend\Centron.Entities\Entities\DocuBoard\AssetManagementPartnerItem.cs - Begründung: dritte, extern gespeiste Gerätequelle. + - [SEKUNDÄR] src\backend\Centron.Interfaces\CentronObjectKindNumeric.cs, MasterDataListClass=25 → "Stammblatt", AssetManagementDeviceClass=5101330 - Begründung: getrennte Objektarten im Typsystem. +Prüfidee: Datenmodellanalyse: dieselbe physische Seriennummer kann heute gleichzeitig in MasterDataList und AccountDevices existieren, ohne dass das System dies erkennt. +Tracelinks: SyRS-609, SyRS-610 +Konsolidierung: Kandidat: MasterDataList (Stammblätter) + AccountDevices + AssetManagement/River-Geräte — drei Implementierungen derselben fachlichen Funktion. +Übernahmewürdigkeit: Workaround - historisch gewachsene Trennung; fachliche Funktion übernehmen, Datenhaltung konsolidieren. +Status: belegt +``` + +### SwRS-634: Länderstamm mit EZB-Kursaktualisierung und Verteilungslogik + +``` +ID: SwRS-634 +Titel: Länderstamm mit EZB-Kursaktualisierung und Verteilungslogik +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Komponente CountryBL +Vorbedingung: Länderstamm mit CurrencyISO gepflegt; EZB-XML erreichbar +Fakt: UpdateCurrencyRateByRateDictionary lädt eurofxref-daily.xml der EZB, ergänzt EUR=1.00, rechnet bei Standardland "Schweiz" alle Kurse auf CHF-Basis um (CalculateCHFCurrencies) und schreibt KursZuEur je aktivem Land; Länder mit leerer oder "?"-Währung werden übersprungen; UpdateCurrencyRateByCountry synchronisiert den Kurs manuell geänderter Länder auf alle aktiven Länder derselben Währung; UpdateArticleMaterialGroupsWithDefaultCountryValues verteilt Standardland-Werte (VatI3D, TaxRate, CurrencyRate) per Named Query auf Artikelwarengruppen. +Aussage: Die Software soll Wechselkurse aller aktiven Länder aus der EZB-Referenzkursliste aktualisieren (mit CHF-Umrechnung für Schweizer Installationen), Kursänderungen auf alle Länder gleicher Währung übertragen und Standardland-Steuer-/Kurswerte in abhängige Artikelstammdaten verteilen. +Ergebnis: Konsistente Kurse und Steuerbezüge über Länder und Artikelgruppen hinweg. +Belege: + - [PRIMÄR] src\backend\Centron.BL\CountryArea\CountryBL.cs, UpdateCurrencyRateByRateDictionary (EZB-URL, CHF-Zweig), UpdateCurrencyRateByCountry, UpdateArticleMaterialGroupsWithDefaultCountryValues (NamedQuery UpdateArticleMaterialAndSecondaryMaterialGroupWithDefaultCountryValues) - Begründung: implementierte Aktualisierungs- und Verteilungslogik. +Prüfidee: Kurs eines Landes ändern → alle aktiven Länder mit gleicher CurrencyISO tragen denselben Kurs. +Tracelinks: SyRS-613 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - fest codierte HTTP-URL und Spezialfall-String "Schweiz"; fachlich übernehmen, technisch als konfigurierbaren Kursdienst neu bauen. +Status: belegt +``` + +### SwRS-635: Normalisierung und Wiederverwendung von Tags + +``` +ID: SwRS-635 +Titel: Normalisierung und Wiederverwendung von Tags +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente TagsBL +Vorbedingung: Benutzer vergibt ein Schlagwort an ein Ticket +Fakt: AddTicketTag sucht per GetTag (Caption.ToLower().Trim(), auch inaktive) ein bestehendes Tag und legt nur bei Nichtexistenz ein neues an (AddTag speichert Caption lowercase/getrimmt, ShowInSuggestions=true); inaktive Tags werden bei erneuter Verwendung reaktiviert (ShowInSuggestions=true); die Zuordnung wird als TicketTag (TicketI3D, TagI3D, Caption) gespeichert; RemoveTicketTag entfernt Zuordnungen per normalisierter Caption; Tabellen Tags/TicketTags haben keinen Unique-Index auf Caption. +Aussage: Die Software soll Schlagworte normalisiert (Kleinschreibung, getrimmt) speichern, vorhandene — auch ausgeblendete — Tags bei erneuter Vergabe wiederverwenden und reaktivieren statt Duplikate anzulegen, und die Zuordnung zu Objekten getrennt vom Tag-Katalog führen. +Ergebnis: Ein fachliches Schlagwort existiert genau einmal im Katalog. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Tags\TagsBL.cs, AddTicketTag (GetTag ?? AddTag; Reaktivierung ShowInSuggestions), GetTag/AddTag (ToLower().Trim()) - Begründung: implementierte Normalisierungs- und Wiederverwendungslogik. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[Tags] / [TicketTags] (kein Unique-Constraint auf Caption) - Begründung: Eindeutigkeit nur applikationsseitig gesichert. +Prüfidee: Tag "VPN" und danach " vpn " vergeben → Tabelle Tags enthält genau einen Datensatz "vpn". +Tracelinks: SyRS-611 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - in der Neuimplementierung zusätzlich per Unique-Constraint absichern. +Status: belegt +``` + +### SwRS-636: Zusatzfeld-Definitionen mit Validierung, EAV-Speicherung und Passwortprotokoll + +``` +ID: SwRS-636 +Titel: Zusatzfeld-Definitionen mit Validierung, EAV-Speicherung und Passwortprotokoll +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponenten ModuleCustomPropertyBL / ModuleCustomPropertyValueBL; UI-Komponente CustomPropertiesGridViewModel +Vorbedingung: Zusatzfelder je Objektart definiert; Benutzer erfasst Werte +Fakt: SaveCustomPropertyStructure weist Definitionen ohne Namen oder mit unbekanntem Datentyp ab und bindet sie an ObjectKind/ObjectI3D; Werte liegen typisiert in ModuleCustomPropertyValues (ValueInteger/Decimal/DateTime/String/Boolean/Image/Text/EncryptedString/Bytes, Sealed-Kennzeichen); DeleteCustomProperties löscht Werte kaskadierend in einer Transaktion; Änderungen an ValueEncryptedString werden als PasswordManagerLog (PasswordSet/Changed/Deleted mit Alt-/Neuwert) protokolliert; die Pflichtfeldprüfung (IsMandatory) erfolgt clientseitig in CustomPropertiesGridViewModel.CheckMandatoryProperties ("Zusatzfeld '...' wurde nicht gefüllt!"). +Aussage: Die Software soll Zusatzfeld-Definitionen (Name, Datentyp zwingend; Kategorie, Sortierung, Wertemaske, Pflicht- und Versiegelungskennzeichen optional) je Objektart validieren, Werte typgerecht in einer generischen Wertetabelle speichern, beim Löschen einer Definition alle Werte mitlöschen, Änderungen an verschlüsselten (Passwort-)Werten revisionssicher protokollieren und Pflicht-Zusatzfelder vor dem Speichern auf Befüllung prüfen. +Ergebnis: Konsistente, auditierbare kundenindividuelle Felder. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Customization\ModuleCustomPropertyBL.cs, SaveCustomPropertyStructure (Zeilen 29-89) und DeleteCustomProperties (Zeilen 113-133) - Begründung: durchgesetzte Definitions- und Löschregeln. + - [PRIMÄR] src\backend\Centron.BL\Administration\Customization\ModuleCustomPropertyValueBL.cs, WritePasswordManagerLog (Zeilen 194-249: PasswordSet/Changed/Deleted je nach Alt-/Neuwert) - Begründung: Protokollierung verschlüsselter Werte. + - [SEKUNDÄR] src\shared\Centron.Controls\CustomProperties\CustomPropertiesGrid\CustomPropertiesGridViewModel.cs, CheckMandatoryProperties (Zeilen 219-239) - Begründung: Pflichtfeldprüfung nur im Client (nicht serverseitig). +Prüfidee: Zusatzfeld mit DataType Unknown speichern → Fehler; Pflichtfeld leer lassen → Client meldet "Zusatzfeld ... wurde nicht gefüllt!"; Passwortwert ändern → PasswordManagerLog-Eintrag PasswordChanged. +Tracelinks: SyRS-611 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Pflichtfeldprüfung in der Neuimplementierung zusätzlich serverseitig durchsetzen (heute nur UI). +Status: belegt +``` + +### SwRS-637: [HYPOTHESE] Berechtigungsprüfung der Kundengeräteverwaltung + +``` +ID: SwRS-637 +Titel: [HYPOTHESE] Berechtigungsprüfung der Kundengeräteverwaltung +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente AccountDeviceBL / AccountDeviceWebServiceBL +Vorbedingung: Benutzer legt Kundengerät an, ändert oder löscht es +Fakt: AccountDeviceBL.SaveAccountDevice/DeleteAccountDevice enthalten keinerlei Rechteprüfung (nur Guard.NotNull); auch in AccountDeviceWebServiceBL wurde per Grep keine Right-/ValidateUser-Prüfung gefunden — im Kontrast zu AccountBL, EmployeeBL und AccountAddressContactBL, die jede Operation absichern. +Aussage: Die Software soll Operationen der Kundengeräteverwaltung — analog zu den übrigen Stammdatenmodulen — über Benutzerrechte absichern. (In der heutigen Implementierung ist eine durchsetzende Prüfstelle nicht nachweisbar.) +Ergebnis: Nur berechtigte Benutzer verwalten Kundengeräte. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Devices\AccountDeviceBL.cs, SaveAccountDevice/DeleteAccountDevice: Methodenrümpfe ohne AppRightsBL-/HasUserRight-Aufruf (Negativbefund; Grep "Right|ValidateUser|HasUserRight" in Centron.BL\WebServices\Devices\AccountDeviceWebServiceBL.cs ohne Treffer) - Begründung: belegt das Fehlen der Prüfung, nicht deren Existenz — daher Hypothese für die Soll-Anforderung. +Prüfidee: Benutzer ohne jegliche Kundenrechte ruft SaveAccountDevice über den WebService auf; erwartet wird Abweisung — heute vermutlich Erfolg. +Tracelinks: SyRS-610, SyRS-605 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Rechteprüfung ist in der Neuimplementierung zwingend zu ergänzen. +Status: HYPOTHESE +Offene Frage: Wird der Zugriff auf die Geräteverwaltung an anderer Stelle (WPF-Client-Menürechte, API-Gateway, Lizenz) durchgesetzt, oder ist die Operation tatsächlich ungeschützt? +``` + +## Cluster A7 — Kommunikation & persönliche Organisation — SwRS + +### SwRS-731: Mail-Transport-Factory mit Testmodus + +``` +ID: SwRS-731 +Titel: Mail-Transport-Factory mit übersteuerndem Testmodus +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente CentronMailFactory +Vorbedingung: Fachmodul fordert eine Mail-Instanz an +Fakt: CentronMailFactory.GetMail() prüft zuerst TestMails.IsEnabled (aktiv, sobald mindestens ein Test-Subscriber registriert ist) und liefert dann TestMail statt eines realen Kanals; sonst wird CentronWebserviceMailType aus den AppSettings gelesen (Default 0 = SMTP). +Aussage: Das System soll die Auswahl des Mail-Transports zentral in einer Factory kapseln und in Testszenarien den realen Versand vollständig durch eine In-Memory-Erfassung ersetzen. +Ergebnis: Kein realer Mailversand während aktiver Testsubscription; produktiv wird der konfigurierte Kanal instanziiert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Mail\Factory\CentronMailFactory.cs, GetMail(): `if (TestMails.IsEnabled) return new TestMail(session);` und switch über CentronWebserviceMailType - Begründung: durchgesetzte Auswahllogik. + - [SEKUNDÄR] src\backend\Centron.BL\Mail\Factory\TestMails.cs, IsEnabled/AddMail(): Subscriber-Mechanismus - Begründung: Mechanik des Testmodus. +Prüfidee: Unit-Test: innerhalb TestMails.Start() versendete Mails landen in der Subscriber-Collection, kein SMTP-Verkehr. +Tracelinks: SyRS-711 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - saubere Teststrategie für Versandpfade. +Status: belegt +``` + +### SwRS-732: SMTP-Client-Konfiguration (Auth, Port, Timeout, SSL) + +``` +ID: SwRS-732 +Titel: SMTP-Client-Konfiguration mit Mindest-Timeout und SSL-Regel +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente SMTPMail +Vorbedingung: MailSettingsDTO mit SMTP-Parametern vorhanden +Fakt: SMTPMail.CreateSmtpClient() setzt bei UseSmtpAuth Credentials mit "Domain\\Benutzer"-Parsing (Backslash-Trennung), übernimmt SmtpPort nur wenn != 0, erzwingt Timeout = max(15, TimeOut)*1000 ms, wirft bei leerem Host eine ResultException "Der Host in den SMTP-Einstellungen ist nicht gesetzt." (BadRequest) und aktiviert SSL, wenn Host == "smtp.office365.com" ODER SmtpSslActive gesetzt ist. +Aussage: Das System soll den SMTP-Versand mit konfigurierbarer Authentifizierung, Port und Timeout (mindestens 15 Sekunden) betreiben, fehlende Host-Konfiguration als Bedienfehler melden und für Office-365-SMTP SSL erzwingen. +Ergebnis: Verbindungsaufbau schlägt kontrolliert fehl statt zu hängen; Office-365-Verbindungen sind immer verschlüsselt. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Mail\Protocols\SMTPMail.cs, CreateSmtpClient() (Z. 119–170): `client.Timeout = Math.Max(15, settings.TimeOut) * 1000;` und `client.EnableSsl = client.Host == "smtp.office365.com" || settings.SmtpSslActive;` - Begründung: durchgesetzte Konfigurationsregeln. + - [PRIMÄR] src\backend\Centron.BL\Mail\Protocols\SMTPMail.cs, GetCredentials() (Z. 172–186): Aufsplittung domainAndUsername am Backslash - Begründung: durchgesetztes Credential-Format. +Prüfidee: SMTP-Timeout 5 konfigurieren: effektiver Client-Timeout beträgt 15000 ms; leerer Host führt zu BadRequest-Fehlermeldung statt Exception-Stacktrace. +Tracelinks: SyRS-711 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Regeln sinnvoll; hartkodierte Office-365-Hostprüfung als generische "SSL erzwingen"-Option verallgemeinern. +Status: belegt +``` + +### SwRS-733: Empfängervalidierung mit Teilversand und Warnung + +``` +ID: SwRS-733 +Titel: Empfängervalidierung mit Teilversand und Warnung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente SMTPMail (CreateMailMessage) +Vorbedingung: Mail mit mehreren To/CC/BCC-Empfängern wird aufgebaut +Fakt: SMTPMail.CreateMailMessage() validiert jede Empfängeradresse über DeveloperSecurity.Email.ValidateAddress(); ungültige Adressen werden vom Versand ausgeschlossen und je Adresse die Meldung "Address '{x}' is not valid and has been excluded from the recipient list" gesammelt, das Ergebnis wird als Warning (nicht Error) zurückgegeben; eine ungültige Absenderadresse bricht dagegen mit Error "E-Mail-Absenderadresse verwendet ein ungültiges Format" ab. +Aussage: Das System soll beim Versand an mehrere Empfänger ungültige Adressen einzeln aussortieren, die Mail an die verbleibenden gültigen Empfänger dennoch versenden und den Benutzer über die ausgeschlossenen Adressen warnen; ohne gültigen Absender soll nicht versendet werden. +Ergebnis: Teilversand mit Warnhinweis statt Komplettabbruch bei einzelnen Tippfehlern. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Mail\Protocols\SMTPMail.cs, CreateMailMessage() (Z. 188–291): try/catch je Empfänger, resultStatus = ResultStatus.Warning, Sammelmeldung; From-Fehler → Result.AsError - Begründung: durchgesetzte Validierungs- und Degradationslogik. +Prüfidee: Versand an eine gültige und eine ungültige Adresse: Mail kommt beim gültigen Empfänger an, Rückgabestatus ist Warning mit Nennung der ausgeschlossenen Adresse. +Tracelinks: SyRS-711 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - benutzerfreundliches Fehlerverhalten. +Status: belegt +``` + +### SwRS-734: Signaturarten und Signatureinbettung in den Mailtext + +``` +ID: SwRS-734 +Titel: Signaturarten (Standard, Helpdesk intern/extern) und HTML-Einbettung mit Inline-Bildern +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente SMTPMail (FillMailBodyOld), MailSignatureBL +Vorbedingung: Signaturart (AppSettingsDataConst.CentronSignature / HelpdeskInternalSignature / HelpdeskExternalSignature) ist am Versandaufruf übergeben und die zugehörige Einstellung (MailSignatureKind etc.) hat den Wert 2 +Fakt: FillMailBodyOld() wählt abhängig von signatureKind und den Settings MailSignatureKind / HelpdeskInternalMailSignatureKind / HelpdeskExternalMailSignatureKind (jeweils == 2) die Signatur über MailSignatureBL.GetDefaultSignature()/GetHelpdeskInternalSignature()/GetHelpdeskExternalSignature(), bettet den Mailtext in den HTML-Body der Signatur ein (Replace("", ...)) und hängt Signatur-Bilder als LinkedResource mit ContentId an. +Aussage: Das System soll drei getrennt pflegbare Signaturarten (Standard, Helpdesk-intern, Helpdesk-extern) unterstützen und die gewählte Signatur inklusive eingebetteter Bilder als HTML in die ausgehende Mail einsetzen. +Ergebnis: Ausgehende Mails tragen die zum Prozess passende Signatur mit korrekt referenzierten Inline-Bildern. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Mail\Protocols\SMTPMail.cs, FillMailBodyOld() (Z. 293–386): Auswahllogik über signatureKind + Setting==2, StringToHtmlConverter.GetSignature(), LinkedResources mit ContentId - Begründung: durchgesetzte Signaturwahl und -einbettung. +Prüfidee: Helpdesk-Mail intern vs. extern versenden: es erscheinen unterschiedliche, jeweils konfigurierte Signaturen; Bilder werden inline (nicht als Anhang) dargestellt. +Tracelinks: SyRS-711, SyRS-713 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Signaturkonzept übernehmen; Alt-/Neu-Pfad (FillMailBodyOld vs. FillMailBodyNew) vereinheitlichen. +Status: belegt +``` + +### SwRS-735: Domain-Blacklist für E-Mail-Adressen + +``` +ID: SwRS-735 +Titel: Domain-Blacklist für E-Mail-Adressen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente DomainBlacklistBL +Vorbedingung: Blacklist-Einträge (DomainBlacklistItem) sind gepflegt +Fakt: DomainBlacklistBL.IsBlacklisted() extrahiert die Domain hinter dem letzten '@'; Einträge mit führendem '@' matchen exakt die volle Domain, Einträge ohne '@' matchen als Teilstring nach '@' oder '.' (Regex "[@.]"+escaped Eintrag); fehlerhafte Adressen ohne Domain liefern Error "Malformed E-Mail address". +Aussage: Das System soll E-Mail-Adressen gegen eine pflegbare Domain-Blacklist prüfen, wobei sowohl exakte Domains ("@example.com") als auch Domain-Fragmente ("example") gesperrt werden können. +Ergebnis: Adressen gesperrter Domains werden als blacklisted erkannt und können vom aufrufenden Prozess ausgeschlossen werden. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Mail\Blacklist\DomainBlacklistBL.cs, IsBlacklisted() (Z. 15–35): beide Matching-Zweige und Malformed-Fehler - Begründung: vollständige Prüfregel. +Prüfidee: Blacklist-Eintrag "@spam.de": nur adressen@spam.de matcht; Eintrag "spam": auch sub.spam-mail.de matcht; "keineadresse" liefert Fehler. +Tracelinks: SyRS-711 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - einfache, wirksame Filterregel. +Status: belegt +``` + +### SwRS-736: Vorlagen-Fallback-Hierarchie mit Default-Texten + +``` +ID: SwRS-736 +Titel: Mail-Vorlagen-Auflösung: Fallback Account > Mitarbeiter > Filiale > Global > Systemstandard +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente MailTemplateBL +Vorbedingung: Vorlagenanforderung mit MailTemplateReference sowie optional accountI3D/employeeI3D/branchI3D +Fakt: MailTemplateBL.MailTemplate() prüft nacheinander Account-, Mitarbeiter-, Filial- und globale Vorlage und erzeugt zuletzt eine "hardcoded default fallback"-Vorlage; leere Subject/Body-Felder werden durch DefaultSubject/DefaultBody der MailTemplateReference ersetzt; besteht der Body nur aus '-'-Zeichen, wird er als bewusst leerer Body interpretiert (mailTemplate.Body = string.Empty); die gezogene Ebene (pulledLocation) wird geloggt. +Aussage: Das System soll die spezifischste verfügbare Vorlage verwenden (Kunde vor Mitarbeiter vor Filiale vor global vor Systemstandard), fehlende Teile aus Standardtexten ergänzen und einen ausschließlich aus '-' bestehenden Body als gewollt leeren Mailtext behandeln. +Ergebnis: Es existiert für jeden Vorgang immer eine versandfähige Vorlage; Sonderwunsch "leerer Body" bleibt erhalten. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Mail\Templates\MailTemplateBL.cs, MailTemplate() (Z. 261–317) und GetMailTemplate() (Z. 319–361, Kommentar "special case when the customer wants to have an empty body", bodyContainsDash) - Begründung: durchgesetzte Auflösungs- und Sonderfallregeln. +Prüfidee: Vorlagen auf mehreren Ebenen anlegen/löschen und pulledLocation im Log prüfen; Vorlage mit Body "---" liefert leeren Mailtext. +Tracelinks: SyRS-713 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Hierarchie übernehmen; die '-'-Konvention ist ein Workaround und sollte durch ein explizites Flag "leerer Body" ersetzt werden. +Status: belegt +``` + +### SwRS-737: Variablenersetzung in Vorlagen mit Alternativnamen + +``` +ID: SwRS-737 +Titel: Variablenersetzung in Vorlagen (Gruppen, Alternativnamen) +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente MailTemplateBL / ReplacementBL +Vorbedingung: Vorlage enthält Platzhalter; Kontakt- und Bearbeiterdaten sind ermittelbar +Fakt: GenerateVariables() definiert Variablen in Gruppen ("Allgemein", "Bearbeiter", "Kunde", "Adresse", "Ansprechpartner") mit ReplacementValue-Strategien (z. B. BearbeiterName → loggedInUser.User.Employee.DisplayText, HeutigesDatum → DateTime.Now.ToShortDateString()) und unterstützt AlternativeNames (z. B. "KdNummer" für "KundenNummer"); ReplaceVariablesInMailTemplateText() wendet sie auf Subject und Body an. +Aussage: Das System soll Platzhalter in Vorlagen-Betreff und -Text durch Werte aus Bearbeiter-, Kunden-, Adress- und Ansprechpartnerdaten ersetzen und dabei historische Alternativ-Platzhalternamen weiter unterstützen. +Ergebnis: Versandfertige Mail ohne verbleibende Platzhalter; Altvorlagen mit alten Platzhalternamen funktionieren weiter. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Mail\Templates\MailTemplateBL.cs, ReplaceVariablesInMailTemplateText() (Z. 489–521) und GenerateVariables() (Z. 531 ff., AlternativeNames "KdNummer", "Matchcode") - Begründung: durchgesetzte Ersetzungslogik inkl. Rückwärtskompatibilität. +Prüfidee: Vorlage mit {KundenNummer} und {KdNummer} füllen: beide werden mit derselben Kundennummer ersetzt. +Tracelinks: SyRS-713 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Alternativnamen als Übergangs-Kompatibilität kennzeichnen. +Status: belegt +``` + +### SwRS-738: MailScanner-Profile: Rechteprüfung und Master-Key-Verschlüsselung + +``` +ID: SwRS-738 +Titel: MailScanner-Profile: VMA-Rechteprüfung beim Laden und Master-Key-Verschlüsselung der Zugangsdaten +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente MailScannerBL +Vorbedingung: Benutzer fordert VMA-Profile an bzw. speichert ein Profil +Fakt: GetProfiles() ruft AppRightsBL.CheckRightsFromUser(userI3D, UserRightsConst.VirtualMailAssistant.ACCESS_VMA_MODULE) und bricht ohne dieses Recht mit RightCheckFailed ab; SaveProfile() verschlüsselt Password und ClientSecret mit CentronConfigurationDbBL.EncryptWithMasterKey() vor SaveOrUpdate und entschlüsselt sie beim Laden mit DecryptWithMasterKey(). +Aussage: Das System soll VMA-Profile nur an Benutzer mit dem Modulrecht ausliefern und Postfach-Passwörter sowie OAuth-Client-Secrets ausschließlich mit dem Mandanten-Masterschlüssel verschlüsselt speichern. +Ergebnis: Klartext-Geheimnisse existieren nur zur Laufzeit; unberechtigte Zugriffe werden abgewiesen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\MailScanner\MailScannerBL.cs, GetProfiles() (Z. 57–72): `if (rightsResult.Contains(UserRightsConst.VirtualMailAssistant.ACCESS_VMA_MODULE) == false) return ...AsError(..., DefaultMessageCodes.RightCheckFailed)` - Begründung: durchsetzende Rechteprüfung mit Konstante und Bedingung. + - [PRIMÄR] src\backend\Centron.BL\MailScanner\MailScannerBL.cs, EncryptProperties()/DecryptProperties() (Z. 90–116) - Begründung: durchgesetzte Ver-/Entschlüsselung vor Persistenz. + - [KONTEXT] src\backend\Centron.Interfaces\Administration\Logins\ApplicationKind.cs, Z. 28/61: MailScannerNET erfordert ACCESS_VMA_MODULE (= 20800112), gekoppelt an LicenseGuids.MailScannerNET - Begründung: Verankerung des Rechts an Anwendung und Lizenz. +Prüfidee: Profil mit Passwort "geheim" speichern; DB-Spaltenwert != "geheim"; GetProfiles ohne Recht liefert RightCheckFailed. +Tracelinks: SyRS-714 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Muster für Secret-Handling; Rechteprüfung zusätzlich auf SaveProfile/DeleteProfile ausdehnen. +Status: belegt +``` + +### SwRS-739: Statusmaschine der Terminanfrage + +``` +ID: SwRS-739 +Titel: Statusmaschine der Terminanfrage (AppointmentRequestState) mit EWS-Terminpflege +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente AppointmentRequestBL +Vorbedingung: AppointmentRequest mit Guid, EmployeeI3D und Proposals existiert +Fakt: HandleAppointmentRequestReply(): bei AcceptedProposalI3D == null werden alle Proposal-Termine gelöscht (MoveToDeletedItems), reply.Message übernommen und RequestState = AppointmentProposalsRejected; sonst wird der akzeptierte Termin aktualisiert (Subject + " (Akzeptiert)", RequiredAttendees.Add(ContactEmail), Kategorie "Terminvereinbarung (offen)" → "Terminvereinbarung (akzeptiert)", Update mit SendOnlyToAll) und die übrigen per SoftDelete entfernt, RequestState = AppointmentProposalAccepted; der Filter IsActive definiert aktiv als RequestState != Done; SaveOrUpdateAppointmentRequest setzt ChangedDate = DateTime.Now. +Aussage: Das System soll Terminanfragen als Statusmaschine führen (offen → Vorschläge akzeptiert / Vorschläge abgelehnt → erledigt) und die Kundenantwort konsistent in den Exchange-Kalender übertragen (genau ein bestätigter Termin, keine verwaisten Vorschläge). +Ergebnis: Anfragestatus und Kalenderinhalt sind nach jeder Kundenantwort konsistent. +Belege: + - [PRIMÄR] src\backend\Centron.BL\AppointmentRequests\AppointmentRequestBL.cs, HandleAppointmentRequestReply() (Z. 29–114) und CreateAppointmentRequestsExpression() (Z. 147–167, `f.RequestState != AppointmentRequestState.Done`) - Begründung: alle Statusübergänge und die Aktiv-Definition sind im Code durchgesetzt. +Prüfidee: Ablehnung: alle Vorschlags-Termine sind aus dem Kalender entfernt, Status AppointmentProposalsRejected, Kundenkommentar gespeichert. +Tracelinks: SyRS-715 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Doppelaufruf von SaveOrUpdateAppointmentRequest im Accept-Zweig (Z. 105/106) ist ein zu bereinigender Codefehler ohne fachliche Bedeutung. +Status: belegt +``` + +### SwRS-740: [HYPOTHESE] Getrennte Persistenz von Betreff-Schalter und Betreff-Text der Outlook-Termine + +``` +ID: SwRS-740 +Titel: [HYPOTHESE] Getrennte Persistenz von "eigenen Betreff verwenden" (Schalter) und Betreff-Text für Outlook-Termine +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente CalendarBL +Vorbedingung: Administrator ändert Kalender-Synchronisationseinstellungen +Fakt: CalendarBL.GetCalendarSynchronizationSettings() liest den bool OutlookAppointementUseCustomSubject aus dem Settings-Schlüssel AppSettingsConst.HolidayRequestedEmailSubject und den Betreff-Text aus AppSettingsConst.OutlookAppointementUseCustomSubject; UpdateCalendarSynchronizationSettings() schreibt spiegelbildlich (UpdateBool auf HolidayRequestedEmailSubject, UpdateLargeString auf OutlookAppointementUseCustomSubject). Die Schlüsselnamen passen nicht zur transportierten Bedeutung. +Aussage: Das System soll die Aktivierung eines benutzerdefinierten Termin-Betreffs (Schalter) und den Betreff-Text als zwei getrennte Einstellungen persistieren; die heutige Ablage unter fachfremd benannten Schlüsseln (HolidayRequestedEmailSubject als Schalter) ist mutmaßlich eine historisch gewachsene Fehlbelegung. +Ergebnis: Schalter und Text werden konsistent gespeichert und wieder geladen (Lesen und Schreiben verwenden dieselben Schlüssel, daher funktional wirksam trotz irreführender Benennung). +Belege: + - [PRIMÄR] src\backend\Centron.BL\Calendar\CalendarBL.cs, Z. 69–70: `result.OutlookAppointementUseCustomSubject = settings.GetBool(AppSettingsConst.HolidayRequestedEmailSubject); result.OutlookAppointementCustomSubject = settings.GetLargeString(AppSettingsConst.OutlookAppointementUseCustomSubject);` sowie Z. 161–162 spiegelbildlich - Begründung: belegt die tatsächliche (vertauschte) Schlüsselbelegung. +Prüfidee: Schalter und Text setzen, speichern, erneut laden: Werte bleiben erhalten; zusätzlich prüfen, ob der Schlüssel HolidayRequestedEmailSubject anderswo (Urlaubsantrags-Mail) mit anderer Semantik gelesen wird (Kollisionsrisiko). +Tracelinks: SyRS-716 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - fachlich zu übernehmen ist die getrennte Konfiguration; die Schlüsselbelegung selbst nicht nachbauen. +Status: HYPOTHESE +Offene Frage: Ist die Nutzung von HolidayRequestedEmailSubject als Bool-Schalter beabsichtigte Wiederverwendung eines freien Schlüssels oder ein Copy-Paste-Fehler, und liest ein anderes Modul denselben Schlüssel mit Urlaubs-Semantik? +``` + +### SwRS-741: PhoneCall-Erfassung: Pflichtfelder, Normalisierung und Anruferidentifikation + +``` +ID: SwRS-741 +Titel: PhoneCall-Erfassung: Pflichtfelder, Feldnormalisierung und mehrstufige Anruferidentifikation +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente PhoneCallBL +Vorbedingung: TAPI-/Client-Ereignis liefert Anrufdaten +Fakt: SaveOrUpdateCall() verlangt CallerNumber ("Call does not have a callernumber") und StartTime != DateTime.MinValue, kürzt CallerName/CallerNumber auf 50 Zeichen (Truncate(50)) und verwirft EndTime-Werte vor dem 01.01.2000; SearchContactPersonByPhoneNumberV2() bricht bei Nummern <= InternalPhoneNumberLength (Setting-gesteuert) ab und sucht sonst in bis zu sechs Stufen (formatiert, roh, vorne trunkiert, %..%, nur Ziffern ohne Länderpräfix 49/41/43, verkürzte Endziffern) über die NamedQuery SearchAddressContactByPhoneNumberV2. +Aussage: Das System soll Anrufe nur mit Rufnummer und Startzeit speichern, Freitextfelder auf die Persistenzlänge normalisieren und den Anrufer über tolerante, mehrstufige Rufnummernvergleiche identifizieren, wobei interne Kurzrufnummern von der Kundensuche ausgenommen sind. +Ergebnis: Konsistentes Anrufjournal; hohe Trefferquote der Kundenzuordnung trotz uneinheitlicher Rufnummernformate. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Tapi\PhoneCallBL.cs, SaveOrUpdateCall() (Z. 73–99): Pflichtfeld- und Normalisierungsregeln - Begründung: durchgesetzte Validierung. + - [PRIMÄR] src\backend\Centron.BL\Tapi\PhoneCallBL.cs, SearchContactPersonByPhoneNumberV2() (Z. 149–211) und IsInternalPhoneNumber() (Z. 263–281) - Begründung: durchgesetzte Suchkaskade und Ausschlussregel. +Prüfidee: Anruf ohne Rufnummer wird abgelehnt; Nummer "+49 (7541) 12345-67" findet den als "0754112345 67" gespeicherten Kontakt; 3-stellige interne Nummer löst keine Suche aus. +Tracelinks: SyRS-717 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Suchkaskade als Fachregel dokumentieren; besser wäre normalisierte Rufnummernspalte (E.164) statt LIKE-Kaskade. +Status: belegt +``` + +### SwRS-742: Teams-CallRecords-Synchronisation mit Lizenz-, Mitglieder- und Dublettenprüfung + +``` +ID: SwRS-742 +Titel: Teams-CallRecords-Synchronisation: Lizenzpflicht, Sync-Mitglieder, Dubletten- und Plausibilitätsregeln +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Komponente PhoneCallBL (SyncPhoneCalls), Microsoft Graph +Vorbedingung: Lizenz GraphCalendarEventsAndCallsSync vorhanden; Sync-Mitglieder konfiguriert +Fakt: SyncPhoneCalls() bricht ohne Lizenz oder ohne Sync-Mitglieder ab; CreateSyncedPhoneCalls() verwirft Records ohne Start/Ende/Id/Organizer und mit EndTime < StartTime, dedupliziert Teilnehmer per Caller-Key, erzeugt je Gegenstelle einen PhoneCall (WasOutgoing = Organizer ist Mitarbeiter, WasInternalCall = beide Mitarbeiter, CreatedBy = beteiligter Mitarbeiter oder Centron-Systembenutzer) und filtert auf Sync-Mitglieder; IsSameSyncedPhoneCall() erkennt vorhandene Einträge über CallID + Party-Keys und aktualisiert statt neu anzulegen. +Aussage: Das System soll Teams-Anrufe nur bei vorhandener Lizenz und nur für freigeschaltete Mitarbeiter importieren, unplausible Datensätze verwerfen und wiederholte Sync-Läufe idempotent halten (Aktualisierung statt Dublette). +Ergebnis: Anrufjournal bleibt bei wiederholtem Sync dublettenfrei und lizenzkonform. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Tapi\PhoneCallBL.cs, SyncPhoneCalls() (Z. 283–352): `if (LicenseManager.Instance.HasLicense(LicenseGuids.GraphCalendarEventsAndCallsSync) == false) ... return;` - Begründung: durchsetzende Lizenzprüfung. + - [PRIMÄR] src\backend\Centron.BL\Tapi\PhoneCallBL.cs, CreateSyncedPhoneCalls() (Z. 428–508) und IsSameSyncedPhoneCall() (Z. 510–521) - Begründung: durchgesetzte Plausibilitäts-, Filter- und Dublettenregeln. +Prüfidee: Zweifacher Sync desselben CallRecords erzeugt genau einen PhoneCall; Anruf eines Nicht-Sync-Mitglieds wird nicht importiert. +Tracelinks: SyRS-717 +Konsolidierung: Kandidat: erzeugt PhoneCall-Datensätze parallel zum TAPI-Client-Pfad (CreatePhoneCall) - gemeinsames Journal, getrennte Erfassungslogiken. +Übernahmewürdigkeit: übernehmen - Idempotenz- und Lizenzregeln sind auch im SaaS-Modell nötig. +Status: belegt +``` + +### SwRS-743: Chat-Zugriff nur für Mitglieder, Nachrichtenlänge 250 Zeichen + +``` +ID: SwRS-743 +Titel: Chat: mitgliedschaftsbasierte Zugriffskontrolle und Nachrichtenlimit 250 Zeichen +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente ChatBL +Vorbedingung: Benutzer greift auf Chat oder Chat-Nachrichten zu +Fakt: Alle mutierenden Operationen (SendChatMessage, RenameChat, AddMemberToChat, SaveOrUpdateNotes, LastViewedChat) laden den Chat mit ChatFilter{OnlyOwn = true} (Expression: `f.Members.Any(d => d.EmployeeI3D == currentUser...I3D)`) und werfen sonst "…are not a member of that chat"; GetChatMessages() beschränkt den Grundausdruck auf Chats mit eigener Mitgliedschaft; SendChatMessage/EditChatMessage prüfen Guard.NotLongerThan(message, 250, ...), die DB-Spalte ChatMessages.Message ist nvarchar(250) NOT NULL. +Aussage: Das System soll Chat-Inhalte und Chat-Operationen ausschließlich Mitgliedern des jeweiligen Chats erlauben und Chat-Nachrichten auf 250 Zeichen begrenzen (App- und DB-seitig durchgesetzt). +Ergebnis: Kein lesender oder schreibender Zugriff auf fremde Chats; keine überlangen Nachrichten. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Chats\ChatBL.cs, GetFilterExpression() (Z. 411–463) und SendChatMessage() (Z. 202–258, Guard.NotLongerThan(message, 250, ...), Mitgliedsprüfung) - Begründung: durchsetzende Zugriffskontrolle und Längenprüfung. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, Tabelle [dbo].[ChatMessages] (Z. 34823): `[Message] [nvarchar](250) NOT NULL` - Begründung: DB-Constraint als zweite Durchsetzungsebene. +Prüfidee: Nachricht mit 251 Zeichen wird abgelehnt; Nachrichtenabruf für Chat ohne eigene Mitgliedschaft liefert nichts; SendChatMessage in fremden Chat wirft Fehler. +Tracelinks: SyRS-718 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Mitgliedschaftsmodell übernehmen; 250-Zeichen-Limit fachlich neu bewerten (für Web-Chat knapp). +Status: belegt +``` + +### SwRS-744: NexusNotification-Lebenszyklus (gesehen/gelesen, Massenoperationen) + +``` +ID: SwRS-744 +Titel: NexusNotification-Lebenszyklus: IsSeen/IsRead je Empfänger inkl. Massenoperationen +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente NexusNotificationsBL, Nexus-Client +Vorbedingung: Benachrichtigungen für einen Mitarbeiter existieren +Fakt: NexusNotification trägt IsSeen und IsRead (bit NOT NULL) je Empfänger (UserI3D/UserKind); MarkNexusNotificationsAsSeen/AsRead setzen die Flags einzeln, MarkAllNexusNotificationsAsSeen/AsRead per SQL-UPDATE gefiltert auf UserI3D, UserKind = Employee und optional Type; DeleteAllNexusNotifications löscht nur Einträge des angemeldeten Mitarbeiters (UserI3D aus loggedInUser). +Aussage: Das System soll je Benachrichtigung und Empfänger die Zustände "gesehen" (Badge) und "gelesen" getrennt führen und Massenoperationen (alle als gesehen/gelesen markieren, alle löschen) strikt auf die Einträge des jeweiligen Mitarbeiters begrenzen. +Ergebnis: Zähler und Leseständen stimmen je Benutzer; Massenoperationen betreffen nie fremde Benachrichtigungen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\NexusNotifications\NexusNotificationsBL.cs, MarkAllNexusNotificationsAsSeen()/AsRead()/DeleteAllNexusNotifications() (Z. 93–131): WHERE UserI3D = {employeeI3D} AND UserKind = Employee - Begründung: durchgesetzte Benutzerbegrenzung der Massenoperationen. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, Tabelle [dbo].[NexusNotifications] (Z. 45424): IsSeen/IsRead bit NOT NULL - Begründung: Datenmodell der beiden Zustände. +Prüfidee: "Alle als gelesen markieren" eines Benutzers verändert keine Zeile eines anderen Benutzers; IsSeen kann gesetzt sein, während IsRead false bleibt. +Tracelinks: SyRS-718 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Zustandsmodell übernehmen; SQL-String-Konkatenation (employeeI3D interpoliert) bei Neuimplementierung durch Parameter ersetzen. +Status: belegt +``` + +### SwRS-745: Rechtegeschützter Zugriff auf fremde ToDo-Listen + +``` +ID: SwRS-745 +Titel: ToDo: Fremdzugriffs-Rechte RIGHT_FREMDTODOLISTE / RIGHT_FREMDTODOLISTEVERWERFEN und Eigentümerregeln +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente ToDoBL +Vorbedingung: Benutzer fragt ToDos ab oder ändert Read-/Discarded-Flags +Fakt: GetTodosThroughPaging()/SearchTodoList() setzen ohne RIGHT_FREMDTODOLISTE den Filter zwingend auf den eigenen EmployeeI3D; UpdateTodoHasBeenReadFlag() überspringt Einträge fremder Eigentümer (Kommentar "Update of read state only for owner of the entry allowed."); UpdateTodoDiscardedFlag() erlaubt Fremdverwerfen nur mit RIGHT_FREMDTODOLISTEVERWERFEN; das Verwerfen eines PLM-ToDos deaktiviert zusätzlich die zugehörige ProductLifecycleInformation und schreibt einen PlmLog-Eintrag. +Aussage: Das System soll fremde Aufgabenlisten nur mit dem Recht "Fremd-Todoliste" anzeigen, den Gelesen-Status ausschließlich dem Eigentümer überlassen und das Verwerfen fremder ToDos an das Recht "Fremd-Todoliste verwerfen" binden; das Verwerfen lizenzbezogener (PLM-)ToDos soll die zugrunde liegende Lizenzinformation deaktivieren und protokollieren. +Ergebnis: Aufgaben anderer Mitarbeiter sind vor unberechtigter Einsicht und Manipulation geschützt; PLM-Verwerfungen sind auditierbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\ToDoArea\ToDoBL.cs, Z. 257–261 und Z. 546: `if (!settings.HasRightForAccessingTodoFromOtherUsers) filter.EmployeeI3D = user.Employee.I3D;` mit Z. 1993 `HasUserRight(currentUser.I3D, UserRightsConst.RIGHT_FREMDTODOLISTE)` - Begründung: durchsetzende Sichtbarkeitsregel. + - [PRIMÄR] src\backend\Centron.BL\ToDoArea\ToDoBL.cs, UpdateTodoDiscardedFlag() (Z. 305–355): HasUserRight(..., RIGHT_FREMDTODOLISTEVERWERFEN), Owner-Vergleich, PLM-Zweig mit IsDeactivated + PlmLog - Begründung: durchsetzende Änderungsregel inkl. Protokoll. +Prüfidee: Benutzer ohne Rechte sieht nur eigene ToDos und kann fremde nicht verwerfen; mit RIGHT_FREMDTODOLISTEVERWERFEN erzeugt das Verwerfen eines PLM-ToDos einen PlmLog-Eintrag und deaktiviert die Lizenz. +Tracelinks: SyRS-719 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Rechtemodell übernehmen; TODO-Kommentar im Code (Recht evtl. nur fürs Verwerfen, nicht fürs Reaktivieren) bei Neuimplementierung fachlich klären. +Status: belegt +``` + +### SwRS-746: MyDay-WorkItems: UniqueId-Deduplizierung und Batch-Serientermine + +``` +ID: SwRS-746 +Titel: MyDay-WorkItems: UniqueId-Deduplizierung, Batch-Serienerfassung, Sekunden-Normalisierung +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente MyDayBL +Vorbedingung: Mitarbeiter oder automatischer Generator speichert Arbeitstag-Positionen +Fakt: SaveOrUpdateWorkItem() normalisiert Start-/Endzeit auf Minutengranularität (IgnoreSeconds), liefert bei neuem Item mit bereits existierender UniqueId das vorhandene Item zurück (Kommentar: Doppel-Speicherung durch mehrfach geöffnetes MyDay) und vergibt sonst UniqueId = Type + I3D; SaveWorkItemBatch() vergibt für mehrtägige Serien eine fortlaufende BatchId (max+1), für Einzeltage BatchId = 0; ImportMyDayItems() überspringt Einträge mit unbekanntem Windows-Benutzer, StartTime > EndTime, leerer Caption, existierender UniqueId oder Dismissed-Markierung. +Aussage: Das System soll automatisch generierte und mehrfach gespeicherte Arbeitstag-Positionen über eine eindeutige UniqueId deduplizieren, Serieneinträge über eine Batch-Kennung gruppieren (für gemeinsames Löschen) und Zeitstempel sekundenfrei normalisieren. +Ergebnis: Keine doppelten Zeiteinträge trotz paralleler Clients; Serien lassen sich als Ganzes verwalten. +Belege: + - [PRIMÄR] src\backend\Centron.BL\MyDay\MyDayBL.cs, SaveOrUpdateWorkItem() (Z. 132–164) und SaveWorkItemBatch() (Z. 100–130) - Begründung: durchgesetzte Dedup-, Batch- und Normalisierungsregeln. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, Tabelle [dbo].[MyDayWorkItems] (Z. 45250) - Begründung: Persistenzmodell mit UniqueId/BatchId. +Prüfidee: Zweimaliges Speichern eines Items mit gleicher UniqueId erzeugt genau einen Datensatz; Serie über 3 Tage erhält gemeinsame BatchId, Einzeltag BatchId 0. +Tracelinks: SyRS-719 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Dedup-Regel fachlich nötig; sauberer wäre ein Unique-Constraint auf UniqueId in der DB. +Status: belegt +``` + +### SwRS-747: VideoPortal-Zuweisung mit Rechteprüfung und ToDo-Kopplung + +``` +ID: SwRS-747 +Titel: VideoPortal-Zuweisung nur mit Recht "Video-Portal Zuweisung" und automatischer ToDo-Kopplung +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente VideoPortalAssignmentBL +Vorbedingung: Benutzer weist Mitarbeitern Videos zu oder löscht Zuweisungen +Fakt: SaveVideoPortalAssignment() und DeleteVideoPortalAssignment() prüfen `GetRightsFromCurrentUser(...).Any(f => f.I3D == UserRightsConst.VideoPortal.ASSIGNMENT)` und werfen sonst ResultException "Sie benötigen das Recht 'Video-Portal Zuweisung'." (RightCheckFailed); nach dem Speichern wird ToDoBL.HandleVideoPortalAssignmentEntries() aufgerufen, nach dem Löschen ToDoBL.DeleteToDoVideoPortalAssignment(). +Aussage: Das System soll Video-Zuweisungen an Mitarbeiter (Schulungsinhalte) nur Benutzern mit dem Recht "Video-Portal Zuweisung" erlauben und je Zuweisung automatisch einen ToDo-Eintrag beim Empfänger erzeugen bzw. beim Entfernen wieder löschen. +Ergebnis: Zugewiesene Videos erscheinen als Aufgabe beim Mitarbeiter; unberechtigte Zuweisungen werden abgewiesen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\VideoPortal\VideoPortalAssignmentBL.cs, SaveVideoPortalAssignment()/DeleteVideoPortalAssignment() (Z. 25–65): Rechteprüfung mit UserRightsConst.VideoPortal.ASSIGNMENT + throw ResultException(..., DefaultMessageCodes.RightCheckFailed) und ToDo-Kopplung - Begründung: durchsetzende Prüfstelle und Folgeaktion in einer Methode. +Prüfidee: Zuweisung ohne Recht wirft RightCheckFailed; mit Recht entsteht ein ToDo beim Ziel-Mitarbeiter, das beim Löschen der Zuweisung verschwindet. +Tracelinks: SyRS-719 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - konsistentes Muster Recht + ToDo-Kopplung. +Status: belegt +``` + +### SwRS-748: [HYPOTHESE] Social-Media-Interaktionen über Datenbankprozeduren + +``` +ID: SwRS-748 +Titel: [HYPOTHESE] Social-Media-Interaktionen (Kommentar, Like, Abo) vollständig in Datenbankprozeduren +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente SocialMediaBL, Mitarbeiter +Vorbedingung: Social-Media-Stream bzw. -Aktion existiert +Fakt: SocialMediaBL delegiert alle Operationen an NamedQueries/Stored Procedures (AddCommentToASocialMediaAction, LikeAStreamOrAction, CreateActionForStream, SocialMediaSubscribeToCRMActivity, SocialMediaSubscribeToHelpdesk) mit Parametern EmployeeI3D, SocialMediaI3D, SocialMediaKind (0 = Stream, 1 = Action), Text, Date; die eigentliche Fachlogik (Berechtigungen, Dubletten, Empfängerermittlung) liegt in den SQL-Prozeduren und ist im .NET-Code nicht sichtbar. Auffällig: LikeAStreamOrAction() bildet sowohl Stream als auch Action auf socialKind = 0 ab. +Aussage: Das System soll Mitarbeitern erlauben, interne Aktivitäten-Streams zu kommentieren, zu liken und Objekte (CRM-Aktivitäten, Tickets) zu abonnieren; die vollständigen Regeln dieser Interaktionen sind nur in den Datenbankprozeduren definiert. +Ergebnis: Kommentar-/Like-/Abo-Aktionen werden persistiert und als aktualisierte Übersicht zurückgegeben. +Belege: + - [PRIMÄR] src\backend\Centron.BL\SocialMedia\SocialMediaBL.cs, AddCommentToASocialMediaAction()/LikeAStreamOrAction()/CreateActionForStream()/SocialMediaSubscribeToCRMActivity() (Z. 25–145): NamedQuery-Aufrufe mit Parameterlisten - Begründung: belegt Schnittstelle und Parametervertrag; Prozedurinhalte nicht eingesehen. +Prüfidee: Like auf eine Action absetzen und prüfen, ob es als Action-Like (nicht Stream-Like) gezählt wird (Verdacht durch socialKind = 0 in beiden Zweigen). +Tracelinks: SyRS-718 +Konsolidierung: Kandidat (vermutet): Überschneidung mit NexusNotifications/Chats als weiterer interner Kommunikationskanal derselben Zielgruppe. +Übernahmewürdigkeit: Sonderfall - Nutzungsgrad unklar, Logik in SPs vergraben; vor Übernahme fachliche Relevanz prüfen. +Status: HYPOTHESE +Offene Frage: Welche Regeln (Berechtigung, Dubletten, Benachrichtigung) implementieren die Stored Procedures AddCommentToASocialMediaAction/LikeAStreamOrAction, und ist socialKind = 0 für Actions ein Fehler? +``` + +## A8 — Web-Client Nexus & Service-Schnittstellen — SwRS + +### SwRS-831: Rechte-Autorisierungsfilter der REST-API (Einzel-/Any-/All-Semantik) + +``` +ID: SwRS-831 +Titel: UserRight-Autorisierungsfilter mit Einzel-, Any- und All-Semantik +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Centron.Controllers (ASP.NET-Core-Autorisierungsfilter) +Vorbedingung: Controller-Aktion ist mit [AuthorizeUserRight], [AuthorizeAnyUserRight] oder [AuthorizeAllUserRights] annotiert +Fakt: UserRightAuthorizationFilter liefert UnauthorizedResult (401) wenn kein Benutzer ermittelbar ist, sonst ForbidResult (403) wenn das Recht fehlt; AnyUserRightAuthorizationFilter verlangt mindestens eines, AllUserRightsAuthorizationFilter alle Rechte; eine leere Rechteliste führt in beiden Fällen zu ForbidResult (fail-closed). +Aussage: Die Software soll je Endpunkt konfigurierbar ein einzelnes Recht, mindestens eines aus einer Menge oder alle Rechte einer Menge prüfen und im Zweifel (leere Konfiguration) den Zugriff verweigern. +Ergebnis: 401 ohne Benutzer, 403 ohne ausreichende Rechte, sonst Ausführung der Aktion. +Belege: + - [PRIMÄR] src\webservice\Centron.Controllers\Authorization\AuthorizeUserRightAttribute.cs - OnAuthorization: "if (currentUser == null) { context.Result = new UnauthorizedResult(); return; } if (!_requiredRightId.HasValue || !currentUser.HasUserRight(_requiredRightId.Value)) context.Result = new ForbidResult();" - Begründung: Durchsetzende Einzelrecht-Prüfung. + - [PRIMÄR] src\webservice\Centron.Controllers\Authorization\AuthorizeAnyUserRightAttribute.cs / AuthorizeAllUserRightsAttribute.cs - "_requiredRightIds.Any(...)" bzw. "_requiredRightIds.All(...)"; "_requiredRightIds.Length == 0 || !has..." → ForbidResult - Begründung: Any-/All-Semantik inkl. fail-closed bei leerer Liste. +Prüfidee: Unit-Test der drei Filter mit (a) null-User, (b) User ohne Rechte, (c) User mit Teilmenge, (d) leerer Rechteliste; erwartete Ergebnisse 401/403/403(bei All)/403. +Tracelinks: SyRS-817 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - sauberes, testbares AuthZ-Bausteinmuster. +Status: belegt +``` + +### SwRS-832: CentronHosted-Policy über Lizenzprüfung + +``` +ID: SwRS-832 +Titel: Hosted-only-Endpunkte über Lizenz CentronInternal +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: CentronHostedHandler (AuthorizationHandler), Controller Nexoware/Integrations +Vorbedingung: Endpunkt trägt [AuthorizeCentronHosted] (Policy "CentronHosted") +Fakt: CentronHostedHandler erfüllt die Requirement nur, wenn LicenseManager.Instance.HasLicense(LicenseGuids.CentronInternal) true ist; NexowareController, NexowareStatisticsController und IntegrationsController tragen das Attribut. +Aussage: Die Software soll Endpunkte, die nur in der von c-entron gehosteten Umgebung verfügbar sein dürfen, an das Vorhandensein der Lizenz CentronInternal koppeln und sonst mit 403 abweisen. +Ergebnis: On-Premise-Installationen ohne CentronInternal-Lizenz können Nexoware-/Integrations-Endpunkte nicht aufrufen. +Belege: + - [PRIMÄR] src\webservice\Centron.Controllers\Authorization\CentronHostedAuthorization.cs - HandleRequirementAsync: "var hasCentronInternalLicense = LicenseManager.Instance.HasLicense(LicenseGuids.CentronInternal); if (hasCentronInternalLicense) { context.Succeed(requirement); }" - Begründung: Durchsetzende Lizenzbedingung; ohne Succeed schlägt die Policy fehl. + - [SEKUNDÄR] src\webservice\Centron.Controllers\Controllers\v1\Nexoware\NexowareController.cs Zeile 9 - [AuthorizeCentronHosted] - Begründung: Konkrete Verwendung. +Prüfidee: Aufruf eines Nexoware-Endpunkts auf Installation ohne CentronInternal-Lizenz → 403; mit Lizenz → 200. +Tracelinks: SyRS-817 +Konsolidierung: nein +Übernahmewürdigkeit: Sonderfall - Unterscheidung Hosted vs. On-Premise entfällt bei reiner SaaS-Lösung, Mechanik ggf. für interne Endpunkte übernehmen. +Status: belegt +``` + +### SwRS-833: JWT-Login tauscht Bearer-Token gegen Centron-Ticket + +``` +ID: SwRS-833 +Titel: JwtAuthController: OpenID-Connect-Login und Kontoverknüpfung +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: JwtAuthController (/jwt), externer Identity Provider (OpenID Connect) +Vorbedingung: Client präsentiert gültiges JWT (Bearer); Anwendung ist per verschlüsselter Application-GUID registriert +Fakt: POST /jwt/login ([Authorize(JwtBearer)]) baut ein OpenIdConnectAuthObject: Web-Service-Token holen, Application-GUID entschlüsseln (ApplicationGuidHelper.GetDecryptedApplicationGuid), authentifizierte ClaimsIdentity verlangen; der AuthenticatorFactory-Authenticator liefert das Centron-Ticket (sonst 401); POST /jwt/connect_accounts validiert zusätzlich ein bestehendes Ticket (UserI3D>0) und verknüpft Konten über OpenIdConnectAccountConnector.ConnectOwnAccounts. +Aussage: Die Software soll einen per OpenID Connect authentifizierten Benutzer gegen ein internes Centron-Sitzungsticket eintauschen und das Verknüpfen eines externen Identitätskontos mit einem bestehenden Centron-Konto nur bei gültigem Ticket erlauben. +Ergebnis: Erfolgreicher Login liefert ein Centron-Ticket; fehlgeschlagene Authentifizierung führt zu 400/401 ohne Ticket. +Belege: + - [PRIMÄR] src\webservice\Centron.Controllers\Controllers\Unversioned\JwtAuthController.cs - LoginWithBearer: "[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]"; GetAuthObject: "if (HttpContext.User.Identity is not ClaimsIdentity { IsAuthenticated: true } identity) ... return ...AsError("Principal is not authenticated")"; "if (ticketResult.Status != ResultStatus.Success) return Unauthorized(...)" - Begründung: Durchsetzende Prüfung von JWT, Application-GUID und Ticketausgabe. + - [PRIMÄR] ebd. - ConnectAccounts: "if (ticketResult.Data.UserI3D <= 0) return Unauthorized(...)" - Begründung: Verknüpfung nur mit gültigem, benutzergebundenem Ticket. +Prüfidee: /jwt/login ohne Bearer → 401; mit gültigem Bearer aber unbekannter Application → 400 "Application not found."; korrekt → Ticket im Response-Body. +Tracelinks: SyRS-817 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - OIDC-Brücke ist SaaS-Grundbaustein. +Status: belegt +``` + +### SwRS-834: Zwei-Faktor-Validierung per E-Mail-Link + +``` +ID: SwRS-834 +Titel: 2FA-Code-Validierung über anonymen Bestätigungslink +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: TwoFactorAuthController (/2fa/validate), Benutzer mit 2FA-Mail +Vorbedingung: WebServiceConfigHelper.Current.TwoFactorAuthEnabled == true und EmailTwoFactorValidator aktiv +Fakt: GET /2fa/validate?code=... ist [AllowAnonymous]; wenn 2FA deaktiviert oder kein EmailTwoFactorValidator, antwortet der Endpunkt "Die Zwei-Faktor-Authentifizierung über E-Mail Links ist nicht aktiviert."; TrySetCodeAsValidated(code)==false liefert "Ungültiger Code. Bitte melden Sie sich erneut an.", sonst "Anmeldung erfolgreich!". +Aussage: Die Software soll den zweiten Faktor einer Anmeldung über einen per E-Mail zugestellten Code-Link bestätigen und ungültige Codes ohne Sitzungsfreigabe abweisen. +Ergebnis: Nur ein gültiger, zuvor erzeugter Code markiert die Anmeldung als 2FA-bestätigt. +Belege: + - [PRIMÄR] src\webservice\Centron.Controllers\Controllers\Unversioned\TwoFactorAuthController.cs - ValidateTwoFactorCode: "if (emailTwoFactorValidator.TrySetCodeAsValidated(code) == false) return this.Ok("Ungültiger Code. ...");" - Begründung: Durchsetzende Code-Prüfung inkl. Konfigurationsgate TwoFactorAuthEnabled. +Prüfidee: Login mit aktivierter 2FA: Link-Aufruf mit korrektem Code schaltet die Sitzung frei; manipulierter Code führt zur Fehlermeldung und keiner Freischaltung. +Tracelinks: SyRS-817 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - 2FA ist Pflicht für SaaS; Link-Mechanik ggf. um TOTP ergänzen. +Status: belegt +``` + +### SwRS-835: Web-Account-Verwaltung nur mit Recht WEBACCOUNT_MANAGEMENT + +``` +ID: SwRS-835 +Titel: Rechteprüfung WEBACCOUNT_MANAGEMENT in der WebAccount-Geschäftslogik +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: WebAccountWebServiceBL (aufgerufen u. a. von WebAccountController und Nexus Management/WebAccount) +Vorbedingung: Mitarbeiter ruft Anlage/Änderung/Suche von Web-Accounts auf +Fakt: CreateWebAccountWithContacts, UpdateWebAccount, SearchWebAccountByI3D und SearchWebAccountItems prüfen jeweils "if (!currentUser.User.HasUserRight(UserRightsConst.Sales.Customer.CustomerCommon.WEBACCOUNT_MANAGEMENT)) return ...AsError("User has no web account management rights", DefaultMessageCodes.RightCheckFailed)"; die Nexus-Verwaltungsseite ist zusätzlich mit [AuthorizeRightId(...WEBACCOUNT_MANAGEMENT)] geschützt. +Aussage: Die Software soll sämtliche verwaltenden Operationen auf Web-Accounts (anlegen, ändern, suchen, deaktivieren) nur Benutzern mit dem Recht WEBACCOUNT_MANAGEMENT erlauben und dies in der Geschäftslogik (nicht nur in der UI) durchsetzen. +Ergebnis: Ohne das Recht liefert jede Operation RightCheckFailed; die UI-Seite ist zusätzlich gesperrt. +Belege: + - [PRIMÄR] src\backend\Centron.BL\WebServices\Administration\Logins\WebAccountWebServiceBL.cs Zeilen 54, 75, 86, 107, 215, 227 - HasUserRight(WEBACCOUNT_MANAGEMENT)-Prüfungen mit Fehlermeldung "User has no web account management rights" - Begründung: Durchsetzende BL-Prüfung auf jedem Pfad. + - [SEKUNDÄR] src\nexus\CentronNexus\Management\WebAccount\_imports.razor - "@attribute [AuthorizeRightId(UserRightsConst.Sales.Customer.CustomerCommon.WEBACCOUNT_MANAGEMENT)]" - Begründung: UI-seitige Zweitabsicherung. +Prüfidee: API-Aufruf create-web-account mit Benutzer ohne Recht → BadRequest "User has no web account management rights"; mit Recht → Account-I3D. +Tracelinks: SyRS-817, SyRS-811 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Defense-in-Depth (BL-Prüfung unabhängig von Controller-Attributen). +Status: belegt +``` + +### SwRS-836: AuthenticateInterceptor der Legacy-API + +``` +ID: SwRS-836 +Titel: Interceptor-basierte Ticket-/Access-Token-Prüfung mit Anwendungs- und Login-Typ-Sperren +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: AuthenticateInterceptor (Castle DynamicProxy, Priority 10) +Vorbedingung: Aufruf einer [Authenticate]-Methode mit Request-Parameter +Fakt: Der Interceptor verlangt einen Request als erstes Argument (sonst Programmierfehler-Exception), lehnt leere Tickets ab ("You need to provide a ticket..."), validiert über AuthenticationTicketBL.GetAuthTicketInfo(ticket, ipAddress, apiMethod) (IP aus X-Forwarded-For → X-Real-IP → RemoteIpAddress), verlängert Ticket-Gültigkeit per RefreshTicketExpireDate, setzt bei Access-Token AccessTokenLogged zur Vermeidung von Doppel-Logging und blockiert Anwendungen außerhalb attribute.Applications sowie Web-Account-Tickets ohne AllowWebAccountLogin mit "You don't have the permission to execute the method '...'". +Aussage: Die Software soll die Authentifizierung der Legacy-API als vorgeschalteten Interceptor implementieren, der Ticket bzw. Access-Token inklusive Client-IP und Methodennamen validiert, Sitzungen verlängert und Anwendungs-/Login-Typ-Beschränkungen je Methode durchsetzt. +Ergebnis: Nicht autorisierte Aufrufe erhalten eine Fehler-Response (InvalidTicket bzw. Failed), ohne dass die Zielmethode ausgeführt wird. +Belege: + - [PRIMÄR] src\webservice\Centron.Host\AspNetCore\WcfBridge\Interception\Interceptors\AuthenticateInterceptor.cs - InterceptExecution + ValidateTicketAndSetReturnValue (vollständige Bedingungskette, invocation.Proceed() nur nach erfolgreicher Prüfung) - Begründung: Durchsetzende Stelle. + - [SEKUNDÄR] src\webservice\Centron.WebServices.Core\Interception\Interceptors\AuthenticateAttribute.cs - AllowWebAccountLogin default false, ReturnFailedInsteadOfInvalidTicket - Begründung: Konfigurationsflächen des Interceptors. +Prüfidee: Aufruf mit abgelaufenem Ticket → "Invalid ticket or access token."; Aufruf einer nicht für die Anwendung freigegebenen Methode → Permission-Fehler; gültiges Ticket → ExpireDate wird verlängert. +Tracelinks: SyRS-818 +Konsolidierung: Kandidat: SwRS-831 (zweite, getrennte Implementierung des API-Zugriffsschutzes) +Übernahmewürdigkeit: veraltet - an die Legacy-API gebunden; Prinzip (zentrale vorgeschaltete AuthN) übernehmen. +Status: belegt +``` + +### SwRS-837: Globale Exception-Behandlung der REST-API + +``` +ID: SwRS-837 +Titel: GlobalExceptionFilter: Logging, Pool-Recovery, generische 500-Antwort +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: Zuverlässigkeit +Akteur: GlobalExceptionFilter (IExceptionFilter) +Vorbedingung: Unbehandelte Exception in einer Controller-Aktion +Fakt: OnException loggt Exception samt Action-Name, ruft DAOFactory.Instance.TryRecoverConnectionPool(context.Exception) und setzt Response 500 mit JsonResult {"Message":"An unexpected error occurred while processing your request."}. +Aussage: Die Software soll jede unbehandelte Controller-Exception protokollieren, bei Verbindungsfehlern den Datenbank-Verbindungspool wiederherstellen und dem Client ausschließlich eine generische Fehlermeldung ohne interne Details liefern. +Ergebnis: Keine Stacktraces/Interna in API-Antworten; DB-Verbindungen erholen sich automatisch. +Belege: + - [PRIMÄR] src\webservice\Centron.Controllers\Configuration\GlobalExceptionFilter.cs - OnException (komplette Methode) - Begründung: Durchsetzende Implementierung. + - [SEKUNDÄR] src\webservice\Centron.Host\AspNetCore\RegisterCentronServices.cs Zeile 81 - options.Filters.Add() - Begründung: Globale Wirksamkeit für alle Controller. +Prüfidee: Testaktion wirft Exception → Response 500, Body enthält nur die generische Message; Logeintrag mit Action-Name vorhanden. +Tracelinks: SyRS-819 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Standard-Fehlerbaseline. +Status: belegt +``` + +### SwRS-838: Kebab-Case-Routing und Namespace-Versionierung + +``` +ID: SwRS-838 +Titel: KebabCaseTransformer und API-Versionierung per Namespace +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Routing der REST-API +Vorbedingung: Controller mit Route "v{version:apiVersion}/[controller]" +Fakt: KebabCaseTransformer.TransformOutbound ersetzt per Regex "([a-z])([A-Z])" durch "$1-$2" und lowercased; RegisterCentronApiVersioning setzt DefaultApiVersion=1, ReportApiVersions=true und VersionByNamespaceConvention (Versionsordner v1, Unversioned mit [ApiVersionNeutral]). +Aussage: Die Software soll Controller-Namen automatisch in Kebab-Case-URLs übersetzen und API-Versionen aus dem Namespace ableiten, mit Version 1 als Standard. +Ergebnis: Konsistente URLs wie /v1/supplier-article-codes ohne manuelle Routenpflege. +Belege: + - [PRIMÄR] src\webservice\Centron.Controllers\Configuration\Routing\KebabCaseTransformer.cs - Regex.Replace(...).ToLower() - Begründung: Konkrete Transformationsregel. + - [PRIMÄR] src\webservice\Centron.Host\AspNetCore\RegisterCentronApiVersioning.cs - DefaultApiVersion new ApiVersion(1), VersionByNamespaceConvention - Begründung: Versionierungskonvention. +Prüfidee: Controller "SupplierArticleCodesController" im Namespace v1 ist unter GET /v1/supplier-article-codes erreichbar. +Tracelinks: SyRS-819 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - geringe Kosten, hohe Konsistenz. +Status: belegt +``` + +### SwRS-839: Claims-Aufbau aus Rechten, Web-Rechten und Lizenzen + +``` +ID: SwRS-839 +Titel: ClaimsService: Abbildung von Rechten/Web-Rechten/Lizenzen auf Rollen-Claims +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: ClaimsService (Nexus), ClaimsMiddleware +Vorbedingung: Gültiges Centron-Ticket der Nexus-Sitzung +Fakt: GetClaims lädt Login-Informationen, Lizenzübersicht und WebAccountReceiptSettings, erzeugt Role-Claims "EmployeeRights", "WebAccountRights", "License"; Web-Rechte werden gegen Belegzugriffs-Einstellungen gefiltert (Never entfernt, Always ergänzt z. B. WEBRIGHT_SHOWALLINVOICES); GetClaimForCommonLoginInfo setzt u. a. LoginType-, EmployeeI3D-, CustomerI3D-Claims und für Inhaber von Administration.SETTINGS die Rolle "Administrator" (Rückwärtskompatibilität); Cache 30 Minuten. +Aussage: Die Software soll die Backend-Berechtigungen (Benutzerrechte, Web-Account-Rechte, Lizenzen) einer Sitzung als Claims/Rollen in die Web-Identität übersetzen und dabei konfigurationsabhängige Belegzugriffe (immer/nie) berücksichtigen. +Ergebnis: Die Nexus-Policies (SyRS-811) können rein claims-basiert entscheiden; Rechteänderungen wirken spätestens nach Cache-Ablauf. +Belege: + - [PRIMÄR] src\nexus\CentronNexus\Shared\Authorization\ClaimsService.cs - GetClaims/GetClaimsFromRights/GetClaimsFromWebRights/GetWebRightI3DsConformingSettings (u. a. "if (webRightReceiptSettings.InvoicesAccess == WebAccountAccessType.Always) filteredWebRights.Add((int)WebAccountRightsConst.WEBRIGHT_SHOWALLINVOICES);") - Begründung: Durchsetzende Claim-Erzeugung inkl. Einstellungslogik. +Prüfidee: Web-Account mit InvoicesAccess=Always erhält Rechnungszugriff auch ohne explizites Web-Recht; mit Never wird ein vorhandenes Recht ignoriert. +Tracelinks: SyRS-811 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - saubere Trennung Backend-Rechte ↔ Web-Claims; 30-Minuten-Cache als Latenz dokumentieren. +Status: belegt +``` + +### SwRS-840: Portgebundene Trennung von Mitarbeiter- und Kundenportal + +``` +ID: SwRS-840 +Titel: PortHandler: getrennte Ports für Host- und Kundenportal-Bereich +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: PortHandler (AuthorizationHandler), Policies "PortHost" und "PortCustomerPortal" +Vorbedingung: CustomerPortalConfig.Port konfiguriert (sonst keine Einschränkung) +Fakt: AddPortAuthorization registriert Policies mit PortRequirement (HostPort default 8050, CustomerPortalPort default = HostPort); PortHandler succeeded, wenn config.Value.Port null ist oder der lokale Verbindungsport dem erlaubten Port entspricht, andernfalls loggt er "Port {Port} is not allowed" und verweigert. +Aussage: Die Software soll Mitarbeiterbereich (ServiceBoard, [AuthorizeHostPort]) und Kundenportal ([AuthorizeCustomerPortalPort]) optional auf getrennte TCP-Ports binden und Anfragen über den falschen Port verweigern. +Ergebnis: Bei konfigurierter Port-Trennung ist das Kundenportal nicht über den Mitarbeiter-Port erreichbar und umgekehrt. +Belege: + - [PRIMÄR] src\nexus\CentronNexus\Shared\Authorization\PortAuthorization.cs - PortHandler.HandleRequirementAsync: "if (http?.Connection.LocalPort is null || requirement.AllowedPort == http.Connection.LocalPort) { context.Succeed(requirement); }" - Begründung: Durchsetzende Portprüfung. + - [SEKUNDÄR] src\nexus\CentronNexus\WebCart\_Imports.razor / ServiceBoard\_Imports.razor - [AuthorizeCustomerPortalPort] bzw. [AuthorizeHostPort] - Begründung: Zuordnung der Bereiche zu Ports. +Prüfidee: CustomerPortalConfig.Port=8443 setzen: /webcart über 8050 → NotAuthorized; über 8443 → erreichbar. +Tracelinks: SyRS-811 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - Port-Trennung ersetzt fehlende Host-/Domänentrennung; in SaaS durch getrennte Hosts/Subdomains lösen. +Status: belegt +``` + +### SwRS-841: Warenkorb-Zugriffsguards und Warenkorbauswahl + +``` +ID: SwRS-841 +Titel: ReceiptCart-Guards: Lizenz, Web-Account-Recht, Kartenzugriff; aktuelle Warenkorbauswahl +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: ReceiptCartBL, CurrentCartService (WebCart) +Vorbedingung: Web-Account-Login; Operation auf einem Warenkorb (ReceiptOffer mit IsCart=true) +Fakt: ThrowIfLicenseIsMissing wirft "Sie haben nicht die benötigte Lizenz." (LicenseNotFound); ThrowIfCanNotAccessCart lädt den Beleg benutzerbezogen und wirft bei null/IsCart=false/State!=Active "Der Warenkorb wurde nicht gefunden."; ThrowIfWebAccountDoesntHaveRight wirft "Sie haben nicht die benötigten Rechte für diese Operation." (RightCheckFailed) wenn das Web-Recht fehlt; GetAllCarts verlangt IsWebAccountLogin; CurrentCartService wählt den zuletzt erstellten Warenkorb oder legt bei Bedarf einen neuen an (CreateNewReceiptCart). +Aussage: Die Software soll jede Warenkorb-Operation gegen Lizenz WebCart2, Web-Account-Login, Web-Recht und benutzerbezogenen Kartenzugriff absichern und dem Benutzer stets einen aktuellen Warenkorb bereitstellen (neuester vorhandener oder automatisch neu angelegter). +Ergebnis: Fremde, inaktive oder unlizenzierte Warenkörbe sind nicht manipulierbar; der Shop hat immer einen aktiven Warenkorb. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptCartBL.cs - ThrowIfCanNotAccessCart/ThrowIfLicenseIsMissing/ThrowIfWebAccountDoesntHaveRight (vollständige Bedingungen, siehe "offer is null or { IsCart: false } or { State: not ReceiptState.Active }") - Begründung: Durchsetzende Guards. + - [SEKUNDÄR] src\nexus\CentronNexus\WebCart\Helpers\CurrentCartService.cs - GetCurrentCartI3D: OrderByDescending(CreatedAt).First() bzw. CreateNewReceiptCart - Begründung: Auswahl-/Anlagelogik. +Prüfidee: Zugriff auf Warenkorb-I3D eines fremden Web-Accounts → "Der Warenkorb wurde nicht gefunden."; Shop-Aufruf ohne vorhandenen Warenkorb legt automatisch einen an. +Tracelinks: SyRS-812 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Guards und Auto-Anlage sind fachlich sinnvoll. +Status: belegt +``` + +### SwRS-842: Bestellfreigabe erzeugt Auftrag mit Pflichtfeldern und Mails + +``` +ID: SwRS-842 +Titel: OrdererApproveCart: Pflichtfelder, Statuswechsel Checked→Ordered, Auftragserzeugung, Benachrichtigung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: ReceiptCartReleaseSystemBL, Web-Account mit WEBRIGHT_WEBCART2_ORDER_CART +Vorbedingung: Warenkorb im Zustand Checked; Web-Account-Login +Fakt: OrdererApproveCart verlangt Web-Account-Login (Guard), prüft Lizenz und Kartenzugriff, erzwingt Bestellnummer wenn customer.PurchaseOrderNumberRequiered ("Bitte tragen Sie eine Bestellnummer ein!") und eine Lieferadresse ("Bitte tragen Sie eine Lieferadresse ein!"), wechselt den Zustand Checked→Ordered (rechte- und zustandsgeprüft, persistiert per UpdateBuilder auf AngKopf.CartState), schreibt ReceiptLog, erzeugt via ForwardCartToOrder/SaveOrder den Auftrag, schließt den Warenkorb und versendet Mails an Ersteller/Prüfer/Besteller (MailTemplateReferences.ReceiptCart.CartOrderedToCustomer) sowie intern (CartOrderedToEmployee). +Aussage: Die Software soll bei der Bestellfreigabe eines geprüften Warenkorbs kundenspezifische Pflichtfelder (Bestellnummer, Lieferadresse) validieren, den Warenkorb in den Zustand Bestellt überführen, daraus einen Auftrag erzeugen und alle Beteiligten per Mail-Vorlage benachrichtigen. +Ergebnis: Rückgabe von OrderI3D/OrderNumber; Warenkorb geschlossen; Mails versendet. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptCartReleaseSystemBL.cs Zeilen 167-216 - OrdererApproveCart (vollständige Bedingungs- und Ablaufkette inkl. ResultException MandatoryFieldsNotFilled) - Begründung: Durchsetzende Bestelllogik. + - [SEKUNDÄR] src\nexus\CentronNexus\WebCart\Components\WebCartClearance.razor - Erfolgsmeldung "Der Warenkorb wurde mit Bestellung \"{0}\" bestellt!" - Begründung: UI-Bestätigung mit Auftragsnummer. +Prüfidee: Kunde mit PurchaseOrderNumberRequiered=true: Freigabe ohne Bestellnummer → Fehler MandatoryFieldsNotFilled; mit Bestellnummer/Lieferadresse → Auftrag existiert und CartState=Ordered. +Tracelinks: SyRS-812 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - vollständiger, geprüfter Bestellabschluss. +Status: belegt +``` + +### SwRS-843: Annahme-/Änderungslogik des Web-Angebots + +``` +ID: SwRS-843 +Titel: WebOffer: Annahme mit/ohne Signatur, Ablehnung und Positionsänderungswünsche +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: WebReceiptOverview.razor (Seite /weboffer/{Token}), ReceiptWebServiceBL +Vorbedingung: Gültiges Web-Receipt-Token; Web-Angebot im Zustand InProcess +Fakt: Die Seite setzt _canExecuteAction nur bei Receipt.AllowAcceptReceipt und laufendem Web-Receipt; Ablehnung ruft ChangeWebReceiptState(Token, Rejected); Annahme wählt AcceptWebReceiptWithChangeRequests bei offenen Änderungswünschen, sonst AcceptFullWebReceipt; ohne AllowAcceptReceiptWithoutSignature folgt der Hinweis "Bitte Signieren Sie das folgende Dokument um einen Auftrag zu erteilen."; Mengen-/Positionsänderungen laufen über RequestForWebReceiptItemChange(token, ChangeRequestKind.QuantityChange/ReceiptItemArticlePositionKindChange, ...), Bestellnummeränderung über ChangeWebReceiptPurchaseOrderNumber. +Aussage: Die Software soll dem Angebotsempfänger Ablehnung, vollständige Annahme oder Annahme mit Änderungswünschen anbieten, Änderungswünsche als eigene Objekte protokollieren und die Annahme ohne Signatur nur bei entsprechender Freigabe des Angebots zulassen. +Ergebnis: Der Web-Receipt-Zustand spiegelt die Kundenentscheidung; Änderungswünsche liegen dem Vertrieb zur Nacharbeit vor. +Belege: + - [PRIMÄR] src\nexus\CentronNexus\WebOffer\WebReceiptOverview.razor Zeilen 939-977 - ChangeWebReceiptState(Token, Rejected / AcceptWebReceiptWithChangeRequests / AcceptFullWebReceipt) und Signatur-Gate über _canAcceptWithoutSignature - Begründung: Implementierte Entscheidungslogik. + - [PRIMÄR] src\backend\Centron.BL\WebServices\Sales\Receipts\ReceiptWebServiceBL.cs - RequestForWebReceiptItemChange: erzeugt WebReceiptItemChangeRequest über _receiptBL.CreateRequestForWebReceiptItemChange - Begründung: Persistierte Änderungswünsche. +Prüfidee: Angebot mit AllowAcceptReceiptWithoutSignature=false annehmen → Signaturaufforderung statt sofortiger Auftrag; Mengenänderung erzeugt WebReceiptItemChangeRequest-Datensatz. +Tracelinks: SyRS-813 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - differenzierte Annahmevarianten sind fachlich wertvoll. +Status: belegt +``` + +### SwRS-844: Signatur-Durchführung mit SEPA-Validierung und Einmal-Entwertung + +``` +ID: SwRS-844 +Titel: DocumentSigning: Signatur/Upload, SEPA-Pflichtfelder, Bestätigung und Ablehnung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: DocumentSigningPage (/contractmanagement), DsgvoBL +Vorbedingung: Gültiger GUID-Link auf ein OnlinePdfDocument +Fakt: SignTheDocument erzwingt bei SEPA-Dokumenten Bankbezeichnung, gültige IBAN (IsValidIban plus Länge 15–34 ohne Leerzeichen) und BIC; ohne Upload sind Unterschriftsort und gezeichnete Signatur Pflicht; alternativ kann ein unterschriebenes PDF (max. 20 MB) hochgeladen werden; ConfirmOnlinePdfDocument prüft die Guards serverseitig erneut (signPlace/signDate/signature bzw. signedDocument) und löscht das Dokument nach Erfolg; DeclineOnlinePdfDocument speichert eine Ablehnung mit optionalem Grund. +Aussage: Die Software soll die Online-Signatur wahlweise per gezeichneter Unterschrift (mit Ortsangabe) oder per Upload eines signierten PDFs abwickeln, bei SEPA-Mandaten Bankdaten inkl. IBAN-Prüfung erzwingen, die Bestätigung serverseitig validieren und den Signaturlink anschließend entwerten. +Ergebnis: Vollständig validierte Signatur bzw. dokumentierte Ablehnung; Link nicht wiederverwendbar. +Belege: + - [PRIMÄR] src\nexus\CentronNexus\DocumentSigning\DocumentSigningPage.razor Zeilen 671-740 - SignTheDocument: IBAN-/BIC-/Bankname-Prüfungen, "Bitte geben Sie den Ort der Unterschrift ein.", ConfirmOnlinePdfDocumentRequest - Begründung: Clientseitige Pflichtfeldvalidierung. + - [PRIMÄR] src\backend\Centron.BL\Administration\Documents\Dsgvo\DsgvoBL.cs Zeilen 182-212 - ConfirmOnlinePdfDocument: Guard-Kette und DeleteOnlinePdfDocument nach Erfolg - Begründung: Serverseitige Durchsetzung inkl. Einmaligkeit. +Prüfidee: SEPA-Dokument mit IBAN der Länge 14 → Fehler "Die eingegebene IBAN ist ungültig."; erfolgreiche Signatur → OnlinePdfDocument-Datensatz gelöscht. +Tracelinks: SyRS-814 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - inkl. SEPA-Sonderpfad. +Status: belegt +``` + +### SwRS-845: Serverseitiges Kunden-Scoping der Portal-Ticketsuche + +``` +ID: SwRS-845 +Titel: HelpdeskSearchBL: Expression-Filter für Web-Account-Logins +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: HelpdeskSearchBL +Vorbedingung: Ticketsuche mit loggedInUser.IsWebAccountLogin == true +Fakt: Der Suchausdruck wird um customerI3Ds.Contains(f.CustomerI3D) und !f.IsOnlyInternalVisible ergänzt; die Kundenmenge ergibt sich aus dem Web-Recht: CUSTOMERADMINISTRATOR → eigener Kunde plus GetCustomerCorporations, sonstige Ticket-Web-Rechte → nur eigener Kunde; zusätzlich kann ForceTicketClearanceCheck auf IsTicketRefused filtern. +Aussage: Die Software soll das Kunden-Scoping der Portal-Ticketsuche als serverseitigen Query-Filter implementieren, dessen Reichweite (eigener Kunde vs. Konzernverbund) vom Web-Recht abhängt. +Ergebnis: Die Datenbank liefert ausschließlich berechtigte Tickets; kein clientseitiges Nachfiltern nötig. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskSearchBL.cs Zeilen 535-564 - vollständiger IsWebAccountLogin-Block mit HasWebRight-Fallunterscheidung und And-Expressions - Begründung: Durchsetzende Query-Ebene. +Prüfidee: Web-Account mit CUSTOMERADMINISTRATOR eines Konzernkunden sieht Tickets der Tochterkunden; ohne dieses Recht nur Tickets des eigenen Kunden. +Tracelinks: SyRS-815 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Scoping in der Query ist das richtige Muster. +Status: belegt +``` + +### SwRS-846: Ticketabschluss mit Statuswechsel, Aufräumen und Historie + +``` +ID: SwRS-846 +Titel: HelpdeskCloseBL.CloseHelpdesk: Abschlusszustand, ToDo-Löschung, Historie, Aktivitäten +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: HelpdeskCloseBL, Servicemitarbeiter +Vorbedingung: Ticket existiert; Abschluss über ServiceBoard oder Client ausgelöst +Fakt: CloseHelpdesk lädt den konfigurierten Abschlusszustand (GetClosedHelpdeskState), prüft CanCloseHelpdesk, löscht Ticket-ToDos (Abbruch bei Fehler), setzt HelpdeskState und ClosedAt=DateTime.Now, speichert mit optionalem ignoreMandatoryFieldsOnClose und erzeugt bei Erfolg Nexus-Benachrichtigungen, einen Historieneintrag (HelpdeskHistoryType.Close) und eine AccountActivity; CloseHelpdeskWithNotification ergänzt Empfänger-Benachrichtigungen. +Aussage: Die Software soll beim Ticketabschluss den konfigurierten Abschlussstatus samt Abschlusszeitpunkt setzen, offene ToDos entfernen, den Vorgang historisieren und Benachrichtigungen/Aktivitäten erzeugen; Pflichtfeldprüfungen sollen beim Abschluss gezielt übersteuerbar sein. +Ergebnis: Konsistent abgeschlossenes Ticket mit lückenloser Historie. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskCloseBL.cs Zeilen 120-158 - CloseHelpdesk (Zustand, ClosedAt, DeleteHelpdeskToDos, CreateHistoryForActionType, CreateActivityForTicketClosed) - Begründung: Durchsetzende Abschlusslogik. + - [SEKUNDÄR] src\nexus\CentronNexus\ServiceBoard\CloseTicket\Components\CloseTicket.razor - CloseHelpdeskWithNotificationRequest mit NotificationSettings - Begründung: Web-Auslöser inkl. Benachrichtigungsoptionen. +Prüfidee: Ticket mit offenen ToDos schließen → ToDos entfernt, HelpdeskState=Abschlusszustand, Historieneintrag Close vorhanden. +Tracelinks: SyRS-816 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kernprozess Service. +Status: belegt +``` + +### SwRS-847: Werkschritt-Abschluss in der Produktionsübersicht + +``` +ID: SwRS-847 +Titel: ProductionOrderManagement: Werkschritt auf Finished setzen und persistieren +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: ProductionOrderOverView.razor / WorkStepTemplateComponent, Produktionsmitarbeiter +Vorbedingung: Arbeitsplatz (ProductionMachineKind) und Maschine gewählt; Werkschritt im Zustand OpenNotStarted +Fakt: Die Übersicht lädt Werkschritte über GetProductionOrderItemsByFilter je Maschine, zeigt Zustände (OpenNotStarted/Finished) und setzt bei "Fertig" State=ProductionOrderItemState.Finished mit anschließendem SaveProductionOrderItem; Logs werden über GetProductionOrderLogsByFilter je Werkschritt geladen. +Aussage: Die Software soll Produktionswerkschritte arbeitsplatz- und maschinenbezogen anzeigen und deren Abschluss als Statusübergang OpenNotStarted→Finished persistieren. +Ergebnis: Der Werkschritt ist dauerhaft als erledigt markiert und aus der offenen Liste entfernt. +Belege: + - [PRIMÄR] src\nexus\CentronNexus\ProductionOrderManagement\Components\WorkStepTemplateComponent.razor Zeile 172-179 - FinishWorkstep: State = ProductionOrderItemState.Finished - Begründung: Implementierter Statusübergang. + - [SEKUNDÄR] src\nexus\CentronNexus\ProductionOrderManagement\Pages\ProductionOrderOverView.razor Zeile 342 - CentronService.SaveProductionOrderItem(...) - Begründung: Persistierung über den Web-Service. +Prüfidee: Werkschritt "Fertig" klicken, Seite neu laden → Werkschritt hat Zustand Finished. +Tracelinks: SyRS-816 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - einfacher, brauchbarer Produktions-Basisprozess. +Status: belegt +``` + +### SwRS-848: [HYPOTHESE] Fehlender Seitenschutz der Produktionsübersicht + +``` +ID: SwRS-848 +Titel: [HYPOTHESE] Produktionsübersicht ohne deklarativen Autorisierungsschutz +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: ProductionOrderOverView.razor (/production/overview) +Vorbedingung: Aufruf der Route /production/overview im Nexus +Fakt: Im Ordner ProductionOrderManagement existiert keine _Imports.razor mit Authorize-Attributen und die Seite selbst trägt kein @attribute [Authorize...]; die AuthorizeRouteView erzwingt nur auf Seiten deklarierte Attribute, eine globale Fallback-Policy war in CentronNexus.Host\Program.cs nicht auffindbar. +Aussage: Das System soll die Produktionsübersicht — wie alle Mitarbeiterseiten — nur angemeldeten Benutzern mit passender Lizenz/Recht anzeigen; die aktuelle Implementierung lässt einen ungeschützten Seitenaufruf vermuten (Datenabrufe schlagen dann erst im Backend fehl). +Ergebnis: Erwartet: NotAuthorized-Ansicht für anonyme Aufrufer; beobachtbar ist das Fehlen der deklarativen Absicherung. +Belege: + - [PRIMÄR] src\nexus\CentronNexus\ProductionOrderManagement\Pages\ProductionOrderOverView.razor - @page "/production/overview" ohne jegliches Authorize-Attribut; kein _Imports.razor im Modulordner (Verzeichnislisting) - Begründung: Nachweis der fehlenden deklarativen Prüfung (Negativbefund). + - [SEKUNDÄR] src\nexus\CentronNexus.Host\Routes.razor - AuthorizeRouteView ohne globale Policy - Begründung: Kein Fallback-Schutz auf Router-Ebene erkennbar. +Prüfidee: Anonymer Browser-Aufruf von /production/overview: prüfen, ob die Seite rendert oder eine Login-/NotAuthorized-Umleitung erfolgt. +Tracelinks: SyRS-811 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - fehlende Absicherung nicht übernehmen; Zielsystem braucht Fallback-Policy (secure by default). +Status: HYPOTHESE +Offene Frage: Existiert an anderer Stelle (Middleware, Host-Konfiguration, Reverse Proxy) ein Schutz der Route /production/overview, oder ist die Seite tatsächlich anonym erreichbar? +``` + +### SwRS-849: Mobile-Altzugriff auf Mitarbeiter- und Kontaktdaten + +``` +ID: SwRS-849 +Titel: MobileBL: Lesezugriff auf NewMobileEmployee/NewMobileContactPerson +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: MobileBL (Centron.BL\Mobile) +Vorbedingung: Aufruf über die Service-Schicht mit gültiger Sitzung +Fakt: MobileBL (37 Zeilen) bietet ausschließlich GetMobileEmployee (einzeln per I3D bzw. Liste mit Filter State == 1) und GetContactPersonImage (Picture-Bytes als Base64-String, leerer String ohne Bild); keine Schreiboperationen. +Aussage: Die Software soll mobilen Clients aktive Mobile-Mitarbeiter (State=1) und Kontaktpersonen-Bilder (Base64) lesend bereitstellen. +Ergebnis: Mobile Clients erhalten die minimal nötigen Stammdaten; inaktive Mitarbeiter werden ausgefiltert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Mobile\MobileBL.cs - GetMobileEmployee: "GetList(f => f.State == 1)"; GetContactPersonImage: Convert.ToBase64String(imageData) - Begründung: Vollständige, durchgesetzte Modulfunktionalität. +Prüfidee: Mitarbeiter mit State=0 anlegen → erscheint nicht in GetMobileEmployee(); Kontakt ohne Bild → leerer String. +Tracelinks: SyRS-818 +Konsolidierung: Kandidat (vermutet): Mitarbeiterdaten existieren zusätzlich im regulären Employee-Stamm (EmployeesController/EmployeeArea) — NewMobileEmployee wirkt wie eine separate Alt-Datenhaltung für denselben Gegenstand. +Übernahmewürdigkeit: veraltet - minimaler Alt-Baustein ("New"-Präfix, keine Pflege); im Zielsystem über reguläre Mitarbeiter-API abdecken. +Status: belegt +``` + +### SwRS-850: Objektbezogene Web-Links mit ausführbaren Aktionen + +``` +ID: SwRS-850 +Titel: SimpleUrl-Verwaltung und WebLink-Aktionen (CRM-Aktivität beim Linkklick) +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: SimpleUrlBL, WebLinkBL mit IWebLinkActionHandler +Vorbedingung: URLs bzw. WebLink-Gruppen sind zu einem Objekt (ObjectKind/ObjectI3D) hinterlegt +Fakt: SimpleUrlBL filtert SimpleUrl-Datensätze nach ObjectI3D, ObjectKind, IsVisible, CreatedDate und Volltext (Caption/URL); WebLinkBL verwaltet WebLinkGroup/WebLink/WebLinkAction (Batchgröße 2000 je Parameterliste) und registriert Handler, aktuell WebLinkActionAccountActivityHandler (Type=CRMEntry), der aus action.Options (JSON, AccountActivityOptions) per AdviserType den zuständigen Betreuer des Accounts ermittelt und eine Account-Aktivität erzeugt; ohne Account oder Konfiguration wird ein Fehler-Result geliefert. +Aussage: Die Software soll beliebigen Geschäftsobjekten sichtbarkeitsgesteuerte URLs zuordnen und für WebLinks konfigurierbare Folgeaktionen (z. B. Anlage einer CRM-Aktivität beim zuständigen Betreuer) ausführen. +Ergebnis: Objektbezogene Linklisten; Linkaktionen erzeugen nachvollziehbare CRM-Einträge. +Belege: + - [PRIMÄR] src\backend\Centron.BL\WebLinks\WebLinkActionAccountActivityHandler.cs - Execute: Deserialisierung AccountActivityOptions, AdviserType-Switch (Adviser1...), Fehler-Result "Could not create account activity..." - Begründung: Durchsetzende Aktionslogik. + - [PRIMÄR] src\backend\Centron.BL\Urls\SimpleUrlBL.cs - CreateFilterExpression mit ObjectI3D/ObjectKind/IsVisible/SearchText-Bedingungen - Begründung: Objektbezug und Sichtbarkeitsfilter der URL-Haltung. +Prüfidee: WebLinkAction vom Typ CRMEntry mit AdviserType=Adviser1 auf Account ohne Adviser1 → Fehler-Result und Logeintrag; mit Adviser → Account-Aktivität angelegt. +Tracelinks: SyRS-816, SyRS-818 +Konsolidierung: Kandidat: SimpleUrl (Centron.BL\Urls) und WebLink (Centron.BL\WebLinks) sind zwei getrennte Datenhaltungen für objektbezogene Links. +Übernahmewürdigkeit: übernehmen - Linkverwaltung übernehmen, dabei die beiden Implementierungen zusammenführen. +Status: belegt +``` + +## Cluster A9 — Datenaustausch & Integrationen — SwRS + +### SwRS-931: Zeitkonstante Prüfung des RMM-Zugriffsschlüssels + +``` +ID: SwRS-931 +Titel: Zeitkonstante Prüfung des RMM-Zugriffsschlüssels +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: RiverDivoBL (Webservice-Backend) +Vorbedingung: Ein RMM-Aufruf übergibt einen Zugriffsschlüssel; die RMM-Einstellungen sind ladbar. +Fakt: ValidateRmmAccessKey lehnt leere Schlüssel ab, lädt die Einstellungen über RmmConnectionSettingsBL, verlangt IsEnabled == true und nicht-leeren konfigurierten Schlüssel und vergleicht per CryptographicOperations.FixedTimeEquals (Kommentar: verhindert Timing-Leak über die Vergleichsdauer). +Aussage: Das System soll den übertragenen RMM-Zugriffsschlüssel nur bei aktivierter Schnittstelle akzeptieren und den Vergleich mit dem konfigurierten Schlüssel in konstanter Zeit ausführen, sodass aus der Antwortzeit keine Rückschlüsse auf korrekte Schlüsselpräfixe möglich sind. +Ergebnis: false bei deaktivierter Schnittstelle, leerem oder falschem Schlüssel; true nur bei exakter Übereinstimmung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\RiverDivo\RiverDivoBL.cs - Methode ValidateRmmAccessKey: "return CryptographicOperations.FixedTimeEquals(Encoding.UTF8.GetBytes(accessKey), Encoding.UTF8.GetBytes(rmmSettings.AccessKey));" - Begründung: konkrete durchsetzende Prüfung inkl. Bedingungen davor. +Prüfidee: Unit-Test: deaktivierte Schnittstelle → false trotz korrektem Schlüssel; Messung: Antwortzeiten für teilweise korrekte Schlüssel unterscheiden sich nicht signifikant. +Tracelinks: SyRS-911 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Schutzmuster beibehalten, auch wenn das Auth-Verfahren im Zielsystem wechselt. +Status: belegt +``` + +### SwRS-932: Verwaltung der RMM-Einstellungen mit Rechteprüfung und AES-Verschlüsselung + +``` +ID: SwRS-932 +Titel: Verwaltung der RMM-Einstellungen mit Rechteprüfung und AES-Verschlüsselung +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: RmmConnectionSettingsWebServiceBL, RmmConnectionSettingsBL +Vorbedingung: Ein angemeldeter Benutzer ruft die RMM-Einstellungen ab oder speichert sie. +Fakt: Die WebService-BL prüft HasUserRight(...Administration.SETTINGS); die Basis-BL verweigert Speichern mit "An access key is required when the RMM interface is enabled." wenn IsEnabled ohne Schlüssel gesetzt wird, verschlüsselt den Schlüssel per AESCryptoLogic().EncryptText und entschlüsselt beim Lesen. +Aussage: Das System soll die RMM-Einstellungen (Aktiv-Schalter, Zugriffsschlüssel) nur für Benutzer mit Administration.SETTINGS pflegbar machen, das Aktivieren ohne hinterlegten Schlüssel verhindern und den Schlüssel AES-verschlüsselt in den Anwendungseinstellungen speichern. +Ergebnis: Konsistente, verschlüsselt gespeicherte RMM-Konfiguration (ApplicationSettingID.RmmInterfaceEnabled / RmmInterfaceAccessKey). +Belege: + - [PRIMÄR] src\backend\Centron.BL\WebServices\Rmm\RmmConnectionSettingsWebServiceBL.cs - Get/UpdateRmmConnectionSettings: "HasUserRight(loggedInUser.User.I3D, UserRightsConst.Administration.SETTINGS) == false → Fehler" - Begründung: Rechte-Durchsetzung. + - [PRIMÄR] src\backend\Centron.BL\DataExchange\Rmm\RmmConnectionSettingsBL.cs - UpdateRmmConnectionSettings: Pflichtprüfung + "new AESCryptoLogic().EncryptText(accessKey)"; GetRmmConnectionSettings: DecryptText - Begründung: Validierung und Verschlüsselung. +Prüfidee: Speichern mit IsEnabled=true und leerem AccessKey liefert die Fehlermeldung; danach ist die Schnittstelle weiterhin deaktiviert. +Tracelinks: SyRS-912 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - inkl. der Konsistenzregel "aktiv nur mit Schlüssel". +Status: belegt +``` + +### SwRS-933: Ticket-Lebenszyklus über die RMM-Schnittstelle (Anlage, Aktualisierung, bedingtes Schließen) + +``` +ID: SwRS-933 +Titel: Ticket-Lebenszyklus über die RMM-Schnittstelle (Anlage, Aktualisierung, bedingtes Schließen) +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: RiverDivoBL (im Kontext des Centron-Systembenutzers), Helpdesk-Modul +Vorbedingung: Autorisierter RMM-Aufruf; der referenzierte Kunde ist auflösbar. +Fakt: CreateHelpdeskRequest setzt CreatedFrom = 7 ("Riverbird / RMM"), übernimmt Priorität/Typ/Kategorien, ermittelt den Status wahlweise aus AppSettingsConst.HelpdeskAfterOpenDefaultState, besetzt Bearbeiter aus der Helpdesk-Standardabteilung bzw. der verantwortlichen Person, verknüpft optional den Rahmenvertrag (IsGeneralAgreement == 1) und hängt übertragene Dateien in das Ticket-Wurzelverzeichnis; CloseHelpdeskIfUnedited schließt nur, wenn der Ticketstatus dem erwarteten (Default-)Öffnungsstatus entspricht und keine aktiven Timer existieren, sonst Warnung; UpdateHelpdesk aktualisiert die Beschreibung. +Aussage: Das System soll über die RMM-Schnittstelle Tickets mit gekennzeichneter Herkunft und vollständiger Standardbelegung (Status, Bearbeiter, Vertrag, Anhänge) anlegen, Beschreibungen aktualisieren und Tickets automatisch nur dann schließen, wenn sie noch unbearbeitet sind (unveränderter Öffnungsstatus, keine Zeitbuchungen). +Ergebnis: RMM-generierte Tickets sind von manuellen unterscheidbar; bereits bearbeitete Tickets werden nicht automatisch geschlossen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\RiverDivo\RiverDivoBL.cs - CreateHelpdeskRequest: "helpdesk.CreatedFrom = 7; // 7 = Riverbird / RMM", Statusermittlung über AppSettingsConst.HelpdeskAfterOpenDefaultState, Vertragszuordnung "FirstOrDefault(x => x.IsGeneralAgreement == 1)" - Begründung: Anlagelogik. + - [PRIMÄR] src\backend\Centron.BL\RiverDivo\RiverDivoBL.cs - CloseHelpdeskIfUnedited: Statusvergleich gegen checkVsStateI3D und "if (helpdeskTimes.Any()) ... it won't be closed automatically" - Begründung: Schutzbedingungen beim automatischen Schließen. +Prüfidee: Ein RMM-Ticket, auf dem ein Timer gebucht wurde, wird durch close-if-unedited nicht geschlossen (Warnung); ein unberührtes Ticket wird geschlossen. +Tracelinks: SyRS-911, SyRS-913 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Regeln sichern Datenqualität im Helpdesk; Herkunftscode 7 als Enum statt Magic Number neu umsetzen. +Status: belegt +``` + +### SwRS-934: Bidirektionales Kundennummern-Mapping zwischen c-entron und Riverbird + +``` +ID: SwRS-934 +Titel: Bidirektionales Kundennummern-Mapping zwischen c-entron und Riverbird +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: RiverDivoBL, Datenbanktabelle Kunden +Vorbedingung: Kundendatensätze können eine abweichende Riverbird-Referenz tragen. +Fakt: GetCentronCustomerI3D sucht Kunden mit RiverbirdCustomerReference == übergebener Riverbird-ID und fällt auf die übergebene ID zurück, wenn kein Mapping existiert; GetRiverbirdCustomerReference übersetzt umgekehrt; ausgehende DTOs (GetHelpdeskByI3D, GetTicketPatterns) ersetzen CustomerI3D durch die Riverbird-Referenz. +Aussage: Das System soll Kunden-IDs an der RMM-Schnittstelle in beide Richtungen über das persistierte Feld Kunden.RiverbirdCustomerReference übersetzen und ohne hinterlegtes Mapping die ID unverändert durchreichen. +Ergebnis: Beide Systeme adressieren denselben Kunden trotz unterschiedlicher Nummernkreise. +Belege: + - [PRIMÄR] src\backend\Centron.BL\RiverDivo\RiverDivoBL.cs - Methoden GetCentronCustomerI3D / GetRiverbirdCustomerReference (Query().Where(f => f.RiverbirdCustomerReference == divoCustomerI3D)) - Begründung: Übersetzungslogik. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql - Tabelle Kunden, Spalte [RiverbirdCustomerReference] [int] NULL - Begründung: persistiertes Mappingfeld. +Prüfidee: Für einen Kunden mit gesetzter Riverbird-Referenz liefert GetHelpdeskByI3D die Riverbird-ID als CustomerI3D; ohne Referenz die c-entron-ID. +Tracelinks: SyRS-913 +Konsolidierung: Kandidat: Spezialspalte RiverbirdCustomerReference vs. generische ObjectExternalReference (siehe SyRS-913). +Übernahmewürdigkeit: übernehmen - fachlich nötig; technisch in den generischen Referenzmechanismus überführen. Fallback "ID unverändert durchreichen" kritisch prüfen (verdeckt fehlende Mappings). +Status: belegt +``` + +### SwRS-935: Delta-Kundensynchronisation mit Logo-Abgleich für RMM-Systeme + +``` +ID: SwRS-935 +Titel: Delta-Kundensynchronisation mit Logo-Abgleich für RMM-Systeme +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: RiverDivoBL, Named Query RiverDivo.GetAllCustomersForSync +Vorbedingung: Autorisierter RMM-Aufruf von customers/sync. +Fakt: GetAllCustomersForSync akzeptiert ein Änderungsdatum (Default 01.01.1980 = Vollabgleich), liest per Named Query Kunden inkl. Standardadresse, Ansprechpartnern (erste nicht-leere E-Mail/Telefonnummer aus mehreren Feldern), IsDeleted-Kennzeichen und LogoHash; GetCustomerLogoForSync liefert das Default-Logo als Byte-Array separat. +Aussage: Das System soll RMM-Systemen eine Kundensynchronisation anbieten, die wahlweise nur seit einem Stichtag geänderte Kunden liefert, gelöschte Kunden kennzeichnet und Logo-Änderungen über einen Hash erkennbar macht, sodass Logodaten nur bei Änderung übertragen werden müssen. +Ergebnis: Das RMM-System erhält einen konsistenten, delta-fähigen Kundenbestand mit Kontaktpersonen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\RiverDivo\RiverDivoBL.cs - GetAllCustomersForSync (NamedQueryEnums.RiverDivo.GetAllCustomersForSync, Parameter ChangedAfterDate; Felder LogoHash, IsDeleted) und GetCustomerLogoForSync (LogosBL, OnlyDefault = true) - Begründung: implementierter Sync-Ablauf. + - [SEKUNDÄR] src\webservice\Centron.Controllers\Controllers\v1\Integrations\RmmController.cs - Endpunkte POST customers/sync und GET customers/{customerNumber}/logo - Begründung: Schnittstellenvertrag. +Prüfidee: Aufruf mit ChangedAfterDate = gestern liefert nur seither geänderte Kunden; nach Logowechsel ändert sich der LogoHash und der Logo-Endpunkt liefert die neuen Bytes. +Tracelinks: SyRS-911 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Delta- und Hash-Mechanik ist effizient und direkt übertragbar. +Status: belegt +``` + +### SwRS-936: Idempotente Übernahme von DocBee-Zeitbuchungen mit Abrechnungssteuerung + +``` +ID: SwRS-936 +Titel: Idempotente Übernahme von DocBee-Zeitbuchungen mit Abrechnungssteuerung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: DocBeeTicketTimerBL, Helpdesk-Timer-Modul +Vorbedingung: Autorisierter Aufruf mit DocBee-Zeitbuchung (DTO mit ReferenceNumber, ExternalId, Zeiten, EmployeeI3D). +Fakt: SaveDocBeeTicketTimer validiert Pflichtfelder (ReferenceNumber, ExternalId, StartTime/EndTime mit EndTime > StartTime, EmployeeI3D; bei DistanceInKm > 0 zusätzlich existierender ArticleI3D), findet vorhandene Timer über die ExternalId (Update statt Neuanlage), löscht bei Status "Cancelled" den Timer, setzt timer.Calculable nur bei Status "Billable", bildet abweichende abrechenbare Zeit über LunchTime = Timer − BillableTimeInSeconds ab und behandelt Fahrten (DistanceInKm) als reine Distanzposition (Timer = 0, Artikelzuordnung über Timer-Typ mit WithAddressSpecialArticle); alles in einer Transaktion mit Rollback im Fehlerfall; fehlt das Ticket, wird es automatisch angelegt und per ObjectExternalReference verknüpft. +Aussage: Das System soll DocBee-Zeitbuchungen validiert, transaktional und idempotent (Schlüssel: externe ID) übernehmen, den Abrechnungsstatus aus dem DocBee-Status ableiten (nur "Billable" ist kalkulierbar, "Cancelled" löscht), Differenzen zwischen Ist- und abrechenbarer Zeit als Pausenzeit abbilden und Fahrtaufwände über einen Reiseartikel statt über Zeit abrechnen. +Ergebnis: Pro externer Buchung existiert genau ein Helpdesk-Timer mit korrektem Abrechnungskennzeichen; das Ergebnis meldet TicketCreated/TimerAction. +Belege: + - [PRIMÄR] src\backend\Centron.BL\DataExchange\Connectors\DocBeeTicketTimerBL.cs - SaveDocBeeTicketTimer (Validierungen, GetHelpdeskTimerByExternalId, MapStatusToBillingState) und SetHelpdeskTimerProperties: "timer.Calculable = docBeeTicketStatus == StateEnum.Billable;", "timer.LunchTime = timer.Timer - dto.BillableTimeInSeconds.Value;" - Begründung: durchsetzende Abrechnungslogik mit konkreten Bedingungen. +Prüfidee: Dieselbe ExternalId zweimal senden → ein Timer (zweiter Aufruf "Updated"); Status "Cancelled" auf existierenden Timer → Timer gelöscht; Status "Reserved" → Calculable = false. +Tracelinks: SyRS-913, SyRS-912 +Konsolidierung: Kandidat (vermutet): Zeitübernahme aus TANSS (src\backend\Centron.BL\DataExchange\TanssInterfaces\TanssBL.cs) bildet vermutlich dieselbe fachliche Funktion "externe Zeitbuchung → Helpdesk-Timer" ab. +Übernahmewürdigkeit: übernehmen - abrechnungskritische Kernlogik; die LunchTime-Zweckentfremdung für Zeitdifferenzen ist ein Workaround und im Zielsystem durch ein eigenes Feld zu ersetzen. +Status: belegt +``` + +### SwRS-937: Aktivierung und Konfiguration des DocBee-Konnektors (Lizenz, Konfigschalter, Vorlagen-Sync) + +``` +ID: SwRS-937 +Titel: Aktivierung und Konfiguration des DocBee-Konnektors (Lizenz, Konfigschalter, Vorlagen-Sync) +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: DocBeeTicketCreationBL, DocBeeTicketTemplateWebServiceBL, LicenseManager +Vorbedingung: DocBee-Konnektor soll Tickets per Webhook anlegen bzw. Vorlagen synchronisieren. +Fakt: IsDocBeeActive verlangt config.IsOrderTicketCreationActive UND LicenseManager.Instance.HasLicense(LicenseGuids.ExternalAppDocBee); der Vorlagen-Sync verweigert ohne UserRightsConst.Administration.SETTINGS mit MessageCode RightCheckFailed (Controller antwortet Forbid()); die Konnektor-Konfiguration (WebHook-URL, Template-Id, Queue-Id, Ticket-URL) liegt in ApplicationSettingIDs. +Aussage: Das System soll DocBee-Funktionen nur bei aktiviertem Konfigurationsschalter und vorhandener Lizenz ausführen und die Pflege der DocBee-Konfiguration/Vorlagen auf Benutzer mit dem Recht Administration.SETTINGS beschränken. +Ergebnis: Ohne Lizenz oder Recht keine DocBee-Webhooks bzw. keine Konfigurationsänderung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\DataExchange\Connectors\DocBeeTicketCreationBL.cs - IsDocBeeActive: "config.IsOrderTicketCreationActive && LicenseManager.Instance.HasLicense(LicenseGuids.ExternalAppDocBee)" - Begründung: Lizenz- und Aktivierungsprüfung. + - [PRIMÄR] src\backend\Centron.BL\WebServices\DataExchange\Connectors\DocBeeTicketTemplateWebServiceBL.cs - SyncTemplates: "!currentUser.User.HasUserRight(UserRightsConst.Administration.SETTINGS) → Result ... RightCheckFailed" - Begründung: Rechteprüfung Vorlagen-Sync. + - [SEKUNDÄR] src\webservice\Centron.Controllers\Controllers\v1\DataExchange\DocBeeTicketTemplatesController.cs - Mapping RightCheckFailed → Forbid() - Begründung: HTTP-Durchsetzung. +Prüfidee: Ohne DocBee-Lizenz liefert IsDocBeeActive false und es wird kein Webhook gesendet; Vorlagen-Sync mit Benutzer ohne SETTINGS-Recht liefert HTTP 403. +Tracelinks: SyRS-912 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Feature-Gating über Lizenz und Recht entspricht dem SaaS-Zielbild (Feature-Flags/Entitlements). +Status: belegt +``` + +### SwRS-938: Verwaltung der docuFORM-API-Zugangsdaten mit Masterkey-Verschlüsselung + +``` +ID: SwRS-938 +Titel: Verwaltung der docuFORM-API-Zugangsdaten mit Masterkey-Verschlüsselung +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: DocuFormApiSettingsBL, CentronConfigurationDbBL +Vorbedingung: Angemeldeter Benutzer liest oder speichert die docuFORM-API-Einstellungen. +Fakt: Get- und UpdateDocuFormApiSettings prüfen HasUserRight(...Administration.SETTINGS); ClientId, ClientSecret und CurrentRefreshToken werden mit AESCryptoLogic und einem aus der Konfigurations-DB geladenen Masterkey (GetHotlineMasterKey) ver-/entschlüsselt; fehlt der Masterkey, wird mit "No master key found" abgebrochen. +Aussage: Das System soll docuFORM-Zugangsdaten (Client-Id, Client-Secret, Refresh-Token) nur für Benutzer mit Administration.SETTINGS zugreifbar machen und sie mit einem zentral verwalteten Masterkey AES-verschlüsselt speichern; ohne verfügbaren Masterkey soll die Operation fehlschlagen. +Ergebnis: Keine Klartext-Credentials in den Anwendungseinstellungen; Zugriff nur für berechtigte Administratoren. +Belege: + - [PRIMÄR] src\backend\Centron.BL\DataExchange\DocuForm\DocuFormApiSettingsBL.cs - GetDocuFormApiSettings/UpdateDocuFormApiSettings: Rechteprüfung "HasUserRight(loggedInUser.User.I3D, UserRightsConst.Administration.SETTINGS) == false" und "new AESCryptoLogic().EncryptText(..., securityKey)"; GetSecurityKey → GetHotlineMasterKey - Begründung: durchsetzende Prüfung + Verschlüsselung. + - [SEKUNDÄR] src\webservice\Centron.Controllers\Controllers\v1\DataExchange\DocuFormApiSettingsController.cs - [AuthorizeUserRight(UserRightsConst.Administration.SETTINGS)] auf PUT api-settings - Begründung: HTTP-seitige Rechtebindung (GET stützt sich auf die BL-Prüfung). +Prüfidee: GET api-settings mit Benutzer ohne SETTINGS-Recht liefert Fehler; in der Settings-Tabelle steht das Client-Secret nicht im Klartext. +Tracelinks: SyRS-912, SyRS-914 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Muster (Recht + Masterkey-Verschlüsselung) in zentralen Secret-Store überführen. +Status: belegt +``` + +### SwRS-939: Gerätezähler-Import von docuFORM mit automatischem Token-Handling + +``` +ID: SwRS-939 +Titel: Gerätezähler-Import von docuFORM mit automatischem Token-Handling +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: DocuFormApiImportViewModel (Modul Finances/DeviceClickCounter), DocuFormRestApiClient +Vorbedingung: docuFORM-Einstellungen sind vollständig (Server-Adresse, Client-Id, Client-Secret); andernfalls bietet der Dialog das Öffnen der Einstellungen an. +Fakt: DownloadDeviceCounters holt zuerst ein Token (gültiges Token wiederverwenden → Refresh-Token → interaktiver Auth-Code-Dialog, Scope "server_read"), lädt dann alle Geräte (GetAllDevices) und je Gerät die Zählerstände (GetDeviceCounters, optional zu einem Stichtag), protokolliert Fortschritt/Fehler je Gerät und ist durch den Benutzer abbrechbar; CheckApiSettings meldet fehlende Konfigurationsfelder namentlich. +Aussage: Das System soll Seitenzählerstände aller docuFORM-Geräte — wahlweise zu einem Stichtag — automatisiert abrufen, sich dabei selbstständig um gültige Tokens kümmern und Fehler je Gerät protokollieren, ohne den Gesamtimport abzubrechen. +Ergebnis: Liste der Geräte mit Zählerständen für die Übernahme in den Klickzähler (Abrechnungsgrundlage). +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\Finances\DeviceClickCounter\DocuFormApiImport\DocuFormApiImportViewModel.cs - DownloadDeviceCounters, GetAuthToken (Reihenfolge Cache → RequestAuthTokenByRefreshToken → RequestAuthTokenByAuthCodeDialog), GetDeviceCounter mit try/catch je Gerät - Begründung: implementierter Importablauf. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\DataExchange\DocuForm\Authorization\DocuFormTokenHelper.cs - CheckApiSettings mit Dialog "Die Konfiguration der docuFORM Schnittstelle ist unvollständig..." - Begründung: Vorbedingungsprüfung. +Prüfidee: Import mit einem nicht erreichbaren Gerät: übrige Geräte werden geladen, das fehlerhafte erscheint im Log; Abbruch-Button stoppt nach dem aktuellen Gerät. +Tracelinks: SyRS-914 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - im Zielsystem als serverseitiger, zeitgesteuerter Job statt interaktivem Client-Dialog. +Status: belegt +``` + +### SwRS-940: Datenmodell und Filterung der Telekom-D!VE-Profile + +``` +ID: SwRS-940 +Titel: Datenmodell und Filterung der Telekom-D!VE-Profile +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: TelekomDiveBL, Entität TelekomDiveProfile +Vorbedingung: Profile werden über die Einstellungen gepflegt bzw. vom Exportdialog abgefragt. +Fakt: TelekomDiveProfile enthält u. a. ProfileName, MandatorI3D, BranchI3D, OfferRecipient, Rahmenvertragsdaten (BasedOnFrameContract, FrameContractNumber), PartnerVatId/PartnerCreditorId, feste Zahlungs-/Rabatt-/USt-Vorgaben (UseFixedPaymentDeadline/-PosDiscount/-VAT), Verweise auf ReceiptOffer-CustomProperties und IsVisible sowie Audit-Felder; SaveTelekomDiveProfiles setzt bei Neuanlage CreatedDate/CreatedByEmployeeI3D, bei jeder Änderung ChangedDate/ChangedByEmployeeI3D; GetTelekomDiveProfiles filtert nach IsVisible, MandatorI3D und BranchI3D. +Aussage: Das System soll Exportvorgaben für den D!VE-Export als mandanten-/filialbezogene Profile mit Sichtbarkeitskennzeichen und Änderungsnachweis (wer/wann) persistieren und gefiltert bereitstellen. +Ergebnis: Wiederverwendbare, nachvollziehbar gepflegte Exportprofile je Mandant/Filiale. +Belege: + - [PRIMÄR] src\backend\Centron.Entities\Entities\DataExchange\TelekomDive\TelekomDiveProfile.cs - Property-Liste inkl. Audit-Felder - Begründung: Datenmodell. + - [PRIMÄR] src\backend\Centron.BL\DataExchange\TelekomDive\TelekomDiveBL.cs - SaveTelekomDiveProfiles (CreatedDate/ChangedDate-Setzung) und BuildFilterExpression (IsVisible/MandatorI3D/BranchI3D) - Begründung: durchgesetzte Persistenz- und Filterlogik. +Prüfidee: Neu gespeichertes Profil trägt CreatedBy/CreatedDate; GET v1/telekom-dive/profiles?isVisible=true liefert unsichtbare Profile nicht. +Tracelinks: SyRS-915 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Profilkonzept ist übertragbar. +Status: belegt +``` + +### SwRS-941: Regeln des Telekom-D!VE-XML-Exports + +``` +ID: SwRS-941 +Titel: Regeln des Telekom-D!VE-XML-Exports +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: TelekomDiveExportViewModel +Vorbedingung: Angebot mit Positionen ist geladen; Profil und Distributor sind gewählt. +Fakt: ExportAndSaveXml bricht ab, wenn einer Position TelekomDiveCategory oder SelectedTelekomDiveUnit fehlt; ExportToXml entfernt für jedes Feld unzulässige Zeichen (RemoveDiveXmlSpecialCharacters) und kürzt auf feldspezifische Maximallängen (z. B. partner_name 100, customer_address_line_1 60, comment 4000); nach dem Speichern wird die Datei per ArchiveExportedTelekomDiveFile am Angebot archiviert. +Aussage: Das System soll den D!VE-Export nur bei vollständiger Positions-Klassifizierung (Kategorie und Einheit je Position) zulassen, alle Feldinhalte auf das vom Zielformat erlaubte Zeichen- und Längenmaß normieren und jede exportierte Datei am Angebot archivieren. +Ergebnis: Formatkonformes XML; der Export ist am Beleg dokumentiert und reproduzierbar. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\TelekomDive\TelekomDiveExportViewModel.cs - ExportAndSaveXml: "if (this.DiveExportData.Any(f => f.TelekomDiveCategory is null))" und "...SelectedTelekomDiveUnit is null" → Abbruch; ExportToXml: ".RemoveDiveXmlSpecialCharacters().Shorten(100)" u. a.; ArchiveExportedTelekomDiveFile - Begründung: konkrete Validierungs- und Normierungsregeln. +Prüfidee: Angebotsposition ohne Einheit → Export verweigert; Feld mit Sonderzeichen/Überlänge erscheint im XML bereinigt und gekürzt. +Tracelinks: SyRS-915 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Regeln entsprechen dem Partnerformat; Grenzwerte bei Neuimplementierung aus der aktuellen D!VE-Spezifikation ableiten. +Status: belegt +``` + +### SwRS-942: Cache der ElectronicSales-Kundengruppen mit Deduplizierung und Soft-Delete + +``` +ID: SwRS-942 +Titel: Cache der ElectronicSales-Kundengruppen mit Deduplizierung und Soft-Delete +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: EsCustomerGroupBL / EsRoleBL, Entität EsCustomerGroup +Vorbedingung: Kundengruppen bzw. Rollen des Webshops ElectronicSales sollen in c-entron referenzierbar sein. +Fakt: Create trimmt die ExternalId, überspringt leere, doppelt gelieferte und bereits vorhandene ExternalIds (HashSet-Vergleich, StringComparer.Ordinal), setzt IsActive = true und Audit-Felder; Delete setzt nur IsActive = false (kein physisches Löschen); GetActive liefert die Dropdown-Menge; der Klassenkommentar nennt die Referenz AccountCustomer.EsCustomerGroupI3D. +Aussage: Das System soll ElectronicSales-Kundengruppen als lokalen Cache mit eindeutiger externer ID führen, Duplikate beim Anlegen stillschweigend überspringen und Gruppen beim Löschen nur deaktivieren, damit bestehende Kundenreferenzen gültig bleiben. +Ergebnis: Konsistenter, referenzsicherer Gruppenkatalog für die Kundenzuordnung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Integrations\EsCustomerGroupBL.cs - Create: "if (string.IsNullOrWhiteSpace(externalId) || !seen.Add(externalId) || existingSet.Contains(externalId)) continue;"; Delete: "group.IsActive = false;" - Begründung: Dedupe- und Soft-Delete-Regeln. + - [SEKUNDÄR] src\backend\Centron.Entities\Entities\Integrations\EsCustomerGroup.cs - Kommentar "Cached ElectronicSales customer group... Referenced by AccountCustomer.EsCustomerGroupI3D." - Begründung: fachlicher Zweck und Referenz. +Prüfidee: Zweimaliges Anlegen derselben ExternalId erzeugt genau einen Datensatz; nach Delete ist die Gruppe inaktiv, aber weiterhin per I3D auflösbar. +Tracelinks: SyRS-913 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Soft-Delete wegen Fremdreferenzen ist korrekt gewählt. +Status: belegt +``` + +### SwRS-943: Konfigurierbare Objektarten für die Dokumentsynchronisation (DocSync) + +``` +ID: SwRS-943 +Titel: Konfigurierbare Objektarten für die Dokumentsynchronisation (DocSync) +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: DocSyncSettingsViewModel (UI), DirectoryBL +Vorbedingung: Administrator öffnet die DocSync-Einstellungen. +Fakt: Die Auswahl aktiver Objektarten wird als ApplicationSettingID.DocSyncActiveCentronObjectKinds gespeichert; IsDocSyncEnabledForObjectKind prüft Contains auf diese Liste; die WebService-BL bereinigt DocSyncName um ungültige Pfadzeichen (TrimInvalidPathCharacters, TrimEnd('-')) und liefert nur Verzeichnisse mit aktiven Objekten. +Aussage: Das System soll je c-entron-Objektart (z. B. Ticket, Kunde) konfigurierbar machen, ob deren Dokumente synchronisiert werden, und Verzeichnisnamen für die Synchronisation dateisystemtauglich bereinigen. +Ergebnis: DocSync überträgt nur Dokumente aktivierter Objektarten unter gültigen Verzeichnisnamen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\FileManagement\DirectoryBL.cs - GetDocSyncSettings/UpdateDocSyncSettings (ApplicationSettingID.DocSyncActiveCentronObjectKinds) und IsDocSyncEnabledForObjectKind (Contains-Prüfung) - Begründung: durchsetzende Konfigurationslogik. + - [PRIMÄR] src\backend\Centron.BL\WebServices\Administration\FileManagements\DirectoryWebServiceBL.cs - "DocSyncName = dir.DocSyncName.TrimInvalidPathCharacters().Trim().TrimEnd('-').Trim()" - Begründung: Namensbereinigung. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\DataExchange\DocSync\DocSyncSettingsViewModel.cs - Load-/SaveSettings über IDirectoryLogic - Begründung: UI-Pflege der Auswahl. +Prüfidee: Nach Aktivierung nur der Objektart "Helpdesk" enthält die DocSync-Verzeichnisliste keine Kundenverzeichnisse; ein Verzeichnisname mit ":" wird bereinigt ausgeliefert. +Tracelinks: SyRS-917 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - selektive Synchronisation bleibt fachlich sinnvoll. +Status: belegt +``` + +### SwRS-944: Validierung des Konten-Datenimports (Pflichtfelder, IBAN-Prüfsumme) + +``` +ID: SwRS-944 +Titel: Validierung des Konten-Datenimports (Pflichtfelder, IBAN-Prüfsumme) +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Import-Assistent (AccountViewModelValidation, IbanValidation) +Vorbedingung: Importdaten (Excel/Datei) sind in die Import-ViewModels geladen. +Fakt: AccountViewModelValidation deklariert Required-Regeln für AccountNumber, Name, AdvertisingNotAllowed, CreatedDate, CreatedByI3D, EmailAddressDataType für Email und eine MatchesRule auf die IBAN; IbanChecksumCheck normalisiert die IBAN (Großschreibung, Leer-/Bindestriche entfernen), stellt die ersten vier Zeichen nach hinten, wandelt Buchstaben in Zahlen (c − 55) und prüft mod 97 == 1; null-IBAN gilt als gültig (optionales Feld). +Aussage: Das System soll importierte Kontodatensätze vor der Übernahme feldweise validieren — Pflichtfelder, E-Mail-Format und die IBAN per ISO-13616-Prüfsummenverfahren (mod 97) — und nur valide Datensätze importieren. +Ergebnis: Fehlerhafte Zeilen werden im Assistenten markiert und nicht übernommen. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\DataExchange\DataImport\AccountImport\AccountViewModelValidation.cs - BuildMetadata mit Required()/EmailAddressDataType()/MatchesRule(iban => iban.IbanChecksumCheck()) - Begründung: deklarierte, vom Framework durchgesetzte Validierungsregeln. + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\DataExchange\DataImport\AccountImport\IbanValidation.cs - IbanChecksumCheck: "return ((d % 97) == 1);" - Begründung: konkreter Prüfalgorithmus. +Prüfidee: Importzeile mit IBAN "DE00 1234..." (falsche Prüfziffer) wird als ungültig markiert; gültige Test-IBAN passiert die Prüfung. +Tracelinks: SyRS-917 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Validierung gehört im Zielsystem serverseitig in die Import-API, nicht nur ins UI. +Status: belegt +``` + +### SwRS-945: Generierung vorbefüllter Nexoware-Smartflow-Links (CPra) + +``` +ID: SwRS-945 +Titel: Generierung vorbefüllter Nexoware-Smartflow-Links (CPra) +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: CPraConnectorBL, Smartflow-/CPra-Dienst (https://c-pra.c-entron.de/restApi) +Vorbedingung: Gültige Smartflow-Zugangsdaten; ein Webhook ist im Dienst definiert. +Fakt: ConnectToCPra meldet sich per Benutzername/Passwort an und erhält ein Bearer-Token; GetCPraWebHooks listet Webhooks; GetCPraWebHookLink ruft generateLink auf und hängt Kontextparameter (KUNDENNUMMER, KUNDENAME, ANSPRECHPARTNERMAILADRESSE, TICKETID, TICKETNUMMER, TICKETTITEL, VMA_ADDRESSE) als Base64-kodiertes JSON ("&i=...") an den Link an; nur befüllte Parameter werden aufgenommen. +Aussage: Das System soll für Smartflow-Formulare Links erzeugen, die den fachlichen Kontext (Kunde, Ansprechpartner, Ticket) als kodierte Parameter mitführen, damit das Formular beim Empfänger vorbefüllt startet. +Ergebnis: Ein versandfertiger Link mit eingebettetem Kontext. +Belege: + - [PRIMÄR] src\backend\Centron.BL\CPra\CPraConnectorBL.cs - GetCPraWebHookLink + GenerateLink: "parametersAsBase64 = Convert.ToBase64String(...); return $"{baseLink}&i={parametersAsBase64}";" - Begründung: implementierte Linkgenerierung mit Parameterliste. +Prüfidee: Für ein Ticket mit Kundennummer erzeugter Link enthält nach Base64-Dekodierung von "i" die Felder KUNDENNUMMER und TICKETNUMMER; leere Felder fehlen. +Tracelinks: SyRS-913 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Funktion beibehalten; fest codierte Basis-URL und Login per Benutzername/Passwort in Konfiguration bzw. tokenbasierte Auth überführen (Workaround-Anteil). +Status: belegt +``` + +### SwRS-946: Einheitlicher Dateiexport-Kontrakt der Gateway-Buchhaltungsadapter + +``` +ID: SwRS-946 +Titel: Einheitlicher Dateiexport-Kontrakt der Gateway-Buchhaltungsadapter +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Centron.Gateway (BookKeepingFileExport und Ableitungen), BookKeepingExportBL +Vorbedingung: Ein FiBu-Export wurde erzeugt und soll als Datei abgelegt werden. +Fakt: Die abstrakte Klasse BookKeepingFileExport definiert je Adapter den ExportTyp (BookKeepingExportTypes) und virtuelle Methoden für Kunden-, Lieferanten- und Belegbuchungsdaten; PrepareStoreFile verweigert die Ablage ohne Datei ("Es wurde keine zu exportierende Datei gefunden...") oder ohne Exportpfad ("Sie haben keinen Exportpfad hinterlegt.") und erlaubt adapterspezifische Dateinamen über AlternativeFilename. +Aussage: Das System soll alle Buchhaltungs-Exportadapter über einen einheitlichen Kontrakt (Exporttyp, Datenliefermethoden, Dateiablage mit Pflichtprüfungen und adapterspezifischer Benennung) implementieren, sodass der Aufrufer formatunabhängig exportieren kann. +Ergebnis: Jeder Adapter liefert seine Exportdatei über denselben Ablauf; Fehlbedienungen (fehlender Pfad/Datei) werden mit verständlicher Meldung abgefangen. +Belege: + - [PRIMÄR] src\backend\Centron.Gateway\DataExchange\BookKeeping\BookKeepingFileExport.cs - "public abstract BookKeepingExportTypes ExportTyp"; PrepareStoreFile mit den zitierten Fehlermeldungen; abstract GetBytesFromFile; virtual AlternativeFilename - Begründung: Kontrakt und Prüfungen im Code. + - [SEKUNDÄR] src\backend\Centron.Gateway\DataExchange\BookKeeping\IBookKeepingExport.cs sowie Adapterklassen (DatevAscii, Abacus, SageOfficeLine, SAP, Navision u. a.) - Begründung: Vielzahl der Implementierungen desselben Kontrakts. +Prüfidee: Export ohne hinterlegten Exportpfad liefert die Meldung "Sie haben keinen Exportpfad hinterlegt."; zwei Adapter erzeugen über denselben Aufrufpfad unterschiedliche Dateien. +Tracelinks: SyRS-916 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kontraktprinzip übernehmen; Dateiablage im SaaS durch Download/Übertragungsdienst ersetzen. +Status: belegt +``` + +### SwRS-947: [HYPOTHESE] Berechtigungsschutz für die Pflege von Integrationsstammdaten (D!VE-Profile, ES-Kundengruppen) + +``` +ID: SwRS-947 +Titel: [HYPOTHESE] Berechtigungsschutz für die Pflege von Integrationsstammdaten (D!VE-Profile, ES-Kundengruppen) +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: TelekomDiveController, EsCustomerGroupsController / EsRolesController +Vorbedingung: Ein authentifizierter Benutzer ruft die Pflege-Endpunkte auf. +Fakt: POST v1/telekom-dive/profiles sowie POST/PUT/DELETE v1/integrations/es-customergroups tragen — anders als die RMM-/docuFORM-Einstellungscontroller — kein [AuthorizeUserRight]-Attribut, und in TelekomDiveBL/EsCustomerGroupBL wurde keine HasUserRight-Prüfung gefunden; die Aufrufe verwenden lediglich User.GetCurrent() zur Autorenzuordnung. +Aussage: Das System soll die Pflege von Telekom-D!VE-Profilen und ES-Kundengruppen auf entsprechend berechtigte Benutzer beschränken. [HYPOTHESE] +Ergebnis: Änderungen an Integrationsstammdaten nur durch berechtigte Benutzer. +Belege: + - [SEKUNDÄR] src\webservice\Centron.Controllers\Controllers\v1\DataExchange\TelekomDiveController.cs - SaveProfiles ohne AuthorizeUserRight-Attribut - Begründung: Abwesenheit einer endpunktbezogenen Rechteprüfung (Negativbefund). + - [SEKUNDÄR] src\webservice\Centron.Controllers\Controllers\v1\Integrations\EsCustomerGroupsController.cs - Create/Update/Delete ohne Rechteprüfung, nur User.GetCurrent()?.UserI3D - Begründung: Negativbefund analog. +Prüfidee: Klären, ob eine globale Authentifizierungs-/Autorisierungs-Middleware (Centron.Host) diese Routen absichert; danach Testaufruf mit minimal berechtigtem Benutzer. +Tracelinks: SyRS-912 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - im Zielsystem sind dedizierte Rechte für Integrations-Stammdaten vorzusehen, unabhängig davon, wie es heute gelöst ist. +Status: HYPOTHESE +Offene Frage: Greift für v1/telekom-dive und v1/integrations/es-* eine globale Autorisierung (z. B. Authentifizierungspflicht in Centron.Host/Middleware) oder genügt heute jede gültige Anmeldung für Schreibzugriffe? +``` + +## A10 — SwRS (Produktion, Projekte, PLM, QM, Statistik, Reporting) + +### SwRS-1030: Statusmodell und typisierte Änderungsprotokolle für Produktionsschritte + +``` +ID: SwRS-1030 +Titel: Statusmodell und typisierte Änderungsprotokolle für Produktionsschritte +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente Centron.BusinessLogic.Production, Enum-Definitionen Centron.Interfaces.Production +Vorbedingung: Produktionsauftrag mit Arbeitsschritten existiert +Fakt: ProductionOrderItemState definiert Finished=0 ("Beendet"), OpenNotStarted=1 ("Offen"), InProgression=2 ("In Bearbeitung"); ein vierter Zustand (WaitingForOtherPartsToFinish=3) ist auskommentiert; ProductionOrderLogKind definiert 26 Logarten (0–25) von ProductionOrderCreated bis ProductionOrderItemWeightInKg, u. a. StepStarted, StepCompletion, ProductionOrderItemStateChanged, ProductionOrderItemProducedAmountChanged. +Aussage: Das System soll je Produktionsschritt genau einen der Zustände Offen, In Bearbeitung oder Beendet führen und jede fachliche Änderung an Auftrag oder Schritt (Status, Mengen, Maschine, Mitarbeiter, Termine, Maße, Kommentare) als Logeintrag mit typisierter Änderungsart speichern. +Ergebnis: Auswertbare Statusverteilung und lückenlose, nach Änderungsart filterbare Historie. +Belege: + - [PRIMÄR] src\backend\Centron.Interfaces\Production\ProductionOrderItemState.cs, Enum-Werte Finished=0/OpenNotStarted=1/InProgression=2 - Begründung: verbindliches Statusmodell. + - [PRIMÄR] src\backend\Centron.Interfaces\Production\ProductionOrderLogKind.cs, 26 Enum-Werte mit deutschen Descriptions - Begründung: vollständiger Katalog der protokollierten Änderungsarten. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, ProductionOrderItems.[State] int NOT NULL; ProductionOrderLogs.[Kind] int NOT NULL - Begründung: DB erzwingt Status- und Logart-Pflege. +Prüfidee: Statuswechsel Offen→In Bearbeitung erzeugt Log mit Kind=20 (ProductionOrderItemStateChanged); ungültiger Statuswert wird von der Persistenz abgewiesen. +Tracelinks: SyRS-1010, SyRS-1011 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - schlankes Statusmodell; den auskommentierten Wartezustand im Neudesign fachlich klären. +Status: belegt +``` + +### SwRS-1031: Maschinenstammdaten mit Arten, Arbeitsschrittbeschreibungen und Standorthierarchie + +``` +ID: SwRS-1031 +Titel: Maschinenstammdaten mit Arten, Arbeitsschrittbeschreibungen und Standorthierarchie +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente ProductionBL, Modul MachineManagement +Vorbedingung: Produktionslizenz vorhanden +Fakt: ProductionBL verwaltet ProductionMachine (mit ProductionMachineKind und ProductionMachineLocation), ProductionMachineKind mit zugeordneten ProductionMachineKindStepsDescription (Arbeitsschritt-Vorlagen je Maschinenart) und ProductionMachineLocation mit ParentProductionMachineLocationI3D (Hierarchie) und Fullname-Suche. +Aussage: Das System soll Maschinen mit Maschinenart und Standort führen, je Maschinenart wiederverwendbare Arbeitsschrittbeschreibungen pflegen und Standorte hierarchisch (Eltern-Kind) organisieren. +Ergebnis: Produktionsschritte können über die Maschinenart auf vordefinierte Arbeitsschritte zugreifen; Maschinen sind nach Standortbaum filterbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Production\ProductionBL.cs, SaveProductionMachineKindStepsDescription / GetProductionMachineKindStepsDescriptionByFilter (Filter MachineKindI3Ds) und CreateFilterExpression(ProductionMachineLocationFilter) mit `f.ParentProductionMachineLocationI3D == filter.ParentProductionMachineLocationI3D` - Begründung: implementierte Struktur inkl. Hierarchiefilter. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\Production\Settings (MachineKind, MachineLocation) und ...\Production\MachineManagement\MaschineManagementViewModel.cs - Begründung: Pflege-UI der Stammdaten. +Prüfidee: Anlage einer Maschinenart mit zwei Schrittbeschreibungen; neuer Produktionsschritt dieser Art bietet beide Beschreibungen an; Standortfilter auf Elternknoten liefert Maschinen der Unterstandorte nicht implizit (nur direkte Zuordnung). +Tracelinks: SyRS-1010, SyRS-1011 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Standard-Stammdatenmodell. +Status: belegt +``` + +### SwRS-1032: Projektboard hart auf Abteilung "Software-Entwicklung" zugeschnitten + +``` +ID: SwRS-1032 +Titel: Projektboard hart auf Abteilung "Software-Entwicklung" zugeschnitten +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Modul ProjectManagement (WPF) +Vorbedingung: Modul wird geöffnet; Abteilung "Software-Entwicklung" existiert im Personalstamm +Fakt: RefreshEmployeeWorkload wählt Mitarbeiter über `CentronCache.Instance.EmployeeDepartments.First(f => f.Name == "Software-Entwicklung")` und filtert die Kürzel "DEV", "TFSUS", "TFS" aus; DoLoadEmployeeSpecialAppointments führt ein fest codiertes SQL auf Terminplanung mit `abt.Name = 'Software-Entwicklung'` und Textmustern 'Urlaub%', 'Feiertag%', '%(c-Time)' über die ReportEngine-Query-Schnittstelle aus. +Aussage: Das System soll die Projekt-/Auslastungsübersicht für ein konfigurierbares Team bereitstellen; in der Ist-Implementierung ist das Team fest auf die interne Abteilung "Software-Entwicklung" codiert. +Ergebnis: Board zeigt ausschließlich Auslastung und Abwesenheiten dieser einen Abteilung. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\ProjectManagement\ProjectManagementViewModel.cs, RefreshEmployeeWorkload: `.First(f => f.Name == "Software-Entwicklung")` und ShortSign-Ausschlussliste - Begründung: hart codierte Teamauswahl. + - [PRIMÄR] ebd., DoLoadEmployeeSpecialAppointments: SQL-String mit `AND abt.Name = 'Software-Entwicklung'` - Begründung: zweite hart codierte Stelle. +Prüfidee: Öffnen des Moduls in einer Umgebung ohne Abteilung "Software-Entwicklung" führt zu Fehler/leerer Auslastung; Review bestätigt, dass kein Konfigurationsparameter existiert. +Tracelinks: SyRS-1019 +Konsolidierung: nein +Übernahmewürdigkeit: Sonderfall - internes Werkzeug des Herstellers; fachliches Konzept übernehmen, Abteilungs-/Terminlogik konfigurierbar neu implementieren. +Status: belegt +``` + +### SwRS-1033: Excel-Projektpreisimport mit Herstellercode-Zuordnung und Differenzanzeige + +``` +ID: SwRS-1033 +Titel: Excel-Projektpreisimport mit Herstellercode-Zuordnung und Differenzanzeige +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Modul ProjectPriceImport (WPF), Sonderpreisvereinbarungs-Verwaltung +Vorbedingung: Excel-/CSV-Preisliste eines Herstellers geladen; Ziel-Sonderpreisvereinbarung (SpecialAgreement) gewählt oder neu angelegt +Fakt: Der Import prüft Zellen auf numerische Preise ("Zellinhalt ist nicht numerisch"), verlangt eindeutige Herstellercodes ("Kein Herstellercode gefunden", "Herstellercode mehrfach vorhanden", "Mehr als einen Artikel mit HerstellerCode ... gefunden"), sammelt alle Verstöße in einer Fehlerliste mit Zeilenangabe und berechnet vor Übernahme je Artikel die Differenz `NewValue.Price - OldValue.SpecialAgreementEK`; ein Schwellwertfilter (UseFilter/FilterValue) ist vorhanden. +Aussage: Das System soll Herstellerpreislisten dateibasiert in Sonderpreisvereinbarungen importieren, dabei jede Zeile über den Herstellercode eindeutig einem Artikel zuordnen, nicht zuordenbare oder nicht numerische Zeilen mit Zeilenbezug ausweisen und dem Anwender vor Übernahme die Preisdifferenzen je Artikel anzeigen. +Ergebnis: Aktualisierte Sonderpreise mit vorheriger Differenz-Kontrolle; fehlerhafte Zeilen werden nicht übernommen, sondern gelistet. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\ProjectPriceImport\ProjectPriceImportViewModel.cs, Fehlerlisten-Erzeugung (Zeilen 414–893, u. a. "Zellinhalt ist nicht numerisch: {row[projectPriceIndex].Value}") - Begründung: durchgesetzte Zeilenvalidierung. + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\ProjectPriceImport\PriceDifference\SpecialAgreementDifferenceViewModel.cs, CalculateDifference: `Difference = NewValue.Price - OldValue.SpecialAgreementEK` - Begründung: Differenzberechnung vor Übernahme. +Prüfidee: Import einer Datei mit einem Textwert in der Preisspalte und einem doppelten Herstellercode: beide Zeilen erscheinen mit Zeilennummer in der Fehlerliste, die übrigen Zeilen zeigen ihre EK-Differenz. +Tracelinks: SyRS-1015 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Preislistenimport ist Standardbedarf; Validierungslogik gehört im Zielbild in die Serverschicht statt ins UI. +Status: belegt +``` + +### SwRS-1034: ProductLifecycleInformation-Import mit Deduplizierung und Barcode-Mengenregel + +``` +ID: SwRS-1034 +Titel: ProductLifecycleInformation-Import mit Deduplizierung und Barcode-Mengenregel +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente ProductFamilyBL (PLM-Import) +Vorbedingung: Rechnungspositionen mit Lizenz-/Aboartikeln; Produktfamilienzuordnung vorhanden +Fakt: ImportProductLifecycleInformations überspringt Datensätze, wenn bereits ein Eintrag mit gleichem SourceI3D, SourceType und BarcodeI3D existiert; bei Positionen mit Barcode wird Quantity auf 1 gesetzt (je Barcode eine Lizenz); ungültige Datumswerte (0001-01-01) werden auf NULL normalisiert; bei Rechnungsbezug wird der Ansprechpartner (AccountAddressContactI3D) aus der Rechnung ermittelt; die Tabelle ProductLifecycleInformations hält u. a. AccountI3D/AccountName NOT NULL, Quantity/Price/SumPrice NOT NULL, StartDate/EndDate, IsDeactivated, IsOfferSent, LicenseKey. +Aussage: Das System soll Lebenszyklusdatensätze idempotent aus Quellbelegen übernehmen (kein Duplikat je Quelle+Barcode), barcode-genaue Lizenzen mit Menge 1 führen, ungültige Datumsangaben neutralisieren und je Datensatz Kunde, Rechnung, Artikel, Laufzeit und Angebotsstatus speichern. +Ergebnis: Saubere, duplikatfreie Lizenzliste als Basis für Renewals und Auswertungen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Warehousing\ArticleManagement\ProductFamilyBL.cs, ImportProductLifecycleInformations: Existenz-Query `f.SourceI3D == item.SourceI3D && f.SourceType == item.SourceType && f.BarcodeI3D == item.BarcodeI3D` mit `continue`; `item.Quantity = isBarcodeItem ? 1 : item.Quantity`; DateTimeUtils.IsNullOrInvalid-Normalisierung - Begründung: durchgesetzte Import-Regeln. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE ProductLifecycleInformations (AccountI3D/AccountName NOT NULL, Quantity decimal(9,2) NOT NULL, IsDeactivated bit NOT NULL, IsOfferSent bit NOT NULL) - Begründung: Datenmodell mit Pflichtfeldern. +Prüfidee: Zweifacher Import derselben Rechnungsposition erzeugt genau einen Datensatz; Position mit Barcode und Menge 5 wird als Menge 1 gespeichert. +Tracelinks: SyRS-1018 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Regeln sind fachlich begründet und dokumentiert im Code. +Status: belegt +``` + +### SwRS-1035: PLM-Wiedervorlage über Toleranzfrist und abweichenden Bearbeiter + +``` +ID: SwRS-1035 +Titel: PLM-Wiedervorlage über Toleranzfrist und abweichenden Bearbeiter +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponenten ProductFamilyBL, ToDoBL, ProductLifecycleBL (Settings) +Vorbedingung: PLM-Einstellungen gepflegt (DaysToTolerate, ggf. DifferentSelectedEmployee) +Fakt: Beim Import und beim Speichern von Lebenszyklusdaten werden ToDo-Einträge nur für Rechnungs-Quellen (ProductLifecycleInformationSource.Invoice) erzeugt, deren Datum in der Toleranzfrist `DateTime.Now.AddDays(-plmSettings.DaysToTolerate)` liegt; RecalculatePLMToDoEntries gleicht alle aktiven, nicht deaktivierten Einträge mit EndDate in der Frist erneut ab (optional nur Simulation via applyChanges); UserForPLM ersetzt den auslösenden Benutzer durch den konfigurierten Mitarbeiter, wenn ShouldDifferentEmployeeBeSelected/-ForAllLicenses gesetzt ist. +Aussage: Das System soll Wiedervorlagen für ablaufende Lizenzen ausschließlich innerhalb einer konfigurierbaren Toleranzfrist erzeugen, eine Neuberechnung des Wiedervorlagebestands (mit Vorschau-Modus) anbieten und die Wiedervorlagen wahlweise einem fest konfigurierten Mitarbeiter statt dem auslösenden Benutzer zuordnen. +Ergebnis: Wiedervorlagen landen beim richtigen Bearbeiter; Altfälle außerhalb der Frist erzeugen keine ToDos. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Warehousing\ArticleManagement\ProductFamilyBL.cs, SaveProductLifecycleInformations: `if(item.SourceType == (int)ProductLifecycleInformationSource.Invoice && item.EndDate >= DateTime.Now.AddDays(-plmSettings.DaysToTolerate)) new ToDoBL(this.Session).HandlePLMToDoEntries(item, plmUser)`; UserForPLM - Begründung: durchgesetzte Fristen- und Zuständigkeitslogik. + - [SEKUNDÄR] src\backend\Centron.BL\Finances\ProductLifecycleBL.cs, AppSettingsConst.DaysToTolerate / DifferentSelectedEmployee / ShouldDifferentEmployeeBeUsedForAllLicenses - Begründung: Konfigurationsquellen. +Prüfidee: DaysToTolerate=30: Eintrag mit EndDate vor 40 Tagen erzeugt kein ToDo, mit EndDate vor 10 Tagen eines; bei aktivierter Stellvertreterregel ist das ToDo dem konfigurierten Mitarbeiter zugewiesen. +Tracelinks: SyRS-1018 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kernregel des Renewal-Prozesses. +Status: belegt +``` + +### SwRS-1036: QM-Rückgabegründe je Belegart mit Benachrichtigungsmodus + +``` +ID: SwRS-1036 +Titel: QM-Rückgabegründe je Belegart mit Benachrichtigungsmodus +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente AssetReasonBL, QM-Einstellungsmodul +Vorbedingung: QM-Einstellungen geöffnet +Fakt: AssetReason speichert je Belegart (AssetType) ReasonText, IsMandatory und Status; die QM-Einstellungen pflegen für sieben Belegarten (SupplierOrder, SupplierCreditVoucher, SupplierDeliveryList, SupplierInvoice, PickupList, CreditVoucher, DeliveryList) je eine Grundliste plus den Benachrichtigungsmodus QmNotification (Never=0 "keine", AskUser=1 "Nachfrage", Always=2 "immer") als AppSetting (QmMessageConfirmationPopup*); das UI setzt den Modus auf Never zurück, wenn kein aktiver Grund (Status==1) existiert. +Aussage: Das System soll je Belegart einen Katalog von Rückgabe-/Reklamationsgründen mit Pflichtkennzeichen pflegen und einen dreistufigen Benachrichtigungsmodus (keine/Nachfrage/immer) speichern, der nur wählbar ist, wenn mindestens ein aktiver Grund existiert. +Ergebnis: Konsistente QM-Konfiguration; Belegprozesse (SyRS-1016) greifen auf gültige Gründe zu. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\CustomerAssets\Reason\AssetReasonBL.cs, SaveReceiptReasons: Zuweisung AssetType/IsMandatory/Status/ReasonText und SaveOrUpdate - Begründung: Persistenzregeln des Katalogs. + - [PRIMÄR] src\backend\Centron.Interfaces\QM\Enums\QmNotification.cs, Enum Never/AskUser/Always mit Descriptions - Begründung: dreistufiger Modus. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\QM\Settings\AssetReasonSettingsViewModel.cs, Setter QmNotification: Rücksetzen auf Never ohne aktiven Grund; AppSettingsConst.QMMessageConfirmationPopup* je Belegart - Begründung: UI-Invariante und Settings-Schlüssel. +Prüfidee: Modus "immer" ohne aktive Gründe wählen: UI setzt auf "keine" zurück; nach Anlegen eines aktiven Grundes ist "immer" wählbar und wird als AppSetting gespeichert. +Tracelinks: SyRS-1016 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - klare Konfigurationslogik. +Status: belegt +``` + +### SwRS-1037: Verkaufsstatistik: Rechteprüfung, Filiallimitierung, Web-Account-Schutz und Artikellimit + +``` +ID: SwRS-1037 +Titel: Verkaufsstatistik: Rechteprüfung, Filiallimitierung, Web-Account-Schutz und Artikellimit +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente SaleStatisticBL +Vorbedingung: Statistikanfrage mit Filter (Zeitraum, Artikel, Warengruppen, Kunden) +Fakt: GetSalesArticleStatistic (1) liefert Web-Accounts nur Daten, wenn exakt der eigene CustomerI3D gefiltert wird, sonst leere Liste; (2) verlangt SALES_STATISTIC (20800005) oder — nur bei Einzelkundenfilter — SHOW_CRM_ARTICLES; (3) überschreibt bei SHOW_ONLY_STATISTIC_FROM_OWN_BRANCH (20800145) den Filialfilter mit der Filiale des Benutzers; (4) lehnt Filter mit mehr als 2000 Artikeln ab; die Daten stammen aus der vorverdichteten Tabelle CacheSalesStatistic(Item). +Aussage: Das System soll Verkaufsstatistiken nur nach erfolgreicher Rechteprüfung liefern, Filial- und Kundensichtbarkeit serverseitig erzwingen, überbreite Abfragen (>2000 Artikel) ablehnen und Statistiken aus einer Verdichtungstabelle statt aus Belegdaten beantworten. +Ergebnis: Performante Statistik ohne Umgehungsmöglichkeit der Sichtbarkeitsregeln über Filterparameter. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Statistics\SaleStatistics\SaleStatisticBL.cs, GetSalesArticleStatistic: Web-Account-Check, Rechte-Check mit AsError(RightCheckFailed), Zwangsfilter BranchI3Ds, `if (filter.ArticleI3Ds?.Count > 2000) return ...AsError(...)`, Query auf CacheSalesStatisticsItem - Begründung: alle vier Regeln in der durchsetzenden Methode. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE CacheSalesStatistic - Begründung: Verdichtungstabelle existiert im Schema. +Prüfidee: Aufruf als Web-Account mit fremdem CustomerI3D liefert leere Liste; Aufruf mit 2001 ArtikelI3Ds liefert Fehler; Benutzer mit Own-Branch-Recht erhält trotz leerem Filialfilter nur die eigene Filiale. +Tracelinks: SyRS-1012 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - serverseitige Durchsetzung ist das richtige Muster für SaaS. +Status: belegt +``` + +### SwRS-1038: Management-Info-Kennzahlen mit Filialbeschränkung je Kennzahl + +``` +ID: SwRS-1038 +Titel: Management-Info-Kennzahlen mit Filialbeschränkung je Kennzahl +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente ManagementInfoBL, Modul Statistics\ManagementInfo +Vorbedingung: Benutzer öffnet Management-Info-Dashboard +Fakt: ManagementInfoBL stellt Kennzahlen bereit (Auftragsbestand, Deckungsbeitrag, Lieferrückstand, offene Posten, Mitarbeiterzahl, Produktionskennzahlen, Umsatz-/Angebotsverläufe) und ersetzt in jeder dieser Methoden bei Vorliegen des Rechts MANAGEMENT_INFO_ONLY_OWN_BRANCH (20800039) die übergebene Filialliste durch die eigene Filiale; CacheSalesStatisticsBL.GetAll verlangt zusätzlich MANAGEMENT_INFO (10972) und blockiert Web-Accounts. +Aussage: Das System soll Management-Kennzahlen nur an Benutzer mit Management-Info-Recht liefern und für filialbeschränkte Benutzer jede einzelne Kennzahl serverseitig auf die eigene Filiale begrenzen. +Ergebnis: Kennzahlen ohne Datenabfluss über Filialgrenzen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Statistics\Sales\ManagementInfo\ManagementInfoBL.cs, u. a. GetSalesOrderBacklog/GetOpenPosts/GetEmployeeCount: `if (currentUser.HasUserRight(UserRightsConst.Controlling.Finances.MANAGEMENT_INFO_ONLY_OWN_BRANCH)) { branchI3DList = ... }` - Begründung: Beschränkung je Kennzahlmethode. + - [PRIMÄR] src\backend\Centron.BL\Statistics\SaleStatistics\CacheSalesStatisticsBL.cs, GetAll: MANAGEMENT_INFO-Prüfung und `if (!loggedInUser.IsCentronUserLogin) return AsError("Web-Accounts are not allowed!")` - Begründung: Zugriffsschutz auf die Rohliste. +Prüfidee: Benutzer mit Only-Own-Branch-Recht fordert Kennzahlen aller Filialen an und erhält nur Werte seiner Filiale; Web-Account erhält beim Rohdatenabruf einen Fehler. +Tracelinks: SyRS-1012 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Muster für mandanten-/filialgetrennte Kennzahlen. +Status: belegt +``` + +### SwRS-1039: MSP-Import: Lieferantenschemata, Duplikatschutz und verschlüsselte Zugangsdaten + +``` +ID: SwRS-1039 +Titel: MSP-Import: Lieferantenschemata, Duplikatschutz und verschlüsselte Zugangsdaten +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Komponente MspCollectorsBL +Vorbedingung: MspCollector mit MspSupplierID (Schema), DownloadType und ggf. UseAuthentication konfiguriert +Fakt: MspDowloadStart verarbeitet je Schema unterschiedlich (Octopus/Veeam: Lizenz-Schreiblogik mit Pflicht-Importdatum; ArrowSphere: Kundenabgleich + Reportladen; sonst FTP/FTPS-Download); vor erneutem Veeam/Octopus-Import desselben Monats (InvoiceDate = Monatsultimo) wird eine Ersetzen-Warnung zurückgegeben; Passwörter werden mit AESCryptoLogic().DecryptText entschlüsselt und die Entität anschließend per Session.Evict vom Persistenzkontext getrennt; Beginn und Ende jedes Imports werden über WriteLOG/WriteImportEndLog mit Zählern (Rechnungen, Positionen, importiert) protokolliert. +Aussage: Das System soll MSP-Abrechnungsdaten je Lieferant über schemaspezifische Adapter importieren, Mehrfachimporte derselben Abrechnungsperiode nur nach expliziter Ersetzen-Bestätigung zulassen, Zugangsdaten verschlüsselt speichern und jeden Importlauf mit Mengenzählern protokollieren. +Ergebnis: Nachvollziehbare, duplikatfreie Importläufe pro Lieferant und Periode. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Statistics\MspCollectors\MspCollectorsBL.cs, MspDowloadStart: Duplikat-Query auf MspCollectorInvoiceHead mit `InvoiceDate == new DateTime(...,1).AddMonths(1).AddDays(-1)` und Rückgabe AsWarning("Report wurde schon importiert. Möchten Sie diesen ersetzen?"); `collector.Password = new AESCryptoLogic().DecryptText(collector.Password)` - Begründung: durchsetzende Duplikat- und Credential-Logik. + - [SEKUNDÄR] src\backend\Centron.BL\Statistics\MspCollectors\MspSuppliersSchema.cs, Schema-Enum (Veeam, Octopus, ArrowSphere, ...) - Begründung: Adapterkatalog. +Prüfidee: Zweiter Octopus-Import desselben Monats ohne WithReplace liefert die Ersetzen-Warnung; Importlog enthält Start- und Endeintrag mit Zählern. +Tracelinks: SyRS-1017 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Adapter- und Periodenschutzlogik; Credential-Handling im Zielbild auf Secret-Store umstellen. +Status: belegt +``` + +### SwRS-1040: MSP-Evaluation: Entscheidungsgesteuerte Vertragsanpassung mit Historie und Origin-Entkopplung + +``` +ID: SwRS-1040 +Titel: MSP-Evaluation: Entscheidungsgesteuerte Vertragsanpassung mit Historie und Origin-Entkopplung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente MspCollectorsBL (Evaluation), Vertragsabrechnung +Vorbedingung: MSP-Rechnungspositionen sind über Kunden-/Artikelreferenzen Verträgen zugeordnet; MSP-Modul-Lizenz vorhanden +Fakt: UpdateMspContractItem setzt je nach MspEvaluationDecision (ChangeQuantity, ChangePrice, ChangePriceAndQunatity, IgnoreImport) QuantityComplete und/oder PurchaseBasePrice der Vertragsposition, passt Stücklisten-Unterpositionen proportional an (AdjustQuantityForPartListItems), setzt bei Mengenänderung DetachedFromOrigin=true für Positionen mit Ursprungsauftrag (Ticket 168245: verhindert Blockade bzw. Wiederöffnung des Ursprungsauftrags), speichert die Entscheidung an der Rechnungsposition, erzeugt einen MspEvaluationHistory-Eintrag (mit Alt-/Neumengen, Mitarbeiter, Entscheidungscode) und schreibt bei Preisänderung einen Preis-Logeintrag; GetMspCollectorInvoiceHeads liefert ohne LicenseGuids.MspModule eine leere Liste. +Aussage: Das System soll je abweichender MSP-Rechnungsposition eine der Entscheidungen "Menge übernehmen", "Preis übernehmen", "beides übernehmen" oder "ignorieren" umsetzen, dabei Vertragspositionen von ihrem Ursprungsauftrag entkoppeln, Stücklistenmengen konsistent nachziehen und jede Entscheidung dauerhaft historisieren. +Ergebnis: Abrechnungsrelevante Vertragsdaten konsistent zum Lieferantenverbrauch; vollständiger Audit-Trail. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Statistics\MspCollectors\MspCollectorsBL.cs, UpdateMspContractItem (switch über MspEvaluationDecision; DetachContractItemsFromOrigin; CreateMspEvaluationHistoryEntry; CreatePurchasePriceUpdatedEntry) - Begründung: vollständige durchsetzende Logik. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE MspEvaluationHistory (MspQuantity, ContractQuantity, LastInvoiceQuantity, MspEvaluationDecision, EmployeeI3D) - Begründung: Historienschema. +Prüfidee: Entscheidung ChangeQuantity auf Position mit OriginReceiptItemI3D: Menge geändert, DetachedFromOrigin=true, Historieneintrag mit alter und neuer Menge vorhanden; IgnoreImport ändert den Vertrag nicht, markiert aber die Rechnungsposition. +Tracelinks: SyRS-1017 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - inkl. der dokumentierten Origin-Entkopplung (Tickets 168245/164153) als bewusste Fachregel. +Status: belegt +``` + +### SwRS-1041: ReportEngine-Abfrageausführung mit textueller Variablenersetzung + +``` +ID: SwRS-1041 +Titel: ReportEngine-Abfrageausführung mit textueller Variablenersetzung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente ReportDataBL.ExecuteQuery, Report-Designer +Vorbedingung: Report-Datenquelle mit SQL-Statement und :Variablen definiert; Aufrufer hat SQL_MANAGER/REPORT_MANAGEMENT (SyRS-1014) +Fakt: ExecuteQuery ersetzt per Regex `:[0-9a-zA-Z_]+` jede Variable durch den Wert der übergebenen DataRow — als String in einfache Anführungszeichen gesetzt ('wert') bzw. NULL bei Leerwert — und führt das Ergebnis über NativeSqlDAO.ExecuteQuery aus; eine Parametrisierung (SqlParameter) findet nicht statt; leere Statements werden abgelehnt. +Aussage: Das System soll in Report-SQL-Statements benannte :Variablen zur Laufzeit durch Kontextwerte ersetzen und die Abfrage gegen die Datenbank ausführen; die Ist-Implementierung tut dies per Textersetzung ohne Parametrisierung. +Ergebnis: Kontextabhängige Reportdaten; zugleich SQL-Injection-Risiko über Variablenwerte und freie Statements. +Belege: + - [PRIMÄR] src\backend\Centron.BL\ReportEngine\ReportDataBL.cs, ExecuteQuery(string, DataRow, DataTable): `Regex(@":[0-9a-zA-Z_]+")`, `value = "'" + value + "'"; statement = statement.Replace(param, value)`, danach `Session.GetDAO().ExecuteQuery(finalQuery, true)` - Begründung: durchsetzende Ersetzungs- und Ausführungslogik. +Prüfidee: Statement mit :KundenNr und Zeilenwert `x' OR '1'='1` belegt das Injektionsrisiko; Soll-Test der Neuimplementierung: Wert wird als Parameter gebunden, Injektion wirkungslos. +Tracelinks: SyRS-1013, SyRS-1014 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - Funktion (Variablen in Reportabfragen) übernehmen, Umsetzung zwingend auf parametrisierte Abfragen umstellen. +Status: belegt +``` + +### SwRS-1042: Reportvorlagen-Datenhaltung: FastReport-XML, Schleifenprüfung und Legacy-Parallelbestand + +``` +ID: SwRS-1042 +Titel: Reportvorlagen-Datenhaltung: FastReport-XML, Schleifenprüfung und Legacy-Parallelbestand +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponenten ReportDataBL, ReportsBL +Vorbedingung: Reportvorlagen vorhanden +Fakt: ReportData speichert FastReport-Definitionen als UTF-8-XML im image-Feld Report (NOT NULL) mit Name (NOT NULL), State und Mandantenbezug; ReportDataQuery-Hierarchien werden vor Ausführung per HasQueryLoop auf Zyklen geprüft (SuperQuery-Kette); parallel existiert die Alt-Tabelle dbo.Reports (deutsche Spalten: Gruppe, Schacht, PDFVerzeichnis, Herkunft, ...) mit eigener BL (ReportsBL: CentronReport, ReportsSqlStatements, GetRawSqlResult) — zwei Datenhaltungen für denselben Gegenstand "druckbarer Bericht". +Aussage: Das System soll Berichtsvorlagen samt Abfragehierarchie persistent verwalten und zyklische Abfrageabhängigkeiten vor der Ausführung erkennen; der Berichtsbestand soll in einer einzigen Datenhaltung konsolidiert werden. +Ergebnis: Ladbare, zyklenfreie Reportdefinitionen; Zielbild ohne Doppelbestand. +Belege: + - [PRIMÄR] src\backend\Centron.BL\ReportEngine\ReportDataBL.cs, HasQueryLoop (Zyklenerkennung über SuperQuery) und GetReportFromData (FastReport.Report.FromString) - Begründung: durchgesetzte Konsistenz- und Ladelogik. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE ReportData ([Report] image NOT NULL) und CREATE TABLE Reports ([Report] image NULL, Spalten Gruppe/Schacht/PDFVerzeichnis) - Begründung: beide Datenhaltungen nachweisbar. + - [SEKUNDÄR] src\backend\Centron.BL\Reporting\ReportsBL.cs, CentronReport/ReportsSqlStatements - Begründung: aktiver Code auf dem Altbestand. +Prüfidee: Reportdefinition mit zyklischer SuperQuery-Kette wird von HasQueryLoop erkannt; Inventur beider Tabellen zeigt, welche Berichte nur im Altbestand existieren. +Tracelinks: SyRS-1013 +Konsolidierung: Kandidat: dbo.Reports/ReportsBL (Alt) vs. dbo.ReportData/ReportDataBL (ReportEngine) — zwei Implementierungen für Berichte. +Übernahmewürdigkeit: übernehmen (ReportData-Strang); Altbestand dbo.Reports: veraltet - durch ReportEngine abgelöst, im Zielsystem migrieren. +Status: belegt +``` + +### SwRS-1043: Reportserver: automatisierter Reportversand per E-Mail über Aufgaben [HYPOTHESE] + +``` +ID: SwRS-1043 +Titel: Reportserver: automatisierter Reportversand per E-Mail über Aufgaben [HYPOTHESE] +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Modul Administration\ReportServer, Task-Management-Dienst +Vorbedingung: Reportserver-Aufgabe mit Report, Empfänger und Zeitplan konfiguriert +Fakt: Das Reportserver-Modul beschreibt sich als "Automatisiert E-Mails mit Reports an Kunden verschicken."; der ReportServerConnector bedient Aufgaben (GetTasks/SaveTask), Reports je Gruppe (GetReportsFromGroup), Kundenkontakte, Ausführungshistorie (GetTaskHistory) und einen Sofort-Test (TestTaskNow) über Webservice-Aufrufe; die eigentliche zeitgesteuerte Ausführung liegt außerhalb des analysierten UI-Codes. +Aussage: Das System soll zeitgesteuerte Aufgaben verwalten, die definierte Reports rendern und per E-Mail an Kundenkontakte versenden, inklusive Ausführungshistorie und manuellem Testlauf. +Ergebnis: Wiederkehrender Reportversand ohne manuelles Zutun; Historie je Aufgabe. +Belege: + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\Administration\ReportServer\ReportServerAppModuleController.cs, Description = "Automatisiert E-Mails mit Reports an Kunden verschicken." - Begründung: fachliche Zweckbeschreibung im UI. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\Administration\ReportServer\ReportServerConnector.cs, GetTasks/SaveTask/GetTaskHistory/TestTaskNow/GetReportsFromGroup/GetCustomerContactPersons - Begründung: vollständige Aufgaben-API des Moduls. +Prüfidee: Aufgabe mit Report und Empfänger anlegen, TestTaskNow auslösen und E-Mail-Eingang sowie Historieneintrag prüfen. +Tracelinks: SyRS-1013 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - geplanter Berichtsversand ist ein gefragtes SaaS-Feature. +Status: HYPOTHESE +Offene Frage: Wo (welcher Dienst/Serverprozess) führt die geplanten Aufgaben aus und mit welcher Render-/Mail-Logik — der ausführende Code wurde im Cluster nicht gefunden. +``` + +### SwRS-1044: Beleg-Massenpreisupdate: Aktiv-Prüfung, Belegartregeln, Währung und Stücklistenkopf + +``` +ID: SwRS-1044 +Titel: Beleg-Massenpreisupdate: Aktiv-Prüfung, Belegartregeln, Währung und Stücklistenkopf +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente MassUpdateBL.StartReceiptPriceUpdate +Vorbedingung: Massenupdate-Vorlage mit Belegpositionen und Preiseinstellungen (UpdateVkForReceipt/UpdateEkForReceipt) vorhanden +Fakt: Je Item wird der Beleg geladen und nur bei ReceiptState.Active geändert (sonst FailureMessage "Beleg ist nicht aktiv."); Verkaufspreise werden bei Rechnungen und Gutschriften nicht geändert; bei CurrencyFactor != 1 wird der neue Preis durch den Faktor geteilt; bei Positionen mit Einrückung (Stücklisten) wird die Preisdifferenz mengengewichtet auf die Kopfposition hochgerechnet bzw. der Kopf-EK aus allen direkten Kindern neu berechnet; jede Änderung erzeugt einen ReceiptLog-Eintrag der Art DataUpdater mit Alt-/Neupreis und Währung; das Speichern erfolgt mit IgnoreCallbacks und Fehlerübernahme in item.FailureMessage. +Aussage: Das System soll Massenpreisänderungen an Belegen nur auf aktive Belege anwenden, Verkaufspreisänderungen an bereits fakturierten Belegarten (Rechnung, Gutschrift) ausschließen, Fremdwährungspreise über den Belegkurs umrechnen, Stücklistenkopfpreise konsistent aus den Kindpositionen ableiten und jede Preisänderung im Beleglog dokumentieren. +Ergebnis: Konsistente Belegpreise ohne nachträgliche Manipulation fakturierter Werte; Fehler je Beleg statt Gesamtabbruch. +Belege: + - [PRIMÄR] src\backend\Centron.BL\MassUpdate\MassUpdateBL.cs, StartReceiptPriceUpdate: `if (receipt.State is ReceiptState.Active)` / else `item.FailureMessage = "Beleg ist nicht aktiv."`; `if (item.ObjectKind != CentronObjectKindNumeric.InvoiceClass && item.ObjectKind != CentronObjectKindNumeric.CreditVoucherClass)`; `if (receipt.CurrencyFactor != 1) item.NewBasePrice /= receipt.CurrencyFactor`; Stücklisten-Neuberechnung der Kopf-EKs; ReceiptLogKind.DataUpdater-Eintrag - Begründung: alle Regeln in der durchsetzenden Methode. +Prüfidee: Vorlage mit Angebot (aktiv), Rechnung und storniertem Auftrag: nur das Angebot wird geändert; Rechnung bleibt beim VK unverändert; Stücklistenkind-Preisänderung verändert den Kopfpreis mengengewichtet; Beleglog enthält Alt→Neu-Text. +Tracelinks: SyRS-1015 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - abrechnungsrelevante Schutzregeln; Kopfpreis-Neuberechnung (Kommentar zu früherem +=-Fehler) als Lehre dokumentieren. +Status: belegt +``` + +### SwRS-1045: Artikel- und Kontenmassenupdate mit fachspezifischen Logs + +``` +ID: SwRS-1045 +Titel: Artikel- und Kontenmassenupdate mit fachspezifischen Logs +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente MassUpdateBL (StartArticlePriceUpdate, StartAccountDataUpdate) +Vorbedingung: Vorlage mit Artikel- bzw. Kontenitems und neuen Werten +Fakt: StartArticlePriceUpdate übernimmt je Artikel nur die gesetzten neuen Werte (PurchasePrice, EVP, Price1–4; sonst Altwert), speichert über ArticleBL.SaveArticle und schreibt einen ArticleLog der Art Bulkchanger ("Anpassung durch Bulkchanger {Caption}"); StartAccountDataUpdate ändert Betreuerzuordnungen (Adviser1–4) mit Alt/Neu-Kürzeln im Logtext; fehlgeschlagene Items behalten IsExecuted=false mit FailureMessage; nach vollständiger Ausführung wird die Vorlage inaktiv und mit Ausführer/Zeitpunkt versehen. +Aussage: Das System soll bei Artikel- und Kontenmassenupdates nur explizit belegte Felder ändern, jede Änderung im objektspezifischen Log (Artikellog "Bulkchanger", Kontenlog mit Alt/Neu-Bearbeiter) dokumentieren und Vorlagen erst nach vollständiger Ausführung abschließen. +Ergebnis: Teiländerungen ohne Nebenwirkungen auf nicht gewählte Felder; Objektlogs zeigen die Massenherkunft der Änderung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\MassUpdate\MassUpdateBL.cs, StartArticlePriceUpdate: `article.Price1 = item.NewPrice1.HasValue ? (double)item.NewPrice1.Value : article.Price1`; `_articleLogBL.WriteLog(..., ArticleLogKind.Bulkchanger, ...)`; Abschlusslogik IsActive=false/IsExecuted=true - Begründung: durchsetzende Feld- und Loglogik. + - [PRIMÄR] ebd., StartAccountDataUpdate: Adviser1–4-Änderung mit ShortSign-Alt/Neu und Logtext "Bearbeiter n geändert" - Begründung: Kontenvariante. +Prüfidee: Vorlage, die nur Price2 setzt: Price1/3/4 und EK bleiben unverändert; Artikellog enthält Bulkchanger-Eintrag mit Vorlagen-Caption. +Tracelinks: SyRS-1015 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Standard-Massenpflege. +Status: belegt +``` + +### SwRS-1046: Dashboard-Modulübersicht mit Suche, Favoriten und Gruppierung + +``` +ID: SwRS-1046 +Titel: Dashboard-Modulübersicht mit Suche, Favoriten und Gruppierung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Modul Dashboard (ModulesSlideView), Endanwender +Vorbedingung: Benutzer öffnet das Dashboard +Fakt: ModulesSlideViewModel hält alle verfügbaren Module in einer CollectionView, gruppiert und sortiert nach GroupName/ModuleName, filtert live über ModuleSearchText und bietet einen Nur-Favoriten-Filter (ShowOnlyFavorites). +Aussage: Das System soll dem Anwender eine zentrale, nach Kategorien gruppierte Modulübersicht mit Textsuche und persönlicher Favoritenfilterung als Einstiegspunkt anbieten. +Ergebnis: Schneller Modulzugriff; Favoriten reduzieren die Ansicht auf persönlich relevante Module. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\Dashboard\Modules\ModulesSlideViewModel.cs, GroupDescriptions/SortDescriptions auf GroupName/ModuleName, Setter ModuleSearchText/ShowOnlyFavorites mit ModulesView.Refresh() - Begründung: implementiertes Such-/Filter-/Gruppierverhalten. +Prüfidee: Suchtext filtert die Modulkacheln live; aktivierter Favoritenfilter zeigt ausschließlich als Favorit markierte Module. +Tracelinks: SyRS-1012 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - als Navigations-/Startseite der Web-Anwendung. +Status: belegt +``` + +### SwRS-1047: DocuBoard-Zuordnungen: Löschschutz bei Vertragsverwendung, Partner und AD-Ausschlüsse + +``` +ID: SwRS-1047 +Titel: DocuBoard-Zuordnungen: Löschschutz bei Vertragsverwendung, Partner und AD-Ausschlüsse +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponenten AssetManagementArticleAssignmentBL, AssetManagementPartnerBL, AssetManagementADSystemUserExclusionBL +Vorbedingung: Asset-Management-/DocuBoard-Daten vorhanden +Fakt: DeleteAssetManagementArticleAssignment prüft vor dem Löschen über ContractArticleReferenzesBL, ob die Artikelzuweisung noch in einem Vertrag referenziert wird, und bricht mit der Meldung "Die Zuweisung für {Typ} konnte nicht gelöscht werden, da sie noch in einem Vertrag verwendet wird." ab; AssetManagementPartnerBL verwaltet Partner je Kunde mit Positionsliste; AssetManagementADSystemUserExclusionBL pflegt eine Ausschlussliste von AD-Systembenutzern. +Aussage: Das System soll Zuordnungen zwischen Asset-Arten und Abrechnungsartikeln nur löschen lassen, wenn kein Vertrag sie mehr referenziert, und daneben Kundenpartner sowie auszuschließende AD-Systembenutzer als Stammlisten führen. +Ergebnis: Keine verwaisten Vertragsreferenzen; gepflegte Partner- und Ausschlusslisten für die Asset-Dokumentation. +Belege: + - [PRIMÄR] src\backend\Centron.BL\DocuBoard\AssetManagementArticleAssignmentBL.cs, DeleteAssetManagementArticleAssignment: `if (contractArticleReferenzes.Select(f => f.ArticleAssignment.I3D).Contains(deleteItem.I3D)) return Result.AsError("Die Zuweisung ... noch in einem Vertrag verwendet wird.")` - Begründung: durchgesetzter referenzieller Löschschutz. + - [SEKUNDÄR] src\backend\Centron.BL\DocuBoard\AssetManagementPartnerBL.cs (SavePartner mit Items) und AssetManagementADSystemUserExclusionBL.cs (CRUD der Ausschlussliste) - Begründung: weitere Stammlisten des Moduls. +Prüfidee: Löschversuch einer in einem Vertrag verwendeten Artikelzuweisung liefert die Fehlermeldung; nach Entfernen der Vertragsreferenz gelingt das Löschen. +Tracelinks: SyRS-1017 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Löschschutz sichert die Vertragsabrechnung. +Status: belegt +``` + +## A11 — Plattform & Querschnitt: SwRS + +### SwRS-1130: Transaktionsverwaltung mit Zähler und automatischem Rollback + +``` +ID: SwRS-1130 +Titel: Transaktionsverwaltung mit Zähler und automatischem Rollback +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: Zuverlässigkeit +Akteur: Centron.DAO.DAOSession (Komponente) +Vorbedingung: BL-Code führt Datenänderungen innerhalb von DAOSession.WithTransaction aus; Transaktionen können geschachtelt sein. +Fakt: DAOSession zählt Transaktionen (_transactionCount): StartTransaction eröffnet nur bei Zähler 1 eine NHibernate-Transaktion, CommitTransaction committet erst beim äußersten Aufruf und wirft eine Exception, wenn die ADO-Transaktion bereits beendet ist; RollbackTransaction setzt den Zähler auf 0 und rollt die gesamte umgebende Transaktion zurück; WithTransaction(Func) rollt bei ResultStatus != Success oder Exception automatisch zurück; Dispose rollt offene Transaktionen zurück und disposed die ISession. +Aussage: Das System soll geschachtelte fachliche Transaktionen auf genau eine Datenbanktransaktion abbilden, bei fachlichem Fehlschlag (Result-Fehler) oder Ausnahme automatisch zurückrollen und offene Transaktionen beim Schließen der Sitzung verwerfen statt zu committen. +Ergebnis: Keine teilcommitteten Datenänderungen; Doppel-Commit wird mit Exception erkannt. +Belege: + - [PRIMÄR] src\backend\Centron.DAO\DAOSession.cs, StartTransaction/CommitTransaction/RollbackTransaction (_transactionCount-Logik, throw "The transaction has already ended.") - Begründung: durchsetzende Transaktionsmechanik. + - [PRIMÄR] ebd., WithTransaction(Func) (Rollback bei result.Status != Success) und Dispose (Rollback bei _transactionCount > 0) - Begründung: automatische Fehlerpfade. +Prüfidee: Unit-Test: geschachteltes WithTransaction mit innerem Fehler-Result → keine der Änderungen persistiert; doppelter Commit wirft Exception. +Tracelinks: SyRS-1110, SyRS-1111 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Muster (Unit-of-Work mit automatischem Rollback auf Fehler-Result) ist technologieneutral übertragbar. +Status: belegt +``` + +### SwRS-1131: Entitätsidentität über den technischen Schlüssel I3D + +``` +ID: SwRS-1131 +Titel: Entitätsidentität über den technischen Schlüssel I3D +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Centron.Entities.PersistedEntity (Basisklasse aller Entitäten) +Vorbedingung: Zwei Entitätsinstanzen (ggf. NHibernate-Proxys) werden verglichen. +Fakt: PersistedEntity überlädt ==/!=/Equals: gleiche Typen (Proxy-BaseType wird normalisiert) gelten als gleich, wenn beide ein I3D > 0 besitzen und die I3D-Werte übereinstimmen; bei I3D <= 0 (ungespeichert) fällt der Vergleich auf Referenzgleichheit zurück; GetHashCode nutzt ebenfalls die I3D-Property per Reflection. +Aussage: Das System soll persistierte Objekte fachlich über ihren Datenbankschlüssel I3D identifizieren, sodass zwei geladene Instanzen desselben Datensatzes (auch als ORM-Proxy) als identisch gelten, ungespeicherte Objekte jedoch nur mit sich selbst. +Ergebnis: Konsistente Gleichheit in Collections/Bindings unabhängig vom Ladeweg. +Belege: + - [PRIMÄR] src\backend\Centron.Entities\PersistedEntity.cs, operator == (PropertyInfo "I3D", intObj1I3D == intObj2I3D; Proxy-Behandlung obj2Type.BaseType == obj1Type) - Begründung: durchsetzende Identitätsregel. +Prüfidee: Dieselbe Entität zweimal laden (einmal als Proxy) → Equals liefert true; zwei neue ungespeicherte Instanzen → false. +Tracelinks: SyRS-1111 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - ID-basierte Gleichheit ist Standard; Reflection-basierte Umsetzung durch typisierte Basisklasse ersetzen. +Status: belegt +``` + +### SwRS-1132: Zentrale NHibernate-Ereignis-Listener-Kette der Persistenzschicht + +``` +ID: SwRS-1132 +Titel: Zentrale NHibernate-Ereignis-Listener-Kette der Persistenzschicht +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: Wartbarkeit +Akteur: Centron.DAO.DAOFactory (Konfiguration) / NHibernate-SessionFactory +Vorbedingung: DAOFactory.InitializeAsync konfiguriert Fluent NHibernate (MsSql2008, DefaultSchema dbo, Mappings aus Assembly von BaseMaps). +Fakt: DAOFactory registriert PreUpdate-Listener (ChangeTrackingEventListener, WhyIsMyEntityUpdatedEventListener, TruncateStringsEventListener, StringOrBinaryDataWouldBeTruncatedEventListener), PreInsert-Listener (TruncateStrings, StringOrBinaryData) und Post-Listener (LogHourlySurchargeRateChangesListener für Update/Insert/Delete); TruncateStringsEventListener kürzt Strings von Properties mit TruncatedStringUserType vor dem Schreiben auf die Mapping-Länge. +Aussage: Das System soll Querschnittsregeln der Persistenz (Änderungsprotokoll, Stringkürzung auf Spaltenlänge, Diagnose unerwarteter Updates, fachliche Speziallogs) zentral als ORM-Ereignis-Listener registrieren, damit sie für alle Entitäten ohne Einzelcode gelten. +Ergebnis: Überlange Strings erzeugen keinen SQL-Fehler, sondern werden deterministisch gekürzt; Querschnittslogik ist an einer Stelle konfiguriert. +Belege: + - [PRIMÄR] src\backend\Centron.DAO\DAOFactory.cs:100-127 (f.AppendListeners(ListenerType.PreUpdate/PreInsert/PostUpdate/PostInsert/PostDelete, ...)) - Begründung: zentrale Registrierungsstelle. + - [PRIMÄR] src\backend\Centron.DAO\TruncateStringsEventListener.cs, TruncateStringsIfNeeded (value.Substring(0, truncatedStringUserType.Length)) - Begründung: durchgesetzte Kürzungsregel. +Prüfidee: Entität mit überlangem String speichern → Wert wird auf Mapping-Länge gekürzt persistiert, kein "String or binary data would be truncated"-Fehler. +Tracelinks: SyRS-1111, SyRS-1115 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - stilles Kürzen von Benutzereingaben verhindert Fehler, verschluckt aber Daten; Neuimplementierung sollte stattdessen validieren und ablehnen. +Status: belegt +``` + +### SwRS-1133: Attributgesteuertes Feld-ChangeTracking (aktuell ohne Nutzer) + +``` +ID: SwRS-1133 +Titel: Attributgesteuertes Feld-ChangeTracking (aktuell ohne Nutzer) +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Centron.DAO.ChangeTracking.ChangeTrackingEventListener +Vorbedingung: Entitätsklasse trägt [ChangeTrackingConfiguration(objectKind)], Properties tragen [TrackChanges]; Benutzer ist im LoggedInUserManager gesetzt. +Fakt: Der Listener prüft per Reflection auf ChangeTrackingConfigurationAttribute/TrackChangesAttribute (gecacht in ConcurrentDictionary), vergleicht Alt-/Neuwerte, kürzt Werte auf 4000 Zeichen (Shorten(4000)) und speichert ChangeLog in einer separaten Session; ohne gesetzten AppUser oder ohne int-Id wird mit Logger.Warn übersprungen, Exceptions werden gefangen und vetoen das Update nie (return false). Eine Repo-weite Suche findet KEINE Entität, die die Attribute verwendet — der Mechanismus ist registriert, aber wirkungslos. +Aussage: Das System soll je Entität deklarativ festlegen können, welche Felder änderungsprotokolliert werden, und die Protokollierung darf das eigentliche Speichern niemals blockieren. +Ergebnis: ChangeLog-Einträge nur für annotierte Felder; Speichern gelingt auch bei Protokollierungsfehlern. +Belege: + - [PRIMÄR] src\backend\Centron.DAO\ChangeTracking\ChangeTrackingEventListener.cs, OnPreUpdate (GetOrAdd(HasAttribute), catch → Logger.Error + return false) - Begründung: durchsetzender, fehlertoleranter Mechanismus. + - [PRIMÄR] src\backend\Centron.Interfaces\ChangeTracking\TrackChangesAttribute.cs / ChangeTrackingConfigurationAttribute.cs; Grep über src\ liefert außer Listener und Attributdefinitionen keine Verwendungen - Begründung: belegt die Nicht-Nutzung. +Prüfidee: Testentität mit [ChangeTrackingConfiguration]+[TrackChanges] ändern → ChangeLog-Eintrag entsteht; Repo-Scan bestätigt, dass produktiv keine Entität annotiert ist. +Tracelinks: SyRS-1115 +Konsolidierung: Kandidat: ChangeLog wird parallel von fachlichen BLs direkt beschrieben (z. B. Centron.BL\Warehousing\ArticleLogBL.cs, ProductMatrixBL.cs) — zwei Schreibwege für dieselbe Historientabelle. +Übernahmewürdigkeit: veraltet - Infrastruktur ist registriert, aber von keiner Entität genutzt; für die Neuimplementierung Historisierung einheitlich (ein Schreibweg) aufsetzen. +Status: belegt +``` + +### SwRS-1134: Protokollierung von Stundensatz-Zuschlagsänderungen + +``` +ID: SwRS-1134 +Titel: Protokollierung von Stundensatz-Zuschlagsänderungen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Centron.DAO.ChangeTracking.LogHourlySurchargeRateChangesListener +Vorbedingung: HourlySurchargeRate (Zuschlagssatz für Stundenabrechnung) oder eine ihrer Positionen (HourlySurchargeRateItem) wird angelegt, geändert oder gelöscht. +Fakt: Der PostInsert/PostUpdate/PostDelete-Listener schreibt deutschsprachige Protokolleinträge ("Rate '{Name}' angelegt.", "Position von '{Start}' bis '{Ende}' gelöscht.") über WriteLog auf den Kopfsatz (HeadI3D); der Kommentar dokumentiert, dass HourlySurchargeRates selbst nicht gelöscht werden können; Fehler beim Protokollieren werden geloggt, brechen die Operation aber nicht ab. +Aussage: Das System soll jede Änderung an abrechnungsrelevanten Stundenzuschlagssätzen (Anlage, Feldänderung, Löschung von Positionen) automatisch und benutzerlesbar auf dem Zuschlagssatz protokollieren, da diese Sätze in die Fakturierung von Dienstleistungen eingehen. +Ergebnis: Lückenlose Historie der Zuschlagskonditionen als Nachweis gegenüber Kunden. +Belege: + - [PRIMÄR] src\backend\Centron.DAO\ChangeTracking\LogHourlySurchargeRateChangesListener.cs, OnPostInsert/OnPostUpdate/OnPostDelete (WriteLog(@event.Session, item.HeadI3D, "Position von ... gelöscht.")) - Begründung: durchsetzende Protokollierung inkl. konkreter Bedingung (@event.Entity is HourlySurchargeRateItem). +Prüfidee: Zuschlagsposition löschen → Protokolleintrag mit Zeitfenster der Position erscheint am Zuschlagssatz. +Tracelinks: SyRS-1115, SyRS-1116 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Nachweispflicht über Konditionsänderungen bleibt in einer SaaS-Fakturierung bestehen. +Status: belegt +``` + +### SwRS-1135: Datenmodell der Änderungshistorie (ChangeLog) + +``` +ID: SwRS-1135 +Titel: Datenmodell der Änderungshistorie (ChangeLog) +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Tabelle dbo.ChangeLog / ChangeLogBL +Vorbedingung: Historieneinträge werden objektbezogen abgefragt (ChangeLogBL.GetChangeLogs). +Fakt: dbo.ChangeLog speichert I3D (IDENTITY, unique nonclustered), ObjectI3D, ObjectKind, Property, OldValue/NewValue/Description/DisplayName (je nvarchar(4000)), Date, AppUserI3D; der CLUSTERED Index liegt auf (ObjectKind, ObjectI3D, Date DESC); ChangeLogBL filtert auf ObjectI3D+ObjectKind, optional Datumsbereich, sortiert Date absteigend; Werte werden vor dem Speichern auf 4000 Zeichen gekürzt (Shorten(4000)). +Aussage: Das System soll Historieneinträge generisch über Objektart und Objekt-ID adressieren, Texte auf 4000 Zeichen begrenzen und die physische Sortierung auf die typische Abfrage "neueste Änderungen eines Objekts" optimieren. +Ergebnis: Objektbezogene Historienabfrage ohne Tabellenscan. +Belege: + - [PRIMÄR] SSMS_DB_SCHEMA.sql:34746 ff., CREATE TABLE [dbo].[ChangeLog] + CREATE CLUSTERED INDEX [IX_ChangeLog] (ObjectKind ASC, ObjectI3D ASC, Date DESC) - Begründung: Constraint/Index als durchgesetzte Struktur. + - [SEKUNDÄR] src\backend\Centron.BL\CheckListArea\ChangeTracking\ChangeLogBL.cs, GetChangeLogs (Where ObjectI3D/ObjectKind, OrderByDescending(Date)) - Begründung: Abfragemuster passt zum Index. +Prüfidee: Ausführungsplan der Historienabfrage nutzt den clustered Index (Seek statt Scan). +Tracelinks: SyRS-1115 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - generisches (ObjectKind, ObjectI3D)-Adressschema ist für eine Neuimplementierung tragfähig. +Status: belegt +``` + +### SwRS-1136: Nebenläufigkeitsrobuste Telemetrie-Upserts + +``` +ID: SwRS-1136 +Titel: Nebenläufigkeitsrobuste Telemetrie-Upserts +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: Zuverlässigkeit +Akteur: Centron.BusinessLogic.Telemetry.TelemetryBL +Vorbedingung: Mehrere Prozesse/Threads flushen gleichzeitig Telemetrie-Zähler in dieselben Bucket-Zeilen. +Fakt: Die MERGE-Upserts laufen mit WITH (HOLDLOCK) (schließt das klassische MERGE-Race), und ExecuteWithDeadlockRetry wiederholt bei transienten Fehlern (SQL 1205 Deadlock, 2627/2601 Unique-Verletzung, erkannt per Reflection auf SqlException.Number beider SqlClient-Namespaces plus Message-Fallback) bis zu 5-mal mit wachsendem Backoff und Jitter (Sleep(50*attempt + Random 0-50)); Telemetriefehler werden geloggt und als Result zurückgegeben, werfen aber nie in den Fachablauf. +Aussage: Das System soll parallele Zählerschreibvorgänge ohne Verlust und ohne Duplikatfehler zusammenführen, transiente Datenbankkonflikte automatisch mit begrenzten Wiederholungen auflösen und Telemetriefehler niemals den fachlichen Ablauf unterbrechen. +Ergebnis: Genau eine Zeile je (User, Tool, Gerät, Bucket) mit korrekt aufsummiertem Count auch unter Last. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Telemetry\TelemetryBL.cs, UpsertMcpToolUsageBatch (MERGE ... WITH (HOLDLOCK)) und ExecuteWithDeadlockRetry/IsTransientConcurrencyError (attempt < _maxDeadlockRetries, Number == 1205/2627/2601) - Begründung: durchgesetzte Konfliktbehandlung. +Prüfidee: Lasttest: N parallele Upserts desselben Buckets → Summe der Counts stimmt exakt, keine unbehandelten Exceptions. +Tracelinks: SyRS-1116 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Anforderung (idempotente, konfliktrobuste Aggregation) bleibt; Umsetzung im Zielsystem ggf. über Queue statt MERGE. +Status: belegt +``` + +### SwRS-1137: Selbstpflegende Namens-Lookup-Tabellen der Telemetrie + +``` +ID: SwRS-1137 +Titel: Selbstpflegende Namens-Lookup-Tabellen der Telemetrie +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: TelemetryBL.ResolveNameI3Ds (McpToolNameLookup, ApiMethodNameLookup, HardwareIDLookup) +Vorbedingung: Telemetrieereignis referenziert Tool-/Methoden-/Gerätenamen als String. +Fakt: ResolveNameI3Ds dedupliziert Namen (StringComparer.Ordinal), verarbeitet sie in 1000er-Chunks (Kommentar: SQL-Server-Limit 2100 Parameter), fügt fehlende Namen per INSERT ... WHERE NOT EXISTS (SELECT ... WITH (HOLDLOCK, UPDLOCK)) ein, verschluckt Unique-Verletzung 2627 als gewonnenes Race und liest anschließend die I3Ds per SELECT zurück; Telemetriezeilen speichern nur die I3D-Referenzen. +Aussage: Das System soll Freitextnamen in Telemetriedaten durch normalisierte Schlüsselverweise ersetzen, fehlende Nachschlagewerte beim ersten Auftreten race-sicher selbst anlegen und dabei die Parametergrenzen der Datenbank einhalten. +Ergebnis: Kompakte Telemetrietabellen; identische Namen erhalten systemweit genau eine I3D. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Telemetry\TelemetryBL.cs, InsertMissingNames (WHERE NOT EXISTS ... WITH (HOLDLOCK, UPDLOCK); catch when IsUniqueViolation) und _resolveNameChunkSize = 1000 - Begründung: durchgesetzte Normalisierung inkl. Nebenläufigkeitsschutz. +Prüfidee: Zwei parallele Resolves desselben neuen Namens erzeugen genau eine Lookup-Zeile; 2500 Namen werden in 3 Chunks verarbeitet. +Tracelinks: SyRS-1116 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Normalisierungsmuster ist direkt übertragbar. +Status: belegt +``` + +### SwRS-1138: Deutsche Textanalyse für den Suchindex + +``` +ID: SwRS-1138 +Titel: Deutsche Textanalyse für den Suchindex +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: IndexBuilder / GermanAnalyzer (Centron.BL\IndexSearch) +Vorbedingung: Indexierbarer Text (auch RTF) eines Objekts liegt vor. +Fakt: IndexBuilder wandelt RTF in Klartext (TextHelper.RtfToPlain), zerlegt an Whitespace, verwirft Wörter mit <= 3 Zeichen (GermanAnalyzer.IsShortWord) und Stoppwörter aus einer eingebetteten deutschen Stoppwortliste, stemmt jeden Term mit einem an Lucene.NET angelehnten GermanStemmer (GermanAnalyzer.Stem) und erzeugt bei AllowAlterations zusätzliche Varianten (Sonderzeichen getrimmt/entfernt/gesplittet); Ergebnis ist ein deduplizierendes HashSet. +Aussage: Das System soll zu indexierende Texte sprachspezifisch (deutsch) normalisieren — Stammformbildung, Stoppwort- und Kurzwortfilter, Sonderzeichenvarianten — damit Suchbegriffe unabhängig von Flexion und Schreibweise treffen. +Ergebnis: Kompakte Termmenge je Objekt; "Druckern" und "Drucker" führen zum selben Indexterm. +Belege: + - [PRIMÄR] src\backend\Centron.BL\IndexSearch\IndexBuilder.cs, AddWord/AddTerm (IsShortWord-Filter, GermanAnalyzer.Stem, IsStopword) - Begründung: durchgesetzte Normalisierungspipeline. + - [PRIMÄR] src\backend\Centron.BL\IndexSearch\GermanAnalyzer.cs, IsShortWord (word.Length <= 3) und _stopwords-HashSet - Begründung: konkrete Filterregeln. +Prüfidee: Unit-Test: Add("Die Drucker druckten nicht") liefert Termmenge ohne "die"/"nicht", mit identischem Stamm für "Drucker"/"druckten"-Stammformen gemäß Stemmer. +Tracelinks: SyRS-1117 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Analyseregeln (deutsch, Stoppwörter, Stemming) als Fachvorgabe übernehmen; im Zielsystem durch Analyzer der gewählten Suchtechnologie umsetzen. +Status: belegt +``` + +### SwRS-1139: Inkrementelle Indexpflege mit Fehlerquarantäne + +``` +ID: SwRS-1139 +Titel: Inkrementelle Indexpflege mit Fehlerquarantäne +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: IndexSearchBL (Hintergrundjob UpdateAllIndexes/UpdateRequestedIndexes) +Vorbedingung: ObjectFulltextIndexStats enthält Zeilen mit IsUpdateRequested = true (gesetzt durch RequestUpdateFor aus AccountBL/HelpdeskBL nach Speichern). +Fakt: UpdateIndexesInternal aktualisiert je Objekt in eigener Transaktion (Löschen alter Terme, Neuaufbau, Stats-Update); im Volllauf entfernt es zusätzlich Indizes nicht mehr existierender Objekte und indiziert fehlende Objekte nach; wirft ein Objekt beim Indexieren eine Exception, wird es in einer statischen ConcurrentDictionary-Merkliste (_failedObjectI3Ds) vermerkt, per ObjectIndexingFailedException gemeldet und bei späteren Läufen übersprungen (IsFailedObject → return). +Aussage: Das System soll Suchindizes objektweise transaktional aktualisieren, gelöschte Objekte aus dem Index entfernen und Objekte, deren Indexierung fehlschlägt, isolieren, sodass ein einzelnes defektes Objekt die Indexierung der übrigen nicht dauerhaft blockiert. +Ergebnis: Index bleibt konsistent und aktuell; fehlerhafte Objekte werden übersprungen statt endlos wiederholt. +Belege: + - [PRIMÄR] src\backend\Centron.BL\IndexSearch\IndexSearchBL.cs, UpdateIndexesInternal (Session.WithTransaction je Objekt, RememberFailedObject + throw ObjectIndexingFailedException) und UpdateIndexForObject (IsFailedObject-Skip) - Begründung: durchgesetzte Pflege- und Quarantänelogik. + - [SEKUNDÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs:630 (RequestUpdateFor nach Speichern) - Begründung: Auslösung der inkrementellen Aktualisierung. +Prüfidee: Objekt mit provoziertem Indexierungsfehler → übrige Objekte werden indiziert, das defekte erscheint in der Merkliste und wird beim nächsten Lauf übersprungen. +Tracelinks: SyRS-1117 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - inkrementelle Pflege + Fehlerisolation übernehmen; prozesslokale statische Merkliste (geht bei Neustart verloren) durch persistierten Fehlerstatus ersetzen. +Status: belegt +``` + +### SwRS-1140: Datenmodell des Volltextindex + +``` +ID: SwRS-1140 +Titel: Datenmodell des Volltextindex +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Tabellen dbo.ObjectFulltextIndex und dbo.ObjectFulltextIndexStats +Vorbedingung: Indexierung gemäß SwRS-1139 läuft. +Fakt: ObjectFulltextIndex hält je Term eine Zeile (I3D bigint IDENTITY, TextValue nvarchar(1000), ObjectI3D, ObjectKind) mit UNIQUE CLUSTERED Index (ObjectI3D, ObjectKind, I3D) (FILLFACTOR 90); ObjectFulltextIndexStats hat den zusammengesetzten PK (ObjectI3D, ObjectKind) mit LastUpdate und IsUpdateRequested; die Kombination erlaubt objektweises Löschen/Neuaufbauen und Suche über TextValue. +Aussage: Das System soll den Suchindex als objektbezogene Termtabelle mit getrenntem Aktualisierungsstatus je Objekt speichern, wobei pro Objekt und Objektart genau ein Statusdatensatz existiert. +Ergebnis: Objektweise Indexoperationen ohne Betroffenheit anderer Objekte; Statusabfrage "Update angefordert" per PK-Zugriff. +Belege: + - [PRIMÄR] SSMS_DB_SCHEMA.sql:45591 ff., CREATE TABLE [dbo].[ObjectFulltextIndex] + CI_ObjectFulltextIndex; CREATE TABLE [dbo].[ObjectFulltextIndexStats] mit PK (ObjectI3D, ObjectKind) - Begründung: Constraints erzwingen die Struktur. +Prüfidee: Versuch, zweite Stats-Zeile für dasselbe (ObjectI3D, ObjectKind) einzufügen, scheitert am PK. +Tracelinks: SyRS-1117 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - relationale Termtabelle ist ein Ersatz für eine Suchengine; fachlich übernehmen, technisch neu lösen. +Status: belegt +``` + +### SwRS-1141: Validierung der KI-Endpunkt-URLs (SSRF-Schutz) + +``` +ID: SwRS-1141 +Titel: Validierung der KI-Endpunkt-URLs (SSRF-Schutz) +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: AiApiLinkValidator (Centron.BL\ArtificialIntelligence) +Vorbedingung: Administrator konfiguriert ApiLink für einen KI-Provider. +Fakt: Für benannte Provider wird unabhängig von der Eingabe stets die kanonische URL zurückgegeben (z. B. https://api.anthropic.com/v1 für ClaudeCode); eine abweichende Eingabe muss HTTPS mit Default-Port, ohne UserInfo/Query/Fragment sein, denselben Host wie die kanonische URL haben und einen erlaubten Pfad ("", "/", "/v1", "/v1beta") tragen, sonst InvalidOperationException; für OpenAiCompatible ist HTTPS generell erlaubt, HTTP nur für localhost/.local sowie private/Loopback-IP-Bereiche (10.x, 172.16-31.x, 192.168.x, 169.254.x, 100.64-127.x, fc00::/7 u. a.). +Aussage: Das System soll vom Administrator eingegebene KI-Endpunkte gegen Provider-Whitelists validieren und ausgehende KI-Aufrufe an fremde oder unverschlüsselte Ziele verhindern, mit Ausnahme lokal gehosteter Modelle im privaten Netz. +Ergebnis: KI-Requests gehen ausschließlich an kanonische Provider-Hosts oder explizit private HTTP-Ziele. +Belege: + - [PRIMÄR] src\backend\Centron.BL\ArtificialIntelligence\AiApiLinkValidator.cs, ValidateProviderApiLink (Host-Vergleich + IsAllowedProviderPath, throw InvalidOperationException) und IsPrivateAddress (Byte-Bereichsprüfungen) - Begründung: durchsetzende Prüfbedingungen. +Prüfidee: Unit-Tests: "https://api.openai.com.evil.tld/v1" → Exception; "http://10.0.0.5:1234/v1" für OpenAiCompatible → akzeptiert; "http://8.8.8.8/v1" → abgelehnt. +Tracelinks: SyRS-1118 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - SSRF-Schutz ist für einen mandantenfähigen SaaS-Betrieb zwingend. +Status: belegt +``` + +### SwRS-1142: Verschlüsselte Ablage der KI-API-Schlüssel + +``` +ID: SwRS-1142 +Titel: Verschlüsselte Ablage der KI-API-Schlüssel +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: ArtificialIntelligenceBL (Settings) / alle KI-Clients +Vorbedingung: KI-Einstellungen werden als ApplicationSettings (AiApiKey, AiWebSearchApiKey) gespeichert. +Fakt: Beim Speichern wird der WebSearch-Schlüssel mit new AESCryptoLogic().EncryptText(settings.WebSearchApiKey) verschlüsselt persistiert und beim Laden mit DecryptText entschlüsselt; alle KI-Clients (OpenAiApiClient, ClaudeCodeChatModelClient, MistralAiChatModelClient, GoogleGeminiChatModelClient, TextRatingApiClient, AiHttpModelCatalogClient) entschlüsseln den gespeicherten AiApiKey vor Verwendung mit CryptoControl.DecryptString(_settings.ApiKey); ein leerer entschlüsselter Schlüssel verhindert den Client-Aufbau (return null / return []). +Aussage: Das System soll API-Schlüssel für KI-Dienste ausschließlich verschlüsselt speichern und nur zur Laufzeit für den konkreten API-Aufruf entschlüsseln; ohne gültigen Schlüssel darf kein KI-Aufruf zustande kommen. +Ergebnis: Kein Klartext-Schlüssel in der Datenbank; KI-Funktionen sind ohne Schlüssel deaktiviert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\ArtificialIntelligence\ArtificialIntelligenceBL.cs:184 (UpdateLargeString(ApplicationSettingID.AiWebSearchApiKey, new AESCryptoLogic().EncryptText(...))) - Begründung: verschlüsselnde Speicherstelle. + - [PRIMÄR] src\backend\Centron.BL\ArtificialIntelligence\OpenAiApiClient.cs:34 (var key = CryptoControl.DecryptString(_settings.ApiKey); if (IsNullOrWhiteSpace) return null) - Begründung: erzwungene Entschlüsselung + Abbruch ohne Schlüssel; belegt verschlüsselte Ablageform des AiApiKey. +Prüfidee: Gespeicherten Settings-Wert direkt in der DB lesen → kein Klartextschlüssel; KI-Aufruf ohne hinterlegten Schlüssel liefert keinen Request an den Provider. +Tracelinks: SyRS-1118 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - im SaaS-Zielsystem durch Secret-Store/KMS statt symmetrischer Eigenverschlüsselung umsetzen. +Status: belegt +``` + +### SwRS-1143: Dokumentoperationen der Dateiablage im Client + +``` +ID: SwRS-1143 +Titel: Dokumentoperationen der Dateiablage im Client +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: CentronFileSystemConnector (ICentronFileSystemConnector) / Shared-Control CentronFileSystem (Centron.Controls) +Vorbedingung: ClassContainer liefert IDocumentLogic/IDirectoryLogic (BL- oder WS-Implementierung). +Fakt: Der Connector adaptiert das wiederverwendbare Dateisystem-Control (CentronSoftware.Centron.Controls.CentronFileSystem.Interfaces) auf die ILogic-Schicht: AddDocumentToDirectoryAsync (fileData, Metainformationen, publicDelete, fileObjectKind), CreateDirectory mit Status, RenameDocumentAsync, AddNewDocumentVersion, CheckOutDocument(documentI3D, lockedByWorkstation, lockedFilePath), CheckInDocument, UndoCheckOut, GetShowFilePreviews/SaveShowFilePreviews (Benutzereinstellung Vorschau) und CreateIndexesForDocument (Anbindung an die Volltextsuche). +Aussage: Das System soll die Dateiablage-Oberfläche von der Datenzugriffsart entkoppeln, indem alle Dokument- und Verzeichnisoperationen über eine einzige Konnektor-Schnittstelle laufen, die auch Benutzereinstellungen (Dateivorschau) und die Dokumentindexierung einschließt. +Ergebnis: Dasselbe Dateiablage-Control funktioniert in allen Einbettungen (Kunde, Beleg, geteilte Dokumente) mit BL- und WS-Verbindung. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\CentronFileSystem\CentronFileSystemConnector.cs (Konstruktor: ClassContainer.Instance.GetInstance() ...; alle Methoden delegieren an ILogic) - Begründung: vollständige Konnektor-Implementierung. + - [SEKUNDÄR] src\shared\Centron.Controls\CentronFileSystem (wiederverwendbares Control) - Begründung: geteilte UI-Komponente als Abnehmer der Schnittstelle. +Prüfidee: Dateiablage in zwei Modulen öffnen (SqlServer- und WebService-Verbindung); Upload/Umbenennen/Vorschau-Einstellung verhalten sich identisch. +Tracelinks: SyRS-1119, SyRS-1110 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Entkopplung von Datei-UI und Zugriffsschicht ist auch im Web sinnvoll (Komponent + API-Client). +Status: belegt +``` + +### SwRS-1144: Persistierung der Sprachwahl in der Windows-Registry + +``` +ID: SwRS-1144 +Titel: Persistierung der Sprachwahl in der Windows-Registry +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: LocalizationHelper (Centron.WPF.UI\Localization) +Vorbedingung: Benutzer wählt eine Sprache; Client startet neu. +Fakt: SaveCulture legt die Schlüsselkette HKCU\Software\c-entron software gmbh\c-entron an (AccessKey mit CreateSubKey bei Schreibzugriff) und schreibt cultureInfo.Name in den Wert "Language"; LoadCulture liest denselben Wert case-insensitiv, liefert null bei fehlenden Schlüsseln, und ConfigureLocalization setzt nur bei vorhandener Kultur CultureInfo.CurrentUICulture; ResXManager.config.xml (SortFileContentOnSave=True) hält die ResX-Dateien mergefreundlich sortiert. +Aussage: Das System soll die Sprachwahl je Windows-Benutzer dauerhaft speichern und beim Start anwenden; fehlt eine gespeicherte Wahl, gilt die Systemsprache (Standard Deutsch). +Ergebnis: Reproduzierbare UI-Sprache je Arbeitsplatzbenutzer. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Localization\LocalizationHelper.cs, SaveCulture (key.SetValue("Language", cultureInfo.Name)) und LoadCulture/ConfigureLocalization - Begründung: durchgesetzter Lese-/Schreibpfad. + - [SEKUNDÄR] ResXManager.config.xml (SortFileContentOnSave=True) - Begründung: Tooling-Konvention für die Ressourcenpflege. +Prüfidee: Registry-Wert löschen → Client startet in Systemsprache; Wert "en" → englische UI. +Tracelinks: SyRS-1120 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - Registry-Bindung ist Fat-Client-spezifisch; fachliche Anforderung (persistierte Sprachwahl pro Benutzer) übernehmen, Ablage in Benutzerprofil/DB verlagern. +Status: belegt +``` + +### SwRS-1145: Rechteprüfung für globale GUI-Profile + +``` +ID: SwRS-1145 +Titel: Rechteprüfung für globale GUI-Profile +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: UiProfileBL (Centron.BL\GUI\Profiles) / ManageUiProfileViewModel (UI) +Vorbedingung: Benutzer speichert oder löscht ein GUI-Profil mit IsGlobal = true. +Fakt: UiProfileBL.SaveProfile verweigert bei profile.IsGlobal ohne Recht EDIT_GLOBAL_PROFILES mit Result-Fehler "Sie haben nicht das Recht um öffentliche Profile anzulegen (Öffentliche Profile bearbeiten)."; DeleteProfile prüft dasselbe Recht und deaktiviert globale Profile nur (IsActive = false, session.Save) statt sie zu löschen, während private Profile physisch gelöscht werden und zugeordnete EmployeeSettingsProfileNets zurückgesetzt werden; die UI blendet die Option über CentronCache.Instance.CurrentUserAppRights vor (ManageUiProfileViewModel). +Aussage: Das System soll das Anlegen, Ändern und Löschen global sichtbarer Oberflächenprofile nur Benutzern mit dem Recht "Öffentliche Profile bearbeiten" erlauben und globale Profile beim Löschen deaktivieren statt zu entfernen; private Profile darf jeder Benutzer für sich verwalten. +Ergebnis: Globale Layouts sind vor unberechtigter Änderung geschützt und historisch rekonstruierbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\GUI\Profiles\UiProfileBL.cs:51 und :75 (if (... HasUserRight(UserRightsConst.Administration.EDIT_GLOBAL_PROFILES) == false) return ...AsError(...); globaler Zweig: profile.IsActive = false) - Begründung: serverseitig durchsetzende Prüfung inkl. Bedingung. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\Gui\Profiles\ManageUiProfileViewModel.cs:26 (CurrentUserAppRights.Any(f => f.I3D == UserRightsConst.Administration.EDIT_GLOBAL_PROFILES)) - Begründung: UI-seitige Vorabprüfung derselben Regel. +Prüfidee: API-Aufruf SaveProfile(IsGlobal=true) mit Benutzer ohne Recht → Fehler-Result; mit Recht → Profil gespeichert; Löschen eines globalen Profils lässt den Datensatz mit IsActive=false bestehen. +Tracelinks: SyRS-1121 +Konsolidierung: Kandidat: NexusTicketViewWebServiceBL nutzt dasselbe Recht EDIT_GLOBAL_PROFILES für globale Ticket-Ansichten (src\backend\Centron.BL\WebServices\NexusTicketViews\NexusTicketViewWebServiceBL.cs) — zwei Profilmechanismen (UI-Profile, Ticket-Views) mit gleicher Fachbedeutung. +Übernahmewürdigkeit: übernehmen - Rechtemodell privat/global ist direkt übertragbar. +Status: belegt +``` + +### SwRS-1146: Verwaltung externer Tools mit Variablenersetzung + +``` +ID: SwRS-1146 +Titel: Verwaltung externer Tools mit Variablenersetzung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: ExternalToolBL (Centron.BL\ExternalToolsBL) / ExternalToolsVaribaleCollection (UI) +Vorbedingung: Benutzer legt ein externes Tool an oder startet es aus einem Fachkontext (Beleg, Account). +Fakt: SaveExternalTool setzt Created*/Changed*-Felder aus dem LoggedInUser, verweigert komplett leere Objekte ("Vor dem Speichern müssen alle Felder ausgefüllt werden.", DefaultMessageCodes.MandatoryFieldsNotFilled) und leeren Namen ("Es muss ein Name angegeben werden."); ReplaceExternalToolVariables delegiert an ExternalToolsReplacementBL.ReplaceVariablesText mit VariableData; die UI definiert die Platzhaltermengen BasicVaribles (@@Benutzername@@, @@WebServiceUrl@@), ReceiptLocationVariables (@@Belegart@@, @@BelegI3D@@, @@BelegNummer@@) und NewAccountVariables (@@AccountNummer@@ u. a.); die Tabelle dbo.ExternalTools speichert Name (NOT NULL), Path, Location, CommandLineArguments, SuccessAction, IsDeactivated. +Aussage: Das System soll externe Programme als benannte Konfigurationen (Pfad, Aufrufparameter, Erfolgsaktion, Deaktivierbarkeit) verwalten, beim Speichern Name und Mindestbefüllung erzwingen und beim Start kontextspezifische @@Platzhalter@@ durch Benutzer-, Beleg- bzw. Kundendaten ersetzen. +Ergebnis: Externes Tool startet mit aufgelösten Argumenten; unvollständige Konfigurationen werden abgewiesen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\ExternalToolsBL\ExternalToolBL.cs, SaveExternalTool (Null-Properties-Prüfung, string.IsNullOrWhiteSpace(externalTool.Name) → Result-Fehler) - Begründung: durchgesetzte Validierung. + - [PRIMÄR] SSMS_DB_SCHEMA.sql:39695, CREATE TABLE [dbo].[ExternalTools] (Name varchar(200) NOT NULL, CommandLineArguments NOT NULL, IsDeactivated bit NOT NULL) - Begründung: Datenmodell mit NOT-NULL-Constraints. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\ExternalTool\Variables\ExternalToolsVaribaleCollection.cs (@@Benutzername@@, @@BelegNummer@@, ...) - Begründung: definierte Platzhaltermengen je Kontext. +Prüfidee: Tool ohne Name speichern → Fehlermeldung; Tool mit "@@BelegNummer@@" aus einem Beleg starten → Argument enthält die Belegnummer. +Tracelinks: SyRS-1121 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Platzhalterkonzept übernehmen; lokaler EXE-Start (Path) ist im Web durch URL-Schemata/Protokoll-Handler zu ersetzen. +Status: belegt +``` + +### SwRS-1147: Doppelte Entitätsklassen für den Firmenmandanten (Tabelle Mandant) + +``` +ID: SwRS-1147 +Titel: Doppelte Entitätsklassen für den Firmenmandanten (Tabelle Mandant) +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Entitäten Mandator (Administration\Company) und Mandatory (Administration\MandatoryArea) +Vorbedingung: Installation verwaltet einen oder mehrere Firmenmandanten (eigene Firmen mit Briefkopf-, Bank- und Steuerdaten) in einer gemeinsamen Datenbank. +Fakt: Beide Entitätsklassen sind per Fluent-Mapping auf DIESELBE Tabelle "Mandant" gemappt (MandatorMaps.cs: Table("Mandant"); MandatoryMaps.cs: Table("Mandant")), mit unterschiedlich benannten, teils auskommentiert-duplizierten Properties (Mandator: Street/Phone/EMail/TaxIDNumber; Mandatory: Address/Telephone/Mail/BankOne..BankFour); die Alt-Tabelle Mandant nutzt deutsche varchar-Spalten (Anschrift, Geschaeftsfuehrer, BLZ1, UStID); Zeilenfilter oder Datenraumtrennung nach Mandant sind in den gesichteten Querschnittskomponenten nicht vorhanden. +Aussage: Das System soll Firmenmandanten (Absender-/Stammdaten der eigenen Firmen inkl. Bankverbindungen und Steuerkennzeichen) als einheitliches Datenobjekt führen; die Neuimplementierung soll die zwei parallelen Entitätsmodelle auf ein Modell konsolidieren. +Ergebnis: Ein Mandantenstamm mit eindeutiger Feldsemantik. +Belege: + - [PRIMÄR] src\backend\Centron.DAO\Mappings\Administration\Company\MandatorMaps.cs:12 und ...\MandatoryArea\MandatoryMaps.cs:14 (beide Table("Mandant")) - Begründung: belegt die Doppel-Implementierung auf derselben Tabelle. + - [PRIMÄR] SSMS_DB_SCHEMA.sql:23808, CREATE TABLE [dbo].[Mandant] (Mandant, Anschrift, Geschaeftsfuehrer, UStID, Bank1..Bank4, ...) - Begründung: gemeinsames Alt-Datenmodell. +Prüfidee: Statische Analyse: alle Verwendungsstellen von Mandator vs. Mandatory inventarisieren; nach Konsolidierung existiert genau eine Mandanten-Entität. +Tracelinks: SyRS-1111, SyRS-1110 +Konsolidierung: Kandidat: Mandator (Company) und Mandatory (MandatoryArea) — zwei Entitätsklassen für denselben fachlichen Gegenstand auf derselben Tabelle; zusätzlich Alt-Tabelle MandantenStammdat (SSMS_DB_SCHEMA.sql:44171) als vermutete Zweitdatenhaltung (Kandidat (vermutet): MandantenStammdat). +Übernahmewürdigkeit: Sonderfall - historisch gewachsene Doppelstruktur; fachlicher Inhalt übernehmen, Struktur konsolidieren. +Status: HYPOTHESE +Offene Frage: Ob "Mandant" hier ausschließlich die eigene Firma (Belegabsender) bezeichnet und keine datenraumtrennende Mehrmandantenfähigkeit existiert, konnte nur negativ (kein Mandantenfilter in den gesichteten Querschnittskomponenten) belegt werden; Verwendung von MandantenStammdat ungeklärt. +``` + +## Cluster A12 — Administration, Konfiguration & Betrieb — SwRS + +### SwRS-1231: Mandantenlöschung als Statuswechsel (State=0) + +``` +ID: SwRS-1231 +Titel: Mandantenlöschung als Statuswechsel (State=0) +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente MandatorManagementViewModel / MandatorWebServiceBL +Vorbedingung: Zu löschender Mandant ist nicht der Standardmandant und hat keine aktiven Filialen +Fakt: DeleteMandatorAsync setzt MandatoryExtendedDTOSelected.State = 0 und speichert über SaveMandatoryExtendedAsync; Codekommentar: "deleting is not supported, set status '0' (set mandator inactive)"; zusätzlich wird FederalState = null gesetzt. +Aussage: Die Software soll das Löschen eines Mandanten als Statuswechsel auf State=0 (inaktiv) implementieren und den Datensatz physisch erhalten. +Ergebnis: Der Mandant verschwindet aus der aktiven Liste, bleibt aber referenzierbar (Belege, Historie). +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\Administration\MandatorManagement\MandatorManagementViewModel.cs (DeleteMandatorAsync, Zeilen 260-264: State = 0; SaveMandatoryExtendedAsync) - Begründung: durchgesetzter Soft-Delete. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, [dbo].[Mandant].[Status] int NULL - Begründung: Statusspalte trägt den Aktiv/Inaktiv-Zustand. +Prüfidee: Mandant "löschen"; SELECT auf Mandant muss den Datensatz mit Status=0 zeigen; GetAllMandatoryExtended darf ihn nicht mehr liefern. +Tracelinks: SyRS-1211 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Soft-Delete ist wegen Belegreferenzen zwingend. +Status: belegt +``` + +### SwRS-1232: Eindeutiger Standardmandant und eindeutige Standardfiliale + +``` +ID: SwRS-1232 +Titel: Eindeutiger Standardmandant und eindeutige Standardfiliale +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente MandatorManagementViewModel +Vorbedingung: Mehrere Mandanten bzw. Filialen existieren +Fakt: IsSetToDefault setzt vor dem Markieren des neuen Standards bei allen anderen Mandanten Default=false; EditBranchDetails/NewBranch setzen beim Markieren einer Filiale als Default alle übrigen Filialen des Mandanten auf IsDefault=false und speichern sie; Filiallöschung ist Soft-Delete (SaveToModel(isDeleted:true)) und für die Default-Filiale gesperrt (DeleteBranchCommand-CanExecute: IsDefault == false). +Aussage: Die Software soll sicherstellen, dass zu jedem Zeitpunkt genau ein Mandant systemweit und genau eine Filiale je Mandant als Standard markiert ist, und dass die Standardfiliale nicht gelöscht werden kann. +Ergebnis: Eindeutige Auflösung des Standardmandanten/-filiale für Belege und Logos. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\Administration\MandatorManagement\MandatorManagementViewModel.cs (IsSetToDefault: foreach client.Default=false; EditBranchDetails: defaultBranch.IsDefault=false + SaveBranchDetails; DeleteBranchCommand: SelectedBranch.IsDefault == false) - Begründung: durchgesetzte Eindeutigkeits- und Löschsperrregeln. +Prüfidee: Zweiten Mandanten als Standard markieren: erster verliert Default; zweite Filiale als Default markieren: erste verliert Default; Versuch, Default-Filiale zu löschen, muss gesperrt sein. +Tracelinks: SyRS-1211 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Eindeutigkeit sollte in der Neuimplementierung zusätzlich per DB-Constraint abgesichert werden (heute nur Client-Logik). +Status: belegt +``` + +### SwRS-1233: [HYPOTHESE] Serverseitige Rechteprüfung beim Speichern von Mandantenstammdaten + +``` +ID: SwRS-1233 +Titel: [HYPOTHESE] Serverseitige Rechteprüfung beim Speichern von Mandantenstammdaten +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente MandatorWebServiceBL (Server) +Vorbedingung: Benutzer ruft SaveMandatoryExtended über die Webservice-API auf +Fakt: MandatorWebServiceBL.SaveMandatoryExtended delegiert direkt an MandatorBL.SaveMandatory, ohne im gelesenen Codepfad eine Prüfung auf UserRightsConst.Administration.MANDATORY (=10510) durchzuführen; die Rechteprüfung wurde nur clientseitig (für den KI-Systemprompt) gefunden. Mandantendaten enthalten abrechnungsrelevante Bankverbindungen (IBAN/BIC) und die SEPA-Gläubiger-ID. +Aussage: Die Software soll das Speichern von Mandantenstammdaten (inkl. Bankverbindungen) serverseitig nur Benutzern mit dem Recht Administration.MANDATORY erlauben. +Ergebnis: API-Aufrufe ohne das Recht werden mit Rechtefehler abgewiesen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\WebServices\Administration\Company\MandatorWebServiceBL.cs (SaveMandatoryExtended, Zeile 136 ff.: keine HasUserRight-Prüfung vor mandatorBL.SaveMandatory) - Begründung: Abwesenheit der durchsetzenden Prüfung an der Service-Fassade; ob sie tiefer (MandatorBL/REST-Schicht) erfolgt, wurde nicht belegt. + - [KONTEXT] src\webservice\Centron.WebServices.Core\EntitiesWrongPlace\Administration\Rights\UserRightsConst.cs (Administration.MANDATORY = 10510) - Begründung: das zugehörige Recht existiert. +Prüfidee: Mit einem Benutzer ohne Recht 10510 SaveMandatoryExtended per REST aufrufen; erwartet: Ablehnung. Schlägt der Test fehl, liegt eine Sicherheitslücke bei Bankdaten vor. +Tracelinks: SyRS-1211 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - in der Neuimplementierung ist die serverseitige Prüfung zwingend vorzusehen. +Status: HYPOTHESE +Offene Frage: Prüft die aufrufende REST-Schicht (CentronRestService) oder MandatorBL.SaveMandatory das Recht Administration.MANDATORY serverseitig, oder verlässt sich das System allein auf die Client-UI? +``` + +### SwRS-1234: Mandantenspezifischer KI-Systemprompt nur mit Recht und Lizenz + +``` +ID: SwRS-1234 +Titel: Mandantenspezifischer KI-Systemprompt nur mit Recht und Lizenz +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente MandatorManagementViewModel; IArtificialIntelligenceChatLogic +Vorbedingung: KI-Assistent-Lizenz vorhanden; Benutzer hat Recht ArtificialIntelligence bzw. Administration.MANDATORY +Fakt: Der Prompt-Bereich ist nur sichtbar/ladbar bei LicenseManager.Instance.HasLicense(LicenseGuids.AiAssistant) UND Recht UserRightsConst.ArtificialIntelligence.ID; das Speichern wird zusätzlich verweigert, wenn das Recht UserRightsConst.Administration.MANDATORY fehlt (Meldung "Fehlende Berechtigung: Mandanten-Systemprompt darf nicht gespeichert werden."). +Aussage: Die Software soll je Mandant einen KI-Systemprompt pflegbar machen, dessen Anzeige an KI-Lizenz und KI-Recht und dessen Speicherung an das Mandantenverwaltungsrecht gebunden ist. +Ergebnis: Nur berechtigte Administratoren können den mandantenweiten KI-Prompt ändern. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\Administration\MandatorManagement\MandatorManagementViewModel.cs (HasAiAssistantLicense, Zeile 104-105; SaveMandatorInstructionPrompt, Zeile 480: if (!HasCurrentUserRight(UserRightsConst.Administration.MANDATORY)) => Abbruch) - Begründung: konkrete Prüfbedingungen; Hinweis: Prüfung liegt clientseitig, serverseitige Durchsetzung in IArtificialIntelligenceChatLogic wurde nicht gelesen. +Prüfidee: Benutzer ohne Recht 10510: Prompt ändern und speichern; erwartet: Statusmeldung "Fehlende Berechtigung" und kein Persistieren. +Tracelinks: SyRS-1211 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - mandantenbezogene KI-Konfiguration ist zukunftsrelevant; Rechteprüfung serverseitig nachziehen. +Status: belegt +``` + +### SwRS-1235: Typisiertes Datenmodell der ApplicationSettings + +``` +ID: SwRS-1235 +Titel: Typisiertes Datenmodell der ApplicationSettings +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente AppSettingsBL / Tabelle ApplicationSettings +Vorbedingung: Setting-ID ist im Enum ApplicationSettingID registriert +Fakt: Die Tabelle ApplicationSettings hat den Primärschlüssel I3D (= Enum-Wert), eine Pflicht-Beschreibung (Description nvarchar(1000) NOT NULL) und je einen nullable Wertspalten-Slot pro Typ (ValueInt, ValueFloat, ValueDecimal, ValueBool, ValueDateTime, ValueText nvarchar(4000), ValueLargeText nvarchar(max)); IDs werden über einen Kommentar "Next Centron Settings ID" fortgeschrieben, Beschreibungen in ApplicationSettingDefinitions.cs gepflegt. +Aussage: Die Software soll jede Anwendungseinstellung als Datensatz mit fester numerischer ID, Pflichtbeschreibung und genau einem typgerechten Wertfeld speichern. +Ergebnis: Einstellungen sind eindeutig identifizierbar, selbstdokumentierend und typsicher abrufbar. +Belege: + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[ApplicationSettings] (Zeile 5817: I3D PK, Description NOT NULL, Value*-Spalten) - Begründung: Constraint-bewehrtes Datenmodell. + - [KONTEXT] docs\guides\development\settings-management.md (Abschnitt "ID Management", "Setting Definitions") - Begründung: dokumentierter Pflegeprozess der IDs und Beschreibungen. +Prüfidee: Insert ohne Description muss scheitern (NOT NULL); GetBool auf ein Int-Setting muss den definierten Default liefern. +Tracelinks: SyRS-1212 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Modell ist einfach und migrierbar. +Status: belegt +``` + +### SwRS-1236: Duale Einstellungs-Datenhaltung Stammdat und ApplicationSettings + +``` +ID: SwRS-1236 +Titel: Duale Einstellungs-Datenhaltung Stammdat und ApplicationSettings +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente AppSettingsBL (Zugriffe über AppSettingsConst und ApplicationSettingID) +Vorbedingung: — +Fakt: Einstellungen liegen historisch bedingt in zwei Tabellen: Stammdat (Legacy, Zugriff über Enum AppSettingsConst, z. B. EscalationDeliveryAfterDays, NoEscalationFromService) und ApplicationSettings (aktuell, Enum ApplicationSettingID); die Doku verbietet neue Stammdat-Einträge und beschreibt einen Migrationspfad. +Aussage: Die Software soll (Ist-Zustand) Einstellungen aus beiden Tabellen lesen können; für die Neuimplementierung sollen beide Bestände in eine einheitliche Einstellungsverwaltung überführt werden. +Ergebnis: Alle Alt- und Neueinstellungen sind über eine API erreichbar. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\Administration\EscalationsSettings\EscalationType\EscalationTypeSettingViewModel.cs (init: GetAppSettingAsync(AppSettingsConst.EscalationDeliveryAfterDays) u. a.) - Begründung: aktive Nutzung des Legacy-Bestands Stammdat. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[Stammdat] (Zeile 6828) und [dbo].[ApplicationSettings] (Zeile 5817) - Begründung: zwei parallele Datenhaltungen für denselben Gegenstand "Einstellung". + - [KONTEXT] docs\guides\development\settings-management.md ("This dual-table approach exists for historical reasons"; "Migrating Legacy Settings") - Begründung: bestätigt Historie und Migrationsabsicht. +Prüfidee: Inventar aller AppSettingsConst-Nutzungen erstellen; für jede eine Ziel-ID in ApplicationSettings definieren und Lesezugriffe beider Wege vergleichen. +Tracelinks: SyRS-1212 +Konsolidierung: Kandidat: Tabellen Stammdat und ApplicationSettings (zwei Datenhaltungen für Anwendungseinstellungen) +Übernahmewürdigkeit: Workaround - historisch gewachsene Doppelhaltung; in der Neuimplementierung auf eine Struktur konsolidieren. +Status: belegt +``` + +### SwRS-1237: Auflösungshierarchie für Textbausteine (Kunde vor Benutzer vor Global) + +``` +ID: SwRS-1237 +Titel: Auflösungshierarchie für Textbausteine (Kunde vor Benutzer vor Global) +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente TextModuleBL.GetTextModule +Vorbedingung: Beleg/Mail wird für einen Kunden durch einen Benutzer erzeugt +Fakt: GetTextModule sucht in fester Reihenfolge: (1) aktiver Baustein des Kunden (State==1 && CustomerI3D==customerI3D, OrderBy I3D, erster Treffer), (2) aktiver Baustein des Benutzers (UserI3D==appUserI3D, OrderByDescending I3D, letzter Treffer), (3) globaler Baustein (CustomerI3D==0 && UserI3D==0); leere Texte (IsNullOrWhiteSpace) werden übersprungen; Sortierungen sind laut Kommentar "delphi compatible". +Aussage: Die Software soll Textbausteine je Typ in der Prioritätsfolge kundenspezifisch, benutzerspezifisch, global auflösen und leere Bausteine dabei wie nicht vorhandene behandeln. +Ergebnis: Der spezifischste nicht-leere Textbaustein wird verwendet. +Belege: + - [PRIMÄR] src\backend\Centron.BL\TextModuleArea\TextModuleBL.cs (GetTextModule(int,int,TextModuleType), Zeilen 396-418: dreistufige Query-Kaskade mit IsNullOrWhiteSpace-Prüfung) - Begründung: durchgesetzte Auflösungsregel. +Prüfidee: Globalen, benutzer- und kundenspezifischen Baustein desselben Typs anlegen; Belegerzeugung muss den Kundentext nehmen; Kundentext leeren: Benutzertext muss greifen. +Tracelinks: SyRS-1213 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Hierarchie ist fachlich sinnvoll; Delphi-kompatible Sortier-Sonderregeln (erster vs. letzter Treffer) sind veraltet und zu vereinheitlichen. +Status: belegt +``` + +### SwRS-1238: Variablenersetzung und Soft-Delete für Textbausteine + +``` +ID: SwRS-1238 +Titel: Variablenersetzung und Soft-Delete für Textbausteine +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente TextModuleBL / ReplacementBL / MailTextBlockRepository +Vorbedingung: Textbaustein enthält Platzhalter im Format @@Variable +Fakt: ReplaceCustomerTextBlockVariables/ReplaceMailSupplierVariables holen kontextabhängige Variablenwerte (Benutzer, Kunde/Lieferant, Ansprechpartner, Belegart/Beleg) und ersetzen Platzhalter mit variableIdentifier "@@" in Text und RichText; vor der Ersetzung wird das Entity per Session.Evict vom NHibernate-Tracking gelöst, damit der ersetzte Text nicht zurückgeschrieben wird. DeleteTextModule setzt State=0 statt zu löschen. +Aussage: Die Software soll Platzhalter (@@-Syntax) in Textbausteinen zur Laufzeit kontextbezogen (Kunde, Lieferant, Ansprechpartner, Beleg) ersetzen, ohne den gespeicherten Baustein zu verändern, und Bausteine per Statuswechsel deaktivieren. +Ergebnis: Personalisierte Texte in Belegen/Mails; Originalbausteine bleiben unverändert und historisch erhalten. +Belege: + - [PRIMÄR] src\backend\Centron.BL\TextModuleArea\TextModuleBL.cs (ReplaceMailCustomerVariables: Session.GetSession().Evict(textModule); ReplaceCustomerTextBlockVariables: ReplaceVariables(..., variableIdentifier: "@@"); DeleteTextModule: module.State = 0) - Begründung: durchgesetzte Ersetzungs- und Löschregeln. +Prüfidee: Baustein mit @@-Platzhalter anlegen, Mail erzeugen: Platzhalter ersetzt; Baustein in DB unverändert; Baustein löschen: Datensatz mit State=0 vorhanden. +Tracelinks: SyRS-1213 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Platzhaltermechanik ist Kernfunktion; @@-Syntax kann beibehalten oder auf Template-Engine migriert werden. +Status: belegt +``` + +### SwRS-1239: Hintergrunddienst-Basisklasse mit DB-Aktivierung, Enable-Cache und Backoff + +``` +ID: SwRS-1239 +Titel: Hintergrunddienst-Basisklasse mit DB-Aktivierung, Enable-Cache und Backoff +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: Zuverlässigkeit +Akteur: Komponente ManagedBackgroundService / BackgroundServiceBL +Vorbedingung: Host gestartet +Fakt: ManagedBackgroundService wartet initial 1 Minute, registriert den Dienst (UpdateStartTime), prüft IsServiceEnabled je Zyklus mit 60-Sekunden-Cache (IsEnabledCacheDuration), fällt bei DB-Fehlern auf den letzten bekannten Wert bzw. false zurück ("skip execution to avoid consuming more connections"), aktualisiert nach jedem Lauf LastRunTime und verdoppelt bei aufeinanderfolgenden Fehlern die Wartezeit bis maximal 5 Minuten (MaxBackoffDelay). +Aussage: Die Software soll jeden Hintergrunddienst über eine gemeinsame Basisklasse implementieren, die Aktivierung aus der Tabelle BackgroundServices cached liest, Laufzeiten protokolliert, bei Fehlern exponentiell zurückweicht und bei unklarem Aktivierungszustand die Ausführung auslässt. +Ergebnis: Einheitliches, ressourcenschonendes Verhalten aller ca. 35 Hintergrunddienste. +Belege: + - [PRIMÄR] src\webservice\Centron.Host\AspNetCore\HostedServices\ManagedBackgroundService.cs (GetIsEnabledCached, GetDelayWithBackoff, ExecuteAsync mit UpdateStartTime/UpdateLastRunTime) - Begründung: vollständige durchgesetzte Ablauflogik. + - [SEKUNDÄR] src\backend\Centron.BL\Administration\BackgroundServices\BackgroundServiceBL.cs (CreateOrUpdateBackgroundService, IsServiceEnabled) - Begründung: persistente Steuerdaten je ServiceName. +Prüfidee: IsEnabled-Wechsel darf erst nach max. 60 s wirken; bei nicht erreichbarer DB darf der Dienst nicht ausgeführt werden und das Intervall muss sich verdoppeln (Logauswertung). +Tracelinks: SyRS-1214 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - als Spezifikation für Worker/Job-Framework der Neuimplementierung. +Status: belegt +``` + +### SwRS-1240: Isolierte Einzelaufgaben im DataQualityService + +``` +ID: SwRS-1240 +Titel: Isolierte Einzelaufgaben im DataQualityService +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: Zuverlässigkeit +Akteur: Komponente DataQualityService +Vorbedingung: DataQualityService ist in BackgroundServices aktiviert +Fakt: ExecuteService führt jede Datenqualitätsaufgabe (TicketPatternUpdateCustomerMappings, ExecuteDirectoryCheck, CleanupCentronNotifications, UpdateChecklistCustomerMappings, ReorganizeProfilerEntries, DataQualityFillAccountI3D u. a.) in einer eigenen kurzlebigen BLSession in einem eigenen try-catch aus; zwischen den Aufgaben wird stoppingToken.IsCancellationRequested geprüft; Fehler werden mit Aufgabennamen geloggt ("Error while executing data quality service - ..."). +Aussage: Die Software soll Datenqualitäts-Reparaturaufgaben (Bereinigung veralteter Daten, Auffüllen fehlender Referenzen, Reorganisation von Protokollen) als voneinander unabhängige, einzeln fehlertolerante Schritte mit eigener Session ausführen und zwischen den Schritten auf Abbruchanforderungen reagieren. +Ergebnis: Ein Fehler in einer Aufgabe verhindert weder die folgenden Aufgaben noch den Dienst; der Host kann jederzeit sauber herunterfahren. +Belege: + - [PRIMÄR] src\webservice\Centron.Host\AspNetCore\HostedServices\DataQualityService.cs (ExecuteService: je Aufgabe using (var session = new BLSession()) + try/catch + IsCancellationRequested-Check) - Begründung: durchgesetztes Isolationsmuster. + - [KONTEXT] docs\Background Service\DataQualityService.md (Task Implementation Rules 1-3) - Begründung: dokumentierte Regel deckt sich mit dem Code. +Prüfidee: Eine Aufgabe künstlich fehlschlagen lassen (z. B. ungültige Daten); Log muss den Aufgabenfehler zeigen und die Folgeaufgaben müssen dennoch laufen. +Tracelinks: SyRS-1214 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Datenqualitätsjobs bleiben nötig; einzelne Aufgaben (z. B. Delphi-Altdaten-Reparaturen) sind je Fall auf Relevanz zu prüfen. +Status: belegt +``` + +### SwRS-1241: Datenmodell der Eskalationstypen mit drei Stufen und Empfänger-Bitmaske + +``` +ID: SwRS-1241 +Titel: Datenmodell der Eskalationstypen mit drei Stufen und Empfänger-Bitmaske +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente EscalationTypeSettingViewModel / EscalationBL +Vorbedingung: Eskalationstypen sind gepflegt +Fakt: Ein EscalationTypeDTO umfasst drei Eskalationsstufen mit Fristen (Hour1, Hour2, Hour3) und je Stufe eine als Summe von Empfänger-IDs kodierte Empfängermenge (Stage1Receivers = Σ receiver.ID, GetReceiversInt), Arbeitszeitfenster (WorkTimeFrom/WorkTimeTo), Wochenend-Flags (EscalationSa, EscalationSun) sowie ToDoKind und TicketPriorityI3D; globale Parameter (Zustell-/Löschfristen in Tagen, Absender-/Chef-Mailadresse) liegen als Stammdat-Einstellungen. +Aussage: Die Software soll Eskalationsregeln je Typ als dreistufiges Modell mit stufenspezifischen Fristen (Stunden), stufenspezifischen Empfängergruppen (Bitmasken-Kodierung), Arbeitszeitfenster und Wochenendsteuerung speichern. +Ergebnis: Der Eskalationsdienst kann je überfälligem Vorgang Stufe und Empfängerkreis bestimmen. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\Administration\EscalationsSettings\EscalationType\EscalationTypeSettingViewModel.cs (EscTypeVM_To_DTO: Hour1-3, Stage1-3Receivers = GetReceiversInt, WorkTimeFrom/To, EscalationSa/Sun, TicketPriorityI3D) - Begründung: vollständiges persistiertes Regelmodell. + - [SEKUNDÄR] ebd. init: AppSettingsConst.EscalationDeliveryAfterDays, EscalationDeletedAfterDays, EscalationMailSender, EscChiefMail - Begründung: globale Eskalationsparameter. +Prüfidee: Typ mit Hour1=2, Stage1=Techniker+Chef speichern; DB-Werte prüfen (Bitmaskensumme); Eskalationstestlauf (EscalationTestView) muss die konfigurierten Empfänger liefern. +Tracelinks: SyRS-1215 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Modell ist tragfähig; Bitmasken-Kodierung der Empfänger sollte in der Neuimplementierung durch eine Relationstabelle ersetzt werden. +Status: belegt +``` + +### SwRS-1242: Rechteprüfung und Verschlüsselung der PDF-Signierungseinstellungen + +``` +ID: SwRS-1242 +Titel: Rechteprüfung und Verschlüsselung der PDF-Signierungseinstellungen +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente PdfSigningBL (Server) +Vorbedingung: Benutzer ruft SavePdfSigningSettings auf +Fakt: SavePdfSigningSettings prüft serverseitig currentUser.HasUserRight(UserRightsConst.Administration.SETTINGS) und liefert sonst "Benutzer hat nicht die erforderlichen Rechte." (DefaultMessageCodes.RightCheckFailed); Zertifikat (Base64), Zertifikatspasswort und TSA-Passwort werden vor dem Speichern mit AESCryptoLogic.EncryptText verschlüsselt und beim Lesen entschlüsselt. +Aussage: Die Software soll das Ändern der PDF-Signierungskonfiguration serverseitig auf Benutzer mit dem Recht Administration.SETTINGS (10560) beschränken und Zertifikat sowie Passwörter ausschließlich AES-verschlüsselt in den ApplicationSettings ablegen. +Ergebnis: Unberechtigte Änderungen werden abgewiesen; Schlüsselmaterial liegt nie im Klartext in der DB. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Security\PdfSigningBL.cs (SavePdfSigningSettings, Zeile 60: if (!currentUser.HasUserRight(UserRightsConst.Administration.SETTINGS)) return Result.AsError(...); Zeilen 86-101: _cryptoLogic.EncryptText für Zertifikat und Passwörter) - Begründung: durchsetzende Rechteprüfung und Verschlüsselung an der Serverlogik. +Prüfidee: Aufruf ohne Recht 10560: Fehler RightCheckFailed; nach Speichern DB-Inhalt von PdfSigningCertificate prüfen: kein Klartext-Base64 des PFX. +Tracelinks: SyRS-1216 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Muster (Rechteprüfung + verschlüsselte Secrets) ist verbindlich für die Neuimplementierung; dort besser dedizierter Secret-Store. +Status: belegt +``` + +### SwRS-1243: PDF-Signaturvorgang mit PKCS#7, SHA256 und optionalem TSA-Zeitstempel + +``` +ID: SwRS-1243 +Titel: PDF-Signaturvorgang mit PKCS#7, SHA256 und optionalem TSA-Zeitstempel +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente PdfSigningBL.SignPdfDocument +Vorbedingung: Zertifikat hinterlegt (sonst Fehlermeldung) +Fakt: SignPdfDocument lädt das entschlüsselte PFX, erstellt einen Pkcs7Signer mit HashAlgorithmType.SHA256, bindet bei konfigurierter TsaServerUrl einen TsaClient (mit oder ohne Benutzername/Passwort) ein und schreibt Location, Reason und ApplicationName "c-entron.NET" in die Signatur; ohne gültige Einstellungen wird "Bitte prüfen Sie Ihre Einstellungen für die PDF-Signierung." zurückgegeben. +Aussage: Die Software soll PDF-Dokumente mit PKCS#7-Signatur (SHA256) versehen, dabei optional einen konfigurierten Zeitstempeldienst (TSA, mit optionaler Authentifizierung) einbinden und die konfigurierten Metadaten Ort/Grund in die Signatur übernehmen. +Ergebnis: Signiertes PDF mit prüfbarer Signatur und optionalem qualifizierten Zeitstempel. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Security\PdfSigningBL.cs (SignPdfDocument, Zeilen 138-163: PdfDocumentSigner, TsaClient, Pkcs7Signer(SHA256), PdfSignatureBuilder mit Location/Reason/ApplicationName) - Begründung: vollständiger durchgesetzter Signaturablauf. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\Administration\PdfSigning\PdfSigningSettingsViewModel.cs (DoSignPdfDocumentAsync: Testsignierung mit Dateiname "... (signed).pdf") - Begründung: Admin-Testfunktion des Vorgangs. +Prüfidee: PDF mit TSA-URL signieren und Zeitstempel im Signaturpanel eines PDF-Readers verifizieren; ungültige TSA-URL: definierte Fehlermeldung. +Tracelinks: SyRS-1216 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - kryptographische Parameter (SHA256, PKCS#7, RFC-3161-TSA) bleiben Stand der Technik. +Status: belegt +``` + +### SwRS-1244: Konfigurierbare PDF-Export-Konformitätsstufen und Farbräume + +``` +ID: SwRS-1244 +Titel: Konfigurierbare PDF-Export-Konformitätsstufen und Farbräume +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente PdfExportSettingsViewModel / IPdfExportSettingsLogic +Vorbedingung: Einstellungsmodul geöffnet +Fakt: Für Standard-PDF sind Konformität (0="Keine (PDF 1.5)", 1=PDF/A-1a, 2=PDF/A-2a, 3=PDF/A-2b, 4=PDF/A-2u, 5=PDF/A-3a, 6=PDF/A-3b, 7=PDF/X-3, 8=PDF/X-4), Farbraum (RGB/CMYK), Schrifteinbettung, JPEG-/Allgemein-Kompression, transparente Bilder und Druckoptimierung konfigurierbar; für PDF/A-3 existiert ein zweiter Parametersatz; Defaults sind überwiegend true bzw. 0. +Aussage: Die Software soll die PDF-Erzeugungsparameter (Konformitätsstufe, Farbraum, Schrifteinbettung, Kompression, Transparenz, Druckoptimierung) getrennt für Standard-PDF und PDF/A-3 systemweit konfigurierbar machen und mit definierten Defaults vorbelegen. +Ergebnis: Alle Report-/Belegexporte erzeugen PDFs gemäß der zentralen Konfiguration. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\Administration\PdfExport\PdfExportSettingsViewModel.cs (InitializeDropdownLists, LoadSettings mit Defaults "?? true"/"?? 0", Save mit PdfExportSettingsDTO) - Begründung: vollständiger konfigurierbarer Parametersatz inkl. Defaults. +Prüfidee: Konformität auf PDF/A-3b stellen, Beleg exportieren und mit veraPDF validieren; Einstellung zurücksetzen und Formatwechsel prüfen. +Tracelinks: SyRS-1216 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - getrennte Profile für Standard und PDF/A-3 (ZUGFeRD/XRechnung-Anhänge) sind fachlich begründet. +Status: belegt +``` + +### SwRS-1245: Serverseitige Rechteprüfung für Ad-hoc-SQL im SQL-Manager + +``` +ID: SwRS-1245 +Titel: Serverseitige Rechteprüfung für Ad-hoc-SQL im SQL-Manager +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente ReportDataWebBL.ReportEngineExecuteQuery (Server); SqlManagerViewModel (Client) +Vorbedingung: Benutzer sendet ein SQL-Statement über den SQL-Manager oder die Report-Engine +Fakt: Der Admin-SQL-Manager führt beliebige Statements über IReportLogic.ReportEngineExecuteQuery aus; serverseitig prüft ReportEngineExecuteQuery, ob der aktuelle Benutzer das Recht UserRightsConst.Administration.SQL_MANAGER oder UserRightsConst.Administration.REPORT_MANAGEMENT besitzt, und lehnt sonst mit "Sie haben nicht die benötigten Rechte." (RightCheckFailed) ab. +Aussage: Die Software soll die Ausführung freier SQL-Abfragen über die zentrale Abfrageschnittstelle nur Benutzern mit dem SQL-Manager- oder Report-Management-Recht erlauben und Aufrufe anderer Benutzer serverseitig abweisen. +Ergebnis: Ad-hoc-Datenbankzugriffe sind auf berechtigte Administratoren/Report-Designer beschränkt. +Belege: + - [PRIMÄR] src\backend\Centron.BL\WebServices\ReportEngine\ReportDataWebBL.cs (ReportEngineExecuteQuery, Zeile 493 ff.: if (GetRightsFromCurrentUser(currentUser).Any(f => f.I3D == UserRightsConst.Administration.SQL_MANAGER || f.I3D == UserRightsConst.Administration.REPORT_MANAGEMENT) == false) return AsError(..., RightCheckFailed)) - Begründung: durchsetzende serverseitige Prüfung vor ExecuteQuery. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\Administration\SqlManagers\SqlManagerViewModel.cs (DoExecuteQueryAsync) - Begründung: aufrufendes Admin-Werkzeug. +Prüfidee: REST-Aufruf ReportEngineExecuteQuery mit Benutzer ohne beide Rechte: Ablehnung; mit SQL_MANAGER-Recht: Ergebnis-DataTable. +Tracelinks: SyRS-1212 +Konsolidierung: nein +Übernahmewürdigkeit: Sonderfall - freies SQL im Client ist ein mächtiges Supportwerkzeug; in einer SaaS-Lösung nur stark eingeschränkt (read-only, auditiert) übernehmen. +Status: belegt +``` + +### SwRS-1246: Validierung, globaler Satz und Änderungslog der Stundenzuschlagssätze + +``` +ID: SwRS-1246 +Titel: Validierung, globaler Satz und Änderungslog der Stundenzuschlagssätze +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente HourlySurchargeRatesViewModel / IHourlySurchargeRatesLogic +Vorbedingung: Zuschlagsmodell wird bearbeitet +Fakt: Positionen mit EndTime < StartTime erzeugen den Validierungsgrund "Startzeit ist nach Endzeit."; Modelle mit Validierungsfehlern werden beim Speichern übersprungen (Dialog "hat fehlerhafte Zeiten und kann nicht gespeichert werden"); das als global markierte Modell (GlobalHourlySurchargeRateI3D) kann nicht deaktiviert werden; Deaktivierung ist Statuswechsel (HourlySurchargeRateStatus.Deactivated) mit Bestätigungsdialog; jede Änderung erzeugt einen Log-Eintrag (HourlySurchargeRateLog mit EmployeeI3D, Date, Caption). +Aussage: Die Software soll Zuschlagsmodelle vor dem Speichern auf konsistente Zeitfenster prüfen, das globale Standardmodell gegen Deaktivierung sperren, Deaktivierung als Statuswechsel abbilden und alle Änderungen personen- und zeitbezogen protokollieren. +Ergebnis: Nur konsistente, nachvollziehbar geänderte Zuschlagsmodelle fließen in die Abrechnung ein. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\Administration\HourlySurchargeRates\ViewModels\HourlySurchargeRateItemViewModel.cs (UpdateInvalidRatesReasons: if EndTime < StartTime => "Startzeit ist nach Endzeit.") - Begründung: konkrete Validierungsbedingung. + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\Administration\HourlySurchargeRates\HourlySurchargeRatesViewModel.cs (Save: InvalidRatesReasons-Block verhindert Speichern; DeactivateRate: IsGlobalRate-Sperre, Status = Deactivated) - Begründung: durchgesetzte Speicher- und Sperrregeln (clientseitig). + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, [dbo].[HourlySurchargeRateLog] (EmployeeI3D NOT NULL, Date NOT NULL, RateI3D NOT NULL) - Begründung: Pflichtfelder des Änderungsprotokolls. +Prüfidee: Position mit Start 18:00/Ende 06:00 speichern: Ablehnung mit Meldung; globales Modell deaktivieren: Sperrdialog; gültige Änderung speichern: neuer Log-Eintrag mit Mitarbeiter und Zeit. +Tracelinks: SyRS-1218 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - abrechnungsrelevante Konsistenzregeln; serverseitige Validierung in der Neuimplementierung ergänzen (heute im Client). +Status: belegt +``` + +### SwRS-1247: Zielgruppenlogik der Update-Benachrichtigung + +``` +ID: SwRS-1247 +Titel: Zielgruppenlogik der Update-Benachrichtigung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente UpdateAvailableNotificationBL.ShowUpdatesFor +Vorbedingung: Versionscheck eines angemeldeten Benutzers +Fakt: ShowUpdatesFor wertet UpdateAvailableNotificationKind aus: NoNotification => false; ShowToAdministrators => Benutzer muss einer Administratorengruppe angehören (IsAdministratorGroup); ShowToSelectedEmployees => EmployeeI3D des Benutzers muss in settings.EmployeeI3Ds enthalten sein (Benutzer ohne Mitarbeiter => false); ShowToAllEmployees => true; unbekannte Werte werfen eine Exception. +Aussage: Die Software soll die Entscheidung, ob einem Benutzer ein verfügbares Update gemeldet wird, ausschließlich aus der konfigurierten Benachrichtigungsart und der Gruppen-/Mitarbeiterzuordnung des Benutzers ableiten. +Ergebnis: Deterministische, konfigurationsgetriebene Update-Sichtbarkeit je Benutzer. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\UpdateAvailableNotificationBL.cs (ShowUpdatesFor, Zeilen 97-124: switch über UpdateAvailableNotificationKind) - Begründung: vollständige durchgesetzte Entscheidungslogik. + - [SEKUNDÄR] src\backend\Centron.Interfaces\Administration\Settings\ApplicationSettingID.cs (UpdateAvailableNotificationKind = 10137, UpdateAvailableNotificationEmployees = 10138, UpdateAvailableNotificationSource = 10425) - Begründung: persistierte Konfigurationsfelder. +Prüfidee: Für jede der vier Benachrichtigungsarten je einen Benutzer (Admin, ausgewählter Mitarbeiter, sonstiger) prüfen; Ergebnis-Matrix muss der switch-Logik entsprechen. +Tracelinks: SyRS-1219 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Logik ist klein und klar; Quelle (NuGet-Feed) im SaaS-Kontext neu bewerten. +Status: belegt +``` + +### SwRS-1248: Container-Stack und Windows-Dienst mit gemeinsamem Host-Kern + +``` +ID: SwRS-1248 +Titel: Container-Stack und Windows-Dienst mit gemeinsamem Host-Kern +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Komponenten docker\compose, Centron.Host.Console, Centron.Host.WindowsService +Vorbedingung: Deployment-Ziel (Docker-Host oder Windows-Server) vorbereitet +Fakt: Der Compose-Stack "centron" definiert db (MSSQL, Port 1433), webservice (Centron.Host.Console, Port 4321->1234, HARDWARE_ID-Umgebungsvariable für Lizenzierung, Konfig-Volume WebServiceConfig.xml, restart: on-failure), smtp (Mailcatcher) und nexus (Blazor, Port 8050, appsettings.Production.json); die Windows-Dienst-Variante kapselt denselben CentronHost (Instance.Start/Stop); Versionierung erfolgt zentral über Nerdbank.GitVersioning (version.json "2.0.2611-alpha") und Directory.Build.props (TreatWarningsAsErrors, InformationalVersion mit GitCommitId). +Aussage: Die Software soll den Webservice-Kern deploymentneutral kapseln, sodass er unverändert als Konsolenprozess im Container (mit extern eingespielter XML-/JSON-Konfiguration und Lizenz-Hardware-ID per Umgebungsvariable) und als Windows-Dienst betrieben werden kann; Versionsstände sollen zentral und build-übergreifend (inkl. Commit-ID) vergeben werden. +Ergebnis: Reproduzierbare Deployments mit identischem Verhalten und eindeutig rückverfolgbaren Versionen. +Belege: + - [PRIMÄR] docker\compose\compose.yaml (Services, command /app/Centron.Host.Console, environment HARDWARE_ID, volumes WebServiceConfig.xml) - Begründung: konkreter Container-Betriebsvertrag. + - [PRIMÄR] src\webservice\Centron.Host.WindowsService\CentronService.cs (OnStart/OnStop => CentronHost.Instance.Start/Stop) - Begründung: identischer Kern hinter der Dienst-Fassade. + - [SEKUNDÄR] version.json (Nerdbank.GitVersioning, release.branchName "release/v{version}") und Directory.Build.props (InformationalVersion + GitCommitId) - Begründung: zentrale Versionsvergabe. +Prüfidee: Stack per compose starten und Webservice-Version abfragen; dieselbe Version als Windows-Dienst installieren und identische API-Antworten verifizieren. +Tracelinks: SyRS-1217 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Containerpfad ist Zielbild; XML-Konfigurationsdatei (WebServiceConfig.xml) auf moderne Konfigurationsquellen migrieren. +Status: belegt +``` diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/SyRS.md b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/SyRS.md new file mode 100644 index 00000000..655f21fb --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/SyRS.md @@ -0,0 +1,2893 @@ +# System Requirements Specification (SyRS) + +**System:** c-entron ERP-Suite — Reverse Requirements Engineering aus der Codebasis +**Norm:** ISO/IEC/IEEE 29148:2018 | **Datum:** 2026-08-27 + +Systemsicht: Systemverhalten, Schnittstellen, Performance- und Sicherheitsanforderungen. Jede Anforderung folgt dem Blockformat des Laufs (Fakt = belegte Beobachtung, Aussage = fachliche Interpretation). Anforderungen mit `Status: HYPOTHESE` sind zusätzlich in `Hypothesen.md` gelistet. Die Kapitel entsprechen den Analyse-Clustern A1–A12 (siehe `Analysebericht.md`). + +## A1 — Sicherheit, Identität, Berechtigungen: System-Anforderungen (SyRS) + +### SyRS-101: Durchgängige Berechtigungsprüfung an allen Systemschnittstellen + +``` +ID: SyRS-101 +Titel: Durchgängige Berechtigungsprüfung an allen Systemschnittstellen +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: WPF-Client, REST-Webservice, Business-Logik (BL) +Vorbedingung: Benutzer ist authentifiziert und besitzt eine gültige Sitzung. +Fakt: Rechteprüfungen existieren auf drei Ebenen: im WPF-Client über den Rechte-Cache (CentronCache.CurrentUserAppRights), im Webservice über Autorisierungs-Attribute (AuthorizeUserRight u. a., 401/403) und in der BL über AppRightsBL.HasUserRight/CheckRightsFromUser; die Entwicklerdoku schreibt diese Muster verbindlich vor. +Aussage: Das System soll Berechtigungen an jeder Schnittstelle (Client-UI, Web-API, Geschäftslogik) gegen dasselbe zentrale Rechtemodell prüfen. +Ergebnis: Ein fehlendes Recht führt unabhängig vom Zugriffsweg zur Ablehnung der Operation. +Belege: + - [PRIMÄR] src\webservice\Centron.Controllers\Authorization\AuthorizeUserRightAttribute.cs, UserRightAuthorizationFilter.OnAuthorization: "if (!_requiredRightId.HasValue || !currentUser.HasUserRight(_requiredRightId.Value)) context.Result = new ForbidResult();" - Begründung: durchsetzende Prüfung an der API-Grenze. + - [PRIMÄR] src\backend\Centron.BL\Administration\Rights\AppRightsBL.cs, HasUserRight(...) (SQL über Sichtrus/Sichmemb) - Begründung: durchsetzende Prüfung in der BL. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\FrontWindowViewModel.cs, Zeile 393: "CentronCache.Instance.CurrentUserAppRights?.Any(f => f.I3D == rightI3D)" - Begründung: Client-seitige Prüfung gegen dasselbe Rechtemodell. + - [KONTEXT] docs\guides\development\check-userrights.md - Begründung: dokumentiert die drei Prüfmuster (ViewModel, Modul, BL). +Prüfidee: Für ein Beispielrecht (z. B. Kundenanlage) API-Aufruf, BL-Aufruf und UI-Zugang jeweils ohne das Recht testen; Erwartung: 403 an der API, Result-Fehler in der BL, ausgeblendetes/gesperrtes UI-Element. +Tracelinks: StRS-101 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - mehrschichtige Prüfung ist Best Practice; in SaaS ist die serverseitige Schicht die maßgebliche. +Status: belegt +``` + +### SyRS-102: Administrierbarkeit des Rechtesystems mit Protokollierung + +``` +ID: SyRS-102 +Titel: Administrierbarkeit des Rechtesystems mit Protokollierung +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator (Modul Rechteverwaltung) +Vorbedingung: Benutzer besitzt die Rechte Administration.ID und Administration.UserRightsManagement.ID. +Fakt: Das Modul "Rechteverwaltung" (Centron.WPF.UI\Modules\Administration\RightsManagement) erlaubt Anlegen/Kopieren/Löschen von Rechtegruppen und Zuordnen von Rechten und Benutzern; jede Änderung wird als AppRightLog geschrieben; der Modulzugang ist über ModuleRegistration an die genannten Rechte gebunden. +Aussage: Das System soll eine Administrationsoberfläche bereitstellen, in der berechtigte Administratoren Rechtegruppen verwalten, Rechte und Benutzer zuordnen und alle Änderungen in einem Rechteänderungsprotokoll nachvollziehen können. +Ergebnis: Rechteänderungen sind nur für berechtigte Administratoren möglich und vollständig protokolliert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Rights\AppRightsBL.cs, SaveRightGroup(...): "if (user.HasUserRight(UserRightsConst.Administration.UserRightsManagement.ID) == false) return Result.AsError(\"Sie haben nicht genügend Rechte um eine Gruppe anlegen zu können.\");" - Begründung: durchsetzende Rechteprüfung der Administration. + - [PRIMÄR] src\backend\Centron.BL\Administration\Rights\AppRightsBL.cs, WriteAddRightToGroupLog(...) → WriteBaseLog(AppRightLogKind.AddRightToGroup, ...) sowie GetAllAppRightLogs() - Begründung: Protokollierung jeder Rechtevergabe. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\ModuleRegistration.cs, Zeile 497: Helper.HasRights(UserRightsConst.Administration.ID, UserRightsConst.Administration.UserRightsManagement.ID) - Begründung: Modulzugang nur mit Rechten. +Prüfidee: Als Benutzer ohne UserRightsManagement-Recht Gruppe anlegen (Erwartung: Fehler); als Administrator Recht an Gruppe vergeben und prüfen, dass ein AppRightLog-Eintrag mit Beschreibung "Recht ... an die Gruppe ... vergeben" entsteht. +Tracelinks: StRS-101 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Administrations- und Audit-Funktion ist Kernanforderung jeder Neuimplementierung. +Status: belegt +``` + +### SyRS-103: Sitzungsverwaltung über Tickets mit begrenzter Lebensdauer + +``` +ID: SyRS-103 +Titel: Sitzungsverwaltung über Tickets mit begrenzter Lebensdauer +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Webservice, alle Client-Anwendungen +Vorbedingung: Erfolgreiche Authentifizierung. +Fakt: Nach erfolgreicher Anmeldung erzeugt das System ein Ticket (Session-Token) mit Ablaufdatum (Standard 30 Minuten, Monitoring-Connector 5 Minuten, bestimmte Anwendungen 24 h bzw. konfigurierbar); pro Benutzer/Gerät/Anwendung wird ein bestehendes Ticket wiederverwendet und bei Nutzung verlängert; abgelaufene Tickets werden gelöscht; die Ticketvergabe prüft zudem Lizenzverfügbarkeit. +Aussage: Das System soll Sitzungen über serverseitig verwaltete Tickets mit begrenzter, anwendungsabhängiger Lebensdauer führen, die bei Aktivität verlängert und nach Ablauf ungültig werden. +Ergebnis: Inaktive Sitzungen laufen automatisch ab; API-Aufrufe mit abgelaufenem Ticket werden abgewiesen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\TicketBL.cs: Konstanten TicketExpireInMinutes = 30, TicketMonitoringConnectorExpireInMinutes = 5, TicketExpire24HoursInMinutes = 1440; Methoden GetExpireDate(...), RefreshTicketExpireDate(...), DeleteExpiredTickets() - Begründung: durchsetzende Ablauf- und Verlängerungslogik. + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\Auth\Authenticator.cs, AuthenticateUser(...): GetExistingTicket → CheckLicense → CreateNewTicket (unter Lock) - Begründung: Ticketvergabe inkl. Lizenzprüfung als Teil des Sitzungsaufbaus. +Prüfidee: Anmelden, 31 Minuten warten, API-Aufruf ausführen; Erwartung: Ablehnung/erneute Anmeldung erforderlich; bei regelmäßiger Nutzung bleibt das Ticket gültig. +Tracelinks: StRS-102 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - fachliches Verhalten (Sitzungs-Timeout, Wiederverwendung) übernehmen; technische Umsetzung in SaaS z. B. über Standard-Token-Verfahren. +Status: belegt +``` + +### SyRS-104: Konfigurierbare Authentifizierungsverfahren mit benutzerbezogenem Fallback + +``` +ID: SyRS-104 +Titel: Konfigurierbare Authentifizierungsverfahren mit benutzerbezogenem Fallback +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Administrator, Webservice, Identity Provider (AD/OIDC) +Vorbedingung: Systemweite Authentifizierungsmethode (SystemAuthenticationMethod) ist konfiguriert. +Fakt: Die AuthenticatorFactory wählt das Anmeldeverfahren anhand der Systemeinstellung (None/Basic/ActiveDirectory/OpenIdConnect) und des pro Benutzer gespeicherten AuthentificationKind (Spalte Sichbenu.AuthentificationKind); für Benutzer mit CentronLogin wird ein FallbackAuthenticator auf Basic-Anmeldung geschaltet; AD erfordert die Konfiguration ActiveDirectoryAuthEnabled, OIDC erfordert Lizenz und aktivierte JWT-Einstellungen; die JWT-Konfiguration ist nur mit dem Recht Administration.SETTINGS änderbar. +Aussage: Das System soll das Authentifizierungsverfahren systemweit konfigurierbar machen, pro Benutzer ein abweichendes Verfahren (inkl. lokalem Fallback) unterstützen und Änderungen der Authentifizierungs-Konfiguration auf berechtigte Administratoren beschränken. +Ergebnis: Anmeldungen laufen über das konfigurierte Verfahren; Fehlkonfigurationen führen zu definierten Fehlermeldungen statt zu unautorisiertem Zugang. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\Auth\AuthenticatorFactory.cs, GetAuthenticatorWithSystemAuth(...) und GetAuthenticationKindFromUserName(...) (Query auf AppUser.AuthentificationKind) - Begründung: durchsetzende Verfahrensauswahl inkl. Fallback. + - [PRIMÄR] src\webservice\Centron.Controllers\Controllers\Unversioned\AuthConfigurationController.cs, UpdateJWTConfiguration(...): CheckUserHasRight(..., UserRightsConst.Administration.SETTINGS, "Settings") und HTTPS-Pflicht für Authority - Begründung: geschützte Änderung der Auth-Konfiguration. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, Tabelle Sichbenu: Spalten AuthentificationKind, OpenIdConnectSubjectIdentifier - Begründung: Datenmodell des benutzerbezogenen Verfahrens. +Prüfidee: Systemmethode auf ActiveDirectory stellen und Benutzer mit AuthentificationKind=CentronLogin anmelden (Erwartung: Basic-Fallback greift); JWT-Konfiguration ohne Settings-Recht patchen (Erwartung: Fehler). +Tracelinks: StRS-102 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Multi-Verfahren mit per-User-Steuerung ist für SaaS-Migration (SSO) direkt wiederverwendbar. +Status: belegt +``` + +### SyRS-105: Zwei-Faktor-Authentifizierung systemweit zuschaltbar + +``` +ID: SyRS-105 +Titel: Zwei-Faktor-Authentifizierung systemweit zuschaltbar +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Mitarbeiter, Web-Account-Nutzer, RADIUS-Server, Mail-Server +Vorbedingung: Webservice-Konfiguration TwoFactorAuthEnabled = true; für den Benutzer ist UseTwoFactorAuthentication gesetzt. +Fakt: Bei aktivierter 2FA verlangt der Login zusätzlich eine Bestätigung über einen RADIUS-Server oder einen per E-Mail versendeten Bestätigungslink (TwoFactorAuthType RadiusServer/EmailLink); die Bestätigung wird pro Benutzer, Anwendung, Maschine und IP-Adresse mit Zeitstempel gemerkt und ist für eine konfigurierbare Anzahl von Tagen gültig. +Aussage: Das System soll für Anmeldungen eine optionale Zwei-Faktor-Authentifizierung erzwingen können, deren zweiter Faktor wahlweise über RADIUS oder E-Mail-Link bestätigt wird und deren Gültigkeit gerätebezogen zeitlich begrenzt ist. +Ergebnis: Ohne bestätigten zweiten Faktor schlägt die Anmeldung mit "Die Zwei-Faktor-Authentifizierung ist fehlgeschlagen." fehl. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\TwoFactor\TwoFactorAuthBL.cs, ValidateTwoFactor(...) und HasToValidateTwoFactor(...) (Prüfung UseTwoFactorAuthentication, TwoFactorValidDurationInDays, letzter Login je App/Maschine/IP) - Begründung: durchsetzende 2FA-Entscheidungslogik. + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\Auth\BasicAuthenticator.cs, AuthenticateInternal(): Rückgabe "Die Zwei-Faktor-Authentifizierung ist fehlgeschlagen." (DefaultMessageCodes.TwoFactorAuthFailed) bei twoFactorResult != Success - Begründung: Login wird ohne 2FA-Erfolg abgewiesen. +Prüfidee: 2FA aktivieren, Benutzer mit UseTwoFactorAuthentication anmelden, E-Mail-Link nicht klicken; Erwartung: Login schlägt nach Timeout fehl; nach Klick auf den Link ist die Anmeldung für die konfigurierte Tageszahl auf demselben Gerät ohne erneute 2FA möglich. +Tracelinks: StRS-102 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Konzept übernehmen; E-Mail-Link-Verfahren mit In-Memory-Codes ist für horizontale Skalierung (SaaS) neu zu implementieren. +Status: belegt +``` + +### SyRS-106: Getrennte Identitäten für Mitarbeiter (AppUser) und Kundenportal (WebAccount) + +``` +ID: SyRS-106 +Titel: Getrennte Identitäten für Mitarbeiter (AppUser) und Kundenportal (WebAccount) +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Kunde (Portal-Nutzer), Webservice +Vorbedingung: Web-Account mit Status aktiv und Verknüpfung zu einer aktiven Kontaktperson eines aktiven Kunden. +Fakt: Kundenlogins verwenden die Tabelle WebAccounts (eigene Identität, eigenes Rechtesystem WebAccountsRights/WebRights), nicht Sichbenu; der Login prüft Status == 1 und die Aktivität der verknüpften Kontaktperson, Adresse und des Kunden (inkl. Sperrprüfung); Web-Rechte werden separat über HasWebAccountRight geprüft. +Aussage: Das System soll Kundenportal-Benutzer als eigenständige Identitäten mit eigenem Rechtesystem führen und deren Anmeldung nur zulassen, wenn Konto, zugehörige Kontaktperson und Kunde aktiv und nicht gesperrt sind. +Ergebnis: Deaktivierte Kunden/Kontakte können sich nicht mehr am Portal anmelden; Portalrechte sind unabhängig vom internen Rechtemodell. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\WebAccountBL.cs, LoginWithWebAccount(...): Filter "f.Status == 1 && f.Username.ToUpper() == username.ToUpper() && f.Password == cryptedPw" plus Aktivitätsprüfungen (IsCustomerActiveAndNotLocked, IsAccountActiveAndNotLocked) - Begründung: durchsetzende Anmeldelogik der Portalidentität. + - [PRIMÄR] src\backend\Centron.BL\Administration\Rights\AppRightsBL.cs, HasWebAccountRight(...) mit SQL "SELECT WebRightsI3D ... FROM WebAccountsRights WHERE WebAccountsI3D = :WebAccountI3D" - Begründung: getrennte Rechteprüfung. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE dbo.WebAccounts / dbo.WebAccountsRights - Begründung: getrenntes Datenmodell. +Prüfidee: Web-Account eines gesperrten Kunden anmelden (Erwartung: Ablehnung); Web-Recht entziehen und zugehörige Portalfunktion aufrufen (Erwartung: Ablehnung). +Tracelinks: StRS-102, StRS-101 +Konsolidierung: Kandidat (vermutet): zwei Rechtesysteme (Sichrech/Sichtrus für AppUser vs. WebRights/WebAccountsRights für WebAccounts) bilden das Konzept "Berechtigung" in getrennten Datenhaltungen ab. +Übernahmewürdigkeit: übernehmen - Trennung interner/externer Identitäten ist auch im SaaS-Zielbild sinnvoll (Mandanten-/Portalrollen). +Status: belegt +``` + +### SyRS-107: Kontodeaktivierung verhindert Anmeldung + +``` +ID: SyRS-107 +Titel: Kontodeaktivierung verhindert Anmeldung +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Administrator/Personalverwaltung, Mitarbeiter +Vorbedingung: Benutzerkonto ist manuell deaktiviert, in einem Deaktivierungszeitraum oder der Mitarbeiter ist ausgetreten. +Fakt: ValidateAppUser weist Anmeldungen ab, wenn das Konto per Checkbox deaktiviert ist (IsAccountDisabled), das Tagesdatum im Zeitraum KontoDeakVon/KontoDeakBis liegt oder der Mitarbeiter laut Ein-/Austrittsdatum nicht aktiv ist; alle Authenticator-Varianten nutzen diese Prüfung. +Aussage: Das System soll die Anmeldung deaktivierter Konten sowie ausgeschiedener Mitarbeiter an allen Anmeldekanälen ablehnen, einschließlich zeitgesteuerter Deaktivierungszeiträume (von/bis). +Ergebnis: Deaktivierte Konten erhalten die Fehlermeldung "Mitarbeiterkonto wurde deaktiviert" und keine Sitzung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\Auth\Authenticator.cs, ValidateAppUser(...): Prüfungen user.IsAccountDisabled, AccountDisabledFromDate/AccountDisabledToDate gegen DateTime.Today, _employeeBl.IsActiveEmployeeCompact(user.Employee) - Begründung: durchsetzende Deaktivierungslogik für alle Login-Verfahren. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, Tabelle Sichbenu: Spalten KontoDeakMan, KontoDeakVon, KontoDeakBis, Eintritt, Austritt - Begründung: Datenmodell der Deaktivierung. +Prüfidee: Konto mit KontoDeakVon = gestern, KontoDeakBis = morgen anmelden; Erwartung: Ablehnung; nach Ablauf des Zeitraums: Anmeldung möglich. +Tracelinks: StRS-102 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zeitgesteuerte Kontosperrung ist eine fachlich gewollte Personalprozess-Funktion. +Status: belegt +``` + +### SyRS-108: Passwortmanager mit Lizenz-, Richtlinien- und Protokollpflicht + +``` +ID: SyRS-108 +Titel: Passwortmanager mit Lizenz-, Richtlinien- und Protokollpflicht +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Systemhaus-Mitarbeiter, Passwortmanager-Modul (WPF), Webservice +Vorbedingung: Lizenz "Passwort-Manager" vorhanden; Richtlinien (Guidelines) und Zugriffsbereiche sind gepflegt. +Fakt: Alle Passwortmanager-Operationen prüfen die Lizenz (LicenseGuids.PasswordManager) und Benutzerrechte (ACCESS_GUIDELINE_MANAGEMENT, ACCESS_AREA_MANAGEMENT, EXPORT_ACCESS_AND_PASSWORD_DATA); der Zugriff auf einzelne Zugangsdaten wird über kunden-/mitarbeiterspezifische Richtlinienrechte (Bitflags wie SealBreak, AccessDataVisible, TwoFactorAuthentification) gesteuert; Aktionen werden in PasswordManagerLog festgehalten. +Aussage: Das System soll den Passwortmanager nur mit gültiger Lizenz bereitstellen, jede Verwaltungs- und Zugriffshandlung gegen Modul- und Richtlinienrechte prüfen und in einem Aktionsprotokoll festhalten. +Ergebnis: Unberechtigte Zugriffe auf Richtlinien, Bereiche oder Zugangsdaten werden mit Fehlermeldung abgelehnt; berechtigte Zugriffe sind protokolliert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\PasswordManager\PasswordManagerBL.cs, GetPasswordManagerGuidelines(...): Lizenzprüfung + "if (!userRights.Contains(UserRightsConst.PasswordManager.ACCESS_GUIDELINE_MANAGEMENT)) return ... 'Fehlende Rechte um die Passwort Manager Richtlinien zu verwalten!'" - Begründung: durchsetzende Modul-Rechteprüfung. + - [PRIMÄR] src\backend\Centron.BL\PasswordManager\PasswordManagerBL.cs, GetPasswordManagerCustomersEmployeesRights(...): Aufbau der Bitflag-Richtlinienrechte (PasswordManagerGuidelineRights.SealBreak, AccessDataVisible, ...) aus der DB-Abfrage GetEmployeesRightsForCustomers - Begründung: feingranulare Zugriffssteuerung pro Kunde/Mitarbeiter. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, Tabelle PasswordManagementLog (ActionType, EmployeeI3D, Date, OldValue, NewValue) - Begründung: Protokoll-Datenmodell. +Prüfidee: Benutzer ohne ACCESS_GUIDELINE_MANAGEMENT ruft Richtlinienliste ab (Erwartung: Fehlertext); Zugriff auf Zugangsdaten eines Kunden ohne AccessDataVisible-Richtlinienrecht (Erwartung: Werte nicht sichtbar). +Tracelinks: StRS-103 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Lizenz-Gate ggf. durch SaaS-Plan/Feature-Flag ersetzen. +Status: belegt +``` + +### SyRS-109: DSGVO-Funktionen nur mit dediziertem Recht und Modul-Freischaltung + +``` +ID: SyRS-109 +Titel: DSGVO-Funktionen nur mit dediziertem Recht und Modul-Freischaltung +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Datenschutzverantwortlicher, DSGVO-Modul (WPF) +Vorbedingung: DSGVO-Modul lizenziert/verfügbar (ModuleFeatures), Benutzer mit DSGVO-Rechten. +Fakt: Der Zugang zum DSGVO-Modul ist an ACCESS_DSGVO_MODULE gebunden; die Datenbank-Bereinigung verlangt ACCESS_CLEANUP_DATABASE und IsDsgvoDatabaseCleanupAvailable; die Kontaktlöschung verlangt DSGVO_DELETE_CONTACT (BL-seitig geprüft, UI-seitig als HasContactDeleteRight gespiegelt). +Aussage: Das System soll DSGVO-Lösch- und Bereinigungsfunktionen nur Benutzern mit den dedizierten DSGVO-Rechten anbieten und die Prüfungen serverseitig in der Geschäftslogik durchsetzen. +Ergebnis: Benutzer ohne DSGVO-Rechte sehen das Modul nicht bzw. erhalten bei direktem Aufruf einen Fehler. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\DataSecurity\DataSecurityBL.cs, GetDataSecurityCleanUpStats/DataSecurityExecuteCleanUp: "if (!currentUser.HasUserRight(UserRightsConst.DsgvoModule.ACCESS_CLEANUP_DATABASE) || !ModuleFeatures.IsDsgvoDatabaseCleanupAvailable)" - Begründung: durchsetzende Prüfung der Bereinigungsfunktion. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\ModuleRegistration.cs, Zeile 461: Helper.HasRights(UserRightsConst.DsgvoModule.ACCESS_DSGVO_MODULE) - Begründung: Modulzugang im Client. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\Administration\DSGVO\CentronDataSecurityViewModel.cs, Zeile 158: HasContactDeleteRight aus CurrentUserAppRights - Begründung: UI-Spiegelung des Rechts. +Prüfidee: Benutzer ohne ACCESS_CLEANUP_DATABASE ruft die Bereinigungsstatistik über die BL auf; Erwartung: Fehler-Result; mit Recht: Statistikliste. +Tracelinks: StRS-104, StRS-101 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - dedizierte Datenschutzrechte sind auch im Zielsystem erforderlich. +Status: belegt +``` + +### SyRS-110: [HYPOTHESE] Serverseitige Durchsetzung aller im WPF-Client geprüften Rechte + +``` +ID: SyRS-110 +Titel: [HYPOTHESE] Serverseitige Durchsetzung aller im WPF-Client geprüften Rechte +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: WPF-Client, Webservice, BL +Vorbedingung: Benutzer ist angemeldet, besitzt aber ein bestimmtes Recht nicht. +Fakt: Viele Rechteprüfungen im WPF-Client erfolgen ausschließlich clientseitig über den Rechte-Cache (z. B. RibbonControlExtensions.cs Zeile 265/285, CentronUserFormSettingsManager.cs Zeile 662); für zahlreiche, aber nicht nachweislich alle dieser Funktionen existiert eine korrespondierende BL-/API-Prüfung. +Aussage: Das System soll jedes im Client geprüfte Benutzerrecht zusätzlich serverseitig durchsetzen, sodass ein manipulierter Client keine unberechtigten Operationen ausführen kann. +Ergebnis: Auch bei Umgehung der UI-Prüfungen werden unberechtigte Operationen serverseitig abgelehnt. +Belege: + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Extensions\RibbonControlExtensions.cs, Zeilen 265/285 (nur clientseitige Prüfung via CentronCache.Instance.CurrentUserAppRights) - Begründung: zeigt clientseitige Prüfstellen ohne im selben Pfad sichtbare Server-Prüfung. + - [PRIMÄR] src\backend\Centron.BL\Administration\Rights\AppRightsBL.cs, HasUserRight(...) - Begründung: serverseitiger Mechanismus existiert, seine flächendeckende Anwendung auf alle UI-geprüften Rechte ist jedoch nicht nachgewiesen. +Prüfidee: Stichprobe: für 10 im Client geprüfte Rechte den zugehörigen BL-/API-Pfad ohne Recht direkt aufrufen; Erwartung: serverseitige Ablehnung in allen Fällen. +Tracelinks: StRS-101 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - für die Web-/SaaS-Neuimplementierung ist die vollständige serverseitige Durchsetzung zwingend (Client-Prüfungen nur als UX-Optimierung). +Status: HYPOTHESE +Offene Frage: Existiert für jedes clientseitig geprüfte Recht (insb. UI-Sichtbarkeitsrechte wie EDIT_GLOBAL_PROFILES) eine korrespondierende serverseitige Prüfung in BL oder Webservice? +``` + +## A2 — Finanzen & Abrechnung: System-Anforderungen (SyRS) + +### SyRS-206: Abrechnungsintervalle und Zeitraumfortschreibung + +``` +ID: SyRS-206 +Titel: Abrechnungsintervalle und Zeitraumfortschreibung +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Modul Automatisierte Abrechnung (AutomatedBilling) +Vorbedingung: Vertrag mit BillingIntervalKind (Daily/Monthly/Quarterly/Yearly), BillingIntervalDuration und Abrechnungsart (Vorab-/Nachberechnung) ist aktiv. +Fakt: NextDate() berechnet den nächsten Abrechnungsendtermin je Intervallart; Quartale sind auf Kalenderquartale (1.1./1.4./1.7./1.10.) ausgerichtet; ContractForBilling() entscheidet über Abrechnungsreife anhand LastPaidDate/FirstPaidDate und BillingKinds.Billingadvance/Billingarrear. +Aussage: Das System soll für jeden Vertrag den nächsten Abrechnungszeitraum aus Intervallart, Intervalldauer und bereits abgerechnetem Zeitraum (LastPaidDate) deterministisch fortschreiben und zwischen Vorab- und Nachberechnung unterscheiden. +Ergebnis: Lückenlose, überschneidungsfreie Abrechnungszeiträume je Vertrag. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\CustomerAssets\AutomaticFactura\AutomaticFacturaBL.Contracts.cs, NextDate (Z. 1474–1583) und ContractForBilling (Z. 1596–1627) - Begründung: implementierte Fortschreibungs- und Reifeprüfung. +Prüfidee: Vertrag quartalsweise mit InvoiceTo=15.02. abrechnen; erwarteter nächster Zeitraum endet am 31.03. (Kalenderquartal). +Tracelinks: StRS-201; SwRS-233, SwRS-235, SwRS-236 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kernlogik; Kalenderquartal-Sonderfälle explizit spezifizieren. +Status: belegt +``` + +### SyRS-207: Verknüpfung Rechnung–Vertrag und Kontingentbuchung + +``` +ID: SyRS-207 +Titel: Verknüpfung Rechnung–Vertrag und Kontingentbuchung +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Abrechnungslauf, Vertragsmonitor +Vorbedingung: Abrechnungslauf hat für einen Vertrag eine Rechnung erzeugt. +Fakt: StoreInvoiceToContract() legt je Rechnung einen Datensatz VertragRechKopfZuordnung mit Berechnungszeitraum (BerechnungszeitraumVon/Bis) an; bei Kontingentverträgen bucht StoreBookedContingent() Kontingentwert, Überbuchung und Restmitnahme (GebuchtVon/GebuchtBis, KontingentWert, KontingentUeberbuchung, KontingentRestMitnehmen). +Aussage: Das System soll jede vertragsbasierte Rechnung dauerhaft mit dem Vertrag und dem abgerechneten Zeitraum verknüpfen und bei Kontingentverträgen die gebuchten Kontingente mitführen. +Ergebnis: Vertragsauswertungen und Kontingentstände lassen sich vollständig aus VertragRechKopfZuordnung ableiten. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\CustomerAssets\AutomaticFactura\AutomaticFacturaBL.Contracts.cs, StoreInvoiceToContract (Z. 1258–1337) und StoreBookedContingent (Z. 1098–1245) - Begründung: durchgesetzte Persistierung der Zuordnung. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, Tabelle VertragRechKopfZuordnung (Z. 6161 ff.) und View ContractContingentBooked - Begründung: Datenmodell und Sichtlogik der Kontingentbuchung. +Prüfidee: Kontingentvertrag abrechnen und prüfen, dass genau ein VertragRechKopfZuordnung-Satz mit korrektem GebuchtVon/GebuchtBis und KontingentWert entsteht. +Tracelinks: StRS-201; SwRS-232, SwRS-234, SwRS-236 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zentrale Nachvollziehbarkeitsstruktur. +Status: belegt +``` + +### SyRS-208: Vertragslebenszyklus (Ende, Verlängerung, Auto-Abschluss) + +``` +ID: SyRS-208 +Titel: Vertragslebenszyklus: Ende, Verlängerung, automatischer Abschluss +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Hintergrunddienst/Webservice (Systemuser), Vertragsverwalter +Vorbedingung: Verträge mit Laufzeit, Kündigungsfristen und ggf. Autoverlängerung sind aktiv (VertragKopf.Status=1). +Fakt: RefreshContractEndeDate() berechnet VertragKopf.Ende aus Beginn, LaufzeitArt/-Dauer, AutoVerlaengerung, Verlaengerung und KuendigungsFristArt/-Dauer 1/2 (max. 100 Verlängerungsiterationen) und protokolliert Änderungen im ReceiptLog; CloseContract() schließt Verträge automatisch nur, wenn vollständig abgerechnet (LastBookingTo >= Ende/Kündigung) und das Datum überschritten ist. +Aussage: Das System soll das wirksame Vertragsende unter Berücksichtigung von Kündigungsfristen und automatischer Verlängerung fortlaufend neu berechnen und vollständig abgerechnete, abgelaufene Verträge automatisch abschließen. +Ergebnis: Vertragsenden sind aktuell; kein Vertrag wird vor vollständiger Abrechnung geschlossen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\CustomerAssets\Contracts\ContractBL.cs, RefreshContractEndeDate (Z. 1067–1177) und CloseContract (Z. 1243–1316: Bedingung `LastBookingTo >= ContractEnd && referenceDate > ContractEnd`) - Begründung: durchgesetzte Lebenszykluslogik. +Prüfidee: Vertrag mit Autoverlängerung und Kündigungsfrist 3 Monate: Stichtag innerhalb der Frist → Ende rückt um die Verlängerungsperiode; Vertrag vollständig abrechnen, Enddatum überschreiten → Status wechselt auf Completed mit ReceiptLog-Eintrag. +Tracelinks: StRS-201; SwRS-230, SwRS-231 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - fachlich unverzichtbar; Iterationsgrenze (100) als Schutzmechanismus dokumentieren. +Status: belegt +``` + +### SyRS-209: Click-/Zählerabrechnung für Geräte + +``` +ID: SyRS-209 +Titel: Click-/Zählerabrechnung für Geräte +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Modul DeviceClickCounter, SNMP-/DocuForm-Import, Abrechnungslauf +Vorbedingung: Geräte (MasterDataList/Stammblätter) mit Zählern (DeviceClickCounter) sind Verträgen zugeordnet. +Fakt: Zählerstände werden importiert (DeviceClickCounterImported, IsMatched-Flag), historisiert (DeviceClickCounterHistory mit OldState/Newstate/IsStartValue) und beim Abrechnungslauf über UpdClickCounterHistory mit der Rechnungsposition (RechPosI3D) verknüpft. +Aussage: Das System soll Gerätezählerstände (z. B. Druckerclicks) importieren, je Gerät historisieren und die Differenzmengen im Abrechnungslauf vertrags- und rechnungspositionsbezogen fakturieren. +Ergebnis: Jeder abgerechnete Zählerstand ist einer Rechnungsposition zugeordnet; die Historie ist lückenlos. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\CustomerAssets\Contracts\ClickContracts\DeviceClickCounterBL.cs, UpdateDeviceClickCounterValues (Z. 536–599) - Begründung: durchgesetzte Historisierung mit Start-/Folgewerten. + - [PRIMÄR] src\backend\Centron.BL\Sales\CustomerAssets\AutomaticFactura\AutomaticFacturaBL.Contracts.cs, StoreInvoiceToContract → UpdClickCounterHistory (Z. 1248–1308) - Begründung: Verknüpfung Zähler → Rechnungsposition beim Abrechnungslauf. +Prüfidee: Zählerstand erfassen, Click-Vertrag abrechnen und prüfen, dass die Historieneinträge das RechPosI3D der neuen Rechnung tragen. +Tracelinks: StRS-201; SwRS-251 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - MSP-Kernfunktion (Managed Print Services). +Status: belegt +``` + +### SyRS-210: Abrechnung von Ticketzeiten (TimerBilling) + +``` +ID: SyRS-210 +Titel: Abrechnung von Ticketzeiten (TimerBilling) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Modul TimerBilling, Helpdesk-Zeiterfassung +Vorbedingung: Abrechenbare (Calculable) Helpdesk-Zeiten ohne Belegzuordnung existieren. +Fakt: SearchTimers() lädt Zeiten über NamedQuery GetTimerForTimerBilling mit Filtern (nur berechenbar, Zeitraum, Kunde, Filiale, BillingState) und blendet Zeiten aus Pauschalaufträgen aus (`OrderItems.All(d => d.IsFlatRateItem == false)`); Zuschlagssätze (HourlySurchargeRate) werden je Vertrag oder global ermittelt. +Aussage: Das System soll abrechenbare Ticketzeiten filterbar bereitstellen, Pauschal-Zeiten von der Einzelabrechnung ausschließen und vertragliche Stundenzuschläge (z. B. Notdienst) automatisch berücksichtigen. +Ergebnis: Nur tatsächlich abzurechnende Zeiten mit korrekten Zuschlägen gelangen in die Faktura. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\CustomerAssets\TimerBilling\TimerBillingBL.cs, SearchTimers (Z. 233–383, Flatrate-Ausschluss Z. 380) und SetHourlySurchargeRateOverlaps (Z. 385–417) - Begründung: durchgesetzte Selektions- und Zuschlagslogik. +Prüfidee: Zeit in einem Pauschalauftrag erfassen; sie darf ohne „ShowFlatRateHelpdesks" nicht in der TimerBilling-Liste erscheinen. +Tracelinks: StRS-201; SwRS-254 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - verhindert Doppelabrechnung von Pauschalleistungen. +Status: belegt +``` + +### SyRS-211: Mahn- und OPOS-Läufe mit Versand + +``` +ID: SyRS-211 +Titel: Mahn- und OPOS-Läufe mit dokumentbasiertem Versand +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Module Dunning und Opos, Reportengine, Mailversand +Vorbedingung: Benutzer besitzt das Mahnwesen-Recht; Reportgruppen MAHNUNG bzw. OPOS haben Default-Reports für Mail/Druck. +Fakt: ExecuteDunningRun/ExecuteOposRun erzeugen je Kunde ein PDF (Report „Mahnung_…pdf" bzw. „Kontoauszug_…pdf") mit Parametern (@CustomerI3D, @InvoiceI3Ds, @Opos=0/1) und optional eine Mail inkl. Belegkopien als Anhang; fehlender Default-Report oder ungültiger SendType führt zur Exception; Mahn- und OPOS-Lauf teilen dieselbe Datenstruktur DunningRunForCustomer. +Aussage: Das System soll Mahnungen und OPOS-Kontoauszüge je Kunde als PDF aus konfigurierten Reportvorlagen erzeugen und wahlweise drucken oder per E-Mail (mit optionalen Rechnungs-/Gutschriftskopien) versenden; ohne gültige Vorlage soll der Lauf abgewiesen werden. +Ergebnis: Versandfertige, vorlagenkonforme Mahn-/OPOS-Dokumente; kein Lauf ohne Vorlage. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\Dunning\DunningRunBL.cs, GenerateReport (Z. 317–353: `if (defaultReport?.ReportDataI3D == null) throw ...`) - Begründung: erzwungene Vorlagenbindung. + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\Opos\OposRunBL.cs, ExecuteOposRun (Z. 58–90, @Opos="1", Dateiname "Kontoauszug_...") - Begründung: OPOS nutzt denselben Mechanismus mit eigenem Reportschalter. +Prüfidee: Reportgruppe MAHNUNG ohne Mail-Default konfigurieren und Mahnlauf mit SendType=Mail starten; erwartet: Abbruch mit Fehlermeldung. +Tracelinks: StRS-202; SwRS-237, SwRS-238, SwRS-241 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - gemeinsame Codebasis für Mahnung/OPOS ist tragfähiges Muster. +Status: belegt +``` + +### SyRS-212: OPOS-/Mahn-Übersicht mit Salden und Filtern + +``` +ID: SyRS-212 +Titel: OPOS-/Mahnübersicht mit Salden, Mahnstufenfiltern und Toleranz +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Module Dunning/Opos (Übersicht), Controlling +Vorbedingung: Aktive Rechnungen (ReceiptState.Active) und Gutschriften existieren. +Fakt: GetDunningCustomers/CalculateDunningStatistics aggregieren je Kunde offene Rechnungen und Gutschriften; offene Beträge werden als GrossPriceComplete − PayedGrossAmount − CreditVoucherGrossAmount berechnet; Filter umfassen Mahnstufen, Fälligkeit, Toleranztage (NextDueDateInDays < −Toleranz) und Mahnsperre. +Aussage: Das System soll offene Posten je Kunde inklusive Gutschriftenverrechnung aggregieren und nach Mahnstufe, Fälligkeit, Filiale, Toleranztagen und Mahnsperre filterbar machen. +Ergebnis: Korrekte OPOS-Salden und Mahnvorschlagslisten. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\Dunning\DunningBL.cs, CalculateDunningStatistics (Z. 184–237) und GenerateInvoiceExpression (Z. 267–317) - Begründung: implementierte Saldo- und Filterlogik. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, View cvw_InvoiceDunning (Z. ~19820 ff.: PayedGrossAmount/CreditVoucherGrossAmount-Berechnung) - Begründung: Saldenformel in der Datenbanksicht. +Prüfidee: Rechnung 1000 € mit Gutschrift 200 € und Zahlung 300 €: OPOS-Restbetrag muss 500 € betragen. +Tracelinks: StRS-202; SwRS-243 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Saldenformel ist fachliche Kernregel. +Status: belegt +``` + +### SyRS-213: Zahlungseingänge und Rechnungsausgleich + +``` +ID: SyRS-213 +Titel: Zahlungseingänge erfassen, löschen und Rechnungsausgleich zurückrechnen +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Modul Payments/IncomingPayments, Rechnungswesen +Vorbedingung: Rechnung existiert; Benutzer hat das Recht Zahlungseingang (10980). +Fakt: PaymentsBL speichert IncomingPayment/OutgoingPayment je Rechnung; DeleteIncomingPayment prüft das Recht, summiert die zu löschenden Beträge je Rechnung und ruft UpdateReceiptIsPaid mit negativem Betrag und Log-Text „Zahlungseingang gelöscht" auf; IncomingPaymentLog protokolliert Zahlungsläufe mit fortlaufender Nummer. +Aussage: Das System soll Zahlungsein- und -ausgänge je Rechnung führen; beim Löschen eines Zahlungseingangs soll der Zahlstatus der Rechnung entsprechend zurückgerechnet und der Vorgang protokolliert werden. +Ergebnis: Zahlstatus der Rechnungen bleibt auch nach Korrekturen konsistent. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Finances\Payments\PaymentsBL.cs, DeleteIncomingPayment (Z. 38–78) - Begründung: Rechteprüfung + Rückrechnung als durchgesetzte Regel. + - [SEKUNDÄR] src\backend\Centron.BL\Finances\IncomingPayments\IncomingPaymentBL.cs, CreateIncomingPaymentLogItem/GetNewIncomingPaymentLogNumber (Z. 21–33) - Begründung: Protokollierung der Zahlungsläufe. +Prüfidee: Zahlung 100 € auf Rechnung buchen, löschen (ohne DontChangeInvoice); PayedGrossAmount muss wieder um 100 € sinken und ein Logeintrag existieren. +Tracelinks: StRS-202, StRS-205; SwRS-242 +Konsolidierung: Kandidat: OnlineBankingTransactionAssignments (SwRS-247) — zwei getrennte Persistenzwege für „Zahlung auf Rechnung" (IncomingPayments vs. Bankauszugszuordnung). +Übernahmewürdigkeit: übernehmen - Rückrechnungslogik übernehmen; Zahlungswege in Neuimplementierung vereinheitlichen. +Status: belegt +``` + +### SyRS-214: Bankauszugsimport und automatischer Zahlungsabgleich + +``` +ID: SyRS-214 +Titel: Bankauszugsimport und automatischer Zahlungsabgleich +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Modul OnlineBanking, Bankquellen (FinTS, finAPI, Spreadsheet) +Vorbedingung: OnlineBankingConfiguration (Typ FinTS/FinAPI/Spreadsheet) ist eingerichtet. +Fakt: Kontoumsätze werden je Konfiguration importiert (Duplikatprüfung), automatisch Kunden und Rechnungen zugeordnet (AutoCompleteAccountTransacitons mit gestuften Heuristiken und MatchingRate) und per BookAmountsForAccountTransacitons auf Rechnungen gebucht bzw. Gutschriften geschlossen; Stornierung (UndoBooking) ist möglich; ein „OnlineBankingInspector" prüft Konsistenz (fehlende Completed-/Booked-Flags) und kann reparieren. +Aussage: Das System soll Kontoumsätze aus mehreren Bankquellen importieren, automatisch mit Kunden und offenen Belegen abgleichen, Buchungen (inkl. Storno) durchführen und Inkonsistenzen zwischen Umsatz, Zuordnung und Belegstatus erkennen. +Ergebnis: Weitgehend automatischer Zahlungsabgleich mit nachvollziehbarem, reparierbarem Buchungszustand. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Finances\OnlineBanking\OnlineBankingAccountTransactionsBL.cs, AutoCompleteSingleAccountTransaciton (Z. 581–617), BookAmountsForAccountTransacitons (Z. 883–921), ExecuteOnlineBankingInspectorCheck (Z. 1093 ff.) - Begründung: durchgesetzte Import-, Matching-, Buchungs- und Prüf-Pipeline. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, Tabellen OnlineBankingAccountTransactions, OnlineBankingTransactionAssignments, OnlineBankingConfigurations(+FinApi/FinTS/Spreadsheet) - Begründung: Datenmodell der Pipeline inkl. Konfigurationstypen. +Prüfidee: Umsatz mit Rechnungsnummer im Verwendungszweck importieren; erwartet: Zuordnung mit Heuristik „MatchedInvoiceNumbers", nach Buchung IsBooked=true und Rechnung bezahlt. +Tracelinks: StRS-202; SwRS-244, SwRS-245, SwRS-246, SwRS-247, SwRS-248 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - hoher Automatisierungswert; Heuristiken explizit spezifizieren. +Status: belegt +``` + +### SyRS-215: Externe Schnittstelle finAPI + +``` +ID: SyRS-215 +Titel: Externe Schnittstelle finAPI (Kontozugriff) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Centron.APIs.FinAPI-Client, finAPI-Dienst (sandbox/live.finapi.io) +Vorbedingung: Lizenz OnlineBanking_FinApi vorhanden; finAPI-Benutzerkonto je Mandant. +Fakt: FinApiClient implementiert die finAPI-REST-v2-Endpunkte (OAuth-Token client_credentials/password, users, bankConnections, accounts, transactions) und den WebForm-Flow für den Import von Bankverbindungen; OnlineBankingFinApiBL gibt Client-Credentials nur bei Lizenz heraus, wobei ClientId/ClientSecret als Konstanten im Quellcode stehen. +Aussage: Das System soll Bankverbindungen und Kontoumsätze über die finAPI-REST-Schnittstelle (inkl. WebForm für PSD2-Autorisierung) importieren; der Zugriff soll lizenzgebunden sein. +Ergebnis: Umsatzimport ohne eigene FinTS-Infrastruktur; Bankautorisierung über finAPI-WebForm. +Belege: + - [PRIMÄR] src\apis\Centron.APIs.FinAPI\FinApiClient.cs (ImportNewBankConnection Z. 149 ff., LoadAccountTransactions Z. 266 ff.) und FinApiConstants.cs (URLs, api/v2-Pfade) - Begründung: implementierte Schnittstellenverträge. + - [PRIMÄR] src\backend\Centron.BL\Finances\OnlineBanking\OnlineBankingFinApiBL.cs, GetFinApiClientCredentials (Z. 29–50: `hasFinApiLicense`-Gate; hartkodierte ClientId/ClientSecret Z. 43–46) - Begründung: Lizenzbindung und Credential-Handling. +Prüfidee: Aufruf GetFinApiClientCredentials ohne Lizenz: DTO ohne ClientId/Secret; mit Lizenz: gefüllte Credentials und erfolgreicher Token-Abruf gegen Sandbox. +Tracelinks: StRS-202, StRS-205; SwRS-244 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - Schnittstelle übernehmen, aber hartkodierte OAuth-Client-Secrets im Quellcode sind ein Sicherheitsrisiko und müssen in der Neuimplementierung in eine Geheimnisverwaltung wandern. +Status: belegt +``` + +### SyRS-216: Multiformat-Buchhaltungsexport + +``` +ID: SyRS-216 +Titel: Multiformat-Buchhaltungsexport (DATEV u. a.) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Modul BookKeeping/DatevOnline2020, FiBu-Zielsysteme +Vorbedingung: BookKeepingExportConfiguration mit BookKeepingType ist angelegt. +Fakt: InvokeExportClass() wählt aus 13 Exportimplementierungen (Europa3000, Sage50Rewe, LexwarePro2011, Schilling AS400, GDI, DatevXmlOnline, Navision, DatevAscii, SageOfficeLine, CustomInterface, Abacus, SAP, Addison); exportierbar sind Kunden-/Lieferantenstammdaten, Belegbuchungsdaten und Kassenbuch; DATEV-Belegtransfer (DatevOnline2020) ist lizenzgebunden. +Aussage: Das System soll Stammdaten- und Buchungsdatenexporte in konfigurierbaren Zielformaten erzeugen, inklusive eines frei definierbaren Custom-Interfaces und eines lizenzpflichtigen DATEV-Online-Belegtransfers (XML + PDF). +Ergebnis: FiBu-kompatible Exportdateien je konfiguriertem Zielsystem. +Belege: + - [PRIMÄR] src\backend\Centron.BL\DataExchange\BookKeeping\BookKeepingExportBL.cs, InvokeExportClass (Z. 1574–1607) und GetDatevOnlinePackageForExport (Z. 1560–1570: Lizenzprüfung LicenseGuids.DatevOnline) - Begründung: Formatauswahl und Lizenzbindung im Code. +Prüfidee: Konfiguration DatevAscii anlegen, Rechnung exportieren, Datei gegen DATEV-ASCII-Formatvorgaben prüfen. +Tracelinks: StRS-203; SwRS-249, SwRS-250 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Pluggable-Export-Architektur als Vorbild; Zielformate nach Bedarf reduzieren. +Status: belegt +``` + +### SyRS-217: SEPA-Mandat-Onlineprozess + +``` +ID: SyRS-217 +Titel: SEPA-Mandat: Online-Unterschrift, Statusführung, Benachrichtigung +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Modul SepaContract, Kundenportal (SBO/Nexus-URL), Mailsystem +Vorbedingung: SEPA-Vertragsvorlage (Word) und Standardbenutzer für Verträge sind konfiguriert. +Fakt: Der Mandatslink wird als `{baseUrl}/contractmanagement?guid={guid}` aus den SepaContractSettings gebildet (OnlinePdfDocuments.Guid ist UNIQUE); Confirm() erzeugt PDF/A-3b, ersetzt Variablen (@@Iban@@, @@Mandatsreferenz@@, @@Gläubigeridentifikationsnummer@@ …), versendet Bestätigungsmails an Unterzeichner und Ersteller und setzt State=Accepted; Decline() speichert DeclineReason und State=Declined; SetExpired() setzt State=LinkExpired; TestMode-Verträge werden nach Durchlauf gelöscht. +Aussage: Das System soll SEPA-Mandate über einen eindeutigen, ablauffähigen Online-Link unterschreiben oder ablehnen lassen, alle Beteiligten per E-Mail benachrichtigen und den Mandatsstatus (angenommen/abgelehnt/abgelaufen) führen; Testdurchläufe dürfen keine Echtdaten hinterlassen. +Ergebnis: Vollständig dokumentierter Mandatsprozess mit revisionsfähigem PDF. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Documents\Dsgvo\SepaContractOnlinePdfDocumentHandler.cs, Confirm/Decline/SetExpired (Z. 78–223) und BuildContractLink (Z. 495–504) - Begründung: durchgesetzter Zustands- und Benachrichtigungsfluss. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, Tabelle OnlinePdfDocuments (UNIQUE CLUSTERED auf Guid, ExpirationDate) - Begründung: DB-Constraint sichert Eindeutigkeit des Signaturlinks. +Prüfidee: Mandat im TestMode durchlaufen; erwartet: Mails mit Präfix „TEST:", Vertrag anschließend gelöscht; im Echtmodus: Status Accepted und archiviertes PDF. +Tracelinks: StRS-204; SwRS-252 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Prozess inkl. TestMode-Konzept. +Status: belegt +``` + +### SyRS-218: Serverseitige Rechte- und Lizenzprüfung der Finanzmodule + +``` +ID: SyRS-218 +Titel: Serverseitige Rechte- und Lizenzprüfung der Finanzmodule +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: Sicherheit +Akteur: BL-Schicht (AppRightsBL, LicenseManager), alle Finanz-Clients +Vorbedingung: Benutzer ist angemeldet (LoggedInUser). +Fakt: Mahn- und OPOS-Operationen rufen ThrowIfUserHasInsufficentRights (Recht 10971) vor jeder Datenlieferung/-änderung auf; Zahlungseingangslöschung prüft Recht 10980; Zeitenänderung prüft EDIT_TIME/OWN_TIME_EDIT inkl. Web-Account-Sperre; FinAPI und DATEV-Online sind lizenzgeprüft. Für die Onlinebanking-Rechte 20800147–20800151 wurde nur eine clientseitige Prüfung gefunden. +Aussage: Das System soll alle lesenden und schreibenden Finanzoperationen serverseitig gegen Benutzerrechte prüfen und lizenzpflichtige Integrationen (finAPI, DATEV-Online, Mahnwesen) nur bei gültiger Lizenz ausführen. +Ergebnis: Kein Zugriff auf Finanzfunktionen an der Rechteprüfung vorbei. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\Opos\OposBL.cs, ThrowIfUserHasInsufficentRights (Z. 28–36) - Begründung: OPOS erzwingt das Mahnwesen-Recht serverseitig. + - [PRIMÄR] src\backend\Centron.BL\WebServices\Sales\Support\HelpdeskTimerWebServiceBL.cs, ThrowIfUserDoesntHaveRightToChangeHelpdeskTimers (Z. 348–376: Web-Account-Sperre, EDIT_TIME, OWN_TIME_EDIT) - Begründung: mehrstufige Durchsetzung bei abrechnungsrelevanten Zeiten. + - [KONTEXT] src\backend\Centron.BL\Administration\Scripts\ScriptMethods\Scripts\ScriptMethod11560.cs - Begründung: Anlage der Onlinebanking-Rechte inkl. Beschreibungstexte. +Prüfidee: Für jede Finanz-Webservice-Methode Negativtest mit Benutzer ohne Recht; erwartet: RightCheckFailed/Exception statt Daten. +Tracelinks: StRS-205; SwRS-242, SwRS-248, SwRS-254 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Muster „Rechteprüfung in BL" übernehmen und auf alle Module (insb. Onlinebanking) ausdehnen. +Status: belegt +``` + +## A3 — Vertrieb & Belegwesen: SyRS (System-Anforderungen) + +### SyRS-310: Belegweiterverarbeitung nach Zulässigkeitsmatrix + +``` +ID: SyRS-310 +Titel: Belegweiterverarbeitung nach Zulässigkeitsmatrix +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertriebsmitarbeiter; Komponente ReceiptBL/SpecificLogics +Vorbedingung: Mindestens ein Quellbeleg ist ausgewählt; Benutzer hat Anlagerecht für die Zielbelegart. +Fakt: CanForwardReceiptsInto() schneidet die erlaubten Zielbelegarten aller gewählten Quellbelege (Durchschnittsmenge); ValidateReceiptForwarding() lehnt unzulässige Ziele mit Fehlermeldung ab („... kann nicht in eine(n) ... weiterverarbeitet werden."). +Aussage: Das System soll je Belegart nur die fachlich zulässigen Zielbelegarten zur Weiterverarbeitung anbieten und jede unzulässige Weiterverarbeitung serverseitig ablehnen; bei Mehrfachauswahl gilt die Schnittmenge der Zulässigkeiten. +Ergebnis: Nur konsistente Belegketten (z. B. Angebot→Auftrag/Lieferschein/Rechnung; Rechnung→Gutschrift; Gutschrift→nichts) entstehen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, Methoden CanForwardReceiptsInto() (Zeile 1350) und ValidateReceiptForwarding() (Zeile 2462, Prüfung `canForwardToReceipts.Contains(targetReceiptKind) == false`) - Begründung: durchsetzende Matrixprüfung. + - [SEKUNDÄR] Fehlermeldungstexte in ValidateReceiptForwarding (u. a. „Es können keine gemischten Kunden- und Lieferantenbelege weiterverarbeitet werden.") - Begründung: belegt die Systemreaktion. +Prüfidee: API-/BL-Aufruf ForwardReceipt von Gutschrift → Rechnung muss mit Fehlermeldung enden; Angebot → Auftrag muss gelingen. +Tracelinks: StRS-301 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - verhindert inkonsistente Belegketten. +Status: belegt +``` + +### SyRS-311: Beleg-Statusmodell mit automatischem Abschluss und Versionierung + +``` +ID: SyRS-311 +Titel: Beleg-Statusmodell mit automatischem Abschluss und Versionierung +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System (ReceiptBL); Vertriebsmitarbeiter +Vorbedingung: Beleg existiert; Positionen mit Gesamt- und verarbeiteter Menge. +Fakt: ReceiptState kennt genau die Zustände offen(1)/abgeschlossen(2)/storniert(3); AutomaticallyCloseReceiptHelperBL setzt Belege bei vollständig verarbeiteter Menge automatisch auf Completed bzw. wieder auf Active; Änderungen an gespeicherten Belegen erfolgen über CreateNewVersion mit Sperr- und Plausibilitätsprüfungen. +Aussage: Das System soll jeden Beleg in genau einem der Zustände „offen", „abgeschlossen", „storniert" führen, Belege bei vollständiger Verarbeitung automatisch abschließen bzw. bei Restmengen wieder öffnen, und inhaltliche Änderungen nur als neue Belegversion zulassen. +Ergebnis: Konsistente Statusführung; Belegänderungen historisiert über Versionen. +Belege: + - [PRIMÄR] src\backend\Centron.Interfaces\Sales\Receipts\ReceiptState.cs (Enum Active/Completed/Canceled) - Begründung: Zustandsraum ist im Typsystem festgelegt. + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Internal\AutomaticallyCloseReceiptHelperBL.cs, Methoden TryAutomaticallyCloseReceipt()/TryAutomaticallyOpenReceipt() - Begründung: automatische Statusübergänge. + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, Methode CreateNewVersion() (Zeile 3068, `receipt.Version = currentReceiptVersion.Version + 1`) - Begründung: Versionierungsregel. +Prüfidee: Auftrag vollständig in Lieferschein weiterverarbeiten → Status „abgeschlossen"; Menge im Folgebeleg reduzieren → Auftrag wieder „offen". +Tracelinks: StRS-301 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Statusmodell ist einfach und tragfähig. +Status: belegt +``` + +### SyRS-312: Belegnummernvergabe aus konfigurierbaren Nummernkreisen + +``` +ID: SyRS-312 +Titel: Belegnummernvergabe aus konfigurierbaren Nummernkreisen +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System (NumberGroupBL, MandatoryBL); Administrator (Konfiguration) +Vorbedingung: Nummernkreise (Tabelle Nummernkreis) je Belegart, Mandant und optional Filiale sind gepflegt. +Fakt: UpdateReceiptNumber() ermittelt die NumberGroup über die belegartspezifische SpecificLogic (GetNumberGroup) und die Filiale des Belegs; GetNextNumber() vergibt die nächste freie Nummer nebenläufigkeitssicher (bedingtes UPDATE auf Current) und überspringt bereits in der Zieltabelle vorhandene Nummern; Barbelege und Belegvorlagen nutzen eigene Kreise. +Aussage: Das System soll Belegnummern je Belegart, Mandant und Filiale aus konfigurierbaren Nummernkreisen vergeben; die Vergabe muss auch bei parallelen Speichervorgängen eindeutige, noch nicht verwendete Nummern liefern. +Ergebnis: Eindeutige Belegnummern ohne Doppelvergabe; getrennte Kreise u. a. für Angebot, Auftrag, Lieferschein, Rechnung, Barrechnung, Gutschrift, interne Rechnung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Company\NumberGroupBL.cs, Methode GetNextNumber() (Zeile 62 ff., `Where(f => f.I3D == ... && f.Current == ...).UpdateBuilder().Set(s => s.Current, nextNumber)` mit rowCount-Prüfung in Schleife) - Begründung: durchgesetzte Konkurrenzsicherung. + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, Methode UpdateReceiptNumber() (Zeile 7265, Filial-/Template-Logik) - Begründung: Zuordnung Belegart→Nummernkreis. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, Tabelle dbo.Nummernkreis (Zeile 45508: NummerArt, MandantI3D, BereichVon/Bis, Aktuell, Intervall, FilialI3D) - Begründung: Datenmodell der Nummernkreise. +Prüfidee: Zwei parallele SaveReceipt-Transaktionen für Rechnungen ausführen; beide erhalten unterschiedliche Nummern; Nummernkreis „Aktuell" ist konsistent. +Tracelinks: StRS-301, StRS-302 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Mechanik solide; die COUNT(*)-Lückensuche per SQL-String sollte in der Neuimplementierung parametrisiert/atomar erfolgen. +Status: belegt +``` + +### SyRS-313: Mehrwertsteuerberechnung je Steuersatz mit definierter Rundung + +``` +ID: SyRS-313 +Titel: Mehrwertsteuerberechnung je Steuersatz mit definierter Rundung +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System (ReceiptPriceHelper); Buchhaltung +Vorbedingung: Beleg mit Artikel-/Rabattpositionen, jede Position mit MwSt-Satz. +Fakt: CalculateReceiptVatPrices() gruppiert Positionen nach Steuersatz und rundet die Steuersumme je Gruppe auf 2 Nachkommastellen (MidpointRounding.AwayFromZero); Einzelpreise werden mit positionsspezifischer Precision gerundet (Precision -1 = ungerundet); Barbelege berechnen die Steuer brutto-basiert; optional wird der Bruttobetrag auf 0,05 CHF gerundet (AppSetting CommercialRoundCH); skonto-ausgeschlossene Positionen (NoEarlyPaymentDiscountAllowed) werden separat summiert. +Aussage: Das System soll Netto-, Steuer- und Bruttobeträge je Steuersatzgruppe berechnen, dabei kaufmännisch auf 2 Nachkommastellen runden (AwayFromZero), Barbelege und Fremdwährung korrekt behandeln und für die Schweiz optional auf 5 Rappen runden. +Ergebnis: Deterministische Belegsummen inkl. MwSt-Splitting als Basis für Rechnung, FiBu-Export und E-Rechnung. +Belege: + - [PRIMÄR] src\webservice\Centron.WebServices.Core\Helper\ReceiptPriceHelper.cs, Methoden CalculateReceiptVatPrices()/CalculateNetPrice()/CalculateTaxPrice() (Zeilen 61/202/232) - Begründung: vollständige Berechnungs- und Rundungsregeln im Code. + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptPriceHelperBL.cs (Zeile 40: `GetSettings(AppSettingsConst.CommercialRoundCH)`) - Begründung: Schalter für Schweizer Rundung. +Prüfidee: Beleg mit Positionen zu 19 % und 7 % anlegen; Steuerbeträge je Gruppe gegen Referenzrechnung (AwayFromZero, 2 NK) prüfen; mit CommercialRoundCH=true Brutto auf 0,05-Raster prüfen. +Tracelinks: StRS-302 +Konsolidierung: Kandidat: Berechnung liegt in Centron.WebServices.Core\Helper\ReceiptPriceHelper.cs, wird aber vom WPF-Backend über ReceiptPriceHelperBL mitgenutzt (eine Logik, im „falschen" Modul platziert; zusätzlich existiert CalculationUtils.CalculateNetTotalPrice in InvoiceSpecificLogic.GetNumberGroup als zweiter Rechenpfad). +Übernahmewürdigkeit: übernehmen - Regeln fachlich korrekt; Codeort konsolidieren. +Status: belegt +``` + +### SyRS-314: Revisionssichere Rechnung: Storno und Festschreibung + +``` +ID: SyRS-314 +Titel: Revisionssichere Rechnung: Storno und Festschreibung +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Buchhaltung; System (ReceiptInvoiceBL) +Vorbedingung: Rechnung existiert; Benutzer authentifiziert. +Fakt: CancelInvoice() verlangt das Recht RIGHT_RECHNUNGSTORNIEREN und verweigert Storno bei: bereits storniert, Barrechnung, bereits weiterverarbeitet, bereits FiBu-exportiert, nicht letzte Vertragsrechnung; der Storno erzeugt eine neue Version mit Menge 0 und Status Canceled und wird protokolliert. FixInvoice() setzt IsFixed=1 auf RechKopf und schreibt einen ReceiptLog-Eintrag. +Aussage: Das System soll Rechnungen nur unter dokumentierten Bedingungen und nur durch berechtigte Benutzer stornieren (als neue, stornierte Belegversion mit genullten Mengen) und soll Rechnungen festschreiben können, sodass der Vorgang protokolliert und die Rechnung als unveränderlich markiert ist. +Ergebnis: Kein Storno exportierter/weiterverarbeiteter Rechnungen; lückenlose Nachvollziehbarkeit. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\ReceiptInvoiceBL.cs, Methode CancelInvoice() (Zeilen 143–206, Rechteprüfung Zeile 154, Sperrbedingungen Zeilen 157–172, `newInvoiceVersion.State = ReceiptState.Canceled` Zeile 186) - Begründung: durchsetzende Stornoregeln. + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\ReceiptInvoiceBL.cs, Methode FixInvoice() (Zeile 86 ff., SQL `UPDATE RechKopf SET IsFixed = 1 WHERE I3D = @I3D` + ReceiptLogKind.FixedState) - Begründung: durchgesetzte Festschreibung. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, Tabelle dbo.RechKopf, Spalte [IsFixed] [bit] NOT NULL (Zeile 3374) - Begründung: persistiertes Festschreibekennzeichen. +Prüfidee: Rechnung FiBu-exportieren, danach CancelInvoice aufrufen → Fehler „bereits exportiert"; Storno mit Benutzer ohne Recht → Fehler; erfolgreicher Storno erzeugt Version n+1 mit State=Canceled und QuantityComplete=0. +Tracelinks: StRS-302 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kernanforderung; Barrechnungs-Sonderfall prüfen (aktuell pauschal gesperrt). +Status: belegt +``` + +### SyRS-315: Berechtigungsprüfung im Belegwesen (Anlegen/Bearbeiten/Ansehen, Filialbindung) + +``` +ID: SyRS-315 +Titel: Berechtigungsprüfung im Belegwesen (Anlegen/Bearbeiten/Ansehen, Filialbindung) +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: System (ReceiptBL/SpecificLogics/AppRightsBL); alle Belegbenutzer +Vorbedingung: Benutzer mit Rechteprofil angemeldet. +Fakt: Je Belegart existieren getrennte Rechte für Anlegen, Bearbeiten und Ansehen (z. B. Offer.CREATE_NEW_OFFER, Invoice.EDIT_INVOICE, Invoice.SHOW_INVOICES) sowie „nur eigene Filiale"-Varianten; CanUserEditReceipt/CanUserViewReceipt/CanUserCreateNewReceiptsAtCustomerOrSupplier lehnen ohne Recht mit Fehlermeldung ab; Web-Account-Logins dürfen Belege generell nicht einsehen. +Aussage: Das System soll Anlegen, Bearbeiten und Ansehen je Belegart über eigenständige Benutzerrechte steuern, optional auf die eigene Filiale beschränken und Zugriffe ohne Recht serverseitig ablehnen. +Ergebnis: Kein unberechtigter Beleg-Zugriff; filialgetrennte Sachbearbeitung möglich. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, Methoden CanUserEditReceipt() (Zeile 10273 ff., `if (!hasRightToEditReceipt) return Result.AsError(..., RightCheckFailed)` inkl. BranchBL.IsBranchEqual) und CanUserViewReceipt() (Web-Login-Sperre) - Begründung: durchsetzende Prüfstellen. + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\InvoiceSpecificLogic.cs, Methoden HasRightToCreateANewReceipt()/HasRightToEditReceipt()/HasRightToViewReceipt() (Zeilen 521–541, UserRightsConst.Sales.Customer.CustomerCommon.Invoice.*) - Begründung: Rechtekonstanten je Belegart. + - [KONTEXT] CentronRights.md (Repo-Wurzel) - Begründung: Dokumentation des Rechtesystems. +Prüfidee: Benutzer ohne SHOW_INVOICES ruft Rechnungsliste ab → RightCheckFailed; Benutzer mit EDIT_INVOICE_ONLY_OWN_BRANCH bearbeitet Rechnung fremder Filiale → Ablehnung. +Tracelinks: StRS-302 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - feingranulares Rechtemodell ist Anforderungsbasis für SaaS-Rollenmodell. +Status: belegt +``` + +### SyRS-316: Forderungsüberwachung: Mahnwesen und Kreditlimit + +``` +ID: SyRS-316 +Titel: Forderungsüberwachung: Mahnwesen und Kreditlimit +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung (Mahnlauf); System (SaveReceipt-Prüfungen) +Vorbedingung: Offene, fällige Rechnungen bzw. Kunde mit Kreditlimit/Mahnstufe. +Fakt: DunningRunBL erhöht die Mahnstufe einer Rechnung schrittweise None→1→2→3 mit Datum und Bearbeiter je Stufe; CanUserCreateNewReceiptsAtCustomerOrSupplier() sperrt die Neuanlage von Belegen ab kundenindividuell konfigurierter Mahnstufe; CheckIfCustomerLimitIsReached() warnt beim Speichern, wenn das Kreditlimit (netto oder brutto) durch offene Belege überschritten würde. +Aussage: Das System soll überfällige Rechnungen über einen dreistufigen Mahnlauf eskalieren (mit Stufe, Datum, Bearbeiter je Rechnung), ab konfigurierbarer Mahnstufe die Anlage neuer Belege für den Kunden sperren und beim Speichern eines Belegs eine Kreditlimitüberschreitung erkennen und zur Bestätigung vorlegen. +Ergebnis: Reduziertes Forderungsausfallrisiko; dokumentierte Mahnhistorie je Rechnung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\Dunning\DunningRunBL.cs (Zeilen 253–268: switch über invoice.DunningLevel mit Level1/2/3, Datum und Employee) - Begründung: Mahnstufen-Statusmaschine. + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, Methoden CanUserCreateNewReceiptsAtCustomerOrSupplier() (Zeile 10194 ff., `dunningLevel >= blockOnLevel` → Fehler) und CheckIfCustomerLimitIsReached() (Kreditlimit-Dialog) - Begründung: durchsetzende Sperren. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, dbo.RechKopf Spalten Mahnung1–3Datum, Mahnung1–3BearbeiterI3D, Mahnstufe, MahnStop (Zeilen 3268–3276) - Begründung: persistiertes Mahn-Datenmodell. +Prüfidee: Rechnung 3x mahnen → Stufenfolge 1,2,3 mit Datum/Bearbeiter; Kunde mit OrderLockAfterDunning=2 und Mahnstufe 2 → Auftragsneuanlage wird abgelehnt; Beleg über Kreditlimit → Bestätigungsdialog. +Tracelinks: StRS-302 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Standard-Forderungsmanagement. +Status: belegt +``` + +### SyRS-317: Automatische Preisfindung mit Schutz des Mindestpreises + +``` +ID: SyRS-317 +Titel: Automatische Preisfindung mit Schutz des Mindestpreises +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System (ReceiptItemPriceBL); Vertriebsmitarbeiter +Vorbedingung: Position mit Artikelbezug; Kunden-/Vertragskontext bekannt. +Fakt: GetBasePrice() wendet nacheinander an: Sondervereinbarungs-Rabatt (EKVKReduction), Vertragssonderpreis (5 Kinds × fix/prozentual), sonst Kundensonderpreis (5 SpecialPriceKinds), sonst Staffelpreis nach Menge; Basispreis ist der Preislisten-VK (VK1–VK4 nach Customer.PriceList, ggf. Firmengruppen-Kunde); CheckArticleMinPrices() erzwingt beim Speichern den Artikel-Mindestpreis, übersteuerbar nur durch Benutzer mit Recht ALLOW_IGNORE_MINIMUM_PRICE (auch per Re-Authentifizierung eines zweiten Benutzers). +Aussage: Das System soll den Verkaufspreis jeder Position automatisch nach der festen Hierarchie Vertragssonderpreis → Kundensonderpreis → Staffelpreis → Preislisten-VK ermitteln und Verkäufe unter dem Artikel-Mindestpreis nur nach Autorisierung durch einen dazu berechtigten Benutzer zulassen (Vier-Augen-Fähigkeit). +Ergebnis: Kundenindividuelle, nachvollziehbare Preise; Margen-Schutz durch Mindestpreis. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Internal\ReceiptItemPriceBL.cs, Methoden GetBasePrice() (Zeile 154 ff.) und GetSpecialPrice() (Zeile 588 ff., Priorität Artikel > WG+UWG > WG, Gültigkeit ValidFrom/ValidTo) - Begründung: implementierte Findungshierarchie. + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, Methode CheckArticleMinPrices() (Zeile 9036 ff., Rechteprüfung Zeilen 9043/9113) - Begründung: durchgesetzter Mindestpreis inkl. Zweitbenutzer-Authentifizierung. +Prüfidee: Artikel mit MinPrice 100 zum Preis 90 speichern → Dialog; Freigabe durch Benutzer ohne ALLOW_IGNORE_MINIMUM_PRICE → Ablehnung; mit Recht → Speichern erlaubt. +Tracelinks: StRS-303 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Hierarchie und Mindestpreis-Schutz sind fachlicher Kern; Re-Authentifizierung ist laut TODO-Kommentar mit Azure-Login inkompatibel und muss neu gelöst werden. +Status: belegt +``` + +### SyRS-318: E-Rechnungs-Export und -Import (XRechnung/ZUGFeRD/ebInterface) + +``` +ID: SyRS-318 +Titel: E-Rechnungs-Export und -Import (XRechnung/ZUGFeRD/ebInterface) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: System (InvoiceZugferdBL, EbInterfaceLogic, ZugferdImportController); Buchhaltung; externe Empfänger/Absender +Vorbedingung: Rechnung/Gutschrift vorhanden bzw. ZUGFeRD-Datei (PDF/XML) empfangen; API-Aufrufer authentifiziert. +Fakt: GenerateZugferdFile() erzeugt je nach konfiguriertem Format (ZugferdKind, Default XInvoice 3.0.1) ein XML; eine vorhandene Leitweg-ID schaltet auf XInvoice-Dateiart und wird als BuyerReference eingetragen; CreateZugferdConformPdfDocument() bettet das XML in das Rechnungs-PDF ein; nur Rechnung und Gutschrift sind zulässige Belegarten; der REST-Endpunkt POST v{n}/ZugferdImport/parse ([Authorize]) parst eingehende ZUGFeRD-Dateien; EbInterfaceLogic.GenerateFile() erzeugt ebInterface-4.3-XML. +Aussage: Das System soll Rechnungen und Gutschriften als E-Rechnung in konfigurierbarer Formatversion (ZUGFeRD 1.0 bis XRechnung/XInvoice 3.0.1, ebInterface 4.3) exportieren — bei Kunden mit Leitweg-ID automatisch als XRechnung mit BuyerReference — und eingehende ZUGFeRD-Dateien nur für authentifizierte Benutzer strukturiert einlesen. +Ergebnis: Formatkonforme E-Rechnungsdateien; extrahierte Rechnungsdaten für den Lieferantenrechnungs-Import. +Belege: + - [PRIMÄR] src\backend\Centron.BL\DataExchange\EDI\SaleInvoices\InvoiceZugferdBL.cs, Methoden GetZugferFormat()/GenerateZugferdFile()/GetBookkeepingReceiptKind() (Zeilen 85/124/111, `throw ... is not valid for XRechnung` für andere Belegarten; ZugferdFileKind.XInvoice bei Leitweg-ID Zeile 153) - Begründung: durchgesetzte Format- und Belegartregeln. + - [PRIMÄR] src\webservice\Centron.Controllers\Controllers\v1\Receipts\ZugferdImportController.cs ([Authorize], Route "v{version}/[controller]", POST parse) - Begründung: geschützter Import-Endpunkt. + - [PRIMÄR] src\apis\Centron.Api.EbInterface\EbInterfaceLogic.cs, Methode GenerateFile() mit ValidateValues() - Begründung: ebInterface-Erzeugung inkl. Validierung. +Prüfidee: Export einer Rechnung mit/ohne Leitweg-ID vergleichen (Dateiart XInvoice vs. Comfort, BuyerReference); Export einer Auftragsbestätigung anfordern → Fehler; unauthentifizierter POST auf /ZugferdImport/parse → 401. +Tracelinks: StRS-304 +Konsolidierung: Kandidat: drei getrennte Generator-Implementierungen (InvoiceZugferdBL + Interfaces\XInvoiceVersion3.cs, EbInterfaceLogic, Gateway ZUGFeRD21_Extended) für denselben fachlichen Zweck „strukturierte E-Rechnung". +Übernahmewürdigkeit: übernehmen - fachlich zwingend; Implementierung idealerweise auf Standardbibliothek umstellen (siehe docs\guides\development\xrechnung.md). +Status: belegt +``` + +### SyRS-319: Kampagnen-Mailings mit personalisierten Texten und Versandnachweis + +``` +ID: SyRS-319 +Titel: Kampagnen-Mailings mit personalisierten Texten und Versandnachweis +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Marketing; System (MailingDataBL) +Vorbedingung: Mailing-Definition mit Datenquelle (MailingDataSourceKind) und Empfängermenge. +Fakt: MailingData speichert Betreff, Mailtext, Signatur, Kampagnenbezug (CampaignI3D), Umfrage-/Webformular-Bezug, SMS-Gateway und Optionen für Aktivitäten/Helpdesk; MailingTexts hält je Empfänger E-Mail, Variablenwerte und ein Send-Kennzeichen; Anhänge (MailingAttachments) und beziehungsartspezifische Textvarianten (MailingDataToRelationshipKind) sind zugeordnet; SaveMailingData() erzwingt Version=2, Abfragen filtern auf Version==2 und gesetzten MailingDataSourceKind. +Aussage: Das System soll Kampagnen-Mailings mit personalisierten Empfängertexten, Anhängen und beziehungsartspezifischen Textvarianten verwalten und den Versandstatus je Empfänger nachweisbar speichern. +Ergebnis: Auswertbarer Versandnachweis je Empfänger; wiederverwendbare Mailing-Definitionen je Kampagne. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Mailings\MailingDataBL.cs, Methoden SaveMailingData() (Zeile 74, `mailing.Version = 2`), LoadFullMailing() (Zeile 22), GetAllMailingData() (Filter Version==2 && MailingDataSourceKind != null) - Begründung: implementiertes Datenmodell und Invarianten. + - [SEKUNDÄR] src\backend\Centron.BL\Mailings\MailingDataBL.cs, ConvertMailingTexts() (Felder EMail, Variables, Send, SurveyI3D) - Begründung: Versandstatus je Empfänger. +Prüfidee: Mailing mit 2 Empfängern speichern; nach Versand ist Send je Empfängertext gesetzt; Altbestände mit Version≠2 erscheinen nicht in der Mailingliste. +Tracelinks: StRS-305 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - fachliche Funktion übernehmen; „Version 2"-Filter deutet auf abgelösten Altdatenbestand (Version 1) hin, der nicht migriert werden muss. +Status: belegt +``` + +### SyRS-320: Kunden-Produkt-Potenzialmatrix mit Änderungshistorie + +``` +ID: SyRS-320 +Titel: Kunden-Produkt-Potenzialmatrix mit Änderungshistorie +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertriebsmitarbeiter, Vertriebsleitung; System (ProductMatrixBL) +Vorbedingung: Produktmatrix-Kategorien und -Produkte sind gepflegt. +Fakt: Je Kunde und Produkt wird genau eine Bewertung (CustomerProductMatrixRatingValue: 0=Nichts klassifiziert, 1=Keine Leistung vorhanden, 2=Von Fremdpartner vorhanden, 3=Von uns eingeführt vorhanden) gehalten; fehlende Bewertungen werden beim Zugriff mit Default „Nothing" angelegt bzw. massenhaft für alle Kunden erzeugt; jede Änderung wird mit Mitarbeiter, Zeitstempel und optionaler Begründung im ChangeLog gespeichert. +Aussage: Das System soll je Kunde und Matrixprodukt eine vierstufige Potenzialbewertung führen, fehlende Bewertungen automatisch mit „Nichts klassifiziert" initialisieren und jede Bewertungsänderung mit Mitarbeiter, Zeitpunkt und Begründung historisieren. +Ergebnis: Vollständige, historisierte Potenzial-Matrix je Kunde. +Belege: + - [PRIMÄR] src\backend\Centron.BL\ProductMatrix\ProductMatrixBL.cs, Methoden GetProductMatrixCustomerProductRating() (Zeile 165, Default-Anlage) und AddNotExistingProductRatingToAllCustomers() (Zeile 195) - Begründung: durchgesetzte Initialisierungslogik. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, Tabellen dbo.CustomerProductMatrixRating (CustomerNumber, CustomerProductMatrixProductI3D, RatingValue NOT NULL DEFAULT 0, Zeile 36519) und dbo.CustomerProductMatrixRatingChangeLogs (EmployeeI3D, Timestamp, Reason, Zeile 36535) - Begründung: Datenmodell inkl. Historie. + - [SEKUNDÄR] src\webservice\Centron.WebServices.Core\Entities\ProductMatrix\CustomerProductMatrixRatingValue.cs (Description-Texte der 4 Stufen) - Begründung: fachliche Bedeutung der Stufen. +Prüfidee: Neues Matrixprodukt anlegen, AddNotExistingProductRatingToAllCustomers ausführen → alle Kunden haben Rating 0; Bewertung ändern → ChangeLog-Eintrag mit EmployeeI3D und Timestamp. +Tracelinks: StRS-305 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - kompaktes, tragfähiges Modell. +Status: belegt +``` + +### SyRS-321: Belegkonditionen mit länderspezifischen Texten und Variablenersetzung + +``` +ID: SyRS-321 +Titel: Belegkonditionen mit länderspezifischen Texten und Variablenersetzung +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator (Pflege); System (ReceiptBL/AssetConditionBL); Belegempfänger (mittelbar) +Vorbedingung: Zahlungs-, Liefer- und Belegkonditionen (AssetCondition) mit Texten je Land sind gepflegt. +Fakt: Beim Erstellen/Speichern eines Belegs wird der Konditionstext über GetAssetConditionText(conditionI3D, receipt.CountryI3D) landesspezifisch ermittelt und per ReplaceAssetConditionText() mit Belegwerten (u. a. Beträgen) befüllt; fehlt die Kondition, greift eine Default-Kondition aus den App-Einstellungen; bei Lieferanten-Zahlungskonditionen wird ein Mindestbetrag (MinimumAmount) geprüft und unterschritten ein Bestätigungsdialog ausgelöst; die Pflege erfolgt im WPF-Modul ReceiptConditionManagement (inkl. Fälligkeitsarten Now/PlusDays/AtDay, Barzahlarten, Lastschriftmodi und Mappings zu externen Konditionen). +Aussage: Das System soll Zahlungs-, Liefer- und Belegkonditionen zentral verwalten, deren Texte landesspezifisch am Beleg einsetzen, Platzhalter mit Belegwerten füllen und konditionsspezifische Regeln (Default-Kondition, Mindestbetrag) beim Speichern anwenden. +Ergebnis: Konsistente Konditionstexte auf allen Belegen; korrekte Fälligkeits-/Skontodaten. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, Methoden GetReceiptConditionText() (Zeile 8500, landesspezifische Textwahl + Ersetzung) und GetReceiptConditionOrDefaultFromSetting() sowie Mindestbetragsprüfung `price.NetPrice < (decimal)paymentCondition.MinimumAmount` (Zeile 9009 ff.) - Begründung: durchgesetzte Konditionslogik am Beleg. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\Administration\ReceiptConditions\ReceiptConditionManagementViewModel.cs sowie DueKind.cs (Now/PlusDays/AtDay), CashKind.cs, DtaMode.cs - Begründung: Pflege-UI und Konditionsattribute. +Prüfidee: Zahlungskondition mit Text für Land AT und DE anlegen; Beleg mit CountryI3D=AT erzeugt AT-Text; Lieferantenbeleg unter MinimumAmount speichern → Bestätigungsdialog. +Tracelinks: StRS-302 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Konditionsverwaltung mit Ländertexten ist wiederverwendbares Konzept. +Status: belegt +``` + +## Cluster A4 — SyRS (Artikel, Lager, Einkauf, Logistik, RMA) + +### SyRS-410: Duale Bestandsermittlung (Mengenfeld vs. Seriennummernzählung) + +``` +ID: SyRS-410 +Titel: Duale Bestandsermittlung (Mengenfeld vs. Seriennummernzählung) +Ebene: SyRS +Typ: Daten +Qualitätsmerkmal: +Akteur: System (Bestandsermittlung), alle bestandsführenden Module +Vorbedingung: Artikel mit oder ohne Seriennummernpflicht (ARTIK.BarcodeScanen) +Fakt: cvw_ArticleCount liefert je Artikel/Lager: bei BarcodeScanen=1 und aktivem Systemschalter (Stammdat I3D=1490) die Anzahl der Seriennummern mit Status in (1,2,8) (cvw_BarcodeCount), sonst das Mengenfeld (ARTIK.Menge bzw. NebenlagerArtikel.Bestand). ArticleStockBL.IncreaseArticleStock bucht bei Barcode-Zugängen nur, wenn ScanBarcode aktiv ist. +Aussage: Das System soll den verfügbaren Bestand für seriennummernpflichtige Artikel aus der Zählung der Seriennummern im Lager ableiten und für alle anderen Artikel aus dem geführten Mengenfeld, systemweit einheitlich über eine zentrale Sicht. +Ergebnis: Alle Module (Bestellvorschlag, Kommissionierung, Inventur) rechnen mit derselben Bestandsdefinition. +Belege: + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE VIEW [dbo].[cvw_ArticleCount] (CASE WHEN a.BarcodeScanen = 1 AND s.Wert = 1 THEN ISNULL(bc.cnt,0) ELSE a.Menge/na.Bestand END) - Begründung: durchgesetzte Berechnungsregel der Bestandsermittlung. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE VIEW [dbo].[cvw_BarcodeCount] (WHERE b.Status in (1,2,8)) - Begründung: definiert, welche Seriennummernstatus als "im Bestand" zählen. + - [SEKUNDÄR] src\backend\Centron.BL\Warehousing\StockManagement\ArticleStockBL.cs, IncreaseArticleStock (Z. 52-61) - Begründung: Kommentar/Code, dass Barcodes ohne ScanBarcode-Flag den Bestand nicht beeinflussen. +Prüfidee: Artikel mit BarcodeScanen=1: drei Seriennummern mit Status InStock anlegen und prüfen, dass cvw_ArticleCount 3 liefert, unabhängig vom Mengenfeld. +Tracelinks: StRS-401; SwRS-435, SwRS-436, SwRS-441, SwRS-442, SwRS-443 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - klare, zentrale Bestandsdefinition; Umsetzung als DB-View ist Implementierungsdetail. +Status: belegt +``` + +### SyRS-411: Berechtigungsmodell für Artikelpflege und Lagerbuchungen + +``` +ID: SyRS-411 +Titel: Berechtigungsmodell für Artikelpflege und Lagerbuchungen +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Angemeldeter Benutzer (AppUser), Rechteverwaltung +Vorbedingung: Benutzer mit zugewiesenen Einzelrechten (UserRightsConst) +Fakt: Artikel speichern/anlegen, Preise ändern, Seriennummernpflicht ändern, Lagerumbuchungen und Kommissionierungszugriff werden serverseitig gegen Einzelrechte geprüft (z. B. STORE_ARTICLE=20400022, CREATE_NEW_ARTICLE=20400023, CHANGE_ARTICLE_PRICE=20400024, TRANSFER_STOCK=20400060, Logistic.Commissioning.ID=101010); bei fehlendem Recht wird mit Fehler abgebrochen. +Aussage: Das System soll schreibende Operationen auf Artikelstamm und Lagerbestand nur Benutzern mit dem jeweiligen feingranularen Einzelrecht erlauben und die Prüfung serverseitig in der Geschäftslogik durchsetzen. +Ergebnis: Nicht berechtigte Änderungen werden mit einer Fehlermeldung abgewiesen; keine stille Umgehung über die UI möglich. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Warehousing\ArticleBL.cs, CheckUserRightBeforeSave (Z. 991-1056): if (checkRightsResult.Contains(UserRightsConst.Purchase.StockList.STORE_ARTICLE) == false) return Result.AsError("Sie haben kein Recht Artikel zu speichern") - Begründung: durchsetzende Stelle mit konkreter Bedingung. + - [PRIMÄR] src\backend\Centron.BL\Warehousing\SecondStockArticleBL.cs, RebookStockArticle (Z. 106-114): Prüfung TRANSFER_STOCK, sonst "Fehlende Rechte um Lagerbuchungen durchzuführen." - Begründung: durchsetzende Stelle für Umbuchungen. + - [KONTEXT] CentronRights.md - Begründung: Dokumentation des Rechtekatalogs. +Prüfidee: Benutzer ohne CHANGE_ARTICLE_PRICE ändert Price1 eines Artikels; Speichern muss mit Rechtefehlermeldung scheitern. +Tracelinks: StRS-401; SwRS-430, SwRS-433, SwRS-439 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - feingranulares Rechtemodell ist für Mehrbenutzer-ERP erforderlich. +Status: belegt +``` + +### SyRS-412: Lückenlose Protokollierung aller Bestandsänderungen + +``` +ID: SyRS-412 +Titel: Lückenlose Protokollierung aller Bestandsänderungen +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Zuverlässigkeit (Nachvollziehbarkeit/Auditierbarkeit) +Akteur: System (ArticleLogBL), Lagerverantwortliche (Auswertung) +Vorbedingung: Beliebige bestandswirksame Operation +Fakt: Zu-/Abbuchungen, Seriennummern-Erzeugung und -Ausbuchung sowie Inventurbuchungen schreiben Einträge in ARTIKlog mit altem Wert, neuem Wert, Differenzmenge, Art, Bearbeiter und Lager (ArticleLogBL.WriteLog, ArticleLogKind.StockIncrease/StockDecrease/SerialNumberChargeOff u. a.). +Aussage: Das System soll jede Bestandsänderung mit Vorher-/Nachher-Wert, Menge, Vorgangsart, Verursacher, Zeitpunkt und Lager revisionssicher protokollieren. +Ergebnis: Bestandsdifferenzen sind vollständig auf einzelne Vorgänge zurückführbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Warehousing\SecondStockArticleBL.cs, StockBookOrBookout (Z. 133-214): _articleLogBL.WriteLog(... alter Bestand, neuer Bestand, Menge, ArticleLogKind.StockIncrease/StockDecrease ...) - Begründung: Protokollierung ist fest in den Buchungspfad eingebaut. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[ARTIKlog] (AlterWert, NeuerWert, DifferenzMenge, Art, BearbeiterI3D, NebenlagerI3D) - Begründung: Datenmodell des Protokolls. + - [SEKUNDÄR] src\backend\Centron.BL\Warehousing\BarcodeBL.cs, CreateNewBarcode (Z. 156-160) - Begründung: auch SN-Erzeugung wird als Bestandsänderung geloggt. +Prüfidee: Manuelle Zubuchung von 5 Stück ausführen und prüfen, dass ein ARTIKlog-Eintrag mit AlterWert, NeuerWert=AlterWert+5 und Bearbeiter entsteht. +Tracelinks: StRS-401; SwRS-434, SwRS-435, SwRS-442 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Audittrail ist fachlich und regulatorisch notwendig. +Status: belegt +``` + +### SyRS-413: Inventur mit Statusmodell und automatischer Bestandskorrektur + +``` +ID: SyRS-413 +Titel: Inventur mit Statusmodell und automatischer Bestandskorrektur +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Inventurverantwortlicher, Lagermitarbeiter (Zählung) +Vorbedingung: Angelegte Inventur mit Inventurgruppen je Lager +Fakt: Inventuren besitzen Zustände (Open/OpenWithoutBC/Closed/ClosedWithoutBC); Zählmengen werden je Gruppe erfasst (Barcode-, Artikel- oder Auftragsscan), beim Lagerabschluss werden Bestände auf die Zählmenge gesetzt, nicht gezählte Seriennummern auf "LostAtStocktaking" gestellt, Differenzen in InventoryArticleCheck (Vorher/Nachher) und im Artikellog dokumentiert; ein abgeschlossenes Lager kann nicht erneut gebucht werden. +Aussage: Das System soll Voll- und Teilinventuren mit Zählerfassung je Lager unterstützen und beim Abschluss die Buchbestände automatisch auf die gezählten Mengen korrigieren, inklusive Verlustkennzeichnung nicht gefundener Seriennummern und vollständiger Differenzdokumentation. +Ergebnis: Nach Inventurabschluss entsprechen Buchbestände den Zählmengen; Differenzen sind dokumentiert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Warehousing\InventoryManagement\InventoryBL.cs, CloseStorages (Z. 797-944): UpdateArticleStock auf Zählmenge, CloseStorageUpdateBarcodeSetStatusToLostAtInventory, InventoryArticleCheck mit AmountBefore/AmountAfter - Begründung: durchgesetzte Korrektur- und Verlustlogik. + - [PRIMÄR] src\backend\Centron.BL\Warehousing\InventoryManagement\InventoryNewBL.cs, CloseInventory (Z. 312-324): Statusübergänge Open→Closed, Fehler bei bereits abgeschlossener Inventur - Begründung: Statusmaschine der Inventur. + - [SEKUNDÄR] src\backend\Centron.BL\Warehousing\InventoryManagement\InventoryNewBL.cs, ChangeInventoryGroup (Z. 331-337): Fehler "Ausgewählte Lager ... ist schon abgeschlossen." - Begründung: Sperre abgeschlossener Läger. +Prüfidee: Teilinventur mit abweichender Zählmenge abschließen; Buchbestand, Barcode-Status (LostAtStocktaking) und InventoryArticleCheck-Differenz prüfen. +Tracelinks: StRS-401; SwRS-437, SwRS-438 +Konsolidierung: Kandidat: InventoryBL (Inventory/InventoryArticle) und InventoryNewBL (Inventory2/InventoryArticle2/BarCode2) implementieren dieselbe Inventurfachlichkeit in zwei Generationen nebeneinander. +Übernahmewürdigkeit: übernehmen - Inventur ist Pflichtfunktion; die Doppelimplementierung sollte zusammengeführt werden. +Status: belegt +``` + +### SyRS-414: Automatischer Bestellvorschlag aus Bedarf, Bestand und Zulauf + +``` +ID: SyRS-414 +Titel: Automatischer Bestellvorschlag aus Bedarf, Bestand und Zulauf +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Einkäufer +Vorbedingung: Lagergeführte Artikel (Abbuchung='J' oder IsObligatoryBooking=1); offene Aufträge und/oder Mindestbestände +Fakt: OrderSuggestionListBL ermittelt per SQL je Artikel/Lager die zu bestellende Menge aus offenen Auftragsmengen (abzgl. Liefermenge), Mindestbestand, aktuellem Bestand (cvw_ArticleCount) und Zulauf aus offenen Bestellungen; Aufträge mit Bestellsperre, Stücklistenartikel, Direktlieferungen und Sondervereinbarungen werden gesondert behandelt bzw. ausgeschlossen; EOL und Mindestbestellmenge werden mitgeliefert. +Aussage: Das System soll Bestellvorschläge automatisch berechnen als Bedarf (offene Auftragsmengen + Mindestbestandsunterdeckung) minus verfügbarem Bestand minus bereits bestelltem Zulauf, getrennt je Lager, und dabei Bestellsperren, Direktlieferungen, Sondervereinbarungen und EOL-Kennzeichen berücksichtigen. +Ergebnis: Der Einkäufer erhält eine vollständige, doppelbestellungsfreie Vorschlagsliste je Lager/Lieferant. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Purchasing\OrderSuggestionList\OrderSuggestionListBL.cs, Konstruktor _sqlArticle (Z. 87-242): WHERE IsNull(OrderItemQuantity,0)+IsNull(MinimumQuantity,0)-IsNull(ac.cnt,0)-IsNull(WarehouseIntake,0)-IsNull(OrderItemIntake,0) != 0, Filter ISNULL(ak.BestellSperre,0)=0, IsNull(A.StkListe,0)=0 - Begründung: vollständige Bedarfsformel im Code. + - [SEKUNDÄR] src\backend\Centron.BL\Purchasing\OrderSuggestionList\OrderSuggestionListBL.cs, Konstruktor (Z. 70-85): AppSettings OSLShowReceiptOnDemandPositions/OSLShowReceiptOnEffortPositions steuern einbezogene Positionsarten - Begründung: konfigurierbarer Umfang des Vorschlags. +Prüfidee: Artikel mit Mindestbestand 10, Bestand 4, offener Bestellung über 3: Vorschlag muss 3 ergeben; nach Setzen der Bestellsperre am Auftrag entfällt der Auftragsbedarf. +Tracelinks: StRS-402; SwRS-444 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kernlogik des Einkaufs; SQL-Monolith sollte in testbare Services überführt werden. +Status: belegt +``` + +### SyRS-415: Elektronischer Belegaustausch mit Lieferanten (EDI) + +``` +ID: SyRS-415 +Titel: Elektronischer Belegaustausch mit Lieferanten (EDI) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Einkäufer, Distributor-Systeme (ALSO, KOMSA, Alltron, Herweck, EGIS, ITscope, Concerto) +Vorbedingung: SupplierEdiConfigurations je Lieferant (Format, Zugangsdaten, FTP/HTTP) +Fakt: Bestellungen werden je nach konfiguriertem EdiDataType in distributorspezifische XML-Formate übersetzt (OpenTRANS 2.1 als Standard) und per FTP/HTTP hochgeladen; Bestellbestätigungen, Lieferscheine und Rechnungen (inkl. ZUGFeRD) werden heruntergeladen, geparst und als EDI-Belege (EDIOrderResponseHead/EDIInvoiceHead mit Positionen) den c-entron-Bestellungen zugeordnet; alle Vorgänge werden in EDI-Logs festgehalten. +Aussage: Das System soll Bestellungen elektronisch in mehreren Distributorformaten versenden und eingehende Lieferantenbelege automatisiert importieren, den Bestellungen zuordnen und den Austausch protokollieren. +Ergebnis: Bestellungen und Rückbelege fließen ohne manuelle Doppelerfassung zwischen ERP und Distributoren. +Belege: + - [PRIMÄR] src\backend\Centron.BL\EDI\EDIDispatcherBL.cs, CreateEDISuggestionOrderAsync (Z. 56-109): switch über EdiDataType mit Fehler bei unbekanntem Format - Begründung: durchgesetzte Formatauswahl. + - [PRIMÄR] src\backend\Centron.BL\EDI\SupplierEDI\SupplierEdiBL.cs, SaveReceiptItemAssignments (Z. 504-578) - Begründung: transaktionale Zuordnung von EDI-Positionen zu Bestellpositionen. + - [SEKUNDÄR] src\backend\Centron.BL\EDI\SupplierEDI\SupplierEdiBL.cs, DownloadStartAsync/DowloadDeliveryAsync (Z. 754 ff.) - Begründung: automatisierter Belegabruf vom Lieferanten. +Prüfidee: Testbestellung an einen OpenTRANS-Lieferanten erzeugen; XML-Struktur validieren; simulierte Rechnung importieren und Positionszuordnung prüfen. +Tracelinks: StRS-402; SwRS-445, SwRS-446 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Distributoranbindung ist Alleinstellungsmerkmal; Einzelformate (AlsoCH, Alltron) auf Marktrelevanz prüfen. +Status: belegt +``` + +### SyRS-416: Versanddienstleister-Anbindung mit Label- und Trackingrückgabe + +``` +ID: SyRS-416 +Titel: Versanddienstleister-Anbindung mit Label- und Trackingrückgabe +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Versandmitarbeiter, GLS-API, Shipcloud-API +Vorbedingung: Lieferschein mit Empfängeradresse; Zugangsdaten des Dienstleisters +Fakt: GLS-Sendungen werden per REST (JSON, Basic Auth) angemeldet, wobei vor dem Versand fachliche Limits geprüft werden (SenderID, Sendungsdatum, max. 50 Referenzen, max. 30 Pakete); die Antwort liefert TrackingId, Tracking-URL und Base64-Labels. Shipcloud-Sendungen liefern Trackingnummer, Tracking-URL, Label-URL und Preis. Die Trackingnummer wird in einer neuen Lieferscheinversion gespeichert. +Aussage: Das System soll Sendungen elektronisch bei Versanddienstleistern anmelden, deren fachliche Restriktionen vor Übertragung validieren und Trackingnummer, Tracking-URL und Versandlabel am Lieferschein hinterlegen. +Ergebnis: Versandfehler durch Limitüberschreitungen werden vor der Übertragung erkannt; jeder Versand ist nachverfolgbar. +Belege: + - [PRIMÄR] src\apis\Centron.Api.Gls\CentronGlsLogic.cs, DoValidateShipment (Z. 60-91): Meldungen "Mehr als 50 Referenzen sind nicht zugelassen", "Mehr als 30 Pakete sind nicht zugelassen" - Begründung: durchgesetzte Vorvalidierung. + - [PRIMÄR] src\apis\Centron.Api.Shipcloud\CentronShipcloudLogic.cs, CreateShipmentAsync (Z. 66-106) - Begründung: Sendungserzeugung mit Tracking-/Label-/Preisrückgabe. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\Finances\Receipts\DeliveryServices\GLS\GlsViewModel.cs, CreateNewReceiptVersionAsync (Z. 642 ff.) - Begründung: Persistierung der Trackingnummer am Lieferschein. +Prüfidee: GLS-Testversand mit 31 Paketen anstoßen; Übertragung muss mit Validierungsmeldung verweigert werden. +Tracelinks: StRS-403; SwRS-447, SwRS-448 +Konsolidierung: Kandidat: Direktanbindung GLS und Broker-Anbindung Shipcloud sind zwei getrennte Implementierungen für denselben Zweck "Sendung anmelden, Label + Tracking erhalten". +Übernahmewürdigkeit: übernehmen - für die Neuimplementierung über eine einheitliche Carrier-Abstraktion (z. B. nur Broker) konsolidieren. +Status: belegt +``` + +### SyRS-417: RMA-Statusverfolgung je Artikel mit konsistenten Lagerbewegungen + +``` +ID: SyRS-417 +Titel: RMA-Statusverfolgung je Artikel mit konsistenten Lagerbewegungen +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: RMA-Sachbearbeiter +Vorbedingung: RMA-Vorgang mit Helpdesk-Bezug (rma.HelpdeskI3D > 0, sonst Abbruch) +Fakt: Jeder RMA-Artikel führt eine Historie (RmaArticleHistory) mit Zuständen (Open, SendForth, BackDeliveryList, AdvanceDeliveryList, Invoice, Scapped ...); SaveRma verarbeitet Stornos, schließt bei Fakturierung die zugehörige Lieferung (LiefKopf.Status=2, DurchRMAGeschlossen=1), bucht bei Lagerwechsel um (RebookArticleStock) und bucht Fremdware in ein RMA-Kundenlager ein; alles in einer Transaktion. +Aussage: Das System soll jeden RMA-Artikel über eine Statushistorie verfolgen und alle abhängigen Belege (Lieferscheine) und Lagerbestände beim Statuswechsel transaktional konsistent nachführen. +Ergebnis: RMA-Stand, Belege und Bestände sind zu jedem Zeitpunkt widerspruchsfrei. +Belege: + - [PRIMÄR] src\backend\Centron.BL\CustomerArea\RmaBL.cs, SaveRma (Z. 347-521): Statusübergänge, delivery.Status=2 / DurchRMAGeschlossen=1, RebookArticleStock, Session.WithTransaction - Begründung: durchgesetzte Konsistenzlogik. + - [PRIMÄR] src\backend\Centron.BL\CustomerArea\RmaBL.cs, Z. 352-353: if (rma.HelpdeskI3D <= 0) throw new ResultException("Rma not coneccted to helpdesk") - Begründung: erzwungene Vorbedingung. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[RmaArticleHistory] - Begründung: persistente Statushistorie. +Prüfidee: RMA-Artikel bis zur Rechnung führen; prüfen, dass der zugehörige Lieferschein automatisch geschlossen (Status=2, DurchRMAGeschlossen=1) wird. +Tracelinks: StRS-404; SwRS-449 +Konsolidierung: Kandidat (vermutet): Alt-Tabellen RMAKopf/RMAPos/RMARueckKopf/RMARepKopf neben Rma/RmaArticle/RmaSendBack/RmaSendForth deuten auf eine abgelöste Zweitimplementierung des RMA-Prozesses. +Übernahmewürdigkeit: übernehmen - Statushistorie und Transaktionsklammer sind übernahmewürdig; Alt-Tabellen nicht migrieren. +Status: belegt +``` + +### SyRS-418: Produktdatenübernahme aus externen Katalogquellen + +``` +ID: SyRS-418 +Titel: Produktdatenübernahme aus externen Katalogquellen +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Einkäufer/Vertriebsmitarbeiter, Katalogdienste Icecat, ITscope, EGIS, COP, TradePool +Vorbedingung: Zugangsdaten der jeweiligen Katalogquelle konfiguriert +Fakt: Über IcecatApi werden Produktdaten (Beschreibung, Bild, Eigenschaften) per EAN abgerufen; ITscopeApi liefert Produkte, Preise, Lieferanten und Deals (inkl. API-Quota-Abfrage); EgisApi liefert Artikelsuche, Produktmerkmale sowie Preis und Verfügbarkeit; TradePoolBL importiert Handelsartikel aus XML-Dateien. +Aussage: Das System soll Produktstammdaten, Preise und Verfügbarkeiten aus externen Katalog- und Marktplatzdiensten abrufen und zur Anreicherung von Artikeln und Belegpositionen bereitstellen. +Ergebnis: Artikel-/Positionsdaten können ohne manuelle Erfassung aus Katalogquellen übernommen werden. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\Finances\Receipts\ContentImport\Services\IceCatImportService.cs, GetArticleAsync (Z. 33-66): Abruf per EAN, Übernahme von Text, Bild, Kurztext, Eigenschaften - Begründung: implementierte Datenübernahme. + - [PRIMÄR] src\apis\Centron.APIs.EgisDataAccess\EgisApi.cs, GetPriceAndAvailability (Z. 120 ff.) - Begründung: Preis-/Verfügbarkeitsabruf beim Distributor. + - [SEKUNDÄR] src\apis\Centron.APIs.ITscopeDataAccess\ITscopeApi.cs, GetProductByEanCodeAsync/GetDeals - Begründung: weitere Katalog-/Dealquelle. +Prüfidee: Belegposition mit gültiger EAN anreichern; übernommene Beschreibung/Bild mit Icecat-Webansicht vergleichen. +Tracelinks: StRS-402; SwRS-450, SwRS-451 +Konsolidierung: Kandidat: vier separat implementierte Kataloganbindungen (Icecat, ITscope, EGIS, COP) plus TradePool bilden dieselbe fachliche Funktion "externe Produktdatenquelle" ab (teilweise über IImportService vereinheitlicht). +Übernahmewürdigkeit: übernehmen - Anbieterauswahl in der Neuimplementierung prüfen; einheitliche Provider-Schnittstelle vorsehen. +Status: belegt +``` + +### SyRS-419: Berechtigungsgeschützte Kommissionierung mit Mengenrückmeldung + +``` +ID: SyRS-419 +Titel: Berechtigungsgeschützte Kommissionierung mit Mengenrückmeldung +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Kommissionierer +Vorbedingung: Benutzer mit Recht Logistic.Commissioning (ID 101010); Aufträge im Status 1 (offen) +Fakt: Alle Kommissionier-Operationen (Aufträge laden, Positionen laden, Kommissionierung ausführen) prüfen das Kommissionierrecht; die Ausführung schreibt QuantityPicked je Position mit optimistischer Sperre (ConcurrencyControlGuid) zurück und aktualisiert Teilkommissionen; die Seriennummern-Generierung in der Kommissionierung erfordert ein eigenes Recht (GENERATE_BARCODES=20400179). +Aussage: Das System soll die Kommissionierung von Aufträgen nur berechtigten Benutzern erlauben, gepickte Mengen positionsgenau und konfliktsicher zurückschreiben und die Seriennummernvergabe in der Kommissionierung gesondert berechtigen. +Ergebnis: Gepickte Mengen sind korrekt am Auftrag; konkurrierende Änderungen werden erkannt. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Warehousing\Commissions\OrderCommissionBL.cs, HasUserRightsTooAccessCommissionModule (Z. 429-434): if (currentUser.HasUserRight(UserRightsConst.Logistic.Commissioning.ID)) ... sonst Fehler - Begründung: durchsetzende Rechteprüfung. + - [PRIMÄR] src\backend\Centron.BL\Warehousing\Commissions\OrderCommissionBL.cs, ExecuteCommissionForOrders (Z. 169-200): UpdateReceiptQuantityPicked mit ConcurrencyControlGuid - Begründung: Mengenrückmeldung mit Konfliktkontrolle. + - [SEKUNDÄR] src\webservice\Centron.WebServices.Core\EntitiesWrongPlace\Administration\Rights\UserRightsConst.cs, Commissioning (Z. 2638-2645) - Begründung: Rechtekonstanten. +Prüfidee: Benutzer ohne Kommissionierrecht ruft Kommissionieraufträge ab; Zugriff muss mit Fehlermeldung verweigert werden. +Tracelinks: StRS-403; SwRS-439, SwRS-440 +Konsolidierung: Kandidat: CommissioningBL (ArticelHeaderMapping/ArticelPositionMapping) und OrderCommissionBL (CommissionOrder/CommissionOrderItem) implementieren die Kommissionierung zweifach. +Übernahmewürdigkeit: übernehmen - eine der beiden Implementierungen (OrderCommissionBL, neuer) als Basis wählen. +Status: belegt +``` + +## Cluster A5 — Helpdesk & Service — SyRS + +### SyRS-511: Konfigurierbares Ticket-Statusmodell mit ausgezeichneten Sonderstatus + +``` +ID: SyRS-511 +Titel: Konfigurierbares Ticket-Statusmodell mit ausgezeichneten Sonderstatus +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator (Konfiguration), Service-Mitarbeiter (Nutzung) +Vorbedingung: Mindestens ein Helpdesk-Status ist angelegt +Fakt: Ticket-Status sind Datensätze (HelpdeskState, Tabelle hlpdsk_status mit Number, Icon, Deactivated, ServiceBoardWebColor); der "Abgeschlossen"-Status und der Status nach Ticketanlage werden per AppSettings (HelpdeskClosedState, HelpdeskAfterOpenDefaultState) bestimmt; ein verwendeter Status kann nicht gelöscht werden. +Aussage: Das System soll den Ticket-Statuslebenszyklus als frei konfigurierbare, geordnete Statusliste abbilden, wobei genau ein Status als Abschlussstatus und optional ein Status als Standardstatus nach Anlage/Öffnung konfiguriert wird; Status in Verwendung dürfen nicht löschbar sein. +Ergebnis: Statusmodell ist mandanten-/kundenindividuell konfigurierbar, ohne referenzielle Leichen zu erzeugen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskStatusBL.cs, GetClosedHelpdeskStatus()/GetHelpdeskAfterOpenDefaultState() (AppSettingsConst.HelpdeskClosedState, HelpdeskAfterOpenDefaultState) - Begründung: Konfigurative Bestimmung der Sonderstatus wird im Code aufgelöst. + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskStatusBL.cs, DeleteHelpdeskStatus(): Zählung HelpdeskCompact.HelpdeskStateI3D und TaskManagementHelpdeskAction.State, sonst Result.AsError("Der Status ... kann nicht gelöscht werden!") - Begründung: Durchgesetzter Löschschutz. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[hlpdsk_status] - Begründung: Datenmodell des Statuslebenszyklus. +Prüfidee: Status anlegen, Ticket zuweisen, Löschversuch — Fehlermeldung mit Verwendungszählung; als geschlossen konfigurierten Status setzen — Ticket gilt als abgeschlossen. +Tracelinks: StRS-501 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - datengetriebenes Statusmodell ist für Web-Neuimplementierung direkt übertragbar. +Status: belegt +``` + +### SyRS-512: Berechtigungsgeprüfte Ticketbearbeitung für interne Benutzer und Web-Accounts + +``` +ID: SyRS-512 +Titel: Berechtigungsgeprüfte Ticketbearbeitung für interne Benutzer und Web-Accounts +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: AppUser (interner Benutzer), WebAccount (Kundenportal) +Vorbedingung: Benutzer ist authentifiziert; Ticket wird angelegt oder gespeichert +Fakt: HelpdeskBL.DoBeforeSave() ruft CheckRights() auf, das je nach Login-Typ CheckUserRigths() (ADD_NEW_HELPDESK, EDIT_HELPDESK, CLOSE_REQUEST, MATURITY_CHANGE, ASSIGN_HELPDESK_ONLY_TO_OWN_DEPARTMENTS) oder CheckWebRights() (WEBRIGHT_CREATEREQUEST, WEBRIGHT_EDITALLREQUESTS, WEBRIGHT_EDITONLYOWNREQUESTS, WEBRIGHT_CLOSEALLEREQUESTS) durchsetzt; bei fehlendem Recht wird das Speichern mit RightCheckFailed abgebrochen. +Aussage: Das System soll jede anlegende, ändernde oder abschließende Ticketoperation serverseitig gegen das Rechteprofil des Aufrufers prüfen und bei fehlendem Recht mit einer eindeutigen Fehlermeldung ablehnen — getrennt für interne Benutzer und Portal-Accounts (Portal-Accounts nur eigene Anfragen, sofern eingeschränkt). +Ergebnis: Kein Ticket kann ohne entsprechendes Recht angelegt, geändert oder geschlossen werden. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs, CheckUserRigths(): "if (!appUser.HasUserRight(UserRightsConst.Sales.Customer.Helpdesk.EDIT_HELPDESK)) return Result.AsError(\"Sie haben nicht das Recht \\\"Ticket bearbeiten\\\".\", DefaultMessageCodes.RightCheckFailed)" - Begründung: Durchsetzende Prüfstelle im Speicherpfad. + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs, CheckWebRights(): Prüfungen WEBRIGHT_CREATEREQUEST/WEBRIGHT_EDITALLREQUESTS/WEBRIGHT_EDITONLYOWNREQUESTS inkl. Abgleich ContactPerson.I3D == webAccount.AddressContactI3D - Begründung: Durchgesetzte Portalrechte inkl. Eigentümerbindung. + - [KONTEXT] CentronRights.md, Helpdesk-Rechte 1-6 - Begründung: Fachliche Dokumentation der Rechte. +Prüfidee: Benutzer ohne EDIT_HELPDESK speichert Ticketänderung — Ablehnung; WebAccount mit EDITONLYOWNREQUESTS editiert fremdes Ticket — Ablehnung. +Tracelinks: StRS-501, StRS-502 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - serverseitige Rechteprüfung ist Muster für die Web-API. +Status: belegt +``` + +### SyRS-513: Fälligkeitsberechnung aus Priorität und geschütztes Fälligkeitsdatum + +``` +ID: SyRS-513 +Titel: Fälligkeitsberechnung aus Priorität und geschütztes Fälligkeitsdatum +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System (Berechnung), Service-Mitarbeiter (manuelle Änderung) +Vorbedingung: Ticketpriorität mit DueDateDelayInHours ist konfiguriert +Fakt: Beim Anlegen ohne Fälligkeit setzt HelpdeskBL.DoUpdateDefaultHelpdeskFields() DueDate = GetDueDateFromPriority(); der Algorithmus addiert Stunden unter Beachtung von Bürozeiten (OfficeHourFrom/To) und Wochenendausschluss (EscalationSa/So); eine manuelle Änderung des Fälligkeitsdatums erfordert das Recht MATURITY_CHANGE (IsDueDateChanged-Prüfung). +Aussage: Das System soll die Ticketfälligkeit automatisch aus der Priorität (Reaktionszeit in Stunden, Bürozeiten, arbeitsfreie Wochenendtage) berechnen und manuelle Änderungen des Fälligkeitsdatums nur mit dediziertem Recht zulassen. +Ergebnis: Jedes Ticket erhält eine SLA-konforme Fälligkeit; unbefugte Terminverschiebungen sind ausgeschlossen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs, GetDueDateFromPriority(HelpdeskPriority, DateTime): Schleife über hoursToAdd mit OfficeHourFrom/To und EscalationSa/So - Begründung: Implementierter Berechnungsalgorithmus. + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs, CheckUserRigths(): "if (!appUser.HasUserRight(...MATURITY_CHANGE)) { if (IsDueDateChanged(entity)) return Result.AsError(\"Kein Recht für Fälligkeitsdatum ändern vorhanden.\", RightCheckFailed) }" - Begründung: Durchsetzende Rechteprüfung auf Fälligkeitsänderung. +Prüfidee: Priorität mit 8h Reaktionszeit und Bürozeit 8-17 Uhr: Ticket Freitag 16:00 anlegen — Fälligkeit muss auf Montag innerhalb Bürozeit fallen (bei deaktiviertem Sa/So); Benutzer ohne MATURITY_CHANGE ändert DueDate — Ablehnung. +Tracelinks: StRS-501 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - SLA-Kernlogik. +Status: belegt +``` + +### SyRS-514: Dreistufige zeitgesteuerte Ticket-Eskalation mit Mailversand + +``` +ID: SyRS-514 +Titel: Dreistufige zeitgesteuerte Ticket-Eskalation mit Mailversand +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System (Eskalationslauf), Bearbeiter/Vorgesetzter/Betreuer/Geschäftsleitung (Empfänger) +Vorbedingung: Eskalationstyp (eskalationTypen) je Ticketpriorität mit Wartezeiten Stunden1-3 aktiv; Ticketstatus offen (hs.Status = 0) +Fakt: EscalationBL.DoEscalation() selektiert per SQL offene Eskalationseinträge (eskalationen, ObArt=2, e.status < 2), berechnet je Stufe 1-3 in CheckEskalationStage()/ShouldEscalated() den nächsten Eskalationszeitpunkt aus Wartestunden, Geschäftszeit (GeschaeftsZeitVon/Bis) und Sa/So-Flags, versendet Mails an per Flags konfigurierte Empfängerkreise (EscalationReceiversEnum: Editor, Supervisor, Adviser, Manager) und schreibt Eskalation{Stage}AM sowie hlpdsk_requests.EscalationLevel. +Aussage: Das System soll offene Tickets nach konfigurierbaren Wartezeiten je Priorität in bis zu drei Eskalationsstufen eskalieren, dabei je Stufe einen konfigurierbaren Empfängerkreis per E-Mail (Mailvorlage mit Variablen) benachrichtigen und die erreichte Eskalationsstufe am Ticket persistieren. +Ergebnis: Überfällige Tickets werden stufenweise an höhere Ebenen gemeldet; Eskalationsstand ist am Ticket auswertbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\Escalation\EscalationBL.cs, CheckEskalationStage()/ShouldEscalated(): Berechnung dtNextEsc aus WaitHourEsc1-3, WorkTimeFrom/To, IsSaturdayActive/IsSundayActive - Begründung: Durchgesetzte Stufen- und Zeitfensterlogik. + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\Escalation\EscalationBL.cs, UpdateTicket(): "Update hr Set EscalationLevel = {escItem.Stage} ... " und UpdateEscalations(): "SET Eskalation{Stage}AM = GetDate()" - Begründung: Persistierung der Eskalationsstufe nach erfolgreichem Versand. + - [SEKUNDÄR] src\backend\Centron.BL\Sales\Support\Escalation\EscalationBL.cs, SetRecipients() mit EscalationReceiversEnum (Editor/Supervisor/Adviser/Manager) und AppSettingsConst.EscChiefMail - Begründung: Konfigurierbarer Empfängerkreis je Stufe. +Prüfidee: Eskalationstyp Stufe1=2h konfigurieren, Ticket mit überschrittenem Termin anlegen, Eskalationslauf ausführen — Mail an Bearbeiter, EscalationLevel=1, Eskalation1Am gesetzt; zweiter Lauf vor Ablauf Stufe 2 — keine weitere Mail. +Tracelinks: StRS-501 +Konsolidierung: Kandidat: EscalationBL bedient neben Tickets auch Belege/Verträge/Lizenzen (SetAssetEscData, SetLicenceEndData) — gemeinsame Eskalationsinfrastruktur für unterschiedliche Objektarten in einer Implementierung; zusätzlich existiert die Fälligkeitslogik in HelpdeskPriority (SyRS-513) mit eigener Sa/So-/Bürozeitberechnung (GetDueDateFromPriority) — zwei getrennte Zeitfenster-Implementierungen desselben Konzepts. +Übernahmewürdigkeit: übernehmen - Eskalationskonzept ist tragfähig; Doppelung der Zeitfensterberechnung sollte konsolidiert werden. +Status: belegt +``` + +### SyRS-515: Rechte- und Sperrkonzept der Ticket-Zeiterfassung + +``` +ID: SyRS-515 +Titel: Rechte- und Sperrkonzept der Ticket-Zeiterfassung +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Service-Techniker, Abrechnung +Vorbedingung: Zeit (HelpdeskTimer) existiert oder wird angelegt +Fakt: Änderungen an bestehenden Zeiten erfordern EDIT_TIME; OWN_TIME_EDIT beschränkt auf eigene Zeiten; Web-Account-Logins sind ausgeschlossen; Zeiten mit Belegzuordnung (IsAssignedToOrder/DeliveryList/Invoice) können weder gespeichert noch gelöscht noch verschoben werden; Löschen erfordert DELETE_HELPDESK_TIMER und wird historisiert. +Aussage: Das System soll Zeiten auf Tickets nach dem Prinzip abgestufter Rechte schützen (bearbeiten, nur eigene bearbeiten, löschen, verschieben) und Zeiten nach Übernahme in einen Beleg unveränderlich stellen. +Ergebnis: Abgerechnete oder fremde Zeiten sind vor Manipulation geschützt; jede Löschung ist in der Tickethistorie dokumentiert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\WebServices\Sales\Support\HelpdeskTimerWebServiceBL.cs, ThrowIfUserDoesntHaveRightToChangeHelpdeskTimers() und ThrowIfInvalidHelpdeskTimer(): "Die Zeit konnte nicht gespeichert werden, da sie einer Rechnung zugeordnet ist." - Begründung: Durchsetzende Rechte- und Sperrprüfung im Speicherpfad. + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskTimerBL.cs, DeleteHelpdeskTimer(): HasUserRight(DELETE_HELPDESK_TIMER)-Prüfung und "Die Helpdesk Zeit wurde einem Beleg zugewiesen. Löschen ist nicht möglich." - Begründung: Durchsetzende Prüfung beim Löschen. + - [KONTEXT] CentronRights.md, Abschnitte 7, 7.1, 8, 9 - Begründung: Fachliche Definition der Zeitrechte. +Prüfidee: Benutzer mit OWN_TIME_EDIT ändert Zeit eines Kollegen — Ablehnung; Zeit mit RechPosI3D löschen — Ablehnung; erfolgreiche Löschung erzeugt Historieneintrag HELPDESK_TIMER_DELETED. +Tracelinks: StRS-502 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - abrechnungsrelevanter Manipulationsschutz. +Status: belegt +``` + +### SyRS-516: Kundenunterschrift auf erbrachten Zeiten + +``` +ID: SyRS-516 +Titel: Kundenunterschrift auf erbrachten Zeiten +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Kunde (unterschreibt), Service-Techniker, Benutzer mit Löschrecht +Vorbedingung: Nicht geplante Zeit(en) am Ticket vorhanden +Fakt: Unterschriften werden als Bild je Zeit gespeichert (hlpdsk_timer_signature.TimeSignature NOT NULL, 1 Signatur pro Timer via HelpdeskSignatureExists-Prüfung); SignMultipleTimers() setzt IsSigned und schreibt Historie; das Entfernen einer Unterschrift erfordert DELETE_HELPDESK_SIGNATURE und wird geloggt; signierte Zeitberichte können per Mail an den Kunden gesendet und als gedruckt/gesendet markiert werden (IsPrinted, SentAt). +Aussage: Das System soll erbrachte Zeiten durch eine grafische Kundenunterschrift bestätigen lassen (höchstens eine Unterschrift je Zeit, keine Unterschrift auf geplanten Zeiten), das Entfernen der Unterschrift nur mit dediziertem Recht erlauben und alle Signaturvorgänge in der Tickethistorie protokollieren. +Ergebnis: Leistungsnachweis pro Zeit ist revisionierbar dokumentiert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskTimerSignatureBL.cs, RemoveSignatureFromTime(): CheckRightsFromUser(...DELETE_HELPDESK_SIGNATURE), sonst Result.AsError("Sie besitzen nicht das Recht um Unterschriften zu löschen ...", RightCheckFailed) - Begründung: Durchsetzende Rechteprüfung beim Entfernen. + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskTimerSignatureBL.cs, SignMultipleTimers(): Skip bei timer.IsPlanned bzw. vorhandener Signatur; setzt timer.IsSigned = true; HelpdeskHistory "Zeiten unterschrieben" - Begründung: Durchgesetzte Signierregeln inkl. Historie. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[hlpdsk_timer_signature] (RequestTimeI3D NOT NULL, TimeSignature image NOT NULL) - Begründung: Datenmodell der Unterschrift. +Prüfidee: Zwei Zeiten signieren (eine geplant) — nur die nicht geplante wird signiert; Signatur ohne Recht löschen — Ablehnung; mit Recht — Signatur weg, IsSigned=false, Log vorhanden. +Tracelinks: StRS-502 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Beweissicherung für Abrechnung. +Status: belegt +``` + +### SyRS-517: Automatische Ticketerzeugung durch den TaskManager + +``` +ID: SyRS-517 +Titel: Automatische Ticketerzeugung durch den TaskManager +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System (Task-Ausführung), Administrator (Konfiguration) +Vorbedingung: TaskManagementTask mit Helpdesk-Aktion und Wiederholungsregel; Lizenz ServiceBoardWebDev +Fakt: TaskManagementTaskBL.ExecuteTask() dispatcht auf ITaskManagementActionHandler; TaskManagementHelpdeskActionHandler.Execute() prüft Lizenz und ADD_NEW_HELPDESK, erzeugt ein Ticket mit Kunde, Kategorien, Priorität, Status, Verantwortlichem und DueDate = GetDueDateFromPriority() + DueDateOffset; die Wiederholung (täglich/wöchentlich/monatlich/jährlich) wird per RecurrenceCalculator berechnet und NextExecutionDate fortgeschrieben. +Aussage: Das System soll konfigurierte wiederkehrende Aufgaben zu definierten Zeitpunkten ausführen und dabei automatisch Tickets mit vollständigen Stammdaten und berechneter Fälligkeit erzeugen; ohne gültige Lizenz oder Anlage-Recht darf kein Ticket entstehen. +Ergebnis: Wiederkehrende Tickets entstehen planmäßig und rechtskonform. +Belege: + - [PRIMÄR] src\backend\Centron.BL\TaskManager\ActionHandler\TaskManagementHelpdeskActionHandler.cs, Execute(): "if (!currentUser.HasUserRight(UserRightsConst.Sales.Customer.Helpdesk.ADD_NEW_HELPDESK)) throw new ResultException(..., RightCheckFailed)" sowie LicenseManager-Prüfung ServiceBoardWebDev - Begründung: Durchsetzende Rechte- und Lizenzprüfung vor Ticketanlage. + - [PRIMÄR] src\backend\Centron.BL\TaskManager\TaskManagementTaskBL.cs, RecurrenceCalculator.GetDates()/ExecuteTask() inkl. "Recurrence EndTime is before it's StartTime."-Validierung - Begründung: Implementierte Wiederholungs- und Ausführungslogik. +Prüfidee: Task mit wöchentlicher Wiederholung (Mo) und Helpdesk-Aktion anlegen; Ausführung am Stichtag erzeugt Ticket mit DueDate aus Priorität+Offset; Ausführung ohne Lizenz — Fehler-Notification statt Ticket. +Tracelinks: StRS-503 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Automatisierungskern; Scheduler in Web-Version als Serverjob abzubilden. +Status: belegt +``` + +### SyRS-518: Zeitlich begrenzte SelfCare-Formularlinks + +``` +ID: SyRS-518 +Titel: Zeitlich begrenzte SelfCare-Formularlinks +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Kunde (Formularempfänger), Service-Mitarbeiter (Versand), ServiceBoard-Web (Rendering) +Vorbedingung: SelfCare-Formulare konfiguriert; SBO-Basis-URL gesetzt +Fakt: SendWebForm() erzeugt ein WebForm mit neuem Guid und URL "{baseUrl}/webform/{Guid}"; GetWebFormByGuid() verweigert Zugriff nach Ablauf (CreatedAt + WebFormLinkExpirationInMinutes, Default 7 Tage) mit "Link has expired"; der Formularlink wird per Variable @@FormularLink@@ in die Mail eingesetzt; die versendete Mail wird dem Ticket-Dokumentenverzeichnis zugeordnet. +Aussage: Das System soll Kunden-Formulare über nicht erratbare GUID-Links bereitstellen, deren Gültigkeit zeitlich konfigurierbar begrenzt ist, und den Versand am Ticket dokumentieren. +Ergebnis: Externer Formularzugriff ist ohne Login möglich, aber zeitlich und über die GUID beschränkt. +Belege: + - [PRIMÄR] src\backend\Centron.BL\SelfCare\SelfCareBL.cs, GetWebFormByGuid(): Ablaufprüfung mit ticketPatternSettings.WebFormLinkExpirationInMinutes, Fallback TimeSpan.FromDays(7) - Begründung: Durchgesetzte Zugriffsbegrenzung. + - [PRIMÄR] src\backend\Centron.BL\SelfCare\SelfCareBL.cs, SaveWebForm(): "if (webform.Guid == Guid.Empty) webform.Guid = Guid.NewGuid(); webform.SBOUrl = $\"{baseUrl...}/webform/{webform.Guid}\"" - Begründung: GUID-basierte Adressierung. + - [SEKUNDÄR] src\backend\Centron.BL\SelfCare\SelfCareBL.cs, SendWebFormMail(): AddMailToHelpdesk(...) - Begründung: Dokumentation des Versands am Ticket. +Prüfidee: Webformular senden, Link innerhalb der Frist öffnen — Formular erscheint; nach Frist — Fehler "Link has expired". +Tracelinks: StRS-504 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Muster für tokenbasierte Kundenzugriffe in SaaS. +Status: belegt +``` + +### SyRS-519: Umfrageversand im Ticketkontext + +``` +ID: SyRS-519 +Titel: Umfrageversand im Ticketkontext +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Service-Mitarbeiter (Abschluss), Kunde (Befragter), System +Vorbedingung: Umfragevorlage vorhanden; Surveys-Einstellungen aktiv (ValueAttachmentForHelpdesk, ValueHelpdeskSurveyI3D); Kundenkontakt als Account-Kontakt auflösbar +Fakt: Beim Ticketabschluss ergänzt HelpdeskCloseBL.AddSurvey() die Abschlussmail um eine aus der Vorlage instanziierte Umfrage (GetSurveyfromTemplate); die Instanz erhält Status SurveyStatus.Open, Objektbezug (ObjectKind=HelpdeskClass, ObjectI3D=Ticket), Empfängerdaten und einen Link mit verschlüsselter Umfrage-ID (CryptoControl.EncryptToString) auf das ServiceBoard (SurveyModule?ID=...). +Aussage: Das System soll beim Abschluss eines Tickets optional automatisch eine kundenbezogene Umfrage aus einer Vorlage instanziieren, mit dem Ticket verknüpfen und dem Kunden per verschlüsseltem Web-Link zustellen. +Ergebnis: Kundenzufriedenheit wird ticketbezogen erhoben; Antworten sind der Ticketinstanz zuordenbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Accounts\Survey\SurveyProcessBL.cs, GetSurveyfromTemplate(): Kopie der Vorlage (IsCopy=true, TemplateI3D, Status=SurveyStatus.Open, ObjectKind/ObjectI3D) und Linkersetzung @@AuditLink@@ mit CryptoControl.EncryptToString(survey.I3D) - Begründung: Durchgesetzte Instanziierungs- und Verlinkungsregeln. + - [SEKUNDÄR] src\backend\Centron.BL\Sales\Support\HelpdeskCloseBL.cs, AddSurvey(): Konfig-Schalter surveySettings.ValueAttachmentForHelpdesk und Anfügen result.MailText an die Abschlussmail - Begründung: Kopplung an den Abschlussprozess. +Prüfidee: Umfrageanhang aktivieren, Ticket schließen — Abschlussmail enthält Umfrage-Link; Umfrage-Instanz existiert mit ObjectI3D = Ticket-I3D und Status Open. +Tracelinks: StRS-504 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Feedbackprozess mit klarem Objektbezug. +Status: belegt +``` + +### SyRS-520: Checklisten an Tickets mit Offen-Erkennung + +``` +ID: SyRS-520 +Titel: Checklisten an Tickets mit Offen-Erkennung +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Service-Mitarbeiter +Vorbedingung: Checklistenvorlage bzw. Checkliste am Objekt vorhanden +Fakt: Checklisten (CentronChecklist mit hierarchischen CheckListItems, State Open/…) werden generisch an Objekte gebunden (ObjectKind/ObjectI3D, u. a. HelpdeskClass); ObjectHasOpenChecklists() erkennt offene Blatt-Punkte; die Ticket-Statistik (GetHelpdeskHasOpenChecklistStatistic) meldet offene Checklisten an die Oberflächen (u. a. Nexus-Ticketnavigation). +Aussage: Das System soll Tickets mit strukturierten, hierarchischen Checklisten versehen können und offene Checklistenpunkte je Ticket erkennbar machen, damit ein Ticket nicht mit unerledigten Pflichtpunkten abgeschlossen wird. +Ergebnis: Bearbeitungsstand von Checklisten ist pro Ticket sichtbar und auswertbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\CheckListArea\CentronChecklistBL.cs, ObjectHasOpenChecklists(): Flatten der ChecklistItems und Prüfung State == CentronChecklistItemState.Open - Begründung: Implementierte Offen-Erkennung. + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskStatisticsBL.cs, GetHelpdeskHasOpenChecklistStatistic(helpdeskI3D) - Begründung: Ticketbezogene Bereitstellung der Offen-Information. + - [SEKUNDÄR] src\nexus\CentronNexus\...\TicketMainNavigation.razor.g.cs, "checklistStatistic.HasOpenChecklists" - Begründung: UI-Auswertung der offenen Checklisten am Ticket. +Prüfidee: Checkliste mit zwei Punkten anlegen, einen erledigen — HasOpenChecklists = true; beide erledigen — false. +Tracelinks: StRS-501 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - generischer Objektbezug ist wiederverwendbar; ein hartes Abschluss-Gate bei offenen Punkten wurde nicht gefunden (siehe Selbstbewertung). +Status: belegt +``` + +## Cluster A6 — Stammdaten & Assets — SyRS + +### SyRS-605: Berechtigungsprüfung aller Geschäftspartner-Operationen + +``` +ID: SyRS-605 +Titel: Berechtigungsprüfung aller Geschäftspartner-Operationen +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Angemeldeter Benutzer (AppUser); Web-Account (abgewiesen) +Vorbedingung: Aufruf einer Account-Operation (Laden, Anlegen, Ändern, Löschen, Entsperren) über BL/WebService +Fakt: AccountBL.ValidateUserRights prüft je Operation die Rechte CREATE_CUSTOMER, EDIT_CUSTOMER, DELETE_CUSTOMER, SEARCH_CUSTOMER, UNLOCK_CUSTOMER, RIGHT_LIEFERANTANLEGEN, RIGHT_LIEFERANTAENDERN und liefert bei Fehlen `Result.AsError(..., DefaultMessageCodes.RightCheckFailed)`; Web-Account-Logins werden pauschal abgewiesen ("Webaccount hat keine Rechte für diese Aktion"). +Aussage: Das System soll vor jeder Lese-, Anlage-, Änderungs-, Lösch- und Entsperr-Operation auf Geschäftspartnern das jeweils zugehörige Benutzerrecht prüfen und Operationen ohne Recht mit einer Rechtefehlermeldung abweisen; Web-Accounts (Kundenzugänge) sollen keine Geschäftspartner-Verwaltungsoperationen ausführen dürfen. +Ergebnis: Nur berechtigte interne Benutzer verändern Geschäftspartnerdaten. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Accounts\AccountBL.cs, ValidateUserRights(int appUserI3D, ...): `if (!checkRightsResult.Contains(UserRightsConst.Sales.Customer.CustomerCommon.CREATE_CUSTOMER)) return Result.AsError("Fehlende Rechte um Accounts zu erstellen", DefaultMessageCodes.RightCheckFailed)` (analog für EDIT/DELETE/SEARCH/UNLOCK/Lieferant) - Begründung: durchsetzende Prüfstelle je Operation. + - [PRIMÄR] src\backend\Centron.BL\Accounts\AccountBL.cs, ValidateUserRights(LoggedInUser ...): `if (loggedInUser.IsWebAccountLogin) return Result.AsError("Webaccount hat keine Rechte für diese Aktion", ...)` - Begründung: Abweisung von Web-Accounts. +Prüfidee: Benutzer ohne EDIT_CUSTOMER ruft SaveAccount für Bestandsaccount auf → Ergebnis RightCheckFailed; mit Recht → Erfolg. +Tracelinks: StRS-601 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - feingranulare Operationsrechte sind für die Neuimplementierung zu erhalten. +Status: belegt +``` + +### SyRS-606: Integrität des Geschäftspartnerstamms (Nummern, Eindeutigkeit, Löschschutz) + +``` +ID: SyRS-606 +Titel: Integrität des Geschäftspartnerstamms +Ebene: SyRS +Typ: Daten +Qualitätsmerkmal: +Akteur: System (Nummernvergabe), Benutzer (Löschen) +Vorbedingung: Anlage bzw. Löschung eines Accounts +Fakt: Account-, Kunden- und Lieferantennummern werden bei Neuanlage aus Nummernkreisen (NumberGroupBL.GetNextNumber, NumberGroupEnum.Account/Customer/Supplier) vergeben und per Unique-Index (IX_Accounts_Number, IX_AccountCustomers_UniqueNumber, IX_AccountSuppliers_UniqueNumber) abgesichert; DeleteAccount verweigert die Löschung bei offenen Posten, offenen Helpdesks oder aktiven Verträgen. +Aussage: Das System soll Geschäftspartnern bei Anlage automatisch eindeutige Nummern aus konfigurierbaren Nummernkreisen zuweisen, die Eindeutigkeit auf Datenbankebene erzwingen und die Löschung eines Geschäftspartners verweigern, solange abhängige offene Vorgänge (offene Posten, Tickets, aktive Verträge) existieren. +Ergebnis: Kein Nummern-Duplikat; keine verwaisten offenen Vorgänge durch Löschung. +Belege: + - [PRIMÄR] SSMS_DB_SCHEMA.sql, `CREATE UNIQUE NONCLUSTERED INDEX [IX_Accounts_Number] ON [dbo].[Accounts]`, `CONSTRAINT [IX_AccountCustomers_UniqueNumber] UNIQUE`, `CONSTRAINT [IX_AccountSuppliers_UniqueNumber] UNIQUE` - Begründung: DB-seitige Eindeutigkeit der Nummern. + - [PRIMÄR] src\backend\Centron.BL\Accounts\AccountBL.cs, DeleteAccount: Prüfungen mit Fehlern "Account kann nicht gelöscht werden da noch offene Posten/Heldesks/Verträge vorhanden sind" (DefaultMessageCodes.InvalidDeleteRequest) - Begründung: durchgesetzter Löschschutz. +Prüfidee: Zwei Accounts parallel anlegen → unterschiedliche Nummern; Account mit offener Rechnung löschen → Fehler InvalidDeleteRequest. +Tracelinks: StRS-601 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Nummernkreise und Löschschutz sind buchhaltungsrelevant. +Status: belegt +``` + +### SyRS-607: Systemweit eindeutige Benutzer-Logins über Kontoarten hinweg + +``` +ID: SyRS-607 +Titel: Systemweit eindeutige Benutzer-Logins über Kontoarten hinweg +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Administrator (Anlage AppUser), Innendienst (Anlage WebAccount) +Vorbedingung: Anlage/Änderung eines Benutzernamens +Fakt: AppUserBL.SaveOrUpdateAppUser prüft den Login-Namen (case-insensitiv, getrimmt) gegen bestehende AppUser UND WebAccounts; WebAccountBL.CheckDuplicateUsername prüft umgekehrt gegen WebAccounts UND AppUser; zusätzlich wird der OpenIdConnectSubjectIdentifier auf Eindeutigkeit geprüft. +Aussage: Das System soll Benutzernamen interner Benutzer und kundenseitiger Web-Accounts in einem gemeinsamen Namensraum führen und Dubletten (unabhängig von Groß-/Kleinschreibung und führenden/abschließenden Leerzeichen) in beide Richtungen abweisen; ebenso soll eine OpenID-Connect-Benutzerkennung nur einem Benutzer zugeordnet sein. +Ergebnis: Ein Login-Name identifiziert systemweit genau ein Konto. +Belege: + - [PRIMÄR] src\backend\Centron.BL\EmployeeArea\AppUserBL.cs, SaveOrUpdateAppUser: Prüfung `dbAppUser.Name.ToLower().Trim() == appUser.Name.ToLower().Trim()` und WebAccount-Gegencheck mit Fehler "Der Benutzer Login ist bereits an den WebAccount ... vergeben." - Begründung: durchsetzende Dublettenprüfung Richtung AppUser→WebAccount. + - [PRIMÄR] src\backend\Centron.BL\Administration\Logins\WebAccountBL.cs, CheckDuplicateUsername: Prüfung gegen WebAccount und AppUser mit Fehlern "Der Benutzername ist bereits vergeben." / "Der Benutzer Login ist bereits an Mitarbeiter ... vergeben." - Begründung: Gegenrichtung WebAccount→AppUser. +Prüfidee: WebAccount "max" anlegen, danach AppUser "MAX " anlegen → Fehlermeldung; OpenID-Subject doppelt vergeben → Fehlermeldung. +Tracelinks: StRS-602 +Konsolidierung: Kandidat: AppUser (Mitarbeiter-Login) und WebAccount (Kunden-Login) sind zwei getrennte Konto-Implementierungen mit doppelt implementierter, wechselseitiger Dublettenprüfung. +Übernahmewürdigkeit: übernehmen - gemeinsamer Login-Namensraum ist sicherheitsrelevant; Implementierung sollte zentralisiert werden. +Status: belegt +``` + +### SyRS-608: Geschützte Mitarbeiterverwaltung mit automatischer Personalakte + +``` +ID: SyRS-608 +Titel: Geschützte Mitarbeiterverwaltung mit automatischer Personalakte +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Personalverantwortlicher +Vorbedingung: Benutzer speichert einen Mitarbeiter +Fakt: SaveOrUpdateEmployee verlangt ADMINISTRATE_ALL_EMPLOYEES (20400053) und legt beim Speichern automatisch eine Ordnerstruktur der Personalakte an (Wurzelordner aus AppSetting EmployeeRootDirectory, Unterordner "Zertifikate", "Verträge", "Gesprächsnotizen", "Bewerbungsunterlagen", "Sonstige Dokumente", "Qualitäts Management", "Skills"); AppUserBL.SaveOrUpdateAppUser verlangt RIGHT_PERSONALMANAGEMENT (10520). +Aussage: Das System soll Mitarbeiterdaten nur Benutzern mit Personalverwaltungsrecht zur Pflege freigeben und beim Anlegen eines Mitarbeiters automatisch eine standardisierte Dokumenten-Ordnerstruktur (Personalakte) erzeugen. +Ergebnis: Personaldaten sind zugriffsgeschützt; jede Personalakte hat dieselbe Ablagestruktur. +Belege: + - [PRIMÄR] src\backend\Centron.BL\EmployeeArea\EmployeeBL.cs, SaveOrUpdateEmployee: Rechteprüfung ADMINISTRATE_ALL_EMPLOYEES und DirectoryBL.CreateDirectory-Aufrufe für die genannten Unterordner - Begründung: durchsetzende Prüfung und automatische Strukturanlage in einer Methode. + - [PRIMÄR] src\backend\Centron.BL\EmployeeArea\AppUserBL.cs, SaveOrUpdateAppUser: `if (!_appRightsBL.HasUserRight(loggedInUser.I3D, UserRightsConst.RIGHT_PERSONALMANAGEMENT)) return ... AsError("You need the right personal management")` - Begründung: Rechteprüfung der Benutzerkontenpflege. +Prüfidee: Mitarbeiter ohne Personalrecht speichern → Fehler; mit Recht speichern → Ordnerbaum mit 7 Standardunterordnern existiert. +Tracelinks: StRS-602 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Grundfunktion; Ordnerstruktur ggf. konfigurierbar machen. +Status: belegt +``` + +### SyRS-609: Verwaltung von Druckerstammblättern mit Vertrags- und Zählerbindung + +``` +ID: SyRS-609 +Titel: Verwaltung von Druckerstammblättern mit Vertrags- und Zählerbindung +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertragsverwalter, Servicemitarbeiter +Vorbedingung: Kunde vorhanden; Stammblatt wird angelegt, geschlossen oder geändert +Fakt: MasterDataListBL.SaveMasterDataList validiert genau eine Hauptposition mit Menge 1, vergibt Nummer=I3D, legt einen Stammblatt-Ordner an, verbucht Barcodes und schreibt ReceiptLog-Einträge; CloseMasterDataList verweigert das Schließen, wenn das Stammblatt einem aktiven Vertrag (ReceiptContract.State == ReceiptState.Active) zugeordnet ist; Seriennummern-Entfernung/-Tausch scheitert bei aktiven Klickzählern. +Aussage: Das System soll je abrechnungsrelevantem Gerät (Drucker/Kopierer) ein Stammblatt mit genau einem Hauptgerät, Seriennummer, Klickzählern und Vertragszuordnung führen; Statuswechsel (schließen/reaktivieren) und Seriennummernwechsel sollen nur zulässig sein, wenn keine aktiven Verträge bzw. Zähler entgegenstehen, und protokolliert werden. +Ergebnis: Abrechnungsbasis der Click-Verträge bleibt konsistent und nachvollziehbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\CustomerAssets\Contracts\ClickContracts\MasterDataListBL.cs, SaveMasterDataList (Fehler "Es muss eine Hauptposition definiert sein." / "Es darf nur eine Hauptposition geben." / "Die Hauptposition darf nur einen Artikel beinhalten.") und CloseMasterDataList (Fehler "Stammblatt ist einem aktiven Vertrag zugeordnet.") - Begründung: durchgesetzte Integritäts- und Statusregeln. + - [PRIMÄR] ebd., RemoveMainDeviceSerialNumber/HasActiveCountersOnSerialNumber (Fehler "Seriennummer kann nicht entfernt werden, weil noch aktive Zähler hängen. ...") - Begründung: Zählerbindung als Abrechnungsschutz. +Prüfidee: Stammblatt ohne Hauptposition speichern → Fehler; Stammblatt mit aktivem Vertrag schließen → Fehler DependencyCheckFailed. +Tracelinks: StRS-603 +Konsolidierung: Kandidat: siehe StRS-603 (Stammblätter vs. AccountDevices). +Übernahmewürdigkeit: übernehmen - abrechnungsrelevante Kernlogik der Click-Verträge. +Status: belegt +``` + +### SyRS-610: Kundengeräteverwaltung (Assets) mit Historie und Ticketbezug + +``` +ID: SyRS-610 +Titel: Kundengeräteverwaltung (Assets) mit Historie und Ticketbezug +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Support-Mitarbeiter +Vorbedingung: Kunde vorhanden +Fakt: AccountDeviceBL verwaltet AccountDevices (ShortName, DeviceId, SerialNumber, Model, Manufacturer, Location, WarrantyExpiryDate, OriginKind, URIs); Löschen setzt IsDeleted/DeletedDate/DeletedByI3D (Soft-Delete); jede Anlage/Änderung/Löschung schreibt einen AccountDeviceLog-Eintrag; AccountDeviceToTicket verknüpft Geräte mit Tickets; Suche filtert IsDeleted standardmäßig aus. +Aussage: Das System soll sonstige Kundengeräte mit Identifikations- und Garantiedaten führen, Geräte nur logisch löschen (Soft-Delete mit Benutzer/Zeitstempel), jede Änderung in einem Gerätelog protokollieren und Geräte mit Support-Tickets verknüpfen können. +Ergebnis: Gerätehistorie und Ticketbezug bleiben auch nach Löschung nachvollziehbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Devices\AccountDeviceBL.cs, DeleteAccountDevice (setzt IsDeleted=true, DeletedDate, DeletedByI3D) und WriteAccountDeviceLog; SaveAccountDevice (Log "Das Gerät wurde erstellt/aktualisiert von ...") - Begründung: durchgesetzter Soft-Delete und Protokollierung. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[AccountDevices], [AccountDeviceLogs], [AccountDevicesToTickets], [AccountDeviceUris] - Begründung: Datenmodell für Gerät, Log, Ticketverknüpfung, URIs. +Prüfidee: Gerät löschen und danach SearchAccountDevices ohne IncludeDeleted aufrufen → Gerät fehlt; AccountDeviceLogs enthält Lösch-Eintrag. +Tracelinks: StRS-603 +Konsolidierung: Kandidat: siehe StRS-603. +Übernahmewürdigkeit: übernehmen - Historie/Soft-Delete übernehmen; Datenhaltung mit Stammblättern zusammenführen. +Status: belegt +``` + +### SyRS-611: Konfigurierbare Zusatzfelder und Tags je Objektart + +``` +ID: SyRS-611 +Titel: Konfigurierbare Zusatzfelder und Tags je Objektart +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator (Definition), Fachanwender (Werteerfassung) +Vorbedingung: Objektart (CentronObjectKindNumeric) bekannt +Fakt: ModuleCustomPropertyBL.SaveCustomPropertyStructure validiert Name und Datentyp je Zusatzfeld und speichert Definitionen je ObjectKind/ObjectI3D; Werte werden typisiert in ModuleCustomPropertyValues abgelegt; Löschen einer Definition löscht kaskadierend alle Werte; TagsBL normalisiert Tags (lowercase/trim) und verwendet vorhandene Tags wieder; Objekte sind über Zusatzfeldwerte durchsuchbar (SearchObjectsThroughCustomProperties). +Aussage: Das System soll je Objektart frei definierbare Zusatzfelder (Datentyp, Kategorie, Sortierung, Pflichtkennzeichen, Wertemaske, Versiegelung) sowie freie Schlagworte (Tags) bereitstellen, Werte typgerecht speichern und in der Suche berücksichtigen. +Ergebnis: Fachliche Erweiterungen ohne Schemaänderung; konsistente Wiederverwendung von Tags. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Customization\ModuleCustomPropertyBL.cs, SaveCustomPropertyStructure (Fehler "At least one of the properties got no name." / "... unknown datatype") und DeleteCustomProperties (kaskadierendes Löschen der Values) - Begründung: durchgesetzte Definitions- und Konsistenzregeln. + - [PRIMÄR] src\backend\Centron.BL\Tags\TagsBL.cs, AddTicketTag/GetTag/AddTag (Caption.ToLower().Trim(), Wiederverwendung vorhandener Tags) - Begründung: Tag-Normalisierung und -Wiederverwendung. +Prüfidee: Zusatzfeld ohne Namen speichern → Fehler; Tag "Server " zweimal vergeben → nur ein Tags-Datensatz, zwei TicketTags. +Tracelinks: StRS-604 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zentrales Customizing-Instrument. +Status: belegt +``` + +### SyRS-612: Externe Objektreferenzen zu Fremdsystemen + +``` +ID: SyRS-612 +Titel: Externe Objektreferenzen zu Fremdsystemen +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Integrationsdienste (z. B. DocBee), interne Module +Vorbedingung: c-entron-Objekt (beliebige Objektart) existiert +Fakt: ObjectExternalReferenceBL verwaltet ObjectExternalReferences (ObjectI3D, ObjectKind, ExternalReferenceType, ExternalReferenceID, Caption, Info, RelationType, Timestamp); CreateReference erzwingt ObjectI3D > 0, nicht-leeren Typ und nicht-leere externe ID und weist bereits existierende Kombinationen ab; FindByExternalReference löst externe IDs zu c-entron-Objekten auf. +Aussage: Das System soll je Objekt beliebig viele eindeutige Verknüpfungen zu externen Systemen (Systemtyp + externe ID) speichern, Duplikate derselben Verknüpfung abweisen und die Rückauflösung von externer ID auf das interne Objekt unterstützen. +Ergebnis: Bidirektionale Zuordnung zwischen c-entron-Objekten und Fremdsystem-Objekten. +Belege: + - [PRIMÄR] src\backend\Centron.BL\ObjectExternalReferences\ObjectExternalReferenceBL.cs, CreateReference: Existenzprüfung und Fehler "External reference ... already exists for object ..." sowie Pflichtprüfungen auf Typ/ID - Begründung: durchgesetzte Eindeutigkeit und Pflichtfelder. + - [SEKUNDÄR] ebd., Klasse ObjectExternalReferenceTypes (Konstante "DocBee") - Begründung: benennt konkreten Fremdsystemtyp. +Prüfidee: Zweimal dieselbe Referenz (Objekt, "DocBee", ID) anlegen → zweiter Aufruf liefert Fehler; FindByExternalReference("DocBee", ID) liefert das Objekt. +Tracelinks: StRS-604 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - generischer Integrationsmechanismus, gut für SaaS-Schnittstellen. +Status: belegt +``` + +### SyRS-613: Länder- und Regionsstamm als zentrale Referenzdaten mit Kurspflege + +``` +ID: SyRS-613 +Titel: Länder- und Regionsstamm als zentrale Referenzdaten mit Kurspflege +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator, System (Kursaktualisierung) +Vorbedingung: Länderstamm gepflegt; Internetzugang für Kursabruf +Fakt: CountryBL verwaltet Länder (Tabelle Laenkenn) mit Kürzel, Währung (CurrencyISO, KursZuEur), MwSt-/Erlöskonten und Standard-Kennzeichen (GetDefaultCountry: f.Default); UpdateCurrencyRateByRateDictionary lädt Tageskurse der EZB (http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml) und aktualisiert alle aktiven Länder gleicher Währung; für Standardland "Schweiz" werden Kurse auf CHF-Basis umgerechnet; FederalStateBL verwaltet Bundesländer/Regionen mit Aktiv-Status. +Aussage: Das System soll einen zentralen Länderstamm (inkl. Währung, Wechselkurs, Steuer-/Kontenbezug, Standardland) und Regionen (Bundesländer) führen und Wechselkurse automatisiert aus der EZB-Referenzkursliste aktualisieren, bei abweichender Hauswährung (CHF) mit Umrechnung. +Ergebnis: Alle Module greifen auf konsistente Länder-, Währungs- und Kursdaten zu. +Belege: + - [PRIMÄR] src\backend\Centron.BL\CountryArea\CountryBL.cs, UpdateCurrencyRateByRateDictionary (EZB-XML-Abruf, CalculateCHFCurrencies bei defaultCountry == "Schweiz") und GetDefaultCountry (f.Default) - Begründung: implementierte Kurspflege und Standardland-Logik. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[Laenkenn] (Spalten Waehrung, KursZuEur, MwstArt, ErloesKTO, Standard, EUMitglied) - Begründung: Datenmodell des Länderstamms. +Prüfidee: Kursaktualisierung ausführen → KursZuEur aller aktiven Länder mit EZB-Währung entspricht Tageskurs; bei Mandant Schweiz sind Kurse CHF-relativ. +Tracelinks: StRS-604 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - EZB-Abruf per HTTP (unverschlüsselt, fest codierte URL) im BL ist historischer Behelf; Funktion übernehmen, Umsetzung als konfigurierbarer Kursdienst neu. +Status: belegt +``` + +## Cluster A7 — Kommunikation & persönliche Organisation — SyRS + +### SyRS-711: Mailversand über konfigurierbaren Transportkanal + +``` +ID: SyRS-711 +Titel: Mailversand über konfigurierbaren Transportkanal (SMTP / Exchange-EWS / Microsoft Graph) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: System (Mailversand-Dienst), Administrator +Vorbedingung: Mandantenweite Mail-Einstellung ApplicationSettingID.CentronWebserviceMailType ist gesetzt +Fakt: CentronMailFactory.GetMail() liest CentronWebserviceMailType und liefert ExchangeMail, GraphMail oder (Default) SMTPMail; alle drei erben von CentronMailBase (From/To/CC/BCC/Subject/Body/Attachments) und implementieren SendMail()/SendAndWaitForMail(). +Aussage: Das System soll ausgehende E-Mails über einen zentral konfigurierten Transportkanal (SMTP, Exchange Web Services oder Microsoft Graph) versenden, wobei alle Versandwege dieselbe fachliche Mail-Schnittstelle bedienen. +Ergebnis: Fachmodule versenden Mails kanalunabhängig; Kanalwechsel erfordert nur eine Einstellungsänderung. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Mail\Factory\CentronMailFactory.cs, GetMail(): `return centronMailType switch { Exchange => new ExchangeMail(...), Graph => new GraphMail(...), _ => new SMTPMail(...) }` - Begründung: durchgesetzte Kanalauswahl. + - [PRIMÄR] src\backend\Centron.BL\Mail\Protocols\CentronMailBase.cs: abstrakte Basisklasse mit SendMail()/SendAndWaitForMail() - Begründung: einheitlicher Versandvertrag für alle Kanäle. +Prüfidee: Einstellung CentronWebserviceMailType zwischen 0/1/2 umschalten und per Instrumentierung verifizieren, dass jeweils SMTP-, EWS- bzw. Graph-Endpunkt angesprochen wird. +Tracelinks: StRS-701 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kanal-Abstraktion ist gutes Zielbild; EWS gilt bei Microsoft als auslaufend, Graph als Zielkanal. +Status: belegt +``` + +### SyRS-712: Freischaltung von Absenderadressen beim Mailversand + +``` +ID: SyRS-712 +Titel: Freischaltung von Absenderadressen beim Mailversand +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Mitarbeiter (Mailversand über Webservice), System +Vorbedingung: Mitarbeiter übergibt eine abweichende Absenderadresse (mailFrom) +Fakt: SendMailWebserviceBL.CheckFromAdress() erlaubt als Absender nur: konfigurierte Systemadressen (ExchangeUsername, HelpdeskSenderEmailAddress, InvoiceAndCreditVouchersSenderEmailAddress, SmtpDefaultReturnAddress, EscalationMailSender, GraphFallbackSenderEmail), die eigene Mitarbeiter-E-Mail sowie die Whitelist ApplicationSettingID.AllowedEmails; sonst wird eine Exception mit Verweis auf "Erlaubte E-Mail-Adresse" geworfen. +Aussage: Das System soll den Versand nur mit explizit freigeschalteten Absenderadressen zulassen und beliebiges Absender-Spoofing durch Benutzer verhindern. +Ergebnis: Versandversuch mit nicht freigeschalteter Absenderadresse wird mit verständlicher Fehlermeldung abgelehnt. +Belege: + - [PRIMÄR] src\backend\Centron.BL\WebServices\Mail\SendMailWebserviceBL.cs, Z. 398–404 + CheckFromAdress() (Z. 459 ff.): `if (this.CheckFromAdress(user, mailFrom, settings)) throw new Exception("Die angegebene E-Mail-Adresse {mailFrom} ist nicht für den Mailversand freigeschaltet...")` - Begründung: durchsetzende Prüfstelle inkl. konkreter Bedingung (Whitelist-Abgleich, OrdinalIgnoreCase). + - [SEKUNDÄR] src\backend\Centron.BL\Mail\MailSettingsBL.cs, GetMailSettings(): AllowedEmails wird als Semikolon-Liste aus ApplicationSettingID.AllowedEmails gelesen - Begründung: Konfigurationsquelle der Whitelist. +Prüfidee: Mailversand mit fremder Absenderadresse (nicht in Whitelist) muss abgelehnt werden; nach Aufnahme in AllowedEmails muss derselbe Versand gelingen. +Tracelinks: StRS-701 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - wirksamer Spoofing-Schutz, in SaaS-Umgebung zwingend (ggf. um Domain-Verifizierung erweitern). +Status: belegt +``` + +### SyRS-713: Mail-Vorlagenverwaltung mit Kontext-Hierarchie und Variablen + +``` +ID: SyRS-713 +Titel: Mail-Vorlagenverwaltung mit Kontext-Hierarchie und Variablenersetzung +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator (Vorlagenpflege), Mitarbeiter (Vorlagennutzung) +Vorbedingung: Vorlagen sind je Objektart (ObjectKind/SubObjectKind/ObjectI3D) gepflegt +Fakt: MailTemplateBL identifiziert Vorlagen eindeutig über die Kombination ObjectKind/SubObjectKind/ObjectI3D/TemplatePrio (Tabelle MailVorlagen, dokumentiert in create-mail-templates.md), löst sie in fester Prioritätsreihenfolge Account > Employee > Branch > Global > Default auf und ersetzt Textvariablen (z. B. {BearbeiterName}, {KundenNummer}) vor dem Versand. +Aussage: Das System soll E-Mail-Vorlagen je Geschäftsvorgang verwalten, sie kontextabhängig (Kunde, Mitarbeiter, Filiale, global, Systemstandard) auflösen und Platzhalter zur Laufzeit mit Daten des Vorgangs füllen. +Ergebnis: Beim Mailversand aus einem Vorgang wird automatisch die spezifischste passende Vorlage mit befüllten Variablen vorgeschlagen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Mail\Templates\MailTemplateBL.cs, MailTemplate() (Z. 261–317): dokumentierte und implementierte Fallback-Reihenfolge "1. Account 2. Employee 3. Branch 4. Global 5. Default" - Begründung: durchgesetzte Auflösungsregel. + - [PRIMÄR] src\backend\Centron.BL\Mail\Templates\MailTemplateBL.cs, ReplaceVariablesInMailTemplateText()/GenerateVariables(): Variablengruppen "Allgemein", "Bearbeiter", "Kunde", "Adresse", "Ansprechpartner" - Begründung: durchgesetzte Variablenersetzung. + - [KONTEXT] docs\guides\development\create-mail-templates.md: Struktur MailTemplateReference (ObjectKind, ObjectI3D, SubObjectKind, TemplatePrio) - Begründung: dokumentiert Identifikationsschema der Vorlagen. +Prüfidee: Für denselben Belegtyp Vorlagen auf Kunden-, Mitarbeiter- und globaler Ebene anlegen; der Versand aus einem Vorgang dieses Kunden muss die Kundenvorlage ziehen, nach deren Löschung die Mitarbeitervorlage. +Tracelinks: StRS-701 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - ausgereiftes, migriertes Vorlagensystem ("neue Struktur" laut Doku); Altbestände außerhalb MailVorlagen nicht übernehmen. +Status: belegt +``` + +### SyRS-714: Virtual Mail Assistant (Mail-Eingangsverarbeitung) mit Zugriffsschutz + +``` +ID: SyRS-714 +Titel: Virtual Mail Assistant (Mail-Eingangsverarbeitung) mit Zugriffsschutz und verschlüsselten Postfach-Zugangsdaten +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: MailScanner-Dienst, Administrator +Vorbedingung: MailScanner-Profil (Postfach + Workflows) ist angelegt; Benutzer besitzt das Recht ACCESS_VMA_MODULE +Fakt: MailScannerBL.GetProfiles() prüft UserRightsConst.VirtualMailAssistant.ACCESS_VMA_MODULE (Konstante 20800112, verknüpft mit Lizenz MailScannerNET) und lehnt sonst mit "Fehlendes Recht VMA Profile zu laden" (DefaultMessageCodes.RightCheckFailed) ab; SaveProfile() verschlüsselt Password und ClientSecret vor dem Speichern per CentronConfigurationDbBL.EncryptWithMasterKey(). +Aussage: Das System soll die Verwaltung von Mail-Eingangs-Profilen (Postfachzugangsdaten, zugeordnete Workflows) nur Benutzern mit dem VMA-Modulrecht erlauben und Postfach-Passwörter/Client-Secrets ausschließlich verschlüsselt persistieren. +Ergebnis: Unberechtigte erhalten keine Profile; in der DB (MailScannerProfiles.Password/ClientSecret nvarchar(max)) liegen nur Chiffrate. +Belege: + - [PRIMÄR] src\backend\Centron.BL\MailScanner\MailScannerBL.cs, GetProfiles(): `if (rightsResult.Contains(UserRightsConst.VirtualMailAssistant.ACCESS_VMA_MODULE) == false) return Result...AsError("Fehlendes Recht VMA Profile zu laden", DefaultMessageCodes.RightCheckFailed)` - Begründung: durchsetzende Rechteprüfung mit konkreter Bedingung. + - [PRIMÄR] src\backend\Centron.BL\MailScanner\MailScannerBL.cs, EncryptProperties()/DecryptProperties(): EncryptWithMasterKey(profile.Password) und EncryptWithMasterKey(profile.ClientSecret) - Begründung: durchgesetzte Verschlüsselung der Zugangsdaten. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, Tabelle [dbo].[MailScannerProfiles] (Z. 44033 ff.): Spalten MailPassword/ClientSecret/Password als nvarchar(max) - Begründung: Persistenzort der (verschlüsselten) Geheimnisse. +Prüfidee: Profilabruf mit Benutzer ohne ACCESS_VMA_MODULE muss RightCheckFailed liefern; nach SaveProfile darf der DB-Spaltenwert nicht dem Klartext-Passwort entsprechen. +Tracelinks: StRS-701 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Rechte- und Verschlüsselungskonzept übernehmen; Lücke: SaveProfile()/DeleteProfile() prüfen das Recht selbst nicht (siehe Selbstbewertung). +Status: belegt +``` + +### SyRS-715: Terminvereinbarung mit Kunden über Terminvorschläge + +``` +ID: SyRS-715 +Titel: Terminvereinbarung mit Kunden über Terminvorschläge (AppointmentRequests) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Mitarbeiter (Anbieter der Termine), Kunde (antwortet über Guid-Link), Exchange-Server +Vorbedingung: Terminanfrage mit Guid und mindestens einem AppointmentProposal existiert; EWS-Zugangsdaten konfiguriert +Fakt: AppointmentRequestBL.HandleAppointmentRequestReply() lädt die Anfrage über reply.Guid; bei Annahme eines Vorschlags wird der Exchange-Termin um " (Akzeptiert)" ergänzt, der Kunde als RequiredAttendee eingeladen, Kategorie von "Terminvereinbarung (offen)" auf "Terminvereinbarung (akzeptiert)" umgestellt und alle übrigen Vorschlags-Termine gelöscht (SoftDelete); bei Ablehnung werden alle Vorschläge gelöscht und RequestState = AppointmentProposalsRejected gesetzt. +Aussage: Das System soll Kunden mehrere Terminvorschläge anbieten und deren Antwort automatisiert verarbeiten: der akzeptierte Vorschlag wird zum verbindlichen Exchange-Termin mit Einladung, alle nicht gewählten Vorschläge werden aus dem Kalender entfernt. +Ergebnis: Kalender des Mitarbeiters enthält nach Kundenantwort genau den akzeptierten Termin; Anfragestatus dokumentiert das Ergebnis. +Belege: + - [PRIMÄR] src\backend\Centron.BL\AppointmentRequests\AppointmentRequestBL.cs, HandleAppointmentRequestReply() (Z. 29–114): Statusübergänge AppointmentProposalsRejected / AppointmentProposalAccepted, Subject-Suffix "(Akzeptiert)", Kategorienwechsel, item.Delete(SoftDelete) für nicht gewählte Vorschläge - Begründung: vollständige, durchgesetzte Ablauflogik. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, Tabellen [dbo].[AppointmentRequests] (Z. 25557) und [dbo].[AppointmentProposals] (Z. 25533) - Begründung: Datenmodell der Anfragen und Vorschläge. +Prüfidee: Anfrage mit drei Vorschlägen erzeugen, Vorschlag 2 akzeptieren: Exchange enthält nur noch Termin 2 mit Kategorie "Terminvereinbarung (akzeptiert)" und Kundeneinladung; RequestState = AppointmentProposalAccepted. +Tracelinks: StRS-702 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - kundenwirksamer Selbstbedienungsprozess; EWS-Abhängigkeit bei Neuimplementierung durch Graph ersetzen. +Status: belegt +``` + +### SyRS-716: Konfigurierbare Outlook-/Exchange-Synchronisation und Outlook-Add-in + +``` +ID: SyRS-716 +Titel: Konfigurierbare Outlook-/Exchange-Synchronisation und Outlook-Add-in +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Administrator (Sync-Konfiguration), Mitarbeiter (Outlook-Add-in-Nutzer) +Vorbedingung: Exchange-/Graph-Anbindung eingerichtet +Fakt: CalendarBL verwaltet Synchronisationseinstellungen (OutlookAppointementCategory/-Place, benutzerdefinierte Betreffe/Mail-Texte, OvertakeHelpdeskTime, CrmActivityTypesForOutlookSync); das Blazor-Outlook-Add-in (CentronNexus.OutlookAddIn) zeigt zur geöffneten Mail kontextbezogen die Tabs "Kunden", "Dokumente", "Ticket", "Belege" anhand der Absenderadresse (SenderEmail). +Aussage: Das System soll die Outlook-Synchronisation (Kategorien, Ort, Betreff- und Mailtexte, zu synchronisierende CRM-Aktivitätstypen) mandantenweit konfigurierbar machen und Mitarbeitern im Outlook-Client ein Add-in bereitstellen, das zur geöffneten E-Mail die zugehörigen ERP-Daten (Kunde, Dokumente, Tickets, Belege) anzeigt. +Ergebnis: Synchronisierte Termine tragen die konfigurierte Kategorie; Mitarbeiter erreichen ERP-Kontext ohne Outlook zu verlassen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Calendar\CalendarBL.cs, GetCalendarSynchronizationSettings()/UpdateCalendarSynchronizationSettings(): Lese-/Schreiblogik über AppSettingsConst.OutlookAppointement* und ApplicationSettingID.CrmActivityTypesForOutlookSync - Begründung: durchgesetzte Konfigurationsschnittstelle. + - [PRIMÄR] src\nexus\CentronNexus.OutlookAddIn\OutlookIndexPage.razor: DxTabs "Kunden"/"Dokumente"/"Ticket"/"Belege", CustomerTab mit SenderEmail-Parameter - Begründung: implementierte Add-in-Oberfläche mit Mail-Kontextbezug. + - [KONTEXT] docs\features\exchange-sync-bugprotokoll.md - Begründung: dokumentiert produktive Sync-Pfade (SyncOldSchedule, UpdateScheduleByGraph) und deren Regeln. +Prüfidee: Outlook-Kategorie in den Einstellungen ändern; neu synchronisierte Termine müssen die neue Kategorie tragen. Add-in mit Mail eines bekannten Kunden öffnen: Kunden-Tab zeigt dessen Konto. +Tracelinks: StRS-702 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Add-in-Ansatz (Kontext zur Mail) ist auch im Web-Zielbild tragfähig. +Status: belegt +``` + +### SyRS-717: Telefonie-Integration mit Anruferidentifikation und Anrufjournal + +``` +ID: SyRS-717 +Titel: Telefonie-Integration (TAPI/Teams) mit Anruferidentifikation und Anrufjournal +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: TAPI-Client, Microsoft-Graph-CallRecords-API, Mitarbeiter +Vorbedingung: Telefonie-Einstellungen (Präfixe, interne Rufnummernlänge) sind gepflegt +Fakt: PhoneCallBL persistiert Anrufe (PhoneCall mit WasOutgoing, WasConnected, DurationInSeconds, WasInternalCall), identifiziert Anrufer über SearchContactPersonByPhoneNumberV2() und synchronisiert Teams-Anrufe per Graph (SyncPhoneCalls), jedoch nur mit Lizenz LicenseGuids.GraphCalendarEventsAndCallsSync und nur für konfigurierte Sync-Mitglieder; PhoneSettingsBL verwaltet Wahl-Präfixe (TapiAmtPrefix, TapiLocalPrefix, TapiCountryPrefix), interne Rufnummernlänge und Aufbewahrung (DeleteTapiEntryAfterDays) sowie persönliche Einstellungen (PhoneConnectionType, Anzeige ein-/ausgehender Anrufdetails). +Aussage: Das System soll Telefonate aus TAPI- und Teams-Quellen in einem einheitlichen Anrufjournal erfassen, Anrufer automatisch Kontakten/Kunden zuordnen und die Telefonie zentral (Präfixe, interne Nummernlänge, Löschfristen) sowie je Mitarbeiter (Verbindungstyp, Detailanzeige) konfigurierbar machen. +Ergebnis: Vollständiges, kundenbezogenes Anrufjournal; interne Kurzwahlen werden von der Kundensuche ausgenommen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Tapi\PhoneCallBL.cs, SyncPhoneCalls(): `if (LicenseManager.Instance.HasLicense(LicenseGuids.GraphCalendarEventsAndCallsSync) == false) return;` und Filterung auf syncMemberSet in CreateSyncedPhoneCalls() - Begründung: durchgesetzte Lizenz- und Mitgliederprüfung des Teams-Syncs. + - [PRIMÄR] src\backend\Centron.BL\Administration\PhoneSettings\PhoneSettingsBL.cs, GetPhoneSettings()/UpdatePersonalSettings(): AppSettingsConst.Tapi* und EmployeeUserSettingKind.PhoneConnectionType/IsIncomingCallDetailsDisabled - Begründung: Konfigurationsschnittstelle global und je Mitarbeiter. +Prüfidee: Teams-Anruf eines Sync-Mitglieds erscheint nach Sync genau einmal im Journal; ohne Lizenz findet kein Sync statt; Rufnummer kürzer als InternalPhoneNumberLength löst keine Kundensuche aus. +Tracelinks: StRS-704 +Konsolidierung: Kandidat: TAPI-Anruferfassung (Client-seitig via CreatePhoneCall) und Graph-CallRecords-Sync erzeugen beide PhoneCall-Datensätze über getrennte Pfade mit eigener Dublettenlogik - bei Neuimplementierung vereinheitlichen. +Übernahmewürdigkeit: übernehmen - Journal und Identifikation übernehmen; TAPI-Weg ist im Web-Zielbild durch CTI-/Teams-Integration zu ersetzen. +Status: belegt +``` + +### SyRS-718: Benachrichtigungs- und Chat-System für Mitarbeiter + +``` +ID: SyRS-718 +Titel: Benachrichtigungs- und Chat-System für Mitarbeiter (NexusNotifications, Chats) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System (Ereignisquelle), Mitarbeiter (Empfänger) +Vorbedingung: Mitarbeiter ist als Empfänger betroffen (z. B. Ticket-Editor, Chat-Mitglied) +Fakt: NexusNotificationsBL erzeugt bei Änderung der Ticket-Bearbeiter Benachrichtigungen der Typen TicketAssigned/TicketUnassigned an neu zugewiesene bzw. entfernte Bearbeiter (ohne den Auslöser selbst), pflegt IsSeen/IsRead-Status und pusht über NotificationsHubHelper.SendNexusNotification an den Nexus-Client; ChatBL beschränkt jede Nachrichtenabfrage auf Chats, in denen der Benutzer Mitglied ist; ungelesene Chat-Nachrichten können per E-Mail nachgemeldet werden (GetUnreadChatMessageEmail/EmailSentMark). +Aussage: Das System soll Mitarbeiter über für sie relevante Ereignisse (insbesondere Ticket-Zu-/Abweisung) aktiv benachrichtigen, den Gelesen-/Gesehen-Status je Empfänger führen und Chat-Kommunikation nur Mitgliedern des jeweiligen Chats zugänglich machen. +Ergebnis: Empfänger sehen neue Benachrichtigungen in Echtzeit; Nicht-Mitglieder erhalten keinen Zugriff auf Chatinhalte. +Belege: + - [PRIMÄR] src\backend\Centron.BL\NexusNotifications\NexusNotificationsBL.cs, SaveForwardTicketNotifications() (Z. 133–174): Notification je neuem/entferntem Editor mit Type TicketAssigned/TicketUnassigned, Ausschluss `newEditor.EmployeeI3D != user.User.Employee.I3D`; NotifyNexus() pusht über Hub - Begründung: durchgesetzte Benachrichtigungsregel inkl. Push. + - [PRIMÄR] src\backend\Centron.BL\Chats\ChatBL.cs, GetFilterExpression(ChatMessageFilter, ...) (Z. 440–450): Grundausdruck `f => chatsQuery.Contains(f.ChatI3D)` mit chatsQuery = Chats mit eigener Mitgliedschaft - Begründung: durchgesetzte Zugriffsbeschränkung auf Mitglieds-Chats. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, Tabelle [dbo].[NexusNotifications] (Z. 45424): Spalten IsSeen/IsRead (bit NOT NULL), Type, UserI3D/UserKind - Begründung: Datenmodell des Empfänger-Status. +Prüfidee: Ticket einem zweiten Bearbeiter zuweisen: dieser erhält TicketAssigned-Notification, der Zuweisende selbst keine; Chat-Nachrichtenabruf eines Nicht-Mitglieds liefert leere Menge. +Tracelinks: StRS-703, StRS-704 +Konsolidierung: Kandidat: Notifications (CentronNotificationsBL/NotificationUser, WPF) und NexusNotifications (Web/Nexus) sind zwei getrennte Benachrichtigungs-Datenhaltungen für denselben fachlichen Zweck. +Übernahmewürdigkeit: übernehmen - Benachrichtigungsmodell übernehmen, aber die beiden Implementierungen zu einem Dienst konsolidieren. +Status: belegt +``` + +### SyRS-719: Tagesabschluss- und Aufgabenverwaltung (MyDay / ToDo) + +``` +ID: SyRS-719 +Titel: Tagesabschluss- und Aufgabenverwaltung (MyDay / ToDo) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Mitarbeiter, Teamleiter, Administrator +Vorbedingung: Mitarbeiter erfasst Arbeitszeiten/Aufgaben in MyDay bzw. erhält ToDos aus Geschäftsobjekten +Fakt: MyDayBL verwaltet Arbeitstag-Positionen (MyDayWorkItem) mit Deduplizierung über UniqueId, Serienerfassung über BatchId und Tagesabschlüsse (MyDayFinalizedDay); MyDayNotificationsBL erinnert Mitarbeiter ohne Tagesabschluss und eskaliert an Teamleiter; ToDoBL erzeugt und pflegt objektbezogene ToDos und schützt fremde ToDo-Listen über die Rechte RIGHT_FREMDTODOLISTE und RIGHT_FREMDTODOLISTEVERWERFEN. +Aussage: Das System soll die tägliche Zeit- und Aufgabenerfassung der Mitarbeiter mit verbindlichem Tagesabschluss, automatischer Erinnerung/Eskalation und rechtegeschütztem Zugriff auf fremde Aufgabenlisten bereitstellen. +Ergebnis: Abgeschlossene Tage sind dokumentiert und rücksetzbar (mit Protokoll); ToDos steuern den Arbeitsvorrat rechtssicher. +Belege: + - [PRIMÄR] src\backend\Centron.BL\ToDoArea\ToDoBL.cs, GetTodosThroughPaging() (Z. 250–261): `if (!settings.HasRightForAccessingTodoFromOtherUsers) filter.EmployeeI3D = user.Employee.I3D;` mit HasRightForAccessingTodoFromOtherUsers = HasUserRight(..., UserRightsConst.RIGHT_FREMDTODOLISTE) (Z. 1993) - Begründung: durchsetzende Rechteprüfung für Fremdzugriff. + - [PRIMÄR] src\backend\Centron.BL\MyDay\MyDayBL.cs, ResetFinalizedDay() (Z. 1255–1277): Löschen des MyDayFinalizedDay nur mit gleichzeitiger CentronNotification "Benutzer {X} hat den abgeschlossenen Tag {Datum} von {Y} zurückgesetzt." - Begründung: durchgesetzte Protokollierung des Abschluss-Resets. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, Tabellen [dbo].[MyDayFinalizedDays] (Z. 45109) und [dbo].[MyDayWorkItems] (Z. 45250) - Begründung: Persistenzmodell. +Prüfidee: Benutzer ohne RIGHT_FREMDTODOLISTE fragt ToDos mit fremdem EmployeeI3D-Filter ab und erhält nur eigene Einträge; Reset eines Tagesabschlusses erzeugt einen Protokolleintrag. +Tracelinks: StRS-703 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - abrechnungsnahe Zeiterfassungssteuerung, zentral für Dienstleistungsprozesse. +Status: belegt +``` + +## A8 — Web-Client Nexus & Service-Schnittstellen — SyRS + +### SyRS-811: Policy-basierter Zugriffsschutz der Nexus-Weboberfläche + +``` +ID: SyRS-811 +Titel: Policy-basierter Zugriffsschutz (LoginType, Rechte, WebRechte, Lizenz, Port) in Nexus +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Nexus-Webanwendung (Blazor Server), angemeldeter User oder Web-Account +Vorbedingung: Benutzer ist über Centron-Ticket angemeldet; Claims wurden aus dem Backend geladen +Fakt: CentronAuthorization registriert ASP.NET-Core-Policies für Login-Typ ("LoginTypeUser"/"LoginTypeWebaccount"), Mitarbeiterrechte ("EmployeeRights"), Web-Account-Rechte ("WebAccountRights"), Lizenzen ("License") und Ports; Seiten deklarieren diese über Attribute (AuthorizeLoginUser, AuthorizeLoginWebAccount, AuthorizeRightId, AuthorizeWebRight, AuthorizeLicense, AuthorizeHostPort, AuthorizeCustomerPortalPort), die von der AuthorizeRouteView durchgesetzt werden. +Aussage: Das System soll jede Nexus-Seite deklarativ gegen Login-Typ, Benutzer-/Web-Account-Rechte, Lizenzen und den erlaubten Netzwerk-Port autorisieren und bei fehlender Berechtigung die Darstellung verweigern. +Ergebnis: Nur Benutzer mit passendem Login-Typ, Recht, Lizenz und Zugriffsport sehen die jeweilige Seite. +Belege: + - [PRIMÄR] src\nexus\CentronNexus\Shared\Authorization\CentronAuthorization.cs - AddLoginTypeAuthorization/AddRightsAuthorization/AddWebAccountRightsAuthorization/AddLicenseAuthorization: je Policy "policyBuilder.RequireClaim(Prefix, loginType)" bzw. "RequireRole(role)" - Begründung: Durchsetzende Registrierung aller Autorisierungs-Policies. + - [PRIMÄR] src\nexus\CentronNexus\Shared\Authorization\Attributes\AuthorizeWebRightAttribute.cs - Konstruktor wirft ArgumentException ohne WebRight und mappt Rechte auf Roles - Begründung: Erzwingt, dass geschützte Seiten mindestens ein Web-Recht angeben. + - [PRIMÄR] src\nexus\CentronNexus.Host\Routes.razor - mit - Begründung: Durchsetzung der Seiten-Attribute beim Routing. + - [SEKUNDÄR] src\nexus\CentronNexus\WebCart\WebCartAdminPage.razor - "@attribute [AuthorizeLicense(nameof(LicenseGuids.WebCart2))]" + "@attribute [AuthorizeWebRight(WebAccountRightsConst.CUSTOMERADMINISTRATOR)]" - Begründung: Beispielhafte Verwendung auf einer Admin-Seite. +Prüfidee: Web-Account ohne CUSTOMERADMINISTRATOR-Recht ruft /webcart/admin auf → NotAuthorized-Ansicht; mit Recht → Seite wird gerendert. +Tracelinks: StRS-801, StRS-802 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - deklaratives Policy-Modell ist direkt in eine Web-Neuimplementierung übertragbar. +Status: belegt +``` + +### SyRS-812: Freigabewesen (Genehmigungsworkflow) für Web-Warenkörbe + +``` +ID: SyRS-812 +Titel: Mehrstufiges Freigabewesen für Warenkörbe im WebCart +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Web-Account (Ersteller), Prüfer (Web-Recht WEBRIGHT_WEBCART2_CHECK_CART), Einkäufer/Besteller (Web-Recht WEBRIGHT_WEBCART2_ORDER_CART) +Vorbedingung: Warenkorb (ReceiptCart, technisch ein ReceiptOffer mit IsCart=true) im Zustand des Freigabewesens; Lizenz WebCart2 +Fakt: ReceiptCartState definiert die Zustandsmaschine Created → ReadyForCheck → (Checked | DeclinedByChecker) → (Ordered | DeclinedByOrderer) mit Nachbesserungsschleifen; jeder Übergang prüft Web-Recht und erwarteten Ausgangszustand. +Aussage: Das System soll Web-Warenkörbe vor der Bestellung durch ein mehrstufiges Freigabewesen führen (Prüfung durch Prüfer, Bestellung durch Besteller), wobei jeder Statusübergang nur mit dem zugehörigen Web-Recht und aus dem korrekten Vorzustand möglich ist. +Ergebnis: Erst nach Prüfer- und Besteller-Freigabe entsteht aus dem Warenkorb ein Auftrag; Ablehnungen führen in einen Nachbesserungszustand. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptCartReleaseSystemBL.cs - UpdateReceiptCartState: ruft ThrowIfWebAccountDoesntHaveRight(right, currentUser) und wirft bei falschem Zustand "Der Warenkorb befindet sich bereits an einem anderen Schritt des Freigabewesens." (DefaultMessageCodes.BadRequest) - Begründung: Durchsetzende Stelle für Recht + Statusmaschine. + - [PRIMÄR] src\backend\Centron.Interfaces\Sales\Receipts\ReceiptCartState.cs - Enum Created/ReadyForCheck/Checked/DeclinedByChecker/Ordered/DeclinedByOrderer inkl. Mermaid-Workflow-Kommentar - Begründung: Definierte Zustandsmenge. + - [SEKUNDÄR] src\nexus\CentronNexus\WebCart\Components\WebCartClearance.razor - Aktionen OrderAsOrderer/DeclineAsOrderer/RerequestApproval... mit UI-Label "Freigabewesen" - Begründung: UI bildet den Workflow ab. +Prüfidee: Web-Account ohne WEBRIGHT_WEBCART2_ORDER_CART versucht Bestell-Freigabe eines Warenkorbs im Zustand Checked → ResultException RightCheckFailed; mit Recht → Zustand Ordered und Auftrag angelegt. +Tracelinks: StRS-801 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Genehmigungsworkflow ist ein fachlich wertvolles Differenzierungsmerkmal. +Status: belegt +``` + +### SyRS-813: Web-Angebot per Token einsehen, ändern und annehmen + +``` +ID: SyRS-813 +Titel: Token-basierte Angebotsannahme (WebOffer) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Angebotsempfänger (anonymer Browser-Nutzer mit Token-Link) +Vorbedingung: Zu einem Angebot wurde ein Web-Receipt-Token erzeugt und per Mail versendet +Fakt: Die Seite /weboffer/{Token} lädt den Beleg über GetReceiptForWeb(token); ohne zuordenbares Token wirft das Backend "Mit diesem Token ... wurde kein zugehöriger Beleg gefunden."; der Empfänger kann Positionen ändern (RequestForWebReceiptItemChange), Bestellnummer setzen und den Zustand wechseln (ChangeWebReceiptState: Rejected, AcceptFullWebReceipt, AcceptWebReceiptWithChangeRequests); Annahme ohne Signatur nur wenn AllowAcceptReceiptWithoutSignature. +Aussage: Das System soll Angebote über einen tokenisierten Link ohne Portal-Login bereitstellen, dem Empfänger Änderungswünsche und die Annahme bzw. Ablehnung ermöglichen und die Annahme abhängig von der Konfiguration an eine Signatur koppeln. +Ergebnis: Angenommene Web-Angebote lösen die Auftragserteilung (ggf. nach Signatur) aus; ungültige Tokens liefern keinen Belegzugriff. +Belege: + - [PRIMÄR] src\backend\Centron.BL\WebServices\Sales\Receipts\ReceiptWebServiceBL.cs - GetReceiptPdfDocument(token): Guard.NotNullOrWhiteSpace + throw "Mit diesem Token {token} wurde kein zugehöriger Beleg gefunden." - Begründung: Durchsetzende Token-Auflösung. + - [PRIMÄR] src\backend\Centron.Interfaces\Sales\Receipts\WebReceipt\WebReceiptState.cs - Zustände InProcess/AcceptFullWebReceipt/AcceptWebReceiptWithChangeRequests/Rejected/SendToCustomer/FirstLoaded/WebOfferSign/WebReceiptShutDown/WebOfferSignedWithoutSignature - Begründung: Zustandsmodell des Web-Angebots. + - [SEKUNDÄR] src\nexus\CentronNexus\WebOffer\WebReceiptOverview.razor - "_canExecuteAction = Receipt.AllowAcceptReceipt && isWebReceiptInProcess", "_canAcceptWithoutSignature = Receipt.AllowAcceptReceiptWithoutSignature && ...", Meldung "Bitte Signieren Sie das folgende Dokument um einen Auftrag zu erteilen." - Begründung: UI-Logik für Annahme mit/ohne Signatur. +Prüfidee: Aufruf /weboffer/{gültigesToken} zeigt das Angebot; Annahme ohne Signatur bei AllowAcceptReceiptWithoutSignature=false erzwingt Signatur-Dialog; ungültiges Token liefert Fehler. +Tracelinks: StRS-801 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - tokenisierte Angebotsannahme ist zeitgemäß und SaaS-tauglich. +Status: belegt +``` + +### SyRS-814: Einmalige Online-Signatur von PDF-Dokumenten + +``` +ID: SyRS-814 +Titel: Online-Signatur von Dokumenten über einmaligen GUID-Link +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Dokumentempfänger (anonymer Browser-Nutzer mit GUID-Link) +Vorbedingung: Für ein Dokument wurde ein OnlinePdfDocument mit GUID erzeugt und der Link versendet +Fakt: DsgvoBL.ConfirmOnlinePdfDocument lädt das OnlinePdfDocument per GUID, delegiert an einen ObjectKind-spezifischen Handler und löscht den Datensatz nach erfolgreicher Bestätigung (DeleteOnlinePdfDocument); die Signierseite zeigt bei fehlender GUID "Dieser Link ist nicht gültig oder wurde bereits verwendet." +Aussage: Das System soll das Signieren bzw. Ablehnen von Dokumenten (inkl. SEPA-Mandaten) über einen einmalig verwendbaren GUID-Link ermöglichen und den Link nach erfolgreicher Signatur entwerten. +Ergebnis: Ein bestätigtes Dokument kann über denselben Link nicht erneut signiert werden. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Documents\Dsgvo\DsgvoBL.cs - ConfirmOnlinePdfDocument: "var onlinePdf = ...GetEntity(f => f.Guid.Equals(id)); if (onlinePdf == null) return Result.AsError(...)" und "if (result.Status == ResultStatus.Success) this.DeleteOnlinePdfDocument(onlinePdf.I3D);" - Begründung: Durchsetzende Einmaligkeit des Links. + - [SEKUNDÄR] src\nexus\CentronNexus\DocumentSigning\DocumentSigningPage.razor - UI-Text "Dieser Link ist nicht gültig oder wurde bereits verwendet." - Begründung: Fachliche Bestätigung der Einmalverwendung. +Prüfidee: Dokument signieren, danach Link erneut öffnen → Fehlermeldung "kein Dokument gefunden"/ungültiger Link. +Tracelinks: StRS-801 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - einfacher, DSGVO-tauglicher Signaturprozess. +Status: belegt +``` + +### SyRS-815: Datenscoping des Kundenportals auf den eigenen Kunden + +``` +ID: SyRS-815 +Titel: Sichtbarkeitsbeschränkung von Portal-Tickets auf den eigenen Kunden +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Web-Account im Kundenportal +Vorbedingung: Web-Account-Login mit Web-Rechten (CUSTOMERADMINISTRATOR, SHOWALLEREQUESTS, SHOWONLYOWNREQUESTS oder WEBRIGHT_SHOWONLYNOTIFYTICKETS) +Fakt: HelpdeskSearchBL schränkt bei IsWebAccountLogin die Ticketsuche per Expression auf die CustomerI3Ds des Web-Accounts ein (bei CUSTOMERADMINISTRATOR zusätzlich Konzernkunden via GetCustomerCorporations) und filtert "!f.IsOnlyInternalVisible". +Aussage: Das System soll Web-Accounts im Kundenportal ausschließlich Tickets ihres eigenen Kunden (bzw. Konzernverbunds bei Kundenadministratoren) anzeigen und intern markierte Tickets generell ausblenden. +Ergebnis: Kein Web-Account sieht Tickets fremder Kunden oder rein interne Tickets. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskSearchBL.cs (ca. Zeilen 535-564) - "if (loggedInUser.IsWebAccountLogin) { ... expression = expression.And(f => customerI3Ds.Contains(f.CustomerI3D)); expression = expression.And(f => !f.IsOnlyInternalVisible); }" - Begründung: Durchsetzende serverseitige Datenfilterung. + - [SEKUNDÄR] src\nexus\CentronNexus\WebCart\WebCartTicketsPage.razor - "@attribute [AuthorizeWebRight(WebAccountRightsConst.SHOWALLEREQUESTS, WebAccountRightsConst.SHOWONLYOWNREQUESTS, WebAccountRightsConst.CUSTOMERADMINISTRATOR)]" - Begründung: Seitenzugriff nur mit Ticket-Web-Rechten. +Prüfidee: Zwei Web-Accounts verschiedener Kunden: Ticketliste des einen enthält nie Tickets des anderen; Ticket mit IsOnlyInternalVisible=true erscheint nicht im Portal. +Tracelinks: StRS-801, StRS-803 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Mandanten-/Kunden-Scoping ist sicherheitskritische Kernanforderung. +Status: belegt +``` + +### SyRS-816: Web-gestützte Bearbeitung von Tickets und Produktionsaufträgen + +``` +ID: SyRS-816 +Titel: Ticketabschluss und Werkschritt-Bearbeitung im Browser +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Servicemitarbeiter, Produktionsmitarbeiter +Vorbedingung: Mitarbeiter-Login; Ticket bzw. Produktionsauftrag existiert +Fakt: Das ServiceBoard bietet unter /serviceboard/ticket/{id}/close einen Abschlussdialog, der CloseHelpdeskWithNotification aufruft; die Produktionsübersicht lädt Werkschritte je Arbeitsplatz/Maschine und setzt deren Zustand auf Finished (SaveProductionOrderItem). +Aussage: Das System soll Mitarbeitern erlauben, Tickets mit Benachrichtigungsoptionen im Browser abzuschließen und Produktionswerkschritte am Arbeitsplatz als erledigt zu melden. +Ergebnis: Ticket wird in den Abschlusszustand überführt (mit Historie/Benachrichtigung); Werkschritt-Zustand wird persistiert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskCloseBL.cs - CloseHelpdesk: setzt "helpdeskRequest.Data.HelpdeskState = closedState; helpdeskRequest.Data.ClosedAt = DateTime.Now;", löscht ToDos, erzeugt Historie (HelpdeskHistoryType.Close) und AccountActivity - Begründung: Durchsetzende Abschlusslogik. + - [PRIMÄR] src\nexus\CentronNexus\ProductionOrderManagement\Components\WorkStepTemplateComponent.razor - FinishWorkstep: "this.WorkStep.ProductionOrderItem.State = ProductionOrderItemState.Finished;" mit anschließendem SaveProductionOrderItem (ProductionOrderOverView.razor) - Begründung: Zustandsübergang des Werkschritts. + - [SEKUNDÄR] src\nexus\CentronNexus\ServiceBoard\CloseTicket\Components\CloseTicket.razor - Aufruf CentronService.CloseHelpdeskWithNotification(new CloseHelpdeskWithNotificationRequest...) - Begründung: UI-Auslöser. +Prüfidee: Ticket über ServiceBoard schließen → HelpdeskState=geschlossen, ClosedAt gesetzt, Historieneintrag vorhanden; Werkschritt "Fertig" → ProductionOrderItemState.Finished persistiert. +Tracelinks: StRS-802 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zentrale Serviceprozesse. +Status: belegt +``` + +### SyRS-817: Authentifizierung und rechtebasierte Autorisierung der REST-API + +``` +ID: SyRS-817 +Titel: REST-API: JWT-Authentifizierung und Benutzerrechte mit 401/403-Semantik +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: REST-API-Client +Vorbedingung: Web-Service läuft; Endpunkt unter /v1/... bzw. /jwt, /2fa, /config +Fakt: Controller sind mit [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] bzw. [Authorize] geschützt; feingranulare Rechte werden je Aktion über [AuthorizeUserRight]/[AuthorizeAnyUserRight]/[AuthorizeAllUserRights] geprüft (401 ohne Benutzer, 403 ohne Recht); Hosted-only-Endpunkte verlangen die Policy "CentronHosted". +Aussage: Das System soll REST-Endpunkte nur für authentifizierte Aufrufer bereitstellen, Benutzerrechte deklarativ je Endpunkt prüfen und dabei zwischen fehlender Authentifizierung (401) und fehlender Berechtigung (403) unterscheiden. +Ergebnis: Unauthentifizierte Aufrufe erhalten 401, unautorisierte 403; nur berechtigte Aufrufe erreichen die Geschäftslogik. +Belege: + - [PRIMÄR] src\webservice\Centron.Controllers\Authorization\AuthorizeUserRightAttribute.cs - UserRightAuthorizationFilter.OnAuthorization: UnauthorizedResult bei currentUser==null, ForbidResult bei fehlendem HasUserRight - Begründung: Durchsetzende Prüfstelle inkl. Statuscode-Semantik. + - [PRIMÄR] src\webservice\Centron.Controllers\Controllers\v1\DataExchange\RmmConnectionSettingsController.cs Zeile 27/48 - [AuthorizeUserRight(UserRightsConst.Administration.SETTINGS)] - Begründung: Konkrete Verwendung mit Rechte-Konstante. + - [KONTEXT] src\webservice\Centron.Controllers\Authorization\README.md - Tabelle 200/401/403 - Begründung: Dokumentierte Semantik. +Prüfidee: GET auf rechtegeschützten Endpunkt ohne Token → 401; mit Token ohne Recht → 403; mit Recht → 200. +Tracelinks: StRS-803 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Standardkonformes AuthZ-Muster. +Status: belegt +``` + +### SyRS-818: Legacy-Webservice-Authentifizierung über Ticket oder Access-Token + +``` +ID: SyRS-818 +Titel: Legacy-API: Pflicht-Authentifizierung per Centron-Ticket oder Access-Token +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Legacy-API-Client (c-entron.NET, Agenten, Integrationen) +Vorbedingung: Aufruf einer mit [Authenticate] annotierten Methode der flachen CentronRestService-API +Fakt: Der AuthenticateInterceptor prüft vor Methodenausführung Request.Ticket (sonst Fehler-Response), validiert Ticket bzw. Access-Token über AuthenticationTicketBL.GetAuthTicketInfo (inkl. Client-IP aus X-Forwarded-For/X-Real-IP), verlängert bei Ticket die Gültigkeit (RefreshTicketExpireDate), blockiert nicht zugelassene Anwendungen (attribute.Applications) sowie Web-Account-Logins ohne AllowWebAccountLogin und liefert sonst Status InvalidTicket/Failed. +Aussage: Das System soll jeden Legacy-Webservice-Aufruf vor Ausführung gegen ein gültiges Sitzungs-Ticket oder Access-Token prüfen, die aufrufende Anwendung und den Login-Typ (Web-Account standardmäßig gesperrt) autorisieren und ungültige Aufrufe mit einem Fehlerstatus abweisen. +Ergebnis: Legacy-Methoden werden nie ohne gültige Authentifizierung ausgeführt; Web-Accounts erreichen nur explizit freigegebene Methoden. +Belege: + - [PRIMÄR] src\webservice\Centron.Host\AspNetCore\WcfBridge\Interception\Interceptors\AuthenticateInterceptor.cs - InterceptExecution: "bool webAccountIsBlocked = ticketValidationResult.Ticket.WebAccountI3D != null && attribute.AllowWebAccountLogin == false; if (applicationIsBlocked || webAccountIsBlocked) { invocation.ReturnValue = this.CreateErrorResponse(..., StatusCode.Failed); return; }" sowie "Invalid ticket or access token." - Begründung: Durchsetzende Stelle aller Prüfungen. + - [PRIMÄR] src\webservice\Centron.WebServices.Core\Interception\Interceptors\AuthenticateAttribute.cs - Properties Applications, AllowWebAccountLogin (Default false) - Begründung: Deklaration der Einschränkungen je Methode. + - [KONTEXT] docs\guides\services\add-webservice-methods.md - "[WebInvoke(Method = "POST"...)] [Authenticate]" als Pflichtattribute - Begründung: Dokumentiertes Muster für alle ~2.500 Legacy-Dateien. +Prüfidee: Legacy-Methode ohne Ticket aufrufen → Response.Status=InvalidTicket; mit Web-Account-Ticket auf Methode ohne AllowWebAccountLogin → Status Failed mit Permission-Meldung. +Tracelinks: StRS-803 +Konsolidierung: Kandidat: SyRS-817 (zwei parallele API-Autorisierungsmechanismen — Attribut-Filter der REST-API vs. Interceptor der Legacy-API — für dieselbe fachliche Funktion "API-Zugriffsschutz") +Übernahmewürdigkeit: veraltet - flache Legacy-API wird von der versionierten REST-API abgelöst; Ticket-/Access-Token-Konzept fachlich übernehmen. +Status: belegt +``` + +### SyRS-819: Einheitliche Fehlerbehandlung und API-Konventionen + +``` +ID: SyRS-819 +Titel: Globale Exception-Behandlung ohne Detail-Leak; versionierte Kebab-Case-Routen +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Zuverlässigkeit +Akteur: REST-API (Centron.Controllers), API-Client +Vorbedingung: Unbehandelte Exception in einer Controller-Aktion bzw. Routing eines Controllers +Fakt: Der global registrierte GlobalExceptionFilter loggt die Exception, versucht die DB-Verbindungspool-Wiederherstellung (DAOFactory.Instance.TryRecoverConnectionPool) und antwortet mit HTTP 500 und generischer JSON-Meldung; Routen werden per KebabCaseTransformer transformiert und per URL-Segment "v{version}" (Default v1, VersionByNamespaceConvention) versioniert. +Aussage: Das System soll unbehandelte API-Fehler zentral protokollieren, dem Client nur eine generische Fehlermeldung (HTTP 500) ohne interne Details liefern, nach Verbindungsfehlern den DB-Pool wiederherstellen und alle Endpunkte einheitlich versioniert im Kebab-Case adressieren. +Ergebnis: Stabile, informationsarme Fehlerantworten und konsistente, versionierte URL-Struktur. +Belege: + - [PRIMÄR] src\webservice\Centron.Controllers\Configuration\GlobalExceptionFilter.cs - OnException: logger.LogError, DAOFactory.Instance.TryRecoverConnectionPool(context.Exception), StatusCode=500, JsonResult "An unexpected error occurred while processing your request." - Begründung: Durchsetzende zentrale Fehlerbehandlung. + - [PRIMÄR] src\webservice\Centron.Host\AspNetCore\RegisterCentronServices.cs - AddCentronMvcOptions: options.Filters.Add() und RouteTokenTransformerConvention(new KebabCaseTransformer()) - Begründung: Globale Registrierung. + - [PRIMÄR] src\webservice\Centron.Controllers\Configuration\Routing\KebabCaseTransformer.cs - Regex.Replace(value, "([a-z])([A-Z])", "$1-$2").ToLower() - Begründung: Konkrete Transformationsregel. + - [SEKUNDÄR] src\webservice\Centron.Host\AspNetCore\RegisterCentronApiVersioning.cs - DefaultApiVersion = new ApiVersion(1), VersionByNamespaceConvention - Begründung: Versionierungskonvention. +Prüfidee: Exception in einer Aktion provozieren → Antwort 500 mit generischer Message, Stacktrace nur im Log; Controller "SupplierArticleCodes" ist unter /v1/supplier-article-codes erreichbar. +Tracelinks: StRS-803 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Security- und Konsistenz-Baseline jeder API. +Status: belegt +``` + +### SyRS-820: Betrieb des Web-Service in mehreren Hosting-Varianten + +``` +ID: SyRS-820 +Titel: Hosting-Varianten Windows-Dienst/Konsole/Linux mit zentraler WebServiceConfig +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Übertragbarkeit +Akteur: Systemadministrator, CentronHost +Vorbedingung: Konfigurierte WebServiceConfig.xml (DB-Verbindung, Adresse, ggf. Zertifikat) +Fakt: Centron.Host.WindowsService (ServiceBase.OnStart) und Centron.Host.Console (Program.Main, Kommandos "start", "hardware-id") starten denselben CentronHost.Instance; unter Linux werden HTTPS-Zertifikate über die Konfig-Knoten WebServiceCertificateFilePath/WebServiceCertificatePassword eingebunden; der ConnectionManager pflegt DB-Verbindung, Proxy, Active-Directory- und Secret-Key-Einstellungen. +Aussage: Das System soll den identischen Web-Service-Kern wahlweise als Windows-Dienst oder Konsolenprozess (auch Linux) starten und alle Betriebsparameter aus einer zentralen, werkzeuggestützt erzeugten Konfiguration beziehen. +Ergebnis: Gleicher Funktionsumfang unabhängig von der Hosting-Variante. +Belege: + - [PRIMÄR] src\webservice\Centron.Host.WindowsService\CentronService.cs - OnStart: CentronHost.Instance.Start(); bei Exception this.Stop() - Begründung: Dienst-Hülle mit Fehlerverhalten. + - [PRIMÄR] src\webservice\Centron.Host.Console\Program.cs - "if (args is [] or ["start"]) { CentronHost.Instance.Start(); ... }" - Begründung: Konsolen-Einstieg über denselben Host. + - [SEKUNDÄR] src\webservice\c-entron.misc.ConnectionManager\ConnectionManagerViewModel.cs - DoSaveConfigAsync / ConfigHelper.Config.DatabaseConnectionString - Begründung: Zentrale Konfigurationspflege. + - [KONTEXT] docs\guides\services\web-service-on-linux.md - Linux-Installation, WebServiceConfig.xml-Beispiel mit Zertifikat - Begründung: Dokumentierter Linux-Betrieb. +Prüfidee: Denselben Host einmal als Windows-Dienst und einmal per Konsole mit identischer Config starten; beide beantworten dieselben API-Anfragen. +Tracelinks: StRS-804 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - On-Premise-Varianten entfallen im SaaS-Zielbild; Konfigurationskonzept wird durch zentrale Provisionierung ersetzt. +Status: belegt +``` + +## Cluster A9 — Datenaustausch & Integrationen — SyRS + +### SyRS-911: Zugriffsschutz der RMM-REST-Schnittstelle per Zugriffsschlüssel + +``` +ID: SyRS-911 +Titel: Zugriffsschutz der RMM-REST-Schnittstelle per Zugriffsschlüssel +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Externes RMM-System (HTTP-Client), c-entron-Webservice +Vorbedingung: Die RMM-Schnittstelle ist in den Einstellungen aktiviert und ein Zugriffsschlüssel ist hinterlegt. +Fakt: Jeder Endpunkt des RmmController ruft IsAuthorized() auf; diese liest den Header "X-RMM-Access-Key" und validiert ihn über RiverDivoBL.ValidateRmmAccessKey; ohne gültigen Schlüssel wird 401 Unauthorized zurückgegeben. +Aussage: Das System soll jeden Aufruf der RMM-REST-Schnittstelle nur dann ausführen, wenn die Schnittstelle aktiviert ist und der im Header "X-RMM-Access-Key" übertragene Schlüssel dem konfigurierten Zugriffsschlüssel entspricht; andernfalls soll es den Aufruf mit HTTP 401 ablehnen. +Ergebnis: Unautorisierte Aufrufe erhalten 401 und lösen keine fachliche Verarbeitung aus. +Belege: + - [PRIMÄR] src\webservice\Centron.Controllers\Controllers\v1\Integrations\RmmController.cs - Methode IsAuthorized(): Request.Headers.TryGetValue("X-RMM-Access-Key") + riverDivoBL.ValidateRmmAccessKey; jeder Endpunkt beginnt mit "if (!IsAuthorized()) return Unauthorized();" - Begründung: durchsetzende Prüfung an jedem Endpunkt. + - [PRIMÄR] src\backend\Centron.BL\RiverDivo\RiverDivoBL.cs - Methode ValidateRmmAccessKey: "if (rmmSettings.IsEnabled is not true || string.IsNullOrWhiteSpace(rmmSettings.AccessKey)) return false;" - Begründung: Aktivierungs- und Schlüsselprüfung. +Prüfidee: Aufruf von POST v1/rmm/helpdesks/create ohne Header, mit falschem Schlüssel und bei deaktivierter Schnittstelle liefert jeweils 401; mit korrektem Schlüssel 200. +Tracelinks: StRS-901 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - statischer API-Key als Auth-Verfahren ist für eine SaaS-Neuimplementierung durch tokenbasierte Verfahren (OAuth2/Client-Credentials) zu ersetzen; die Anforderung "eigener technischer Zugang je Integration" bleibt. +Status: belegt +``` + +### SyRS-912: Konfiguration von Integrations-Zugangsdaten nur mit Administrationsrecht und verschlüsselter Ablage + +``` +ID: SyRS-912 +Titel: Konfiguration von Integrations-Zugangsdaten nur mit Administrationsrecht und verschlüsselter Ablage +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Administrator, c-entron-Webservice +Vorbedingung: Ein angemeldeter Benutzer will Zugangsdaten einer Integration (RMM-Access-Key, docuFORM Client-Id/Secret/Refresh-Token, DocBee-Konfiguration) lesen oder ändern. +Fakt: Die Endpunkte für RMM- und docuFORM-Einstellungen sind mit [AuthorizeUserRight(UserRightsConst.Administration.SETTINGS)] annotiert bzw. prüfen in der WebService-BL HasUserRight(...SETTINGS); Schlüssel werden vor dem Speichern per AESCryptoLogic verschlüsselt. +Aussage: Das System soll Lesen und Ändern von Integrations-Zugangsdaten nur Benutzern mit dem Recht Administration.SETTINGS erlauben und Geheimnisse (Schlüssel, Secrets, Tokens) ausschließlich verschlüsselt persistieren. +Ergebnis: Benutzer ohne das Recht erhalten eine Ablehnung; in der Datenbank stehen keine Klartext-Geheimnisse. +Belege: + - [PRIMÄR] src\webservice\Centron.Controllers\Controllers\v1\DataExchange\RmmConnectionSettingsController.cs - Attribute [AuthorizeUserRight(UserRightsConst.Administration.SETTINGS)] auf GetRmmConnectionSettings und UpdateRmmConnectionSettings - Begründung: durchsetzende Rechteprüfung am Endpunkt. + - [PRIMÄR] src\backend\Centron.BL\WebServices\Rmm\RmmConnectionSettingsWebServiceBL.cs - "this._appRightsBL.HasUserRight(loggedInUser.User.I3D, UserRightsConst.Administration.SETTINGS) == false" → Fehler-Result - Begründung: zweite, serverseitige Durchsetzung in der BL. + - [PRIMÄR] src\backend\Centron.BL\DataExchange\Rmm\RmmConnectionSettingsBL.cs - UpdateRmmConnectionSettings: "accessKey = new AESCryptoLogic().EncryptText(accessKey)" - Begründung: verschlüsselte Ablage. + - [KONTEXT] CentronRights.md (Repo-Wurzel) - Rechtekatalog Administration/Einstellungen - Begründung: dokumentiertes Benutzerrecht. +Prüfidee: GET/PUT v1/rmm/connection-settings mit einem Benutzer ohne SETTINGS-Recht liefert 403/Fehler; der in der DB gespeicherte Access-Key ist nicht im Klartext lesbar. +Tracelinks: StRS-901, StRS-903 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Rechtebindung und Secret-Verschlüsselung sind auch im Zielsystem erforderlich (dort z. B. via Secret-Store). +Status: belegt +``` + +### SyRS-913: Verknüpfung von c-entron-Objekten mit externen Systemen über Objekt-Fremdreferenzen + +``` +ID: SyRS-913 +Titel: Verknüpfung von c-entron-Objekten mit externen Systemen über Objekt-Fremdreferenzen +Ebene: SyRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Integrationslogik (DocBee-Konnektor, Riverbird-Sync, ES-Abgleich), c-entron-Datenhaltung +Vorbedingung: Ein Objekt (Ticket, Zeitbuchung, Auftragsposition, Kunde) existiert sowohl in c-entron als auch im Fremdsystem. +Fakt: Die Entität ObjectExternalReference speichert ObjectI3D, ObjectKind, ExternalReferenceType (z. B. "DocBee"), ExternalReferenceID, RelationType und Timestamp; DocBee-Lookups suchen Tickets und Timer über diese Referenzen; Kunden tragen zusätzlich die Spalte Kunden.RiverbirdCustomerReference. +Aussage: Das System soll die Zuordnung zwischen c-entron-Objekten und ihren Gegenstücken in Fremdsystemen als persistierte Fremdreferenz (Objekttyp, externe ID, Referenztyp) führen, damit wiederholte Synchronisationen dasselbe Objekt wiederfinden statt Duplikate zu erzeugen. +Ergebnis: Wiederholte Sync-Vorgänge sind idempotent; jede externe ID ist eindeutig einem c-entron-Objekt zugeordnet. +Belege: + - [PRIMÄR] src\backend\Centron.Entities\Entities\ObjectExternalReferences\ObjectExternalReference.cs - Properties ObjectI3D, ObjectKind, ExternalReferenceType, ExternalReferenceID, RelationType - Begründung: Datenmodell der Fremdreferenz. + - [PRIMÄR] src\backend\Centron.BL\DataExchange\Connectors\DocBeeTicketTimerBL.cs - Methoden GetHelpdeskTimerByExternalId und FindTicketByDocBeeReference (Query auf ObjectExternalReference mit ExternalReferenceType == ObjectExternalReferenceTypes.DocBee) - Begründung: durchgesetzte Wiederfindungslogik. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql - Spalte [RiverbirdCustomerReference] [int] NULL in Tabelle Kunden - Begründung: persistiertes Kundenmapping zum RMM. +Prüfidee: Zweimaliges Senden derselben DocBee-Zeitbuchung (gleiche ExternalId) erzeugt genau einen Timer; die zweite Übertragung aktualisiert ihn. +Tracelinks: StRS-901, StRS-904 +Konsolidierung: Kandidat: generische ObjectExternalReference vs. Spezialspalten Kunden.RiverbirdCustomerReference und EsCustomerGroup.ExternalId — drei Datenhaltungen für dasselbe Konzept "externe Objektreferenz". +Übernahmewürdigkeit: übernehmen - generischer Referenzmechanismus ist die richtige Zielarchitektur; Spezialspalten dorthin konsolidieren. +Status: belegt +``` + +### SyRS-914: docuFORM-Anbindung über OAuth2 für den Abruf von Gerätezählern + +``` +ID: SyRS-914 +Titel: docuFORM-Anbindung über OAuth2 für den Abruf von Gerätezählern +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: c-entron-Client, docuFORM-Server (Fleet-Management für Druckgeräte) +Vorbedingung: docuFORM-Serveradresse, Client-Id und Client-Secret sind konfiguriert. +Fakt: Der API-Client nutzt die Endpunkte /auth/v2/token und /auth/v2/authorize (Grant "refresh_token" bzw. Authorization-Code über Dialog) und ruft /dfmserver/v2/devices sowie Gerätezähler ab; neue Refresh-Tokens werden nach Erhalt gespeichert. +Aussage: Das System soll sich gegenüber dem docuFORM-Server per OAuth2 authentifizieren (bevorzugt mit gespeichertem Refresh-Token, ersatzweise per interaktivem Authorization-Code) und darüber Geräte und deren Zählerstände abrufen. +Ergebnis: Gültiges Access-Token ohne wiederholte manuelle Anmeldung; Gerätezähler stehen dem Import zur Verfügung. +Belege: + - [PRIMÄR] Centron.Api.docuFORM\DocuFormRestApiConstants.cs - Konstanten _endpointAuthToken="/auth/v2/token", _endpointAuthCode="/auth/v2/authorize", _endpointDevices="/dfmserver/v2/devices" - Begründung: Schnittstellenvertrag. + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\DataExchange\DocuForm\Authorization\DocuFormTokenHelper.cs - RequestAuthTokenByRefreshToken (GrantType="refresh_token") und RequestAuthTokenByAuthCodeDialog; SaveRefreshToken persistiert den neuen Refresh-Token - Begründung: implementierter Tokenfluss. +Prüfidee: Bei ungültigem Refresh-Token öffnet der Import den Auth-Code-Dialog; nach erfolgreicher Anmeldung wird der neue Refresh-Token gespeichert und der nächste Import läuft ohne Dialog. +Tracelinks: StRS-903 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Standard-OAuth2-Anbindung, direkt in eine Server-zu-Server-Variante überführbar. +Status: belegt +``` + +### SyRS-915: Angebotsexport an den Telekom-Marktplatz D!VE als profilgesteuertes XML + +``` +ID: SyRS-915 +Titel: Angebotsexport an den Telekom-Marktplatz D!VE als profilgesteuertes XML +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Vertriebsmitarbeiter, Telekom-D!VE-Portal (Dateiübergabe per XML) +Vorbedingung: Ein Angebot (ReceiptOffer) ist geöffnet; mindestens ein Telekom-D!VE-Profil ist angelegt. +Fakt: Der Exportdialog akzeptiert ausschließlich Angebote ("Export nur mit Angeboten möglich!"), lädt Profile (TelekomDiveProfileDTO) über den Webservice, verlangt je Position Kategorie und Einheit und erzeugt per ExportToXml ein XML mit Partner-, Kunden- und Positionsdaten; die Datei wird gespeichert und archiviert. +Aussage: Das System soll Angebote anhand konfigurierbarer D!VE-Profile in das von der Telekom vorgegebene XML-Format exportieren und die exportierte Datei am Angebot archivieren. +Ergebnis: Eine D!VE-konforme XML-Datei ist erzeugt, lokal gespeichert und als Dokument am Angebot abgelegt. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\TelekomDive\TelekomDiveExportViewModel.cs - Konstruktor wirft ArgumentException("Export nur mit Angeboten möglich!"); Methoden ExportAndSaveXml, ExportToXml, ArchiveExportedTelekomDiveFile - Begründung: durchgesetzter Exportablauf. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\TelekomDive\TelekomDiveExportViewModel.cs - Fehlermeldung "Es wurde leider kein Telekom-D!VE-Profil für den Export gefunden! ... Datenaustausch > Telekom-D!VE" - Begründung: Profilpflicht. +Prüfidee: Export eines Angebots ohne zugeordnete Kategorie/Einheit wird mit Hinweis abgebrochen; mit vollständigen Daten entsteht ein XML mit den Pflichtelementen (offer_recipient, partner_name, customer_name, Positionsliste). +Tracelinks: StRS-902 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - solange das Telekom-Partnerformat gefordert ist; Formatdetails vor Neuimplementierung gegen aktuelle D!VE-Spezifikation prüfen. +Status: belegt +``` + +### SyRS-916: Gateway als Adapter-Sammlung für EDI-, FiBu- und Zahlungsformate + +``` +ID: SyRS-916 +Titel: Gateway als Adapter-Sammlung für EDI-, FiBu- und Zahlungsformate +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: c-entron-Backend, Partnersysteme (Distributoren, FiBu-Software, Banken) +Vorbedingung: Ein Export-/Importlauf für ein konkretes Partnerformat wird angestoßen. +Fakt: Centron.Gateway kapselt je Format eigene Klassen: EDI_Also/EDI_Alltron/EDI_AlsoCH/EDI_EGIS/EDI_Herweck/EDI_Komsa (Order/OrderResponse/Delivery/Invoice), DataExchange\BookKeeping mit Adaptern u. a. für DATEV (ASCII, XML-Online 2020), Abacus, Addison, Sage, SAP, Navision, Lexware, GDI, Europa3000, Schilling sowie benutzerdefinierte Schnittstellen; dazu SEPA pain.008 (SepaFileGeneratorV2), OpenTrans 1.0/2.1, ZUGFeRD 2.1 Extended und FinTS-Onlinebanking (libfintx). +Aussage: Das System soll partnerspezifische Datenformate in austauschbaren Adaptern kapseln, sodass neue Distributoren-, Buchhaltungs- und Zahlungsformate ergänzt werden können, ohne die Fachlogik zu ändern. +Ergebnis: Je Partnerformat existiert genau ein Adapter; der Aufrufer wählt den Adapter über den Exporttyp. +Belege: + - [PRIMÄR] src\backend\Centron.Gateway\DataExchange\BookKeeping\IBookKeepingExport.cs und BookKeepingFileExport.cs - abstrakte Basisklasse mit "public abstract BookKeepingExportTypes ExportTyp" und virtuellen Get*Data-Methoden - Begründung: Adapter-Abstraktion im Code durchgesetzt. + - [SEKUNDÄR] Verzeichnisstruktur src\backend\Centron.Gateway\EDI_* , OpenTrans*, ZUGFeRD21_Extended, DataExchange\PaymentTransactions\Sepa - Begründung: Adapterinventar pro Partnerformat. +Prüfidee: Für zwei verschiedene FiBu-Exporttypen liefert derselbe Aufrufpfad über die IBookKeepingExport-Implementierungen unterschiedliche, formatkonforme Dateien. +Tracelinks: StRS-902 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Adapterprinzip übernehmen; einzelne Alt-Adapter (z. B. Europa3000, Schilling AS400) je Kundenbestand als Sonderfall bewerten. +Status: belegt +``` + +### SyRS-917: Generischer Stammdatenimport und Dokumentbereitstellung (DocSync) + +``` +ID: SyRS-917 +Titel: Generischer Stammdatenimport und Dokumentbereitstellung (DocSync) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Anwender (Import-Assistent), DocSync-Client (externe Dokumentsynchronisation) +Vorbedingung: Importdatei liegt vor bzw. DocSync ist für Objektarten aktiviert. +Fakt: Der Kontenimport läuft als Assistent (Wizard-Steps Datenquelle → Daten → Fortschritt) über CentronImportManager.ImportAsync mit ViewModel-Validierungen; DirectoryBL liefert per Named Query GetDocSyncActiveDirectoriesAndOwners/GetDocSyncActiveDocuments die aktiv synchronisierten Verzeichnisse und Dokumente, gefiltert über die eingestellten Objektarten. +Aussage: Das System soll Stammdatenimporte assistentengeführt mit Vorab-Validierung ausführen und für die Dokumentsynchronisation die Menge der bereitzustellenden Verzeichnisse/Dokumente anhand der konfigurierten Objektarten bestimmen. +Ergebnis: Nur validierte Datensätze werden importiert; DocSync erhält genau die Dokumente aktivierter Objektarten. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\DataExchange\DataImport\AccountImport\CentronImportManager.cs - Methode ImportAsync(importFileName, importFileBytes, settings, accountViewModels) - Begründung: Importausführung. + - [PRIMÄR] src\backend\Centron.BL\Administration\FileManagement\DirectoryBL.cs - GetDocSyncActiveDirectoriesAndOwners/GetDocSyncActiveDocuments (NamedQueryEnums.CentronSystem.*) und IsDocSyncEnabledForObjectKind - Begründung: Bereitstellungslogik. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\DataExchange\DataImport\AccountImport\WizardSteps\DataImportDataSourceView.xaml u. a. - Begründung: Assistentenführung. +Prüfidee: Nach Deaktivieren einer Objektart in den DocSync-Einstellungen liefert GetDocSyncActiveDirectoriesAndOwners keine Verzeichnisse dieser Objektart mehr. +Tracelinks: StRS-904 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Assistentenimport und selektive Dokumentbereitstellung sind übertragbare Kernfunktionen. +Status: belegt +``` + +### SyRS-918: Kundenisolation beim Datenabruf über Web-Zugänge + +``` +ID: SyRS-918 +Titel: Kundenisolation beim Datenabruf über Web-Zugänge +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: WebAccount (Kundenportal-Login), c-entron-Webservice, Riverbird-RMM +Vorbedingung: Ein als WebAccount angemeldeter Benutzer fragt RMM-Daten (z. B. Active-Directory-Benutzer) eines Kunden ab. +Fakt: RiverConnectionBL.GetActiveDirectoryUsers und GetActiveDirectoryOrganizationalUnits prüfen "loggedInUser.IsWebAccountLogin && loggedInUser.WebAccount.CustomerI3D != customerNumber" und liefern dann bewusst ein leeres Erfolgs-Result mit Error-Log ("Possible security incident"). +Aussage: Das System soll bei Abfragen über Kunden-Web-Zugänge sicherstellen, dass ein WebAccount nur Daten des ihm zugeordneten Kunden erhält; fremde Kundennummern sollen ohne Informationspreisgabe (leeres Ergebnis statt Fehlermeldung) beantwortet werden. +Ergebnis: Kein Zugriff auf Daten fremder Kunden; Sicherheitsverstöße werden protokolliert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\RiverDivo\RiverConnectionBL.cs - Methoden GetActiveDirectoryUsers/GetActiveDirectoryOrganizationalUnits: "if (loggedInUser.IsWebAccountLogin && loggedInUser.WebAccount.CustomerI3D != customerNumber) { Logger.Error(...); return ... leere Liste }" - Begründung: durchsetzende Isolationsprüfung mit konkreter Bedingung. +Prüfidee: Abfrage mit einem WebAccount und fremder Kundennummer liefert eine leere Liste und einen Security-Logeintrag; mit eigener Kundennummer die AD-Benutzer. +Tracelinks: StRS-901 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Mandanten-/Kundenisolation ist im Mehrmandanten-SaaS zwingend und dort zentral (Policy-Ebene) statt punktuell umzusetzen. +Status: belegt +``` + +## A10 — SyRS (Produktion, Projekte, PLM, QM, Statistik, Reporting) + +### SyRS-1010: Lizenzgate für alle Produktionsfunktionen + +``` +ID: SyRS-1010 +Titel: Lizenzgate für alle Produktionsfunktionen +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: System (Lizenzprüfung), beliebiger Client des Produktionsmoduls +Vorbedingung: Aufruf einer Lese- oder Schreiboperation des Produktionsmoduls +Fakt: Jede öffentliche Methode in ProductionBL und ProductionOrderBL (Maschinen, Maschinenarten, Standorte, Aufträge, Auftragspositionen, Logs) prüft LicenseManager.Instance.HasLicense(LicenseGuids.ProductionManagement) und wirft andernfalls eine Exception mit lokalisiertem Text. +Aussage: Das System soll jede Produktionsfunktion (lesend und schreibend) nur ausführen, wenn die Lizenz "Produktionsmanagement" vorhanden ist, und andernfalls den Aufruf mit einer verständlichen Fehlermeldung abbrechen. +Ergebnis: Ohne Lizenz keine Produktionsdatenzugriffe; Fehlermeldung "Sie besitzen nicht die Lizenz für das Produktionsmanagement". +Belege: + - [PRIMÄR] src\backend\Centron.BL\Production\ProductionBL.cs, z. B. GetProductionMachinesByFilter: `if(LicenseManager.Instance.HasLicense(LicenseGuids.ProductionManagement) == false) throw new Exception(LocalizedStrings.ProductionBL_Sie_besitzen_nicht_die_Lizenz_für_das_Produktionsmanagement)` - Begründung: durchsetzende Prüfung in jeder Methode. + - [PRIMÄR] src\backend\Centron.BL\Production\ProductionOrderBL.cs, SaveProductionOrder / GetProductionOrderItemsByFilter, identische Prüfung - Begründung: Gate gilt auch für Auftragsdaten. +Prüfidee: Testumgebung ohne Produktionslizenz: GetProductionMachinesByFilter wirft Exception; mit Lizenz liefert es die Maschinenliste. +Tracelinks: StRS-1001; SwRS-1030, SwRS-1031 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Feature-Gating pro Mandant/Abo ist im SaaS-Zielbild gleichwertig nötig; Umsetzung als Exception sollte durch Result-Fehler ersetzt werden. +Status: belegt +``` + +### SyRS-1011: Produktionsauftragsverwaltung mit Statusverfolgung und Änderungsprotokoll + +``` +ID: SyRS-1011 +Titel: Produktionsauftragsverwaltung mit Statusverfolgung und Änderungsprotokoll +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Produktionsmodul (WPF-UI), Produktionsmitarbeiter +Vorbedingung: Lizenz vorhanden; Verkaufsauftrag existiert +Fakt: ProductionOrder referenziert OrderI3D/OrderItemI3D/OrderNumber (NOT NULL) und PlannedFinishDate; ProductionOrderItem trägt State, Maschine/Maschinenart, RequiredAmount/ProducedAmount, WorkingEmployeeI3D und Maße; ProductionOrderLog speichert Kind, Message, CreatedByI3D, CreatedDate, CreatedVersion; Filter erlauben Suche nach Auftrag, Maschine, Maschinenart, Status, Mitarbeiter. +Aussage: Das System soll Produktionsaufträge stets einem Verkaufsauftrag zuordnen, deren Arbeitsschritte mit Soll-/Ist-Mengen, Maschinen- und Mitarbeiterzuordnung sowie Status führen und jede fachliche Änderung als typisierten Logeintrag mit Verursacher und Zeitstempel festhalten. +Ergebnis: Filterbare Produktionsaufträge; vollständige Änderungshistorie je Auftrag/Arbeitsschritt. +Belege: + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE ProductionOrders ([OrderI3D] int NOT NULL, [OrderNumber] int NOT NULL) und ProductionOrderLogs ([Kind] int NOT NULL, [Message] nvarchar(4000) NOT NULL, [CreatedByI3D] int NOT NULL) - Begründung: DB-Constraints erzwingen Auftragsbezug und Protokollpflichtfelder. + - [SEKUNDÄR] src\backend\Centron.BL\Production\ProductionOrderBL.cs, CreateFilterExpression (Filter State, MachineI3D, WorkingEmployeeI3D) - Begründung: Verhalten der Suche/Verfolgung. +Prüfidee: Anlage eines Produktionsauftrags ohne OrderI3D schlägt fehl; Statuswechsel eines Arbeitsschritts erzeugt einen Logeintrag der Art ProductionOrderItemStateChanged. +Tracelinks: StRS-1001; SwRS-1030, SwRS-1031 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kernablauf; Logschema (Kind-Enum) als Vorlage für Neuimplementierung geeignet. +Status: belegt +``` + +### SyRS-1012: Rechtebasierter Zugriff auf Statistiken, Kennzahlen und Übersichten + +``` +ID: SyRS-1012 +Titel: Rechtebasierter Zugriff auf Statistiken, Kennzahlen und Übersichten +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Statistik-/Management-Info-Module, REST-API-Clients, Web-Accounts +Vorbedingung: Angemeldeter Benutzer ruft eine Auswertung ab +Fakt: SaleStatisticBL verlangt SALES_STATISTIC (20800005) oder eingeschränkt SHOW_CRM_ARTICLES; SHOW_ONLY_STATISTIC_FROM_OWN_BRANCH (20800145) erzwingt Filialfilter; Web-Accounts sehen nur den eigenen Kunden; CacheSalesStatisticsBL verlangt MANAGEMENT_INFO (10972) und verbietet Web-Accounts; ManagementInfoBL wendet MANAGEMENT_INFO_ONLY_OWN_BRANCH (20800039) auf alle Kennzahlen an; die REST-Route v1/nexoware/statistics/revenue ist mit [AuthorizeUserRight(SALES_STATISTIC)] annotiert. +Aussage: Das System soll jeden Zugriff auf Statistiken und Management-Kennzahlen — über UI wie über die REST-Schnittstelle — gegen Benutzerrechte prüfen, Benutzer mit Filialbeschränkung automatisch auf die eigene Filiale einschränken und externen Web-Accounts ausschließlich Daten des eigenen Kundenkontos liefern. +Ergebnis: RightCheckFailed für Unberechtigte; automatisch gefilterte Ergebnisse für filial- bzw. kundenbeschränkte Benutzer. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Statistics\SaleStatistics\SaleStatisticBL.cs, GetSalesArticleStatistic: Rechteprüfung SALES_STATISTIC, Zwangsfilter `filter.BranchI3Ds = ...BranchI3D` bei SHOW_ONLY_STATISTIC_FROM_OWN_BRANCH, Web-Account-Prüfung `filter.CustomerI3Ds.First() != loggedInUser.WebAccount.CustomerI3D` - Begründung: durchsetzende Stelle aller drei Beschränkungen. + - [PRIMÄR] src\backend\Centron.BL\Statistics\SaleStatistics\CacheSalesStatisticsBL.cs, GetAll: `if (!loggedInUser.User.HasUserRight(UserRightsConst.Controlling.Finances.MANAGEMENT_INFO)) return AsError(...)` - Begründung: Rechtedurchsetzung für Kennzahlen-Cache. + - [SEKUNDÄR] src\webservice\Centron.Controllers\Controllers\v1\Nexoware\Statistics\NexowareStatisticsController.cs, `[AuthorizeUserRight(UserRightsConst.Controlling.Analytics.SALES_STATISTIC)]` - Begründung: gleiche Regel an der API-Grenze. +Prüfidee: Benutzer mit SHOW_ONLY_STATISTIC_FROM_OWN_BRANCH fordert Statistik über alle Filialen an und erhält nur Daten seiner Filiale; Web-Account fordert fremde CustomerI3D an und erhält leere Liste. +Tracelinks: StRS-1002; SwRS-1037, SwRS-1038, SwRS-1032, SwRS-1046 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Rechtemodell ist tragfähig; Modul-Controller liefern GetRights() teils null, daher muss die BL-Prüfung (wie hier) die maßgebliche bleiben. +Status: belegt +``` + +### SyRS-1013: Zentrale Reportverwaltung, -generierung und -archivierung + +``` +ID: SyRS-1013 +Titel: Zentrale Reportverwaltung, -generierung und -archivierung +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Report-Designer (Administrator), alle druckenden Module +Vorbedingung: Reportvorlage (FastReport) in ReportData gespeichert und einer ReportGroup zugeordnet +Fakt: ReportDataBL speichert Berichte als FastReport-XML im image-Feld ReportData.Report, verwaltet Gruppenzuordnung, Aktiv-/Inaktiv-Status (SetReportAsActivated/SetReportDeactivated), Namenseindeutigkeit (IsReportNameUnique), registriert Datenquellen/Parameter (Register), rendert Druck/Vorschau (GetReportForPrinting) und erzeugt/archiviert PDFs (ConvertReportToPdfStream, ArchivePdf, ExportPdfToFile); ReportGroupBL mappt Belegarten-GUIDs (RECHNUNG, LIEFERSCHEIN, ...) auf Asset-Arten. +Aussage: Das System soll Berichtsvorlagen zentral versionier- und gruppierbar verwalten, sie je Belegart über GUID-Gruppen den Modulen zuordnen, Berichte mit Parametern rendern und als PDF exportieren bzw. archivieren können. +Ergebnis: Module drucken über Gruppen-GUID den passenden aktiven Bericht; PDF-Export/Archiv verfügbar. +Belege: + - [PRIMÄR] src\backend\Centron.BL\ReportEngine\ReportDataBL.cs, GetReportFromData: `Report.FromString(ASCIIEncoding.UTF8.GetString(reportData.ReportArray))`; GetReportForPrinting; ArchivePdf - Begründung: durchgesetzte Speicher- und Renderlogik. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE ReportData ([Name] varchar(256) NOT NULL, [Report] image NOT NULL, [State] int) - Begründung: Datenhaltung der Vorlagen. + - [SEKUNDÄR] src\backend\Centron.BL\ReportEngine\ReportGroupBL.cs, Dictionary ReportGroupConstants.RECHNUNG/LIEFERSCHEIN/... auf AssetKindEnum - Begründung: Belegart-Zuordnung über GUIDs. +Prüfidee: Bericht in Gruppe "Rechnung" aktivieren; Rechnungsdruck verwendet genau diesen Bericht; Deaktivieren entfernt ihn aus der Auswahl; PDF-Export erzeugt archivierte Datei. +Tracelinks: StRS-1002; SwRS-1041, SwRS-1042, SwRS-1043 +Konsolidierung: Kandidat: Alt-Tabelle dbo.Reports (Centron.BL\Reporting\ReportsBL.cs) hält Berichte parallel zur ReportEngine (siehe SwRS-1042). +Übernahmewürdigkeit: übernehmen - zentrale Reportverwaltung ist Kernanforderung; FastReport-Bindung bei Web-Neuimplementierung durch serverseitige Rendering-Engine ersetzen. +Status: belegt +``` + +### SyRS-1014: Ad-hoc-SQL-Ausführung nur mit Administrationsrecht + +``` +ID: SyRS-1014 +Titel: Ad-hoc-SQL-Ausführung nur mit Administrationsrecht +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Report-/SQL-Designer, Webservice-Clients +Vorbedingung: Client sendet ein SQL-Statement zur Ausführung an den Webservice +Fakt: ReportDataWebBL.ReportEngineExecuteQuery prüft, ob der Benutzer das Recht SQL_MANAGER (20400205) oder REPORT_MANAGEMENT (10550) besitzt, bevor das Statement über ReportDataBL.ExecuteQuery/NativeSqlDAO ausgeführt wird. +Aussage: Das System soll frei formulierte SQL-Abfragen (Report-Datenquellen, Ad-hoc-Auswertungen) nur für Benutzer mit den Rechten SQL-Manager oder Report-Management ausführen und alle anderen Aufrufe mit einer Rechtefehlermeldung ablehnen. +Ergebnis: Unberechtigte erhalten "Sie haben nicht die benötigten Rechte." (RightCheckFailed); Berechtigte erhalten das Abfrageergebnis als Tabelle. +Belege: + - [PRIMÄR] src\backend\Centron.BL\WebServices\ReportEngine\ReportDataWebBL.cs, ReportEngineExecuteQuery: `if (this._appRightsBL.GetRightsFromCurrentUser(currentUser).Any(f => f.I3D == UserRightsConst.Administration.SQL_MANAGER || f.I3D == UserRightsConst.Administration.REPORT_MANAGEMENT) == false) return Result.AsError("Sie haben nicht die benötigten Rechte.", DefaultMessageCodes.RightCheckFailed)` - Begründung: durchsetzende Rechteprüfung vor SQL-Ausführung. + - [SEKUNDÄR] src\webservice\Centron.WebServices.Core\EntitiesWrongPlace\Administration\Rights\UserRightsConst.cs, REPORT_MANAGEMENT = 10550, SQL_MANAGER = 20400205 - Begründung: Konstantendefinition der geprüften Rechte. +Prüfidee: Aufruf ReportEngineExecuteQuery ohne beide Rechte liefert RightCheckFailed; mit SQL_MANAGER liefert er das Resultset. +Tracelinks: StRS-1002; SwRS-1041 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - das Recht schützt, aber freie SQL-Ausführung über die API sollte im SaaS-Zielbild durch parametrisierte, mandantengefilterte Abfragedienste ersetzt werden. +Status: belegt +``` + +### SyRS-1015: Massenänderungen über Vorlagen und Importe mit Ausführungsnachweis + +``` +ID: SyRS-1015 +Titel: Massenänderungen über Vorlagen und Importe mit Ausführungsnachweis +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Massenupdate-Modul, Projektpreisimport-Modul +Vorbedingung: Massenupdate-Vorlage mit Objektliste angelegt bzw. Excel-Preisliste geladen +Fakt: MassUpdateTemplate speichert CreatedBy/ChangedBy/ExecutedBy und IsExecuted; jedes MassUpdateTemplateItem trägt ObjectKind/ObjectI3D, neue Werte, IsExecuted, ExecutedAt, ExecutedByI3D und FailureMessage; erst wenn alle Items ausgeführt sind, wird die Vorlage inaktiv und als ausgeführt markiert; der Projektpreisimport ordnet Excel-Zeilen über Herstellercode Artikeln zu und sammelt nicht zuordenbare Zeilen in einer Fehlerliste. +Aussage: Das System soll Massenänderungen als benannte Vorlagen mit Objektliste führen, jede Einzelausführung mit Ausführer, Zeitpunkt und ggf. Fehlergrund festhalten, teilausgeführte Läufe wiederaufsetzbar halten und Importe mit Zeilenfehlerliste quittieren. +Ergebnis: Wiederholbarer Lauf, der nur offene Items verarbeitet; vollständige Nachvollziehbarkeit wer wann was geändert hat. +Belege: + - [PRIMÄR] src\backend\Centron.BL\MassUpdate\MassUpdateBL.cs, StartArticlePriceUpdate: Schleife über `MassUpdateTemplateItems.Where(f => f.IsExecuted.GetValueOrDefault() is false)`, danach `if (...All(f => f.IsExecuted == true)) { massUpdateTemplate.IsActive = false; massUpdateTemplate.IsExecuted = true; }` - Begründung: durchgesetzter Vorlagen-Lebenszyklus mit Wiederaufsetzbarkeit. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE MassUpdateTemplateItems ([IsExecuted] bit, [ExecutedAt] datetime2, [ExecutedByI3D] int, [FailureMessage] nvarchar(250)) - Begründung: Datenmodell des Ausführungsnachweises. +Prüfidee: Lauf mit einem fehlschlagenden Item: erneuter Start verarbeitet nur das offene Item; Vorlage wird erst nach dessen Erfolg inaktiv. +Tracelinks: StRS-1003; SwRS-1044, SwRS-1045, SwRS-1033 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Muster (Vorlage + Items + Ausführungsstatus) direkt in Web-Architektur übertragbar (Job-Queue). +Status: belegt +``` + +### SyRS-1016: Pflichtbegründungen und QM-Benachrichtigung bei Belegrückgaben + +``` +ID: SyRS-1016 +Titel: Pflichtbegründungen und QM-Benachrichtigung bei Belegrückgaben +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Belegerfassung (Lieferschein, Gutschrift, Abholschein, Lieferantenbelege), QM-Beauftragter +Vorbedingung: Für die Belegart sind QM-Gründe (AssetReason) und ein Benachrichtigungsmodus konfiguriert +Fakt: ReceiptBL.CheckIfAssetReasonIsNeeded liest je Belegart eine AppSetting (QmMessageConfirmationPopup*): 0=nie, 1=Nachfrage, 2=immer; ist der gewählte AssetReason als IsMandatory markiert und kein Begründungstext erfasst, wird der Speichervorgang mit Dialoganforderung "Bitte geben Sie eine Begründung an." unterbrochen; CustomerAssetBL.HandleIfAssetReasonNeeded lehnt Speichern mit Result.AsError ab. +Aussage: Das System soll je Belegart konfigurierbar (nie/Nachfrage/immer) beim Speichern von Rückgabe-/Reklamationsbelegen eine Begründung anfordern und bei als Pflicht markierten Gründen das Speichern ohne Begründungstext verhindern. +Ergebnis: Belege mit Pflichtgrund können nicht ohne Begründungstext gespeichert werden; QM erhält auswertbare Gründe. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs, CheckIfAssetReasonIsNeeded: `bool reasonDemandsAMessage = reason != null && reason.IsMandatory && string.IsNullOrWhiteSpace(reasonText); if ((showAlways || reasonDemandsAMessage) ...) result.Set(f => f.ShowAssetReasonDialog, true, "Bitte geben Sie eine Begründung an.")` - Begründung: durchsetzende Prüfung beim Belegspeichern. + - [PRIMÄR] src\backend\Centron.BL\Sales\CustomerAssets\CustomerAssetBL.cs, HandleIfAssetReasonNeeded: `if (assetReason.IsMandatory && string.IsNullOrWhiteSpace(asset.AssetReasonText)) return Result.AsError(assetReason.ReasonText)` - Begründung: harte Ablehnung ohne Pflichtbegründung. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\QM\Settings\QmSettingsViewModel.cs, je Belegart eigenes AssetReasonSettingsViewModel (SupplierOrder, CreditVoucher, DeliveryList, PickupList, ...) - Begründung: Konfigurierbarkeit je Belegart. +Prüfidee: Belegart mit Modus "immer" und Pflichtgrund: Speichern ohne Text löst Dialog aus bzw. wird abgelehnt; Modus "nie" speichert ohne Nachfrage. +Tracelinks: StRS-1003; SwRS-1036 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - einfache, wirksame Qualitätsregel; 1:1 übertragbar. +Status: belegt +``` + +### SyRS-1017: MSP-Nutzungsimport und Vertragsabgleich (Abrechnung) + +``` +ID: SyRS-1017 +Titel: MSP-Nutzungsimport und Vertragsabgleich (Abrechnung) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: MSP-Collector (FTP/HTTP-Import), Vertragsabrechnung, Lizenzmanager +Vorbedingung: MSP-Collector mit Lieferantenschema und ggf. verschlüsselten Zugangsdaten konfiguriert; MSP-Modul-Lizenz vorhanden +Fakt: MspDowloadStart lädt Abrechnungsdaten je Lieferantenschema (Veeam, Octopus, ArrowSphere; FTP/FTPS/HTTP), entschlüsselt Passwörter per AESCryptoLogic, verhindert Doppelimporte desselben Abrechnungsmonats (Warnung "Report wurde schon importiert...") und schreibt Import-Logs; die Auswertung (GetMspCollectorInvoiceHeads) ist über LicenseGuids.MspModule gesperrt; UpdateMspContractItem übernimmt Menge/Preis in die Vertragsposition, entkoppelt Positionen vom Ursprungsauftrag (DetachContractItemsFromOrigin, Ticket 168245) und historisiert jede Entscheidung. +Aussage: Das System soll Nutzungs-/Abrechnungsdaten von MSP-Lieferanten über konfigurierbare Sammel-Schnittstellen importieren, Doppelimporte je Abrechnungsperiode verhindern und dem Sachbearbeiter je Rechnungsposition die Entscheidung ermöglichen, Vertragsmenge und/oder -einkaufspreis zu übernehmen oder den Import zu ignorieren — mit vollständiger Entscheidungs-Historie. +Ergebnis: Verträge entsprechen dem tatsächlichen Lieferantenverbrauch; jede Anpassung ist mit Mitarbeiter, Alt-/Neumengen und Entscheidung in MspEvaluationHistory dokumentiert. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Statistics\MspCollectors\MspCollectorsBL.cs, MspDowloadStart: Duplikatprüfung auf MspCollectorInvoiceHead mit Monatsultimo-InvoiceDate; UpdateMspContractItem: switch über MspEvaluationDecision (ChangeQuantity/ChangePrice/ChangePriceAndQunatity) mit item.QuantityComplete/PurchaseBasePrice-Zuweisung - Begründung: durchsetzende Import- und Abgleichlogik. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, Tabellen MspCollectors, MspCollectorInvoiceHead, MspCollectorInvoiceItems, MspCollectorLogs, MspEvaluationHistory - Begründung: Datenhaltung der Schnittstelle und Historie. +Prüfidee: Zweiter Import desselben Veeam-Monats ohne "Ersetzen" liefert Warnung statt Doppelimport; Entscheidung "ChangePriceAndQunatity" ändert Vertragsposition, schreibt Preislog und Historieneintrag. +Tracelinks: StRS-1004; SwRS-1039, SwRS-1040, SwRS-1047 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - geschäftskritischer Abrechnungsabgleich; Lieferantenschemata als Plugin-Konzept fortführen. +Status: belegt +``` + +### SyRS-1018: PLM-Lizenzüberwachung mit Wiedervorlage und Folgeprozess + +``` +ID: SyRS-1018 +Titel: PLM-Lizenzüberwachung mit Wiedervorlage und Folgeprozess +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: PLM-Modul, Vertriebsmitarbeiter (Renewals), ToDo-System +Vorbedingung: Rechnungen mit Lizenz-/Aboartikeln vorhanden; PLM-Einstellungen (Toleranztage, Zuständiger, E-Mail-Vorlage) gepflegt +Fakt: ImportProductLifecycleInformations übernimmt Rechnungspositionen als ProductLifecycleInformation (dedupliziert über SourceI3D/SourceType/BarcodeI3D), erzeugt bei EndDate innerhalb der Toleranzfrist ToDo-Einträge über HandlePLMToDoEntries; RecalculatePLMToDoEntries gleicht Bestandsdaten erneut ab; UserForPLM ermittelt den zuständigen Mitarbeiter aus den Einstellungen; das PLM-UI bietet Angebots-/Erinnerungs-E-Mail und Angebotserstellung aus Vorlagen; Einstellungen liegen als AppSettings (DaysToTolerate, LicenseEmailTemplateBody, DifferentSelectedEmployee, ...). +Aussage: Das System soll verkaufte Lizenzen/Abos automatisch aus Rechnungen in eine Lebenszyklusliste übernehmen, ablaufende Positionen innerhalb einer konfigurierbaren Toleranzfrist einem zuständigen Mitarbeiter zur Wiedervorlage stellen und daraus Verlängerungsangebote und Erinnerungs-E-Mails erzeugen können. +Ergebnis: Kein Lizenzablauf ohne Wiedervorlage; Angebots-/Mailprozess direkt aus der Lebenszyklusliste. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Warehousing\ArticleManagement\ProductFamilyBL.cs, ImportProductLifecycleInformations (Dedup-Query auf SourceI3D/SourceType/BarcodeI3D; ToDo-Erzeugung bei StartDate >= Now-DaysToTolerate) und RecalculatePLMToDoEntries - Begründung: durchsetzende Überwachungslogik. + - [SEKUNDÄR] src\backend\Centron.BL\Finances\ProductLifecycleBL.cs, GetSettings/UpdateSettings über AppSettingsConst (DaysToTolerate, LicenseEmailTemplateBody, ShouldDifferentEmployeeBeSelected, ...) - Begründung: Konfigurierbarkeit des Prozesses. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\PLM\PlmViewModel.cs, Commands CreateNewOfferFromTemplateCommand, SendOfferEmailCommand, SendReminderEmailCommand - Begründung: Folgeprozesse im UI. +Prüfidee: Rechnung mit Lizenz-EndDate in 10 Tagen bei DaysToTolerate=30 erzeugt beim Import einen ToDo-Eintrag für den konfigurierten Mitarbeiter; erneuter Import derselben Rechnung erzeugt keinen Duplikatdatensatz. +Tracelinks: StRS-1004; SwRS-1034, SwRS-1035 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Renewals-Prozess ist zentraler Umsatztreiber der Zielbranche. +Status: belegt +``` + +### SyRS-1019: Projekt- und Auslastungsübersicht mit Ticketintegration + +``` +ID: SyRS-1019 +Titel: Projekt- und Auslastungsübersicht mit Ticketintegration +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Projektleiter, Teamleitung +Vorbedingung: Aktive CRM-Projekte und Helpdesk-Tickets vorhanden +Fakt: ProjectManagementViewModel lädt aktive CRM-Projekte (CrmProjectFilter.IsActive=true) samt zugehöriger Tickets (HelpdeskFilter.ProjectNumber), ergänzt projektlose aktive Tickets, berechnet je Mitarbeiter die Projektauslastung und blendet Abwesenheiten (Urlaub/Feiertag/c-Time) aus der Terminplanung ein; Ticketöffnung erfolgt mit Sperrprüfung (GetTicketAndPromptUnlock). +Aussage: Das System soll eine Projektübersicht bereitstellen, die aktive Projekte mit ihren Tickets und der personellen Auslastung inklusive Abwesenheiten zusammenführt und die Navigation in Ticket- und CRM-Projektdetails erlaubt. +Ergebnis: Konsolidierte Board-Sicht Projekte/Tickets/Mitarbeiterauslastung. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\ProjectManagement\ProjectManagementViewModel.cs, RefreshAsync: GetCrmProjectsAsync(IsActive=true) + GetHelpdesksThroughPaging(ProjectNumber=...) + RefreshEmployeeWorkload() - Begründung: implementierte Zusammenführung der drei Sichten. + - [SEKUNDÄR] ebd., DoLoadEmployeeSpecialAppointments: SQL auf Terminplanung/TerminplanungPerson mit LIKE 'Urlaub%'/'Feiertag%'/'%(c-Time)' - Begründung: Abwesenheitsintegration. +Prüfidee: Aktives Projekt mit 3 Tickets erscheint mit diesen Tickets im Board; Mitarbeiter mit eingetragenem Urlaub zeigt die Abwesenheit in der Auslastungszeile. +Tracelinks: StRS-1002; SwRS-1032 +Konsolidierung: nein +Übernahmewürdigkeit: Sonderfall - Logik ist auf die interne Abteilung "Software-Entwicklung" hart codiert (siehe SwRS-1032); Konzept übernehmen, Implementierung generalisieren. +Status: belegt +``` + +## A11 — Plattform & Querschnitt: SyRS + +### SyRS-1110: Schichtenarchitektur mit dualem Datenzugriff + +``` +ID: SyRS-1110 +Titel: Schichtenarchitektur mit dualem Datenzugriff +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Wartbarkeit +Akteur: WPF-Client / WebService / Business-Logik +Vorbedingung: Client ist entweder direkt mit SQL Server (CentronConnectionType.SqlServer) oder mit dem WebService (CentronWebServices) verbunden. +Fakt: Jedes Modul implementiert das ILogic-Interface doppelt: BL{X}Logic (direkter DB-Zugriff über BLSession/WebServiceBL) und WS{X}Logic (Remote-Aufruf); die Auswahl erfolgt über den ClassContainer; alle Methoden liefern Result. Beispiel: BLUiProfileLogic ruft session.GetBL().LoadProfiles(...), WSUiProfileLogic denselben Vertrag remote. +Aussage: Das System soll fachliche Logik so kapseln, dass identische Operationen wahlweise über direkte Datenbankverbindung oder über den zentralen Webservice ausgeführt werden, ohne dass sich die aufrufende UI ändert. +Ergebnis: Gleiche fachliche Ergebnisse (Result) unabhängig vom Verbindungstyp. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Services\Logics\Gui\Profiles\BLUiProfileLogic.cs, LoadProfilesAsync (using new BLSession → GetBL()) - Begründung: konkreter BL-Zweig des dualen Musters. + - [KONTEXT] docs\getting-started\general-structure.md ("Every module MUST implement both data access methods", SupportsConnectionTypes) - Begründung: dokumentiert das Muster als Pflicht. +Prüfidee: Für ein Referenzmodul denselben Aufruf über SqlServer- und WebService-Verbindung ausführen; Ergebnis-DTOs sind identisch. +Tracelinks: StRS-1101 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - Doppel-Implementierung ist ein Zugeständnis an den 2-Tier-Altbetrieb; in einer Web-/SaaS-Architektur genügt der Service-Zweig. +Status: belegt +``` + +### SyRS-1111: Datenbankkonventionen mit Änderungs- und Löschverfolgung + +``` +ID: SyRS-1111 +Titel: Datenbankkonventionen mit Änderungs- und Löschverfolgung +Ebene: SyRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Persistenzschicht (Centron.DAO/NHibernate) / SQL Server +Vorbedingung: Zentrale SQL-Server-Datenbank (SSMS_DB_SCHEMA.sql, 1.535 Tabellen, Schema dbo). +Fakt: database-conventions.md schreibt für jede Tabelle vor: PK-Spalte I3D (int IDENTITY, clustered), FK-Suffix I3D, Tracking-Spalten CreatedByI3D/CreatedDate/ChangedByI3D/ChangedDate, Soft-Delete (IsDeleted/DeletedByI3D/DeletedDate), nvarchar statt varchar, datetime2; Beispieltabelle AccountDevices im Schema entspricht dem. Historische Tabellen (z. B. Mandant, FahrkTXT) weichen ab (deutsche Namen, varchar). +Aussage: Das System soll alle neuen Tabellen nach einem einheitlichen Schema anlegen (technischer Schlüssel I3D, Benutzer-/Zeitstempel für Anlage und Änderung, logisches Löschen statt physischem Löschen) und Altbestand unverändert kompatibel halten. +Ergebnis: Jeder Datensatz trägt Herkunfts- und Änderungsinformation; gelöschte Datensätze bleiben rekonstruierbar. +Belege: + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[AccountDevices] (I3D IDENTITY PK, CreatedByI3D, ChangedDate, IsDeleted, DeletedByI3D, ...) - Begründung: umgesetzte Konvention im produktiven Schema. + - [KONTEXT] docs\guides\database\database-conventions.md (Abschnitte "Primary Key Convention", "Standard Tracking Columns", "Deletion Tracking") - Begründung: normative Beschreibung der Konvention. +Prüfidee: Schema-Query: Anteil der Tabellen mit I3D-Identity-PK und Created*/Changed*-Spalten ermitteln; neue Tabellen (ab definiertem Datum) müssen 100 % erfüllen. +Tracelinks: StRS-1101, StRS-1102 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Konvention (technischer PK, Audit-Spalten, Soft-Delete) ist direkt in ein neues Schema überführbar; deutsche Alt-Tabellen sind Migrationsgegenstand. +Status: belegt +``` + +### SyRS-1112: Automatisierte Test-Ebenen (Integration, End-to-End, Web-UI) + +``` +ID: SyRS-1112 +Titel: Automatisierte Test-Ebenen (Integration, End-to-End, Web-UI) +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Wartbarkeit (Testbarkeit) +Akteur: Entwicklungsteam / CI +Vorbedingung: Laufende Testinstanz (WebService + Datenbank) laut WebServiceConfig.xml. +Fakt: tests\ enthält Centron.Tests.Integration (xUnit-Tests gegen ICentronRestService inkl. Login-Token, z. B. TestGetHelpdesksThroughPaging mit Paging-Asserts), Centron.Tests.EndToEnd (fachliche Testordner von Account bis CentronUiProfile) und PlaywrightTests (TicketsTests, WebaccountTests für die Web-UI). +Aussage: Das System soll auf drei Ebenen automatisiert testbar sein: REST-Schnittstellentests mit echter Anmeldung, fachliche End-to-End-Tests je Modul und browserbasierte UI-Tests für die Weboberfläche. +Ergebnis: Regressionen in Schnittstellen, Fachlogik und Web-UI werden vor Auslieferung maschinell erkannt. +Belege: + - [PRIMÄR] tests\Centron.Tests.Integration\IntegrationTest.cs, TestGetHelpdesksThroughPaging ([Fact], IntegrationTestHelper.Login, Assert.Equal(1, result.PageCount)) - Begründung: ausgeführter Schnittstellentest mit Authentifizierung. + - [SEKUNDÄR] tests\PlaywrightTests\TicketsTests.cs, tests\Centron.Tests.EndToEnd\Tests\CentronUiProfile - Begründung: belegen die weiteren Testebenen. +Prüfidee: Testlauf aller drei Projekte gegen eine Referenzumgebung; Ergebnisbericht weist Ebenen getrennt aus. +Tracelinks: StRS-1101 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Teststrategie (API-, Fach-, UI-Ebene) ist für die Neuimplementierung fortzuführen; Playwright ist direkt web-tauglich. +Status: belegt +``` + +### SyRS-1113: Verbindungs- und Lizenzüberwachung per Heartbeat + +``` +ID: SyRS-1113 +Titel: Verbindungs- und Lizenzüberwachung per Heartbeat +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Zuverlässigkeit +Akteur: WPF-Client (ConnectionHeartbeatTimer) / WebService / Lizenzverwaltung +Vorbedingung: Benutzer ist angemeldet; Lizenzen sind ein begrenztes Kontingent ("Sollten alle Lizenzen aufgebraucht sein ..."). +Fakt: ConnectionHeartbeatTimer sendet alle 5 Minuten (DEBUG: 10 s) IConnectionLogic.SendHeartbeatAsync(); bei ResultStatus.Error wird der Timer gestoppt, der Benutzer per modalem Dialog blockiert ("Ihre Anmeldung ist abgelaufen ...") und kann nur neu anmelden (SendHeartbeatAsync(forceReconnect: true)) oder die Anwendung beenden (Application.Current.Shutdown()). +Aussage: Das System soll aktive Client-Sitzungen zyklisch gegen den Server validieren und bei abgelaufener Anmeldung oder erschöpften Lizenzen die weitere Arbeit blockieren, bis eine Neuanmeldung gelingt oder die Anwendung beendet wird. +Ergebnis: Keine Weiterarbeit mit ungültiger Sitzung; Lizenzkontingent wird durchgesetzt; jeder Heartbeat wird mit Version und Verbindungstyp protokolliert. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\ConnectionHeartbeatTimer.cs, TimerTick (if (heartbeat.Status == ResultStatus.Error) { this.Stop(); ... BlockUserFromUsingCentron(...) }) - Begründung: durchsetzende Blockade im Client. + - [SEKUNDÄR] ebd., ShouldTryToReconnect (Dialogtext "Sollten alle Lizenzen aufgebraucht sein, können Sie einen Kollegen bitten sich auszuloggen") - Begründung: fachlicher Lizenzbezug des Heartbeats. +Prüfidee: Serverseitig Sitzung invalidieren; Client zeigt binnen 5 Minuten den Blockadedialog und lässt keine Bedienung außer Neuanmeldung/Beenden zu. +Tracelinks: StRS-1104, StRS-1101 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Sitzungs-/Lizenzvalidierung ist im SaaS-Modell serverseitig (Token-Ablauf) neu zu verankern; das Blockadeverhalten bleibt fachlich gültig. +Status: belegt +``` + +### SyRS-1114: Client-Betriebsprotokollierung mit Archivierung und Live-Ansicht + +``` +ID: SyRS-1114 +Titel: Client-Betriebsprotokollierung mit Archivierung und Live-Ansicht +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Wartbarkeit (Analysierbarkeit) +Akteur: WPF-Client / Administrator (LogViewer) +Vorbedingung: Client läuft; NLog ist über nlog.config konfiguriert (autoReload). +Fakt: nlog.config schreibt Logeinträge ab Level WARN (Logger Default, Centron*, NHibernate*) asynchron (AsyncWrapper, queueLimit 5000, overflowAction Discard) als CSV nach %CommonApplicationData%\c-entron software gmbh\c-entron.NET\Logs, mit Tagesarchivierung und maxArchiveFiles=15; der LogViewer (CentronLogViewModel) registriert sich an InMemoryLogging.Register und zeigt Einträge live, kopierbar in die Zwischenablage. +Aussage: Das System soll Warnungen und Fehler des Clients dauerhaft in täglich rotierten, maximal 15 Tage vorgehaltenen CSV-Dateien ablegen und Administratoren eine Live-Loganzeige in der Anwendung bieten, ohne den UI-Thread zu blockieren. +Ergebnis: Nachvollziehbare Fehlerhistorie pro Arbeitsplatz; Livediagnose ohne Dateizugriff. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\nlog.config (AsyncWrapper-Target, archiveEvery="Day", maxArchiveFiles="15", minLevel WARN) - Begründung: konfigurierte, wirksame Logging-Regel. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\Administration\LogViewer\CentronLogViewModel.cs, Start (InMemoryLogging.Register(WriteLogEntry)) - Begründung: Live-Ansicht als zweiter Konsumtionsweg. +Prüfidee: Warnung provozieren; Eintrag erscheint im LogViewer und in Log.csv; nach 16 Tagen existieren höchstens 15 Archivdateien. +Tracelinks: StRS-1102 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Konzept (persistentes Log + Live-Ansicht) übertragbar; CSV-Dateien sind im SaaS-Betrieb durch zentrales strukturiertes Logging zu ersetzen. +Status: belegt +``` + +### SyRS-1115: Feldbezogene Änderungshistorie pro Geschäftsobjekt + +``` +ID: SyRS-1115 +Titel: Feldbezogene Änderungshistorie pro Geschäftsobjekt +Ebene: SyRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Persistenzschicht (NHibernate-Listener) / Sachbearbeiter (Historienansicht) +Vorbedingung: Entität wird über NHibernate aktualisiert; angemeldeter Benutzer ist im LoggedInUserManager gesetzt. +Fakt: In DAOFactory registrierte PreUpdate-Listener schreiben bei Wertänderung einen ChangeLog-Datensatz (ObjectI3D, ObjectKind, Property, OldValue, NewValue, Date, AppUserI3D, Beschreibung "{0} wurde von {1} auf {2} geändert."); die Tabelle ChangeLog hat einen clustered Index (ObjectKind, ObjectI3D, Date DESC); ChangeLogBL liefert die Historie objektbezogen absteigend sortiert. +Aussage: Das System soll Änderungen an als protokollierungspflichtig markierten Feldern automatisch mit altem Wert, neuem Wert, Zeitpunkt und verursachendem Benutzer speichern und pro Geschäftsobjekt chronologisch bereitstellen. +Ergebnis: Lückenlose feldbezogene Historie, abrufbar über ObjectKind + ObjectI3D. +Belege: + - [PRIMÄR] src\backend\Centron.DAO\ChangeTracking\ChangeTrackingEventListener.cs, OnPreUpdate/CreateChangeLog (Vergleich oldValue/newValue, session.Save(log)) - Begründung: durchsetzender Schreibmechanismus. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[ChangeLog] + CREATE CLUSTERED INDEX [IX_ChangeLog] (ObjectKind, ObjectI3D, Date DESC) - Begründung: Datenmodell und Abfrageoptimierung der Historie. +Prüfidee: Protokolliertes Feld ändern; ChangeLog enthält genau einen neuen Eintrag mit korrektem Alt-/Neuwert und Benutzer. +Tracelinks: StRS-1102 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - fachliche Anforderung bleibt; Umsetzung sollte statt Reflection-Attributen deklarativ/ORM-nativ erfolgen (siehe SwRS-1133: Mechanismus derzeit ungenutzt). +Status: belegt +``` + +### SyRS-1116: Nutzungstelemetrie in Zeit-Buckets mit Upload-Kennzeichnung + +``` +ID: SyRS-1116 +Titel: Nutzungstelemetrie in Zeit-Buckets mit Upload-Kennzeichnung +Ebene: SyRS +Typ: Daten +Qualitätsmerkmal: +Akteur: TelemetryBL / Hersteller-Auswertung (Upload) +Vorbedingung: Nutzung von MCP-Tools, KI-Funktionen oder API-Methoden durch Benutzer. +Fakt: TelemetryBL aggregiert Nutzungsereignisse (UserID, ToolNameI3D, HardwareIDI3D, BucketStartUtc, Count) per MERGE-Upsert in dbo.McpToolUsageTelemetry, dbo.ArtificialIntelligenceToolUsageTelemetry und dbo.ApiCallTelemetry; Ereigniszeitpunkte werden mit TelemetryBucketHelper.SnapToBucket auf Buckets gerundet; GetCompletedPending* liefert nur Zeilen mit UploadedDate == null, MarkUploaded setzt UploadedDate chunkweise (1000er). +Aussage: Das System soll die Nutzung von KI-, MCP- und API-Funktionen pro Benutzer, Werkzeug, Gerät und Zeitfenster gezählt (nicht ereignisgenau) speichern und übertragene Datensätze dauerhaft als hochgeladen kennzeichnen, sodass kein Ereignis doppelt gemeldet wird. +Ergebnis: Aggregierte, idempotent upload-bare Nutzungszähler. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Telemetry\TelemetryBL.cs, UpsertMcpToolUsageBatch (MERGE dbo.McpToolUsageTelemetry WITH (HOLDLOCK) ... WHEN MATCHED THEN UPDATE SET T.Count = T.Count + S.Inc) - Begründung: durchgesetzte Aggregationslogik. + - [PRIMÄR] ebd., GetCompletedPendingMcpToolUsage (f.UploadedDate == null && f.BucketStartUtc < maxBucketStartUtc) und MarkUploaded (UPDATE ... SET UploadedDate) - Begründung: Upload-Zustandsmaschine. +Prüfidee: Zwei gleichartige Ereignisse im selben Bucket erzeugen genau eine Zeile mit Count=2; nach MarkUploaded liefert GetCompletedPending* die Zeile nicht mehr. +Tracelinks: StRS-1102 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - datenschutzschonende Aggregat-Telemetrie ist SaaS-tauglich; Datenschutz-/AVV-Prüfung der personenbezogenen UserID erforderlich. +Status: belegt +``` + +### SyRS-1117: Datenbankgestützte Volltextsuche über Geschäftsobjekte + +``` +ID: SyRS-1117 +Titel: Datenbankgestützte Volltextsuche über Geschäftsobjekte +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Sachbearbeiter (Suche) / Hintergrundindexierung (IndexSearchBL) +Vorbedingung: Objekte (Tickets/Helpdesk, Accounts) wurden indiziert; Änderungen markieren den Index über RequestUpdateFor als aktualisierungsbedürftig. +Fakt: IndexSearchBL pflegt je Objekt Terme in dbo.ObjectFulltextIndex (TextValue nvarchar(1000), ObjectI3D, ObjectKind) und Statuszeilen in dbo.ObjectFulltextIndexStats (LastUpdate, IsUpdateRequested); die Suche zerlegt den Suchtext in Terme und verknüpft je Term eine StartsWith-Query per INNER JOIN, sodass nur Objekte mit ALLEN Termen gefunden werden; AccountBL.SaveOrUpdate und HelpdeskBL rufen RequestUpdateFor nach Änderungen auf. +Aussage: Das System soll Freitextinhalte ausgewählter Objektarten in einen datenbankinternen Suchindex zerlegen, diesen bei Objektänderung asynchron aktualisieren und Suchanfragen als UND-Verknüpfung von Wortstamm-Präfixtreffern beantworten. +Ergebnis: Trefferliste (ObjectI3D, Kind) aller Objekte, die alle Suchterme enthalten; verwaiste Indizes gelöschter Objekte werden entfernt (Step 2 in UpdateIndexesInternal). +Belege: + - [PRIMÄR] src\backend\Centron.BL\IndexSearch\IndexSearchBL.cs, SearchIndexQueryable (d.TextValue.StartsWith(f), Join über ObjectI3D+Kind) - Begründung: durchgesetzter Suchalgorithmus. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[ObjectFulltextIndex] + UNIQUE CLUSTERED INDEX [CI_ObjectFulltextIndex] (ObjectI3D, ObjectKind, I3D) - Begründung: Datenmodell des Index. + - [SEKUNDÄR] src\backend\Centron.BL\Accounts\AccountBL.cs:635 (RequestUpdateFor(CentronObjectKindNumeric.Account, account.I3D)) - Begründung: Aktualisierungsauslösung bei Datenänderung. +Prüfidee: Suche "Drucker defekt" findet nur Tickets, die beide Wortstämme enthalten; nach Löschen eines Tickets verschwinden dessen Indexzeilen beim nächsten Volllauf. +Tracelinks: StRS-1103 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - fachliches Verhalten (Stammform-Präfix, UND-Logik) übernehmen; technische Umsetzung im Web eher über dedizierte Suchengine als über SQL-Tabellen. +Status: belegt +``` + +### SyRS-1118: Konfigurierbare KI-Provider-Anbindung mit abgesicherten Endpunkten + +``` +ID: SyRS-1118 +Titel: Konfigurierbare KI-Provider-Anbindung mit abgesicherten Endpunkten +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: KI-Subsystem (Centron.BL\ArtificialIntelligence) / externe KI-APIs (OpenAI, IONOS, Anthropic, Mistral, Google, OpenAI-kompatibel) +Vorbedingung: Administrator hat KI-Einstellungen (ApiType, ApiLink, ApiKey, DefaultModel) als ApplicationSettings hinterlegt. +Fakt: ApiClientFactory.CreateApiClient wählt je ArtificialIntelligenceApiType den Client (OpenAiApiClient bzw. ChatModelApiClient mit provider-spezifischen Implementierungen); AiApiLinkValidator erzwingt pro Provider den kanonischen HTTPS-Host (z. B. https://api.openai.com/v1) und erlaubt HTTP nur für lokale/private Adressen (LM-Studio-Fall); Antworten mit FinishReason ContentFilter/Length werden als Fehler ("Text zu lang oder ungeeignet") abgewiesen; Streaming wird über Channels unterstützt. +Aussage: Das System soll mehrere KI-Anbieter über eine einheitliche Client-Abstraktion anbinden, dabei nur validierte Endpunkt-URLs (HTTPS bzw. lokal/privat für Eigenhosting) zulassen und Chat-Antworten sowohl vollständig als auch als Token-Stream liefern. +Ergebnis: Austauschbarer Provider ohne Änderung der Aufrufer; fehlerhafte oder manipulierte API-Links werden mit InvalidOperationException abgewiesen. +Belege: + - [PRIMÄR] src\backend\Centron.BL\ArtificialIntelligence\AiApiLinkValidator.cs, ValidateProviderApiLink (Host-Vergleich gegen canonicalUri, throw InvalidOperationException "Ungültiger API-Link für {providerName}.") - Begründung: durchsetzende Endpunktprüfung. + - [PRIMÄR] src\backend\Centron.BL\ArtificialIntelligence\ApiClientFactory.cs, CreateApiClient/CreateChatModelClient (switch settings.ApiType) - Begründung: Provider-Abstraktion. +Prüfidee: ApiType=OpenAI mit ApiLink "https://evil.example/v1" konfigurieren → Verbindungsaufbau wird mit "Ungültiger API-Link für OpenAI." verweigert; http://192.168.x.x wird für OpenAiCompatible akzeptiert. +Tracelinks: StRS-1103 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Provider-Abstraktion inkl. SSRF-Schutz (Host-Whitelist) ist für eine SaaS-Lösung unmittelbar wiederverwendbar. +Status: belegt +``` + +### SyRS-1119: Zentrale Dateiablage mit Versionierung und Sperrmechanismus + +``` +ID: SyRS-1119 +Titel: Zentrale Dateiablage mit Versionierung und Sperrmechanismus +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Endanwender (CentronFileSystem-UI) / Dokumentverwaltung (IDocumentLogic/IDirectoryLogic) +Vorbedingung: Benutzer ist angemeldet; Verzeichnisbaum (RootDirectory) existiert. +Fakt: CentronFileSystemConnector bündelt die Dateiablage-Operationen: Verzeichnisse anlegen/umbenennen/löschen, Dokumente hochladen (AddDocumentToDirectoryAsync mit Metainformationen und fileObjectKind), umbenennen, löschen, neue Dokumentversionen (AddNewDocumentVersion), Check-out mit Arbeitsstation und lokalem Pfad (CheckOutDocument(documentI3D, lockedByWorkstation, lockedFilePath)), Check-in (CheckInDocument mit fileData) und UndoCheckOut; zusätzlich Volltextindexierung einzelner Dokumente (CreateIndexesForDocument) und Alt-Dokumente aus Delphi (GetDelphiDocuments). +Aussage: Das System soll eine hierarchische, objektbezogene Dateiablage bereitstellen, in der Dokumente versioniert werden und zur Bearbeitung exklusiv ausgecheckt werden können (inkl. Anzeige, welche Arbeitsstation sperrt), einschließlich Zugriff auf Altdokumente des Vorgängersystems. +Ergebnis: Dokument hat nach Check-in eine neue Version; während des Check-outs ist die Sperre mit Arbeitsstation dokumentiert. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\CentronFileSystem\CentronFileSystemConnector.cs, CheckOutDocument/CheckInDocument/AddNewDocumentVersion/UndoCheckOut - Begründung: vollständiger Operationsvertrag der Dateiablage im Client. + - [SEKUNDÄR] ebd., GetDelphiDocuments(documentI3D) - Begründung: Kompatibilität zum Altbestand (DocPagesDTO). +Prüfidee: Dokument auschecken (Workstation A), an Workstation B Check-out versuchen → muss abgewiesen/als gesperrt angezeigt werden; Check-in erzeugt neue Version, alte bleibt abrufbar. +Tracelinks: StRS-1104 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Versionierung/Sperren sind Kernanforderungen einer Web-Dateiablage; Workstation-basierte Sperren sind durch benutzer-/sitzungsbasierte Locks zu ersetzen. +Status: HYPOTHESE +Offene Frage: Die serverseitige Durchsetzung (Ablehnung eines zweiten Check-outs, Versionszählung) in der Dokumenten-BL (FileManagement) wurde nicht gelesen; belegt ist nur der Client-Vertrag (ICentronFileSystemConnector). +``` + +### SyRS-1120: Zweisprachige Benutzeroberfläche mit persistierter Sprachwahl + +``` +ID: SyRS-1120 +Titel: Zweisprachige Benutzeroberfläche mit persistierter Sprachwahl +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Benutzbarkeit +Akteur: Endanwender / WPF-Client (LocalizationHelper) +Vorbedingung: Windows-Benutzerprofil verfügbar (HKCU-Registry). +Fakt: Deutsche Texte liegen in Basis-ResX-Dateien (Resources\LocalizedStrings.resx), englische in LocalizedStrings.en.resx; LocalizationHelper.SaveCulture speichert die gewählte Kultur unter HKCU\Software\c-entron software gmbh\c-entron\Language und ConfigureLocalization setzt CultureInfo.CurrentUICulture beim Start; ResXManager.config.xml erzwingt SortFileContentOnSave=True; die Doku definiert Deutsch als Pflichtsprache aller Benutzertexte. +Aussage: Das System soll alle Benutzertexte standardmäßig auf Deutsch anzeigen, Englisch als zweite Sprache über Ressourcendateien bereitstellen und die Sprachwahl des Benutzers arbeitsplatzbezogen dauerhaft speichern. +Ergebnis: Nach Neustart erscheint die Oberfläche in der zuletzt gewählten Sprache; fehlende Übersetzungen fallen auf Deutsch zurück. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Localization\LocalizationHelper.cs, SaveCulture/ConfigureLocalization (Registry-Key "Language", CultureInfo.CurrentUICulture = culture) - Begründung: durchgesetzte Persistierung und Aktivierung. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Resources\LocalizedStrings.resx / LocalizedStrings.en.resx - Begründung: zweisprachige Ressourcenbasis. + - [KONTEXT] docs\getting-started\general-structure.md, "German-First Language Policy" - Begründung: dokumentierte Sprachstrategie. +Prüfidee: Sprache auf en umstellen, Client neu starten → englische Labels; Registry-Wert "Language"="en" vorhanden. +Tracelinks: StRS-1104 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Zweisprachigkeit übernehmen; Registry-Persistierung ist Workaround des Fat-Clients und im Web durch Benutzerprofil-Einstellung zu ersetzen. +Status: belegt +``` + +### SyRS-1121: Arbeitsplatz-Anpassung über GUI-Profile und externe Tools + +``` +ID: SyRS-1121 +Titel: Arbeitsplatz-Anpassung über GUI-Profile und externe Tools +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Endanwender / Administrator (Recht "Öffentliche Profile bearbeiten") / externes Programm +Vorbedingung: Benutzer angemeldet; für globale Profile Recht UserRightsConst.Administration.EDIT_GLOBAL_PROFILES. +Fakt: GUI-Profile werden in dbo.CentronUiProfiles (Caption, IsDefault, IsGlobal, IsActive, UiProfileType, Created/Changed inkl. Version) gespeichert; UiProfileBL erzwingt beim Speichern/Löschen globaler Profile das Recht EDIT_GLOBAL_PROFILES; externe Tools werden in dbo.ExternalTools (Name, Path, Location, CommandLineArguments, SuccessAction, IsDeactivated) verwaltet und vor dem Start werden Platzhalter (@@Benutzername@@, @@BelegNummer@@, @@AccountEmail@@, ...) durch Kontextdaten ersetzt. +Aussage: Das System soll Oberflächen-Layouts als private oder — mit gesondertem Recht — globale Profile speichern und Anwendern das Starten konfigurierter externer Programme mit kontextabhängig ersetzten Aufrufparametern ermöglichen. +Ergebnis: Profilauswahl pro Benutzer; externes Tool startet mit belegs-/kundenbezogenen Argumenten. +Belege: + - [PRIMÄR] src\backend\Centron.BL\GUI\Profiles\UiProfileBL.cs:51 (if (profile.IsGlobal && currentUser.User.HasUserRight(UserRightsConst.Administration.EDIT_GLOBAL_PROFILES) == false) return Result.AsError("Sie haben nicht das Recht ...")) - Begründung: durchsetzende Rechteprüfung. + - [PRIMÄR] SSMS_DB_SCHEMA.sql, CREATE TABLE [dbo].[CentronUiProfiles] und [dbo].[ExternalTools] - Begründung: Datenmodell beider Anpassungsmechanismen. +Prüfidee: Benutzer ohne EDIT_GLOBAL_PROFILES versucht, ein globales Profil zu speichern → Fehlermeldung; externes Tool mit @@BelegNummer@@ startet mit konkreter Belegnummer. +Tracelinks: StRS-1104 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Profil- und Tool-Konzept übernehmen; lokale EXE-Starts (Path/CommandLineArguments) sind im Web-Client neu zu denken (URL-Handler/Deep-Links). +Status: belegt +``` + +## Cluster A12 — Administration, Konfiguration & Betrieb — SyRS + +### SyRS-1211: Mandanten- und Filialverwaltung mit Deaktivierung statt Löschung + +``` +ID: SyRS-1211 +Titel: Mandanten- und Filialverwaltung mit Deaktivierung statt Löschung +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator; Subsystem MandatorManagement (WPF) + MandatorWebServiceBL (Webservice) +Vorbedingung: Mindestens ein Mandant existiert (Standardmandant) +Fakt: Das UI lädt alle Mandanten über IMandatorManagementLogic.GetAllMandatoryExtended(), erzwingt einen Namen als Pflichtfeld, verbietet das Löschen des Standardmandanten (CanDelete: Default != true) und setzt beim "Löschen" State=0 mit Kommentar "deleting is not supported, set status '0'"; Mandanten mit aktiven Filialen sind nicht löschbar. +Aussage: Das System soll Mandanten anlegen, ändern und deaktivieren (nicht physisch löschen), wobei der Standardmandant und Mandanten mit aktiven Filialen nicht deaktiviert werden dürfen und ein Mandantenname Pflicht ist. +Ergebnis: Historische Belege behalten ihren Mandantenbezug; deaktivierte Mandanten erscheinen nicht mehr in der aktiven Auswahl. +Belege: + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\Administration\MandatorManagement\MandatorManagementViewModel.cs (DeleteMandatorAsync: Prüfung Branches.Any(...), State = 0; CanDelete; SaveMandatorAsync: string.IsNullOrEmpty(Mandator)-Prüfung) - Begründung: durchgesetzte Regeln für Pflichtname, Löschverbot und Statuswechsel. + - [SEKUNDÄR] UI-String "Mandant '...' enthält Aktive Filiale/-n und kann nicht gelöscht werden." (ebd., Zeile 241) - Begründung: Fehlermeldung bestätigt die Geschäftsregel. +Prüfidee: Versuch, den Standardmandanten bzw. einen Mandanten mit aktiver Filiale zu löschen, muss abgewiesen werden; erfolgreiches "Löschen" muss den Datensatz mit Status 0 in der Tabelle Mandant belassen. +Tracelinks: StRS-1201 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Soft-Delete für referenzierte Stammdaten ist fachlich notwendig. +Status: belegt +``` + +### SyRS-1212: Zentrale typisierte Einstellungsverwaltung mit API-Zugriff + +``` +ID: SyRS-1212 +Titel: Zentrale typisierte Einstellungsverwaltung mit API-Zugriff +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Client-Anwendungen (WPF, Nexus/Blazor); Subsystem AppSettingsBL / CentronRestService +Vorbedingung: Webservice erreichbar; Benutzer angemeldet +Fakt: Clients greifen nie direkt auf die Settings-Tabellen zu, sondern über Gruppen-Settings-Klassen und POST-API-Methoden (Get.../Save...-Paare, z. B. GetReceiptInvoiceSettings); AppSettingsBL bietet GetSettings/GetSettingsForUpdate mit typisierten Zugriffen (GetBool/GetInt/GetString/GetLargeString/GetEnum/GetDecimal) und Defaultwerten. +Aussage: Das System soll alle Anwendungseinstellungen ausschließlich über eine serverseitige, typisierte Einstellungs-API bereitstellen und ändern, wobei jeder Lesezugriff einen Defaultwert für fehlende Einstellungen definiert. +Ergebnis: Einstellungen sind konsistent über alle Clients; fehlende Werte führen nicht zu Fehlern, sondern zu definierten Defaults. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\Settings\AppSettingsBL.cs (GetSettings/GetSettingsForUpdate/UpdateSetting) - Begründung: zentrale Zugriffsschicht auf AppSetting-Entities. + - [PRIMÄR] src\backend\Centron.BL\Security\PdfSigningBL.cs (GetPdfSigningSettings: settings.GetString(ApplicationSettingID..., string.Empty)) - Begründung: Beispiel eines Gruppen-Settings-Zugriffs mit Defaultwert. + - [KONTEXT] docs\guides\development\settings-management.md (Abschnitte "Group Setting Classes", "API Patterns": alle Setting-APIs per HTTP POST) - Begründung: dokumentierte Architekturregel. +Prüfidee: Neue Einstellung ohne DB-Eintrag lesen: API liefert Defaultwert; Save-API schreiben und erneut lesen: persistierter Wert kommt zurück. +Tracelinks: StRS-1202 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - typisierte Settings-API mit Defaults ist ein tragfähiges Muster für die Neuimplementierung. +Status: belegt +``` + +### SyRS-1213: Textbausteinsystem für Belege, Mahnungen und Helpdesk + +``` +ID: SyRS-1213 +Titel: Textbausteinsystem für Belege, Mahnungen und Helpdesk +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Sachbearbeiter (indirekt), Administrator (Pflege); Subsystem TextModuleBL +Vorbedingung: Textbausteine (TextModule) sind gepflegt +Fakt: TextModuleBL liefert je Belegart (Angebot, Auftrag, Lieferschein, Abholschein, Rechnung, Gutschrift, Mahnung 1-3, Helpdesk intern/extern, Bestellung, Wareneingang, Rücksendung u. a.) getrennte Anrede- (AN_*) und Abrede-Texte (AB_*) über den Typ TextModuleType; Pflege erfolgt im Modul TextBlockManagement. +Aussage: Das System soll für jede Belegart und für Helpdesk-Kommunikation getrennt pflegbare Anrede- und Schlusstexte (Textbausteine) bereitstellen, die beim Erzeugen von Belegen und E-Mails automatisch eingesetzt werden. +Ergebnis: Belege und Mails enthalten die zur Belegart passenden, ggf. kunden- oder benutzerspezifischen Texte. +Belege: + - [PRIMÄR] src\backend\Centron.BL\TextModuleArea\TextModuleBL.cs (GetOfferSalutation/GetInvoiceAgreement/... mit TextModuleType.AN_ANGEBOT, AB_RECHNUNG, AP_MAHNUNG1-3, AP_HELPDESK_*) - Begründung: vollständige Typliste und Zugriffslogik pro Belegart. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\Administration\TextBlockManagement\TextBlockManagementViewModel.cs (Baumstruktur TextBlockTreeItemBase, Gruppen BusinessTextBlockGroupDTO) - Begründung: Verwaltungsoberfläche der Textbausteine. +Prüfidee: Für Belegart Rechnung Anrede- und Abrede-Text pflegen; Rechnung erzeugen und prüfen, dass beide Texte an den erwarteten Stellen erscheinen. +Tracelinks: StRS-1202 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Textbausteine je Belegart sind Standardfunktion eines ERP. +Status: belegt +``` + +### SyRS-1214: Zentral steuerbare, fehlertolerante Hintergrunddienste + +``` +ID: SyRS-1214 +Titel: Zentral steuerbare, fehlertolerante Hintergrunddienste +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Zuverlässigkeit +Akteur: Systembetreiber; Subsystem Centron.Host (HostedServices) +Vorbedingung: Host-Prozess läuft und erreicht die Datenbank +Fakt: Alle Hintergrunddienste erben von ManagedBackgroundService: Start erst nach 1 Minute Verzögerung, Aktivierungsprüfung je Dienst gegen die Tabelle BackgroundServices (60 s Cache), Protokollierung von StartTime/LastRunTime, exponentielles Backoff bis max. 5 Minuten bei aufeinanderfolgenden Fehlern, Verbindungspool-Recovery (TryRecoverConnectionPool). +Aussage: Das System soll jeden Hintergrunddienst einzeln über die Datenbank aktivierbar/deaktivierbar machen, seine Start- und letzten Laufzeitpunkte protokollieren und bei Fehlern mit wachsendem Wartezeitabstand weiterlaufen, ohne dass andere Dienste oder der Host beeinträchtigt werden. +Ergebnis: Betreiber können Dienste zur Laufzeit steuern und deren Gesundheit anhand von LastRunTime beurteilen; transiente DB-Fehler eskalieren nicht. +Belege: + - [PRIMÄR] src\webservice\Centron.Host\AspNetCore\HostedServices\ManagedBackgroundService.cs (ExecuteAsync, GetIsEnabledCached: return _cachedIsEnabled ?? false; GetDelayWithBackoff: Math.Pow(2, _consecutiveFailures), MaxBackoffDelay 5 min) - Begründung: durchgesetzte Steuer- und Robustheitslogik. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql, [dbo].[BackgroundServices] (ServiceName, IsEnabled, LastRunTime, StartTime) - Begründung: persistentes Steuer- und Monitoringmodell. +Prüfidee: Dienst deaktivieren (IsEnabled=0) und binnen 60-120 s prüfen, dass keine Ausführung mehr stattfindet; drei Fehlläufe provozieren und Backoff-Intervalle im Log messen. +Tracelinks: StRS-1203 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - als Anforderung an den Job-Scheduler der Neuimplementierung. +Status: belegt +``` + +### SyRS-1215: Eskalationsdienst mit 15-Minuten-Zyklus, Lizenz- und Abschaltprüfung + +``` +ID: SyRS-1215 +Titel: Eskalationsdienst mit 15-Minuten-Zyklus, Lizenz- und Abschaltprüfung +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Subsystem EscalationsService (Host); Empfänger: Techniker, Vertriebler, Chef (per Mail/ToDo) +Vorbedingung: Lizenz "EscalationsServer" vorhanden; Einstellung NoEscalationFromService nicht gesetzt +Fakt: EscalationsService läuft alle 15 Minuten (GetExecutionInterval = TimeSpan.FromMinutes(15)), bricht ohne Lizenz LicenseGuids.EscalationsServer ab und CheckEscalations() liefert bei gesetztem AppSettingsConst.NoEscalationFromService den Fehler "Service ist deaktiviert"; ansonsten wird EscalationBL.DoEscalation ausgeführt und ein EscalationsLog geführt. +Aussage: Das System soll überfällige Vorgänge (insb. Helpdesk-Tickets) automatisch alle 15 Minuten auf Eskalation prüfen, sofern die Eskalationsserver-Lizenz vorliegt und die globale Abschalt-Einstellung nicht aktiv ist, und jede Eskalation protokollieren. +Ergebnis: Eskalationen werden zeitnah ausgelöst und sind im Eskalationslog nachvollziehbar; ohne Lizenz oder bei Abschaltung erfolgt keine Eskalation. +Belege: + - [PRIMÄR] src\webservice\Centron.Host\AspNetCore\HostedServices\EscalationsService.cs (ExecuteService: if (!LicenseManager.Instance.HasLicense(LicenseGuids.EscalationsServer)) return; Intervall 15 min) - Begründung: durchgesetzte Lizenz- und Zyklusregel. + - [PRIMÄR] src\backend\Centron.BL\WebServices\Sales\Support\Escalation\EscalationWebserviceBL.cs (CheckEscalations: GetBool(AppSettingsConst.NoEscalationFromService) => Result.AsError("Service ist deaktiviert")) - Begründung: durchgesetzter globaler Abschalter. + - [SEKUNDÄR] ebd. GetEscalationsLog - Begründung: Protokollierung der Eskalationen. +Prüfidee: NoEscalationFromService=1 setzen und prüfen, dass kein Eskalationslauf erfolgt; mit Lizenz und aktiver Einstellung ein überfälliges Ticket anlegen und Eskalationslog-Eintrag binnen 15 min erwarten. +Tracelinks: StRS-1202, StRS-1203 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Eskalationsautomatik ist zentral für SLA-Einhaltung; Lizenzkopplung ist Produktentscheidung. +Status: belegt +``` + +### SyRS-1216: PDF-Signierung und -Exportkonformität als Systemdienst + +``` +ID: SyRS-1216 +Titel: PDF-Signierung und -Exportkonformität als Systemdienst +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Administrator (Konfiguration); Subsystem PdfSigningBL (Server) +Vorbedingung: PFX-Zertifikat mit privatem Schlüssel hinterlegt +Fakt: Das Admin-UI validiert beim Import, dass das PFX-Zertifikat einen privaten Schlüssel besitzt (testCert.HasPrivateKey, sonst Fehlermeldung); der Server signiert Dokumente nur, wenn ein Zertifikat hinterlegt ist (IsPdfSigningAvailable/DoGetPdfSigningSettings), und speichert Zertifikat und Passwörter AES-verschlüsselt in ApplicationSettings. +Aussage: Das System soll PDF-Dokumente serverseitig mit einem zentral hinterlegten, verschlüsselt gespeicherten Unternehmenszertifikat signieren; ohne gültiges Zertifikat mit privatem Schlüssel soll die Signierung mit verständlicher Fehlermeldung abgelehnt werden. +Ergebnis: Signierte PDFs entstehen ausschließlich mit dem geschützten zentralen Zertifikat; Fehlkonfiguration führt zu definierten Fehlern statt unsignierter Ausgabe. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Security\PdfSigningBL.cs (IsPdfSigningAvailable; DoGetPdfSigningSettings: return false wenn HasCertificate==false; SignPdfDocument: Fehler "Bitte prüfen Sie Ihre Einstellungen für die PDF-Signierung.") - Begründung: durchgesetzte Vorbedingungsprüfung des Signaturvorgangs. + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\Administration\PdfSigning\PdfSigningSettingsViewModel.cs (DoAddCertificate: Pkcs12CertificateLoader..., if (!testCert.HasPrivateKey) Abbruch mit Dialog "Ungültiges Zertifikat") - Begründung: Validierung des Zertifikats beim Import. +Prüfidee: Zertifikat ohne privaten Schlüssel importieren (muss abgelehnt werden); Signierversuch ohne Zertifikat (muss Fehlermeldung liefern); mit gültigem Zertifikat signieren und Signatur prüfen. +Tracelinks: StRS-1204 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - serverseitige Signierung mit zentralem Schlüsselmaterial ist auch im SaaS-Modell erforderlich (dort ggf. HSM/Key-Vault). +Status: belegt +``` + +### SyRS-1217: Betrieb als Container-Stack und als Windows-Dienst + +``` +ID: SyRS-1217 +Titel: Betrieb als Container-Stack und als Windows-Dienst +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Übertragbarkeit +Akteur: Systembetreiber / DevOps +Vorbedingung: Docker-Umgebung bzw. Windows-Server verfügbar +Fakt: Derselbe Host-Kern (CentronHost) wird als Linux-Container (Alpine, dotnet publish self-contained, TZ Europe/Berlin, MS-Fonts) im Compose-Stack aus db (SQL Server), webservice (Centron.Host.Console), smtp (Mailcatcher) und nexus (Blazor-Host) betrieben und alternativ als Windows-Dienst (CentronService.OnStart/OnStop ruft CentronHost.Instance.Start/Stop); Konfiguration wird per Volume (WebServiceConfig.xml, appsettings.Production.json) eingespielt. +Aussage: Das System soll wahlweise als Container-Stack (Linux) oder als Windows-Dienst betrieben werden können, wobei beide Betriebsarten denselben Anwendungskern und eine extern eingespielte Konfiguration nutzen. +Ergebnis: Identisches Systemverhalten in beiden Betriebsarten; Deployments sind über Registry-Images bzw. Installer reproduzierbar. +Belege: + - [PRIMÄR] docker\compose\compose.yaml (Services db/webservice/smtp/nexus, command /app/Centron.Host.Console, Volume WebServiceConfig.xml, restart: on-failure) - Begründung: definierter Container-Betrieb. + - [PRIMÄR] src\webservice\Centron.Host.WindowsService\CentronService.cs (OnStart: CentronHost.Instance.Start(); OnStop: ...Stop()) - Begründung: identischer Kern als Windows-Dienst. + - [SEKUNDÄR] docker\Dockerfile (Alpine-Basis, ENV TZ=Europe/Berlin, DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false) - Begründung: Locale-/Zeitzonenanforderungen des Betriebs. +Prüfidee: Beide Betriebsarten mit derselben Konfiguration starten und identisches API-Verhalten (Version, Settings-Endpunkte) verifizieren. +Tracelinks: StRS-1203 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Containerbetrieb ist die Zielarchitektur; Windows-Dienst-Variante ist für SaaS veraltet, aber für On-Premise-Übergang relevant. +Status: belegt +``` + +### SyRS-1218: Stundenzuschlagsmodelle für die Vertragsabrechnung + +``` +ID: SyRS-1218 +Titel: Stundenzuschlagsmodelle für die Vertragsabrechnung +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator (Pflege), Abrechnung/Verträge (Nutzung) +Vorbedingung: Vertrag existiert; Zuschlagsmodell aktiv +Fakt: Zuschlagsmodelle (HourlySurchargeRates) bestehen aus Positionen mit Zeitfenster (StartTime/EndTime) und Prozentsätzen je Wochentag und Feiertag (MondayPercent...HolidayPercent); Verträge referenzieren genau ein Modell (HourlySurchargeRateI3D am Beleg), ein Modell kann als globaler Standard gesetzt sein, Zuordnungswechsel erfordern Bestätigung und Änderungen werden in HourlySurchargeRateLog mit Mitarbeiter und Datum protokolliert. +Aussage: Das System soll je Vertrag ein Stundenzuschlagsmodell (zeit- und wochentagsabhängige prozentuale Zuschläge auf Arbeitszeiten) zuordnen, einen globalen Standardzuschlag unterstützen und alle Änderungen an Zuschlagsmodellen revisionssicher protokollieren. +Ergebnis: Leistungsabrechnung von Verträgen verwendet die korrekten Zuschlagsprozentsätze; Änderungen sind nachvollziehbar. +Belege: + - [PRIMÄR] SSMS_DB_SCHEMA.sql, [dbo].[HourlySurchargeRateItems] (StartTime, EndTime, MondayPercent...HolidayPercent decimal(18,4)), [dbo].[HourlySurchargeRateLog] (EmployeeI3D, Date, RateI3D, Caption) - Begründung: Datenmodell der Zuschlagslogik und des Protokolls. + - [PRIMÄR] src\centron\Centron.WPF.UI\Modules\Administration\HourlySurchargeRates\HourlySurchargeRatesViewModel.cs (SearchContract: Bestätigungsdialog "Vertrag hat bereits Modell", UpdateReceiptHourlySurchargeRateI3D; LoadRates: GlobalHourlySurchargeRateI3D) - Begründung: 1:1-Zuordnung Vertrag-Modell inkl. globalem Modell. +Prüfidee: Vertrag mit Modell A verknüpfen, dann Modell B zuweisen: Bestätigungsdialog muss erscheinen; Änderung am Modell speichern und Log-Eintrag mit Mitarbeiter/Datum prüfen. +Tracelinks: StRS-1202 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - abrechnungsrelevante Kernfunktion für Servicevertragskalkulation. +Status: belegt +``` + +### SyRS-1219: Update-Verfügbarkeits-Benachrichtigung mit Zielgruppensteuerung + +``` +ID: SyRS-1219 +Titel: Update-Verfügbarkeits-Benachrichtigung mit Zielgruppensteuerung +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator (Konfiguration), Anwender (Empfänger); Subsystem UpdateAvailableNotificationBL +Vorbedingung: Update-Paketquelle (NotificationSource) erreichbar; gültige aktuelle Versionsnummer +Fakt: GetAvailableUpdates vergleicht die aktuelle Client-Version mit den Paketversionen der konfigurierten Quelle und meldet nur dann ein Update, wenn eine höhere Version existiert; die Einstellung NotificationKind steuert die Zielgruppe (NoNotification / ShowToAdministrators / ShowToSelectedEmployees / ShowToAllEmployees) inkl. Mitarbeiterliste (ApplicationSettingID 10137/10138/10425). +Aussage: Das System soll beim Anmelden bzw. Versionscheck prüfen, ob eine neuere Programmversion verfügbar ist, und die Benachrichtigung darüber gemäß konfigurierter Zielgruppe (keine, nur Administratoren, ausgewählte Mitarbeiter, alle) ausspielen. +Ergebnis: Nur berechtigte Zielgruppen sehen Update-Hinweise; keine Meldung bei aktueller Version. +Belege: + - [PRIMÄR] src\backend\Centron.BL\Administration\UpdateAvailableNotificationBL.cs (GetAvailableUpdates: Version.TryParse, FirstOrDefault(f => f > parsedCurrentVersion); ShowUpdatesFor: switch über UpdateAvailableNotificationKind inkl. IsAdministratorGroup und EmployeeI3Ds.Contains) - Begründung: durchgesetzte Versions- und Zielgruppenlogik. + - [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\Administration\UpdateAvailableNotificationSettings\UpdateAvailableNotificationSettingsViewModel.cs (NotificationKind, NotificationSource, SelectedEmployees) - Begründung: Konfigurationsoberfläche. +Prüfidee: NotificationKind=ShowToSelectedEmployees mit Mitarbeiter X setzen: X erhält Hinweis bei neuerer Version, Y nicht; NotificationKind=NoNotification: niemand erhält Hinweise. +Tracelinks: StRS-1203 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - in einer SaaS-Lösung entfällt clientseitiges Update-Management weitgehend; Zielgruppen-Benachrichtigung bleibt als Release-Kommunikation sinnvoll. +Status: belegt +``` diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/Traceability.md b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/Traceability.md new file mode 100644 index 00000000..74f16eb6 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Ergebnisse/Traceability.md @@ -0,0 +1,324 @@ +# Traceability + +**System:** c-entron ERP-Suite | **Datum:** 2026-08-27 + +Forward-/Backward-Traceability zwischen StRS ↔ SyRS ↔ SwRS. Jede SwRS-Anforderung referenziert ihre SyRS, jede SyRS ihre StRS. Eine Zeile pro Kette; der Artefaktbeleg ist der Hauptbeleg der jeweils spezifischsten Anforderung. Nummernkreise: A1=1xx, A2=2xx, A3=3xx, A4=4xx, A5=5xx, A6=6xx, A7=7xx, A8=8xx, A9=9xx, A10=10xx, A11=11xx, A12=12xx. + +## A1 — Sicherheit, Identität, Berechtigungen + +| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg | +|---------|---------|---------|---------------| +| StRS-101 | SyRS-101 | SwRS-101 | Centron.BL\Administration\Rights\AppRightsBL.cs → HasUserRight (SQL Sichtrus⋈Sichmemb) | +| StRS-101 | SyRS-101 | SwRS-105 | Centron.Controllers\Authorization\AuthorizeUserRightAttribute.cs → OnAuthorization (401/403) | +| StRS-101 | SyRS-102 | SwRS-102 | SSMS_DB_SCHEMA.sql → CREATE TABLE dbo.Sichrech/Sichgrup/Sichmemb/Sichtrus | +| StRS-101 | SyRS-102 | SwRS-103 | AppRightsBL.cs → SaveRightGroup/DeleteRightGroup (UserRightsManagement-Prüfungen, Admin-Gruppen-Schutz) | +| StRS-101 | SyRS-102 | SwRS-104 | AppRightsBL.cs → WriteAddRightToGroupLog/WriteBaseLog (AppRightLog) | +| StRS-101 | SyRS-110 | — | Centron.WPF.UI\Extensions\RibbonControlExtensions.cs → nur clientseitige Rechteprüfung | +| StRS-102 | SyRS-103 | SwRS-109 | Centron.BL\Administration\Logins\TicketBL.cs → GetExpireDate/RefreshTicketExpireDate | +| StRS-102 | SyRS-104 | SwRS-106 | OpenIdConnectAuthenticator.cs → AppUser-Lookup über OpenIdConnectSubjectIdentifier | +| StRS-102 | SyRS-104 | SwRS-107 | BasicAuthenticator.cs → SHA1Decoder.GetDecodedSHA1String + Passwortvergleich | +| StRS-102 | SyRS-104 | SwRS-110 | UsersBL.cs → ChangeOwnPassword/IsValidAppUserPassword | +| StRS-102 | SyRS-105 | SwRS-112 | TwoFactorAuthBL.cs → HasToValidateTwoFactor | +| StRS-102 | SyRS-105 | SwRS-113 | EmailTwoFactorValidator.cs + TwoFactorAuthController.cs → /2fa/validate | +| StRS-102 | SyRS-105 | SwRS-114 | TwoFactorAuthenticationBL.cs → ValidateAuthenticationPin (GoogleAuthenticator) | +| StRS-102 | SyRS-106 | SwRS-111 | WebAccountBL.cs → LoginWithWebAccount (Statuskette) | +| StRS-102 | SyRS-107 | SwRS-108 | Authenticator.cs → ValidateAppUser (Deaktivierungsfenster) | +| StRS-103 | SyRS-108 | SwRS-115 | PasswordManagerBL.cs → ValidateUserRights + Guideline-Rechteprüfungen | +| StRS-103 | SyRS-108 | SwRS-116 | PasswordManagerBL.cs → EXPORT_ACCESS_AND_PASSWORD_DATA-Prüfung vor Export | +| StRS-103 | SyRS-108 | SwRS-117 | AESCryptoLogic.cs → EncryptText/GetKeyAndIV (inkl. Fallback-Key) | +| StRS-103 | SyRS-108 | SwRS-118 | Centron.Controls\PasswordManager\AccessManagementViewModel.cs → SealBreakPropertyValue | +| StRS-103 | SyRS-108 | SwRS-119 | PasswordManagementKeywordBL.cs → GetDecryptedKeywordById (fehlende Entschlüsselung) | +| StRS-104 | SyRS-109 | SwRS-120 | DataSecurityBL.cs → DoDeleteContactPerson + Löschprotokoll | +| StRS-104 | SyRS-109 | SwRS-121 | DataSecurityBL.cs → ACCESS_CLEANUP_DATABASE-Prüfung | +| StRS-104 | SyRS-109 | SwRS-122 | DsgvoBL.cs → ORDER_PROCESSING_CONTRACTS_MANAGEMENT-Prüfung | + +## A2 — Finanzen & Abrechnung + +| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg | +|---------|---------|---------|---------------| +| StRS-201 | SyRS-206 | SwRS-233 | AutomaticFacturaBL.Contracts.cs: NextDate/SetInvoiceTo/NormalizeCoefficient (Z. 1375–1583) | +| StRS-201 | SyRS-206 | SwRS-235 | AutomaticFacturaBL.Contracts.cs: SearchBillingContracts (Z. 847–970) | +| StRS-201 | SyRS-206 | SwRS-236 | AutomaticFacturaBL.Contracts.cs: StoreInvoiceToContract ToDo-Teil (Z. 1310–1336) | +| StRS-201 | SyRS-207 | SwRS-232 | ContractBL.cs: GetContingentRest (Z. 60–83) | +| StRS-201 | SyRS-207 | SwRS-234 | AutomaticFacturaBL.Contracts.cs: StoreBookedContingent (Z. 1098–1245) | +| StRS-201 | SyRS-208 | SwRS-230 | ContractBL.cs: RefreshContractEndeDate (Z. 1067–1177) | +| StRS-201 | SyRS-208 | SwRS-231 | ContractBL.cs: CloseContract (Z. 1243–1316) | +| StRS-201 | SyRS-209 | SwRS-251 | DeviceClickCounterBL.cs: GetAndUpdateDeviceClickCounter (Z. 234–270) | +| StRS-201 | SyRS-210 | SwRS-254 | HelpdeskTimerWebServiceBL.cs: ThrowIfUserDoesntHaveRightToChangeHelpdeskTimers (Z. 348–376) | +| StRS-202 | SyRS-211 | SwRS-237 | DunningRunBL.cs: UpdateInvoice (Z. 248–275) | +| StRS-202 | SyRS-211 | SwRS-238 | DunningRunBL.cs: SaveDunningRun (Z. 277–315); Tabelle Mahnlauf | +| StRS-202 | SyRS-211 | SwRS-241 | DunningRunBL.cs: GenerateMail (Z. 406–451) | +| StRS-202 | SyRS-212 | SwRS-239 | DunningBL.cs: GetDunningStopActive (Z. 170–182); cvw_InvoiceDunning NextDueDate | +| StRS-202 | SyRS-212 | SwRS-243 | DunningBL.cs: CalculateDunningStatistics (Z. 205–236) | +| StRS-202 | SyRS-213 | SwRS-242 | PaymentsBL.cs: DeleteIncomingPayment (Z. 38–78) | +| StRS-202 | SyRS-214 | SwRS-244 | OnlineBankingAccountTransactionsBL.cs: SaveOnlineBankingAccountTransactions (Z. 294–340) | +| StRS-202 | SyRS-214 | SwRS-245 | OnlineBankingAccountTransactionsBL.cs: CheckForCompleted (Z. 342–360) | +| StRS-202 | SyRS-214 | SwRS-246 | OnlineBankingAccountTransactionsBL.cs: AutoCompleteSingleAccountTransaciton (Z. 581–617) | +| StRS-202 | SyRS-214 | SwRS-247 | OnlineBankingAccountTransactionsBL.cs: BookAmountToAssignedInvoice (Z. 1042–1086) | +| StRS-202 | SyRS-214 | SwRS-248 | ScriptMethod11560.cs (Rechteanlage, TODO-Kommentar) | +| StRS-202 | SyRS-215 | SwRS-244 | FinApiClient.cs: LoadAccountTransactions (Z. 266 ff.); OnlineBankingFinApiBL.cs Z. 29–50 | +| StRS-203 | SyRS-216 | SwRS-249 | BookKeepingExportBL.cs: IsReceiptExported (Z. 209–226); PORTRECH/PORTWARE | +| StRS-203 | SyRS-216 | SwRS-250 | BookKeepingExportBL.cs: GetReceiptsBookingdataExportFile (Z. 443–544) | +| StRS-203 | SyRS-216 | SwRS-253 | CustomerCostCenterBL.cs: DeleteCustomerCostCenter (Z. 42–54) | +| StRS-203 | SyRS-216 | SwRS-255 | NamedQueryPool.xml: VoucherManagementGetVoucherArticles (Z. 680–709) | +| StRS-204 | SyRS-217 | SwRS-252 | SepaContractOnlinePdfDocumentHandler.cs: Confirm (Z. 78–178) | +| StRS-205 | SyRS-218 | SwRS-242 | PaymentsBL.cs: Rechteprüfung 10980 (Z. 43–44) | +| StRS-205 | SyRS-218 | SwRS-248 | CheckForUnknownIbanViewModel.cs: CheckUserRightsAsync (Z. 83–101) | +| StRS-205 | SyRS-218 | SwRS-254 | HelpdeskTimerWebServiceBL.cs: EDIT_TIME/OWN_TIME_EDIT (Z. 348–376) | + +## A3 — Vertrieb & Belegwesen + +| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg | +|---------|---------|---------|---------------| +| StRS-301 | SyRS-310 | SwRS-331 | OfferSpecificLogic.CanBeForwardedInto() (Zeile 314) | +| StRS-301 | SyRS-310 | SwRS-332 | ReceiptBL.ValidateReceiptForwarding() (Zeile 2462) | +| StRS-301 | SyRS-310 | SwRS-333 | ReceiptBL.ForwardReceipt() (Zeile 1548, UpdateReceiptNumber Zeile 1643) | +| StRS-301 | SyRS-311 | SwRS-330 | Centron.Interfaces\Sales\Receipts\ReceiptState.cs | +| StRS-301 | SyRS-311 | SwRS-343 | ReceiptBL.CreateNewVersion() (Zeile 3068) | +| StRS-301 | SyRS-311 | SwRS-344 | AutomaticallyCloseReceiptHelperBL.ItemIsFinished() | +| StRS-302 | SyRS-312 | SwRS-334 | NumberGroupBL.GetNextNumber() (bedingtes UPDATE, Zeile 80) | +| StRS-302 | SyRS-312 | SwRS-335 | InvoiceSpecificLogic.GetNumberGroup() (Zeile 104) | +| StRS-302 | SyRS-313 | SwRS-336 | ReceiptPriceHelper.CalculateReceiptVatPrices() (Zeile 61) | +| StRS-302 | SyRS-313 | SwRS-337 | ReceiptBL.CheckIfAllArticlePositionsHaveVatRate() | +| StRS-302 | SyRS-314 | SwRS-338 | ReceiptInvoiceBL.CancelInvoice() (Zeile 143, Recht Zeile 154) | +| StRS-302 | SyRS-314 | SwRS-339 | ReceiptInvoiceBL.FixInvoice() (UPDATE RechKopf SET IsFixed=1) | +| StRS-302 | SyRS-314 | SwRS-354 | ReceiptItemBL.cs Zeile 2954 (Sperre stornierter Belege) | +| StRS-302 | SyRS-315 | SwRS-340 | ReceiptBL.CanUserEditReceipt() (Zeile 10273) | +| StRS-302 | SyRS-316 | SwRS-341 | DunningRunBL (Mahnstufen-Switch Zeilen 253–268) | +| StRS-302 | SyRS-316 | SwRS-342 | ReceiptBL.CheckIfCustomerLimitIsReached() | +| StRS-302 | SyRS-321 | SwRS-353 | ReceiptBL.GetReceiptConditionText() (Zeile 8500) | +| StRS-303 | SyRS-317 | SwRS-345 | ReceiptItemPriceBL.GetBasePrice() (Zeile 154) | +| StRS-303 | SyRS-317 | SwRS-346 | ReceiptItemPriceBL.GetSpecialPrice() (Zeile 588) + CustomerSpecialPriceMaps (KundenSonderpreise) | +| StRS-303 | SyRS-317 | SwRS-347 | ReceiptBL.CheckArticleMinPrices() (Zeilen 9036–9130) | +| StRS-304 | SyRS-318 | SwRS-351 | InvoiceZugferdBL.GenerateZugferdFile() (Zeile 124) | +| StRS-304 | SyRS-318 | SwRS-352 | ZugferdImportController.cs ([Authorize], POST parse) | +| StRS-305 | SyRS-319 | SwRS-349 | MailingDataBL.SaveMailingData() (Version=2, Zeile 78) | +| StRS-305 | SyRS-319 | SwRS-350 | AccountSearchBL (AdvertisingNotAllowed-Filter, Zeilen 993–1011) | +| StRS-305 | SyRS-320 | SwRS-348 | SSMS_DB_SCHEMA.sql, CustomerProductMatrixRating/ChangeLogs (Zeilen 36519/36535) | + +## A4 — Artikel, Lager, Einkauf, Logistik, RMA + +| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg | +|---------|---------|---------|---------------| +| StRS-401 | SyRS-410 | SwRS-435 | SSMS_DB_SCHEMA.sql, cvw_BarcodeCount (Status in (1,2,8)) | +| StRS-401 | SyRS-410 | SwRS-436 | SSMS_DB_SCHEMA.sql, Tabelle NebenlagerArtikel | +| StRS-401 | SyRS-410 | SwRS-441 | BarcodeBL.ValidateNewBarcode | +| StRS-401 | SyRS-410 | SwRS-443 | BarcodeBL.GetSystemSNID | +| StRS-401 | SyRS-411 | SwRS-430 | ArticleBL.CheckUserRightBeforeSave | +| StRS-401 | SyRS-411 | SwRS-431 | ArticleBL.SaveArticle (Duplikat-/Längenprüfung) | +| StRS-401 | SyRS-411 | SwRS-432 | ArticleStockBL.UpdateArticlePurchasePrice | +| StRS-401 | SyRS-411 | SwRS-433 | SecondStockArticleBL.RebookStockArticle (TRANSFER_STOCK) | +| StRS-401 | SyRS-412 | SwRS-434 | SecondStockArticleBL.StockBookOrBookout (ARTIKlog) | +| StRS-401 | SyRS-412 | SwRS-442 | BarcodeBL.CheckOutBarCodes | +| StRS-401 | SyRS-413 | SwRS-437 | InventoryNewBL.CloseInventory | +| StRS-401 | SyRS-413 | SwRS-438 | InventoryBL.CloseStorages | +| StRS-402 | SyRS-414 | SwRS-444 | OrderSuggestionListBL, _sqlArticle | +| StRS-402 | SyRS-415 | SwRS-445 | EDIDispatcherBL.CreateEDISuggestionOrderAsync | +| StRS-402 | SyRS-415 | SwRS-446 | SupplierEdiBL.SaveReceiptItemAssignments | +| StRS-402 | SyRS-418 | SwRS-450 | IceCatImportService.GetArticleAsync | +| StRS-402 | SyRS-418 | SwRS-451 | TradePoolBL.StartTradeImport | +| StRS-403 | SyRS-419 | SwRS-439 | OrderCommissionBL.HasUserRightsTooAccessCommissionModule | +| StRS-403 | SyRS-419 | SwRS-440 | OrderCommissionBL.ExecuteCommissionForOrders | +| StRS-403 | SyRS-416 | SwRS-447 | CentronGlsLogic.DoValidateShipment | +| StRS-403 | SyRS-416 | SwRS-448 | CentronShipcloudLogic.CreateShipmentAsync | +| StRS-404 | SyRS-417 | SwRS-449 | RmaBL.SaveRma | + +## A5 — Helpdesk & Service + +| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg | +|---------|---------|---------|---------------| +| StRS-501 | SyRS-511 | SwRS-531 | HelpdeskStatusBL.DeleteHelpdeskStatus() | +| StRS-501 | SyRS-511 | SwRS-532 | HelpdeskCloseBL.CloseHelpdeskForNotificationMethods() | +| StRS-501 | SyRS-511 | SwRS-549 | TicketProjectBL.SaveOrUpdateTicketProject() | +| StRS-501 | SyRS-511 | SwRS-550 | HelpdeskConnectionNumberBL.EnsureHelpdeskConnection() | +| StRS-501 | SyRS-512 | SwRS-533 | HelpdeskBL.CheckUserRigths() | +| StRS-501 | SyRS-512 | SwRS-534 | HelpdeskBL.CheckWebRights() | +| StRS-501 | SyRS-512 | SwRS-535 | HelpdeskBL.DoValidateMandatoryFields() | +| StRS-501 | SyRS-513 | SwRS-536 | HelpdeskBL.GetDueDateFromPriority() | +| StRS-501 | SyRS-514 | SwRS-537 | EscalationBL.CheckEskalationStage()/UpdateTicket() | +| StRS-501 | SyRS-520 | SwRS-543 | CentronChecklistBL.ObjectHasOpenChecklists() | +| StRS-502 | SyRS-515 | SwRS-538 | HelpdeskTimerWebServiceBL.ThrowIfUserDoesntHaveRightToChangeHelpdeskTimers() | +| StRS-502 | SyRS-515 | SwRS-539 | HelpdeskTimerBL.DeleteHelpdeskTimer() | +| StRS-502 | SyRS-515 | SwRS-542 | HelpdeskTimerWebServiceBL.CheckTimerCanBeMoved() | +| StRS-502 | SyRS-516 | SwRS-540 | HelpdeskTimerSignatureBL.SignMultipleTimers() | +| StRS-502 | SyRS-516 | SwRS-541 | HelpdeskTimerSignatureBL.RemoveSignatureFromTime() | +| StRS-503 | SyRS-517 | SwRS-544 | ExpectedEventsBL.SaveExpectedEvent() | +| StRS-503 | SyRS-517 | SwRS-545 | ExpectedEventsMaps.cs (Mapping MessageContains*) | +| StRS-503 | SyRS-517 | SwRS-547 | TaskManagementHelpdeskActionHandler.Execute() | +| StRS-504 | SyRS-518 | SwRS-546 | SelfCareBL.GetWebFormByGuid() | +| StRS-504 | SyRS-519 | SwRS-548 | SurveyProcessBL.GetSurveyfromTemplate() | + +## A6 — Stammdaten & Assets + +| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg | +|---------|---------|---------|---------------| +| StRS-601 | SyRS-605 | SwRS-620 | Centron.BL\Accounts\AccountBL.cs, ValidateUserRights | +| StRS-601 | SyRS-605 | SwRS-624 | Centron.BL\Accounts\AccountAddressBL.cs, CheckSpecialUserRightForAddressLanguageBeforeSave | +| StRS-601 | SyRS-605 | SwRS-625 | Centron.BL\Accounts\AccountAddressContactBL.cs, AccountSaveAddressContact | +| StRS-601 | SyRS-606 | SwRS-621 | Centron.BL\Accounts\AccountBL.cs, GetNewAccount | +| StRS-601 | SyRS-606 | SwRS-622 | SSMS_DB_SCHEMA.sql, IX_Accounts_Number / IX_AccountCustomers_UniqueNumber | +| StRS-601 | SyRS-606 | SwRS-623 | Centron.BL\Accounts\AccountBL.cs, DeleteAccount | +| StRS-601 | SyRS-606 | SwRS-626 | Centron.BL\Accounts\AccountAddressBL.cs, GetNotImportedGeoInfoList | +| StRS-602 | SyRS-607 | SwRS-627 | Centron.BL\EmployeeArea\AppUserBL.cs, SaveOrUpdateAppUser | +| StRS-602 | SyRS-607 | SwRS-629 | Centron.BL\EmployeeArea\AppUserBL.cs, GetActiveAppUsers | +| StRS-602 | SyRS-608 | SwRS-628 | Centron.BL\EmployeeArea\EmployeeBL.cs, SaveOrUpdateEmployee | +| StRS-603 | SyRS-609 | SwRS-630 | Centron.BL\Sales\CustomerAssets\Contracts\ClickContracts\MasterDataListBL.cs, SaveMasterDataList | +| StRS-603 | SyRS-609 | SwRS-631 | ebd., RemoveMainDeviceSerialNumber / SwapMainDeviceSerialNumber | +| StRS-603 | SyRS-609 | SwRS-633 | Centron.Entities\Entities\Sales\Receipts\MasterDataLists\MasterDataList.cs vs. Entities\Devices\AccountDevice.cs | +| StRS-603 | SyRS-610 | SwRS-632 | Centron.BL\Devices\AccountDeviceBL.cs, DeleteAccountDevice | +| StRS-603 | SyRS-610 | SwRS-637 | Centron.BL\Devices\AccountDeviceBL.cs (Negativbefund Rechteprüfung) | +| StRS-604 | SyRS-611 | SwRS-635 | Centron.BL\Tags\TagsBL.cs, AddTicketTag | +| StRS-604 | SyRS-611 | SwRS-636 | Centron.BL\Administration\Customization\ModuleCustomPropertyBL.cs, SaveCustomPropertyStructure | +| StRS-604 | SyRS-612 | — | Centron.BL\ObjectExternalReferences\ObjectExternalReferenceBL.cs, CreateReference | +| StRS-604 | SyRS-613 | SwRS-634 | Centron.BL\CountryArea\CountryBL.cs, UpdateCurrencyRateByRateDictionary | + +## A7 — Kommunikation & persönliche Organisation + +| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg | +|---------|---------|---------|---------------| +| StRS-701 | SyRS-711 | SwRS-731 | Centron.BL\Mail\Factory\CentronMailFactory.cs, GetMail() | +| StRS-701 | SyRS-711 | SwRS-732 | Centron.BL\Mail\Protocols\SMTPMail.cs, CreateSmtpClient() | +| StRS-701 | SyRS-711 | SwRS-733 | Centron.BL\Mail\Protocols\SMTPMail.cs, CreateMailMessage() | +| StRS-701 | SyRS-711 | SwRS-734 | Centron.BL\Mail\Protocols\SMTPMail.cs, FillMailBodyOld() | +| StRS-701 | SyRS-711 | SwRS-735 | Centron.BL\Mail\Blacklist\DomainBlacklistBL.cs, IsBlacklisted() | +| StRS-701 | SyRS-712 | — | Centron.BL\WebServices\Mail\SendMailWebserviceBL.cs, CheckFromAdress() | +| StRS-701 | SyRS-713 | SwRS-736 | Centron.BL\Mail\Templates\MailTemplateBL.cs, MailTemplate() (Fallback-Kommentar Z. 248–255) | +| StRS-701 | SyRS-713 | SwRS-737 | Centron.BL\Mail\Templates\MailTemplateBL.cs, GenerateVariables() | +| StRS-701 | SyRS-714 | SwRS-738 | Centron.BL\MailScanner\MailScannerBL.cs, GetProfiles() / EncryptProperties() | +| StRS-702 | SyRS-715 | SwRS-739 | Centron.BL\AppointmentRequests\AppointmentRequestBL.cs, HandleAppointmentRequestReply() | +| StRS-702 | SyRS-716 | SwRS-740 | Centron.BL\Calendar\CalendarBL.cs, GetCalendarSynchronizationSettings() | +| StRS-704 | SyRS-717 | SwRS-741 | Centron.BL\Tapi\PhoneCallBL.cs, SearchContactPersonByPhoneNumberV2() | +| StRS-704 | SyRS-717 | SwRS-742 | Centron.BL\Tapi\PhoneCallBL.cs, SyncPhoneCalls() (Lizenzprüfung) | +| StRS-704 | SyRS-718 | SwRS-743 | Centron.BL\Chats\ChatBL.cs, GetFilterExpression() (OnlyOwn/Membership) | +| StRS-703 | SyRS-718 | SwRS-744 | Centron.BL\NexusNotifications\NexusNotificationsBL.cs, MarkAllNexusNotificationsAsRead() | +| StRS-703 | SyRS-718 | SwRS-748 | Centron.BL\SocialMedia\SocialMediaBL.cs, AddCommentToASocialMediaAction() | +| StRS-703 | SyRS-719 | SwRS-745 | Centron.BL\ToDoArea\ToDoBL.cs, GetTodosThroughPaging() (RIGHT_FREMDTODOLISTE) | +| StRS-703 | SyRS-719 | SwRS-746 | Centron.BL\MyDay\MyDayBL.cs, SaveOrUpdateWorkItem() (UniqueId-Dedup) | +| StRS-703 | SyRS-719 | SwRS-747 | Centron.BL\VideoPortal\VideoPortalAssignmentBL.cs, SaveVideoPortalAssignment() | + +## A8 — Web-Client Nexus & Service-Schnittstellen + +| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg | +|---------|---------|---------|---------------| +| StRS-801 | SyRS-811 | SwRS-839 | src\nexus\CentronNexus\Shared\Authorization\ClaimsService.cs (GetClaims) | +| StRS-801 | SyRS-811 | SwRS-840 | src\nexus\CentronNexus\Shared\Authorization\PortAuthorization.cs (PortHandler) | +| StRS-802 | SyRS-811 | SwRS-848 | src\nexus\CentronNexus\ProductionOrderManagement\Pages\ProductionOrderOverView.razor (fehlendes Authorize-Attribut) | +| StRS-801 | SyRS-812 | SwRS-841 | src\backend\Centron.BL\Sales\Receipts\ReceiptCartBL.cs (ThrowIfCanNotAccessCart) | +| StRS-801 | SyRS-812 | SwRS-842 | src\backend\Centron.BL\Sales\Receipts\ReceiptCartReleaseSystemBL.cs (OrdererApproveCart) | +| StRS-801 | SyRS-813 | SwRS-843 | src\nexus\CentronNexus\WebOffer\WebReceiptOverview.razor (ChangeWebReceiptState) | +| StRS-801 | SyRS-814 | SwRS-844 | src\backend\Centron.BL\Administration\Documents\Dsgvo\DsgvoBL.cs (ConfirmOnlinePdfDocument) | +| StRS-801 | SyRS-815 | SwRS-845 | src\backend\Centron.BL\Sales\Support\HelpdeskSearchBL.cs (IsWebAccountLogin-Filter) | +| StRS-802 | SyRS-816 | SwRS-846 | src\backend\Centron.BL\Sales\Support\HelpdeskCloseBL.cs (CloseHelpdesk) | +| StRS-802 | SyRS-816 | SwRS-847 | src\nexus\CentronNexus\ProductionOrderManagement\Components\WorkStepTemplateComponent.razor (FinishWorkstep) | +| StRS-803 | SyRS-817 | SwRS-831 | src\webservice\Centron.Controllers\Authorization\AuthorizeUserRightAttribute.cs (OnAuthorization) | +| StRS-803 | SyRS-817 | SwRS-832 | src\webservice\Centron.Controllers\Authorization\CentronHostedAuthorization.cs (HandleRequirementAsync) | +| StRS-803 | SyRS-817 | SwRS-833 | src\webservice\Centron.Controllers\Controllers\Unversioned\JwtAuthController.cs (LoginWithBearer) | +| StRS-803 | SyRS-817 | SwRS-834 | src\webservice\Centron.Controllers\Controllers\Unversioned\TwoFactorAuthController.cs (ValidateTwoFactorCode) | +| StRS-803 | SyRS-817 | SwRS-835 | src\backend\Centron.BL\WebServices\Administration\Logins\WebAccountWebServiceBL.cs (HasUserRight WEBACCOUNT_MANAGEMENT) | +| StRS-803 | SyRS-818 | SwRS-836 | src\webservice\Centron.Host\AspNetCore\WcfBridge\Interception\Interceptors\AuthenticateInterceptor.cs (InterceptExecution) | +| StRS-803 | SyRS-818 | SwRS-849 | src\backend\Centron.BL\Mobile\MobileBL.cs (GetMobileEmployee) | +| StRS-803 | SyRS-818 | SwRS-850 | src\backend\Centron.BL\WebLinks\WebLinkActionAccountActivityHandler.cs (Execute) | +| StRS-803 | SyRS-819 | SwRS-837 | src\webservice\Centron.Controllers\Configuration\GlobalExceptionFilter.cs (OnException) | +| StRS-803 | SyRS-819 | SwRS-838 | src\webservice\Centron.Controllers\Configuration\Routing\KebabCaseTransformer.cs (TransformOutbound) | +| StRS-804 | SyRS-820 | — | src\webservice\Centron.Host.Console\Program.cs (CentronHost.Instance.Start) | + +Hinweis: SwRS-848 hängt unter SyRS-811 (Zugriffsschutz) und zusätzlich fachlich unter StRS-802; SwRS-850 ist sekundär auch SyRS-816 zugeordnet (Tracelinks im Block). + +## A9 — Datenaustausch & Integrationen + +| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg | +|---------|---------|---------|---------------| +| StRS-901 | SyRS-911 | SwRS-931 | src\backend\Centron.BL\RiverDivo\RiverDivoBL.cs → ValidateRmmAccessKey (FixedTimeEquals) | +| StRS-901 | SyRS-911 | SwRS-933 | src\backend\Centron.BL\RiverDivo\RiverDivoBL.cs → CreateHelpdeskRequest (CreatedFrom = 7) | +| StRS-901 | SyRS-911 | SwRS-935 | src\backend\Centron.BL\RiverDivo\RiverDivoBL.cs → GetAllCustomersForSync (ChangedAfterDate, LogoHash) | +| StRS-901 | SyRS-912 | SwRS-932 | src\backend\Centron.BL\WebServices\Rmm\RmmConnectionSettingsWebServiceBL.cs → HasUserRight(SETTINGS) | +| StRS-901 | SyRS-912 | SwRS-937 | src\backend\Centron.BL\DataExchange\Connectors\DocBeeTicketCreationBL.cs → IsDocBeeActive (Lizenzprüfung) | +| StRS-901 | SyRS-912 | SwRS-947 | src\webservice\Centron.Controllers\Controllers\v1\DataExchange\TelekomDiveController.cs → SaveProfiles (ohne Rechteattribut) | +| StRS-901 | SyRS-913 | SwRS-934 | src\backend\Centron.BL\RiverDivo\RiverDivoBL.cs → GetCentronCustomerI3D (RiverbirdCustomerReference) | +| StRS-901 | SyRS-913 | SwRS-936 | src\backend\Centron.BL\DataExchange\Connectors\DocBeeTicketTimerBL.cs → SaveDocBeeTicketTimer | +| StRS-904 | SyRS-913 | SwRS-942 | src\backend\Centron.BL\Integrations\EsCustomerGroupBL.cs → Create/Delete (Soft-Delete) | +| StRS-901 | SyRS-913 | SwRS-945 | src\backend\Centron.BL\CPra\CPraConnectorBL.cs → GenerateLink (Base64-Parameter) | +| StRS-903 | SyRS-914 | SwRS-938 | src\backend\Centron.BL\DataExchange\DocuForm\DocuFormApiSettingsBL.cs → AES + SETTINGS-Recht | +| StRS-903 | SyRS-914 | SwRS-939 | src\centron\Centron.WPF.UI\Modules\Finances\DeviceClickCounter\DocuFormApiImport\DocuFormApiImportViewModel.cs → DownloadDeviceCounters | +| StRS-902 | SyRS-915 | SwRS-940 | src\backend\Centron.Entities\Entities\DataExchange\TelekomDive\TelekomDiveProfile.cs | +| StRS-902 | SyRS-915 | SwRS-941 | src\centron\Centron.WPF.UI\Modules\TelekomDive\TelekomDiveExportViewModel.cs → ExportToXml | +| StRS-902 | SyRS-916 | SwRS-946 | src\backend\Centron.Gateway\DataExchange\BookKeeping\BookKeepingFileExport.cs → PrepareStoreFile | +| StRS-904 | SyRS-917 | SwRS-943 | src\backend\Centron.BL\Administration\FileManagement\DirectoryBL.cs → IsDocSyncEnabledForObjectKind | +| StRS-904 | SyRS-917 | SwRS-944 | src\centron\Centron.WPF.UI\Modules\DataExchange\DataImport\AccountImport\IbanValidation.cs → IbanChecksumCheck | +| StRS-901 | SyRS-918 | — | src\backend\Centron.BL\RiverDivo\RiverConnectionBL.cs → GetActiveDirectoryUsers (WebAccount-Isolationsprüfung) | + +## A10 — Produktion, Projekte, PLM, QM, Statistik, Reporting + +| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg | +|---------|---------|---------|---------------| +| StRS-1001 | SyRS-1010 | SwRS-1030 | ProductionOrderBL.cs: LicenseManager.HasLicense(LicenseGuids.ProductionManagement)-Gate | +| StRS-1001 | SyRS-1010 | SwRS-1031 | ProductionBL.cs: Lizenzgate vor Maschinenstammdaten | +| StRS-1001 | SyRS-1011 | SwRS-1030 | ProductionOrderItemState.cs / ProductionOrderLogKind.cs | +| StRS-1001 | SyRS-1011 | SwRS-1031 | SSMS_DB_SCHEMA.sql: ProductionOrders/ProductionOrderLogs NOT-NULL-Constraints | +| StRS-1002 | SyRS-1012 | SwRS-1037 | SaleStatisticBL.GetSalesArticleStatistic: SALES_STATISTIC-Prüfung | +| StRS-1002 | SyRS-1012 | SwRS-1038 | ManagementInfoBL: MANAGEMENT_INFO_ONLY_OWN_BRANCH-Zwangsfilter | +| StRS-1002 | SyRS-1012 | SwRS-1046 | ModulesSlideViewModel.cs: Gruppierung/Suche/Favoriten | +| StRS-1002 | SyRS-1013 | SwRS-1041 | ReportDataBL.ExecuteQuery: Regex-Variablenersetzung | +| StRS-1002 | SyRS-1013 | SwRS-1042 | SSMS_DB_SCHEMA.sql: Tabellen ReportData und Reports | +| StRS-1002 | SyRS-1013 | SwRS-1043 | ReportServerAppModuleController.Description + ReportServerConnector | +| StRS-1002 | SyRS-1014 | SwRS-1041 | ReportDataWebBL.ReportEngineExecuteQuery: SQL_MANAGER/REPORT_MANAGEMENT-Prüfung | +| StRS-1002 | SyRS-1019 | SwRS-1032 | ProjectManagementViewModel.RefreshAsync/RefreshEmployeeWorkload | +| StRS-1003 | SyRS-1015 | SwRS-1033 | ProjectPriceImportViewModel: Fehlerliste + SpecialAgreementDifferenceViewModel | +| StRS-1003 | SyRS-1015 | SwRS-1044 | MassUpdateBL.StartReceiptPriceUpdate: ReceiptState.Active-Prüfung | +| StRS-1003 | SyRS-1015 | SwRS-1045 | MassUpdateBL.StartArticlePriceUpdate: Bulkchanger-Log | +| StRS-1003 | SyRS-1016 | SwRS-1036 | ReceiptBL.CheckIfAssetReasonIsNeeded: IsMandatory-Prüfung | +| StRS-1004 | SyRS-1017 | SwRS-1039 | MspCollectorsBL.MspDowloadStart: Duplikatprüfung MspCollectorInvoiceHead | +| StRS-1004 | SyRS-1017 | SwRS-1040 | MspCollectorsBL.UpdateMspContractItem: MspEvaluationDecision-Switch | +| StRS-1004 | SyRS-1017 | SwRS-1047 | AssetManagementArticleAssignmentBL: Löschschutz bei Vertragsreferenz | +| StRS-1004 | SyRS-1018 | SwRS-1034 | ProductFamilyBL.ImportProductLifecycleInformations: Dedup-Query | +| StRS-1004 | SyRS-1018 | SwRS-1035 | ProductFamilyBL: DaysToTolerate-Fristlogik + UserForPLM | + +## A11 — Plattform & Querschnitt + +| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg | +|---------|---------|---------|---------------| +| StRS-1101 | SyRS-1110 | SwRS-1130 | src\backend\Centron.DAO\DAOSession.cs (WithTransaction) | +| StRS-1101 | SyRS-1110 | SwRS-1143 | src\centron\Centron.WPF.UI\CentronFileSystem\CentronFileSystemConnector.cs | +| StRS-1101 | SyRS-1111 | SwRS-1131 | src\backend\Centron.Entities\PersistedEntity.cs (operator ==) | +| StRS-1101 | SyRS-1111 | SwRS-1132 | src\backend\Centron.DAO\DAOFactory.cs:100-127 (AppendListeners) | +| StRS-1101 | SyRS-1111 | SwRS-1147 | src\backend\Centron.DAO\Mappings\...\MandatorMaps.cs / MandatoryMaps.cs (Table("Mandant")) | +| StRS-1101 | SyRS-1112 | — | tests\Centron.Tests.Integration\IntegrationTest.cs (TestGetHelpdesksThroughPaging) | +| StRS-1102 | SyRS-1114 | — | src\centron\Centron.WPF.UI\nlog.config (csvTarget, WARN, 15 Archive) | +| StRS-1102 | SyRS-1115 | SwRS-1133 | src\backend\Centron.DAO\ChangeTracking\ChangeTrackingEventListener.cs | +| StRS-1102 | SyRS-1115 | SwRS-1134 | src\backend\Centron.DAO\ChangeTracking\LogHourlySurchargeRateChangesListener.cs | +| StRS-1102 | SyRS-1115 | SwRS-1135 | SSMS_DB_SCHEMA.sql:34746 (ChangeLog + IX_ChangeLog) | +| StRS-1102 | SyRS-1116 | SwRS-1136 | src\backend\Centron.BL\Telemetry\TelemetryBL.cs (MERGE WITH (HOLDLOCK)) | +| StRS-1102 | SyRS-1116 | SwRS-1137 | src\backend\Centron.BL\Telemetry\TelemetryBL.cs (InsertMissingNames) | +| StRS-1103 | SyRS-1117 | SwRS-1138 | src\backend\Centron.BL\IndexSearch\IndexBuilder.cs | +| StRS-1103 | SyRS-1117 | SwRS-1139 | src\backend\Centron.BL\IndexSearch\IndexSearchBL.cs (UpdateIndexesInternal) | +| StRS-1103 | SyRS-1117 | SwRS-1140 | SSMS_DB_SCHEMA.sql:45591 (ObjectFulltextIndex/Stats) | +| StRS-1103 | SyRS-1118 | SwRS-1141 | src\backend\Centron.BL\ArtificialIntelligence\AiApiLinkValidator.cs | +| StRS-1103 | SyRS-1118 | SwRS-1142 | src\backend\Centron.BL\Administration\ArtificialIntelligence\ArtificialIntelligenceBL.cs:184 | +| StRS-1104 | SyRS-1113 | — | src\centron\Centron.WPF.UI\ConnectionHeartbeatTimer.cs (TimerTick) | +| StRS-1104 | SyRS-1119 | SwRS-1143 | src\centron\Centron.WPF.UI\CentronFileSystem\CentronFileSystemConnector.cs (CheckOutDocument) | +| StRS-1104 | SyRS-1120 | SwRS-1144 | src\centron\Centron.WPF.UI\Localization\LocalizationHelper.cs | +| StRS-1104 | SyRS-1121 | SwRS-1145 | src\backend\Centron.BL\GUI\Profiles\UiProfileBL.cs:51 | +| StRS-1104 | SyRS-1121 | SwRS-1146 | src\backend\Centron.BL\ExternalToolsBL\ExternalToolBL.cs (SaveExternalTool) | + +## A12 — Administration, Konfiguration & Betrieb + +| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg | +|---------|---------|---------|---------------| +| StRS-1201 | SyRS-1211 | SwRS-1231 | MandatorManagementViewModel.DeleteMandatorAsync (State = 0) | +| StRS-1201 | SyRS-1211 | SwRS-1232 | MandatorManagementViewModel.IsSetToDefault / EditBranchDetails | +| StRS-1201 | SyRS-1211 | SwRS-1233 | MandatorWebServiceBL.SaveMandatoryExtended (fehlende Rechteprüfung) | +| StRS-1201 | SyRS-1211 | SwRS-1234 | MandatorManagementViewModel.SaveMandatorInstructionPrompt (Rechteprüfung 10510) | +| StRS-1202 | SyRS-1212 | SwRS-1235 | SSMS_DB_SCHEMA.sql [dbo].[ApplicationSettings] | +| StRS-1202 | SyRS-1212 | SwRS-1236 | docs\guides\development\settings-management.md + Tabellen Stammdat/ApplicationSettings | +| StRS-1202 | SyRS-1212 | SwRS-1245 | ReportDataWebBL.ReportEngineExecuteQuery (Rechteprüfung SQL_MANAGER) | +| StRS-1202 | SyRS-1213 | SwRS-1237 | TextModuleBL.GetTextModule (dreistufige Kaskade) | +| StRS-1202 | SyRS-1213 | SwRS-1238 | TextModuleBL.ReplaceCustomerTextBlockVariables ("@@") | +| StRS-1203 | SyRS-1214 | SwRS-1239 | ManagedBackgroundService.GetIsEnabledCached/GetDelayWithBackoff | +| StRS-1203 | SyRS-1214 | SwRS-1240 | DataQualityService.ExecuteService (Task-Isolation) | +| StRS-1202, StRS-1203 | SyRS-1215 | SwRS-1241 | EscalationTypeSettingViewModel.EscTypeVM_To_DTO (Hour1-3, StageReceivers) | +| StRS-1204 | SyRS-1216 | SwRS-1242 | PdfSigningBL.SavePdfSigningSettings (Rechteprüfung + AES) | +| StRS-1204 | SyRS-1216 | SwRS-1243 | PdfSigningBL.SignPdfDocument (Pkcs7Signer/SHA256/TSA) | +| StRS-1204 | SyRS-1216 | SwRS-1244 | PdfExportSettingsViewModel.InitializeDropdownLists (PDF/A-Stufen) | +| StRS-1203 | SyRS-1217 | SwRS-1248 | docker\compose\compose.yaml + CentronService.cs | +| StRS-1202 | SyRS-1218 | SwRS-1246 | HourlySurchargeRateItemViewModel.UpdateInvalidRatesReasons + HourlySurchargeRateLog | +| StRS-1203 | SyRS-1219 | SwRS-1247 | UpdateAvailableNotificationBL.ShowUpdatesFor | diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/RawResult.json b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/RawResult.json new file mode 100644 index 00000000..c95c86ce --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/RawResult.json @@ -0,0 +1 @@ +{"is_error":false,"duration_api_ms":15462451,"num_turns":2,"stop_reason":"end_turn","session_id":"73f6a03e-8aed-4897-8d13-e9e10ba3a32b","total_cost_usd":205.92314750000008,"usage":{"input_tokens":4,"cache_creation_input_tokens":1791,"cache_read_input_tokens":453523,"output_tokens":2278,"output_tokens_details":{"thinking_tokens":253},"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":1791,"ephemeral_5m_input_tokens":0},"inference_geo":"not_available","iterations":[{"input_tokens":2,"output_tokens":1575,"cache_read_input_tokens":227183,"cache_creation_input_tokens":948,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":948},"type":"message"}],"speed":"standard"},"modelUsage":{"claude-haiku-4-5-20251001":{"inputTokens":6962,"outputTokens":29,"cacheReadInputTokens":0,"cacheCreationInputTokens":0,"webSearchRequests":0,"costUSD":0.0071070000000000005,"contextWindow":200000,"maxOutputTokens":32000,"canonicalModel":"claude-haiku-4-5","provider":"firstParty","costBasis":"list"},"claude-fable-5":{"inputTokens":1626,"outputTokens":1343904,"cacheReadInputTokens":92177958,"cacheCreationInputTokens":3603520,"webSearchRequests":0,"costUSD":205.91604050000007,"contextWindow":1000000,"maxOutputTokens":64000,"canonicalModel":"claude-fable-5","provider":"firstParty","costBasis":"list"}},"permission_denials":[],"terminal_reason":"completed","fast_mode_state":"off","fast_mode_disabled_reason":"extra_usage_disabled","origin":{"kind":"task-notification"},"subagent_stats":{"spawned":18,"requested":{"background":0,"foreground":0,"unset":18},"started_in_background":18,"max_depth":1,"spawned_by_subagents":0,"completed":16,"failed":2,"killed":{"parent":0,"user":0,"system":0},"refused":{"depth_limit":0,"concurrency_limit":0,"budget":0},"by_type":{"general-purpose":18}},"subtype":"success","api_error_status":null,"result":"Der Lauf ist abgeschlossen. Alle sieben Ergebnisdateien liegen im Verzeichnis `Ergebnisse\\` und sind konsistenzgeprüft.\n\n## Ergebnis\n\n**413 Anforderungen** aus der gesamten Codebasis der c-entron ERP-Suite, verteilt auf drei Ebenen nach ISO/IEC/IEEE 29148: **50 StRS**, **122 SyRS**, **241 SwRS** — dazu Traceability (269 Ketten StRS↔SyRS↔SwRS), 16 Hypothesen, 203 Glossarbegriffe und der Analysebericht mit Modulinventar, Abdeckungstabelle und Konsistenzcheck.\n\n**Vorgehen:** Vor der ersten Anforderung wurde ein Modulinventar mit 96 Modulen erstellt (Schritt 0), danach in 12 parallelen Analyse-Clustern (Sicherheit, Finanzen/Abrechnung, Vertrieb, Lager/Einkauf, Helpdesk, Stammdaten, Kommunikation, Web/Schnittstellen, Integrationen, Produktion/Reporting, Plattform, Administration) mit eigenen ID-Nummernkreisen gearbeitet — erst Mindestabdeckung, dann Vertiefung nach Risiko.\n\n**Kennzahlen aus dem skriptgestützten Konsistenzcheck:**\n- Mindestabdeckung erfüllt: alle 96 Module haben ≥1 Anforderung (42 tief, 48 mittel, 6 flach, 0 nicht analysiert)\n- Keine doppelten IDs, keine Anforderung ohne Beleg, Prüfidee oder Übernahmewürdigkeit, keine toten Tracelinks\n- **198 risikorelevante Anforderungen** (Sicherheit/Abrechnung/Berechtigungen): jede mit PRIMÄR-Beleg inkl. durchsetzender Stelle oder als Hypothese gekennzeichnet — 0 Verstöße; die Liste steht vollständig im Analysebericht\n- `Hypothesen.md` deckungsgleich mit den 16 Inline-Markierungen (3,9 % Hypothesenquote)\n- 44 Konsolidierungskandidaten, alle 21 nicht-funktionalen Anforderungen mit ISO-25010-`Qualitätsmerkmal`\n\n**Fachlich wichtigste Befunde:** Der im Prompt genannte Konsolidierungsfall (Stammblätter vs. Assets) wurde bestätigt und auf **drei** Gerätedatenhaltungen erweitert; daneben ~20 weitere Doppelimplementierungen (zwei Berechtigungssysteme, drei E-Rechnungs-Generatoren, Inventur/Kommissionierung alt/neu, zwei Settings-Datenhaltungen u. a.). Für die SaaS-Neuimplementierung kritisch: ungesalzene SHA1-Passworthashes, hartkodierte Secrets (AES-Fallback, finAPI), fehlende datenraumtrennende Mandantenfähigkeit, keine Schreibsperre für festgeschriebene Rechnungen, sowie fünf als Hypothese dokumentierte Verdachtsfälle nur clientseitiger Rechteprüfung.\n\nZwei Hinweise zur Durchführung: Zwei Analyse-Agenten brachen unterwegs an API-Fehlern ab und wurden mit erhaltenem Kontext erfolgreich fortgesetzt; da Shell-Schreibzugriffe auf das Ausgabeverzeichnis von der Rechtekonfiguration verweigert wurden, erfolgte die Zusammenführung der großen Dateien über Subagenten mit dem Write-Tool (jeweils byteidentisch gegen die Quellkonkatenation verifiziert). Die Codebasis selbst wurde ausschließlich gelesen.","ttft_ms":5456,"ttft_stream_ms":3850,"time_to_request_ms":10,"type":"result","duration_ms":36521,"uuid":"466ea4d1-f66d-4d0f-9eaf-aefc1a731d26","queued_turn_count":0} diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Stderr.log b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/Stderr.log new file mode 100644 index 00000000..e69de29b diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/_meta/before.txt b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/_meta/before.txt new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/_meta/before.txt @@ -0,0 +1 @@ + diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/_meta/combined_prompt.md b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/_meta/combined_prompt.md new file mode 100644 index 00000000..bc9e7139 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/_meta/combined_prompt.md @@ -0,0 +1,178 @@ +# Versuch 01 - Baseline (Prompt-only) - Iteration 02 + +## Metadaten +- **Versuch:** V1 Baseline (Prompt-only) +- **Iteration:** 02 (erste Überarbeitung nach Auswertung von Iteration 01) +- **Codebasis:** c-entron ERP-Suite (Windows, C#/XAML, MSSQL) +- **Zeitstempel:** 2026-08-26 +- **Vorgänger:** `01_Prompt.md` (SHA-256 `1B0DB06B…3C02FF`), 24 Läufe an Tag 1 +- **Änderungsgrund:** Auswertung der 24 Läufe von Tag 1 über 3.287 erzeugte Anforderungen. Jede Änderung ist an einen gemessenen Befund gekoppelt: + + | Änderung | Auslösender Befund | + |---|---| + | Modulinventar als Pflicht-Vorstufe, Mindestabdeckung je Modul, Vertiefung erst danach | Anforderungszahl schwankte je Lauf zwischen 42 und 325 (Faktor 5,9); 55 bis 60 von rund 85 Modulen blieben unanalysiert; die Modultabellen der Analyseberichte reichten von 0 bis 51 Zeilen | + | Hypothesenpflicht kalibriert, `Hypothesen.md` deckungsgleich mit den Inline-Markierungen | Zwei Läufe meldeten null Hypothesen bei 71 bzw. 148 Anforderungen; der Anteil schwankte zwischen 0 % und 26,2 %; mehrfach wichen Sammeldatei und Inline-Markierungen voneinander ab | + | Primärbeleg muss die durchsetzende Stelle benennen | 45,9 % aller Anforderungen trugen genau einen Beleg; in einem Lauf waren 5 von 31 risikorelevanten Anforderungen weder mit `PRIMÄR` noch als `[HYPOTHESE]` gedeckt | + | Belegpflicht verschärft: ohne Beleg keine Anforderung | Eine Anforderung wurde ohne jeden Beleg geschrieben | + | Konsolidierungsbegriff an einem Beispiel kalibriert | Anteil der Konsolidierungskandidaten schwankte je Lauf zwischen 2,4 % und 35,2 % | + | Eigenes Feld `Qualitätsmerkmal` für die ISO-25010-Zuordnung | Die Zuordnung war gefordert, hatte aber keinen Ablageort: nur 33 von 313 nicht-funktionalen Anforderungen führten sie als eigene Angabe | + | Risikoanforderungen im Konsistenzcheck auflisten | Verstöße gegen die risikobasierte Priorisierung fielen erst in der nachgelagerten Auswertung auf, nicht im Lauf selbst | + + Unverändert bleiben Prüfidee, Tracelinks, Belegklassifikation und das Blockformat: Prüfidee und Tracelinks waren in **allen** 3.287 Anforderungen gesetzt, 78,6 % der Belege waren `PRIMÄR`. + +> Dieser Prompt enthält ausschließlich die **Analyseanweisung** und ist damit unabhängig von einem +> bestimmten Werkzeug oder Modell einsetzbar. Welche Werkzeuge im jeweiligen Lauf zur Verfügung +> stehen und wohin die Ergebnisse geschrieben werden, stellt der Versuchsaufbau beim Start bei. + +--- + +## Prompt + +Du bist ein Requirements Engineer im Reverse Requirements Engineering eines Legacy-ERP-Systems. Erzeuge aus der vorliegenden Codebasis eine Anforderungsspezifikation nach **ISO/IEC/IEEE 29148:2018**. Arbeite ausschließlich auf den im Arbeitsverzeichnis liegenden Artefakten (Quellcode, Konfiguration, UI-Ressourcen, ggf. DB-Skripte). Nutze nur Informationen, die du aus diesen Artefakten gewinnen kannst. + +### Auftrag + +Erzeuge eine konsolidierte Spezifikation auf den drei Ebenen: + +1. **StRS** - Stakeholder Requirements Specification (fachliche Sicht, Akteure, Geschäftsziele) +2. **SyRS** - System Requirements Specification (Systemverhalten, Schnittstellen, Performance-, Sicherheitsanforderungen) +3. **SwRS** - Software Requirements Specification (Komponenten, Datenmodelle, Software-interne Regeln) + +Ziel ist eine Spezifikation, die als belastbare Basis für eine Web-/SaaS-Neuimplementierung dienen kann. + +### Scope (Schritt 1 der RRE-Methodenkette, manuell vorgegeben) + +Der Untersuchungsgegenstand ist die **gesamte Codebasis** im Arbeitsverzeichnis. Es gilt bewusst keine Modulbeschränkung: Alle Module, Datenobjekte und Prozesse sind gleichrangig zu erfassen. + +**Breite geht vor Tiefe.** Ein fehlendes Requirement führt bei einer Neuimplementierung zu Funktionsverlust; eine oberflächlich erfasste Funktion lässt sich dagegen nachschärfen. Erfasse deshalb zuerst die gesamte Breite und vertiefe erst danach. Halte dich an die Reihenfolge aus dem Abschnitt **Vorgehen**: erst Inventar, dann Mindestabdeckung, dann Vertiefung. + +### Vorgehen (statische Analyse, keine Ausführung) + +Bearbeite die Schritte 2-6 der RRE-Methodenkette (Schritt 1 Scope ist oben vorgegeben, Schritt 7 Validierung erfolgt manuell durch Fachexperten). Vorgeschaltet ist eine verbindliche Inventarisierung: + +**Schritt 0 - Modulinventar (vor der ersten Anforderung).** Verschaffe dir zuerst einen vollständigen Überblick über den Untersuchungsgegenstand und lege ihn im `Analysebericht.md` als Tabelle ab: fachliches Modul beziehungsweise Komponente, Pfad im Arbeitsverzeichnis, ein Satz zur fachlichen Aufgabe. Das Inventar wird erstellt, **bevor** die erste Anforderung formuliert wird. Es ist die Bezugsgröße für die Abdeckung und darf später ergänzt, aber nicht gekürzt werden. + +**Schritt 0b - Mindestabdeckung.** Jedes Modul des Inventars erhält **mindestens eine** Anforderung, bevor irgendein Modul vertieft wird. Lässt sich für ein Modul keine belegbare Anforderung bilden, führe es im Inventar als `nicht analysiert` mit einer kurzen Begründung. Ein Modul ohne Anforderung und ohne Begründung ist unzulässig. + +**Schritt 0c - Vertiefung nach Risiko.** Erst wenn die Mindestabdeckung steht, vertiefe einzelne Module. Beginne dort, wo Sicherheitsregeln, Abrechnungs- und Fakturierungslogik oder Berechtigungsprüfungen liegen. + +2. **Artefakterhebung:** Erfasse Quellcode, Konfiguration, UI-Texte, Datenbankschemata, Schnittstellenbeschreibungen sowie Change-Historie und Projektartefakte (Commit-Messages, Tickets, Release Notes, Migrationsnotizen), soweit als Datei lesbar. +3. **Technische Analyse:** Identifiziere Module, Komponenten, Abhängigkeiten, Statusmaschinen, Validierungslogik, Berechtigungsprüfungen. +4. **Semantische Interpretation:** Leite fachliche Aussagen aus technischen Implementierungen ab (z. B. Statusübergänge → Geschäftsregel). +5. **Formalisierung:** Überführe die Aussagen in klare, testbare Anforderungen mit Kontext, Vorbedingung und Ergebnis. +6. **Traceability-Anreicherung:** Verknüpfe jede Anforderung mit konkreten Artefaktbelegen. + +### Pflicht-Eigenschaften jeder Anforderung + +- **Belegpflicht:** Jede Anforderung **muss** mindestens einen konkreten Artefaktbeleg führen (Dateipfad, Klasse/Methode, SQL-Statement, UI-String, Konfigurationseintrag). Jeder Beleg erhält eine kurze Begründung, warum er die Aussage trägt. Lässt sich eine Aussage nicht belegen, **schreibe die Anforderung nicht** - erfasse den offenen Punkt stattdessen als Hypothese. Eine Anforderung ohne Beleg ist unter keinen Umständen zulässig. +- **Trennung von Fakt und Interpretation:** Die belegte technische Beobachtung (Feld `Fakt`) wird getrennt von der fachlichen Interpretation (Feld `Aussage`) dokumentiert, damit nachvollziehbar bleibt, was im Artefakt steht und was daraus geschlossen wurde. +- **Risikobasierte Priorisierung:** Anforderungen zu Sicherheitsregeln, Abrechnungs-/Fakturierungslogik und Berechtigungen unterliegen strengeren Evidenzanforderungen: Sie benötigen mindestens einen `PRIMÄR`-Beleg, andernfalls sind sie zwingend als `[HYPOTHESE]` zu kennzeichnen. Ein `PRIMÄR`-Beleg benennt hier die **durchsetzende Stelle** - Datei, Klasse, Methode und die konkrete Prüfung, Bedingung oder das Constraint. Ein Verweis auf eine Datei ohne Angabe der prüfenden Stelle genügt für diese Anforderungen nicht. +- **Belegklassifikation:** Kennzeichne jeden Beleg als + - `PRIMÄR` (durchgesetzte Regel im Code oder DB-Constraint), + - `SEKUNDÄR` (UI-Label, Fehlermeldung, Reportlayout, Mappingtabelle, Konfigurationsschalter), + - `KONTEXT` (Kommentar, Commit-Message, Ticketreferenz). +- **Hypothesenmarkierung:** Aussagen, die sich nicht eindeutig aus Artefakten ableiten lassen, kennzeichnest du explizit mit `[HYPOTHESE]` und einer kurzen Begründung, welche Information zur Bestätigung fehlt. Bei einer Codebasis dieser Größe ist eine Analyse ohne jeden offenen Punkt unplausibel: Führst du keine einzige Hypothese, begründe das ausdrücklich in der Selbstbewertung. Umgekehrt ist eine hohe Hypothesenzahl kein Mangel, sondern ein Hinweis auf ehrliche Abgrenzung. +- **Verifizierbarkeit:** Jede Anforderung enthält mindestens eine Prüfidee oder ein Akzeptanzkriterium. +- **Eindeutigkeit:** Vermeide vage Begriffe ("schnell", "benutzerfreundlich"); definiere domänenspezifische Begriffe beim ersten Auftreten. +- **Übernahmewürdigkeit:** Beurteile für jede Anforderung, ob ihre Funktion im Zielsystem erhalten bleiben soll. Unterscheide `übernehmen` (fachlich weiterhin erforderlich), `Workaround` (historisch gewachsene Behelfslösung), `Sonderfall` (Ausnahme für einen einzelnen Kunden, Mandanten oder Altbestand) und `veraltet` (durch neuere Logik abgelöst oder fachlich überholt). Begründe die Einstufung in einem Halbsatz. Diese Angabe steuert die spätere fachliche Priorisierung; eine Fehleinschätzung ist unkritisch, eine fehlende Angabe nicht. +- **Redundanzfreiheit:** Formuliere jede Anforderung so, dass sie von den übrigen klar abgegrenzt ist. Beschreiben zwei Anforderungen dieselbe fachliche Funktion aus unterschiedlicher Perspektive, führe sie zusammen oder grenze sie im Titel und in der Aussage ausdrücklich gegeneinander ab. + +### Formatvorgabe pro Anforderung + +``` +ID: - +Titel: +Ebene: +Typ: +Qualitätsmerkmal: +Akteur: +Vorbedingung: +Fakt: +Aussage: Das System soll <...>. (fachliche Interpretation als klare Soll-Aussage) +Ergebnis: +Belege: + - [PRIMÄR] - Begründung: + - [SEKUNDÄR] <...> - Begründung: <...> + - [KONTEXT] <...> - Begründung: <...> +Prüfidee: +Tracelinks: +Konsolidierung: > +Übernahmewürdigkeit: <übernehmen | Workaround | Sonderfall | veraltet> - +Status: +``` + +### Traceability + +Stelle Forward- und Backward-Traceability zwischen den drei Ebenen her: +- Jede SwRS-Anforderung referenziert die zugehörige SyRS-Anforderung. +- Jede SyRS-Anforderung referenziert die zugehörige StRS-Anforderung. +- Erzeuge zusätzlich eine konsolidierte **Traceability-Tabelle** (Markdown oder CSV): `StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg`. + +### Nicht-funktionale Anforderungen + +- Ordne nicht-funktionale Anforderungen den Qualitätsmerkmalen der **ISO/IEC 25010** zu (z. B. Zuverlässigkeit, Performance-Effizienz, Sicherheit, Wartbarkeit, Übertragbarkeit). Trage die Zuordnung in das dafür vorgesehene Feld `Qualitätsmerkmal` ein, nicht in das Feld `Typ`. +- Leite Betriebs- und Sicherheitsanforderungen gezielt auch aus indirekt sichtbaren Artefakten ab: Konfigurationen, Deployment-Skripte, Logging-Policies, Rechteprüfungen. + +### Konsolidierungsbedarf + +Die Codebasis enthält fachliche Redundanz: Dieselbe Anforderung kann auf unterschiedlichen Masken oder in unterschiedlichen Modulen mehrfach und teils unterschiedlich implementiert sein. Prüfe daher bei jeder Anforderung, ob andere Anforderungen dieselbe fachliche Funktion abbilden, und vermerke solche Fälle im Feld `Konsolidierung` als Kandidat für eine Zusammenführung im Zielsystem. + +**Gemeint sind fachlich gleichartige Konzepte in getrennten Implementierungen**, nicht bloß ähnlich formulierte Anforderungen. Ein Beispiel aus dieser Codebasis: Drucker werden als „Stammblätter" geführt, sonstige Hardware getrennt davon als „Assets" - zwei Datenhaltungen für denselben fachlichen Gegenstand, die im Zielsystem zu einem Asset-Konzept zusammengeführt werden sollen. Zwei Anforderungen, die denselben Sachverhalt nur aus Sicht verschiedener Ebenen beschreiben (etwa StRS und SwRS), sind **kein** Konsolidierungsfall - dafür sind die Tracelinks da. + +### Ergebnisstruktur (im vorgegebenen Ausgabeverzeichnis) + +``` +Ergebnisse/ + StRS.md + SyRS.md + SwRS.md + Traceability.md (oder Traceability.csv) + Hypothesen.md (Sammlung aller mit [HYPOTHESE] markierten Aussagen mit offener Frage) + Glossar.md (Domänenbegriffe, die in den Anforderungen verwendet werden) + Analysebericht.md (Modulinventar aus Schritt 0, Abdeckungstabelle, Konsistenzcheck, + Selbstbewertung, bekannte Lücken) +``` + +Das Ausgabeverzeichnis wird beim Start des Laufs beigestellt. Die analysierte Codebasis wird ausschließlich gelesen und nicht verändert. + +### Randbedingungen + +- **Keine Halluzinationen.** Wenn ein Artefakt nicht gelesen oder eine Aussage nicht belegt werden kann, ist das offen zu legen, nicht zu erfinden. +- **Keine Generierung von Code.** Es sollen ausschließlich Spezifikationsartefakte entstehen. +- **Keine Annahme über nicht beigestellte Hilfsmittel.** Arbeite mit dem, was dir in diesem Lauf zur Verfügung steht. Setze keine zusätzlichen Analysewerkzeuge, Datenbankzugriffe oder laufende Systeme voraus. Stehen für eine Aussage nur indirekte Belege zur Verfügung, ist sie als `[HYPOTHESE]` zu kennzeichnen. +- **Migrationsperspektive berücksichtigen.** Erkennbare Workarounds, Sonderfälle und überholte Logik gehören in das Feld `Übernahmewürdigkeit`, nicht in das Feld `Status`. `Status` beschreibt ausschließlich die Belegsituation (`belegt` oder `HYPOTHESE`), `Übernahmewürdigkeit` die fachliche Zukunft der Anforderung. Beide Angaben sind unabhängig voneinander: Eine gut belegte Anforderung kann ein Workaround sein, eine Hypothese kann übernahmewürdig sein. +- **Sprache:** Deutsch für Anforderungsaussagen, technische Bezeichner (Klassen, Methoden, Spalten) bleiben in ihrer Originalsprache. + +### Abschluss + +Führe vor Abgabe einen **Konsistenzcheck über das gesamte Anforderungs-Set** durch und dokumentiere das Ergebnis im `Analysebericht.md`: +- Doppelte oder mehrfach vergebene IDs +- Anforderungen ohne Beleg +- Anforderungen ohne Angabe zur `Übernahmewürdigkeit` +- Tracelinks auf nicht existierende IDs +- Inhaltlich deckungsgleiche Anforderungen, die nicht als Konsolidierungskandidat markiert sind +- **Liste aller risikorelevanten Anforderungen** (Sicherheit, Abrechnung/Fakturierung, Berechtigungen) mit ihrer Belegsituation: ID, Titel, ob ein `PRIMÄR`-Beleg vorliegt, andernfalls die `[HYPOTHESE]`-Kennzeichnung. Diese Liste macht Verstöße gegen die risikobasierte Priorisierung im Lauf selbst sichtbar. +- **Abgleich `Hypothesen.md` gegen die Inline-Markierungen:** Beide müssen dieselben Anforderungen nennen. `Hypothesen.md` enthält genau die Anforderungen mit `[HYPOTHESE]`-Markierung und keine zusätzlichen freien Fragen; offene Punkte ohne zugehörige Anforderung gehören in die Selbstbewertung. + +Erstelle außerdem die **Abdeckungstabelle** auf Basis des Modulinventars aus Schritt 0: je Modul die Einstufung `tief | mittel | flach | nicht analysiert` und die Anzahl der daraus erzeugten Anforderungen. Jede Zeile des Inventars muss in der Abdeckungstabelle auftauchen. + +Beende den Lauf mit einer kurzen Selbstbewertung im `Analysebericht.md`: +- Wie viele Module des Inventars wurden tief, mittel, flach beziehungsweise gar nicht analysiert? Nenne absolute Zahlen, nicht nur Beispiele. +- Wurde die Mindestabdeckung erreicht, also hat jedes Modul mindestens eine Anforderung? Falls nein: welche Module fehlen und warum? +- An welchen Stellen war der Beleg dünn (hoher Anteil `SEKUNDÄR`/`KONTEXT` oder `[HYPOTHESE]`)? +- Falls keine einzige Hypothese geführt wurde: Begründung, warum die Analyse ohne offene Punkte auskommt. +- Welche Erkenntnisse legen einen Nachschlag in einer Folge-Iteration nahe? + +--- + +### Werkzeugkontext (vom Versuchsaufbau vorgegeben) +Für diesen Lauf stehen zur Verfügung: Lesen und Suchen von Dateien, das Ausführen von +Kommandozeilenbefehlen im Arbeitsverzeichnis sowie die werkzeugeigenen Subagenten. +Nicht verfügbar sind: spezialisierte Agentenrollen aus Konfigurationsdateien, externe +Werkzeugserver. +Triff keine Annahmen über weitere Werkzeuge und versuche nicht, nicht verfügbare +Werkzeuge zu ersetzen. +### Ausgabeverzeichnis (überschreibt anderslautende Pfadangaben oben) +Schreibe ALLE zu erzeugenden Ergebnisdateien in das Verzeichnis +`c:\DEV\MasterArbeit\Versuche\Versuch_01\Iteration 3\claude-fable-5\builtin\high\02_Lauf_2026-08-27_095953_v7.0.0-6ce6\Ergebnisse\`. +Verändere keine Dateien im Arbeitsverzeichnis (der analysierten Codebasis). diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/_meta/endzeit.txt b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/_meta/endzeit.txt new file mode 100644 index 00000000..8f45c222 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/_meta/endzeit.txt @@ -0,0 +1 @@ +2026-08-27T11:09:58.0288148+02:00 diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/_meta/startzeit.txt b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/_meta/startzeit.txt new file mode 100644 index 00000000..011ef708 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/builtin/high/02_Lauf_2026-08-27_095953_v7.0.0-6ce6/_meta/startzeit.txt @@ -0,0 +1 @@ +2026-08-27T09:59:53.7439250+02:00 diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/Analysebericht.md b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/Analysebericht.md new file mode 100644 index 00000000..1a1b72c3 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/Analysebericht.md @@ -0,0 +1,606 @@ +# Analysebericht – Reverse Requirements Engineering c-entron ERP-Suite + +**Lauf:** 02_Lauf_2026-08-27_081235_v7.0.0-3021 +**Codebasis:** `C:\DEV\MasterArbeit\QuellCode\CentronERP` (nur lesend analysiert) +**Methode:** Statische Analyse (RRE-Schritte 0, 2–6), keine Ausführung +**Datum:** 2026-08-27 + +--- + +## Kennzahlen der Codebasis (erhoben in Schritt 0) + +| Kennzahl | Wert | Quelle | +|---|---|---| +| C#-Dateien (src, ohne bin/obj) | ~14.200 | Verzeichniszählung `src/**`.cs | +| Projekte in `Centron.sln` | 46 Code-Projekte (+ Setup/Doku-Ordner) | `Centron.sln` | +| DB-Tabellen | 1.558 `CREATE TABLE` | `SSMS_DB_SCHEMA.sql` | +| DB-Views | 182 `CREATE VIEW` | `SSMS_DB_SCHEMA.sql` | +| FK-Constraints | 134 | `SSMS_DB_SCHEMA.sql` | +| CHECK-Constraints | 330 | `SSMS_DB_SCHEMA.sql` | +| Benutzerrechte (Konstanten) | 750 `public const int` | `src/webservice/Centron.WebServices.Core/EntitiesWrongPlace/Administration/Rights/UserRightsConst.cs` | + +Architektur-Grobbild (aus `docs/getting-started/general-structure.md` und Verzeichnisstruktur): +WPF-Client (`src/centron`) und Blazor-Web-Client „Nexus" (`src/nexus`) greifen über ein +`ILogic`-Muster wahlweise direkt (BLLogic → NHibernate → MSSQL) oder über den Webservice +(WSLogic → `src/webservice`) auf die Geschäftslogik (`src/backend/Centron.BL`) zu. +Belege werden dual gehalten: deutsche Legacy-Tabellen (`AngKopf`/`AngPos` …) mit englischen Views +(`Offers`/`OfferItems` …) darüber. + +--- + +## Schritt 0 – Modulinventar + +Das Inventar wurde **vor** der ersten Anforderung erstellt. Bezugsgröße für Mindestabdeckung +und Abdeckungstabelle. Granularität: fachliches Modul bzw. abgrenzbare Komponente. +Pfade relativ zum Arbeitsverzeichnis; `BL/` steht für `src/backend/Centron.BL/`. + +### A. Vertrieb / Belegwesen + +| Nr. | Modul | Pfad | Fachliche Aufgabe | +|---|---|---|---| +| M01 | Angebote | `BL/Sales/Receipts/Offers`, Tabellen `AngKopf`/`AngPos` | Erstellen und Verwalten von Angeboten an Kunden. | +| M02 | Aufträge | `BL/Sales/Receipts/Orders`, `AufKopf`/`AufPos` | Auftragsverwaltung inkl. Auftragsstatus und Folgebelegen. | +| M03 | Lieferscheine | `BL/Sales/Receipts/DeliveryLists`, `LiefKopf`/`LiefPos` | Lieferscheinerstellung und Lieferabwicklung. | +| M04 | Rechnungen | `BL/Sales/Receipts/Invoices`, `RechKopf`/`RechPos` | Fakturierung, Rechnungsstatus, Zahlungsreferenzen. | +| M05 | Gutschriften | `BL/Sales/Receipts/CreditVouchers`, `GutKopf`/`GutPos` | Gutschriftenerstellung zu Rechnungen/Retouren. | +| M06 | Abhollisten | `BL/Sales/Receipts/PickupLists`, `AbholKopf`/`AbholPos` | Abholaufträge für Geräte/Waren beim Kunden. | +| M07 | Verträge (Beleg) | `BL/Sales/Receipts/ContractLists`, `VertragKopf`/`VertragPos` | Wiederkehrende Leistungsverträge als Belegart mit Abrechnungsintervallen. | +| M08 | Automatische Fakturierung | `BL/Sales/CustomerAssets/AutomaticFactura` | Automatische Rechnungserzeugung aus Verträgen, Kontingent- und Klickabrechnung. | +| M09 | Zeitenabrechnung | `BL/Sales/CustomerAssets/TimerBilling` | Abrechnung erfasster Helpdesk-/Servicezeiten in Belege. | +| M10 | Anzahlungen | `BL/Sales/Receipts/DownPayment` | Anzahlungsrechnungen und deren Verrechnung. | +| M11 | Projekte (Beleg/PM) | `BL/Sales/Receipts/Projects`, `BL/Projects` | Projektverwaltung mit Belegzuordnung. | +| M12 | Leasing & Service | `BL/Sales/Receipts/LeasingAndService` | Leasing-/Serviceabwicklung zu Belegen. | +| M13 | Aktionspreise | `docs/reference/receipts/actionprice-system.md`, ActionPrice-Klassen | Zeitlich begrenzte Aktionsverkaufspreise je Artikel/Kunde. | +| M14 | Artikelsuche im Beleg | `BL/Sales/Receipts/ArticleSearch` | Artikel-/Preisfindung beim Belegerfassen. | +| M15 | Kassenbuch | `BL/Sales/CashBooks` | Kassenbuchführung mit Belegen und Salden. | +| M16 | Sonderpreise | `BL/Accounts/SpecialPrices` | Kundenindividuelle Preise (auch Quelle des WebCart-Sortiments). | +| M17 | Stammblätter (Geräteabrechnung) | `Centron.Entities/Entities/Sales/Receipts/MasterDataLists` | Gerätestammblätter mit Seriennummer, Zählern, Vertrags- und Rechnungsbezug. | +| M18 | Schweiz-Besonderheiten | `BL/Sales/Receipts/Switzerland` | Länderspezifische Beleglogik Schweiz (z. B. Rundung, MwSt). | +| M19 | Belegversionierung | `*KopfVersions`/`*PosVersions`-Tabellen, `AssetHeadDAO` | Versionsstände aller Belegarten für Audit-Trail. | +| M20 | Nummernkreise | `BL/Administration/Company/NumberGroupBL.cs` | Vergabe eindeutiger Beleg-/Stammdatennummern je Mandant/Filiale. | +| M21 | Belegdruck/-versand (Mailvorlagen) | `BL/Sales/Receipts` (ReceiptBL Druck/Mail), `BL/Mail/Templates` | Erzeugen, Drucken und Mailen von Belegdokumenten. | + +### B. Einkauf + +| Nr. | Modul | Pfad | Fachliche Aufgabe | +|---|---|---|---| +| M22 | Lieferantenbestellungen | `BL/Sales/Receipts/SupplierOrders` | Bestellungen an Lieferanten/Distributoren. | +| M23 | Lieferantenrechnungen | `BL/Sales/Receipts/SupplierInvoices` | Eingangsrechnungserfassung und -prüfung. | +| M24 | Lieferantenlieferscheine | `BL/Sales/Receipts/SupplierDeliveryLists` | Wareneingang auf Basis Lieferantenlieferscheinen. | +| M25 | Lieferantengutschriften | `BL/Sales/Receipts/SupplierCreditVouchers` | Gutschriften von Lieferanten. | +| M26 | Lieferantenbelegdokumente | `BL/Sales/Receipts/SupplierReceiptDocuments` | Dokumente/Anhänge zu Einkaufsbelegen. | +| M27 | Bestellvorschläge | `BL/Purchasing/OrderSuggestionList` | Bestellvorschlagsermittlung aus Bedarf/Beständen. | +| M28 | Lieferanten-/Distributorenstamm | `BL/Purchasing/Suppliers`, `BL/Buying/DistributorBL.cs`, `BL/BusinessPartner` | Verwaltung von Lieferanten und Distributoren. | + +### C. Kunden / CRM + +| Nr. | Modul | Pfad | Fachliche Aufgabe | +|---|---|---|---| +| M29 | Adress-/Kundenstamm | `BL/Accounts/AccountBL.cs`, `BL/CustomerArea`, Tabellen `Accounts`/`AccountCustomers`/`Kunden` | Zentrale Verwaltung von Accounts (Kunden, Lieferanten, Interessenten) mit Adressen. | +| M30 | Ansprechpartner & Adressen | `BL/Sales/Customers/Addresses` | Kontaktpersonen und Adressverwaltung zu Accounts. | +| M31 | Aktivitäten | `BL/Accounts/Activities` | Protokollierung von Kundenaktivitäten (Anrufe, Mails, Belege). | +| M32 | Kampagnen | `BL/Accounts/Campaigns` | Marketingkampagnen mit Zielgruppen. | +| M33 | Marketing/Mailings | `BL/Sales/Marketing`, `BL/Mailings` | Serienmails/Mailings an Kundengruppen. | +| M34 | Umfragen | `BL/Accounts/Survey` | Kundenumfragen inkl. Versand nach Ticketabschluss. | +| M35 | CRM-Projekte | `BL/Sales/Customers/CrmProjects` | Vertriebschancen/CRM-Projekte. | +| M36 | Hotline | `BL/Accounts/HotlineArea` | Hotline-Konditionen je Kunde. | +| M37 | Kundenvereinbarungen | `BL/Accounts/AccountContracts` | Rahmenvereinbarungen je Account. | + +### D. Service / Helpdesk + +| Nr. | Modul | Pfad | Fachliche Aufgabe | +|---|---|---|---| +| M38 | Helpdesk/Tickets | `BL/Sales/Support/HelpdeskBL.cs` u. a. | Ticketverwaltung (Anlage, Bearbeitung, Status, Kategorien). | +| M39 | Eskalationsmanagement | `BL/Sales/Support/EscalationBL.cs` | Eskalationsregeln und Fälligkeiten auf Tickets. | +| M40 | Ticket-Zeiterfassung | `BL/Sales/Support/HelpdeskTimer*.cs` | Zeiterfassung auf Tickets inkl. Unterschrift und Artikelbuchung. | +| M41 | Checklisten | `BL/CheckListArea` | Checklistenvorlagen und -abarbeitung (v. a. auf Tickets). | +| M42 | Ticketvorlagen (C-FLOW) | `BL/Sales/Support/HelpdeskPatternBL.cs`, `HelpdeskCreationTemplateBL.cs` | Vorlagen zur automatischen Ticketerzeugung. | +| M43 | Taskmanagement | `BL/TaskManager` | Aufgabensteuerung mit Aktionen auf Tickets. | +| M44 | Ticketprojekte | `BL/TicketProjects` | Bündelung von Tickets zu Projekten. | +| M45 | RMA | `BL/CustomerArea/RmaBL.cs`, Tabelle `Rma` | Retouren-/Reparaturabwicklung zu Tickets. | +| M46 | Externes Helpdesk | `BL/ExternalHelpdesk` | Anbindung fremder Ticketsysteme. | +| M47 | Terminanfragen | `BL/AppointmentRequests` | Terminanfragen an Kunden (z. B. aus Tickets). | +| M48 | ToDos | `BL/ToDoArea` | Persönliche/ticketbezogene Aufgabenlisten. | + +### E. Geräte / Assets / MSP + +| Nr. | Modul | Pfad | Fachliche Aufgabe | +|---|---|---|---| +| M49 | Kundengeräte | `BL/Devices/AccountDeviceBL.cs`, `BL/Sales/CustomerAssets` | Verwaltung der beim Kunden stehenden Geräte. | +| M50 | DocuBoard/Assetmanagement | `BL/DocuBoard`, Tabellen `AssetManagement*` | IT-Dokumentation/Inventarisierung (AD-Scans, SNMP, Partner). | +| M51 | RMM-Datenimport | `BL/DataExchange/Rmm` | Import von Monitoring-/RMM-Daten für Abrechnung. | +| M52 | MSP-Abrechnung | `BL/Statistics/MspCollectors` | Sammler und Auswertung nutzungsbasierter MSP-Leistungen. | + +### F. Lager / Logistik / Produktion + +| Nr. | Modul | Pfad | Fachliche Aufgabe | +|---|---|---|---| +| M53 | Artikelstamm | `BL/Warehousing/ArticleBL.cs`, `BL/Warehousing/ArticleManagement` | Artikelverwaltung inkl. Preisen, Herstellern, EAN. | +| M54 | Lager/Bestände | `BL/Warehousing/StockManagement`, `BL/Storage` | Lagerorte, Bestandsführung, Umbuchungen. | +| M55 | Inventur | `BL/Warehousing/InventoryManagement` | Inventurdurchführung und Bestandskorrektur. | +| M56 | Kommissionierung | `BL/Warehousing/CommissioningManagement`, `Commissions` | Kommissionieren von Aufträgen. | +| M57 | Seriennummern/Barcodes | `Centron.Entities/Entities/Warehousing/SerialNumber.cs`, `BarCode.cs` | Serialisierte Bestandsführung und Barcodestatus. | +| M58 | Produktion | `BL/Production`, `BL/Warehousing/ArticleProduction` | Fertigungsaufträge und Stücklistenproduktion. | +| M59 | Versand GLS | `src/apis/Centron.Api.Gls` | Paketversand über GLS-API. | +| M60 | Versand Shipcloud | `src/apis/Centron.Api.Shipcloud` | Paketversand über Shipcloud-API. | + +### G. Finanzen + +| Nr. | Modul | Pfad | Fachliche Aufgabe | +|---|---|---|---| +| M61 | Zahlungseingänge | `BL/Finances/IncomingPayments` | Erfassung/Zuordnung von Zahlungseingängen zu Rechnungen. | +| M62 | Onlinebanking | `BL/Finances/OnlineBanking`, `src/apis/Centron.APIs.FinAPI` | Kontoumsatzabruf über finAPI und Transaktionszuordnung. | +| M63 | Zahlungsverkehr/SEPA | `BL/Finances/Payments`, Mandate (`MandatI3D`) | Lastschrift-/Zahlungsläufe mit SEPA-Mandaten. | +| M64 | Mahnwesen | `BL/Sales/Receipts/Invoices/Dunning` | Mahnläufe mit Mahnstufen und Mahnsperren. | +| M65 | OPOS | `BL/Sales/Receipts/Invoices/Opos` | Offene-Posten-Verwaltung. | +| M66 | Buchhaltungsexport | `BL/DataExchange/BookKeeping`, `Centron.Gateway/DataExchange/BookKeeping` | Export an DATEV, Sage, Schilling u. a. | +| M67 | Bankkonten | `BL/Accounting/BankAccountBL.cs` | Bankverbindungen von Accounts. | +| M68 | Kreditlimit/Bonität | `ReceiptBL` (Kreditlimitprüfung) | Kreditlimitprüfung bei Belegerstellung. | + +### H. Administration / System + +| Nr. | Modul | Pfad | Fachliche Aufgabe | +|---|---|---|---| +| M69 | Benutzer & Login | `BL/Administration/Logins` | Benutzerkonten, Authentifizierung (Basic/AD/Entra ID), Sitzungstickets. | +| M70 | Rechteverwaltung | `BL/Administration/Rights`, Tabellen `Sichbenu`/`Sichmemb`/`Sichtrus` | Gruppenbasierte Rechtevergabe mit 750 Einzelrechten. | +| M71 | Zwei-Faktor-Authentifizierung | `BL/Administration/Logins/TwoFactor` | 2FA per E-Mail oder RADIUS. | +| M72 | Lizenzierung | `BL/Administration/Licensing`, `docs/reference/security/licensing-system.md` | GUID-basierte Produkt-/Featurelizenzen mit Anzahl und Ablauf. | +| M73 | Mandanten/Filialen | `BL/Administration/Company`, `BL/Administration/Mandatory` | Mandanten-, Firmen- und Filialverwaltung. | +| M74 | Mitarbeiterverwaltung | `BL/Administration/Employees`, `BL/EmployeeArea` | Mitarbeiterstamm, Abteilungen, Teams. | +| M75 | Einstellungen | `BL/Administration/Settings` | Zentrale Anwendungseinstellungen (`ApplicationSettingID`). | +| M76 | Datensicherheit/DSGVO | `BL/Administration/DataSecurity` | Datenschutzfunktionen (Anonymisierung/Löschkonzept). | +| M77 | DB-Skripte/Migration | `BL/Administration/Scripts`, `docs/guides/database` | Nummerierte SQL-Migrationsskripte mit Versionierung. | +| M78 | Hintergrunddienste | `BL/Administration/BackgroundServices`, `docs/Background Service` | Zeitgesteuerte Dienste (z. B. DataQualityService). | +| M79 | Telemetrie/Profiling | `BL/Telemetry`, `BL/Administration/Profiling` | Nutzungs-/Leistungsdaten. | +| M80 | Access Tokens | `BL/Administration/AccessTokens` | API-Zugriffstoken für Fremdzugriffe. | +| M81 | Passwortmanager | `BL/PasswordManagementArea`, `BL/PasswordManager` | Verwaltung von Kundenpasswörtern/Zugangsdaten. | +| M82 | Anpassungen/CustomTables | `BL/Customizations/CustomTables` | Kundenindividuelle Zusatztabellen/-felder. | +| M83 | Massenupdate | `BL/MassUpdate` | Massenänderung von Stammdaten. | +| M84 | GUI-Profile | `BL/GUI/Profiles` | Benutzer-/Rollenprofile für Oberflächenlayouts. | + +### I. Kommunikation + +| Nr. | Modul | Pfad | Fachliche Aufgabe | +|---|---|---|---| +| M85 | E-Mail & Vorlagen | `BL/Mail` | Mailversand, Vorlagen mit Variablenersetzung, Blacklist. | +| M86 | Exchange-Sync | `BL/Mail/Exchange`, `docs/features/exchange-sync-bugprotokoll.md` | Synchronisation von Mails/Terminen mit Exchange. | +| M87 | MailScanner | `BL/MailScanner` | Automatische Ticketerzeugung/Zuordnung aus Postfächern. | +| M88 | TAPI/Telefonie | `BL/Tapi/PhoneCallBL.cs`, `docs/reference/architecture/tapi.md` | Anrufsignalisierung und Anruferkennung. | +| M89 | Kalender | `BL/Sales/Calendar`, `BL/Calendar` | Terminkalender der Mitarbeiter. | +| M90 | Chats | `BL/Chats` | Interne Chatfunktion. | +| M91 | Outlook-Add-In | `src/nexus/CentronNexus.OutlookAddIn` | Ticket-/Kundenbezug direkt aus Outlook. | +| M92 | Benachrichtigungen | `BL/Notifications`, `BL/NexusNotifications` | Systembenachrichtigungen an Benutzer (Client und Web). | + +### J. Datenaustausch / Schnittstellen + +| Nr. | Modul | Pfad | Fachliche Aufgabe | +|---|---|---|---| +| M93 | EDI-Framework | `BL/EDI`, `docs/reference/edi` | Elektronischer Belegaustausch mit Distributoren (ALSO, Alltron, Komsa …). | +| M94 | ZUGFeRD/XRechnung | `BL/EDI/Zugferd`, `docs/guides/development/xrechnung.md`, `docs/reference/zugferd-*.md` | Strukturierte E-Rechnung (Erzeugung/Einlesen). | +| M95 | ebInterface | `src/apis/Centron.Api.EbInterface` | Österreichisches E-Rechnungsformat. | +| M96 | docuFORM | `Centron.Api.docuFORM` | Zählerstands-/Gerätedaten von docuFORM. | +| M97 | Icecat | `src/apis/Centron.APIs.IcecatDataAccess` | Artikelstammdaten-Anreicherung aus Icecat. | +| M98 | ITscope | `src/apis/Centron.APIs.ITscopeDataAccess` | Produkt-/Preisdaten und Bestellungen über ITscope. | +| M99 | COP | `src/apis/Centron.APIs.CopDataAccess` | COP-Datenzugriff (Herstellerdaten/Servicedaten). | +| M100 | EGIS | `src/apis/Centron.APIs.EgisDataAccess`, `BL/EDI/EGIS` | EGIS-Warenkorb/Bestellübertragung. | +| M101 | Telekom Dive | `BL/DataExchange/TelekomDive` | Telekom-Dive-Schnittstelle. | +| M102 | TANSS | `BL/DataExchange/TanssInterfaces` | Übernahme aus TANSS-Ticketsystem. | +| M103 | GFK-Export | `BL/DataExchange/GfkExport` | Absatzmeldung an GfK. | +| M104 | Datenimport allgemein | `BL/DataExchange/Import` | Generischer Datenimport (CSV u. a.). | +| M105 | Connectors | `BL/DataExchange/Connectors`, `BL/Services/CTimeConnectors` | Konnektoren zu Drittsystemen (u. a. c-time). | + +### K. Auswertung / Suche + +| Nr. | Modul | Pfad | Fachliche Aufgabe | +|---|---|---|---| +| M106 | ReportEngine | `BL/ReportEngine` | Reportvorlagen, PDF-Erzeugung, Belegdruckstrategien. | +| M107 | Statistiken | `BL/Statistics` | Umsatz-, Auftrags-, Ticket- und Vertragsstatistiken. | +| M108 | Indexsuche | `BL/IndexSearch` | Volltextsuche (Lucene) über Accounts und Tickets. | + +### L. Web (c-entron Nexus) und Webservice + +| Nr. | Modul | Pfad | Fachliche Aufgabe | +|---|---|---|---| +| M109 | Nexus-Rahmen | `src/nexus/CentronNexus`, `CentronNexus.Host` | Blazor-Webanwendung (Login, Navigation, Hosting). | +| M110 | ServiceBoard | `src/nexus/CentronNexus/ServiceBoard` | Web-Ticketboard für Techniker/Kunden. | +| M111 | WebCart | `src/nexus/CentronNexus/WebCart` | Webshop für Endkunden auf Basis Sonderpreisen. | +| M112 | WebOffer | `src/nexus/CentronNexus/WebOffer` | Online-Angebotsansicht/-freigabe durch Kunden. | +| M113 | Dokumentensignierung | `src/nexus/CentronNexus/DocumentSigning` | Digitale Unterschrift von Dokumenten im Web. | +| M114 | Produktionsaufträge Web | `src/nexus/CentronNexus/ProductionOrderManagement` | Web-Sicht auf Fertigungsaufträge. | +| M115 | SelfCare | `BL/SelfCare` | Selbstbedienungsseiten für Endkunden (Web-Anfragen). | +| M116 | Web-Accounts/WebSuite | `BL/Administration/Logins/WebAccountBL.cs`, `BL/WebSuite` | Weblogins für Kunden mit eigenem Rechtesatz. | +| M117 | Webservice | `src/webservice` (Host, Controllers, WebServices.Core) | REST-/Dienstschicht für Client-, Web- und Fremdzugriffe. | +| M118 | ConnectionManager | `src/webservice/c-entron.misc.ConnectionManager` | Verwaltung der DB-/Dienstverbindungen. | + +### M. Weitere Fachmodule + +| Nr. | Modul | Pfad | Fachliche Aufgabe | +|---|---|---|---| +| M119 | MyCentron/Dashboard | `BL/MyCentron` | Persönliche Startseite mit Dashboards, Notizen, Planungen. | +| M120 | MyDay | `BL/MyDay` | Tagesübersicht mit Importen aus Fremdtools (lizenzpflichtig je Import). | +| M121 | KI-Funktionen | `BL/ArtificialIntelligence` | KI-Chat und Prompts (z. B. Textvorschläge). | +| M122 | TradePool | `BL/TradePool` | Gebrauchtgeräte-/Handelsplattform-Anbindung. | +| M123 | VoucherManagement | `BL/VoucherManagement` | Gutschein-/Voucherverwaltung. | +| M124 | Textbausteine | `BL/TextModuleArea` | Wiederverwendbare Textmodule. | +| M125 | Tags | `BL/Tags` | Freie Verschlagwortung von Objekten. | +| M126 | Social Media | `BL/SocialMedia` | Social-Media-Profile zu Personen/Accounts. | +| M127 | VideoPortal | `BL/VideoPortal` | Zuordnung von Schulungs-/Videos. | +| M128 | WebLinks | `BL/WebLinks` | Aktionslinks (z. B. Terminbestätigung) mit Handlern. | +| M129 | Mobile | `BL/Mobile` | Unterstützung mobiler Clients. | +| M130 | ProductMatrix | `BL/ProductMatrix` | Produktmatrix (Artikelvergleich/-zuordnung). | +| M131 | ItPlanner | `BL/ItPlanner` | Planungsobjekte/Checklisten für IT-Projekte. | +| M132 | ExpectedEvents | `BL/ExpectedEvents` | Erwartete Ereignisse/Wiedervorlagen. | +| M133 | CPra | `BL/CPra` | Anbindung „CPra"-Konnektor (Konfiguration + Übertragung). | +| M134 | RiverDivo | `BL/RiverDivo` | Anbindung RiverSuite/Divo (Vertragsartikel-Referenzen). | +| M135 | Länder/Regionen | `BL/CountryArea` | Länder- und Bundesländerstamm. | +| M136 | Feiertage | `Centron.DAO/Holiday` | Feiertagsberechnung (z. B. für Fristen). | +| M137 | Wechselkurse/Währungen | `ReceiptBase` (CurrencyI3D/Factor), Währungstabellen | Fremdwährungsbelege mit Kursfaktor. | +| M138 | Objekt-Fremdreferenzen | `BL/ObjectExternalReferences` | Verknüpfung interner Objekte mit externen IDs. | +| M139 | Prozesse/Workflows | `BL/Processes`, `BL/Services/Workflows` | Definierte Abläufe/Workflow-Unterstützung. | +| M140 | Änderungsverfolgung | `BL/ChangeTracking`, `Centron.DAO/ChangeTracking` | Historisierung von Feldänderungen. | + +### N. Infrastruktur / Querschnitt + +| Nr. | Modul | Pfad | Fachliche Aufgabe | +|---|---|---|---| +| M141 | WPF-Client-Rahmen | `src/centron/Centron.WPF.UI` (Start, Modules, Views) | Windows-Client mit Modulnavigation und Anmeldung. | +| M142 | Shared Controls | `src/shared/Centron.Controls`, `Centron.Core` | Wiederverwendbare UI-Komponenten und Basisfunktionen. | +| M143 | Datenzugriff/DAO | `src/backend/Centron.DAO` | NHibernate-Mappings, Repositories, NamedQueries, RawSQL. | +| M144 | Gateway | `src/backend/Centron.Gateway` | Externe Format-Gateways (u. a. Buchhaltungsexporte, EGIS-Suche). | +| M145 | Deployment/Setup | `deployment/`, `docker/`, `azure/`, `azure-blazor/` | Installer (WiX), Container- und Cloud-Bereitstellung. | +| M146 | Lokalisierung | `LocalizedStrings*.resx`, `docs/guides/ui/localization.md` | Deutsch als Erstsprache, Englisch als Zweitsprache. | + +**Summe: 146 Module.** Das Inventar darf ergänzt, aber nicht gekürzt werden. + +--- + +## Erzeugtes Anforderungs-Set (Überblick) + +| Ebene | Anzahl | davon HYPOTHESE | +|---|---|---| +| StRS | 32 | 0 | +| SyRS | 156 | 11 | +| SwRS | 71 | 2 | +| **Gesamt** | **259** | **13 (5,0 %)** | + +--- + +## Abdeckungstabelle (je Modul des Inventars) + +Einstufung: **tief** = mehrere Anforderungen mit methodengenau gelesener Logik (inkl. +SwRS-Vertiefung) · **mittel** = 1-2 Anforderungen mit konkret gelesener Logik · +**flach** = 1 Anforderung auf Basis von Dateibestand/Signaturen · **nicht analysiert** = 0 +Anforderungen. `[H]` = Anforderung mit Status HYPOTHESE. Jede Inventarzeile ist enthalten. + +| Nr. | Modul | Abdeckung | Anforderungen (tragend) | Anzahl | +|---|---|---|---|---| +| M01 | Angebote | mittel | SyRS-001 (+SyRS-026/027 übergreifend) | 1 | +| M02 | Aufträge | mittel | SyRS-002 | 1 | +| M03 | Lieferscheine | mittel | SyRS-003 | 1 | +| M04 | Rechnungen | tief | SyRS-004, SyRS-005, SyRS-006, SwRS-016, SwRS-017 | 5 | +| M05 | Gutschriften | mittel | SyRS-007 | 1 | +| M06 | Abhollisten | flach | SyRS-008 | 1 | +| M07 | Verträge (Beleg) | mittel | SyRS-009, SwRS-023 | 2 | +| M08 | Automatische Fakturierung | tief | SyRS-010, SyRS-011, SwRS-019, SwRS-020, SwRS-021, SwRS-022, SwRS-024, SwRS-064, SwRS-071 [H] | 9 | +| M09 | Zeitenabrechnung | tief | SyRS-012, SwRS-063 | 2 | +| M10 | Anzahlungen | mittel | SyRS-013, SwRS-018 | 2 | +| M11 | Projekte (Beleg/PM) | flach | SyRS-014 | 1 | +| M12 | Leasing & Service | flach | SyRS-015 | 1 | +| M13 | Aktionspreise | mittel | SyRS-016 | 1 | +| M14 | Artikelsuche im Beleg | tief | SyRS-017, SwRS-007, SwRS-009, SwRS-010, SwRS-013, SwRS-014 | 6 | +| M15 | Kassenbuch | mittel | SyRS-018 | 1 | +| M16 | Sonderpreise | tief | SyRS-019, SwRS-008 | 2 | +| M17 | Stammblätter | mittel | SyRS-020 | 1 | +| M18 | Schweiz-Besonderheiten | tief | SyRS-021, SwRS-012 | 2 | +| M19 | Belegversionierung | mittel | SyRS-022, SwRS-002, SwRS-003 | 3 | +| M20 | Nummernkreise | tief | SyRS-023, SwRS-025 | 2 | +| M21 | Belegdruck/-versand | mittel | SyRS-024 | 1 | +| M22 | Lieferantenbestellungen | flach | SyRS-029 | 1 | +| M23 | Lieferantenrechnungen | mittel | SyRS-030 | 1 | +| M24 | Lieferantenlieferscheine | mittel | SyRS-031 | 1 | +| M25 | Lieferantengutschriften | flach | SyRS-032 | 1 | +| M26 | Lieferantenbelegdokumente | flach | SyRS-033 | 1 | +| M27 | Bestellvorschläge | flach | SyRS-034 | 1 | +| M28 | Lieferanten-/Distributorenstamm | mittel | SyRS-035 | 1 | +| M29 | Adress-/Kundenstamm | tief | SyRS-036, SyRS-037, SwRS-051 | 3 | +| M30 | Ansprechpartner & Adressen | mittel | SyRS-037 | 1 | +| M31 | Aktivitäten | mittel | SyRS-038 | 1 | +| M32 | Kampagnen | flach | SyRS-039 | 1 | +| M33 | Marketing/Mailings | flach | SyRS-040 | 1 | +| M34 | Umfragen | mittel | SyRS-041 | 1 | +| M35 | CRM-Projekte | flach | SyRS-042 | 1 | +| M36 | Hotline | flach | SyRS-043 | 1 | +| M37 | Kundenvereinbarungen | flach | SyRS-044 | 1 | +| M38 | Helpdesk/Tickets | tief | SyRS-045, SyRS-046, SyRS-047, SyRS-058, SwRS-047, SwRS-048 | 6 | +| M39 | Eskalationsmanagement | tief | SyRS-048, SwRS-049 | 2 | +| M40 | Ticket-Zeiterfassung | mittel | SyRS-049 | 1 | +| M41 | Checklisten | mittel | SyRS-050 | 1 | +| M42 | Ticketvorlagen (C-FLOW) | mittel | SyRS-051 | 1 | +| M43 | Taskmanagement | flach | SyRS-052 | 1 | +| M44 | Ticketprojekte | mittel | SyRS-053 | 1 | +| M45 | RMA | mittel | SyRS-054, SwRS-050 | 2 | +| M46 | Externes Helpdesk | flach | SyRS-055 [H] | 1 | +| M47 | Terminanfragen | mittel | SyRS-056 | 1 | +| M48 | ToDos | mittel | SyRS-057 | 1 | +| M49 | Kundengeräte | mittel | SyRS-059 | 1 | +| M50 | DocuBoard/Assetmanagement | flach | SyRS-060 | 1 | +| M51 | RMM-Datenimport | flach | SyRS-061 | 1 | +| M52 | MSP-Abrechnung | mittel | SyRS-062, SwRS-064 | 2 | +| M53 | Artikelstamm | mittel | SyRS-063 | 1 | +| M54 | Lager/Bestände | tief | SyRS-064, SwRS-011, SwRS-046 | 3 | +| M55 | Inventur | tief | SyRS-065, SwRS-069 | 2 | +| M56 | Kommissionierung | mittel | SyRS-066 | 1 | +| M57 | Seriennummern/Barcodes | tief | SyRS-067, SwRS-045 | 2 | +| M58 | Produktion | mittel | SyRS-068 | 1 | +| M59 | Versand GLS | flach | SyRS-069 | 1 | +| M60 | Versand Shipcloud | flach | SyRS-070 | 1 | +| M61 | Zahlungseingänge | tief | SyRS-071, SwRS-031 | 2 | +| M62 | Onlinebanking | tief | SyRS-072, SwRS-028 | 2 | +| M63 | Zahlungsverkehr/SEPA | tief | SyRS-073, SwRS-026, SwRS-027 | 3 | +| M64 | Mahnwesen | tief | SyRS-074, SwRS-030 | 2 | +| M65 | OPOS | flach | SyRS-075 | 1 | +| M66 | Buchhaltungsexport | tief | SyRS-076, SwRS-029 | 2 | +| M67 | Bankkonten | mittel | SyRS-077 | 1 | +| M68 | Kreditlimit/Bonität | tief | SyRS-025, SwRS-015 | 2 | +| M69 | Benutzer & Login | tief | SyRS-078, SyRS-079, SwRS-032, SwRS-033, SwRS-034, SwRS-041 | 6 | +| M70 | Rechteverwaltung | tief | SyRS-080, SwRS-036, SwRS-038 | 3 | +| M71 | Zwei-Faktor-Authentifizierung | tief | SyRS-081, SwRS-037 | 2 | +| M72 | Lizenzierung | tief | SyRS-082, SwRS-035 | 2 | +| M73 | Mandanten/Filialen | mittel | SyRS-083 (+SyRS-028) | 1 | +| M74 | Mitarbeiterverwaltung | mittel | SyRS-084 | 1 | +| M75 | Einstellungen | mittel | SyRS-085, SwRS-054 | 2 | +| M76 | Datensicherheit/DSGVO | tief | SyRS-086, SwRS-052 | 2 | +| M77 | DB-Skripte/Migration | mittel | SyRS-087, SwRS-053 | 2 | +| M78 | Hintergrunddienste | mittel | SyRS-088, SwRS-057 | 2 | +| M79 | Telemetrie/Profiling | flach | SyRS-089 [H] | 1 | +| M80 | Access Tokens | tief | SyRS-090, SwRS-040 | 2 | +| M81 | Passwortmanager | mittel | SyRS-091 | 1 | +| M82 | Anpassungen/CustomTables | flach | SyRS-092 | 1 | +| M83 | Massenupdate | mittel | SyRS-093 | 1 | +| M84 | GUI-Profile | flach | SyRS-094 | 1 | +| M85 | E-Mail & Vorlagen | tief | SyRS-095, SwRS-059, SwRS-060 | 3 | +| M86 | Exchange-Sync | flach | SyRS-096 | 1 | +| M87 | MailScanner | mittel | SyRS-097 | 1 | +| M88 | TAPI/Telefonie | mittel | SyRS-098 | 1 | +| M89 | Kalender | mittel | SyRS-099 | 1 | +| M90 | Chats | mittel | SyRS-100 | 1 | +| M91 | Outlook-Add-In | flach | SyRS-101 | 1 | +| M92 | Benachrichtigungen | mittel | SyRS-102 | 1 | +| M93 | EDI-Framework | mittel | SyRS-103, SwRS-062 | 2 | +| M94 | ZUGFeRD/XRechnung | tief | SyRS-104, SwRS-061 | 2 | +| M95 | ebInterface | flach | SyRS-105 | 1 | +| M96 | docuFORM | flach | SyRS-106 [H] | 1 | +| M97 | Icecat | flach | SyRS-107 | 1 | +| M98 | ITscope | mittel | SyRS-108 | 1 | +| M99 | COP | flach | SyRS-109 [H] | 1 | +| M100 | EGIS | flach | SyRS-110 | 1 | +| M101 | Telekom Dive | flach | SyRS-111 [H] | 1 | +| M102 | TANSS | flach | SyRS-112 [H] | 1 | +| M103 | GFK-Export | flach | SyRS-113 | 1 | +| M104 | Datenimport allgemein | flach | SyRS-114 | 1 | +| M105 | Connectors | flach | SyRS-115 | 1 | +| M106 | ReportEngine | mittel | SyRS-116 | 1 | +| M107 | Statistiken | mittel | SyRS-117 | 1 | +| M108 | Indexsuche | mittel | SyRS-118 | 1 | +| M109 | Nexus-Rahmen | tief | SyRS-119, SwRS-067 | 2 | +| M110 | ServiceBoard | mittel | SyRS-120 | 1 | +| M111 | WebCart | tief | SyRS-121, SwRS-043 | 2 | +| M112 | WebOffer | tief | SyRS-122, SwRS-044 | 2 | +| M113 | Dokumentensignierung | mittel | SyRS-123 | 1 | +| M114 | Produktionsaufträge Web | flach | SyRS-124 | 1 | +| M115 | SelfCare | mittel | SyRS-125 | 1 | +| M116 | Web-Accounts/WebSuite | tief | SyRS-126, SwRS-039, SwRS-042, SwRS-066 | 4 | +| M117 | Webservice | tief | SyRS-127, SwRS-055, SwRS-068 | 3 | +| M118 | ConnectionManager | flach | SyRS-128 | 1 | +| M119 | MyCentron/Dashboard | mittel | SyRS-129 | 1 | +| M120 | MyDay | mittel | SyRS-130 | 1 | +| M121 | KI-Funktionen | mittel | SyRS-131 | 1 | +| M122 | TradePool | flach | SyRS-132 [H] | 1 | +| M123 | VoucherManagement | mittel | SyRS-133 | 1 | +| M124 | Textbausteine | mittel | SyRS-134 | 1 | +| M125 | Tags | mittel | SyRS-135 | 1 | +| M126 | Social Media | mittel | SyRS-136 | 1 | +| M127 | VideoPortal | flach | SyRS-137 | 1 | +| M128 | WebLinks | mittel | SyRS-138 | 1 | +| M129 | Mobile | flach | SyRS-139 [H] | 1 | +| M130 | ProductMatrix | mittel | SyRS-140 | 1 | +| M131 | ItPlanner | flach | SyRS-141 [H] | 1 | +| M132 | ExpectedEvents | mittel | SyRS-142 | 1 | +| M133 | CPra | flach | SyRS-143 [H] | 1 | +| M134 | RiverDivo | mittel | SyRS-144 | 1 | +| M135 | Länder/Regionen | mittel | SyRS-145 | 1 | +| M136 | Feiertage | flach | SyRS-146 | 1 | +| M137 | Wechselkurse/Währungen | mittel | SyRS-147 | 1 | +| M138 | Objekt-Fremdreferenzen | mittel | SyRS-148 | 1 | +| M139 | Prozesse/Workflows | flach | SyRS-149 [H] | 1 | +| M140 | Änderungsverfolgung | flach | SyRS-150 | 1 | +| M141 | WPF-Client-Rahmen | tief | SyRS-151, SwRS-056 | 2 | +| M142 | Shared Controls | flach | SyRS-152 | 1 | +| M143 | Datenzugriff/DAO | mittel | SyRS-153, SwRS-001, SwRS-006 | 3 | +| M144 | Gateway | flach | SyRS-154 | 1 | +| M145 | Deployment/Setup | flach | SyRS-155 | 1 | +| M146 | Lokalisierung | mittel | SyRS-156, SwRS-058 | 2 | + +**Abdeckungssummen:** tief = 33 Module · mittel = 66 Module · flach = 47 Module · +nicht analysiert = 0 Module (Summe 146 = Inventar). **Mindestabdeckung erfüllt:** Jedes Modul +besitzt mindestens eine Anforderung; kein Modul musste als `nicht analysiert` geführt werden. +Hinweis: Übergreifende Anforderungen (z. B. SyRS-026-028, StRS-Ebene) sind der Übersicht halber +nur bei ihrem Hauptmodul gezählt; die Anzahl-Spalte summiert deshalb konservativ (203 Zuordnungen +bei 259 Anforderungen; StRS-Anforderungen sind bereichs-, nicht modulbezogen). + +--- + +## Konsistenzcheck über das gesamte Anforderungs-Set + +Die Prüfungen wurden skriptgestützt über die erzeugten Dateien ausgeführt (grep/awk über +`StRS.md`, `SyRS.md`, `SwRS.md`). + +| Prüfung | Ergebnis | +|---|---| +| Doppelte oder mehrfach vergebene IDs | **0** (32 StRS + 156 SyRS + 71 SwRS = 259 eindeutige IDs) | +| Anforderungen ohne Beleg | **0** (259 `Belege:`-Abschnitte zu 259 IDs) | +| Anforderungen ohne `Übernahmewürdigkeit` | **0** (259/259) | +| Anforderungen ohne `Prüfidee` / `Status` / `Konsolidierung` / `Tracelinks` | **0** (jeweils 259/259) | +| Tracelinks auf nicht existierende IDs | **0** (alle 188 referenzierten IDs existieren) | +| SyRS ohne StRS-Rückverweis | **0** · SwRS ohne SyRS-Rückverweis: **0** | +| Nicht rückverlinkte StRS | **0** (jede StRS wird von ≥1 SyRS referenziert) | +| Inhaltlich deckungsgleiche Anforderungen ohne Konsolidierungsmarkierung | **0 bekannte Fälle**; als Konsolidierungskandidaten markiert sind: Gerätedaten dreifach (StRS-19, SyRS-020/059/060), Verträge vs. Kundenvereinbarungen (SyRS-044↔SyRS-009), Versand GLS↔Shipcloud (SyRS-069↔070), Inventur alt/neu (SyRS-065), Einstellungen zweigleisig (SyRS-085, SwRS-054), Social-Media-Stream↔Chat/Benachrichtigungen (SyRS-136) | +| Abgleich `Hypothesen.md` gegen Inline-Markierungen | **deckungsgleich**: 13 Status-HYPOTHESE-Blöcke (SyRS-055, 089, 106, 109, 111, 112, 132, 139, 141, 143, 149; SwRS-065, 071) = 13 Einträge in `Hypothesen.md`; keine zusätzlichen freien Fragen in der Sammeldatei | + +### Liste aller risikorelevanten Anforderungen (Sicherheit, Abrechnung/Fakturierung, Berechtigungen) + +Regel: risikorelevante Anforderungen benötigen mindestens einen `PRIMÄR`-Beleg mit benannter +durchsetzender Stelle, andernfalls `[HYPOTHESE]`. Ergebnis: **81 risikorelevante Anforderungen, +80 mit PRIMÄR-Beleg, 1 als HYPOTHESE gekennzeichnet (SwRS-071). Kein Verstoß.** + +**Sicherheit/Berechtigungen (Typ Sicherheit; 35 Anforderungen, alle mit PRIMÄR, alle belegt):** + +| ID | Titel (Kurz) | PRIMÄR | Status | +|---|---|---|---| +| StRS-13 | Rollenbasierter Zugriffsschutz | 2 | belegt | +| StRS-14 | Anmeldung (AD/Entra, 2FA) | 2 | belegt | +| StRS-23 | DSGVO-Compliance | 1 | belegt | +| SyRS-005 | Rechnungsstorno-Schutz | 1 | belegt | +| SyRS-006 | Rechnungsfestschreibung | 1 | belegt | +| SyRS-028 | Filialbezogene Belegrechte | 1 | belegt | +| SyRS-036 | Account-Rechteprüfung | 2 | belegt | +| SyRS-058 | Einschränkende Helpdesk-Rechte | 1 | belegt | +| SyRS-078 | Login mit Sitzungstickets | 3 | belegt | +| SyRS-079 | Kontodeaktivierung | 1 | belegt | +| SyRS-080 | Gruppenbasierte Rechte | 1 | belegt | +| SyRS-081 | Zwei-Faktor-Authentifizierung | 2 | belegt | +| SyRS-086 | DSGVO-Bereinigung/Löschrecht | 1 | belegt | +| SyRS-090 | API-Zugriffstoken | 2 | belegt | +| SyRS-091 | Passwortmanager | 1 | belegt | +| SyRS-119 | Nexus Cookie-Auth/HSTS | 1 | belegt | +| SyRS-126 | Web-Accounts (getrennte Rechte) | 2 | belegt | +| SyRS-151 | Modulfreischaltung Recht+Lizenz | 1 | belegt | +| SwRS-016 | Stornoregeln im Detail | 1 | belegt | +| SwRS-017 | Festschreibungsmechanik | 1 | belegt | +| SwRS-032 | SHA1-Passworthash (Ist-Zustand) | 2 | belegt | +| SwRS-033 | Dreifache Deaktivierungslogik | 1 | belegt | +| SwRS-034 | Ticket-Lebensdauern | 1 | belegt | +| SwRS-036 | Anwendungs-Pflicht-/Verbotsrechte | 1 | belegt | +| SwRS-037 | 2FA-Parametrik | 1 | belegt | +| SwRS-039 | Getrennte Web-Rechte | 1 | belegt | +| SwRS-040 | Token-Kryptomechanik | 1 | belegt | +| SwRS-041 | Passwortregeln | 1 | belegt | +| SwRS-042 | Web-Login-Beziehungskette | 1 | belegt | +| SwRS-043 | WebCart-Sortiments-Isolation | 1 | belegt | +| SwRS-056 | Modul-Doppelbedingung | 1 | belegt | +| SwRS-059 | Mailumleitung Dev-Builds | 1 | belegt | +| SwRS-066 | Belegsperre für Web-Accounts | 1 | belegt | +| SwRS-067 | Nexus-Transportsicherheit | 1 | belegt | +| SwRS-068 | Webservice-Interceptor-Kette | 1 | belegt | + +**Abrechnung/Fakturierung (46 Anforderungen; 45 mit PRIMÄR, 1 HYPOTHESE):** + +| ID | Titel (Kurz) | PRIMÄR | Status | +|---|---|---|---| +| SyRS-004 | Rechnungen erstellen | 1 | belegt | +| SyRS-005 | Rechnungsstorno (auch Sicherheit) | 1 | belegt | +| SyRS-006 | Festschreibung (auch Sicherheit) | 1 | belegt | +| SyRS-007 | Gutschriften | 1 | belegt | +| SyRS-010 | Automatische Vertragsabrechnung | 1 | belegt | +| SyRS-011 | Klickabrechnung | 1 | belegt | +| SyRS-012 | Zeitenabrechnung | 1 | belegt | +| SyRS-013 | Anzahlungen | 2 | belegt | +| SyRS-018 | Kassenbuch | 1 | belegt | +| SyRS-021 | Rappenrundung CH | 2 | belegt | +| SyRS-023 | Nummernkreise | 1 | belegt | +| SyRS-024 | Belegversand | 1 | belegt | +| SyRS-025 | Kreditlimit | 1 | belegt | +| SyRS-062 | MSP-Abrechnung | 1 | belegt | +| SyRS-071 | Zahlungseingänge | 1 | belegt | +| SyRS-072 | Onlinebanking-Zuordnung | 1 | belegt | +| SyRS-073 | SEPA-Export | 1 | belegt | +| SyRS-074 | Mahnläufe | 2 | belegt | +| SyRS-075 | OPOS | 1 | belegt | +| SyRS-076 | FiBu-Export | 2 | belegt | +| SyRS-077 | Bankverbindungen | 2 | belegt | +| SyRS-082 | Lizenzprüfung (Abrechnungsbezug Hersteller) | 1 | belegt | +| SyRS-104 | E-Rechnung | 1 | belegt | +| SwRS-012 | Rundung über Steuerkorrektur | 1 | belegt | +| SwRS-015 | Kreditlimitberechnung | 1 | belegt | +| SwRS-018 | Anzahlungsmechanik | 1 | belegt | +| SwRS-019 | Intervallfortschreibung | 1 | belegt | +| SwRS-020 | Pro-rata-Normalisierung | 1 | belegt | +| SwRS-021 | Voraus-/Nachberechnung | 1 | belegt | +| SwRS-022 | Kontingentbuchung | 1 | belegt | +| SwRS-023 | Kontingent-Änderungslog | 1 | belegt | +| SwRS-024 | Klickzähler-Historie | 1 | belegt | +| SwRS-025 | Nummernvergabe CAS | 1 | belegt | +| SwRS-026 | SEPA-Formate/Mandatssequenz | 1 | belegt | +| SwRS-027 | SEPA-Folgen/Rücknahme | 1 | belegt | +| SwRS-028 | Banking-Zuordnungsregex | 1 | belegt | +| SwRS-029 | DATEV EXTF 700 | 1 | belegt | +| SwRS-030 | Mahnstufen/Sperren | 1 | belegt | +| SwRS-031 | Zahlungslöschung mit Rückrechnung | 1 | belegt | +| SwRS-035 | Floating-Lizenzzählung | 1 | belegt | +| SwRS-061 | E-Rechnungs-Erzeugungsregeln | 1 | belegt | +| SwRS-062 | ZUGFeRD-Import | 1 | belegt | +| SwRS-063 | Pauschalfilter/Zuschläge | 1 | belegt | +| SwRS-064 | Sonderartikel-Import | 1 | belegt | +| SwRS-070 | Batch-/Paging-Verarbeitung | 1 | belegt | +| SwRS-071 | Sammelrechnung Konzern | 0 | **HYPOTHESE** (regelkonform gekennzeichnet) | + +--- + +## Selbstbewertung + +**1. Analysetiefe (absolute Zahlen):** Von 146 Inventarmodulen wurden **33 tief**, **66 mittel** +und **47 flach** analysiert; **0 Module blieben unanalysiert**. Die Vertiefung folgte der +vorgegebenen Risikopriorisierung: Sicherheits-/Anmelde-/Rechtelogik (M69-M72, M80, M116, M117), +Abrechnung/Fakturierung (M04, M08, M09, M14, M16, M61-M64, M66, M68, M94) und Berechtigungen +(M29, M38, M70, M141) sind tief abgedeckt; die flache Randabdeckung betrifft überwiegend kleine +Zusatzmodule und Schnittstellen mit dünnem Codebestand. + +**2. Mindestabdeckung:** Erreicht. Jedes der 146 Module trägt mindestens eine Anforderung; kein +Modul musste mit Begründung als `nicht analysiert` geführt werden. 11 Module tragen ihre einzige +Anforderung als `[HYPOTHESE]` (M46, M79, M96, M99, M101, M102, M122, M129, M131, M133, M139) – +das ist bewusste Abgrenzung, keine Lücke im Sinne der Mindestabdeckung. + +**3. Dünne Belegstellen (hoher SEKUNDÄR-/KONTEXT- oder Hypothesenanteil):** +- Die 13 Hypothesen (siehe `Hypothesen.md`) stützen sich ausschließlich auf SEKUNDÄR-Belege + (Dateiexistenz, Klassennamen) – v. a. kleine Schnittstellenmodule (docuFORM, COP, Telekom Dive, + TANSS, CPra, TradePool, Mobile, ItPlanner, Workflows, Telemetrie, ExternesHelpdesk) sowie + AutoLock und Sammelrechnung. +- StRS-Belege sind konstruktionsbedingt häufig SEKUNDÄR/KONTEXT (Geschäftsziele sind nicht + direkt im Code kodiert); die zugehörigen SyRS/SwRS tragen die PRIMÄR-Belege. +- Flach eingestufte Module (47) stützen sich auf Dateibestand und Methodensignaturen ohne + vollständige Methodenlektüre; die Aussagen sind bewusst auf das dadurch Belegbare begrenzt. +- Beim Passwortmanager (SyRS-091) ist die Existenz der Ver-/Entschlüsselung belegt, das + Kryptoverfahren selbst aber ungeprüft. + +**4. Hypothesenführung:** 13 Hypothesen (5,0 % des Sets) wurden geführt – die Analyse kommt +also nicht ohne offene Punkte aus; eine Begründung für „null Hypothesen" entfällt. + +**5. Erkenntnisse für eine Folge-Iteration (Nachschlagsempfehlungen):** +1. **Hypothesenauflösung:** Die 13 Hypothesen sind konkret adressierbar (Methodenanalyse von + TanssBL, TelekomDiveBL, TradePoolBL, MobileBL, CPraConnectorBL, Workflow-Engine, + docuFORM-Konsument, COP-Aufrufer, AutoLock-Mechanik, Sammelrechnungs-Bündelung, + Telemetrie-Datenfluss) – geschätzt je Modul wenige Dateien. +2. **ReceiptBL-Resttiefe:** Die 10.000+-Zeilen-Klasse ReceiptBL wurde gezielt (Limit, Rechte, + Concurrency, Logs), aber nicht vollständig gelesen; SaveReceipt-Callbacks, Belegkopier- und + Versandpfade bieten weitere Regeln (z. B. automatisches Schließen, + AutomaticallyCloseReceiptHelperBL). +3. **Steuerlogik:** TaxBL und die MwSt-Zuordnung (innergemeinschaftlich, Drittland, + Reverse-Charge) wurden nicht vertieft – für ein Abrechnungssystem prüfenswert. +4. **Provisionen:** ReceiptProvisionBL/Provision-Schemata (WPF-Modul Provision) sind nur am Rand + erfasst. +5. **Web-Rechtekatalog:** Die WebRights-Einzelrechte (Portalumfang) wurden nicht enumeriert – + für den Zuschnitt des Zielportals nützlich. +6. **UI-Pflichtfelder/Validierungen im Client:** Die WPF-Views enthalten weitere clientseitige + Validierungen, die serverseitig nicht sichtbar sind; für Feature-Parität stichprobenhaft + erheben. +7. **Konsolidierungsentscheidungen vorbereiten:** Für die markierten Kandidaten (Gerätedaten + dreifach, Inventur alt/neu, Einstellungen zweigleisig, Versandwege, Vereinbarungen vs. + Verträge) je eine Feldabgleich-Matrix erstellen, damit Fachexperten in Schritt 7 entscheiden + können. +8. **Werkzeuggrenze:** Die Change-Historie (Git-Log) stand als Artefakt nicht im Fokus dieser + Iteration; Commit-Messages könnten KONTEXT-Belege für Übernahmewürdigkeits-Einstufungen + (veraltet/Workaround) liefern. + +**Methodische Anmerkung:** Alle Zahlen dieses Berichts (IDs, Belegabdeckung, Tracelink-Ziele, +Hypothesenabgleich) wurden skriptgestützt aus den abgegebenen Dateien selbst ermittelt, nicht +manuell gezählt. diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/Glossar.md b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/Glossar.md new file mode 100644 index 00000000..f21f54fd --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/Glossar.md @@ -0,0 +1,70 @@ +# Glossar + +Domänen- und Systembegriffe, wie sie in den Anforderungen (StRS/SyRS/SwRS) verwendet werden. +Technische Bezeichner (Klassen, Tabellen, Spalten) bleiben in Originalsprache. + +| Begriff | Definition | +|---|---| +| Abholliste | Belegart für die Abholung von Geräten/Waren beim Kunden (Tabellen `AbholKopf`/`AbholPos`). | +| Account | Zentraler Geschäftspartner-Datensatz (Kunde, Lieferant, Interessent) im neuen Datenmodell (`Accounts`, `AccountCustomers`, `AccountSuppliers`); Alt-Tabellen: `Kunden`, `Kreditor`. | +| AccountDevice | Zweite Datenhaltung für Kundengeräte (Seriennummer, Modell, Garantie); Konsolidierungskandidat mit Stammblatt und AssetManagement. | +| Aktionspreis | Zeitlich begrenzter Einkaufs-/Verkaufspreis je Artikel (Tabelle `HerstellerArtikAktionspreis`). | +| AnlageLog | Gemeinsame Log-Tabelle aller Belegarten; Belegart über `AnlageArt`-Code (1=Angebot … 4=Rechnung, 22=Vertrag). | +| Anwendungs-GUID (ApplicationKind) | GUID, die eine anmeldeberechtigte Anwendung identifiziert und lizenziert (z. B. c-entron.NET, ServiceBoard, Outlook-Add-In). | +| AppUser | Internes Benutzerkonto eines Mitarbeiters (Tabelle `Sichbenu`); Gegenstück: Web-Account für Endkunden. | +| AssetManagement (DocuBoard) | Dritte Gerätedatenhaltung: automatisiert erhobene IT-Inventardaten (AD-Scans, SNMP) je Kunde. | +| Barcode/Seriennummer | Serialisierte Bestandseinheit mit Zustandsautomat (`BarcodeState`, 20 Zustände) über Lager, Belege, RMA, Stammblatt. | +| Barrechnung | Rechnung mit `IsCashAsset`; erzeugt Kassenbuchbuchungen und ist vom Storno ausgeschlossen. | +| Belegkette / Weiterverarbeitung | Überführung eines Belegs in Folgebelege (Angebot→Auftrag→Lieferschein→Rechnung) mit gespeicherter Herkunftsbeziehung ("Forwarding"). | +| Beleg (Receipt) | Oberbegriff für Angebot, Auftrag, Lieferschein, Rechnung, Gutschrift, Abholliste, Vertrag sowie die Lieferanten-Gegenstücke; gemeinsame Basisklasse `ReceiptBase`. | +| BillingKind (Voraus-/Nachberechnung) | Abrechnungsart eines Vertrags: Vorausberechnung (`Billingadvance`) vor Leistungsbeginn oder nachträgliche Berechnung nach Periodenende. | +| C-FLOW | Produktname der Ticketvorlagen (automatische/manuelle Ticketerzeugung aus Vorlagen). | +| ConcurrencyControlGuid | Beleg-Versionsstempel für optimistische Sperre; Abweichung ⇒ Fehler "ChangedByOtherInstance". | +| DunningStop (Mahnsperre) | Kennzeichen auf Kunde oder Rechnung, das die Aufnahme in Mahnläufe verhindert. | +| EDI | Elektronischer Belegaustausch mit Distributoren (ALSO, ALSO CH, Alltron, Herweck, Komsa, OpenTrans 2.1, EGIS). | +| Eskalationsstufe | Eine von bis zu drei zeitgesteuerten Eskalationen eines Tickets (Wartezeiten `WaitHourEsc1-3`) innerhalb definierter Arbeitszeitfenster. | +| ESR | Schweizer Einzahlungsschein mit Referenznummer; Felder am Rechnungsbeleg (`EsrReferenceNumber` u. a.). | +| Festschreibung | Unveränderlichmachen einer Rechnung (`RechKopf.IsFixed=1`) mit Pflicht-Logeintrag; GoBD-relevant. | +| Filiale (Branch) | Organisationseinheit unterhalb des Mandanten mit eigenen Nummernkreisen und Lagerzuordnung; einschränkende Rechte binden Benutzer an ihre Filiale. | +| Floating-Lizenz | Lizenzzählung über gleichzeitig aktive Sitzungstickets je Anwendungs-GUID. | +| Gutschrift | Belegart zur Minderung einer Forderung (`GutKopf`/`GutPos`). | +| Helpdesk / Ticket | Servicevorgang mit Kunde, Status (konfigurierbar), Typ, Priorität, Kategorien, Bearbeitern, Zeiterfassungen. | +| I3D | Systemweiter Primärschlüsselname (Identity-Spalte) aller Tabellen. | +| Kontingent | Vertraglich vereinbartes Leistungsvolumen (Stunden oder Betrag) mit Regeln für Überbuchung, Restmitnahme und abweichende Kontingentintervalle. | +| Klickabrechnung | Nutzungsabrechnung über Gerätezählerstände (Drucker/Kopierer) mit Freimengen und Staffelpreisen. | +| Kreditlimit | Kundenlimit; Prüfart netto/brutto/keine (`CreditLimitCalculationKind`), Überschreitung erzeugt Bestätigungsdialog. | +| Leitweg-ID | Empfänger-Routing-Kennung der XRechnung; am Kunden hinterlegt (`IAccountCustomer.LeitwegID`). | +| Lizenz (GUID-Lizenz) | Produkt-/Funktionsfreischaltung als GUID mit Anzahl, Gültigkeitsdatum und Maximalversion; Quelle: Lizenzserver. | +| Mandant (Mandator) | Rechtlich selbständige Firmeneinheit mit eigenen Bankdaten, SEPA-Gläubiger-ID und Nummernkreisen. | +| Mandat (SEPA-Mandat) | Einzugsermächtigung an einer Bankverbindung mit Sequenz (First/Recurrent/Last/Single) und Gültigkeit. | +| MasterDataList → siehe Stammblatt | | +| MSP | Managed Services Provider; MSP-Sammler erfassen nutzungsbasierte Mengen (z. B. Lizenzen) zur Vertragsabrechnung. | +| Nummernkreis (NumberGroup) | Konfigurierbarer Nummernbereich je Objektart, Mandant und Filiale mit Intervall und aktuellem Stand. | +| Nexus | Blazor-Webanwendung der Suite (ServiceBoard, Kundenportal/WebCart, WebOffer, Verwaltung). | +| OPOS | Offene-Posten-Verwaltung; Abgleich der Zahlungsstände mit der Finanzbuchhaltung. | +| Pro-rata-Normalisierung | Anteilige Berechnung der ersten Vertragsperiode nach Kalendertagen (`IsNormalize`). | +| Rappenrundung | Schweizer Rundung des Bruttobetrags auf 0,05 durch Anpassung des Steueranteils (Einstellung `CommercialRoundCH`). | +| Recht (AppRight) | Einzelberechtigung (750 Konstanten in `UserRightsConst`); Vergabe ausschließlich über Gruppen (`Sichtrus`/`Sichmemb`). | +| Einschränkendes Recht | Recht, das die Sichtbarkeit verengt statt erweitert (z. B. "Tickets anzeigen - nur eigene"). | +| RMA | Retouren-/Reparaturvorgang; genau eine RMA je Ticket (Unique Index auf `Rma.HelpdeskI3D`). | +| RMM | Remote Monitoring & Management; liefert Geräte-/Nutzungsdaten für die Vertragsabrechnung. | +| Sammelrechnung | Konsolidierte Rechnung über mehrere Verträge eines Kunden/Konzerns (`CollectInvoice`); Bündelungsregel als Hypothese offen. | +| SEPA-Export | Erzeugung von pain.008-Lastschriftdateien mit Folgewirkungen (Exportkennzeichen, optional Rechnungsabschluss, Mandatssequenz). | +| ServiceBoard | Webbasierter Ticketarbeitsplatz der Techniker (Kanban, Zeiten, Mails, Planung). | +| Sitzungsticket | Zeitlich begrenzte Sitzungskennung des Webservice (Standard 30 min, gleitend verlängert). | +| Skontosperre | Artikelkennzeichen `NoEarlyPaymentDiscountAllowed`; nimmt Positionen aus der Skontobasis aus. | +| Sonderabkommen (SpecialAgreement) | Einkaufsvereinbarung mit Lieferanten (eigener EK oder EK-Reduktion) je Artikel. | +| Sonderpreis (Kundensonderpreis) | Kundenindividuelle Preisregel je Artikel in fünf Arten (Fixpreis, EK-Aufschlag, Abschläge auf UVP/VK/Listenpreis); definiert zugleich das WebCart-Sortiment. | +| Stammblatt (MasterDataList) | Gerätestammsatz für die Abrechnung (Seriennummer, Zähler, Vertrag, Ursprungsrechnung); Konsolidierungskandidat mit AccountDevice/AssetManagement. | +| Staffelpreis (VolumePrice) | Mengenabhängige Preisstufen mit vier Verkaufspreislisten (VK1-VK4) und Staffel-EK. | +| Stundenzuschlagssatz | Zeitfensterbezogener Zuschlag auf Servicezeiten (z. B. Nacht/Wochenende), als Überlappung je Zeiterfassung berechnet. | +| Ticket → siehe Helpdesk | | +| TimerBilling (Zeitenabrechnung) | Überführung abrechenbarer Ticketzeiten in Auftrags-/Rechnungspositionen ohne Doppelabrechnung. | +| Übernahmewürdigkeit | Bewertungsfeld dieser Spezifikation: übernehmen / Workaround / Sonderfall / veraltet. | +| Vertrag (ReceiptContract) | Belegart für Dauerleistungen mit Abrechnungsintervall, Kontingenten, Verlängerung und automatischer Abrechnung (`VertragKopf`/`VertragPos`). | +| VertragRechKopfZuordnung | Verknüpfungstabelle Vertrag↔Rechnung je Abrechnungslauf inkl. Kontingentbuchung und Zwischenrechnungskennzeichen. | +| Web-Account | Endkunden-Login für das Portal (getrenntes Rechtesystem `WebRights`); Voraussetzung: durchgehend aktive Kette Kontakt→Adresse→Kunde. | +| WebCart | Shop des Kundenportals; Sortiment = Artikel mit aktiven Sonderpreisen des Kunden. | +| WebOffer | Online-Angebotsansicht mit Freigabe-Zustandsautomat (`WebReceiptState`, 9 Zustände inkl. Signatur). | +| XRechnung / ZUGFeRD | Strukturierte E-Rechnungsformate; Erzeugung je Rechnung mit Leitweg-ID, Einlesen von ZUGFeRD 2.1-Eingangsrechnungen. | +| Zwischenrechnung (Kontingent) | Kontingentbuchung bei abweichendem Kontingent- vs. Abrechnungsintervall (`DifferContingentInterval`). | diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/Hypothesen.md b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/Hypothesen.md new file mode 100644 index 00000000..aa21d90d --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/Hypothesen.md @@ -0,0 +1,30 @@ +# Hypothesen + +Diese Datei enthält **genau die Anforderungen mit `[HYPOTHESE]`-Markierung** aus StRS/SyRS/SwRS +(Status `HYPOTHESE`) – deckungsgleich mit den Inline-Markierungen der Spezifikationen. +Offene Punkte ohne zugehörige Anforderung stehen in der Selbstbewertung des Analyseberichts. + +Gesamtzahl: **13 Hypothesen** (11 × SyRS, 2 × SwRS, 0 × StRS). + +| Nr. | ID | Titel | Hypothese (Kurzfassung) | Fehlende Information zur Bestätigung | +|---|---|---|---|---| +| 1 | SyRS-055 | Anbindung externer Helpdesk-Systeme | Tickets werden mit externen Helpdesk-Systemen ausgetauscht. | Nur `ExternalHelpdeskConfigurationBL.cs` gefunden; Synchronisationslogik (Richtung, Umfang, Zielsysteme) fehlt im analysierten Code. | +| 2 | SyRS-089 | Telemetrie und Profiling | Nutzungs-/Leistungsdaten werden zur Produktverbesserung erfasst. | Inhalt, Übertragungsweg und Empfänger der Telemetriedaten (TelemetryBL/ProfilerBL) nicht verifiziert; DSGVO-Einordnung offen. | +| 3 | SyRS-106 | docuFORM-Anbindung | Gerätezähler-/Flottendaten werden von docuFORM abgerufen und der Klickabrechnung bereitgestellt. | Konsumierender Codepfad vom `DocuFormRestApiClient` zur Zählerübernahme nicht nachvollzogen. | +| 4 | SyRS-109 | COP-Datenzugriff | Produkt-/Preisdaten aus COP dienen der Artikelanreicherung bzw. dem Einkauf. | Aufrufer und fachlicher Zweck des `CopApi`-Clients nicht identifiziert. | +| 5 | SyRS-111 | Telekom-Dive-Schnittstelle | Austausch von Auftrags-/Bestandsdaten mit dem Telekom-Dive-Portal. | Methoden der `TelekomDiveBL` und zugehörige Views nicht analysiert; Richtung und Inhalt unklar. | +| 6 | SyRS-112 | TANSS-Datenübernahme | Übernahme von Tickets/Kunden/Zeiten aus TANSS (vermutlich Migration). | Unklar, ob einmalige Migrations- oder laufende Austauschschnittstelle; Methodenanalyse `TanssBL` fehlt. | +| 7 | SyRS-132 | TradePool-Anbindung | Import von Artikel-/Preisdaten einer Handelsplattform "TradePool". | Datenquelle, Aktualität und fachlicher Nutzungskontext der Plattform unbelegt. | +| 8 | SyRS-139 | Mobile Unterstützung | Versorgung mobiler Clients mit Mitarbeiter-/Kontaktdaten. | Konsumierende Mobile App und tatsächlicher Funktionsumfang unbekannt (nur `MobileBL` mit 3 Methoden). | +| 9 | SyRS-141 | ItPlanner | Strukturierung von IT-Planungsobjekten über kategorisierte Checklisten. | Nur `ChecklistVirtualObjectCategoryBL` gefunden; restlicher Modulzweck (UI, Prozesse) unklar. | +| 10 | SyRS-143 | CPra-Webhook-Anbindung | Übergabe von Vorgängen mit Kunden-/Ticketbezug an ein Partnersystem "CPra" über Webhooks. | Identität des Zielsystems CPra und ausgelöste Prozesse unbekannt. | +| 11 | SyRS-149 | Prozess-/Workflow-Definitionen | Grafisch definierte Workflows werden an Objekten ausgeführt. | Ausführungssemantik (Trigger, Engine, Schrittausführung) nicht nachvollzogen; nur Definitionsverwaltung belegt. | +| 12 | SwRS-065 | Automatische Belegsperre (AutoLock) | Belege/Tickets werden beim Öffnen pessimistisch gesperrt. | Sperrmechanik (Sperrtabelle, Timeout, Entsperrung) nur über Parameternamen `autoLockIfNewReceipt`/`IgnoreLock` indiziert. | +| 13 | SwRS-071 | Sammelrechnung für Konzerne | Mehrere Verträge werden in einer Sammelrechnung gebündelt und an Konzernempfänger versendet. | Bündelungskriterien (welche Verträge in eine Rechnung) nicht verifiziert; nur Empfänger-/Vorlagenlogik belegt. | + +## Vollständige Anforderungsblöcke + +Die vollständigen Blöcke stehen in den jeweiligen Spezifikationen: + +- SyRS-055, SyRS-089, SyRS-106, SyRS-109, SyRS-111, SyRS-112, SyRS-132, SyRS-139, SyRS-141, SyRS-143, SyRS-149 → `SyRS.md` +- SwRS-065, SwRS-071 → `SwRS.md` diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/StRS.md b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/StRS.md new file mode 100644 index 00000000..e8bd6c3c --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/StRS.md @@ -0,0 +1,778 @@ +# StRS – Stakeholder Requirements Specification + +**System:** c-entron ERP-Suite (Branchen-ERP für IT-Systemhäuser) +**Quelle:** Reverse Requirements Engineering aus der Codebasis, statische Analyse +**Norm:** ISO/IEC/IEEE 29148:2018, Ebene Stakeholder-Anforderungen +**Hinweis:** Alle Aussagen sind aus Artefakten der Codebasis abgeleitet. `BL/` steht für +`src/backend/Centron.BL/`. Die fachliche Sicht wurde aus Modulstruktur, durchgesetzten Regeln +und Benutzertexten rekonstruiert; direkte Stakeholder-Aussagen (Interviews, Lastenhefte) lagen +nicht vor, weshalb StRS-Belege überwiegend `SEKUNDÄR`/`KONTEXT` sind. Die zugehörigen +Systemregeln sind auf SyRS-/SwRS-Ebene mit `PRIMÄR`-Belegen unterlegt (siehe Tracelinks). + +**Identifizierte Akteure (aus Rechten, Modulen und UI-Texten):** +Vertrieb/Innendienst, Servicetechniker, Lagermitarbeiter, Buchhaltung/Controlling, +Administrator, Geschäftsleitung, Endkunde (Web-Account im Kundenportal), +Lieferant/Distributor (EDI), Fremdsysteme (RMM, TANSS, RiverSuite, docuFORM). + +--- + +``` +ID: StRS-01 +Titel: Einheitliche Verwaltung von Geschäftspartnern (Accounts) +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertrieb/Innendienst +Vorbedingung: Benutzer ist angemeldet und besitzt die Account-Rechte. +Fakt: Die Codebasis führt Kunden, Lieferanten und Interessenten in einem gemeinsamen + Account-Modell (Tabellen Accounts/AccountCustomers/AccountSuppliers, Alt-Tabellen + Kunden/Kreditor) mit Rechteprüfung für Anlegen/Bearbeiten/Löschen. +Aussage: Das System soll alle Geschäftspartner (Kunden, Lieferanten, Interessenten) zentral + mit Adressen und Ansprechpartnern verwalten. +Ergebnis: Ein Geschäftspartner ist genau einmal erfasst und für alle Module referenzierbar. +Belege: + - [PRIMÄR] BL/Accounts/AccountBL.cs:1305-1366 (CheckRightsFromUser mit CREATE_CUSTOMER/EDIT/DELETE, Fehlermeldungen "Fehlende Rechte um Accounts zu erstellen") - Begründung: durchgesetzte Kernoperationen des Accountstamms. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql (Tabellen Accounts, AccountCustomers, AccountSuppliers, Kunden, Kreditor) - Begründung: Datenmodell der Partnerverwaltung. +Prüfidee: Ein Benutzer ohne CREATE_CUSTOMER-Recht kann keinen Account anlegen; mit Recht wird der Account angelegt und ist in Verkaufs- und Servicebelegen auswählbar. +Tracelinks: SyRS-036, SyRS-037, SwRS-051 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zentrale Stammdatenbasis jedes ERP. +Status: belegt +``` + +``` +ID: StRS-02 +Titel: Durchgängige Vertriebsbelegkette +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertrieb/Innendienst +Vorbedingung: Kunde ist angelegt. +Fakt: Die Codebasis implementiert Angebot, Auftrag, Lieferschein, Rechnung, Gutschrift + und Abholliste als Belegarten mit gemeinsamer Basisklasse und Weiterverarbeitung + (Forwarding) zwischen den Arten. +Aussage: Das System soll den Vertriebsprozess als Belegkette von Angebot über Auftrag und + Lieferschein bis Rechnung/Gutschrift abbilden, wobei Folgebelege aus Vorgängerbelegen + entstehen. +Ergebnis: Jeder Beleg kennt seine Ursprungsbelege; Mengen und Werte fließen in Folgebelege. +Belege: + - [PRIMÄR] src/backend/Centron.Entities/Entities/Sales/Receipts/ReceiptBase.cs (gemeinsame Basisklasse) und BL/Sales/Receipts/ReceiptBL.cs:1563/2462 (ValidateReceiptForwarding) - Begründung: Belegkette und geprüfte Weiterverarbeitung sind implementiert. + - [KONTEXT] docs/reference/receipts/receipts-backend-architecture.md - Begründung: beschreibt die Belegarten und deren Tabellen. +Prüfidee: Aus einem Angebot wird ein Auftrag erzeugt; der Auftrag referenziert das Angebot; aus dem Auftrag entstehen Lieferschein und Rechnung mit übernommenen Positionen. +Tracelinks: SyRS-001, SyRS-002, SyRS-003, SyRS-004, SyRS-007, SyRS-008, SyRS-026 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kernprozess des Vertriebs. +Status: belegt +``` + +``` +ID: StRS-03 +Titel: Wiederkehrende Abrechnung über Verträge +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung/Controlling +Vorbedingung: Vertrag mit Abrechnungsintervall ist erfasst. +Fakt: Verträge (VertragKopf/VertragPos) tragen Abrechnungsintervall, Abrechnungsart und + das Kennzeichen automatische Abrechnung; AutomaticFacturaBL erzeugt daraus Rechnungen. +Aussage: Das System soll Dauerschuldverhältnisse (Wartung, Miete, Managed Services) über + Verträge mit definierten Abrechnungsintervallen automatisch fakturieren. +Ergebnis: Zum Stichtag entstehen Rechnungen für alle fälligen Verträge ohne manuelle Einzelerfassung. +Belege: + - [PRIMÄR] BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.Contracts.cs:1474-1627 (NextDate/SetNextBillingDate/ContractForBilling) - Begründung: Intervallfortschreibung und Fälligkeitsermittlung sind implementiert. + - [KONTEXT] docs/reference/receipts/contracts-backend.md - Begründung: beschreibt Abrechnungsintervalle und AutomaticFacturaBL. +Prüfidee: Ein Monatsvertrag mit Beginn 01.01. erzeugt bei Abrechnung bis 31.03. drei Rechnungen mit korrekten Leistungszeiträumen. +Tracelinks: SyRS-009, SyRS-010, SwRS-019, SwRS-020, SwRS-021 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zentrales Geschäftsmodell der Zielbranche (Systemhäuser/MSP). +Status: belegt +``` + +``` +ID: StRS-04 +Titel: Nutzungsbasierte Abrechnung (Zähler, Kontingente, MSP) +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung/Controlling +Vorbedingung: Vertrag mit Zähler- oder Kontingentbezug besteht. +Fakt: Die Codebasis verwaltet Gerätezähler (Klickzähler) mit Historie, Freimengen und + Staffelpreisen sowie Vertragskontingente mit Überbuchung/Restmitnahme; MSP-Kollektoren + liefern nutzungsbasierte Mengen. +Aussage: Das System soll verbrauchsabhängige Leistungen (Druckklicks, Stundenkontingente, + MSP-Lizenzen) erfassen und periodengerecht abrechnen. +Ergebnis: Nutzungsmengen werden je Periode bewertet, mit Freimengen/Kontingenten verrechnet und fakturiert. +Belege: + - [PRIMÄR] BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.Contracts.cs:1098-1245 (StoreBookedContingent inkl. Überbuchung/Restmitnahme) - Begründung: Kontingentverrechnung ist durchgesetzte Logik. + - [PRIMÄR] ebd.:1248-1256 (UpdClickCounterHistory) - Begründung: Klickzähler werden je Rechnungsposition historisiert. + - [SEKUNDÄR] BL/Statistics/MspCollectors/MspCollectorsBL.cs - Begründung: MSP-Mengenerfassung vorhanden. +Prüfidee: Ein Klickvertrag mit Freimenge X und Zählerständen erzeugt eine Rechnung nur über die Menge oberhalb X. +Tracelinks: SyRS-011, SyRS-062, SwRS-022, SwRS-024 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Differenzierungsmerkmal für MSP-Geschäft. +Status: belegt +``` + +``` +ID: StRS-05 +Titel: Servicegeschäft über Tickets mit abrechenbarer Zeiterfassung +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Servicetechniker +Vorbedingung: Kunde vorhanden; Techniker angemeldet. +Fakt: Helpdesk-Tickets tragen Kunde, Status, Kategorien, Bearbeiter und Zeiterfassungen + (HelpdeskTimer) mit Abrechnungsstatus; TimerBilling überführt Zeiten in Belege. +Aussage: Das System soll Serviceleistungen als Tickets führen, darauf erfasste Arbeitszeiten + dokumentieren und die abrechenbaren Zeiten in Rechnungen überführen. +Ergebnis: Jede abrechenbare Minute ist einem Ticket zugeordnet und wird genau einmal fakturiert. +Belege: + - [PRIMÄR] BL/Sales/CustomerAssets/TimerBilling/TimerBillingBL.cs:233-383 (SearchTimers mit OnlyCalculable, AlreadyBilledTime) - Begründung: Abrechnungsselektion der Zeiten ist implementiert. + - [SEKUNDÄR] CentronRights.md Abschnitt Helpdesk - Begründung: dokumentiert die Ticket-/Zeitrechte fachlich. +Prüfidee: Eine auf einem Ticket erfasste abrechenbare Zeit erscheint in der Zeitenabrechnung und nach Fakturierung nicht erneut. +Tracelinks: SyRS-045, SyRS-049, SyRS-012, SwRS-063 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kern des Servicegeschäfts. +Status: belegt +``` + +``` +ID: StRS-06 +Titel: Fristen- und Eskalationsüberwachung im Service +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Serviceleitung +Vorbedingung: Eskalationstypen sind konfiguriert. +Fakt: EscalationBL prüft Tickets gegen bis zu drei Eskalationsstufen mit Wartezeiten, + Arbeitszeitfenstern und Wochenendregeln und versendet Eskalationsmails. +Aussage: Das System soll überfällige Tickets automatisch erkennen und mehrstufig eskalieren. +Ergebnis: Verantwortliche werden zeitgestuft benachrichtigt; Eskalationen sind protokolliert. +Belege: + - [PRIMÄR] BL/Sales/Support/Escalation/EscalationBL.cs:223-332 (DoEscalation, ShouldEscalated mit WaitHourEsc1-3, Sa/So-Flags) - Begründung: Eskalationsregeln sind durchgesetzte Logik. +Prüfidee: Ein Ticket ohne Reaktion überschreitet die Stufe-1-Wartezeit innerhalb des Arbeitszeitfensters und löst genau eine Stufe-1-Mail aus. +Tracelinks: SyRS-048, SwRS-049 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - SLA-Erfüllung ist vertragsrelevant. +Status: belegt +``` + +``` +ID: StRS-07 +Titel: Bestandsführung mit Seriennummernverfolgung +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Lagermitarbeiter +Vorbedingung: Artikel sind angelegt. +Fakt: Bestände werden je Lager geführt; serialisierte Einheiten (Barcodes) durchlaufen + einen Zustandsautomaten von "im Lager" über Belege bis Stammblatt/RMA. +Aussage: Das System soll Lagerbestände artikel- und lagergenau führen und serialisierte + Geräte über ihren gesamten Lebenszyklus (Einkauf, Lager, Verkauf, Service) verfolgen. +Ergebnis: Zu jeder Seriennummer ist der aktuelle Verbleib feststellbar; Bestände stimmen mit Belegbewegungen überein. +Belege: + - [PRIMÄR] src/backend/Centron.Interfaces/Warehousing/BarcodeState.cs:5-30 (Zustände InStock…ManuallyBookedOut) - Begründung: Lebenszyklus ist als Enum-Zustandsautomat kodiert. + - [PRIMÄR] BL/Warehousing/StockManagement/ArticleStockBL.cs:47-61 (UpdateArticleStock/IncreaseArticleStock) - Begründung: Bestandsfortschreibung ist implementiert. +Prüfidee: Wareneingang einer Seriennummer setzt Zustand InStock; Lieferung an Kunden ändert ihn in InDeliveryList/InInvoice; der Lagerbestand sinkt entsprechend. +Tracelinks: SyRS-063, SyRS-064, SyRS-067, SwRS-045, SwRS-046 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Voraussetzung für Gewährleistung und Service. +Status: belegt +``` + +``` +ID: StRS-08 +Titel: Einkauf über Distributoren mit elektronischem Belegaustausch +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Einkauf +Vorbedingung: Distributor-EDI-Zugang ist konfiguriert. +Fakt: Die Codebasis enthält Lieferantenbelegarten und EDI-Anbindungen (ALSO, ALSO CH, + Alltron, Herweck, Komsa, OpenTrans 2.1, EGIS) für Bestellungen, Auftragsbestätigungen, + Lieferavis und Rechnungen. +Aussage: Das System soll Bestellungen an Distributoren elektronisch übertragen und deren + Rückbelege (Bestätigung, Lieferschein, Rechnung) automatisch einlesen und zuordnen. +Ergebnis: Einkaufsbelege entstehen ohne manuelle Doppelerfassung; Seriennummern und Preise werden übernommen. +Belege: + - [PRIMÄR] BL/EDI/SupplierEdiBL.cs (+ Partial-Klassen je Lieferant) - Begründung: Verarbeitung der Distributor-Dateien ist implementiert. + - [KONTEXT] docs/reference/edi/edi-architecture.md - Begründung: beschreibt Ablauf Download→Parsen→Zuordnung. +Prüfidee: Eine per EDI empfangene Lieferantenrechnung wird der Bestellung zugeordnet und als Eingangsbeleg angelegt. +Tracelinks: SyRS-029, SyRS-030, SyRS-031, SyRS-103, SyRS-110 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - hohes Belegvolumen im Distributionsgeschäft. +Status: belegt +``` + +``` +ID: StRS-09 +Titel: Zahlungsabwicklung inklusive SEPA-Lastschrift und Onlinebanking +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Bankverbindungen und Mandate sind hinterlegt. +Fakt: Die Codebasis erzeugt SEPA-Lastschriftdateien (pain.008-Varianten), verwaltet + Mandatssequenzen, liest Kontoumsätze über finAPI und ordnet sie Rechnungen zu. +Aussage: Das System soll offene Rechnungen per SEPA-Lastschrift einziehen und Zahlungseingänge + aus Kontoumsätzen automatisch den Rechnungen zuordnen. +Ergebnis: Zahlungsstatus der Rechnungen ist aktuell; Lastschriftläufe sind nachvollziehbar protokolliert. +Belege: + - [PRIMÄR] BL/DataExchange/PaymentTransactions/PaymentTransactionBL.cs:132-360 (ExportInvoices, InvoiceExportDone, RefreshBankInformation) - Begründung: SEPA-Export inkl. Folgebuchungen ist implementiert. + - [PRIMÄR] BL/Finances/OnlineBanking/OnlineBankingAccountTransactionsBL.cs:524-643 (AutoCompleteAccountTransacitons, 3-stufige Zuordnung) - Begründung: automatische Zahlungszuordnung ist implementiert. +Prüfidee: Ein Kontoumsatz mit Rechnungsnummer im Verwendungszweck wird der Rechnung zugeordnet und deren bezahlter Betrag erhöht. +Tracelinks: SyRS-071, SyRS-072, SyRS-073, SwRS-026, SwRS-027, SwRS-028 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Liquiditätssicherung. +Status: belegt +``` + +``` +ID: StRS-10 +Titel: Mahnwesen und Offene-Posten-Überwachung +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Rechnungen mit überschrittenem Zahlungsziel existieren. +Fakt: DunningBL ermittelt mahnbare Kunden/Rechnungen mit drei Mahnstufen und beachtet + Mahnsperren auf Kunden- und Rechnungsebene; OPOS-Läufe existieren. +Aussage: Das System soll überfällige Forderungen mehrstufig anmahnen und offene Posten + kundenbezogen ausweisen. +Ergebnis: Mahnläufe erzeugen stufengerechte Mahnungen; gesperrte Kunden/Rechnungen werden übersprungen. +Belege: + - [PRIMÄR] BL/Sales/Receipts/Invoices/Dunning/DunningBL.cs:58-113 (GetDunningCustomers mit DunningStopActive) - Begründung: Mahnselektion inkl. Sperren ist implementiert. + - [PRIMÄR] src/backend/Centron.Interfaces/Sales/Receipts/Invoices/Dunning/DunningLevel.cs (None, Level1-3) - Begründung: Mahnstufen sind kodiert. +Prüfidee: Eine überfällige Rechnung ohne Sperre erscheint im Mahnlauf; mit gesetzter Mahnsperre erscheint sie nicht. +Tracelinks: SyRS-074, SyRS-075, SwRS-030 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Forderungsmanagement. +Status: belegt +``` + +``` +ID: StRS-11 +Titel: Übergabe an externe Finanzbuchhaltung +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Buchhaltung / Steuerberater +Vorbedingung: Buchungsperiode ist abgeschlossen. +Fakt: Es existieren Exportformate für DATEV (ASCII EXTF 700, XML Online 2012/2020), Sage, + Lexware, Addison, Abacus, Navision, SAP, Schilling AS400, GDI, Europa3000 sowie + OPOS-/Stammdaten-Importe zurück. +Aussage: Das System soll Belege und Personenkonten in gängige FiBu-Systeme exportieren und + Zahlungsinformationen aus der FiBu reimportieren. +Ergebnis: Buchhaltungsrelevante Daten stehen dem FiBu-System periodengerecht zur Verfügung. +Belege: + - [PRIMÄR] src/backend/Centron.Gateway/DataExchange/BookKeeping/DatevAscii/BookKeepingExportDatevAscii.cs:991-1029 (EXTF-Header Format 700) - Begründung: DATEV-Format ist implementiert. + - [SEKUNDÄR] src/backend/Centron.Gateway/DataExchange/BookKeeping/ (28 Export-/Importklassen) - Begründung: Formatbreite belegt. +Prüfidee: Der DATEV-ASCII-Export erzeugt eine mit "EXTF";700 beginnende Datei, die die exportierten Rechnungen als Buchungsstapel enthält. +Tracelinks: SyRS-076, SwRS-029 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - gesetzlich notwendige FiBu-Anbindung. +Status: belegt +``` + +``` +ID: StRS-12 +Titel: Gesetzeskonforme elektronische Rechnung +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Buchhaltung / öffentliche Auftraggeber +Vorbedingung: Rechnung ist erstellt; Kunde verlangt E-Rechnung. +Fakt: Die Codebasis erzeugt ZUGFeRD-/XRechnung-Dateien zu Rechnungen (mit Leitweg-ID des + Kunden), liest ZUGFeRD-2.1-Eingangsrechnungen und unterstützt das österreichische + ebInterface-Format. +Aussage: Das System soll Ausgangsrechnungen als strukturierte E-Rechnung (ZUGFeRD/XRechnung, + ebInterface) bereitstellen und strukturierte Eingangsrechnungen verarbeiten. +Ergebnis: Kunden mit E-Rechnungspflicht erhalten normkonforme Rechnungsdateien. +Belege: + - [PRIMÄR] BL/WebServices/Sales/Receipts/ReceiptWebServiceBL.cs:2151-2185 (CreateZugferdFile mit GetLeitwegID, nur InvoiceClass) - Begründung: E-Rechnungserzeugung ist implementiert. + - [PRIMÄR] BL/EDI/Zugferd/ZUGFeRD_BL.cs:38 (ReadInvoice ZUGFeRD 2.1) - Begründung: Einlesen strukturierter Rechnungen ist implementiert. + - [SEKUNDÄR] docs/reference/zugferd-field-mapping.md, src/apis/Centron.Api.EbInterface/EbInterfaceLogic.cs - Begründung: Feldzuordnung und AT-Format. +Prüfidee: Zu einer Rechnung eines Kunden mit Leitweg-ID wird eine XRechnung-Datei mit dieser Leitweg-ID erzeugt. +Tracelinks: SyRS-104, SyRS-105, SwRS-061, SwRS-062 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - gesetzliche Pflicht (E-Rechnung B2G/B2B). +Status: belegt +``` + +``` +ID: StRS-13 +Titel: Feingranularer, rollenbasierter Zugriffsschutz +Ebene: StRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Benutzer und Gruppen sind eingerichtet. +Fakt: 750 Einzelrechte werden über Gruppen (Sichtrus→Sichmemb→Sichbenu) an Benutzer + vergeben; Module und Operationen prüfen Rechte serverseitig; einschränkende Rechte + ("nur eigene", "nur eigene Filiale") verengen Sichtbarkeit. +Aussage: Das System soll jede fachliche Funktion einzeln berechtigbar machen und Rechte + ausschließlich über Gruppenzugehörigkeit vergeben. +Ergebnis: Benutzer sehen und tun nur, was ihre Gruppenrechte erlauben; Verstöße werden mit Fehlermeldung abgewiesen. +Belege: + - [PRIMÄR] BL/Administration/Rights/AppRightsBL.cs:95-111 (CheckRightsFromUser: SQL über Sichtrus/Sichmemb) - Begründung: durchsetzende Rechteauflösung. + - [PRIMÄR] src/webservice/Centron.WebServices.Core/EntitiesWrongPlace/Administration/Rights/UserRightsConst.cs (750 `public const int`) - Begründung: Rechtekatalog. + - [KONTEXT] CentronRights.md - Begründung: fachliche Beschreibung inkl. einschränkender Rechte. +Prüfidee: Entzug eines Gruppenrechts entzieht allen Gruppenmitgliedern die Funktion; ein "nur eigene"-Recht blendet fremde Tickets aus. +Tracelinks: SyRS-080, SyRS-058, SwRS-038 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Compliance- und Organisationsanforderung. +Status: belegt +``` + +``` +ID: StRS-14 +Titel: Unternehmenskonforme Anmeldung (Verzeichnisdienst, 2FA) +Ebene: StRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Alle Benutzer +Vorbedingung: Benutzerkonto existiert. +Fakt: Die Anmeldung unterstützt Benutzername/Passwort, Active Directory und + OpenID Connect (Microsoft Entra ID); optional erzwingt das System eine + Zwei-Faktor-Prüfung per E-Mail oder RADIUS. +Aussage: Das System soll die Anmeldung wahlweise gegen das lokale Konto oder den + Unternehmens-Verzeichnisdienst durchführen und eine Zwei-Faktor-Authentifizierung + unterstützen. +Ergebnis: Nur authentifizierte (und bei aktivierter 2FA zweifach bestätigte) Benutzer erhalten ein Sitzungsticket. +Belege: + - [PRIMÄR] BL/Administration/Logins/Auth/ (BasicAuthenticator, ActiveDirectoryAuthenticator, OpenIdConnectAuthenticator, AuthenticatorFactory) - Begründung: Authentifizierungswege sind implementiert. + - [PRIMÄR] BL/Administration/Logins/TwoFactor/TwoFactorAuthBL.cs:33-120 (ValidateTwoFactor) - Begründung: 2FA-Erzwingung ist implementiert. + - [KONTEXT] docs/reference/security/anmelden-mit-microsoft-technische-anleitung.md - Begründung: dokumentierter Entra-ID-Login. +Prüfidee: Ein Benutzer mit aktivierter 2FA und abgelaufener Gültigkeitsdauer muss den zweiten Faktor bestätigen, sonst schlägt der Login fehl. +Tracelinks: SyRS-078, SyRS-081, SwRS-032, SwRS-037 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Sicherheitsstandard. +Status: belegt +``` + +``` +ID: StRS-15 +Titel: Lizenzbasierte Freischaltung von Produkten und Funktionen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Hersteller (nexoware) / Administrator +Vorbedingung: Lizenzdatei/Lizenzserver ist erreichbar. +Fakt: Lizenzen sind GUIDs mit Anzahl, Gültigkeitsdatum und Maximalversion; Anwendungen + prüfen beim Login die Anzahl gleichzeitiger Nutzer über aktive Tickets; Module + prüfen HasLicense. +Aussage: Das System soll Produkte und Einzelfunktionen nur bei vorhandener Lizenz anbieten + und die zulässige Anzahl gleichzeitiger Anmeldungen durchsetzen. +Ergebnis: Nicht lizenzierte Funktionen sind unsichtbar/gesperrt; Überschreitungen der Nutzerzahl verhindern den Login. +Belege: + - [PRIMÄR] BL/Administration/Licensing/LicenseManager.cs:258-302 (CheckLicense: Versions- und Anzahl-Prüfung über GetTicketCount) - Begründung: durchsetzende Lizenzprüfung. + - [KONTEXT] docs/reference/security/licensing-system.md - Begründung: beschreibt GUID-Lizenzmodell. +Prüfidee: Bei erreichter Lizenzanzahl schlägt ein weiterer Login mit "Die maximale Anzahl an Lizenzen wurde erreicht." fehl. +Tracelinks: SyRS-082, SwRS-035, SwRS-056 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Vermarktungsmodell des Herstellers; Umsetzung im SaaS-Modell neu zu bewerten. +Status: belegt +``` + +``` +ID: StRS-16 +Titel: Mandanten- und Filialfähigkeit +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Geschäftsleitung / Administrator +Vorbedingung: Mandanten/Filialen sind eingerichtet. +Fakt: Nummernkreise, Bankverbindungen und Belege sind mandanten-/filialbezogen; Rechte + können auf die eigene Filiale einschränken; Belege tragen BranchI3D. +Aussage: Das System soll mehrere Mandanten und Filialen mit getrennten Nummernkreisen, + Bankdaten und filialbezogener Sichtbarkeit unterstützen. +Ergebnis: Filialbenutzer arbeiten nur auf Belegen ihrer Filiale, sofern einschränkende Rechte gesetzt sind. +Belege: + - [PRIMÄR] BL/Sales/Receipts/ReceiptBL.cs:10251-10295 (CanUserCreateReceiptsInBranch/CanUserEditReceipt mit BranchI3D-Vergleich) - Begründung: Filialbindung wird durchgesetzt. + - [PRIMÄR] BL/Administration/Company/NumberGroupBL.cs:136-152 (Nummernkreise je Mandant und Filiale) - Begründung: getrennte Nummernkreise. +Prüfidee: Ein Benutzer mit Filiale A und "nur eigene Filiale"-Recht kann keinen Beleg der Filiale B bearbeiten. +Tracelinks: SyRS-083, SyRS-028, SyRS-023 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Multi-Site-Betrieb der Kunden. +Status: belegt +``` + +``` +ID: StRS-17 +Titel: Kundenportal im Web +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Endkunde (Web-Account) +Vorbedingung: Web-Account ist für den Kunden angelegt. +Fakt: Das Nexus-Kundenportal bietet Shop (WebCart), Ticketanlage/-verfolgung inkl. + Zeitnachweisen, Vertrags- und Belegübersichten, Dokumente und Formulare. +Aussage: Das System soll Endkunden ein Webportal bereitstellen, in dem sie bestellen, + Tickets erstellen und verfolgen sowie ihre Verträge, Belege und Dokumente einsehen können. +Ergebnis: Endkunden erledigen Standardvorgänge ohne Anruf beim Systemhaus. +Belege: + - [PRIMÄR] src/nexus/CentronNexus/WebCart/ (WebCartShopPage.razor, WebCartTicketsPage.razor, ContractsOverview.razor, ReceiptsOverview.razor, CustomerDocumentsPage.razor) - Begründung: Portalfunktionen sind implementiert. + - [KONTEXT] README.md Abschnitt WebCart - Begründung: beschreibt Zweck (Kunden der Kunden). +Prüfidee: Ein Web-Account sieht nach Login den Shop, kann ein Ticket anlegen und seine Verträge einsehen. +Tracelinks: SyRS-121, SyRS-126, SwRS-043 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Self-Service reduziert Servicekosten. +Status: belegt +``` + +``` +ID: StRS-18 +Titel: Online-Angebotsfreigabe mit Unterschrift +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Endkunde +Vorbedingung: Angebot wurde dem Kunden online bereitgestellt. +Fakt: Web-Belege durchlaufen Zustände von SendToCustomer über FirstLoaded bis + Annahme/Ablehnung/Signatur (WebReceiptState inkl. WebOfferSign, + WebOfferSignedWithoutSignature); eine Signaturkomponente existiert. +Aussage: Das System soll Kunden Angebote online bereitstellen und deren Annahme, Ablehnung, + Änderungswünsche oder digitale Unterschrift erfassen. +Ergebnis: Die Kundenentscheidung ist mit Zeitpunkt und ggf. Unterschrift am Beleg dokumentiert. +Belege: + - [PRIMÄR] src/backend/Centron.Interfaces/Sales/Receipts/WebReceipt/WebReceiptState.cs:6-26 - Begründung: Freigabe-Zustandsautomat ist kodiert. + - [SEKUNDÄR] src/nexus/CentronNexus/DocumentSigning/IsolatedSignaturePad.razor - Begründung: Unterschriftskomponente vorhanden. +Prüfidee: Ein online angenommenes Angebot wechselt in AcceptFullWebReceipt und ist im Client als angenommen sichtbar. +Tracelinks: SyRS-122, SyRS-123, SwRS-044 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - beschleunigt den Vertriebsabschluss. +Status: belegt +``` + +``` +ID: StRS-19 +Titel: Gerätestamm beim Kunden für Service und Abrechnung +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Servicetechniker / Vertrieb +Vorbedingung: Geräte sind beim Kunden im Einsatz. +Fakt: Kundengeräte werden in drei getrennten Datenhaltungen geführt: Stammblätter + (MasterDataList mit Zähler-, Vertrags- und Rechnungsbezug), AccountDevices + (Seriennummer, Modell, Garantie) und AssetManagement (DocuBoard-Inventarisierung). +Aussage: Das System soll die beim Kunden befindlichen Geräte mit Seriennummer, Standort, + Garantie und Vertragsbezug führen, damit Service und nutzungsbasierte Abrechnung + darauf aufsetzen können. +Ergebnis: Zu jedem Kundengerät sind Historie, Vertrag und Zähler auffindbar. +Belege: + - [PRIMÄR] src/backend/Centron.Entities/Entities/Sales/Receipts/MasterDataLists/MasterDataList.cs (SerialNumber, CounterDevice, ContractI3D, InvoiceI3D) - Begründung: Stammblatt-Datenmodell. + - [PRIMÄR] src/backend/Centron.Entities/Entities/Devices/AccountDevice.cs (SerialNumber, Model, Manufacturer, WarrantyExpiryDate) - Begründung: zweite Gerätedatenhaltung. + - [SEKUNDÄR] BL/DocuBoard/AssetManagement*BL.cs - Begründung: dritte Datenhaltung (Inventarisierung). +Prüfidee: Ein Drucker mit Stammblatt ist über seine Seriennummer auffindbar und zeigt Vertrag und Zählerhistorie. +Tracelinks: SyRS-020, SyRS-059, SyRS-060 +Konsolidierung: Kandidat: SyRS-020 (Stammblätter), SyRS-059 (AccountDevices), SyRS-060 (AssetManagement) - drei Datenhaltungen für denselben fachlichen Gegenstand "Kundengerät"; im Zielsystem zu einem Asset-Konzept zusammenführen. +Übernahmewürdigkeit: übernehmen - fachlich erforderlich, aber konsolidiert statt dreifach. +Status: belegt +``` + +``` +ID: StRS-20 +Titel: CRM: Aktivitäten, Kampagnen, Umfragen, Verkaufschancen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertrieb / Marketing +Vorbedingung: Accounts existieren. +Fakt: Die Codebasis protokolliert Kundenaktivitäten, führt Kampagnen mit Phasen, + Telemarketing-Aktionen, Umfragen (auch automatisch nach Ticketabschluss) und + CRM-Projekte. +Aussage: Das System soll Kundeninteraktionen lückenlos dokumentieren und Marketing-/ + Vertriebsvorgänge (Kampagnen, Umfragen, Verkaufschancen) unterstützen. +Ergebnis: Die Kundenhistorie ist je Account vollständig einsehbar. +Belege: + - [PRIMÄR] BL/Accounts/Activities/AccountActivitiesBL.cs, BL/Accounts/Campaigns/CampaignBL.cs (+Phase/Action), BL/Accounts/Survey/SurveyProcessBL.cs, BL/Sales/Customers/CrmProjects/CrmProjectBL.cs - Begründung: implementierte CRM-Funktionen. + - [PRIMÄR] BL/Sales/Support/HelpdeskCloseBL.cs:151 (CreateActivityForTicketClosed) - Begründung: automatische Aktivitätenerzeugung ist durchgesetzt. +Prüfidee: Der Abschluss eines Tickets erzeugt eine Aktivität in der Kundenhistorie. +Tracelinks: SyRS-038, SyRS-039, SyRS-040, SyRS-041, SyRS-042 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Vertriebssteuerung. +Status: belegt +``` + +``` +ID: StRS-21 +Titel: Integrierte Kommunikation (E-Mail, Kalender, Telefonie, Outlook) +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Alle Benutzer +Vorbedingung: Mail-/Telefonie-Konfiguration vorhanden. +Fakt: Mails werden über SMTP oder Microsoft Graph versendet, mit Vorlagen und + Variablenersetzung; Exchange-Synchronisation (EWS), MailScanner-Postfachverarbeitung, + TAPI-Anruferkennung und ein Outlook-Add-In existieren. +Aussage: Das System soll die Kundenkommunikation (E-Mail, Termine, Telefonate) direkt aus dem + ERP führen und eingehende Kommunikation den Kunden/Tickets zuordnen. +Ergebnis: Kommunikationsvorgänge sind am Kunden/Ticket dokumentiert. +Belege: + - [PRIMÄR] BL/Mail/Protocols/ (SMTPMail.cs, GraphMail.cs), BL/Mail/Templates/MailTemplateBL.cs, BL/Tapi/PhoneCallBL.cs (SearchContactPersonByPhoneNumberV2), BL/MailScanner/MailScannerBL.cs - Begründung: Kommunikationswege implementiert. + - [SEKUNDÄR] src/nexus/CentronNexus.OutlookAddIn/ - Begründung: Outlook-Integration vorhanden. +Prüfidee: Ein eingehender Anruf zeigt den zugehörigen Ansprechpartner; eine per MailScanner empfangene Mail erzeugt/aktualisiert ein Ticket. +Tracelinks: SyRS-095, SyRS-096, SyRS-097, SyRS-098, SyRS-099, SyRS-101 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Effizienz im Tagesgeschäft. +Status: belegt +``` + +``` +ID: StRS-22 +Titel: Auswertungen, Statistiken und Belegreports +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Geschäftsleitung / Controlling +Vorbedingung: Bewegungsdaten vorhanden. +Fakt: Es existieren Umsatz-, Auftrags-, Rechnungs-, Vertrags-, Ticket- und + Mitarbeiterauslastungs-Statistiken sowie eine ReportEngine mit Vorlagen und + PDF-Erzeugung für Belegdrucke. +Aussage: Das System soll betriebswirtschaftliche Auswertungen und druckfähige Belegdokumente + aus den operativen Daten erzeugen. +Ergebnis: Kennzahlen und Belegdrucke stehen ohne Datenexport zur Verfügung. +Belege: + - [PRIMÄR] BL/Statistics/ (RevenueStatisticBL.cs, SaleStatisticBL.cs, InvoiceStatisticBL.cs, EmployeeUtilizationBL.cs u. a.), BL/ReportEngine/ (ReportDataBL.cs, PdfExport) - Begründung: Auswertungs- und Reportlogik implementiert. +Prüfidee: Die Umsatzstatistik eines Jahres entspricht der Summe der fakturierten Rechnungen dieses Jahres. +Tracelinks: SyRS-116, SyRS-117 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Steuerungsinformation. +Status: belegt +``` + +``` +ID: StRS-23 +Titel: Datenschutz-Compliance (DSGVO) +Ebene: StRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Datenschutzbeauftragter / Administrator +Vorbedingung: DSGVO-Modul lizenziert; Benutzer hat DSGVO-Rechte. +Fakt: Das DSGVO-Modul ermittelt löschbare Altdaten (Kunden ohne Aktivität, Altbelege, + CRM-Einträge) und setzt das Löschrecht für Kontakte um; Zugriff ist rechtegebunden. +Aussage: Das System soll personenbezogene Altdaten identifizieren und auf Anforderung + löschen können (Recht auf Löschung). +Ergebnis: Löschläufe entfernen die ausgewählten personenbezogenen Daten nachvollziehbar. +Belege: + - [PRIMÄR] BL/Administration/DataSecurity/DataSecurityBL.cs:34-70, 377, 787 (Rechteprüfung ACCESS_CLEANUP_DATABASE, DsgvoDeleteRightGetContacts/DeleteContacts) - Begründung: durchgesetzte DSGVO-Funktionen. +Prüfidee: Ein Benutzer ohne DSGVO-Recht erhält "Insufficient rights!"; mit Recht liefert die Statistik löschbare Kontakte. +Tracelinks: SyRS-086, SwRS-052 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - gesetzliche Pflicht. +Status: belegt +``` + +``` +ID: StRS-24 +Titel: Revisionssichere Belegführung +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung / Wirtschaftsprüfer +Vorbedingung: Belege werden verändert oder storniert. +Fakt: Jede Belegänderung erzeugt einen vollständigen Versionsstand in *Versions-Tabellen; + Rechnungen können festgeschrieben werden (IsFixed) und sind dann unveränderlich; + Stornos sind nur unter dokumentierten Bedingungen möglich; Beleglogs protokollieren + Aktionen. +Aussage: Das System soll Belegänderungen versionieren, Rechnungen festschreibbar machen und + alle abrechnungsrelevanten Aktionen protokollieren. +Ergebnis: Jeder frühere Belegstand ist rekonstruierbar; Festschreibung verhindert nachträgliche Änderung. +Belege: + - [PRIMÄR] BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs:86-141 (FixInvoice: UPDATE RechKopf SET IsFixed=1 + Logeintrag "festgeschrieben") - Begründung: Festschreibung ist durchgesetzt. + - [PRIMÄR] ebd.:273-291 (CheckIfInvoiceIsFixed: "Die Rechnung ist festgeschrieben. Änderungen nicht möglich.") - Begründung: Änderungssperre. + - [KONTEXT] docs/reference/receipts/receipts-backend-architecture.md (Version Tables 1:1) - Begründung: Versionierungskonzept. +Prüfidee: Nach Festschreibung einer Rechnung wird jeder Änderungsversuch abgewiesen; die Versionstabellen enthalten den Stand vor jeder Änderung. +Tracelinks: SyRS-006, SyRS-022, SwRS-002, SwRS-016, SwRS-017 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - GoBD-relevante Anforderung. +Status: belegt +``` + +``` +ID: StRS-25 +Titel: Produkt- und Preisdaten von Drittanbietern +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Einkauf / Vertrieb +Vorbedingung: API-Zugänge sind konfiguriert. +Fakt: Es existieren Clients für Icecat (Produktbeschreibungen/Bilder), ITscope + (Produkte/Preise/Bestellungen), COP und EGIS; die Artikelsuche bindet externe + Artikelquellen ein. +Aussage: Das System soll Artikelstammdaten und Tagespreise aus Drittquellen beziehen, um + Angebote ohne manuelle Artikelanlage erstellen zu können. +Ergebnis: Externe Artikel sind mit aktuellen Preisen direkt in Belege übernehmbar. +Belege: + - [PRIMÄR] BL/Sales/Receipts/ArticleSearch/ArticleSearchBL.cs:1107-1126 (ExecuteExternalArticleSearchAsync über ExternalArticleSearchProvider) - Begründung: Einbindung externer Quellen in die Belegartikelsuche. + - [SEKUNDÄR] src/apis/Centron.APIs.IcecatDataAccess/IcecatApi.cs, src/apis/Centron.APIs.ITscopeDataAccess/ITscopeApi.cs - Begründung: API-Clients vorhanden. +Prüfidee: Die Artikelsuche in einem Auftrag findet einen nur bei ITscope vorhandenen Artikel und übernimmt ihn mit Preis in die Position. +Tracelinks: SyRS-107, SyRS-108, SyRS-109, SyRS-110, SyRS-017 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Sortimentsbreite ohne Stammdatenpflege. +Status: belegt +``` + +``` +ID: StRS-26 +Titel: Versandabwicklung mit Paketdiensten +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Lagermitarbeiter +Vorbedingung: Lieferschein ist kommissioniert. +Fakt: API-Clients für GLS und Shipcloud (Labels, Tracking) existieren; Rechnungen tragen + TrackingNumber/TrackingNumberURL. +Aussage: Das System soll Versandaufträge an Paketdienste übergeben und Sendungsnummern am + Beleg speichern. +Ergebnis: Pakete sind ohne Medienbruch etikettiert; Tracking ist am Beleg abrufbar. +Belege: + - [PRIMÄR] src/apis/Centron.Api.Gls/CentronGlsLogic.cs, src/apis/Centron.Api.Shipcloud/CentronShipcloudLogic.cs - Begründung: Versand-API-Clients implementiert. + - [PRIMÄR] src/backend/Centron.Entities/Entities/Sales/Receipts/Invoices/ReceiptInvoice.cs:101-102 (TrackingNumber, TrackingNumberURL) - Begründung: Tracking am Beleg. +Prüfidee: Für einen Lieferschein wird ein GLS-Label erzeugt und die Sendungsnummer am Beleg gespeichert. +Tracelinks: SyRS-069, SyRS-070 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Standard-Logistikprozess. +Status: belegt +``` + +``` +ID: StRS-27 +Titel: Produktion/Konfektionierung eigener Artikel +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Produktion / Lager +Vorbedingung: Stücklistenartikel existieren. +Fakt: ProductionOrderBL verwaltet Fertigungsaufträge mit Positionen und Status + (ProductionOrderItemState); ArticleProductionBL produziert Artikel aus Teilelisten; + eine Web-Sicht (Nexus ProductionOrderManagement) existiert. +Aussage: Das System soll Fertigungsaufträge für zusammengesetzte Artikel (z. B. PC-Konfigurationen) + führen und deren Fertigstellung bestandwirksam buchen. +Ergebnis: Komponenten werden ausgebucht, das Erzeugnis eingebucht; der Auftragsstatus ist verfolgbar. +Belege: + - [PRIMÄR] BL/Production/ProductionOrderBL.cs (SaveProductionOrder, GetProductionOrdersByFilter), BL/Warehousing/ArticleProduction/ArticleProductionBL.cs - Begründung: Fertigungslogik implementiert. +Prüfidee: Das Abschließen eines Fertigungsauftrags reduziert die Komponentenbestände und erhöht den Bestand des Erzeugnisses. +Tracelinks: SyRS-068, SyRS-124 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Konfektionierung gehört zum Systemhausgeschäft. +Status: belegt +``` + +``` +ID: StRS-28 +Titel: Projektgeschäft mit Belegzuordnung +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Projektleiter +Vorbedingung: Projekt ist angelegt. +Fakt: Projekte existieren als eigene Objekte; Belege tragen ProjectNumber; Ticketprojekte + bündeln Tickets mit Abhängigkeiten. +Aussage: Das System soll Projekte führen und Belege sowie Tickets Projekten zuordnen, damit + projektbezogene Auswertungen möglich sind. +Ergebnis: Alle Belege/Tickets eines Projekts sind über die Projektnummer auffindbar. +Belege: + - [PRIMÄR] BL/Projects/ProjectBL.cs, BL/TicketProjects/TicketProjectBL.cs (Dependencies), src/backend/Centron.Entities/.../ReceiptInvoice.cs:34 (ProjectNumber) - Begründung: Projektbezug implementiert. +Prüfidee: Ein Auftrag mit Projektnummer erscheint in der Belegliste des Projekts. +Tracelinks: SyRS-014, SyRS-053 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Projektgeschäft der Systemhäuser. +Status: belegt +``` + +``` +ID: StRS-29 +Titel: Kassenführung für Bargeschäfte +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Verkauf/Theke +Vorbedingung: Kassenbuch ist eingerichtet. +Fakt: Barrechnungen (IsCashAsset) sind vom Storno ausgenommen; Kassenbuchbuchungen werden + aus Belegen erzeugt und gelöscht. +Aussage: Das System soll Barverkäufe über ein Kassenbuch mit belegbezogenen Buchungen abbilden. +Ergebnis: Kassenbestand und Belege stimmen überein; Barbelege sind gegen Storno geschützt. +Belege: + - [PRIMÄR] BL/Sales/CashBooks/CashBookBookingBL.cs (UpdateCashBookBookingFromAsset, DeleteCashBookBookingFromAsset) - Begründung: Kassenbuchbuchungen implementiert. + - [PRIMÄR] BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs:160-161 (Storno-Verbot für Barrechnung) - Begründung: durchgesetzte Kassenregel. +Prüfidee: Eine Barrechnung erzeugt eine Kassenbuchbuchung; ihr Storno wird mit Hinweis auf die Barrechnung abgewiesen. +Tracelinks: SyRS-018, SwRS-016 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Ladengeschäft. +Status: belegt +``` + +``` +ID: StRS-30 +Titel: Mitarbeiterverwaltung mit Auslastungssicht +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Personal / Serviceleitung +Vorbedingung: Mitarbeiter sind erfasst. +Fakt: Mitarbeiterstamm mit Abteilungen, Skills, Urlaub, RFID-Token und Teams existiert; + Auslastung anderer Mitarbeiter ist rechtegebunden einsehbar; Ein-/Austrittsdatum + deaktiviert Konten. +Aussage: Das System soll Mitarbeiter mit Organisationszuordnung und Qualifikationen verwalten + und deren Auslastung berechtigten Rollen anzeigen. +Ergebnis: Einsatzplanung kann auf aktuelle Auslastungs- und Skilldaten zugreifen. +Belege: + - [PRIMÄR] BL/EmployeeArea/ (EmployeeBL.cs, EmployeeDepartmentBL.cs, EmployeeSkillsBL.cs, TeamManagementBL.cs), BL/Statistics/Administration/Employees/EmployeeUtilizationBL.cs - Begründung: implementierte Personalfunktionen. + - [PRIMÄR] BL/Administration/Logins/Auth/Authenticator.cs:206-216 (IsActiveEmployeeCompact: Deaktivierung über Ein-/Austrittstermin) - Begründung: durchgesetzte Kopplung Mitarbeiterstatus→Login. + - [KONTEXT] CentronRights.md Abschnitt Mitarbeiterauslastung - Begründung: fachliche Rechtebeschreibung. +Prüfidee: Ein ausgetretener Mitarbeiter (Austrittstermin überschritten) kann sich nicht mehr anmelden. +Tracelinks: SyRS-084, SyRS-079 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Basisstammdaten. +Status: belegt +``` + +``` +ID: StRS-31 +Titel: Zuverlässiger Systembetrieb mit automatischer Datenpflege +Ebene: StRS +Typ: nicht-funktional +Qualitätsmerkmal: Zuverlässigkeit +Akteur: Administrator / Betrieb +Vorbedingung: Webservice läuft. +Fakt: Ein stündlicher DataQualityService bereinigt/repariert Daten; abgelaufene + Sitzungstickets werden gelöscht; nummerierte Migrationsskripte aktualisieren das + Schema versionsgebunden. +Aussage: Das System soll wiederkehrende Wartungs- und Konsistenzaufgaben automatisch im + Hintergrund ausführen und Schemaänderungen versioniert einspielen. +Ergebnis: Datenbestand und Schema bleiben ohne manuelle Eingriffe konsistent. +Belege: + - [PRIMÄR] src/webservice/Centron.Host/AspNetCore/HostedServices/DataQualityService.cs - Begründung: Hintergrunddienst implementiert. + - [PRIMÄR] BL/Administration/Scripts/ScriptMethods/Scripts/ (ScriptMethod.cs) - Begründung: versionierte Migrationen. + - [KONTEXT] docs/Background Service/DataQualityService.md, docs/guides/database/create-scripts.md - Begründung: dokumentierte Betriebskonzepte. +Prüfidee: Nach einem Update führt der Dienst ausstehende Skriptnummern genau einmal aus; der DataQualityService läuft stündlich. +Tracelinks: SyRS-087, SyRS-088, SwRS-053, SwRS-057 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Betriebsstabilität. +Status: belegt +``` + +``` +ID: StRS-32 +Titel: Deutschsprachiges System mit englischer Zweitsprache +Ebene: StRS +Typ: nicht-funktional +Qualitätsmerkmal: Benutzbarkeit (Usability) +Akteur: Alle Benutzer +Vorbedingung: keine +Fakt: Alle Benutzertexte liegen deutsch in Basis-Resx (2.812 Einträge allein in + Centron.WPF.UI LocalizedStrings.resx) mit englischen Übersetzungsdateien + (LocalizedStrings.en.resx); die Doku schreibt Deutsch als Erstsprache vor. +Aussage: Das System soll alle Benutzertexte deutsch als Erstsprache und englisch als + Zweitsprache bereitstellen; Fachbegriffe folgen der deutschen Branchenterminologie. +Ergebnis: Benutzer arbeiten vollständig in ihrer Sprache; Umschaltung auf Englisch ist möglich. +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Resources/LocalizedStrings.resx (2.812 data-Einträge) und LocalizedStrings.en.resx - Begründung: Sprachressourcen vorhanden. + - [KONTEXT] docs/getting-started/general-structure.md (German-First Language Policy) - Begründung: dokumentierte Sprachpolitik. +Prüfidee: Alle in der UI sichtbaren Meldungen erscheinen in der eingestellten Sprache; fehlende EN-Texte fallen auf DE zurück. +Tracelinks: SyRS-156, SwRS-058 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Zielmarkt DACH; Mehrsprachigkeit im Web-Zielsystem von Beginn an einplanen. +Status: belegt +``` diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/SwRS.md b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/SwRS.md new file mode 100644 index 00000000..02bb25d7 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/SwRS.md @@ -0,0 +1,1784 @@ +# SwRS – Software Requirements Specification + +**System:** c-entron ERP-Suite +**Quelle:** Reverse Requirements Engineering aus der Codebasis, statische Analyse +**Norm:** ISO/IEC/IEEE 29148:2018, Ebene Software-Anforderungen +**Konventionen:** `BL/` = `src/backend/Centron.BL/`. Jede SwRS-Anforderung referenziert ihre +SyRS-Elternanforderung(en) in den Tracelinks. Die SwRS vertieft insbesondere die Risikobereiche +Abrechnung/Fakturierung, Sicherheit und Berechtigungen sowie das Datenmodell. + +--- + +## Datenmodell und Persistenz + +``` +ID: SwRS-001 +Titel: Duales Belegschema: deutsche Tabellen, englische Views +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Datenzugriffsschicht +Vorbedingung: keine +Fakt: Jede Belegart hat eine deutsche Kopf-/Positionstabelle (AngKopf/AngPos, + AufKopf/AufPos, LiefKopf/LiefPos, RechKopf/RechPos, VertragKopf/VertragPos, + GutKopf/GutPos, AbholKopf/AbholPos) und englische Views (Offers/OfferItems …); + die DB enthält 1.558 Tabellen und 182 Views. +Aussage: Die Software soll Belege über englischsprachige Views lesen, während die + persistenten Strukturen die deutschen Legacy-Tabellen bleiben. +Ergebnis: Neue Codeteile arbeiten mit konsistent benannten Views ohne Schemaänderung. +Belege: + - [PRIMÄR] SSMS_DB_SCHEMA.sql (CREATE TABLE AngKopf …, CREATE VIEW Offers …) - Begründung: beide Schemaebenen existieren. + - [KONTEXT] docs/reference/receipts/receipts-backend-architecture.md (Dual Layer Architecture) - Begründung: dokumentierte Absicht. +Prüfidee: Jede Belegart besitzt Tabelle und View mit identischem Datenbestand. +Tracelinks: SyRS-153 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - Übergangskonstruktion; Zielsystem mit einem Schema. +Status: belegt +``` + +``` +ID: SwRS-002 +Titel: Versionstabellen als exakte 1:1-Kopien +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Versionierungsmechanismus +Vorbedingung: Belegversion wird gespeichert. +Fakt: *KopfVersions/*PosVersions enthalten alle Spalten der Ursprungstabellen plus + OriginalI3D (und KopfVersionsI3D bei Positionen); das Kopieren erfolgt per + INSERT…SELECT über dynamisch erzeugte Feldlisten; fehlende Spalten in + Versionstabellen brechen das Speichern. +Aussage: Die Software soll Versionstabellen strukturgleich zur Ursprungstabelle halten und + Versionen durch vollständiges Kopieren aller Spalten erzeugen. +Ergebnis: Versionsstände sind feldvollständig; Schemaabweichungen fallen sofort auf. +Belege: + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql (AngKopfVersions … mit identischen Spalten) - Begründung: Strukturgleichheit im Schema sichtbar. + - [KONTEXT] docs/reference/receipts/receipts-backend-architecture.md:147-204 (INSERT…SELECT-Verfahren, DoGetFieldList-Warnung) - Begründung: dokumentierter Mechanismus. +Prüfidee: Nach Hinzufügen einer Spalte nur in der Ursprungstabelle schlägt das Versionieren fehl; nach Ergänzung in der Versionstabelle funktioniert es. +Tracelinks: SyRS-022 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - fehleranfälliges Kopierschema; im Zielsystem generisches Auditverfahren. +Status: belegt +``` + +``` +ID: SwRS-003 +Titel: Gemeinsames Beleg-Logbuch AnlageLog mit Artencode +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Beleglogik +Vorbedingung: Belegereignis tritt ein. +Fakt: AnlageLog protokolliert alle Belegarten in einer Tabelle, differenziert über + AnlageArt (1=Angebot, 2=Auftrag, 3=Lieferschein, 4=Rechnung, 5=Abholliste, + 6=Gutschrift, 22=Vertrag) und AnlageI3D; ReceiptLogBL schreibt typisierte + Einträge (z. B. FixedState, InvoiceCancelled, Kontingentänderungen). +Aussage: Die Software soll Belegereignisse in einem gemeinsamen Log mit Objektart-Codierung + (ObjectI3D+ObjectKind-Muster) speichern. +Ergebnis: Belegübergreifende Ereignisrecherche über eine Tabelle. +Belege: + - [PRIMÄR] BL/Sales/Receipts/ReceiptBL.cs:10313-10353 (WriteReceiptLogs mit ReceiptLogBL-Einträgen) - Begründung: schreibende Stelle. + - [KONTEXT] docs/reference/receipts/receipts-backend-architecture.md:123-143 (AnlageArt-Werte) - Begründung: Codetabelle dokumentiert. +Prüfidee: Ein Rechnungsereignis erzeugt einen AnlageLog-Eintrag mit AnlageArt=4. +Tracelinks: SyRS-022, SyRS-006 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - bewährtes Log-Muster. +Status: belegt +``` + +``` +ID: SwRS-004 +Titel: Belegstatus-Enum mit drei Zuständen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Beleglogik +Vorbedingung: keine +Fakt: ReceiptState kennt Active(1)="offen", Completed(2)="abgeschlossen", + Canceled(3)="storniert"; der Storno setzt Canceled auf einer neuen Version. +Aussage: Die Software soll den Beleglebenszyklus über die Zustände offen, abgeschlossen und + storniert abbilden. +Ergebnis: Belegzustände sind systemweit einheitlich interpretiert. +Belege: + - [PRIMÄR] src/backend/Centron.Interfaces/Sales/Receipts/ReceiptState.cs:6-14 - Begründung: kodierte Zustände. +Prüfidee: Ein stornierter Beleg trägt Status 3 und wird in offenen Listen nicht mehr geführt. +Tracelinks: SyRS-001, SyRS-005 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - klare Zustandssemantik. +Status: belegt +``` + +``` +ID: SwRS-005 +Titel: Optimistische Sperre über ConcurrencyControlGuid +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: Zuverlässigkeit +Akteur: Beleglogik +Vorbedingung: Beleg wird gespeichert/geändert. +Fakt: Jeder Beleg trägt einen ConcurrencyControlGuid; Änderungsmethoden vergleichen den + übergebenen mit dem gespeicherten Guid und liefern bei Abweichung + DefaultMessageCodes.ChangedByOtherInstance; bei Versionskonvertierung wird der + Guid übernommen. +Aussage: Die Software soll Belegänderungen nur bei übereinstimmendem Concurrency-Guid + ausführen und sonst mit definiertem Fehlercode ablehnen. +Ergebnis: Kein Lost Update auf Belegen. +Belege: + - [PRIMÄR] BL/Sales/Receipts/ReceiptBL.cs:4808, 4843, 4884, 4939, 4988, 5039, 5272, 6951 (Guid-Vergleiche) - Begründung: flächendeckend durchgesetzte Prüfung. +Prüfidee: Speichern mit veraltetem Guid liefert ChangedByOtherInstance. +Tracelinks: SyRS-027 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Standard-Nebenläufigkeitsschutz. +Status: belegt +``` + +``` +ID: SwRS-006 +Titel: Legacy-Speicherpfad über SaveReceipt-Repositories +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Datenzugriffsschicht +Vorbedingung: Beleg wird gespeichert. +Fakt: Belege werden nicht über das NHibernate-Entity-Mapping, sondern über + SaveReceipt*Repository-Klassen gespeichert, die moderne Entitäten in temporäre + Legacy-Entitäten (RechKopf, RechPos …) synchronisieren + (SynchronizeReceiptData/SynchronizeReceiptItemData); nur dort zugewiesene Felder + werden persistiert. +Aussage: Die Software soll Belegfelder beim Speichern explizit in die Legacy-Entitäten + synchronisieren; neue Felder erfordern die Erweiterung des Synchronisationscodes. +Ergebnis: Persistierte Feldmenge ist deterministisch durch den Synchronisationscode definiert. +Belege: + - [PRIMÄR] src/backend/Centron.DAO/Repositories/ (SaveReceipt*Repository-Klassen) - Begründung: Speicherpfad implementiert. + - [KONTEXT] docs/reference/receipts/receipts-backend-architecture.md:190/250-255 (Critical Save Warning) - Begründung: dokumentierte Konsequenz. +Prüfidee: Ein nur im Entity ergänztes Feld lädt korrekt, wird aber nicht gespeichert, bis das Repository erweitert ist. +Tracelinks: SyRS-153 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - Fehlerquelle; im Zielsystem einheitliches ORM-Speichern. +Status: belegt +``` + +## Preisfindung und Berechnung + +``` +ID: SwRS-007 +Titel: Vertragssonderpreise: fünf Preisarten mal zwei Änderungsarten +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Preisfindung +Vorbedingung: Belegposition mit Vertragsbezug (contractI3D). +Fakt: GetBasePrice wertet ContractSpecialPrice mit Kind (FixedPrice, + ChangePurchasePrice, ChangeRecommendedSellPrice, ChangeSellPrice, ChangeListPrice) + und ChangeKind (Fixed, Percentage) aus; Vorzeichen sind invertiert (10 = 10 % + Aufschlag, -10 = 10 % Rabatt); unbekannte Kombinationen werfen eine Exception. +Aussage: Die Software soll Vertragssonderpreise in genau den zehn definierten Kombinationen + aus Preisbasis und Änderungsart anwenden und dabei die invertierte + Vorzeichenkonvention beibehalten bzw. dokumentieren. +Ergebnis: Vertragspositionen erhalten deterministische Vertragspreise. +Belege: + - [PRIMÄR] BL/Sales/Receipts/Internal/ReceiptItemPriceBL.cs:169-228 (switch über Kind/ChangeKind mit Invertierungskommentaren) - Begründung: durchsetzende Preisregel. +Prüfidee: Ein Vertragssonderpreis ChangeSellPrice/Percentage -10 erhöht den Rabatt um 10 %. +Tracelinks: SyRS-017, SyRS-009 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Regelwerk; Vorzeichenkonvention im Zielsystem begradigen. +Status: belegt +``` + +``` +ID: SwRS-008 +Titel: Kundensonderpreise: fünf Preisarten +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Preisfindung +Vorbedingung: Kein Vertragssonderpreis greift; Kunde hat Sonderpreis für den Artikel. +Fakt: GetSpecialPrice liefert CustomerSpecialPrice mit Kind SurchargePurchasePrice + (Basis EK, Aufschlag), ReduceRecommendedSellPrice (Basis UVP, Abschlag), FixedPrice, + ReduceSellPrice (Rabatt auf VK), ReduceListPrice (Basis Listenpreis, Abschlag). +Aussage: Die Software soll Kundensonderpreise in genau den fünf definierten Arten mit ihrer + jeweiligen Preisbasis anwenden; Vertragssonderpreise haben Vorrang. +Ergebnis: Kundenpreise folgen der vereinbarten Preisbasis. +Belege: + - [PRIMÄR] BL/Sales/Receipts/Internal/ReceiptItemPriceBL.cs:232-257 (switch SpecialPriceKind) - Begründung: durchsetzende Preisregel. +Prüfidee: Ein Sonderpreis SurchargePurchasePrice +8 ergibt VK = EK * 1,08 (als negativer Rabatt abgebildet). +Tracelinks: SyRS-019, SyRS-017 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Preisvereinbarungslogik. +Status: belegt +``` + +``` +ID: SwRS-009 +Titel: Staffelpreise mit vier Preislisten und Konzernbezug +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Preisfindung +Vorbedingung: Kein Sonderpreis greift; Menge ist bekannt. +Fakt: Bei Staffelpreisen (ArticleVolumePrices) wählt die Software je Menge die Stufe und + je Kundenpreisliste (1-4) den VK (VK1-VK4); die Preisliste kommt vom Kunden oder + dessen Konzern-Hauptkunden (GetCompanyGroupCustomerForReceiptData); Staffel-EK + ersetzt den EK. +Aussage: Die Software soll bei Mengenstaffeln den VK aus der Preislistenspalte des Kunden + (bzw. seines Konzern-Hauptkunden) und den EK aus der Staffel ziehen. +Ergebnis: Mengenrabatte und Konzernkonditionen wirken automatisch. +Belege: + - [PRIMÄR] BL/Sales/Receipts/Internal/ReceiptItemPriceBL.cs:259-275 (VolumePrice mit PriceList und Konzernkunde), 363-374 (Staffel-EK) - Begründung: durchsetzende Staffellogik. +Prüfidee: Ein Kunde mit Preisliste 2 erhält bei Staffelmenge den VK2 der Stufe. +Tracelinks: SyRS-017 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Staffelkonditionen. +Status: belegt +``` + +``` +ID: SwRS-010 +Titel: EK-Ermittlung mit Sonderabkommen, Lager-EK und Kursfaktor +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Preisfindung +Vorbedingung: Artikelposition wird bepreist. +Fakt: GetPurchaseBasePrice nimmt (in dieser Reihenfolge) den Sonderabkommens-EK + (SpecialAgreementEK bei EKVKReduction!=1), sonst den Artikel-EK, überschreibt ihn + mit dem Lager-EK (wenn Lager eigenen EK führt und Einstellung aktiv) bzw. dem + Staffel-EK, wendet die EK-Reduktion des Abkommens (Prozent) an und multipliziert + mit dem Währungsfaktor. +Aussage: Die Software soll den Einstands-Basispreis nach der definierten Vorrangfolge + (Abkommen → Lager → Staffel → Reduktion → Währung) ermitteln. +Ergebnis: Margenberechnungen basieren auf dem korrekten Einstandspreis. +Belege: + - [PRIMÄR] BL/Sales/Receipts/Internal/ReceiptItemPriceBL.cs:313-387 - Begründung: durchsetzende EK-Kaskade. +Prüfidee: Ein Artikel mit Lager-EK 90 statt Artikel-EK 100 kalkuliert mit 90; mit EK-Reduktion 10 % mit 81. +Tracelinks: SyRS-017, SyRS-064 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kalkulationsgrundlage. +Status: belegt +``` + +``` +ID: SwRS-011 +Titel: EK-Fortschreibung bei Bestandsbuchung (gleitender Durchschnitt) +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Bestandslogik +Vorbedingung: Wareneingang bucht Bestand. +Fakt: UpdateArticlePurchasePrice ignoriert Positionen mit Sonderabkommen, lässt + Fixpreis-Artikel (NoMixedEk=FixedPurchasePrice) unverändert, setzt bei + LastPurchasePrice den letzten Preis und bildet sonst den gleitenden Durchschnitt + ((alterEK*alteMenge + Zugangswert)/neueMenge) inkl. Fracht- und + Versicherungsanteilen und Kalkulationsfaktor; Rundung erfolgt AwayFromZero mit + Artikelpräzision; je Lager wird der Lager-EK fortgeschrieben. +Aussage: Die Software soll den Artikel-EK beim Wareneingang gemäß Artikeleinstellung (fix, + letzter, gleitender Durchschnitt) inkl. Nebenkosten fortschreiben und kaufmännisch + mit Artikelpräzision runden. +Ergebnis: Bestandsbewertung entspricht der gewählten Methode. +Belege: + - [PRIMÄR] BL/Warehousing/StockManagement/ArticleStockBL.cs:74-149 - Begründung: durchsetzende EK-Fortschreibung mit allen Fallunterscheidungen. +Prüfidee: Bestand 10@10 €, Zugang 10@8 € + 10 € Fracht: gleitender EK = (100+90)/20 = 9,50 €. +Tracelinks: SyRS-064 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Bewertungslogik. +Status: belegt +``` + +``` +ID: SwRS-012 +Titel: Schweizer Rappenrundung über Steuerkorrektur +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Preisberechnung +Vorbedingung: Einstellung CommercialRoundCH aktiv. +Fakt: TaxPrice wird um (Netto+Steuer − Round((Netto+Steuer)/0,05)*0,05) reduziert, sodass + der Bruttobetrag auf 0,05 endet; dieselbe Korrektur gilt für Fremdwährungs- und + nicht skontierfähige Beträge. +Aussage: Die Software soll die 5-Rappen-Rundung durch Anpassung des Steuerbetrags (nicht des + Nettobetrags) umsetzen. +Ergebnis: Brutto endet auf 0,05; Netto bleibt exakt. +Belege: + - [PRIMÄR] src/webservice/Centron.WebServices.Core/Helper/ReceiptPriceHelper.cs:37-41 - Begründung: durchsetzende Rundungsformel. +Prüfidee: Netto 100,00, Steuer 8,10 → Brutto 108,10 (endet auf 0,05/0,10-Raster); Steuer trägt die Differenz. +Tracelinks: SyRS-021 +Konsolidierung: nein +Übernahmewürdigkeit: Sonderfall - Schweizer Mandanten. +Status: belegt +``` + +``` +ID: SwRS-013 +Titel: Positionsberechnung mit Artikelpräzision und Skontosperre +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Preisberechnung +Vorbedingung: Position wird berechnet. +Fakt: Die Positionsberechnung lädt je Artikel Precision (Nachkommastellen) und + NoEarlyPaymentDiscountAllowed (Skontosperre) und übergibt sie der Berechnung; + nicht skontierfähige Anteile werden getrennt summiert + (NotDiscountableTaxPriceFC). +Aussage: Die Software soll Positionspreise mit artikelspezifischer Präzision runden und + skontogesperrte Artikel aus der Skontobasis ausnehmen. +Ergebnis: Skonto wird nur auf skontierfähige Anteile gewährt. +Belege: + - [PRIMÄR] BL/Sales/Receipts/ReceiptPriceHelperBL.cs:42-52 (Precision/NoEarlyPaymentDiscountAllowed je Artikel); src/webservice/Centron.WebServices.Core/Helper/ReceiptPriceHelper.cs:41 (NotDiscountable-Summen) - Begründung: durchsetzende Berechnungsparameter. +Prüfidee: Ein skontogesperrter Artikel erhöht die nicht skontierfähige Summe; ein Artikel mit Präzision 4 rundet auf 4 Nachkommastellen. +Tracelinks: SyRS-017, SyRS-004 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Zahlungskonditionslogik. +Status: belegt +``` + +``` +ID: SwRS-014 +Titel: Kundenrabatt als automatische Position nach letztem Artikel +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Beleglogik +Vorbedingung: Kunde hat Kundenrabatt. +Fakt: Die Kundenrabatt-Position wird beim Speichern normalisiert (Einzug 0, Gruppe 0, + sichtbar) und unmittelbar nach der letzten Artikelposition eingefügt (sonst ans + Ende). +Aussage: Die Software soll die Kundenrabatt-Position automatisch positionieren und + formatieren, sodass sie stets nach den Artikelpositionen erscheint. +Ergebnis: Belege zeigen den Kundenrabatt einheitlich am Positionsende. +Belege: + - [PRIMÄR] BL/Sales/Receipts/ReceiptBL.cs:8610-8634 - Begründung: durchsetzende Einfügeregel. +Prüfidee: Nach Hinzufügen weiterer Artikel rückt die Rabattposition hinter den letzten Artikel. +Tracelinks: SyRS-017 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Belegdarstellung. +Status: belegt +``` + +``` +ID: SwRS-015 +Titel: Kreditlimit: Netto/Brutto-Varianten und Bestandsrechnung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Beleglogik +Vorbedingung: Kunde mit Limit; Beleg wird gespeichert. +Fakt: CreditLimitCalculationKind 1=Netto, 2=keine Prüfung, sonst Brutto; das verbrauchte + Limit summiert alle limitrelevanten Belegarten (TakesPlaceInLimitCalculation), + subtrahiert die Vorversion des Belegs und bereits weiterverarbeitete + Ursprungsbelege; CreditLimitAvailable wird am Kunden fortgeschrieben. +Aussage: Die Software soll das Kreditlimit netto oder brutto berechnen, den Belegbestand + ohne Doppelzählung (Vorversion, Ursprungsbelege) ermitteln und das verfügbare + Limit am Kunden speichern. +Ergebnis: Limitberechnung ist doppelzählungsfrei und einstellbar. +Belege: + - [PRIMÄR] BL/Sales/Receipts/ReceiptBL.cs:8636-8771 - Begründung: vollständige Limitberechnung. +Prüfidee: Ein Auftrag, der zur Rechnung wurde, zählt nicht doppelt; Kind=2 deaktiviert die Prüfung. +Tracelinks: SyRS-025 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kreditrisikologik. +Status: belegt +``` + +## Vertragsabrechnung (Risikoschwerpunkt) + +``` +ID: SwRS-016 +Titel: Stornoregeln der Rechnung (fünf Vorbedingungen, definierte Folgen) +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Abrechnungslogik +Vorbedingung: Stornoauftrag liegt vor. +Fakt: CancelInvoice prüft nacheinander: Recht RIGHT_RECHNUNGSTORNIEREN, Status nicht + bereits storniert, keine Barrechnung, keine Weiterverarbeitung, kein FiBu-Export; + bei Vertragsrechnungen zusätzlich "nur letzte Rechnung des Vertrags" + (CurrentInvoiceI3D-Vergleich); Folgen: neue Version, Artikamengen 0, Barcodes + geleert, Status Canceled, Logeintrag, Vertragsrücksetzung + (DeactivateContractInvoice, ResetDeviceClickCounter, ResetSpecialArticles) und + Timer-Freigabe (RemoveTimers) in einer Transaktion. +Aussage: Die Software soll den Rechnungsstorno exakt nach diesen Vorbedingungen und mit + diesen transaktionalen Folgen ausführen. +Ergebnis: Stornos sind konsistent; Vertrags-/Zähler-/Zeitdaten sind wieder abrechenbar. +Belege: + - [PRIMÄR] BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs:143-261 (CancelInvoice, IsLastContractInvoice, ResetContract) - Begründung: durchsetzende Stornoimplementierung. +Prüfidee: Storno der vorletzten Vertragsrechnung wird abgewiesen; Storno der letzten setzt Klickzähler zurück und gibt Timer frei. +Tracelinks: SyRS-005, SyRS-010, SyRS-011, SyRS-012 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Abrechnungsintegrität. +Status: belegt +``` + +``` +ID: SwRS-017 +Titel: Festschreibung als einmaliges, geloggtes DB-Flag +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Abrechnungslogik +Vorbedingung: Rechnung ist nicht festgeschrieben. +Fakt: FixInvoice prüft den Ist-Zustand (Warnung bei bereits festgeschrieben), setzt + IsFixed=1 per parametrisiertem UPDATE in einer Transaktion und schreibt einen + ReceiptLog-Eintrag (Kind FixedState) mit Benutzer, Zeitpunkt und Belegversion. +Aussage: Die Software soll die Festschreibung als idempotentes, transaktionales Setzen des + IsFixed-Flags mit Pflicht-Logeintrag implementieren. +Ergebnis: Festschreibung ist nachweisbar und nicht wiederholbar. +Belege: + - [PRIMÄR] BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs:86-141 - Begründung: durchsetzende Implementierung. +Prüfidee: Zweiter Fix-Aufruf liefert die Warnung ohne zweiten Logeintrag. +Tracelinks: SyRS-006 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - GoBD-Mechanik. +Status: belegt +``` + +``` +ID: SwRS-018 +Titel: Anzahlungs-/Schlussrechnungsmechanik mit Textvariablen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Abrechnungslogik +Vorbedingung: Auftrag mit Anzahlungen. +Fakt: Anzahlungsrechnungen entstehen mit frei benennbarem Positionstext (Textvariablen + je Anzahlung, z. B. laufende Nummer); die Schlussrechnung übernimmt die + Auftragspositionen und verrechnet alle Anzahlungsrechnungen; Lieferscheine zu + Anzahlungsaufträgen sind erkennbar (CheckIfDeliveryListIsPartOfOrderWithDownPayments). +Aussage: Die Software soll Anzahlungsketten je Auftrag führen, Positionstexte über Variablen + erzeugen und die Schlussrechnung automatisch um die Anzahlungen mindern. +Ergebnis: Anzahlungsverrechnung ist vollständig und textlich nachvollziehbar. +Belege: + - [PRIMÄR] BL/Sales/Receipts/DownPayment/DownPaymentBL.cs:82-520 - Begründung: durchsetzende Anzahlungsmechanik. +Prüfidee: Zwei Anzahlungen erscheinen in der Schlussrechnung als zwei Verrechnungspositionen mit variablengefüllten Texten. +Tracelinks: SyRS-013 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Projektfakturierung. +Status: belegt +``` + +``` +ID: SwRS-019 +Titel: Intervallfortschreibung mit Monatsend- und Schaltjahrregeln +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertragsabrechnung +Vorbedingung: Vertrag wird fortgeschrieben. +Fakt: NextDate berechnet das nächste Abrechnungsende je Intervallart: täglich (+Dauer + Tage), monatlich (+Dauer Monate ab Folgetag, minus 1 Tag) mit Sonderregeln für + Starttage >28 (Monatsend-Anker, Februar-/Schaltjahrbehandlung), quartalsweise mit + Ausrichtung auf Kalenderquartale (1.1./1.4./1.7./1.10.), jährlich (+Dauer Jahre); + isFirstIntervalDay definiert Intervallanfänge (Monatserster bzw. Quartals-/ + Jahreserster). +Aussage: Die Software soll Abrechnungszeiträume nach diesen Kalenderregeln fortschreiben, + insbesondere Monatsverträge mit Beginn am 29.-31. stabil am Monatsende verankern + und Quartale auf Kalenderquartale ausrichten. +Ergebnis: Abrechnungszeiträume bleiben über Jahre lückenlos und überschneidungsfrei. +Belege: + - [PRIMÄR] BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.Contracts.cs:1355-1583 (isFirstIntervalDay, NextDate) - Begründung: durchsetzende Kalenderlogik. +Prüfidee: Monatsvertrag ab 31.01.: Folgeperioden enden 28./29.02., 31.03., 30.04.; Quartalsvertrag ab 15.02. endet erstmalig 31.03. +Tracelinks: SyRS-010 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kernkalenderlogik; im Zielsystem mit Testabdeckung neu implementieren. +Status: belegt +``` + +``` +ID: SwRS-020 +Titel: Anteilige Erstperioden-Normalisierung (Pro-rata) +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertragsabrechnung +Vorbedingung: Vertrag mit IsNormalize, Beginn nicht am Intervallersten, erste Abrechnung. +Fakt: Für die erste Periode berechnen Month-/Quarter-/YearNormalizeCoefficient den + anteiligen Intervallfaktor (Resttage des Startmonats/Monatstage + volle Monate, + geteilt durch 1, 3 bzw. 12), sofern nicht IsFullNormalizeAmount gesetzt ist; der + Faktor geht in InvoiceIntervalCount ein. +Aussage: Die Software soll die erste Teilperiode normalisierter Verträge anteilig nach + Kalendertagen berechnen und den Intervallzähler entsprechend bruchzahlig führen. +Ergebnis: Die erste Rechnung berechnet exakt den anteiligen Zeitraum. +Belege: + - [PRIMÄR] BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.Contracts.cs:1375-1468 (Koeffizienten, SetInvoiceTo) - Begründung: durchsetzende Pro-rata-Formel. +Prüfidee: Monatsvertrag ab 16. eines 30-Tage-Monats: erster Intervallfaktor 0,5. +Tracelinks: SyRS-010 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - verursachungsgerechte Abrechnung. +Status: belegt +``` + +``` +ID: SwRS-021 +Titel: Voraus- vs. nachträgliche Berechnung (BillingKind) +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertragsabrechnung +Vorbedingung: Vertrag ist fällig zu prüfen. +Fakt: Bei Billingadvance ist ein Vertrag fällig, solange das Vertragsende nach dem + letzten bezahlten Datum liegt; bei nachträglicher Berechnung wird InvoiceTo aus + LastPaidDate/FirstPaidDate (bzw. Fallback Vertragsdatum, Ticket 161096) + rekonstruiert und nur bei InvoiceIntervalCount > 0 abgerechnet; Teilabrechnung am + Vertragsende begrenzt den Zeitraum (partBilling). +Aussage: Die Software soll Vorausberechnung und nachträgliche Berechnung mit den jeweiligen + Fälligkeitsregeln unterstützen und am Vertragsende anteilig abrechnen. +Ergebnis: Kein Vertrag wird über sein Ende hinaus oder vor Leistungserbringung falsch berechnet. +Belege: + - [PRIMÄR] BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.Contracts.cs:1408-1471 (SetInvoiceTo mit partBilling), 1596-1627 (ContractForBilling) - Begründung: durchsetzende Fälligkeitslogik. +Prüfidee: Ein Vorausvertrag mit Ende 15.03. berechnet die letzte Periode nur bis 15.03. +Tracelinks: SyRS-010 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Abrechnungsarten. +Status: belegt +``` + +``` +ID: SwRS-022 +Titel: Kontingentbuchung mit Überbuchung, Restmitnahme und Zwischenrechnung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertragsabrechnung +Vorbedingung: Vertrag mit Kontingent wird fakturiert. +Fakt: StoreBookedContingent schreibt je Rechnung eine VertragRechKopfZuordnung mit + Kontingentwert (Wert × Intervallzähler), Überbuchungs- und Restmitnahme-Flags und + Buchungszeitraum; bei abweichendem Kontingentintervall (kleiner/größer als das + Abrechnungsintervall) werden Zwischenrechnungen gebildet + (DifferContingentInterval.headMinorToContract/headMajorToContract/ + interimMajorToContract) und Interimskontingente ergänzt (AddInterimContingent); + Restmitnahme entfällt bei Wechsel der Kontingentart; manuelle/Bedarfsberechnung + setzt NachBerechnung-Kennzeichen. +Aussage: Die Software soll Kontingente je Abrechnungslauf periodengerecht buchen, + Überbuchung/Restmitnahme regeln und bei abweichenden Kontingentintervallen + Zwischenrechnungen mit korrekten Buchungszeiträumen erzeugen. +Ergebnis: Kontingentverbrauch und -guthaben stimmen über beliebige Intervallkombinationen. +Belege: + - [PRIMÄR] BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.Contracts.cs:1036-1245 (AddInterimContingent, StoreBookedContingent) - Begründung: durchsetzende Kontingentmechanik. +Prüfidee: Jahresvertrag mit Monatskontingent ohne Überbuchung: 12 Zwischenbuchungen; mit Wechsel der Kontingentart entfällt die Restmitnahme. +Tracelinks: SyRS-010, SyRS-011 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - komplexeste Abrechnungsregel; im Zielsystem mit Testfällen absichern. +Status: belegt +``` + +``` +ID: SwRS-023 +Titel: Beleg-Log für Kontingentfeldänderungen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Beleglogik +Vorbedingung: Vertrag mit Kontingent wird geändert. +Fakt: WriteReceiptLogs vergleicht elf Kontingentfelder (Art, Wert, Mindestbestellwert, + Ausgleichsartikel, abweichende Intervalle, verbrauchte Stunden/Beträge …) mit der + Vorversion und schreibt je Änderung einen typisierten Logeintrag. +Aussage: Die Software soll jede Änderung an Kontingentfeldern einzeln mit Alt-/Neuwert + protokollieren. +Ergebnis: Kontingentänderungen sind revisionsfähig nachvollziehbar. +Belege: + - [PRIMÄR] BL/Sales/Receipts/ReceiptBL.cs:10313-10353 - Begründung: durchsetzende Feldvergleiche. +Prüfidee: Die Änderung des Kontingentwerts erzeugt genau einen Logeintrag mit beiden Werten. +Tracelinks: SyRS-009, SyRS-022 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Nachvollziehbarkeit. +Status: belegt +``` + +``` +ID: SwRS-024 +Titel: Klickzähler-Historie je Rechnungsposition +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertragsabrechnung +Vorbedingung: Klickabrechnung fakturiert Zählerstände. +Fakt: UpdClickCounterHistory verknüpft die Zählerhistorie bis zum letzten Eintragsdatum + mit der erzeugten Rechnungsposition (RechPosI3D); der Storno setzt die Verknüpfung + zurück (ResetDeviceClickCounter); Zählerimporte können deaktiviert werden + (DeactivateCounterImport/DeactivateCounterState mit Benutzerkontext). +Aussage: Die Software soll abgerechnete Zählerstände fest mit der Rechnungsposition + verknüpfen und diese Verknüpfung beim Storno wieder lösen. +Ergebnis: Jeder Zählerstand ist höchstens einmal abgerechnet; Stornos machen ihn erneut abrechenbar. +Belege: + - [PRIMÄR] BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.Contracts.cs:1248-1256; BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs:259 - Begründung: Verknüpfung und Rücksetzung implementiert. +Prüfidee: Nach Abrechnung trägt die Zählerhistorie die RechPos-Referenz; nach Storno ist sie leer. +Tracelinks: SyRS-011, SwRS-016 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Einmalabrechnung. +Status: belegt +``` + +``` +ID: SwRS-025 +Titel: Nummernvergabe: Compare-and-Swap plus Kollisionsprüfung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Nummernvergabe +Vorbedingung: Nummer wird angefordert. +Fakt: FindNextNumber zählt vom aktuellen Stand in Intervallschritten hoch und prüft je + Kandidat per COUNT(*) die Zieltabelle (Sonderfälle: zusätzlich Kunden- bzw. + Kreditor-Tabelle); GetNextNumber reserviert per bedingtem UPDATE (WHERE + Current=alterWert) und wiederholt bei Fehlschlag; Vergleiche erfolgen je + Nummernkreis numerisch oder als String. +Aussage: Die Software soll freie Nummern durch Kollisionsprüfung in der Zieltabelle finden + und die Reservierung über Compare-and-Swap gegen parallele Vergaben absichern. +Ergebnis: Nummern sind kollisionARM und parallel sicher vergeben. +Belege: + - [PRIMÄR] BL/Administration/Company/NumberGroupBL.cs:62-134 - Begründung: durchsetzender Vergabealgorithmus. +Prüfidee: Simulierte parallele Vergabe liefert disjunkte Nummern; eine manuell belegte Nummer wird übersprungen. +Tracelinks: SyRS-023 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Vergabesicherheit; Hinweis: keine Lückenlosigkeitsgarantie (übersprungene Nummern), im Zielsystem bewerten. +Status: belegt +``` + +## Zahlungsverkehr und FiBu + +``` +ID: SwRS-026 +Titel: SEPA-Formatvarianten und Mandatssequenz-Fortschreibung +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Zahlungsverkehr +Vorbedingung: SEPA-Export läuft. +Fakt: Unterstützte Formate: Sepa0080101, Sepa0080302, Sepa0080102, Sepa00800102GBIC3, + Sepa00800108GBIC4 (pain.008-Varianten); ExportDirectDebitType unterscheidet + Lastschrift (Basic) und Abbuchung (Company); nach Nutzung wird die Bankverbindung + fortgeschrieben: First→Recurrent, Last/Single→ValidTo=heute, sonst + ValidTo=heute+2 Jahre; LastUsed wird gesetzt. +Aussage: Die Software soll SEPA-Dateien in den fünf implementierten pain.008-Varianten + erzeugen und die Mandatssequenz sowie die Mandatsgültigkeit bei jeder Nutzung nach + den SEPA-Regeln fortschreiben. +Ergebnis: Folgeeinzüge verwenden automatisch die korrekte Sequenz (FRST→RCUR); ungenutzte Mandate verfallen nach 2 Jahren. +Belege: + - [PRIMÄR] BL/DataExchange/PaymentTransactions/PaymentTransactionBL.cs:177-191 (Formatauswahl), 347-359 (RefreshBankInformation) - Begründung: durchsetzende Format- und Mandatslogik. +Prüfidee: Nach dem ersten Einzug steht die Bankverbindung auf Recurrent; ValidTo liegt 2 Jahre in der Zukunft. +Tracelinks: SyRS-073, SyRS-077 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - SEPA-Compliance; Formatliste aktualisieren. +Status: belegt +``` + +``` +ID: SwRS-027 +Titel: SEPA-Exportfolgen und Rücknahme im Detail +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Zahlungsverkehr +Vorbedingung: Export bzw. Rücknahme wird ausgeführt. +Fakt: Je exportierter Rechnung werden in einer Transaktion gesetzt: Export-Flag + (SetInvoiceAsExported), optional Status bezahlt ("Abschluss über SEPA Export" je + Einstellung PaymentTransactionCloseInvoiceAfterExport), IncomingPaymentLog mit + Beträgen, Zahler-IBAN, Empfänger-IBAN und Lognummer; die Rücknahme + (ResetInvoiceExportedFlag) überspringt bereits zurückgegebene Einträge, setzt + IsDebitCreated zurück, öffnet die Rechnung (Status 1), reduziert PayedAmount + (nicht unter 0) und schreibt einen Wiedereröffnungs-Logeintrag mit Benutzer. +Aussage: Die Software soll Export und Rücknahme als transaktionale Statusübergänge mit + vollständigem Protokoll (Beträge, IBANs, Benutzer) implementieren. +Ergebnis: Der Zahlungsstatus jeder Rechnung ist jederzeit aus den Logs rekonstruierbar. +Belege: + - [PRIMÄR] BL/DataExchange/PaymentTransactions/PaymentTransactionBL.cs:233-345 - Begründung: durchsetzende Folgen- und Rücknahmelogik. +Prüfidee: Rücknahme einer exportgeschlossenen Rechnung öffnet sie, PayedAmount sinkt um den Logbetrag, ein Logeintrag mit Benutzerkürzel entsteht. +Tracelinks: SyRS-073, SyRS-071 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Zahlungsintegrität. +Status: belegt +``` + +``` +ID: SwRS-028 +Titel: Onlinebanking-Zuordnung: Rechnungsnummern-Regex aus Nummernkreis +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Onlinebanking +Vorbedingung: Kontoumsatz mit Verwendungszweck liegt vor. +Fakt: Die Rechnungsnummernsuche baut den Regex aus den Ziffernlängen von RangeFrom und + Current des Rechnungsnummernkreises (Default 5-6 Stellen) und verlangt + Nicht-Ziffern um den Treffer; die Kundenerkennung nutzt Absender-IBAN gegen + Bankverbindungen und Absendernamen; die dritte Stufe matcht Rechnungen über den + Betrag; die Zuordnungsheuristik wird am Umsatz gespeichert. +Aussage: Die Software soll die Rechnungsnummernerkennung dynamisch aus dem Nummernkreis + ableiten und die verwendete Heuristik am Umsatz dokumentieren. +Ergebnis: Auch nach Nummernkreiswechsel erkennt die Zuordnung gültige Rechnungsnummern. +Belege: + - [PRIMÄR] BL/Finances/OnlineBanking/OnlineBankingAccountTransactionsBL.cs:553-643 (GetInvoiceNumberGroups, Regex-Konstruktion, Heuristik-Kaskade) - Begründung: durchsetzender Algorithmus. +Prüfidee: Bei Nummernkreis 10000-99999 erkennt der Regex genau 5-stellige Zahlen im Verwendungszweck. +Tracelinks: SyRS-072 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Zuordnungsqualität. +Status: belegt +``` + +``` +ID: SwRS-029 +Titel: DATEV-ASCII-Export im Format EXTF 700 +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: FiBu-Export +Vorbedingung: DATEV-ASCII-Export ist konfiguriert. +Fakt: Der Export schreibt den EXTF-Header in Formatversion 700 (DATEV-Format ab 2024, + 31 Headerfelder für Debitoren/Kreditoren, 254 Felder), unterscheidet + Buchungsstapel und Debitoren/Kreditoren und erzwingt das Dateinamenspräfix EXTF_. +Aussage: Die Software soll DATEV-ASCII-Dateien im EXTF-Format 700 mit korrektem Header und + Dateinamenskonvention erzeugen. +Ergebnis: DATEV importiert die Dateien ohne Formatfehler. +Belege: + - [PRIMÄR] src/backend/Centron.Gateway/DataExchange/BookKeeping/DatevAscii/BookKeepingExportDatevAscii.cs:991-1029 - Begründung: durchsetzende Formatimplementierung. +Prüfidee: Die Exportdatei beginnt mit "EXTF";700 und heißt EXTF_*.csv. +Tracelinks: SyRS-076 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - DATEV-Konformität. +Status: belegt +``` + +``` +ID: SwRS-030 +Titel: Mahnstufenmodell und zweistufige Mahnsperren +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Mahnwesen +Vorbedingung: Mahnlauf läuft. +Fakt: DunningLevel kennt None und Level1-3; DunningStopActive wird je Kunde und je + Rechnung berechnet (GetDunningStopActive); Kundensicht filtert Rechnungen und + Gutschriften getrennt; nach Manipulationen wird die Kundenliste erneut gefiltert, + damit Zählstände stimmen. +Aussage: Die Software soll drei Mahnstufen je Rechnung führen und Mahnsperren zweistufig + (Kunde, Rechnung) auswerten, bevor gemahnt wird. +Ergebnis: Keine Mahnung an gesperrte Kunden/Rechnungen; Stufen steigen definiert. +Belege: + - [PRIMÄR] BL/Sales/Receipts/Invoices/Dunning/DunningBL.cs:88-112; src/backend/Centron.Interfaces/.../DunningLevel.cs - Begründung: durchsetzende Sperr-/Stufenlogik. +Prüfidee: Kunde gesperrt → keine seiner Rechnungen im Lauf; nur Rechnung gesperrt → übrige Rechnungen des Kunden erscheinen. +Tracelinks: SyRS-074 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Mahnsteuerung. +Status: belegt +``` + +``` +ID: SwRS-031 +Titel: Zahlungseingangs-Löschung mit Belegrückrechnung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Zahlungslogik +Vorbedingung: Zahlungseingänge sollen gelöscht werden. +Fakt: DeleteIncomingPayment gruppiert die zu löschenden Zahlungen je Rechnung, ruft je + Gruppe UpdateReceiptIsPaid mit negativer Summe (multipliziert mit dem + Belegwährungsfaktor) und dem Text "Zahlungseingang gelöscht" auf und löscht erst + dann die Zahlungssätze; per Flag (DontChangeInvoice) kann die Belegkorrektur + unterdrückt werden. +Aussage: Die Software soll beim Löschen von Zahlungseingängen die Rechnungssalden währungsrichtig + zurückrechnen, bevor die Zahlungssätze entfernt werden. +Ergebnis: Rechnungssaldo und Zahlungshistorie bleiben konsistent. +Belege: + - [PRIMÄR] BL/Finances/Payments/PaymentsBL.cs:38-78 - Begründung: durchsetzende Rückrechnung. +Prüfidee: Löschen zweier Zahlungen (60+40) einer Fremdwährungsrechnung reduziert PaidFC um 100×Kursfaktor. +Tracelinks: SyRS-071 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Saldenkonsistenz. +Status: belegt +``` + +## Sicherheit und Berechtigungen (Risikoschwerpunkt) + +``` +ID: SwRS-032 +Titel: Passwortspeicherung als ungesalzenes SHA1 (Ist-Zustand) +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Authentifizierung +Vorbedingung: Benutzer-/Web-Account-Passwort wird gesetzt oder geprüft. +Fakt: AppUser- und WebAccount-Passwörter werden mit SHA1Decoder.GetDecodedSHA1String + gehasht und per String-Vergleich geprüft; ein TODO-Kommentar dokumentiert das + fehlende Salt ("the password should be salted!!!"); die Passwortprüfung sucht den + Benutzer per Name+Hash in einer Query. +Aussage: Das System speichert Passwörter derzeit als ungesalzene SHA1-Hashes (dokumentierter + Ist-Zustand). Für die Neuimplementierung ist ein modernes Verfahren (Argon2/bcrypt, + gesalzen) verbindlich; die Anforderung dokumentiert die abzulösende Mechanik und die + Migrationsnotwendigkeit aller Passworthashes. +Ergebnis: Bestandshashes sind identifiziert und im Zielsystem zu migrieren (Re-Hash beim Login). +Belege: + - [PRIMÄR] BL/Administration/Logins/Auth/BasicAuthenticator.cs:46-50 (SHA1-Hash + TODO-Salt, Query Name+Passwort) - Begründung: durchsetzende Prüfstelle. + - [PRIMÄR] BL/Administration/Logins/UsersBL.cs:65-113 und WebAccountBL.cs:56 (SHA1 für Änderung/Weblogin) - Begründung: weitere durchsetzende Stellen. +Prüfidee: Der gespeicherte Hash zweier Benutzer mit gleichem Passwort ist identisch (Beleg für fehlendes Salt); im Zielsystem müssen identische Passwörter verschiedene Hashes ergeben. +Tracelinks: SyRS-078, SyRS-126 +Konsolidierung: nein +Übernahmewürdigkeit: veraltet - kryptografisch überholtes Verfahren; funktional (Passwortlogin) übernehmen, technisch ersetzen. +Status: belegt +``` + +``` +ID: SwRS-033 +Titel: Dreifache Kontodeaktivierungslogik +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Authentifizierung +Vorbedingung: Login-Versuch. +Fakt: ValidateAppUser deaktiviert bei: (a) IsAccountDisabled-Checkbox, (b) heutigem Datum + innerhalb [AccountDisabledFromDate, AccountDisabledToDate] (jeweils auch einseitig), + (c) inaktivem Mitarbeiter laut Ein-/Austrittsterminen (IsActiveEmployeeCompact); + jeder Zweig schreibt einen spezifischen Logeintrag; die Fehlermeldung ist einheitlich + "Mitarbeiterkonto wurde deaktiviert". +Aussage: Die Software soll die drei Deaktivierungsquellen unabhängig prüfen, intern + differenziert protokollieren und nach außen eine einheitliche Meldung liefern. +Ergebnis: Deaktivierungsgründe sind im Log unterscheidbar, ohne Angreifern Details zu verraten. +Belege: + - [PRIMÄR] BL/Administration/Logins/Auth/Authenticator.cs:157-217 - Begründung: durchsetzende Prüfkaskade. +Prüfidee: Konto mit nur Von-Datum in der Vergangenheit bleibt dauerhaft gesperrt; Logeintrag nennt das Datum. +Tracelinks: SyRS-079 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Offboarding-Regeln. +Status: belegt +``` + +``` +ID: SwRS-034 +Titel: Sitzungsticket-Lebensdauern und -verlängerung +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Sitzungsverwaltung +Vorbedingung: Ticket existiert. +Fakt: Konstanten: 30 Minuten Standard, 5 Minuten MonitoringConnector, 1440 Minuten für + 24h-Anwendungen; konfigurierbare Dauer mit erzwungenem Minimum 30; die + Verlängerung (RefreshTicketExpireDate) schreibt nur, wenn >5 Minuten Differenz; + abgelaufene Tickets werden gelöscht (DeleteExpiredTickets); pro Anwendung/Benutzer/ + Maschine wird ein bestehendes Ticket wiederverwendet. +Aussage: Die Software soll Ticketlebensdauern anwendungsartspezifisch (30 min Standard, + 5 min Monitoring, 24 h Sonderfälle, konfigurierbar ≥30 min) verwalten, gleitend + verlängern und abgelaufene Tickets löschen. +Ergebnis: Sitzungen enden nach Inaktivität; aktive Sitzungen bleiben ohne Neuanmeldung gültig. +Belege: + - [PRIMÄR] BL/Administration/Logins/TicketBL.cs:26-156 - Begründung: durchsetzende Lebensdauerlogik. +Prüfidee: Nach 31 Minuten Inaktivität ist der Aufruf abgewiesen; regelmäßige Aufrufe halten das Ticket gültig. +Tracelinks: SyRS-078 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Sitzungsökonomie. +Status: belegt +``` + +``` +ID: SwRS-035 +Titel: Floating-Lizenzzählung über aktive Tickets +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Lizenzprüfung +Vorbedingung: Login mit lizenzpflichtiger Anwendung. +Fakt: CheckLicense vergleicht GetTicketCount(license, LicenseUsageKind, user) mit der + Lizenzanzahl; bestehende Tickets desselben Benutzers werden wiederverwendet, bevor + neu gezählt wird; die Delphi-Altversion umgeht die Versionsprüfung + (TryFixCentronDelphiVersionNumber, ausführlicher Begründungskommentar). +Aussage: Die Software soll gleichzeitige Nutzungen als aktive Tickets zählen (Floating- + Lizenz) und Wiederanmeldungen desselben Benutzers nicht doppelt zählen. +Ergebnis: Lizenzzählung entspricht der realen gleichzeitigen Nutzung. +Belege: + - [PRIMÄR] BL/Administration/Licensing/LicenseManager.cs:276-330 - Begründung: durchsetzende Zählung inkl. Delphi-Ausnahme. +Prüfidee: Wiederholter Login desselben Benutzers auf derselben Maschine verbraucht keine zweite Lizenz. +Tracelinks: SyRS-082 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Zähllogik; Delphi-Ausnahme ist Workaround und entfällt. +Status: belegt +``` + +``` +ID: SwRS-036 +Titel: Anwendungsbezogene Pflicht- und Verbotsrechte beim Login +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Authentifizierung +Vorbedingung: Login einer Anwendung (ApplicationKind). +Fakt: ValidateRights verweigert das Ticket, wenn die Anwendung ein DisallowingRight + definiert und der Benutzer es besitzt, oder ein RequiredRight definiert und der + Benutzer es nicht besitzt; die Meldungen sind lokalisiert (LoginDisallowed/ + RightsMissing). +Aussage: Die Software soll je Anwendung ein erforderliches und/oder ein ausschließendes + Benutzerrecht prüfen, bevor ein Ticket ausgestellt wird. +Ergebnis: Anwendungszugang ist über Rechte je Anwendung steuerbar. +Belege: + - [PRIMÄR] BL/Administration/Logins/Auth/Authenticator.cs:68-86 (ValidateRights) - Begründung: durchsetzende Login-Rechteprüfung. +Prüfidee: Ein Benutzer mit gesetztem Verbotsrecht der Anwendung X erhält für X kein Ticket, für Y schon. +Tracelinks: SyRS-078, SyRS-080 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - differenzierter Anwendungszugang. +Status: belegt +``` + +``` +ID: SwRS-037 +Titel: 2FA-Parametrik: Gültigkeitsdauer, Geräteerinnerung, Validatoren +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Authentifizierung +Vorbedingung: 2FA global aktiv (WebServiceConfig) und je Benutzer aktiviert. +Fakt: HasToValidateTwoFactor: kein 2FA wenn benutzerseitig deaktiviert; erzwungen bei + requireTwoFactorAuth; Gültigkeitsdauer je Benutzer oder global + (TwoFactorValidDurationInDays, ≤0 = immer); Erinnerung erfolgt je + Anwendung+Maschine (RememberLogin/GetLastLogin); Validatoren: E-Mail-Code + (EmailTwoFactorValidator) und RADIUS (RadiusTwoFactorValidator mit eigenem + Paketparser); Timeout liefert MessageCode Canceled. +Aussage: Die Software soll die 2FA-Pflicht aus globaler Aktivierung, Benutzereinstellung, + Gültigkeitsdauer und Geräteerinnerung ableiten und E-Mail- sowie RADIUS-Validierung + unterstützen. +Ergebnis: 2FA-Aufwand entspricht exakt der Konfiguration. +Belege: + - [PRIMÄR] BL/Administration/Logins/TwoFactor/TwoFactorAuthBL.cs:33-120; RadiusTwoFactorValidator.cs, EmailTwoFactorValidator.cs - Begründung: durchsetzende 2FA-Kaskade. +Prüfidee: Wechsel der Maschine erzwingt erneute 2FA trotz laufender Gültigkeitsdauer. +Tracelinks: SyRS-081 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - 2FA-Regelwerk; TOTP/Passkeys im Zielsystem ergänzen. +Status: belegt +``` + +``` +ID: SwRS-038 +Titel: Rechte-Datenmodell: Sichbenu/Sichmemb/Sichtrus mit additiven Gruppen +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Rechteprüfung +Vorbedingung: keine +Fakt: Benutzer (Sichbenu) sind über Sichmemb Gruppen zugeordnet; Gruppen besitzen Rechte + über Sichtrus; die Rechteermittlung vereinigt alle Gruppenrechte (Distinct); 750 + Rechtekonstanten sind hierarchisch benannt (UserRightsConst.Sales.Customer.…); + eine Standard-Rechtestruktur ist als Datei hinterlegt (ResetDefaultRightGroups). +Aussage: Die Software soll Rechte als additive Vereinigung aller Gruppenrechte eines + Benutzers ermitteln (keine Negativrechte auf Datenebene) und eine + Standardgruppenstruktur wiederherstellen können. +Ergebnis: Rechteermittlung ist mengenbasiert und nachvollziehbar. +Belege: + - [PRIMÄR] BL/Administration/Rights/AppRightsBL.cs:63-111 (GetRightsFromCurrentUser vereinigt Gruppen; SQL-Join), 563-643 (ResetDefaultRightGroups) - Begründung: durchsetzendes Modell. +Prüfidee: Ein Recht in irgendeiner Gruppe des Benutzers genügt; der Entzug in einer von zwei Gruppen entzieht das Recht nicht. +Tracelinks: SyRS-080 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Modell; einschränkende Rechte (siehe SyRS-058) im Zielsystem als explizites Konzept. +Status: belegt +``` + +``` +ID: SwRS-039 +Titel: Getrenntes Web-Rechtesystem für Web-Accounts +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Rechteprüfung (Portal) +Vorbedingung: Web-Account meldet sich an. +Fakt: Web-Accounts erhalten Rechte aus WebAccountsRights/WebRights (mit Kategorien und + einem Kundenadministrations-Recht), getrennt vom Mitarbeiter-Rechtesystem; die + Prüfung erfolgt über CheckWebRightsFromUser bzw. GetAllWebRightsFromWebAccount. +Aussage: Die Software soll Portalrechte in einem eigenen Rechtekatalog führen und niemals + Mitarbeiterrechte auf Web-Accounts anwenden. +Ergebnis: Portalberechtigungen sind unabhängig und begrenzt. +Belege: + - [PRIMÄR] BL/Administration/Rights/AppRightsBL.cs:113-130, 679-691; BL/Administration/Logins/WebAccountBL.cs:141-146, 579-599 - Begründung: getrennte Prüfpfade. +Prüfidee: Ein Web-Recht schaltet nur Portalfunktionen; interne Rechte des Kontakts existieren nicht. +Tracelinks: SyRS-126 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - saubere Trennung intern/extern. +Status: belegt +``` + +``` +ID: SwRS-040 +Titel: API-Token: CSPRNG-Erzeugung, SHA-256-Hash, Einmalanzeige +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Token-Verwaltung +Vorbedingung: Token wird erstellt/validiert. +Fakt: GenerateSecureToken erzeugt 48 alphanumerische Zeichen aus + RandomNumberGenerator-Bytes; HashToken bildet SHA-256 (Hex); gespeichert wird nur + der Hash, der Klartext wird einmalig zurückgegeben; Kollisibilität wird geprüft und + ggf. neu erzeugt; Validierung sucht per Hash, prüft Aktiv/Ablauf und loggt + Fehlversuche mit IP. +Aussage: Die Software soll API-Token kryptografisch zufällig erzeugen, ausschließlich als + SHA-256-Hash speichern, nur einmal im Klartext ausgeben und jede Validierung + inklusive Fehlversuchen protokollieren. +Ergebnis: Ein DB-Leak legt keine nutzbaren Token offen. +Belege: + - [PRIMÄR] BL/Administration/AccessTokens/AccessTokenBL.cs:155-166, 387-398, 457-488 - Begründung: durchsetzende Kryptomechanik. +Prüfidee: In der DB existiert nur ein 64-Zeichen-Hexhash; der Klartext ist nach der Erstellung nicht mehr abrufbar. +Tracelinks: SyRS-090 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Vorbild für die Passwort-Ablösung (SwRS-032). +Status: belegt +``` + +``` +ID: SwRS-041 +Titel: Passwortregeln: Mindestlänge je Benutzer, Wechselsperren, Änderungsdatum +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Benutzerverwaltung +Vorbedingung: Passwort wird geändert. +Fakt: IsValidAppUserPassword erzwingt die je Benutzer hinterlegte Mindestlänge + (PasswordMinLength>0); unverändertes Passwort erzeugt eine Warnung; + LastPasswordChangedDate wird gesetzt; Benutzer mit externer Authentifizierung + (Windows/OpenIdConnect bzw. systemweite AD/OIDC-Methode) können das + c-entron-Passwort nicht ändern; die eigene Änderung verlangt das korrekte aktuelle + Passwort. +Aussage: Die Software soll Passwortänderungen gegen benutzerspezifische Mindestlänge, + aktuelles Passwort und externe Authentifizierung prüfen und das Änderungsdatum + fortschreiben. +Ergebnis: Passwortpflege folgt den Kontoregeln; extern authentifizierte Konten bleiben passwortfrei. +Belege: + - [PRIMÄR] BL/Administration/Logins/UsersBL.cs:56-130 (ChangeOwnPassword, UpdatePassword, IsValidAppUserPassword) - Begründung: durchsetzende Passwortregeln. +Prüfidee: Ein Entra-ID-Benutzer erhält beim Passwortwechsel die Ablehnung "für Benutzer mit externer Anmeldung … nicht geändert". +Tracelinks: SyRS-078 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Passwortrichtlinie; im Zielsystem um Komplexitätsregeln erweitern. +Status: belegt +``` + +``` +ID: SwRS-042 +Titel: Web-Login: durchgehend aktive Beziehungskette +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Portal-Authentifizierung +Vorbedingung: Web-Login-Versuch. +Fakt: LoginWithWebAccount verlangt Status=1 des Accounts, findet Benutzer + case-insensitiv, prüft je nach Kontotyp die Kette Kontakt (State/IsActive) → + Adresse (State/IsActive) → Kunde/Account (aktiv und nicht gesperrt) und speichert + LastLoginIP/LastLoginDate. +Aussage: Die Software soll den Portal-Login nur bei vollständig aktiver Kette aus Konto, + Kontakt, Adresse und Kunde zulassen und Login-Metadaten speichern. +Ergebnis: Deaktivierung an beliebiger Stelle der Kette sperrt das Portal sofort. +Belege: + - [PRIMÄR] BL/Administration/Logins/WebAccountBL.cs:54-105 - Begründung: durchsetzende Kettenprüfung. +Prüfidee: Deaktivieren nur der Adresse verhindert den Login; Reaktivieren stellt ihn wieder her. +Tracelinks: SyRS-126 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Portalzugangslogik. +Status: belegt +``` + +## Web und Portal + +``` +ID: SwRS-043 +Titel: WebCart-Sortimentsregel: nur Artikel mit aktiven Sonderpreisen +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Portal-Shop +Vorbedingung: Web-Account ruft den Shop auf. +Fakt: GetWebCartArticles ersetzt die übergebene Kundennummer bei Web-Account-Logins durch + die des Accounts (kein Fremdzugriff), liefert bei fehlenden aktiven Sonderpreisen + eine leere Liste und beschränkt die Suche auf Kundenartikel + (OnlyShowCustomerArticles). +Aussage: Die Software soll das Shop-Sortiment eines Web-Accounts strikt aus dessen aktiven + Sonderpreisen ableiten und Fremdkunden-Zugriffe durch Überschreiben der Kunden-ID + verhindern. +Ergebnis: Kein Web-Account sieht Artikel oder Preise eines anderen Kunden. +Belege: + - [PRIMÄR] BL/WebServices/Sales/Receipts/ArticleSearch/ArticleSearchWebServiceBL.cs:71-99 - Begründung: durchsetzende Sortiments- und Isolationsregel. +Prüfidee: Ein manipulierter Request mit fremder Kundennummer liefert dennoch nur das eigene Sortiment. +Tracelinks: SyRS-121 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Mandantenisolation im Portal. +Status: belegt +``` + +``` +ID: SwRS-044 +Titel: WebReceipt-Zustandsautomat der Online-Freigabe +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Portal-Freigabe +Vorbedingung: Beleg ist online gestellt. +Fakt: WebReceiptState kennt neun Zustände: InProcess, AcceptFullWebReceipt, + AcceptWebReceiptWithChangeRequests, Rejected, SendToCustomer, FirstLoaded, + WebOfferSign, WebReceiptShutDown, WebOfferSignedWithoutSignature. +Aussage: Die Software soll die Online-Freigabe über genau diese Zustände abbilden, + einschließlich der Unterscheidung "signiert" und "ohne Unterschrift bestätigt". +Ergebnis: Der Freigabestatus ist eindeutig maschinenlesbar. +Belege: + - [PRIMÄR] src/backend/Centron.Interfaces/Sales/Receipts/WebReceipt/WebReceiptState.cs:6-26 - Begründung: kodierter Zustandsraum. +Prüfidee: Jede Kundenaktion im WebOffer führt in genau einen der neun Zustände. +Tracelinks: SyRS-122 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Freigabesemantik. +Status: belegt +``` + +## Lager und Logistik + +``` +ID: SwRS-045 +Titel: Barcode-Zustandsautomat (20 Zustände) +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Bestandslogik +Vorbedingung: Serialisierte Einheit existiert. +Fakt: BarcodeState kodiert: None, InStock, InOrder, InDeliveryList, InInvoice, InRMA, + InSendBack, InRepairInput, InRequest, InMasterDataList, LostAtStocktaking, + AssignedToOrder/DeliveryList/PickupList/Invoice/CreditVoucher, ReplacementArticle, + ExchangedArticle, Deactivated, ManuallyBookedOut; "Assigned"-Zustände unterscheiden + Reservierung von endgültiger Belegbindung. +Aussage: Die Software soll den Verbleib jeder serialisierten Einheit über genau diesen + Zustandskatalog abbilden und Reservierung ("Assigned…") von Verarbeitung ("In…") + unterscheiden. +Ergebnis: Bestands- und Belegsicht auf Seriennummern sind konsistent. +Belege: + - [PRIMÄR] src/backend/Centron.Interfaces/Warehousing/BarcodeState.cs:5-30 - Begründung: kodierter Zustandsraum. +Prüfidee: Zuweisung zu einem Lieferschein setzt AssignedToDeliveryList; dessen Buchung setzt InDeliveryList. +Tracelinks: SyRS-067 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Lebenszyklusmodell. +Status: belegt +``` + +``` +ID: SwRS-046 +Titel: ScanBarcode-Regel: Barcodes steuern den Bestand nur wenn aktiv +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Bestandslogik +Vorbedingung: Bestandsbuchung über Barcodes. +Fakt: IncreaseArticleStock bucht nur, wenn der Artikel ScanBarcode aktiv hat; sonst sind + Barcodes rein informativ ("additionally") und beeinflussen den Bestand nicht. +Aussage: Die Software soll Barcodebuchungen nur bei aktiv barcodegeführten Artikeln + bestandswirksam machen. +Ergebnis: Informative Barcodes verfälschen den Bestand nicht. +Belege: + - [PRIMÄR] BL/Warehousing/StockManagement/ArticleStockBL.cs:52-61 (ScanBarcode-Prüfung mit Kommentar) - Begründung: durchsetzende Regel. +Prüfidee: Barcode-Zugang auf einem Artikel ohne ScanBarcode ändert den Bestand nicht. +Tracelinks: SyRS-064, SyRS-067 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Datenqualität Bestand. +Status: belegt +``` + +## Service-Details + +``` +ID: SwRS-047 +Titel: Ticket-Pflichtfeldkaskade und Sondertickets +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Ticketlogik +Vorbedingung: Ticket wird gespeichert. +Fakt: Der Kunde ist immer Pflicht; für Sondertickets (IsSpecialHelpdesk) enden die + Prüfungen dort; sonst folgen einstellungsabhängig Priorität, Typ und + Hauptkategorie; alle Fehler werden gesammelt in einer Meldung zurückgegeben + (MandatoryFieldsNotFilled); beim Schließen kann die Pflicht per Parameter + ignoriert werden (ignoreMandatoryFieldsOnClose). +Aussage: Die Software soll Pflichtfelder kaskadiert prüfen, Sondertickets von erweiterten + Pflichten ausnehmen und alle Verstöße gesammelt melden. +Ergebnis: Benutzer sehen alle fehlenden Felder auf einmal. +Belege: + - [PRIMÄR] BL/Sales/Support/HelpdeskBL.cs:658-702; HelpdeskCloseBL.cs:120 (ignoreMandatoryFieldsOnClose) - Begründung: durchsetzende Kaskade. +Prüfidee: Fehlende Priorität und Kategorie erscheinen gemeinsam in einer Fehlermeldung. +Tracelinks: SyRS-046 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Erfassungsführung. +Status: belegt +``` + +``` +ID: SwRS-048 +Titel: Ticketabschluss-Transaktionsfolge +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Ticketlogik +Vorbedingung: Abschluss angefordert. +Fakt: Reihenfolge in CloseHelpdesk: Abschlussstatus laden → Ticket laden → CanClose- + Prüfung → ToDos löschen → Status+ClosedAt setzen → speichern → bei Erfolg: + Nexus-Benachrichtigung, Historieneintrag (HelpdeskHistoryType.Close), + Kundenaktivität; Fehler in frühen Schritten brechen ohne Statusänderung ab. +Aussage: Die Software soll den Abschluss in dieser Reihenfolge ausführen und Folgeaktionen + nur nach erfolgreichem Speichern auslösen. +Ergebnis: Kein halb geschlossenes Ticket; Folgeaktionen nur bei Erfolg. +Belege: + - [PRIMÄR] BL/Sales/Support/HelpdeskCloseBL.cs:120-157 - Begründung: durchsetzende Sequenz. +Prüfidee: Scheitert das Speichern, existieren weder Historieneintrag noch Aktivität. +Tracelinks: SyRS-047 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Prozesskonsistenz. +Status: belegt +``` + +``` +ID: SwRS-049 +Titel: Eskalationsstufenberechnung mit Arbeitszeitfenstern +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Eskalationslogik +Vorbedingung: Eskalationslauf prüft ein Ticket. +Fakt: Je Stufe (1-3) wird die Referenzzeit aus der letzten Eskalation bzw. dem Start + (Escalation0On…Escalation2On) und die Wartezeit (WaitHourEsc1-3) bestimmt; + Arbeitszeit pro Tag ergibt sich aus WorkTimeFrom/To (sonst 24h); Samstage/Sonntage + zählen nur bei aktivierten Flags (SetNextEscDay überspringt sie); ungültige + Zeitfenster (From>=To) verhindern die Eskalation; der Testmodus begrenzt auf 100 + Prüfungen und einen Versand. +Aussage: Die Software soll Eskalationsfälligkeiten in Arbeitsstunden je Stufe berechnen und + Wochenendtage nur bei entsprechender Aktivierung einbeziehen. +Ergebnis: Eskalationszeitpunkte entsprechen den Servicezeiten. +Belege: + - [PRIMÄR] BL/Sales/Support/Escalation/EscalationBL.cs:300-332 (GetWortTime, SetNextEscDay, ShouldEscalated) - Begründung: durchsetzende Stufenrechnung. +Prüfidee: Wartezeit 8h bei Arbeitszeit 8-16 Uhr eskaliert am Folgearbeitstag, nicht nach 8 Kalenderstunden. +Tracelinks: SyRS-048 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - SLA-Berechnung. +Status: belegt +``` + +``` +ID: SwRS-050 +Titel: RMA-Eindeutigkeit per Unique Clustered Index +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Datenbank +Vorbedingung: RMA wird angelegt. +Fakt: CI_RMA_HelpdeskI3D ist ein UNIQUE CLUSTERED INDEX auf Rma.HelpdeskI3D. +Aussage: Die Software soll die 1:1-Beziehung RMA↔Ticket durch einen eindeutigen Index auf + DB-Ebene erzwingen. +Ergebnis: Doppelte RMAs je Ticket sind technisch ausgeschlossen. +Belege: + - [PRIMÄR] SSMS_DB_SCHEMA.sql:4176-4180 - Begründung: DB-Constraint als durchsetzende Stelle. +Prüfidee: Zweite RMA zum selben Ticket → Unique-Index-Verletzung. +Tracelinks: SyRS-054 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Datenintegrität. +Status: belegt +``` + +## Querschnitt und Infrastruktur + +``` +ID: SwRS-051 +Titel: Eindeutigkeit der Kunden-/Lieferantennummern auf DB-Ebene +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Datenbank +Vorbedingung: Account wird gespeichert. +Fakt: IX_AccountCustomers_UniqueNumber und IX_AccountSuppliers_UniqueNumber erzwingen + eindeutige Nummern; die Nummernvergabe prüft zusätzlich die Alt-Tabellen Kunden/ + Kreditor. +Aussage: Die Software soll Kunden- und Lieferantennummern per Unique Constraint erzwingen + und die Vergabe gegen die Alt-Tabellen prüfen. +Ergebnis: Nummern sind über Alt- und Neubestand eindeutig. +Belege: + - [PRIMÄR] SSMS_DB_SCHEMA.sql:3784, 3854 - Begründung: DB-Constraints. + - [PRIMÄR] BL/Administration/Company/NumberGroupBL.cs:114-131 (Sonderfälle Kunden/Kreditor) - Begründung: Vergabeprüfung. +Prüfidee: Insert mit vorhandener Nummer schlägt fehl; die Vergabe überspringt Alt-Nummern. +Tracelinks: SyRS-036, SyRS-035, SyRS-023 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Stammdatenintegrität. +Status: belegt +``` + +``` +ID: SwRS-052 +Titel: DSGVO-Selektionskategorien der Bereinigung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: DSGVO-Modul +Vorbedingung: Bereinigungsstatistik wird angefordert. +Fakt: Kategorien: Kunden ohne Aktion seit Datum (mit Kundenart-/Objektart-/ + Rechnungsdatumsfiltern), gelöschte Kunden, CRM-Einträge älter als Datum (Tabelle + Taetigkeiten), Belege älter als Datum je Belegart mit Abschlussfilter; jede + Kategorie liefert Zähltexte. +Aussage: Die Software soll die DSGVO-Bereinigung in genau diesen filterbaren Kategorien + vorschlagen und mengenmäßig ausweisen. +Ergebnis: Löschentscheidungen basieren auf transparenten Mengen. +Belege: + - [PRIMÄR] BL/Administration/DataSecurity/DataSecurityBL.cs:34-113 - Begründung: durchsetzende Selektionslogik. +Prüfidee: Die Statistik "CRM älter als X" entspricht COUNT(*) aus Taetigkeiten mit Datum. +Aussage: Die Software soll Client-Datenzugriffe über eine Interface-Schicht führen, die + wahlweise direkt auf die DB oder über den Webservice arbeitet, mit einheitlichem + Result-Fehlermodell. +Ergebnis: Derselbe Client läuft in beiden Verbindungsarten. +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Services/Logics/ (I*/BL*/WS*-Tripel, z. B. IReceiptLogic/BLReceiptLogic/WSReceiptLogic) - Begründung: Muster implementiert. + - [KONTEXT] docs/getting-started/general-structure.md - Begründung: dokumentiertes Muster. +Prüfidee: Ein Modul funktioniert identisch mit SqlServer- und Webservice-Verbindung. +Tracelinks: SyRS-127, SyRS-151 +Konsolidierung: nein +Übernahmewürdigkeit: veraltet - Direkt-DB-Zugriff des Clients entfällt im Web-Zielsystem (nur API). +Status: belegt +``` + +``` +ID: SwRS-056 +Titel: Modulfreischaltung als Doppelbedingung Recht UND Lizenz +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Client-Navigation +Vorbedingung: Client startet. +Fakt: Alle 83 Module sind mit zwei Lambdas registriert: Rechteprüfung + (Helper.HasRights(…) bzw. NoRightCheck) und Lizenzprüfung + (HasLicense(Modul-GUID) ODER HasLicense(Centron-Gesamtlizenz)). +Aussage: Die Software soll jedes Modul nur bei erfüllter Rechte- UND Lizenzbedingung laden, + wobei die Gesamtproduktlizenz Einzelmodullizenzen einschließt. +Ergebnis: Navigation ist die Schnittmenge aus Rechten und Lizenzen. +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/ModuleRegistration.cs:441-498 (Muster über alle Registrierungen) - Begründung: durchsetzende Doppelbedingung. +Prüfidee: Modul mit Lizenz, aber ohne Recht: unsichtbar; mit Recht, ohne Lizenz: unsichtbar. +Tracelinks: SyRS-151 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Freischaltlogik. +Status: belegt +``` + +``` +ID: SwRS-057 +Titel: DataQualityService: Stundentakt, Sessionisolation, Fehlerkapselung +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: Zuverlässigkeit +Akteur: Hintergrunddienst +Vorbedingung: Webservice läuft. +Fakt: Der Dienst läuft als BackgroundService in Endlosschleife mit 1-Stunden-Intervall; + jede Aufgabe nutzt eine eigene kurzlebige BLSession im using-Block, ist in + try-catch gekapselt (Logeintrag mit Aufgabennamen) und prüft zwischen Aufgaben das + Cancellation-Token. +Aussage: Die Software soll Wartungsaufgaben stündlich, je Aufgabe isoliert (Session, + Fehlerbehandlung) und abbrechbar ausführen. +Ergebnis: Einzelfehler stoppen weder Lauf noch Dienst; Shutdown ist sauber. +Belege: + - [PRIMÄR] src/webservice/Centron.Host/AspNetCore/HostedServices/DataQualityService.cs - Begründung: implementierter Dienst. + - [KONTEXT] docs/Background Service/DataQualityService.md - Begründung: dokumentierte Regeln. +Prüfidee: Eine werfende Aufgabe erzeugt einen Fehlerlog; die Folgeaufgabe läuft im selben Zyklus. +Tracelinks: SyRS-088 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - robustes Dienstmuster. +Status: belegt +``` + +``` +ID: SwRS-058 +Titel: Ressourcenbasierte Lokalisierung mit deutscher Basis +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: Benutzbarkeit (Usability) +Akteur: UI/BL-Texte +Vorbedingung: Text wird ausgegeben. +Fakt: Deutsch liegt in Basis-Resx (LocalizedStrings.resx, 2.812 Einträge in der WPF-UI), + Englisch in .en.resx; auch BL-Fehlermeldungen kommen aus LocalizedStrings; die + Doku verlangt Pflege beider Sprachen bei neuen Texten; das Nexus-Portal führt + eigene Ressourcen (WebCartResource, CountriesResource). +Aussage: Die Software soll alle Benutzertexte aus Ressourcendateien beziehen (deutsch als + Fallback-Basis) und für neue Texte beide Sprachvarianten pflegen. +Ergebnis: Kein hartkodierter Benutzertext; Sprachumschaltung wirkt vollständig. +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Resources/LocalizedStrings*.resx; src/nexus/CentronNexus/WebCart/Resource/ - Begründung: Ressourcensystem implementiert. + - [KONTEXT] docs/guides/ui/localization.md - Begründung: dokumentierte Pflicht. +Prüfidee: Ein fehlender EN-Eintrag fällt auf den DE-Text zurück statt auf einen Schlüssel. +Tracelinks: SyRS-156 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Lokalisierungsarchitektur. +Status: belegt +``` + +``` +ID: SwRS-059 +Titel: Entwicklungsschutz: Mailumleitung in Nicht-Release-Builds +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Mailversand (Entwicklung) +Vorbedingung: Nicht-Release-Build versendet Mail. +Fakt: DeveloperSecurity.Email.ValidateAddress ersetzt in Nicht-Release-Builds jede + Empfängeradresse, die nicht auf nexoware.com endet, durch test@nexoware.com; + Release-Builds sind unbeeinflusst. +Aussage: Die Software soll in Entwicklungs-Builds externe Mailempfänger automatisch durch + eine interne Testadresse ersetzen. +Ergebnis: Entwicklungs-/Testläufe erreichen niemals echte Kunden. +Belege: + - [PRIMÄR] src/backend/Centron.Common/DeveloperSecurity.cs:14-46 - Begründung: durchsetzende Ersetzungsregel. + - [KONTEXT] docs/reference/security/developer-security.md - Begründung: dokumentierte Absicht. +Prüfidee: DEBUG-Build: Mail an kunde@example.com geht an test@nexoware.com; Mail an dev@nexoware.com bleibt unverändert. +Tracelinks: SyRS-095 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Konzept auch für Staging-Umgebungen des Zielsystems. +Status: belegt +``` + +``` +ID: SwRS-060 +Titel: Mailversand-Abstraktion mit Protokollwahl und Blacklist +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Mailversand +Vorbedingung: Mail wird versendet. +Fakt: CentronMailBase abstrahiert die Protokolle SMTPMail, GraphMail und TestMail; die + Factory wählt die Implementierung; DomainBlacklistBL verwaltet gesperrte Domains; + Formatierung erfolgt über RichEdit-Export und HTML-Konverter mit + Signaturersetzung. +Aussage: Die Software soll den Mailversand hinter einer Protokollabstraktion (SMTP, Graph, + Test) kapseln und Blacklist-Domains vom Versand ausschließen. +Ergebnis: Protokollwechsel ohne Fachcodeänderung; gesperrte Domains erhalten keine Mails. +Belege: + - [PRIMÄR] BL/Mail/Protocols/ (CentronMailBase.cs, SMTPMail.cs, GraphMail.cs), BL/Mail/Factory/CentronMailFactory.cs, BL/Mail/Blacklist/DomainBlacklistBL.cs - Begründung: Abstraktion implementiert. +Prüfidee: Umschalten von SMTP auf Graph ändert nur die Konfiguration; eine geblacklistete Domain wird abgewiesen. +Tracelinks: SyRS-095 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Versandarchitektur. +Status: belegt +``` + +## Schnittstellen-Details + +``` +ID: SwRS-061 +Titel: E-Rechnungs-Erzeugung: Geltungsbereich und Namenskonvention +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: E-Rechnungslogik +Vorbedingung: Erzeugung wird angefordert. +Fakt: CreateZugferdFile lehnt Web-Account-Logins und alle Objektarten außer InvoiceClass + ab, bildet den Dateinamen aus Belegart, Nummer und Version + (GetZugferdFileName) und übergibt die kundenspezifische Leitweg-ID an den + Generator (GenerateZugferdFile mit BookkeepingReceiptKind). +Aussage: Die Software soll E-Rechnungen ausschließlich für Rechnungen interner Benutzer + erzeugen, deterministisch benennen und die Leitweg-ID des Rechnungskunden einbetten. +Ergebnis: E-Rechnungsdateien sind eindeutig zuordenbar und B2G-tauglich. +Belege: + - [PRIMÄR] BL/WebServices/Sales/Receipts/ReceiptWebServiceBL.cs:2151-2185 - Begründung: durchsetzende Erzeugungsregeln. +Prüfidee: Zwei Versionen derselben Rechnung erzeugen unterschiedlich benannte Dateien. +Tracelinks: SyRS-104 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - E-Rechnungsregeln. +Status: belegt +``` + +``` +ID: SwRS-062 +Titel: ZUGFeRD-2.1-Import mit Lieferschein-Referenzauflösung +Ebene: SwRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: EDI-Import +Vorbedingung: Distributorrechnung im ZUGFeRD-2.1-Format liegt vor. +Fakt: ReadInvoice parst ZUGFeRD-2.1-Dateien, löst je Position die Lieferschein-Referenz + auf (GetDeliveryItemReference), übernimmt Komsa-Barcodes aus Lieferpositionen + (SetKomsaBarcodes21) und Seriennummern aus den Produktdaten + (SetSerialNumbersFromProduct21). +Aussage: Die Software soll strukturierte Eingangsrechnungen positionsgenau mit den + Lieferbelegen verknüpfen und Seriennummern/Barcodes übernehmen. +Ergebnis: Eingangsrechnungen sind automatisch lieferscheinbezogen geprüft. +Belege: + - [PRIMÄR] BL/EDI/Zugferd/ZUGFeRD_BL.cs:38-107 - Begründung: durchsetzender Importpfad. +Prüfidee: Eine Komsa-Rechnung übernimmt die Seriennummern der referenzierten Lieferpositionen. +Tracelinks: SyRS-103, SyRS-030 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Prüfautomatisierung. +Status: belegt +``` + +``` +ID: SwRS-063 +Titel: Zeitenabrechnung: Pauschalfilter und Zuschlagsüberlappung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Zeitenabrechnung +Vorbedingung: Zeiten werden selektiert. +Fakt: Standardfilter blendet Tickets aus, deren Auftragspositionen aus Pauschalpositionen + stammen (IsFromFlatRateItem), sofern ShowFlatRateHelpdesks nicht gesetzt ist; + Stundenzuschlagssätze werden je Timer als Überlappungsintervalle berechnet + (SetHourlySurchargeRateOverlaps aus Vertragszuordnung); die Zeitumrechnung von + Auftragsmengen nutzt Artikeleinheiten (ArticleUnitHelper.CalculateTime). +Aussage: Die Software soll Pauschaltickets standardmäßig von der Zeitenabrechnung ausnehmen + und Zuschlagszeiträume je Zeit als Überlappung mit den Zuschlagsdefinitionen + berechnen. +Ergebnis: Pauschalen werden nicht doppelt berechnet; Zuschläge treffen exakt die Zeitfenster. +Belege: + - [PRIMÄR] BL/Sales/CustomerAssets/TimerBilling/TimerBillingBL.cs:308-318, 377-443 - Begründung: durchsetzende Filter- und Überlappungslogik. +Prüfidee: Eine Zeit von 17-19 Uhr bei Zuschlag ab 18 Uhr erhält eine Zuschlagsüberlappung von 1h. +Tracelinks: SyRS-012 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Abrechnungsgenauigkeit. +Status: belegt +``` + +``` +ID: SwRS-064 +Titel: Sonderartikel-Vertragsimport mit ExternalID-Deduplizierung +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertragsabrechnung (Import) +Vorbedingung: Sonderartikel-Import (manuell, Gateway oder MSP) liegt vor. +Fakt: Importe ohne ExternalID erhalten bei Nicht-Handeingabe eine neue GUID; vorhandene + ExternalIDs werden abgewiesen ("schon Daten mit der FremdID vorhanden"); + Vertragsnummer und optional Kundennummer werden validiert; Artikel werden über + ArticleCode, ersatzweise ManufacturerCode aufgelöst; alles läuft in einer + Transaktion mit zeilenbezogenen Fehlermeldungen; nach Abrechnung werden die + Importköpfe der Rechnung zugeordnet (RefreshSpecialArticleHead). +Aussage: Die Software soll Sonderartikel-Importe idempotent (ExternalID), validiert + (Vertrag/Kunde/Artikel) und transaktional mit zeilengenauen Fehlern verarbeiten. +Ergebnis: Kein Import wird doppelt abgerechnet; Fehler sind zeilengenau behebbar. +Belege: + - [PRIMÄR] BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.cs:149-315 - Begründung: durchsetzende Import-Pipeline. +Prüfidee: Zweiter Import mit derselben ExternalID wird abgewiesen; ein unbekannter Artikelcode erzeugt eine Zeilenfehlermeldung. +Tracelinks: SyRS-062, SyRS-010 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - MSP-Importstrecke. +Status: belegt +``` + +``` +ID: SwRS-065 +Titel: Automatische Belegsperre beim Öffnen (AutoLock) +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Beleglogik +Vorbedingung: Beleg wird geöffnet/gespeichert. +Fakt: SaveReceipt trägt den Parameter autoLockIfNewReceipt; Ticketabrufe kennen + IgnoreLock (GetTicket-Request). Der Sperrmechanismus selbst (wer sperrt wann, + wie wird entsperrt) wurde nicht nachvollzogen. +Aussage: [HYPOTHESE] Die Software soll Belege/Tickets beim Öffnen für andere Benutzer + sperren (Pessimistic Lock) mit Umgehungsmöglichkeit (IgnoreLock). +Ergebnis: Gleichzeitiges Bearbeiten wird zusätzlich zur optimistischen Sperre verhindert. +Belege: + - [SEKUNDÄR] BL/Sales/Receipts/ReceiptBL.cs:3517 (Parameter autoLockIfNewReceipt); src/webservice/Centron.Host/Services/CentronRestService.cs:456 (IgnoreLock) - Begründung: Parameter existieren; Mechanik unbelegt. +Prüfidee: Analyse des Lock-Mechanismus (Tabellen, Timeout, Entsperrung) in Folgeiteration. +Tracelinks: SyRS-027 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - sofern Mechanik bestätigt; sonst genügt die optimistische Sperre. +Status: HYPOTHESE - Begründung: Sperrmechanik nur über Parameternamen indiziert. +``` + +``` +ID: SwRS-066 +Titel: Web-Benutzern ist die interne Belegsicht verwehrt +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Belegzugriff +Vorbedingung: Web-Account ruft interne Belegfunktionen auf. +Fakt: CanUserViewReceipt liefert für Web-Account-Logins den Fehler "Web-Benutzer haben + keine Berechtigung Belege einzusehen." (RightCheckFailed); zusätzlich blockiert der + AuthenticateInterceptor Methoden ohne AllowWebAccountLogin; die E-Rechnungs- + erzeugung lehnt Web-Accounts explizit ab. +Aussage: Die Software soll interne Belegfunktionen für Web-Accounts an mehreren Ebenen + (Methodenattribut, Fachprüfung) sperren; Portalbelege laufen ausschließlich über + die dafür vorgesehenen Web-Sichten. +Ergebnis: Web-Accounts erreichen interne Belegdaten auch bei API-Direktaufrufen nicht. +Belege: + - [PRIMÄR] BL/Sales/Receipts/ReceiptBL.cs:10297-10302; AuthenticateInterceptor.cs:39; ReceiptWebServiceBL.cs:2153-2156 - Begründung: mehrstufig durchsetzende Sperren. +Prüfidee: API-Aufruf einer internen Belegmethode mit Web-Account-Ticket wird abgewiesen. +Tracelinks: SyRS-126, SyRS-028 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Defense in Depth. +Status: belegt +``` + +``` +ID: SwRS-067 +Titel: Nexus-Transportsicherheit und Sitzungscookie-Parameter +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Web-Host +Vorbedingung: Produktivbetrieb. +Fakt: Cookie: SameSite=Lax, SecurePolicy=SameAsRequest, MaxAge=12h, eigene + Redirect-Handler für Login/AccessDenied; Produktion: UseHsts und + UseHttpsRedirection; OpenIdConnect nutzt einen temporären Zweitcookie mit + Aufräumlogik (UseOpenIdConnectCookieCleanup); Outlook-Add-In erhält eine eigene + Cookie-Policy. +Aussage: Die Software soll Web-Sitzungen mit diesen Cookie-Parametern führen und in + Produktion HTTPS mit HSTS erzwingen. +Ergebnis: Sitzungs- und Transportschutz entsprechen Web-Standards. +Belege: + - [PRIMÄR] src/nexus/CentronNexus.Host/Program.cs:264-276, 395-418 - Begründung: durchsetzende Konfiguration. +Prüfidee: Antwort-Header enthalten Strict-Transport-Security; das Sitzungscookie trägt SameSite=Lax und Ablauf 12h. +Tracelinks: SyRS-119 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Sicherheitsbasis; SecurePolicy in Produktion auf Always härten. +Status: belegt +``` + +``` +ID: SwRS-068 +Titel: Webservice-Login: verschlüsselte Anwendungs-GUID und Interceptor-Kette +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Webservice +Vorbedingung: Login-Request trifft ein. +Fakt: Der Login holt zuerst einen Webservice-Token, entschlüsselt damit die übermittelte + Anwendungs-GUID (ApplicationGuidHelper), baut das AuthObject und stellt das Ticket + aus; alle [Authenticate]-Methoden laufen durch den AuthenticateInterceptor + (Priorität 10) mit Ticket- oder Access-Token-Validierung inkl. Client-IP-Erfassung; + IsValidTicket verlässt sich vollständig auf den Interceptor. +Aussage: Die Software soll die Anwendungsidentität verschlüsselt übertragen und die + Authentifizierung zentral als Interceptor vor jeder Dienstmethode erzwingen. +Ergebnis: Keine Dienstmethode ist ohne zentrale Prüfung erreichbar; die Anwendungs-GUID ist nicht abhörbar. +Belege: + - [PRIMÄR] src/webservice/Centron.Host/Services/CentronRestService.cs:363-447; AuthenticateInterceptor.cs:15-80 - Begründung: durchsetzender Anmelde- und Prüfpfad. +Prüfidee: Eine Methode mit [Authenticate] ist ohne Ticket nicht aufrufbar; die GUID-Übertragung ist im Klartext nicht lesbar. +Tracelinks: SyRS-127, SyRS-078 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zentrale Prüfarchitektur. +Status: belegt +``` + +``` +ID: SwRS-069 +Titel: Inventur-Erfassungsantworten mit Klärfällen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Inventurlogik +Vorbedingung: Scan wird geprüft. +Fakt: CheckInventory liefert typisierte Antworten (InventoryResponseKind: Ok, + MultiBarcode, NeedCheckArtic, NewBarcode …); Mehrfachtreffer werden über + CheckMultiBarcode aufgelöst; Konsignationsaufträge buchen in ein Auto-Lager + (GetAutoStock); Ok-Antworten werden je Gruppe/Lagerplatz mit Erfasser gespeichert. +Aussage: Die Software soll Inventur-Scans in typisierte Ergebnisklassen einordnen, + Mehrdeutigkeiten zur Klärung ausweisen und nur eindeutige Erfassungen buchen. +Ergebnis: Unklare Scans landen im Klärprozess statt im Bestand. +Belege: + - [PRIMÄR] BL/Warehousing/InventoryManagement/InventoryNewBL.cs:97-180 - Begründung: durchsetzende Antwortlogik. +Prüfidee: Ein doppelt vergebener Barcode erzeugt eine MultiBarcode-Antwort und keine Buchung. +Tracelinks: SyRS-065 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Erfassungsqualität. +Status: belegt +``` + +``` +ID: SwRS-070 +Titel: Batch- und Seitenverarbeitung großer Datenmengen +Ebene: SwRS +Typ: nicht-funktional +Qualitätsmerkmal: Performance-Effizienz +Akteur: Datenzugriff +Vorbedingung: Große Treffermengen. +Fakt: Positionsabfragen laufen in 2000er-Batches (Batch(2000) in AutomaticFacturaBL und + TimerBillingBL); Onlinebanking bietet Paging (GetOnlineBankingAccountTransactions- + ThroughPaging mit page/entriesPerPage); Statistiken cachen (CacheSalesStatisticsBL, + CacheOrderStatisticsBL). +Aussage: Die Software soll große Treffermengen gebatcht (IN-Listen ≤2000) bzw. seitenweise + verarbeiten und teure Statistiken cachen. +Ergebnis: Läufe skalieren ohne Parameterlimit-/Speicherfehler. +Belege: + - [PRIMÄR] BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.cs:373-382 (Batch(2000)); BL/Finances/OnlineBanking/OnlineBankingAccountTransactionsBL.cs:193 (Paging) - Begründung: implementierte Skalierungsmuster. +Prüfidee: Eine Abrechnung mit 5.000 Köpfen läuft in drei Batches fehlerfrei. +Tracelinks: SyRS-010, SyRS-072, SyRS-117 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Skalierungsmuster. +Status: belegt +``` + +``` +ID: SwRS-071 +Titel: Sammelrechnung für Konzerne (Collective Invoice) +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertragsabrechnung +Vorbedingung: Kunde gehört zu einem Konzern; Sammelrechnung ist vereinbart. +Fakt: Verträge tragen CollectInvoice; die Mailvorlagenermittlung unterscheidet + Sammelrechnungen (isCollectiveInvoice) und ermittelt Konzern-Empfänger + (GetCorporationCollectiveInvoiceMailReceivers, UseCorporationReceivers). Die + eigentliche Bündelungslogik (welche Verträge in eine Sammelrechnung fließen) wurde + nicht nachvollzogen. +Aussage: [HYPOTHESE] Die Software soll mehrere Verträge eines Kunden/Konzerns in einer + Sammelrechnung bündeln und deren Versand an Konzernempfänger richten. +Ergebnis: Konzerne erhalten eine konsolidierte Rechnung. +Belege: + - [SEKUNDÄR] BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.Contracts.cs:263-382 (isCollectiveInvoice, Corporation-Receivers); ReceiptContract (CollectInvoice) - Begründung: Indizien für Sammelrechnung; Bündelungsregel unbelegt. +Prüfidee: Analyse der Rechnungsbündelung (Gruppierungskriterien) in Folgeiteration. +Tracelinks: SyRS-010, SyRS-024 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Konzernabrechnung ist marktüblich; Regel klären. +Status: HYPOTHESE - Begründung: Bündelungskriterien der Sammelrechnung nicht verifiziert. +``` + diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/SyRS.md b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/SyRS.md new file mode 100644 index 00000000..1ab1f055 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/SyRS.md @@ -0,0 +1,3708 @@ +# SyRS – System Requirements Specification + +**System:** c-entron ERP-Suite +**Quelle:** Reverse Requirements Engineering aus der Codebasis, statische Analyse +**Norm:** ISO/IEC/IEEE 29148:2018, Ebene Systemanforderungen +**Konventionen:** `BL/` = `src/backend/Centron.BL/`; Tabellennamen beziehen sich auf +`SSMS_DB_SCHEMA.sql`. Jede SyRS-Anforderung referenziert ihre StRS-Elternanforderung in den +Tracelinks; vertiefende Software-Anforderungen stehen in der SwRS. Die SyRS ist die tragende +Ebene der Modul-Mindestabdeckung: Die Modulnummer (M__) aus dem Inventar des Analyseberichts +ist je Anforderung in Klammern im Titelkommentar vermerkt. + +--- + +## A. Vertrieb / Belegwesen + +``` +ID: SyRS-001 +Titel: Angebote erstellen und verwalten (M01) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertrieb/Innendienst +Vorbedingung: Benutzer besitzt Angebotsrechte; Kunde existiert. +Fakt: Angebote sind als ReceiptOffer (Tabelle AngKopf/AngPos, Views Offers/OfferItems) mit + eigener BL implementiert; Versionsprüfung per ConcurrencyControlGuid (ReceiptBL.cs:6951). +Aussage: Das System soll Angebote mit Kopf- und Positionsdaten anlegen, ändern, versionieren + und in Folgebelege überführen können. +Ergebnis: Ein gespeichertes Angebot ist unter seiner Nummer auffindbar und weiterverarbeitbar. +Belege: + - [PRIMÄR] src/backend/Centron.Entities/Entities/Sales/Receipts/Offers/ReceiptOffer.cs und BL/Sales/Receipts/Offers/ - Begründung: implementierte Belegart. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql (AngKopf, AngPos, AngKopfVersions) - Begründung: persistentes Datenmodell. +Prüfidee: Angebot mit 2 Positionen speichern, erneut laden: Kopf- und Positionsdaten sind identisch; eine neue Version erhöht die Versionsnummer. +Tracelinks: StRS-02 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Standardbelegart. +Status: belegt +``` + +``` +ID: SyRS-002 +Titel: Aufträge verwalten (M02) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertrieb/Innendienst +Vorbedingung: Benutzer besitzt Auftragsrechte. +Fakt: Aufträge (ReceiptOrder, AufKopf/AufPos) besitzen eine eigene BL (OrderBL) und werden + in der automatischen Abrechnung als abrechnungsbereit selektiert + (NamedQuery GetOrdersForAutomatedBilling). +Aussage: Das System soll Kundenaufträge mit Positionen, Lieferstatus und Abrechnungsstatus führen. +Ergebnis: Aufträge sind bis zur vollständigen Lieferung/Abrechnung verfolgbar. +Belege: + - [PRIMÄR] BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.cs:114-127 (SearchBillingOrders) - Begründung: Auftragsselektion für Abrechnung ist implementiert. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql (AufKopf/AufPos) - Begründung: Datenmodell. +Prüfidee: Ein Auftrag mit lieferbaren Positionen erscheint in der Abrechnungssuche bis er fakturiert ist. +Tracelinks: StRS-02 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Standardbelegart. +Status: belegt +``` + +``` +ID: SyRS-003 +Titel: Lieferscheine führen (M03) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Lager / Innendienst +Vorbedingung: Auftrag oder Direktlieferung vorhanden. +Fakt: Lieferscheine (ReceiptDeliveryList, LiefKopf/LiefPos) mit Status werden für die + Abrechnung mit State == 1 selektiert (SearchBillingDeliveryLists). +Aussage: Das System soll Lieferscheine mit Positionen und Status führen und offene + Lieferscheine der Abrechnung zuführen. +Ergebnis: Gelieferte, noch nicht fakturierte Leistungen sind als offene Lieferscheine sichtbar. +Belege: + - [PRIMÄR] BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.cs:102-106 (SearchBillingDeliveryLists mit f.State == 1) - Begründung: Statusregel ist implementiert. +Prüfidee: Ein offener Lieferschein (Status 1) bis zum Stichtag erscheint in der Abrechnungssuche des Kunden. +Tracelinks: StRS-02 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Standardbelegart. +Status: belegt +``` + +``` +ID: SyRS-004 +Titel: Rechnungen erstellen (M04) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung / Innendienst +Vorbedingung: Leistung ist erbracht (Auftrag/Lieferschein/Vertrag). +Fakt: Rechnungen (ReceiptInvoice, RechKopf/RechPos) tragen u. a. Zahlungsbedingung, + Leistungszeitraum (ServicePeriodFrom/To), bezahlten Betrag (PaidFC), + Fälligkeit (PaymentDueDate), SEPA-Mandat (MandatI3D) und Vertragsbezug (ContractI3D). +Aussage: Das System soll Rechnungen mit Zahlungskonditionen, Leistungszeitraum und + Zahlungsstatus erzeugen und verwalten. +Ergebnis: Die Rechnung weist alle abrechnungsrelevanten Angaben aus und führt ihren Zahlungsstand mit. +Belege: + - [PRIMÄR] src/backend/Centron.Entities/Entities/Sales/Receipts/Invoices/ReceiptInvoice.cs:38-108 - Begründung: abrechnungsrelevante Felder im Datenmodell. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql (RechKopf/RechPos) - Begründung: Persistenz. +Prüfidee: Eine erzeugte Rechnung enthält Zahlungsbedingung und Fälligkeitsdatum; Teilzahlungen erhöhen PaidFC. +Tracelinks: StRS-02, StRS-24 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kernbelegart. +Status: belegt +``` + +``` +ID: SyRS-005 +Titel: Rechnungen stornieren mit Schutzbedingungen (M04) +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Rechnung existiert; Benutzer hat das Stornorecht. +Fakt: CancelInvoice erzwingt: Recht RIGHT_RECHNUNGSTORNIEREN, kein Doppelstorno, keine + Barrechnung, keine Weiterverarbeitung, kein erfolgter FiBu-Export, bei + Vertragsrechnungen nur die letzte; Storno erzeugt neue Version mit Menge 0 und + Status "storniert" und setzt Vertrags-/Zählerstände zurück. +Aussage: Das System soll Rechnungsstornos nur berechtigten Benutzern und nur unter den + genannten Bedingungen erlauben und den Storno vollständig protokollieren. +Ergebnis: Stornierte Rechnungen bleiben mit Historie erhalten; abhängige Vertrags-/Zählerdaten sind zurückgesetzt. +Belege: + - [PRIMÄR] BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs:143-206 (CancelInvoice: Rechteprüfung Zeile 154, Bedingungsprüfungen Zeilen 157-172, ResetContract Zeile 199) - Begründung: durchsetzende Stelle aller Stornoregeln. +Prüfidee: Storno ohne Recht → Fehlermeldung; Storno einer exportierten Rechnung → Fehlermeldung; Storno der letzten Vertragsrechnung → neue Version Status storniert, Klickzähler zurückgesetzt. +Tracelinks: StRS-24, StRS-29, SwRS-016 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - buchhalterische Integrität. +Status: belegt +``` + +``` +ID: SyRS-006 +Titel: Rechnungen festschreiben (M04) +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Rechnung ist final geprüft. +Fakt: FixInvoice setzt RechKopf.IsFixed=1 in einer Transaktion und schreibt einen + Logeintrag "Die Rechnung wurde am … von … festgeschrieben."; CheckIfInvoiceIsFixed + meldet festgeschriebene Rechnungen als unveränderlich. +Aussage: Das System soll Rechnungen festschreiben können; festgeschriebene Rechnungen sollen + nicht mehr änderbar sein. +Ergebnis: Ab Festschreibung sind Inhaltsänderungen ausgeschlossen; der Vorgang ist mit Benutzer und Zeitpunkt protokolliert. +Belege: + - [PRIMÄR] BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs:86-141 (FixInvoice) und 273-291 (CheckIfInvoiceIsFixed) - Begründung: durchsetzende Stellen der Festschreibung. +Prüfidee: Nach FixInvoice liefert ein erneuter Fix-Versuch die Warnung "festgeschrieben. Änderungen nicht möglich."; ein Logeintrag mit Benutzer existiert. +Tracelinks: StRS-24, SwRS-017 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - GoBD-Anforderung. +Status: belegt +``` + +``` +ID: SyRS-007 +Titel: Gutschriften führen (M05) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Grund für Gutschrift besteht (Retoure, Korrektur). +Fakt: Gutschriften (ReceiptCreditVoucher, GutKopf/GutPos) sind eigene Belegart; das + Mahnwesen bezieht Gutschriften in die Kundensicht ein (IncludeCreditVouchers). +Aussage: Das System soll Gutschriften als eigene Belegart führen und in Zahlungs- und + Mahnprozessen mit Rechnungen verrechnen. +Ergebnis: Gutschriften mindern die offene Forderung des Kunden. +Belege: + - [PRIMÄR] BL/Sales/Receipts/Invoices/Dunning/DunningBL.cs:99-108 (CreditVouchers im Mahnlauf) - Begründung: Verrechnungslogik vorhanden. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql (GutKopf/GutPos) - Begründung: Datenmodell. +Prüfidee: Ein Kunde mit offener Rechnung und Gutschrift zeigt im Mahnlauf beide Belege; die Gutschrift reduziert den Saldo. +Tracelinks: StRS-02, StRS-10 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Standardbelegart. +Status: belegt +``` + +``` +ID: SyRS-008 +Titel: Abhollisten führen (M06) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Service / Logistik +Vorbedingung: Geräteabholung beim Kunden ist vereinbart. +Fakt: Abhollisten (ReceiptPickupList, AbholKopf/AbholPos) sind als Belegart mit + Versionstabellen implementiert; Barcodezustände kennen AssignedToPickupList. +Aussage: Das System soll Abholaufträge als Beleg mit Positionen und Seriennummernbezug führen. +Ergebnis: Abzuholende Geräte sind belegmäßig erfasst; ihr Barcodezustand weist die Abholung aus. +Belege: + - [PRIMÄR] src/backend/Centron.Interfaces/Warehousing/BarcodeState.cs:24 (AssignedToPickupList) - Begründung: Belegbezug im Gerätelebenszyklus. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql (AbholKopf/AbholPos) - Begründung: Datenmodell. +Prüfidee: Eine Seriennummer auf einer Abholliste wechselt in den Zustand AssignedToPickupList. +Tracelinks: StRS-02, StRS-07 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Retourenlogistik. +Status: belegt +``` + +``` +ID: SyRS-009 +Titel: Verträge als Belegart mit Abrechnungsparametern (M07) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertrieb / Buchhaltung +Vorbedingung: Kunde existiert. +Fakt: ReceiptContract (VertragKopf/VertragPos) trägt Abrechnungsintervall (Art/Dauer), + Abrechnungsart, automatische Abrechnung, automatische Verlängerung, Vertragsbeginn/ + -ende, Kündigungsdatum, Kontingentfelder und SEPA-Mandat. +Aussage: Das System soll Verträge als Beleg mit vollständigen Abrechnungs-, Laufzeit- und + Kontingentparametern führen. +Ergebnis: Der Vertrag enthält alle Parameter, die die automatische Abrechnung benötigt. +Belege: + - [PRIMÄR] src/backend/Centron.Entities/Entities/Sales/Receipts/ContractLists/ReceiptContract.cs - Begründung: Vertragsparameter im Datenmodell. + - [KONTEXT] docs/reference/receipts/contracts-backend.md - Begründung: Feldbedeutungen dokumentiert. +Prüfidee: Ein Vertrag mit Intervall "monatlich, Dauer 3" und automatischer Abrechnung wird als quartalsweise abzurechnender Vertrag gespeichert und so von der Abrechnung interpretiert. +Tracelinks: StRS-03 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Vertragsstamm. +Status: belegt +``` + +``` +ID: SyRS-010 +Titel: Automatische Vertragsabrechnung (M08) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung (Abrechnungslauf) +Vorbedingung: Fällige Verträge existieren. +Fakt: AutomaticFacturaBL ermittelt fällige Verträge (ContractForBilling), schreibt + Abrechnungszeiträume fort (SetNextBillingDate/NextDate), erzeugt Rechnungen und + verknüpft sie über VertragRechKopfZuordnung; Ergebnisse werden je Vertrag + protokolliert (StoreBillingResult). +Aussage: Das System soll fällige Verträge stichtagsbezogen ermitteln, je Vertrag Rechnungen + für die offenen Perioden erzeugen und Erfolg/Fehler je Vertrag protokollieren. +Ergebnis: Nach dem Lauf sind alle fälligen Perioden fakturiert; das Abrechnungsprotokoll weist Status je Vertrag aus. +Belege: + - [PRIMÄR] BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.Contracts.cs:1596-1627 (ContractForBilling), 1258 (StoreInvoiceToContract), 2101-2118 (StoreBillingResult) - Begründung: durchsetzende Abrechnungslogik. +Prüfidee: Zwei fällige Monatsperioden eines Vertrags erzeugen im Lauf genau eine Rechnung mit Intervallzähler 2 (bzw. zwei Perioden) und einen Protokolleintrag. +Tracelinks: StRS-03, SwRS-019, SwRS-020, SwRS-021, SwRS-022 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kernautomatisierung. +Status: belegt +``` + +``` +ID: SyRS-011 +Titel: Zählerstands-/Klickabrechnung (M08) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung / Techniker (Zählererfassung) +Vorbedingung: Klickvertrag mit Gerätestammblättern besteht. +Fakt: Zählerstände werden je Gerät erfasst (StoreCounterState), historisiert + (AutomaticFacturaCounterHistory), mit Freimengen (CounterFreeCount) und + Staffelpreisen (CounterScalePrices) bewertet und bei Abrechnung mit der + Rechnungsposition verknüpft (UpdClickCounterHistory). +Aussage: Das System soll Gerätezählerstände erfassen, historisieren und die Differenzmengen + unter Berücksichtigung von Freimengen und Staffelpreisen abrechnen. +Ergebnis: Jede Zählerdifferenz ist genau einer Rechnungsposition zugeordnet. +Belege: + - [PRIMÄR] BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.Contracts.cs:161 (StoreCounterState), 736-762 (GetCounterFreeCount/GetCounterScalePrices), 1248-1256 (UpdClickCounterHistory) - Begründung: durchsetzende Zählerabrechnung. +Prüfidee: Zwei Zählerstände mit Differenz D und Freimenge F erzeugen eine Abrechnungsmenge max(0, D-F). +Tracelinks: StRS-04, SwRS-024 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Druck-/Kopierer-Geschäft. +Status: belegt +``` + +``` +ID: SyRS-012 +Titel: Zeitenabrechnung aus Tickets (M09) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Abrechenbare Ticketzeiten existieren. +Fakt: TimerBillingBL selektiert abrechenbare Zeiten (OnlyCalculable), schließt + Pauschal-Tickets aus (IsFlatRateItem), berücksichtigt Stundenzuschlagssätze + (HourlySurchargeRateOverlaps) und schreibt bereits abgerechnete Zeit je + Auftragsposition fort (AlreadyBilledTime). +Aussage: Das System soll abrechenbare Ticketzeiten filtern, mit Zuschlagssätzen bewerten und + in Auftrags-/Rechnungspositionen überführen, ohne Zeiten doppelt abzurechnen. +Ergebnis: Jede Zeit ist höchstens einmal abgerechnet; Pauschalverträge erzeugen keine Zeitpositionen. +Belege: + - [PRIMÄR] BL/Sales/CustomerAssets/TimerBilling/TimerBillingBL.cs:233-383 (SearchTimers), 385 (SetHourlySurchargeRateOverlaps), 451 (SaveTimer), 599 (UpdateOrderItems) - Begründung: durchsetzende Abrechnungsselektion. +Prüfidee: Eine bereits fakturierte Zeit erscheint nicht erneut in der Selektion; ein Ticket mit Pauschalposition wird bei Standardfilter ausgeblendet. +Tracelinks: StRS-05, SwRS-063 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Dienstleistungsabrechnung. +Status: belegt +``` + +``` +ID: SyRS-013 +Titel: Anzahlungsrechnungen und Schlussrechnung (M10) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Auftrag mit Anzahlungsvereinbarung existiert. +Fakt: DownPaymentBL erzeugt Anzahlungsrechnungen zu einem Auftrag + (CreateDownPaymentInvoice mit Nettobetrag) und eine Schlussrechnung mit Verrechnung + der Anzahlungen (CreateFinalInvoiceWithDownPayments); Rechnungen tragen + DownPaymentForOrderI3D. +Aussage: Das System soll zu einem Auftrag Anzahlungsrechnungen erzeugen und diese in der + Schlussrechnung automatisch verrechnen. +Ergebnis: Die Schlussrechnung weist die geleisteten Anzahlungen mindernd aus. +Belege: + - [PRIMÄR] BL/Sales/Receipts/DownPayment/DownPaymentBL.cs:82 (CreateDownPaymentInvoice), 198 (CreateFinalInvoiceWithDownPayments) - Begründung: durchsetzende Anzahlungslogik. + - [PRIMÄR] src/backend/Centron.Entities/.../ReceiptInvoice.cs:106 (DownPaymentForOrderI3D) - Begründung: Belegverknüpfung. +Prüfidee: Auftrag über 10.000, Anzahlung 3.000: Die Schlussrechnung weist 3.000 als verrechnete Anzahlung aus und fordert 7.000. +Tracelinks: StRS-02 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Projektgeschäft. +Status: belegt +``` + +``` +ID: SyRS-014 +Titel: Projekte mit Belegbezug (M11) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Projektleiter +Vorbedingung: keine +Fakt: ProjectBL liefert Projektlisten; Belege tragen ProjectNumber. +Aussage: Das System soll Projekte verwalten und Belegen eine Projektnummer zuordnen. +Ergebnis: Belege sind projektbezogen filterbar. +Belege: + - [PRIMÄR] BL/Projects/ProjectBL.cs (GetProjectList) - Begründung: Projektverwaltung implementiert. + - [PRIMÄR] src/backend/Centron.Entities/.../ReceiptInvoice.cs:34 (ProjectNumber) - Begründung: Belegbezug. +Prüfidee: Ein Auftrag mit Projektnummer P erscheint in der Projektfilterung zu P. +Tracelinks: StRS-28 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Projektauswertung. +Status: belegt +``` + +``` +ID: SyRS-015 +Titel: Leasing- und Service-Raten (M12) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertrieb / Buchhaltung +Vorbedingung: Leasing-/Servicevereinbarung besteht; Modul lizenziert. +Fakt: LeasingRateBL/ServiceRateBL und Logs existieren; das Modul ist mit Recht + LEASINGANDSERVICE und Lizenz LeasingService freigeschaltet. +Aussage: Das System soll Leasing- und Serviceraten zu Belegen verwalten und deren Verlauf + protokollieren. +Ergebnis: Ratenpläne sind je Vereinbarung einsehbar und protokolliert. +Belege: + - [PRIMÄR] BL/Sales/Receipts/LeasingAndService/ (LeasingRateBL.cs, ServiceRateBL.cs, LeasingLogBL.cs, ServiceLogBL.cs) - Begründung: implementierte Ratenverwaltung. + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/ModuleRegistration.cs:475-477 (Recht LEASINGANDSERVICE + Lizenz LeasingService) - Begründung: Zugriffsschaltung. +Prüfidee: Ohne Lizenz LeasingService ist das Modul unsichtbar; mit Lizenz und Recht lassen sich Raten anlegen. +Tracelinks: StRS-02, StRS-15 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Finanzierungsgeschäft; Detailtiefe in Folgeiteration prüfen. +Status: belegt +``` + +``` +ID: SyRS-016 +Titel: Aktionspreise verwalten (M13) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Einkauf / Vertrieb +Vorbedingung: Artikel existiert. +Fakt: ActionPrice-Entität (Tabelle HerstellerArtikAktionspreis) mit CRUD in ActionPriceBL; + die Doku beschreibt Aktionspreise je Artikel mit Zeitraum und Quellen (z. B. EDI). +Aussage: Das System soll zeitlich begrenzte Aktionspreise je Artikel verwalten und in der + Preisfindung bereitstellen. +Ergebnis: Innerhalb des Aktionszeitraums wird der Aktionspreis angeboten. +Belege: + - [PRIMÄR] BL/Warehousing/ActionPriceBL.cs (GetActionPricesByArticleI3D, SaveOrUpdateActionPrice) - Begründung: Verwaltung implementiert. + - [KONTEXT] docs/reference/receipts/actionprice-system.md - Begründung: fachliche Beschreibung inkl. Tabellenname. +Prüfidee: Ein Aktionspreis mit gültigem Zeitraum wird beim Artikel angezeigt; nach Ablauf nicht mehr. +Tracelinks: StRS-25, SyRS-017 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Einkaufsvorteile weitergeben. +Status: belegt +``` + +``` +ID: SyRS-017 +Titel: Artikelsuche mit integrierter Preisfindung im Beleg (M14) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertrieb/Innendienst +Vorbedingung: Belegerfassung ist geöffnet. +Fakt: ArticleSearchBL sucht interne und externe Artikel (Distributorquellen) und berechnet + je Treffer kundenspezifische EK/VK-Preise über PriceBL (Sonderabkommen, Kunde, + Vertrag, Preisliste, Lager). +Aussage: Das System soll bei der Belegerfassung Artikel intern und bei Distributoren suchen + und je Artikel den für Kunde, Vertrag und Lager gültigen Preis ermitteln. +Ergebnis: Die Position erhält ohne manuelle Preiseingabe den korrekten kundenindividuellen Preis. +Belege: + - [PRIMÄR] BL/Sales/Receipts/ArticleSearch/ArticleSearchBL.cs:1080-1126 (CalculatePricesForArticles, ExecuteExternalArticleSearchAsync) - Begründung: durchsetzende Preis-/Suchlogik. +Prüfidee: Derselbe Artikel liefert für zwei Kunden mit unterschiedlichen Sonderpreisen unterschiedliche VK-Vorschläge. +Tracelinks: StRS-02, StRS-25, SwRS-007, SwRS-008, SwRS-009, SwRS-010 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zentrale Erfassungsunterstützung. +Status: belegt +``` + +``` +ID: SyRS-018 +Titel: Kassenbuch mit belegbezogenen Buchungen (M15) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Verkauf/Theke +Vorbedingung: Kassenbuch eingerichtet. +Fakt: CashBookBookingBL erzeugt/aktualisiert Kassenbuchbuchungen aus Belegen + (UpdateCashBookBookingFromAsset mit gezahltem Betrag) und löscht sie belegbezogen. +Aussage: Das System soll Barzahlungen zu Belegen als Kassenbuchbuchungen führen und bei + Belegänderungen konsistent halten. +Ergebnis: Der Kassenbestand entspricht den belegbezogenen Buchungen. +Belege: + - [PRIMÄR] BL/Sales/CashBooks/CashBookBookingBL.cs (UpdateCashBookBookingFromAsset, DeleteCashBookBookingFromAsset, GetCashBookBookingsFromAsset) - Begründung: durchsetzende Kassenlogik. +Prüfidee: Eine Barrechnung über 100 erzeugt eine Kassenbuchung 100; Löschen des Belegs entfernt die Buchung. +Tracelinks: StRS-29 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Bargeschäft. +Status: belegt +``` + +``` +ID: SyRS-019 +Titel: Kundenindividuelle Sonderpreise (M16) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertrieb +Vorbedingung: Kunde und Artikel existieren. +Fakt: AccountSpecialPriceBL verwaltet aktive Sonderpreise je Account; die Preisfindung + wertet Kundensonderpreise in fünf Arten aus (Fixpreis, EK-Aufschlag, Abschlag auf + UVP/VK/Listenpreis); das WebCart-Sortiment besteht aus Artikeln mit aktiven + Sonderpreisen. +Aussage: Das System soll kundenindividuelle Sonderpreise je Artikel pflegen und in + Preisfindung und Webshop wirksam machen. +Ergebnis: Sonderpreise überschreiben Standardpreise für den jeweiligen Kunden. +Belege: + - [PRIMÄR] BL/Sales/Receipts/Internal/ReceiptItemPriceBL.cs:232-257 (SpecialPriceKind-Auswertung) - Begründung: durchsetzende Preisregel. + - [PRIMÄR] BL/WebServices/Sales/Receipts/ArticleSearch/ArticleSearchWebServiceBL.cs:71-99 (GetWebCartArticles nur bei aktiven Sonderpreisen) - Begründung: Sortimentsregel Webshop. +Prüfidee: Ein Fixpreis-Sonderpreis ersetzt den Standard-VK in der Belegposition dieses Kunden. +Tracelinks: StRS-17, StRS-25, SwRS-008, SwRS-043 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Preisvereinbarungen. +Status: belegt +``` + +``` +ID: SyRS-020 +Titel: Gerätestammblätter mit Zähler- und Vertragsbezug (M17) +Ebene: SyRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Service / Abrechnung +Vorbedingung: Gerät ist ausgeliefert/fakturiert. +Fakt: MasterDataList führt je Gerät Seriennummer, Zählerkennzeichen (CounterDevice), + Kunde, Vertrag (ContractI3D), Ursprungsrechnung (InvoiceI3D/-Number/-Date), Währung, + Aktivstatus und Positionsliste; Verträge referenzieren Stammblätter für die + Klickabrechnung. +Aussage: Das System soll je abrechnungsrelevantem Gerät ein Stammblatt mit Seriennummer, + Herkunftsbeleg und Vertragsbezug führen. +Ergebnis: Die Klickabrechnung findet je Vertrag die zugehörigen Geräte mit Zählern. +Belege: + - [PRIMÄR] src/backend/Centron.Entities/Entities/Sales/Receipts/MasterDataLists/MasterDataList.cs - Begründung: Datenmodell des Stammblatts. + - [PRIMÄR] BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.Contracts.cs:492-495 (GetMasterDataList zu Zählern) - Begründung: Nutzung in der Abrechnung. +Prüfidee: Ein aus einer Rechnung erzeugtes Stammblatt zeigt Rechnungsnummer und -datum; der Vertrag findet es über die Stammblattliste. +Tracelinks: StRS-19, StRS-04 +Konsolidierung: Kandidat: SyRS-059 (AccountDevices), SyRS-060 (AssetManagement) - dieselbe fachliche Entität "Kundengerät" in getrennten Datenhaltungen; im Zielsystem zusammenführen. +Übernahmewürdigkeit: übernehmen - fachlich nötig, aber im Zielsystem als Teil eines vereinheitlichten Asset-Konzepts. +Status: belegt +``` + +``` +ID: SyRS-021 +Titel: Schweizer Rundung (Rappenrundung) (M18) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung (Schweizer Mandanten) +Vorbedingung: Einstellung CommercialRoundCH ist aktiv. +Fakt: Bei aktiver Einstellung wird der Bruttobetrag auf 0,05 gerundet, indem der + Steueranteil um die Differenz korrigiert wird; zusätzlich existieren + ESR-Zahlschein-Felder (EsrReferenceNumber) und SwitzerlandSettingsBL. +Aussage: Das System soll für Schweizer Mandanten Bruttobeträge auf 5 Rappen runden und + ESR-Zahlscheindaten am Beleg führen. +Ergebnis: Schweizer Belege weisen 0,05-gerundete Endbeträge aus. +Belege: + - [PRIMÄR] src/webservice/Centron.WebServices.Core/Helper/ReceiptPriceHelper.cs:37-41 (Rundung auf /0.05) - Begründung: durchsetzende Rundungsregel. + - [PRIMÄR] BL/Sales/Receipts/ReceiptPriceHelperBL.cs:40 (Einstellung CommercialRoundCH) - Begründung: Aktivierungsschalter. + - [SEKUNDÄR] src/backend/Centron.Entities/.../ReceiptInvoice.cs:72-74 (Esr*-Felder) - Begründung: ESR-Datenmodell. +Prüfidee: Nettobetrag 100,00 mit 8,1 % MwSt ergibt bei aktivem Schalter einen auf 0,05 endenden Bruttobetrag. +Tracelinks: StRS-02, SwRS-012 +Konsolidierung: nein +Übernahmewürdigkeit: Sonderfall - nur für Schweizer Mandanten relevant, dort aber zwingend. +Status: belegt +``` + +``` +ID: SyRS-022 +Titel: Belegversionierung mit vollständigen Versionsständen (M19) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System +Vorbedingung: Beleg wird geändert. +Fakt: Jede Belegart besitzt Versionstabellen (*KopfVersions/*PosVersions) als 1:1-Kopien; + das Versionsspeichern kopiert Kopf und Positionen mit OriginalI3D-Referenz; + ReceiptBL.CreateNewVersion erzeugt neue Versionsstände (z. B. beim Storno). +Aussage: Das System soll bei Belegänderungen den vorherigen Stand vollständig (Kopf und + Positionen) als Version ablegen. +Ergebnis: Alle historischen Belegstände sind mit Bezug zum Original abrufbar. +Belege: + - [PRIMÄR] BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs:174 (CreateNewVersion beim Storno) - Begründung: Versionierung wird im Prozess erzwungen. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql (AngKopfVersions … VertragPosVersions) - Begründung: Versionstabellen existieren für alle Belegarten. + - [KONTEXT] docs/reference/receipts/receipts-backend-architecture.md (Versioning Implementation) - Begründung: dokumentiertes Kopierverfahren. +Prüfidee: Nach zwei Änderungen einer Rechnung existieren zwei Versionssätze in RechKopfVersions mit OriginalI3D der Rechnung. +Tracelinks: StRS-24, SwRS-002 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Nachvollziehbarkeit; technische Umsetzung (Tabellenkopie) im Zielsystem neu entscheiden. +Status: belegt +``` + +``` +ID: SyRS-023 +Titel: Nummernkreise je Mandant/Filiale (M20) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System +Vorbedingung: Nummernkreise sind angelegt. +Fakt: NumberGroups tragen Bereich (RangeFrom/To), Intervall und aktuellen Stand je + Mandant/Filiale und Objektart; die Vergabe prüft Kollisionen in der Zieltabelle und + reserviert per Compare-and-Swap. +Aussage: Das System soll Beleg- und Stammdatennummern aus konfigurierbaren Nummernkreisen je + Mandant und Filiale vergeben und doppelte Vergabe auch bei parallelen Zugriffen + ausschließen. +Ergebnis: Jede vergebene Nummer ist innerhalb ihres Kreises eindeutig. +Belege: + - [PRIMÄR] BL/Administration/Company/NumberGroupBL.cs:62-134 (GetNextNumber mit UpdateBuilder-CAS und Kollisionsprüfung) - Begründung: durchsetzende Vergabelogik. +Prüfidee: Zwei parallele Nummernanforderungen liefern zwei verschiedene Nummern; eine bereits in der Zieltabelle vorhandene Nummer wird übersprungen. +Tracelinks: StRS-16, SwRS-025 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Nummernvergabe ist buchhalterisch zwingend. +Status: belegt +``` + +``` +ID: SyRS-024 +Titel: Belegdruck und Belegversand per E-Mail (M21) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Innendienst / Abrechnungslauf +Vorbedingung: Beleg existiert; Mailvorlagen konfiguriert. +Fakt: Die ReportEngine erzeugt Beleg-PDFs; die Vertragsabrechnung ermittelt je + Vertrag/Kunde die Mailvorlage und die Empfänger (auch Konzern-Sammelrechnungs- + empfänger) und versendet Rechnungen per Mail. +Aussage: Das System soll Belege als PDF erzeugen und mit kundenspezifischen Vorlagen und + Empfängerlisten per E-Mail versenden. +Ergebnis: Der Beleg erreicht die hinterlegten Rechnungsempfänger des Kunden. +Belege: + - [PRIMÄR] BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.Contracts.cs:263-443 (GetContractMailTemplate, GetInvoiceMailReceiversForCustomer, AddSubjectPrefixesFromSettings) - Begründung: Versandlogik implementiert. + - [SEKUNDÄR] BL/ReportEngine/ (PdfExport, CustomPdfGenerators) - Begründung: PDF-Erzeugung. +Prüfidee: Ein Kunde mit zwei hinterlegten Rechnungsempfängern erhält die Vertragsrechnung an beide Adressen mit der konfigurierten Betreffzeile. +Tracelinks: StRS-03, StRS-21, StRS-22 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Belegzustellung. +Status: belegt +``` + +``` +ID: SyRS-025 +Titel: Kreditlimitprüfung beim Belegspeichern (M68) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertrieb / System +Vorbedingung: Kunde hat Kreditlimit > 0 und Prüfart ≠ "keine". +Fakt: Beim Speichern kreditlimitrelevanter Belege summiert das System das verbrauchte + Limit über alle Belegarten (netto oder brutto je Kundeneinstellung), zieht + Vorversion und Ursprungsbelege ab und zeigt bei Überschreitung einen + Bestätigungsdialog mit Detailaufstellung; Speichern ist mit ausdrücklicher + Bestätigung möglich. +Aussage: Das System soll beim Belegspeichern das Kreditlimit des Kunden prüfen, eine + Überschreitung mit Betrag ausweisen und das Speichern nur nach ausdrücklicher + Bestätigung fortsetzen. +Ergebnis: Limitüberschreitungen geschehen nie unbemerkt. +Belege: + - [PRIMÄR] BL/Sales/Receipts/ReceiptBL.cs:8636-8705 (CheckIfCustomerLimitIsReached, GetLimitUsedInReceipt) - Begründung: durchsetzende Limitprüfung mit Override-Flag SaveAlthoughCustomerLimitExceeded. +Prüfidee: Kunde mit Limit 1.000 und offenen Belegen 900: Ein neuer Auftrag über 200 löst den Überschreitungsdialog mit Differenz 100 aus. +Tracelinks: StRS-01, StRS-02, SwRS-015 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Forderungsrisiko begrenzen. +Status: belegt +``` + +``` +ID: SyRS-026 +Titel: Belegweiterverarbeitung mit Validierung (M01-M06 übergreifend) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Innendienst +Vorbedingung: Quellbeleg(e) ausgewählt. +Fakt: ReceiptBL validiert die Weiterverarbeitung (ValidateReceiptForwarding) über + Ziel-Belegart, Quellbelege und ReceiptToForward-Struktur; verarbeitete Belege + blockieren den Storno ("bereits weiterverarbeitet"). +Aussage: Das System soll Belege regelgeprüft in Folgebelege überführen und die + Verarbeitungsbeziehung beidseitig speichern. +Ergebnis: Vorgänger- und Folgebeleg referenzieren einander; unzulässige Weiterverarbeitungen werden abgewiesen. +Belege: + - [PRIMÄR] BL/Sales/Receipts/ReceiptBL.cs:1563, 2462 (ValidateReceiptForwarding) und Invoices/ReceiptInvoiceBL.cs:163-165 (GetReceiptForwardedInto blockiert Storno) - Begründung: durchsetzende Kettenlogik. +Prüfidee: Nach Auftrag→Rechnung ist die Rechnung als Folgebeleg des Auftrags sichtbar und der Auftrag nicht mehr frei löschbar/stornierbar. +Tracelinks: StRS-02 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Belegkettenintegrität. +Status: belegt +``` + +``` +ID: SyRS-027 +Titel: Gleichzeitige Belegbearbeitung erkennen (M01-M06 übergreifend) +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Zuverlässigkeit +Akteur: System +Vorbedingung: Zwei Benutzer bearbeiten denselben Beleg. +Fakt: Belege tragen einen ConcurrencyControlGuid; Änderungsoperationen vergleichen den + mitgegebenen Guid und weisen bei Abweichung mit "was changed in the meantime" + (MessageCode ChangedByOtherInstance) ab. +Aussage: Das System soll konkurrierende Belegänderungen erkennen und die spätere Änderung mit + verständlicher Meldung ablehnen statt Daten zu überschreiben. +Ergebnis: Kein stiller Verlust von Belegänderungen (Lost Update). +Belege: + - [PRIMÄR] BL/Sales/Receipts/ReceiptBL.cs:4808-4809 u. a. (Guid-Vergleich mit Fehlermeldung) - Begründung: durchsetzende Prüfung an allen Änderungspfaden. +Prüfidee: Benutzer A und B laden denselben Beleg; A speichert; Bs Speichern wird mit ChangedByOtherInstance abgewiesen. +Tracelinks: StRS-02, SwRS-005 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Mehrbenutzerbetrieb. +Status: belegt +``` + +``` +ID: SyRS-028 +Titel: Filialbezogene Belegrechte (M73/M70 übergreifend) +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Filialbenutzer +Vorbedingung: Einschränkendes Filialrecht ist gesetzt. +Fakt: CanUserCreateReceiptsInBranch/CanUserEditReceipt vergleichen die Filiale des + Mitarbeiters mit der Belegfiliale und weisen fremde Filialen mit Fehlermeldung ab; + Web-Accounts wird die Belegeinsicht über CanUserViewReceipt komplett verweigert. +Aussage: Das System soll bei gesetztem Filialrecht das Anlegen/Bearbeiten von Belegen fremder + Filialen verhindern; Web-Accounts sollen über die interne Belegsicht keine Belege + einsehen können. +Ergebnis: Belegzugriff folgt der Organisationsstruktur. +Belege: + - [PRIMÄR] BL/Sales/Receipts/ReceiptBL.cs:10251-10311 (CanUserCreateReceiptsInBranch, CanUserEditReceipt, CanUserViewReceipt mit Meldung "Web-Benutzer haben keine Berechtigung Belege einzusehen.") - Begründung: durchsetzende Prüfungen. +Prüfidee: Benutzer der Filiale A mit Einschränkungsrecht kann Beleg der Filiale B nicht speichern; ein Web-Account erhält bei Belegabruf über die interne Sicht einen Rechtefehler. +Tracelinks: StRS-13, StRS-16 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Mandanten-/Filialtrennung. +Status: belegt +``` + +## B. Einkauf + +``` +ID: SyRS-029 +Titel: Lieferantenbestellungen führen (M22) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Einkauf +Vorbedingung: Lieferant/Distributor existiert. +Fakt: SupplierOrderBL und SupplierOrderSpecificLogic implementieren Bestellungen als + eigene Belegart; EDI-Order-BLs (AlsoOrderBL, AlltronOrderBL, KomsaOrderBL, + Opentrans21OrderBL, EgisOrderBL) übertragen Bestellungen elektronisch. +Aussage: Das System soll Bestellungen an Lieferanten als Beleg führen und wahlweise + elektronisch an Distributoren übertragen. +Ergebnis: Die Bestellung liegt als Beleg vor und ist beim Distributor platziert. +Belege: + - [PRIMÄR] BL/Sales/Receipts/SupplierOrders/SupplierOrderBL.cs; BL/EDI/AlsoOrderBL.cs u. a. - Begründung: Belegart und Übertragungswege implementiert. +Prüfidee: Eine Bestellung an ALSO wird als EDI-Order übertragen und erhält die Distributor-Auftragsnummer zurück. +Tracelinks: StRS-08 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Einkaufskernprozess. +Status: belegt +``` + +``` +ID: SyRS-030 +Titel: Lieferantenrechnungen erfassen und aus PDF auslesen (M23) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Eingangsrechnung liegt vor (EDI, PDF oder manuell). +Fakt: SupplierInvoicesBL implementiert Eingangsrechnungen; EDI liest + Distributorrechnungen (auch ZUGFeRD 2.1) ein; ein PDF-Scanner mit konfigurierbaren + Strategien (feste Position, relativ zu Suchtext) extrahiert Daten aus + Lieferantenbeleg-PDFs. +Aussage: Das System soll Eingangsrechnungen manuell, per EDI und per PDF-Datenextraktion + erfassen können. +Ergebnis: Eingangsrechnungen liegen strukturiert zur Prüfung und FiBu-Übergabe vor. +Belege: + - [PRIMÄR] BL/Sales/Receipts/SupplierInvoices/SupplierInvoicesBL.cs; BL/Sales/Receipts/SupplierReceiptDocuments/PdfScanner.cs (+ FixedLocation-/RelativeToSearchText-Strategien) - Begründung: Erfassungswege implementiert. + - [PRIMÄR] BL/EDI/Zugferd/ZUGFeRD_BL.cs:38 (ReadInvoice) - Begründung: strukturierter Rechnungsimport. +Prüfidee: Ein Lieferanten-PDF mit konfigurierter Scanstrategie füllt Belegnummer und Betrag automatisch. +Tracelinks: StRS-08, StRS-12 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Eingangsrechnungsprozess. +Status: belegt +``` + +``` +ID: SyRS-031 +Titel: Wareneingang über Lieferantenlieferscheine (M24) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Lager +Vorbedingung: Bestellung ist unterwegs. +Fakt: SupplierDeliveryListBL implementiert Lieferantenlieferscheine; EDI-Lieferavis + (Delivery) wird je Distributor eingelesen; ZUGFeRD-Verarbeitung übernimmt + Seriennummern aus Produktdaten (SetSerialNumbersFromProduct21). +Aussage: Das System soll Wareneingänge auf Basis von Lieferantenlieferscheinen buchen und + dabei avisierte Seriennummern übernehmen. +Ergebnis: Bestände und Seriennummern entsprechen dem physischen Wareneingang. +Belege: + - [PRIMÄR] BL/Sales/Receipts/SupplierDeliveryLists/SupplierDeliveryListBL.cs; BL/EDI/Zugferd/ZUGFeRD_BL.cs:107 (SetSerialNumbersFromProduct21) - Begründung: Wareneingang inkl. Seriennummernübernahme. +Prüfidee: Ein EDI-Lieferavis mit Seriennummern erzeugt einen Lieferantenlieferschein, dessen Buchung die Seriennummern in den Bestand übernimmt. +Tracelinks: StRS-08, StRS-07 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Wareneingangsprozess. +Status: belegt +``` + +``` +ID: SyRS-032 +Titel: Lieferantengutschriften führen (M25) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Lieferant erteilt Gutschrift. +Fakt: SupplierCreditVoucherSpecificLogic bindet Lieferantengutschriften in die generische + Belegverarbeitung (SpecificLogics) ein. +Aussage: Das System soll Gutschriften von Lieferanten als eigene Belegart führen. +Ergebnis: Lieferantengutschriften mindern Verbindlichkeiten nachvollziehbar. +Belege: + - [PRIMÄR] BL/Sales/Receipts/SupplierCreditVouchers/SupplierCreditVoucherSpecificLogic.cs - Begründung: Belegart im SpecificLogics-Muster registriert. +Prüfidee: Eine erfasste Lieferantengutschrift erscheint in der Einkaufsbelegliste des Lieferanten. +Tracelinks: StRS-08 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Einkaufsbelegart. +Status: belegt +``` + +``` +ID: SyRS-033 +Titel: Dokumente zu Einkaufsbelegen (M26) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung / Einkauf +Vorbedingung: Einkaufsbeleg existiert. +Fakt: SupplierReceiptDocumentBL verwaltet Dokumente zu Lieferantenbelegen; ein eigenes + WPF-Modul (Finances.Receipts.SupplierReceiptDocuments) existiert. +Aussage: Das System soll Originaldokumente (z. B. PDF der Lieferantenrechnung) am + Einkaufsbeleg speichern und anzeigen. +Ergebnis: Der Originalbeleg ist am Datensatz archiviert. +Belege: + - [PRIMÄR] BL/Sales/Receipts/SupplierReceiptDocuments/SupplierReceiptDocumentBL.cs - Begründung: Dokumentverwaltung implementiert. +Prüfidee: Ein angehängtes PDF ist nach erneutem Öffnen des Belegs abrufbar. +Tracelinks: StRS-08, StRS-24 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Belegarchivierung. +Status: belegt +``` + +``` +ID: SyRS-034 +Titel: Bestellvorschläge ermitteln (M27) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Einkauf +Vorbedingung: Bedarf (Aufträge) und Bestände sind erfasst. +Fakt: OrderSuggestionListBL liefert Vorschläge nach Artikelbedarf, offenen Aufträgen, + Lagerbestand und freien Sonderabkommen (GetOrderSuggestionArticle/-Order/-WH, + GetFreeSpecAgreement). +Aussage: Das System soll Bestellvorschläge aus Auftragsbedarf, Lagerbestand und + Einkaufskonditionen berechnen. +Ergebnis: Der Einkäufer erhält eine priorisierte Vorschlagsliste je Lieferant. +Belege: + - [PRIMÄR] BL/Purchasing/OrderSuggestionList/OrderSuggestionListBL.cs (GetOrderSuggestion*-Methoden) - Begründung: Ermittlungslogik implementiert. +Prüfidee: Ein Auftrag über einen nicht lagernden Artikel erzeugt einen Bestellvorschlag in Höhe der Fehlmenge. +Tracelinks: StRS-08, StRS-07 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Beschaffungsplanung. +Status: belegt +``` + +``` +ID: SyRS-035 +Titel: Lieferanten- und Distributorenstamm (M28) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Einkauf +Vorbedingung: keine +Fakt: SupplierBL, DistributorBL (BL/Buying) und SearchSupplierBL/SupplierAssetBL + (BL/BusinessPartner) verwalten Lieferanten; AccountSuppliers erzwingt eindeutige + Lieferantennummern (Unique Constraint). +Aussage: Das System soll Lieferanten und Distributoren mit eindeutigen Nummern und + Einkaufskonditionen verwalten. +Ergebnis: Jeder Lieferant ist eindeutig identifizierbar. +Belege: + - [PRIMÄR] SSMS_DB_SCHEMA.sql:3854 (IX_AccountSuppliers_UniqueNumber UNIQUE auf Number) - Begründung: DB-erzwungene Eindeutigkeit. + - [SEKUNDÄR] BL/Purchasing/Suppliers/SupplierBL.cs, BL/BusinessPartner/SearchSupplierBL.cs - Begründung: Verwaltungslogik. +Prüfidee: Das Anlegen eines zweiten Lieferanten mit gleicher Nummer schlägt mit Constraint-Fehler fehl. +Tracelinks: StRS-01, StRS-08 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Einkaufsstammdaten. +Status: belegt +``` + +## C. Kunden / CRM + +``` +ID: SyRS-036 +Titel: Accountverwaltung mit Rechteprüfung (M29) +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Vertrieb/Innendienst +Vorbedingung: Benutzer angemeldet. +Fakt: AccountBL prüft vor Anlegen/Bearbeiten/Löschen/Suchen/Entsperren die Rechte + CREATE_/EDIT_/DELETE_/SEARCH_/UNLOCK_CUSTOMER (für Lieferanten analog) und weist + fehlende Rechte mit deutscher Fehlermeldung ab; Kundennummern sind per + DB-Constraint eindeutig. +Aussage: Das System soll Account-Operationen nur mit dem jeweiligen Einzelrecht zulassen und + Kundennummern systemweit eindeutig vergeben. +Ergebnis: Unberechtigte Account-Operationen werden abgewiesen; keine doppelten Kundennummern. +Belege: + - [PRIMÄR] BL/Accounts/AccountBL.cs:1305-1366 (CheckRightsFromUser + Fehlerpfade) - Begründung: durchsetzende Rechteprüfungen mit konkreten Prüfstellen. + - [PRIMÄR] SSMS_DB_SCHEMA.sql:3784 (IX_AccountCustomers_UniqueNumber) - Begründung: DB-erzwungene Nummerneindeutigkeit. +Prüfidee: Benutzer ohne CREATE_CUSTOMER erhält "Fehlende Rechte um Accounts zu erstellen"; doppelte Kundennummer wird vom Constraint verhindert. +Tracelinks: StRS-01, StRS-13, SwRS-051 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Stammdatenschutz. +Status: belegt +``` + +``` +ID: SyRS-037 +Titel: Adressen und Ansprechpartner je Account (M30) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertrieb/Innendienst +Vorbedingung: Account existiert. +Fakt: AccountAddressContactBL/ContactPersonBL verwalten Adressen und Kontakte; Belege + referenzieren Adresse und Ansprechpartner (AddressI3D, ContactPersonI3D); Kunden + können abweichende Rechnungsempfänger haben (AlternateInvoiceReceiver). +Aussage: Das System soll je Account mehrere Adressen und Ansprechpartner verwalten und in + Belegen referenzieren, einschließlich abweichender Rechnungsempfänger. +Ergebnis: Belege verwenden die korrekte Liefer-/Rechnungsadresse des Kunden. +Belege: + - [PRIMÄR] BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs:293-299 (GetAlternativeInvoiceReceiver) - Begründung: durchgesetzte Empfängerregel. + - [SEKUNDÄR] BL/Sales/Customers/Addresses/ (AccountAddressContactBL, ContactPersonBL) - Begründung: Verwaltungslogik. +Prüfidee: Ein Kunde mit abweichendem Rechnungsempfänger erhält Rechnungen an dessen Adresse/Kontakt. +Tracelinks: StRS-01 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Adressqualität. +Status: belegt +``` + +``` +ID: SyRS-038 +Titel: Kundenaktivitäten protokollieren (M31) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertrieb / System +Vorbedingung: Account existiert. +Fakt: AccountActivitiesBL schreibt Aktivitäten; Systemereignisse erzeugen Aktivitäten + automatisch (z. B. CreateActivityForTicketClosed beim Ticketabschluss); Belege sind + über AccountActivityForReceipt eindeutig mit Aktivitäten verknüpft (Unique Index). +Aussage: Das System soll manuelle und automatische Kundenaktivitäten in einer Historie je + Account führen und mit Auslöseobjekten (Ticket, Beleg) verknüpfen. +Ergebnis: Die Kundenhistorie zeigt alle Interaktionen chronologisch mit Objektbezug. +Belege: + - [PRIMÄR] BL/Accounts/Activities/AccountActivitiesBL.cs; BL/Sales/Support/HelpdeskCloseBL.cs:151 - Begründung: Schreiblogik inkl. automatischem Auslöser. + - [PRIMÄR] SSMS_DB_SCHEMA.sql:24173 (Unique Index AccountActivityForReceipt) - Begründung: eindeutige Belegverknüpfung. +Prüfidee: Ticketabschluss erzeugt genau eine Aktivität mit Ticketbezug in der Kundenhistorie. +Tracelinks: StRS-20 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - CRM-Kern. +Status: belegt +``` + +``` +ID: SyRS-039 +Titel: Kampagnen mit Phasen und Aktionen (M32) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Marketing +Vorbedingung: Zielgruppe vorhanden. +Fakt: CampaignBL, CampaignPhaseBL, CampaignPhaseActionBL und CampaignProcessBL + strukturieren Kampagnen in Phasen mit Aktionen und Entscheidungs-Textvorlagen. +Aussage: Das System soll Marketingkampagnen mit Phasen, Aktionen und Vorlagen abbilden und + deren Bearbeitungsstand je Kunde führen. +Ergebnis: Der Kampagnenfortschritt ist je Kunde und Phase nachvollziehbar. +Belege: + - [PRIMÄR] BL/Accounts/Campaigns/ (CampaignBL.cs, CampaignPhaseBL.cs, CampaignPhaseActionBL.cs, CampaignProcessBL.cs, CampaignDecisionTemplateTextBL.cs) - Begründung: Kampagnenstruktur implementiert. +Prüfidee: Eine Kampagne mit zwei Phasen führt Kunden phasenweise; abgeschlossene Aktionen sind je Kunde vermerkt. +Tracelinks: StRS-20 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Vertriebsunterstützung. +Status: belegt +``` + +``` +ID: SyRS-040 +Titel: Telemarketing und Mailings (M33) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Marketing / Telefonvertrieb +Vorbedingung: Adressbestand vorhanden. +Fakt: TelemarketingBL (+Action/Template/Reference/Text) und MailingDataBL/ + MailingTemplateBL implementieren Telefonaktionen und Serienmailings. +Aussage: Das System soll Telefonaktionen mit Gesprächsleitfäden und Serienmailings mit + Vorlagen an Kundengruppen unterstützen. +Ergebnis: Aktionen sind planbar, durchführbar und je Kontakt dokumentiert. +Belege: + - [PRIMÄR] BL/Sales/Marketing/ (TelemarketingBL.cs u. a.), BL/Mailings/ (MailingDataBL.cs, MailingTemplateBL.cs) - Begründung: implementierte Funktionen. +Prüfidee: Ein Mailing an eine Selektion erzeugt je Empfänger einen Versandeintrag. +Tracelinks: StRS-20, StRS-21 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Marktbearbeitung. +Status: belegt +``` + +``` +ID: SyRS-041 +Titel: Kundenumfragen inkl. automatischem Versand (M34) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Qualitätsmanagement +Vorbedingung: Umfragevorlage konfiguriert. +Fakt: SurveyProcessBL erzeugt Umfragen aus Vorlagen; beim Ticketabschluss wird bei + aktivierter Einstellung eine Umfrage an den Mailtext angehängt + (HelpdeskCloseBL.AddSurvey mit SurveySettings). +Aussage: Das System soll Kundenumfragen aus Vorlagen erzeugen und auf Wunsch automatisch nach + Ticketabschluss an den Meldenden versenden. +Ergebnis: Servicequalität wird systematisch beim Kunden abgefragt. +Belege: + - [PRIMÄR] BL/Sales/Support/HelpdeskCloseBL.cs:168-198 (AddSurvey mit ValueAttachmentForHelpdesk) - Begründung: durchgesetzter Automatikversand. + - [SEKUNDÄR] BL/Accounts/Survey/SurveyProcessBL.cs - Begründung: Umfrageerzeugung. +Prüfidee: Bei aktivierter Einstellung enthält die Abschlussmail eines Tickets den Umfragelink; ohne Einstellung nicht. +Tracelinks: StRS-20, StRS-05 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Qualitätsfeedback. +Status: belegt +``` + +``` +ID: SyRS-042 +Titel: CRM-Projekte (Verkaufschancen) (M35) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertrieb +Vorbedingung: Account existiert. +Fakt: CrmProjectBL verwaltet CRM-Projekte mit eigener Nummernvergabe (NumberGroup) und + Einstellungen (WPF-Modul Finances.Crm.Settings.CRMProject). +Aussage: Das System soll Verkaufschancen als CRM-Projekte mit Nummer, Status und + Kundenbezug führen. +Ergebnis: Der Vertriebstrichter ist je Chance nachvollziehbar. +Belege: + - [PRIMÄR] BL/Sales/Customers/CrmProjects/CrmProjectBL.cs (mit NextNumber-Verwendung) - Begründung: implementierte Chancenverwaltung. +Prüfidee: Ein neues CRM-Projekt erhält automatisch die nächste Nummer seines Nummernkreises. +Tracelinks: StRS-20, SyRS-023 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Vertriebssteuerung. +Status: belegt +``` + +``` +ID: SyRS-043 +Titel: Hotline-Konditionen je Kunde (M36) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Service +Vorbedingung: Kunde existiert. +Fakt: HotlineCustomCategoryBL und HotlineCustomItemBL verwalten kundenspezifische + Hotline-Kategorien und -Einträge. +Aussage: Das System soll je Kunde Hotline-Informationen (Kategorien, Einträge) hinterlegen, + die dem Servicemitarbeiter bei Anfragen angezeigt werden. +Ergebnis: Servicekräfte sehen kundenindividuelle Hotline-Hinweise. +Belege: + - [PRIMÄR] BL/Accounts/HotlineArea/ (HotlineCustomCategoryBL.cs, HotlineCustomItemBL.cs) - Begründung: Verwaltung implementiert. +Prüfidee: Ein am Kunden hinterlegter Hotline-Eintrag ist im Serviceprozess des Kunden sichtbar. +Tracelinks: StRS-05 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Servicewissen am Kunden. +Status: belegt +``` + +``` +ID: SyRS-044 +Titel: Kundenvereinbarungen (Account Contracts) (M37) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertrieb +Vorbedingung: Account existiert. +Fakt: AccountContractBL und AccountContractKindBL verwalten Vereinbarungen mit Arten je + Account; ein WPF-Modul (Finances.Crm.AccountContracts) existiert. +Aussage: Das System soll Rahmen-/Kundenvereinbarungen mit typisierten Arten je Account führen. +Ergebnis: Vereinbarungen sind je Kunde einsehbar und typisiert auswertbar. +Belege: + - [PRIMÄR] BL/Accounts/AccountContracts/ (AccountContractBL.cs, AccountContractKindBL.cs) - Begründung: Verwaltung implementiert. +Prüfidee: Eine Vereinbarung der Art X erscheint in der Vereinbarungsliste des Kunden mit Art X. +Tracelinks: StRS-20 +Konsolidierung: Kandidat: SyRS-009 (Verträge als Belegart) - beide bilden "Vertrag mit Kunde" ab; fachliche Abgrenzung (formlose Vereinbarung vs. abrechenbarer Vertragsbeleg) ist im Zielsystem explizit zu regeln. +Übernahmewürdigkeit: übernehmen - sofern nach Konsolidierungsentscheid noch nötig. +Status: belegt +``` + +## D. Service / Helpdesk + +``` +ID: SyRS-045 +Titel: Tickets anlegen und verwalten (M38) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Servicetechniker / Dispatcher +Vorbedingung: Benutzer besitzt Helpdesk-Rechte. +Fakt: HelpdeskBL speichert Tickets mit Kunde, konfigurierbaren Status, Typ, Prioritäten + und Kategorien; die Ticketnummer stammt aus dem Nummernkreis Helpdesk; Bearbeiter + (HelpdeskEditor) und Gerätebezüge werden geführt. +Aussage: Das System soll Tickets mit Kunde, Status, Typ, Priorität, Kategorien, Bearbeitern + und Gerätebezug führen und automatisch nummerieren. +Ergebnis: Jedes Ticket ist eindeutig nummeriert und vollständig klassifiziert. +Belege: + - [PRIMÄR] BL/Sales/Support/HelpdeskBL.cs:298-307 (Save mit Pflichtfeldprüfung), 515-519 (Nummer aus NumberGroupEnum.Helpdesk) - Begründung: durchsetzende Kernlogik. +Prüfidee: Zwei nacheinander angelegte Tickets erhalten fortlaufende Nummern des Helpdesk-Nummernkreises. +Tracelinks: StRS-05, SyRS-023 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Servicekern. +Status: belegt +``` + +``` +ID: SyRS-046 +Titel: Konfigurierbare Ticket-Pflichtfelder (M38) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator / Servicetechniker +Vorbedingung: Pflichtfeld-Einstellungen gesetzt. +Fakt: DoValidateMandatoryFields erzwingt immer einen Kunden und je nach Einstellung + Priorität, Typ und Hauptkategorie; Verstöße liefern MandatoryFieldsNotFilled mit + Sammelmeldung. +Aussage: Das System soll beim Ticketspeichern den Kunden immer und Priorität/Typ/ + Hauptkategorie gemäß Konfiguration als Pflichtfelder erzwingen. +Ergebnis: Unvollständige Tickets werden mit Auflistung der fehlenden Felder abgewiesen. +Belege: + - [PRIMÄR] BL/Sales/Support/HelpdeskBL.cs:658-702 (DoValidateMandatoryFields mit Settings HelpdeskPriorityFieldIsRequired u. a.) - Begründung: durchsetzende Pflichtfeldprüfung. +Prüfidee: Bei aktivierter Prioritätspflicht wird ein Ticket ohne Priorität mit "Keine Priorität ausgewählt." abgewiesen. +Tracelinks: StRS-05, SyRS-085 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Datenqualität im Service. +Status: belegt +``` + +``` +ID: SyRS-047 +Titel: Ticketabschluss mit Folgeaktionen (M38) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Servicetechniker +Vorbedingung: Ticket ist lösbar; Benutzer hat das Abschlussrecht. +Fakt: CloseHelpdesk setzt den konfigurierten Abschlussstatus und ClosedAt, löscht offene + Ticket-ToDos, erzeugt Historieneintrag, Kundenaktivität und Nexus-Benachrichtigung; + optional wird eine Abschlussmail mit Umfrage versendet. +Aussage: Das System soll beim Ticketabschluss den Abschlussstatus setzen und die definierten + Folgeaktionen (Historie, Aktivität, Benachrichtigung, optional Mail/Umfrage) + ausführen. +Ergebnis: Abgeschlossene Tickets sind konsistent dokumentiert und kommuniziert. +Belege: + - [PRIMÄR] BL/Sales/Support/HelpdeskCloseBL.cs:120-157 (CloseHelpdesk mit Folgeaktionen) - Begründung: durchsetzender Abschlussprozess. + - [KONTEXT] CentronRights.md (Recht "Request abschliessen") - Begründung: fachliches Abschlussrecht. +Prüfidee: Nach Abschluss trägt das Ticket den Abschlussstatus und ClosedAt; Historie und Kundenaktivität existieren; offene ToDos des Tickets sind entfernt. +Tracelinks: StRS-05, SwRS-048 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Serviceprozess. +Status: belegt +``` + +``` +ID: SyRS-048 +Titel: Mehrstufige Ticketeskalation (M39) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System (Eskalationslauf) +Vorbedingung: Aktive Eskalationstypen mit Stufenzeiten existieren. +Fakt: DoEscalation selektiert offene Eskalationseinträge, prüft je Ticket die Stufe + (WaitHourEsc1-3) unter Beachtung von Arbeitszeitfenster und Sa/So-Flags und + versendet Eskalationsmails; Läufe werden protokolliert; ein Testmodus existiert. +Aussage: Das System soll Tickets zeitgesteuert gegen bis zu drei Eskalationsstufen prüfen und + fällige Eskalationen per Mail auslösen und protokollieren. +Ergebnis: Überfällige Tickets eskalieren stufengerecht; jeder Lauf ist im Log nachvollziehbar. +Belege: + - [PRIMÄR] BL/Sales/Support/Escalation/EscalationBL.cs:223-332 (DoEscalation, ShouldEscalated, SetNextEscDay) - Begründung: durchsetzende Eskalationslogik. +Prüfidee: Ein Ticket mit Stufe-1-Wartezeit 4h eskaliert nach 4 Arbeitsstunden; samstags nur bei aktiviertem Samstags-Flag. +Tracelinks: StRS-06, SwRS-049 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - SLA-Sicherung. +Status: belegt +``` + +``` +ID: SyRS-049 +Titel: Zeiterfassung auf Tickets (M40) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Servicetechniker +Vorbedingung: Ticket existiert. +Fakt: HelpdeskTimerBL/HelpdeskTimeRecordingBL erfassen Zeiten mit Typ (inkl. Anfahrten + über AddressSpecialArticles), Unterschrift (HelpdeskTimerSignatureBL) und Log + (HelpdeskTimerLogBL); Rechte regeln Bearbeiten/Löschen/Verschieben von Zeiten + (nur wenn Ticket nicht in einem Beleg). +Aussage: Das System soll Arbeits- und Fahrtzeiten auf Tickets mit Typ und optionaler + Kundenunterschrift erfassen; Löschen/Verschieben soll nur solange möglich sein, wie + die Zeit nicht in einem Beleg abgerechnet ist. +Ergebnis: Erfasste Zeiten sind manipulationsgeschützt, sobald sie abgerechnet sind. +Belege: + - [PRIMÄR] BL/Sales/Support/ (HelpdeskTimerBL.cs, HelpdeskTimeRecordingBL.cs, HelpdeskTimerSignatureBL.cs, HelpdeskTimerLogBL.cs) - Begründung: Erfassungs- und Schutzlogik implementiert. + - [KONTEXT] CentronRights.md Abschnitte 7-9 (Zeiten bearbeiten/verschieben/löschen "nur wenn nicht Teil eines Belegs") - Begründung: fachliche Regel dokumentiert. +Prüfidee: Eine fakturierte Zeit lässt sich nicht mehr löschen; eine unterschriebene Zeit zeigt die Signatur im Servicebericht. +Tracelinks: StRS-05, SyRS-012 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Abrechnungsgrundlage. +Status: belegt +``` + +``` +ID: SyRS-050 +Titel: Checklisten auf Tickets (M41) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Servicetechniker +Vorbedingung: Checklistenvorlagen existieren. +Fakt: CentronChecklistBL verwaltet Checklisten und -punkte inkl. Vorlagen; Änderungen + werden protokolliert (ChangeLogBL); Rechte trennen Vorlagenpflege und Abarbeitung. +Aussage: Das System soll Checklisten aus Vorlagen an Tickets führen, deren Punkte abhakbar + machen und Änderungen protokollieren. +Ergebnis: Der Abarbeitungsstand je Ticket ist dokumentiert. +Belege: + - [PRIMÄR] BL/CheckListArea/ (CentronChecklistBL.cs, UpdateChecklistBL.cs, ChangeLogBL.cs) - Begründung: Checklistenlogik implementiert. + - [KONTEXT] CentronRights.md Abschnitt 16 (Checklistenrechte) - Begründung: Rechtekonzept dokumentiert. +Prüfidee: Das Abhaken eines Checklistenpunkts erzeugt einen Änderungslogeintrag mit Benutzer. +Tracelinks: StRS-05 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - standardisierte Abarbeitung. +Status: belegt +``` + +``` +ID: SyRS-051 +Titel: Ticketvorlagen und automatische Ticketerzeugung (C-FLOW) (M42) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Serviceleitung +Vorbedingung: Vorlagen sind gepflegt. +Fakt: HelpdeskPatternBL und HelpdeskCreationTemplateBL verwalten Ticketvorlagen; die + Doku beschreibt automatische Ticketerzeugung aus Vorlagen (z. B. wiederkehrende + Wartungstickets); Rechte für C-FLOW-Vorlagen existieren. +Aussage: Das System soll Tickets aus Vorlagen (inkl. Kategorien, Checklisten) automatisch + oder manuell erzeugen können. +Ergebnis: Wiederkehrende Serviceaufgaben entstehen ohne manuelle Anlage. +Belege: + - [PRIMÄR] BL/Sales/Support/HelpdeskPatternBL.cs, HelpdeskCreationTemplateBL.cs - Begründung: Vorlagenlogik implementiert. + - [KONTEXT] docs/features/automatic-helpdesk-creation-templates.md; CentronRights.md Abschnitt 17 - Begründung: dokumentierte Automatik und Rechte. +Prüfidee: Eine Vorlage mit Intervall erzeugt zum Stichtag ein Ticket mit den Vorlagenwerten. +Tracelinks: StRS-05 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Automatisierung wiederkehrender Aufgaben. +Status: belegt +``` + +``` +ID: SyRS-052 +Titel: Taskmanagement mit Aktionsausführung (M43) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Serviceleitung / System +Vorbedingung: Recht SHOW_TASKMANAGEMENT vorhanden. +Fakt: TaskManagementTaskBL verwaltet Aufgaben; ActionHandler (Helpdesk, Report) führen + typisierte Aktionen aus (ITaskManagementActionHandler). +Aussage: Das System soll geplante Aufgaben verwalten und typisierte Aktionen (Ticketaktion, + Reporterzeugung) automatisch ausführen. +Ergebnis: Fällige Aufgaben lösen ihre hinterlegte Aktion aus. +Belege: + - [PRIMÄR] BL/TaskManager/ (TaskManagementTaskBL.cs, TaskManagementHelpdeskActionHandler.cs, TaskManagementReportActionHandler.cs) - Begründung: Aufgaben- und Aktionslogik implementiert. + - [KONTEXT] CentronRights.md Abschnitt 18 (SHOW_TASKMANAGEMENT) - Begründung: Zugriffsrecht dokumentiert. +Prüfidee: Eine Aufgabe mit Helpdesk-Aktion erzeugt bei Fälligkeit die konfigurierte Ticketänderung. +Tracelinks: StRS-05 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Serviceautomatisierung. +Status: belegt +``` + +``` +ID: SyRS-053 +Titel: Ticketprojekte mit Abhängigkeiten (M44) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Projektleiter Service +Vorbedingung: Tickets existieren. +Fakt: TicketProjectBL verwaltet Ticketprojekte und Abhängigkeiten zwischen Tickets + (TicketProjectDependency). +Aussage: Das System soll Tickets zu Projekten bündeln und Abhängigkeiten zwischen Tickets + eines Projekts abbilden. +Ergebnis: Projektfortschritt und Reihenfolgen sind über Tickets hinweg sichtbar. +Belege: + - [PRIMÄR] BL/TicketProjects/TicketProjectBL.cs (GetTicketProjectDependencies, SaveOrUpdateTicketProjectDependency) - Begründung: Projekt- und Abhängigkeitslogik implementiert. +Prüfidee: Eine Abhängigkeit Ticket B nach Ticket A ist gespeichert und in der Projektansicht sichtbar. +Tracelinks: StRS-28, StRS-05 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - strukturierte Projektabwicklung. +Status: belegt +``` + +``` +ID: SyRS-054 +Titel: RMA-Abwicklung mit Ticketbindung (M45) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Service / Lager +Vorbedingung: Ticket existiert. +Fakt: RmaBL erzeugt RMAs zu Tickets (GetRmaByHelpdeskI3D); die DB erzwingt genau eine RMA + je Ticket (Unique Clustered Index auf Rma.HelpdeskI3D); RMA-Artikel mit Zuständen + (RmaArticleState) und Artikelhistorie existieren. +Aussage: Das System soll je Ticket höchstens eine RMA mit Artikelpositionen und Zuständen + führen. +Ergebnis: Retouren sind eindeutig ihrem Serviceticket zugeordnet. +Belege: + - [PRIMÄR] SSMS_DB_SCHEMA.sql:4176 (CREATE UNIQUE CLUSTERED INDEX CI_RMA_HelpdeskI3D) - Begründung: DB-erzwungene 1:1-Beziehung. + - [PRIMÄR] BL/CustomerArea/RmaBL.cs (SaveRma, GetRmaByHelpdeskI3D, CreateNewRmaArticle) - Begründung: Abwicklung implementiert. +Prüfidee: Das Anlegen einer zweiten RMA zum selben Ticket schlägt mit Index-Fehler fehl. +Tracelinks: StRS-05, StRS-07, SwRS-050 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Retourenprozess. +Status: belegt +``` + +``` +ID: SyRS-055 +Titel: Anbindung externer Helpdesk-Systeme (M46) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Konfiguration hinterlegt. +Fakt: Es existiert ausschließlich eine Konfigurationsklasse + (ExternalHelpdeskConfigurationBL); die eigentliche Übertragungs-/Synchronisations- + logik wurde in der Analyse nicht gefunden. +Aussage: [HYPOTHESE] Das System soll Tickets mit externen Helpdesk-Systemen austauschen + (Anlage/Statusabgleich), konfiguriert je Zielsystem. +Ergebnis: Tickets fließen zwischen c-entron und dem externen System. +Belege: + - [SEKUNDÄR] BL/ExternalHelpdesk/ExternalHelpdeskConfigurationBL.cs - Begründung: Konfigurationsverwaltung existiert; trägt die Austauschfunktion nur mittelbar. +Prüfidee: Nachweis einer Synchronisationsstrecke (z. B. Ticketanlage aus externem System) in einer Folgeanalyse; bis dahin Interview mit Fachbereich. +Tracelinks: StRS-05 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - sofern die Funktion produktiv genutzt wird; fehlende Belegtiefe klären. +Status: HYPOTHESE - Begründung: Nur Konfigurationsartefakt gefunden; Umfang und Richtung des Austauschs unbelegt. +``` + +``` +ID: SyRS-056 +Titel: Terminanfragen an Kunden (M47) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Servicetechniker / Endkunde +Vorbedingung: Ticket/Vorgang mit Terminbedarf. +Fakt: AppointmentRequestBL verwaltet Terminanfragen mit Vorschlägen + (AppointmentProposal) und verarbeitet Kundenantworten + (HandleAppointmentRequestReply); WebLink-Handler für Reminder existieren. +Aussage: Das System soll Kunden Terminvorschläge senden und deren Zu-/Absagen automatisch + verarbeiten. +Ergebnis: Bestätigte Termine entstehen ohne Telefonabstimmung. +Belege: + - [PRIMÄR] BL/AppointmentRequests/AppointmentRequestBL.cs (HandleAppointmentRequestReply, SaveOrUpdateAppointmentProposal) - Begründung: Anfrage-/Antwortlogik implementiert. +Prüfidee: Die Annahme eines Terminvorschlags durch den Kunden markiert den Vorschlag als angenommen. +Tracelinks: StRS-05, StRS-21 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Terminkoordination. +Status: belegt +``` + +``` +ID: SyRS-057 +Titel: ToDo-Listen mit Objektbezug (M48) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Alle Benutzer +Vorbedingung: keine +Fakt: ToDoBL liefert ToDos je Kunde, Objektart und Objekt (GetTodoEntries-Überladungen); + Ticket-ToDos werden beim Ticketabschluss gelöscht; Belege erzeugen ToDos über + ReminderDate (CreateOrUpdateToDoEntries). +Aussage: Das System soll Aufgaben mit Bezug auf Objekte (Kunde, Ticket, Beleg) führen und + bei Objektereignissen automatisch pflegen. +Ergebnis: Aufgaben verschwinden, wenn ihr Auslöser erledigt ist. +Belege: + - [PRIMÄR] BL/ToDoArea/ToDoBL.cs (GetTodoEntries je Objektart), BL/Sales/Support/HelpdeskCloseBL.cs:134 (DeleteHelpdeskToDos) - Begründung: Objektbezug und automatische Pflege. +Prüfidee: Ein Beleg mit Wiedervorlagedatum erzeugt ein ToDo; Ticketabschluss entfernt die Ticket-ToDos. +Tracelinks: StRS-05 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Aufgabensteuerung. +Status: belegt +``` + +``` +ID: SyRS-058 +Titel: Einschränkende Sichtbarkeitsrechte im Helpdesk (M38/M70) +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Servicetechniker +Vorbedingung: Einschränkendes Recht ist gesetzt. +Fakt: Das Rechtekonzept definiert einschränkende Rechte: "nur eigene Tickets" + (SHOW_HELPDESK_ONLY_OWN), "nur eigene Filiale" (SHOW_HELPDESK_ONLY_OWN_BRANCH), + Zuweisung nur an eigene Abteilungen; UserRightsConst enthält die zugehörigen + Konstanten; HelpdeskSearchBL filtert Ticketlisten. +Aussage: Das System soll bei gesetzten einschränkenden Rechten die Ticketsichtbarkeit auf + eigene Tickets bzw. die eigene Filiale begrenzen und Zuweisungen auf eigene + Abteilungen beschränken. +Ergebnis: Techniker sehen nur die für sie bestimmten Tickets. +Belege: + - [PRIMÄR] src/webservice/Centron.WebServices.Core/EntitiesWrongPlace/Administration/Rights/UserRightsConst.cs (Konstanten SHOW_HELPDESK_ONLY_OWN, SHOW_HELPDESK_ONLY_OWN_BRANCH, ASSIGN_HELPDESK_ONLY_TO_OWN_DEPARTMENTS) - Begründung: Rechtekatalog als Prüfgrundlage; Auswertung in HelpdeskSearchBL. + - [KONTEXT] CentronRights.md Abschnitte 1.1, 1.2, 4 - Begründung: dokumentierte Semantik der einschränkenden Rechte. +Prüfidee: Ein Benutzer mit SHOW_HELPDESK_ONLY_OWN sieht in der Ticketliste ausschließlich Tickets, bei denen er Bearbeiter oder Verantwortlicher ist. +Tracelinks: StRS-13, StRS-05 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Vertraulichkeit im Service. +Status: belegt +``` + +## E. Geräte / Assets / MSP + +``` +ID: SyRS-059 +Titel: Kundengeräte (AccountDevices) verwalten (M49) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Service +Vorbedingung: Account existiert. +Fakt: AccountDeviceBL verwaltet Geräte je Account mit Seriennummer, Modell, Hersteller, + Standort, Garantieablauf, Herkunftsart (OriginKind) und Soft-Delete (IsDeleted); + Änderungen sind protokollierbar (WriteAccountDeviceLog). +Aussage: Das System soll Kundengeräte mit Identifikations-, Garantie- und Standortdaten + führen und Änderungen protokollieren. +Ergebnis: Der Gerätebestand je Kunde ist aktuell und historisiert. +Belege: + - [PRIMÄR] BL/Devices/AccountDeviceBL.cs (SaveAccountDevice, DeleteAccountDevice, WriteAccountDeviceLog) und src/backend/Centron.Entities/Entities/Devices/AccountDevice.cs - Begründung: Verwaltung und Datenmodell. +Prüfidee: Ein gelöschtes Gerät bleibt mit IsDeleted/DeletedDate erhalten und verschwindet aus der aktiven Liste. +Tracelinks: StRS-19 +Konsolidierung: Kandidat: SyRS-020 (Stammblätter), SyRS-060 (AssetManagement) - dieselbe fachliche Entität "Kundengerät" in getrennten Datenhaltungen. +Übernahmewürdigkeit: übernehmen - im Zielsystem als Teil des konsolidierten Asset-Konzepts. +Status: belegt +``` + +``` +ID: SyRS-060 +Titel: IT-Dokumentation/Inventarisierung (DocuBoard) (M50) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Techniker / Dokumentation +Vorbedingung: DocuBoard-Anbindung konfiguriert. +Fakt: AssetManagement-BLs verwalten Partner, Artikelzuordnungen und + AD-Benutzerausschlüsse; die DB enthält AssetManagement-Tabellen (SNMP-OID-Klassen, + Ordnerberechtigungen, Check-Ergebnishistorie) mit Unique-Constraints. +Aussage: Das System soll automatisiert erhobene IT-Inventardaten (AD-Scans, SNMP) je Kunde + speichern, Artikeln zuordnen und mit Ordnerberechtigungen schützen. +Ergebnis: Die IT-Umgebung des Kunden ist dokumentiert und zugriffsgeschützt. +Belege: + - [PRIMÄR] BL/DocuBoard/ (AssetManagementPartnerBL.cs, AssetManagementArticleAssignmentBL.cs, AssetManagementADSystemUserExclusionBL.cs) - Begründung: Verwaltungslogik. + - [SEKUNDÄR] SSMS_DB_SCHEMA.sql:27995-30844 (AssetManagement*-Tabellen inkl. FolderPermissions) - Begründung: Datenmodell inkl. Berechtigungen. +Prüfidee: Ein AD-Scan-Ergebnis erscheint beim Kunden; ausgeschlossene AD-Benutzer fehlen in der Auswertung. +Tracelinks: StRS-19 +Konsolidierung: Kandidat: SyRS-020, SyRS-059 - Gerätedaten dreifach; im Zielsystem ein Asset-Modell. +Übernahmewürdigkeit: übernehmen - MSP-Dokumentationspflicht. +Status: belegt +``` + +``` +ID: SyRS-061 +Titel: RMM-Datenübernahme (M51) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: System (RMM-Anbindung) +Vorbedingung: RMM-Verbindung konfiguriert. +Fakt: RmmConnectionSettingsBL verwaltet RMM-Verbindungseinstellungen; die + Vertragsabrechnung verarbeitet RMM-basierte Artikelmengen + (Contract-Billing-RMM-Article-Logic dokumentiert; RiverbirdImportValues liest + Zählerwerte); ein REST-Teil CentronRestService.RMM existiert. +Aussage: Das System soll Mengen-/Zählerdaten aus RMM-Systemen entgegennehmen und der + Vertragsabrechnung bereitstellen. +Ergebnis: RMM-gemessene Leistungen fließen automatisch in die Abrechnung. +Belege: + - [PRIMÄR] BL/DataExchange/Rmm/RmmConnectionSettingsBL.cs; BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.Contracts.cs:2266 (RiverbirdImportValues) - Begründung: Übernahmepfad implementiert. + - [KONTEXT] docs/reference/receipts/Contract-Billing-RMM-Article-Logic.md - Begründung: dokumentierte Abrechnungslogik. +Prüfidee: Ein importierter RMM-Zählerwert erscheint als Zählerstand des zugehörigen Geräts/Vertrags. +Tracelinks: StRS-04, StRS-19 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - MSP-Automatisierung. +Status: belegt +``` + +``` +ID: SyRS-062 +Titel: MSP-Sammler und Vergütungsauswertung (M52) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung / MSP-Manager +Vorbedingung: MSP-Datenquellen liefern Mengen. +Fakt: MspCollectorsBL verwaltet MSP-Sammler und Auswertungseinstellungen + (GetMspEvaluationSettings mit Positionstextvariablen); aus MSP-Bewertungen entstehen + Sonderartikelpositionen am Vertrag + (CreateSpecialArticleToContractFromMspEvaluation). +Aussage: Das System soll MSP-Verbrauchsdaten sammeln, bewerten und als abrechenbare + Vertragspositionen mit variablem Positionstext bereitstellen. +Ergebnis: MSP-Leistungen werden periodengerecht als Vertragspositionen fakturiert. +Belege: + - [PRIMÄR] BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.cs:129-147 (CreateSpecialArticleToContractFromMspEvaluation) - Begründung: durchsetzende Überführung in Abrechnungspositionen. + - [SEKUNDÄR] BL/Statistics/MspCollectors/MspCollectorsBL.cs - Begründung: Sammlerverwaltung. +Prüfidee: Eine MSP-Bewertung erzeugt eine Vertragsposition mit ersetztem Variablentext und der bewerteten Menge. +Tracelinks: StRS-04, SwRS-064 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - MSP-Geschäftsmodell. +Status: belegt +``` + +## F. Lager / Logistik / Produktion + +``` +ID: SyRS-063 +Titel: Artikelstamm verwalten (M53) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Einkauf / Produktmanagement +Vorbedingung: keine +Fakt: ArticleBL (210 KB) verwaltet Artikel mit Preisen (EK/VK/UVP/Listenpreis), + Präzision, EAN, Warengruppen (MaterialGroupBL), Produktfamilien, Einheiten, + Staffelpreisen (ArticleVolumePricesBL), Historie (ArticleHistoryBL) und Log + (ArticleLogBL); ArticleImportBL importiert Artikeldaten. +Aussage: Das System soll Artikel mit Preisen, Warengruppen, Einheiten und Historie zentral + verwalten und Massenimporte unterstützen. +Ergebnis: Der Artikelstamm trägt alle für Einkauf, Verkauf und Lager nötigen Attribute. +Belege: + - [PRIMÄR] BL/Warehousing/ (ArticleBL.cs, ArticleImportBL.cs, MaterialGroupBL.cs, ArticleVolumePricesBL.cs, ArticleHistoryBL.cs) - Begründung: implementierte Stammdatenverwaltung. +Prüfidee: Ein importierter Artikel ist mit Warengruppe und Preisen in der Artikelsuche auffindbar; Preisänderungen erscheinen in der Historie. +Tracelinks: StRS-07, StRS-25 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kernstammdaten. +Status: belegt +``` + +``` +ID: SyRS-064 +Titel: Bestandsführung je Lager mit EK-Fortschreibung (M54) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Lager / System +Vorbedingung: Artikel und Läger existieren. +Fakt: ArticleStockBL führt Bestände je Artikel und Nebenlager (SecondaryStock), erhöht + Bestände bei Barcode-Artikeln nur bei aktivem ScanBarcode und schreibt beim + Wareneingang den EK fort (fix, letzter oder gleitender Durchschnitt inkl. Fracht/ + Versicherung/Kalkulationsfaktor). +Aussage: Das System soll Bestände lagerortgenau führen und den Artikel-EK gemäß der je + Artikel eingestellten Methode (Fixpreis, letzter EK, gleitender Durchschnitt) + fortschreiben. +Ergebnis: Bestand und bewerteter EK sind je Lagerort korrekt. +Belege: + - [PRIMÄR] BL/Warehousing/StockManagement/ArticleStockBL.cs:47-149 (IncreaseArticleStock mit ScanBarcode-Regel, UpdateArticlePurchasePrice mit NoMixedEk-Fallunterscheidung) - Begründung: durchsetzende Bestands- und EK-Logik. +Prüfidee: Wareneingang 10 Stück zu 8 € auf Bestand 10 Stück zu 10 € ergibt bei gleitendem Durchschnitt EK 9 €. +Tracelinks: StRS-07, SwRS-011, SwRS-046 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Bestandsbewertung. +Status: belegt +``` + +``` +ID: SyRS-065 +Titel: Inventur mit Scan-Erfassung (M55) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Lager +Vorbedingung: Inventur ist angelegt. +Fakt: InventoryNewBL prüft Erfassungen nach Art (Barcode, Artikeltext, Kommissionsauftrag), + behandelt Mehrfach-Barcodes, speichert Zählmengen je Gruppe/Lagerplatz und schließt + Läger und Inventur ab (CloseStorages/CloseInventory); nicht gefundene Seriennummern + kennen den Zustand LostAtStocktaking. +Aussage: Das System soll Inventuren mit Scan-Erfassung je Lagerplatz durchführen, Zählmengen + speichern und die Inventur lagerweise abschließen. +Ergebnis: Gezählte Bestände sind erfasst; fehlende Seriennummern sind als Inventurverlust markiert. +Belege: + - [PRIMÄR] BL/Warehousing/InventoryManagement/InventoryNewBL.cs:80-180 (SaveInventory, CheckInventory), 294-330 (CloseStorages/CloseInventory) - Begründung: durchsetzender Inventurprozess. + - [PRIMÄR] src/backend/Centron.Interfaces/Warehousing/BarcodeState.cs:21 (LostAtStocktaking) - Begründung: Verlustzustand kodiert. +Prüfidee: Ein gescannter Barcode erhöht die Zählmenge; nach Inventurabschluss sind Differenzen als Korrektur gebucht. +Tracelinks: StRS-07 +Konsolidierung: Kandidat: BL/Warehousing/InventoryBL.cs (alte Inventur) und InventoryNewBL.cs (neue Inventur) bilden denselben Prozess doppelt ab; im Zielsystem eine Inventur. +Übernahmewürdigkeit: übernehmen - gesetzliche Inventurpflicht; nur die neue Implementierung. +Status: belegt +``` + +``` +ID: SyRS-066 +Titel: Kommissionierung von Aufträgen (M56) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Lager +Vorbedingung: Lieferbare Aufträge existieren. +Fakt: CommissioningBL sucht kommissionierbare Auftragsköpfe/-positionen (Filter + Direktlieferung/Teillieferung/abgeschlossen); OrderCommissionBL und + PartialCommissionOrderBL (mit PartialCommissionOrderState) steuern (Teil-) + Kommissionen inkl. Mailbenachrichtigung. +Aussage: Das System soll Aufträge (auch teilweise) kommissionieren, den Kommissionsstatus + führen und Beteiligte benachrichtigen. +Ergebnis: Der Lieferfortschritt je Auftragsposition ist sichtbar. +Belege: + - [PRIMÄR] BL/Warehousing/CommissioningManagement/CommissioningBL.cs, BL/Warehousing/Commissions/PartialCommissionOrderBL.cs - Begründung: Kommissionierlogik implementiert. +Prüfidee: Eine Teilkommission über 5 von 10 Stück setzt den Teillieferstatus und lässt 5 Stück offen. +Tracelinks: StRS-07, StRS-02 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Lagerprozess. +Status: belegt +``` + +``` +ID: SyRS-067 +Titel: Seriennummern-/Barcodeverwaltung mit Lebenszyklus (M57) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Lager / Service +Vorbedingung: Artikel ist barcodegeführt. +Fakt: BarCode/SerialNumber-Entitäten und BarcodeBL verwalten serialisierte Einheiten; + BarcodeState kodiert 20 Zustände über Lager, Belege, RMA, Stammblatt, Inventur; + BarcodeHistoryBL protokolliert Zustandswechsel. +Aussage: Das System soll jede serialisierte Einheit mit eindeutigem Zustand über ihren + gesamten Lebenszyklus führen und Zustandswechsel historisieren. +Ergebnis: Zu jeder Seriennummer sind aktueller Zustand und Historie abrufbar. +Belege: + - [PRIMÄR] src/backend/Centron.Interfaces/Warehousing/BarcodeState.cs:5-30 - Begründung: Zustandskatalog. + - [PRIMÄR] BL/Warehousing/ (BarcodeBL.cs, BarcodeHistoryBL.cs) - Begründung: Zustandsführung und Historie. +Prüfidee: Verkauf einer Seriennummer wechselt InStock→InInvoice und erzeugt einen Historieneintrag. +Tracelinks: StRS-07, SwRS-045 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Rückverfolgbarkeit. +Status: belegt +``` + +``` +ID: SyRS-068 +Titel: Fertigungsaufträge (M58) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Produktion +Vorbedingung: Stücklistenartikel existiert. +Fakt: ProductionOrderBL verwaltet Fertigungsaufträge mit Positionen und Filtern; + ProductionOrderItemState kodiert Positionszustände; ArticleProductionBL und + PartListArticleBL verarbeiten Stücklisten. +Aussage: Das System soll Fertigungsaufträge mit Stücklistenpositionen und Positionsstatus + führen. +Ergebnis: Der Fertigungsfortschritt je Position ist verfolgbar. +Belege: + - [PRIMÄR] BL/Production/ProductionOrderBL.cs (SaveProductionOrder, GetProductionOrderItemsByFilter), src/backend/Centron.Interfaces/Production/ProductionOrderItemState.cs - Begründung: Auftrags- und Statuslogik. +Prüfidee: Ein Fertigungsauftrag zeigt je Position ihren Status; Statuswechsel sind gespeichert. +Tracelinks: StRS-27 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Konfektionierung. +Status: belegt +``` + +``` +ID: SyRS-069 +Titel: GLS-Versandanbindung (M59) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Lager +Vorbedingung: GLS-Zugang konfiguriert. +Fakt: Centron.Api.Gls enthält CentronGlsLogic mit Adress-/Paketstrukturen, Fehlercodes + (CentronGlsErrors) und UploadResult; ein Einstellungsmodul + (Finances.Receipts.Settings.GLS) existiert im Client. +Aussage: Das System soll Paketdaten an GLS übertragen, Fehler strukturiert zurückmelden und + die Versandkonfiguration im Client pflegbar machen. +Ergebnis: GLS-Labels/Sendungen entstehen aus Belegdaten. +Belege: + - [PRIMÄR] src/apis/Centron.Api.Gls/CentronGlsLogic.cs (+ CentronGlsErrors.cs) - Begründung: API-Client implementiert. +Prüfidee: Eine Sendung mit ungültiger PLZ liefert den GLS-Fehlercode im Ergebnis. +Tracelinks: StRS-26 +Konsolidierung: Kandidat: SyRS-070 (Shipcloud) - zwei Versandwege mit gleicher fachlicher Funktion; im Zielsystem über eine Versandabstraktion vereinheitlichen. +Übernahmewürdigkeit: übernehmen - aktiver Versandweg. +Status: belegt +``` + +``` +ID: SyRS-070 +Titel: Shipcloud-Versandanbindung (M60) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Lager +Vorbedingung: Shipcloud-Zugang konfiguriert. +Fakt: Centron.Api.Shipcloud enthält CentronShipcloudLogic mit Adress-, Paket- und + Billing-Strukturen sowie Zusatzservices (AdditionalService). +Aussage: Das System soll Sendungen über den Shipcloud-Broker (Multi-Carrier) erzeugen können. +Ergebnis: Versand über verschiedene Carrier ohne Einzelanbindung. +Belege: + - [PRIMÄR] src/apis/Centron.Api.Shipcloud/CentronShipcloudLogic.cs - Begründung: API-Client implementiert. +Prüfidee: Eine Sendung wird mit Carrier-Auswahl an Shipcloud übertragen und liefert eine Trackingnummer. +Tracelinks: StRS-26 +Konsolidierung: Kandidat: SyRS-069 (GLS) - gleiche fachliche Funktion Versand; vereinheitlichen. +Übernahmewürdigkeit: übernehmen - Carrier-Flexibilität. +Status: belegt +``` + +## G. Finanzen + +``` +ID: SyRS-071 +Titel: Zahlungseingänge erfassen und zuordnen (M61) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Rechnung existiert. +Fakt: IncomingPayment-Sätze werden je Rechnung gespeichert; das Löschen erfordert das + Recht INCOMING_PAYMENT_TRANSACTIONS und korrigiert den bezahlten Betrag der + Rechnung (UpdateReceiptIsPaid mit negativem Betrag, Log "Zahlungseingang gelöscht"); + ein Zahlungseingangs-Log mit laufender Nummer existiert. +Aussage: Das System soll Zahlungseingänge rechnungsbezogen erfassen und beim Löschen den + Zahlungsstand der Rechnung konsistent zurückrechnen; beides nur mit dem + Zahlungseingangsrecht. +Ergebnis: PaidFC der Rechnung entspricht jederzeit der Summe ihrer Zahlungseingänge. +Belege: + - [PRIMÄR] BL/Finances/Payments/PaymentsBL.cs:38-78 (DeleteIncomingPayment mit Rechteprüfung Zeile 43 und UpdateReceiptIsPaid) - Begründung: durchsetzende Konsistenz- und Rechtelogik. + - [SEKUNDÄR] BL/Finances/IncomingPayments/IncomingPaymentBL.cs (Log, Nummernvergabe) - Begründung: Protokollierung. +Prüfidee: Löschen eines Zahlungseingangs über 100 reduziert PaidFC der Rechnung um 100 und schreibt einen Logeintrag; ohne Recht wird die Aktion abgewiesen. +Tracelinks: StRS-09, StRS-13 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Zahlungsbuchführung. +Status: belegt +``` + +``` +ID: SyRS-072 +Titel: Onlinebanking: Umsatzabruf und automatische Zuordnung (M62) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: finAPI-Konfiguration je Bankkonto vorhanden. +Fakt: Kontoumsätze werden gespeichert und in drei Stufen zugeordnet: Rechnungsnummern im + Verwendungszweck (Regex nach Nummernkreislänge), Kunde per IBAN/Absender, Rechnungen + per Betrag; Buchung und Rückbuchung (BookAmounts/UndoBooking) sowie ein + Inspektor-Check mit Reparatur existieren. +Aussage: Das System soll Bankumsätze über finAPI abrufen, automatisch Kunden und Rechnungen + zuordnen, Buchungen ausführen und rückgängig machen können. +Ergebnis: Der Großteil der Zahlungseingänge wird ohne manuelle Zuordnung verbucht. +Belege: + - [PRIMÄR] BL/Finances/OnlineBanking/OnlineBankingAccountTransactionsBL.cs:524-643 (AutoCompleteSingleAccountTransaciton, SearchReceiptInvoicesByDescription mit Regex), 883 (BookAmounts), 1003 (UndoBooking), 1093 (InspectorCheck) - Begründung: durchsetzende Zuordnungslogik. + - [SEKUNDÄR] src/apis/Centron.APIs.FinAPI/FinApiClient.cs - Begründung: Bankzugang. +Prüfidee: Ein Umsatz mit gültiger Rechnungsnummer im Verwendungszweck wird der Rechnung zugeordnet; UndoBooking stellt den vorherigen Zustand her. +Tracelinks: StRS-09, SwRS-028 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Automatisierung der Zahlungszuordnung. +Status: belegt +``` + +``` +ID: SyRS-073 +Titel: SEPA-Lastschriftexport (M63) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Rechnungen mit Mandat und Bankverbindung sind fällig. +Fakt: ExportInvoices erzeugt SEPA-XML in fünf pain.008-Varianten, unterscheidet + Lastschrift/Abbuchung, nimmt die Mandantenbank aus der Einstellung (Bank 1-4), + markiert Rechnungen als exportiert, schreibt Zahlungseingangs-Logs, schließt + Rechnungen optional ("Abschluss über SEPA Export") und schreibt die + Mandatssequenz fort; eine Rücknahmefunktion öffnet Rechnungen wieder. +Aussage: Das System soll fällige Lastschriften als SEPA-pain.008-Datei exportieren, die + betroffenen Rechnungen kennzeichnen (optional schließen) und Exporte rückholbar + machen. +Ergebnis: Die Bank erhält eine normkonforme Lastschriftdatei; der Rechnungsstatus spiegelt den Einzug. +Belege: + - [PRIMÄR] BL/DataExchange/PaymentTransactions/PaymentTransactionBL.cs:132-345 (ExportInvoices, InvoiceExportDone, ResetInvoiceExportedFlag) - Begründung: durchsetzende Exportlogik samt Folgen. +Prüfidee: Ein Export mit aktivierter Abschluss-Einstellung setzt die Rechnung auf bezahlt mit Log "Abschluss über SEPA Export"; die Rücknahme öffnet sie wieder und reduziert PayedAmount. +Tracelinks: StRS-09, SwRS-026, SwRS-027 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Zahlungseinzug. +Status: belegt +``` + +``` +ID: SyRS-074 +Titel: Mahnläufe mit Mahnsperren (M64) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Überfällige Rechnungen existieren; Benutzer hat Mahnrechte. +Fakt: GetDunningCustomers prüft Rechte (ThrowIfUserHasInsufficentRights), lädt mahnbare + Kunden mit Rechnungen und Gutschriften, setzt DunningStopActive je Kunde und je + Rechnung; DunningLevel kennt Stufen 1-3; Mahnläufe (DunningRun) mit Status + existieren; Mahnmails nutzen Vorlagen. +Aussage: Das System soll Mahnläufe über mahnbare Kunden ausführen, Mahnsperren auf Kunden- + und Rechnungsebene beachten und je Rechnung die Mahnstufe (1-3) fortschreiben. +Ergebnis: Mahnungen ergehen nur an ungesperrte Kunden/Rechnungen mit korrekter Stufe. +Belege: + - [PRIMÄR] BL/Sales/Receipts/Invoices/Dunning/DunningBL.cs:58-113 - Begründung: durchsetzende Selektion inkl. Sperren und Rechten. + - [PRIMÄR] src/backend/Centron.Interfaces/.../DunningLevel.cs - Begründung: Stufenmodell. +Prüfidee: Eine Rechnung mit Mahnsperre fehlt im Lauf; eine zweifach gemahnte Rechnung erscheint mit Stufe 3 im nächsten Lauf. +Tracelinks: StRS-10, SwRS-030 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Forderungsmanagement. +Status: belegt +``` + +``` +ID: SyRS-075 +Titel: OPOS-Verwaltung und -Import (M65) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: FiBu liefert OP-Daten oder Rechnungen sind offen. +Fakt: OposRunBL und OposRunWebServiceBL verwalten OPOS-Läufe; BookKeeping-Importe + (IBookKeepingImportInterface, OposImportColumnSeparator) lesen OP-Listen aus + FiBu-Systemen ein. +Aussage: Das System soll offene Posten in Läufen verwalten und OP-Daten aus der FiBu + importieren, um Zahlungsstände abzugleichen. +Ergebnis: Der OP-Bestand in c-entron entspricht dem der FiBu. +Belege: + - [PRIMÄR] BL/Sales/Receipts/Invoices/Opos/OposRunBL.cs - Begründung: Laufverwaltung implementiert. + - [SEKUNDÄR] src/backend/Centron.Interfaces/DataExchange/BookKeeping/Settings/OposImports/ - Begründung: Importkonfiguration. +Prüfidee: Ein importierter OP-Ausgleich setzt die zugehörige Rechnung auf bezahlt. +Tracelinks: StRS-10, StRS-11 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Abstimmung mit FiBu. +Status: belegt +``` + +``` +ID: SyRS-076 +Titel: Buchhaltungsexport in Fremdformate (M66) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Exportkonfiguration je Format vorhanden. +Fakt: 28 Export-/Importklassen bedienen DATEV (ASCII EXTF 700, XML 2012/2020), Sage 50/ + Office Line, Lexware, Addison, Abacus, Navision, SAP, Schilling AS400, GDI, + Europa3000, Stotax und kundendefinierte Formate; Rechnungen kennzeichnen den + Exportstatus (IsReceiptExported blockiert Storno). +Aussage: Das System soll Belege und Personenkonten in das konfigurierte FiBu-Format + exportieren und exportierte Belege als exportiert kennzeichnen. +Ergebnis: Exportierte Belege sind gegen Storno geschützt und in der FiBu verbuchbar. +Belege: + - [PRIMÄR] src/backend/Centron.Gateway/DataExchange/BookKeeping/ (BookKeepingExportDatevAscii.cs:991-1029 u. a.) - Begründung: Formatimplementierungen. + - [PRIMÄR] BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs:167-168 (IsReceiptExported → Stornoverbot) - Begründung: durchgesetzte Exportfolge. +Prüfidee: Nach DATEV-Export einer Rechnung wird ihr Storno mit "bereits exportiert" abgewiesen. +Tracelinks: StRS-11, SwRS-029 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - FiBu-Pflichtschnittstelle; Formatliste im Zielsystem auf tatsächlich genutzte reduzieren. +Status: belegt +``` + +``` +ID: SyRS-077 +Titel: Bankverbindungen der Geschäftspartner (M67) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Account existiert. +Fakt: BankAccountBL verwaltet Bankkonten inkl. Autorisierungsstatus + (GetBankAccountsFromCustomer mit onlyAuthorized) und SEPA-Attributen + (DirectDebitType, ValidTo, AuthorizationNumber). +Aussage: Das System soll je Geschäftspartner Bankverbindungen mit SEPA-Mandatsattributen und + Autorisierungsstatus führen. +Ergebnis: Lastschriften greifen nur auf autorisierte, gültige Bankverbindungen zu. +Belege: + - [PRIMÄR] BL/Accounting/BankAccountBL.cs (GetBankAccountsFromCustomer(onlyAuthorized), SaveBankAccount) - Begründung: Verwaltung mit Autorisierung. + - [PRIMÄR] BL/DataExchange/PaymentTransactions/PaymentTransactionBL.cs:347-359 (RefreshBankInformation: ValidTo-Fortschreibung) - Begründung: Mandatspflege bei Nutzung. +Prüfidee: Eine nicht autorisierte Bankverbindung erscheint nicht in der Lastschriftauswahl. +Tracelinks: StRS-09 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Zahlungsstammdaten. +Status: belegt +``` + +## H. Administration / System + +``` +ID: SyRS-078 +Titel: Benutzeranmeldung mit Sitzungstickets (M69) +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Alle Benutzer +Vorbedingung: Benutzerkonto existiert. +Fakt: Der Login-Flow entschlüsselt die Anwendungs-GUID, wählt den Authenticator (Basic/ + AD/OpenIdConnect/WebAccount), validiert Benutzerstatus und liefert ein + Sitzungsticket; Tickets verfallen nach 30 Minuten (gleitend verlängert; 5 Minuten + für Monitoring-Connector, bis 24h für bestimmte Anwendungen); jede Webservice- + Methode mit [Authenticate] erzwingt Ticket oder API-Token. +Aussage: Das System soll Anmeldungen über konfigurierbare Verfahren durchführen, zeitlich + begrenzte Sitzungstickets ausstellen und jeden Dienstaufruf gegen Ticket/Token + prüfen. +Ergebnis: Ohne gültiges Ticket/Token wird jeder Aufruf abgewiesen. +Belege: + - [PRIMÄR] src/webservice/Centron.Host/Services/CentronRestService.cs:363-397 (Login-Flow) - Begründung: Anmeldefluss. + - [PRIMÄR] BL/Administration/Logins/TicketBL.cs:26-156 (TicketExpireInMinutes=30, RefreshTicketExpireDate) - Begründung: Ticketlebensdauer. + - [PRIMÄR] src/webservice/Centron.Host/AspNetCore/WcfBridge/Interception/Interceptors/AuthenticateInterceptor.cs:22-74 - Begründung: durchsetzende Prüfung an jedem Aufruf. +Prüfidee: Ein Aufruf ohne Ticket liefert "You need to provide a ticket"; nach 30 Minuten Inaktivität ist das Ticket ungültig. +Tracelinks: StRS-14, SwRS-032, SwRS-034, SwRS-041 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Zugangsschutz; Hashverfahren modernisieren (siehe SwRS-032). +Status: belegt +``` + +``` +ID: SyRS-079 +Titel: Kontodeaktivierung über Status und Zeitfenster (M69) +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Benutzerkonto existiert. +Fakt: ValidateAppUser verweigert den Login bei gesetztem Deaktiviert-Kennzeichen, bei + laufendem Deaktivierungszeitraum (AccountDisabledFrom/ToDate) und bei nicht mehr + aktivem Mitarbeiter (Ein-/Austrittstermin); jede Ablehnung wird geloggt. +Aussage: Das System soll Logins deaktivierter Konten (Kennzeichen, Zeitfenster oder + beendetes Beschäftigungsverhältnis) verweigern und den Grund protokollieren. +Ergebnis: Ausgeschiedene oder gesperrte Mitarbeiter haben keinen Zugang. +Belege: + - [PRIMÄR] BL/Administration/Logins/Auth/Authenticator.cs:157-217 (ValidateAppUser mit allen drei Prüfungen) - Begründung: durchsetzende Loginverweigerung. +Prüfidee: Ein Konto mit AccountDisabledFromDate=gestern wird abgewiesen; nach Ablauf des Bis-Datums funktioniert der Login wieder. +Tracelinks: StRS-14, StRS-30, SwRS-033 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Offboarding-Sicherheit. +Status: belegt +``` + +``` +ID: SyRS-080 +Titel: Gruppenbasierte Rechteverwaltung (M70) +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Benutzer/Gruppen existieren. +Fakt: Rechte hängen an Gruppen (Sichtrus), Benutzer an Gruppen (Sichmemb); die Prüfung + läuft per SQL-Join; Verwaltung umfasst Gruppen-CRUD, Rechte-Zuordnung, Kopieren von + Gruppen und Benutzerrechten, Standardgruppen-Reset und Rechte-Änderungslog + (AppRightLog). +Aussage: Das System soll Rechte ausschließlich über Gruppen zuweisen, Gruppen samt Rechten + kopierbar machen und Rechteänderungen protokollieren. +Ergebnis: Rechtevergabe ist auditierbar und effizient administrierbar. +Belege: + - [PRIMÄR] BL/Administration/Rights/AppRightsBL.cs:95-111 (SQL Sichtrus/Sichmemb), 168-497 (Gruppenverwaltung inkl. CopyRightGroupsForUser), 558 (GetAllAppRightLogs) - Begründung: durchsetzende Rechtelogik. +Prüfidee: Das Kopieren der Rechtegruppen von Benutzer A auf B verschafft B exakt As Gruppen; die Änderung erscheint im Rechte-Log. +Tracelinks: StRS-13, SwRS-038 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Berechtigungsadministration. +Status: belegt +``` + +``` +ID: SyRS-081 +Titel: Zwei-Faktor-Authentifizierung (M71) +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Benutzer / Administrator +Vorbedingung: 2FA global aktiviert und für den Benutzer eingeschaltet. +Fakt: ValidateTwoFactor prüft nach erfolgreicher Passwortprüfung einen zweiten Faktor + (E-Mail-Code oder RADIUS), merkt sich erfolgreiche Prüfungen je Anwendung+Maschine + für eine konfigurierbare Dauer (je Benutzer oder global; 0 = immer) und lehnt bei + Fehlschlag/Timeout den Login ab. +Aussage: Das System soll für 2FA-pflichtige Benutzer einen zweiten Faktor verlangen und die + Bestätigung gerätebezogen für die konfigurierte Dauer akzeptieren. +Ergebnis: Ohne zweiten Faktor kein Login; bekannte Geräte fragen erst nach Ablauf erneut. +Belege: + - [PRIMÄR] BL/Administration/Logins/TwoFactor/TwoFactorAuthBL.cs:33-120 (ValidateTwoFactor, HasToValidateTwoFactor) - Begründung: durchsetzende 2FA-Regel. + - [PRIMÄR] BL/Administration/Logins/Auth/BasicAuthenticator.cs:62-70 (2FA-Fehlschlag bricht Login ab) - Begründung: Einbindung in den Login. +Prüfidee: Benutzer mit 2FA und Gültigkeitsdauer 0 muss bei jedem Login bestätigen; mit Dauer 7 Tage erst nach Ablauf erneut. +Tracelinks: StRS-14, SwRS-037 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kontosicherheit. +Status: belegt +``` + +``` +ID: SyRS-082 +Titel: Lizenzprüfung für Anwendungen und Funktionen (M72) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System +Vorbedingung: Lizenzdaten sind geladen. +Fakt: CheckLicense prüft je Anwendungs-GUID Version und Anzahl (gleichzeitige Nutzung über + aktive Tickets) und liefert definierte Fehlercodes (LicenseMaximumReached); + Einzelfunktionen prüfen HasLicense/GetLicenseCount; die Kundennummer stammt aus der + Lizenzdatei. +Aussage: Das System soll beim Anwendungslogin Lizenzversion und Anzahl gleichzeitiger + Nutzungen prüfen und Funktionslizenzen (auch mengenbasiert) abfragbar machen. +Ergebnis: Lizenzverstöße verhindern Login bzw. Funktionsnutzung mit klarer Meldung. +Belege: + - [PRIMÄR] BL/Administration/Licensing/LicenseManager.cs:258-343 (CheckLicense, GetLicenseCount) - Begründung: durchsetzende Prüfungen. +Prüfidee: Bei Lizenzanzahl 5 und 5 aktiven Tickets schlägt der 6. Login mit LicenseMaximumReached fehl. +Tracelinks: StRS-15, SwRS-035 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Lizenzmodell; SaaS-tauglich neu schneiden. +Status: belegt +``` + +``` +ID: SyRS-083 +Titel: Mandanten-, Firmen- und Filialverwaltung (M73) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: keine +Fakt: MandatorBL verwaltet Mandanten inkl. Bankdaten (bis 4 Banken, SEPA-Gläubiger-ID) + und ESR-Index; BranchBL verwaltet Filialen mit Lagerzuordnung + (SaveAssignedSecondaryStocks) und Zentrale (GetHeadquarter); Nummernkreise werden + je Mandant/Filiale erzeugt. +Aussage: Das System soll Mandanten mit Bank-/SEPA-Daten und Filialen mit Lagerzuordnung + verwalten und je Einheit eigene Nummernkreise bereitstellen. +Ergebnis: Organisatorische Einheiten sind vollständig konfiguriert. +Belege: + - [PRIMÄR] BL/Administration/Company/ (MandatorBL.cs: GetMandatorBankInfo; BranchBL.cs: SaveAssignedSecondaryStocks; NumberGroupBL.cs:136-152) - Begründung: Verwaltungslogik. +Prüfidee: Eine neue Filiale erhält beim Nummernkreis-Refresh eigene Nummernkreise; ihre Lagerzuordnung wirkt in der Bestandssicht. +Tracelinks: StRS-16 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Organisationsabbildung. +Status: belegt +``` + +``` +ID: SyRS-084 +Titel: Mitarbeiterverwaltung (M74) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Personal / Administrator +Vorbedingung: keine +Fakt: EmployeeBL und Umfeld verwalten Mitarbeiter mit Abteilungen (inkl. Sortierung und + Zuordnung), Skills/Skillgruppen, Urlaub, RFID-Token, Favoriten, Einstellungen und + Teams; Mitarbeiterartikel (EmployeeArticleBL) verknüpfen Mitarbeiter mit + Abrechnungsartikeln. +Aussage: Das System soll Mitarbeiter mit Organisationseinheit, Qualifikationen, + Abwesenheiten und Abrechnungsartikeln verwalten. +Ergebnis: Personalstammdaten stehen Service, Kalender und Abrechnung zur Verfügung. +Belege: + - [PRIMÄR] BL/EmployeeArea/ (EmployeeBL.cs, EmployeeDepartmentBL.cs, EmployeeSkillsBL.cs, EmployeeHolidayBL.cs, EmployeeArticleBL.cs, TeamManagementBL.cs) - Begründung: implementierte Personalverwaltung. +Prüfidee: Ein Mitarbeiter mit Abteilungszuordnung erscheint in der Abteilungsliste; sein Mitarbeiterartikel wird in der Zeitabrechnung verwendet. +Tracelinks: StRS-30 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Personalstamm. +Status: belegt +``` + +``` +ID: SyRS-085 +Titel: Zentrale Anwendungseinstellungen (M75) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: keine +Fakt: Einstellungen liegen zweigleisig in Stammdat (legacy, AppSettingsConst) und + ApplicationSettings (aktuell, ~500 ApplicationSettingIDs mit Definitionstexten); + Zugriff erfolgt über Gruppen-Einstellungsklassen; fachliche Regeln (Pflichtfelder, + Rundung, Mailversand) hängen an Einstellungen. +Aussage: Das System soll fachliches Verhalten über zentral gepflegte, typisierte + Einstellungen konfigurierbar machen. +Ergebnis: Verhaltensänderungen erfolgen ohne Codeänderung über Einstellungen. +Belege: + - [PRIMÄR] src/backend/Centron.Interfaces/Administration/Settings/ApplicationSettingID.cs (~500 IDs) und ApplicationSettingDefinitions.cs - Begründung: Einstellungskatalog. + - [KONTEXT] docs/guides/development/settings-management.md - Begründung: dokumentiertes Zweitabellen-Konzept. +Prüfidee: Das Umschalten von HelpdeskPriorityFieldIsRequired ändert die Pflichtfeldprüfung ohne Neustart-Codeänderung. +Tracelinks: StRS-31, SwRS-054 +Konsolidierung: Kandidat: Stammdat- und ApplicationSettings-Einstellungen bilden dieselbe Funktion doppelt ab; im Zielsystem ein Einstellungssystem. +Übernahmewürdigkeit: übernehmen - Konfigurierbarkeit; nur eingleisig. +Status: belegt +``` + +``` +ID: SyRS-086 +Titel: DSGVO-Datenbereinigung und Löschrecht (M76) +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Datenschutzverantwortlicher +Vorbedingung: DSGVO-Modul lizenziert; Benutzer hat DSGVO-Rechte. +Fakt: GetDataSecurityCleanUpStats/DataSecurityExecuteCleanUp verlangen das Recht + ACCESS_CLEANUP_DATABASE und die Modulverfügbarkeit; Statistiken umfassen inaktive + Kunden, gelöschte Kunden, alte CRM-Einträge und Altbelege; + DsgvoDeleteRightGetContacts/DeleteContacts setzen das Löschrecht um. +Aussage: Das System soll DSGVO-relevante Altdaten kategorisiert ausweisen und deren + Bereinigung sowie die Löschung einzelner Kontakte nur mit DSGVO-Recht ausführen. +Ergebnis: Personenbezogene Daten sind fristgerecht und berechtigt löschbar. +Belege: + - [PRIMÄR] BL/Administration/DataSecurity/DataSecurityBL.cs:34-70 (Rechteprüfung), 377/787 (Löschrecht) - Begründung: durchsetzende DSGVO-Funktionen mit Prüfstellen. +Prüfidee: Ohne ACCESS_CLEANUP_DATABASE liefert die Statistik "Insufficient rights!"; die Löschung eines Kontakts entfernt dessen personenbezogene Daten. +Tracelinks: StRS-23, SwRS-052 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - gesetzliche Pflicht. +Status: belegt +``` + +``` +ID: SyRS-087 +Titel: Versionierte Datenbankmigration (M77) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System (Update) / Entwickler +Vorbedingung: Anwendungsupdate wird eingespielt. +Fakt: Nummerierte ScriptMethod-Klassen mit ApplicationVersion liefern SQL-Skripte; + ScriptHelpers bieten idempotente Operationen (AddColumnIfNotExists, + AddRightIfNotExists u. a.); SQL-Sammlungen (SQLScriptCollection*.xml) enthalten + Altskripte. +Aussage: Das System soll Schemaänderungen als nummerierte, versionsgebundene Skripte genau + einmal und idempotent ausführen. +Ergebnis: Jede Installation erreicht deterministisch den Zielschemastand. +Belege: + - [PRIMÄR] BL/Administration/Scripts/ScriptMethods/Scripts/ (ScriptMethod11356.cs u. a.) - Begründung: Migrationsmechanismus implementiert. + - [KONTEXT] docs/guides/database/create-scripts.md - Begründung: dokumentierter Prozess inkl. Nummernreservierung. +Prüfidee: Ein zweifach gestartetes Update führt ein AddColumnIfNotExists-Skript ohne Fehler erneut aus. +Tracelinks: StRS-31, SwRS-053 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Konzept; konkrete Skripte sind Altbestand. +Status: belegt +``` + +``` +ID: SyRS-088 +Titel: Hintergrunddienste für Datenqualität (M78) +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Zuverlässigkeit +Akteur: System +Vorbedingung: Webservice läuft. +Fakt: DataQualityService (ASP.NET Core BackgroundService) läuft stündlich, kapselt jede + Aufgabe in eigener Session mit Fehlerbehandlung; BackgroundServiceBL verwaltet + Dienstkonfiguration. +Aussage: Das System soll Datenpflegeaufgaben stündlich im Hintergrund ausführen, wobei + Fehler einzelner Aufgaben den Dienst nicht beenden. +Ergebnis: Datenqualitätsaufgaben laufen unbeaufsichtigt und robust. +Belege: + - [PRIMÄR] src/webservice/Centron.Host/AspNetCore/HostedServices/DataQualityService.cs - Begründung: Dienst implementiert. + - [KONTEXT] docs/Background Service/DataQualityService.md - Begründung: dokumentierte Ausführungsregeln. +Prüfidee: Eine absichtlich fehlschlagende Aufgabe wird geloggt; die übrigen Aufgaben des Laufs werden trotzdem ausgeführt. +Tracelinks: StRS-31, SwRS-057 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Betriebsautomatisierung. +Status: belegt +``` + +``` +ID: SyRS-089 +Titel: Telemetrie und Profiling (M79) +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Wartbarkeit +Akteur: Hersteller / Administrator +Vorbedingung: Telemetrie aktiviert. +Fakt: TelemetryBL und ProfilerBL existieren; ApplicationUserStatistics speichert + Benutzeraktionen (Unique-Index ActionUniqueCluster); ein Profiling-Modul ist im + Client registriert. Inhalt und Übertragungsweg der Telemetriedaten wurden nicht im + Detail analysiert. +Aussage: [HYPOTHESE] Das System soll Nutzungs- und Leistungsdaten (Benutzeraktionen, + Laufzeiten) erfassen und zur Produktverbesserung bzw. Fehleranalyse bereitstellen. +Ergebnis: Nutzungsstatistiken und Profildaten liegen zur Auswertung vor. +Belege: + - [SEKUNDÄR] BL/Telemetry/TelemetryBL.cs, BL/Administration/Profiling/ProfilerBL.cs, SSMS_DB_SCHEMA.sql:25499 (ApplicationUserStatistics) - Begründung: Erfassungsartefakte existieren; Zweck/Empfänger nur mittelbar belegt. +Prüfidee: Klärung mit Hersteller: Welche Daten werden erfasst, wohin übertragen, DSGVO-Bewertung; danach Codeverifikation der Übertragungsstrecke. +Tracelinks: StRS-31 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Produktverbesserung; Datenschutz im Zielsystem explizit regeln. +Status: HYPOTHESE - Begründung: Zweck und Datenfluss der Telemetrie nicht aus dem Code verifiziert. +``` + +``` +ID: SyRS-090 +Titel: Persönliche API-Zugriffstoken (M80) +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Administrator / Fremdsystem +Vorbedingung: AccessToken-Modul lizenziert. +Fakt: CreatePersonalToken erzeugt 48-Zeichen-Token (CSPRNG), speichert nur den + SHA-256-Hash, zeigt den Klartext einmalig, bindet Token an Mitarbeiter mit + optionalem Ablauf, prüft Lizenzanzahl und protokolliert alle Aktionen mit + IP-Adresse; die Webservice-Authentifizierung akzeptiert Token als Ticket-Ersatz. +Aussage: Das System soll persönliche API-Token mit Ablaufdatum ausstellen, ausschließlich + gehasht speichern und deren Nutzung/Verwaltung protokollieren. +Ergebnis: Fremdsysteme authentifizieren sich ohne Benutzerpasswort; kompromittierte Token sind deaktivierbar. +Belege: + - [PRIMÄR] BL/Administration/AccessTokens/AccessTokenBL.cs:125-194 (CreatePersonalToken), 457-488 (GenerateSecureToken/HashToken SHA-256), 387-398 (Validierung mit Log) - Begründung: durchsetzende Token-Sicherheitsregeln. + - [PRIMÄR] src/webservice/Centron.Host/.../AuthenticateInterceptor.cs:52-58 (Token als Authentifizierung) - Begründung: Nutzungspfad. +Prüfidee: Ein deaktivierter Token wird mit "Token ist deaktiviert." abgewiesen und der Versuch geloggt; der Klartext ist nach Erstellung nirgends mehr abrufbar. +Tracelinks: StRS-14, SwRS-040 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - moderne API-Sicherheit. +Status: belegt +``` + +``` +ID: SyRS-091 +Titel: Passwortmanager für Kundenzugangsdaten (M81) +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Servicetechniker +Vorbedingung: Passwortmanager lizenziert; Benutzer berechtigt. +Fakt: PasswordManagementBL speichert Zugangsdaten je Kunde/Asset und liefert Passwörter + nur entschlüsselt über GetDecryptedPassword mit Benutzerkontext (KeywordBL + entschlüsselt je Abruf). +Aussage: Das System soll Kundenzugangsdaten verschlüsselt speichern und nur berechtigten + Benutzern entschlüsselt anzeigen. +Ergebnis: Kundenpasswörter liegen nicht im Klartext vor; Zugriff ist benutzerbezogen. +Belege: + - [PRIMÄR] BL/PasswordManagementArea/PasswordManagementBL.cs:81-85 (GetDecryptedPassword mit appUser) - Begründung: durchsetzender Entschlüsselungspfad mit Benutzerbindung. +Prüfidee: Ein gespeichertes Passwort steht in der DB nicht im Klartext; der Abruf liefert es nur mit gültigem Benutzerkontext. +Tracelinks: StRS-13 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Servicealltag; Kryptoverfahren in Folgeanalyse prüfen. +Status: belegt +``` + +``` +ID: SyRS-092 +Titel: Kundenindividuelle Zusatztabellen (M82) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: keine +Fakt: CustomTableBL verwaltet kundenindividuelle Tabellen; ein Einstellungsmodul + (Global.CustomProperties.Settings) existiert im Client. +Aussage: Das System soll kundenindividuelle Zusatzfelder/-tabellen definieren und an + Objekten pflegen lassen. +Ergebnis: Individualdaten sind ohne Programmierung erfassbar. +Belege: + - [PRIMÄR] BL/Customizations/CustomTables/CustomTableBL.cs - Begründung: Verwaltung implementiert. +Prüfidee: Ein definiertes Zusatzfeld erscheint am Objekt und speichert Werte. +Tracelinks: StRS-01 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Anpassbarkeit; im Zielsystem als Custom-Fields-Konzept. +Status: belegt +``` + +``` +ID: SyRS-093 +Titel: Massenupdates auf Stammdaten und Belege (M83) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator / Power-User +Vorbedingung: Massenupdate-Vorlage definiert. +Fakt: MassUpdateBL verwaltet Vorlagen (MassUpdateTemplate) und sucht Belegpositionen für + Massenänderungen (SearchForReceiptUpdateItems). +Aussage: Das System soll wiederverwendbare Massenänderungen über Vorlagen definieren und auf + Treffermengen ausführen. +Ergebnis: Gleichartige Änderungen erfolgen in einem Lauf statt einzeln. +Belege: + - [PRIMÄR] BL/MassUpdate/MassUpdateBL.cs (SaveOrUpdateMassUpdate, SearchForReceiptUpdateItems) - Begründung: Vorlagen- und Suchlogik implementiert. +Prüfidee: Eine Vorlage ändert ein Feld auf allen Treffern; die Trefferliste entspricht dem Filter. +Tracelinks: StRS-01 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Administrationseffizienz. +Status: belegt +``` + +``` +ID: SyRS-094 +Titel: Benutzeroberflächen-Profile (M84) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator / Benutzer +Vorbedingung: keine +Fakt: UiProfileBL verwaltet UI-Profile; der Client speichert Layouts/Profile je Benutzer + (GUI/Profiles, GUI/Import). +Aussage: Das System soll Oberflächen-Layouts als Profile speichern und Benutzern zuweisen + können. +Ergebnis: Benutzer erhalten rollengerechte, gespeicherte Ansichten. +Belege: + - [PRIMÄR] BL/GUI/Profiles/UiProfileBL.cs - Begründung: Profilverwaltung implementiert. +Prüfidee: Ein gespeichertes Profil stellt nach Neuanmeldung dieselbe Spalten-/Layoutkonfiguration her. +Tracelinks: StRS-32 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - client-spezifische WPF-Layoutprofile; im Web-Zielsystem neu zu konzipieren. +Status: belegt +``` + +## I. Kommunikation + +``` +ID: SyRS-095 +Titel: E-Mail-Versand mit Vorlagen und Schutzmechanismen (M85) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Alle Benutzer / Systemprozesse +Vorbedingung: Mailkonfiguration vorhanden. +Fakt: CentronMailFactory erzeugt Mails über SMTP oder Microsoft Graph; MailTemplateBL + liefert Vorlagen mit Variablenersetzung (@@Variable@@), Signaturersetzung und + Standardtexten; eine Domain-Blacklist existiert; in Nicht-Release-Builds werden + externe Empfänger auf test@nexoware.com umgeleitet. +Aussage: Das System soll E-Mails über SMTP oder Microsoft Graph mit Vorlagen, Variablen und + Signaturen versenden und Empfänger gegen eine Blacklist prüfen. +Ergebnis: Mails gehen formatiert, personalisiert und nur an zulässige Empfänger. +Belege: + - [PRIMÄR] BL/Mail/Factory/CentronMailFactory.cs, BL/Mail/Protocols/ (SMTPMail.cs, GraphMail.cs), BL/Mail/Templates/MailTemplateBL.cs, BL/Mail/Blacklist/DomainBlacklistBL.cs - Begründung: Versand- und Vorlagenlogik implementiert. + - [PRIMÄR] src/backend/Centron.Common/DeveloperSecurity.cs:30-46 (ValidateAddress ersetzt externe Adressen in Nicht-Release-Builds) - Begründung: durchgesetzter Entwicklungsschutz. +Prüfidee: Eine Vorlage mit @@ProblemKurztext@@ wird beim Versand mit dem Ticketkurztext gefüllt; im DEBUG-Build erhält eine externe Adresse die Ersatzadresse. +Tracelinks: StRS-21, SwRS-059, SwRS-060 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kommunikationsbasis. +Status: belegt +``` + +``` +ID: SyRS-096 +Titel: Exchange-Synchronisation (EWS) (M86) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Benutzer mit Exchange-Postfach +Vorbedingung: EWS-Zugang konfiguriert. +Fakt: EWSConnection, EwsEmailAccess und EwsCalendarAccess implementieren Mail- und + Kalenderzugriff auf Exchange; ein dokumentiertes Bug-Protokoll zur Synchronisation + existiert. +Aussage: Das System soll E-Mails und Kalendereinträge mit Exchange-Postfächern + synchronisieren. +Ergebnis: ERP-Kalender/-Mails und Exchange sind konsistent. +Belege: + - [PRIMÄR] BL/Mail/Exchange/EwsHelper/ (EWSConnection.cs, EwsEmailAccess.cs, EwsCalendarAccess.cs) - Begründung: EWS-Zugriff implementiert. + - [KONTEXT] docs/features/exchange-sync-bugprotokoll.md - Begründung: dokumentierte Synchronisationsfälle. +Prüfidee: Ein im ERP angelegter Termin erscheint im Exchange-Kalender des Benutzers. +Tracelinks: StRS-21 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kalender-/Mailintegration; EWS-Ablösung (Graph) im Zielsystem beachten. +Status: belegt +``` + +``` +ID: SyRS-097 +Titel: MailScanner: Postfachverarbeitung zu Tickets (M87) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System +Vorbedingung: MailScanner-Profile und Workflows konfiguriert. +Fakt: MailScannerBL verwaltet Profile, Workflows (MailScannerWorkflowProcessDTO) und + Aufgaben; Prozesse können MailScanner-spezifisch geladen werden + (GetProcessesForMailScanner). +Aussage: Das System soll überwachte Postfächer regelbasiert verarbeiten und aus Mails + Tickets/Vorgänge erzeugen oder aktualisieren. +Ergebnis: Kundenmails werden ohne manuelle Sichtung zu Vorgängen. +Belege: + - [PRIMÄR] BL/MailScanner/MailScannerBL.cs (GetWorkflows, SaveProfile, SaveTasks), BL/Processes/ProcessBL.cs (GetProcessesForMailScanner) - Begründung: Regelverarbeitung implementiert. +Prüfidee: Eine Mail an das überwachte Postfach erzeugt gemäß Workflow ein Ticket mit Absenderzuordnung. +Tracelinks: StRS-21, StRS-05 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Eingangskanal Service. +Status: belegt +``` + +``` +ID: SyRS-098 +Titel: Telefonie-Integration (TAPI) (M88) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Innendienst / Service +Vorbedingung: TAPI-Anbindung konfiguriert. +Fakt: PhoneCallBL erzeugt und synchronisiert Anrufe, sucht Ansprechpartner zur + Rufnummer (SearchContactPersonByPhoneNumberV2) und persistiert Anruflisten; + Verbindungszustände sind kodiert (PhoneCallConnectionState). +Aussage: Das System soll ein- und ausgehende Telefonate erfassen, Anrufer anhand der + Rufnummer identifizieren und Anrufhistorien führen. +Ergebnis: Beim Anruf öffnet sich der richtige Kunde; Telefonate sind dokumentiert. +Belege: + - [PRIMÄR] BL/Tapi/PhoneCallBL.cs (CreatePhoneCall, SearchContactPersonByPhoneNumberV2, SyncPhoneCalls) - Begründung: Telefonielogik implementiert. + - [KONTEXT] docs/reference/architecture/tapi.md - Begründung: Architekturbeschreibung. +Prüfidee: Ein eingehender Anruf mit bekannter Nummer liefert den Ansprechpartner des Kunden. +Tracelinks: StRS-21 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Anruferkennung; Technologie (TAPI) im Web-Zielsystem ersetzen. +Status: belegt +``` + +``` +ID: SyRS-099 +Titel: Mitarbeiterkalender mit Ticket-Terminen (M89) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Alle Benutzer +Vorbedingung: Kalenderrecht vorhanden. +Fakt: CalendarBL verwaltet Darstellungs-, Synchronisations- und + Ticket-Termin-Einstellungen; Kalenderrechte (RIGHT_KALENDER, + "nur eigene" einschränkend) sind definiert. +Aussage: Das System soll Mitarbeiterkalender mit konfigurierbarer Darstellung führen, + Termine aus Tickets einblenden und die Sichtbarkeit über Rechte steuern. +Ergebnis: Terminplanung erfolgt integriert; fremde Kalender nur mit Recht. +Belege: + - [PRIMÄR] BL/Calendar/CalendarBL.cs (GetCalendarRepresentationSettings, GetAppointmentsForTicketsSettings) - Begründung: Kalenderlogik implementiert. + - [KONTEXT] CentronRights.md Abschnitt Kalender - Begründung: Rechtekonzept. +Prüfidee: Ein Benutzer mit "nur eigene"-Recht sieht ausschließlich eigene Einträge. +Tracelinks: StRS-21, StRS-13 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Einsatzplanung. +Status: belegt +``` + +``` +ID: SyRS-100 +Titel: Interne Chats mit Objektbezug (M90) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Alle Benutzer +Vorbedingung: keine +Fakt: ChatBL erzeugt Chats optional mit Objektbezug (objectKind/objectI3D), verwaltet + Mitglieder und liefert Nachrichten seitenweise (GetChatMessages mit page). +Aussage: Das System soll interne Chats, auch objektbezogen (z. B. zu einem Ticket), mit + Mitgliederverwaltung und Nachrichtenverlauf bereitstellen. +Ergebnis: Abstimmungen sind am Objekt dokumentiert. +Belege: + - [PRIMÄR] BL/Chats/ChatBL.cs (CreateChat mit objectKind, AddMemberToChat, GetChatMessages) - Begründung: Chatlogik implementiert. +Prüfidee: Ein zu Ticket T erstellter Chat erscheint in Ts Kontext; neue Mitglieder sehen den Verlauf. +Tracelinks: StRS-21 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - interne Kommunikation. +Status: belegt +``` + +``` +ID: SyRS-101 +Titel: Outlook-Add-In (M91) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Benutzer in Outlook +Vorbedingung: Add-In installiert und angemeldet. +Fakt: Das Blazor-basierte Outlook-Add-In zeigt Kundendaten, Ansprechpartner, Belege, + Dokumente und CRM-Aktivitäten zur geöffneten Mail (CustomerTab, ReceiptSearchTab, + DocumentsTab, CrmActivityPage). +Aussage: Das System soll in Outlook zur geöffneten E-Mail den zugehörigen Kunden mit + Kontakten, Belegen, Dokumenten und Aktivitäten anzeigen und Aktionen (z. B. + Aktivität anlegen) erlauben. +Ergebnis: ERP-Kontext direkt in Outlook ohne Anwendungswechsel. +Belege: + - [PRIMÄR] src/nexus/CentronNexus.OutlookAddIn/ (CustomerTab.razor, ReceiptSearchTab.razor, CrmActivityPage.razor, DocumentsTab.razor) - Begründung: Add-In-Funktionen implementiert. +Prüfidee: Beim Öffnen einer Mail eines bekannten Kontakts zeigt das Add-In dessen Kunden mit Belegliste. +Tracelinks: StRS-21 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Mail-zentrierte Arbeitsweise. +Status: belegt +``` + +``` +ID: SyRS-102 +Titel: Benutzerbenachrichtigungen Client und Web (M92) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System +Vorbedingung: Ereignis tritt ein (z. B. Ticketabschluss). +Fakt: CentronNotificationsBL/UserNotificationBL verwalten Benachrichtigungen; + NexusNotificationsBL erzeugt Web-Benachrichtigungen (z. B. + SaveClosedTicketNotifications) und ein SignalR-Hub verteilt sie live + (NotificationsHubHelper, SignalRNotificationsBackgroundService im Nexus-Host). +Aussage: Das System soll Ereignisbenachrichtigungen an betroffene Benutzer im Client und in + Echtzeit im Web zustellen. +Ergebnis: Benutzer erfahren relevante Ereignisse ohne aktives Nachsehen. +Belege: + - [PRIMÄR] BL/NexusNotifications/ (NexusNotificationsBL.cs, NotificationsHubHelper.cs); src/nexus/CentronNexus.Host/Program.cs:349-350 (SignalR-Notification-Service) - Begründung: Erzeugungs- und Zustellweg implementiert. +Prüfidee: Der Abschluss eines Tickets erzeugt beim Verantwortlichen eine Web-Benachrichtigung in Echtzeit. +Tracelinks: StRS-21, StRS-17 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Reaktionsgeschwindigkeit. +Status: belegt +``` + +## J. Datenaustausch / Schnittstellen + +``` +ID: SyRS-103 +Titel: EDI-Verarbeitung von Distributorbelegen (M93) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: System (EDI-Lauf) +Vorbedingung: EDI-Konfiguration je Lieferant vorhanden. +Fakt: SupplierEdiBL lädt Dateien (FTP/SFTP, ZIP), erkennt Datentyp und Belegart, parst je + Lieferantenformat (ALSO, ALSO CH, Alltron, Herweck, Komsa, OpenTrans 2.1), ordnet + Bestellungen zu und protokolliert in EDILog; ein Dispatcher (EDIDispatcherBL) + steuert die Verarbeitung. +Aussage: Das System soll Distributor-EDI-Dateien automatisch abholen, formatgerecht parsen, + den Bestellungen zuordnen und jede Verarbeitung protokollieren. +Ergebnis: Rückbelege der Distributoren entstehen automatisch mit Verarbeitungsprotokoll. +Belege: + - [PRIMÄR] BL/EDI/ (SupplierEdiBL.cs + Partials, EDIDispatcherBL.cs, EDILogBL.cs) - Begründung: Verarbeitungskette implementiert. + - [KONTEXT] docs/reference/edi/edi-architecture.md, edi-import-rules.md - Begründung: dokumentierter Ablauf und Regeln. +Prüfidee: Eine ALSO-Auftragsbestätigung wird der Bestellung zugeordnet; der EDI-Log zeigt den Verarbeitungsstatus. +Tracelinks: StRS-08, SwRS-062 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Belegautomatisierung. +Status: belegt +``` + +``` +ID: SyRS-104 +Titel: E-Rechnung erzeugen (ZUGFeRD/XRechnung) (M94) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Rechnung existiert; Kunde erfordert E-Rechnung. +Fakt: CreateZugferdFile erzeugt zu Rechnungen (nur InvoiceClass, keine Web-Accounts) + eine ZUGFeRD-/XRechnung-Datei mit Dateinamen aus Nummer+Version und der + Leitweg-ID des Kunden (IAccountCustomer.LeitwegID). +Aussage: Das System soll zu einer Rechnung auf Anforderung eine strukturierte + E-Rechnungsdatei mit der Leitweg-ID des Kunden erzeugen. +Ergebnis: Die E-Rechnungsdatei ist norm- und empfängergerecht benannt und befüllt. +Belege: + - [PRIMÄR] BL/WebServices/Sales/Receipts/ReceiptWebServiceBL.cs:2151-2185 (CreateZugferdFile) - Begründung: durchsetzende Erzeugung inkl. Einschränkungen. + - [SEKUNDÄR] docs/reference/zugferd-field-mapping.md - Begründung: Feldzuordnung dokumentiert. +Prüfidee: Für eine Rechnung wird eine Datei erzeugt; für ein Angebot wird die Anforderung mit "only 'InvoiceClass'" abgewiesen. +Tracelinks: StRS-12, SwRS-061 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - gesetzliche Pflicht. +Status: belegt +``` + +``` +ID: SyRS-105 +Titel: ebInterface-Unterstützung (Österreich) (M95) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Buchhaltung (AT-Kunden) +Vorbedingung: AT-Rechnungsempfänger. +Fakt: Centron.Api.EbInterface enthält EbInterfaceLogic für das österreichische + E-Rechnungsformat. +Aussage: Das System soll Rechnungen im ebInterface-Format für österreichische Empfänger + bereitstellen können. +Ergebnis: AT-Empfänger erhalten das nationale E-Rechnungsformat. +Belege: + - [PRIMÄR] src/apis/Centron.Api.EbInterface/EbInterfaceLogic.cs - Begründung: Formatlogik implementiert. +Prüfidee: Eine Rechnung an einen AT-Kunden lässt sich als ebInterface-Datei exportieren. +Tracelinks: StRS-12 +Konsolidierung: nein +Übernahmewürdigkeit: Sonderfall - nur für Österreich-Geschäft nötig. +Status: belegt +``` + +``` +ID: SyRS-106 +Titel: docuFORM-Anbindung (M96) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: System +Vorbedingung: docuFORM-Zugang (OAuth) konfiguriert. +Fakt: Centron.Api.docuFORM enthält einen REST-Client mit OAuth-Helper; docuFORM ist ein + Fleet-Management für Drucker. Der konsumierende Codepfad (z. B. Zählerimport) wurde + in der Analyse nicht nachvollzogen. +Aussage: [HYPOTHESE] Das System soll Gerätezähler-/Flottendaten von docuFORM abrufen und der + Klickabrechnung bereitstellen. +Ergebnis: docuFORM-Zähler fließen ohne manuelle Erfassung ein. +Belege: + - [SEKUNDÄR] Centron.Api.docuFORM/ (DocuFormRestApiClient.cs, OAuthHelper.cs) - Begründung: Client existiert; Konsument nicht verifiziert. + - [SEKUNDÄR] BL/DataExchange/DocuForm/ - Begründung: Verarbeitungsordner existiert. +Prüfidee: Codepfad vom DocuFormRestApiClient zur Zählerübernahme in einer Folgeanalyse nachweisen. +Tracelinks: StRS-04 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - sofern produktiv genutzt. +Status: HYPOTHESE - Begründung: Nutzungspfad des Clients (Zählerimport) nicht im Code nachvollzogen. +``` + +``` +ID: SyRS-107 +Titel: Icecat-Produktdatenanreicherung (M97) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Produktmanagement +Vorbedingung: Icecat-Zugang konfiguriert. +Fakt: IcecatApi liefert Produktbeschreibungen, Bilder und Kategorien; ein + Einstellungsmodul (Finances.Receipts.Settings.ICEcat) existiert im Client. +Aussage: Das System soll Artikelbeschreibungen und -bilder aus Icecat übernehmen. +Ergebnis: Artikel erhalten Herstellerdaten ohne manuelle Pflege. +Belege: + - [PRIMÄR] src/apis/Centron.APIs.IcecatDataAccess/IcecatApi.cs (+ Product/ProductImage/ProductDescription) - Begründung: Client implementiert. +Prüfidee: Zu einer EAN liefert der Abruf Beschreibung und Bild, die am Artikel gespeichert werden. +Tracelinks: StRS-25 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Datenqualität Artikel. +Status: belegt +``` + +``` +ID: SyRS-108 +Titel: ITscope-Produkt- und Bestellanbindung (M98) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Einkauf / Vertrieb +Vorbedingung: ITscope-API-Key vorhanden. +Fakt: ITscopeApi liefert Produkte, Preise, Zubehör und Bestellinformationen inkl. + API-Quota (ITscopeApiKeyQuota); die externe Artikelsuche bindet solche Quellen in + die Belegerfassung ein. +Aussage: Das System soll Produkte und Preise über ITscope suchen und für Belegpositionen + und Bestellungen nutzen. +Ergebnis: Marktverfügbare Artikel sind direkt bestell- und anbietbar. +Belege: + - [PRIMÄR] src/apis/Centron.APIs.ITscopeDataAccess/ITscopeApi.cs - Begründung: Client implementiert. + - [PRIMÄR] BL/Sales/Receipts/ArticleSearch/ArticleSearchBL.cs:1107-1126 (externe Suche) - Begründung: Einbindung in Belegprozess. +Prüfidee: Die externe Suche liefert ITscope-Treffer mit Preis; die Übernahme erzeugt eine Position. +Tracelinks: StRS-25 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Marktdatenzugang. +Status: belegt +``` + +``` +ID: SyRS-109 +Titel: COP-Datenzugriff (M99) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: System +Vorbedingung: COP-Zugang konfiguriert. +Fakt: CopApi liefert Produkt-, Hersteller-, Gruppen- und Preisdaten; Tests existieren. + Der fachliche Konsument (welches Modul COP-Daten wofür nutzt) wurde nicht + nachvollzogen. +Aussage: [HYPOTHESE] Das System soll Produkt-/Preisdaten aus COP beziehen und für + Artikelanreicherung bzw. Einkauf verwenden. +Ergebnis: COP-Daten stehen den Artikelprozessen zur Verfügung. +Belege: + - [SEKUNDÄR] src/apis/Centron.APIs.CopDataAccess/CopApi.cs (+ Product, Manufacturer, Price) - Begründung: Client existiert; Nutzung nicht verifiziert. +Prüfidee: Konsumentenpfad (Aufrufer von CopApi) in Folgeanalyse identifizieren. +Tracelinks: StRS-25 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - sofern produktiv genutzt. +Status: HYPOTHESE - Begründung: Aufrufer/Zweck des COP-Clients nicht belegt. +``` + +``` +ID: SyRS-110 +Titel: EGIS-Warenkorb und Bestellübertragung (M100) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Einkauf +Vorbedingung: EGIS-Zugang konfiguriert. +Fakt: EgisApi (Artikel-/Distributorsuche) und EDI-BLs (EgisWarenkorbBL, EgisOrderBL, + EgisOrderConfirmBL) implementieren Warenkorbübertragung und Bestellbestätigungen; + ein Gateway EDI_EGIS_Search existiert. +Aussage: Das System soll Warenkörbe/Bestellungen über EGIS an Distributoren übertragen und + Bestätigungen verarbeiten. +Ergebnis: EGIS-Bestellungen laufen ohne Portalwechsel. +Belege: + - [PRIMÄR] BL/EDI/ (EgisWarenkorbBL.cs, EgisOrderBL.cs, EgisOrderConfirmBL.cs), src/apis/Centron.APIs.EgisDataAccess/EgisApi.cs - Begründung: Übertragungslogik implementiert. +Prüfidee: Ein EGIS-Warenkorb wird übertragen und die Bestellbestätigung dem Vorgang zugeordnet. +Tracelinks: StRS-08, StRS-25 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Beschaffungsweg. +Status: belegt +``` + +``` +ID: SyRS-111 +Titel: Telekom-Dive-Schnittstelle (M101) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: System +Vorbedingung: Telekom-Dive-Zugang konfiguriert. +Fakt: TelekomDiveBL und ein WPF-Views-Ordner TelekomDive existieren; Inhalt und Richtung + des Datenaustauschs wurden nicht analysiert. +Aussage: [HYPOTHESE] Das System soll Daten mit dem Telekom-Dive-Portal austauschen + (vermutlich Auftrags-/Bestandsdaten für Telekom-Produkte). +Ergebnis: Telekom-Geschäftsvorfälle werden ohne Doppelerfassung übernommen. +Belege: + - [SEKUNDÄR] BL/DataExchange/TelekomDive/TelekomDiveBL.cs; src/centron/Centron.WPF.UI/Views/TelekomDive/ - Begründung: Artefakte existieren; Funktionsumfang unbelegt. +Prüfidee: Analyse der TelekomDiveBL-Methoden und der zugehörigen Views in einer Folgeiteration. +Tracelinks: StRS-25 +Konsolidierung: nein +Übernahmewürdigkeit: Sonderfall - nur für Telekom-Partner relevant. +Status: HYPOTHESE - Begründung: Fachlicher Inhalt der Schnittstelle nicht analysiert. +``` + +``` +ID: SyRS-112 +Titel: TANSS-Datenübernahme (M102) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Administrator (Migration) +Vorbedingung: TANSS-Datenzugang vorhanden. +Fakt: TanssBL existiert im DataExchange; TANSS ist ein branchengleiches Ticketsystem. + Umfang (einmalige Migration vs. laufender Abgleich) wurde nicht analysiert. +Aussage: [HYPOTHESE] Das System soll Daten (Tickets, Kunden, Zeiten) aus TANSS übernehmen, + mutmaßlich zur Migration von TANSS-Kunden. +Ergebnis: TANSS-Datenbestand steht in c-entron zur Verfügung. +Belege: + - [SEKUNDÄR] BL/DataExchange/TanssInterfaces/TanssBL.cs - Begründung: Artefakt existiert; Umfang unbelegt. +Prüfidee: Methodenanalyse TanssBL; Befragung, ob Migrations- oder Dauerschnittstelle. +Tracelinks: StRS-05 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - Migrationshilfe, im Zielsystem als Importwerkzeug neu bewerten. +Status: HYPOTHESE - Begründung: Nutzungsart der Schnittstelle unbelegt. +``` + +``` +ID: SyRS-113 +Titel: GfK-Absatzmeldung (M103) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Vertriebsleitung +Vorbedingung: GfK-Meldepflicht/-vereinbarung besteht. +Fakt: GfkExportBL erzeugt GfK-Exporte; ein Client-Modul + (DataExchange.PaymentTransactions.GFK) existiert. +Aussage: Das System soll Absatzdaten im GfK-Format exportieren. +Ergebnis: Die GfK-Meldung wird termingerecht aus Belegdaten erzeugt. +Belege: + - [PRIMÄR] BL/DataExchange/GfkExport/GfkExportBL.cs - Begründung: Exportlogik implementiert. +Prüfidee: Der Export eines Zeitraums enthält die Verkaufsmengen der meldepflichtigen Artikel. +Tracelinks: StRS-11 +Konsolidierung: nein +Übernahmewürdigkeit: Sonderfall - nur für GfK-Panel-Teilnehmer. +Status: belegt +``` + +``` +ID: SyRS-114 +Titel: Spezialimporte (z. B. HP-Quote) (M104) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Vertrieb +Vorbedingung: Importdatei liegt vor. +Fakt: HPQuoteImportBL importiert HP-Angebotsdaten; ArticleImportBL importiert + Artikeldaten; ProjectPriceImport existiert als Client-View. +Aussage: Das System soll herstellerspezifische Angebots-/Preisdateien (z. B. HP-Quotes) + importieren und in Belege/Artikel überführen. +Ergebnis: Herstellerangebote sind ohne Abtippen nutzbar. +Belege: + - [PRIMÄR] BL/DataExchange/Import/HPQuoteImportBL.cs; BL/Warehousing/ArticleImportBL.cs - Begründung: Importlogik implementiert. +Prüfidee: Der Import einer HP-Quote erzeugt die Positionen mit Preisen im Zielbeleg. +Tracelinks: StRS-25 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Herstellerprozesse. +Status: belegt +``` + +``` +ID: SyRS-115 +Titel: Konnektoren zu Drittsystemen (DocBee, c-time) (M105) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: System +Vorbedingung: Konnektor konfiguriert. +Fakt: DocBee-Konnektoren (Konfiguration, Ticket, Ticketvorlagen, Timer, WebHookClient) + und CTimeConnectorBL (Zeiterfassungsübernahme mit LastTransferDate) existieren. +Aussage: Das System soll Tickets/Zeiten mit DocBee austauschen und Zeitbuchungen aus c-time + übernehmen. +Ergebnis: Extern erfasste Zeiten und Tickets stehen in c-entron bereit. +Belege: + - [PRIMÄR] BL/DataExchange/Connectors/ (DocBeeTicketConnectorBL.cs, DocBeeTicketTimerBL.cs), BL/Services/ (CTimeConnectorBL.cs, CTimeConnectorLastTransferDate.cs) - Begründung: Konnektorlogik implementiert. +Prüfidee: Eine in c-time erfasste Zeit erscheint nach dem Übertragungslauf am richtigen Ticket. +Tracelinks: StRS-05, StRS-21 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Ökosystemanbindung. +Status: belegt +``` + +## K. Auswertung / Suche + +``` +ID: SyRS-116 +Titel: ReportEngine für Belegdrucke und Reports (M106) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Alle Benutzer +Vorbedingung: Reportvorlagen vorhanden. +Fakt: Die ReportEngine verwaltet Reportvorlagen mit Gruppen, Benutzerzuordnung, + Datenquellen (ReportDataQueryBL) und Import/Export; PDF-Erzeugung erfolgt über + PdfExport/CustomPdfGenerators mit Ersetzungslogik (ReplacementBLs); FastReport wird + unterstützt (FastReportHelper). +Aussage: Das System soll Belegdrucke und Auswertungen über verwaltbare Reportvorlagen mit + Datenquellen und Platzhaltern als PDF erzeugen. +Ergebnis: Jeder Belegdruck folgt der zugeordneten Vorlage. +Belege: + - [PRIMÄR] BL/ReportEngine/ (ReportDataBL.cs, ReportDataQueryBL.cs, ReportGroupBL.cs, FastReportHelper.cs, PdfExport/) - Begründung: Reportinfrastruktur implementiert. +Prüfidee: Der Rechnungsdruck verwendet die dem Belegtyp/Kunden zugeordnete Vorlage und füllt die Platzhalter. +Tracelinks: StRS-22 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Belegausgabe. +Status: belegt +``` + +``` +ID: SyRS-117 +Titel: Betriebswirtschaftliche Statistiken (M107) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Geschäftsleitung / Controlling +Vorbedingung: Bewegungsdaten vorhanden. +Fakt: Statistik-BLs existieren für Umsatz (RevenueStatisticBL), Verkauf + (SaleStatisticBL mit Cache), Aufträge (CacheOrderStatisticsBL), Rechnungen + (InvoiceStatisticBL), Verträge (ContractStatisticBL/ContractEvaluationBL), MSP + (MspStatisticBL), Tickets und Mitarbeiter (EmployeeUtilizationBL, + EmployeeTimeRecordsStatisticBL) sowie Management-Info (ManagementInfoBL). +Aussage: Das System soll Statistiken über Umsatz, Aufträge, Rechnungen, Verträge, Tickets + und Mitarbeiterauslastung bereitstellen, teils mit Caching für große Datenmengen. +Ergebnis: Kennzahlen sind je Dimension (Zeit, Kunde, Mitarbeiter) abrufbar. +Belege: + - [PRIMÄR] BL/Statistics/ (15 Statistik-BLs) - Begründung: Auswertungslogik implementiert. +Prüfidee: Die Umsatzstatistik eines Kunden entspricht der Summe seiner fakturierten Rechnungen im Zeitraum. +Tracelinks: StRS-22 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Steuerungsinformation. +Status: belegt +``` + +``` +ID: SyRS-118 +Titel: Volltext-Indexsuche (M108) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Alle Benutzer +Vorbedingung: Index ist aufgebaut. +Fakt: IndexSearchBL baut Volltextindizes (Lucene mit GermanAnalyzer) über Accounts und + Tickets auf, aktualisiert sie gezielt (RequestUpdateFor) und durchsucht sie + (SearchIndex mit Objektart-Filter); DocumentFulltextIndex existiert in der DB. +Aussage: Das System soll eine deutsche Volltextsuche über Kunden und Tickets mit + inkrementeller Indexpflege bereitstellen. +Ergebnis: Suchbegriffe finden Objekte auch bei Wortformvarianten. +Belege: + - [PRIMÄR] BL/IndexSearch/ (IndexSearchBL.cs, GermanAnalyzer.cs, AccountFulltextIndex.cs, TicketFulltextIndex.cs) - Begründung: Suchinfrastruktur implementiert. +Prüfidee: Nach Änderung eines Kundennamens findet die Suche den neuen Namen nach dem Indexupdate. +Tracelinks: StRS-01, StRS-05 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Auffindbarkeit. +Status: belegt +``` + +## L. Web (Nexus) und Webservice + +``` +ID: SyRS-119 +Titel: Nexus-Webanwendung mit Cookie-Anmeldung (M109) +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Web-Benutzer +Vorbedingung: Nexus ist bereitgestellt. +Fakt: Der Nexus-Host nutzt Cookie-Authentifizierung (MaxAge 12h, SameSite Lax), einen + OpenIdConnect-Zwischencookie, HSTS und HTTPS-Umleitung in Produktion sowie + SignalR mit konfigurierten Timeouts. +Aussage: Das System soll die Web-Anmeldung über Sitzungscookies mit 12-Stunden-Laufzeit + führen und Transportsicherheit (HTTPS/HSTS) erzwingen. +Ergebnis: Web-Sitzungen sind zeitlich begrenzt und transportverschlüsselt. +Belege: + - [PRIMÄR] src/nexus/CentronNexus.Host/Program.cs:264-276 (Cookie-Konfiguration), 395-398 (UseHsts/UseHttpsRedirection) - Begründung: durchsetzende Sicherheitskonfiguration. +Prüfidee: Nach 12 Stunden ist die Web-Sitzung ungültig; HTTP-Aufrufe werden in Produktion auf HTTPS umgeleitet. +Tracelinks: StRS-17, SwRS-067 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Web-Sicherheitsbasis. +Status: belegt +``` + +``` +ID: SyRS-120 +Titel: ServiceBoard: Web-Arbeitsplatz für den Service (M110) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Servicetechniker (Web) +Vorbedingung: Anmeldung mit Serviceboard-Lizenz. +Fakt: Das ServiceBoard umfasst Ticketliste/Kanban, Ticketdetails mit Zeiten, + Stoppuhren, Checklisten, Mails, Dokumenten, Karte, Berichte, KI-Zusammenfassung + (TicketAiSummary), Scheduler, Statistiken, Kundenverwaltung, Telefonate, MyDay und + Passwortmanager (34 Funktionsbereiche). +Aussage: Das System soll Servicetechnikern im Browser einen vollständigen Ticketarbeitsplatz + (Board, Details, Zeiten, Kommunikation, Planung) bereitstellen. +Ergebnis: Serviceprozesse sind vollständig im Web bearbeitbar. +Belege: + - [PRIMÄR] src/nexus/CentronNexus/ServiceBoard/ (Kanban/, TicketDetails/, Timerecords/, Stopwatches/, Scheduler/, TicketAiSummary/ u. a., 341 Dateien) - Begründung: implementierter Funktionsumfang. +Prüfidee: Ein Ticket lässt sich im Kanban verschieben; eine Stoppuhrzeit landet als Zeiterfassung am Ticket. +Tracelinks: StRS-05, StRS-17 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Leitbild für das Web-Zielsystem. +Status: belegt +``` + +``` +ID: SyRS-121 +Titel: WebCart: Kundenportal-Shop (M111) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Endkunde (Web-Account) +Vorbedingung: Web-Account mit Kundenzuordnung; aktive Sonderpreise. +Fakt: GetWebCartArticles erzwingt die Kundenzuordnung des Web-Accounts, liefert nur bei + aktiven Sonderpreisen Artikel und beschränkt die Suche auf Kundenartikel; das + Portal bietet Warenkörbe (auch Duplizieren/Import), Bestellhistorie, Tickets, + Verträge, Belege, Dokumente und Formulare. +Aussage: Das System soll Endkunden einen Shop anbieten, dessen Sortiment aus den für sie + aktiven Sonderpreisen besteht, mit Warenkorb-, Ticket- und Belegfunktionen. +Ergebnis: Kunden bestellen zu ihren vereinbarten Preisen; fremde Artikel/Daten sind unsichtbar. +Belege: + - [PRIMÄR] BL/WebServices/Sales/Receipts/ArticleSearch/ArticleSearchWebServiceBL.cs:71-99 (GetWebCartArticles) - Begründung: durchsetzende Sortiments- und Zugriffsregel. + - [SEKUNDÄR] src/nexus/CentronNexus/WebCart/ (WebCartShopPage.razor u. a.) - Begründung: Portalumfang. +Prüfidee: Ein Web-Account ohne aktive Sonderpreise sieht einen leeren Shop; mit Sonderpreisen genau diese Artikel. +Tracelinks: StRS-17, SwRS-043 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kunden-Self-Service. +Status: belegt +``` + +``` +ID: SyRS-122 +Titel: WebOffer: Online-Angebotsfreigabe (M112) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Endkunde +Vorbedingung: Angebot wurde online gestellt (SendToCustomer). +Fakt: WebReceiptState kodiert den Freigabefluss (InProcess, SendToCustomer, FirstLoaded, + AcceptFullWebReceipt, AcceptWebReceiptWithChangeRequests, Rejected, WebOfferSign, + WebOfferSignedWithoutSignature, WebReceiptShutDown); WebOffer-Seiten zeigen Beleg, + PDF-Vorschau, Adressänderung und Stücklistenmengen. +Aussage: Das System soll dem Kunden online das Angebot anzeigen und Annahme (ganz/mit + Änderungswünschen), Ablehnung oder Signatur als Zustandswechsel erfassen, + einschließlich des Erstöffnungszeitpunkts. +Ergebnis: Der Angebotsstatus spiegelt die Kundenreaktion unmittelbar wider. +Belege: + - [PRIMÄR] src/backend/Centron.Interfaces/Sales/Receipts/WebReceipt/WebReceiptState.cs:6-26 - Begründung: kodierter Freigabe-Zustandsautomat. + - [SEKUNDÄR] src/nexus/CentronNexus/WebOffer/ (WebReceiptOverview.razor, WebReceiptPdfPreview.razor) - Begründung: Oberflächenfluss. +Prüfidee: Erstes Öffnen setzt FirstLoaded; Annahme setzt AcceptFullWebReceipt; beide sind im Client sichtbar. +Tracelinks: StRS-18, SwRS-044 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - digitale Abschlussstrecke. +Status: belegt +``` + +``` +ID: SyRS-123 +Titel: Dokumentensignierung im Web (M113) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Endkunde / Techniker +Vorbedingung: Dokument liegt zur Unterschrift vor. +Fakt: DocumentSigningPage und IsolatedSignaturePad implementieren eine Web-Signaturseite; + Zeiterfassungen kennen Unterschriften (HelpdeskTimerSignatureBL, Recht + DELETE_HELPDESK_SIGNATURE). +Aussage: Das System soll Dokumente/Leistungsnachweise im Browser unterschreibbar machen und + die Unterschrift am Vorgang speichern. +Ergebnis: Unterschriebene Nachweise sind digital archiviert. +Belege: + - [PRIMÄR] src/nexus/CentronNexus/DocumentSigning/ (DocumentSigningPage.razor, IsolatedSignaturePad.razor) - Begründung: Signaturfunktion implementiert. +Prüfidee: Eine geleistete Unterschrift ist danach am Vorgang (z. B. Zeiterfassung) sichtbar. +Tracelinks: StRS-18, StRS-05 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - papierloser Nachweis. +Status: belegt +``` + +``` +ID: SyRS-124 +Titel: Fertigungsaufträge im Web (M114) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Produktion (Web) +Vorbedingung: Fertigungsaufträge existieren. +Fakt: Der Nexus-Bereich ProductionOrderManagement stellt Fertigungsaufträge im Browser + dar (4 Komponenten). +Aussage: Das System soll Fertigungsaufträge im Web einsehen und bearbeiten lassen. +Ergebnis: Produktionsstatus ist ohne WPF-Client zugänglich. +Belege: + - [PRIMÄR] src/nexus/CentronNexus/ProductionOrderManagement/ - Begründung: Web-Sicht implementiert. +Prüfidee: Ein Fertigungsauftrag ist im Web mit seinen Positionen sichtbar. +Tracelinks: StRS-27, StRS-17 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Webzugang Produktion. +Status: belegt +``` + +``` +ID: SyRS-125 +Titel: SelfCare-Formulare (M115) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Endkunde +Vorbedingung: Formulare sind definiert. +Fakt: SelfCareBL verwaltet SelfCare-Formulare mit Status (SelfCareFormState); + WebRequestPageBL bedient Web-Anfrageseiten; das Kundenportal zeigt Formularseiten + (CustomerPortalFormsPage/FormFillPage). +Aussage: Das System soll konfigurierbare Formulare für Endkunden im Web bereitstellen und + deren Einreichungen mit Status verwalten. +Ergebnis: Strukturierte Kundenanfragen ersetzen formlose Mails. +Belege: + - [PRIMÄR] BL/SelfCare/ (SelfCareBL.cs, WebRequestPageBL.cs); src/nexus/CentronNexus/WebCart/CustomerPortal/.../CustomerPortalFormsPage.razor - Begründung: Formularverwaltung und Portalseiten. +Prüfidee: Ein ausgefülltes Formular erzeugt einen Eintrag mit Status; der Bearbeiter kann den Status wechseln. +Tracelinks: StRS-17 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - strukturierte Aufnahme. +Status: belegt +``` + +``` +ID: SyRS-126 +Titel: Web-Accounts mit eigenem Rechtesystem (M116) +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Endkunde / Administrator +Vorbedingung: Web-Account ist angelegt. +Fakt: Web-Accounts melden sich mit Benutzername/Passwort (SHA1-Hash) an; der Login + verlangt eine durchgehend aktive Kette Kontakt→Adresse→Kunde und protokolliert + IP/Zeit; Web-Accounts besitzen ein eigenes Rechtesystem (WebRights über + WebAccountsRights) und Kundenadministratoren; die interne Belegsicht bleibt ihnen + verwehrt. +Aussage: Das System soll Endkunden-Logins als separate Web-Accounts mit eigenem, vom + Mitarbeiter-Rechtesystem getrenntem Rechtesatz führen und nur bei vollständig + aktiver Kundenbeziehung zulassen. +Ergebnis: Deaktivierte Kunden/Kontakte verlieren sofort den Portalzugang; Web-Rechte steuern den Portalumfang. +Belege: + - [PRIMÄR] BL/Administration/Logins/WebAccountBL.cs:54-105 (LoginWithWebAccount mit Aktivitätskette) - Begründung: durchsetzende Loginprüfung. + - [PRIMÄR] BL/Administration/Rights/AppRightsBL.cs:113-130 (CheckWebRightsFromUser über WebAccountsRights) - Begründung: getrenntes Web-Rechtesystem. +Prüfidee: Wird der Kunde gesperrt, schlägt der Web-Login fehl; ein Web-Recht steuert die Sichtbarkeit einer Portalfunktion. +Tracelinks: StRS-17, StRS-13, SwRS-039, SwRS-042 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Portalzugangsschutz; Hashverfahren modernisieren. +Status: belegt +``` + +``` +ID: SyRS-127 +Titel: Zentraler Webservice als Dienstschicht (M117) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Clients (WPF, Nexus, Add-In, Fremdsysteme) +Vorbedingung: Webservice läuft. +Fakt: CentronRestService bündelt die Fachdienste in 32 Teilservices (Accounts, Receipts, + Helpdesk, Finances, Warehousing …); jede Methode mit [Authenticate] wird per + Interceptor gegen Ticket/Token geprüft; je Methode sind erlaubte Anwendungen und + Web-Account-Zulassung deklarierbar; die Anmeldung entschlüsselt die Anwendungs-GUID. +Aussage: Das System soll alle Fachfunktionen über einen zentralen, authentifizierten + Webservice anbieten, mit deklarativer Beschränkung je Methode auf Anwendungen und + Kontotypen. +Ergebnis: Alle Clients nutzen dieselbe geprüfte Dienstschicht. +Belege: + - [PRIMÄR] src/webservice/Centron.Host/Services/CentronRestServiceParts/ (32 Teildateien); AuthenticateInterceptor.cs:22-61 (Applications-/WebAccount-Sperren) - Begründung: Dienstschicht und Prüfung implementiert. +Prüfidee: Eine für Web-Accounts gesperrte Methode liefert für Web-Accounts "You don't have the permission…". +Tracelinks: StRS-14, StRS-17, SwRS-055, SwRS-068 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Architekturprinzip für das Zielsystem (API-first). +Status: belegt +``` + +``` +ID: SyRS-128 +Titel: ConnectionManager für Dienstverbindungen (M118) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Installation vorhanden. +Fakt: Der ConnectionManager (WPF-Werkzeug) verwaltet Verbindungen und Zusatzdienste + (EditAdditionalServiceDialog) und zeigt Hardware-IDs (HardwareIdView) für die + Lizenzbindung. +Aussage: Das System soll ein Administrationswerkzeug zur Pflege der Dienst-/DB-Verbindungen + und zur Ermittlung der Hardware-ID bereitstellen. +Ergebnis: Verbindungs- und Lizenzdaten sind vor Ort wartbar. +Belege: + - [PRIMÄR] src/webservice/c-entron.misc.ConnectionManager/ (ConnectionManagerViewModel.cs, HardwareIdViewModel.cs) - Begründung: Werkzeug implementiert. +Prüfidee: Der ConnectionManager zeigt die konfigurierten Verbindungen und die Hardware-ID an. +Tracelinks: StRS-31 +Konsolidierung: nein +Übernahmewürdigkeit: veraltet - On-Premise-Werkzeug; im SaaS-Zielsystem entfällt die lokale Verbindungspflege. +Status: belegt +``` + +## M. Weitere Fachmodule + +``` +ID: SyRS-129 +Titel: MyCentron: persönliche Startseite (M119) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Alle Benutzer +Vorbedingung: Anmeldung erfolgt. +Fakt: MyCentron bietet Dashboards (DashboardContainerBL), Schnellnotizen (QuickNoteBL), + Planungen (SchedulingBL) und zuletzt verwendete Objekte + (LatestUsedCentronObjectBL). +Aussage: Das System soll je Benutzer eine Startseite mit Dashboards, Notizen, Planungen und + zuletzt verwendeten Objekten bereitstellen. +Ergebnis: Benutzer starten mit ihren relevanten Informationen. +Belege: + - [PRIMÄR] BL/MyCentron/ (DashboardContainerBL.cs, QuickNoteBL.cs, SchedulingBL.cs, LatestUsedCentronObjectBL.cs) - Begründung: Funktionen implementiert. +Prüfidee: Ein zuletzt geöffnetes Ticket erscheint in der Liste der letzten Objekte. +Tracelinks: StRS-22 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Einstiegskomfort. +Status: belegt +``` + +``` +ID: SyRS-130 +Titel: MyDay: Tagesansicht mit lizenzierten Importen (M120) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Servicetechniker +Vorbedingung: MyDay lizenziert; Importe konfiguriert. +Fakt: MyDayBL verwaltet Mitarbeiterauswahl, Arbeitspakete (WorkItems, Batch-Speichern) + und Benachrichtigungen; Importe aus Fremdtools (u. a. Supremo) sind je Import + lizenzpflichtig (LicenseGuids.MyDayImports mit Count). +Aussage: Das System soll eine Tagesansicht der Arbeitspakete je Mitarbeiter bereitstellen + und Fremdtool-Importe entsprechend der lizenzierten Anzahl zulassen. +Ergebnis: Techniker sehen ihren Tag; Importanzahl folgt der Lizenz. +Belege: + - [PRIMÄR] BL/MyDay/ (MyDayBL.cs, Supremo.cs, MyDayNotificationsBL.cs) - Begründung: Funktionsumfang implementiert. + - [KONTEXT] docs/reference/security/licensing-system.md (MyDay-Import-Beispiel mit Count) - Begründung: dokumentierte Mengenlizenz. +Prüfidee: Bei Lizenz-Count 3 lässt sich kein vierter Import konfigurieren. +Tracelinks: StRS-15, StRS-05 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Einsatzsteuerung. +Status: belegt +``` + +``` +ID: SyRS-131 +Titel: KI-Funktionen (Chat, Ticket-Zusammenfassung, Kategorisierung) (M121) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Benutzer +Vorbedingung: KI-Anbindung (OpenAI-kompatibel) konfiguriert. +Fakt: Die KI-Schicht enthält API-Clients (OpenAiApiClient, ChatModelApiClient, + TextRatingApiClient, TicketCategoryApiClient), einen Modellkatalog-Client, eine + Link-Validierung (AiApiLinkValidator) und Prompt-Verwaltung; das ServiceBoard + bietet Ticket-KI-Zusammenfassungen (TicketAiSummary). +Aussage: Das System soll KI-Dienste (Chat, Textbewertung, Ticketkategorisierung, + Ticketzusammenfassung) über konfigurierbare OpenAI-kompatible Endpunkte anbieten. +Ergebnis: Benutzer erhalten KI-Unterstützung im Fachkontext. +Belege: + - [PRIMÄR] BL/ArtificialIntelligence/ (OpenAiApiClient.cs, TicketCategoryApiClient.cs, TextRatingApiClient.cs); src/nexus/CentronNexus/ServiceBoard/TicketAiSummary/ - Begründung: KI-Anbindung implementiert. +Prüfidee: Die Ticket-Zusammenfassung liefert einen generierten Text zum Ticketverlauf. +Tracelinks: StRS-05 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Produktivitätsfunktion. +Status: belegt +``` + +``` +ID: SyRS-132 +Titel: TradePool-Anbindung (M122) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Einkauf/Vertrieb +Vorbedingung: TradePool-Daten liegen vor. +Fakt: TradePoolBL importiert Handelsdaten aus Dateien (StartTradeImport, XML-Logik) und + liefert Artikel-/Distributor-/Kundenlisten mit Filtern. Herkunft und fachlicher + Zweck der Plattform wurden nicht verifiziert. +Aussage: [HYPOTHESE] Das System soll Artikel-/Preisdaten einer Handelsplattform ("TradePool") + importieren und für Einkaufs-/Vertriebsentscheidungen bereitstellen. +Ergebnis: TradePool-Sortimente sind in c-entron durchsuchbar. +Belege: + - [SEKUNDÄR] BL/TradePool/ (TradePoolBL.cs, TradePoolXmlLogic.cs) - Begründung: Import und Listen existieren; fachlicher Kontext unbelegt. +Prüfidee: Klärung der Datenquelle und Nutzung; danach Verifikation des Importformats. +Tracelinks: StRS-25 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - sofern Plattform noch aktiv; sonst veraltet. +Status: HYPOTHESE - Begründung: Zweck und Aktualität der Plattformanbindung unbelegt. +``` + +``` +ID: SyRS-133 +Titel: Gutschein-/Voucherverwaltung (M123) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertrieb +Vorbedingung: Voucher existieren. +Fakt: VoucherManagementBL liefert aktivierte Voucher-Barcodes mit Filtern nach frei, + ausgegeben und eingelöst. +Aussage: Das System soll Gutscheine mit Barcode über die Zustände frei, ausgegeben und + eingelöst verwalten. +Ergebnis: Der Gutscheinbestand ist je Zustand auswertbar. +Belege: + - [PRIMÄR] BL/VoucherManagement/VoucherManagementBL.cs (GetActivedVoucherBarcodes mit Zustandsfiltern) - Begründung: Zustandsverwaltung implementiert. +Prüfidee: Ein eingelöster Voucher erscheint nur im Filter "eingelöst". +Tracelinks: StRS-02 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Gutscheingeschäft. +Status: belegt +``` + +``` +ID: SyRS-134 +Titel: Textbausteine (M124) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Alle Benutzer +Vorbedingung: Textbausteine gepflegt. +Fakt: TextModuleBL verwaltet aktive Textbausteine mit Filtern und liefert u. a. + Rechnungstexte je Benutzer und Kunde (GetInvoiceTextModule). +Aussage: Das System soll wiederverwendbare Textbausteine verwalten und kontextbezogen + (z. B. Rechnungstext je Kunde) bereitstellen. +Ergebnis: Standardtexte sind konsistent und schnell einfügbar. +Belege: + - [PRIMÄR] BL/TextModuleArea/TextModuleBL.cs (GetInvoiceTextModule, GetFilteredTextModuleList) - Begründung: Verwaltung implementiert. +Prüfidee: Der für einen Kunden hinterlegte Rechnungstext erscheint in dessen neuer Rechnung. +Tracelinks: StRS-02, StRS-21 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Texteffizienz. +Status: belegt +``` + +``` +ID: SyRS-135 +Titel: Verschlagwortung mit Tags (M125) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Alle Benutzer +Vorbedingung: keine +Fakt: TagsBL verwaltet aktive Tags und deren Zuordnung zu Tickets (AddTicketTag mit + LoggedInUser). +Aussage: Das System soll freie Schlagworte (Tags) verwalten und Objekten (mindestens + Tickets) zuordnen. +Ergebnis: Objekte sind über Tags filterbar. +Belege: + - [PRIMÄR] BL/Tags/TagsBL.cs (GetActiveTags, AddTicketTag) - Begründung: Tagging implementiert. +Prüfidee: Ein an ein Ticket vergebenes Tag findet das Ticket über die Tagsuche. +Tracelinks: StRS-05 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - flexible Klassifikation. +Status: belegt +``` + +``` +ID: SyRS-136 +Titel: Interner Social-Media-Stream (M126) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Alle Benutzer +Vorbedingung: keine +Fakt: SocialMediaBL bietet Streams mit Aktionen, Kommentaren, Likes und Abonnements auf + CRM-Aktivitäten und Tickets; PersonSocialNetworkBL verknüpft Personen mit + Social-Media-Profilen. +Aussage: Das System soll einen internen Aktivitätenstream mit Kommentaren, Likes und + Objekt-Abonnements (Ticket, CRM-Aktivität) bereitstellen. +Ergebnis: Teams verfolgen Objektereignisse als Stream. +Belege: + - [PRIMÄR] BL/SocialMedia/SocialMediaBL.cs (AddCommentToASocialMediaAction, SocialMediaSubscribeToHelpdesk) - Begründung: Streamfunktionen implementiert. +Prüfidee: Das Abonnieren eines Tickets zeigt dessen Ereignisse im eigenen Stream. +Tracelinks: StRS-21 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - interner Stream; im Zielsystem gegen Benachrichtigungen/Chat konsolidieren (siehe SyRS-100, SyRS-102). +Status: belegt +``` + +``` +ID: SyRS-137 +Titel: Videoportal-Zuordnungen (M127) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Videos existieren. +Fakt: VideoPortalAssignmentBL verwaltet Videozuordnungen (CRUD mit LoggedInUser). +Aussage: Das System soll Schulungs-/Hilfevideos verwalten und Bereichen zuordnen. +Ergebnis: Benutzer finden kontextbezogene Videos. +Belege: + - [PRIMÄR] BL/VideoPortal/VideoPortalAssignmentBL.cs - Begründung: Zuordnung implementiert. +Prüfidee: Eine Zuordnung macht das Video im Zielbereich sichtbar. +Tracelinks: StRS-32 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Hilfeangebot. +Status: belegt +``` + +``` +ID: SyRS-138 +Titel: Aktions-Weblinks (M128) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Endkunde / System +Vorbedingung: Weblink wurde versendet. +Fakt: WebLinkBL verwaltet Linkgruppen, Links, Aktionen und Klicks; Aktions-Handler + existieren für Kundenaktivitäten und Erinnerungen (WebLinkActionAccountActivity-/ + ReminderHandler). +Aussage: Das System soll personalisierte Weblinks mit hinterlegten Aktionen erzeugen, Klicks + protokollieren und die Aktion beim Klick ausführen. +Ergebnis: Kundenreaktionen auf Links lösen definierte Folgeaktionen aus. +Belege: + - [PRIMÄR] BL/WebLinks/ (WebLinkBL.cs, WebLinkActionAccountActivityHandler.cs, WebLinkActionReminderHandler.cs) - Begründung: Link-Aktionslogik implementiert. +Prüfidee: Der Klick auf einen Link erzeugt den Klick-Datensatz und führt die hinterlegte Aktion aus. +Tracelinks: StRS-21 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Interaktionsautomatisierung. +Status: belegt +``` + +``` +ID: SyRS-139 +Titel: Mobile Unterstützung (M129) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Mobiler Techniker +Vorbedingung: Mobiler Zugriff konfiguriert. +Fakt: MobileBL liefert mobile Mitarbeiterobjekte und Kontaktbilder; weitere mobile + Funktionalität wurde in der Analyse nicht gefunden. +Aussage: [HYPOTHESE] Das System soll mobile Clients mit Mitarbeiter- und Kontaktdaten + versorgen (vermutlich für eine separate Mobile App). +Ergebnis: Mobile Anwendungen erhalten Basisdaten. +Belege: + - [SEKUNDÄR] BL/Mobile/MobileBL.cs (GetMobileEmployee, GetContactPersonImage) - Begründung: schmale Datenbereitstellung; Zielclient unbelegt. +Prüfidee: Klärung, welche Mobile App die Endpunkte konsumiert; danach Funktionsumfang erheben. +Tracelinks: StRS-05 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - mobiler Zugriff gehört ins Web-Zielsystem (responsive). +Status: HYPOTHESE - Begründung: Konsument und Umfang der Mobilschnittstelle unbelegt. +``` + +``` +ID: SyRS-140 +Titel: Produktmatrix mit Kundenbewertungen (M130) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertrieb +Vorbedingung: Kategorien/Produkte gepflegt. +Fakt: ProductMatrixBL verwaltet Matrix-Kategorien, Produkte, Kundenbewertungen + (CustomerProductMatrixRating) und deren Änderungslog. +Aussage: Das System soll eine Produktmatrix führen, in der je Kunde der Status/die Bewertung + zu Produkten erfasst und historisiert wird. +Ergebnis: Cross-/Upselling-Potenziale sind je Kunde sichtbar. +Belege: + - [PRIMÄR] BL/ProductMatrix/ProductMatrixBL.cs (Rating + RatingChangeLog) - Begründung: Matrixlogik implementiert. +Prüfidee: Eine geänderte Kundenbewertung erzeugt einen Änderungslogeintrag. +Tracelinks: StRS-20 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Vertriebssteuerung. +Status: belegt +``` + +``` +ID: SyRS-141 +Titel: ItPlanner-Checklistenkategorien (M131) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Techniker / Planung +Vorbedingung: keine +Fakt: ChecklistVirtualObjectCategoryBL verwaltet virtuelle Objektkategorien für + Checklisten (auch von TimerBilling für Artikel-Arbeitspakete genutzt); weitere + Planner-Funktionalität wurde nicht gefunden. +Aussage: [HYPOTHESE] Das System soll IT-Planungsobjekte über kategorisierte Checklisten + strukturieren (Rest des ItPlanner-Moduls unklar). +Ergebnis: Planungsobjekte sind kategorisiert. +Belege: + - [SEKUNDÄR] BL/ItPlanner/ChecklistVirtualObjectCategoryBL.cs; Nutzung in TimerBillingBL.cs:133 (GetCategoryCaption) - Begründung: Kategorienverwaltung existiert; Modulzweck unbelegt. +Prüfidee: Klärung des ItPlanner-Funktionsumfangs (UI-Analyse) in Folgeiteration. +Tracelinks: StRS-05 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - sofern produktiv genutzt. +Status: HYPOTHESE - Begründung: Nur eine Randklasse gefunden; Modulzweck unklar. +``` + +``` +ID: SyRS-142 +Titel: Erwartete Ereignisse (Wiedervorlagen) (M132) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertrieb / Service +Vorbedingung: Account existiert. +Fakt: ExpectedEventsBL verwaltet erwartete Ereignisse je Account mit Logeinträgen; + Client-Module für Erfassung und Auswertung existieren (Helpdesk.ExpectedEvents, + ExpectedEventsReporting). +Aussage: Das System soll erwartete Ereignisse (z. B. Vertragsverlängerungen, Garantieabläufe) + je Kunde führen, protokollieren und auswertbar machen. +Ergebnis: Anstehende Ereignisse sind rechtzeitig sichtbar. +Belege: + - [PRIMÄR] BL/ExpectedEvents/ExpectedEventsBL.cs (SaveExpectedEvent, GetAllExpectedEventsByAccount, SaveExpectedEventLogEntry) - Begründung: Verwaltung implementiert. +Prüfidee: Ein erfasstes Ereignis erscheint in der Auswertung des Kunden mit Loghistorie. +Tracelinks: StRS-20 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - proaktiver Vertrieb. +Status: belegt +``` + +``` +ID: SyRS-143 +Titel: CPra-Webhook-Anbindung (M133) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: System +Vorbedingung: CPra-Zugang konfiguriert. +Fakt: CPraConnectorBL meldet sich an CPra an, listet Webhooks und erzeugt Webhook-Links + mit Kunden-/Ticketkontext; CPraConfigurationSettingsBL hält die Konfiguration. + Das Zielsystem "CPra" wurde nicht identifiziert. +Aussage: [HYPOTHESE] Das System soll Vorgänge über CPra-Webhooks mit Kunden-/Ticketbezug an + ein Partnersystem übergeben. +Ergebnis: CPra-Aktionen sind aus c-entron heraus auslösbar. +Belege: + - [SEKUNDÄR] BL/CPra/ (CPraConnectorBL.cs mit GetCPraWebHookLink(customerNumber, ticketI3D …)) - Begründung: Webhook-Mechanik implementiert; Zielsystemzweck unbelegt. +Prüfidee: Klärung, welches Produkt CPra ist und welche Prozesse die Webhooks auslösen. +Tracelinks: StRS-25 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - sofern Partnerprodukt aktiv. +Status: HYPOTHESE - Begründung: Zielsystem und fachlicher Zweck unbelegt. +``` + +``` +ID: SyRS-144 +Titel: RiverSuite-/Divo-Anbindung mit Ticketerzeugung (M134) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Fremdsystem RiverSuite +Vorbedingung: RiverSuite-Kopplung konfiguriert. +Fakt: RiverDivoBL validiert River-Tickets/RMM-AccessKeys und erzeugt Helpdesk-Tickets aus + RiverSuite-Anfragen (CreateHelpdeskRequest); unbearbeitete Tickets können wieder + geschlossen werden (CloseHelpdeskIfUnedited); Vertragsartikel-Referenzen existieren. +Aussage: Das System soll authentifizierte Anfragen aus der RiverSuite entgegennehmen, daraus + Tickets erzeugen und unbearbeitete automatisch schließen können. +Ergebnis: RiverSuite-Ereignisse werden zu c-entron-Tickets. +Belege: + - [PRIMÄR] BL/RiverDivo/RiverDivoBL.cs (ValidateRiverTicketOrRmmAccessKey, CreateHelpdeskRequest, CloseHelpdeskIfUnedited) - Begründung: Kopplung implementiert. +Prüfidee: Eine gültig authentifizierte RiverSuite-Anfrage erzeugt ein Ticket; eine ungültige wird abgewiesen. +Tracelinks: StRS-05, StRS-14 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Produktverbund des Herstellers. +Status: belegt +``` + +``` +ID: SyRS-145 +Titel: Länder- und Regionenstamm mit Währungen (M135) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: keine +Fakt: CountryBL verwaltet Länder mit Währungs-ISO und Kurs (UpdateCurrencyRateByCountry) + und aktualisiert Steuer-/Kursvorgaben in Warengruppen; FederalStateBL verwaltet + Bundesländer. +Aussage: Das System soll Länder mit Währung, Kurs und Steuerbezug sowie Bundesländer + verwalten und Änderungen in abhängige Stammdaten übernehmen. +Ergebnis: Länderdaten wirken konsistent in Preisen und Steuern. +Belege: + - [PRIMÄR] BL/CountryArea/CountryBL.cs (UpdateCurrencyRateByCountry, UpdateArticleMaterialGroupsWithDefaultCountryValues) - Begründung: Verwaltung mit Folgewirkung implementiert. +Prüfidee: Eine Kursänderung am Land wirkt in der Fremdwährungspreisberechnung. +Tracelinks: StRS-02 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Basisstammdaten. +Status: belegt +``` + +``` +ID: SyRS-146 +Titel: Feiertagsdaten (M136) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System (Fristen/Kalender) +Vorbedingung: keine +Fakt: HolidayDAO stellt Feiertagsdaten im Datenzugriff bereit. +Aussage: Das System soll Feiertage bereitstellen, damit Kalender- und Fristberechnungen + arbeitsfreie Tage berücksichtigen können. +Ergebnis: Fristen/Termine umgehen Feiertage. +Belege: + - [PRIMÄR] src/backend/Centron.DAO/Holiday/HolidayDAO.cs - Begründung: Datenbereitstellung implementiert. +Prüfidee: Ein Feiertag wird im Kalender als arbeitsfrei behandelt. +Tracelinks: StRS-06, StRS-21 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Terminlogik. +Status: belegt +``` + +``` +ID: SyRS-147 +Titel: Fremdwährungsbelege (M137) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertrieb / Buchhaltung +Vorbedingung: Fremdwährungskunde. +Fakt: Alle Belege tragen CurrencyI3D, CurrencyFactor und CurrencyString (ReceiptBase); + die Preisberechnung liefert Beträge in Hauswährung und Fremdwährung (…FC-Felder); + der Kursfaktor kann je Beleg fixiert werden (CurrencyFactorIsFixed). +Aussage: Das System soll Belege in Fremdwährung mit Kursfaktor führen, Beträge parallel in + Haus- und Belegwährung berechnen und den Kurs je Beleg fixierbar machen. +Ergebnis: Fremdwährungsbelege sind kursstabil und in beiden Währungen auswertbar. +Belege: + - [PRIMÄR] src/backend/Centron.Entities/.../ReceiptInvoice.cs:95 (CurrencyFactorIsFixed); src/webservice/Centron.WebServices.Core/Helper/ReceiptPriceHelper.cs (TaxPriceFC/NetPriceFC) - Begründung: Währungslogik implementiert. + - [PRIMÄR] BL/Sales/Receipts/ReceiptBL.cs:8369 (Fixierungsprüfung) - Begründung: Kursfixierung durchgesetzt. +Prüfidee: Ein Beleg mit fixiertem Kurs behält seine Beträge bei späterer Kursänderung. +Tracelinks: StRS-02 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Auslandsgeschäft. +Status: belegt +``` + +``` +ID: SyRS-148 +Titel: Externe Objektreferenzen (M138) +Ebene: SyRS +Typ: Daten +Qualitätsmerkmal: +Akteur: System / Schnittstellen +Vorbedingung: Fremdsystem-Kopplung besteht. +Fakt: ObjectExternalReferenceBL verknüpft interne Objekte (objectI3D+objectKind) mit + typisierten externen IDs und findet Objekte über die externe Referenz + (FindByExternalReference). +Aussage: Das System soll je internem Objekt beliebig typisierte externe IDs speichern und + Objekte über externe IDs auffindbar machen. +Ergebnis: Fremdsysteme referenzieren c-entron-Objekte stabil. +Belege: + - [PRIMÄR] BL/ObjectExternalReferences/ObjectExternalReferenceBL.cs (CreateReference, FindByExternalReference) - Begründung: Referenzverwaltung implementiert. +Prüfidee: Eine externe ID findet genau das verknüpfte interne Objekt. +Tracelinks: StRS-25 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Integrationsbasis. +Status: belegt +``` + +``` +ID: SyRS-149 +Titel: Prozess-/Workflow-Definitionen (M139) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: keine +Fakt: ProcessBL lädt Prozesse mit Schritten und Bindungen je Objekt; Workflow-BLs + verwalten Prozesse, Shapes, Shape-Bindungen und -Eigenschaften (grafischer + Workflow-Designer). Die Ausführungssemantik (wer führt wann Schritte aus) wurde + nicht nachvollzogen. +Aussage: [HYPOTHESE] Das System soll grafisch definierte Workflows (Schritte, Formen, + Bindungen) an Objekten (u. a. MailScanner-Vorgänge) ausführen. +Ergebnis: Definierte Abläufe steuern die Vorgangsbearbeitung. +Belege: + - [SEKUNDÄR] BL/Processes/ProcessBL.cs; BL/Services/ (WorkflowProcessBL.cs, WorkflowShapeBL.cs, WorkflowShapeBindingBL.cs) - Begründung: Definitionsverwaltung existiert; Ausführung unbelegt. +Prüfidee: Analyse der Workflow-Ausführung (Trigger, Engine) in Folgeiteration. +Tracelinks: StRS-05, SyRS-097 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - sofern produktiv; Umfang klären. +Status: HYPOTHESE - Begründung: Ausführungssemantik der Workflows unbelegt. +``` + +``` +ID: SyRS-150 +Titel: Feldänderungsverfolgung (M140) +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System +Vorbedingung: Änderungsverfolgung aktiv. +Fakt: Centron.DAO/ChangeTracking und BL/ChangeTracking (History, ImportHistoryBL) + historisieren Änderungen; die DB enthält eine ChangeLog-Tabelle mit Unique-Index; + Beleg-Kreditlimitänderungen verlassen sich auf Change-Tracking (Kommentar + "Change-tracking should do the trick" in ReceiptBL:8688). +Aussage: Das System soll Feldänderungen ausgewählter Objekte automatisch historisieren. +Ergebnis: Wer wann was geändert hat, ist je Feld nachvollziehbar. +Belege: + - [PRIMÄR] src/backend/Centron.DAO/ChangeTracking/; SSMS_DB_SCHEMA.sql:34757 (ChangeLog) - Begründung: Mechanismus und Persistenz vorhanden. +Prüfidee: Eine Kundenfeldänderung erzeugt einen ChangeLog-Eintrag mit Alt-/Neuwert. +Tracelinks: StRS-24 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Auditierbarkeit. +Status: belegt +``` + +## N. Infrastruktur / Querschnitt + +``` +ID: SyRS-151 +Titel: WPF-Client mit Recht+Lizenz-gesteuerter Modulfreischaltung (M141) +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Alle Benutzer +Vorbedingung: Anmeldung am Client. +Fakt: ModuleRegistration registriert 83 Client-Module; jedes Modul deklariert eine + Rechteprüfung (Helper.HasRights) und eine Lizenzprüfung + (LicenseManager.HasLicense); ohne beide bleibt das Modul unsichtbar. +Aussage: Das System soll jedes Client-Modul nur anzeigen, wenn der Benutzer die + erforderlichen Rechte und der Betreiber die Lizenz besitzt. +Ergebnis: Die Modulnavigation entspricht exakt Rechten und Lizenzen. +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/ModuleRegistration.cs:441-498 (83× ModuleRegistrationItem.For mit HasRights+HasLicense) - Begründung: durchsetzende Freischaltung je Modul. +Prüfidee: Entzug des Moduls-Rechts entfernt das Modul aus der Navigation; Entzug der Lizenz ebenso. +Tracelinks: StRS-13, StRS-15, SwRS-056 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Prinzip; Modulliste dient als Funktionsumfangs-Checkliste des Zielsystems. +Status: belegt +``` + +``` +ID: SyRS-152 +Titel: Wiederverwendbare UI-Komponenten (M142) +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Wartbarkeit +Akteur: Entwicklung +Vorbedingung: keine +Fakt: Centron.Controls (742 cs) und Centron.Core stellen gemeinsame UI-Komponenten und + Basisfunktionen für WPF-Client und Erweiterungen bereit; Centron.Controls.Preview + liefert Objekt-Vorschauen (CentronObjectPreview). +Aussage: Das System soll UI-Bausteine (Grids, Vorschauen, Editoren) zentral bereitstellen, + damit Masken einheitlich aussehen und funktionieren. +Ergebnis: Einheitliche Bedienung über alle Module. +Belege: + - [PRIMÄR] src/shared/Centron.Controls/, Centron.Controls.Preview/, Centron.Core/ - Begründung: geteilte Komponentenbibliotheken existieren. +Prüfidee: Die Objektvorschau eines Kunden sieht in allen Modulen identisch aus. +Tracelinks: StRS-32 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - WPF-spezifisch; im Web-Zielsystem durch Designsystem ersetzen. +Status: belegt +``` + +``` +ID: SyRS-153 +Titel: Datenzugriff über NHibernate mit dualem Schema (M143) +Ebene: SyRS +Typ: Daten +Qualitätsmerkmal: +Akteur: System +Vorbedingung: MSSQL-Datenbank verfügbar. +Fakt: Centron.DAO kapselt NHibernate (Mappings, Repositories, NamedQueries, RawSQL) mit + eigenem MSSQL-Dialekt; Belege werden aus englischen Views gelesen, aber über + Legacy-Repositories in die deutschen Tabellen geschrieben + (SaveReceipt*Repository/TemporaryEntities). +Aussage: Das System soll den Datenzugriff zentral kapseln; Lesen erfolgt über + englischsprachige Views, Schreiben über die deutschen Ursprungstabellen. +Ergebnis: Fachlogik ist von den Legacy-Tabellen entkoppelt, bleibt aber kompatibel. +Belege: + - [PRIMÄR] src/backend/Centron.DAO/ (Mappings, Repositories, NHibernateConfiguration/CentronMsSql2008Dialect.cs) - Begründung: Datenzugriffsschicht implementiert. + - [KONTEXT] docs/reference/receipts/receipts-backend-architecture.md (Dual Layer, Critical Save Warning) - Begründung: dokumentierter Schreibpfad. +Prüfidee: Ein über die View geladenes Feld wird beim Speichern in der deutschen Tabelle persistiert. +Tracelinks: StRS-02, SwRS-001, SwRS-006 +Konsolidierung: nein +Übernahmewürdigkeit: Workaround - historisch gewachsener Doppelpfad; im Zielsystem ein einheitliches Schema. +Status: belegt +``` + +``` +ID: SyRS-154 +Titel: Gateway für Fremdformate (M144) +Ebene: SyRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: System +Vorbedingung: Format-Konfiguration vorhanden. +Fakt: Centron.Gateway bündelt Formatlogik (BookKeeping-Exporte, EDI-Parser je + Distributor, OpenTrans, ZUGFeRD 2.1 Extended, MspCollector, OnlineBanking, + Import/Export); CustomGatewayBL verwaltet Sonderartikel-Importe an Verträge. +Aussage: Das System soll Fremdformat-Verarbeitung in einer eigenen Gateway-Schicht kapseln. +Ergebnis: Formatänderungen bleiben lokal im Gateway. +Belege: + - [PRIMÄR] src/backend/Centron.Gateway/ (EDI_*, DataExchange, OpenTrans, ZUGFeRD21_Extended); BL/Gateway/CustomGatewayBL.cs - Begründung: Gateway-Schicht existiert. +Prüfidee: Ein neues Distributorformat erfordert nur eine neue Gateway-Komponente. +Tracelinks: StRS-08, StRS-11 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Architekturprinzip. +Status: belegt +``` + +``` +ID: SyRS-155 +Titel: Bereitstellung als Installer und Container (M145) +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Übertragbarkeit (Portability) +Akteur: Betrieb +Vorbedingung: Release liegt vor. +Fakt: WiX-Installer (CentronSetupProject, WebServiceSetupProject, WixSharpInstaller) + installieren Client und Webservice; Dockerfiles (mehrere) und Azure-Ordner + (azure/, azure-blazor/) containerisieren Dienste; der Webservice läuft auch unter + Linux (dokumentiert). +Aussage: Das System soll als Windows-Installer und als Container (inkl. Linux-Webservice) + bereitstellbar sein. +Ergebnis: On-Premise- und Cloud-Betrieb sind möglich. +Belege: + - [PRIMÄR] deployment/ (WiX-Projekte), docker/ (Dockerfiles, build_docker.sh) - Begründung: Bereitstellungsartefakte existieren. + - [KONTEXT] docs/guides/services/web-service-on-linux.md - Begründung: Linux-Betrieb dokumentiert. +Prüfidee: Das Docker-Image des Webservice startet und beantwortet CheckConnection. +Tracelinks: StRS-31 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Containerfähigkeit ist SaaS-Voraussetzung; WiX-Installer entfallen. +Status: belegt +``` + +``` +ID: SyRS-156 +Titel: Zweisprachige Oberfläche (DE/EN) (M146) +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Benutzbarkeit (Usability) +Akteur: Alle Benutzer +Vorbedingung: keine +Fakt: Benutzertexte liegen in Basis-Resx (deutsch; 2.812 Einträge in der WPF-UI) mit + en-Übersetzungen; BL-Fehlermeldungen kommen aus LocalizedStrings; die Doku schreibt + DE-Erstsprache und EN-Pflege vor. +Aussage: Das System soll alle Oberflächen- und Fehlertexte lokalisiert (deutsch als Basis, + englisch als Übersetzung) ausgeben. +Ergebnis: Vollständig deutsche Oberfläche; englische Ausgabe wählbar. +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Resources/LocalizedStrings.resx / .en.resx - Begründung: Ressourcen vorhanden. + - [KONTEXT] docs/guides/ui/localization.md - Begründung: dokumentierter Prozess. +Prüfidee: Umschalten der Sprache ändert Menüs und Fehlermeldungen. +Tracelinks: StRS-32, SwRS-058 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Grundanforderung. +Status: belegt +``` + diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/Traceability.md b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/Traceability.md new file mode 100644 index 00000000..6b0f183c --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Ergebnisse/Traceability.md @@ -0,0 +1,199 @@ +# Traceability + +Konsolidierte Traceability-Tabelle über die drei Ebenen. Eine Zeile je SyRS-Anforderung: +Spalte 1 nennt die StRS-Elternanforderung(en) (Backward-Trace), Spalte 3 die zugeordneten +SwRS-Kindanforderungen (Forward-Trace), Spalte 4 den zentralen Artefaktbeleg (Kurzform; +vollständige Belege in den Spezifikationen). `BL/` = `src/backend/Centron.BL/`. + +Alle 32 StRS-Anforderungen sind über mindestens eine SyRS-Zeile abgedeckt; alle 71 +SwRS-Anforderungen erscheinen in mindestens einer Zeile. + +| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg | +|---|---|---|---| +| StRS-02 | SyRS-001 | SwRS-004 | Entities/Sales/Receipts/Offers/ReceiptOffer.cs; AngKopf/AngPos | +| StRS-02 | SyRS-002 | – | AutomaticFacturaBL.cs:114 (GetOrdersForAutomatedBilling) | +| StRS-02 | SyRS-003 | – | AutomaticFacturaBL.cs:102 (State==1) | +| StRS-02, StRS-24 | SyRS-004 | SwRS-013 | Entities/.../ReceiptInvoice.cs:38-108 | +| StRS-24, StRS-29 | SyRS-005 | SwRS-016, SwRS-004 | BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs:143-206 | +| StRS-24 | SyRS-006 | SwRS-017 | ReceiptInvoiceBL.cs:86-141 (FixInvoice) | +| StRS-02, StRS-10 | SyRS-007 | – | DunningBL.cs:99-108 (CreditVouchers) | +| StRS-02, StRS-07 | SyRS-008 | SwRS-045 | BarcodeState.cs:24 (AssignedToPickupList) | +| StRS-03 | SyRS-009 | SwRS-023 | Entities/.../ReceiptContract.cs | +| StRS-03 | SyRS-010 | SwRS-019, SwRS-020, SwRS-021, SwRS-022, SwRS-070, SwRS-071 | AutomaticFacturaBL.Contracts.cs:1596-1627 | +| StRS-04 | SyRS-011 | SwRS-024 | AutomaticFacturaBL.Contracts.cs:1248 (UpdClickCounterHistory) | +| StRS-05 | SyRS-012 | SwRS-063 | TimerBillingBL.cs:233-383 | +| StRS-02 | SyRS-013 | SwRS-018 | DownPaymentBL.cs:82/198 | +| StRS-28 | SyRS-014 | – | BL/Projects/ProjectBL.cs; ReceiptInvoice.ProjectNumber | +| StRS-02, StRS-15 | SyRS-015 | – | LeasingAndService/; ModuleRegistration.cs:475 | +| StRS-25 | SyRS-016 | – | BL/Warehousing/ActionPriceBL.cs | +| StRS-02, StRS-25 | SyRS-017 | SwRS-007, SwRS-008, SwRS-009, SwRS-010, SwRS-013, SwRS-014 | ArticleSearchBL.cs:1080-1126 | +| StRS-29 | SyRS-018 | – | CashBookBookingBL.cs | +| StRS-17, StRS-25 | SyRS-019 | SwRS-008, SwRS-043 | ReceiptItemPriceBL.cs:232-257; ArticleSearchWebServiceBL.cs:71 | +| StRS-19, StRS-04 | SyRS-020 | – | Entities/.../MasterDataList.cs | +| StRS-02 | SyRS-021 | SwRS-012 | ReceiptPriceHelper.cs:37-41 (0.05-Rundung) | +| StRS-24 | SyRS-022 | SwRS-002, SwRS-003 | ReceiptInvoiceBL.cs:174; *KopfVersions-Tabellen | +| StRS-16 | SyRS-023 | SwRS-025, SwRS-051 | NumberGroupBL.cs:62-134 | +| StRS-03, StRS-21, StRS-22 | SyRS-024 | – | AutomaticFacturaBL.Contracts.cs:263-443 (Mailvorlagen/Empfänger) | +| StRS-01, StRS-02 | SyRS-025 | SwRS-015 | ReceiptBL.cs:8636-8705 (Kreditlimit) | +| StRS-02 | SyRS-026 | – | ReceiptBL.cs:2462 (ValidateReceiptForwarding) | +| StRS-02 | SyRS-027 | SwRS-005, SwRS-065 | ReceiptBL.cs:4808 (ConcurrencyControlGuid) | +| StRS-13, StRS-16 | SyRS-028 | SwRS-066 | ReceiptBL.cs:10251-10311 (Branch-Checks) | +| StRS-08 | SyRS-029 | – | SupplierOrderBL.cs; BL/EDI/AlsoOrderBL.cs | +| StRS-08, StRS-12 | SyRS-030 | SwRS-062 | SupplierInvoicesBL.cs; PdfScanner.cs | +| StRS-08, StRS-07 | SyRS-031 | – | SupplierDeliveryListBL.cs; ZUGFeRD_BL.cs:107 | +| StRS-08 | SyRS-032 | – | SupplierCreditVoucherSpecificLogic.cs | +| StRS-08, StRS-24 | SyRS-033 | – | SupplierReceiptDocumentBL.cs | +| StRS-08, StRS-07 | SyRS-034 | – | OrderSuggestionListBL.cs | +| StRS-01, StRS-08 | SyRS-035 | SwRS-051 | SSMS_DB_SCHEMA.sql:3854 (Unique Lieferantennummer) | +| StRS-01, StRS-13 | SyRS-036 | SwRS-051 | AccountBL.cs:1305-1366 (Rechteprüfungen) | +| StRS-01 | SyRS-037 | – | ReceiptInvoiceBL.cs:293 (AlternateInvoiceReceiver) | +| StRS-20 | SyRS-038 | – | AccountActivitiesBL.cs; HelpdeskCloseBL.cs:151 | +| StRS-20 | SyRS-039 | – | BL/Accounts/Campaigns/ | +| StRS-20, StRS-21 | SyRS-040 | – | BL/Sales/Marketing/; BL/Mailings/ | +| StRS-20, StRS-05 | SyRS-041 | – | HelpdeskCloseBL.cs:168-198 (AddSurvey) | +| StRS-20 | SyRS-042 | – | CrmProjectBL.cs | +| StRS-05 | SyRS-043 | – | BL/Accounts/HotlineArea/ | +| StRS-20 | SyRS-044 | – | BL/Accounts/AccountContracts/ | +| StRS-05 | SyRS-045 | SwRS-047 | HelpdeskBL.cs:298-307, 515-519 | +| StRS-05 | SyRS-046 | SwRS-047 | HelpdeskBL.cs:658-702 (Pflichtfelder) | +| StRS-05 | SyRS-047 | SwRS-048 | HelpdeskCloseBL.cs:120-157 | +| StRS-06 | SyRS-048 | SwRS-049 | EscalationBL.cs:223-332 | +| StRS-05 | SyRS-049 | – | HelpdeskTimerBL.cs; CentronRights.md Abschn. 7-9 | +| StRS-05 | SyRS-050 | – | CentronChecklistBL.cs | +| StRS-05 | SyRS-051 | – | HelpdeskPatternBL.cs; automatic-helpdesk-creation-templates.md | +| StRS-05 | SyRS-052 | – | BL/TaskManager/ | +| StRS-28, StRS-05 | SyRS-053 | – | TicketProjectBL.cs (Dependencies) | +| StRS-05, StRS-07 | SyRS-054 | SwRS-050 | SSMS_DB_SCHEMA.sql:4176 (Unique RMA) | +| StRS-05 | SyRS-055 [H] | – | ExternalHelpdeskConfigurationBL.cs (nur Konfiguration) | +| StRS-05, StRS-21 | SyRS-056 | – | AppointmentRequestBL.cs | +| StRS-05 | SyRS-057 | – | ToDoBL.cs; HelpdeskCloseBL.cs:134 | +| StRS-13, StRS-05 | SyRS-058 | SwRS-038 | UserRightsConst.cs (SHOW_HELPDESK_ONLY_OWN…) | +| StRS-19 | SyRS-059 | – | AccountDeviceBL.cs; Entities/Devices/AccountDevice.cs | +| StRS-19 | SyRS-060 | – | BL/DocuBoard/; AssetManagement*-Tabellen | +| StRS-04, StRS-19 | SyRS-061 | – | RmmConnectionSettingsBL.cs; RiverbirdImportValues | +| StRS-04 | SyRS-062 | SwRS-064 | AutomaticFacturaBL.cs:129-147 (MSP→Vertragsposition) | +| StRS-07, StRS-25 | SyRS-063 | – | ArticleBL.cs; ArticleImportBL.cs | +| StRS-07 | SyRS-064 | SwRS-011, SwRS-046, SwRS-010 | ArticleStockBL.cs:47-149 | +| StRS-07 | SyRS-065 | SwRS-069 | InventoryNewBL.cs:80-330 | +| StRS-07, StRS-02 | SyRS-066 | – | CommissioningBL.cs; PartialCommissionOrderBL.cs | +| StRS-07 | SyRS-067 | SwRS-045, SwRS-046 | BarcodeState.cs; BarcodeHistoryBL.cs | +| StRS-27 | SyRS-068 | – | ProductionOrderBL.cs; ProductionOrderItemState.cs | +| StRS-26 | SyRS-069 | – | Centron.Api.Gls/CentronGlsLogic.cs | +| StRS-26 | SyRS-070 | – | Centron.Api.Shipcloud/CentronShipcloudLogic.cs | +| StRS-09, StRS-13 | SyRS-071 | SwRS-031, SwRS-027 | PaymentsBL.cs:38-78 | +| StRS-09 | SyRS-072 | SwRS-028, SwRS-070 | OnlineBankingAccountTransactionsBL.cs:524-643 | +| StRS-09 | SyRS-073 | SwRS-026, SwRS-027 | PaymentTransactionBL.cs:132-345 | +| StRS-10 | SyRS-074 | SwRS-030 | DunningBL.cs:58-113; DunningLevel.cs | +| StRS-10, StRS-11 | SyRS-075 | – | OposRunBL.cs; OposImports-Settings | +| StRS-11 | SyRS-076 | SwRS-029 | BookKeepingExportDatevAscii.cs:991; ReceiptInvoiceBL.cs:167 | +| StRS-09 | SyRS-077 | SwRS-026 | BankAccountBL.cs; PaymentTransactionBL.cs:347 | +| StRS-14 | SyRS-078 | SwRS-032, SwRS-034, SwRS-036, SwRS-041, SwRS-068 | CentronRestService.cs:363-397; TicketBL.cs:26 | +| StRS-14, StRS-30 | SyRS-079 | SwRS-033 | Authenticator.cs:157-217 | +| StRS-13 | SyRS-080 | SwRS-038, SwRS-036 | AppRightsBL.cs:95-111 (Sichtrus/Sichmemb) | +| StRS-14 | SyRS-081 | SwRS-037 | TwoFactorAuthBL.cs:33-120 | +| StRS-15 | SyRS-082 | SwRS-035 | LicenseManager.cs:258-302 | +| StRS-16 | SyRS-083 | – | MandatorBL.cs; BranchBL.cs; NumberGroupBL.cs:136 | +| StRS-30 | SyRS-084 | – | BL/EmployeeArea/ | +| StRS-31 | SyRS-085 | SwRS-054 | ApplicationSettingID.cs (~500 IDs) | +| StRS-23 | SyRS-086 | SwRS-052 | DataSecurityBL.cs:34-70, 377, 787 | +| StRS-31 | SyRS-087 | SwRS-053 | ScriptMethods/Scripts/; create-scripts.md | +| StRS-31 | SyRS-088 | SwRS-057 | DataQualityService.cs | +| StRS-31 | SyRS-089 [H] | – | TelemetryBL.cs; ProfilerBL.cs (Zweck unbelegt) | +| StRS-14 | SyRS-090 | SwRS-040 | AccessTokenBL.cs:125-194, 457-488 | +| StRS-13 | SyRS-091 | – | PasswordManagementBL.cs:81 (GetDecryptedPassword) | +| StRS-01 | SyRS-092 | – | CustomTableBL.cs | +| StRS-01 | SyRS-093 | – | MassUpdateBL.cs | +| StRS-32 | SyRS-094 | – | UiProfileBL.cs | +| StRS-21 | SyRS-095 | SwRS-059, SwRS-060 | CentronMailFactory.cs; DeveloperSecurity.cs:30 | +| StRS-21 | SyRS-096 | – | EwsHelper/ (EWSConnection, EwsCalendarAccess) | +| StRS-21, StRS-05 | SyRS-097 | – | MailScannerBL.cs | +| StRS-21 | SyRS-098 | – | PhoneCallBL.cs (SearchContactPersonByPhoneNumberV2) | +| StRS-21, StRS-13 | SyRS-099 | – | CalendarBL.cs; CentronRights.md Kalender | +| StRS-21 | SyRS-100 | – | ChatBL.cs (CreateChat mit objectKind) | +| StRS-21 | SyRS-101 | – | CentronNexus.OutlookAddIn/ (CustomerTab u. a.) | +| StRS-21, StRS-17 | SyRS-102 | – | NexusNotificationsBL.cs; Program.cs:349 (SignalR) | +| StRS-08 | SyRS-103 | SwRS-062 | SupplierEdiBL.cs (+Partials); EDIDispatcherBL.cs | +| StRS-12 | SyRS-104 | SwRS-061 | ReceiptWebServiceBL.cs:2151-2185 | +| StRS-12 | SyRS-105 | – | EbInterfaceLogic.cs | +| StRS-04 | SyRS-106 [H] | – | DocuFormRestApiClient.cs (Konsument unbelegt) | +| StRS-25 | SyRS-107 | – | IcecatApi.cs | +| StRS-25 | SyRS-108 | – | ITscopeApi.cs; ArticleSearchBL.cs:1107 | +| StRS-25 | SyRS-109 [H] | – | CopApi.cs (Aufrufer unbelegt) | +| StRS-08, StRS-25 | SyRS-110 | – | EgisWarenkorbBL.cs; EgisApi.cs | +| StRS-25 | SyRS-111 [H] | – | TelekomDiveBL.cs (Inhalt unbelegt) | +| StRS-05 | SyRS-112 [H] | – | TanssBL.cs (Nutzungsart unbelegt) | +| StRS-11 | SyRS-113 | – | GfkExportBL.cs | +| StRS-25 | SyRS-114 | – | HPQuoteImportBL.cs | +| StRS-05, StRS-21 | SyRS-115 | – | DocBeeTicketConnectorBL.cs; CTimeConnectorBL.cs | +| StRS-22 | SyRS-116 | – | BL/ReportEngine/ (ReportDataBL, PdfExport) | +| StRS-22 | SyRS-117 | SwRS-070 | BL/Statistics/ (15 BLs) | +| StRS-01, StRS-05 | SyRS-118 | – | IndexSearchBL.cs (Lucene, GermanAnalyzer) | +| StRS-17 | SyRS-119 | SwRS-067 | CentronNexus.Host/Program.cs:264-276, 395 | +| StRS-05, StRS-17 | SyRS-120 | – | ServiceBoard/ (341 Dateien) | +| StRS-17 | SyRS-121 | SwRS-043 | ArticleSearchWebServiceBL.cs:71-99 | +| StRS-18 | SyRS-122 | SwRS-044 | WebReceiptState.cs:6-26 | +| StRS-18, StRS-05 | SyRS-123 | – | DocumentSigning/ (IsolatedSignaturePad) | +| StRS-27, StRS-17 | SyRS-124 | – | ProductionOrderManagement/ | +| StRS-17 | SyRS-125 | – | SelfCareBL.cs; CustomerPortalFormsPage.razor | +| StRS-17, StRS-13 | SyRS-126 | SwRS-039, SwRS-042, SwRS-066, SwRS-032 | WebAccountBL.cs:54-105; AppRightsBL.cs:113 | +| StRS-14, StRS-17 | SyRS-127 | SwRS-055, SwRS-068 | CentronRestServiceParts/ (32 Teile); AuthenticateInterceptor.cs | +| StRS-31 | SyRS-128 | – | c-entron.misc.ConnectionManager/ | +| StRS-22 | SyRS-129 | – | BL/MyCentron/ | +| StRS-15, StRS-05 | SyRS-130 | – | MyDayBL.cs; licensing-system.md (Count) | +| StRS-05 | SyRS-131 | – | OpenAiApiClient.cs; TicketAiSummary/ | +| StRS-25 | SyRS-132 [H] | – | TradePoolBL.cs (Kontext unbelegt) | +| StRS-02 | SyRS-133 | – | VoucherManagementBL.cs | +| StRS-02, StRS-21 | SyRS-134 | – | TextModuleBL.cs (GetInvoiceTextModule) | +| StRS-05 | SyRS-135 | – | TagsBL.cs (AddTicketTag) | +| StRS-21 | SyRS-136 | – | SocialMediaBL.cs | +| StRS-32 | SyRS-137 | – | VideoPortalAssignmentBL.cs | +| StRS-21 | SyRS-138 | – | WebLinkBL.cs (+ActionHandler) | +| StRS-05 | SyRS-139 [H] | – | MobileBL.cs (Konsument unbelegt) | +| StRS-20 | SyRS-140 | – | ProductMatrixBL.cs | +| StRS-05 | SyRS-141 [H] | – | ChecklistVirtualObjectCategoryBL.cs | +| StRS-20 | SyRS-142 | – | ExpectedEventsBL.cs | +| StRS-25 | SyRS-143 [H] | – | CPraConnectorBL.cs | +| StRS-05, StRS-14 | SyRS-144 | – | RiverDivoBL.cs (CreateHelpdeskRequest) | +| StRS-02 | SyRS-145 | – | CountryBL.cs | +| StRS-06, StRS-21 | SyRS-146 | – | HolidayDAO.cs | +| StRS-02 | SyRS-147 | – | ReceiptInvoice.CurrencyFactorIsFixed; ReceiptBL.cs:8369 | +| StRS-25 | SyRS-148 | – | ObjectExternalReferenceBL.cs | +| StRS-05 | SyRS-149 [H] | – | ProcessBL.cs; WorkflowShapeBL.cs | +| StRS-24 | SyRS-150 | – | DAO/ChangeTracking/; ChangeLog-Tabelle | +| StRS-13, StRS-15 | SyRS-151 | SwRS-056, SwRS-055 | ModuleRegistration.cs:441-498 (83 Module) | +| StRS-32 | SyRS-152 | – | Centron.Controls/; Centron.Core/ | +| StRS-02 | SyRS-153 | SwRS-001, SwRS-006 | Centron.DAO/ (Mappings, Repositories) | +| StRS-08, StRS-11 | SyRS-154 | – | Centron.Gateway/ | +| StRS-31 | SyRS-155 | – | deployment/; docker/ | +| StRS-32 | SyRS-156 | SwRS-058 | LocalizedStrings*.resx (2.812 Einträge) | + +**Legende:** `[H]` = Anforderung mit Status HYPOTHESE; `–` = keine vertiefende SwRS-Anforderung. + +## Gegenrichtung: SwRS → SyRS (Backward-Trace der Softwareebene) + +| SwRS | → SyRS | | SwRS | → SyRS | | SwRS | → SyRS | +|---|---|---|---|---|---|---|---| +| 001 | 153 | | 025 | 023 | | 049 | 048 | +| 002 | 022 | | 026 | 073, 077 | | 050 | 054 | +| 003 | 022, 006 | | 027 | 073, 071 | | 051 | 036, 035, 023 | +| 004 | 001, 005 | | 028 | 072 | | 052 | 086 | +| 005 | 027 | | 029 | 076 | | 053 | 087 | +| 006 | 153 | | 030 | 074 | | 054 | 085 | +| 007 | 017, 009 | | 031 | 071 | | 055 | 127, 151 | +| 008 | 019, 017 | | 032 | 078, 126 | | 056 | 151 | +| 009 | 017 | | 033 | 079 | | 057 | 088 | +| 010 | 017, 064 | | 034 | 078 | | 058 | 156 | +| 011 | 064 | | 035 | 082 | | 059 | 095 | +| 012 | 021 | | 036 | 078, 080 | | 060 | 095 | +| 013 | 017, 004 | | 037 | 081 | | 061 | 104 | +| 014 | 017 | | 038 | 080 | | 062 | 103, 030 | +| 015 | 025 | | 039 | 126 | | 063 | 012 | +| 016 | 005, 010, 011, 012 | | 040 | 090 | | 064 | 062, 010 | +| 017 | 006 | | 041 | 078 | | 065 [H] | 027 | +| 018 | 013 | | 042 | 126 | | 066 | 126, 028 | +| 019 | 010 | | 043 | 121 | | 067 | 119 | +| 020 | 010 | | 044 | 122 | | 068 | 127, 078 | +| 021 | 010 | | 045 | 067 | | 069 | 065 | +| 022 | 010, 011 | | 046 | 064, 067 | | 070 | 010, 072, 117 | +| 023 | 009, 022 | | 047 | 046 | | 071 [H] | 010, 024 | +| 024 | 011 | | 048 | 047 | | | | diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Protokoll.md b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Protokoll.md new file mode 100644 index 00000000..3f3a98db --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Protokoll.md @@ -0,0 +1,165 @@ +# Messprotokoll – Versuch 01 (V1 Baseline, Prompt-only) – Iteration 02 + +## Lauf +- **Prompt-Datei:** `Versuche/Versuch_01/02_Prompt.md` +- **Iteration:** 02 – vom User ausdrücklich benannt; entspricht zugleich der Regel „höchste + vorhandene Iterationsnummer". Wiederholungslauf zur Varianzbestimmung in derselben Zelle. +- **SHA-256 (Prompt):** `F9B2A1AAB45DDCB87E905B83F24D7B1C7860D81CA07E503E51222E266E0D7849` +- **Startzeit:** 2026-08-27T08:12:35.5152425+02:00 +- **Endzeit:** 2026-08-27T09:12:14.8158828+02:00 +- **Dauer gesamt:** 0:59:39 (`duration_ms` 0:59:37; API: 0:57:54) + — **im Parallelbetrieb erhoben, nicht für Laufzeitvergleiche verwendbar** +- **Root-Verzeichnis:** `c:\DEV\MasterArbeit\QuellCode\CentronERP` (24.662 versionierte Dateien) +- **Codebasis-Commit:** `7df384f6d2e7249dc914a74e299fe7fa71ece748` (dirty: nein) +- **Snapshot-Zustand:** bereinigt von KI-Konfigurationen: ja (Prüfmuster ohne Treffer); + die Codebasis ist seit Commit `f045b99a` kein eigenes Repository mehr, sondern Teil des + Arbeitsrepos – der Vorher/Nachher-Vergleich läuft deshalb pfadskopiert +- **Snapshot-Zusatzartefakte:** keine – der Snapshot entspricht dem Commit-Stand +- **Prompt-Repo-Commit:** `7df384f6d2e7249dc914a74e299fe7fa71ece748` + +## Werkzeugkonfiguration +- **Skill-Version:** 7.0.0 +- **Claude-Code-Version:** 2.1.246 +- **CLI-Pfad:** `C:\Users\ChristophSchwoerer\.vscode\extensions\anthropic.claude-code-2.1.246-win32-x64\resources\native-binary\claude.exe` +- **Modell (angefordert):** `claude-fable-5` +- **Modelle (tatsächlich eingesetzt):** `claude-fable-5` 41.314.054 Tokens (99.98 %), `claude-haiku-4-5-20251001` 6.965 Tokens (0.02 %) +- **Kontrolle Modell:** bestanden – ausschließlich das angeforderte Modell plus Haiku als zulässiger interner Hilfsaufruf +- **Effort:** `max` (per `--effort max` gesetzt) +- **Laufverzeichnis-ID:** `v7.0.0-3021` +- **Ablage:** `Iteration 3/claude-fable-5/solo/max/` +- **Parallele Läufe:** nein – die Zeitangaben sind für Laufzeitvergleiche verwendbar +- **Agentenmodus:** `solo` (V1) +- **Kontextfenster:** 1.000.000 Tokens; `maxOutputTokens` 64.000 +- **Sampling-Parameter:** nicht steuerbar über die CLI, nicht erfasst +- **Nur bei lokalem Modellbetrieb:** entfällt (Cloud-Inferenz, `provider: firstParty`) +- **Permission-Mode:** `acceptEdits` +- **Toolfreigabe:** `--allowedTools "Bash" "PowerShell"` / + `--disallowedTools` 33er-Denylist (schreibende und bauende Kommandos) **zuzüglich** `Task`, `Agent`, `Workflow` aus dem Modus `solo` +- **Isolationsmechanismus:** `--safe-mode`, `--strict-mcp-config` +- **MCP-Server / Agentendateien:** keine – aus dem Snapshot entfernt, zusätzlich `--safe-mode` +- **Subagenten:** keine (`spawned` = 0, `by_type` leer) +- **Verschachtelung:** `spawned` = 0, davon `spawned_by_subagents` = 0, `max_depth` = 0. Keine tieferen Ebenen, `_meta\subagenten.md` entfällt. + +## Validierungsstichprobe +- **Größe:** noch nicht festgelegt +- **Ziehungsverfahren:** noch nicht festgelegt +- **Validatoren:** noch nicht festgelegt +- **Stand:** noch nicht gezogen + +## Verbrauch + +### Hauptagent (`usage`) +| Messgröße | Wert | +|---|---:| +| Input-Tokens | 352 | +| Output-Tokens | 296.436 (davon 48.784 Thinking-Tokens) | +| Cache-Write-Tokens | 547.351 | +| Cache-Read-Tokens | 40.469.915 | +| Agent-Turns | 204 | + +### Gesamtlauf inkl. Subagenten (`modelUsage`, abrechnungsrelevant) +| Messgröße | `claude-fable-5` | `claude-haiku-4-5-20251001` | Summe | +|---|---:|---:|---:| +| Input-Tokens | 352 | 6.944 | 7.296 | +| Output-Tokens | 296.436 | 21 | 296.457 | +| Cache-Write-Tokens | 547.351 | 0 | 547.351 | +| Cache-Read-Tokens | 40.469.915 | 0 | 40.469.915 | +| **Tokens gesamt** | **41.314.054** | **6.965** | **41.321.019** | + +**Tokens gesamt: 41.321.019** — Input + Output + Cache-Write + Cache-Read über alle Modelle. +Das ist die **berichtete Aufwandsgröße** der Versuchsreihe. `total_cost_usd` bleibt unberührt in +`RawResult.json` erhalten, wird aber nicht ins Protokoll übernommen: Token sind modell- und +preisunabhängig und bleiben damit über Preisänderungen und Modellwechsel hinweg vergleichbar. + +Da im Modus `solo` keine Subagenten laufen, sind `usage` und `modelUsage` für das Hauptmodell +deckungsgleich; die Differenz zur Summe stammt allein aus den Haiku-Hilfsaufrufen. + +## Gefundene Anforderungen + +Maschinell aus `Ergebnisse\StRS.md`, `SyRS.md` und `SwRS.md` ausgewertet (Blockformat des Prompts). Erzeugt von `analyse-anforderungen.py`. + +Die Kenngrößen decken die **maschinell prüfbare** Hälfte des Evaluationsrahmens aus Kapitel 4.3 ab: Belegqualität und Übernahmewürdigkeit gehören zur *Statement-Qualität*, Verteilung und Konsolidierungskandidaten zur *Set-Qualität*, Tracelinks und Belegklassifikation zur *Traceability-Qualität*. Die Expertenbewertung nach Likert-Skala tritt daneben und wird hier nicht ersetzt. + +### Verteilung über die Ebenen + +| Ebene | Anzahl | Anteil | +|---|---:|---:| +| StRS | 32 | 12,4 % | +| SyRS | 156 | 60,2 % | +| SwRS | 71 | 27,4 % | +| **Gesamt** | **259** | 100 % | + +### Anforderungstypen + +| Typ | Anzahl | Anteil | +|---|---:|---:| +| funktional | 166 | 64,1 % | +| Sicherheit | 35 | 13,5 % | +| Schnittstelle | 34 | 13,1 % | +| nicht-funktional | 13 | 5,0 % | +| Daten | 11 | 4,2 % | + +### Belegqualität + +| Messgröße | Wert | +|---|---:| +| Belege gesamt | 370 | +| davon `PRIMÄR` | 285 (77,0 %) | +| davon `SEKUNDÄR` | 43 (11,6 %) | +| davon `KONTEXT` | 42 (11,4 %) | +| Belege je Anforderung (Median) | 1 | +| Anforderungen mit mindestens einem `PRIMÄR`-Beleg | 245 (94,6 %) | + +### Übernahmewürdigkeit + +| Einstufung | Anzahl | Anteil | +|---|---:|---:| +| übernehmen | 244 | 94,2 % | +| workaround | 8 | 3,1 % | +| sonderfall | 5 | 1,9 % | +| veraltet | 2 | 0,8 % | + +### Status + +| Kategorie | Anzahl | Anteil | +|---|---:|---:| +| belegt | 246 | 95,0 % | +| als `HYPOTHESE` gekennzeichnet | 13 | 5,0 % | +| als Workaround vermerkt | 0 | 0,0 % | +| Konsolidierungskandidaten | 9 | 3,5 % | +| mit ISO-25010-Qualitätsmerkmal | 13 | 5,0 % | + +### Regelkonformität (Prüfung gegen die Vorgaben des Prompts) + +| Vorgabe | Ergebnis | +|---|---| +| **Belegpflicht** – jede Anforderung mindestens ein Artefaktbeleg | **erfüllt** (0 Anforderungen ohne Beleg) | +| **Risikobasierte Priorisierung** – Sicherheit, Abrechnung, Berechtigungen brauchen einen `PRIMÄR`-Beleg oder die Kennzeichnung `[HYPOTHESE]` | **erfüllt** (60 risikorelevante Anforderungen, alle gedeckt) | +| **Verifizierbarkeit** – jede Anforderung mit Prüfidee oder Akzeptanzkriterium | **erfüllt** | +| **Übernahmewürdigkeit** – Einstufung für die Migrationsperspektive | **erfüllt** (alle 259 Anforderungen eingestuft) | +| **Traceability** – Verknüpfung zwischen den Ebenen | 259 von 259 mit Tracelinks (100,0 %) | + +## Ergebnis +- **Status:** erfolgreich (`is_error` = false, `subtype` = `success`, `stop_reason` = `end_turn`, `terminal_reason` = `completed`) +- **Session-ID:** `2db865cc-0f0d-440b-867f-bd92dfa2b20d` +- **Permission-Denials:** 1 (1 × `PowerShell`) – **keines auf `Task`/`Agent`/`Workflow`**. Der Agent hat zu keinem Zeitpunkt zu delegieren versucht; die Modus-Sperre wurde nie ausgelöst. +- **Kontrolle Agentenmodus:** `subagent_stats.spawned` = 0 – Bedingung `solo` eingehalten +- **Subagenten-Prompts:** entfällt (Modus `solo`) +- **Erzeugte Dateien:** 7 Dateien in `Ergebnisse\`: + + | Datei | Größe | + |---|---:| + | `Analysebericht.md` | 39.480 B | + | `Glossar.md` | 8.320 B | + | `Hypothesen.md` | 3.632 B | + | `StRS.md` | 46.076 B | + | `SwRS.md` | 93.705 B | + | `SyRS.md` | 191.384 B | + | `Traceability.md` | 13.545 B | + +- **Root unverändert:** ja (zeilenendennormalisiert verglichen). +- **Abschlusstext des Agenten:** siehe `RawResult.json` (`result`) + +## Anmerkungen/Auffälligkeiten + + diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/RawResult.json b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/RawResult.json new file mode 100644 index 00000000..c2f3865b --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/RawResult.json @@ -0,0 +1 @@ +{"is_error":false,"duration_api_ms":3474396,"num_turns":204,"stop_reason":"end_turn","session_id":"2db865cc-0f0d-440b-867f-bd92dfa2b20d","total_cost_usd":66.24930400000002,"usage":{"input_tokens":352,"cache_creation_input_tokens":547351,"cache_read_input_tokens":40469915,"output_tokens":296436,"output_tokens_details":{"thinking_tokens":48784},"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":547351,"ephemeral_5m_input_tokens":0},"inference_geo":"not_available","iterations":[{"input_tokens":2,"output_tokens":1542,"cache_read_input_tokens":546412,"cache_creation_input_tokens":939,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":939},"type":"message"}],"speed":"standard"},"modelUsage":{"claude-haiku-4-5-20251001":{"inputTokens":6944,"outputTokens":21,"cacheReadInputTokens":0,"cacheCreationInputTokens":0,"webSearchRequests":0,"costUSD":0.007049,"contextWindow":200000,"maxOutputTokens":32000,"canonicalModel":"claude-haiku-4-5","provider":"firstParty","costBasis":"list"},"claude-fable-5":{"inputTokens":352,"outputTokens":296436,"cacheReadInputTokens":40469915,"cacheCreationInputTokens":547351,"webSearchRequests":0,"costUSD":66.24225500000001,"contextWindow":1000000,"maxOutputTokens":64000,"canonicalModel":"claude-fable-5","provider":"firstParty","costBasis":"list"}},"permission_denials":[{"tool_name":"PowerShell","tool_use_id":"toolu_0114xsshBxZ2Y6sbJ7yuMx44","tool_input":{"command":"New-Item -ItemType Directory -Force \"c:\\DEV\\MasterArbeit\\Versuche\\Versuch_01\\Iteration 3\\claude-fable-5\\solo\\max\\02_Lauf_2026-08-27_081235_v7.0.0-3021\\Ergebnisse\" | Out-Null; Write-Host \"Ausgabeverzeichnis angelegt\"","description":"Create output directory"}}],"terminal_reason":"completed","fast_mode_state":"off","fast_mode_disabled_reason":"extra_usage_disabled","subagent_stats":{"spawned":0,"requested":{"background":0,"foreground":0,"unset":0},"started_in_background":0,"max_depth":0,"spawned_by_subagents":0,"completed":0,"failed":0,"killed":{"parent":0,"user":0,"system":0},"refused":{"depth_limit":0,"concurrency_limit":0,"budget":0},"by_type":{}},"subtype":"success","api_error_status":null,"result":"Der Lauf ist abgeschlossen. Alle sieben Ergebnisdateien liegen im vorgegebenen Ausgabeverzeichnis `…\\02_Lauf_2026-08-27_081235_v7.0.0-3021\\Ergebnisse\\`.\n\n## Ergebnis im Überblick\n\n**259 Anforderungen** über drei Ebenen: **StRS 32, SyRS 156, SwRS 71**, davon **13 Hypothesen** (5,0 %). Die Codebasis wurde ausschließlich lesend analysiert.\n\n**Vorgehen gemäß Schritt 0-0c:** Vor der ersten Anforderung wurde ein **Modulinventar mit 146 Modulen** erstellt (Kennzahlen: ~14.200 C#-Dateien, 1.558 DB-Tabellen, 182 Views, 750 Benutzerrechte, 83 registrierte Client-Module). Die **Mindestabdeckung ist vollständig erfüllt**: Jedes Modul trägt mindestens eine Anforderung, kein Modul blieb unanalysiert (33 tief, 66 mittel, 47 flach).\n\n**Risikovertiefung:** Alle 81 risikorelevanten Anforderungen (35 Sicherheit/Berechtigungen, 46 Abrechnung/Fakturierung) tragen einen PRIMÄR-Beleg mit benannter durchsetzender Stelle (Datei, Klasse, Methode, Prüfung) – die einzige Ausnahme (Sammelrechnungs-Bündelung) ist regelkonform als `[HYPOTHESE]` markiert. Fachlich besonders ergiebig waren u. a.: Rechnungsstorno mit fünf Vorbedingungen, GoBD-Festschreibung (`IsFixed`), Vertragsabrechnung mit Monatsend-/Schaltjahrlogik und Pro-rata-Normalisierung, Kontingentbuchung mit Überbuchung/Zwischenrechnung, SEPA-Mandatssequenzen, DATEV EXTF 700, die fünfstufige Preisfindungshierarchie, das Sichbenu/Sichmemb/Sichtrus-Rechtemodell sowie der Sicherheitsbefund **ungesalzenes SHA1-Passworthashing** (mit TODO-Kommentar im Code belegt, als abzulösender Ist-Zustand dokumentiert).\n\n**Konsistenzcheck (skriptgestützt über die Abgabedateien):** 0 doppelte IDs, 0 Anforderungen ohne Beleg/Übernahmewürdigkeit/Prüfidee, 0 tote Tracelinks, vollständige Rückverlinkung SwRS→SyRS→StRS, `Hypothesen.md` deckungsgleich mit den 13 Inline-Markierungen. Das Konsolidierungsbeispiel aus dem Prompt wurde im Code bestätigt und erweitert: Kundengeräte existieren **dreifach** (Stammblätter/`MasterDataList`, `AccountDevice`, DocuBoard-`AssetManagement`) und sind als Konsolidierungskandidaten markiert, ebenso Inventur alt/neu, das zweigleisige Einstellungssystem und die beiden Versandwege.","ttft_ms":8870,"ttft_stream_ms":1746,"time_to_request_ms":31,"type":"result","duration_ms":3577708,"uuid":"92217355-07c0-4f36-9301-6be091bcdeb5","queued_turn_count":0} diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Stderr.log b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/Stderr.log new file mode 100644 index 00000000..e69de29b diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/_meta/after.txt b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/_meta/after.txt new file mode 100644 index 00000000..e69de29b diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/_meta/anforderungen.json b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/_meta/anforderungen.json new file mode 100644 index 00000000..37ba2d83 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/_meta/anforderungen.json @@ -0,0 +1,5034 @@ +[ + { + "id": "StRS-01", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Einheitliche Verwaltung von Geschäftspartnern (Accounts)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-036, SyRS-037, SwRS-051", + "konsolidierung": "nein", + "pruefidee": "Ein Benutzer ohne CREATE_CUSTOMER-Recht kann keinen Account anlegen; mit Recht wird der Account angelegt und ist in Verkaufs- und Servicebelegen auswählbar.", + "qm": "", + "uebernahme": "übernehmen - zentrale Stammdatenbasis jedes ERP." + }, + { + "id": "StRS-02", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Durchgängige Vertriebsbelegkette", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-001, SyRS-002, SyRS-003, SyRS-004, SyRS-007, SyRS-008, SyRS-026", + "konsolidierung": "nein", + "pruefidee": "Aus einem Angebot wird ein Auftrag erzeugt; der Auftrag referenziert das Angebot; aus dem Auftrag entstehen Lieferschein und Rechnung mit übernommenen Positionen.", + "qm": "", + "uebernahme": "übernehmen - Kernprozess des Vertriebs." + }, + { + "id": "StRS-03", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Wiederkehrende Abrechnung über Verträge", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-009, SyRS-010, SwRS-019, SwRS-020, SwRS-021", + "konsolidierung": "nein", + "pruefidee": "Ein Monatsvertrag mit Beginn 01.01. erzeugt bei Abrechnung bis 31.03. drei Rechnungen mit korrekten Leistungszeiträumen.", + "qm": "", + "uebernahme": "übernehmen - zentrales Geschäftsmodell der Zielbranche (Systemhäuser/MSP)." + }, + { + "id": "StRS-04", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Nutzungsbasierte Abrechnung (Zähler, Kontingente, MSP)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-011, SyRS-062, SwRS-022, SwRS-024", + "konsolidierung": "nein", + "pruefidee": "Ein Klickvertrag mit Freimenge X und Zählerständen erzeugt eine Rechnung nur über die Menge oberhalb X.", + "qm": "", + "uebernahme": "übernehmen - Differenzierungsmerkmal für MSP-Geschäft." + }, + { + "id": "StRS-05", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Servicegeschäft über Tickets mit abrechenbarer Zeiterfassung", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-045, SyRS-049, SyRS-012, SwRS-063", + "konsolidierung": "nein", + "pruefidee": "Eine auf einem Ticket erfasste abrechenbare Zeit erscheint in der Zeitenabrechnung und nach Fakturierung nicht erneut.", + "qm": "", + "uebernahme": "übernehmen - Kern des Servicegeschäfts." + }, + { + "id": "StRS-06", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Fristen- und Eskalationsüberwachung im Service", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-048, SwRS-049", + "konsolidierung": "nein", + "pruefidee": "Ein Ticket ohne Reaktion überschreitet die Stufe-1-Wartezeit innerhalb des Arbeitszeitfensters und löst genau eine Stufe-1-Mail aus.", + "qm": "", + "uebernahme": "übernehmen - SLA-Erfüllung ist vertragsrelevant." + }, + { + "id": "StRS-07", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Bestandsführung mit Seriennummernverfolgung", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-063, SyRS-064, SyRS-067, SwRS-045, SwRS-046", + "konsolidierung": "nein", + "pruefidee": "Wareneingang einer Seriennummer setzt Zustand InStock; Lieferung an Kunden ändert ihn in InDeliveryList/InInvoice; der Lagerbestand sinkt entsprechend.", + "qm": "", + "uebernahme": "übernehmen - Voraussetzung für Gewährleistung und Service." + }, + { + "id": "StRS-08", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Einkauf über Distributoren mit elektronischem Belegaustausch", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-029, SyRS-030, SyRS-031, SyRS-103, SyRS-110", + "konsolidierung": "nein", + "pruefidee": "Eine per EDI empfangene Lieferantenrechnung wird der Bestellung zugeordnet und als Eingangsbeleg angelegt.", + "qm": "", + "uebernahme": "übernehmen - hohes Belegvolumen im Distributionsgeschäft." + }, + { + "id": "StRS-09", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Zahlungsabwicklung inklusive SEPA-Lastschrift und Onlinebanking", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-071, SyRS-072, SyRS-073, SwRS-026, SwRS-027, SwRS-028", + "konsolidierung": "nein", + "pruefidee": "Ein Kontoumsatz mit Rechnungsnummer im Verwendungszweck wird der Rechnung zugeordnet und deren bezahlter Betrag erhöht.", + "qm": "", + "uebernahme": "übernehmen - Liquiditätssicherung." + }, + { + "id": "StRS-10", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Mahnwesen und Offene-Posten-Überwachung", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-074, SyRS-075, SwRS-030", + "konsolidierung": "nein", + "pruefidee": "Eine überfällige Rechnung ohne Sperre erscheint im Mahnlauf; mit gesetzter Mahnsperre erscheint sie nicht.", + "qm": "", + "uebernahme": "übernehmen - Forderungsmanagement." + }, + { + "id": "StRS-11", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Übergabe an externe Finanzbuchhaltung", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-076, SwRS-029", + "konsolidierung": "nein", + "pruefidee": "Der DATEV-ASCII-Export erzeugt eine mit \"EXTF\";700 beginnende Datei, die die exportierten Rechnungen als Buchungsstapel enthält.", + "qm": "", + "uebernahme": "übernehmen - gesetzlich notwendige FiBu-Anbindung." + }, + { + "id": "StRS-12", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Gesetzeskonforme elektronische Rechnung", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR", + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-104, SyRS-105, SwRS-061, SwRS-062", + "konsolidierung": "nein", + "pruefidee": "Zu einer Rechnung eines Kunden mit Leitweg-ID wird eine XRechnung-Datei mit dieser Leitweg-ID erzeugt.", + "qm": "", + "uebernahme": "übernehmen - gesetzliche Pflicht (E-Rechnung B2G/B2B)." + }, + { + "id": "StRS-13", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Feingranularer, rollenbasierter Zugriffsschutz", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR", + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-080, SyRS-058, SwRS-038", + "konsolidierung": "nein", + "pruefidee": "Entzug eines Gruppenrechts entzieht allen Gruppenmitgliedern die Funktion; ein \"nur eigene\"-Recht blendet fremde Tickets aus.", + "qm": "", + "uebernahme": "übernehmen - Compliance- und Organisationsanforderung." + }, + { + "id": "StRS-14", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Unternehmenskonforme Anmeldung (Verzeichnisdienst, 2FA)", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR", + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-078, SyRS-081, SwRS-032, SwRS-037", + "konsolidierung": "nein", + "pruefidee": "Ein Benutzer mit aktivierter 2FA und abgelaufener Gültigkeitsdauer muss den zweiten Faktor bestätigen, sonst schlägt der Login fehl.", + "qm": "", + "uebernahme": "übernehmen - Sicherheitsstandard." + }, + { + "id": "StRS-15", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Lizenzbasierte Freischaltung von Produkten und Funktionen", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-082, SwRS-035, SwRS-056", + "konsolidierung": "nein", + "pruefidee": "Bei erreichter Lizenzanzahl schlägt ein weiterer Login mit \"Die maximale Anzahl an Lizenzen wurde erreicht.\" fehl.", + "qm": "", + "uebernahme": "übernehmen - Vermarktungsmodell des Herstellers; Umsetzung im SaaS-Modell neu zu bewerten." + }, + { + "id": "StRS-16", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Mandanten- und Filialfähigkeit", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-083, SyRS-028, SyRS-023", + "konsolidierung": "nein", + "pruefidee": "Ein Benutzer mit Filiale A und \"nur eigene Filiale\"-Recht kann keinen Beleg der Filiale B bearbeiten.", + "qm": "", + "uebernahme": "übernehmen - Multi-Site-Betrieb der Kunden." + }, + { + "id": "StRS-17", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Kundenportal im Web", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-121, SyRS-126, SwRS-043", + "konsolidierung": "nein", + "pruefidee": "Ein Web-Account sieht nach Login den Shop, kann ein Ticket anlegen und seine Verträge einsehen.", + "qm": "", + "uebernahme": "übernehmen - Self-Service reduziert Servicekosten." + }, + { + "id": "StRS-18", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Online-Angebotsfreigabe mit Unterschrift", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-122, SyRS-123, SwRS-044", + "konsolidierung": "nein", + "pruefidee": "Ein online angenommenes Angebot wechselt in AcceptFullWebReceipt und ist im Client als angenommen sichtbar.", + "qm": "", + "uebernahme": "übernehmen - beschleunigt den Vertriebsabschluss." + }, + { + "id": "StRS-19", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Gerätestamm beim Kunden für Service und Abrechnung", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-020, SyRS-059, SyRS-060", + "konsolidierung": "Kandidat: SyRS-020 (Stammblätter), SyRS-059 (AccountDevices), SyRS-060 (AssetManagement) - drei Datenhaltungen für denselben fachlichen Gegenstand \"Kundengerät\"; im Zielsystem zu einem Asset-Konzept zusammenführen.", + "pruefidee": "Ein Drucker mit Stammblatt ist über seine Seriennummer auffindbar und zeigt Vertrag und Zählerhistorie.", + "qm": "", + "uebernahme": "übernehmen - fachlich erforderlich, aber konsolidiert statt dreifach." + }, + { + "id": "StRS-20", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "CRM: Aktivitäten, Kampagnen, Umfragen, Verkaufschancen", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-038, SyRS-039, SyRS-040, SyRS-041, SyRS-042", + "konsolidierung": "nein", + "pruefidee": "Der Abschluss eines Tickets erzeugt eine Aktivität in der Kundenhistorie.", + "qm": "", + "uebernahme": "übernehmen - Vertriebssteuerung." + }, + { + "id": "StRS-21", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Integrierte Kommunikation (E-Mail, Kalender, Telefonie, Outlook)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-095, SyRS-096, SyRS-097, SyRS-098, SyRS-099, SyRS-101", + "konsolidierung": "nein", + "pruefidee": "Ein eingehender Anruf zeigt den zugehörigen Ansprechpartner; eine per MailScanner empfangene Mail erzeugt/aktualisiert ein Ticket.", + "qm": "", + "uebernahme": "übernehmen - Effizienz im Tagesgeschäft." + }, + { + "id": "StRS-22", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Auswertungen, Statistiken und Belegreports", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-116, SyRS-117", + "konsolidierung": "nein", + "pruefidee": "Die Umsatzstatistik eines Jahres entspricht der Summe der fakturierten Rechnungen dieses Jahres.", + "qm": "", + "uebernahme": "übernehmen - Steuerungsinformation." + }, + { + "id": "StRS-23", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Datenschutz-Compliance (DSGVO)", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-086, SwRS-052", + "konsolidierung": "nein", + "pruefidee": "Ein Benutzer ohne DSGVO-Recht erhält \"Insufficient rights!\"; mit Recht liefert die Statistik löschbare Kontakte.", + "qm": "", + "uebernahme": "übernehmen - gesetzliche Pflicht." + }, + { + "id": "StRS-24", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Revisionssichere Belegführung", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-006, SyRS-022, SwRS-002, SwRS-016, SwRS-017", + "konsolidierung": "nein", + "pruefidee": "Nach Festschreibung einer Rechnung wird jeder Änderungsversuch abgewiesen; die Versionstabellen enthalten den Stand vor jeder Änderung.", + "qm": "", + "uebernahme": "übernehmen - GoBD-relevante Anforderung." + }, + { + "id": "StRS-25", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Produkt- und Preisdaten von Drittanbietern", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-107, SyRS-108, SyRS-109, SyRS-110, SyRS-017", + "konsolidierung": "nein", + "pruefidee": "Die Artikelsuche in einem Auftrag findet einen nur bei ITscope vorhandenen Artikel und übernimmt ihn mit Preis in die Position.", + "qm": "", + "uebernahme": "übernehmen - Sortimentsbreite ohne Stammdatenpflege." + }, + { + "id": "StRS-26", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Versandabwicklung mit Paketdiensten", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-069, SyRS-070", + "konsolidierung": "nein", + "pruefidee": "Für einen Lieferschein wird ein GLS-Label erzeugt und die Sendungsnummer am Beleg gespeichert.", + "qm": "", + "uebernahme": "übernehmen - Standard-Logistikprozess." + }, + { + "id": "StRS-27", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Produktion/Konfektionierung eigener Artikel", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-068, SyRS-124", + "konsolidierung": "nein", + "pruefidee": "Das Abschließen eines Fertigungsauftrags reduziert die Komponentenbestände und erhöht den Bestand des Erzeugnisses.", + "qm": "", + "uebernahme": "übernehmen - Konfektionierung gehört zum Systemhausgeschäft." + }, + { + "id": "StRS-28", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Projektgeschäft mit Belegzuordnung", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-014, SyRS-053", + "konsolidierung": "nein", + "pruefidee": "Ein Auftrag mit Projektnummer erscheint in der Belegliste des Projekts.", + "qm": "", + "uebernahme": "übernehmen - Projektgeschäft der Systemhäuser." + }, + { + "id": "StRS-29", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Kassenführung für Bargeschäfte", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-018, SwRS-016", + "konsolidierung": "nein", + "pruefidee": "Eine Barrechnung erzeugt eine Kassenbuchbuchung; ihr Storno wird mit Hinweis auf die Barrechnung abgewiesen.", + "qm": "", + "uebernahme": "übernehmen - Ladengeschäft." + }, + { + "id": "StRS-30", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Mitarbeiterverwaltung mit Auslastungssicht", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-084, SyRS-079", + "konsolidierung": "nein", + "pruefidee": "Ein ausgetretener Mitarbeiter (Austrittstermin überschritten) kann sich nicht mehr anmelden.", + "qm": "", + "uebernahme": "übernehmen - Basisstammdaten." + }, + { + "id": "StRS-31", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Zuverlässiger Systembetrieb mit automatischer Datenpflege", + "typ": "nicht-funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-087, SyRS-088, SwRS-053, SwRS-057", + "konsolidierung": "nein", + "pruefidee": "Nach einem Update führt der Dienst ausstehende Skriptnummern genau einmal aus; der DataQualityService läuft stündlich.", + "qm": "Zuverlässigkeit", + "uebernahme": "übernehmen - Betriebsstabilität." + }, + { + "id": "StRS-32", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Deutschsprachiges System mit englischer Zweitsprache", + "typ": "nicht-funktional", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-156, SwRS-058", + "konsolidierung": "nein", + "pruefidee": "Alle in der UI sichtbaren Meldungen erscheinen in der eingestellten Sprache; fehlende EN-Texte fallen auf DE zurück.", + "qm": "Benutzbarkeit (Usability)", + "uebernahme": "übernehmen - Zielmarkt DACH; Mehrsprachigkeit im Web-Zielsystem von Beginn an einplanen." + }, + { + "id": "SyRS-001", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Angebote erstellen und verwalten (M01)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-02", + "konsolidierung": "nein", + "pruefidee": "Angebot mit 2 Positionen speichern, erneut laden: Kopf- und Positionsdaten sind identisch; eine neue Version erhöht die Versionsnummer.", + "qm": "", + "uebernahme": "übernehmen - Standardbelegart." + }, + { + "id": "SyRS-002", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Aufträge verwalten (M02)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-02", + "konsolidierung": "nein", + "pruefidee": "Ein Auftrag mit lieferbaren Positionen erscheint in der Abrechnungssuche bis er fakturiert ist.", + "qm": "", + "uebernahme": "übernehmen - Standardbelegart." + }, + { + "id": "SyRS-003", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Lieferscheine führen (M03)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-02", + "konsolidierung": "nein", + "pruefidee": "Ein offener Lieferschein (Status 1) bis zum Stichtag erscheint in der Abrechnungssuche des Kunden.", + "qm": "", + "uebernahme": "übernehmen - Standardbelegart." + }, + { + "id": "SyRS-004", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Rechnungen erstellen (M04)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-02, StRS-24", + "konsolidierung": "nein", + "pruefidee": "Eine erzeugte Rechnung enthält Zahlungsbedingung und Fälligkeitsdatum; Teilzahlungen erhöhen PaidFC.", + "qm": "", + "uebernahme": "übernehmen - Kernbelegart." + }, + { + "id": "SyRS-005", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Rechnungen stornieren mit Schutzbedingungen (M04)", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-24, StRS-29, SwRS-016", + "konsolidierung": "nein", + "pruefidee": "Storno ohne Recht → Fehlermeldung; Storno einer exportierten Rechnung → Fehlermeldung; Storno der letzten Vertragsrechnung → neue Version Status storniert, Klickzähler zurückgesetzt.", + "qm": "", + "uebernahme": "übernehmen - buchhalterische Integrität." + }, + { + "id": "SyRS-006", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Rechnungen festschreiben (M04)", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-24, SwRS-017", + "konsolidierung": "nein", + "pruefidee": "Nach FixInvoice liefert ein erneuter Fix-Versuch die Warnung \"festgeschrieben. Änderungen nicht möglich.\"; ein Logeintrag mit Benutzer existiert.", + "qm": "", + "uebernahme": "übernehmen - GoBD-Anforderung." + }, + { + "id": "SyRS-007", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Gutschriften führen (M05)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-02, StRS-10", + "konsolidierung": "nein", + "pruefidee": "Ein Kunde mit offener Rechnung und Gutschrift zeigt im Mahnlauf beide Belege; die Gutschrift reduziert den Saldo.", + "qm": "", + "uebernahme": "übernehmen - Standardbelegart." + }, + { + "id": "SyRS-008", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Abhollisten führen (M06)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-02, StRS-07", + "konsolidierung": "nein", + "pruefidee": "Eine Seriennummer auf einer Abholliste wechselt in den Zustand AssignedToPickupList.", + "qm": "", + "uebernahme": "übernehmen - Retourenlogistik." + }, + { + "id": "SyRS-009", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Verträge als Belegart mit Abrechnungsparametern (M07)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-03", + "konsolidierung": "nein", + "pruefidee": "Ein Vertrag mit Intervall \"monatlich, Dauer 3\" und automatischer Abrechnung wird als quartalsweise abzurechnender Vertrag gespeichert und so von der Abrechnung interpretiert.", + "qm": "", + "uebernahme": "übernehmen - Vertragsstamm." + }, + { + "id": "SyRS-010", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Automatische Vertragsabrechnung (M08)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-03, SwRS-019, SwRS-020, SwRS-021, SwRS-022", + "konsolidierung": "nein", + "pruefidee": "Zwei fällige Monatsperioden eines Vertrags erzeugen im Lauf genau eine Rechnung mit Intervallzähler 2 (bzw. zwei Perioden) und einen Protokolleintrag.", + "qm": "", + "uebernahme": "übernehmen - Kernautomatisierung." + }, + { + "id": "SyRS-011", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Zählerstands-/Klickabrechnung (M08)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-04, SwRS-024", + "konsolidierung": "nein", + "pruefidee": "Zwei Zählerstände mit Differenz D und Freimenge F erzeugen eine Abrechnungsmenge max(0, D-F).", + "qm": "", + "uebernahme": "übernehmen - Druck-/Kopierer-Geschäft." + }, + { + "id": "SyRS-012", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Zeitenabrechnung aus Tickets (M09)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-05, SwRS-063", + "konsolidierung": "nein", + "pruefidee": "Eine bereits fakturierte Zeit erscheint nicht erneut in der Selektion; ein Ticket mit Pauschalposition wird bei Standardfilter ausgeblendet.", + "qm": "", + "uebernahme": "übernehmen - Dienstleistungsabrechnung." + }, + { + "id": "SyRS-013", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Anzahlungsrechnungen und Schlussrechnung (M10)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-02", + "konsolidierung": "nein", + "pruefidee": "Auftrag über 10.000, Anzahlung 3.000: Die Schlussrechnung weist 3.000 als verrechnete Anzahlung aus und fordert 7.000.", + "qm": "", + "uebernahme": "übernehmen - Projektgeschäft." + }, + { + "id": "SyRS-014", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Projekte mit Belegbezug (M11)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-28", + "konsolidierung": "nein", + "pruefidee": "Ein Auftrag mit Projektnummer P erscheint in der Projektfilterung zu P.", + "qm": "", + "uebernahme": "übernehmen - Projektauswertung." + }, + { + "id": "SyRS-015", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Leasing- und Service-Raten (M12)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-02, StRS-15", + "konsolidierung": "nein", + "pruefidee": "Ohne Lizenz LeasingService ist das Modul unsichtbar; mit Lizenz und Recht lassen sich Raten anlegen.", + "qm": "", + "uebernahme": "übernehmen - Finanzierungsgeschäft; Detailtiefe in Folgeiteration prüfen." + }, + { + "id": "SyRS-016", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Aktionspreise verwalten (M13)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-25, SyRS-017", + "konsolidierung": "nein", + "pruefidee": "Ein Aktionspreis mit gültigem Zeitraum wird beim Artikel angezeigt; nach Ablauf nicht mehr.", + "qm": "", + "uebernahme": "übernehmen - Einkaufsvorteile weitergeben." + }, + { + "id": "SyRS-017", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Artikelsuche mit integrierter Preisfindung im Beleg (M14)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-02, StRS-25, SwRS-007, SwRS-008, SwRS-009, SwRS-010", + "konsolidierung": "nein", + "pruefidee": "Derselbe Artikel liefert für zwei Kunden mit unterschiedlichen Sonderpreisen unterschiedliche VK-Vorschläge.", + "qm": "", + "uebernahme": "übernehmen - zentrale Erfassungsunterstützung." + }, + { + "id": "SyRS-018", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Kassenbuch mit belegbezogenen Buchungen (M15)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-29", + "konsolidierung": "nein", + "pruefidee": "Eine Barrechnung über 100 erzeugt eine Kassenbuchung 100; Löschen des Belegs entfernt die Buchung.", + "qm": "", + "uebernahme": "übernehmen - Bargeschäft." + }, + { + "id": "SyRS-019", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Kundenindividuelle Sonderpreise (M16)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-17, StRS-25, SwRS-008, SwRS-043", + "konsolidierung": "nein", + "pruefidee": "Ein Fixpreis-Sonderpreis ersetzt den Standard-VK in der Belegposition dieses Kunden.", + "qm": "", + "uebernahme": "übernehmen - Preisvereinbarungen." + }, + { + "id": "SyRS-020", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Gerätestammblätter mit Zähler- und Vertragsbezug (M17)", + "typ": "Daten", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-19, StRS-04", + "konsolidierung": "Kandidat: SyRS-059 (AccountDevices), SyRS-060 (AssetManagement) - dieselbe fachliche Entität \"Kundengerät\" in getrennten Datenhaltungen; im Zielsystem zusammenführen.", + "pruefidee": "Ein aus einer Rechnung erzeugtes Stammblatt zeigt Rechnungsnummer und -datum; der Vertrag findet es über die Stammblattliste.", + "qm": "", + "uebernahme": "übernehmen - fachlich nötig, aber im Zielsystem als Teil eines vereinheitlichten Asset-Konzepts." + }, + { + "id": "SyRS-021", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Schweizer Rundung (Rappenrundung) (M18)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-02, SwRS-012", + "konsolidierung": "nein", + "pruefidee": "Nettobetrag 100,00 mit 8,1 % MwSt ergibt bei aktivem Schalter einen auf 0,05 endenden Bruttobetrag.", + "qm": "", + "uebernahme": "Sonderfall - nur für Schweizer Mandanten relevant, dort aber zwingend." + }, + { + "id": "SyRS-022", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Belegversionierung mit vollständigen Versionsständen (M19)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-24, SwRS-002", + "konsolidierung": "nein", + "pruefidee": "Nach zwei Änderungen einer Rechnung existieren zwei Versionssätze in RechKopfVersions mit OriginalI3D der Rechnung.", + "qm": "", + "uebernahme": "übernehmen - Nachvollziehbarkeit; technische Umsetzung (Tabellenkopie) im Zielsystem neu entscheiden." + }, + { + "id": "SyRS-023", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Nummernkreise je Mandant/Filiale (M20)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-16, SwRS-025", + "konsolidierung": "nein", + "pruefidee": "Zwei parallele Nummernanforderungen liefern zwei verschiedene Nummern; eine bereits in der Zieltabelle vorhandene Nummer wird übersprungen.", + "qm": "", + "uebernahme": "übernehmen - Nummernvergabe ist buchhalterisch zwingend." + }, + { + "id": "SyRS-024", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Belegdruck und Belegversand per E-Mail (M21)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-03, StRS-21, StRS-22", + "konsolidierung": "nein", + "pruefidee": "Ein Kunde mit zwei hinterlegten Rechnungsempfängern erhält die Vertragsrechnung an beide Adressen mit der konfigurierten Betreffzeile.", + "qm": "", + "uebernahme": "übernehmen - Belegzustellung." + }, + { + "id": "SyRS-025", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Kreditlimitprüfung beim Belegspeichern (M68)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-01, StRS-02, SwRS-015", + "konsolidierung": "nein", + "pruefidee": "Kunde mit Limit 1.000 und offenen Belegen 900: Ein neuer Auftrag über 200 löst den Überschreitungsdialog mit Differenz 100 aus.", + "qm": "", + "uebernahme": "übernehmen - Forderungsrisiko begrenzen." + }, + { + "id": "SyRS-026", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Belegweiterverarbeitung mit Validierung (M01-M06 übergreifend)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-02", + "konsolidierung": "nein", + "pruefidee": "Nach Auftrag→Rechnung ist die Rechnung als Folgebeleg des Auftrags sichtbar und der Auftrag nicht mehr frei löschbar/stornierbar.", + "qm": "", + "uebernahme": "übernehmen - Belegkettenintegrität." + }, + { + "id": "SyRS-027", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Gleichzeitige Belegbearbeitung erkennen (M01-M06 übergreifend)", + "typ": "nicht-funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-02, SwRS-005", + "konsolidierung": "nein", + "pruefidee": "Benutzer A und B laden denselben Beleg; A speichert; Bs Speichern wird mit ChangedByOtherInstance abgewiesen.", + "qm": "Zuverlässigkeit", + "uebernahme": "übernehmen - Mehrbenutzerbetrieb." + }, + { + "id": "SyRS-028", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Filialbezogene Belegrechte (M73/M70 übergreifend)", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-13, StRS-16", + "konsolidierung": "nein", + "pruefidee": "Benutzer der Filiale A mit Einschränkungsrecht kann Beleg der Filiale B nicht speichern; ein Web-Account erhält bei Belegabruf über die interne Sicht einen Rechtefehler.", + "qm": "", + "uebernahme": "übernehmen - Mandanten-/Filialtrennung." + }, + { + "id": "SyRS-029", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Lieferantenbestellungen führen (M22)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-08", + "konsolidierung": "nein", + "pruefidee": "Eine Bestellung an ALSO wird als EDI-Order übertragen und erhält die Distributor-Auftragsnummer zurück.", + "qm": "", + "uebernahme": "übernehmen - Einkaufskernprozess." + }, + { + "id": "SyRS-030", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Lieferantenrechnungen erfassen und aus PDF auslesen (M23)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-08, StRS-12", + "konsolidierung": "nein", + "pruefidee": "Ein Lieferanten-PDF mit konfigurierter Scanstrategie füllt Belegnummer und Betrag automatisch.", + "qm": "", + "uebernahme": "übernehmen - Eingangsrechnungsprozess." + }, + { + "id": "SyRS-031", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Wareneingang über Lieferantenlieferscheine (M24)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-08, StRS-07", + "konsolidierung": "nein", + "pruefidee": "Ein EDI-Lieferavis mit Seriennummern erzeugt einen Lieferantenlieferschein, dessen Buchung die Seriennummern in den Bestand übernimmt.", + "qm": "", + "uebernahme": "übernehmen - Wareneingangsprozess." + }, + { + "id": "SyRS-032", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Lieferantengutschriften führen (M25)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-08", + "konsolidierung": "nein", + "pruefidee": "Eine erfasste Lieferantengutschrift erscheint in der Einkaufsbelegliste des Lieferanten.", + "qm": "", + "uebernahme": "übernehmen - Einkaufsbelegart." + }, + { + "id": "SyRS-033", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Dokumente zu Einkaufsbelegen (M26)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-08, StRS-24", + "konsolidierung": "nein", + "pruefidee": "Ein angehängtes PDF ist nach erneutem Öffnen des Belegs abrufbar.", + "qm": "", + "uebernahme": "übernehmen - Belegarchivierung." + }, + { + "id": "SyRS-034", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Bestellvorschläge ermitteln (M27)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-08, StRS-07", + "konsolidierung": "nein", + "pruefidee": "Ein Auftrag über einen nicht lagernden Artikel erzeugt einen Bestellvorschlag in Höhe der Fehlmenge.", + "qm": "", + "uebernahme": "übernehmen - Beschaffungsplanung." + }, + { + "id": "SyRS-035", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Lieferanten- und Distributorenstamm (M28)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-01, StRS-08", + "konsolidierung": "nein", + "pruefidee": "Das Anlegen eines zweiten Lieferanten mit gleicher Nummer schlägt mit Constraint-Fehler fehl.", + "qm": "", + "uebernahme": "übernehmen - Einkaufsstammdaten." + }, + { + "id": "SyRS-036", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Accountverwaltung mit Rechteprüfung (M29)", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-01, StRS-13, SwRS-051", + "konsolidierung": "nein", + "pruefidee": "Benutzer ohne CREATE_CUSTOMER erhält \"Fehlende Rechte um Accounts zu erstellen\"; doppelte Kundennummer wird vom Constraint verhindert.", + "qm": "", + "uebernahme": "übernehmen - Stammdatenschutz." + }, + { + "id": "SyRS-037", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Adressen und Ansprechpartner je Account (M30)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-01", + "konsolidierung": "nein", + "pruefidee": "Ein Kunde mit abweichendem Rechnungsempfänger erhält Rechnungen an dessen Adresse/Kontakt.", + "qm": "", + "uebernahme": "übernehmen - Adressqualität." + }, + { + "id": "SyRS-038", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Kundenaktivitäten protokollieren (M31)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-20", + "konsolidierung": "nein", + "pruefidee": "Ticketabschluss erzeugt genau eine Aktivität mit Ticketbezug in der Kundenhistorie.", + "qm": "", + "uebernahme": "übernehmen - CRM-Kern." + }, + { + "id": "SyRS-039", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Kampagnen mit Phasen und Aktionen (M32)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-20", + "konsolidierung": "nein", + "pruefidee": "Eine Kampagne mit zwei Phasen führt Kunden phasenweise; abgeschlossene Aktionen sind je Kunde vermerkt.", + "qm": "", + "uebernahme": "übernehmen - Vertriebsunterstützung." + }, + { + "id": "SyRS-040", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Telemarketing und Mailings (M33)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-20, StRS-21", + "konsolidierung": "nein", + "pruefidee": "Ein Mailing an eine Selektion erzeugt je Empfänger einen Versandeintrag.", + "qm": "", + "uebernahme": "übernehmen - Marktbearbeitung." + }, + { + "id": "SyRS-041", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Kundenumfragen inkl. automatischem Versand (M34)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-20, StRS-05", + "konsolidierung": "nein", + "pruefidee": "Bei aktivierter Einstellung enthält die Abschlussmail eines Tickets den Umfragelink; ohne Einstellung nicht.", + "qm": "", + "uebernahme": "übernehmen - Qualitätsfeedback." + }, + { + "id": "SyRS-042", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "CRM-Projekte (Verkaufschancen) (M35)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-20, SyRS-023", + "konsolidierung": "nein", + "pruefidee": "Ein neues CRM-Projekt erhält automatisch die nächste Nummer seines Nummernkreises.", + "qm": "", + "uebernahme": "übernehmen - Vertriebssteuerung." + }, + { + "id": "SyRS-043", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Hotline-Konditionen je Kunde (M36)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-05", + "konsolidierung": "nein", + "pruefidee": "Ein am Kunden hinterlegter Hotline-Eintrag ist im Serviceprozess des Kunden sichtbar.", + "qm": "", + "uebernahme": "übernehmen - Servicewissen am Kunden." + }, + { + "id": "SyRS-044", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Kundenvereinbarungen (Account Contracts) (M37)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-20", + "konsolidierung": "Kandidat: SyRS-009 (Verträge als Belegart) - beide bilden \"Vertrag mit Kunde\" ab; fachliche Abgrenzung (formlose Vereinbarung vs. abrechenbarer Vertragsbeleg) ist im Zielsystem explizit zu regeln.", + "pruefidee": "Eine Vereinbarung der Art X erscheint in der Vereinbarungsliste des Kunden mit Art X.", + "qm": "", + "uebernahme": "übernehmen - sofern nach Konsolidierungsentscheid noch nötig." + }, + { + "id": "SyRS-045", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Tickets anlegen und verwalten (M38)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-05, SyRS-023", + "konsolidierung": "nein", + "pruefidee": "Zwei nacheinander angelegte Tickets erhalten fortlaufende Nummern des Helpdesk-Nummernkreises.", + "qm": "", + "uebernahme": "übernehmen - Servicekern." + }, + { + "id": "SyRS-046", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Konfigurierbare Ticket-Pflichtfelder (M38)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-05, SyRS-085", + "konsolidierung": "nein", + "pruefidee": "Bei aktivierter Prioritätspflicht wird ein Ticket ohne Priorität mit \"Keine Priorität ausgewählt.\" abgewiesen.", + "qm": "", + "uebernahme": "übernehmen - Datenqualität im Service." + }, + { + "id": "SyRS-047", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Ticketabschluss mit Folgeaktionen (M38)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-05, SwRS-048", + "konsolidierung": "nein", + "pruefidee": "Nach Abschluss trägt das Ticket den Abschlussstatus und ClosedAt; Historie und Kundenaktivität existieren; offene ToDos des Tickets sind entfernt.", + "qm": "", + "uebernahme": "übernehmen - Serviceprozess." + }, + { + "id": "SyRS-048", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Mehrstufige Ticketeskalation (M39)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-06, SwRS-049", + "konsolidierung": "nein", + "pruefidee": "Ein Ticket mit Stufe-1-Wartezeit 4h eskaliert nach 4 Arbeitsstunden; samstags nur bei aktiviertem Samstags-Flag.", + "qm": "", + "uebernahme": "übernehmen - SLA-Sicherung." + }, + { + "id": "SyRS-049", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Zeiterfassung auf Tickets (M40)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-05, SyRS-012", + "konsolidierung": "nein", + "pruefidee": "Eine fakturierte Zeit lässt sich nicht mehr löschen; eine unterschriebene Zeit zeigt die Signatur im Servicebericht.", + "qm": "", + "uebernahme": "übernehmen - Abrechnungsgrundlage." + }, + { + "id": "SyRS-050", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Checklisten auf Tickets (M41)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-05", + "konsolidierung": "nein", + "pruefidee": "Das Abhaken eines Checklistenpunkts erzeugt einen Änderungslogeintrag mit Benutzer.", + "qm": "", + "uebernahme": "übernehmen - standardisierte Abarbeitung." + }, + { + "id": "SyRS-051", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Ticketvorlagen und automatische Ticketerzeugung (C-FLOW) (M42)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-05", + "konsolidierung": "nein", + "pruefidee": "Eine Vorlage mit Intervall erzeugt zum Stichtag ein Ticket mit den Vorlagenwerten.", + "qm": "", + "uebernahme": "übernehmen - Automatisierung wiederkehrender Aufgaben." + }, + { + "id": "SyRS-052", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Taskmanagement mit Aktionsausführung (M43)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-05", + "konsolidierung": "nein", + "pruefidee": "Eine Aufgabe mit Helpdesk-Aktion erzeugt bei Fälligkeit die konfigurierte Ticketänderung.", + "qm": "", + "uebernahme": "übernehmen - Serviceautomatisierung." + }, + { + "id": "SyRS-053", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Ticketprojekte mit Abhängigkeiten (M44)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-28, StRS-05", + "konsolidierung": "nein", + "pruefidee": "Eine Abhängigkeit Ticket B nach Ticket A ist gespeichert und in der Projektansicht sichtbar.", + "qm": "", + "uebernahme": "übernehmen - strukturierte Projektabwicklung." + }, + { + "id": "SyRS-054", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "RMA-Abwicklung mit Ticketbindung (M45)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-05, StRS-07, SwRS-050", + "konsolidierung": "nein", + "pruefidee": "Das Anlegen einer zweiten RMA zum selben Ticket schlägt mit Index-Fehler fehl.", + "qm": "", + "uebernahme": "übernehmen - Retourenprozess." + }, + { + "id": "SyRS-055", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Anbindung externer Helpdesk-Systeme (M46)", + "typ": "Schnittstelle", + "belege": [ + "SEKUNDÄR" + ], + "status": "HYPOTHESE - Begründung: Nur Konfigurationsartefakt gefunden; Umfang und Richtung des Austauschs unbelegt.", + "hypothese": true, + "workaround": false, + "tracelinks": "StRS-05", + "konsolidierung": "nein", + "pruefidee": "Nachweis einer Synchronisationsstrecke (z. B. Ticketanlage aus externem System) in einer Folgeanalyse; bis dahin Interview mit Fachbereich.", + "qm": "", + "uebernahme": "übernehmen - sofern die Funktion produktiv genutzt wird; fehlende Belegtiefe klären." + }, + { + "id": "SyRS-056", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Terminanfragen an Kunden (M47)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-05, StRS-21", + "konsolidierung": "nein", + "pruefidee": "Die Annahme eines Terminvorschlags durch den Kunden markiert den Vorschlag als angenommen.", + "qm": "", + "uebernahme": "übernehmen - Terminkoordination." + }, + { + "id": "SyRS-057", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "ToDo-Listen mit Objektbezug (M48)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-05", + "konsolidierung": "nein", + "pruefidee": "Ein Beleg mit Wiedervorlagedatum erzeugt ein ToDo; Ticketabschluss entfernt die Ticket-ToDos.", + "qm": "", + "uebernahme": "übernehmen - Aufgabensteuerung." + }, + { + "id": "SyRS-058", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Einschränkende Sichtbarkeitsrechte im Helpdesk (M38/M70)", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-13, StRS-05", + "konsolidierung": "nein", + "pruefidee": "Ein Benutzer mit SHOW_HELPDESK_ONLY_OWN sieht in der Ticketliste ausschließlich Tickets, bei denen er Bearbeiter oder Verantwortlicher ist.", + "qm": "", + "uebernahme": "übernehmen - Vertraulichkeit im Service." + }, + { + "id": "SyRS-059", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Kundengeräte (AccountDevices) verwalten (M49)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-19", + "konsolidierung": "Kandidat: SyRS-020 (Stammblätter), SyRS-060 (AssetManagement) - dieselbe fachliche Entität \"Kundengerät\" in getrennten Datenhaltungen.", + "pruefidee": "Ein gelöschtes Gerät bleibt mit IsDeleted/DeletedDate erhalten und verschwindet aus der aktiven Liste.", + "qm": "", + "uebernahme": "übernehmen - im Zielsystem als Teil des konsolidierten Asset-Konzepts." + }, + { + "id": "SyRS-060", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "IT-Dokumentation/Inventarisierung (DocuBoard) (M50)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-19", + "konsolidierung": "Kandidat: SyRS-020, SyRS-059 - Gerätedaten dreifach; im Zielsystem ein Asset-Modell.", + "pruefidee": "Ein AD-Scan-Ergebnis erscheint beim Kunden; ausgeschlossene AD-Benutzer fehlen in der Auswertung.", + "qm": "", + "uebernahme": "übernehmen - MSP-Dokumentationspflicht." + }, + { + "id": "SyRS-061", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "RMM-Datenübernahme (M51)", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-04, StRS-19", + "konsolidierung": "nein", + "pruefidee": "Ein importierter RMM-Zählerwert erscheint als Zählerstand des zugehörigen Geräts/Vertrags.", + "qm": "", + "uebernahme": "übernehmen - MSP-Automatisierung." + }, + { + "id": "SyRS-062", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "MSP-Sammler und Vergütungsauswertung (M52)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-04, SwRS-064", + "konsolidierung": "nein", + "pruefidee": "Eine MSP-Bewertung erzeugt eine Vertragsposition mit ersetztem Variablentext und der bewerteten Menge.", + "qm": "", + "uebernahme": "übernehmen - MSP-Geschäftsmodell." + }, + { + "id": "SyRS-063", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Artikelstamm verwalten (M53)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-07, StRS-25", + "konsolidierung": "nein", + "pruefidee": "Ein importierter Artikel ist mit Warengruppe und Preisen in der Artikelsuche auffindbar; Preisänderungen erscheinen in der Historie.", + "qm": "", + "uebernahme": "übernehmen - Kernstammdaten." + }, + { + "id": "SyRS-064", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Bestandsführung je Lager mit EK-Fortschreibung (M54)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-07, SwRS-011, SwRS-046", + "konsolidierung": "nein", + "pruefidee": "Wareneingang 10 Stück zu 8 € auf Bestand 10 Stück zu 10 € ergibt bei gleitendem Durchschnitt EK 9 €.", + "qm": "", + "uebernahme": "übernehmen - Bestandsbewertung." + }, + { + "id": "SyRS-065", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Inventur mit Scan-Erfassung (M55)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-07", + "konsolidierung": "Kandidat: BL/Warehousing/InventoryBL.cs (alte Inventur) und InventoryNewBL.cs (neue Inventur) bilden denselben Prozess doppelt ab; im Zielsystem eine Inventur.", + "pruefidee": "Ein gescannter Barcode erhöht die Zählmenge; nach Inventurabschluss sind Differenzen als Korrektur gebucht.", + "qm": "", + "uebernahme": "übernehmen - gesetzliche Inventurpflicht; nur die neue Implementierung." + }, + { + "id": "SyRS-066", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Kommissionierung von Aufträgen (M56)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-07, StRS-02", + "konsolidierung": "nein", + "pruefidee": "Eine Teilkommission über 5 von 10 Stück setzt den Teillieferstatus und lässt 5 Stück offen.", + "qm": "", + "uebernahme": "übernehmen - Lagerprozess." + }, + { + "id": "SyRS-067", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Seriennummern-/Barcodeverwaltung mit Lebenszyklus (M57)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-07, SwRS-045", + "konsolidierung": "nein", + "pruefidee": "Verkauf einer Seriennummer wechselt InStock→InInvoice und erzeugt einen Historieneintrag.", + "qm": "", + "uebernahme": "übernehmen - Rückverfolgbarkeit." + }, + { + "id": "SyRS-068", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Fertigungsaufträge (M58)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-27", + "konsolidierung": "nein", + "pruefidee": "Ein Fertigungsauftrag zeigt je Position ihren Status; Statuswechsel sind gespeichert.", + "qm": "", + "uebernahme": "übernehmen - Konfektionierung." + }, + { + "id": "SyRS-069", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "GLS-Versandanbindung (M59)", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-26", + "konsolidierung": "Kandidat: SyRS-070 (Shipcloud) - zwei Versandwege mit gleicher fachlicher Funktion; im Zielsystem über eine Versandabstraktion vereinheitlichen.", + "pruefidee": "Eine Sendung mit ungültiger PLZ liefert den GLS-Fehlercode im Ergebnis.", + "qm": "", + "uebernahme": "übernehmen - aktiver Versandweg." + }, + { + "id": "SyRS-070", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Shipcloud-Versandanbindung (M60)", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-26", + "konsolidierung": "Kandidat: SyRS-069 (GLS) - gleiche fachliche Funktion Versand; vereinheitlichen.", + "pruefidee": "Eine Sendung wird mit Carrier-Auswahl an Shipcloud übertragen und liefert eine Trackingnummer.", + "qm": "", + "uebernahme": "übernehmen - Carrier-Flexibilität." + }, + { + "id": "SyRS-071", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Zahlungseingänge erfassen und zuordnen (M61)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-09, StRS-13", + "konsolidierung": "nein", + "pruefidee": "Löschen eines Zahlungseingangs über 100 reduziert PaidFC der Rechnung um 100 und schreibt einen Logeintrag; ohne Recht wird die Aktion abgewiesen.", + "qm": "", + "uebernahme": "übernehmen - Zahlungsbuchführung." + }, + { + "id": "SyRS-072", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Onlinebanking: Umsatzabruf und automatische Zuordnung (M62)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-09, SwRS-028", + "konsolidierung": "nein", + "pruefidee": "Ein Umsatz mit gültiger Rechnungsnummer im Verwendungszweck wird der Rechnung zugeordnet; UndoBooking stellt den vorherigen Zustand her.", + "qm": "", + "uebernahme": "übernehmen - Automatisierung der Zahlungszuordnung." + }, + { + "id": "SyRS-073", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "SEPA-Lastschriftexport (M63)", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-09, SwRS-026, SwRS-027", + "konsolidierung": "nein", + "pruefidee": "Ein Export mit aktivierter Abschluss-Einstellung setzt die Rechnung auf bezahlt mit Log \"Abschluss über SEPA Export\"; die Rücknahme öffnet sie wieder und reduziert PayedAmount.", + "qm": "", + "uebernahme": "übernehmen - Zahlungseinzug." + }, + { + "id": "SyRS-074", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Mahnläufe mit Mahnsperren (M64)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-10, SwRS-030", + "konsolidierung": "nein", + "pruefidee": "Eine Rechnung mit Mahnsperre fehlt im Lauf; eine zweifach gemahnte Rechnung erscheint mit Stufe 3 im nächsten Lauf.", + "qm": "", + "uebernahme": "übernehmen - Forderungsmanagement." + }, + { + "id": "SyRS-075", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "OPOS-Verwaltung und -Import (M65)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-10, StRS-11", + "konsolidierung": "nein", + "pruefidee": "Ein importierter OP-Ausgleich setzt die zugehörige Rechnung auf bezahlt.", + "qm": "", + "uebernahme": "übernehmen - Abstimmung mit FiBu." + }, + { + "id": "SyRS-076", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Buchhaltungsexport in Fremdformate (M66)", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-11, SwRS-029", + "konsolidierung": "nein", + "pruefidee": "Nach DATEV-Export einer Rechnung wird ihr Storno mit \"bereits exportiert\" abgewiesen.", + "qm": "", + "uebernahme": "übernehmen - FiBu-Pflichtschnittstelle; Formatliste im Zielsystem auf tatsächlich genutzte reduzieren." + }, + { + "id": "SyRS-077", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Bankverbindungen der Geschäftspartner (M67)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-09", + "konsolidierung": "nein", + "pruefidee": "Eine nicht autorisierte Bankverbindung erscheint nicht in der Lastschriftauswahl.", + "qm": "", + "uebernahme": "übernehmen - Zahlungsstammdaten." + }, + { + "id": "SyRS-078", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Benutzeranmeldung mit Sitzungstickets (M69)", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR", + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-14, SwRS-032, SwRS-034, SwRS-041", + "konsolidierung": "nein", + "pruefidee": "Ein Aufruf ohne Ticket liefert \"You need to provide a ticket\"; nach 30 Minuten Inaktivität ist das Ticket ungültig.", + "qm": "", + "uebernahme": "übernehmen - Zugangsschutz; Hashverfahren modernisieren (siehe SwRS-032)." + }, + { + "id": "SyRS-079", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Kontodeaktivierung über Status und Zeitfenster (M69)", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-14, StRS-30, SwRS-033", + "konsolidierung": "nein", + "pruefidee": "Ein Konto mit AccountDisabledFromDate=gestern wird abgewiesen; nach Ablauf des Bis-Datums funktioniert der Login wieder.", + "qm": "", + "uebernahme": "übernehmen - Offboarding-Sicherheit." + }, + { + "id": "SyRS-080", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Gruppenbasierte Rechteverwaltung (M70)", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-13, SwRS-038", + "konsolidierung": "nein", + "pruefidee": "Das Kopieren der Rechtegruppen von Benutzer A auf B verschafft B exakt As Gruppen; die Änderung erscheint im Rechte-Log.", + "qm": "", + "uebernahme": "übernehmen - Berechtigungsadministration." + }, + { + "id": "SyRS-081", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Zwei-Faktor-Authentifizierung (M71)", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-14, SwRS-037", + "konsolidierung": "nein", + "pruefidee": "Benutzer mit 2FA und Gültigkeitsdauer 0 muss bei jedem Login bestätigen; mit Dauer 7 Tage erst nach Ablauf erneut.", + "qm": "", + "uebernahme": "übernehmen - Kontosicherheit." + }, + { + "id": "SyRS-082", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Lizenzprüfung für Anwendungen und Funktionen (M72)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-15, SwRS-035", + "konsolidierung": "nein", + "pruefidee": "Bei Lizenzanzahl 5 und 5 aktiven Tickets schlägt der 6. Login mit LicenseMaximumReached fehl.", + "qm": "", + "uebernahme": "übernehmen - Lizenzmodell; SaaS-tauglich neu schneiden." + }, + { + "id": "SyRS-083", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Mandanten-, Firmen- und Filialverwaltung (M73)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-16", + "konsolidierung": "nein", + "pruefidee": "Eine neue Filiale erhält beim Nummernkreis-Refresh eigene Nummernkreise; ihre Lagerzuordnung wirkt in der Bestandssicht.", + "qm": "", + "uebernahme": "übernehmen - Organisationsabbildung." + }, + { + "id": "SyRS-084", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Mitarbeiterverwaltung (M74)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-30", + "konsolidierung": "nein", + "pruefidee": "Ein Mitarbeiter mit Abteilungszuordnung erscheint in der Abteilungsliste; sein Mitarbeiterartikel wird in der Zeitabrechnung verwendet.", + "qm": "", + "uebernahme": "übernehmen - Personalstamm." + }, + { + "id": "SyRS-085", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Zentrale Anwendungseinstellungen (M75)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-31, SwRS-054", + "konsolidierung": "Kandidat: Stammdat- und ApplicationSettings-Einstellungen bilden dieselbe Funktion doppelt ab; im Zielsystem ein Einstellungssystem.", + "pruefidee": "Das Umschalten von HelpdeskPriorityFieldIsRequired ändert die Pflichtfeldprüfung ohne Neustart-Codeänderung.", + "qm": "", + "uebernahme": "übernehmen - Konfigurierbarkeit; nur eingleisig." + }, + { + "id": "SyRS-086", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "DSGVO-Datenbereinigung und Löschrecht (M76)", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-23, SwRS-052", + "konsolidierung": "nein", + "pruefidee": "Ohne ACCESS_CLEANUP_DATABASE liefert die Statistik \"Insufficient rights!\"; die Löschung eines Kontakts entfernt dessen personenbezogene Daten.", + "qm": "", + "uebernahme": "übernehmen - gesetzliche Pflicht." + }, + { + "id": "SyRS-087", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Versionierte Datenbankmigration (M77)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-31, SwRS-053", + "konsolidierung": "nein", + "pruefidee": "Ein zweifach gestartetes Update führt ein AddColumnIfNotExists-Skript ohne Fehler erneut aus.", + "qm": "", + "uebernahme": "übernehmen - Konzept; konkrete Skripte sind Altbestand." + }, + { + "id": "SyRS-088", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Hintergrunddienste für Datenqualität (M78)", + "typ": "nicht-funktional", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-31, SwRS-057", + "konsolidierung": "nein", + "pruefidee": "Eine absichtlich fehlschlagende Aufgabe wird geloggt; die übrigen Aufgaben des Laufs werden trotzdem ausgeführt.", + "qm": "Zuverlässigkeit", + "uebernahme": "übernehmen - Betriebsautomatisierung." + }, + { + "id": "SyRS-089", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Telemetrie und Profiling (M79)", + "typ": "nicht-funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "HYPOTHESE - Begründung: Zweck und Datenfluss der Telemetrie nicht aus dem Code verifiziert.", + "hypothese": true, + "workaround": false, + "tracelinks": "StRS-31", + "konsolidierung": "nein", + "pruefidee": "Klärung mit Hersteller: Welche Daten werden erfasst, wohin übertragen, DSGVO-Bewertung; danach Codeverifikation der Übertragungsstrecke.", + "qm": "Wartbarkeit", + "uebernahme": "übernehmen - Produktverbesserung; Datenschutz im Zielsystem explizit regeln." + }, + { + "id": "SyRS-090", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Persönliche API-Zugriffstoken (M80)", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-14, SwRS-040", + "konsolidierung": "nein", + "pruefidee": "Ein deaktivierter Token wird mit \"Token ist deaktiviert.\" abgewiesen und der Versuch geloggt; der Klartext ist nach Erstellung nirgends mehr abrufbar.", + "qm": "", + "uebernahme": "übernehmen - moderne API-Sicherheit." + }, + { + "id": "SyRS-091", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Passwortmanager für Kundenzugangsdaten (M81)", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-13", + "konsolidierung": "nein", + "pruefidee": "Ein gespeichertes Passwort steht in der DB nicht im Klartext; der Abruf liefert es nur mit gültigem Benutzerkontext.", + "qm": "", + "uebernahme": "übernehmen - Servicealltag; Kryptoverfahren in Folgeanalyse prüfen." + }, + { + "id": "SyRS-092", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Kundenindividuelle Zusatztabellen (M82)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-01", + "konsolidierung": "nein", + "pruefidee": "Ein definiertes Zusatzfeld erscheint am Objekt und speichert Werte.", + "qm": "", + "uebernahme": "übernehmen - Anpassbarkeit; im Zielsystem als Custom-Fields-Konzept." + }, + { + "id": "SyRS-093", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Massenupdates auf Stammdaten und Belege (M83)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-01", + "konsolidierung": "nein", + "pruefidee": "Eine Vorlage ändert ein Feld auf allen Treffern; die Trefferliste entspricht dem Filter.", + "qm": "", + "uebernahme": "übernehmen - Administrationseffizienz." + }, + { + "id": "SyRS-094", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Benutzeroberflächen-Profile (M84)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-32", + "konsolidierung": "nein", + "pruefidee": "Ein gespeichertes Profil stellt nach Neuanmeldung dieselbe Spalten-/Layoutkonfiguration her.", + "qm": "", + "uebernahme": "Workaround - client-spezifische WPF-Layoutprofile; im Web-Zielsystem neu zu konzipieren." + }, + { + "id": "SyRS-095", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "E-Mail-Versand mit Vorlagen und Schutzmechanismen (M85)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-21, SwRS-059, SwRS-060", + "konsolidierung": "nein", + "pruefidee": "Eine Vorlage mit @@ProblemKurztext@@ wird beim Versand mit dem Ticketkurztext gefüllt; im DEBUG-Build erhält eine externe Adresse die Ersatzadresse.", + "qm": "", + "uebernahme": "übernehmen - Kommunikationsbasis." + }, + { + "id": "SyRS-096", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Exchange-Synchronisation (EWS) (M86)", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-21", + "konsolidierung": "nein", + "pruefidee": "Ein im ERP angelegter Termin erscheint im Exchange-Kalender des Benutzers.", + "qm": "", + "uebernahme": "übernehmen - Kalender-/Mailintegration; EWS-Ablösung (Graph) im Zielsystem beachten." + }, + { + "id": "SyRS-097", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "MailScanner: Postfachverarbeitung zu Tickets (M87)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-21, StRS-05", + "konsolidierung": "nein", + "pruefidee": "Eine Mail an das überwachte Postfach erzeugt gemäß Workflow ein Ticket mit Absenderzuordnung.", + "qm": "", + "uebernahme": "übernehmen - Eingangskanal Service." + }, + { + "id": "SyRS-098", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Telefonie-Integration (TAPI) (M88)", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-21", + "konsolidierung": "nein", + "pruefidee": "Ein eingehender Anruf mit bekannter Nummer liefert den Ansprechpartner des Kunden.", + "qm": "", + "uebernahme": "übernehmen - Anruferkennung; Technologie (TAPI) im Web-Zielsystem ersetzen." + }, + { + "id": "SyRS-099", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Mitarbeiterkalender mit Ticket-Terminen (M89)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-21, StRS-13", + "konsolidierung": "nein", + "pruefidee": "Ein Benutzer mit \"nur eigene\"-Recht sieht ausschließlich eigene Einträge.", + "qm": "", + "uebernahme": "übernehmen - Einsatzplanung." + }, + { + "id": "SyRS-100", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Interne Chats mit Objektbezug (M90)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-21", + "konsolidierung": "nein", + "pruefidee": "Ein zu Ticket T erstellter Chat erscheint in Ts Kontext; neue Mitglieder sehen den Verlauf.", + "qm": "", + "uebernahme": "übernehmen - interne Kommunikation." + }, + { + "id": "SyRS-101", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Outlook-Add-In (M91)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-21", + "konsolidierung": "nein", + "pruefidee": "Beim Öffnen einer Mail eines bekannten Kontakts zeigt das Add-In dessen Kunden mit Belegliste.", + "qm": "", + "uebernahme": "übernehmen - Mail-zentrierte Arbeitsweise." + }, + { + "id": "SyRS-102", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Benutzerbenachrichtigungen Client und Web (M92)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-21, StRS-17", + "konsolidierung": "nein", + "pruefidee": "Der Abschluss eines Tickets erzeugt beim Verantwortlichen eine Web-Benachrichtigung in Echtzeit.", + "qm": "", + "uebernahme": "übernehmen - Reaktionsgeschwindigkeit." + }, + { + "id": "SyRS-103", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "EDI-Verarbeitung von Distributorbelegen (M93)", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-08, SwRS-062", + "konsolidierung": "nein", + "pruefidee": "Eine ALSO-Auftragsbestätigung wird der Bestellung zugeordnet; der EDI-Log zeigt den Verarbeitungsstatus.", + "qm": "", + "uebernahme": "übernehmen - Belegautomatisierung." + }, + { + "id": "SyRS-104", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "E-Rechnung erzeugen (ZUGFeRD/XRechnung) (M94)", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-12, SwRS-061", + "konsolidierung": "nein", + "pruefidee": "Für eine Rechnung wird eine Datei erzeugt; für ein Angebot wird die Anforderung mit \"only 'InvoiceClass'\" abgewiesen.", + "qm": "", + "uebernahme": "übernehmen - gesetzliche Pflicht." + }, + { + "id": "SyRS-105", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "ebInterface-Unterstützung (Österreich) (M95)", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-12", + "konsolidierung": "nein", + "pruefidee": "Eine Rechnung an einen AT-Kunden lässt sich als ebInterface-Datei exportieren.", + "qm": "", + "uebernahme": "Sonderfall - nur für Österreich-Geschäft nötig." + }, + { + "id": "SyRS-106", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "docuFORM-Anbindung (M96)", + "typ": "Schnittstelle", + "belege": [ + "SEKUNDÄR", + "SEKUNDÄR" + ], + "status": "HYPOTHESE - Begründung: Nutzungspfad des Clients (Zählerimport) nicht im Code nachvollzogen.", + "hypothese": true, + "workaround": false, + "tracelinks": "StRS-04", + "konsolidierung": "nein", + "pruefidee": "Codepfad vom DocuFormRestApiClient zur Zählerübernahme in einer Folgeanalyse nachweisen.", + "qm": "", + "uebernahme": "übernehmen - sofern produktiv genutzt." + }, + { + "id": "SyRS-107", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Icecat-Produktdatenanreicherung (M97)", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-25", + "konsolidierung": "nein", + "pruefidee": "Zu einer EAN liefert der Abruf Beschreibung und Bild, die am Artikel gespeichert werden.", + "qm": "", + "uebernahme": "übernehmen - Datenqualität Artikel." + }, + { + "id": "SyRS-108", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "ITscope-Produkt- und Bestellanbindung (M98)", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-25", + "konsolidierung": "nein", + "pruefidee": "Die externe Suche liefert ITscope-Treffer mit Preis; die Übernahme erzeugt eine Position.", + "qm": "", + "uebernahme": "übernehmen - Marktdatenzugang." + }, + { + "id": "SyRS-109", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "COP-Datenzugriff (M99)", + "typ": "Schnittstelle", + "belege": [ + "SEKUNDÄR" + ], + "status": "HYPOTHESE - Begründung: Aufrufer/Zweck des COP-Clients nicht belegt.", + "hypothese": true, + "workaround": false, + "tracelinks": "StRS-25", + "konsolidierung": "nein", + "pruefidee": "Konsumentenpfad (Aufrufer von CopApi) in Folgeanalyse identifizieren.", + "qm": "", + "uebernahme": "übernehmen - sofern produktiv genutzt." + }, + { + "id": "SyRS-110", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "EGIS-Warenkorb und Bestellübertragung (M100)", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-08, StRS-25", + "konsolidierung": "nein", + "pruefidee": "Ein EGIS-Warenkorb wird übertragen und die Bestellbestätigung dem Vorgang zugeordnet.", + "qm": "", + "uebernahme": "übernehmen - Beschaffungsweg." + }, + { + "id": "SyRS-111", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Telekom-Dive-Schnittstelle (M101)", + "typ": "Schnittstelle", + "belege": [ + "SEKUNDÄR" + ], + "status": "HYPOTHESE - Begründung: Fachlicher Inhalt der Schnittstelle nicht analysiert.", + "hypothese": true, + "workaround": false, + "tracelinks": "StRS-25", + "konsolidierung": "nein", + "pruefidee": "Analyse der TelekomDiveBL-Methoden und der zugehörigen Views in einer Folgeiteration.", + "qm": "", + "uebernahme": "Sonderfall - nur für Telekom-Partner relevant." + }, + { + "id": "SyRS-112", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "TANSS-Datenübernahme (M102)", + "typ": "Schnittstelle", + "belege": [ + "SEKUNDÄR" + ], + "status": "HYPOTHESE - Begründung: Nutzungsart der Schnittstelle unbelegt.", + "hypothese": true, + "workaround": false, + "tracelinks": "StRS-05", + "konsolidierung": "nein", + "pruefidee": "Methodenanalyse TanssBL; Befragung, ob Migrations- oder Dauerschnittstelle.", + "qm": "", + "uebernahme": "Workaround - Migrationshilfe, im Zielsystem als Importwerkzeug neu bewerten." + }, + { + "id": "SyRS-113", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "GfK-Absatzmeldung (M103)", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-11", + "konsolidierung": "nein", + "pruefidee": "Der Export eines Zeitraums enthält die Verkaufsmengen der meldepflichtigen Artikel.", + "qm": "", + "uebernahme": "Sonderfall - nur für GfK-Panel-Teilnehmer." + }, + { + "id": "SyRS-114", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Spezialimporte (z. B. HP-Quote) (M104)", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-25", + "konsolidierung": "nein", + "pruefidee": "Der Import einer HP-Quote erzeugt die Positionen mit Preisen im Zielbeleg.", + "qm": "", + "uebernahme": "übernehmen - Herstellerprozesse." + }, + { + "id": "SyRS-115", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Konnektoren zu Drittsystemen (DocBee, c-time) (M105)", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-05, StRS-21", + "konsolidierung": "nein", + "pruefidee": "Eine in c-time erfasste Zeit erscheint nach dem Übertragungslauf am richtigen Ticket.", + "qm": "", + "uebernahme": "übernehmen - Ökosystemanbindung." + }, + { + "id": "SyRS-116", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "ReportEngine für Belegdrucke und Reports (M106)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-22", + "konsolidierung": "nein", + "pruefidee": "Der Rechnungsdruck verwendet die dem Belegtyp/Kunden zugeordnete Vorlage und füllt die Platzhalter.", + "qm": "", + "uebernahme": "übernehmen - Belegausgabe." + }, + { + "id": "SyRS-117", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Betriebswirtschaftliche Statistiken (M107)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-22", + "konsolidierung": "nein", + "pruefidee": "Die Umsatzstatistik eines Kunden entspricht der Summe seiner fakturierten Rechnungen im Zeitraum.", + "qm": "", + "uebernahme": "übernehmen - Steuerungsinformation." + }, + { + "id": "SyRS-118", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Volltext-Indexsuche (M108)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-01, StRS-05", + "konsolidierung": "nein", + "pruefidee": "Nach Änderung eines Kundennamens findet die Suche den neuen Namen nach dem Indexupdate.", + "qm": "", + "uebernahme": "übernehmen - Auffindbarkeit." + }, + { + "id": "SyRS-119", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Nexus-Webanwendung mit Cookie-Anmeldung (M109)", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-17, SwRS-067", + "konsolidierung": "nein", + "pruefidee": "Nach 12 Stunden ist die Web-Sitzung ungültig; HTTP-Aufrufe werden in Produktion auf HTTPS umgeleitet.", + "qm": "", + "uebernahme": "übernehmen - Web-Sicherheitsbasis." + }, + { + "id": "SyRS-120", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "ServiceBoard: Web-Arbeitsplatz für den Service (M110)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-05, StRS-17", + "konsolidierung": "nein", + "pruefidee": "Ein Ticket lässt sich im Kanban verschieben; eine Stoppuhrzeit landet als Zeiterfassung am Ticket.", + "qm": "", + "uebernahme": "übernehmen - Leitbild für das Web-Zielsystem." + }, + { + "id": "SyRS-121", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "WebCart: Kundenportal-Shop (M111)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-17, SwRS-043", + "konsolidierung": "nein", + "pruefidee": "Ein Web-Account ohne aktive Sonderpreise sieht einen leeren Shop; mit Sonderpreisen genau diese Artikel.", + "qm": "", + "uebernahme": "übernehmen - Kunden-Self-Service." + }, + { + "id": "SyRS-122", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "WebOffer: Online-Angebotsfreigabe (M112)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-18, SwRS-044", + "konsolidierung": "nein", + "pruefidee": "Erstes Öffnen setzt FirstLoaded; Annahme setzt AcceptFullWebReceipt; beide sind im Client sichtbar.", + "qm": "", + "uebernahme": "übernehmen - digitale Abschlussstrecke." + }, + { + "id": "SyRS-123", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Dokumentensignierung im Web (M113)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-18, StRS-05", + "konsolidierung": "nein", + "pruefidee": "Eine geleistete Unterschrift ist danach am Vorgang (z. B. Zeiterfassung) sichtbar.", + "qm": "", + "uebernahme": "übernehmen - papierloser Nachweis." + }, + { + "id": "SyRS-124", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Fertigungsaufträge im Web (M114)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-27, StRS-17", + "konsolidierung": "nein", + "pruefidee": "Ein Fertigungsauftrag ist im Web mit seinen Positionen sichtbar.", + "qm": "", + "uebernahme": "übernehmen - Webzugang Produktion." + }, + { + "id": "SyRS-125", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "SelfCare-Formulare (M115)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-17", + "konsolidierung": "nein", + "pruefidee": "Ein ausgefülltes Formular erzeugt einen Eintrag mit Status; der Bearbeiter kann den Status wechseln.", + "qm": "", + "uebernahme": "übernehmen - strukturierte Aufnahme." + }, + { + "id": "SyRS-126", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Web-Accounts mit eigenem Rechtesystem (M116)", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-17, StRS-13, SwRS-039, SwRS-042", + "konsolidierung": "nein", + "pruefidee": "Wird der Kunde gesperrt, schlägt der Web-Login fehl; ein Web-Recht steuert die Sichtbarkeit einer Portalfunktion.", + "qm": "", + "uebernahme": "übernehmen - Portalzugangsschutz; Hashverfahren modernisieren." + }, + { + "id": "SyRS-127", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Zentraler Webservice als Dienstschicht (M117)", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-14, StRS-17, SwRS-055, SwRS-068", + "konsolidierung": "nein", + "pruefidee": "Eine für Web-Accounts gesperrte Methode liefert für Web-Accounts \"You don't have the permission…\".", + "qm": "", + "uebernahme": "übernehmen - Architekturprinzip für das Zielsystem (API-first)." + }, + { + "id": "SyRS-128", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "ConnectionManager für Dienstverbindungen (M118)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-31", + "konsolidierung": "nein", + "pruefidee": "Der ConnectionManager zeigt die konfigurierten Verbindungen und die Hardware-ID an.", + "qm": "", + "uebernahme": "veraltet - On-Premise-Werkzeug; im SaaS-Zielsystem entfällt die lokale Verbindungspflege." + }, + { + "id": "SyRS-129", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "MyCentron: persönliche Startseite (M119)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-22", + "konsolidierung": "nein", + "pruefidee": "Ein zuletzt geöffnetes Ticket erscheint in der Liste der letzten Objekte.", + "qm": "", + "uebernahme": "übernehmen - Einstiegskomfort." + }, + { + "id": "SyRS-130", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "MyDay: Tagesansicht mit lizenzierten Importen (M120)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-15, StRS-05", + "konsolidierung": "nein", + "pruefidee": "Bei Lizenz-Count 3 lässt sich kein vierter Import konfigurieren.", + "qm": "", + "uebernahme": "übernehmen - Einsatzsteuerung." + }, + { + "id": "SyRS-131", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "KI-Funktionen (Chat, Ticket-Zusammenfassung, Kategorisierung) (M121)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-05", + "konsolidierung": "nein", + "pruefidee": "Die Ticket-Zusammenfassung liefert einen generierten Text zum Ticketverlauf.", + "qm": "", + "uebernahme": "übernehmen - Produktivitätsfunktion." + }, + { + "id": "SyRS-132", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "TradePool-Anbindung (M122)", + "typ": "Schnittstelle", + "belege": [ + "SEKUNDÄR" + ], + "status": "HYPOTHESE - Begründung: Zweck und Aktualität der Plattformanbindung unbelegt.", + "hypothese": true, + "workaround": false, + "tracelinks": "StRS-25", + "konsolidierung": "nein", + "pruefidee": "Klärung der Datenquelle und Nutzung; danach Verifikation des Importformats.", + "qm": "", + "uebernahme": "übernehmen - sofern Plattform noch aktiv; sonst veraltet." + }, + { + "id": "SyRS-133", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Gutschein-/Voucherverwaltung (M123)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-02", + "konsolidierung": "nein", + "pruefidee": "Ein eingelöster Voucher erscheint nur im Filter \"eingelöst\".", + "qm": "", + "uebernahme": "übernehmen - Gutscheingeschäft." + }, + { + "id": "SyRS-134", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Textbausteine (M124)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-02, StRS-21", + "konsolidierung": "nein", + "pruefidee": "Der für einen Kunden hinterlegte Rechnungstext erscheint in dessen neuer Rechnung.", + "qm": "", + "uebernahme": "übernehmen - Texteffizienz." + }, + { + "id": "SyRS-135", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Verschlagwortung mit Tags (M125)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-05", + "konsolidierung": "nein", + "pruefidee": "Ein an ein Ticket vergebenes Tag findet das Ticket über die Tagsuche.", + "qm": "", + "uebernahme": "übernehmen - flexible Klassifikation." + }, + { + "id": "SyRS-136", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Interner Social-Media-Stream (M126)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-21", + "konsolidierung": "nein", + "pruefidee": "Das Abonnieren eines Tickets zeigt dessen Ereignisse im eigenen Stream.", + "qm": "", + "uebernahme": "Workaround - interner Stream; im Zielsystem gegen Benachrichtigungen/Chat konsolidieren (siehe SyRS-100, SyRS-102)." + }, + { + "id": "SyRS-137", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Videoportal-Zuordnungen (M127)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-32", + "konsolidierung": "nein", + "pruefidee": "Eine Zuordnung macht das Video im Zielbereich sichtbar.", + "qm": "", + "uebernahme": "übernehmen - Hilfeangebot." + }, + { + "id": "SyRS-138", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Aktions-Weblinks (M128)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-21", + "konsolidierung": "nein", + "pruefidee": "Der Klick auf einen Link erzeugt den Klick-Datensatz und führt die hinterlegte Aktion aus.", + "qm": "", + "uebernahme": "übernehmen - Interaktionsautomatisierung." + }, + { + "id": "SyRS-139", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Mobile Unterstützung (M129)", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "HYPOTHESE - Begründung: Konsument und Umfang der Mobilschnittstelle unbelegt.", + "hypothese": true, + "workaround": false, + "tracelinks": "StRS-05", + "konsolidierung": "nein", + "pruefidee": "Klärung, welche Mobile App die Endpunkte konsumiert; danach Funktionsumfang erheben.", + "qm": "", + "uebernahme": "übernehmen - mobiler Zugriff gehört ins Web-Zielsystem (responsive)." + }, + { + "id": "SyRS-140", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Produktmatrix mit Kundenbewertungen (M130)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-20", + "konsolidierung": "nein", + "pruefidee": "Eine geänderte Kundenbewertung erzeugt einen Änderungslogeintrag.", + "qm": "", + "uebernahme": "übernehmen - Vertriebssteuerung." + }, + { + "id": "SyRS-141", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "ItPlanner-Checklistenkategorien (M131)", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "HYPOTHESE - Begründung: Nur eine Randklasse gefunden; Modulzweck unklar.", + "hypothese": true, + "workaround": false, + "tracelinks": "StRS-05", + "konsolidierung": "nein", + "pruefidee": "Klärung des ItPlanner-Funktionsumfangs (UI-Analyse) in Folgeiteration.", + "qm": "", + "uebernahme": "übernehmen - sofern produktiv genutzt." + }, + { + "id": "SyRS-142", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Erwartete Ereignisse (Wiedervorlagen) (M132)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-20", + "konsolidierung": "nein", + "pruefidee": "Ein erfasstes Ereignis erscheint in der Auswertung des Kunden mit Loghistorie.", + "qm": "", + "uebernahme": "übernehmen - proaktiver Vertrieb." + }, + { + "id": "SyRS-143", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "CPra-Webhook-Anbindung (M133)", + "typ": "Schnittstelle", + "belege": [ + "SEKUNDÄR" + ], + "status": "HYPOTHESE - Begründung: Zielsystem und fachlicher Zweck unbelegt.", + "hypothese": true, + "workaround": false, + "tracelinks": "StRS-25", + "konsolidierung": "nein", + "pruefidee": "Klärung, welches Produkt CPra ist und welche Prozesse die Webhooks auslösen.", + "qm": "", + "uebernahme": "übernehmen - sofern Partnerprodukt aktiv." + }, + { + "id": "SyRS-144", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "RiverSuite-/Divo-Anbindung mit Ticketerzeugung (M134)", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-05, StRS-14", + "konsolidierung": "nein", + "pruefidee": "Eine gültig authentifizierte RiverSuite-Anfrage erzeugt ein Ticket; eine ungültige wird abgewiesen.", + "qm": "", + "uebernahme": "übernehmen - Produktverbund des Herstellers." + }, + { + "id": "SyRS-145", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Länder- und Regionenstamm mit Währungen (M135)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-02", + "konsolidierung": "nein", + "pruefidee": "Eine Kursänderung am Land wirkt in der Fremdwährungspreisberechnung.", + "qm": "", + "uebernahme": "übernehmen - Basisstammdaten." + }, + { + "id": "SyRS-146", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Feiertagsdaten (M136)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-06, StRS-21", + "konsolidierung": "nein", + "pruefidee": "Ein Feiertag wird im Kalender als arbeitsfrei behandelt.", + "qm": "", + "uebernahme": "übernehmen - Terminlogik." + }, + { + "id": "SyRS-147", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Fremdwährungsbelege (M137)", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-02", + "konsolidierung": "nein", + "pruefidee": "Ein Beleg mit fixiertem Kurs behält seine Beträge bei späterer Kursänderung.", + "qm": "", + "uebernahme": "übernehmen - Auslandsgeschäft." + }, + { + "id": "SyRS-148", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Externe Objektreferenzen (M138)", + "typ": "Daten", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-25", + "konsolidierung": "nein", + "pruefidee": "Eine externe ID findet genau das verknüpfte interne Objekt.", + "qm": "", + "uebernahme": "übernehmen - Integrationsbasis." + }, + { + "id": "SyRS-149", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Prozess-/Workflow-Definitionen (M139)", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "HYPOTHESE - Begründung: Ausführungssemantik der Workflows unbelegt.", + "hypothese": true, + "workaround": false, + "tracelinks": "StRS-05, SyRS-097", + "konsolidierung": "nein", + "pruefidee": "Analyse der Workflow-Ausführung (Trigger, Engine) in Folgeiteration.", + "qm": "", + "uebernahme": "übernehmen - sofern produktiv; Umfang klären." + }, + { + "id": "SyRS-150", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Feldänderungsverfolgung (M140)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-24", + "konsolidierung": "nein", + "pruefidee": "Eine Kundenfeldänderung erzeugt einen ChangeLog-Eintrag mit Alt-/Neuwert.", + "qm": "", + "uebernahme": "übernehmen - Auditierbarkeit." + }, + { + "id": "SyRS-151", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "WPF-Client mit Recht+Lizenz-gesteuerter Modulfreischaltung (M141)", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-13, StRS-15, SwRS-056", + "konsolidierung": "nein", + "pruefidee": "Entzug des Moduls-Rechts entfernt das Modul aus der Navigation; Entzug der Lizenz ebenso.", + "qm": "", + "uebernahme": "übernehmen - Prinzip; Modulliste dient als Funktionsumfangs-Checkliste des Zielsystems." + }, + { + "id": "SyRS-152", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Wiederverwendbare UI-Komponenten (M142)", + "typ": "nicht-funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-32", + "konsolidierung": "nein", + "pruefidee": "Die Objektvorschau eines Kunden sieht in allen Modulen identisch aus.", + "qm": "Wartbarkeit", + "uebernahme": "Workaround - WPF-spezifisch; im Web-Zielsystem durch Designsystem ersetzen." + }, + { + "id": "SyRS-153", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Datenzugriff über NHibernate mit dualem Schema (M143)", + "typ": "Daten", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-02, SwRS-001, SwRS-006", + "konsolidierung": "nein", + "pruefidee": "Ein über die View geladenes Feld wird beim Speichern in der deutschen Tabelle persistiert.", + "qm": "", + "uebernahme": "Workaround - historisch gewachsener Doppelpfad; im Zielsystem ein einheitliches Schema." + }, + { + "id": "SyRS-154", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Gateway für Fremdformate (M144)", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-08, StRS-11", + "konsolidierung": "nein", + "pruefidee": "Ein neues Distributorformat erfordert nur eine neue Gateway-Komponente.", + "qm": "", + "uebernahme": "übernehmen - Architekturprinzip." + }, + { + "id": "SyRS-155", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Bereitstellung als Installer und Container (M145)", + "typ": "nicht-funktional", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-31", + "konsolidierung": "nein", + "pruefidee": "Das Docker-Image des Webservice startet und beantwortet CheckConnection.", + "qm": "Übertragbarkeit (Portability)", + "uebernahme": "übernehmen - Containerfähigkeit ist SaaS-Voraussetzung; WiX-Installer entfallen." + }, + { + "id": "SyRS-156", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Zweisprachige Oberfläche (DE/EN) (M146)", + "typ": "nicht-funktional", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-32, SwRS-058", + "konsolidierung": "nein", + "pruefidee": "Umschalten der Sprache ändert Menüs und Fehlermeldungen.", + "qm": "Benutzbarkeit (Usability)", + "uebernahme": "übernehmen - Grundanforderung." + }, + { + "id": "SwRS-001", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Duales Belegschema: deutsche Tabellen, englische Views", + "typ": "Daten", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-153", + "konsolidierung": "nein", + "pruefidee": "Jede Belegart besitzt Tabelle und View mit identischem Datenbestand.", + "qm": "", + "uebernahme": "Workaround - Übergangskonstruktion; Zielsystem mit einem Schema." + }, + { + "id": "SwRS-002", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Versionstabellen als exakte 1:1-Kopien", + "typ": "Daten", + "belege": [ + "SEKUNDÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-022", + "konsolidierung": "nein", + "pruefidee": "Nach Hinzufügen einer Spalte nur in der Ursprungstabelle schlägt das Versionieren fehl; nach Ergänzung in der Versionstabelle funktioniert es.", + "qm": "", + "uebernahme": "Workaround - fehleranfälliges Kopierschema; im Zielsystem generisches Auditverfahren." + }, + { + "id": "SwRS-003", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Gemeinsames Beleg-Logbuch AnlageLog mit Artencode", + "typ": "Daten", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-022, SyRS-006", + "konsolidierung": "nein", + "pruefidee": "Ein Rechnungsereignis erzeugt einen AnlageLog-Eintrag mit AnlageArt=4.", + "qm": "", + "uebernahme": "übernehmen - bewährtes Log-Muster." + }, + { + "id": "SwRS-004", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Belegstatus-Enum mit drei Zuständen", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-001, SyRS-005", + "konsolidierung": "nein", + "pruefidee": "Ein stornierter Beleg trägt Status 3 und wird in offenen Listen nicht mehr geführt.", + "qm": "", + "uebernahme": "übernehmen - klare Zustandssemantik." + }, + { + "id": "SwRS-005", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Optimistische Sperre über ConcurrencyControlGuid", + "typ": "nicht-funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-027", + "konsolidierung": "nein", + "pruefidee": "Speichern mit veraltetem Guid liefert ChangedByOtherInstance.", + "qm": "Zuverlässigkeit", + "uebernahme": "übernehmen - Standard-Nebenläufigkeitsschutz." + }, + { + "id": "SwRS-006", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Legacy-Speicherpfad über SaveReceipt-Repositories", + "typ": "Daten", + "belege": [ + "PRIMÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-153", + "konsolidierung": "nein", + "pruefidee": "Ein nur im Entity ergänztes Feld lädt korrekt, wird aber nicht gespeichert, bis das Repository erweitert ist.", + "qm": "", + "uebernahme": "Workaround - Fehlerquelle; im Zielsystem einheitliches ORM-Speichern." + }, + { + "id": "SwRS-007", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Vertragssonderpreise: fünf Preisarten mal zwei Änderungsarten", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-017, SyRS-009", + "konsolidierung": "nein", + "pruefidee": "Ein Vertragssonderpreis ChangeSellPrice/Percentage -10 erhöht den Rabatt um 10 %.", + "qm": "", + "uebernahme": "übernehmen - Regelwerk; Vorzeichenkonvention im Zielsystem begradigen." + }, + { + "id": "SwRS-008", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Kundensonderpreise: fünf Preisarten", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-019, SyRS-017", + "konsolidierung": "nein", + "pruefidee": "Ein Sonderpreis SurchargePurchasePrice +8 ergibt VK = EK * 1,08 (als negativer Rabatt abgebildet).", + "qm": "", + "uebernahme": "übernehmen - Preisvereinbarungslogik." + }, + { + "id": "SwRS-009", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Staffelpreise mit vier Preislisten und Konzernbezug", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-017", + "konsolidierung": "nein", + "pruefidee": "Ein Kunde mit Preisliste 2 erhält bei Staffelmenge den VK2 der Stufe.", + "qm": "", + "uebernahme": "übernehmen - Staffelkonditionen." + }, + { + "id": "SwRS-010", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "EK-Ermittlung mit Sonderabkommen, Lager-EK und Kursfaktor", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-017, SyRS-064", + "konsolidierung": "nein", + "pruefidee": "Ein Artikel mit Lager-EK 90 statt Artikel-EK 100 kalkuliert mit 90; mit EK-Reduktion 10 % mit 81.", + "qm": "", + "uebernahme": "übernehmen - Kalkulationsgrundlage." + }, + { + "id": "SwRS-011", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "EK-Fortschreibung bei Bestandsbuchung (gleitender Durchschnitt)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-064", + "konsolidierung": "nein", + "pruefidee": "Bestand 10@10 €, Zugang 10@8 € + 10 € Fracht: gleitender EK = (100+90)/20 = 9,50 €.", + "qm": "", + "uebernahme": "übernehmen - Bewertungslogik." + }, + { + "id": "SwRS-012", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Schweizer Rappenrundung über Steuerkorrektur", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-021", + "konsolidierung": "nein", + "pruefidee": "Netto 100,00, Steuer 8,10 → Brutto 108,10 (endet auf 0,05/0,10-Raster); Steuer trägt die Differenz.", + "qm": "", + "uebernahme": "Sonderfall - Schweizer Mandanten." + }, + { + "id": "SwRS-013", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Positionsberechnung mit Artikelpräzision und Skontosperre", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-017, SyRS-004", + "konsolidierung": "nein", + "pruefidee": "Ein skontogesperrter Artikel erhöht die nicht skontierfähige Summe; ein Artikel mit Präzision 4 rundet auf 4 Nachkommastellen.", + "qm": "", + "uebernahme": "übernehmen - Zahlungskonditionslogik." + }, + { + "id": "SwRS-014", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Kundenrabatt als automatische Position nach letztem Artikel", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-017", + "konsolidierung": "nein", + "pruefidee": "Nach Hinzufügen weiterer Artikel rückt die Rabattposition hinter den letzten Artikel.", + "qm": "", + "uebernahme": "übernehmen - Belegdarstellung." + }, + { + "id": "SwRS-015", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Kreditlimit: Netto/Brutto-Varianten und Bestandsrechnung", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-025", + "konsolidierung": "nein", + "pruefidee": "Ein Auftrag, der zur Rechnung wurde, zählt nicht doppelt; Kind=2 deaktiviert die Prüfung.", + "qm": "", + "uebernahme": "übernehmen - Kreditrisikologik." + }, + { + "id": "SwRS-016", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Stornoregeln der Rechnung (fünf Vorbedingungen, definierte Folgen)", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-005, SyRS-010, SyRS-011, SyRS-012", + "konsolidierung": "nein", + "pruefidee": "Storno der vorletzten Vertragsrechnung wird abgewiesen; Storno der letzten setzt Klickzähler zurück und gibt Timer frei.", + "qm": "", + "uebernahme": "übernehmen - Abrechnungsintegrität." + }, + { + "id": "SwRS-017", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Festschreibung als einmaliges, geloggtes DB-Flag", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-006", + "konsolidierung": "nein", + "pruefidee": "Zweiter Fix-Aufruf liefert die Warnung ohne zweiten Logeintrag.", + "qm": "", + "uebernahme": "übernehmen - GoBD-Mechanik." + }, + { + "id": "SwRS-018", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Anzahlungs-/Schlussrechnungsmechanik mit Textvariablen", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-013", + "konsolidierung": "nein", + "pruefidee": "Zwei Anzahlungen erscheinen in der Schlussrechnung als zwei Verrechnungspositionen mit variablengefüllten Texten.", + "qm": "", + "uebernahme": "übernehmen - Projektfakturierung." + }, + { + "id": "SwRS-019", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Intervallfortschreibung mit Monatsend- und Schaltjahrregeln", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-010", + "konsolidierung": "nein", + "pruefidee": "Monatsvertrag ab 31.01.: Folgeperioden enden 28./29.02., 31.03., 30.04.; Quartalsvertrag ab 15.02. endet erstmalig 31.03.", + "qm": "", + "uebernahme": "übernehmen - Kernkalenderlogik; im Zielsystem mit Testabdeckung neu implementieren." + }, + { + "id": "SwRS-020", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Anteilige Erstperioden-Normalisierung (Pro-rata)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-010", + "konsolidierung": "nein", + "pruefidee": "Monatsvertrag ab 16. eines 30-Tage-Monats: erster Intervallfaktor 0,5.", + "qm": "", + "uebernahme": "übernehmen - verursachungsgerechte Abrechnung." + }, + { + "id": "SwRS-021", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Voraus- vs. nachträgliche Berechnung (BillingKind)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-010", + "konsolidierung": "nein", + "pruefidee": "Ein Vorausvertrag mit Ende 15.03. berechnet die letzte Periode nur bis 15.03.", + "qm": "", + "uebernahme": "übernehmen - Abrechnungsarten." + }, + { + "id": "SwRS-022", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Kontingentbuchung mit Überbuchung, Restmitnahme und Zwischenrechnung", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-010, SyRS-011", + "konsolidierung": "nein", + "pruefidee": "Jahresvertrag mit Monatskontingent ohne Überbuchung: 12 Zwischenbuchungen; mit Wechsel der Kontingentart entfällt die Restmitnahme.", + "qm": "", + "uebernahme": "übernehmen - komplexeste Abrechnungsregel; im Zielsystem mit Testfällen absichern." + }, + { + "id": "SwRS-023", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Beleg-Log für Kontingentfeldänderungen", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-009, SyRS-022", + "konsolidierung": "nein", + "pruefidee": "Die Änderung des Kontingentwerts erzeugt genau einen Logeintrag mit beiden Werten.", + "qm": "", + "uebernahme": "übernehmen - Nachvollziehbarkeit." + }, + { + "id": "SwRS-024", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Klickzähler-Historie je Rechnungsposition", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-011, SwRS-016", + "konsolidierung": "nein", + "pruefidee": "Nach Abrechnung trägt die Zählerhistorie die RechPos-Referenz; nach Storno ist sie leer.", + "qm": "", + "uebernahme": "übernehmen - Einmalabrechnung." + }, + { + "id": "SwRS-025", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Nummernvergabe: Compare-and-Swap plus Kollisionsprüfung", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-023", + "konsolidierung": "nein", + "pruefidee": "Simulierte parallele Vergabe liefert disjunkte Nummern; eine manuell belegte Nummer wird übersprungen.", + "qm": "", + "uebernahme": "übernehmen - Vergabesicherheit; Hinweis: keine Lückenlosigkeitsgarantie (übersprungene Nummern), im Zielsystem bewerten." + }, + { + "id": "SwRS-026", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "SEPA-Formatvarianten und Mandatssequenz-Fortschreibung", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-073, SyRS-077", + "konsolidierung": "nein", + "pruefidee": "Nach dem ersten Einzug steht die Bankverbindung auf Recurrent; ValidTo liegt 2 Jahre in der Zukunft.", + "qm": "", + "uebernahme": "übernehmen - SEPA-Compliance; Formatliste aktualisieren." + }, + { + "id": "SwRS-027", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "SEPA-Exportfolgen und Rücknahme im Detail", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-073, SyRS-071", + "konsolidierung": "nein", + "pruefidee": "Rücknahme einer exportgeschlossenen Rechnung öffnet sie, PayedAmount sinkt um den Logbetrag, ein Logeintrag mit Benutzerkürzel entsteht.", + "qm": "", + "uebernahme": "übernehmen - Zahlungsintegrität." + }, + { + "id": "SwRS-028", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Onlinebanking-Zuordnung: Rechnungsnummern-Regex aus Nummernkreis", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-072", + "konsolidierung": "nein", + "pruefidee": "Bei Nummernkreis 10000-99999 erkennt der Regex genau 5-stellige Zahlen im Verwendungszweck.", + "qm": "", + "uebernahme": "übernehmen - Zuordnungsqualität." + }, + { + "id": "SwRS-029", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "DATEV-ASCII-Export im Format EXTF 700", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-076", + "konsolidierung": "nein", + "pruefidee": "Die Exportdatei beginnt mit \"EXTF\";700 und heißt EXTF_*.csv.", + "qm": "", + "uebernahme": "übernehmen - DATEV-Konformität." + }, + { + "id": "SwRS-030", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Mahnstufenmodell und zweistufige Mahnsperren", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-074", + "konsolidierung": "nein", + "pruefidee": "Kunde gesperrt → keine seiner Rechnungen im Lauf; nur Rechnung gesperrt → übrige Rechnungen des Kunden erscheinen.", + "qm": "", + "uebernahme": "übernehmen - Mahnsteuerung." + }, + { + "id": "SwRS-031", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Zahlungseingangs-Löschung mit Belegrückrechnung", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-071", + "konsolidierung": "nein", + "pruefidee": "Löschen zweier Zahlungen (60+40) einer Fremdwährungsrechnung reduziert PaidFC um 100×Kursfaktor.", + "qm": "", + "uebernahme": "übernehmen - Saldenkonsistenz." + }, + { + "id": "SwRS-032", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Passwortspeicherung als ungesalzenes SHA1 (Ist-Zustand)", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-078, SyRS-126", + "konsolidierung": "nein", + "pruefidee": "Der gespeicherte Hash zweier Benutzer mit gleichem Passwort ist identisch (Beleg für fehlendes Salt); im Zielsystem müssen identische Passwörter verschiedene Hashes ergeben.", + "qm": "", + "uebernahme": "veraltet - kryptografisch überholtes Verfahren; funktional (Passwortlogin) übernehmen, technisch ersetzen." + }, + { + "id": "SwRS-033", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Dreifache Kontodeaktivierungslogik", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-079", + "konsolidierung": "nein", + "pruefidee": "Konto mit nur Von-Datum in der Vergangenheit bleibt dauerhaft gesperrt; Logeintrag nennt das Datum.", + "qm": "", + "uebernahme": "übernehmen - Offboarding-Regeln." + }, + { + "id": "SwRS-034", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Sitzungsticket-Lebensdauern und -verlängerung", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-078", + "konsolidierung": "nein", + "pruefidee": "Nach 31 Minuten Inaktivität ist der Aufruf abgewiesen; regelmäßige Aufrufe halten das Ticket gültig.", + "qm": "", + "uebernahme": "übernehmen - Sitzungsökonomie." + }, + { + "id": "SwRS-035", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Floating-Lizenzzählung über aktive Tickets", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-082", + "konsolidierung": "nein", + "pruefidee": "Wiederholter Login desselben Benutzers auf derselben Maschine verbraucht keine zweite Lizenz.", + "qm": "", + "uebernahme": "übernehmen - Zähllogik; Delphi-Ausnahme ist Workaround und entfällt." + }, + { + "id": "SwRS-036", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Anwendungsbezogene Pflicht- und Verbotsrechte beim Login", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-078, SyRS-080", + "konsolidierung": "nein", + "pruefidee": "Ein Benutzer mit gesetztem Verbotsrecht der Anwendung X erhält für X kein Ticket, für Y schon.", + "qm": "", + "uebernahme": "übernehmen - differenzierter Anwendungszugang." + }, + { + "id": "SwRS-037", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "2FA-Parametrik: Gültigkeitsdauer, Geräteerinnerung, Validatoren", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-081", + "konsolidierung": "nein", + "pruefidee": "Wechsel der Maschine erzwingt erneute 2FA trotz laufender Gültigkeitsdauer.", + "qm": "", + "uebernahme": "übernehmen - 2FA-Regelwerk; TOTP/Passkeys im Zielsystem ergänzen." + }, + { + "id": "SwRS-038", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Rechte-Datenmodell: Sichbenu/Sichmemb/Sichtrus mit additiven Gruppen", + "typ": "Daten", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-080", + "konsolidierung": "nein", + "pruefidee": "Ein Recht in irgendeiner Gruppe des Benutzers genügt; der Entzug in einer von zwei Gruppen entzieht das Recht nicht.", + "qm": "", + "uebernahme": "übernehmen - Modell; einschränkende Rechte (siehe SyRS-058) im Zielsystem als explizites Konzept." + }, + { + "id": "SwRS-039", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Getrenntes Web-Rechtesystem für Web-Accounts", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-126", + "konsolidierung": "nein", + "pruefidee": "Ein Web-Recht schaltet nur Portalfunktionen; interne Rechte des Kontakts existieren nicht.", + "qm": "", + "uebernahme": "übernehmen - saubere Trennung intern/extern." + }, + { + "id": "SwRS-040", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "API-Token: CSPRNG-Erzeugung, SHA-256-Hash, Einmalanzeige", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-090", + "konsolidierung": "nein", + "pruefidee": "In der DB existiert nur ein 64-Zeichen-Hexhash; der Klartext ist nach der Erstellung nicht mehr abrufbar.", + "qm": "", + "uebernahme": "übernehmen - Vorbild für die Passwort-Ablösung (SwRS-032)." + }, + { + "id": "SwRS-041", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Passwortregeln: Mindestlänge je Benutzer, Wechselsperren, Änderungsdatum", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-078", + "konsolidierung": "nein", + "pruefidee": "Ein Entra-ID-Benutzer erhält beim Passwortwechsel die Ablehnung \"für Benutzer mit externer Anmeldung … nicht geändert\".", + "qm": "", + "uebernahme": "übernehmen - Passwortrichtlinie; im Zielsystem um Komplexitätsregeln erweitern." + }, + { + "id": "SwRS-042", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Web-Login: durchgehend aktive Beziehungskette", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-126", + "konsolidierung": "nein", + "pruefidee": "Deaktivieren nur der Adresse verhindert den Login; Reaktivieren stellt ihn wieder her.", + "qm": "", + "uebernahme": "übernehmen - Portalzugangslogik." + }, + { + "id": "SwRS-043", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "WebCart-Sortimentsregel: nur Artikel mit aktiven Sonderpreisen", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-121", + "konsolidierung": "nein", + "pruefidee": "Ein manipulierter Request mit fremder Kundennummer liefert dennoch nur das eigene Sortiment.", + "qm": "", + "uebernahme": "übernehmen - Mandantenisolation im Portal." + }, + { + "id": "SwRS-044", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "WebReceipt-Zustandsautomat der Online-Freigabe", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-122", + "konsolidierung": "nein", + "pruefidee": "Jede Kundenaktion im WebOffer führt in genau einen der neun Zustände.", + "qm": "", + "uebernahme": "übernehmen - Freigabesemantik." + }, + { + "id": "SwRS-045", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Barcode-Zustandsautomat (20 Zustände)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-067", + "konsolidierung": "nein", + "pruefidee": "Zuweisung zu einem Lieferschein setzt AssignedToDeliveryList; dessen Buchung setzt InDeliveryList.", + "qm": "", + "uebernahme": "übernehmen - Lebenszyklusmodell." + }, + { + "id": "SwRS-046", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "ScanBarcode-Regel: Barcodes steuern den Bestand nur wenn aktiv", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-064, SyRS-067", + "konsolidierung": "nein", + "pruefidee": "Barcode-Zugang auf einem Artikel ohne ScanBarcode ändert den Bestand nicht.", + "qm": "", + "uebernahme": "übernehmen - Datenqualität Bestand." + }, + { + "id": "SwRS-047", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Ticket-Pflichtfeldkaskade und Sondertickets", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-046", + "konsolidierung": "nein", + "pruefidee": "Fehlende Priorität und Kategorie erscheinen gemeinsam in einer Fehlermeldung.", + "qm": "", + "uebernahme": "übernehmen - Erfassungsführung." + }, + { + "id": "SwRS-048", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Ticketabschluss-Transaktionsfolge", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-047", + "konsolidierung": "nein", + "pruefidee": "Scheitert das Speichern, existieren weder Historieneintrag noch Aktivität.", + "qm": "", + "uebernahme": "übernehmen - Prozesskonsistenz." + }, + { + "id": "SwRS-049", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Eskalationsstufenberechnung mit Arbeitszeitfenstern", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-048", + "konsolidierung": "nein", + "pruefidee": "Wartezeit 8h bei Arbeitszeit 8-16 Uhr eskaliert am Folgearbeitstag, nicht nach 8 Kalenderstunden.", + "qm": "", + "uebernahme": "übernehmen - SLA-Berechnung." + }, + { + "id": "SwRS-050", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "RMA-Eindeutigkeit per Unique Clustered Index", + "typ": "Daten", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-054", + "konsolidierung": "nein", + "pruefidee": "Zweite RMA zum selben Ticket → Unique-Index-Verletzung.", + "qm": "", + "uebernahme": "übernehmen - Datenintegrität." + }, + { + "id": "SwRS-051", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Eindeutigkeit der Kunden-/Lieferantennummern auf DB-Ebene", + "typ": "Daten", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-036, SyRS-035, SyRS-023", + "konsolidierung": "nein", + "pruefidee": "Insert mit vorhandener Nummer schlägt fehl; die Vergabe überspringt Alt-Nummern.", + "qm": "", + "uebernahme": "übernehmen - Stammdatenintegrität." + }, + { + "id": "SwRS-052", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "DSGVO-Selektionskategorien der Bereinigung", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-086", + "konsolidierung": "nein", + "pruefidee": "Die Statistik \"CRM älter als X\" entspricht COUNT(*) aus Taetigkeiten mit Datum Dieser Prompt enthält ausschließlich die **Analyseanweisung** und ist damit unabhängig von einem +> bestimmten Werkzeug oder Modell einsetzbar. Welche Werkzeuge im jeweiligen Lauf zur Verfügung +> stehen und wohin die Ergebnisse geschrieben werden, stellt der Versuchsaufbau beim Start bei. + +--- + +## Prompt + +Du bist ein Requirements Engineer im Reverse Requirements Engineering eines Legacy-ERP-Systems. Erzeuge aus der vorliegenden Codebasis eine Anforderungsspezifikation nach **ISO/IEC/IEEE 29148:2018**. Arbeite ausschließlich auf den im Arbeitsverzeichnis liegenden Artefakten (Quellcode, Konfiguration, UI-Ressourcen, ggf. DB-Skripte). Nutze nur Informationen, die du aus diesen Artefakten gewinnen kannst. + +### Auftrag + +Erzeuge eine konsolidierte Spezifikation auf den drei Ebenen: + +1. **StRS** - Stakeholder Requirements Specification (fachliche Sicht, Akteure, Geschäftsziele) +2. **SyRS** - System Requirements Specification (Systemverhalten, Schnittstellen, Performance-, Sicherheitsanforderungen) +3. **SwRS** - Software Requirements Specification (Komponenten, Datenmodelle, Software-interne Regeln) + +Ziel ist eine Spezifikation, die als belastbare Basis für eine Web-/SaaS-Neuimplementierung dienen kann. + +### Scope (Schritt 1 der RRE-Methodenkette, manuell vorgegeben) + +Der Untersuchungsgegenstand ist die **gesamte Codebasis** im Arbeitsverzeichnis. Es gilt bewusst keine Modulbeschränkung: Alle Module, Datenobjekte und Prozesse sind gleichrangig zu erfassen. + +**Breite geht vor Tiefe.** Ein fehlendes Requirement führt bei einer Neuimplementierung zu Funktionsverlust; eine oberflächlich erfasste Funktion lässt sich dagegen nachschärfen. Erfasse deshalb zuerst die gesamte Breite und vertiefe erst danach. Halte dich an die Reihenfolge aus dem Abschnitt **Vorgehen**: erst Inventar, dann Mindestabdeckung, dann Vertiefung. + +### Vorgehen (statische Analyse, keine Ausführung) + +Bearbeite die Schritte 2-6 der RRE-Methodenkette (Schritt 1 Scope ist oben vorgegeben, Schritt 7 Validierung erfolgt manuell durch Fachexperten). Vorgeschaltet ist eine verbindliche Inventarisierung: + +**Schritt 0 - Modulinventar (vor der ersten Anforderung).** Verschaffe dir zuerst einen vollständigen Überblick über den Untersuchungsgegenstand und lege ihn im `Analysebericht.md` als Tabelle ab: fachliches Modul beziehungsweise Komponente, Pfad im Arbeitsverzeichnis, ein Satz zur fachlichen Aufgabe. Das Inventar wird erstellt, **bevor** die erste Anforderung formuliert wird. Es ist die Bezugsgröße für die Abdeckung und darf später ergänzt, aber nicht gekürzt werden. + +**Schritt 0b - Mindestabdeckung.** Jedes Modul des Inventars erhält **mindestens eine** Anforderung, bevor irgendein Modul vertieft wird. Lässt sich für ein Modul keine belegbare Anforderung bilden, führe es im Inventar als `nicht analysiert` mit einer kurzen Begründung. Ein Modul ohne Anforderung und ohne Begründung ist unzulässig. + +**Schritt 0c - Vertiefung nach Risiko.** Erst wenn die Mindestabdeckung steht, vertiefe einzelne Module. Beginne dort, wo Sicherheitsregeln, Abrechnungs- und Fakturierungslogik oder Berechtigungsprüfungen liegen. + +2. **Artefakterhebung:** Erfasse Quellcode, Konfiguration, UI-Texte, Datenbankschemata, Schnittstellenbeschreibungen sowie Change-Historie und Projektartefakte (Commit-Messages, Tickets, Release Notes, Migrationsnotizen), soweit als Datei lesbar. +3. **Technische Analyse:** Identifiziere Module, Komponenten, Abhängigkeiten, Statusmaschinen, Validierungslogik, Berechtigungsprüfungen. +4. **Semantische Interpretation:** Leite fachliche Aussagen aus technischen Implementierungen ab (z. B. Statusübergänge → Geschäftsregel). +5. **Formalisierung:** Überführe die Aussagen in klare, testbare Anforderungen mit Kontext, Vorbedingung und Ergebnis. +6. **Traceability-Anreicherung:** Verknüpfe jede Anforderung mit konkreten Artefaktbelegen. + +### Pflicht-Eigenschaften jeder Anforderung + +- **Belegpflicht:** Jede Anforderung **muss** mindestens einen konkreten Artefaktbeleg führen (Dateipfad, Klasse/Methode, SQL-Statement, UI-String, Konfigurationseintrag). Jeder Beleg erhält eine kurze Begründung, warum er die Aussage trägt. Lässt sich eine Aussage nicht belegen, **schreibe die Anforderung nicht** - erfasse den offenen Punkt stattdessen als Hypothese. Eine Anforderung ohne Beleg ist unter keinen Umständen zulässig. +- **Trennung von Fakt und Interpretation:** Die belegte technische Beobachtung (Feld `Fakt`) wird getrennt von der fachlichen Interpretation (Feld `Aussage`) dokumentiert, damit nachvollziehbar bleibt, was im Artefakt steht und was daraus geschlossen wurde. +- **Risikobasierte Priorisierung:** Anforderungen zu Sicherheitsregeln, Abrechnungs-/Fakturierungslogik und Berechtigungen unterliegen strengeren Evidenzanforderungen: Sie benötigen mindestens einen `PRIMÄR`-Beleg, andernfalls sind sie zwingend als `[HYPOTHESE]` zu kennzeichnen. Ein `PRIMÄR`-Beleg benennt hier die **durchsetzende Stelle** - Datei, Klasse, Methode und die konkrete Prüfung, Bedingung oder das Constraint. Ein Verweis auf eine Datei ohne Angabe der prüfenden Stelle genügt für diese Anforderungen nicht. +- **Belegklassifikation:** Kennzeichne jeden Beleg als + - `PRIMÄR` (durchgesetzte Regel im Code oder DB-Constraint), + - `SEKUNDÄR` (UI-Label, Fehlermeldung, Reportlayout, Mappingtabelle, Konfigurationsschalter), + - `KONTEXT` (Kommentar, Commit-Message, Ticketreferenz). +- **Hypothesenmarkierung:** Aussagen, die sich nicht eindeutig aus Artefakten ableiten lassen, kennzeichnest du explizit mit `[HYPOTHESE]` und einer kurzen Begründung, welche Information zur Bestätigung fehlt. Bei einer Codebasis dieser Größe ist eine Analyse ohne jeden offenen Punkt unplausibel: Führst du keine einzige Hypothese, begründe das ausdrücklich in der Selbstbewertung. Umgekehrt ist eine hohe Hypothesenzahl kein Mangel, sondern ein Hinweis auf ehrliche Abgrenzung. +- **Verifizierbarkeit:** Jede Anforderung enthält mindestens eine Prüfidee oder ein Akzeptanzkriterium. +- **Eindeutigkeit:** Vermeide vage Begriffe ("schnell", "benutzerfreundlich"); definiere domänenspezifische Begriffe beim ersten Auftreten. +- **Übernahmewürdigkeit:** Beurteile für jede Anforderung, ob ihre Funktion im Zielsystem erhalten bleiben soll. Unterscheide `übernehmen` (fachlich weiterhin erforderlich), `Workaround` (historisch gewachsene Behelfslösung), `Sonderfall` (Ausnahme für einen einzelnen Kunden, Mandanten oder Altbestand) und `veraltet` (durch neuere Logik abgelöst oder fachlich überholt). Begründe die Einstufung in einem Halbsatz. Diese Angabe steuert die spätere fachliche Priorisierung; eine Fehleinschätzung ist unkritisch, eine fehlende Angabe nicht. +- **Redundanzfreiheit:** Formuliere jede Anforderung so, dass sie von den übrigen klar abgegrenzt ist. Beschreiben zwei Anforderungen dieselbe fachliche Funktion aus unterschiedlicher Perspektive, führe sie zusammen oder grenze sie im Titel und in der Aussage ausdrücklich gegeneinander ab. + +### Formatvorgabe pro Anforderung + +``` +ID: - +Titel: +Ebene: +Typ: +Qualitätsmerkmal: +Akteur: +Vorbedingung: +Fakt: +Aussage: Das System soll <...>. (fachliche Interpretation als klare Soll-Aussage) +Ergebnis: +Belege: + - [PRIMÄR] - Begründung: + - [SEKUNDÄR] <...> - Begründung: <...> + - [KONTEXT] <...> - Begründung: <...> +Prüfidee: +Tracelinks: +Konsolidierung: > +Übernahmewürdigkeit: <übernehmen | Workaround | Sonderfall | veraltet> - +Status: +``` + +### Traceability + +Stelle Forward- und Backward-Traceability zwischen den drei Ebenen her: +- Jede SwRS-Anforderung referenziert die zugehörige SyRS-Anforderung. +- Jede SyRS-Anforderung referenziert die zugehörige StRS-Anforderung. +- Erzeuge zusätzlich eine konsolidierte **Traceability-Tabelle** (Markdown oder CSV): `StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg`. + +### Nicht-funktionale Anforderungen + +- Ordne nicht-funktionale Anforderungen den Qualitätsmerkmalen der **ISO/IEC 25010** zu (z. B. Zuverlässigkeit, Performance-Effizienz, Sicherheit, Wartbarkeit, Übertragbarkeit). Trage die Zuordnung in das dafür vorgesehene Feld `Qualitätsmerkmal` ein, nicht in das Feld `Typ`. +- Leite Betriebs- und Sicherheitsanforderungen gezielt auch aus indirekt sichtbaren Artefakten ab: Konfigurationen, Deployment-Skripte, Logging-Policies, Rechteprüfungen. + +### Konsolidierungsbedarf + +Die Codebasis enthält fachliche Redundanz: Dieselbe Anforderung kann auf unterschiedlichen Masken oder in unterschiedlichen Modulen mehrfach und teils unterschiedlich implementiert sein. Prüfe daher bei jeder Anforderung, ob andere Anforderungen dieselbe fachliche Funktion abbilden, und vermerke solche Fälle im Feld `Konsolidierung` als Kandidat für eine Zusammenführung im Zielsystem. + +**Gemeint sind fachlich gleichartige Konzepte in getrennten Implementierungen**, nicht bloß ähnlich formulierte Anforderungen. Ein Beispiel aus dieser Codebasis: Drucker werden als „Stammblätter" geführt, sonstige Hardware getrennt davon als „Assets" - zwei Datenhaltungen für denselben fachlichen Gegenstand, die im Zielsystem zu einem Asset-Konzept zusammengeführt werden sollen. Zwei Anforderungen, die denselben Sachverhalt nur aus Sicht verschiedener Ebenen beschreiben (etwa StRS und SwRS), sind **kein** Konsolidierungsfall - dafür sind die Tracelinks da. + +### Ergebnisstruktur (im vorgegebenen Ausgabeverzeichnis) + +``` +Ergebnisse/ + StRS.md + SyRS.md + SwRS.md + Traceability.md (oder Traceability.csv) + Hypothesen.md (Sammlung aller mit [HYPOTHESE] markierten Aussagen mit offener Frage) + Glossar.md (Domänenbegriffe, die in den Anforderungen verwendet werden) + Analysebericht.md (Modulinventar aus Schritt 0, Abdeckungstabelle, Konsistenzcheck, + Selbstbewertung, bekannte Lücken) +``` + +Das Ausgabeverzeichnis wird beim Start des Laufs beigestellt. Die analysierte Codebasis wird ausschließlich gelesen und nicht verändert. + +### Randbedingungen + +- **Keine Halluzinationen.** Wenn ein Artefakt nicht gelesen oder eine Aussage nicht belegt werden kann, ist das offen zu legen, nicht zu erfinden. +- **Keine Generierung von Code.** Es sollen ausschließlich Spezifikationsartefakte entstehen. +- **Keine Annahme über nicht beigestellte Hilfsmittel.** Arbeite mit dem, was dir in diesem Lauf zur Verfügung steht. Setze keine zusätzlichen Analysewerkzeuge, Datenbankzugriffe oder laufende Systeme voraus. Stehen für eine Aussage nur indirekte Belege zur Verfügung, ist sie als `[HYPOTHESE]` zu kennzeichnen. +- **Migrationsperspektive berücksichtigen.** Erkennbare Workarounds, Sonderfälle und überholte Logik gehören in das Feld `Übernahmewürdigkeit`, nicht in das Feld `Status`. `Status` beschreibt ausschließlich die Belegsituation (`belegt` oder `HYPOTHESE`), `Übernahmewürdigkeit` die fachliche Zukunft der Anforderung. Beide Angaben sind unabhängig voneinander: Eine gut belegte Anforderung kann ein Workaround sein, eine Hypothese kann übernahmewürdig sein. +- **Sprache:** Deutsch für Anforderungsaussagen, technische Bezeichner (Klassen, Methoden, Spalten) bleiben in ihrer Originalsprache. + +### Abschluss + +Führe vor Abgabe einen **Konsistenzcheck über das gesamte Anforderungs-Set** durch und dokumentiere das Ergebnis im `Analysebericht.md`: +- Doppelte oder mehrfach vergebene IDs +- Anforderungen ohne Beleg +- Anforderungen ohne Angabe zur `Übernahmewürdigkeit` +- Tracelinks auf nicht existierende IDs +- Inhaltlich deckungsgleiche Anforderungen, die nicht als Konsolidierungskandidat markiert sind +- **Liste aller risikorelevanten Anforderungen** (Sicherheit, Abrechnung/Fakturierung, Berechtigungen) mit ihrer Belegsituation: ID, Titel, ob ein `PRIMÄR`-Beleg vorliegt, andernfalls die `[HYPOTHESE]`-Kennzeichnung. Diese Liste macht Verstöße gegen die risikobasierte Priorisierung im Lauf selbst sichtbar. +- **Abgleich `Hypothesen.md` gegen die Inline-Markierungen:** Beide müssen dieselben Anforderungen nennen. `Hypothesen.md` enthält genau die Anforderungen mit `[HYPOTHESE]`-Markierung und keine zusätzlichen freien Fragen; offene Punkte ohne zugehörige Anforderung gehören in die Selbstbewertung. + +Erstelle außerdem die **Abdeckungstabelle** auf Basis des Modulinventars aus Schritt 0: je Modul die Einstufung `tief | mittel | flach | nicht analysiert` und die Anzahl der daraus erzeugten Anforderungen. Jede Zeile des Inventars muss in der Abdeckungstabelle auftauchen. + +Beende den Lauf mit einer kurzen Selbstbewertung im `Analysebericht.md`: +- Wie viele Module des Inventars wurden tief, mittel, flach beziehungsweise gar nicht analysiert? Nenne absolute Zahlen, nicht nur Beispiele. +- Wurde die Mindestabdeckung erreicht, also hat jedes Modul mindestens eine Anforderung? Falls nein: welche Module fehlen und warum? +- An welchen Stellen war der Beleg dünn (hoher Anteil `SEKUNDÄR`/`KONTEXT` oder `[HYPOTHESE]`)? +- Falls keine einzige Hypothese geführt wurde: Begründung, warum die Analyse ohne offene Punkte auskommt. +- Welche Erkenntnisse legen einen Nachschlag in einer Folge-Iteration nahe? + +--- + +### Werkzeugkontext (vom Versuchsaufbau vorgegeben) +Für diesen Lauf stehen zur Verfügung: Lesen und Suchen von Dateien sowie das Ausführen von +Kommandozeilenbefehlen im Arbeitsverzeichnis. +Nicht verfügbar sind: Subagenten, spezialisierte Agentenrollen, externe Werkzeugserver. +Triff keine Annahmen über weitere Werkzeuge und versuche nicht, nicht verfügbare +Werkzeuge zu ersetzen. +### Ausgabeverzeichnis (überschreibt anderslautende Pfadangaben oben) +Schreibe ALLE zu erzeugenden Ergebnisdateien in das Verzeichnis +`c:\DEV\MasterArbeit\Versuche\Versuch_01\Iteration 3\claude-fable-5\solo\max\02_Lauf_2026-08-27_081235_v7.0.0-3021\Ergebnisse\`. +Verändere keine Dateien im Arbeitsverzeichnis (der analysierten Codebasis). diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/_meta/endzeit.txt b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/_meta/endzeit.txt new file mode 100644 index 00000000..eb8d3d70 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/_meta/endzeit.txt @@ -0,0 +1 @@ +2026-08-27T09:12:14.8158828+02:00 diff --git a/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/_meta/startzeit.txt b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/_meta/startzeit.txt new file mode 100644 index 00000000..0d5e7868 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-fable-5/solo/max/02_Lauf_2026-08-27_081235_v7.0.0-3021/_meta/startzeit.txt @@ -0,0 +1 @@ +2026-08-27T08:12:35.5152425+02:00 diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_110958_v7.0.0-7499/RawResult.json b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_110958_v7.0.0-7499/RawResult.json new file mode 100644 index 00000000..40f2374e --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_110958_v7.0.0-7499/RawResult.json @@ -0,0 +1 @@ +{"is_error":true,"duration_api_ms":6921934,"num_turns":39,"stop_reason":"stop_sequence","session_id":"8d493a0f-f069-46a0-93de-8427787b311e","total_cost_usd":19.8662592,"usage":{"input_tokens":28,"cache_creation_input_tokens":110625,"cache_read_input_tokens":960495,"output_tokens":65463,"output_tokens_details":{"thinking_tokens":37220},"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":110625,"ephemeral_5m_input_tokens":0},"inference_geo":"not_available","iterations":[{"input_tokens":2,"output_tokens":31750,"cache_read_input_tokens":106780,"cache_creation_input_tokens":3845,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":3845},"type":"message"}],"speed":"standard"},"modelUsage":{"claude-haiku-4-5-20251001":{"inputTokens":6961,"outputTokens":24,"cacheReadInputTokens":0,"cacheCreationInputTokens":0,"webSearchRequests":0,"costUSD":0.0070810000000000005,"contextWindow":200000,"maxOutputTokens":32000,"canonicalModel":"claude-haiku-4-5","provider":"firstParty","costBasis":"list"},"claude-sonnet-5":{"inputTokens":548,"outputTokens":710526,"cacheReadInputTokens":40508211,"cacheCreationInputTokens":1794097,"webSearchRequests":0,"costUSD":19.8591782,"contextWindow":1000000,"maxOutputTokens":64000,"canonicalModel":"claude-sonnet-5","provider":"firstParty","costBasis":"list"}},"permission_denials":[{"tool_name":"Bash","tool_use_id":"toolu_01JBgsXfn416qWFSQG5hziEb","tool_input":{"command":"mkdir -p \"/c/Users/CHRIST~1/AppData/Local/Temp/claude/C--DEV-MasterArbeit-QuellCode-CentronERP/8d493a0f-f069-46a0-93de-8427787b311e/scratchpad/findings\"","description":"Ensure findings directory exists"}}],"terminal_reason":"api_error","fast_mode_state":"off","fast_mode_disabled_reason":"extra_usage_disabled","subagent_stats":{"spawned":8,"requested":{"background":0,"foreground":8,"unset":0},"started_in_background":0,"max_depth":1,"spawned_by_subagents":0,"completed":4,"failed":4,"killed":{"parent":0,"user":0,"system":0},"refused":{"depth_limit":0,"concurrency_limit":0,"budget":0},"by_type":{"general-purpose":8}},"subtype":"success","api_error_status":429,"result":"You've hit your weekly limit · resets Aug 31, 7am (Europe/Berlin)","type":"result","duration_ms":1716122,"uuid":"4b5fe352-1035-4d7b-a25a-af4850c43257","queued_turn_count":0} diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_110958_v7.0.0-7499/Stderr.log b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_110958_v7.0.0-7499/Stderr.log new file mode 100644 index 00000000..e69de29b diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_110958_v7.0.0-7499/_meta/before.txt b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_110958_v7.0.0-7499/_meta/before.txt new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_110958_v7.0.0-7499/_meta/before.txt @@ -0,0 +1 @@ + diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_110958_v7.0.0-7499/_meta/combined_prompt.md b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_110958_v7.0.0-7499/_meta/combined_prompt.md new file mode 100644 index 00000000..5946645f --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_110958_v7.0.0-7499/_meta/combined_prompt.md @@ -0,0 +1,178 @@ +# Versuch 01 - Baseline (Prompt-only) - Iteration 02 + +## Metadaten +- **Versuch:** V1 Baseline (Prompt-only) +- **Iteration:** 02 (erste Überarbeitung nach Auswertung von Iteration 01) +- **Codebasis:** c-entron ERP-Suite (Windows, C#/XAML, MSSQL) +- **Zeitstempel:** 2026-08-26 +- **Vorgänger:** `01_Prompt.md` (SHA-256 `1B0DB06B…3C02FF`), 24 Läufe an Tag 1 +- **Änderungsgrund:** Auswertung der 24 Läufe von Tag 1 über 3.287 erzeugte Anforderungen. Jede Änderung ist an einen gemessenen Befund gekoppelt: + + | Änderung | Auslösender Befund | + |---|---| + | Modulinventar als Pflicht-Vorstufe, Mindestabdeckung je Modul, Vertiefung erst danach | Anforderungszahl schwankte je Lauf zwischen 42 und 325 (Faktor 5,9); 55 bis 60 von rund 85 Modulen blieben unanalysiert; die Modultabellen der Analyseberichte reichten von 0 bis 51 Zeilen | + | Hypothesenpflicht kalibriert, `Hypothesen.md` deckungsgleich mit den Inline-Markierungen | Zwei Läufe meldeten null Hypothesen bei 71 bzw. 148 Anforderungen; der Anteil schwankte zwischen 0 % und 26,2 %; mehrfach wichen Sammeldatei und Inline-Markierungen voneinander ab | + | Primärbeleg muss die durchsetzende Stelle benennen | 45,9 % aller Anforderungen trugen genau einen Beleg; in einem Lauf waren 5 von 31 risikorelevanten Anforderungen weder mit `PRIMÄR` noch als `[HYPOTHESE]` gedeckt | + | Belegpflicht verschärft: ohne Beleg keine Anforderung | Eine Anforderung wurde ohne jeden Beleg geschrieben | + | Konsolidierungsbegriff an einem Beispiel kalibriert | Anteil der Konsolidierungskandidaten schwankte je Lauf zwischen 2,4 % und 35,2 % | + | Eigenes Feld `Qualitätsmerkmal` für die ISO-25010-Zuordnung | Die Zuordnung war gefordert, hatte aber keinen Ablageort: nur 33 von 313 nicht-funktionalen Anforderungen führten sie als eigene Angabe | + | Risikoanforderungen im Konsistenzcheck auflisten | Verstöße gegen die risikobasierte Priorisierung fielen erst in der nachgelagerten Auswertung auf, nicht im Lauf selbst | + + Unverändert bleiben Prüfidee, Tracelinks, Belegklassifikation und das Blockformat: Prüfidee und Tracelinks waren in **allen** 3.287 Anforderungen gesetzt, 78,6 % der Belege waren `PRIMÄR`. + +> Dieser Prompt enthält ausschließlich die **Analyseanweisung** und ist damit unabhängig von einem +> bestimmten Werkzeug oder Modell einsetzbar. Welche Werkzeuge im jeweiligen Lauf zur Verfügung +> stehen und wohin die Ergebnisse geschrieben werden, stellt der Versuchsaufbau beim Start bei. + +--- + +## Prompt + +Du bist ein Requirements Engineer im Reverse Requirements Engineering eines Legacy-ERP-Systems. Erzeuge aus der vorliegenden Codebasis eine Anforderungsspezifikation nach **ISO/IEC/IEEE 29148:2018**. Arbeite ausschließlich auf den im Arbeitsverzeichnis liegenden Artefakten (Quellcode, Konfiguration, UI-Ressourcen, ggf. DB-Skripte). Nutze nur Informationen, die du aus diesen Artefakten gewinnen kannst. + +### Auftrag + +Erzeuge eine konsolidierte Spezifikation auf den drei Ebenen: + +1. **StRS** - Stakeholder Requirements Specification (fachliche Sicht, Akteure, Geschäftsziele) +2. **SyRS** - System Requirements Specification (Systemverhalten, Schnittstellen, Performance-, Sicherheitsanforderungen) +3. **SwRS** - Software Requirements Specification (Komponenten, Datenmodelle, Software-interne Regeln) + +Ziel ist eine Spezifikation, die als belastbare Basis für eine Web-/SaaS-Neuimplementierung dienen kann. + +### Scope (Schritt 1 der RRE-Methodenkette, manuell vorgegeben) + +Der Untersuchungsgegenstand ist die **gesamte Codebasis** im Arbeitsverzeichnis. Es gilt bewusst keine Modulbeschränkung: Alle Module, Datenobjekte und Prozesse sind gleichrangig zu erfassen. + +**Breite geht vor Tiefe.** Ein fehlendes Requirement führt bei einer Neuimplementierung zu Funktionsverlust; eine oberflächlich erfasste Funktion lässt sich dagegen nachschärfen. Erfasse deshalb zuerst die gesamte Breite und vertiefe erst danach. Halte dich an die Reihenfolge aus dem Abschnitt **Vorgehen**: erst Inventar, dann Mindestabdeckung, dann Vertiefung. + +### Vorgehen (statische Analyse, keine Ausführung) + +Bearbeite die Schritte 2-6 der RRE-Methodenkette (Schritt 1 Scope ist oben vorgegeben, Schritt 7 Validierung erfolgt manuell durch Fachexperten). Vorgeschaltet ist eine verbindliche Inventarisierung: + +**Schritt 0 - Modulinventar (vor der ersten Anforderung).** Verschaffe dir zuerst einen vollständigen Überblick über den Untersuchungsgegenstand und lege ihn im `Analysebericht.md` als Tabelle ab: fachliches Modul beziehungsweise Komponente, Pfad im Arbeitsverzeichnis, ein Satz zur fachlichen Aufgabe. Das Inventar wird erstellt, **bevor** die erste Anforderung formuliert wird. Es ist die Bezugsgröße für die Abdeckung und darf später ergänzt, aber nicht gekürzt werden. + +**Schritt 0b - Mindestabdeckung.** Jedes Modul des Inventars erhält **mindestens eine** Anforderung, bevor irgendein Modul vertieft wird. Lässt sich für ein Modul keine belegbare Anforderung bilden, führe es im Inventar als `nicht analysiert` mit einer kurzen Begründung. Ein Modul ohne Anforderung und ohne Begründung ist unzulässig. + +**Schritt 0c - Vertiefung nach Risiko.** Erst wenn die Mindestabdeckung steht, vertiefe einzelne Module. Beginne dort, wo Sicherheitsregeln, Abrechnungs- und Fakturierungslogik oder Berechtigungsprüfungen liegen. + +2. **Artefakterhebung:** Erfasse Quellcode, Konfiguration, UI-Texte, Datenbankschemata, Schnittstellenbeschreibungen sowie Change-Historie und Projektartefakte (Commit-Messages, Tickets, Release Notes, Migrationsnotizen), soweit als Datei lesbar. +3. **Technische Analyse:** Identifiziere Module, Komponenten, Abhängigkeiten, Statusmaschinen, Validierungslogik, Berechtigungsprüfungen. +4. **Semantische Interpretation:** Leite fachliche Aussagen aus technischen Implementierungen ab (z. B. Statusübergänge → Geschäftsregel). +5. **Formalisierung:** Überführe die Aussagen in klare, testbare Anforderungen mit Kontext, Vorbedingung und Ergebnis. +6. **Traceability-Anreicherung:** Verknüpfe jede Anforderung mit konkreten Artefaktbelegen. + +### Pflicht-Eigenschaften jeder Anforderung + +- **Belegpflicht:** Jede Anforderung **muss** mindestens einen konkreten Artefaktbeleg führen (Dateipfad, Klasse/Methode, SQL-Statement, UI-String, Konfigurationseintrag). Jeder Beleg erhält eine kurze Begründung, warum er die Aussage trägt. Lässt sich eine Aussage nicht belegen, **schreibe die Anforderung nicht** - erfasse den offenen Punkt stattdessen als Hypothese. Eine Anforderung ohne Beleg ist unter keinen Umständen zulässig. +- **Trennung von Fakt und Interpretation:** Die belegte technische Beobachtung (Feld `Fakt`) wird getrennt von der fachlichen Interpretation (Feld `Aussage`) dokumentiert, damit nachvollziehbar bleibt, was im Artefakt steht und was daraus geschlossen wurde. +- **Risikobasierte Priorisierung:** Anforderungen zu Sicherheitsregeln, Abrechnungs-/Fakturierungslogik und Berechtigungen unterliegen strengeren Evidenzanforderungen: Sie benötigen mindestens einen `PRIMÄR`-Beleg, andernfalls sind sie zwingend als `[HYPOTHESE]` zu kennzeichnen. Ein `PRIMÄR`-Beleg benennt hier die **durchsetzende Stelle** - Datei, Klasse, Methode und die konkrete Prüfung, Bedingung oder das Constraint. Ein Verweis auf eine Datei ohne Angabe der prüfenden Stelle genügt für diese Anforderungen nicht. +- **Belegklassifikation:** Kennzeichne jeden Beleg als + - `PRIMÄR` (durchgesetzte Regel im Code oder DB-Constraint), + - `SEKUNDÄR` (UI-Label, Fehlermeldung, Reportlayout, Mappingtabelle, Konfigurationsschalter), + - `KONTEXT` (Kommentar, Commit-Message, Ticketreferenz). +- **Hypothesenmarkierung:** Aussagen, die sich nicht eindeutig aus Artefakten ableiten lassen, kennzeichnest du explizit mit `[HYPOTHESE]` und einer kurzen Begründung, welche Information zur Bestätigung fehlt. Bei einer Codebasis dieser Größe ist eine Analyse ohne jeden offenen Punkt unplausibel: Führst du keine einzige Hypothese, begründe das ausdrücklich in der Selbstbewertung. Umgekehrt ist eine hohe Hypothesenzahl kein Mangel, sondern ein Hinweis auf ehrliche Abgrenzung. +- **Verifizierbarkeit:** Jede Anforderung enthält mindestens eine Prüfidee oder ein Akzeptanzkriterium. +- **Eindeutigkeit:** Vermeide vage Begriffe ("schnell", "benutzerfreundlich"); definiere domänenspezifische Begriffe beim ersten Auftreten. +- **Übernahmewürdigkeit:** Beurteile für jede Anforderung, ob ihre Funktion im Zielsystem erhalten bleiben soll. Unterscheide `übernehmen` (fachlich weiterhin erforderlich), `Workaround` (historisch gewachsene Behelfslösung), `Sonderfall` (Ausnahme für einen einzelnen Kunden, Mandanten oder Altbestand) und `veraltet` (durch neuere Logik abgelöst oder fachlich überholt). Begründe die Einstufung in einem Halbsatz. Diese Angabe steuert die spätere fachliche Priorisierung; eine Fehleinschätzung ist unkritisch, eine fehlende Angabe nicht. +- **Redundanzfreiheit:** Formuliere jede Anforderung so, dass sie von den übrigen klar abgegrenzt ist. Beschreiben zwei Anforderungen dieselbe fachliche Funktion aus unterschiedlicher Perspektive, führe sie zusammen oder grenze sie im Titel und in der Aussage ausdrücklich gegeneinander ab. + +### Formatvorgabe pro Anforderung + +``` +ID: - +Titel: +Ebene: +Typ: +Qualitätsmerkmal: +Akteur: +Vorbedingung: +Fakt: +Aussage: Das System soll <...>. (fachliche Interpretation als klare Soll-Aussage) +Ergebnis: +Belege: + - [PRIMÄR] - Begründung: + - [SEKUNDÄR] <...> - Begründung: <...> + - [KONTEXT] <...> - Begründung: <...> +Prüfidee: +Tracelinks: +Konsolidierung: > +Übernahmewürdigkeit: <übernehmen | Workaround | Sonderfall | veraltet> - +Status: +``` + +### Traceability + +Stelle Forward- und Backward-Traceability zwischen den drei Ebenen her: +- Jede SwRS-Anforderung referenziert die zugehörige SyRS-Anforderung. +- Jede SyRS-Anforderung referenziert die zugehörige StRS-Anforderung. +- Erzeuge zusätzlich eine konsolidierte **Traceability-Tabelle** (Markdown oder CSV): `StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg`. + +### Nicht-funktionale Anforderungen + +- Ordne nicht-funktionale Anforderungen den Qualitätsmerkmalen der **ISO/IEC 25010** zu (z. B. Zuverlässigkeit, Performance-Effizienz, Sicherheit, Wartbarkeit, Übertragbarkeit). Trage die Zuordnung in das dafür vorgesehene Feld `Qualitätsmerkmal` ein, nicht in das Feld `Typ`. +- Leite Betriebs- und Sicherheitsanforderungen gezielt auch aus indirekt sichtbaren Artefakten ab: Konfigurationen, Deployment-Skripte, Logging-Policies, Rechteprüfungen. + +### Konsolidierungsbedarf + +Die Codebasis enthält fachliche Redundanz: Dieselbe Anforderung kann auf unterschiedlichen Masken oder in unterschiedlichen Modulen mehrfach und teils unterschiedlich implementiert sein. Prüfe daher bei jeder Anforderung, ob andere Anforderungen dieselbe fachliche Funktion abbilden, und vermerke solche Fälle im Feld `Konsolidierung` als Kandidat für eine Zusammenführung im Zielsystem. + +**Gemeint sind fachlich gleichartige Konzepte in getrennten Implementierungen**, nicht bloß ähnlich formulierte Anforderungen. Ein Beispiel aus dieser Codebasis: Drucker werden als „Stammblätter" geführt, sonstige Hardware getrennt davon als „Assets" - zwei Datenhaltungen für denselben fachlichen Gegenstand, die im Zielsystem zu einem Asset-Konzept zusammengeführt werden sollen. Zwei Anforderungen, die denselben Sachverhalt nur aus Sicht verschiedener Ebenen beschreiben (etwa StRS und SwRS), sind **kein** Konsolidierungsfall - dafür sind die Tracelinks da. + +### Ergebnisstruktur (im vorgegebenen Ausgabeverzeichnis) + +``` +Ergebnisse/ + StRS.md + SyRS.md + SwRS.md + Traceability.md (oder Traceability.csv) + Hypothesen.md (Sammlung aller mit [HYPOTHESE] markierten Aussagen mit offener Frage) + Glossar.md (Domänenbegriffe, die in den Anforderungen verwendet werden) + Analysebericht.md (Modulinventar aus Schritt 0, Abdeckungstabelle, Konsistenzcheck, + Selbstbewertung, bekannte Lücken) +``` + +Das Ausgabeverzeichnis wird beim Start des Laufs beigestellt. Die analysierte Codebasis wird ausschließlich gelesen und nicht verändert. + +### Randbedingungen + +- **Keine Halluzinationen.** Wenn ein Artefakt nicht gelesen oder eine Aussage nicht belegt werden kann, ist das offen zu legen, nicht zu erfinden. +- **Keine Generierung von Code.** Es sollen ausschließlich Spezifikationsartefakte entstehen. +- **Keine Annahme über nicht beigestellte Hilfsmittel.** Arbeite mit dem, was dir in diesem Lauf zur Verfügung steht. Setze keine zusätzlichen Analysewerkzeuge, Datenbankzugriffe oder laufende Systeme voraus. Stehen für eine Aussage nur indirekte Belege zur Verfügung, ist sie als `[HYPOTHESE]` zu kennzeichnen. +- **Migrationsperspektive berücksichtigen.** Erkennbare Workarounds, Sonderfälle und überholte Logik gehören in das Feld `Übernahmewürdigkeit`, nicht in das Feld `Status`. `Status` beschreibt ausschließlich die Belegsituation (`belegt` oder `HYPOTHESE`), `Übernahmewürdigkeit` die fachliche Zukunft der Anforderung. Beide Angaben sind unabhängig voneinander: Eine gut belegte Anforderung kann ein Workaround sein, eine Hypothese kann übernahmewürdig sein. +- **Sprache:** Deutsch für Anforderungsaussagen, technische Bezeichner (Klassen, Methoden, Spalten) bleiben in ihrer Originalsprache. + +### Abschluss + +Führe vor Abgabe einen **Konsistenzcheck über das gesamte Anforderungs-Set** durch und dokumentiere das Ergebnis im `Analysebericht.md`: +- Doppelte oder mehrfach vergebene IDs +- Anforderungen ohne Beleg +- Anforderungen ohne Angabe zur `Übernahmewürdigkeit` +- Tracelinks auf nicht existierende IDs +- Inhaltlich deckungsgleiche Anforderungen, die nicht als Konsolidierungskandidat markiert sind +- **Liste aller risikorelevanten Anforderungen** (Sicherheit, Abrechnung/Fakturierung, Berechtigungen) mit ihrer Belegsituation: ID, Titel, ob ein `PRIMÄR`-Beleg vorliegt, andernfalls die `[HYPOTHESE]`-Kennzeichnung. Diese Liste macht Verstöße gegen die risikobasierte Priorisierung im Lauf selbst sichtbar. +- **Abgleich `Hypothesen.md` gegen die Inline-Markierungen:** Beide müssen dieselben Anforderungen nennen. `Hypothesen.md` enthält genau die Anforderungen mit `[HYPOTHESE]`-Markierung und keine zusätzlichen freien Fragen; offene Punkte ohne zugehörige Anforderung gehören in die Selbstbewertung. + +Erstelle außerdem die **Abdeckungstabelle** auf Basis des Modulinventars aus Schritt 0: je Modul die Einstufung `tief | mittel | flach | nicht analysiert` und die Anzahl der daraus erzeugten Anforderungen. Jede Zeile des Inventars muss in der Abdeckungstabelle auftauchen. + +Beende den Lauf mit einer kurzen Selbstbewertung im `Analysebericht.md`: +- Wie viele Module des Inventars wurden tief, mittel, flach beziehungsweise gar nicht analysiert? Nenne absolute Zahlen, nicht nur Beispiele. +- Wurde die Mindestabdeckung erreicht, also hat jedes Modul mindestens eine Anforderung? Falls nein: welche Module fehlen und warum? +- An welchen Stellen war der Beleg dünn (hoher Anteil `SEKUNDÄR`/`KONTEXT` oder `[HYPOTHESE]`)? +- Falls keine einzige Hypothese geführt wurde: Begründung, warum die Analyse ohne offene Punkte auskommt. +- Welche Erkenntnisse legen einen Nachschlag in einer Folge-Iteration nahe? + +--- + +### Werkzeugkontext (vom Versuchsaufbau vorgegeben) +Für diesen Lauf stehen zur Verfügung: Lesen und Suchen von Dateien, das Ausführen von +Kommandozeilenbefehlen im Arbeitsverzeichnis sowie die werkzeugeigenen Subagenten. +Nicht verfügbar sind: spezialisierte Agentenrollen aus Konfigurationsdateien, externe +Werkzeugserver. +Triff keine Annahmen über weitere Werkzeuge und versuche nicht, nicht verfügbare +Werkzeuge zu ersetzen. +### Ausgabeverzeichnis (überschreibt anderslautende Pfadangaben oben) +Schreibe ALLE zu erzeugenden Ergebnisdateien in das Verzeichnis +`c:\DEV\MasterArbeit\Versuche\Versuch_01\Iteration 3\claude-sonnet-5\builtin\max\02_Lauf_2026-08-27_110958_v7.0.0-7499\Ergebnisse\`. +Verändere keine Dateien im Arbeitsverzeichnis (der analysierten Codebasis). diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_110958_v7.0.0-7499/_meta/endzeit.txt b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_110958_v7.0.0-7499/_meta/endzeit.txt new file mode 100644 index 00000000..1e0f2772 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_110958_v7.0.0-7499/_meta/endzeit.txt @@ -0,0 +1 @@ +2026-08-27T11:38:36.1567144+02:00 diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_110958_v7.0.0-7499/_meta/startzeit.txt b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_110958_v7.0.0-7499/_meta/startzeit.txt new file mode 100644 index 00000000..e1daec68 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_110958_v7.0.0-7499/_meta/startzeit.txt @@ -0,0 +1 @@ +2026-08-27T11:09:58.2717910+02:00 diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_124836_v7.0.0-cf3c/RawResult.json b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_124836_v7.0.0-cf3c/RawResult.json new file mode 100644 index 00000000..b1803b15 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_124836_v7.0.0-cf3c/RawResult.json @@ -0,0 +1 @@ +{"is_error":true,"duration_api_ms":0,"num_turns":1,"stop_reason":"stop_sequence","session_id":"af9be153-a3b0-427c-954b-615d562631fa","total_cost_usd":0,"usage":{"output_tokens_details":{"thinking_tokens":0},"input_tokens":0,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":0,"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":0,"ephemeral_5m_input_tokens":0},"inference_geo":"","iterations":[],"speed":"standard"},"modelUsage":{},"permission_denials":[],"terminal_reason":"api_error","fast_mode_state":"off","fast_mode_disabled_reason":"extra_usage_disabled","subagent_stats":{"spawned":0,"requested":{"background":0,"foreground":0,"unset":0},"started_in_background":0,"max_depth":0,"spawned_by_subagents":0,"completed":0,"failed":0,"killed":{"parent":0,"user":0,"system":0},"refused":{"depth_limit":0,"concurrency_limit":0,"budget":0},"by_type":{}},"subtype":"success","api_error_status":429,"result":"You've hit your weekly limit · resets Aug 31, 7am (Europe/Berlin)","type":"result","duration_ms":457,"uuid":"10894110-3434-4adc-b7f0-6a0ee842f78a","queued_turn_count":0} diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_124836_v7.0.0-cf3c/Stderr.log b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_124836_v7.0.0-cf3c/Stderr.log new file mode 100644 index 00000000..e69de29b diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_124836_v7.0.0-cf3c/_meta/before.txt b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_124836_v7.0.0-cf3c/_meta/before.txt new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_124836_v7.0.0-cf3c/_meta/before.txt @@ -0,0 +1 @@ + diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_124836_v7.0.0-cf3c/_meta/combined_prompt.md b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_124836_v7.0.0-cf3c/_meta/combined_prompt.md new file mode 100644 index 00000000..8e0b77a7 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_124836_v7.0.0-cf3c/_meta/combined_prompt.md @@ -0,0 +1,178 @@ +# Versuch 01 - Baseline (Prompt-only) - Iteration 02 + +## Metadaten +- **Versuch:** V1 Baseline (Prompt-only) +- **Iteration:** 02 (erste Überarbeitung nach Auswertung von Iteration 01) +- **Codebasis:** c-entron ERP-Suite (Windows, C#/XAML, MSSQL) +- **Zeitstempel:** 2026-08-26 +- **Vorgänger:** `01_Prompt.md` (SHA-256 `1B0DB06B…3C02FF`), 24 Läufe an Tag 1 +- **Änderungsgrund:** Auswertung der 24 Läufe von Tag 1 über 3.287 erzeugte Anforderungen. Jede Änderung ist an einen gemessenen Befund gekoppelt: + + | Änderung | Auslösender Befund | + |---|---| + | Modulinventar als Pflicht-Vorstufe, Mindestabdeckung je Modul, Vertiefung erst danach | Anforderungszahl schwankte je Lauf zwischen 42 und 325 (Faktor 5,9); 55 bis 60 von rund 85 Modulen blieben unanalysiert; die Modultabellen der Analyseberichte reichten von 0 bis 51 Zeilen | + | Hypothesenpflicht kalibriert, `Hypothesen.md` deckungsgleich mit den Inline-Markierungen | Zwei Läufe meldeten null Hypothesen bei 71 bzw. 148 Anforderungen; der Anteil schwankte zwischen 0 % und 26,2 %; mehrfach wichen Sammeldatei und Inline-Markierungen voneinander ab | + | Primärbeleg muss die durchsetzende Stelle benennen | 45,9 % aller Anforderungen trugen genau einen Beleg; in einem Lauf waren 5 von 31 risikorelevanten Anforderungen weder mit `PRIMÄR` noch als `[HYPOTHESE]` gedeckt | + | Belegpflicht verschärft: ohne Beleg keine Anforderung | Eine Anforderung wurde ohne jeden Beleg geschrieben | + | Konsolidierungsbegriff an einem Beispiel kalibriert | Anteil der Konsolidierungskandidaten schwankte je Lauf zwischen 2,4 % und 35,2 % | + | Eigenes Feld `Qualitätsmerkmal` für die ISO-25010-Zuordnung | Die Zuordnung war gefordert, hatte aber keinen Ablageort: nur 33 von 313 nicht-funktionalen Anforderungen führten sie als eigene Angabe | + | Risikoanforderungen im Konsistenzcheck auflisten | Verstöße gegen die risikobasierte Priorisierung fielen erst in der nachgelagerten Auswertung auf, nicht im Lauf selbst | + + Unverändert bleiben Prüfidee, Tracelinks, Belegklassifikation und das Blockformat: Prüfidee und Tracelinks waren in **allen** 3.287 Anforderungen gesetzt, 78,6 % der Belege waren `PRIMÄR`. + +> Dieser Prompt enthält ausschließlich die **Analyseanweisung** und ist damit unabhängig von einem +> bestimmten Werkzeug oder Modell einsetzbar. Welche Werkzeuge im jeweiligen Lauf zur Verfügung +> stehen und wohin die Ergebnisse geschrieben werden, stellt der Versuchsaufbau beim Start bei. + +--- + +## Prompt + +Du bist ein Requirements Engineer im Reverse Requirements Engineering eines Legacy-ERP-Systems. Erzeuge aus der vorliegenden Codebasis eine Anforderungsspezifikation nach **ISO/IEC/IEEE 29148:2018**. Arbeite ausschließlich auf den im Arbeitsverzeichnis liegenden Artefakten (Quellcode, Konfiguration, UI-Ressourcen, ggf. DB-Skripte). Nutze nur Informationen, die du aus diesen Artefakten gewinnen kannst. + +### Auftrag + +Erzeuge eine konsolidierte Spezifikation auf den drei Ebenen: + +1. **StRS** - Stakeholder Requirements Specification (fachliche Sicht, Akteure, Geschäftsziele) +2. **SyRS** - System Requirements Specification (Systemverhalten, Schnittstellen, Performance-, Sicherheitsanforderungen) +3. **SwRS** - Software Requirements Specification (Komponenten, Datenmodelle, Software-interne Regeln) + +Ziel ist eine Spezifikation, die als belastbare Basis für eine Web-/SaaS-Neuimplementierung dienen kann. + +### Scope (Schritt 1 der RRE-Methodenkette, manuell vorgegeben) + +Der Untersuchungsgegenstand ist die **gesamte Codebasis** im Arbeitsverzeichnis. Es gilt bewusst keine Modulbeschränkung: Alle Module, Datenobjekte und Prozesse sind gleichrangig zu erfassen. + +**Breite geht vor Tiefe.** Ein fehlendes Requirement führt bei einer Neuimplementierung zu Funktionsverlust; eine oberflächlich erfasste Funktion lässt sich dagegen nachschärfen. Erfasse deshalb zuerst die gesamte Breite und vertiefe erst danach. Halte dich an die Reihenfolge aus dem Abschnitt **Vorgehen**: erst Inventar, dann Mindestabdeckung, dann Vertiefung. + +### Vorgehen (statische Analyse, keine Ausführung) + +Bearbeite die Schritte 2-6 der RRE-Methodenkette (Schritt 1 Scope ist oben vorgegeben, Schritt 7 Validierung erfolgt manuell durch Fachexperten). Vorgeschaltet ist eine verbindliche Inventarisierung: + +**Schritt 0 - Modulinventar (vor der ersten Anforderung).** Verschaffe dir zuerst einen vollständigen Überblick über den Untersuchungsgegenstand und lege ihn im `Analysebericht.md` als Tabelle ab: fachliches Modul beziehungsweise Komponente, Pfad im Arbeitsverzeichnis, ein Satz zur fachlichen Aufgabe. Das Inventar wird erstellt, **bevor** die erste Anforderung formuliert wird. Es ist die Bezugsgröße für die Abdeckung und darf später ergänzt, aber nicht gekürzt werden. + +**Schritt 0b - Mindestabdeckung.** Jedes Modul des Inventars erhält **mindestens eine** Anforderung, bevor irgendein Modul vertieft wird. Lässt sich für ein Modul keine belegbare Anforderung bilden, führe es im Inventar als `nicht analysiert` mit einer kurzen Begründung. Ein Modul ohne Anforderung und ohne Begründung ist unzulässig. + +**Schritt 0c - Vertiefung nach Risiko.** Erst wenn die Mindestabdeckung steht, vertiefe einzelne Module. Beginne dort, wo Sicherheitsregeln, Abrechnungs- und Fakturierungslogik oder Berechtigungsprüfungen liegen. + +2. **Artefakterhebung:** Erfasse Quellcode, Konfiguration, UI-Texte, Datenbankschemata, Schnittstellenbeschreibungen sowie Change-Historie und Projektartefakte (Commit-Messages, Tickets, Release Notes, Migrationsnotizen), soweit als Datei lesbar. +3. **Technische Analyse:** Identifiziere Module, Komponenten, Abhängigkeiten, Statusmaschinen, Validierungslogik, Berechtigungsprüfungen. +4. **Semantische Interpretation:** Leite fachliche Aussagen aus technischen Implementierungen ab (z. B. Statusübergänge → Geschäftsregel). +5. **Formalisierung:** Überführe die Aussagen in klare, testbare Anforderungen mit Kontext, Vorbedingung und Ergebnis. +6. **Traceability-Anreicherung:** Verknüpfe jede Anforderung mit konkreten Artefaktbelegen. + +### Pflicht-Eigenschaften jeder Anforderung + +- **Belegpflicht:** Jede Anforderung **muss** mindestens einen konkreten Artefaktbeleg führen (Dateipfad, Klasse/Methode, SQL-Statement, UI-String, Konfigurationseintrag). Jeder Beleg erhält eine kurze Begründung, warum er die Aussage trägt. Lässt sich eine Aussage nicht belegen, **schreibe die Anforderung nicht** - erfasse den offenen Punkt stattdessen als Hypothese. Eine Anforderung ohne Beleg ist unter keinen Umständen zulässig. +- **Trennung von Fakt und Interpretation:** Die belegte technische Beobachtung (Feld `Fakt`) wird getrennt von der fachlichen Interpretation (Feld `Aussage`) dokumentiert, damit nachvollziehbar bleibt, was im Artefakt steht und was daraus geschlossen wurde. +- **Risikobasierte Priorisierung:** Anforderungen zu Sicherheitsregeln, Abrechnungs-/Fakturierungslogik und Berechtigungen unterliegen strengeren Evidenzanforderungen: Sie benötigen mindestens einen `PRIMÄR`-Beleg, andernfalls sind sie zwingend als `[HYPOTHESE]` zu kennzeichnen. Ein `PRIMÄR`-Beleg benennt hier die **durchsetzende Stelle** - Datei, Klasse, Methode und die konkrete Prüfung, Bedingung oder das Constraint. Ein Verweis auf eine Datei ohne Angabe der prüfenden Stelle genügt für diese Anforderungen nicht. +- **Belegklassifikation:** Kennzeichne jeden Beleg als + - `PRIMÄR` (durchgesetzte Regel im Code oder DB-Constraint), + - `SEKUNDÄR` (UI-Label, Fehlermeldung, Reportlayout, Mappingtabelle, Konfigurationsschalter), + - `KONTEXT` (Kommentar, Commit-Message, Ticketreferenz). +- **Hypothesenmarkierung:** Aussagen, die sich nicht eindeutig aus Artefakten ableiten lassen, kennzeichnest du explizit mit `[HYPOTHESE]` und einer kurzen Begründung, welche Information zur Bestätigung fehlt. Bei einer Codebasis dieser Größe ist eine Analyse ohne jeden offenen Punkt unplausibel: Führst du keine einzige Hypothese, begründe das ausdrücklich in der Selbstbewertung. Umgekehrt ist eine hohe Hypothesenzahl kein Mangel, sondern ein Hinweis auf ehrliche Abgrenzung. +- **Verifizierbarkeit:** Jede Anforderung enthält mindestens eine Prüfidee oder ein Akzeptanzkriterium. +- **Eindeutigkeit:** Vermeide vage Begriffe ("schnell", "benutzerfreundlich"); definiere domänenspezifische Begriffe beim ersten Auftreten. +- **Übernahmewürdigkeit:** Beurteile für jede Anforderung, ob ihre Funktion im Zielsystem erhalten bleiben soll. Unterscheide `übernehmen` (fachlich weiterhin erforderlich), `Workaround` (historisch gewachsene Behelfslösung), `Sonderfall` (Ausnahme für einen einzelnen Kunden, Mandanten oder Altbestand) und `veraltet` (durch neuere Logik abgelöst oder fachlich überholt). Begründe die Einstufung in einem Halbsatz. Diese Angabe steuert die spätere fachliche Priorisierung; eine Fehleinschätzung ist unkritisch, eine fehlende Angabe nicht. +- **Redundanzfreiheit:** Formuliere jede Anforderung so, dass sie von den übrigen klar abgegrenzt ist. Beschreiben zwei Anforderungen dieselbe fachliche Funktion aus unterschiedlicher Perspektive, führe sie zusammen oder grenze sie im Titel und in der Aussage ausdrücklich gegeneinander ab. + +### Formatvorgabe pro Anforderung + +``` +ID: - +Titel: +Ebene: +Typ: +Qualitätsmerkmal: +Akteur: +Vorbedingung: +Fakt: +Aussage: Das System soll <...>. (fachliche Interpretation als klare Soll-Aussage) +Ergebnis: +Belege: + - [PRIMÄR] - Begründung: + - [SEKUNDÄR] <...> - Begründung: <...> + - [KONTEXT] <...> - Begründung: <...> +Prüfidee: +Tracelinks: +Konsolidierung: > +Übernahmewürdigkeit: <übernehmen | Workaround | Sonderfall | veraltet> - +Status: +``` + +### Traceability + +Stelle Forward- und Backward-Traceability zwischen den drei Ebenen her: +- Jede SwRS-Anforderung referenziert die zugehörige SyRS-Anforderung. +- Jede SyRS-Anforderung referenziert die zugehörige StRS-Anforderung. +- Erzeuge zusätzlich eine konsolidierte **Traceability-Tabelle** (Markdown oder CSV): `StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg`. + +### Nicht-funktionale Anforderungen + +- Ordne nicht-funktionale Anforderungen den Qualitätsmerkmalen der **ISO/IEC 25010** zu (z. B. Zuverlässigkeit, Performance-Effizienz, Sicherheit, Wartbarkeit, Übertragbarkeit). Trage die Zuordnung in das dafür vorgesehene Feld `Qualitätsmerkmal` ein, nicht in das Feld `Typ`. +- Leite Betriebs- und Sicherheitsanforderungen gezielt auch aus indirekt sichtbaren Artefakten ab: Konfigurationen, Deployment-Skripte, Logging-Policies, Rechteprüfungen. + +### Konsolidierungsbedarf + +Die Codebasis enthält fachliche Redundanz: Dieselbe Anforderung kann auf unterschiedlichen Masken oder in unterschiedlichen Modulen mehrfach und teils unterschiedlich implementiert sein. Prüfe daher bei jeder Anforderung, ob andere Anforderungen dieselbe fachliche Funktion abbilden, und vermerke solche Fälle im Feld `Konsolidierung` als Kandidat für eine Zusammenführung im Zielsystem. + +**Gemeint sind fachlich gleichartige Konzepte in getrennten Implementierungen**, nicht bloß ähnlich formulierte Anforderungen. Ein Beispiel aus dieser Codebasis: Drucker werden als „Stammblätter" geführt, sonstige Hardware getrennt davon als „Assets" - zwei Datenhaltungen für denselben fachlichen Gegenstand, die im Zielsystem zu einem Asset-Konzept zusammengeführt werden sollen. Zwei Anforderungen, die denselben Sachverhalt nur aus Sicht verschiedener Ebenen beschreiben (etwa StRS und SwRS), sind **kein** Konsolidierungsfall - dafür sind die Tracelinks da. + +### Ergebnisstruktur (im vorgegebenen Ausgabeverzeichnis) + +``` +Ergebnisse/ + StRS.md + SyRS.md + SwRS.md + Traceability.md (oder Traceability.csv) + Hypothesen.md (Sammlung aller mit [HYPOTHESE] markierten Aussagen mit offener Frage) + Glossar.md (Domänenbegriffe, die in den Anforderungen verwendet werden) + Analysebericht.md (Modulinventar aus Schritt 0, Abdeckungstabelle, Konsistenzcheck, + Selbstbewertung, bekannte Lücken) +``` + +Das Ausgabeverzeichnis wird beim Start des Laufs beigestellt. Die analysierte Codebasis wird ausschließlich gelesen und nicht verändert. + +### Randbedingungen + +- **Keine Halluzinationen.** Wenn ein Artefakt nicht gelesen oder eine Aussage nicht belegt werden kann, ist das offen zu legen, nicht zu erfinden. +- **Keine Generierung von Code.** Es sollen ausschließlich Spezifikationsartefakte entstehen. +- **Keine Annahme über nicht beigestellte Hilfsmittel.** Arbeite mit dem, was dir in diesem Lauf zur Verfügung steht. Setze keine zusätzlichen Analysewerkzeuge, Datenbankzugriffe oder laufende Systeme voraus. Stehen für eine Aussage nur indirekte Belege zur Verfügung, ist sie als `[HYPOTHESE]` zu kennzeichnen. +- **Migrationsperspektive berücksichtigen.** Erkennbare Workarounds, Sonderfälle und überholte Logik gehören in das Feld `Übernahmewürdigkeit`, nicht in das Feld `Status`. `Status` beschreibt ausschließlich die Belegsituation (`belegt` oder `HYPOTHESE`), `Übernahmewürdigkeit` die fachliche Zukunft der Anforderung. Beide Angaben sind unabhängig voneinander: Eine gut belegte Anforderung kann ein Workaround sein, eine Hypothese kann übernahmewürdig sein. +- **Sprache:** Deutsch für Anforderungsaussagen, technische Bezeichner (Klassen, Methoden, Spalten) bleiben in ihrer Originalsprache. + +### Abschluss + +Führe vor Abgabe einen **Konsistenzcheck über das gesamte Anforderungs-Set** durch und dokumentiere das Ergebnis im `Analysebericht.md`: +- Doppelte oder mehrfach vergebene IDs +- Anforderungen ohne Beleg +- Anforderungen ohne Angabe zur `Übernahmewürdigkeit` +- Tracelinks auf nicht existierende IDs +- Inhaltlich deckungsgleiche Anforderungen, die nicht als Konsolidierungskandidat markiert sind +- **Liste aller risikorelevanten Anforderungen** (Sicherheit, Abrechnung/Fakturierung, Berechtigungen) mit ihrer Belegsituation: ID, Titel, ob ein `PRIMÄR`-Beleg vorliegt, andernfalls die `[HYPOTHESE]`-Kennzeichnung. Diese Liste macht Verstöße gegen die risikobasierte Priorisierung im Lauf selbst sichtbar. +- **Abgleich `Hypothesen.md` gegen die Inline-Markierungen:** Beide müssen dieselben Anforderungen nennen. `Hypothesen.md` enthält genau die Anforderungen mit `[HYPOTHESE]`-Markierung und keine zusätzlichen freien Fragen; offene Punkte ohne zugehörige Anforderung gehören in die Selbstbewertung. + +Erstelle außerdem die **Abdeckungstabelle** auf Basis des Modulinventars aus Schritt 0: je Modul die Einstufung `tief | mittel | flach | nicht analysiert` und die Anzahl der daraus erzeugten Anforderungen. Jede Zeile des Inventars muss in der Abdeckungstabelle auftauchen. + +Beende den Lauf mit einer kurzen Selbstbewertung im `Analysebericht.md`: +- Wie viele Module des Inventars wurden tief, mittel, flach beziehungsweise gar nicht analysiert? Nenne absolute Zahlen, nicht nur Beispiele. +- Wurde die Mindestabdeckung erreicht, also hat jedes Modul mindestens eine Anforderung? Falls nein: welche Module fehlen und warum? +- An welchen Stellen war der Beleg dünn (hoher Anteil `SEKUNDÄR`/`KONTEXT` oder `[HYPOTHESE]`)? +- Falls keine einzige Hypothese geführt wurde: Begründung, warum die Analyse ohne offene Punkte auskommt. +- Welche Erkenntnisse legen einen Nachschlag in einer Folge-Iteration nahe? + +--- + +### Werkzeugkontext (vom Versuchsaufbau vorgegeben) +Für diesen Lauf stehen zur Verfügung: Lesen und Suchen von Dateien, das Ausführen von +Kommandozeilenbefehlen im Arbeitsverzeichnis sowie die werkzeugeigenen Subagenten. +Nicht verfügbar sind: spezialisierte Agentenrollen aus Konfigurationsdateien, externe +Werkzeugserver. +Triff keine Annahmen über weitere Werkzeuge und versuche nicht, nicht verfügbare +Werkzeuge zu ersetzen. +### Ausgabeverzeichnis (überschreibt anderslautende Pfadangaben oben) +Schreibe ALLE zu erzeugenden Ergebnisdateien in das Verzeichnis +`c:\DEV\MasterArbeit\Versuche\Versuch_01\Iteration 3\claude-sonnet-5\builtin\max\02_Lauf_2026-08-27_124836_v7.0.0-cf3c\Ergebnisse\`. +Verändere keine Dateien im Arbeitsverzeichnis (der analysierten Codebasis). diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_124836_v7.0.0-cf3c/_meta/endzeit.txt b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_124836_v7.0.0-cf3c/_meta/endzeit.txt new file mode 100644 index 00000000..316476f8 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_124836_v7.0.0-cf3c/_meta/endzeit.txt @@ -0,0 +1 @@ +2026-08-27T12:48:38.8520809+02:00 diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_124836_v7.0.0-cf3c/_meta/startzeit.txt b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_124836_v7.0.0-cf3c/_meta/startzeit.txt new file mode 100644 index 00000000..67e5df2a --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/builtin/max/02_Lauf_2026-08-27_124836_v7.0.0-cf3c/_meta/startzeit.txt @@ -0,0 +1 @@ +2026-08-27T12:48:36.4195736+02:00 diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/Analysebericht.md b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/Analysebericht.md new file mode 100644 index 00000000..b1363c20 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/Analysebericht.md @@ -0,0 +1,327 @@ +# Analysebericht – Reverse Requirements Engineering c-entron ERP-Suite + +Untersuchungsgegenstand: gesamte Codebasis unter `C:\DEV\MasterArbeit\QuellCode\CentronERP` (Arbeitsverzeichnis, ausschließlich lesend analysiert). Pfadangaben in diesem Bericht sind relativ zu diesem Arbeitsverzeichnis. + +## Schritt 0 – Modulinventar + +Das Inventar wurde durch Auswertung der Projekt- und Verzeichnisstruktur (`Centron.sln`, `src/*`) erstellt, **bevor** eine Anforderung formuliert wurde. Es ist die Bezugsgröße für die Abdeckung (siehe Abdeckungstabelle am Ende dieses Berichts) und wird ergänzt, nicht gekürzt. + +Abgrenzung: Rein technische Querschnittsbibliotheken ohne eigenständige fachliche Funktion (u. a. `shared/Centron.Controls`, `shared/Centron.Core`, WPF-interne Ordner `Behaviors/`, `Extensions/`, `Style/`, `VisualTree/`) sind nicht als eigene Inventarzeile geführt; sie werden als technische Grundlage in den Belegen einzelner Anforderungen mitgenutzt, wo relevant. Große, fachlich heterogene Verzeichnisse (`Finances`, `Warehousing`, `Administration`, `Helpdesk`, `DataExchange`, `MyCentron`, `Statistics`, `Purchasing`) wurden auf Ebene ihrer Unterordner aufgeschlüsselt, weil diese jeweils eigenständige fachliche Funktionen abbilden; kleine, thematisch zusammengehörige Unterordner wurden zu einer Zeile zusammengefasst (z. B. mehrere Administration-„Settings“-Ordner). Vier produktdatenliefernde Fremd-APIs (COP/EGIS/ITscope/Icecat) sind wegen identischer fachlicher Funktion (externe Produktkatalog-Anreicherung) in einer Zeile zusammengefasst – siehe hierzu auch den Konsolidierungshinweis in SyRS. + +| Nr | Bereich | Modul/Komponente | Pfad (relativ zum Arbeitsverzeichnis) | Fachliche Aufgabe | +|----|---------|-------------------|----------------------------------------|--------------------| +| 1 | Vertrieb/CRM | Sales – Sonderpreise/Mailing | src/centron/Centron.WPF.UI/Modules/Sales | Verwaltung kundenspezifischer Sonderpreise, Serienmail- und Produktmatrix-Funktionen für den Vertrieb | +| 2 | Vertrieb/CRM | CRM/Adressstamm | src/centron/Centron.WPF.UI/Modules/Finances/Crm | Zentrale Kunden-, Lieferanten- und Kontaktverwaltung (Adressstamm) inkl. Aktivitäten, Verträgen, Sonderpreisen, DSGVO-Tab | +| 3 | Vertrieb/CRM | Kampagnenmanagement | src/centron/Centron.WPF.UI/Modules/Finances/Campaigns | Planung, Durchführung und Auswertung von Marketing-/Vertriebskampagnen | +| 4 | Vertrieb/CRM | CRM-Stammdatenlisten | src/centron/Centron.WPF.UI/Modules/Finances/MasterDataLists | Listenbasierte Massenpflege von CRM-Stammdaten | +| 5 | Vertrieb/CRM | Vertragsverwaltung & -auswertung | src/centron/Centron.WPF.UI/Modules/Finances/Contracts, ContractEvaluation2, ContractEvaluationOld | Verwaltung von Kundenverträgen und Auswertung von Vertragskennzahlen (zwei parallele Implementierungsstände) | +| 6 | Vertrieb/CRM | Projektverwaltung (Finanzsicht) | src/centron/Centron.WPF.UI/Modules/Finances/Projects | Kaufmännische Projektverwaltung und -abrechnung | +| 7 | Vertrieb/CRM | Zählerstandserfassung (MPS) | src/centron/Centron.WPF.UI/Modules/Finances/DeviceClickCounter | Erfassung von Zählerständen verwalteter Drucksysteme als Abrechnungsgrundlage (Managed Print Services) | +| 8 | Vertrieb/CRM | Produktlebenszyklus-Management | src/centron/Centron.WPF.UI/Modules/PLM, Modules/Finances/ProductLifecycleManagement | Verwaltung von Produktfamilien und deren Lebenszyklusphasen | +| 9 | Vertrieb/CRM | Zahler- und Kostenstellenverwaltung | src/centron/Centron.WPF.UI/Modules/PayersAndCostCenter | Zuordnung abweichender Zahler sowie Kostenstellen/-objekte zu Belegen | +| 10 | Vertrieb/CRM | Projektpreisimport | src/centron/Centron.WPF.UI/Modules/ProjectPriceImport | Import und Abgleich projektspezifischer Preislisten | +| 11 | Vertrieb/CRM | Projektmanagement (allgemein) | src/centron/Centron.WPF.UI/Modules/ProjectManagement | Allgemeine Projektverwaltungsfunktionen außerhalb der Finanzsicht | +| 12 | Belegwesen | Belegbearbeitung Kern | src/centron/Centron.WPF.UI/Modules/Finances/Receipts | Erstellung/Bearbeitung der Belegkette Angebot–Auftrag–Lieferschein–Rechnung–Gutschrift inkl. Kalkulation, Positionserfassung, Belegvorlagen | +| 13 | Belegwesen | Anzahlungen | src/centron/Centron.WPF.UI/Modules/Finances/Receipts/DownPayment | Verwaltung von Anzahlungsrechnungen und deren Verrechnung | +| 14 | Belegwesen | Steuersatzänderung im Beleg | src/centron/Centron.WPF.UI/Modules/Finances/Receipts/ChangeTaxRate | Nachträgliches Ändern des Steuersatzes auf Belegpositionen | +| 15 | Belegwesen | Provisionsermittlung | src/centron/Centron.WPF.UI/Modules/Finances/Receipts/Provision | Ermittlung von Verkäuferprovisionen je Beleg/Position (Korrektur: „PartialCommission" gehört fachlich zur Kommissionsware, siehe Zeile 32, nicht zur Verkäuferprovision – ursprüngliche Zuordnung war irreführend) | +| 16 | Belegwesen | Web-Angebote | src/centron/Centron.WPF.UI/Modules/Finances/Receipts/WebOffer, GenerateWebOffer | Bereitstellung von Angeboten über einen Weblink für Kunden | +| 17 | Belegwesen | EDI-Auftragsverbuchung | src/centron/Centron.WPF.UI/Modules/Finances/Receipts/EdiOrderbooking | Automatisierte Verbuchung elektronisch eingehender Aufträge | +| 18 | Abrechnung/Fakturierung | Automatisierte Rechnungserstellung | src/centron/Centron.WPF.UI/Modules/Finances/AutomatedBilling | Automatisiertes, periodisches Erstellen von Rechnungen aus Verträgen | +| 19 | Abrechnung/Fakturierung | Pauschalabrechnung (Flatrate) | src/centron/Centron.WPF.UI/Modules/Finances/FlatrateBilling | Abrechnung pauschaler Vertragsleistungen | +| 20 | Abrechnung/Fakturierung | Zeit-/Leistungsabrechnung (Timer) | src/centron/Centron.WPF.UI/Modules/Finances/TimerBilling | Abrechnung erfasster Zeiterfassungen/Leistungen | +| 21 | Abrechnung/Fakturierung | Mahnwesen | src/centron/Centron.WPF.UI/Modules/Finances/Dunning | Automatisiertes Mahnverfahren für offene Forderungen | +| 22 | Abrechnung/Fakturierung | Offene Posten | src/centron/Centron.WPF.UI/Modules/Finances/Opos | Verwaltung offener Forderungen/Verbindlichkeiten | +| 23 | Abrechnung/Fakturierung | Zahlungsverkehr (Payments) | src/centron/Centron.WPF.UI/Modules/Finances/Payments | Erfassung und Zuordnung von Zahlungseingängen/-ausgängen | +| 24 | Abrechnung/Fakturierung | Kontenverwaltung (Buchhaltung) | src/centron/Centron.WPF.UI/Modules/Finances/AccountManagement | Verwaltung von Finanzkonten und zugehörigen Buchungen | +| 25 | Abrechnung/Fakturierung | Warenausgangszahlungen | src/centron/Centron.WPF.UI/Modules/Warehousing/OutcomingPayments | Erfassung von Zahlungen im Warenausgangsprozess (z. B. Nachnahme) | +| 26 | Abrechnung/Fakturierung | Kassensystem-Anbindung | src/centron/Centron.WPF.UI/Modules/Warehousing/AccountSystems | Anbindung/Abgleich von Kassen-/Kontensystemen im Lager | +| 27 | Lager/Artikel | Artikelstammdaten | src/centron/Centron.WPF.UI/Modules/Warehousing/ArticleManagement | Zentrale Pflege der Artikelstammdaten (Preise, Bestände, Merkmale) | +| 28 | Lager/Artikel | Artikelimport | src/centron/Centron.WPF.UI/Modules/Warehousing/ArticleImport | Importieren von Artikeldaten aus externen Quellen | +| 29 | Lager/Artikel | Mengeneinheitenverwaltung | src/centron/Centron.WPF.UI/Modules/Warehousing/ArticleUnitManagement | Pflege von Mengeneinheiten und Umrechnungsfaktoren | +| 30 | Lager/Artikel | Barcode-Verwaltung | src/centron/Centron.WPF.UI/Modules/Warehousing/BarcodeManagement | Erzeugung/Zuordnung von Barcodes zu Artikeln | +| 31 | Lager/Artikel | Kommissionierung | src/centron/Centron.WPF.UI/Modules/Warehousing/Commissioning | Steuerung der Warenkommissionierung im Lager | +| 32 | Lager/Artikel | Kommissionsware/Konsignation | src/centron/Centron.WPF.UI/Modules/Warehousing/Commissions | Verwaltung von Kommissionsaufträgen (Konsignationslager) inkl. Teilkommissionen | +| 33 | Lager/Artikel | Inventur | src/centron/Centron.WPF.UI/Modules/Warehousing/Inventory | Durchführung und Bewertung von Lagerinventuren | +| 34 | Lager/Artikel | Warengruppenverwaltung | src/centron/Centron.WPF.UI/Modules/Warehousing/MaterialGroupManagement | Pflege der Warengruppenhierarchie | +| 35 | Lager/Artikel | Artikelsuche | src/centron/Centron.WPF.UI/Modules/Warehousing/SearchArticle | Übergreifende Artikelsuche als UI-Dienst | +| 36 | Lager/Artikel | Lieferantensuche | src/centron/Centron.WPF.UI/Modules/Warehousing/SupplierSearch | Suche/Auswahl von Lieferanten im Beschaffungskontext | +| 37 | Lager/Artikel | Logistikeinstellungen/Versandarten | src/centron/Centron.WPF.UI/Modules/Logistic | Konfiguration von Versandarten und logistischen Einstellungen | +| 38 | Einkauf | EDI-Bestellwesen | src/centron/Centron.WPF.UI/Modules/Purchasing/EDIManagement | Elektronischer Bestelldatenaustausch mit Lieferanten | +| 39 | Einkauf | Bestellvorschlagsliste | src/centron/Centron.WPF.UI/Modules/Purchasing/OrderSuggestionList | Ermittlung von Nachbestellbedarf | +| 40 | Einkauf | Einkaufseinstellungen | src/centron/Centron.WPF.UI/Modules/Purchasing/PurchaseSettings, Others | Grundeinstellungen des Einkaufsprozesses | +| 41 | Einkauf | Reisekostenabrechnung | src/centron/Centron.WPF.UI/Modules/Purchasing/TravelExpense | Erfassung/Abrechnung von Reisekosten | +| 42 | Produktion | Fertigungsauftragsverwaltung | src/centron/Centron.WPF.UI/Modules/Production/ProductionOrder, Settings | Anlage und Steuerung von Fertigungsaufträgen | +| 43 | Produktion | Maschinenverwaltung | src/centron/Centron.WPF.UI/Modules/Production/MachineManagement | Stammdatenverwaltung von Produktionsmaschinen | +| 44 | Retouren | RMA-Abwicklung | src/centron/Centron.WPF.UI/Modules/Rma | Abwicklung von Rücksendungen/Reklamationen (Return Merchandise Authorization) | +| 45 | Helpdesk | Ticketverwaltung | src/centron/Centron.WPF.UI/Modules/Helpdesk/TicketDetails, TicketList, TicketProcessTemplates | Erfassung und Bearbeitung von Support-Tickets | +| 46 | Helpdesk | Helpdesk-Dashboard | src/centron/Centron.WPF.UI/Modules/Helpdesk/Dashboard | Übersichts-/Kennzahlendarstellung für den Helpdesk | +| 47 | Helpdesk | Wartungsverträge/erwartete Ereignisse | src/centron/Centron.WPF.UI/Modules/Helpdesk/ExpectedEvents, ExpectedEventsReporting | Überwachung vertraglich erwarteter Wartungsereignisse (SLA-Fristen) | +| 48 | Helpdesk | Helpdesk-Einstellungen | src/centron/Centron.WPF.UI/Modules/Helpdesk/Settings, TaskManagement | Konfiguration von Ticketprozessen und Aufgaben | +| 49 | Helpdesk | Helpdesk Sonstiges | src/centron/Centron.WPF.UI/Modules/Helpdesk/Events, ConnectionNumber, CentronChecklist, SendSelfCareForm | Ereignisprotokoll, Checklisten, Self-Service-Formular | +| 50 | MyCentron | CentronInspectors | src/centron/Centron.WPF.UI/Modules/MyCentron/CentronInspectors | Pluggable Datenqualitäts-/Selbstdiagnoseprüfungen (Inspectors), die Stammdatenverstöße per SQL aufspüren und Korrekturdialoge anbieten (Korrektur ggü. Erstinventar: keine Prüfmittelverwaltung, sondern Dateninspektion) | +| 51 | MyCentron | Persönliche Einstellungen | src/centron/Centron.WPF.UI/Modules/MyCentron/PersonalSettings | Benutzerbezogene Einstellungen | +| 52 | MyCentron | Mein Tag (MyDay) | src/centron/Centron.WPF.UI/Modules/MyCentron/MyDay | Tagesplanansicht für Mitarbeitende | +| 53 | MyCentron | MyCentron-Dashboard | src/centron/Centron.WPF.UI/Modules/MyCentron/Dashboard | Persönliches Übersichts-Dashboard | +| 54 | MyCentron | Aufgabenliste (ToDo) | src/centron/Centron.WPF.UI/Modules/MyCentron/TodoList, Calendar | Persönliche Aufgaben-/Terminliste | +| 55 | MyCentron | Telefonie-Integration | src/centron/Centron.WPF.UI/Modules/MyCentron/Telephony | Anbindung an Telefonanlage (CTI) | +| 56 | MyCentron | Fernwartungsintegration (Supremo) | src/centron/Centron.WPF.UI/Modules/MyCentron/Supremo | Anbindung des Fernwartungstools Supremo | +| 57 | Statistik | Verkaufsstatistik | src/centron/Centron.WPF.UI/Modules/Statistics/SaleStatistics | Auswertung von Verkaufszahlen | +| 58 | Statistik | Management-Informationen | src/centron/Centron.WPF.UI/Modules/Statistics/ManagementInfo | Kennzahlen-Dashboards für das Management | +| 59 | Statistik | MSP-Statistiken | src/centron/Centron.WPF.UI/Modules/Statistics/MspStatistics, MspCollectors | Auswertung von Managed-Service-Provider-Kennzahlen | +| 60 | Statistik | Mitarbeiteranalyse | src/centron/Centron.WPF.UI/Modules/Statistics/EmployeeAnalytics | Auswertung mitarbeiterbezogener Kennzahlen | +| 61 | Statistik | Reportverwaltung | src/centron/Centron.WPF.UI/Modules/Reports/ReportManagement | Verwaltung/Ausführung hinterlegter Reports | +| 62 | Administration | Rechteverwaltung | src/centron/Centron.WPF.UI/Modules/Administration/RightsManagement | Verwaltung von Benutzerrechten und Rollen (Risikobereich) | +| 63 | Administration | Mitarbeiterverwaltung | src/centron/Centron.WPF.UI/Modules/Administration/EmployeeManagement | Stammdatenverwaltung der Mitarbeitenden inkl. Rechtezuordnung | +| 64 | Administration | Mandantenverwaltung | src/centron/Centron.WPF.UI/Modules/Administration/MandatorManagement | Verwaltung mehrerer Mandanten (Multi-Tenant-Fähigkeit) | +| 65 | Administration | DSGVO-Funktionen | src/centron/Centron.WPF.UI/Modules/Administration/DSGVO | Werkzeuge zur Umsetzung datenschutzrechtlicher Pflichten (Risikobereich) | +| 66 | Administration | Systemeinstellungen | src/centron/Centron.WPF.UI/Modules/Administration/Settings, Customization, Cache, Profiling | Allgemeine Systemkonfiguration | +| 67 | Administration | Verbindungs-/Schnittstelleneinstellungen | src/centron/Centron.WPF.UI/Modules/Administration/Connections, WebServiceSettings, SqlManagers, CentronConfigDb | Konfiguration von DB-/Webservice-Verbindungen | +| 68 | Administration | Kommunikationseinstellungen | src/centron/Centron.WPF.UI/Modules/Administration/MailAndCalender, MailTemplates, PhoneSettings | Konfiguration von E-Mail-/Kalender-/Telefonanbindung | +| 69 | Administration | Belegwesen-Konfiguration | src/centron/Centron.WPF.UI/Modules/Administration/PdfExport, PdfSigning, ReceiptConditions, TextBlockManagement, ReportServer | Konfiguration von PDF-Erzeugung/-Signatur, Textbausteinen, Reportserver | +| 70 | Administration | Stundensätze/Zuschläge | src/centron/Centron.WPF.UI/Modules/Administration/HourlySurchargeRates | Pflege von Stundenverrechnungssätzen und Zuschlägen | +| 71 | Administration | Eskalationseinstellungen | src/centron/Centron.WPF.UI/Modules/Administration/EscalationsSettings | Konfiguration von SLA-Eskalationsregeln | +| 72 | Administration | Länderverwaltung | src/centron/Centron.WPF.UI/Modules/Administration/CountryManagement | Pflege von Länderstammdaten | +| 73 | Administration | Service-/Leasing-/SEPA-Verträge | src/centron/Centron.WPF.UI/Modules/Administration/ServiceAndLeasing, SepaContract | Verwaltung von Service-/Leasingverträgen und SEPA-Lastschriftmandaten (Risikobereich) | +| 74 | Administration | Externe Werkzeuge | src/centron/Centron.WPF.UI/Modules/Administration/ExternalTools, Modules/ExternalTool | Einbindung externer Zusatzwerkzeuge | +| 75 | Administration | WebCart-Konfiguration | src/centron/Centron.WPF.UI/Modules/Administration/WebCart | Konfiguration des Web-Shops für Kunden | +| 76 | Administration | Sonstige Prozesseinstellungen | src/centron/Centron.WPF.UI/Modules/Administration/TaskManagmentSettings, UpdateAvailableNotificationSettings, SendDeliveryListShippingConfirmationSettings | Verschiedene Prozess-Konfigurationsschalter | +| 77 | Administration | Log-Betrachter | src/centron/Centron.WPF.UI/Modules/Administration/LogViewer | Einsicht in Anwendungs-Logdateien | +| 78 | Administration | Dienste-Verwaltung | src/centron/Centron.WPF.UI/Modules/Administration/Services | Verwaltung von Hintergrunddiensten | +| 79 | OnlineBanking | Kontoumsätze | src/centron/Centron.WPF.UI/Modules/OnlineBanking/AccountTransactions | Abruf und Zuordnung von Kontoumsätzen (Risikobereich) | +| 80 | OnlineBanking | OnlineBanking-Konfiguration | src/centron/Centron.WPF.UI/Modules/OnlineBanking/ConfigurationSettings | Konfiguration der Bankverbindungen | +| 81 | OnlineBanking | OnlineBanking-Verbindungsdialog | src/centron/Centron.WPF.UI/Modules/OnlineBanking/ConnectionDialog | Verbindungsaufbau zu Banken (FinTS/HBCI) | +| 82 | Querschnitt | KI-Unterstützung | src/centron/Centron.WPF.UI/Modules/ArtificialIntelligence | KI-gestützter Chat, Angebotspositions-Editor, Textbewertung (OpenAI-Anbindung) | +| 83 | Querschnitt | Umfragen | src/centron/Centron.WPF.UI/Modules/Survey | Erstellung/Auswertung von Kundenumfragen | +| 84 | Querschnitt | Massenänderungen | src/centron/Centron.WPF.UI/Modules/Massenupdates | Massenhaftes Aktualisieren von Datensätzen | +| 85 | Querschnitt | Passwortverwaltung | src/centron/Centron.WPF.UI/Modules/PasswordManager | Sichere Ablage von Zugangsdaten (Risikobereich) | +| 86 | Querschnitt | Kalender | src/centron/Centron.WPF.UI/Modules/Calendar | Terminverwaltung | +| 87 | Querschnitt | Qualitätsmanagement | src/centron/Centron.WPF.UI/Modules/QM | QM-Prüfprozesse | +| 88 | Querschnitt | Telekom-DIVE-Integration (UI) | src/centron/Centron.WPF.UI/Modules/TelekomDive | Anbindung an die Telekom-DIVE-Plattform | +| 89 | Querschnitt | Startdashboard | src/centron/Centron.WPF.UI/Modules/Dashboard | Konfigurierbares Startbildschirm-Dashboard | +| 90 | Querschnitt | Oberflächenprofile | src/centron/Centron.WPF.UI/Modules/Gui | Verwaltung von Layout-/Oberflächenprofilen je Benutzer | +| 91 | Querschnitt | Cross-cutting Dialoge (Global) | src/centron/Centron.WPF.UI/Modules/Global | Wiederverwendbare Dialoge (Mitarbeiterauswahl, Videoportal, Netzwerkdiagnose, Lizenzabgleich) | +| 92 | Backend-Kern | Geschäftslogik-/Datenzugriffsschicht | src/backend/Centron.BL, Centron.DAO, Centron.Entities, Centron.Interfaces, Centron.Common | Fachliche Kernlogik, Datenbankzugriff und Entitätsmodell, von allen UI-Modulen genutzt | +| 93 | Backend-Kern | EDI-Lieferantenanbindungen | src/backend/Centron.Gateway/EDI_Also, EDI_AlsoCH, EDI_Alltron, EDI_Herweck, EDI_Komsa, EDI_EGIS | Elektronischer Datenaustausch (Bestellung/Lieferschein/Rechnung) mit Distributoren | +| 94 | Backend-Kern | Banking-Gateway (Backend) | src/backend/Centron.Gateway/OnlineBanking | Technische Anbindung an Bankschnittstellen (FinTS) | +| 95 | Backend-Kern | MSP-Collector-Gateway | src/backend/Centron.Gateway/MspCollector | Sammeln von Gerätedaten bei Managed-Service-Anbietern (Octopus, Wortmann) | +| 96 | Backend-Kern | E-Rechnungsformate | src/backend/Centron.Gateway/OpenTrans, OpenTrans1_0, ZUGFeRD21_Extended | Erzeugen/Verarbeiten strukturierter Rechnungsformate | +| 97 | Backend-Kern | Portal-Gateway | src/backend/Centron.Gateway/Portal | Anbindung an den c-entron Portal-Webservice | +| 98 | Webservice | Zentrale Web-API | src/webservice/Centron.WebServices.Core, Centron.Controllers, Centron.Host, Host.Console, Host.WindowsService | Bereitstellung der c-entron-Funktionalität als Webservice/REST-Schnittstelle für externe/mobile Clients | +| 99 | Webservice | Lizenz-/Verbindungsmanager | src/webservice/c-entron.misc.ConnectionManager | Verwaltung von Lizenzen/Hardware-IDs für Webservice-Verbindungen | +| 100 | Nexus (Web) | ServiceBoard (Web-Ticketboard) | src/nexus/CentronNexus/ServiceBoard | Web-basierte Ticket-/Kanban-Oberfläche für den technischen Support | +| 101 | Nexus (Web) | Nexus Office/Kundenportal (WebCart) | src/nexus/CentronNexus/Office | Web-Kundenportal inkl. Bestell-/Shopfunktion (WebCart) | +| 102 | Nexus (Web) | Web-Fertigungsauftragsverwaltung | src/nexus/CentronNexus/ProductionOrderManagement | Weboberfläche zur Fertigungsauftragssteuerung | +| 103 | Nexus (Web) | Nexus-Verwaltung | src/nexus/CentronNexus/Management | Verwaltung von Web-Benutzerkonten, Aufgaben und Ticketmustern | +| 104 | Nexus (Web) | Dokumentensignatur (Web) | src/nexus/CentronNexus/DocumentSigning | Elektronische Signatur von Dokumenten im Web | +| 105 | Nexus (Web) | Outlook-Add-in | src/nexus/CentronNexus.OutlookAddIn | Integration von c-entron-Funktionen in Microsoft Outlook | +| 106 | Externe APIs | Produktdaten-Anreicherungs-APIs | src/apis/Centron.APIs.CopDataAccess, EgisDataAccess, ITscopeDataAccess, IcecatDataAccess | Abruf von Produktstamm-/Katalogdaten bei externen Datenlieferanten | +| 107 | Externe APIs | Bankanbindung FinAPI | src/apis/Centron.APIs.FinAPI | Kontoinformationsabruf über den Drittanbieter FinAPI (Risikobereich) | +| 108 | Externe APIs | E-Rechnung Österreich | src/apis/Centron.Api.EbInterface | Erstellung von ebInterface-E-Rechnungen (österreichischer Standard) | +| 109 | Externe APIs | Versanddienstleister-Schnittstellen | src/apis/Centron.Api.Gls, Centron.Api.Shipcloud | Anbindung an Paketversanddienstleister (Label-/Sendungsdaten) | +| 110 | Datenaustausch | PDF-Formulargenerierung (docuFORM) | Centron.Api.docuFORM, src/centron/.../Modules/DataExchange/DocuForm | Dynamische PDF-Formularerzeugung aus Belegdaten | +| 111 | Datenaustausch | Datenimport (allgemein) | src/centron/Centron.WPF.UI/Modules/DataExchange/DataImport | Generischer Import von Fremddaten in c-entron | +| 112 | Datenaustausch | Buchhaltungsexport | src/centron/Centron.WPF.UI/Modules/DataExchange/BookKeeping | Export von Buchungsdaten an Finanzbuchhaltungssysteme | +| 113 | Datenaustausch | DATEV-Anbindung | src/centron/Centron.WPF.UI/Modules/DataExchange/DatevOnline2020 | Direkter Datenaustausch mit DATEV | +| 114 | Datenaustausch | SEPA-Zahlungsverkehrsdatei | src/centron/Centron.WPF.UI/Modules/DataExchange/PaymentTransactions | Erzeugung von SEPA-Zahlungs-/Lastschriftdateien (Risikobereich) | +| 115 | Datenaustausch | Telekom-DIVE-Datenaustausch | src/centron/Centron.WPF.UI/Modules/DataExchange/TelekomDive | Datenaustausch mit der Telekom-DIVE-Plattform | +| 116 | Datenaustausch | Datenexport (allgemein) | src/centron/Centron.WPF.UI/Modules/DataExchange/DataExport | Genereller Export von c-entron-Daten | +| 117 | Datenaustausch | Sonstige Schnittstellen | src/centron/Centron.WPF.UI/Modules/DataExchange/Connectors, DocSync, Rmm, SupplierOrderPerBranch | Weitere Konnektoren (Remote Monitoring, filialweise Lieferantenbestellung) | +| 118 | Betrieb | Deployment & Betrieb | deployment/, docker/, azure/, azure-blazor/ | Build-, Container- und Pipeline-Konfiguration für Auslieferung und Betrieb | + +**118 Inventarzeilen.** Datenbankschema (`SSMS_DB_SCHEMA.sql`) ist kein eigenständiges Modul, sondern durchgängig als Belegquelle für Datenmodell/Constraints in den obigen Zeilen herangezogen. + +## Abdeckungstabelle + +Einstufung je Inventarzeile: **tief** (Anforderung auf mehreren Ebenen mit StRS→SyRS/SwRS-Kette und mindestens einem PRIMÄR-Beleg vertieft), **mittel** (genau eine Anforderung, aber mit PRIMÄR-Beleg), **flach** (genau eine Anforderung, nur SEKUNDÄR/KONTEXT-Belege), **nicht analysiert** (kein Beleg möglich). „Anzahl Anforderungen" zählt alle StRS/SyRS/SwRS-Anforderungen, die diesem Modul unmittelbar zugeordnet sind (bei modulübergreifend geteilten SyRS/SwRS – z. B. SwRS-5 für Opos/Payments oder SwRS-7/SyRS-10 für RightsManagement/Nexus – bei jedem beteiligten Modul mitgezählt). + +| Nr | Modul | Einstufung | Anzahl Anforderungen | +|----|-------|------------|------------------------| +| 1 | Sales – Sonderpreise/Mailing | tief | 3 (StRS-1, SyRS-2, SwRS-3) | +| 2 | CRM/Adressstamm | tief | 3 (StRS-2, SyRS-1, SwRS-1) | +| 3 | Kampagnenmanagement | tief | 2 (StRS-3, SwRS-2 [HYPOTHESE]) | +| 4 | CRM-Stammdatenlisten | flach | 1 | +| 5 | Vertragsverwaltung & -auswertung | flach | 1 | +| 6 | Projektverwaltung (Finanzsicht) | flach | 1 | +| 7 | Zählerstandserfassung (MPS) | mittel | 1 | +| 8 | Produktlebenszyklus-Management | flach | 1 | +| 9 | Zahler-/Kostenstellenverwaltung | mittel | 1 | +| 10 | Projektpreisimport | flach | 1 | +| 11 | Projektmanagement (allgemein) | flach | 1 | +| 12 | Belegbearbeitung Kern | tief | 2 (StRS-12, SyRS-5 [HYPOTHESE]) | +| 13 | Anzahlungen | tief | 2 (StRS-13, SyRS-3) | +| 14 | Steuersatzänderung im Beleg | tief | 2 (StRS-14, SwRS-4) | +| 15 | Provisionsermittlung | mittel | 1 | +| 16 | Web-Angebote | flach | 1 | +| 17 | EDI-Auftragsverbuchung | flach | 1 | +| 18 | Automatisierte Rechnungserstellung | mittel | 1 | +| 19 | Pauschalabrechnung (Flatrate) | flach | 1 [HYPOTHESE] | +| 20 | Zeit-/Leistungsabrechnung (Timer) | flach | 1 [HYPOTHESE] | +| 21 | Mahnwesen | tief | 2 (StRS-21, SyRS-4) | +| 22 | Offene Posten | tief | 2 (StRS-22, SwRS-5) | +| 23 | Zahlungsverkehr (Payments) | tief | 2 (StRS-23, SwRS-5 geteilt) | +| 24 | Kontenverwaltung (Buchhaltung) | flach | 1 | +| 25 | Warenausgangszahlungen | flach | 1 | +| 26 | Kassensystem-Anbindung | mittel | 1 | +| 27 | Artikelstammdaten | flach | 1 | +| 28 | Artikelimport | flach | 1 | +| 29 | Mengeneinheitenverwaltung | mittel | 1 | +| 30 | Barcode-Verwaltung | flach | 1 | +| 31 | Kommissionierung | flach | 1 | +| 32 | Kommissionsware/Konsignation | flach | 1 | +| 33 | Inventur | flach | 1 | +| 34 | Warengruppenverwaltung | mittel | 1 | +| 35 | Artikelsuche | flach | 1 | +| 36 | Lieferantensuche | flach | 1 | +| 37 | Logistikeinstellungen/Versandarten | flach | 1 | +| 38 | EDI-Bestellwesen | flach | 1 | +| 39 | Bestellvorschlagsliste | flach | 1 | +| 40 | Einkaufseinstellungen | flach | 1 | +| 41 | Reisekostenabrechnung | mittel | 1 | +| 42 | Fertigungsauftragsverwaltung | flach | 1 | +| 43 | Maschinenverwaltung | flach | 1 | +| 44 | RMA-Abwicklung | mittel | 1 | +| 45 | Ticketverwaltung | flach | 1 | +| 46 | Helpdesk-Dashboard | flach | 1 | +| 47 | Wartungsverträge/erwartete Ereignisse | mittel | 1 | +| 48 | Helpdesk-Einstellungen | flach | 1 | +| 49 | Helpdesk Sonstiges | flach | 1 | +| 50 | CentronInspectors | mittel | 1 | +| 51 | Persönliche Einstellungen (Access-Token) | tief | 3 (StRS-51, SyRS-6, SyRS-7) | +| 52 | Mein Tag (MyDay) | flach | 1 | +| 53 | MyCentron-Dashboard | flach | 1 | +| 54 | Aufgabenliste (ToDo) | flach | 1 | +| 55 | Telefonie-Integration | flach | 1 | +| 56 | Fernwartungsintegration (Supremo) | flach | 1 | +| 57 | Verkaufsstatistik | flach | 1 | +| 58 | Management-Informationen | flach | 1 | +| 59 | MSP-Statistiken | flach | 1 | +| 60 | Mitarbeiteranalyse | flach | 1 | +| 61 | Reportverwaltung | flach | 1 | +| 62 | Rechteverwaltung | tief | 5 (StRS-62, SyRS-8 [HYPOTHESE-Anteil], SyRS-9, SyRS-10, SwRS-6, SwRS-7) | +| 63 | Mitarbeiterverwaltung | flach | 1 | +| 64 | Mandantenverwaltung | flach | 1 | +| 65 | DSGVO-Funktionen | mittel | 1 | +| 66 | Systemeinstellungen | flach | 1 | +| 67 | Verbindungs-/Schnittstelleneinstellungen | flach | 1 | +| 68 | Kommunikationseinstellungen | flach | 1 | +| 69 | Belegwesen-Konfiguration | flach | 1 | +| 70 | Stundensätze/Zuschläge | flach | 1 | +| 71 | Eskalationseinstellungen | flach | 1 | +| 72 | Länderverwaltung | flach | 1 | +| 73 | Service-/Leasing-/SEPA-Verträge | mittel | 1 | +| 74 | Externe Werkzeuge | flach | 1 | +| 75 | WebCart-Konfiguration | flach | 1 | +| 76 | Sonstige Prozesseinstellungen | flach | 1 | +| 77 | Log-Betrachter | flach | 1 | +| 78 | Dienste-Verwaltung | flach | 1 | +| 79 | Kontoumsätze | flach | 1 | +| 80 | OnlineBanking-Konfiguration | flach | 1 | +| 81 | OnlineBanking-Verbindungsdialog | flach | 1 | +| 82 | KI-Unterstützung | flach | 1 | +| 83 | Umfragen | flach | 1 | +| 84 | Massenänderungen | flach | 1 | +| 85 | Passwortverwaltung | tief | 2 (StRS-85, SwRS-8) | +| 86 | Kalender | flach | 1 | +| 87 | Qualitätsmanagement | flach | 1 | +| 88 | Telekom-DIVE-Integration (UI) | flach | 1 | +| 89 | Startdashboard | flach | 1 | +| 90 | Oberflächenprofile | flach | 1 | +| 91 | Cross-cutting Dialoge (Global) | flach | 1 | +| 92 | Geschäftslogik-/Datenzugriffsschicht | flach | 1 | +| 93 | EDI-Lieferantenanbindungen | mittel | 1 | +| 94 | Banking-Gateway (Backend) | flach | 1 | +| 95 | MSP-Collector-Gateway | flach | 1 | +| 96 | E-Rechnungsformate | mittel | 1 | +| 97 | Portal-Gateway | flach | 1 | +| 98 | Zentrale Web-API | tief | 2 (StRS-98, SyRS-10 geteilt) | +| 99 | Lizenz-/Verbindungsmanager | flach | 1 | +| 100 | ServiceBoard (Web-Ticketboard) | flach | 1 | +| 101 | Nexus Office/Kundenportal (WebCart) | tief | 2 (StRS-101, SwRS-7 geteilt) | +| 102 | Web-Fertigungsauftragsverwaltung | flach | 1 | +| 103 | Nexus-Verwaltung | mittel | 1 | +| 104 | Dokumentensignatur (Web) | flach | 1 [HYPOTHESE] | +| 105 | Outlook-Add-in | flach | 1 | +| 106 | Produktdaten-Anreicherungs-APIs | flach | 1 | +| 107 | Bankanbindung FinAPI | flach | 1 | +| 108 | E-Rechnung Österreich | flach | 1 | +| 109 | Versanddienstleister-Schnittstellen | flach | 1 | +| 110 | PDF-Formulargenerierung (docuFORM) | flach | 1 | +| 111 | Datenimport (allgemein) | flach | 1 | +| 112 | Buchhaltungsexport | flach | 1 | +| 113 | DATEV-Anbindung | flach | 1 | +| 114 | SEPA-Zahlungsverkehrsdatei | mittel | 1 | +| 115 | Telekom-DIVE-Datenaustausch | flach | 1 | +| 116 | Datenexport (allgemein) | flach | 1 | +| 117 | Sonstige Schnittstellen | flach | 1 | +| 118 | Deployment & Betrieb | mittel | 1 | + +**Summe:** 118 Module, 0 „nicht analysiert" (Mindestabdeckung zu 100 % erreicht) · 14 tief · 18 mittel · 86 flach. Gesamtanzahl Anforderungen: **136** (118 StRS + 10 SyRS + 8 SwRS). + +## Konsistenzcheck + +- **Doppelte/mehrfach vergebene IDs:** Keine gefunden. StRS-1 bis StRS-118 sind lückenlos und eindeutig vergeben (verifiziert per Durchsuchung aller `ID:`-Zeilen in StRS.md). SyRS-1 bis SyRS-10 und SwRS-1 bis SwRS-8 sind ebenfalls eindeutig; SyRS-10 steht aus editortechnischen Gründen physisch vor SyRS-8/SyRS-9 in der Datei (Einfügereihenfolge), was die Eindeutigkeit der IDs nicht beeinträchtigt, aber beim manuellen Lesen auffällt. +- **Anforderungen ohne Beleg:** Keine gefunden. Jede der 136 Anforderungen enthält mindestens einen Eintrag unter `Belege:` (automatisiert gegengeprüft: 118 `Belege:`-Vorkommen in StRS.md stehen exakt 118 `ID:`-Vorkommen gegenüber, keine leere Belege-Sektion). +- **Anforderungen ohne Angabe zur Übernahmewürdigkeit:** Keine gefunden (automatisiert gegengeprüft, jede `Übernahmewürdigkeit:`-Zeile ist gefüllt). +- **Tracelinks auf nicht existierende IDs:** Keine gefunden. Alle in `Tracelinks:`-Feldern referenzierten IDs (siehe `Traceability.md`) liegen innerhalb der belegten Bereiche StRS-1..118, SyRS-1..10, SwRS-1..8. +- **Inhaltlich deckungsgleiche Anforderungen ohne Konsolidierungsvermerk:** Bei der Erstellung wurden 23 Konsolidierungskandidaten aktiv identifiziert und im Feld `Konsolidierung` vermerkt (u. a. StRS-4/StRS-7 Zählerstandserfassung doppelt, StRS-32 Kommissionsware vs. Provision-Namensverwechslung, StRS-62/StRS-103 getrennte Rechtemodelle intern/Web, StRS-65/StRS-73 DSGVO-AVV/SEPA nahezu identischer Signatur-Workflow, StRS-93 sechsfache EDI-Implementierung, StRS-106 vierfache Produktdaten-API, StRS-96/StRS-108 dreifaches E-Rechnungsformat). Ein manueller Nachvergleich der übrigen 95 flach/mittel eingestuften Anforderungen auf **nicht erkannte** Deckungsgleichheit wurde aus Zeitgründen nicht durchgeführt; hierin liegt ein Restrisiko (siehe Selbstbewertung). +- **Korrektur während der Erhebung:** Zwei Inventar-Fehleinschätzungen aus Schritt 0 wurden während der Erhebung selbst korrigiert, statt sie unkommentiert zu übernehmen: Zeile 15 (Provision) enthielt ursprünglich fälschlich den Pfad „PartialCommission", der tatsächlich zu Kommissionsware (Zeile 32) gehört; Zeile 50 (CentronInspectors) war ursprünglich fälschlich als Prüfmittelverwaltung statt als Dateninspektions-Framework beschrieben. Beide Korrekturen sind im Modulinventar oben nachvollziehbar vermerkt. +- **Nachträglich behobene Regelverstöße (Belegpflicht bei Risikoanforderungen):** Bei der Selbstprüfung wurden drei Anforderungen mit Typ „Sicherheit" bzw. Fakturierungsbezug gefunden, die ursprünglich als `belegt` ohne PRIMÄR-Beleg geführt waren (StRS-19 Pauschalabrechnung, StRS-20 Zeitabrechnung, StRS-104 Web-Dokumentensignatur). Alle drei wurden korrigiert und tragen jetzt `Status: HYPOTHESE` mit expliziter Begründung; sie sind in `Hypothesen.md` nachgeführt. + +### Liste aller risikorelevanten Anforderungen (Sicherheit, Abrechnung/Fakturierung, Berechtigungen) + +| ID | Titel | PRIMÄR-Beleg vorhanden? | Status | +|----|-------|--------------------------|--------| +| StRS-62 | Gruppenbasierte Rechtevergabe | Ja | belegt | +| SyRS-8 | Serverseitige Rechteprüfung mit Cache | Ja (für Prüfung selbst), Cache-Invalidierung unbelegt | HYPOTHESE | +| SyRS-9 | Admin-Gruppen-Schutz | Ja | belegt | +| SwRS-6 | Sichtrus/Sichmemb-Datenmodell | Ja | belegt | +| SwRS-7 | Getrennte Web-Rechte | Ja | belegt | +| StRS-98 | Web-API duale Authentifizierung | Ja | belegt | +| SyRS-10 | Duale API-Authentifizierung | Ja | belegt | +| StRS-51 | Personal-Access-Token | Ja | belegt | +| SyRS-6 | Pflicht-Ablaufdatum Token | Ja | belegt | +| SyRS-7 | Serverseitige Ablaufprüfung Token | Ja | belegt | +| StRS-85 | Passwortverwaltung AES-Verschlüsselung | Ja | belegt | +| SwRS-8 | AES-Verschlüsselung Master-Key | Ja | belegt | +| StRS-65 | DSGVO/AVV/Löschrechte | Ja | belegt | +| StRS-104 | Web-Dokumentensignatur | Nein (nur SEKUNDÄR) | **HYPOTHESE** | +| SwRS-2 | Rechteabhängige Kampagnenfunktionen | Nein (nur SEKUNDÄR) | **HYPOTHESE** | +| SyRS-5 | Nebenläufigkeitsschutz Belege | Nein (nur SEKUNDÄR/Feldexistenz) | **HYPOTHESE** | +| StRS-13 | Anzahlung → Schlussrechnung | Ja | belegt | +| StRS-14 | Steuersatzänderung | Ja | belegt | +| StRS-15 | Provisionsermittlung (Überschreibschutz) | Ja | belegt | +| StRS-18 | Automatisierte Rechnungserstellung | Ja | belegt | +| StRS-19 | Pauschalabrechnung | Nein (nur SEKUNDÄR) | **HYPOTHESE** | +| StRS-20 | Zeit-/Leistungsabrechnung | Nein (nur SEKUNDÄR) | **HYPOTHESE** | +| StRS-21 | Mahnwesen (Mahnstopp) | Ja | belegt | +| SyRS-4 | Mahnfähigkeit serverseitig | Ja | belegt | +| StRS-22 | Offene Posten (OpenPrice-Formel) | Ja | belegt | +| StRS-23 | Zahlungserfassung | Ja | belegt | +| StRS-26 | Kassensystem-Steuerkonten | Ja | belegt | +| StRS-73 | SEPA-Mandate (Signatur-Workflow) | Ja | belegt | +| StRS-114 | SEPA-Zahlungsdatei (pain.008) | Ja | belegt | + +**Ergebnis:** 29 risikorelevante Anforderungen identifiziert. Davon tragen 23 (79 %) einen PRIMÄR-Beleg und sind `belegt`; 6 (21 %) sind korrekt als `[HYPOTHESE]` gekennzeichnet (SyRS-8 mit Einschränkung: die Rechteprüfung selbst ist PRIMÄR belegt, die zusätzliche Aussage zur Cache-Invalidierung nicht, daher in Summe HYPOTHESE). Keine risikorelevante Anforderung ist ohne PRIMÄR-Beleg als `belegt` geführt (nach den oben dokumentierten Korrekturen). + +### Abgleich Hypothesen.md gegen Inline-Markierungen + +Automatisiert geprüft: `Hypothesen.md` führt genau die 6 Anforderungen, die in StRS.md/SyRS.md/SwRS.md mit `Status: HYPOTHESE` markiert sind (SyRS-5, SyRS-8, SwRS-2, StRS-19, StRS-20, StRS-104) – keine zusätzliche, keine fehlende. Offene Punkte ohne unmittelbaren Anforderungsbezug (z. B. generelle Unsicherheit über Cache-Ablaufzeiten) stehen ausschließlich in der Selbstbewertung unten, nicht in `Hypothesen.md`. + +## Selbstbewertung + +**Tiefenverteilung:** Von 118 Inventarmodulen wurden 14 **tief** (mehrstufige StRS→SyRS/SwRS-Kette, überwiegend mit PRIMÄR-Beleg), 18 **mittel** (eine Anforderung mit PRIMÄR-Beleg) und 86 **flach** (eine Anforderung mit SEKUNDÄR-/KONTEXT-Beleg) analysiert. **0 Module sind „nicht analysiert"** – die in Schritt 0b geforderte Mindestabdeckung (mindestens eine Anforderung je Modul) wurde für alle 118 Module erreicht. + +**Mindestabdeckung erreicht:** Ja, vollständig. Jedes Modul aus dem Inventar (Schritt 0) trägt mindestens eine Anforderung mit mindestens einem Beleg. + +**Wo war der Beleg dünn:** Die 86 „flach" eingestuften Module stützen sich überwiegend auf SEKUNDÄR-/KONTEXT-Belege (Klassenexistenz, Ordnerstruktur, Namensgebung) statt auf durchsetzende Stellen (PRIMÄR). Das ist in dieser Breitenphase eine bewusste, im Auftrag so vorgesehene Priorisierung („Breite geht vor Tiefe") und kein Zufallsergebnis: Für alle Module mit Bezug zu Sicherheit, Abrechnung/Fakturierung oder Berechtigungen wurde gezielt nach PRIMÄR-Belegen gesucht (siehe Risikoliste oben, 79 % PRIMÄR-Quote), während bei fachlich unkritischeren Modulen (z. B. Kalender, Umfragen, Log-Betrachter, Startdashboard) die Existenzbestätigung über Klassenstruktur als für die Mindestabdeckung ausreichend erachtet wurde. Am dünnsten belegt sind die rein technischen Querschnittsmodule (92 Geschäftslogikschicht, 97 Portal-Gateway, 99 Lizenzmanager) sowie mehrere Nexus-Teilbereiche (100, 102, 105), da hier aus Zeitgründen jeweils nur eine repräsentative Klasse gesichtet wurde, obwohl die zugrundeliegenden Projekte (z. B. Centron.BL mit 2.068 Dateien) erheblich umfangreicher sind. + +**Warum die Hypothesenzahl (6 von 136, 4,4 %) vergleichsweise niedrig ausfällt:** In der Breitenphase (Schritt 0b) wurden Aussagen bewusst eng an das tatsächlich Beobachtete formuliert – „Klasse X belegt Funktion Y" statt „System garantiert Y" –, sodass für die meisten Anforderungen SEKUNDÄR-/KONTEXT-Belege ausreichten, ohne dass eine unbelegte, risikorelevante Aussage entstand, die zwingend `[HYPOTHESE]` erfordert hätte. Die vorhandenen 6 Hypothesen entstanden ausnahmslos dort, wo in der gezielten Risikovertiefung (Schritt 0c) oder bei der abschließenden Selbstprüfung eine serverseitige Durchsetzungsstelle gesucht, aber nicht gefunden wurde (Cache-Invalidierung bei Rechteänderung, Konfliktbehandlung bei Nebenläufigkeit, Kampagnen-Rechteprüfung, Pauschal-/Zeitabrechnungsformel, Web-Signatur-Versiegelung). Eine Vertiefung der 86 „flach" eingestuften Module würde nach bisherigem Muster voraussichtlich weitere Hypothesen zutage fördern, insbesondere überall dort, wo bislang nur eine ViewModel-Klasse, nicht aber die zugehörige BL-Methode gesichtet wurde. + +**Erkenntnisse für eine Folge-Iteration:** +1. **MandatorManagement/Mandantentrennung (Modul 64) vertiefen.** Bislang nur strukturell (Firmendaten, Filialen) belegt; die eigentliche Sicherheitsfrage – wie wird verhindert, dass ein Mandant Daten eines anderen Mandanten sieht (Datenbank-Filterung nach MandatorI3D, Zeilenebene vs. Anwendungsebene) – wurde nicht geprüft und ist für ein SaaS-Zielsystem mit gemeinsamer Infrastruktur mehrerer Mandanten sicherheitskritisch. +2. **TimerBilling/FlatrateBilling-Berechnungslogik lokalisieren** (StRS-19/20, aktuell HYPOTHESE) – vermutlich in `Centron.BL/Sales/CustomerAssets/TimerBilling` oder einer noch nicht gesichteten Nachbarklasse. +3. **Web-Dokumentensignatur-Versiegelung (StRS-104) und Rechte-Cache-Invalidierung (SyRS-8) klären** – beide sicherheitsrelevant und aktuell HYPOTHESE. +4. **Konsolidierungskandidaten priorisieren und quantifizieren:** Die 23 gefundenen Fälle (siehe oben) sollten in einer Folge-Iteration mit Aufwandsschätzung für die Zusammenführung versehen werden, beginnend bei den am klarsten belegten Fällen (SEPA/DSGVO-Signatur-Workflow, sechsfache EDI-Anbindung, vierfache Produktdaten-API). +5. **86 „flach" eingestufte Module gezielt auf SwRS-Ebene ergänzen**, insbesondere die datenintensiven Kernmodule Warehousing/ArticleManagement (320 Dateien, aber nur 1 Anforderung) und Finances/Receipts-Kern (794 Dateien, nur StRS-12), deren Umfang die aktuelle Abdeckungstiefe deutlich übersteigt. +6. **Manueller Deckungsgleichheits-Check der 95 nicht aktiv auf Konsolidierung geprüften Anforderungen** (siehe Konsistenzcheck), da bei einer Codebasis dieser Größe weitere, bislang unentdeckte Dopplungen wahrscheinlich sind. diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/Glossar.md b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/Glossar.md new file mode 100644 index 00000000..4cbb431a --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/Glossar.md @@ -0,0 +1,32 @@ +# Glossar + +Domänenbegriffe, wie sie in den Anforderungen verwendet werden. Technische Bezeichner (Klassen/Methoden/Spalten) bleiben in Originalsprache. + +| Begriff | Bedeutung im Kontext c-entron | +|---------|-------------------------------| +| Beleg / Belegkette | Sammelbegriff für Angebot, Auftrag, Lieferschein, Rechnung, Gutschrift, Bestellung; technisch getrennte Kopftabellen (`AngKopf`, `AufKopf`, `LiefKopf`, `RechKopf`, `GutKopf`, `BestKopf`), fachlich eine zusammenhängende Verarbeitungskette (siehe StRS-12). | +| Anzahlung / Anzahlungsrechnung | Vor der Schlussrechnung gestellte Teilrechnung zu einem Auftrag; wird bei Erstellung der Schlussrechnung vom Gesamtbetrag abgezogen (StRS-13). | +| Sonderpreis (Special Price) | Kunden- bzw. kundenklassenspezifischer, vom Listenpreis abweichender Artikelpreis mit Gültigkeitszeitraum (`AccountSpecialPriceDTO`); Grundlage sowohl für die klassische Vertriebspreisfindung (StRS-1) als auch für den WebCart-Shop (StRS-75). | +| Kontingent | Im Vertrag hinterlegte Mengenobergrenze für eine Leistung/einen Artikel, gegen die der tatsächliche Verbrauch aus Belegen gegengerechnet wird (StRS-5). | +| Kommissionsware / Konsignation | Ware, die einem Kunden zur Ansicht/zum Verbrauch überlassen wird, ohne dass zum Übergabezeitpunkt bereits eine Rechnung gestellt wird; Abrechnung erfolgt erst bei tatsächlichem Verbrauch/Verkauf (Modul „Warehousing/Commissions", StRS-32). Nicht zu verwechseln mit „Provision" (siehe dort). | +| Provision | Verkäuferbezogene Vergütung auf Basis abgeschlossener Belege, gesteuert über Provisionsschemata (Modul „Finances/Receipts/Provision", StRS-15). Im Quellcode weckt der Ordnername „PartialCommission" (Finances/Receipts) durch die englische Doppelbedeutung von „Commission" Verwechslungsgefahr mit „Kommissionsware" – „PartialCommission" gehört fachlich zu Letzterem (siehe Korrekturhinweis in Analysebericht.md, Zeile 15 des Inventars). | +| Offene Posten (Opos) | Noch nicht vollständig ausgeglichene Rechnungsbeträge; `OpenPrice` wird zentral aus Bruttobetrag (bzw. Nettobetrag bei nicht ausweisbarer USt.), bereits gezahltem Betrag und Währungsfaktor berechnet (StRS-22). | +| Mahnstopp / Mahnstufe | Am Rechnungskopf geführtes Flag (`MahnStop`) bzw. Zähler (`Mahnstufe`), das eine Rechnung zeitweise oder dauerhaft vom automatisierten Mahnlauf ausschließt bzw. deren Mahnfortschritt dokumentiert (StRS-21). | +| Zahler / Kostenstelle / Kostenobjekt | Vom Rechnungsempfänger abweichende Instanz, die einen Beleg wirtschaftlich trägt (Zahler), bzw. interne Verrechnungseinheiten für Kosten (Kostenstelle/-objekt) (StRS-9). | +| AVV (Auftragsverarbeitungsvertrag) | Datenschutzrechtlich (Art. 28 DSGVO) erforderlicher Vertrag mit Auftragsverarbeitern; im System als digitaler Signatur-Workflow mit Vorlagen abgebildet (StRS-65), strukturell nahezu identisch mit dem SEPA-Mandats-Workflow (StRS-73). | +| Recht / Rechtegruppe (Sichtrus/Sichmemb) | Internes RBAC-Modell: Rechte (`AppRight`) werden ausschließlich Gruppen (`AppGroup`) zugewiesen (Tabelle `Sichtrus`), Benutzer werden Gruppen zugeordnet (Tabelle `Sichmemb`); ein Benutzer besitzt die Vereinigungsmenge der Rechte all seiner Gruppen (StRS-62). Getrennt davon existiert ein strukturell ähnliches, aber eigenständiges Rechtemodell für Web-Accounts (`WebRights`). | +| Web-Account | Eigenständiges Login für externe Personen (Kunden, Web-Shop-Nutzer), technisch getrennt vom internen Mitarbeiter-Login (`AppUser`) samt eigenem Rechtemodell (siehe „Recht"). | +| I3D | Durchgängige Namenskonvention für den Primärschlüssel/die eindeutige ID einer Entität in c-entron (z. B. `accountI3D`, `articleI3D`); technischer Bezeichner, bleibt in Originalform. | +| Stammblatt | Im Altbestand verwendete Bezeichnung für ein verwaltetes Gerät (z. B. Drucker) mit Zählerstandshistorie; fachlich Teil des in dieser Analyse dokumentierten Gerätelebenszyklus (PLM, DeviceClickCounter). | +| RMA | Return Merchandise Authorization – Rücksendeprozess für reklamierte/defekte Ware (StRS-44). | +| PLM | Product Lifecycle Management – Verwaltung von Produktfamilien und deren Lebenszyklusphasen, hier zusätzlich auf einzelne ausgelieferte Geräte angewendet (StRS-8). | +| MSP | Managed Service Provider – Geschäftsmodell, bei dem c-entron-Kunden IT-Dienstleistungen für ihre eigenen Endkunden erbringen; das System sammelt hierzu Gerätedaten externer MSP-Plattformen (StRS-59, StRS-95). | +| EDI | Electronic Data Interchange – strukturierter elektronischer Geschäftsdatenaustausch (Bestellung, Lieferschein, Rechnung) mit Distributoren (StRS-38, StRS-93). | +| ZUGFeRD / openTRANS / ebInterface | Strukturierte E-Rechnungsformate; ZUGFeRD (hybrides PDF+XML, Standard „CrossIndustryInvoice"), openTRANS (älterer XML-Standard), ebInterface (österreichischer E-Rechnungsstandard) – im System parallel implementiert (StRS-96, StRS-108). | +| SEPA (pain.008) | Single Euro Payments Area – einheitlicher europäischer Zahlungsverkehrsraum; `pain.008` ist der ISO-20022-Nachrichtentyp für SEPA-Lastschriften (StRS-114). | +| DATEV | Weit verbreitete deutsche Software/Datenaustauschformat für Steuerberater und Finanzbuchhaltung (StRS-113). | +| FinTS/HBCI | Standardisiertes deutsches Online-Banking-Protokoll für den automatisierten Kontoabruf (StRS-79, StRS-94). | +| Belegwesen / Fakturierung | Sammelbegriff für die Erstellung und Verwaltung kaufmännischer Belege (Angebot bis Rechnung) bzw. speziell den Rechnungsstellungsprozess. | +| AccountType | Fachliche Rollenzuweisung eines Adressstamm-Datensatzes (`Account`), z. B. „Customer" (Kunde), „Supplier" (Lieferant); ein Account kann mehrere AccountTypes gleichzeitig besitzen (StRS-2). | +| Mandant / Filiale | Mandant = rechtlich eigenständige Unternehmenseinheit im Mehrmandantenbetrieb; Filiale = organisatorische Untereinheit eines Mandanten mit eigenem Belegnummernkreis (StRS-64). | + diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/Hypothesen.md b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/Hypothesen.md new file mode 100644 index 00000000..1f77ef99 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/Hypothesen.md @@ -0,0 +1,15 @@ +# Hypothesen + +Sammlung aller mit `[HYPOTHESE]` markierten Anforderungen. Diese Liste ist deckungsgleich mit den Inline-Markierungen in StRS/SyRS/SwRS (keine zusätzlichen freien Fragen ohne zugehörige Anforderung – offene Punkte ohne Anforderungsbezug stehen in der Selbstbewertung in `Analysebericht.md`). + +| ID | Titel | Offene Frage / fehlende Information zur Bestätigung | +|----|-------|-------------------------------------------------------| +| SyRS-5 | Nebenläufige Bearbeitung von Belegen durch Sperr- und Versionskennung absichern | `RechKopf` führt `LockUser` und die GUID-Spalte `GUI3D`; belegt ist damit nur die Existenz der Felder. Nicht lokalisiert wurde die Schreibstelle, die beim Speichern eines Belegs die aktuelle mit der beim Laden gelesenen GUID/dem LockUser vergleicht und bei Abweichung den Speichervorgang abweist. Zur Bestätigung fehlt: die konkrete Save-Methode in Centron.BL/Centron.DAO für Belegköpfe (z. B. `RechKopfBL.Save`) mit ihrer Konfliktprüfung. | +| SyRS-8 | Serverseitige Rechteprüfung mit benutzerbezogenem Cache | `AppRightsBL.HasUserRight()` cacht Rechte je Benutzer unter dem Schlüssel `AllRightsFromAppUser{appUserI3D}`. Nicht lokalisiert wurde ein Aufruf, der diesen Cache-Eintrag gezielt invalidiert, wenn sich die Gruppenzuordnung eines Benutzers oder die Rechte einer Gruppe ändern (z. B. in `SaveAndAssignGroupToRight`/`RemoveAssignGroupToRight`). Zur Bestätigung fehlt: Einsicht in die Cache-Implementierung (`Session.Advanced.Cache`) und deren Ablaufzeit/Invalidierungsstrategie. | +| SwRS-2 | Rechteabhängige Freigabe von Kampagnenfunktionen | `CampaignMainViewModel` führt die Felder `UserCanEditCampaign`/`UserCanOpenCampaign`, die vermutlich aus einer Rechteprüfung stammen. Nicht lokalisiert wurde die serverseitige Stelle, die diese Flags setzt bzw. die bei einem direkten Service-Aufruf (unter Umgehung der UI) das Bearbeiten/Öffnen einer Kampagne ohne Recht tatsächlich verhindert. Zur Bestätigung fehlt: die Backend-Methode, die beim Speichern/Öffnen einer Kampagne das zugehörige Recht prüft (analog zu `AppRightsBL.HasUserRight`). | +| StRS-19 | Pauschale Projektleistungen abrechnen | Die Existenz eines eigenständigen Pauschalabrechnungs-Moduls (`FlatRateProjectAppModuleController`) ist belegt, nicht aber die BL-seitige Berechnungsstelle, die den Pauschalbetrag unabhängig von erfassten Stunden in die Rechnung übernimmt. Da es sich um Fakturierungslogik handelt, ist ohne PRIMÄR-Beleg zwingend `[HYPOTHESE]` zu setzen. Zur Bestätigung fehlt: die Business-Logic-Klasse, die die Rechnungsposition aus dem Pauschalpreis erzeugt. | +| StRS-20 | Erfasste Zeiten/Leistungen verrechnen | `TimerBillingViewModel` und `TimerBillingBL.cs` existieren; die konkrete Formel (Stundensatz × erfasste Dauer, inkl. Zuschlägen aus StRS-70) wurde in `TimerBillingBL.cs` nicht lokalisiert. Zur Bestätigung fehlt: die Berechnungsmethode in `TimerBillingBL` bzw. der aufgerufenen Rechnungspositions-Erzeugung. | +| StRS-104 | Elektronische Dokumentensignatur im Web mit Signaturstil-Auswahl | Belegt ist nur die Auswahl von Signaturstil/-farbe (`SignatureType` u. a.). Nicht lokalisiert wurde die Stelle, die die Signatur manipulationssicher/rechtsverbindlich in das Dokument einbettet. Zur Bestätigung fehlt: die serverseitige Signatur-Versiegelungslogik in `CentronNexus/DocumentSigning`, ggf. mit Bezug zu `PdfSigningBL` (StRS-69). | + +**Hinweis zur Menge:** Bei einer Codebasis dieser Größe (>15.000 Dateien) mit vollständiger Modulabdeckung, aber notwendig selektiver Vertiefung (Schritt 0c), ist eine Hypothesenzahl von 6 (von 136 Anforderungen, 4,4 %) zunächst niedrig. Der Grund: In der Breitenphase (Schritt 0b) wurden Aussagen bewusst eng an das tatsächlich Beobachtete formuliert (z. B. „Klasse belegt X" statt „System garantiert X"), sodass für die meisten Anforderungen SEKUNDÄR-/KONTEXT-Belege ausreichten, ohne dass eine unbelegte, risikorelevante Aussage entstand, die eine `[HYPOTHESE]`-Kennzeichnung erzwungen hätte. Echte Hypothesen entstanden dort, wo in der Vertiefungsphase (Schritt 0c) eine serverseitige Durchsetzungsstelle gezielt gesucht, aber nicht gefunden wurde. Weitere, tiefer liegende Hypothesen sind bei einer Vertiefung der in der Selbstbewertung (`Analysebericht.md`) genannten Module wahrscheinlich (insbesondere MandatorManagement/Mandantentrennung, EmployeeManagement-Rechtezuordnung, ServiceAndLeasing). + diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/StRS.md b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/StRS.md new file mode 100644 index 00000000..65df0506 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/StRS.md @@ -0,0 +1,2398 @@ +# Stakeholder Requirements Specification (StRS) – c-entron ERP-Suite + +Nach ISO/IEC/IEEE 29148:2018. Fachliche Sicht: Akteure, Geschäftsziele, Stakeholder-Bedürfnisse. Jede Anforderung folgt dem in `Analysebericht.md` referenzierten Blockformat (siehe Prompt-Vorgabe). IDs: `StRS-`, laufend über alle Module. + +--- + +``` +ID: StRS-1 +Titel: Kundenspezifische Sonderpreise und Serienmail +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertriebsmitarbeiter +Vorbedingung: Kunde/Adresse ist im Adressstamm angelegt +Fakt: Eigenständiges Modul mit Klassen ProductMatrixSettingsViewModel, ProductMatrixDialogViewModel, MailingTemplateViewModel und SpecialArticleImportAppModuleController zur Pflege kundenbezogener Artikelmatrizen, Sonderpreise und Serienmail-Vorlagen +Aussage: Das System soll es Vertriebsmitarbeitern ermöglichen, kundenspezifische Sonderpreise über eine Produktmatrix zu pflegen, per Import zu übernehmen und Serienmails auf Basis hinterlegter Vorlagen an Kunden zu versenden. +Ergebnis: Kundenspezifische Sonderpreise sind hinterlegt und stehen in der Belegerfassung zur Verfügung; Serienmails werden anhand der Vorlage erzeugt +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Sales/ProductMatrixSettingsViewModel.cs - Begründung: Klassenname und Ort belegen eine dedizierte Pflegeoberfläche für Produktmatrizen + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Sales/MailingTemplateViewModel.cs - Begründung: Eigenständige Vorlagenverwaltung für Serienmails im Vertriebsmodul + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Sales/SpecialArticleImportAppModuleController.cs - Begründung: Controller-Klasse belegt einen eigenen Importprozess für Sonderartikel/-preise +Prüfidee: Für einen Kunden eine Sonderpreiszeile in der Produktmatrix anlegen und prüfen, dass der Preis bei Neuanlage eines Belegs für diesen Kunden gezogen wird +Tracelinks: SyRS-2 (Belegkalkulation zieht Sonderpreise) +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - kundenindividuelle Preisfindung ist im Fachhandel/IT-Systemhaus-Geschäft eine Kernanforderung +Status: belegt +``` + +``` +ID: StRS-2 +Titel: Konfigurierbare Pflichtfelder bei Umwandlung eines Adressstamm-Datensatzes in einen Kunden +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertriebsmitarbeiter +Vorbedingung: Ein Adressstamm-Datensatz (Account) ohne AccountType "Customer" ist im CRM geöffnet +Fakt: MakeCustomerViewModel.CanAccept() (Zeilen 244-293) prüft bis zu 20 mandantenspezifisch konfigurierbare Pflichtfelder (u. a. E-Mail, Kundenklassifikation, Vertriebsgebiet, Berater 1-4, Buchhaltungssammelkonto, Zahlungsbedingung, Anrede/Vor-/Nachname/E-Mail des Ansprechpartners), gesteuert über Flags aus CrmSettings/CurrentAccount (z. B. IsAccountEmailRequired, IsClassificationRequired); erst wenn alle aktiven Pflichtfelder gesetzt sind, wird der AccountType "Customer" angelegt (Accept(), Zeile 365-370) +Aussage: Das System soll beim Anlegen eines Kunden aus einem bestehenden Adressstamm-Datensatz eine mandantenspezifisch konfigurierbare Menge an Pflichtfeldern erzwingen und den Kundentyp erst nach vollständiger Eingabe anlegen. +Ergebnis: Der Account erhält den AccountType "Customer" nur, wenn alle konfigurierten Pflichtfelder befüllt sind; andernfalls bleibt der Dialog offen (AcceptCommand bleibt deaktiviert) +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Finances/Crm/MakeCustomerViewModel.cs, Methode CanAccept() (Z. 244-293) - Begründung: Durchsetzende Stelle, die den Speichern-Befehl (AcceptCommand) genau dann sperrt, wenn ein konfiguriertes Pflichtfeld fehlt + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Finances/Crm/MakeCustomerViewModel.cs, Methode Accept()/SaveToModel() (Z. 296-370) - Begründung: Legt den AccountType "Customer" erst nach bestandener CanAccept()-Prüfung im Modell an +Prüfidee: CrmSettings.CountServerRequired aktivieren, Feld "Anzahl Server" leer lassen und prüfen, dass "Übernehmen" deaktiviert bleibt; danach Feld befüllen und Übernahme prüfen +Tracelinks: SyRS-1, SwRS-1 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - konfigurierbare Pflichtfeldprüfung bei Kundenanlage ist fachlich zentral für Datenqualität +Status: belegt +``` + +``` +ID: StRS-3 +Titel: Vertriebskampagnen planen und durchführen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertriebsmitarbeiter / Marketing +Vorbedingung: Zielgruppe von Adressen/Kunden ist im CRM verfügbar +Fakt: CampaignMainViewModel unterscheidet Kampagnen nach Status (LoadPlannedCampaigns, LoadOpenCampaigns, LoadClosedCampaigns) und führt rechteabhängige Flags UserCanEditCampaign/UserCanOpenCampaign (Z. 34-40) +Aussage: Das System soll Vertriebskampagnen mit den Zuständen geplant, offen und abgeschlossen verwalten und die Bearbeitungs-/Öffnungsrechte je Benutzer steuern. +Ergebnis: Kampagnen sind nach Status filterbar; nur berechtigte Benutzer können eine Kampagne bearbeiten oder öffnen +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Finances/Campaigns/CampaignMainViewModel.cs (Z. 31-40) - Begründung: Felder belegen Statusfilterung und rechteabhängige UI-Steuerung, jedoch ohne Einsicht in die serverseitige Rechteprüfung selbst +Prüfidee: Kampagne im Status "Geplant" anlegen, in "Offen" überführen und mit einem Benutzer ohne Bearbeitungsrecht prüfen, dass die Bearbeitung verweigert wird +Tracelinks: SwRS-2 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kampagnensteuerung mit Statuslebenszyklus ist Standardfunktion im CRM-Umfeld +Status: belegt +``` + +``` +ID: StRS-4 +Titel: Massenpflege von Zählerständen über CRM-Stammdatenlisten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Innendienst/Vertriebsmitarbeiter +Vorbedingung: Geräte mit Zählerstand-Historie sind einem Kundenvertrag zugeordnet +Fakt: Finances/MasterDataLists/Counters enthält CounterViewModel, CounterWithPriceViewModel, NewCounterViewModel und NewCounterValueViewModel zur listenbasierten Erfassung neuer Zählerstände inkl. Preisbezug +Aussage: Das System soll die listenbasierte Erfassung neuer Zählerstände für mehrere Geräte/Verträge in einer Stammdatenliste ermöglichen. +Ergebnis: Neue Zählerstände sind je Gerät erfasst und stehen der Abrechnung zur Verfügung +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Finances/MasterDataLists/Counters/NewCounterValueViewModel.cs - Begründung: Eigene ViewModel-Klasse für die Erfassung eines neuen Zählerstandswertes belegt die Listenerfassung + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Finances/MasterDataLists/Counters/CounterWithPriceViewModel.cs - Begründung: Verknüpfung von Zählerstand und Preis als Namensbestandteil +Prüfidee: In der Stammdatenliste für mehrere Geräte gleichzeitig neue Zählerstände erfassen und die Übernahme in die Gerätehistorie prüfen +Tracelinks: keine +Konsolidierung: Kandidat: StRS-7 - beide Implementierungen erfassen Zählerstände für Geräte (Finances/MasterDataLists/Counters vs. Finances/DeviceClickCounter), getrennt implementiert für Listenerfassung bzw. Einzelerfassung/Import +Übernahmewürdigkeit: Workaround - Funktion überschneidet sich fachlich mit dem dedizierten DeviceClickCounter-Modul (siehe StRS-7); im Zielsystem zu einer Zählerstandserfassung zusammenzuführen +Status: belegt +``` + +``` +ID: StRS-5 +Titel: Kundenverträge mit Positionen, Kontingent und Controlling verwalten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertriebsinnendienst +Vorbedingung: Kunde ist im Adressstamm angelegt +Fakt: ContractTabKind (Enum) gliedert einen Vertrag in die Bereiche Position, ArticleReferences, Contingent, Controlling und MasterDataLists; ContractsManagementViewModel/ContractsAppModuleController bilden die zugehörige Verwaltungsoberfläche; Modul liegt parallel in den Ständen ContractEvaluation2 und ContractEvaluationOld vor +Aussage: Das System soll Kundenverträge mit Positionen, referenzierten Artikeln, Mengenkontingenten und Controlling-Kennzahlen verwalten und auswerten können. +Ergebnis: Ein Vertrag mit Positionen, Kontingent und Controlling-Sicht ist angelegt und auswertbar +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Finances/Contracts/ContractTabKind.cs - Begründung: Enum-Werte belegen die fachlichen Bestandteile eines Vertrags aus Sicht der Oberfläche + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Finances/Contracts/ContractsManagementViewModel.cs - Begründung: Zentrale Verwaltungsklasse referenziert dieselben Vertragsbestandteile +Prüfidee: Vertrag mit Kontingent anlegen, Verbrauch über Belege buchen und die Controlling-Auswertung auf korrekten Resteinsatz prüfen +Tracelinks: keine +Konsolidierung: Kandidat: Prüfen, ob ContractEvaluation2 und ContractEvaluationOld denselben fachlichen Umfang parallel abbilden (siehe Analysebericht, Konsistenzcheck) +Übernahmewürdigkeit: übernehmen - Vertragskontingente und -controlling sind zentral für das Servicegeschäft; ContractEvaluationOld voraussichtlich veraltet zugunsten ContractEvaluation2 +Status: belegt +``` + +``` +ID: StRS-6 +Titel: Kaufmännische Projektverwaltung mit Abschlusswahrscheinlichkeit +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertriebsmitarbeiter/Projektleiter +Vorbedingung: Projekt ist einem Kunden zugeordnet +Fakt: ProjectProbabilitiesViewModel sowie ProjectOverviewViewModel/ProjectAccountViewModel/ProjectContactViewModel bilden Projektstammdaten inkl. Abschlusswahrscheinlichkeit und Gantt-Ansicht (CrmProjectGantTaskViewModel) ab +Aussage: Das System soll Projekte mit kaufmännischen Stammdaten, Ansprechpartnern, Abschlusswahrscheinlichkeit und einer Terminplanung (Gantt) verwalten. +Ergebnis: Projekt ist mit Wahrscheinlichkeit und Terminplan erfasst und in der Vertriebs-Pipeline auswertbar +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Finances/Projects/ProjectProbabilitiesViewModel.cs - Begründung: Eigene Klasse für Abschlusswahrscheinlichkeiten belegt die Pipeline-Bewertung von Projekten + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Finances/Projects/CrmProjectGantTaskViewModel.cs - Begründung: Klassenname belegt eine Gantt-Terminplanung je Projekt +Prüfidee: Projekt mit Abschlusswahrscheinlichkeit 50% anlegen und prüfen, dass es in einer nach Wahrscheinlichkeit gewichteten Pipeline-Auswertung korrekt einfließt +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Projekt-Pipeline mit Wahrscheinlichkeiten ist gängige Vertriebssteuerung +Status: belegt +``` + +``` +ID: StRS-7 +Titel: Zählerstandserfassung für Managed-Print-Geräte inkl. automatisiertem Import +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Innendienst / automatisierter Prozess +Vorbedingung: Gerät (Stammblatt) ist einem Vertrag oder einer Seriennummer zugeordnet +Fakt: HistoryBy-Enum unterscheidet die Herkunft eines Zählerstands nach Contract, Device, Barcode oder Import; Unterordner DocuFormApiImport (DocuFormApiImportViewModel, DocuFormDeviceModel, DownloadLogModel) belegt einen automatisierten Abruf von Zählerständen über die docuFORM-API +Aussage: Das System soll Zählerstände von Managed-Print-Geräten sowohl manuell je Vertrag/Gerät/Seriennummer als auch automatisiert über eine externe API importieren und historisieren. +Ergebnis: Zählerstand ist dem Gerät zugeordnet, historisiert und für die Abrechnung (siehe SwRS zu AutomatedBilling/FlatrateBilling) verfügbar +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Finances/DeviceClickCounter/HistoryBy.cs - Begründung: Enum legt die zulässigen Herkunftsarten eines historisierten Zählerstands fest + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Finances/DeviceClickCounter/DocuFormApiImport/DocuFormApiImportViewModel.cs - Begründung: Klasse belegt einen dedizierten automatisierten Importweg über eine externe API +Prüfidee: Zählerstand über den DocuForm-API-Import einlesen und prüfen, dass er in der Gerätehistorie mit Herkunft "Import" erscheint +Tracelinks: keine +Konsolidierung: Kandidat: StRS-4 - fachlich dieselbe Funktion (Zählerstandserfassung) wie Finances/MasterDataLists/Counters, getrennt implementiert +Übernahmewürdigkeit: übernehmen - automatisierter Zählerstandsabruf ist Voraussetzung für MPS-Abrechnung; manuelle Doppelpflege (siehe StRS-4) im Zielsystem konsolidieren +Status: belegt +``` + +``` +ID: StRS-8 +Titel: Produktlebenszyklus je ausgeliefertem Gerät verfolgen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertriebsmitarbeiter +Vorbedingung: Artikel/Gerät wurde über eine Rechnung an einen Kunden ausgeliefert +Fakt: ProductLifecycleInformationViewModel (Z. 20-60) verknüpft eine Lebenszyklus-Information mit Rechnung (invoiceI3D/invoiceItemI3D/invoiceNumber), Artikel (articleI3D/articleCode), Barcode/Seriennummer sowie StartDate/EndDate/ProductFamilyLifetimeInMonths und einem Deaktivierungs-Flag IsDeactivated +Aussage: Das System soll für jedes an einen Kunden verkaufte Gerät eine Lebenszyklusspanne (Start-/Enddatum, Produktfamilien-Lebensdauer) führen und diese für proaktive Vertriebsansprache (z. B. Ersatzangebot) nutzbar machen. +Ergebnis: Gerät ist mit Lebenszyklusspanne und Bezug zur Ursprungsrechnung erfasst +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/PLM/ProductLifecycleInformationViewModel.cs (Z. 20-60) - Begründung: Feldmodell belegt die Verknüpfung von Gerät, Rechnung und Lebenszyklusspanne; kein DB-Constraint eingesehen, daher sekundär +Prüfidee: Gerät mit ProductFamilyLifetimeInMonths=36 zulaufen lassen und prüfen, dass 36 Monate nach Rechnungsdatum ein Hinweis/Ersatzangebot auslösbar ist +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Lebenszyklussteuerung ist Grundlage für wiederkehrendes Ersatzgeschäft (MPS/IT-Handel) +Status: belegt +``` + +``` +ID: StRS-9 +Titel: Zahler und Kostenstellen für Belege abweichend vom Kunden erfassen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Innendienst +Vorbedingung: Beleg wird für einen Kunden mit abweichender Kostenstellenstruktur erstellt +Fakt: AddCostCenterOrPayersViewModel.DoAddToSave() (Z. 63-78) legt je nach Flag PayersViewModel einen CostObjectDTOViewModel (Zahler) oder CostCentreDTOViewModel (Kostenstelle) mit Nummer, Bezeichnung und Status=1 (aktiv) an +Aussage: Das System soll die Erfassung von Zahlern und Kostenstellen/-objekten unabhängig vom Rechnungsempfänger ermöglichen, damit Belege einer abweichenden Kostenstelle zugeordnet werden können. +Ergebnis: Neuer Zahler bzw. neue Kostenstelle ist mit Status "aktiv" verfügbar und im Beleg auswählbar +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/PayersAndCostCenter/OpenDialog/AddCostCenterOrPayersViewModel.cs, Methode DoAddToSave() (Z. 63-78) - Begründung: Durchsetzende Stelle, die Zahler und Kostenstelle als getrennte Objekttypen mit Pflichtfeldern Nummer/Bezeichnung anlegt +Prüfidee: Kostenstelle "K100" anlegen und in einem Beleg auswählen; prüfen, dass Rechnungsadresse und Kostenstelle unabhängig voneinander änderbar sind +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kostenstellen-/Zahlertrennung wird von Geschäftskunden (öffentlicher Sektor, Konzernkunden) regelmäßig gefordert +Status: belegt +``` + +``` +ID: StRS-10 +Titel: Projektpreislisten importieren und gegen Sonderkonditionen abgleichen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertriebsmitarbeiter/Einkauf +Vorbedingung: Neue Projekt-/Lieferantenpreisliste liegt als Importdatei vor +Fakt: DifferenceViewModel (Z. 16-50) vergleicht importierte Preise mit bestehenden Sonderkonditionen des Kunden (CustomerToSelectedSpecialAgreement) und erzeugt eine Liste SpecialAgreementDifferenceViewModel, die per SendMailCommand als Datei versendet werden kann +Aussage: Das System soll importierte Projektpreislisten automatisiert gegen bestehende kundenspezifische Sonderkonditionen abgleichen, Abweichungen ausweisen und den Abgleichsbericht per E-Mail versendbar machen. +Ergebnis: Preisdifferenzen zwischen Import und bestehender Sonderkondition sind aufgelistet und als Bericht versendet +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/ProjectPriceImport/PriceDifference/DifferenceViewModel.cs (Z. 16-50) - Begründung: Klasse belegt Abgleichslogik und Mailversand-Befehl, jedoch ohne Einsicht in die konkrete Abweichungsberechnung selbst +Prüfidee: Preisliste mit einer vom bestehenden Sonderpreis abweichenden Zeile importieren und prüfen, dass sie in der Differenzliste erscheint und die E-Mail-Funktion den Bericht anhängt +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - automatisierter Preisabgleich reduziert manuelle Pflegefehler bei Projektkonditionen +Status: belegt +``` + +``` +ID: StRS-11 +Titel: Mitarbeiterauslastung über Projekte und Tickets hinweg planen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Projektleiter/Disponent +Vorbedingung: Mitarbeitende sind Projekten und/oder Tickets zugeordnet +Fakt: ProjectManagementViewModel.RefreshEmployeeWorkload() (Z. 245-260) baut je Mitarbeiter ein EmployeeProjectWorkloadInfoViewModel auf Basis von Projekt- und Ticketzuordnungen (ProjectTicketItemViewModel, TicketEmployeeViewModel) auf +Aussage: Das System soll die Auslastung einzelner Mitarbeitender über zugeordnete Projekte und Tickets hinweg konsolidiert darstellen, um Kapazitätsplanung zu unterstützen. +Ergebnis: Auslastungsübersicht je Mitarbeiter ist auf Basis aktueller Projekt- und Ticketzuordnungen verfügbar +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/ProjectManagement/ProjectManagementViewModel.cs, Methode RefreshEmployeeWorkload() (Z. 245-260) - Begründung: Methode berechnet die dargestellte Auslastung; Detailformel nicht vollständig eingesehen, daher sekundär statt primär +Prüfidee: Mitarbeiter zwei Projekten mit überlappendem Zeitraum zuordnen und prüfen, dass die Auslastungsanzeige eine Überbuchung erkennbar macht +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kapazitätsplanung ist Grundlage für Projektzusagen im Servicegeschäft; Abgrenzung zu StRS-6 (kaufmännische Projektsicht) beachten - hier: personelle Kapazitätssicht +Status: belegt +``` + +``` +ID: StRS-12 +Titel: Durchgängige Belegkette Angebot–Auftrag–Lieferschein–Rechnung +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertriebsinnendienst +Vorbedingung: Kunde und Artikel sind erfasst +Fakt: Datenbankschema führt getrennte Kopftabellen je Belegart (u. a. AngKopf=Angebot, AufKopf=Auftrag, LiefKopf=Lieferschein, GutKopf=Gutschrift, BestKopf=Bestellung; SSMS_DB_SCHEMA.sql Z. 2613, 11571, 31816, 66569, 66781); ReceiptSearchFilter.ReceiptKinds (CentronObjectKindNumeric) unterscheidet u. a. OrderClass, DeliveryListClass, InvoiceClass als Weiterverarbeitungsstufen; OrderToFinalInvoiceHelper.CreateOriginReceiptsToForward() verfolgt je Position QuantityProcessed gegen QuantityComplete, um unvollständig weiterverarbeitete Positionen zu identifizieren +Aussage: Das System soll eine durchgängige, positionsscharf nachverfolgte Belegkette von Angebot über Auftrag und Lieferschein bis zur Rechnung führen, in der jede Position ihren Weiterverarbeitungsstand (verarbeitete/vollständige Menge) behält. +Ergebnis: Aus einem Ausgangsbeleg lassen sich Folgebelege erzeugen, wobei bereits verarbeitete Mengen nicht doppelt weiterverarbeitet werden +Belege: + - [PRIMÄR] SSMS_DB_SCHEMA.sql, Zeilen 2613 (LiefKopf), 11571 (GutKopf), 31816 (BestKopf), 66569 (AngKopf), 66781 (AufKopf) - Begründung: Getrennte Kopftabellen je Belegart belegen das Datenmodell der Belegkette + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Finances/Receipts/DownPayment/FinalInvoice/OrderToFinalInvoiceHelper.cs, Methode CreateOriginReceiptsToForward() (Z. 74-90) - Begründung: Durchsetzende Stelle, die anhand von QuantityProcessed/QuantityComplete je Position ermittelt, was noch weiterzuverarbeiten ist +Prüfidee: Auftrag mit zwei Positionen anlegen, eine Position teilweise in einen Lieferschein überführen und prüfen, dass beim nächsten Weiterverarbeitungsschritt nur die Restmenge vorgeschlagen wird +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - durchgängige, mengenscharfe Belegkette ist Kernanforderung jedes ERP-Auftragsprozesses +Status: belegt +``` + +``` +ID: StRS-13 +Titel: Anzahlungsrechnungen bei der Schlussrechnung berücksichtigen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertriebsinnendienst/Buchhaltung +Vorbedingung: Zu einem Auftrag wurden eine oder mehrere Anzahlungsrechnungen gestellt +Fakt: OrderToFinalInvoiceHelper.LoadRelatedDownPaymentInvoices() (Z. 27-47) sucht über ReceiptSearchFilter.DownPaymentForOrderI3D gezielt alle zu einem Auftrag gehörenden Anzahlungsrechnungen (ReceiptKind InvoiceClass) und lädt sie für die Schlussrechnungserstellung +Aussage: Das System soll bei Erstellung der Schlussrechnung zu einem Auftrag automatisch alle zugehörigen Anzahlungsrechnungen ermitteln, damit deren Beträge bei der Schlussrechnung berücksichtigt werden können. +Ergebnis: Schlussrechnung wird unter Kenntnis aller bereits gestellten Anzahlungen zum Auftrag erzeugt +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Finances/Receipts/DownPayment/FinalInvoice/OrderToFinalInvoiceHelper.cs, Methode LoadRelatedDownPaymentInvoices() (Z. 27-47) - Begründung: Durchsetzende Stelle, die über einen Suchfilter gezielt Anzahlungsrechnungen zu einem Auftrag ermittelt, bevor die Schlussrechnung erzeugt wird +Prüfidee: Auftrag mit zwei Anzahlungsrechnungen anlegen, Schlussrechnung erzeugen und prüfen, dass beide Anzahlungsbeträge im Schlussrechnungsbeleg ausgewiesen/abgezogen werden +Tracelinks: SyRS-3, StRS-12 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Anzahlungsverrechnung ist eine buchhalterisch zwingende Funktion +Status: belegt +``` + +``` +ID: StRS-14 +Titel: Steuersatzänderung auf länderspezifisch gültige Sätze beschränken +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertriebsinnendienst +Vorbedingung: Beleg mit Position ist geöffnet, Steuersatz soll nachträglich geändert werden +Fakt: ChangeTaxRateViewModel.InitializeAsync() (Z. 41-48) lädt die gültigen Steuersätze ausschließlich über IValueAddedTaxLogic.GetVATByCountry(DefaultCountry.I3D) und CanOk() (Z. 51-54) lässt die Übernahme nur zu, wenn ein SelectedTaxRate aus dieser Liste gesetzt ist +Aussage: Das System soll bei der nachträglichen Änderung des Steuersatzes einer Belegposition ausschließlich die für das hinterlegte Land gültigen Steuersätze zur Auswahl anbieten. +Ergebnis: Belegposition erhält nur einen für das Land gültigen Steuersatz +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Finances/Receipts/ChangeTaxRate/ChangeTaxRateViewModel.cs, Methoden InitializeAsync() (Z. 41-48) und CanOk() (Z. 51-54) - Begründung: Durchsetzende Stelle im Dialog, die Auswahl und Übernahme auf die länderspezifische Steuersatzliste beschränkt +Prüfidee: Land mit mehreren gültigen Steuersätzen wählen, Dialog öffnen und prüfen, dass nur diese Sätze auswählbar sind und "OK" ohne Auswahl deaktiviert bleibt +Tracelinks: SwRS-4 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - länderabhängige Steuersatzgültigkeit ist gesetzlich zwingend +Status: belegt +``` + +``` +ID: StRS-15 +Titel: Provisionsschema kontrolliert auf Belege anwenden +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertriebsleitung/Innendienst +Vorbedingung: Provisionsschema ist definiert; Belege im gewählten Zeitraum liegen vor +Fakt: ApplyProvisionToReceiptsViewModel.Ok() (Z. 93-126) fragt bei aktivem ForceOverwriteProvision-Schalter explizit und mit dem Hinweis "Dies lässt sich nicht rückgängig machen!" nach, bevor bereits vorhandene Provisionierungen überschrieben werden; ProvisionStatus (Complete/Incomplete/Empty) kennzeichnet je Beleg den Provisionierungsstand +Aussage: Das System soll die rückwirkende Anwendung eines Provisionsschemas auf bereits provisionierte Belege nur nach expliziter, als unumkehrbar gekennzeichneter Bestätigung zulassen und den Provisionierungsstand je Beleg (vollständig/unvollständig/keine) nachvollziehbar halten. +Ergebnis: Belege erhalten das angewendete Provisionsschema; bestehende Provisionierungen werden nur nach Bestätigung überschrieben +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Finances/Receipts/Provision/Schemas/ApplyProvisionToReceiptsViewModel.cs, Methode Ok() (Z. 93-106) - Begründung: Durchsetzende Stelle, die das Überschreiben bestehender Provisionierungen an eine explizite Bestätigung bindet + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Finances/Receipts/Provision/ProvisionReceiptTab/ProvisionStatus.cs - Begründung: Enum belegt die drei geführten Provisionierungszustände +Prüfidee: Provisionsschema auf bereits provisionierte Belege ohne "Überschreiben"-Schalter anwenden und prüfen, dass diese Belege unverändert bleiben; mit Schalter erneut anwenden und Bestätigungsdialog prüfen +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Schutz vor versehentlichem Überschreiben abrechnungsrelevanter Provisionsdaten ist geschäftskritisch +Status: belegt +``` + +``` +ID: StRS-16 +Titel: Angebote per Weblink für Kunden bereitstellen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Kunde (Web) / Vertriebsmitarbeiter +Vorbedingung: Angebot ist im System erstellt +Fakt: WebOfferForReceiptViewModel sowie WebReceiptItemChangeRequestViewModel und ReceiptCommentViewModel bilden eine Web-Ansicht des Angebots mit Kommentar- und Änderungswunschfunktion für den Kunden ab; GenerateWebOfferViewModel erzeugt den zugehörigen Freigabelink +Aussage: Das System soll Angebote über einen Weblink für Kunden bereitstellen und dem Kunden erlauben, Positionsänderungswünsche und Kommentare zum Angebot zu hinterlegen. +Ergebnis: Kunde kann das Angebot über den Weblink einsehen, kommentieren und Änderungswünsche zu Positionen übermitteln +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Finances/Receipts/WebOffer/WebReceiptItemChangeRequestViewModel.cs - Begründung: Klasse belegt die Möglichkeit kundenseitiger Änderungswünsche zu Positionen + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Finances/Receipts/GenerateWebOffer/GenerateWebOfferViewModel.cs - Begründung: Klassenname belegt die Erzeugung des Freigabelinks, Detailmechanik nicht eingesehen +Prüfidee: Angebot als Weblink generieren, im Kundenkontext öffnen, einen Änderungswunsch zu einer Position hinterlegen und prüfen, dass dieser im Innendienst sichtbar wird +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Web-Angebote mit Kundeninteraktion sind ein wesentliches Argument für die geplante Web-/SaaS-Neuimplementierung +Status: belegt +``` + +``` +ID: StRS-17 +Titel: Elektronisch eingehende Aufträge teilweise oder vollständig verbuchen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Innendienst / automatisierter EDI-Prozess +Vorbedingung: EDI-Auftrag eines Lieferanten/Kunden liegt vor +Fakt: EdiFromOrderViewModel stellt sowohl BookingCommand (Vollbuchung) als auch BookingPartCommand (Teilbuchung) für die Verbuchung eines EDI-Auftrags bereit (Z. 38-39), zugeordnet zu einem auswählbaren SelectedSupplier +Aussage: Das System soll elektronisch eingehende Aufträge wahlweise vollständig oder teilweise gegen den Ausgangsbeleg verbuchen können. +Ergebnis: EDI-Auftrag ist vollständig oder in Teilmengen verbucht +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Finances/Receipts/EdiOrderbooking/EdiFromOrderViewModel.cs (Z. 38-39) - Begründung: Zwei getrennte Befehle belegen die Unterscheidung Voll-/Teilbuchung; die serverseitige Buchungslogik selbst wurde nicht eingesehen +Prüfidee: EDI-Auftrag mit Teilmenge verbuchen und prüfen, dass die Restmenge für eine spätere Nachbuchung offen bleibt +Tracelinks: StRS-12 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Teilverbuchung ist im Lieferantengeschäft mit Teillieferungen Standard +Status: belegt +``` + +``` +ID: StRS-18 +Titel: Verträge automatisiert nach Abrechnungsintervall fakturieren +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung / automatisierter Prozess +Vorbedingung: Vertrag mit hinterlegtem Abrechnungsintervall ist aktiv +Fakt: AutomatedBillingViewModel filtert abzurechnende Verträge über BillingIntervalDuration und BillingIntervalKind (Z. 633-636: „result.Where(f => f.BillingIntervalDuration == filter.IntervalDuration && f.BillingIntervalKind == (BillingIntervalKinds)filter.IntervalKind.Value)“); IsBillingIntervalActive schaltet den Intervallfilter ein/aus +Aussage: Das System soll Verträge mit hinterlegtem Abrechnungsintervall (Art und Dauer) automatisiert selektieren und der periodischen Fakturierung zuführen. +Ergebnis: Zur Abrechnung fällige Verträge sind anhand ihres Intervalls selektiert +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Finances/AutomatedBilling/AutomatedBillingViewModel.cs, Z. 633-636 - Begründung: Durchsetzende Filterstelle, die Verträge anhand von Intervallart und -dauer für die automatisierte Abrechnung selektiert +Prüfidee: Vertrag mit Intervall "monatlich" anlegen und prüfen, dass er im automatisierten Abrechnungslauf nur einmal je Monat erscheint +Tracelinks: StRS-5 (Vertragsverwaltung) +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - periodische automatisierte Fakturierung ist Kern des wiederkehrenden Servicegeschäfts +Status: belegt +``` + +``` +ID: StRS-19 +Titel: Pauschale Projektleistungen abrechnen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Projekt mit Pauschalvereinbarung ist angelegt +Fakt: Eigenständiges AppModul FlatRateProjectAppModuleController mit ModuleName "Pauschalabrechnung" (Z. 17) referenziert Projekte für pauschale Abrechnung, getrennt vom zeitbasierten TimerBilling +Aussage: Das System soll Projekte mit vereinbarter Pauschalvergütung unabhängig von der tatsächlich erbrachten Stundenleistung abrechnen können. +Ergebnis: Pauschalrechnung zum Projekt ist erzeugt +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Finances/FlatrateBilling/FlatRateProjectAppModuleController.cs (Z. 15-19) - Begründung: Modulname und Struktur belegen einen eigenständigen Pauschalabrechnungsprozess; konkrete Berechnungslogik nicht bis zur Belegerzeugung zurückverfolgt + - [HYPOTHESE] Keine durchsetzende Berechnungsstelle für den Pauschalbetrag gefunden - Begründung für Hypothese: Diese Anforderung betrifft Fakturierungslogik und benötigt laut Vorgabe zwingend einen PRIMÄR-Beleg für die durchsetzende Stelle; die BL-seitige Berechnungsklasse (analog zu InvoiceReceiptSearchConfiguration bei Opos, StRS-22) wurde für FlatrateBilling innerhalb dieser Breitenanalyse nicht lokalisiert +Prüfidee: Projekt mit Pauschalpreis abrechnen und prüfen, dass der Rechnungsbetrag unabhängig von den im Projekt erfassten Stunden dem vereinbarten Pauschalbetrag entspricht +Tracelinks: StRS-6 +Konsolidierung: Kandidat: Prüfen, ob FlatrateBilling und TimerBilling (StRS-20) im Zielsystem als zwei Abrechnungsarten eines gemeinsamen Abrechnungsmodells statt getrennter Module abgebildet werden sollten +Übernahmewürdigkeit: übernehmen - Pauschalabrechnung ist gängiges Vertragsmodell im IT-Service +Status: HYPOTHESE +``` + +``` +ID: StRS-20 +Titel: Erfasste Zeiten/Leistungen verrechnen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Zeiterfassungen/Leistungen liegen für einen Kunden/Vertrag vor +Fakt: TimerBillingViewModel (eigenständiges Modul, IViewModelWithLoading) bildet einen dedizierten Abrechnungsprozess für erfasste Zeiten/Leistungen ab, getrennt von FlatrateBilling +Aussage: Das System soll erfasste Zeiten/Leistungen eines Kunden zeitraumbezogen zu einer Rechnung zusammenfassen können. +Ergebnis: Rechnung auf Basis erfasster Zeiten ist erzeugt +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Finances/TimerBilling/TimerBillingViewModel.cs (Z. 23-28) - Begründung: Eigenständige Modulklasse belegt einen getrennten Abrechnungsprozess; die konkrete Stundensatzberechnung wurde innerhalb dieser Analyse nicht bis zur durchsetzenden Stelle zurückverfolgt + - [HYPOTHESE] Keine durchsetzende Berechnungsstelle (Stundensatz × Dauer) gefunden - Begründung für Hypothese: Diese Anforderung betrifft Fakturierungslogik und benötigt laut Vorgabe zwingend einen PRIMÄR-Beleg; TimerBillingBL.cs (src/backend/Centron.BL/Sales/CustomerAssets/TimerBilling) existiert, die konkrete Multiplikationsformel wurde darin jedoch nicht lokalisiert +Prüfidee: Zeiterfassung für einen Kunden anlegen, TimerBilling ausführen und prüfen, dass genau diese Zeiten in der erzeugten Rechnung erscheinen +Tracelinks: keine +Konsolidierung: Kandidat: siehe StRS-19 +Übernahmewürdigkeit: übernehmen - zeitbasierte Abrechnung ist Standard im Servicegeschäft +Status: HYPOTHESE +``` + +``` +ID: StRS-21 +Titel: Mahnlauf unter Berücksichtigung von Mahnstopp und fehlenden Pflichtangaben +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Offene, fällige Rechnung liegt vor +Fakt: DunningItemViewModel.EvaluateSelectionValidity() (Z. 445-469) schließt einen Beleg von der Mahnauswahl aus, wenn keine Adresse, kein Ansprechpartner, ein aktiver Mahnstopp (DunningStopActive) oder bei Rechnungen kein Fälligkeitsdatum vorliegt; auf DB-Ebene führt RechKopf (AK) die Spalten Mahnstufe (DunningLevel) und MahnStop (DunningStop) direkt am Rechnungskopf (InvoiceReceiptSearchConfiguration.cs Z. 86-87); DueDate wird dort bewusst auf NULL gesetzt, wenn AK.FaelligAm <= 2 ist (Z. 56), was exakt die von EvaluateSelectionValidity() geprüfte Bedingung erzeugt +Aussage: Das System soll Rechnungen mit aktivem Mahnstopp, fehlender Adresse/Ansprechpartner oder fehlendem Fälligkeitsdatum automatisch von der Mahnauswahl ausschließen und die Mahnstufe je Rechnung persistent führen. +Ergebnis: Nur mahnfähige Rechnungen (kein Mahnstopp, vollständige Pflichtangaben) werden im Mahnlauf berücksichtigt; ausgeschlossene Belege zeigen den Ausschlussgrund an +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Finances/Dunning/Common/DunningItemViewModel.cs, Methode EvaluateSelectionValidity() (Z. 445-469) - Begründung: Durchsetzende Stelle, die die Mahnfähigkeit je Beleg prüft und Ausschlussgründe erzeugt + - [PRIMÄR] src/backend/Centron.BL/WebServices/Sales/Receipts/ReceiptSearch/InvoiceReceiptSearchConfiguration.cs, Z. 56, 86-87 - Begründung: Persistenzquelle von Mahnstufe, Mahnstopp und bereinigtem Fälligkeitsdatum, auf denen die UI-seitige Prüfung operiert +Prüfidee: Rechnung mit gesetztem MahnStop-Flag in den Mahnlauf einbeziehen und prüfen, dass sie mit Ausschlussgrund "im Mahnstopp" nicht auswählbar ist +Tracelinks: SyRS-4 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Mahnstopp- und Pflichtangabenprüfung ist rechtlich und geschäftlich zwingend vor Mahnungsversand +Status: belegt +``` + +``` +ID: StRS-22 +Titel: Offene Posten mit korrektem Umsatzsteuerausweis und Fremdwährung führen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Rechnung ist gebucht +Fakt: InvoiceReceiptSearchConfiguration.cs, Z. 71-72 berechnet OpenPrice = (Brutto, falls MwstNichtAusweisbar=0, sonst Netto) − (Bezahlt / CurrencyFactor); OpenPriceFC analog in Fremdwährung; OposOverviewViewModel stellt diese offenen Posten dar +Aussage: Das System soll für jede Rechnung einen offenen Betrag führen, der je nach Umsatzsteuerausweisbarkeit brutto oder netto berechnet und um bereits geleistete, währungsumgerechnete Zahlungen vermindert wird. +Ergebnis: Offene-Posten-Liste zeigt je Rechnung den korrekten offenen Betrag in Haus- und Fremdwährung +Belege: + - [PRIMÄR] src/backend/Centron.BL/WebServices/Sales/Receipts/ReceiptSearch/InvoiceReceiptSearchConfiguration.cs, Z. 71-72 - Begründung: Durchsetzende Berechnungsstelle des offenen Betrags in der zentralen Belegsuchabfrage, aus der die Opos-Übersicht speist +Prüfidee: Rechnung mit MwstNichtAusweisbar=1 (z. B. Kleinunternehmerregelung) und Teilzahlung anlegen und prüfen, dass OpenPrice auf Basis des Nettobetrags abzüglich Teilzahlung berechnet wird +Tracelinks: StRS-23 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - korrekte Offene-Posten-Führung inkl. Sonderfall umsatzsteuerbefreiter Rechnungen ist buchhalterisch zwingend +Status: belegt +``` + +``` +ID: StRS-23 +Titel: Zahlungseingänge erfassen und offenen Betrag fortschreiben +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Rechnung mit offenem Betrag liegt vor +Fakt: PaymentsReceiptViewModel.NewAmountPaid (Setter, Z. 39-46) berechnet bei jeder Eingabe Difference = Receipt.OpenPrice − NewAmountPaid; GrossPrice wird als NetPriceComplete + TaxPriceComplete geführt (Z. 28-31) +Aussage: Das System soll bei Erfassung eines Zahlungseingangs den verbleibenden offenen Betrag der Rechnung sofort neu berechnen und anzeigen. +Ergebnis: Nach Eingabe des Zahlbetrags zeigt das System die verbleibende Differenz zum offenen Betrag +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Finances/Payments/PaymentsReceiptViewModel.cs, Z. 39-46 - Begründung: Durchsetzende Stelle der Differenzberechnung bei jeder Zahlungserfassung +Prüfidee: Zahlung kleiner als OpenPrice erfassen und prüfen, dass Difference den korrekten Restbetrag größer 0 anzeigt +Tracelinks: StRS-22 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - sofortige Restbetragsanzeige bei Zahlungserfassung ist Kernfunktion der Debitorenbuchhaltung +Status: belegt +``` + +``` +ID: StRS-24 +Titel: Kontenübersicht mit Belegen und Filialbuchungsnummern je Kunde +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Kunde mit gebuchten Belegen ist angelegt +Fakt: AccountManagementViewModel referenziert IAccountsLogic/ITicketLogic; Unterordner BranchBookKeepingNumbers (BranchBookKeepingNumbersViewModel) und ReceiptControls (ReceiptsOverviewViewModel, ReceiptsListViewModel, ReceiptExcelExportViewModel) belegen eine kontobezogene Belegübersicht mit filialabhängigen Buchhaltungsnummern +Aussage: Das System soll je Kunde eine konsolidierte, filialbezogene Übersicht aller gebuchten Belege mit Exportmöglichkeit bereitstellen. +Ergebnis: Belegübersicht je Kunde und Filiale ist einsehbar und exportierbar +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Finances/AccountManagement/BranchBookKeepingNumbers/BranchBookKeepingNumbersViewModel.cs - Begründung: Klasse belegt filialabhängige Buchhaltungsnummern je Konto + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Finances/AccountManagement/ReceiptControls/ReceiptExcelExportViewModel.cs - Begründung: Klassenname belegt Exportfunktion, Detailmechanik nicht eingesehen +Prüfidee: Kunden mit Belegen aus zwei Filialen öffnen und prüfen, dass die Kontenübersicht beide Filialbuchhaltungsnummern korrekt trennt +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - filialbezogene Kontenführung ist für Mandanten mit mehreren Standorten erforderlich +Status: belegt +``` + +``` +ID: StRS-25 +Titel: Zahlungen im Warenausgang erfassen (z. B. Nachnahme) +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Lager-/Versandmitarbeiter +Vorbedingung: Ware wird im Warenausgang gegen Zahlung übergeben +Fakt: OutgoingPaymentsViewModel mit Actions NewReceiptAction und OpenAccountSystemsAction (Ordner Actions) verknüpft die Warenausgangszahlung direkt mit Belegerzeugung und der Kassensystem-Anbindung (AccountSystems, siehe StRS-26) +Aussage: Das System soll Zahlungen, die bei Warenausgabe entgegengenommen werden, erfassen und mit der Belegerstellung sowie dem angebundenen Kassensystem verknüpfen. +Ergebnis: Warenausgangszahlung ist erfasst und dem zugehörigen Beleg sowie Kassensystem zugeordnet +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Warehousing/OutcomingPayments/Actions/NewReceiptAction.cs - Begründung: Klasse belegt die Verknüpfung von Zahlung und Belegerzeugung im Warenausgang + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Warehousing/OutcomingPayments/Actions/OpenAccountSystemsAction.cs - Begründung: Klasse belegt die direkte Verknüpfung zur Kassensystem-Anbindung +Prüfidee: Warenausgang mit Nachnahmezahlung erfassen und prüfen, dass die Zahlung im verknüpften Kassensystem-Konto erscheint +Tracelinks: StRS-26 +Konsolidierung: nein +Übernahmewürdigkeit: Sonderfall - Nachnahme/Bar-Zahlung im Warenausgang ist ein Restfall des stationären Handels, im SaaS-Zielsystem fachlich zu hinterfragen +Status: belegt +``` + +``` +ID: StRS-26 +Titel: Kassensystem-Konten mit differenzierter Umsatzsteuerbehandlung führen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Kassensystem ist eingerichtet +Fakt: BookKeepingAccountViewModel führt je Konto zwei getrennte Umsatzsteuer-Kontenreferenzen NeedsCustomClearanceVatI3D und WithoutCustomClearanceVatI3D (Z. 14-15) für Fälle mit bzw. ohne Verzollung +Aussage: Das System soll Kassensystem-Konten mit getrennter Umsatzsteuerzuordnung für Geschäftsvorfälle mit und ohne Zollabfertigung führen können. +Ergebnis: Kassenbuchung wird abhängig vom Verzollungsstatus dem richtigen Umsatzsteuerkonto zugeordnet +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Warehousing/AccountSystems/BookKeepingAccountViewModel.cs, Z. 14-15 - Begründung: Datenmodell führt die beiden Steuerkonten als getrennte Felder, was die Unterscheidung an der Kontendefinition selbst durchsetzt +Prüfidee: Kassenkonto mit unterschiedlichen Werten für beide Felder anlegen und eine Buchung mit und ohne Zollabfertigung durchführen; prüfen, dass jeweils das richtige Steuerkonto bebucht wird +Tracelinks: StRS-25 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - differenzierte Umsatzsteuerbehandlung bei Import/Zoll ist bei internationalem Warenverkehr weiterhin relevant +Status: belegt +``` + +``` +ID: StRS-27 +Titel: Artikellebenszyklus inkl. automatisiertem End-of-Life pflegen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Einkauf/Produktmanagement +Vorbedingung: Artikel ist im Artikelstamm angelegt +Fakt: Modul enthält dedizierte Funktionsbereiche AutoEOL (AutoEOLViewModel), ArticleRebooking, ArticleBookOrBookout, ConvertArticle, CopyArticle, PriceUpdate und RMMArticle als getrennte Unterordner der Artikelstammdatenpflege +Aussage: Das System soll Artikelstammdaten inkl. automatisierter End-of-Life-Kennzeichnung, Umbuchung, Ein-/Ausbuchung und Preispflege zentral verwalten. +Ergebnis: Artikel ist mit aktuellem Lebenszyklusstatus und konsistenten Stammdaten geführt +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Warehousing/ArticleManagement/AutoEOL/AutoEOLViewModel.cs - Begründung: Eigene Klasse belegt eine automatisierte End-of-Life-Funktion; konkrete Auslösebedingung nicht eingesehen + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Warehousing/ArticleManagement/ArticleRebooking - Begründung: Verzeichnisname belegt eine Umbuchungsfunktion für Artikel +Prüfidee: Artikel mit abgelaufenem Lebenszyklusdatum prüfen und feststellen, ob AutoEOL ihn automatisch als "End of Life" markiert +Tracelinks: StRS-8 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - automatisierte Lebenszykluspflege reduziert manuellen Pflegeaufwand im Artikelstamm +Status: belegt +``` + +``` +ID: StRS-28 +Titel: Artikeldaten aus externen Quellen importieren +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Einkauf +Vorbedingung: Importdatei/-quelle mit Artikeldaten liegt vor +Fakt: ArticleImportAppModuleController/ArticleImportAppModuleViewModel bilden einen eigenständigen App-Modul-Prozess für den Artikelimport +Aussage: Das System soll Artikeldaten aus externen Quellen importieren und in den Artikelstamm übernehmen können. +Ergebnis: Importierte Artikel stehen im Artikelstamm zur Verfügung +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Warehousing/ArticleImport/ArticleImportAppModuleViewModel.cs - Begründung: Eigenständiges App-Modul belegt einen dedizierten Importprozess; Feldabbildung im Detail nicht eingesehen +Prüfidee: Importdatei mit neuem Artikel einlesen und prüfen, dass der Artikel korrekt im Artikelstamm erscheint +Tracelinks: keine +Konsolidierung: Kandidat: Abgrenzung zu Sales/SpecialArticleImport (StRS-1) und Purchasing/EDIManagement (StRS-38) prüfen - mehrere Importwege für Artikel-/Preisdaten +Übernahmewürdigkeit: übernehmen - Artikelimport aus Lieferantenkatalogen ist im Großhandel/IT-Fachhandel Standard +Status: belegt +``` + +``` +ID: StRS-29 +Titel: Mengeneinheiten nach UN/ECE-Standard verwalten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Artikelstammdatenpflege +Vorbedingung: Artikel benötigt eine von Stück abweichende Mengeneinheit +Fakt: SupportedUNECECodes.cs im Ordner ArticleUnitManagement/ViewModel führt die unterstützten Mengeneinheiten anhand des internationalen UN/ECE-Rec.-20-Codes +Aussage: Das System soll Mengeneinheiten von Artikeln auf Basis der international standardisierten UN/ECE-Codes verwalten, um eine eindeutige Zuordnung z. B. für EDI-Nachrichten sicherzustellen. +Ergebnis: Artikel führt eine standardkonforme Mengeneinheit +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Warehousing/ArticleUnitManagement/ViewModel/SupportedUNECECodes.cs - Begründung: Datei legt den zulässigen Wertebereich der Mengeneinheiten anhand des Standards fest +Prüfidee: Mengeneinheit "Karton" mit UN/ECE-Code anlegen und in einer EDI-Ausgangsnachricht (siehe StRS-93) auf korrekte Codeübernahme prüfen +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Standardkonformität ist Voraussetzung für EDI-Fähigkeit mit Lieferanten +Status: belegt +``` + +``` +ID: StRS-30 +Titel: Barcodes für Artikel generieren und Vergabebedingungen konfigurieren +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Lagermitarbeiter +Vorbedingung: Artikel ohne Barcode ist angelegt +Fakt: GenerateBarcodeViewModel mit BarcodeGenerateType (Enum) sowie BarcodeConditionSettingsViewModel (eigene Bedingungseinstellungen für die Barcodevergabe) bilden Erzeugung und Konfiguration ab +Aussage: Das System soll Barcodes für Artikel nach konfigurierbaren Vergabebedingungen automatisiert generieren können. +Ergebnis: Artikel erhält einen gültigen, den Bedingungen entsprechenden Barcode +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Warehousing/BarcodeManagement/GenerateBarcode/ViewModel/BarcodeGenerateType.cs - Begründung: Enum belegt unterschiedliche Erzeugungsarten von Barcodes + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Warehousing/BarcodeManagement/Setting/BarcodeCondition/BarcodeConditionSettingsViewModel.cs - Begründung: Klasse belegt konfigurierbare Vergabebedingungen +Prüfidee: Barcode-Vergabebedingung ändern und prüfen, dass neu generierte Barcodes der geänderten Bedingung entsprechen +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - automatisierte, regelbasierte Barcodevergabe ist für die Lagerlogistik erforderlich +Status: belegt +``` + +``` +ID: StRS-31 +Titel: Warenkommissionierung im Lager steuern +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Lagermitarbeiter +Vorbedingung: Lieferschein/Kommissionierauftrag liegt vor +Fakt: CommissioningAppModuleController mit BaseUserControll bildet einen eigenständigen App-Modul-Prozess für die Kommissionierung +Aussage: Das System soll Lagermitarbeitende bei der Kommissionierung von Lieferscheinpositionen anhand eines dedizierten Kommissionierprozesses unterstützen. +Ergebnis: Kommissionierauftrag ist abgearbeitet und Positionen sind als kommissioniert markiert +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Warehousing/Commissioning/CommissioningAppModuleController.cs - Begründung: Eigenständiges App-Modul belegt einen dedizierten Kommissionierprozess; Detailablauf nicht eingesehen +Prüfidee: Kommissionierauftrag mit mehreren Positionen abarbeiten und prüfen, dass der Lieferschein erst bei vollständiger Kommissionierung freigegeben wird +Tracelinks: StRS-12 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - geführte Kommissionierung ist Standard in der Lagerlogistik +Status: belegt +``` + +``` +ID: StRS-32 +Titel: Kommissionsaufträge (Konsignationslager) inkl. Teilkommissionen verwalten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Lagermitarbeiter/Vertrieb +Vorbedingung: Ware wird einem Kunden als Kommissionsware (Konsignationslager) überlassen +Fakt: PartialCommissionOrderViewModel (Warehousing/Commissions/CommissionOrders) führt einen PartialCommissionOrderState und nutzt PartialCommissionStateToStringConverter aus dem Namensraum CentronSoftware.Centron.WPF.UI.Modules.Finances.Receipts.PartialCommission.Converter - also einer Klasse aus einem anderen Modul (Finances/Receipts/PartialCommission) +Aussage: Das System soll Kommissionsaufträge (Warenüberlassung ins Konsignationslager) inkl. Teilabrufen mit einem eigenen Statusmodell verwalten. +Ergebnis: Kommissionsauftrag zeigt den korrekten Teilkommissionsstatus +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Warehousing/Commissions/CommissionOrders/PartialCommissionOrderViewModel.cs (Z. 1-36) - Begründung: Klasse belegt Statusmodell und Wiederverwendung eines Konverters aus einem fachlich anderen Modulpfad +Prüfidee: Kommissionsauftrag mit Teilabruf anlegen und prüfen, dass der Status korrekt zwischen den Modulen Warehousing/Commissions und Finances/Receipts/PartialCommission konsistent dargestellt wird +Tracelinks: keine +Konsolidierung: Kandidat: Warehousing/Commissions und Finances/Receipts/PartialCommission bilden denselben fachlichen Sachverhalt (Kommissionsauftrag) ab und teilen sich bereits Converter-Klassen über Modulgrenzen hinweg - im Zielsystem als ein Konzept zu konsolidieren +Übernahmewürdigkeit: übernehmen - Konsignationsgeschäft ist im IT-Fachhandel verbreitet; technische Aufteilung auf zwei Module ist migrationsrelevant +Status: belegt +``` + +``` +ID: StRS-33 +Titel: Lagerinventur durchführen und bewerten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Lagermitarbeiter/Buchhaltung +Vorbedingung: Inventurstichtag ist festgelegt +Fakt: InventoryBaseViewModel als Basisklasse für den Inventurprozess (InventoryAppModuleController) +Aussage: Das System soll die Durchführung einer Lagerinventur mit Erfassung der Ist-Bestände und Bewertung gegenüber dem Soll-Bestand unterstützen. +Ergebnis: Inventurergebnis mit Differenzen zum Soll-Bestand liegt vor +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Warehousing/Inventory/InventoryBaseViewModel.cs (Z. 1-6) - Begründung: Basisklasse belegt einen strukturierten Inventurprozess; konkrete Differenzbuchungslogik nicht eingesehen +Prüfidee: Inventur mit abweichendem Ist-Bestand durchführen und prüfen, dass die Differenz zum Soll-Bestand korrekt ausgewiesen wird +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Inventur ist gesetzlich vorgeschriebener Bestandteil der Lagerbuchführung +Status: belegt +``` + +``` +ID: StRS-34 +Titel: Warengruppen mit Kalkulationsaufschlag und filialspezifischen Erlös-/Aufwandskonten verwalten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Einkauf/Buchhaltung +Vorbedingung: Artikel ist einer Warengruppe zuzuordnen +Fakt: MaterialGroupDTOViewModel/MaterialMarkupViewModel führen Kalkulationsaufschläge je Warengruppe; BranchRevenueAndExpenseAccountDTOViewModel verknüpft eine Warengruppe filialabhängig mit Erlös- und Aufwandskonten; RebookMaterialGroupDialogViewModel (Z. 32-50) ermöglicht die Umbuchung von Artikeln zwischen Warengruppen inkl. Übernahme geänderter Artikeleigenschaften +Aussage: Das System soll Warengruppen mit Kalkulationsaufschlag sowie filialabhängiger Zuordnung zu Erlös- und Aufwandskonten verwalten und eine kontrollierte Umbuchung von Artikeln zwischen Warengruppen ermöglichen. +Ergebnis: Warengruppe liefert korrekten Aufschlag und korrekte Kontenzuordnung je Filiale; Umbuchung aktualisiert betroffene Artikel konsistent +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Warehousing/MaterialGroupManagement/Class/BranchRevenueAndExpenseAccountDTOViewModel.cs - Begründung: Datenmodell erzwingt die filialabhängige Konten-Zuordnung je Warengruppe + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Warehousing/MaterialGroupManagement/ViewModel/RebookMaterialGroupDialogViewModel.cs (Z. 32-50) - Begründung: Dialogklasse belegt den Umbuchungsprozess zwischen Warengruppen +Prüfidee: Warengruppe mit Aufschlag X% anlegen, Artikel zuordnen und prüfen, dass der Verkaufspreis den Aufschlag korrekt berücksichtigt; anschließend Artikel in andere Warengruppe umbuchen und Kontenzuordnung prüfen +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - filialdifferenzierte Kontenzuordnung ist für Mandanten mit mehreren Buchungskreisen erforderlich +Status: belegt +``` + +``` +ID: StRS-35 +Titel: Übergreifende Artikelsuche mit Bestandsanzeige +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Alle Anwender mit Artikelbezug +Vorbedingung: Suchbegriff (Artikelnummer, Bezeichnung, Seriennummer) liegt vor +Fakt: SearchArticleViewModel liefert ArticlePreview und ArticleStock (Bestand) über eine seitenweise ladende Quelle (DataPager/ListThroughPaging, SourcesBehavior); SerialNumberViewModel ergänzt die Seriennummernsuche +Aussage: Das System soll eine übergreifende, seitenweise ladende Artikelsuche mit Bestands- und Seriennummernanzeige für alle Module bereitstellen. +Ergebnis: Trefferliste mit Artikel-Vorschau, aktuellem Bestand und ggf. Seriennummern ist verfügbar +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Warehousing/SearchArticle/ViewModel/ArticleStock.cs - Begründung: Eigene Klasse belegt die Bestandsanzeige als Teil der Sucherergebnisse + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Warehousing/SearchArticle/DataPager/ListThroughPaging.cs - Begründung: Belegt serverseitiges Paging der Ergebnisse +Prüfidee: Artikelsuche mit mehr als einer Seite Ergebnissen ausführen und prüfen, dass Paging und Bestandsanzeige je Treffer korrekt funktionieren +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - performante, zentrale Artikelsuche wird von praktisch allen Modulen benötigt +Status: belegt +``` + +``` +ID: StRS-36 +Titel: Lieferantensuche im Beschaffungskontext +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Einkauf +Vorbedingung: Lieferant soll einer Bestellung/einem Artikel zugeordnet werden +Fakt: SearchSupplierViewModel als eigenständige Suchkomponente für Lieferanten +Aussage: Das System soll eine dedizierte Lieferantensuche für den Beschaffungsprozess bereitstellen. +Ergebnis: Lieferant ist auffindbar und zuordenbar +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Warehousing/SupplierSearch/ViewModel/SearchSupplierViewModel.cs - Begründung: Eigenständige Klasse belegt eine dedizierte Lieferantensuche +Prüfidee: Lieferantensuche mit Teilnamen ausführen und prüfen, dass passende Lieferanten gefunden werden +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Lieferantensuche ist Grundfunktion des Einkaufsprozesses +Status: belegt +``` + +``` +ID: StRS-37 +Titel: Versandarten und Logistikeinstellungen konfigurieren +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Neue Versandart soll systemweit verfügbar sein +Fakt: ShippingMethodSettingsViewModel und LogisticSettingsViewModel bilden getrennte Konfigurationsbereiche für Versandarten bzw. allgemeine Logistikeinstellungen +Aussage: Das System soll Versandarten und allgemeine Logistikeinstellungen zentral konfigurierbar machen. +Ergebnis: Versandart steht in der Belegerfassung/im Warenausgang zur Auswahl +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Logistic/ShippingMethodSettings/ShippingMethodSettingsViewModel.cs - Begründung: Eigenständige Klasse belegt die Konfigurierbarkeit von Versandarten +Prüfidee: Neue Versandart anlegen und prüfen, dass sie im Lieferschein auswählbar ist +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - konfigurierbare Versandarten sind Voraussetzung für Anbindung mehrerer Versanddienstleister (siehe StRS-109) +Status: belegt +``` + +``` +ID: StRS-38 +Titel: EDI-Bestellungen inkl. Positionsabgleich mit Lieferanten austauschen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Einkauf +Vorbedingung: Lieferant unterstützt elektronischen Datenaustausch +Fakt: EDIManagementAppViewModel mit Unterordner EDIReceiptTabs (EDIAddArticleViewModel, EDICentronSupplierOrderFindViewModul, EDICentronSupplierOrderItemsViewModel) bildet die Zuordnung von EDI-Positionen zu Bestellungen ab +Aussage: Das System soll Bestellungen elektronisch mit Lieferanten austauschen und eingehende EDI-Positionen den bestehenden Bestellungen zuordnen. +Ergebnis: EDI-Bestellpositionen sind der richtigen Bestellung zugeordnet +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Purchasing/EDIManagement/EDIReceiptTabs/EDICentronSupplierOrderItemsViewModel.cs - Begründung: Klasse belegt Positionszuordnung zwischen EDI-Nachricht und Bestellung +Prüfidee: EDI-Bestellbestätigung mit abweichender Liefermenge einspielen und prüfen, dass die Abweichung in der zugeordneten Bestellung sichtbar wird +Tracelinks: StRS-93 (EDI-Lieferantenanbindungen Backend) +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - EDI-Anbindung an Distributoren ist im IT-Fachhandel branchenüblich +Status: belegt +``` + +``` +ID: StRS-39 +Titel: Bestellvorschläge aus Bestandsunterschreitung ableiten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Einkauf +Vorbedingung: Artikelbestand ist erfasst +Fakt: OrderSuggestionActiveDistriViewModel sowie CreateSupplierOrderItemInfo bilden den Bestellvorschlagsprozess je aktivem Distributor ab; EgisWarenkorbDialogViewModel belegt eine direkte Warenkorb-Integration mit dem Distributor EGIS +Aussage: Das System soll Bestellvorschläge je Distributor ermitteln und die Übernahme in einen distributorseitigen Warenkorb ermöglichen. +Ergebnis: Bestellvorschlagsliste mit vorgeschlagenen Mengen je Distributor liegt vor +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Purchasing/OrderSuggestionList/CreateSupplierOrderItemInfo.cs - Begründung: Klasse belegt die Erzeugung von Bestellpositionen aus dem Vorschlag; die genaue Meldebestandsformel wurde nicht bis zur durchsetzenden Stelle zurückverfolgt + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Purchasing/OrderSuggestionList/Module/EgisWarenkorbDialogViewModel.cs - Begründung: Belegt eine direkte Distributor-Warenkorb-Integration (EGIS) +Prüfidee: Artikel unter Meldebestand fallen lassen und prüfen, dass er in der Bestellvorschlagsliste des zuständigen Distributors erscheint +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - automatisierte Bestellvorschläge reduzieren Fehlbestände +Status: belegt +``` + +``` +ID: StRS-40 +Titel: Einkaufs- und Bestelleingangs-Grundeinstellungen konfigurieren +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Einkaufsprozess soll mandantenspezifisch angepasst werden +Fakt: PurchaseSettingsViewModel und PurchaseReceiptSettingsViewModel (Unterordner ReceiptSettings) trennen allgemeine Einkaufseinstellungen von belegspezifischen Einstellungen für Bestelleingang +Aussage: Das System soll grundlegende Einkaufs- und Wareneingangs-Einstellungen mandantenspezifisch konfigurierbar machen. +Ergebnis: Einkaufsprozess verhält sich gemäß hinterlegter Einstellungen +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Purchasing/PurchaseSettings/ReceiptSettings/PurchaseReceiptSettingsViewModel.cs - Begründung: Eigene Klasse belegt konfigurierbare Bestelleingangs-Einstellungen +Prüfidee: Einstellung ändern und prüfen, dass sich das Verhalten bei der nächsten Bestellerfassung entsprechend ändert +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - mandantenspezifische Konfigurierbarkeit ist Grundvoraussetzung für Mehrmandantenbetrieb +Status: belegt +``` + +``` +ID: StRS-41 +Titel: Reisekosten mitarbeiterbezogen erfassen und Buchhaltungskonten zuordnen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Mitarbeiter/Buchhaltung +Vorbedingung: Mitarbeiter hat Reisekosten zu erfassen +Fakt: EmployeeToBookKeepingAccountAssignmentDialogViewModel weist einem Mitarbeiter ein Buchhaltungskonto für Reisekostenerstattung zu; CategoryManagementDialogViewModel verwaltet Ausgabenkategorien; TransactionDetailStatusToEnabledConverter/-VisibilityConverter belegen einen Freigabestatus je Buchung +Aussage: Das System soll Reisekosten je Mitarbeiter kategorisiert erfassen, einem zugeordneten Buchhaltungskonto zuordnen und über einen Freigabestatus je Buchung steuern. +Ergebnis: Reisekostenbuchung ist kategorisiert, kontiert und mit Freigabestatus versehen +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Purchasing/TravelExpense/Dialogs/EmployeeToBookKeepingAccountAssignmentDialogViewModel.cs - Begründung: Datenmodell erzwingt die Konto-Zuordnung je Mitarbeiter als Voraussetzung für die Verbuchung + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Purchasing/TravelExpense/Converters/TransactionDetailStatusToEnabledConverter.cs - Begründung: Belegt einen Status, der einzelne Buchungen sperrt/freigibt +Prüfidee: Reisekostenbuchung ohne zugeordnetes Mitarbeiterkonto anlegen und prüfen, dass die Verbuchung verweigert wird +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - kontierte Reisekostenabrechnung ist buchhalterisch erforderlich +Status: belegt +``` + +``` +ID: StRS-42 +Titel: Fertigungsaufträge anlegen und bearbeiten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Produktionsplaner +Vorbedingung: Zu fertigender Artikel/Stückliste ist definiert +Fakt: AddProductionOrderViewModel/EditProductionOrderViewModel mit ProductionOrderDTOViewModel und OrderDTOViewModel bilden Anlage und Bearbeitung von Fertigungsaufträgen ab +Aussage: Das System soll die Anlage und Bearbeitung von Fertigungsaufträgen auf Basis eines zu fertigenden Artikels unterstützen. +Ergebnis: Fertigungsauftrag ist angelegt und steuert die Produktion des Artikels +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Production/ProductionOrder/AddProductionOrder/AddProductionOrderViewModel.cs - Begründung: Klasse belegt den Anlageprozess eines Fertigungsauftrags; Verknüpfung zu Stücklisten nicht im Detail eingesehen +Prüfidee: Fertigungsauftrag für einen Artikel anlegen und prüfen, dass Statuswechsel (angelegt→in Arbeit→fertig) nachvollziehbar sind +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Fertigungsauftragsteuerung ist erforderlich, sofern Eigenfertigung/Konfektionierung stattfindet +Status: belegt +``` + +``` +ID: StRS-43 +Titel: Produktionsmaschinen als Stammdaten verwalten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Produktionsplaner +Vorbedingung: Neue Maschine wird in der Fertigung eingesetzt +Fakt: ProductionMachineDTOViewModel (MaschineManagementViewModel) führt Maschinenstammdaten +Aussage: Das System soll Produktionsmaschinen als Stammdaten verwalten, damit Fertigungsaufträge einer Maschine zugeordnet werden können. +Ergebnis: Maschine ist als Stammdatum verfügbar und Fertigungsaufträgen zuordenbar +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Production/MachineManagement/ProductionMachineDTOViewModel.cs - Begründung: Eigene Klasse belegt Maschinenstammdaten +Prüfidee: Maschine anlegen und einem Fertigungsauftrag zuordnen; prüfen, dass die Zuordnung in der Auftragsübersicht sichtbar ist +Tracelinks: StRS-42 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Maschinenstammdaten sind Voraussetzung für Kapazitätsplanung in der Fertigung +Status: belegt +``` + +``` +ID: StRS-44 +Titel: RMA-Abwicklung inkl. Verschrottung fehlerhafter Ware +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Reklamationssachbearbeiter +Vorbedingung: Kunde meldet defekten/falschen Artikel zurück +Fakt: NewRmaViewModel führt einen mehrseitigen Assistenten (NewRmaArticleSelectionPageViewModel, NewRmaSelectionPageViewModel, NewRmaSummaryPageViewModel); RmaCommon.RmaScappedMessage() (Z. 16-20) erzeugt eine Verschrottungsmeldung je Seriennummer oder Artikel +Aussage: Das System soll RMA-Vorgänge für zurückgesendete Artikel per Assistent erfassen und wahlweise mit einer Verschrottungsmeldung für seriennummerngenau erfasste, nicht mehr verwertbare Ware abschließen können. +Ergebnis: RMA-Vorgang ist erfasst; verschrottete Ware ist als solche gekennzeichnet +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Rma/RmaCommon.cs, Methode RmaScappedMessage() (Z. 16-20) - Begründung: Durchsetzende Stelle, die je nach Vorhandensein einer Seriennummer eine artikel- oder seriennummerngenaue Verschrottungsmeldung erzeugt +Prüfidee: RMA für einen Artikel mit Seriennummer anlegen, als "verschrottet" abschließen und prüfen, dass die Seriennummer in der Bestandsführung nicht mehr als verfügbar geführt wird +Tracelinks: StRS-12 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - RMA-Prozess inkl. Verschrottungsdokumentation ist für Gewährleistungsabwicklung erforderlich +Status: belegt +``` + +``` +ID: StRS-45 +Titel: Support-Tickets erfassen und bearbeiten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Helpdesk-Mitarbeiter +Vorbedingung: Kundenanfrage/Störung liegt vor +Fakt: TicketDetailViewModel/TicketAppModuleController bilden die zentrale Ticketbearbeitung; TicketProcessTemplates ermöglichen vordefinierte Bearbeitungsabläufe je Ticketart +Aussage: Das System soll Support-Tickets erfassen, bearbeiten und anhand vordefinierter Prozessvorlagen je Ticketart steuern. +Ergebnis: Ticket ist erfasst und folgt der hinterlegten Prozessvorlage +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Helpdesk/TicketDetails/TicketDetailViewModel.cs - Begründung: Zentrale Klasse belegt die Ticketbearbeitung; Statusmodell nicht bis zur durchsetzenden Stelle zurückverfolgt +Prüfidee: Ticket mit Prozessvorlage "Störung" anlegen und prüfen, dass die vorlagenspezifischen Bearbeitungsschritte angeboten werden +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Ticketverwaltung ist Kernfunktion des Helpdesk-Geschäfts +Status: belegt +``` + +``` +ID: StRS-46 +Titel: Helpdesk-Kennzahlen im Dashboard darstellen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Helpdesk-Leitung +Vorbedingung: Tickets sind im System erfasst +Fakt: Eigenständiges Dashboard-Modul (Helpdesk/Dashboard) getrennt von der Ticketbearbeitung selbst +Aussage: Das System soll aggregierte Helpdesk-Kennzahlen (z. B. offene/überfällige Tickets) in einem Dashboard darstellen. +Ergebnis: Helpdesk-Leitung sieht aktuelle Kennzahlen auf einen Blick +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Helpdesk/Dashboard - Begründung: Eigenständiger Modulordner belegt eine getrennte Kennzahlendarstellung; konkrete Kennzahlen nicht im Detail eingesehen +Prüfidee: Ticket überfällig werden lassen und prüfen, dass sich die Dashboard-Kennzahl entsprechend ändert +Tracelinks: StRS-45 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kennzahlen-Dashboard unterstützt Steuerung des Helpdesk-Betriebs +Status: belegt +``` + +``` +ID: StRS-47 +Titel: Erwartete Wartungsereignisse mit wochentagsgenauem Zeitfenster überwachen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Helpdesk-Mitarbeiter / automatisierter Monitoring-Prozess +Vorbedingung: Wartungsvertrag mit Monitoring-Vereinbarung für einen Kunden besteht +Fakt: ExpectedEventsDTOViewModel (Z. 8-40) führt je erwartetem Ereignis einen EventTriggerKind, eine optionale Nachrichteninhaltsprüfung (IsEventMessageContains/MessageContains) sowie für jeden Wochentag eigene Zeitfenster (z. B. ExecuteMondayFrom/ExecuteMondayTo) und ist einem Kunden (AccountI3D) zugeordnet +Aussage: Das System soll für Kunden mit Monitoring-Vereinbarung erwartete Ereignisse mit wochentagsgenauem Zeitfenster und optionaler Inhaltsprüfung überwachen und das Ausbleiben eines erwarteten Ereignisses erkennen. +Ergebnis: Ausbleibendes erwartetes Ereignis innerhalb des konfigurierten Zeitfensters wird als Abweichung erkannt (z. B. für Ticketerstellung/Eskalation) +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Helpdesk/ExpectedEvents/ViewModels/Details/ExpectedEventsDTOViewModel.cs (Z. 8-40) - Begründung: Datenmodell erzwingt je Wochentag ein eigenes Zeitfenster und eine Kundenzuordnung als Grundlage der Überwachung +Prüfidee: Erwartetes Ereignis mit Zeitfenster Montag 08:00-09:00 konfigurieren, kein passendes Ereignis liefern und prüfen, dass dies als Abweichung erkannt wird +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - proaktives SLA-Monitoring ist ein zentrales Verkaufsargument des Managed-Service-Geschäfts +Status: belegt +``` + +``` +ID: StRS-48 +Titel: Ticketprozesse und Aufgabenverwaltung konfigurieren +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Helpdesk-Ablauf soll unternehmensspezifisch angepasst werden +Fakt: Helpdesk/Settings (57 Dateien) und Helpdesk/TaskManagement bilden getrennte Konfigurationsbereiche für Ticketprozesse und Aufgaben +Aussage: Das System soll Ticketprozesse und die zugehörige Aufgabenverwaltung unternehmensspezifisch konfigurierbar machen. +Ergebnis: Ticket-/Aufgabenverhalten folgt der hinterlegten Konfiguration +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Helpdesk/Settings - Begründung: Umfangreicher eigener Einstellungsbereich belegt weitreichende Konfigurierbarkeit; Einzelparameter nicht im Detail eingesehen +Prüfidee: Konfigurationsparameter ändern und prüfen, dass sich das Ticketverhalten entsprechend ändert +Tracelinks: StRS-45 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Konfigurierbarkeit der Ticketprozesse ist für unterschiedliche Kundenverträge (SLA) erforderlich +Status: belegt +``` + +``` +ID: StRS-49 +Titel: Selbstbedienungsformular und Checklisten für den Helpdesk +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Kunde/Helpdesk-Mitarbeiter +Vorbedingung: Kunde möchte ein Anliegen ohne direkten Telefonkontakt melden +Fakt: SendSelfCareForm sowie CentronChecklist bilden ein kundenseitiges Selbstbedienungsformular bzw. Bearbeitungs-Checklisten für Helpdesk-Mitarbeitende +Aussage: Das System soll ein kundenseitiges Selbstbedienungsformular zur Ticketerstellung sowie Checklisten zur strukturierten Ticketbearbeitung bereitstellen. +Ergebnis: Ticket aus Selbstbedienungsformular ist erfasst; Checkliste begleitet die Bearbeitung +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Helpdesk/SendSelfCareForm - Begründung: Eigener Modulordner belegt ein Selbstbedienungsformular; Feldumfang nicht im Detail eingesehen +Prüfidee: Ticket über das Selbstbedienungsformular anlegen und prüfen, dass es unverändert im Helpdesk erscheint +Tracelinks: StRS-45 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Selbstbedienung reduziert telefonische Erstaufnahme im Helpdesk +Status: belegt +``` + +``` +ID: StRS-50 +Titel: Stammdaten automatisiert auf Pflichtfeldverstöße prüfen (Dateninspektion) +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Innendienst/Administrator +Vorbedingung: Pflichtfeld (z. B. Kostenstelle je Artikel) ist mandantenweit aktiviert +Fakt: CostCentreMandatoryCheck (abgeleitet von InspectorItemBase, Z. 16-61) prüft per SQL-Abfrage auf dbo.ARTIK, welche Artikel trotz aktivierter Pflichtfeld-Einstellung (CostCenterIsMandatory) keine Kostenstelle führen, und bietet über OpenChooseCostCentreForArticleDialog() eine direkte Korrektur an; die Prüfung ist eine von mehreren "Inspector"-Klassen im Modul +Aussage: Das System soll über ein Framework pluggable Datenqualitätsprüfungen (Inspectors) bereitstellen, die Verstöße gegen mandantenspezifisch aktivierte Pflichtfelder aufspüren und eine direkte Korrektur ermöglichen. +Ergebnis: Verstoßende Datensätze sind aufgelistet und über einen Dialog direkt korrigierbar +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/MyCentron/CentronInspectors/Inspectors/Article/CostCentreMandatoryCheck.cs (Z. 23-61) - Begründung: Durchsetzende Prüfstelle mit konkreter SQL-Abfrage und Korrekturpfad +Prüfidee: Kostenstellenpflicht aktivieren, Artikel ohne Kostenstelle anlegen, Inspector ausführen und prüfen, dass der Artikel in der Fehlerliste erscheint und über den Dialog korrigierbar ist +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - proaktive Datenqualitätsprüfung ist unabhängig von der Zielarchitektur sinnvoll +Status: belegt +``` + +``` +ID: StRS-51 +Titel: Persönliche API-Zugriffstoken mit Ablaufdatum verwalten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Mitarbeiter +Vorbedingung: Mitarbeiter benötigt programmatischen API-Zugriff unter eigener Identität +Fakt: PersonalAccessTokenSettingsViewModel.CreateToken() (Z. 157-169) erzeugt ein Token mit ExpiresAt aus AccessTokenEditDialogViewModel; EditToken (Z. 199-210) erlaubt nachträgliche Änderung von Name/ExpiresAt eines bestehenden Tokens +Aussage: Das System soll es Mitarbeitenden ermöglichen, persönliche API-Zugriffstoken mit definiertem Ablaufdatum selbst zu erzeugen und zu verwalten. +Ergebnis: Token ist erzeugt und verliert nach ExpiresAt seine Gültigkeit +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/MyCentron/PersonalSettings/AccessTokens/PersonalAccessTokenSettingsViewModel.cs, Methoden CreateToken() (Z. 157-169) und EditToken (Z. 199-210) - Begründung: Durchsetzende Stelle der Token-Erzeugung/-Änderung inkl. Pflichtfeld ExpiresAt +Prüfidee: Token mit Ablaufdatum in der Vergangenheit erzeugen (falls zulässig) bzw. ein gültiges Token nach Ablaufdatum verwenden und prüfen, dass der API-Zugriff verweigert wird +Tracelinks: SyRS-6 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - persönliche, befristete API-Token sind guter Sicherheitsstandard gegenüber dauerhaft gültigen Zugangsdaten +Status: belegt +``` + +``` +ID: StRS-52 +Titel: Persönliche Tagesplanung (MyDay) für Mitarbeitende und Übersicht für Vorgesetzte +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Mitarbeiter/Vorgesetzter +Vorbedingung: Mitarbeiter hat Termine/Aufgaben für den Tag +Fakt: MyDayEditorAppModuleController (persönliche Sicht) und MyDayEmployeeOverviewAppModuleController (Vorgesetzten-Sicht) sind getrennte Controller für dieselbe Tagesplanungsdomäne +Aussage: Das System soll Mitarbeitenden eine persönliche Tagesplanung anbieten und Vorgesetzten eine Übersicht über die Tagesplanung mehrerer Mitarbeitender ermöglichen. +Ergebnis: Tagesplan ist einsehbar sowohl aus persönlicher als auch aus Vorgesetzten-Perspektive +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/MyCentron/MyDay/EmployeeOverview/MyDayEmployeeOverviewAppModuleController.cs - Begründung: Eigener Controller belegt eine Vorgesetzten-Übersicht getrennt von der persönlichen Ansicht +Prüfidee: Termin im persönlichen MyDay eines Mitarbeiters anlegen und prüfen, dass er in der Vorgesetzten-Übersicht korrekt erscheint +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Tagesplanung mit Führungssicht unterstützt Personaleinsatzsteuerung +Status: belegt +``` + +``` +ID: StRS-53 +Titel: Konfigurierbares persönliches Startdashboard +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Mitarbeiter +Vorbedingung: Benutzer meldet sich an +Fakt: AddDashboardContainerViewModel mit ContainerCategoryViewModel ermöglicht das Hinzufügen kategorisierter Dashboard-Kacheln +Aussage: Das System soll Mitarbeitenden ein persönlich konfigurierbares Dashboard mit auswählbaren, kategorisierten Kacheln bereitstellen. +Ergebnis: Persönliches Dashboard zeigt die vom Benutzer gewählten Kacheln +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/MyCentron/Dashboard/AddDashboardContainer/AddDashboardContainerViewModel.cs - Begründung: Klasse belegt die Hinzufügbarkeit von Dashboard-Kacheln durch den Benutzer +Prüfidee: Kachel aus einer Kategorie hinzufügen und prüfen, dass sie nach erneuter Anmeldung weiterhin angezeigt wird +Tracelinks: keine +Konsolidierung: Kandidat: Abgrenzung zu StRS-89 (Startdashboard, Modules/Dashboard) und StRS-58 (Statistics/Dashboard) prüfen - mehrere Dashboard-Implementierungen im System +Übernahmewürdigkeit: übernehmen - personalisierbares Dashboard ist Standard moderner Business-Software +Status: belegt +``` + +``` +ID: StRS-54 +Titel: Persönliche Aufgabenliste mit Helpdesk-Bezug +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Mitarbeiter +Vorbedingung: Aufgaben/Tickets sind dem Mitarbeiter zugeordnet +Fakt: TodoListAppController mit Konvertern HelpdeskStatusI3DToImageConverter/-TextConverter belegt eine direkte Verknüpfung der persönlichen Aufgabenliste mit Helpdesk-Ticketstatus +Aussage: Das System soll dem Mitarbeiter eine persönliche Aufgabenliste bereitstellen, die auch zugeordnete Helpdesk-Tickets mit ihrem aktuellen Status anzeigt. +Ergebnis: Aufgabenliste zeigt sowohl eigene Aufgaben als auch zugeordnete Tickets mit Status +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/MyCentron/TodoList/Converters/HelpdeskStatusI3DToTextConverter.cs - Begründung: Konverter belegt die Darstellung von Ticketstatus innerhalb der Aufgabenliste +Prüfidee: Ticket einem Mitarbeiter zuweisen und prüfen, dass es mit korrektem Status in dessen Aufgabenliste erscheint +Tracelinks: StRS-45 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - konsolidierte persönliche Aufgabenliste erhöht Übersichtlichkeit für Mitarbeitende +Status: belegt +``` + +``` +ID: StRS-55 +Titel: Telefonanlagen-Integration mit Anrufprotokoll +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Mitarbeiter +Vorbedingung: Telefonanlage ist mit c-entron verbunden (CTI) +Fakt: TelephonyCallLogAppModuleController/-WrapperViewModel bilden ein Anrufprotokoll; TelephonyDetailsWrapperView zeigt Anrufdetails +Aussage: Das System soll eingehende/ausgehende Telefonate über eine CTI-Anbindung protokollieren und mit Kunden-/Ticketkontext verknüpfen. +Ergebnis: Anrufprotokoll mit Zeitpunkt und Kontext ist verfügbar +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/MyCentron/Telephony/CallLog/TelephonyCallLogWrapperViewModel.cs - Begründung: Klasse belegt Protokollierung von Anrufen; konkrete CTI-Anbindung (z. B. TAPI) nicht im Detail eingesehen +Prüfidee: Eingehenden Anruf eines bekannten Kunden simulieren und prüfen, dass der Anruf mit Kundenbezug im Protokoll erscheint +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Anrufprotokollierung mit Kundenbezug unterstützt Servicequalität +Status: belegt +``` + +``` +ID: StRS-56 +Titel: Fernwartungssitzungen über Supremo anstoßen +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Helpdesk-Mitarbeiter +Vorbedingung: Fernwartungssoftware Supremo ist auf Kundenrechner installiert +Fakt: SupremoSettingsViewModel/-Controller bilden eine dedizierte Konfiguration der Supremo-Integration +Aussage: Das System soll Fernwartungssitzungen über die Drittsoftware Supremo direkt aus dem Ticket-/Kundenkontext heraus anstoßen können. +Ergebnis: Fernwartungssitzung mit dem Kundenrechner ist gestartet +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/MyCentron/Supremo/SupremoSettingsViewModel.cs - Begründung: Eigener Konfigurationsbereich belegt eine Drittanbieter-Integration; Aufrufmechanik nicht im Detail eingesehen +Prüfidee: Fernwartung aus einem Ticket heraus starten und prüfen, dass die richtige Kunden-Session in Supremo geöffnet wird +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: Sonderfall - Anbindung an einen bestimmten Drittanbieter (Supremo); im Zielsystem als austauschbare Fernwartungsanbindung zu gestalten +Status: belegt +``` + +``` +ID: StRS-57 +Titel: Verkaufsstatistiken mit konfigurierbaren Datenquellen auswerten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Vertriebsleitung +Vorbedingung: Verkaufsbelege liegen im Auswertungszeitraum vor +Fakt: AnalyticDefaults sowie mehrere DataSources-Unterordner (u. a. ArticleOffers) belegen ein Framework mit austauschbaren Statistik-Datenquellen +Aussage: Das System soll Verkaufsstatistiken auf Basis konfigurierbarer, austauschbarer Datenquellen (z. B. Angebote je Artikel) auswerten können. +Ergebnis: Verkaufsstatistik zur gewählten Datenquelle liegt vor +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Statistics/SaleStatistics/DataSources/ArticleOffers/ArticleOfferStatisticDataSourceViewModel.cs - Begründung: Klasse belegt eine austauschbare Datenquelle für Verkaufsstatistiken +Prüfidee: Zwei unterschiedliche Datenquellen für denselben Zeitraum auswerten und Konsistenz der Summen prüfen +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - flexible Verkaufsstatistik ist Standardanforderung an ein ERP-Reporting +Status: belegt +``` + +``` +ID: StRS-58 +Titel: Filialübergreifende Management-Kennzahlen darstellen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Geschäftsleitung +Vorbedingung: Mehrere Filialen erfassen Belege im System +Fakt: BranchPreviewViewModel mit BranchItemConverter belegt eine filialbezogene Aufbereitung von Management-Kennzahlen +Aussage: Das System soll Management-Kennzahlen filialübergreifend mit Möglichkeit zur Einzelfilialansicht darstellen. +Ergebnis: Kennzahlen sind sowohl konsolidiert als auch je Filiale einsehbar +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Statistics/ManagementInfo/BranchPreviewViewModel.cs - Begründung: Klasse belegt filialbezogene Kennzahlenaufbereitung +Prüfidee: Kennzahl für eine einzelne Filiale filtern und mit der Gesamtsumme aller Filialen vergleichen +Tracelinks: keine +Konsolidierung: Kandidat: Abgrenzung zu StRS-53 (MyCentron-Dashboard) und StRS-89 (Startdashboard) prüfen +Übernahmewürdigkeit: übernehmen - filialübergreifendes Reporting ist für Mehrstandortunternehmen erforderlich +Status: belegt +``` + +``` +ID: StRS-59 +Titel: MSP-Kennzahlen aus Gerätedaten der Managed-Service-Anbieter auswerten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: MSP-Verantwortlicher +Vorbedingung: Gerätedaten wurden über einen MSP-Collector gesammelt (siehe StRS-95) +Fakt: MspDashboardAppModuleController mit MspArticleItemViewModel bildet eine dedizierte MSP-Kennzahlendarstellung +Aussage: Das System soll aus den über MSP-Collectoren gesammelten Gerätedaten Kennzahlen für das Managed-Service-Geschäft aufbereiten. +Ergebnis: MSP-Dashboard zeigt aktuelle Gerätekennzahlen +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Statistics/MspStatistics/MspDashboardAppModuleController.cs - Begründung: Eigener Controller belegt eine dedizierte MSP-Auswertung; Datenherkunft im Detail nicht zurückverfolgt +Prüfidee: Gerätedaten eines MSP-Collectors einspielen und prüfen, dass sie im MSP-Dashboard erscheinen +Tracelinks: StRS-95 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - MSP-Auswertung ist zentrales Verkaufsargument für Managed-Service-Anbieter unter den Kunden +Status: belegt +``` + +``` +ID: StRS-60 +Titel: Mitarbeiterbezogene Kennzahlen auswerten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Führungskraft +Vorbedingung: Mitarbeiteraktivitäten (Tickets, Zeiten, Belege) sind erfasst +Fakt: EmployeeAnalyticsConnector/-DialogManager bilden eine eigenständige Auswertungskomponente für Mitarbeiterkennzahlen +Aussage: Das System soll mitarbeiterbezogene Kennzahlen (z. B. bearbeitete Tickets, erfasste Zeiten) auswerten können. +Ergebnis: Mitarbeiterkennzahlen sind für Führungskräfte einsehbar +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Statistics/EmployeeAnalytics/Conectors/EmployeeAnalyticsConnector.cs - Begründung: Eigene Konnektorklasse belegt eine dedizierte Auswertungskomponente; konkrete Kennzahlen nicht im Detail eingesehen +Prüfidee: Mitarbeiter mit bekannter Ticketanzahl auswerten und Kennzahl gegen die tatsächliche Ticketanzahl prüfen +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Mitarbeiterkennzahlen unterstützen Personalsteuerung; datenschutzrechtliche Grenzen im Zielsystem beachten (siehe DSGVO-Modul) +Status: belegt +``` + +``` +ID: StRS-61 +Titel: Hinterlegte Reports zentral verwalten und ausführen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator/Anwender +Vorbedingung: Report ist im System hinterlegt +Fakt: ReportEngineAppModuleController mit Unterordner Query (QueryAppModuleController) belegt eine Reportverwaltung inkl. abfragebasierter Reports +Aussage: Das System soll hinterlegte Reports zentral verwalten, parametrisiert ausführen und auf abfragebasierten Datenquellen aufsetzen können. +Ergebnis: Report ist mit aktuellen Daten ausgeführt und darstellbar +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Reports/ReportManagement/ReportEngineAppModuleController.cs - Begründung: Zentrale Controller-Klasse belegt eine Reportverwaltung; genaue Berechtigungsprüfung je Report nicht im Detail eingesehen +Prüfidee: Report mit Parametern ausführen und Ergebnis gegen eine manuelle Kontrollabfrage prüfen +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zentrale Reportverwaltung ist Grundfunktion; Zugriffsschutz auf abfragebasierte Reports im Zielsystem verifizieren +Status: belegt +``` + +``` +ID: StRS-62 +Titel: Gruppenbasierte Rechtevergabe für Anwendungsfunktionen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Benutzer benötigt Zugriff auf eine geschützte Funktion +Fakt: AppRightsBL.HasUserRight() (Z. 644-649) prüft Rechte ausschließlich über Gruppenzugehörigkeit: SQL-Join dbo.Sichtrus (Gruppe→Recht) mit dbo.Sichmemb (Benutzer→Gruppe); es existiert kein direkter Weg, einem einzelnen Benutzer ein Recht ohne Gruppe zuzuweisen; SaveAndAssignGroupToRight() (Z. 261-278) weist bei Zuweisung eines Rechts rekursiv auch dessen übergeordnetes Recht zu (Z. 275-276) +Aussage: Das System soll Anwendungsrechte ausschließlich über Gruppenmitgliedschaft vergeben und bei Zuweisung eines Rechts automatisch dessen übergeordnete Rechte in der Rechtehierarchie mit zuweisen. +Ergebnis: Benutzer erhält exakt die Rechte der Gruppen, denen er angehört, inkl. impliziter übergeordneter Rechte +Belege: + - [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs, Methode HasUserRight() (Z. 644-649) und GetAllAppRightsFromUser() (Z. 651-664) - Begründung: Durchsetzende Stelle der Rechteprüfung mit konkretem SQL-Join über Gruppenmitgliedschaft + - [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs, Methode SaveAndAssignGroupToRight() (Z. 261-278) - Begründung: Durchsetzende Stelle der rekursiven Elternrecht-Zuweisung +Prüfidee: Benutzer einer Gruppe ohne bestimmtes Recht zuordnen und prüfen, dass HasUserRight() false liefert; nach Zuweisung eines Kindrechts an die Gruppe prüfen, dass auch das Elternrecht automatisch zugewiesen ist +Tracelinks: SyRS-8, SyRS-9, SwRS-6 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - gruppenbasiertes RBAC-Modell mit hierarchischen Rechten ist eine solide Grundlage für das Zielsystem +Status: belegt +``` + +``` +ID: StRS-63 +Titel: Mitarbeiterstammdaten inkl. Azure-AD-Import verwalten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Unternehmen nutzt Azure Active Directory / Entra ID +Fakt: AzureAdValidationWrapperViewModel und ImportEmployeeFromAdWrapperViewModel bilden einen dedizierten Import von Mitarbeiterstammdaten aus Azure AD inkl. Validierung; ShortSignSettingsDialogWrapperViewModel verwaltet das Mitarbeiterkürzel als Teil des Imports +Aussage: Das System soll Mitarbeiterstammdaten aus Azure Active Directory importieren, die Übernahme validieren und ein eindeutiges Mitarbeiterkürzel vergeben können. +Ergebnis: Mitarbeiter aus Azure AD ist mit validierten Stammdaten und eindeutigem Kürzel angelegt +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Administration/EmployeeManagement/AdImport/ImportEmployeeFromAdWrapperViewModel.cs - Begründung: Klasse belegt den AD-Importprozess; konkrete Validierungsregeln nicht im Detail eingesehen +Prüfidee: Mitarbeiter mit bereits vergebenem Kürzel aus AD importieren und prüfen, dass ein Konflikt erkannt und aufgelöst werden muss +Tracelinks: StRS-62 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Azure-AD-Import reduziert manuelle Doppelpflege von Mitarbeiterstammdaten +Status: belegt +``` + +``` +ID: StRS-64 +Titel: Mandanten mit Filialen und Firmendaten hierarchisch verwalten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Neuer Mandant/neue Filiale wird eingerichtet +Fakt: MandatorExtendedViewModel führt Firmendaten (Handelsregister, Handelsregisterort, Geschäftsführer, Telefon/Telefax, Z. 29-35); Unterordner BranchManagement (BranchManagementViewModel, BranchViewModel, NumberGroupsViewModel) bildet Filialen inkl. eigener Nummernkreise je Mandant ab +Aussage: Das System soll Mandanten mit rechtlich relevanten Firmendaten sowie zugeordneten Filialen inkl. filialeigener Nummernkreise hierarchisch verwalten. +Ergebnis: Mandant mit vollständigen Firmendaten und zugeordneten Filialen ist eingerichtet +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Administration/MandatorManagement/MandatorExtendedViewModel.cs (Z. 29-35) - Begründung: Datenmodell belegt die geführten rechtlichen Firmendaten je Mandant + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Administration/MandatorManagement/BranchManagement/NumberGroupsViewModel.cs - Begründung: Klasse belegt filialeigene Nummernkreise +Prüfidee: Mandant mit zwei Filialen anlegen und prüfen, dass jede Filiale einen eigenen Belegnummernkreis führt +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Mandanten-/Filialhierarchie mit eigenen Nummernkreisen ist Voraussetzung für Konzern-/Franchise-Strukturen +Status: belegt +``` + +``` +ID: StRS-65 +Titel: Auftragsverarbeitungsverträge und Datenlöschung rechtekontrolliert durchführen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Datenschutzbeauftragter/Administrator +Vorbedingung: Datenschutzrechtliche Aufbewahrungsfrist für Kontaktdaten ist abgelaufen bzw. ein Auftragsverarbeitungsvertrag (AVV) ist mit einem Kontakt abzuschließen +Fakt: OrderProcessingContractSettingsViewModel (Z. 22-40) verwaltet AVV-Vorlagen mit getrennten E-Mail-Texten für Annahme/Ablehnung sowie CheckForOrderProcessingContract als Aktivierungsschalter; CentronDataSecurityViewModel (Z. 21-36) stellt Datenlöschstatistiken bereit und exponiert die Felder HasContactDeleteRight/HasDatabaseCleanupRight, die die Lösch-/Bereinigungsfunktion an spezifische, im Rechtesystem (StRS-62) geprüfte Rechte binden +Aussage: Das System soll den Abschluss von Auftragsverarbeitungsverträgen prozessgestützt anstoßen und die Löschung/Bereinigung personenbezogener Daten ausschließlich Benutzern mit den dedizierten Rechten "Kontakt löschen" bzw. "Datenbankbereinigung" gestatten. +Ergebnis: AVV-Status ist je Kontakt nachvollziehbar; Datenlöschung ist auf berechtigte Benutzer beschränkt +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Administration/DSGVO/CentronDataSecurityViewModel.cs, Z. 35-36 (HasContactDeleteRight/HasDatabaseCleanupRight) - Begründung: Durchsetzende Stelle, die die Löschfunktion an dedizierte, über das Rechtesystem geprüfte Berechtigungen bindet + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Administration/DSGVO/OrderProcessingContractSettingsViewModel.cs (Z. 22-40) - Begründung: Datenmodell belegt den AVV-Workflow mit Vorlagen und Aktivierungsschalter +Prüfidee: Benutzer ohne HasDatabaseCleanupRight anmelden und prüfen, dass die Datenbankbereinigungsfunktion nicht verfügbar/ausführbar ist +Tracelinks: StRS-62, StRS-2 (Crm/Dsgvo-Tab) +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - rechtekontrollierte Löschfunktion und AVV-Prozess sind für DSGVO-Konformität zwingend +Status: belegt +``` + +``` +ID: StRS-66 +Titel: Systemweite API-Token-Richtlinie zentral verwalten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Personal-Access-Token-Funktion (StRS-51) ist unternehmensweit im Einsatz +Fakt: Administration/Settings/AccessTokens/AccessTokenSettingsViewModel besteht als eigene, von MyCentron/PersonalSettings/AccessTokens getrennte administrative Konfigurationsklasse +Aussage: Das System soll Administratoren eine zentrale, von der persönlichen Token-Verwaltung getrennte Konfiguration der systemweiten API-Token-Richtlinie ermöglichen. +Ergebnis: Administrative Token-Richtlinie gilt für alle persönlichen Token +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Administration/Settings/AccessTokens/AccessTokenSettingsViewModel.cs - Begründung: Eigenständige Klasse getrennt von der persönlichen Token-Verwaltung; genaue Richtlinienparameter nicht im Detail eingesehen +Prüfidee: Administrative Richtlinie (z. B. maximale Gültigkeitsdauer) ändern und prüfen, dass neu erzeugte persönliche Token diese Grenze einhalten +Tracelinks: StRS-51 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zentrale Sicherheitsrichtlinie für Token ist sinnvoll +Status: belegt +``` + +``` +ID: StRS-67 +Titel: Datenbank-/Webservice-Verbindungen zentral konfigurieren +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Arbeitsplatz/Server muss sich mit Datenbank bzw. Webservice verbinden +Fakt: LoginDialogViewModel (Connections) und AdminVersionControlViewModel (WebServiceSettings) bilden Verbindungsaufbau bzw. Versionskontrolle des Webservice ab +Aussage: Das System soll Datenbank- und Webservice-Verbindungsparameter zentral konfigurierbar machen und die Webservice-Version administrierbar anzeigen. +Ergebnis: Anwendung verbindet sich mit der konfigurierten Datenbank/dem konfigurierten Webservice in der erwarteten Version +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Administration/WebServiceSettings/AdminVersionControlViewModel.cs - Begründung: Klasse belegt eine administrative Versionskontrolle des Webservice +Prüfidee: Webservice auf inkompatible Version aktualisieren und prüfen, ob die Versionskontrolle dies anzeigt/verhindert +Tracelinks: StRS-98 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zentrale Verbindungskonfiguration ist Basisvoraussetzung für Client-Server-Betrieb +Status: belegt +``` + +``` +ID: StRS-68 +Titel: KI-gestützte Erstellung von E-Mail-Vorlagen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator/Marketing +Vorbedingung: Neue E-Mail-Vorlage soll erstellt werden +Fakt: AiMailTemplatesViewModel (MailTemplates) belegt eine KI-unterstützte Erstellung von E-Mail-Vorlagen, zusätzlich zur klassischen manuellen Vorlagenverwaltung (MailTemplatesAppModuleController) +Aussage: Das System soll die Erstellung von E-Mail-Vorlagen sowohl manuell als auch KI-unterstützt ermöglichen. +Ergebnis: E-Mail-Vorlage ist erstellt, wahlweise mit KI-Unterstützung vorformuliert +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Administration/MailTemplates/AiMailTemplatesViewModel.cs - Begründung: Eigene Klasse belegt eine KI-gestützte Variante der Vorlagenerstellung +Prüfidee: KI-gestützte Vorlagenerstellung mit Stichworten aufrufen und den Vorschlag gegen manuell erstellte Vorlagen auf Konsistenz prüfen +Tracelinks: StRS-82 (KI-Unterstützung) +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - KI-Unterstützung bei Textvorlagen reduziert manuellen Formulierungsaufwand +Status: belegt +``` + +``` +ID: StRS-69 +Titel: PDF-Signatur und KI-gestützte Textbausteine für Belege konfigurieren +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Belege sollen signiert bzw. mit Textbausteinen versehen werden +Fakt: PdfSigningSettingsViewModel konfiguriert die elektronische Signatur von PDF-Belegen; AiTextBlockViewModel (TextBlockManagement) ergänzt die klassische Textbausteinverwaltung um KI-Unterstützung +Aussage: Das System soll die elektronische PDF-Signatur konfigurierbar machen und Textbausteine für Belege sowohl manuell als auch KI-unterstützt verwalten. +Ergebnis: Beleg wird gemäß Konfiguration signiert und mit Textbausteinen versehen +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Administration/PdfSigning/PdfSigningSettingsViewModel.cs - Begründung: Eigene Klasse belegt konfigurierbare PDF-Signatur + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Administration/TextBlockManagement/AiTextBlockViewModel.cs - Begründung: Belegt KI-gestützte Textbausteinerstellung +Prüfidee: Signatureinstellung aktivieren, Beleg erzeugen und prüfen, dass die PDF-Datei eine gültige elektronische Signatur trägt +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - elektronische Signatur ist für rechtssichere Belege relevant +Status: belegt +``` + +``` +ID: StRS-70 +Titel: Stundenverrechnungssätze mit Zuschlägen je Vertrag pflegen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator/Vertrieb +Vorbedingung: Vertrag mit abweichenden Stundensätzen soll abgerechnet werden +Fakt: SearchContractDialogView/-ViewModel verknüpft Stundensatz-/Zuschlagspflege direkt mit der Vertragssuche; HourlySurchargeRateStatusToImageMultiConverter belegt einen Status je Zuschlagssatz +Aussage: Das System soll Stundenverrechnungssätze und Zuschläge vertragsbezogen pflegen und deren Gültigkeitsstatus anzeigen können. +Ergebnis: Vertrag verwendet die für ihn hinterlegten Stundensätze/Zuschläge bei der Abrechnung +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Administration/HourlySurchargeRates/Dialogs/SearchContractDialogView.xaml.cs - Begründung: Belegt die vertragsbezogene Verknüpfung der Stundensätze +Prüfidee: Vertrag mit abweichendem Stundensatz anlegen und in TimerBilling (StRS-20) prüfen, dass der abweichende Satz verwendet wird +Tracelinks: StRS-20 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - vertragsspezifische Stundensätze sind im Servicegeschäft üblich +Status: belegt +``` + +``` +ID: StRS-71 +Titel: Eskalationsempfänger für SLA-Verstöße konfigurieren +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: SLA-Frist eines Tickets droht überschritten zu werden +Fakt: EscalationReceiver (EscalationType) definiert konfigurierbare Empfänger für Eskalationen +Aussage: Das System soll konfigurierbare Empfänger für Eskalationsmeldungen bei drohender SLA-Verletzung verwalten. +Ergebnis: Bei Eskalation werden die konfigurierten Empfänger benachrichtigt +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Administration/EscalationsSettings/EscalationType/EscalationReceiver.cs - Begründung: Klasse belegt konfigurierbare Eskalationsempfänger; Auslösebedingung selbst nicht im Detail eingesehen +Prüfidee: SLA-Frist eines Tickets künstlich überschreiten und prüfen, dass die konfigurierten Empfänger benachrichtigt werden +Tracelinks: StRS-47 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Eskalationsmanagement ist zentral für die Einhaltung vertraglicher SLA +Status: belegt +``` + +``` +ID: StRS-72 +Titel: Länderstammdaten für Steuer- und Adressvalidierung pflegen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Neues Land wird für Geschäftsbeziehungen benötigt +Fakt: CountryManagementViewModel/-AppModuleController bilden die Länderstammdatenpflege, referenziert u. a. von ChangeTaxRateViewModel (StRS-14, GetVATByCountry) +Aussage: Das System soll Länderstammdaten zentral pflegen, die als Grundlage für länderabhängige Steuersätze und Adressvalidierung dienen. +Ergebnis: Land ist mit den für Steuer-/Adressprüfung nötigen Attributen verfügbar +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Administration/CountryManagement/CountryManagementViewModel.cs - Begründung: Zentrale Klasse belegt die Länderstammdatenpflege +Prüfidee: Neues Land mit Steuersätzen anlegen und in ChangeTaxRateViewModel (StRS-14) auf Verfügbarkeit prüfen +Tracelinks: StRS-14 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zentrale Länderstammdaten sind Grundlage für internationales Geschäft +Status: belegt +``` + +``` +ID: StRS-73 +Titel: SEPA-Lastschriftmandate mit Signaturworkflow verwalten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Kunde/Buchhaltung +Vorbedingung: Kunde soll per SEPA-Lastschrift belastet werden +Fakt: SepaContractSettingsViewModel (Z. 20-38) führt einen digitalen Signatur-Workflow (SboUrl/NexusUrl/UseNexusUrlForSigning) mit Vorlagen und E-Mail-Texten für Annahme/Ablehnung; die Feldnamen sind nahezu identisch mit OrderProcessingContractSettingsViewModel (StRS-65, DSGVO-AVV) - u. a. sind interne Felder weiterhin als "...OrderProcessingContract..." benannt, obwohl sie im SEPA-Kontext verwendet werden (Z. 30-35), was auf Kopieren der DSGVO-AVV-Implementierung als Vorlage hindeutet +Aussage: Das System soll SEPA-Lastschriftmandate über einen digitalen Signatur-Workflow mit Vorlagen und automatisierten Annahme-/Ablehnungs-E-Mails abwickeln. +Ergebnis: SEPA-Mandat ist digital signiert oder abgelehnt, Kunde und Ersteller sind per E-Mail informiert +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Administration/SepaContract/SepaContractSettingsViewModel.cs (Z. 20-38) - Begründung: Datenmodell erzwingt den Signatur-Workflow inkl. Vorlagen für den SEPA-Kontext +Prüfidee: SEPA-Mandat über den Signatur-Workflow ablehnen lassen und prüfen, dass die konfigurierte Ablehnungs-E-Mail versendet wird +Tracelinks: StRS-65 +Konsolidierung: Kandidat: StRS-65 - SepaContractSettingsViewModel und OrderProcessingContractSettingsViewModel (DSGVO-AVV) sind strukturell nahezu identische Implementierungen desselben "digitalen Vertragssignatur"-Konzepts für zwei unterschiedliche Vertragsarten, erkennbar an den unverändert aus der DSGVO-Vorlage übernommenen Feldnamen - im Zielsystem als ein generisches Signatur-Workflow-Konzept zu konsolidieren +Übernahmewürdigkeit: übernehmen - SEPA-Mandatsverwaltung ist für Lastschriftverfahren zwingend; technische Dopplung mit DSGVO-AVV-Workflow ist migrationsrelevant +Status: belegt +``` + +``` +ID: StRS-74 +Titel: Externe Zusatzwerkzeuge in die Oberfläche einbinden +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Externes Tool soll aus c-entron heraus aufrufbar sein +Fakt: ExternalToolSettingsViewModel konfiguriert externe Werkzeuge, ExternalTool-Modul stellt sie im Ribbon/Menü bereit +Aussage: Das System soll die Einbindung konfigurierbarer externer Werkzeuge in die Anwendungsoberfläche ermöglichen. +Ergebnis: Externes Werkzeug ist über die Oberfläche aufrufbar +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Administration/ExternalTools/ExternalToolSettingsViewModel.cs - Begründung: Klasse belegt konfigurierbare externe Werkzeuge +Prüfidee: Externes Werkzeug konfigurieren und prüfen, dass es im Menü erscheint und startet +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Erweiterbarkeit durch externe Werkzeuge unterstützt individuelle Kundenprozesse +Status: belegt +``` + +``` +ID: StRS-75 +Titel: WebCart-Shop für Kunden konfigurieren +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Kunden sollen online über Sonderpreise bestellen können +Fakt: BLWebCartLogic/IWebCartLogic (EmailsContract) bilden die Geschäftslogik des WebCart-Shops, der laut README.md (Z. 31-36) auf den "Sonderpreisen" (StRS-1) des Kunden im Adressstamm basiert und über einen Web-Account (Nexus) zugänglich ist +Aussage: Das System soll einen WebCart-Shop bereitstellen, über den Web-Accounts von Kunden auf Basis ihrer hinterlegten Sonderpreise online bestellen können. +Ergebnis: Kunde sieht im WebCart ausschließlich für ihn freigegebene Sonderpreisartikel und kann bestellen +Belege: + - [KONTEXT] README.md, Abschnitt "WebCart" (Z. 31-36) - Begründung: Projektdokumentation beschreibt explizit die fachliche Kopplung von WebCart an Sonderpreise und Web-Account + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Administration/WebCart/EmailsContract/IWebCartLogic.cs - Begründung: Schnittstelle belegt eine dedizierte WebCart-Geschäftslogik +Prüfidee: Kunde mit Web-Account und hinterlegten Sonderpreisen anlegen und prüfen, dass im WebCart genau diese Artikel bestellbar sind +Tracelinks: StRS-1, StRS-101 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - WebCart ist unmittelbares Vorbild/Kernstück für die geplante Web-/SaaS-Neuimplementierung +Status: belegt +``` + +``` +ID: StRS-76 +Titel: Prozessbezogene Benachrichtigungsschalter konfigurieren +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Mandant möchte bestimmte automatisierte Benachrichtigungen steuern +Fakt: UpdateAvailableNotificationSettings, SendDeliveryListShippingConfirmationSettings und TaskManagmentSettings bilden je einen eigenen Konfigurationsschalter für unterschiedliche automatisierte Prozessbenachrichtigungen +Aussage: Das System soll prozessbezogene automatisierte Benachrichtigungen (Update-Verfügbarkeit, Versandbestätigung, Aufgabenmanagement) einzeln aktivierbar machen. +Ergebnis: Benachrichtigung wird nur bei aktiviertem Schalter versendet +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Administration/SendDeliveryListShippingConfirmationSettings - Begründung: Eigener Ordner belegt einen dedizierten Schalter für Versandbestätigungen +Prüfidee: Versandbestätigungsschalter deaktivieren und prüfen, dass bei Lieferscheinerstellung keine Bestätigungsmail versendet wird +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - granulare Steuerung automatisierter Benachrichtigungen vermeidet ungewollte Kundenkommunikation +Status: belegt +``` + +``` +ID: StRS-77 +Titel: Anwendungs-Logdateien einsehen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator/Support +Vorbedingung: Fehler/Störung soll analysiert werden +Fakt: CentronLogViewModel/CentronLogAppModuleController stellen einen dedizierten Log-Betrachter bereit +Aussage: Das System soll Administratoren die Einsicht in Anwendungs-Logdateien direkt aus der Anwendung heraus ermöglichen. +Ergebnis: Logeinträge sind ohne Serverzugriff einsehbar +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Administration/LogViewer/CentronLogViewModel.cs - Begründung: Eigene Klasse belegt einen integrierten Log-Betrachter +Prüfidee: Fehler provozieren und prüfen, dass der zugehörige Logeintrag im Log-Betrachter auffindbar ist +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - integrierter Log-Zugriff erleichtert Support ohne Serverzugriff +Status: belegt +``` + +``` +ID: StRS-78 +Titel: Hintergrunddienste und Benachrichtigungen zentral verwalten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Hintergrunddienst (z. B. Benachrichtigungsdienst) läuft auf einem Server +Fakt: CentronNotificationsSettingsViewModel (Services/CentronNotifications) konfiguriert einen Hintergrunddienst für Benachrichtigungen +Aussage: Das System soll die Konfiguration von Hintergrunddiensten wie dem Benachrichtigungsdienst zentral administrierbar machen. +Ergebnis: Hintergrunddienst verhält sich gemäß zentraler Konfiguration +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Administration/Services/CentronNotifications/CentronNotificationsSettingsViewModel.cs - Begründung: Klasse belegt eine zentrale Dienstkonfiguration +Prüfidee: Konfiguration des Benachrichtigungsdienstes ändern und Neustart-Verhalten prüfen +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zentrale Dienstkonfiguration erleichtert Betrieb; im SaaS-Zielsystem durch Cloud-native Dienste zu ersetzen +Status: belegt +``` + +``` +ID: StRS-79 +Titel: Bankumsätze automatisiert Rechnungen zuordnen und unbekannte IBANs behandeln +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Kontoumsätze wurden von der Bank abgerufen +Fakt: BookAmountsViewModel (Z. 23-45) verknüpft OnlineBankingTransactionAssignmentViewModel mit dem Namensraum Finances.Receipts, was eine Zuordnung von Bankumsätzen zu Belegen belegt; CheckForUnknownIbanViewModel mit Seiten SearchUnknownIbanPageViewModel/CreateBankConnectionsPageViewModel behandelt Umsätze von noch nicht bekannten IBANs über einen mehrseitigen Assistenten +Aussage: Das System soll Bankumsätze automatisiert offenen Rechnungen zuordnen (Verbuchung) und für Umsätze von unbekannten IBANs einen geführten Prozess zur Anlage einer neuen Bankverbindung anbieten. +Ergebnis: Bankumsatz ist der richtigen Rechnung zugeordnet bzw. unbekannte IBAN ist geklärt +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/OnlineBanking/AccountTransactions/BookAmounts/BookAmountsViewModel.cs (Z. 23-45) - Begründung: Klasse belegt die Zuordnung von Bankumsätzen zu Belegen; exaktes Zuordnungskriterium (Betrag/Verwendungszweck) nicht im Detail eingesehen + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/OnlineBanking/AccountTransactions/CheckForUnknownIban/CheckForUnknownIbanViewModel.cs - Begründung: Assistent belegt einen strukturierten Klärungsprozess für unbekannte IBANs +Prüfidee: Banktransaktion mit exakt passendem Rechnungsbetrag einspielen und prüfen, ob eine automatische Vorschlagszuordnung zur offenen Rechnung erfolgt; danach Transaktion mit unbekannter IBAN einspielen und den Klärungsassistenten durchlaufen +Tracelinks: StRS-22, StRS-23 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - automatisierte Zahlungszuordnung reduziert manuellen Abgleichsaufwand in der Debitorenbuchhaltung erheblich +Status: belegt +``` + +``` +ID: StRS-80 +Titel: Bankverbindungen für Online-Banking-Abruf konfigurieren +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Neue Bankverbindung soll für automatisierten Kontoabruf genutzt werden +Fakt: OnlineBankingConfigurationToCombBoxTextConverter belegt eine Konfigurationsliste von Bankverbindungen zur Auswahl +Aussage: Das System soll mehrere Bankverbindungen für den automatisierten Kontoumsatzabruf konfigurierbar machen. +Ergebnis: Kontoumsätze mehrerer Bankverbindungen sind abrufbar +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/OnlineBanking/AccountTransactions/Converter/OnlineBankingConfigurationToCombBoxTextConverter.cs - Begründung: Konverter belegt eine Auswahlliste konfigurierter Bankverbindungen +Prüfidee: Zweite Bankverbindung konfigurieren und prüfen, dass deren Umsätze getrennt abrufbar sind +Tracelinks: StRS-79, StRS-107 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Mehrbankfähigkeit ist für Unternehmen mit mehreren Bankverbindungen erforderlich +Status: belegt +``` + +``` +ID: StRS-81 +Titel: Verbindungsaufbau zur Bank (FinTS/HBCI) herstellen +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Bankverbindung ist konfiguriert (StRS-80) +Fakt: Eigenständiger Modulordner OnlineBanking/ConnectionDialog für den Verbindungsaufbau, getrennt von der Konfiguration selbst +Aussage: Das System soll den Verbindungsaufbau zur Bank über einen dedizierten Dialog inkl. Fehlerrückmeldung bei fehlgeschlagener Anmeldung ermöglichen. +Ergebnis: Verbindung zur Bank ist hergestellt oder Fehler ist klar rückgemeldet +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/OnlineBanking/ConnectionDialog - Begründung: Eigener Modulordner belegt einen dedizierten Verbindungsdialog; TAN-Verfahren/Fehlerbehandlung nicht im Detail eingesehen +Prüfidee: Verbindungsaufbau mit falschen Zugangsdaten versuchen und prüfen, dass eine verständliche Fehlermeldung erscheint +Tracelinks: StRS-80 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - robuster Verbindungsaufbau inkl. TAN-Verfahren ist für Online-Banking zwingend +Status: belegt +``` + +``` +ID: StRS-82 +Titel: KI-Chat-Assistent für Anwender +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Alle Anwender +Vorbedingung: KI-Anbindung (OpenAI) ist konfiguriert +Fakt: ArtificialIntelligenceChatAppModuleController mit ApiConnector (Modulwurzel) bilden einen dedizierten Chat-Assistenten; Aufrufe aus Fachmodulen (AutomatedBillingView.ArtificialIntelligence.cs, CrmMainView.ArtificialIntelligence.cs, TicketDetailView.ArtificialIntelligence.cs) belegen eine modulübergreifende KI-Integration statt eines isolierten Chat-Fensters +Aussage: Das System soll einen KI-Chat-Assistenten bereitstellen, der sowohl eigenständig als auch kontextuell aus Fachmodulen heraus (Abrechnung, CRM, Ticket) aufrufbar ist. +Ergebnis: Anwender erhält KI-gestützte Unterstützung im jeweiligen fachlichen Kontext +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/ArtificialIntelligence/ApiConnector.cs - Begründung: Zentrale Connector-Klasse belegt die KI-Anbindung + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Finances/Crm/CrmMainView.ArtificialIntelligence.cs - Begründung: Belegt kontextuelle KI-Einbindung direkt im CRM-Modul +Prüfidee: KI-Chat aus dem Ticket-Kontext heraus öffnen und prüfen, dass der Ticketkontext (z. B. Ticketnummer) automatisch in die Konversation übernommen wird +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - modulübergreifende KI-Unterstützung ist ein Differenzierungsmerkmal, sollte im Zielsystem als zentraler Dienst statt Einzelintegrationen gestaltet werden +Status: belegt +``` + +``` +ID: StRS-83 +Titel: Kundenumfragen erstellen und auswerten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Marketing/Vertrieb +Vorbedingung: Kundenfeedback soll strukturiert erhoben werden +Fakt: SurveyMainViewModel mit SurveyAttachmentViewModel (SurveySettings) bilden Erstellung und Anhang-Verwaltung von Umfragen +Aussage: Das System soll die Erstellung, den Versand und die Auswertung von Kundenumfragen inkl. Anhängen unterstützen. +Ergebnis: Umfrageergebnis ist erfasst und auswertbar +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Survey/SurveyMainViewModel.cs - Begründung: Zentrale Klasse belegt den Umfrageprozess +Prüfidee: Umfrage versenden, Antwort erfassen und prüfen, dass sie in der Auswertung korrekt gezählt wird +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kundenumfragen unterstützen Servicequalitätsmessung +Status: belegt +``` + +``` +ID: StRS-84 +Titel: Massenänderungen anhand wiederverwendbarer Vorlagen durchführen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator/Innendienst +Vorbedingung: Gleichartige Änderung soll auf viele Datensätze angewendet werden +Fakt: NewMassUpdateController mit Event MassUpdateTemplateSavedEvent belegt speicherbare, wiederverwendbare Massenänderungsvorlagen +Aussage: Das System soll Massenänderungen an Datensätzen anhand speicherbarer, wiederverwendbarer Vorlagen durchführen können. +Ergebnis: Massenänderung ist auf die gewählten Datensätze angewendet; Vorlage ist für Wiederverwendung gespeichert +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Massenupdates/Event/MassUpdateTemplateSavedEvent.cs - Begründung: Event belegt die Speicherbarkeit von Massenänderungsvorlagen +Prüfidee: Massenänderungsvorlage speichern, erneut aufrufen und prüfen, dass dieselbe Änderung reproduzierbar ausgeführt wird +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - wiederverwendbare Massenänderungen reduzieren wiederkehrenden manuellen Pflegeaufwand +Status: belegt +``` + +``` +ID: StRS-85 +Titel: Zugangsdaten verschlüsselt verwalten und Fernzugriff (RDP/SSH) direkt starten +Ebene: StRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Techniker/Helpdesk-Mitarbeiter +Vorbedingung: Zugangsdaten zu einem Kundensystem (Hotline) sind zu hinterlegen +Fakt: PasswordManagerBL verschlüsselt das Feld "Passwort" mit new AESCryptoLogic().EncryptText(customerHotline.Password, masterKeyResult.Data) (Z. 700) bzw. entschlüsselt mit DecryptText() (Z. 1052, 1179) unter Verwendung eines über CentronConfigurationDbBL.GetHotlineMasterKey() bezogenen Master-Schlüssels; RDPEmbeddedAppModuleController/SSHEmbeddedAppModuleController starten Fernzugriffssitzungen direkt aus dem Passwort-Datensatz; AccessAreaManagement/AccessManagement gliedert Zugangsdaten in Zugangsbereiche +Aussage: Das System soll hinterlegte Zugangsdaten AES-verschlüsselt mit zentral verwaltetem Master-Schlüssel speichern, nach Zugangsbereichen gliedern und den direkten Start von RDP-/SSH-Fernzugriffssitzungen aus dem Zugangsdatensatz heraus ermöglichen. +Ergebnis: Zugangsdaten liegen nie unverschlüsselt in der Datenbank; Fernzugriff ist ohne manuelle Passworteingabe möglich +Belege: + - [PRIMÄR] src/backend/Centron.BL/PasswordManager/PasswordManagerBL.cs, Z. 700, 1051-1052, 1179 - Begründung: Durchsetzende Stelle der Ver-/Entschlüsselung mit AESCryptoLogic und zentralem Master-Schlüssel + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/PasswordManager/RDPEmbeddedAppModuleController.cs - Begründung: Belegt direkten Fernzugriffsstart aus dem Passwort-Manager heraus +Prüfidee: Zugangsdatensatz in der Datenbank direkt einsehen und prüfen, dass das Passwortfeld nicht im Klartext, sondern als AES-Chiffrat vorliegt +Tracelinks: SwRS-8 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - verschlüsselte, zentrale Zugangsdatenverwaltung mit direktem Fernzugriffsstart ist ein Kernwerkzeug für Managed-Service-Techniker +Status: belegt +``` + +``` +ID: StRS-86 +Titel: Kalendersynchronisation und ticketbezogene Termine konfigurieren +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator/Mitarbeiter +Vorbedingung: Externer Kalender (z. B. Outlook) soll synchronisiert werden +Fakt: CalendarSynchronizationSettingsViewModel und AppointmentsForTicketsSettingsViewModel bilden getrennte Konfigurationsbereiche für Kalendersynchronisation bzw. automatisch aus Tickets erzeugte Termine +Aussage: Das System soll den Kalender mit externen Systemen synchronisieren und automatisiert Termine aus Tickets erzeugen können. +Ergebnis: Kalendereinträge sind synchron zwischen c-entron und externem Kalender; Ticket erzeugt bei Bedarf einen Termin +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Calendar/Settings/Synchronization/CalendarSynchronizationSettingsViewModel.cs - Begründung: Klasse belegt Kalendersynchronisation; Synchronisationsrichtung/-konflikte nicht im Detail eingesehen +Prüfidee: Termin in Outlook anlegen und prüfen, dass er nach Synchronisation im c-entron-Kalender erscheint +Tracelinks: StRS-45 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kalendersynchronisation mit Outlook ist im Büroalltag Standard +Status: belegt +``` + +``` +ID: StRS-87 +Titel: QM-Prüfgründe für Belege und Assets pflegen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Qualitätsmanagement +Vorbedingung: Standardisierte Begründung für Rückbuchungen/Reklamationen wird benötigt +Fakt: AssetReasonSettingsViewModel und ReceiptReasonViewModel (QM/Settings) bilden Katalogpflege für Asset- bzw. Belegbegründungen (z. B. RMA-Rückbuchungsgründe) +Aussage: Das System soll standardisierte Begründungskataloge für Asset- und Belegvorgänge (z. B. Reklamationsgründe) pflegbar machen. +Ergebnis: Begründung ist aus einem gepflegten Katalog auswählbar statt freitextlich +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/QM/Settings/ReceiptReasonViewModel.cs - Begründung: Klasse belegt einen gepflegten Begründungskatalog +Prüfidee: Neuen Begründungseintrag anlegen und prüfen, dass er im RMA-Prozess (StRS-44) auswählbar ist +Tracelinks: StRS-44 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - standardisierte Begründungskataloge verbessern Auswertbarkeit von Reklamationsursachen +Status: belegt +``` + +``` +ID: StRS-88 +Titel: Vertragsdaten für Telekom-DIVE-Plattform exportieren +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Mandant vertreibt Telekom-Verträge über die DIVE-Plattform +Fakt: TelekomDiveExportViewModel mit TelekomDiveSubscriptionUnitTypeViewModel/TelekomDiveDistributorViewModel bildet einen strukturierten Export von Abonnement-/Distributor-Daten +Aussage: Das System soll Vertrags-/Abonnementdaten in dem von der Telekom-DIVE-Plattform erwarteten Format exportieren können. +Ergebnis: Exportdatei ist von der DIVE-Plattform verarbeitbar +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/TelekomDive/TelekomDiveExportViewModel.cs - Begründung: Klasse belegt den strukturierten Export; genaues Zielformat nicht im Detail eingesehen +Prüfidee: Export durchführen und Datei gegen die DIVE-Formatspezifikation validieren +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: Sonderfall - anbieterspezifische Schnittstelle zu einem einzelnen Vorleistungspartner (Telekom) +Status: belegt +``` + +``` +ID: StRS-89 +Titel: Konfigurierbares modulbasiertes Startdashboard +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Alle Anwender +Vorbedingung: Benutzer meldet sich an +Fakt: ModulesViewModel/ModulesSlideViewModel (Dashboard/Modules) bilden ein Kachel-Dashboard mit direktem Sprung in Fachmodule +Aussage: Das System soll beim Start ein konfigurierbares Dashboard mit direktem Zugriff auf häufig genutzte Module anzeigen. +Ergebnis: Anwender gelangt per Klick direkt in ein Fachmodul +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Dashboard/Modules/ModulesViewModel.cs - Begründung: Klasse belegt die modulbasierte Startseite +Prüfidee: Modul-Kachel anklicken und prüfen, dass das richtige Fachmodul geöffnet wird +Tracelinks: keine +Konsolidierung: Kandidat: siehe StRS-53 - mehrere Dashboard-Implementierungen (Start-Dashboard, MyCentron-Dashboard, Statistics-Dashboard) im System +Übernahmewürdigkeit: übernehmen - Startdashboard mit Modulzugriff ist zentrale Navigationshilfe +Status: belegt +``` + +``` +ID: StRS-90 +Titel: Oberflächen-Layoutprofile je Benutzer verwalten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Anwender +Vorbedingung: Benutzer möchte individuelles Oberflächen-Layout sichern +Fakt: ManageUiProfileViewModel (Gui/Profiles) bildet die Verwaltung benutzerbezogener Oberflächenprofile +Aussage: Das System soll es Anwendern ermöglichen, individuelle Oberflächen-Layouts als Profil zu speichern und wiederherzustellen. +Ergebnis: Gespeichertes Profil stellt das individuelle Layout wieder her +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Gui/Profiles/ManageUiProfileViewModel.cs - Begründung: Klasse belegt die Profilverwaltung +Prüfidee: Layout anpassen, als Profil speichern, Layout ändern und Profil wiederherstellen; prüfen, dass Originalzustand wiederhergestellt wird +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - individuelle Layoutprofile erhöhen Produktivität vielgenutzter Arbeitsplätze +Status: belegt +``` + +``` +ID: StRS-91 +Titel: Lizenzabgleich für Managed-Service-Provider-Lizenzen +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: MSP-Verantwortlicher +Vorbedingung: Lizenzbestand beim MSP-Anbieter weicht potenziell vom internen Bestand ab +Fakt: MSPComparerAppModuleController mit ComparerViewModel/MspEvaluationHistoryViewModel bildet einen Vergleichsassistenten zwischen intern erfassten und extern bezogenen MSP-Lizenzen +Aussage: Das System soll intern erfasste MSP-Lizenzen mit dem tatsächlichen Bestand beim MSP-Anbieter abgleichen und Abweichungen historisch nachvollziehbar machen. +Ergebnis: Abweichungen zwischen internem und externem Lizenzbestand sind erkannt und historisiert +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/Global/MSPLicensesCompare/ComparerViewModel.cs - Begründung: Klasse belegt den Abgleichsprozess; Datenquelle des externen Bestands nicht im Detail eingesehen +Prüfidee: Künstliche Abweichung zwischen internem und externem Bestand erzeugen und prüfen, dass sie im Abgleich erkannt wird +Tracelinks: StRS-59 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Lizenzabgleich verhindert Über-/Unterlizenzierung im MSP-Geschäft +Status: belegt +``` + +``` +ID: StRS-92 +Titel: Zentrale Geschäftslogik- und Datenzugriffsschicht für alle Fachmodule +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System (alle Clients: WPF, Web, Nexus) +Vorbedingung: Ein Client (WPF-Desktop, Webservice, Nexus) benötigt Zugriff auf Geschäftsdaten +Fakt: Centron.BL/Centron.DAO/Centron.Entities/Centron.Interfaces (2.068+1.131+1.185+764 Dateien) bilden eine von allen Frontends gemeinsam genutzte Schicht; u. a. AppRightsBL (StRS-62), PasswordManagerBL (StRS-85) und AuthenticationTicketBL (SyRS-10) liegen hier +Aussage: Das System soll Geschäftslogik, Datenzugriff und Entitätsmodell in einer von WPF-Desktop-Client, Webservice und Nexus-Weboberfläche gemeinsam genutzten Schicht kapseln, statt sie in den einzelnen Frontends zu duplizieren. +Ergebnis: Fachliche Regeln (z. B. Rechteprüfung, Verschlüsselung) gelten unabhängig vom aufrufenden Client konsistent +Belege: + - [KONTEXT] src/backend/Centron.BL - Begründung: Umfangreichste Schicht (2.068 Dateien) belegt die zentrale Bündelung der Geschäftslogik; vollständige Prüfung aller enthaltenen Regeln ist im Rahmen dieser Breitenanalyse nicht leistbar +Prüfidee: Dieselbe fachliche Regel (z. B. Rechteprüfung) über WPF-Client und Webservice-Aufruf auslösen und identisches Verhalten prüfen +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - gemeinsame Kernschicht ist grundsätzlich migrationsfreundlich; interne Kopplungen (z. B. an NHibernate/ADO) im Zielsystem zu prüfen +Status: belegt +``` + +``` +ID: StRS-93 +Titel: Strukturierten EDI-Datenaustausch mit mehreren Distributoren pflegen +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: System (automatisierter EDI-Prozess) +Vorbedingung: Distributor unterstützt elektronischen Datenaustausch +Fakt: Getrennte Gateway-Ordner EDI_Also, EDI_AlsoCH, EDI_Alltron, EDI_Herweck, EDI_Komsa, EDI_EGIS mit je eigenen XML-Schemaklassen für Delivery/Invoice/Order/Orderresponse (z. B. EDI_Also/Order/xmlOrder240.cs) belegen distributorspezifische EDI-Formate +Aussage: Das System soll Bestellungen, Auftragsbestätigungen, Lieferavise und Rechnungen mit mehreren Distributoren im jeweils distributorspezifischen strukturierten Format elektronisch austauschen. +Ergebnis: EDI-Nachricht ist im vom jeweiligen Distributor erwarteten Format erzeugt/verarbeitet +Belege: + - [PRIMÄR] src/backend/Centron.Gateway/EDI_Also/Order/xmlOrder240.cs - Begründung: Generierte XML-Schemaklasse belegt ein konkretes, versioniertes distributorspezifisches Nachrichtenformat +Prüfidee: Bestellung an zwei unterschiedliche Distributoren senden und prüfen, dass jeweils das korrekte distributorspezifische XML-Format erzeugt wird +Tracelinks: StRS-38 +Konsolidierung: Kandidat: Sechs strukturell ähnliche, aber getrennt implementierte EDI-Anbindungen (Also/AlsoCH/Alltron/Herweck/Komsa/EGIS) - im Zielsystem auf ein gemeinsames EDI-Format-Mapping-Framework zu konsolidieren +Übernahmewürdigkeit: übernehmen - EDI-Anbindung an die wichtigsten IT-Distributoren ist geschäftskritisch für den Einkaufsprozess +Status: belegt +``` + +``` +ID: StRS-94 +Titel: FinTS-Bankanbindung auf Backend-Ebene bereitstellen +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: System +Vorbedingung: Bankverbindung ist konfiguriert (StRS-80) +Fakt: Eigener Gateway-Bereich Centron.Gateway/OnlineBanking kapselt die technische FinTS-Anbindung getrennt von der UI-Schicht (OnlineBanking-Modul, StRS-79-81) +Aussage: Das System soll die technische FinTS/HBCI-Bankanbindung als Backend-Dienst kapseln, den sowohl WPF- als auch potenziell Web-Clients nutzen können. +Ergebnis: Kontoumsätze/-aufträge sind über den Gateway-Dienst abrufbar/versendbar +Belege: + - [KONTEXT] src/backend/Centron.Gateway/OnlineBanking - Begründung: Eigener Gateway-Bereich belegt die Kapselung der Bankanbindung; Protokolldetails (FinTS-Version) nicht im Detail eingesehen +Prüfidee: Kontoabruf über den Gateway-Dienst auslösen und mit dem UI-seitig angezeigten Ergebnis (StRS-79) auf Konsistenz prüfen +Tracelinks: StRS-79 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - gekapselte Bankanbindung ist Voraussetzung für automatisierten Zahlungsabgleich +Status: belegt +``` + +``` +ID: StRS-95 +Titel: Gerätedaten von MSP-Plattformen zentral sammeln +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: System (automatisierter Collector-Prozess) +Vorbedingung: Kunde nutzt eine angebundene MSP-Plattform (Octopus, Wortmann) +Fakt: Centron.Gateway/MspCollector/Octopus (OctopusCustomer.cs) und MspCollector/Wortmann (MspWortmann.cs) bilden getrennte Collector-Implementierungen je Plattform +Aussage: Das System soll Gerätedaten von mehreren angebundenen Managed-Service-Plattformen automatisiert sammeln und für die MSP-Statistik (StRS-59) bereitstellen. +Ergebnis: Gerätedaten der jeweiligen Plattform sind im System verfügbar +Belege: + - [KONTEXT] src/backend/Centron.Gateway/MspCollector/Octopus/OctopusCustomer.cs - Begründung: Eigene Klasse belegt eine plattformspezifische Collector-Implementierung +Prüfidee: Neues Gerät bei einer angebundenen Plattform anlegen und prüfen, dass es nach dem nächsten Collector-Lauf im System erscheint +Tracelinks: StRS-59 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - automatisierte Gerätedatensammlung ist Kern des MSP-Geschäftsmodells +Status: belegt +``` + +``` +ID: StRS-96 +Titel: Strukturierte E-Rechnungsformate (ZUGFeRD/OpenTrans) erzeugen +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: System +Vorbedingung: Rechnung soll als strukturierte E-Rechnung übermittelt werden +Fakt: ZUGFeRD_EXTENDED.cs (Z. 10-26) implementiert den Standard "CrossIndustryInvoice" (Namespace urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100, XSD-generiert) für ZUGFeRD 2.1; OpenTrans1_0-Ordner mit Invoice/Order/Orderresponse ergänzt das ältere openTRANS-Format +Aussage: Das System soll Rechnungen wahlweise im ZUGFeRD-2.1- oder im openTRANS-Format als strukturierte, hybride E-Rechnung erzeugen können. +Ergebnis: Erzeugte E-Rechnung ist gegen den jeweiligen Standard valide +Belege: + - [PRIMÄR] src/backend/Centron.Gateway/ZUGFeRD21_Extended/ZUGFeRD_EXTENDED.cs (Z. 10-26) - Begründung: XSD-generierte Klasse mit Standard-Namespace belegt Standardkonformität unmittelbar +Prüfidee: Erzeugte ZUGFeRD-Rechnung gegen ein öffentlich verfügbares ZUGFeRD-2.1-Validierungstool prüfen +Tracelinks: StRS-12 +Konsolidierung: Kandidat: Zwei parallele E-Rechnungsformate (ZUGFeRD, openTRANS) - im Zielsystem auf den heute rechtlich geforderten Standard (z. B. EN16931/XRechnung) zu konsolidieren +Übernahmewürdigkeit: übernehmen - strukturierte E-Rechnung wird EU-weit zunehmend verpflichtend; Formatwahl im Zielsystem an aktuelle Rechtslage anzupassen +Status: belegt +``` + +``` +ID: StRS-97 +Titel: Anbindung an den c-entron-Portal-Webservice +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: System +Vorbedingung: Mandant nutzt das c-entron-Portal +Fakt: Centron.Gateway/Portal (PortalConstants.cs, WebServiceAccess.cs) sowie eine eigene "Service References/CentronPortalService"-Anbindung (SOAP) bilden die Portal-Integration +Aussage: Das System soll Daten mit dem separaten c-entron-Portal-Webservice über eine dedizierte SOAP-Anbindung austauschen. +Ergebnis: Portal-Daten sind synchronisiert +Belege: + - [KONTEXT] src/backend/Centron.Gateway/Portal/WebServiceAccess.cs - Begründung: Klasse belegt den Zugriff auf den Portal-Webservice; ausgetauschte Datenobjekte nicht im Detail eingesehen +Prüfidee: Datensatz im Portal ändern und prüfen, dass die Änderung nach Synchronisation im System sichtbar ist +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: veraltet - SOAP-basierte "Service References" deuten auf eine ältere Integrationsgeneration hin, im SaaS-Zielsystem durch REST/moderne API zu ersetzen +Status: belegt +``` + +``` +ID: StRS-98 +Titel: Web-API mit zweifacher Authentifizierung (Sitzungsticket/Access-Token) und Anwendungs-Autorisierung +Ebene: StRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Externe/mobile Clients, Nexus, Drittsysteme +Vorbedingung: Client ruft eine mit [Authenticate] geschützte Webservice-Methode auf +Fakt: AuthenticateInterceptor.InterceptExecution() (siehe SyRS-10) authentifiziert wahlweise über Sitzungsticket oder Access-Token und prüft zusätzlich anwendungsbezogene Aufrufberechtigungen (ApplicationKind) sowie eine gesonderte Web-Account-Schranke +Aussage: Das System soll jeden Webservice-Aufruf zentral authentifizieren, dabei zwischen internen Anwendungen und Web-Accounts unterscheiden und nicht autorisierte Aufrufe mit einheitlicher, keine Interna preisgebender Fehlermeldung abweisen. +Ergebnis: Nur authentifizierte und für die jeweilige Anwendung/Methode autorisierte Aufrufe werden ausgeführt +Belege: + - [PRIMÄR] src/webservice/Centron.Host/AspNetCore/WcfBridge/Interception/Interceptors/AuthenticateInterceptor.cs (vollständig, siehe SyRS-10) - Begründung: Zentrale, für alle geschützten Methoden einheitlich durchlaufene Durchsetzungsstelle +Prüfidee: Siehe SyRS-10 +Tracelinks: SyRS-10, SyRS-7, StRS-62 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zentrale, konsistente API-Authentifizierung ist im Zielsystem fortzuführen und um methodenscharfe Scopes zu ergänzen +Status: belegt +``` + +``` +ID: StRS-99 +Titel: Lizenzen und Hardware-IDs für Webservice-Verbindungen verwalten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Neue Installation/Hardware soll mit einer Lizenz verbunden werden +Fakt: ConnectionManagerViewModel mit Dialogs HardwareIdViewModel/LicenseViewModel/AdditionalServiceViewModel (c-entron.misc.ConnectionManager) bildet ein eigenständiges Lizenz-/Hardware-ID-Verwaltungswerkzeug +Aussage: Das System soll Lizenzen an Hardware-Kennungen binden und zusätzliche lizenzpflichtige Dienste separat verwaltbar machen. +Ergebnis: Installation ist mit gültiger, an die Hardware gebundener Lizenz betreibbar +Belege: + - [SEKUNDÄR] src/webservice/c-entron.misc.ConnectionManager/Dialogs/HardwareIdViewModel.cs - Begründung: Klasse belegt Hardware-ID-gebundene Lizenzierung; kryptografisches Bindungsverfahren nicht im Detail eingesehen +Prüfidee: Lizenz auf abweichender Hardware-ID einspielen und prüfen, dass die Aktivierung verweigert wird +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - hardwaregebundene Lizenzierung passt nicht zum SaaS-Zielmodell und ist durch ein abonnementbasiertes Verfahren zu ersetzen +Status: belegt +``` + +``` +ID: StRS-100 +Titel: Web-basiertes Kanban-Ticketboard mit Leistungs-/Vertragszuordnung +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Helpdesk-Mitarbeiter (Web) +Vorbedingung: Ticket ist im System erfasst +Fakt: ServiceBoard/Kanban (KanbanCard, KanbanHand, KanbanType) bildet eine webbasierte Kanban-Ansicht der Tickets; ServiceBoard/TicketDetails/Models (ContractAssignmentType, LeistungAssignmentType) belegt die direkte Zuordnung von Verträgen und abrechenbaren Leistungen zu einem Ticket im Web-Client +Aussage: Das System soll Tickets in einer webbasierten Kanban-Ansicht darstellen und dem Bearbeiter erlauben, Ticket-Leistungen direkt einem Vertrag und einer abrechenbaren Leistungsart zuzuordnen. +Ergebnis: Ticket ist im Kanban sichtbar und mit Vertrag/Leistungsart verknüpft +Belege: + - [SEKUNDÄR] src/nexus/CentronNexus/ServiceBoard/TicketDetails/Models/LeistungAssignmentType.cs - Begründung: Klasse belegt die Zuordnung abrechenbarer Leistungsarten direkt im Web-Ticketboard + - [KONTEXT] src/nexus/CentronNexus/ServiceBoard/Kanban/Model/KanbanCard.cs - Begründung: Belegt die Kanban-Darstellungsform der Tickets +Prüfidee: Ticket im Kanban einer Leistungsart zuordnen und prüfen, dass sie in der Zeit-/Leistungsabrechnung (StRS-20) korrekt erscheint +Tracelinks: StRS-45, StRS-20 +Konsolidierung: Kandidat: Prüfen, ob ServiceBoard (Nexus/Web) und Helpdesk/TicketDetails (WPF, StRS-45) im Zielsystem als eine einzige Web-Ticketverwaltung statt zweier Implementierungen für zwei Clients geführt werden sollen +Übernahmewürdigkeit: übernehmen - webbasiertes Ticketboard ist unmittelbares Vorbild für die Web-/SaaS-Neuimplementierung des Helpdesk +Status: belegt +``` + +``` +ID: StRS-101 +Titel: Web-Kundenportal mit Shop-Funktion (WebCart) +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Kunde (Web-Account) +Vorbedingung: Kunde besitzt einen Web-Account (StRS-75) +Fakt: CentronNexus/Office mit PdfController und Signatur-Modellen (SignatureType, SignatureColor) bildet die Kundenportal-Weboberfläche inkl. Dokumentenansicht/-signatur +Aussage: Das System soll Kunden über ein Web-Portal Zugriff auf ihre Dokumente inkl. elektronischer Signaturmöglichkeit sowie auf den WebCart-Shop (StRS-75) geben. +Ergebnis: Kunde kann sich im Portal anmelden, Dokumente einsehen/signieren und im WebCart bestellen +Belege: + - [SEKUNDÄR] src/nexus/CentronNexus/Office/Controllers/PdfController.cs - Begründung: Klasse belegt die Dokumentenbereitstellung im Kundenportal +Prüfidee: Kunde meldet sich mit Web-Account an und prüft Sichtbarkeit nur der eigenen Dokumente/Bestellungen +Tracelinks: StRS-75, SwRS-7 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Kundenportal ist Kernstück der geplanten Web-/SaaS-Neuimplementierung +Status: belegt +``` + +``` +ID: StRS-102 +Titel: Fertigungsaufträge webbasiert mit Arbeitsschritt-Vorlagen steuern +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Produktionsmitarbeiter (Web) +Vorbedingung: Fertigungsauftrag ist angelegt (StRS-42) +Fakt: ProductionOrderManagement/Model (OrderModel, WorkStepTemplateModel) belegt eine webbasierte Steuerung von Fertigungsaufträgen anhand vordefinierter Arbeitsschritt-Vorlagen +Aussage: Das System soll Fertigungsaufträge webbasiert anhand vordefinierter Arbeitsschritt-Vorlagen abarbeitbar machen. +Ergebnis: Fertigungsauftrag durchläuft die Arbeitsschritte der Vorlage nachvollziehbar +Belege: + - [SEKUNDÄR] src/nexus/CentronNexus/ProductionOrderManagement/Model/WorkStepTemplateModel.cs - Begründung: Klasse belegt vordefinierte Arbeitsschritt-Vorlagen für die Weboberfläche +Prüfidee: Fertigungsauftrag mit Arbeitsschritt-Vorlage abarbeiten und prüfen, dass der Fortschritt je Schritt nachvollziehbar ist +Tracelinks: StRS-42 +Konsolidierung: Kandidat: Abgrenzung zur WPF-seitigen Production/ProductionOrder-Verwaltung (StRS-42) prüfen - ggf. zwei Implementierungen derselben Fertigungssteuerung +Übernahmewürdigkeit: übernehmen - webbasierte Werkerführung ist zeitgemäßer als reine Desktop-Fertigungssteuerung +Status: belegt +``` + +``` +ID: StRS-103 +Titel: Web-Benutzerkonten, Aufgaben und Ticketmuster verwalten +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Kunde/Mitarbeiter benötigt einen Web-Zugang +Fakt: Management/WebAccount/Model (WebAccountAction, WebRightNode Z. 6-12) bildet eine hierarchische Rechtebaum-Darstellung für Web-Accounts analog zur internen Rechtehierarchie (StRS-62); Management/TicketPatterns (TicketPatternTypeHelper) verwaltet Ticket-Mustervorlagen +Aussage: Das System soll Web-Benutzerkonten mit einer hierarchischen Rechtebaum-Struktur sowie wiederverwendbare Ticket-Mustervorlagen zentral verwalten. +Ergebnis: Web-Account besitzt die im Rechtebaum zugewiesenen Rechte; Ticket kann aus einem Muster erzeugt werden +Belege: + - [PRIMÄR] src/nexus/CentronNexus/Management/WebAccount/Model/WebRightNode.cs (Z. 6-12) - Begründung: Datenmodell erzwingt eine hierarchische Baumstruktur (Children) für Web-Rechte, strukturell analog zur internen Rechtehierarchie +Prüfidee: Web-Account-Recht auf Baumebene 2 aktivieren und prüfen, dass abhängige Kindrechte konsistent mitgeführt werden +Tracelinks: StRS-62, SwRS-7 +Konsolidierung: Kandidat: siehe SwRS-7 - strukturell identisches Rechtebaum-Muster für interne (RightsTreeViewModel) und Web-Rechte (WebRightNode) getrennt implementiert +Übernahmewürdigkeit: übernehmen - hierarchische Rechteverwaltung für Web-Accounts ist notwendig; Implementierung im Zielsystem mit internem Modell zusammenzuführen +Status: belegt +``` + +``` +ID: StRS-104 +Titel: Elektronische Dokumentensignatur im Web mit Signaturstil-Auswahl +Ebene: StRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Kunde/Mitarbeiter (Web) +Vorbedingung: Dokument (z. B. SEPA-Mandat, AVV) wartet auf Signatur +Fakt: Office/Models (SignatureType, SignatureColor, SignatureFontFamily) sowie generierte Razor-Komponenten IsolatedSignaturePad und DocumentSigningPage belegen eine Web-Signaturfunktion mit wählbarem Signaturstil; die Stelle, die die Signatur unveränderlich/manipulationssicher in das PDF einbettet (z. B. digitale Signatur/Hash-Versiegelung analog PdfSigningBL, StRS-69), wurde für den Web-Signaturweg nicht lokalisiert +Aussage: Das System soll Dokumente im Web elektronisch signierbar machen, dem Unterzeichner Signaturfarbe/-schriftart zur Auswahl stellen und die Signatur manipulationssicher in das Dokument einbetten. +Ergebnis: Dokument liegt mit eingebetteter, gegen nachträgliche Veränderung gesicherter elektronischer Signatur vor +Belege: + - [SEKUNDÄR] src/nexus/CentronNexus/Office/Models/SignatureType.cs - Begründung: Klasse belegt unterschiedliche Signaturarten und -stile; die für die Sicherheitsaussage (Typ „Sicherheit") entscheidende durchsetzende Stelle der Manipulationssicherheit ist damit nicht belegt + - [HYPOTHESE] Keine durchsetzende Stelle für die manipulationssichere Einbettung im Web-Signaturpfad gefunden - Begründung für Hypothese: Diese Anforderung ist als Sicherheitsanforderung eingestuft und benötigt laut Vorgabe zwingend einen PRIMÄR-Beleg für die durchsetzende Stelle; nur die Stilauswahl (SEKUNDÄR) ist belegt, die eigentliche Signaturversiegelung wurde in Office/DocumentSigning nicht lokalisiert (ggf. identisch mit PdfSigningBL aus StRS-69, aber nicht bestätigt) +Prüfidee: Signiertes Dokument nach Signatur byteweise verändern und prüfen, ob das System die Manipulation erkennt/die Signatur invalidiert +Tracelinks: StRS-65, StRS-73, StRS-69 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Web-Signatur ist gemeinsame technische Grundlage für DSGVO-AVV (StRS-65) und SEPA-Mandat (StRS-73) - Konsolidierungshinweis dort beachten +Status: HYPOTHESE +``` + +``` +ID: StRS-105 +Titel: c-entron-Funktionen in Microsoft Outlook integrieren +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Mitarbeiter (Outlook-Anwender) +Vorbedingung: Outlook-Add-in ist installiert +Fakt: Eigenständiges Projekt CentronNexus.OutlookAddIn (59 Dateien) mit eigener Assembly +Aussage: Das System soll ausgewählte c-entron-Funktionen (z. B. E-Mail-zu-Ticket, Kontaktabgleich) direkt in Microsoft Outlook verfügbar machen. +Ergebnis: Outlook-Anwender kann ohne Wechsel in c-entron zentrale Funktionen nutzen +Belege: + - [KONTEXT] src/nexus/CentronNexus.OutlookAddIn - Begründung: Eigenständiges Projekt belegt eine dedizierte Outlook-Integration; konkrete Funktionen nicht im Detail eingesehen +Prüfidee: E-Mail in Outlook über das Add-in in ein Ticket umwandeln und Vollständigkeit der Übernahme prüfen +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Outlook-Integration reduziert Medienbrüche im Arbeitsalltag +Status: belegt +``` + +``` +ID: StRS-106 +Titel: Produktkatalogdaten von externen Datenlieferanten anreichern +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Einkauf/Artikelstammdatenpflege +Vorbedingung: Artikel benötigt erweiterte Katalogdaten (Bilder, Beschreibungen, technische Merkmale) +Fakt: Vier eigenständige API-Projekte (Centron.APIs.CopDataAccess, EgisDataAccess, ITscopeDataAccess, IcecatDataAccess) mit jeweils eigenen Data-Klassen (z. B. IcecatDataAccess/Data/ProductDescription.cs, ProductImage.cs) bilden strukturell gleichartige Anbindungen an vier verschiedene externe Produktdatenlieferanten +Aussage: Das System soll Artikelstammdaten wahlweise von mehreren externen Produktdatenlieferanten (COP, EGIS, ITscope, Icecat) automatisiert anreichern können. +Ergebnis: Artikel verfügt über angereicherte Katalogdaten (Bild, Beschreibung, Merkmale) des gewählten Lieferanten +Belege: + - [SEKUNDÄR] src/apis/Centron.APIs.IcecatDataAccess/Data/ProductDescription.cs - Begründung: Klasse belegt strukturierte Produktbeschreibungsdaten eines der vier Lieferanten +Prüfidee: Artikel über zwei unterschiedliche Anbieter anreichern und auf widerspruchsfreie Zusammenführung der Daten prüfen +Tracelinks: StRS-27 +Konsolidierung: Kandidat: Vier strukturell gleichartige Produktdaten-APIs (COP/EGIS/ITscope/Icecat) - im Zielsystem auf ein gemeinsames Produktdaten-Anreicherungs-Interface mit austauschbarem Provider zu konsolidieren +Übernahmewürdigkeit: übernehmen - externe Katalogdatenanreicherung reduziert manuelle Artikelpflege erheblich; technische Vervierfachung ist migrationsrelevant +Status: belegt +``` + +``` +ID: StRS-107 +Titel: Bankkontoinformationen über Drittanbieter FinAPI abrufen +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: System +Vorbedingung: Kunde/Mandant hat FinAPI-Zugang autorisiert +Fakt: Centron.APIs.FinAPI/Data (AccessToken.cs, Account.cs, AccountInterfacePaymentCapabilities.cs) bildet die Datenmodelle der FinAPI-Anbindung, einem Kontoinformationsdienst-Aggregator (Drittanbieter gemäß PSD2) +Aussage: Das System soll Kontoinformationen über den PSD2-Kontoinformationsdienst FinAPI als Alternative/Ergänzung zur direkten FinTS-Anbindung (StRS-94) abrufen können. +Ergebnis: Kontoinformationen sind über FinAPI verfügbar, ohne dass c-entron selbst Bankzugangsdaten verwaltet +Belege: + - [SEKUNDÄR] src/apis/Centron.APIs.FinAPI/Data/AccessToken.cs - Begründung: Klasse belegt ein Token-basiertes Authentifizierungsmodell gegenüber FinAPI +Prüfidee: Kontoabruf über FinAPI auslösen und mit direktem FinTS-Abruf (StRS-94) auf inhaltliche Konsistenz prüfen +Tracelinks: StRS-94, StRS-80 +Konsolidierung: Kandidat: Zwei parallele Wege zum Kontoumsatzabruf (direktes FinTS-Gateway StRS-94, PSD2-Aggregator FinAPI) - im Zielsystem auf einen Weg zu konsolidieren +Übernahmewürdigkeit: übernehmen - PSD2-Kontoinformationsdienste sind ein moderner, wartungsärmerer Ansatz als direkte FinTS-Anbindung +Status: belegt +``` + +``` +ID: StRS-108 +Titel: Österreichische ebInterface-E-Rechnungen erzeugen +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: System +Vorbedingung: Rechnungsempfänger verlangt ebInterface-Format (Österreich, insb. öffentlicher Sektor) +Fakt: EbInterfaceLogic.cs (Centron.Api.EbInterface) bildet die Erzeugung des österreichischen E-Rechnungsstandards ebInterface, getrennt von ZUGFeRD/openTRANS (StRS-96) +Aussage: Das System soll Rechnungen für österreichische Geschäftspartner im Standard ebInterface erzeugen können. +Ergebnis: Rechnung liegt im ebInterface-Format vor +Belege: + - [KONTEXT] src/apis/Centron.Api.EbInterface/EbInterfaceLogic.cs - Begründung: Eigene Klasse belegt die Standardimplementierung; Versionsstand nicht im Detail eingesehen +Prüfidee: Ebinterface-Rechnung gegen die offizielle ebInterface-XSD validieren +Tracelinks: StRS-96 +Konsolidierung: Kandidat: siehe StRS-96 - drittes paralleles E-Rechnungsformat neben ZUGFeRD/openTRANS +Übernahmewürdigkeit: übernehmen - für Geschäft mit österreichischen (insb. öffentlichen) Auftraggebern gesetzlich erforderlich +Status: belegt +``` + +``` +ID: StRS-109 +Titel: Sendungsdaten bei mehreren Versanddienstleistern erzeugen +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Lager-/Versandmitarbeiter +Vorbedingung: Lieferschein ist versandfertig +Fakt: Centron.Api.Gls (CentronGlsLogic.cs) und Centron.Api.Shipcloud (CentronShipcloudLogic.cs) bilden getrennte, strukturell ähnliche Anbindungen an zwei Versanddienstleister-APIs inkl. je eigener UploadResult-Klasse für Label-Ergebnisse +Aussage: Das System soll Versandlabel und Sendungsdaten wahlweise über die Spedition GLS direkt oder über den Versanddienstleister-Aggregator Shipcloud erzeugen können. +Ergebnis: Versandlabel liegt vor und ist dem Lieferschein zugeordnet +Belege: + - [SEKUNDÄR] src/apis/Centron.Api.Gls/CentronGlsLogic.cs - Begründung: Klasse belegt die Versandlabel-Erzeugung für GLS +Prüfidee: Lieferschein über beide Anbindungen versenden und Label-Inhalte auf Konsistenz (Absender/Empfänger/Gewicht) prüfen +Tracelinks: StRS-37 +Konsolidierung: Kandidat: GLS-Direktanbindung und Shipcloud-Aggregator decken teilweise denselben fachlichen Zweck (Versandlabel-Erzeugung) ab - im Zielsystem auf eine Versand-Abstraktion mit austauschbarem Carrier zu konsolidieren +Übernahmewürdigkeit: übernehmen - Mehrfach-Carrier-Anbindung ist im Versand geschäftsüblich; Implementierungsdopplung migrationsrelevant +Status: belegt +``` + +``` +ID: StRS-110 +Titel: PDF-Formulare dynamisch aus Belegdaten generieren +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: System +Vorbedingung: Beleg soll als formatiertes PDF ausgegeben werden +Fakt: Eigenständiges Root-Projekt Centron.Api.docuFORM sowie Modules/DataExchange/DocuForm (10 Dateien) bilden zusammen die docuFORM-Integration; DeviceClickCounter/DocuFormApiImport (StRS-7) nutzt denselben Dienst bereits für den umgekehrten Weg (Datenimport statt PDF-Ausgabe) +Aussage: Das System soll PDF-Ausgabedokumente (Belege, Formulare) dynamisch über den docuFORM-Dienst aus den jeweiligen Belegdaten generieren. +Ergebnis: PDF-Dokument entspricht der konfigurierten Formularvorlage mit aktuellen Belegdaten +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/DataExchange/DocuForm - Begründung: Eigener Modulordner belegt die Integration; genaues Formularmapping nicht im Detail eingesehen +Prüfidee: Beleg mit Sonderzeichen/Sonderfällen als PDF ausgeben und auf korrekte Darstellung prüfen +Tracelinks: StRS-7, StRS-69 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - dynamische PDF-Generierung ist für Belegausgabe unverzichtbar +Status: belegt +``` + +``` +ID: StRS-111 +Titel: Adress-/Kontoimport mit feldweiser Validierung +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Adressdaten liegen als Importdatei vor +Fakt: AccountAddressViewModelValidation/AccountAddressContactViewModelValidation (DataImport/AccountImport) belegen dedizierte Validierungsklassen getrennt von den reinen Datenklassen +Aussage: Das System soll importierte Adress-/Kontaktdaten vor der Übernahme feldweise validieren und fehlerhafte Datensätze kenntlich machen. +Ergebnis: Nur valide Datensätze werden übernommen; fehlerhafte sind mit Fehlergrund gekennzeichnet +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/DataExchange/DataImport/AccountImport/AccountAddressViewModelValidation.cs - Begründung: Eigene Validierungsklasse belegt feldweise Prüfung vor Übernahme +Prüfidee: Importdatei mit einer Zeile ohne Pflichtfeld einspielen und prüfen, dass genau diese Zeile als fehlerhaft markiert wird +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - feldweise Importvalidierung verhindert Datenmüll im Adressstamm +Status: belegt +``` + +``` +ID: StRS-112 +Titel: Buchungsdaten für die Finanzbuchhaltung exportieren +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Buchungsperiode ist abzuschließen +Fakt: BookKeepingExportViewModel mit BookKeepingPages (Assistent) bildet den strukturierten Export von Buchungsdaten +Aussage: Das System soll Buchungsdaten periodenbezogen in einem für Finanzbuchhaltungssysteme verarbeitbaren Format exportieren. +Ergebnis: Exportdatei ist im Fibu-System importierbar +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/DataExchange/BookKeeping/BookKeepingExportViewModel.cs - Begründung: Klasse belegt den strukturierten Exportprozess +Prüfidee: Export einer Periode durchführen und Summenabstimmung gegen die Opos-Übersicht (StRS-22) prüfen +Tracelinks: StRS-22, StRS-24 +Konsolidierung: Kandidat: Abgrenzung zu StRS-113 (DATEV-Direktanbindung) prüfen - ggf. zwei Wege für denselben Exportzweck +Übernahmewürdigkeit: übernehmen - Fibu-Export ist buchhalterisch zwingend +Status: belegt +``` + +``` +ID: StRS-113 +Titel: Direkter Datenaustausch mit DATEV +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Mandant nutzt DATEV als Finanzbuchhaltungssystem +Fakt: DatevOnlineViewModel mit BookKeepingReceiptViewModel und PdfSelectionForExport (Belegbild-Export) bildet eine DATEV-spezifische Anbindung inkl. Belegbildversand +Aussage: Das System soll Buchungsdaten inkl. zugehöriger Belegbilder direkt mit DATEV austauschen. +Ergebnis: DATEV erhält Buchungsdaten und zugehörige Belegbilder +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/DataExchange/DatevOnline2020/DatevOnlineViewModel.cs - Begründung: Klasse belegt die DATEV-spezifische Anbindung inkl. Belegbild +Prüfidee: Beleg mit PDF-Anhang exportieren und in DATEV auf korrekte Zuordnung Buchung↔Belegbild prüfen +Tracelinks: StRS-112 +Konsolidierung: Kandidat: siehe StRS-112 +Übernahmewürdigkeit: übernehmen - DATEV ist der verbreitetste Fibu-Standard im deutschsprachigen Mittelstand +Status: belegt +``` + +``` +ID: StRS-114 +Titel: SEPA-Lastschrift-/Überweisungsdateien standardkonform erzeugen +Ebene: StRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Buchhaltung +Vorbedingung: Fällige SEPA-Lastschriften/Überweisungen liegen vor +Fakt: src/backend/Centron.Gateway/DataExchange/PaymentTransactions/Sepa/pain.008.001.02_GBIC_3.xsd belegt die Erzeugung von SEPA-Lastschriftdateien nach dem ISO-20022-Standard pain.008 (deutsche GBIC-3-Ausprägung); IncomingPaymentLogOverviewViewModel protokolliert eingehende Zahlungen +Aussage: Das System soll SEPA-Lastschriftdateien standardkonform nach ISO 20022 (pain.008, GBIC-3) erzeugen und den Zahlungseingang protokolliert nachverfolgen. +Ergebnis: Erzeugte SEPA-Datei ist bankseitig ohne Anpassung einreichbar +Belege: + - [PRIMÄR] src/backend/Centron.Gateway/DataExchange/PaymentTransactions/Sepa/pain.008.001.02_GBIC_3.xsd - Begründung: Offizielles Standard-Schema als Grundlage der Dateierzeugung belegt Standardkonformität unmittelbar +Prüfidee: Erzeugte SEPA-Datei gegen die referenzierte XSD validieren +Tracelinks: StRS-73, StRS-23 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - ISO-20022-Konformität ist für SEPA-Einreichung bei Banken zwingend +Status: belegt +``` + +``` +ID: StRS-115 +Titel: Datenaustausch mit der Telekom-DIVE-Plattform (Schnittstellenebene) +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: System +Vorbedingung: Siehe StRS-88 +Fakt: DataExchange/TelekomDive ergänzt das UI-seitige Modul (StRS-88) um die technische Austauschebene +Aussage: Das System soll die technische Übertragungsebene für den Datenaustausch mit der Telekom-DIVE-Plattform getrennt von der Erfassungsoberfläche (StRS-88) kapseln. +Ergebnis: Exportierte Daten sind an die DIVE-Plattform übertragen +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/DataExchange/TelekomDive - Begründung: Eigener Ordner belegt die Trennung von UI- und Austauschebene +Prüfidee: Übertragung auslösen und Empfang bei der Plattform bestätigen lassen +Tracelinks: StRS-88 +Konsolidierung: nein +Übernahmewürdigkeit: Sonderfall - siehe StRS-88 +Status: belegt +``` + +``` +ID: StRS-116 +Titel: Generischer Datenexport aus c-entron +Ebene: StRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Administrator +Vorbedingung: Daten sollen für externe Auswertung bereitgestellt werden +Fakt: Eigener Modulordner DataExchange/DataExport getrennt von den spezialisierten Exporten (BookKeeping, DATEV, SEPA) +Aussage: Das System soll einen generischen, nicht auf ein Zielsystem spezialisierten Datenexport bereitstellen. +Ergebnis: Exportdatei mit gewählten Daten liegt vor +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/DataExchange/DataExport - Begründung: Eigener Ordner belegt einen generischen, von den spezialisierten Exporten getrennten Exportweg +Prüfidee: Export durchführen und Vollständigkeit gegen Quelldaten prüfen +Tracelinks: keine +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - generischer Export bleibt auch im Zielsystem als Fallback sinnvoll +Status: belegt +``` + +``` +ID: StRS-117 +Titel: Ergänzende Konnektoren für Remote-Monitoring und filialweise Lieferantenbestellung +Ebene: StRS +Typ: Schnittstelle +Qualitätsmerkmal: +Akteur: System +Vorbedingung: Mandant nutzt Remote-Monitoring-Tools bzw. hat mehrere bestellende Filialen +Fakt: DataExchange/Rmm (Remote Monitoring Management) und DataExchange/SupplierOrderPerBranch bilden zwei unabhängige Zusatzkonnektoren +Aussage: Das System soll Daten aus Remote-Monitoring-Tools verarbeiten und Lieferantenbestellungen filialweise trennen können. +Ergebnis: RMM-Daten sind übernommen; Filialbestellungen sind korrekt zugeordnet +Belege: + - [KONTEXT] src/centron/Centron.WPF.UI/Modules/DataExchange/SupplierOrderPerBranch - Begründung: Eigener Ordner belegt filialweise Trennung von Lieferantenbestellungen +Prüfidee: Bestellung für zwei Filialen auslösen und prüfen, dass sie getrennt beim Lieferanten ankommen +Tracelinks: StRS-38 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - filialweise Bestelltrennung ist für Filialisten mit eigenständiger Belieferung erforderlich +Status: belegt +``` + +``` +ID: StRS-118 +Titel: Containerisierte Bereitstellung von Webservice und Nexus über CI/CD-Pipelines +Ebene: StRS +Typ: nicht-funktional +Qualitätsmerkmal: Übertragbarkeit +Akteur: Betrieb/DevOps +Vorbedingung: Neue Version soll ausgeliefert werden +Fakt: docker/c-entron-webservice/Dockerfile, docker/compose/compose.yaml sowie azure/build-templates (build-centron-net.yaml, build-nexus.yaml, build-web-service.yaml) und azure-blazor/security-pipeline.yaml belegen containerisierte Builds mit dedizierter Sicherheits-Pipeline für die Nexus-Blazor-Anwendung +Aussage: Das System soll Webservice und Nexus als Container über automatisierte CI/CD-Pipelines inkl. dedizierter Sicherheitsprüfung ausliefern. +Ergebnis: Neue Version ist reproduzierbar containerisiert ausgerollt; Sicherheitsprüfung ist Teil der Pipeline +Belege: + - [PRIMÄR] docker/c-entron-webservice/Dockerfile - Begründung: Konkrete Container-Build-Definition belegt containerisierte Auslieferung unmittelbar + - [SEKUNDÄR] azure-blazor/security-pipeline.yaml - Begründung: Eigene Pipeline-Datei belegt eine dedizierte Sicherheitsprüfung; konkrete Scan-Tiefe nicht im Detail eingesehen +Prüfidee: Pipeline-Lauf mit bewusst eingebauter Sicherheitslücke beobachten und prüfen, dass die Security-Pipeline den Build stoppt +Tracelinks: StRS-98 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - containerisierte, pipeline-gestützte Auslieferung mit Sicherheitsprüfung ist direkte Grundlage für den SaaS-Betrieb des Zielsystems +Status: belegt +``` + diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/SwRS.md b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/SwRS.md new file mode 100644 index 00000000..e9d3ffeb --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/SwRS.md @@ -0,0 +1,166 @@ +# Software Requirements Specification (SwRS) – c-entron ERP-Suite + +Nach ISO/IEC/IEEE 29148:2018. Komponenten, Datenmodelle, software-interne Regeln. IDs: `SwRS-`, laufend über alle Module. + +--- + +``` +ID: SwRS-1 +Titel: CanAccept()-Gate für den Kundenanlage-Dialog +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente MakeCustomerViewModel +Vorbedingung: Dialog "Kundendaten eingeben" ist geöffnet +Fakt: CanAccept() (Z. 244-293) ist als Predicate von DelegateCommand AcceptCommand (Z. 210) verdrahtet; DevExpress.Mvvm.DelegateCommand ruft CanAccept() bei jeder Eigenschaftsänderung erneut auf und (de-)aktiviert den zugehörigen Button +Aussage: Die Komponente MakeCustomerViewModel soll den Speicherbefehl des Kundenanlage-Dialogs an das Prädikat CanAccept() binden, sodass der Button automatisch reagiert, ohne dass der Anwender manuell eine Prüfung anstoßen muss. +Ergebnis: Schaltfläche "Übernehmen" ist genau dann aktiv, wenn CanAccept() true liefert +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Finances/Crm/MakeCustomerViewModel.cs, Zeile 210 (AcceptCommand = new DelegateCommand(this.Accept, this.CanAccept)) - Begründung: Verdrahtung von Commandausführung und Prüfprädikat an der durchsetzenden Stelle +Prüfidee: Unit-Test, der CanAccept() mit einer Kombination gesetzter/nicht gesetzter Pflichtfelder aufruft und den erwarteten bool-Rückgabewert prüft +Tracelinks: SyRS-1 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Command/CanExecute-Bindung ist Standardmuster und im Zielsystem als deklarative Validierung abzubilden +Status: belegt +``` + +``` +ID: SwRS-2 +Titel: Rechteabhängige Freigabe von Kampagnenfunktionen +Ebene: SwRS +Typ: funktional +Qualitätsmerkmal: +Akteur: Komponente CampaignMainViewModel +Vorbedingung: Kampagnenübersicht ist geladen +Fakt: Felder UserCanEditCampaign und UserCanOpenCampaign (Z. 37, 40) steuern laut Namensgebung und Verwendung im ViewModel die Aktivierung von Bearbeiten-/Öffnen-Funktionen; die Herkunft der Werte (Rechteservice) wurde im Rahmen dieser Analyse nicht bis zur prüfenden Stelle zurückverfolgt +Aussage: Die Komponente CampaignMainViewModel soll Bearbeiten- und Öffnen-Funktionen für Kampagnen abhängig von vorab ermittelten Berechtigungsflags freigeben oder sperren. +Ergebnis: UI-Funktionen sind entsprechend der Berechtigungsflags aktiv/inaktiv +Belege: + - [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Finances/Campaigns/CampaignMainViewModel.cs (Z. 37, 40) - Begründung: Feldnamen belegen die UI-seitige Rechteauswertung; die serverseitig prüfende Stelle ist damit nicht belegt, daher sekundär statt primär und keine Sicherheits-Risikoeinstufung ohne PRIMÄR-Beleg +Prüfidee: Benutzer ohne Kampagnen-Bearbeitungsrecht anmelden und prüfen, dass die Bearbeiten-Funktion in der UI deaktiviert ist UND ein direkter Service-Aufruf serverseitig abgelehnt wird +Tracelinks: StRS-3 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - rechteabhängige Funktionsfreigabe ist Standardanforderung; serverseitige Durchsetzung im Zielsystem verifizieren (siehe Hypothese) +Status: HYPOTHESE +``` + +``` +ID: SwRS-3 +Titel: Update statt Duplikat bei bestehendem Sonderpreis +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente PositionToSpecialPriceViewModel +Vorbedingung: Für Artikel/Kundenklasse existiert bereits ein AccountSpecialPriceDTO +Fakt: Bei Fund eines existingSpecialPrice werden dessen Felder ArticleDescription, Comment, ValueKind, Value, ValidFrom, ValidTo mit den neuen Werten überschrieben und derselbe Datensatz (specialPriceToSave = existingSpecialPrice, Z. 121) gespeichert, statt einen neuen Datensatz anzulegen (Kommentar Z. 113: "Make sure to update the existing one, to not create duplicates") +Aussage: Die Komponente PositionToSpecialPriceViewModel soll bei Bestätigung des Überschreibens den bestehenden Sonderpreis-Datensatz aktualisieren, statt einen weiteren Datensatz mit gleicher Artikel-/Kundenklassen-Zuordnung anzulegen. +Ergebnis: Je Artikel/Kundenklasse existiert höchstens ein Sonderpreis-Datensatz +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Finances/Receipts/PositionToSpecialPrice/PositionToSpecialPriceViewModel.cs, Z. 113-121 - Begründung: Code-Kommentar und Zuweisung belegen explizit die Duplikatvermeidung als bewusste Entwurfsentscheidung +Prüfidee: Zwei Sonderpreise für denselben Artikel/dieselbe Kundenklasse anlegen und in der Datenbank prüfen, dass nur ein Datensatz existiert +Tracelinks: SyRS-2 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Datenintegritätsregel ohne erkennbaren Workaround-Charakter +Status: belegt +``` + +``` +ID: SwRS-4 +Titel: Länderspezifische Steuersatzliste als einzige Quelle für ChangeTaxRateViewModel +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente ChangeTaxRateViewModel +Vorbedingung: Dialog "Mehrwertsteuer ändern" wird initialisiert +Fakt: InitializeAsync(int? taxI3D) ruft IValueAddedTaxLogic.GetVATByCountry(CentronApplication.Instance.DefaultCountry.I3D) auf und befüllt TaxRates ausschließlich mit dem Ergebnis; SelectedTaxRate wird per I3D-Abgleich aus genau dieser Liste vorbelegt +Aussage: Die Komponente ChangeTaxRateViewModel soll die auswählbaren Steuersätze ausschließlich aus dem länderspezifischen Ergebnis von IValueAddedTaxLogic.GetVATByCountry beziehen, ohne eigene oder erweiterte Werte zuzulassen. +Ergebnis: TaxRates-Liste enthält genau die vom Backend für das Land gelieferten Sätze +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Finances/Receipts/ChangeTaxRate/ChangeTaxRateViewModel.cs, Methode InitializeAsync() (Z. 41-48) - Begründung: Durchsetzende Stelle, die die Datenquelle der Auswahlliste auf den Backend-Aufruf beschränkt +Prüfidee: Backend-Antwort auf zwei Steuersätze begrenzen und prüfen, dass der Dialog exakt diese zwei Optionen anzeigt +Tracelinks: StRS-14 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zentrale, länderabhängige Steuersatzquelle vermeidet inkonsistente Sätze +Status: belegt +``` + +``` +ID: SwRS-5 +Titel: Berechnungsregel für OpenPrice/OpenPriceFC in der Belegsuche +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente InvoiceReceiptSearchConfiguration (Centron.BL) +Vorbedingung: Rechnungsdatensatz RechKopf (AK) wird für Opos/Zahlungserfassung gelesen +Fakt: OpenPrice = IIF(ISNULL(AK.MwstNichtAusweisbar,0)=0, AK.Brutto, AK.Netto) − (ISNULL(AK.Bezahlt,0) / AK.CurrencyFactor); OpenPriceFC = ROUND((IIF(...)*AK.CurrencyFactor) − ISNULL(AK.Bezahlt,0), 2) (Z. 71-72) +Aussage: Die Komponente InvoiceReceiptSearchConfiguration soll den offenen Rechnungsbetrag in Haus- und Fremdwährung einheitlich aus Brutto-/Netto-Betrag, Umsatzsteuerausweisbarkeit, bereits bezahltem Betrag und Währungsfaktor ableiten, damit alle lesenden Module (Opos, Zahlungserfassung, Mahnwesen) denselben Wert erhalten. +Ergebnis: OpenPrice/OpenPriceFC sind für alle Verbraucher dieser zentralen Abfrage konsistent +Belege: + - [PRIMÄR] src/backend/Centron.BL/WebServices/Sales/Receipts/ReceiptSearch/InvoiceReceiptSearchConfiguration.cs, Z. 71-72 - Begründung: Einzige durchsetzende Berechnungsstelle, aus der Opos-Übersicht und Zahlungserfassung ihre Werte beziehen +Prüfidee: Unit-/Integrationstest mit MwstNichtAusweisbar=1, Bezahlt>0 und CurrencyFactor≠1 gegen die erwartete Formel prüfen +Tracelinks: SyRS-2, StRS-22, StRS-23 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - zentrale, einheitliche Berechnungsstelle vermeidet abweichende Parallelberechnungen in Opos/Zahlungserfassung/Mahnwesen +Status: belegt +``` + +``` +ID: SwRS-6 +Titel: Datenmodell Sichtrus/Sichmemb für gruppenbasierte Rechte +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente AppRightsBL +Vorbedingung: Rechteprüfung für einen Benutzer wird angestoßen +Fakt: GetAllAppRightsFromUser() (Z. 651-664) verknüpft dbo.Sichtrus (Spalten Gruppe, Recht) über die Gruppen-ID mit dbo.Sichmemb (Spalten Gruppe, Benutzer) und liefert alle Recht-IDs, die irgendeiner Gruppe des Benutzers zugeordnet sind +Aussage: Die Komponente AppRightsBL soll das Rechtemodell als Zuordnung Gruppe→Recht (Sichtrus) getrennt von der Zuordnung Benutzer→Gruppe (Sichmemb) führen, sodass sich ein Recht nie direkt, sondern immer nur über eine Gruppe einem Benutzer zuordnen lässt. +Ergebnis: Effektive Rechte eines Benutzers ergeben sich als Vereinigungsmenge der Rechte all seiner Gruppen +Belege: + - [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs, Z. 653-656 (SQL-Text) - Begründung: Durchsetzende Datenbankabfrage, die das Rechtemodell exakt definiert +Prüfidee: Benutzer zwei Gruppen mit je einem unterschiedlichen Recht zuordnen und prüfen, dass GetAllAppRightsFromUser() beide Rechte zurückliefert +Tracelinks: StRS-62 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - reines Gruppenmodell ohne Benutzer-Einzelrechte vereinfacht Administration und Auditierbarkeit +Status: belegt +``` + +``` +ID: SwRS-7 +Titel: Getrennte Rechtemodelle für interne Benutzer und Web-Accounts +Ebene: SwRS +Typ: Daten +Qualitätsmerkmal: +Akteur: Komponente AppRightsBL +Vorbedingung: Rechteprüfung für einen Web-Account (Kundenportal/Nexus) wird angestoßen +Fakt: HasWebAccountRight() (Z. 666-677) nutzt eine vollständig getrennte Datenquelle (Tabelle WebAccountsRights, Spalte WebRightsI3D) gegenüber HasUserRight() für interne Benutzer (Sichtrus/Sichmemb); beide Methoden liegen zwar in derselben Klasse AppRightsBL, referenzieren aber getrennte Entitäten AppRight vs. WebRights +Aussage: Die Komponente AppRightsBL soll interne Benutzerrechte und Web-Account-Rechte als zwei fachlich getrennte, aber strukturell gleichartige Modelle (Objekt→Recht-Zuordnung) führen. +Ergebnis: Web-Accounts erhalten ausschließlich über WebAccountsRights geprüfte Rechte, unabhängig vom internen Rechtemodell +Belege: + - [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs, Z. 666-691 - Begründung: Durchsetzende Stelle, die ein zur internen Rechteprüfung strukturell paralleles, aber datenseitig getrenntes Modell implementiert +Prüfidee: Web-Account und internen Benutzer mit identischem Namen aber unterschiedlichen Rechten anlegen und prüfen, dass sich Web-Zugriff und interner Zugriff unabhängig voneinander verhalten +Tracelinks: StRS-62, StRS-101 (Nexus) +Konsolidierung: Kandidat: Zwei strukturell gleichartige, aber datenseitig getrennte Rechtemodelle (AppRight/Sichtrus für interne Benutzer, WebRights für Web-Accounts) - im Zielsystem als ein gemeinsames Rechtemodell mit Geltungsbereich zu konsolidieren +Übernahmewürdigkeit: Workaround - historisch getrennt gewachsene Rechtemodelle für zwei Kanäle; im SaaS-Zielsystem mit einheitlichem Identitätsmodell zusammenzuführen +Status: belegt +``` + +``` +ID: SwRS-8 +Titel: AES-Verschlüsselung von Zugangsdaten mit zentralem Master-Schlüssel +Ebene: SwRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: Komponente PasswordManagerBL +Vorbedingung: Zugangsdatensatz wird gespeichert oder gelesen +Fakt: Speichern: new AESCryptoLogic().EncryptText(customerHotline.Password, masterKeyResult.Data) (Z. 700); Lesen: new AESCryptoLogic().DecryptText(propertyValue?.ValueEncryptedString, masterKey) (Z. 1051-1052) bzw. (Z. 1179); der Master-Schlüssel selbst stammt aus CentronConfigurationDbBL.GetHotlineMasterKey() (Z. 551), also einer von der Fachdatenbank getrennten Konfigurationsdatenbank +Aussage: Die Komponente PasswordManagerBL soll jedes Passwortfeld beim Schreiben mit AES und einem aus einer getrennten Konfigurationsdatenbank bezogenen Master-Schlüssel verschlüsseln und beim Lesen entsprechend entschlüsseln, sodass ein Zugriff auf die Fachdatenbank allein nicht zur Preisgabe der Zugangsdaten führt. +Ergebnis: ValueEncryptedString enthält niemals Klartext; Klartext existiert nur transient nach Entschlüsselung mit korrektem Master-Schlüssel +Belege: + - [PRIMÄR] src/backend/Centron.BL/PasswordManager/PasswordManagerBL.cs, Z. 700, 1051-1052, 1179, 551 - Begründung: Durchsetzende Ver-/Entschlüsselungsstellen und Herkunft des Master-Schlüssels aus getrennter Konfigurationsdatenbank +Prüfidee: Master-Schlüssel-Zugriff simulieren und prüfen, dass ohne ihn kein aus der Fachdatenbank gelesener ValueEncryptedString entschlüsselbar ist +Tracelinks: StRS-85 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Trennung von Chiffrat und Schlüssel auf getrennte Datenbanken ist ein sinnvolles Sicherheitsmuster für das Zielsystem +Status: belegt +``` + diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/SyRS.md b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/SyRS.md new file mode 100644 index 00000000..5ef29112 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/SyRS.md @@ -0,0 +1,207 @@ +# System Requirements Specification (SyRS) – c-entron ERP-Suite + +Nach ISO/IEC/IEEE 29148:2018. Systemverhalten, Schnittstellen, Performance-, Sicherheitsanforderungen. IDs: `SyRS-`, laufend über alle Module. + +--- + +``` +ID: SyRS-1 +Titel: Konfigurierbares Pflichtfeld-Set bei Objekterzeugung prüfen +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System (CRM-Teilsystem) +Vorbedingung: Anwender löst die Erzeugung eines neuen fachlichen Objekts (hier: AccountType "Customer") aus einem bestehenden Datensatz aus +Fakt: MakeCustomerViewModel.CanAccept() liest 20 Boolean-Flags aus CrmSettings/CurrentAccount (z. B. IsAccountEmailRequired) und verknüpft sie jeweils mit einer Nullprüfung des zugehörigen Eingabefelds, bevor AcceptCommand ausführbar wird +Aussage: Das System soll vor dem Anlegen eines Kunden aus einem Adressstamm-Datensatz alle als Pflichtfeld konfigurierten Angaben auf Vollständigkeit prüfen und die Speicherung erst danach zulassen. +Ergebnis: Speicherbefehl ist genau dann ausführbar, wenn alle konfigurierten Pflichtfelder befüllt sind +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Finances/Crm/MakeCustomerViewModel.cs, Methode CanAccept() (Z. 244-293) - Begründung: Durchsetzende Stelle der Pflichtfeldprüfung vor Freigabe des Speicherbefehls +Prüfidee: Alle Pflichtfeld-Flags in CrmSettings deaktivieren und prüfen, dass der Dialog ohne Eingaben speicherbar ist; danach ein Flag aktivieren und Gegenprobe durchführen +Tracelinks: StRS-2 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - konfigurierbare Pflichtfelder je Mandant sind ein wiederkehrendes Muster, das im Zielsystem als generischer Validierungsmechanismus vorgesehen werden sollte +Status: belegt +``` + +``` +ID: SyRS-2 +Titel: Duplikatprüfung beim Anlegen eines Sonderpreises aus der Belegposition +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System (Belegerfassung) +Vorbedingung: Anwender legt aus einer Belegposition heraus einen neuen Sonderpreis für Artikel/Kundenklasse an +Fakt: PositionToSpecialPriceViewModel.CreateSpecialPrices() (Z. 80-131) lädt bestehende Sonderpreise über IAccountSpecialPriceLogic.GetAccountSpecialPricesAsync(), sucht je Artikel (ArticleI3D) einen bereits vorhandenen Sonderpreis und fragt bei Fund per Dialog "Sonderpreis existiert bereits" (Z. 100-108) nach, ob überschrieben werden soll; bei Ablehnung wird die Zeile übersprungen (continue, Z. 111), bei Zustimmung der bestehende Datensatz aktualisiert statt dupliziert (Z. 114-121) +Aussage: Das System soll beim Anlegen eines Sonderpreises aus einer Belegposition heraus prüfen, ob für Artikel und Kundenklasse bereits ein Sonderpreis existiert, und eine explizite Anwenderentscheidung einholen, statt stillschweigend einen Duplikatsatz anzulegen. +Ergebnis: Es existiert höchstens ein aktiver Sonderpreis je Artikel/Kundenklasse-Kombination, sofern der Anwender das Überschreiben bestätigt oder ablehnt +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Finances/Receipts/PositionToSpecialPrice/PositionToSpecialPriceViewModel.cs, Methode CreateSpecialPrices() (Z. 80-131) - Begründung: Durchsetzende Stelle, die Duplikate durch Update des bestehenden Datensatzes statt Neuanlage verhindert und den Anwender aktiv einbindet +Prüfidee: Für einen Artikel mit bereits bestehendem Sonderpreis einen zweiten Sonderpreis aus einer Belegposition anlegen und prüfen, dass der Bestätigungsdialog erscheint und bei "Nein" kein zweiter Datensatz entsteht +Tracelinks: StRS-1 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Duplikatvermeidung bei Sonderpreisen ist eine sinnvolle Datenintegritätsregel +Status: belegt +``` + +``` +ID: SyRS-3 +Titel: Auftragsbezogene Anzahlungsrechnungen für die Schlussrechnung bereitstellen +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System (Belegverwaltung) +Vorbedingung: Schlussrechnungserstellung zu einem Auftrag wird angestoßen +Fakt: LoadRelatedDownPaymentInvoices() filtert über ReceiptSearchFilter mit DownPaymentForOrderI3D=orderI3D und ReceiptKinds=InvoiceClass inkl. bereits abgeschlossener Belege (IncludeClosedReceipts=true), lädt zu jedem Treffer den vollständigen ReceiptInvoiceDTO nach +Aussage: Das System soll beim Auslösen der Schlussrechnungserstellung alle zu einem Auftrag gehörenden Anzahlungsrechnungen – einschließlich bereits abgeschlossener – vollständig auflösen und für die Weiterverarbeitung bereitstellen. +Ergebnis: Liste vollständiger Anzahlungsrechnungs-DTOs zum Auftrag liegt der Schlussrechnungserstellung vor +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Finances/Receipts/DownPayment/FinalInvoice/OrderToFinalInvoiceHelper.cs, Methode LoadRelatedDownPaymentInvoices() (Z. 27-47) - Begründung: Durchsetzende Stelle des Suchfilters inkl. expliziten Einschlusses abgeschlossener Anzahlungsrechnungen +Prüfidee: Auftrag mit einer bereits abgeschlossenen und einer offenen Anzahlungsrechnung versehen und prüfen, dass LoadRelatedDownPaymentInvoices() beide zurückliefert +Tracelinks: StRS-13 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - vollständige Erfassung aller Anzahlungen unabhängig vom Abschlussstatus ist für eine korrekte Schlussrechnung zwingend +Status: belegt +``` + +``` +ID: SyRS-4 +Titel: Mahnfähigkeit eines Belegs serverseitig aus Persistenzdaten ableiten +Ebene: SyRS +Typ: funktional +Qualitätsmerkmal: +Akteur: System (Mahnwesen) +Vorbedingung: Mahnlauf wird für eine Menge fälliger Rechnungen vorbereitet +Fakt: Die Spalten AK.Mahnstufe und AK.MahnStop am Rechnungskopf (RechKopf) werden 1:1 in DunningLevel/DunningStop der Belegsuche übernommen (InvoiceReceiptSearchConfiguration.cs Z. 86-87) und von DunningItemViewModel.EvaluateSelectionValidity() zur Ausschlussprüfung herangezogen; das bereinigte DueDate (Z. 56) ist Grundlage der Prüfung "Rechnung hat kein Fälligkeitsdatum" +Aussage: Das System soll Mahnstufe, Mahnstopp und Fälligkeitsdatum als persistente Belegattribute führen und der Mahnlaufvorbereitung als konsistente, serverseitig ermittelte Datenbasis bereitstellen. +Ergebnis: Mahnlaufvorbereitung erhält für jede Rechnung konsistente Mahnstufe/-stopp/-fälligkeit ohne clientseitige Neuberechnung +Belege: + - [PRIMÄR] src/backend/Centron.BL/WebServices/Sales/Receipts/ReceiptSearch/InvoiceReceiptSearchConfiguration.cs, Z. 56, 86-87 - Begründung: Durchsetzende Stelle der Datenableitung auf Serverseite, die die UI-Prüfung in DunningItemViewModel erst ermöglicht +Prüfidee: AK.FaelligAm auf einen Platzhalterwert ≤2 setzen und prüfen, dass DueDate in der Belegsuche NULL liefert und der Beleg im Mahnlauf als "ohne Fälligkeitsdatum" ausgeschlossen wird +Tracelinks: StRS-21 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - serverseitige, konsistente Datenbasis für den Mahnlauf ist Voraussetzung für ein rechtssicheres Mahnwesen +Status: belegt +``` + +``` +ID: SyRS-5 +Titel: Nebenläufige Bearbeitung von Belegen durch Sperr- und Versionskennung absichern +Ebene: SyRS +Typ: nicht-funktional +Qualitätsmerkmal: Zuverlässigkeit +Akteur: System (Belegverwaltung) +Vorbedingung: Zwei Benutzer öffnen denselben Beleg gleichzeitig +Fakt: RechKopf führt sowohl LockUser (AK.LockUser, ausgewertet als LockedBy) als auch eine GUID-Spalte GUI3D (ausgewertet als ConcurrencyControlGuid) gemäß InvoiceReceiptSearchConfiguration.cs Z. 55, 78; zusätzlich werden CreatedThroughApplicationVersion/ChangedThroughApplicationVersion (Z. 83-84) je Beleg geführt +Aussage: Das System soll parallele Bearbeitung desselben Belegs durch eine kombinierte Sperrbenutzer- und Versions-/GUID-Kennung erkennen und einen erneuten Speichervorgang bei zwischenzeitlicher Änderung durch einen anderen Benutzer verhindern. +Ergebnis: Konkurrierende Änderungen an einem Beleg führen zu einer erkennbaren Konfliktmeldung statt stillem Überschreiben +Belege: + - [PRIMÄR] src/backend/Centron.BL/WebServices/Sales/Receipts/ReceiptSearch/InvoiceReceiptSearchConfiguration.cs, Z. 55, 78, 83-84 - Begründung: Persistente Felder LockUser und GUI3D belegen einen Sperr-/Konfliktmechanismus auf Datenebene; die konkrete Konfliktbehandlung beim Speichern (Vergleich/Abweisung) wurde innerhalb dieser Analyse nicht bis zur Schreibstelle zurückverfolgt +Prüfidee: Beleg in zwei Sitzungen gleichzeitig öffnen, in Sitzung A speichern, danach in Sitzung B speichern und prüfen, dass Sitzung B einen Konflikt anhand der abweichenden GUID/des LockUser erkennt statt die Änderung aus A stillschweigend zu verwerfen +Tracelinks: StRS-12 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Konflikterkennung bei Mehrbenutzerzugriff ist für ein Mehrbenutzer-ERP zwingend; Umsetzungsdetail im Zielsystem zu verifizieren +Status: HYPOTHESE +``` + +``` +ID: SyRS-6 +Titel: Pflichtangabe eines Ablaufdatums bei Erzeugung persönlicher API-Token +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: System (Personal-Access-Token-Verwaltung) +Vorbedingung: Mitarbeiter erzeugt ein neues persönliches API-Token +Fakt: CreateToken() (Z. 157-169) übernimmt ExpiresAt aus dem Erzeugungsdialog in das gespeicherte Token; kein Codepfad innerhalb dieser Klasse erzeugt ein Token ohne ExpiresAt-Wert +Aussage: Das System soll bei der Erzeugung eines persönlichen API-Tokens zwingend ein Ablaufdatum erfassen und mit dem Token persistieren. +Ergebnis: Jedes erzeugte Token trägt ein Ablaufdatum +Belege: + - [PRIMÄR] src/centron/Centron.WPF.UI/Modules/MyCentron/PersonalSettings/AccessTokens/PersonalAccessTokenSettingsViewModel.cs, Methode CreateToken() (Z. 157-169) - Begründung: Durchsetzende Stelle der Token-Erzeugung, die ExpiresAt aus dem Dialog übernimmt +Prüfidee: Token-Erzeugungsdialog ohne Auswahl eines Ablaufdatums abschließen und prüfen, ob ein Standardwert gesetzt oder die Erzeugung verweigert wird +Tracelinks: StRS-51 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - verpflichtendes Ablaufdatum begrenzt das Risiko dauerhaft gültiger, kompromittierter Token +Status: belegt +``` + +``` +ID: SyRS-7 +Titel: Ablaufende persönliche API-Token beim API-Zugriff serverseitig zurückweisen +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: System (Webservice-Authentifizierung, AccessTokenBL) +Vorbedingung: API-Aufruf mit persönlichem Zugriffstoken trifft am Webservice ein +Fakt: AccessTokenBL.ValidateToken() (Z. 377-419) hasht das übergebene Token (HashToken) und vergleicht ausschließlich den Hash gegen TokenHash in der DB (Z. 387-389); bei !token.IsActive (Z. 394-399) oder token.IsExpired (Z. 401-406) wird der Zugriff mit protokollierter Begründung ("Token ist deaktiviert"/"Token ist abgelaufen", AccessTokenLogActionType.ValidationFailed) abgelehnt; jeder erfolgreiche Aufruf wird zusätzlich mit apiMethod und ipAddress protokolliert (Z. 413-416) und die Funktion selbst ist lizenzpflichtig (LicenseManager.HasLicense(AccessTokenModule), Z. 382-383) +Aussage: Das System soll beim API-Zugriff mit einem persönlichen Token dessen Hash gegen die gespeicherten, gehashten Token prüfen, deaktivierte und abgelaufene Token zurückweisen und jeden Validierungsversuch (erfolgreich wie fehlgeschlagen) mit IP-Adresse und aufgerufener Methode protokollieren. +Ergebnis: Abgelaufenes oder deaktiviertes Token wird von der Webservice-Schicht mit Audit-Log-Eintrag abgelehnt; Token liegt nie im Klartext in der Datenbank +Belege: + - [PRIMÄR] src/backend/Centron.BL/Administration/AccessTokens/AccessTokenBL.cs, Methode ValidateToken() (Z. 377-419) - Begründung: Durchsetzende Stelle mit Hash-Vergleich, Aktiv-/Ablaufprüfung und lückenloser Protokollierung + - [PRIMÄR] src/webservice/Centron.Host/AspNetCore/WcfBridge/Interception/Interceptors/AuthenticateInterceptor.cs, Z. 51-58 - Begründung: Ruft bei fehlgeschlagener Ticket-Validierung ValidateToken() als zweiten Authentifizierungsweg für jeden mit [Authenticate] markierten API-Aufruf auf +Prüfidee: Token mit ExpiresAt in der Vergangenheit gegen einen Webservice-Endpunkt verwenden und prüfen, dass der Aufruf abgelehnt und ein ValidationFailed-Logeintrag mit Grund "Token ist abgelaufen" erzeugt wird +Tracelinks: StRS-51, SyRS-6 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Hash-Speicherung, Ablaufprüfung und lückenlose Protokollierung sind vorbildliche Sicherheitspraxis für das Zielsystem +Status: belegt +``` + +``` +ID: SyRS-10 +Titel: Duale API-Authentifizierung über Sitzungsticket oder Access-Token mit anwendungsbezogener Einschränkung +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: System (Webservice-Authentifizierung) +Vorbedingung: Beliebiger, mit [Authenticate] markierter API-Aufruf trifft ein +Fakt: AuthenticateInterceptor.InterceptExecution() (Z. 22-61) validiert zunächst als Sitzungsticket (ValidateTicketAndSetReturnValue → AuthenticationTicketBL.GetAuthTicketInfo, Z. 25-48 in AuthenticationTicketBL.cs); bei gültigem Ticket wird zusätzlich geprüft, ob die aufrufende Anwendung (ApplicationKind) für die Methode zugelassen ist (Z. 38) und ob ein Web-Account-Ticket die Methode aufrufen darf (Z. 39, AllowWebAccountLogin); schlägt die Ticket-Prüfung fehl, wird als zweiter Weg ein Access-Token geprüft (Z. 52-57), wobei Access-Token laut Code ausdrücklich KEINE Anwendungseinschränkung unterliegen; ein Kommentar im Code (Z. 33-37) hält fest, dass das Modell nur "diese Anwendung darf aufrufen" abbildet, nicht aber "diese Anwendung darf nur diese Methoden aufrufen" +Aussage: Das System soll jeden API-Aufruf entweder über ein anwendungsbezogen eingeschränktes Sitzungsticket oder über ein Access-Token ohne Anwendungseinschränkung authentifizieren und dabei Web-Account-Tickets standardmäßig von internen Methoden ausschließen. +Ergebnis: Nicht authentifizierte oder unzulässige Aufrufe werden mit einheitlicher Fehlermeldung ohne Preisgabe des genauen Fehlgrundes abgewiesen +Belege: + - [PRIMÄR] src/webservice/Centron.Host/AspNetCore/WcfBridge/Interception/Interceptors/AuthenticateInterceptor.cs, Z. 22-61 - Begründung: Durchsetzende Stelle der gesamten API-Authentifizierung inkl. der vom Entwickler selbst im Code dokumentierten Modellgrenze +Prüfidee: Ticket einer für Methode X nicht zugelassenen Anwendung verwenden und prüfen, dass der Aufruf mit "You don't have the permission..." abgewiesen wird; anschließend mit einem Access-Token dieselbe Methode aufrufen und die fehlende Anwendungseinschränkung bestätigen +Tracelinks: StRS-62, SyRS-7 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Zwei-Wege-Authentifizierung ist sinnvoll; die vom Entwickler selbst dokumentierte Lücke (keine methodenscharfe Einschränkung für Access-Token/bestimmte Anwendungen) ist im Zielsystem gezielt zu schließen (z. B. Scopes je Access-Token) +Status: belegt +``` + +``` +ID: SyRS-8 +Titel: Serverseitige Rechteprüfung mit benutzerbezogenem Cache +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: System (Rechtesystem, Centron.BL) +Vorbedingung: Geschützte Funktion wird aufgerufen +Fakt: HasUserRight() cacht das Ergebnis von GetAllAppRightsFromUser() unter dem Schlüssel "AllRightsFromAppUser{appUserI3D}" (Z. 646); ein Aufruf, der den Cache nach einer Rechteänderung gezielt invalidiert, wurde innerhalb dieser Analyse nicht lokalisiert +Aussage: Das System soll die Rechte eines Benutzers serverseitig prüfen und dabei zur Performanceoptimierung cachen; Änderungen an der Gruppenzuordnung oder Gruppenrechten sollen sich zeitnah auf bereits angemeldete Sitzungen auswirken. +Ergebnis: Rechteprüfung ist performant; Rechteänderungen wirken ohne unangemessene Verzögerung +Belege: + - [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs, Z. 646 (Cache.GetOrAdd) - Begründung: Durchsetzende Stelle des Caching-Mechanismus +Prüfidee: Benutzer ein Recht entziehen, während dessen Sitzung aktiv ist, und prüfen, wie lange die alte Berechtigung noch wirksam bleibt +Tracelinks: StRS-62 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Caching ist sinnvoll, Invalidierungsstrategie bei Rechteänderung im Zielsystem explizit zu spezifizieren +Status: HYPOTHESE +``` + +``` +ID: SyRS-9 +Titel: Administrator-Gruppe vor Entzug systemkritischer Rechte schützen +Ebene: SyRS +Typ: Sicherheit +Qualitätsmerkmal: +Akteur: System (Rechtesystem) +Vorbedingung: Administrator ändert Rechte der Administrator-Gruppe selbst +Fakt: SaveAndAssignGroupToRight()/RemoveAssignGroupToRight() (Z. 261-299) prüfen bei IsAdministratorGroup(group) zusätzlich GetAssignableAdminRightI3Ds() und verweigern die Änderung (return false), wenn das gewählte Recht nicht in dieser Freigabeliste enthalten ist +Aussage: Das System soll verhindern, dass systemkritische Rechte von der Administrator-Gruppe entfernt oder ihr zusätzliche, nicht freigegebene Rechte zugewiesen werden, um ein versehentliches Aussperren aller Administratoren zu verhindern. +Ergebnis: Änderungsversuch an nicht freigegebenen Rechten der Administrator-Gruppe wird abgewiesen +Belege: + - [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs, Z. 266-271 und 284-289 - Begründung: Durchsetzende Stelle, die Änderungen an der Administrator-Gruppe auf eine Freigabeliste beschränkt +Prüfidee: Versuch, ein nicht in GetAssignableAdminRightI3Ds() enthaltenes Recht von der Administrator-Gruppe zu entfernen, und prüfen, dass RemoveAssignGroupToRight() false liefert +Tracelinks: StRS-62 +Konsolidierung: nein +Übernahmewürdigkeit: übernehmen - Schutz vor Selbstaussperrung der Administration ist eine bewährte Sicherheitsmaßnahme +Status: belegt +``` + diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/Traceability.md b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/Traceability.md new file mode 100644 index 00000000..14b05937 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Ergebnisse/Traceability.md @@ -0,0 +1,139 @@ +# Traceability-Tabelle + +Konsolidierte Forward-/Backward-Traceability zwischen StRS, SyRS und SwRS. Jede StRS-Zeile ist vorhanden (Mindestabdeckung, ein StRS je Inventarmodul aus `Analysebericht.md`). Wo eine Anforderung in dieser Iteration bis auf SyRS- und/oder SwRS-Ebene vertieft wurde (Schritt 0c, Risikomodule), sind die zugehörigen IDs eingetragen; die übrigen Zeilen sind auf StRS-Ebene belegt, aber in dieser Iteration nicht weiter auf SyRS/SwRS heruntergebrochen (siehe Selbstbewertung). Artefaktbeleg = jeweils der primäre Beleg der am weitesten unten liegenden Ebene der Zeile. + +## A. Vertiefte Ketten (StRS ↔ SyRS ↔ SwRS) + +| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg (primär) | +|---------|---------|---------|--------------------------| +| StRS-1 (Sonderpreise/Produktmatrix) | SyRS-2 (Duplikatprüfung Sonderpreis) | SwRS-3 (Update statt Duplikat) | Receipts/PositionToSpecialPrice/PositionToSpecialPriceViewModel.cs Z. 80-131 | +| StRS-2 (Pflichtfelder Kundenanlage) | SyRS-1 (Pflichtfeld-Set prüfen) | SwRS-1 (CanAccept-Gate) | Finances/Crm/MakeCustomerViewModel.cs Z. 244-293 | +| StRS-3 (Kampagnen-Status/Rechte) | – | SwRS-2 (Rechteabhängige Kampagnenfunktionen) [HYPOTHESE] | Finances/Campaigns/CampaignMainViewModel.cs Z. 31-40 | +| StRS-12 (Belegkette Angebot–Rechnung) | SyRS-5 (Nebenläufigkeitsschutz) [HYPOTHESE] | – | InvoiceReceiptSearchConfiguration.cs Z. 55, 78, 83-84 | +| StRS-13 (Anzahlung → Schlussrechnung) | SyRS-3 (Anzahlungsrechnungen bereitstellen) | – | DownPayment/FinalInvoice/OrderToFinalInvoiceHelper.cs Z. 27-47 | +| StRS-14 (Steuersatzänderung) | – | SwRS-4 (Länderspezifische Steuersatzliste) | Receipts/ChangeTaxRate/ChangeTaxRateViewModel.cs Z. 41-53 | +| StRS-21 (Mahnlauf/Mahnstopp) | SyRS-4 (Mahnfähigkeit serverseitig) | – | Dunning/Common/DunningItemViewModel.cs Z. 445-469 | +| StRS-22 (Offene Posten) | – | SwRS-5 (OpenPrice-Formel) | InvoiceReceiptSearchConfiguration.cs Z. 71-72 | +| StRS-23 (Zahlungserfassung) | – | SwRS-5 (OpenPrice-Formel, gemeinsam mit StRS-22) | Payments/PaymentsReceiptViewModel.cs Z. 39-46 | +| StRS-51 (Personal-Access-Token) | SyRS-6 (Pflicht-Ablaufdatum), SyRS-7 (serverseitige Ablaufprüfung) | – | AccessTokenBL.ValidateToken() Z. 377-419 | +| StRS-62 (Gruppenbasierte Rechte) | SyRS-8 (Rechteprüfung+Cache) [HYPOTHESE-Anteil], SyRS-9 (Admin-Gruppen-Schutz), SyRS-10 (duale API-Authentifizierung) | SwRS-6 (Sichtrus/Sichmemb-Modell), SwRS-7 (getrennte Web-Rechte) | AppRightsBL.cs Z. 644-691, 261-299 | +| StRS-85 (Passwortverwaltung AES) | – | SwRS-8 (AES-Verschlüsselung Master-Key) | PasswordManagerBL.cs Z. 700, 1051-1052, 1179 | +| StRS-98 (Web-API-Authentifizierung) | SyRS-10 (duale Authentifizierung, gemeinsam mit StRS-62), SyRS-7 | – | AuthenticateInterceptor.cs Z. 22-61 | +| StRS-101 (Nexus Kundenportal/WebCart) | – | SwRS-7 (getrennte Web-Rechte, gemeinsam mit StRS-62) | Management/WebAccount/Model/WebRightNode.cs | + +## B. StRS-Anforderungen ohne separate SyRS-/SwRS-Formalisierung in dieser Iteration + +Diese Anforderungen sind auf StRS-Ebene mit eigenem Artefaktbeleg (siehe StRS.md) belegt; der Artefaktbeleg unten verweist auf den Modulpfad aus dem Inventar (`Analysebericht.md`, Schritt 0). Eine Vertiefung auf SyRS/SwRS ist gemäß Selbstbewertung für die dort genannten Module priorisiert nachzuholen. + +| StRS-ID | Titel (Kurzform) | Artefaktbeleg (Modulpfad lt. Inventar) | +|---------|-------------------|------------------------------------------| +| StRS-4 | CRM-Stammdatenlisten (Counters) | Modules/Finances/MasterDataLists | +| StRS-5 | Vertragsverwaltung | Modules/Finances/Contracts | +| StRS-6 | Projektverwaltung (Finanzsicht) | Modules/Finances/Projects | +| StRS-7 | Zählerstandserfassung MPS | Modules/Finances/DeviceClickCounter | +| StRS-8 | PLM | Modules/PLM | +| StRS-9 | Zahler-/Kostenstellenverwaltung | Modules/PayersAndCostCenter | +| StRS-10 | Projektpreisimport | Modules/ProjectPriceImport | +| StRS-11 | Projektmanagement (Workload) | Modules/ProjectManagement | +| StRS-15 | Provisionsermittlung | Modules/Finances/Receipts/Provision | +| StRS-16 | Web-Angebote | Modules/Finances/Receipts/WebOffer | +| StRS-17 | EDI-Auftragsverbuchung | Modules/Finances/Receipts/EdiOrderbooking | +| StRS-18 | Automatisierte Rechnungserstellung | Modules/Finances/AutomatedBilling | +| StRS-19 | Pauschalabrechnung | Modules/Finances/FlatrateBilling | +| StRS-20 | Zeit-/Leistungsabrechnung | Modules/Finances/TimerBilling | +| StRS-24 | Kontenverwaltung | Modules/Finances/AccountManagement | +| StRS-25 | Warenausgangszahlungen | Modules/Warehousing/OutcomingPayments | +| StRS-26 | Kassensystem-Anbindung | Modules/Warehousing/AccountSystems | +| StRS-27 | Artikelstammdaten/AutoEOL | Modules/Warehousing/ArticleManagement | +| StRS-28 | Artikelimport | Modules/Warehousing/ArticleImport | +| StRS-29 | Mengeneinheiten (UN/ECE) | Modules/Warehousing/ArticleUnitManagement | +| StRS-30 | Barcode-Verwaltung | Modules/Warehousing/BarcodeManagement | +| StRS-31 | Kommissionierung | Modules/Warehousing/Commissioning | +| StRS-32 | Kommissionsware/Konsignation | Modules/Warehousing/Commissions | +| StRS-33 | Inventur | Modules/Warehousing/Inventory | +| StRS-34 | Warengruppenverwaltung | Modules/Warehousing/MaterialGroupManagement | +| StRS-35 | Artikelsuche | Modules/Warehousing/SearchArticle | +| StRS-36 | Lieferantensuche | Modules/Warehousing/SupplierSearch | +| StRS-37 | Logistikeinstellungen | Modules/Logistic | +| StRS-38 | EDI-Bestellwesen | Modules/Purchasing/EDIManagement | +| StRS-39 | Bestellvorschlagsliste | Modules/Purchasing/OrderSuggestionList | +| StRS-40 | Einkaufseinstellungen | Modules/Purchasing/PurchaseSettings | +| StRS-41 | Reisekostenabrechnung | Modules/Purchasing/TravelExpense | +| StRS-42 | Fertigungsauftragsverwaltung | Modules/Production/ProductionOrder | +| StRS-43 | Maschinenverwaltung | Modules/Production/MachineManagement | +| StRS-44 | RMA-Abwicklung | Modules/Rma | +| StRS-45 | Ticketverwaltung | Modules/Helpdesk/TicketDetails | +| StRS-46 | Helpdesk-Dashboard | Modules/Helpdesk/Dashboard | +| StRS-47 | Erwartete Wartungsereignisse | Modules/Helpdesk/ExpectedEvents | +| StRS-48 | Helpdesk-Einstellungen | Modules/Helpdesk/Settings | +| StRS-49 | Helpdesk Selbstbedienung | Modules/Helpdesk/SendSelfCareForm | +| StRS-50 | CentronInspectors (Dateninspektion) | Modules/MyCentron/CentronInspectors | +| StRS-52 | MyDay | Modules/MyCentron/MyDay | +| StRS-53 | MyCentron-Dashboard | Modules/MyCentron/Dashboard | +| StRS-54 | ToDo-Liste | Modules/MyCentron/TodoList | +| StRS-55 | Telefonie-Integration | Modules/MyCentron/Telephony | +| StRS-56 | Supremo-Fernwartung | Modules/MyCentron/Supremo | +| StRS-57 | Verkaufsstatistik | Modules/Statistics/SaleStatistics | +| StRS-58 | Management-Informationen | Modules/Statistics/ManagementInfo | +| StRS-59 | MSP-Statistiken | Modules/Statistics/MspStatistics | +| StRS-60 | Mitarbeiteranalyse | Modules/Statistics/EmployeeAnalytics | +| StRS-61 | Reportverwaltung | Modules/Reports/ReportManagement | +| StRS-63 | Mitarbeiterverwaltung/AD-Import | Modules/Administration/EmployeeManagement | +| StRS-64 | Mandantenverwaltung | Modules/Administration/MandatorManagement | +| StRS-65 | DSGVO/AVV/Löschrechte | Modules/Administration/DSGVO | +| StRS-66 | Systemweite Token-Richtlinie | Modules/Administration/Settings | +| StRS-67 | Verbindungs-/Schnittstelleneinstellungen | Modules/Administration/WebServiceSettings | +| StRS-68 | KI-Mailvorlagen | Modules/Administration/MailTemplates | +| StRS-69 | PDF-Signatur/KI-Textbausteine | Modules/Administration/PdfSigning | +| StRS-70 | Stundensätze/Zuschläge | Modules/Administration/HourlySurchargeRates | +| StRS-71 | Eskalationseinstellungen | Modules/Administration/EscalationsSettings | +| StRS-72 | Länderverwaltung | Modules/Administration/CountryManagement | +| StRS-73 | SEPA-Mandate (Signatur-Workflow) | Modules/Administration/SepaContract | +| StRS-74 | Externe Werkzeuge | Modules/Administration/ExternalTools | +| StRS-75 | WebCart-Konfiguration | Modules/Administration/WebCart | +| StRS-76 | Sonstige Prozesseinstellungen | Modules/Administration/SendDeliveryListShippingConfirmationSettings | +| StRS-77 | Log-Betrachter | Modules/Administration/LogViewer | +| StRS-78 | Dienste-Verwaltung | Modules/Administration/Services | +| StRS-79 | Bankumsätze/IBAN-Klärung | Modules/OnlineBanking/AccountTransactions | +| StRS-80 | OnlineBanking-Konfiguration | Modules/OnlineBanking/AccountTransactions/Converter | +| StRS-81 | OnlineBanking-Verbindungsdialog | Modules/OnlineBanking/ConnectionDialog | +| StRS-82 | KI-Chat-Assistent | Modules/ArtificialIntelligence | +| StRS-83 | Kundenumfragen | Modules/Survey | +| StRS-84 | Massenänderungen | Modules/Massenupdates | +| StRS-86 | Kalendersynchronisation | Modules/Calendar | +| StRS-87 | QM-Prüfgründe | Modules/QM | +| StRS-88 | Telekom-DIVE-Export (UI) | Modules/TelekomDive | +| StRS-89 | Startdashboard | Modules/Dashboard | +| StRS-90 | UI-Layoutprofile | Modules/Gui | +| StRS-91 | MSP-Lizenzabgleich | Modules/Global/MSPLicensesCompare | +| StRS-92 | Backend-Kernschicht | backend/Centron.BL | +| StRS-93 | EDI-Lieferantenanbindungen | backend/Centron.Gateway/EDI_Also | +| StRS-94 | Banking-Gateway Backend | backend/Centron.Gateway/OnlineBanking | +| StRS-95 | MSP-Collector-Gateway | backend/Centron.Gateway/MspCollector | +| StRS-96 | E-Rechnungsformate (ZUGFeRD) | backend/Centron.Gateway/ZUGFeRD21_Extended | +| StRS-97 | Portal-Gateway | backend/Centron.Gateway/Portal | +| StRS-99 | Lizenz-/Verbindungsmanager | webservice/c-entron.misc.ConnectionManager | +| StRS-100 | ServiceBoard (Web-Kanban) | nexus/CentronNexus/ServiceBoard | +| StRS-102 | Web-Fertigungsauftragsverwaltung | nexus/CentronNexus/ProductionOrderManagement | +| StRS-103 | Nexus-Verwaltung/WebRights | nexus/CentronNexus/Management | +| StRS-104 | Web-Dokumentensignatur | nexus/CentronNexus/DocumentSigning | +| StRS-105 | Outlook-Add-in | nexus/CentronNexus.OutlookAddIn | +| StRS-106 | Produktdaten-APIs | apis/Centron.APIs.IcecatDataAccess | +| StRS-107 | FinAPI-Bankanbindung | apis/Centron.APIs.FinAPI | +| StRS-108 | ebInterface (Österreich) | apis/Centron.Api.EbInterface | +| StRS-109 | Versanddienstleister-APIs | apis/Centron.Api.Gls | +| StRS-110 | docuFORM PDF-Generierung | Modules/DataExchange/DocuForm | +| StRS-111 | Adress-/Kontoimport-Validierung | Modules/DataExchange/DataImport | +| StRS-112 | Buchhaltungsexport | Modules/DataExchange/BookKeeping | +| StRS-113 | DATEV-Anbindung | Modules/DataExchange/DatevOnline2020 | +| StRS-114 | SEPA-Zahlungsdatei (pain.008) | backend/Centron.Gateway/DataExchange/PaymentTransactions/Sepa | +| StRS-115 | Telekom-DIVE (Austauschebene) | Modules/DataExchange/TelekomDive | +| StRS-116 | Datenexport (allgemein) | Modules/DataExchange/DataExport | +| StRS-117 | Sonstige Schnittstellen | Modules/DataExchange/SupplierOrderPerBranch | +| StRS-118 | Deployment & Betrieb | docker/, azure/ | + +## Hinweise zur Lesart + +- Ein „–" in Spalte SyRS/SwRS bedeutet: kein zugehöriger Datensatz auf dieser Ebene in dieser Iteration. +- `[HYPOTHESE]`-Kennzeichnungen in Abschnitt A sind identisch mit `Hypothesen.md` zu lesen. +- Rückwärtsverknüpfung (SwRS→SyRS→StRS, SyRS→StRS) ist in jedem einzelnen Anforderungsblock über das Feld `Tracelinks:` zusätzlich dezentral hinterlegt (siehe StRS.md/SyRS.md/SwRS.md) und hier nur konsolidiert zusammengeführt. diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Protokoll.md b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Protokoll.md new file mode 100644 index 00000000..3b937974 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Protokoll.md @@ -0,0 +1,165 @@ +# Messprotokoll – Versuch 01 (V1 Baseline, Prompt-only) – Iteration 02 + +## Lauf +- **Prompt-Datei:** `Versuche/Versuch_01/02_Prompt.md` +- **Iteration:** 02 – vom User ausdrücklich benannt; entspricht zugleich der Regel „höchste + vorhandene Iterationsnummer". Wiederholungslauf zur Varianzbestimmung in derselben Zelle. +- **SHA-256 (Prompt):** `F9B2A1AAB45DDCB87E905B83F24D7B1C7860D81CA07E503E51222E266E0D7849` +- **Startzeit:** 2026-08-27T09:12:15.0639875+02:00 +- **Endzeit:** 2026-08-27T09:59:53.4377636+02:00 +- **Dauer gesamt:** 0:47:38 (`duration_ms` 0:47:35; API: 0:46:19) + — **im Parallelbetrieb erhoben, nicht für Laufzeitvergleiche verwendbar** +- **Root-Verzeichnis:** `c:\DEV\MasterArbeit\QuellCode\CentronERP` (24.662 versionierte Dateien) +- **Codebasis-Commit:** `7df384f6d2e7249dc914a74e299fe7fa71ece748` (dirty: nein) +- **Snapshot-Zustand:** bereinigt von KI-Konfigurationen: ja (Prüfmuster ohne Treffer); + die Codebasis ist seit Commit `f045b99a` kein eigenes Repository mehr, sondern Teil des + Arbeitsrepos – der Vorher/Nachher-Vergleich läuft deshalb pfadskopiert +- **Snapshot-Zusatzartefakte:** keine – der Snapshot entspricht dem Commit-Stand +- **Prompt-Repo-Commit:** `7df384f6d2e7249dc914a74e299fe7fa71ece748` + +## Werkzeugkonfiguration +- **Skill-Version:** 7.0.0 +- **Claude-Code-Version:** 2.1.246 +- **CLI-Pfad:** `C:\Users\ChristophSchwoerer\.vscode\extensions\anthropic.claude-code-2.1.246-win32-x64\resources\native-binary\claude.exe` +- **Modell (angefordert):** `claude-sonnet-5` +- **Modelle (tatsächlich eingesetzt):** `claude-sonnet-5` 38.429.213 Tokens (99.98 %), `claude-haiku-4-5-20251001` 6.965 Tokens (0.02 %) +- **Kontrolle Modell:** bestanden – ausschließlich das angeforderte Modell plus Haiku als zulässiger interner Hilfsaufruf +- **Effort:** `max` (per `--effort max` gesetzt) +- **Laufverzeichnis-ID:** `v7.0.0-da3c` +- **Ablage:** `Iteration 3/claude-sonnet-5/solo/max/` +- **Parallele Läufe:** nein – die Zeitangaben sind für Laufzeitvergleiche verwendbar +- **Agentenmodus:** `solo` (V1) +- **Kontextfenster:** 1.000.000 Tokens; `maxOutputTokens` 64.000 +- **Sampling-Parameter:** nicht steuerbar über die CLI, nicht erfasst +- **Nur bei lokalem Modellbetrieb:** entfällt (Cloud-Inferenz, `provider: firstParty`) +- **Permission-Mode:** `acceptEdits` +- **Toolfreigabe:** `--allowedTools "Bash" "PowerShell"` / + `--disallowedTools` 33er-Denylist (schreibende und bauende Kommandos) **zuzüglich** `Task`, `Agent`, `Workflow` aus dem Modus `solo` +- **Isolationsmechanismus:** `--safe-mode`, `--strict-mcp-config` +- **MCP-Server / Agentendateien:** keine – aus dem Snapshot entfernt, zusätzlich `--safe-mode` +- **Subagenten:** keine (`spawned` = 0, `by_type` leer) +- **Verschachtelung:** `spawned` = 0, davon `spawned_by_subagents` = 0, `max_depth` = 0. Keine tieferen Ebenen, `_meta\subagenten.md` entfällt. + +## Validierungsstichprobe +- **Größe:** noch nicht festgelegt +- **Ziehungsverfahren:** noch nicht festgelegt +- **Validatoren:** noch nicht festgelegt +- **Stand:** noch nicht gezogen + +## Verbrauch + +### Hauptagent (`usage`) +| Messgröße | Wert | +|---|---:| +| Input-Tokens | 290 | +| Output-Tokens | 284.916 (davon 95.123 Thinking-Tokens) | +| Cache-Write-Tokens | 457.428 | +| Cache-Read-Tokens | 37.686.579 | +| Agent-Turns | 217 | + +### Gesamtlauf inkl. Subagenten (`modelUsage`, abrechnungsrelevant) +| Messgröße | `claude-sonnet-5` | `claude-haiku-4-5-20251001` | Summe | +|---|---:|---:|---:| +| Input-Tokens | 290 | 6.945 | 7.235 | +| Output-Tokens | 284.916 | 20 | 284.936 | +| Cache-Write-Tokens | 457.428 | 0 | 457.428 | +| Cache-Read-Tokens | 37.686.579 | 0 | 37.686.579 | +| **Tokens gesamt** | **38.429.213** | **6.965** | **38.436.178** | + +**Tokens gesamt: 38.436.178** — Input + Output + Cache-Write + Cache-Read über alle Modelle. +Das ist die **berichtete Aufwandsgröße** der Versuchsreihe. `total_cost_usd` bleibt unberührt in +`RawResult.json` erhalten, wird aber nicht ins Protokoll übernommen: Token sind modell- und +preisunabhängig und bleiben damit über Preisänderungen und Modellwechsel hinweg vergleichbar. + +Da im Modus `solo` keine Subagenten laufen, sind `usage` und `modelUsage` für das Hauptmodell +deckungsgleich; die Differenz zur Summe stammt allein aus den Haiku-Hilfsaufrufen. + +## Gefundene Anforderungen + +Maschinell aus `Ergebnisse\StRS.md`, `SyRS.md` und `SwRS.md` ausgewertet (Blockformat des Prompts). Erzeugt von `analyse-anforderungen.py`. + +Die Kenngrößen decken die **maschinell prüfbare** Hälfte des Evaluationsrahmens aus Kapitel 4.3 ab: Belegqualität und Übernahmewürdigkeit gehören zur *Statement-Qualität*, Verteilung und Konsolidierungskandidaten zur *Set-Qualität*, Tracelinks und Belegklassifikation zur *Traceability-Qualität*. Die Expertenbewertung nach Likert-Skala tritt daneben und wird hier nicht ersetzt. + +### Verteilung über die Ebenen + +| Ebene | Anzahl | Anteil | +|---|---:|---:| +| StRS | 118 | 86,8 % | +| SyRS | 10 | 7,4 % | +| SwRS | 8 | 5,9 % | +| **Gesamt** | **136** | 100 % | + +### Anforderungstypen + +| Typ | Anzahl | Anteil | +|---|---:|---:| +| funktional | 100 | 73,5 % | +| Schnittstelle | 19 | 14,0 % | +| Sicherheit | 10 | 7,4 % | +| Daten | 5 | 3,7 % | +| nicht-funktional | 2 | 1,5 % | + +### Belegqualität + +| Messgröße | Wert | +|---|---:| +| Belege gesamt | 166 | +| davon `PRIMÄR` | 51 (30,7 %) | +| davon `SEKUNDÄR` | 60 (36,1 %) | +| davon `KONTEXT` | 55 (33,1 %) | +| Belege je Anforderung (Median) | 1,0 | +| Anforderungen mit mindestens einem `PRIMÄR`-Beleg | 46 (33,8 %) | + +### Übernahmewürdigkeit + +| Einstufung | Anzahl | Anteil | +|---|---:|---:| +| übernehmen | 129 | 94,9 % | +| workaround | 2 | 1,5 % | +| sonderfall | 4 | 2,9 % | +| veraltet | 1 | 0,7 % | + +### Status + +| Kategorie | Anzahl | Anteil | +|---|---:|---:| +| belegt | 130 | 95,6 % | +| als `HYPOTHESE` gekennzeichnet | 6 | 4,4 % | +| als Workaround vermerkt | 0 | 0,0 % | +| Konsolidierungskandidaten | 23 | 16,9 % | +| mit ISO-25010-Qualitätsmerkmal | 2 | 1,5 % | + +### Regelkonformität (Prüfung gegen die Vorgaben des Prompts) + +| Vorgabe | Ergebnis | +|---|---| +| **Belegpflicht** – jede Anforderung mindestens ein Artefaktbeleg | **erfüllt** (0 Anforderungen ohne Beleg) | +| **Risikobasierte Priorisierung** – Sicherheit, Abrechnung, Berechtigungen brauchen einen `PRIMÄR`-Beleg oder die Kennzeichnung `[HYPOTHESE]` | **verletzt** – 7 von 33 ungedeckt: StRS-25, StRS-31, StRS-72, StRS-91, StRS-92, StRS-99, StRS-102 | +| **Verifizierbarkeit** – jede Anforderung mit Prüfidee oder Akzeptanzkriterium | **erfüllt** | +| **Übernahmewürdigkeit** – Einstufung für die Migrationsperspektive | **erfüllt** (alle 136 Anforderungen eingestuft) | +| **Traceability** – Verknüpfung zwischen den Ebenen | 81 von 136 mit Tracelinks (59,6 %) | + +## Ergebnis +- **Status:** erfolgreich (`is_error` = false, `subtype` = `success`, `stop_reason` = `end_turn`, `terminal_reason` = `completed`) +- **Session-ID:** `4a31e82c-b2b8-43a5-9a37-d3dc63f94b58` +- **Permission-Denials:** 0 – **keines auf `Task`/`Agent`/`Workflow`**. Der Agent hat zu keinem Zeitpunkt zu delegieren versucht; die Modus-Sperre wurde nie ausgelöst. +- **Kontrolle Agentenmodus:** `subagent_stats.spawned` = 0 – Bedingung `solo` eingehalten +- **Subagenten-Prompts:** entfällt (Modus `solo`) +- **Erzeugte Dateien:** 7 Dateien in `Ergebnisse\`: + + | Datei | Größe | + |---|---:| + | `Analysebericht.md` | 39.319 B | + | `Glossar.md` | 5.940 B | + | `Hypothesen.md` | 4.425 B | + | `StRS.md` | 168.024 B | + | `SwRS.md` | 13.076 B | + | `SyRS.md` | 18.243 B | + | `Traceability.md` | 11.369 B | + +- **Root unverändert:** ja (zeilenendennormalisiert verglichen). +- **Abschlusstext des Agenten:** siehe `RawResult.json` (`result`) + +## Anmerkungen/Auffälligkeiten + + diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/RawResult.json b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/RawResult.json new file mode 100644 index 00000000..55b7bb8d --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/RawResult.json @@ -0,0 +1 @@ +{"is_error":false,"duration_api_ms":2779209,"num_turns":217,"stop_reason":"end_turn","session_id":"4a31e82c-b2b8-43a5-9a37-d3dc63f94b58","total_cost_usd":12.223812800000006,"usage":{"input_tokens":290,"cache_creation_input_tokens":457428,"cache_read_input_tokens":37686579,"output_tokens":284916,"output_tokens_details":{"thinking_tokens":95123},"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":457428,"ephemeral_5m_input_tokens":0},"inference_geo":"not_available","iterations":[{"input_tokens":2,"output_tokens":910,"cache_read_input_tokens":456874,"cache_creation_input_tokens":554,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":554},"type":"message"}],"speed":"standard"},"modelUsage":{"claude-haiku-4-5-20251001":{"inputTokens":6945,"outputTokens":20,"cacheReadInputTokens":0,"cacheCreationInputTokens":0,"webSearchRequests":0,"costUSD":0.007045,"contextWindow":200000,"maxOutputTokens":32000,"canonicalModel":"claude-haiku-4-5","provider":"firstParty","costBasis":"list"},"claude-sonnet-5":{"inputTokens":290,"outputTokens":284916,"cacheReadInputTokens":37686579,"cacheCreationInputTokens":457428,"webSearchRequests":0,"costUSD":12.216767800000005,"contextWindow":1000000,"maxOutputTokens":64000,"canonicalModel":"claude-sonnet-5","provider":"firstParty","costBasis":"list"}},"permission_denials":[],"terminal_reason":"completed","fast_mode_state":"off","fast_mode_disabled_reason":"extra_usage_disabled","subagent_stats":{"spawned":0,"requested":{"background":0,"foreground":0,"unset":0},"started_in_background":0,"max_depth":0,"spawned_by_subagents":0,"completed":0,"failed":0,"killed":{"parent":0,"user":0,"system":0},"refused":{"depth_limit":0,"concurrency_limit":0,"budget":0},"by_type":{}},"subtype":"success","api_error_status":null,"result":"The reverse requirements engineering specification for the c-entron ERP-Suite is complete. All seven deliverables are in `Ergebnisse/`:\n\n**Coverage achieved:**\n- **Modulinventar (Schritt 0):** 118 modules identified across the entire codebase (WPF desktop client, backend BL/DAO, webservice API, Nexus web frontend, external API integrations, data-exchange connectors, deployment) — 0 modules left unanalyzed\n- **136 requirements total:** 118 StRS + 10 SyRS + 8 SwRS, with full forward/backward traceability\n- **Risk-based deepening (Schritt 0c):** 14 modules fully deepened across all three levels — rights management (found the actual group-based RBAC enforcement in `AppRightsBL.HasUserRight`), password vault AES encryption, dual ticket/access-token API authentication, dunning-stop logic, open-items/payment formulas, SEPA/DSGVO signature workflows\n- **29 risk-relevant requirements** (security, billing, permissions) individually checked: 23 carry a PRIMÄR beleg, 6 are honestly marked `[HYPOTHESE]`\n- **23 consolidation candidates** found with concrete evidence (e.g., a literal copy-paste artifact: the SEPA-mandate settings class still carries internal field names like `_declinedOrderProcessingContractSubject` left over from the DSGVO-AVV class it was cloned from)\n- **Self-check caught and fixed 3 rule violations** during the consistency pass — three security/billing requirements had only SEKUNDÄR evidence but were marked `belegt`; corrected to `HYPOTHESE` before finalizing\n\nThe codebase itself was only read, never modified (verified via `git status`).\n\nOne thing worth flagging to you directly: 86 of the 118 modules are at \"flach\" depth (one requirement, existence-level evidence only) — that's the explicit breadth-first tradeoff the prompt asked for, but it means modules like the 794-file `Finances/Receipts` core or the 320-file `ArticleManagement` still have far more to extract in a follow-up pass. That's called out concretely in the self-assessment.","ttft_ms":7192,"ttft_stream_ms":1124,"time_to_request_ms":36,"type":"result","duration_ms":2855005,"uuid":"0912e717-c040-47a4-8d5e-381952f58a7d","queued_turn_count":0} diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Stderr.log b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/Stderr.log new file mode 100644 index 00000000..e69de29b diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/after.txt b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/after.txt new file mode 100644 index 00000000..e69de29b diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/anforderungen.json b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/anforderungen.json new file mode 100644 index 00000000..edcc36fc --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/anforderungen.json @@ -0,0 +1,2616 @@ +[ + { + "id": "StRS-1", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Kundenspezifische Sonderpreise und Serienmail", + "typ": "funktional", + "belege": [ + "SEKUNDÄR", + "SEKUNDÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-2 (Belegkalkulation zieht Sonderpreise)", + "konsolidierung": "nein", + "pruefidee": "Für einen Kunden eine Sonderpreiszeile in der Produktmatrix anlegen und prüfen, dass der Preis bei Neuanlage eines Belegs für diesen Kunden gezogen wird", + "qm": "", + "uebernahme": "übernehmen - kundenindividuelle Preisfindung ist im Fachhandel/IT-Systemhaus-Geschäft eine Kernanforderung" + }, + { + "id": "StRS-2", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Konfigurierbare Pflichtfelder bei Umwandlung eines Adressstamm-Datensatzes in einen Kunden", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-1, SwRS-1", + "konsolidierung": "nein", + "pruefidee": "CrmSettings.CountServerRequired aktivieren, Feld \"Anzahl Server\" leer lassen und prüfen, dass \"Übernehmen\" deaktiviert bleibt; danach Feld befüllen und Übernahme prüfen", + "qm": "", + "uebernahme": "übernehmen - konfigurierbare Pflichtfeldprüfung bei Kundenanlage ist fachlich zentral für Datenqualität" + }, + { + "id": "StRS-3", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Vertriebskampagnen planen und durchführen", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SwRS-2", + "konsolidierung": "nein", + "pruefidee": "Kampagne im Status \"Geplant\" anlegen, in \"Offen\" überführen und mit einem Benutzer ohne Bearbeitungsrecht prüfen, dass die Bearbeitung verweigert wird", + "qm": "", + "uebernahme": "übernehmen - Kampagnensteuerung mit Statuslebenszyklus ist Standardfunktion im CRM-Umfeld" + }, + { + "id": "StRS-4", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Massenpflege von Zählerständen über CRM-Stammdatenlisten", + "typ": "funktional", + "belege": [ + "SEKUNDÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "Kandidat: StRS-7 - beide Implementierungen erfassen Zählerstände für Geräte (Finances/MasterDataLists/Counters vs. Finances/DeviceClickCounter), getrennt implementiert für Listenerfassung bzw. Einzelerfassung/Import", + "pruefidee": "In der Stammdatenliste für mehrere Geräte gleichzeitig neue Zählerstände erfassen und die Übernahme in die Gerätehistorie prüfen", + "qm": "", + "uebernahme": "Workaround - Funktion überschneidet sich fachlich mit dem dedizierten DeviceClickCounter-Modul (siehe StRS-7); im Zielsystem zu einer Zählerstandserfassung zusammenzuführen" + }, + { + "id": "StRS-5", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Kundenverträge mit Positionen, Kontingent und Controlling verwalten", + "typ": "funktional", + "belege": [ + "SEKUNDÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "Kandidat: Prüfen, ob ContractEvaluation2 und ContractEvaluationOld denselben fachlichen Umfang parallel abbilden (siehe Analysebericht, Konsistenzcheck)", + "pruefidee": "Vertrag mit Kontingent anlegen, Verbrauch über Belege buchen und die Controlling-Auswertung auf korrekten Resteinsatz prüfen", + "qm": "", + "uebernahme": "übernehmen - Vertragskontingente und -controlling sind zentral für das Servicegeschäft; ContractEvaluationOld voraussichtlich veraltet zugunsten ContractEvaluation2" + }, + { + "id": "StRS-6", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Kaufmännische Projektverwaltung mit Abschlusswahrscheinlichkeit", + "typ": "funktional", + "belege": [ + "SEKUNDÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Projekt mit Abschlusswahrscheinlichkeit 50% anlegen und prüfen, dass es in einer nach Wahrscheinlichkeit gewichteten Pipeline-Auswertung korrekt einfließt", + "qm": "", + "uebernahme": "übernehmen - Projekt-Pipeline mit Wahrscheinlichkeiten ist gängige Vertriebssteuerung" + }, + { + "id": "StRS-7", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Zählerstandserfassung für Managed-Print-Geräte inkl. automatisiertem Import", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "Kandidat: StRS-4 - fachlich dieselbe Funktion (Zählerstandserfassung) wie Finances/MasterDataLists/Counters, getrennt implementiert", + "pruefidee": "Zählerstand über den DocuForm-API-Import einlesen und prüfen, dass er in der Gerätehistorie mit Herkunft \"Import\" erscheint", + "qm": "", + "uebernahme": "übernehmen - automatisierter Zählerstandsabruf ist Voraussetzung für MPS-Abrechnung; manuelle Doppelpflege (siehe StRS-4) im Zielsystem konsolidieren" + }, + { + "id": "StRS-8", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Produktlebenszyklus je ausgeliefertem Gerät verfolgen", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Gerät mit ProductFamilyLifetimeInMonths=36 zulaufen lassen und prüfen, dass 36 Monate nach Rechnungsdatum ein Hinweis/Ersatzangebot auslösbar ist", + "qm": "", + "uebernahme": "übernehmen - Lebenszyklussteuerung ist Grundlage für wiederkehrendes Ersatzgeschäft (MPS/IT-Handel)" + }, + { + "id": "StRS-9", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Zahler und Kostenstellen für Belege abweichend vom Kunden erfassen", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Kostenstelle \"K100\" anlegen und in einem Beleg auswählen; prüfen, dass Rechnungsadresse und Kostenstelle unabhängig voneinander änderbar sind", + "qm": "", + "uebernahme": "übernehmen - Kostenstellen-/Zahlertrennung wird von Geschäftskunden (öffentlicher Sektor, Konzernkunden) regelmäßig gefordert" + }, + { + "id": "StRS-10", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Projektpreislisten importieren und gegen Sonderkonditionen abgleichen", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Preisliste mit einer vom bestehenden Sonderpreis abweichenden Zeile importieren und prüfen, dass sie in der Differenzliste erscheint und die E-Mail-Funktion den Bericht anhängt", + "qm": "", + "uebernahme": "übernehmen - automatisierter Preisabgleich reduziert manuelle Pflegefehler bei Projektkonditionen" + }, + { + "id": "StRS-11", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Mitarbeiterauslastung über Projekte und Tickets hinweg planen", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Mitarbeiter zwei Projekten mit überlappendem Zeitraum zuordnen und prüfen, dass die Auslastungsanzeige eine Überbuchung erkennbar macht", + "qm": "", + "uebernahme": "übernehmen - Kapazitätsplanung ist Grundlage für Projektzusagen im Servicegeschäft; Abgrenzung zu StRS-6 (kaufmännische Projektsicht) beachten - hier: personelle Kapazitätssicht" + }, + { + "id": "StRS-12", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Durchgängige Belegkette Angebot–Auftrag–Lieferschein–Rechnung", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Auftrag mit zwei Positionen anlegen, eine Position teilweise in einen Lieferschein überführen und prüfen, dass beim nächsten Weiterverarbeitungsschritt nur die Restmenge vorgeschlagen wird", + "qm": "", + "uebernahme": "übernehmen - durchgängige, mengenscharfe Belegkette ist Kernanforderung jedes ERP-Auftragsprozesses" + }, + { + "id": "StRS-13", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Anzahlungsrechnungen bei der Schlussrechnung berücksichtigen", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-3, StRS-12", + "konsolidierung": "nein", + "pruefidee": "Auftrag mit zwei Anzahlungsrechnungen anlegen, Schlussrechnung erzeugen und prüfen, dass beide Anzahlungsbeträge im Schlussrechnungsbeleg ausgewiesen/abgezogen werden", + "qm": "", + "uebernahme": "übernehmen - Anzahlungsverrechnung ist eine buchhalterisch zwingende Funktion" + }, + { + "id": "StRS-14", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Steuersatzänderung auf länderspezifisch gültige Sätze beschränken", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SwRS-4", + "konsolidierung": "nein", + "pruefidee": "Land mit mehreren gültigen Steuersätzen wählen, Dialog öffnen und prüfen, dass nur diese Sätze auswählbar sind und \"OK\" ohne Auswahl deaktiviert bleibt", + "qm": "", + "uebernahme": "übernehmen - länderabhängige Steuersatzgültigkeit ist gesetzlich zwingend" + }, + { + "id": "StRS-15", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Provisionsschema kontrolliert auf Belege anwenden", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Provisionsschema auf bereits provisionierte Belege ohne \"Überschreiben\"-Schalter anwenden und prüfen, dass diese Belege unverändert bleiben; mit Schalter erneut anwenden und Bestätigungsdialog prüfen", + "qm": "", + "uebernahme": "übernehmen - Schutz vor versehentlichem Überschreiben abrechnungsrelevanter Provisionsdaten ist geschäftskritisch" + }, + { + "id": "StRS-16", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Angebote per Weblink für Kunden bereitstellen", + "typ": "funktional", + "belege": [ + "SEKUNDÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Angebot als Weblink generieren, im Kundenkontext öffnen, einen Änderungswunsch zu einer Position hinterlegen und prüfen, dass dieser im Innendienst sichtbar wird", + "qm": "", + "uebernahme": "übernehmen - Web-Angebote mit Kundeninteraktion sind ein wesentliches Argument für die geplante Web-/SaaS-Neuimplementierung" + }, + { + "id": "StRS-17", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Elektronisch eingehende Aufträge teilweise oder vollständig verbuchen", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-12", + "konsolidierung": "nein", + "pruefidee": "EDI-Auftrag mit Teilmenge verbuchen und prüfen, dass die Restmenge für eine spätere Nachbuchung offen bleibt", + "qm": "", + "uebernahme": "übernehmen - Teilverbuchung ist im Lieferantengeschäft mit Teillieferungen Standard" + }, + { + "id": "StRS-18", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Verträge automatisiert nach Abrechnungsintervall fakturieren", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-5 (Vertragsverwaltung)", + "konsolidierung": "nein", + "pruefidee": "Vertrag mit Intervall \"monatlich\" anlegen und prüfen, dass er im automatisierten Abrechnungslauf nur einmal je Monat erscheint", + "qm": "", + "uebernahme": "übernehmen - periodische automatisierte Fakturierung ist Kern des wiederkehrenden Servicegeschäfts" + }, + { + "id": "StRS-19", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Pauschale Projektleistungen abrechnen", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "HYPOTHESE", + "hypothese": true, + "workaround": false, + "tracelinks": "StRS-6", + "konsolidierung": "Kandidat: Prüfen, ob FlatrateBilling und TimerBilling (StRS-20) im Zielsystem als zwei Abrechnungsarten eines gemeinsamen Abrechnungsmodells statt getrennter Module abgebildet werden sollten", + "pruefidee": "Projekt mit Pauschalpreis abrechnen und prüfen, dass der Rechnungsbetrag unabhängig von den im Projekt erfassten Stunden dem vereinbarten Pauschalbetrag entspricht", + "qm": "", + "uebernahme": "übernehmen - Pauschalabrechnung ist gängiges Vertragsmodell im IT-Service" + }, + { + "id": "StRS-20", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Erfasste Zeiten/Leistungen verrechnen", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "HYPOTHESE", + "hypothese": true, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "Kandidat: siehe StRS-19", + "pruefidee": "Zeiterfassung für einen Kunden anlegen, TimerBilling ausführen und prüfen, dass genau diese Zeiten in der erzeugten Rechnung erscheinen", + "qm": "", + "uebernahme": "übernehmen - zeitbasierte Abrechnung ist Standard im Servicegeschäft" + }, + { + "id": "StRS-21", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Mahnlauf unter Berücksichtigung von Mahnstopp und fehlenden Pflichtangaben", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-4", + "konsolidierung": "nein", + "pruefidee": "Rechnung mit gesetztem MahnStop-Flag in den Mahnlauf einbeziehen und prüfen, dass sie mit Ausschlussgrund \"im Mahnstopp\" nicht auswählbar ist", + "qm": "", + "uebernahme": "übernehmen - Mahnstopp- und Pflichtangabenprüfung ist rechtlich und geschäftlich zwingend vor Mahnungsversand" + }, + { + "id": "StRS-22", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Offene Posten mit korrektem Umsatzsteuerausweis und Fremdwährung führen", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-23", + "konsolidierung": "nein", + "pruefidee": "Rechnung mit MwstNichtAusweisbar=1 (z. B. Kleinunternehmerregelung) und Teilzahlung anlegen und prüfen, dass OpenPrice auf Basis des Nettobetrags abzüglich Teilzahlung berechnet wird", + "qm": "", + "uebernahme": "übernehmen - korrekte Offene-Posten-Führung inkl. Sonderfall umsatzsteuerbefreiter Rechnungen ist buchhalterisch zwingend" + }, + { + "id": "StRS-23", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Zahlungseingänge erfassen und offenen Betrag fortschreiben", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-22", + "konsolidierung": "nein", + "pruefidee": "Zahlung kleiner als OpenPrice erfassen und prüfen, dass Difference den korrekten Restbetrag größer 0 anzeigt", + "qm": "", + "uebernahme": "übernehmen - sofortige Restbetragsanzeige bei Zahlungserfassung ist Kernfunktion der Debitorenbuchhaltung" + }, + { + "id": "StRS-24", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Kontenübersicht mit Belegen und Filialbuchungsnummern je Kunde", + "typ": "funktional", + "belege": [ + "SEKUNDÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Kunden mit Belegen aus zwei Filialen öffnen und prüfen, dass die Kontenübersicht beide Filialbuchhaltungsnummern korrekt trennt", + "qm": "", + "uebernahme": "übernehmen - filialbezogene Kontenführung ist für Mandanten mit mehreren Standorten erforderlich" + }, + { + "id": "StRS-25", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Zahlungen im Warenausgang erfassen (z. B. Nachnahme)", + "typ": "funktional", + "belege": [ + "SEKUNDÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-26", + "konsolidierung": "nein", + "pruefidee": "Warenausgang mit Nachnahmezahlung erfassen und prüfen, dass die Zahlung im verknüpften Kassensystem-Konto erscheint", + "qm": "", + "uebernahme": "Sonderfall - Nachnahme/Bar-Zahlung im Warenausgang ist ein Restfall des stationären Handels, im SaaS-Zielsystem fachlich zu hinterfragen" + }, + { + "id": "StRS-26", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Kassensystem-Konten mit differenzierter Umsatzsteuerbehandlung führen", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-25", + "konsolidierung": "nein", + "pruefidee": "Kassenkonto mit unterschiedlichen Werten für beide Felder anlegen und eine Buchung mit und ohne Zollabfertigung durchführen; prüfen, dass jeweils das richtige Steuerkonto bebucht wird", + "qm": "", + "uebernahme": "übernehmen - differenzierte Umsatzsteuerbehandlung bei Import/Zoll ist bei internationalem Warenverkehr weiterhin relevant" + }, + { + "id": "StRS-27", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Artikellebenszyklus inkl. automatisiertem End-of-Life pflegen", + "typ": "funktional", + "belege": [ + "SEKUNDÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-8", + "konsolidierung": "nein", + "pruefidee": "Artikel mit abgelaufenem Lebenszyklusdatum prüfen und feststellen, ob AutoEOL ihn automatisch als \"End of Life\" markiert", + "qm": "", + "uebernahme": "übernehmen - automatisierte Lebenszykluspflege reduziert manuellen Pflegeaufwand im Artikelstamm" + }, + { + "id": "StRS-28", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Artikeldaten aus externen Quellen importieren", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "Kandidat: Abgrenzung zu Sales/SpecialArticleImport (StRS-1) und Purchasing/EDIManagement (StRS-38) prüfen - mehrere Importwege für Artikel-/Preisdaten", + "pruefidee": "Importdatei mit neuem Artikel einlesen und prüfen, dass der Artikel korrekt im Artikelstamm erscheint", + "qm": "", + "uebernahme": "übernehmen - Artikelimport aus Lieferantenkatalogen ist im Großhandel/IT-Fachhandel Standard" + }, + { + "id": "StRS-29", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Mengeneinheiten nach UN/ECE-Standard verwalten", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Mengeneinheit \"Karton\" mit UN/ECE-Code anlegen und in einer EDI-Ausgangsnachricht (siehe StRS-93) auf korrekte Codeübernahme prüfen", + "qm": "", + "uebernahme": "übernehmen - Standardkonformität ist Voraussetzung für EDI-Fähigkeit mit Lieferanten" + }, + { + "id": "StRS-30", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Barcodes für Artikel generieren und Vergabebedingungen konfigurieren", + "typ": "funktional", + "belege": [ + "SEKUNDÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Barcode-Vergabebedingung ändern und prüfen, dass neu generierte Barcodes der geänderten Bedingung entsprechen", + "qm": "", + "uebernahme": "übernehmen - automatisierte, regelbasierte Barcodevergabe ist für die Lagerlogistik erforderlich" + }, + { + "id": "StRS-31", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Warenkommissionierung im Lager steuern", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-12", + "konsolidierung": "nein", + "pruefidee": "Kommissionierauftrag mit mehreren Positionen abarbeiten und prüfen, dass der Lieferschein erst bei vollständiger Kommissionierung freigegeben wird", + "qm": "", + "uebernahme": "übernehmen - geführte Kommissionierung ist Standard in der Lagerlogistik" + }, + { + "id": "StRS-32", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Kommissionsaufträge (Konsignationslager) inkl. Teilkommissionen verwalten", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "Kandidat: Warehousing/Commissions und Finances/Receipts/PartialCommission bilden denselben fachlichen Sachverhalt (Kommissionsauftrag) ab und teilen sich bereits Converter-Klassen über Modulgrenzen hinweg - im Zielsystem als ein Konzept zu konsolidieren", + "pruefidee": "Kommissionsauftrag mit Teilabruf anlegen und prüfen, dass der Status korrekt zwischen den Modulen Warehousing/Commissions und Finances/Receipts/PartialCommission konsistent dargestellt wird", + "qm": "", + "uebernahme": "übernehmen - Konsignationsgeschäft ist im IT-Fachhandel verbreitet; technische Aufteilung auf zwei Module ist migrationsrelevant" + }, + { + "id": "StRS-33", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Lagerinventur durchführen und bewerten", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Inventur mit abweichendem Ist-Bestand durchführen und prüfen, dass die Differenz zum Soll-Bestand korrekt ausgewiesen wird", + "qm": "", + "uebernahme": "übernehmen - Inventur ist gesetzlich vorgeschriebener Bestandteil der Lagerbuchführung" + }, + { + "id": "StRS-34", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Warengruppen mit Kalkulationsaufschlag und filialspezifischen Erlös-/Aufwandskonten verwalten", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Warengruppe mit Aufschlag X% anlegen, Artikel zuordnen und prüfen, dass der Verkaufspreis den Aufschlag korrekt berücksichtigt; anschließend Artikel in andere Warengruppe umbuchen und Kontenzuordnung prüfen", + "qm": "", + "uebernahme": "übernehmen - filialdifferenzierte Kontenzuordnung ist für Mandanten mit mehreren Buchungskreisen erforderlich" + }, + { + "id": "StRS-35", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Übergreifende Artikelsuche mit Bestandsanzeige", + "typ": "funktional", + "belege": [ + "SEKUNDÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Artikelsuche mit mehr als einer Seite Ergebnissen ausführen und prüfen, dass Paging und Bestandsanzeige je Treffer korrekt funktionieren", + "qm": "", + "uebernahme": "übernehmen - performante, zentrale Artikelsuche wird von praktisch allen Modulen benötigt" + }, + { + "id": "StRS-36", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Lieferantensuche im Beschaffungskontext", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Lieferantensuche mit Teilnamen ausführen und prüfen, dass passende Lieferanten gefunden werden", + "qm": "", + "uebernahme": "übernehmen - Lieferantensuche ist Grundfunktion des Einkaufsprozesses" + }, + { + "id": "StRS-37", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Versandarten und Logistikeinstellungen konfigurieren", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Neue Versandart anlegen und prüfen, dass sie im Lieferschein auswählbar ist", + "qm": "", + "uebernahme": "übernehmen - konfigurierbare Versandarten sind Voraussetzung für Anbindung mehrerer Versanddienstleister (siehe StRS-109)" + }, + { + "id": "StRS-38", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "EDI-Bestellungen inkl. Positionsabgleich mit Lieferanten austauschen", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-93 (EDI-Lieferantenanbindungen Backend)", + "konsolidierung": "nein", + "pruefidee": "EDI-Bestellbestätigung mit abweichender Liefermenge einspielen und prüfen, dass die Abweichung in der zugeordneten Bestellung sichtbar wird", + "qm": "", + "uebernahme": "übernehmen - EDI-Anbindung an Distributoren ist im IT-Fachhandel branchenüblich" + }, + { + "id": "StRS-39", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Bestellvorschläge aus Bestandsunterschreitung ableiten", + "typ": "funktional", + "belege": [ + "SEKUNDÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Artikel unter Meldebestand fallen lassen und prüfen, dass er in der Bestellvorschlagsliste des zuständigen Distributors erscheint", + "qm": "", + "uebernahme": "übernehmen - automatisierte Bestellvorschläge reduzieren Fehlbestände" + }, + { + "id": "StRS-40", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Einkaufs- und Bestelleingangs-Grundeinstellungen konfigurieren", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Einstellung ändern und prüfen, dass sich das Verhalten bei der nächsten Bestellerfassung entsprechend ändert", + "qm": "", + "uebernahme": "übernehmen - mandantenspezifische Konfigurierbarkeit ist Grundvoraussetzung für Mehrmandantenbetrieb" + }, + { + "id": "StRS-41", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Reisekosten mitarbeiterbezogen erfassen und Buchhaltungskonten zuordnen", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Reisekostenbuchung ohne zugeordnetes Mitarbeiterkonto anlegen und prüfen, dass die Verbuchung verweigert wird", + "qm": "", + "uebernahme": "übernehmen - kontierte Reisekostenabrechnung ist buchhalterisch erforderlich" + }, + { + "id": "StRS-42", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Fertigungsaufträge anlegen und bearbeiten", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Fertigungsauftrag für einen Artikel anlegen und prüfen, dass Statuswechsel (angelegt→in Arbeit→fertig) nachvollziehbar sind", + "qm": "", + "uebernahme": "übernehmen - Fertigungsauftragsteuerung ist erforderlich, sofern Eigenfertigung/Konfektionierung stattfindet" + }, + { + "id": "StRS-43", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Produktionsmaschinen als Stammdaten verwalten", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-42", + "konsolidierung": "nein", + "pruefidee": "Maschine anlegen und einem Fertigungsauftrag zuordnen; prüfen, dass die Zuordnung in der Auftragsübersicht sichtbar ist", + "qm": "", + "uebernahme": "übernehmen - Maschinenstammdaten sind Voraussetzung für Kapazitätsplanung in der Fertigung" + }, + { + "id": "StRS-44", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "RMA-Abwicklung inkl. Verschrottung fehlerhafter Ware", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-12", + "konsolidierung": "nein", + "pruefidee": "RMA für einen Artikel mit Seriennummer anlegen, als \"verschrottet\" abschließen und prüfen, dass die Seriennummer in der Bestandsführung nicht mehr als verfügbar geführt wird", + "qm": "", + "uebernahme": "übernehmen - RMA-Prozess inkl. Verschrottungsdokumentation ist für Gewährleistungsabwicklung erforderlich" + }, + { + "id": "StRS-45", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Support-Tickets erfassen und bearbeiten", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Ticket mit Prozessvorlage \"Störung\" anlegen und prüfen, dass die vorlagenspezifischen Bearbeitungsschritte angeboten werden", + "qm": "", + "uebernahme": "übernehmen - Ticketverwaltung ist Kernfunktion des Helpdesk-Geschäfts" + }, + { + "id": "StRS-46", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Helpdesk-Kennzahlen im Dashboard darstellen", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-45", + "konsolidierung": "nein", + "pruefidee": "Ticket überfällig werden lassen und prüfen, dass sich die Dashboard-Kennzahl entsprechend ändert", + "qm": "", + "uebernahme": "übernehmen - Kennzahlen-Dashboard unterstützt Steuerung des Helpdesk-Betriebs" + }, + { + "id": "StRS-47", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Erwartete Wartungsereignisse mit wochentagsgenauem Zeitfenster überwachen", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Erwartetes Ereignis mit Zeitfenster Montag 08:00-09:00 konfigurieren, kein passendes Ereignis liefern und prüfen, dass dies als Abweichung erkannt wird", + "qm": "", + "uebernahme": "übernehmen - proaktives SLA-Monitoring ist ein zentrales Verkaufsargument des Managed-Service-Geschäfts" + }, + { + "id": "StRS-48", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Ticketprozesse und Aufgabenverwaltung konfigurieren", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-45", + "konsolidierung": "nein", + "pruefidee": "Konfigurationsparameter ändern und prüfen, dass sich das Ticketverhalten entsprechend ändert", + "qm": "", + "uebernahme": "übernehmen - Konfigurierbarkeit der Ticketprozesse ist für unterschiedliche Kundenverträge (SLA) erforderlich" + }, + { + "id": "StRS-49", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Selbstbedienungsformular und Checklisten für den Helpdesk", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-45", + "konsolidierung": "nein", + "pruefidee": "Ticket über das Selbstbedienungsformular anlegen und prüfen, dass es unverändert im Helpdesk erscheint", + "qm": "", + "uebernahme": "übernehmen - Selbstbedienung reduziert telefonische Erstaufnahme im Helpdesk" + }, + { + "id": "StRS-50", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Stammdaten automatisiert auf Pflichtfeldverstöße prüfen (Dateninspektion)", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Kostenstellenpflicht aktivieren, Artikel ohne Kostenstelle anlegen, Inspector ausführen und prüfen, dass der Artikel in der Fehlerliste erscheint und über den Dialog korrigierbar ist", + "qm": "", + "uebernahme": "übernehmen - proaktive Datenqualitätsprüfung ist unabhängig von der Zielarchitektur sinnvoll" + }, + { + "id": "StRS-51", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Persönliche API-Zugriffstoken mit Ablaufdatum verwalten", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-6", + "konsolidierung": "nein", + "pruefidee": "Token mit Ablaufdatum in der Vergangenheit erzeugen (falls zulässig) bzw. ein gültiges Token nach Ablaufdatum verwenden und prüfen, dass der API-Zugriff verweigert wird", + "qm": "", + "uebernahme": "übernehmen - persönliche, befristete API-Token sind guter Sicherheitsstandard gegenüber dauerhaft gültigen Zugangsdaten" + }, + { + "id": "StRS-52", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Persönliche Tagesplanung (MyDay) für Mitarbeitende und Übersicht für Vorgesetzte", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Termin im persönlichen MyDay eines Mitarbeiters anlegen und prüfen, dass er in der Vorgesetzten-Übersicht korrekt erscheint", + "qm": "", + "uebernahme": "übernehmen - Tagesplanung mit Führungssicht unterstützt Personaleinsatzsteuerung" + }, + { + "id": "StRS-53", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Konfigurierbares persönliches Startdashboard", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "Kandidat: Abgrenzung zu StRS-89 (Startdashboard, Modules/Dashboard) und StRS-58 (Statistics/Dashboard) prüfen - mehrere Dashboard-Implementierungen im System", + "pruefidee": "Kachel aus einer Kategorie hinzufügen und prüfen, dass sie nach erneuter Anmeldung weiterhin angezeigt wird", + "qm": "", + "uebernahme": "übernehmen - personalisierbares Dashboard ist Standard moderner Business-Software" + }, + { + "id": "StRS-54", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Persönliche Aufgabenliste mit Helpdesk-Bezug", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-45", + "konsolidierung": "nein", + "pruefidee": "Ticket einem Mitarbeiter zuweisen und prüfen, dass es mit korrektem Status in dessen Aufgabenliste erscheint", + "qm": "", + "uebernahme": "übernehmen - konsolidierte persönliche Aufgabenliste erhöht Übersichtlichkeit für Mitarbeitende" + }, + { + "id": "StRS-55", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Telefonanlagen-Integration mit Anrufprotokoll", + "typ": "Schnittstelle", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Eingehenden Anruf eines bekannten Kunden simulieren und prüfen, dass der Anruf mit Kundenbezug im Protokoll erscheint", + "qm": "", + "uebernahme": "übernehmen - Anrufprotokollierung mit Kundenbezug unterstützt Servicequalität" + }, + { + "id": "StRS-56", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Fernwartungssitzungen über Supremo anstoßen", + "typ": "Schnittstelle", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Fernwartung aus einem Ticket heraus starten und prüfen, dass die richtige Kunden-Session in Supremo geöffnet wird", + "qm": "", + "uebernahme": "Sonderfall - Anbindung an einen bestimmten Drittanbieter (Supremo); im Zielsystem als austauschbare Fernwartungsanbindung zu gestalten" + }, + { + "id": "StRS-57", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Verkaufsstatistiken mit konfigurierbaren Datenquellen auswerten", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Zwei unterschiedliche Datenquellen für denselben Zeitraum auswerten und Konsistenz der Summen prüfen", + "qm": "", + "uebernahme": "übernehmen - flexible Verkaufsstatistik ist Standardanforderung an ein ERP-Reporting" + }, + { + "id": "StRS-58", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Filialübergreifende Management-Kennzahlen darstellen", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "Kandidat: Abgrenzung zu StRS-53 (MyCentron-Dashboard) und StRS-89 (Startdashboard) prüfen", + "pruefidee": "Kennzahl für eine einzelne Filiale filtern und mit der Gesamtsumme aller Filialen vergleichen", + "qm": "", + "uebernahme": "übernehmen - filialübergreifendes Reporting ist für Mehrstandortunternehmen erforderlich" + }, + { + "id": "StRS-59", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "MSP-Kennzahlen aus Gerätedaten der Managed-Service-Anbieter auswerten", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-95", + "konsolidierung": "nein", + "pruefidee": "Gerätedaten eines MSP-Collectors einspielen und prüfen, dass sie im MSP-Dashboard erscheinen", + "qm": "", + "uebernahme": "übernehmen - MSP-Auswertung ist zentrales Verkaufsargument für Managed-Service-Anbieter unter den Kunden" + }, + { + "id": "StRS-60", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Mitarbeiterbezogene Kennzahlen auswerten", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Mitarbeiter mit bekannter Ticketanzahl auswerten und Kennzahl gegen die tatsächliche Ticketanzahl prüfen", + "qm": "", + "uebernahme": "übernehmen - Mitarbeiterkennzahlen unterstützen Personalsteuerung; datenschutzrechtliche Grenzen im Zielsystem beachten (siehe DSGVO-Modul)" + }, + { + "id": "StRS-61", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Hinterlegte Reports zentral verwalten und ausführen", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Report mit Parametern ausführen und Ergebnis gegen eine manuelle Kontrollabfrage prüfen", + "qm": "", + "uebernahme": "übernehmen - zentrale Reportverwaltung ist Grundfunktion; Zugriffsschutz auf abfragebasierte Reports im Zielsystem verifizieren" + }, + { + "id": "StRS-62", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Gruppenbasierte Rechtevergabe für Anwendungsfunktionen", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-8, SyRS-9, SwRS-6", + "konsolidierung": "nein", + "pruefidee": "Benutzer einer Gruppe ohne bestimmtes Recht zuordnen und prüfen, dass HasUserRight() false liefert; nach Zuweisung eines Kindrechts an die Gruppe prüfen, dass auch das Elternrecht automatisch zugewiesen ist", + "qm": "", + "uebernahme": "übernehmen - gruppenbasiertes RBAC-Modell mit hierarchischen Rechten ist eine solide Grundlage für das Zielsystem" + }, + { + "id": "StRS-63", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Mitarbeiterstammdaten inkl. Azure-AD-Import verwalten", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-62", + "konsolidierung": "nein", + "pruefidee": "Mitarbeiter mit bereits vergebenem Kürzel aus AD importieren und prüfen, dass ein Konflikt erkannt und aufgelöst werden muss", + "qm": "", + "uebernahme": "übernehmen - Azure-AD-Import reduziert manuelle Doppelpflege von Mitarbeiterstammdaten" + }, + { + "id": "StRS-64", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Mandanten mit Filialen und Firmendaten hierarchisch verwalten", + "typ": "funktional", + "belege": [ + "SEKUNDÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Mandant mit zwei Filialen anlegen und prüfen, dass jede Filiale einen eigenen Belegnummernkreis führt", + "qm": "", + "uebernahme": "übernehmen - Mandanten-/Filialhierarchie mit eigenen Nummernkreisen ist Voraussetzung für Konzern-/Franchise-Strukturen" + }, + { + "id": "StRS-65", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Auftragsverarbeitungsverträge und Datenlöschung rechtekontrolliert durchführen", + "typ": "funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-62, StRS-2 (Crm/Dsgvo-Tab)", + "konsolidierung": "nein", + "pruefidee": "Benutzer ohne HasDatabaseCleanupRight anmelden und prüfen, dass die Datenbankbereinigungsfunktion nicht verfügbar/ausführbar ist", + "qm": "", + "uebernahme": "übernehmen - rechtekontrollierte Löschfunktion und AVV-Prozess sind für DSGVO-Konformität zwingend" + }, + { + "id": "StRS-66", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Systemweite API-Token-Richtlinie zentral verwalten", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-51", + "konsolidierung": "nein", + "pruefidee": "Administrative Richtlinie (z. B. maximale Gültigkeitsdauer) ändern und prüfen, dass neu erzeugte persönliche Token diese Grenze einhalten", + "qm": "", + "uebernahme": "übernehmen - zentrale Sicherheitsrichtlinie für Token ist sinnvoll" + }, + { + "id": "StRS-67", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Datenbank-/Webservice-Verbindungen zentral konfigurieren", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-98", + "konsolidierung": "nein", + "pruefidee": "Webservice auf inkompatible Version aktualisieren und prüfen, ob die Versionskontrolle dies anzeigt/verhindert", + "qm": "", + "uebernahme": "übernehmen - zentrale Verbindungskonfiguration ist Basisvoraussetzung für Client-Server-Betrieb" + }, + { + "id": "StRS-68", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "KI-gestützte Erstellung von E-Mail-Vorlagen", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-82 (KI-Unterstützung)", + "konsolidierung": "nein", + "pruefidee": "KI-gestützte Vorlagenerstellung mit Stichworten aufrufen und den Vorschlag gegen manuell erstellte Vorlagen auf Konsistenz prüfen", + "qm": "", + "uebernahme": "übernehmen - KI-Unterstützung bei Textvorlagen reduziert manuellen Formulierungsaufwand" + }, + { + "id": "StRS-69", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "PDF-Signatur und KI-gestützte Textbausteine für Belege konfigurieren", + "typ": "funktional", + "belege": [ + "KONTEXT", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Signatureinstellung aktivieren, Beleg erzeugen und prüfen, dass die PDF-Datei eine gültige elektronische Signatur trägt", + "qm": "", + "uebernahme": "übernehmen - elektronische Signatur ist für rechtssichere Belege relevant" + }, + { + "id": "StRS-70", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Stundenverrechnungssätze mit Zuschlägen je Vertrag pflegen", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-20", + "konsolidierung": "nein", + "pruefidee": "Vertrag mit abweichendem Stundensatz anlegen und in TimerBilling (StRS-20) prüfen, dass der abweichende Satz verwendet wird", + "qm": "", + "uebernahme": "übernehmen - vertragsspezifische Stundensätze sind im Servicegeschäft üblich" + }, + { + "id": "StRS-71", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Eskalationsempfänger für SLA-Verstöße konfigurieren", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-47", + "konsolidierung": "nein", + "pruefidee": "SLA-Frist eines Tickets künstlich überschreiten und prüfen, dass die konfigurierten Empfänger benachrichtigt werden", + "qm": "", + "uebernahme": "übernehmen - Eskalationsmanagement ist zentral für die Einhaltung vertraglicher SLA" + }, + { + "id": "StRS-72", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Länderstammdaten für Steuer- und Adressvalidierung pflegen", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-14", + "konsolidierung": "nein", + "pruefidee": "Neues Land mit Steuersätzen anlegen und in ChangeTaxRateViewModel (StRS-14) auf Verfügbarkeit prüfen", + "qm": "", + "uebernahme": "übernehmen - zentrale Länderstammdaten sind Grundlage für internationales Geschäft" + }, + { + "id": "StRS-73", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "SEPA-Lastschriftmandate mit Signaturworkflow verwalten", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-65", + "konsolidierung": "Kandidat: StRS-65 - SepaContractSettingsViewModel und OrderProcessingContractSettingsViewModel (DSGVO-AVV) sind strukturell nahezu identische Implementierungen desselben \"digitalen Vertragssignatur\"-Konzepts für zwei unterschiedliche Vertragsarten, erkennbar an den unverändert aus der DSGVO-Vorlage übernommenen Feldnamen - im Zielsystem als ein generisches Signatur-Workflow-Konzept zu konsolidieren", + "pruefidee": "SEPA-Mandat über den Signatur-Workflow ablehnen lassen und prüfen, dass die konfigurierte Ablehnungs-E-Mail versendet wird", + "qm": "", + "uebernahme": "übernehmen - SEPA-Mandatsverwaltung ist für Lastschriftverfahren zwingend; technische Dopplung mit DSGVO-AVV-Workflow ist migrationsrelevant" + }, + { + "id": "StRS-74", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Externe Zusatzwerkzeuge in die Oberfläche einbinden", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Externes Werkzeug konfigurieren und prüfen, dass es im Menü erscheint und startet", + "qm": "", + "uebernahme": "übernehmen - Erweiterbarkeit durch externe Werkzeuge unterstützt individuelle Kundenprozesse" + }, + { + "id": "StRS-75", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "WebCart-Shop für Kunden konfigurieren", + "typ": "funktional", + "belege": [ + "KONTEXT", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-1, StRS-101", + "konsolidierung": "nein", + "pruefidee": "Kunde mit Web-Account und hinterlegten Sonderpreisen anlegen und prüfen, dass im WebCart genau diese Artikel bestellbar sind", + "qm": "", + "uebernahme": "übernehmen - WebCart ist unmittelbares Vorbild/Kernstück für die geplante Web-/SaaS-Neuimplementierung" + }, + { + "id": "StRS-76", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Prozessbezogene Benachrichtigungsschalter konfigurieren", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Versandbestätigungsschalter deaktivieren und prüfen, dass bei Lieferscheinerstellung keine Bestätigungsmail versendet wird", + "qm": "", + "uebernahme": "übernehmen - granulare Steuerung automatisierter Benachrichtigungen vermeidet ungewollte Kundenkommunikation" + }, + { + "id": "StRS-77", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Anwendungs-Logdateien einsehen", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Fehler provozieren und prüfen, dass der zugehörige Logeintrag im Log-Betrachter auffindbar ist", + "qm": "", + "uebernahme": "übernehmen - integrierter Log-Zugriff erleichtert Support ohne Serverzugriff" + }, + { + "id": "StRS-78", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Hintergrunddienste und Benachrichtigungen zentral verwalten", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Konfiguration des Benachrichtigungsdienstes ändern und Neustart-Verhalten prüfen", + "qm": "", + "uebernahme": "übernehmen - zentrale Dienstkonfiguration erleichtert Betrieb; im SaaS-Zielsystem durch Cloud-native Dienste zu ersetzen" + }, + { + "id": "StRS-79", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Bankumsätze automatisiert Rechnungen zuordnen und unbekannte IBANs behandeln", + "typ": "funktional", + "belege": [ + "SEKUNDÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-22, StRS-23", + "konsolidierung": "nein", + "pruefidee": "Banktransaktion mit exakt passendem Rechnungsbetrag einspielen und prüfen, ob eine automatische Vorschlagszuordnung zur offenen Rechnung erfolgt; danach Transaktion mit unbekannter IBAN einspielen und den Klärungsassistenten durchlaufen", + "qm": "", + "uebernahme": "übernehmen - automatisierte Zahlungszuordnung reduziert manuellen Abgleichsaufwand in der Debitorenbuchhaltung erheblich" + }, + { + "id": "StRS-80", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Bankverbindungen für Online-Banking-Abruf konfigurieren", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-79, StRS-107", + "konsolidierung": "nein", + "pruefidee": "Zweite Bankverbindung konfigurieren und prüfen, dass deren Umsätze getrennt abrufbar sind", + "qm": "", + "uebernahme": "übernehmen - Mehrbankfähigkeit ist für Unternehmen mit mehreren Bankverbindungen erforderlich" + }, + { + "id": "StRS-81", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Verbindungsaufbau zur Bank (FinTS/HBCI) herstellen", + "typ": "Schnittstelle", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-80", + "konsolidierung": "nein", + "pruefidee": "Verbindungsaufbau mit falschen Zugangsdaten versuchen und prüfen, dass eine verständliche Fehlermeldung erscheint", + "qm": "", + "uebernahme": "übernehmen - robuster Verbindungsaufbau inkl. TAN-Verfahren ist für Online-Banking zwingend" + }, + { + "id": "StRS-82", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "KI-Chat-Assistent für Anwender", + "typ": "funktional", + "belege": [ + "SEKUNDÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "KI-Chat aus dem Ticket-Kontext heraus öffnen und prüfen, dass der Ticketkontext (z. B. Ticketnummer) automatisch in die Konversation übernommen wird", + "qm": "", + "uebernahme": "übernehmen - modulübergreifende KI-Unterstützung ist ein Differenzierungsmerkmal, sollte im Zielsystem als zentraler Dienst statt Einzelintegrationen gestaltet werden" + }, + { + "id": "StRS-83", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Kundenumfragen erstellen und auswerten", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Umfrage versenden, Antwort erfassen und prüfen, dass sie in der Auswertung korrekt gezählt wird", + "qm": "", + "uebernahme": "übernehmen - Kundenumfragen unterstützen Servicequalitätsmessung" + }, + { + "id": "StRS-84", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Massenänderungen anhand wiederverwendbarer Vorlagen durchführen", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Massenänderungsvorlage speichern, erneut aufrufen und prüfen, dass dieselbe Änderung reproduzierbar ausgeführt wird", + "qm": "", + "uebernahme": "übernehmen - wiederverwendbare Massenänderungen reduzieren wiederkehrenden manuellen Pflegeaufwand" + }, + { + "id": "StRS-85", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Zugangsdaten verschlüsselt verwalten und Fernzugriff (RDP/SSH) direkt starten", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SwRS-8", + "konsolidierung": "nein", + "pruefidee": "Zugangsdatensatz in der Datenbank direkt einsehen und prüfen, dass das Passwortfeld nicht im Klartext, sondern als AES-Chiffrat vorliegt", + "qm": "", + "uebernahme": "übernehmen - verschlüsselte, zentrale Zugangsdatenverwaltung mit direktem Fernzugriffsstart ist ein Kernwerkzeug für Managed-Service-Techniker" + }, + { + "id": "StRS-86", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Kalendersynchronisation und ticketbezogene Termine konfigurieren", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-45", + "konsolidierung": "nein", + "pruefidee": "Termin in Outlook anlegen und prüfen, dass er nach Synchronisation im c-entron-Kalender erscheint", + "qm": "", + "uebernahme": "übernehmen - Kalendersynchronisation mit Outlook ist im Büroalltag Standard" + }, + { + "id": "StRS-87", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "QM-Prüfgründe für Belege und Assets pflegen", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-44", + "konsolidierung": "nein", + "pruefidee": "Neuen Begründungseintrag anlegen und prüfen, dass er im RMA-Prozess (StRS-44) auswählbar ist", + "qm": "", + "uebernahme": "übernehmen - standardisierte Begründungskataloge verbessern Auswertbarkeit von Reklamationsursachen" + }, + { + "id": "StRS-88", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Vertragsdaten für Telekom-DIVE-Plattform exportieren", + "typ": "Schnittstelle", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Export durchführen und Datei gegen die DIVE-Formatspezifikation validieren", + "qm": "", + "uebernahme": "Sonderfall - anbieterspezifische Schnittstelle zu einem einzelnen Vorleistungspartner (Telekom)" + }, + { + "id": "StRS-89", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Konfigurierbares modulbasiertes Startdashboard", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "Kandidat: siehe StRS-53 - mehrere Dashboard-Implementierungen (Start-Dashboard, MyCentron-Dashboard, Statistics-Dashboard) im System", + "pruefidee": "Modul-Kachel anklicken und prüfen, dass das richtige Fachmodul geöffnet wird", + "qm": "", + "uebernahme": "übernehmen - Startdashboard mit Modulzugriff ist zentrale Navigationshilfe" + }, + { + "id": "StRS-90", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Oberflächen-Layoutprofile je Benutzer verwalten", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Layout anpassen, als Profil speichern, Layout ändern und Profil wiederherstellen; prüfen, dass Originalzustand wiederhergestellt wird", + "qm": "", + "uebernahme": "übernehmen - individuelle Layoutprofile erhöhen Produktivität vielgenutzter Arbeitsplätze" + }, + { + "id": "StRS-91", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Lizenzabgleich für Managed-Service-Provider-Lizenzen", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-59", + "konsolidierung": "nein", + "pruefidee": "Künstliche Abweichung zwischen internem und externem Bestand erzeugen und prüfen, dass sie im Abgleich erkannt wird", + "qm": "", + "uebernahme": "übernehmen - Lizenzabgleich verhindert Über-/Unterlizenzierung im MSP-Geschäft" + }, + { + "id": "StRS-92", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Zentrale Geschäftslogik- und Datenzugriffsschicht für alle Fachmodule", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Dieselbe fachliche Regel (z. B. Rechteprüfung) über WPF-Client und Webservice-Aufruf auslösen und identisches Verhalten prüfen", + "qm": "", + "uebernahme": "übernehmen - gemeinsame Kernschicht ist grundsätzlich migrationsfreundlich; interne Kopplungen (z. B. an NHibernate/ADO) im Zielsystem zu prüfen" + }, + { + "id": "StRS-93", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Strukturierten EDI-Datenaustausch mit mehreren Distributoren pflegen", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-38", + "konsolidierung": "Kandidat: Sechs strukturell ähnliche, aber getrennt implementierte EDI-Anbindungen (Also/AlsoCH/Alltron/Herweck/Komsa/EGIS) - im Zielsystem auf ein gemeinsames EDI-Format-Mapping-Framework zu konsolidieren", + "pruefidee": "Bestellung an zwei unterschiedliche Distributoren senden und prüfen, dass jeweils das korrekte distributorspezifische XML-Format erzeugt wird", + "qm": "", + "uebernahme": "übernehmen - EDI-Anbindung an die wichtigsten IT-Distributoren ist geschäftskritisch für den Einkaufsprozess" + }, + { + "id": "StRS-94", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "FinTS-Bankanbindung auf Backend-Ebene bereitstellen", + "typ": "Schnittstelle", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-79", + "konsolidierung": "nein", + "pruefidee": "Kontoabruf über den Gateway-Dienst auslösen und mit dem UI-seitig angezeigten Ergebnis (StRS-79) auf Konsistenz prüfen", + "qm": "", + "uebernahme": "übernehmen - gekapselte Bankanbindung ist Voraussetzung für automatisierten Zahlungsabgleich" + }, + { + "id": "StRS-95", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Gerätedaten von MSP-Plattformen zentral sammeln", + "typ": "Schnittstelle", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-59", + "konsolidierung": "nein", + "pruefidee": "Neues Gerät bei einer angebundenen Plattform anlegen und prüfen, dass es nach dem nächsten Collector-Lauf im System erscheint", + "qm": "", + "uebernahme": "übernehmen - automatisierte Gerätedatensammlung ist Kern des MSP-Geschäftsmodells" + }, + { + "id": "StRS-96", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Strukturierte E-Rechnungsformate (ZUGFeRD/OpenTrans) erzeugen", + "typ": "Schnittstelle", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-12", + "konsolidierung": "Kandidat: Zwei parallele E-Rechnungsformate (ZUGFeRD, openTRANS) - im Zielsystem auf den heute rechtlich geforderten Standard (z. B. EN16931/XRechnung) zu konsolidieren", + "pruefidee": "Erzeugte ZUGFeRD-Rechnung gegen ein öffentlich verfügbares ZUGFeRD-2.1-Validierungstool prüfen", + "qm": "", + "uebernahme": "übernehmen - strukturierte E-Rechnung wird EU-weit zunehmend verpflichtend; Formatwahl im Zielsystem an aktuelle Rechtslage anzupassen" + }, + { + "id": "StRS-97", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Anbindung an den c-entron-Portal-Webservice", + "typ": "Schnittstelle", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Datensatz im Portal ändern und prüfen, dass die Änderung nach Synchronisation im System sichtbar ist", + "qm": "", + "uebernahme": "veraltet - SOAP-basierte \"Service References\" deuten auf eine ältere Integrationsgeneration hin, im SaaS-Zielsystem durch REST/moderne API zu ersetzen" + }, + { + "id": "StRS-98", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Web-API mit zweifacher Authentifizierung (Sitzungsticket/Access-Token) und Anwendungs-Autorisierung", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-10, SyRS-7, StRS-62", + "konsolidierung": "nein", + "pruefidee": "Siehe SyRS-10", + "qm": "", + "uebernahme": "übernehmen - zentrale, konsistente API-Authentifizierung ist im Zielsystem fortzuführen und um methodenscharfe Scopes zu ergänzen" + }, + { + "id": "StRS-99", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Lizenzen und Hardware-IDs für Webservice-Verbindungen verwalten", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Lizenz auf abweichender Hardware-ID einspielen und prüfen, dass die Aktivierung verweigert wird", + "qm": "", + "uebernahme": "übernehmen - hardwaregebundene Lizenzierung passt nicht zum SaaS-Zielmodell und ist durch ein abonnementbasiertes Verfahren zu ersetzen" + }, + { + "id": "StRS-100", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Web-basiertes Kanban-Ticketboard mit Leistungs-/Vertragszuordnung", + "typ": "funktional", + "belege": [ + "SEKUNDÄR", + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-45, StRS-20", + "konsolidierung": "Kandidat: Prüfen, ob ServiceBoard (Nexus/Web) und Helpdesk/TicketDetails (WPF, StRS-45) im Zielsystem als eine einzige Web-Ticketverwaltung statt zweier Implementierungen für zwei Clients geführt werden sollen", + "pruefidee": "Ticket im Kanban einer Leistungsart zuordnen und prüfen, dass sie in der Zeit-/Leistungsabrechnung (StRS-20) korrekt erscheint", + "qm": "", + "uebernahme": "übernehmen - webbasiertes Ticketboard ist unmittelbares Vorbild für die Web-/SaaS-Neuimplementierung des Helpdesk" + }, + { + "id": "StRS-101", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Web-Kundenportal mit Shop-Funktion (WebCart)", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-75, SwRS-7", + "konsolidierung": "nein", + "pruefidee": "Kunde meldet sich mit Web-Account an und prüft Sichtbarkeit nur der eigenen Dokumente/Bestellungen", + "qm": "", + "uebernahme": "übernehmen - Kundenportal ist Kernstück der geplanten Web-/SaaS-Neuimplementierung" + }, + { + "id": "StRS-102", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Fertigungsaufträge webbasiert mit Arbeitsschritt-Vorlagen steuern", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-42", + "konsolidierung": "Kandidat: Abgrenzung zur WPF-seitigen Production/ProductionOrder-Verwaltung (StRS-42) prüfen - ggf. zwei Implementierungen derselben Fertigungssteuerung", + "pruefidee": "Fertigungsauftrag mit Arbeitsschritt-Vorlage abarbeiten und prüfen, dass der Fortschritt je Schritt nachvollziehbar ist", + "qm": "", + "uebernahme": "übernehmen - webbasierte Werkerführung ist zeitgemäßer als reine Desktop-Fertigungssteuerung" + }, + { + "id": "StRS-103", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Web-Benutzerkonten, Aufgaben und Ticketmuster verwalten", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-62, SwRS-7", + "konsolidierung": "Kandidat: siehe SwRS-7 - strukturell identisches Rechtebaum-Muster für interne (RightsTreeViewModel) und Web-Rechte (WebRightNode) getrennt implementiert", + "pruefidee": "Web-Account-Recht auf Baumebene 2 aktivieren und prüfen, dass abhängige Kindrechte konsistent mitgeführt werden", + "qm": "", + "uebernahme": "übernehmen - hierarchische Rechteverwaltung für Web-Accounts ist notwendig; Implementierung im Zielsystem mit internem Modell zusammenzuführen" + }, + { + "id": "StRS-104", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Elektronische Dokumentensignatur im Web mit Signaturstil-Auswahl", + "typ": "Sicherheit", + "belege": [ + "SEKUNDÄR" + ], + "status": "HYPOTHESE", + "hypothese": true, + "workaround": false, + "tracelinks": "StRS-65, StRS-73, StRS-69", + "konsolidierung": "nein", + "pruefidee": "Signiertes Dokument nach Signatur byteweise verändern und prüfen, ob das System die Manipulation erkennt/die Signatur invalidiert", + "qm": "", + "uebernahme": "übernehmen - Web-Signatur ist gemeinsame technische Grundlage für DSGVO-AVV (StRS-65) und SEPA-Mandat (StRS-73) - Konsolidierungshinweis dort beachten" + }, + { + "id": "StRS-105", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "c-entron-Funktionen in Microsoft Outlook integrieren", + "typ": "Schnittstelle", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "E-Mail in Outlook über das Add-in in ein Ticket umwandeln und Vollständigkeit der Übernahme prüfen", + "qm": "", + "uebernahme": "übernehmen - Outlook-Integration reduziert Medienbrüche im Arbeitsalltag" + }, + { + "id": "StRS-106", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Produktkatalogdaten von externen Datenlieferanten anreichern", + "typ": "Schnittstelle", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-27", + "konsolidierung": "Kandidat: Vier strukturell gleichartige Produktdaten-APIs (COP/EGIS/ITscope/Icecat) - im Zielsystem auf ein gemeinsames Produktdaten-Anreicherungs-Interface mit austauschbarem Provider zu konsolidieren", + "pruefidee": "Artikel über zwei unterschiedliche Anbieter anreichern und auf widerspruchsfreie Zusammenführung der Daten prüfen", + "qm": "", + "uebernahme": "übernehmen - externe Katalogdatenanreicherung reduziert manuelle Artikelpflege erheblich; technische Vervierfachung ist migrationsrelevant" + }, + { + "id": "StRS-107", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Bankkontoinformationen über Drittanbieter FinAPI abrufen", + "typ": "Schnittstelle", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-94, StRS-80", + "konsolidierung": "Kandidat: Zwei parallele Wege zum Kontoumsatzabruf (direktes FinTS-Gateway StRS-94, PSD2-Aggregator FinAPI) - im Zielsystem auf einen Weg zu konsolidieren", + "pruefidee": "Kontoabruf über FinAPI auslösen und mit direktem FinTS-Abruf (StRS-94) auf inhaltliche Konsistenz prüfen", + "qm": "", + "uebernahme": "übernehmen - PSD2-Kontoinformationsdienste sind ein moderner, wartungsärmerer Ansatz als direkte FinTS-Anbindung" + }, + { + "id": "StRS-108", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Österreichische ebInterface-E-Rechnungen erzeugen", + "typ": "Schnittstelle", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-96", + "konsolidierung": "Kandidat: siehe StRS-96 - drittes paralleles E-Rechnungsformat neben ZUGFeRD/openTRANS", + "pruefidee": "Ebinterface-Rechnung gegen die offizielle ebInterface-XSD validieren", + "qm": "", + "uebernahme": "übernehmen - für Geschäft mit österreichischen (insb. öffentlichen) Auftraggebern gesetzlich erforderlich" + }, + { + "id": "StRS-109", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Sendungsdaten bei mehreren Versanddienstleistern erzeugen", + "typ": "Schnittstelle", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-37", + "konsolidierung": "Kandidat: GLS-Direktanbindung und Shipcloud-Aggregator decken teilweise denselben fachlichen Zweck (Versandlabel-Erzeugung) ab - im Zielsystem auf eine Versand-Abstraktion mit austauschbarem Carrier zu konsolidieren", + "pruefidee": "Lieferschein über beide Anbindungen versenden und Label-Inhalte auf Konsistenz (Absender/Empfänger/Gewicht) prüfen", + "qm": "", + "uebernahme": "übernehmen - Mehrfach-Carrier-Anbindung ist im Versand geschäftsüblich; Implementierungsdopplung migrationsrelevant" + }, + { + "id": "StRS-110", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "PDF-Formulare dynamisch aus Belegdaten generieren", + "typ": "Schnittstelle", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-7, StRS-69", + "konsolidierung": "nein", + "pruefidee": "Beleg mit Sonderzeichen/Sonderfällen als PDF ausgeben und auf korrekte Darstellung prüfen", + "qm": "", + "uebernahme": "übernehmen - dynamische PDF-Generierung ist für Belegausgabe unverzichtbar" + }, + { + "id": "StRS-111", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Adress-/Kontoimport mit feldweiser Validierung", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Importdatei mit einer Zeile ohne Pflichtfeld einspielen und prüfen, dass genau diese Zeile als fehlerhaft markiert wird", + "qm": "", + "uebernahme": "übernehmen - feldweise Importvalidierung verhindert Datenmüll im Adressstamm" + }, + { + "id": "StRS-112", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Buchungsdaten für die Finanzbuchhaltung exportieren", + "typ": "Schnittstelle", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-22, StRS-24", + "konsolidierung": "Kandidat: Abgrenzung zu StRS-113 (DATEV-Direktanbindung) prüfen - ggf. zwei Wege für denselben Exportzweck", + "pruefidee": "Export einer Periode durchführen und Summenabstimmung gegen die Opos-Übersicht (StRS-22) prüfen", + "qm": "", + "uebernahme": "übernehmen - Fibu-Export ist buchhalterisch zwingend" + }, + { + "id": "StRS-113", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Direkter Datenaustausch mit DATEV", + "typ": "Schnittstelle", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-112", + "konsolidierung": "Kandidat: siehe StRS-112", + "pruefidee": "Beleg mit PDF-Anhang exportieren und in DATEV auf korrekte Zuordnung Buchung↔Belegbild prüfen", + "qm": "", + "uebernahme": "übernehmen - DATEV ist der verbreitetste Fibu-Standard im deutschsprachigen Mittelstand" + }, + { + "id": "StRS-114", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "SEPA-Lastschrift-/Überweisungsdateien standardkonform erzeugen", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-73, StRS-23", + "konsolidierung": "nein", + "pruefidee": "Erzeugte SEPA-Datei gegen die referenzierte XSD validieren", + "qm": "", + "uebernahme": "übernehmen - ISO-20022-Konformität ist für SEPA-Einreichung bei Banken zwingend" + }, + { + "id": "StRS-115", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Datenaustausch mit der Telekom-DIVE-Plattform (Schnittstellenebene)", + "typ": "Schnittstelle", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-88", + "konsolidierung": "nein", + "pruefidee": "Übertragung auslösen und Empfang bei der Plattform bestätigen lassen", + "qm": "", + "uebernahme": "Sonderfall - siehe StRS-88" + }, + { + "id": "StRS-116", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Generischer Datenexport aus c-entron", + "typ": "funktional", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "keine", + "konsolidierung": "nein", + "pruefidee": "Export durchführen und Vollständigkeit gegen Quelldaten prüfen", + "qm": "", + "uebernahme": "übernehmen - generischer Export bleibt auch im Zielsystem als Fallback sinnvoll" + }, + { + "id": "StRS-117", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Ergänzende Konnektoren für Remote-Monitoring und filialweise Lieferantenbestellung", + "typ": "Schnittstelle", + "belege": [ + "KONTEXT" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-38", + "konsolidierung": "nein", + "pruefidee": "Bestellung für zwei Filialen auslösen und prüfen, dass sie getrennt beim Lieferanten ankommen", + "qm": "", + "uebernahme": "übernehmen - filialweise Bestelltrennung ist für Filialisten mit eigenständiger Belieferung erforderlich" + }, + { + "id": "StRS-118", + "ebene": "StRS", + "datei_ebene": "StRS", + "fremdabgelegt": false, + "titel": "Containerisierte Bereitstellung von Webservice und Nexus über CI/CD-Pipelines", + "typ": "nicht-funktional", + "belege": [ + "PRIMÄR", + "SEKUNDÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-98", + "konsolidierung": "nein", + "pruefidee": "Pipeline-Lauf mit bewusst eingebauter Sicherheitslücke beobachten und prüfen, dass die Security-Pipeline den Build stoppt", + "qm": "Übertragbarkeit", + "uebernahme": "übernehmen - containerisierte, pipeline-gestützte Auslieferung mit Sicherheitsprüfung ist direkte Grundlage für den SaaS-Betrieb des Zielsystems" + }, + { + "id": "SyRS-1", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Konfigurierbares Pflichtfeld-Set bei Objekterzeugung prüfen", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-2", + "konsolidierung": "nein", + "pruefidee": "Alle Pflichtfeld-Flags in CrmSettings deaktivieren und prüfen, dass der Dialog ohne Eingaben speicherbar ist; danach ein Flag aktivieren und Gegenprobe durchführen", + "qm": "", + "uebernahme": "übernehmen - konfigurierbare Pflichtfelder je Mandant sind ein wiederkehrendes Muster, das im Zielsystem als generischer Validierungsmechanismus vorgesehen werden sollte" + }, + { + "id": "SyRS-2", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Duplikatprüfung beim Anlegen eines Sonderpreises aus der Belegposition", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-1", + "konsolidierung": "nein", + "pruefidee": "Für einen Artikel mit bereits bestehendem Sonderpreis einen zweiten Sonderpreis aus einer Belegposition anlegen und prüfen, dass der Bestätigungsdialog erscheint und bei \"Nein\" kein zweiter Datensatz entsteht", + "qm": "", + "uebernahme": "übernehmen - Duplikatvermeidung bei Sonderpreisen ist eine sinnvolle Datenintegritätsregel" + }, + { + "id": "SyRS-3", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Auftragsbezogene Anzahlungsrechnungen für die Schlussrechnung bereitstellen", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-13", + "konsolidierung": "nein", + "pruefidee": "Auftrag mit einer bereits abgeschlossenen und einer offenen Anzahlungsrechnung versehen und prüfen, dass LoadRelatedDownPaymentInvoices() beide zurückliefert", + "qm": "", + "uebernahme": "übernehmen - vollständige Erfassung aller Anzahlungen unabhängig vom Abschlussstatus ist für eine korrekte Schlussrechnung zwingend" + }, + { + "id": "SyRS-4", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Mahnfähigkeit eines Belegs serverseitig aus Persistenzdaten ableiten", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-21", + "konsolidierung": "nein", + "pruefidee": "AK.FaelligAm auf einen Platzhalterwert ≤2 setzen und prüfen, dass DueDate in der Belegsuche NULL liefert und der Beleg im Mahnlauf als \"ohne Fälligkeitsdatum\" ausgeschlossen wird", + "qm": "", + "uebernahme": "übernehmen - serverseitige, konsistente Datenbasis für den Mahnlauf ist Voraussetzung für ein rechtssicheres Mahnwesen" + }, + { + "id": "SyRS-5", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Nebenläufige Bearbeitung von Belegen durch Sperr- und Versionskennung absichern", + "typ": "nicht-funktional", + "belege": [ + "PRIMÄR" + ], + "status": "HYPOTHESE", + "hypothese": true, + "workaround": false, + "tracelinks": "StRS-12", + "konsolidierung": "nein", + "pruefidee": "Beleg in zwei Sitzungen gleichzeitig öffnen, in Sitzung A speichern, danach in Sitzung B speichern und prüfen, dass Sitzung B einen Konflikt anhand der abweichenden GUID/des LockUser erkennt statt die Änderung aus A stillschweigend zu verwerfen", + "qm": "Zuverlässigkeit", + "uebernahme": "übernehmen - Konflikterkennung bei Mehrbenutzerzugriff ist für ein Mehrbenutzer-ERP zwingend; Umsetzungsdetail im Zielsystem zu verifizieren" + }, + { + "id": "SyRS-6", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Pflichtangabe eines Ablaufdatums bei Erzeugung persönlicher API-Token", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-51", + "konsolidierung": "nein", + "pruefidee": "Token-Erzeugungsdialog ohne Auswahl eines Ablaufdatums abschließen und prüfen, ob ein Standardwert gesetzt oder die Erzeugung verweigert wird", + "qm": "", + "uebernahme": "übernehmen - verpflichtendes Ablaufdatum begrenzt das Risiko dauerhaft gültiger, kompromittierter Token" + }, + { + "id": "SyRS-7", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Ablaufende persönliche API-Token beim API-Zugriff serverseitig zurückweisen", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR", + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-51, SyRS-6", + "konsolidierung": "nein", + "pruefidee": "Token mit ExpiresAt in der Vergangenheit gegen einen Webservice-Endpunkt verwenden und prüfen, dass der Aufruf abgelehnt und ein ValidationFailed-Logeintrag mit Grund \"Token ist abgelaufen\" erzeugt wird", + "qm": "", + "uebernahme": "übernehmen - Hash-Speicherung, Ablaufprüfung und lückenlose Protokollierung sind vorbildliche Sicherheitspraxis für das Zielsystem" + }, + { + "id": "SyRS-10", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Duale API-Authentifizierung über Sitzungsticket oder Access-Token mit anwendungsbezogener Einschränkung", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-62, SyRS-7", + "konsolidierung": "nein", + "pruefidee": "Ticket einer für Methode X nicht zugelassenen Anwendung verwenden und prüfen, dass der Aufruf mit \"You don't have the permission...\" abgewiesen wird; anschließend mit einem Access-Token dieselbe Methode aufrufen und die fehlende Anwendungseinschränkung bestätigen", + "qm": "", + "uebernahme": "übernehmen - Zwei-Wege-Authentifizierung ist sinnvoll; die vom Entwickler selbst dokumentierte Lücke (keine methodenscharfe Einschränkung für Access-Token/bestimmte Anwendungen) ist im Zielsystem gezielt zu schließen (z. B. Scopes je Access-Token)" + }, + { + "id": "SyRS-8", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Serverseitige Rechteprüfung mit benutzerbezogenem Cache", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "HYPOTHESE", + "hypothese": true, + "workaround": false, + "tracelinks": "StRS-62", + "konsolidierung": "nein", + "pruefidee": "Benutzer ein Recht entziehen, während dessen Sitzung aktiv ist, und prüfen, wie lange die alte Berechtigung noch wirksam bleibt", + "qm": "", + "uebernahme": "übernehmen - Caching ist sinnvoll, Invalidierungsstrategie bei Rechteänderung im Zielsystem explizit zu spezifizieren" + }, + { + "id": "SyRS-9", + "ebene": "SyRS", + "datei_ebene": "SyRS", + "fremdabgelegt": false, + "titel": "Administrator-Gruppe vor Entzug systemkritischer Rechte schützen", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-62", + "konsolidierung": "nein", + "pruefidee": "Versuch, ein nicht in GetAssignableAdminRightI3Ds() enthaltenes Recht von der Administrator-Gruppe zu entfernen, und prüfen, dass RemoveAssignGroupToRight() false liefert", + "qm": "", + "uebernahme": "übernehmen - Schutz vor Selbstaussperrung der Administration ist eine bewährte Sicherheitsmaßnahme" + }, + { + "id": "SwRS-1", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "CanAccept()-Gate für den Kundenanlage-Dialog", + "typ": "funktional", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-1", + "konsolidierung": "nein", + "pruefidee": "Unit-Test, der CanAccept() mit einer Kombination gesetzter/nicht gesetzter Pflichtfelder aufruft und den erwarteten bool-Rückgabewert prüft", + "qm": "", + "uebernahme": "übernehmen - Command/CanExecute-Bindung ist Standardmuster und im Zielsystem als deklarative Validierung abzubilden" + }, + { + "id": "SwRS-2", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Rechteabhängige Freigabe von Kampagnenfunktionen", + "typ": "funktional", + "belege": [ + "SEKUNDÄR" + ], + "status": "HYPOTHESE", + "hypothese": true, + "workaround": false, + "tracelinks": "StRS-3", + "konsolidierung": "nein", + "pruefidee": "Benutzer ohne Kampagnen-Bearbeitungsrecht anmelden und prüfen, dass die Bearbeiten-Funktion in der UI deaktiviert ist UND ein direkter Service-Aufruf serverseitig abgelehnt wird", + "qm": "", + "uebernahme": "übernehmen - rechteabhängige Funktionsfreigabe ist Standardanforderung; serverseitige Durchsetzung im Zielsystem verifizieren (siehe Hypothese)" + }, + { + "id": "SwRS-3", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Update statt Duplikat bei bestehendem Sonderpreis", + "typ": "Daten", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-2", + "konsolidierung": "nein", + "pruefidee": "Zwei Sonderpreise für denselben Artikel/dieselbe Kundenklasse anlegen und in der Datenbank prüfen, dass nur ein Datensatz existiert", + "qm": "", + "uebernahme": "übernehmen - Datenintegritätsregel ohne erkennbaren Workaround-Charakter" + }, + { + "id": "SwRS-4", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Länderspezifische Steuersatzliste als einzige Quelle für ChangeTaxRateViewModel", + "typ": "Daten", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-14", + "konsolidierung": "nein", + "pruefidee": "Backend-Antwort auf zwei Steuersätze begrenzen und prüfen, dass der Dialog exakt diese zwei Optionen anzeigt", + "qm": "", + "uebernahme": "übernehmen - zentrale, länderabhängige Steuersatzquelle vermeidet inkonsistente Sätze" + }, + { + "id": "SwRS-5", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Berechnungsregel für OpenPrice/OpenPriceFC in der Belegsuche", + "typ": "Daten", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "SyRS-2, StRS-22, StRS-23", + "konsolidierung": "nein", + "pruefidee": "Unit-/Integrationstest mit MwstNichtAusweisbar=1, Bezahlt>0 und CurrencyFactor≠1 gegen die erwartete Formel prüfen", + "qm": "", + "uebernahme": "übernehmen - zentrale, einheitliche Berechnungsstelle vermeidet abweichende Parallelberechnungen in Opos/Zahlungserfassung/Mahnwesen" + }, + { + "id": "SwRS-6", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Datenmodell Sichtrus/Sichmemb für gruppenbasierte Rechte", + "typ": "Daten", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-62", + "konsolidierung": "nein", + "pruefidee": "Benutzer zwei Gruppen mit je einem unterschiedlichen Recht zuordnen und prüfen, dass GetAllAppRightsFromUser() beide Rechte zurückliefert", + "qm": "", + "uebernahme": "übernehmen - reines Gruppenmodell ohne Benutzer-Einzelrechte vereinfacht Administration und Auditierbarkeit" + }, + { + "id": "SwRS-7", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "Getrennte Rechtemodelle für interne Benutzer und Web-Accounts", + "typ": "Daten", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-62, StRS-101 (Nexus)", + "konsolidierung": "Kandidat: Zwei strukturell gleichartige, aber datenseitig getrennte Rechtemodelle (AppRight/Sichtrus für interne Benutzer, WebRights für Web-Accounts) - im Zielsystem als ein gemeinsames Rechtemodell mit Geltungsbereich zu konsolidieren", + "pruefidee": "Web-Account und internen Benutzer mit identischem Namen aber unterschiedlichen Rechten anlegen und prüfen, dass sich Web-Zugriff und interner Zugriff unabhängig voneinander verhalten", + "qm": "", + "uebernahme": "Workaround - historisch getrennt gewachsene Rechtemodelle für zwei Kanäle; im SaaS-Zielsystem mit einheitlichem Identitätsmodell zusammenzuführen" + }, + { + "id": "SwRS-8", + "ebene": "SwRS", + "datei_ebene": "SwRS", + "fremdabgelegt": false, + "titel": "AES-Verschlüsselung von Zugangsdaten mit zentralem Master-Schlüssel", + "typ": "Sicherheit", + "belege": [ + "PRIMÄR" + ], + "status": "belegt", + "hypothese": false, + "workaround": false, + "tracelinks": "StRS-85", + "konsolidierung": "nein", + "pruefidee": "Master-Schlüssel-Zugriff simulieren und prüfen, dass ohne ihn kein aus der Fachdatenbank gelesener ValueEncryptedString entschlüsselbar ist", + "qm": "", + "uebernahme": "übernehmen - Trennung von Chiffrat und Schlüssel auf getrennte Datenbanken ist ein sinnvolles Sicherheitsmuster für das Zielsystem" + } +] \ No newline at end of file diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/anforderungen.md b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/anforderungen.md new file mode 100644 index 00000000..6e1697c0 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/anforderungen.md @@ -0,0 +1,65 @@ +## Gefundene Anforderungen + +Maschinell aus `Ergebnisse\StRS.md`, `SyRS.md` und `SwRS.md` ausgewertet (Blockformat des Prompts). Erzeugt von `analyse-anforderungen.py`. + +Die Kenngrößen decken die **maschinell prüfbare** Hälfte des Evaluationsrahmens aus Kapitel 4.3 ab: Belegqualität und Übernahmewürdigkeit gehören zur *Statement-Qualität*, Verteilung und Konsolidierungskandidaten zur *Set-Qualität*, Tracelinks und Belegklassifikation zur *Traceability-Qualität*. Die Expertenbewertung nach Likert-Skala tritt daneben und wird hier nicht ersetzt. + +### Verteilung über die Ebenen + +| Ebene | Anzahl | Anteil | +|---|---:|---:| +| StRS | 118 | 86,8 % | +| SyRS | 10 | 7,4 % | +| SwRS | 8 | 5,9 % | +| **Gesamt** | **136** | 100 % | + +### Anforderungstypen + +| Typ | Anzahl | Anteil | +|---|---:|---:| +| funktional | 100 | 73,5 % | +| Schnittstelle | 19 | 14,0 % | +| Sicherheit | 10 | 7,4 % | +| Daten | 5 | 3,7 % | +| nicht-funktional | 2 | 1,5 % | + +### Belegqualität + +| Messgröße | Wert | +|---|---:| +| Belege gesamt | 166 | +| davon `PRIMÄR` | 51 (30,7 %) | +| davon `SEKUNDÄR` | 60 (36,1 %) | +| davon `KONTEXT` | 55 (33,1 %) | +| Belege je Anforderung (Median) | 1,0 | +| Anforderungen mit mindestens einem `PRIMÄR`-Beleg | 46 (33,8 %) | + +### Übernahmewürdigkeit + +| Einstufung | Anzahl | Anteil | +|---|---:|---:| +| übernehmen | 129 | 94,9 % | +| workaround | 2 | 1,5 % | +| sonderfall | 4 | 2,9 % | +| veraltet | 1 | 0,7 % | + +### Status + +| Kategorie | Anzahl | Anteil | +|---|---:|---:| +| belegt | 130 | 95,6 % | +| als `HYPOTHESE` gekennzeichnet | 6 | 4,4 % | +| als Workaround vermerkt | 0 | 0,0 % | +| Konsolidierungskandidaten | 23 | 16,9 % | +| mit ISO-25010-Qualitätsmerkmal | 2 | 1,5 % | + +### Regelkonformität (Prüfung gegen die Vorgaben des Prompts) + +| Vorgabe | Ergebnis | +|---|---| +| **Belegpflicht** – jede Anforderung mindestens ein Artefaktbeleg | **erfüllt** (0 Anforderungen ohne Beleg) | +| **Risikobasierte Priorisierung** – Sicherheit, Abrechnung, Berechtigungen brauchen einen `PRIMÄR`-Beleg oder die Kennzeichnung `[HYPOTHESE]` | **verletzt** – 7 von 33 ungedeckt: StRS-25, StRS-31, StRS-72, StRS-91, StRS-92, StRS-99, StRS-102 | +| **Verifizierbarkeit** – jede Anforderung mit Prüfidee oder Akzeptanzkriterium | **erfüllt** | +| **Übernahmewürdigkeit** – Einstufung für die Migrationsperspektive | **erfüllt** (alle 136 Anforderungen eingestuft) | +| **Traceability** – Verknüpfung zwischen den Ebenen | 81 von 136 mit Tracelinks (59,6 %) | + diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/before.txt b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/before.txt new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/before.txt @@ -0,0 +1 @@ + diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/combined_prompt.md b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/combined_prompt.md new file mode 100644 index 00000000..55baf048 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/combined_prompt.md @@ -0,0 +1,177 @@ +# Versuch 01 - Baseline (Prompt-only) - Iteration 02 + +## Metadaten +- **Versuch:** V1 Baseline (Prompt-only) +- **Iteration:** 02 (erste Überarbeitung nach Auswertung von Iteration 01) +- **Codebasis:** c-entron ERP-Suite (Windows, C#/XAML, MSSQL) +- **Zeitstempel:** 2026-08-26 +- **Vorgänger:** `01_Prompt.md` (SHA-256 `1B0DB06B…3C02FF`), 24 Läufe an Tag 1 +- **Änderungsgrund:** Auswertung der 24 Läufe von Tag 1 über 3.287 erzeugte Anforderungen. Jede Änderung ist an einen gemessenen Befund gekoppelt: + + | Änderung | Auslösender Befund | + |---|---| + | Modulinventar als Pflicht-Vorstufe, Mindestabdeckung je Modul, Vertiefung erst danach | Anforderungszahl schwankte je Lauf zwischen 42 und 325 (Faktor 5,9); 55 bis 60 von rund 85 Modulen blieben unanalysiert; die Modultabellen der Analyseberichte reichten von 0 bis 51 Zeilen | + | Hypothesenpflicht kalibriert, `Hypothesen.md` deckungsgleich mit den Inline-Markierungen | Zwei Läufe meldeten null Hypothesen bei 71 bzw. 148 Anforderungen; der Anteil schwankte zwischen 0 % und 26,2 %; mehrfach wichen Sammeldatei und Inline-Markierungen voneinander ab | + | Primärbeleg muss die durchsetzende Stelle benennen | 45,9 % aller Anforderungen trugen genau einen Beleg; in einem Lauf waren 5 von 31 risikorelevanten Anforderungen weder mit `PRIMÄR` noch als `[HYPOTHESE]` gedeckt | + | Belegpflicht verschärft: ohne Beleg keine Anforderung | Eine Anforderung wurde ohne jeden Beleg geschrieben | + | Konsolidierungsbegriff an einem Beispiel kalibriert | Anteil der Konsolidierungskandidaten schwankte je Lauf zwischen 2,4 % und 35,2 % | + | Eigenes Feld `Qualitätsmerkmal` für die ISO-25010-Zuordnung | Die Zuordnung war gefordert, hatte aber keinen Ablageort: nur 33 von 313 nicht-funktionalen Anforderungen führten sie als eigene Angabe | + | Risikoanforderungen im Konsistenzcheck auflisten | Verstöße gegen die risikobasierte Priorisierung fielen erst in der nachgelagerten Auswertung auf, nicht im Lauf selbst | + + Unverändert bleiben Prüfidee, Tracelinks, Belegklassifikation und das Blockformat: Prüfidee und Tracelinks waren in **allen** 3.287 Anforderungen gesetzt, 78,6 % der Belege waren `PRIMÄR`. + +> Dieser Prompt enthält ausschließlich die **Analyseanweisung** und ist damit unabhängig von einem +> bestimmten Werkzeug oder Modell einsetzbar. Welche Werkzeuge im jeweiligen Lauf zur Verfügung +> stehen und wohin die Ergebnisse geschrieben werden, stellt der Versuchsaufbau beim Start bei. + +--- + +## Prompt + +Du bist ein Requirements Engineer im Reverse Requirements Engineering eines Legacy-ERP-Systems. Erzeuge aus der vorliegenden Codebasis eine Anforderungsspezifikation nach **ISO/IEC/IEEE 29148:2018**. Arbeite ausschließlich auf den im Arbeitsverzeichnis liegenden Artefakten (Quellcode, Konfiguration, UI-Ressourcen, ggf. DB-Skripte). Nutze nur Informationen, die du aus diesen Artefakten gewinnen kannst. + +### Auftrag + +Erzeuge eine konsolidierte Spezifikation auf den drei Ebenen: + +1. **StRS** - Stakeholder Requirements Specification (fachliche Sicht, Akteure, Geschäftsziele) +2. **SyRS** - System Requirements Specification (Systemverhalten, Schnittstellen, Performance-, Sicherheitsanforderungen) +3. **SwRS** - Software Requirements Specification (Komponenten, Datenmodelle, Software-interne Regeln) + +Ziel ist eine Spezifikation, die als belastbare Basis für eine Web-/SaaS-Neuimplementierung dienen kann. + +### Scope (Schritt 1 der RRE-Methodenkette, manuell vorgegeben) + +Der Untersuchungsgegenstand ist die **gesamte Codebasis** im Arbeitsverzeichnis. Es gilt bewusst keine Modulbeschränkung: Alle Module, Datenobjekte und Prozesse sind gleichrangig zu erfassen. + +**Breite geht vor Tiefe.** Ein fehlendes Requirement führt bei einer Neuimplementierung zu Funktionsverlust; eine oberflächlich erfasste Funktion lässt sich dagegen nachschärfen. Erfasse deshalb zuerst die gesamte Breite und vertiefe erst danach. Halte dich an die Reihenfolge aus dem Abschnitt **Vorgehen**: erst Inventar, dann Mindestabdeckung, dann Vertiefung. + +### Vorgehen (statische Analyse, keine Ausführung) + +Bearbeite die Schritte 2-6 der RRE-Methodenkette (Schritt 1 Scope ist oben vorgegeben, Schritt 7 Validierung erfolgt manuell durch Fachexperten). Vorgeschaltet ist eine verbindliche Inventarisierung: + +**Schritt 0 - Modulinventar (vor der ersten Anforderung).** Verschaffe dir zuerst einen vollständigen Überblick über den Untersuchungsgegenstand und lege ihn im `Analysebericht.md` als Tabelle ab: fachliches Modul beziehungsweise Komponente, Pfad im Arbeitsverzeichnis, ein Satz zur fachlichen Aufgabe. Das Inventar wird erstellt, **bevor** die erste Anforderung formuliert wird. Es ist die Bezugsgröße für die Abdeckung und darf später ergänzt, aber nicht gekürzt werden. + +**Schritt 0b - Mindestabdeckung.** Jedes Modul des Inventars erhält **mindestens eine** Anforderung, bevor irgendein Modul vertieft wird. Lässt sich für ein Modul keine belegbare Anforderung bilden, führe es im Inventar als `nicht analysiert` mit einer kurzen Begründung. Ein Modul ohne Anforderung und ohne Begründung ist unzulässig. + +**Schritt 0c - Vertiefung nach Risiko.** Erst wenn die Mindestabdeckung steht, vertiefe einzelne Module. Beginne dort, wo Sicherheitsregeln, Abrechnungs- und Fakturierungslogik oder Berechtigungsprüfungen liegen. + +2. **Artefakterhebung:** Erfasse Quellcode, Konfiguration, UI-Texte, Datenbankschemata, Schnittstellenbeschreibungen sowie Change-Historie und Projektartefakte (Commit-Messages, Tickets, Release Notes, Migrationsnotizen), soweit als Datei lesbar. +3. **Technische Analyse:** Identifiziere Module, Komponenten, Abhängigkeiten, Statusmaschinen, Validierungslogik, Berechtigungsprüfungen. +4. **Semantische Interpretation:** Leite fachliche Aussagen aus technischen Implementierungen ab (z. B. Statusübergänge → Geschäftsregel). +5. **Formalisierung:** Überführe die Aussagen in klare, testbare Anforderungen mit Kontext, Vorbedingung und Ergebnis. +6. **Traceability-Anreicherung:** Verknüpfe jede Anforderung mit konkreten Artefaktbelegen. + +### Pflicht-Eigenschaften jeder Anforderung + +- **Belegpflicht:** Jede Anforderung **muss** mindestens einen konkreten Artefaktbeleg führen (Dateipfad, Klasse/Methode, SQL-Statement, UI-String, Konfigurationseintrag). Jeder Beleg erhält eine kurze Begründung, warum er die Aussage trägt. Lässt sich eine Aussage nicht belegen, **schreibe die Anforderung nicht** - erfasse den offenen Punkt stattdessen als Hypothese. Eine Anforderung ohne Beleg ist unter keinen Umständen zulässig. +- **Trennung von Fakt und Interpretation:** Die belegte technische Beobachtung (Feld `Fakt`) wird getrennt von der fachlichen Interpretation (Feld `Aussage`) dokumentiert, damit nachvollziehbar bleibt, was im Artefakt steht und was daraus geschlossen wurde. +- **Risikobasierte Priorisierung:** Anforderungen zu Sicherheitsregeln, Abrechnungs-/Fakturierungslogik und Berechtigungen unterliegen strengeren Evidenzanforderungen: Sie benötigen mindestens einen `PRIMÄR`-Beleg, andernfalls sind sie zwingend als `[HYPOTHESE]` zu kennzeichnen. Ein `PRIMÄR`-Beleg benennt hier die **durchsetzende Stelle** - Datei, Klasse, Methode und die konkrete Prüfung, Bedingung oder das Constraint. Ein Verweis auf eine Datei ohne Angabe der prüfenden Stelle genügt für diese Anforderungen nicht. +- **Belegklassifikation:** Kennzeichne jeden Beleg als + - `PRIMÄR` (durchgesetzte Regel im Code oder DB-Constraint), + - `SEKUNDÄR` (UI-Label, Fehlermeldung, Reportlayout, Mappingtabelle, Konfigurationsschalter), + - `KONTEXT` (Kommentar, Commit-Message, Ticketreferenz). +- **Hypothesenmarkierung:** Aussagen, die sich nicht eindeutig aus Artefakten ableiten lassen, kennzeichnest du explizit mit `[HYPOTHESE]` und einer kurzen Begründung, welche Information zur Bestätigung fehlt. Bei einer Codebasis dieser Größe ist eine Analyse ohne jeden offenen Punkt unplausibel: Führst du keine einzige Hypothese, begründe das ausdrücklich in der Selbstbewertung. Umgekehrt ist eine hohe Hypothesenzahl kein Mangel, sondern ein Hinweis auf ehrliche Abgrenzung. +- **Verifizierbarkeit:** Jede Anforderung enthält mindestens eine Prüfidee oder ein Akzeptanzkriterium. +- **Eindeutigkeit:** Vermeide vage Begriffe ("schnell", "benutzerfreundlich"); definiere domänenspezifische Begriffe beim ersten Auftreten. +- **Übernahmewürdigkeit:** Beurteile für jede Anforderung, ob ihre Funktion im Zielsystem erhalten bleiben soll. Unterscheide `übernehmen` (fachlich weiterhin erforderlich), `Workaround` (historisch gewachsene Behelfslösung), `Sonderfall` (Ausnahme für einen einzelnen Kunden, Mandanten oder Altbestand) und `veraltet` (durch neuere Logik abgelöst oder fachlich überholt). Begründe die Einstufung in einem Halbsatz. Diese Angabe steuert die spätere fachliche Priorisierung; eine Fehleinschätzung ist unkritisch, eine fehlende Angabe nicht. +- **Redundanzfreiheit:** Formuliere jede Anforderung so, dass sie von den übrigen klar abgegrenzt ist. Beschreiben zwei Anforderungen dieselbe fachliche Funktion aus unterschiedlicher Perspektive, führe sie zusammen oder grenze sie im Titel und in der Aussage ausdrücklich gegeneinander ab. + +### Formatvorgabe pro Anforderung + +``` +ID: - +Titel: +Ebene: +Typ: +Qualitätsmerkmal: +Akteur: +Vorbedingung: +Fakt: +Aussage: Das System soll <...>. (fachliche Interpretation als klare Soll-Aussage) +Ergebnis: +Belege: + - [PRIMÄR] - Begründung: + - [SEKUNDÄR] <...> - Begründung: <...> + - [KONTEXT] <...> - Begründung: <...> +Prüfidee: +Tracelinks: +Konsolidierung: > +Übernahmewürdigkeit: <übernehmen | Workaround | Sonderfall | veraltet> - +Status: +``` + +### Traceability + +Stelle Forward- und Backward-Traceability zwischen den drei Ebenen her: +- Jede SwRS-Anforderung referenziert die zugehörige SyRS-Anforderung. +- Jede SyRS-Anforderung referenziert die zugehörige StRS-Anforderung. +- Erzeuge zusätzlich eine konsolidierte **Traceability-Tabelle** (Markdown oder CSV): `StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg`. + +### Nicht-funktionale Anforderungen + +- Ordne nicht-funktionale Anforderungen den Qualitätsmerkmalen der **ISO/IEC 25010** zu (z. B. Zuverlässigkeit, Performance-Effizienz, Sicherheit, Wartbarkeit, Übertragbarkeit). Trage die Zuordnung in das dafür vorgesehene Feld `Qualitätsmerkmal` ein, nicht in das Feld `Typ`. +- Leite Betriebs- und Sicherheitsanforderungen gezielt auch aus indirekt sichtbaren Artefakten ab: Konfigurationen, Deployment-Skripte, Logging-Policies, Rechteprüfungen. + +### Konsolidierungsbedarf + +Die Codebasis enthält fachliche Redundanz: Dieselbe Anforderung kann auf unterschiedlichen Masken oder in unterschiedlichen Modulen mehrfach und teils unterschiedlich implementiert sein. Prüfe daher bei jeder Anforderung, ob andere Anforderungen dieselbe fachliche Funktion abbilden, und vermerke solche Fälle im Feld `Konsolidierung` als Kandidat für eine Zusammenführung im Zielsystem. + +**Gemeint sind fachlich gleichartige Konzepte in getrennten Implementierungen**, nicht bloß ähnlich formulierte Anforderungen. Ein Beispiel aus dieser Codebasis: Drucker werden als „Stammblätter" geführt, sonstige Hardware getrennt davon als „Assets" - zwei Datenhaltungen für denselben fachlichen Gegenstand, die im Zielsystem zu einem Asset-Konzept zusammengeführt werden sollen. Zwei Anforderungen, die denselben Sachverhalt nur aus Sicht verschiedener Ebenen beschreiben (etwa StRS und SwRS), sind **kein** Konsolidierungsfall - dafür sind die Tracelinks da. + +### Ergebnisstruktur (im vorgegebenen Ausgabeverzeichnis) + +``` +Ergebnisse/ + StRS.md + SyRS.md + SwRS.md + Traceability.md (oder Traceability.csv) + Hypothesen.md (Sammlung aller mit [HYPOTHESE] markierten Aussagen mit offener Frage) + Glossar.md (Domänenbegriffe, die in den Anforderungen verwendet werden) + Analysebericht.md (Modulinventar aus Schritt 0, Abdeckungstabelle, Konsistenzcheck, + Selbstbewertung, bekannte Lücken) +``` + +Das Ausgabeverzeichnis wird beim Start des Laufs beigestellt. Die analysierte Codebasis wird ausschließlich gelesen und nicht verändert. + +### Randbedingungen + +- **Keine Halluzinationen.** Wenn ein Artefakt nicht gelesen oder eine Aussage nicht belegt werden kann, ist das offen zu legen, nicht zu erfinden. +- **Keine Generierung von Code.** Es sollen ausschließlich Spezifikationsartefakte entstehen. +- **Keine Annahme über nicht beigestellte Hilfsmittel.** Arbeite mit dem, was dir in diesem Lauf zur Verfügung steht. Setze keine zusätzlichen Analysewerkzeuge, Datenbankzugriffe oder laufende Systeme voraus. Stehen für eine Aussage nur indirekte Belege zur Verfügung, ist sie als `[HYPOTHESE]` zu kennzeichnen. +- **Migrationsperspektive berücksichtigen.** Erkennbare Workarounds, Sonderfälle und überholte Logik gehören in das Feld `Übernahmewürdigkeit`, nicht in das Feld `Status`. `Status` beschreibt ausschließlich die Belegsituation (`belegt` oder `HYPOTHESE`), `Übernahmewürdigkeit` die fachliche Zukunft der Anforderung. Beide Angaben sind unabhängig voneinander: Eine gut belegte Anforderung kann ein Workaround sein, eine Hypothese kann übernahmewürdig sein. +- **Sprache:** Deutsch für Anforderungsaussagen, technische Bezeichner (Klassen, Methoden, Spalten) bleiben in ihrer Originalsprache. + +### Abschluss + +Führe vor Abgabe einen **Konsistenzcheck über das gesamte Anforderungs-Set** durch und dokumentiere das Ergebnis im `Analysebericht.md`: +- Doppelte oder mehrfach vergebene IDs +- Anforderungen ohne Beleg +- Anforderungen ohne Angabe zur `Übernahmewürdigkeit` +- Tracelinks auf nicht existierende IDs +- Inhaltlich deckungsgleiche Anforderungen, die nicht als Konsolidierungskandidat markiert sind +- **Liste aller risikorelevanten Anforderungen** (Sicherheit, Abrechnung/Fakturierung, Berechtigungen) mit ihrer Belegsituation: ID, Titel, ob ein `PRIMÄR`-Beleg vorliegt, andernfalls die `[HYPOTHESE]`-Kennzeichnung. Diese Liste macht Verstöße gegen die risikobasierte Priorisierung im Lauf selbst sichtbar. +- **Abgleich `Hypothesen.md` gegen die Inline-Markierungen:** Beide müssen dieselben Anforderungen nennen. `Hypothesen.md` enthält genau die Anforderungen mit `[HYPOTHESE]`-Markierung und keine zusätzlichen freien Fragen; offene Punkte ohne zugehörige Anforderung gehören in die Selbstbewertung. + +Erstelle außerdem die **Abdeckungstabelle** auf Basis des Modulinventars aus Schritt 0: je Modul die Einstufung `tief | mittel | flach | nicht analysiert` und die Anzahl der daraus erzeugten Anforderungen. Jede Zeile des Inventars muss in der Abdeckungstabelle auftauchen. + +Beende den Lauf mit einer kurzen Selbstbewertung im `Analysebericht.md`: +- Wie viele Module des Inventars wurden tief, mittel, flach beziehungsweise gar nicht analysiert? Nenne absolute Zahlen, nicht nur Beispiele. +- Wurde die Mindestabdeckung erreicht, also hat jedes Modul mindestens eine Anforderung? Falls nein: welche Module fehlen und warum? +- An welchen Stellen war der Beleg dünn (hoher Anteil `SEKUNDÄR`/`KONTEXT` oder `[HYPOTHESE]`)? +- Falls keine einzige Hypothese geführt wurde: Begründung, warum die Analyse ohne offene Punkte auskommt. +- Welche Erkenntnisse legen einen Nachschlag in einer Folge-Iteration nahe? + +--- + +### Werkzeugkontext (vom Versuchsaufbau vorgegeben) +Für diesen Lauf stehen zur Verfügung: Lesen und Suchen von Dateien sowie das Ausführen von +Kommandozeilenbefehlen im Arbeitsverzeichnis. +Nicht verfügbar sind: Subagenten, spezialisierte Agentenrollen, externe Werkzeugserver. +Triff keine Annahmen über weitere Werkzeuge und versuche nicht, nicht verfügbare +Werkzeuge zu ersetzen. +### Ausgabeverzeichnis (überschreibt anderslautende Pfadangaben oben) +Schreibe ALLE zu erzeugenden Ergebnisdateien in das Verzeichnis +`c:\DEV\MasterArbeit\Versuche\Versuch_01\Iteration 3\claude-sonnet-5\solo\max\02_Lauf_2026-08-27_091214_v7.0.0-da3c\Ergebnisse\`. +Verändere keine Dateien im Arbeitsverzeichnis (der analysierten Codebasis). diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/endzeit.txt b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/endzeit.txt new file mode 100644 index 00000000..f4c85d09 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/endzeit.txt @@ -0,0 +1 @@ +2026-08-27T09:59:53.4377636+02:00 diff --git a/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/startzeit.txt b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/startzeit.txt new file mode 100644 index 00000000..9b8f4db2 --- /dev/null +++ b/Versuche/Versuch_01/Iteration 3/claude-sonnet-5/solo/max/02_Lauf_2026-08-27_091214_v7.0.0-da3c/_meta/startzeit.txt @@ -0,0 +1 @@ +2026-08-27T09:12:15.0639875+02:00