V01 Erste Runs
This commit is contained in:
+114
@@ -0,0 +1,114 @@
|
||||
# Analysebericht — V1 Baseline, Iteration 01
|
||||
|
||||
## 1. Vorgehen dieser Iteration
|
||||
|
||||
Ausgangsbasis: `C:\DEV\MasterArbeit\QuellCode\CentronERP` — 82 Projekte laut `Centron.sln`, ca. 17.300 Quell-/Markup-Dateien (`.cs`, `.xaml`, `.razor`), keine `.sql`-Migrationsdateien (Schema/DDL steckt in Fluent-NHibernate-Mappings bzw. eingebetteten SQL-Skripten in `Centron.BL\Administration\Scripts\`). Es standen weder spezialisierte Agentendateien noch MCP-Server zur Verfügung (Baseline-Bedingung dieses Versuchs); genutzt wurden ausschließlich Read/Glob/Grep/Bash sowie generische Recherche-Subagenten (Claude-Code-interne Explore-Agenten) zur parallelen Erstsichtung, deren Befunde in dieser Sitzung manuell zu den vorliegenden Anforderungsdokumenten verdichtet, quergeprüft und teils korrigiert wurden (siehe Abschnitt 4, Traceability-Konsistenz).
|
||||
|
||||
Angesichts des Umfangs (keine Modulbeschränkung laut Auftrag, aber ~85 Top-Level-Module allein in `Centron.BL`) wurde eine **risikobasierte Tiefenpriorisierung** vorgenommen: Domänen mit hoher fachlicher Kritikalität (Fakturierung, Zahlungsverkehr, Rechte-/Authentifizierungssystem, C-Sign/Vertragsabschluss) wurden bis auf Methoden-/Zeilenebene analysiert; breite funktionale Abdeckung (Helpdesk, RMA, Lager, Einkauf, EDI, Web-Kanäle) wurde mit soliden, aber nicht erschöpfenden Belegen abgedeckt; ein großer Teil der Codebasis wurde **nicht** untersucht (siehe Abschnitt 3).
|
||||
|
||||
## 2. Analysetiefe je Modul/Bereich
|
||||
|
||||
### 2.1 Vollständig/detailliert analysiert (Methoden-/Zeilenebene, mehrere Belege, in StRS/SyRS/SwRS abgebildet)
|
||||
|
||||
| Bereich | Repräsentative Klassen | Requirement-Block |
|
||||
|---|---|---|
|
||||
| Belegkette (Angebot/Auftrag/Lieferschein/Rechnung) | `ReceiptBL`, `*SpecificLogic`, `AutomaticallyCloseReceiptHelperBL` | Block A |
|
||||
| C-Sign / WebOffer | `SharedDocumentBL`, `ReceiptBL.AcceptWebReceipt` | Block A |
|
||||
| Rechnungsfestschreibung, Steuerberechnung | `ReceiptInvoiceBL`, `CalculationUtils` | Block A |
|
||||
| Helpdesk/Ticketing | `HelpdeskBL`, `HelpdeskCloseBL`, `HelpdeskTimerBL` | Block B |
|
||||
| RMA | `RmaBL` (2084 Zeilen) | Block B |
|
||||
| TaskManager (Automatisierung) | `TaskManagementTaskBL`, ActionHandler | Block B |
|
||||
| Artikelstamm/Rechteschutz | `ArticleBL` | Block C |
|
||||
| Inventur | `InventoryBL` | Block C |
|
||||
| Kommissionierung | `PartialCommissionOrderBL`, `OrderCommissionBL` | Block C |
|
||||
| Bestellvorschlag | `OrderSuggestionListBL` | Block C |
|
||||
| EDI-Dispatch | `EDIDispatcherBL` | Block C |
|
||||
| Zahlungen/OnlineBanking | `OnlineBankingAccountTransactionsBL`, `PaymentsBL` | Block D |
|
||||
| Timer Billing Rechte | `ReceiptWebServiceBL`, `TimerBillingSettingsPageViewModel` | Block D |
|
||||
| Rechtesystem | `AppRightsBL`, `UserRightsConst`, `UserRightsExt` | Block E |
|
||||
| Authentifizierung/2FA/Tickets | `AuthenticatorFactory`, `BasicAuthenticator`, `TicketBL`, `TwoFactorAuthBL` | Block E |
|
||||
| Passwort-Tresor | `PasswordManagementAccessLogBL` | Block E |
|
||||
| Kundenportal/WebCart | `WebCartShopPage`, `CustomerAuthPage`, `CurrentCartService` | Block F |
|
||||
| Deployment/CI-CD | `build.yml`, `Dockerfile`, WiX-Setups | Block F |
|
||||
| Datenmodell (Kern) | `Centron.Entities`/`Centron.DAO` (Sales, CustomerArea, Warehousing, BranchArea — stichprobenartig, ~5 von 75 Domänenordnern gelesen) | quer |
|
||||
| Web-Service-Schnittstelle | `Centron.Controllers` (Struktur, ~15 von vermutlich 50+ Controllern gelesen), Authorization-Attribute | quer |
|
||||
|
||||
### 2.2 Mit reduzierter Tiefe analysiert (Struktur/wenige Dateien gelesen, StRS + leichtere SyRS/SwRS-Abdeckung)
|
||||
|
||||
| Bereich | Tiefe | Grund für reduzierte Tiefe |
|
||||
|---|---|---|
|
||||
| Externe Produktdaten-APIs (COP, Egis, ITscope, Icecat) | Je 1 Kernklasse gelesen | Vier strukturell ähnliche Klienten; ein Vertreter (ITscope) im Detail, übrige stichprobenartig zur Bestätigung des Patterns |
|
||||
| Versandintegration (GLS, Shipcloud) | Je 1 Kernklasse gelesen | Analog, geringeres fachliches Risiko als Fakturierung |
|
||||
| E-Rechnung (ebInterface, ZUGFeRD) | 1 Kernklasse + 1 Controller | Format-Erzeugung/-Import bestätigt, keine Feldvalidierung im Detail geprüft |
|
||||
| docuFORM (Managed Print Services) | 1 Klient + Konstanten | Randintegration, geringe fachliche Kernrelevanz für ERP-Kernprozesse |
|
||||
| Accounting (Bankverbindungen) | 1 Datei vollständig | Klein, überschaubar |
|
||||
| Buying (Distributoren) | 1 Datei vollständig | Sehr dünn/thin, wirkt wie Legacy-Stub |
|
||||
| Logistics (Lagerstammdaten) | 2 Dateien | Kleiner Bereich |
|
||||
| TradePool | 2 Kerndateien | B2B-Portal-Funktion, sekundär gegenüber Kernprozessen |
|
||||
| VoucherManagement | 1 Datei (sehr dünn) | Nur eine Methode vorhanden |
|
||||
| Storage (Legacy) | Vollständig gelesen, aber **inaktiv** (auskommentiert) | Historischer Beleg für InventoryBL-Ablösung |
|
||||
| Production | 2 Dateien | Lizenzgeschütztes Zusatzmodul, ohne Rechteprüfung im Code |
|
||||
| CPra, Time, Mail, Mailings, BusinessPartner, Projects, TicketProjects | Je 1-4 Dateien | Sekundäre Module, keine erkennbare hohe fachliche Kritikalität |
|
||||
|
||||
### 2.3 Nicht analysiert (nur über Verzeichnislisting bekannt, keine Datei gelesen)
|
||||
|
||||
Aus `Centron.BL` (≈85 Top-Level-Module) wurden folgende **nicht inhaltlich untersucht**: `Administration` (außer Rights/Logins), `Accounts`, `AppointmentRequests`, `ArtificialIntelligence`, `Calendar`, `Chats`, `CheckListArea`, `Customizations`, `Devices`, `DocuBoard`, `DocumentationArea`, `ExpectedEvents`, `ExternalHelpdesk`, `ExternalToolsBL`, `Gateway`, `IndexSearch`, `Integrations`, `ItPlanner`, `Mobile`, `Modules`, `MyCentron`, `MyDay`, `NexusNotifications`, `NexusTicketViews`, `Notifications`, `ObjectExternalReferences`, `Outlook`, `Processes`, `ProductMatrix`, `Reporting`, `ReportEngine`, `RiverDivo`, `SelfCare`, `Services`, `SocialMedia`, `Statistics`, `SystemArea`, `Tags`, `TextModuleArea`, `Tools`, `Transactions`, `Urls`, `VideoPortal`, `WebLinks`, `WebServices` (generisch), `WebSuite`, `WebVersion`.
|
||||
|
||||
Ebenfalls nicht untersucht: die überwiegende Mehrheit der `Centron.Entities`/`Centron.DAO`-Domänenordner (nur ~5 von ~75 gelesen), die überwiegende Mehrheit der Web-Service-Controller und -DTOs (`Centron.WebServices.Core\Entities`, hunderte Dateien), die überwiegende Mehrheit der 1066 WPF-`.xaml`-Views (nur Ribbon-Merging und einzelne Rechteprüfungs-Fundstellen im Detail), der Großteil von `docs\reference\` (nur stichprobenartig zusammengefasst, nicht jede Datei einzeln gelesen), sowie sämtliche `tests\`-Inhalte auf Ebene einzelner Testfälle (nur Projektstruktur/-anzahl erhoben).
|
||||
|
||||
**Konsequenz:** Diese Iteration deckt einen für eine Erstaufnahme soliden, aber keinen vollständigen Querschnitt der Codebasis ab. Für ca. 55-60 von ~85 BL-Modulen liegt **keine** Anforderung in StRS/SyRS/SwRS vor.
|
||||
|
||||
## 3. Bekannte Lücken (Auszug, priorisiert für Folge-Iteration)
|
||||
|
||||
1. **Reporting/ReportEngine** — vollständig unanalysiert, vermutlich hohe fachliche Relevanz (Auswertungen für Vertrieb/Finance).
|
||||
2. **Statistics** — vollständig unanalysiert; `ManagementInfoBL` wurde nur im Security-Survey am Rande als Beispiel für einschränkende Rechte erwähnt, nicht fachlich untersucht.
|
||||
3. **Reporting-/Statistik-Rechte** und **Mobile**-Modul — keine Aussage möglich.
|
||||
4. **Integrations**, **Gateway**, **ObjectExternalReferences** — Namen deuten auf weitere externe Schnittstellen hin, die nicht erfasst wurden.
|
||||
5. **DocuBoard**, **DocumentationArea** — Dokumentenmanagement-Funktionalität außerhalb der bereits erfassten `SharedDocumentBL`/C-Sign-Logik unbekannt.
|
||||
6. **ArtificialIntelligence** (BL-Modul, zusätzlich zu den in Nexus gefundenen KI-Chat-Features) — nicht untersucht, obwohl KI-Funktionen laut Verzeichnisnamen offenbar mehrfach im System vorkommen (`Centron.BL\ArtificialIntelligence`, `CentronNexus\ServiceBoard\TicketAiSummary`, `AIAssist.razor`).
|
||||
7. Vollständige Controller-/DTO-Landschaft der Web-Service-Schicht (nur ~15 von vermutlich 50+ Controllern gesichtet).
|
||||
8. Vollständige WPF-UI-Maskenebene (nur 1 von 1066 `.xaml`-Dateien im Detail betrachtet — die Ribbon-Merging-Logik).
|
||||
|
||||
## 4. Konsistenzcheck
|
||||
|
||||
Durchgeführt am fertigen Anforderungs-Set (StRS-001…028, SyRS-001…028, SwRS-001…040):
|
||||
|
||||
- **Doppelt/mehrfach vergebene IDs:** Keine gefunden. Jede ID (StRS-/SyRS-/SwRS-Präfix + laufende Nummer) kommt in ihrer jeweiligen Datei genau einmal als Anforderungs-Header vor.
|
||||
- **Anforderungen ohne Beleg:** Keine gefunden. Jede der 96 Anforderungen führt mindestens einen klassifizierten Beleg (PRIMÄR/SEKUNDÄR/KONTEXT).
|
||||
- **Risikoklassen ohne PRIMÄR-Beleg:** Keine gefunden. Alle als Sicherheit/Abrechnung/Berechtigung klassifizierten Anforderungen (u. a. StRS-003, -004, -015, -016, -018 bis -021; SyRS-003 bis -005, -016 bis -023; SwRS-004, -005, -007, -008, -024, -026, -028, -031, -034) führen mindestens einen PRIMÄR-Beleg; keine dieser Anforderungen musste als vollständige `[HYPOTHESE]` markiert werden (einzelne, engere Detailfragen innerhalb sonst PRIMÄR-belegter Anforderungen wurden dennoch als `[HYPOTHESE]` in Prüfidee/Status vermerkt, siehe Hypothesen.md).
|
||||
- **Tracelinks auf nicht existierende IDs:** Bei der Erstformulierung wurden **drei Inkonsistenzen** identifiziert und vor Abgabe korrigiert:
|
||||
1. StRS-005 verwies zunächst nur auf SyRS-001, obwohl die zugehörige Aussage (automatischer Status-Übergang) auch in SyRS-002 behandelt wird → ergänzt.
|
||||
2. StRS-007 verwies fälschlich zusätzlich auf SyRS-021 (Authentifizierungs-Ticket-Ausstellung), was fachlich nicht zusammenhängt → entfernt.
|
||||
3. SyRS-010, SyRS-021 und SyRS-027 wiesen unvollständige Vorwärtsreferenzen zu SwRS-017, SwRS-031 bzw. bereits vorhandenen SwRS auf → ergänzt; zugehörige Rückwärtsreferenzen in StRS-020/StRS-022 wurden zur Bidirektionalität ergänzt.
|
||||
Nach diesen Korrekturen sind alle Tracelinks bidirektional konsistent (jede StRS↔SyRS- und SyRS↔SwRS-Referenz ist in beiden Richtungen auffindbar); eine erneute Stichprobenprüfung von 15 zufällig gewählten IDs nach der Korrektur ergab keine weiteren offenen Verweise.
|
||||
|
||||
## 5. Selbstbewertung
|
||||
|
||||
**Vollständig analysiert** (im Sinne von: alle vorhandenen Dateien des Bereichs gelesen): Accounting, Buying, VoucherManagement, Logistics, TradePool (Kerndateien), Storage (Legacy, inaktiv), CentronRights.md, `docs\`-Indexstruktur (Dateinamen/Übersicht, nicht jede Datei vollständig).
|
||||
|
||||
**Stichprobenhaft analysiert** (repräsentative Auswahl innerhalb eines großen Bereichs): Warehousing (38 Dateien, davon ~6 im Detail), Sales (248 Dateien, davon ~15 im Detail), Centron.Entities/Centron.DAO (~75 Domänenordner, davon 5 im Detail), Centron.WPF.UI (1066 `.xaml`, davon 1 Mechanismus im Detail), Centron.Controllers (~50+ Controller, davon ~15 benannt), Finances (9 Dateien, 3 im Detail), Purchasing (4 Dateien, 2 im Detail).
|
||||
|
||||
**Gar nicht analysiert:** ca. 55-60 von 85 BL-Top-Level-Modulen (siehe Abschnitt 3), der überwiegende Teil der Entity-/DTO-Landschaft, der überwiegende Teil der WPF-Maskenebene, alle Testfälle im Detail (nur Projektstruktur).
|
||||
|
||||
**Stellen mit dünner Beleglage** (hoher Anteil SEKUNDÄR/KONTEXT bzw. verbleibende `[HYPOTHESE]`-Detailfragen trotz insgesamt PRIMÄR-belegter Kernanforderung):
|
||||
- Timer-Billing-Rechteprüfung im tatsächlichen Schreibpfad (H-001).
|
||||
- Serverseitiges Scoping einzelner Kundenportal-Endpunkte (H-002).
|
||||
- Verhalten des `AuthorizeLicense`-Attributs im Detail (H-003).
|
||||
- Resilience-/Retry-Verhalten externer Integrationen (H-004, Block G generell — hier ist die Beleglage über alle vier StRS-025..028 hinweg strukturell dünner als in Block A-E, da nur je 1-2 Kernklassen statt vollständiger Aufrufketten gelesen wurden).
|
||||
- Zwei-Faktor-Authentifizierung: zwei parallele Implementierungen, Verhältnis ungeklärt (H-007).
|
||||
|
||||
**Erkenntnisse, die einen Nachschlag in einer Folge-Iteration nahelegen:**
|
||||
1. **Reporting/Statistics/Integrations/Mobile** vollständig neu erschließen — diese Bereiche fehlen komplett und sind für eine SaaS-Neuimplementierung vermutlich hoch relevant (Reporting typischerweise eine der am stärksten migrationsrelevanten Funktionsgruppen).
|
||||
2. **Vollständige Controller-/DTO-Landschaft** der Web-Service-Schicht systematisch erfassen (aktuell nur ~30 % der vermuteten Controller benannt) — Grundlage für eine belastbare SyRS-Schnittstellenspezifikation einer Web-/SaaS-Neuimplementierung.
|
||||
3. **Sicherheitsbefunde vertiefen und Fachexperten vorlegen:** unsalted SHA-1 bei Passwort-Hashing (SwRS-031), `IsAdmin()`-Bypass über Gruppennamen-String, hartkodierte `true`-Rückgaben in mindestens einer `*SpecificLogic`-Klasse (H-008), fehlende strukturierte Audit-Protokollierung für Logins/Rechteänderungen (H-009) — diese vier Punkte sollten vor einer Zielarchitektur-Entscheidung priorisiert von Fachexperten bewertet werden, da sie über reine Anforderungsdokumentation hinaus sicherheitsrelevante Entscheidungen für die Neuimplementierung beeinflussen.
|
||||
4. **Konsolidierungskandidaten vertiefen:** GLS/Shipcloud (StRS-025/026), OnlineBanking/PaymentsBL (SyRS-016/017), zwei 2FA-Implementierungen (H-007) — je ein Kandidat für Zusammenführung im Zielsystem, aber noch nicht bis zur Entscheidungsreife untersucht.
|
||||
5. **WPF-Maskenebene vs. Web-Service-Rechte-Konsistenz**: systematische Prüfung, ob jede der 1066 WPF-Masken eine äquivalente serverseitige Rechteprüfung besitzt (Stichprobe H-010 deutet auf mögliche Lücken hin).
|
||||
|
||||
## 6. Ergebnisumfang dieser Iteration
|
||||
|
||||
- StRS.md: 28 Anforderungen
|
||||
- SyRS.md: 28 Anforderungen
|
||||
- SwRS.md: 40 Anforderungen
|
||||
- Traceability.md: 40 Traceability-Zeilen (StRS↔SyRS↔SwRS) + 2 ergänzende StRS/SyRS-Paare ohne eigene SwRS
|
||||
- Hypothesen.md: 12 Hypothesen + 1 Prozess-Hinweis
|
||||
- Glossar.md: 26 Begriffe
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
# Glossar
|
||||
|
||||
Domänenbegriffe, wie sie in StRS/SyRS/SwRS dieser Iteration verwendet werden. Herkunft: Code, `CentronRights.md`, `docs/`. Deutsche Fachbegriffe dominieren, da die Codebasis überwiegend deutschsprachige Domänenobjekte verwendet (z. B. Tabellen `RechKopf`, `AngKopf`, `AufKopf`, `LiefKopf`).
|
||||
|
||||
| Begriff | Definition | Quelle |
|
||||
|---|---|---|
|
||||
| **Beleg / Receipt** | Sammelbegriff für alle kaufmännischen Dokumente einer Kette: Angebot (Offer), Auftrag (Order), Lieferschein (DeliveryList), Rechnung (Invoice), Gutschrift (CreditVoucher), Abholliste (PickupList), Vertragsliste (ContractList). Alle Belegarten teilen sich eine gemeinsame Basis-Engine (`ReceiptBL`) und einen gemeinsamen Status (`ReceiptState`), unterscheiden sich aber je Belegart durch eine `*SpecificLogic`-Strategieklasse. | `Centron.Interfaces\Sales.Receipts\ReceiptState.cs`, `Centron.BL\Sales\Receipts\*SpecificLogic.cs` |
|
||||
| **ReceiptState** | Grobstatus eines Belegs: `Active` (offen), `Completed` (abgeschlossen), `Canceled` (storniert). Nicht zu verwechseln mit `IsFixed` (Festschreibung, nur Rechnungen). | `Centron.Interfaces\Sales.Receipts\ReceiptState.cs` |
|
||||
| **Festschreibung (IsFixed)** | Unumkehrbare Fixierung einer Rechnung: Nach Setzen des Flags `IsFixed = 1` auf `RechKopf` sind keine Änderungen mehr möglich. Getrennt vom `ReceiptState`. | `Centron.BL\Sales\Receipts\Invoices\ReceiptInvoiceBL.cs` (`FixInvoice`) |
|
||||
| **C-Sign / WebOffer** | Web-basierter Signatur- und Freigabeprozess, bei dem ein Kunde ein Angebot über einen tokenbasierten Link ohne Login öffnet, signiert (Eingeben/Hochladen/Zeichnen) oder ohne Unterschrift annimmt; die Annahme wandelt das Angebot in einen Auftrag um. | `CentronNexus\Office\SharedDocumentSignPage.razor`, `Centron.BL\Sales\Receipts\ReceiptBL.cs` (`AcceptWebReceipt`) |
|
||||
| **SharedDocument** | Backend-Entität für einen tokenbasierten, zeitlich befristeten Freigabe-/Signaturvorgang eines Dokuments (z. B. C-Sign-Angebot). Trägt Ablaufdatum, Signaturstatus und Historie. | `Centron.BL\Administration\FileManagement\SharedDocumentBL.cs` |
|
||||
| **Helpdesk / Ticket** | Zentrale Supportvorgang-Einheit; verwaltet Status (datengetrieben über `HelpdeskState`, nicht als hartkodiertes Enum), Zuständigkeit, Fälligkeit, Zeiterfassung, Checklisten. | `Centron.BL\Sales\Support\HelpdeskBL.cs`, `CentronRights.md` |
|
||||
| **RMA** | Return Merchandise Authorization; Rücksende-/Reparaturvorgang zu einem Ticket, mit eigenem Artikel-Statusmodell (`RmaArticleState`) und Reparatur-Workflow (`RmaForthAction`). | `Centron.BL\CustomerArea\RmaBL.cs` |
|
||||
| **UserRightsConst** | Zentrale Konstanten-Klasse mit ca. 751 Rechte-IDs, hierarchisch nach Modul/Bildschirm/Aktion organisiert (z. B. `Sales.Customer.Helpdesk.SHOW_HELPDESK`); daneben ältere flache `RIGHT_XXX`-Konstanten. | `Centron.WebServices.Core\EntitiesWrongPlace\Administration\Rights\UserRightsConst.cs` |
|
||||
| **Restricting Right (einschränkendes Recht)** | Ein Recht, das ein bereits vergebenes (umfassenderes) Recht auf eine Teilmenge einschränkt, z. B. „nur eigene Filiale“ zusätzlich zu einem generellen Anzeige-Recht. | `CentronRights.md` |
|
||||
| **Mandator** | Mandant/Firma in einem Mehrmandanten-Betrieb; referenziert über `Branch.MandatorI3D`. | `Centron.Entities\Entities\BranchArea\Branch.cs` |
|
||||
| **I3D** | Primärschlüssel-Namenskonvention (int-Identity) für praktisch alle Entitäten; historisch aus dem Delphi/InterBase-Erbe des Systems. | `Centron.Entities\BaseEntity.cs` |
|
||||
| **WebCart** | Web-Shop-Funktion für Kunden von c-entron-Kunden: Login als Web-Account, Anzeige der für den Kunden hinterlegten „Sonderpreise“-Artikel, Warenkorb/Bestellung. | `README.md`, `CentronNexus\WebCart\*` |
|
||||
| **CustomerPortal** | Übergeordnetes Self-Service-Webportal für Web-Accounts (Kunden), das u. a. WebCart, Ticketansicht, Dokumente und Formulare bündelt. | `CentronNexus\CustomperPortalHomePage.razor` |
|
||||
| **ServiceBoard** | Interner Web-Arbeitsbereich (Nexus) für Support-/Ticketbearbeitung: Kanban, Scheduler, Dashboard, Kundenansicht 360°. | `CentronNexus\ServiceBoard\*` |
|
||||
| **Nexus** | Blazor-basierte Web-Anwendung „c-entron Nexus“ (interner Arbeitsbereich + Kundenportal), containerisiert deploybar. | `src\nexus\CentronNexus*`, `README.md` |
|
||||
| **c-entron.NET** | WPF-Desktop-Client, der Hauptarbeitsoberfläche des ERP für interne Anwender. | `src\centron\Centron.WPF.UI` |
|
||||
| **Web-Service (c-entron Web-Service)** | Backend-Dienst (Windows Service / ASP.NET Core Host), an den sowohl WPF-Client als auch Nexus über REST/SignalR angebunden sind. | `src\webservice\Centron.Host*` |
|
||||
| **Timer Billing** | Abrechnungsfunktion für erfasste (Ticket-)Zeiten; erzeugt Rechnungen/Lieferscheine aus Zeiterfassungen, mit einstellbarem Abrechnungsdatum. | `Centron.WPF.UI\Modules\Finances\TimerBilling\*` |
|
||||
| **EDI** | Electronic Data Interchange; automatisierter Bestell-/Auftragsdatenaustausch mit Distributoren (ALSO, Egis, Komsa, Alltron, ITScope, OpenTrans 2.1). | `Centron.BL\EDI\EDIDispatcherBL.cs` |
|
||||
| **docuFORM (MPS)** | Externe Integration für „Managed Print Services“: Geräteflottenüberwachung (Zähler, Verbrauchsmaterial) und Druckauftragsverwaltung. | `Centron.Api.docuFORM\*` |
|
||||
| **ZUGFeRD / ebInterface / XRechnung** | Elektronische Rechnungsformate (Deutschland/Österreich); ZUGFeRD-Import über eigenen Controller, ebInterface-Export als lokale XML-Erzeugung. | `docs\reference\zugferd-field-mapping.md`, `Centron.Api.EbInterface\EbInterfaceLogic.cs` |
|
||||
| **AppRightsBL** | Zentrale Business-Logic-Klasse zur Rechteprüfung; liest Gruppenrechte aus den (legacy benannten) Tabellen `Sichtrus`/`Sichmemb`, cached pro Benutzer. | `Centron.BL\Administration\Rights\AppRightsBL.cs` |
|
||||
| **Ticket (Auth)** | Zeitlich befristetes, nach erfolgreicher Anmeldung ausgestelltes Session-Artefakt (nicht zu verwechseln mit Helpdesk-„Ticket“); Grundlage des benutzerdefinierten `TicketAuthenticationHandler`-Schemas. | `Centron.BL\Administration\Logins\TicketBL.cs`, `Centron.Host\AspNetCore\TicketAuthenticationHandler.cs` |
|
||||
| **Lizenz (License)** | Feature-Gate über GUID (`LicenseGuids.*`), unabhängig vom Rechtesystem; steuert Verfügbarkeit ganzer Module (z. B. Produktionsmanagement, WebCart2). | `docs\reference\security\licensing-system.md` |
|
||||
| **Distributor / Trade Pool** | Externe Großhändler-/Herstellerkataloge, die per XML-Feed importiert werden; eigenes B2B-Login-Portal für Handelskunden. | `Centron.BL\TradePool\TradePoolBL.cs` |
|
||||
| **OnlineBanking-Abgleich** | Automatischer Import und Zuordnung von Kontoauszugsbuchungen zu offenen Rechnungen/Gutschriften über FinAPI. | `Centron.BL\Finances\OnlineBanking\OnlineBankingAccountTransactionsBL.cs` |
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
# Hypothesen
|
||||
|
||||
Sammlung aller mit `[HYPOTHESE]` markierten Aussagen aus StRS/SyRS/SwRS sowie zusätzlicher, im Rahmen der Recherche aufgefallener offener Punkte, die für eine Validierung durch Fachexperten bzw. für eine Folge-Iteration relevant sind. Jeder Eintrag nennt die betroffene Anforderung, die offene Frage und die fehlende Information zur Bestätigung.
|
||||
|
||||
---
|
||||
|
||||
### H-001 — Durchsetzung der Rechteprüfung im tatsächlichen Schreibpfad für Abrechnungsdaten
|
||||
**Betrifft:** SyRS-018, SwRS-027 (Timer-Billing-Datumsrechte)
|
||||
**Aussage:** Es ist unklar, ob die serverseitig berechneten Flags `CanChangeDateInInvoices`/`CanChangeDateInDeliveryLists` auch im eigentlichen Speicherpfad (nicht nur bei der Anzeige-Berechnung in `ReceiptWebServiceBL`) erneut geprüft werden.
|
||||
**Fehlende Information:** Nachverfolgung des konkreten Save-Aufrufs für Rechnungs-/Lieferschein-Datum bis zur tatsächlichen Persistierung, um zu bestätigen, dass eine Umgehung über einen direkten API-Aufruf (unter Auslassung der UI) nicht möglich ist.
|
||||
|
||||
### H-002 — Serverseitiges Scoping pro Kundenportal-Endpunkt
|
||||
**Betrifft:** SyRS-024 (Isolierung Web-Account-Sitzungen), StRS-022
|
||||
**Aussage:** Es wird angenommen, dass jeder Kundenportal-Endpunkt die Datenabfrage auf den angemeldeten Web-Account beschränkt.
|
||||
**Fehlende Information:** Einzelverifikation der Scoping-Logik in den ~15 identifizierten Kundenportal-Controllern/-Komponenten (`ServiceBoard\Customers\*`, `Office\*`, `WebCart\*`); in dieser Iteration wurde nur das Vorhandensein getrennter Login-Pfade, nicht die serverseitige Datenfilterung jedes einzelnen Endpunkts geprüft.
|
||||
|
||||
### H-003 — Verhalten des Attributs `AuthorizeLicense` bei fehlender Lizenz
|
||||
**Betrifft:** SyRS-025, SwRS-036 (WebCart-Lizenzprüfung)
|
||||
**Aussage:** Es wird angenommen, dass `[AuthorizeLicense(...)]` den Zugriff serverseitig vollständig verweigert (kein Datenleck vor Umleitung).
|
||||
**Fehlende Information:** Quellcode der Attributimplementierung selbst (nicht nur ihre Verwendung) wurde nicht gelesen; Verhalten bei fehlender Lizenz (Redirect/Fehlerseite/Exception, Zeitpunkt der Prüfung im Blazor-Circuit-Lebenszyklus) ist nicht im Detail bestätigt.
|
||||
|
||||
### H-004 — Fehlendes einheitliches Timeout-/Retry-Verhalten bei externen Integrationen
|
||||
**Betrifft:** SyRS-028, SwRS-040 (docuFORM u. a.)
|
||||
**Aussage:** Da kein expliziter `HttpClient.Timeout`-Override und keine Resilience-Bibliothek gefunden wurden, wird angenommen, dass die .NET-Standardwerte (100 s Default-Timeout) greifen und kein automatischer Retry bei transienten Fehlern erfolgt.
|
||||
**Fehlende Information:** Laufzeitverhalten wurde nicht getestet (nur statische Codeanalyse); ein Retry könnte z. B. über eine übergeordnete Aufruferschicht (Scheduler, Hintergrunddienst) realisiert sein, die in dieser Iteration nicht untersucht wurde.
|
||||
|
||||
### H-005 — Transaktionsisolation bei Bestellvorschlagsberechnung
|
||||
**Betrifft:** SyRS-014, SwRS-022 (OrderSuggestionListBL)
|
||||
**Aussage:** Es ist unklar, unter welcher Transaktionsisolationsstufe die ca. 10 Einzel-SQL-Abfragen ausgeführt werden und ob sie einen konsistenten Datenstand (gleicher Zeitpunkt) garantieren oder bei hoher Nebenläufigkeit inkonsistente Zwischenstände liefern können.
|
||||
**Fehlende Information:** NHibernate-/`RawSqlAccess`-Konfiguration der Transaktionsisolationsstufe wurde nicht recherchiert.
|
||||
|
||||
### H-006 — Bestätigungsmöglichkeit für erkannte Duplikat-Transaktionsimporte
|
||||
**Betrifft:** SwRS-024 (OnlineBanking-Duplikatserkennung)
|
||||
**Aussage:** Die Duplikatsprüfung liefert laut Code eine Warnung, keinen Hard-Block; unklar ist, ob der Anwender den Import trotz Warnung bestätigen und damit eine Rechnung doppelt verbuchen kann.
|
||||
**Fehlende Information:** UI-seitiger Umgang mit der Warnmeldung (WPF-ViewModel-Ebene) wurde nicht zurückverfolgt.
|
||||
|
||||
### H-007 — Verhältnis zweier augenscheinlich überlappender 2FA-Implementierungen
|
||||
**Betrifft:** StRS-020, SwRS-033
|
||||
**Aussage:** Im Code existieren zwei separate Namespaces für Zwei-Faktor-Authentifizierung: `Centron.BL\Administration\Logins\TwoFactor\TwoFactorAuthBL.cs` und `Centron.BL\TwoFactorAuthenticator\TwoFactorAuthenticationBL.cs`. Unklar ist, ob es sich um (a) eine historische Migration mit totem Altcode, (b) zwei unterschiedliche Anwendungsfälle (z. B. Mitarbeiter- vs. Kunden-2FA) oder (c) eine unbeabsichtigte Duplikation handelt.
|
||||
**Fehlende Information:** Aufrufer beider Klassen wurden nicht vollständig ermittelt; Klärung durch Fachexperten/Entwicklerteam erforderlich.
|
||||
|
||||
### H-008 — Umfang der Rechteprüfung in `*SpecificLogic`-Klassen der Belegverarbeitung
|
||||
**Betrifft:** StRS-018, SyRS-019 (Rechtesystem, allgemein)
|
||||
**Aussage:** Bei der Sicherheitsrecherche wurde festgestellt, dass mindestens eine `*SpecificLogic`-Methode (`SupplierOrderSpecificLogic.HasRightToEditReceipt`, Zeile ~685) unbedingt `return true;` liefert, statt ein tatsächliches Recht zu prüfen — im Gegensatz zum sonst konsistent durchgesetzten Muster. Es ist unklar, ob dies eine bewusste Design-Entscheidung (z. B. weil das Recht an anderer Stelle bereits geprüft wurde) oder eine Sicherheitslücke ist.
|
||||
**Fehlende Information:** Vollständige Durchsicht aller 13 `*SpecificLogic.cs`-Dateien unter `Sales\Receipts\` auf weitere hartkodierte `true`/`false`-Rückgaben; Abgleich mit vorgelagerten Prüfpunkten in `ReceiptBL`.
|
||||
|
||||
### H-009 — Fehlende strukturierte Audit-Protokollierung für Login-Ereignisse und Rechteänderungen
|
||||
**Betrifft:** StRS-018, StRS-019 (Rechtesystem, Authentifizierung)
|
||||
**Aussage:** Außer den Passwort-Tresor-Zugriffsprotokollen (`PasswordManagementAccessLogBL`) und unstrukturierten NLog-Einträgen wurde keine dedizierte, abfragbare Tabelle für Login-Historie oder Änderungen an Rechtegruppen (`AppRightsBL.AddRightToRightGroup`) gefunden. Angesichts des vorhandenen `DsgvoModule`-Rechte-Namensraums ist unklar, ob dies für Compliance-Zwecke (DSGVO/GoBD) ausreicht.
|
||||
**Fehlende Information:** Vollständigere Suche nach Audit-/Protokolltabellen außerhalb der in dieser Iteration durchsuchten Muster (`LoginLog`, `AuditLog`, `AuditTrail`, `Protokoll`); Rückfrage beim Entwicklungs-/Compliance-Team.
|
||||
|
||||
### H-010 — Client-seitiges Rechte-Caching im WPF-Client als Defense-in-Depth-Lücke
|
||||
**Betrifft:** StRS-018, SwRS-028
|
||||
**Aussage:** `FrontWindowViewModel.HasCurrentUserRight` prüft gegen eine beim Login einmalig geladene, clientseitig gecachte Rechteliste (`CentronCache.Instance.CurrentUserAppRights`), die während der Sitzung nicht erneut serverseitig abgeglichen wird. Wird einem Benutzer während einer laufenden Sitzung ein Recht entzogen, bleibt die UI ggf. bis zum nächsten Login inkonsistent — sofern die entsprechende BL-Methode nicht selbst nochmals serverseitig prüft.
|
||||
**Fehlende Information:** Für jede WPF-UI-Aktion, die nur clientseitig geprüft wird, müsste bestätigt werden, dass die zugehörige BL-Methode dieselbe Prüfung serverseitig wiederholt (wie es z. B. bei `HelpdeskBL.CheckUserRigths` der Fall ist) — dies wurde nicht für alle WPF-Module systematisch verifiziert.
|
||||
|
||||
### H-011 — Umgang mit historisch eingebetteten Klartext-Zugangsdaten in `app.config`
|
||||
**Betrifft:** SyRS-027 (Konfigurationsmanagement/Deployment), allgemeine Sicherheitsbewertung
|
||||
**Aussage:** `src\webservice\Centron.Host.Console\app.config` enthält ein aktives Klartext-SQL-Passwort sowie mehrere auskommentierte historische Zugangsdatensätze. Unklar ist, ob dies ausschließlich für lokale Entwicklungsumgebungen ohne Produktionsbezug verwendet wird (dann geringes Risiko) oder ob vergleichbare Muster auch in produktiv genutzten Konfigurationspfaden vorkommen.
|
||||
**Fehlende Information:** Abgleich mit tatsächlichen Produktions-Deployment-Konfigurationen (liegen ggf. außerhalb des Repositories, z. B. in einem Secrets-Management-System) — in dieser Iteration nicht einsehbar.
|
||||
|
||||
### H-012 — Sum-Null-Schutz bei Rechnungsfestschreibung
|
||||
**Betrifft:** StRS-003, SwRS-007
|
||||
**Aussage:** Es wurde keine explizite Prüfung gefunden, die eine Rechnung mit Summe null gegen Festschreibung sperrt (nur eine mögliche UI-Warnung, kein bestätigter BL-/DB-Guard).
|
||||
**Fehlende Information:** Vollständige Durchsicht von `ReceiptInvoiceBL.FixInvoice` auf weitere, in dieser Iteration nicht zitierte Vorbedingungen sowie Prüfung der UI-Schicht (WPF/Nexus) auf eine entsprechende Warnung.
|
||||
|
||||
---
|
||||
|
||||
## Hinweis zu nicht verifizierbaren Prozessartefakten
|
||||
|
||||
Der Analyseauftrag verlangt auch die Auswertung von Commit-Messages, Tickets und Release Notes. Ticket-Nummern (z. B. „Ticket 168496“, „Ticket 150766“) konnten über Git-Commit-Titel referenziert werden (`git log`-Kurzhistorie), eine inhaltliche Verknüpfung einzelner Codeänderungen zu genauen Commit-SHAs über `git log --grep` war im Rahmen einzelner Rechercheagenten technisch nicht möglich (interaktive Bestätigung erforderlich, im Sandbox-Kontext nicht verfügbar). Wo Ticketnummern in dieser Spezifikation auftauchen, stammen sie entweder aus Commit-Titeln (Kontext-Beleg) oder aus Code-Kommentaren, die die jeweilige Ticketnummer selbst referenzieren (z. B. „Ticket 161840“ in `TimerBillingSettingsDTO.cs`) — nicht aus einer verifizierten Commit-zu-Code-Zuordnung.
|
||||
+559
@@ -0,0 +1,559 @@
|
||||
# Stakeholder Requirements Specification (StRS)
|
||||
|
||||
Reverse-engineert aus der c-entron-ERP-Codebasis. Ebene: fachliche Sicht, Akteure, Geschäftsziele. Format je Anforderung siehe Vorgabe im Auftrag. Alle Belege sind Datei-/Codereferenzen aus `C:\DEV\MasterArbeit\QuellCode\CentronERP` (Pfade relativ dazu angegeben).
|
||||
|
||||
---
|
||||
|
||||
## Block A — Order-to-Cash / Belegkette (Angebot–Auftrag–Lieferschein–Rechnung)
|
||||
|
||||
```
|
||||
ID: StRS-001
|
||||
Titel: Durchgängige Belegkette Angebot–Auftrag–Lieferschein–Rechnung
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Vertriebsmitarbeiter
|
||||
Vorbedingung: Kundendaten und mind. ein Artikel sind erfasst.
|
||||
Fakt: Alle Belegarten (Offer, Order, DeliveryList, Invoice, CreditVoucher, PickupList, ContractList) implementieren dieselbe abstrakte Basis `CustomerAssetExtended<T>` und werden über eine gemeinsame Engine (`ReceiptBL`) verarbeitet; die belegartspezifischen Regeln stecken in austauschbaren `*SpecificLogic`-Klassen (Strategy-Pattern), die das Interface `IReceiptSpecificLogic` implementieren.
|
||||
Aussage: Das System soll Angebote, Aufträge, Lieferscheine und Rechnungen als eine zusammenhängende, weiterverarbeitbare Belegkette abbilden, sodass ein Beleg aus einem vorangehenden Beleg abgeleitet ("weitergeführt") werden kann, ohne Daten erneut erfassen zu müssen.
|
||||
Ergebnis: Ein Folgebeleg (z. B. Auftrag aus Angebot) übernimmt Kunden-, Positions- und Preisdaten des Vorgängerbelegs.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.Entities\Entities\Sales\CustomerAssets\ - Begründung: gemeinsame Basisklasse `CustomerAssetExtended<T>` zeigt, dass alle Belegarten strukturell als eine Familie behandelt werden.
|
||||
- [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs - Begründung: zentrale Verarbeitungslogik für alle Belegarten (u. a. `AcceptWebReceipt`, Weiterführungslogik).
|
||||
- [SEKUNDÄR] src\backend\Centron.BL\Sales\Receipts\Offers\OfferSpecificLogic.cs, Orders\OrderSpecificLogic.cs, Invoices\InvoiceSpecificLogic.cs - Begründung: belegartspezifische Ausprägung derselben Kette, belegt Wiederverwendung eines gemeinsamen Mechanismus.
|
||||
Prüfidee: Ein Angebot mit n Positionen wird zu einem Auftrag weitergeführt; Kunde und Positionsdaten müssen identisch übernommen werden (Stichprobe über UI oder Integrationstest).
|
||||
Tracelinks: SyRS-001, SyRS-002
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-002
|
||||
Titel: Digitale Angebotsannahme per C-Sign (WebOffer)
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Kunde (ohne Login, tokenbasiert)
|
||||
Vorbedingung: Ein Angebot wurde als Web-Angebot freigegeben; ein Signaturvorgang (`SharedDocument`) wurde erzeugt.
|
||||
Fakt: `ReceiptBL.AcceptWebReceipt` erzeugt über `SharedDocumentBL.GenerateTokenForDocument` einen Signier-Token und setzt `WebReceiptState = WebOfferSign`; die Blazor-Seite `SharedDocumentSignPage.razor` bietet dem Kunden drei Signaturmodi (Eingeben/Hochladen/Zeichnen) und ruft `SignSharedDocument` auf; bei Angebotsdokumenten wird der Button "Kostenpflichtig bestellen" angezeigt.
|
||||
Aussage: Das System soll es Kunden ermöglichen, ein Angebot ohne Benutzerkonto über einen personalisierten, zeitlich befristeten Link online zu signieren oder ohne Unterschrift anzunehmen, wodurch das Angebot in einen kostenpflichtigen Auftrag überführt wird.
|
||||
Ergebnis: Nach erfolgreicher Signatur/Annahme wechselt der Beleg in den Zustand `WebOfferSign`/`WebOfferSignedWithoutSignature`; ein Folgeauftrag kann erzeugt werden.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs (Methoden AcceptWebReceipt, AcceptWebReceiptWithoutSignature) - Begründung: enthält die durchgesetzte Zustandsänderung und ist keine reine UI-Beschriftung.
|
||||
- [PRIMÄR] src\backend\Centron.Interfaces\Sales.Receipts\WebReceipt\WebReceiptState.cs - Begründung: definiert die tatsächlich im Code verwendeten Zustandswerte WebOfferSign/WebOfferSignedWithoutSignature.
|
||||
- [SEKUNDÄR] src\nexus\CentronNexus\Office\SharedDocumentSignPage.razor - Begründung: UI-Ausprägung des Vorgangs, zeigt Signaturmodi und den Beschriftungswechsel auf "Kostenpflichtig bestellen".
|
||||
Prüfidee: Signaturprozess mit gültigem Token durchlaufen; danach Prüfen, dass `WebReceiptState` gesetzt ist und ein erneuter Aufruf desselben Tokens als "bereits signiert" abgelehnt wird.
|
||||
Tracelinks: SyRS-003, SyRS-004
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-003
|
||||
Titel: Unveränderlichkeit festgeschriebener Rechnungen
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Finanzbuchhaltung
|
||||
Vorbedingung: Eine Rechnung existiert und ist noch nicht festgeschrieben (`IsFixed = 0`).
|
||||
Fakt: `ReceiptInvoiceBL.FixInvoice` prüft über `CheckIfInvoiceIsFixed`, ob die Rechnung bereits festgeschrieben ist, und bricht in diesem Fall mit Fehlermeldung ab; bei Erfolg wird `RechKopf.IsFixed` per SQL auf 1 gesetzt (Spalte `NOT NULL DEFAULT(0)`, migriert über Skript `CreateIsFixedColumnInRechKopfTable`) und ein unveränderlicher Protokolleintrag (`ReceiptLogKind.FixedState`) geschrieben.
|
||||
Aussage: Das System soll eine Rechnung nach ihrer Festschreibung dauerhaft vor inhaltlichen Änderungen schützen und diesen Vorgang nachvollziehbar protokollieren, um die Anforderungen ordnungsgemäßer Buchführung (Unveränderlichkeit gebuchter Belege) zu erfüllen.
|
||||
Ergebnis: Rechnung ist nach Festschreibung nicht mehr editierbar; Protokolleintrag mit Zeitstempel und Benutzer ist vorhanden.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\ReceiptInvoiceBL.cs (FixInvoice, CheckIfInvoiceIsFixed) - Begründung: durchgesetzte Zustandsprüfung und -änderung im Code, nicht nur UI-Hinweis.
|
||||
- [PRIMÄR] src\backend\Centron.BL\Administration\Scripts\ScriptMethods\SqlStatements\SQLScriptCollection2.xml (Skript CreateIsFixedColumnInRechKopfTable, #10208) - Begründung: DB-Constraint `NOT NULL DEFAULT(0)` auf `RechKopf.IsFixed` — technischer Durchsetzungsmechanismus auf Datenbankebene.
|
||||
- [SEKUNDÄR] src\backend\Centron.DAO\Mappings\...\ReceiptInvoiceBaseMaps.cs (Zeile ~175, Not.Nullable() auf IsFixed) - Begründung: bestätigt Pflichtfeld-Mapping in der ORM-Schicht.
|
||||
Prüfidee: Rechnung festschreiben, danach Änderungsversuch an Position/Kopf durchführen → muss abgelehnt werden; erneutes Festschreiben → muss abgelehnt werden ("Die Rechnung ist festgeschrieben...").
|
||||
Tracelinks: SyRS-005
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-004
|
||||
Titel: Automatische Umsatzsteuerberechnung auf Belegen
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Ein Beleg mit Nettobetrag und gültigem Steuersatz liegt vor.
|
||||
Fakt: `CalculationUtils.CalculateTaxTotalPrice`/`CalculateGrossPrice` berechnen Steuerbetrag bzw. Bruttopreis aus Netto- und Steuersatzangaben (kaufmännisch gerundet, `MidpointRounding.AwayFromZero`); `InvoiceSpecificLogic.GetDateTimeForVATCalculation` legt das für die Steuersatzermittlung maßgebliche Datum fest (Belegdatum), `TakeoverVATWhenForwarding` steuert, ob beim Weiterführen (z. B. Auftrag→Rechnung) die USt neu berechnet oder übernommen wird.
|
||||
Aussage: Das System soll die Umsatzsteuer für jeden Beleg automatisch und nach einer für alle Belegarten einheitlichen Regel berechnen, wobei bei der Weiterführung von Belegen konfigurierbar ist, ob der ursprüngliche Steuersatz übernommen oder neu berechnet wird.
|
||||
Ergebnis: Steuerbetrag und Bruttopreis sind für jede Belegposition konsistent zur zentralen Berechnungslogik.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.Interfaces\DataExchange.BookKeeping\CalculationUtils.cs - Begründung: zentrale, für alle Belegarten wiederverwendete Berechnungsfunktion.
|
||||
- [SEKUNDÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\InvoiceSpecificLogic.cs (GetDateTimeForVATCalculation, TakeoverVATWhenForwarding) - Begründung: belegt fachliche Sonderregel bei Belegübergängen, ergänzt aber die Kernberechnung nur.
|
||||
Prüfidee: Für Netto=100, Steuersatz=19 → Steuerbetrag=19.00, Brutto=119.00 (kaufmännisch gerundet); Test mit Rabatt und Fremdwährungsfaktor.
|
||||
Tracelinks: SyRS-006
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-005
|
||||
Titel: Automatisches Öffnen/Schließen von Belegen nach Restmenge
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Ein Beleg mit Positionen und gebuchten Teilmengen existiert.
|
||||
Fakt: `AutomaticallyCloseReceiptHelperBL` (Methoden `TryAutomaticallyCloseReceipt`/`TryAutomaticallyOpenReceipt`) steuert den Übergang zwischen `ReceiptState.Active` und `ReceiptState.Completed` automatisiert anhand verbleibender Restmengen.
|
||||
Aussage: Das System soll einen Beleg automatisch als abgeschlossen markieren, sobald alle Positionen vollständig weiterverarbeitet (z. B. geliefert/fakturiert) sind, und ihn bei nachträglicher Änderung wieder öffnen können.
|
||||
Ergebnis: `ReceiptState` wechselt ohne manuellen Eingriff korrekt zwischen Active und Completed.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Internal\AutomaticallyCloseReceiptHelperBL.cs - Begründung: enthält die tatsächliche Zustandsübergangslogik.
|
||||
- [SEKUNDÄR] src\backend\Centron.Interfaces\Sales.Receipts\ReceiptState.cs - Begründung: definiert die beteiligten Zustandswerte (Active=1, Completed=2, Canceled=3).
|
||||
Prüfidee: Beleg mit 2 Positionen anlegen, eine Position vollständig weiterverarbeiten (Beleg bleibt Active), zweite Position vollständig weiterverarbeiten (Beleg wechselt zu Completed).
|
||||
Tracelinks: SyRS-001, SyRS-002
|
||||
Konsolidierung: Kandidat: StRS-001 (Teil derselben Belegketten-Logik)
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Block B — Helpdesk / Support / RMA
|
||||
|
||||
```
|
||||
ID: StRS-006
|
||||
Titel: Ticket-basierte Kundenservice-Bearbeitung (Helpdesk)
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Support-Mitarbeiter
|
||||
Vorbedingung: Ein Kunde und ein Anliegen liegen vor.
|
||||
Fakt: `HelpdeskBL` (1043 Zeilen) implementiert CRUD, Pflichtfeldprüfung (`DoValidateMandatoryFields`), Textfeldlängenprüfung und eine mandatorische Rechteprüfung vor jedem Speichervorgang (`CheckUserRigths`); der Ticketstatus ist datengetrieben über die Entität `HelpdeskState` (kein hartkodiertes Enum), Standard-/Abschluss-Zustände stammen aus `AppSettingsBL`.
|
||||
Aussage: Das System soll Kundenanliegen als Tickets mit konfigurierbarem Status, Zuständigkeit, Fälligkeit und Zeiterfassung verwalten und dabei alle Änderungen an eine Rechteprüfung koppeln.
|
||||
Ergebnis: Ticket ist angelegt, hat einen gültigen Status aus der konfigurierten Statusliste und eine dokumentierte Historie.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs (Save/DoBeforeSave, Zeilen ~298-326) - Begründung: durchgesetzte Validierung im Speicherpfad.
|
||||
- [SEKUNDÄR] CentronRights.md (Abschnitt Helpdesk) - Begründung: fachliche Beschreibung der zugehörigen Rechte durch das Entwicklerteam selbst.
|
||||
Prüfidee: Ticket ohne Pflichtfeld anlegen → muss abgelehnt werden; Ticket mit allen Pflichtfeldern anlegen → muss erfolgreich sein und Historieneintrag erzeugen.
|
||||
Tracelinks: SyRS-007, SyRS-008
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-007
|
||||
Titel: Rollenbasierte Sichtbarkeits- und Zuständigkeitssteuerung von Tickets
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Support-Mitarbeiter
|
||||
Vorbedingung: Benutzer ist angemeldet und einer Abteilung/Filiale zugeordnet.
|
||||
Fakt: `HelpdeskBL.CheckUserRigths` (Zeilen ~410-466) wertet u. a. `SHOW_HELPDESK_ONLY_OWN`, `SHOW_HELPDESK_ONLY_OWN_BRANCH` und `ASSIGN_HELPDESK_ONLY_TO_OWN_DEPARTMENTS` aus und schränkt Sichtbarkeit bzw. zulässige Zuweisungsziele (`ResponsiblePerson`) entsprechend ein; `CentronRights.md` beschreibt dieselben Rechte explizit als "restricting rights".
|
||||
Aussage: Das System soll es erlauben, den Zugriff auf Tickets granular auf "nur eigene", "nur eigene Filiale" oder "nur eigene Abteilung" einzuschränken, unabhängig vom allgemeinen Anzeige-/Bearbeitungsrecht.
|
||||
Ergebnis: Ein Benutzer mit einschränkendem Recht sieht/bearbeitet ausschließlich die für ihn zulässige Teilmenge an Tickets.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs (CheckUserRigths, GetLoggedInUserShowHelpdeskRight) - Begründung: durchgesetzte Filterlogik im Code.
|
||||
- [KONTEXT] CentronRights.md, Abschnitte 1.1/1.2/4 - Begründung: fachliche Definition durch das Entwicklerteam, bestätigt Intention der einschränkenden Rechte.
|
||||
Prüfidee: Benutzer mit `SHOW_HELPDESK_ONLY_OWN_BRANCH` darf Ticket anderer Filiale nicht in der Liste sehen (Integrationstest mit zwei Filialen).
|
||||
Tracelinks: SyRS-008
|
||||
Konsolidierung: Kandidat: StRS-018 (allgemeines Rechtesystem, hier domänenspezifische Ausprägung)
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-008
|
||||
Titel: RMA-Rücksende- und Reparaturabwicklung
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Support-Mitarbeiter
|
||||
Vorbedingung: Ein Helpdesk-Ticket existiert, zu dem ein RMA-Vorgang angelegt werden soll.
|
||||
Fakt: `RmaBL.SaveRma` (2084 Zeilen Gesamtdatei) erzwingt über `ResultException("Rma not coneccted to helpdesk", ...)`, dass ein RMA-Vorgang zwingend mit einem Ticket verknüpft ist (`rma.HelpdeskI3D <= 0` → Fehler); Artikelzustände durchlaufen ein feingranulares Enum `RmaArticleState` (Open, SendForth, SendBack, Invoice, Scapped, Rebooked, ...) und ein Reparatur-Workflow-Enum `RmaForthAction` (Repair, UnRepair, EqualChange, ForeignChange, Scapped, ...).
|
||||
Aussage: Das System soll Rücksendungen und Reparaturen (RMA) ausschließlich im Kontext eines Helpdesk-Tickets zulassen und den Bearbeitungsfortschritt über ein definiertes Artikel-Zustandsmodell inklusive Lagerrückbuchung nachvollziehbar abbilden.
|
||||
Ergebnis: RMA-Vorgang ist mit Ticket verknüpft; Artikel durchläuft dokumentierte Zustände bis Abschluss (z. B. Rebooked/Invoice/Scapped).
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\CustomerArea\RmaBL.cs (SaveRma, Zeilen 347-521) - Begründung: durchgesetzte Verknüpfungsprüfung und Zustandsübergänge im Code.
|
||||
Prüfidee: RMA ohne HelpdeskI3D anlegen → muss mit DependencyCheckFailed-Fehler abgelehnt werden.
|
||||
Tracelinks: SyRS-009
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-009
|
||||
Titel: Automatisierte Ticketerzeugung über Aufgabenplaner
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: System (geplante Aufgabe)
|
||||
Vorbedingung: Eine wiederkehrende Aufgabe (Tages-/Wochen-/Monats-/Jahresrhythmus) ist konfiguriert.
|
||||
Fakt: `TaskManagementTaskBL.ExecuteTask` wertet Wiederholungsregeln aus (интern über DevExpress `OccurrenceCalculator`) und führt bei Fälligkeit eine pluggable Aktion aus (`TaskManagementHelpdeskActionHandler` erzeugt automatisch ein Ticket, gesichert durch das Recht `ADD_NEW_HELPDESK`); ein verteilter DB-Lock (`sp_getapplock`) verhindert Doppelausführung bei parallelen Prozessen.
|
||||
Aussage: Das System soll wiederkehrende Aufgaben (z. B. regelmäßige Wartungstickets) automatisiert und ohne Doppelausführung ausführen und dabei dieselben Rechteprüfungen anwenden wie eine manuelle Ticketerstellung.
|
||||
Ergebnis: Zur Fälligkeit wird genau ein Ticket erzeugt; Status der Aufgabe (`ProjectStatus`: Started/Paused/Finished) steuert, ob weiter ausgeführt wird.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\TaskManager\TaskManagementTaskBL.cs (ExecuteTask, sp_getapplock-Aufruf) - Begründung: technisch durchgesetzter Sperrmechanismus gegen Doppelausführung.
|
||||
- [SEKUNDÄR] src\backend\Centron.BL\TaskManager\ActionHandler\TaskManagementHelpdeskActionHandler.cs (Zeile 57) - Begründung: zeigt Wiederverwendung der Helpdesk-Rechteprüfung bei automatisierter Erstellung.
|
||||
Prüfidee: Zwei parallele Ausführungsversuche derselben fälligen Aufgabe → nur ein Ticket darf entstehen.
|
||||
Tracelinks: SyRS-007, SyRS-010
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Block C — Warehousing / Purchasing
|
||||
|
||||
```
|
||||
ID: StRS-010
|
||||
Titel: Zentrale Artikelstammdatenverwaltung mit Preis- und Rechteschutz
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Lagermitarbeiter / Einkauf
|
||||
Vorbedingung: Artikel existiert oder wird neu angelegt.
|
||||
Fakt: `ArticleBL.CheckUserRightBeforeSave` (Zeilen ~991-1055) blockiert Preisänderungen ohne Recht `CHANGE_ARTICLE_PRICE`, Änderungen der Barcode-Pflicht ohne `CHANGE_SERIALNUMBER_REQUIRED_FLAG` und erkennt konkurrierende Änderungen ("ChangedByOtherInstance"); `CheckSpecialUserRightBeforeSave` (Zeilen ~1058-1089) setzt bestimmte Felder (Warengruppe u. a.) stillschweigend auf den ursprünglichen DB-Wert zurück, wenn dem Benutzer das entsprechende Recht fehlt oder er `NOT_CHANGEABLE_ARTICLE_PROPERTIES` besitzt.
|
||||
Aussage: Das System soll Änderungen an sicherheits- und preisrelevanten Artikeleigenschaften nur berechtigten Benutzern erlauben und nicht berechtigte Änderungen automatisch verwerfen statt sie stillschweigend zu übernehmen.
|
||||
Ergebnis: Preis-/Sicherheitsfelder bleiben unverändert, wenn der speichernde Benutzer nicht berechtigt ist; entsprechende Felder werden auf DB-Stand zurückgesetzt.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Warehousing\ArticleBL.cs (CheckUserRightBeforeSave, CheckSpecialUserRightBeforeSave) - Begründung: durchgesetzte serverseitige Prüfung, kein reiner UI-Schutz.
|
||||
Prüfidee: Benutzer ohne `CHANGE_ARTICLE_PRICE` versucht Preisänderung zu speichern → Preis bleibt auf altem DB-Wert.
|
||||
Tracelinks: SyRS-011
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-011
|
||||
Titel: Physische Inventur mit Bestandsabgleich
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Lagermitarbeiter
|
||||
Vorbedingung: Eine Inventur (`Inventory`) wurde angelegt und erwartete Artikelmengen sind bekannt.
|
||||
Fakt: `InventoryBL` verwendet die Zustände `InventoryState` (Open, OpenWithoutBC, Deleted) sowie einen berechneten `CloseState` (Counted, Ok, Risk, problem) pro Inventurposition, ermittelt aus gezählter vs. erwarteter Menge und Barcode-Zustandskonflikten; `DeleteInventory` erlaubt Löschen/Wiederherstellen nur mit Recht `DROP_INVENTORY`.
|
||||
Aussage: Das System soll den Abschluss einer Inventur nur zulassen, wenn Zähl- und Sollmengen abgeglichen sind, Abweichungen (Risk/problem) sichtbar kennzeichnen und das Löschen einer Inventur an ein eigenes Recht koppeln.
|
||||
Ergebnis: Inventurpositionen sind mit korrektem `CloseState` markiert; gelöschte Inventuren sind wiederherstellbar (Statuswechsel Deleted→Open), sofern berechtigt.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Warehousing\InventoryManagement\InventoryBL.cs (DeleteInventory Zeilen 98-109, CloseState-Berechnung Zeilen ~694-750) - Begründung: durchgesetzte Statuslogik und Rechteprüfung im Code.
|
||||
- [KONTEXT] src\backend\Centron.BL\Storage\StorageBL.cs (vollständig auskommentiert, Kommentar "SKA 2014-07-17: Obsolete... Replaced with InventoryBL") - Begründung: dokumentiert Historie/Ablösung einer Altimplementierung, keine aktive Regel mehr.
|
||||
Prüfidee: Inventurposition mit abweichender Zählmenge anlegen → `CloseState` muss "Risk" oder "problem" ergeben, nicht "Ok".
|
||||
Tracelinks: SyRS-012
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-012
|
||||
Titel: Auftragskommissionierung (Picking)
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Lagermitarbeiter
|
||||
Vorbedingung: Ein Auftrag mit lagerpflichtigen Positionen liegt vor.
|
||||
Fakt: `OrderCommissionBL`/`PartialCommissionOrderBL` steuern Kommissioniervorgänge inkl. Barcodegenerierung, geschützt durch Rechte `CREATE_PARTIAL_COMMISSION_FOR_ORDER`, `DELETE_PARTIAL_COMMISSION_FOR_ORDER`, `Logistic.Commissioning.ID`, `GENERATE_BARCODES`.
|
||||
Aussage: Das System soll die (Teil-)Kommissionierung eines Auftrags rechtegeschützt ermöglichen und dabei Barcodes für die kommissionierten Artikel bereitstellen.
|
||||
Ergebnis: Kommissionierte Positionen sind als (teil-)kommissioniert markiert; nicht berechtigte Benutzer können keine Teilkommissionierung anlegen/löschen.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Warehousing\Commissions\PartialCommissionOrderBL.cs (Zeilen 135, 170, 426, 453) - Begründung: durchgesetzte Rechteprüfung vor Kommissionsänderung.
|
||||
- [SEKUNDÄR] src\backend\Centron.BL\Warehousing\Commissions\OrderCommissionBL.cs (Zeilen 431, 438) - Begründung: ergänzende Rechteprüfung für Barcodegenerierung.
|
||||
Prüfidee: Benutzer ohne `CREATE_PARTIAL_COMMISSION_FOR_ORDER` versucht Teilkommission anzulegen → Ablehnung.
|
||||
Tracelinks: SyRS-013
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-013
|
||||
Titel: Automatisierte Bestellvorschlagsermittlung
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Einkauf
|
||||
Vorbedingung: Mindestbestände, offene Aufträge und offene Bestellungen sind im System erfasst.
|
||||
Fakt: `OrderSuggestionListBL` (~1145 Zeilen) kombiniert über ca. 10 umfangreiche Roh-SQL-Statements (`_sqlArticle`, `_sqlOrder`, `_sqlWH`, u. a., ausgeführt via `RawSqlAccess.ExecuteQuery<T>`) Lagerbestand, Mindestbestandseinstellungen, offenen Auftragsbedarf und offenen Bestellbestand zu einer Vorschlagsliste je Artikel/Lager.
|
||||
Aussage: Das System soll dem Einkauf automatisiert eine Liste nachzubestellender Artikel auf Basis von Mindestbestand, offenem Bedarf und offenem Zulauf vorschlagen.
|
||||
Ergebnis: Bestellvorschlagsliste enthält je Artikel die rechnerisch benötigte Nachbestellmenge.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Purchasing\OrderSuggestionList\OrderSuggestionListBL.cs - Begründung: enthält die tatsächliche, technisch durchgesetzte Berechnungslogik (SQL-Aggregation über mehrere Legacy-Tabellen).
|
||||
Prüfidee: Artikel mit Mindestbestand 10, aktuellem Bestand 3, offenem Auftragsbedarf 5 → Vorschlagsmenge muss ≥ 12 ergeben (rechnerische Nachvollziehung, exakte Formel im Quellcode zu verifizieren).
|
||||
Tracelinks: SyRS-014
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround (starke Abhängigkeit von Legacy-DB-Ansichten/-Tabellen: AufPos, AufKopf, BestPos2, BestKopf2, Artik)
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-014
|
||||
Titel: EDI-Anbindung an Distributoren für Bestelldatenaustausch
|
||||
Ebene: StRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: System (automatisierter Bestellprozess)
|
||||
Vorbedingung: Ein Bestellvorschlag existiert und eine EDI-Konfiguration für den Distributor ist hinterlegt.
|
||||
Fakt: `EDIDispatcherBL.CreateEDISuggestionOrderAsync` wählt anhand `EDIMultidistributors`/`EdiDataType` einen distributorspezifischen Dokumentenersteller aus (u. a. ALSO, EGIS, Komsa, Alltron, ITScope, OpenTrans 2.1).
|
||||
Aussage: Das System soll Bestellungen automatisiert im jeweils vom Distributor geforderten elektronischen Format erzeugen und übermitteln können, ohne dass der Anwender das Format manuell wählen muss.
|
||||
Ergebnis: Für einen gewählten Distributor wird automatisch das korrekte EDI-Dokumentformat erzeugt.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\EDI\EDIDispatcherBL.cs (Zeilen 56-70) - Begründung: enthält die Dispatch-Entscheidung basierend auf Konfigurationsdaten.
|
||||
- [KONTEXT] docs\reference\edi\edi-architecture.md - Begründung: vom Entwicklerteam verfasste Architekturbeschreibung, keine erzwungene Regel, aber Bestätigung der Absicht.
|
||||
Prüfidee: EDI-Konfiguration mit Distributor "EGIS" → erzeugtes Dokument muss dem EGIS-spezifischen Format entsprechen (Format-Validierung).
|
||||
Tracelinks: SyRS-015
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Block D — Finances / Zahlungen
|
||||
|
||||
```
|
||||
ID: StRS-015
|
||||
Titel: Automatischer Zahlungsabgleich über Online-Banking-Integration
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Finanzbuchhaltung
|
||||
Vorbedingung: Bankkontoverbindung über FinAPI ist konfiguriert; Rechnungen mit offenem Betrag liegen vor.
|
||||
Fakt: `OnlineBankingAccountTransactionsBL` importiert Kontoumsätze und ordnet sie heuristisch Kunden/Rechnungen zu (`AutoCompleteSingleAccountTransaciton`); `BookAmountToAssignedInvoice` (Zeilen ~1042-1086) verbucht nur, wenn die Rechnung `Active` ist (oder `Completed` beim Rückgängigmachen, oder der Betrag negativ ist/Rückbuchung) und markiert die Rechnung als bezahlt, sobald `PaidFC >= DemandedGrossAmount`; `SaveOnlineBankingAccountTransactions` (Zeilen ~294-340) weist doppelte Transaktionen (gleiche Kombination aus Konfiguration/Datum/Betrag/IBAN/Beschreibung) mit einer Warnung zurück.
|
||||
Aussage: Das System soll importierte Bankumsätze automatisiert offenen Rechnungen zuordnen, doppelte Importe erkennen und den Zahlstatus einer Rechnung korrekt aktualisieren.
|
||||
Ergebnis: Rechnung ist nach vollständigem Zahlungseingang als bezahlt markiert; doppelte Transaktionsimporte werden abgewiesen.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Finances\OnlineBanking\OnlineBankingAccountTransactionsBL.cs (BookAmountToAssignedInvoice, SaveOnlineBankingAccountTransactions) - Begründung: durchgesetzte Buchungs- und Duplikatsprüfungslogik, hohe fachliche Kritikalität (Zahlungsverkehr) → PRIMÄR-Beleg erforderlich und vorhanden.
|
||||
Prüfidee: Zwei identische Transaktionsimporte (gleiche IBAN/Datum/Betrag/Beschreibung) → zweiter Import muss als Duplikat markiert werden, nicht doppelt verbucht werden.
|
||||
Tracelinks: SyRS-016, SyRS-017
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-016
|
||||
Titel: Manuelle Zahlungserfassung mit Rechteschutz
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Finanzbuchhaltung
|
||||
Vorbedingung: Ein- oder Ausgangszahlung soll manuell erfasst/storniert werden.
|
||||
Fakt: `PaymentsBL.DeleteIncomingPayment` prüft das Recht `UserRightsConst.Controlling.Finances.INCOMING_PAYMENT_TRANSACTIONS`, bevor eine erfasste Zahlung storniert und der bezahlte Betrag auf der zugehörigen Rechnung zurückgenommen wird.
|
||||
Aussage: Das System soll das Löschen/Stornieren einer erfassten Zahlung nur berechtigten Benutzern erlauben und dabei den bezahlten Betrag auf dem zugehörigen Beleg konsistent zurücksetzen.
|
||||
Ergebnis: Nicht berechtigter Löschversuch wird mit Fehlermeldung "Sie haben nicht das Recht 'Zahlungseingang'" abgelehnt; bei Erfolg ist der Rechnungsbetrag korrekt zurückgesetzt.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Finances\Payments\PaymentsBL.cs (Zeilen 43-44) - Begründung: durchgesetzte Rechteprüfung vor sicherheitskritischer Finanzoperation.
|
||||
Prüfidee: Benutzer ohne Recht versucht Zahlung zu löschen → Ablehnung mit definierter Fehlermeldung; Rechnungsbetrag bleibt unverändert.
|
||||
Tracelinks: SyRS-016
|
||||
Konsolidierung: Kandidat: StRS-015 (beide betreffen Zahlungsbuchung auf Rechnungen)
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-017
|
||||
Titel: Timer-basierte Leistungsabrechnung (Timer Billing)
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Support-Mitarbeiter / Finanzbuchhaltung
|
||||
Vorbedingung: Zeiten wurden auf einem Ticket erfasst und sollen abgerechnet werden.
|
||||
Fakt: `TimerBillingSettingsPageViewModel.UpdateBillingDateIsEnabled` aktiviert das Feld "Abrechnungsdatum" nur, wenn der Benutzer laut `CentronCache.Instance.ReceiptSettings` das Recht `CanChangeDateInInvoices` bzw. `CanChangeDateInDeliveryLists` besitzt; diese Werte werden serverseitig in `ReceiptWebServiceBL` aus `UserRightsConst.Sales.Customer.CustomerCommon.Invoice.CAN_CHANGE_DATE` (ID 20400143) bzw. `.DeliveryList.CAN_CHANGE_DATE` (ID 20400141) berechnet.
|
||||
Aussage: Das System soll das Ändern des Abrechnungsdatums bei aus Zeiterfassungen erzeugten Rechnungen/Lieferscheinen nur Benutzern mit dem jeweils spezifischen Recht erlauben.
|
||||
Ergebnis: Abrechnungsdatum-Feld ist für nicht berechtigte Benutzer deaktiviert/serverseitig nicht änderbar.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.WebServices.Core\WebServices\Sales.Receipts\ReceiptWebServiceBL.cs (Zeilen 994-1000) - Begründung: serverseitig berechnete Berechtigung, nicht nur Client-Anzeige.
|
||||
- [SEKUNDÄR] src\centron\Centron.WPF.UI\Modules\Finances\TimerBilling\Pages\TimerBillingSettingsPageViewModel.cs (Zeile 567) - Begründung: UI-Ausprägung derselben Regel.
|
||||
Prüfidee: Benutzer ohne `CAN_CHANGE_DATE`-Recht öffnet Timer-Billing-Einstellungen → Datumsfeld ist deaktiviert; direkter Web-Service-Aufruf mit geänderten Datum ohne Recht muss serverseitig abgelehnt werden (nicht nur UI-Test!).
|
||||
Tracelinks: SyRS-018
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Block E — Security / Rechte / Authentifizierung
|
||||
|
||||
```
|
||||
ID: StRS-018
|
||||
Titel: Rollenbasiertes Rechtesystem für alle Module
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Systemadministrator / alle internen Benutzer
|
||||
Vorbedingung: Benutzer ist einer oder mehreren Rechtegruppen zugeordnet.
|
||||
Fakt: `UserRightsConst` definiert ca. 751 Rechte-Konstanten, hierarchisch nach Modul/Bildschirm/Aktion organisiert; `AppRightsBL.HasUserRight` liest Gruppenrechte aus den Tabellen `Sichtrus`/`Sichmemb` und cached das Ergebnis pro Benutzer; Aufrufe finden sich konsistent über praktisch alle BL-Module (Sales, Finances, Warehousing, TaskManager, Security) verteilt.
|
||||
Aussage: Das System soll jede sicherheits- oder datenrelevante Aktion serverseitig gegen ein zentral verwaltetes, granular definiertes Recht prüfen, bevor die Aktion ausgeführt wird.
|
||||
Ergebnis: Aktionen ohne ausreichendes Recht werden serverseitig abgelehnt, unabhängig vom verwendeten Client (WPF, Web, API).
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Administration\Rights\AppRightsBL.cs (HasUserRight, ~Zeile 644) - Begründung: zentrale, technisch durchgesetzte Prüfimplementierung.
|
||||
- [PRIMÄR] src\webservice\Centron.WebServices.Core\EntitiesWrongPlace\Administration\Rights\UserRightsConst.cs - Begründung: vollständige Liste der durchsetzbaren Rechte-IDs, Grundlage jeder Einzelprüfung.
|
||||
Prüfidee: Für eine Stichprobe von 10 unterschiedlichen Modulaktionen: Benutzer ohne jeweiliges Recht → serverseitige Ablehnung (nicht nur UI-Ausblendung).
|
||||
Tracelinks: SyRS-019, SyRS-020
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-019
|
||||
Titel: Mehrverfahren-Authentifizierung (Basic/AD/OIDC/Web-Account)
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Alle Benutzer (intern und Kunde)
|
||||
Vorbedingung: Benutzer verfügt über gültige Zugangsdaten in mindestens einem unterstützten Verfahren.
|
||||
Fakt: `AuthenticatorFactory` wählt zwischen `BasicAuthenticator` (Benutzername/Passwort), `ActiveDirectoryAuthenticator`, `OpenIdConnectAuthenticator` (Microsoft Entra ID/SSO) und `WebAccountAuthenticator` (Kundenportal); nach erfolgreicher Anmeldung wird über `TicketBL`/`AuthenticationTicketBL` ein zeitlich befristetes Ticket ausgestellt.
|
||||
Aussage: Das System soll mehrere Authentifizierungsverfahren parallel unterstützen und nach erfolgreicher Anmeldung eine zeitlich befristete Sitzung ausstellen.
|
||||
Ergebnis: Benutzer ist nach erfolgreicher Anmeldung über eines der Verfahren mit gültigem, befristetem Ticket angemeldet.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Administration\Logins\Auth\AuthenticatorFactory.cs, BasicAuthenticator.cs, ActiveDirectoryAuthenticator.cs, OpenIdConnectAuthenticator.cs, WebAccountAuthenticator.cs - Begründung: enthalten die tatsächlich ausgeführte Verfahrensauswahl und -prüfung.
|
||||
- [SEKUNDÄR] src\nexus\CentronNexus\Shared\Auth\AUTHENTICATION.md - Begründung: vom Entwicklerteam verfasste Dokumentation des JWT-/SSO-Ablaufs, ergänzt aber die Codebelege nur.
|
||||
Prüfidee: Anmeldung über jedes der vier Verfahren mit gültigen Testdaten → gültiges Ticket wird ausgestellt; ungültige Zugangsdaten → Ablehnung.
|
||||
Tracelinks: SyRS-021, SyRS-022
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-020
|
||||
Titel: Zwei-Faktor-Authentifizierung
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Alle internen Benutzer (sofern aktiviert)
|
||||
Vorbedingung: 2FA ist über `WebServiceConfigHelper.Current.TwoFactorAuthEnabled` aktiviert.
|
||||
Fakt: `TwoFactorAuthBL` orchestriert die zweite Faktorprüfung über austauschbare Validatoren (`EmailTwoFactorValidator`, `RadiusTwoFactorValidator` inkl. eigenem RADIUS-Client/-Parser); die Aktivierung ist konfigurationsgesteuert, nicht global fest verdrahtet.
|
||||
Aussage: Das System soll optional eine zweite Authentifizierungsstufe (E-Mail-Code oder RADIUS-Hardwaretoken) verlangen, bevor der erste Faktor als vollständige Anmeldung akzeptiert wird.
|
||||
Ergebnis: Bei aktivierter 2FA ist eine Anmeldung ohne erfolgreiche zweite Faktorprüfung nicht möglich.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Administration\Logins\TwoFactor\TwoFactorAuthBL.cs, EmailTwoFactorValidator.cs, RadiusTwoFactorValidator.cs - Begründung: durchgesetzte zweite Prüfstufe im Anmeldeprozess.
|
||||
Prüfidee: Anmeldung mit korrektem ersten Faktor, aber ohne/mit falschem zweiten Faktor → Anmeldung muss abgelehnt werden.
|
||||
Tracelinks: SyRS-021
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround (zwei augenscheinlich überlappende 2FA-Implementierungen im Code vorhanden: `Administration\Logins\TwoFactor\` und separat `TwoFactorAuthenticator\` — Verhältnis ungeklärt, siehe Hypothesen.md)
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-021
|
||||
Titel: Zentrale Passwortverwaltung (Vault) für Kunden-/Systemzugänge
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Support-/Administrationsmitarbeiter
|
||||
Vorbedingung: Ein Zugang (z. B. Kunden-Systemzugang) soll sicher hinterlegt werden.
|
||||
Fakt: `PasswordManagementArea` (u. a. `PasswordManagementBL`, `PasswordManagementAccessLogBL`) verwaltet hinterlegte Zugangsdaten und protokolliert jeden Zugriff (`PasswordManagementAccessLog`: ActionType, Date, EmployeeI3D) sowie jede Änderung (`PasswordManagementLog`).
|
||||
Aussage: Das System soll Zugriffe auf und Änderungen an im Passwort-Tresor gespeicherten Zugangsdaten vollständig protokollieren, um Zugriffe im Nachhinein nachvollziehen zu können.
|
||||
Ergebnis: Jeder Lese-/Änderungszugriff auf ein gespeichertes Passwort erzeugt einen Protokolleintrag mit Benutzer und Zeitstempel.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\PasswordManagementArea\PasswordManagementAccessLogBL.cs, PasswordManagementLogBL.cs - Begründung: durchgesetzte, nicht abschaltbare Protokollierung im Zugriffs-/Änderungspfad.
|
||||
Prüfidee: Gespeichertes Passwort einsehen → Protokolleintrag mit ActionType "Zugriff" muss entstehen.
|
||||
Tracelinks: SyRS-023
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Block F — Web-Kanäle (Kundenportal, WebCart, Multi-Channel-Betrieb)
|
||||
|
||||
```
|
||||
ID: StRS-022
|
||||
Titel: Kundenportal für Web-Accounts (Self-Service)
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Kunde (Web-Account)
|
||||
Vorbedingung: Für den Kunden ist ein Web-Account in der Adressstammverwaltung angelegt.
|
||||
Fakt: `CentronNexus` bietet unter `/customerportal` ein Self-Service-Portal (`CustomperPortalHomePage.razor`) mit Formularen (`CustomerPortalFormsPage.razor`), öffentlichen Dokumenten, Ticketansicht (`CustomerTicketDetailsPage.razor`, `CustomerTicketHistoryPage.razor`) und Zeiterfassungseinsicht (`CustomerPortalCustomerTicketTimeRecordsPage.razor`); Authentifizierung separat über `CustomerAuthPage.razor`.
|
||||
Aussage: Das System soll Kunden mit Web-Account einen eigenständigen Web-Zugang bieten, über den sie ihre Tickets, Dokumente und Formulare einsehen können, getrennt von der internen Mitarbeiteranmeldung.
|
||||
Ergebnis: Angemeldeter Web-Account-Kunde sieht ausschließlich seine eigenen Tickets/Dokumente.
|
||||
Belege:
|
||||
- [PRIMÄR] src\nexus\CentronNexus\CustomperPortalHomePage.razor, CustomerTicketDetailsPage.razor - Begründung: enthält die tatsächliche Portal-Logik/Routen.
|
||||
- [SEKUNDÄR] src\nexus\CentronNexus\Shared\Auth\CustomerAuthPage.razor - Begründung: separate Login-Oberfläche, bestätigt getrennten Zugangsweg.
|
||||
Prüfidee: Kunde A meldet sich an und darf keine Tickets von Kunde B sehen (Mandanten-/Kundentrennungstest).
|
||||
Tracelinks: SyRS-024, SyRS-021
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-023
|
||||
Titel: WebCart – Web-Shop für Sonderpreiskunden
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Kunde (Web-Account, Kunde eines c-entron-Kunden)
|
||||
Vorbedingung: Web-Account ist angelegt; für den zugehörigen Kunden sind Sonderpreisartikel hinterlegt; Lizenz `WebCart2` ist aktiv.
|
||||
Fakt: `WebCartShopPage.razor` ist mit `[AuthorizeLicense(nameof(LicenseGuids.WebCart2))]` lizenzgeschützt und lädt Artikel über `ICentronService.SearchArticles`; `CurrentCartService` verwaltet den Warenkorb (`ReceiptCartDTO`) inkl. automatischer Neuanlage.
|
||||
Aussage: Das System soll Kunden von c-entron-Kunden ermöglichen, über einen lizenzpflichtigen Web-Zugang die für sie freigegebenen Sonderpreisartikel zu durchsuchen und in einem Warenkorb zu bestellen.
|
||||
Ergebnis: Warenkorb enthält nur für den jeweiligen Kunden freigegebene Sonderpreisartikel.
|
||||
Belege:
|
||||
- [PRIMÄR] src\nexus\CentronNexus\WebCart\WebCartShopPage.razor - Begründung: enthält Lizenzprüfung und Preislogik-Aufruf.
|
||||
- [SEKUNDÄR] README.md (Abschnitt "1. WebCart") - Begründung: Entwicklerteam-Beschreibung des fachlichen Zwecks, bestätigt Code-Befund.
|
||||
Prüfidee: Web-Account ohne WebCart2-Lizenz ruft `/webcart/shop` auf → Zugriff muss verweigert werden.
|
||||
Tracelinks: SyRS-024, SyRS-025
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-024
|
||||
Titel: Multi-Channel-Bereitstellung (Desktop, Web, Containerisiert) und Betrieb
|
||||
Ebene: StRS
|
||||
Typ: nicht-funktional
|
||||
Akteur: Systemadministrator (Kunde/Betreiber), NEXOWARE-Betrieb
|
||||
Vorbedingung: Zielumgebung (On-Premises-Windows oder Container-Host) ist vorbereitet.
|
||||
Fakt: Drei Auslieferungsformen sind belegt: WPF-Client + Windows-Service als signierte MSI (WiX, `deployment\centron\*\Product.wxs`), sowie Nexus als containerisiertes Blazor-Server-Deployment (`docker\Dockerfile`, .NET-10-Alpine-Basis, Push nach Azure Container Registry `centron.azurecr.io`).
|
||||
Aussage: Das System soll sowohl als klassische Windows-Desktop-/Service-Installation als auch als containerisierte Web-Anwendung betreibbar sein, um unterschiedliche Kundenumgebungen (On-Premises, Cloud) zu bedienen.
|
||||
Ergebnis: Für jede der drei Komponenten existiert ein eigenständiger, automatisiert erstellter und signierter Auslieferungsartefakt-Typ.
|
||||
Belege:
|
||||
- [PRIMÄR] docker\Dockerfile, deployment\centron\CentronSetupProject\Product.wxs, deployment\centron\WebServiceSetupProject\Product.wxs - Begründung: konkrete, tatsächlich verwendete Build-/Paketierungsartefakte.
|
||||
- [KONTEXT] .github\workflows\build.yml - Begründung: CI-Pipeline bestätigt automatisierten, signierten Build aller drei Artefakte, ist aber Prozess- und kein Laufzeitbeleg.
|
||||
Prüfidee: CI-Pipeline-Lauf erzeugt alle drei signierten Artefakte (MSI ×2, Container-Image) ohne manuellen Eingriff.
|
||||
Tracelinks: SyRS-026, SyRS-027
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Block G — Externe Integrationen (leichtere Analysetiefe, siehe Analysebericht.md)
|
||||
|
||||
```
|
||||
ID: StRS-025
|
||||
Titel: Produktdatenanreicherung über externe Kataloganbieter
|
||||
Ebene: StRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: Einkauf / System
|
||||
Vorbedingung: Artikel mit Hersteller-/EAN-Kennung liegt vor; Zugangsdaten für externen Dienst sind konfiguriert.
|
||||
Fakt: Vier eigenständige API-Clients (COP – SOAP, Egis, ITscope – XML/HTTP mit API-Key, Icecat) liefern Produktbeschreibungen, Bilder, Preise/Verfügbarkeit; jeder Client kapselt Fehler in einer eigenen Exception-Klasse mit deutschsprachiger Meldung (z. B. `ITscopeException("Der API-Key ist ungültig.")`).
|
||||
Aussage: Das System soll Artikelstammdaten wahlweise über mehrere unabhängige externe Katalogdienste anreichern können, ohne dass ein Ausfall eines Dienstes die anderen beeinträchtigt.
|
||||
Ergebnis: Artikeldaten (Bild, Beschreibung, Preis/Verfügbarkeit) werden aus dem jeweils konfigurierten Dienst geladen; Fehler eines Dienstes werden isoliert behandelt.
|
||||
Belege:
|
||||
- [PRIMÄR] src\apis\Centron.APIs.ITscopeDataAccess\ITscopeApi.cs (Zeilen 293-314) - Begründung: durchgesetzte Fehlerbehandlung pro Dienst.
|
||||
- [SEKUNDÄR] src\apis\Centron.APIs.IcecatDataAccess\IcecatApi.cs, Centron.APIs.CopDataAccess\CopApi.cs, Centron.APIs.EgisDataAccess\EgisApi.cs - Begründung: bestätigen paralleles, unabhängiges Client-Design.
|
||||
Prüfidee: Ein Dienst liefert HTTP 401 → nur dieser Dienst wird als fehlgeschlagen markiert, übrige Anreicherungsquellen bleiben nutzbar.
|
||||
Tracelinks: SyRS-028
|
||||
Konsolidierung: Kandidat: strukturell ähnliches Client-Pattern wie StRS-026 (Versanddienstleister)
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-026
|
||||
Titel: Versanddienstleister-Integration (Paketversand)
|
||||
Ebene: StRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: Lagermitarbeiter / Versand
|
||||
Vorbedingung: Sendung mit Empfängerdaten ist bereit zum Versand.
|
||||
Fakt: `CentronGlsLogic.UploadShipment` sendet eine `ShippmentRequest` an GLS und liefert Tracking-ID/-URL sowie Label zurück; `CentronShipcloudLogic` bietet eine mehrere Carrier umfassende Alternative (Shipcloud) inkl. Webhook-Empfang für Statusupdates (`WebhookSecurity`).
|
||||
Aussage: Das System soll Versandaufträge elektronisch an mindestens einen Paketdienstleister übermitteln und die zurückgelieferte Sendungsverfolgung sowie das Versandlabel dem Beleg zuordnen.
|
||||
Ergebnis: Beleg enthält nach erfolgreichem Versandauftrag Tracking-Referenz und Label.
|
||||
Belege:
|
||||
- [PRIMÄR] src\apis\Centron.Api.Gls\CentronGlsLogic.cs (UploadShipment) - Begründung: durchgesetzter Aufruf- und Rückgabepfad.
|
||||
- [SEKUNDÄR] src\apis\Centron.Api.Shipcloud\CentronShipcloudLogic.cs - Begründung: alternative/ergänzende Umsetzung desselben fachlichen Ziels.
|
||||
Prüfidee: Versandauftrag mit gültigen Empfängerdaten auslösen → Tracking-ID und Label müssen im System hinterlegt sein.
|
||||
Tracelinks: SyRS-028
|
||||
Konsolidierung: Kandidat: GLS und Shipcloud bilden dieselbe fachliche Funktion "Versandauftrag erstellen" redundant ab.
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-027
|
||||
Titel: Elektronischer Rechnungsaustausch (ZUGFeRD/ebInterface/XRechnung)
|
||||
Ebene: StRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: Finanzbuchhaltung
|
||||
Vorbedingung: Eine Rechnung soll in einem elektronischen, normierten Format ausgetauscht werden.
|
||||
Fakt: `EbInterfaceLogic` erzeugt lokal ebInterface-4.3-konforme XML aus einem `ReceiptInfo`-Objekt (österreichischer E-Rechnungsstandard); ein separater `ZugferdImportController` importiert ZUGFeRD-Rechnungen; `docs\reference\zugferd-field-mapping.md` dokumentiert das Feldmapping.
|
||||
Aussage: Das System soll Eingangsrechnungen im ZUGFeRD-Format importieren und ausgehende Rechnungen im ebInterface-Format exportieren können, um gesetzliche/branchenübliche E-Rechnungsanforderungen in Deutschland und Österreich zu erfüllen.
|
||||
Ergebnis: Import einer gültigen ZUGFeRD-Datei überführt deren Daten in einen Beleg; Export einer Rechnung erzeugt eine schemakonforme ebInterface-XML.
|
||||
Belege:
|
||||
- [PRIMÄR] src\apis\Centron.Api.EbInterface\EbInterfaceLogic.cs - Begründung: durchgesetzte XML-Erzeugung nach Zielschema.
|
||||
- [SEKUNDÄR] src\webservice\Centron.Controllers\Controllers\v1\Receipts\ZugferdImportController.cs, docs\reference\zugferd-field-mapping.md - Begründung: Import-Endpunkt bzw. Entwicklerdokumentation als ergänzender Beleg.
|
||||
Prüfidee: ebInterface-Export einer Testrechnung gegen offizielles XSD-Schema validieren.
|
||||
Tracelinks: SyRS-028
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-028
|
||||
Titel: Druckerflottenmanagement (Managed Print Services / docuFORM)
|
||||
Ebene: StRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: System / Administrator (Gerätemonitoring)
|
||||
Vorbedingung: Geräte sind im externen docuFORM-System (MPS-Dienstleister) registriert; OAuth2-Zugangsdaten sind konfiguriert.
|
||||
Fakt: `DocuFormRestApiClient` authentifiziert sich per OAuth2 (`OAuthHelper`) gegen `/auth/v2/token` und ruft anschließend `/dfmserver/v2/devices` u. a. für Zählerstände (`DeviceCounters`), Verbrauchsmaterial (`DeviceSupplies`) und Ereignisse (`DeviceEvent`) ab; Konfiguration über `DocuFormApiSettingsController`.
|
||||
Aussage: Das System soll Zählerstände, Verbrauchsmaterialstatus und Ereignisse angebundener Drucker-/Kopierergeräte über die docuFORM-Schnittstelle automatisiert abrufen können.
|
||||
Ergebnis: Gerätestatus (Zähler, Verbrauchsmaterial) ist im System aktuell verfügbar, ohne manuelle Ablesung.
|
||||
Belege:
|
||||
- [PRIMÄR] src\apis\Centron.Api.docuFORM\DocuFormRestApiClient.cs, DocuFormRestApiConstants.cs - Begründung: durchgesetzter Abruf-Client mit versionierten Endpunktpfaden.
|
||||
- [SEKUNDÄR] src\webservice\Centron.Controllers\Controllers\v1\DataExchange\DocuFormApiSettingsController.cs - Begründung: Konfigurationsoberfläche für die Integration.
|
||||
Prüfidee: Abruf von `GetDeviceCounters` für ein Testgerät liefert plausible Zählerwerte zurück.
|
||||
Tracelinks: SyRS-028
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
+761
@@ -0,0 +1,761 @@
|
||||
# Software Requirements Specification (SwRS)
|
||||
|
||||
Ebene: Komponenten, Datenmodelle, software-interne Regeln. Tracelinks verweisen auf die zugehörige(n) SyRS-Anforderung(en).
|
||||
|
||||
---
|
||||
|
||||
## Block A — Belegkette / Order-to-Cash
|
||||
|
||||
```
|
||||
ID: SwRS-001
|
||||
Titel: IReceiptSpecificLogic als Erweiterungspunkt je Belegart
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: Komponente ReceiptBL
|
||||
Vorbedingung: Beleg einer bestimmten Art (Offer/Order/DeliveryList/Invoice/...) wird verarbeitet.
|
||||
Fakt: `IReceiptSpecificLogic` wird von `OfferSpecificLogic`, `OrderSpecificLogic`, `DeliveryListSpecificLogic`, `InvoiceSpecificLogic` u. a. implementiert; `ReceiptBL` erhält die passende Implementierung injiziert statt Typprüfungen (`is`/`switch` auf Belegart) durchzuführen.
|
||||
Aussage: Die Komponente `ReceiptBL` soll belegartspezifisches Verhalten ausschließlich über die injizierte `IReceiptSpecificLogic`-Instanz beziehen.
|
||||
Ergebnis: Neue Belegart erfordert nur eine neue `IReceiptSpecificLogic`-Implementierung, keine Änderung an `ReceiptBL` selbst.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.Interfaces\Sales.Receipts\IReceiptSpecificLogic.cs - Begründung: definiert den Erweiterungsvertrag.
|
||||
- [SEKUNDÄR] src\backend\Centron.BL\Sales\Receipts\Offers\OfferSpecificLogic.cs, Invoices\InvoiceSpecificLogic.cs - Begründung: konkrete Implementierungen belegen konsistente Nutzung des Patterns.
|
||||
Prüfidee: Statische Codeanalyse: keine belegartspezifische Fallunterscheidung außerhalb der `*SpecificLogic`-Klassen in `ReceiptBL`.
|
||||
Tracelinks: SyRS-001
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-002
|
||||
Titel: CustomerAssetExtended<T> als gemeinsame Entitätsbasis
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: Datenmodell (Centron.Entities)
|
||||
Vorbedingung: Entität einer Belegart wird modelliert.
|
||||
Fakt: `Order`, `Invoice`, `Offer` erben (mittelbar über belegartspezifische Basisklassen) von `CustomerAssetExtended<T>`; Belegart-Diskriminierung erfolgt über `CentronObjectKindNumeric` (`AssetKindOa = ...OrderClass`/`InvoiceClass`).
|
||||
Aussage: Das Datenmodell soll alle Belegarten strukturell als Ausprägungen derselben abstrakten Basis führen, um gemeinsame Felder (Kunde, Datum, Status) nur einmal zu definieren.
|
||||
Ergebnis: Gemeinsame Felder sind für alle Belegarten strukturell identisch benannt/typisiert.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.Interfaces\CentronObjectKindNumeric.cs - Begründung: enthält die tatsächlich verwendete Diskriminator-Enumeration.
|
||||
- [SEKUNDÄR] src\backend\Centron.Entities\Entities\Sales\CustomerAssets\Orders\Order.cs, Invoices\Invoice.cs - Begründung: konkrete Vererbungshierarchie.
|
||||
Prüfidee: Reflection-Test: alle Belegart-Entitäten erben von derselben Basisklasse.
|
||||
Tracelinks: SyRS-001
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-003
|
||||
Titel: AutomaticallyCloseReceiptHelperBL steuert ReceiptState-Übergänge
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: Komponente AutomaticallyCloseReceiptHelperBL
|
||||
Vorbedingung: Belegposition wurde vollständig oder teilweise weiterverarbeitet.
|
||||
Fakt: `TryAutomaticallyCloseReceipt` setzt `ReceiptState = Completed`, wenn keine offene Restmenge mehr vorhanden ist; `TryAutomaticallyOpenReceipt` macht dies bei nachträglicher Änderung rückgängig.
|
||||
Aussage: Die Komponente soll nach jeder Mengenänderung an einem Beleg prüfen, ob ein automatischer Statuswechsel erforderlich ist, und diesen ausführen.
|
||||
Ergebnis: `ReceiptState` ist nach jeder Mengenänderung konsistent mit der tatsächlichen Restmenge.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Internal\AutomaticallyCloseReceiptHelperBL.cs - Begründung: enthält die tatsächliche Übergangslogik.
|
||||
Prüfidee: Letzte offene Position eines Belegs vollständig verarbeiten → `ReceiptState` wechselt automatisch zu `Completed`.
|
||||
Tracelinks: SyRS-002
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-004
|
||||
Titel: Ein-aktiver-Vorgang-Regel bei SharedDocumentBL.GenerateTokenForDocument
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Komponente SharedDocumentBL
|
||||
Vorbedingung: Für einen Beleg soll ein neuer Signiervorgang gestartet werden.
|
||||
Fakt: `GenerateTokenForDocument` (Zeilen 128-130) ruft `GetActiveAndUnsignedSharedDocumentForReceipt` auf; existiert bereits ein solcher, wird `Result<SharedDocument>.AsError("Es existiert bereits ein aktiver Signierungs-Ablauf", ...)` zurückgegeben statt eines neuen Tokens.
|
||||
Aussage: Die Methode soll für einen Beleg maximal einen aktiven, unsignierten Vorgang gleichzeitig zulassen.
|
||||
Ergebnis: Zweiter Aufruf für denselben Beleg bei bestehendem aktivem Vorgang liefert einen Fehler statt eines zweiten Tokens.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Administration\FileManagement\SharedDocumentBL.cs (Zeilen 128-130) - Begründung: sicherheits-/rechtsverbindlichkeitsrelevant, PRIMÄR-Beleg vorhanden (durchgesetzte Prüfung).
|
||||
Prüfidee: Zweiten `GenerateTokenForDocument`-Aufruf für denselben `receiptI3D` bei aktivem Vorgang → `Result.AsError`.
|
||||
Tracelinks: SyRS-003
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-005
|
||||
Titel: Ablauf- und Einmaligkeitsprüfung in SharedDocumentBL.GetSharedDocumentByToken
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Komponente SharedDocumentBL
|
||||
Vorbedingung: Ein Token wird zum Abrufen eines Signiervorgangs verwendet.
|
||||
Fakt: Zeilen 405-406: `if (foundByToken.ExpiredDate.HasValue && foundByToken.ExpiredDate.Value < DateTime.Now) return Result<int>.AsError("Die Signierungsanfrage ist bereits abgelaufen.", ...)`; Zeile 408-409: `if (foundByToken.IsSigned) return Result<int>.AsError("Dokument wurde bereits signiert.", ...)`.
|
||||
Aussage: Die Methode soll Zugriffe mit abgelaufenem oder bereits verwendetem Token serverseitig ablehnen, bevor Dokumentinhalte ausgeliefert werden.
|
||||
Ergebnis: Abgelaufener/verwendeter Token liefert einen definierten Fehler, keine Dokumentdaten.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Administration\FileManagement\SharedDocumentBL.cs (Zeilen 405-409) - Begründung: durchgesetzte serverseitige Prüfung.
|
||||
Prüfidee: Abgelaufenen Token per direktem Methodenaufruf/HTTP-Request verwenden → definierter Fehlercode, keine Nutzdaten.
|
||||
Tracelinks: SyRS-004
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-006
|
||||
Titel: Zustandssetzung durch ReceiptBL.AcceptWebReceipt / AcceptWebReceiptWithoutSignature
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: Komponente ReceiptBL
|
||||
Vorbedingung: Kunde signiert oder akzeptiert ein Web-Angebot ohne Unterschrift.
|
||||
Fakt: `AcceptWebReceipt` (~Zeile 6256) setzt `receiptPdfDocument.WebReceiptState = WebReceiptState.WebOfferSign` (Zeile 6302); `AcceptWebReceiptWithoutSignature` (~Zeile 6311) setzt `WebOfferSignedWithoutSignature` (Zeile 6360) und leitet die Weiterführung zum Auftrag ein.
|
||||
Aussage: Die Methoden sollen den Belegstatus abhängig vom gewählten Annahmeweg (mit/ohne Signatur) eindeutig und unterscheidbar setzen.
|
||||
Ergebnis: `WebReceiptState` zeigt nach Annahme eindeutig, ob mit oder ohne Signatur akzeptiert wurde.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs (Zeilen 6256-6360) - Begründung: enthält die tatsächliche Zustandssetzung.
|
||||
- [PRIMÄR] src\backend\Centron.Interfaces\Sales.Receipts\WebReceipt\WebReceiptState.cs - Begründung: definiert die verwendeten Enumwerte.
|
||||
Prüfidee: Annahme mit Signatur → `WebOfferSign`; Annahme ohne Signatur → `WebOfferSignedWithoutSignature`.
|
||||
Tracelinks: SyRS-004
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-007
|
||||
Titel: ReceiptInvoiceBL.FixInvoice mit Guard CheckIfInvoiceIsFixed
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: Komponente ReceiptInvoiceBL
|
||||
Vorbedingung: Rechnung soll festgeschrieben werden.
|
||||
Fakt: `FixInvoice` (Zeile 86) ruft `CheckIfInvoiceIsFixed` (Zeile 273) auf; ist die Rechnung bereits fixiert, wird die Warnung "Die Rechnung ist festgeschrieben. Änderungen nicht möglich." in einen harten Fehler umgewandelt, bevor der eigentliche Festschreibungs-Schreibvorgang beginnt; bei Erfolg wird ein Protokolleintrag `ReceiptLogKind.FixedState` mit Zeitstempel und Benutzer erzeugt.
|
||||
Aussage: Die Methode soll eine bereits festgeschriebene Rechnung nicht erneut festschreiben und jede erfolgreiche Festschreibung mit einem unveränderlichen Protokolleintrag versehen.
|
||||
Ergebnis: Zweite Festschreibung derselben Rechnung wird abgelehnt; jede erfolgreiche Festschreibung ist protokolliert.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\ReceiptInvoiceBL.cs (FixInvoice Zeile 86, CheckIfInvoiceIsFixed Zeile 273) - Begründung: Fakturierungslogik, PRIMÄR-Beleg zwingend und vorhanden.
|
||||
Prüfidee: Bereits fixierte Rechnung erneut festschreiben → Ablehnung mit definierter Meldung.
|
||||
Tracelinks: SyRS-005
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-008
|
||||
Titel: DB-Constraint RechKopf.IsFixed NOT NULL DEFAULT(0)
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: Datenbank
|
||||
Vorbedingung: Neue Rechnungszeile (`RechKopf`) wird angelegt.
|
||||
Fakt: Migrationsskript `CreateIsFixedColumnInRechKopfTable` (#10208, `SQLScriptCollection2.xml`) definiert `IsFixed bit NOT NULL CONSTRAINT DF_RechKopf_IsFixed DEFAULT(0)`, gespiegelt auf `RechKopfVersions`.
|
||||
Aussage: Die Spalte `IsFixed` soll auf Datenbankebene nie NULL sein, unabhängig davon, ob die Anwendungsschicht den Wert explizit setzt.
|
||||
Ergebnis: Jede Rechnungszeile hat nach dem Anlegen `IsFixed = 0` (Standardwert), sofern nicht explizit anders gesetzt.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Administration\Scripts\ScriptMethods\SqlStatements\SQLScriptCollection2.xml (Skript #10208) - Begründung: DB-Constraint, höchste Evidenzstufe.
|
||||
- [SEKUNDÄR] src\backend\Centron.DAO\Mappings\...\ReceiptInvoiceBaseMaps.cs (Not.Nullable() auf IsFixed) - Begründung: ORM-seitige Bestätigung des Pflichtfelds.
|
||||
Prüfidee: INSERT ohne explizite Angabe von `IsFixed` → DB setzt automatisch 0, NULL wird von der DB abgelehnt.
|
||||
Tracelinks: SyRS-005
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-009
|
||||
Titel: CalculationUtils.CalculateTaxTotalPrice / CalculateGrossPrice
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: Komponente CalculationUtils
|
||||
Vorbedingung: Netto-Betrag und Steuersatz liegen vor.
|
||||
Fakt: `CalculateTaxTotalPrice(netTotalPrice, taxRate) = Math.Round(netTotalPrice * (taxRate/100), 2, MidpointRounding.AwayFromZero)`; `CalculateGrossPrice` berechnet zunächst den Nettopreis unter Berücksichtigung von Währungsfaktor und Rabatt, dann den Bruttopreis mit Steueraufschlag, gerundet mit konfigurierbarer Präzision.
|
||||
Aussage: Die Funktionen sollen Steuer- und Bruttobeträge nach einer festen, kaufmännischen Rundungsregel (2 Nachkommastellen, `AwayFromZero`) berechnen.
|
||||
Ergebnis: Für identische Eingabewerte liefert die Funktion stets dasselbe, deterministische Ergebnis.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.Interfaces\DataExchange.BookKeeping\CalculationUtils.cs - Begründung: enthält die tatsächliche Berechnungs-/Rundungslogik.
|
||||
Prüfidee: Netto=100,005, Steuersatz=19 → erwarteter, kaufmännisch gerundeter Wert (Unit-Test mit Grenzwerten wie x,xx5).
|
||||
Tracelinks: SyRS-006
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-010
|
||||
Titel: InvoiceSpecificLogic.TakeoverVATWhenForwarding steuert USt-Übernahme bei Belegübergängen
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: Komponente InvoiceSpecificLogic
|
||||
Vorbedingung: Ein Beleg wird zu einem Folgebeleg weitergeführt (z. B. Auftrag → Rechnung).
|
||||
Fakt: `TakeoverVATWhenForwarding() => TakeoverVatMode.Yes`; `GetDateTimeForVATCalculation(receipt) => receipt.Date` legt fest, welches Datum für die Steuersatzermittlung bei Neuberechnung herangezogen wird.
|
||||
Aussage: Die Komponente soll bei Belegweiterführung explizit steuern, ob die Umsatzsteuer vom Vorgängerbeleg übernommen oder anhand des Belegdatums neu berechnet wird.
|
||||
Ergebnis: Weitergeführter Beleg hat einen nachvollziehbar (Übernahme oder Neuberechnung) bestimmten Steuersatz.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\Invoices\InvoiceSpecificLogic.cs (TakeoverVATWhenForwarding, GetDateTimeForVATCalculation) - Begründung: enthält die tatsächliche Steuerungslogik.
|
||||
Prüfidee: Auftrag mit Steuersatz X zu Rechnung mit späterem Datum (nach Steuersatzänderung) weiterführen → Ergebnis muss mit `TakeoverVatMode.Yes`-Regel übereinstimmen (Übernahme statt Neuberechnung).
|
||||
Tracelinks: SyRS-006
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Block B — Helpdesk / RMA / TaskManager
|
||||
|
||||
```
|
||||
ID: SwRS-011
|
||||
Titel: HelpdeskBL.Save/DoBeforeSave Validierungspipeline
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: Komponente HelpdeskBL
|
||||
Vorbedingung: Ticket wird gespeichert.
|
||||
Fakt: `Save`/`DoBeforeSave` (Zeilen ~298-326) führen sequenziell `DoValidateMandatoryFields`, `CheckUserRigths`, `CheckTextFieldLengths` und eine Zeilenumbruch-Normalisierung aus, bevor der eigentliche Speichervorgang beginnt.
|
||||
Aussage: Die Methode soll ein Ticket nur speichern, wenn alle Pflichtfelder gesetzt, der Benutzer berechtigt und Textfeldlängen eingehalten sind.
|
||||
Ergebnis: Speicherversuch mit fehlendem Pflichtfeld oder überlanger Texteingabe wird abgelehnt.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs (Zeilen 298-326) - Begründung: durchgesetzte Validierungskette im Speicherpfad.
|
||||
Prüfidee: Ticket ohne Pflichtfeld "Kunde" speichern → Ablehnung vor Persistierung.
|
||||
Tracelinks: SyRS-007
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-012
|
||||
Titel: HelpdeskBL.CheckUserRigths differenziert nach Aktion (Anlage/Bearbeitung/Schließen/Zuweisung)
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Komponente HelpdeskBL
|
||||
Vorbedingung: Ticket-Änderung mit bestimmter Aktion (neu/bearbeiten/schließen/zuweisen/Fälligkeit ändern) wird angestoßen.
|
||||
Fakt: `CheckUserRigths` (Zeilen 410-466) prüft je nach Aktion ein spezifisches Recht: `ADD_NEW_HELPDESK` (Neuanlage), `EDIT_HELPDESK` (Bearbeitung), `CLOSE_REQUEST` (Schließen, sonst wird `entity.ClosedAt = null` zurückgesetzt), `MATURITY_CHANGE` (Fälligkeitsänderung, geprüft über `HelpdeskRepositoryDAO.IsDueDateChanged`), `ASSIGN_HELPDESK_ONLY_TO_OWN_DEPARTMENTS` (Einschränkung von `ResponsiblePerson` auf eigene Abteilung, Zeilen 454-462).
|
||||
Aussage: Die Methode soll für jede Art der Ticketänderung ein eigenständiges, spezifisches Recht prüfen statt ein einzelnes generisches "Bearbeiten"-Recht für alle Aktionen zu verwenden.
|
||||
Ergebnis: Benutzer mit `EDIT_HELPDESK`, aber ohne `CLOSE_REQUEST`, kann Ticket bearbeiten, aber nicht schließen (Schließversuch wird durch Zurücksetzen von `ClosedAt` neutralisiert).
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs (Zeilen 410-466) - Begründung: durchgesetzte, aktionsspezifische Rechteprüfung.
|
||||
Prüfidee: Benutzer mit `EDIT_HELPDESK` ohne `CLOSE_REQUEST` versucht `ClosedAt` zu setzen → Feld wird serverseitig zurückgesetzt.
|
||||
Tracelinks: SyRS-007
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-013
|
||||
Titel: Sichtbarkeitsfilter SHOW_HELPDESK_ONLY_OWN / _ONLY_OWN_BRANCH in Abfragekonstruktion
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Komponente HelpdeskBL
|
||||
Vorbedingung: Ticketliste wird für einen Benutzer mit einschränkendem Recht abgefragt.
|
||||
Fakt: `GetLoggedInUserShowHelpdeskRight` (Zeilen ~271-284) bestimmt den anzuwendenden Scope (own/own branch/all) und dieser fließt in den Abfrageaufbau ein, bevor Daten aus der DB gelesen werden; `RmaBL.GetNamedQueryParams` (Zeilen 653-669) delegiert dieselbe Scope-Logik für RMA-Sichtbarkeit an `HelpdeskBL`.
|
||||
Aussage: Die Abfragekonstruktion soll den Sichtbarkeits-Scope bereits vor dem Datenbankzugriff anwenden, nicht als Post-Filter auf einer bereits vollständig geladenen Ergebnismenge.
|
||||
Ergebnis: Datenbankabfrage enthält bereits die Scope-Einschränkung als Teil des WHERE-Kriteriums bzw. der Query-Parameter.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs (GetLoggedInUserShowHelpdeskRight) - Begründung: durchgesetzte Scope-Bestimmung vor Datenzugriff.
|
||||
- [SEKUNDÄR] src\backend\Centron.BL\CustomerArea\RmaBL.cs (GetNamedQueryParams, Zeilen 653-669) - Begründung: Wiederverwendung derselben Scope-Logik in einem zweiten Modul, stützt die Aussage zur konsistenten Durchsetzung.
|
||||
Prüfidee: SQL-Profiling der Abfrage eines eingeschränkten Benutzers → WHERE-Klausel enthält bereits die Scope-Bedingung.
|
||||
Tracelinks: SyRS-008
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-014
|
||||
Titel: RmaBL.SaveRma erzwingt HelpdeskI3D > 0
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: Komponente RmaBL
|
||||
Vorbedingung: RMA-Datensatz wird gespeichert.
|
||||
Fakt: Zeilen 352-353: `if (rma.HelpdeskI3D <= 0) throw new ResultException("Rma not coneccted to helpdesk", DependencyCheckFailed);` vor jeglicher weiterer Verarbeitung.
|
||||
Aussage: Die Methode soll die Ticketverknüpfung als erste Prüfung im Speicherpfad durchführen, bevor weitere (aufwändigere) Verarbeitungsschritte wie Lagerbuchungen ausgeführt werden.
|
||||
Ergebnis: RMA ohne gültige Ticketreferenz wird abgelehnt, bevor Nebenwirkungen (z. B. Lagerbuchungen) eintreten.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\CustomerArea\RmaBL.cs (Zeilen 352-353) - Begründung: durchgesetzte Prüfung als erster Schritt des Speicherpfads.
|
||||
Prüfidee: RMA mit `HelpdeskI3D = 0` speichern → `ResultException` vor jeder Nebenwirkung, keine Teilverarbeitung.
|
||||
Tracelinks: SyRS-009
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-015
|
||||
Titel: RmaArticleState-Zustandsmodell und Reparatur-Workflow RmaForthAction
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: Komponente RmaBL
|
||||
Vorbedingung: RMA-Artikelposition durchläuft den Reparatur-/Rücksendeprozess.
|
||||
Fakt: `RmaArticleState` (u. a. `none`, `Open`, `SendForth`, `SendBack`, `BackDeliveryList`, `Invoice`, `Scapped`, `Rebooked`) und `RmaForthAction` (u. a. `Repair`, `UnRepair`, `EqualChange`, `ForeignChange`, `Scapped`) werden in `SaveRma` (Zeilen 378-521) und `HistoryCanceled` (825-879) als Zustandsübergänge durchgesetzt.
|
||||
Aussage: Die Komponente soll den Bearbeitungsfortschritt einer RMA-Artikelposition ausschließlich über die definierten Enum-Zustände abbilden und Übergänge nachvollziehbar in der Historie (`RmaArticleHistory`) festhalten.
|
||||
Ergebnis: Jede RMA-Artikelposition hat zu jedem Zeitpunkt einen der definierten `RmaArticleState`-Werte; Zustandswechsel sind über Historieneinträge nachvollziehbar.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\CustomerArea\RmaBL.cs (SaveRma Zeilen 378-521, HistoryCanceled Zeilen 825-879) - Begründung: enthält die tatsächlichen Zustandsübergänge.
|
||||
Prüfidee: Artikel von `SendForth` zu `Invoice` überführen → Historieneintrag mit korrektem Alt-/Neu-Zustand entsteht.
|
||||
Tracelinks: SyRS-009
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-016
|
||||
Titel: TaskManagementTaskBL.ExecuteTask mit sp_getapplock-Sperre
|
||||
Ebene: SwRS
|
||||
Typ: nicht-funktional
|
||||
Akteur: Komponente TaskManagementTaskBL
|
||||
Vorbedingung: Fällige wiederkehrende Aufgabe wird ausgewertet.
|
||||
Fakt: Private Overload (Zeilen ~673-687) führt `DECLARE @result int; EXEC @result = sp_getapplock @Resource = :resource, @LockMode = 'Exclusive', @LockOwner = 'Transaction', @LockTimeout = 0; SELECT @result` aus, bevor die eigentliche Aktion (`TaskManagementHelpdeskAction`/`TaskManagementReportAction`) ausgeführt wird.
|
||||
Aussage: Die Methode soll vor Ausführung einer fälligen Aufgabe ein exklusives, transaktionsgebundenes Datenbank-Lock mit Timeout 0 erwerben und bei Nichterhalt die Ausführung nicht durchführen.
|
||||
Ergebnis: Bei parallelem Zugriff zweier Prozesse erhält nur einer das Lock; der andere überspringt die Ausführung.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\TaskManager\TaskManagementTaskBL.cs (sp_getapplock-Aufruf) - Begründung: DB-seitig durchgesetzter, prozessübergreifender Sperrmechanismus.
|
||||
Prüfidee: Zwei parallele Prozessaufrufe für dieselbe Aufgaben-ID → nur ein Prozess erhält das Lock (LockTimeout=0 lässt zweiten sofort fehlschlagen).
|
||||
Tracelinks: SyRS-010
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-017
|
||||
Titel: TaskManagementHelpdeskActionHandler prüft ADD_NEW_HELPDESK vor automatischer Ticketerstellung
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Komponente TaskManagementHelpdeskActionHandler
|
||||
Vorbedingung: Automatisierte Aufgabe erzeugt ein Helpdesk-Ticket.
|
||||
Fakt: Zeile 57 prüft `UserRightsConst.Sales.Customer.Helpdesk.ADD_NEW_HELPDESK`, bevor das Ticket erzeugt wird — dieselbe Rechteprüfung wie bei manueller Ticketerstellung in `HelpdeskBL`.
|
||||
Aussage: Der Action-Handler soll dieselbe Rechteprüfung wie der manuelle Ticket-Anlagepfad verwenden, um zu verhindern, dass automatisierte Aufgaben Rechteprüfungen umgehen.
|
||||
Ergebnis: Automatisierte Ticketerstellung ohne konfigurierten, berechtigten Ausführungsbenutzer schlägt fehl statt das Recht zu umgehen.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\TaskManager\ActionHandler\TaskManagementHelpdeskActionHandler.cs (Zeile 57) - Begründung: identische Rechteprüfung wie im manuellen Pfad, verhindert Umgehung.
|
||||
Prüfidee: Aufgabe mit Ausführungskontext ohne `ADD_NEW_HELPDESK`-Recht fällig werden lassen → Ticketerstellung schlägt fehl statt das Recht zu ignorieren.
|
||||
Tracelinks: SyRS-010
|
||||
Konsolidierung: Kandidat: SwRS-012 (gleiche zugrundeliegende Rechteklasse ADD_NEW_HELPDESK)
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Block C — Warehousing / Purchasing
|
||||
|
||||
```
|
||||
ID: SwRS-018
|
||||
Titel: ArticleBL Feldschutz: Blockade vs. stiller Rollback je Feld
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Komponente ArticleBL
|
||||
Vorbedingung: Artikel wird mit geänderten Feldern gespeichert.
|
||||
Fakt: `CheckUserRightBeforeSave` (Zeilen 991-1055) blockiert den gesamten Speichervorgang bei fehlendem Recht für Preis/Barcode-Pflicht-Änderung; `CheckSpecialUserRightBeforeSave` (Zeilen 1058-1089) hingegen setzt nur die betroffenen Felder (Warengruppe, Nebenwarengruppe, `MailToCollection`, `ClassI3D2`) auf den ursprünglichen DB-Wert zurück und lässt den restlichen Speichervorgang zu, wenn `NOT_CHANGEABLE_ARTICLE_PROPERTIES` gesetzt ist oder `EDIT_MaterialGroup` fehlt.
|
||||
Aussage: Die Komponente soll zwei unterschiedliche Schutzstrategien anwenden: harte Ablehnung für hochkritische Felder (Preis), stiller Feld-Rollback für weniger kritische Klassifikationsfelder, um den restlichen Speichervorgang nicht unnötig zu blockieren.
|
||||
Ergebnis: Speichervorgang mit gemischt berechtigten/nicht berechtigten Feldänderungen führt zu partiellem Erfolg (erlaubte Felder gespeichert, geschützte zurückgesetzt) statt Totalausfall.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Warehousing\ArticleBL.cs (Zeilen 991-1089) - Begründung: enthält beide durchgesetzten Schutzmechanismen im Detail.
|
||||
Prüfidee: Speichervorgang mit geänderter Warengruppe (ohne Recht) und geändertem Namen (mit Recht) → Name wird gespeichert, Warengruppe bleibt auf DB-Wert.
|
||||
Tracelinks: SyRS-011
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-019
|
||||
Titel: Berechnung von CloseState (Counted/Ok/Risk/problem) je Inventurposition
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: Komponente InventoryBL
|
||||
Vorbedingung: Inventurposition wurde gezählt.
|
||||
Fakt: Berechnungslogik (Zeilen ~694-750) vergleicht gezählte mit erwarteter Menge und berücksichtigt Barcode-Zustandskonflikte zur Ableitung von `CloseState`.
|
||||
Aussage: Die Berechnung soll deterministisch aus Zähl-/Sollmenge und Barcode-Zustand erfolgen, ohne manuelle Nacherfassung durch den Anwender.
|
||||
Ergebnis: Jede gezählte Position hat unmittelbar nach der Zählung einen berechneten `CloseState`.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Warehousing\InventoryManagement\InventoryBL.cs (Zeilen 694-750) - Begründung: enthält die tatsächliche Berechnungslogik.
|
||||
Prüfidee: Zählmenge = Sollmenge, kein Barcode-Konflikt → `CloseState = Ok`; Zählmenge ≠ Sollmenge → `Risk`/`problem`.
|
||||
Tracelinks: SyRS-012
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-020
|
||||
Titel: InventoryBL.DeleteInventory: Statuswechsel Open⇄Deleted mit Rechteprüfung
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Komponente InventoryBL
|
||||
Vorbedingung: Inventur soll gelöscht oder wiederhergestellt werden.
|
||||
Fakt: Zeilen 98-109: Wechsel von `Open`/`OpenWithoutBC` zu `Deleted` (und zurück, als Undo-Delete), gesichert durch `UserRightsConst.Purchase.Inventory.DROP_INVENTORY`.
|
||||
Aussage: Die Methode soll sowohl das Löschen als auch das Wiederherstellen einer Inventur an dasselbe Recht koppeln, da beide Operationen denselben fachlichen Eingriff (Statusänderung) darstellen.
|
||||
Ergebnis: Benutzer ohne `DROP_INVENTORY` kann weder löschen noch wiederherstellen.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Warehousing\InventoryManagement\InventoryBL.cs (Zeilen 98-109) - Begründung: durchgesetzte Rechteprüfung bei beiden Richtungen des Statuswechsels.
|
||||
Prüfidee: Benutzer ohne Recht versucht gelöschte Inventur wiederherzustellen → Ablehnung.
|
||||
Tracelinks: SyRS-012
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-021
|
||||
Titel: PartialCommissionOrderBL: getrennte Rechteprüfung für Anlage und Löschung
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Komponente PartialCommissionOrderBL
|
||||
Vorbedingung: Teilkommissionierung wird angelegt oder gelöscht.
|
||||
Fakt: Zeilen 135/170 prüfen `CREATE_PARTIAL_COMMISSION_FOR_ORDER` bei Anlage; Zeilen 426/453 prüfen `DELETE_PARTIAL_COMMISSION_FOR_ORDER` bei Löschung — zwei unabhängige Prüfpunkte.
|
||||
Aussage: Die Komponente soll Anlage- und Löschrecht getrennt und unabhängig voneinander prüfen.
|
||||
Ergebnis: Ein Benutzer kann eines der beiden Rechte besitzen, ohne automatisch auch das andere zu haben.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Warehousing\Commissions\PartialCommissionOrderBL.cs (Zeilen 135, 170, 426, 453) - Begründung: enthält beide unabhängigen Prüfpunkte.
|
||||
Prüfidee: Benutzer mit nur Anlage-Recht versucht Löschung → Ablehnung; umgekehrter Test analog.
|
||||
Tracelinks: SyRS-013
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-022
|
||||
Titel: OrderSuggestionListBL: SQL-Aggregation aus Bestand/Bedarf/Zulauf
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: Komponente OrderSuggestionListBL
|
||||
Vorbedingung: Bestellvorschlagsliste wird berechnet.
|
||||
Fakt: Ca. 10 vordefinierte Roh-SQL-Strings (`_sqlArticle`, `_sqlSpec`, `_sqlOrder`, `_sqlOrderComplete`, `_sqlWH`, `_sqlFreeSpec`, `_sqlFreeArticlePerWH`, `_sqlDistri`, `_sqlLastArticlUse`, `_sqlImprtedPM`, `_sqlAktionsPreis`, `_sqlPPStockIntake`) werden über `Session.Advanced.RawSqlAccess.ExecuteQuery<T>()` gegen Legacy-Tabellen/-Views (`AufPos`, `AufKopf`, `BestPos2`, `BestKopf2`, `Artik`, `NebenlagerArtikel`, `cvw_ArticleCount`, `cvw_ConsignmentArticleQuantity`) ausgeführt.
|
||||
Aussage: Die Komponente soll Bestand, offenen Auftragsbedarf und offenen Bestellzulauf über SQL-Abfragen gegen die produktiven Legacy-Tabellen kombinieren, statt über die NHibernate-ORM-Abstraktion.
|
||||
Ergebnis: Bestellvorschlagsliste enthält je Artikel eine berechnete Nachbestellmenge.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Purchasing\OrderSuggestionList\OrderSuggestionListBL.cs - Begründung: enthält die tatsächlichen SQL-Strings und deren Ausführung.
|
||||
Prüfidee: Vergleich der berechneten Vorschlagsmenge gegen manuell nachgerechneten Erwartungswert für einen Testartikel.
|
||||
Tracelinks: SyRS-014
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround (Legacy-DB-Schema-Abhängigkeit statt ORM)
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-023
|
||||
Titel: EDIDispatcherBL.CreateEDISuggestionOrderAsync Distributor-Dispatch
|
||||
Ebene: SwRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: Komponente EDIDispatcherBL
|
||||
Vorbedingung: EDI-Bestellvorschlag soll an konfigurierten Distributor übermittelt werden.
|
||||
Fakt: Zeilen 56-70 selektieren anhand `ediConfigurations.EdiDataType`/`EDIMultidistributors` den passenden distributorspezifischen Dokumentersteller.
|
||||
Aussage: Die Methode soll den zu verwendenden Dokumentersteller ausschließlich aus der Konfiguration ableiten, ohne fest verdrahtete Distributor-Logik im Aufrufer.
|
||||
Ergebnis: Änderung der Distributor-Konfiguration führt ohne Codeänderung zu korrektem Zielformat.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\EDI\EDIDispatcherBL.cs (Zeilen 56-70) - Begründung: enthält die tatsächliche konfigurationsgesteuerte Dispatch-Logik.
|
||||
Prüfidee: Konfigurationswechsel auf anderen Distributor → anderer Dokumentersteller wird aufgerufen (Unit-Test mit Mock).
|
||||
Tracelinks: SyRS-015
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Block D — Finances
|
||||
|
||||
```
|
||||
ID: SwRS-024
|
||||
Titel: OnlineBankingAccountTransactionsBL.SaveOnlineBankingAccountTransactions Duplikatserkennung
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Komponente OnlineBankingAccountTransactionsBL
|
||||
Vorbedingung: Bankumsatz wird importiert.
|
||||
Fakt: Zeilen 294-340 prüfen auf bereits vorhandene Transaktion mit identischer Kombination aus Konfiguration/Datum/Betrag/IBAN/Beschreibung und geben bei Fund eine Warnung statt eines Fehlers zurück (kein Hard-Reject, sondern Soft-Warnung — Import wird nicht automatisch verhindert).
|
||||
Aussage: Die Methode soll doppelte Transaktionsimporte erkennen und den Anwender warnen; die endgültige Entscheidung über den Doppelimport verbleibt beim Anwender (Soft-Check, kein Hard-Block).
|
||||
Ergebnis: Import einer bereits vorhandenen Transaktion erzeugt eine Warnmeldung.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Finances\OnlineBanking\OnlineBankingAccountTransactionsBL.cs (Zeilen 294-340) - Begründung: Fakturierungs-/Zahlungsverkehrslogik, PRIMÄR-Beleg zwingend und vorhanden.
|
||||
Prüfidee: Identischen Transaktionsdatensatz zweimal importieren → zweiter Import löst Warnung aus; [HYPOTHESE]: ob der Anwender den Doppelimport trotzdem bestätigen kann, wurde nicht bis zur UI-Ebene zurückverfolgt — siehe Hypothesen.md.
|
||||
Tracelinks: SyRS-016
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-025
|
||||
Titel: OnlineBankingAccountTransactionsBL.BookAmountToAssignedInvoice Verbuchungsregel
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: Komponente OnlineBankingAccountTransactionsBL
|
||||
Vorbedingung: Transaktion ist einer Rechnung zugeordnet und soll verbucht werden.
|
||||
Fakt: Zeilen 1042-1086: Verbuchung erfolgt nur, wenn Rechnung `Active` ist, oder `Completed` während eines Undo-Vorgangs, oder der Betrag negativ ist (Rückbuchung/Chargeback); berechnet `newPaidFC` und markiert die Rechnung als bezahlt, sobald `newPaidFC >= DemandedGrossAmount`.
|
||||
Aussage: Die Methode soll eine Verbuchung nur unter den drei definierten Bedingungen zulassen und den Zahlstatus ausschließlich anhand der berechneten Summe, nicht anhand eines einzelnen Zahlungsereignisses, bestimmen.
|
||||
Ergebnis: Verbuchung außerhalb der drei zulässigen Fälle wird nicht durchgeführt; Zahlstatus berücksichtigt kumulierte Zahlungen.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Finances\OnlineBanking\OnlineBankingAccountTransactionsBL.cs (Zeilen 1042-1086) - Begründung: PRIMÄR-Beleg für Fakturierungslogik, durchgesetzte Bedingungsprüfung.
|
||||
Prüfidee: Verbuchungsversuch auf eine bereits `Canceled`-Rechnung mit positivem Betrag → muss abgelehnt werden.
|
||||
Tracelinks: SyRS-016, SyRS-017
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-026
|
||||
Titel: PaymentsBL.DeleteIncomingPayment Rechteprüfung vor Stornierung
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Komponente PaymentsBL
|
||||
Vorbedingung: Erfasste Eingangszahlung soll gelöscht/storniert werden.
|
||||
Fakt: Zeilen 43-44: `if (loggedInUser.User.HasUserRight(UserRightsConst.Controlling.Finances.INCOMING_PAYMENT_TRANSACTIONS) == false) return Result.AsError("Sie haben nicht das Recht 'Zahlungseingang.", DefaultMessageCodes.RightCheckFailed);` — vor jeder weiteren Verarbeitung.
|
||||
Aussage: Die Methode soll die Rechteprüfung als ersten Schritt durchführen, bevor der bezahlte Betrag auf der Rechnung zurückgesetzt wird.
|
||||
Ergebnis: Nicht berechtigter Löschversuch hinterlässt die Rechnung unverändert.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Finances\Payments\PaymentsBL.cs (Zeilen 43-44) - Begründung: PRIMÄR-Beleg, Fakturierungslogik.
|
||||
Prüfidee: Benutzer ohne Recht versucht Löschung → Rechnung/`PaidFC` bleibt exakt unverändert (nicht nur Fehlermeldung prüfen, sondern Datenzustand).
|
||||
Tracelinks: SyRS-016
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-027
|
||||
Titel: ReceiptWebServiceBL berechnet CanChangeDateInInvoices/CanChangeDateInDeliveryLists serverseitig
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Komponente ReceiptWebServiceBL
|
||||
Vorbedingung: Client fragt Berechtigungsstatus für Datumsänderung ab.
|
||||
Fakt: Zeilen 994-1000: `result.CanChangeDateInDeliveryLists = rights.Any(f => f.I3D == UserRightsConst...DeliveryList.CAN_CHANGE_DATE)`; `result.CanChangeDateInInvoices = rights.Any(f => f.I3D == UserRightsConst...Invoice.CAN_CHANGE_DATE)` — Rechte-IDs 20400141 bzw. 20400143.
|
||||
Aussage: Die Komponente soll die Berechtigung serverseitig aus den tatsächlichen Benutzerrechten berechnen und dem Client als Ergebnis übergeben, statt dem Client die Prüfung zu überlassen.
|
||||
Ergebnis: Client erhält ein serverseitig berechnetes Berechtigungsflag, das nicht durch Client-Manipulation veränderbar ist (der Flag-Wert selbst schon; siehe SyRS-018 zur offenen Frage der Durchsetzung im Schreibpfad).
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.WebServices.Core\WebServices\Sales.Receipts\ReceiptWebServiceBL.cs (Zeilen 994-1000) - Begründung: serverseitige Berechnung.
|
||||
Prüfidee: Vergleich der von zwei unterschiedlich berechtigten Testbenutzern gelieferten Flag-Werte.
|
||||
Tracelinks: SyRS-018
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Block E — Security / Rechte / Authentifizierung
|
||||
|
||||
```
|
||||
ID: SwRS-028
|
||||
Titel: AppRightsBL.HasUserRight mit Caching und Fail-Closed-Erweiterung UserRightsExt
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Komponente AppRightsBL / UserRightsExt
|
||||
Vorbedingung: BL-Methode prüft ein Benutzerrecht.
|
||||
Fakt: `AppRightsBL.HasUserRight(appUserI3D, rightID)` liest via `Session.Advanced.Cache.GetOrAdd($"AllRightsFromAppUser{appUserI3D}", ...)` gecachte Rechte-IDs aus SQL gegen `Sichtrus`/`Sichmemb`; `UserRightsExt.HasUserRight` (Erweiterungsmethode) kapselt den Aufruf in try/catch und liefert bei Exception `false`.
|
||||
Aussage: Die Komponenten sollen Rechteprüfungen mit Caching beschleunigen, dabei aber im Fehlerfall (Exception, z. B. DB-Verbindungsproblem) grundsätzlich `false` (kein Recht) statt einer Exception oder eines optimistischen `true` liefern.
|
||||
Ergebnis: Ausnahmesituationen während der Rechteprüfung führen zu Zugriffsverweigerung.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Administration\Rights\AppRightsBL.cs (~Zeile 644) - Begründung: zentrale Prüfimplementierung.
|
||||
- [PRIMÄR] src\backend\Centron.BL\Administration\Rights\UserRightsExt.cs (try/catch → false) - Begründung: sicherheitskritisches Fail-Closed-Verhalten, PRIMÄR-Beleg zwingend und vorhanden.
|
||||
Prüfidee: Rechteprüfung mit simuliertem DB-Fehler → Rückgabewert `false`.
|
||||
Tracelinks: SyRS-019
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-029
|
||||
Titel: UserRightsConst: manuell inkrementierter ID-Zähler für neue Rechte
|
||||
Ebene: SwRS
|
||||
Typ: nicht-funktional
|
||||
Akteur: Entwicklungsteam
|
||||
Vorbedingung: Neues Recht wird der Konstantenklasse hinzugefügt.
|
||||
Fakt: Header-Kommentar "NEW .NET MODULE RIGHTS START AT 20800000 / NEXT ID: 20800174" in `UserRightsConst.cs`; keine automatisierte (z. B. DB-Sequenz-basierte) ID-Vergabe gefunden.
|
||||
Aussage: Die Klasse soll neue Rechte-IDs eindeutig vergeben; der aktuelle Mechanismus (manuell gepflegter Kommentar) erreicht dies nur, solange alle Entwickler diszipliniert den Kommentar aktuell halten.
|
||||
Ergebnis: Eindeutigkeit ist aktuell durch Konvention, nicht durch technischen Zwang sichergestellt.
|
||||
Belege:
|
||||
- [PRIMÄR] src\webservice\Centron.WebServices.Core\EntitiesWrongPlace\Administration\Rights\UserRightsConst.cs (Header-Kommentar) - Begründung: unmittelbarer, technischer Beleg für den Vergabemechanismus.
|
||||
Prüfidee: Code-Review-Historie prüfen: gab es je einen ID-Kollisionsfall bei parallelen Pull-Requests? (retrospektive Prüfidee)
|
||||
Tracelinks: SyRS-020
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-030
|
||||
Titel: AuthenticatorFactory wählt Authentifizierungsverfahren nach Konfiguration
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Komponente AuthenticatorFactory
|
||||
Vorbedingung: Anmeldeversuch wird entgegengenommen.
|
||||
Fakt: `AuthenticatorFactory` liefert eine von `BasicAuthenticator`, `ActiveDirectoryAuthenticator`, `OpenIdConnectAuthenticator`, `WebAccountAuthenticator` (sowie `FailingAuthenticator`/`FallbackAuthenticator` für Fehlerfälle).
|
||||
Aussage: Die Factory soll das zu verwendende Authentifizierungsverfahren eindeutig und konfigurationsgesteuert bestimmen.
|
||||
Ergebnis: Für eine gegebene Konfiguration wird immer dasselbe Verfahren verwendet.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Administration\Logins\Auth\AuthenticatorFactory.cs - Begründung: enthält die tatsächliche Auswahllogik.
|
||||
Prüfidee: Konfigurationswechsel AD → OIDC → Verhalten der Factory ändert sich entsprechend (Unit-Test).
|
||||
Tracelinks: SyRS-021
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-031
|
||||
Titel: BasicAuthenticator verwendet unsalted SHA-1 zur Passwortprüfung [Sicherheitsrisiko]
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Komponente BasicAuthenticator
|
||||
Vorbedingung: Benutzer meldet sich mit Benutzername/Passwort an.
|
||||
Fakt: Zeile 46: `var decodedPassword = SHA1Decoder.GetDecodedSHA1String(Auth.Password.ToString());`, verglichen gegen `AppUser.Password`; Zeile 48 trägt den Code-Kommentar `// TODO the password should be salted!!!`. Implementierung: `src\backend\Centron.Common\TextCoding\SHA1Decoder.cs` — unsalted SHA-1. Derselbe Mechanismus in `UsersBL.cs` (Zeilen 65, 88) bei Passwortänderung.
|
||||
Aussage: Die Komponente soll Passwörter mit einem Verfahren speichern/prüfen, das gegen Rainbow-Table- und GPU-Brute-Force-Angriffe widerstandsfähig ist (z. B. gesalzenes, iteriertes Hashing wie PBKDF2/bcrypt/Argon2). Der aktuelle Zustand (unsalted SHA-1, vom Entwicklerteam selbst als TODO markiert) erfüllt dies **nicht** und stellt eine dokumentierte Sicherheitslücke dar.
|
||||
Ergebnis: Aktuell: identische Passwörter erzeugen identische Hashes ohne Salt, wodurch Rainbow-Table-Angriffe bei DB-Kompromittierung erleichtert werden. Soll-Zustand für Zielsystem: gesalzenes, adaptives Hashverfahren.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Administration\Logins\Auth\BasicAuthenticator.cs (Zeilen 46, 48) - Begründung: unmittelbar durchgesetzte, schwache Hash-Prüfung; Authentifizierung ist höchste Sicherheitsstufe, PRIMÄR-Beleg zwingend und vorhanden.
|
||||
- [PRIMÄR] src\backend\Centron.Common\TextCoding\SHA1Decoder.cs - Begründung: technische Implementierung des unsalted SHA-1.
|
||||
- [KONTEXT] BasicAuthenticator.cs Zeile 48 (Code-Kommentar "TODO the password should be salted!!!") - Begründung: bestätigt, dass das Entwicklerteam die Schwäche selbst kennt, aber noch nicht behoben hat.
|
||||
Prüfidee: Sicherheitsreview/Penetrationstest: identische Testpasswörter zweier Benutzer erzeugen identischen gespeicherten Hash (Nachweis fehlenden Salts).
|
||||
Tracelinks: SyRS-021
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround (bekannte, vom Team selbst markierte Sicherheitslücke — hohe Priorität für Migrationsentscheidung)
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-032
|
||||
Titel: TicketBL: gerätegebundener Salt und konfigurierbare Ablaufzeit für Session-Tickets
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Komponente TicketBL
|
||||
Vorbedingung: Nach erfolgreicher Authentifizierung wird ein Ticket ausgestellt.
|
||||
Fakt: Zeilen 166-169: `CryptoUtils.CreateSalt(32)` + `CryptoUtils.CreatePasswordHash(deviceId, salt)`; Ablaufzeit über `ExpirationKind.FromSettings`/`OneDay`.
|
||||
Aussage: Die Komponente soll jedes Ticket an ein Gerät binden (Salt-basiert) und nach konfigurierbarer Zeit ungültig werden lassen.
|
||||
Ergebnis: Ticket ist nach Ablauf oder bei Verwendung von einem anderen Gerät ungültig.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Administration\Logins\TicketBL.cs (Zeilen 166-169) - Begründung: durchgesetzte Salt-/Ablaufmechanik.
|
||||
Prüfidee: Ticket auf simuliertem Fremdgerät verwenden → Ablehnung; Ticket nach Ablaufzeit verwenden → Ablehnung.
|
||||
Tracelinks: SyRS-021, SyRS-022
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-033
|
||||
Titel: TwoFactorAuthBL: austauschbare Validatoren (E-Mail/RADIUS)
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Komponente TwoFactorAuthBL
|
||||
Vorbedingung: 2FA ist aktiviert und erster Faktor wurde erfolgreich geprüft.
|
||||
Fakt: `TwoFactorAuthBL` orchestriert `ITwoFactorValidator`-Implementierungen (`EmailTwoFactorValidator`, `RadiusTwoFactorValidator` mit eigenem `RadiusClient`/`RadiusPaketParser`); Aktivierung über `WebServiceConfigHelper.Current.TwoFactorAuthEnabled`.
|
||||
Aussage: Die Komponente soll den zweiten Faktor über eine austauschbare Validator-Schnittstelle prüfen, sodass weitere Verfahren ergänzt werden können, ohne die Orchestrierungslogik zu ändern.
|
||||
Ergebnis: Bei aktivierter 2FA wird erst nach erfolgreicher Validator-Prüfung eine vollständige Anmeldung gewährt.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Administration\Logins\TwoFactor\TwoFactorAuthBL.cs, EmailTwoFactorValidator.cs, RadiusTwoFactorValidator.cs - Begründung: durchgesetzte zweite Prüfstufe.
|
||||
Prüfidee: 2FA aktiv, korrekter erster Faktor, falscher zweiter Faktor → Anmeldung wird verweigert.
|
||||
Tracelinks: SyRS-021
|
||||
Konsolidierung: Kandidat: Verhältnis zu separatem Modul `TwoFactorAuthenticator\TwoFactorAuthenticationBL.cs` ungeklärt — siehe Hypothesen.md.
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-034
|
||||
Titel: PasswordManagementAccessLogBL protokolliert jeden Zugriff mit ActionType/Date/EmployeeI3D
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Komponente PasswordManagementAccessLogBL
|
||||
Vorbedingung: Gespeichertes Passwort wird gelesen.
|
||||
Fakt: Bei jedem Zugriff wird ein `PasswordManagementAccessLog`-Datensatz mit `ActionType`, `Date`, `EmployeeI3D` erzeugt, als Teil des Zugriffspfads (nicht optional/deaktivierbar laut Codebefund).
|
||||
Aussage: Die Komponente soll jeden Lesezugriff auf ein gespeichertes Passwort unmittelbar und vollständig protokollieren.
|
||||
Ergebnis: Nach jedem Zugriff existiert ein Protokolleintrag mit Benutzer- und Zeitreferenz.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\PasswordManagementArea\PasswordManagementAccessLogBL.cs - Begründung: durchgesetzte Protokollierung im Zugriffspfad.
|
||||
Prüfidee: Zugriff auf Testpasswort → Protokolleintrag mit korrektem `EmployeeI3D` und aktuellem Zeitstempel.
|
||||
Tracelinks: SyRS-023
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Block F — Web-Kanäle
|
||||
|
||||
```
|
||||
ID: SwRS-035
|
||||
Titel: Getrennte Login-Komponenten CustomerAuthPage / AuthPage / OutlookAuthPage
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Komponente Nexus-Auth-Subsystem
|
||||
Vorbedingung: Benutzer (intern, Kunde oder Outlook-Add-In) meldet sich an Nexus an.
|
||||
Fakt: Drei getrennte Blazor-Seiten (`AuthPage.razor`, `OutlookAuthPage.razor`, `CustomerAuthPage.razor`) mit jeweils eigenem Authentifizierungspfad (`WebAccountAuthenticator` für Kunden).
|
||||
Aussage: Die Komponenten sollen sicherstellen, dass ein Kundenzugang nicht denselben Anmeldepfad wie ein interner Mitarbeiterzugang durchläuft.
|
||||
Ergebnis: Kunde kann sich ausschließlich über `CustomerAuthPage` mit dem `WebAccountAuthenticator`-Pfad anmelden.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Administration\Logins\Auth\WebAccountAuthenticator.cs - Begründung: eigenständiger Authentifizierungspfad.
|
||||
- [SEKUNDÄR] src\nexus\CentronNexus\Shared\Auth\CustomerAuthPage.razor, AuthPage.razor, OutlookAuthPage.razor - Begründung: UI-seitige Bestätigung der Trennung.
|
||||
Prüfidee: Versuch, sich als Kunde über den internen Login-Pfad anzumelden → muss fehlschlagen bzw. ist technisch nicht vorgesehen.
|
||||
Tracelinks: SyRS-024
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-036
|
||||
Titel: WebCartShopPage.razor: [AuthorizeLicense(WebCart2)] als serverseitige Blazor-Server-Prüfung
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Komponente WebCartShopPage
|
||||
Vorbedingung: Web-Account ruft die WebCart-Shop-Seite auf.
|
||||
Fakt: Attribut `[AuthorizeLicense(nameof(LicenseGuids.WebCart2))]` auf der Seite; Blazor Server führt die Seitenlogik serverseitig aus (kein clientseitig umgehbarer WebAssembly-Code).
|
||||
Aussage: Die Komponente soll den Seitenaufruf bereits serverseitig verweigern, bevor Seiteninhalte an den Client übertragen werden.
|
||||
Ergebnis: Client ohne gültige Lizenz erhält keine Shop-Inhalte, unabhängig vom Aufrufweg (Navigation oder direkter URL-Aufruf).
|
||||
Belege:
|
||||
- [PRIMÄR] src\nexus\CentronNexus\WebCart\WebCartShopPage.razor (Attribut) - Begründung: serverseitig wirksame Zugriffsprüfung im Blazor-Server-Modell.
|
||||
Prüfidee: Direkter URL-Aufruf `/webcart/shop` ohne Lizenz → keine Artikel-/Preisdaten werden übertragen (Netzwerk-Mitschnitt).
|
||||
Tracelinks: SyRS-025
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-037
|
||||
Titel: CurrentCartService bindet Warenkorb an Sitzung/Kunde
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: Komponente CurrentCartService
|
||||
Vorbedingung: Kunde nutzt WebCart-Warenkorb.
|
||||
Fakt: `ICurrentCartService` wählt den aktuellsten `ReceiptCartDTO` des Kunden oder legt automatisch einen neuen an (`CreateNewReceiptCart`), ohne dass der Kunde explizit einen Warenkorb anlegen muss.
|
||||
Aussage: Die Komponente soll jedem Kunden automatisch genau einen aktiven Warenkorb zuordnen, ohne manuellen Anlageschritt.
|
||||
Ergebnis: Kunde findet beim Aufruf von WebCart stets einen nutzbaren Warenkorb vor.
|
||||
Belege:
|
||||
- [PRIMÄR] src\nexus\CentronNexus\WebCart\Helpers\CurrentCartService.cs - Begründung: enthält die tatsächliche Auswahl-/Anlagelogik.
|
||||
Prüfidee: Erster Aufruf ohne bestehenden Warenkorb → neuer Warenkorb wird automatisch angelegt und zurückgegeben.
|
||||
Tracelinks: SyRS-025
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-038
|
||||
Titel: CI/CD-Pipeline build.yml erzeugt und signiert alle Auslieferungsartefakte
|
||||
Ebene: SwRS
|
||||
Typ: nicht-funktional
|
||||
Akteur: CI/CD-Komponente (GitHub Actions)
|
||||
Vorbedingung: Push/Merge auf relevanten Branch.
|
||||
Fakt: `.github\workflows\build.yml` baut WPF-Client, Web-Service-Host (+Connection Manager) und Nexus-Host, erzeugt WiX-MSIs bzw. Docker-Image, verifiziert Authenticode-Signaturen, lädt Artefakte in die "SoftwareBuilds"-Umgebung hoch.
|
||||
Aussage: Die Pipeline soll bei jedem relevanten Push alle drei Artefakttypen ohne manuellen Eingriff bauen, signieren und verifizieren.
|
||||
Ergebnis: Nach jedem erfolgreichen Pipeline-Lauf liegen signierte, verifizierte Artefakte vor.
|
||||
Belege:
|
||||
- [PRIMÄR] .github\workflows\build.yml - Begründung: enthält den tatsächlichen automatisierten Ablauf.
|
||||
- [SEKUNDÄR] docker\Dockerfile, deployment\centron\*\Product.wxs - Begründung: konkrete Paketierungsdefinitionen, die die Pipeline referenziert.
|
||||
Prüfidee: Pipeline-Lauf beobachten: Signaturverifikation muss für alle drei Artefakte grün sein, sonst Pipeline-Abbruch.
|
||||
Tracelinks: SyRS-026, SyRS-027
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Block G — Externe Integrationen (leichtere Analysetiefe)
|
||||
|
||||
```
|
||||
ID: SwRS-039
|
||||
Titel: ITscopeApi kapselt HTTP-Statuscodes in clientspezifische Exceptions
|
||||
Ebene: SwRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: Komponente ITscopeApi
|
||||
Vorbedingung: Externer Aufruf an itscope.com liefert einen Fehlerstatus.
|
||||
Fakt: Zeilen 293-314: `HttpStatusCode.Unauthorized` → `ITscopeException("Der API-Key ist ungültig.")`; `HttpStatusCode.NotFound` → leeres Ergebnis (Soft-Fail, kein Retry).
|
||||
Aussage: Die Komponente soll HTTP-Fehlerstatuscodes in aussagekräftige, deutschsprachige Exceptions bzw. definiertes Leerergebnis übersetzen, statt die rohe HTTP-Exception weiterzureichen.
|
||||
Ergebnis: Aufrufende Module erhalten eine domänenspezifische Fehlerauskunft statt eines rohen `WebException`.
|
||||
Belege:
|
||||
- [PRIMÄR] src\apis\Centron.APIs.ITscopeDataAccess\ITscopeApi.cs (Zeilen 293-314) - Begründung: durchgesetzte Fehlerübersetzung.
|
||||
Prüfidee: Simulierter 401-Response → `ITscopeException` mit definierter Meldung; simulierter 404 → leere Liste statt Exception.
|
||||
Tracelinks: SyRS-028
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-040
|
||||
Titel: DocuFormRestApiClient: OAuth2-Token-Beschaffung vor jedem Geräteabruf
|
||||
Ebene: SwRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: Komponente DocuFormRestApiClient
|
||||
Vorbedingung: Geräte-/Zählerdaten sollen von docuFORM abgerufen werden.
|
||||
Fakt: `OAuthHelper` (`RequestAuthorization`/`RequestToken`) beschafft ein OAuth2-Token gegen `/auth/v2/token`, bevor Aufrufe gegen `/dfmserver/v2/devices` erfolgen; `SocketsHttpHandler { MaxConnectionsPerServer = 20 }` begrenzt die Verbindungsanzahl.
|
||||
Aussage: Die Komponente soll vor jedem Datenabruf ein gültiges OAuth2-Token sicherstellen und die Anzahl gleichzeitiger Verbindungen zum externen Dienst begrenzen.
|
||||
Ergebnis: Geräteabruf erfolgt nur mit gültigem Token; Verbindungsanzahl zum externen Dienst bleibt begrenzt.
|
||||
Belege:
|
||||
- [PRIMÄR] src\apis\Centron.Api.docuFORM\DocuFormRestApiClient.cs, DocuFormRestApiConstants.cs - Begründung: durchgesetzter Token-Beschaffungspfad und Verbindungslimit.
|
||||
Prüfidee: Abruf mit abgelaufenem Token → automatische Erneuerung vor erneutem Versuch (bzw. [HYPOTHESE], falls kein automatischer Retry gefunden — siehe Hypothesen.md).
|
||||
Tracelinks: SyRS-028
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
+548
@@ -0,0 +1,548 @@
|
||||
# System Requirements Specification (SyRS)
|
||||
|
||||
Ebene: Systemverhalten, Schnittstellen, Performance-, Sicherheitsanforderungen. Nicht-funktionale Anforderungen sind zusätzlich einem Qualitätsmerkmal nach **ISO/IEC 25010** zugeordnet (Feld `ISO25010`). Tracelinks verweisen rückwärts auf StRS und vorwärts auf SwRS.
|
||||
|
||||
---
|
||||
|
||||
## Block A — Belegkette / Order-to-Cash (System-Ebene)
|
||||
|
||||
```
|
||||
ID: SyRS-001
|
||||
Titel: Einheitliche Beleg-Verarbeitungs-Engine für alle Belegarten
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: Web-Service (BL-Schicht)
|
||||
Vorbedingung: Ein Beleg beliebiger Art (Angebot/Auftrag/Lieferschein/Rechnung/Gutschrift) liegt zur Verarbeitung vor.
|
||||
Fakt: `ReceiptBL` ist die einzige Verarbeitungsklasse für alle Belegarten; belegartspezifisches Verhalten wird über `IReceiptSpecificLogic`-Implementierungen (Strategy-Pattern) injiziert statt über belegartspezifische Subklassen von `ReceiptBL` selbst.
|
||||
Aussage: Das System soll Änderungen an gemeinsamer Belegverarbeitungslogik (z. B. Validierung, Statuswechsel) zentral an einer Stelle implementieren und über alle Belegarten hinweg konsistent wirksam werden lassen, ohne belegartspezifischen Code zu duplizieren.
|
||||
Ergebnis: Eine Änderung in `ReceiptBL` wirkt sich konsistent auf Angebot, Auftrag, Lieferschein, Rechnung usw. aus.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs - Begründung: zentrale, tatsächlich für alle Belegarten aufgerufene Verarbeitungsklasse.
|
||||
- [SEKUNDÄR] src\backend\Centron.Interfaces\Sales.Receipts (IReceiptSpecificLogic und Implementierungen) - Begründung: belegt das Strategy-Pattern als Erweiterungsmechanismus.
|
||||
Prüfidee: Code-Review: Suche nach belegartspezifischer if/else- oder switch-Verzweigung innerhalb `ReceiptBL` außerhalb der `IReceiptSpecificLogic`-Aufrufe (sollte nicht signifikant vorkommen).
|
||||
Tracelinks: StRS-001; SwRS-001, SwRS-002
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-002
|
||||
Titel: Konsistente Statuspersistenz über Belegarten hinweg (Datenintegrität)
|
||||
Ebene: SyRS
|
||||
Typ: Daten
|
||||
Akteur: Web-Service (BL-Schicht) / Datenbank
|
||||
Vorbedingung: Beleg wird gespeichert oder automatisch weiterverarbeitet.
|
||||
Fakt: Alle Belegarten nutzen denselben `ReceiptState`-Enumwert (Active/Completed/Canceled); der Zustandswechsel wird zentral in `AutomaticallyCloseReceiptHelperBL` anhand von Restmengen berechnet statt dezentral je Belegart.
|
||||
Aussage: Das System soll den Belegstatus als gemeinsames, für alle Belegarten identisch strukturiertes Datenfeld führen, damit modulübergreifende Auswertungen (z. B. "alle offenen Belege") ohne belegartspezifische Sonderlogik möglich sind.
|
||||
Ergebnis: Abfragen über `ReceiptState` liefern für alle Belegarten konsistente, vergleichbare Ergebnisse.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.Interfaces\Sales.Receipts\ReceiptState.cs - Begründung: ein einziges, geteiltes Enum für alle Belegarten.
|
||||
- [SEKUNDÄR] src\backend\Centron.BL\Sales\Receipts\Internal\AutomaticallyCloseReceiptHelperBL.cs - Begründung: zentrale Berechnungslogik statt Duplikation je Belegart.
|
||||
Prüfidee: Datenbankabfrage über alle Belegtabellen mit `ReceiptState`-Spalte liefert konsistente Wertemenge {1,2,3}.
|
||||
Tracelinks: StRS-001, StRS-005; SwRS-003
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-003
|
||||
Titel: Zeitlich befristete, einmalig gültige Signier-Tokens für Web-Dokumentenfreigabe
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Web-Service / Kunde (anonym, tokenbasiert)
|
||||
Vorbedingung: Ein Angebot/Dokument wurde zur Kundensignatur freigegeben.
|
||||
Fakt: `SharedDocumentBL.GenerateTokenForDocument` verweigert die Erzeugung eines neuen Tokens, solange bereits ein aktiver, unsignierter Vorgang für denselben Beleg existiert ("Es existiert bereits ein aktiver Signierungs-Ablauf"); das Ablaufdatum wird aus `SharedDocumentSettingsDTO.OfferSignExpiredDateCount` berechnet.
|
||||
Aussage: Das System soll für jeden Beleg zu jedem Zeitpunkt höchstens einen aktiven, nicht abgelaufenen Signiervorgang zulassen und den Gültigkeitszeitraum konfigurierbar begrenzen.
|
||||
Ergebnis: Zweiter Signieranstoß für denselben Beleg bei bestehendem aktivem Vorgang wird abgelehnt; abgelaufene Tokens sind nicht mehr nutzbar.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Administration\FileManagement\SharedDocumentBL.cs (GenerateTokenForDocument, Zeilen 128-130) - Begründung: durchgesetzte Ein-Vorgang-Regel, hochkritisch für Rechtsverbindlichkeit der Angebotsannahme → PRIMÄR-Beleg vorhanden.
|
||||
Prüfidee: Zweiten Signiervorgang für denselben Beleg anstoßen, während erster aktiv ist → Ablehnung mit definierter Fehlermeldung.
|
||||
Tracelinks: StRS-002; SwRS-004
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-004
|
||||
Titel: Serverseitige Ablehnung abgelaufener oder bereits verwendeter Signier-Tokens
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Web-Service
|
||||
Vorbedingung: Ein Token für einen Signiervorgang wird per öffentlichem Link aufgerufen.
|
||||
Fakt: `SharedDocumentBL.GetSharedDocumentByToken` prüft `ExpiredDate < DateTime.Now` → Fehler "Die Signierungsanfrage ist bereits abgelaufen."; und `IsSigned == true` → Fehler "Dokument wurde bereits signiert.".
|
||||
Aussage: Das System soll bei jedem Zugriff auf einen Signier-Link serverseitig sowohl Ablauf als auch Mehrfachnutzung prüfen, unabhängig davon, ob der Client (Browser) diese Prüfung bereits vorgenommen hat.
|
||||
Ergebnis: Zugriff mit abgelaufenem oder bereits verwendetem Token wird serverseitig abgelehnt.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Administration\FileManagement\SharedDocumentBL.cs (GetSharedDocumentByToken, Zeilen 405-409) - Begründung: serverseitige, nicht umgehbare Prüfung vor Auslieferung sensibler Vertragsdaten.
|
||||
Prüfidee: Abgelaufenen Token direkt per HTTP-Request aufrufen (ohne UI) → Server muss ablehnen.
|
||||
Tracelinks: StRS-002; SwRS-005, SwRS-006
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-005
|
||||
Titel: Datenbankseitig durchgesetzte Unveränderlichkeit festgeschriebener Rechnungen
|
||||
Ebene: SyRS
|
||||
Typ: Daten
|
||||
Akteur: Datenbank / Web-Service
|
||||
Vorbedingung: Rechnung mit `IsFixed = 1` liegt vor.
|
||||
Fakt: Spalte `RechKopf.IsFixed` ist als `NOT NULL DEFAULT(0)` per Migrationsskript definiert; die Anwendungslogik (`ReceiptInvoiceBL.FixInvoice`) ist der einzige Pfad, der das Flag auf 1 setzt, und lehnt danach jede erneute Festschreibung ab.
|
||||
Aussage: Das System soll den Festschreibungsstatus einer Rechnung als verpflichtendes, nicht auf NULL setzbares Datenbankfeld führen, sodass der Zustand "nicht festgeschrieben" niemals unspezifiziert (NULL) sein kann.
|
||||
Ergebnis: `IsFixed` ist für jede Rechnung eindeutig 0 oder 1, niemals unbestimmt.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Administration\Scripts\ScriptMethods\SqlStatements\SQLScriptCollection2.xml (Skript #10208) - Begründung: technischer DB-Constraint, höchste Evidenzstufe für sicherheits-/buchführungsrelevante Anforderung.
|
||||
Prüfidee: Direkter INSERT ohne Angabe von `IsFixed` gegen Testdatenbank → DB muss Default 0 setzen, NULL darf nicht möglich sein.
|
||||
Tracelinks: StRS-003; SwRS-007, SwRS-008
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-006
|
||||
Titel: Zentrale, wiederverwendete Steuerberechnungskomponente
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: Web-Service (alle Clients: WPF, Nexus, API)
|
||||
Vorbedingung: Beleg mit Positionen und Steuersätzen liegt in beliebigem Client vor.
|
||||
Fakt: `CalculationUtils.CalculateTaxTotalPrice`/`CalculateGrossPrice` liegt in `Centron.Interfaces` (nicht client-spezifisch) und wird laut Recherche von allen Belegarten verwendet; Rundung ist explizit `MidpointRounding.AwayFromZero` mit 2 Nachkommastellen.
|
||||
Aussage: Das System soll die Umsatzsteuerberechnung in genau einer Komponente kapseln, die von allen Clients (Desktop, Web, API) und allen Belegarten aufgerufen wird, um abweichende Rundungs- oder Berechnungsergebnisse zwischen Clients zu verhindern.
|
||||
Ergebnis: Identische Eingabewerte (Netto, Steuersatz, Rabatt, Währungsfaktor) liefern client-unabhängig identische Steuer-/Bruttobeträge.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.Interfaces\DataExchange.BookKeeping\CalculationUtils.cs - Begründung: einzige, geteilte Implementierung, keine Duplikate pro Client identifiziert.
|
||||
Prüfidee: Gleiche Testwerte über WPF-Client und Nexus-Web-Client eingeben → identisches Ergebnis.
|
||||
Tracelinks: StRS-004; SwRS-009, SwRS-010
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Block B — Helpdesk / RMA / Automatisierung (System-Ebene)
|
||||
|
||||
```
|
||||
ID: SyRS-007
|
||||
Titel: Serverseitige, client-unabhängige Autorisierung von Ticket-Operationen
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Web-Service
|
||||
Vorbedingung: Eine Ticket-Änderungsoperation (Anlage/Bearbeitung/Schließen) wird angestoßen, gleich über welchen Client.
|
||||
Fakt: `HelpdeskBL.CheckUserRigths` wird im Speicherpfad (`Save`/`DoBeforeSave`) aufgerufen, also serverseitig im BL, unabhängig davon, ob der Aufruf vom WPF-Client, von Nexus oder von der API kommt.
|
||||
Aussage: Das System soll jede Ticket-Änderungsoperation unabhängig vom aufrufenden Client an derselben zentralen serverseitigen Rechteprüfung vorbeiführen.
|
||||
Ergebnis: Ein direkter API-Aufruf ohne UI unterliegt denselben Rechteprüfungen wie eine UI-Aktion.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs (Save/DoBeforeSave, CheckUserRigths) - Begründung: Prüfung liegt in der BL-Schicht, nicht im UI-Code.
|
||||
Prüfidee: Direkter API-Aufruf zum Schließen eines Tickets ohne `CLOSE_REQUEST`-Recht → serverseitige Ablehnung.
|
||||
Tracelinks: StRS-006, StRS-009; SwRS-011, SwRS-012
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-008
|
||||
Titel: Ergebnismengen-Filterung nach einschränkenden Rechten (Datenscoping)
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Web-Service
|
||||
Vorbedingung: Benutzer mit einschränkendem Recht (nur eigene/nur eigene Filiale/nur eigene Abteilung) fragt eine Ticketliste ab.
|
||||
Fakt: `HelpdeskBL.GetLoggedInUserShowHelpdeskRight` bestimmt die anzuwendende Sichtbarkeits-Einschränkung und wird beim Aufbau der Abfrage (nicht erst beim clientseitigen Filtern der vollständigen Liste) berücksichtigt.
|
||||
Aussage: Das System soll einschränkende Rechte bereits auf Ebene der Datenbankabfrage anwenden und nicht erst nach Auslieferung der vollständigen Ergebnismenge an den Client filtern, um ungewollte Datenexposition zu vermeiden.
|
||||
Ergebnis: Die vom Server ausgelieferte Ergebnismenge enthält von vornherein nur die für den Benutzer zulässigen Datensätze.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs (GetLoggedInUserShowHelpdeskRight, Zeilen ~271-284) - Begründung: Filterlogik ist Teil der Abfragekonstruktion, nicht nachgelagert.
|
||||
Prüfidee: Netzwerk-Mitschnitt einer Listenabfrage eines eingeschränkten Benutzers → Antwortdaten dürfen keine unzulässigen Datensätze enthalten (nicht nur UI-Ausblendung).
|
||||
Tracelinks: StRS-006, StRS-007; SwRS-013
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-009
|
||||
Titel: Referenzielle Pflichtverknüpfung von RMA-Vorgängen an Tickets
|
||||
Ebene: SyRS
|
||||
Typ: Daten
|
||||
Akteur: Web-Service
|
||||
Vorbedingung: Ein RMA-Vorgang wird gespeichert.
|
||||
Fakt: `RmaBL.SaveRma` wirft `ResultException("Rma not coneccted to helpdesk", DependencyCheckFailed)`, wenn `rma.HelpdeskI3D <= 0`.
|
||||
Aussage: Das System soll einen RMA-Datensatz ohne gültige Ticketreferenz nicht persistieren.
|
||||
Ergebnis: Jeder gespeicherte RMA-Datensatz hat eine gültige `HelpdeskI3D`-Referenz > 0.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\CustomerArea\RmaBL.cs (SaveRma, Zeile ~352-353) - Begründung: harte Exception verhindert Persistierung ohne Verknüpfung.
|
||||
Prüfidee: Speicherversuch eines RMA mit `HelpdeskI3D = 0` → `ResultException` mit Code `DependencyCheckFailed`.
|
||||
Tracelinks: StRS-008; SwRS-014, SwRS-015
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-010
|
||||
Titel: Verteiltes Sperren zur Vermeidung doppelter Aufgabenausführung
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional
|
||||
ISO25010: Zuverlässigkeit (Fehlertoleranz)
|
||||
Akteur: Web-Service (mehrere Instanzen/Prozesse möglich)
|
||||
Vorbedingung: Eine fällige wiederkehrende Aufgabe wird ggf. von mehreren Prozessen gleichzeitig ausgewertet.
|
||||
Fakt: `TaskManagementTaskBL.ExecuteTask` erwirbt vor Ausführung ein exklusives, transaktionsgebundenes DB-Lock über `sp_getapplock` (`@LockMode = 'Exclusive'`, `@LockTimeout = 0`).
|
||||
Aussage: Das System soll bei mehreren parallel laufenden Prozessinstanzen sicherstellen, dass eine fällige wiederkehrende Aufgabe (z. B. automatische Ticketerstellung) genau einmal ausgeführt wird.
|
||||
Ergebnis: Bei gleichzeitiger Auswertung derselben Aufgabe durch zwei Prozesse erhält nur einer das Lock und führt aus.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\TaskManager\TaskManagementTaskBL.cs (ExecuteTask, sp_getapplock-SQL) - Begründung: DB-seitig durchgesetzter Sperrmechanismus, nicht nur In-Process-Lock (würde bei mehreren Prozessen/Servern versagen).
|
||||
Prüfidee: Simultane Ausführung derselben Aufgabe aus zwei Prozessen → nur eine Ausführung erfolgreich, zweite erhält Lock-Timeout.
|
||||
Tracelinks: StRS-009; SwRS-016, SwRS-017
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Block C — Warehousing / Purchasing (System-Ebene)
|
||||
|
||||
```
|
||||
ID: SyRS-011
|
||||
Titel: Feldgranulare, serverseitige Schreibautorisierung auf Artikelstammdaten
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Web-Service
|
||||
Vorbedingung: Artikel wird gespeichert, unabhängig vom Client.
|
||||
Fakt: `ArticleBL.CheckUserRightBeforeSave`/`CheckSpecialUserRightBeforeSave` prüfen einzelne Felder (Preis, Barcode-Pflicht, Warengruppe) getrennt und setzen bei fehlendem Recht den ursprünglichen DB-Wert zurück, statt den gesamten Speichervorgang abzulehnen.
|
||||
Aussage: Das System soll Schreibrechte auf Artikelfeld-Ebene (nicht nur auf Entitäts-Ebene) prüfen, damit ein Benutzer mit Teilrechten einen Artikel speichern kann, ohne versehentlich geschützte Felder zu verändern.
|
||||
Ergebnis: Nicht berechtigte Feldänderungen werden stillschweigend verworfen, berechtigte Felder werden trotzdem gespeichert.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Warehousing\ArticleBL.cs (CheckUserRightBeforeSave Zeilen 991-1055, CheckSpecialUserRightBeforeSave Zeilen 1058-1089) - Begründung: granulare, im BL durchgesetzte Feldprüfung.
|
||||
Prüfidee: Benutzer mit Recht "Artikel bearbeiten", aber ohne `CHANGE_ARTICLE_PRICE`, ändert Preis und Beschreibung gleichzeitig → Beschreibung wird gespeichert, Preis bleibt unverändert.
|
||||
Tracelinks: StRS-010; SwRS-018
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-012
|
||||
Titel: Regelbasierte Klassifikation von Inventurabweichungen
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: Web-Service
|
||||
Vorbedingung: Inventurzählung einer Position ist erfasst.
|
||||
Fakt: `InventoryBL` berechnet pro Position einen `CloseState` (Counted/Ok/Risk/problem) aus Differenz zwischen Zähl- und Sollmenge sowie Barcode-Zustandskonflikten; dieselbe Klassifikationslogik existierte zuvor dupliziert in der inzwischen deaktivierten `Storage\StorageBL.cs`.
|
||||
Aussage: Das System soll jede Inventurposition automatisiert in eine der definierten Abweichungskategorien einordnen, damit Positionen mit Risiko/Problem gezielt nachbearbeitet werden können, bevor die Inventur abgeschlossen wird.
|
||||
Ergebnis: Jede Inventurposition hat nach Zählung einen gültigen `CloseState`-Wert.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Warehousing\InventoryManagement\InventoryBL.cs (Zeilen ~694-750) - Begründung: aktuell aktive, technisch durchgesetzte Klassifikationslogik.
|
||||
- [KONTEXT] src\backend\Centron.BL\Storage\StorageBL.cs (auskommentiert) - Begründung: dokumentiert Vorgängerimplementierung derselben Regel, nur historischer Beleg.
|
||||
Prüfidee: Position mit Zählmenge ≠ Sollmenge und ohne Barcode-Konflikt → `CloseState = Risk`, keine Freigabe als "Ok".
|
||||
Tracelinks: StRS-011; SwRS-019, SwRS-020
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-013
|
||||
Titel: Konsistente Rechteprüfung für Kommissionierungsvorgänge über Module hinweg
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Web-Service
|
||||
Vorbedingung: Teilkommissionierung eines Auftrags wird angelegt/gelöscht.
|
||||
Fakt: `PartialCommissionOrderBL` prüft an vier Stellen (Zeilen 135, 170, 426, 453) konsistent dieselben Rechte-Konstanten vor Anlage/Löschung.
|
||||
Aussage: Das System soll Anlage und Löschung einer Teilkommissionierung jeweils eigenständig und unabhängig voneinander autorisieren, sodass ein Recht zum Anlegen nicht implizit auch das Löschen erlaubt.
|
||||
Ergebnis: Benutzer mit `CREATE_PARTIAL_COMMISSION_FOR_ORDER`, aber ohne `DELETE_PARTIAL_COMMISSION_FOR_ORDER`, kann anlegen, aber nicht löschen.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Warehousing\Commissions\PartialCommissionOrderBL.cs (Zeilen 135, 170, 426, 453) - Begründung: getrennte Prüfpunkte für Anlage und Löschung im Code.
|
||||
Prüfidee: Benutzer mit nur Anlage-Recht versucht Löschung → Ablehnung.
|
||||
Tracelinks: StRS-012; SwRS-021
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-014
|
||||
Titel: Mehrquellen-Aggregation für Bestellvorschlagsberechnung
|
||||
Ebene: SyRS
|
||||
Typ: Daten
|
||||
Akteur: Web-Service
|
||||
Vorbedingung: Bestand, Mindestbestand, offene Aufträge und offene Bestellungen liegen für einen Artikel vor.
|
||||
Fakt: `OrderSuggestionListBL` kombiniert ca. 10 separate SQL-Abfragen (Bestand je Lager, offener Auftragsbedarf, offener Bestellzulauf, Sonderpreise) zu einer Gesamtvorschlagsliste; ausgeführt über `RawSqlAccess.ExecuteQuery<T>`, nicht über die NHibernate-ORM-Abstraktion.
|
||||
Aussage: Das System soll Bestellvorschläge aus mehreren, potenziell inkonsistenten Datenquellen (Bestand, Bedarf, Zulauf) zu einem konsistenten Zeitpunkt aggregieren.
|
||||
Ergebnis: Vorschlagsliste spiegelt einen in sich konsistenten Datenstand wider (keine Vermischung unterschiedlicher Zeitpunkte je Teilabfrage).
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Purchasing\OrderSuggestionList\OrderSuggestionListBL.cs - Begründung: enthält die tatsächliche Aggregationslogik.
|
||||
Prüfidee: Lasttest: Bestellvorschlagsberechnung während gleichzeitiger Bestandsbuchung → Ergebnis muss nachvollziehbar einem Zeitpunkt zuordenbar sein (Konsistenzprüfung, ggf. [HYPOTHESE] bzgl. Transaktionsisolationsstufe, siehe Hypothesen.md).
|
||||
Tracelinks: StRS-013; SwRS-022
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround (starke Kopplung an Legacy-DB-Schema statt ORM-Abstraktion)
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-015
|
||||
Titel: Pluggable-Adapter für distributorspezifische EDI-Dokumentformate
|
||||
Ebene: SyRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: Web-Service
|
||||
Vorbedingung: Bestellvorschlag soll an einen konfigurierten Distributor übermittelt werden.
|
||||
Fakt: `EDIDispatcherBL.CreateEDISuggestionOrderAsync` selektiert anhand `EDIMultidistributors`/`EdiDataType` aus der Konfiguration den passenden Dokumentersteller (ALSO, EGIS, Komsa, Alltron, ITScope, OpenTrans 2.1).
|
||||
Aussage: Das System soll das Format des erzeugten Bestelldokuments ausschließlich anhand der hinterlegten Konfiguration bestimmen, sodass ein neuer Distributor durch Hinzufügen eines Adapters unterstützt werden kann, ohne bestehende Adapter zu verändern.
|
||||
Ergebnis: Distributor-Konfigurationswechsel führt ohne Codeänderung zu korrektem Zielformat.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\EDI\EDIDispatcherBL.cs (Zeilen 56-70) - Begründung: enthält die tatsächliche, konfigurationsgesteuerte Auswahllogik.
|
||||
Prüfidee: Konfiguration auf "ITScope" umstellen → erzeugtes Dokument muss ITScope-spezifisches Format aufweisen, ohne Codeänderung.
|
||||
Tracelinks: StRS-014; SwRS-023
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Block D — Finances (System-Ebene)
|
||||
|
||||
```
|
||||
ID: SyRS-016
|
||||
Titel: Autorisierung und Idempotenz bei sicherheitskritischen Zahlungsoperationen
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Web-Service
|
||||
Vorbedingung: Zahlungstransaktion wird importiert oder eine erfasste Zahlung gelöscht.
|
||||
Fakt: `OnlineBankingAccountTransactionsBL.SaveOnlineBankingAccountTransactions` weist Duplikate (gleiche Konfiguration/Datum/Betrag/IBAN/Beschreibung) ab; `PaymentsBL.DeleteIncomingPayment` prüft das Recht `INCOMING_PAYMENT_TRANSACTIONS`, bevor eine Zahlung storniert wird — beides Kernoperationen der Zahlungsabwicklung.
|
||||
Aussage: Das System soll sicherheitskritische Zahlungsoperationen (Import, Löschung) sowohl gegen Mehrfachausführung (Idempotenz) als auch gegen fehlende Berechtigung serverseitig absichern, da Fehler hier unmittelbaren finanziellen Schaden verursachen können.
|
||||
Ergebnis: Doppelter Transaktionsimport wird abgewiesen; Löschung ohne Recht wird abgewiesen.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Finances\OnlineBanking\OnlineBankingAccountTransactionsBL.cs (SaveOnlineBankingAccountTransactions, Zeilen 294-340) - Begründung: hohe Kritikalität (Fakturierung/Zahlungsverkehr) erfordert PRIMÄR-Beleg, vorhanden als durchgesetzte Duplikatsprüfung.
|
||||
- [PRIMÄR] src\backend\Centron.BL\Finances\Payments\PaymentsBL.cs (Zeilen 43-44) - Begründung: durchgesetzte Rechteprüfung vor irreversibler Finanzoperation.
|
||||
Prüfidee: Duplikat-Importtest sowie Lösch-Test ohne Recht (siehe StRS-015/016 für Details).
|
||||
Tracelinks: StRS-015, StRS-016; SwRS-024, SwRS-025, SwRS-026
|
||||
Konsolidierung: Kandidat: SyRS-017 (beide betreffen Zahlungsverbuchung)
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-017
|
||||
Titel: Toleranzbasierter Abgleich von Zahlungsbeträgen mit Belegforderung
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: Web-Service
|
||||
Vorbedingung: Bankumsatz ist einer offenen Rechnung zugeordnet.
|
||||
Fakt: `BookAmountToAssignedInvoice` (Zeilen ~1042-1086) verbucht nur bei Rechnungsstatus `Active` (oder `Completed` beim Undo, oder negativem Betrag als Rückbuchung) und markiert die Rechnung als bezahlt, sobald `PaidFC >= DemandedGrossAmount`; an anderer Stelle im Modul wird eine Tolerenz von 0,1 für Abschlussvergleiche verwendet (`CheckForCompleted`).
|
||||
Aussage: Das System soll den Zahlstatus eines Belegs aus der Summe zugeordneter Zahlungen unter Berücksichtigung einer definierten Toleranz automatisch ableiten, statt exakte Centgleichheit zu verlangen.
|
||||
Ergebnis: Rechnung mit vollständig zugeordnetem Betrag (innerhalb Toleranz) wird automatisch als bezahlt markiert.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Finances\OnlineBanking\OnlineBankingAccountTransactionsBL.cs (BookAmountToAssignedInvoice, CheckForCompleted) - Begründung: durchgesetzte Verbuchungs- und Toleranzlogik.
|
||||
Prüfidee: Zahlung mit Differenz 0,05 zur Forderung → Rechnung wird als bezahlt markiert; Differenz 0,20 → nicht.
|
||||
Tracelinks: StRS-015; SwRS-025
|
||||
Konsolidierung: Kandidat: SyRS-016
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-018
|
||||
Titel: Serverseitige Durchsetzung feldspezifischer Rechte auf Abrechnungsdaten
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Web-Service
|
||||
Vorbedingung: Änderung des Abrechnungsdatums einer Rechnung/eines Lieferscheins wird angestoßen.
|
||||
Fakt: `ReceiptWebServiceBL` berechnet `CanChangeDateInInvoices`/`CanChangeDateInDeliveryLists` serverseitig aus den Rechten des angemeldeten Benutzers (Zeilen 994-1000); die WPF-Oberfläche (`TimerBillingSettingsPageViewModel`) verwendet dieses serverseitig berechnete Ergebnis lediglich zur Anzeige.
|
||||
Aussage: Das System soll die Berechtigung zum Ändern von Abrechnungsdaten serverseitig ermitteln und durchsetzen; eine reine UI-seitige Deaktivierung des Eingabefelds genügt nicht als alleinige Kontrolle.
|
||||
Ergebnis: Ein direkter API-Aufruf zur Datumsänderung ohne serverseitiges Recht wird abgelehnt, unabhängig vom UI-Zustand.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.WebServices.Core\WebServices\Sales.Receipts\ReceiptWebServiceBL.cs (Zeilen 994-1000) - Begründung: serverseitige Berechnung, nicht nur Client-Anzeige.
|
||||
Prüfidee: Direkter Web-Service-Aufruf zur Datumsänderung ohne Recht (unter Umgehung der UI) → muss serverseitig abgelehnt werden. [HYPOTHESE]: Ob der eigentliche Schreibpfad (nicht nur die Anzeige-Flags) diese Prüfung ebenfalls erzwingt, wurde im Rahmen dieser Iteration nicht bis zur konkreten Save-Methode zurückverfolgt — siehe Hypothesen.md.
|
||||
Tracelinks: StRS-017; SwRS-027
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Block E — Security / Rechte / Authentifizierung (System-Ebene)
|
||||
|
||||
```
|
||||
ID: SyRS-019
|
||||
Titel: Zentraler, gecachter Autorisierungsdienst für alle BL-Module
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Web-Service (alle BL-Module)
|
||||
Vorbedingung: Eine BL-Operation prüft ein Benutzerrecht.
|
||||
Fakt: `AppRightsBL.HasUserRight` liest Rechte aus `Sichtrus`/`Sichmemb` und cached das Ergebnis pro Benutzer (`Session.Advanced.Cache.GetOrAdd`); die Erweiterungsmethode `UserRightsExt.HasUserRight` fängt Exceptions ab und liefert im Fehlerfall `false` (fail-closed).
|
||||
Aussage: Das System soll Rechteprüfungen über einen einzigen, wiederverwendeten Dienst mit Caching realisieren und im Fehlerfall (z. B. DB-Ausfall während der Prüfung) grundsätzlich den Zugriff verweigern statt ihn zu gewähren.
|
||||
Ergebnis: Bei technischem Fehler während der Rechteprüfung wird die angefragte Aktion abgelehnt, nicht zugelassen.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Administration\Rights\AppRightsBL.cs (HasUserRight, ~Zeile 644) - Begründung: zentrale Implementierung.
|
||||
- [PRIMÄR] src\backend\Centron.BL\Administration\Rights\UserRightsExt.cs (HasUserRight-Erweiterungsmethode, try/catch → false) - Begründung: durchgesetztes Fail-Closed-Verhalten, sicherheitskritisch → PRIMÄR-Beleg erforderlich und vorhanden.
|
||||
Prüfidee: Rechteprüfung während simuliertem DB-Verbindungsfehler auslösen → Ergebnis muss `false` (verweigert) sein, nicht Exception nach oben durchreichen oder `true` liefern.
|
||||
Tracelinks: StRS-018; SwRS-028
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-020
|
||||
Titel: Erweiterbarer Rechte-Katalog mit eindeutiger ID-Vergabe
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional
|
||||
ISO25010: Wartbarkeit (Modifizierbarkeit)
|
||||
Akteur: Entwicklungsteam
|
||||
Vorbedingung: Ein neues Recht soll dem System hinzugefügt werden.
|
||||
Fakt: `UserRightsConst.cs` (2819 Zeilen, ~751 Konstanten) enthält den Kommentarblock "NEW .NET MODULE RIGHTS START AT 20800000 / NEXT ID: 20800174" — ein manuell gepflegter, fortlaufender ID-Zähler ohne ersichtliche automatisierte Kollisionsprüfung; ältere Rechte tragen numerische IDs mit `[Obsolete]`-Markierung, bleiben aber im Code.
|
||||
Aussage: Das System soll neue Rechte-IDs eindeutig und kollisionsfrei vergeben können; aktuell geschieht dies durch manuelle Pflege eines Zählerkommentars, was ein Wartbarkeitsrisiko bei parallelen Änderungen durch mehrere Entwickler darstellt.
|
||||
Ergebnis: Jede Rechte-ID ist im gesamten System eindeutig.
|
||||
Belege:
|
||||
- [PRIMÄR] src\webservice\Centron.WebServices.Core\EntitiesWrongPlace\Administration\Rights\UserRightsConst.cs (Header-Kommentar) - Begründung: unmittelbarer Beleg für den manuellen, nicht automatisiert abgesicherten Vergabeprozess.
|
||||
Prüfidee: Code-Review-Test: zwei parallele Branches fügen ein neues Recht mit dem "nächsten" ID-Wert hinzu → Merge-Konflikt wird nicht automatisch, sondern nur durch Textgleichheit des Kommentars erkannt (Risiko einer stillen ID-Kollision, falls nicht rechtzeitig bemerkt).
|
||||
Tracelinks: StRS-018; SwRS-029
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround (manuoll gepflegter ID-Zähler statt automatisierter Vergabe/Datenbanksequenz)
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-021
|
||||
Titel: Einheitliches Session-Ticket unabhängig vom Authentifizierungsverfahren
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Web-Service
|
||||
Vorbedingung: Benutzer hat sich über eines der unterstützten Verfahren erfolgreich authentifiziert.
|
||||
Fakt: `AuthenticatorFactory` liefert je nach Konfiguration eine von vier `Authenticator`-Implementierungen; alle münden in denselben nachgelagerten Ticket-Ausstellungspfad (`TicketBL`/`AuthenticationTicketBL`), sodass nachgelagerte Systemteile nicht wissen müssen, welches Verfahren verwendet wurde.
|
||||
Aussage: Das System soll unabhängig vom verwendeten Authentifizierungsverfahren ein einheitlich strukturiertes, zeitlich befristetes Session-Ticket ausstellen, damit nachgelagerte Autorisierungsprüfungen verfahrensunabhängig funktionieren.
|
||||
Ergebnis: Nachgelagerte BL-Aufrufe benötigen keine Fallunterscheidung nach Authentifizierungsverfahren.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Administration\Logins\Auth\AuthenticatorFactory.cs, TicketBL.cs - Begründung: gemeinsamer Ausstellungspfad für alle vier Verfahren.
|
||||
Prüfidee: Anmeldung über Basic-Auth und über OIDC vergleichen → resultierendes Ticket hat identische Struktur/Felder.
|
||||
Tracelinks: StRS-019, StRS-020, StRS-022; SwRS-030, SwRS-031, SwRS-032, SwRS-033
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-022
|
||||
Titel: Zeitliche Befristung von Authentifizierungs-Tickets
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Web-Service
|
||||
Vorbedingung: Ticket wurde ausgestellt.
|
||||
Fakt: `TicketBL` verwendet `ExpirationKind.FromSettings`/`OneDay` zur Bestimmung der Ticket-Gültigkeitsdauer, kombiniert mit einem gerätegebundenen Salt (`CryptoUtils.CreateSalt(32)` + `CreatePasswordHash(deviceId, salt)`).
|
||||
Aussage: Das System soll jedes ausgestellte Authentifizierungs-Ticket nach einer konfigurierbaren Zeitspanne automatisch ungültig werden lassen.
|
||||
Ergebnis: Ein Ticket ist nach Ablauf der konfigurierten Frist nicht mehr für Authentifizierung nutzbar.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Administration\Logins\TicketBL.cs (Zeilen ~166-169, ExpirationKind-Verwendung) - Begründung: durchgesetzte Ablauflogik.
|
||||
Prüfidee: Ticket erzeugen, künstlich Systemzeit über Ablaufgrenze vorstellen (Testsystem) → Ticket wird abgelehnt.
|
||||
Tracelinks: StRS-019; SwRS-032
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-023
|
||||
Titel: Vollständige, nicht abschaltbare Zugriffs- und Änderungsprotokollierung im Passwort-Tresor
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Web-Service
|
||||
Vorbedingung: Gespeichertes Passwort wird gelesen oder geändert.
|
||||
Fakt: `PasswordManagementAccessLogBL` und `PasswordManagementLogBL` schreiben bei jedem Zugriff/jeder Änderung einen Protokolleintrag (ActionType, Date, EmployeeI3D); die Protokollierung ist Teil des Zugriffspfads selbst, nicht ein optionales Zusatzfeature.
|
||||
Aussage: Das System soll jeden Zugriff auf und jede Änderung an gespeicherten Zugangsdaten so protokollieren, dass die Protokollierung durch den zugreifenden Benutzer nicht umgangen werden kann.
|
||||
Ergebnis: Für jeden Zugriff existiert ein nicht nachträglich durch den Benutzer löschbarer Protokolleintrag.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\PasswordManagementArea\PasswordManagementAccessLogBL.cs, PasswordManagementLogBL.cs - Begründung: Protokollierung ist im Zugriffsablauf selbst verankert.
|
||||
Prüfidee: Zugriff auf gespeichertes Passwort → Protokolleintrag muss unmittelbar entstehen, unabhängig vom Ergebnis des Zugriffs.
|
||||
Tracelinks: StRS-021; SwRS-034
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Block F — Web-Kanäle (System-Ebene)
|
||||
|
||||
```
|
||||
ID: SyRS-024
|
||||
Titel: Isolierung von Kunden-Web-Account-Sitzungen von internen Benutzersitzungen
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Web-Service (Nexus)
|
||||
Vorbedingung: Ein Web-Account-Kunde meldet sich am Kundenportal an.
|
||||
Fakt: Es existieren getrennte Login-Oberflächen/Handler für internen Mitarbeiterzugang (`AuthPage.razor`), Outlook-Add-In (`OutlookAuthPage.razor`) und Kunden (`CustomerAuthPage.razor`); Kundenportal-Datenabfragen sind auf den authentifizierten Web-Account beschränkt (impliziert durch getrennten `WebAccountAuthenticator`).
|
||||
Aussage: Das System soll Kunden-Web-Account-Sitzungen strikt von internen Mitarbeitersitzungen trennen und Datenabfragen im Kundenportal auf den jeweils angemeldeten Kunden beschränken.
|
||||
Ergebnis: Ein Web-Account-Kunde kann über das Kundenportal keine Daten anderer Kunden oder interne Mitarbeiterfunktionen erreichen.
|
||||
Belege:
|
||||
- [PRIMÄR] src\backend\Centron.BL\Administration\Logins\Auth\WebAccountAuthenticator.cs - Begründung: eigenständiger Authentifizierungspfad für Web-Accounts.
|
||||
- [SEKUNDÄR] src\nexus\CentronNexus\Shared\Auth\CustomerAuthPage.razor, AuthPage.razor, OutlookAuthPage.razor - Begründung: drei separate Login-Oberflächen bestätigen die Trennung auf UI-Ebene.
|
||||
Prüfidee: Als Web-Account-Kunde angemeldet, direkten API-Aufruf auf einen internen/administrativen Endpunkt oder auf Daten eines anderen Kunden versuchen → muss abgelehnt werden. [HYPOTHESE]: Die konkrete serverseitige Scoping-Prüfung pro Kundenportal-Endpunkt wurde nicht für jeden einzelnen Controller einzeln verifiziert — siehe Hypothesen.md.
|
||||
Tracelinks: StRS-022, StRS-023; SwRS-035
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-025
|
||||
Titel: Serverseitige Lizenzprüfung für Web-Shop-Funktionalität
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Web-Service (Nexus)
|
||||
Vorbedingung: Web-Account-Kunde ruft WebCart-Funktion auf.
|
||||
Fakt: `WebCartShopPage.razor` trägt das Attribut `[AuthorizeLicense(nameof(LicenseGuids.WebCart2))]`, das laut Namensmuster serverseitig vor Rendern der Seite geprüft wird (Blazor-Server-Modell, Ausführung auf dem Server, nicht im Browser).
|
||||
Aussage: Das System soll den Zugriff auf die WebCart-Funktion an eine serverseitig geprüfte Lizenz koppeln, unabhängig davon, ob der Kunde die URL direkt aufruft.
|
||||
Ergebnis: Web-Account ohne WebCart2-Lizenz kann die Shop-Seite nicht öffnen, auch nicht durch direkten URL-Aufruf.
|
||||
Belege:
|
||||
- [PRIMÄR] src\nexus\CentronNexus\WebCart\WebCartShopPage.razor (Attribut AuthorizeLicense) - Begründung: Blazor-Server-Ausführungsmodell macht dies zu einer serverseitigen, nicht umgehbaren Prüfung (im Gegensatz zu Blazor WebAssembly).
|
||||
Prüfidee: Web-Account ohne Lizenz ruft `/webcart/shop` direkt per URL auf → Zugriff wird verweigert. [HYPOTHESE]: Das genaue Verhalten des `AuthorizeLicense`-Attributs (Redirect vs. Fehlerseite vs. Exception) wurde nicht im Detail nachvollzogen — siehe Hypothesen.md.
|
||||
Tracelinks: StRS-023; SwRS-036
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-026
|
||||
Titel: Automatisierte, signierte Erstellung aller Auslieferungsartefakte
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional
|
||||
ISO25010: Übertragbarkeit (Installierbarkeit)
|
||||
Akteur: CI/CD-System
|
||||
Vorbedingung: Änderung wird auf `main`/`release/*`-Branch gemerged.
|
||||
Fakt: `.github\workflows\build.yml` baut und signiert alle drei Artefakte (Web-Service-Host + Connection Manager, WPF-Client, Nexus-Host) in einem Lauf, erzeugt WiX-MSIs, verifiziert Authenticode-Signaturen und lädt die Artefakte hoch.
|
||||
Aussage: Das System soll bei jeder Änderung auf den relevanten Branches alle drei Auslieferungsartefakte automatisiert, reproduzierbar und signiert erzeugen, ohne manuellen Eingriff.
|
||||
Ergebnis: Nach jedem Build-Lauf liegen drei signierte, verifizierte Artefakte vor.
|
||||
Belege:
|
||||
- [PRIMÄR] .github\workflows\build.yml - Begründung: enthält den tatsächlich ausgeführten, automatisierten Build-/Signier-/Verifizierungsprozess.
|
||||
Prüfidee: CI-Lauf beobachten: alle drei Artefakte müssen mit gültiger Authenticode-Signatur vorliegen, Pipeline darf bei Signaturfehler nicht grün werden.
|
||||
Tracelinks: StRS-024; SwRS-038
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-027
|
||||
Titel: Containerisierte, konfigurationsexterne Bereitstellung des Web-Portals
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional
|
||||
ISO25010: Übertragbarkeit (Anpassbarkeit)
|
||||
Akteur: Betreiber (Cloud/On-Premises)
|
||||
Vorbedingung: Container-Host (z. B. Azure) steht bereit.
|
||||
Fakt: `docker\Dockerfile` baut ein `.NET 10 Alpine`-Image, Konfiguration erfolgt über `appsettings.json`/`appsettings.Development.json` mit Platzhaltern für produktive Werte statt eingebetteter Zugangsdaten (im Gegensatz zum legacy `app.config` der Konsolen-Variante, siehe Hypothesen.md); Deployment via `docker compose` auf einer Ziel-VM.
|
||||
Aussage: Das System soll das Web-Portal als eigenständigen, umgebungsunabhängigen Container bereitstellen können, dessen Konfiguration extern (nicht im Image fest codiert) erfolgt.
|
||||
Ergebnis: Dasselbe Container-Image ist mit unterschiedlicher externer Konfiguration in unterschiedlichen Umgebungen einsetzbar.
|
||||
Belege:
|
||||
- [PRIMÄR] docker\Dockerfile, docker\README.md - Begründung: enthält den tatsächlichen Build- und Konfigurationsmechanismus.
|
||||
- [SEKUNDÄR] src\nexus\CentronNexus.Host\appsettings.json - Begründung: zeigt produktionsseitig weitgehend leere/platzhalterhafte Werte, die extern befüllt werden.
|
||||
Prüfidee: Dasselbe Image mit zwei unterschiedlichen `appsettings`-Overrides starten → unterschiedliches Zielsystem wird angesprochen, ohne Image-Neubau.
|
||||
Tracelinks: StRS-024; SwRS-038
|
||||
Konsolidierung: Kandidat: SyRS-026 (beide betreffen Auslieferung/Deployment)
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Block G — Externe Integrationen (System-Ebene, leichtere Analysetiefe)
|
||||
|
||||
```
|
||||
ID: SyRS-028
|
||||
Titel: Fehlerisolation zwischen unabhängigen externen Integrationen
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional
|
||||
ISO25010: Zuverlässigkeit (Fehlertoleranz)
|
||||
Akteur: Web-Service
|
||||
Vorbedingung: Eine von mehreren konfigurierten externen Schnittstellen (COP/Egis/ITscope/Icecat, GLS/Shipcloud, ebInterface/ZUGFeRD, docuFORM) ist nicht erreichbar oder liefert einen Fehler.
|
||||
Fakt: Jeder externe Client kapselt Fehler in einer eigenen Exception-Klasse (`ITscopeException`, `CopException`, `EgisException`, `IcecatException`) mit eigener Fehlerbehandlung; es wurde **keine gemeinsame Resilience-Bibliothek (Polly o. ä.)** und **kein einheitliches Retry-/Timeout-Konzept** über alle Integrationen hinweg gefunden — jede Integration behandelt Fehler eigenständig und unterschiedlich (z. B. ITscope: HTTP 404 → stilles Leerergebnis; andere Clients: Exception-Weiterwurf).
|
||||
Aussage: Das System soll den Ausfall einer externen Integration so behandeln, dass andere, unabhängige Integrationen und Kernfunktionen davon unberührt bleiben; aktuell ist dies nicht durch ein einheitliches Resilience-Konzept, sondern durch voneinander unabhängige, uneinheitliche Fehlerbehandlungen je Client erreicht.
|
||||
Ergebnis: Ausfall eines externen Dienstes (z. B. Icecat) führt nicht zum Ausfall anderer Funktionen (z. B. GLS-Versand).
|
||||
Belege:
|
||||
- [PRIMÄR] src\apis\Centron.APIs.ITscopeDataAccess\ITscopeApi.cs (Zeilen 293-314) - Begründung: durchgesetzte, clientspezifische Fehlerbehandlung.
|
||||
- [SEKUNDÄR] src\apis\Centron.Api.docuFORM\Helper\HttpResponseMessageExtensions.cs - Begründung: weiterer, eigenständiger Fehlerbehandlungspfad, bestätigt fehlende Vereinheitlichung.
|
||||
Prüfidee: Simulierter Ausfall eines externen Dienstes (z. B. Timeout) → übrige Integrationen und Kernfunktionen bleiben funktionsfähig; Antwortzeitverhalten bei Ausfall ist [HYPOTHESE] (kein Timeout-Override gefunden, Default-`HttpClient`-Timeout vermutlich wirksam — siehe Hypothesen.md).
|
||||
Tracelinks: StRS-025, StRS-026, StRS-027, StRS-028; SwRS-039, SwRS-040
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround (uneinheitliche, nicht zentralisierte Resilience-Strategie über alle externen Integrationen)
|
||||
```
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
# Traceability-Tabelle
|
||||
|
||||
Eine Zeile je SwRS-Anforderung (feinste Granularität), mit jeweils primärer SyRS- und StRS-Referenz sowie dem stärksten (i. d. R. PRIMÄR-)Artefaktbeleg. Vollständige, teils mehrfache Verknüpfungen (eine SyRS kann mehrere StRS bedienen, eine StRS mehrere SyRS) sind in den `Tracelinks`-Feldern der jeweiligen Einzelanforderung in `StRS.md`/`SyRS.md`/`SwRS.md` dokumentiert; diese Tabelle bildet die jeweils primäre Kette ab.
|
||||
|
||||
| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg (primär) |
|
||||
|---|---|---|---|
|
||||
| StRS-001 | SyRS-001 | SwRS-001 | src\backend\Centron.Interfaces\Sales.Receipts\IReceiptSpecificLogic.cs |
|
||||
| StRS-001 | SyRS-001 | SwRS-002 | src\backend\Centron.Interfaces\CentronObjectKindNumeric.cs |
|
||||
| StRS-001, StRS-005 | SyRS-002 | SwRS-003 | src\backend\Centron.BL\Sales\Receipts\Internal\AutomaticallyCloseReceiptHelperBL.cs |
|
||||
| StRS-002 | SyRS-003 | SwRS-004 | src\backend\Centron.BL\Administration\FileManagement\SharedDocumentBL.cs (GenerateTokenForDocument, Z. 128-130) |
|
||||
| StRS-002 | SyRS-004 | SwRS-005 | src\backend\Centron.BL\Administration\FileManagement\SharedDocumentBL.cs (GetSharedDocumentByToken, Z. 405-409) |
|
||||
| StRS-002 | SyRS-004 | SwRS-006 | src\backend\Centron.BL\Sales\Receipts\ReceiptBL.cs (AcceptWebReceipt, Z. 6256-6360) |
|
||||
| StRS-003 | SyRS-005 | SwRS-007 | src\backend\Centron.BL\Sales\Receipts\Invoices\ReceiptInvoiceBL.cs (FixInvoice, Z. 86) |
|
||||
| StRS-003 | SyRS-005 | SwRS-008 | src\backend\Centron.BL\Administration\Scripts\ScriptMethods\SqlStatements\SQLScriptCollection2.xml (Skript #10208) |
|
||||
| StRS-004 | SyRS-006 | SwRS-009 | src\backend\Centron.Interfaces\DataExchange.BookKeeping\CalculationUtils.cs |
|
||||
| StRS-004 | SyRS-006 | SwRS-010 | src\backend\Centron.BL\Sales\Receipts\Invoices\InvoiceSpecificLogic.cs |
|
||||
| StRS-006 | SyRS-007 | SwRS-011 | src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs (Z. 298-326) |
|
||||
| StRS-006 | SyRS-007 | SwRS-012 | src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs (CheckUserRigths, Z. 410-466) |
|
||||
| StRS-006, StRS-007 | SyRS-008 | SwRS-013 | src\backend\Centron.BL\Sales\Support\HelpdeskBL.cs (GetLoggedInUserShowHelpdeskRight, Z. 271-284) |
|
||||
| StRS-008 | SyRS-009 | SwRS-014 | src\backend\Centron.BL\CustomerArea\RmaBL.cs (SaveRma, Z. 352-353) |
|
||||
| StRS-008 | SyRS-009 | SwRS-015 | src\backend\Centron.BL\CustomerArea\RmaBL.cs (SaveRma, Z. 378-521) |
|
||||
| StRS-009 | SyRS-010 | SwRS-016 | src\backend\Centron.BL\TaskManager\TaskManagementTaskBL.cs (sp_getapplock) |
|
||||
| StRS-009 | SyRS-010 | SwRS-017 | src\backend\Centron.BL\TaskManager\ActionHandler\TaskManagementHelpdeskActionHandler.cs (Z. 57) |
|
||||
| StRS-010 | SyRS-011 | SwRS-018 | src\backend\Centron.BL\Warehousing\ArticleBL.cs (Z. 991-1089) |
|
||||
| StRS-011 | SyRS-012 | SwRS-019 | src\backend\Centron.BL\Warehousing\InventoryManagement\InventoryBL.cs (Z. 694-750) |
|
||||
| StRS-011 | SyRS-012 | SwRS-020 | src\backend\Centron.BL\Warehousing\InventoryManagement\InventoryBL.cs (DeleteInventory, Z. 98-109) |
|
||||
| StRS-012 | SyRS-013 | SwRS-021 | src\backend\Centron.BL\Warehousing\Commissions\PartialCommissionOrderBL.cs (Z. 135, 170, 426, 453) |
|
||||
| StRS-013 | SyRS-014 | SwRS-022 | src\backend\Centron.BL\Purchasing\OrderSuggestionList\OrderSuggestionListBL.cs |
|
||||
| StRS-014 | SyRS-015 | SwRS-023 | src\backend\Centron.BL\EDI\EDIDispatcherBL.cs (Z. 56-70) |
|
||||
| StRS-015, StRS-016 | SyRS-016 | SwRS-024 | src\backend\Centron.BL\Finances\OnlineBanking\OnlineBankingAccountTransactionsBL.cs (Z. 294-340) |
|
||||
| StRS-015 | SyRS-016, SyRS-017 | SwRS-025 | src\backend\Centron.BL\Finances\OnlineBanking\OnlineBankingAccountTransactionsBL.cs (BookAmountToAssignedInvoice, Z. 1042-1086) |
|
||||
| StRS-016 | SyRS-016 | SwRS-026 | src\backend\Centron.BL\Finances\Payments\PaymentsBL.cs (Z. 43-44) |
|
||||
| StRS-017 | SyRS-018 | SwRS-027 | src\backend\Centron.WebServices.Core\WebServices\Sales.Receipts\ReceiptWebServiceBL.cs (Z. 994-1000) |
|
||||
| StRS-018 | SyRS-019 | SwRS-028 | src\backend\Centron.BL\Administration\Rights\AppRightsBL.cs (HasUserRight); UserRightsExt.cs |
|
||||
| StRS-018 | SyRS-020 | SwRS-029 | src\webservice\Centron.WebServices.Core\EntitiesWrongPlace\Administration\Rights\UserRightsConst.cs (Header-Kommentar) |
|
||||
| StRS-019 | SyRS-021 | SwRS-030 | src\backend\Centron.BL\Administration\Logins\Auth\AuthenticatorFactory.cs |
|
||||
| StRS-019 | SyRS-021 | SwRS-031 | src\backend\Centron.BL\Administration\Logins\Auth\BasicAuthenticator.cs (Z. 46, 48) |
|
||||
| StRS-019, StRS-020 | SyRS-021, SyRS-022 | SwRS-032 | src\backend\Centron.BL\Administration\Logins\TicketBL.cs (Z. 166-169) |
|
||||
| StRS-020 | SyRS-021 | SwRS-033 | src\backend\Centron.BL\Administration\Logins\TwoFactor\TwoFactorAuthBL.cs |
|
||||
| StRS-021 | SyRS-023 | SwRS-034 | src\backend\Centron.BL\PasswordManagementArea\PasswordManagementAccessLogBL.cs |
|
||||
| StRS-022 | SyRS-024 | SwRS-035 | src\backend\Centron.BL\Administration\Logins\Auth\WebAccountAuthenticator.cs |
|
||||
| StRS-023 | SyRS-025 | SwRS-036 | src\nexus\CentronNexus\WebCart\WebCartShopPage.razor (AuthorizeLicense) |
|
||||
| StRS-023 | SyRS-025 | SwRS-037 | src\nexus\CentronNexus\WebCart\Helpers\CurrentCartService.cs |
|
||||
| StRS-024 | SyRS-026, SyRS-027 | SwRS-038 | .github\workflows\build.yml |
|
||||
| StRS-025 | SyRS-028 | SwRS-039 | src\apis\Centron.APIs.ITscopeDataAccess\ITscopeApi.cs (Z. 293-314) |
|
||||
| StRS-028 | SyRS-028 | SwRS-040 | src\apis\Centron.Api.docuFORM\DocuFormRestApiClient.cs |
|
||||
|
||||
## Ergänzende StRS ohne eigene SwRS-Detailtiefe (leichtere Analysetiefe)
|
||||
|
||||
Diese StRS/SyRS-Paare wurden gebildet, besitzen aber laut Priorisierung keine eigenständige SwRS-Anforderung über die in obiger Tabelle bereits unter StRS-025/StRS-028 (SyRS-028) gebündelte Ebene hinaus:
|
||||
|
||||
| StRS-ID | SyRS-ID | Artefaktbeleg |
|
||||
|---|---|---|
|
||||
| StRS-026 | SyRS-028 | src\apis\Centron.Api.Gls\CentronGlsLogic.cs; src\apis\Centron.Api.Shipcloud\CentronShipcloudLogic.cs |
|
||||
| StRS-027 | SyRS-028 | src\apis\Centron.Api.EbInterface\EbInterfaceLogic.cs; src\webservice\Centron.Controllers\Controllers\v1\Receipts\ZugferdImportController.cs |
|
||||
|
||||
Siehe Analysebericht.md, Abschnitt "Analysetiefe je Modul", für die Begründung der reduzierten Tiefe bei Block G (externe Integrationen).
|
||||
+191
@@ -0,0 +1,191 @@
|
||||
# Messprotokoll – V1 Baseline (Prompt-only) – Iteration 01
|
||||
|
||||
## Lauf
|
||||
- **Prompt-Datei:** `Versuche/Versuch_01/01_Prompt.md`
|
||||
- **SHA-256 (Prompt):** `1B0DB06B8E0A5B92A5EFBDBEC5A0C554351FC928A16AEF34AAD9EAA0893C02FF`
|
||||
- **Startzeit:** 2026-08-25T12:29:05.2074784+02:00
|
||||
- **Endzeit:** 2026-08-25T13:00:35.7607833+02:00
|
||||
- **Dauer gesamt:** 00:31:31 (Wanduhr) bzw. 00:31:26 (`duration_ms`) — API: 00:47:05 (`duration_api_ms`)
|
||||
- Die API-Dauer übersteigt die Wanduhrzeit, weil 8 `Explore`-Subagenten parallel liefen; die Werte summieren sich über nebenläufige Anfragen.
|
||||
- **Root-Verzeichnis:** `c:\DEV\MasterArbeit\QuellCode\CentronERP`
|
||||
- **Codebasis-Commit:** `89ccfd650de2b112c5d20df4230457e413210aad` (dirty vor Eingriff: nein; während des Laufs: ja – siehe *Vorbereitender Eingriff*)
|
||||
- **Prompt-Repo-Commit:** `0ec86aed8cb8781054c86cbe0dd9f5eb0f7e5f05`
|
||||
|
||||
## Vorbereitender Eingriff (Herstellung der Baseline-Bedingung)
|
||||
Das Root enthielt Werkzeugkonfigurationen, die der Versuchsbedingung „keine Agentendateien,
|
||||
keine MCP-Server" widersprechen. Sie wurden auf Anweisung des Versuchsleiters **vor** dem Lauf
|
||||
gelöscht (92 versionierte Dateien in 17 Root-Einträgen):
|
||||
|
||||
`.agents/`, `.aiignore`, `.claude/`, `.claudeignore`, `.codex/`, `.cursor/`, `.cursorignore`,
|
||||
`.mcp.json`, `.mcp.disabled.json.bak`, `.memory-mcp/`, `.serena/`, `.opencode/`, `AGENTS.md`,
|
||||
`CLAUDE.md`, `opencode.json`, `skills-lock.json`, `.coderabbit.yaml`
|
||||
|
||||
Darin enthalten waren u. a. 3 projektspezifische Subagenten, 34 Skill-Definitionen, 6 Slash-Commands,
|
||||
7 Output-Styles, 11 Serena-Memories und der MCP-Server `serena`.
|
||||
|
||||
Kontrollen der Isolation:
|
||||
- Verschachtelte `CLAUDE.md`/`AGENTS.md`/`.mcp.json`/`.claude` unterhalb des Roots: **keine**
|
||||
- Übergeordnete Verzeichnisse (`QuellCode/`): **frei von Agentendateien**
|
||||
- User-Ebene (`~/.claude`): **keine** Agenten, **keine** Skills, **keine** `CLAUDE.md`;
|
||||
`settings.json` enthält nur `model` und `agentPushNotifEnabled`
|
||||
- Die Modellpräferenz der User-Settings (`opus[1m]`) wurde per `--model` überschrieben
|
||||
|
||||
Wiederherstellung: `git -C QuellCode/CentronERP restore .` (alle Dateien waren versioniert,
|
||||
Working Tree vor dem Eingriff sauber). Der Eingriff wurde nach dem Lauf vollständig
|
||||
zurückgenommen; zum weiteren Weg der Codebasis siehe Anmerkung 9.
|
||||
|
||||
## Werkzeugkonfiguration
|
||||
- **Laufverzeichnis-ID:** `v1.0.0-23e8`
|
||||
- **Ablage:** `claude-sonnet-5/builtin/high/`
|
||||
- **Parallele Läufe:** nein
|
||||
- **Skill-Version:** `1.0.0` (Ausgangsfassung: kein Shell-Zugriff, Isolation durch Löschen der KI-Konfigurationsdateien im Root)
|
||||
- **Claude-Code-Version:** 2.1.245
|
||||
- **Effort:** `high` — **nicht zur Laufzeit gesetzt**, sondern aus der Sitzung geerbt und
|
||||
nachtraeglich aus dem Session-Transkript rekonstruiert (69 Nachrichten, durchgaengig `high`).
|
||||
`RawResult.json` enthaelt kein `effort`-Feld. Ab Skill-Version 3.4.0 wird der Wert per
|
||||
`--effort` explizit gesetzt.
|
||||
- **Modell:** `claude-sonnet-5` (explizit gesetzt, Kontextfenster 1.000.000, max. Output 64.000);
|
||||
zusätzlich `claude-haiku-4-5-20251001` für interne Hilfsaufrufe (4.176 Input-/20 Output-Tokens)
|
||||
- **Permission-Mode:** `acceptEdits`
|
||||
- **MCP-Server / Agentendateien:** keine (siehe *Vorbereitender Eingriff*)
|
||||
- **Aufruf:** `claude -p --output-format json --permission-mode acceptEdits --model claude-sonnet-5 --add-dir <Laufverzeichnis>`,
|
||||
Prompt per stdin, Arbeitsverzeichnis = Root
|
||||
- **Subagenten:** 8 (alle vom eingebauten Typ `Explore`, foreground, max. Tiefe 1, 8 abgeschlossen, 0 fehlgeschlagen).
|
||||
Es handelt sich um Claude-Code-Bordmittel, nicht um projektspezifische Agentendateien.
|
||||
- **Fast-Mode:** aus
|
||||
|
||||
## Verbrauch
|
||||
|
||||
### Hauptagent (`usage` im Ergebnisobjekt)
|
||||
| Messgröße | Wert |
|
||||
|---|---|
|
||||
| Input-Tokens | 46 |
|
||||
| Output-Tokens | 105.959 (davon 25.299 Thinking-Tokens) |
|
||||
| Cache-Write-Tokens | 217.738 (vollständig 1h-ephemeral) |
|
||||
| Cache-Read-Tokens | 3.534.395 |
|
||||
| Agent-Turns | 43 |
|
||||
|
||||
### Gesamtlauf inkl. Subagenten (`modelUsage`, abrechnungsrelevant)
|
||||
| Messgröße | `claude-sonnet-5` | `claude-haiku-4-5-20251001` | Summe |
|
||||
|---|---:|---:|---:|
|
||||
| Input-Tokens | 366 | 4.176 | 4.542 |
|
||||
| Output-Tokens | 249.020 | 20 | 249.040 |
|
||||
| Cache-Write-Tokens | 839.291 | 0 | 839.291 |
|
||||
| Cache-Read-Tokens | 11.959.137 | 0 | 11.959.137 |
|
||||
| Tokens gesamt | 13.047.814 | 4.196 | **13.052.010** |
|
||||
|
||||
**Tokens gesamt: 13.052.010** (Summe aus Input, Output, Cache-Write und Cache-Read ueber alle Modelle; `total_cost_usd` steht weiterhin in `RawResult.json`)
|
||||
|
||||
## Ergebnis
|
||||
- **Status:** erfolgreich (`is_error: false`, `subtype: "success"`, `stop_reason: "end_turn"`, Exit-Code 0, `Stderr.log` leer)
|
||||
- **Session-ID:** `18b1d5b6-f3e3-49cd-b5aa-38bf1fff642c`
|
||||
- **Erzeugte Dateien:** alle 7 geforderten Artefakte in `Ergebnisse\`
|
||||
|
||||
| Datei | Größe | Inhalt |
|
||||
|---|---:|---|
|
||||
| `StRS.md` | 45.710 B | 28 Anforderungen |
|
||||
| `SyRS.md` | 40.758 B | 28 Anforderungen |
|
||||
| `SwRS.md` | 51.795 B | 40 Anforderungen |
|
||||
| `Traceability.md` | 6.095 B | 44 Zeilen StRS→SyRS→SwRS |
|
||||
| `Hypothesen.md` | 9.182 B | 12 Einträge (H-001…H-012) |
|
||||
| `Glossar.md` | 6.698 B | Domänenbegriffe |
|
||||
| `Analysebericht.md` | 13.637 B | Modulübersicht, Konsistenzcheck, Selbstbewertung |
|
||||
|
||||
Summe: 96 Anforderungen über drei Ebenen.
|
||||
- **Root unverändert:** ja. `git status --porcelain` nach dem Lauf ist zeilenweise identisch mit
|
||||
dem vor dem Lauf gesicherten Stand (92 Einträge, ausnahmslos Status `D` aus dem vorbereitenden
|
||||
Eingriff). Der Lauf selbst hat keine Datei der Codebasis angelegt, geändert oder gelöscht.
|
||||
- **Abschlusstext des Agenten:** siehe `RawResult.json` (`result`)
|
||||
|
||||
## Gefundene Anforderungen
|
||||
|
||||
Maschinell aus `Ergebnisse\StRS.md`, `SyRS.md` und `SwRS.md` ausgewertet (Blockformat des Prompts). Erzeugt von `analyse-anforderungen.py`.
|
||||
|
||||
### Verteilung über die Ebenen
|
||||
|
||||
| Ebene | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| StRS | 28 | 29,2 % |
|
||||
| SyRS | 28 | 29,2 % |
|
||||
| SwRS | 40 | 41,7 % |
|
||||
| **Gesamt** | **96** | 100 % |
|
||||
|
||||
### Anforderungstypen
|
||||
|
||||
| Typ | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| Sicherheit | 38 | 39,6 % |
|
||||
| funktional | 28 | 29,2 % |
|
||||
| Daten | 12 | 12,5 % |
|
||||
| Schnittstelle | 9 | 9,4 % |
|
||||
| nicht-funktional | 9 | 9,4 % |
|
||||
|
||||
### Belegqualität
|
||||
|
||||
| Messgröße | Wert |
|
||||
|---|---:|
|
||||
| Belege gesamt | 138 |
|
||||
| davon `PRIMÄR` | 105 (76,1 %) |
|
||||
| davon `SEKUNDÄR` | 27 (19,6 %) |
|
||||
| davon `KONTEXT` | 6 (4,3 %) |
|
||||
| Belege je Anforderung (Median) | 1,0 |
|
||||
| Anforderungen mit mindestens einem `PRIMÄR`-Beleg | 96 (100,0 %) |
|
||||
|
||||
### Status
|
||||
|
||||
| Kategorie | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| belegt | 88 | 91,7 % |
|
||||
| als `HYPOTHESE` gekennzeichnet | 8 | 8,3 % |
|
||||
| als Workaround vermerkt | 8 | 8,3 % |
|
||||
| Konsolidierungskandidaten | 10 | 10,4 % |
|
||||
| mit ISO-25010-Qualitätsmerkmal | 0 | 0,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** (49 risikorelevante Anforderungen, alle gedeckt) |
|
||||
| **Verifizierbarkeit** – jede Anforderung mit Prüfidee oder Akzeptanzkriterium | **erfüllt** |
|
||||
| **Traceability** – Verknüpfung zwischen den Ebenen | 96 von 96 mit Tracelinks (100,0 %) |
|
||||
|
||||
## Anmerkungen/Auffälligkeiten
|
||||
1. **36 Permission-Denials** (32 × `Bash`, 4 × `PowerShell`). Unter `acceptEdits` sind Shell-Aufrufe
|
||||
nicht freigegeben; der Lauf brach dadurch nicht ab, sondern wich auf `Read`/`Grep`/`Glob`/`Explore`
|
||||
aus. Methodisch relevant: Verzeichnisinventuren und Dateizählungen per Shell standen dem Agenten
|
||||
nicht zur Verfügung, was die Breitenabdeckung beeinflusst haben kann. Für Folgeiterationen ist zu
|
||||
entscheiden, ob Shell-Zugriff Teil der Werkzeugkonfiguration sein soll.
|
||||
2. **Abdeckung laut Selbstbewertung des Agenten:** ~17.300 Quelldateien, 82 Projekte, ~85 BL-Module.
|
||||
Tiefenanalyse für Order-to-Cash/Zahlungseingang, C-Sign-Websignatur, Rechnungsfestschreibung,
|
||||
Steuerberechnung, Helpdesk/RMA, Lagerhaltung, Einkauf, Online-Banking-Abgleich sowie Rechte-/
|
||||
Authentifizierungssystem. Leichtere Behandlung externer Integrationen; **rund 55–60 der ~85
|
||||
BL-Module (Reporting, Statistik, Integrationen, Mobile u. a.) wurden nicht analysiert.**
|
||||
3. **Sicherheitsbefund:** ungesalzenes SHA-1-Passwort-Hashing, im Code selbst als TODO markiert.
|
||||
Vom Agenten als belegter Primärfund ausgewiesen.
|
||||
4. **Konsistenzcheck:** Der Agent gibt an, drei Traceability-Inkonsistenzen gefunden und vor
|
||||
Abgabe korrigiert zu haben (dokumentiert im `Analysebericht.md`).
|
||||
5. **Zählabweichung bei Hypothesen:** `Hypothesen.md` führt 12 Einträge (H-001…H-012), während in
|
||||
den Anforderungsdateien nur 7 Inline-Markierungen `[HYPOTHESE]` stehen (SyRS 5, SwRS 2, StRS 0).
|
||||
Die Sammeldatei enthält demnach auch Hypothesen ohne zugeordnete Anforderung. Für die Auswertung
|
||||
der Belegdichte ist zu klären, welche Zählweise maßgeblich ist.
|
||||
6. **Cache-Dominanz:** 11,96 Mio. Cache-Read- gegenüber 4.542 echten Input-Tokens. Der Verbrauch
|
||||
wird fast vollständig von wiederholtem Kontextlesen bestimmt — bei Vergleichen zwischen
|
||||
Iterationen sind Cache-Tokens deshalb getrennt auszuweisen.
|
||||
7. **Manuelle Eingriffe während des Laufs:** keine.
|
||||
8. **Vergleichbarkeit mit Folgeläufen:** Dieser Lauf entstand unter der Vorgänger-Konfiguration —
|
||||
ohne Shell-Freigabe (`acceptEdits` allein) und mit Isolation durch Löschen der
|
||||
AI-Konfigurationsdateien im Root. Ab Iteration 02 gilt die geänderte Standardkonfiguration
|
||||
des Skills: `--allowedTools "Bash" "PowerShell"` mit Denylist für schreibende Kommandos
|
||||
sowie Isolation über einen eingefrorenen Codebasis-Snapshot ohne KI-Konfigurationen
|
||||
(zusätzlich `--safe-mode` und `--strict-mcp-config`). Die
|
||||
Werkzeugkonfiguration ist damit zwischen Iteration 01 und den Folgeläufen **nicht identisch**
|
||||
und bei Vergleichen als Einflussgröße zu berücksichtigen.
|
||||
9. **Weiterer Weg der Codebasis nach diesem Lauf:** Der für diesen Lauf gelöschte Zustand wurde
|
||||
zunächst per `git restore .` vollständig auf `89ccfd6` zurückgesetzt. Anschließend wurde die
|
||||
Codebasis als **eingefrorener Versuchssnapshot** eingerichtet: Das GitHub-Remote
|
||||
(`NEXOWARE-Systems/CentronERP`) wurde entkoppelt und die KI-Assistenz-Konfigurationen wurden
|
||||
dauerhaft entfernt (Commit `79c1142`, Parent `89ccfd6`, 92 Dateien, nur lokal – nichts
|
||||
gepusht). Ab Iteration 02 ist der Untersuchungsgegenstand also `79c1142`. Inhaltlich
|
||||
unterscheidet er sich von `89ccfd6` ausschließlich um die entfernten KI-Konfigurationen;
|
||||
der analysierte Produktivcode ist identisch.
|
||||
+1
File diff suppressed because one or more lines are too long
+1580
File diff suppressed because it is too large
Load Diff
+53
@@ -0,0 +1,53 @@
|
||||
## Gefundene Anforderungen
|
||||
|
||||
Maschinell aus `Ergebnisse\StRS.md`, `SyRS.md` und `SwRS.md` ausgewertet (Blockformat des Prompts). Erzeugt von `analyse-anforderungen.py`.
|
||||
|
||||
### Verteilung über die Ebenen
|
||||
|
||||
| Ebene | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| StRS | 28 | 29,2 % |
|
||||
| SyRS | 28 | 29,2 % |
|
||||
| SwRS | 40 | 41,7 % |
|
||||
| **Gesamt** | **96** | 100 % |
|
||||
|
||||
### Anforderungstypen
|
||||
|
||||
| Typ | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| Sicherheit | 38 | 39,6 % |
|
||||
| funktional | 28 | 29,2 % |
|
||||
| Daten | 12 | 12,5 % |
|
||||
| Schnittstelle | 9 | 9,4 % |
|
||||
| nicht-funktional | 9 | 9,4 % |
|
||||
|
||||
### Belegqualität
|
||||
|
||||
| Messgröße | Wert |
|
||||
|---|---:|
|
||||
| Belege gesamt | 138 |
|
||||
| davon `PRIMÄR` | 105 (76,1 %) |
|
||||
| davon `SEKUNDÄR` | 27 (19,6 %) |
|
||||
| davon `KONTEXT` | 6 (4,3 %) |
|
||||
| Belege je Anforderung (Median) | 1,0 |
|
||||
| Anforderungen mit mindestens einem `PRIMÄR`-Beleg | 96 (100,0 %) |
|
||||
|
||||
### Status
|
||||
|
||||
| Kategorie | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| belegt | 88 | 91,7 % |
|
||||
| als `HYPOTHESE` gekennzeichnet | 8 | 8,3 % |
|
||||
| als Workaround vermerkt | 8 | 8,3 % |
|
||||
| Konsolidierungskandidaten | 10 | 10,4 % |
|
||||
| mit ISO-25010-Qualitätsmerkmal | 0 | 0,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** (49 risikorelevante Anforderungen, alle gedeckt) |
|
||||
| **Verifizierbarkeit** – jede Anforderung mit Prüfidee oder Akzeptanzkriterium | **erfüllt** |
|
||||
| **Traceability** – Verknüpfung zwischen den Ebenen | 96 von 96 mit Tracelinks (100,0 %) |
|
||||
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
[
|
||||
{
|
||||
"id": "toolu_01XQQaEyB5DtoAwVe7My7V6G",
|
||||
"werkzeug": "Agent",
|
||||
"subagent_type": "Explore",
|
||||
"description": "Survey BL domains: finance/logistics side",
|
||||
"run_in_background": false,
|
||||
"model": null,
|
||||
"prompt": "You are surveying a large legacy C# ERP codebase (c-entron) at C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP for a reverse-engineering requirements effort. This is READ-ONLY research — do not modify anything.\n\nFocus on these subfolders of the business logic project `src\\backend\\Centron.BL\\`:\n- Accounting\n- Buying\n- Finances\n- Warehousing\n- Purchasing\n- Production\n- Logistics\n- TradePool\n- VoucherManagement\n- Storage\n\nFor EACH of these folders, report:\n1. Purpose/business domain in one or two sentences, inferred from class/method names and any comments.\n2. The 3-8 most important classes (with exact file path) and what they do.\n3. Any status/state enums or state-machine-like logic (e.g., an enum like `InvoiceStatus`, and methods that transition between states with guard conditions) — quote the enum values and the exact file/method where transitions are enforced.\n4. Any validation logic or business rules enforced in code (e.g. \"cannot post an invoice if X\") — with exact file/method reference.\n5. Any permission/rights checks (e.g. references to UserRightsConst or similar) — exact file/method reference.\n6. Any DB constraints, stored procedures, or SQL visible in these areas (file path).\n\nBe concrete and always cite exact file paths (relative to repo root) and, where feasible, class/method names or line numbers. If a folder is huge, sample representatively rather than reading every file, but note what you skipped.\n\nReport back in a structured format, one section per folder. Keep total response under ~2500 words — prioritize concrete evidence (file paths + short quotes) over prose.",
|
||||
"ergebnis_zeichen": 14338
|
||||
},
|
||||
{
|
||||
"id": "toolu_013i37jGgA53CAH2PakBm6zR",
|
||||
"werkzeug": "Agent",
|
||||
"subagent_type": "Explore",
|
||||
"description": "Survey BL domains: sales/customer side",
|
||||
"run_in_background": false,
|
||||
"model": null,
|
||||
"prompt": "You are surveying a large legacy C# ERP codebase (c-entron) at C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP for a reverse-engineering requirements effort. This is READ-ONLY research — do not modify anything.\n\nFocus on these subfolders of the business logic project `src\\backend\\Centron.BL\\`:\n- Sales (this is large — includes Customer/Helpdesk/ticketing; look for subfolders like Sales\\Customer\\Helpdesk if present)\n- CustomerArea\n- BusinessPartner\n- Projects\n- TicketProjects\n- TaskManager\n- Time\n- CPra\n- EDI\n- Mail\n- Mailings\n\nFor EACH of these folders, report:\n1. Purpose/business domain in one or two sentences, inferred from class/method names and any comments.\n2. The 3-8 most important classes (with exact file path) and what they do.\n3. Any status/state enums or state-machine-like logic (e.g. ticket status, order status) with transition guard conditions — quote enum values and exact file/method.\n4. Any validation logic or business rules enforced in code — exact file/method reference.\n5. Any permission/rights checks (references to UserRightsConst or similar, especially anything matching entries in CentronRights.md like Helpdesk rights) — exact file/method reference.\n6. Any DB constraints, stored procedures, or SQL visible (file path).\n\nBe concrete and always cite exact file paths (relative to repo root) and class/method names or line numbers. Sample representatively for huge folders, note what you skipped.\n\nReport back structured, one section per folder. Keep total response under ~2500 words — prioritize concrete evidence (file paths + short quotes) over prose.",
|
||||
"ergebnis_zeichen": 13557
|
||||
},
|
||||
{
|
||||
"id": "toolu_019xFjsDuuhReRjdrQ3rxKzG",
|
||||
"werkzeug": "Agent",
|
||||
"subagent_type": "Explore",
|
||||
"description": "Survey Entities and DAO data model",
|
||||
"run_in_background": false,
|
||||
"model": null,
|
||||
"prompt": "You are surveying a large legacy C# ERP codebase (c-entron) at C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP for a reverse-engineering requirements effort. This is READ-ONLY research — do not modify anything.\n\nFocus on:\n- src\\backend\\Centron.Entities\\ (data model / entity classes)\n- src\\backend\\Centron.DAO\\ (data access layer)\n- src\\backend\\Centron.Interfaces\\ (interfaces, may reveal contracts)\n- Search the whole repo for .sql files (migration scripts, schema definitions) — report where they live and what a representative one contains (e.g. CREATE TABLE, CHECK, FOREIGN KEY constraints).\n\nReport:\n1. Overall structure of Centron.Entities and Centron.DAO — how are entities organized (by domain folder? one giant namespace?), what ORM/data access pattern is used (NHibernate? Entity Framework? raw ADO.NET? look for mapping files like .hbm.xml or Fluent mappings or DbContext).\n2. List 10-15 core entity classes central to the domain (e.g. things like Customer/Kunde, Order/Auftrag, Invoice/Rechnung, Article/Artikel, Employee/Mitarbeiter) with exact file paths, and their most important fields/relationships.\n3. Any DB-level constraints you can find (NOT NULL, CHECK, FOREIGN KEY, UNIQUE) in .sql or mapping files — exact file + snippet.\n4. Any enums representing status/type fields used across many entities (e.g. a generic status enum) — file path + values.\n5. Evidence of multi-tenancy, soft-delete, audit/history tracking patterns (e.g. a \"ChangeTracking\" mechanism, \"deleted\" flags, \"created by/modified by\" fields) — file path.\n\nBe concrete, cite exact file paths and short code snippets. Sample representatively given the scale, note what you skipped. Keep response under ~2500 words.",
|
||||
"ergebnis_zeichen": 11901
|
||||
},
|
||||
{
|
||||
"id": "toolu_017VawHGcNQRBJBuHWeTSzib",
|
||||
"werkzeug": "Agent",
|
||||
"subagent_type": "Explore",
|
||||
"description": "Survey interfaces, webservice and external APIs",
|
||||
"run_in_background": false,
|
||||
"model": null,
|
||||
"prompt": "You are surveying a large legacy C# ERP codebase (c-entron) at C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP for a reverse-engineering requirements effort. This is READ-ONLY research — do not modify anything.\n\nFocus on:\n- src\\webservice\\ (Centron.Controllers, Centron.Host, Centron.Host.Console, Centron.Host.WindowsService, Centron.WebServices.Core, c-entron.misc.ConnectionManager)\n- src\\apis\\ (Centron.APIs.CopDataAccess, Centron.APIs.EgisDataAccess, Centron.APIs.FinAPI, Centron.APIs.ITscopeDataAccess, Centron.APIs.IcecatDataAccess, Centron.Api.EbInterface, Centron.Api.Gls, Centron.Api.Shipcloud)\n- Centron.Api.docuFORM (top-level folder)\n\nReport:\n1. For src\\webservice: what kind of service is this (REST API? WCF? SOAP?), how are controllers/endpoints organized, list 10-15 representative endpoint/controller classes with exact file paths and what business function they expose. Look for authentication/authorization attributes on controllers (exact file + attribute).\n2. For each external API integration under src\\apis\\ and Centron.Api.docuFORM: what external system does it integrate with (infer from name/code — COP, Egis, FinAPI, ITscope, Icecat, ebInterface [likely e-invoicing], GLS [shipping], Shipcloud [shipping], docuFORM [likely PDF/document generation or e-signature]), what data flows in/out, exact file path for the main client/service class.\n3. Any rate limiting, retry logic, timeout configuration, or error handling policies visible for these integrations — exact file reference.\n4. Any API versioning, request/response DTOs that hint at the external contract shape — exact file path.\n\nBe concrete, cite exact file paths. Sample representatively, note what you skipped. Keep response under ~2500 words.",
|
||||
"ergebnis_zeichen": 13305
|
||||
},
|
||||
{
|
||||
"id": "toolu_01RenrX7KYjqsYv88VQyog3w",
|
||||
"werkzeug": "Agent",
|
||||
"subagent_type": "Explore",
|
||||
"description": "Survey security and permissions enforcement",
|
||||
"run_in_background": false,
|
||||
"model": null,
|
||||
"prompt": "You are surveying a large legacy C# ERP codebase (c-entron) at C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP for a reverse-engineering requirements effort. This is READ-ONLY research — do not modify anything.\n\nGoal: understand how authentication and authorization (\"rights\") work across the system, since this feeds security requirements that need strong evidence.\n\nSteps:\n1. Read C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP\\CentronRights.md fully (it documents ~a small sample of rights, e.g. Helpdesk, Kalender, Mitarbeiterauslastung) to understand the rights naming convention (UserRightsConst.*).\n2. Find where UserRightsConst is defined (search for \"class UserRightsConst\" or similar) — exact file path, and get a sense of how many rights constants exist total (rough count) and how they're namespaced/organized.\n3. Find the actual enforcement mechanism: search for a method like `HasRight`, `CheckRight`, `IsAllowed`, or similar that takes a UserRightsConst value and returns bool — exact file/class/method. Quote a representative implementation if not too long.\n4. Find 5-10 representative call sites across different modules (Sales, Finances, Security folder, WPF UI) where a right is checked before an action — exact file/line + the right being checked + what it gates.\n5. Look at src\\backend\\Centron.BL\\Security\\ folder specifically — what's in there (authentication, session handling, password management, 2FA — note TwoFactorAuthenticator folder exists in BL too, and PasswordManagementArea/PasswordManager).\n6. Look for any encryption, hashing of passwords, or token-based auth (JWT?) — exact file reference.\n7. Look for any audit logging of security-relevant actions (login, rights changes) — exact file reference.\n\nBe concrete, cite exact file paths and short snippets. Keep response under ~2500 words.",
|
||||
"ergebnis_zeichen": 11497
|
||||
},
|
||||
{
|
||||
"id": "toolu_016d43StAEwPXmp9HWQNPV5J",
|
||||
"werkzeug": "Agent",
|
||||
"subagent_type": "Explore",
|
||||
"description": "Survey Nexus web and WPF desktop UI",
|
||||
"run_in_background": false,
|
||||
"model": null,
|
||||
"prompt": "You are surveying a large legacy C# ERP codebase (c-entron) at C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP for a reverse-engineering requirements effort. This is READ-ONLY research — do not modify anything.\n\nFocus on:\n- src\\nexus\\ (CentronNexus, CentronNexus.Host, CentronNexus.OutlookAddIn) — this is a Blazor-based web frontend, \"c-entron Nexus\" per its README.md\n- src\\centron\\Centron.WPF.UI and Centron.WPF.UI.Extension — the legacy WPF desktop client\n\nReport:\n1. For CentronNexus: what are the main pages/features exposed via the web (look at .razor files, folder structure under Pages or Components). The root README.md mentions a \"WebCart\" feature for customers of customers logging in as a \"web-account\" — find the relevant code (search for WebCart) and describe how it works based on code (exact file paths). List other distinct web-facing features you find (e.g. helpdesk portal, document viewer, offer acceptance / C-Sign — there's a recent commit about \"C-Sign (WebOffer & Acceptance)\", try to find that code).\n2. For Centron.WPF.UI: this is presumably the main desktop ERP client. List the top-level folder/module structure (just directory names, one level or two deep) to map desktop screens to BL domains from Accounting/Sales/Warehousing/etc. Identify how many distinct \"masks\"/views exist roughly (count .xaml files if easy). Look for a Ribbon-related module (mentioned to have custom ribbon merging) — exact folder/file.\n3. Any evidence of role-based UI customization (menus/buttons hidden based on rights) — exact file reference, tie back to UserRightsConst if visible.\n4. Any localization/multi-language evidence (resource files, .resx) — note languages supported if visible.\n\nBe concrete, cite exact file paths. Sample representatively given scale (these are large UI trees), note what you skipped. Keep response under ~2500 words.",
|
||||
"ergebnis_zeichen": 10366
|
||||
},
|
||||
{
|
||||
"id": "toolu_01Xx1xu6RiPckpy6ENJGacQ8",
|
||||
"werkzeug": "Agent",
|
||||
"subagent_type": "Explore",
|
||||
"description": "Survey deployment, docs and NFR evidence",
|
||||
"run_in_background": false,
|
||||
"model": null,
|
||||
"prompt": "You are surveying a large legacy C# ERP codebase (c-entron) at C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP for a reverse-engineering requirements effort. This is READ-ONLY research — do not modify anything.\n\nFocus on non-functional / operational evidence:\n- deployment\\ folder\n- docker\\ folder and .dockerignore at root\n- azure\\ and azure-blazor\\ folders\n- scripts\\ folder\n- docs\\ folder (subfolders: \"Background Service\", features, getting-started, guides, operations, reference) — READ the README.md and a representative sample of files in each subfolder, these are likely genuine feature/ops documentation written by the dev team\n- global.json, Directory.Build.props, nuget.config, version.json at root (just report .NET version / key facts)\n- .github folder (CI/CD workflows — what do they build/test/deploy)\n- tests\\ folder — what test projects exist, roughly how many test files, what's covered (unit/integration/e2e?)\n\nReport:\n1. Deployment architecture as far as inferable (containerized? Azure App Service? on-prem Windows service + desktop client distribution?) — exact file references.\n2. Logging approach (what logging framework, where configured) — exact file reference.\n3. Configuration management (appsettings.json, connection strings, secrets handling) — exact file reference, and flag anything that looks like a hardcoded secret (do NOT quote the secret value, just note file + line and that it looks sensitive).\n4. .NET target framework version(s) used across the solution.\n5. CI/CD: what pipelines exist, what they do (build/test/deploy stages) — exact file reference.\n6. Summarize the docs\\ folder content per subfolder — what topics are documented (this may directly describe existing requirements/features in the dev team's own words) — list file names and one-line summaries.\n7. Test coverage impression: which BL/domain areas have dedicated test projects, which appear to have none.\n\nBe concrete, cite exact file paths. Keep response under ~2500 words.",
|
||||
"ergebnis_zeichen": 15353
|
||||
},
|
||||
{
|
||||
"id": "toolu_01QVX8oYQyzWKBc1JENviUfE",
|
||||
"werkzeug": "Agent",
|
||||
"subagent_type": "Explore",
|
||||
"description": "Deep dive invoicing, offers and C-Sign billing logic",
|
||||
"run_in_background": false,
|
||||
"model": null,
|
||||
"prompt": "You are surveying a large legacy C# ERP codebase (c-entron) at C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP for a reverse-engineering requirements effort. This is READ-ONLY research — do not modify anything.\n\nThis is a DEEP DIVE into billing/invoicing/offer logic specifically, because these requirements need strong PRIMARY evidence (enforced code/DB constraints, not just UI labels).\n\nRecent commit history mentions:\n- \"Ticket 168496 & 169060 - C-Sign (WebOffer & Acceptance)\" — find this code: search for \"CSign\", \"C-Sign\", \"WebOffer\" across the repo (likely in Centron.BL\\Sales or similar, and in CentronNexus for the web acceptance flow).\n- \"Ticket 150766: rights check for editing invoice or delivery list date in the settings of timer billing\" — search for \"TimerBilling\" or similar in Centron.BL\\Time or Sales, find the rights check added.\n\nAlso investigate generally:\n1. Where is Angebot (offer/quote), Auftrag (order), Lieferschein (delivery note), and Rechnung (invoice) status logic implemented? Look in Centron.BL\\Sales and Centron.BL\\Finances / Accounting. Find the status enum(s) (e.g. quote states: open/accepted/rejected/expired; invoice states: draft/posted/paid/cancelled) — exact file + enum values.\n2. Find the exact method(s) that transition an invoice from draft to \"posted\"/finalized (booked, irreversible) — what validation/guards exist before that transition (e.g. can't post if sum is zero, can't edit after posting)? Exact file/method/line, quote the guard condition code if short.\n3. Find how tax (VAT/MwSt) is calculated — exact file/method.\n4. Find where the C-Sign / WebOffer acceptance flow validates a customer's acceptance (e.g. signature captured, then order status changes) — exact file/method, and what business rule enforces that an offer can only be accepted once / within a validity period, if present.\n5. Find the rights check added for editing invoice/delivery-list dates in timer billing settings (from the commit mentioned above) — exact file/method/UserRightsConst name.\n6. Any DB constraints (in .sql files or mapping) around invoice/financial tables (e.g. immutability, foreign keys to accounting periods) — exact file.\n\nBe concrete, cite exact file paths, class/method names, and short code quotes for guard conditions. This is the highest-scrutiny domain so precision matters more than breadth. Keep response under ~3000 words.",
|
||||
"ergebnis_zeichen": 8638
|
||||
}
|
||||
]
|
||||
+232
@@ -0,0 +1,232 @@
|
||||
# Subagenten-Aufrufe
|
||||
|
||||
Session `18b1d5b6-f3e3-49cd-b5aa-38bf1fff642c`, Transkript `18b1d5b6-f3e3-49cd-b5aa-38bf1fff642c.jsonl`.
|
||||
|
||||
`subagent_stats`: **8** Subagenten gesamt, davon **0** von Subagenten gestartet (max_depth 1). Direkt vom Hauptagenten erwartet: **8**. Im Transkript gefunden: **8**.
|
||||
|
||||
## 1. Survey BL domains: finance/logistics side
|
||||
|
||||
- **Werkzeug:** `Agent` **Typ:** `Explore` **Hintergrund:** False
|
||||
- **Prompt-Zeichen:** 1596 **Ergebnis-Zeichen:** 14338
|
||||
|
||||
### Prompt
|
||||
|
||||
```
|
||||
You are surveying a large legacy C# ERP codebase (c-entron) at C:\DEV\MasterArbeit\QuellCode\CentronERP for a reverse-engineering requirements effort. This is READ-ONLY research — do not modify anything.
|
||||
|
||||
Focus on these subfolders of the business logic project `src\backend\Centron.BL\`:
|
||||
- Accounting
|
||||
- Buying
|
||||
- Finances
|
||||
- Warehousing
|
||||
- Purchasing
|
||||
- Production
|
||||
- Logistics
|
||||
- TradePool
|
||||
- VoucherManagement
|
||||
- Storage
|
||||
|
||||
For EACH of these folders, report:
|
||||
1. Purpose/business domain in one or two sentences, inferred from class/method names and any comments.
|
||||
2. The 3-8 most important classes (with exact file path) and what they do.
|
||||
3. Any status/state enums or state-machine-like logic (e.g., an enum like `InvoiceStatus`, and methods that transition between states with guard conditions) — quote the enum values and the exact file/method where transitions are enforced.
|
||||
4. Any validation logic or business rules enforced in code (e.g. "cannot post an invoice if X") — with exact file/method reference.
|
||||
5. Any permission/rights checks (e.g. references to UserRightsConst or similar) — exact file/method reference.
|
||||
6. Any DB constraints, stored procedures, or SQL visible in these areas (file path).
|
||||
|
||||
Be concrete and always cite exact file paths (relative to repo root) and, where feasible, class/method names or line numbers. If a folder is huge, sample representatively rather than reading every file, but note what you skipped.
|
||||
|
||||
Report back in a structured format, one section per folder. Keep total response under ~2500 words — prioritize concrete evidence (file paths + short quotes) over prose.
|
||||
```
|
||||
|
||||
## 2. Survey BL domains: sales/customer side
|
||||
|
||||
- **Werkzeug:** `Agent` **Typ:** `Explore` **Hintergrund:** False
|
||||
- **Prompt-Zeichen:** 1581 **Ergebnis-Zeichen:** 13557
|
||||
|
||||
### Prompt
|
||||
|
||||
```
|
||||
You are surveying a large legacy C# ERP codebase (c-entron) at C:\DEV\MasterArbeit\QuellCode\CentronERP for a reverse-engineering requirements effort. This is READ-ONLY research — do not modify anything.
|
||||
|
||||
Focus on these subfolders of the business logic project `src\backend\Centron.BL\`:
|
||||
- Sales (this is large — includes Customer/Helpdesk/ticketing; look for subfolders like Sales\Customer\Helpdesk if present)
|
||||
- CustomerArea
|
||||
- BusinessPartner
|
||||
- Projects
|
||||
- TicketProjects
|
||||
- TaskManager
|
||||
- Time
|
||||
- CPra
|
||||
- EDI
|
||||
- Mail
|
||||
- Mailings
|
||||
|
||||
For EACH of these folders, report:
|
||||
1. Purpose/business domain in one or two sentences, inferred from class/method names and any comments.
|
||||
2. The 3-8 most important classes (with exact file path) and what they do.
|
||||
3. Any status/state enums or state-machine-like logic (e.g. ticket status, order status) with transition guard conditions — quote enum values and exact file/method.
|
||||
4. Any validation logic or business rules enforced in code — exact file/method reference.
|
||||
5. Any permission/rights checks (references to UserRightsConst or similar, especially anything matching entries in CentronRights.md like Helpdesk rights) — exact file/method reference.
|
||||
6. Any DB constraints, stored procedures, or SQL visible (file path).
|
||||
|
||||
Be concrete and always cite exact file paths (relative to repo root) and class/method names or line numbers. Sample representatively for huge folders, note what you skipped.
|
||||
|
||||
Report back structured, one section per folder. Keep total response under ~2500 words — prioritize concrete evidence (file paths + short quotes) over prose.
|
||||
```
|
||||
|
||||
## 3. Survey Entities and DAO data model
|
||||
|
||||
- **Werkzeug:** `Agent` **Typ:** `Explore` **Hintergrund:** False
|
||||
- **Prompt-Zeichen:** 1692 **Ergebnis-Zeichen:** 11901
|
||||
|
||||
### Prompt
|
||||
|
||||
```
|
||||
You are surveying a large legacy C# ERP codebase (c-entron) at C:\DEV\MasterArbeit\QuellCode\CentronERP for a reverse-engineering requirements effort. This is READ-ONLY research — do not modify anything.
|
||||
|
||||
Focus on:
|
||||
- src\backend\Centron.Entities\ (data model / entity classes)
|
||||
- src\backend\Centron.DAO\ (data access layer)
|
||||
- src\backend\Centron.Interfaces\ (interfaces, may reveal contracts)
|
||||
- Search the whole repo for .sql files (migration scripts, schema definitions) — report where they live and what a representative one contains (e.g. CREATE TABLE, CHECK, FOREIGN KEY constraints).
|
||||
|
||||
Report:
|
||||
1. Overall structure of Centron.Entities and Centron.DAO — how are entities organized (by domain folder? one giant namespace?), what ORM/data access pattern is used (NHibernate? Entity Framework? raw ADO.NET? look for mapping files like .hbm.xml or Fluent mappings or DbContext).
|
||||
2. List 10-15 core entity classes central to the domain (e.g. things like Customer/Kunde, Order/Auftrag, Invoice/Rechnung, Article/Artikel, Employee/Mitarbeiter) with exact file paths, and their most important fields/relationships.
|
||||
3. Any DB-level constraints you can find (NOT NULL, CHECK, FOREIGN KEY, UNIQUE) in .sql or mapping files — exact file + snippet.
|
||||
4. Any enums representing status/type fields used across many entities (e.g. a generic status enum) — file path + values.
|
||||
5. Evidence of multi-tenancy, soft-delete, audit/history tracking patterns (e.g. a "ChangeTracking" mechanism, "deleted" flags, "created by/modified by" fields) — file path.
|
||||
|
||||
Be concrete, cite exact file paths and short code snippets. Sample representatively given the scale, note what you skipped. Keep response under ~2500 words.
|
||||
```
|
||||
|
||||
## 4. Survey interfaces, webservice and external APIs
|
||||
|
||||
- **Werkzeug:** `Agent` **Typ:** `Explore` **Hintergrund:** False
|
||||
- **Prompt-Zeichen:** 1723 **Ergebnis-Zeichen:** 13305
|
||||
|
||||
### Prompt
|
||||
|
||||
```
|
||||
You are surveying a large legacy C# ERP codebase (c-entron) at C:\DEV\MasterArbeit\QuellCode\CentronERP for a reverse-engineering requirements effort. This is READ-ONLY research — do not modify anything.
|
||||
|
||||
Focus on:
|
||||
- src\webservice\ (Centron.Controllers, Centron.Host, Centron.Host.Console, Centron.Host.WindowsService, Centron.WebServices.Core, c-entron.misc.ConnectionManager)
|
||||
- src\apis\ (Centron.APIs.CopDataAccess, Centron.APIs.EgisDataAccess, Centron.APIs.FinAPI, Centron.APIs.ITscopeDataAccess, Centron.APIs.IcecatDataAccess, Centron.Api.EbInterface, Centron.Api.Gls, Centron.Api.Shipcloud)
|
||||
- Centron.Api.docuFORM (top-level folder)
|
||||
|
||||
Report:
|
||||
1. For src\webservice: what kind of service is this (REST API? WCF? SOAP?), how are controllers/endpoints organized, list 10-15 representative endpoint/controller classes with exact file paths and what business function they expose. Look for authentication/authorization attributes on controllers (exact file + attribute).
|
||||
2. For each external API integration under src\apis\ and Centron.Api.docuFORM: what external system does it integrate with (infer from name/code — COP, Egis, FinAPI, ITscope, Icecat, ebInterface [likely e-invoicing], GLS [shipping], Shipcloud [shipping], docuFORM [likely PDF/document generation or e-signature]), what data flows in/out, exact file path for the main client/service class.
|
||||
3. Any rate limiting, retry logic, timeout configuration, or error handling policies visible for these integrations — exact file reference.
|
||||
4. Any API versioning, request/response DTOs that hint at the external contract shape — exact file path.
|
||||
|
||||
Be concrete, cite exact file paths. Sample representatively, note what you skipped. Keep response under ~2500 words.
|
||||
```
|
||||
|
||||
## 5. Survey security and permissions enforcement
|
||||
|
||||
- **Werkzeug:** `Agent` **Typ:** `Explore` **Hintergrund:** False
|
||||
- **Prompt-Zeichen:** 1809 **Ergebnis-Zeichen:** 11497
|
||||
|
||||
### Prompt
|
||||
|
||||
```
|
||||
You are surveying a large legacy C# ERP codebase (c-entron) at C:\DEV\MasterArbeit\QuellCode\CentronERP for a reverse-engineering requirements effort. This is READ-ONLY research — do not modify anything.
|
||||
|
||||
Goal: understand how authentication and authorization ("rights") work across the system, since this feeds security requirements that need strong evidence.
|
||||
|
||||
Steps:
|
||||
1. Read C:\DEV\MasterArbeit\QuellCode\CentronERP\CentronRights.md fully (it documents ~a small sample of rights, e.g. Helpdesk, Kalender, Mitarbeiterauslastung) to understand the rights naming convention (UserRightsConst.*).
|
||||
2. Find where UserRightsConst is defined (search for "class UserRightsConst" or similar) — exact file path, and get a sense of how many rights constants exist total (rough count) and how they're namespaced/organized.
|
||||
3. Find the actual enforcement mechanism: search for a method like `HasRight`, `CheckRight`, `IsAllowed`, or similar that takes a UserRightsConst value and returns bool — exact file/class/method. Quote a representative implementation if not too long.
|
||||
4. Find 5-10 representative call sites across different modules (Sales, Finances, Security folder, WPF UI) where a right is checked before an action — exact file/line + the right being checked + what it gates.
|
||||
5. Look at src\backend\Centron.BL\Security\ folder specifically — what's in there (authentication, session handling, password management, 2FA — note TwoFactorAuthenticator folder exists in BL too, and PasswordManagementArea/PasswordManager).
|
||||
6. Look for any encryption, hashing of passwords, or token-based auth (JWT?) — exact file reference.
|
||||
7. Look for any audit logging of security-relevant actions (login, rights changes) — exact file reference.
|
||||
|
||||
Be concrete, cite exact file paths and short snippets. Keep response under ~2500 words.
|
||||
```
|
||||
|
||||
## 6. Survey Nexus web and WPF desktop UI
|
||||
|
||||
- **Werkzeug:** `Agent` **Typ:** `Explore` **Hintergrund:** False
|
||||
- **Prompt-Zeichen:** 1849 **Ergebnis-Zeichen:** 10366
|
||||
|
||||
### Prompt
|
||||
|
||||
```
|
||||
You are surveying a large legacy C# ERP codebase (c-entron) at C:\DEV\MasterArbeit\QuellCode\CentronERP for a reverse-engineering requirements effort. This is READ-ONLY research — do not modify anything.
|
||||
|
||||
Focus on:
|
||||
- src\nexus\ (CentronNexus, CentronNexus.Host, CentronNexus.OutlookAddIn) — this is a Blazor-based web frontend, "c-entron Nexus" per its README.md
|
||||
- src\centron\Centron.WPF.UI and Centron.WPF.UI.Extension — the legacy WPF desktop client
|
||||
|
||||
Report:
|
||||
1. For CentronNexus: what are the main pages/features exposed via the web (look at .razor files, folder structure under Pages or Components). The root README.md mentions a "WebCart" feature for customers of customers logging in as a "web-account" — find the relevant code (search for WebCart) and describe how it works based on code (exact file paths). List other distinct web-facing features you find (e.g. helpdesk portal, document viewer, offer acceptance / C-Sign — there's a recent commit about "C-Sign (WebOffer & Acceptance)", try to find that code).
|
||||
2. For Centron.WPF.UI: this is presumably the main desktop ERP client. List the top-level folder/module structure (just directory names, one level or two deep) to map desktop screens to BL domains from Accounting/Sales/Warehousing/etc. Identify how many distinct "masks"/views exist roughly (count .xaml files if easy). Look for a Ribbon-related module (mentioned to have custom ribbon merging) — exact folder/file.
|
||||
3. Any evidence of role-based UI customization (menus/buttons hidden based on rights) — exact file reference, tie back to UserRightsConst if visible.
|
||||
4. Any localization/multi-language evidence (resource files, .resx) — note languages supported if visible.
|
||||
|
||||
Be concrete, cite exact file paths. Sample representatively given scale (these are large UI trees), note what you skipped. Keep response under ~2500 words.
|
||||
```
|
||||
|
||||
## 7. Survey deployment, docs and NFR evidence
|
||||
|
||||
- **Werkzeug:** `Agent` **Typ:** `Explore` **Hintergrund:** False
|
||||
- **Prompt-Zeichen:** 1973 **Ergebnis-Zeichen:** 15353
|
||||
|
||||
### Prompt
|
||||
|
||||
```
|
||||
You are surveying a large legacy C# ERP codebase (c-entron) at C:\DEV\MasterArbeit\QuellCode\CentronERP for a reverse-engineering requirements effort. This is READ-ONLY research — do not modify anything.
|
||||
|
||||
Focus on non-functional / operational evidence:
|
||||
- deployment\ folder
|
||||
- docker\ folder and .dockerignore at root
|
||||
- azure\ and azure-blazor\ folders
|
||||
- scripts\ folder
|
||||
- docs\ folder (subfolders: "Background Service", features, getting-started, guides, operations, reference) — READ the README.md and a representative sample of files in each subfolder, these are likely genuine feature/ops documentation written by the dev team
|
||||
- global.json, Directory.Build.props, nuget.config, version.json at root (just report .NET version / key facts)
|
||||
- .github folder (CI/CD workflows — what do they build/test/deploy)
|
||||
- tests\ folder — what test projects exist, roughly how many test files, what's covered (unit/integration/e2e?)
|
||||
|
||||
Report:
|
||||
1. Deployment architecture as far as inferable (containerized? Azure App Service? on-prem Windows service + desktop client distribution?) — exact file references.
|
||||
2. Logging approach (what logging framework, where configured) — exact file reference.
|
||||
3. Configuration management (appsettings.json, connection strings, secrets handling) — exact file reference, and flag anything that looks like a hardcoded secret (do NOT quote the secret value, just note file + line and that it looks sensitive).
|
||||
4. .NET target framework version(s) used across the solution.
|
||||
5. CI/CD: what pipelines exist, what they do (build/test/deploy stages) — exact file reference.
|
||||
6. Summarize the docs\ folder content per subfolder — what topics are documented (this may directly describe existing requirements/features in the dev team's own words) — list file names and one-line summaries.
|
||||
7. Test coverage impression: which BL/domain areas have dedicated test projects, which appear to have none.
|
||||
|
||||
Be concrete, cite exact file paths. Keep response under ~2500 words.
|
||||
```
|
||||
|
||||
## 8. Deep dive invoicing, offers and C-Sign billing logic
|
||||
|
||||
- **Werkzeug:** `Agent` **Typ:** `Explore` **Hintergrund:** False
|
||||
- **Prompt-Zeichen:** 2373 **Ergebnis-Zeichen:** 8638
|
||||
|
||||
### Prompt
|
||||
|
||||
```
|
||||
You are surveying a large legacy C# ERP codebase (c-entron) at C:\DEV\MasterArbeit\QuellCode\CentronERP for a reverse-engineering requirements effort. This is READ-ONLY research — do not modify anything.
|
||||
|
||||
This is a DEEP DIVE into billing/invoicing/offer logic specifically, because these requirements need strong PRIMARY evidence (enforced code/DB constraints, not just UI labels).
|
||||
|
||||
Recent commit history mentions:
|
||||
- "Ticket 168496 & 169060 - C-Sign (WebOffer & Acceptance)" — find this code: search for "CSign", "C-Sign", "WebOffer" across the repo (likely in Centron.BL\Sales or similar, and in CentronNexus for the web acceptance flow).
|
||||
- "Ticket 150766: rights check for editing invoice or delivery list date in the settings of timer billing" — search for "TimerBilling" or similar in Centron.BL\Time or Sales, find the rights check added.
|
||||
|
||||
Also investigate generally:
|
||||
1. Where is Angebot (offer/quote), Auftrag (order), Lieferschein (delivery note), and Rechnung (invoice) status logic implemented? Look in Centron.BL\Sales and Centron.BL\Finances / Accounting. Find the status enum(s) (e.g. quote states: open/accepted/rejected/expired; invoice states: draft/posted/paid/cancelled) — exact file + enum values.
|
||||
2. Find the exact method(s) that transition an invoice from draft to "posted"/finalized (booked, irreversible) — what validation/guards exist before that transition (e.g. can't post if sum is zero, can't edit after posting)? Exact file/method/line, quote the guard condition code if short.
|
||||
3. Find how tax (VAT/MwSt) is calculated — exact file/method.
|
||||
4. Find where the C-Sign / WebOffer acceptance flow validates a customer's acceptance (e.g. signature captured, then order status changes) — exact file/method, and what business rule enforces that an offer can only be accepted once / within a validity period, if present.
|
||||
5. Find the rights check added for editing invoice/delivery-list dates in timer billing settings (from the commit mentioned above) — exact file/method/UserRightsConst name.
|
||||
6. Any DB constraints (in .sql files or mapping) around invoice/financial tables (e.g. immutability, foreign keys to accounting periods) — exact file.
|
||||
|
||||
Be concrete, cite exact file paths, class/method names, and short code quotes for guard conditions. This is the highest-scrutiny domain so precision matters more than breadth. Keep response under ~3000 words.
|
||||
```
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
# Analysebericht
|
||||
|
||||
**Status: ENTWURF / IN BEARBEITUNG** — dieser Bericht wird laufend während der Analyse aktualisiert und am Ende der Iteration finalisiert (Konsistenzcheck, Selbstbewertung).
|
||||
|
||||
## 1. Untersuchungsgegenstand
|
||||
|
||||
Codebasis: `C:\DEV\MasterArbeit\QuellCode\CentronERP` (c-entron ERP-Suite), Git-Branch `main`, Stand des Commits `79c1142f48`.
|
||||
|
||||
Umfang (statische Auszählung): 22.346 Dateien unter `src/`, davon 15.554 `.cs`-Dateien, 1.233 `.xaml`-Dateien, 491 `.razor`-Dateien. Keine `.sql`-Skriptdateien im Repository gefunden (Datenbankschema wird über C#-Migrationsklassen ausgerollt, siehe unten).
|
||||
|
||||
Hinweis: Der jüngste Commit (`79c1142f48`, "Versuchsbasis: KI-Assistenz-Konfigurationen entfernt") hat `.claude/`, `CLAUDE.md` und `.cursor/` entfernt; einige interne Entwicklerdokumente (`docs/getting-started/ai-codebase-navigation.md`) verweisen noch auf diese entfernten Dateien. Dies ist für die vorliegende Analyse ohne Belang, wird aber der Vollständigkeit halber dokumentiert.
|
||||
|
||||
## 2. Architektur-Überblick (grob)
|
||||
|
||||
| Bereich | Pfad | Rolle |
|
||||
|---|---|---|
|
||||
| Backend-Geschäftslogik | `src/backend/Centron.BL` | Serverseitige Fachlogik, NHibernate-Zugriff, ~90 fachliche Unterordner |
|
||||
| Backend-Datenzugriff | `src/backend/Centron.DAO` | FluentNHibernate-Mappings |
|
||||
| Backend-Entitäten | `src/backend/Centron.Entities` | NHibernate-Entity-Klassen |
|
||||
| Gemeinsame Verträge | `src/backend/Centron.Interfaces` | Rechte-, Settings-, Lizenz-Konstanten; Legacy-REST-Contract (`ICentronRestService`) |
|
||||
| WPF-Desktop-Client | `src/centron/Centron.WPF.UI` | Hauptanwendung "c-entron.NET" (Windows) |
|
||||
| Web-API (modern) | `src/webservice/Centron.Controllers` | ASP.NET-Core-Controller (`v1/...`, `Unversioned/...`) |
|
||||
| Web-API (legacy) | `src/webservice/Centron.WebServices.Core` | Legacy-REST-Dienst (`CentronRestService.cs`), DTOs |
|
||||
| Web-Hosts | `src/webservice/Centron.Host*` | Hostprozesse (Console, Windows-Dienst) |
|
||||
| Web-Portal | `src/nexus/CentronNexus` | Blazor-Server-Webclient ("c-entron Nexus"), inkl. WebCart/WebOffer/C-Sign |
|
||||
| Externe Integrationen | `src/apis/*` | Distributoren-/Katalog-/Versand-/Finanz-Schnittstellen (CopDataAccess, EgisDataAccess, ITscopeDataAccess, IcecatDataAccess, FinAPI, EbInterface, Gls, Shipcloud) |
|
||||
| Geteilte Bausteine | `src/shared/*` | `Centron.Core`, `Centron.Controls` |
|
||||
| Tests | `tests/*` | Unit (BL/DAO), Integration, End-to-End, Playwright, Nexus-Tests |
|
||||
| Deployment | `docker/`, `azure/`, `azure-blazor/`, `deployment/` | Docker-Compose-Stack, Azure-Pipelines, WiX-Installer |
|
||||
|
||||
Quelle: eigene Verzeichniserhebung (`find`, `.csproj`-Liste) und `docs/getting-started/ai-codebase-navigation.md`, `docs/getting-started/general-structure.md`.
|
||||
|
||||
## 3. Modul-/Themenabdeckung dieser Iteration (wird laufend aktualisiert)
|
||||
|
||||
Legende Analysetiefe: **TIEF** (Code + Dokumentation gelesen, mehrere Belege), **MITTEL** (Dokumentation + stichprobenhafte Code-Belege), **OBERFLÄCHLICH** (nur Verzeichnisstruktur/Namen erhoben), **NICHT ANALYSIERT**.
|
||||
|
||||
| Fachbereich (Centron.BL-Ordner u. verwandte Bereiche) | Analysetiefe | Quelle(n) |
|
||||
|---|---|---|
|
||||
| Web-API / Auth / Nexus / Deployment (Systemarchitektur) | TIEF | Subagent-Recherche (Controllers, Authorization, CentronHost.cs, Nexus, Docker/Azure-Pipelines) |
|
||||
| Sales – Belegsystem (Angebot/Auftrag/Lieferschein/Rechnung/Gutschrift/Abholschein) | TIEF | `docs/reference/receipts/receipts-backend-architecture.md` + Subagent-Recherche |
|
||||
| Sales – Verträge (Contracts, Kontingente, RMM-Abrechnung) | TIEF | `docs/reference/receipts/contracts-backend.md`, `Contract-Billing-RMM-Article-Logic.md` |
|
||||
| Security / Rechte (Sichrech, UserRightsConst) | MITTEL–TIEF | `CentronRights.md`, `docs/guides/development/add-a-new-right.md`, `check-userrights.md` + Subagent-Recherche |
|
||||
| Lizenzsystem | TIEF | `docs/reference/security/licensing-system.md` |
|
||||
| Authentifizierung (Ticket, JWT/OIDC) | TIEF | `docs/reference/security/anmelden-mit-microsoft-technische-anleitung.md` + Subagent-Recherche |
|
||||
| Einstellungen (ApplicationSettings/Stammdat) | MITTEL | `docs/guides/development/settings-management.md` |
|
||||
| EDI (Lieferanten-Datenaustausch) | MITTEL | `docs/reference/edi/edi-architecture.md` |
|
||||
| ActionPrice / Preismatrix | MITTEL–TIEF | `docs/reference/receipts/actionprice-system.md` |
|
||||
| Helpdesk / Ticket (inkl. automatische Ticketerstellung) | MITTEL | `CentronRights.md`, `docs/features/automatic-helpdesk-creation-templates.md` |
|
||||
| Datenbank-Konventionen (Schema, Skripte) | TIEF | `docs/guides/database/database-conventions.md`, `docs/reference/database/script-rules.md` |
|
||||
| Architekturmuster (ILogic/BL/WS, DTO/Entity, Result/Response) | TIEF | `docs/getting-started/general-structure.md`, `docs/reference/architecture/*.md` |
|
||||
| Lokalisierung (DE/EN) | MITTEL | `docs/guides/ui/localization.md` |
|
||||
| Hintergrunddienste (DataQualityService) | MITTEL | `docs/Background Service/DataQualityService.md` |
|
||||
| Buying/Purchasing, Warehousing, Logistics, TradePool | *ausstehend* | Subagent-Recherche läuft |
|
||||
| BusinessPartner/CRM, Angebots-/Auftragsstatus, C-Sign | *ausstehend* | Subagent-Recherche läuft |
|
||||
| Accounting/Finances, Voucher-Nummernkreise, Zahlungslogik | *ausstehend* | Subagent-Recherche läuft |
|
||||
| Entities/DAO-Konventionen (Concurrency, Multi-Tenancy, Soft-Delete) | *ausstehend* | Subagent-Recherche läuft |
|
||||
| Alle übrigen ~75 `Centron.BL`-Unterordner (u. a. Production, TicketProjects, MailScanner, Mobile, Outlook, TwoFactorAuthenticator im Detail, VideoPortal, SocialMedia, ItPlanner, ProductMatrix, Chats, Notifications, Mailings, WebSuite, Tapi, TaskManager, ToDoArea u. v. m.) | NICHT ANALYSIERT | nur Verzeichnisname erhoben |
|
||||
| WPF-Client-Module im Detail (`Centron.WPF.UI/Modules/*`) | NICHT ANALYSIERT | nur Verzeichnisstruktur erhoben |
|
||||
| Externe API-Integrationen im Detail (COP, EGIS, ITscope, Icecat, FinAPI, EbInterface, GLS, Shipcloud) | OBERFLÄCHLICH | *ausstehend*, teilweise durch Purchasing-Subagent |
|
||||
|
||||
*Dieser Abschnitt wird nach Abschluss aller Teilrecherchen final aktualisiert (Abschnitt "Selbstbewertung" unten).*
|
||||
|
||||
## 4. Konsistenzcheck
|
||||
|
||||
*Wird nach Fertigstellung aller Anforderungsdokumente durchgeführt (doppelte IDs, Anforderungen ohne Beleg, ungültige Tracelinks).*
|
||||
|
||||
## 5. Selbstbewertung
|
||||
|
||||
*Wird am Ende der Iteration ergänzt.*
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
# Glossar
|
||||
|
||||
Domänenbegriffe, die in StRS/SyRS/SwRS verwendet werden. Technische Bezeichner (Klassen, Tabellen, Methoden) bleiben unübersetzt. Quellenangaben sind Sekundär-/Kontextbelege für die Begriffsklärung, nicht für die zugehörigen Anforderungen (diese führen eigene Belege).
|
||||
|
||||
| Begriff | Definition | Quelle (Kontext) |
|
||||
|---|---|---|
|
||||
| **I3D** | Primärschlüsselspalte ("ID 3develop") jeder Tabelle; `int IDENTITY(1,1) NOT NULL`, geclusterter PK. Fremdschlüssel enden auf das Suffix `I3D` (z. B. `AccountI3D`). | `docs/guides/database/database-conventions.md` |
|
||||
| **Beleg / Receipt** | Sammelbegriff für die kaufmännischen Vorgangsdokumente der Sales-Pipeline. Alle Belegtypen erben von der abstrakten Basisklasse `ReceiptBase` (`src/backend/Centron.Entities/Entities/Sales/Receipts/ReceiptBase.cs`). | `docs/reference/receipts/receipts-backend-architecture.md` |
|
||||
| **Angebot (Offer)** | Beleg-Typ "Angebot"; Entity `ReceiptOffer`, Tabelle `AngKopf`/`AngPos`, View `Offers`/`OfferItems`. | ebd. |
|
||||
| **Auftrag (Order)** | Beleg-Typ "Auftrag"; Entity `ReceiptOrder`, Tabelle `AufKopf`/`AufPos`, View `Orders`/`OrderItems`. | ebd. |
|
||||
| **Lieferschein (Delivery List)** | Beleg-Typ "Lieferschein"; Entity `ReceiptDeliveryList`, Tabelle `LiefKopf`/`LiefPos`. | ebd. |
|
||||
| **Rechnung (Invoice)** | Beleg-Typ "Rechnung"; Entity `ReceiptInvoice`, Tabelle `RechKopf`/`RechPos`. | ebd. |
|
||||
| **Vertrag (Contract)** | Beleg-Typ für wiederkehrende Leistungen/Verträge; Entity `ReceiptContract`, Tabelle `VertragKopf`/`VertragPos`; unterstützt Abrechnungsintervalle, Kontingente, Geräteanbindung. | `docs/reference/receipts/contracts-backend.md` |
|
||||
| **Gutschrift (Credit Voucher)** | Beleg-Typ "Gutschrift"; Entity `ReceiptCreditVoucher`, Tabelle `GutKopf`/`GutPos`. | `docs/reference/receipts/receipts-backend-architecture.md` |
|
||||
| **Abholschein (Pickup List)** | Beleg-Typ "Abholschein"; Entity `ReceiptPickupList`, Tabelle `AbholKopf`/`AbholPos`. | ebd. |
|
||||
| **Kopf/Pos-Muster** | Wiederkehrendes DB-Muster: `*Kopf`-Tabelle für den Belegkopf, `*Pos`-Tabelle für Positionszeilen, `*KopfVersions`/`*PosVersions` für 1:1-Versionshistorie. | ebd. |
|
||||
| **AnlageLog** | Zentrale, tabellenübergreifende Protokolltabelle für Belegereignisse; referenziert über `AnlageI3D` + `AnlageArt` (Typkennzahl je Belegtyp, z. B. 4 = Rechnung, 22 = Vertrag). | ebd. |
|
||||
| **Kontingent (Contingent)** | Im Vertrag hinterlegtes Leistungs-/Stundenbudget, das durch Leistungen verbraucht wird (`ContingentUsedHours`, `ContingentUsedAmount`, `ContingentLimitValue` u. a.). | `docs/reference/receipts/contracts-backend.md` |
|
||||
| **RMM (Remote Monitoring & Management)** | Externes Überwachungssystem (Produktname intern "Riverbird"), aus dem Nutzungsdaten für die automatische Vertragsabrechnung bezogen werden (`RiverConnectionBL`). | `docs/reference/receipts/Contract-Billing-RMM-Article-Logic.md` |
|
||||
| **Sichrech** | Datenbanktabelle, die alle Berechtigungen ("Rechte") des Systems auflistet; jede Zeile entspricht einer Konstante in `UserRightsConst.cs`. | `docs/guides/development/add-a-new-right.md` |
|
||||
| **Recht (Right)** | Feingranulare, hierarchisch organisierte Berechtigung (z. B. `UserRightsConst.Sales.Customer.Helpdesk.SHOW_HELPDESK`); kann Gruppen zugewiesen werden; "einschränkende Rechte" (restricting rights) filtern statt zu gewähren (z. B. "nur eigene Filiale"). | `CentronRights.md`, `docs/guides/development/check-userrights.md` |
|
||||
| **Filiale (Branch)** | Organisationseinheit, nach der Datensätze isoliert/gefiltert werden können (`BranchI3D`); Basis mehrerer "einschränkender Rechte". | `CentronRights.md` |
|
||||
| **Mandant** | (Hypothesenkandidat, siehe Hypothesen.md) Mögliche Mehrmandantenfähigkeit oberhalb der Filialebene. | |
|
||||
| **Lizenz (License)** | GUID-basiertes Merkmal, das eine Anwendung ("Application", darf sich am Webservice anmelden) oder ein Einzelfeature freischaltet; verwaltet in `LicenseGuids.cs`/`ApplicationKind.cs`, geprüft via `LicenseManager`. | `docs/reference/security/licensing-system.md` |
|
||||
| **Ticket (Application/Auth)** | Sitzungs-Token, das nach erfolgreichem Login clientseitig für weitere API-Aufrufe verwendet wird; serverseitig in Tabelle `Ticket` mit Ablaufzeit (u. a. 30 Minuten bei OIDC-Login). | `docs/reference/security/anmelden-mit-microsoft-technische-anleitung.md` |
|
||||
| **BL (Business Logic)** | Serverseitige Geschäftslogik-Schicht, arbeitet direkt mit NHibernate-Entities und der DB (`Centron.BL`). | `docs/getting-started/general-structure.md` |
|
||||
| **WebServiceBL** | Schicht, die Entities in DTOs konvertiert und die Webservice-Methoden bereitstellt. | ebd. |
|
||||
| **DTO (Data Transfer Object)** | Datenübertragungsobjekt zwischen WebService und Client/ViewModel; darf keine Fachlogik enthalten. | `docs/reference/architecture/dtos-and-entities.md` |
|
||||
| **ILogic / BLLogic / WSLogic** | Dreiteiliges Client-Zugriffsmuster: `ILogic`-Interface, `BLLogic`-Implementierung (Direktzugriff SQL Server) und `WSLogic`-Implementierung (Webservice-Zugriff); pro Modul verpflichtend beide Implementierungen. | `docs/getting-started/general-structure.md` |
|
||||
| **ClassContainer** | Client-seitiger DI-Container/Singleton, der die passende `ILogic`-Implementierung (BL oder WS) je nach Verbindungstyp auflöst. | ebd. |
|
||||
| **Result / Response** | Internes (`Result`/`Result<T>`) bzw. API-seitiges (`Response`/`Response<T>`) Standardobjekt für Erfolg/Fehler/Warnung-Status und Fehlermeldungen. | `docs/reference/architecture/results-and-responses.md` |
|
||||
| **ActionPrice (Aktionspreis)** | Zeitlich befristeter Sonderpreis von Distributoren/Herstellern zu einem Artikel; eigene Quelle innerhalb der "Preismatrix" neben externen Preisquellen (ITscope, COP, NEOS, TradersGuide, EGIS). | `docs/reference/receipts/actionprice-system.md` |
|
||||
| **Preismatrix (Price Matrix)** | UI/Backend-Mechanismus, der Einkaufspreise aus mehreren internen/externen Quellen parallel für einen Artikel anzeigt. | ebd. |
|
||||
| **EDI (Electronic Data Interchange)** | Automatisierter elektronischer Belegaustausch mit Lieferanten (Bestellungen, Auftragsbestätigungen, Lieferungen, Rechnungen) über lieferantenspezifische Formate (OpenTrans 2.1, ALSO, ALSO CH, Herweck, Komsa, Alltron) sowie ZUGFeRD für Rechnungen. | `docs/reference/edi/edi-architecture.md` |
|
||||
| **ZUGFeRD / XRechnung** | Standards für strukturierte/elektronische Rechnungen (Deutschland); im System als Datenaustauschformat für Rechnungen verankert (u. a. `IsZugferdInvoiceActive`-Einstellung). | `docs/guides/development/xrechnung.md`, `docs/guides/development/settings-management.md` |
|
||||
| **C-Sign** | Funktion zur elektronischen Unterschrift/Annahme von Web-Angeboten durch den Kunden (WebOffer & Acceptance). | Commit `89ccfd650d` "Ticket 168496 & 169060 - C-Sign (WebOffer & Acceptance)" |
|
||||
| **WebCart** | Self-Service-Bestellfunktion für Kunden der Kunden (Endkunden mit Web-Account), basierend auf hinterlegten "Sonderpreisen". | `README.md` (Nexus) |
|
||||
| **TradePool** | Eigenständiges BL-Modul (`Centron.BL/TradePool`); Funktion gemäß Codebasis noch nicht abschließend verifiziert (siehe Hypothesen.md). | |
|
||||
| **Nexus (c-entron Web / c-entron Nexus)** | Blazor-Server-basierter Web-Client des Systems, u. a. für Kundenportal-/WebCart-Funktionen; nutzt DevExpress-Blazor-Komponenten. | `README.md`, `docs/getting-started/ai-codebase-navigation.md` |
|
||||
| **c-entron.NET (WPF-Client)** | Desktop-Hauptclient des ERP-Systems (Windows/WPF), Projekt `Centron.WPF.UI`. | `docs/getting-started/general-structure.md` |
|
||||
| **DataQualityService** | Serverseitiger Hintergrunddienst (`BackgroundService`), der stündlich Datenbereinigungs- und Konsistenzaufgaben ausführt. | `docs/Background Service/DataQualityService.md` |
|
||||
| **DeveloperSecurity** | Schutzmechanismus, der in Debug-Builds E-Mail-Versand an externe (nicht-`nexoware.com`) Adressen automatisch auf eine Testadresse umleitet. | `docs/reference/security/developer-security.md` |
|
||||
| **ApplicationSettings / Stammdat** | Zwei parallele DB-Tabellen für Systemeinstellungen; `Stammdat` ist die historische, `ApplicationSettings` die aktuelle Tabelle für neue Einstellungen. | `docs/guides/development/settings-management.md` |
|
||||
|
||||
*Weitere Begriffe werden bei Bedarf in Folge-Iterationen ergänzt (siehe Analysebericht.md, Abschnitt "Empfehlungen für Folge-Iteration").*
|
||||
+896
@@ -0,0 +1,896 @@
|
||||
# StRS — Stakeholder Requirements Specification
|
||||
|
||||
c-entron ERP-Suite — Reverse Requirements Engineering, Iteration 01 (Baseline).
|
||||
Fachliche Sicht: Akteure, Geschäftsziele, Geschäftsprozesse. Ebene: `StRS`.
|
||||
|
||||
Akteure (aus Rechte-/Modulanalyse abgeleitet, `[HYPOTHESE]`-Anteile siehe Hypothesen.md):
|
||||
Innendienst-/Vertriebsmitarbeiter, Einkäufer, Lager-/Logistikmitarbeiter, Buchhaltung/Controlling, Servicetechniker/Helpdesk-Bearbeiter, Systemadministrator, Kunde (Web-Account/WebCart), Endkunde ohne Web-Account (nur Angebotsempfänger via C-Sign), externer Lieferant/Distributor (EDI-Gegenstelle), c-entron/NEXOWARE-Entwickler & DevOps.
|
||||
|
||||
---
|
||||
|
||||
## A. Beleg-Lebenszyklus & Belegweiterleitung (Sales Order-to-Cash)
|
||||
|
||||
```
|
||||
ID: StRS-001
|
||||
Titel: Einheitlicher Belegzyklus für kaufmännische Vorgangsdokumente
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Vertriebsmitarbeiter, System
|
||||
Vorbedingung: Ein Geschäftsvorfall (Angebot, Auftrag, Lieferschein, Rechnung, Vertrag, Gutschrift, Abholschein) wird angelegt.
|
||||
Fakt: Alle Belegtypen erben von der gemeinsamen Basisklasse `ReceiptBase` und nutzen denselben Statuswert `ReceiptState` (`Active`=offen, `Completed`=abgeschlossen, `Canceled`=storniert).
|
||||
Aussage: Das System soll alle kaufmännischen Belegarten (Angebot, Auftrag, Lieferschein, Rechnung, Vertrag, Gutschrift, Abholschein) über ein einheitliches, gemeinsames Belegmodell mit denselben drei Grundzuständen (offen/abgeschlossen/storniert) abbilden.
|
||||
Ergebnis: Jeder Beleg besitzt zu jedem Zeitpunkt genau einen der drei definierten Zustände; belegtypübergreifende Auswertungen und UI-Bausteine sind wiederverwendbar.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Interfaces/Sales/Receipts/ReceiptState.cs:6-14 - Begründung: Definiert die durchgesetzte Zustandsmenge (Active=1, Completed=2, Canceled=3), von der `ReceiptBase.State` typisiert ist.
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/Sales/Receipts/ReceiptBase.cs - Begründung: Abstrakte Basisklasse, von der alle sieben Belegentitäten (ReceiptOffer, ReceiptOrder, ReceiptDeliveryList, ReceiptInvoice, ReceiptContract, ReceiptCreditVoucher, ReceiptPickupList) erben.
|
||||
- [SEKUNDÄR] docs/reference/receipts/receipts-backend-architecture.md - Begründung: Beschreibt die Belegtyp-Tabelle und das Kopf/Pos-Muster für alle sieben Belegarten.
|
||||
Prüfidee: Für jeden der sieben Belegtypen erzeugen, in jeden der drei Zustände überführen und prüfen, dass kein vierter Zustand erreichbar ist.
|
||||
Tracelinks: SyRS-001, SyRS-002
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-002
|
||||
Titel: Kontrollierte Belegweiterleitung entlang der Vertriebskette
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Vertriebsmitarbeiter
|
||||
Vorbedingung: Ein Beleg (z. B. Angebot) existiert und soll in einen Folgebeleg überführt werden.
|
||||
Fakt: Jeder Belegtyp deklariert über `IReceiptSpecificLogic` explizit, aus welchen Belegtypen er weitergeleitet werden darf (`CanBeForwardedFrom`) und in welche Belegtypen er weitergeleitet werden darf (`CanBeForwardedInto`); z. B. darf ein Auftrag nur aus einem Angebot entstehen und nur in Lieferschein, Rechnung oder Vertrag weitergeleitet werden.
|
||||
Aussage: Das System soll die Weiterleitung eines Belegs in einen Folgebeleg nur entlang fachlich vordefinierter, je Belegtyp konfigurierter Übergänge zulassen.
|
||||
Ergebnis: Unzulässige Belegübergänge (z. B. direkte Umwandlung eines Lieferscheins in ein Angebot) werden verhindert; die Vertriebskette Angebot→Auftrag→Lieferschein/Rechnung/Vertrag bleibt nachvollziehbar.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/Orders/OrderSpecificLogic.cs:256-257 - Begründung: `CanBeForwardedFrom() => [OfferClass]`, `CanBeForwardedInto() => [DeliveryListClass, InvoiceClass, ContractClass]` legen den erlaubten Übergangsgraphen für Aufträge fest.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs (ForwardReceipt<TTarget,...>) - Begründung: Zentrale, generische Weiterleitungsmethode, die die deklarierten Übergänge durchsetzt.
|
||||
- [SEKUNDÄR] src/backend/Centron.BL/Sales/CustomerAssets/Offers/OfferBL.cs:98-106 (ForewardOfferToOrder) - Begründung: Konkrete Implementierung des Übergangs Angebot→Auftrag im (parallelen) Legacy-Belegsystem.
|
||||
Prüfidee: Versuch, einen Lieferschein direkt in ein Angebot umzuwandeln, muss vom System zurückgewiesen werden; Angebot→Auftrag muss gelingen.
|
||||
Tracelinks: SyRS-003
|
||||
Konsolidierung: Kandidat: Zwei parallele Implementierungen (Legacy "Asset"-System `Sales/CustomerAssets/*` und modernes "Receipt"-System `Sales/Receipts/*`) bilden denselben Belegzyklus und dieselbe Weiterleitungslogik redundant ab (siehe SwRS-Abschnitt "Datenmodell").
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-003
|
||||
Titel: Nachvollziehbare Versionshistorie kaufmännischer Belege
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Vertriebsmitarbeiter, Buchhaltung, Systemadministrator (Revisionssicherheit)
|
||||
Vorbedingung: Ein bestehender Beleg wird inhaltlich geändert (z. B. Stornierung, Preisänderung, Feldänderung nach Erstanlage).
|
||||
Fakt: Für jeden Belegtyp existiert eine 1:1-Versions-Schattentabelle (`*KopfVersions`/`*PosVersions`), die bei jeder relevanten Änderung eine vollständige Kopie des vorherigen Zustands anlegt; jede neue Spalte muss zwingend auch in der Versionstabelle ergänzt werden.
|
||||
Aussage: Das System soll bei jeder wesentlichen Änderung eines Belegs eine vollständige, unveränderliche Kopie des vorherigen Belegzustands (Kopf und Positionen) revisionssicher speichern.
|
||||
Ergebnis: Zu jedem Beleg ist die vollständige Änderungshistorie inklusive früherer Werte rekonstruierbar.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/reference/receipts/receipts-backend-architecture.md (Abschnitt "Version Tables: 1:1 Copies") - Begründung: Dokumentiert Pflicht zur identischen Spaltenstruktur zwischen Basis- und Versionstabelle sowie den `AssetHeadDAO.SaveAssetVersion`-Mechanismus.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs (CancelInvoice, CreateNewVersion) - Begründung: Eine Rechnungsstornierung erzeugt nachweislich eine neue Version statt den Beleg in-place zu verändern.
|
||||
- [SEKUNDÄR] docs/reference/receipts/contracts-backend.md - Begründung: Bestätigt dasselbe Muster für Verträge (VertragKopfVersions/VertragPosVersions).
|
||||
Prüfidee: Rechnung stornieren und prüfen, dass eine neue Version erzeugt wird und die ursprünglichen Werte in der Versionstabelle erhalten bleiben.
|
||||
Tracelinks: SyRS-004, SyRS-005
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-004
|
||||
Titel: Schutz vor gleichzeitiger Bearbeitung desselben Belegs
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Vertriebsmitarbeiter
|
||||
Vorbedingung: Zwei Benutzer öffnen denselben Beleg gleichzeitig zur Bearbeitung.
|
||||
Fakt: Es existieren zwei parallele Schutzmechanismen: ein anwendungsseitiges pessimistisches Sperrobjekt je Belegtyp (`*Lock`-Entität mit `Lockuser`-Spalte) sowie ein optimistisches `ConcurrencyControlGuid`-Feld auf `ReceiptBase`, das bei Speicherung auf Konflikt geprüft wird.
|
||||
Aussage: Das System soll verhindern, dass zwei Benutzer denselben Beleg gleichzeitig widersprüchlich bearbeiten und speichern können.
|
||||
Ergebnis: Ein zweiter Benutzer erhält beim Versuch, einen gesperrten oder zwischenzeitlich geänderten Beleg zu speichern, eine Fehlermeldung statt eines stillen Datenverlusts.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/Sales/CustomerAssets/AssetLocks/AssetLock.cs:6-10 - Begründung: Enthält `Lockuser` und `Version`, das explizite anwendungsseitige Sperrmodell.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs (UpdateReceiptIsPaid, ConcurrencyControlGuid-Prüfung) - Begründung: Verifizierter Code-Pfad, der bei Guid-Mismatch einen Fehler zurückgibt.
|
||||
- [SEKUNDÄR] tests/Centron.Tests.EndToEnd/Tests/ReceiptLock/*.expected.txt (8 Testfälle) - Begründung: End-to-End-Tests decken alle Kombinationen aus "gesperrt/nicht gesperrt", "durch anderen Benutzer gesperrt" und "Benutzerrecht vorhanden" ab und bestätigen, dass dies als geschäftskritische Regel getestet wird.
|
||||
Prüfidee: Beleg durch Benutzer A öffnen (sperren), Speicherversuch durch Benutzer B muss abgelehnt bzw. mit Hinweis versehen werden.
|
||||
Tracelinks: SyRS-006
|
||||
Konsolidierung: Kandidat: Zwei redundante Mechanismen (pessimistische Sperre + optimistisches Concurrency-Guid) lösen dieselbe fachliche Anforderung; im Zielsystem auf einen Mechanismus konsolidieren.
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## B. Verträge & wiederkehrende Abrechnung
|
||||
|
||||
```
|
||||
ID: StRS-005
|
||||
Titel: Automatisierte, intervallbasierte Vertragsabrechnung
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Buchhaltung, Vertriebsinnendienst
|
||||
Vorbedingung: Ein Servicevertrag mit konfiguriertem Abrechnungsintervall (täglich/monatlich/quartalsweise/jährlich) und `AutomatedBilling = true` existiert.
|
||||
Fakt: `ReceiptContract` besitzt Felder `BillingIntervalKind`, `BillingIntervalDuration`, `AutomatedBilling`; `AutomaticFacturaBL.Contracts` erzeugt automatisiert Rechnungen auf Basis der Intervallkonfiguration.
|
||||
Aussage: Das System soll wiederkehrende Vertragsleistungen automatisiert gemäß dem konfigurierten Abrechnungsintervall in Rechnungen überführen, ohne dass für jede Abrechnung eine manuelle Rechnungserstellung nötig ist.
|
||||
Ergebnis: Fällige Verträge werden zum Stichtag automatisch abgerechnet; das Abrechnungsdatum des Vertrags wird fortgeschrieben.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/Sales/Receipts/ContractLists/ReceiptContract.cs (BillingIntervalKind, AutomatedBilling, LastSubsequentBillingDate) - Begründung: Datenmodell erzwingt Erfassung der Abrechnungskonfiguration am Vertrag.
|
||||
- [SEKUNDÄR] docs/reference/receipts/contracts-backend.md (Abschnitt "Automated Billing Process") - Begründung: Beschreibt den dreistufigen Ablauf Contract Evaluation → Invoice Generation → Post-Processing.
|
||||
- [SEKUNDÄR] src/backend/Centron.BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.Contracts.cs - Begründung: Konkrete Klasse für automatisierte Vertragsabrechnung inkl. RMM-Integration.
|
||||
Prüfidee: Vertrag mit monatlichem Intervall und fälligem Abrechnungsdatum anlegen, Abrechnungslauf ausführen, Rechnung sowie fortgeschriebenes `LastSubsequentBillingDate` prüfen.
|
||||
Tracelinks: SyRS-007, SyRS-008
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-006
|
||||
Titel: Verbrauchsbasierte Abrechnung aus externem Monitoring-System (RMM)
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Buchhaltung, Servicetechniker
|
||||
Vorbedingung: Ein Vertrag ist für RMM-Abrechnung konfiguriert (`WhetherRMM` = true) und besitzt Artikelreferenzen zu RMM-Metriken.
|
||||
Fakt: Während `CreateInvoiceToContractComplete` ruft `CheckRMMArticle` den externen RMM-Dienst ("Riverbird") über `RiverConnectionBL.GetContractBillingAmounts` ab und fügt für jede Artikelreferenz mit Nutzungsdaten eine berechnete Rechnungsposition ein; ist der Dienst nicht erreichbar und werden RMM-Artikel erwartet, wird eine `RMMServiceUnavailableException` geworfen und die Rechnungserstellung abgebrochen.
|
||||
Aussage: Das System soll nutzungsbasierte Vertragspositionen automatisch anhand von Messdaten eines externen Remote-Monitoring-Systems berechnen und in die Rechnung einfügen; ist der externe Dienst nicht erreichbar, darf keine Rechnung mit unvollständigen Nutzungsdaten erzeugt werden.
|
||||
Ergebnis: Entweder wird die Rechnung mit korrekten, aktuellen Nutzungsdaten erstellt, oder die Erstellung wird kontrolliert abgebrochen (kein stillschweigend falscher Rechnungsbetrag).
|
||||
Belege:
|
||||
- [PRIMÄR] docs/reference/receipts/Contract-Billing-RMM-Article-Logic.md (Abschnitt "Error Handling") - Begründung: Beschreibt den Abbruchmechanismus samt zitiertem Code (`RMMServiceUnavailableException`) und die fachliche Begründung ("ensuring customers are billed correctly").
|
||||
- [PRIMÄR] AutomaticFacturaWebServiceBL / RiverConnectionBL (referenziert in obiger Doku) - Begründung: Konkrete Klassen der Nutzungsdatenabfrage und Rechnungspositionserzeugung.
|
||||
Prüfidee: Rechnungslauf für einen RMM-Vertrag bei simuliert nicht erreichbarem RMM-Dienst ausführen; erwartetes Ergebnis: Abbruch mit definierter Fehlermeldung, keine Rechnung erzeugt.
|
||||
Tracelinks: SyRS-009
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-007
|
||||
Titel: Kontingentverwaltung für Servicevereinbarungen
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Buchhaltung, Servicetechniker
|
||||
Vorbedingung: Ein Vertrag mit Leistungskontingent (Stunden oder Betrag) existiert.
|
||||
Fakt: `ReceiptContract` führt `ContingentUsedHours`, `ContingentUsedAmount`, `ContingentLimitValue`, `ContingentLimitKind`, `IsMonitoring`; `ReceiptContractBL.ContractContingentBalanceCalculation` berechnet Verbrauch und Restbestand.
|
||||
Aussage: Das System soll den Verbrauch eines vertraglich vereinbarten Leistungskontingents (Stunden oder Betrag) fortlaufend erfassen, den Restbestand ausweisen und bei Erreichen konfigurierter Grenzwerte eine Überwachung ermöglichen.
|
||||
Ergebnis: Vertragsverantwortliche erkennen Kontingentüberschreitungen zeitnah; Abrechnung von Mehrverbrauch ("Überbuchung") ist möglich.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/reference/receipts/contracts-backend.md (Abschnitt "Contingent Management") - Begründung: Listet die konkreten Entitätsfelder für Kontingentverbrauch und -grenzen.
|
||||
- [SEKUNDÄR] ReceiptContractBL.UpdateTakeRestAndOverBooking() (referenziert in obiger Doku) - Begründung: Konkrete Methode zur Behandlung von Restbeträgen und Überbuchung.
|
||||
Prüfidee: Vertrag mit Stundenkontingent anlegen, Verbrauch über das Kontingent hinaus buchen, Monitoring-Warnung/Restbestand prüfen.
|
||||
Tracelinks: SyRS-008
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## C. C-Sign — Elektronische Web-Angebotsannahme & Signatur
|
||||
|
||||
```
|
||||
ID: StRS-008
|
||||
Titel: Digitale Kundenannahme von Web-Angeboten mit interner Freigabe
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Kunde (ohne Login), Vertriebsmitarbeiter (Freigabe)
|
||||
Vorbedingung: Ein Angebot wurde für die Kundenannahme über einen Web-Link vorbereitet.
|
||||
Fakt: `WebReceiptState`-Enum umfasst u. a. `SendToCustomer`, `WebOfferSign`, `AcceptFullWebReceipt`, `AcceptWebReceiptWithChangeRequests`, `Rejected`; `SharedDocumentAcceptancePage.razor` verlangt laut UI-Text eine interne Mitarbeiter-Prüfung ("Bitte Prüfen Sie dieses Dokument, bevor es an den Kunden geht"), bevor das Dokument dem Kunden zur Unterschrift zugestellt wird.
|
||||
Aussage: Das System soll Kunden die webbasierte Annahme, Änderungsanforderung oder Ablehnung eines Angebots ermöglichen, wobei dem Versand an den Kunden optional eine interne Freigabeprüfung durch einen Mitarbeiter vorgeschaltet ist.
|
||||
Ergebnis: Der Angebotsstatus spiegelt lückenlos den Weg von "an Kunden gesendet" über ggf. "zur Unterschrift" bis "angenommen/abgelehnt/mit Änderungswunsch" wider.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Interfaces/Sales/Receipts/WebReceipt/WebReceiptState.cs:6-26 - Begründung: Definiert die vollständige, im Code durchgesetzte Zustandsmenge des Web-Angebotsprozesses.
|
||||
- [PRIMÄR] src/nexus/CentronNexus/Office/SharedDocumentAcceptancePage.razor - Begründung: UI-Text und `AcceptSharedDocument()`/`DeclineSharedDocument()` belegen die interne Freigabestufe vor Kundenversand.
|
||||
- [SEKUNDÄR] src/nexus/CentronNexus/WebOffer/WebReceiptOverview.razor - Begründung: Kundenseitige Annahme-/Ablehnungs-/Kommentarfunktion (`RejectWebReceipt`, `ChangeWebReceiptState`, `LeaveComment`).
|
||||
Prüfidee: Angebot über den Web-Kanal versenden, interne Freigabe erteilen, Kundenannahme simulieren, resultierenden Auftrag und Statuskette prüfen.
|
||||
Tracelinks: SyRS-010, SyRS-011
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-009
|
||||
Titel: Rechtssichere elektronische Signatur von Kundendokumenten
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Kunde, System
|
||||
Vorbedingung: Ein Angebot erfordert laut Konfiguration eine Signatur (kein `AllowAcceptReceiptWithoutSignature`).
|
||||
Fakt: `PdfSigningBL.SignPdfDocument` signiert das PDF serverseitig mit einem hochgeladenen PKCS12-Zertifikat via DevExpress `PdfDocumentSigner`/`Pkcs7Signer`, optional mit Zeitstempel eines TSA-Servers.
|
||||
Aussage: Das System soll kundenseitig zu unterzeichnende Dokumente mit einer zertifikatsbasierten elektronischen Signatur (inkl. optionalem Zeitstempel) versehen können.
|
||||
Ergebnis: Das signierte PDF-Dokument ist kryptographisch nachweisbar unverändert und mit Signaturzeitpunkt versehen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Security/PdfSigningBL.cs:126-165 - Begründung: Konkrete Implementierung der PDF-Signatur inkl. Zertifikats- und TSA-Handling.
|
||||
Prüfidee: Dokument mit gültigem Zertifikat signieren und die Signatur mit einem PDF-Prüfwerkzeug verifizieren.
|
||||
Tracelinks: SyRS-011
|
||||
Konsolidierung: nein
|
||||
Status: belegt; [HYPOTHESE] unklar, ob zusätzlich eine handschriftliche Kundenunterschrift (Bitmap) erfasst wird — nicht im untersuchten Code gefunden (siehe Hypothesen.md H-01).
|
||||
```
|
||||
|
||||
## D. Kunden/CRM, Kreditlimit, Sonderpreise
|
||||
|
||||
```
|
||||
ID: StRS-010
|
||||
Titel: Schutz vor Umsatzausfall durch Kreditlimitkontrolle
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Vertriebsmitarbeiter, Buchhaltung
|
||||
Vorbedingung: Für einen Kunden ist ein Kreditlimit (`CreditLimit`) hinterlegt; ein neuer, offener Auftrag soll gespeichert werden.
|
||||
Fakt: `ReceiptBL.CheckIfCustomerLimitIsReached` summiert den bereits genutzten Kreditrahmen aus allen limitrelevanten, offenen Belegen und vergleicht ihn mit `Customer.CreditLimit`; bei Überschreitung wird `ShowCustomerLimitExceededDialog` gesetzt und der Benutzer muss aktiv bestätigen ("Möchten Sie den Speichervorgang fortsetzen?").
|
||||
Aussage: Das System soll beim Speichern eines Auftrags prüfen, ob das vereinbarte Kreditlimit des Kunden durch alle offenen Belege überschritten würde, und den Benutzer in diesem Fall aktiv zur Bestätigung auffordern, bevor gespeichert wird.
|
||||
Ergebnis: Eine Kreditlimitüberschreitung wird nicht stillschweigend zugelassen, kann aber vom berechtigten Benutzer bewusst übersteuert werden (weicher, kein harter Block).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs:8636 (CheckIfCustomerLimitIsReached) - Begründung: Enthält die vollständige Berechnungs- und Dialoglogik inkl. deutschsprachiger Nutzermeldung.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/Orders/OrderSpecificLogic.cs:356-380 (TakesPlaceInLimitCalculation, GetUsedLimitAmount) - Begründung: Legt fest, dass nur `Active`-Aufträge in die Kreditlimitberechnung einfließen.
|
||||
Prüfidee: Kunde mit Kreditlimit 1.000 € anlegen, offene Aufträge über 1.000 € erfassen, weiteren Auftrag anlegen und Bestätigungsdialog verifizieren.
|
||||
Tracelinks: SyRS-012
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-011
|
||||
Titel: Kundenindividuelle Sonderpreise als Grundlage des Web-Einkaufs
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Vertriebsinnendienst, Kunde (Web-Account)
|
||||
Vorbedingung: Für einen Kunden sind Sonderpreise ("Sonderpreise") gepflegt.
|
||||
Fakt: `Customer.SpecialPrices` (Collection von `CustomerSpecialPrice`) wird gemäß README als Grundlage für die im WebCart sichtbaren Artikel verwendet; `CustomersController` stellt eigene Endpunkte `special-price-articles` bereit.
|
||||
Aussage: Das System soll es ermöglichen, kundenindividuelle Sonderpreise zu pflegen, und soll diese Sonderpreise als Grundlage dafür verwenden, welche Artikel ein Kunde über den Web-Selbstbedienungskanal (WebCart) sehen und bestellen kann.
|
||||
Ergebnis: Kunden im WebCart sehen ausschließlich für sie freigegebene/bepreiste Artikel; die Pflege erfolgt zentral im ERP.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/CustomerArea/Customer.cs:28,266 (SpecialPrices) - Begründung: Entity-seitige Verknüpfung Kunde↔Sonderpreisliste.
|
||||
- [PRIMÄR] src/webservice/Centron.Controllers/Controllers/v1/Customers/CustomersController.cs (GET special-price-articles, GET {customerId}/special-price-articles) - Begründung: Dedizierte API-Endpunkte, die dieses Konzept operationalisieren.
|
||||
- [KONTEXT] README.md (Abschnitt "WebCart") - Begründung: Beschreibt explizit den fachlichen Zusammenhang zwischen Sonderpreisen und WebCart-Sichtbarkeit.
|
||||
Prüfidee: Kunde mit Sonderpreisen für Artikel X anlegen, per Web-Account im WebCart einloggen, Sichtbarkeit von Artikel X prüfen.
|
||||
Tracelinks: SyRS-013, SyRS-014
|
||||
Konsolidierung: Kandidat: `ProductMatrix`-Mechanismus (kundenindividuelle Katalogkategorien/Produkte) deckt fachlich ähnliches Ziel ab (Steuerung der für einen Kunden sichtbaren Artikel) — Verhältnis zu Sonderpreisen ungeklärt, siehe Hypothesen.md.
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-012
|
||||
Titel: Einheitliche Geschäftspartner-Stammdaten für Kunden und Lieferanten
|
||||
Ebene: StRS
|
||||
Typ: Daten
|
||||
Akteur: Vertriebsinnendienst, Einkäufer
|
||||
Vorbedingung: Eine Adresse/Kontaktperson soll sowohl im Kunden- als auch im Lieferantenkontext nutzbar sein.
|
||||
Fakt: `Address` besitzt sowohl `CustomerI3D` als auch `SupplierI3D` als nullable Fremdschlüssel; ein expliziter "BusinessPartner"-Entitätstyp existiert nicht, Kunde (`Customer`) und Lieferant (`Supplier`) sind getrennte Klassen, teilen sich aber dasselbe Adress-/Kontaktmodell.
|
||||
Aussage: Das System soll Adress- und Kontaktinformationen so verwalten, dass dieselbe physische Struktur sowohl für Kunden als auch für Lieferanten verwendbar ist.
|
||||
Ergebnis: Adress-/Kontaktdaten müssen nicht separat für Kunden- und Lieferantensicht gepflegt werden.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/CustomerArea/Address.cs:13-14 - Begründung: Zeigt die duale FK-Struktur (`CustomerI3D`, `SupplierI3D`) auf derselben Tabelle.
|
||||
Prüfidee: Adressobjekt für einen Lieferanten anlegen und prüfen, dass dieselbe Tabellenstruktur wie bei Kundenadressen verwendet wird.
|
||||
Tracelinks: SwRS (siehe SwRS-Abschnitt Datenmodell)
|
||||
Konsolidierung: Kandidat: Es existiert daneben ein neuerer Begriff "Account" (`Centron.BL/Accounts/*`) als mögliche Nachfolgeabstraktion zu `Customer` — Verhältnis ungeklärt, [HYPOTHESE] siehe Hypothesen.md H-02.
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## E. Helpdesk / Ticket
|
||||
|
||||
```
|
||||
ID: StRS-013
|
||||
Titel: Automatische Serviceticket-Erstellung aus Aufträgen mit Vorlagen
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Vertriebsmitarbeiter, Servicetechniker
|
||||
Vorbedingung: Ein Auftrag wird abgeschlossen bzw. es sollen für Auftragspositionen automatisiert Helpdesk-Tickets erzeugt werden.
|
||||
Fakt: Feature "Automatic Helpdesk Creation Templates": Nutzer können mehrere benannte Vorlagen (`HelpdeskCreationTemplate`) für die automatische Ticketerstellung pflegen, eine davon als Standard markieren; Vorlage bestimmt u. a. Kategorie, Einzel-/Sammelticket-Modus, automatisches Öffnen.
|
||||
Aussage: Das System soll es ermöglichen, aus Auftragspositionen automatisiert Helpdesk-Tickets zu erzeugen, wobei Nutzer wiederverwendbare, benannte Konfigurationsvorlagen (inkl. einer Standardvorlage) für diese Ticketerstellung verwalten können.
|
||||
Ergebnis: Wiederkehrende Ticketerstellungs-Konfigurationen müssen nicht jedes Mal neu eingegeben werden; eine Standardvorlage wird automatisch vorgeschlagen.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/features/automatic-helpdesk-creation-templates.md (Abschnitt "Business Rules", `HelpdeskCreationTemplateBL.SetStandardTemplate`) - Begründung: Dokumentiert die durchgesetzte Regel "nur eine Standardvorlage gleichzeitig" und "Standardvorlage kann nicht gelöscht werden".
|
||||
- [PRIMÄR] ScriptMethod11751.cs (Tabellenerstellung `HelpdeskCreationTemplate`, referenziert in obiger Doku) - Begründung: Belegt das persistente Datenmodell inkl. Soft-Delete- und Audit-Spalten gemäß Datenbankkonvention.
|
||||
Prüfidee: Vorlage anlegen, als Standard markieren, neues Ticket-Erstellungsformular öffnen und automatisches Vorbefüllen mit Standardvorlage prüfen; Löschversuch der Standardvorlage muss abgelehnt werden.
|
||||
Tracelinks: SyRS-015
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-014
|
||||
Titel: Kontrollierter Ticketabschluss
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Servicetechniker/Helpdesk-Bearbeiter
|
||||
Vorbedingung: Ein Helpdesk-Ticket soll geschlossen werden.
|
||||
Fakt: `HelpdeskCloseBL.CloseHelpdesk` ermittelt den konfigurierten "geschlossen"-Status, prüft `CanCloseHelpdesk()` (aktuell nur ein allgemeiner Guard-Check; ein Kommentar `//Todo: if rma exists check if finished` zeigt eine noch nicht vollständig implementierte fachliche Prüfung), löscht offene To-Dos und protokolliert den Abschluss inkl. Benachrichtigungen.
|
||||
Aussage: Das System soll das Schließen eines Helpdesk-Tickets nur nach Durchlaufen definierter Abschlussprüfungen zulassen und dabei offene Folgeaufgaben bereinigen sowie den Vorgang protokollieren.
|
||||
Ergebnis: Ein Ticket kann nicht ohne Nachvollziehbarkeit geschlossen werden; Historie/Benachrichtigungen/CRM-Aktivität werden ausgelöst.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Support/HelpdeskCloseBL.cs:120-166 - Begründung: Enthält den vollständigen Abschluss-Ablauf inkl. des unvollständigen `CanCloseHelpdesk()`-Guards.
|
||||
Prüfidee: Ticket mit offenem RMA-Vorgang schließen und prüfen, ob (aktuell) keine Blockade erfolgt — Regressionsbasis für spätere Vervollständigung der Prüfung.
|
||||
Tracelinks: SyRS-015
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround (Abschlussprüfung für RMA-Bezug laut Code-Kommentar unvollständig — priorisiert für Validierung vormerken)
|
||||
```
|
||||
|
||||
## F. Rechte & Zugriffssteuerung
|
||||
|
||||
```
|
||||
ID: StRS-015
|
||||
Titel: Feingranulare, rollenbasierte Funktionsfreischaltung
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Systemadministrator, alle internen Benutzerrollen
|
||||
Vorbedingung: Ein Benutzer meldet sich an und nutzt eine geschützte Funktion.
|
||||
Fakt: `UserRightsConst.cs` definiert 750 einzelne, hierarchisch organisierte Rechte-Konstanten (z. B. `Sales.Customer.Helpdesk.SHOW_HELPDESK`); Rechte werden ausschließlich über Gruppenmitgliedschaft vergeben (`AppUser.Groups` → `AppGroup.Rights`), es existiert keine direkte Nutzer-Recht-Zuordnung.
|
||||
Aussage: Das System soll den Zugriff auf einzelne Funktionen über feingranulare, hierarchisch organisierte Berechtigungen steuern, die ausschließlich über die Zuordnung von Benutzern zu Berechtigungsgruppen vergeben werden.
|
||||
Ergebnis: Jede geschützte Aktion kann individuell freigegeben/gesperrt werden; Rechteverwaltung erfolgt zentral über Gruppen statt Einzelzuweisung.
|
||||
Belege:
|
||||
- [PRIMÄR] src/webservice/Centron.WebServices.Core/EntitiesWrongPlace/Administration/Rights/UserRightsConst.cs (750 `public const int`-Deklarationen) - Begründung: Vollständige, im Code durchgesetzte Rechtemenge.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs:644 (HasUserRight), SQL-Join `Sichtrus`↔`Sichmemb` - Begründung: Zeigt die tatsächliche DB-seitige Durchsetzung über Gruppenmitgliedschaft, keine direkte Nutzer-Recht-Tabelle gefunden.
|
||||
- [SEKUNDÄR] CentronRights.md, docs/guides/development/add-a-new-right.md, check-userrights.md - Begründung: Entwicklerdokumentation bestätigt und erläutert das Konzept.
|
||||
Prüfidee: Benutzer aus allen Rechtegruppen entfernen und prüfen, dass sämtliche geschützten Funktionen gesperrt sind; nach Gruppenzuordnung Freischaltung prüfen.
|
||||
Tracelinks: SyRS-016, SyRS-017
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-016
|
||||
Titel: Einschränkende Rechte für filial-/eigentumsbezogene Datensichtbarkeit
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Systemadministrator, Fachbereichsleiter
|
||||
Vorbedingung: Ein Benutzer besitzt ein "einschränkendes Recht" (z. B. "nur eigene Filiale").
|
||||
Fakt: Mehrfach verifiziertes Muster (Helpdesk, Kalender, Mitarbeiterauslastung, Rechteverwaltung selbst): ein zusätzliches Recht schränkt eine bereits gewährte Berechtigung auf einen Teilbereich ein (eigene Datensätze oder eigene Filiale), technisch umgesetzt als Filterbedingung auf `BranchI3D`/Bearbeiter-/Verantwortlicher-Feld.
|
||||
Aussage: Das System soll es ermöglichen, gewährte Berechtigungen durch zusätzliche "einschränkende Rechte" auf die eigene Filiale oder auf eigene Datensätze zu begrenzen.
|
||||
Ergebnis: Führungskräfte/Administratoren können steuern, ob ein Benutzer nur eigene bzw. filialeigene Daten sieht, auch wenn das Grundrecht global gewährt ist.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Support/HelpdeskBL.cs:196 - Begründung: Konkrete Codeprüfung, die den Zugriff auf Tickets anderer Filialen mit Fehlermeldung blockiert.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Calendar/ScheduleBL.cs:373-381,692-703 - Begründung: Analoge Implementierung für Kalendereinträge ("nur eigene").
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs:39 (GetAllRightGroups) - Begründung: Selbst die Rechteverwaltung unterliegt diesem Muster (`MANAGE_RIGHTS_ONLY_OWN_BRANCH`).
|
||||
- [SEKUNDÄR] CentronRights.md - Begründung: Dokumentiert das Konzept "restricting right" explizit für mehrere Fachbereiche.
|
||||
Prüfidee: Benutzer mit Grundrecht + "nur eigene Filiale" anlegen, Datensätze anderer Filialen anlegen, Sichtbarkeit/Zugriff verifizieren.
|
||||
Tracelinks: SyRS-017
|
||||
Konsolidierung: Kandidat: identisches Muster ist in mind. 4 Fachmodulen (Helpdesk, Kalender, Mitarbeiterauslastung, Rechteverwaltung) separat implementiert statt zentral wiederverwendet.
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-017
|
||||
Titel: Getrennte Berechtigungsdomäne für externe Web-Kunden
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Kunde (Web-Account)
|
||||
Vorbedingung: Ein externer Kunde meldet sich über das Web-Portal (Nexus/WebCart) an.
|
||||
Fakt: Eine eigenständige Konstantenklasse `WebAccountRightsConst.cs` (separate ID-Räume, ca. 50 Konstanten) und eine eigene Prüfmethode `HasWebAccountRight`/`AppUser.HasWebRight` bilden eine von den internen Mitarbeiterrechten (`UserRightsConst`) getrennte Berechtigungsdomäne.
|
||||
Aussage: Das System soll die Berechtigungen externer Web-Kunden in einer von den internen Mitarbeiterberechtigungen getrennten Domäne verwalten.
|
||||
Ergebnis: Interne Rechteänderungen wirken sich nicht unbeabsichtigt auf externe Kundenkonten aus und umgekehrt.
|
||||
Belege:
|
||||
- [PRIMÄR] src/webservice/Centron.WebServices.Core/EntitiesWrongPlace/Administration/Rights/WebAccountRightsConst.cs - Begründung: Eigenständige Konstantenklasse mit eigenem ID-Raum.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs:666-670 (HasWebAccountRight) - Begründung: Getrennte DB-Abfrage über Tabelle `WebAccountsRights`.
|
||||
Prüfidee: Web-Account-Recht vergeben/entziehen und prüfen, dass dies keine Auswirkung auf interne `UserRightsConst`-Prüfungen hat.
|
||||
Tracelinks: SyRS-016
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-018
|
||||
Titel: Nachvollziehbarkeit von Rechteänderungen
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Systemadministrator
|
||||
Vorbedingung: Ein Recht wird einer Berechtigungsgruppe hinzugefügt oder entzogen.
|
||||
Fakt: `AppRightsBL.AddRightToRightGroup`/`RemoveRightFromRightGroup` schreiben bei jeder Änderung einen Protokolleintrag (`WriteAddRightToGroupLog`).
|
||||
Aussage: Das System soll jede Änderung an der Rechtezuordnung einer Berechtigungsgruppe protokollieren.
|
||||
Ergebnis: Nachträglich ist nachvollziehbar, wer wann welches Recht welcher Gruppe zugewiesen oder entzogen hat.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs:168-200 (AddRightToRightGroup, WriteAddRightToGroupLog) - Begründung: Direkter Code-Beleg für die Protokollierung.
|
||||
Prüfidee: Recht einer Gruppe hinzufügen und Vorhandensein eines Protokolleintrags mit Benutzer/Zeitstempel prüfen.
|
||||
Tracelinks: SyRS-017
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## G. Authentifizierung & Sitzungsverwaltung
|
||||
|
||||
```
|
||||
ID: StRS-019
|
||||
Titel: Mehrere gleichwertige Anmeldewege (Passwort, Active Directory, Microsoft Entra ID)
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: alle Benutzerrollen, Systemadministrator
|
||||
Vorbedingung: Ein Benutzer meldet sich am System an.
|
||||
Fakt: `AuthenticatorFactory` wählt je nach konfigurierter `SystemAuthenticationMethod` zwischen `BasicAuthenticator` (Passwort), `ActiveDirectoryAuthenticator` (Windows/AD) und `OpenIdConnectAuthenticator` (Microsoft Entra ID/OIDC) sowie einer `FallbackAuthenticator`-Verkettung.
|
||||
Aussage: Das System soll wahlweise Passwort-basierte Anmeldung, Active-Directory-Anmeldung oder Anmeldung über Microsoft Entra ID (OpenID Connect) unterstützen, konfigurierbar je Installation.
|
||||
Ergebnis: Unternehmen können den für sie passenden Identitätsanbieter nutzen, ohne den Anwendungscode anzupassen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Logins/Auth/AuthenticatorFactory.cs - Begründung: Zentrale Weiche zwischen den drei Authentifizierungsmethoden.
|
||||
- [PRIMÄR] docs/reference/security/anmelden-mit-microsoft-technische-anleitung.md - Begründung: Vollständig dokumentierter OIDC-Ablauf inkl. konkreter Endpunkte und Settings-IDs (JwtAuthority=10351, JwtAudience=10352, SystemAuthenticationMethod=10360).
|
||||
Prüfidee: Anmeldung über jede der drei Methoden in einer Testumgebung durchführen und erfolgreichen Login sowie Ticket-Erstellung prüfen.
|
||||
Tracelinks: SyRS-018, SyRS-019
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-020
|
||||
Titel: Zeitlich begrenzte Sitzungen (Tickets)
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System
|
||||
Vorbedingung: Ein Benutzer hat sich erfolgreich angemeldet.
|
||||
Fakt: `TicketBL` vergibt serverseitige Sitzungs-"Tickets" mit festen Ablaufzeiten: 30 Minuten Standard (`TicketExpireInMinutes`), 5 Minuten für Monitoring-Connector, 1440 Minuten (24 h) für eine gesonderte Kategorie.
|
||||
Aussage: Das System soll Anmeldesitzungen zeitlich begrenzen und nach Ablauf eine erneute Authentifizierung verlangen.
|
||||
Ergebnis: Ein kompromittiertes oder vergessenes Sitzungstoken verliert nach spätestens 24 Stunden (Regelfall 30 Minuten) seine Gültigkeit.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Logins/TicketBL.cs:26-28,61 (CreateNewTicket, TicketExpireInMinutes=30, TicketMonitoringConnectorExpireInMinutes=5, TicketExpire24HoursInMinutes=1440) - Begründung: Konkrete, im Code fest codierte Ablaufwerte.
|
||||
- [SEKUNDÄR] src/nexus/CentronNexus/Shared/Auth/CentronAuthenticationStateProvider.cs:15-66 - Begründung: Zeigt clientseitige Revalidierung (alle 1-2 Minuten) gegen dieselbe Ticket-Gültigkeit im Web-Portal.
|
||||
Prüfidee: Ticket erzeugen, 31 Minuten warten (bzw. Ablaufzeit simulieren), nachfolgenden API-Aufruf auf Ablehnung prüfen.
|
||||
Tracelinks: SyRS-020
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-021
|
||||
Titel: Optionale Zwei-Faktor-Authentifizierung
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Benutzer mit aktivierter 2FA
|
||||
Vorbedingung: `AppUser.UseTwoFactorAuthentication = true`.
|
||||
Fakt: `TwoFactorAuthenticator`-Klasse implementiert TOTP (6-stelliger PIN, 30-Sekunden-Schritt, ±4 Minuten Zeittoleranz) nach `otpauth://totp/...`-Standard; Prüfung erfolgt inline innerhalb von `BasicAuthenticator.AuthenticateInternal`.
|
||||
Aussage: Das System soll optional eine zeitbasierte Zwei-Faktor-Authentifizierung (TOTP) je Benutzer erzwingen können.
|
||||
Ergebnis: Benutzer mit aktivierter 2FA müssen zusätzlich zum Passwort einen gültigen Einmalcode eingeben.
|
||||
Belege:
|
||||
- [PRIMÄR] src/shared/Centron.Core/GoogleAuthenticator/TwoFactorAuthenticator.cs:18-27 - Begründung: Konkrete TOTP-Implementierung inkl. Provisionierungs-URL.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Logins/Auth/BasicAuthenticator.cs:62 (_twoFactorAuthBL.ValidateTwoFactor) - Begründung: Zeigt die Einbindung in den Login-Ablauf.
|
||||
Prüfidee: 2FA für einen Benutzer aktivieren, Login ohne bzw. mit korrektem/falschem TOTP-Code testen.
|
||||
Tracelinks: SyRS-018
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## H. Lizenzierung
|
||||
|
||||
```
|
||||
ID: StRS-022
|
||||
Titel: Modulare, GUID-basierte Produktlizenzierung
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Systemadministrator, NEXOWARE-Vertrieb
|
||||
Vorbedingung: Ein Kunde soll Zugriff auf eine bestimmte Anwendung oder ein Einzelfeature erhalten.
|
||||
Fakt: Jede lizenzierbare Anwendung ("Application", darf sich am Webservice anmelden) und jedes Einzelfeature ("Only License") wird über eine eindeutige GUID identifiziert (`LicenseGuids.cs`); jede Lizenz kann zusätzlich eine Anzahl (`count`), ein Ablaufdatum und eine Versionsgrenze besitzen.
|
||||
Aussage: Das System soll den Zugriff auf Anwendungen und Einzelfeatures über eine GUID-basierte Lizenzverwaltung mit optionaler Mengen-, Zeit- und Versionsbegrenzung steuern.
|
||||
Ergebnis: Funktionen/Anwendungen ohne gültige Lizenz sind für den Kunden nicht nutzbar bzw. nicht sichtbar; Mengenlizenzen (z. B. Anzahl Importe) werden durchgesetzt.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/reference/security/licensing-system.md - Begründung: Vollständige Beschreibung des Lizenzmodells inkl. Codebeispielen (`LicenseManager.Instance.HasLicense`, `GetLicenseCount`).
|
||||
- [PRIMÄR] src/webservice/Centron.Controllers/Authorization/CentronHostedAuthorization.cs (CentronHostedRequirement, LicenseGuids.CentronInternal) - Begründung: Konkrete Durchsetzung einer Lizenzprüfung als ASP.NET-Core-Autorisierungs-Requirement.
|
||||
Prüfidee: Feature ohne zugehörige Lizenz aufrufen und Sperrung/Ausblendung prüfen; Mengenlizenz mit `count=3` testen (4. Nutzung muss abgelehnt werden).
|
||||
Tracelinks: SyRS-021
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## I. Rechnungsstellung, Nummerierung, Festschreibung, Storno, Zahlungen
|
||||
|
||||
```
|
||||
ID: StRS-023
|
||||
Titel: Eindeutige, lückenlose Belegnummernvergabe je Mandant/Filiale
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Buchhaltung, System
|
||||
Vorbedingung: Ein neuer Beleg (z. B. Rechnung) wird angelegt und benötigt eine Belegnummer.
|
||||
Fakt: `NumberGroupBL.GetNextNumber`/`FindNextNumber` inkrementiert eine je Mandant/Filiale/Nummernkreis geführte laufende Nummer, prüft dabei per Datenbankabfrage auf bereits existierende Nummern und verwendet eine bedingte `UPDATE ... WHERE Current = <alter Wert>`-Schleife zur Vermeidung von Kollisionen bei gleichzeitigem Zugriff.
|
||||
Aussage: Das System soll Belegnummern (u. a. Rechnungsnummern) je Mandant und Filiale eindeutig und kollisionsfrei auch bei gleichzeitigem Zugriff mehrerer Benutzer vergeben.
|
||||
Ergebnis: Keine doppelt vergebenen Belegnummern, auch nicht bei parallelen Speichervorgängen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Company/NumberGroupBL.cs (GetNextNumber, FindNextNumber) - Begründung: Enthält die konkrete, kollisionssichere Vergabelogik inkl. optimistischer Update-Schleife.
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/Administration/Company/NumberGroup.cs (RangeFrom, RangeTo, Current, Interval, MandatorI3D, BranchI3D) - Begründung: Datenmodell für Nummernkreise je Mandant/Filiale.
|
||||
Prüfidee: Zwei gleichzeitige Rechnungserstellungen (parallelisiert) simulieren und prüfen, dass keine doppelte Nummer vergeben wird.
|
||||
Tracelinks: SyRS-022
|
||||
Konsolidierung: nein
|
||||
Status: belegt; [HYPOTHESE] ob dies aus einer expliziten GoBD-Anforderung (Deutschland) abgeleitet ist, ist im Code nicht dokumentiert — siehe Hypothesen.md H-03.
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-024
|
||||
Titel: Unveränderlichkeit festgeschriebener Rechnungen
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Buchhaltung
|
||||
Vorbedingung: Eine Rechnung wurde als "festgeschrieben" markiert (`IsFixed = true`).
|
||||
Fakt: `ReceiptInvoiceBL.CheckIfInvoiceIsFixed` blockiert Änderungen an einer festgeschriebenen Rechnung mit der Meldung "Die Rechnung ist festgeschrieben. Änderungen nicht möglich."; `FixInvoice` setzt das Flag per direktem SQL-Update und protokolliert dies.
|
||||
Aussage: Das System soll verhindern, dass eine als festgeschrieben markierte Rechnung inhaltlich verändert wird.
|
||||
Ergebnis: Nach Festschreibung sind nur noch kontrollierte Folgeprozesse (z. B. Stornierung mit Neuversionierung) möglich, keine direkte Bearbeitung.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs:86,273 (FixInvoice, CheckIfInvoiceIsFixed) - Begründung: Konkrete Guard-Implementierung inkl. Nutzermeldung.
|
||||
Prüfidee: Rechnung festschreiben, Änderungsversuch durchführen und Ablehnung mit definierter Fehlermeldung prüfen.
|
||||
Tracelinks: SyRS-023
|
||||
Konsolidierung: nein
|
||||
Status: belegt; [HYPOTHESE] gesetzlicher Hintergrund (GoBD) nicht im Code dokumentiert, siehe Hypothesen.md H-03.
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-025
|
||||
Titel: Kontrollierte Rechnungsstornierung mit Mehrfachprüfung
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Buchhaltung
|
||||
Vorbedingung: Eine Rechnung soll storniert werden.
|
||||
Fakt: `ReceiptInvoiceBL.CancelInvoice` erfordert das Recht `RIGHT_RECHNUNGSTORNIEREN`, verweigert die Stornierung bereits stornierter, bereits an die Buchhaltung exportierter (`IsReceiptExported`), bereits weitergeleiteter oder bei Vertragsrechnungen nicht-letzter Rechnungen; die eigentliche Stornierung erzeugt eine neue Version statt In-place-Änderung.
|
||||
Aussage: Das System soll die Stornierung einer Rechnung nur nach Prüfung mehrerer Sperrbedingungen (Berechtigung, bereits exportiert, bereits weitergeleitet, Vertragsreihenfolge) zulassen und dabei eine neue Belegversion erzeugen.
|
||||
Ergebnis: Bereits an die Finanzbuchhaltung übergebene oder anderweitig referenzierte Rechnungen können nicht unkontrolliert storniert werden.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs:143 (CancelInvoice) - Begründung: Enthält alle genannten Sperrbedingungen als expliziten Code-Ablauf.
|
||||
Prüfidee: Stornierung einer bereits exportierten Rechnung versuchen (muss abgelehnt werden); Stornierung einer offenen, nicht exportierten Rechnung durchführen (muss gelingen und neue Version erzeugen).
|
||||
Tracelinks: SyRS-023
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-026
|
||||
Titel: Nachvollziehbare Zahlungsbuchung mit Stornofunktion
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Buchhaltung
|
||||
Vorbedingung: Ein Zahlungseingang/-ausgang soll erfasst oder storniert werden.
|
||||
Fakt: `PaymentsBL.DeleteIncomingPayment` erfordert das Recht `Controlling.Finances.INCOMING_PAYMENT_TRANSACTIONS`; bei Löschung wird die Zahlung durch einen umgekehrt vorzeichenbehafteten Aufruf von `ReceiptBL.UpdateReceiptIsPaid` (inkl. Währungsumrechnung) korrekt zurückgebucht statt nur den Datensatz zu entfernen.
|
||||
Aussage: Das System soll das Löschen einer erfassten Zahlung nur berechtigten Benutzern erlauben und dabei den Bezahlt-Status des zugehörigen Belegs korrekt (inkl. Währungsumrechnung) zurücksetzen.
|
||||
Ergebnis: Der Bezahlt-Status eines Belegs bleibt auch nach Korrekturen konsistent mit den tatsächlich erfassten Zahlungen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Finances/Payments/PaymentsBL.cs:38 (DeleteIncomingPayment) - Begründung: Konkrete Implementierung inkl. Rechteprüfung und Rückbuchung.
|
||||
Prüfidee: Zahlung erfassen (Beleg wird "bezahlt"), Zahlung löschen und Rückkehr des Belegs in den unbezahlten Zustand inkl. korrekten Betrags prüfen.
|
||||
Tracelinks: SyRS-023
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-027
|
||||
Titel: Kontrollierte Bankverbindungsverwaltung mit Verwendungsprüfung
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Buchhaltung
|
||||
Vorbedingung: Eine Bankverbindung soll gelöscht werden.
|
||||
Fakt: `BankAccountBL.DeleteBankAccount` prüft, ob die Bankverbindung von einem Beleg mit SEPA-Mandat (`IReceiptWithMandat`) referenziert wird, und verweigert in diesem Fall die Löschung mit Auflistung der blockierenden Belege.
|
||||
Aussage: Das System soll die Löschung einer Bankverbindung verhindern, solange diese von mindestens einem Beleg mit SEPA-Mandatsbezug verwendet wird, und dem Benutzer die blockierenden Belege anzeigen.
|
||||
Ergebnis: Keine verwaisten Mandatsreferenzen durch gelöschte Bankverbindungen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Accounting/BankAccountBL.cs:119 (DeleteBankAccount) - Begründung: Konkrete Implementierung inkl. Belegliste in der Fehlermeldung.
|
||||
Prüfidee: Bankverbindung löschen, die von einem aktiven Vertrag mit SEPA-Mandat referenziert wird; Ablehnung mit Belegliste prüfen.
|
||||
Tracelinks: SyRS-023
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## J. E-Invoicing & Lieferanten-EDI
|
||||
|
||||
```
|
||||
ID: StRS-028
|
||||
Titel: Normkonforme elektronische Rechnungsstellung (ZUGFeRD, ebInterface)
|
||||
Ebene: StRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: Buchhaltung, externer Kunde/Lieferant
|
||||
Vorbedingung: Eine Rechnung soll als strukturiertes E-Invoice ausgegeben werden.
|
||||
Fakt: `InvoiceZugferdBL`/`ZUGFeRD_BL` erzeugen ZUGFeRD-konforme Hybrid-PDF/XML-Rechnungen (deutscher/europäischer Standard); `EbInterfaceLogic` erzeugt ebInterface-Dateien (österreichischer Standard); die Aktivierung ist über die Einstellung `IsZugferdInvoiceActive` steuerbar.
|
||||
Aussage: Das System soll Ausgangsrechnungen wahlweise im ZUGFeRD- und/oder ebInterface-Format als strukturierte elektronische Rechnung erzeugen können.
|
||||
Ergebnis: Rechnungsempfänger mit entsprechenden Systemen können die Rechnung automatisiert maschinell verarbeiten; gesetzliche E-Rechnungspflichten (z. B. B2G) sind adressierbar.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/DataExchange/EDI/SaleInvoices/InvoiceZugferdBL.cs (GenerateZugferdFile, CreateZugferdConformPdfDocument) - Begründung: Konkrete Erzeugungslogik für ZUGFeRD-Dateien.
|
||||
- [PRIMÄR] src/apis/Centron.Api.EbInterface/EbInterfaceLogic.cs (GenerateFile) - Begründung: Konkrete Erzeugungslogik für ebInterface.
|
||||
- [SEKUNDÄR] docs/guides/development/xrechnung.md, docs/guides/development/settings-management.md (IsZugferdInvoiceActive) - Begründung: Zeigt die Aktivierbarkeit über Einstellungen sowie Bezug zu XRechnung.
|
||||
Prüfidee: Rechnung mit aktivierter ZUGFeRD-Einstellung erzeugen und die PDF-eingebettete XML mit einem Validator (z. B. KOSIT-Tool) prüfen.
|
||||
Tracelinks: SyRS-024
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-029
|
||||
Titel: Automatisierter elektronischer Belegaustausch mit Distributoren (EDI)
|
||||
Ebene: StRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: Einkäufer, externer Lieferant/Distributor
|
||||
Vorbedingung: Eine Bestellung soll elektronisch an einen angebundenen Distributor übermittelt oder eine Auftragsbestätigung/Lieferung/Rechnung empfangen werden.
|
||||
Fakt: `EDIDispatcherBL` routet die Belegerzeugung je Distributor (`EDIMultidistributors`: ITScope, EGIS, Concerto, Orderowner) und nutzt standardmäßig openTRANS 2.1; `SupplierEdiBL` verarbeitet eingehende Auftragsbestätigungen/Lieferungen/Rechnungen für ALSO, ALSO CH, Alltron, Herweck, Komsa.
|
||||
Aussage: Das System soll Bestellungen, Auftragsbestätigungen, Lieferavise und Rechnungen mit angebundenen Distributoren über standardisierte bzw. distributorspezifische EDI-Formate automatisiert austauschen.
|
||||
Ergebnis: Manuelle Doppelerfassung von Bestell- und Lieferdaten entfällt für angebundene Distributoren.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/EDI/EDIDispatcherBL.cs (CreateEDISuggestionOrderAsync, EDIMultidistributors) - Begründung: Zeigt konkrete Distributor-Routing-Logik für den Bestellversand.
|
||||
- [PRIMÄR] src/backend/Centron.BL/EDI/SupplierEDI/SupplierEdiBL.cs (2179 Zeilen, Partial-Klassen je Distributor) - Begründung: Zentrale Empfangsverarbeitung für mehrere EDI-Formate.
|
||||
- [SEKUNDÄR] docs/reference/edi/edi-architecture.md - Begründung: Dokumentiert unterstützte Formate/Dokumenttypen je Lieferant tabellarisch.
|
||||
Prüfidee: Testbestellung an einen konfigurierten EDI-Distributor senden und Empfang/Verarbeitung einer simulierten Auftragsbestätigung prüfen.
|
||||
Tracelinks: SyRS-025, SyRS-026
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## K. Einkauf & Lieferantenmanagement
|
||||
|
||||
```
|
||||
ID: StRS-030
|
||||
Titel: Bedarfsgesteuerte Bestellvorschläge
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Einkäufer
|
||||
Vorbedingung: Artikelbestände unterschreiten einen Mindestbestand bzw. es besteht offener Auftragsbedarf.
|
||||
Fakt: `OrderSuggestionListBL` (1144 Zeilen) berechnet Bestellvorschläge je Artikel/Auftrag/Lager (`GetOrderSuggestionArticle`, `GetOrderSuggestionOrder`, `GetOrderSuggestionWH`), inkl. distributorspezifischer Preisermittlung und Berücksichtigung von Wareneingängen im Zulauf (`RefreshIntake`).
|
||||
Aussage: Das System soll auf Basis von Mindestbeständen, offenem Auftragsbedarf und bereits im Zulauf befindlicher Ware automatisiert Bestellvorschläge je Artikel und Lager erzeugen.
|
||||
Ergebnis: Einkäufer erhalten eine priorisierte, datenbasierte Grundlage für Nachbestellungen statt manueller Bestandsprüfung.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Purchasing/OrderSuggestionList/OrderSuggestionListBL.cs - Begründung: Zentrale, umfangreiche Implementierung der Bestellvorschlagslogik.
|
||||
Prüfidee: Artikel unter Mindestbestand setzen und Erscheinen in der Bestellvorschlagsliste mit korrekter Menge prüfen.
|
||||
Tracelinks: SyRS-027
|
||||
Konsolidierung: nein
|
||||
Status: belegt; [HYPOTHESE] genaue Meldebestands-/Reorder-Formel nicht vollständig nachvollzogen, siehe Hypothesen.md H-04.
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-031
|
||||
Titel: Partiallieferungsfähige Lieferantenbestellabwicklung
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Einkäufer, Lagermitarbeiter
|
||||
Vorbedingung: Eine Lieferantenbestellung wird teilweise geliefert.
|
||||
Fakt: `ReceiptSupplierOrderIntake` verfolgt je Bestellposition die kumulierte Wareneingangsmenge (`InStock`, `Booked`) gegenüber der Bestellmenge; `SupplierOrderSpecificLogic.UpdateIntake` aktualisiert diese bei jedem Wareneingang.
|
||||
Aussage: Das System soll Teillieferungen zu einer Lieferantenbestellung erfassen und den kumulierten Lieferstatus je Bestellposition nachverfolgen.
|
||||
Ergebnis: Offener Restbedarf je Bestellposition ist jederzeit ersichtlich, auch bei mehreren Teillieferungen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/SupplierOrders/SupplierOrderSpecificLogic.cs:177-215 (UpdateIntake) - Begründung: Konkrete Implementierung der kumulierten Mengenverfolgung.
|
||||
Prüfidee: Bestellung mit 100 Stück anlegen, zwei Teillieferungen von je 40 und 60 Stück buchen, kumulierten Status nach jeder Teillieferung prüfen.
|
||||
Tracelinks: SyRS-028
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## L. Lager & Bestandsführung
|
||||
|
||||
```
|
||||
ID: StRS-032
|
||||
Titel: Schutz vor unautorisierten Negativbuchungen im Warenausgang
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Lagermitarbeiter
|
||||
Vorbedingung: Eine Warenausgangsbuchung (z. B. Lieferschein) würde den Bestand eines Artikels neu ins Negative treiben.
|
||||
Fakt: `ReceiptArticleBookingBL` erkennt eine Buchung als "negativ" nur, wenn der Bestand dadurch neu negativ wird; ohne das Recht `RIGHT_NEGATIVBUCHUNG` wird die Buchung blockiert und ein Dialog zur Anmeldung eines berechtigten Kollegen angeboten. Diese Prüfung ist für Wareneingänge (Lieferantenbestellung/-lieferschein) deaktiviert, für Warenausgang (Kundenlieferschein) aktiv.
|
||||
Aussage: Das System soll eine Warenausgangsbuchung, die den Artikelbestand neu ins Negative treibt, nur mit einem gesonderten Recht zulassen; ist dieses Recht nicht vorhanden, soll die Anmeldung eines berechtigten Kollegen zur Freigabe angeboten werden.
|
||||
Ergebnis: Unautorisierte Negativbestände im Warenausgang werden verhindert, während Wareneingänge nicht unnötig blockiert werden.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/Internal/ReceiptArticleBookingBL.cs:340-429 - Begründung: Enthält die vollständige Erkennungs- und Freigabelogik inkl. Kollegen-Anmeldedialog.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/DeliveryLists/DeliveryListSpecificLogic.cs:200-201 vs. SupplierOrderSpecificLogic.cs:222-230 / SupplierDeliveryListSpecificLogic.cs:247-255 - Begründung: Belegt die differenzierte Aktivierung je Belegrichtung (Ausgang aktiv, Eingang deaktiviert).
|
||||
Prüfidee: Warenausgang ohne Negativbuchungsrecht über den verfügbaren Bestand hinaus buchen; Ablehnung und Kollegen-Anmeldedialog prüfen.
|
||||
Tracelinks: SyRS-029
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-033
|
||||
Titel: Vollständige Bestandsänderungsprotokollierung
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Lagermitarbeiter, Buchhaltung (Inventurprüfung)
|
||||
Vorbedingung: Eine Artikelbestandsänderung wird durchgeführt.
|
||||
Fakt: `ReceiptArticleBookingBL` ruft nach jeder Bestandsaktualisierung `_articleLogBL.WriteAmountChangeLog` auf; separat protokolliert `StockBL.WriteStockRebookLog` Lagerumbuchungen zwischen zwei Lagerorten mit Pflichtangabe von Quell-/Ziellager und Mitarbeiter.
|
||||
Aussage: Das System soll jede Artikelbestandsänderung inklusive Lagerumbuchungen mit Quelle, Ziel und ausführendem Mitarbeiter protokollieren.
|
||||
Ergebnis: Bestandsdifferenzen sind nachträglich auf konkrete Buchungsvorgänge zurückführbar.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/Internal/ReceiptArticleBookingBL.cs:429 (WriteAmountChangeLog) - Begründung: Direkter Aufruf nach jeder Bestandsänderung.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Logistics/Warehousing/StockBL.cs:84-108 (WriteStockRebookLog) - Begründung: Pflichtfeldprüfung für Umbuchungsprotokoll.
|
||||
Prüfidee: Bestandsänderung durchführen und Vorhandensein eines zugehörigen Protokolleintrags mit Benutzer/Zeitstempel/Mengenänderung prüfen.
|
||||
Tracelinks: SyRS-029
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## M. Externe Preis-/Kataloganbindung
|
||||
|
||||
```
|
||||
ID: StRS-034
|
||||
Titel: Konsolidierte Mehrquellen-Einkaufspreisübersicht (Preismatrix)
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Einkäufer, Vertriebsmitarbeiter
|
||||
Vorbedingung: Für einen Artikel sollen aktuelle Einkaufspreise verglichen werden.
|
||||
Fakt: Die "Preismatrix" zeigt parallel bis zu sieben Preisquellen je Artikel: interne zeitlich befristete Aktionspreise sowie vier externe Distributor-/Marktplatz-APIs (ITscope, COP/NEOS/TradersGuide über eine gemeinsame SOAP-Basisklasse, EGIS) und importierte Artikeldaten.
|
||||
Aussage: Das System soll für einen Artikel Einkaufspreise aus mehreren internen und externen Quellen (Aktionspreise, Distributor-APIs) gebündelt und tagesaktuell (unter Berücksichtigung von Gültigkeitszeiträumen) darstellen.
|
||||
Ergebnis: Einkäufer/Vertrieb sehen ohne Systemwechsel den jeweils günstigsten verfügbaren Bezugspreis.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/reference/receipts/actionprice-system.md (Abschnitt "Integration with Price Matrix") - Begründung: Listet die sieben parallelen Preisquellen explizit auf.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ArticleSearch/CopApiBaseExternalArticleSearchProvider.cs (Unterklassen für COP, NEOS, TradersGuide) - Begründung: Konkrete, wiederverwendete Anbindung dreier Distributoren über ein gemeinsames SOAP-Protokoll.
|
||||
- [SEKUNDÄR] src/apis/Centron.APIs.ITscopeDataAccess/ITscopeApi.cs, Centron.APIs.EgisDataAccess/EgisApi.cs - Begründung: Weitere externe Preis-/Verfügbarkeitsquellen.
|
||||
Prüfidee: Artikel mit hinterlegtem Aktionspreis und aktivierten externen Quellen öffnen; alle Quellen müssen parallel mit Anbieterkennzeichnung angezeigt werden.
|
||||
Tracelinks: SyRS-030
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## N. Web-Selbstbedienungsportal (Nexus/WebCart) & TradePool
|
||||
|
||||
```
|
||||
ID: StRS-035
|
||||
Titel: Web-Selbstbedienungsportal für Endkunden (WebCart)
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Kunde (Web-Account)
|
||||
Vorbedingung: Ein Kunde besitzt einen Web-Account und meldet sich am Nexus-Webportal an.
|
||||
Fakt: `CentronNexus/WebCart` bietet Shop-, Warenkorb-, Vertrags-, Beleg- und Ticketübersichtsseiten für Endkunden; Sichtbarkeit basiert auf den kundenindividuellen Sonderpreisen (siehe StRS-011).
|
||||
Aussage: Das System soll Endkunden über ein Web-Portal einen Selbstbedienungs-Bestellkanal mit Einsicht in eigene Verträge, Belege und Tickets bereitstellen.
|
||||
Ergebnis: Kunden können ohne Einbindung eines Innendienstmitarbeiters bestellen und den eigenen Vorgangsstatus einsehen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/nexus/CentronNexus/WebCart/ (WebCartShopPage.razor, WebCartCartPage.razor, ContractsOverview.razor, ReceiptsOverview.razor, WebCartTicketsPage.razor) - Begründung: Vollständige Feature-Seiten-Struktur des Selbstbedienungsportals.
|
||||
- [KONTEXT] README.md (Abschnitt "WebCart") - Begründung: Fachliche Einordnung als "Feature primarily intended for the customers of our customers".
|
||||
Prüfidee: Als Web-Account anmelden, Artikel im Shop auswählen, Bestellung auslösen, im Belegverlauf wiederfinden.
|
||||
Tracelinks: SyRS-013, SyRS-031
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-036
|
||||
Titel: Multi-Distributor-Ressale-Katalog für c-entron-Kunden (TradePool)
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Kunde (Wiederverkäufer/Händler)
|
||||
Vorbedingung: Ein c-entron-Kunde ist für den TradePool-Zugang authentifiziert.
|
||||
Fakt: `TradePoolBL`/`TradePoolXmlLogic` importieren artikel-/preis-/bestandsbezogene XML-Feeds mehrerer Distributoren je Kunde und stellen sie über eine eigene, passwortgeschützte Anmeldung (`TradeCustomerLogin`) durchsuchbar bereit.
|
||||
Aussage: Das System soll c-entron-Kunden über einen separaten, authentifizierten Zugang einen aggregierten, mehrere Distributoren umfassenden Artikel-, Preis- und Bestandskatalog bereitstellen.
|
||||
Ergebnis: Kunden (vermutlich Wiederverkäufer) können ohne eigene Distributor-Zugänge über c-entron auf gebündelte Distributor-Kataloge zugreifen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/TradePool/Core/TradePoolXmlLogic.cs:118-159 (ImportTradeArticles) - Begründung: Konkrete XML-Importlogik mit Distributor-/Kunden-Struktur.
|
||||
- [PRIMÄR] src/backend/Centron.BL/TradePool/TradePoolBL.cs:170-183 (TradeCustomerLogin) - Begründung: Eigenständiger, von den übrigen Auth-Mechanismen getrennter Login.
|
||||
Prüfidee: TradePool-Zugang für einen Testkunden einrichten, Artikelsuche über mehrere importierte Distributoren durchführen.
|
||||
Tracelinks: SyRS-032
|
||||
Konsolidierung: nein
|
||||
Status: belegt; [HYPOTHESE] genauer fachlicher Geschäftszweck (Dropshipping? Preisvergleich für Endkunden?) nicht durch Code-Kommentar bestätigt, siehe Hypothesen.md H-05.
|
||||
```
|
||||
|
||||
## O. Plattformübergreifender Betrieb & DevOps
|
||||
|
||||
```
|
||||
ID: StRS-037
|
||||
Titel: Plattformunabhängiger Web-Service-Betrieb (Windows und Linux)
|
||||
Ebene: StRS
|
||||
Typ: nicht-funktional
|
||||
Akteur: Systemadministrator (Kunde/Hosting)
|
||||
Vorbedingung: Der c-entron Web-Service soll auf einer vom Kunden gewählten Serverplattform betrieben werden.
|
||||
Fakt: Der Web-Service ist sowohl als Windows-Installation (WiX-MSI, Windows-Dienst) als auch als Linux-Variante (Docker-Image auf Alpine, `Centron.Host.Console`, systemd-Unit-Beispiel) betreibbar; dokumentierte Unterschiede bestehen u. a. bei Sub-Web-Services (nur Windows) und Zertifikatskonfiguration.
|
||||
Aussage: Das System soll den Web-Service sowohl unter Windows als auch unter Linux betreibbar machen, mit dokumentierten, akzeptierten Funktionseinschränkungen auf Linux.
|
||||
Ergebnis: Kunden können die Serverplattform frei wählen; bekannte Linux-Einschränkungen (z. B. fehlende Sub-Web-Service-Unterstützung, manuelle Zertifikatskonfiguration) sind dokumentiert statt stillschweigend zu scheitern.
|
||||
Belege:
|
||||
- [PRIMÄR] docker/c-entron-api/Dockerfile (Alpine-Runtime, .NET 10) - Begründung: Konkretes, produktives Linux-Container-Image.
|
||||
- [SEKUNDÄR] docs/guides/services/web-service-on-linux.md - Begründung: Dokumentiert Installationsschritte, HTTPS-Konfiguration und explizite Linux-Einschränkungen.
|
||||
- [PRIMÄR] deployment/ (WixSharpInstaller, CentronSetupProject, WebServiceSetupProject) - Begründung: Belegt parallelen Windows-Installer-Vertriebsweg.
|
||||
Prüfidee: Web-Service-Container unter Linux gemäß Dokumentation starten und Basisfunktionalität (Login, einfacher API-Aufruf) verifizieren.
|
||||
Tracelinks: SyRS-033, SyRS-034
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-038
|
||||
Titel: Automatisierte, nachvollziehbare Build- und Ticket-Verknüpfung
|
||||
Ebene: StRS
|
||||
Typ: nicht-funktional
|
||||
Akteur: NEXOWARE-Entwickler, Qualitätssicherung
|
||||
Vorbedingung: Ein Pull Request mit Ticketbezug wird gemergt.
|
||||
Fakt: Ein Azure-DevOps-Webhook (`DevOpsCentronTicketBridge`) durchsucht Titel/Beschreibung gemergter Pull Requests nach Ticketnummern (mehrere unterstützte Schreibweisen), trägt die resultierende Versionsnummer automatisch in das referenzierte c-entron-Ticket ein und leitet es automatisch an die Qualitätssicherung weiter (außer bei `[skip-forwarding]`-Markierung).
|
||||
Aussage: Das System soll nach einem erfolgreichen Build automatisiert erkennen, welche Tickets durch den zugehörigen Pull Request adressiert wurden, die Build-Versionsnummer in diese Tickets eintragen und sie zur Qualitätssicherung weiterleiten.
|
||||
Ergebnis: Jede ausgelieferte Änderung ist ohne manuellen Zusatzaufwand einer konkreten Versionsnummer und einem QS-Prozessschritt zugeordnet.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/operations/build-server-and-automated-builds.md (Abschnitt "c-entron Tickets") - Begründung: Vollständige Beschreibung des Webhook-Mechanismus inkl. unterstützter Ticket-Referenzformate und Opt-out-Tag.
|
||||
Prüfidee: Pull Request mit "Ticket 12345" im Titel mergen und automatischen Eintrag der Versionsnummer im Ticketsystem prüfen.
|
||||
Tracelinks: SyRS-035
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## P. Wartbarkeit, Nachvollziehbarkeit, Mehrsprachigkeit (architektonische Querschnittsziele)
|
||||
|
||||
```
|
||||
ID: StRS-039
|
||||
Titel: Austauschbarkeit von Datenzugriff (Direktverbindung vs. Web-Service)
|
||||
Ebene: StRS
|
||||
Typ: nicht-funktional
|
||||
Akteur: NEXOWARE-Entwickler, Systemadministrator
|
||||
Vorbedingung: Ein Kunde betreibt den WPF-Client entweder mit direkter SQL-Server-Verbindung oder über den Web-Service.
|
||||
Fakt: Jedes fachliche Modul MUSS laut Entwicklerdokumentation sowohl eine direkte Datenbank-Implementierung (`BL*Logic`) als auch eine Web-Service-Implementierung (`WS*Logic`) hinter einem gemeinsamen `ILogic`-Interface bereitstellen; `ClassContainer` wählt zur Laufzeit die passende Implementierung.
|
||||
Aussage: Das System soll es ermöglichen, denselben WPF-Client wahlweise mit direkter Datenbankverbindung oder über den zentralen Web-Service zu betreiben, ohne die fachliche Modulimplementierung zu duplizieren.
|
||||
Ergebnis: Kunden können je nach Infrastruktur (Terminalserver mit Direktzugriff vs. verteilte/Cloud-Installation) zwischen beiden Betriebsarten wählen.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/getting-started/general-structure.md (Abschnitt "Dual Implementation Architecture") - Begründung: Beschreibt die verpflichtende Dual-Implementierung inkl. Codebeispielen für `ILogic`/`BLLogic`/`WSLogic` und `ClassContainer`.
|
||||
Prüfidee: Denselben Anwendungsfall (z. B. Kundenanlage) einmal über Direktverbindung und einmal über Web-Service ausführen; identisches fachliches Ergebnis prüfen.
|
||||
Tracelinks: SyRS-041
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-040
|
||||
Titel: Zweisprachige Benutzeroberfläche (Deutsch/Englisch)
|
||||
Ebene: StRS
|
||||
Typ: nicht-funktional
|
||||
Akteur: alle Benutzerrollen (international)
|
||||
Vorbedingung: Ein Benutzer stellt seine Anzeigesprache ein.
|
||||
Fakt: Alle UI-Texte liegen als Ressourcendateien in Deutsch (Standard, `LocalizedStrings.resx`) und Englisch (`LocalizedStrings.en.resx`) vor; Auswahl erfolgt über `CultureInfo.CurrentUICulture`; Web-Service-Antworten unterstützen den `Accept-Language`-Header.
|
||||
Aussage: Das System soll die Benutzeroberfläche und Systemmeldungen wahlweise in Deutsch (Standard) oder Englisch anzeigen.
|
||||
Ergebnis: Nicht-deutschsprachige Mitarbeiter/Kunden können das System in englischer Sprache nutzen.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/guides/ui/localization.md - Begründung: Vollständige Dokumentation der Ressourcendatei-Struktur, Sprachauswahl und Konventionen.
|
||||
- [KONTEXT] docs/getting-started/general-structure.md (Abschnitt "German-First Language Policy") - Begründung: Bestätigt Deutsch als verbindlichen Standard für neue UI-Texte.
|
||||
Prüfidee: Anzeigesprache auf Englisch umstellen und Vorhandensein englischer Übersetzung für eine Stichprobe von UI-Elementen prüfen.
|
||||
Tracelinks: SyRS-042
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-041
|
||||
Titel: Automatisierte, wiederkehrende Datenqualitätssicherung
|
||||
Ebene: StRS
|
||||
Typ: nicht-funktional
|
||||
Akteur: System, Systemadministrator
|
||||
Vorbedingung: Der Web-Service läuft im Dauerbetrieb.
|
||||
Fakt: Ein `DataQualityService` (ASP.NET-Core-`BackgroundService`) führt stündlich mehrere fest definierte Bereinigungs-/Reparaturaufgaben aus (u. a. Ticketmuster-Kundenzuordnungen, verwaiste Konto-Referenzen in To-Dos, Bereinigung sekundärer Lagerartikel), jede Aufgabe fehlertolerant und unabhängig von den übrigen.
|
||||
Aussage: Das System soll im laufenden Betrieb automatisiert und regelmäßig Dateninkonsistenzen erkennen und beheben, ohne dass eine einzelne fehlschlagende Aufgabe den Gesamtdienst beeinträchtigt.
|
||||
Ergebnis: Datenqualitätsprobleme (fehlende Referenzen, veraltete Zuordnungen) werden ohne manuellen Eingriff kontinuierlich reduziert.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/Background Service/DataQualityService.md - Begründung: Vollständige Dokumentation der Aufgabenliste, Fehlerbehandlung und Ausführungsintervalle.
|
||||
Prüfidee: Bekannte Dateninkonsistenz (z. B. fehlende AccountI3D in einem Todo) erzeugen und nach einem Ausführungszyklus die automatische Korrektur prüfen.
|
||||
Tracelinks: SyRS-036
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-042
|
||||
Titel: Sichere, versionierte Programmierschnittstelle für Clients und Drittanwendungen
|
||||
Ebene: StRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: interner Client (WPF/Nexus/Outlook-Add-In), Drittanwendung, NEXOWARE-Entwickler
|
||||
Vorbedingung: Ein Client oder eine Drittanwendung ruft eine Funktion über die REST-API auf.
|
||||
Fakt: Die moderne REST-API (`Centron.Controllers`) ist konsequent nach Version organisiert (`v1/...`), setzt Authentifizierung/Autorisierung über wiederverwendbare Attribute (`AuthorizeUserRight`, `AuthorizeCentronHosted`) durch und trennt 15 fachliche Domänen (Accounts, Contracts, Customers, Helpdesks, Offers, Orders, Receipts, Tickets, WebAccount u. a.) in eigene Controller.
|
||||
Aussage: Das System soll externen und internen Clients eine versionierte, nach Fachdomänen strukturierte REST-Schnittstelle mit einheitlicher, wiederverwendbarer Authentifizierungs-/Autorisierungsprüfung bereitstellen.
|
||||
Ergebnis: Neue API-Versionen können eingeführt werden, ohne bestehende Client-Integrationen zu brechen; jede Aktion ist konsistent gegen Benutzerrecht und Lizenz geprüft.
|
||||
Belege:
|
||||
- [PRIMÄR] src/webservice/Centron.Controllers/Controllers/v1/ (15 Domänen-Unterordner) - Begründung: Belegt die tatsächliche Domänenaufteilung und Versionierung der API.
|
||||
- [PRIMÄR] src/webservice/Centron.Controllers/Configuration/RegisterCentronApiVersioning.cs - Begründung: Konfiguriert namensraumbasierte Versionierung (Asp.Versioning) mit URL-Segment `v{version}`.
|
||||
- [SEKUNDÄR] src/webservice/Centron.Controllers/Authorization/README.md - Begründung: Dokumentiert das vorgesehene Zusammenspiel von `AuthorizeCentronHosted` (Lizenz) und `AuthorizeUserRight` (Berechtigung).
|
||||
Prüfidee: API-Aufruf ohne gültiges Recht (403), ohne gültige Authentifizierung (401) und mit beidem (Erfolg) gegen einen v1-Endpunkt prüfen.
|
||||
Tracelinks: SyRS-037, SyRS-038
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-043
|
||||
Titel: Nachvollziehbare Produktnutzung für Lizenz- und Produktsteuerung
|
||||
Ebene: StRS
|
||||
Typ: nicht-funktional
|
||||
Akteur: NEXOWARE (Produktmanagement/Lizenzierung)
|
||||
Vorbedingung: Ein Benutzer nutzt eine API-Methode, ein KI-gestütztes Werkzeug oder ein MCP-Tool.
|
||||
Fakt: `TelemetryBL` erfasst und speichert (nach Benutzer, Hardware-ID, Zeit-Bucket gruppiert) die Nutzung von MCP-Tools, KI-Assistenz-Werkzeugen und API-Methoden in eigenen Tabellen und lädt diese Daten gebündelt zu einem externen Server hoch.
|
||||
Aussage: Das System soll die Nutzung von API-Methoden und KI-/MCP-Werkzeugen je Benutzer/Installation erfassen und für eine zentrale Auswertung bereitstellen.
|
||||
Ergebnis: NEXOWARE erhält eine Datengrundlage für Produkt- und Lizenzentscheidungen (z. B. Mengenlizenzen, Funktionsnutzung).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Telemetry/TelemetryBL.cs:36-95,181-276 - Begründung: Konkrete Tabellen (`McpToolUsageTelemetry`, `ArtificialIntelligenceToolUsageTelemetry`, `ApiCallTelemetry`), Bucket-Logik und Upload-Mechanismus.
|
||||
Prüfidee: API-Aufruf durchführen und Vorhandensein eines entsprechenden Telemetrie-Eintrags nach dem nächsten Bucket-Zyklus prüfen.
|
||||
Tracelinks: SyRS-039
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-044
|
||||
Titel: Filial- und mandantenübergreifende Datenisolierung
|
||||
Ebene: StRS
|
||||
Typ: Daten
|
||||
Akteur: Systemadministrator, Fachbereichsleiter
|
||||
Vorbedingung: Ein Unternehmen mit mehreren Filialen bzw. mehreren rechtlichen Einheiten (Mandanten) betreibt eine gemeinsame Installation.
|
||||
Fakt: Es existieren zwei getrennte Skalierungsebenen: `Mandator` (Unternehmen/rechtliche Einheit) und `Branch`/`Filiale` (Standort); zentrale Geschäftsobjekte (Aufträge, Lagerbestände, Nummernkreise) tragen `BranchI3D`, Nummernkreise zusätzlich `MandatorI3D`.
|
||||
Aussage: Das System soll Geschäftsdaten auf zwei Ebenen — Mandant (rechtliche Einheit) und Filiale (Standort) — organisatorisch trennen und filialbezogene Auswertungen/Berechtigungen ermöglichen.
|
||||
Ergebnis: Ein Unternehmen mit mehreren Filialen/Mandanten kann Daten korrekt zuordnen und filial-/mandantenbezogen einschränken (siehe auch StRS-016).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/Administration/Company/Mandator.cs - Begründung: Eigenständige Entität für die Mandantenebene.
|
||||
- [PRIMÄR] src/backend/Centron.DAO/Mappings/Sales/CustomerAssets/Orders/OrderMaps.cs:74-75 (BranchI3D, BranchFrom) - Begründung: Belegt Filial-Scoping auf zentralen Geschäftsobjekten.
|
||||
Prüfidee: Zwei Filialen unter einem Mandanten anlegen, Auftrag je Filiale erfassen und filialbezogene Auswertung/Berechtigungsfilterung prüfen.
|
||||
Tracelinks: SyRS-040
|
||||
Konsolidierung: nein
|
||||
Status: belegt; [HYPOTHESE] wie konsequent DAO-Abfragen global nach Mandant/Filiale filtern, wurde nicht vollständig verifiziert — siehe Hypothesen.md H-06.
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-045
|
||||
Titel: Sichere Speicherung von Benutzerpasswörtern
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Systemadministrator, alle Benutzer (mittelbar)
|
||||
Vorbedingung: Ein Benutzerpasswort wird gespeichert oder bei Login geprüft.
|
||||
Fakt: `BasicAuthenticator.AuthenticateInternal` hasht das eingegebene Passwort ausschließlich mit `SHA1Decoder.GetDecodedSHA1String(...)` ohne erkennbares Salt und vergleicht es direkt gegen den gespeicherten Wert; ein Code-Kommentar im selben Modul lautet explizit `// TODO the password should be salted!!!`.
|
||||
Aussage: Das System soll Benutzerpasswörter mit einem modernen, gesalzenen Hash-Verfahren speichern, das gegen Rainbow-Table- und Brute-Force-Angriffe widerstandsfähig ist.
|
||||
Ergebnis: Bei einem Datenbank-Kompromittierungsszenario sind gespeicherte Passwort-Hashes nicht trivial in Klartext rückführbar.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Logins/Auth/BasicAuthenticator.cs:46-48 - Begründung: Direkter Code- und Kommentarbeleg für ungesalzenes SHA-1-Hashing; von den Entwicklern selbst als offene Baustelle markiert.
|
||||
Prüfidee: Zwei Benutzer mit identischem Passwort anlegen und prüfen, ob die gespeicherten Hash-Werte identisch sind (Indiz für fehlendes Salt); Ergebnis mit Sicherheitsverantwortlichen bewerten.
|
||||
Tracelinks: SyRS-044
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround (von den Entwicklern selbst als technische Schuld markiert — hohe Priorität für Zielsystem-Migration)
|
||||
```
|
||||
+846
@@ -0,0 +1,846 @@
|
||||
# SyRS — System Requirements Specification
|
||||
|
||||
c-entron ERP-Suite — Reverse Requirements Engineering, Iteration 01 (Baseline).
|
||||
Systemverhalten, Schnittstellen, Performance-/Sicherheitsanforderungen. Ebene: `SyRS`. NFR-Einordnung folgt ISO/IEC 25010 (Feld `Typ` bzw. Erläuterung im Text).
|
||||
|
||||
## A. Beleg-Lebenszyklus (zu StRS-001..004)
|
||||
|
||||
```
|
||||
ID: SyRS-001
|
||||
Titel: Einheitlicher Belegstatus-Wertebereich
|
||||
Ebene: SyRS
|
||||
Typ: Daten
|
||||
Akteur: System
|
||||
Vorbedingung: Ein Belegobjekt jeden Typs wird angelegt oder verändert.
|
||||
Fakt: `ReceiptState` ist eine geschlossene Aufzählung mit genau drei Werten (Active=1, Completed=2, Canceled=3), typisiert auf `ReceiptBase.State`.
|
||||
Aussage: Das System soll für alle Belegtypen ausschließlich die Statuswerte "Active", "Completed" und "Canceled" als gültige Werte des Feldes `State` zulassen.
|
||||
Ergebnis: Kein Beleg kann einen undefinierten oder belegtypspezifischen vierten Status annehmen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Interfaces/Sales/Receipts/ReceiptState.cs:6-14 - Begründung: Enum-Definition ist die einzige im Code zulässige Wertemenge.
|
||||
Prüfidee: Versuch, einen ungültigen Integer-Wert außerhalb {1,2,3} in `State` zu schreiben, muss durch Typsystem/DB verhindert werden.
|
||||
Tracelinks: StRS-001; SwRS-001
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-002
|
||||
Titel: Gemeinsames Basisdatenmodell für alle Belegtypen
|
||||
Ebene: SyRS
|
||||
Typ: Daten
|
||||
Akteur: System
|
||||
Vorbedingung: Ein neuer Belegtyp wird im System benötigt.
|
||||
Fakt: Alle sieben Belegtypen (Angebot, Auftrag, Lieferschein, Rechnung, Vertrag, Gutschrift, Abholschein) sind über eine gemeinsame Kopf/Positions-Struktur (`ReceiptBase`/`ReceiptItemBase`) sowie ein Kopf/Pos/Versions-Tabellenmuster abgebildet.
|
||||
Aussage: Das System soll für neue Belegtypen dasselbe Kopf/Positions-Basisdatenmodell wie für bestehende Belegtypen verwenden.
|
||||
Ergebnis: Gemeinsame Funktionalität (Suche, Sperren, Versionierung, Protokollierung) steht neuen Belegtypen ohne Neuimplementierung zur Verfügung.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/Sales/Receipts/ReceiptBase.cs, ReceiptItemBase.cs - Begründung: Gemeinsame Basisklassen aller Belegentitäten.
|
||||
- [SEKUNDÄR] docs/reference/receipts/receipts-backend-architecture.md (Abschnitt "Extensibility") - Begründung: Beschreibt den vorgesehenen Ablauf zur Erweiterung um neue Belegtypen.
|
||||
Prüfidee: Struktur eines neu hinzugefügten Belegtyps (z. B. anhand der Dokumentation) gegen die Basisklassen validieren.
|
||||
Tracelinks: StRS-001; SwRS-002
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-003
|
||||
Titel: Deklarative Belegweiterleitungs-Matrix je Belegtyp
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Eine Belegweiterleitung wird angestoßen.
|
||||
Fakt: Jede Implementierung von `IReceiptSpecificLogic` deklariert `CanBeForwardedFrom()`/`CanBeForwardedInto()` als Liste erlaubter `CentronObjectKindNumeric`-Werte; `ReceiptBL.ForwardReceipt<TTarget,...>` prüft diese Deklaration vor Ausführung.
|
||||
Aussage: Das System soll vor jeder Belegweiterleitung die deklarierte Übergangserlaubnis des Quell- und Zielbelegtyps prüfen und bei Verstoß die Weiterleitung ablehnen.
|
||||
Ergebnis: Nicht deklarierte Belegübergänge werden systemseitig, nicht nur durch UI-Konvention, verhindert.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/Orders/OrderSpecificLogic.cs:256-257 - Begründung: Konkrete Deklaration für den Belegtyp Auftrag.
|
||||
Prüfidee: Direkter API-/BL-Aufruf zur Weiterleitung eines nicht erlaubten Übergangs muss mit definiertem Fehler abgelehnt werden (nicht nur UI-seitig ausgeblendet).
|
||||
Tracelinks: StRS-002; SwRS-003
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-004
|
||||
Titel: Strukturidentität von Basis- und Versionstabellen
|
||||
Ebene: SyRS
|
||||
Typ: Daten
|
||||
Akteur: System, Datenbankschema-Migration
|
||||
Vorbedingung: Eine neue Spalte wird einer Belegtabelle hinzugefügt.
|
||||
Fakt: Versionstabellen (`*KopfVersions`/`*PosVersions`) müssen laut Architekturdokumentation exakt dieselben Spalten wie die Basistabelle enthalten (außer `I3D`, plus `OriginalI3D`/`KopfVersionsI3D`); fehlende Spalten führen zu Laufzeitfehlern in `DoGetFieldList()`.
|
||||
Aussage: Das System soll sicherstellen, dass jede Spalte einer Beleg-Basistabelle auch in der zugehörigen Versionstabelle mit identischem Datentyp existiert.
|
||||
Ergebnis: Der Versionierungsmechanismus kann für jeden Beleg vollständige Schnappschüsse erzeugen, ohne durch fehlende Spalten zu scheitern.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/reference/receipts/receipts-backend-architecture.md (Abschnitt "Adding New Columns - Complete Checklist", "Critical Warning") - Begründung: Dokumentiert den Fehlerfall bei Abweichung sowie die 10-Schritte-Checkliste zur korrekten Erweiterung.
|
||||
Prüfidee: Neue Spalte nur an der Basistabelle ergänzen (Versionstabelle bewusst auslassen) und Auftreten des dokumentierten Laufzeitfehlers bei Versionierung verifizieren.
|
||||
Tracelinks: StRS-003; SwRS-004
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround (manuell zu pflegende Strukturparität statt automatisierter Schema-Synchronisation — Migrationsrisiko für Zielsystem)
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-005
|
||||
Titel: Zentrale, belegtypübergreifende Ereignisprotokollierung
|
||||
Ebene: SyRS
|
||||
Typ: Daten
|
||||
Akteur: System
|
||||
Vorbedingung: Ein Belegereignis (Erstellung, Änderung, Abrechnung, Stornierung) tritt ein.
|
||||
Fakt: Die Tabelle `AnlageLog` protokolliert Ereignisse für alle Belegtypen einheitlich über `AnlageI3D` + `AnlageArt` (Typkennzahl je Belegtyp).
|
||||
Aussage: Das System soll belegbezogene Ereignisse aller Belegtypen in einer zentralen, typkennzahlbasierten Protokolltabelle erfassen.
|
||||
Ergebnis: Auswertungen über Belegereignisse sind belegtypübergreifend ohne UNION mehrerer Spezialtabellen möglich.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/reference/receipts/receipts-backend-architecture.md (Abschnitt "Shared Logging Infrastructure") - Begründung: Beschreibt Tabellenstruktur und AnlageArt-Wertetabelle.
|
||||
Prüfidee: Ereignis für zwei unterschiedliche Belegtypen auslösen und Vorhandensein je eines `AnlageLog`-Eintrags mit korrektem `AnlageArt` prüfen.
|
||||
Tracelinks: StRS-003; SwRS-004
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-006
|
||||
Titel: Kollisionsschutz bei gleichzeitigem Belegzugriff
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (Zuverlässigkeit, ISO 25010: Fehlertoleranz)
|
||||
Akteur: System
|
||||
Vorbedingung: Zwei Sitzungen greifen gleichzeitig auf denselben Beleg zu.
|
||||
Fakt: Anwendungsseitige Sperrentität (`AssetLock`, Spalte `Lockuser`) plus optimistisches `ConcurrencyControlGuid`-Feld auf `ReceiptBase`; beide Mechanismen sind unabhängig voneinander im Code vorhanden.
|
||||
Aussage: Das System soll konkurrierende Schreibzugriffe auf denselben Beleg erkennen und einen davon kontrolliert zurückweisen, statt Änderungen stillschweigend zu überschreiben.
|
||||
Ergebnis: Datenverlust durch "Last-Write-Wins" wird verhindert.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/Sales/CustomerAssets/AssetLocks/AssetLock.cs:6-10 - Begründung: Explizites Sperrmodell.
|
||||
- [SEKUNDÄR] tests/Centron.Tests.EndToEnd/Tests/ReceiptLock/*.expected.txt - Begründung: 8 getestete Kombinationen belegen den Anspruch an vollständige Fallabdeckung.
|
||||
Prüfidee: Siehe StRS-004.
|
||||
Tracelinks: StRS-004; SwRS-005
|
||||
Konsolidierung: Kandidat: siehe StRS-004 (zwei parallele Mechanismen).
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## B. Verträge & RMM-Abrechnung (zu StRS-005..007)
|
||||
|
||||
```
|
||||
ID: SyRS-007
|
||||
Titel: Konfigurierbares Abrechnungsintervall je Vertrag
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Ein Vertrag mit `AutomatedBilling = true` erreicht sein nächstes Abrechnungsdatum.
|
||||
Fakt: `BillingIntervalKind` (Daily/Monthly/Quarterly/Yearly) kombiniert mit `BillingIntervalDuration` bestimmt den nächsten Abrechnungszeitpunkt; `LastSubsequentBillingDate` wird nach Ausführung fortgeschrieben.
|
||||
Aussage: Das System soll das nächste Abrechnungsdatum eines Vertrags aus Intervalltyp und -dauer berechnen und nach jeder automatisierten Abrechnung fortschreiben.
|
||||
Ergebnis: Kein Vertrag wird doppelt oder verspätet automatisch abgerechnet.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/Sales/Receipts/ContractLists/ReceiptContract.cs (BillingIntervalKind, BillingIntervalDuration, LastSubsequentBillingDate) - Begründung: Datenfelder, die die Berechnung tragen.
|
||||
Prüfidee: Vertrag mit Quartalsintervall (Monthly×3) anlegen und Fälligkeitsberechnung über mehrere Zyklen prüfen.
|
||||
Tracelinks: StRS-005; SwRS-006
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-008
|
||||
Titel: Kontingentbilanzierung mit Grenzwertüberwachung
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Eine kontingentrelevante Leistung wird einem Vertrag zugebucht.
|
||||
Fakt: `ReceiptContractBL.ContractContingentBalanceCalculation` berechnet `ContingentUsedHours`/`ContingentUsedAmount` gegen `ContingentLimitValue`; `IsMonitoring`/`MonitoringValue` steuern eine zusätzliche Überwachungsschwelle.
|
||||
Aussage: Das System soll bei jeder kontingentrelevanten Buchung den Kontingentverbrauch neu berechnen und bei Überschreitung der konfigurierten Überwachungsschwelle eine Markierung setzen.
|
||||
Ergebnis: Vertragsverantwortliche werden zeitnah auf drohende oder eingetretene Kontingentüberschreitung hingewiesen.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/reference/receipts/contracts-backend.md (Abschnitt "Contingent Limits and Monitoring") - Begründung: Beschreibt die Feld- und Berechnungslogik.
|
||||
Prüfidee: Kontingent bis knapp unter, dann über die Überwachungsschwelle buchen und Statusänderung prüfen.
|
||||
Tracelinks: StRS-005, StRS-007; SwRS-006
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-009
|
||||
Titel: Fail-Closed-Verhalten bei nicht erreichbarem RMM-Dienst
|
||||
Ebene: SyRS
|
||||
Typ: Zuverlässigkeit (ISO 25010: Fehlertoleranz)
|
||||
Akteur: System
|
||||
Vorbedingung: Ein RMM-fähiger Vertrag wird abgerechnet; der externe RMM-Dienst antwortet nicht.
|
||||
Fakt: `RiverConnectionBL.GetContractBillingAmounts` liefert einen Fehlerstatus zurück; ist mindestens eine RMM-Artikelreferenz oder ein RMM-Platzhalter vorhanden, wirft der Aufrufer eine `RMMServiceUnavailableException`, die die gesamte Rechnungserstellung abbricht.
|
||||
Aussage: Das System soll die automatische Rechnungserstellung für einen RMM-abhängigen Vertrag vollständig abbrechen, wenn der externe RMM-Dienst zum Abrechnungszeitpunkt nicht erreichbar ist.
|
||||
Ergebnis: Keine Rechnung mit fehlenden oder veralteten Nutzungsdaten wird versehentlich final gestellt.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/reference/receipts/Contract-Billing-RMM-Article-Logic.md (Codebeispiel `RMMServiceUnavailableException`) - Begründung: Zeigt exakten Bedingungs- und Abbruchcode.
|
||||
Prüfidee: RMM-Dienst-Endpunkt für einen Testlauf deaktivieren und Abbruch der Rechnungserstellung mit definierter Fehlermeldung prüfen.
|
||||
Tracelinks: StRS-006; SwRS-007
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## C. C-Sign / Web-Angebot (zu StRS-008..009)
|
||||
|
||||
```
|
||||
ID: SyRS-010
|
||||
Titel: Mehrstufiger Statuswechsel für Web-Angebote
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Ein Angebot wird über den Web-Kanal versendet.
|
||||
Fakt: `WebReceiptState` definiert 9 Zustände (`InProcess`, `FirstLoaded`, `SendToCustomer`, `WebOfferSign`, `AcceptFullWebReceipt`, `AcceptWebReceiptWithChangeRequests`, `Rejected`, `WebReceiptShutDown`, `WebOfferSignedWithoutSignature`); `ReceiptBL.ChangeWebReceiptState` dispatcht je nach Zielzustand auf spezialisierte Methoden.
|
||||
Aussage: Das System soll den Fortschritt eines Web-Angebots über die neun definierten Zwischenzustände nachvollziehbar abbilden und Zustandswechsel nur über definierte Dispatch-Methoden zulassen.
|
||||
Ergebnis: Der aktuelle Bearbeitungsstand eines Web-Angebots ist jederzeit eindeutig bestimmbar.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Interfaces/Sales/Receipts/WebReceipt/WebReceiptState.cs:6-26 - Begründung: Vollständige Enum-Definition.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs:5903-5934 (ChangeWebReceiptState) - Begründung: Zentrale Dispatch-Methode.
|
||||
Prüfidee: Web-Angebot durch alle Hauptpfade (Annahme ohne Signatur / mit Signatur / Ablehnung / Änderungswunsch) führen und Zustandsfolge protokollieren.
|
||||
Tracelinks: StRS-008; SwRS-008
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-011
|
||||
Titel: Getrennte interne Freigabe vor externem Kundenversand
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Vertriebsmitarbeiter
|
||||
Vorbedingung: Ein zu signierendes Dokument soll an den Kunden versendet werden.
|
||||
Fakt: `SharedDocumentAcceptancePage.razor` implementiert einen eigenen, internen Freigabeschritt (`AcceptSharedDocument`/`DeclineSharedDocument`) über einen Token-Link, bevor `AcceptWebReceipt` den kundenseitigen Signaturlink per E-Mail versendet.
|
||||
Aussage: Das System soll den Versand eines zur Kundenunterschrift bestimmten Dokuments von einer vorgelagerten internen Freigabe durch einen Mitarbeiter abhängig machen können.
|
||||
Ergebnis: Fehlerhafte oder unvollständige Dokumente erreichen den Kunden nicht ungeprüft.
|
||||
Belege:
|
||||
- [PRIMÄR] src/nexus/CentronNexus/Office/SharedDocumentAcceptancePage.razor:167-179 - Begründung: Konkrete Freigabe-/Ablehnungsaktionen.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Security/PdfSigningBL.cs:126-165 - Begründung: Nachgelagerte kryptographische Signatur nach Freigabe.
|
||||
Prüfidee: Dokument ohne interne Freigabe darf nicht an den Kunden-Signaturlink gelangen; nach Freigabe muss der Versand erfolgen.
|
||||
Tracelinks: StRS-008, StRS-009; SwRS-008
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## D. Kunde/CRM (zu StRS-010..012)
|
||||
|
||||
```
|
||||
ID: SyRS-012
|
||||
Titel: Kreditlimitprüfung als weicher Kontrollpunkt beim Belegspeichern
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Ein limitrelevanter Beleg (aktiver Auftrag) wird gespeichert.
|
||||
Fakt: `ReceiptBL.CheckIfCustomerLimitIsReached` berechnet den genutzten Kreditrahmen aus allen `Active`-Belegen, die laut `TakesPlaceInLimitCalculation()` limitrelevant sind, und liefert bei Überschreitung ein Bestätigungserfordernis (`ShowCustomerLimitExceededDialog`) statt eines harten Fehlers zurück.
|
||||
Aussage: Das System soll bei jedem Speichern eines limitrelevanten Belegs den genutzten Kreditrahmen neu berechnen und bei Überschreitung ein explizites Bestätigungssignal an den aufrufenden Client zurückgeben.
|
||||
Ergebnis: Die UI kann dem Benutzer eine Bestätigungsabfrage anzeigen, ohne die Geschäftslogik zu duplizieren.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs:8636 - Begründung: Konkrete Berechnungs- und Rückgabelogik.
|
||||
Prüfidee: Siehe StRS-010.
|
||||
Tracelinks: StRS-010; SwRS-009
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-013
|
||||
Titel: API-Bereitstellung kundenspezifischer Sonderpreis-Artikellisten
|
||||
Ebene: SyRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: Nexus-Web-Client
|
||||
Vorbedingung: Ein Web-Account ruft die für ihn verfügbaren Artikel ab.
|
||||
Fakt: `CustomersController` stellt `GET special-price-articles` und `GET {customerId}/special-price-articles` bereit.
|
||||
Aussage: Das System soll eine REST-Schnittstelle bereitstellen, über die die für einen Kunden hinterlegten Sonderpreis-Artikel abgefragt werden können.
|
||||
Ergebnis: Der Web-Client kann die WebCart-Artikelsicht ohne direkten Datenbankzugriff aufbauen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/webservice/Centron.Controllers/Controllers/v1/Customers/CustomersController.cs:12-100 - Begründung: Konkrete Endpunktdefinition.
|
||||
Prüfidee: Endpunkt für einen Testkunden mit Sonderpreisen aufrufen und korrekte Artikelliste inkl. Preis prüfen.
|
||||
Tracelinks: StRS-011, StRS-035; SwRS-010
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-014
|
||||
Titel: Kundenindividuelle Katalogsteuerung (Produktmatrix)
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Ein Kunde/Web-Account ruft den Artikelkatalog ab.
|
||||
Fakt: `CustomerProductMatrixCategory`/`CustomerProductMatrixProduct` bilden eine kundenindividuell kuratierte Kategorie-/Produktstruktur ab (`ProductMatrixBL`).
|
||||
Aussage: Das System soll es ermöglichen, den für einen Kunden sichtbaren Artikelkatalog über kundenindividuell zugeordnete Kategorien/Produkte einzuschränken.
|
||||
Ergebnis: Kunden sehen nur die für sie freigegebenen Kategorien/Produkte.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/ProductMatrix/ProductMatrixBL.cs:27-60 - Begründung: Konkrete Zugriffsmethoden auf die kundenindividuelle Struktur.
|
||||
Prüfidee: Kundenindividuelle Produktmatrix konfigurieren und Filterwirkung im Katalog/WebCart prüfen.
|
||||
Tracelinks: StRS-011; SwRS-010
|
||||
Konsolidierung: Kandidat: Verhältnis zu Sonderpreis-Mechanismus (SyRS-013) ungeklärt — möglicherweise zwei Mechanismen für dasselbe fachliche Ziel "Artikelsichtbarkeit je Kunde steuern" (siehe Hypothesen.md).
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## E. Helpdesk/Ticket (zu StRS-013..014)
|
||||
|
||||
```
|
||||
ID: SyRS-015
|
||||
Titel: Konfigurierbare Ticketerstellungs-Vorlagen mit eindeutiger Standardvorlage
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Mehrere Ticketerstellungs-Vorlagen existieren.
|
||||
Fakt: `HelpdeskCreationTemplateBL.SetStandardTemplate` stellt sicher, dass zu jedem Zeitpunkt höchstens eine Vorlage als Standard markiert ist; `DeleteTemplate` verweigert das Löschen der Standardvorlage.
|
||||
Aussage: Das System soll zu jedem Zeitpunkt höchstens eine Ticketerstellungs-Standardvorlage zulassen und deren Löschung verhindern, solange sie als Standard markiert ist.
|
||||
Ergebnis: Es ist immer eindeutig, welche Vorlage bei Neuöffnung des Formulars automatisch geladen wird.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/features/automatic-helpdesk-creation-templates.md (Abschnitt "Business Rules", "Known Limitations") - Begründung: Dokumentiert beide Regeln explizit inkl. Methodennamen.
|
||||
Prüfidee: Zweite Vorlage als Standard setzen und Aberkennung des Standard-Flags der ersten Vorlage prüfen; Löschversuch der aktuellen Standardvorlage muss scheitern.
|
||||
Tracelinks: StRS-013, StRS-014; SwRS-011
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## F. Rechte & Zugriffssteuerung (zu StRS-015..018)
|
||||
|
||||
```
|
||||
ID: SyRS-016
|
||||
Titel: Zentraler, gecachter Rechteprüfungsdienst
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System (jede geschützte Aktion)
|
||||
Vorbedingung: Eine geschützte Aktion wird ausgeführt.
|
||||
Fakt: `AppRightsBL.HasUserRight` nutzt einen Session-Cache (`Session.Advanced.Cache.GetOrAdd`) für die Rechteliste je Benutzer, rückt aber bei jeder Prüfung auf denselben SQL-Join (`Sichtrus`↔`Sichmemb`) zurück, falls nicht gecacht.
|
||||
Aussage: Das System soll die Menge der einem Benutzer zugewiesenen Rechte innerhalb einer Sitzung cachen, um wiederholte Datenbankabfragen bei aufeinanderfolgenden Rechteprüfungen zu vermeiden.
|
||||
Ergebnis: Rechteprüfungen sind performant, ohne die Autorisierungslogik zu duplizieren.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs:644-651 - Begründung: Konkrete Cache- und SQL-Join-Implementierung.
|
||||
Prüfidee: Mehrere Rechteprüfungen innerhalb derselben Sitzung ausführen und (via Profiling) genau einen SQL-Zugriff für die Rechteliste nachweisen.
|
||||
Tracelinks: StRS-015, StRS-017; SwRS-012
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-017
|
||||
Titel: Ausschließliche Rechtevergabe über Gruppenmitgliedschaft
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Systemadministrator
|
||||
Vorbedingung: Ein Recht soll einem Benutzer zugeordnet werden.
|
||||
Fakt: Es existiert keine Datenbanktabelle für eine direkte Nutzer-Recht-Zuordnung; Rechte werden ausschließlich über `AppGroup.Rights` und `AppUser.Groups` (Join `Sichtrus`↔`Sichmemb`) vergeben.
|
||||
Aussage: Das System soll Benutzerrechte ausschließlich über die Zuordnung von Benutzern zu Berechtigungsgruppen vergeben, nicht über eine direkte Benutzer-Recht-Zuordnung.
|
||||
Ergebnis: Rechteänderungen für mehrere Benutzer gleichzeitig sind über eine einzige Gruppenänderung möglich; Einzelrechte pro Benutzer sind architektonisch ausgeschlossen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs:63-87 (GetRightsFromCurrentUser, Union über user.Groups) - Begründung: Zeigt, dass die effektiven Rechte ausschließlich aus Gruppen ermittelt werden.
|
||||
Prüfidee: Versuch, einem Benutzer ohne Gruppenzuordnung ein Einzelrecht zuzuweisen — es muss kein entsprechender Mechanismus im System existieren.
|
||||
Tracelinks: StRS-015, StRS-016, StRS-018; SwRS-012, SwRS-013
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-018
|
||||
Titel: Austauschbare Authentifizierungsstrategie über Factory-Pattern
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System
|
||||
Vorbedingung: Ein Login-Versuch wird empfangen.
|
||||
Fakt: `AuthenticatorFactory` liefert je nach `SystemAuthenticationMethod` und `WebLoginType` eine passende `IAuthenticator`-Implementierung (Basic/ActiveDirectory/OpenIdConnect/WebAccount), optional verkettet mit `FallbackAuthenticator`.
|
||||
Aussage: Das System soll die Wahl der Authentifizierungsmethode zur Laufzeit anhand einer Systemeinstellung treffen, ohne dass aufrufender Code die konkrete Methode kennen muss.
|
||||
Ergebnis: Neue Authentifizierungsmethoden können ergänzt werden, ohne bestehende Aufrufer zu ändern.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Logins/Auth/AuthenticatorFactory.cs - Begründung: Konkrete Factory-Implementierung.
|
||||
Prüfidee: Systemeinstellung zwischen den drei Methoden umschalten und erfolgreichen Login je Methode prüfen.
|
||||
Tracelinks: StRS-019, StRS-021; SwRS-014
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-019
|
||||
Titel: Zertifikatsbasierte JWT-Bearer-Validierung für OIDC-Anmeldung
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System
|
||||
Vorbedingung: Ein Client präsentiert ein Microsoft-Entra-ID-Token an `POST jwt/login`.
|
||||
Fakt: `CentronHost.cs` konfiguriert `AddJwtBearer` mit `ValidateIssuer/Audience/Lifetime/IssuerSigningKey = true`, `RequireSignedTokens = true`, `RequireExpirationTime = true`, `ValidateTokenReplay = true`; der Endpunkt ist zusätzlich mit `[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]` geschützt.
|
||||
Aussage: Das System soll bei der OIDC-Anmeldung sämtliche Standard-JWT-Validierungsprüfungen (Signatur, Aussteller, Zielgruppe, Gültigkeitsdauer, Replay-Schutz) durchsetzen, bevor ein internes Sitzungsticket ausgestellt wird.
|
||||
Ergebnis: Manipulierte, abgelaufene oder wiederverwendete Tokens werden abgelehnt.
|
||||
Belege:
|
||||
- [PRIMÄR] src/webservice/Centron.Host/CentronHost.cs:186-205 - Begründung: Konkrete `TokenValidationParameters`-Konfiguration.
|
||||
- [SEKUNDÄR] docs/reference/security/anmelden-mit-microsoft-technische-anleitung.md - Begründung: Beschreibt den vollständigen Ablauf inkl. Discovery-Document und JWKS-Abruf.
|
||||
Prüfidee: Manipuliertes/abgelaufenes Token gegen `jwt/login` senden und Ablehnung (401) prüfen.
|
||||
Tracelinks: StRS-019; SwRS-014
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-020
|
||||
Titel: Feste Sitzungs-Gültigkeitsdauern mit kontinuierlicher Revalidierung im Web-Client
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System, Nexus-Web-Client
|
||||
Vorbedingung: Eine Sitzung ist aktiv.
|
||||
Fakt: Server: `TicketExpireInMinutes=30`; Web-Client: `CentronAuthenticationStateProvider` revalidiert alle 1-2 Minuten gegen `ICentronService.IsValidTicket()`, mit bis zu 3 Wiederholungsversuchen (2 s Verzögerung) bei transienten Fehlern, bevor eine erzwungene Abmeldung erfolgt.
|
||||
Aussage: Das System soll serverseitige Sitzungen nach spätestens 30 Minuten automatisch ungültig werden lassen und im Web-Client die Sitzungsgültigkeit in kürzeren Abständen aktiv prüfen, um Sitzungsabläufe zeitnah zu erkennen.
|
||||
Ergebnis: Eine im Hintergrund abgelaufene Sitzung wird dem Nutzer im Web-Client innerhalb weniger Minuten angezeigt statt erst beim nächsten fehlschlagenden Aufruf.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Logins/TicketBL.cs:26-28,61 - Begründung: Serverseitige Ablaufzeit.
|
||||
- [PRIMÄR] src/nexus/CentronNexus/Shared/Auth/CentronAuthenticationStateProvider.cs:15-66 - Begründung: Clientseitige Revalidierungs-/Retry-Konfiguration inkl. Kommentar zur bewussten Intervallverkürzung gegen ein Race-Window.
|
||||
Prüfidee: Ticket serverseitig invalidieren und Zeit bis zur client-seitigen Erkennung (Abmeldung/Hinweis) messen; muss innerhalb des konfigurierten Revalidierungsintervalls liegen.
|
||||
Tracelinks: StRS-020; SwRS-015
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## G. Lizenzierung (zu StRS-022)
|
||||
|
||||
```
|
||||
ID: SyRS-021
|
||||
Titel: Lizenzgate als eigenständige Autorisierungsanforderung
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System
|
||||
Vorbedingung: Ein API-Aufruf betrifft eine lizenzpflichtige, intern gehostete Funktion.
|
||||
Fakt: `CentronHostedAuthorization` implementiert eine ASP.NET-Core-`AuthorizationRequirement`, deren einzige Prüfung `LicenseManager.Instance.HasLicense(LicenseGuids.CentronInternal)` ist — unabhängig von Benutzeridentität.
|
||||
Aussage: Das System soll eine Lizenzprüfung als eigenständige, von der Benutzeridentität unabhängige Autorisierungsanforderung im API-Pipeline umsetzen, kombinierbar mit rechtebasierten Prüfungen.
|
||||
Ergebnis: Funktionen ohne gültige Installationslizenz sind unabhängig von individuellen Benutzerrechten gesperrt.
|
||||
Belege:
|
||||
- [PRIMÄR] src/webservice/Centron.Controllers/Authorization/CentronHostedAuthorization.cs:8-35 - Begründung: Konkrete Requirement-/Handler-Implementierung.
|
||||
Prüfidee: Lizenz `CentronInternal` deaktivieren und Zugriff auf entsprechend geschützten Endpunkt trotz gültiger Benutzerrechte prüfen (muss abgelehnt werden).
|
||||
Tracelinks: StRS-022, StRS-042; SwRS-016
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## H. Rechnungsstellung/Nummerierung/Festschreibung (zu StRS-023..027)
|
||||
|
||||
```
|
||||
ID: SyRS-022
|
||||
Titel: Kollisionssichere Nummernvergabe unter Nebenläufigkeit
|
||||
Ebene: SyRS
|
||||
Typ: Zuverlässigkeit (ISO 25010: Fehlertoleranz)
|
||||
Akteur: System
|
||||
Vorbedingung: Zwei Belege desselben Nummernkreises werden nahezu gleichzeitig gespeichert.
|
||||
Fakt: `NumberGroupBL` verwendet eine bedingte `UPDATE NumberGroup SET Current = next WHERE I3D=... AND Current = <alter Wert>`-Schleife, die bei Nichttreffer (paralleler Änderung durch anderen Prozess) wiederholt wird, bis genau eine Zeile betroffen ist.
|
||||
Aussage: Das System soll die Vergabe der nächsten Belegnummer eines Nummernkreises so implementieren, dass bei gleichzeitigem Zugriff mehrerer Prozesse keine doppelte Nummer entstehen kann.
|
||||
Ergebnis: Auch unter hoher Last/Parallelität bleibt die Nummernvergabe eindeutig.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Company/NumberGroupBL.cs (GetNextNumber, FindNextNumber) - Begründung: Konkrete optimistische Update-Schleife.
|
||||
Prüfidee: Lasttest mit ≥10 parallelen Rechnungserstellungen gegen denselben Nummernkreis; Eindeutigkeit aller vergebenen Nummern prüfen.
|
||||
Tracelinks: StRS-023; SwRS-017
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-023
|
||||
Titel: Mehrfach abgesicherte Änderungssperre für finalisierte/exportierte Rechnungen
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System
|
||||
Vorbedingung: Eine Änderung/Stornierung/Löschung an einer Rechnung, Zahlung oder Bankverbindung wird angefragt.
|
||||
Fakt: Mehrere unabhängige Guard-Prüfungen verhindern inkonsistente Finanzbuchungen: `IsFixed`-Prüfung vor Bearbeitung, Export-Status-Prüfung (`IsReceiptExported`) vor Stornierung, Referenzprüfung vor Löschung einer Bankverbindung, Rechteprüfung vor Zahlungslöschung mit korrekter Rückbuchung.
|
||||
Aussage: Das System soll Änderungen, Stornierungen und Löschungen an finanzrelevanten Objekten (Rechnung, Zahlung, Bankverbindung) nur zulassen, wenn keine der jeweils relevanten Sperrbedingungen (Festschreibung, Buchhaltungsexport, aktive Referenzierung, fehlende Berechtigung) zutrifft.
|
||||
Ergebnis: Bereits weiterverarbeitete oder referenzierte Finanzdaten bleiben konsistent.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs:86,143,273 - Begründung: Festschreibungs- und Stornierungs-Guards.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Accounting/BankAccountBL.cs:119 - Begründung: Referenzprüfung vor Löschung.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Finances/Payments/PaymentsBL.cs:38 - Begründung: Rechteprüfung + korrekte Rückbuchung bei Zahlungslöschung.
|
||||
Prüfidee: Je Guard einen gezielten Verletzungsversuch durchführen und Ablehnung mit spezifischer Fehlermeldung prüfen.
|
||||
Tracelinks: StRS-024, StRS-025, StRS-026, StRS-027; SwRS-018
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## I. E-Invoicing/EDI (zu StRS-028..029)
|
||||
|
||||
```
|
||||
ID: SyRS-024
|
||||
Titel: Konfigurierbare Erzeugung strukturierter E-Rechnungsformate
|
||||
Ebene: SyRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: System
|
||||
Vorbedingung: Eine Rechnung wird finalisiert und die entsprechende Einstellung ist aktiviert.
|
||||
Fakt: `IsZugferdInvoiceActive` (ApplicationSettings) steuert, ob `InvoiceZugferdBL` beim Rechnungsdruck zusätzlich eine ZUGFeRD-konforme Hybrid-PDF erzeugt; `EbInterfaceLogic` erzeugt unabhängig davon ebInterface-XML.
|
||||
Aussage: Das System soll die Erzeugung des ZUGFeRD-Rechnungsformats über eine globale Einstellung aktivierbar/deaktivierbar machen und bei Aktivierung automatisch bei jeder Rechnungsfinalisierung anwenden.
|
||||
Ergebnis: Kunden mit gesetzlicher oder vertraglicher E-Rechnungspflicht erhalten automatisch konforme Dokumente, ohne Sonderprozess je Rechnung.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/guides/development/settings-management.md (Beispiel `IsZugferdInvoiceActive`) - Begründung: Zeigt die Einstellung als steuerbaren Schalter.
|
||||
- [PRIMÄR] src/backend/Centron.BL/DataExchange/EDI/SaleInvoices/InvoiceZugferdBL.cs - Begründung: Konkrete Erzeugungslogik.
|
||||
Prüfidee: Einstellung aktivieren, Rechnung finalisieren, PDF auf eingebettete ZUGFeRD-XML prüfen (z. B. mit KOSIT-Validator).
|
||||
Tracelinks: StRS-028; SwRS-019
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-025
|
||||
Titel: Distributorspezifisches EDI-Routing für ausgehende Bestellungen
|
||||
Ebene: SyRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: System
|
||||
Vorbedingung: Ein Bestellvorschlag wird an einen EDI-fähigen Distributor übermittelt.
|
||||
Fakt: `EDIDispatcherBL` wählt anhand `EDIMultidistributors` (None/Orderowner/ITScope/EGIS/Concerto) die passende Bestell-Erzeugungsklasse; ohne spezifische Konfiguration wird openTRANS 2.1 als Standardformat verwendet.
|
||||
Aussage: Das System soll für jeden angebundenen Distributor automatisch das jeweils passende EDI-Bestellformat erzeugen und bei fehlender Distributor-spezifischer Konfiguration auf den offenen Branchenstandard openTRANS 2.1 zurückfallen.
|
||||
Ergebnis: Neue Distributoren ohne Sonderformat sind ohne Zusatzentwicklung sofort anbindbar.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/EDI/EDIDispatcherBL.cs:36,56 - Begründung: Konkrete Routing- und Default-Logik.
|
||||
Prüfidee: Bestellung an einen nicht speziell konfigurierten Distributor auslösen und Erzeugung eines validen openTRANS-2.1-Dokuments prüfen.
|
||||
Tracelinks: StRS-029; SwRS-020
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-026
|
||||
Titel: Formaterkennung und Partial-Class-Verarbeitung eingehender Lieferanten-EDI-Dokumente
|
||||
Ebene: SyRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: System
|
||||
Vorbedingung: Eine EDI-Datei eines Lieferanten wird empfangen (Auftragsbestätigung, Lieferung, Rechnung).
|
||||
Fakt: `SupplierEdiBL` erkennt Format/Objektart (`EdiDataType`, `EDIConnectionObjectKind`) und delegiert an eine lieferantenspezifische Partial-Class (`.Also.cs`, `.AlsoCH.cs`, `.Alltron.cs`, `.Herweck.cs`, `.Komsa.cs`, `.Opentrans.cs`).
|
||||
Aussage: Das System soll eingehende EDI-Dokumente automatisch nach Format und Dokumentart klassifizieren und an eine dedizierte, lieferantenspezifische Verarbeitungsroutine weiterleiten.
|
||||
Ergebnis: Format-Erweiterungen (neue Lieferanten) sind isoliert ergänzbar, ohne die zentrale Dispatch-Logik zu ändern.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/EDI/SupplierEDI/SupplierEdiBL.cs (2179 Zeilen, Partial-Class-Struktur) - Begründung: Konkrete Klassenstruktur.
|
||||
- [SEKUNDÄR] docs/reference/edi/edi-architecture.md - Begründung: Dokumentiert Klassenhierarchie und Datenflussdiagramm.
|
||||
Prüfidee: Testdatei je unterstütztem Format einspielen und korrekte Delegation an die jeweilige Partial-Class (per Log/Trace) prüfen.
|
||||
Tracelinks: StRS-029; SwRS-020
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## J. Einkauf (zu StRS-030..031)
|
||||
|
||||
```
|
||||
ID: SyRS-027
|
||||
Titel: Bestandsbasierte Bestellvorschlagsberechnung je Lager
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Artikelbestand, offener Bedarf und Zulauf sind bekannt.
|
||||
Fakt: `OrderSuggestionListBL.GetOrderSuggestionWH` berechnet Vorschläge je Lager unter Einbeziehung von `RefreshIntake` (Zulauf/erwarteter Wareneingang) und distributorspezifischer Preisdaten (`GetDistributorToArticle`).
|
||||
Aussage: Das System soll Bestellvorschläge je Artikel und Lager unter Berücksichtigung des bereits im Zulauf befindlichen Bestands berechnen.
|
||||
Ergebnis: Doppelbestellungen für bereits unterwegs befindliche Ware werden vermieden.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Purchasing/OrderSuggestionList/OrderSuggestionListBL.cs (GetOrderSuggestionWH, RefreshIntake:1088) - Begründung: Konkrete Berechnungsmethoden.
|
||||
Prüfidee: Artikel mit offenem Zulauf und Unterschreitung des Mindestbestands prüfen; Bestellvorschlagsmenge muss den Zulauf berücksichtigen.
|
||||
Tracelinks: StRS-030; SwRS-021
|
||||
Konsolidierung: nein
|
||||
Status: belegt; [HYPOTHESE] siehe Hypothesen.md H-04.
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-028
|
||||
Titel: Kumulierte Teillieferungsverfolgung je Bestellposition
|
||||
Ebene: SyRS
|
||||
Typ: Daten
|
||||
Akteur: System
|
||||
Vorbedingung: Ein Wareneingang zu einer Lieferantenbestellung wird gebucht.
|
||||
Fakt: `ReceiptSupplierOrderIntake` speichert `InStock`/`Booked` je Bestellposition; `SupplierOrderSpecificLogic.UpdateIntake` aktualisiert diese Werte kumulativ bei jeder Wareneingangsbuchung.
|
||||
Aussage: Das System soll bei jedem Wareneingang zu einer Bestellposition die kumulierte Eingangsmenge fortschreiben, statt nur den letzten Eingang zu speichern.
|
||||
Ergebnis: Der Gesamtstatus einer Bestellposition ("wie viel wurde insgesamt geliefert") ist nach beliebig vielen Teillieferungen korrekt.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/SupplierOrders/SupplierOrderSpecificLogic.cs:177-215 - Begründung: Konkrete kumulative Update-Logik.
|
||||
Prüfidee: Siehe StRS-031.
|
||||
Tracelinks: StRS-031; SwRS-022
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## K. Lager (zu StRS-032..033)
|
||||
|
||||
```
|
||||
ID: SyRS-029
|
||||
Titel: Richtungsabhängige Negativbestands-Kontrollpolitik mit vollständiger Protokollierung
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Eine Bestandsbuchung wird durchgeführt.
|
||||
Fakt: `ReceiptArticleBookingBL` prüft Negativbuchung nur bei "neu negativ" werdendem Bestand; die Aktivierung dieser Prüfung ist je Belegrichtung konfigurierbar (`WarnIfUserMakesNegativeArticleBooking`/`UserNeedsRightToMakeNegativeArticleBooking`, deaktiviert für Wareneingang, aktiv für Warenausgang); jede Bestandsänderung wird unabhängig davon über `WriteAmountChangeLog` protokolliert.
|
||||
Aussage: Das System soll die Negativbestandsprüfung richtungsabhängig (Wareneingang vs. -ausgang) konfigurierbar machen und unabhängig vom Ergebnis der Prüfung jede Bestandsänderung protokollieren.
|
||||
Ergebnis: Fachlich sinnvolle Buchungsrichtungen werden nicht unnötig blockiert; jede Mengenänderung bleibt nachvollziehbar.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/Internal/ReceiptArticleBookingBL.cs:340-429 - Begründung: Zentrale Buchungs- und Protokollierungslogik.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/DeliveryLists/DeliveryListSpecificLogic.cs:200-201 vs. SupplierOrderSpecificLogic.cs:222-230 - Begründung: Konkreter Beleg für die richtungsabhängige Konfiguration.
|
||||
Prüfidee: Siehe StRS-032/033.
|
||||
Tracelinks: StRS-032, StRS-033; SwRS-023
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## L. Externe Preisquellen (zu StRS-034)
|
||||
|
||||
```
|
||||
ID: SyRS-030
|
||||
Titel: Parallele, zeitlich gefilterte Aggregation mehrerer Preisquellen
|
||||
Ebene: SyRS
|
||||
Typ: Performance-Effizienz
|
||||
Akteur: System
|
||||
Vorbedingung: Ein Benutzer öffnet die Preismatrix eines Artikels.
|
||||
Fakt: Bis zu sieben Preisquellen (interne Aktionspreise + vier externe APIs + Artikelimport) werden parallel geladen; Ergebnisse werden nach Herstellercode+EAN gecacht und bei Änderung an Aktionspreisen invalidiert; Aktionspreise werden zusätzlich nach Gültigkeitszeitraum gefiltert (`EffectiveFrom.StartOfDay() <= DateTime.Now && EffectiveUntil >= DateTime.Now`).
|
||||
Aussage: Das System soll Preisdaten aus mehreren internen und externen Quellen parallel abrufen, das Ergebnis cachen und bei Änderung interner Preisdaten gezielt invalidieren.
|
||||
Ergebnis: Die Preismatrix bleibt trotz mehrerer externer Abhängigkeiten performant nutzbar.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/reference/receipts/actionprice-system.md (Abschnitt "Cache Behavior", "Display Rules") - Begründung: Beschreibt Cache-Schlüssel, Invalidierung und Gültigkeitsfilter.
|
||||
Prüfidee: Aktionspreis außerhalb des Gültigkeitszeitraums anlegen und Nichterscheinen in der Preismatrix prüfen; Preismatrix-Ladezeit mit und ohne Cache messen.
|
||||
Tracelinks: StRS-034; SwRS-024
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## M. Web-Portal & TradePool (zu StRS-035..036)
|
||||
|
||||
```
|
||||
ID: SyRS-031
|
||||
Titel: Cookie-/Ticket-basierte Sitzungsverwaltung im Blazor-Server-Portal
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Kunde (Web-Account)
|
||||
Vorbedingung: Ein Kunde meldet sich am Nexus-Portal an (direkt oder über OIDC).
|
||||
Fakt: `AuthController` (`Route("auth")`) signiert nach erfolgreichem Ticket-Erhalt über `CookieAuthenticationDefaults.AuthenticationScheme` ein; zusätzliche OIDC-Routen (`auth/oidc/login`, `.../reauthenticate`) nutzen `OpenIdConnectDefaults` mit einer temporären Cookie-Zwischenstufe.
|
||||
Aussage: Das System soll die Web-Portal-Sitzung eines Kunden nach erfolgreicher Authentifizierung (direkt oder über OIDC) über ein serverseitiges Authentifizierungs-Cookie verwalten, das an das zugrunde liegende c-entron-Ticket gekoppelt ist.
|
||||
Ergebnis: Der Kunde bleibt im Web-Portal angemeldet, solange sowohl Cookie als auch zugrunde liegendes Ticket gültig sind.
|
||||
Belege:
|
||||
- [PRIMÄR] src/nexus/CentronNexus/Shared/Auth/AuthController.cs (auth/complete_login, auth/oidc/*) - Begründung: Konkrete Cookie-/OIDC-Implementierung.
|
||||
Prüfidee: Login über Nexus durchführen, Cookie-Setzung prüfen, Ticket serverseitig invalidieren und erzwungene Abmeldung gemäß SyRS-020 prüfen.
|
||||
Tracelinks: StRS-035; SwRS-025
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-032
|
||||
Titel: Eigenständige, salted-hash-basierte Authentifizierung für TradePool-Kunden
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Kunde (TradePool)
|
||||
Vorbedingung: Ein TradePool-Kunde meldet sich am separaten Portal an.
|
||||
Fakt: `TradePoolBL.AuthenticateUser` nutzt eine gesalzene Passwort-Hash-Prüfung, getrennt von den übrigen Authentifizierungswegen (Ticket/JWT/AD/OIDC).
|
||||
Aussage: Das System soll für den TradePool-Kundenzugang eine eigenständige, vom Haupt-Authentifizierungssystem unabhängige Anmeldung mit gesalzenem Passwort-Hash bereitstellen.
|
||||
Ergebnis: TradePool-Kunden benötigen keinen regulären c-entron-Benutzer-/Web-Account.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/TradePool/TradePoolBL.cs:170-183 - Begründung: Konkrete, eigenständige Authentifizierungsimplementierung.
|
||||
Prüfidee: TradePool-Login mit korrektem/falschem Passwort testen; Nichtverfügbarkeit einer TradePool-Sitzung für reguläre c-entron-Endpunkte prüfen.
|
||||
Tracelinks: StRS-036; SwRS-025
|
||||
Konsolidierung: Kandidat: dritter, unabhängiger Authentifizierungsmechanismus neben Haupt-Auth (SyRS-018) und Web-Account-Rechten (StRS-017) — Konsolidierungspotenzial für Zielsystem.
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## N. Betrieb/DevOps (zu StRS-037..038)
|
||||
|
||||
```
|
||||
ID: SyRS-033
|
||||
Titel: Container-basierte Referenzarchitektur für Testbetrieb
|
||||
Ebene: SyRS
|
||||
Typ: Übertragbarkeit
|
||||
Akteur: Systemadministrator/DevOps
|
||||
Vorbedingung: Eine Testumgebung soll aufgesetzt werden.
|
||||
Fakt: `docker/compose/compose.yaml` definiert vier Dienste (db=MSSQL, webservice, smtp=Mailcatcher, nexus) in einem gemeinsamen Netzwerk; das produktive Webservice-Image basiert auf .NET 10 / Alpine Linux mit vorinstallierten ICU/Schriftarten für Dokumentgenerierung.
|
||||
Aussage: Das System soll über eine vollständige Docker-Compose-Referenzarchitektur (Datenbank, Web-Service, Mail-Testserver, Web-Portal) reproduzierbar als Testumgebung aufsetzbar sein.
|
||||
Ergebnis: Neue Entwickler/Umgebungen können ohne manuelle Einzelinstallation eine funktionsfähige Instanz starten.
|
||||
Belege:
|
||||
- [PRIMÄR] docker/compose/compose.yaml:1-54 - Begründung: Vollständige Dienstdefinition inkl. Ports, Abhängigkeiten, Health-relevanter Reihenfolge (`depends_on`).
|
||||
- [PRIMÄR] docker/c-entron-api/Dockerfile - Begründung: Bestätigt .NET 10/Alpine als produktive Laufzeitbasis.
|
||||
Prüfidee: `docker compose up` gemäß Konfiguration ausführen und Erreichbarkeit aller vier Dienste prüfen.
|
||||
Tracelinks: StRS-037; SwRS-026
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-034
|
||||
Titel: Ausgewiesene funktionale Einschränkungen im Linux-Betrieb
|
||||
Ebene: SyRS
|
||||
Typ: Übertragbarkeit
|
||||
Akteur: Systemadministrator
|
||||
Vorbedingung: Der Web-Service wird unter Linux statt Windows betrieben.
|
||||
Fakt: Dokumentierte Einschränkungen: Sub-Web-Services funktionieren nicht unter Linux (Code liegt nur in der Windows-only "Connection Manager"-Anwendung); es existiert kein Konfigurationswerkzeug für Linux (manuelles Editieren von `WebServiceConfig.xml`); das Zertifikatspasswort liegt unter Linux im Klartext in der Konfigurationsdatei (im Gegensatz zur verschlüsselten Windows-Konfiguration).
|
||||
Aussage: Das System soll die unter Linux bestehenden funktionalen und sicherheitsrelevanten Einschränkungen (fehlende Sub-Web-Service-Unterstützung, Klartext-Zertifikatspasswort, kein Konfigurationswerkzeug) gegenüber dem Windows-Betrieb dokumentieren.
|
||||
Ergebnis: Betreiber treffen die Plattformwahl auf Basis bekannter, nicht erst im Betrieb entdeckter Einschränkungen.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/guides/services/web-service-on-linux.md (Abschnitte "Differences between Linux and Windows", "What is left to do") - Begründung: Explizite Auflistung aller drei Einschränkungen durch die Entwickler selbst.
|
||||
Prüfidee: Linux-Installation gemäß Dokumentation aufsetzen und Nichtverfügbarkeit der Sub-Web-Services sowie Klartext-Zertifikatspasswort in der Konfigurationsdatei verifizieren.
|
||||
Tracelinks: StRS-037; SwRS-026
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround (Klartext-Zertifikatspasswort unter Linux ist ein von den Entwicklern selbst dokumentierter Sicherheits-Workaround, kein Zielzustand)
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-035
|
||||
Titel: Automatisierte Ticket-Version-Verknüpfung über Webhook
|
||||
Ebene: SyRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: System (Build-Infrastruktur)
|
||||
Vorbedingung: Ein Build für einen gemergten Pull Request wird erfolgreich abgeschlossen.
|
||||
Fakt: Ein Azure-DevOps-Service-Hook löst bei `Build completed`/`Succeeded` einen HTTP-POST an `DevOpsCentronTicketBridge` aus, der über konfigurierbare reguläre Ausdrücke Ticketnummern aus Titel/Beschreibung des zugehörigen Pull Requests extrahiert und per c-entron-API in die referenzierten Tickets einträgt.
|
||||
Aussage: Das System soll bei jedem erfolgreichen Produktions-Build automatisiert per Webhook erkennen, welche Tickets betroffen sind, und deren Versionsfeld sowie QS-Weiterleitung automatisch aktualisieren.
|
||||
Ergebnis: Kein manueller Schritt zur Ticket-Versions-Pflege nach einem Release erforderlich.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/operations/build-server-and-automated-builds.md (Abschnitte "c-entron Tickets", "Azure DevOps setup") - Begründung: Vollständige technische Beschreibung inkl. konkreter Konfigurationswerte (Webhook-Filter, Regex-Beispiele).
|
||||
Prüfidee: Test-Pull-Request mit Ticketreferenz mergen, Build auslösen und automatischen Ticket-Eintrag verifizieren.
|
||||
Tracelinks: StRS-038; SwRS-026
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## O. Wartung/Datenqualität (zu StRS-041)
|
||||
|
||||
```
|
||||
ID: SyRS-036
|
||||
Titel: Fehlertolerante, sequenzielle Ausführung wiederkehrender Wartungsaufgaben
|
||||
Ebene: SyRS
|
||||
Typ: Zuverlässigkeit (ISO 25010: Fehlertoleranz)
|
||||
Akteur: System
|
||||
Vorbedingung: Der stündliche Wartungszyklus des `DataQualityService` läuft.
|
||||
Fakt: Jede der (mindestens neun) Wartungsaufgaben läuft in einer eigenen, kurzlebigen `BLSession`, ist einzeln in try-catch gekapselt (Fehler werden mit Aufgabennamen geloggt, brechen aber nicht den gesamten Zyklus ab) und prüft nach jeder Aufgabe auf Abbruchanforderung.
|
||||
Aussage: Das System soll jede Wartungsaufgabe des Datenqualitätsdienstes unabhängig von den übrigen Aufgaben ausführen, sodass der Fehlschlag einer einzelnen Aufgabe die übrigen Aufgaben und den nächsten Zyklus nicht verhindert.
|
||||
Ergebnis: Ein Defekt in einer einzelnen Wartungsroutine gefährdet nicht die übrigen Datenqualitätsmaßnahmen.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/Background Service/DataQualityService.md (Abschnitte "Error Handling", "Session Management") - Begründung: Beschreibt Muster inkl. Codebeispiel für Session-Kapselung und Fehlerbehandlung.
|
||||
Prüfidee: Eine Wartungsaufgabe gezielt zum Fehlschlagen bringen (z. B. durch inkonsistente Testdaten) und Fortsetzung der übrigen Aufgaben im selben Zyklus prüfen.
|
||||
Tracelinks: StRS-041; SwRS-027
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## P. API-Architektur, Telemetrie, Mandantenfähigkeit (zu StRS-042..044)
|
||||
|
||||
```
|
||||
ID: SyRS-037
|
||||
Titel: Namensraumbasierte API-Versionierung mit einheitlicher Routing-Konvention
|
||||
Ebene: SyRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: Client-Entwickler (intern/extern)
|
||||
Vorbedingung: Ein neuer API-Endpunkt wird veröffentlicht oder eine bestehende Version weiterentwickelt.
|
||||
Fakt: `RegisterCentronApiVersioning` leitet die API-Version aus dem Controller-Namensraum ab (`Controllers.v1.*`), Standardversion=1; `KebabCaseTransformer` wandelt PascalCase-Routensegmente automatisch in Kebab-Case um (z. B. `special-price-articles`).
|
||||
Aussage: Das System soll die API-Version aus der Namensraumstruktur der Controller ableiten und Routensegmente einheitlich im Kebab-Case-Format bereitstellen.
|
||||
Ergebnis: Konsistente, vorhersagbare URL-Struktur über alle API-Domänen hinweg; neue Versionen sind durch neue Namensräume statt manueller Attributpflege einführbar.
|
||||
Belege:
|
||||
- [PRIMÄR] src/webservice/Centron.Controllers/Configuration/RegisterCentronApiVersioning.cs:9-23 - Begründung: Konkrete Versionierungskonfiguration.
|
||||
- [PRIMÄR] src/webservice/Centron.Controllers/Configuration/Routing/KebabCaseTransformer.cs:6-14 - Begründung: Konkrete Routing-Transformation.
|
||||
Prüfidee: Neuen Controller im Namensraum `Controllers.v2.*` anlegen und automatische Zuordnung zur API-Version 2 ohne weitere Konfiguration prüfen.
|
||||
Tracelinks: StRS-042; SwRS-028
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-038
|
||||
Titel: Offene CORS-Richtlinie ohne Ursprungsbeschränkung
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System
|
||||
Vorbedingung: Ein Browser sendet eine Cross-Origin-Anfrage an die API.
|
||||
Fakt: `CentronHost.cs:266` konfiguriert CORS mit `AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()` — keine Einschränkung auf bekannte Ursprünge.
|
||||
Aussage: Das System erlaubt aktuell Cross-Origin-Anfragen von jedem beliebigen Ursprung ohne Einschränkung.
|
||||
Ergebnis: Beliebige Webanwendungen können clientseitig gegen die API browserbasierte Anfragen stellen; dies erleichtert Drittintegrationen, stellt aber zugleich eine erhöhte Angriffsfläche dar (siehe Prüfidee).
|
||||
Belege:
|
||||
- [PRIMÄR] src/webservice/Centron.Host/CentronHost.cs:168,266 (AddCors, UseCors mit AllowAnyOrigin/AllowAnyHeader/AllowAnyMethod) - Begründung: Direkter, unmissverständlicher Codebeleg.
|
||||
Prüfidee: Cross-Origin-Testanfrage von einer nicht autorisierten Domain senden und erfolgreiche CORS-Freigabe (statt Ablehnung) verifizieren; im Rahmen der Validierung mit Sicherheitsverantwortlichen klären, ob dies beabsichtigt ist.
|
||||
Tracelinks: StRS-042; SwRS-028
|
||||
Konsolidierung: nein
|
||||
Status: belegt; [HYPOTHESE] ob die offene CORS-Konfiguration bewusste Designentscheidung (z. B. für Nexoware-übergreifende Integrationen) oder ein zu härtender Zustand ist, ist im Code nicht dokumentiert — siehe Hypothesen.md H-07.
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-039
|
||||
Titel: Bucket-basierte, batch-hochgeladene Nutzungstelemetrie
|
||||
Ebene: SyRS
|
||||
Typ: Daten
|
||||
Akteur: System
|
||||
Vorbedingung: Eine API-Methode, ein MCP-Tool oder ein KI-Assistenz-Werkzeug wird aufgerufen.
|
||||
Fakt: `TelemetryBL` schreibt Nutzung in zeitlich gebündelte ("gebucketete") Datensätze über `MERGE ... WITH (HOLDLOCK)`-Upserts mit Deadlock-Retry-Logik (bis zu 5 Versuche, SQL-Fehlercodes 1205/2627/2601) und markiert hochgeladene Datensätze über einen separaten Upload-Client.
|
||||
Aussage: Das System soll Nutzungsdaten lokal zeitlich gebündelt (Bucket) und nebenläufigkeitssicher speichern und anschließend gebündelt an einen zentralen Server hochladen.
|
||||
Ergebnis: Nutzungsstatistiken gehen auch unter hoher gleichzeitiger Last nicht durch Datenbank-Deadlocks verloren.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Telemetry/TelemetryBL.cs:36-95,181-276 - Begründung: Konkrete MERGE-Logik und Retry-Mechanismus.
|
||||
Prüfidee: Parallele API-Aufrufe (≥20 gleichzeitig) simulieren und korrekte, verlustfreie Bucket-Aggregation prüfen.
|
||||
Tracelinks: StRS-043; SwRS-029
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-040
|
||||
Titel: Zweistufiges Skalierungsmodell Mandant/Filiale in zentralen Geschäftsobjekten
|
||||
Ebene: SyRS
|
||||
Typ: Daten
|
||||
Akteur: System
|
||||
Vorbedingung: Ein Geschäftsobjekt (Auftrag, Bestand, Nummernkreis) wird angelegt.
|
||||
Fakt: `Mandator`-Entität (rechtliche Einheit) existiert getrennt von `BranchI3D`/Filiale; zentrale Objekte wie `Order` tragen `BranchI3D`, Nummernkreise zusätzlich `MandatorI3D`.
|
||||
Aussage: Das System soll Geschäftsobjekte konsistent auf zwei Ebenen — Mandant und Filiale — referenzierbar machen.
|
||||
Ergebnis: Auswertungen und Berechtigungen können sowohl je Mandant als auch je Filiale erfolgen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/Administration/Company/Mandator.cs - Begründung: Eigenständige Mandanten-Entität.
|
||||
- [PRIMÄR] src/backend/Centron.DAO/Mappings/Sales/CustomerAssets/Orders/OrderMaps.cs:74-75 - Begründung: Filial-Referenzierung auf zentralem Geschäftsobjekt.
|
||||
Prüfidee: Siehe StRS-044.
|
||||
Tracelinks: StRS-044; SwRS-030
|
||||
Konsolidierung: nein
|
||||
Status: belegt; [HYPOTHESE] durchgängige Filterung aller DAO-Abfragen nach Mandant/Filiale nicht vollständig verifiziert, siehe Hypothesen.md H-06.
|
||||
```
|
||||
|
||||
## Q. Architekturmuster, Lokalisierung, Betriebsgrenzen (zu StRS-039, StRS-040, StRS-042, StRS-045)
|
||||
|
||||
```
|
||||
ID: SyRS-041
|
||||
Titel: Verpflichtender Dual-Implementierungsvertrag je Fachmodul (ILogic)
|
||||
Ebene: SyRS
|
||||
Typ: Wartbarkeit
|
||||
Akteur: NEXOWARE-Entwickler
|
||||
Vorbedingung: Ein neues Fachmodul im WPF-Client wird implementiert.
|
||||
Fakt: Jedes Modul muss laut Entwicklerkonvention ein `ILogic`-Interface sowie eine `BL*Logic`- (Direktverbindung) und eine `WS*Logic`-Implementierung (Web-Service) bereitstellen; `ClassContainer` löst die passende Implementierung anhand des konfigurierten `CentronConnectionType` auf.
|
||||
Aussage: Das System soll für jedes Fachmodul erzwingen (durch Konvention/Registrierung), dass sowohl eine Direktverbindungs- als auch eine Web-Service-Implementierung desselben Interfaces existiert.
|
||||
Ergebnis: Kein Modul funktioniert nur in einer der beiden Betriebsarten.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/getting-started/general-structure.md (Abschnitt "Dual Implementation Architecture", Punkt 2 "Implementation Guidelines") - Begründung: Explizite Verpflichtung ("MUST implement both") inkl. Namenskonvention.
|
||||
Prüfidee: Neues Modul ohne eine der beiden Implementierungen registrieren und Fehlverhalten/Registrierungsfehler beim Start prüfen.
|
||||
Tracelinks: StRS-039; SwRS-031
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-042
|
||||
Titel: Kulturabhängige Ressourcenauflösung für UI- und Fehlertexte
|
||||
Ebene: SyRS
|
||||
Typ: Übertragbarkeit (Internationalisierbarkeit)
|
||||
Akteur: System
|
||||
Vorbedingung: Ein UI-Text oder eine Fehlermeldung wird angezeigt bzw. eine Web-Service-Antwort wird zurückgegeben.
|
||||
Fakt: Jede Assembly mit UI-relevanten Texten führt Ressourcendateien `LocalizedStrings.resx` (Deutsch, Standard) und `LocalizedStrings.en.resx` (Englisch); die Sprache wird aus `CultureInfo.CurrentUICulture` bzw. dem HTTP-Header `Accept-Language` bestimmt.
|
||||
Aussage: Das System soll UI- und Fehlertexte anhand der aktuellen Kultureinstellung des Clients bzw. eines übermittelten Sprachheaders aus vordefinierten Ressourcendateien auflösen.
|
||||
Ergebnis: Neue Sprachen können durch Ergänzung weiterer Ressourcendateien unterstützt werden, ohne Code zu ändern.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/guides/ui/localization.md (Abschnitte "Resource Files Structure", "Get localized strings through Web-Service call") - Begründung: Beschreibt Ressourcenstruktur und HTTP-Header-Mechanismus im Detail.
|
||||
Prüfidee: Web-Service-Aufruf mit `Accept-Language: en-US` senden und englische statt deutsche Fehlermeldung prüfen.
|
||||
Tracelinks: StRS-040; SwRS-032
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-043
|
||||
Titel: Fehlende serverseitige Anfragebegrenzung bei gleichzeitig sehr langen Timeouts
|
||||
Ebene: SyRS
|
||||
Typ: Zuverlässigkeit / Sicherheit (ISO 25010: Verfügbarkeit, Missbrauchsresistenz)
|
||||
Akteur: System
|
||||
Vorbedingung: Der Web-Service verarbeitet eingehende HTTP-Anfragen.
|
||||
Fakt: `CentronHost.cs` konfiguriert `MaxRequestBodySize = null` (unbegrenzt), `IdleConnection`/`RequestQueue`-Timeout von 30 Minuten (Windows/HttpSys) bzw. `KeepAliveTimeout` von 30 Minuten (Linux/Kestrel); im gesamten `src/webservice`- und `src/nexus`-Code wurde keine Rate-Limiting-Middleware (`AddRateLimiter`, `[EnableRateLimiting]`) gefunden.
|
||||
Aussage: Das System soll die Anzahl bzw. Rate eingehender Anfragen pro Client begrenzen können, insbesondere in Kombination mit unbegrenzter Anfragegröße und sehr langen Verbindungs-Timeouts.
|
||||
Ergebnis: Aktuell besteht kein serverseitiger Schutz gegen exzessive parallele oder wiederholte Anfragen eines einzelnen Clients auf API-Ebene.
|
||||
Belege:
|
||||
- [PRIMÄR] src/webservice/Centron.Host/CentronHost.cs:116-150 - Begründung: Konkrete, unbegrenzte Body-Size- und lange Timeout-Konfiguration.
|
||||
- [KONTEXT] Repository-weite Suche nach `RateLimit`/`EnableRateLimiting` (Subagent-Recherche) - Begründung: Keine Treffer außerhalb von NuGet-Build-Caches; Abwesenheitsbeleg, kein abschließender Beweis für Gesamtsystem.
|
||||
Prüfidee: Lasttest mit sehr vielen parallelen/wiederholten Anfragen eines einzelnen Clients durchführen und Verhalten (Drosselung ja/nein) beobachten.
|
||||
Tracelinks: StRS-042; SwRS-033
|
||||
Konsolidierung: nein
|
||||
Status: belegt; [HYPOTHESE] ob Rate-Limiting auf einer vorgelagerten Infrastrukturebene (Reverse Proxy/API-Gateway) außerhalb des Repositories erfolgt, konnte nicht geprüft werden — siehe Hypothesen.md H-08.
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-044
|
||||
Titel: Unzureichende kryptographische Stärke der Passwort-Hash-Funktion
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System
|
||||
Vorbedingung: Ein Passwort wird bei Registrierung/Änderung gehasht oder bei Login verglichen.
|
||||
Fakt: `BasicAuthenticator` verwendet `SHA1Decoder.GetDecodedSHA1String(...)` ohne erkennbares, individuelles Salt pro Benutzer; SHA-1 gilt kryptographisch als gebrochen/veraltet für Passwort-Hashing (branchenüblicher Konsens, nicht separat im Repository dokumentiert).
|
||||
Aussage: Das System soll für die Passwort-Hash-Bildung ein für Passwörter geeignetes, salted und rechenintensives Verfahren (z. B. bcrypt/Argon2/PBKDF2) verwenden statt eines einzelnen, ungesalzenen SHA-1-Hashs.
|
||||
Ergebnis: Ein Offline-Angriff auf entwendete Passwort-Hashes wird signifikant erschwert.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Logins/Auth/BasicAuthenticator.cs:46-48 - Begründung: Direkter Code-/Kommentarbeleg, siehe StRS-045.
|
||||
Prüfidee: Siehe StRS-045.
|
||||
Tracelinks: StRS-045; SwRS-034
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround
|
||||
```
|
||||
|
||||
+198
@@ -0,0 +1,198 @@
|
||||
# Messprotokoll – V1 Baseline (Prompt-only) – Iteration 01, Lauf 2 (ABGEBROCHEN)
|
||||
|
||||
> **Status: Lauf unvollständig.** Der Headless-Lauf brach nach 24:08 mit einem API-Fehler ab.
|
||||
> Es liegen 4 von 7 geforderten Ergebnisdateien vor. Die Messwerte unten sind vollständig
|
||||
> erfasst, beziehen sich aber auf einen **abgebrochenen** Lauf und sind nicht mit einem
|
||||
> vollständigen Lauf vergleichbar.
|
||||
|
||||
## Lauf
|
||||
- **Prompt-Datei:** `Versuche/Versuch_01/01_Prompt.md`
|
||||
- **SHA-256 (Prompt):** `1B0DB06B8E0A5B92A5EFBDBEC5A0C554351FC928A16AEF34AAD9EAA0893C02FF`
|
||||
(identisch zu Lauf 1 – der Prompt wurde nicht verändert)
|
||||
- **Startzeit:** 2026-08-25T13:49:05.7854277+02:00
|
||||
- **Endzeit:** 2026-08-25T14:20:29.6392629+02:00
|
||||
- **Dauer gesamt:** 00:31:24 (Wanduhr) bzw. 00:24:08 (`duration_ms`) — API: 00:49:57 (`duration_api_ms`)
|
||||
- Die API-Dauer übersteigt die Wanduhrzeit, weil 6 Subagenten nebenläufig liefen.
|
||||
- **Root-Verzeichnis:** `c:\DEV\MasterArbeit\QuellCode\CentronERP`
|
||||
- **Codebasis-Commit:** `79c1142f489a32ba6a4a4cb043fd7f8550a9f257` (dirty: nein)
|
||||
- **Snapshot-Zustand:** bereinigt von KI-Konfigurationen: **ja** (Prüfung vor dem Lauf: 0 Treffer);
|
||||
Remote entkoppelt: **ja** (`git remote` leer)
|
||||
- **Prompt-Repo-Commit:** `0ec86aed8cb8781054c86cbe0dd9f5eb0f7e5f05`
|
||||
|
||||
## Werkzeugkonfiguration
|
||||
- **Laufverzeichnis-ID:** `v2.0.0-8b0a`
|
||||
- **Ablage:** `claude-sonnet-5/builtin/high/`
|
||||
- **Parallele Läufe:** nein
|
||||
- **Skill-Version:** `2.0.0` (Shell-Zugriff + Denylist, Isolation über eingefrorenen Snapshot)
|
||||
- **Claude-Code-Version:** 2.1.245
|
||||
- **CLI-Pfad:** `C:\Users\ChristophSchwoerer\.vscode\extensions\anthropic.claude-code-2.1.245-win32-x64\resources\native-binary\claude.exe`
|
||||
- **Effort:** `high` — **nicht zur Laufzeit gesetzt**, sondern aus der Sitzung geerbt und
|
||||
nachtraeglich aus dem Session-Transkript rekonstruiert (100 Nachrichten, durchgaengig `high`).
|
||||
`RawResult.json` enthaelt kein `effort`-Feld. Ab Skill-Version 3.4.0 wird der Wert per
|
||||
`--effort` explizit gesetzt.
|
||||
- **Modell:** `claude-sonnet-5` (explizit gesetzt); zusätzlich `claude-haiku-4-5-20251001`
|
||||
für interne Hilfsaufrufe (4.176 Input-/26 Output-Tokens)
|
||||
- **Permission-Mode:** `acceptEdits`
|
||||
- **Toolfreigabe:**
|
||||
- `--allowedTools "Bash" "PowerShell"`
|
||||
- `--disallowedTools` mit 33 Einträgen: 22 × `Bash(...)` und 11 × `PowerShell(...)` für
|
||||
schreibende Kommandos (`rm`, `rmdir`, `mv`, `cp`, `dd`, `truncate`, `chmod`, `chown`, `ln`,
|
||||
`tee`, `sed -i`, `Remove-Item`, `Move-Item`, `Copy-Item`, `New-Item`, `Set-Content`,
|
||||
`Add-Content`, `Clear-Content`, `Out-File`, `Set-ItemProperty`), Git-Mutationen
|
||||
(`checkout`, `restore`, `clean`, `reset`, `add`, `commit`, `push`) und Build-Werkzeuge
|
||||
(`dotnet`, `msbuild`, `nuget`, `npm install`)
|
||||
- **Isolationsmechanismus:** eingefrorener Codebasis-Snapshot ohne KI-Konfigurationen,
|
||||
zusätzlich `--safe-mode` und `--strict-mcp-config`
|
||||
- **MCP-Server / Agentendateien:** keine – aus dem Snapshot entfernt, zusätzlich `--safe-mode`
|
||||
- **Subagenten:** 6 × `general-purpose` (alle im Hintergrund gestartet, max. Tiefe 1,
|
||||
6 abgeschlossen, 0 fehlgeschlagen)
|
||||
- **Fast-Mode:** aus
|
||||
|
||||
## Verbrauch
|
||||
|
||||
### Hauptagent (`usage`)
|
||||
| Messgröße | Wert |
|
||||
|---|---|
|
||||
| Input-Tokens | 10 |
|
||||
| Output-Tokens | 81.610 (davon 13.370 Thinking-Tokens) |
|
||||
| Cache-Write-Tokens | 86.138 (vollständig 1h-ephemeral) |
|
||||
| Cache-Read-Tokens | 1.369.720 |
|
||||
| Agent-Turns | 8 |
|
||||
|
||||
### Gesamtlauf inkl. Subagenten (`modelUsage`, abrechnungsrelevant)
|
||||
| Messgröße | `claude-sonnet-5` | `claude-haiku-4-5-20251001` | Summe |
|
||||
|---|---:|---:|---:|
|
||||
| Input-Tokens | 364 | 4.176 | 4.540 |
|
||||
| Output-Tokens | 226.587 | 26 | 226.613 |
|
||||
| Cache-Write-Tokens | 805.842 | 0 | 805.842 |
|
||||
| Cache-Read-Tokens | 15.618.130 | 0 | 15.618.130 |
|
||||
| Tokens gesamt | 16.650.923 | 4.202 | **16.655.125** |
|
||||
|
||||
**Tokens gesamt: 16.655.125** (Summe aus Input, Output, Cache-Write und Cache-Read ueber alle Modelle; `total_cost_usd` steht weiterhin in `RawResult.json`)
|
||||
|
||||
## Ergebnis
|
||||
- **Status:** **Fehler.** `is_error: true`, `terminal_reason: "api_error"`,
|
||||
`stop_reason: "stop_sequence"`, `api_error_status: null`, Exit-Code 1.
|
||||
Abschlusstext des Agenten wörtlich:
|
||||
`API Error: The response stopped arriving. The response above may be incomplete.`
|
||||
`Stderr.log` ist leer (0 Byte) – die CLI hat keine zusätzliche Diagnose ausgegeben.
|
||||
Das Feld `subtype` steht auf `success` und widerspricht damit `is_error: true`;
|
||||
maßgeblich sind `is_error` und `terminal_reason`.
|
||||
- **Session-ID:** `46eee72a-c498-4572-a51e-b29ac39a180e`
|
||||
(Transkript persistiert, 1.504.499 Byte – eine Fortsetzung per `--resume` ist technisch möglich)
|
||||
- **Permission-Denials:** **0.** Die neue Werkzeugkonfiguration hat den Lauf zu keinem Zeitpunkt
|
||||
eingeschränkt; der Abbruch hat keinen Bezug zu Berechtigungen.
|
||||
- **Erzeugte Dateien:** 4 von 7
|
||||
|
||||
| Datei | Größe | Zeitstempel | Inhalt |
|
||||
|---|---:|---|---|
|
||||
| `Glossar.md` | 8.309 B | 13:53 | Domänenbegriffe |
|
||||
| `Analysebericht.md` | 6.292 B | 13:55 | **als ENTWURF markiert**, nicht finalisiert |
|
||||
| `StRS.md` | 74.069 B | 14:09 | 45 Anforderungen |
|
||||
| `SyRS.md` | 58.925 B | 14:10 | 44 Anforderungen |
|
||||
|
||||
**Fehlend:** `SwRS.md`, `Traceability.md`, `Hypothesen.md`.
|
||||
Der Abbruch erfolgte nach `SyRS.md` (14:10) und vor Fertigstellung der SwRS-Ebene.
|
||||
- **Root unverändert:** ja. `git status --porcelain` nach dem Lauf ist leer, HEAD unverändert
|
||||
`79c1142`. Der Lauf hat trotz voller Shell-Freigabe keine Datei der Codebasis angelegt,
|
||||
geändert oder gelöscht.
|
||||
|
||||
## Gefundene Anforderungen
|
||||
|
||||
Maschinell aus `Ergebnisse\StRS.md`, `SyRS.md` und `SwRS.md` ausgewertet (Blockformat des Prompts). Erzeugt von `analyse-anforderungen.py`.
|
||||
|
||||
### Verteilung über die Ebenen
|
||||
|
||||
| Ebene | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| StRS | 45 | 50,6 % |
|
||||
| SyRS | 44 | 49,4 % |
|
||||
| SwRS | 0 | 0,0 % |
|
||||
| **Gesamt** | **89** | 100 % |
|
||||
|
||||
### Anforderungstypen
|
||||
|
||||
| Typ | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| funktional | 33 | 37,1 % |
|
||||
| Sicherheit | 22 | 24,7 % |
|
||||
| Daten | 9 | 10,1 % |
|
||||
| Schnittstelle | 9 | 10,1 % |
|
||||
| nicht-funktional | 6 | 6,7 % |
|
||||
| Zuverlässigkeit (ISO 25010: Fehlertoleranz) | 3 | 3,4 % |
|
||||
| Übertragbarkeit | 2 | 2,2 % |
|
||||
| nicht-funktional (Zuverlässigkeit, ISO 25010: Fehlertoleranz) | 1 | 1,1 % |
|
||||
| Performance-Effizienz | 1 | 1,1 % |
|
||||
| Wartbarkeit | 1 | 1,1 % |
|
||||
| (2 weitere) | 2 | 2,2 % |
|
||||
|
||||
### Belegqualität
|
||||
|
||||
| Messgröße | Wert |
|
||||
|---|---:|
|
||||
| Belege gesamt | 149 |
|
||||
| davon `PRIMÄR` | 125 (83,9 %) |
|
||||
| davon `SEKUNDÄR` | 20 (13,4 %) |
|
||||
| davon `KONTEXT` | 4 (2,7 %) |
|
||||
| Belege je Anforderung (Median) | 1 |
|
||||
| Anforderungen mit mindestens einem `PRIMÄR`-Beleg | 89 (100,0 %) |
|
||||
|
||||
### Status
|
||||
|
||||
| Kategorie | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| belegt | 78 | 87,6 % |
|
||||
| als `HYPOTHESE` gekennzeichnet | 11 | 12,4 % |
|
||||
| als Workaround vermerkt | 5 | 5,6 % |
|
||||
| Konsolidierungskandidaten | 8 | 9,0 % |
|
||||
| mit ISO-25010-Qualitätsmerkmal | 0 | 0,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** (34 risikorelevante Anforderungen, alle gedeckt) |
|
||||
| **Verifizierbarkeit** – jede Anforderung mit Prüfidee oder Akzeptanzkriterium | **erfüllt** |
|
||||
| **Traceability** – Verknüpfung zwischen den Ebenen | 89 von 89 mit Tracelinks (100,0 %) |
|
||||
|
||||
## Anmerkungen/Auffälligkeiten
|
||||
|
||||
1. **Abbruchursache: API-Transportfehler, keine Konfigurationsfrage.** Die Antwort des Modells
|
||||
hörte auf einzutreffen (`terminal_reason: "api_error"`). Weder die Toolfreigabe noch die
|
||||
Denylist noch die Isolation waren beteiligt – `permission_denials` ist 0 und `Stderr.log` leer.
|
||||
Es handelt sich um einen Infrastrukturfehler, der eine Wiederholung erfordert.
|
||||
|
||||
2. **Die neue Werkzeugkonfiguration hat funktioniert.** Gegenüber Lauf 1 (36 Denials) traten
|
||||
**0 Denials** auf. Der Agent konnte Shell-gestützt inventarisieren und weist im
|
||||
`Analysebericht.md` erstmals eine statische Auszählung aus: 22.346 Dateien unter `src/`,
|
||||
davon 15.554 `.cs`, 1.233 `.xaml`, 491 `.razor`. In Lauf 1 fehlten solche Zahlen.
|
||||
|
||||
3. **Höhere Anforderungsdichte bis zum Abbruch.** Die beiden fertiggestellten Ebenen enthalten
|
||||
mehr Anforderungen als im vollständigen Lauf 1: StRS 45 gegenüber 28, SyRS 44 gegenüber 28.
|
||||
Auch die Dateigrößen liegen deutlich höher (StRS 74,1 KB gegenüber 45,7 KB; SyRS 58,9 KB
|
||||
gegenüber 40,8 KB). Ein belastbarer Vergleich ist erst nach einem vollständigen Lauf möglich.
|
||||
|
||||
4. **Anderer Subagenten-Typ.** Lauf 2 nutzte 6 × `general-purpose` (im Hintergrund gestartet),
|
||||
Lauf 1 dagegen 8 × `Explore` (Vordergrund). Der Prompt war identisch; die Wahl des
|
||||
Subagenten-Typs ist damit keine Konstante der Versuchsanordnung und bei der Interpretation
|
||||
von Laufzeit- und Kostenunterschieden zu berücksichtigen.
|
||||
|
||||
5. **Kosten trotz Abbruch nahezu identisch zum vollständigen Lauf 1:** 16.655.125 Tokens gegenüber
|
||||
13.052.010 Tokens. Die Cache-Read-Tokens liegen mit 15,62 Mio. sogar über Lauf 1 (11,96 Mio.).
|
||||
|
||||
6. **Beobachtung des Agenten zum Snapshot:** Im `Analysebericht.md` vermerkt er, dass
|
||||
`docs/getting-started/ai-codebase-navigation.md` noch auf die im Commit `79c1142` entfernten
|
||||
Dateien (`.claude/`, `CLAUDE.md`, `.cursor/`) verweist. Der Verweis ist inhaltlich folgenlos,
|
||||
dokumentiert aber, dass der Snapshot-Eingriff im Repository nachvollziehbare Spuren
|
||||
hinterlässt.
|
||||
|
||||
7. **Werkzeugfehler im Skill entdeckt und behoben:** Die Sicherung `before.txt` wurde per
|
||||
`git status --porcelain | Set-Content` erzeugt. Ist die Pipeline leer (sauberes Root),
|
||||
schreibt `Set-Content` die Datei **nicht** und lässt den alten Inhalt stehen. Dadurch enthielt
|
||||
`before.txt` noch die 92 Löschzeilen aus Lauf 1, und der Vorher/Nachher-Vergleich meldete
|
||||
fälschlich eine Abweichung. Die Kontrolle wurde unabhängig per direktem
|
||||
`git status --porcelain` (leer) und `git rev-parse HEAD` (`79c1142`) wiederholt – das Root ist
|
||||
unverändert. Der Skill wurde auf eine leerwertsichere Variante umgestellt.
|
||||
|
||||
8. **Manuelle Eingriffe während des Laufs:** keine.
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"is_error":true,"duration_api_ms":2996847,"num_turns":8,"stop_reason":"stop_sequence","session_id":"46eee72a-c498-4572-a51e-b29ac39a180e","total_cost_usd":7.839986,"usage":{"input_tokens":10,"cache_creation_input_tokens":86138,"cache_read_input_tokens":1369720,"output_tokens":81610,"output_tokens_details":{"thinking_tokens":13370},"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":86138,"ephemeral_5m_input_tokens":0},"inference_geo":"not_available","iterations":[{"input_tokens":2,"output_tokens":3377,"cache_read_input_tokens":316766,"cache_creation_input_tokens":5403,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":5403},"type":"message"}],"speed":"standard"},"modelUsage":{"claude-haiku-4-5-20251001":{"inputTokens":4176,"outputTokens":26,"cacheReadInputTokens":0,"cacheCreationInputTokens":0,"webSearchRequests":0,"costUSD":0.004306,"contextWindow":200000,"maxOutputTokens":32000,"canonicalModel":"claude-haiku-4-5","provider":"firstParty"},"claude-sonnet-5":{"inputTokens":364,"outputTokens":226587,"cacheReadInputTokens":15618130,"cacheCreationInputTokens":805842,"webSearchRequests":0,"costUSD":7.83568,"contextWindow":1000000,"maxOutputTokens":64000,"canonicalModel":"claude-sonnet-5","provider":"firstParty"}},"permission_denials":[],"terminal_reason":"api_error","fast_mode_state":"off","fast_mode_disabled_reason":"extra_usage_disabled","origin":{"kind":"task-notification"},"subagent_stats":{"spawned":6,"requested":{"background":0,"foreground":0,"unset":6},"started_in_background":6,"max_depth":1,"spawned_by_subagents":0,"completed":6,"failed":0,"killed":{"parent":0,"user":0,"system":0},"refused":{"depth_limit":0,"concurrency_limit":0,"budget":0},"by_type":{"general-purpose":6}},"subtype":"success","api_error_status":null,"result":"API Error: The response stopped arriving. The response above may be incomplete.","type":"result","duration_ms":1447523,"uuid":"4a8486c6-43ee-4c77-9ba1-c2ff508e801d","queued_turn_count":0}
|
||||
+1486
File diff suppressed because it is too large
Load Diff
+59
@@ -0,0 +1,59 @@
|
||||
## Gefundene Anforderungen
|
||||
|
||||
Maschinell aus `Ergebnisse\StRS.md`, `SyRS.md` und `SwRS.md` ausgewertet (Blockformat des Prompts). Erzeugt von `analyse-anforderungen.py`.
|
||||
|
||||
### Verteilung über die Ebenen
|
||||
|
||||
| Ebene | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| StRS | 45 | 50,6 % |
|
||||
| SyRS | 44 | 49,4 % |
|
||||
| SwRS | 0 | 0,0 % |
|
||||
| **Gesamt** | **89** | 100 % |
|
||||
|
||||
### Anforderungstypen
|
||||
|
||||
| Typ | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| funktional | 33 | 37,1 % |
|
||||
| Sicherheit | 22 | 24,7 % |
|
||||
| Daten | 9 | 10,1 % |
|
||||
| Schnittstelle | 9 | 10,1 % |
|
||||
| nicht-funktional | 6 | 6,7 % |
|
||||
| Zuverlässigkeit (ISO 25010: Fehlertoleranz) | 3 | 3,4 % |
|
||||
| Übertragbarkeit | 2 | 2,2 % |
|
||||
| nicht-funktional (Zuverlässigkeit, ISO 25010: Fehlertoleranz) | 1 | 1,1 % |
|
||||
| Performance-Effizienz | 1 | 1,1 % |
|
||||
| Wartbarkeit | 1 | 1,1 % |
|
||||
| (2 weitere) | 2 | 2,2 % |
|
||||
|
||||
### Belegqualität
|
||||
|
||||
| Messgröße | Wert |
|
||||
|---|---:|
|
||||
| Belege gesamt | 149 |
|
||||
| davon `PRIMÄR` | 125 (83,9 %) |
|
||||
| davon `SEKUNDÄR` | 20 (13,4 %) |
|
||||
| davon `KONTEXT` | 4 (2,7 %) |
|
||||
| Belege je Anforderung (Median) | 1 |
|
||||
| Anforderungen mit mindestens einem `PRIMÄR`-Beleg | 89 (100,0 %) |
|
||||
|
||||
### Status
|
||||
|
||||
| Kategorie | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| belegt | 78 | 87,6 % |
|
||||
| als `HYPOTHESE` gekennzeichnet | 11 | 12,4 % |
|
||||
| als Workaround vermerkt | 5 | 5,6 % |
|
||||
| Konsolidierungskandidaten | 8 | 9,0 % |
|
||||
| mit ISO-25010-Qualitätsmerkmal | 0 | 0,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** (34 risikorelevante Anforderungen, alle gedeckt) |
|
||||
| **Verifizierbarkeit** – jede Anforderung mit Prüfidee oder Akzeptanzkriterium | **erfüllt** |
|
||||
| **Traceability** – Verknüpfung zwischen den Ebenen | 89 von 89 mit Tracelinks (100,0 %) |
|
||||
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
[
|
||||
{
|
||||
"id": "toolu_01LtGmoAa9pyj5dVZeE9K8tZ",
|
||||
"werkzeug": "Agent",
|
||||
"subagent_type": "general-purpose",
|
||||
"description": "Survey security & rights model",
|
||||
"run_in_background": null,
|
||||
"model": null,
|
||||
"prompt": "You are gathering EVIDENCE for a Reverse Requirements Engineering effort on the c-entron ERP codebase at C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP. Do NOT write requirements text, do NOT modify any files — this is read-only research. Your output will be used by another process to write ISO/IEC/IEEE 29148 requirements, so it must be precise, evidence-cited (exact file path + class/method/line), and separate raw facts from any interpretation.\n\nFocus area: the authorization / user-rights model.\n\nInvestigate:\n1. src/backend/Centron.BL/Security — what classes/services exist, how are rights checked at runtime (e.g. a method like HasRight(...)), how are rights structured (hierarchical constants, per-branch/per-department restrictions)?\n2. Find the actual \"UserRightsConst\" class/file(s) (likely in Centron.Common or Centron.Entities or Centron.BL) — report its structure/organization (roughly how many rights, how organized into categories) and a handful of concrete representative examples with full constant names.\n3. Read CentronRights.md at the repo root fully (already partially known: documents Helpdesk, Kalender, Mitarbeiterauslastung rights) — note it's a partial doc; check if there are other *.md rights docs elsewhere.\n4. Find where authentication happens (login flow) — for the WPF client and for the webservice/Controllers (src/webservice/Centron.Controllers/Authorization). What auth mechanism is used (session token, JWT, Windows auth, 2FA)? Look at src/backend/Centron.BL/TwoFactorAuthenticator too.\n5. Find examples of \"restricting rights\" implemented in code (a right that filters a list to \"only own\" or \"only own branch\") — cite 2-3 concrete code locations showing the actual filter logic (e.g. LINQ where clause or SQL WHERE referencing a UserId/BranchId).\n6. Look for role/group concepts (is there a \"role\" entity distinct from individual rights, and how are rights assigned to users — directly, via groups, via roles)?\n7. Any password policy / account lockout / session timeout logic (PasswordManagementArea, PasswordManager folders)?\n\nFor each fact, report: exact file path, class/method name (with line number if feasible), a short verbatim or near-verbatim code/text excerpt, and classify it as PRIMÄR (enforced rule in code/DB constraint), SEKUNDÄR (UI label, config, mapping), or KONTEXT (comment/doc/commit). Flag anything you could not verify as UNCLEAR.\n\nReport back in a structured list, organized by the 7 numbered topics above. Be thorough — read actual file contents, don't guess from names. Target ~800-1500 words of dense factual findings.",
|
||||
"ergebnis_zeichen": 1093
|
||||
},
|
||||
{
|
||||
"id": "toolu_01Uf2tDybxNBkfuhXMenQoks",
|
||||
"werkzeug": "Agent",
|
||||
"subagent_type": "general-purpose",
|
||||
"description": "Survey billing/invoicing/accounting logic",
|
||||
"run_in_background": null,
|
||||
"model": null,
|
||||
"prompt": "You are gathering EVIDENCE for a Reverse Requirements Engineering effort on the c-entron ERP codebase at C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP. Do NOT write requirements text, do NOT modify any files — read-only research only. Output must be precise, evidence-cited (exact file path + class/method, line numbers where feasible), separating raw fact from interpretation.\n\nFocus area: billing / invoicing / accounting (Fakturierung, Rechnung, Zahlung, Buchhaltung).\n\nInvestigate:\n1. src/backend/Centron.BL/Accounting and src/backend/Centron.BL/Finances — list the main classes/services and what they do (invoice creation, payment booking, dunning/Mahnwesen, VAT/tax handling, currency).\n2. src/backend/Centron.BL/VoucherManagement — what is a \"Voucher\" here (receipt/document type)? How does status progress (draft -> booked -> paid -> cancelled etc)? Find an actual status enum (e.g. VoucherStatus or similar) with its values, and find the code that enforces valid transitions (state machine / guard checks, e.g. \"cannot edit a booked invoice\").\n3. Look for entities in src/backend/Centron.Entities relevant to invoices/orders/receipts (e.g. Rechnung, Auftrag, Beleg, Voucher) — report field names relevant to money (amounts, tax rates, currency) and any DB-level constraints visible (e.g. Required attributes, foreign keys, check constraints) in the entity classes or any .edmx/mapping files.\n4. Find numbering-scheme logic for invoices (Rechnungsnummer / sequential numbering) — is there a class enforcing unique, gapless, or year-based numbering? This is often legally required (GoBD in Germany) — look for related comments.\n5. Find validation logic before finalizing/\"printing\"/\"booking\" an invoice (e.g. required fields, credit limit checks, permission checks referencing UserRightsConst for Accounting/Finances rights).\n6. Look at the recent commit \"feat: added rights check for editing invoice or delivery list date in the settings of timer billing\" (git log) — find the actual changed files/code to understand this specific business rule about editing invoice/delivery-list dates and the associated right.\n7. Any interfaces to external accounting/payment systems (e.g. src/apis/Centron.APIs.FinAPI, EDI folder, EbInterface API for e-invoicing) — what do they do at a high level?\n\nFor each fact: exact file path, class/method, short excerpt, classification PRIMÄR/SEKUNDÄR/KONTEXT, and flag UNCLEAR items. Read actual file contents, don't guess from names. Target ~1000-1800 words of dense factual findings, organized by the 7 topics.",
|
||||
"ergebnis_zeichen": 1093
|
||||
},
|
||||
{
|
||||
"id": "toolu_01L9ZUv5JiL5XWnNwcufSW3U",
|
||||
"werkzeug": "Agent",
|
||||
"subagent_type": "general-purpose",
|
||||
"description": "Survey sales order lifecycle and CRM",
|
||||
"run_in_background": null,
|
||||
"model": null,
|
||||
"prompt": "You are gathering EVIDENCE for a Reverse Requirements Engineering effort on the c-entron ERP codebase at C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP. Do NOT write requirements text, do NOT modify any files — read-only research only. Output must be precise, evidence-cited (exact file path + class/method, line numbers where feasible), separating raw fact from interpretation.\n\nFocus area: Sales / Order-to-cash process and Customer/CRM (BusinessPartner).\n\nInvestigate:\n1. src/backend/Centron.BL/Sales — list main subfolders/classes. Find the core \"Auftrag\"/order object's lifecycle: locate a status enum (e.g. OrderStatus/AuftragStatus) with its values, and the code enforcing valid status transitions (a state machine, switch statement, or guard method).\n2. src/backend/Centron.BL/BusinessPartner — what is a BusinessPartner (customer/supplier/both)? What are the main sub-entities (contacts, addresses, special prices \"Sonderpreise\" mentioned in README, credit limits)? Look for validation rules (e.g. required fields, duplicate detection).\n3. Find how quotations/offers (\"Angebot\") relate to orders — is there a conversion process (Angebot -> Auftrag)? Cite code.\n4. Find delivery/shipment logic (Lieferschein / delivery list) — connects to src/apis/Centron.Api.Gls, Centron.Api.Shipcloud shipping integrations. What triggers a shipment, what status does it set on the order?\n5. Look at recent commits related to \"C-Sign\" (WebOffer & Acceptance, ticket 168496 & 169060) — find the actual code for electronic signing of offers, understand what business process this represents (customer digitally accepts/signs a web-based offer). Cite files.\n6. Find the Helpdesk domain (src/backend/Centron.BL/... helpdesk related, also cross-check CentronRights.md content already known) — is Helpdesk part of Sales/CustomerArea? What's a \"Ticket\" status lifecycle?\n7. Any product/article catalog logic worth noting (ProductMatrix folder) — briefly, what does it do?\n\nFor each fact: exact file path, class/method, short excerpt, classification PRIMÄR/SEKUNDÄR/KONTEXT, flag UNCLEAR items. Read actual file contents, don't guess from names alone. Target ~1200-1800 words of dense factual findings organized by the 7 topics.",
|
||||
"ergebnis_zeichen": 1093
|
||||
},
|
||||
{
|
||||
"id": "toolu_0192J98jM7xPFAej2ppjypYF",
|
||||
"werkzeug": "Agent",
|
||||
"subagent_type": "general-purpose",
|
||||
"description": "Survey purchasing, warehousing, logistics",
|
||||
"run_in_background": null,
|
||||
"model": null,
|
||||
"prompt": "You are gathering EVIDENCE for a Reverse Requirements Engineering effort on the c-entron ERP codebase at C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP. Do NOT write requirements text, do NOT modify any files — read-only research only. Output must be precise, evidence-cited (exact file path + class/method, line numbers where feasible), separating raw fact from interpretation.\n\nFocus area: Purchasing (Einkauf), Warehousing (Lager), Logistics.\n\nInvestigate:\n1. src/backend/Centron.BL/Buying (or Purchasing) — main classes: purchase order lifecycle, supplier (\"Lieferant\") handling, find a status enum if present with its values and transition logic.\n2. src/backend/Centron.BL/Warehousing — stock/inventory management: find how stock levels are tracked (a \"Bestand\" or \"Stock\" concept), find booking/movement logic (goods receipt \"Wareneingang\", goods issue), and any validation preventing negative stock or similar business rule enforced in code.\n3. src/backend/Centron.BL/Logistics — what does this cover distinctly from Warehousing (shipping, tours, routes)?\n4. src/backend/Centron.BL/TradePool — what is this (looks like a distinctive c-entron concept, maybe pooled/shared trading inventory between dealers)? Investigate and explain based on code/comments.\n5. Look at src/apis/* external data-access integrations: Centron.APIs.CopDataAccess, Centron.APIs.EgisDataAccess, Centron.APIs.ITscopeDataAccess, Centron.APIs.IcecatDataAccess — briefly identify what external systems/catalogs these integrate (likely wholesaler/distributor product data and pricing feeds for the IT/electronics trade). Cite a representative class/method per API.\n6. src/backend/Centron.BL/EDI — what EDI processes exist (electronic data interchange with suppliers, likely order/invoice exchange)? Cite concrete classes.\n7. Find any DB-level or code-level constraints tied to stock/quantity fields in src/backend/Centron.Entities (e.g. non-negative constraints, required warehouse references).\n\nFor each fact: exact file path, class/method, short excerpt, classification PRIMÄR/SEKUNDÄR/KONTEXT, flag UNCLEAR items. Read actual file contents, don't guess from names alone. Target ~1200-1800 words of dense factual findings organized by the 7 topics.",
|
||||
"ergebnis_zeichen": 1093
|
||||
},
|
||||
{
|
||||
"id": "toolu_01UjCMWRfusUhbaz2yYbj7Ak",
|
||||
"werkzeug": "Agent",
|
||||
"subagent_type": "general-purpose",
|
||||
"description": "Survey webservice API, auth, and web client",
|
||||
"run_in_background": null,
|
||||
"model": null,
|
||||
"prompt": "You are gathering EVIDENCE for a Reverse Requirements Engineering effort on the c-entron ERP codebase at C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP. Do NOT write requirements text, do NOT modify any files — read-only research only. Output must be precise, evidence-cited (exact file path + class/method, line numbers where feasible), separating raw fact from interpretation.\n\nFocus area: Web-facing system architecture — REST API layer, Blazor web client (Nexus), deployment/operations config. This feeds SyRS (system requirements: interfaces, performance, security, deployment).\n\nInvestigate:\n1. src/webservice/Centron.Controllers/Controllers/v1 and /Unversioned — list controller names (gives an inventory of the REST API surface: what business objects are exposed via API). Pick 3-4 representative controllers and note their endpoints (HTTP verbs, routes) and any [Authorize] attributes or custom auth filters.\n2. src/webservice/Centron.Controllers/Authorization — how is API authentication/authorization implemented (token validation, middleware, policies)?\n3. src/webservice/Centron.Controllers/Configuration and Configuration/Routing — API versioning strategy, any rate-limiting, CORS, or Swagger/OpenAPI config.\n4. src/nexus/CentronNexus — this is \"c-entron Nexus\" (web client per README, Blazor + DevExpress). Explore top-level structure, identify main feature areas (e.g. WebCart mentioned in README — self-service ordering for customers' customers via \"Sonderpreise\"). Cite the WebCart implementation location and how it authenticates (\"web-account\" concept).\n5. Deployment/ops artifacts: look in docker/, azure/, azure-blazor/, deployment/ directories at repo root — what do the Dockerfiles / docker-compose / azure pipeline yaml / deployment scripts reveal about: runtime environment, required services (SQL Server, etc.), logging/telemetry setup, environment configuration (appsettings), health checks. Cite specific files and relevant excerpts.\n6. src/backend/Centron.BL/Telemetry — what telemetry/logging is implemented (Application Insights? Custom)?\n7. Look for rate limits, timeouts, or performance-related configuration anywhere (appsettings.json values, HttpClient timeout configs, connection pool settings).\n\nFor each fact: exact file path, class/method, short excerpt, classification PRIMÄR/SEKUNDÄR/KONTEXT, flag UNCLEAR items. Read actual file contents, don't guess from names alone. Target ~1200-1800 words of dense factual findings organized by the 7 topics.",
|
||||
"ergebnis_zeichen": 1093
|
||||
},
|
||||
{
|
||||
"id": "toolu_01SvBc4WPXL7jW4VkYXJhjLH",
|
||||
"werkzeug": "Agent",
|
||||
"subagent_type": "general-purpose",
|
||||
"description": "Survey entities data model and change tracking",
|
||||
"run_in_background": null,
|
||||
"model": null,
|
||||
"prompt": "You are gathering EVIDENCE for a Reverse Requirements Engineering effort on the c-entron ERP codebase at C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP. Do NOT write requirements text, do NOT modify any files — read-only research only. Output must be precise, evidence-cited (exact file path + class/method, line numbers where feasible), separating raw fact from interpretation.\n\nFocus area: cross-cutting data model conventions and audit/change-tracking (feeds SwRS: data requirements, software-internal rules).\n\nInvestigate:\n1. src/backend/Centron.Entities/Entities — how many entity classes roughly (a count is fine), and what ORM/data-access pattern is used (look for base classes, attributes like [Table], [Key], [Required], [MaxLength], DataAnnotations or Fluent mapping). Pick 3-4 representative entity classes central to the business (e.g. something order/invoice/customer related) and report their key fields and any constraints.\n2. src/backend/Centron.DAO — what pattern is used for data access (Repository pattern? Direct ADO.NET? Stored procedures? Entity Framework?) Look for a representative DAO class and report its structure, including any raw SQL found (stored procedure calls, parameterized queries) — cite exact SQL text if found.\n3. src/backend/Centron.BL/ChangeTracking — what does the change-tracking/audit-trail mechanism do? Is every entity change logged? Who/what triggers it? Find the core class and report its mechanism (e.g. a generic audit table, before/after value diffing).\n4. Look for soft-delete vs hard-delete conventions (an \"IsDeleted\" or \"Aktiv\" flag pattern vs actual DELETE statements) — cite examples.\n5. Look for multi-tenancy or multi-company (\"Mandant\"/\"Filiale\"/Branch) scoping in entities or DAO queries — is there a company/branch ID that scopes almost all queries?\n6. Look for concurrency control (optimistic concurrency via a timestamp/rowversion column, or pessimistic locking) in entities or DAO.\n7. Database technology: search for connection string configuration or ADO.NET provider references to confirm MSSQL usage, and note the .NET target framework version(s) from a few .csproj files (TargetFramework element) to establish technical baseline.\n\nFor each fact: exact file path, class/method, short excerpt, classification PRIMÄR/SEKUNDÄR/KONTEXT, flag UNCLEAR items. Read actual file contents, don't guess from names alone. Target ~1200-1800 words of dense factual findings organized by the 7 topics.",
|
||||
"ergebnis_zeichen": 1093
|
||||
}
|
||||
]
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
# Subagenten-Aufrufe
|
||||
|
||||
Session `46eee72a-c498-4572-a51e-b29ac39a180e`, Transkript `46eee72a-c498-4572-a51e-b29ac39a180e.jsonl`.
|
||||
|
||||
`subagent_stats`: **6** Subagenten gesamt, davon **0** von Subagenten gestartet (max_depth 1). Direkt vom Hauptagenten erwartet: **6**. Im Transkript gefunden: **6**.
|
||||
|
||||
## 1. Survey security & rights model
|
||||
|
||||
- **Werkzeug:** `Agent` **Typ:** `general-purpose` **Hintergrund:** None
|
||||
- **Prompt-Zeichen:** 2579 **Ergebnis-Zeichen:** 1093
|
||||
|
||||
### Prompt
|
||||
|
||||
```
|
||||
You are gathering EVIDENCE for a Reverse Requirements Engineering effort on the c-entron ERP codebase at C:\DEV\MasterArbeit\QuellCode\CentronERP. Do NOT write requirements text, do NOT modify any files — this is read-only research. Your output will be used by another process to write ISO/IEC/IEEE 29148 requirements, so it must be precise, evidence-cited (exact file path + class/method/line), and separate raw facts from any interpretation.
|
||||
|
||||
Focus area: the authorization / user-rights model.
|
||||
|
||||
Investigate:
|
||||
1. src/backend/Centron.BL/Security — what classes/services exist, how are rights checked at runtime (e.g. a method like HasRight(...)), how are rights structured (hierarchical constants, per-branch/per-department restrictions)?
|
||||
2. Find the actual "UserRightsConst" class/file(s) (likely in Centron.Common or Centron.Entities or Centron.BL) — report its structure/organization (roughly how many rights, how organized into categories) and a handful of concrete representative examples with full constant names.
|
||||
3. Read CentronRights.md at the repo root fully (already partially known: documents Helpdesk, Kalender, Mitarbeiterauslastung rights) — note it's a partial doc; check if there are other *.md rights docs elsewhere.
|
||||
4. Find where authentication happens (login flow) — for the WPF client and for the webservice/Controllers (src/webservice/Centron.Controllers/Authorization). What auth mechanism is used (session token, JWT, Windows auth, 2FA)? Look at src/backend/Centron.BL/TwoFactorAuthenticator too.
|
||||
5. Find examples of "restricting rights" implemented in code (a right that filters a list to "only own" or "only own branch") — cite 2-3 concrete code locations showing the actual filter logic (e.g. LINQ where clause or SQL WHERE referencing a UserId/BranchId).
|
||||
6. Look for role/group concepts (is there a "role" entity distinct from individual rights, and how are rights assigned to users — directly, via groups, via roles)?
|
||||
7. Any password policy / account lockout / session timeout logic (PasswordManagementArea, PasswordManager folders)?
|
||||
|
||||
For each fact, report: exact file path, class/method name (with line number if feasible), a short verbatim or near-verbatim code/text excerpt, and classify it as PRIMÄR (enforced rule in code/DB constraint), SEKUNDÄR (UI label, config, mapping), or KONTEXT (comment/doc/commit). Flag anything you could not verify as UNCLEAR.
|
||||
|
||||
Report back in a structured list, organized by the 7 numbered topics above. Be thorough — read actual file contents, don't guess from names. Target ~800-1500 words of dense factual findings.
|
||||
```
|
||||
|
||||
## 2. Survey billing/invoicing/accounting logic
|
||||
|
||||
- **Werkzeug:** `Agent` **Typ:** `general-purpose` **Hintergrund:** None
|
||||
- **Prompt-Zeichen:** 2543 **Ergebnis-Zeichen:** 1093
|
||||
|
||||
### Prompt
|
||||
|
||||
```
|
||||
You are gathering EVIDENCE for a Reverse Requirements Engineering effort on the c-entron ERP codebase at C:\DEV\MasterArbeit\QuellCode\CentronERP. Do NOT write requirements text, do NOT modify any files — read-only research only. Output must be precise, evidence-cited (exact file path + class/method, line numbers where feasible), separating raw fact from interpretation.
|
||||
|
||||
Focus area: billing / invoicing / accounting (Fakturierung, Rechnung, Zahlung, Buchhaltung).
|
||||
|
||||
Investigate:
|
||||
1. src/backend/Centron.BL/Accounting and src/backend/Centron.BL/Finances — list the main classes/services and what they do (invoice creation, payment booking, dunning/Mahnwesen, VAT/tax handling, currency).
|
||||
2. src/backend/Centron.BL/VoucherManagement — what is a "Voucher" here (receipt/document type)? How does status progress (draft -> booked -> paid -> cancelled etc)? Find an actual status enum (e.g. VoucherStatus or similar) with its values, and find the code that enforces valid transitions (state machine / guard checks, e.g. "cannot edit a booked invoice").
|
||||
3. Look for entities in src/backend/Centron.Entities relevant to invoices/orders/receipts (e.g. Rechnung, Auftrag, Beleg, Voucher) — report field names relevant to money (amounts, tax rates, currency) and any DB-level constraints visible (e.g. Required attributes, foreign keys, check constraints) in the entity classes or any .edmx/mapping files.
|
||||
4. Find numbering-scheme logic for invoices (Rechnungsnummer / sequential numbering) — is there a class enforcing unique, gapless, or year-based numbering? This is often legally required (GoBD in Germany) — look for related comments.
|
||||
5. Find validation logic before finalizing/"printing"/"booking" an invoice (e.g. required fields, credit limit checks, permission checks referencing UserRightsConst for Accounting/Finances rights).
|
||||
6. Look at the recent commit "feat: added rights check for editing invoice or delivery list date in the settings of timer billing" (git log) — find the actual changed files/code to understand this specific business rule about editing invoice/delivery-list dates and the associated right.
|
||||
7. Any interfaces to external accounting/payment systems (e.g. src/apis/Centron.APIs.FinAPI, EDI folder, EbInterface API for e-invoicing) — what do they do at a high level?
|
||||
|
||||
For each fact: exact file path, class/method, short excerpt, classification PRIMÄR/SEKUNDÄR/KONTEXT, and flag UNCLEAR items. Read actual file contents, don't guess from names. Target ~1000-1800 words of dense factual findings, organized by the 7 topics.
|
||||
```
|
||||
|
||||
## 3. Survey sales order lifecycle and CRM
|
||||
|
||||
- **Werkzeug:** `Agent` **Typ:** `general-purpose` **Hintergrund:** None
|
||||
- **Prompt-Zeichen:** 2207 **Ergebnis-Zeichen:** 1093
|
||||
|
||||
### Prompt
|
||||
|
||||
```
|
||||
You are gathering EVIDENCE for a Reverse Requirements Engineering effort on the c-entron ERP codebase at C:\DEV\MasterArbeit\QuellCode\CentronERP. Do NOT write requirements text, do NOT modify any files — read-only research only. Output must be precise, evidence-cited (exact file path + class/method, line numbers where feasible), separating raw fact from interpretation.
|
||||
|
||||
Focus area: Sales / Order-to-cash process and Customer/CRM (BusinessPartner).
|
||||
|
||||
Investigate:
|
||||
1. src/backend/Centron.BL/Sales — list main subfolders/classes. Find the core "Auftrag"/order object's lifecycle: locate a status enum (e.g. OrderStatus/AuftragStatus) with its values, and the code enforcing valid status transitions (a state machine, switch statement, or guard method).
|
||||
2. src/backend/Centron.BL/BusinessPartner — what is a BusinessPartner (customer/supplier/both)? What are the main sub-entities (contacts, addresses, special prices "Sonderpreise" mentioned in README, credit limits)? Look for validation rules (e.g. required fields, duplicate detection).
|
||||
3. Find how quotations/offers ("Angebot") relate to orders — is there a conversion process (Angebot -> Auftrag)? Cite code.
|
||||
4. Find delivery/shipment logic (Lieferschein / delivery list) — connects to src/apis/Centron.Api.Gls, Centron.Api.Shipcloud shipping integrations. What triggers a shipment, what status does it set on the order?
|
||||
5. Look at recent commits related to "C-Sign" (WebOffer & Acceptance, ticket 168496 & 169060) — find the actual code for electronic signing of offers, understand what business process this represents (customer digitally accepts/signs a web-based offer). Cite files.
|
||||
6. Find the Helpdesk domain (src/backend/Centron.BL/... helpdesk related, also cross-check CentronRights.md content already known) — is Helpdesk part of Sales/CustomerArea? What's a "Ticket" status lifecycle?
|
||||
7. Any product/article catalog logic worth noting (ProductMatrix folder) — briefly, what does it do?
|
||||
|
||||
For each fact: exact file path, class/method, short excerpt, classification PRIMÄR/SEKUNDÄR/KONTEXT, flag UNCLEAR items. Read actual file contents, don't guess from names alone. Target ~1200-1800 words of dense factual findings organized by the 7 topics.
|
||||
```
|
||||
|
||||
## 4. Survey purchasing, warehousing, logistics
|
||||
|
||||
- **Werkzeug:** `Agent` **Typ:** `general-purpose` **Hintergrund:** None
|
||||
- **Prompt-Zeichen:** 2220 **Ergebnis-Zeichen:** 1093
|
||||
|
||||
### Prompt
|
||||
|
||||
```
|
||||
You are gathering EVIDENCE for a Reverse Requirements Engineering effort on the c-entron ERP codebase at C:\DEV\MasterArbeit\QuellCode\CentronERP. Do NOT write requirements text, do NOT modify any files — read-only research only. Output must be precise, evidence-cited (exact file path + class/method, line numbers where feasible), separating raw fact from interpretation.
|
||||
|
||||
Focus area: Purchasing (Einkauf), Warehousing (Lager), Logistics.
|
||||
|
||||
Investigate:
|
||||
1. src/backend/Centron.BL/Buying (or Purchasing) — main classes: purchase order lifecycle, supplier ("Lieferant") handling, find a status enum if present with its values and transition logic.
|
||||
2. src/backend/Centron.BL/Warehousing — stock/inventory management: find how stock levels are tracked (a "Bestand" or "Stock" concept), find booking/movement logic (goods receipt "Wareneingang", goods issue), and any validation preventing negative stock or similar business rule enforced in code.
|
||||
3. src/backend/Centron.BL/Logistics — what does this cover distinctly from Warehousing (shipping, tours, routes)?
|
||||
4. src/backend/Centron.BL/TradePool — what is this (looks like a distinctive c-entron concept, maybe pooled/shared trading inventory between dealers)? Investigate and explain based on code/comments.
|
||||
5. Look at src/apis/* external data-access integrations: Centron.APIs.CopDataAccess, Centron.APIs.EgisDataAccess, Centron.APIs.ITscopeDataAccess, Centron.APIs.IcecatDataAccess — briefly identify what external systems/catalogs these integrate (likely wholesaler/distributor product data and pricing feeds for the IT/electronics trade). Cite a representative class/method per API.
|
||||
6. src/backend/Centron.BL/EDI — what EDI processes exist (electronic data interchange with suppliers, likely order/invoice exchange)? Cite concrete classes.
|
||||
7. Find any DB-level or code-level constraints tied to stock/quantity fields in src/backend/Centron.Entities (e.g. non-negative constraints, required warehouse references).
|
||||
|
||||
For each fact: exact file path, class/method, short excerpt, classification PRIMÄR/SEKUNDÄR/KONTEXT, flag UNCLEAR items. Read actual file contents, don't guess from names alone. Target ~1200-1800 words of dense factual findings organized by the 7 topics.
|
||||
```
|
||||
|
||||
## 5. Survey webservice API, auth, and web client
|
||||
|
||||
- **Werkzeug:** `Agent` **Typ:** `general-purpose` **Hintergrund:** None
|
||||
- **Prompt-Zeichen:** 2482 **Ergebnis-Zeichen:** 1093
|
||||
|
||||
### Prompt
|
||||
|
||||
```
|
||||
You are gathering EVIDENCE for a Reverse Requirements Engineering effort on the c-entron ERP codebase at C:\DEV\MasterArbeit\QuellCode\CentronERP. Do NOT write requirements text, do NOT modify any files — read-only research only. Output must be precise, evidence-cited (exact file path + class/method, line numbers where feasible), separating raw fact from interpretation.
|
||||
|
||||
Focus area: Web-facing system architecture — REST API layer, Blazor web client (Nexus), deployment/operations config. This feeds SyRS (system requirements: interfaces, performance, security, deployment).
|
||||
|
||||
Investigate:
|
||||
1. src/webservice/Centron.Controllers/Controllers/v1 and /Unversioned — list controller names (gives an inventory of the REST API surface: what business objects are exposed via API). Pick 3-4 representative controllers and note their endpoints (HTTP verbs, routes) and any [Authorize] attributes or custom auth filters.
|
||||
2. src/webservice/Centron.Controllers/Authorization — how is API authentication/authorization implemented (token validation, middleware, policies)?
|
||||
3. src/webservice/Centron.Controllers/Configuration and Configuration/Routing — API versioning strategy, any rate-limiting, CORS, or Swagger/OpenAPI config.
|
||||
4. src/nexus/CentronNexus — this is "c-entron Nexus" (web client per README, Blazor + DevExpress). Explore top-level structure, identify main feature areas (e.g. WebCart mentioned in README — self-service ordering for customers' customers via "Sonderpreise"). Cite the WebCart implementation location and how it authenticates ("web-account" concept).
|
||||
5. Deployment/ops artifacts: look in docker/, azure/, azure-blazor/, deployment/ directories at repo root — what do the Dockerfiles / docker-compose / azure pipeline yaml / deployment scripts reveal about: runtime environment, required services (SQL Server, etc.), logging/telemetry setup, environment configuration (appsettings), health checks. Cite specific files and relevant excerpts.
|
||||
6. src/backend/Centron.BL/Telemetry — what telemetry/logging is implemented (Application Insights? Custom)?
|
||||
7. Look for rate limits, timeouts, or performance-related configuration anywhere (appsettings.json values, HttpClient timeout configs, connection pool settings).
|
||||
|
||||
For each fact: exact file path, class/method, short excerpt, classification PRIMÄR/SEKUNDÄR/KONTEXT, flag UNCLEAR items. Read actual file contents, don't guess from names alone. Target ~1200-1800 words of dense factual findings organized by the 7 topics.
|
||||
```
|
||||
|
||||
## 6. Survey entities data model and change tracking
|
||||
|
||||
- **Werkzeug:** `Agent` **Typ:** `general-purpose` **Hintergrund:** None
|
||||
- **Prompt-Zeichen:** 2448 **Ergebnis-Zeichen:** 1093
|
||||
|
||||
### Prompt
|
||||
|
||||
```
|
||||
You are gathering EVIDENCE for a Reverse Requirements Engineering effort on the c-entron ERP codebase at C:\DEV\MasterArbeit\QuellCode\CentronERP. Do NOT write requirements text, do NOT modify any files — read-only research only. Output must be precise, evidence-cited (exact file path + class/method, line numbers where feasible), separating raw fact from interpretation.
|
||||
|
||||
Focus area: cross-cutting data model conventions and audit/change-tracking (feeds SwRS: data requirements, software-internal rules).
|
||||
|
||||
Investigate:
|
||||
1. src/backend/Centron.Entities/Entities — how many entity classes roughly (a count is fine), and what ORM/data-access pattern is used (look for base classes, attributes like [Table], [Key], [Required], [MaxLength], DataAnnotations or Fluent mapping). Pick 3-4 representative entity classes central to the business (e.g. something order/invoice/customer related) and report their key fields and any constraints.
|
||||
2. src/backend/Centron.DAO — what pattern is used for data access (Repository pattern? Direct ADO.NET? Stored procedures? Entity Framework?) Look for a representative DAO class and report its structure, including any raw SQL found (stored procedure calls, parameterized queries) — cite exact SQL text if found.
|
||||
3. src/backend/Centron.BL/ChangeTracking — what does the change-tracking/audit-trail mechanism do? Is every entity change logged? Who/what triggers it? Find the core class and report its mechanism (e.g. a generic audit table, before/after value diffing).
|
||||
4. Look for soft-delete vs hard-delete conventions (an "IsDeleted" or "Aktiv" flag pattern vs actual DELETE statements) — cite examples.
|
||||
5. Look for multi-tenancy or multi-company ("Mandant"/"Filiale"/Branch) scoping in entities or DAO queries — is there a company/branch ID that scopes almost all queries?
|
||||
6. Look for concurrency control (optimistic concurrency via a timestamp/rowversion column, or pessimistic locking) in entities or DAO.
|
||||
7. Database technology: search for connection string configuration or ADO.NET provider references to confirm MSSQL usage, and note the .NET target framework version(s) from a few .csproj files (TargetFramework element) to establish technical baseline.
|
||||
|
||||
For each fact: exact file path, class/method, short excerpt, classification PRIMÄR/SEKUNDÄR/KONTEXT, flag UNCLEAR items. Read actual file contents, don't guess from names alone. Target ~1200-1800 words of dense factual findings organized by the 7 topics.
|
||||
```
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
# Analysebericht – Reverse Requirements Engineering c-entron ERP (V1 Baseline, Iteration 01)
|
||||
|
||||
## 1. Vorgehen dieser Iteration
|
||||
|
||||
Die Analyse erfolgte ausschließlich statisch (kein Ausführen der Anwendung) in mehreren Wellen:
|
||||
|
||||
1. **Strukturelle Größenermittlung**: Zählung von Quelldateien je Top-Level-Projekt (`src/backend`, `src/centron`, `src/webservice`, `src/nexus`, `src/apis`, `src/shared`) → 15.554 C#-Dateien, 1.233 XAML-Dateien insgesamt. Damit ist die Codebasis eine vollständige kommerzielle ERP-Suite; eine erschöpfende Zeile-für-Zeile-Analyse war innerhalb dieser Iteration nicht leistbar und wurde auch nicht angestrebt (siehe Vorgabe zur selbstständigen Tiefenpriorisierung).
|
||||
2. **Parallele Struktur-Surveys** (7 nebenläufige Recherche-Agenten) über: Entitätsmodell (`Centron.Entities`), Geschäftslogik (`Centron.BL`), Datenzugriff (`Centron.DAO`), WPF-Oberfläche (`Centron.WPF.UI`), Webservice-API-Schicht, Nexus/externe APIs/Dokumentation, Deployment/Betrieb/Tests.
|
||||
3. **Vertiefte Lektüre der internen Entwicklerdokumentation** (`docs/**`, 35 Markdown-Dateien vollständig gelesen) – diese erwies sich als ungewöhnlich reichhaltige, teils code-zeilen-genaue Quelle (insbesondere Architektur-, Beleg-, EDI-, ZUGFeRD- und Sicherheitsdokumente) und wurde als primäre Grundlage für SEKUNDÄR-/teils PRIMÄR-Belege verwendet, wo sie konkrete Codezitate mit Dateiname/Zeilennummer enthielt.
|
||||
4. **Commit-Historie** (80 jüngste Commits) als KONTEXT-Quelle für aktive Weiterentwicklung, Modulnamen und Ticketreferenzen.
|
||||
5. **Formalisierung** in StRS (30 Anforderungen), SyRS (38 Anforderungen), SwRS (38 Anforderungen) mit durchgängiger Belegpflicht, Fakt/Aussage-Trennung, Belegklassifikation und Traceability.
|
||||
|
||||
Es wurden **keine Codedateien der analysierten Codebasis verändert**; alle Ergebnisdateien liegen ausschließlich im vorgegebenen Ausgabeverzeichnis.
|
||||
|
||||
## 2. Modul-/Komponentenübersicht mit Analysetiefe
|
||||
|
||||
| Bereich | Analysetiefe | Begründung/Beleglage |
|
||||
|---|---|---|
|
||||
| Beleg-Engine (Angebot/Auftrag/Lieferschein/Rechnung/Gutschrift/Vertrag/Abholschein), `ReceiptBL`, `IReceiptSpecificLogic` | **Tief** | Ausführliche interne Architekturdokumentation mit Codezeilenreferenzen; ergänzt durch direkte Agentenrecherche in `Centron.BL`. Mehrheit der PRIMÄR-Belege dieser Iteration stammt aus diesem Bereich. |
|
||||
| Vertrags-/Kontingent-/RMM-Abrechnung | **Tief** | Zwei dedizierte, detaillierte Architekturdokumente inkl. Fehlerbehandlungscode. |
|
||||
| EDI-Lieferantenintegration | **Tief** | Zwei vollständige Architekturdokumente mit Enum-/Klassendefinitionen im Original. |
|
||||
| ZUGFeRD/XRechnung-E-Invoicing | **Tief** | Feld-für-Feld-Mapping-Dokument mit exakten Codezeilenverweisen (höchster Detailgrad aller gesichteten Dokumente). |
|
||||
| Rechte-/Rollenverwaltung (`UserRightsConst`, `HasUserRight`, `AppRightsBL`) | **Tief** | Verbindliche Entwicklerdokumentation plus quantifizierter Codebefund (318 Aufrufstellen in 93 Dateien) durch Agentenrecherche. |
|
||||
| Authentifizierung (Ticket, OpenID Connect/Microsoft Entra, JWT, Access Tokens, RADIUS-2FA) | **Tief** | Vollständiges technisches Anleitungsdokument mit Sequenzdiagramm und Dateireferenzen; zusätzlich Testevidenz (`RadiusMessageAuthenticationTest.cs`). |
|
||||
| Lizenzierung | **Mittel** | Ein gutes Konzeptdokument, aber keine direkte Codelektüre von `LicenseManager.cs`/`LicenseGuids.cs`. |
|
||||
| Datenbank-Schema-/Migrationskonventionen | **Tief** | Drei dedizierte Konventionsdokumente plus Agentenrecherche mit konkreten DDL-Fundstellen (`CentronConfigurationDbRepository.cs`). |
|
||||
| Webservice-/API-Schicht (Legacy-WCF-Bridge, moderne v1-Controller, SignalR) | **Tief** | Eigener Recherche-Agent mit konkreten Controller-/Endpunktlisten, Auth-Mechanismen, Middleware. |
|
||||
| WPF-Oberfläche – Modulinventar | **Mittel (Breite), oberflächlich (Tiefe je Modul)** | Ein Recherche-Agent lieferte eine breite Modulübersicht (ca. 27 Top-Level-Module) mit Stichprobenklassen; einzelne Module (z. B. Production, PLM, QM, Survey, TelekomDive, PayersAndCostCenter, Massenupdates) wurden nur namentlich, nicht inhaltlich erfasst. |
|
||||
| Helpdesk/Ticketing (WPF + Nexus ServiceBoard) | **Mittel** | Gute Dokumentation zur automatischen Ticketerstellung; Statusmodell (`HelpdeskState`) nur auf Strukturebene (datengetrieben statt Enum) erkannt, nicht inhaltlich mit konkreten Statuswerten befüllt. |
|
||||
| RMA/Retourenmanagement | **Oberflächlich** | Nur UI-Modulexistenz und eine Commit-Referenz; keine BL-Klassen gelesen. |
|
||||
| Mahnwesen (Dunning) / OPOS | **Tief für Rechteschutz, mittel für fachliche Berechnungslogik** | Konkrete Codezeilen für Rechteprüfung gefunden; genaue Mahnstufen-Fristenlogik nicht im Detail gelesen. |
|
||||
| Nexus (Blazor-Webportal: ServiceBoard, WebCart/WebOffer, Outlook-Add-in) | **Tief (Architektur/Existenznachweis), mittel (Detailfunktionen)** | Playwright-Tests liefern konkrete, funktionsfähige Workflows (Freigabe, Ticketsichtbarkeit); vollständiger Seiten-für-Seite-Funktionsumfang nicht erhoben. |
|
||||
| Exchange-/Outlook-Kalendersynchronisation | **Tief** | Außergewöhnlich detailliertes QS-Protokoll mit Root-Cause-Analysen und Codezitaten für acht konkrete Tickets. |
|
||||
| Externe API-Integrationen (GLS, Shipcloud, ITscope, Icecat, COP, EGIS, FinAPI, docuFORM, EbInterface) | **Mittel** | Für jede Integration wurde die Existenz, der Zweck und typische Endpunkte identifiziert; Geschäftsregeln (z. B. Matching-Logik bei Banking) wurden nicht im Detail gelesen. |
|
||||
| Deployment/Betrieb (Docker, Installer, CI/CD) | **Tief** | Eigener Recherche-Agent mit konkreten Konfigurationsdateien, inkl. sicherheitsrelevanter Negativbefunde (Klartext-Secrets, fehlendes Rate-Limiting, offenes CORS). |
|
||||
| Tests (E2E, Unit, Playwright) | **Mittel** | Struktur- und Stichprobenanalyse (Dateizahlen, Testnamen); keine Testimplementierungen im Detail gelesen außer den zitierten QS-Protokoll-Beispielen. |
|
||||
| Produktion (`Modules\Production`), PLM, QM, Survey, TelekomDive, PayersAndCostCenter, Massenupdates, OnlineBanking (UI-Detail), PasswordManager, DataQuality-Feinlogik über die dokumentierte Liste hinaus | **Nicht analysiert** | Nur Modulname aus Ordnerstruktur bekannt; kein Code oder Dokumentation gelesen. |
|
||||
| DSGVO-Modul (konkreter Funktionsumfang) | **Nicht analysiert (nur Existenznachweis)** | Als `[HYPOTHESE]` in StRS-028 geführt. |
|
||||
| "C-Sign" und "C-FLOW" (laut Commit-Historie existierende Features) | **Nicht analysiert** | Nur über Commit-Nachrichten bzw. ein Entitätsfeld (`CFlowStateI3D`) indirekt erschlossen; siehe `Hypothesen.md` H-04/H-05. |
|
||||
|
||||
## 3. Konsistenzcheck über das gesamte Anforderungs-Set
|
||||
|
||||
Durchgeführt am fertigen Anforderungsbestand (StRS-001…030, SyRS-001…038, SwRS-001…038, insgesamt 106 Anforderungen):
|
||||
|
||||
- **Doppelte/mehrfach vergebene IDs:** Keine gefunden. Alle IDs wurden per Grep über alle drei Dokumente extrahiert und sind lückenlos, sequenziell und eindeutig (StRS-001 bis StRS-030, SyRS-001 bis SyRS-038, SwRS-001 bis SwRS-038).
|
||||
- **Anforderungen ohne Beleg:** Keine gefunden – jede der 106 Anforderungen führt mindestens einen klassifizierten Beleg (PRIMÄR/SEKUNDÄR/KONTEXT). Alle abrechnungs-, sicherheits- und rechterelevanten Anforderungen (StRS-013, StRS-014, StRS-016, StRS-017, SyRS-007 bis SyRS-012, SyRS-018, SyRS-028 bis SyRS-031, SwRS-012 bis SwRS-021, SwRS-034, SwRS-035) verfügen über mindestens einen PRIMÄR-Beleg; wo dies nicht eindeutig möglich war (SyRS-029 Ratenbegrenzung), wurde konsequent `[HYPOTHESE]` vergeben statt einer unbelegten Verallgemeinerung.
|
||||
- **Tracelinks auf nicht existierende IDs:** Keine gefunden. Alle referenzierten StRS-/SyRS-/SwRS-IDs in den `Tracelinks`-Feldern existieren im jeweiligen Dokument.
|
||||
- **Korrigierte Inkonsistenzen während des Checks:** Zwei Abweichungen wurden identifiziert und direkt behoben: (1) SwRS-008 (Steuersatzkette) verwies nur auf SwRS-007, ohne eine SyRS-/StRS-Rückverknüpfung – ergänzt um StRS-008/SyRS-013. (2) SwRS-034 (Modul-Rechteprüfung) referenzierte fälschlich „StRS-011" (Ticket-Vorlagen, thematisch unpassend) statt der beabsichtigten „SyRS-011" (Autorisierung) – korrigiert.
|
||||
- **Traceability-Vollständigkeit:** Die konsolidierte Tabelle in `Traceability.md` deckt alle 30 StRS- und alle 38 SyRS-Anforderungen ab; für 12 SyRS-Anforderungen (v. a. querschnittliche/technische Themen wie Fehlerbehandlung, DB-Konventionen, Lokalisierung, Kodierung, Build-Pipeline) wurde keine 1:1-StRS-Zuordnung vorgenommen, da sie mehrere StRS-Anforderungen gemeinsam unterstützen, statt einer einzelnen zugeordnet zu sein (siehe Hinweis in `Traceability.md`).
|
||||
|
||||
## 4. Selbstbewertung
|
||||
|
||||
### Welche Module wurden vollständig, welche nur stichprobenhaft, welche gar nicht analysiert?
|
||||
|
||||
- **Vollständig (im Sinne von: alle verfügbaren internen Primärquellen gelesen, nicht im Sinne von Zeile-für-Zeile-Codeanalyse):** Beleg-/Vertrags-/EDI-/ZUGFeRD-/Rechte-/Auth-Architektur, da hierzu erschöpfende, code-referenzierte interne Dokumentation existierte.
|
||||
- **Stichprobenhaft:** WPF-UI-Modulinventar (Breite statt Tiefe – ca. 27 Module identifiziert, aber nur 8–10 mit konkreten View/ViewModel-Pfaden belegt), Testlandschaft (Struktur- und Namensanalyse, keine Testcode-Lektüre in der Breite), externe API-Integrationen (Existenz und Zweck, keine Detailregeln).
|
||||
- **Gar nicht analysiert:** Produktion, PLM, QM, Survey, TelekomDive, PayersAndCostCenter, Massenupdates, PasswordManager (Funktionsdetails), OnlineBanking-Abgleichlogik, DSGVO-Funktionsdetails, "C-Sign", "C-FLOW". Diese sind im Ordnerinventar (WPF-UI-Survey bzw. Commit-Historie) benannt, aber inhaltlich nicht erschlossen.
|
||||
|
||||
### An welchen Stellen war der Beleg dünn?
|
||||
|
||||
- **Hoher SEKUNDÄR-Anteil:** Externe API-Integrationen (StRS-022 bis StRS-025) stützen sich überwiegend auf Client-Klassenexistenz statt auf gelesene Geschäftsregeln.
|
||||
- **KONTEXT-lastig:** RMA (StRS-009), C-Sign/C-FLOW (nur in `Hypothesen.md` geführt) stützen sich im Wesentlichen auf Commit-Nachrichten.
|
||||
- **Explizit als HYPOTHESE geführt:** StRS-028 (DSGVO-Funktionsumfang), SwRS-004 (Synchronität von `ReceiptState` und Legacy-`Status`-Feld), SyRS-029 (Fehlen von Rate-Limiting als vollständige Sicherheitsaussage). Details und die jeweils fehlende Information zur Klärung stehen in `Hypothesen.md`.
|
||||
|
||||
### Welche Erkenntnisse legen einen Nachschlag in einer Folge-Iteration nahe?
|
||||
|
||||
1. **Statusmodell-Fragmentierung**: Es existieren mindestens drei parallele Statusmodellierungen im System – das moderne `ReceiptState`-Enum (Active/Completed/Canceled), das numerische Legacy-Feld `AufKopf.Status`/`FreigabeStatus`, und das generische `PersistedEntity.StateEnum` (Existing/Deleted) für Soft-Delete, ergänzt um das datengetriebene `HelpdeskState`. Eine Folgeiteration sollte gezielt die Synchronisationslogik zwischen diesen Modellen lesen (`SaveReceipt*Repository.SynchronizeReceiptData`), um SwRS-004 von HYPOTHESE auf „belegt" zu heben oder eine tatsächliche Inkonsistenz zu dokumentieren.
|
||||
2. **Sicherheitsrelevante Lücken (SyRS-029, SyRS-030, SyRS-031)**: Fehlendes API-Rate-Limiting, offene CORS-Konfiguration und im Docker-Referenzsetup hartkodierte Zugangsdaten sollten mit dem Betriebsteam abgeglichen werden, da unklar ist, inwieweit vorgelagerte Infrastruktur (Reverse Proxy, WAF) dies kompensiert – für eine SaaS-Neuimplementierung sind dies jedoch in jedem Fall explizit zu adressierende Sicherheitsanforderungen.
|
||||
3. **Zwei-Generationen-API (SyRS-004/SyRS-005)**: Legacy-WCF-Bridge und moderne v1-Controller decken teils identische fachliche Bereiche ab (z. B. Kunden, Aufträge) – eine Folgeiteration sollte den Überlappungsgrad systematisch kartieren, um im Zielsystem eine einzige API-Generation zu definieren.
|
||||
4. **Nexus-Migrationsstand (H-08, H-09 in `Hypothesen.md`)**: Da Nexus (Blazor) erkennbar als Web-/SaaS-Nachfolger des WPF-Clients entsteht (eigene CI-Pipeline-Familie, Playwright-Suite, OIDC-Konfiguration), ist eine Feature-für-Feature-Gegenüberstellung WPF- vs. Nexus-Funktionsumfang der wichtigste nächste Analyseschritt für das erklärte Ziel „Basis für Web-/SaaS-Neuimplementierung".
|
||||
5. **WPF-Modultiefe**: Die 27 identifizierten WPF-Module (u. a. Production, PLM, QM, Purchasing-Detailprozesse) sollten in weiteren Iterationen priorisiert nach Geschäftskritikalität (z. B. anhand Ticketvolumen/Commit-Häufigkeit) vertieft werden, da diese erste Iteration bewusst auf die beleg-/abrechnungs- und sicherheitsnahen Bereiche fokussiert hat.
|
||||
6. **Rechtegranularität im Legacy-API-Pfad (H-06)**: Ob der WCF-Bridge-Pfad dieselbe granulare Rechteprüfung wie die modernen Controller durchsetzt, wurde nicht verifiziert und ist sicherheitsrelevant für die Konsolidierungsentscheidung (SyRS-004 Konsolidierungshinweis).
|
||||
|
||||
## 5. Bekannte Grenzen dieser Iteration
|
||||
|
||||
- Kein Zugriff auf produktive Datenbankinstanzen, Kundenumgebungen oder Laufzeitverhalten – alle Aussagen sind statisch aus Quellcode/Dokumentation/Tests abgeleitet.
|
||||
- Interne Entwicklerdokumentation (`docs/**`) wurde als SEKUNDÄR/teilweise PRIMÄR (bei wörtlichem Codezitat) eingestuft, jedoch nicht in jedem Fall durch eigenständiges Lesen der referenzierten Originaldatei gegengeprüft; sie stellt in einzelnen Fällen möglicherweise leicht veralteten oder aspirationalen Stand dar (z. B. Best-Practice-Abschnitte in Feature-Dokumenten).
|
||||
- Die Anzahl von 106 formalisierten Anforderungen bildet eine bewusste Priorisierung der beleg-, abrechnungs-, EDI-, e-invoicing-, sicherheits- und betriebsrelevanten Kernarchitektur ab, nicht eine erschöpfende Eins-zu-eins-Abdeckung aller 15.554 Quelldateien. Dies entspricht der in der Aufgabenstellung vorgesehenen selbstständigen Tiefenpriorisierung mit dokumentierter Offenlegung der Lücken (siehe Abschnitt 2 und `Hypothesen.md`).
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
# Glossar – c-entron ERP
|
||||
|
||||
Dieses Glossar sammelt Domänen- und Architekturbegriffe, die in StRS/SyRS/SwRS verwendet werden. Deutsche Fachbegriffe aus der Codebasis werden beibehalten (Originalsprache), technische Bezeichner (Klassen, Methoden, Tabellen) ebenfalls.
|
||||
|
||||
Legende Quellentyp: `CODE` = aus Quellcode/DB abgeleitet, `DOC` = aus interner Entwicklerdokumentation (`docs/`), `HYPOTHESE` = nicht abschließend verifiziert.
|
||||
|
||||
| Begriff | Erklärung | Quelle |
|
||||
|---|---|---|
|
||||
| **I3D** | Primärschlüssel-Konvention in praktisch allen Tabellen ("ID 3develop"), `int IDENTITY(1,1) NOT NULL`, clustered. Fremdschlüsselspalten enden auf das Suffix `I3D` (z. B. `KundenI3D`). | DOC: `docs/guides/database/database-conventions.md` |
|
||||
| **Beleg (Receipt)** | Sammelbegriff für die Dokumenttypen Angebot (Offer), Auftrag (Order), Lieferschein (DeliveryList), Rechnung (Invoice), Vertrag (Contract), Gutschrift (CreditVoucher), Abholschein (PickupList); alle erben von `ReceiptBase`. | DOC: `docs/reference/receipts/receipts-backend-architecture.md` |
|
||||
| **Kopf/Pos-Tabellenpaar** | Legacy-DB-Muster: `*Kopf`-Tabelle (Belegkopf, z. B. `AufKopf`) + `*Pos`-Tabelle (Positionen, z. B. `AufPos`); dazu je eine `*Versions`-Tabelle als 1:1-Kopie für Versionierung/Audit-Trail. | DOC/CODE: `docs/reference/receipts/receipts-backend-architecture.md` |
|
||||
| **Mandator** | Eigene Firma/Betreiber-Stammdaten (z. B. Name, HRB, Steuer-ID, Bankverbindungen) im Gegensatz zu `Branch` (Filiale). | DOC: `docs/reference/zugferd-field-mapping.md` |
|
||||
| **Branch (Filiale)** | Organisatorische Unterebene des Mandanten; kann eigene Adress-/Kontaktdaten für Rechnungsausgabe tragen; Zugriffssteuerung z. T. filialbezogen ("Branch Isolation"). | DOC: `docs/reference/receipts/receipts-backend-architecture.md` |
|
||||
| **Sichrech / UserRightsConst** | Datenbanktabelle für Benutzerrechte (`Sichrech`) und zugehörige C#-Konstanten-Klasse `UserRightsConst.cs`; Grundlage der rollenbasierten Zugriffssteuerung ("Rechteverwaltung"). | DOC: `docs/guides/development/check-userrights.md`, `add-a-new-right.md` |
|
||||
| **Sichbenu / AppUser** | Benutzertabelle (`Sichbenu`), u. a. mit Spalte `OpenIdConnectSubjectIdentifier` für Microsoft-Entra-Kopplung. | DOC: `docs/reference/security/anmelden-mit-microsoft-technische-anleitung.md` |
|
||||
| **Ticket (Session-Ticket)** | Von der Webservice-Anmeldung ausgestellter, zeitlich begrenzter (Standard: 30 Minuten) Sitzungs-Token, der bei nachfolgenden API-Aufrufen als Authentifizierungsnachweis dient. Nicht zu verwechseln mit einem Helpdesk-Ticket. | DOC: `docs/reference/security/anmelden-mit-microsoft-technische-anleitung.md` |
|
||||
| **Lizenz (License)** | GUID-basiertes Berechtigungsmerkmal für Produkte/Einzelfunktionen; besitzt optional `count`, `valid until date`, `valid until version`. Unterschieden werden `Applications` (login-berechtigt, in `ApplicationKind.cs`) und `Only Licenses` (Einzelfunktionen, in `LicenseGuids.cs`). | DOC: `docs/reference/security/licensing-system.md` |
|
||||
| **ApplicationSettings / Stammdat** | Zwei parallele DB-Tabellen für Anwendungseinstellungen: `Stammdat` (Legacy, über `AppSettingsConst`) und `ApplicationSettings` (aktueller Standard, über `ApplicationSettingID`). Neue Einstellungen nur in `ApplicationSettings`. | DOC: `docs/guides/development/settings-management.md` |
|
||||
| **Script / ScriptMethod** | C#-Klasse (`ScriptMethod<Nummer>.cs`), die Datenbank-Migrationsschritte (DDL/DML) über `GetSqlQueries()` bereitstellt; Ausführung versioniert über `ApplicationVersion`. De-facto-Migrationsmechanismus des Systems (kein separates Migrations-Tool). | DOC: `docs/guides/database/create-scripts.md`, `docs/reference/database/script-rules.md` |
|
||||
| **Result / Response** | Internes Fehler-/Ergebnisobjekt (`Result`, `Result<T>`) für die BL-Schicht mit Status `Success/Error/Warning`; wird an der Webservice-Grenze in `Response`/`Response<T>` (Status `Success/Failed`) übersetzt. | DOC: `docs/reference/architecture/results-and-responses.md` |
|
||||
| **DTO (Data Transfer Object)** | Datenklasse zum Transport von Entitätsdaten zwischen BL/Webservice und ViewModel; darf keine Logik enthalten; `[DataContract]`/`[DataMember]`-attributiert. | DOC: `docs/reference/architecture/dtos-and-entities.md` |
|
||||
| **Entity** | NHibernate-verwaltete Domänenklasse mit 1:1-Bezug zu einer DB-Tabellenzeile; erbt `BaseEntity` (liefert `I3D`); darf keine Geschäftslogik enthalten. | DOC: `docs/reference/architecture/dtos-and-entities.md` |
|
||||
| **ILogic / BLLogic / WSLogic** | Dreiteiliges Zugriffsmuster im WPF-Client: `ILogic`-Interface, `BL<Modul>Logic` (Direktzugriff via NHibernate/`BLSession`) und `WS<Modul>Logic` (Zugriff via Webservice); Modul deklariert unterstützte `CentronConnectionType`s (SqlServer, CentronWebServices). | DOC: `docs/getting-started/general-structure.md` |
|
||||
| **ObjectKind / AnlageArt** | Numerischer Diskriminator zur Identifikation eines Beleg-/Objekttyps über mehrere Tabellen hinweg (z. B. `AnlageArt`: 1=Angebot, 2=Auftrag, 3=Lieferschein, 4=Rechnung, 5=Abholschein, 6=Gutschrift, 22=Vertrag), verwendet u. a. im zentralen Log (`AnlageLog`). | DOC: `docs/reference/receipts/receipts-backend-architecture.md` |
|
||||
| **Kontingent (Contingent)** | Vertragskomponente für vorab vereinbarte Nutzungs-/Stundenkontingente (z. B. Servicezeiten), mit Verbrauchs- und Restwert-Tracking (`ContingentUsedHours`, `ContingentBalanceUsedAmount`, ...). | DOC: `docs/reference/receipts/contracts-backend.md` |
|
||||
| **RMM (Remote Monitoring & Management)** | Externes Überwachungssystem (z. B. "Riverbird"), aus dem Nutzungsstatistiken für nutzungsbasierte Vertragsabrechnung (`ContractArticleReferenzes`) abgerufen werden. | DOC: `docs/reference/receipts/Contract-Billing-RMM-Article-Logic.md` |
|
||||
| **EDI (Electronic Data Interchange)** | Automatisierter Belegaustausch mit Lieferanten (Bestellantwort, Lieferschein, Rechnung) über lieferantenspezifische Formate (OpenTrans 2.1, ALSO, ALSO CH, Herweck, Komsa, Alltron) sowie ZUGFeRD für Rechnungen. | DOC: `docs/reference/edi/edi-architecture.md` |
|
||||
| **ZUGFeRD / XRechnung** | Hybrides bzw. rein strukturiertes elektronisches Rechnungsformat (XML), das aus Belegdaten generiert wird; unterstützt mehrere Versionen (1.0 bis 2.1/XRechnung 3.0.1). | DOC: `docs/reference/zugferd-field-mapping.md` |
|
||||
| **Aktionspreis (ActionPrice)** | Zeitlich befristeter Sonderpreis von Distributoren/Herstellern, dargestellt in der Preismatrix neben weiteren externen Preisquellen (ITscope, COP, NEOS, TradersGuide, EGIS). | DOC: `docs/reference/receipts/actionprice-system.md` |
|
||||
| **Preismatrix (Price Matrix)** | UI-/Datenaggregation mehrerer paralleler Preisquellen (intern und extern) zu einem Artikel. | DOC: `docs/reference/receipts/actionprice-system.md` |
|
||||
| **Nexus** | Blazor-Server-Webportal (`CentronNexus`) inkl. zugehörigem Outlook-Add-In; u. a. Terminplanungs-/Synchronisationskomponente (Exchange/Microsoft Graph ↔ c-entron). | DOC: `docs/getting-started/ai-codebase-navigation.md`, `docs/features/exchange-sync-bugprotokoll.md` |
|
||||
| **CenSU (CentronSystemUser)** | Technisches Systemkonto, unter dem automatisierte Hintergrundprozesse (u. a. Exchange-Synchronisation) laufen. | DOC: `docs/features/exchange-sync-bugprotokoll.md` |
|
||||
| **Soft Delete** | Lösch-Konvention: Datensätze werden nicht physisch gelöscht, sondern über `IsDeleted=1` (+ `DeletedByI3D`, `DeletedDate`) markiert. | DOC: `docs/guides/database/database-conventions.md` |
|
||||
| **BackgroundService** | ASP.NET-Core-Hintergrunddienst-Muster (u. a. `DataQualityService`, `EdiDownloadService`, Exchange-Sync-Dienst) für periodische Wartungs-/Synchronisationsaufgaben. | DOC: `docs/Background Service/DataQualityService.md`, `docs/reference/edi/edi-import-rules.md` |
|
||||
| **Helpdesk / Ticket (Vorgang)** | Ticketing-/Vorgangsmodul für Kundenanfragen, Service-/RMA-Fälle; unterstützt automatische Ticketerstellung aus Aufträgen über konfigurierbare Vorlagen. | DOC: `docs/features/automatic-helpdesk-creation-templates.md` |
|
||||
| **RMA** | Retourenprozess (Return Merchandise Authorization) für Fremd-/Lieferantenretouren, laut Commit-Historie mehrfach angepasst (z. B. Mehrfach-RMA-Erfassung). | CODE (Commit-Historie) |
|
||||
| **C-Sign** | Modul für digitale Signatur von Web-Angeboten/Auftragsbestätigungen ("WebOffer & Acceptance"), laut Commit-Historie. | CODE (Commit-Historie) — Tiefe der Analyse: gering, siehe Analysebericht |
|
||||
| **C-FLOW** | Erwähntes Modul im Kontext von Belegpositionen/Vorlagen; Funktionsumfang nicht im Detail verifiziert. | `[HYPOTHESE]` — Beleg nur aus Commit-Nachricht |
|
||||
| **MSP (Managed Service Provider)** | Vertrags-/Abrechnungsszenario mit Geräte-/Positionsverwaltung für Managed-Service-Kunden. | CODE (Commit-Historie), DOC: `docs/reference/receipts/contracts-backend.md` |
|
||||
| **ObjectType / ObjectTypeDictionary** | Zentrales, technisches "Objektart"-Enum (`Entities/ObjectTypes/ObjectType.cs`), das über viele fachlich unabhängige Tabellen hinweg als generischer Polymorphie-Diskriminator verwendet wird (z. B. Offer=1, Order=2, Invoice=4, Helpdesk=10, Contract=22, Customer=5000012). Wird u. a. bei `CreatedFromObjectKind`-Feldern verwendet, um die Herkunft eines Datensatzes typübergreifend zu referenzieren. | CODE: `src/backend/Centron.Entities/Entities/ObjectTypes/ObjectType.cs` |
|
||||
| **AssetKindEnum** | Enum zur Kennzeichnung der Belegart eines "CustomerAsset" (Offer=1, Order=2, DeliveryList=3, Invoice=4, PickupList=5, CreditVoucher=6, Contract=22, Helpdesk=23 u. a.); ähnlich zu `ObjectType`, aber eigenständig und mit eigener Namensauflösung (`AssetKindValues.GetAssetName`). | CODE: `src/backend/Centron.Entities/Entities/Sales/CustomerAssets/AssetKindEnum.cs` |
|
||||
| **HelpdeskState** | Datengetriebener Ticket-Status: keine feste C#-Enumeration, sondern eine administrierbare Stammdaten-Tabelle/-Entität (`HelpdeskStateBase`: `Name`, `Number`, `Description`, `State`), die im laufenden Betrieb erweiterbar ist. | CODE: `src/backend/Centron.Entities/Entities/CustomerArea/Support/HelpdeskStateBase.cs` |
|
||||
| **PersistedEntity.StateEnum** | Generisches, historisch älteres Soft-Delete-Kennzeichen (`Existing=0`, `Deleted=1`) auf Basisklassenebene (`PersistedEntity`), parallel zum neueren, spaltenbasierten `IsDeleted`/`DeletedByI3D`/`DeletedDate`-Muster (siehe `database-conventions.md`). | CODE: `src/backend/Centron.Entities/PersistedEntity.cs` |
|
||||
| **ChangeLog** | Generische, feldbezogene Änderungshistorie (`ObjectI3D`, `ObjectKind`, `Property`, `OldValue`, `NewValue`, `Date`, `AppUser`), die unabhängig vom `AnlageLog`-Belegprotokoll als zusätzlicher, entitätsübergreifender Audit-Mechanismus existiert. | CODE: `src/backend/Centron.Entities/Entities/ChangeTracking/ChangeLog.cs` |
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
# Hypothesen – Sammlung offener, nicht abschließend belegter Aussagen
|
||||
|
||||
Diese Datei sammelt alle mit `[HYPOTHESE]` bzw. Status `HYPOTHESE` gekennzeichneten Aussagen aus StRS/SyRS/SwRS, jeweils mit der konkret fehlenden Information zur Bestätigung. Zusätzlich sind Stellen aufgeführt, an denen die Analyse aus Zeit-/Umfangsgründen nicht vertieft wurde und die für eine Folgeiteration priorisiert werden sollten.
|
||||
|
||||
## Formal als HYPOTHESE gekennzeichnete Anforderungen
|
||||
|
||||
### H-01 (StRS-028 – Datenschutz-Compliance/DSGVO)
|
||||
**Aussage:** Das System soll Funktionen zur Unterstützung datenschutzrechtlicher Anforderungen (Auskunft, Löschung, Anonymisierung) bereitstellen.
|
||||
**Warum Hypothese:** Es wurde lediglich die Existenz eines UI-Moduls `Modules\Administration\DSGVO\CentronDataSecurityView.xaml` festgestellt (SEKUNDÄR-Beleg). Der konkrete Funktionsumfang (welche DSGVO-Artikel/-Prozesse tatsächlich unterstützt werden – Art. 15 Auskunft, Art. 17 Löschung, Datenexport, Verarbeitungsverzeichnis o. Ä.) wurde nicht durch Lesen der zugehörigen ViewModel-/BL-Klassen verifiziert.
|
||||
**Fehlende Information zur Bestätigung:** Quelltext von `CentronDataSecurityViewModel` und zugehöriger BL-Klasse(n); ggf. Interview mit Produktverantwortlichem/Datenschutzbeauftragtem.
|
||||
|
||||
### H-02 (SwRS-004 – ReceiptState vs. Legacy-Status-Synchronisation)
|
||||
**Aussage:** Unklar, ob `ReceiptState`-Enum (moderne Entity-Ebene) und das numerische `Status`/`FreigabeStatus`-Feld der Legacy-Spiegeltabelle (`AufKopf` u. a.) bei jeder Statusänderung synchron gehalten werden.
|
||||
**Warum Hypothese:** Beide Felder wurden durch unterschiedliche Recherche-Agenten in unterschiedlichen Schichten (Interfaces/BL vs. Entities/DbEntities) identifiziert; eine gemeinsame Synchronisationsmethode wurde nicht gelesen.
|
||||
**Fehlende Information zur Bestätigung:** Quelltext der `SaveReceipt*Repository.SynchronizeReceiptData()`-Methoden auf expliziten Statusabgleich zwischen `ReceiptState` und `AufKopf.Status`/`FreigabeStatus` prüfen.
|
||||
|
||||
### H-03 (SyRS-029 – Fehlende Ratenbegrenzung der Webservice-API)
|
||||
**Aussage:** Das System besitzt keinen Schutz vor übermäßig häufigen/übergroßen Anfragen auf API-Ebene.
|
||||
**Warum Hypothese:** Es handelt sich um einen Negativbefund (keine Rate-Limiting-Middleware im Code gefunden). Es ist nicht auszuschließen, dass eine Ratenbegrenzung außerhalb des Repositories (Reverse Proxy, API-Gateway, Firewall/WAF beim Kunden oder in der c-entron-Hosting-Infrastruktur) umgesetzt ist und daher im Quellcode nicht sichtbar wäre.
|
||||
**Fehlende Information zur Bestätigung:** Betriebs-/Infrastrukturdokumentation der produktiven c-entron-SaaS-/Hosting-Umgebung (außerhalb dieses Repositories) einsehen; Interview mit Betriebsverantwortlichen.
|
||||
|
||||
## Weitere, nicht formal als eigene Anforderung geführte offene Punkte
|
||||
|
||||
### H-04 (Umfang von "C-Sign")
|
||||
Die jüngste Commit-Historie (`89ccfd650d Ticket 168496 & 169060 - C-Sign (WebOffer & Acceptance)`) deutet auf ein digitales Signaturfeature für Web-Angebote hin; in der BL-Schicht wurde nur eine thematisch verwandte Klasse `Security\PdfSigningBL.cs` (PDF-Signierung) identifiziert, ohne dass eine explizite "C-Sign"-Komponente gelesen wurde. Es ist unklar, ob `PdfSigningBL` und "C-Sign" identisch, verwandt oder unabhängig sind.
|
||||
**Fehlende Information:** Gezielte Codesuche nach "CSign"/"C-Sign"/"WebOffer.*Accept" in `Centron.BL`, `Centron.Controllers` und `CentronNexus` (WebOffer-Modul), die in dieser Iteration nicht durchgeführt wurde.
|
||||
|
||||
### H-05 (Umfang von "C-FLOW")
|
||||
Der Commit `8e1ea85069 Ticket 167957 - Belegposition to receipt vorlagen in C-FLOW (#56)` erwähnt ein Modul/Feature "C-FLOW"; auf Entitätsebene wurde ein Feld `CFlowStateI3D` auf der `Helpdesk`-Entität gefunden (Hinweis auf einen workflow-artigen Zustandsautomaten für Tickets), aber keine dedizierte C-FLOW-Dokumentation oder -Klasse gelesen.
|
||||
**Fehlende Information:** Gezielte Codesuche nach "CFlow"/"C-Flow" in `Centron.BL`/`Centron.Entities`, um Funktionsumfang und Beziehung zum Helpdesk-Statusmodell zu klären.
|
||||
|
||||
### H-06 (Vollständigkeit der Autorisierungsprüfung bei Legacy-WCF-Bridge)
|
||||
`AuthenticateInterceptor`/`LoggedInUserInterceptor` (Castle-DynamicProxy-basiert) sichern den Legacy-REST-Pfad (`ICentronRestService`) ab; es wurde nicht verifiziert, ob dieselbe Rechtegranularität (`AuthorizeUserRightAttribute`) wie bei den modernen v1-Controllern durchgesetzt wird oder ob der Legacy-Pfad lediglich Authentifizierung (angemeldet ja/nein), nicht aber granulare Autorisierung prüft.
|
||||
**Fehlende Information:** Quelltext von `AuthenticateInterceptor.cs` und Stichproben von `ICentronRestService`-Methoden auf rechte-spezifische Prüfungen (`HasUserRight`) innerhalb der Methodenimplementierung statt nur auf Attributebene.
|
||||
|
||||
### H-07 (Reichweite der finAPI-/Online-Banking-Integration)
|
||||
Es wurde nicht verifiziert, ob der Abgleich importierter Banktransaktionen mit offenen Rechnungen automatisch (Matching-Algorithmus) oder rein manuell erfolgt.
|
||||
**Fehlende Information:** Quelltext des `Modules\OnlineBanking`-Bereichs bzw. zugehöriger BL-Klassen (`AccountTransactions`) auf automatische Zuordnungslogik prüfen.
|
||||
|
||||
### H-08 (Tatsächlicher Migrationsstand Desktop → Nexus)
|
||||
Aus CI/CD-Artefakten (separate `azure-blazor`-Pipeline-Familie, eigene Playwright-Suite, OIDC-/Branding-Konfiguration) lässt sich ableiten, dass Nexus eine im Aufbau befindliche Web-/SaaS-Alternative zum WPF-Client ist. Der genaue funktionale Deckungsgrad (welcher Anteil der WPF-Module bereits in Nexus verfügbar ist) wurde nicht systematisch Modul-für-Modul verglichen.
|
||||
**Fehlende Information:** Vollständige Feature-Gegenüberstellung WPF-Modulliste (`ModuleRegistration.cs`) vs. Nexus-Seitenstruktur (`CentronNexus/**/*.razor`), was den Rahmen dieser Iteration überschritten hätte.
|
||||
|
||||
### H-09 (Multi-Tenant-Fähigkeit von Nexus)
|
||||
`appsettings`-Konfiguration von Nexus (Docker-Referenzkonfiguration) enthält Hinweise auf einen OIDC-Block sowie mandantenspezifische Branding-Einstellungen; ob Nexus bereits echte Mandantentrennung (mehrere Kunden auf gemeinsamer Instanz) unterstützt oder weiterhin ein 1-Instanz-pro-Kunde-Modell voraussetzt, wurde nicht verifiziert.
|
||||
**Fehlende Information:** Quelltext-/Konfigurationsanalyse zu mandantenübergreifender Datenisolation in `CentronNexus.Host` (z. B. Datenbankverbindungsauswahl pro Tenant).
|
||||
|
||||
## Empfehlung für Folgeiterationen
|
||||
|
||||
Die oben genannten Punkte (insbesondere H-04, H-05, H-06, H-08, H-09) sollten in einer Folgeiteration mit gezielter Tiefenanalyse (nicht nur Doku-/Struktur-Survey, sondern Quellcodelesen der konkret benannten Klassen) geklärt werden, da sie sowohl für die Vollständigkeit der StRS (Funktionsumfang) als auch für sicherheitsrelevante SyRS-Aussagen (Autorisierung im Legacy-Pfad) relevant sind.
|
||||
+575
@@ -0,0 +1,575 @@
|
||||
# Stakeholder Requirements Specification (StRS) – c-entron ERP
|
||||
|
||||
Diese StRS beschreibt die fachliche Sicht (Akteure, Geschäftsziele, Kernfähigkeiten) des c-entron-ERP-Systems, wie sie aus der Codebasis (Modulstruktur, Webservice-Oberfläche, Dokumentation, Commit-Historie) rekonstruierbar ist. Sie bildet die Grundlage für SyRS/SwRS und für eine Web-/SaaS-Neuimplementierung.
|
||||
|
||||
Akteursübersicht (aus Rechte-/Modulstruktur abgeleitet, `[HYPOTHESE]` sofern nicht explizit benannt):
|
||||
- **Innendienst-/Vertriebsmitarbeiter** (Beleg-, Kunden-, Artikelbearbeitung)
|
||||
- **Lager-/Logistikmitarbeiter** (Warenwirtschaft, Kommissionierung, Inventur)
|
||||
- **Einkäufer** (Bestellwesen, Lieferantenmanagement, EDI)
|
||||
- **Service-/Support-Mitarbeiter** (Helpdesk, RMA, Zeiterfassung)
|
||||
- **Buchhaltung** (Rechnungswesen, Mahnwesen, OPOS, Banking)
|
||||
- **Administrator** (Rechte-, Mandanten-, Lizenz-, Systemverwaltung)
|
||||
- **Endkunde / Webaccount-Nutzer** (Kundenportal, Web-Shop, Ticketeinsicht)
|
||||
- **Externe Systeme** (Lieferanten-EDI-Server, Distributoren-APIs, Versanddienstleister, Bankdienste, Microsoft 365/Entra ID, RMM-System)
|
||||
|
||||
---
|
||||
|
||||
```
|
||||
ID: StRS-001
|
||||
Titel: Durchgängige Belegkette Angebot–Auftrag–Lieferschein–Rechnung–Gutschrift
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Innendienst-/Vertriebsmitarbeiter
|
||||
Vorbedingung: Kunde und Artikel sind im System erfasst.
|
||||
Fakt: Alle Belegtypen (Angebot, Auftrag, Lieferschein, Rechnung, Gutschrift, Vertrag, Abholschein) erben von einer gemeinsamen Basisklasse `ReceiptBase` und werden über ein gemeinsames Backend (`ReceiptBL`) verwaltet; jeder Belegtyp definiert erlaubte Vorgänger-/Nachfolgebelege.
|
||||
Aussage: Das System soll es Vertriebsmitarbeitern ermöglichen, einen Verkaufsvorgang durchgängig von Angebot über Auftrag und Lieferschein bis zur Rechnung (und ggf. Gutschrift) fortzuführen, ohne Daten erneut erfassen zu müssen.
|
||||
Ergebnis: Ein Folgebeleg wird mit übernommenen Kopf- und Positionsdaten aus dem Ursprungsbeleg erzeugt.
|
||||
Belege:
|
||||
- [SEKUNDÄR] `docs/reference/receipts/receipts-backend-architecture.md` - Begründung: Beschreibt die gemeinsame Belegarchitektur und Tabellen/Views je Belegtyp.
|
||||
- [PRIMÄR] `src/backend/Centron.BL/Sales/Receipts/IReceiptSpecificLogic.cs`, `SpecificLogics.cs` - Begründung: Definiert und prüft programmatisch, welche Belegtyp-Übergänge zulässig sind (`CanBeForwardedFrom`/`CanBeForwardedInto`).
|
||||
Prüfidee: End-to-End-Test: Angebot anlegen → in Auftrag wandeln → in Rechnung wandeln; prüfen, dass Kundendaten, Positionen und Preise unverändert übernommen werden.
|
||||
Tracelinks: SyRS-013, SyRS-014, SwRS-001, SwRS-002, SwRS-003, SwRS-004
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-002
|
||||
Titel: Zentrale Kunden-/Interessentenverwaltung (CRM)
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Vertriebsmitarbeiter
|
||||
Vorbedingung: -
|
||||
Fakt: Eigenständiges CRM-Modul (`Modules\Finances\Crm`) mit Kundenstamm, Kontaktpersonen, Adressen sowie Finanz-/Beleghistorie je Kunde.
|
||||
Aussage: Das System soll Kunden- und Interessentendaten inkl. Kontaktpersonen, Adressen und zugehöriger Belege zentral verwalten und im Vertriebsprozess referenzierbar machen.
|
||||
Ergebnis: Kundendaten sind einmalig gepflegt und in allen Belegen/Modulen konsistent referenziert (`CustomerI3D`/`KundenI3D`).
|
||||
Belege:
|
||||
- [SEKUNDÄR] `src/centron/Centron.WPF.UI/Modules/Finances/Crm/CrmMainView.xaml`, `CrmMainViewModel.cs` - Begründung: Eigenständige CRM-Hauptmaske mit Finanz-Tab.
|
||||
- [SEKUNDÄR] `src/webservice/Centron.Controllers/Controllers/v1/Accounts/AccountsController.cs`, `v1/Customers/CustomersController.cs` - Begründung: Dedizierte REST-Endpunkte für Kunden-/Account-Daten.
|
||||
Prüfidee: Neuen Kunden anlegen, Adresse/Kontaktperson hinzufügen, anschließend in einem Angebot referenzieren und Übernahme der Stammdaten prüfen.
|
||||
Tracelinks: SyRS-001, SyRS-003
|
||||
Konsolidierung: Kandidat: CRM-Kundendaten (`Kunden`-Tabelle) und Webaccount-Kundenportalzugang (StRS-018) könnten im Zielsystem als ein Identitätsmodell konsolidiert werden.
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-003
|
||||
Titel: Wiederkehrende Vertragsabrechnung mit Kontingenten
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Vertrieb / Buchhaltung
|
||||
Vorbedingung: Ein Vertrag (Belegtyp `ReceiptContract`) ist mit Kunde, Positionen und Abrechnungsintervall angelegt.
|
||||
Fakt: `ReceiptContract` besitzt Felder für Abrechnungsintervall (`BillingIntervalKind`, `BillingIntervalDuration`), automatisierte Abrechnung (`AutomatedBilling`) sowie Kontingentverwaltung (`ContingentUsedHours`, `ContingentLimitValue`, `ContingentBalanceUsedAmount`).
|
||||
Aussage: Das System soll Verträge mit wiederkehrenden Abrechnungsintervallen (täglich/monatlich/quartalsweise/jährlich) abbilden und automatisiert Rechnungen daraus erzeugen können, inkl. Verrechnung vereinbarter Nutzungskontingente.
|
||||
Ergebnis: Zum fälligen Abrechnungstermin wird automatisiert eine Rechnung mit den vertraglich vereinbarten und kontingentbereinigten Positionen erzeugt.
|
||||
Belege:
|
||||
- [SEKUNDÄR] `docs/reference/receipts/contracts-backend.md` - Begründung: Beschreibt Vertragsentität, Abrechnungsintervall- und Kontingentfelder im Detail mit Codereferenzen.
|
||||
- [PRIMÄR] `src/backend/Centron.BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.Contracts.cs` - Begründung: Enthält die automatisierte Rechnungserzeugung aus Verträgen (laut Dokumentation und Modulübersicht der BL-Schicht).
|
||||
Prüfidee: Vertrag mit monatlichem Abrechnungsintervall anlegen, automatisierte Abrechnung aktivieren, Fälligkeitsdatum erreichen lassen (Testlauf) und Rechnungserzeugung prüfen.
|
||||
Tracelinks: SyRS-013, SwRS-001, SwRS-009
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-004
|
||||
Titel: Nutzungsbasierte Abrechnung über externe RMM-Systeme
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Buchhaltung / MSP-Dienstleister-Kunde
|
||||
Vorbedingung: Vertrag ist für RMM-Abrechnung konfiguriert (`WhetherRMM` = true) und Artikelreferenzen sind hinterlegt.
|
||||
Fakt: Bei aktivierter RMM-Abrechnung ruft `RiverConnectionBL` Nutzungsdaten aus dem externen RMM-System ("Riverbird") für den Abrechnungszeitraum ab und fügt daraus berechnete Positionen automatisiert in die Rechnung ein.
|
||||
Aussage: Das System soll für Managed-Service-Verträge automatisiert Nutzungsdaten aus einem externen Monitoring-System (RMM) abrufen und in die Rechnungsstellung integrieren.
|
||||
Ergebnis: Rechnungspositionen für RMM-Artikel enthalten die tatsächlich im Abrechnungszeitraum gemessene Nutzung; ist der RMM-Dienst nicht erreichbar, wird die Rechnungserstellung abgebrochen statt mit unvollständigen Daten fortzufahren.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/receipts/Contract-Billing-RMM-Article-Logic.md` (zitiert `RiverConnectionBL.GetContractBillingAmounts`, `RMMServiceUnavailableException`) - Begründung: Dokumentiert konkrete Abbruchlogik bei Nichterreichbarkeit des externen Dienstes, ein durchgesetztes Verhalten.
|
||||
Prüfidee: RMM-Dienst simuliert nicht erreichbar → Rechnungserstellung für RMM-Vertrag muss mit Fehlermeldung abbrechen, keine Teil-Rechnung darf erzeugt werden.
|
||||
Tracelinks: SyRS-013, SwRS-009, SwRS-010, SwRS-011
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-005
|
||||
Titel: Einkauf und Lieferantenbestellwesen
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Einkäufer
|
||||
Vorbedingung: Artikel und Lieferant sind erfasst.
|
||||
Fakt: Eigenständiges Modul `Modules\Purchasing` mit `OrderSuggestionList` (Bestellvorschlagsliste) sowie Belegtyp `SupplierOrder` mit spiegelbildlicher Belegkette (`SupplierOrderSpecificLogic` → `SupplierDeliveryList` → `SupplierInvoice` → `SupplierCreditVoucher`).
|
||||
Aussage: Das System soll Einkäufern die Erstellung von Bestellvorschlägen und Lieferantenbestellungen sowie deren Verfolgung über Lieferschein und Lieferantenrechnung ermöglichen.
|
||||
Ergebnis: Aus einem Bestellvorschlag wird eine Lieferantenbestellung erzeugt, deren Wareneingang und Rechnungsprüfung im System nachverfolgt werden können.
|
||||
Belege:
|
||||
- [SEKUNDÄR] `src/centron/Centron.WPF.UI/Modules/Purchasing/OrderSuggestionList` - Begründung: Eigenständige UI für Bestellvorschläge.
|
||||
- [PRIMÄR] `src/backend/Centron.BL/Sales/Receipts/SupplierOrders/SupplierOrderSpecificLogic.cs` - Begründung: Definiert programmatisch die zulässige Belegfolge für Lieferantenbestellungen.
|
||||
Prüfidee: Bestellvorschlag erzeugen, in Lieferantenbestellung wandeln, Lieferschein und Lieferantenrechnung erfassen; Mengen-/Preisübernahme prüfen.
|
||||
Tracelinks: SyRS-013, SyRS-014, SwRS-002
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-006
|
||||
Titel: Automatisierter EDI-Belegaustausch mit Lieferanten
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Einkäufer / System (Hintergrunddienst)
|
||||
Vorbedingung: Für einen Lieferanten ist eine EDI-Konfiguration (`SupplierEdiConfigurations`) hinterlegt.
|
||||
Fakt: `SupplierEdiBL` unterstützt mehrere lieferantenspezifische EDI-Formate (OpenTrans 2.1, ALSO, ALSO CH, Herweck, Komsa, Alltron) für Bestellantwort, Lieferung und Rechnung; ein Hintergrunddienst lädt Dateien alle 30 Minuten automatisch herunter und verarbeitet sie.
|
||||
Aussage: Das System soll Bestellantworten, Lieferavise und Lieferantenrechnungen automatisiert per EDI von unterstützten Distributoren abrufen und in die entsprechenden c-entron-Belege überführen, ohne manuelle Dateneingabe.
|
||||
Ergebnis: Empfangene EDI-Dokumente werden automatisch in c-entron-Belege umgesetzt bzw. mit bestehenden Bestellungen abgeglichen; fehlerhafte Dateien werden protokolliert und nach mehrfachem Fehlschlag von weiteren Verarbeitungsversuchen ausgeschlossen.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/edi/edi-architecture.md`, `docs/reference/edi/edi-import-rules.md` (zitieren `EdiDownloadService`, `SupplierEdiBL.DownloadStartAsync`, konkrete Blacklist-SQL) - Begründung: Beschreiben eine tatsächlich implementierte, automatisiert laufende Verarbeitungskette inkl. Fehlerbehandlung.
|
||||
- [SEKUNDÄR] `src/centron/Centron.WPF.UI/Modules/Purchasing/EDIManagement/EDIManagementView.xaml` - Begründung: UI zur Konfiguration/Überwachung der EDI-Anbindung.
|
||||
Prüfidee: EDI-Testdatei eines unterstützten Lieferantenformats bereitstellen, Download-Zyklus abwarten, Übernahme in c-entron-Beleg prüfen.
|
||||
Tracelinks: SyRS-021, SyRS-022, SyRS-026, SwRS-026, SwRS-027, SwRS-028
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-007
|
||||
Titel: Artikelstamm- und Lagerverwaltung
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Lager-/Logistikmitarbeiter
|
||||
Vorbedingung: -
|
||||
Fakt: Modul `Modules\Warehousing` mit Untermodulen `ArticleManagement`, `InventoryManagement` (Inventur), `StockManagement`, `CommissioningManagement`, `BarcodeManagement`.
|
||||
Aussage: Das System soll die Verwaltung von Artikelstammdaten, Lagerbeständen, Inventuren, Kommissionierung und Barcode-/Seriennummernerfassung ermöglichen.
|
||||
Ergebnis: Artikel- und Bestandsdaten sind zentral gepflegt und werden bei Beleganlage (z. B. Lieferschein) automatisch fortgeschrieben.
|
||||
Belege:
|
||||
- [SEKUNDÄR] `src/centron/Centron.WPF.UI/Modules/Warehousing/ArticleManagement`, `Inventory`, `Commissioning*`, `BarcodeManagement` - Begründung: Eigenständige UI-Module je Teilfunktion.
|
||||
- [SEKUNDÄR] `docs/reference/receipts/receipts-backend-architecture.md` (Abschnitt "Inventory System") - Begründung: Beschreibt Echtzeit-Bestandsprüfung und automatische Lagerbuchung bei Belegverarbeitung.
|
||||
Prüfidee: Artikel anlegen, Lieferschein mit diesem Artikel buchen, Bestandsfortschreibung im Lagerbestand prüfen.
|
||||
Tracelinks: SyRS-013, SwRS-001
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-008
|
||||
Titel: Mehrquellen-Preisfindung inkl. externer Distributorpreise
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Einkäufer / Vertriebsmitarbeiter
|
||||
Vorbedingung: Artikel ist mit Hersteller-/Distributorcode versehen.
|
||||
Fakt: Die "Preismatrix" aggregiert bis zu sieben parallele Preisquellen (ITscope, Artikelimport, COP, NEOS, TradersGuide, EGIS, interne Aktionspreise) zu einem Artikel und filtert Aktionspreise nach Gültigkeitszeitraum.
|
||||
Aussage: Das System soll Einkaufs-/Verkaufspreise aus mehreren internen und externen Quellen konsolidiert darstellen, um eine informierte Preisentscheidung zu unterstützen.
|
||||
Ergebnis: Für einen Artikel werden alle aktuell gültigen Preise mehrerer Quellen gleichzeitig angezeigt.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/receipts/actionprice-system.md` (zitiert `PriceMatrixViewModel.GetPriceItemsFromArticleActionPrices()`, Zeilen 416-459) - Begründung: Konkrete Methode mit Datumsfilterlogik für Aktionspreise, PRIMÄR belegt.
|
||||
- [SEKUNDÄR] `src/apis/Centron.APIs.ITscopeDataAccess`, `Centron.APIs.IcecatDataAccess`, `Centron.APIs.EgisDataAccess`, `Centron.APIs.CopDataAccess` - Begründung: Client-Bibliotheken für die genannten externen Preis-/Produktdatenquellen.
|
||||
Prüfidee: Artikel mit gültigem Aktionspreis und externem API-Preis öffnen; Preismatrix muss beide Quellen gleichzeitig mit korrekter Kennzeichnung anzeigen.
|
||||
Tracelinks: SyRS-013, SwRS-007
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-009
|
||||
Titel: Retouren- und Reklamationsmanagement (RMA)
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Service-/Vertriebsmitarbeiter
|
||||
Vorbedingung: Ursprungsbeleg/Artikel mit Seriennummer ist vorhanden.
|
||||
Fakt: Eigenständiges Modul `Modules\Rma` mit Untermodulen `SendBack`, `SendForth`, `NewRma`; Commit-Historie zeigt aktive Weiterentwicklung ("mehrere Fremd-RMA-Fälle auf einmal erfassen").
|
||||
Aussage: Das System soll die Erfassung, Bearbeitung und Nachverfolgung von Kunden- und Lieferantenretouren (RMA) unterstützen, einschließlich Sammelerfassung mehrerer Fälle.
|
||||
Ergebnis: Ein RMA-Vorgang ist mit Bezug zum Ursprungsartikel/-beleg nachvollziehbar dokumentiert.
|
||||
Belege:
|
||||
- [SEKUNDÄR] `src/centron/Centron.WPF.UI/Modules/Rma/RmaOverviewView.xaml`, `SendBack/SendBackViewModel.cs`, `SendForth/SendForthViewModel.cs` - Begründung: Eigenständige RMA-UI-Module.
|
||||
- [KONTEXT] Commit `79e6512154 Ticket 165253: mehrere Fremd-RMA-Fälle auf einmal erfassen (#49)` - Begründung: Bestätigt aktive fachliche Weiterentwicklung der Sammelerfassung.
|
||||
Prüfidee: RMA-Fall für retournierten Artikel anlegen, Status bis Abschluss verfolgen.
|
||||
Tracelinks: SyRS-013
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-010
|
||||
Titel: Helpdesk-/Ticketsystem für Kundenanfragen
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Service-/Support-Mitarbeiter, Endkunde
|
||||
Vorbedingung: Kunde ist erfasst.
|
||||
Fakt: Modul `Modules\Helpdesk` (WPF) sowie eigenständiges "ServiceBoard" im Nexus-Webportal (Dashboard, Kanban, Ticketliste, Ticketdetails) bilden ein durchgängiges Ticketsystem; REST-Endpunkte `v1/Helpdesks`.
|
||||
Aussage: Das System soll die Erfassung, Kategorisierung, Bearbeitung, Weiterleitung und den Abschluss von Kundenservice-Tickets sowohl im Desktop-Client als auch im Webportal unterstützen.
|
||||
Ergebnis: Ein Ticket durchläuft nachvollziehbar Status von Eingang bis Abschluss inkl. Historie, Dokumenten und Kommentaren.
|
||||
Belege:
|
||||
- [SEKUNDÄR] `src/centron/Centron.WPF.UI/Modules/Helpdesk/TicketList`, `TicketDetails` - Begründung: WPF-Ticket-UI.
|
||||
- [SEKUNDÄR] `src/nexus/CentronNexus/ServiceBoard/Dashboard`, `Kanban`, `TicketList/TicketSearchPage.razor` - Begründung: Web-Ticket-UI (Nexus/Blazor).
|
||||
- [SEKUNDÄR] `src/webservice/Centron.Controllers/Controllers/v1/Helpdesks/HelpdesksController.cs` - Begründung: REST-Endpunkte für Ticketabschluss/Kommentare.
|
||||
Prüfidee: Ticket im WPF-Client anlegen, im Webportal auffindbar und bearbeitbar prüfen, Status bis "geschlossen" verfolgen.
|
||||
Tracelinks: SyRS-003, SyRS-037, SwRS-034
|
||||
Konsolidierung: Kandidat: WPF-Helpdesk-Modul und Nexus-ServiceBoard bilden zwei parallele UI-Implementierungen derselben fachlichen Funktion – im Zielsystem konsolidierungsbedürftig.
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-011
|
||||
Titel: Automatische Ticketerstellung aus Aufträgen über Vorlagen
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Service-/Vertriebsmitarbeiter
|
||||
Vorbedingung: Ein Auftrag mit Positionen existiert; mindestens eine Ticket-Erstellungsvorlage ist gepflegt.
|
||||
Fakt: Feature "Automatische Helpdeskfallerstellung" erlaubt das Speichern, Laden und Verwalten mehrerer Vorlagen (Kategorie, Priorität, Bearbeiter, Erstellungsmodus Single/Group/Custom); eine Vorlage kann als Standard markiert werden.
|
||||
Aussage: Das System soll es ermöglichen, aus Auftragspositionen automatisiert Helpdesk-Tickets nach konfigurierbaren, wiederverwendbaren Vorlagen zu erzeugen.
|
||||
Ergebnis: Beim Auslösen der automatischen Ticketerstellung werden je nach gewähltem Modus ein Ticket pro Position, ein Sammelticket oder eine benutzerdefinierte Auswahl erzeugt, vorbelegt mit den Vorlagenwerten.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/features/automatic-helpdesk-creation-templates.md` (zitiert `HelpdeskCreationTemplateBL.SetStandardTemplate`, Tabelle `HelpdeskCreationTemplate`) - Begründung: Vollständig dokumentierte, mit Datenbankschema und Business-Logik belegte Funktion.
|
||||
Prüfidee: Vorlage mit Modus "Group" anlegen, als Standard setzen, aus Auftrag Tickets erzeugen lassen; genau ein Sammelticket mit Vorlagenwerten muss entstehen.
|
||||
Tracelinks: SyRS-013, SwRS-034
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-012
|
||||
Titel: Zeiterfassung und automatisierte Zeitabrechnung
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Service-Mitarbeiter, Buchhaltung
|
||||
Vorbedingung: Mitarbeiter ist einem Ticket/Auftrag zugeordnet.
|
||||
Fakt: Modul `Modules\Finances\TimerBilling` sowie Rechteprüfung für Änderungen an Rechnungs-/Lieferscheindatum in den Timer-Billing-Einstellungen ("added rights check for editing invoice or delivery list date in the settings of timer billing").
|
||||
Aussage: Das System soll erfasste Arbeitszeiten (Timer) mit Bezug zu Tickets/Aufträgen erfassen und automatisiert in Rechnungen überführen können, wobei kritische Datumseinstellungen rechtebeschränkt sind.
|
||||
Ergebnis: Erfasste Zeiten werden gemäß Abrechnungsregeln in Rechnungspositionen umgewandelt; Nutzer ohne entsprechendes Recht erhalten beim Versuch, das Rechnungs-/Lieferscheindatum zu ändern, einen Hinweis statt der Möglichkeit zur Änderung.
|
||||
Belege:
|
||||
- [PRIMÄR] Commit `baa9e7bd9b feat: added rights check for editing invoice or delivery list date in the settings of timer billing. If user has no right an info field is shown. (#97)` - Begründung: Beschreibt eine tatsächlich umgesetzte, rechtegeschützte Regel (Commit-Titel + Verhalensbeschreibung).
|
||||
- [SEKUNDÄR] `src/centron/Centron.WPF.UI/Modules/Finances/TimerBilling` - Begründung: Eigenständiges UI-Modul für Zeitabrechnung.
|
||||
Prüfidee: Benutzer ohne das entsprechende Recht öffnet Timer-Billing-Einstellungen; Datumseingabe für Rechnungs-/Lieferscheindatum muss gesperrt sein und ein Hinweisfeld anzeigen.
|
||||
Tracelinks: SyRS-011, SwRS-014
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-013
|
||||
Titel: Mahnwesen für überfällige Rechnungen
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Buchhaltung
|
||||
Vorbedingung: Offene, überfällige Rechnung(en) für einen Kunden liegen vor.
|
||||
Fakt: `DunningBL` (~1060 Zeilen) implementiert Mahnstufenberechnung, Mahnlauf-Statistiken und automatisierte Mahnschreiben-Texterzeugung; Ausführung ist über `ThrowIfUserHasInsufficentRights` rechtegeschützt.
|
||||
Aussage: Das System soll überfällige Kundenrechnungen erkennen, Mahnstufen berechnen und Mahnläufe mit automatisiert generierten Mahntexten durchführen, wobei nur berechtigte Buchhaltungsmitarbeiter Mahnläufe auslösen können.
|
||||
Ergebnis: Ein Mahnlauf erzeugt je überfälligem Kunden eine Mahnung der korrekten Mahnstufe; Benutzer ohne Recht können keinen Mahnlauf starten.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/backend/Centron.BL/Sales/Receipts/Invoices/Dunning/DunningBL.cs` (Zeile ~1059, Methode `ThrowIfUserHasInsufficentRights`) - Begründung: Konkrete, im Code durchgesetzte Rechteprüfung vor Ausführung eines abrechnungsrelevanten Vorgangs (erfüllt PRIMÄR-Anforderung für Abrechnungslogik).
|
||||
- [SEKUNDÄR] `DunningRunWebServiceBL.cs` - Begründung: Web-Service-Fassade für den Mahnlauf.
|
||||
Prüfidee: Mahnlauf mit Benutzer ohne Mahnungsrecht auslösen → Abbruch mit Fehlermeldung; mit berechtigtem Benutzer → korrekte Mahnstufenzuordnung je Kunde.
|
||||
Tracelinks: SyRS-011, SwRS-012, SwRS-013, SwRS-014
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-014
|
||||
Titel: Verwaltung offener Posten (OPOS)
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Buchhaltung
|
||||
Vorbedingung: Rechnungen mit offenem Zahlungsstatus liegen vor.
|
||||
Fakt: `OposBL`/`OposRunBL` verwalten offene Posten; Ausführung ist ebenfalls über `ThrowIfUserHasInsufficentRights` rechtegeschützt.
|
||||
Aussage: Das System soll offene Forderungen (offene Posten) je Kunde konsolidiert darstellen und Verarbeitungsläufe (z. B. Zahlungsabgleich) nur berechtigten Benutzern erlauben.
|
||||
Ergebnis: Offene-Posten-Liste zeigt korrekt saldierte, noch nicht ausgeglichene Rechnungsbeträge je Kunde; ein OPOS-Lauf durch einen nicht berechtigten Benutzer wird abgelehnt.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/backend/Centron.BL/Sales/Receipts/Invoices/Opos/OposBL.cs` (Zeile ~28, `ThrowIfUserHasInsufficentRights`) - Begründung: Durchgesetzte Rechteprüfung vor abrechnungsrelevanter Verarbeitung.
|
||||
Prüfidee: OPOS-Lauf durch nicht berechtigten Benutzer auslösen → Abbruch; Saldenkontrolle einer Testrechnung mit Teilzahlung.
|
||||
Tracelinks: SyRS-011, SwRS-013, SwRS-014
|
||||
Konsolidierung: Kandidat: OPOS und Mahnwesen (StRS-013) teilen dieselbe Rechteschutz-Idiom (`ThrowIfUserHasInsufficentRights`) und denselben fachlichen Kontext (Zahlungsüberwachung) – ggf. im Zielsystem als ein "Forderungsmanagement"-Baustein konsolidierbar.
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-015
|
||||
Titel: Elektronische Rechnungsstellung (ZUGFeRD/XRechnung/ebInterface)
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Buchhaltung, System
|
||||
Vorbedingung: Rechnung ist final erstellt.
|
||||
Fakt: `InvoiceZugferdBL` generiert ZUGFeRD-/XRechnung-konforme XML in mehreren Versionen (1.0 bis 2.1/XRechnung 3.0.1); `Centron.Api.EbInterface` erzeugt zusätzlich das österreichische ebInterface-Format.
|
||||
Aussage: Das System soll Rechnungen in strukturierten, europäisch/national genormten elektronischen Rechnungsformaten (ZUGFeRD, XRechnung, ebInterface) erzeugen können, um gesetzlichen E-Invoicing-Pflichten nachzukommen.
|
||||
Ergebnis: Zu einer Rechnung wird eine normkonforme XML-Datei erzeugt, deren Summen mit den Belegsummen übereinstimmen (Toleranzprüfung).
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/zugferd-field-mapping.md` (zitiert `InvoiceZugferdBL.cs:117-158`, Toleranzregel ±3,00) - Begründung: Konkrete Methoden- und Regelreferenzen im Code.
|
||||
- [SEKUNDÄR] `src/apis/Centron.Api.EbInterface/EbInterfaceLogic.cs` - Begründung: Eigenständiger Generator für das österreichische Format.
|
||||
Prüfidee: Rechnung mit mehreren Steuersätzen erzeugen, ZUGFeRD-Export prüfen (KOSIT-Validator), Summenabgleich innerhalb der Toleranz verifizieren.
|
||||
Tracelinks: SyRS-023, SyRS-024, SwRS-029, SwRS-030
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-016
|
||||
Titel: Rollenbasierte Benutzer- und Rechteverwaltung
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Administrator
|
||||
Vorbedingung: -
|
||||
Fakt: Eigenständiges Modul "Rechteverwaltung" (`Modules\Administration\RightsManagement`); Rechte sind in DB-Tabelle `Sichrech` hinterlegt und werden im Code 318-mal über `HasUserRight(UserRightsConst...)` in 93 Dateien der BL-Schicht geprüft.
|
||||
Aussage: Das System soll es Administratoren ermöglichen, Benutzern und Gruppen granulare, modul- und funktionsspezifische Rechte zuzuweisen, die im gesamten System konsistent durchgesetzt werden.
|
||||
Ergebnis: Ein Benutzer ohne zugewiesenes Recht kann die zugehörige Funktion weder in der UI aufrufen noch über die Business-Logik ausführen.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/backend/Centron.BL/Administration/Rights/UserRightsExt.cs` (`HasUserRight`) - Begründung: Zentrale, im Code durchgesetzte Autorisierungsprüfung, 318 Aufrufstellen.
|
||||
- [SEKUNDÄR] `docs/guides/development/check-userrights.md`, `add-a-new-right.md` - Begründung: Entwicklerdokumentation des Rechte-Konzepts.
|
||||
Prüfidee: Benutzer ohne Recht "Kunde anlegen" versucht, einen Kunden anzulegen → UI-Funktion ist deaktiviert und BL-Aufruf liefert Fehlermeldung "Fehlende Rechte...".
|
||||
Tracelinks: SyRS-011, SyRS-012, SwRS-014, SwRS-015, SwRS-016
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-017
|
||||
Titel: Produkt-/Feature-Lizenzierung
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Administrator, System
|
||||
Vorbedingung: Kunde hat eine oder mehrere Lizenzen erworben.
|
||||
Fakt: Lizenzen sind GUID-basiert, mit optionalem Zähler, Ablaufdatum und Versionsgrenze; unterschieden werden `Applications` (login-berechtigt) und `Only Licenses` (Einzelfunktionen); zentrale Prüfung über `LicenseManager.Instance.HasLicense(...)`.
|
||||
Aussage: Das System soll den Zugriff auf Anwendungen und Einzelfunktionen anhand erworbener Lizenzen (inkl. Mengen- und Zeitbegrenzung) steuern.
|
||||
Ergebnis: Nicht lizenzierte Funktionen/Module sind für den Kunden nicht sichtbar bzw. nicht nutzbar; bei mengenbegrenzten Lizenzen wird die vereinbarte Obergrenze durchgesetzt.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/security/licensing-system.md` (zitiert `LicenseManager.Instance.HasLicense`, `GetLicenseCount`) - Begründung: Beschreibt konkrete, im Code aufgerufene Prüfmethoden.
|
||||
- [SEKUNDÄR] `src/webservice/Centron.Controllers/Controllers/v1/Administration/LicenseController.cs` - Begründung: REST-Endpunkt zur Lizenzverwaltung.
|
||||
Prüfidee: Kunde ohne Lizenz für Modul X öffnet c-entron → Modul ist nicht im Modul-Menü sichtbar (`ModuleRegistration.IsModuleAvailable`).
|
||||
Tracelinks: SyRS-018, SwRS-021
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-018
|
||||
Titel: Kundenportal mit Web-Shop und Angebotsannahme
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Endkunde (Webaccount-Nutzer)
|
||||
Vorbedingung: Kunde besitzt einen Webaccount-Zugang.
|
||||
Fakt: Nexus-Blazor-Portal enthält "WebCart"/"WebOffer"-Komponenten (`CustomerPortal`) für Warenkorb, Angebotsansicht und -annahme; Playwright-Tests (`WebaccountTests.cs`) bestätigen einen Warenkorb-mit-Freigabe-Workflow und eine "Receipts"-Übersicht (Angebote/Aufträge/Lieferscheine/Rechnungen/Gutschriften).
|
||||
Aussage: Das System soll Endkunden über ein Webportal Selbstbedienungsfunktionen bieten: Produkte in den Warenkorb legen, Bestellungen/Angebote freigeben lassen und eigene Belege (Angebote, Aufträge, Rechnungen) einsehen.
|
||||
Ergebnis: Ein Endkunde kann ohne Mitwirkung eines internen Mitarbeiters eine Bestellung anlegen, zur Freigabe einreichen und nach Freigabe den Bestellstatus sowie zugehörige Belege einsehen.
|
||||
Belege:
|
||||
- [PRIMÄR] `tests/PlaywrightTests/WebaccountTests.cs` (`CheckWebAccount`: "Request approval" → "Approve" → "Ready for order") - Begründung: Automatisierter Test beweist den tatsächlich funktionsfähigen Freigabe-Workflow im Livesystem.
|
||||
- [SEKUNDÄR] `src/nexus/CentronNexus/WebCart/CustomerPortal`, `WebOffer/Components` - Begründung: Zugehörige UI-Komponenten.
|
||||
Prüfidee: Als Webaccount-Nutzer Artikel in Warenkorb legen, Freigabe anfordern, als Freigebender genehmigen, Status "bestellbereit" prüfen.
|
||||
Tracelinks: SyRS-003, SyRS-037, SwRS-001
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-019
|
||||
Titel: Rollenbasierte Sichtbarkeit von Tickets im Kundenportal
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Endkunde (Webaccount-Nutzer)
|
||||
Vorbedingung: Mehrere Webaccount-Rollen (unterschiedliche Nutzer desselben Kunden) existieren.
|
||||
Fakt: Playwright-Tests unterscheiden explizit Testkonten (Alpha/Beta/Gamma) mit unterschiedlicher Ticketsichtbarkeit sowie eine datumsbasierte Sichtbarkeitsregel (`CheckWebAccountTicketsAfter240101`).
|
||||
Aussage: Das System soll die Sichtbarkeit von Tickets im Kundenportal je nach Nutzerrolle und ggf. Erstellungsdatum einschränken, sodass ein Kundenkontakt nur die für ihn freigegebenen Tickets sieht.
|
||||
Ergebnis: Ein Webaccount-Nutzer ohne entsprechende Freigabe sieht bestimmte Tickets nicht, unabhängig davon, dass sie demselben Kundenkonto zugeordnet sind.
|
||||
Belege:
|
||||
- [PRIMÄR] `tests/PlaywrightTests/WebaccountTests.cs` (`CheckWebAccountTicketsCanSeeDisabled` vs. `CanSeeEnabled`, `CheckWebAccountTicketsAfter240101`) - Begründung: Automatisierte Tests belegen eine tatsächlich durchgesetzte, zeilenspezifische Sichtbarkeitsregel.
|
||||
Prüfidee: Zwei Webaccount-Nutzer desselben Kunden mit unterschiedlicher Ticket-Sichtbarkeitskonfiguration anlegen; prüfen, dass jeder nur die für ihn freigegebenen Tickets sieht.
|
||||
Tracelinks: SyRS-011, SyRS-012
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-020
|
||||
Titel: Outlook-Integration für Ticket- und Kundenzuordnung
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Service-/Vertriebsmitarbeiter
|
||||
Vorbedingung: Outlook-Add-in ist installiert und mit c-entron verbunden.
|
||||
Fakt: `CentronNexus.OutlookAddIn` stellt eine Taskpane bereit, mit der E-Mails Tickets/Vorgängen zugeordnet oder neue Tickets direkt aus einer E-Mail erstellt werden können (Manifest-Beschreibung: "Mails direkt Vorgängen zuordnen und Tickets in Outlook finden").
|
||||
Aussage: Das System soll es Mitarbeitern ermöglichen, direkt aus Microsoft Outlook heraus E-Mails bestehenden Tickets/Kunden zuzuordnen oder neue Tickets zu erstellen.
|
||||
Ergebnis: Eine im Outlook-Add-in bearbeitete E-Mail ist im c-entron-Ticket nachvollziehbar verknüpft bzw. hat ein neues Ticket erzeugt.
|
||||
Belege:
|
||||
- [SEKUNDÄR] `src/nexus/CentronNexus.OutlookAddIn/Manifest/Manifest.xml`, `OfficeDialog/NewTicketForm.razor`, `Ticket/ManageTicketTab.razor` - Begründung: Konkrete Add-in-UI-Komponenten und Manifestbeschreibung des Funktionsumfangs.
|
||||
Prüfidee: E-Mail in Outlook öffnen, Add-in nutzen, um ein neues Ticket zu erstellen; Ticket muss im c-entron-System mit E-Mail-Bezug erscheinen.
|
||||
Tracelinks: SyRS-038
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-021
|
||||
Titel: Kalendersynchronisation mit Microsoft Exchange/Outlook
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Mitarbeiter (Techniker/Service)
|
||||
Vorbedingung: Exchange-Synchronisation ist für den Mitarbeiter aktiviert (Exchange Online via Microsoft Graph).
|
||||
Fakt: `ExchangeSyncService` synchronisiert bidirektional zwischen c-entron-Terminplanung und Outlook-Kalender; für Helpdesk-Zeiterfassungstermine gilt c-entron als "Source of Truth", reine Outlook-Termine werden von Outlook aus aktualisiert.
|
||||
Aussage: Das System soll Termine zwischen c-entron-Zeitplanung und Microsoft Outlook/Exchange automatisiert synchronisieren, wobei bei Helpdesk-Zeiterfassungsterminen c-entron die maßgebliche Datenquelle bleibt.
|
||||
Ergebnis: Ein in c-entron erfasster Helpdesk-Zeittermin erscheint im Outlook-Kalender; eine nachträgliche Änderung des Termins direkt in Outlook überschreibt nicht Datum/Uhrzeit des c-entron-Datensatzes.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/features/exchange-sync-bugprotokoll.md` (zitiert `IsHelpdeskSchedule()`, `SyncOldSchedule()`, `UpdateScheduleByGraph()` mit Codebeispielen) - Begründung: Konkrete, im Code umgesetzte und durch QS-Testfälle verifizierte Source-of-Truth-Regel.
|
||||
Prüfidee: Helpdesk-Zeit in c-entron anlegen (Datum X), Sync abwarten, Termin in Outlook manuell auf Datum Y ändern, erneut synchronisieren → c-entron-Datensatz muss weiterhin Datum X zeigen.
|
||||
Tracelinks: SyRS-027, SwRS-031, SwRS-032
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-022
|
||||
Titel: Anbindung von Versanddienstleistern
|
||||
Ebene: StRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: Lager-/Logistikmitarbeiter
|
||||
Vorbedingung: Lieferschein/Paket ist versandfertig.
|
||||
Fakt: Zwei eigenständige API-Clients: `Centron.Api.Gls` (direkte GLS-API) und `Centron.Api.Shipcloud` (Multi-Carrier-Aggregator) für Versandauftrag, Label-Erzeugung und Sendungsverfolgung.
|
||||
Aussage: Das System soll Versandaufträge und Versandlabels für unterstützte Paketdienstleister (u. a. GLS, über Shipcloud weitere Carrier) direkt aus dem Lieferschein erzeugen und den Sendungsstatus zurückmelden können.
|
||||
Ergebnis: Zu einem Lieferschein wird ein Versandlabel erzeugt; Statusänderungen des Paketdienstes werden dem Beleg zugeordnet.
|
||||
Belege:
|
||||
- [SEKUNDÄR] `src/apis/Centron.Api.Gls/CentronGlsLogic.cs`, `src/apis/Centron.Api.Shipcloud/CentronShipcloudLogic.cs` - Begründung: Konkrete Client-Implementierungen mit Versand-/Tracking-Endpunkten.
|
||||
- [SEKUNDÄR] `src/webservice/Centron.Controllers/Controllers/v1/Receipts/ShipcloudPackageTemplatesController.cs` - Begründung: REST-Endpunkt für Versandvorlagen.
|
||||
Prüfidee: Lieferschein abschließen, Versandlabel über GLS/Shipcloud erzeugen, Tracking-Nummer im Beleg prüfen.
|
||||
Tracelinks: SyRS-003
|
||||
Konsolidierung: Kandidat: GLS-Direktanbindung und Shipcloud-Aggregator decken teils überlappende Funktionalität ab – im Zielsystem auf einen Versand-Abstraktionsdienst konsolidierbar.
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-023
|
||||
Titel: Abgleich von Produktdaten mit externen Distributoren/Katalogen
|
||||
Ebene: StRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: Einkäufer, Artikelstammpfleger
|
||||
Vorbedingung: Artikel besitzt Hersteller-/EAN-Code.
|
||||
Fakt: Vier eigenständige API-Clients (ITscope, Icecat, COP, EGIS) liefern Produktstammdaten, Beschreibungen, Bilder, Verfügbarkeiten und Preise von IT-Distributoren/-Katalogen.
|
||||
Aussage: Das System soll Artikelstammdaten (Beschreibungen, Bilder, Verfügbarkeit, Distributorpreise) automatisiert mit mehreren externen Produktdatenquellen abgleichen können.
|
||||
Ergebnis: Ein Artikel kann mit angereicherten Herstellerinhalten (Icecat) sowie tagesaktuellen Distributorpreisen/-verfügbarkeiten (ITscope/COP/EGIS) dargestellt werden.
|
||||
Belege:
|
||||
- [SEKUNDÄR] `src/apis/Centron.APIs.ITscopeDataAccess/ITscopeApi.cs`, `Centron.APIs.IcecatDataAccess/IcecatApi.cs`, `Centron.APIs.CopDataAccess/CopApi.cs`, `Centron.APIs.EgisDataAccess/EgisApi.cs` - Begründung: Vier eigenständige, dokumentierte API-Clients mit spezifischen Produktdaten-Endpunkten.
|
||||
Prüfidee: Artikel mit bekanntem Herstellercode über Icecat-Abgleich anreichern lassen, Ergebnis (Beschreibung/Bild) im Artikelstamm prüfen.
|
||||
Tracelinks: SyRS-013
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-024
|
||||
Titel: Bankdatenabgleich (Online-Banking)
|
||||
Ebene: StRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: Buchhaltung
|
||||
Vorbedingung: Bankverbindung ist über finAPI verknüpft.
|
||||
Fakt: `Centron.APIs.FinAPI` implementiert einen REST/OAuth2-Client für den PSD2-Bankdaten-Aggregator finAPI (Konten, Bankverbindungen, Transaktionen); eigenständiges WPF-Modul `Modules\OnlineBanking`.
|
||||
Aussage: Das System soll Kontobewegungen und Bankverbindungen automatisiert über einen Banking-Aggregationsdienst abrufen, um den manuellen Abgleich von Zahlungseingängen zu reduzieren.
|
||||
Ergebnis: Neue Kontotransaktionen werden importiert und können offenen Rechnungen zugeordnet werden.
|
||||
Belege:
|
||||
- [SEKUNDÄR] `src/apis/Centron.APIs.FinAPI/FinApiClient.cs`, `Data/Transaction.cs` - Begründung: Konkrete Transaktions-/Konto-Datenmodelle und Client.
|
||||
- [SEKUNDÄR] `src/centron/Centron.WPF.UI/Modules/OnlineBanking` - Begründung: Zugehöriges UI-Modul.
|
||||
Prüfidee: Testkonto über finAPI-Sandbox verbinden, Transaktionsimport auslösen, Zuordnung zu offener Rechnung prüfen.
|
||||
Tracelinks: SyRS-013, StRS-014
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-025
|
||||
Titel: Fernüberwachung angebundener Drucksysteme (Managed Print Services)
|
||||
Ebene: StRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: Service-Mitarbeiter (Kopierer-/Druckerfachhändler-Kontext)
|
||||
Vorbedingung: Gerät ist bei docuFORM registriert und in c-entron verknüpft.
|
||||
Fakt: `Centron.Api.docuFORM` bindet die docuFORM-MPS-API an (`/dfmserver/v2/devices`), liefert Zählerstände, Verbrauchsmaterial-Status, SNMP-Daten und Gewährleistungsinformationen von Druckern/Kopierern.
|
||||
Aussage: Das System soll Zählerstände und Verbrauchsmaterialdaten angebundener Drucker/Kopierer über eine externe MPS-Plattform automatisiert abrufen, um Klickabrechnung und Serviceplanung zu unterstützen.
|
||||
Ergebnis: Aktuelle Zählerstände eines Gerätes stehen für die Vertragsabrechnung (Klickabrechnung) automatisiert zur Verfügung, ohne manuelle Zählerablesung.
|
||||
Belege:
|
||||
- [SEKUNDÄR] `src/webservice/Centron.Controllers/Controllers/v1/DataExchange/DocuFormApiSettingsController.cs`, `Centron.Api.docuFORM/Models/Swagger/DeviceCounters.cs` - Begründung: Konkrete Konfigurations-/Datenmodelle für Gerätezähler.
|
||||
Prüfidee: Gerät mit docuFORM verknüpfen, Zählerstand-Abfrage auslösen, Übernahme in Vertragskontingent-Verbrauch (StRS-004) prüfen.
|
||||
Tracelinks: SyRS-013, StRS-004
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-026
|
||||
Titel: Reporting und betriebswirtschaftliche Statistiken
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Geschäftsführung, Vertriebsleitung
|
||||
Vorbedingung: Ausreichend Beleg-/Bewegungsdaten liegen vor.
|
||||
Fakt: Module `Modules\Statistics` (u. a. `SaleStatistics`, `ManagementInfo`) und `Modules\Reports` sowie eine eigene ReportEngine-Schicht in der BL (`ReportEngine`, `Reporting`).
|
||||
Aussage: Das System soll konfigurierbare betriebswirtschaftliche Auswertungen und Berichte (u. a. Verkaufsstatistiken, Management-Informationen) auf Basis der Beleg- und Stammdaten bereitstellen.
|
||||
Ergebnis: Ein Bericht liefert aggregierte, dem gewählten Zeitraum/Filter entsprechende Kennzahlen.
|
||||
Belege:
|
||||
- [SEKUNDÄR] `src/centron/Centron.WPF.UI/Modules/Statistics/SaleStatistics`, `Modules/Reports` - Begründung: Eigenständige UI-Module.
|
||||
Prüfidee: Verkaufsstatistik für definierten Zeitraum abrufen und Summenkontrolle gegen manuell aggregierte Belegdaten durchführen.
|
||||
Tracelinks: SyRS-013
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-027
|
||||
Titel: Mandanten- und Filialverwaltung
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Administrator
|
||||
Vorbedingung: -
|
||||
Fakt: Modul `Modules\Administration\MandatorManagement`; Entitäten `Mandator` (Firmenstammdaten) und `Branch` (Filiale) werden u. a. für Rechnungsausstellerdaten und Zugriffsisolation ("Branch Isolation") verwendet.
|
||||
Aussage: Das System soll die Verwaltung mehrerer Mandanten/Filialen mit eigenen Stammdaten (Adresse, Bankverbindung, Steuer-ID) unterstützen und den Datenzugriff optional auf die eigene Filiale beschränken.
|
||||
Ergebnis: Rechnungen einer Filiale weisen automatisch deren Absenderdaten aus; ein filialbeschränkter Benutzer sieht nur Belege der eigenen Filiale.
|
||||
Belege:
|
||||
- [SEKUNDÄR] `docs/reference/zugferd-field-mapping.md` (Abschnitt "Data Sources": "If BranchI3D is set: Load from Branch table") - Begründung: Konkrete Datenherkunftsregel für Rechnungsabsenderdaten.
|
||||
- [SEKUNDÄR] `docs/reference/receipts/receipt-search-architecture.md` (Abschnitt "Branch Isolation") - Begründung: Beschreibt filialbezogene Zugriffsbeschränkung in der Belegsuche.
|
||||
Prüfidee: Benutzer mit "nur eigene Filiale"-Recht sucht Belege → nur Belege der eigenen Filiale werden zurückgegeben.
|
||||
Tracelinks: SyRS-012
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-028
|
||||
Titel: Datenschutz-Compliance (DSGVO)
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Administrator, Datenschutzbeauftragter
|
||||
Vorbedingung: -
|
||||
Fakt: Eigenständiges Modul `Modules\Administration\DSGVO` (`CentronDataSecurityView.xaml`).
|
||||
Aussage: Das System soll Funktionen zur Unterstützung datenschutzrechtlicher Anforderungen (DSGVO), z. B. Auskunfts- oder Löschprozesse, bereitstellen.
|
||||
Ergebnis: `[HYPOTHESE]` – der konkrete Funktionsumfang (Auskunft, Löschung, Anonymisierung) ist aus dem Vorhandensein des Moduls allein nicht ableitbar.
|
||||
Belege:
|
||||
- [SEKUNDÄR] `src/centron/Centron.WPF.UI/Modules/Administration/DSGVO/CentronDataSecurityView.xaml` - Begründung: Belegt Existenz des Moduls, nicht dessen genauen Funktionsumfang.
|
||||
Prüfidee: Modul öffnen und konkrete Funktionen (Auskunft/Löschung/Anonymisierung) inventarisieren; mit Datenschutzbeauftragtem abgleichen.
|
||||
Tracelinks: -
|
||||
Konsolidierung: nein
|
||||
Status: HYPOTHESE
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-029
|
||||
Titel: KI-gestützte Assistenzfunktionen
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Mitarbeiter (diverse Rollen)
|
||||
Vorbedingung: KI-Funktion ist lizenziert/aktiviert.
|
||||
Fakt: Eigenes WPF-Modul `Modules\ArtificialIntelligence`, REST-Controller `ArtificialIntelligenceChatsController` (Chats, Nachrichten, Tool-Ergebnisse, Instruktions-Prompt-Einstellungen je Mandant/Filiale/Mitarbeiter) sowie ein Kontextmenüeintrag "Zeitbeschreibungen mit KI prüfen"/"Textvorschlag mit KI generieren" in der Zeitabrechnung.
|
||||
Aussage: Das System soll KI-gestützte Assistenzfunktionen (Chat-Assistent, Textvorschläge, z. B. für Zeitbeschreibungen) mit konfigurierbaren Instruktions-Prompts je Organisationsebene bereitstellen.
|
||||
Ergebnis: Ein Mitarbeiter kann über einen Chat-Assistenten Anfragen stellen bzw. sich Textvorschläge (z. B. für Zeitbeschreibungen) generieren lassen.
|
||||
Belege:
|
||||
- [SEKUNDÄR] `src/webservice/Centron.Controllers/Controllers/v1/Administration/ArtificialIntelligenceChatsController.cs` - Begründung: Konkrete REST-Endpunkte für Chat-/Prompt-Verwaltung je Mandant/Filiale/Mitarbeiter.
|
||||
- [SEKUNDÄR] `src/centron/Centron.WPF.UI/Modules/Finances/TimerBilling/Pages/TimerBillingAITextRatingPageView.xaml` - Begründung: Konkreter UI-Anwendungsfall (KI-Textvorschlag für Zeitbeschreibung).
|
||||
Prüfidee: Chat-Assistenten mit Testanfrage aufrufen, Antwortverhalten und Rechteschutz (Mandanten-/Filial-/Mitarbeiterebene) prüfen.
|
||||
Tracelinks: SyRS-013
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-030
|
||||
Titel: Gleichwertiger Zugriff über Desktop-Client und Webservice
|
||||
Ebene: StRS
|
||||
Typ: nicht-funktional
|
||||
Akteur: Alle internen Benutzerrollen, externe Anwendungen
|
||||
Vorbedingung: -
|
||||
Fakt: Jedes fachliche Modul soll laut Entwicklerdokumentation sowohl eine direkte Datenbankanbindung (`BLLogic`/SqlServer) als auch eine Webservice-Anbindung (`WSLogic`/CentronWebServices) unterstützen ("Every module MUST implement both data access methods").
|
||||
Aussage: Das System soll fachliche Funktionen unabhängig vom gewählten Zugriffsweg (lokale Datenbankverbindung des Desktop-Clients oder zentraler Webservice) mit gleichem Funktionsumfang bereitstellen.
|
||||
Ergebnis: Ein Anwender erhält unabhängig vom konfigurierten Verbindungstyp (`CentronConnectionType.SqlServer` vs. `CentronWebServices`) dieselben Ergebnisse bei gleicher Funktion.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/getting-started/general-structure.md` (Abschnitt "Dual Implementation Architecture") - Begründung: Dokumentiert eine als verpflichtend beschriebene Architekturregel mit Codebeispielen (`IAccountContractsLogic`, `BLAccountContractsLogic`, `WSAccountContractsLogic`).
|
||||
Prüfidee: Gleiche fachliche Aktion (z. B. Kunde anlegen) einmal über Direktverbindung, einmal über Webservice-Verbindung ausführen; Ergebnis muss identisch sein.
|
||||
Tracelinks: SyRS-001
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround (historisch aus On-Premise-Modell mit optionaler Direkt-DB-Anbindung entstanden – für eine SaaS-Neuimplementierung mit zentralem Mehrmandanten-Backend voraussichtlich obsolet)
|
||||
```
|
||||
+693
@@ -0,0 +1,693 @@
|
||||
# Software Requirements Specification (SwRS) – c-entron ERP
|
||||
|
||||
Diese SwRS beschreibt Komponenten, Datenmodelle und softwareinterne Regeln auf Ebene konkreter Klassen, Methoden und Datenbankobjekte. Jede Anforderung konkretisiert eine übergeordnete SyRS-Anforderung.
|
||||
|
||||
---
|
||||
|
||||
```
|
||||
ID: SwRS-001
|
||||
Titel: ReceiptBase als gemeinsame Basisklasse aller Belegtypen
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: System
|
||||
Vorbedingung: -
|
||||
Fakt: `ReceiptBase` (abstrakt, `src/backend/Centron.Entities/Entities/Sales/Receipts/ReceiptBase.cs`) definiert Kopf-Informationen (Nummer, Datum, Version, State, Editor), Filial-, Währungs-, Kontakt-, Adress- und Audit-Felder sowie abstrakte Methoden `GetReceiptItems()`, `AddItem()`, `RemoveItem()`; alle sieben Belegtypen (Offer, Order, DeliveryList, Invoice, Contract, CreditVoucher, PickupList) erben davon.
|
||||
Aussage: Das System soll gemeinsame Kopf-Attribute und Grundoperationen aller Belegtypen in einer einzigen Basisklasse kapseln, um Redundanz zwischen den sieben Belegarten zu vermeiden.
|
||||
Ergebnis: Eine Änderung an einem gemeinsamen Kopf-Attribut (z. B. `ConcurrencyControlGuid`) wirkt einheitlich für alle Belegtypen.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/backend/Centron.Entities/Entities/Sales/Receipts/ReceiptBase.cs` - Begründung: Konkrete abstrakte Basisklasse mit den genannten Feldern/Methoden (dokumentiert in `docs/reference/receipts/receipts-backend-architecture.md`).
|
||||
Prüfidee: Neues gemeinsames Kopf-Feld in `ReceiptBase` hinzufügen und Sichtbarkeit in allen sieben abgeleiteten Belegtypen ohne Zusatzaufwand prüfen.
|
||||
Tracelinks: SyRS-013, SyRS-015
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-002
|
||||
Titel: IReceiptSpecificLogic als typspezifische Übergangs- und Verhaltensschnittstelle
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: -
|
||||
Fakt: `IReceiptSpecificLogic` (`src/backend/Centron.BL/Sales/Receipts/IReceiptSpecificLogic.cs`, >250 Member) deklariert je Belegtyp u. a. `CanBeForwardedFrom()`, `CanBeForwardedInto()`, `OnReceiptCreated`, `UpdatesStock`, `IsCostCenterNeeded`, `CanBeAutomaticallyOpened/Closed`; konkrete Implementierungen je Belegtyp (`OfferSpecificLogic`, `OrderSpecificLogic`, `DeliveryListSpecificLogic`, `InvoiceSpecificLogic`, `CreditVoucherSpecificLogic`, `PickupListSpecificLogic`, `ContractSpecificLogic`) sowie gespiegelt für Lieferantenbelege.
|
||||
Aussage: Das System soll belegtypspezifisches Verhalten (erlaubte Übergänge, Lagerwirkung, Kostenstellenpflicht, Automatisierungsregeln) über eine einheitliche Strategie-Schnittstelle kapseln statt über verstreute Fallunterscheidungen.
|
||||
Ergebnis: Neues belegtypspezifisches Verhalten wird durch Implementierung/Überschreiben der Schnittstelle hinzugefügt, ohne die generische `ReceiptBL` zu verändern.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/backend/Centron.BL/Sales/Receipts/IReceiptSpecificLogic.cs`, `Offers/OfferSpecificLogic.cs`, `Orders/OrderSpecificLogic.cs`, `Invoices/InvoiceSpecificLogic.cs`, `CreditVouchers/CreditVoucherSpecificLogic.cs` u. a. - Begründung: Konkrete Interface- und Implementierungsklassen laut Agentenrecherche der BL-Schicht.
|
||||
Prüfidee: Für Belegtyp "Rechnung" prüfen, dass `CanBeForwardedInto` ausschließlich `CreditVoucherClass` erlaubt; Versuch, eine Rechnung in einen Auftrag zu wandeln, muss abgelehnt werden.
|
||||
Tracelinks: SyRS-013, SyRS-014, SwRS-001
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-003
|
||||
Titel: SpecificLogics-Dispatcher mit Start-Konsistenzprüfung
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Anwendung startet.
|
||||
Fakt: `SpecificLogics.cs` löst über `_specificLogics.Execute(receipt.ReceiptKind, f => ...)` die passende `IReceiptSpecificLogic`-Implementierung anhand des `ReceiptKind`/`CentronObjectKindNumeric` auf; `ValidateConsistency()` (Zeilen ~148–170) prüft die Symmetrie aller `CanBeForwardedInto`/`CanBeForwardedFrom`-Paare und wirft bei Verletzung eine `ApplicationException`.
|
||||
Aussage: Das System soll die Zuordnung von Belegtyp zu Verhalten über eine zentrale, beim Start selbstprüfende Registry vornehmen, um Inkonsistenzen im Übergangsmodell frühzeitig (zur Startzeit, nicht erst zur Laufzeit eines betroffenen Belegs) zu erkennen.
|
||||
Ergebnis: Eine fehlerhafte Konfiguration des Übergangsmodells verhindert den Systemstart, statt erst bei Benutzung des betroffenen Belegtyps sichtbar zu werden.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/backend/Centron.BL/Sales/Receipts/SpecificLogics.cs` (Zeilen ~148–170) - Begründung: Konkrete Konsistenzprüfmethode mit definiertem Fehlerverhalten.
|
||||
Prüfidee: Unit-Test: `ValidateConsistency()` mit absichtlich asymmetrischer Testkonfiguration aufrufen → `ApplicationException` erwarten.
|
||||
Tracelinks: SyRS-014, SwRS-002
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-004
|
||||
Titel: ReceiptState-Enum als kanonischer Belegstatus
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: System
|
||||
Vorbedingung: -
|
||||
Fakt: `src/backend/Centron.Interfaces/Sales/Receipts/ReceiptState.cs` definiert `Active`, `Completed`, `Canceled`; daneben führt die Legacy-Spiegeltabelle `Entities/DbEntities/AufKopf.cs` ein rein numerisches Feld `Status` (int?, kein Enum-Typ) sowie ein zusätzliches Feld `FreigabeStatus` (Freigabe-/Genehmigungsstatus) parallel.
|
||||
Aussage: Das System soll den Verarbeitungsstatus eines Belegs über ein einziges, typsicheres Enum abbilden; aktuell existiert dieses Enum nur auf der modernen Entitätsebene, während die Legacy-Tabellenebene weiterhin einen unabhängigen, nicht typsicheren Integer-Status führt.
|
||||
Ergebnis: `[HYPOTHESE]` Es ist unklar, ob und wie `ReceiptState` und das Legacy-`AufKopf.Status`-Feld bei jeder Statusänderung synchron gehalten werden oder ob beide Felder unabhängig fortgeschrieben werden können. Zur Bestätigung fehlt eine Codeanalyse der `SaveReceipt*Repository`-Synchronisationsmethoden (`SynchronizeReceiptData`) auf Statusabgleich.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/backend/Centron.Interfaces/Sales/Receipts/ReceiptState.cs`, `src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs` (Statuszuweisungen) - Begründung: Belegt das moderne Enum und dessen Verwendung.
|
||||
- [PRIMÄR] `src/backend/Centron.Entities/Entities/DbEntities/AufKopf.cs` (Feld `Status`, `FreigabeStatus`, int?) - Begründung: Belegt das parallel existierende, nicht typisierte Legacy-Statusfeld.
|
||||
Prüfidee: Beleg-Statuswechsel auslösen und beide Felder (`ReceiptState` auf modernem Entity, `Status` in Legacy-Tabelle `AufKopf`) per SQL-Abfrage vergleichen.
|
||||
Tracelinks: SyRS-013
|
||||
Konsolidierung: Kandidat: Konsolidierung von `ReceiptState`-Enum und Legacy-`Status`/`FreigabeStatus`-Feldern zu einem einzigen Statusmodell im Zielsystem.
|
||||
Status: HYPOTHESE
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-005
|
||||
Titel: Kopf/Pos/Versions-Tabellenschema je Belegtyp
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: System
|
||||
Vorbedingung: -
|
||||
Fakt: Je Belegtyp existiert ein Tripel aus Legacy-Tabelle (`*Kopf`/`*Pos`), Versionstabelle (`*KopfVersions`/`*PosVersions`, exakte 1:1-Struktur) und moderner View (`Offers`, `OfferItems`, `OfferVersions`, `OfferItemVersions` usw., analog für alle sieben Belegtypen).
|
||||
Aussage: Das System soll für jeden Belegtyp ein durchgängiges Dreifach-Schema aus operativer Tabelle, Versionshistorie und lesefreundlicher View pflegen; beim Hinzufügen einer neuen Spalte müssen alle zehn in der Dokumentation genannten Stellen (Basistabelle, Versionstabelle, beide Views, Entity, Mapping, temporäre Legacy-Entity/-Mapping, `SaveReceipt*Repository`, DTO/Interfaces) konsistent aktualisiert werden.
|
||||
Ergebnis: Fehlt eine dieser zehn Anpassungen, tritt laut Dokumentation ein Laufzeitfehler beim Speichern der Versionshistorie auf, oder ein Feld wird beim Laden angezeigt, aber beim Speichern verworfen.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/receipts/receipts-backend-architecture.md` (Abschnitt "Adding New Columns - Complete Checklist", "Critical Save Warning") - Begründung: Explizit dokumentierte, technisch erzwungene Konsistenzkette mit zwei unterschiedlichen Fehlermodi.
|
||||
Prüfidee: Neue Spalte nur in Basistabelle und modernem Entity hinzufügen (bewusst unvollständig) → Speichern über `SaveReceipt*Repository` muss den Wert NICHT persistieren (Nachweis des dokumentierten Fehlerbilds).
|
||||
Tracelinks: SyRS-015, SyRS-016
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-006
|
||||
Titel: SaveReceipt*Repository als zusätzlicher Legacy-Persistenzpfad
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: System
|
||||
Vorbedingung: Beleg wird gespeichert.
|
||||
Fakt: Belegspeicherung läuft nicht ausschließlich über das moderne NHibernate-Entity-Mapping, sondern zusätzlich über `SaveReceipt*Repository`-Klassen (z. B. `SaveReceiptContractRepository`, `SaveReceiptInvoiceRepository`), die Werte explizit in temporäre Legacy-Tabellenentities synchronisieren (`SynchronizeReceiptData` für Kopf-, `SynchronizeReceiptItemData` für Positionsfelder).
|
||||
Aussage: Das System soll sicherstellen, dass jedes persistierte Belegfeld sowohl über das moderne Entity-Mapping als auch über den Legacy-Repository-Pfad korrekt geschrieben wird, da beide Pfade beim Speichern gemeinsam wirken.
|
||||
Ergebnis: Ein Feld, das nur im modernen Mapping, nicht aber im Repository-Pfad berücksichtigt ist, wird beim Laden angezeigt, geht aber beim erneuten Speichern verloren.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/receipts/receipts-backend-architecture.md` (Abschnitt "Critical Save Warning") - Begründung: Explizit als kritische, tatsächlich beobachtete Fehlerquelle dokumentiert.
|
||||
Prüfidee: End-to-End-Test gemäß Empfehlung der Dokumentation: Feld setzen, speichern, Beleg neu laden, Rohwert in Legacy-Tabelle per SQL prüfen.
|
||||
Tracelinks: SyRS-015, SwRS-005
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-007
|
||||
Titel: ReceiptPriceHelperBL zentrale Preis-/Steuerberechnung
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Belegposition mit Menge, Basispreis, Rabatt und Steuersatz liegt vor.
|
||||
Fakt: `ReceiptPriceHelperBL` (`src/backend/Centron.BL/Sales/Receipts/ReceiptPriceHelperBL.cs`) stellt `CalculateReceiptPrices()`, `CalculateReceiptVatPrices()` (Netto-/Brutto-Split je Steuersatz) und mehrere Überladungen von `CalculateReceiptItemPrices()`/`CalculateReceiptItemBasePrice()` bereit.
|
||||
Aussage: Das System soll die Berechnung von Positions- und Belegsummen (netto, Steuer, brutto, je nach Steuersatzgruppe getrennt) zentral in einer wiederverwendbaren Berechnungskomponente kapseln, statt sie in jedem Belegtyp separat zu implementieren.
|
||||
Ergebnis: Alle Belegtypen berechnen Summen nach identischer Logik; eine Änderung der Rundungs- oder Rabattregel wirkt einheitlich für alle Belegtypen.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/backend/Centron.BL/Sales/Receipts/ReceiptPriceHelperBL.cs` (laut Agentenrecherche der BL-Schicht, konkrete Methodensignaturen) - Begründung: Zentrale, tatsächlich vorhandene Berechnungsklasse.
|
||||
Prüfidee: Beleg mit gemischten Steuersätzen (7 %/19 %) anlegen; Summenberechnung je Steuersatzgruppe manuell nachrechnen und mit Systemergebnis vergleichen.
|
||||
Tracelinks: StRS-008, SyRS-013
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-008
|
||||
Titel: TaxBL effektivdatierte Steuersatzkette
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: System
|
||||
Vorbedingung: Steuersatzänderung (z. B. gesetzliche MwSt-Änderung) ist im System hinterlegt.
|
||||
Fakt: `TaxBL.GetTaxRateChain(taxRateI3D)` und `GetTaxRateForReceiptItem(taxRateI3D, receiptDate, articleI3D)` lösen den zum Belegdatum gültigen Steuersatz anhand einer historisierten Steuersatzkette auf, statt immer den aktuellen Satz zu verwenden.
|
||||
Aussage: Das System soll bei rückwirkender oder historischer Belegbearbeitung stets den zum jeweiligen Belegdatum gesetzlich gültigen Steuersatz anwenden, auch wenn sich der Steuersatz zwischenzeitlich geändert hat.
|
||||
Ergebnis: Ein am 30.06. erfasster Beleg verwendet auch nach einer zum 01.07. wirksamen Steuersatzänderung weiterhin den bis 30.06. gültigen Satz.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/backend/Centron.BL/Warehousing/TaxBL.cs` (`GetTaxRateChain`, `GetTaxRateForReceiptItem`) - Begründung: Konkrete, datumsparametrisierte Methode zur historisierten Steuersatzauflösung.
|
||||
Prüfidee: Steuersatzänderung zu einem Stichtag anlegen; Beleg mit Datum vor und nach dem Stichtag erzeugen und jeweils angewandten Steuersatz prüfen.
|
||||
Tracelinks: StRS-008, SyRS-013, SwRS-007
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-009
|
||||
Titel: Kontingent-Berechnung in ContractBL/ContractSpecificLogic
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Vertrag mit Kontingent ist angelegt.
|
||||
Fakt: `ReceiptContractBL.ContractContingentBalanceCalculation()`, `CalculateContingentWithRecalculationArticle()`, `UpdateContractContingentBalanceCalculationForReceiptChange()` und `UpdateTakeRestAndOverBooking()` berechnen Kontingentverbrauch, Restwerte und Überbuchungsfälle.
|
||||
Aussage: Das System soll bei jeder abrechnungsrelevanten Änderung eines Vertragsbelegs (z. B. Mengenänderung) automatisch die betroffenen Kontingentsalden (verbrauchte Stunden/Beträge, Restwert) neu berechnen.
|
||||
Ergebnis: Eine nachträgliche Änderung einer Vertragsposition führt zu einer konsistenten Neuberechnung des Kontingentsaldos, inklusive korrekter Behandlung von Restwert- und Überbuchungsfällen.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/receipts/contracts-backend.md` (konkrete Methodenliste `ReceiptContractBL`) - Begründung: Dokumentierte, im Code vorhandene Berechnungsmethoden.
|
||||
Prüfidee: Vertrag mit Kontingent 10h anlegen, 4h verbrauchen, Position nachträglich auf 6h Verbrauch ändern; Kontingentsaldo muss korrekt auf 4h Rest aktualisiert werden.
|
||||
Tracelinks: StRS-003, StRS-004
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-010
|
||||
Titel: RMM-Artikel-Abrechnung via RiverConnectionBL
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Vertrag mit `WhetherRMM=true` und konfigurierten `ContractArticleReferenzes`.
|
||||
Fakt: Während `CreateInvoiceToContractComplete` ruft `CheckRMMArticle` die Methode `RiverConnectionBL.GetContractBillingAmounts(from, to, customerI3D, rmmArticleReferences)` auf; das Ergebnis wird an der Position des Platzhalters `@@RMMArtikel@@` im Rechnungstext eingefügt oder, falls kein Platzhalter vorhanden, an vorletzter Position.
|
||||
Aussage: Das System soll bei der Rechnungserstellung für RMM-abrechnungspflichtige Verträge automatisiert Nutzungsdaten vom externen RMM-Dienst abrufen und als zusätzliche Rechnungsposition(en) an einer im Rechnungstext markierten oder impliziten Position einfügen.
|
||||
Ergebnis: Die erzeugte Rechnung enthält für jede Artikelreferenz mit verfügbaren Nutzungsdaten eine berechnete Position mit erläuterndem Text.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/receipts/Contract-Billing-RMM-Article-Logic.md` (Codebeispiel `rmmItem = invoice.Items.FirstOrDefault(...)`, `RiverConnectionBL.GetContractBillingAmounts(...)`) - Begründung: Konkreter, zitierter Quellcodeausschnitt.
|
||||
Prüfidee: Rechnung für RMM-Vertrag mit Platzhalter `@@RMMArtikel@@` im Textbaustein erzeugen; RMM-Position muss exakt an der Platzhalterstelle erscheinen und der Platzhaltertext entfernt sein.
|
||||
Tracelinks: StRS-004, SwRS-011
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-011
|
||||
Titel: Abbruchregel bei Nichterreichbarkeit des RMM-Dienstes
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Externer RMM-Dienst ist nicht erreichbar; Vertrag erwartet RMM-Positionen.
|
||||
Fakt: Liefert `RiverConnectionBL.GetContractBillingAmounts` einen Fehlerstatus und existieren erwartete RMM-Artikelreferenzen oder ein `@@RMMArtikel@@`-Platzhalter, wird eine `RMMServiceUnavailableException` geworfen und die Rechnungserstellung abgebrochen; ohne erwartete RMM-Referenzen wird die Verarbeitung stillschweigend fortgesetzt (`return`).
|
||||
Aussage: Das System soll die Erstellung einer Rechnung mit erwarteten, aber nicht abrufbaren RMM-Nutzungsdaten zwingend verhindern, um eine fehlerhafte (zu niedrige) Abrechnung des Kunden auszuschließen.
|
||||
Ergebnis: Bei Nichterreichbarkeit des RMM-Dienstes und vorhandenem RMM-Bezug wird keine Rechnung erzeugt; stattdessen wird ein Fehler mit Diagnoseinformation geloggt.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/receipts/Contract-Billing-RMM-Article-Logic.md` (Codebeispiel mit `RMMServiceUnavailableException`, Bedingung `rmmItem != null || rmmArticleReferences.Any()`) - Begründung: Konkrete, im Code durchgesetzte Abbruchbedingung für einen abrechnungsrelevanten Vorgang (erfüllt PRIMÄR-Anforderung).
|
||||
Prüfidee: RMM-Dienst in Testumgebung deaktivieren, Rechnungserstellung für Vertrag mit RMM-Artikelreferenz auslösen → Erstellung muss mit definierter Fehlermeldung abbrechen, keine Rechnung darf im System entstehen.
|
||||
Tracelinks: StRS-004, SwRS-010
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-012
|
||||
Titel: DunningBL Mahnstufenberechnung
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Überfällige Rechnung(en) liegen vor.
|
||||
Fakt: `DunningBL.GetDunningCustomers()`, `CalculateDunningStatistics()`, `UpdateDunningSettingsForCustomer()`, `UpdateDunningStopAndInfo()` implementieren die Mahnstufenlogik inkl. Textbaustein-basierter Mahnschreiben-Generierung (`GetTextWithReplacedVariablesForCustomerEmail`).
|
||||
Aussage: Das System soll je Kunde und überfälliger Rechnung die korrekte Mahnstufe anhand konfigurierbarer Fristen berechnen und daraus automatisiert ein Mahnschreiben mit variablen Textbausteinen generieren.
|
||||
Ergebnis: Ein Kunde mit mehreren unterschiedlich lang überfälligen Rechnungen erhält eine Mahnung auf der höchsten zutreffenden Mahnstufe mit korrekt eingesetzten Variablen (Betrag, Fälligkeitsdatum).
|
||||
Belege:
|
||||
- [PRIMÄR] `src/backend/Centron.BL/Sales/Receipts/Invoices/Dunning/DunningBL.cs` (konkrete Methoden laut Agentenrecherche der BL-Schicht) - Begründung: Zentrale Mahnwesen-Klasse, ~1060 Zeilen fachlicher Logik.
|
||||
Prüfidee: Kunde mit Rechnungen unterschiedlicher Überfälligkeit anlegen, Mahnlauf ausführen, korrekte Mahnstufenzuordnung und Textvariablen prüfen.
|
||||
Tracelinks: StRS-013, SwRS-014
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-013
|
||||
Titel: Rechteschutz vor Ausführung abrechnungsrelevanter Läufe
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System
|
||||
Vorbedingung: Benutzer löst Mahnlauf oder OPOS-Lauf aus.
|
||||
Fakt: Sowohl `DunningBL.cs` (Zeile ~1059) als auch `OposBL.cs` (Zeile ~28) rufen vor Ausführung `ThrowIfUserHasInsufficentRights(LoggedInUser)` auf (Methodenname mit Tippfehler "Insufficent" im Original-Code beibehalten).
|
||||
Aussage: Das System soll vor dem Anstoßen eines Mahnlaufs oder eines Offene-Posten-Laufs zwingend prüfen, ob der auslösende Benutzer über das erforderliche Recht verfügt, und die Ausführung andernfalls mit einer Exception verhindern.
|
||||
Ergebnis: Ein Benutzer ohne das erforderliche Recht kann weder einen Mahnlauf noch einen OPOS-Lauf tatsächlich starten, unabhängig davon, ob die UI die entsprechende Schaltfläche anzeigt.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/backend/Centron.BL/Sales/Receipts/Invoices/Dunning/DunningBL.cs:1059`, `src/backend/Centron.BL/Sales/Receipts/Invoices/Opos/OposBL.cs:28` (`ThrowIfUserHasInsufficentRights`) - Begründung: Direkter, im BL-Code durchgesetzter Rechte-Check unmittelbar vor abrechnungsrelevanter Verarbeitung (PRIMÄR-Beleg für Abrechnungslogik gemäß Risikoklassifikation).
|
||||
Prüfidee: BL-Methode `RunDunning`/`RunOpos` direkt (unter Umgehung der UI) mit einem Benutzer ohne Recht aufrufen → Exception muss geworfen werden, kein Lauf darf erzeugt werden.
|
||||
Tracelinks: StRS-013, StRS-014, SyRS-011
|
||||
Konsolidierung: Kandidat: identisches Rechteschutz-Idiom in Dunning und Opos – im Zielsystem als gemeinsamer Decorator/Cross-Cutting-Concern (z. B. Attribut) statt Code-Duplikation umsetzbar.
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-014
|
||||
Titel: UserRightsConst/HasUserRight-Autorisierungsmuster
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System
|
||||
Vorbedingung: -
|
||||
Fakt: `UserRightsExt.HasUserRight(this AppUser, int rightId)` prüft ein Recht gegen die vom Benutzer geladenen Rechte; Aufrufkonvention verwendet stets Konstanten aus `UserRightsConst` (z. B. `UserRightsConst.Sales.Customer.CustomerCommon.CREATE_CUSTOMER`) statt numerischer Literale; 318 Aufrufstellen in 93 Dateien der BL-Schicht.
|
||||
Aussage: Das System soll jede Rechteprüfung ausschließlich über benannte Konstanten (`UserRightsConst`) und eine einheitliche Extension-Methode (`HasUserRight`) vornehmen, um Lesbarkeit und Konsistenz der Autorisierung sicherzustellen.
|
||||
Ergebnis: Eine Änderung der internen Rechte-ID erfordert keine Anpassung an den 318 Aufrufstellen, solange die Konstante unverändert bleibt.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/backend/Centron.BL/Administration/Rights/UserRightsExt.cs` - Begründung: Zentrale, tatsächlich 318-fach verwendete Methode (durch Agentenrecherche gezählt).
|
||||
- [SEKUNDÄR] `docs/guides/development/check-userrights.md` - Begründung: Dokumentiertes Verwendungsmuster mit Codebeispiel aus `AccountBL.cs`.
|
||||
Prüfidee: Statische Codeprüfung: Keine direkte numerische Rechte-ID (Literal) in einem `HasUserRight`-Aufruf ohne `UserRightsConst`-Referenz.
|
||||
Tracelinks: StRS-016, SyRS-011
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-015
|
||||
Titel: AppRightsBL zentrale Rechteverwaltung
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Administrator
|
||||
Vorbedingung: -
|
||||
Fakt: `AppRightsBL` bietet `GetAllRights()`, `GetAllRightGroups(AppUser)`, `GetRightsFromCurrentUser(AppUser)`, `CheckRightsFromUser(currentUserI3D, rightIds)`; `AppUserGroupBL` verwaltet Gruppen-Rechte-Zuordnungen.
|
||||
Aussage: Das System soll Rechtevergabe strukturiert über Gruppen ermöglichen, wobei einem Benutzer über seine Gruppenzugehörigkeit(en) ein aggregiertes Rechteset zugeordnet wird.
|
||||
Ergebnis: Ein Benutzer erhält alle Rechte, die einer seiner zugeordneten Gruppen zugewiesen sind (Vereinigungsmenge).
|
||||
Belege:
|
||||
- [PRIMÄR] `src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs`, `AppUserGroupBL.cs` - Begründung: Konkrete, zentrale Rechteverwaltungsklassen laut Agentenrecherche.
|
||||
Prüfidee: Benutzer zwei Gruppen mit unterschiedlichen Rechten zuordnen; `GetRightsFromCurrentUser` muss die Vereinigungsmenge beider Gruppenrechte liefern.
|
||||
Tracelinks: StRS-016, SwRS-014, SwRS-016
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-016
|
||||
Titel: Skriptbasierte Rechtevergabe über die Sichrech-Tabelle
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: Entwickler (bei Erweiterung), System (Migration)
|
||||
Vorbedingung: Neues Recht soll eingeführt werden.
|
||||
Fakt: Neue Rechte werden über Migrationsskripte in die Tabelle `Sichrech` eingefügt (`I3D`, `Text`, `OwnerRecht`, `NumChildren`, `Beschreibung`); empfohlener Weg ist `ScriptHelpers.AddRightIfNotExists(...)`, das zusätzlich den `NumChildren`-Zähler des übergeordneten Rechts konsistent hochzählt.
|
||||
Aussage: Das System soll neue Berechtigungen ausschließlich über den standardisierten Migrationsmechanismus in die zentrale Rechtetabelle einfügen, inklusive korrekter Pflege der Eltern-Kind-Beziehung (`OwnerRecht`/`NumChildren`).
|
||||
Ergebnis: Ein neu eingeführtes Recht erscheint korrekt eingeordnet in der Rechtebaum-Hierarchie der Rechteverwaltung, ohne dass der `NumChildren`-Zähler des Elternrechts manuell inkonsistent gepflegt werden muss.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/guides/development/add-a-new-right.md` (konkretes SQL-Beispiel `INSERT INTO Sichrech`, `ScriptHelpers.AddRightIfNotExists`) - Begründung: Verbindlich dokumentierter, im Code umgesetzter Mechanismus.
|
||||
Prüfidee: Neues Recht per `AddRightIfNotExists` unterhalb eines bestehenden Elternrechts anlegen; `NumChildren` des Elternrechts muss automatisch um 1 erhöht sein.
|
||||
Tracelinks: StRS-016, SwRS-015, SyRS-017
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-017
|
||||
Titel: TicketAuthenticationHandler
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System
|
||||
Vorbedingung: Anfrage enthält `Authorization: Bearer <ticket>` oder Query-Parameter `access_token`.
|
||||
Fakt: `TicketAuthenticationHandler` (Default-Authentifizierungsschema) validiert das Ticket gegen `AuthenticationTicketBL.GetAuthTicketInfo` und erstellt bei Erfolg einen `ClaimsPrincipal`; Ticket-Erstellung protokolliert IP-Adresse und angefragte API-Methode.
|
||||
Aussage: Das System soll jede eingehende Anfrage anhand eines gültigen, in der Datenbank hinterlegten Tickets authentifizieren und dabei IP-Adresse sowie aufgerufene Methode zu Prüfzwecken protokollieren.
|
||||
Ergebnis: Eine Anfrage ohne gültiges Ticket wird mit 401 abgelehnt; jede erfolgreiche Authentifizierung ist mit IP und Methode nachvollziehbar.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/webservice/Centron.Host/AspNetCore/TicketAuthenticationHandler.cs` - Begründung: Konkrete Handler-Implementierung laut Agentenrecherche.
|
||||
Prüfidee: Anfrage mit manipuliertem/gefälschtem Ticket senden → 401; erfolgreiche Anfrage im Audit-Log mit korrekter IP/Methode wiederfinden.
|
||||
Tracelinks: SyRS-007
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-018
|
||||
Titel: OpenIdConnectAuthenticator (oid-Claim-Lookup)
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System
|
||||
Vorbedingung: Gültiges Microsoft-ID-Token liegt vor.
|
||||
Fakt: `OpenIdConnectAuthenticator` extrahiert den `oid`-Claim aus dem validierten JWT und sucht den zugehörigen Benutzer über `OpenIdConnectSubjectIdentifier` in der Tabelle `Sichbenu`; `AuthenticatorFactory` routet abhängig von `SystemAuthenticationMethod` (0=Any, 3=OpenIdConnect) dorthin.
|
||||
Aussage: Das System soll die Zuordnung eines extern authentifizierten Microsoft-Kontos zu einem c-entron-Benutzerkonto ausschließlich über die eindeutige, unveränderliche Entra-Object-ID (`oid`) vornehmen, nicht über E-Mail-Adresse oder Anzeigenamen.
|
||||
Ergebnis: Eine Änderung der E-Mail-Adresse oder des Anzeigenamens im Microsoft-Konto hat keinen Einfluss auf die Benutzerzuordnung.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/security/anmelden-mit-microsoft-technische-anleitung.md` (Codebeispiel `identity.Claims.FirstOrDefault(c => c.Type == "oid")`, konkreter Dateipfad `OpenIdConnectAuthenticator.cs`) - Begründung: Konkrete, code-referenzierte Zuordnungslogik.
|
||||
Prüfidee: E-Mail-Adresse des verknüpften Microsoft-Kontos ändern; Anmeldung muss weiterhin denselben c-entron-Benutzer zuordnen.
|
||||
Tracelinks: SyRS-008
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-019
|
||||
Titel: JWT-Bearer-Validierung (Issuer/Audience/Lifetime/Signatur)
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System
|
||||
Vorbedingung: JWT-Authentifizierung ist konfiguriert (`JwtAuthority`/`JwtAudience`).
|
||||
Fakt: `CentronHost.cs` konfiguriert `AddJwtBearer(...)` mit Validierung von Issuer, Audience, Lifetime und Signatur, `ValidateTokenReplay = true`; Fehlschläge werden inkl. Header/Payload über `LoggingJwtBearerEvents` protokolliert.
|
||||
Aussage: Das System soll eingehende JWTs vollständig gegen Aussteller, Empfänger, Gültigkeitszeitraum und kryptografische Signatur validieren und zusätzlich Replay-Angriffe durch Token-Wiederverwendung verhindern.
|
||||
Ergebnis: Ein abgelaufenes, mit falschem Schlüssel signiertes oder bereits verwendetes Token wird abgelehnt und der Vorgang protokolliert.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/webservice/Centron.Host/CentronHost.cs` (Zeilen ~184–205) - Begründung: Konkrete Validierungsparameter im Code laut Agentenrecherche.
|
||||
Prüfidee: Manipuliertes JWT (falsche Signatur, abgelaufen, wiederverwendet) gegen `POST /jwt/login` senden → Ablehnung in allen drei Fällen, mit Log-Eintrag.
|
||||
Tracelinks: SyRS-008
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-020
|
||||
Titel: AccessTokensController (Personal Access Tokens)
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Benutzer, externe Anwendung
|
||||
Vorbedingung: Benutzer ist per JWT authentifiziert.
|
||||
Fakt: `AccessTokensController` (nur `[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]`) bietet `GET my`, `GET {id}`, `GET {id}/logs`, `GET {id}/statistics`, `POST my`, `PUT {id}`, `PUT {id}/deactivate|activate`, `DELETE {id}`.
|
||||
Aussage: Das System soll persönliche API-Zugriffstoken ausschließlich über einen eigenen, JWT-geschützten Verwaltungsendpunkt erzeugen, deaktivieren und deren Nutzung protokollieren lassen.
|
||||
Ergebnis: Ein deaktivierter Token wird sofort für alle nachfolgenden API-Aufrufe ungültig, unabhängig vom bisherigen Ablaufdatum.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/webservice/Centron.Controllers/Controllers/v1/Administration/AccessTokensController.cs` - Begründung: Konkrete Endpunktliste laut Agentenrecherche.
|
||||
Prüfidee: Access Token erstellen, erfolgreichen API-Aufruf durchführen, Token per `PUT {id}/deactivate` deaktivieren, identischen Aufruf wiederholen → Ablehnung.
|
||||
Tracelinks: SyRS-009
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-021
|
||||
Titel: LicenseManager/LicenseGuids/ApplicationKind
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System
|
||||
Vorbedingung: -
|
||||
Fakt: `LicenseGuids.cs` listet alle vergebenen Lizenz-GUIDs (Applications und Einzelfunktionen); `ApplicationKind.cs` listet die Teilmenge, die zum Login am Webservice berechtigt (dort werden `count`, `valid until date`, `valid until version` automatisch geprüft); `LicenseManager.Instance.HasLicense(guid)`/`GetLicenseCount(guid)` sind die zentralen Prüfmethoden.
|
||||
Aussage: Das System soll zwischen login-berechtigenden "Applications" und reinen Feature-Lizenzen technisch unterscheiden und für Applications automatisch Mengen-, Zeit- und Versionsgrenzen durchsetzen, für einfache Feature-Lizenzen hingegen nur eine Ja/Nein-Prüfung anbieten.
|
||||
Ergebnis: Eine Anwendung, die nicht in `ApplicationKind.cs` gelistet ist, kann sich nicht am Webservice anmelden, selbst wenn eine gültige Lizenz-GUID vorliegt.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/security/licensing-system.md` - Begründung: Vollständig dokumentiertes, im Code verwendetes Unterscheidungsmuster mit konkreten Dateinamen.
|
||||
Prüfidee: Lizenz-GUID, die nur in `LicenseGuids.cs`, nicht aber in `ApplicationKind.cs` gelistet ist, für einen Login-Versuch verwenden → Ablehnung.
|
||||
Tracelinks: StRS-017, SyRS-018
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-022
|
||||
Titel: ApplicationSettings/Stammdat Dual-Table-Konfigurationszugriff
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: Entwickler, System
|
||||
Vorbedingung: -
|
||||
Fakt: Legacy-Einstellungen liegen in `Stammdat` (Zugriff über `AppSettingsConst`, `AppSettingsBL.GetSettings(AppSettingsConst)`), neue Einstellungen ausschließlich in `ApplicationSettings` (Zugriff über `ApplicationSettingID`, `ApplicationSettingDefinitions`); Zugriff stets über typisierte Gruppen-Settings-Klassen, nie direkt auf die Tabellen.
|
||||
Aussage: Das System soll neue Konfigurationseinstellungen ausschließlich in der aktuellen `ApplicationSettings`-Tabelle mit eindeutiger, fortlaufend vergebener ID und dokumentierter Beschreibung anlegen; die Legacy-`Stammdat`-Tabelle wird nur noch gelesen, nicht erweitert.
|
||||
Ergebnis: Jede neue Einstellung ist über eine eindeutige `ApplicationSettingID` mit zugehöriger Beschreibung in `ApplicationSettingDefinitions.cs` auffindbar; kein direkter SQL-Zugriff auf die Einstellungstabellen durch den Client.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/guides/development/settings-management.md` (Codebeispiele `AppSettingsBL.GetSettings`, `GetSettingsForUpdate`) - Begründung: Verbindlich dokumentiertes, im Code umgesetztes Konfigurationsmuster.
|
||||
Prüfidee: Neue Einstellung mit nächster freier ID gemäß Kommentar in `ApplicationSettingID.cs` anlegen, Lese-/Schreibzugriff über `AppSettingsBL` prüfen.
|
||||
Tracelinks: SyRS-016
|
||||
Konsolidierung: Kandidat: Doppelte Konfigurationsablage (`Stammdat` vs. `ApplicationSettings`) ist ein expliziter Migrationskandidat für das Zielsystem.
|
||||
Status: belegt; Workaround
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-023
|
||||
Titel: ScriptMethod/ScriptHelpers Migrationsklassen
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: System (Anwendungsstart)
|
||||
Vorbedingung: Neue Anwendungsversion enthält neue Skripte.
|
||||
Fakt: 764 Klassen `ScriptMethod<Nummer>.cs` implementieren `BaseScriptMethod.GetSqlQueries()`; `ScriptHelpers.cs` erzeugt idempotente DDL (`AddTableIfNotExists`, `AddColumnIfNotExists`, `AddForeignKeyIfNotExists`, `AddIndexIfNotExists`, `ChangeColumnTypeIfExists`); `AddTableIfNotExists` erzeugt automatisch die `I3D`-Primärschlüsselspalte.
|
||||
Aussage: Das System soll beim Start automatisch alle noch nicht ausgeführten, nach Skriptnummer sortierten Migrationsskripte anwenden und dabei stets die generierenden Hilfsmethoden (`ScriptHelpers`) statt handgeschriebener DDL verwenden, um Idempotenz sicherzustellen.
|
||||
Ergebnis: Ein wiederholter Start mit bereits angewendeten Skripten führt zu keiner erneuten Änderung oder Fehlermeldung (Idempotenz durch `IF NOT EXISTS`-Prüfungen).
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/database/script-rules.md`, `docs/guides/database/create-scripts.md` - Begründung: Verbindlich dokumentierter Mechanismus mit konkreten Beispielskripten (`ScriptMethod11699.cs` u. a.).
|
||||
Prüfidee: Anwendung zweimal hintereinander gegen dieselbe (bereits migrierte) Datenbank starten; zweiter Start darf keine SQL-Fehler und keine erneuten Schemaänderungen erzeugen.
|
||||
Tracelinks: SyRS-017
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-024
|
||||
Titel: Fluent-NHibernate-Mapping-Konventionen
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: Entwickler
|
||||
Vorbedingung: -
|
||||
Fakt: Jede Entität besitzt eine zugehörige `ClassMap<T>`-Klasse unter `Centron.DAO/Mappings/`, die Tabelle, ID und alle Eigenschaften explizit mit `.Not.Nullable()`/`.Length(n)` beschreibt; ca. 600+ Mapping-Klassen im Repository.
|
||||
Aussage: Das System soll jede persistierte Eigenschaft explizit (nicht implizit über NHibernate-Konvention) hinsichtlich Spaltenname, Nullbarkeit und Länge abbilden, um Diskrepanzen zwischen Datenbankschema und Objektmodell zu vermeiden.
|
||||
Ergebnis: Eine über NHibernate gespeicherte Entität erzeugt exakt die im Mapping deklarierte Spaltenstruktur, ohne stillschweigende Konventionsannahmen.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/architecture/dtos-and-entities.md` (Codebeispiel `ThingyMaps : ClassMap<Thingy>`) - Begründung: Verbindlich dokumentiertes Mapping-Muster.
|
||||
- [PRIMÄR] Agentenrecherche `Centron.DAO`: ca. 600+ `*Maps.cs`-Dateien unter `Mappings/` - Begründung: Tatsächlicher Umfang des Musters im Code.
|
||||
Prüfidee: Neue Entität ohne explizite Längenangabe in einem Mapping anlegen und Abweichung vom tatsächlichen DB-Schema als Codereview-Fehler identifizieren.
|
||||
Tracelinks: SyRS-016
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-025
|
||||
Titel: GenericStoredProcedureDAO als Rohzugriffs-Fallback
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: System
|
||||
Vorbedingung: Eine Operation ist mit reinem NHibernate-Mapping nicht praktikabel (z. B. komplexe Reporting-Abfrage, Massenoperation).
|
||||
Fakt: `GenericStoredProcedureDAO`/`RawSqlAccessDAO` bieten `GetRawSqlResult`, `ExecuteSqlScalarWithIntResult`, `CreateSQLQuery(...).ExecuteUpdate()` als expliziten Rohzugriffspfad neben dem generischen NHibernate-CRUD (`GenericDAO`); ein umfangreicher externer Abfragekatalog (`NamedQueryPool.xml`, 11.477 Zeilen) hält parametrisierte SQL-/HQL-Abfragen vor.
|
||||
Aussage: Das System soll für performancekritische oder mit dem ORM nicht abbildbare Datenzugriffe einen kontrollierten Rohzugriffspfad (parametrisierte Named Queries bzw. direkte SQL-Ausführung) bereitstellen, statt das ORM in solchen Fällen zu erzwingen.
|
||||
Ergebnis: Komplexe Reporting- und Massenverarbeitungs-Abfragen laufen performant über parametrisierte Rohabfragen, ohne die NHibernate-Session-Semantik zu verletzen.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/backend/Centron.DAO/GenericStoredProcedureDAO.cs`, `AdoNETDataAccess/RawSqlAccessDAO.cs`, `NamedQueries/NamedQueryPool.xml` - Begründung: Konkrete, umfangreiche Rohzugriffsschicht laut Agentenrecherche der DAO-Schicht.
|
||||
- [KONTEXT] `src/backend/Centron.DAO/TradePool/TradePoolDAO.cs:21` (`"EXECUTE dbo.spInsertNewArticle ..."`, stringverkettet, unparametrisiert) - Begründung: Als Negativbeispiel/Risikohinweis dokumentiert (siehe Analysebericht), nicht als durchgesetzte Regel.
|
||||
Prüfidee: Alle Verwendungsstellen von `RawSqlAccessDAO`/`GenericStoredProcedureDAO` auf konsequente Parametrisierung prüfen (keine Stringverkettung von Benutzereingaben).
|
||||
Tracelinks: SyRS-016
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-026
|
||||
Titel: SupplierEdiBL Partial-Klassen je Lieferant
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: -
|
||||
Fakt: `SupplierEdiBL` ist als `partial class` über mehrere Dateien (`SupplierEdiBL.AlsoCH.cs`, `.Also.cs`, `.Alltron.cs`, `.Herweck.cs`, `.Komsa.cs`, `.Opentrans.cs`) organisiert; zentrale Dispatch-Methode `ApplyDistriToCentron` routet je nach `EdiDataType` und `ObjectKind` in die passende lieferantenspezifische Parsing-Methode.
|
||||
Aussage: Das System soll lieferantenspezifische EDI-Parsing- und Mapping-Logik über das Partial-Class-Muster organisieren, sodass eine gemeinsame Klassenschnittstelle nach außen besteht, während die Implementierung je Lieferant isoliert wartbar bleibt.
|
||||
Ergebnis: Eine Änderung an der ALSO-CH-spezifischen Verarbeitung (z. B. Swiss-ESR-Handling) wirkt sich nicht auf andere Lieferantenformate aus.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/edi/edi-architecture.md` (Abschnitt "Partial Class Architecture", konkrete Dateiliste) - Begründung: Dokumentierte Klassenstruktur mit Codebeispiel.
|
||||
Prüfidee: EDI-Datei im ALSO-CH-Format mit Swiss-ESR-Code verarbeiten und prüfen, dass andere Lieferantenformate (z. B. Herweck) unverändert funktionieren (Regressionstest).
|
||||
Tracelinks: StRS-006, SyRS-021
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-027
|
||||
Titel: EdiDataType/EDIConnectionObjectKind-Enums
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: System
|
||||
Vorbedingung: -
|
||||
Fakt: `EdiDataType` (OpenTrans21=1, Also=2, AlsoCH=3, Herweck=4, Komsa=5, Alltron=6, Zugferd=7) und `EDIConnectionObjectKind` (Order=1, OrderResponse=2, Delivery=3, Invoice=4) steuern zusammen mit `SupplierEdiConfigurations` (`SupplierI3D`, `EdiDataType`, `ObjectKind`, `ConnectionString`), welcher Parser für welches Dokument einer Lieferantenkonfiguration verwendet wird.
|
||||
Aussage: Das System soll die Kombination aus Lieferant, Datenformat und Dokumenttyp eindeutig über zwei orthogonale Enums konfigurierbar machen, sodass ein Lieferant potenziell mehrere Formate/Dokumenttypen parallel nutzen kann.
|
||||
Ergebnis: Für denselben Lieferanten können z. B. Bestellantworten im ALSO-Format und Rechnungen im ZUGFeRD-Format parallel konfiguriert und verarbeitet werden.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/edi/edi-architecture.md` (Enum-Definitionen im Original-Code zitiert) - Begründung: Direkte Übernahme der Enum-Deklarationen aus dem Quellcode laut Dokumentation.
|
||||
Prüfidee: Lieferantenkonfiguration mit zwei unterschiedlichen `EdiDataType`/`ObjectKind`-Kombinationen anlegen und getrennte, korrekte Verarbeitung beider Dokumentarten prüfen.
|
||||
Tracelinks: SwRS-026
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-028
|
||||
Titel: EDI-Dateiblacklist-Mechanismus
|
||||
Ebene: SwRS
|
||||
Typ: nicht-funktional (Zuverlässigkeit, ISO 25010)
|
||||
Akteur: System
|
||||
Vorbedingung: EDI-Datei ist mehrfach fehlgeschlagen.
|
||||
Fakt: `GetDownloadWithError(distributorI3D, objectKind)` zählt fehlgeschlagene Verarbeitungsversuche je Dateiname aus `EDIManagementLog` (Status `Exception`); Dateien mit mehr als drei Fehlversuchen werden in nachfolgenden Downloadzyklen (`Ftp_DownloadAsync`/`sFtp_DownloadAsync`) explizit übersprungen (`if (badFiles.Any(f => f.Value.Contains(file.Name))) continue;`).
|
||||
Aussage: Das System soll pro EDI-Datei die Anzahl fehlgeschlagener Verarbeitungsversuche zählen und die Datei nach Überschreiten eines Schwellenwerts (3 Fehlversuche) von weiteren automatischen Verarbeitungsversuchen ausschließen.
|
||||
Ergebnis: Eine dauerhaft defekte Datei blockiert nicht wiederholt Systemressourcen und Log-Volumen durch endlose erneute Verarbeitungsversuche.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/edi/edi-import-rules.md` (konkrete SQL-Abfrage und Codezeile `badFiles.Where(f => f.ID > 3)`) - Begründung: Direkt zitierter Quellcode mit konkretem Schwellenwert.
|
||||
Prüfidee: Testdatei erzeugen, die 4-mal hintereinander eine Exception auslöst; Datei darf beim 5. Downloadzyklus nicht mehr verarbeitet werden, bleibt aber im Log sichtbar.
|
||||
Tracelinks: SyRS-022
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-029
|
||||
Titel: InvoiceZugferdBL Feldmapping-Engine
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Rechnung/Gutschrift ist final erstellt.
|
||||
Fakt: `InvoiceZugferdBL.cs` (`GenerateZugferdFile`, Zeilen 117-158; `GetZugferdExportItem`, Zeilen 237-434; `DoGenerateZugferdXRechnungXmlDocument`, Zeilen 727-750; `GetTaxCategoryCode`/`GetTaxExemptionReason`, Zeilen 1369-1400) mappt interne Belegfelder (`IBookKeepingReceipt`, `ReceiptReceiver`, `BookKeepingReceiptItem`, `Mandator`, `Branch`) auf die ZUGFeRD-/XRechnung-XML-Struktur inkl. Steuerkategorie-Ableitung und Bankverbindungsauswahl.
|
||||
Aussage: Das System soll die vollständige Ableitung aller ZUGFeRD-/XRechnung-Pflichtfelder (Verkäufer, Käufer, Steuerkategorien, Zahlungsbedingungen, Positionsdaten) aus den internen Belegentitäten in einer zentralen, versionsfähigen Mapping-Komponente kapseln.
|
||||
Ergebnis: Für jede unterstützte ZUGFeRD-/XRechnung-Version wird aus denselben internen Belegdaten eine versionskonforme XML-Struktur erzeugt.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/zugferd-field-mapping.md` (vollständige Feld-für-Feld-Mapping-Tabelle mit exakten Codezeilenreferenzen) - Begründung: Höchster Detailgrad der verfügbaren Dokumentation, direkte Zeilenverweise auf Quellcode.
|
||||
Prüfidee: Rechnung mit Skonto-Zahlungsbedingung erzeugen; generierte XML muss BR-DE-18-konforme Skonto-Beschreibung inkl. korrekter Zeilenumbrüche (`
`) enthalten.
|
||||
Tracelinks: StRS-015, SyRS-023, SyRS-024
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-030
|
||||
Titel: EbInterfaceLogic (österreichisches Rechnungsformat)
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Rechnung für österreichischen Kunden/Mandanten ist zu exportieren.
|
||||
Fakt: `Centron.Api.EbInterface/EbInterfaceLogic.cs` konvertiert eine interne `ReceiptInfo` in ebInterface-4.3-konforme XML (Namespace `http://www.ebinterface.at/schema/4p3/`).
|
||||
Aussage: Das System soll für den österreichischen Markt Rechnungen zusätzlich zum ZUGFeRD-Format im landesspezifischen ebInterface-Standard exportieren können.
|
||||
Ergebnis: Eine für den österreichischen E-Rechnungsversand vorgesehene Rechnung kann als ebInterface-konforme Datei erzeugt werden.
|
||||
Belege:
|
||||
- [SEKUNDÄR] `src/apis/Centron.Api.EbInterface/EbInterfaceLogic.cs` - Begründung: Eigenständige, klar abgegrenzte Konverterklasse laut Agentenrecherche.
|
||||
Prüfidee: Rechnung exportieren und resultierende XML gegen das ebInterface-4.3-XSD-Schema validieren.
|
||||
Tracelinks: StRS-015
|
||||
Konsolidierung: Kandidat: ZUGFeRD- (SwRS-029) und ebInterface-Export (SwRS-030) bilden zwei unabhängige Implementierungen für die fachlich verwandte Aufgabe "elektronische Rechnung erzeugen" – im Zielsystem auf eine gemeinsame E-Invoicing-Abstraktion mit länderspezifischen Profilen konsolidierbar.
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-031
|
||||
Titel: ScheduleBL.SyncByGraphV2/SyncOldSchedule
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Exchange-Online-Anbindung ist aktiv.
|
||||
Fakt: `ExchangeSyncService` (`src/webservice/Centron.Host/AspNetCore/HostedServices/ExchangeSyncService.cs`) ruft im Standardintervall von 60 Sekunden `ScheduleBL.SyncByGraphV2()` (Outlook→Nexus, Microsoft-Graph-Delta-Abfrage) und `ScheduleBL.SyncOldSchedule()` (Nexus→Outlook, für Termine ohne `MailEntryID`) auf.
|
||||
Aussage: Das System soll Terminänderungen zwischen c-entron und Exchange Online über einen inkrementellen Delta-Abgleich (Microsoft Graph Delta-Query) synchronisieren, um nicht bei jedem Zyklus den vollständigen Kalender neu abfragen zu müssen.
|
||||
Ergebnis: Nur seit dem letzten Abgleich geänderte Termine werden übertragen; ein vollständiger Kalenderabgleich erfolgt nur bei Erstsynchronisation.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/features/exchange-sync-bugprotokoll.md` (Abschnitt "Sync-Architektur") - Begründung: Konkrete Methodennamen und Architekturbeschreibung mit Dateipfad.
|
||||
Prüfidee: Einzelnen Termin in Outlook ändern und Netzwerkverkehr/Log des nächsten Sync-Zyklus prüfen: nur der geänderte Termin darf übertragen werden, nicht der gesamte Kalender.
|
||||
Tracelinks: StRS-021, SyRS-027
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-032
|
||||
Titel: IsHelpdeskSchedule Source-of-Truth-Schutzregel
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Termin ist ein Helpdesk-Zeiterfassungstermin (`ObjectType = HelpdeskTimerClass` oder `HelpdeskClass`).
|
||||
Fakt: `IsHelpdeskSchedule(Schedule schedule)` identifiziert Helpdesk-gebundene Termine; `UpdateScheduleByGraph()` überschreibt `DateStart`/`DateEnd` solcher Termine nicht mit aus Exchange zurückgelieferten Werten; `SyncOldSchedule()` schließt Helpdesk-Termine explizit von der Weiterleitung an Exchange über diesen Pfad aus.
|
||||
Aussage: Das System soll für Helpdesk-Zeiterfassungstermine c-entron als alleinige maßgebliche Datenquelle (Source of Truth) behandeln und jede Rücküberschreibung von Datum/Uhrzeit aus Exchange technisch verhindern.
|
||||
Ergebnis: Eine manuelle Änderung von Datum/Uhrzeit eines Helpdesk-Zeittermins direkt in Outlook wird beim nächsten Sync-Zyklus nicht in c-entron übernommen.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/features/exchange-sync-bugprotokoll.md` (Ticket 164020, 158813; konkreter Code `if (!this.IsHelpdeskSchedule(schedule)) { schedule.DateStart = ...; }`) - Begründung: Durch QS-Testfälle verifizierte, im Code umgesetzte Schutzregel.
|
||||
Prüfidee: Helpdesk-Zeittermin in c-entron anlegen, Sync abwarten, Termin in Outlook manuell auf anderes Datum ändern, erneut synchronisieren → c-entron-Datensatz muss unverändert bleiben (siehe StRS-021 Prüfidee).
|
||||
Tracelinks: StRS-021, SwRS-031
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-033
|
||||
Titel: DataQualityService Hintergrundaufgabenliste
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Webservice läuft, stündlicher Zyklus ist erreicht.
|
||||
Fakt: `DataQualityService.ExecuteAsync` führt sequenziell u. a. `TicketPatternUpdateCustomerMappingsFilter`, `DirectoryCheckBL.ExecuteDirectoryCheck()`, `CentronNotificationsBL.CleanupCentronNotifications()`, `AccountBL.CheckAndRepairAccountTypeToAccountsTable()`, `HelpdeskTimerBL.DataQualityUpdateMissingHelpdeskTimerProperties()`, `SecondStockArticleBL.DataQualityCleanupSecondaryStockArticles()` aus; jede Aufgabe läuft in eigener `BLSession`, ist einzeln try-catch-isoliert und wird bei Abbruchanforderung zwischen den Aufgaben unterbrochen.
|
||||
Aussage: Das System soll eine feste, erweiterbare Liste von Datenkorrektur- und Aufräumaufgaben stündlich automatisiert und fehlerisoliert ausführen.
|
||||
Ergebnis: Datenintegritätsprobleme (fehlende Fremdschlüssel, verwaiste Zuordnungen) werden auch ohne manuellen Eingriff innerhalb einer Stunde selbstständig behoben.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/Background Service/DataQualityService.md` (vollständige Aufgabenliste mit BL-Methodenreferenzen) - Begründung: Vollständig dokumentierte, im Code umgesetzte Aufgabenliste.
|
||||
Prüfidee: Fehlende `AccountI3D`-Zuordnung in einem Todo-Eintrag künstlich erzeugen; nach einem Ausführungszyklus muss `ToDoBL.DataQualityFillAccountI3D()` den Wert korrigiert haben.
|
||||
Tracelinks: SyRS-025
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-034
|
||||
Titel: ModuleRegistration/ICentronAppModuleController Rechteprüfung je Modul
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System (WPF-Client)
|
||||
Vorbedingung: Benutzer meldet sich am WPF-Client an.
|
||||
Fakt: `ModuleRegistration.IsModuleAvailable<T>()` prüft `CentronCache.Instance.CurrentUserAppRights` gegen die für ein Modul über `ModuleRegistrationItem.For<TController>(() => Helper.HasRights(...))` deklarierten Rechte sowie optional gegen `ModuleFeatures`-Freischaltflags (Feature-Flag für unfertige Module) und Lizenzprüfung (`LicenseManager.Instance.HasLicense`).
|
||||
Aussage: Das System soll die Sichtbarkeit jedes Moduls im Modulmenü des Desktop-Clients aus drei unabhängigen Bedingungen ableiten: zugewiesenes Benutzerrecht, aktivierte Lizenz und (für unfertige Module) ein Feature-Flag.
|
||||
Ergebnis: Ein Modul erscheint im Modulmenü nur, wenn alle drei zutreffenden Bedingungen erfüllt sind; fehlt eine, ist das Modul für den Benutzer nicht sichtbar.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/centron/Centron.WPF.UI/Modules/ModuleRegistration.cs` (`IsModuleAvailable<T>()`, `GetRightsForModule()`, `GetPersonalSettings()`) - Begründung: Zentrale, im Code durchgesetzte Sichtbarkeitslogik laut Agentenrecherche.
|
||||
Prüfidee: Modul mit Recht X und Lizenz Y konfigurieren; Benutzer mit Recht, aber ohne Lizenz → Modul nicht sichtbar; Benutzer mit Lizenz, aber ohne Recht → Modul nicht sichtbar.
|
||||
Tracelinks: StRS-016, StRS-017, SyRS-011, SwRS-021
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-035
|
||||
Titel: DeveloperSecurity Mailversand-Schutz (DEBUG)
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System (DEBUG-Build)
|
||||
Vorbedingung: Anwendung läuft als DEBUG-Build.
|
||||
Fakt: `DeveloperSecurity.cs` ersetzt in DEBUG-Builds jede externe (nicht auf `nexoware.com` endende) E-Mail-Adresse vor dem Versand durch `test@nexoware.com`; internes Verhalten ist über die Property `AllowSendingEmailToExternalAddresses` deaktivierbar; in RELEASE-Builds ist dieser Mechanismus nicht aktiv.
|
||||
Aussage: Das System soll ausschließlich im DEBUG-Kompilat einen automatischen Adress-Ersatzmechanismus für externe E-Mail-Empfänger bereitstellen, um versehentliche Testmails an reale Kunden während der Entwicklung zu verhindern.
|
||||
Ergebnis: Ein in einer lokalen Entwicklungsumgebung ausgelöster Testversand an eine beliebige externe Adresse erreicht immer nur die interne Testadresse.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/security/developer-security.md` (Verweis auf konkrete Implementierungsdatei und Property) - Begründung: Konkret benannte Implementierung mit eindeutigem Verhalten.
|
||||
Prüfidee: In DEBUG-Konfiguration Mailversand an fiktive externe Adresse `kunde@fremdefirma.de` auslösen; tatsächlicher SMTP-Empfänger muss `test@nexoware.com` sein.
|
||||
Tracelinks: SyRS-028
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-036
|
||||
Titel: CentronWcfBridge Legacy-Endpunkt-Mapping
|
||||
Ebene: SwRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: System
|
||||
Vorbedingung: -
|
||||
Fakt: `CentronWcfBridge.cs` reflektiert zur Startzeit über alle mit `[WebInvoke(UriTemplate=...)]` dekorierten Methoden von `ICentronRestService` (partial interface, aufgeteilt in Dateien wie `ICentronRestService.Accounts.cs`, `ICentronRestService.Administration.cs`) und registriert je Methode zwei Minimal-API-Endpunkte (`/REST/<UriTemplate>`, komprimiert `/RESTC/<UriTemplate>`) mit eigenem `MethodHandler` für (De-)Serialisierung von DataContract-Objekten.
|
||||
Aussage: Das System soll die Erschließung neuer bzw. bestehender Legacy-REST-Methoden automatisiert durch Reflexion vornehmen, sodass keine manuelle Registrierung einzelner Endpunkte im Hosting-Code notwendig ist.
|
||||
Ergebnis: Eine neue Methode mit `[WebInvoke(UriTemplate="X")]` in `ICentronRestService` ist ohne weitere Hosting-Änderung automatisch unter `/REST/X` erreichbar.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/webservice/Centron.Host/AspNetCore/WcfBridge/CentronWcfBridge.cs` - Begründung: Konkrete Reflection-basierte Implementierung laut Agentenrecherche.
|
||||
Prüfidee: Neue Testmethode mit `[WebInvoke(UriTemplate="TestPing")]` hinzufügen, Neustart des Hosts, Aufruf von `/REST/TestPing` ohne weitere Codeänderung muss funktionieren.
|
||||
Tracelinks: SyRS-004
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-037
|
||||
Titel: GlobalExceptionFilter/LoggingInterceptor
|
||||
Ebene: SwRS
|
||||
Typ: nicht-funktional (Zuverlässigkeit, ISO 25010)
|
||||
Akteur: System
|
||||
Vorbedingung: Unbehandelte Exception tritt während eines API-Aufrufs auf.
|
||||
Fakt: `GlobalExceptionFilter` (moderne Controller) loggt die Exception, ruft `DAOFactory.Instance.TryRecoverConnectionPool(exception)` auf und liefert eine generische 500-Antwort ohne Stacktrace; für den Legacy-Pfad protokolliert `LoggingInterceptor` Methodenname, Ticket und Laufzeit je Aufruf (bei aktivierter `veryDetailedWebServiceLogging`-Einstellung inkl. vollständiger Payload).
|
||||
Aussage: Das System soll unbehandelte Fehler zentral abfangen, protokollieren, eine Wiederherstellung des Datenbankverbindungspools versuchen und dem Client keine internen Implementierungsdetails preisgeben.
|
||||
Ergebnis: Ein interner Fehler führt nicht zum Absturz des Webservice-Prozesses und liefert dem Client keine sicherheitsrelevanten Details (Stacktrace) außerhalb der Entwicklungsumgebung.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/webservice/Centron.Controllers/Configuration/GlobalExceptionFilter.cs`, `src/webservice/Centron.Host/AspNetCore/WcfBridge/Interception/Interceptors/LoggingInterceptor.cs` - Begründung: Konkrete Filter-/Interceptor-Implementierungen laut Agentenrecherche.
|
||||
Prüfidee: Endpunkt mit provozierter NullReferenceException aufrufen (Produktionsmodus) → Antwort darf keinen Stacktrace enthalten, Fehler muss im Log erscheinen.
|
||||
Tracelinks: SyRS-002
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-038
|
||||
Titel: PersistedEntity.StateEnum als generisches Soft-Delete-Muster
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: System
|
||||
Vorbedingung: -
|
||||
Fakt: `PersistedEntity.cs` definiert `enum StateEnum { Existing = 0, Deleted = 1 }`; `DBEntity` (Basisklasse vieler Domänenentitäten, u. a. `CustomerBase`, `Helpdesk`) führt zusätzlich `State` (int?), `CreatedBy`/`CreatedDate`/`CreatedVersion`, `ChangedBy`/`ChangedDate`/`ChangedVersion`.
|
||||
Aussage: Das System soll den Soft-Delete-Zustand einer Entität sowie deren Erstellungs-/Änderungs-Audit-Informationen einheitlich über eine gemeinsame Basisklasse (`DBEntity`) statt individuell je Entität abbilden.
|
||||
Ergebnis: Eine als gelöscht markierte Entität (`State = Deleted`) bleibt in der Datenbank erhalten und kann für Audit-Zwecke rekonstruiert werden, ist aber für reguläre Abfragen ausgeblendet.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/backend/Centron.Entities/PersistedEntity.cs` (`enum StateEnum`), `src/backend/Centron.Entities/DBEntity.cs` - Begründung: Konkrete Basisklassen laut Agentenrecherche der Entitätsschicht.
|
||||
Prüfidee: Entität löschen (Soft Delete), per SQL prüfen, dass der Datensatz weiterhin existiert mit `State=1`; reguläre fachliche Abfrage darf den Datensatz nicht mehr zurückliefern.
|
||||
Tracelinks: SyRS-016
|
||||
Konsolidierung: Kandidat: Doppelte Soft-Delete-Modellierung – generisches `DBEntity.State` (StateEnum, ältere Entitäten) versus das in `docs/guides/database/database-conventions.md` beschriebene, neuere `IsDeleted`/`DeletedByI3D`/`DeletedDate`-Spaltenmuster (neue Tabellen). Im Zielsystem auf ein einheitliches Muster konsolidierbar.
|
||||
Status: belegt
|
||||
```
|
||||
+702
@@ -0,0 +1,702 @@
|
||||
# System Requirements Specification (SyRS) – c-entron ERP
|
||||
|
||||
Diese SyRS beschreibt Systemverhalten, Schnittstellen sowie Performance-/Sicherheitsanforderungen, abgeleitet aus der technischen Analyse der Architektur (Backend-Schichten, Webservice, Nexus-Webportal, Datenbank, Betrieb). Nicht-funktionale Anforderungen sind zusätzlich mit ihrem ISO/IEC-25010-Qualitätsmerkmal gekennzeichnet.
|
||||
|
||||
---
|
||||
|
||||
```
|
||||
ID: SyRS-001
|
||||
Titel: Dreischichtige Architektur mit austauschbarem Zugriffspfad
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (Wartbarkeit / Übertragbarkeit, ISO 25010)
|
||||
Akteur: System
|
||||
Vorbedingung: -
|
||||
Fakt: Jedes Modul folgt dem Muster ViewModel → `ILogic`-Interface → `BL<Modul>Logic` (Direktzugriff via NHibernate) bzw. `WS<Modul>Logic` (Webservice) → `WebServiceBL` (DTO↔Entity) → `BL` (NHibernate/DB); Verbindungstypen werden je Modul über `CentronConnectionType[]` deklariert.
|
||||
Aussage: Das System soll fachliche Logik strikt in klar getrennten Schichten (ViewModel, Zugriffslogik, Web-Service-Fassade, Geschäftslogik, Datenzugriff) kapseln, sodass ein Modul wahlweise über Direktverbindung oder Webservice angesprochen werden kann, ohne dass Geschäftslogik dupliziert wird.
|
||||
Ergebnis: Neue oder geänderte Geschäftsregeln müssen nur einmal in der BL-Schicht implementiert werden und wirken unabhängig vom Zugriffsweg.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/getting-started/general-structure.md` (Codebeispiele `IAccountContractsLogic`, `BLAccountContractsLogic`, `WSAccountContractsLogic`) - Begründung: Als verbindliche Implementierungsregel dokumentiertes, im Code wiederkehrendes Muster.
|
||||
Prüfidee: Statische Codeprüfung: Für ein Stichprobenmodul existieren `I*Logic`, `BL*Logic`, `WS*Logic` mit identischer Methodensignatur.
|
||||
Tracelinks: StRS-030
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-002
|
||||
Titel: Einheitliches Fehler-/Ergebnisprotokoll über alle Schichten
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (Zuverlässigkeit, ISO 25010)
|
||||
Akteur: System
|
||||
Vorbedingung: -
|
||||
Fakt: BL-Methoden liefern `Result`/`Result<T>` mit Status `Success/Error/Warning`; an der Webservice-Grenze erfolgt Übersetzung in `Response`/`Response<T>` mit Status `Success/Failed` (Warning wird zu Success gemappt).
|
||||
Aussage: Das System soll Operationsergebnisse konsistent über ein einheitliches Result-/Response-Objektmodell mit Status, Nachricht und optionalem Fehlercode kommunizieren, statt Exceptions als regulären Kontrollfluss zu nutzen.
|
||||
Ergebnis: Jeder Aufruf einer Geschäftsoperation liefert ein einheitlich auswertbares Ergebnisobjekt; Aufrufer können Erfolg/Warnung/Fehler ohne Try-Catch unterscheiden.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/backend/Centron.Interfaces/Results/Result.cs`, `src/webservice/Centron.WebServices.Core/Messages/Response.cs` - Begründung: Konkrete, im gesamten Backend verwendete Klassen (laut Dokumentation Kernbestandteil, mehrfach in anderen Agenten-Berichten referenziert, u. a. `OposBL`, `DunningBL`, alle WebServiceBL-Klassen).
|
||||
Prüfidee: BL-Methode mit provoziertem Fehler aufrufen; Response muss `StatusCode.Failed` mit aussagekräftiger `Message` liefern, kein unbehandelter Exception-Durchschlag zum Client.
|
||||
Tracelinks: StRS-030
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-003
|
||||
Titel: REST-Webservice als zentrale Systemschnittstelle
|
||||
Ebene: SyRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: WPF-Client, Nexus-Webportal, Outlook-Add-in, externe Anwendungen
|
||||
Vorbedingung: -
|
||||
Fakt: Selbst gehosteter ASP.NET-Core-Prozess (`Centron.Host`), Kestrel unter Linux/HttpSys unter Windows; kombiniert legacy WCF-Bridge-Endpunkte (`/REST/...`, `/RESTC/...`) mit modernen versionierten Controllern (`v1/...`).
|
||||
Aussage: Das System soll sämtliche Client-Anwendungen (Desktop, Web, Outlook-Add-in, Drittsysteme) über eine zentrale, selbst gehostete Webservice-Schicht mit einheitlicher Authentifizierung bedienen.
|
||||
Ergebnis: Alle Clients erreichen dieselbe Geschäftslogik über HTTP(S)-Endpunkte, unabhängig vom Betriebssystem des Clients.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/webservice/Centron.Host/CentronHost.cs` - Begründung: Konkrete Host-Konfiguration (Kestrel/HttpSys, Routing, Auth) laut Agentenrecherche.
|
||||
Prüfidee: Gleichen Endpunkt von WPF-Client und einer unabhängigen HTTP-Anfrage (z. B. curl) mit gültigem Ticket aufrufen; identisches Ergebnis erwarten.
|
||||
Tracelinks: StRS-002, StRS-010, StRS-018, StRS-022
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-004
|
||||
Titel: Legacy-WCF-Bridge-Kompatibilität
|
||||
Ebene: SyRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: WPF-Client (Bestandsclient)
|
||||
Vorbedingung: -
|
||||
Fakt: `CentronWcfBridge.cs` reflektiert über `ICentronRestService`-Methoden mit `[WebInvoke(UriTemplate=...)]` und bildet sie manuell auf ASP.NET-Core-Minimal-Endpunkte (`MapPost("/REST"+uri, ...)`) ab, inkl. eigenem Interceptor-basiertem Auth-/Logging-Stack (Castle DynamicProxy).
|
||||
Aussage: Das System soll die historisch gewachsene WCF-artige REST-Schnittstelle (Data-Contract-Objekte, `UriTemplate`) technologisch unter ASP.NET Core weiterbetreiben, um Kompatibilität mit dem bestehenden WPF-Client ohne dessen Neuentwicklung sicherzustellen.
|
||||
Ergebnis: Alle in `ICentronRestService` deklarierten Altmethoden bleiben unter `/REST/<UriTemplate>` und `/RESTC/<UriTemplate>` (komprimierte Variante) erreichbar.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/webservice/Centron.Host/AspNetCore/WcfBridge/CentronWcfBridge.cs` - Begründung: Konkrete, reflektionsbasierte Bridge-Implementierung laut Agentenrecherche.
|
||||
Prüfidee: Bestandsmethode aus `ICentronRestService` über `/REST/<Name>` aufrufen und Antwortformat/-inhalt gegen Erwartung prüfen.
|
||||
Tracelinks: SyRS-003
|
||||
Konsolidierung: Kandidat: Legacy-WCF-Bridge (SyRS-004) und moderne v1-Controller (SyRS-005) bilden zwei parallele API-Generationen für teils gleiche fachliche Funktionen (z. B. Kunden/Aufträge existieren in beiden) – zentraler Konsolidierungskandidat für die Web-/SaaS-Neuimplementierung.
|
||||
Status: belegt; Workaround
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-005
|
||||
Titel: Versionierte moderne REST-Controller
|
||||
Ebene: SyRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: Nexus-Webportal, externe Anwendungen, Drittintegrationen
|
||||
Vorbedingung: -
|
||||
Fakt: `Centron.Controllers` nutzt ASP.NET-Core-MVC-Controller mit `Asp.Versioning` (`VersionByNamespaceConvention`), URL-Segment-Versionierung (`v{version:apiVersion}/...`), Kebab-Case-Routentransformation.
|
||||
Aussage: Das System soll für neu entwickelte Programmierschnittstellen ein versioniertes, standardkonformes REST-Muster (ASP.NET-Core-Controller, semantische Versionierung im URL-Pfad) bereitstellen.
|
||||
Ergebnis: Endpunkte sind unter `/v1/<ressource>` erreichbar; künftige Breaking Changes können unter `/v2/...` parallel angeboten werden.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/webservice/Centron.Controllers/Controllers/v1/**` (u. a. `CustomersController.cs`, `OrdersController.cs`, `ContractsController.cs`, `HelpdesksController.cs`, `AccessTokensController.cs`) - Begründung: Konkrete, im Repository vorhandene versionierte Controller-Klassen.
|
||||
Prüfidee: `GET v1/customers/{id}` mit gültigem Token aufrufen und Response-Schema gegen DTO-Definition prüfen.
|
||||
Tracelinks: SyRS-004
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-006
|
||||
Titel: Echtzeitkommunikation über SignalR
|
||||
Ebene: SyRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: WPF-Client, Nexus-Webportal
|
||||
Vorbedingung: -
|
||||
Fakt: Mehrere SignalR-Hubs (`ChatHub`, `NotificationsHub`, `AvailabilityStatusHub`, `TapiClientHub`), teils zusätzlich per `SecretKeyRequirement`/`SecretKeyHandler` abgesichert.
|
||||
Aussage: Das System soll Echtzeit-Benachrichtigungen (Chat, Systembenachrichtigungen, Verfügbarkeitsstatus, Telefonie-Events) über eine bidirektionale WebSocket-/SignalR-Verbindung an verbundene Clients ausliefern.
|
||||
Ergebnis: Ein serverseitiges Ereignis (z. B. neue Chat-Nachricht) wird ohne Polling zeitnah an alle betroffenen, verbundenen Clients zugestellt.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/webservice/Centron.Host/RealTimeServices/ChatHub.cs`, `NotificationsHub.cs`, `AvailabilityStatusHub.cs`, `TapiClientHub.cs` - Begründung: Konkrete Hub-Implementierungen laut Agentenrecherche.
|
||||
Prüfidee: Zwei Clients verbinden, Chat-Nachricht von Client A senden, Zustellzeit/-inhalt bei Client B prüfen.
|
||||
Tracelinks: StRS-010
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-007
|
||||
Titel: Sitzungsbasierte Ticket-Authentifizierung
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: WPF-Client
|
||||
Vorbedingung: Benutzer hat sich erfolgreich angemeldet.
|
||||
Fakt: `TicketAuthenticationHandler` validiert ein per `Authorization: Bearer <ticket>` oder Query-Parameter `access_token` übergebenes Ticket gegen `AuthenticationTicketBL.GetAuthTicketInfo`; Tickets sind laut OIDC-Doku standardmäßig 30 Minuten gültig.
|
||||
Aussage: Das System soll nach erfolgreicher Anmeldung ein zeitlich begrenztes Sitzungs-Ticket ausstellen, das für nachfolgende API-Aufrufe als Authentifizierungsnachweis dient.
|
||||
Ergebnis: Ein abgelaufenes oder ungültiges Ticket führt zur Ablehnung des API-Aufrufs (401).
|
||||
Belege:
|
||||
- [PRIMÄR] `src/webservice/Centron.Host/AspNetCore/TicketAuthenticationHandler.cs` - Begründung: Konkrete, als Default-Scheme registrierte Authentifizierungslogik.
|
||||
- [PRIMÄR] `docs/reference/security/anmelden-mit-microsoft-technische-anleitung.md` (Ticket-Erstellung: `expireDate = DateTime.Now.AddMinutes(30)`) - Begründung: Konkreter, dokumentierter Gültigkeitszeitraum mit Codebeleg.
|
||||
Prüfidee: Mit abgelaufenem Ticket einen geschützten Endpunkt aufrufen → Antwort 401.
|
||||
Tracelinks: StRS-016
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-008
|
||||
Titel: Anmeldung über OpenID Connect (Microsoft Entra ID)
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Benutzer mit Microsoft-Konto
|
||||
Vorbedingung: Azure-AD-App-Registrierung und `JwtAuthority`/`JwtAudience`-Einstellungen sind konfiguriert.
|
||||
Fakt: Client erhält per MSAL ein Microsoft-ID-Token, tauscht es über `POST /jwt/login` gegen ein c-entron-Ticket; Server validiert das JWT (Signatur, Issuer, Audience, Lifetime) und sucht den Benutzer über den `oid`-Claim in `Sichbenu.OpenIdConnectSubjectIdentifier`.
|
||||
Aussage: Das System soll die Anmeldung mittels Single-Sign-On über Microsoft Entra ID (Azure AD) unterstützen und dabei ein extern ausgestelltes ID-Token gegen ein internes Sitzungs-Ticket austauschen.
|
||||
Ergebnis: Ein Benutzer mit verknüpftem Microsoft-Konto kann sich ohne c-entron-Passwort anmelden; ein Benutzer ohne verknüpfte `OpenIdConnectSubjectIdentifier` erhält eine Fehlermeldung.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/security/anmelden-mit-microsoft-technische-anleitung.md` (vollständiger Sequenzablauf mit Dateireferenzen: `JwtAuthController.cs`, `OpenIdConnectAuthenticator.cs`) - Begründung: Vollständig dokumentierter, mit konkreten Datei-/Klassenreferenzen belegter Sicherheitsfluss.
|
||||
Prüfidee: Anmeldung mit verknüpftem Microsoft-Testkonto durchführen, gültiges Ticket erhalten; Anmeldung mit nicht verknüpftem Konto → Fehler.
|
||||
Tracelinks: StRS-016
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-009
|
||||
Titel: Authentifizierung über persönliche Access Tokens
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Externe Anwendungen/Integrationen
|
||||
Vorbedingung: Benutzer hat einen Access Token erstellt.
|
||||
Fakt: `AccessTokensController` (JWT-geschützt) erlaubt Erstellung/Aktivierung/Deaktivierung/Löschung persönlicher Access Tokens inkl. Nutzungsprotokoll (`/logs`) und Statistiken (`/statistics`).
|
||||
Aussage: Das System soll es Benutzern ermöglichen, persönliche API-Zugriffstoken für Drittanwendungen zu erstellen, zu deaktivieren und deren Nutzung nachzuvollziehen.
|
||||
Ergebnis: Ein deaktivierter Access Token wird bei nachfolgenden API-Aufrufen abgelehnt; Nutzungsprotokoll zeigt historische Aufrufe.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/webservice/Centron.Controllers/Controllers/v1/Administration/AccessTokensController.cs` - Begründung: Konkrete CRUD-/Statistik-Endpunkte laut Agentenrecherche.
|
||||
Prüfidee: Access Token erstellen, damit Aufruf durchführen (Erfolg), Token deaktivieren, gleichen Aufruf wiederholen (Ablehnung).
|
||||
Tracelinks: StRS-016
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-010
|
||||
Titel: Zwei-Faktor-Authentifizierung (RADIUS)
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Benutzer, RADIUS-Server
|
||||
Vorbedingung: `TwoFactorAuthEnabled`/`TwoFactorAuthType=RadiusServer` ist konfiguriert.
|
||||
Fakt: `WebServiceConfig.xml` unterstützt `TwoFactorAuthEnabled`/`TwoFactorAuthType`; ein dedizierter Test `RadiusMessageAuthenticationTest.cs` (`PacketTestAccessRequestWithoutClass`, `SendFlow`) verifiziert das RADIUS-Protokollverhalten; `TwoFactorAuthController` (`GET 2fa/validate`) bietet den zugehörigen Validierungsendpunkt.
|
||||
Aussage: Das System soll optional eine Zwei-Faktor-Authentifizierung über einen RADIUS-Server als zusätzliche Absicherung der Anmeldung unterstützen.
|
||||
Ergebnis: Bei aktivierter 2FA wird eine Anmeldung erst nach erfolgreicher RADIUS-Validierung des zweiten Faktors abgeschlossen.
|
||||
Belege:
|
||||
- [PRIMÄR] `tests/Centron.Tests.EndToEnd/Tests/Radius/RadiusMessageAuthenticationTest.cs` - Begründung: Automatisierter Test des RADIUS-Nachrichtenflusses belegt eine tatsächlich funktionsfähige Implementierung (nicht nur Konfigurationsschalter).
|
||||
- [SEKUNDÄR] `src/webservice/Centron.Controllers/Controllers/Unversioned/TwoFactorAuthController.cs` - Begründung: Zugehöriger Validierungsendpunkt.
|
||||
Prüfidee: 2FA aktivieren, Anmeldung ohne zweiten Faktor → Ablehnung; mit korrektem RADIUS-Code → Erfolg.
|
||||
Tracelinks: StRS-016
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-011
|
||||
Titel: Rollenbasierte Autorisierung pro Endpunkt/Funktion
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System
|
||||
Vorbedingung: Benutzer ist authentifiziert.
|
||||
Fakt: `AuthorizeUserRightAttribute`/`AuthorizeAllUserRightsAttribute`/`AuthorizeAnyUserRightAttribute` prüfen `currentUser.HasUserRight(id)` und liefern 401/403; im WPF-Client und in der BL-Schicht wird dieselbe Grundprüfung (`HasUserRight`) 318-mal in 93 Dateien eingesetzt.
|
||||
Aussage: Das System soll den Zugriff auf einzelne API-Endpunkte, Module und Funktionen konsistent anhand feingranularer, pro Benutzer/Gruppe vergebener Rechte einschränken.
|
||||
Ergebnis: Ein Aufruf eines rechtegeschützten Endpunkts durch einen Benutzer ohne das erforderliche Recht wird mit 401/403 abgelehnt.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/webservice/Centron.Controllers/Authorization/AuthorizeUserRightAttribute.cs` - Begründung: Konkretes, im Code durchgesetztes Autorisierungsattribut.
|
||||
- [PRIMÄR] `src/backend/Centron.BL/Administration/Rights/UserRightsExt.cs` (`HasUserRight`, 318 Aufrufstellen) - Begründung: Durchgängig verwendetes Autorisierungsmuster auf BL-Ebene.
|
||||
Prüfidee: Endpunkt mit `[AuthorizeUserRight(X)]` durch Benutzer ohne Recht X aufrufen → 401/403; mit Recht X → Erfolg.
|
||||
Tracelinks: StRS-016, StRS-013, StRS-014
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-012
|
||||
Titel: Filialbezogene Zugriffsisolation (Branch Isolation)
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Benutzer mit filialbeschränktem Recht
|
||||
Vorbedingung: Benutzer besitzt ein "nur eigene Filiale"-Recht (`OnlyOwnBranchRight`).
|
||||
Fakt: `ReceiptSearchConfiguration` definiert je Belegtyp `ShowRight`, `OnlyOwnRight`, `OnlyOwnBranchRight`; fehlt das passende Recht, liefert `CreateSqlStatementAndParameters` `null` (keine Ergebnisse für diesen Belegtyp).
|
||||
Aussage: Das System soll die Sichtbarkeit von Belegen für filialbeschränkte Benutzer serverseitig in der Suchlogik durchsetzen, nicht nur in der Benutzeroberfläche ausblenden.
|
||||
Ergebnis: Ein filialbeschränkter Benutzer erhält bei einer Belegsuche ausschließlich Belege der eigenen Filiale, unabhängig vom verwendeten Client.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/receipts/receipt-search-architecture.md` (zitiert `ReceiptSearchConfiguration.OnlyOwnBranchRight`, `ReceiptSearcher.CreateSqlStatementAndParameters`) - Begründung: Konkrete, serverseitig durchgesetzte Filterlogik.
|
||||
Prüfidee: Filialbeschränkter Benutzer sucht Belege anderer Filialen über direkten API-Aufruf (nicht UI) → Ergebnis darf keine fremden Filialbelege enthalten.
|
||||
Tracelinks: StRS-027, SyRS-011
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-013
|
||||
Titel: Belegstatusmaschine (Active/Completed/Canceled)
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Beleg existiert.
|
||||
Fakt: `src/backend/Centron.Interfaces/Sales/Receipts/ReceiptState.cs` definiert die Zustände `Active`, `Completed`, `Canceled`; `ReceiptBL.cs` setzt/liest diese Zustände (`receipt.State = ReceiptState.Completed`, Prüfungen `if (receipt.State != ReceiptState.Canceled)`).
|
||||
Aussage: Das System soll jeden Beleg (Angebot, Auftrag, Lieferschein, Rechnung, Gutschrift, Vertrag) einer von drei einheitlichen Statuswerten zuordnen und Statuswechsel nur über definierte BL-Methoden zulassen.
|
||||
Ergebnis: Ein stornierter Beleg (`Canceled`) kann nicht mehr in nachgelagerte Prozesse (z. B. Rechnungsstellung) einfließen.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/backend/Centron.Interfaces/Sales/Receipts/ReceiptState.cs` - Begründung: Enum-Definition der drei Statuswerte.
|
||||
- [PRIMÄR] `src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs` (Zeilen ~3274, ~4148, ~4178, ~4936) - Begründung: Konkrete Statusprüfungen/-zuweisungen im Code.
|
||||
Prüfidee: Beleg stornieren, danach Versuch, ihn in einen Folgebeleg zu wandeln → muss vom System verhindert werden.
|
||||
Tracelinks: StRS-001, StRS-003, StRS-005, StRS-007, StRS-008, StRS-010, StRS-011, StRS-018, StRS-023, StRS-024, StRS-025, StRS-026, StRS-029, SwRS-004
|
||||
Konsolidierung: Kandidat: Die Legacy-Spiegeltabellen (`Entities/DbEntities/AufKopf.cs` u. a.) führen ein rein numerisches `Status`-Feld (kein Enum) parallel zum modernen `ReceiptState`-Enum – im Zielsystem auf ein einziges Statusmodell konsolidierungsbedürftig.
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-014
|
||||
Titel: Selbstprüfender Belegtyp-Übergangsgraph
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: Anwendung startet.
|
||||
Fakt: `IReceiptSpecificLogic` deklariert `CanBeForwardedFrom()`/`CanBeForwardedInto()` je Belegtyp; `SpecificLogics.ValidateConsistency()` prüft beim Start, dass alle Vorwärts-/Rückwärtsreferenzen symmetrisch sind, und wirft andernfalls eine `ApplicationException`.
|
||||
Aussage: Das System soll den Übergangsgraphen zwischen Belegtypen (welcher Beleg aus welchem hervorgehen darf) als konsistentes, beim Systemstart automatisch validiertes Modell führen.
|
||||
Ergebnis: Eine inkonsistente Konfiguration des Übergangsgraphen (z. B. Beleg A erlaubt Übergang zu B, aber B erlaubt keinen Ursprung aus A) verhindert den erfolgreichen Systemstart.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/backend/Centron.BL/Sales/Receipts/SpecificLogics.cs` (Zeilen ~148–170, `ValidateConsistency`) - Begründung: Konkrete, beim Start ausgeführte Konsistenzprüfung mit Exception bei Verletzung.
|
||||
Prüfidee: Testweise inkonsistente `CanBeForwardedFrom`/`CanBeForwardedInto`-Konfiguration einspielen → Systemstart muss mit `ApplicationException` fehlschlagen.
|
||||
Tracelinks: StRS-001, StRS-005, SwRS-002, SwRS-003
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-015
|
||||
Titel: Vollständiger Audit-Trail durch Kopf-/Positions-Versionierung
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (Zuverlässigkeit / Sicherheit, ISO 25010)
|
||||
Akteur: System
|
||||
Vorbedingung: Beleg wird gespeichert.
|
||||
Fakt: Je Belegtyp existiert eine 1:1-Kopie-Versionstabelle (`*KopfVersions`/`*PosVersions`); jede Spalte der Basistabelle muss zwingend auch in der Versionstabelle vorhanden sein, sonst schlägt `AssetHeadDAO.SaveAssetVersion` zur Laufzeit fehl.
|
||||
Aussage: Das System soll bei jeder Beleg-Speicherung eine vollständige, strukturidentische Historienkopie des vorherigen Zustands anlegen, um lückenlose Nachvollziehbarkeit von Änderungen zu gewährleisten.
|
||||
Ergebnis: Zu jedem Beleg lässt sich der Stand zu jedem früheren Speicherzeitpunkt rekonstruieren.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/receipts/receipts-backend-architecture.md` (Abschnitt "Version Tables: 1:1 Copies of Original Tables", zitiert `AssetHeadDAO.SaveAssetVersion`) - Begründung: Konkrete, technisch erzwungene Struktur mit dokumentiertem Fehlerverhalten bei Abweichung.
|
||||
Prüfidee: Beleg mehrfach ändern und speichern; Anzahl und Inhalt der Einträge in `<Typ>KopfVersions` gegen die Änderungshistorie prüfen.
|
||||
Tracelinks: StRS-001, SwRS-005
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-016
|
||||
Titel: Einheitliche Datenbank-Schemakonventionen
|
||||
Ebene: SyRS
|
||||
Typ: Daten
|
||||
Akteur: System / Entwickler
|
||||
Vorbedingung: -
|
||||
Fakt: Verbindliche Konventionen: Primärschlüssel `I3D` (`int IDENTITY(1,1)`, clustered), Fremdschlüsselsuffix `I3D`, Pflicht-Audit-Spalten (`CreatedByI3D`, `CreatedDate`, `ChangedByI3D`, `ChangedDate`), Soft-Delete-Muster (`IsDeleted`, `DeletedByI3D`, `DeletedDate`), `nvarchar` statt `varchar`, Schema `dbo`.
|
||||
Aussage: Das System soll für alle (neuen) Datenbanktabellen ein einheitliches Schema-Muster (Primärschlüssel, Fremdschlüsselnamensgebung, Audit-Spalten, Soft-Delete) verbindlich durchsetzen.
|
||||
Ergebnis: Neue Tabellen sind ohne zusätzliche Dokumentation anhand ihrer Spaltennamen konsistent interpretierbar (z. B. Fremdschlüssel immer per `*I3D`-Suffix erkennbar).
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/guides/database/database-conventions.md` - Begründung: Verbindlich dokumentierte Konvention mit konkreten Beispieltabellen (`AccountDevices`, `AccountDeviceUris`).
|
||||
- [PRIMÄR] `src/backend/Centron.DAO/Repositories/Administration/CentronConfigDb/CentronConfigurationDbRepository.cs` (Zeilen ~393–420, `PRIMARY KEY CLUSTERED`, `FOREIGN KEY` mit `WITH CHECK`) - Begründung: Tatsächlich ausgeführte DDL, die die Konvention umsetzt.
|
||||
Prüfidee: Stichprobenprüfung mehrerer neuerer Tabellen (z. B. `HelpdeskCreationTemplate`) auf Einhaltung aller Konventionspunkte.
|
||||
Tracelinks: -
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-017
|
||||
Titel: Versionsgesteuerter Datenbank-Migrationsmechanismus
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (Wartbarkeit, ISO 25010)
|
||||
Akteur: System (Anwendungsstart), Entwickler
|
||||
Vorbedingung: Anwendungsversion wurde erhöht.
|
||||
Fakt: 764 Klassen `ScriptMethod<Nummer>.cs` unter `Centron.BL/Administration/Scripts/ScriptMethods/Scripts/` implementieren `BaseScriptMethod` und liefern über `GetSqlQueries()` idempotente SQL-Anweisungen (häufig via `ScriptHelpers.AddColumnIfNotExists`/`AddTableIfNotExists`/`AddForeignKeyIfNotExists`), verknüpft mit einer `ApplicationVersion`.
|
||||
Aussage: Das System soll Datenbankschema-Änderungen ausschließlich über versionierte, beim Anwendungsstart automatisch ausgeführte, idempotente Migrationsskripte vornehmen (kein manuelles Schema-Deployment).
|
||||
Ergebnis: Ein Upgrade auf eine neue Anwendungsversion führt alle noch nicht angewendeten Skripte automatisch und reproduzierbar aus.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/guides/database/create-scripts.md`, `docs/reference/database/script-rules.md` - Begründung: Verbindlich dokumentierter Mechanismus mit Codebeispielen (`ScriptMethod11699.cs` u. a.).
|
||||
- [PRIMÄR] 764 Dateien unter `src/backend/Centron.BL/Administration/Scripts/ScriptMethods/Scripts/` (durch Agentenrecherche gezählt) - Begründung: Tatsächlicher Umfang des Mechanismus im Code.
|
||||
Prüfidee: Anwendung mit älterer DB-Version starten und Ausführung aller ausstehenden Skripte in der Konsolenausgabe verifizieren (vgl. Testvorgehen in `docs/guides/database/create-scripts.md`).
|
||||
Tracelinks: -
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-018
|
||||
Titel: Lizenzprüfung als Systemzugriffsvoraussetzung
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System
|
||||
Vorbedingung: Anwendung/Modul wird aufgerufen.
|
||||
Fakt: `LicenseManager.Instance.HasLicense(...)`/`GetLicenseCount(...)` werden zur Steuerung von Modul-Sichtbarkeit (`ModuleRegistration.IsModuleAvailable`) und Login-Berechtigung (`ApplicationKind`) verwendet; Lizenzen besitzen GUID, optionalen Zähler, Ablaufdatum, Versionsgrenze.
|
||||
Aussage: Das System soll den Zugriff auf Anwendungen (Login) und Einzelfunktionen (Module) zentral gegen eine GUID-basierte Lizenzprüfung mit optionaler Mengen- und Zeitbegrenzung absichern.
|
||||
Ergebnis: Eine abgelaufene oder mengenmäßig ausgeschöpfte Lizenz verhindert Login bzw. Nutzung der betroffenen Funktion.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/security/licensing-system.md` (Codebeispiele `LicenseManager.Instance.HasLicense`, `GetLicenseCount`) - Begründung: Dokumentiertes, im Code verwendetes Prüfmuster.
|
||||
Prüfidee: Lizenz mit `count=0` bzw. abgelaufenem Datum simulieren → betroffene Funktion muss verweigert werden.
|
||||
Tracelinks: StRS-017
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-019
|
||||
Titel: Mehrsprachige Benutzeroberfläche (Deutsch/Englisch)
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (Übertragbarkeit, ISO 25010)
|
||||
Akteur: Benutzer
|
||||
Vorbedingung: -
|
||||
Fakt: Separate `.resx`-Ressourcendateien je Schicht (`LocalizedStrings.resx` = Deutsch/Standard, `LocalizedStrings.en.resx` = Englisch) in WPF-UI und BL; Sprachwahl über `CultureInfo.CurrentUICulture`, bei Webservice-Aufrufen über `Accept-Language`-Header.
|
||||
Aussage: Das System soll alle benutzersichtbaren Texte standardmäßig auf Deutsch und zusätzlich auf Englisch bereitstellen, wobei Deutsch die verbindliche Ausgangssprache für neue Texte ist.
|
||||
Ergebnis: Bei Umschaltung der UI-Kultur auf Englisch werden alle vorhandenen Textressourcen in Englisch angezeigt; für neue Texte ohne Übersetzung wird der deutsche Standardtext angezeigt (Fallback).
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/guides/ui/localization.md` (konkrete Ressourcenpfade, Namenskonvention `[ClassName]_[MethodName]_[Description]`) - Begründung: Verbindlich dokumentiertes, im Code umgesetztes Lokalisierungsmuster.
|
||||
Prüfidee: UI-Kultur auf Englisch umstellen, Stichprobe von Dialogen auf vollständige Übersetzung prüfen.
|
||||
Tracelinks: -
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-020
|
||||
Titel: Verbindliche UTF-8-BOM-Dateikodierung
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (Wartbarkeit, ISO 25010)
|
||||
Akteur: Entwickler / Build-System
|
||||
Vorbedingung: -
|
||||
Fakt: Für alle `.cs`- und `.xaml`-Dateien ist UTF-8 mit BOM vorgeschrieben, um Sonderzeichen und Merge-Konflikte zu vermeiden.
|
||||
Aussage: Das System soll für sämtliche Quelltextdateien eine einheitliche Zeichenkodierung (UTF-8 mit BOM) sicherstellen, um korrekte Darstellung deutscher Sonderzeichen (Umlaute, ß) durchgängig zu gewährleisten.
|
||||
Ergebnis: Deutsche Sonderzeichen in Quelltext, Ressourcendateien und UI werden in allen Umgebungen korrekt dargestellt.
|
||||
Belege:
|
||||
- [SEKUNDÄR] `docs/getting-started/general-structure.md` (Abschnitt "File Encoding Requirements") - Begründung: Dokumentierte Konvention, jedoch nicht durch ein automatisiertes Prüfwerkzeug im Repository verifiziert (kein Encoding-Linter gefunden).
|
||||
Prüfidee: Stichprobenprüfung der Byte-Order-Mark in neu committeten `.cs`-Dateien.
|
||||
Tracelinks: -
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-021
|
||||
Titel: Mehrformatiger EDI-Dokumentenaustausch mit Lieferanten
|
||||
Ebene: SyRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: Externe Lieferanten-EDI-Server
|
||||
Vorbedingung: Lieferant ist für EDI konfiguriert.
|
||||
Fakt: `SupplierEdiBL` (partial classes je Lieferant) unterstützt OpenTrans 2.1, ALSO, ALSO CH, Herweck, Komsa, Alltron, ZUGFeRD; Verbindung per FTP/SFTP/FTPS; Dateien werden alle 30 Minuten automatisiert abgerufen.
|
||||
Aussage: Das System soll Bestellantwort-, Liefer- und Rechnungsdokumente in mehreren lieferantenspezifischen EDI-Formaten über gesicherte Protokolle (FTPS/SFTP) automatisiert austauschen.
|
||||
Ergebnis: Neue Dateien im konfigurierten Format werden innerhalb des 30-Minuten-Intervalls abgeholt und verarbeitet.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/edi/edi-architecture.md`, `docs/reference/edi/edi-import-rules.md` (konkrete Klassen `EdiDownloadService`, `EDIConnectBL`, Intervall "every 30 minutes") - Begründung: Vollständig dokumentierter, technisch belegter Mechanismus.
|
||||
Prüfidee: Testdatei auf konfiguriertem SFTP-Server ablegen, 30-Minuten-Zyklus abwarten, Verarbeitung im `EDIManagementLog` prüfen.
|
||||
Tracelinks: StRS-006
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-022
|
||||
Titel: Fehlerresilienz bei EDI-Verarbeitung (Datei-Blacklist)
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (Zuverlässigkeit, ISO 25010)
|
||||
Akteur: System
|
||||
Vorbedingung: Eine EDI-Datei ist mehrfach fehlgeschlagen.
|
||||
Fakt: Dateien mit mehr als 3 protokollierten Exceptions (`EDIManagementLog`, `State = Exception`) werden von weiteren Verarbeitungsversuchen ausgeschlossen (`badFiles.Where(f => f.ID > 3)`).
|
||||
Aussage: Das System soll wiederholt fehlschlagende EDI-Dateien nach einer definierten Fehleranzahl automatisch von erneuten Verarbeitungsversuchen ausschließen, um Endlos-Fehlerschleifen und unnötige Systemlast zu vermeiden.
|
||||
Ergebnis: Eine dauerhaft fehlerhafte Datei wird nach dem vierten Fehlschlag nicht mehr automatisch erneut verarbeitet, bleibt aber protokolliert und für manuelle Behebung sichtbar.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/edi/edi-import-rules.md` (konkrete SQL-Abfrage gegen `EDIManagementLog`, Schwellenwert `f.ID > 3`) - Begründung: Konkrete, im Code durchgesetzte Schwellenwertlogik.
|
||||
Prüfidee: Datei erzeugen, die 4-mal hintereinander einen Parsing-Fehler auslöst; fünfter Verarbeitungsversuch darf nicht mehr erfolgen.
|
||||
Tracelinks: StRS-006, SyRS-021
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-023
|
||||
Titel: Normkonforme E-Invoicing-Generierung
|
||||
Ebene: SyRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: System, Empfänger (Kunde/Behörde)
|
||||
Vorbedingung: Rechnung ist final erstellt.
|
||||
Fakt: `InvoiceZugferdBL` erzeugt ZUGFeRD/XRechnung-XML in vier Versionsgruppen (1.0 bis 2.1/XRechnung 3.0.1); Tax-Category-Codes (S/E/K/G/AE) und Steuerbefreiungstexte werden regelbasiert abgeleitet.
|
||||
Aussage: Das System soll elektronische Rechnungen in strukturierten, versionsspezifisch konfigurierbaren XML-Formaten nach ZUGFeRD-/XRechnung-Standard erzeugen, inklusive korrekter Steuerkategorie- und Befreiungslogik.
|
||||
Ergebnis: Die erzeugte XML-Datei ist gegen die jeweilige ZUGFeRD-/XRechnung-Version schemakonform (z. B. mittels KOSIT-Validator prüfbar).
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/zugferd-field-mapping.md` (vollständige Feldtabellen, Codereferenzen `InvoiceZugferdBL.cs:117-158`, `:1369-1400`) - Begründung: Detailliert dokumentierte, code-referenzierte Generierungslogik.
|
||||
Prüfidee: Rechnung mit Reverse-Charge-Position erzeugen; generierte XML muss Tax-Category "AE" und den vorgeschriebenen Befreiungstext enthalten.
|
||||
Tracelinks: StRS-015
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-024
|
||||
Titel: Toleranzprüfung bei E-Invoicing-Summenabgleich
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System
|
||||
Vorbedingung: ZUGFeRD-Export wird ausgelöst.
|
||||
Fakt: System validiert, dass die Summe der Positionsnetto-/-bruttopreise mit dem Kopfbetrag übereinstimmt; bei Abweichung ≤ 3,00 wird eine Warnung geloggt und der Wert korrigiert, bei Überschreitung schlägt der Export fehl.
|
||||
Aussage: Das System soll vor dem Export einer elektronischen Rechnung die rechnerische Konsistenz zwischen Kopf- und Positionssummen prüfen und den Export bei signifikanten Abweichungen verhindern.
|
||||
Ergebnis: Eine Rechnung mit einer Summenabweichung von mehr als 3,00 Währungseinheiten kann nicht als ZUGFeRD-Datei exportiert werden.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/zugferd-field-mapping.md` (Abschnitt "Validation Tolerances", "±3.00") - Begründung: Konkret dokumentierter Schwellenwert mit unterschiedlichem Verhalten (Warnung vs. Fehler).
|
||||
Prüfidee: Testrechnung mit künstlicher Summenabweichung von 5,00 erzeugen → ZUGFeRD-Export muss mit Fehler abbrechen.
|
||||
Tracelinks: StRS-015, SyRS-023
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-025
|
||||
Titel: Periodischer Hintergrunddienst zur Datenqualitätssicherung
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (Zuverlässigkeit, ISO 25010)
|
||||
Akteur: System
|
||||
Vorbedingung: Webservice läuft.
|
||||
Fakt: `DataQualityService` (ASP.NET-Core `BackgroundService`) führt stündlich eine feste Liste von Wartungsaufgaben aus (u. a. Bereinigung von Benachrichtigungen, Reparatur von `AccountTypeToAccounts`, Nachpflege fehlender `AccountI3D` bei Todos), jede Aufgabe einzeln try-catch-isoliert und mit eigener kurzlebiger DB-Session.
|
||||
Aussage: Das System soll wiederkehrende Datenkonsistenz- und Aufräumaufgaben automatisiert im Hintergrund ausführen, ohne dass ein Fehler in einer Aufgabe den gesamten Wartungslauf oder den Webservice beeinträchtigt.
|
||||
Ergebnis: Ein Fehler in einer einzelnen Wartungsaufgabe wird geloggt, verhindert aber nicht die Ausführung der übrigen Aufgaben im selben oder nächsten Zyklus.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/Background Service/DataQualityService.md` (konkrete Aufgabenliste mit BL-Methodenreferenzen, Try-Catch-Vorgabe) - Begründung: Vollständig dokumentiertes, im Code umgesetztes Verhalten.
|
||||
Prüfidee: Eine Wartungsaufgabe künstlich zum Fehlschlagen bringen; nachfolgende Aufgaben im selben Zyklus müssen dennoch ausgeführt werden (Log-Analyse).
|
||||
Tracelinks: -
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-026
|
||||
Titel: Intervallgesteuerter EDI-Download-Hintergrunddienst
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (Zuverlässigkeit, ISO 25010)
|
||||
Akteur: System
|
||||
Vorbedingung: Webservice läuft.
|
||||
Fakt: `EdiDownloadService` (ASP.NET-Core `BackgroundService`) läuft alle 30 Minuten (initiale Verzögerung 1 Minute nach Start); Log-Bereinigung für Einträge älter als 185 Tage erfolgt zwischen 00:00–02:00 Uhr.
|
||||
Aussage: Das System soll den EDI-Abruf als eigenständigen, konfigurierbaren Hintergrunddienst mit fester Wiederholungsfrequenz betreiben, getrennt von der interaktiven Benutzeranwendung.
|
||||
Ergebnis: Auch ohne aktiven Benutzer-Client werden EDI-Dokumente regelmäßig automatisch abgerufen.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/edi/edi-import-rules.md` (Abschnitt "Execution Frequency") - Begründung: Konkret dokumentierte Zeitparameter.
|
||||
Prüfidee: Webservice ohne verbundenen WPF-Client betreiben; EDI-Abruf muss dennoch planmäßig laufen (Log-Zeitstempel prüfen).
|
||||
Tracelinks: StRS-006, SyRS-021
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-027
|
||||
Titel: Bidirektionaler Kalender-Synchronisationsdienst
|
||||
Ebene: SyRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: System, Microsoft Exchange/Graph
|
||||
Vorbedingung: Exchange-Online-Anbindung ist konfiguriert.
|
||||
Fakt: `ExchangeSyncService` (HostedService, Standardintervall 60s) führt `ScheduleBL.SyncByGraphV2()` (Outlook→Nexus, Graph-API-Delta) und `ScheduleBL.SyncOldSchedule()` (Nexus→Outlook) aus; für On-Premise-Exchange-Kunden existiert laut Dokumentation ein separater, älterer EWS-Agent mit eingeschränktem Funktionsumfang.
|
||||
Aussage: Das System soll Termine zwischen c-entron-Zeitplanung und Microsoft Exchange (Online via Graph-API, On-Premise via EWS) in konfigurierbarem Intervall automatisiert synchronisieren.
|
||||
Ergebnis: Änderungen an Terminen werden innerhalb des Sync-Intervalls in beide Richtungen abgeglichen, wobei bekannte Graph-spezifische Funktionen (z. B. Serientermin-Kaskadenlöschung) für On-Premise-Kunden nicht verfügbar sind.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/features/exchange-sync-bugprotokoll.md` (Abschnitt "Sync-Architektur", "Geltungsbereich der Fixes") - Begründung: Detailliert dokumentierte Architektur mit expliziter Abgrenzung Graph vs. EWS.
|
||||
Prüfidee: Termin in Outlook (Exchange Online) ändern, 60s abwarten, Änderung in Nexus/c-entron prüfen; gleichen Test für On-Premise-Exchange wiederholen und Einschränkungen verifizieren.
|
||||
Tracelinks: StRS-021
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround (Doppelpfad Graph/EWS als historisch gewachsene Zwischenlösung)
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-028
|
||||
Titel: Entwickler-Schutzmechanismus gegen versehentlichen Mailversand
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Entwickler (DEBUG-Build)
|
||||
Vorbedingung: Anwendung läuft als DEBUG-Build.
|
||||
Fakt: In DEBUG-Builds werden alle externen E-Mail-Adressen (nicht auf `nexoware.com` endend) automatisch durch `test@nexoware.com` ersetzt; steuerbar über `DeveloperSecurity.AllowSendingEmailToExternalAddresses`. In RELEASE-Builds ist dieser Schutz nicht aktiv.
|
||||
Aussage: Das System soll in Entwicklungs-/Debug-Umgebungen den unbeabsichtigten Versand von E-Mails an echte Kundenadressen technisch verhindern.
|
||||
Ergebnis: Ein in einer DEBUG-Umgebung ausgelöster Mailversand an eine externe Adresse erreicht stattdessen eine interne Testadresse.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/reference/security/developer-security.md` (verweist auf `DeveloperSecurity.cs`) - Begründung: Konkret benannte Implementierungsdatei und Verhaltensbeschreibung.
|
||||
Prüfidee: In DEBUG-Build Mailversand an externe Testadresse auslösen → tatsächlicher Empfänger muss `test@nexoware.com` sein.
|
||||
Tracelinks: -
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-029
|
||||
Titel: Fehlende Ratenbegrenzung der Webservice-API
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit (Lücke/Risiko, ISO 25010: Sicherheit)
|
||||
Akteur: System / Angreifer
|
||||
Vorbedingung: -
|
||||
Fakt: Im gesamten `src/webservice`-Baum wurde keine Rate-Limiting-Middleware (`Microsoft.AspNetCore.RateLimiting` o. ä.) gefunden; zugleich ist `MaxRequestBodySize` explizit auf `null` (unbegrenzt) gesetzt, um große Datei-Uploads zu erlauben.
|
||||
Aussage: `[HYPOTHESE]` Das System besitzt aktuell keinen Schutz vor übermäßig häufigen oder übergroßen Anfragen auf API-Ebene; dies stellt ein Risiko für Denial-of-Service-Angriffe oder Ressourcenerschöpfung dar. Zur Bestätigung fehlt die Prüfung, ob Ratenbegrenzung auf einer vorgelagerten Netzwerkebene (Reverse Proxy, Firewall, WAF) beim Kunden umgesetzt wird, was im Code nicht sichtbar wäre.
|
||||
Ergebnis: Ohne vorgelagerten Schutz kann ein Client eine unbegrenzte Anzahl an Anfragen mit potenziell sehr großen Anfragekörpern senden.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/webservice/Centron.Host/CentronHost.cs` (`options.MaxRequestBodySize = null`) - Begründung: Konkrete, im Code deaktivierte Größenbegrenzung.
|
||||
- [KONTEXT] Fehlender Treffer für Rate-Limiting-Middleware bei gezielter Codesuche durch Recherche-Agent - Begründung: Negativbefund, kein direkter Dateibeleg möglich; daher Status HYPOTHESE für die Vollständigkeit der Aussage (evtl. Absicherung außerhalb des Repositories).
|
||||
Prüfidee: Lasttest mit hoher Anfragefrequenz gegen einen ungeschützten Webservice-Endpunkt durchführen und Systemverhalten (Verfügbarkeit, Ressourcenverbrauch) beobachten.
|
||||
Tracelinks: SyRS-003
|
||||
Konsolidierung: nein
|
||||
Status: HYPOTHESE
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-030
|
||||
Titel: Offene CORS-Konfiguration
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit (Lücke/Risiko)
|
||||
Akteur: System / Angreifer (Cross-Origin)
|
||||
Vorbedingung: -
|
||||
Fakt: `CentronHost.cs` konfiguriert CORS mit `AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()`.
|
||||
Aussage: Das System soll (aktuell) Cross-Origin-Anfragen von beliebigen Ursprüngen zulassen; dies ist eine bewusste oder historisch gewachsene Öffnung, die im Zielsystem (insb. bei mandantenfähigem SaaS-Betrieb) auf konkrete, vertrauenswürdige Ursprünge eingeschränkt werden sollte.
|
||||
Ergebnis: Eine beliebige Website kann клиентseitig (im Browserkontext) Anfragen an die c-entron-API stellen, sofern ein gültiges Ticket/Token vorliegt.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/webservice/Centron.Host/CentronHost.cs` (`.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()`) - Begründung: Konkrete, im Code gesetzte Konfiguration.
|
||||
Prüfidee: Cross-Origin-Testanfrage von einer Fremd-Domain mit gültigem Ticket absetzen und Antwortverhalten (CORS-Header) prüfen.
|
||||
Tracelinks: SyRS-003
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround (vermutlich historisch für Outlook-Add-in-/Iframe-Einbettung erforderlich, siehe StRS-020/SwRS)
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-031
|
||||
Titel: Unzureichend gesicherte Zugangsdaten in Container-Konfiguration
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit (Lücke/Risiko)
|
||||
Akteur: Betreiber, Angreifer mit Repository-/Image-Zugriff
|
||||
Vorbedingung: -
|
||||
Fakt: `docker/compose/compose.yaml` und `docker/deploy/compose.yaml` enthalten ein hartkodiertes, schwaches SA-Passwort (`SA!password`); `docker/compose/WebServiceConfig.xml` enthält eine Klartext-Datenbank-Verbindungszeichenfolge sowie einen wiederverwendeten Base64-`SecretKey`.
|
||||
Aussage: Das System soll (in der aktuellen Docker-Referenzkonfiguration) sicherstellen, dass Datenbankpasswörter, Verbindungszeichenfolgen und kryptografische Schlüssel nicht im Klartext im Versionskontrollsystem oder in Beispielkonfigurationen hinterlegt sind.
|
||||
Ergebnis: Aktuell ist dies nicht der Fall: Die genannten Geheimnisse sind im Repository einsehbar, was bei unveränderter Übernahme in Produktivbetrieb ein erhebliches Sicherheitsrisiko darstellt.
|
||||
Belege:
|
||||
- [PRIMÄR] `docker/compose/compose.yaml`, `docker/deploy/compose.yaml` (`MSSQL_SA_PASSWORD: SA!password`) - Begründung: Konkreter, im Repository sichtbarer Klartextwert.
|
||||
- [PRIMÄR] `docker/compose/WebServiceConfig.xml` (`DatabaseConnectionStringPlain`, `SecretKey`) - Begründung: Konkrete, im Repository sichtbare Klartext-Zugangsdaten.
|
||||
- [KONTEXT] `docker/README.md` (Hinweis, dass die Docker-Verpackung von einem Drittanbieter "für Dokumentationszwecke" stammt und ersetzt werden kann) - Begründung: Relativiert den Befund als Demo-/Referenzkonfiguration, nicht zwingend Produktivsetup; dennoch reales Risiko bei unreflektierter Übernahme.
|
||||
Prüfidee: Repository-Historie auf enthaltene Zugangsdaten scannen (z. B. mit Secret-Scanning-Tool); Empfehlung: Rotation aller im Repository sichtbaren Geheimnisse.
|
||||
Tracelinks: SyRS-033
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround (als Demo-/Referenzkonfiguration deklariert)
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-032
|
||||
Titel: On-Premise-Deployment als Windows-Dienst-Trio
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (Übertragbarkeit, ISO 25010)
|
||||
Akteur: Betreiber/Administrator beim Kunden
|
||||
Vorbedingung: -
|
||||
Fakt: Drei separate, code-signierte MSI-Installer: WPF-Desktop-Client ("c-entron 2.0"), Web-Service (`Centron.Host.WindowsService`) und Nexus (`CentronNexus.Host`, als Windows-Dienst "NEXOWARE ServiceBoard"); WiX-basiert (`deployment/centron`, `deployment/WixSharpInstaller`).
|
||||
Aussage: Das System soll in seiner aktuellen Auslieferungsform als drei getrennt zu installierende Windows-Komponenten (Desktop-Client je Arbeitsplatz, zentraler Web-Service, Nexus-Webportal) beim Kunden vor Ort betrieben werden können.
|
||||
Ergebnis: Eine Neuinstallation erfordert die Installation und Konfiguration aller drei Komponenten einzeln pro Kundenumgebung (kein Mandantenmodell mit gemeinsam genutzter Infrastruktur).
|
||||
Belege:
|
||||
- [PRIMÄR] `deployment/WixSharpInstaller/Program.cs`, `deployment/centron/CentronSetupProject`, `deployment/centron/WebServiceSetupProject` - Begründung: Konkrete Installer-Projekte für alle drei Komponenten.
|
||||
Prüfidee: Vollständige Neuinstallation aller drei Komponenten in einer sauberen Testumgebung durchführen und Aufwand/Abhängigkeiten dokumentieren.
|
||||
Tracelinks: -
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround (historisches On-Premise-Modell, für SaaS-Zielarchitektur zu ersetzen)
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-033
|
||||
Titel: Sekundäre Container-Bereitstellung (Docker/Linux)
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (Übertragbarkeit, ISO 25010)
|
||||
Akteur: Betreiber (Demo-/Testumgebung)
|
||||
Vorbedingung: -
|
||||
Fakt: Docker-Compose-Stack (`db`, `webservice`, `smtp`, `nexus`) existiert für Demo-/Testzwecke; laut `docker/README.md` stammt die Docker-Verpackung von einem Drittanbieter "zu Dokumentationszwecken" und ist nicht der primäre Auslieferungsweg. Web-Service kann zusätzlich manuell als Linux-Framework-dependent-Build betrieben werden (`docs/guides/services/web-service-on-linux.md`), jedoch ohne Konfigurationswerkzeug und ohne funktionierende Sub-Webservices.
|
||||
Aussage: Das System soll (ergänzend zum Windows-Betrieb) eine containerisierte bzw. Linux-basierte Bereitstellung des Web-Service und des Nexus-Portals ermöglichen, wenn auch mit eingeschränktem Funktionsumfang und ohne offizielle Erstunterstützung.
|
||||
Ergebnis: Web-Service und Nexus lassen sich unter Linux/Docker betreiben; Sub-Web-Services und eine grafische Konfigurationsoberfläche stehen dort jedoch nicht zur Verfügung.
|
||||
Belege:
|
||||
- [SEKUNDÄR] `docker/compose/compose.yaml`, `docker/README.md` - Begründung: Konkrete, aber als sekundär/nicht offiziell deklarierte Container-Definition.
|
||||
- [SEKUNDÄR] `docs/guides/services/web-service-on-linux.md` (Abschnitt "Differences between Linux and Windows") - Begründung: Explizit dokumentierte Funktionslücken unter Linux.
|
||||
Prüfidee: Web-Service unter Ubuntu/Debian gemäß Anleitung installieren und Funktionsumfang gegen Windows-Betrieb vergleichen (insbesondere Sub-Web-Services).
|
||||
Tracelinks: SyRS-031, SyRS-032
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-034
|
||||
Titel: Automatisierte, signierte Build- und Versionierungspipeline
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (Wartbarkeit, ISO 25010)
|
||||
Akteur: Entwickler, Build-System
|
||||
Vorbedingung: -
|
||||
Fakt: `Centron.Scripts`-Projekt erzeugt Versionsnummer (Nerdbank.GitVersioning, `version.json`), baut, signiert (Azure Trusted Signing) und archiviert Installer für Desktop-Client, Web-Service und Nexus; Azure-DevOps- und neuere GitHub-Actions-Pipelines (.NET 10) lösen dies pro Pull Request/Branch automatisch aus.
|
||||
Aussage: Das System soll bei jedem Merge in die Hauptzweige automatisiert kompiliert, versioniert, digital signiert und als Installationspaket bereitgestellt werden, ohne manuellen Eingriff.
|
||||
Ergebnis: Jeder erfolgreiche Build erzeugt eindeutig versionierte, signierte Installationspakete, die automatisch mit referenzierten Tickets verknüpft werden.
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/operations/build-server-and-automated-builds.md` (konkrete Versionsschema-, Signierungs- und Ticket-Verknüpfungslogik) - Begründung: Vollständig dokumentierter, produktiv laufender Prozess.
|
||||
- [SEKUNDÄR] `.github/workflows/build.yml` - Begründung: Aktuelle GitHub-Actions-Umsetzung.
|
||||
Prüfidee: Pull Request mit Ticketreferenz mergen; Build-Version muss automatisch im referenzierten Ticket hinterlegt werden.
|
||||
Tracelinks: -
|
||||
Konsolidierung: Kandidat: Parallel gepflegte Azure-DevOps-Pipelines (`azure/*`, `azure-blazor/*`) und neuere GitHub-Actions-Workflows decken teils dieselben Build-/Test-Schritte ab – Konsolidierungskandidat.
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-035
|
||||
Titel: Automatisiertes Sicherheits-Scanning in der CI-Pipeline
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Build-System
|
||||
Vorbedingung: -
|
||||
Fakt: `azure/analyze-pipeline.yml` und `azure-blazor/security-pipeline.yaml` führen nächtlich (Cron `0 0 * * *`) CodeQL-Analysen für C#/JavaScript sowie Abhängigkeitsprüfungen durch.
|
||||
Aussage: Das System soll regelmäßig automatisiert auf bekannte Sicherheitslücken im Quellcode und in Abhängigkeiten geprüft werden.
|
||||
Ergebnis: Neu eingeführte, durch CodeQL erkennbare Schwachstellen werden spätestens im nächsten nächtlichen Lauf gemeldet.
|
||||
Belege:
|
||||
- [SEKUNDÄR] `azure/analyze-pipeline.yml`, `azure-blazor/security-pipeline.yaml` - Begründung: Konkrete, im Repository vorhandene Pipeline-Definitionen laut Agentenrecherche.
|
||||
Prüfidee: Bekannte, absichtlich eingefügte Testschwachstelle in einem Feature-Branch committen und CodeQL-Erkennung im nächsten Lauf prüfen.
|
||||
Tracelinks: SyRS-034
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-036
|
||||
Titel: Reproduzierbare Ende-zu-Ende-Testumgebung
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (Zuverlässigkeit, ISO 25010)
|
||||
Akteur: Entwickler, CI-System
|
||||
Vorbedingung: -
|
||||
Fakt: Vor jedem EndToEnd-Test wird ein Datenbank-Backup restauriert, ausstehende Migrationsskripte ausgeführt, der Test ausgeführt und die Datenbank anschließend entfernt; Ergebnisse werden über Snapshot-Vergleich (`*.expected.txt` vs. `*.actual.txt`) verifiziert.
|
||||
Aussage: Das System soll über eine Testinfrastruktur verfügen, die für jeden Testlauf einen identischen Ausgangszustand garantiert, sodass Tests deterministisch reproduzierbar sind.
|
||||
Ergebnis: Ein und derselbe Test liefert bei unverändertem Code zu jedem Zeitpunkt dasselbe Ergebnis (keine Datenabhängigkeit von vorherigen Testläufen).
|
||||
Belege:
|
||||
- [PRIMÄR] `docs/guides/development/end-to-end-testing.md` (Ablaufbeschreibung Backup-Restore → Skriptausführung → Testausführung → Verifier-Snapshot-Vergleich) - Begründung: Konkret dokumentierter, technischer Testablauf.
|
||||
- [SEKUNDÄR] `.github/workflows/regression-tests.yml` (Guard gegen committete `Verifier.OverrideExpectedFiles = true`) - Begründung: Zusätzliche CI-seitige Absicherung der Testintegrität.
|
||||
Prüfidee: Denselben EndToEnd-Test zweimal hintereinander ausführen und Ergebnisidentität prüfen.
|
||||
Tracelinks: SyRS-034
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-037
|
||||
Titel: Web-basierte Kundenportal-Instanz (Nexus) als eigenständige Systemkomponente
|
||||
Ebene: SyRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: Endkunde, Service-Mitarbeiter
|
||||
Vorbedingung: -
|
||||
Fakt: `CentronNexus`/`CentronNexus.Host` ist eine Blazor-Server-Anwendung, separat installierbar (eigener Windows-Dienst "NEXOWARE ServiceBoard"), mit eigener Playwright-Testsuite und eigenständiger CI-Pipeline-Familie (`azure-blazor/*`).
|
||||
Aussage: Das System soll das Kundenportal und das interne ServiceBoard als eigenständig deploybare Webanwendung (getrennt vom WPF-Desktop-Client) bereitstellen, die dieselbe Geschäftslogik über den zentralen Webservice nutzt.
|
||||
Ergebnis: Nexus kann unabhängig vom WPF-Client aktualisiert und betrieben werden, ohne dass Endanwender eine lokale Installation benötigen.
|
||||
Belege:
|
||||
- [PRIMÄR] `deployment/WixSharpInstaller/Program.cs` (separater Installer/Windows-Dienst) - Begründung: Eigenständiger Installationsweg bestätigt Systemkomponente.
|
||||
- [PRIMÄR] `tests/PlaywrightTests/*` (Browser-E2E-Tests gegen Nexus) - Begründung: Automatisierte, laufende Tests belegen produktiven Charakter der Komponente.
|
||||
Prüfidee: Nexus ohne installierten WPF-Client betreiben und vollständigen Kundenportal-Workflow (StRS-018) end-to-end durchführen.
|
||||
Tracelinks: StRS-010, StRS-018, StRS-019, StRS-020, StRS-021
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-038
|
||||
Titel: Eigenständige Outlook-Add-in-Client-Integration
|
||||
Ebene: SyRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: Mitarbeiter mit Microsoft Outlook
|
||||
Vorbedingung: Add-in ist gemäß Office-Manifest installiert.
|
||||
Fakt: `CentronNexus.OutlookAddIn` wird über ein Microsoft-Office-"MailApp"-Manifest (`Manifest.xml`) bereitgestellt und im selben Host-Prozess wie Nexus ausgeliefert (`.AddOutlookAddInComponents()`); spezielle Middleware erlaubt die Einbettung in ein Outlook-Taskpane-iFrame.
|
||||
Aussage: Das System soll eine über das Microsoft-Office-Add-in-Framework standardkonform ausgelieferte Outlook-Erweiterung bereitstellen, die im selben Backend wie das Webportal läuft.
|
||||
Ergebnis: Das Add-in lässt sich über den regulären Office-Add-in-Store-/Manifest-Mechanismus in Outlook (Web, Desktop, Mac) installieren und funktioniert dort eingebettet.
|
||||
Belege:
|
||||
- [PRIMÄR] `src/nexus/CentronNexus.OutlookAddIn/Manifest/Manifest.xml` - Begründung: Konkretes, standardkonformes Office-Add-in-Manifest.
|
||||
Prüfidee: Add-in gemäß Manifest in Outlook (Desktop und Web) installieren und Grundfunktion (Ticket aus E-Mail erstellen) prüfen.
|
||||
Tracelinks: StRS-020
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
# Traceability-Tabelle – c-entron ERP
|
||||
|
||||
Konsolidierte Forward-/Backward-Traceability zwischen StRS, SyRS und SwRS. Jede Zeile verknüpft eine SwRS-Anforderung (sofern vorhanden) über ihre zugehörige SyRS-Anforderung mit der auslösenden StRS-Anforderung, zusammen mit dem primären Artefaktbeleg. "–" bedeutet: keine Anforderung auf dieser Ebene direkt verknüpft (z. B. rein architektonische SyRS ohne unmittelbare Stakeholder-Formulierung, oder StRS ohne bislang detaillierte SwRS-Ausprägung).
|
||||
|
||||
| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg |
|
||||
|---|---|---|---|
|
||||
| StRS-001 | SyRS-013 | SwRS-001 | `src/backend/Centron.Entities/Entities/Sales/Receipts/ReceiptBase.cs` |
|
||||
| StRS-001 | SyRS-014 | SwRS-002 | `src/backend/Centron.BL/Sales/Receipts/IReceiptSpecificLogic.cs` |
|
||||
| StRS-001 | SyRS-014 | SwRS-003 | `src/backend/Centron.BL/Sales/Receipts/SpecificLogics.cs` |
|
||||
| StRS-001 | SyRS-013 | SwRS-004 | `src/backend/Centron.Interfaces/Sales/Receipts/ReceiptState.cs`; `Entities/DbEntities/AufKopf.cs` |
|
||||
| StRS-001 | SyRS-015 | SwRS-005 | `docs/reference/receipts/receipts-backend-architecture.md` |
|
||||
| StRS-001 | SyRS-015 | SwRS-006 | `docs/reference/receipts/receipts-backend-architecture.md` (Abschnitt "Critical Save Warning") |
|
||||
| StRS-003 | SyRS-013 | SwRS-009 | `docs/reference/receipts/contracts-backend.md` |
|
||||
| StRS-004 | SyRS-013 | SwRS-010 | `docs/reference/receipts/Contract-Billing-RMM-Article-Logic.md` |
|
||||
| StRS-004 | SyRS-013 | SwRS-011 | `docs/reference/receipts/Contract-Billing-RMM-Article-Logic.md` |
|
||||
| StRS-005 | SyRS-014 | SwRS-002 | `src/backend/Centron.BL/Sales/Receipts/SupplierOrders/SupplierOrderSpecificLogic.cs` |
|
||||
| StRS-006 | SyRS-021 | SwRS-026 | `docs/reference/edi/edi-architecture.md` |
|
||||
| StRS-006 | SyRS-021 | SwRS-027 | `docs/reference/edi/edi-architecture.md` |
|
||||
| StRS-006 | SyRS-022 | SwRS-028 | `docs/reference/edi/edi-import-rules.md` |
|
||||
| StRS-007 | SyRS-013 | SwRS-001 | `src/backend/Centron.Entities/Entities/Sales/Receipts/ReceiptBase.cs` |
|
||||
| StRS-008 | SyRS-013 | SwRS-007 | `src/backend/Centron.BL/Sales/Receipts/ReceiptPriceHelperBL.cs` |
|
||||
| StRS-008 | SyRS-013 | SwRS-008 | `src/backend/Centron.BL/Warehousing/TaxBL.cs` |
|
||||
| StRS-009 | SyRS-013 | – | `src/centron/Centron.WPF.UI/Modules/Rma/RmaOverviewView.xaml` |
|
||||
| StRS-010 | SyRS-003 | – | `src/webservice/Centron.Controllers/Controllers/v1/Helpdesks/HelpdesksController.cs` |
|
||||
| StRS-010 | SyRS-037 | SwRS-034 | `src/centron/Centron.WPF.UI/Modules/ModuleRegistration.cs` |
|
||||
| StRS-011 | SyRS-013 | SwRS-034 | `docs/features/automatic-helpdesk-creation-templates.md` |
|
||||
| StRS-012 | SyRS-011 | SwRS-014 | `src/backend/Centron.BL/Administration/Rights/UserRightsExt.cs` |
|
||||
| StRS-013 | SyRS-011 | SwRS-012 | `src/backend/Centron.BL/Sales/Receipts/Invoices/Dunning/DunningBL.cs` |
|
||||
| StRS-013 | SyRS-011 | SwRS-013 | `src/backend/Centron.BL/Sales/Receipts/Invoices/Dunning/DunningBL.cs:1059` |
|
||||
| StRS-013 | SyRS-011 | SwRS-014 | `src/backend/Centron.BL/Administration/Rights/UserRightsExt.cs` |
|
||||
| StRS-014 | SyRS-011 | SwRS-013 | `src/backend/Centron.BL/Sales/Receipts/Invoices/Opos/OposBL.cs:28` |
|
||||
| StRS-014 | SyRS-011 | SwRS-014 | `src/backend/Centron.BL/Administration/Rights/UserRightsExt.cs` |
|
||||
| StRS-015 | SyRS-023 | SwRS-029 | `docs/reference/zugferd-field-mapping.md` |
|
||||
| StRS-015 | SyRS-024 | SwRS-029 | `docs/reference/zugferd-field-mapping.md` (Abschnitt "Validation Tolerances") |
|
||||
| StRS-015 | – | SwRS-030 | `src/apis/Centron.Api.EbInterface/EbInterfaceLogic.cs` |
|
||||
| StRS-016 | SyRS-011 | SwRS-014 | `src/backend/Centron.BL/Administration/Rights/UserRightsExt.cs` |
|
||||
| StRS-016 | SyRS-011 | SwRS-015 | `src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs` |
|
||||
| StRS-016 | SyRS-017 | SwRS-016 | `docs/guides/development/add-a-new-right.md` |
|
||||
| StRS-016 | SyRS-007 | SwRS-017 | `src/webservice/Centron.Host/AspNetCore/TicketAuthenticationHandler.cs` |
|
||||
| StRS-016 | SyRS-008 | SwRS-018 | `docs/reference/security/anmelden-mit-microsoft-technische-anleitung.md` |
|
||||
| StRS-016 | SyRS-008 | SwRS-019 | `src/webservice/Centron.Host/CentronHost.cs` |
|
||||
| StRS-016 | SyRS-009 | SwRS-020 | `src/webservice/Centron.Controllers/Controllers/v1/Administration/AccessTokensController.cs` |
|
||||
| StRS-016 | SyRS-012 | – | `docs/reference/receipts/receipt-search-architecture.md` |
|
||||
| StRS-017 | SyRS-018 | SwRS-021 | `docs/reference/security/licensing-system.md` |
|
||||
| StRS-017 | SyRS-013 | SwRS-034 | `src/centron/Centron.WPF.UI/Modules/ModuleRegistration.cs` |
|
||||
| StRS-018 | SyRS-003 | SwRS-001 | `src/backend/Centron.Entities/Entities/Sales/Receipts/ReceiptBase.cs` |
|
||||
| StRS-018 | SyRS-037 | – | `tests/PlaywrightTests/WebaccountTests.cs` |
|
||||
| StRS-019 | SyRS-011 | – | `tests/PlaywrightTests/WebaccountTests.cs` |
|
||||
| StRS-019 | SyRS-012 | – | `tests/PlaywrightTests/WebaccountTests.cs` |
|
||||
| StRS-020 | SyRS-038 | – | `src/nexus/CentronNexus.OutlookAddIn/Manifest/Manifest.xml` |
|
||||
| StRS-021 | SyRS-027 | SwRS-031 | `docs/features/exchange-sync-bugprotokoll.md` |
|
||||
| StRS-021 | SyRS-027 | SwRS-032 | `docs/features/exchange-sync-bugprotokoll.md` (Ticket 164020, 158813) |
|
||||
| StRS-022 | SyRS-003 | – | `src/apis/Centron.Api.Gls/CentronGlsLogic.cs`; `src/apis/Centron.Api.Shipcloud/CentronShipcloudLogic.cs` |
|
||||
| StRS-023 | SyRS-013 | – | `src/apis/Centron.APIs.ITscopeDataAccess/ITscopeApi.cs` |
|
||||
| StRS-024 | SyRS-013 | – | `src/apis/Centron.APIs.FinAPI/FinApiClient.cs` |
|
||||
| StRS-025 | SyRS-013 | – | `Centron.Api.docuFORM/Models/Swagger/DeviceCounters.cs` |
|
||||
| StRS-026 | SyRS-013 | – | `src/centron/Centron.WPF.UI/Modules/Statistics/SaleStatistics` |
|
||||
| StRS-027 | SyRS-012 | – | `docs/reference/receipt-search-architecture.md` (Branch Isolation) |
|
||||
| StRS-028 | – | – | `src/centron/Centron.WPF.UI/Modules/Administration/DSGVO/CentronDataSecurityView.xaml` (HYPOTHESE) |
|
||||
| StRS-029 | SyRS-013 | – | `src/webservice/Centron.Controllers/Controllers/v1/Administration/ArtificialIntelligenceChatsController.cs` |
|
||||
| StRS-030 | SyRS-001 | – | `docs/getting-started/general-structure.md` |
|
||||
| – | SyRS-002 | SwRS-037 | `src/webservice/Centron.Controllers/Configuration/GlobalExceptionFilter.cs` |
|
||||
| – | SyRS-004 | SwRS-036 | `src/webservice/Centron.Host/AspNetCore/WcfBridge/CentronWcfBridge.cs` |
|
||||
| – | SyRS-005 | – | `src/webservice/Centron.Controllers/Controllers/v1/**` |
|
||||
| – | SyRS-006 | – | `src/webservice/Centron.Host/RealTimeServices/ChatHub.cs` |
|
||||
| – | SyRS-010 | – | `docs/reference/receipts/receipt-search-architecture.md` |
|
||||
| – | SyRS-016 | SwRS-022 | `docs/guides/database/settings-management.md` |
|
||||
| – | SyRS-016 | SwRS-024 | `docs/reference/architecture/dtos-and-entities.md` |
|
||||
| – | SyRS-016 | SwRS-025 | `src/backend/Centron.DAO/GenericStoredProcedureDAO.cs` |
|
||||
| – | SyRS-016 | SwRS-038 | `src/backend/Centron.Entities/PersistedEntity.cs` |
|
||||
| – | SyRS-017 | SwRS-023 | `docs/reference/database/script-rules.md` |
|
||||
| – | SyRS-019 | – | `docs/guides/ui/localization.md` |
|
||||
| – | SyRS-020 | – | `docs/getting-started/general-structure.md` (File Encoding Requirements) |
|
||||
| – | SyRS-025 | SwRS-033 | `docs/Background Service/DataQualityService.md` |
|
||||
| – | SyRS-026 | – | `docs/reference/edi/edi-import-rules.md` (Execution Frequency) |
|
||||
| – | SyRS-028 | SwRS-035 | `docs/reference/security/developer-security.md` |
|
||||
| – | SyRS-029 | – | `src/webservice/Centron.Host/CentronHost.cs` (`MaxRequestBodySize = null`) (HYPOTHESE) |
|
||||
| – | SyRS-030 | – | `src/webservice/Centron.Host/CentronHost.cs` (`AllowAnyOrigin`) |
|
||||
| – | SyRS-031 | – | `docker/compose/compose.yaml`; `docker/compose/WebServiceConfig.xml` |
|
||||
| – | SyRS-032 | – | `deployment/WixSharpInstaller/Program.cs` |
|
||||
| – | SyRS-033 | – | `docker/compose/compose.yaml`; `docs/guides/services/web-service-on-linux.md` |
|
||||
| – | SyRS-034 | – | `docs/operations/build-server-and-automated-builds.md` |
|
||||
| – | SyRS-035 | – | `azure/analyze-pipeline.yml`; `azure-blazor/security-pipeline.yaml` |
|
||||
| – | SyRS-036 | – | `docs/guides/development/end-to-end-testing.md` |
|
||||
|
||||
## Hinweise zur Traceability
|
||||
|
||||
- Mehrere SwRS-Anforderungen referenzieren dieselbe SyRS-/StRS-Anforderung (z. B. SwRS-012/SwRS-013/SwRS-014 unter StRS-013), da eine fachliche Anforderung typischerweise durch mehrere zusammenwirkende Softwarekomponenten realisiert wird.
|
||||
- Zeilen mit "–" in der StRS-Spalte kennzeichnen SyRS-Anforderungen, die primär architektonisch/technisch begründet sind (z. B. Fehlerbehandlung, Datenbankkonventionen) und keiner einzelnen, isolierten Stakeholder-Anforderung zugeordnet wurden, jedoch mehrere StRS-Anforderungen querschnittlich unterstützen.
|
||||
- Zeilen mit "–" in der SwRS-Spalte kennzeichnen StRS-/SyRS-Anforderungen, zu denen im Rahmen dieser Iteration keine tiefergehende komponentenbezogene Analyse (SwRS-Ebene) durchgeführt wurde (siehe `Analysebericht.md`, Abschnitt Abdeckung/Tiefe).
|
||||
- Die vollständige, bidirektionale Referenzierung ist zusätzlich in den `Tracelinks`-Feldern der einzelnen Anforderungen in `StRS.md`, `SyRS.md` und `SwRS.md` hinterlegt.
|
||||
+221
@@ -0,0 +1,221 @@
|
||||
# Messprotokoll – V1 Baseline (Prompt-only) – Iteration 01, Lauf 3
|
||||
|
||||
> Dritter Lauf des Prompts `01_Prompt.md`, erster **vollständiger** Lauf unter der ab
|
||||
> Iteration 02 geltenden Werkzeugkonfiguration (Shell-Zugriff, Snapshot-Isolation).
|
||||
> Vorgeschichte: Lauf 1 (`claude-sonnet-5/builtin/high/01_Lauf_2026-08-25_122905_v1.0.0-23e8`) vollständig unter der Alt-Konfiguration;
|
||||
> Lauf 2 (`claude-sonnet-5/builtin/high/01_Lauf_2026-08-25_134905_v2.0.0-8b0a`) mit neuer Konfiguration, nach 24:08 durch API-Fehler
|
||||
> abgebrochen. Dieser Lauf ist die gültige Messung für die neue Konfiguration.
|
||||
|
||||
## Lauf
|
||||
- **Prompt-Datei:** `Versuche/Versuch_01/01_Prompt.md`
|
||||
- **SHA-256 (Prompt):** `1B0DB06B8E0A5B92A5EFBDBEC5A0C554351FC928A16AEF34AAD9EAA0893C02FF`
|
||||
(identisch zu Lauf 1 und 2 – der Prompt wurde nie verändert)
|
||||
- **Startzeit:** 2026-08-25T14:29:32.2116097+02:00
|
||||
- **Endzeit:** 2026-08-25T14:53:12.2739434+02:00
|
||||
- **Dauer gesamt:** 00:23:40 (Wanduhr) bzw. 00:23:22 (`duration_ms`) — API: 00:43:25 (`duration_api_ms`)
|
||||
- Die API-Dauer übersteigt die Wanduhrzeit, weil 7 `Explore`-Subagenten nebenläufig liefen.
|
||||
- **Root-Verzeichnis:** `c:\DEV\MasterArbeit\QuellCode\CentronERP`
|
||||
- **Codebasis-Commit:** `79c1142f489a32ba6a4a4cb043fd7f8550a9f257` (dirty: nein)
|
||||
- **Snapshot-Zustand:** bereinigt von KI-Konfigurationen: **ja** (Prüfung vor dem Lauf: 0 Treffer);
|
||||
Remote entkoppelt: **ja** (`git remote` leer)
|
||||
- **Prompt-Repo-Commit:** `0ec86aed8cb8781054c86cbe0dd9f5eb0f7e5f05`
|
||||
|
||||
## Werkzeugkonfiguration
|
||||
- **Laufverzeichnis-ID:** `v2.0.1-5dc4`
|
||||
- **Ablage:** `claude-sonnet-5/builtin/high/`
|
||||
- **Parallele Läufe:** nein
|
||||
- **Skill-Version:** `2.0.1` (wie 2.0.0, zusätzlich leerwertsicheres `before.txt`)
|
||||
- **Claude-Code-Version:** 2.1.245
|
||||
- **CLI-Pfad:** `C:\Users\ChristophSchwoerer\.vscode\extensions\anthropic.claude-code-2.1.245-win32-x64\resources\native-binary\claude.exe`
|
||||
- **Effort:** `high` — **nicht zur Laufzeit gesetzt**, sondern aus der Sitzung geerbt und
|
||||
nachtraeglich aus dem Session-Transkript rekonstruiert (104 Nachrichten, durchgaengig `high`).
|
||||
`RawResult.json` enthaelt kein `effort`-Feld. Ab Skill-Version 3.4.0 wird der Wert per
|
||||
`--effort` explizit gesetzt.
|
||||
- **Modell:** `claude-sonnet-5` (explizit gesetzt, Kontextfenster 1.000.000, max. Output 64.000);
|
||||
zusätzlich `claude-haiku-4-5-20251001` für interne Hilfsaufrufe (4.176 Input-/21 Output-Tokens)
|
||||
- **Permission-Mode:** `acceptEdits`
|
||||
- **Toolfreigabe:**
|
||||
- `--allowedTools "Bash" "PowerShell"`
|
||||
- `--disallowedTools` mit 33 Einträgen: 22 × `Bash(...)`, 11 × `PowerShell(...)` für schreibende
|
||||
Kommandos (`rm`, `rmdir`, `mv`, `cp`, `dd`, `truncate`, `chmod`, `chown`, `ln`, `tee`, `sed -i`,
|
||||
`Remove-Item`, `Move-Item`, `Copy-Item`, `New-Item`, `Set-Content`, `Add-Content`,
|
||||
`Clear-Content`, `Out-File`, `Set-ItemProperty`), Git-Mutationen (`checkout`, `restore`,
|
||||
`clean`, `reset`, `add`, `commit`, `push`) und Build-Werkzeuge (`dotnet`, `msbuild`,
|
||||
`nuget`, `npm install`)
|
||||
- **Isolationsmechanismus:** eingefrorener Codebasis-Snapshot ohne KI-Konfigurationen,
|
||||
zusätzlich `--safe-mode` und `--strict-mcp-config`
|
||||
- **MCP-Server / Agentendateien:** keine – aus dem Snapshot entfernt, zusätzlich `--safe-mode`
|
||||
- **Subagenten:** 7 × `Explore` (max. Tiefe 1, 7 abgeschlossen, 0 fehlgeschlagen)
|
||||
- **Fast-Mode:** aus
|
||||
|
||||
## Verbrauch
|
||||
|
||||
### Hauptagent (`usage`)
|
||||
| Messgröße | Wert |
|
||||
|---|---|
|
||||
| Input-Tokens | 52 |
|
||||
| Output-Tokens | 140.195 (davon 27.568 Thinking-Tokens) |
|
||||
| Cache-Write-Tokens | 372.984 |
|
||||
| Cache-Read-Tokens | 5.246.930 |
|
||||
| Agent-Turns | 69 |
|
||||
|
||||
### Gesamtlauf inkl. Subagenten (`modelUsage`, abrechnungsrelevant)
|
||||
| Messgröße | `claude-sonnet-5` | `claude-haiku-4-5-20251001` | Summe |
|
||||
|---|---:|---:|---:|
|
||||
| Input-Tokens | 312 | 4.176 | 4.488 |
|
||||
| Output-Tokens | 229.976 | 21 | 229.997 |
|
||||
| Cache-Write-Tokens | 739.626 | 0 | 739.626 |
|
||||
| Cache-Read-Tokens | 10.542.089 | 0 | 10.542.089 |
|
||||
| Tokens gesamt | 11.512.003 | 4.197 | **11.516.200** |
|
||||
|
||||
**Tokens gesamt: 11.516.200** (Summe aus Input, Output, Cache-Write und Cache-Read ueber alle Modelle; `total_cost_usd` steht weiterhin in `RawResult.json`)
|
||||
|
||||
## Ergebnis
|
||||
- **Status:** erfolgreich (`is_error: false`, `subtype: "success"`, `stop_reason: "end_turn"`,
|
||||
`terminal_reason: "completed"`, Exit-Code 0, `Stderr.log` leer)
|
||||
- **Session-ID:** `88426b05-5eb1-4dbd-b89a-ffe5c7220ac4`
|
||||
- **Permission-Denials:** **0**
|
||||
- **Erzeugte Dateien:** alle 7 geforderten Artefakte in `Ergebnisse\`
|
||||
|
||||
| Datei | Größe | Inhalt |
|
||||
|---|---:|---|
|
||||
| `StRS.md` | 44.803 B | 30 Anforderungen |
|
||||
| `SyRS.md` | 53.729 B | 38 Anforderungen |
|
||||
| `SwRS.md` | 57.279 B | 38 Anforderungen |
|
||||
| `Traceability.md` | 9.010 B | 56 Zeilen StRS→SyRS→SwRS |
|
||||
| `Hypothesen.md` | 6.812 B | 9 Einträge (H-001…H-009) |
|
||||
| `Glossar.md` | 10.710 B | Domänenbegriffe |
|
||||
| `Analysebericht.md` | 13.802 B | Abdeckungstiefe je Modul, Konsistenzcheck, Selbstbewertung |
|
||||
|
||||
Summe: **106 Anforderungen** über drei Ebenen.
|
||||
- **Root unverändert:** ja. Vorher/Nachher-Vergleich per `git status --porcelain` identisch
|
||||
(beide leer), HEAD unverändert `79c1142`. Der Lauf hat trotz voller Shell-Freigabe keine Datei
|
||||
der Codebasis angelegt, geändert oder gelöscht.
|
||||
- **Abschlusstext des Agenten:** siehe `RawResult.json` (`result`)
|
||||
|
||||
## Gefundene Anforderungen
|
||||
|
||||
Maschinell aus `Ergebnisse\StRS.md`, `SyRS.md` und `SwRS.md` ausgewertet (Blockformat des Prompts). Erzeugt von `analyse-anforderungen.py`.
|
||||
|
||||
### Verteilung über die Ebenen
|
||||
|
||||
| Ebene | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| StRS | 30 | 28,3 % |
|
||||
| SyRS | 38 | 35,8 % |
|
||||
| SwRS | 38 | 35,8 % |
|
||||
| **Gesamt** | **106** | 100 % |
|
||||
|
||||
### Anforderungstypen
|
||||
|
||||
| Typ | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| funktional | 37 | 34,9 % |
|
||||
| Sicherheit | 23 | 21,7 % |
|
||||
| Schnittstelle | 14 | 13,2 % |
|
||||
| Daten | 13 | 12,3 % |
|
||||
| nicht-funktional (Zuverlässigkeit, ISO 25010) | 7 | 6,6 % |
|
||||
| nicht-funktional (Wartbarkeit, ISO 25010) | 3 | 2,8 % |
|
||||
| nicht-funktional (Übertragbarkeit, ISO 25010) | 3 | 2,8 % |
|
||||
| Sicherheit (Lücke/Risiko) | 2 | 1,9 % |
|
||||
| nicht-funktional | 1 | 0,9 % |
|
||||
| nicht-funktional (Wartbarkeit / Übertragbarkeit, ISO 25010) | 1 | 0,9 % |
|
||||
| (2 weitere) | 2 | 1,9 % |
|
||||
|
||||
### Belegqualität
|
||||
|
||||
| Messgröße | Wert |
|
||||
|---|---:|
|
||||
| Belege gesamt | 143 |
|
||||
| davon `PRIMÄR` | 98 (68,5 %) |
|
||||
| davon `SEKUNDÄR` | 41 (28,7 %) |
|
||||
| davon `KONTEXT` | 4 (2,8 %) |
|
||||
| Belege je Anforderung (Median) | 1,0 |
|
||||
| Anforderungen mit mindestens einem `PRIMÄR`-Beleg | 89 (84,0 %) |
|
||||
|
||||
### Status
|
||||
|
||||
| Kategorie | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| belegt | 103 | 97,2 % |
|
||||
| als `HYPOTHESE` gekennzeichnet | 3 | 2,8 % |
|
||||
| als Workaround vermerkt | 10 | 9,4 % |
|
||||
| Konsolidierungskandidaten | 12 | 11,3 % |
|
||||
| mit ISO-25010-Qualitätsmerkmal | 0 | 0,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]` | **verletzt** – 1 von 43 ungedeckt: SyRS-035 |
|
||||
| **Verifizierbarkeit** – jede Anforderung mit Prüfidee oder Akzeptanzkriterium | **erfüllt** |
|
||||
| **Traceability** – Verknüpfung zwischen den Ebenen | 97 von 106 mit Tracelinks (91,5 %) |
|
||||
|
||||
## Vergleich der drei Läufe (identischer Prompt)
|
||||
|
||||
| Messgröße | Lauf 1 (alt) | Lauf 2 (neu, Abbruch) | **Lauf 3 (neu)** |
|
||||
|---|---:|---:|---:|
|
||||
| Werkzeugkonfiguration | ohne Shell | mit Shell | mit Shell |
|
||||
| Status | erfolgreich | **API-Fehler** | erfolgreich |
|
||||
| Permission-Denials | 36 | 0 | **0** |
|
||||
| Dauer (Wanduhr) | 31:31 | 31:24 | **23:40** |
|
||||
| Agent-Turns | 43 | 8 | 69 |
|
||||
| Subagenten | 8 × Explore | 6 × general-purpose | 7 × Explore |
|
||||
| Anforderungen gesamt | 96 | 89 (unvollständig) | **106** |
|
||||
| — davon StRS / SyRS / SwRS | 28 / 28 / 40 | 45 / 44 / – | 30 / 38 / 38 |
|
||||
| Traceability-Zeilen | 44 | – | 56 |
|
||||
| Hypothesen | 12 | – | 9 |
|
||||
| Output-Tokens (gesamt) | 249.040 | 226.613 | 229.997 |
|
||||
| Cache-Read-Tokens | 11.959.137 | 15.618.130 | 10.542.089 |
|
||||
| Tokens gesamt | 13.052.010 | 16.655.125 | **11.516.200** |
|
||||
|
||||
## Anmerkungen/Auffälligkeiten
|
||||
|
||||
1. **Shell-Zugriff wirkt: 0 statt 36 Permission-Denials.** Die Werkzeugkonfiguration hat den
|
||||
Lauf zu keinem Zeitpunkt eingeschränkt. Gleichzeitig ist der Lauf **schneller** (23:40 statt
|
||||
31:31) und **günstiger** (6,82 statt 13.052.010 Tokens) als Lauf 1 und liefert **mehr** Anforderungen
|
||||
(106 statt 96) sowie eine dichtere Traceability (56 statt 44 Zeilen). Die Cache-Read-Tokens
|
||||
sanken um 12 % – der Agent musste weniger wiederholt lesen, weil er gezielt suchen konnte.
|
||||
|
||||
2. **Deutlich mehr Agent-Turns bei kürzerer Laufzeit:** 69 statt 43. Der Agent führte mehr,
|
||||
dafür kleinere und gezieltere Werkzeugschritte aus – ein plausibler Effekt des Shell-Zugriffs,
|
||||
der Inventuren in einem Aufruf erledigt, statt sie über viele Dateilesungen zu rekonstruieren.
|
||||
|
||||
3. **Verschiebung der Anforderungsverteilung.** Lauf 1 war SwRS-lastig (28/28/40), Lauf 3 ist
|
||||
gleichmäßiger und system-schwerer (30/38/38). Ob das an der Werkzeugkonfiguration liegt oder
|
||||
Laufvarianz ist, lässt sich aus einem einzelnen Lauf nicht entscheiden; für belastbare
|
||||
Aussagen wären Wiederholungsläufe nötig.
|
||||
|
||||
4. **Subagenten-Typ ist keine Konstante.** Lauf 1: 8 × `Explore`; Lauf 2: 6 × `general-purpose`;
|
||||
Lauf 3: 7 × `Explore` – bei identischem Prompt. Die Wahl trifft der Agent selbst und sie
|
||||
beeinflusst Laufzeit und Kosten, ist also bei Vergleichen als Störgröße zu führen.
|
||||
|
||||
5. **Konsistenzcheck laut Agent:** keine doppelten oder verwaisten IDs; zwei fehlerhafte
|
||||
Tracelinks wurden vor Abgabe gefunden und korrigiert (dokumentiert im `Analysebericht.md`).
|
||||
|
||||
6. **Zählabweichung bei Hypothesen** (wie in Lauf 1, in geringerem Ausmaß): `Hypothesen.md`
|
||||
führt 9 Einträge, in den Anforderungsdateien stehen 8 Inline-Markierungen `[HYPOTHESE]`.
|
||||
Für die Auswertung der Belegdichte ist weiterhin zu klären, welche Zählweise maßgeblich ist.
|
||||
|
||||
7. **Sicherheitsbefunde:** Der Agent weist auf SyRS-Ebene fehlende Rate-Limitierung, offene
|
||||
CORS-Konfiguration und Secrets in Docker-Konfigurationen aus. Der SHA-1-Passwortbefund aus
|
||||
Lauf 1 ist im Abschlusstext dieses Laufs nicht erwähnt – ein Hinweis darauf, dass die
|
||||
Befundmenge zwischen Läufen variiert und eine Zusammenführung über mehrere Läufe sinnvoll ist.
|
||||
|
||||
8. **Abdeckung laut Selbstbewertung:** Tiefe auf Beleg-/Abrechnungs-Engine, Rechte/Auth/Lizenzen,
|
||||
EDI/E-Rechnung und Deployment/Sicherheit. Explizit flach oder gar nicht analysiert:
|
||||
Production, PLM, QM, C-Sign, C-FLOW, DSGVO-Modulinterna. Der Agent dokumentiert das als
|
||||
Abdeckungstabelle statt gleichmäßige Abdeckung zu behaupten.
|
||||
|
||||
9. **Verlaufsbeobachtung:** Der abgebrochene Lauf 2 hatte bis zum Abbruch mehr Anforderungen
|
||||
je Ebene erzeugt (StRS 45, SyRS 44) als Lauf 3 (30, 38) – bei ähnlichem Output-Token-Volumen.
|
||||
Die Mengengerüste schwanken zwischen Läufen also erheblich; Anforderungsanzahl allein ist
|
||||
kein robustes Qualitätsmaß.
|
||||
|
||||
10. **Werkzeughinweis:** Die Verfolgung des Hintergrundprozesses durch die Oberfläche riss
|
||||
während dieses Laufs ab (Meldung „stopped" ohne Abschlussdatensatz), während der Prozess
|
||||
normal weiterlief. Der Abschluss wurde über eine eigene Warteschleife auf
|
||||
`RawResult.json` erkannt. Kein Einfluss auf die Messwerte.
|
||||
|
||||
11. **Manuelle Eingriffe während des Laufs:** keine.
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"is_error":false,"duration_api_ms":2605172,"num_turns":69,"stop_reason":"end_turn","session_id":"88426b05-5eb1-4dbd-b89a-ffe5c7220ac4","total_cost_usd":6.8216238,"usage":{"input_tokens":52,"cache_creation_input_tokens":372984,"cache_read_input_tokens":5246930,"output_tokens":140195,"output_tokens_details":{"thinking_tokens":27568},"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":372984,"ephemeral_5m_input_tokens":0},"inference_geo":"not_available","iterations":[{"input_tokens":2,"output_tokens":763,"cache_read_input_tokens":410704,"cache_creation_input_tokens":722,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":722},"type":"message"}],"speed":"standard"},"modelUsage":{"claude-haiku-4-5-20251001":{"inputTokens":4176,"outputTokens":21,"cacheReadInputTokens":0,"cacheCreationInputTokens":0,"webSearchRequests":0,"costUSD":0.004281,"contextWindow":200000,"maxOutputTokens":32000,"canonicalModel":"claude-haiku-4-5","provider":"firstParty"},"claude-sonnet-5":{"inputTokens":312,"outputTokens":229976,"cacheReadInputTokens":10542089,"cacheCreationInputTokens":739626,"webSearchRequests":0,"costUSD":6.8173428000000005,"contextWindow":1000000,"maxOutputTokens":64000,"canonicalModel":"claude-sonnet-5","provider":"firstParty"}},"permission_denials":[],"terminal_reason":"completed","fast_mode_state":"off","fast_mode_disabled_reason":"extra_usage_disabled","subagent_stats":{"spawned":7,"requested":{"background":0,"foreground":0,"unset":7},"started_in_background":7,"max_depth":1,"spawned_by_subagents":0,"completed":7,"failed":0,"killed":{"parent":0,"user":0,"system":0},"refused":{"depth_limit":0,"concurrency_limit":0,"budget":0},"by_type":{"Explore":7}},"subtype":"success","api_error_status":null,"result":"All seven required deliverables have been produced in `Ergebnisse/`:\n\n- **StRS.md** – 30 stakeholder requirements (order-to-cash, contracts/RMM billing, EDI, CRM, RMA, helpdesk, dunning/OPOS, e-invoicing, rights, licensing, customer web portal, Outlook/Exchange integration, shipping/banking/catalog/MPS integrations, reporting, GDPR, AI assistant).\n- **SyRS.md** – 38 system-level requirements (3-tier architecture, Result/Response pattern, legacy WCF-bridge + modern v1 API, SignalR, auth (ticket/OIDC/JWT/AccessToken/RADIUS-2FA), branch isolation, receipt state machine, DB/migration conventions, EDI/e-invoicing, background services, Nexus/Outlook add-in, plus flagged security gaps: missing rate limiting, open CORS, secrets in Docker configs).\n- **SwRS.md** – 38 component-level requirements with concrete class/method/table evidence (ReceiptBase/IReceiptSpecificLogic/SpecificLogics, TaxBL, DunningBL/OposBL rights guards, UserRightsExt, auth handlers, licensing, ScriptMethod migrations, EDI partial classes, ZUGFeRD mapping, Exchange sync source-of-truth rule, etc.).\n- **Traceability.md**, **Hypothesen.md** (9 open questions with what's missing to confirm them), **Glossar.md**, and **Analysebericht.md** (module coverage-depth table, consistency check — no duplicate/dangling IDs, two tracelink errors found and fixed — and a self-assessment with concrete follow-up priorities).\n\nGiven the codebase's scale (~15,500 C# files), this iteration deliberately concentrated depth on the receipt/billing engine, rights/auth/licensing, EDI/e-invoicing, and deployment/security, while explicitly documenting shallow or unanalyzed areas (Production, PLM, QM, C-Sign, C-FLOW, GDPR module internals, etc.) rather than claiming uniform coverage — as the Analysebericht spells out for follow-up iterations.","ttft_ms":9636,"ttft_stream_ms":2977,"time_to_request_ms":41,"type":"result","duration_ms":1401511,"uuid":"f7b4c7b1-1efe-4848-ab48-d5609ae4d2a4","queued_turn_count":0}
|
||||
+1735
File diff suppressed because it is too large
Load Diff
+59
@@ -0,0 +1,59 @@
|
||||
## Gefundene Anforderungen
|
||||
|
||||
Maschinell aus `Ergebnisse\StRS.md`, `SyRS.md` und `SwRS.md` ausgewertet (Blockformat des Prompts). Erzeugt von `analyse-anforderungen.py`.
|
||||
|
||||
### Verteilung über die Ebenen
|
||||
|
||||
| Ebene | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| StRS | 30 | 28,3 % |
|
||||
| SyRS | 38 | 35,8 % |
|
||||
| SwRS | 38 | 35,8 % |
|
||||
| **Gesamt** | **106** | 100 % |
|
||||
|
||||
### Anforderungstypen
|
||||
|
||||
| Typ | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| funktional | 37 | 34,9 % |
|
||||
| Sicherheit | 23 | 21,7 % |
|
||||
| Schnittstelle | 14 | 13,2 % |
|
||||
| Daten | 13 | 12,3 % |
|
||||
| nicht-funktional (Zuverlässigkeit, ISO 25010) | 7 | 6,6 % |
|
||||
| nicht-funktional (Wartbarkeit, ISO 25010) | 3 | 2,8 % |
|
||||
| nicht-funktional (Übertragbarkeit, ISO 25010) | 3 | 2,8 % |
|
||||
| Sicherheit (Lücke/Risiko) | 2 | 1,9 % |
|
||||
| nicht-funktional | 1 | 0,9 % |
|
||||
| nicht-funktional (Wartbarkeit / Übertragbarkeit, ISO 25010) | 1 | 0,9 % |
|
||||
| (2 weitere) | 2 | 1,9 % |
|
||||
|
||||
### Belegqualität
|
||||
|
||||
| Messgröße | Wert |
|
||||
|---|---:|
|
||||
| Belege gesamt | 143 |
|
||||
| davon `PRIMÄR` | 98 (68,5 %) |
|
||||
| davon `SEKUNDÄR` | 41 (28,7 %) |
|
||||
| davon `KONTEXT` | 4 (2,8 %) |
|
||||
| Belege je Anforderung (Median) | 1,0 |
|
||||
| Anforderungen mit mindestens einem `PRIMÄR`-Beleg | 89 (84,0 %) |
|
||||
|
||||
### Status
|
||||
|
||||
| Kategorie | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| belegt | 103 | 97,2 % |
|
||||
| als `HYPOTHESE` gekennzeichnet | 3 | 2,8 % |
|
||||
| als Workaround vermerkt | 10 | 9,4 % |
|
||||
| Konsolidierungskandidaten | 12 | 11,3 % |
|
||||
| mit ISO-25010-Qualitätsmerkmal | 0 | 0,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]` | **verletzt** – 1 von 43 ungedeckt: SyRS-035 |
|
||||
| **Verifizierbarkeit** – jede Anforderung mit Prüfidee oder Akzeptanzkriterium | **erfüllt** |
|
||||
| **Traceability** – Verknüpfung zwischen den Ebenen | 97 von 106 mit Tracelinks (91,5 %) |
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
[
|
||||
{
|
||||
"id": "toolu_014c5RBBXovP3hsw2khZxMMY",
|
||||
"werkzeug": "Agent",
|
||||
"subagent_type": "Explore",
|
||||
"description": "Survey backend domain model (Entities)",
|
||||
"run_in_background": null,
|
||||
"model": null,
|
||||
"prompt": "You are surveying a large legacy C# ERP codebase (c-entron ERP) at C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP for a reverse-engineering requirements analysis. This is read-only exploration — do not modify anything.\n\nFocus area: C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP\\src\\backend\\Centron.Entities (1185 .cs files) — this is presumably the domain/entity model layer.\n\nTask: Produce an inventory, not a deep read of every file. Specifically:\n1. List the top-level namespace/folder structure under Centron.Entities (what business areas do the folder names suggest — e.g. Auftrag, Rechnung, Artikel, Kunde, Lager, Personal, etc.)\n2. For each major business area folder, sample 2-4 representative entity classes and note: class name, file path, notable fields (especially status/enum fields, foreign keys, audit fields), and any inline validation attributes or comments suggesting business rules.\n3. Look specifically for status/enum types (e.g. AuftragStatus, RechnungStatus, files with \"Status\" or \"Enum\" in the name) across the whole folder — list file paths and the enum values found, since status machines are high-value for requirements extraction.\n4. Look for any classes/attributes suggesting audit trail, soft-delete, multi-tenant/mandant fields, or versioning.\n\nReport back as structured text: a list of business areas with file path evidence, a list of found status enums with their values and file paths, and any other structural observations. Include concrete file paths for everything (I need traceability evidence). Keep the report focused and factual — this feeds into a formal requirements specification, so cite exact paths, not vague descriptions. Aim for a report of 800-1500 words.",
|
||||
"ergebnis_zeichen": 1093
|
||||
},
|
||||
{
|
||||
"id": "toolu_01PAjHsNvGeWGQE4eGYGXsnM",
|
||||
"werkzeug": "Agent",
|
||||
"subagent_type": "Explore",
|
||||
"description": "Survey backend business logic (BL)",
|
||||
"run_in_background": null,
|
||||
"model": null,
|
||||
"prompt": "You are surveying a large legacy C# ERP codebase (c-entron ERP) at C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP for a reverse-engineering requirements analysis. This is read-only exploration — do not modify anything.\n\nFocus area: C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP\\src\\backend\\Centron.BL (2068 .cs files) — presumably the business logic layer.\n\nTask: Produce an inventory, not a deep read of every file. Specifically:\n1. List the top-level namespace/folder structure under Centron.BL (what business areas/modules do folder names suggest — e.g. Auftrag, Rechnung/Faktura, Artikel, Kunde/CRM, Lager, Einkauf, Zeiterfassung/Timer, C-Sign, Benutzerverwaltung/Berechtigungen, etc.)\n2. Search for and list files/classes related to: status transitions or workflow logic (methods like \"ChangeStatus\", \"SetStatus\", state machine patterns), permission/rights checks (search for \"Recht\", \"Permission\", \"HasRight\", \"IsAllowed\", \"Berechtigung\"), and billing/invoicing calculation logic (search for \"Rechnung\", \"Faktura\", \"Preis\", \"Berechnung\", \"Steuer\", \"MwSt\", \"Rabatt\").\n3. For each category found, give concrete file paths and short (1-2 line) descriptions of what the method/class appears to do based on its name and a quick look at signatures.\n4. Note any classes that look like they implement a state machine (enum-driven if/switch on status with allowed-transition logic).\n\nReport back as structured text with concrete file paths and short descriptions for traceability purposes — this feeds into a formal requirements specification. Aim for 1000-1800 words, prioritize breadth of module coverage over depth on any one file.",
|
||||
"ergebnis_zeichen": 1093
|
||||
},
|
||||
{
|
||||
"id": "toolu_01CAck4seaV26Qjosw3twHSp",
|
||||
"werkzeug": "Agent",
|
||||
"subagent_type": "Explore",
|
||||
"description": "Survey backend DAO and DB constraints",
|
||||
"run_in_background": null,
|
||||
"model": null,
|
||||
"prompt": "You are surveying a large legacy C# ERP codebase (c-entron ERP) at C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP for a reverse-engineering requirements analysis. Read-only exploration, do not modify anything.\n\nFocus area: C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP\\src\\backend\\Centron.DAO (1131 .cs files) — presumably the data access layer (likely raw SQL or an ORM against MSSQL).\n\nTask:\n1. Identify what data-access pattern is used (raw ADO.NET with SQL strings, an ORM like Entity Framework/NHibernate, stored-procedure calls, etc.) — cite example file paths.\n2. List the top-level namespace/folder structure and what business areas the folders suggest.\n3. Search the whole repository (not just this folder) for .sql files, database migration scripts, or schema definition files (e.g. under a \"Datenbank\", \"DB\", \"Migrations\", \"Scripts\" folder) and report their locations and what they contain (table names, constraints, triggers if visible).\n4. Within Centron.DAO, search for SQL fragments containing constraints, CHECK, FOREIGN KEY, UNIQUE, NOT NULL, or transaction/locking logic (e.g. \"BEGIN TRAN\", \"TransactionScope\") and report file paths + snippet.\n5. Search for stored procedure calls (CommandType.StoredProcedure or \"EXEC \") and list a sample of procedure names found, with file paths.\n\nReport back as structured text with concrete file paths for traceability. Aim for 1000-1500 words, prioritizing evidence of enforced data rules (constraints) since these are high-value PRIMÄR evidence for a requirements spec.",
|
||||
"ergebnis_zeichen": 1093
|
||||
},
|
||||
{
|
||||
"id": "toolu_01Y2UUWzGyXC9sS6PD2aduzH",
|
||||
"werkzeug": "Agent",
|
||||
"subagent_type": "Explore",
|
||||
"description": "Survey WPF UI module structure",
|
||||
"run_in_background": null,
|
||||
"model": null,
|
||||
"prompt": "You are surveying a large legacy C# WPF desktop ERP codebase (c-entron ERP) at C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP for a reverse-engineering requirements analysis. Read-only exploration, do not modify anything.\n\nFocus area: C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP\\src\\centron\\Centron.WPF.UI (5255 .cs files + most of the 1233 .xaml files) — this is the main desktop client application, the primary user-facing part of the ERP.\n\nTask: Produce a broad inventory of the application's functional modules as visible from folder/file naming, since this is the main UI a business user interacts with.\n1. List the top-level folder structure (1-2 levels deep) and identify which folders correspond to which business modules (e.g. Auftragsverwaltung, Rechnungswesen, Artikelstamm, Kundenverwaltung/CRM, Lagerverwaltung, Zeiterfassung, C-Sign/Signatur, Einstellungen/Administration, Berichte/Reports, Angebote, Bestellungen, etc.)\n2. For 8-10 of the most significant business modules, list a couple of representative View/ViewModel/Window .xaml or .cs file paths.\n3. Search for UI validation logic: look for files/methods with names like \"Validate\", \"CanExecute\", \"IsValid\", error message strings (e.g. resource files, .resx, or string literals shown to users) — report a sample with file paths.\n4. Search for permission/rights-based UI restrictions (e.g. \"Visibility\", \"IsEnabled\" tied to a rights-check property, \"HasRight\", \"Berechtigung\") — report sample file paths.\n5. Look for any menu/ribbon definition files that enumerate the application's main functions/menu items (this is useful to reconstruct the stakeholder-level feature list) — report file paths and a sample of menu item labels found.\n\nReport back as structured text with concrete file paths. This feeds into a formal requirements specification needing traceability, so always cite paths. Aim for 1200-1800 words, prioritizing breadth across business modules.",
|
||||
"ergebnis_zeichen": 1093
|
||||
},
|
||||
{
|
||||
"id": "toolu_01EEtnTW4qSPGuKc57zWa8uM",
|
||||
"werkzeug": "Agent",
|
||||
"subagent_type": "Explore",
|
||||
"description": "Survey webservice API layer",
|
||||
"run_in_background": null,
|
||||
"model": null,
|
||||
"prompt": "You are surveying a large legacy C# ERP codebase (c-entron ERP) at C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP for a reverse-engineering requirements analysis. Read-only exploration, do not modify anything.\n\nFocus areas:\n- C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP\\src\\webservice\\Centron.WebServices.Core (2530 .cs files)\n- C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP\\src\\webservice\\Centron.Controllers (57 .cs files)\n- C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP\\src\\webservice\\Centron.Host, Centron.Host.Console, Centron.Host.WindowsService (hosting)\n- C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP\\Centron.Api.docuFORM\n\nTask:\n1. Identify the web API technology used (ASP.NET Web API / OWIN / minimal API / SOAP/WCF, routing style, authentication mechanism) — cite example file paths (Controller classes, Startup/Program files, [Authorize] attributes, API key checks, JWT, etc.)\n2. List the controllers found in Centron.Controllers and Centron.WebServices.Core with their route prefixes/endpoints (search for [Route], [HttpGet], [HttpPost] attributes) — give a representative list (doesn't need to be exhaustive, aim for the ones covering distinct business capabilities: e.g. Auftrag, Rechnung, Kunde, Artikel, Zeiterfassung, C-Sign etc.)\n3. Look for authentication/authorization logic: API keys, tokens, session handling — cite file paths.\n4. Look for rate-limiting, logging middleware, or error-handling middleware — cite file paths (relevant for non-functional/security requirements).\n5. What does Centron.Api.docuFORM appear to integrate with (based on name and any docs/comments)?\n\nReport back as structured text with concrete file paths for traceability purposes. Aim for 1200-1600 words.",
|
||||
"ergebnis_zeichen": 1093
|
||||
},
|
||||
{
|
||||
"id": "toolu_012QzkMxgz4nftJ7GJQtdu6n",
|
||||
"werkzeug": "Agent",
|
||||
"subagent_type": "Explore",
|
||||
"description": "Survey Nexus, external APIs, and docs",
|
||||
"run_in_background": null,
|
||||
"model": null,
|
||||
"prompt": "You are surveying a large legacy C# ERP codebase (c-entron ERP) at C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP for a reverse-engineering requirements analysis. Read-only exploration, do not modify anything.\n\nFocus areas:\n1. C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP\\src\\nexus (CentronNexus, CentronNexus.Host, CentronNexus.OutlookAddIn) — figure out what \"Nexus\" is (based on README/docs/comments/class names): likely a synchronization service or Outlook integration. Report what it does, its architecture (service? addin?), and 3-5 key classes with file paths.\n2. C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP\\src\\apis\\* — these are external system integrations: Centron.APIs.CopDataAccess, Centron.APIs.EgisDataAccess, Centron.APIs.FinAPI, Centron.APIs.ITscopeDataAccess, Centron.APIs.IcecatDataAccess, Centron.Api.EbInterface, Centron.Api.Gls, Centron.Api.Shipcloud. For EACH, briefly state (1-3 sentences) what external system/service it integrates with and what kind of data is exchanged, based on class/method names, comments, or config keys. Cite file paths.\n3. C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP\\docs — list the doc folder structure (features, guides, operations, reference, getting-started) and for each subfolder list the document titles/filenames found. If any documents clearly describe business features, functional scope, or architecture, note their titles and paths so they can be read in depth later.\n\nReport back as structured text with concrete file/folder paths for traceability purposes. Aim for 1200-1800 words.",
|
||||
"ergebnis_zeichen": 1093
|
||||
},
|
||||
{
|
||||
"id": "toolu_015APkVCMPxvMNCcbGJEft5u",
|
||||
"werkzeug": "Agent",
|
||||
"subagent_type": "Explore",
|
||||
"description": "Survey deployment, ops, and test coverage hints",
|
||||
"run_in_background": null,
|
||||
"model": null,
|
||||
"prompt": "You are surveying a large legacy C# ERP codebase (c-entron ERP) at C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP for a reverse-engineering requirements analysis, focused on non-functional / operational / security requirements evidence. Read-only exploration, do not modify anything.\n\nFocus areas:\n1. C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP\\docker\\* (compose files, dockerfiles for c-entron-api, c-entron-webservice, c-entron-demo, c-entron-mailcatcher, regression-tests-db/pipeline) — report what services/containers are defined, exposed ports, environment variables that hint at configuration (DB connection, secrets, feature flags), and any health-check or logging configuration.\n2. C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP\\azure and azure-blazor and .github/workflows and .github/actions — report what CI/CD pipelines exist (build, test, deploy stages), and any azure-blazor evidence of a planned/existing web migration (this is directly relevant to a \"SaaS re-implementation\" project — flag anything found).\n3. C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP\\deployment (WixSharpInstaller, centron, riverbird folders) — report what installer/deployment artifacts exist, and what this tells us about the current on-premise deployment model (installer-based Windows desktop app + service?).\n4. C:\\DEV\\MasterArbeit\\QuellCode\\CentronERP\\tests\\* folder structure (Centron.Tests.EndToEnd, Centron.Tests.Integration, CentronNexusTests, PlaywrightTests, apis, backend, shared) — report roughly how many test files per folder, and sample 5-10 test class/method names that reveal business rules being tested (e.g. \"Test_Cannot_Delete_Invoiced_Order\", validation tests, permission tests). Playwright tests are especially interesting since they suggest an existing web UI — investigate what PlaywrightTests actually tests (which web app) and report findings with file paths.\n\nReport back as structured text with concrete file paths for traceability purposes. Aim for 1200-1800 words.",
|
||||
"ergebnis_zeichen": 1093
|
||||
}
|
||||
]
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
# Subagenten-Aufrufe
|
||||
|
||||
Session `88426b05-5eb1-4dbd-b89a-ffe5c7220ac4`, Transkript `88426b05-5eb1-4dbd-b89a-ffe5c7220ac4.jsonl`.
|
||||
|
||||
`subagent_stats`: **7** Subagenten gesamt, davon **0** von Subagenten gestartet (max_depth 1). Direkt vom Hauptagenten erwartet: **7**. Im Transkript gefunden: **7**.
|
||||
|
||||
## 1. Survey backend domain model (Entities)
|
||||
|
||||
- **Werkzeug:** `Agent` **Typ:** `Explore` **Hintergrund:** None
|
||||
- **Prompt-Zeichen:** 1696 **Ergebnis-Zeichen:** 1093
|
||||
|
||||
### Prompt
|
||||
|
||||
```
|
||||
You are surveying a large legacy C# ERP codebase (c-entron ERP) at C:\DEV\MasterArbeit\QuellCode\CentronERP for a reverse-engineering requirements analysis. This is read-only exploration — do not modify anything.
|
||||
|
||||
Focus area: C:\DEV\MasterArbeit\QuellCode\CentronERP\src\backend\Centron.Entities (1185 .cs files) — this is presumably the domain/entity model layer.
|
||||
|
||||
Task: Produce an inventory, not a deep read of every file. Specifically:
|
||||
1. List the top-level namespace/folder structure under Centron.Entities (what business areas do the folder names suggest — e.g. Auftrag, Rechnung, Artikel, Kunde, Lager, Personal, etc.)
|
||||
2. For each major business area folder, sample 2-4 representative entity classes and note: class name, file path, notable fields (especially status/enum fields, foreign keys, audit fields), and any inline validation attributes or comments suggesting business rules.
|
||||
3. Look specifically for status/enum types (e.g. AuftragStatus, RechnungStatus, files with "Status" or "Enum" in the name) across the whole folder — list file paths and the enum values found, since status machines are high-value for requirements extraction.
|
||||
4. Look for any classes/attributes suggesting audit trail, soft-delete, multi-tenant/mandant fields, or versioning.
|
||||
|
||||
Report back as structured text: a list of business areas with file path evidence, a list of found status enums with their values and file paths, and any other structural observations. Include concrete file paths for everything (I need traceability evidence). Keep the report focused and factual — this feeds into a formal requirements specification, so cite exact paths, not vague descriptions. Aim for a report of 800-1500 words.
|
||||
```
|
||||
|
||||
## 2. Survey backend business logic (BL)
|
||||
|
||||
- **Werkzeug:** `Agent` **Typ:** `Explore` **Hintergrund:** None
|
||||
- **Prompt-Zeichen:** 1620 **Ergebnis-Zeichen:** 1093
|
||||
|
||||
### Prompt
|
||||
|
||||
```
|
||||
You are surveying a large legacy C# ERP codebase (c-entron ERP) at C:\DEV\MasterArbeit\QuellCode\CentronERP for a reverse-engineering requirements analysis. This is read-only exploration — do not modify anything.
|
||||
|
||||
Focus area: C:\DEV\MasterArbeit\QuellCode\CentronERP\src\backend\Centron.BL (2068 .cs files) — presumably the business logic layer.
|
||||
|
||||
Task: Produce an inventory, not a deep read of every file. Specifically:
|
||||
1. List the top-level namespace/folder structure under Centron.BL (what business areas/modules do folder names suggest — e.g. Auftrag, Rechnung/Faktura, Artikel, Kunde/CRM, Lager, Einkauf, Zeiterfassung/Timer, C-Sign, Benutzerverwaltung/Berechtigungen, etc.)
|
||||
2. Search for and list files/classes related to: status transitions or workflow logic (methods like "ChangeStatus", "SetStatus", state machine patterns), permission/rights checks (search for "Recht", "Permission", "HasRight", "IsAllowed", "Berechtigung"), and billing/invoicing calculation logic (search for "Rechnung", "Faktura", "Preis", "Berechnung", "Steuer", "MwSt", "Rabatt").
|
||||
3. For each category found, give concrete file paths and short (1-2 line) descriptions of what the method/class appears to do based on its name and a quick look at signatures.
|
||||
4. Note any classes that look like they implement a state machine (enum-driven if/switch on status with allowed-transition logic).
|
||||
|
||||
Report back as structured text with concrete file paths and short descriptions for traceability purposes — this feeds into a formal requirements specification. Aim for 1000-1800 words, prioritize breadth of module coverage over depth on any one file.
|
||||
```
|
||||
|
||||
## 3. Survey backend DAO and DB constraints
|
||||
|
||||
- **Werkzeug:** `Agent` **Typ:** `Explore` **Hintergrund:** None
|
||||
- **Prompt-Zeichen:** 1516 **Ergebnis-Zeichen:** 1093
|
||||
|
||||
### Prompt
|
||||
|
||||
```
|
||||
You are surveying a large legacy C# ERP codebase (c-entron ERP) at C:\DEV\MasterArbeit\QuellCode\CentronERP for a reverse-engineering requirements analysis. Read-only exploration, do not modify anything.
|
||||
|
||||
Focus area: C:\DEV\MasterArbeit\QuellCode\CentronERP\src\backend\Centron.DAO (1131 .cs files) — presumably the data access layer (likely raw SQL or an ORM against MSSQL).
|
||||
|
||||
Task:
|
||||
1. Identify what data-access pattern is used (raw ADO.NET with SQL strings, an ORM like Entity Framework/NHibernate, stored-procedure calls, etc.) — cite example file paths.
|
||||
2. List the top-level namespace/folder structure and what business areas the folders suggest.
|
||||
3. Search the whole repository (not just this folder) for .sql files, database migration scripts, or schema definition files (e.g. under a "Datenbank", "DB", "Migrations", "Scripts" folder) and report their locations and what they contain (table names, constraints, triggers if visible).
|
||||
4. Within Centron.DAO, search for SQL fragments containing constraints, CHECK, FOREIGN KEY, UNIQUE, NOT NULL, or transaction/locking logic (e.g. "BEGIN TRAN", "TransactionScope") and report file paths + snippet.
|
||||
5. Search for stored procedure calls (CommandType.StoredProcedure or "EXEC ") and list a sample of procedure names found, with file paths.
|
||||
|
||||
Report back as structured text with concrete file paths for traceability. Aim for 1000-1500 words, prioritizing evidence of enforced data rules (constraints) since these are high-value PRIMÄR evidence for a requirements spec.
|
||||
```
|
||||
|
||||
## 4. Survey WPF UI module structure
|
||||
|
||||
- **Werkzeug:** `Agent` **Typ:** `Explore` **Hintergrund:** None
|
||||
- **Prompt-Zeichen:** 1921 **Ergebnis-Zeichen:** 1093
|
||||
|
||||
### Prompt
|
||||
|
||||
```
|
||||
You are surveying a large legacy C# WPF desktop ERP codebase (c-entron ERP) at C:\DEV\MasterArbeit\QuellCode\CentronERP for a reverse-engineering requirements analysis. Read-only exploration, do not modify anything.
|
||||
|
||||
Focus area: C:\DEV\MasterArbeit\QuellCode\CentronERP\src\centron\Centron.WPF.UI (5255 .cs files + most of the 1233 .xaml files) — this is the main desktop client application, the primary user-facing part of the ERP.
|
||||
|
||||
Task: Produce a broad inventory of the application's functional modules as visible from folder/file naming, since this is the main UI a business user interacts with.
|
||||
1. List the top-level folder structure (1-2 levels deep) and identify which folders correspond to which business modules (e.g. Auftragsverwaltung, Rechnungswesen, Artikelstamm, Kundenverwaltung/CRM, Lagerverwaltung, Zeiterfassung, C-Sign/Signatur, Einstellungen/Administration, Berichte/Reports, Angebote, Bestellungen, etc.)
|
||||
2. For 8-10 of the most significant business modules, list a couple of representative View/ViewModel/Window .xaml or .cs file paths.
|
||||
3. Search for UI validation logic: look for files/methods with names like "Validate", "CanExecute", "IsValid", error message strings (e.g. resource files, .resx, or string literals shown to users) — report a sample with file paths.
|
||||
4. Search for permission/rights-based UI restrictions (e.g. "Visibility", "IsEnabled" tied to a rights-check property, "HasRight", "Berechtigung") — report sample file paths.
|
||||
5. Look for any menu/ribbon definition files that enumerate the application's main functions/menu items (this is useful to reconstruct the stakeholder-level feature list) — report file paths and a sample of menu item labels found.
|
||||
|
||||
Report back as structured text with concrete file paths. This feeds into a formal requirements specification needing traceability, so always cite paths. Aim for 1200-1800 words, prioritizing breadth across business modules.
|
||||
```
|
||||
|
||||
## 5. Survey webservice API layer
|
||||
|
||||
- **Werkzeug:** `Agent` **Typ:** `Explore` **Hintergrund:** None
|
||||
- **Prompt-Zeichen:** 1681 **Ergebnis-Zeichen:** 1093
|
||||
|
||||
### Prompt
|
||||
|
||||
```
|
||||
You are surveying a large legacy C# ERP codebase (c-entron ERP) at C:\DEV\MasterArbeit\QuellCode\CentronERP for a reverse-engineering requirements analysis. Read-only exploration, do not modify anything.
|
||||
|
||||
Focus areas:
|
||||
- C:\DEV\MasterArbeit\QuellCode\CentronERP\src\webservice\Centron.WebServices.Core (2530 .cs files)
|
||||
- C:\DEV\MasterArbeit\QuellCode\CentronERP\src\webservice\Centron.Controllers (57 .cs files)
|
||||
- C:\DEV\MasterArbeit\QuellCode\CentronERP\src\webservice\Centron.Host, Centron.Host.Console, Centron.Host.WindowsService (hosting)
|
||||
- C:\DEV\MasterArbeit\QuellCode\CentronERP\Centron.Api.docuFORM
|
||||
|
||||
Task:
|
||||
1. Identify the web API technology used (ASP.NET Web API / OWIN / minimal API / SOAP/WCF, routing style, authentication mechanism) — cite example file paths (Controller classes, Startup/Program files, [Authorize] attributes, API key checks, JWT, etc.)
|
||||
2. List the controllers found in Centron.Controllers and Centron.WebServices.Core with their route prefixes/endpoints (search for [Route], [HttpGet], [HttpPost] attributes) — give a representative list (doesn't need to be exhaustive, aim for the ones covering distinct business capabilities: e.g. Auftrag, Rechnung, Kunde, Artikel, Zeiterfassung, C-Sign etc.)
|
||||
3. Look for authentication/authorization logic: API keys, tokens, session handling — cite file paths.
|
||||
4. Look for rate-limiting, logging middleware, or error-handling middleware — cite file paths (relevant for non-functional/security requirements).
|
||||
5. What does Centron.Api.docuFORM appear to integrate with (based on name and any docs/comments)?
|
||||
|
||||
Report back as structured text with concrete file paths for traceability purposes. Aim for 1200-1600 words.
|
||||
```
|
||||
|
||||
## 6. Survey Nexus, external APIs, and docs
|
||||
|
||||
- **Werkzeug:** `Agent` **Typ:** `Explore` **Hintergrund:** None
|
||||
- **Prompt-Zeichen:** 1529 **Ergebnis-Zeichen:** 1093
|
||||
|
||||
### Prompt
|
||||
|
||||
```
|
||||
You are surveying a large legacy C# ERP codebase (c-entron ERP) at C:\DEV\MasterArbeit\QuellCode\CentronERP for a reverse-engineering requirements analysis. Read-only exploration, do not modify anything.
|
||||
|
||||
Focus areas:
|
||||
1. C:\DEV\MasterArbeit\QuellCode\CentronERP\src\nexus (CentronNexus, CentronNexus.Host, CentronNexus.OutlookAddIn) — figure out what "Nexus" is (based on README/docs/comments/class names): likely a synchronization service or Outlook integration. Report what it does, its architecture (service? addin?), and 3-5 key classes with file paths.
|
||||
2. C:\DEV\MasterArbeit\QuellCode\CentronERP\src\apis\* — these are external system integrations: Centron.APIs.CopDataAccess, Centron.APIs.EgisDataAccess, Centron.APIs.FinAPI, Centron.APIs.ITscopeDataAccess, Centron.APIs.IcecatDataAccess, Centron.Api.EbInterface, Centron.Api.Gls, Centron.Api.Shipcloud. For EACH, briefly state (1-3 sentences) what external system/service it integrates with and what kind of data is exchanged, based on class/method names, comments, or config keys. Cite file paths.
|
||||
3. C:\DEV\MasterArbeit\QuellCode\CentronERP\docs — list the doc folder structure (features, guides, operations, reference, getting-started) and for each subfolder list the document titles/filenames found. If any documents clearly describe business features, functional scope, or architecture, note their titles and paths so they can be read in depth later.
|
||||
|
||||
Report back as structured text with concrete file/folder paths for traceability purposes. Aim for 1200-1800 words.
|
||||
```
|
||||
|
||||
## 7. Survey deployment, ops, and test coverage hints
|
||||
|
||||
- **Werkzeug:** `Agent` **Typ:** `Explore` **Hintergrund:** None
|
||||
- **Prompt-Zeichen:** 1964 **Ergebnis-Zeichen:** 1093
|
||||
|
||||
### Prompt
|
||||
|
||||
```
|
||||
You are surveying a large legacy C# ERP codebase (c-entron ERP) at C:\DEV\MasterArbeit\QuellCode\CentronERP for a reverse-engineering requirements analysis, focused on non-functional / operational / security requirements evidence. Read-only exploration, do not modify anything.
|
||||
|
||||
Focus areas:
|
||||
1. C:\DEV\MasterArbeit\QuellCode\CentronERP\docker\* (compose files, dockerfiles for c-entron-api, c-entron-webservice, c-entron-demo, c-entron-mailcatcher, regression-tests-db/pipeline) — report what services/containers are defined, exposed ports, environment variables that hint at configuration (DB connection, secrets, feature flags), and any health-check or logging configuration.
|
||||
2. C:\DEV\MasterArbeit\QuellCode\CentronERP\azure and azure-blazor and .github/workflows and .github/actions — report what CI/CD pipelines exist (build, test, deploy stages), and any azure-blazor evidence of a planned/existing web migration (this is directly relevant to a "SaaS re-implementation" project — flag anything found).
|
||||
3. C:\DEV\MasterArbeit\QuellCode\CentronERP\deployment (WixSharpInstaller, centron, riverbird folders) — report what installer/deployment artifacts exist, and what this tells us about the current on-premise deployment model (installer-based Windows desktop app + service?).
|
||||
4. C:\DEV\MasterArbeit\QuellCode\CentronERP\tests\* folder structure (Centron.Tests.EndToEnd, Centron.Tests.Integration, CentronNexusTests, PlaywrightTests, apis, backend, shared) — report roughly how many test files per folder, and sample 5-10 test class/method names that reveal business rules being tested (e.g. "Test_Cannot_Delete_Invoiced_Order", validation tests, permission tests). Playwright tests are especially interesting since they suggest an existing web UI — investigate what PlaywrightTests actually tests (which web app) and report findings with file paths.
|
||||
|
||||
Report back as structured text with concrete file paths for traceability purposes. Aim for 1200-1800 words.
|
||||
```
|
||||
+247
@@ -0,0 +1,247 @@
|
||||
# Analysebericht
|
||||
|
||||
## 1. Auftrag und Rahmenbedingungen
|
||||
|
||||
Untersuchungsgegenstand: gesamte Codebasis unter `C:\DEV\MasterArbeit\QuellCode\CentronERP`
|
||||
(c-entron.NET ERP-Suite: WPF-Client, Web-Services/REST-API, Blazor-Portal "Nexus", diverse
|
||||
Backend-Bibliotheken, externe API-Integrationen, Datenbankskripte, Dokumentation).
|
||||
Werkzeugkonfiguration dieses Laufs: Claude Code ohne Agentendateien (`.claude/agents`) und ohne
|
||||
MCP-Server — reine Dateisystem-Analyse (Read/Grep/Glob/Bash) durch ein einzelnes Modell ohne
|
||||
Subagenten-Parallelisierung. Es wurde ausschließlich gelesen, keine Datei der Codebasis verändert.
|
||||
|
||||
Umfang der Codebasis (grobe Kennzahlen, per `find`/`wc`):
|
||||
- `src/backend/Centron.BL`: 2068 .cs-Dateien, 89 fachliche Unterordner
|
||||
- `src/backend/Centron.DAO`: 1131 .cs-Dateien
|
||||
- `src/backend/Centron.Entities`: 1185 .cs-Dateien
|
||||
- `src/backend/Centron.Interfaces`: 764 .cs-Dateien
|
||||
- `src/centron/Centron.WPF.UI`: 5255 .cs-Dateien (Desktop-Client)
|
||||
- `src/nexus/CentronNexus`: 762 .cs-Dateien (Blazor-Portal)
|
||||
- `src/webservice/Centron.Controllers`: 57 .cs-Dateien (moderne REST-API)
|
||||
- weitere: `Centron.Common`, `Centron.Gateway`, `Centron.Core`, `src/apis/*` (externe Integrationen:
|
||||
FinAPI, GLS, Shipcloud, ITscope, Icecat, EGIS, C-Sign/docuFORM), `docker/*`, `deployment/*`, `docs/*`.
|
||||
|
||||
Insgesamt weit über 11.000 C#-Quelldateien plus Datenbankskripte, Docker-/Deployment-Konfiguration
|
||||
und ca. 30 kuratierte Architektur-/Prozessdokumente unter `docs/`. Eine vollständige Tiefenanalyse
|
||||
jeder einzelnen Datei ist in dieser Iteration nicht leistbar; es wurde eine risikobasierte,
|
||||
selbst priorisierte Tiefenanalyse durchgeführt (siehe Abschnitt 3).
|
||||
|
||||
## 2. Vorgehen
|
||||
|
||||
1. Breitenerhebung der Modulstruktur (Verzeichnisbaum `Centron.BL`, `Centron.Entities`,
|
||||
`Centron.WPF.UI`, `src/apis`, `src/nexus`, `docs/`) zur Bildung eines Moduleninventars.
|
||||
2. Auswertung der vorhandenen Architektur-/Prozessdokumentation unter `docs/` als Kontext-
|
||||
und Sekundärbelege (Dokumentation selbst ist keine durchgesetzte Regel, sondern beschreibt
|
||||
sie – daher grundsätzlich `KONTEXT`/`SEKUNDÄR`, nie alleinige Basis für `PRIMÄR`-pflichtige
|
||||
Aussagen zu Sicherheit/Fakturierung/Berechtigungen).
|
||||
3. Tiefenanalyse ausgewählter, geschäftskritischer Module anhand von Quellcode (Entities, BL-
|
||||
Klassen, Statuscodes/Enums, Rechteprüfungen, DB-Skripten), um für jede Anforderung mindestens
|
||||
einen Beleg zu erhalten; bei sicherheits-/abrechnungs-/berechtigungsrelevanten Aussagen wurde
|
||||
gezielt nach `PRIMÄR`-Belegen (Code, das die Regel tatsächlich durchsetzt) gesucht.
|
||||
4. Ableitung von StRS/SyRS/SwRS-Anforderungen je Modul mit Traceability und Konsolidierungsprüfung.
|
||||
5. Konsistenzcheck über das Gesamtergebnis (Abschnitt 5).
|
||||
|
||||
## 3. Moduleninventar und Analysetiefe
|
||||
|
||||
Legende Analysetiefe: **TIEF** = Quellcode mehrerer Kernklassen gelesen, Anforderungen mit
|
||||
PRIMÄR-Beleg abgeleitet · **MITTEL** = gezielte Grep-Stichproben / einzelne Kernklasse gelesen ·
|
||||
**FLACH** = nur Verzeichnis-/Dateinamen sowie ggf. Dokumentation gesichtet, keine Quellcode-Prüfung ·
|
||||
**NICHT ANALYSIERT** = nur in der Inventarliste erfasst, keine weitere Prüfung.
|
||||
|
||||
### 3.1 TIEF analysiert (Quellcode mehrerer Kernklassen gelesen, PRIMÄR-Belege erhoben)
|
||||
|
||||
Modul | Kernartefakte | Anforderungen
|
||||
---|---|---
|
||||
Sicherheit & Berechtigungen | `AppRightsBL.cs`, `DeveloperSecurity.cs` | StRS-1..3, SyRS-1..4, SwRS-1..5
|
||||
Lizenzierung | `LicenseManager.cs` | StRS-4, SyRS-5..6, SwRS-6..7
|
||||
Verkaufsbelege (Sales/Receipts, Kernarchitektur) | `ReceiptBase.cs`, `ReceiptState.cs`, `ReceiptBL.cs` (Kernmethoden, nicht vollständig — Datei hat >10.000 Zeilen), `SaveReceiptRepository.cs` + Implementierungen | StRS-5..8, SyRS-7..11, SwRS-8..12
|
||||
Verträge & automatisierte Abrechnung | `AutomaticFacturaBL.Contracts.cs` (Kernmethoden, Datei hat >2400 Zeilen, nicht vollständig gelesen) | StRS-9..10, SyRS-12..13, SwRS-13..14
|
||||
|
||||
### 3.2 MITTEL analysiert (gezielte Stichprobe: 1 Kernklasse/Methode gelesen oder gezielte Grep-Suche mit Codebeleg)
|
||||
|
||||
Modul | Kernartefakte | Anforderungen
|
||||
---|---|---
|
||||
Mahnwesen (Sales/Receipts/Invoices/Dunning) | `DunningBL.cs` (Auszug) | StRS-11, SyRS-14, SwRS-15
|
||||
Umsatzsteuer (Warehousing/Tax) | `TaxBL.cs` (Auszug) | StRS-12, SyRS-15, SwRS-16
|
||||
Kunden-/Lieferantenstammdaten (Accounts) | `AccountBL.cs` (Auszug) | StRS-13, SyRS-16, SwRS-17
|
||||
Zeiterfassungsabrechnung (Timer Billing) | `ReceiptWebServiceBL.cs` (Auszug), `TimerBillingSettingsPageViewModel.cs` (via Commit-Diff) | StRS-14, SyRS-17, SwRS-18
|
||||
Helpdesk/Ticketsystem (CustomerArea/Support) | `HelpdeskState.cs`, `HelpdeskStateBase.cs`, Mapping-Datei (Existenzprüfung) | StRS-15, SyRS-18, SwRS-19
|
||||
Betrieb & Bereitstellung (Docker/Compose) | `docker/compose/compose.yaml` (vollständig) | StRS-16, SyRS-19, SwRS-20
|
||||
|
||||
### 3.3 FLACH analysiert (nur Dokumentation und/oder Verzeichnis-/Dateinamen gesichtet, kein Quellcode gelesen)
|
||||
|
||||
Bereich | Quelle | Bemerkung
|
||||
---|---|---
|
||||
EDI-Architektur (Buying/EDI, Gateway.EDI_*) | `docs/reference/edi/edi-architecture.md` | Vollständig als Dokument gelesen; keine Codeverifikation der beschriebenen Klassen (`SupplierEdiBL`, `EDICommonBL`, `EDILogBL`) durchgeführt. Alle darauf gestützten Aussagen wären daher `SEKUNDÄR`/`KONTEXT`, nicht `PRIMÄR` — in dieser Iteration wurden deshalb bewusst **keine** EDI-Anforderungen formuliert, um die Belegpflicht nicht zu verletzen.
|
||||
ZUGFeRD/XRechnung E-Rechnung | `docs/guides/development/xrechnung.md`, Erwähnung in `ReceiptBL.cs` (Z.3272-3274, `InvoiceZugferdBL`) | Nur Randerwähnung im Code gesehen (Bedingung für Layout-Item), `InvoiceZugferdBL`/`ZugferdParseBL` selbst nicht gelesen.
|
||||
Allgemeine Architektur/Layering | `docs/getting-started/general-structure.md`, `docs/getting-started/ai-codebase-navigation.md` | Als Kontextwissen für Traceability-Struktur verwendet, nicht in eigene Anforderungen übersetzt (beschreibt Bauprinzipien, keine Fachfunktion).
|
||||
Datenbank-Konventionen | `docs/guides/database/database-conventions.md` | Für Glossar (I3D-Konvention) verwendet.
|
||||
Receipts-/Contracts-Architektur (ergänzend zu 3.1) | `docs/reference/receipts/receipts-backend-architecture.md`, `contracts-backend.md` | Als SEKUNDÄR-Beleg neben Code verwendet, nicht als alleinige Quelle.
|
||||
|
||||
### 3.4 NICHT ANALYSIERT (nur im Verzeichnisinventar erfasst)
|
||||
|
||||
Die folgenden fachlichen Unterordner von `src/backend/Centron.BL` (89 insgesamt, siehe Abschnitt 1)
|
||||
wurden ausschließlich über ihren Verzeichnisnamen erfasst; ihr Inhalt wurde in dieser Iteration
|
||||
**nicht** gelesen und es wurden **keine** Anforderungen daraus abgeleitet:
|
||||
|
||||
`Accounting, Administration (außer Rights/Licensing), AppointmentRequests, ArtificialIntelligence,
|
||||
BusinessPartner (außer SearchSupplierBL/SupplierAssetBL-Existenzprüfung), Buying, CPra, Calendar,
|
||||
CentronIcons, CentronNexus, ChangeTracking, Chats, CheckListArea, Core, CountryArea, CustomerArea
|
||||
(außer Support/HelpdeskState), Customizations, DataExchange, Devices, DocuBoard, DocumentationArea,
|
||||
EDI, EmployeeArea, Exceptions, ExpectedEvents, ExternalHelpdesk, ExternalToolsBL, Finances, GUI,
|
||||
Gateway, Helpers, IndexSearch, Integrations, ItPlanner, Logistics, Mail, MailScanner, Mailings,
|
||||
MassUpdate, Mobile, Modules, MyCentron, MyDay, NexusNotifications, NexusTicketViews, Notifications,
|
||||
ObjectExternalReferences, Outlook, PasswordManagementArea, PasswordManager, Processes, ProductMatrix,
|
||||
Production, Projects, Properties, Purchasing, ReportEngine, Reporting, Resources, RiverDivo, Sales
|
||||
(außer Receipts-Kern/CustomerAssets.AutomaticFactura/Receipts.Invoices.Dunning), Security (eigener
|
||||
Ordner, NICHT identisch mit Administration/Rights — nicht geprüft, ob Übernahmen/Abgrenzung besteht,
|
||||
siehe Hypothesen H-4), SelfCare, Services, SocialMedia, Start, Statistics, Storage, SystemArea, Tags,
|
||||
Tapi, TaskManager, Telemetry, TextModuleArea, TicketProjects, Time, ToDoArea, Tools, TradePool,
|
||||
Transactions, TwoFactorAuthenticator, Urls, VideoPortal, VoucherManagement, Warehousing (außer TaxBL),
|
||||
WebLinks, WebServices (außer den zitierten Receipts/Timer-Billing-Ausschnitten), WebSuite, WebVersion`
|
||||
|
||||
Ebenfalls nicht analysiert (nur als Vorhandensein/Struktur festgestellt, keine Datei geöffnet):
|
||||
- `src/backend/Centron.DAO` (1131 Dateien) — außer `SaveReceiptRepository.cs`-Familie und Existenz
|
||||
von `HelpdeskStateMaps.cs`
|
||||
- `src/backend/Centron.Entities` (1185 Dateien) — außer den zitierten Receipt-/Helpdesk-Entities
|
||||
- `src/backend/Centron.Interfaces` (764 Dateien) — außer `ReceiptState.cs`, Existenzprüfung
|
||||
`UserRightsConst.cs`, `LicenseGuids.cs`, `ApplicationKind.cs`
|
||||
- `src/centron/Centron.WPF.UI` (5255 Dateien, Desktop-Client) — außer der zitierten
|
||||
`TimerBillingSettingsPageViewModel.cs` (nur via Commit-Diff, nicht vollständige Datei gelesen)
|
||||
- `src/nexus/CentronNexus` (762 Dateien, Blazor-Kundenportal) — vollständig ungeprüft
|
||||
- `src/webservice/Centron.Controllers` (moderne REST-API), `Centron.WebServices.Core` (Legacy-REST) —
|
||||
vollständig ungeprüft, außer der zitierten Ausschnitte aus `ReceiptWebServiceBL.cs`
|
||||
- `src/apis/*` (FinAPI, GLS, Shipcloud, ITscope, Icecat, EGIS, EbInterface) — vollständig ungeprüft
|
||||
- `Centron.Api.docuFORM` (C-Sign, laut Commit-Historie aktiv weiterentwickelt) — vollständig ungeprüft
|
||||
- `deployment/*` (WiX-Installer), `azure/*`, `scripts/*` — vollständig ungeprüft
|
||||
- `tests/*` (Unit/Integration/E2E/Playwright) — vollständig ungeprüft; keine Anforderung wurde durch
|
||||
Testfälle verifiziert oder aus Testcode abgeleitet
|
||||
- Die überwiegende Mehrheit von `docs/` (u. a. `docs/guides/ui/*`, `docs/guides/services/*`,
|
||||
`docs/operations/*`, `docs/features/*`, `docs/reference/architecture/*` außer den zitierten) wurde
|
||||
nicht gelesen
|
||||
- Datenbankskripte/Migrationsverzeichnis selbst (nur indirekt über `docs/guides/development/add-a-new-right.md`
|
||||
referenziert, keine SQL-Migrationsdatei direkt geöffnet)
|
||||
- Git-Historie/Commit-Messages: nur `git log` (Kurzformat) und ein einzelner `git show` (Commit
|
||||
baa9e7bd9b) ausgewertet; keine systematische Auswertung von Tickets/Issues (nicht Teil der
|
||||
Codebasis / nicht als Datei zugänglich)
|
||||
|
||||
## 4. Bekannte Lücken
|
||||
|
||||
Aus dem Abgleich zwischen Auftragsumfang ("gesamte Codebasis", alle Module gleichrangig) und der in
|
||||
dieser Iteration tatsächlich erreichten Tiefe (Abschnitt 3) ergeben sich folgende Lücken:
|
||||
|
||||
1. **Kernprozesse ohne jede Prüfung.** Einkauf/Beschaffung (`Buying`, `Purchasing`), Lager-/
|
||||
Bestandsführung im engeren Sinn (Wareneingang, Bestandskorrektur — `Warehousing` außer `TaxBL`),
|
||||
Produktion (`Production`), Projektverwaltung (`Projects`, `TicketProjects`), Zeiterfassung im
|
||||
Kernprozess (`Time`, außer dem Ausschnitt zu Timer-Billing-Rechten) sowie die vollständige
|
||||
Business-Logik des Helpdesk-Kernprozesses (`ExternalHelpdesk`, `Sales/Support/HelpdeskBL` selbst
|
||||
nicht gelesen, nur die Status-Entity) wurden nicht analysiert. Für diese Bereiche existiert **keine**
|
||||
einzige Anforderung in dieser Spezifikation, obwohl sie vermutlich zentrale Geschäftsprozesse
|
||||
der ERP-Suite abbilden.
|
||||
2. **Desktop-Client (WPF-UI, 5255 Dateien) praktisch ungeprüft.** Bis auf einen einzelnen ViewModel-
|
||||
Ausschnitt (Commit-Diff) wurde keine XAML-Maske und kein ViewModel gelesen. UI-seitige
|
||||
Geschäftsregeln (Pflichtfeldvalidierungen, Masken-Workflows, Wizard-Schritte) sind daher nicht
|
||||
erfasst — nur die serverseitige BL-Logik.
|
||||
3. **Blazor-Kundenportal "Nexus" (762 Dateien) vollständig ungeprüft.** Keine Aussage zu
|
||||
Selbstbedienungsfunktionen für Endkunden möglich, obwohl `HelpdeskState.ServiceBoardWebColor` auf
|
||||
ein relevantes Kundenportal-Feature hindeutet.
|
||||
4. **Externe Integrationen ungeprüft.** `src/apis/*` (FinAPI, GLS, Shipcloud, ITscope, Icecat,
|
||||
EbInterface) sowie `Centron.Api.docuFORM` (C-Sign, laut Commit-Historie #128 aktiv weiterentwickelt)
|
||||
wurden nicht geöffnet; entsprechende Schnittstellenanforderungen (SyRS "Schnittstelle") fehlen
|
||||
in dieser Fassung nahezu vollständig.
|
||||
5. **EDI bewusst ausgeklammert.** Trotz vorhandener, ausführlicher Dokumentation
|
||||
(`docs/reference/edi/edi-architecture.md`) wurden keine Anforderungen formuliert, da die
|
||||
Belegpflicht (mind. 1 Beleg, bei Bedarf PRIMÄR) ohne Codeverifikation nicht methodenkonform
|
||||
erfüllbar war (siehe 3.3). Dies ist eine bewusste Qualitätsentscheidung, aber dennoch eine Lücke
|
||||
im Abdeckungsgrad.
|
||||
6. **Datenbankschema nicht direkt geprüft.** Es wurden keine SQL-Skripte/Migrationsdateien selbst
|
||||
geöffnet; alle Aussagen zu Tabellenspalten stammen aus Entity-Klassen, DAO-Mappings oder
|
||||
Dokumentation, nicht aus dem tatsächlichen Schema (CREATE TABLE-Statements).
|
||||
7. **Keine Laufzeitverifikation.** Alle Prüfideen sind statisch aus dem Code abgeleitet; es wurde
|
||||
nichts kompiliert, ausgeführt oder getestet (auftragsgemäß, da rein statische Analyse gefordert war).
|
||||
8. **Ticket-/Issue-Historie nicht ausgewertet.** Obwohl der Auftrag "Change-Historie und
|
||||
Projektartefakte (Commit-Messages, Tickets, Release Notes, Migrationsnotizen)" nennt, waren nur
|
||||
`git log` und ein einzelner `git show`-Aufruf im Rahmen dieser Iteration möglich; ein externes
|
||||
Ticketsystem war nicht als Datei zugänglich.
|
||||
|
||||
## 5. Konsistenzcheck
|
||||
|
||||
Durchgeführt vor Abgabe, mittels `grep`/Zählung über die finalen Dateien `StRS.md`, `SyRS.md`, `SwRS.md`:
|
||||
|
||||
1. **Doppelt/mehrfach vergebene IDs:** Keine gefunden. `StRS-1..16` (16 Anforderungen), `SyRS-1..19`
|
||||
(19 Anforderungen), `SwRS-1..20` (20 Anforderungen) sind jeweils lückenlos und ohne Duplikate
|
||||
vergeben (per Zähl- und Sortierprüfung über alle `^ID:`-Zeilen). Insgesamt **55 Anforderungen**.
|
||||
2. **Anforderungen ohne Beleg:** Keine gefunden. Jede der 55 Anforderungen enthält mindestens einen
|
||||
Beleg-Eintrag; jede der als Sicherheits-, Abrechnungs-/Fakturierungs- oder Berechtigungsanforderung
|
||||
eingestuften Aussagen (StRS-1..4, StRS-8, StRS-9..14, entsprechende SyRS/SwRS) trägt mindestens
|
||||
einen `PRIMÄR`-Beleg mit konkretem Datei-/Zeilenbezug — keine dieser Aussagen musste als
|
||||
`[HYPOTHESE]` markiert werden, da für alle bearbeiteten Bereiche tatsächlicher Quellcode (keine
|
||||
reine Dokumentation) als Grundlage gefunden wurde. Bereiche, für die kein ausreichender Beleg
|
||||
auffindbar war (z. B. EDI), wurden stattdessen bewusst **nicht** in eigene Anforderungen überführt
|
||||
(siehe Abschnitt 4, Punkt 5) statt unbelegte Anforderungen zu erzeugen.
|
||||
3. **Tracelinks auf nicht existierende IDs:** Keine gefunden. Alle in `Tracelinks:`-Feldern
|
||||
referenzierten IDs liegen innerhalb der tatsächlich vergebenen Bereiche (StRS ≤ 16, SyRS ≤ 19,
|
||||
SwRS ≤ 20); stichprobenartig und per Maximalwert-Prüfung verifiziert.
|
||||
4. **Traceability-Tabelle:** `Traceability.md` enthält für jede StRS-Anforderung mindestens eine Zeile
|
||||
mit zugehöriger SyRS-/SwRS-ID und Artefaktbeleg; für die vier ausschließlich technischen
|
||||
SwRS-Anforderungen ohne direkten StRS/SyRS-Bezug (SwRS-4, SwRS-5) ist dies mit "—" und Begründung
|
||||
explizit vermerkt statt stillschweigend ausgelassen.
|
||||
5. **Statusfeld-Konsistenz:** 51 von 55 Anforderungen tragen `Status: belegt`; 4 SwRS-Anforderungen
|
||||
(SwRS-3, SwRS-5, SwRS-7, SwRS-12) tragen zusätzlich den Vermerk `Workaround` mit Migrationshinweis,
|
||||
wie im Auftrag für erkennbare historische Sonderfälle gefordert. Kein Wert weicht vom
|
||||
vorgegebenen Vokabular (`belegt`/`HYPOTHESE`, ggf. mit Workaround-Zusatz) ab.
|
||||
6. **Offene Hypothesen:** 4 Einträge (H-1 bis H-4) in `Hypothesen.md`, jeweils mit Bezug auf eine
|
||||
konkrete Anforderungs-ID und einer klar formulierten offenen Frage — keine dieser Hypothesen wurde
|
||||
als eigene, unbelegte Anforderung verkleidet, sondern konsequent als Anmerkung zu einer ansonsten
|
||||
belegten Anforderung bzw. als eigenständiger Modulinventar-Hinweis geführt.
|
||||
|
||||
## 6. Selbstbewertung
|
||||
|
||||
**Vollständig analysiert (TIEF):** Nichts im Sinne von "jede Zeile gelesen" — auch bei den vier
|
||||
TIEF-eingestuften Modulen (Sicherheit & Berechtigungen, Lizenzierung, Verkaufsbelege-Kernarchitektur,
|
||||
Verträge/automatisierte Abrechnung) wurden gezielt Kernklassen und Kernmethoden gelesen, nicht der
|
||||
gesamte Dateibestand des jeweiligen Ordners. Bei `ReceiptBL.cs` (laut Dokumentation >10.000 Zeilen)
|
||||
und `AutomaticFacturaBL.Contracts.cs` (>2400 Zeilen) wurden nur die für die identifizierten
|
||||
Anforderungen relevanten Ausschnitte gelesen, nicht die vollständigen Dateien.
|
||||
|
||||
**Nur stichprobenhaft analysiert (MITTEL):** Mahnwesen, Umsatzsteuer, Kunden-/Lieferantenstammdaten,
|
||||
Zeiterfassungsabrechnung, Helpdesk-Statusverwaltung, Docker-Bereitstellung — hier wurde jeweils genau
|
||||
eine Kernklasse oder ein sehr eng umrissener Codeausschnitt gelesen. Für diese Module besteht ein
|
||||
erhöhtes Risiko, dass wichtige Nebenregeln (Validierungen, Ausnahmefälle) übersehen wurden.
|
||||
|
||||
**Gar nicht analysiert:** Der weit überwiegende Teil der Codebasis — insbesondere der komplette
|
||||
WPF-Desktop-Client (5255 Dateien), das Blazor-Kundenportal Nexus (762 Dateien), alle externen
|
||||
API-Integrationen (`src/apis/*`), der komplette Datenbank-Zugriffslayer bis auf einen Ausschnitt
|
||||
(`Centron.DAO`, 1131 Dateien) sowie ca. 75 der 89 fachlichen Unterordner von `Centron.BL` (u. a.
|
||||
Einkauf, Produktion, Projektverwaltung, Zeiterfassung im Kern, EDI, Reporting, Statistik,
|
||||
Zwei-Faktor-Authentifizierung, Passwortmanager) — siehe Abschnitt 3.4 für die vollständige Liste.
|
||||
|
||||
**Wo war der Beleg dünn?** Innerhalb der bearbeiteten Module war der Belegstand durchgehend `PRIMÄR`
|
||||
für sicherheits-/abrechnungs-/berechtigungsrelevante Aussagen (Auftragsvorgabe eingehalten). Am
|
||||
ehesten dünn belegt sind:
|
||||
- **StRS-4 (Lizenzierung, Geschäftsziel-Ebene)**, deren StRS-Formulierung sich primär auf die
|
||||
SEKUNDÄRE Dokumentation stützt (die zugehörigen SyRS/SwRS-Anforderungen sind dagegen PRIMÄR belegt).
|
||||
- **SwRS-4** (Sichrech-Rechteschema), das sich auf ein Dokumentations-Codebeispiel statt auf
|
||||
tatsächlich gelesenen Produktionscode der `UserRightsConst.cs`-Konstantenliste stützt (Datei selbst
|
||||
nur auf Existenz geprüft, nicht inhaltlich gelesen).
|
||||
- **StRS-16/SyRS-19 (Betrieb)**, wo die Linux-Fähigkeit aus der Compose-Konfiguration erschlossen,
|
||||
aber nicht durch Lesen von `docs/guides/services/web-service-on-linux.md` bestätigt wurde (H-3).
|
||||
- Alle vier offenen Hypothesen (H-1 bis H-4) markieren Stellen, an denen entweder Dokumentation und
|
||||
Code scheinbar auseinanderlaufen (H-1) oder eine serverseitige Durchsetzung nicht bis zum
|
||||
eigentlichen Speicherpfad zurückverfolgt wurde (H-2).
|
||||
|
||||
**Empfehlungen für eine Folge-Iteration** (Priorisierung nach vermuteter fachlicher Kritikalität):
|
||||
1. Kernprozesse Einkauf/Beschaffung, Bestandsführung, Produktion und Projektverwaltung nachholen —
|
||||
in dieser Iteration mit null Anforderungen, aber vermutlich zentrale ERP-Funktionen.
|
||||
2. `ReceiptBL.cs` vollständig (nicht nur Ausschnitte) auswerten; die Datei ist laut Dokumentation der
|
||||
zentrale Belegprozess-Knoten und mit >10.000 Zeilen die mit Abstand komplexeste Komponente.
|
||||
3. Datenbankschema direkt prüfen (CREATE-TABLE-/Constraint-Skripte), um `PRIMÄR`-Belege für
|
||||
Datenmodell-Anforderungen zu erhalten, die aktuell nur über Entity-Klassen/Dokumentation
|
||||
abgeleitet sind.
|
||||
4. EDI-Modul gezielt nachholen (Code statt nur Dokumentation), um die in Abschnitt 3.3/4.5 bewusst
|
||||
ausgelassenen Anforderungen belegbar nachzutragen.
|
||||
5. Externe Schnittstellen (`src/apis/*`, `Centron.Api.docuFORM`/C-Sign) für die SyRS-Kategorie
|
||||
"Schnittstelle" erschließen — bisher praktisch nicht abgedeckt.
|
||||
6. WPF-Client und Nexus-Portal zumindest stichprobenartig (MITTEL) für UI-seitige Geschäftsregeln und
|
||||
Kundenportal-Selbstbedienungsfunktionen einbeziehen.
|
||||
7. Offene Hypothesen H-1 bis H-4 gezielt durch Fachexperten (Schritt 7 der RRE-Methodenkette) oder
|
||||
durch vertiefte Codeprüfung klären.
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
# Glossar
|
||||
|
||||
Domänenbegriffe, wie sie in den Anforderungen (StRS/SyRS/SwRS) verwendet werden. Deutsche
|
||||
Fachbegriffe und technische Originalbezeichner (Tabellen, Klassen) werden gegenübergestellt.
|
||||
|
||||
Begriff | Definition | Technischer Bezug
|
||||
---|---|---
|
||||
I3D | Primärschlüsselkonvention des Systems ("ID 3develop"); jede Tabelle besitzt eine Spalte `I3D` als `int IDENTITY(1,1)`-Primärschlüssel; Fremdschlüsselspalten enden ebenfalls auf `I3D`. | docs/guides/database/database-conventions.md; durchgängig in Entities/DAO
|
||||
Recht | Eine einzelne, im System prüfbare Berechtigung für eine Aktion oder Sicht (z. B. "Kunde anlegen"). Rechte sind hierarchisch (Eltern-Kind über `OwnerRecht`) organisiert. | Tabelle `Sichrech`, Klasse `AppRight`, Konstanten in `UserRightsConst.cs`
|
||||
Rechtegruppe | Sammlung von Rechten, die gemeinsam einer oder mehreren Personen zugewiesen wird; Rechteprüfung erfolgt ausschließlich über Gruppenzugehörigkeit. | Tabelle `Sichgrup`, Klasse `AppGroup`
|
||||
Filiale (Branch) | Organisatorische Niederlassung eines Kunden-Unternehmens; steuert u. a. Sichtbarkeits-/Verwaltungsgrenzen bei eingeschränkten Rechten. | Spalte `BranchI3D`, Recht `MANAGE_RIGHTS_ONLY_OWN_BRANCH`
|
||||
Lizenz | Vom Lizenzserver ausgestellte, GUID-identifizierte Freischaltung einer Applikation oder Einzelfunktion, optional mit Anzahl-, Datums- und Versionsbegrenzung. | `LicenseGuids.cs`, `LicenseManager.cs`
|
||||
Applikation (Lizenzkontext) | Eine der Login-fähigen c-entron-Programme (z. B. c-entron.NET, Service-Board, Outlook-Add-In); jede Applikation besitzt eine eigene Lizenz-GUID. | `ApplicationKind.cs`
|
||||
Beleg (im Sinn dieser Spezifikation) | Konkreter Nachweis für eine Anforderung: Dateipfad/Klasse/Methode/SQL/UI-String/Kommentar, klassifiziert als PRIMÄR/SEKUNDÄR/KONTEXT. | Formatvorgabe des Auftrags (nicht codebezogen)
|
||||
Beleg (Geschäftsdokument, "Receipt") | Sammelbegriff für Angebot, Auftrag, Lieferschein, Rechnung, Gutschrift, Vertrag, Abholschein sowie deren lieferantenseitige Pendants; alle teilen eine gemeinsame technische Basis. | `ReceiptBase`, `ReceiptBL`
|
||||
Kopf/Position (Kopf/Pos) | Legacy-Datenbankmuster: ein Beleg besteht aus einem Kopfdatensatz (Header, Tabelle `*Kopf`) und mehreren Positionsdatensätzen (Zeilen, Tabelle `*Pos`). | z. B. `AngKopf`/`AngPos`, `RechKopf`/`RechPos`
|
||||
Belegstatus (ReceiptState) | Lebenszyklus-Zustand eines Belegs: offen (Active), abgeschlossen (Completed) oder storniert (Canceled). | `ReceiptState`-Enum
|
||||
Optimistische Sperre (Concurrency Control) | Mechanismus, der eine Speicherung ablehnt, wenn der Datensatz seit dem Laden durch eine andere Instanz geändert wurde, erkannt über ein pro Speicherung wechselndes GUID. | `ConcurrencyControlGuid`, Fehlercode `ChangedByOtherInstance`
|
||||
Kontingent | Im Vertrag vereinbartes Nutzungsguthaben (Stunden oder Betrag), das bei Leistungserbringung verbraucht und bei Überschreitung gesondert abgerechnet wird. | `ContingentUsedHours`, `ContingentLimitValue` (ReceiptContract)
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
# Hypothesen
|
||||
|
||||
Sammlung aller mit `[HYPOTHESE]` markierten Aussagen aus StRS/SyRS/SwRS, mit offener Frage,
|
||||
die zur Bestätigung geklärt werden müsste. Zur Validierung durch Fachexperten (Schritt 7 der
|
||||
RRE-Methodenkette).
|
||||
|
||||
ID | Ebene | Aussage (gekürzt) | Offene Frage / fehlende Information
|
||||
---|---|---|---
|
||||
H-1 | SwRS (SwRS-8) | Belegstatus hat laut Code nur 3 Werte (offen/abgeschlossen/storniert), Architekturdoku beschreibt 4 ("Draft/Released/Processed/Cancelled"). | Bildet ein weiteres Feld (Kandidat: `ReceiptUserStateI3D`, konfigurierbarer Benutzerstatus, ReceiptBL.cs Z.5268ff.) die von der Doku beschriebenen Zwischenzustände "Draft"/"Released" ab, oder ist die Doku an dieser Stelle veraltet? Nicht geklärt, da ReceiptUserStateI3D-Konfiguration nicht vertieft geprüft wurde.
|
||||
H-2 | StRS (StRS-14) | Recht CAN_CHANGE_DATE steuert nachweislich die UI-Feldfreigabe für ein abweichendes Abrechnungsdatum. | Wird dasselbe Recht auch beim serverseitigen Speichern des Belegs (ReceiptBL-Speicherpfad) erneut geprüft, oder verlässt sich das System ausschließlich auf die UI-Sperre? Falls Letzteres: ein direkter API-Aufruf könnte die Beschränkung umgehen. Nicht verifiziert, da ReceiptBL-Speicherpfad für Datumsfelder nicht vertieft geprüft wurde.
|
||||
H-3 | SyRS (SyRS-19) | Webservice läuft nachweislich in einem Linux-Container (compose.yaml). | Ist der Funktionsumfang unter Linux vollständig identisch zu Windows, oder bestehen bekannte Einschränkungen (z. B. bei TAPI/Outlook-Integration, die typischerweise Windows-spezifisch sind)? docs/guides/services/web-service-on-linux.md wurde nicht gelesen; Inhalt könnte dies klären.
|
||||
H-4 | Analysebericht (Modulinventar) | `src/backend/Centron.BL` enthält sowohl einen Ordner `Administration/Rights` (dort liegt `AppRightsBL.cs`, die Basis für StRS-1..3) als auch einen eigenständigen, gleichrangigen Ordner `Security`. | Wofür ist der separate `Security`-Ordner zuständig — überschneidet er sich fachlich mit der Rechteverwaltung (z. B. Verschlüsselung, Passwort-Policies, Session-Handling) oder ist er unabhängig? Nicht geprüft, da außerhalb der Tiefenanalyse dieser Iteration.
|
||||
|
||||
+482
@@ -0,0 +1,482 @@
|
||||
# Stakeholder Requirements Specification (StRS)
|
||||
## c-entron ERP-Suite — Reverse Requirements Engineering (Baseline V1, Iteration 01)
|
||||
|
||||
Erhoben nach ISO/IEC/IEEE 29148:2018 durch statische Codeanalyse der Codebasis unter
|
||||
`C:\DEV\MasterArbeit\QuellCode\CentronERP`. Diese Datei enthält die fachliche Sicht
|
||||
(Akteure, Geschäftsziele, Stakeholder-Erwartungen). Format je Anforderung siehe Auftragsvorgabe.
|
||||
Details zu Methodik, Abdeckung und Grenzen: siehe `Analysebericht.md`.
|
||||
|
||||
---
|
||||
|
||||
## Modul: Sicherheit & Berechtigungen (Rechteverwaltung)
|
||||
|
||||
```
|
||||
ID: StRS-1
|
||||
Titel: Rollen-/gruppenbasierte Rechteverwaltung
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Administrator, Fachanwender
|
||||
Vorbedingung: Benutzer ist im System angelegt und mindestens einer Rechtegruppe zugeordnet.
|
||||
Fakt: Rechte (`AppRight`/Tabelle `Sichrech`) werden Gruppen (`AppGroup`/`Sichgrup`) zugewiesen,
|
||||
Benutzer werden Gruppen zugeordnet (`AppUserMember`/`Sichmemb`); Rechteprüfung erfolgt
|
||||
ausschließlich über die Gruppenzugehörigkeit, nicht direkt am Benutzer.
|
||||
Aussage: Das System soll den Zugriff auf Funktionen und Daten ausschließlich über einem Benutzer
|
||||
zugeordnete Rechtegruppen steuern, sodass Administratoren Berechtigungen zentral über
|
||||
Gruppen statt für jeden Benutzer einzeln pflegen können.
|
||||
Ergebnis: Ein Benutzer erhält genau die Rechte, die einer seiner zugeordneten Gruppen zugewiesen sind.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs :: GetRightsFromCurrentUser,
|
||||
CheckRightsFromUser (SQL JOIN Sichtrus/Sichmemb über Gruppe) - Begründung: Rechteauflösung
|
||||
ist ausschließlich gruppenbasiert implementiert, kein direkter Benutzer-Rechte-Pfad vorhanden.
|
||||
- [KONTEXT] docs/guides/development/check-userrights.md - Begründung: beschreibt denselben Mechanismus
|
||||
als verbindliches Entwicklungsmuster.
|
||||
Prüfidee: Einem Benutzer wird ein Recht ausschließlich über Gruppenmitgliedschaft zugewiesen; Entfernen
|
||||
der Gruppenmitgliedschaft entzieht das Recht (Test über CheckRightsFromUser vor/nach Entfernen).
|
||||
Tracelinks: SyRS-1, SyRS-4, SwRS-1, SwRS-2
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-2
|
||||
Titel: Filialbezogene Einschränkung von Verwaltungsrechten
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Administrator (mit eingeschränktem Recht "nur eigene Filiale")
|
||||
Vorbedingung: Benutzer besitzt das Recht MANAGE_RIGHTS_ONLY_OWN_BRANCH.
|
||||
Fakt: `AppRightsBL.SaveRightGroup`/`DeleteRightGroup`/`GetAllRightGroups` prüfen bei gesetztem
|
||||
Recht `MANAGE_RIGHTS_ONLY_OWN_BRANCH`, ob `user.Employee.BranchI3D` mit `AppGroup.BranchI3D`
|
||||
übereinstimmt, und verweigern die Aktion sonst mit Fehlermeldung.
|
||||
Aussage: Das System soll Administratoren mit eingeschränktem Recht die Verwaltung von Rechtegruppen
|
||||
nur innerhalb der eigenen Filiale (Niederlassung) erlauben.
|
||||
Ergebnis: Zugriffsversuche auf Rechtegruppen anderer Filialen werden mit einer Fehlermeldung abgelehnt.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs :: SaveRightGroup (Zeilen 391-393),
|
||||
DeleteRightGroup (Zeilen 355-357) - Begründung: harte Prüfung mit Result.AsError vor jeder
|
||||
Schreiboperation, keine Umgehungsmöglichkeit im Code sichtbar.
|
||||
Prüfidee: Benutzer mit MANAGE_RIGHTS_ONLY_OWN_BRANCH versucht Gruppe einer fremden Filiale zu löschen;
|
||||
erwartet: Result mit Status Error und definierter Fehlermeldung.
|
||||
Tracelinks: SyRS-1, SwRS-3
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-3
|
||||
Titel: Nachvollziehbarkeit von Rechteänderungen
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Administrator, Auditor
|
||||
Vorbedingung: Eine Rechte- oder Gruppenänderung wird durchgeführt (Recht zuweisen/entziehen, Gruppe
|
||||
anlegen/löschen/kopieren, Benutzer zu-/abmelden).
|
||||
Fakt: Jede der genannten Operationen erzeugt einen Eintrag in `AppRightLog` mit Zeitstempel,
|
||||
ausführendem Benutzer, Aktionsart (`AppRightLogKind`) und lesbarer Beschreibung.
|
||||
Aussage: Das System soll jede Änderung an Rechten, Gruppen und Gruppenzuordnungen für eine spätere
|
||||
Nachvollziehbarkeit protokollieren.
|
||||
Ergebnis: Zu jeder rechterelevanten Änderung existiert ein abrufbarer Protokolleintrag.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs :: WriteBaseLog und die
|
||||
spezialisierten WriteXxxLog-Methoden (Zeilen 761-858) - Begründung: Logging ist untrennbar
|
||||
in den Schreibpfad jeder Rechteoperation eingebaut, nicht optional.
|
||||
Prüfidee: Nach AddRightToRightGroup existiert ein neuer AppRightLog-Eintrag mit Kind=AddRightToGroup.
|
||||
Tracelinks: SyRS-4, SwRS-3
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## Modul: Lizenzierung
|
||||
|
||||
```
|
||||
ID: StRS-4
|
||||
Titel: Feature- und Applikationslizenzierung pro Kunde
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Vertrieb, Kunde (Lizenznehmer), System (Login-Prüfung)
|
||||
Vorbedingung: Kunde hat ein c-entron-System im Einsatz und einen Lizenzsatz vom Lizenzserver bezogen.
|
||||
Fakt: Lizenzen werden als GUIDs (`LicenseGuids.cs`) geführt; `Applications` (`ApplicationKind.cs`)
|
||||
dürfen sich am Webservice anmelden, `Only Licenses` schalten einzelne Module/Funktionen frei;
|
||||
jede Lizenz kennt optional `count`, `valid until date`, `valid until version`.
|
||||
Aussage: Das System soll den Funktionsumfang und die Anmeldefähigkeit einzelner Applikationen anhand
|
||||
kundenspezifischer, zeitlich/mengenmäßig begrenzbarer Lizenzen steuern.
|
||||
Ergebnis: Nur lizenzierte Applikationen können sich anmelden; nur lizenzierte Module/Funktionen sind
|
||||
für den Kunden sichtbar/nutzbar.
|
||||
Belege:
|
||||
- [SEKUNDÄR] docs/reference/security/licensing-system.md - Begründung: beschreibt das Lizenzmodell,
|
||||
ist jedoch Dokumentation und kein durchgesetzter Code; Aussage daher [HYPOTHESE]-nah, siehe
|
||||
SwRS-Belege für die tatsächliche Durchsetzung im Code (LicenseManager).
|
||||
Prüfidee: Kunde ohne Lizenz für Modul X: LicenseManager.HasLicense(X) liefert false, UI blendet Modul X aus.
|
||||
Tracelinks: SyRS-2, SwRS-6
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modul: Verkaufsbelege (Angebot – Auftrag – Lieferschein – Rechnung – Gutschrift – Vertrag)
|
||||
|
||||
```
|
||||
ID: StRS-5
|
||||
Titel: Einheitlicher Belegprozess über den gesamten Auftrag-zu-Zahlung-Zyklus
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Vertriebsmitarbeiter, Buchhaltung, Kunde
|
||||
Vorbedingung: Ein Geschäftsvorfall (Angebot, Bestellung, Lieferung, Abrechnung) soll abgebildet werden.
|
||||
Fakt: Sieben Belegtypen (Offer/Angebot, Order/Auftrag, DeliveryList/Lieferschein, Invoice/Rechnung,
|
||||
Contract/Vertrag, CreditVoucher/Gutschrift, PickupList/Abholschein) erben von der
|
||||
gemeinsamen Basisklasse `ReceiptBase` mit einheitlichen Feldern (Nummer, Datum, Status,
|
||||
Kunde/Adresse, Währung, Audit-Felder) und werden über eine gemeinsame `ReceiptBL`
|
||||
(>10.000 Zeilen) verarbeitet.
|
||||
Aussage: Das System soll alle Stufen des Verkaufsprozesses (Angebot bis Zahlung) als zusammenhängende,
|
||||
strukturell einheitliche Belegkette abbilden, sodass Folgebelege konsistent aus Vorgängern
|
||||
abgeleitet und gemeinsam ausgewertet werden können.
|
||||
Ergebnis: Jeder Beleg ist eindeutig einem der sieben Belegtypen zugeordnet, referenziert bei Bedarf
|
||||
Vorgänger-/Folgebelege und wird über eine gemeinsame Business-Logik-Schicht verwaltet.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/Sales/Receipts/ReceiptBase.cs - Begründung: konkrete
|
||||
gemeinsame Basisklasse mit abstraktem `ReceiptKind`, in allen sieben Beleg-Entities verwendet.
|
||||
- [SEKUNDÄR] docs/reference/receipts/receipts-backend-architecture.md (Tabelle Belegtyp→Entity→Tabelle→View)
|
||||
- Begründung: bestätigt und benennt die konkreten sieben Belegtypen mit Tabellenbezug.
|
||||
Prüfidee: Für jeden der sieben Belegtypen existiert eine Entity-Klasse, die von ReceiptBase erbt und
|
||||
ReceiptKind liefert (Code-Review); GetReceiptForwardedInto liefert Folgebelege eines Belegs.
|
||||
Tracelinks: SyRS-7, SyRS-8, SwRS-8
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-6
|
||||
Titel: Nachvollziehbare, unveränderliche Belegversionshistorie
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Buchhaltung, Auditor, Fachanwender
|
||||
Vorbedingung: Ein bereits gespeicherter Beleg wird inhaltlich verändert und erneut gespeichert.
|
||||
Fakt: Beim Speichern eines bestehenden Belegs wird `receipt.Version = currentReceiptVersion.Version + 1`
|
||||
gesetzt und `SaveReceiptVersion(receipt, previousReceiptVersion)` aufgerufen, welches laut
|
||||
Architekturdokumentation den bisherigen Stand in eine `*Versions`-Tabelle (1:1-Kopie der
|
||||
Basistabelle) kopiert.
|
||||
Aussage: Das System soll bei jeder inhaltlichen Änderung eines Belegs den vorherigen Stand als
|
||||
eigene, unveränderliche Version aufbewahren, sodass der komplette Änderungsverlauf eines
|
||||
Belegs nachvollzogen werden kann.
|
||||
Ergebnis: Nach einer Änderung existiert sowohl die neue (aktuelle) als auch die vorherige Version des
|
||||
Belegs abrufbar über `GetReceiptVersionByI3D`.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs, Zeilen 3117 (Versionsinkrement) und 3629
|
||||
(SaveReceiptVersion-Aufruf im Speicherpfad) - Begründung: Versionierung ist unbedingter
|
||||
Bestandteil des Speicherpfades, nicht optional.
|
||||
- [SEKUNDÄR] docs/reference/receipts/receipts-backend-architecture.md, Abschnitt "Version Tables" -
|
||||
Begründung: erläutert das Zielschema (1:1-Kopie) der Versionstabellen ergänzend zum Code.
|
||||
Prüfidee: Beleg wird zweimal gespeichert (Version 1 → 2); GetReceiptVersionByI3D(..., version:1) liefert
|
||||
weiterhin den ursprünglichen Inhalt, unverändert durch die zweite Speicherung.
|
||||
Tracelinks: SyRS-10, SwRS-11, SwRS-12
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-7
|
||||
Titel: Schutz vor gleichzeitiger, kollidierender Bearbeitung eines Belegs
|
||||
Ebene: StRS
|
||||
Typ: nicht-funktional (Zuverlässigkeit, ISO25010)
|
||||
Akteur: Mehrere gleichzeitig arbeitende Fachanwender
|
||||
Vorbedingung: Zwei Benutzer öffnen denselben Beleg gleichzeitig zur Bearbeitung.
|
||||
Fakt: Jeder Beleg trägt ein `ConcurrencyControlGuid`; beim Speichern wird geprüft, ob das vom
|
||||
Client mitgesendete Guid noch mit dem aktuellen serverseitigen Guid übereinstimmt; bei
|
||||
Abweichung wird die Speicherung mit Fehlercode `ChangedByOtherInstance` abgelehnt. Zusätzlich
|
||||
existiert ein serverseitiger Locking-Mechanismus (`TryLockReceipt`/`UnLockReceipt`).
|
||||
Aussage: Das System soll verhindern, dass ein Benutzer die Änderungen eines anderen Benutzers am
|
||||
selben Beleg unbemerkt überschreibt, indem gleichzeitige, auf einem veralteten Stand
|
||||
basierende Speicherversuche abgelehnt werden.
|
||||
Ergebnis: Ein Speicherversuch auf Basis eines veralteten Belegstands wird mit einer eindeutigen
|
||||
Fehlermeldung abgelehnt, statt die zwischenzeitliche Änderung stillschweigend zu verwerfen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs, u. a. Zeilen 4808-4809, 4843-4844,
|
||||
4884-4885 (wiederkehrendes Muster ConcurrencyControlGuid-Vergleich); Zeilen 3093-3096
|
||||
(TryLockReceipt) - Begründung: an mehreren unabhängigen Update-Methoden wiederkehrend
|
||||
durchgesetzte Prüfung, kein Einzelfall.
|
||||
Prüfidee: Benutzer A lädt Beleg (Guid=X), Benutzer B speichert denselben Beleg zuerst (Guid ändert
|
||||
sich auf Y); Speicherversuch von Benutzer A mit Guid=X liefert Fehlercode ChangedByOtherInstance.
|
||||
Tracelinks: SyRS-8, SwRS-9
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-8
|
||||
Titel: Verwaltung des Zahlungsstatus eines Belegs durch die Debitorenbuchhaltung
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Mitarbeiter Debitorenbuchhaltung/Zahlungseingang
|
||||
Vorbedingung: Ein Zahlungseingang zu einem Beleg (z. B. Rechnung) ist eingetroffen oder storniert worden.
|
||||
Fakt: `ReceiptBL.UpdateReceiptIsPaid` setzt anhand eines `isPaid`-Flags den Belegstatus auf
|
||||
`Completed` oder `Active` und erlaubt dies auch Benutzern ohne allgemeines
|
||||
Belegbearbeitungsrecht, sofern sie das gesonderte Recht `INCOMING_PAYMENT_TRANSACTIONS`
|
||||
besitzen.
|
||||
Aussage: Das System soll es dem für Zahlungseingänge zuständigen Personal ermöglichen, den
|
||||
Zahlungsstatus eines Belegs eigenständig zu pflegen, unabhängig von der allgemeinen
|
||||
Bearbeitungsberechtigung für den jeweiligen Belegtyp.
|
||||
Ergebnis: Der Belegstatus spiegelt den tatsächlichen Zahlungseingang wider und ist für Berichtszwecke
|
||||
(offene Posten) auswertbar.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs :: UpdateReceiptIsPaid (Z.4902-4950)
|
||||
- Begründung: Statuszuweisung und Sonderrecht sind im selben Methodenkörper durchgesetzt.
|
||||
Prüfidee: Setzen von isPaid=true auf einem aktiven Beleg ändert dessen State auf Completed; erneutes
|
||||
Setzen von isPaid=false ändert ihn zurück auf Active.
|
||||
Tracelinks: SyRS-9, SyRS-11, SwRS-8, SwRS-10
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modul: Verträge & automatisierte Abrechnung (MSP/Wartungsverträge)
|
||||
|
||||
```
|
||||
ID: StRS-9
|
||||
Titel: Automatisierte, wiederkehrende Vertragsabrechnung
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Buchhaltung, Vertriebsinnendienst (Abrechnungslauf), Kunde (Vertragsnehmer)
|
||||
Vorbedingung: Ein aktiver Vertrag mit konfiguriertem Abrechnungsintervall existiert.
|
||||
Fakt: `AutomaticFacturaBL.SearchBillingContracts`/`GetActiveContracts` selektieren Verträge anhand
|
||||
von Status, Berechnungsart (`ContractCalculationKind`: Auto/Bedarf/Manuell), Abrechnungs-
|
||||
intervall, Filiale und weiteren Ausschlusskriterien für einen automatisierten Abrechnungslauf,
|
||||
der anschließend Rechnungen erzeugt (`StoreInvoiceToContract`).
|
||||
Aussage: Das System soll Verträge mit wiederkehrender Leistungserbringung (z. B. Wartungs-/MSP-Verträge)
|
||||
automatisiert und periodisch abrechnen können, ohne dass für jede Abrechnungsperiode eine
|
||||
manuelle Rechnungserstellung notwendig ist.
|
||||
Ergebnis: Für alle zur Abrechnung fälligen und qualifizierten Verträge werden im Abrechnungslauf
|
||||
Rechnungen erzeugt und das Ergebnis je Vertrag protokolliert (`StoreBillingResult`).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.Contracts.cs
|
||||
:: GetActiveContracts (Z.820-845), SearchBillingContracts (Z.847ff.), StoreInvoiceToContract
|
||||
(Z.1258), StoreBillingResult (Z.2101) - Begründung: durchgängige, mehrstufige Selektions- und
|
||||
Verarbeitungskette für die automatische Rechnungserzeugung, kein UI-Mock oder Doku-Aussage.
|
||||
- [SEKUNDÄR] docs/reference/receipts/contracts-backend.md, Abschnitt "Automated Billing Process" -
|
||||
Begründung: beschreibt denselben Ablauf auf konzeptioneller Ebene, deckungsgleich mit Code.
|
||||
Prüfidee: Vertrag mit CalculationKind=Auto, State=aktiv, fälligem Intervall und mind. einer abrechenbaren
|
||||
Position wird von SearchBillingContracts zurückgeliefert und mündet in einer neuen Rechnung.
|
||||
Tracelinks: SyRS-12, SyRS-13, SwRS-13, SwRS-14
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: StRS-10
|
||||
Titel: Unterschiedliche Abrechnungssteuerung je Vertrag (automatisch / nach Bedarf / manuell)
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Vertriebsinnendienst, Buchhaltung
|
||||
Vorbedingung: Vertrag wird angelegt oder gepflegt.
|
||||
Fakt: `ContractCalculationKind` unterscheidet mindestens die Werte `Auto`, `Need` ("Bedarf") und
|
||||
einen darüberliegenden manuellen Modus; die Selektionslogik in `GetActiveContracts`
|
||||
behandelt jede Berechnungsart mit eigenen Bedingungen (automatisch: Zeitraum-/Zahlungsprüfung;
|
||||
Bedarf/Manuell: direkte Filterauswahl durch den Anwender).
|
||||
Aussage: Das System soll je Vertrag festlegen können, ob die Abrechnung vollautomatisch, nur bei
|
||||
tatsächlichem Bedarf (z. B. variabler Nutzung) oder ausschließlich manuell ausgelöst wird.
|
||||
Ergebnis: Verträge mit Berechnungsart "Auto" erscheinen automatisch im fälligen Abrechnungslauf,
|
||||
"Bedarf"/"Manuell"-Verträge nur bei expliziter Auswahl durch den Anwender.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.Contracts.cs
|
||||
:: GetActiveContracts (Z.828-831) - Begründung: unterschiedliche Bedingungszweige je
|
||||
CalculationKind sind direkt im Code sichtbar.
|
||||
Prüfidee: Zwei sonst identische Verträge mit CalculationKind=Auto bzw. =Need: nur der Auto-Vertrag wird
|
||||
bei einem automatisierten Lauf ohne explizite Filterauswahl selektiert.
|
||||
Tracelinks: SyRS-12, SwRS-13
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modul: Mahnwesen (Dunning)
|
||||
|
||||
```
|
||||
ID: StRS-11
|
||||
Titel: Mehrstufiges Mahnwesen für überfällige Rechnungen
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Debitorenbuchhaltung, Kunde (Rechnungsempfänger)
|
||||
Vorbedingung: Eine Rechnung ist ganz oder teilweise unbezahlt und überfällig.
|
||||
Fakt: `DunningBL` verwaltet Rechnungen über ein vierstufiges `DunningLevel` (None, Level1, Level2,
|
||||
Level3), berechnet je Stufe offene Bruttobeträge (`GrossPriceComplete - PayedGrossAmount -
|
||||
CreditVoucherGrossAmount`) und unterstützt eine kunden-/objektbezogene Mahnsperre
|
||||
(`UpdateDunningStopAndInfo` mit Zeitraum) sowie individuelle Mahnadressen/-versandarten.
|
||||
Aussage: Das System soll überfällige, unbezahlte Rechnungen automatisiert in aufeinanderfolgende
|
||||
Mahnstufen einordnen und dabei kundenspezifische Ausnahmen (Mahnsperre, abweichende
|
||||
Mahnadresse) berücksichtigen.
|
||||
Ergebnis: Jede überfällige Rechnung ist eindeutig einer Mahnstufe zugeordnet; für Kunden mit aktiver
|
||||
Mahnsperre im gültigen Zeitraum wird keine Mahnstufe erhöht bzw. kein Mahnschreiben versendet.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/Invoices/Dunning/DunningBL.cs :: GetDunningCustomers,
|
||||
CalculateDunningStatistics (Z.184-231), UpdateDunningStopAndInfo (Z.392) - Begründung:
|
||||
konkrete, durchgesetzte Berechnungs- und Sperrlogik im Code.
|
||||
Prüfidee: Rechnung mit DunningLevel=Level1 und Restbetrag > 0 erscheint in
|
||||
CalculateDunningStatistics.InvoicesInLevel1Count; nach Setzen einer aktiven Mahnsperre für
|
||||
den Kunden wird die Rechnung im nächsten Mahnlauf nicht weiter eskaliert (Prüfung an
|
||||
GetDunningCustomers mit gesetztem DunningStop-Zeitraum).
|
||||
Tracelinks: SyRS-14, SwRS-15
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modul: Umsatzsteuer (Warehousing/Tax)
|
||||
|
||||
```
|
||||
ID: StRS-12
|
||||
Titel: Zeitlich korrekte Umsatzsteuerermittlung für Belegpositionen
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Buchhaltung, System (Belegerstellung)
|
||||
Vorbedingung: Eine Belegposition mit einem Artikel/Steuersatz wird zu einem bestimmten Belegdatum berechnet.
|
||||
Fakt: `TaxBL.GetTaxRateForReceiptItem(taxRateI3D, receiptDate, ...)` ermittelt den zum Belegdatum
|
||||
gültigen Steuersatz über eine verkettete Historie (`NextTaxRate`/`ExpirationDate`) statt
|
||||
den zum Aufrufzeitpunkt aktuellen Satz zu verwenden.
|
||||
Aussage: Das System soll für jede Belegposition den zum jeweiligen Belegdatum gesetzlich gültigen
|
||||
Umsatzsteuersatz ermitteln, auch wenn sich der Steuersatz zwischenzeitlich geändert hat
|
||||
(z. B. befristete Steuersatzänderungen).
|
||||
Ergebnis: Belege mit historischem Datum verwenden den zu diesem Zeitpunkt gültigen Steuersatz, nicht
|
||||
den aktuell in der Stammdatenverwaltung hinterlegten.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Warehousing/TaxBL.cs :: GetTaxRateForReceiptItem (Z.207-ff.),
|
||||
GetTaxRateChain (Z.172-205) - Begründung: konkrete, im Code durchgesetzte Verkettungs- und
|
||||
Datumslogik, kein reiner Stammdatenzugriff.
|
||||
Prüfidee: Belegposition mit Belegdatum vor einer historischen Steuersatzänderung liefert den alten
|
||||
Steuersatz; dieselbe Position mit aktuellem Datum liefert den neuen Steuersatz.
|
||||
Tracelinks: SyRS-15, SwRS-16
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modul: Kunden-/Lieferantenstammdaten (Account/CRM)
|
||||
|
||||
```
|
||||
ID: StRS-13
|
||||
Titel: Vereinheitlichte Geschäftspartner-Stammdaten (Kunde und/oder Lieferant in einer Entität)
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Vertrieb, Einkauf, Buchhaltung
|
||||
Vorbedingung: Ein Geschäftspartner wird angelegt oder gepflegt.
|
||||
Fakt: Die Entität `Account` (`AccountBL`) führt sowohl `CustomerNumber` als auch `SupplierNumber`
|
||||
parallel; Rechteprüfungen unterscheiden zwischen kunden- (`CustomerCommon.*`) und
|
||||
lieferantenbezogenen Rechten (`RIGHT_LIEFERANTANLEGEN`/`RIGHT_LIEFERANTAENDERN`) auf
|
||||
demselben Datensatz.
|
||||
Aussage: Das System soll Geschäftspartner unabhängig davon, ob sie als Kunde, Lieferant oder beides
|
||||
auftreten, als einen gemeinsamen Stammdatensatz (Account) verwalten.
|
||||
Ergebnis: Ein Geschäftspartner kann gleichzeitig eine Kunden- und eine Lieferantennummer besitzen,
|
||||
ohne als zwei getrennte Datensätze gepflegt werden zu müssen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Accounts/AccountBL.cs, Z.980-983 (AccountName/AccountNumber/
|
||||
CustomerNumber/SupplierNumber im selben DTO), Z.1302-1312 (getrennte Kunden-/
|
||||
Lieferantenrechte auf demselben Save-Aufruf) - Begründung: Datenmodell und Rechteprüfung
|
||||
behandeln Kunde/Lieferant als Aspekte derselben Entität, nicht als getrennte Objekte.
|
||||
Prüfidee: Ein Account-Datensatz mit gesetzter CustomerNumber UND SupplierNumber lässt sich anlegen und
|
||||
über beide Nummern wiederfinden.
|
||||
Tracelinks: SyRS-16, SwRS-17
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modul: Zeiterfassungsabrechnung (Timer Billing)
|
||||
|
||||
```
|
||||
ID: StRS-14
|
||||
Titel: Rechtebasierte Freigabe zum manuellen Überschreiben des Abrechnungsdatums
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Fachanwender (Zeiterfassung/Abrechnung), Buchhaltung
|
||||
Vorbedingung: Aus erfassten Zeiten (Timern) soll ein Beleg (Rechnung oder Lieferschein) mit einem vom
|
||||
Systemdatum abweichenden Datum erzeugt werden.
|
||||
Fakt: Das Recht `CAN_CHANGE_DATE` (getrennt für Rechnung und Lieferschein) wird serverseitig in
|
||||
`ReceiptWebServiceBL` ausgewertet (`CanChangeDateInInvoices`/`CanChangeDateInDeliveryLists`)
|
||||
und über die ReceiptSettings an den Client übertragen; die Timer-Billing-Einstellungsseite
|
||||
aktiviert das Datumsfeld nur, wenn dieses Recht vorliegt, und zeigt sonst einen Hinweistext.
|
||||
Aussage: Das System soll das manuelle Setzen eines abweichenden Abrechnungsdatums bei aus
|
||||
Zeiterfassung erzeugten Rechnungen/Lieferscheinen nur Benutzern mit dem entsprechenden
|
||||
Recht erlauben.
|
||||
Ergebnis: Benutzer ohne das Recht sehen das Datumsfeld deaktiviert und einen erklärenden Hinweistext;
|
||||
Benutzer mit Recht können ein abweichendes Datum setzen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/WebServices/Sales/Receipts/ReceiptWebServiceBL.cs, Z.996,998
|
||||
(Auswertung von UserRightsConst...CAN_CHANGE_DATE) - Begründung: serverseitige Auswertung
|
||||
des tatsächlichen Benutzerrechts, keine reine UI-Annahme.
|
||||
- [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Finances/TimerBilling/Pages/TimerBillingSettingsPageViewModel.cs
|
||||
:: UpdateBillingDateIsEnabled (Commit baa9e7bd9b) - Begründung: UI-Umsetzung, die auf dem
|
||||
serverseitig ermittelten Recht aufbaut.
|
||||
Prüfidee: Benutzer ohne CAN_CHANGE_DATE-Recht öffnet Timer-Billing-Einstellungen: Datumsfeld ist
|
||||
deaktiviert, Hinweistext "Sie besitzen nicht das Recht..." wird angezeigt.
|
||||
Tracelinks: SyRS-17, SwRS-18
|
||||
Konsolidierung: Kandidat: StRS-1 (gleiches zugrundeliegendes Rechtesystem, hier auf ein einzelnes Feld
|
||||
statt eine ganze Operation angewendet)
|
||||
Status: belegt
|
||||
```
|
||||
Hinweis [HYPOTHESE] zu StRS-14: Ob das abweichende Datum auch serverseitig beim eigentlichen Speichern des
|
||||
Belegs (nicht nur bei der UI-Feld-Aktivierung) gegen das Recht geprüft wird, wurde in dieser Iteration nicht
|
||||
verifiziert (ReceiptBL-Speicherpfad für Datumsfelder nicht vertieft geprüft) — siehe Hypothesen.md (H-2).
|
||||
|
||||
---
|
||||
|
||||
## Modul: Helpdesk/Ticketsystem
|
||||
|
||||
```
|
||||
ID: StRS-15
|
||||
Titel: Konfigurierbare Ticketstatus-Verwaltung mit Verrechnungssteuerung je Status
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Administrator (Konfiguration), Support-Mitarbeiter
|
||||
Vorbedingung: Ein Ticket wird bearbeitet und durchläuft verschiedene Bearbeitungsstände.
|
||||
Fakt: Anders als der fest codierte `ReceiptState`-Enum ist der Ticketstatus (`HelpdeskState`,
|
||||
erbt von `HelpdeskStateBase`) eine frei konfigurierbare Stammdaten-Entität mit Name, Icon,
|
||||
Deaktivierungsflag, Web-Darstellung fürs Kundenportal ("Service Board") sowie einem
|
||||
eigenen Flag `IsInternalCompanyBillingActive`.
|
||||
Aussage: Das System soll es Administratoren erlauben, Ticketstatus frei zu definieren (Name, Icon,
|
||||
Darstellung im Kundenportal) und je Status zu steuern, ob für Tickets in diesem Status die
|
||||
interne Verrechnung aktiv ist.
|
||||
Ergebnis: Administratoren können neue Ticketstatus anlegen/deaktivieren, ohne Code-Änderung; die
|
||||
interne Verrechnung von Tickets folgt dem je Status konfigurierten Verrechnungsflag.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/CustomerArea/Support/HelpdeskStateBase.cs und
|
||||
HelpdeskState.cs (vollständige Dateien) - Begründung: Statuswerte sind als Datenbank-Entität
|
||||
mit Verwaltungsfeldern modelliert, nicht als Programm-Enum wie bei Belegen.
|
||||
Prüfidee: Anlegen eines neuen HelpdeskState-Datensatzes mit IsInternalCompanyBillingActive=false; Tickets
|
||||
in diesem Status werden in der internen Verrechnung nicht berücksichtigt (Abgrenzung zu
|
||||
Status mit IsInternalCompanyBillingActive=true).
|
||||
Tracelinks: SyRS-18, SwRS-19
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modul: Betrieb & Bereitstellung (Deployment)
|
||||
|
||||
```
|
||||
ID: StRS-16
|
||||
Titel: Containerisierte, mehrteilige Serverbereitstellung
|
||||
Ebene: StRS
|
||||
Typ: nicht-funktional (Übertragbarkeit, ISO25010)
|
||||
Akteur: Betrieb/DevOps, Hosting-Kunde
|
||||
Vorbedingung: Das Backend (Webservice, Datenbank, Blazor-Portal "Nexus") soll bereitgestellt werden.
|
||||
Fakt: `docker/compose/compose.yaml` definiert vier eigenständige Container (MSSQL-Datenbank,
|
||||
Webservice unter `/app/Centron.Host.Console`, SMTP-Mailcatcher für Testzwecke, Blazor-Portal
|
||||
"Nexus" unter `/app/CentronNexus.Host`) mit expliziten Abhängigkeiten (`depends_on`) und
|
||||
Neustartrichtlinie (`restart: on-failure`).
|
||||
Aussage: Das System soll Webservice, Datenbank und Kundenportal als unabhängig containerisierte,
|
||||
über Docker Compose orchestrierbare Dienste bereitstellbar machen.
|
||||
Ergebnis: Eine vollständige Serverumgebung (DB, API, Portal) lässt sich mit einem einzigen
|
||||
Compose-Befehl aus vordefinierten Container-Images starten.
|
||||
Belege:
|
||||
- [PRIMÄR] docker/compose/compose.yaml (vollständige Datei) - Begründung: konkrete, lauffähige
|
||||
Konfigurationsdatei mit Image-Referenzen, Ports und Abhängigkeiten, kein Konzeptpapier.
|
||||
Prüfidee: `docker compose up` im Verzeichnis docker/compose startet alle vier Dienste; der Webservice
|
||||
ist erst nach erfolgreichem DB-Start (depends_on) aktiv nutzbar.
|
||||
Tracelinks: SyRS-19, SwRS-20
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
+574
@@ -0,0 +1,574 @@
|
||||
# Software Requirements Specification (SwRS)
|
||||
## c-entron ERP-Suite — Reverse Requirements Engineering (Baseline V1, Iteration 01)
|
||||
|
||||
Komponenten, Datenmodelle, software-interne Regeln. Details zu Methodik, Abdeckung und Grenzen:
|
||||
siehe `Analysebericht.md`.
|
||||
|
||||
---
|
||||
|
||||
## Modul: Sicherheit & Berechtigungen
|
||||
|
||||
```
|
||||
ID: SwRS-1
|
||||
Titel: Sessionweites Caching der Benutzerrechte
|
||||
Ebene: SwRS
|
||||
Typ: nicht-funktional (Performance-Effizienz, ISO25010)
|
||||
Akteur: BL-Komponente AppRightsBL
|
||||
Vorbedingung: HasUserRight wird für einen Benutzer innerhalb derselben Session mehrfach aufgerufen.
|
||||
Fakt: `HasUserRight` liest über `Session.Advanced.Cache.GetOrAdd($"AllRightsFromAppUser{appUserI3D}", ...)`;
|
||||
erst beim Cache-Miss wird die SQL-Abfrage gegen `Sichtrus`/`Sichmemb` ausgeführt.
|
||||
Aussage: Das System soll die vollständige Rechteliste eines Benutzers innerhalb einer Session cachen,
|
||||
um wiederholte Datenbankzugriffe bei mehrfachen Rechteprüfungen zu vermeiden.
|
||||
Ergebnis: Nur der erste HasUserRight-Aufruf pro Benutzer und Session löst eine SQL-Abfrage aus; alle
|
||||
folgenden Aufrufe werden aus dem Cache bedient.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs :: HasUserRight (Z.644-649)
|
||||
- Begründung: Cache-Schlüssel und GetOrAdd-Aufruf sind direkt im Code sichtbar.
|
||||
Prüfidee: Zwei aufeinanderfolgende HasUserRight-Aufrufe für denselben Benutzer in derselben Session:
|
||||
nur beim ersten Aufruf wird die SQL-Query protokolliert/ausgeführt (z. B. per SQL-Profiler).
|
||||
Tracelinks: SyRS-1
|
||||
Konsolidierung: Kandidat: SwRS-2 (ähnlicher Cache-Mechanismus für Web-Account-Rechte, HasWebAccountRight)
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-2
|
||||
Titel: Massenprüfung mehrerer Rechte in einem Datenbankzugriff
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: BL-Komponente AppRightsBL
|
||||
Vorbedingung: Aufrufer möchte mehrere Rechte eines Benutzers gleichzeitig prüfen (z. B. Create/Edit/Delete/
|
||||
Search/Unlock für Kunden).
|
||||
Fakt: `CheckRightsFromUser(int appUserI3D, IList<int> rightI3Ds)` führt eine einzelne SQL-Abfrage mit
|
||||
`IN (:RightI3Ds)`-Klausel aus und liefert die Teilmenge der tatsächlich zugewiesenen Rechte zurück.
|
||||
Aussage: Das System soll die Prüfung mehrerer Rechte eines Benutzers in einem einzigen Datenbankzugriff
|
||||
ermöglichen, statt pro Recht einen eigenen Aufruf zu benötigen.
|
||||
Ergebnis: Der Aufrufer erhält die Schnittmenge aus angefragten und tatsächlich zugewiesenen Rechten
|
||||
als Liste von I3Ds zurück.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs :: CheckRightsFromUser (Z.95-111)
|
||||
- Begründung: SQL mit IN-Klausel und Parameterliste ist der durchgesetzte Mechanismus.
|
||||
- [KONTEXT] docs/guides/development/check-userrights.md (AccountBL-Beispiel) - Begründung: zeigt
|
||||
Verwendungsmuster in einer aufrufenden BL-Klasse.
|
||||
Prüfidee: Aufruf mit 5 Recht-IDs, von denen der Benutzer 3 besitzt, liefert eine Liste mit genau
|
||||
diesen 3 IDs.
|
||||
Tracelinks: SyRS-1
|
||||
Konsolidierung: Kandidat: SwRS-1
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-3
|
||||
Titel: Hartkodierte Positivliste änderbarer Administrator-Rechte
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: BL-Komponente AppRightsBL
|
||||
Vorbedingung: Eine Rechteänderung an der Administratoren-Gruppe wird versucht.
|
||||
Fakt: `GetAssignableAdminRightI3Ds()` liefert eine im Quellcode fest verdrahtete Liste von ca. 38
|
||||
numerischen Recht-IDs (mit Klartext-Kommentaren, z. B. "Angebote anzeigen - nur Eigene");
|
||||
nur diese IDs dürfen bei der Administratorgruppe hinzugefügt/entfernt werden.
|
||||
Aussage: Das System soll die Menge der bei der Administratoren-Gruppe änderbaren Rechte auf eine
|
||||
fest im Code hinterlegte Liste beschränken.
|
||||
Ergebnis: Versuche, ein nicht gelistetes Recht der Administratorgruppe hinzuzufügen oder zu entziehen,
|
||||
werden mit Rückgabewert `false` abgelehnt, ohne Datenbankänderung.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs :: GetAssignableAdminRightI3Ds
|
||||
(Z.714-759) - Begründung: Liste wird direkt im Code als Prüfgrundlage verwendet (SaveAndAssignGroupToRight).
|
||||
Prüfidee: Zuweisungsversuch eines Rechts mit I3D, das nicht in der Liste enthalten ist, an die
|
||||
Administratorgruppe liefert `false`.
|
||||
Tracelinks: SyRS-3, SyRS-4
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround (hartkodierte ID-Liste statt konfigurierbarer Regel — Migrationsrisiko:
|
||||
bei neuen Rechten muss die Liste manuell im Quellcode gepflegt werden, sonst inkonsistentes
|
||||
Verhalten zwischen Rechteverwaltung und Administratorgruppen-Schutz)
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-4
|
||||
Titel: Hierarchisches Rechteschema in Tabelle Sichrech
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: Entwickler (bei Anlage neuer Rechte), System (Rechteprüfung)
|
||||
Vorbedingung: Ein neues Recht soll dem System hinzugefügt werden.
|
||||
Fakt: Rechte werden in der Tabelle `Sichrech` mit den Spalten `I3D` (eindeutige Recht-ID),
|
||||
`OwnerRecht` (übergeordnetes Recht), `NumChildren` (Anzahl untergeordneter Rechte), `Text`
|
||||
(Anzeigename) und `Beschreibung` gespeichert; neue Rechte werden per
|
||||
`ScriptHelpers.AddRightIfNotExists(...)` in Migrationsskripten angelegt.
|
||||
Aussage: Das System soll Rechte als hierarchische Baumstruktur (Eltern-Kind über OwnerRecht) in der
|
||||
Datenbank abbilden, sodass Rechtegruppen thematisch gegliedert und in der Rechteverwaltung
|
||||
strukturiert dargestellt werden können.
|
||||
Ergebnis: Jedes neue Recht besitzt eine eindeutige I3D, ein Elternrecht (OwnerRecht) und ist über
|
||||
Migrationsskripte reproduzierbar in jeder Umgebung anlegbar.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/guides/development/add-a-new-right.md, Codebeispiel `ScriptHelpers.AddRightIfNotExists(...)`
|
||||
mit realer INSERT-Anweisung gegen Sichrech (I3D, Nummer, Text, OwnerRecht, NumChildren,
|
||||
Beschreibung) - Begründung: das dokumentierte SQL ist die tatsächliche Anlagemethode für
|
||||
Produktivdaten, kein bloßer Vorschlag.
|
||||
- [KONTEXT] src/webservice/Centron.WebServices.Core/EntitiesWrongPlace/Administration/Rights/UserRightsConst.cs
|
||||
- Begründung: enthält die im Code referenzierten Recht-Konstanten (nicht inhaltlich gelesen,
|
||||
nur als Fundstelle bestätigt; Datei ist mit 764 Dateien im Interfaces-Baum Teil einer sehr
|
||||
großen Struktur — Tiefenprüfung des vollständigen Konstantenbaums nicht erfolgt, siehe Analysebericht).
|
||||
Prüfidee: Ausführen eines Migrationsskripts mit AddRightIfNotExists erzeugt einen neuen Sichrech-Datensatz
|
||||
mit korrektem OwnerRecht-Bezug; NumChildren des Elternrechts erhöht sich um 1.
|
||||
Tracelinks: SyRS-1
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-5
|
||||
Titel: Entwicklungsseitige Umleitung externer E-Mail-Adressen in Debug-Builds
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System (Mailversand-Komponente)
|
||||
Vorbedingung: Die Anwendung läuft als DEBUG-Build; eine E-Mail an eine externe Adresse (nicht endend auf
|
||||
"nexoware.com") soll versendet werden.
|
||||
Fakt: `DeveloperSecurity.Email.ValidateAddress(string emailAddress)` ersetzt jede nicht-interne
|
||||
Zieladresse durch `test@nexoware.com`, sofern `AllowSendingEmailToExternalAddresses`
|
||||
(Standardwert: `DebugHelper.IsReleaseBuild()`) nicht gesetzt ist; in Release-Builds ist die
|
||||
Umleitung standardmäßig deaktiviert.
|
||||
Aussage: Das System soll in Entwicklungs-/Debug-Builds automatisch verhindern, dass E-Mails an
|
||||
tatsächliche (externe) Kundenadressen versendet werden, indem die Zieladresse durch eine
|
||||
interne Testadresse ersetzt wird.
|
||||
Ergebnis: In Debug-Builds erreichen ausgehende E-Mails an externe Adressen nie den echten Empfänger,
|
||||
sondern immer `test@nexoware.com`; interne (nexoware.com) Adressen bleiben unverändert.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Common/DeveloperSecurity.cs :: ValidateAddress (Z.30-46) - Begründung:
|
||||
die Ersetzungslogik ist zwingend im Code verankert, nicht optional zuschaltbar außer durch
|
||||
Codeänderung der Property.
|
||||
Prüfidee: Debug-Build, Versand an "kunde@fremdefirma.de": tatsächlicher SMTP-Empfänger ist
|
||||
"test@nexoware.com"; Versand an "kollege@nexoware.com" bleibt unverändert.
|
||||
Tracelinks: (kein direkter StRS/SyRS-Bezug – reine Entwicklungssicherheitsmaßnahme, kein Fachprozess)
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround (baujahresspezifischer Schutzmechanismus für die bestehende Delphi-/
|
||||
.NET-Desktop-Systemlandschaft; für eine Web-/SaaS-Neuimplementierung ist ein äquivalentes,
|
||||
umgebungsbasiertes Schutzkonzept — z. B. getrennte Sandbox-Mandanten/Test-Tenants statt
|
||||
Build-Konfiguration — zu definieren)
|
||||
```
|
||||
|
||||
## Modul: Lizenzierung
|
||||
|
||||
```
|
||||
ID: SwRS-6
|
||||
Titel: Lizenzmanager als Prozess-Singleton mit expliziter Einmalinitialisierung
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System (Applikationsstart)
|
||||
Vorbedingung: Anwendung (c-entron.NET oder Webservice) startet.
|
||||
Fakt: `LicenseManager.Initialize(settings)` wirft eine Exception, wenn `_instance` bereits gesetzt
|
||||
ist; `LicenseManager.Instance` wirft eine Exception, wenn `Initialize` noch nicht aufgerufen
|
||||
wurde. Für Webservice, c-entron.NET und Tests existieren jeweils eigene statische
|
||||
Settings-Fabriken (`SettingsForWebService`, `SettingsForCentronNet`, `SettingsForTests`).
|
||||
Aussage: Das System soll den Lizenzmanager pro Prozess genau einmal initialisieren und danach über
|
||||
einen globalen Zugriffspunkt (Singleton) verfügbar machen, mit klar unterscheidbarer
|
||||
Konfiguration je Hostumgebung (Webservice, Desktop-Client, Testlauf).
|
||||
Ergebnis: Doppelte Initialisierung führt zu einer Exception beim Start; Zugriff vor Initialisierung
|
||||
führt ebenfalls zu einer Exception.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Licensing/LicenseManager.cs :: Initialize (Z.174-182),
|
||||
Instance (Z.185-194) - Begründung: beide Guard-Exceptions sind unmittelbar im Code sichtbar
|
||||
und erzwingen das Singleton-Verhalten.
|
||||
Prüfidee: Zweiter Aufruf von Initialize() in derselben Prozessinstanz löst eine Exception aus;
|
||||
Zugriff auf Instance vor jedem Initialize()-Aufruf löst ebenfalls eine Exception aus.
|
||||
Tracelinks: SyRS-5, SyRS-6
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-7
|
||||
Titel: Sonderbehandlung der c-entron-Delphi-Versionsnummer bei der Lizenzprüfung
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: System (Lizenzprüfung beim Login)
|
||||
Vorbedingung: Ein Login mit der gemeinsamen Centron-Lizenz-GUID und einer Versionsnummer im Muster
|
||||
"9.3.x.y" (c-entron Delphi) wird geprüft.
|
||||
Fakt: `TryFixCentronDelphiVersionNumber` ersetzt bei `licenseGuid == ApplicationKind.Centron.LicenseGuid`
|
||||
und `Major==9 && Minor==3` die übergebene Versionsnummer durch die aktuelle Assembly-Version
|
||||
des c-entron.NET, bevor die Versionsprüfung erfolgt.
|
||||
Aussage: Das System soll für den Alt-Client "c-entron Delphi", der dieselbe Lizenz-GUID wie
|
||||
c-entron.NET verwendet, aber ein inkompatibles Versionsschema (9.3.x.y) besitzt, die
|
||||
Versionsprüfung so anpassen, dass ein gültiges Delphi-Login nicht fälschlich wegen
|
||||
scheinbar zu hoher Versionsnummer abgelehnt wird.
|
||||
Ergebnis: c-entron-Delphi-Logins werden anhand der c-entron.NET-Versionsnummer geprüft, nicht anhand
|
||||
ihrer eigenen (irreführenden) Versionsnummer.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Licensing/LicenseManager.cs :: TryFixCentronDelphiVersionNumber
|
||||
(Z.304-330), inkl. ausführlichem Erklärkommentar - Begründung: Code und Kommentar decken sich
|
||||
und beschreiben denselben, aktiv durchgesetzten Sonderfall.
|
||||
Prüfidee: Login mit Version "9.3.40.2" und Centron-Lizenz-GUID wird nicht wegen Versionsüberschreitung
|
||||
abgelehnt, obwohl 9.3 > die eigentliche c-entron.NET-Lizenzobergrenze (z. B. 2.x) wäre.
|
||||
Tracelinks: SyRS-5
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround (Altlast aus der Koexistenz von c-entron Delphi und c-entron.NET; für
|
||||
eine Web-/SaaS-Neuimplementierung ohne Delphi-Altclient voraussichtlich entfallend – vor
|
||||
Migration klären, ob Delphi-Client noch im Feld ist)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modul: Verkaufsbelege
|
||||
|
||||
```
|
||||
ID: SwRS-8
|
||||
Titel: Dreiwertiger Belegstatus (ReceiptState) als gemeinsamer Zustandsautomat
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: System (ReceiptBase-abgeleitete Entities)
|
||||
Vorbedingung: Ein Beleg wird angelegt oder verändert.
|
||||
Fakt: `enum ReceiptState { Active=1 ("offen"), Completed=2 ("abgeschlossen"), Canceled=3
|
||||
("storniert") }` ist die einzige State-Property auf `ReceiptBase` und wird von allen sieben
|
||||
Belegtypen gemeinsam genutzt.
|
||||
Aussage: Das System soll den Lebenszyklus jedes Belegs unabhängig vom konkreten Belegtyp über
|
||||
denselben dreiwertigen Zustand (offen/abgeschlossen/storniert) abbilden.
|
||||
Ergebnis: Jeder Beleg befindet sich zu jedem Zeitpunkt in genau einem der drei Zustände.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Interfaces/Sales/Receipts/ReceiptState.cs (komplette Datei) - Begründung:
|
||||
abschließende Enum-Definition, keine weiteren Werte im Typ vorhanden.
|
||||
Prüfidee: Kompilierzeitprüfung/Reflection: ReceiptState besitzt genau die drei genannten Werte.
|
||||
Tracelinks: StRS-5, SyRS-9
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
Anmerkung [HYPOTHESE] zu SwRS-8: Die Architekturdokumentation (receipts-backend-architecture.md) beschreibt
|
||||
umgangssprachlich vier Zustände ("Draft/Released/Processed/Cancelled"), die im tatsächlichen Code nicht als
|
||||
eigene ReceiptState-Werte existieren — siehe `Hypothesen.md` (H-1) für die offene Frage.
|
||||
|
||||
```
|
||||
ID: SwRS-9
|
||||
Titel: SpecificLogics-Dispatch für belegtypspezifische Rechteprüfung
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System (ReceiptBL)
|
||||
Vorbedingung: CanUserEditReceipt wird für einen konkreten receiptKind aufgerufen.
|
||||
Fakt: `CanUserEditReceipt` delegiert über `this._specificLogics.Execute(receiptKind, f => f.HasRightToEditReceipt(appUser))`
|
||||
an eine belegtyp-spezifische Implementierung (z. B. `OfferSpecificLogic`, `InvoiceSpecificLogic`),
|
||||
statt die Rechte-ID direkt hart zu kodieren.
|
||||
Aussage: Das System soll die Zuordnung zwischen Belegtyp und den dafür jeweils erforderlichen
|
||||
Benutzerrechten über eine austauschbare, belegtypspezifische Logikkomponente kapseln.
|
||||
Ergebnis: Jeder Belegtyp kann eigene Rechte-IDs für Bearbeitung/Filialbeschränkung hinterlegen, ohne
|
||||
die zentrale ReceiptBL ändern zu müssen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs :: CanUserEditReceipt (Z.10272-10295)
|
||||
- Begründung: Dispatch-Aufruf ist direkt sichtbar; Existenz von mind. OfferSpecificLogic.cs,
|
||||
InvoiceSpecificLogic.cs, OrderSpecificLogic.cs, ContractSpecificLogic.cs, PickupListSpecificLogic.cs,
|
||||
DeliveryListSpecificLogic.cs bestätigt per Grep (src/backend/Centron.BL/Sales/Receipts/**).
|
||||
Prüfidee: Für zwei verschiedene Belegtypen mit unterschiedlichen HasRightToEditReceipt-Implementierungen
|
||||
liefert CanUserEditReceipt bei gleichem Benutzer unterschiedliche Ergebnisse (Code-Review-Kriterium).
|
||||
Tracelinks: SyRS-7, StRS-7
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-10
|
||||
Titel: Ableitung des Belegstatus aus dem Zahlungsflag
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System (ReceiptBL)
|
||||
Vorbedingung: UpdateReceiptIsPaid wird mit einem isPaid-Wert ungleich null aufgerufen.
|
||||
Fakt: `var newState = isPaid.Value ? ReceiptState.Completed : ReceiptState.Active;` gefolgt von
|
||||
einer Zuweisung, sofern sich der Status ändert (Z.4944ff.).
|
||||
Aussage: Das System soll den Belegstatus direkt und ausschließlich aus dem übergebenen Zahlungsflag
|
||||
ableiten (bezahlt → abgeschlossen, nicht bezahlt → offen), ohne weitere Zwischenzustände.
|
||||
Ergebnis: Nach Aufruf entspricht der Belegstatus exakt der Abbildung isPaid=true→Completed,
|
||||
isPaid=false→Active.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs :: UpdateReceiptIsPaid (Z.4942-4946)
|
||||
- Begründung: unmittelbare, unbedingte Zuweisungslogik.
|
||||
Prüfidee: isPaid=true auf einem Active-Beleg: State wird Completed; isPaid=false auf einem
|
||||
Completed-Beleg: State wird Active.
|
||||
Tracelinks: StRS-8, SyRS-9
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-11
|
||||
Titel: Versionsinkrement als eigenständiger Zustand vor dem eigentlichen Speichern
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System (ReceiptBL)
|
||||
Vorbedingung: Ein Beleg mit vom Client angeforderter abweichender Version wird bearbeitet
|
||||
(`version != currentReceiptVersion.Version`).
|
||||
Fakt: `GetReceiptVersionForNewVersion` lädt die historische Version, aus der eine neue Version
|
||||
erzeugt wird; anschließend erfolgt eine Validierung (aktive Barcodes, referenzierende
|
||||
Folgebelege dürfen kein Hindernis sein), bevor `receipt.Version = currentReceiptVersion.Version + 1`
|
||||
gesetzt wird.
|
||||
Aussage: Das System soll das Erzeugen einer neuen Belegversion aus einer beliebigen historischen
|
||||
Version nur zulassen, wenn keine aktiven Barcodes oder nicht-stornierten Folgebelege dem
|
||||
entgegenstehen.
|
||||
Ergebnis: Eine neue Version wird nur erzeugt, wenn die Konsistenzbedingungen erfüllt sind; andernfalls
|
||||
wird die Operation mit Fehlermeldung abgelehnt.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs, Z.3099-3117 - Begründung: Validierungs-
|
||||
und Versionslogik liegen unmittelbar im selben Codeblock.
|
||||
Prüfidee: Versuch, aus einer historischen Version mit aktiven Barcodes eine neue Version zu erzeugen,
|
||||
wird abgelehnt (Fehlermeldung); ohne aktive Barcodes/blockierende Folgebelege gelingt es.
|
||||
Tracelinks: StRS-6, SyRS-10
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-12
|
||||
Titel: Duale Persistenzschicht: moderne Entity plus Legacy-Repository-Synchronisation
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: System (DAO-Schicht)
|
||||
Vorbedingung: Ein Beleg wird gespeichert.
|
||||
Fakt: Für jeden Belegtyp existiert eine `SaveReceipt*Repository`-Klasse (bestätigt u. a.
|
||||
`SaveReceiptOfferRepository`, `SaveReceiptOrderRepository`, `SaveReceiptSupplierOrderRepository`,
|
||||
`SaveReceiptSupplierInvoiceRepository`, `SaveReceiptPickupListRepository`), die von
|
||||
`SaveReceiptRepository<TReceiptInterface, TReceiptTable>` erbt und die abstrakten Methoden
|
||||
`SynchronizeReceiptData`/`SynchronizeReceiptItemData` implementiert, um Werte aus der
|
||||
modernen NHibernate-Entity explizit in die historische Legacy-Tabellenstruktur (z. B.
|
||||
`AngKopf`, `AufKopf`, `BestKopf2`, `KalkKopf`, `WareKopf`, `LiGutKopf`) zu übertragen.
|
||||
Aussage: Das System soll Belegdaten beim Speichern nicht ausschließlich über das moderne
|
||||
NHibernate-Mapping, sondern zusätzlich explizit in die historischen Legacy-Tabellen
|
||||
synchronisieren, um Abwärtskompatibilität mit bestehenden Auswertungen/Prozessen auf diesen
|
||||
Tabellen zu erhalten.
|
||||
Ergebnis: Nach dem Speichern sind sowohl die moderne Sicht (View) als auch die zugrunde liegende
|
||||
Legacy-Tabelle konsistent befüllt.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.DAO/Repositories/Sales/Receipts/SaveReceiptRepository.cs (abstrakte
|
||||
Basisklasse, Z.190,196) sowie mind. 7 konkrete Implementierungen (Grep-Treffer, u. a.
|
||||
Offers/SaveReceiptOfferRepository.cs, Order/SaveReceiptOrderRepository.cs) - Begründung:
|
||||
wiederkehrendes, in der DAO-Schicht real implementiertes Muster, kein Dokumentationsartefakt.
|
||||
- [KONTEXT] docs/reference/receipts/receipts-backend-architecture.md, Abschnitt "Critical Save Warning"
|
||||
- Begründung: bestätigt und erläutert die fachliche Notwendigkeit ("nicht der einzige
|
||||
Persistenzpfad"); explizite Warnung, dass neue Felder sonst nicht gespeichert werden.
|
||||
Prüfidee: Neues Feld wird nur der modernen Entity/Mapping hinzugefügt, nicht dem Repository: Wert wird
|
||||
beim Laden über die View sichtbar, geht aber beim erneuten Speichern verloren (Regressionstest-Idee).
|
||||
Tracelinks: StRS-6, SyRS-10
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Workaround (historisch gewachsene Doppelpersistenz; zentrales Migrationsrisiko für
|
||||
eine Web-/SaaS-Neuimplementierung: bei Neuentwicklung sollte KEINE äquivalente Doppelstruktur
|
||||
übernommen werden, sondern ein einheitliches Zielschema definiert werden – jedes bestehende
|
||||
Feld ist gegen beide Pfade zu prüfen, bevor es als vollständig verstanden gilt)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modul: Verträge & automatisierte Abrechnung
|
||||
|
||||
```
|
||||
ID: SwRS-13
|
||||
Titel: Bedingte LINQ-Filterausdrücke je Berechnungsart in GetActiveContracts
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System (AutomaticFacturaBL)
|
||||
Vorbedingung: GetActiveContracts wird mit einem SearchBillingContractsFilter aufgerufen.
|
||||
Fakt: Die Query kombiniert `f.State == 1`, Zeitraumprüfung mit `AutomatedProlongation`,
|
||||
bitweise Verknüpfung `filter.CalculationKind & f.CalculationKind`, Zahlungsdatenvergleich
|
||||
(`LastPaidDate`, `FirstPaidDate`) sowie Filial-, Kunden- und Vertragsart-Filter in einem
|
||||
einzigen LINQ-Ausdruck gegen `ReceiptContractHead`.
|
||||
Aussage: Das System soll die Selektionslogik für abrechnungsfähige Verträge als eine zusammengesetzte,
|
||||
datenbankseitig auswertbare Abfrage umsetzen, die Status, Zeitraum, Zahlungshistorie,
|
||||
Berechnungsart und organisatorische Filter (Filiale, Kunde, Vertragsart) gleichzeitig
|
||||
berücksichtigt.
|
||||
Ergebnis: Ein einziger Datenbankzugriff liefert die vollständige Kandidatenliste für den nachfolgenden
|
||||
mehrstufigen Ausschlussprozess (SyRS-12).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.Contracts.cs
|
||||
:: GetActiveContracts (Z.820-845) - Begründung: vollständiger, geschlossener LINQ-Ausdruck.
|
||||
Prüfidee: Vertrag mit LastPaidDate >= ContractEnd und CalculationKind=Auto wird NICHT selektiert
|
||||
(Bedingung `f.LastPaidDate < f.ContractEnd` nicht erfüllt).
|
||||
Tracelinks: SyRS-12, StRS-10
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SwRS-14
|
||||
Titel: Stapelweise (Batch) Nachfilterung großer Vertragsmengen über NamedQueries
|
||||
Ebene: SwRS
|
||||
Typ: nicht-funktional (Performance-Effizienz, ISO25010)
|
||||
Akteur: System (AutomaticFacturaBL)
|
||||
Vorbedingung: Die initiale Vertragsliste aus GetActiveContracts enthält potenziell sehr viele Einträge.
|
||||
Fakt: Nachfolgende Zusatzabfragen (`GetContractsWithSpecialArticle`, `GetNoEmptyContracts`,
|
||||
`GetContractsWithEmptyPos`, `GetNoBillingContracts`) werden nicht für die gesamte Liste auf
|
||||
einmal, sondern über `.Batch(2000)` in Blöcken von 2000 Vertrags-I3Ds ausgeführt.
|
||||
Aussage: Das System soll Nachfilterabfragen über große Vertragsmengen in Blöcken von maximal 2000
|
||||
IDs ausführen, um Grenzen von SQL-IN-Klauseln bzw. Parameteranzahl-Limits zu vermeiden und
|
||||
die Abfrageperformance zu sichern.
|
||||
Ergebnis: Auch bei sehr vielen abrechnungsfähigen Verträgen bleibt der Abrechnungslauf ohne
|
||||
SQL-Parameterlimit-Fehler funktionsfähig.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.Contracts.cs,
|
||||
Z.859-862, 888-892, 896-899, 908-912 (vier unabhängige .Batch(2000)-Aufrufe) - Begründung:
|
||||
wiederkehrendes, konsistent angewendetes Muster.
|
||||
Prüfidee: Abrechnungslauf mit > 2000 abrechnungsfähigen Verträgen schlägt nicht mit einem
|
||||
SQL-Parameterlimit-Fehler fehl (Lasttest-Idee).
|
||||
Tracelinks: SyRS-12
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modul: Mahnwesen
|
||||
|
||||
```
|
||||
ID: SwRS-15
|
||||
Titel: Offener-Betrag-Berechnung je Mahnstufe aus drei Rechnungsbeträgen
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: System (DunningBL)
|
||||
Vorbedingung: Statistik über Rechnungen je Mahnstufe wird angefordert.
|
||||
Fakt: `CalculateDunningStatistics` berechnet den offenen Betrag je Rechnung als
|
||||
`GrossPriceComplete - PayedGrossAmount - CreditVoucherGrossAmount` und summiert diesen Wert
|
||||
getrennt für die vier DunningLevel-Werte.
|
||||
Aussage: Das System soll den offenen Rechnungsbetrag als Bruttorechnungsbetrag abzüglich bereits
|
||||
gezahlter Beträge und abzüglich verrechneter Gutschriften berechnen.
|
||||
Ergebnis: Die je Mahnstufe ausgewiesene Summe entspricht dem tatsächlich noch ausstehenden Betrag.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/Invoices/Dunning/DunningBL.cs, Z.221,224,227,230
|
||||
- Begründung: identische Berechnungsformel an vier Stellen für je eine Mahnstufe wiederholt.
|
||||
Prüfidee: Rechnung mit GrossPriceComplete=1000, PayedGrossAmount=300, CreditVoucherGrossAmount=100:
|
||||
offener Betrag in der Statistik ist 600.
|
||||
Tracelinks: StRS-11, SyRS-14
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modul: Umsatzsteuer
|
||||
|
||||
```
|
||||
ID: SwRS-16
|
||||
Titel: Verkettete Steuersatz-Entität mit Fallback auf artikelspezifischen Standardsatz
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: System (TaxBL)
|
||||
Vorbedingung: Die übergebene taxRateI3D existiert nicht (mehr) in der Datenbank.
|
||||
Fakt: `GetTaxRateForReceiptItem` fällt bei `currentTaxRate is null` auf
|
||||
`GetDefaultTaxtRateByArticle(receiptItemArticleI3D)` zurück, bevor die Kettensuche beginnt.
|
||||
Aussage: Das System soll bei einem nicht mehr existierenden Steuersatz auf einen artikelspezifischen
|
||||
Standardsteuersatz zurückfallen, statt die Berechnung mit einem Fehler abzubrechen.
|
||||
Ergebnis: Auch bei einer ungültigen/gelöschten Steuersatzreferenz liefert die Methode einen
|
||||
verwendbaren Steuersatz zurück.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Warehousing/TaxBL.cs, Z.213-216 - Begründung: expliziter Null-Check
|
||||
mit Fallback-Aufruf im Code.
|
||||
Prüfidee: Aufruf mit einer nicht existierenden taxRateI3D liefert nicht null, sondern den
|
||||
artikelspezifischen Standardsatz (sofern für den Artikel einer hinterlegt ist).
|
||||
Tracelinks: StRS-12, SyRS-15
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modul: Kunden-/Lieferantenstammdaten
|
||||
|
||||
```
|
||||
ID: SwRS-17
|
||||
Titel: Konfigurierbare Kopplung von Buchhaltungsnummer und Kundennummer
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: System (AccountBL), Buchhaltung (Konfiguration)
|
||||
Vorbedingung: Die Anwendungseinstellung `AccountsBookKeepingNumberEqualsCustomerNumber` ist aktiviert.
|
||||
Fakt: Beim Anlegen/Import eines Kunden wird `customerData.BookKeepingNumber = customerData.Number.ToString()`
|
||||
gesetzt, sofern die genannte Einstellung aktiv ist und (im Importfall) noch keine
|
||||
Buchhaltungsnummer vorhanden ist.
|
||||
Aussage: Das System soll optional, gesteuert über eine Anwendungseinstellung, die Buchhaltungsnummer
|
||||
eines Kunden automatisch mit dessen Kundennummer gleichsetzen.
|
||||
Ergebnis: Bei aktivierter Einstellung stimmen Kundennummer und Buchhaltungsnummer neuer Kunden überein.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Accounts/AccountBL.cs, Z.147-175, 542-564 - Begründung: Einstellung
|
||||
wird zweimal (Neuanlage, Import) unabhängig ausgewertet und durchgesetzt.
|
||||
Prüfidee: Mit aktivierter Einstellung: neu angelegter Kunde mit Nummer 4711 erhält BookKeepingNumber
|
||||
"4711"; bei deaktivierter Einstellung bleibt BookKeepingNumber unabhängig davon editierbar.
|
||||
Tracelinks: StRS-13, SyRS-16
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modul: Zeiterfassungsabrechnung
|
||||
|
||||
```
|
||||
ID: SwRS-18
|
||||
Titel: Belegtypabhängige UI-Feldsperre mit erklärendem Hinweistext
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: WPF-Client (TimerBillingSettingsPageViewModel)
|
||||
Vorbedingung: UseBillingDate ist aktiviert und ReceiptKind (Invoice/DeliveryList) ist gesetzt.
|
||||
Fakt: `UpdateBillingDateIsEnabled()` wählt abhängig von `ReceiptKind` zwischen
|
||||
`CanChangeDateInInvoices` und `CanChangeDateInDeliveryLists` aus `CentronCache.Instance.ReceiptSettings`;
|
||||
ist das Recht nicht vorhanden, wird `ShowBillingDateNoteEnabledInfo=true` und ein
|
||||
belegtypspezifischer Hinweistext ("Datum der Rechnung"/"Datum des Lieferscheins") gesetzt.
|
||||
Aussage: Das System soll dem Benutzer bei fehlendem Recht nicht nur das Datumsfeld sperren, sondern
|
||||
auch einen belegtypspezifischen Hinweis anzeigen, welches Recht fehlt.
|
||||
Ergebnis: Bei fehlendem Recht ist das Feld gesperrt und ein Hinweistext mit dem exakten Rechtenamen
|
||||
wird angezeigt.
|
||||
Belege:
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Finances/TimerBilling/Pages/TimerBillingSettingsPageViewModel.cs
|
||||
:: UpdateBillingDateIsEnabled (Commit baa9e7bd9b, Zeilen gem. Diff Z.566-590) - Begründung:
|
||||
vollständige, kürzlich eingeführte und im Repository nachvollziehbare Implementierung.
|
||||
Prüfidee: ReceiptKind=InvoiceClass, CanChangeDateInInvoices=false: BillingDateIsEnabled=false,
|
||||
BillingDateNotEnabledInfo enthält "der Rechnung".
|
||||
Tracelinks: StRS-14, SyRS-17
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modul: Helpdesk/Ticketsystem
|
||||
|
||||
```
|
||||
ID: SwRS-19
|
||||
Titel: Erweiterung der Basis-Statusdaten um Verrechnungs- und Portaldarstellungsfelder
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: System (HelpdeskState-Entity)
|
||||
Vorbedingung: -
|
||||
Fakt: `HelpdeskState : HelpdeskStateBase` fügt den Basisfeldern (Name, Number, Description, State)
|
||||
die Felder `Icon` (byte[]), `IsDeactivated`, `IsInternalCompanyBillingActive`,
|
||||
`ServiceBoardWebColor`, `ServiceBoardWebIcon` hinzu.
|
||||
Aussage: Das System soll je Ticketstatus zusätzlich zur reinen Bezeichnung eine visuelle Darstellung
|
||||
für das Kundenportal sowie ein Verrechnungssteuerungsfeld vorhalten.
|
||||
Ergebnis: Jeder Ticketstatus kann unabhängig voneinander deaktiviert, mit Portal-Farbe/-Icon versehen
|
||||
und für die interne Verrechnung ein-/ausgeschlossen werden.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/CustomerArea/Support/HelpdeskState.cs (vollständige
|
||||
Datei, 8 Zeilen) - Begründung: abschließende Feldliste der Entity-Klasse.
|
||||
Prüfidee: Zwei HelpdeskState-Datensätze mit unterschiedlichem ServiceBoardWebColor erscheinen im
|
||||
Kundenportal mit der jeweils konfigurierten Farbe (UI-Abgleich).
|
||||
Tracelinks: StRS-15, SyRS-18
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modul: Betrieb & Bereitstellung
|
||||
|
||||
```
|
||||
ID: SwRS-20
|
||||
Titel: Explizite Dienstabhängigkeit und Neustartrichtlinie in der Compose-Topologie
|
||||
Ebene: SwRS
|
||||
Typ: nicht-funktional (Zuverlässigkeit, ISO25010)
|
||||
Akteur: System (Container-Orchestrierung)
|
||||
Vorbedingung: Ein Container (webservice oder nexus) beendet sich unerwartet.
|
||||
Fakt: `webservice` und `nexus` sind in compose.yaml mit `restart: on-failure` konfiguriert; `nexus`
|
||||
deklariert zusätzlich `depends_on: - webservice`, `webservice` entsprechend `depends_on: - db`.
|
||||
Aussage: Das System soll einzelne Dienste bei unerwartetem Absturz automatisch neu starten und die
|
||||
Startreihenfolge (Datenbank vor Webservice vor Portal) über deklarative Abhängigkeiten
|
||||
sicherstellen.
|
||||
Ergebnis: Ein abgestürzter Webservice- oder Nexus-Container wird automatisch neu gestartet; ein
|
||||
Neustart des Gesamtstacks respektiert die Abhängigkeitsreihenfolge.
|
||||
Belege:
|
||||
- [PRIMÄR] docker/compose/compose.yaml, Z.19-20, 27, 42-43, 50 - Begründung: konkrete, in der
|
||||
Konfigurationsdatei sichtbare Direktiven.
|
||||
Prüfidee: Manuelles Beenden des webservice-Containers: Compose startet ihn automatisch neu, ohne dass
|
||||
db oder nexus manuell neu gestartet werden müssen.
|
||||
Tracelinks: StRS-16, SyRS-19
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
+534
@@ -0,0 +1,534 @@
|
||||
# System Requirements Specification (SyRS)
|
||||
## c-entron ERP-Suite — Reverse Requirements Engineering (Baseline V1, Iteration 01)
|
||||
|
||||
Systemverhalten, Schnittstellen, Performance- und Sicherheitsanforderungen. Nicht-funktionale
|
||||
Anforderungen sind, wo zutreffend, mit dem entsprechenden ISO/IEC 25010 Qualitätsmerkmal im
|
||||
Feld `Typ` gekennzeichnet. Details zu Methodik, Abdeckung und Grenzen: siehe `Analysebericht.md`.
|
||||
|
||||
---
|
||||
|
||||
## Modul: Sicherheit & Berechtigungen
|
||||
|
||||
```
|
||||
ID: SyRS-1
|
||||
Titel: Serverseitige Rechteprüfung vor sicherheitsrelevanten Operationen
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System (BL-Schicht)
|
||||
Vorbedingung: Ein Client (WPF-UI oder Webservice-Aufrufer) fordert eine rechtebeschränkte Operation an.
|
||||
Fakt: `AppRightsBL.HasUserRight`/`CheckRightsFromUser` führen eine SQL-Abfrage gegen die Tabellen
|
||||
`Sichtrus`/`Sichmemb` aus und werden aus BL-Methoden heraus aufgerufen (z. B. AccountBL,
|
||||
vgl. docs/guides/development/check-userrights.md); das Ergebnis wird pro Aufruf serverseitig
|
||||
berechnet und für die Dauer der Session gecacht.
|
||||
Aussage: Das System soll vor Ausführung rechtebeschränkter Operationen die Berechtigung des
|
||||
anfragenden Benutzers serverseitig (nicht nur in der UI) prüfen.
|
||||
Ergebnis: Operationen ohne ausreichendes Recht werden mit einem Error-Result abgelehnt, unabhängig
|
||||
davon, ob der Client (WPF/Web) eine UI-Sperre umgeht.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs :: HasUserRight, HasUserRightWithDefaultMessage
|
||||
- Begründung: BL-seitige, vom UI-Layer unabhängige Prüfmethode mit Cache und SQL-Beleg.
|
||||
- [KONTEXT] docs/guides/development/check-userrights.md - Begründung: dokumentiert die verbindliche
|
||||
Verwendung in BL-Klassen als Entwicklungsstandard.
|
||||
Prüfidee: Direkter (simulierter) Aufruf einer BL-Methode ohne vorherige UI-Prüfung mit einem Benutzer
|
||||
ohne Recht liefert Result.Error, nicht Erfolg.
|
||||
Tracelinks: StRS-1, SwRS-1, SwRS-2
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-2
|
||||
Titel: Getrenntes Rechtesystem für Web-Konten
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System (Webservice), externer Web-Account (z. B. Kundenportal/Self-Care)
|
||||
Vorbedingung: Ein Web-Account meldet sich am Webservice an und fordert eine Operation an.
|
||||
Fakt: `AppRightsBL.HasWebAccountRight`/`GetAllWebRightsFromWebAccount` verwenden eine eigene
|
||||
Tabelle `WebAccountsRights`, getrennt von den internen Rechten (`Sichtrus`/`Sichmemb`) der
|
||||
Desktop-/Mitarbeiter-Benutzer.
|
||||
Aussage: Das System soll externe Web-Konten über ein von internen Mitarbeiterrechten unabhängiges
|
||||
Rechtemodell autorisieren, um Vermischung interner und externer Berechtigungen zu vermeiden.
|
||||
Ergebnis: Ein Web-Account kann ausschließlich über `WebAccountsRights` zugewiesene Rechte nutzen, nie
|
||||
über `Sichtrus`-Mitarbeiterrechte.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs :: HasWebAccountRight (Zeilen
|
||||
666-691) - Begründung: eigenständiger Codepfad mit eigener Tabelle, keine Vermischung im Code.
|
||||
Prüfidee: Web-Account mit Recht X, aber ohne entsprechendes internes Sichtrus-Recht, wird bei HasWebAccountRight(X)
|
||||
korrekt zugelassen; HasUserRight desselben Datensatzes (falls anwendbar) liefert unabhängiges Ergebnis.
|
||||
Tracelinks: StRS-1, SwRS-1
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-3
|
||||
Titel: Schutz der Administratoren-Gruppe vor Löschung und Rechteentzug
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Administrator
|
||||
Vorbedingung: Administrator versucht, die Gruppe "Administratoren" (I3D=6) zu löschen oder deren
|
||||
Rechte über eine nicht-freigegebene Teilmenge zu ändern.
|
||||
Fakt: `AppRightsBL.DeleteRightGroup` bricht bei `group.I3D == 6` bzw. Gruppenname
|
||||
"Administratoren" mit Fehlermeldung ab; `SaveAndAssignGroupToRight`/`RemoveAssignGroupToRight`
|
||||
prüfen für die Administratorgruppe zusätzlich `GetAssignableAdminRightI3Ds()` (hartcodierte
|
||||
Positivliste von ca. 38 Rechte-IDs), außerhalb derer keine Änderung zulässig ist.
|
||||
Aussage: Das System soll verhindern, dass die Administratoren-Gruppe gelöscht oder außerhalb einer
|
||||
fest definierten Positivliste in ihren Rechten verändert wird, um eine versehentliche
|
||||
Selbstaussperrung von Administratoren zu vermeiden.
|
||||
Ergebnis: Löschversuche der Administratorengruppe und nicht freigegebene Rechteänderungen werden
|
||||
abgelehnt (Result-Error bzw. Rückgabe `false`).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs :: DeleteRightGroup (Z.359-360),
|
||||
GetAssignableAdminRightI3Ds (Z.714-759), SaveAndAssignGroupToRight (Z.266-271) - Begründung:
|
||||
direkte, unumgehbare Prüfung im Schreibpfad.
|
||||
Prüfidee: Löschversuch der Gruppe I3D=6 liefert Result.Error "Die Adminstratoren Gruppe darf nicht
|
||||
gelöscht werden"; Zuweisen eines nicht gelisteten Rechts zur Admin-Gruppe liefert `false`.
|
||||
Tracelinks: StRS-2, SwRS-3
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-4
|
||||
Titel: Lückenlose Protokollierung rechterelevanter Änderungen
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (Zuverlässigkeit / Security-ISO25010)
|
||||
Akteur: System
|
||||
Vorbedingung: Eine rechte-/gruppenbezogene Schreiboperation wird ausgeführt.
|
||||
Fakt: Jede öffentliche Schreibmethode in `AppRightsBL` (Add/Remove Right-to-Group, Add/Remove
|
||||
User-to-Group, Create/Delete/Copy Group) ruft am Ende eine `WriteXxxLog`-Methode auf, die
|
||||
unbedingt (kein optionaler Zweig) einen `AppRightLog`-Eintrag mit `CreatedByI3D`,
|
||||
`CreatedDate`, `CreatedVersion` und `Kind` schreibt.
|
||||
Aussage: Das System soll jede rechterelevante Änderung so protokollieren, dass Zeitpunkt, ausführender
|
||||
Benutzer, Softwareversion und Art der Änderung nachvollziehbar sind.
|
||||
Ergebnis: Für jede Änderungsoperation existiert genau ein zugehöriger, nicht überspringbarer
|
||||
AppRightLog-Eintrag.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs :: WriteBaseLog (Z.762-781)
|
||||
- Begründung: Guard-Klauseln erzwingen vollständige Angaben, Aufruf ist nicht bedingt.
|
||||
Prüfidee: Für jede der acht Schreibmethoden existiert im Code ein zugehöriger, unbedingter WriteXxxLog-Aufruf
|
||||
(Code-Review-Kriterium); funktional: AppRightLog-Tabelle wächst um genau einen Eintrag pro Aufruf.
|
||||
Tracelinks: StRS-3, SwRS-3
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
## Modul: Lizenzierung
|
||||
|
||||
```
|
||||
ID: SyRS-5
|
||||
Titel: Versions- und Mengenbeschränkte Lizenzprüfung beim Anwendungs-Login
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System (Webservice-Login), Applikation (c-entron.NET, Service-Board, Outlook-Add-In, ...)
|
||||
Vorbedingung: Eine Applikation (`ApplicationKind`) versucht sich mit einer Client-Version am Webservice anzumelden.
|
||||
Fakt: `LicenseManager.CheckLicense(ApplicationKind app, string applicationVersion, LoggedInUser user)`
|
||||
prüft je Login die Lizenzversion (`CheckLicenseVersion`) und, sofern ein `user` übergeben wird,
|
||||
die aktuell genutzte Lizenzanzahl gegen `GetLicenseCount` mittels `TicketBL.GetTicketCount`;
|
||||
bei Überschreitung wird der Login mit Fehlercode `LicenseMaximumReached` abgelehnt.
|
||||
Aussage: Das System soll bei jeder Anwendungsanmeldung serverseitig prüfen, ob eine gültige Lizenz für
|
||||
die anfragende Applikation und Version vorliegt und ob die maximale Anzahl gleichzeitig
|
||||
genutzter Lizenzen nicht überschritten wird.
|
||||
Ergebnis: Logins ohne gültige Lizenz oder bei ausgeschöpftem Lizenzkontingent werden mit einer
|
||||
definierten Fehlermeldung abgelehnt; gültige Logins werden zugelassen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Licensing/LicenseManager.cs :: CheckLicense (Z.258-302)
|
||||
- Begründung: durchgesetzte Prüfung inkl. Zähl- und Versionsvergleich im Login-Pfad, mit
|
||||
spezifischem Fehlercode `DefaultMessageCodes.LicenseMaximumReached`.
|
||||
Prüfidee: Login mit abgelaufener Lizenzversion liefert Result.Error; Login, der die maximale
|
||||
Lizenzanzahl überschreitet, liefert Result.Error mit Code LicenseMaximumReached.
|
||||
Tracelinks: StRS-4, SwRS-6
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-6
|
||||
Titel: Datenbank-Update wird bei fehlender Lizenz blockiert
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System (Webservice-Start)
|
||||
Vorbedingung: Webservice startet und lädt Lizenzdatei.
|
||||
Fakt: `LicenseManager.LoadLicenses()` ruft `CheckLicense(ApplicationKind.Centron, ...).ThrowIfError()`
|
||||
VOR dem Datenbank-Strukturupdate auf; der zugehörige Kommentar im Code beschreibt explizit,
|
||||
dass dies verhindern soll, dass ein Kunde ohne gültige Lizenz die Datenbank auf eine neuere
|
||||
Struktur aktualisiert und dadurch mit einer älteren Version nicht mehr arbeiten kann.
|
||||
Aussage: Das System soll ein Datenbankschema-Update beim Start verweigern, wenn keine gültige
|
||||
Lizenz für die aktuelle Applikationsversion vorliegt.
|
||||
Ergebnis: Fehlt die Lizenz, bricht der Webservice-Start mit Exception ab; die Datenbank bleibt
|
||||
unverändert (kein Strukturupdate).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Licensing/LicenseManager.cs :: LoadLicenses (Z.219-236)
|
||||
- Begründung: Reihenfolge im Code (Lizenzprüfung mit ThrowIfError() vor Update-Logik) setzt
|
||||
die Regel technisch durch.
|
||||
- [KONTEXT] Inline-Kommentar Z.226-233 derselben Datei - Begründung: erläutert die fachliche Absicht
|
||||
("If he doesn't have a license, the database should stay the same").
|
||||
Prüfidee: Webservice-Start ohne gültige Centron-Lizenz: Startvorgang bricht ab, bevor Migrationsskripte
|
||||
ausgeführt werden (beobachtbar z. B. an unverändertem Schema-Versionsstand).
|
||||
Tracelinks: StRS-4, SwRS-6
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modul: Verkaufsbelege
|
||||
|
||||
```
|
||||
ID: SyRS-7
|
||||
Titel: Recht- und filialbasierte Bearbeitungsprüfung vor jeder Belegänderung
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System (ReceiptBL)
|
||||
Vorbedingung: Eine Änderung an einem Beleg (Speichern, Zahlungsstatus, Erinnerungsdatum, Projektnummer,
|
||||
Stundensatz, Benutzerstatus) wird angefordert.
|
||||
Fakt: `CanUserEditReceipt` wird in praktisch jeder öffentlichen Änderungsmethode von `ReceiptBL`
|
||||
aufgerufen (belegt an mind. 6 unabhängigen Stellen) und kombiniert eine belegtypspezifische
|
||||
Rechteprüfung (`HasRightToEditReceipt`) mit einer optionalen Filialprüfung
|
||||
(`HasRightToEditReceiptOnlyOwnBranch` + `BranchBL.IsBranchEqual`).
|
||||
Aussage: Das System soll vor jeder Änderung an einem Verkaufsbeleg serverseitig prüfen, ob der
|
||||
anfragende Benutzer sowohl das allgemeine Bearbeitungsrecht für diesen Belegtyp als auch,
|
||||
falls eingeschränkt, das Recht zur Bearbeitung von Belegen der jeweiligen Filiale besitzt.
|
||||
Ergebnis: Änderungsversuche ohne ausreichendes Recht bzw. an Belegen einer fremden Filiale werden mit
|
||||
spezifischer Fehlermeldung (Fehlercode RightCheckFailed) abgelehnt.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs :: CanUserEditReceipt (Z.10272-10295),
|
||||
aufgerufen u. a. in Z.3081, 3625, 4804, 4839, 4880, 4921, 5114, 5268 - Begründung: zentrale,
|
||||
wiederholt genutzte Prüfmethode, kein Einzelfall.
|
||||
Prüfidee: Benutzer ohne Bearbeitungsrecht für Rechnungen versucht, eine Rechnung zu speichern; Result
|
||||
enthält Fehlercode RightCheckFailed und keine Datenbankänderung erfolgt.
|
||||
Tracelinks: StRS-5, StRS-7, SwRS-9
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-8
|
||||
Titel: Optimistische Sperre verhindert verlorene Aktualisierungen
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (Zuverlässigkeit, ISO25010)
|
||||
Akteur: System (ReceiptBL)
|
||||
Vorbedingung: Ein Client sendet eine Belegänderung mit einem zuvor geladenen `ConcurrencyControlGuid`.
|
||||
Fakt: Vor dem Schreiben wird `receipt.ConcurrencyControlGuid != concurrencyControlGuid` geprüft;
|
||||
bei Ungleichheit liefert die Methode `Result.AsError(..., DefaultMessageCodes.ChangedByOtherInstance)`
|
||||
und die Änderung wird nicht übernommen.
|
||||
Aussage: Das System soll Änderungen an einem Beleg zurückweisen, wenn der Beleg seit dem Laden durch
|
||||
den Client bereits durch eine andere Instanz geändert wurde (Lost-Update-Vermeidung).
|
||||
Ergebnis: Der Client erhält den Fehlercode `ChangedByOtherInstance` und muss den Beleg neu laden,
|
||||
bevor eine erneute Änderung möglich ist.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs, Z.4808-4809, 4843-4844, 4884-4885, 4939-4940,
|
||||
5272-5273 - Begründung: identisches Prüfmuster an mindestens 5 unabhängigen Update-Pfaden.
|
||||
Prüfidee: Zwei parallele Ladevorgänge desselben Belegs, sequentielle Speicherversuche: der zweite
|
||||
Speicherversuch mit veraltetem Guid schlägt mit ChangedByOtherInstance fehl.
|
||||
Tracelinks: StRS-7, SwRS-9
|
||||
Konsolidierung: Kandidat: SyRS-9 (verwandter Zustands-Schutzmechanismus)
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-9
|
||||
Titel: Stornierte Belege sind gegen Zahlungsstatusänderung geschützt
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System (ReceiptBL), Debitorenbuchhaltung
|
||||
Vorbedingung: Ein Beleg befindet sich im Status `Canceled` (storniert).
|
||||
Fakt: `UpdateReceiptIsPaid` prüft `receipt.State == ReceiptState.Canceled` und liefert in diesem
|
||||
Fall unbedingt einen Error zurück ("... wurde storniert und kann daher nicht als bezahlt
|
||||
oder nicht bezahlt eingestellt werden."), bevor der Zahlungsstatus geändert wird.
|
||||
Aussage: Das System soll verhindern, dass der Zahlungsstatus eines bereits stornierten Belegs
|
||||
geändert wird.
|
||||
Ergebnis: Versuche, den Zahlungsstatus eines stornierten Belegs zu setzen, werden abgelehnt.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs :: UpdateReceiptIsPaid (Z.4936-4937)
|
||||
- Begründung: unbedingte Prüfung vor jeder Statusänderung, keine Ausnahme im Code sichtbar.
|
||||
Prüfidee: UpdateReceiptIsPaid auf einem Beleg mit State=Canceled liefert Result.Error unabhängig vom
|
||||
übergebenen isPaid-Wert.
|
||||
Tracelinks: StRS-5, SwRS-8, SwRS-10
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-10
|
||||
Titel: Vollständige Versionierung bei jeder Belegspeicherung
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (Zuverlässigkeit, ISO25010)
|
||||
Akteur: System (ReceiptBL)
|
||||
Vorbedingung: Ein bestehender Beleg wird gespeichert und ist keine reine Neuanlage.
|
||||
Fakt: Im Speicherpfad wird nach erfolgreicher Rechte-/Concurrency-Prüfung unbedingt
|
||||
`this._specificLogics.Execute(receipt, f => f.SaveReceiptVersion(receipt, previousReceiptVersion))`
|
||||
aufgerufen (Z.3629), unabhängig vom konkreten Belegtyp (SpecificLogics-Pattern).
|
||||
Aussage: Das System soll bei jeder Speicherung eines geänderten Belegs unabhängig vom Belegtyp eine
|
||||
Versionshistorie fortschreiben.
|
||||
Ergebnis: Zu jedem gespeicherten Änderungsstand eines Belegs existiert ein Versionsdatensatz.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs, Z.3625-3633 - Begründung: Aufruf liegt im
|
||||
gemeinsamen, belegtyp-unabhängigen Speicherpfad, nicht in einer optional übersprungenen Verzweigung.
|
||||
Prüfidee: Für jeden der sieben Belegtypen: Speichern einer Änderung erzeugt einen neuen Versionsdatensatz
|
||||
(stichprobenartig für mind. 2 Belegtypen zu verifizieren, siehe Analysebericht/Lücken).
|
||||
Tracelinks: StRS-6, SwRS-11, SwRS-12
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-11
|
||||
Titel: Ausnahmerecht für Zahlungseingang unabhängig vom allgemeinen Bearbeitungsrecht
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Mitarbeiter Debitorenbuchhaltung/Zahlungseingang
|
||||
Vorbedingung: Benutzer besitzt nicht das allgemeine Bearbeitungsrecht für den Belegtyp, wohl aber das
|
||||
Recht `INCOMING_PAYMENT_TRANSACTIONS`.
|
||||
Fakt: `UpdateReceiptIsPaid` behandelt ein fehlgeschlagenes `CanUserEditReceipt` mit Fehlercode
|
||||
`RightCheckFailed` als nicht endgültig abgelehnt, sofern der Benutzer zusätzlich
|
||||
`UserRightsConst.Controlling.Finances.INCOMING_PAYMENT_TRANSACTIONS` besitzt; in diesem Fall
|
||||
wird die Operation dennoch fortgesetzt.
|
||||
Aussage: Das System soll Mitarbeitern mit dem speziellen Recht für Zahlungseingänge erlauben, den
|
||||
Zahlungsstatus eines Belegs zu setzen, auch wenn sie kein allgemeines Bearbeitungsrecht für
|
||||
diesen Belegtyp besitzen.
|
||||
Ergebnis: Ein Benutzer mit ausschließlich dem Zahlungseingangsrecht kann `UpdateReceiptIsPaid`
|
||||
erfolgreich ausführen, jedoch keine sonstigen Belegänderungen vornehmen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs :: UpdateReceiptIsPaid (Z.4921-4934)
|
||||
- Begründung: expliziter Sonderfall-Codepfad mit eigenem Rechtekonstantenbezug.
|
||||
Prüfidee: Benutzer mit ausschließlich INCOMING_PAYMENT_TRANSACTIONS (kein allgemeines Bearbeitungsrecht):
|
||||
UpdateReceiptIsPaid liefert Erfolg; SaveReceipt (allgemein) liefert weiterhin RightCheckFailed.
|
||||
Tracelinks: StRS-8
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modul: Verträge & automatisierte Abrechnung
|
||||
|
||||
```
|
||||
ID: SyRS-12
|
||||
Titel: Mehrstufige Selektion abrechnungsfähiger Verträge
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System (AutomaticFacturaBL)
|
||||
Vorbedingung: Ein automatisierter oder manuell ausgelöster Abrechnungslauf wird gestartet.
|
||||
Fakt: `GetActiveContracts` filtert zunächst auf `State == 1` (aktiv), gültigen Zeitraum
|
||||
(ContractBegin/ContractEnd, ggf. AutomatedProlongation) und Berechnungsart; `SearchBillingContracts`
|
||||
reduziert die Trefferliste danach in mehreren Schritten weiter: `InvoicePeriodCalculate`
|
||||
(Abrechnungszeitraum), Ausschluss dynamischer Bedarfsverträge ohne Sonderartikel-Stichtag,
|
||||
Ausschluss von Verträgen ohne abrechenbare Positionen ("leere RE vermeiden"), Kennzeichnung
|
||||
von Verträgen mit Stückzahl- bzw. Barcode-/Seriennummer-Besonderheiten.
|
||||
Aussage: Das System soll vor der eigentlichen Rechnungserzeugung sicherstellen, dass nur Verträge mit
|
||||
gültigem Status, fälligem Abrechnungszeitraum und tatsächlich abrechenbarem Inhalt in den
|
||||
Abrechnungslauf gelangen, um Leerrechnungen und fehlerhafte automatische Buchungen zu vermeiden.
|
||||
Ergebnis: Die an `StoreInvoiceToContract` übergebene Vertragsliste enthält ausschließlich geprüfte,
|
||||
abrechnungsfähige Verträge.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.Contracts.cs
|
||||
:: SearchBillingContracts (Z.847-919, insb. Kommentar "leere RE vermeiden" Z.886) - Begründung:
|
||||
mehrstufige, im Code nachvollziehbare Ausschlusslogik, kein einzelner Filter.
|
||||
Prüfidee: Aktiver Vertrag ohne Vertragspositionen wird trotz fälligem Intervall NICHT in die finale
|
||||
Abrechnungsliste aufgenommen (WithEmptyPos-Fall).
|
||||
Tracelinks: StRS-9, SwRS-13, SwRS-14
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
```
|
||||
ID: SyRS-13
|
||||
Titel: Berücksichtigung von Sonderartikel-Stichtagen bei dynamischen Bedarfsverträgen
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System (AutomaticFacturaBL)
|
||||
Vorbedingung: Vertrag hat CalculationKind=Need und CalcNeedKind=Dynamic.
|
||||
Fakt: Solche Verträge werden aus der Abrechnungsliste entfernt (`contracts.RemoveAll(...)`), außer
|
||||
es liegt ein Sonderartikel mit einem Stichtag vor dem Ende des Abrechnungszeitraums
|
||||
(`WithSpecialArticle`) vor, ermittelt über die NamedQuery `GetContractsWithSpecialArticle`.
|
||||
Aussage: Das System soll dynamische Bedarfsverträge nur dann automatisch abrechnen, wenn ein
|
||||
konkreter, terminierter Abrechnungsanlass (Sonderartikel mit Stichtag) vorliegt.
|
||||
Ergebnis: Dynamische Bedarfsverträge ohne aktuellen Abrechnungsanlass werden nicht automatisch berechnet.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaBL.Contracts.cs,
|
||||
Z.859-884 - Begründung: konkrete Query- und Ausschlusslogik im Code.
|
||||
Prüfidee: Dynamischer Bedarfsvertrag ohne Sonderartikel-Stichtag im Abrechnungszeitraum wird aus der
|
||||
Trefferliste entfernt; mit passendem Stichtag bleibt er enthalten.
|
||||
Tracelinks: StRS-9, StRS-10
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modul: Mahnwesen
|
||||
|
||||
```
|
||||
ID: SyRS-14
|
||||
Titel: Zeitraumbezogene Mahnsperre je Kunde/Objekt
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System (DunningBL)
|
||||
Vorbedingung: Für einen Kunden oder ein konkretes Objekt (Rechnung) ist eine Mahnsperre mit Start-/Enddatum
|
||||
gesetzt (`dunningStop`, `dunningStopBegin`, `dunningStopEnd`).
|
||||
Fakt: `UpdateDunningStopAndInfo(objectI3D, objectKind, dunningStop, dunningInfo, dunningStopBegin,
|
||||
dunningStopEnd, loggedInUser)` persistiert die Sperre inkl. Freitext-Info und optionalem
|
||||
Zeitraum je referenziertem Objekt (`CentronObjectKindNumeric`).
|
||||
Aussage: Das System soll erlauben, das Mahnwesen für einen Kunden oder ein einzelnes Objekt zeitlich
|
||||
begrenzt oder unbegrenzt auszusetzen, mit dokumentiertem Grund.
|
||||
Ergebnis: Während des gesperrten Zeitraums wird das betroffene Objekt im Mahnlauf nicht weiter eskaliert.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/Invoices/Dunning/DunningBL.cs :: UpdateDunningStopAndInfo
|
||||
(Z.392-ff.) - Begründung: dedizierte Methode mit allen notwendigen Parametern zur Durchsetzung.
|
||||
Prüfidee: Setzen einer Mahnsperre mit dunningStopEnd in der Zukunft: das Objekt wird im nächsten
|
||||
GetDunningCustomers-Aufruf als gesperrt markiert bzw. ausgeschlossen (je nach Filterparameter).
|
||||
Tracelinks: StRS-11, SwRS-15
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modul: Umsatzsteuer
|
||||
|
||||
```
|
||||
ID: SyRS-15
|
||||
Titel: Rückwärtssuche in der Steuersatzhistorie bis zum passenden Gültigkeitszeitraum
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System (TaxBL)
|
||||
Vorbedingung: Eine Steuersatzkette (`ValueAddedTax.NextTaxRate`) mit mindestens einem historischen und
|
||||
einem aktuellen Satz existiert.
|
||||
Fakt: `GetTaxRateForReceiptItem` läuft zunächst bis zum jüngsten Kettenglied (`NextTaxRate == null`)
|
||||
und geht anschließend rückwärts, bis ein Satz gefunden wird, dessen Gültigkeitszeitraum
|
||||
(`ExpirationDate` des Vorgängers) das übergebene `receiptDate` abdeckt.
|
||||
Aussage: Das System soll bei mehreren historisch aufeinanderfolgenden Steuersätzen denjenigen
|
||||
auswählen, dessen Gültigkeitszeitraum das Belegdatum tatsächlich einschließt.
|
||||
Ergebnis: Für ein gegebenes receiptDate wird genau ein zeitlich passender Steuersatz zurückgegeben.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Warehousing/TaxBL.cs, Z.212-229 - Begründung: die Schleifenlogik mit
|
||||
ExpirationDate-Prüfung ist direkt im Code sichtbar.
|
||||
Prüfidee: Kette mit Steuersatz A (gültig bis 30.06.), Nachfolger B (ab 01.07.): receiptDate=15.06.
|
||||
liefert A, receiptDate=15.07. liefert B.
|
||||
Tracelinks: StRS-12, SwRS-16
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modul: Kunden-/Lieferantenstammdaten
|
||||
|
||||
```
|
||||
ID: SyRS-16
|
||||
Titel: Granulare Rechteprüfung je CRUD-Operation auf Geschäftspartnerdaten
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System (AccountBL)
|
||||
Vorbedingung: Ein Account (Kunde/Lieferant) wird angelegt, bearbeitet oder gelöscht.
|
||||
Fakt: `AccountBL` prüft vor dem jeweiligen Vorgang gezielt das passende Recht
|
||||
(CREATE_CUSTOMER/EDIT_CUSTOMER/DELETE_CUSTOMER bzw. RIGHT_LIEFERANTANLEGEN/-AENDERN) über
|
||||
`AppRightsBL.CheckRightsFromUser` und bricht bei fehlendem Recht mit `RightCheckFailed` ab.
|
||||
Aussage: Das System soll für Anlage, Bearbeitung und Löschung von Geschäftspartner-Stammdaten jeweils
|
||||
spezifische, einzeln prüfbare Rechte durchsetzen.
|
||||
Ergebnis: Ein Benutzer mit z. B. nur EDIT_CUSTOMER kann bestehende Kunden bearbeiten, aber keine neuen
|
||||
anlegen oder löschen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Accounts/AccountBL.cs, Z.1302-1348 - Begründung: getrennte
|
||||
If-Abfragen je Operation mit jeweils eigenem Rechtebezug.
|
||||
- [KONTEXT] docs/guides/development/check-userrights.md (identisches Codebeispiel) - Begründung:
|
||||
bestätigt, dass dieses Muster als Referenzimplementierung dokumentiert ist.
|
||||
Prüfidee: Benutzer mit ausschließlich EDIT_CUSTOMER: Bearbeiten eines bestehenden Kunden gelingt,
|
||||
Anlegen eines neuen Kunden liefert RightCheckFailed.
|
||||
Tracelinks: StRS-13, SwRS-17
|
||||
Konsolidierung: Kandidat: SyRS-1 (gleiches zugrundeliegendes Rechteprüfungsmuster CheckRightsFromUser,
|
||||
unterschiedliche Fachdomäne)
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modul: Zeiterfassungsabrechnung
|
||||
|
||||
```
|
||||
ID: SyRS-17
|
||||
Titel: Getrennte Rechte für Datumsänderung bei Rechnung und Lieferschein
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: System (ReceiptWebServiceBL)
|
||||
Vorbedingung: ReceiptSettings werden für einen angemeldeten Benutzer ermittelt.
|
||||
Fakt: `CanChangeDateInDeliveryLists` prüft `UserRightsConst...DeliveryList.CAN_CHANGE_DATE`,
|
||||
`CanChangeDateInInvoices` prüft unabhängig davon `UserRightsConst...Invoice.CAN_CHANGE_DATE` –
|
||||
zwei eigenständige Rechte-IDs für zwei Belegtypen.
|
||||
Aussage: Das System soll die Berechtigung zur Datumsänderung für Rechnungen und für Lieferscheine
|
||||
unabhängig voneinander vergebbar machen.
|
||||
Ergebnis: Ein Benutzer kann z. B. das Datum von Lieferscheinen ändern dürfen, ohne automatisch auch
|
||||
das Recht für Rechnungsdaten zu besitzen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/WebServices/Sales/Receipts/ReceiptWebServiceBL.cs, Z.996,998
|
||||
- Begründung: zwei getrennte Rechtekonstanten werden unabhängig ausgewertet.
|
||||
Prüfidee: Benutzer mit DeliveryList.CAN_CHANGE_DATE, aber ohne Invoice.CAN_CHANGE_DATE:
|
||||
CanChangeDateInDeliveryLists=true, CanChangeDateInInvoices=false.
|
||||
Tracelinks: StRS-14, SwRS-18
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modul: Helpdesk/Ticketsystem
|
||||
|
||||
```
|
||||
ID: SyRS-18
|
||||
Titel: Ticketstatus als Stammdaten statt Programmkonstante
|
||||
Ebene: SyRS
|
||||
Typ: Daten
|
||||
Akteur: System (HelpdeskBL/HelpdeskState)
|
||||
Vorbedingung: Ein Ticket wird einem Status zugeordnet.
|
||||
Fakt: `HelpdeskState` wird über NHibernate gemappt (`HelpdeskStateMaps.cs`) und in der Datenbank
|
||||
verwaltet, im Gegensatz zum festen `ReceiptState`-Enum bei Verkaufsbelegen (vgl. SwRS-8).
|
||||
Aussage: Das System soll den Ticketstatus als datenbankgestützte, administrierbare Stammdatenliste
|
||||
führen, nicht als im Quellcode fest kodierte Werteliste.
|
||||
Ergebnis: Neue Ticketstatus können ohne Software-Update angelegt werden.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.DAO/Mappings/CustomerArea/Support/HelpdeskStateMaps.cs (Existenz einer
|
||||
NHibernate-Mapping-Klasse) - Begründung: Mapping-Klassen existieren ausschließlich für
|
||||
datenbankgestützte Entitäten, nicht für Enums.
|
||||
Prüfidee: Ein neuer HelpdeskState-Datensatz ist über die Rechteverwaltungs-/Admin-UI anlegbar und
|
||||
sofort als Auswahloption bei der Ticketbearbeitung verfügbar, ohne Deployment.
|
||||
Tracelinks: StRS-15, SwRS-19
|
||||
Konsolidierung: Kandidat: SwRS-8 (gegensätzliches Muster: Belegstatus fest vs. Ticketstatus konfigurierbar –
|
||||
als Konsolidierungshinweis für Zielarchitektur relevant, ob ein einheitliches Statuskonzept
|
||||
sinnvoll ist)
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Modul: Betrieb & Bereitstellung
|
||||
|
||||
```
|
||||
ID: SyRS-19
|
||||
Titel: Linux-Fähigkeit des Webservice-Hosts
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (Übertragbarkeit, ISO25010)
|
||||
Akteur: System (Webservice-Host)
|
||||
Vorbedingung: Webservice wird in einem Linux-Container gestartet.
|
||||
Fakt: Das Docker-Image `centron.azurecr.io/centron_webservice` startet den Prozess
|
||||
`/app/Centron.Host.Console` unter Linux (kein Windows-Container-Basisimage in compose.yaml
|
||||
erkennbar); zusätzlich referenziert `LicenseManager.cs` einen bedingten Codepfad
|
||||
`#elif WINDOWS` mit sonst plattformneutralem Verhalten.
|
||||
Aussage: Das System soll den Webservice-Host plattformunabhängig (insbesondere unter Linux)
|
||||
betreibbar machen, nicht ausschließlich unter Windows.
|
||||
Ergebnis: Der Webservice startet und arbeitet in einem Linux-Container ohne Windows-spezifische
|
||||
Laufzeitumgebung.
|
||||
Belege:
|
||||
- [PRIMÄR] docker/compose/compose.yaml, Z.13-16 - Begründung: konkrete Startkonfiguration ohne
|
||||
Windows-Abhängigkeit.
|
||||
- [KONTEXT] docs/guides/services/web-service-on-linux.md (referenziert, Inhalt in dieser Iteration
|
||||
nicht gelesen) - Begründung: Dateiname deutet auf dediziertes Vorgehen für Linux-Betrieb hin;
|
||||
[HYPOTHESE]: genauer Funktionsumfang unter Linux (z. B. ob alle Features identisch zu Windows
|
||||
verfügbar sind) wurde nicht verifiziert, siehe Hypothesen.md (H-3).
|
||||
Prüfidee: Webservice-Container basierend auf einem Linux-Basisimage startet erfolgreich und beantwortet
|
||||
einen Health-Check-Request.
|
||||
Tracelinks: StRS-16, SwRS-20
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
```
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
# Traceability-Tabelle
|
||||
|
||||
StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg
|
||||
---|---|---|---
|
||||
StRS-1 | SyRS-1 | SwRS-1, SwRS-2 | AppRightsBL.cs (HasUserRight, CheckRightsFromUser)
|
||||
StRS-1 | SyRS-2 | SwRS-1 | AppRightsBL.cs (HasWebAccountRight)
|
||||
StRS-2 | SyRS-1 | SwRS-3 | AppRightsBL.cs (SaveRightGroup, DeleteRightGroup — Branch-Check)
|
||||
StRS-2 | SyRS-3 | SwRS-3 | AppRightsBL.cs (GetAssignableAdminRightI3Ds, DeleteRightGroup)
|
||||
StRS-3 | SyRS-4 | SwRS-3 | AppRightsBL.cs (WriteBaseLog + WriteXxxLog-Methoden)
|
||||
StRS-4 | SyRS-5 | SwRS-6, SwRS-7 | LicenseManager.cs (CheckLicense, TryFixCentronDelphiVersionNumber)
|
||||
StRS-4 | SyRS-6 | SwRS-6 | LicenseManager.cs (LoadLicenses)
|
||||
— | — | SwRS-4 | docs/guides/development/add-a-new-right.md, UserRightsConst.cs (Sichrech-Schema; kein direkter StRS/SyRS-Bezug, Basisinfrastruktur)
|
||||
— | — | SwRS-5 | Centron.Common/DeveloperSecurity.cs (Entwicklungssicherheitsmaßnahme, kein Fachprozess)
|
||||
StRS-5 | SyRS-7 | SwRS-9 | ReceiptBL.cs (ReceiptBase, CanUserEditReceipt, SpecificLogics-Dispatch)
|
||||
StRS-6 | SyRS-10 | SwRS-11, SwRS-12 | ReceiptBL.cs (Versionierung), SaveReceiptRepository.cs (Legacy-Sync)
|
||||
StRS-7 | SyRS-8 | SwRS-9 | ReceiptBL.cs (ConcurrencyControlGuid-Prüfung, TryLockReceipt)
|
||||
StRS-8 | SyRS-9, SyRS-11 | SwRS-8, SwRS-10 | ReceiptBL.cs (UpdateReceiptIsPaid, ReceiptState)
|
||||
StRS-9 | SyRS-12 | SwRS-13, SwRS-14 | AutomaticFacturaBL.Contracts.cs (SearchBillingContracts, GetActiveContracts)
|
||||
StRS-10 | SyRS-12, SyRS-13 | SwRS-13 | AutomaticFacturaBL.Contracts.cs (ContractCalculationKind-Zweige)
|
||||
StRS-11 | SyRS-14 | SwRS-15 | DunningBL.cs (GetDunningCustomers, CalculateDunningStatistics, UpdateDunningStopAndInfo)
|
||||
StRS-12 | SyRS-15 | SwRS-16 | TaxBL.cs (GetTaxRateForReceiptItem, GetTaxRateChain)
|
||||
StRS-13 | SyRS-16 | SwRS-17 | AccountBL.cs (Rechteprüfung CRUD, BookKeepingNumber-Kopplung)
|
||||
StRS-14 | SyRS-17 | SwRS-18 | ReceiptWebServiceBL.cs (CAN_CHANGE_DATE), TimerBillingSettingsPageViewModel.cs
|
||||
StRS-15 | SyRS-18 | SwRS-19 | HelpdeskState.cs, HelpdeskStateBase.cs, HelpdeskStateMaps.cs
|
||||
StRS-16 | SyRS-19 | SwRS-20 | docker/compose/compose.yaml
|
||||
|
||||
+223
@@ -0,0 +1,223 @@
|
||||
# Messprotokoll – V1 Baseline (Prompt-only) – Iteration 01, Lauf 4 (Wiederholungsmessung)
|
||||
|
||||
> Vierter Lauf des Prompts `01_Prompt.md`. **Konfiguration identisch zu Lauf 3** – gleiches
|
||||
> Modell, gleiche Flags, gleicher Codebasis-Snapshot. Zweck: Bestimmung der **Laufvarianz**
|
||||
> bei unveränderter Versuchsbedingung, um die Verbesserungen aus dem Shell-Zugriff von
|
||||
> Zufallsstreuung trennen zu können.
|
||||
|
||||
## Lauf
|
||||
- **Prompt-Datei:** `Versuche/Versuch_01/01_Prompt.md`
|
||||
- **SHA-256 (Prompt):** `1B0DB06B8E0A5B92A5EFBDBEC5A0C554351FC928A16AEF34AAD9EAA0893C02FF`
|
||||
(identisch zu allen bisherigen Läufen)
|
||||
- **Startzeit:** 2026-08-25T15:05:17.4372276+02:00
|
||||
- **Endzeit:** 2026-08-25T15:28:51.3123231+02:00
|
||||
- **Dauer gesamt:** 00:23:34 (Wanduhr) bzw. 00:22:44 (`duration_ms`) — API: 00:22:09 (`duration_api_ms`)
|
||||
- **Anders als in allen Vorläufen liegt die API-Dauer hier *unter* der Wanduhrzeit**, weil
|
||||
dieser Lauf ohne Subagenten arbeitete und damit keine nebenläufigen Anfragen summierte.
|
||||
- **Root-Verzeichnis:** `c:\DEV\MasterArbeit\QuellCode\CentronERP`
|
||||
- **Codebasis-Commit:** `79c1142f489a32ba6a4a4cb043fd7f8550a9f257` (dirty: nein)
|
||||
- **Snapshot-Zustand:** bereinigt von KI-Konfigurationen: **ja** (strenge Prüfung: 0 Treffer);
|
||||
Remote entkoppelt: **ja**
|
||||
- **Prompt-Repo-Commit:** `0ec86aed8cb8781054c86cbe0dd9f5eb0f7e5f05`
|
||||
|
||||
## Werkzeugkonfiguration
|
||||
- **Laufverzeichnis-ID:** `v2.1.0-acab`
|
||||
- **Ablage:** `claude-sonnet-5/builtin/high/`
|
||||
- **Parallele Läufe:** nein
|
||||
- **Skill-Version:** `2.1.0` (wie 2.0.1, zusätzlich verpflichtende Modellabfrage vor dem Lauf)
|
||||
- **Claude-Code-Version:** 2.1.245
|
||||
- **CLI-Pfad:** `C:\Users\ChristophSchwoerer\.vscode\extensions\anthropic.claude-code-2.1.245-win32-x64\resources\native-binary\claude.exe`
|
||||
- **Effort:** `high` — **nicht zur Laufzeit gesetzt**, sondern aus der Sitzung geerbt und
|
||||
nachtraeglich aus dem Session-Transkript rekonstruiert (247 Nachrichten, durchgaengig `high`).
|
||||
`RawResult.json` enthaelt kein `effort`-Feld. Ab Skill-Version 3.4.0 wird der Wert per
|
||||
`--effort` explizit gesetzt.
|
||||
- **Modell:** `claude-sonnet-5` (explizit gesetzt, vom Versuchsleiter vor dem Lauf gewählt);
|
||||
zusätzlich `claude-haiku-4-5-20251001` für interne Hilfsaufrufe (4.176 Input-/20 Output-Tokens)
|
||||
- **Permission-Mode:** `acceptEdits`
|
||||
- **Toolfreigabe:**
|
||||
- `--allowedTools "Bash" "PowerShell"`
|
||||
- `--disallowedTools` mit 33 Einträgen (22 × `Bash(...)`, 11 × `PowerShell(...)`) für
|
||||
schreibende Kommandos, Git-Mutationen und Build-Werkzeuge – identisch zu Lauf 3
|
||||
- **Isolationsmechanismus:** eingefrorener Codebasis-Snapshot ohne KI-Konfigurationen,
|
||||
zusätzlich `--safe-mode` und `--strict-mcp-config`
|
||||
- **MCP-Server / Agentendateien:** keine – aus dem Snapshot entfernt, zusätzlich `--safe-mode`
|
||||
- **Subagenten:** **0** (`spawned: 0`, `by_type: {}`)
|
||||
- **Fast-Mode:** aus
|
||||
|
||||
## Verbrauch
|
||||
|
||||
### Hauptagent (`usage`)
|
||||
| Messgröße | Wert |
|
||||
|---|---|
|
||||
| Input-Tokens | 280 |
|
||||
| Output-Tokens | 121.969 (davon 25.826 Thinking-Tokens) |
|
||||
| Cache-Write-Tokens | 256.300 |
|
||||
| Cache-Read-Tokens | 27.179.499 |
|
||||
| Agent-Turns | 147 |
|
||||
|
||||
### Gesamtlauf inkl. Subagenten (`modelUsage`, abrechnungsrelevant)
|
||||
| Messgröße | `claude-sonnet-5` | `claude-haiku-4-5-20251001` | Summe |
|
||||
|---|---:|---:|---:|
|
||||
| Input-Tokens | 280 | 4.176 | 4.456 |
|
||||
| Output-Tokens | 121.969 | 20 | 121.989 |
|
||||
| Cache-Write-Tokens | 256.300 | 0 | 256.300 |
|
||||
| Cache-Read-Tokens | 27.179.499 | 0 | 27.179.499 |
|
||||
| Tokens gesamt | 27.558.048 | 4.196 | **27.562.244** |
|
||||
|
||||
**Tokens gesamt: 27.562.244** (Summe aus Input, Output, Cache-Write und Cache-Read ueber alle Modelle; `total_cost_usd` steht weiterhin in `RawResult.json`)
|
||||
|
||||
Da keine Subagenten liefen, sind Haupt- und Gesamtwerte für `claude-sonnet-5` hier identisch –
|
||||
in allen Vorläufen klafften sie deutlich auseinander.
|
||||
|
||||
## Ergebnis
|
||||
- **Status:** erfolgreich (`is_error: false`, `subtype: "success"`, `stop_reason: "end_turn"`,
|
||||
`terminal_reason: "completed"`, Exit-Code 0, `Stderr.log` leer)
|
||||
- **Session-ID:** `f3744c04-c4e2-4d9b-8fd6-d2e5e8ba2c15`
|
||||
- **Permission-Denials:** **0**
|
||||
- **Erzeugte Dateien:** alle 7 geforderten Artefakte in `Ergebnisse\`
|
||||
|
||||
| Datei | Größe | Inhalt |
|
||||
|---|---:|---|
|
||||
| `StRS.md` | 29.243 B | 16 Anforderungen |
|
||||
| `SyRS.md` | 31.070 B | 19 Anforderungen |
|
||||
| `SwRS.md` | 33.879 B | 20 Anforderungen |
|
||||
| `Traceability.md` | 2.085 B | 21 Datenzeilen |
|
||||
| `Hypothesen.md` | 2.156 B | 4 Einträge (H-1…H-4) |
|
||||
| `Glossar.md` | 2.980 B | Domänenbegriffe |
|
||||
| `Analysebericht.md` | 19.813 B | Modulinventar mit Tiefenklassifikation, Konsistenzcheck, Selbstbewertung |
|
||||
|
||||
Summe: **55 Anforderungen** über drei Ebenen.
|
||||
- **Root unverändert:** ja. Vorher/Nachher-Vergleich identisch (beide leer), HEAD `79c1142`.
|
||||
- **Abschlusstext des Agenten:** siehe `RawResult.json` (`result`)
|
||||
|
||||
## Gefundene Anforderungen
|
||||
|
||||
Maschinell aus `Ergebnisse\StRS.md`, `SyRS.md` und `SwRS.md` ausgewertet (Blockformat des Prompts). Erzeugt von `analyse-anforderungen.py`.
|
||||
|
||||
### Verteilung über die Ebenen
|
||||
|
||||
| Ebene | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| StRS | 16 | 29,1 % |
|
||||
| SyRS | 19 | 34,5 % |
|
||||
| SwRS | 20 | 36,4 % |
|
||||
| **Gesamt** | **55** | 100 % |
|
||||
|
||||
### Anforderungstypen
|
||||
|
||||
| Typ | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| funktional | 23 | 41,8 % |
|
||||
| Sicherheit | 13 | 23,6 % |
|
||||
| Daten | 10 | 18,2 % |
|
||||
| nicht-funktional (Zuverlässigkeit, ISO25010) | 4 | 7,3 % |
|
||||
| nicht-funktional (Übertragbarkeit, ISO25010) | 2 | 3,6 % |
|
||||
| nicht-funktional (Performance-Effizienz, ISO25010) | 2 | 3,6 % |
|
||||
| nicht-funktional (Zuverlässigkeit / Security-ISO25010) | 1 | 1,8 % |
|
||||
|
||||
### Belegqualität
|
||||
|
||||
| Messgröße | Wert |
|
||||
|---|---:|
|
||||
| Belege gesamt | 67 |
|
||||
| davon `PRIMÄR` | 54 (80,6 %) |
|
||||
| davon `SEKUNDÄR` | 5 (7,5 %) |
|
||||
| davon `KONTEXT` | 8 (11,9 %) |
|
||||
| Belege je Anforderung (Median) | 1 |
|
||||
| Anforderungen mit mindestens einem `PRIMÄR`-Beleg | 54 (98,2 %) |
|
||||
|
||||
### Status
|
||||
|
||||
| Kategorie | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| belegt | 51 | 92,7 % |
|
||||
| als `HYPOTHESE` gekennzeichnet | 4 | 7,3 % |
|
||||
| als Workaround vermerkt | 4 | 7,3 % |
|
||||
| Konsolidierungskandidaten | 6 | 10,9 % |
|
||||
| mit ISO-25010-Qualitätsmerkmal | 0 | 0,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** (37 risikorelevante Anforderungen, alle gedeckt) |
|
||||
| **Verifizierbarkeit** – jede Anforderung mit Prüfidee oder Akzeptanzkriterium | **erfüllt** |
|
||||
| **Traceability** – Verknüpfung zwischen den Ebenen | 55 von 55 mit Tracelinks (100,0 %) |
|
||||
|
||||
## Vergleich aller Läufe (identischer Prompt)
|
||||
|
||||
| Messgröße | Lauf 1 (ohne Shell) | Lauf 2 (Abbruch) | Lauf 3 (mit Shell) | **Lauf 4 (mit Shell)** |
|
||||
|---|---:|---:|---:|---:|
|
||||
| Status | erfolgreich | API-Fehler | erfolgreich | erfolgreich |
|
||||
| Modell | claude-sonnet-5 | claude-sonnet-5 | claude-sonnet-5 | claude-sonnet-5 |
|
||||
| Permission-Denials | 36 | 0 | 0 | **0** |
|
||||
| Dauer (Wanduhr) | 31:31 | 31:24 | 23:40 | **23:34** |
|
||||
| Dauer (API) | 47:05 | 49:57 | 43:25 | **22:09** |
|
||||
| Agent-Turns | 43 | 8 | 69 | **147** |
|
||||
| Subagenten | 8 × Explore | 6 × general-purpose | 7 × Explore | **0** |
|
||||
| Anforderungen gesamt | 96 | 89 (unvollst.) | 106 | **55** |
|
||||
| — StRS / SyRS / SwRS | 28 / 28 / 40 | 45 / 44 / – | 30 / 38 / 38 | 16 / 19 / 20 |
|
||||
| Traceability-Zeilen | 44 | – | 56 | 21 |
|
||||
| Hypothesen | 12 | – | 9 | 4 |
|
||||
| Output-Tokens (gesamt) | 249.040 | 226.613 | 229.997 | **121.989** |
|
||||
| Cache-Read-Tokens | 11.959.137 | 15.618.130 | 10.542.089 | **27.179.499** |
|
||||
| Tokens gesamt | 13.052.010 | 16.655.125 | 11.516.200 | **27.562.244** |
|
||||
|
||||
## Anmerkungen/Auffälligkeiten
|
||||
|
||||
1. **Zentrales Ergebnis dieser Wiederholungsmessung: Die Laufvarianz ist sehr groß.** Bei
|
||||
*identischer* Konfiguration und *identischem* Prompt lieferte Lauf 4 **55 Anforderungen
|
||||
gegenüber 106 in Lauf 3** – knapp die Hälfte. Auch Traceability (21 statt 56 Zeilen),
|
||||
Hypothesen (4 statt 9) und Output-Tokens (121.989 statt 229.997) halbierten sich nahezu,
|
||||
während die Kosten **stiegen** (7,69 statt 11.516.200 Tokens).
|
||||
|
||||
**Konsequenz für die Auswertung:** Der Vergleich Lauf 1 gegen Lauf 3 (96 gegenüber 106
|
||||
Anforderungen) liegt vollständig innerhalb dieser Streuung. Die Anforderungsanzahl taugt
|
||||
damit **nicht** als Wirkungsmaß für die Werkzeugkonfiguration. Belastbar bleibt allein die
|
||||
Denial-Zahl (36 gegenüber 0), die eine direkte Eigenschaft der Konfiguration ist. Für
|
||||
inhaltliche Aussagen sind mehrere Läufe je Bedingung und ein qualitatives Maß nötig.
|
||||
|
||||
2. **Ursache der Streuung: der Agent wählte eine völlig andere Strategie.** Lauf 4 startete
|
||||
**keinen einzigen Subagenten** (Lauf 1: 8, Lauf 2: 6, Lauf 3: 7) und arbeitete stattdessen
|
||||
in 147 eigenen Turns – mehr als doppelt so viele wie Lauf 3. Der gesamte Kontext lief dabei
|
||||
durch den Hauptagenten, sichtbar an 27,18 Mio. Cache-Read-Tokens (2,6-fach gegenüber Lauf 3).
|
||||
Das erklärt die höheren Kosten bei geringerem Output: Der Hauptagent las viel wiederholt,
|
||||
statt Leseleistung an Subagenten mit eigenem Kontext auszulagern.
|
||||
|
||||
3. **Erstmals liegt die API-Dauer unter der Wanduhrzeit** (22:09 gegenüber 23:34). Das bestätigt
|
||||
die Deutung aus den Vorprotokollen: Die Überschreitung in Lauf 1–3 entstand ausschließlich
|
||||
durch nebenläufige Subagenten. Ohne sie summiert sich nichts mehr auf.
|
||||
|
||||
4. **Der Subagenten-Einsatz ist die dominierende Störgröße der Versuchsanordnung.** Er variierte
|
||||
über vier Läufe bei identischem Prompt zwischen 0 und 8 Subagenten und zwischen zwei Typen
|
||||
(`Explore`, `general-purpose`). Er bestimmt Laufzeit, Kosten, Token-Verteilung und
|
||||
Ergebnisumfang stärker als die untersuchte Werkzeugkonfiguration. Für die Arbeit sollte
|
||||
entweder je Bedingung über mehrere Läufe gemittelt oder der Subagenten-Einsatz im Prompt
|
||||
bzw. per Flag festgeschrieben werden.
|
||||
|
||||
5. **Geringere Abdeckung, aber ehrlich dokumentiert.** Der Agent analysierte nach eigener Angabe
|
||||
nur 10 geschäftskritische Module mit Quellcodebeleg und legt unanalysierte Bereiche (Einkauf,
|
||||
Produktion, Projektverwaltung, kompletter WPF-Client, Nexus-Portal, externe API-Integrationen,
|
||||
EDI) im `Analysebericht.md` offen. Der Bericht ist mit 19,8 KB der umfangreichste aller Läufe
|
||||
und enthält ein Modulinventar mit Tiefenklassifikation (TIEF/MITTEL/FLACH/NICHT ANALYSIERT).
|
||||
Weniger Anforderungen gehen hier also mit mehr Transparenz über die Lücken einher.
|
||||
|
||||
6. **Abweichende Dateistruktur bei Traceability und Hypothesen.** `Traceability.md` verwendet
|
||||
eine Markdown-Tabelle ohne führendes `|`, `Hypothesen.md` eine Tabelle statt Überschriften
|
||||
je Hypothese. Beides ist prompt-konform, erschwert aber die automatisierte Auswertung über
|
||||
Läufe hinweg. Für die Arbeit wäre ein festes Ausgabeformat im Prompt sinnvoll.
|
||||
|
||||
7. **Zählabweichung bei Hypothesen** (wie in allen Läufen): `Hypothesen.md` führt 4 Einträge,
|
||||
in den Anforderungsdateien stehen 6 Inline-Markierungen `[HYPOTHESE]`.
|
||||
|
||||
8. **Skill-Verbesserungen aus diesem Lauf** (bereits umgesetzt):
|
||||
- Das Modell wird ab sofort **vor jedem Lauf beim User erfragt**; es gibt keinen Default mehr.
|
||||
Kurzformen (`opus`, `sonnet`) sind untersagt, da sie sich über die Zeit verschieben.
|
||||
- Die Snapshot-Prüfung meldete zunächst 3 Treffer, weil ein verkürzter Regex zusammen mit dem
|
||||
case-insensitiven `Select-String` auf echte Produktdateien ansprach
|
||||
(`ClaudeCodeChatModelClient.cs`, `GoogleGeminiChatModelClient.cs` – Teil des
|
||||
KI-Assistenz-Features der ERP-Suite). Der strenge, verankerte Regex liefert korrekt 0.
|
||||
Im Skill ist das nun als Warnung samt Beispielpfaden dokumentiert.
|
||||
|
||||
9. **Manuelle Eingriffe während des Laufs:** keine.
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"is_error":false,"duration_api_ms":1328822,"num_turns":147,"stop_reason":"end_turn","session_id":"f3744c04-c4e2-4d9b-8fd6-d2e5e8ba2c15","total_cost_usd":7.685625800000001,"usage":{"input_tokens":280,"cache_creation_input_tokens":256300,"cache_read_input_tokens":27179499,"output_tokens":121969,"output_tokens_details":{"thinking_tokens":25826},"server_tool_use":{"web_search_requests":0,"web_fetch_requests":0},"service_tier":"standard","cache_creation":{"ephemeral_1h_input_tokens":256300,"ephemeral_5m_input_tokens":0},"inference_geo":"not_available","iterations":[{"input_tokens":2,"output_tokens":832,"cache_read_input_tokens":294066,"cache_creation_input_tokens":676,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":676},"type":"message"}],"speed":"standard"},"modelUsage":{"claude-haiku-4-5-20251001":{"inputTokens":4176,"outputTokens":20,"cacheReadInputTokens":0,"cacheCreationInputTokens":0,"webSearchRequests":0,"costUSD":0.004276,"contextWindow":200000,"maxOutputTokens":32000,"canonicalModel":"claude-haiku-4-5","provider":"firstParty"},"claude-sonnet-5":{"inputTokens":280,"outputTokens":121969,"cacheReadInputTokens":27179499,"cacheCreationInputTokens":256300,"webSearchRequests":0,"costUSD":7.681349800000001,"contextWindow":1000000,"maxOutputTokens":64000,"canonicalModel":"claude-sonnet-5","provider":"firstParty"}},"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":"Der Lauf ist abgeschlossen. Zusammenfassung:\n\n**Ergebnis** (in `c:\\DEV\\MasterArbeit\\Versuche\\Versuch_01\\01_Lauf_2026-08-25_1505\\Ergebnisse\\`):\n- **55 Anforderungen** (StRS-1..16, SyRS-1..19, SwRS-1..20) über 10 fachliche Module: Rechteverwaltung, Lizenzierung, Verkaufsbelege-Kernarchitektur, Verträge/automatisierte Abrechnung, Mahnwesen, Umsatzsteuer, Kunden-/Lieferantenstammdaten, Zeiterfassungsabrechnung, Helpdesk-Statusverwaltung, Betrieb/Docker-Bereitstellung.\n- Jede Anforderung mit Fakt/Aussage-Trennung, klassifizierten Belegen (PRIMÄR/SEKUNDÄR/KONTEXT), Prüfidee und Tracelinks; sicherheits-/abrechnungs-/berechtigungsrelevante Aussagen tragen durchweg mindestens einen PRIMÄR-Beleg aus echtem Quellcode (z. B. `AppRightsBL.cs`, `LicenseManager.cs`, `ReceiptBL.cs`, `AutomaticFacturaBL.Contracts.cs`, `TaxBL.cs`).\n- 4 offene Hypothesen (H-1 bis H-4) dokumentiert, Konsistenzcheck ohne Duplikate/fehlende Belege/kaputte Tracelinks, vollständiges Moduleninventar mit ehrlicher Tiefenklassifikation (TIEF/MITTEL/FLACH/NICHT ANALYSIERT) im `Analysebericht.md`.\n\n**Wichtigste Einschränkung**: Angesichts der Codebasis-Größe (>11.000 Quelldateien) wurden nur 10 geschäftskritische Module tatsächlich mit Quellcode belegt; große Bereiche (Einkauf, Produktion, Projektverwaltung, kompletter WPF-Client, Nexus-Portal, externe API-Integrationen, EDI) blieben unanalysiert – das ist in Abschnitt 3.4 und 4 des Analyseberichts offengelegt, nicht verschwiegen.","ttft_ms":11081,"ttft_stream_ms":1148,"time_to_request_ms":36,"type":"result","duration_ms":1363916,"uuid":"43ba2f31-1596-4239-9d67-7896c1740965","queued_turn_count":0}
|
||||
+894
@@ -0,0 +1,894 @@
|
||||
[
|
||||
{
|
||||
"id": "StRS-1",
|
||||
"ebene": "StRS",
|
||||
"titel": "Rollen-/gruppenbasierte Rechteverwaltung",
|
||||
"typ": "Sicherheit",
|
||||
"belege": [
|
||||
"PRIMÄR",
|
||||
"KONTEXT"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "SyRS-1, SyRS-4, SwRS-1, SwRS-2",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Einem Benutzer wird ein Recht ausschließlich über Gruppenmitgliedschaft zugewiesen; Entfernen",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "StRS-2",
|
||||
"ebene": "StRS",
|
||||
"titel": "Filialbezogene Einschränkung von Verwaltungsrechten",
|
||||
"typ": "Sicherheit",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "SyRS-1, SwRS-3",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Benutzer mit MANAGE_RIGHTS_ONLY_OWN_BRANCH versucht Gruppe einer fremden Filiale zu löschen;",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "StRS-3",
|
||||
"ebene": "StRS",
|
||||
"titel": "Nachvollziehbarkeit von Rechteänderungen",
|
||||
"typ": "Sicherheit",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "SyRS-4, SwRS-3",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Nach AddRightToRightGroup existiert ein neuer AppRightLog-Eintrag mit Kind=AddRightToGroup.",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "StRS-4",
|
||||
"ebene": "StRS",
|
||||
"titel": "Feature- und Applikationslizenzierung pro Kunde",
|
||||
"typ": "funktional",
|
||||
"belege": [
|
||||
"SEKUNDÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": true,
|
||||
"workaround": false,
|
||||
"tracelinks": "SyRS-2, SwRS-6",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Kunde ohne Lizenz für Modul X: LicenseManager.HasLicense(X) liefert false, UI blendet Modul X aus.",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "StRS-5",
|
||||
"ebene": "StRS",
|
||||
"titel": "Einheitlicher Belegprozess über den gesamten Auftrag-zu-Zahlung-Zyklus",
|
||||
"typ": "funktional",
|
||||
"belege": [
|
||||
"PRIMÄR",
|
||||
"SEKUNDÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "SyRS-7, SyRS-8, SwRS-8",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Für jeden der sieben Belegtypen existiert eine Entity-Klasse, die von ReceiptBase erbt und",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "StRS-6",
|
||||
"ebene": "StRS",
|
||||
"titel": "Nachvollziehbare, unveränderliche Belegversionshistorie",
|
||||
"typ": "funktional",
|
||||
"belege": [
|
||||
"PRIMÄR",
|
||||
"SEKUNDÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "SyRS-10, SwRS-11, SwRS-12",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Beleg wird zweimal gespeichert (Version 1 → 2); GetReceiptVersionByI3D(..., version:1) liefert",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "StRS-7",
|
||||
"ebene": "StRS",
|
||||
"titel": "Schutz vor gleichzeitiger, kollidierender Bearbeitung eines Belegs",
|
||||
"typ": "nicht-funktional (Zuverlässigkeit, ISO25010)",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "SyRS-8, SwRS-9",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Benutzer A lädt Beleg (Guid=X), Benutzer B speichert denselben Beleg zuerst (Guid ändert",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "StRS-8",
|
||||
"ebene": "StRS",
|
||||
"titel": "Verwaltung des Zahlungsstatus eines Belegs durch die Debitorenbuchhaltung",
|
||||
"typ": "funktional",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "SyRS-9, SyRS-11, SwRS-8, SwRS-10",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Setzen von isPaid=true auf einem aktiven Beleg ändert dessen State auf Completed; erneutes",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "StRS-9",
|
||||
"ebene": "StRS",
|
||||
"titel": "Automatisierte, wiederkehrende Vertragsabrechnung",
|
||||
"typ": "funktional",
|
||||
"belege": [
|
||||
"PRIMÄR",
|
||||
"SEKUNDÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "SyRS-12, SyRS-13, SwRS-13, SwRS-14",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Vertrag mit CalculationKind=Auto, State=aktiv, fälligem Intervall und mind. einer abrechenbaren",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "StRS-10",
|
||||
"ebene": "StRS",
|
||||
"titel": "Unterschiedliche Abrechnungssteuerung je Vertrag (automatisch / nach Bedarf / manuell)",
|
||||
"typ": "funktional",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "SyRS-12, SwRS-13",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Zwei sonst identische Verträge mit CalculationKind=Auto bzw. =Need: nur der Auto-Vertrag wird",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "StRS-11",
|
||||
"ebene": "StRS",
|
||||
"titel": "Mehrstufiges Mahnwesen für überfällige Rechnungen",
|
||||
"typ": "funktional",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "SyRS-14, SwRS-15",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Rechnung mit DunningLevel=Level1 und Restbetrag > 0 erscheint in",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "StRS-12",
|
||||
"ebene": "StRS",
|
||||
"titel": "Zeitlich korrekte Umsatzsteuerermittlung für Belegpositionen",
|
||||
"typ": "funktional",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "SyRS-15, SwRS-16",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Belegposition mit Belegdatum vor einer historischen Steuersatzänderung liefert den alten",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "StRS-13",
|
||||
"ebene": "StRS",
|
||||
"titel": "Vereinheitlichte Geschäftspartner-Stammdaten (Kunde und/oder Lieferant in einer Entität)",
|
||||
"typ": "funktional",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "SyRS-16, SwRS-17",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Ein Account-Datensatz mit gesetzter CustomerNumber UND SupplierNumber lässt sich anlegen und",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "StRS-14",
|
||||
"ebene": "StRS",
|
||||
"titel": "Rechtebasierte Freigabe zum manuellen Überschreiben des Abrechnungsdatums",
|
||||
"typ": "funktional",
|
||||
"belege": [
|
||||
"PRIMÄR",
|
||||
"SEKUNDÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": true,
|
||||
"workaround": false,
|
||||
"tracelinks": "SyRS-17, SwRS-18",
|
||||
"konsolidierung": "Kandidat: StRS-1 (gleiches zugrundeliegendes Rechtesystem, hier auf ein einzelnes Feld",
|
||||
"pruefidee": "Benutzer ohne CAN_CHANGE_DATE-Recht öffnet Timer-Billing-Einstellungen: Datumsfeld ist",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "StRS-15",
|
||||
"ebene": "StRS",
|
||||
"titel": "Konfigurierbare Ticketstatus-Verwaltung mit Verrechnungssteuerung je Status",
|
||||
"typ": "funktional",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "SyRS-18, SwRS-19",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Anlegen eines neuen HelpdeskState-Datensatzes mit IsInternalCompanyBillingActive=false; Tickets",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "StRS-16",
|
||||
"ebene": "StRS",
|
||||
"titel": "Containerisierte, mehrteilige Serverbereitstellung",
|
||||
"typ": "nicht-funktional (Übertragbarkeit, ISO25010)",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "SyRS-19, SwRS-20",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "`docker compose up` im Verzeichnis docker/compose startet alle vier Dienste; der Webservice",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SyRS-1",
|
||||
"ebene": "SyRS",
|
||||
"titel": "Serverseitige Rechteprüfung vor sicherheitsrelevanten Operationen",
|
||||
"typ": "Sicherheit",
|
||||
"belege": [
|
||||
"PRIMÄR",
|
||||
"KONTEXT"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-1, SwRS-1, SwRS-2",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Direkter (simulierter) Aufruf einer BL-Methode ohne vorherige UI-Prüfung mit einem Benutzer",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SyRS-2",
|
||||
"ebene": "SyRS",
|
||||
"titel": "Getrenntes Rechtesystem für Web-Konten",
|
||||
"typ": "Sicherheit",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-1, SwRS-1",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Web-Account mit Recht X, aber ohne entsprechendes internes Sichtrus-Recht, wird bei HasWebAccountRight(X)",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SyRS-3",
|
||||
"ebene": "SyRS",
|
||||
"titel": "Schutz der Administratoren-Gruppe vor Löschung und Rechteentzug",
|
||||
"typ": "Sicherheit",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-2, SwRS-3",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Löschversuch der Gruppe I3D=6 liefert Result.Error \"Die Adminstratoren Gruppe darf nicht",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SyRS-4",
|
||||
"ebene": "SyRS",
|
||||
"titel": "Lückenlose Protokollierung rechterelevanter Änderungen",
|
||||
"typ": "nicht-funktional (Zuverlässigkeit / Security-ISO25010)",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-3, SwRS-3",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Für jede der acht Schreibmethoden existiert im Code ein zugehöriger, unbedingter WriteXxxLog-Aufruf",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SyRS-5",
|
||||
"ebene": "SyRS",
|
||||
"titel": "Versions- und Mengenbeschränkte Lizenzprüfung beim Anwendungs-Login",
|
||||
"typ": "Sicherheit",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-4, SwRS-6",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Login mit abgelaufener Lizenzversion liefert Result.Error; Login, der die maximale",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SyRS-6",
|
||||
"ebene": "SyRS",
|
||||
"titel": "Datenbank-Update wird bei fehlender Lizenz blockiert",
|
||||
"typ": "Sicherheit",
|
||||
"belege": [
|
||||
"PRIMÄR",
|
||||
"KONTEXT"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-4, SwRS-6",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Webservice-Start ohne gültige Centron-Lizenz: Startvorgang bricht ab, bevor Migrationsskripte",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SyRS-7",
|
||||
"ebene": "SyRS",
|
||||
"titel": "Recht- und filialbasierte Bearbeitungsprüfung vor jeder Belegänderung",
|
||||
"typ": "Sicherheit",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-5, StRS-7, SwRS-9",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Benutzer ohne Bearbeitungsrecht für Rechnungen versucht, eine Rechnung zu speichern; Result",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SyRS-8",
|
||||
"ebene": "SyRS",
|
||||
"titel": "Optimistische Sperre verhindert verlorene Aktualisierungen",
|
||||
"typ": "nicht-funktional (Zuverlässigkeit, ISO25010)",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-7, SwRS-9",
|
||||
"konsolidierung": "Kandidat: SyRS-9 (verwandter Zustands-Schutzmechanismus)",
|
||||
"pruefidee": "Zwei parallele Ladevorgänge desselben Belegs, sequentielle Speicherversuche: der zweite",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SyRS-9",
|
||||
"ebene": "SyRS",
|
||||
"titel": "Stornierte Belege sind gegen Zahlungsstatusänderung geschützt",
|
||||
"typ": "funktional",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-5, SwRS-8, SwRS-10",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "UpdateReceiptIsPaid auf einem Beleg mit State=Canceled liefert Result.Error unabhängig vom",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SyRS-10",
|
||||
"ebene": "SyRS",
|
||||
"titel": "Vollständige Versionierung bei jeder Belegspeicherung",
|
||||
"typ": "nicht-funktional (Zuverlässigkeit, ISO25010)",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-6, SwRS-11, SwRS-12",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Für jeden der sieben Belegtypen: Speichern einer Änderung erzeugt einen neuen Versionsdatensatz",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SyRS-11",
|
||||
"ebene": "SyRS",
|
||||
"titel": "Ausnahmerecht für Zahlungseingang unabhängig vom allgemeinen Bearbeitungsrecht",
|
||||
"typ": "Sicherheit",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-8",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Benutzer mit ausschließlich INCOMING_PAYMENT_TRANSACTIONS (kein allgemeines Bearbeitungsrecht):",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SyRS-12",
|
||||
"ebene": "SyRS",
|
||||
"titel": "Mehrstufige Selektion abrechnungsfähiger Verträge",
|
||||
"typ": "funktional",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-9, SwRS-13, SwRS-14",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Aktiver Vertrag ohne Vertragspositionen wird trotz fälligem Intervall NICHT in die finale",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SyRS-13",
|
||||
"ebene": "SyRS",
|
||||
"titel": "Berücksichtigung von Sonderartikel-Stichtagen bei dynamischen Bedarfsverträgen",
|
||||
"typ": "funktional",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-9, StRS-10",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Dynamischer Bedarfsvertrag ohne Sonderartikel-Stichtag im Abrechnungszeitraum wird aus der",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SyRS-14",
|
||||
"ebene": "SyRS",
|
||||
"titel": "Zeitraumbezogene Mahnsperre je Kunde/Objekt",
|
||||
"typ": "funktional",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-11, SwRS-15",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Setzen einer Mahnsperre mit dunningStopEnd in der Zukunft: das Objekt wird im nächsten",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SyRS-15",
|
||||
"ebene": "SyRS",
|
||||
"titel": "Rückwärtssuche in der Steuersatzhistorie bis zum passenden Gültigkeitszeitraum",
|
||||
"typ": "funktional",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-12, SwRS-16",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Kette mit Steuersatz A (gültig bis 30.06.), Nachfolger B (ab 01.07.): receiptDate=15.06.",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SyRS-16",
|
||||
"ebene": "SyRS",
|
||||
"titel": "Granulare Rechteprüfung je CRUD-Operation auf Geschäftspartnerdaten",
|
||||
"typ": "Sicherheit",
|
||||
"belege": [
|
||||
"PRIMÄR",
|
||||
"KONTEXT"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-13, SwRS-17",
|
||||
"konsolidierung": "Kandidat: SyRS-1 (gleiches zugrundeliegendes Rechteprüfungsmuster CheckRightsFromUser,",
|
||||
"pruefidee": "Benutzer mit ausschließlich EDIT_CUSTOMER: Bearbeiten eines bestehenden Kunden gelingt,",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SyRS-17",
|
||||
"ebene": "SyRS",
|
||||
"titel": "Getrennte Rechte für Datumsänderung bei Rechnung und Lieferschein",
|
||||
"typ": "Sicherheit",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-14, SwRS-18",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Benutzer mit DeliveryList.CAN_CHANGE_DATE, aber ohne Invoice.CAN_CHANGE_DATE:",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SyRS-18",
|
||||
"ebene": "SyRS",
|
||||
"titel": "Ticketstatus als Stammdaten statt Programmkonstante",
|
||||
"typ": "Daten",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-15, SwRS-19",
|
||||
"konsolidierung": "Kandidat: SwRS-8 (gegensätzliches Muster: Belegstatus fest vs. Ticketstatus konfigurierbar –",
|
||||
"pruefidee": "Ein neuer HelpdeskState-Datensatz ist über die Rechteverwaltungs-/Admin-UI anlegbar und",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SyRS-19",
|
||||
"ebene": "SyRS",
|
||||
"titel": "Linux-Fähigkeit des Webservice-Hosts",
|
||||
"typ": "nicht-funktional (Übertragbarkeit, ISO25010)",
|
||||
"belege": [
|
||||
"PRIMÄR",
|
||||
"KONTEXT"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": true,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-16, SwRS-20",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Webservice-Container basierend auf einem Linux-Basisimage startet erfolgreich und beantwortet",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SwRS-1",
|
||||
"ebene": "SwRS",
|
||||
"titel": "Sessionweites Caching der Benutzerrechte",
|
||||
"typ": "nicht-funktional (Performance-Effizienz, ISO25010)",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "SyRS-1",
|
||||
"konsolidierung": "Kandidat: SwRS-2 (ähnlicher Cache-Mechanismus für Web-Account-Rechte, HasWebAccountRight)",
|
||||
"pruefidee": "Zwei aufeinanderfolgende HasUserRight-Aufrufe für denselben Benutzer in derselben Session:",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SwRS-2",
|
||||
"ebene": "SwRS",
|
||||
"titel": "Massenprüfung mehrerer Rechte in einem Datenbankzugriff",
|
||||
"typ": "funktional",
|
||||
"belege": [
|
||||
"PRIMÄR",
|
||||
"KONTEXT"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "SyRS-1",
|
||||
"konsolidierung": "Kandidat: SwRS-1",
|
||||
"pruefidee": "Aufruf mit 5 Recht-IDs, von denen der Benutzer 3 besitzt, liefert eine Liste mit genau",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SwRS-3",
|
||||
"ebene": "SwRS",
|
||||
"titel": "Hartkodierte Positivliste änderbarer Administrator-Rechte",
|
||||
"typ": "Daten",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt; Workaround (hartkodierte ID-Liste statt konfigurierbarer Regel — Migrationsrisiko:",
|
||||
"hypothese": false,
|
||||
"workaround": true,
|
||||
"tracelinks": "SyRS-3, SyRS-4",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Zuweisungsversuch eines Rechts mit I3D, das nicht in der Liste enthalten ist, an die",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SwRS-4",
|
||||
"ebene": "SwRS",
|
||||
"titel": "Hierarchisches Rechteschema in Tabelle Sichrech",
|
||||
"typ": "Daten",
|
||||
"belege": [
|
||||
"PRIMÄR",
|
||||
"KONTEXT"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "SyRS-1",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Ausführen eines Migrationsskripts mit AddRightIfNotExists erzeugt einen neuen Sichrech-Datensatz",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SwRS-5",
|
||||
"ebene": "SwRS",
|
||||
"titel": "Entwicklungsseitige Umleitung externer E-Mail-Adressen in Debug-Builds",
|
||||
"typ": "Sicherheit",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt; Workaround (baujahresspezifischer Schutzmechanismus für die bestehende Delphi-/",
|
||||
"hypothese": false,
|
||||
"workaround": true,
|
||||
"tracelinks": "(kein direkter StRS/SyRS-Bezug – reine Entwicklungssicherheitsmaßnahme, kein Fachprozess)",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Debug-Build, Versand an \"kunde@fremdefirma.de\": tatsächlicher SMTP-Empfänger ist",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SwRS-6",
|
||||
"ebene": "SwRS",
|
||||
"titel": "Lizenzmanager als Prozess-Singleton mit expliziter Einmalinitialisierung",
|
||||
"typ": "funktional",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "SyRS-5, SyRS-6",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Zweiter Aufruf von Initialize() in derselben Prozessinstanz löst eine Exception aus;",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SwRS-7",
|
||||
"ebene": "SwRS",
|
||||
"titel": "Sonderbehandlung der c-entron-Delphi-Versionsnummer bei der Lizenzprüfung",
|
||||
"typ": "Daten",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt; Workaround (Altlast aus der Koexistenz von c-entron Delphi und c-entron.NET; für",
|
||||
"hypothese": false,
|
||||
"workaround": true,
|
||||
"tracelinks": "SyRS-5",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Login mit Version \"9.3.40.2\" und Centron-Lizenz-GUID wird nicht wegen Versionsüberschreitung",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SwRS-8",
|
||||
"ebene": "SwRS",
|
||||
"titel": "Dreiwertiger Belegstatus (ReceiptState) als gemeinsamer Zustandsautomat",
|
||||
"typ": "Daten",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": true,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-5, SyRS-9",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Kompilierzeitprüfung/Reflection: ReceiptState besitzt genau die drei genannten Werte.",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SwRS-9",
|
||||
"ebene": "SwRS",
|
||||
"titel": "SpecificLogics-Dispatch für belegtypspezifische Rechteprüfung",
|
||||
"typ": "funktional",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "SyRS-7, StRS-7",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Für zwei verschiedene Belegtypen mit unterschiedlichen HasRightToEditReceipt-Implementierungen",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SwRS-10",
|
||||
"ebene": "SwRS",
|
||||
"titel": "Ableitung des Belegstatus aus dem Zahlungsflag",
|
||||
"typ": "funktional",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-8, SyRS-9",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "isPaid=true auf einem Active-Beleg: State wird Completed; isPaid=false auf einem",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SwRS-11",
|
||||
"ebene": "SwRS",
|
||||
"titel": "Versionsinkrement als eigenständiger Zustand vor dem eigentlichen Speichern",
|
||||
"typ": "funktional",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-6, SyRS-10",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Versuch, aus einer historischen Version mit aktiven Barcodes eine neue Version zu erzeugen,",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SwRS-12",
|
||||
"ebene": "SwRS",
|
||||
"titel": "Duale Persistenzschicht: moderne Entity plus Legacy-Repository-Synchronisation",
|
||||
"typ": "Daten",
|
||||
"belege": [
|
||||
"PRIMÄR",
|
||||
"KONTEXT"
|
||||
],
|
||||
"status": "belegt; Workaround (historisch gewachsene Doppelpersistenz; zentrales Migrationsrisiko für",
|
||||
"hypothese": false,
|
||||
"workaround": true,
|
||||
"tracelinks": "StRS-6, SyRS-10",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Neues Feld wird nur der modernen Entity/Mapping hinzugefügt, nicht dem Repository: Wert wird",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SwRS-13",
|
||||
"ebene": "SwRS",
|
||||
"titel": "Bedingte LINQ-Filterausdrücke je Berechnungsart in GetActiveContracts",
|
||||
"typ": "funktional",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "SyRS-12, StRS-10",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Vertrag mit LastPaidDate >= ContractEnd und CalculationKind=Auto wird NICHT selektiert",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SwRS-14",
|
||||
"ebene": "SwRS",
|
||||
"titel": "Stapelweise (Batch) Nachfilterung großer Vertragsmengen über NamedQueries",
|
||||
"typ": "nicht-funktional (Performance-Effizienz, ISO25010)",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "SyRS-12",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Abrechnungslauf mit > 2000 abrechnungsfähigen Verträgen schlägt nicht mit einem",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SwRS-15",
|
||||
"ebene": "SwRS",
|
||||
"titel": "Offener-Betrag-Berechnung je Mahnstufe aus drei Rechnungsbeträgen",
|
||||
"typ": "Daten",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-11, SyRS-14",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Rechnung mit GrossPriceComplete=1000, PayedGrossAmount=300, CreditVoucherGrossAmount=100:",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SwRS-16",
|
||||
"ebene": "SwRS",
|
||||
"titel": "Verkettete Steuersatz-Entität mit Fallback auf artikelspezifischen Standardsatz",
|
||||
"typ": "Daten",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-12, SyRS-15",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Aufruf mit einer nicht existierenden taxRateI3D liefert nicht null, sondern den",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SwRS-17",
|
||||
"ebene": "SwRS",
|
||||
"titel": "Konfigurierbare Kopplung von Buchhaltungsnummer und Kundennummer",
|
||||
"typ": "Daten",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-13, SyRS-16",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Mit aktivierter Einstellung: neu angelegter Kunde mit Nummer 4711 erhält BookKeepingNumber",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SwRS-18",
|
||||
"ebene": "SwRS",
|
||||
"titel": "Belegtypabhängige UI-Feldsperre mit erklärendem Hinweistext",
|
||||
"typ": "funktional",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-14, SyRS-17",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "ReceiptKind=InvoiceClass, CanChangeDateInInvoices=false: BillingDateIsEnabled=false,",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SwRS-19",
|
||||
"ebene": "SwRS",
|
||||
"titel": "Erweiterung der Basis-Statusdaten um Verrechnungs- und Portaldarstellungsfelder",
|
||||
"typ": "Daten",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-15, SyRS-18",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Zwei HelpdeskState-Datensätze mit unterschiedlichem ServiceBoardWebColor erscheinen im",
|
||||
"qm": ""
|
||||
},
|
||||
{
|
||||
"id": "SwRS-20",
|
||||
"ebene": "SwRS",
|
||||
"titel": "Explizite Dienstabhängigkeit und Neustartrichtlinie in der Compose-Topologie",
|
||||
"typ": "nicht-funktional (Zuverlässigkeit, ISO25010)",
|
||||
"belege": [
|
||||
"PRIMÄR"
|
||||
],
|
||||
"status": "belegt",
|
||||
"hypothese": false,
|
||||
"workaround": false,
|
||||
"tracelinks": "StRS-16, SyRS-19",
|
||||
"konsolidierung": "nein",
|
||||
"pruefidee": "Manuelles Beenden des webservice-Containers: Compose startet ihn automatisch neu, ohne dass",
|
||||
"qm": ""
|
||||
}
|
||||
]
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
## Gefundene Anforderungen
|
||||
|
||||
Maschinell aus `Ergebnisse\StRS.md`, `SyRS.md` und `SwRS.md` ausgewertet (Blockformat des Prompts). Erzeugt von `analyse-anforderungen.py`.
|
||||
|
||||
### Verteilung über die Ebenen
|
||||
|
||||
| Ebene | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| StRS | 16 | 29,1 % |
|
||||
| SyRS | 19 | 34,5 % |
|
||||
| SwRS | 20 | 36,4 % |
|
||||
| **Gesamt** | **55** | 100 % |
|
||||
|
||||
### Anforderungstypen
|
||||
|
||||
| Typ | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| funktional | 23 | 41,8 % |
|
||||
| Sicherheit | 13 | 23,6 % |
|
||||
| Daten | 10 | 18,2 % |
|
||||
| nicht-funktional (Zuverlässigkeit, ISO25010) | 4 | 7,3 % |
|
||||
| nicht-funktional (Übertragbarkeit, ISO25010) | 2 | 3,6 % |
|
||||
| nicht-funktional (Performance-Effizienz, ISO25010) | 2 | 3,6 % |
|
||||
| nicht-funktional (Zuverlässigkeit / Security-ISO25010) | 1 | 1,8 % |
|
||||
|
||||
### Belegqualität
|
||||
|
||||
| Messgröße | Wert |
|
||||
|---|---:|
|
||||
| Belege gesamt | 67 |
|
||||
| davon `PRIMÄR` | 54 (80,6 %) |
|
||||
| davon `SEKUNDÄR` | 5 (7,5 %) |
|
||||
| davon `KONTEXT` | 8 (11,9 %) |
|
||||
| Belege je Anforderung (Median) | 1 |
|
||||
| Anforderungen mit mindestens einem `PRIMÄR`-Beleg | 54 (98,2 %) |
|
||||
|
||||
### Status
|
||||
|
||||
| Kategorie | Anzahl | Anteil |
|
||||
|---|---:|---:|
|
||||
| belegt | 51 | 92,7 % |
|
||||
| als `HYPOTHESE` gekennzeichnet | 4 | 7,3 % |
|
||||
| als Workaround vermerkt | 4 | 7,3 % |
|
||||
| Konsolidierungskandidaten | 6 | 10,9 % |
|
||||
| mit ISO-25010-Qualitätsmerkmal | 0 | 0,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** (37 risikorelevante Anforderungen, alle gedeckt) |
|
||||
| **Verifizierbarkeit** – jede Anforderung mit Prüfidee oder Akzeptanzkriterium | **erfüllt** |
|
||||
| **Traceability** – Verknüpfung zwischen den Ebenen | 55 von 55 mit Tracelinks (100,0 %) |
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
[]
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
# Subagenten-Aufrufe
|
||||
|
||||
Session `f3744c04-c4e2-4d9b-8fd6-d2e5e8ba2c15`, Transkript `f3744c04-c4e2-4d9b-8fd6-d2e5e8ba2c15.jsonl`.
|
||||
|
||||
`subagent_stats`: **0** Subagenten gesamt, davon **0** von Subagenten gestartet (max_depth 0). Direkt vom Hauptagenten erwartet: **0**. Im Transkript gefunden: **0**.
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
# Analysebericht — Reverse Requirements Engineering CentronERP
|
||||
|
||||
Versuch 01 (Baseline, Prompt-only), Iteration 01. Erstellt am 2026-08-25. Untersuchungsgegenstand: gesamte Codebasis unter `C:\DEV\MasterArbeit\QuellCode\CentronERP` (15.554 `.cs`-Dateien, 1.233 `.xaml`-Dateien, ca. 90 fachliche Business-Logic-Module unter `src/backend/Centron.BL`, mehrere eigenständige Anwendungen: WPF-Desktop-Client, CentronNexus-Webanwendung, diverse API-/Integrationsprojekte). Ergebnis: 43 StRS-, 150 SyRS- und 132 SwRS-Anforderungen (325 gesamt) in elf fachlichen Analyseclustern.
|
||||
|
||||
## 1. Vorgehen
|
||||
|
||||
Da eine gleich tiefe Analyse aller ca. 90 Business-Logic-Module, aller WPF-Views/ViewModels und aller Datenbankentitäten in einem Lauf nicht leistbar ist, wurde die Analysetiefe selbstständig priorisiert (wie im Auftrag vorgesehen): Es wurden elf fachliche Cluster gebildet und jeweils durch einen eigenen Analyse-Durchgang mit Lesezugriff auf Quellcode, Dokumentation (`docs/`) und Commit-Historie bearbeitet:
|
||||
|
||||
| Cluster | Schwerpunkt | Primäre Codebereiche |
|
||||
|---|---|---|
|
||||
| ARCH | Anwendungsarchitektur & Systemrahmen | `Centron.WPF.UI/{Modules,Start,Managers,Layout,Wizards,Localization}`, `Centron.Core`, `docs/reference/architecture` |
|
||||
| SEC | Sicherheit & Berechtigungen | `Centron.BL/{Security,PasswordManager,PasswordManagementArea,TwoFactorAuthenticator}`, `CentronRights.md`, `docs/reference/security` |
|
||||
| CRM | Stammdaten (Geschäftspartner, Kunden, Mitarbeiter) | `Centron.BL/{BusinessPartner,CustomerArea,EmployeeArea,CountryArea}` |
|
||||
| SALES | Vertrieb & Einkauf | `Centron.BL/{Sales,Buying,Purchasing,ProductMatrix,TradePool}` |
|
||||
| BILL | Abrechnung, Fakturierung & Verträge | `Centron.BL/{VoucherManagement,Accounting,Finances}`, `docs/reference/receipts`, ZUGFeRD/XRechnung-Doku |
|
||||
| TIME | Zeiterfassung, Projekte & Tickets (intern) | `Centron.BL/{Time,TicketProjects,Projects,TaskManager,MyDay,Calendar,AppointmentRequests}` |
|
||||
| LOG | Lager, Logistik & Produktion | `Centron.BL/{Warehousing,Logistics,Production,Devices}` |
|
||||
| ADM | Administration, Systemkonfiguration & Kommunikation | `Centron.BL/{Administration,SystemArea,Customizations,Modules,Notifications,Mailings,Mail,MailScanner}` |
|
||||
| DOC | Dokumente & Reporting | `Centron.BL/{DocuBoard,DocumentationArea,Reporting,ReportEngine,TextModuleArea}`, `Centron.Api.docuFORM` |
|
||||
| INT | Externe Integrationen & Schnittstellen | `Centron.BL/{EDI,DataExchange,WebServices,Gateway,Integrations}`, `Centron.Gateway`, `src/apis/*`, `src/webservice` |
|
||||
| NEX | CentronNexus (Ticket-/Helpdesk-System) | `src/nexus/*`, `Centron.BL/{ExternalHelpdesk,CentronNexus,NexusNotifications,NexusTicketViews}` |
|
||||
|
||||
Jeder Cluster-Durchgang erfasste Fakten mit Artefaktbeleg, leitete Anforderungskandidaten für StRS/SyRS/SwRS ab und klassifizierte Belege als PRIMÄR/SEKUNDÄR/KONTEXT. In einem zweiten Schritt wurden die Kandidaten je Cluster in das finale ID-Schema (`<Ebene>-<CLUSTER>-<laufende Nummer>`) überführt und intra-cluster Tracelinks gebildet. Abschließend wurden alle elf Cluster zentral zusammengeführt, ein cluster-übergreifender Konsistenzcheck durchgeführt (Abschnitt 3) und cluster-übergreifende Konsolidierungskandidaten identifiziert (Abschnitt 4).
|
||||
|
||||
## 2. Abdeckung nach Modul
|
||||
|
||||
### 2.1 Vollständig bzw. gezielt tief analysiert (mit Artefaktbelegen in StRS/SyRS/SwRS)
|
||||
|
||||
Business-Logic-Module: `Security`, `PasswordManager`, `PasswordManagementArea`, `TwoFactorAuthenticator`, `BusinessPartner`, `CustomerArea`, `EmployeeArea`, `CountryArea`, `Sales`, `Buying`, `Purchasing`, `ProductMatrix`, `TradePool`, `VoucherManagement`, `Accounting`, `Finances`, `Time`, `TicketProjects`, `Projects`, `TaskManager`, `MyDay`, `Calendar`, `AppointmentRequests`, `Warehousing`, `Logistics`, `Production`, `Devices`, `Administration`, `SystemArea`, `Customizations`, `Modules`, `Notifications`, `Mailings`, `Mail`, `MailScanner`, `DocuBoard`, `DocumentationArea`, `Reporting`, `ReportEngine`, `TextModuleArea`, `EDI`, `DataExchange`, `WebServices`, `Gateway`, `Integrations`, `ExternalHelpdesk`, `CentronNexus` (BL-Anteil), `NexusNotifications`, `NexusTicketViews`.
|
||||
|
||||
Eigenständige Projekte: `src/nexus/CentronNexus`, `src/nexus/CentronNexus.Host`, `Centron.Gateway`, `Centron.Api.docuFORM`, `src/apis/Centron.Api.EbInterface`, `src/apis/Centron.APIs.{CopDataAccess,EgisDataAccess,FinAPI,IcecatDataAccess,ITscopeDataAccess}`, `src/webservice` (als Integrationsplattform), `Centron.WPF.UI/{Modules,Start,StartupArgs,Managers,Layout,Wizards,Localization}`, `Centron.Core`.
|
||||
|
||||
Dokumentation: alle Dateien unter `docs/reference/` und `docs/guides/` sowie `docs/features/automatic-helpdesk-creation-templates.md` wurden gelesen und als Belege verwendet; `CentronRights.md` vollständig.
|
||||
|
||||
Innerhalb dieser Module wurde nicht jede einzelne Datei vollständig gelesen — die Cluster-Agenten haben gezielt Statusmaschinen, Validierungslogik, Berechtigungsprüfungen und Berechnungsregeln über Grep/Glob lokalisiert und die betroffenen Methoden/Klassen im Detail gelesen. Bekannte Detaillücken pro Cluster sind in den jeweiligen "Abdeckung"-Abschnitten der Rohbefunde dokumentiert (siehe `_staging/*.md`) und teilweise als `[HYPOTHESE]` in Hypothesen.md erfasst.
|
||||
|
||||
### 2.2 Nur stichprobenhaft/oberflächlich analysiert
|
||||
|
||||
- `src/apis/Centron.Api.Gls`, `src/apis/Centron.Api.Shipcloud` (Versanddienstleister-APIs): nur als Kontextreferenz aus dem LOG-Cluster erwähnt, keine eigene Tiefenanalyse (siehe SyRS-LOG-15, als Hypothese/Lücke dokumentiert).
|
||||
- `src/nexus/CentronNexus.OutlookAddIn`: nur oberflächlich, Kernlogik von CentronNexus.Host stand im Vordergrund.
|
||||
- `Centron.WPF.UI/{Dialogs,Views,ViewModels}`: nur punktuell dort gelesen, wo eine Anforderung dies erforderte (z. B. `PriceMatrixViewModel.cs` im BILL-Cluster); die überwiegende Mehrheit der >1.200 XAML-Views und zugehörigen ViewModels wurde nicht gesichtet.
|
||||
- `Centron.BL/CentronIcons`: nur als Ausgangspunkt genannt, nicht inhaltlich vertieft.
|
||||
- `Centron.DAO`, `Centron.Interfaces`, `Centron.Common`: nur indirekt über gezielte Grep-Suchen (z. B. nach Statusmaschinen/Constraints) einbezogen, nicht als eigenständiges Modul analysiert.
|
||||
- Commit-Historie (52.135 Commits): nicht durchsucht, mit einer gezielten Ausnahme (Commit `baa9e7bd9b`, explizit im TIME-Cluster-Auftrag verankert und als Beleg in TIME-07 verwendet).
|
||||
|
||||
### 2.3 Nicht analysiert (keine eigene Betrachtung in dieser Iteration)
|
||||
|
||||
Business-Logic-Module ohne jede Betrachtung: `Accounts`, `ArtificialIntelligence`, `ChangeTracking`, `Chats`, `CheckListArea`, `Core` (BL-internes, nicht zu verwechseln mit `Centron.Core`), `CPra`, `Exceptions`, `ExpectedEvents`, `ExternalToolsBL`, `GUI`, `Helpers`, `IndexSearch`, `ItPlanner`, `MassUpdate`, `Mobile`, `MyCentron`, `Outlook` (BL-Anteil), `PasswordManagementArea/PasswordManagementKeywordBL` (nur namentlich als Legacy-Verdacht erwähnt, nicht im Detail gelesen — siehe SwRS-SEC-06), `Processes`, `Resources`, `RiverDivo`, `SelfCare`, `Services`, `SocialMedia`, `Statistics`, `Storage`, `Tags`, `Telemetry` (nur indirekt über SyRS-ARCH-13 gestreift), `ToDoArea`, `Tools`, `Transactions`, `Urls`, `VideoPortal`, `WebLinks`, `WebSuite`, `WebVersion`.
|
||||
|
||||
Weitere nicht analysierte Bereiche: `src/shared/Centron.Controls`, `src/shared/Centron.Controls.Preview`, `src/centron/Centron.WPF.UI.Extension`, `azure/`, `azure-blazor/`, `deployment/`, `docker/`, `scripts/`, `nugets/`, `tests/*` (alle Testprojekte — hier hätten Testfälle als zusätzliche, oft sehr präzise Belege für Geschäftsregeln dienen können, wurden aber aus Zeitgründen nicht herangezogen).
|
||||
|
||||
**Konkrete Lücke mit Auftragsbezug:** Der Auftrag verlangt explizit, Betriebs-/Sicherheitsanforderungen "gezielt auch aus indirekt sichtbaren Artefakten" wie Deployment-Skripten und Logging-Policies abzuleiten. Die Verzeichnisse `deployment/`, `docker/` und `azure/` (CI/CD-Pipelines) wurden in dieser Iteration nicht geöffnet — das ist die größte bekannte Abdeckungslücke gegenüber dem Auftrag und sollte in einer Folge-Iteration priorisiert werden (siehe Abschnitt 5).
|
||||
|
||||
## 3. Konsistenzcheck (mechanisch durchgeführt und iterativ korrigiert)
|
||||
|
||||
Nach Zusammenführung der elf Cluster wurde ein automatisierter Konsistenzcheck über den gesamten Anforderungsbestand (StRS.md, SyRS.md, SwRS.md, Traceability.md, Hypothesen.md) durchgeführt:
|
||||
|
||||
1. **Doppelte oder mehrfach vergebene IDs:** keine gefunden (325 Anforderungen, 325 eindeutige IDs; das cluster-präfigierte Schema `<Ebene>-<CLUSTER>-<Nr>` garantiert Eindeutigkeit ohne zentrale Koordination).
|
||||
2. **Anforderungen ohne Beleg:** keine gefunden — jede der 325 Anforderungen enthält mindestens eine `Belege:`-Zeile mit PRIMÄR/SEKUNDÄR/KONTEXT-Klassifikation.
|
||||
3. **Tracelinks auf nicht existierende IDs:** keine gefunden — alle in `Tracelinks:`-Feldern, in der Traceability-Tabelle und in `Konsolidierung:`-Feldern referenzierten IDs sind im Bestand definiert (automatisierter Soll-/Ist-Abgleich über alle 325 IDs).
|
||||
4. **Risikobasierte Evidenzregel (Sicherheits-, Abrechnungs-, Berechtigungsanforderungen benötigen mindestens einen PRIMÄR-Beleg, sonst zwingend `HYPOTHESE`):** Bei der ersten Zusammenführung wurden **4 Verstöße** gefunden — die Anforderungen `SyRS-BILL-10`, `SyRS-BILL-17`, `SwRS-BILL-03` und `SwRS-BILL-05` trugen den Status `belegt`, obwohl nur ein `SEKUNDÄR`-Beleg (Dokumentation, nicht im Quellcode gegengelesen) vorlag. Diese wurden im Rahmen dieses Berichts korrigiert: Status auf `HYPOTHESE` mit Begründung geändert und in `Hypothesen.md` nachgetragen. Nach der Korrektur bestehen keine offenen Verstöße gegen diese Regel (verifiziert für alle Anforderungen mit `Typ: Sicherheit` sowie für die Cluster SEC und BILL).
|
||||
5. **Vollständigkeit der Hypothesen-Sammlung:** Es wurde zusätzlich geprüft, ob alle Anforderungen mit dem Wortbestandteil `HYPOTHESE` im Status-Feld auch in `Hypothesen.md` erscheinen. Ursprünglich fehlten 21 Anforderungen, die zwar insgesamt als `belegt` eingestuft waren, aber eine eingebettete `[HYPOTHESE]`-Markierung zu einem Detailaspekt trugen (uneinheitliche Notation zwischen den Clustern ARCH/INT/SEC/CRM einerseits, die diese Nuance nutzten, und den übrigen Clustern andererseits, die nur strikt "Status = HYPOTHESE" exportierten). Diese wurden ergänzt (Abschnitt "Eingebettete Teilhypothesen" in `Hypothesen.md`). `Hypothesen.md` referenziert nun alle 54 Anforderungen mit Status-Wort `HYPOTHESE` plus 2 vom SALES-Cluster nachrichtlich (nicht Status-bildend) gemeldete Anforderungen.
|
||||
|
||||
## 4. Cluster-übergreifende Konsolidierungskandidaten
|
||||
|
||||
Die Konsolidierungshinweise innerhalb der einzelnen Anforderungen (`Konsolidierung:`-Feld) wurden von den Cluster-Durchgängen ausschließlich **innerhalb** des jeweiligen Clusters vergeben, da zum Zeitpunkt der Cluster-Analyse keine Sicht auf die anderen Cluster bestand. Bei der Zusammenführung wurden folgende **cluster-übergreifende** Konsolidierungskandidaten identifiziert (Betriebsbegriffe, die in mehreren Clustern unabhängig voneinander als eigenständige fachliche Regel dokumentiert wurden):
|
||||
|
||||
- **Belegstatus-Automat (ReceiptState: Active/Completed/Canceled):** unabhängig in BILL (`SyRS-BILL-01`, `SyRS-BILL-04`) und SALES (`SyRS-SALES-01`, `SyRS-SALES-10`, `SwRS-SALES-01`, `SwRS-SALES-02`, `SwRS-SALES-05`, `SwRS-SALES-10`) als dieselbe zugrunde liegende Statusmaschine des Beleg-Frameworks (`IReceiptBase`/`ReceiptBL`) beschrieben. Kandidat für eine gemeinsame SwRS-Anforderung "Belegstatus-Automat" im Zielsystem statt getrennter Beschreibung je Modul.
|
||||
- **E-Rechnungsformate (ZUGFeRD/XRechnung):** in drei Clustern parallel behandelt — BILL (Kernlogik, `SyRS-BILL-06/09/10/17/19`, `StRS-BILL-01`), DOC (PDF/A-3-Erzeugung und Archivierung, `SwRS-DOC-06`, `SyRS-DOC-05/06`) und INT (als Schnittstellenformat im Kontext von ebInterface/EDI, `StRS-INT-01`, `SwRS-INT-07`). Für die Zielarchitektur sollte eine einzige, modulübergreifende "E-Invoicing"-Fähigkeit spezifiziert werden statt einer Aufteilung nach technischer Zuständigkeit (Fakturierung vs. Dokumentenerzeugung vs. Schnittstelle).
|
||||
- **Mahnwesen/Belegsperre (Mahnstufe/Dunning Level):** unabhängig in BILL (`StRS-BILL-03`, `SwRS-BILL-01`, `SyRS-BILL-16`) und SALES (`SyRS-SALES-16`) sowie am Rande in DOC (`SwRS-DOC-09`, Sperre von Mahnschreiben-Reports) beschrieben. Sollte im Zielsystem als eine zentrale Regel (Kunde gesperrt ab Mahnstufe X → wirkt auf alle Belegarten) konsolidiert werden, statt separat für Vertrieb und Abrechnung geführt zu werden.
|
||||
- **Kunden-/externer Portal-Login (WebAccount):** in vier Clustern beschrieben — ARCH (Architekturüberblick, `SyRS-ARCH-02/16`), SEC (Authentifizierungsregeln, `SwRS-SEC-03/04`, `SyRS-SEC-03/04/13/16`), CRM (Stammdatenbezug, `SyRS-CRM-05`) und NEX (Kundenportal-Nutzung, `StRS-NEX-01/04`, `SyRS-NEX-08/10`). Ergänzend beschreibt SALES ein davon unabhängiges, eigenständiges `TradeCustomerLogin`-Verfahren für den Handelswaren-Bereich (`SyRS-SALES-14`, als Hypothese markiert, ob dies ein bewusst getrenntes Legacy-System ist). Für die Neuimplementierung ist zu klären, ob ein einheitliches externes Identitätsmodell alle vier/fünf Ausprägungen ablösen soll.
|
||||
- **Timer-Abrechnung als Spezialfall der Belegerzeugung:** TIME (`StRS-TIME-01`, `SyRS-TIME-04/06`, `SwRS-TIME-08`, über `ReceiptItemTimerBL`) erzeugt Positionen in denselben Belegarten (Auftrag/Lieferschein/Rechnung), die auch in BILL/SALES beschrieben werden. Die Timer-Abrechnung sollte im Zielsystem als ein spezifischer Positions-Erzeugungspfad in die gemeinsame Belegarchitektur eingeordnet werden, nicht als eigenständiger Abrechnungsweg.
|
||||
- **I3D-Primärschlüsselkonvention:** als technisches Datenmodell-Muster in praktisch jedem Cluster referenziert (siehe Glossar) — kein fachlicher Konsolidierungsbedarf, aber ein deutlicher Hinweis, dass die Neuimplementierung durchgängig von diesem Legacy-Namensmuster wegmigrieren sollte (technische Migrationsanmerkung, kein Requirement-Duplikat).
|
||||
|
||||
Diese cluster-übergreifenden Kandidaten sind zusätzlich zu den in den einzelnen Anforderungen dokumentierten intra-cluster-`Konsolidierung:`-Feldern zu verstehen; sie wurden nicht in die einzelnen Requirement-Blöcke zurückgeschrieben, um Nacharbeiten durch die Fachvalidierung (Schritt 7) nicht vorwegzunehmen.
|
||||
|
||||
## 5. Zentrale inhaltliche Befunde (Auswahl, priorisiert nach Risiko)
|
||||
|
||||
Diese Befunde stammen aus den Cluster-Analysen und werden hier gebündelt hervorgehoben, da sie unmittelbaren Handlungsbedarf für die Zielarchitektur signalisieren:
|
||||
|
||||
- **Passwort-Hashing ohne Salt (SHA1):** Im Login-Code der internen Benutzerverwaltung (`AppUser`/`Sichbenu`) wird ein Salt-Mechanismus nicht konsequent genutzt; SHA1 gilt für Passwort-Speicherung als veraltet (siehe SwRS-SEC-03, Cluster SEC, PRIMÄR belegt inkl. Code-TODO-Kommentar).
|
||||
- **Klartext-Passwortversand per E-Mail** bei Neuanlage von Web-Accounts (Cluster SEC).
|
||||
- **Kein erkennbarer Kontosperrmechanismus** nach fehlgeschlagenen Login-Versuchen (Cluster SEC, als `SyRS-SEC-16` mit Status HYPOTHESE dokumentiert, da nicht auszuschließen ist, dass dies auf Infrastrukturebene abgedeckt wird).
|
||||
- **Hartkodierte Zugangsdaten/Tokens** bei mindestens zwei Drittanbieter-Integrationen (GLS, ITScope) sowie **deaktivierte TLS-Zertifikatsprüfung** bei einer FTPS-Verbindung (`SwRS-INT-01`, als HYPOTHESE markiert, da die Begründung im Code fehlt) — Cluster INT.
|
||||
- **Clientseitige statt serverseitige Validierung von Aktionspreisen** (`BILL-24`-Rohbefund, in SwRS-BILL-03 als HYPOTHESE aufgrund fehlenden PRIMÄR-Belegs geführt, aber unabhängig davon als Architekturrisiko dokumentiert): Preisintegrität ist im aktuellen System nicht serverseitig erzwungen.
|
||||
- **Begriffsverwirrung "DocuBoard"/"docuFORM":** Beide Namen legen eine Dokumentenverwaltungsfunktion nahe, bezeichnen im Code aber IT-Asset- bzw. Drucker-Fleet-Management. Für die Zielarchitektur ist dies vor allem als Hinweis auf irreführende Modulbenennung relevant, nicht als fachliche Anforderung selbst (Cluster DOC).
|
||||
|
||||
## 6. Selbstbewertung
|
||||
|
||||
**Vollständig analysierte Module:** siehe Abschnitt 2.1 — ca. 50 von ca. 90 Business-Logic-Modulen sowie die wichtigsten Integrationsprojekte und die gesamte technische Dokumentation unter `docs/`.
|
||||
|
||||
**Nur stichprobenhaft analysierte Bereiche:** siehe Abschnitt 2.2 — insbesondere die WPF-UI-Schicht (Views/ViewModels) wurde nur dort vertieft, wo eine konkrete Anforderung dies erforderte; die überwiegende Mehrheit der über 1.200 XAML-Views wurde nicht gesichtet. Auch die Datenzugriffsschicht (`Centron.DAO`) wurde nur über gezielte Stichproben statt vollständig durchsucht.
|
||||
|
||||
**Nicht analysierte Module:** siehe Abschnitt 2.3 — rund 35–40 Business-Logic-Module (u. a. `ArtificialIntelligence`, `SocialMedia`, `VideoPortal`, `SelfCare`, `MyCentron`, `WebSuite`, `Mobile`, `Statistics`, `Storage`) sowie alle Deployment-/CI-CD-Artefakte (`deployment/`, `docker/`, `azure/`) und alle Testprojekte (`tests/*`).
|
||||
|
||||
**Stellen mit dünner Beleglage** (hoher Anteil SEKUNDÄR/KONTEXT oder HYPOTHESE):
|
||||
- Cluster **INT** (Integrationen): mehrere Sicherheits-relevante Befunde (Zertifikatsprüfung, Schlüsselmanagement) sind nur über Code-Kommentare oder Konfigurationswerte, nicht über eine explizite Dokumentation der Absicht belegt.
|
||||
- Cluster **ARCH**: mehrere Referenzdokumente (`mvvm-in-centron.md`, `requests-and-responses.md`) waren leer oder unvollständig, sodass zentrale Architekturmuster aus Namenskonventionen und Nachbardokumenten rekonstruiert werden mussten (siehe embedded Hypotheses zu SwRS-ARCH-04/05).
|
||||
- Cluster **BILL**: 4 von 30 Anforderungen (13 %) mussten wegen fehlendem PRIMÄR-Beleg nachträglich auf HYPOTHESE korrigiert werden (Abschnitt 3, Punkt 4) — deutet darauf hin, dass die ZUGFeRD-Feldzuordnungsdokumentation zwar inhaltlich sehr detailliert, aber nicht durchgängig mit dem tatsächlichen Quellcode gegengelesen wurde.
|
||||
- Cluster **CRM**: mit 7 von 28 Anforderungen (25 %) der höchste Hypothesen-Anteil — v. a. offene Fragen zu Dubletten-Erkennung, Nebenläufigkeitssicherheit der Kundennummernvergabe und uneinheitlicher USt-IdNr.-Führung.
|
||||
- Cluster **NEX**: ebenfalls hoher Hypothesen-Anteil (7 von 25) — CentronNexus als separate Web-/Blazor-Anwendung wurde primär über die Backend-Anbindung (`Centron.BL`), weniger über den eigentlichen Frontend-Code analysiert.
|
||||
|
||||
**Empfehlungen für eine Folge-Iteration:**
|
||||
1. **Deployment-/Betriebsartefakte nachholen** (`deployment/`, `docker/`, `azure/`) — bislang komplett unanalysiert, obwohl der Auftrag ausdrücklich Betriebs- und Sicherheitsanforderungen aus solchen Artefakten fordert.
|
||||
2. **WPF-UI-Schicht (Views/ViewModels) gezielt vertiefen**, insbesondere dort, wo SwRS-Anforderungen bislang nur auf BL-Ebene belegt sind, UI-seitige Validierung aber ggf. abweicht (Konsistenz Client-/Serverprüfung, vgl. Befund zu Aktionspreisen).
|
||||
3. **Die 4 auf HYPOTHESE korrigierten BILL-Anforderungen sowie alle als "eingebettete Teilhypothese" markierten Punkte** gezielt im Quellcode nachverifizieren, bevor sie als Migrationsgrundlage dienen.
|
||||
4. **Bislang nicht analysierte Module mit vermutetem Sicherheits-/Compliance-Bezug priorisieren**, insbesondere `ArtificialIntelligence` (KI-Funktionen, Datenschutzrelevanz), `SelfCare`/`MyCentron` (weitere Kundenportal-Varianten neben WebAccount) und `Mobile`.
|
||||
5. **Testprojekte (`tests/*`) als zusätzliche Beleg-/Validierungsquelle heranziehen** — Testfälle enthalten häufig präzise, ausführbare Beschreibungen von Geschäftsregeln und könnten insbesondere HYPOTHESE-Einträge in PRIMÄR-belegte Anforderungen umwandeln.
|
||||
6. **Cluster-übergreifende Konsolidierung vertiefen** (Abschnitt 4) — die dort identifizierten fünf Kandidaten sollten in einer Folge-Iteration in konkrete, zusammengeführte Ziel-Anforderungen überführt werden, statt (wie hier) nur als Hinweis dokumentiert zu sein.
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
# Glossar — CentronERP
|
||||
|
||||
Domänenbegriffe, die in den Anforderungen von StRS/SyRS/SwRS verwendet werden. Zusammengeführt aus den elf Analyseclustern (Kürzel in Klammern = Cluster, in dem der Begriff zuerst/hauptsächlich verwendet wird; ein Begriff kann in mehreren Clustern relevant sein). Bei mehrfach vorkommenden Begriffen mit unterschiedlicher Nuance ist dies vermerkt; bei zwei fachlich unterschiedlichen Konzepten mit gleichlautendem deutschem Begriff sind beide getrennt aufgeführt.
|
||||
|
||||
- **Abschlussgrund (Complete Reason)** (SALES): Stammdatensatz, der beim Schließen eines Angebots den Grund für dessen Abschluss (z. B. Nichtzustandekommen) dokumentiert.
|
||||
- **AccountDevice** (LOG): Im System verwaltetes Kundengerät (Hardware-Asset beim Kunden), u. a. mit Support-Tickets verknüpft, per Soft-Delete verwaltet.
|
||||
- **Adviser1I3D…Adviser6I3D ("Betreuer")** (CRM): Kundenbezogene Zuordnung mehrerer Mitarbeiterrollen (Innendienst, Außendienst, Techniker 1/2, zwei weitere unbenannte Rollen).
|
||||
- **AESCryptoLogic** (SEC): AES-basierte Verschlüsselungskomponente für schützenswerte Zugangsdaten im aktiven Passwort-Manager-Modul (`PasswordManagerBL`).
|
||||
- **Aktionspreis (ActionPrice)** (BILL): Zeitlich befristeter Sonderpreis eines Herstellers/Distributors für einen Artikel, angezeigt in der Preismatrix im Gültigkeitszeitraum.
|
||||
- **AnlageLog** (BILL): Zentrale, belegtypübergreifende Protokolltabelle für Audit-Log-Einträge (Erstellung, Änderung, Abrechnung, Kündigung etc.), referenziert Belege über `AnlageI3D`+`AnlageArt`.
|
||||
- **Angebot (Offer)** (SALES): Unverbindliches Vertriebsdokument, Startpunkt der Belegkette; kann in Auftrag, Lieferschein oder Rechnung weitergeleitet werden.
|
||||
- **Anrede/Abrede** (DOC): Textbausteine am Anfang ("Anrede", z. B. Begrüßung) bzw. Ende ("Abrede", z. B. Grußformel/AGB-Hinweis) eines Belegs oder einer Mail.
|
||||
- **Anzahlungsrechnung (Down Payment Invoice)** (SALES): Aus einem Auftrag erzeugte, mit diesem referenziell verknüpfte Rechnung über eine Vorauszahlung.
|
||||
- **AppGroup / Sichrech / Sichtrus / Sichmemb** (SEC): Rechte-Datenmodell — `Sichrech` = Rechte-Katalog, `Sichmemb` = Zuordnung Benutzer↔Gruppe, `Sichtrus` = Zuordnung Gruppe↔Recht, `AppGroup` = objektorientiertes Pendant zur Gruppen-Entität.
|
||||
- **ApplicationKind** (ARCH, SEC): Katalog aller Client-Anwendungen, die sich am c-entron-Web-Service anmelden dürfen (z. B. c-entron.NET, Service-Board, WebCart), mit zugehöriger Lizenz-GUID, Ablaufverhalten und optional einem erforderlichen/ausschließenden Recht.
|
||||
- **ApplicationSettings vs. Stammdat** (ADM): Zwei parallel existierende DB-Ablagen für Systemeinstellungen — `Stammdat` (historisch, Zugriff über `AppSettingsConst`) vs. `ApplicationSettings` (aktuell, Zugriff über `ApplicationSettingID`).
|
||||
- **AppointmentRequest (Terminanfrage)** (TIME): An einen Kunden versendeter Vorschlag mehrerer möglicher Termine; Rückmeldung wird über Microsoft Exchange verarbeitet.
|
||||
- **AppUser (Sichbenu)** (SEC): Interner c-entron-Mitarbeiterbenutzer, gespeichert in Tabelle `Sichbenu`; eigenes Passwortfeld, Aktivierungsstatus, Verknüpfung zu `Employee`. Abzugrenzen von `Employee` (Personal-Stammdaten der Person selbst) — beide führen eigene, nicht deckungsgleiche "aktiv"-Konzepte (CRM).
|
||||
- **Auftrag (Order)** (SALES): Verbindlicher Kundenbeleg, entsteht ausschließlich aus einem Angebot; kann in Lieferschein, Rechnung oder Vertrag weitergeleitet werden.
|
||||
- **Barcode / Seriennummer** (LOG): Synonym verwendete Begriffe für ein einzeln identifizierbares Exemplar eines Artikels, verfolgt über einen eigenen Zustandsautomat (`BarcodeState`).
|
||||
- **Beleg (Receipt)** (SALES, TIME, BILL): Sammelbegriff für alle im System verwalteten Geschäftsdokumente (Angebot, Auftrag, Lieferschein, Rechnung, Gutschrift, Abholliste, Vertrag, Bestellung, Wareneingang etc.), abgebildet über ein gemeinsames polymorphes Framework (`IReceiptBase`, `ReceiptBL`); im Zeiterfassungskontext insbesondere die Zielbelege der Timer-Abrechnung (Auftrag, Lieferschein, Rechnung).
|
||||
- **Belegnummernkreis (NumberGroup)** (BILL): Konfigurierbarer, meist mandantenweiter Zähler zur eindeutigen, race-condition-sicheren Vergabe von Belegnummern (Rechnungen, Verträge etc.).
|
||||
- **Bestellung (SupplierOrder)** (SALES): Einkaufsseitiger Beleg an einen Lieferanten; kann ausschließlich in einen Wareneingang (SupplierDeliveryList) weitergeleitet werden.
|
||||
- **Bestellvorschlagsliste (BVL, OrderSuggestionList)** (SALES): Zentrales Einkaufswerkzeug, das offenen Bedarf aus Artikeln, Aufträgen und Lagerbeständen konsolidiert zur Bestellauslösung an Lieferanten vorschlägt.
|
||||
- **BillingStateI3D** (TIME): Feld an der Ticketzeit, das den Abrechnungszustand referenziert (z. B. offen/reserviert/nicht abrechnen).
|
||||
- **Calculable (Abrechenbarkeit)** (TIME): Boolesches Flag an einer Ticketzeit, das angibt, ob die Zeit grundsätzlich in Rechnung gestellt werden darf.
|
||||
- **CentronModuleCategory** (ARCH): Enum zur fachlichen Gruppierung aller registrierten Module (z. B. Sales, Ticket, Billing, Administration); verwandtes Konzept zur "Modulkategorie" (ADM) für die UI-Gruppierung.
|
||||
- **CentronWebserviceMailType** (ADM): Zentrale Einstellung, die das E-Mail-Transportprotokoll (SMTP, Exchange/EWS oder Microsoft Graph) für den serverseitigen Mailversand festlegt.
|
||||
- **ContractArticleReferenzes** (BILL): Verknüpfungsentität zwischen einem Vertragsartikel und den zugehörigen RMM-Abrechnungsregeln (Kontingentmenge, Über-/Unterbuchungsdeckelung).
|
||||
- **COP** (INT): Externer Produktdatendienst, der über eine SOAP-Schnittstelle Artikeldaten, verwandte Produkte und Lieferantenzuordnungen bereitstellt.
|
||||
- **CrmProject** (TIME): Vertriebsprojekt (Kundenprojekt) mit Umsatz-/Margenprognose, Beratern und Entscheidungsdatum, losgelöst von der reinen Ticketbearbeitung.
|
||||
- **Direktlieferung — zwei unterschiedliche Bedeutungen:**
|
||||
- *Auftragsmerkmal* (`IsDirectDelivery`, LOG): kennzeichnet eine direkte Lieferung ohne Zwischenlagerung/Standardkommissionierung und beeinflusst z. B. den Versand von Kommissionierungs-E-Mails.
|
||||
- *Streckengeschäft* (SALES): Beschaffungsvariante, bei der eine Lieferantenbestellung direkt für einen konkreten Kundenauftrag ausgelöst wird, ohne über das eigene Lager zu laufen; Liefertermine werden zwischen Bestellung und Auftrag synchronisiert.
|
||||
- **DMS-Sync** (DOC): Kennzeichnung, ob/wann ein `Document` in ein externes Dokumentenmanagementsystem synchronisiert wurde (Felder `DMSSyncUniqueID`, `DMSSyncDate`, `DMSSyncType`, `DMSSyncEmployeeI3D`).
|
||||
- **DocBee** (TIME): Externes mobiles Zeiterfassungssystem, das Zeitbuchungen über eine definierte Schnittstelle an CentronERP übermittelt.
|
||||
- **docuFORM** (DOC): Name eines externen Drittsystems für Multifunktionsdrucker-Fleet-Management (Geräte, Zählerstände), angebunden über `Centron.Api.docuFORM` per REST/OAuth2 — **nicht** zu verwechseln mit Dokumentgenerierung.
|
||||
- **DocuBoard** (DOC): Namespace/Ordnername im Quellcode (`Centron.BL/DocuBoard`), der entgegen der Erwartung **kein** Dokumentenmodul bezeichnet, sondern IT-Asset-/Gerätemanagement (Partner, Artikelzuordnung, AD-Systembenutzer-Ausschluss). Die eigentliche Dokumentenverwaltung liegt unter `Administration/FileManagement`.
|
||||
- **Domain-Blacklist** (ADM): Liste gesperrter Empfänger-Domains/-Muster, gegen die jede Ziel-E-Mail-Adresse vor dem Versand geprüft wird.
|
||||
- **Dongle-ID** (ARCH): Aus der Lizenz abgeleitete Kundennummer, u. a. zur Identifikation einer c-entron-Installation in Analytics/Telemetrie.
|
||||
- **DSGVO-Löschung (Anonymisierung)** (CRM): Prozess, bei dem personenbezogene Daten einer Kontaktperson auf Anfrage entfernt/überschrieben werden, ohne den Datensatz technisch vollständig zu löschen (Soft-Anonymisierung mit Audit-Trail).
|
||||
- **DueDateDelayInHours** (NEX): Prioritätsabhängige Vorlaufzeit (Stunden) zur automatischen Berechnung des Fälligkeitsdatums eines Tickets.
|
||||
- **EDI (Electronic Data Interchange)** (INT, SALES): Automatisierter, strukturierter elektronischer Austausch von Geschäftsdokumenten (Bestellung, Auftragsbestätigung, Lieferschein, Rechnung) zwischen Handelspartnern ohne manuelle Neuerfassung; im Einkauf u. a. für automatisiert eingespielte Auftragsbestätigungen genutzt.
|
||||
- **EGIS** (INT): Elektronische Bestell-/Rechnungsaustauschplattform für die IT-Distribution, angebunden über XML-basierte HTTP-Requests.
|
||||
- **EscalationLevel** (NEX): Numerisches Feld am Ticket, das die zuletzt erreichte Eskalationsstufe (0–3) speichert.
|
||||
- **ESR/QR-Referenz** (ADM): Schweizer Zahlungsreferenzverfahren (Einzahlungsschein mit Referenznummer bzw. QR-Rechnung); je Mandant eines von bis zu vier Bankkonten als aktives Referenzkonto wählbar.
|
||||
- **Fertigungsauftrag (ArticleProductionOrder)** (LOG): Konkreter, ausführbarer Auftrag zur Produktion einer Artikelmenge auf Basis einer Stückliste und definierter Fertigungsschritte.
|
||||
- **Festschreibung (IsFixed)** (BILL): Zustand einer Rechnung, ab dem inhaltliche Änderungen softwareseitig gesperrt sind (typischerweise nach Buchung/Export).
|
||||
- **Filiale (Branch)** (ARCH): Niederlassung eines Mandanten mit eigenen Nummernkreisen und rechtebasierten Einschränkungen (z. B. Recht "nur eigene Filiale"); genaue Abgrenzung zu "Mandant" laut Recherche nicht abschließend geklärt.
|
||||
- **Freigabewesen — zwei unterschiedliche Bedeutungen:**
|
||||
- *Cart-Release-Workflow* (SALES): mehrstufiger Genehmigungsprozess für Web-Warenkörbe mit Rollen Ersteller, Prüfer ("Checker"), Besteller ("Orderer") und Zuständen Created → ReadyForCheck → Checked/DeclinedByChecker → Ordered/DeclinedByOrderer.
|
||||
- *CustomerApprovalEnabledSBO* (NEX): kundenspezifische Einstellung, ob von Kunden über das Portal erstellte Tickets vor Sichtbarkeit für den Support intern freigegeben werden müssen.
|
||||
- **FTP/FTPS/SFTP** (INT): Drei Dateiübertragungsprotokolle für den EDI-Dateiaustausch mit Lieferanten — FTP unverschlüsselt, FTPS mit TLS auf FTP-Basis, SFTP eigenständig SSH-basiert verschlüsselt.
|
||||
- **GfK** (INT): Marktforschungsinstitut, an das aufbereitete Verkaufs-/Bestandsdaten zur Branchenauswertung (Sell-out-Reporting) übermittelt werden.
|
||||
- **Group Setting Class** (ADM): Serverseitige Business-Logic-Klasse, die mehrere fachlich zusammengehörige Einstellungen lädt, typisiert kapselt (DTO) und über eine dedizierte API bereitstellt, statt direkten Tabellenzugriff zu erlauben.
|
||||
- **Handelsware / Warenpool (TradePool)** (SALES): Separater, über XML-Importe gespeister externer Artikelpool für Handelsware, unabhängig vom internen Artikelstamm, mit eigenem Kundenlogin-System.
|
||||
- **Hauptlager** (LOG): Zentrales, immer implizit vorhandenes Standardlager eines Mandanten (technisch häufig `I3D = -1`), abgegrenzt von benannten Nebenlagern.
|
||||
- **HelpdeskCreationTemplate** (NEX): Speicherbare Voreinstellung für die automatische Ticketerstellung aus Bestellpositionen (nicht identisch mit TicketPattern).
|
||||
- **HelpdeskEditor** (NEX): Zuordnungsentität zwischen einem Ticket (Helpdesk) und einem Mitarbeiter als Bearbeiter.
|
||||
- **HelpdeskState (Ticketstatus)** (NEX, TIME): Konfigurierbare Lookup-Entität für Ticket-Status (kein fester Enum); Administratoren können Status anlegen, deaktivieren und einen als "geschlossen" markieren — "geschlossen" ist also keine feste Codierung, sondern eine Einstellung.
|
||||
- **Hotline-Masterkey** (ADM): Zentral hinterlegtes, separat verwaltetes kryptografisches Geheimnis, mit dem weitere sensible Zugangsdaten (z. B. MailScanner-Postfachpasswörter, OAuth-Client-Secrets) zusätzlich AES-verschlüsselt werden; ohne Masterkey keine Ver-/Entschlüsselung möglich.
|
||||
- **I3D**: Durchgängig in der CentronERP-Codebasis und -Datenbank verwendete Bezeichnung für den Primärschlüssel (technische ID) einer Entität; funktionales Pendant zu einer generischen "Id"-Spalte, teils auch fachlich sichtbar (z. B. `CustomerNumber = I3D`).
|
||||
- **Icecat** (INT): Herstellerunabhängige, mehrsprachige Produktdatenbank (Datenblätter, Beschreibungen, Bilder), abgefragt per EAN oder Hersteller-Produkt-ID.
|
||||
- **Inventur (Stocktaking)** (LOG): Geschäftsvorgang zur Zählung und zum Abgleich des tatsächlichen mit dem gebuchten Lagerbestand, mit eigenem Zustandsautomat (offen/geschlossen/gelöscht, mit/ohne Seriennummernpflicht).
|
||||
- **IsOnlyInternalVisible** (NEX): Ticket-Flag, das ein Ticket vollständig vor Kunden-Logins verbirgt, unabhängig vom sonstigen Rechtelevel.
|
||||
- **ITScope** (INT): IT-Beschaffungs-/Marktplatzplattform, über die Bestellungen an mehrere Distributoren gebündelt sowie Produktdaten und Kontingent-Informationen (Quota) abgerufen werden.
|
||||
- **Kommissionierung** (LOG): Prozess der Zusammenstellung der für einen Auftrag benötigten Artikel/Seriennummern aus dem Lagerbestand vor der Lieferung.
|
||||
- **Kontingent (Vertrag)** (BILL): Im Wartungs-/Servicevertrag vereinbartes Leistungs- oder Geldvolumen, das über die Vertragslaufzeit durch Rechnungen verbraucht und durch Gutschriften wieder freigegeben wird.
|
||||
- **Kreditlimit (CreditLimit)** (SALES): Der einem Kunden zugewiesene maximale offene Forderungsbetrag; bei Überschreitung durch einen neuen Beleg wird ein Bestätigungsdialog ausgelöst.
|
||||
- **Kundenherkunft (CustomerAncestry)** (CRM): Stammdaten-Klassifikationswert, der die Herkunft/Quelle eines Kunden beschreibt (z. B. Akquisekanal); referenziert über `Customer.CustomerOriginI3D`.
|
||||
- **Leitweg-ID** (BILL): Adressierungs-/Routing-Code für öffentliche Auftraggeber in Deutschland, identifiziert die empfangende Behörde in einer XRechnung.
|
||||
- **LicenseGuids / LicenseManager** (ARCH, SEC): Zentrale Liste GUID-basierter Lizenzmerkmale (Anwendungen und einzelne Features); `LicenseManager.Instance.HasLicense(...)` prüft, ob eine GUID für den aktuellen Mandanten freigeschaltet ist.
|
||||
- **Lizenzmodul (ProductionManagement)** (LOG): Separat lizenzierbare Funktionsgruppe für Produktionsmanagement (Maschinen, Stücklisten, Fertigungsaufträge); ohne gültige Lizenz gesperrt/eingeschränkt.
|
||||
- **LogKind** (ADM): Statuswert einer Systembenachrichtigung (Successful, PartlyError, Error), u. a. für Filterung und automatisierte Fehleranalyse.
|
||||
- **Mahnstufe (Dunning Level)** (BILL, SALES): Eskalationsstufe (1–3) im Mahnwesen, an die Fristen, Gebühren und optionale Belegsperren gekoppelt sind; ab konfigurierbarem Schwellwert werden neue Belege für den betroffenen Kunden gesperrt.
|
||||
- **MailScanner / Virtual Mail Assistant (VMA)** (ADM): Komponente zum automatisierten Abholen/Verarbeiten eingehender E-Mails aus konfigurierten Postfächern; Profilzugriff über Recht `ACCESS_VMA_MODULE` geschützt.
|
||||
- **MailTemplateReference** (ADM): Eindeutige Kennzeichnung einer Mailvorlage über Kombination von ObjectKind, ObjectI3D, SubObjectKind und TemplatePrio.
|
||||
- **Mandant** (ADM, ARCH, CRM): Eine in sich abgeschlossene Unternehmens-/Firmeneinheit innerhalb von CentronERP mit eigenen Stammdaten (Logos, Bankverbindungen, Standardland); genau ein Mandant ist als Standard-Mandant markiert. Die genaue Abgrenzung zu "Filiale" ist laut ARCH-Recherche nicht abschließend geklärt.
|
||||
- **Matchcode** (CRM): Kurzbezeichnung/Suchbegriff eines Kunden, zusätzlich zum Namen für die Freitextsuche verwendet.
|
||||
- **MEF (Managed Extensibility Framework)** (ARCH): .NET-Technologie zum dynamischen Laden von Plugin-Assemblies zur Laufzeit; Basis der c-entron "Extension Engine".
|
||||
- **Mention-Syntax** (NEX): Im Kommentartext eingebettete Erwähnung eines Mitarbeiters im Format `[@Name:employeeI3D]`, löst eine gezielte Benachrichtigung aus.
|
||||
- **Mindestbestand (Meldebestand)** (LOG): Je Artikel und Lager konfigurierbare Bestandsschwelle, deren Unterschreitung eine automatische Bestellvorschlagsgenerierung auslöst.
|
||||
- **Mindestpreis (MinPrice)** (SALES): Je Artikel hinterlegter niedrigster zulässiger Verkaufsnettopreis; Unterschreitung erfordert besonderes Benutzerrecht oder Zweitfreigabe (Vier-Augen-Prinzip).
|
||||
- **ModuleFeatures** (ARCH): Zentrale Klasse mit booleschen Feature-Flags, über die Module unabhängig vom Rechtesystem ein-/ausgeblendet werden können.
|
||||
- **Modulkategorie** (ADM): Feste, lokalisierte Gruppierungsebene für Anwendungsmodule (z. B. "Vertrieb", "Abrechnung", "Administration") zur strukturierten Anzeige (u. a. Favoritenmenü); vgl. `CentronModuleCategory` (ARCH).
|
||||
- **MyDay ("Mein Tag")** (TIME): Modul zur tagesbezogenen Arbeitszeit-/Aktivitätsübersicht eines Mitarbeiters, gespeist u. a. aus Ticketzeiten, Kalender und Telefonie.
|
||||
- **MyDayWorkItem** (TIME): Einzelner Tageseintrag innerhalb von MyDay, z. B. ein aus einer Ticketzeit abgeleiteter Arbeitsblock.
|
||||
- **Nebenlager (SecondaryStock)** (LOG): Zusätzliches, benanntes Lager (z. B. Filiallager, Technikerfahrzeug, Projektlager) neben dem Hauptlager, mit eigener Bestandsführung je Artikel (`SecondaryStockArticle`).
|
||||
- **NeedsUserValidation** (INT): Datenbankflag an EDI-Belegköpfen; zeigt an, dass ein importierter Beleg vor endgültiger Übernahme noch manuell geprüft/zugeordnet werden muss.
|
||||
- **NexusNotification** (NEX): Datensatz für eine Push-Benachrichtigung im CentronNexus-System (Empfänger, Typ, Bezugsticket, Text), verteilt über einen SignalR-artigen Hub (`NotificationsHubHelper`).
|
||||
- **NexusTicketView** (NEX): Gespeicherte Filter-/Spaltenkonfiguration für die Ticketliste, persönlich oder global geteilt.
|
||||
- **NonCalculableTimersHandling** (TIME): Konfigurationsoption, die steuert, ob nicht abrechenbare Ticketzeiten beim Belegerzeugen ausgelassen oder mit Preis 0 ausgewiesen werden.
|
||||
- **NotificationUser** (ADM): Frei definierbarer Benachrichtigungsempfänger (nicht zwingend Systembenutzer) mit Name/Telefon/E-Mail, beliebigen Geschäftsobjekten zuordenbar.
|
||||
- **ObjectExternalReference** (TIME): Generischer Verknüpfungsmechanismus zwischen einem CentronERP-Objekt (z. B. Ticket, Ticketzeit) und einer ID in einem externen System (z. B. DocBee).
|
||||
- **OIDC / `oid`-Claim / OpenID Connect / Microsoft Entra ID** (ARCH, SEC): Standardprotokoll für föderierte Anmeldung; im ID-Token enthaltene eindeutige Objekt-ID des Benutzerkontos in Microsoft Entra ID, über die ein c-entron-Benutzerkonto mit dem externen Identitätsanbieter verknüpft wird — c-entron tauscht das Microsoft-ID-Token gegen ein eigenes Sitzungs-Ticket.
|
||||
- **OpenTrans 2.1** (INT): Herstellerneutraler XML-Branchenstandard für elektronischen Geschäftsdokumentenaustausch im IT-/Bürobedarfshandel, u. a. von ALSO als Basis verwendet.
|
||||
- **Pauschale / Ausgleichsartikel (Balance Item)** (SALES): Sammelposition (Flatrate) in einem Auftrag, gegen die einzelne Leistungen (z. B. Helpdeskzeiten) wertmäßig verrechnet werden.
|
||||
- **PasswordManager vs. PasswordManagementArea** (SEC): Zwei unterschiedliche, nicht zu verwechselnde Module — `PasswordManagerBL` (Hotline-/Kundenzugangsdaten, aktiv genutzt, AES-verschlüsselt, lizenzpflichtig) und `PasswordManagementArea`/`PasswordManagementKeywordBL` (vermutlich veraltetes Altmodul ohne wirksame Verschlüsselung).
|
||||
- **PDF/A-3b** (DOC): ISO-Standard zur Langzeitarchivierung von PDF-Dokumenten mit eingebetteten Dateianhängen (Voraussetzung für ZUGFeRD); erzwingt u. a. eingebettete Schriften.
|
||||
- **Produktmatrix (ProductMatrix)** (SALES): Werkzeug zur strukturierten Bewertung der Relevanz von Produktkategorien/-produkten je Kunde (Cross-/Upselling-Steuerung) mit Änderungshistorie.
|
||||
- **Provisionierung** (SALES): Automatisierte Zuordnung eines Provisionsempfängers (Kundenbetreuer) und -anteils zu einem neuen Auftrag anhand konfigurierbarer Regeln.
|
||||
- **PSD2** (INT): EU-Zahlungsdiensterichtlinie, die u. a. den regulierten Zugriff von Drittanbietern auf Bankkonten mit Einwilligung des Kontoinhabers ermöglicht.
|
||||
- **ReceiptState** (BILL, SALES): Einheitliche, belegtypübergreifende Statusmaschine mit den Werten Active ("offen"), Completed ("abgeschlossen") und Canceled ("storniert").
|
||||
- **ReportGroup/ReportData** (DOC): Grundstruktur der FastReport-basierten Reporting-Engine — `ReportGroup` bündelt Reports eines Belegtyps, `ReportData` ist der einzelne Report (FastReport-Definition, Base64-serialisiert) mit Parametern und Abfragen.
|
||||
- **Restricting Right (einschränkendes Recht)** (SEC): Sonderkategorie von Berechtigung, die eine bereits gewährte Sichtbarkeit zusätzlich einschränkt (z. B. "nur eigene Datensätze", "nur eigene Filiale"), statt zusätzliche Handlungen freizuschalten.
|
||||
- **Reverse Charge** (BILL): Umkehr der Steuerschuldnerschaft auf den Leistungsempfänger gem. §13b UStG; Rechnung weist 0 % USt. mit Hinweistext aus.
|
||||
- **RFID-Token** (CRM, LOG): Verschlüsselt gespeicherte Kennung eines physischen Transponders, einem Mitarbeiter zugeordnet — allgemein für Zutritts-/Zeiterfassung (CRM) bzw. speziell zur An-/Abmeldung an einer Maschine/einem Fertigungsschritt zur automatischen Arbeitszeiterfassung (LOG).
|
||||
- **RMA-Lager** (LOG): Spezielle, meist prozessbedingt gesperrte Lager für den Retouren-/Reklamationsprozess (Kunden-, Eigen-, Versand- und Auftragslager), von regulärer Lagerauswahl und ggf. Inventur ausgeschlossen.
|
||||
- **RMM (Remote Monitoring & Management)** (BILL): Externes System (in c-entron z. B. "Riverbird") zur Fernüberwachung von Kunden-IT-Infrastruktur, liefert Nutzungsdaten als Grundlage für nutzungsbasierte Vertragsabrechnung.
|
||||
- **RTF (Rich Text Format)** (ADM): Internes Speicherformat für formatierten Text in Mailvorlagen und Signaturen; Klartext wird bei Bedarf automatisch in RTF konvertiert.
|
||||
- **Schedule (Kalendertermin)** (TIME): Kalendereintrag, u. a. automatisch aus einer geplanten/gebuchten Ticketzeit erzeugt, mit Outlook/Exchange synchronisierbar.
|
||||
- **ScanBarcode (Seriennummernpflicht, "SN-Pflicht")** (LOG): Artikel-Flag, das festlegt, ob ein Artikel über individuelle Seriennummern (Barcodes) einzeln nachverfolgt oder rein mengenbasiert geführt wird.
|
||||
- **Sentinel-Datum (1900-01-01)** (CRM): Im Legacy-Datenmodell verwendeter technischer Ersatzwert für "kein Datum gesetzt" bei `LeavingDate`, anstelle von NULL.
|
||||
- **SEPA-Mandatsreferenz** (BILL): Eindeutige Referenznummer eines SEPA-Lastschriftmandats, ermächtigt den Bankeinzug beim Kunden.
|
||||
- **SEPA / PAIN.008** (INT): Single Euro Payments Area — einheitlicher europäischer Zahlungsverkehrsraum; PAIN.008 ist das ISO-20022-XML-Nachrichtenformat für SEPA-Lastschriften (banken-/länderspezifisch in mehreren Versionen, z. B. GBIC3/GBIC4).
|
||||
- **ServiceBoard** (NEX): Web-basierte Ticket-/Kanban-Oberfläche von CentronNexus für Support-Mitarbeiter.
|
||||
- **SHA1 / Salt** (SEC): SHA1 ist eine für Passwort-Speicherung als veraltet/schwach geltende Hash-Funktion; ein "Salt" ist ein zufälliger Zusatzwert vor dem Hashing gegen Rainbow-Table-Angriffe — im untersuchten Login-Code wird dieser Mechanismus nicht konsequent genutzt.
|
||||
- **ShowHelpdeskRight** (NEX): Rechtestufen-Enum (None/OnlyOwn/OnlyOwnBranch/All), bestimmt den Sichtbarkeitsumfang von Tickets für einen Benutzer.
|
||||
- **Soft-Delete** (LOG, DOC): Löschstrategie, bei der ein Datensatz nicht physisch entfernt, sondern nur als gelöscht markiert wird (`IsDeleted=true` bzw. entitätsspezifisches `State`-Flag), um Historie/Nachvollziehbarkeit zu erhalten (siehe auch **State-Flag**).
|
||||
- **Sonderpreise** (ARCH): Im c-entron.NET-Adressstamm hinterlegte kundenspezifische Preise, die die im WebCart sichtbaren Artikel/Preise für den jeweiligen Web-Account bestimmen.
|
||||
- **Standardadresse (DefaultCustomer) / DefaultCreditor** (CRM): Die als Vorgabe markierte Adresse eines Kunden (pro Kunde genau eine) bzw. analog die Standard-Lieferantenadresse bei Kreditoren.
|
||||
- **State/Locked** (CRM): Zwei getrennte Felder zur Steuerung der Nutzbarkeit eines Kunden — `State` (aktiv/inaktiv als Ganzzahl) und `Locked` (Sperr-Flag); beide müssen für "aktiv nutzbar" positiv sein.
|
||||
- **State-Flag** (DOC): Wiederkehrendes Muster in mehreren Entitäten (Documentation, TextModule, ReportData), bei dem ein Integer-Feld `State` (0/1) Aktivierung bzw. logisches Löschen (Soft-Delete) abbildet statt physischem Löschen.
|
||||
- **Stückliste (BOM, `ArticleProductionMaterial`)** (LOG): Liste der für die Fertigung eines Artikels benötigten Materialkomponenten und Mengen.
|
||||
- **Stundenzuschlag (HourlySurchargeRate)** (TIME): Prozentualer Auf-/Abschlag auf den Artikelpreis, abhängig von Wochentag, Uhrzeit oder Feiertag auf abgerechnete Zeiten angewendet.
|
||||
- **SystemAuthenticationMethod** (ARCH): Systemweite Einstellung, die das primär zu verwendende Authentifizierungsverfahren (None/Basic/ActiveDirectory/OpenIdConnect) festlegt.
|
||||
- **TAPI** (ARCH): Telephony API — Windows-Standardschnittstelle für Telefonie-Integration, hier über die modifizierte Drittanbieterkomponente TraySoft AddTAPI.NET genutzt.
|
||||
- **TaskManagementTask** (TIME): Wiederkehrende, automatisiert ausgeführte Aufgabe (z. B. automatische Ticketerstellung oder Report-Versand) mit konfigurierbarem Wiederholungsrhythmus.
|
||||
- **Teil-Kommissionierung (PartialCommissionOrder)** (LOG): Kommissionierungssatz, der nur einen Teil der Positionen/Mengen eines Auftrags abdeckt, mit eigenem Fortschrittsstatus (unvollständig/vollständig/teilweise/geliefert).
|
||||
- **Textbaustein (TextModule)** (DOC): Konfigurierbarer, wiederverwendbarer Textabschnitt (Anrede/Abrede/Prozesstext) mit Platzhaltern, kunden-, benutzer- oder global-spezifisch hinterlegbar.
|
||||
- **Ticket — zwei unterschiedliche Bedeutungen:**
|
||||
- *Sitzungs-Ticket* (ARCH, SEC): serverseitig ausgestellter, zeitlich begrenzter Authentifizierungs-Token (Plain-Text-String, hier 30 Minuten gültig) nach erfolgreichem Login, dient bei jedem API-Aufruf als Authentifizierungsnachweis.
|
||||
- *Helpdesk-/Support-Ticket* (NEX, TIME): fachlicher Vorgang im Ticket-/Helpdesksystem, Basis der Ticketzeiterfassung und Kundenkommunikation.
|
||||
- **TicketPattern** (NEX): Vordefinierte Vorlage zur Ticketerstellung mit vorbelegten Feldern (Typ, Kategorie, Beschreibung, Abteilung etc.).
|
||||
- **TicketProject** (TIME): Projekt-Objekt, das mehrere Tickets/Aufgaben bündelt und mit eigenem Status, Terminplan und Fortschritt geführt wird.
|
||||
- **TicketProjectDependency** (TIME): Abhängigkeitsbeziehung zwischen zwei Objekten eines Ticketprojekts nach dem Gantt-Prinzip (z. B. Ende-Anfang).
|
||||
- **Ticketzeit / HelpdeskTimer** (TIME): Auf einem Ticket erfasster Zeiteintrag eines Mitarbeiters mit Start-, Stopp- und Pausenzeit, Basis der späteren Abrechnung.
|
||||
- **Timer-Abrechnung (TimerBilling)** (TIME): Vorgang, bei dem erfasste Ticketzeiten gebündelt in Positionen eines Auftrags, Lieferscheins oder einer Rechnung überführt werden.
|
||||
- **Titelposition** (BILL): Gruppierende Rechnungsposition, die mehrere untergeordnete Artikelpositionen zusammenfasst; kann beim E-Rechnungsexport nur eingeklappt (aggregiert) exportiert werden.
|
||||
- **USt-IdNr. (Umsatzsteuer-Identifikationsnummer)** (CRM): Steuerliche Kennung eines Geschäftspartners für innergemeinschaftliche Geschäfte; im System an mehreren Stellen redundant geführt.
|
||||
- **Vier-Augen-Prinzip** (SALES): Kontrollmechanismus, bei dem eine kritische Aktion (hier: Preis unterhalb Mindestpreis) nur nach Freigabe/Authentifizierung durch eine zweite, berechtigte Person zulässig ist.
|
||||
- **Warenkorb (ReceiptCart)** (SALES): Technisch als Angebot mit zusätzlichem `CartState` geführter, über das Kunden-Web-Portal erstellter Bestellvorgang.
|
||||
- **WEEE**: Abkürzung für "Waste Electrical and Electronic Equipment" (Elektro-/Elektronikgerätegesetz); im System eine Pflichtnummer je Artikelposition für WEEE-pflichtige Artikel in Aufträgen (SALES).
|
||||
- **WebAccount** (ARCH, CRM, NEX, SEC): Eigener Kontotyp für externe Kunden (Kunden der Kunden), getrennt vom internen Mitarbeiter-Login (`AppUser`), u. a. für WebCart/CentronNexus-Kundenportal genutzt — technisch im selben Login-Namensraum eindeutigkeitsgeprüft wie interne Konten, ggf. mit mehreren verknüpften Kontaktpersonen (Multi-Web-Account).
|
||||
- **WebHook** (INT): Technisches Muster, bei dem das System bei einem Ereignis proaktiv eine HTTP-POST-Nachricht an eine vom Empfänger vorgegebene URL sendet (Gegenstück zum Polling-Modell).
|
||||
- **Weiterleitung/Forwarding (Belegkette)** (SALES): Vorgang, bei dem Positionen eines Belegs (z. B. Angebot) in einen Folgebeleg (z. B. Auftrag) übernommen werden; technisch über `ReceiptBL.ForwardReceipt()` und je Belegart erlaubte Quell-/Zielarten gesteuert.
|
||||
- **XRechnung** (BILL): XML-basiertes E-Rechnungsformat nach EN16931, in Deutschland verpflichtend für Rechnungen an öffentliche Auftraggeber; benötigt zwingend eine Leitweg-ID.
|
||||
- **ZUGFeRD** (BILL, DOC, INT): Deutsches Hybridformat für elektronische Rechnungen, kombiniert ein menschenlesbares PDF/A-3-Dokument mit eingebettetem strukturiertem XML (Cross Industry Invoice).
|
||||
- **c-entron Nexus** (ARCH): Separate, web-/Blazor-basierte Anwendung ("c-entron Web") für externe Web-Accounts (u. a. WebCart-Shop), ergänzend zum WPF-Desktop-Client; Basis des CentronNexus-Ticket-/Helpdesksystems.
|
||||
- **ebInterface** (INT): Österreichischer nationaler Standard für strukturierte XML-E-Rechnungen, u. a. verpflichtend für Rechnungen an österreichische Bundesbehörden.
|
||||
- **finAPI** (INT): Deutscher Multibanking-/Kontoinformationsdienstleister (Third-Party-Provider), über den PSD2-konform auf Bankkonten und Kontoumsätze zugegriffen wird.
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
# Hypothesen — offene Punkte für Schritt 7 (fachliche Validierung)
|
||||
|
||||
Alle Anforderungen mit Status `HYPOTHESE` aus StRS/SyRS/SwRS, gruppiert nach Analysecluster. Jede Zeile nennt die betroffene ID, den Titel und die fehlende Information, die zur Bestätigung nötig wäre.
|
||||
|
||||
**Hinweis zur Vollständigkeit:** Die Cluster-Agenten haben zwei unterschiedliche Notationsformen für Unsicherheit verwendet: (a) Status **strikt** `HYPOTHESE` für Anforderungen, die insgesamt unbestätigt sind (siehe Abschnitte unten), und (b) Status `belegt` mit einer **eingebetteten** `[HYPOTHESE]`-Markierung für einen einzelnen Detailaspekt einer ansonsten belegten Anforderung. Da beide Formen laut Auftragsstellung ("alle mit `[HYPOTHESE]` markierten Aussagen") erfassungspflichtig sind, werden Fall (b) gesondert im Abschnitt "Eingebettete Teilhypothesen" am Ende dieses Dokuments aufgeführt.
|
||||
|
||||
## Anwendungsarchitektur & Systemrahmen (ARCH)
|
||||
|
||||
|
||||
- **SwRS-ARCH-06** (Fehlende repository-interne Web-Service-API-Referenz): Die zentrale Web-Service-API-Dokumentation existiert offenbar nur als externe PDF auf einem internen Netzlaufwerk (`P:\Entwicklung C#\...`); diese war im Rahmen der Recherche nicht zugreifbar, sodass unklar bleibt, ob/wo eine vollständige, versionierte API-Referenz für die c-entron Web-Service-Schnittstelle tatsächlich existiert.
|
||||
|
||||
|
||||
## Sicherheit & Berechtigungen (SEC)
|
||||
|
||||
|
||||
- **SyRS-SEC-16** (Fehlender Brute-Force-Schutz bei Login-Versuchen): Kein Beleg im Anwendungscode für Zähler fehlgeschlagener Logins, Kontosperrung oder Rate-Limiting gefunden; offen ist, ob dies auf Infrastrukturebene (Reverse Proxy/WAF/API-Gateway) oder für AD-Logins über Active-Directory-eigene Kontosperrrichtlinien abgedeckt wird - im untersuchten Code-Cluster nicht einsehbar.
|
||||
- **SwRS-SEC-05** (Zwei parallele, unabhängige 2FA-Subsysteme): Offen ist, in welchem konkreten Aufrufkontext (welche UI-Aktion, welcher Workflow) `TwoFactorAuthenticationBL.ValidateAuthenticationPin` tatsächlich im Produktivbetrieb verwendet wird - nur die Definition der Klasse wurde gelesen, nicht ihre Aufrufer.
|
||||
- **SwRS-SEC-06** (Legacy-Passwortmodul ohne wirksame Verschlüsselung): Offen ist, ob das Modul `PasswordManagementArea` noch aktiv von der WPF-UI referenziert wird oder bereits vollständig durch das Hotline-basierte Passwort-Manager-Modul (`PasswordManagerBL`) ersetzt wurde - dazu wäre eine Prüfung der UI-Referenzen/Aufrufer nötig, die in dieser Recherche nicht durchgeführt wurde.
|
||||
|
||||
|
||||
## Stammdaten: Geschäftspartner, Kunden, Mitarbeiter (CRM)
|
||||
|
||||
|
||||
- **StRS-CRM-01** (Statusmodell für Geschäftspartner): Ob Lieferanten-Sperre über ein anderes Feld/Modul realisiert wird – im gesichteten `Supplier`-Entity fehlt ein zu `Customer.Locked` äquivalentes Feld.
|
||||
- **StRS-CRM-04** (Dubletten-Erkennung und Zusammenführung von Geschäftspartnern): Negativbefund (keine Dubletten-/Merge-Logik gefunden) beruht auf gezielter Grep-Suche über einen begrenzten Verzeichnisbereich; nicht abschließend geprüft, ob Logik in einem nicht durchsuchten Modul oder externen Tool existiert.
|
||||
- **SyRS-CRM-07** (Rechtebeschränkung Kundenzugriff): Ob `RIGHT_KUNDENSTAMM` und `SEARCH_CUSTOMER` bewusst unterschiedliche Berechtigungsstufen abbilden oder ein historisches Duplikat sind.
|
||||
- **SwRS-CRM-07** (Redundante USt-IdNr. ohne Formatvalidierung): Welches der drei redundanten Felder (`Address.AdressSalesTaxIdentificationNumber`, `CustomerFinanceInfo.SalesTaxIdentificationNumber`, `Customer.VATNotActive`) tatsächlich führend ist und ob eine Formatvalidierung an anderer, hier nicht durchsuchter Stelle existiert.
|
||||
- **SwRS-CRM-10** (Fehlende Duplikatsprüfung bei RFID-Tokens): Ob Eindeutigkeit von `RfidTokenEncrypted` ggf. per DB-Unique-Index sichergestellt ist – DAO-/Mapping-Definitionen wurden für dieses Cluster nicht vollständig durchsucht.
|
||||
- **SwRS-CRM-11** (Kundenbetreuerrollen (Adviser1-6)): Fachliche Bezeichnung/Verwendung von `Adviser5I3D`/`Adviser6I3D` ist im gesichteten Code nicht dokumentiert.
|
||||
- **SwRS-CRM-12** (Kundenindividuelle Pflichtangaben-Flags): Ob und wie `PurchaseOrderNumberRequiered`/`ProjNrNeeded`/`ProductionConfigurationRequiring` tatsächlich in der Auftragserfassung ausgewertet/durchgesetzt werden, wurde außerhalb dieses Clusters nicht verifiziert.
|
||||
|
||||
|
||||
## Vertrieb & Einkauf (SALES)
|
||||
|
||||
|
||||
In diesem Cluster trägt keine Anforderung den strikten Status "HYPOTHESE" (alle 32 Anforderungen sind primär durch Code belegt,
|
||||
Status "belegt" bzw. "belegt; Workaround"). Die folgenden drei Anforderungen enthalten jedoch einen dokumentierten offenen
|
||||
Punkt bzw. eine eingebettete Hypothese und werden nachrichtlich aufgeführt, da sie für die Konsolidierung relevant sein könnten:
|
||||
|
||||
- **SyRS-SALES-14** (Authentifizierung Handelspartner-Portal): Offen ist, ob das eigenständige TradeCustomerLogin-Verfahren (eigener Salt/Hash, losgelöst von AppUser/WebAccount) ein bewusst separates Legacy-System ist oder ob es künftig durch das zentrale Login-/Web-Account-System ersetzt werden soll; keine Information im Code darüber gefunden, ob dieses Verfahren noch aktiv genutzt wird.
|
||||
- **SwRS-SALES-11** (Blockade von Bar-Belegen): Offen ist, ob Barverkauf für die Web/SaaS-Neuimplementierung überhaupt als Anforderung gilt oder ob die aktuelle Blockade eine bewusste, dauerhafte Produktentscheidung ist; im Code kein Hinweis auf geplante Aufhebung gefunden.
|
||||
- **SwRS-SALES-13** (Manueller Angebotsabschluss (Legacy)): Offen ist, ob `OfferBL.CloseOfferByHand()` (CustomerAssets-Architektur) im aktuellen UI überhaupt noch erreichbar/aktiv ist, oder ob dieser Pfad bereits vollständig durch das neuere Receipt-Framework (`ReceiptOfferBL`/`OfferSpecificLogic`, siehe SwRS-SALES-10) abgelöst wurde; ohne Einsicht in die UI-Schicht nicht klärbar.
|
||||
|
||||
|
||||
## Abrechnung, Fakturierung & Verträge (BILL)
|
||||
|
||||
- **SyRS-BILL-19** (Standard-Steuersatz 19% bei leeren Titelpositionen): Regel nur durch zwei übereinstimmende Dokumentationsartefakte belegt (docs/reference/zugferd-feldzuordnung-anwender.md:331, docs/reference/zugferd-field-mapping.md:365), kein PRIMÄR-Codebeleg (konkrete Codezeile in `InvoiceZugferdBL.cs` für den 19%-Default nicht gegengelesen). Für den Risikobereich Abrechnung/Steuerberechnung ist vor Übernahme in die konsolidierte Spezifikation eine Verifikation im Quellcode nötig.
|
||||
|
||||
|
||||
## Zeiterfassung, Projekte & Tickets (intern) (TIME)
|
||||
|
||||
|
||||
Keine Anforderungen mit Status HYPOTHESE im Cluster TIME. Alle 35 Kandidaten sind mit Status "belegt" oder "belegt; Workaround" eingestuft (siehe SwRS-TIME-12 und SwRS-TIME-13 sowie SyRS-TIME-15 für die Workaround-Fälle mit eingeschränkter Belegtiefe bzw. beobachtetem Code-Defekt statt reiner Anforderung).
|
||||
|
||||
|
||||
## Lager, Logistik & Produktion (LOG)
|
||||
|
||||
|
||||
- **SyRS-LOG-15** (Schnittstellen zu Versanddienstleistern (GLS, Shipcloud)): Keine Tiefenanalyse der API-Projekte `Centron.Api.Gls` und `Centron.Api.Shipcloud` im Rahmen dieses Clusters durchgeführt - offen sind u.a. das genaue Statusmapping einer Sendung, die Fehlerbehandlung bei Übergabefehlern sowie ob/wie der Sendungsstatus in den Barcode-/Lieferschein-Zustandsautomaten dieses Clusters zurückgespielt wird.
|
||||
|
||||
|
||||
## Administration, Systemkonfiguration & Kommunikation (ADM)
|
||||
|
||||
|
||||
- **StRS-ADM-04** (Kontextabhängige E-Mail-Signaturen): Offen, ob die Signaturquelle "Outlook" (lokales Windows-Client-Profil/Registry) in einer Web-/SaaS-Architektur ohne lokalen Windows-Client überhaupt sinnvoll fortgeführt werden kann oder durch rein zentrale (Centron-)Signaturverwaltung ersetzt werden muss - im Code keine Migrationsentscheidung dokumentiert.
|
||||
- **SwRS-ADM-17** (Domain-Blacklist für Mailversand): Offen, welche fachliche Absicht hinter der Zeichen-für-Zeichen-Regex-Konstruktion für Nicht-"@"-Einträge steht (Sub-Domain-Wildcard vs. Teilstringsperre) - im Code nicht kommentiert, Klärung mit Fachbereich empfohlen.
|
||||
- **SwRS-ADM-18** (Objektspezifische Mail-Tracking-Schlüsselwörter): Offen, wie die konfigurierten Tracking-Keywords beim Mailempfang tatsächlich ausgewertet werden (Verknüpfungslogik zu MailScanner/Zuordnung eingehender Antworten wurde in diesem Rechercheumfang nicht gelesen).
|
||||
- **SwRS-ADM-19** (Rechteprüfung beim Zugriff auf MailScanner-Profile): Offen, ob `SaveProfile`, `DeleteProfile` und `SaveTasks` an anderer Stelle (z. B. WebService-/API-Schicht) ebenfalls rechtegeprüft werden - im gelesenen BL-Code selbst nicht erkennbar, nicht abschließend verifiziert.
|
||||
- **SyRS-ADM-06** (Externe Lizenzserver-Anbindung): Offen, ob/wie das aktuelle On-Premise-Lizenzmodell (Hardware-ID- und Einzeldatenbank-Bindung über externen c-entron-Office-Lizenzserver) auf eine Multi-Tenant-SaaS-Architektur übertragen werden soll - im Code keine Aussage zu einer geplanten SaaS-Lizenzierung.
|
||||
|
||||
|
||||
## Dokumente & Reporting (DOC)
|
||||
|
||||
- **SwRS-DOC-03** (S/MIME-Signaturprüfung bei archivierten E-Mail-Dokumenten): Unklar, ob die geloggte Warnung bei fehlgeschlagener S/MIME-Verifikation tatsächlich bis in die Benutzeroberfläche durchgereicht wird oder nur im Server-Log verbleibt — WPF-Client-Code wurde in diesem Cluster nicht geprüft.
|
||||
- **SyRS-DOC-08** (Schnittstelle zu externem Drucker-Fleet-Management docuFORM): Kein Aufrufer/Consumer des `DocuFormRestApiClient` wurde in `Centron.BL` innerhalb des untersuchten Bereichs gefunden; Verwendungszweck (Abrechnung? Controlling?) und aufrufende Business-Logik sind unklar, ggf. in einem anderen Cluster (Administration/Gerätemanagement) verortet.
|
||||
|
||||
|
||||
## Externe Integrationen & Schnittstellen (INT)
|
||||
|
||||
- **SwRS-INT-19** (Export von Verkaufsdaten für GfK-Marktforschung): Datei `GfkExportBL.cs` nur oberflächlich gesichtet (erste 60 Zeilen); genaues Exportformat (Feldstruktur), tatsächlicher Übertragungsweg (konkrete FTP-Zieladresse) und Trigger/Frequenz des Exports nicht verifiziert.
|
||||
|
||||
|
||||
## CentronNexus (Ticket-/Helpdesk-System) (NEX)
|
||||
|
||||
|
||||
- **StRS-NEX-01** (Kunden-Ticketerstellung mit optionalem internen Freigabeverfahren): Konkreter Freigabe-Workflow-Schritt, der ein Ticket mit `HelpdeskState == null` final in einen sichtbaren Status überführt, wurde in diesem Cluster nicht lokalisiert (evtl. Teil des CRM/Sales-Clusters - dortiges Rechercheergebnis abgleichen).
|
||||
- **StRS-NEX-03** (Annahme-/Ablehnungsworkflow für neue Tickets): Der Enum `HelpdeskAfterOpenAction { Reject, Accept }` wurde isoliert gefunden; die konsumierende UI-/BL-Logik liegt außerhalb der gelesenen Dateien. Fehlende Information: konkreter Aufrufkontext, Auswirkung von Reject (Ticket löschen? Status zurücksetzen? Rückmeldung an Kunden?).
|
||||
- **SyRS-NEX-06** (Echtzeit-Synchronisation des Ticketstatus zwischen Web und Outlook-Add-In): Der konkrete Transportmechanismus (SignalR-Hub-Name, Verbindung zu `NotificationsHubHelper`) wurde nicht im Detail verifiziert - `TicketUpdateService`-Implementierung liegt außerhalb der gelesenen Dateien.
|
||||
- **SyRS-NEX-09** (Konfigurierbare Freigabe-/Berechtigungsmatrix für externe Helpdesk-Anbindung): Es wurde keine Business-Logik gefunden, die die Flags `AllowHelpdeskCreation`/`AllowCloseHelpdesks`/`TicketReleaseSystemEnabled` zur Laufzeit auswertet. Fehlende Information: Wo/wie werden diese Flags konsultiert (Controller/WebServices außerhalb der Startpunkte)?
|
||||
- **SyRS-NEX-11** (Ticketerstellung aus E-Mail-Kontext im Outlook-Add-In): Die `CreateNewTicket`-Komponente selbst wurde in diesem Lauf nicht gelesen; exakte Feldvorbelegung (über MailSubject/AccountI3D hinaus) nicht verifiziert.
|
||||
- **SwRS-NEX-07** (Vorlagenverwaltung für automatische Ticketerstellung aus Bestellungen): Basiert nur auf Feature-Dokumentation, nicht auf Code (`HelpdeskCreationTemplateBL.cs` nicht gelesen). Fehlende Information: exakte Implementierungsdetails, z.B. ob `CreateSeparateTicketsMode.Custom` tatsächlich eine Positionsauswahl unterstützt.
|
||||
- **SwRS-NEX-09** (Definierter Ticket-Abschluss-Workflow inkl. ToDo-Bereinigung): `CanCloseHelpdesk`-Regeln (z.B. Pflichtfelder, offene Timer) wurden nicht im Detail gelesen (Datei `HelpdeskCloseBL.cs` nur Zeilen 1-140 von >300). Fehlende Information: genaue Ablehnungsgründe beim Schließen.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Eingebettete Teilhypothesen (Status: "belegt", mit punktueller `[HYPOTHESE]`-Markierung)
|
||||
|
||||
Diese 21 Anforderungen sind in ihrem Kern durch Artefakte belegt (Status `belegt` bzw. `belegt; Workaround`), enthalten aber einen ausdrücklich als `[HYPOTHESE]` gekennzeichneten Teilaspekt, der ebenfalls fachlicher Validierung bedarf.
|
||||
|
||||
### Anwendungsarchitektur & Systemrahmen (ARCH)
|
||||
- **StRS-ARCH-03** (Eingeschränkte Sprachauswahl im Produktivbetrieb): Produktentscheidung, ob Mehrsprachigkeit für Endkunden freigeschaltet werden soll, ist offen.
|
||||
- **StRS-ARCH-04** (Mandanten- und Filialverwaltung): Abgrenzung "Mandant" vs. "Filiale" nur aus Namensgebung/Icon abgeleitet, keine Fachdokumentation gelesen.
|
||||
- **StRS-ARCH-05** (WebCart als Kundenweb-Kanal): Detailarchitektur von c-entron Nexus (Blazor-Code) nicht gelesen, nur README ausgewertet.
|
||||
- **SwRS-ARCH-04** (Persistenz benutzerspezifischer UI-Layouts): Speicherort/Synchronisationsverhalten nicht verifiziert.
|
||||
- **SwRS-ARCH-05** (Einheitliches MVVM-Grundgerüst): Referenzdokumentation `mvvm-in-centron.md` leer/unvollständig; Muster nur aus Nachbardokumenten/Namenskonventionen rekonstruiert.
|
||||
- **SyRS-ARCH-03** (TOTP-basierte Zwei-Faktor-Authentifizierung): Kein Beleg gefunden, ob TOTP-2FA erzwingend (Pflicht) oder optional ist.
|
||||
- **SyRS-ARCH-04** (Entwickler-Schutz vor Kunden-E-Mail-Versand, DEBUG): Nur aus Dokumentation belegt, Quellcode `DeveloperSecurity.cs` nicht gegengelesen.
|
||||
- **SyRS-ARCH-12** (Anwendungsweite Command Palette): Bedeutung/Priorität aus Endnutzersicht nicht belegt, keine Nutzungsstatistik verfügbar.
|
||||
- **SyRS-ARCH-13** (Lizenz- und benutzerbezogene Nutzungstelemetrie): Opt-out-/Einwilligungsmechanismus (Consent-Handling) nicht verifiziert.
|
||||
- **SyRS-ARCH-17** (RDP-/Terminalserver-Reconnect-Behandlung, Workaround): Unklar, ob RDP-Betrieb weiterhin offizielle Systemvoraussetzung ist oder nur Altlast (Mechanismus im Code aktuell deaktiviert).
|
||||
|
||||
### Sicherheit & Berechtigungen (SEC)
|
||||
- **SyRS-SEC-10** (Serverseitige Validierung des Microsoft-ID-Tokens): Details zu erlaubten Signaturalgorithmen/Clock-Skew-Toleranz nicht verifiziert (`CentronHost.cs` nicht gelesen, nur Dokumentation ausgewertet).
|
||||
- **SyRS-SEC-12** (Zugriffsprotokollierung im Passwort-Manager): Unklar, ob es im aktuell aktiven Passwort-Manager-Modul (`PasswordManagerBL.cs`) ein Äquivalent zum dokumentierten Zugriffsprotokoll gibt; nur `PasswordManagerLog` für andere Zwecke gefunden.
|
||||
|
||||
### Stammdaten: Geschäftspartner, Kunden, Mitarbeiter (CRM)
|
||||
- **SwRS-CRM-04** (Automatische Vervollständigung von Kunde, Adresse, Ansprechpartner und Kundennummer): Kundennummernvergabe per `MAX(I3D)+1` ohne erkennbare Sperre/Transaktion — Nebenläufigkeitssicherheit gegen Race Conditions im gesichteten Code nicht erkennbar.
|
||||
|
||||
### Externe Integrationen & Schnittstellen (INT)
|
||||
- **StRS-INT-03** (Webservice-Schnittstelle für Partnersysteme): Authentifizierungsdetails des Ticket-Mechanismus (Lebensdauer, Erneuerung) im gesichteten Code nicht verifiziert.
|
||||
- **SwRS-INT-01** (FTP/FTPS/SFTP-Dateiübertragung mit ungeprüftem FTPS-Zertifikat): Keine Begründung im Code für die Zertifikatsausnahme (`ValidateAnyCertificate=true`) gefunden.
|
||||
- **SwRS-INT-04** (AES-Verschlüsselung gespeicherter EDI-Zugangsdaten): Speicherort/Rotation des AES-Schlüssels im gesichteten Code nicht ersichtlich.
|
||||
- **SwRS-INT-13** (Produktdatenabfrage über COP-SOAP-Schnittstelle): Aufrufzeitpunkt/Turnus (Trigger) nicht ermittelbar.
|
||||
- **SwRS-INT-16** (Live-Verfügbarkeitsabfrage bei Komsa): Unklare Feldsemantik — Feld "Additional" wirkt wie ein Passwortfeld, aber Datenmodell inkonsistent.
|
||||
- **SwRS-INT-17** (Generischer WebHook-Client für ausgehende Benachrichtigungen): Kein Wiederholungsmechanismus (Retry) im gesichteten Code erkennbar.
|
||||
- **SyRS-INT-07** (PSD2-Bankanbindung über finAPI): Kein Token-Refresh-Mechanismus im gesichteten Code gefunden, ggf. an anderer Stelle implementiert.
|
||||
- **SyRS-INT-08** (Verfügbarkeit und Betriebssicherheit der Webservice-Schnittstelle): Kein Beleg für einen zum Linux-Watchdog äquivalenten Mechanismus unter Windows gefunden.
|
||||
|
||||
---
|
||||
|
||||
## Nachträglich reklassifiziert: Abrechnungsanforderungen ohne PRIMÄR-Beleg
|
||||
|
||||
Diese vier Anforderungen waren im Rohbefund des Clusters BILL mit Status `belegt` markiert, obwohl nur ein `SEKUNDÄR`-Beleg (Dokumentation, nicht im Quellcode gegengelesen) vorlag. Da Abrechnungs-/Fakturierungslogik gemäß Auftragsstellung eine strengere Evidenzanforderung (mindestens ein `PRIMÄR`-Beleg, sonst zwingend `HYPOTHESE`) unterliegt, wurden sie im Rahmen des Konsistenzchecks auf Status `HYPOTHESE` korrigiert (siehe SyRS.md/SwRS.md).
|
||||
|
||||
- **SyRS-BILL-10** (Behandlung negativer Preise im E-Rechnungsexport): Vorzeichenbehandlung negativer Einzelpreise nur über Dokumentation und einen thematisch verwandten Code-Kommentar zur Rabattlogik indirekt gestützt; die tatsächliche Umsetzung selbst wurde nicht im Quellcode gegengelesen.
|
||||
- **SyRS-BILL-17** (Hierarchische Bankauswahl für E-Rechnungsexport): Bankauswahl-Hierarchie nur über Dokumentation belegt, Settlement-Bereich in `InvoiceZugferdBL.cs` nicht zeilengenau verifiziert.
|
||||
- **SwRS-BILL-03** (Gültigkeitsfilter für Aktionspreise in der Preismatrix): Filterlogik nur über Dokumentation mit Code-Referenz belegt, `PriceMatrixViewModel.cs` selbst nicht gegengelesen.
|
||||
- **SwRS-BILL-05** (AnlageLog-Audit-Eintrag für Vertragsereignisse, AnlageArt=22): Tabellenschema/AnlageArt=22 nur über Dokumentation belegt, korrespondierender Enum-/Konstantenwert nicht separat im Code verifiziert.
|
||||
+868
@@ -0,0 +1,868 @@
|
||||
# Stakeholder Requirements Specification (StRS) — CentronERP
|
||||
|
||||
Reverse Requirements Engineering — CentronERP. Erstellt am 2026-08-25 (Versuch 01, Iteration 01).
|
||||
|
||||
**ID-Konvention:** `StRS-<CLUSTER>-<laufende Nummer>`, wobei CLUSTER das fachliche Analysecluster kennzeichnet (siehe Cluster-Liste unten). Die Nummerierung ist je Cluster und Ebene fortlaufend, nicht global — Eindeutigkeit ist durch die Cluster-Präfixe gewährleistet.
|
||||
|
||||
**Cluster-Übersicht:**
|
||||
- `ARCH` — Anwendungsarchitektur & Systemrahmen
|
||||
- `SEC` — Sicherheit & Berechtigungen
|
||||
- `CRM` — Stammdaten: Geschäftspartner, Kunden, Mitarbeiter
|
||||
- `SALES` — Vertrieb & Einkauf
|
||||
- `BILL` — Abrechnung, Fakturierung & Verträge
|
||||
- `TIME` — Zeiterfassung, Projekte & Tickets (intern)
|
||||
- `LOG` — Lager, Logistik & Produktion
|
||||
- `ADM` — Administration, Systemkonfiguration & Kommunikation
|
||||
- `DOC` — Dokumente & Reporting
|
||||
- `INT` — Externe Integrationen & Schnittstellen
|
||||
- `NEX` — CentronNexus (Ticket-/Helpdesk-System)
|
||||
|
||||
---
|
||||
|
||||
## Anwendungsarchitektur & Systemrahmen (ARCH)
|
||||
|
||||
|
||||
ID: StRS-ARCH-01
|
||||
Titel: GUID-basiertes Lizenzmodell
|
||||
Ebene: StRS
|
||||
Typ: funktional / Lizenzierung
|
||||
Akteur: c-entron-Vertrieb, Kunde, Systemadministrator
|
||||
Vorbedingung: Kunde hat einen Lizenzvertrag
|
||||
Fakt: Lizenzen sind GUID-basierte Merkmale mit optionalem `count`, `valid until date`, `valid until version`. Es wird zwischen `Applications` (dürfen sich am Web-Service anmelden, Liste in `ApplicationKind.cs`, ca. 40 Einträge z.B. Centron, ServiceBoard, WebCart, PasswordManager, Outlook Add-In) und reinen Einzel-Feature-Lizenzen (`LicenseGuids.cs`) unterschieden. Single Source of Truth ist ein zentraler Lizenzserver.
|
||||
Aussage: Das System soll ein zentrales, GUID-basiertes Lizenzmodell mit Zähler-, Ablaufdatum- und Versionsbindung besitzen, das sowohl den Zugang ganzer Anwendungen als auch einzelner Features steuert.
|
||||
Ergebnis: Feingranulare kommerzielle Steuerung von Funktionsumfang und Zugriff; zentrale Voraussetzung für Feature-Gating in einer SaaS-Variante (z.B. Tarif-/Paketmodell).
|
||||
Belege:
|
||||
- [PRIMÄR] docs/reference/security/licensing-system.md:1-44 - Beschreibung GUID/count/valid until date/valid until version, Applications vs. Only Licenses
|
||||
- [PRIMÄR] src/backend/Centron.Interfaces/Administration/Logins/ApplicationKind.cs:11-53 - ca. 40 ApplicationKind-Einträge mit LicenseGuids, teils mit `licenseUsageKind: LicenseUsageKind.PerUser`, `expirationKind`
|
||||
- [SEKUNDÄR] src/backend/Centron.BL/Administration/Licensing/LicenseManager.cs:26-40 - ILicenseManager Interface (HasLicense, GetLicenseCount, CheckLicense)
|
||||
Prüfidee: Klären, ob Lizenzprüfung offline (Dongle/Cache) funktionsfähig bleibt und wie oft synchronisiert wird (`FileLicenseCache`, `UpdateLicenseInterval`).
|
||||
Tracelinks: SyRS-ARCH-02, SyRS-ARCH-13, SyRS-ARCH-15
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-ARCH-02
|
||||
Titel: Windows-Desktop-Systemvoraussetzung
|
||||
Ebene: StRS
|
||||
Typ: nicht-funktional (ISO25010: Kompatibilität / Systemumgebung)
|
||||
Akteur: IT-Administrator, Endanwender
|
||||
Vorbedingung: -
|
||||
Fakt: Der Client (`Centron.WPF.UI.csproj`) zielt auf `net10.0-windows`, ist ein `WinExe` (WPF, WinForms-Abhängigkeiten wie `System.Windows.Forms.Screen`), bindet COM-Interop zu Microsoft Outlook (`Microsoft.Office.Interop.Outlook`) sowie ein modifiziertes Drittanbieter-TAPI-Modul (`Traysoft.AddTapi.dll`) ein. `global.json` fixiert die .NET-SDK-Version auf 10.0.100.
|
||||
Aussage: Das System (c-entron.NET) soll als natives Windows-Desktop-Programm mit lokalen Windows-/Outlook-/TAPI-Abhängigkeiten betrieben werden und ist somit nicht plattformunabhängig.
|
||||
Ergebnis: Klare Systemvoraussetzung "Windows + .NET 10 Runtime + ggf. Outlook/TAPI-Hardware" für den Bestandsclient; zentrale Motivation für die geplante Web-/SaaS-Neuimplementierung (Plattformunabhängigkeit als Ziel).
|
||||
Belege:
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/Centron.WPF.UI.csproj:1-24 - TargetFramework net10.0-windows, WinExe, COM-Interop-Referenzen
|
||||
- [PRIMÄR] global.json:1-6 - SDK-Version 10.0.100
|
||||
- [SEKUNDÄR] docs/reference/architecture/tapi.md:1-10 - TAPI-Integration nur für Windows-Produkte (c-entron.NET, Outlook Add-In, ServiceBoard)
|
||||
Prüfidee: Abgleich mit Kunden-Systemvoraussetzungsdokument (falls vorhanden) auf weitere Hardware-/Software-Voraussetzungen (z.B. Terminalserver-Freigabe).
|
||||
Tracelinks: SyRS-ARCH-08, SyRS-ARCH-11, SyRS-ARCH-14, SyRS-ARCH-17
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-ARCH-03
|
||||
Titel: Eingeschränkte Sprachauswahl im Produktivbetrieb
|
||||
Ebene: StRS
|
||||
Typ: nicht-funktional (ISO25010: Internationalisierbarkeit) — Abweichung/Workaround
|
||||
Akteur: Endanwender
|
||||
Vorbedingung: LoginDialog wird angezeigt
|
||||
Fakt: Im `LoginDialogViewModel` wird die Sprachliste initial nur mit `de-DE` befüllt; `en-US` wird nur hinzugefügt, wenn `IsDevBuild` (Compile-Symbol `DEV_BUILD`) aktiv ist. Standardsprache ist explizit "German is the default language" (Kommentar im Code). Produktivbenutzer können in der UI somit i.d.R. nur Deutsch wählen, obwohl englische Ressourcendateien im Code existieren.
|
||||
Aussage: Das System soll (Soll-Zustand im Ist offen) die im Backend vorhandene Mehrsprachigkeit (Deutsch/Englisch) auch produktiv über die Login-/Spracheinstellung zugänglich machen.
|
||||
Ergebnis: Diskrepanz zwischen technischer Lokalisierungs-Infrastruktur (SyRS-ARCH-09) und tatsächlich für Endanwender nutzbarer Sprachauswahl; für SaaS-Zielbild zu klären, ob Mehrsprachigkeit ein echtes Geschäftsziel ist oder nur Entwickler-/Testzweck.
|
||||
Belege:
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Administration/Connections/LoginDialogViewModel.cs:93-98 - Languages.Add(en-US) nur `if (IsDevBuild)`
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Administration/Connections/LoginDialogViewModel.cs:197-206 - IsDevBuild liest Compile-Symbol DEV_BUILD
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Administration/Connections/LoginDialogViewModel.cs:239 - Kommentar "German is the default language."
|
||||
Prüfidee: Produktentscheidung/Product Owner befragen, ob Englisch-Support als Geschäftsziel für die Web-Neuimplementierung gilt (aktuell nur "verstecktes" Dev-Feature).
|
||||
Tracelinks: SyRS-ARCH-09
|
||||
Konsolidierung: nein
|
||||
Status: belegt (Soll-Zustand/Produktentscheidung zu Mehrsprachigkeit offen; HYPOTHESE: fehlende Produktentscheidung, ob Mehrsprachigkeit für Endkunden freigeschaltet werden soll)
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-ARCH-04
|
||||
Titel: Mandanten- und Filialverwaltung
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Kunde mit mehreren Gesellschaften/Niederlassungen, Administrator
|
||||
Vorbedingung: Lizenz "branch functionality" vorhanden (laut licensing-system.md Beispiel)
|
||||
Fakt: Es existiert ein Modul "Mandantenverwaltung" (`MandatorManagementAppModuleController`, ID `{717AD6A2-...}`, Kategorie Administration) sowie ein separates "BranchManagement" (Filialverwaltung, Nummernkreise) unter demselben Namensraum `Administration.MandatorManagement`.
|
||||
Aussage: Das System soll die Verwaltung mehrerer Mandanten/Gesellschaften bzw. Filialen (Niederlassungen) innerhalb einer c-entron-Instanz unterstützen, inklusive eigener Nummernkreise je Filiale.
|
||||
Ergebnis: Mehrmandantenfähigkeit auf Ebene "mehrere Unternehmenseinheiten in einer Datenbank" (kein Hinweis auf Datenbank-pro-Kunde-Mandantentrennung im Sinne von SaaS-Multi-Tenancy); wichtig für SyRS-Datenmodell-Entscheidung bei Neuimplementierung.
|
||||
Belege:
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Administration/MandatorManagement/MandatorManagementAppModuleController.cs:9-45 - Modul "Mandanten Verwaltung"
|
||||
- [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Administration/MandatorManagement/BranchManagement/* - BranchManagementView/ViewModel, NumberGroupsViewModel (Dateiliste)
|
||||
- [KONTEXT] CentronRights.md:14-26 - Rechte mit Filial-Einschränkung ("nur eigene Filiale") als Beleg für aktive fachliche Nutzung von Filialen/Mandanten in Rechten
|
||||
Prüfidee: Klären, ob "Mandant" hier = rechtlich eigenständige Gesellschaft (mit eigener Buchhaltung) oder nur Organisationseinheit ist; Datenmodell (MandantI3D-Spalten) verifizieren.
|
||||
Tracelinks: keine direkte Verknüpfung (Lücke)
|
||||
Konsolidierung: nein
|
||||
Status: belegt (Abgrenzung "Mandant" vs. "Filiale" nicht abschließend verifiziert; HYPOTHESE: Begriffsdefinition nur aus Namensgebung/Icon abgeleitet, keine Fachdoku gelesen)
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-ARCH-05
|
||||
Titel: WebCart als Kundenweb-Kanal
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Kunde des Kunden (Web-Account-Benutzer)
|
||||
Vorbedingung: Web-Account wurde in c-entron.NET Adressstamm angelegt, Sonderpreise hinterlegt
|
||||
Fakt: README.md beschreibt "WebCart" als Feature primär für Kunden der Kunden: Login als Web-Account bei "c-entron Nexus" (separate Web-Anwendung, "c-entron Web"), Artikelanzeige basiert auf hinterlegten "Sonderpreisen" im c-entron.NET Adressstamm, Zugriff über Menüpunkt "Shop".
|
||||
Aussage: Das System soll einen webbasierten Bestellkanal (WebCart) für Endkunden der c-entron-Kunden bereitstellen, dessen Sortiment/Preise zentral im ERP (c-entron.NET) gepflegt werden.
|
||||
Ergebnis: Bereits vorhandener Web-Kanal (c-entron Nexus) als Blaupause/Vorstufe für die geplante SaaS-Neuimplementierung — zeigt, dass Teile des Systems bereits heute web-basiert sind und mit dem ERP-Kern über Web-Accounts/Sonderpreise integriert sind.
|
||||
Belege:
|
||||
- [PRIMÄR] README.md:1,29-35 - Beschreibung WebCart, Web-Account-Login, Sonderpreise, "Shop"
|
||||
- [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Administration/WebCart (Namensraum in ModuleRegistration.cs Zeile 40) - zugehöriges WPF-Verwaltungsmodul
|
||||
Prüfidee: Architektur von "c-entron Nexus" (separates Blazor-Projekt laut README-Kontext "azure-blazor") im Detail untersuchen — ggf. eigener Cluster/Repository-Bereich außerhalb des hier untersuchten Scopes.
|
||||
Tracelinks: SyRS-ARCH-16
|
||||
Konsolidierung: nein
|
||||
Status: belegt (Detailarchitektur von c-entron Nexus außerhalb des recherchierten Bereichs; HYPOTHESE: Nexus/Blazor-Code nicht gelesen, nur README)
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-ARCH-06
|
||||
Titel: Breites Produkt-/Anwendungsportfolio
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Produktmanagement, Entwickler
|
||||
Vorbedingung: -
|
||||
Fakt: `ApplicationKind.cs` listet neben dem Kern-ERP ("NEXOWARE c-entron ERP") ca. 40 weitere, separat lizenzierte Anwendungen/Produkte im selben Ökosystem (u.a. Service-Board, Service-Board Online, c-entron Nexus, Outlook Add-In, PasswordManager, WebCart, WebSuitePro, DocumentSync, Riversuite-Familie [Inventory/Compliance/Monitoring/Mobile/Online/Pro/N13/RFlow/SupRemo], TAPI-Server, Communicator, MailScanner/MailScannerNET, diverse ExternalApp-Connectoren zu Drittsystemen wie c-pra, DocBee, Visoma, WOASI).
|
||||
Aussage: Das System ist Teil eines breiten Produkt-/Anwendungsportfolios (nicht nur ein einzelnes ERP), das über ein gemeinsames Lizenz- und Authentifizierungssystem am zentralen Web-Service andockt.
|
||||
Ergebnis: Wichtige Erkenntnis für den StRS-Systemüberblick: Die Web-/SaaS-Neuimplementierung des ERP-Kerns muss die Schnittstellen zu diesem breiteren Produktportfolio (mind. Authentifizierung/Lizenzierung) weiterhin bedienen können, auch wenn die Einzelprodukte selbst außerhalb des Scopes liegen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Interfaces/Administration/Logins/ApplicationKind.cs:11-53 - vollständige Liste der ApplicationKind-Instanzen
|
||||
Prüfidee: Mit Produktmanagement klären, welche dieser Anwendungen im Rahmen der SaaS-Neuimplementierung migriert/integriert werden müssen vs. weiterhin als separate Legacy-Clients bestehen bleiben.
|
||||
Tracelinks: SyRS-ARCH-01
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
|
||||
## Sicherheit & Berechtigungen (SEC)
|
||||
|
||||
|
||||
ID: StRS-SEC-01
|
||||
Titel: Getrennte Identitätsklassen für Mitarbeiter und Kunden
|
||||
Ebene: StRS
|
||||
Typ: Stakeholder-Ziel
|
||||
Akteur: c-entron Mitarbeiter (interner Benutzer, "AppUser"), Kunde (Web-Account)
|
||||
Vorbedingung: -
|
||||
Fakt: Das System unterscheidet technisch zwei vollständig getrennte Benutzerarten mit eigenen Tabellen/Entities und eigenen Authentifizierungspfaden: interne Mitarbeiter (`AppUser`/Tabelle `Sichbenu`) und Kunden-Zugänge (`WebAccount`). Beide durchlaufen unterschiedliche Authenticator-Klassen (`BasicAuthenticator`/`ActiveDirectoryAuthenticator` vs. `WebAccountAuthenticator`).
|
||||
Aussage: Das System soll interne Mitarbeiterkonten und externe Kundenzugänge als getrennte Identitätsklassen mit eigenen Rechte- und Authentifizierungsregeln führen.
|
||||
Ergebnis: Zwei unabhängige Benutzer-/Rechtemodelle (App-Rechte über `Sichrech`/`Sichtrus`/`Sichmemb` für Mitarbeiter, `WebRights`/`WebAccountsRights` für Kunden).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Logins/Auth/Authenticator.cs (AuthenticatorFactory.GetMainAuthenticator, Zeilen 88-95) - Begründung: Routing anhand des konkreten `AuthObject`-Typs (BasicAuthObject/WebAccountAuthObject/OpenIdConnectAuthObject) belegt getrennte Codepfade.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Logins/Auth/WebAccountAuthenticator.cs (Zeile 20-83) - Begründung: Eigene Authentifizierungsklasse nur für Kundenzugänge.
|
||||
Prüfidee: Prüfen, ob im Zielsystem beide Identitätsklassen (Mitarbeiter, Kunde) weiterhin getrennt modelliert werden müssen oder ob ein einheitliches Identity-Modell mit Rollenattribut ausreicht.
|
||||
Tracelinks: SyRS-SEC-01, SyRS-SEC-02, SyRS-SEC-03, SyRS-SEC-04, SyRS-SEC-13, SyRS-SEC-14
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-SEC-02
|
||||
Titel: Gruppenbasierte Rechtevergabe (RBAC)
|
||||
Ebene: StRS
|
||||
Typ: Stakeholder-Ziel
|
||||
Akteur: Administrator (Rechteverwaltung)
|
||||
Vorbedingung: -
|
||||
Fakt: Rechte werden nicht direkt an Benutzer, sondern an Gruppen (`AppGroup`) vergeben; Benutzer werden Gruppen zugeordnet (`AppUserMember`), Gruppen erhalten Rechte (`AppGroupRightAssignment`). Das Modul "Rechteverwaltung" (`Rechteverwaltung`) verwaltet dies laut Doku.
|
||||
Aussage: Das System soll Zugriffsrechte gruppenbasiert (rollenbasiert) statt benutzerindividuell vergeben, um Verwaltungsaufwand und Fehlerquote bei der Rechtevergabe zu reduzieren.
|
||||
Ergebnis: Ein Benutzer erhält die Vereinigungsmenge aller Rechte seiner zugeordneten Gruppen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs (GetRightsFromCurrentUser, Zeilen 63-87; CheckRightsFromUser, Zeilen 95-111) - Begründung: SQL-Join über `Sichtrus`/`Sichmemb` aggregiert Rechte ausschließlich über Gruppenmitgliedschaft.
|
||||
- [KONTEXT] docs/guides/development/check-userrights.md (Zeile 3) - Begründung: "Rights and groups can be managed in the Rechteverwaltung module."
|
||||
Prüfidee: Klären, ob im SaaS-Zielsystem weiterhin Gruppen als einzige Rechteträger dienen sollen oder zusätzlich direkte Nutzer-Overrides (Allow/Deny) benötigt werden.
|
||||
Tracelinks: SyRS-SEC-04, SwRS-SEC-01, SwRS-SEC-02
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-SEC-03
|
||||
Titel: Einschränkende Rechte für Datensparsamkeit
|
||||
Ebene: StRS
|
||||
Typ: Stakeholder-Ziel
|
||||
Akteur: Administrator, Mitarbeiter (eingeschränkter Sichtbereich)
|
||||
Vorbedingung: -
|
||||
Fakt: Neben "Vollrechten" existiert die dokumentierte Kategorie "einschränkendes Recht" (restricting right), z. B. `SHOW_HELPDESK_ONLY_OWN`, `SHOW_HELPDESK_ONLY_OWN_BRANCH`, `MANAGE_RIGHTS_ONLY_OWN_BRANCH`. Diese Rechte schränken eine bereits gewährte Sichtbarkeit weiter ein (z. B. nur eigene Filiale).
|
||||
Aussage: Das System soll eine Datensparsamkeit nach Bedarfsprinzip ("need-to-know") über kombinierbare einschränkende Rechte (nur eigene Datensätze / nur eigene Filiale) umsetzen können.
|
||||
Ergebnis: Ein Benutzer mit Grundrecht + einschränkendem Recht sieht nur eine Teilmenge der Datensätze, die er ohne das einschränkende Recht sehen würde.
|
||||
Belege:
|
||||
- [PRIMÄR] CentronRights.md (Abschnitte 1.1, 1.2, 2.1, Zeilen 9-26) - Begründung: Explizite Dokumentation als "restricting right" mit fachlicher Wirkung.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs (SaveRightGroup, Zeilen 391-393; DeleteRightGroup, Zeilen 355-357) - Begründung: `MANAGE_RIGHTS_ONLY_OWN_BRANCH` wird serverseitig ausgewertet und verweigert filialübergreifende Aktionen.
|
||||
Prüfidee: Ermitteln, wie viele "nur eigene"/"nur eigene Filiale"-Rechte insgesamt existieren (Sichrech-Auswertung) und ob dieses Muster generisch (z. B. Row-Level-Security/Policy Engine) statt Recht-für-Recht abgebildet werden kann.
|
||||
Tracelinks: SwRS-SEC-01, SwRS-SEC-02
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-SEC-04
|
||||
Titel: Schutz der Administratorengruppe
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Administrator
|
||||
Vorbedingung: -
|
||||
Fakt: Die Gruppe mit `I3D == 6` bzw. Name "Administratoren" ist im Code hart gegen Löschung geschützt (`DeleteRightGroup`) und nur eine explizite Whitelist von ca. 30 Rechten darf dieser Gruppe hinzugefügt/entzogen werden (`GetAssignableAdminRightI3Ds`).
|
||||
Aussage: Das System soll die Administratorengruppe strukturell vor versehentlicher Löschung und vor Entzug sicherheitskritischer Rechte schützen.
|
||||
Ergebnis: Löschversuch der Administratorengruppe liefert Fehlermeldung "Die Adminstratoren Gruppe darf nicht gelöscht werden"; Rechteänderungen an dieser Gruppe außerhalb der Whitelist werden abgelehnt (Rückgabe `false`).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs (DeleteRightGroup, Zeilen 348-374; SaveAndAssignGroupToRight/RemoveAssignGroupToRight, Zeilen 261-299; GetAssignableAdminRightI3Ds, Zeilen 714-759) - Begründung: Serverseitige Schutzlogik unabhängig vom UI, harte Prüfung `group.I3D == 6`.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Rights/AppUserGroupBL.cs (IsAdministratorGroup/IsAdministratorGroupI3D, Zeilen 78-89) - Begründung: Zentrale Definition "Administratorengruppe = I3D 6 ODER Name = 'Administratoren'".
|
||||
Prüfidee: Verifizieren, ob Namensvergleich ("Administratoren") als Sicherheitskriterium zuverlässig ist (Umbenennungsrisiko) oder nur der I3D-Vergleich sicherheitsrelevant sein sollte.
|
||||
Tracelinks: SwRS-SEC-01, SwRS-SEC-02
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-SEC-05
|
||||
Titel: Zwei-Faktor-Authentifizierung als Sicherheitsstufe
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Mitarbeiter, Kunde (Web-Account)
|
||||
Vorbedingung: -
|
||||
Fakt: Zusätzlich zu Benutzername/Passwort existiert eine konfigurierbare Zwei-Faktor-Authentifizierung mit zwei austauschbaren Verfahren: RADIUS-Server (`RadiusTwoFactorValidator`) und E-Mail-Link (`EmailTwoFactorValidator`), gesteuert über `WebServiceConfigHelper.Current.TwoFactorAuthType`.
|
||||
Aussage: Das System soll eine zusätzliche Authentifizierungsstufe (2FA) als organisatorisch konfigurierbare Sicherheitsmaßnahme anbieten.
|
||||
Ergebnis: Login schlägt fehl, wenn 2FA aktiviert, aber nicht erfolgreich validiert wurde ("Die Zwei-Faktor-Authentifizierung ist fehlgeschlagen.").
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Logins/TwoFactor/TwoFactorAuthBL.cs (GetTwoFactorValidator, Zeilen 181-194; ValidateTwoFactor, Zeilen 33-80) - Begründung: Zentrale Weiche für 2FA-Verfahren, in allen drei Authenticator-Klassen (Basic/AD/WebAccount) eingebunden.
|
||||
Prüfidee: Klären, ob im Zielsystem TOTP/App-basierte 2FA (wie im separaten Passwort-Manager-Verfahren, siehe SwRS-SEC-05) als drittes gleichwertiges Verfahren für den Login ergänzt werden soll.
|
||||
Tracelinks: SyRS-SEC-07, SyRS-SEC-08, SyRS-SEC-09, SwRS-SEC-05
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-SEC-06
|
||||
Titel: Single Sign-On über Microsoft Entra ID
|
||||
Ebene: StRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: Mitarbeiter (Unternehmens-Konto)
|
||||
Vorbedingung: Azure AD App Registration vorhanden, Lizenz `OpenIDConnectAuthentication`
|
||||
Fakt: Die Funktion "Anmelden mit Microsoft" ist als vollständiger OpenID-Connect-Flow über MSAL dokumentiert und implementiert (`/config/jwt`, `/jwt/login`, `/jwt/connect_accounts`).
|
||||
Aussage: Das System soll Single-Sign-On über Microsoft Entra ID als alternativen, konfigurierbaren Anmeldeweg unterstützen.
|
||||
Ergebnis: Erfolgreiche Anmeldung liefert ein c-entron-Ticket (Session) ohne c-entron-eigenes Passwort.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/reference/security/anmelden-mit-microsoft-technische-anleitung.md (gesamt, insb. Zeilen 126-146, 386-403) - Begründung: Vollständige technische Dokumentation inkl. Dateipfaden.
|
||||
- [SEKUNDÄR] src/backend/Centron.BL/Administration/Logins/Auth/AuthenticatorFactory.cs (GetFromOpenIdConnectAuth, Zeilen 129-145) - Begründung: Lizenzprüfung `LicenseGuids.OpenIDConnectAuthentication` und Aktivierungs-Flag `JwtEnabled` als Vorbedingung bestätigt.
|
||||
Prüfidee: Prüfen, ob Redirect-/Consent-Flow und Token-Validierung 1:1 in eine Web-/SaaS-Neuimplementierung (z. B. mit Standard-OIDC-Middleware) übernommen werden können.
|
||||
Tracelinks: SyRS-SEC-10
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-SEC-07
|
||||
Titel: Lizenzpflichtiger Zugriff auf den Passwort-Manager
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Administrator, Vertriebsmitarbeiter mit Zugriff auf Kundenzugangsdaten
|
||||
Vorbedingung: Lizenz "Passwort-Manager" vorhanden
|
||||
Fakt: Der Zugriff auf das gesamte Passwort-Manager-Modul (Kundenzugänge/Passwörter) ist zusätzlich zur Rechteprüfung an eine kommerzielle Lizenz gekoppelt (`LicenseManager.Instance.HasLicense(LicenseGuids.PasswordManager)`), die in praktisch jeder öffentlichen Methode von `PasswordManagerBL` geprüft wird.
|
||||
Aussage: Das System soll den Zugriff auf sicherheitskritische Zusatzmodule (z. B. Passwort-Manager) sowohl über Lizenz als auch über Benutzerrechte absichern (zweistufige Zugriffskontrolle).
|
||||
Ergebnis: Ohne Lizenz: Fehlermeldung "Sie besitzen keine Lizenz für den Passwort-Manager." (`DefaultMessageCodes.LicenseNotFound`), unabhängig von vorhandenen Rechten.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/PasswordManager/PasswordManagerBL.cs (z. B. Zeilen 94-95, 243-244, 263-264, 331-332, 349-350, 896-897, 932-933) - Begründung: Wiederkehrendes Muster in mind. 8 Methoden.
|
||||
- [KONTEXT] docs/reference/security/licensing-system.md (Zeilen 50-63) - Begründung: Allgemeines Lizenzkonzept (`LicenseManager.Instance.HasLicense`) bestätigt als Standardmuster.
|
||||
Prüfidee: Klären, ob Lizenzprüfung im SaaS-Modell durch Tenant-/Subscription-Feature-Flags ersetzt wird und ob die doppelte Prüfung (Lizenz UND Recht) beibehalten werden soll.
|
||||
Tracelinks: SyRS-SEC-11, SyRS-SEC-12
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
|
||||
## Stammdaten: Geschäftspartner, Kunden, Mitarbeiter (CRM)
|
||||
|
||||
|
||||
ID: StRS-CRM-01
|
||||
Titel: Statusmodell für Geschäftspartner
|
||||
Ebene: StRS
|
||||
Typ: Daten
|
||||
Akteur: Vertrieb, Buchhaltung
|
||||
Vorbedingung: -
|
||||
Fakt: Der Kundenstatus wird über zwei getrennte, unabhängig setzbare Attribute abgebildet: `State` (int, wirkt wie "aktiv/inaktiv", Vergleich `== 1`) und `Locked` (bool, "gesperrt"). Es existiert kein enumeriertes Statusmodell mit benannten Zuständen (z. B. "gelöscht", "archiviert", "Bonitätssperre") im gesichteten BL-Code.
|
||||
Aussage: Das System soll den Lebenszyklus-Status eines Kunden (aktiv/inaktiv, gesperrt/entsperrt) als eigenständiges fachliches Konzept abbilden, das im Zielsystem klar benannte, erweiterbare Zustände (z. B. Enum statt Rohint) unterstützt.
|
||||
Ergebnis: Migrationsrelevanter Fakt: Legacy-Datenmodell nutzt zwei binäre/int-Felder statt eines State-Machine-Modells.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/CustomerArea/CustomerBase.cs:15,30 (`State`, `Locked`) - Begründung: Felddefinition.
|
||||
- [KONTEXT] src/backend/Centron.Entities/Entities/Businesspartner/Supplier.cs:8-9 - Begründung: Lieferant besitzt nur `State`, kein `Locked`-Äquivalent – Asymmetrie zwischen Kunden- und Lieferanten-Stammdatenmodell.
|
||||
Prüfidee: Klärung mit Fachbereich, ob Lieferanten je gesperrt werden können und wie das aktuell (ohne `Locked`-Feld) gehandhabt wird.
|
||||
Tracelinks: SyRS-CRM-03
|
||||
Konsolidierung: nein
|
||||
Status: HYPOTHESE (fehlende Information: ob Lieferanten-Sperre über anderes Feld/Modul realisiert wird – im gesichteten `Supplier`-Entity nicht vorhanden)
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-CRM-02
|
||||
Titel: DSGVO-konforme Löschung von Kontaktpersonen
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit / Compliance
|
||||
Akteur: Buchhaltung, Vertrieb, Datenschutzbeauftragter
|
||||
Vorbedingung: Löschantrag zu einer Kontaktperson (DSGVO/Art. 17 DSGVO)
|
||||
Fakt: `DataSecurityBL` implementiert eine "DSGVO löschen"-Funktion für `ContactPerson`: personenbezogene Felder (Geburtsdatum, Beruf, Telefon 1-5, Fax 1-2, E-Mail 1-2, Mailing-Flags, Kommentarfelder, Abteilung, Bild, Active-Directory-SID, Website, Web-Zugangsdaten) werden geleert bzw. mit dem Platzhaltertext "DSGVO: Auf Anfrage gelöscht. (Durchgeführt von {ShortSign} am {Datum} um {Uhrzeit} Uhr)" überschrieben; jeder gelöschte Wert wird vor dem Löschen in ein Lösch-Protokoll (`deleteProtocol`) geschrieben; die Kontaktperson erhält `IsDsgvoDeleted=true`, `DsgvoDeletedEmployeeI3D`, `DsgvoDeletedDate` und wird (außer bei `Standard`-Kontakt) deaktiviert (`Status=0`).
|
||||
Aussage: Das System soll auf Anfrage die personenbezogenen Daten einer Kontaktperson DSGVO-konform anonymisieren, den Vorgang inkl. verantwortlichem Mitarbeiter und Zeitpunkt nachvollziehbar protokollieren und die vorherigen Werte für Nachweiszwecke in einem Löschprotokoll festhalten.
|
||||
Ergebnis: Kontaktperson ist nach Ausführung anonymisiert, als DSGVO-gelöscht markiert und (i. d. R.) deaktiviert; ein Audit-Trail bleibt erhalten.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/DataSecurity/DataSecurityBL.cs:1152-1276 - Begründung: Vollständige Feld-für-Feld-Anonymisierungslogik inkl. Protokollierung und Statusmarkierung.
|
||||
- [SEKUNDÄR] src/backend/Centron.BL/Administration/DataSecurity/DataSecurityBL.cs:26-27 - Begründung: Konstanten für den Lösch-Kommentartext.
|
||||
Prüfidee: DSGVO-Löschung einer Testkontaktperson auslösen; prüfen, dass alle genannten Felder geleert sind, `IsDsgvoDeleted=true` gesetzt ist und ein lesbares Protokoll erzeugt wird.
|
||||
Tracelinks: SwRS-CRM-08 (kein SyRS-Zwischenschritt im Cluster vorhanden – Lücke auf SyRS-Ebene)
|
||||
Konsolidierung: Kandidat: SwRS-CRM-08, StRS-CRM-03 (gemeinsames Thema DSGVO-Datenlöschung/-bereinigung)
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-CRM-03
|
||||
Titel: Übersicht löschrelevanter Altdatenbestände (DSGVO)
|
||||
Ebene: StRS
|
||||
Typ: Compliance / Sicherheit
|
||||
Akteur: Datenschutzbeauftragter
|
||||
Vorbedingung: Durchführung einer DSGVO-Datenbereinigung
|
||||
Fakt: `DataSecurityBL.GetDataSecurityCleanUpStats` liefert Statistiken zu löschrelevanten Datenbeständen (Kunden mit letzter Aktion älter als Datum X, bereits gelöschte Kunden, CRM-Aktivitäten älter als Datum X, Belege [Angebote/Aufträge/Lieferscheine/Abholscheine/Rechnungen/Gutschriften] älter als Datum X, mit Filter nach Kundenart/Objektart/Abschlussstatus). Zugriff ist an das Recht `UserRightsConst.DsgvoModule.ACCESS_CLEANUP_DATABASE` UND ein Feature-Flag `ModuleFeatures.IsDsgvoDatabaseCleanupAvailable` gekoppelt.
|
||||
Aussage: Das System soll autorisierten Benutzern eine Übersicht über lösch-/archivierungsrelevante Alt-Datenbestände (Kunden, CRM-Aktivitäten, Belege) auf Basis konfigurierbarer Aufbewahrungsfristen bereitstellen, bevor eine Bereinigung ausgeführt wird.
|
||||
Ergebnis: Statistik-Report vor Ausführung der eigentlichen Löschung; feature-geflaggt und rechtebeschränkt.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/DataSecurity/DataSecurityBL.cs:34-62 (`GetDataSecurityCleanUpStats`) - Begründung: Zeigt Filter- und Rechtekombination.
|
||||
- [SEKUNDÄR] src/backend/Centron.BL/Administration/DataSecurity/DataSecurityBL.cs:64-70 (`DataSecurityExecuteCleanUp`) - Begründung: Ausführungsmethode ist rechtegeschützt, der eigentliche Bereinigungsvorgang liefert im gesichteten Ausschnitt nur `Result.AsSuccess()` ohne sichtbare Löschlogik an dieser Stelle (weitere Implementierung evtl. in nicht gelesenen Codeteilen der 1900-Zeilen-Datei).
|
||||
Prüfidee: Statistikabruf mit und ohne Recht `ACCESS_CLEANUP_DATABASE` testen; Feature-Flag deaktivieren und Verhalten prüfen.
|
||||
Tracelinks: keine direkte Verknüpfung (Lücke)
|
||||
Konsolidierung: Kandidat: StRS-CRM-02, SwRS-CRM-08 (gemeinsames Thema DSGVO-Datenlöschung/-bereinigung)
|
||||
Status: belegt (Ausführungslogik nur teilweise gesichtet – Datei hat 1900 Zeilen, nicht vollständig gelesen)
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-CRM-04
|
||||
Titel: Dubletten-Erkennung und Zusammenführung von Geschäftspartnern
|
||||
Ebene: StRS
|
||||
Typ: nicht-funktional (Datenqualität)
|
||||
Akteur: Vertrieb, Buchhaltung
|
||||
Vorbedingung: Anlage/Pflege von Kunden- und Lieferanten-Stammdaten über die Zeit
|
||||
Fakt: Im gesamten gesichteten `Centron.BL`-Code (Customer-, Address-, ContactPerson-, Supplier-Bereich) wurde keine Dubletten-Erkennung (z. B. Ähnlichkeitssuche über Name/Adresse/USt-IdNr.) und keine Merge-Funktion für zwei Geschäftspartner-Datensätze gefunden; die einzige Unterstützung ist die Freitext-Suche nach Matchcode/Name/I3D vor manueller Neuanlage (`SearchCustomerBL`, `SearchCustomerBySearchText`).
|
||||
Aussage: Das System soll Vertriebs- und Buchhaltungsmitarbeiter bei der Neuanlage von Geschäftspartnern durch eine aktive Dubletten-Prüfung (z. B. Ähnlichkeitssuche) unterstützen und eine Funktion zum Zusammenführen (Merge) versehentlich doppelt angelegter Datensätze bereitstellen.
|
||||
Ergebnis: Fehlende Funktionalität im Ist-System; Dublettenvermeidung liegt vollständig in der manuellen Sorgfalt des Sachbearbeiters.
|
||||
Belege:
|
||||
- [KONTEXT] src/backend/Centron.BL/Sales/Customers/CustomerBL.cs:73-99 (`SearchCustomerBySearchText`) - Begründung: Zeigt, dass nur eine einfache Textsuche als Vorab-Prüfung existiert.
|
||||
- [KONTEXT] Negativbefund aus gezielter Suche (`grep -rniE "dublette|duplicate|merge"` über `Sales/Customers`, `EmployeeArea`, `CountryArea`, `BusinessPartner`) - Begründung: Keine Treffer zu fachlicher Dubletten-/Merge-Logik für Geschäftspartner (nur technische Login-Duplikatsprüfungen, siehe SyRS-CRM-05).
|
||||
Prüfidee: Fachbereich befragen, ob Dublettenbereinigung ggf. über ein separates, hier nicht durchsuchtes Modul (z. B. externes Datenqualitäts-Tool) erfolgt, das nicht Teil von `Centron.BL` ist.
|
||||
Tracelinks: keine direkte Verknüpfung (Lücke)
|
||||
Konsolidierung: nein (explizit abgegrenzt von SyRS-CRM-05: dort nur technische Login-Namen-Eindeutigkeit, keine fachliche Geschäftspartner-Dublette)
|
||||
Status: HYPOTHESE (fehlende Information: Negativbefund – Abwesenheit von Funktionalität kann nicht abschließend über Quellcode-Grep bewiesen werden, ggf. existiert Logik in einem nicht durchsuchten Modul oder als externes Tool)
|
||||
|
||||
|
||||
## Vertrieb & Einkauf (SALES)
|
||||
|
||||
|
||||
ID: StRS-SALES-01
|
||||
Titel: CRM-Klassifizierung von Angeboten
|
||||
Ebene: StRS
|
||||
Typ: funktional (Geschäftsziel CRM/Vertriebssteuerung)
|
||||
Akteur: Vertrieb, Vertriebsleitung
|
||||
Vorbedingung: Ein Beleg implementiert `IReceiptWithClassifications` (u.a. Angebote).
|
||||
Fakt: `ReceiptBL.CheckIfClassificationIsNeeded()` verlangt drei Felder als Pflichtfelder für die
|
||||
CRM-Klassifizierung: `ProjectEnd` (Projektende), `ProductGroupClassificationI3D` (Produktgruppe),
|
||||
`ProbabilityClassificationI3D` (Abschlusswahrscheinlichkeit), sofern `data.IgnoreCallbacks==false`.
|
||||
Ergänzend liefert `OfferSpecificLogic.ShouldBeSetCrmProjectByThreshold()=true`.
|
||||
Aussage: Das System soll bei Angeboten eine CRM-Klassifizierung (Produktgruppe, Abschlusswahrscheinlichkeit, geplantes
|
||||
Projektende) als verpflichtende Angaben zur Vertriebssteuerung/Forecasting erzwingen.
|
||||
Ergebnis: Strukturierte Vertriebs-Pipeline-Daten (Sales-Funnel) als Basis für Umsatzprognosen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs:9415-9440 - CheckIfClassificationIsNeeded() - Begründung: erzwingt die drei Pflichtfelder beim Speichern eines klassifizierbaren Belegs.
|
||||
- [SEKUNDÄR] src/backend/Centron.BL/Sales/Receipts/Offers/OfferSpecificLogic.cs:631 - ShouldBeSetCrmProjectByThreshold() => true - Begründung: bestätigt, dass Angebote diese Klassifizierung fachlich nutzen.
|
||||
Prüfidee: Angebot ohne Klassifizierung speichern → Fehler zu fehlenden Feldern ProjectEnd/ProductGroupClassification/ProbabilityClassification.
|
||||
Tracelinks: keine direkte Verknüpfung (Lücke) - keine eigenständige SyRS-/SwRS-Anforderung in diesem Cluster elaboriert die technische Umsetzung separat.
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-SALES-02
|
||||
Titel: Bestellvorschlagsliste (BVL) für Einkauf
|
||||
Ebene: StRS
|
||||
Typ: funktional (Bedarfsermittlung/Dispo)
|
||||
Akteur: Einkauf
|
||||
Vorbedingung: Artikel mit Lagerabbuchung (`Abbuchung='J'`) oder Pflichtbuchung (`IsObligatoryBooking`) sind in offenen
|
||||
Aufträgen/Beständen unterbestellt.
|
||||
Fakt: `OrderSuggestionListBL` liefert mehrere Bestellvorschlagslisten (BVL): `GetOrderSuggestionArticle`
|
||||
(artikelbasiert inkl. Sonderartikel/Spezialvereinbarungen), `GetOrderSuggestionOrder`
|
||||
(auftragsbasiert, filterbar nach Direktlieferung `Direktlieferung=1` und Mietportal-Sonderfall `isMietPortal`),
|
||||
`GetOrderSuggestionWH` (lagerbasiert). `StoreSuggestionInfo()`/`RemoveDirectDelivery()` erlauben manuelle
|
||||
Bearbeitung einzelner Auftragspositionen (Infotext, Direktlieferungs-Flag) direkt aus der BVL heraus.
|
||||
Aussage: Das System soll dem Einkauf eine mehrdimensionale Bestellvorschlagsliste (je Artikel, je Auftrag, je Lager)
|
||||
bereitstellen, die offene Bedarfe inklusive Direktlieferungs- und Mietportal-Sonderfällen konsolidiert und
|
||||
eine direkte Bearbeitung einzelner Auftragspositionen (Infotext, Direktlieferung entfernen) ermöglicht.
|
||||
Ergebnis: Zentrales Werkzeug zur Bedarfsbündelung/Disposition vor der eigentlichen Bestellauslösung an Lieferanten.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Purchasing/OrderSuggestionList/OrderSuggestionListBL.cs:589-733 - GetOrderSuggestionArticle(), GetArticlePerItems(), GetOrderSuggestionOrder() - Begründung: implementiert die drei Kernsichten der Bestellvorschlagsliste.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Purchasing/OrderSuggestionList/OrderSuggestionListBL.cs:1039-1067 - StoreSuggestionInfo(), RemoveDirectDelivery() - Begründung: belegt direkte Bearbeitbarkeit von Auftragspositionen aus der BVL.
|
||||
- [KONTEXT] git log -- src/backend/Centron.BL/Purchasing: "2fbbe1561e Ticket 148592: Mindestbestellmenge in BVL", "4e8dca6f3e Ticket 147996: BVL mit Teil-Direktlieferung", "f54e265bff Ticket 155192: Neue Artikeleigenschaft 'Bei BVL berücksichtigen'", "78e1854f60 BVL: CRMProjekt für Aufträge" - Begründung: belegt kontinuierliche fachliche Weiterentwicklung als Kern-Einkaufswerkzeug.
|
||||
Prüfidee: BVL für Artikel mit offenem Bedarf aus mehreren Aufträgen aufrufen, Direktlieferungs-Flag einer Position entfernen und Persistenz prüfen.
|
||||
Tracelinks: SyRS-SALES-12 - Begründung: SyRS-SALES-12 (Rückspiegelung Liefertermin bei Direktlieferung) konkretisiert den Direktlieferungs-Sonderfall, den die BVL filtert/bearbeitet.
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
|
||||
## Abrechnung, Fakturierung & Verträge (BILL)
|
||||
|
||||
|
||||
ID: StRS-BILL-01
|
||||
Titel: E-Rechnungserzeugung (ZUGFeRD/XRechnung) rechtssicher automatisieren
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Buchhaltung / Finanzbuchhaltung
|
||||
Vorbedingung: Rechnung/Gutschrift ist im System erfasst und soll elektronisch versendet werden
|
||||
Fakt: c-entron generiert beim Rechnungs-/Gutschriftexport automatisiert ZUGFeRD- bzw. XRechnung-konforme XML-Dateien (Versionen 1.0 bis 2.1/XRechnung 3.0.1), implementiert in `InvoiceZugferdBL.cs`. Die Formatwahl (ZUGFeRD Comfort vs. XRechnung) erfolgt automatisch anhand des Vorhandenseins einer Leitweg-ID.
|
||||
Aussage: Das System soll rechtssichere elektronische Rechnungen (ZUGFeRD/XRechnung) automatisiert aus den erfassten Rechnungs- und Gutschriftdaten erzeugen können, ohne manuelle Nacharbeit der Anwenderin.
|
||||
Ergebnis: Verkäufer kann gesetzeskonforme E-Rechnungen (auch für öffentliche Auftraggeber) versenden.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/DataExchange/EDI/SaleInvoices/InvoiceZugferdBL.cs:124-156 (GenerateZugferdFile, Formatwahl anhand leitwegID) - Begründung: Kernmechanik der automatisierten E-Rechnungserzeugung im Code nachgewiesen
|
||||
- [SEKUNDÄR] docs/reference/zugferd-feldzuordnung-anwender.md:9-14 - Begründung: Anwenderdokumentation bestätigt unterstützte Versionen
|
||||
Prüfidee: Export einer Rechnung ohne und mit Leitweg-ID durchführen, resultierendes Dateiformat/-schema prüfen (KOSIT-Validator)
|
||||
Tracelinks: SyRS-BILL-06, SyRS-BILL-07, SyRS-BILL-08, SyRS-BILL-09, SyRS-BILL-10, SyRS-BILL-11, SyRS-BILL-12, SyRS-BILL-17, SyRS-BILL-19
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-BILL-02
|
||||
Titel: Automatisierte wiederkehrende Vertragsabrechnung (Contract-Billing)
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Vertriebsinnendienst / Vertragsmanagement
|
||||
Vorbedingung: Kunde hat einen laufenden Wartungs-/Servicevertrag mit wiederkehrender Abrechnung
|
||||
Fakt: c-entron bietet ein eigenständiges Contract-Billing-Subsystem (`ReceiptContract`, `AutomaticFacturaBL.Contracts`), das Verträge nach konfigurierbaren Intervallen (Daily/Monthly/Quarterly/Yearly) automatisiert abrechnet, inkl. Integration externer RMM-Nutzungsdaten (Riverbird) und Kontingentverwaltung.
|
||||
Aussage: Das System soll wiederkehrende Vertragsleistungen automatisiert, nach konfigurierbarem Abrechnungsintervall und unter Berücksichtigung von Nutzungsdaten/Kontingenten korrekt fakturieren.
|
||||
Ergebnis: Reduzierter manueller Aufwand bei der Abrechnung von Wartungs-/MSP-Verträgen, korrekte periodengerechte Rechnungsstellung.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/Sales/Receipts/ContractLists/ReceiptContract.cs (Felder BillingIntervalKind, BillingIntervalDuration, AutomatedBilling) - Begründung: Entität trägt Konfigurationsfelder für automatisierte Intervallabrechnung
|
||||
- [PRIMÄR] src/backend/Centron.BL/WebServices/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaWebServiceBL.cs:721-802 (CheckRMMArticle) - Begründung: Ausführbare Logik zur automatisierten RMM-basierten Rechnungspositionserzeugung
|
||||
Prüfidee: Testvertrag mit monatlichem Intervall anlegen, automatische Abrechnung anstoßen, Rechnungsperiode/-betrag verifizieren
|
||||
Tracelinks: SyRS-BILL-13, SyRS-BILL-14, SyRS-BILL-15
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-BILL-03
|
||||
Titel: Mahnstufenbasierte Beleg-/Auftragssperre zur Kreditrisikobegrenzung
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Finanzbuchhaltung / Mahnwesen
|
||||
Vorbedingung: Kunde hat offene, überfällige Forderungen
|
||||
Fakt: Das System führt ein Mahnstufen-Modell (`DunningLevel1Fees/2/3`, `DunningLetterAfterDays1-3`) je Kunde und kann konfigurierbar ab einer bestimmten Mahnstufe die Neuanlage von Belegen (z.B. Aufträgen) sperren (`LockOrderAfterDunningLevel`, durchgesetzt in `ReceiptBL.CanUserCreateNewReceiptsAtCustomerOrSupplier`).
|
||||
Aussage: Das System soll säumige Kunden anhand eines Mahnstufenmodells identifizieren und optional automatisch von der Neuanlage weiterer Belege ausschließen, um das Ausfallrisiko zu begrenzen.
|
||||
Ergebnis: Kreditrisikobegrenzung; Vertrieb kann keine neuen Aufträge/Belege für gesperrte Kunden anlegen, solange die Mahnstufe nicht sinkt.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs:10194-10219 (CanUserCreateNewReceiptsAtCustomerOrSupplier, exakte Fehlermeldung "Aufgrund der Mahnstufe darf kein neuer Beleg ... angelegt werden.") - Begründung: Durchgesetzte Regel im Code, inkl. Fehlermeldungstext
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/Accounts/AccountCustomer.cs:25 (LockOrderAfterDunningLevel) - Begründung: Persistiertes Feld je Kunde als Datengrundlage der Regel
|
||||
Prüfidee: Kunde mit LockOrderAfterDunningLevel=2 und aktueller Mahnstufe 2 anlegen, Versuch neuen Auftrag zu erstellen -> erwartete Fehlermeldung
|
||||
Tracelinks: SyRS-BILL-16, SwRS-BILL-01
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-BILL-04
|
||||
Titel: Rechtssichere Rechnungsstornierung ohne Bruch der Buchhaltungsintegrität
|
||||
Ebene: StRS
|
||||
Typ: nicht-funktional (Compliance/Datenintegrität)
|
||||
Akteur: Buchhaltung / Wirtschaftsprüfung
|
||||
Vorbedingung: Eine Rechnung wurde bereits weiterverarbeitet (z.B. exportiert, in Buchhaltung übernommen) oder ist eine Barrechnung
|
||||
Fakt: `ReceiptInvoiceBL.CancelInvoice` verweigert die Stornierung, wenn die Rechnung bereits storniert ist, es sich um eine Barrechnung handelt, sie bereits weiterverarbeitet oder bereits an die Buchhaltung exportiert wurde, oder es sich bei einer Vertragsrechnung nicht um die zuletzt erstellte handelt.
|
||||
Aussage: Das System soll die Stornierung von Rechnungen nur zulassen, solange keine downstream-Verarbeitung (Export, Weiterverarbeitung) stattgefunden hat, um Inkonsistenzen mit Buchhaltung/Finanzamt zu vermeiden.
|
||||
Ergebnis: Verhinderung nachträglicher Inkonsistenzen zwischen ERP und exportierten/gebuchten Finanzdaten.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs:143-206 (CancelInvoice, komplette Prüfkette) - Begründung: Vollständige, im Code durchgesetzte Vorbedingungskette mit exakten Fehlermeldungen
|
||||
Prüfidee: Testrechnung exportieren (BookKeepingExportBL) und danach Stornoversuch -> Fehlermeldung "...bereits exportiert wurde." erwarten
|
||||
Tracelinks: SyRS-BILL-01, SyRS-BILL-02, SyRS-BILL-03, SyRS-BILL-04, SyRS-BILL-05, SyRS-BILL-18, SyRS-BILL-20, SwRS-BILL-02, SwRS-BILL-05
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
|
||||
## Zeiterfassung, Projekte & Tickets (intern) (TIME)
|
||||
|
||||
|
||||
ID: StRS-TIME-01
|
||||
Titel: Konfigurierbares Regelwerk für die Timer-Abrechnung
|
||||
Ebene: StRS
|
||||
Typ: Daten
|
||||
Akteur: Buchhaltung
|
||||
Vorbedingung: Die Abrechnung von Ticketzeiten zu Belegen soll konfiguriert werden.
|
||||
Fakt: `TimerBillingSettingsDTO`/`HelpdeskSettings` bilden ein umfangreiches Regelwerk ab, u. a.: Gruppierung nach Zeittyp (`GroupTimersByType`) und gleichem Artikel (`GroupEqualArticles`), Rundung vor/nach Summierung (`RoundTimersBeforeGrouping`), Sortierung (`ChronologicalUp/Down/ByEmployee`), Einfügen von Ticket-Kurzbeschreibung/-Beschreibung, Sonderartikel am Ende oder direkt bei der Position, Übernahme der Ticketzeit als Leistungszeitraum (`UseTicketTimeAsServicePeriod`), Übertragung in Stücklisten (`TransferAllTimesToPartsList`/`TransferTimesWithSamePriceToPartsList`), Standard-Stücklistenkopf, Ersetzen von Stücklistenartikeln/-text, Sortierung der Stückliste nach Ticket.
|
||||
Aussage: Das System soll der Buchhaltung ein umfangreiches, granular konfigurierbares Regelwerk zur Steuerung bereitstellen, wie Ticketzeiten zu Belegpositionen (inkl. Stücklisten) zusammengefasst, sortiert und dargestellt werden.
|
||||
Ergebnis: Breites Konfigurationsmodell für die Timer-Abrechnung bestätigt.
|
||||
Belege:
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Finances/TimerBilling/Pages/TimerBillingSettingsPageViewModel.cs:440-483 - Begründung: 1:1-Mapping der UI-Einstellungen auf die persistierten HelpdeskSettings-Felder.
|
||||
- [SEKUNDÄR] src/backend/Centron.BL/Sales/Receipts/Internal/ReceiptItemTimerBL.cs:89-173,521-568 - Begründung: Verarbeitung dieser Einstellungen beim Erzeugen der Belegpositionen.
|
||||
Prüfidee: Einstellung GroupTimersByType aktivieren -> Zeiten werden mit Titel-Trennzeile je Zeittyp gruppiert (Text aus AppSetting-Vorlage mit Platzhalter @@Typ@@).
|
||||
Tracelinks: SyRS-TIME-03, SyRS-TIME-04, SyRS-TIME-05, SyRS-TIME-06, SyRS-TIME-09
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-TIME-02
|
||||
Titel: Terminanfrage-Workflow mit Kundenauswahl (Exchange-Integration)
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Kunde, Mitarbeiter
|
||||
Vorbedingung: Ein Mitarbeiter schickt einem Kunden Terminvorschläge zur Auswahl (z. B. für einen Service-Einsatz).
|
||||
Fakt: `AppointmentRequestState` beschreibt einen linearen Workflow: `RequestOpen`(1) → `AppointmentProposalsSent`(2) → `AppointmentProposalAccepted`(3) ODER `AppointmentProposalsRejected`(4) → `Done`(5). `AppointmentRequestBL.HandleAppointmentRequestReply` verarbeitet die Kundenantwort über Microsoft Exchange (EWS): bei Ablehnung werden alle vorgeschlagenen Exchange-Termine gelöscht und `RequestState = AppointmentProposalsRejected` gesetzt; bei Annahme wird der akzeptierte Termin im Exchange-Kalender als "(Akzeptiert)" markiert, der Kunde als Pflichtteilnehmer ergänzt, die Kategorie von "Terminvereinbarung (offen)" auf "...(akzeptiert)" umgestellt und alle übrigen Vorschläge werden entfernt.
|
||||
Aussage: Das System soll Terminanfragen an Kunden mit mehreren Terminvorschlägen unterstützen, deren Antwort (Annahme/Ablehnung) automatisiert im Exchange-Kalender nachvollziehen und den Anfragestatus entsprechend fortschreiben.
|
||||
Ergebnis: Terminanfrage-Workflow mit Exchange-Integration bestätigt.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/AppointmentRequests/AppointmentRequestBL.cs:29-114 - Begründung: vollständige Antwortverarbeitung inkl. Exchange-Aktionen.
|
||||
- [SEKUNDÄR] src/backend/Centron.Interfaces/AppointmentRequests/AppointmentRequestState.cs:9-16 - Begründung: Statusdefinition.
|
||||
Prüfidee: Kunde akzeptiert einen von drei Terminvorschlägen -> akzeptierter Termin bleibt mit Zusatz "(Akzeptiert)" bestehen, die anderen zwei werden entfernt, Status wechselt auf AppointmentProposalAccepted.
|
||||
Tracelinks: keine direkte Verknüpfung (Lücke)
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-TIME-03
|
||||
Titel: Aktives Vertriebsprojektmanagement (CrmProject)
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Projektleiter, Vertrieb
|
||||
Vorbedingung: Ein CRM-/Vertriebsprojekt (CrmProject, z. B. Kundenprojekt mit Umsatzprognose) wird angelegt oder ausgewertet.
|
||||
Fakt: `CrmProject` verwaltet u. a. bis zu vier Berater- (`Adviser1-4I3D`) und Kontaktperson-Slots, `ProjectStateI3D`/`ProjectKindI3D`/`ProjectProbabilityI3D` (jeweils eigene Stammdaten-Entität statt Enum), Umsatz-/Margenwerte (auch monatlich), `DecisionDate`, `CloseProjectReason`. `CrmProjectBL.SaveCrmProject` erzwingt `Name` als Pflichtfeld, vergibt bei Neuanlage automatisch Nummer (`NumberGroupEnum.CRMProject`) und setzt `State = 1` (aktiv) fest. Das Recht `UserRightsConst.RIGHT_CRMPROJEKTONLYOWN` erzwingt bei fehlendem Vollzugriff eine Filterung auf Projekte, in denen der Mitarbeiter als Berater, Verantwortlicher oder Ersteller eingetragen ist.
|
||||
Aussage: Das System soll Vertriebsprojekte mit mehreren Beratern/Kontaktpersonen, konfigurierbaren Status-/Art-/Wahrscheinlichkeits-Stammdaten sowie Umsatz-/Margenprognose verwalten und den Zugriff darauf optional auf eigene bzw. zugeordnete Projekte einschränken.
|
||||
Ergebnis: Aktives Projektmanagement-Datenmodell (CrmProject, nicht das Legacy-„Project") mit Zugriffsbeschränkung bestätigt.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/Sales/Customers/CrmProjects/CrmProject.cs (lt. Sub-Recherche) - Begründung: vollständige Feldliste.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Customers/CrmProjects/CrmProjectBL.cs:105-174,469-541 (lt. Sub-Recherche) - Begründung: Anlage-Validierung, automatische Nummernvergabe, Rechtefilterung `RIGHT_CRMPROJEKTONLYOWN`.
|
||||
Prüfidee: Mitarbeiter ohne RIGHT_CRMPROJEKTONLYOWN-Ausnahme ruft Projektliste ab -> nur Projekte mit ihm als Berater/Verantwortlichem/Ersteller werden geliefert.
|
||||
Tracelinks: SwRS-TIME-13
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
|
||||
## Lager, Logistik & Produktion (LOG)
|
||||
|
||||
|
||||
ID: StRS-LOG-01
|
||||
Titel: Warnung bei Lieferschein-Erstellung trotz aktiver Teil-Kommissionierung
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Vertrieb/Lager (Auftragsabwicklung)
|
||||
Vorbedingung: Ein Auftrag mit aktiven Teil-Kommissionierungssätzen wird in einen Lieferschein überführt
|
||||
Fakt: `PartialCommissionOrderBL.HasPartialCommissionOrdersForItems` prüft, ob mindestens eine der zu liefernden Auftragspositionen zu einem aktiven (weder gelöschten noch gelieferten) Teil-Kommissionierungssatz gehört — laut Code-Kommentar zur Warnung des Anwenders, dass Teil-Kommissionierungssätze beim direkten Umwandeln eines Auftrags in einen Lieferschein ignoriert werden (Ticket 165243).
|
||||
Aussage: Das System soll den Anwender warnen, wenn beim Erzeugen eines Lieferscheins aus einem Auftrag aktive Teil-Kommissionierungssätze für betroffene Positionen bestehen, die dabei ignoriert würden.
|
||||
Ergebnis: Vermeidung von Fehllieferungen bzw. inkonsistenter Kommissionsdaten durch Umgehung des Teil-Kommissionierungs-Workflows.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Warehousing/Commissions/PartialCommissionOrderBL.cs:100-129 (HasPartialCommissionOrdersForItems, inkl. XML-Doc-Kommentar mit Ticketreferenz)
|
||||
Prüfidee: Auftrag mit aktivem Teil-Kommissionierungssatz direkt in Lieferschein umwandeln und auf Warnhinweis prüfen.
|
||||
Tracelinks: SyRS-LOG-08
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-LOG-02
|
||||
Titel: Produktionsmanagement als lizenzpflichtiges Zusatzmodul
|
||||
Ebene: StRS
|
||||
Typ: funktional / Lizenzierung
|
||||
Akteur: Produktionsplaner
|
||||
Vorbedingung: Zugriff auf jegliche Produktionsfunktion (Maschinen, Stücklisten, Fertigungsaufträge)
|
||||
Fakt: Praktisch jede Methode in `ProductionBL`, `ProductionOrderBL` und `ArticleProductionBL` prüft zu Beginn `LicenseManager.Instance.HasLicense(LicenseGuids.ProductionManagement)`; bei fehlender Lizenz wird je nach Methode entweder eine `Exception` mit der Meldung "Sie besitzen nicht die Lizenz für das Produktionsmanagement" geworfen oder (bei einigen Lesemethoden in `ArticleProductionBL`) stillschweigend ein leeres Objekt/eine leere Liste zurückgegeben.
|
||||
Aussage: Das System soll sämtliche Produktionsmanagement-Funktionen (Maschinen, Maschinenarten, Standorte, Stücklisten, Fertigungsschritte, Fertigungsaufträge) an eine separate Lizenz binden.
|
||||
Ergebnis: Produktionsmanagement als optional lizenzierbares Modul, klar abgegrenzt von der Basis-Warenwirtschaft.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Production/ProductionBL.cs:29-30,39-40,49-50,105-106,115-116,126-127,166-167,177-178,185-186,226-227,236-237,246-247,256-257 (wiederholte Lizenzprüfung)
|
||||
- [SEKUNDÄR] src/backend/Centron.BL/Warehousing/ArticleProduction/ArticleProductionBL.cs:34-35,44-45,55-56,75-76 (uneinheitliches Verhalten: teils Exception, teils leeres Ergebnis)
|
||||
Prüfidee: Produktionsfunktionen ohne gültige ProductionManagement-Lizenz aufrufen und Verhalten (Exception vs. leeres Ergebnis) je Methode dokumentieren.
|
||||
Tracelinks: SyRS-LOG-11, SwRS-LOG-09, SwRS-LOG-10
|
||||
Konsolidierung: nein
|
||||
Status: belegt (Detailaspekt als Hypothese offen: uneinheitliches Fehlerverhalten bei fehlender Lizenz (Exception vs. leere Liste) wirkt wie technische Inkonsistenz statt bewusster fachlicher Anforderung, für Web-Neuimplementierung zu klären)
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-LOG-03
|
||||
Titel: Automatisierte Bestellvorschläge bei Mindestbestand-Unterschreitung
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Einkauf/Disposition
|
||||
Vorbedingung: Artikelbestand unterschreitet den konfigurierten Mindestbestand in Haupt- oder Nebenlager
|
||||
Fakt: `OrderSuggestionListBL` ermittelt per SQL Bestellvorschläge, indem der aktuelle Bestand (`cvw_ArticleCount.cnt`) je Artikel/Lager mit `Mindestbestand` (+ Bestellungen in Zulieferung, `IsNull(ab.duration,0)`) verglichen wird — getrennt für Hauptlager (`WarehouseI3D = -1`, Quelle `ARTIK.Mindestbestand`) und Nebenlager (Quelle `NebenlagerArtikel.Mindestbestand`). Artikel müssen zusätzlich `Abbuchung = 'J'` (Bestandsführung aktiv) oder `IsObligatoryBooking = 1` erfüllen.
|
||||
Aussage: Das System soll automatisch Bestellvorschläge generieren, wenn der Lagerbestand (Haupt- oder Nebenlager) unter den je Lager konfigurierbaren Mindestbestand fällt, unter Berücksichtigung bereits laufender Zulieferungen.
|
||||
Ergebnis: Automatisierte Nachbestellung zur Vermeidung von Fehlbeständen (Basis für Beschaffungsprozess).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Purchasing/OrderSuggestionList/OrderSuggestionListBL.cs:139-158,425-436,860-870 (SQL-Logik Mindestbestand vs. cvw_ArticleCount, getrennt Haupt-/Nebenlager)
|
||||
Prüfidee: Artikel mit Mindestbestand 10 auf Bestand 5 senken, Bestellvorschlagsliste generieren und Aufnahme des Artikels prüfen.
|
||||
Tracelinks: keine direkte Verknüpfung (Lücke)
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
|
||||
## Administration, Systemkonfiguration & Kommunikation (ADM)
|
||||
|
||||
|
||||
ID: StRS-ADM-01
|
||||
Titel: Zentrale, clientunabhängige Konfigurationsverwaltung
|
||||
Ebene: StRS
|
||||
Typ: nicht-funktional (Architekturprinzip)
|
||||
Akteur: Systemadministrator, IT-Verantwortlicher
|
||||
Vorbedingung: Client-Anwendung möchte Einstellungen lesen/schreiben.
|
||||
Fakt: Laut Entwicklerdokumentation greift der Client "nie direkt" auf die Settings-Tabellen zu; stattdessen existieren pro fachlichem Bereich "Group Setting Classes", die Settings laden, typisiert kapseln und über dedizierte REST-API-Methoden (POST) bereitstellen (Beispiel `ReceiptWebServiceBL.GetReceiptInvoiceSettings`/`SaveReceiptInvoiceSettings`).
|
||||
Aussage: Das System soll Systemkonfiguration ausschließlich über eine serverseitige Business-Logic-Schicht mit klar definierten, fachlich gruppierten DTOs bereitstellen und den direkten Tabellenzugriff durch Clients unterbinden.
|
||||
Ergebnis: Zentrale, versionierbare Konfigurationsschnittstelle als Grundlage für eine künftige Web-/SaaS-API.
|
||||
Belege:
|
||||
- [SEKUNDÄR] docs/guides/development/settings-management.md:63-114 - Begründung: Beschreibt explizit "The client never accesses settings tables directly" sowie Group-Setting-Class-Pattern mit Beispielcode.
|
||||
- [KONTEXT] src/backend/Centron.BL/Administration/Settings/AppSettingsGroupBL.cs:1864-1887 - Begründung: Konkretes Beispiel eines Group-Setting-Zugriffs (CentronNotifications).
|
||||
Prüfidee: Architekturreview: Prüfen, ob WPF-Client tatsächlich nur über WebService-DTOs auf Settings zugreift (keine direkten SQL/DAO-Aufrufe aus UI-Schicht).
|
||||
Tracelinks: SyRS-ADM-01; SwRS-ADM-01, SwRS-ADM-02, SwRS-ADM-03, SwRS-ADM-04
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-ADM-02
|
||||
Titel: Personalisierte Modulfavoriten je Mitarbeiter
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Sachbearbeiter/Endbenutzer
|
||||
Vorbedingung: Benutzer ist angemeldet und möchte häufig genutzte Module schnell erreichen.
|
||||
Fakt: Benutzer können Module individuell als Favoriten markieren (`ModuleFavorite` verknüpft `Employee` und `Module`); die Anzeige erfolgt gruppiert nach Modulkategorie (`GetModuleFavoritesGroupedByCategory`). Beim Speichern der Favoriten wird bei technischem Fehler die Meldung "Die Favoriten konnten nicht gespeichert werden." zurückgegeben, beim Umschalten eines einzelnen Favoriten "Der Favorite konnte nicht geändert werden.".
|
||||
Aussage: Das System soll es jedem Benutzer ermöglichen, Module individuell als Favoriten zu markieren und diese nach Kategorie gruppiert anzuzeigen; Fehler beim Speichern sollen dem Benutzer mit einer verständlichen Meldung angezeigt werden.
|
||||
Ergebnis: Personalisierte, schnellere Navigation im Modulmenü je Mitarbeiter.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Modules/ModuleBL.cs:44-81 (GetModuleFavorites, SaveModuleFavorites, UpdateModuleFavorite) - Begründung: Zeigt Favoriten-Datenmodell (pro Employee) und Fehlermeldungstexte.
|
||||
- [SEKUNDÄR] src/backend/Centron.BL/Modules/ModuleCategoryBL.cs:88-113 (GetModuleFavoritesGroupedByCategory) - Begründung: Zeigt Gruppierungslogik nach Kategorie für die Anzeige.
|
||||
Prüfidee: UI-/API-Test: Favorit setzen, Session neu laden, prüfen ob Favorit weiterhin gruppiert nach Kategorie erscheint; Fehlerfall (DB nicht erreichbar) prüfen auf Fehlermeldungstext.
|
||||
Tracelinks: SwRS-ADM-05, SwRS-ADM-06 (Modul-/Kategoriesynchronisation als technische Grundlage); SyRS: keine direkte Verknüpfung (Lücke)
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-ADM-03
|
||||
Titel: Konfigurierbares E-Mail-Transportprotokoll
|
||||
Ebene: StRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: IT-Verantwortlicher
|
||||
Vorbedingung: Das System soll E-Mails im Namen des Unternehmens versenden/empfangen.
|
||||
Fakt: Der zu verwendende Mail-Client wird zentral über die Einstellung `CentronWebserviceMailType` gesteuert und kann zwischen SMTP (Default), Microsoft Exchange (EWS) und Microsoft Graph umgeschaltet werden (`CentronMailFactory.GetMail`). Zusätzlich existiert ein globaler Testmail-Modus (`TestMails.IsEnabled`), der bei aktiven Subscribern jede reale Mail-Versendung durch einen In-Memory-Mock ersetzt.
|
||||
Aussage: Das System soll die Wahl des E-Mail-Transportprotokolls (SMTP/Exchange/Microsoft Graph) als zentrale, administrierbare Einstellung anbieten und einen von der Konfiguration unabhängigen Test-/Simulationsmodus für den Mailversand unterstützen.
|
||||
Ergebnis: Flexible Integration in unterschiedliche Kunden-Mailinfrastrukturen; sichere Testbarkeit ohne reale Mailversendung.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/Factory/CentronMailFactory.cs:26-53 (GetMail) - Begründung: Zeigt Protokollauswahl per Setting und TestMail-Vorrang.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/Factory/TestMails.cs:1-56 - Begründung: Zeigt Subscriber-Pattern für Testmail-Abfang.
|
||||
Prüfidee: Konfigurationstest: CentronWebserviceMailType nacheinander auf 0/Exchange/Graph setzen und prüfen, dass jeweils die korrekte Implementierungsklasse instanziiert wird.
|
||||
Tracelinks: SyRS-ADM-03; SwRS-ADM-09, SwRS-ADM-10, SwRS-ADM-11, SwRS-ADM-12, SwRS-ADM-17, SwRS-ADM-18
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-ADM-04
|
||||
Titel: Kontextabhängige E-Mail-Signaturen
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Systemadministrator/Sachbearbeiter
|
||||
Vorbedingung: Ausgehende Mails (allgemein, Helpdesk intern, Helpdesk extern) sollen eine Signatur erhalten.
|
||||
Fakt: `MailSignatureBL` unterscheidet drei unabhängig konfigurierbare Signaturkontexte (Standard `MailSignatureKind`, `HelpdeskInternalMailSignatureKind`, `HelpdeskExternalMailSignatureKind`) und je Kontext eine Signaturquelle (`MailSignatureKind`-Enum: None/Outlook/Centron). Bei Quelle "Outlook" wird die Signatur aus lokalen Outlook-RTF-Dateien plus Windows-Registry-Konfiguration (`HKCU\...\Outlook\Profiles\...`) gelesen; bei Quelle "Centron" aus einer in der Datenbank hinterlegten Signatur (`AppSettingData`, Encoding 1252).
|
||||
Aussage: Das System soll pro Mail-Kontext (Standard, Helpdesk intern, Helpdesk extern) eine unabhängig konfigurierbare Signaturquelle unterstützen, wahlweise aus lokalem Outlook-Profil oder zentral in der Datenbank gepflegter Signatur.
|
||||
Ergebnis: Fachlich getrennte, kontextabhängige Signaturgestaltung; Outlook-Quelle ist jedoch an lokale Windows-Umgebung/Registry gebunden (Client-seitige Abhängigkeit).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/MailSignatureBL.cs:111-182 (GetHelpdeskExternalSignature, GetHelpdeskInternalSignature, GetDefaultSignature, GetSignature) - Begründung: Drei parallele, strukturell identische Methoden für die drei Kontexte.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/MailSignatureBL.cs:41-96 (GetDefaultOutlookSignature) - Begründung: Zeigt Registry-/Dateisystem-Abhängigkeit der Outlook-Signaturquelle inkl. `OperatingSystem.IsWindows()`-Prüfung mit Fehler "Outlook default signature can only be loaded on windows".
|
||||
Prüfidee: Für Web-/SaaS-Migration klären: Outlook-Signaturquelle ist im Web-/SaaS-Kontext (kein lokales Windows-Client-Profil) nicht sinnvoll übertragbar - Anforderung an Nachfolgesystem prüfen (nur noch zentrale Signaturverwaltung?).
|
||||
Tracelinks: StRS-ADM-03 (gemeinsamer Kommunikations-/Mail-Kontext); SyRS/SwRS: keine direkte Verknüpfung (Lücke)
|
||||
Konsolidierung: nein
|
||||
Status: belegt; HYPOTHESE bzgl. Weiterverwendung der Outlook-Quelle im Web/SaaS-Kontext (technische Prämisse "lokaler Windows-Client mit Outlook" entfällt vermutlich in einer SaaS-Architektur - im Code nicht explizit als Migrationsentscheidung dokumentiert)
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-ADM-05
|
||||
Titel: Mandantenstammdaten mit Logos und Bankverbindungen
|
||||
Ebene: StRS
|
||||
Typ: Daten
|
||||
Akteur: Systemadministrator
|
||||
Vorbedingung: Unternehmensstammdaten (Mandant) sollen gepflegt und für Belegdruck/Kommunikation verwendet werden.
|
||||
Fakt: `MandatorBL` erwartet genau einen als Standard markierten Mandanten (`Default == 1`, `GetDefaultMandator`/`GetDefaultMandatorExtended`); ein Mandant kann bis zu acht unterschiedliche Logo-/Bildvarianten hinterlegen (`PictureOne` … `PictureEight`, Zugriff über `GetMandatorLogoByIndex` mit Index 1-8, sonst Fehler "image index was out of range (index can be between 1 and 8)"). Für ESR/QR-Zahlungsreferenzen kann eines von vier hinterlegten Bankkonten je Mandant als aktiv markiert werden (`UseBankForEsr` 1-4, `GetEsrBankIndex`/`GetIBANFromEsrIndex`).
|
||||
Aussage: Das System soll pro Mandant genau einen als Standard gekennzeichneten Datensatz mit bis zu acht wählbaren Firmenlogos sowie bis zu vier hinterlegten Bankverbindungen verwalten, von denen eine für ESR/QR-Referenzen aktiv gewählt werden kann.
|
||||
Ergebnis: Mandantenfähige Stammdatenverwaltung als Grundlage für Corporate-Design (Logo) und Zahlungsverkehr je Mandant.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Company/MandatorBL.cs:19-27 (GetDefaultMandator, GetDefaultMandatorExtended) - Begründung: Zeigt Default-Flag-Semantik.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Company/MandatorBL.cs:90-125 (GetMandatorLogoByIndex) - Begründung: Zeigt Acht-Bilder-Struktur inkl. Fehlermeldung bei ungültigem Index.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Company/MandatorBL.cs:54-88 (GetEsrBankIndex, GetIBANFromEsrIndex) - Begründung: Zeigt Vier-Konten-Struktur mit wählbarem Referenzkonto.
|
||||
Prüfidee: Datenmodelltest: Mehrere Mandanten mit Default=1 in Testdaten anlegen und prüfen, welches Verhalten GetDefaultMandator zeigt (GetEntity liefert vermutlich undefiniertes Verhalten bei Mehrfachtreffern - Eindeutigkeit als Datenintegritätsregel prüfen/erzwingen).
|
||||
Tracelinks: SyRS/SwRS: keine direkte Verknüpfung (Lücke)
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
|
||||
## Dokumente & Reporting (DOC)
|
||||
|
||||
|
||||
ID: StRS-DOC-01
|
||||
Titel: Zentrale Dokumentenablage in Ordnerstruktur
|
||||
Ebene: StRS
|
||||
Typ: funktional (Geschäftsziel)
|
||||
Akteur: Sachbearbeiter (Vertrieb/Verwaltung), Administrator
|
||||
Vorbedingung: Benutzer ist an c-entron angemeldet und besitzt Zugriff auf einen Ordner (Directory)
|
||||
Fakt: `DocumentBL.AddFileToDirectory` legt Dokumente in einer Ordnerstruktur (`Directory`) ab, verknüpft Metainformationen (`DocumentMetaInformation`), setzt einen Dokumenttyp-abhängigen Icon-Index (`GetImageIndexForDocumentType`) und aktualisiert die Trefferanzahl des Ordners (`NumDocuments`). Bei Helpdesk-Ordnern wird zusätzlich ein Historieneintrag erzeugt (`HelpdeskHistoryBL.CreateHistoryForDocument`).
|
||||
Aussage: Das System soll es Sachbearbeitern ermöglichen, beliebige Dateien in einer hierarchischen Ordnerstruktur abzulegen, automatisch nach Dateityp zu kategorisieren (Icon/Typ) und bei fachlichem Bezug (z. B. Helpdesk-Vorgang) automatisch eine Historie zu führen.
|
||||
Ergebnis: Zentrale, typisierte Dokumentenablage mit Prozessanbindung.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/FileManagement/DocumentBL.cs:587-648 - Begründung: `AddFileToDirectory` Implementierung inkl. MetaInformations, ImageIndex, Historie.
|
||||
- [SEKUNDÄR] src/backend/Centron.Entities/Entities/Administration/FileManagement/Document.cs:17-54 - Begründung: Entity-Felder bestätigen Typ/Version/Directory-Modell.
|
||||
Prüfidee: UI-Test: Datei in Kundenordner hochladen, prüfen ob Icon nach Dateityp korrekt vergeben wird und `NumDocuments` im Elternordner steigt.
|
||||
Tracelinks: SyRS-DOC-01, SyRS-DOC-02, SyRS-DOC-03, SyRS-DOC-04
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-DOC-02
|
||||
Titel: Trennung öffentliche/interne Dokumentation
|
||||
Ebene: StRS
|
||||
Typ: funktional (Geschäftsziel)
|
||||
Akteur: Sachbearbeiter (interne Dokumentation/Wissensdatenbank), Management
|
||||
Vorbedingung: Benutzer hat Recht `READ_DOCUMENTATION` bzw. `READ_INTERNAL_DOCUMENTATION`
|
||||
Fakt: `DocumentationBL` verwaltet fachliche „Dokumentationen" (z. B. zu Helpdesk-Vorgängen) mit zwei getrennten Sichtbarkeitsstufen: `PublicDocumentation` (immer sichtbar) und `InternalDocumentation` (wird aus dem Ergebnis entfernt, falls der Benutzer nicht das Recht `READ_INTERNAL_DOCUMENTATION` besitzt — in allen Get-Methoden konsequent per Schleife `documentation.InternalDocumentation = null`).
|
||||
Aussage: Das System soll bei Wissens-/Vorgangsdokumentationen zwischen einer öffentlichen und einer nur intern sichtbaren Textkomponente unterscheiden und die interne Komponente rechteabhängig aus der Antwort entfernen (nicht nur UI-seitig ausblenden).
|
||||
Ergebnis: Informationstrennung zwischen kundenseitig sichtbaren und internen Vermerken.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/DocumentationArea/DocumentationBL.cs:27-95 - Begründung: Mehrere GetDocumentation*-Methoden mit identischem Muster (Rechteprüfung + Entfernen von InternalDocumentation).
|
||||
- [SEKUNDÄR] src/backend/Centron.Entities/Entities/DocumentationArea/Documentation.cs:19-23 - Begründung: Entity-Felder PublicDocumentation/InternalDocumentation.
|
||||
Prüfidee: Dokumentation mit beiden Feldern anlegen, mit Benutzer ohne READ_INTERNAL_DOCUMENTATION abrufen → InternalDocumentation muss `null` sein, nicht nur UI-verborgen.
|
||||
Tracelinks: keine direkte SyRS-Verknüpfung (Lücke - im Kandidatenset wurde keine SyRS-Ebene zur Dokumentations-Sichtbarkeit erhoben); fachlich direkt umgesetzt durch SwRS-DOC-05
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
|
||||
## Externe Integrationen & Schnittstellen (INT)
|
||||
|
||||
|
||||
ID: StRS-INT-01
|
||||
Titel: Automatisierter EDI-Belegaustausch mit Distributoren
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Distributoren/Lieferanten (ALSO, Alltron, Komsa, Herweck, ITScope, EGIS), Einkaufsabteilung
|
||||
Vorbedingung: Lieferant unterstützt elektronischen Belegaustausch (EDI)
|
||||
Fakt: Das System automatisiert den Austausch von Bestellungen, Auftragsbestätigungen, Lieferscheinen und Rechnungen mit mehreren Distributoren über unterschiedliche EDI-Formate (OpenTrans 2.1, ALSO, ALSO CH, Herweck, Komsa, Alltron, ZUGFeRD).
|
||||
Aussage: Das System soll den automatisierten, bidirektionalen elektronischen Belegaustausch (Bestellung, Auftragsbestätigung, Lieferschein, Rechnung) mit angebundenen Distributoren unterstützen, unabhängig vom jeweiligen lieferantenspezifischen Datenformat.
|
||||
Ergebnis: Reduzierter manueller Erfassungsaufwand im Einkauf, schnellere Verfügbarkeit von Bestell- und Lieferstatus.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/EDI/SupplierEDI/SupplierEdiBL.cs:754-829 (DownloadStartAsync) - Begründung: zentrale Einstiegsmethode, dispatcht je Lieferantenkonfiguration.
|
||||
- [SEKUNDÄR] docs/reference/edi/edi-architecture.md:20,108-122 - Begründung: Architekturübersicht inkl. Formattabelle je Lieferant.
|
||||
Prüfidee: Prüfen, ob für jeden aktiven Lieferanten-EDI-Vertrag ein vollständiger Order→Response→Delivery→Invoice-Zyklus im System nachvollziehbar ist.
|
||||
Tracelinks: SyRS-INT-01, SyRS-INT-02, SyRS-INT-03, SyRS-INT-04, SyRS-INT-09
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-INT-02
|
||||
Titel: Lizenzsteuerung der EDI-Integrationen
|
||||
Ebene: StRS
|
||||
Typ: funktional (Lizenzsteuerung)
|
||||
Akteur: Vertrieb/Lizenzierung, Einkaufsabteilung
|
||||
Vorbedingung: Kundenvertrag mit entsprechendem Lizenzmodul
|
||||
Fakt: EDI-Funktionalität ist über drei getrennte Lizenz-GUIDs steuerbar: `EDI_General` (klassische Lieferanten-EDI), `EDI_ITScope`, `EDI_EGIS`. Ohne aktive Lizenz wird der jeweilige Verarbeitungszweig übersprungen.
|
||||
Aussage: Das System soll die Nutzung der EDI-Anbindung (klassisches EDI, ITScope-Marktplatz, EGIS) getrennt lizenzierbar und pro Mandant aktivierbar/deaktivierbar machen.
|
||||
Ergebnis: Differenzierte Vermarktung/Paketierung der Integrationsfunktionen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/EDI/SupplierEDI/SupplierEdiBL.cs:777,978,1003,1115 - Begründung: `LicenseManager.Instance.HasLicense(LicenseGuids.EDI_*)`-Prüfungen an mehreren Verzweigungspunkten.
|
||||
Prüfidee: Prüfen, ob in einer SaaS-Neuimplementierung ein äquivalentes Feature-Flag-/Tarifmodell für Integrationen vorgesehen werden soll.
|
||||
Tracelinks: SyRS-INT-01, SyRS-INT-04
|
||||
Konsolidierung: nein
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-INT-03
|
||||
Titel: Webservice-Schnittstelle für Partnersysteme
|
||||
Ebene: StRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: Partner-/Drittsysteme, externe Anwendungen
|
||||
Vorbedingung: Partnersystem verfügt über gültiges Ticket/Zugangsdaten
|
||||
Fakt: C-ENTRON stellt selbst eine REST-artige Webservice-Schicht bereit (`CentronRestService`/`ICentronRestService`), über die externe Anwendungen per `Request<T>`/`Response<T>`-Konvention (ausschließlich POST, `[Authenticate]`-Attribut, ticketbasierte Anmeldung via `GetLoggedInUserByTicket`) auf Geschäftsobjekte zugreifen können; laut Entwicklerdokumentation auch per WSDL-Service-Reference nutzbar.
|
||||
Aussage: Das System soll externen Anwendungen/Partnersystemen eine dokumentierte, authentifizierte Webservice-Schnittstelle (Request/Response-Kontrakt) zum lesenden und schreibenden Zugriff auf Geschäftsobjekte bereitstellen.
|
||||
Ergebnis: C-ENTRON fungiert selbst als Integrationsplattform für Drittsysteme (nicht nur Konsument externer APIs).
|
||||
Belege:
|
||||
- [PRIMÄR] docs/guides/services/add-webservice-methods.md:32-66 - Begründung: dokumentierter, im Code verbindlich vorgeschriebener Webservice-Kontrakt (Namenskonvention, Attribute, Signatur).
|
||||
Prüfidee: Prüfen, welche Authentifizierungsmechanismen (Ticket-Lebensdauer, Rotation) hinter `GetLoggedInUserByTicket` stehen und ob dies für eine SaaS-Neuimplementierung durch OAuth2/OIDC ersetzt werden soll.
|
||||
Tracelinks: SyRS-INT-08
|
||||
Konsolidierung: nein
|
||||
Status: belegt; Authentifizierungsdetails [HYPOTHESE: Ticket-Mechanismus (Lebensdauer, Erneuerung) nicht im gesichteten Code verifiziert]
|
||||
|
||||
|
||||
## CentronNexus (Ticket-/Helpdesk-System) (NEX)
|
||||
|
||||
|
||||
ID: StRS-NEX-01
|
||||
Titel: Kunden-Ticketerstellung mit optionalem internen Freigabeverfahren
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Kunde (Web-Account), Support-Mitarbeiter
|
||||
Vorbedingung: Kunde erstellt Ticket über CentronNexus-Weboberfläche (Web-Account-Login).
|
||||
Fakt: `HelpdeskCustomerBL.SaveNewSimpleTicketWebAccount()` prüft für den Kundenaccount, ob "Freigabewesen" (`CustomerData.CustomerApprovalEnabledSBO`) aktiv ist. Ist es aktiv und der Benutzer kein `CUSTOMERADMINISTRATOR`, wird `ticket.HelpdeskState = null` gesetzt ("make sure the state is reseted, to have a normal flow of rejecting or accepting ticket"); ist Freigabewesen deaktiviert oder der Benutzer Administrator, wird sofort der konfigurierte Default-Status (`AppSettingsConst.HelpdeskAfterOpenDefaultState`) gesetzt. Ein Ticket mit `HelpdeskState == null` erscheint laut Code-Kommentar in `HelpdeskCustomerBL.SaveNewSimpleTicket` (Zeile 128-131) NICHT in der regulären Ticketliste, sondern gilt als rein interne Kundennotiz, bis ein Kunden-IT-Admin sie eskaliert.
|
||||
Aussage: Das System soll es Kunden ermöglichen, neue Tickets über ein Kundenportal zu erstellen; ist für den Kunden ein internes Freigabeverfahren (Freigabewesen) aktiviert, soll ein neu erstelltes Ticket zunächst ohne sichtbaren Status (interne Vorstufe) angelegt und erst nach interner Freigabe für den Support sichtbar geschaltet werden.
|
||||
Ergebnis: Zweistufiger Kunden-Ticket-Erstellungsprozess mit optionalem internen Freigabe-Gate.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Support/HelpdeskCustomerBL.cs:466-493 - Freigabewesen-Prüfung in `SaveNewSimpleTicketWebAccount`
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Support/HelpdeskCustomerBL.cs:126-141 - Kommentar/Logik zu HelpdeskState==null in `SaveNewSimpleTicket`
|
||||
Prüfidee: Kundenkonto mit aktivem Freigabewesen ein Ticket anlegen lassen und prüfen, dass es nicht im Standard-Ticket-Board erscheint, bis ein interner Nutzer es freigibt (Statuszuweisung).
|
||||
Tracelinks: SyRS-NEX-01
|
||||
Konsolidierung: nein (clusterübergreifender Hinweis: konkreter Freigabe-Workflow-Schritt evtl. Teil des CRM/Sales-Clusters, dort Rechercheergebnis abgleichen)
|
||||
Status: belegt; Freigabe-Zielaktion nicht vollständig lokalisiert (siehe HYPOTHESEN-Abschnitt)
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-NEX-02
|
||||
Titel: Auslastungsbasierte Ticket-Weiterleitung im Outlook-Add-In
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Support-Mitarbeiter
|
||||
Vorbedingung: Outlook-Add-In zeigt Kontakt-/E-Mail-Kontext eines Kunden; Mitarbeiter-Favoritenliste ist gepflegt.
|
||||
Fakt: `EmployeeFavorites.razor` erlaubt das Markieren von Mitarbeitern als Favoriten (`CentronService.CreateEmployeeFavorits`) und zeigt für jeden (Favoriten-)Mitarbeiter Live-Statistiken (`GetHelpdeskStatisticFromEmployee`: `AllOpenHelpdesks`, `HelpdesksInWork`, `HelpdesksClosedToday`, `NewHelpdesksFromToday`) als gestapelten Fortschrittsbalken an. Über den Button "Weiterleiten" wird das aktuelle Ticket per `CentronService.ForwardHelpdeskV3` an den gewählten Mitarbeiter weitergeleitet, inkl. optionalem Statuswechsel (`NewHelpdeskStateI3D`) gemäß konfigurierten Weiterleitungs-Einstellungen (`HelpdeskAfterForwardDefaultStateI3D`).
|
||||
Aussage: Das System soll dem Support-Mitarbeiter im Outlook-Add-In eine Übersicht favorisierter Kollegen mit deren aktueller Ticket-Auslastung anzeigen und die direkte Weiterleitung des aktuellen Tickets inkl. automatischem Statuswechsel an einen ausgewählten Kollegen ermöglichen.
|
||||
Ergebnis: Auslastungsbasierte, komfortable Ticket-Weiterleitung direkt aus Outlook.
|
||||
Belege:
|
||||
- [PRIMÄR] src/nexus/CentronNexus.OutlookAddIn/Ticket/EmployeeFavorites.razor:280-323 - Statistikanzeige (`GetHelpdeskPercentage`, `OnExpandEmployeeAccordianItem`)
|
||||
- [PRIMÄR] src/nexus/CentronNexus.OutlookAddIn/Ticket/EmployeeFavorites.razor:366-416 - `ForwardNow` mit `ForwardHelpdeskRequestV3DTO`, `NewHelpdeskStateI3D`
|
||||
Prüfidee: Ticket an favorisierten Mitarbeiter weiterleiten und prüfen, dass (a) Editorenliste den neuen Mitarbeiter enthält (siehe SwRS-NEX-02/SyRS-NEX-02), (b) Status gemäß konfiguriertem `HelpdeskAfterForwardDefaultStateI3D` gesetzt wird, (c) Outlook-Mail-Entwurf mit Ticketinhalt vorbereitet wird.
|
||||
Tracelinks: SyRS-NEX-02, SyRS-NEX-05, SyRS-NEX-06, SyRS-NEX-07, SyRS-NEX-11
|
||||
Konsolidierung: Kandidat: SwRS-NEX-02 (Editor-Zuweisung), SyRS-NEX-02 (Notification), SyRS-NEX-01 und SwRS-NEX-01 (Statuswechsel) - kombiniert in einem UI-Workflow.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-NEX-03
|
||||
Titel: Annahme-/Ablehnungsworkflow für neue Tickets
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Support-Mitarbeiter
|
||||
Vorbedingung: Ticket-Board (ServiceBoard) im Kanban-Modus, neues Ticket wird geöffnet/bearbeitet.
|
||||
Fakt: Der Enum `HelpdeskAfterOpenAction { Reject, Accept }` im CachedTicketList-Modul deutet auf einen Annahme-/Ablehnungs-Workflow beim Öffnen neuer Tickets im ServiceBoard hin (analog zum in StRS-NEX-01 beschriebenen kundenseitigen Freigabewesen, hier vermutlich support-seitig).
|
||||
Aussage: Das System soll es dem Support-Mitarbeiter ermöglichen, ein neu eingegangenes Ticket im ServiceBoard explizit anzunehmen oder abzulehnen.
|
||||
Ergebnis: Annahme-/Ablehnungsschritt als Teil des Ticket-Eingangs-Workflows im Web-Board.
|
||||
Belege:
|
||||
- [PRIMÄR] src/nexus/CentronNexus/ServiceBoard/CachedTicketList/Enums/HelpdeskAfterOpenAction.cs:1-7 - Enum-Definition
|
||||
Prüfidee: Neues Ticket im ServiceBoard öffnen, "Annehmen"/"Ablehnen"-Aktion ausführen und Auswirkung auf Status/Editorenliste dokumentieren.
|
||||
Tracelinks: keine direkte Verknüpfung (Lücke)
|
||||
Konsolidierung: nein
|
||||
Status: HYPOTHESE (nur Enum-Fund, Verwendungskontext nicht verifiziert)
|
||||
|
||||
---
|
||||
|
||||
ID: StRS-NEX-04
|
||||
Titel: CentronNexus als eigenständig konfigurierbare Webkomponente
|
||||
Ebene: StRS
|
||||
Typ: nicht-funktional
|
||||
Akteur: Support-Mitarbeiter, Systemadministrator
|
||||
Vorbedingung: CentronNexus-Web-Anwendung wird betrieben (separater Host `CentronNexus.Host`, konfigurierbar über `CentronNexusSettingsDTO`).
|
||||
Fakt: `CentronNexusBL` verwaltet zentrale Betriebseinstellungen: `CentronNexusUrl` (Basis-URL der Nexus-Instanz), `ServiceBoardOnlineUrl` (separate URL für das Web-Board, referenziert auch im Outlook-Add-In als Ziel-Link, siehe SyRS-NEX-05/StRS-NEX-02-Kontext `serviceboard/ticket/{I3D}`), sowie `UseNexusForPublicWebForms` (Umschalter, ob öffentliche Webformulare über CentronNexus statt eines Altsystems bedient werden).
|
||||
Aussage: Das System soll CentronNexus als eigenständig konfigurierbare Web-Anwendung mit eigener Basis-URL betreiben, wobei Systemadministratoren zentral festlegen können, ob öffentliche Web-Formulare (Kundenanfragen) über CentronNexus abgewickelt werden.
|
||||
Ergebnis: CentronNexus als austauschbare, eigenständig adressierbare Webkomponente im Gesamtsystem CentronERP.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/CentronNexus/CentronNexusBL.cs:19-54 - `GetCentronNexusSettings`/`UpdateCentronNexusSettings`
|
||||
Prüfidee: `UseNexusForPublicWebForms` umschalten und prüfen, dass öffentliche Formulare (z.B. Kontaktformular) danach tatsächlich CentronNexus statt Altsystem ansprechen.
|
||||
Tracelinks: SyRS-NEX-06
|
||||
Konsolidierung: nein (clusterübergreifender Hinweis: ggf. mit Web-Konfigurations-Cluster/WebAccountConfig/HostConfig konsolidieren)
|
||||
Status: belegt
|
||||
|
||||
|
||||
+2540
File diff suppressed because it is too large
Load Diff
+2922
File diff suppressed because it is too large
Load Diff
+331
@@ -0,0 +1,331 @@
|
||||
# Traceability-Tabelle — CentronERP
|
||||
|
||||
Konsolidierte Forward-/Backward-Traceability zwischen StRS, SyRS und SwRS, gruppiert nach Analysecluster. Leere Zellen bedeuten: auf dieser Ebene existiert für die Kette keine eigenständig extrahierte Anforderung (dokumentierte Lücke, siehe auch Analysebericht.md).
|
||||
|
||||
## Anwendungsarchitektur & Systemrahmen (ARCH)
|
||||
|
||||
| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg |
|
||||
|---|---|---|---|
|
||||
|
||||
| StRS-ARCH-01 | SyRS-ARCH-02 | SwRS-ARCH-01 | docs/reference/security/anmelden-mit-microsoft-technische-anleitung.md |
|
||||
| StRS-ARCH-06 | SyRS-ARCH-01 | SwRS-ARCH-02 | docs/reference/architecture/dtos-and-entities.md |
|
||||
| StRS-ARCH-06 | SyRS-ARCH-01 | SwRS-ARCH-03 | docs/reference/architecture/results-and-responses.md |
|
||||
| | SyRS-ARCH-10 | SwRS-ARCH-03 | src/centron/Centron.WPF.UI/Managers/CentronExceptionHandler.cs |
|
||||
| | SyRS-ARCH-05 | SwRS-ARCH-05 | docs/guides/ui/create-module.md |
|
||||
| | | SwRS-ARCH-04 | src/centron/Centron.WPF.UI/Layout/GridControlLayoutSerializer.cs |
|
||||
| | | SwRS-ARCH-06 | docs/reference/architecture/stanislaus-secret-api-documentation.md |
|
||||
| StRS-ARCH-02 | SyRS-ARCH-08 | | src/centron/Centron.WPF.UI/StartupArgs/StartupArgSynchronizer.cs |
|
||||
| StRS-ARCH-02 | SyRS-ARCH-11 | | src/centron/Centron.WPF.UI/App.xaml.cs |
|
||||
| StRS-ARCH-02 | SyRS-ARCH-14 | | docs/reference/architecture/tapi.md |
|
||||
| StRS-ARCH-02 | SyRS-ARCH-17 | | src/centron/Centron.WPF.UI/App.xaml.cs |
|
||||
| StRS-ARCH-01 | SyRS-ARCH-13 | | src/centron/Centron.WPF.UI/Managers/CentronAnalyticsManager.cs |
|
||||
| StRS-ARCH-01 | SyRS-ARCH-15 | | docs/reference/security/anmelden-mit-microsoft-technische-anleitung.md |
|
||||
| StRS-ARCH-03 | SyRS-ARCH-09 | | docs/guides/ui/localization.md |
|
||||
| StRS-ARCH-05 | SyRS-ARCH-16 | | src/backend/Centron.BL/Administration/Logins/Auth/AuthenticatorFactory.cs |
|
||||
|
||||
|
||||
## Sicherheit & Berechtigungen (SEC)
|
||||
|
||||
| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg |
|
||||
|---|---|---|---|
|
||||
|
||||
| StRS-SEC-01 | SyRS-SEC-01 | SwRS-SEC-03 | src/backend/Centron.BL/Administration/Logins/Auth/BasicAuthenticator.cs |
|
||||
| StRS-SEC-01 | SyRS-SEC-02 | | src/backend/Centron.BL/Administration/Logins/Auth/ActiveDirectoryAuthenticator.cs |
|
||||
| StRS-SEC-01 | SyRS-SEC-03 | | src/backend/Centron.BL/Administration/Logins/Auth/Authenticator.cs |
|
||||
| StRS-SEC-01 | SyRS-SEC-04 | SwRS-SEC-01 | src/backend/Centron.BL/Administration/Logins/Auth/Authenticator.cs |
|
||||
| StRS-SEC-01 | SyRS-SEC-13 | SwRS-SEC-04 | src/backend/Centron.BL/Administration/Logins/WebAccountBL.cs |
|
||||
| StRS-SEC-01 | SyRS-SEC-14 | SwRS-SEC-03 | src/backend/Centron.BL/Administration/Logins/UsersBL.cs |
|
||||
| StRS-SEC-01 | SyRS-SEC-15 | | src/backend/Centron.BL/Administration/Logins/UsersBL.cs |
|
||||
| StRS-SEC-01 | SyRS-SEC-16 | | Negativrecherche (Grep) über src/backend/Centron.BL |
|
||||
| StRS-SEC-02 | SyRS-SEC-04 | SwRS-SEC-01 | src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs |
|
||||
| StRS-SEC-02 | | SwRS-SEC-02 | src/webservice/Centron.WebServices.Core/EntitiesWrongPlace/Administration/Rights/UserRightsConst.cs |
|
||||
| StRS-SEC-03 | | SwRS-SEC-01 | src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs (SaveRightGroup/DeleteRightGroup) |
|
||||
| StRS-SEC-04 | | SwRS-SEC-01 | src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs (DeleteRightGroup) |
|
||||
| StRS-SEC-04 | | SwRS-SEC-02 | src/backend/Centron.BL/Administration/Rights/AppRightsBL.cs (GetAssignableAdminRightI3Ds) |
|
||||
| StRS-SEC-05 | SyRS-SEC-07 | SwRS-SEC-05 | src/backend/Centron.BL/Administration/Logins/TwoFactor/TwoFactorAuthBL.cs |
|
||||
| StRS-SEC-05 | SyRS-SEC-08 | | src/backend/Centron.BL/Administration/Logins/TwoFactor/EmailTwoFactorValidator.cs |
|
||||
| StRS-SEC-05 | SyRS-SEC-09 | | src/backend/Centron.BL/Administration/Logins/TwoFactor/RadiusTwoFactorValidator.cs |
|
||||
| StRS-SEC-06 | SyRS-SEC-10 | | docs/reference/security/anmelden-mit-microsoft-technische-anleitung.md |
|
||||
| StRS-SEC-07 | SyRS-SEC-11 | | src/backend/Centron.BL/PasswordManager/PasswordManagerBL.cs (GetCustomerAccessDataForExport) |
|
||||
| StRS-SEC-07 | SyRS-SEC-12 | SwRS-SEC-06 | src/backend/Centron.BL/PasswordManagementArea/PasswordManagementKeywordBL.cs |
|
||||
| | SyRS-SEC-05 | SwRS-SEC-07 | src/backend/Centron.BL/Administration/Logins/TicketBL.cs |
|
||||
| | SyRS-SEC-06 | | src/backend/Centron.BL/Administration/Logins/TicketBL.cs (RefreshTicketExpireDate) |
|
||||
|
||||
|
||||
## Stammdaten: Geschäftspartner, Kunden, Mitarbeiter (CRM)
|
||||
|
||||
| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg |
|
||||
|---|---|---|---|
|
||||
|
||||
| StRS-CRM-01 | SyRS-CRM-03 | SwRS-CRM-02 | src/backend/Centron.BL/Sales/Customers/CustomerBL.cs:382-391 |
|
||||
| StRS-CRM-02 | | SwRS-CRM-08 | src/backend/Centron.BL/Administration/DataSecurity/DataSecurityBL.cs:856-858 |
|
||||
| StRS-CRM-02 | | | src/backend/Centron.BL/Administration/DataSecurity/DataSecurityBL.cs:1152-1276 |
|
||||
| StRS-CRM-03 | | | src/backend/Centron.BL/Administration/DataSecurity/DataSecurityBL.cs:34-62 |
|
||||
| StRS-CRM-04 | | | src/backend/Centron.BL/Sales/Customers/CustomerBL.cs:73-99 |
|
||||
| | SyRS-CRM-01 | SwRS-CRM-03 | src/backend/Centron.BL/Sales/Customers/Addresses/AddressBL.cs:225-238 |
|
||||
| | SyRS-CRM-01 | SwRS-CRM-04 | src/backend/Centron.BL/Sales/Customers/StoreCustomerBL.cs:53-106 |
|
||||
| | SyRS-CRM-02 | SwRS-CRM-04 | src/backend/Centron.BL/Sales/Customers/ContactPersonBL.cs:190-220 |
|
||||
| | SyRS-CRM-04 | | src/backend/Centron.BL/EmployeeArea/EmployeeBL.cs:128-131 |
|
||||
| | SyRS-CRM-05 | | src/backend/Centron.BL/EmployeeArea/AppUserBL.cs:136-186 |
|
||||
| | SyRS-CRM-06 | SwRS-CRM-06 | src/backend/Centron.BL/EmployeeArea/AppUserBL.cs:38-55 |
|
||||
| | SyRS-CRM-07 | | src/backend/Centron.BL/Sales/Customers/CustomerBL.cs:234-240 |
|
||||
| | SyRS-CRM-08 | | src/backend/Centron.Entities/Entities/CustomerArea/Customer.cs:134-146 |
|
||||
| | SyRS-CRM-09 | | src/centron/Centron.WPF.UI/Modules/Finances/Crm/Finance/CrmFinanceView.xaml.cs:30-39 |
|
||||
| | SyRS-CRM-10 | | src/backend/Centron.BL/Sales/Customers/ContactPersonBL.cs:310-411 |
|
||||
| | SyRS-CRM-11 | | src/backend/Centron.BL/CountryArea/CountryBL.cs:190-207 |
|
||||
| | SyRS-CRM-12 | | src/backend/Centron.BL/BusinessPartner/SearchSupplierBL.cs:84-121 |
|
||||
| | | SwRS-CRM-01 | src/backend/Centron.BL/Sales/Customers/StoreCustomerBL.cs:39-51 |
|
||||
| | | SwRS-CRM-05 | src/backend/Centron.BL/Sales/Customers/CustomerBL.cs:438-597 |
|
||||
| | | SwRS-CRM-07 | src/backend/Centron.Entities/Entities/CustomerArea/Address.cs:30 |
|
||||
| | | SwRS-CRM-09 | src/backend/Centron.BL/Sales/Customers/CustomerDetails/CustomerAncestryBL.cs:33-43 |
|
||||
| | | SwRS-CRM-10 | src/backend/Centron.BL/EmployeeArea/EmployeeRfidTokenBL.cs:39-57 |
|
||||
| | | SwRS-CRM-11 | src/backend/Centron.Entities/Entities/CustomerArea/CustomerBase.cs:19-24 |
|
||||
| | | SwRS-CRM-12 | src/backend/Centron.Entities/Entities/CustomerArea/Customer.cs:48 |
|
||||
|
||||
|
||||
## Vertrieb & Einkauf (SALES)
|
||||
|
||||
| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg |
|
||||
|---|---|---|---|
|
||||
|
||||
| StRS-SALES-01 | | | src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs:9415-9440 (CheckIfClassificationIsNeeded) |
|
||||
| StRS-SALES-02 | SyRS-SALES-12 | | src/backend/Centron.BL/Purchasing/OrderSuggestionList/OrderSuggestionListBL.cs:589-733,1039-1067 |
|
||||
| | SyRS-SALES-01 | | src/backend/Centron.Interfaces/Sales/Receipts/ReceiptState.cs:6-14 |
|
||||
| | SyRS-SALES-01 | SwRS-SALES-01 | src/backend/Centron.BL/Sales/Receipts/Offers/OfferSpecificLogic.cs:245-281 |
|
||||
| | SyRS-SALES-01 | SwRS-SALES-02 | src/backend/Centron.BL/Sales/Receipts/Orders/OrderSpecificLogic.cs:233-240 |
|
||||
| | SyRS-SALES-01 | SwRS-SALES-05 | src/backend/Centron.BL/Sales/Receipts/Orders/OrderSpecificLogic.cs:262-322 |
|
||||
| | SyRS-SALES-01 | SwRS-SALES-10 | src/backend/Centron.BL/Sales/Receipts/ReceiptCompleteReasonBL.cs:63-76 |
|
||||
| | SyRS-SALES-01 | SwRS-SALES-13 | src/backend/Centron.BL/Sales/CustomerAssets/Offers/OfferBL.cs:66-81 |
|
||||
| | SyRS-SALES-02 | | src/backend/Centron.BL/Sales/Receipts/Offers/OfferSpecificLogic.cs:313-314 |
|
||||
| | SyRS-SALES-02 | SwRS-SALES-04 | src/backend/Centron.BL/Sales/Receipts/DownPayment/DownPaymentBL.cs:82-120 |
|
||||
| | SyRS-SALES-02 | SwRS-SALES-12 | src/backend/Centron.BL/Sales/Receipts/Orders/OrderSpecificLogic.cs:440-484 |
|
||||
| | SyRS-SALES-03 | | src/backend/Centron.BL/Sales/Receipts/SupplierOrders/SupplierOrderSpecificLogic.cs:296-298 |
|
||||
| | SyRS-SALES-04 | | src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs:9258-9276 |
|
||||
| | SyRS-SALES-05 | | src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs:10802-10844 |
|
||||
| | SyRS-SALES-06 | | src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs:8636-8690 |
|
||||
| | SyRS-SALES-07 | | src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs:9036-9124 |
|
||||
| | SyRS-SALES-08 | | src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs:9393-9413 |
|
||||
| | SyRS-SALES-09 | SwRS-SALES-03 | src/backend/Centron.BL/Sales/Receipts/ReceiptCartReleaseSystemBL.cs:65-298 |
|
||||
| | SyRS-SALES-10 | SwRS-SALES-03 | src/backend/Centron.BL/Sales/Receipts/ReceiptCartReleaseSystemBL.cs:193-198,356-381 |
|
||||
| | SyRS-SALES-11 | | src/backend/Centron.BL/Sales/Receipts/SupplierOrders/SupplierOrderBL.cs:35-140 |
|
||||
| | SyRS-SALES-13 | | src/backend/Centron.BL/TradePool/TradePoolBL.cs:28-101 |
|
||||
| | SyRS-SALES-14 | | src/backend/Centron.BL/TradePool/TradePoolBL.cs:147-183 |
|
||||
| | SyRS-SALES-15 | | src/backend/Centron.BL/Sales/Receipts/Offers/OfferSpecificLogic.cs:480-501 |
|
||||
| | SyRS-SALES-16 | | src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs:10205-10216 |
|
||||
| | SyRS-SALES-17 | | src/backend/Centron.BL/Sales/Receipts/Offers/OfferSpecificLogic.cs:549-551 |
|
||||
| | | SwRS-SALES-06 | src/backend/Centron.BL/Sales/Receipts/Orders/OrderSpecificLogic.cs:513-548 |
|
||||
| | | SwRS-SALES-07 | src/backend/Centron.BL/Purchasing/SupplierOrderPerBranchBL.cs:24-116 |
|
||||
| | | SwRS-SALES-08 | src/backend/Centron.BL/ProductMatrix/ProductMatrixBL.cs:165-192 |
|
||||
| | | SwRS-SALES-09 | src/backend/Centron.BL/Sales/CustomerAssets/Orders/OrderBalanceBL.cs:81-193 |
|
||||
| | | SwRS-SALES-11 | src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs:3763-3765 |
|
||||
|
||||
|
||||
## Abrechnung, Fakturierung & Verträge (BILL)
|
||||
|
||||
| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg |
|
||||
|---|---|---|---|
|
||||
| StRS-BILL-01 | SyRS-BILL-06 | | src/backend/Centron.BL/DataExchange/EDI/SaleInvoices/InvoiceZugferdBL.cs:124-156 |
|
||||
| StRS-BILL-01 | SyRS-BILL-07 | | src/backend/Centron.BL/DataExchange/EDI/SaleInvoices/InvoiceZugferdBL.cs:2092-2107 |
|
||||
| StRS-BILL-01 | SyRS-BILL-08 | | src/backend/Centron.BL/DataExchange/EDI/SaleInvoices/InvoiceZugferdBL.cs:2109-2122 |
|
||||
| StRS-BILL-01 | SyRS-BILL-09 | | src/backend/Centron.BL/DataExchange/EDI/SaleInvoices/InvoiceZugferdBL.cs:64,1033-1043 |
|
||||
| StRS-BILL-01 | SyRS-BILL-10 | | docs/reference/zugferd-field-mapping.md:355-359 (nur SEKUNDÄR, kein Primärbeleg vorhanden) |
|
||||
| StRS-BILL-01 | SyRS-BILL-11 | | src/backend/Centron.BL/DataExchange/EDI/SaleInvoices/InvoiceZugferdBL.cs:938-953 |
|
||||
| StRS-BILL-01 | SyRS-BILL-12 | | src/backend/Centron.BL/DataExchange/EDI/SaleInvoices/InvoiceZugferdBL.cs:803-811,1873-1878 |
|
||||
| StRS-BILL-01 | SyRS-BILL-17 | | docs/reference/zugferd-field-mapping.md:157-160 (nur SEKUNDÄR, kein Primärbeleg vorhanden) |
|
||||
| StRS-BILL-01 | SyRS-BILL-19 | | docs/reference/zugferd-feldzuordnung-anwender.md:331 (nur SEKUNDÄR, kein Primärbeleg vorhanden) |
|
||||
| StRS-BILL-02 | SyRS-BILL-13 | | src/backend/Centron.BL/WebServices/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaWebServiceBL.cs:790-802,2412-2415 |
|
||||
| StRS-BILL-02 | SyRS-BILL-14 | | src/backend/Centron.Entities/Entities/Sales/CustomerAssets/Contracts/ContractArticleReferenzes.cs:27-39 |
|
||||
| StRS-BILL-02 | SyRS-BILL-15 | | src/backend/Centron.BL/Sales/Receipts/ContractLists/ReceiptContractBL.cs:149-221 |
|
||||
| StRS-BILL-03 | SyRS-BILL-16 | SwRS-BILL-01 | src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs:10194-10219 |
|
||||
| StRS-BILL-04 | SyRS-BILL-01 | | src/backend/Centron.Interfaces/Sales/Receipts/ReceiptState.cs:6-14 |
|
||||
| StRS-BILL-04 | SyRS-BILL-02 | | src/backend/Centron.BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs:157-186 |
|
||||
| StRS-BILL-04 | SyRS-BILL-03 | | src/backend/Centron.BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs:86-141 |
|
||||
| StRS-BILL-04 | SyRS-BILL-04 | SwRS-BILL-02 | src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs:4936-4951 |
|
||||
| StRS-BILL-04 | SyRS-BILL-05 | | src/backend/Centron.BL/Administration/Company/NumberGroupBL.cs:62-134 |
|
||||
| StRS-BILL-04 | SyRS-BILL-18 | SwRS-BILL-05 | docs/reference/receipts/receipts-backend-architecture.md:147-204 |
|
||||
| StRS-BILL-04 | SyRS-BILL-20 | | src/backend/Centron.BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs:170-172,236-251 |
|
||||
| | | SwRS-BILL-03 | docs/reference/receipts/actionprice-system.md:196-212,306-312 |
|
||||
| | | SwRS-BILL-04 | src/centron/Centron.WPF.UI/Modules/Warehousing/ArticleManagement/OpenDialog/ActionPrice/AddActionPriceViewModel.cs:69-79 |
|
||||
| | | SwRS-BILL-06 | docs/reference/receipts/receipt-search-architecture.md:154-190 |
|
||||
|
||||
|
||||
## Zeiterfassung, Projekte & Tickets (intern) (TIME)
|
||||
|
||||
| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg |
|
||||
|---|---|---|---|
|
||||
|
||||
| StRS-TIME-01 | SyRS-TIME-03 | | Commit baa9e7bd9b; src/centron/Centron.WPF.UI/Modules/Finances/TimerBilling/Pages/TimerBillingSettingsPageViewModel.cs:195-243,440-467,563-587 |
|
||||
| StRS-TIME-01 | SyRS-TIME-04 | | src/backend/Centron.BL/Sales/Receipts/Internal/ReceiptItemTimerBL.cs:734-758,775-776,984-990 |
|
||||
| StRS-TIME-01 | SyRS-TIME-05 | SwRS-TIME-08 | src/backend/Centron.BL/Sales/Support/HelpdeskTimerBL.cs:173-341 |
|
||||
| StRS-TIME-01 | SyRS-TIME-06 | | src/backend/Centron.BL/Sales/Receipts/Internal/ReceiptItemTimerBL.cs:390-461 |
|
||||
| StRS-TIME-01 | SyRS-TIME-09 | | src/backend/Centron.BL/Sales/Support/HelpdeskTimerArticleBookingBL.cs:105-173,314-356 |
|
||||
| | SyRS-TIME-01 | SwRS-TIME-01 | src/backend/Centron.Entities/Entities/Sales/Support/HelpdeskTimerArea/HelpdeskTimer.cs:11-62 |
|
||||
| | SyRS-TIME-01 | SwRS-TIME-02 | src/backend/Centron.BL/Sales/Support/HelpdeskTimerBL.cs:353-407 |
|
||||
| | SyRS-TIME-01 | SwRS-TIME-03 | src/backend/Centron.BL/WebServices/Sales/Support/HelpdeskTimerWebServiceBL.cs:327-346 |
|
||||
| | SyRS-TIME-01 | SwRS-TIME-04 | src/backend/Centron.BL/Sales/CustomerAssets/TimerBilling/TimerBillingBL.cs:482-483 |
|
||||
| | SyRS-TIME-02 | | src/backend/Centron.BL/Sales/Support/HelpdeskTimerBL.cs:554-602 |
|
||||
| | SyRS-TIME-07 | | src/backend/Centron.BL/Sales/Support/HelpdeskTimerBL.cs:421-466 |
|
||||
| | SyRS-TIME-08 | SwRS-TIME-07 | src/backend/Centron.BL/DataExchange/Connectors/DocBeeTicketTimerBL.cs:70-145,111-177,411-550 |
|
||||
| | SyRS-TIME-10 | SwRS-TIME-15 | src/backend/Centron.BL/MyDay/MyDayBL.cs:417-468 |
|
||||
| | SyRS-TIME-11 | | src/backend/Centron.BL/Sales/Calendar/ScheduleBL.cs:2379-2508 |
|
||||
| | SyRS-TIME-12 | | src/backend/Centron.BL/Sales/Calendar/ScheduleBL.cs:362-417 |
|
||||
| | SyRS-TIME-13 | | src/backend/Centron.Entities/Entities/CustomerArea/Support/HelpdeskState.cs:6-15 |
|
||||
| | SyRS-TIME-14 | | src/backend/Centron.BL/Sales/Support/HelpdeskCloseBL.cs:120-157,200-362 |
|
||||
| | SyRS-TIME-15 | SwRS-TIME-14 | src/backend/Centron.BL/TaskManager/TaskManagementTaskBL.cs:673-715 |
|
||||
| | SyRS-TIME-16 | | src/backend/Centron.BL/TaskManager/ActionHandler/TaskManagementHelpdeskActionHandler.cs:50-58 |
|
||||
| | SyRS-TIME-17 | SwRS-TIME-15 | src/backend/Centron.BL/MyDay/MyDayNotificationsBL.cs:39-280 |
|
||||
| | | SwRS-TIME-05 | src/backend/Centron.BL/Sales/Support/HelpdeskTimerSignatureBL.cs:31-65,132-206 |
|
||||
| | | SwRS-TIME-06 | src/backend/Centron.BL/Sales/Support/HelpdeskTimerLogBL.cs:23-237 |
|
||||
| | | SwRS-TIME-09 | src/backend/Centron.Entities/Entities/TicketProjects/TicketProject.cs:5-19 |
|
||||
| | | SwRS-TIME-10 | src/backend/Centron.BL/TicketProjects/TicketProjectBL.cs:79-105,225-237 |
|
||||
| | | SwRS-TIME-11 | src/backend/Centron.BL/TicketProjects/TicketProjectBL.cs:38-58 |
|
||||
| | | SwRS-TIME-12 | src/backend/Centron.BL/TicketProjects/TicketProjectBL.cs:122-135,193-223 |
|
||||
| StRS-TIME-02 | | | src/backend/Centron.BL/AppointmentRequests/AppointmentRequestBL.cs:29-114 |
|
||||
| StRS-TIME-03 | | SwRS-TIME-13 | src/backend/Centron.BL/Projects/ProjectBL.cs:1-36 |
|
||||
|
||||
|
||||
## Lager, Logistik & Produktion (LOG)
|
||||
|
||||
| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg |
|
||||
|---|---|---|---|
|
||||
|
||||
| StRS-LOG-01 | SyRS-LOG-08 | | src/backend/Centron.BL/Warehousing/Commissions/PartialCommissionOrderBL.cs:304-324 |
|
||||
| StRS-LOG-02 | SyRS-LOG-11 | SwRS-LOG-09 | src/backend/Centron.BL/Warehousing/ArticleProduction/ArticleProductionBL.cs:457-506 |
|
||||
| StRS-LOG-02 | | SwRS-LOG-10 | src/backend/Centron.BL/Production/ProductionBL.cs:23-301 |
|
||||
| StRS-LOG-03 | | | src/backend/Centron.BL/Purchasing/OrderSuggestionList/OrderSuggestionListBL.cs:139-158 |
|
||||
| | SyRS-LOG-01 | | src/backend/Centron.BL/Logistics/Warehousing/StockBL.cs:55-75 |
|
||||
| | SyRS-LOG-02 | | src/webservice/Centron.WebServices.Core/Entities/Warehousing/InventoryManagement/InventoryState.cs:6-18 |
|
||||
| | SyRS-LOG-03 | | src/backend/Centron.BL/Warehousing/InventoryManagement/InventoryBL.cs:75-109 |
|
||||
| | SyRS-LOG-04 | SwRS-LOG-01 | src/backend/Centron.BL/Warehousing/InventoryManagement/InventoryBL.cs:379-399 |
|
||||
| | SyRS-LOG-04 | SwRS-LOG-06 | src/backend/Centron.BL/Warehousing/ArticleBL.cs:1536-1549 |
|
||||
| | SyRS-LOG-04 | SwRS-LOG-07 | src/backend/Centron.BL/Warehousing/ArticleBL.cs:1553-1559 |
|
||||
| | SyRS-LOG-05 | SwRS-LOG-05 | src/backend/Centron.BL/Warehousing/InventoryManagement/InventoryBL.cs:797-944 |
|
||||
| | SyRS-LOG-06 | | src/backend/Centron.BL/Warehousing/ArticleBL.cs:108-121 |
|
||||
| | SyRS-LOG-07 | SwRS-LOG-04 | src/backend/Centron.Interfaces/Warehousing/BarcodeState.cs:6-35 |
|
||||
| | SyRS-LOG-07 | SwRS-LOG-08 | src/backend/Centron.BL/Warehousing/BarcodeBL.cs:73-120 |
|
||||
| | SyRS-LOG-09 | | src/backend/Centron.BL/Warehousing/Commissions/OrderCommissionBL.cs:202-385 |
|
||||
| | SyRS-LOG-10 | | src/backend/Centron.BL/Warehousing/Commissions/OrderCommissionBL.cs:429-441 |
|
||||
| | SyRS-LOG-12 | | src/backend/Centron.BL/Devices/AccountDeviceBL.cs:42-107 |
|
||||
| | SyRS-LOG-13 | | src/backend/Centron.BL/Devices/AccountDeviceBL.cs:109-174 |
|
||||
| | SyRS-LOG-14 | | src/backend/Centron.BL/Logistics/Warehousing/StockBL.cs:133-151 |
|
||||
| | SyRS-LOG-15 | | src/apis/Centron.Api.Gls (Projektverzeichnis) |
|
||||
| | | SwRS-LOG-02 | src/backend/Centron.BL/Warehousing/StockManagement/ArticleStockBL.cs:74-149 |
|
||||
| | | SwRS-LOG-03 | src/backend/Centron.BL/Logistics/Warehousing/StockBL.cs:82-110 |
|
||||
| | | SwRS-LOG-11 | src/backend/Centron.BL/Warehousing/StockManagement/StoragePlaceBL.cs:35-59 |
|
||||
| | | SwRS-LOG-12 | src/backend/Centron.BL/Warehousing/BarcodeConditionBL.cs:20-80 |
|
||||
|
||||
|
||||
## Administration, Systemkonfiguration & Kommunikation (ADM)
|
||||
|
||||
| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg |
|
||||
|---|---|---|---|
|
||||
|
||||
| StRS-ADM-01 | SyRS-ADM-01 | SwRS-ADM-01 | src/backend/Centron.BL/Administration/Settings/AppSettingsBL.cs:47-65 |
|
||||
| StRS-ADM-01 | SyRS-ADM-01 | SwRS-ADM-02 | src/backend/Centron.Interfaces/Administration/Settings/ApplicationSettingID.cs:14 |
|
||||
| StRS-ADM-01 | SyRS-ADM-01 | SwRS-ADM-03 | src/backend/Centron.BL/Administration/Settings/AppSettingsBL.cs:106-152 |
|
||||
| StRS-ADM-01 | SyRS-ADM-01 | SwRS-ADM-04 | src/backend/Centron.BL/Administration/Settings/SettingsCollection.cs:106-123 |
|
||||
| StRS-ADM-02 | | SwRS-ADM-05 | src/backend/Centron.BL/Modules/ModuleBL.cs:22-42 |
|
||||
| StRS-ADM-02 | | SwRS-ADM-06 | src/backend/Centron.BL/Modules/ModuleCategoryBL.cs:26-83 |
|
||||
| | SyRS-ADM-02 | SwRS-ADM-07 | src/backend/Centron.BL/Notifications/CentronNotificationsBL.cs:79-121 |
|
||||
| | SyRS-ADM-02 | SwRS-ADM-08 | src/backend/Centron.BL/Notifications/UserNotificationBL.cs:41-117 |
|
||||
| StRS-ADM-03 | SyRS-ADM-03 | SwRS-ADM-09 | src/backend/Centron.BL/Mail/Protocols/SMTPMail.cs:160 |
|
||||
| StRS-ADM-03 | | SwRS-ADM-10 | src/backend/Centron.BL/Mail/MailSettingsBL.cs:110-227 |
|
||||
| StRS-ADM-03 | | SwRS-ADM-11 | src/backend/Centron.BL/Mail/Protocols/SMTPMail.cs:218-266 |
|
||||
| StRS-ADM-03 | | SwRS-ADM-12 | src/backend/Centron.BL/Mail/Protocols/SMTPMail.cs:151-159 |
|
||||
| StRS-ADM-03 | SyRS-ADM-03 | | src/backend/Centron.BL/Mail/Factory/TestMails.cs:1-56 |
|
||||
| StRS-ADM-03 | | SwRS-ADM-17 | src/backend/Centron.BL/Mail/Blacklist/DomainBlacklistBL.cs:15-36 |
|
||||
| StRS-ADM-03 | | SwRS-ADM-18 | src/backend/Centron.BL/Mail/MailSettingsBL.cs:233-270 |
|
||||
| StRS-ADM-04 | | | src/backend/Centron.BL/Mail/MailSignatureBL.cs:111-182 |
|
||||
| StRS-ADM-05 | | | src/backend/Centron.BL/Administration/Company/MandatorBL.cs:19-125 |
|
||||
| | | SwRS-ADM-13 | src/backend/Centron.BL/Mail/Templates/MailTemplateBL.cs:248-317 |
|
||||
| | | SwRS-ADM-14 | src/backend/Centron.BL/Mail/Templates/MailTemplateBL.cs:133-156 |
|
||||
| | | SwRS-ADM-15 | src/backend/Centron.BL/Mail/Templates/MailTemplateBL.cs:531-1037 |
|
||||
| | | SwRS-ADM-16 | src/backend/Centron.BL/Mail/Templates/MailTemplateBL.cs:1049-1061 |
|
||||
| | SyRS-ADM-04 | SwRS-ADM-19 | src/backend/Centron.BL/MailScanner/MailScannerBL.cs:57-72 |
|
||||
| | SyRS-ADM-04 | SwRS-ADM-10 | src/backend/Centron.BL/Administration/CentronConfigDb/CentronConfigurationDbBL.cs:78-110 |
|
||||
| | SyRS-ADM-05 | | src/backend/Centron.BL/Administration/CentronConfigDb/CentronConfigurationDbBL.cs:20-33 |
|
||||
| | SyRS-ADM-06 | | src/backend/Centron.BL/Administration/Licensing/LicenseManager.cs:26-40 |
|
||||
|
||||
|
||||
## Dokumente & Reporting (DOC)
|
||||
|
||||
| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg |
|
||||
|---|---|---|---|
|
||||
| StRS-DOC-01 | SyRS-DOC-01 | SwRS-DOC-01 | src/backend/Centron.BL/Administration/FileManagement/DocumentBL.cs:538-585 |
|
||||
| | SyRS-DOC-05 | SwRS-DOC-02 | src/backend/Centron.BL/Administration/FileManagement/DocumentBL.cs:74-92 |
|
||||
| StRS-DOC-01 | | SwRS-DOC-03 | src/backend/Centron.BL/Administration/FileManagement/DocumentBL.cs:196-234 |
|
||||
| StRS-DOC-01 | | SwRS-DOC-04 | src/backend/Centron.BL/Administration/FileManagement/DocumentBL.cs:680-686 |
|
||||
| StRS-DOC-02 | | SwRS-DOC-05 | src/backend/Centron.BL/DocumentationArea/DocumentationBL.cs:317-347 |
|
||||
| | SyRS-DOC-05 | SwRS-DOC-06 | src/backend/Centron.BL/ReportEngine/PdfStategy/PdfStrategies.cs:23-157 |
|
||||
| | SyRS-DOC-06 | SwRS-DOC-06 | src/backend/Centron.BL/ReportEngine/PdfStategy/PdfStrategies.cs:23-157 |
|
||||
| | SyRS-DOC-05 | SwRS-DOC-07 | src/backend/Centron.BL/ReportEngine/ReportDataBL.cs:969-985 |
|
||||
| | SyRS-DOC-09 | SwRS-DOC-08 | src/backend/Centron.BL/ReportEngine/ReportDataBL.cs:1172-1249 |
|
||||
| | SyRS-DOC-07 | SwRS-DOC-09 | src/backend/Centron.BL/TextModuleArea/TextModuleBL.cs:75-155 |
|
||||
| | SyRS-DOC-07 | SwRS-DOC-10 | src/backend/Centron.BL/Core/ReplacementBL.cs:39-96 |
|
||||
| | SyRS-DOC-07 | SwRS-DOC-11 | src/backend/Centron.BL/TextModuleArea/SalutationAndAgreementReplacementBL.cs:40-215 |
|
||||
| | SyRS-DOC-07 | SwRS-DOC-12 | src/backend/Centron.BL/TextModuleArea/TextModuleBL.cs:510-529 |
|
||||
| | SyRS-DOC-05 | SwRS-DOC-13 | src/backend/Centron.BL/ReportEngine/ReportDataBL.cs:1055-1075 |
|
||||
| StRS-DOC-01 | SyRS-DOC-02 | | src/backend/Centron.BL/Administration/FileManagement/DocumentBL.cs:425-536 |
|
||||
| StRS-DOC-01 | SyRS-DOC-03 | | src/backend/Centron.BL/Administration/FileManagement/DocumentBL.cs:1122-1199 |
|
||||
| StRS-DOC-01 | SyRS-DOC-04 | | src/backend/Centron.BL/Administration/FileManagement/DocumentBL.cs:953-1118 |
|
||||
| | SyRS-DOC-08 | | Centron.Api.docuFORM/DocuFormRestApiClient.cs:1-131 |
|
||||
|
||||
|
||||
## Externe Integrationen & Schnittstellen (INT)
|
||||
|
||||
| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg |
|
||||
|---|---|---|---|
|
||||
| StRS-INT-01 | SyRS-INT-01 | SwRS-INT-01 | src/backend/Centron.BL/EDI/SupplierEDI/ClientConnectBL.cs:56-77,177-228 |
|
||||
| StRS-INT-01 | SyRS-INT-01 | SwRS-INT-02 | docs/reference/edi/edi-import-rules.md:125-143 |
|
||||
| StRS-INT-01 | SyRS-INT-01 | SwRS-INT-03 | docs/reference/edi/edi-import-rules.md:67-91 |
|
||||
| StRS-INT-01 | SyRS-INT-01 | SwRS-INT-04 | src/backend/Centron.BL/EDI/SupplierEDI/SupplierEdiBL.cs:716-725 |
|
||||
| StRS-INT-01 | SyRS-INT-01 | SwRS-INT-18 | src/backend/Centron.BL/EDI/SupplierEDI/ClientConnectBL.cs:305-361 |
|
||||
| StRS-INT-02 | SyRS-INT-01 | | src/backend/Centron.BL/EDI/SupplierEDI/SupplierEdiBL.cs:777 |
|
||||
| StRS-INT-01 | SyRS-INT-02 | | src/backend/Centron.BL/EDI/SupplierEDI/SupplierEdiBL.cs:786,797,801,894-917 |
|
||||
| StRS-INT-01 | SyRS-INT-03 | | src/backend/Centron.BL/EDI/SupplierEDI/SupplierEdiBL.Also.cs:38 |
|
||||
| StRS-INT-01 | SyRS-INT-04 | SwRS-INT-05 | src/backend/Centron.BL/EDI/SupplierEDI/ClientConnectBL.cs:374-402 |
|
||||
| StRS-INT-02 | SyRS-INT-04 | SwRS-INT-14 | src/apis/Centron.APIs.ITscopeDataAccess/ITscopeApi.cs:36-49 |
|
||||
| | SyRS-INT-05 | | src/backend/Centron.BL/DataExchange/PaymentTransactions/PaymentTransactionBL.cs:56-66 |
|
||||
| | SyRS-INT-06 | | src/backend/Centron.BL/DataExchange/PaymentTransactions/PaymentTransactionBL.cs:233-288 |
|
||||
| | SyRS-INT-07 | SwRS-INT-09 | src/apis/Centron.APIs.FinAPI/FinApiClient.cs:266-292,332-367 |
|
||||
| StRS-INT-03 | SyRS-INT-08 | | docs/guides/services/web-service-on-linux.md:15-16,39-58,66-80 |
|
||||
| StRS-INT-01 | SyRS-INT-09 | SwRS-INT-06 | src/backend/Centron.BL/EDI/SupplierEDI/ClientConnectBL.cs:413-435,492-524 |
|
||||
| StRS-INT-01 | | SwRS-INT-07 | src/backend/Centron.BL/EDI/Zugferd/ZUGFeRD_BL.cs:38-59 |
|
||||
| StRS-INT-01 | | SwRS-INT-08 | src/apis/Centron.Api.EbInterface/EbInterfaceLogic.cs:20-77 |
|
||||
| StRS-INT-01 | | SwRS-INT-16 | src/backend/Centron.BL/EDI/SupplierEDI/ClientConnectBL.cs:563-579 |
|
||||
| StRS-INT-03 | | SwRS-INT-17 | src/backend/Centron.BL/DataExchange/Connectors/WebHookClient.cs:15-37,47-106 |
|
||||
| | | SwRS-INT-10 | src/apis/Centron.Api.Gls/CentronGlsConsts.cs:5-17 |
|
||||
| | | SwRS-INT-11 | src/apis/Centron.Api.Gls/CentronGlsLogic.cs:60-91 |
|
||||
| | | SwRS-INT-12 | src/apis/Centron.Api.Shipcloud/CentronShipcloudLogic.cs:14-28,66-106 |
|
||||
| | | SwRS-INT-13 | src/apis/Centron.APIs.CopDataAccess/CopApi.cs:32-81,109-138,170-200 |
|
||||
| | | SwRS-INT-15 | src/apis/Centron.APIs.IcecatDataAccess/IcecatApi.cs:14-33 |
|
||||
| | | SwRS-INT-19 | src/backend/Centron.BL/DataExchange/GfkExport/GfkExportBL.cs:1-60 |
|
||||
|
||||
|
||||
## CentronNexus (Ticket-/Helpdesk-System) (NEX)
|
||||
|
||||
| StRS-ID | SyRS-ID | SwRS-ID | Artefaktbeleg |
|
||||
|---|---|---|---|
|
||||
|
||||
| StRS-NEX-01 | SyRS-NEX-01 | SwRS-NEX-09 | src/backend/Centron.BL/Sales/Support/HelpdeskCustomerBL.cs:466-493 |
|
||||
| StRS-NEX-01 | SyRS-NEX-01 | SwRS-NEX-01 | src/backend/Centron.BL/Sales/Support/HelpdeskBL.cs:558-609 |
|
||||
| StRS-NEX-01 | SyRS-NEX-08 | SwRS-NEX-08 | src/backend/Centron.BL/Sales/Support/HelpdeskBL.cs:140-231 |
|
||||
| StRS-NEX-02 | SyRS-NEX-02 | SwRS-NEX-02 | src/backend/Centron.BL/NexusNotifications/NexusNotificationsBL.cs:133-174 |
|
||||
| StRS-NEX-02 | SyRS-NEX-02 | SwRS-NEX-03 | src/backend/Centron.BL/NexusNotifications/NexusNotificationsBL.cs:253-318 |
|
||||
| StRS-NEX-02 | SyRS-NEX-05 | | src/nexus/CentronNexus.OutlookAddIn/Ticket/ManageTicketTab.razor:311-337,368-411 |
|
||||
| StRS-NEX-02 | SyRS-NEX-06 | | src/nexus/CentronNexus.OutlookAddIn/Ticket/ManageTicketTab.razor:450-550 |
|
||||
| StRS-NEX-02 | SyRS-NEX-07 | | src/nexus/CentronNexus.OutlookAddIn/Ticket/ManageTicketTab.razor:766-787 |
|
||||
| StRS-NEX-02 | SyRS-NEX-11 | | src/nexus/CentronNexus.OutlookAddIn/Ticket/ManageTicketTab.razor:50-57,218-225,844-847 |
|
||||
| StRS-NEX-04 | SyRS-NEX-06 | | src/backend/Centron.BL/CentronNexus/CentronNexusBL.cs:19-54 |
|
||||
| StRS-NEX-03 | | | src/nexus/CentronNexus/ServiceBoard/CachedTicketList/Enums/HelpdeskAfterOpenAction.cs:1-7 |
|
||||
| | SyRS-NEX-02 | SwRS-NEX-04 | src/backend/Centron.BL/NexusNotifications/NexusNotificationsBL.cs:320-383 |
|
||||
| | SyRS-NEX-02 | SwRS-NEX-06 | src/backend/Centron.BL/Sales/Support/HelpdeskCustomerBL.cs:109-111,238-256 |
|
||||
| | SyRS-NEX-04 | SwRS-NEX-05 | src/backend/Centron.BL/Sales/Support/HelpdeskBL.cs:780-827 |
|
||||
| | SyRS-NEX-04 | SwRS-NEX-01 | src/backend/Centron.BL/Sales/Support/HelpdeskBL.cs:558-609 |
|
||||
| | SyRS-NEX-03 | | src/backend/Centron.BL/NexusNotifications/NexusNotificationsBL.cs:385-393 |
|
||||
| | SyRS-NEX-09 | | src/backend/Centron.Entities/Entities/ExternalHelpdesk/ExternalHelpdeskConfiguration.cs:1-11 |
|
||||
| | SyRS-NEX-10 | | src/backend/Centron.BL/NexusTicketViews/NexusTicketViewBL.cs:121-235 |
|
||||
| | | SwRS-NEX-07 | docs/features/automatic-helpdesk-creation-templates.md:159-172 |
|
||||
| | | SwRS-NEX-10 | src/backend/Centron.BL/Sales/Support/HelpdeskBL.cs:966-1004 |
|
||||
|
||||
|
||||
+564
@@ -0,0 +1,564 @@
|
||||
# RRE Rohbefunde - Cluster ADM (Administration, Systemkonfiguration & Kommunikation)
|
||||
|
||||
Projekt: CentronERP (c-entron ERP-Suite)
|
||||
Cluster-Scope: Systemeinstellungen, Mandanten-/Systemverwaltung, Customizing, Modulverwaltung, Mail/Mailings/MailScanner, Benachrichtigungen
|
||||
Agent: RRE-Recherche-Agent ADM
|
||||
Hinweis: Rohbefunde für Konsolidierung, keine finalen Anforderungs-IDs.
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-01
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: Systemadministrator
|
||||
Vorbedingung: Ein Setting soll gelesen oder geschrieben werden.
|
||||
Fakt: Das System verwaltet Anwendungseinstellungen in zwei getrennten Tabellen/Enum-Familien: der Legacy-Tabelle `Stammdat` (Zugriff über `AppSettingsConst`) und der aktuellen Tabelle `ApplicationSettings` (Zugriff über `ApplicationSettingID`). `AppSettingsBL.GetSettings`/`GetSettingsForUpdate` akzeptieren ausschließlich Werte dieser beiden Enum-Typen und werfen sonst eine Exception ("Invalid settings type").
|
||||
Aussage: Das System soll Konfigurationswerte konsistent über genau zwei unterscheidbare Einstellungs-Namensräume (Legacy und aktuell) referenzieren und beim Zugriff typsicher zwischen beiden unterscheiden.
|
||||
Ergebnis: Zugriff auf eine unbekannte/fremde Einstellungs-ID führt zu einer Exception statt eines stillen Fehlers.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Settings/AppSettingsBL.cs:47-65 (GetSettings) - Begründung: Zeigt Typprüfung und Exception "Invalid settings type".
|
||||
- [SEKUNDÄR] docs/guides/development/settings-management.md:7-31 - Begründung: Beschreibt explizit die Dual-Table-Architektur und dass neue Einstellungen nur in ApplicationSettings angelegt werden sollen.
|
||||
Prüfidee: Unit-Test: GetSettings mit gemischter Liste aus AppSettingsConst und ApplicationSettingID prüfen; GetSettings mit anderem Objekttyp muss Exception werfen.
|
||||
Konsolidierungshinweis: Basis für ADM-02, ADM-03, ADM-04.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-02
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: Entwickler/Systemadministrator (Customizing)
|
||||
Vorbedingung: Eine neue Systemeinstellung soll eingeführt werden.
|
||||
Fakt: Neue Einstellungen erhalten eine fortlaufende numerische ID aus einem im Quellcode gepflegten Kommentar ("Next Centron Settings ID"), aktuell Wert 10471 in `ApplicationSettingID.cs` Zeile 14. IDs ab 50000 ("Riverbird") sind für ein anderes Produkt reserviert und werden von c-entron.NET nicht verwendet.
|
||||
Aussage: Das System soll für jede Systemeinstellung eine eindeutige, fortlaufend vergebene numerische Kennung besitzen, die produktübergreifende ID-Bereiche (c-entron vs. Riverbird) getrennt hält.
|
||||
Ergebnis: Eindeutige Zuordnung Setting-ID zu Bedeutung; Namensraum-Trennung zwischen Produktlinien.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Interfaces/Administration/Settings/ApplicationSettingID.cs:14 - Begründung: Aktueller Zähler "Next Centron Settings ID : 10471".
|
||||
- [SEKUNDÄR] docs/guides/development/settings-management.md:33-47 - Begründung: Beschreibt Ablaufprozess für ID-Vergabe und Riverbird-Reservierung.
|
||||
Prüfidee: Prüfen ob je vergebener ID genau eine Beschreibung in ApplicationSettingDefinitions existiert (Konsistenzcheck als Build-Test denkbar).
|
||||
Konsolidierungshinweis: Ergänzt ADM-01.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-03
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System (technisch)
|
||||
Vorbedingung: Eine ApplicationSetting-ID wird erstmals angefragt, aber es existiert noch kein Datensatz.
|
||||
Fakt: `AppSettingsBL.LoadNewSettingsOptimized` legt für angefragte `ApplicationSettingID`-Werte, die weder im Session-Cache noch in der DB vorhanden sind, automatisch einen neuen `ApplicationSetting`-Datensatz mit leerer Beschreibung aus `ApplicationSettingDefinitions.Instance.GetApplicationSettingDescription(...)` an und speichert ihn in der Session.
|
||||
Aussage: Das System soll beim ersten Zugriff auf eine noch nicht existierende Einstellung automatisch einen Standard-Datensatz mit Beschreibungstext anlegen, ohne dass ein expliziter Administrations-Schritt nötig ist.
|
||||
Ergebnis: Keine Null-Referenzfehler bei neu eingeführten Settings; Selbstheilung des Datenbestands.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Settings/AppSettingsBL.cs:106-152 (LoadNewSettingsOptimized, GetDefaultEmptyInstance) - Begründung: Zeigt Anlage-auf-Anfrage-Logik inkl. Session-Cache-Optimierung.
|
||||
Prüfidee: Test: GetSettings mit einer neuen, noch nie gespeicherten ApplicationSettingID aufrufen und prüfen, dass ein Datensatz mit Default-Werten entsteht.
|
||||
Konsolidierungshinweis: Ergänzt ADM-01.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-04
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: Entwickler (API-Konsument)
|
||||
Vorbedingung: Ein Setting-Wert soll gelesen werden, evtl. ohne dass ein Datensatz existiert.
|
||||
Fakt: `SettingsCollection` bietet typisierte Getter (`GetBool`, `GetString`, `GetInt`, `GetLargeString`, `GetDecimal`, `GetDouble`, `GetDateTime`, `GetEnum<T>`) mit optionalem Default-Wert; bei Enum-Werten wird geprüft, ob der gespeicherte Int-Wert überhaupt im Enum definiert ist (`Enum.IsDefined`), sonst wird der übergebene Default zurückgegeben statt eines ungültigen Enum-Werts.
|
||||
Aussage: Das System soll beim Lesen von Einstellungen stets einen typsicheren Wert mit definiertem Fallback liefern und ungültige/undefinierte Enum-Rohwerte automatisch auf den Standardwert abbilden.
|
||||
Ergebnis: Robuste Konfigurationsauswertung auch bei inkonsistenten/veralteten Datenbankwerten (z. B. nach Enum-Änderungen).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Settings/SettingsCollection.cs:106-123 (GetEnum<T>, GetEnumOrDefault) - Begründung: Zeigt Validierung per Enum.IsDefined mit Fallback auf Default.
|
||||
Prüfidee: Test: In DB einen Enum-Setting-Wert außerhalb des gültigen Bereichs speichern (z.B. -1) und prüfen, dass GetEnum<T> den übergebenen Default zurückgibt statt zu werfen.
|
||||
Konsolidierungshinweis: Ergänzt ADM-01.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-05
|
||||
Ebene: StRS
|
||||
Typ: nicht-funktional (Architekturprinzip)
|
||||
Akteur: Systemadministrator, IT-Verantwortlicher
|
||||
Vorbedingung: Client-Anwendung möchte Einstellungen lesen/schreiben.
|
||||
Fakt: Laut Entwicklerdokumentation greift der Client "nie direkt" auf die Settings-Tabellen zu; stattdessen existieren pro fachlichem Bereich "Group Setting Classes", die Settings laden, typisiert kapseln und über dedizierte REST-API-Methoden (POST) bereitstellen (Beispiel `ReceiptWebServiceBL.GetReceiptInvoiceSettings`/`SaveReceiptInvoiceSettings`).
|
||||
Aussage: Das System soll Systemkonfiguration ausschließlich über eine serverseitige Business-Logic-Schicht mit klar definierten, fachlich gruppierten DTOs bereitstellen und den direkten Tabellenzugriff durch Clients unterbinden.
|
||||
Ergebnis: Zentrale, versionierbare Konfigurationsschnittstelle als Grundlage für eine künftige Web-/SaaS-API.
|
||||
Belege:
|
||||
- [SEKUNDÄR] docs/guides/development/settings-management.md:63-114 - Begründung: Beschreibt explizit "The client never accesses settings tables directly" sowie Group-Setting-Class-Pattern mit Beispielcode.
|
||||
- [KONTEXT] src/backend/Centron.BL/Administration/Settings/AppSettingsGroupBL.cs:1864-1887 - Begründung: Konkretes Beispiel eines Group-Setting-Zugriffs (CentronNotifications).
|
||||
Prüfidee: Architekturreview: Prüfen, ob WPF-Client tatsächlich nur über WebService-DTOs auf Settings zugreift (keine direkten SQL/DAO-Aufrufe aus UI-Schicht).
|
||||
Konsolidierungshinweis: Grundprinzip für die SaaS-Neuimplementierung (Config-Service-Schnitt).
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-06
|
||||
Ebene: SyRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: Client-Anwendung (WPF, Web, Add-Ins)
|
||||
Vorbedingung: Einstellungen sollen über die Web-Service-Schnittstelle abgerufen/gespeichert werden.
|
||||
Fakt: Laut Konvention müssen alle Setting-bezogenen API-Methoden HTTP POST verwenden (`[WebInvoke(Method = "POST", ...)]`); Get-Methoden liefern ein Settings-DTO, Save-Methoden nehmen ein DTO entgegen.
|
||||
Aussage: Das System soll für sämtliche Konfigurationsabfragen und -änderungen ausschließlich POST-basierte Endpunkte mit strukturierten DTOs anbieten (keine GET-Query-Parameter für Konfigurationsdaten).
|
||||
Ergebnis: Einheitliches, erweiterbares API-Muster für Konfigurationsdaten.
|
||||
Belege:
|
||||
- [SEKUNDÄR] docs/guides/development/settings-management.md:116-135 - Begründung: Explizite API-Pattern-Vorgabe inkl. Codebeispiel.
|
||||
Prüfidee: Stichprobenprüfung der ICentronRestService.Administration.cs Interface-Definitionen auf WebInvoke-Method-Attribute.
|
||||
Konsolidierungshinweis: Ergänzt ADM-05.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-07
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System (Startup/Migration)
|
||||
Vorbedingung: Anwendung startet oder Modulliste wird synchronisiert.
|
||||
Fakt: `ModuleBL.DoCreateMissingInternalModulesInDB` gleicht eine im Code definierte Liste von `ModuleClass` (ModuleGuid, ModuleName, Category) gegen als „intern" markierte `Module`-Datensätze in der DB ab (Vergleich der GUID case-insensitive) und legt für jedes im Code aber nicht in der DB vorhandene Modul automatisch einen neuen `Module`-Datensatz mit zugehöriger Kategorie an.
|
||||
Aussage: Das System soll interne Anwendungsmodule anhand einer im Code gepflegten Modulliste automatisch mit der Datenbank synchronisieren, sodass neue Module ohne manuellen Administrationsschritt sichtbar werden.
|
||||
Ergebnis: Modulverwaltung bleibt auch nach Software-Updates konsistent ohne manuelle DB-Pflege.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Modules/ModuleBL.cs:22-42 (DoCreateMissingInternalModulesInDB) - Begründung: Zeigt GUID-basierten Abgleich und automatisches Anlegen fehlender Module.
|
||||
Prüfidee: Test: Neues ModuleClass-Objekt mit unbekannter GUID übergeben, prüfen dass genau ein neuer Module-Datensatz inkl. Kategorie entsteht.
|
||||
Konsolidierungshinweis: Zusammenhang mit ADM-08 (Kategorien).
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-08
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System (Startup/Migration)
|
||||
Vorbedingung: Interne Modulkategorien müssen in der DB existieren.
|
||||
Fakt: `ModuleCategoryBL.CreateInternalCategories` definiert eine feste Liste interner `CentronModuleCategory`-Werte (u. a. Purchasing, Sales, Billing, Administration, BaseData, DataExchange, Controlling, Logistic, MyCentron, PasswordManager, NexowareConnect) und legt fehlende Kategorien mit deutschem Anzeigetext an (z. B. "Einkauf", "Vertrieb", "Abrechnung"). `DoGetDisplayTextForCategory` wirft eine `ArgumentOutOfRangeException`, falls für eine Kategorie kein Anzeigetext hinterlegt ist.
|
||||
Aussage: Das System soll eine feste Menge interner Modulkategorien mit lokalisiertem Anzeigetext verwalten und beim Fehlen eines Anzeigetexts einen harten Fehler erzeugen statt eine leere/inkonsistente Kategorie anzulegen.
|
||||
Ergebnis: Konsistente, vollständig übersetzte Kategorie-Struktur; Entwicklerfehler (vergessene Übersetzung) werden früh sichtbar.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Modules/ModuleCategoryBL.cs:26-83 (CreateInternalCategories, DoGetDisplayTextForCategory) - Begründung: Enthält vollständige Kategorienliste, deutsche Anzeigetexte und Exception bei fehlender Zuordnung.
|
||||
Prüfidee: Testfall: Neue CentronModuleCategory ohne case in DoGetDisplayTextForCategory hinzufügen, prüfen dass ArgumentOutOfRangeException geworfen wird ("Unknown category: ...").
|
||||
Konsolidierungshinweis: Ergänzt ADM-07.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-09
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Sachbearbeiter/Endbenutzer
|
||||
Vorbedingung: Benutzer ist angemeldet und möchte häufig genutzte Module schnell erreichen.
|
||||
Fakt: Benutzer können Module individuell als Favoriten markieren (`ModuleFavorite` verknüpft `Employee` und `Module`); die Anzeige erfolgt gruppiert nach Modulkategorie (`GetModuleFavoritesGroupedByCategory`). Beim Speichern der Favoriten wird bei technischem Fehler die Meldung "Die Favoriten konnten nicht gespeichert werden." zurückgegeben, beim Umschalten eines einzelnen Favoriten "Der Favorite konnte nicht geändert werden.".
|
||||
Aussage: Das System soll es jedem Benutzer ermöglichen, Module individuell als Favoriten zu markieren und diese nach Kategorie gruppiert anzuzeigen; Fehler beim Speichern sollen dem Benutzer mit einer verständlichen Meldung angezeigt werden.
|
||||
Ergebnis: Personalisierte, schnellere Navigation im Modulmenü je Mitarbeiter.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Modules/ModuleBL.cs:44-81 (GetModuleFavorites, SaveModuleFavorites, UpdateModuleFavorite) - Begründung: Zeigt Favoriten-Datenmodell (pro Employee) und Fehlermeldungstexte.
|
||||
- [SEKUNDÄR] src/backend/Centron.BL/Modules/ModuleCategoryBL.cs:88-113 (GetModuleFavoritesGroupedByCategory) - Begründung: Zeigt Gruppierungslogik nach Kategorie für die Anzeige.
|
||||
Prüfidee: UI-/API-Test: Favorit setzen, Session neu laden, prüfen ob Favorit weiterhin gruppiert nach Kategorie erscheint; Fehlerfall (DB nicht erreichbar) prüfen auf Fehlermeldungstext.
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-10
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (Betrieb/Datenhaltung)
|
||||
Akteur: Systemadministrator
|
||||
Vorbedingung: Systembenachrichtigungen (CentronNotification, z. B. Batch-/Schnittstellenprotokolle) sammeln sich über Zeit an.
|
||||
Fakt: `CentronNotificationsBL.CleanupCentronNotifications` löscht Benachrichtigungen automatisch, sofern die Einstellung `CentronNotificationsDeleteAutomatically` aktiv ist; die Aufbewahrungsdauer wird über `CentronNotificationsDeleteAfterXTime` (Default 14 Tage, DTO-Feld `DeleteAfterDays`) konfiguriert. Der Löschzeitpunkt wird als `DateTime.Now.AddDays(-DeleteAfterDays)` berechnet.
|
||||
Aussage: Das System soll automatisiertes, konfigurierbares Aufräumen von Systembenachrichtigungen nach einer administrierbaren Aufbewahrungsfrist unterstützen, mit einem sinnvollen Standardwert (14 Tage), falls kein Wert gepflegt ist.
|
||||
Ergebnis: Begrenztes Datenwachstum im Benachrichtigungs-/Protokollbestand ohne manuelle Administration.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Notifications/CentronNotificationsBL.cs:53-68 (CleanupCentronNotifications) - Begründung: Zeigt bedingte automatische Löschung und Datumsberechnung.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Settings/AppSettingsGroupBL.cs:1864-1887 (GetCentronNotificationsSettings/UpdateCentronNotifications) - Begründung: Zeigt Default-Wert 14 Tage und die konkreten ApplicationSettingID-Felder.
|
||||
Prüfidee: Integrationstest: DeleteAutomatically=true, DeleteAfterDays=5 setzen, Notification mit CreatedDate vor 6 Tagen anlegen, Cleanup ausführen, prüfen dass Eintrag gelöscht wird und neuere Einträge erhalten bleiben.
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-11
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: Systemadministrator
|
||||
Vorbedingung: Systembenachrichtigungen sollen gefiltert/durchsucht werden (z. B. Fehleranalyse).
|
||||
Fakt: `CentronNotificationsBL.CreateFilterExpression` erlaubt Filterung nach: nur Fehler (`LogKind.Error`/`LogKind.PartlyError`), Datum-von/-bis, konkretem `LogKind`, `ObjectKind`, `ShortSign` (Kurzzeichen) und `ObjectI3D`. `LogKind` kennt die Werte Successful, PartlyError, Error.
|
||||
Aussage: Das System soll Systembenachrichtigungen nach Status (erfolgreich/teilweise fehlerhaft/fehlerhaft), Zeitraum, Objektbezug und Bearbeiterkürzel filterbar machen.
|
||||
Ergebnis: Gezielte Fehleranalyse und Auditing für Administratoren möglich.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Notifications/CentronNotificationsBL.cs:79-121 (CreateFilterExpression) - Begründung: Vollständige Filterkriterien.
|
||||
- [PRIMÄR] src/webservice/Centron.WebServices.Core/Entities/Notifications/LogKind.cs:1-9 - Begründung: Enum-Definition der drei Status.
|
||||
Prüfidee: API-Test: Filter mit OnlyErrors=true setzen, prüfen dass nur Error/PartlyError-Einträge zurückkommen.
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-12
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: Systemadministrator/Fachbereich
|
||||
Vorbedingung: Ein Geschäftsobjekt (z. B. Workflow/Prozess) soll bei Ereignissen bestimmte Empfänger benachrichtigen.
|
||||
Fakt: `NotificationUser` (Titel, Vor-/Nachname, Telefon, E-Mail) wird über eine m:n-Bindungstabelle `NotificationUsersToObject` (ObjectKind + ObjectI3D) einem beliebigen Geschäftsobjekt zugeordnet. Beim Speichern (`UpdateUsersFromObject`) wird ein Benutzer anhand der Kombination aus Vorname/Nachname/Titel/Telefon/E-Mail dedupliziert wiederverwendet; nicht mehr referenzierte Bindungen werden entfernt.
|
||||
Aussage: Das System soll es erlauben, beliebige Kontaktpersonen (nicht zwingend Systembenutzer) objektbezogen als Benachrichtigungsempfänger zu hinterlegen, wobei identische Kontakte dedupliziert wiederverwendet werden.
|
||||
Ergebnis: Wiederverwendbare Kontaktverwaltung für Benachrichtigungsempfänger je Objektinstanz.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Notifications/UserNotificationBL.cs:41-117 (UpdateUsersFromObject) - Begründung: Zeigt Bindungslogik, Deduplizierung und Bereinigung nicht mehr benötigter Bindungen.
|
||||
Prüfidee: Test: Zwei Objekte mit identischem NotificationUser (gleiche Felder) verknüpfen, prüfen dass nur ein NotificationUser-Datensatz in der DB existiert.
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-13
|
||||
Ebene: StRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: IT-Verantwortlicher
|
||||
Vorbedingung: Das System soll E-Mails im Namen des Unternehmens versenden/empfangen.
|
||||
Fakt: Der zu verwendende Mail-Client wird zentral über die Einstellung `CentronWebserviceMailType` gesteuert und kann zwischen SMTP (Default), Microsoft Exchange (EWS) und Microsoft Graph umgeschaltet werden (`CentronMailFactory.GetMail`). Zusätzlich existiert ein globaler Testmail-Modus (`TestMails.IsEnabled`), der bei aktiven Subscribern jede reale Mail-Versendung durch einen In-Memory-Mock ersetzt.
|
||||
Aussage: Das System soll die Wahl des E-Mail-Transportprotokolls (SMTP/Exchange/Microsoft Graph) als zentrale, administrierbare Einstellung anbieten und einen von der Konfiguration unabhängigen Test-/Simulationsmodus für den Mailversand unterstützen.
|
||||
Ergebnis: Flexible Integration in unterschiedliche Kunden-Mailinfrastrukturen; sichere Testbarkeit ohne reale Mailversendung.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/Factory/CentronMailFactory.cs:26-53 (GetMail) - Begründung: Zeigt Protokollauswahl per Setting und TestMail-Vorrang.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/Factory/TestMails.cs:1-56 - Begründung: Zeigt Subscriber-Pattern für Testmail-Abfang.
|
||||
Prüfidee: Konfigurationstest: CentronWebserviceMailType nacheinander auf 0/Exchange/Graph setzen und prüfen, dass jeweils die korrekte Implementierungsklasse instanziiert wird.
|
||||
Konsolidierungshinweis: Basis für ADM-14 bis ADM-18.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-14
|
||||
Ebene: SwRS
|
||||
Typ: funktional; Workaround
|
||||
Akteur: System (technisch)
|
||||
Vorbedingung: SMTP-Client wird für den Versand aufgebaut.
|
||||
Fakt: `SMTPMail.CreateSmtpClient` aktiviert SSL zwingend (`client.EnableSsl = true`), wenn der konfigurierte Host exakt `"smtp.office365.com"` ist – unabhängig vom konfigurierten Wert der Einstellung `SmtpSslActive`. Für alle anderen Hosts gilt ausschließlich der konfigurierte Wert.
|
||||
Aussage: Das System soll für den Sonderfall Office365-SMTP verschlüsselte Übertragung erzwingen, auch wenn die SSL-Einstellung deaktiviert konfiguriert wurde.
|
||||
Ergebnis: Verhindert versehentlich unverschlüsselten Versand über Office365, führt aber zu inkonsistentem Verhalten der SSL-Einstellung zwischen Hosts (hartkodierter Sonderfall statt allgemeiner Regel).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/Protocols/SMTPMail.cs:160 (`client.EnableSsl = client.Host == "smtp.office365.com" || settings.SmtpSslActive;`) - Begründung: Hartkodierte Sonderregel für einen konkreten Hostnamen.
|
||||
Prüfidee: Konfigurationstest: Host=smtp.office365.com, SmtpSslActive=false setzen, prüfen dass EnableSsl dennoch true ist. Für Web-Neuimplementierung klären, ob dieser Sonderfall fachlich gewollt bleibt oder durch allgemeine Pflichtverschlüsselung ersetzt wird.
|
||||
Konsolidierungshinweis: Ergänzt ADM-13.
|
||||
Status: belegt; Workaround (hartkodierter Hostname als Sonderfall im Code)
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-15
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Systemadministrator
|
||||
Vorbedingung: Zugangsdaten für Mailversand werden gespeichert.
|
||||
Fakt: `MailSettingsBL` verschlüsselt `ExchangePassword` und `GraphAppSecret` mit `AESCryptoLogic` vor dem Speichern (`EncryptText`) bzw. entschlüsselt sie beim Laden (`DecryptText`). Für `SmtpPassword` (Einstellung `MailSmtpPassword`) erfolgt dagegen keinerlei Ver-/Entschlüsselung – der Wert wird als Klartext in `AppSettingsBL.GetSettingsForUpdate`/`UpdateString` gespeichert und gelesen.
|
||||
Aussage: Das System soll alle im Klartext übertragbaren Zugangsgeheimnisse für den Mailversand (inkl. SMTP-Passwort) einheitlich verschlüsselt in der Konfigurationsdatenbank ablegen.
|
||||
Ergebnis: Aktuell inkonsistenter Schutz von Zugangsdaten: Exchange/Graph-Geheimnisse sind verschlüsselt, SMTP-Passwort liegt im Klartext in der Datenbank vor.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/MailSettingsBL.cs:110 (SmtpPassword = setting.GetString(AppSettingsConst.MailSmtpPassword)) vs. Zeile 117 (ExchangePassword = this._cryptoLogic.DecryptText(...)) und Zeile 133 (GraphAppSecret = this._cryptoLogic.DecryptText(...)) - Begründung: Direkter Codevergleich zeigt fehlende Verschlüsselung nur beim SMTP-Passwort.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/MailSettingsBL.cs:205 (UpdateString(AppSettingsConst.MailSmtpPassword, settings.SmtpPassword)) vs. Zeile 212/227 (EncryptText für Exchange/Graph) - Begründung: Bestätigt fehlende Verschlüsselung beim Speichern.
|
||||
Prüfidee: Sicherheitsreview: DB-Inhalt der Stammdat-Zeile für MailSmtpPassword direkt inspizieren und mit ApplicationSetting für GraphAppSecret vergleichen (Klartext vs. Chiffrat).
|
||||
Konsolidierungshinweis: Für SaaS-Neuimplementierung: einheitliches Secret-Handling (z. B. Vault/KMS) für alle Mailprotokoll-Zugangsdaten vorsehen; vgl. ADM-26/ADM-27 (Masterkey-Verschlüsselung bei MailScanner).
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-16
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System (technisch)
|
||||
Vorbedingung: E-Mail mit mehreren Empfängern (To/CC/BCC) wird versendet.
|
||||
Fakt: `SMTPMail.CreateMailMessage` validiert jede Empfängeradresse einzeln über `DeveloperSecurity.Email.ValidateAddress`. Bei ungültiger Adresse wird diese von der jeweiligen Empfängerliste ausgeschlossen und der Ergebnisstatus auf `ResultStatus.Warning` gesetzt (mit Sammel-Meldungstext je ausgeschlossener Adresse), der Versand an die übrigen gültigen Adressen wird jedoch nicht abgebrochen.
|
||||
Aussage: Das System soll beim Mailversand ungültige Einzeladressen tolerant behandeln: sie werden von der Zustellung ausgeschlossen und dem Absender als Warnung gemeldet, ohne den gesamten Versand an die übrigen validen Empfänger zu verhindern.
|
||||
Ergebnis: Höhere Zustellzuverlässigkeit bei Massen-/Sammelmails trotz einzelner fehlerhafter Adressen; Nachvollziehbarkeit über Warnmeldung.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/Protocols/SMTPMail.cs:218-266 (CreateMailMessage, To/CC/BCC-Schleifen) - Begründung: Zeigt Try/Catch pro Adresse mit Warning-Sammlung statt Gesamtabbruch.
|
||||
Prüfidee: Test: Mail mit einer gültigen und einer syntaktisch ungültigen To-Adresse versenden; erwartet ResultStatus.Warning und Zustellung an die gültige Adresse.
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-17
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: Systemadministrator
|
||||
Vorbedingung: SMTP-Host ist in den Mailversand-Einstellungen nicht gepflegt.
|
||||
Fakt: Wird beim Aufbau des `SmtpClient` ein leerer Host übergeben, fängt `SMTPMail.CreateSmtpClient` die resultierende `ArgumentException` ab und wirft stattdessen eine `ResultException` mit der benutzerorientierten deutschen Fehlermeldung "Der Host in den SMTP-Einstellungen ist nicht gesetzt.".
|
||||
Aussage: Das System soll bei fehlender SMTP-Host-Konfiguration eine eindeutige, administratorverständliche Fehlermeldung liefern statt eines technischen Low-Level-Fehlers.
|
||||
Ergebnis: Schnellere Fehlerdiagnose durch Administratoren bei unvollständiger Mailkonfiguration.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/Protocols/SMTPMail.cs:151-159 - Begründung: Konkreter Meldungstext im Catch-Block.
|
||||
Prüfidee: Test: MailSettingsDTO mit leerem SmtpHost übergeben, prüfen dass ResultException mit exaktem Meldungstext geworfen wird.
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-18
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (Testbarkeit/Betrieb)
|
||||
Akteur: IT-Verantwortlicher/QA
|
||||
Vorbedingung: Automatisierte Tests oder Staging-Betrieb sollen keine echten E-Mails versenden.
|
||||
Fakt: `TestMails` implementiert ein statisches Subscriber-Muster (`Start`/`AddMail`), über das während der Aktivierung sämtliche über `CentronMailFactory` erzeugten Mails als `TestMail`-Instanz behandelt werden, die E-Mails nur sammelt statt zu versenden bzw. optional als serialisierte `.eml`-Datei bereitstellt (`waitForMail`).
|
||||
Aussage: Das System soll einen expliziten, laufzeitweit aktivierbaren Testmodus für den Mailversand bereitstellen, in dem E-Mails abgefangen und inspizierbar gemacht werden, statt real versendet zu werden.
|
||||
Ergebnis: Sichere automatisierte Tests von mailauslösenden Geschäftsprozessen ohne Risiko echter Zustellung.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/Factory/TestMails.cs:1-56 - Begründung: Vollständige Implementierung des Subscriber-Patterns.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/Protocols/TestMail.cs:1-82 - Begründung: Konkrete Mail-Implementierung, die nur sammelt/serialisiert statt versendet.
|
||||
Prüfidee: Testinfrastruktur-Review: Prüfen, in welchen automatisierten Testsuiten `TestMails.Start` verwendet wird und ob Staging-Umgebungen dies standardmäßig aktivieren.
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-19
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: Sachbearbeiter/Systemadministrator
|
||||
Vorbedingung: Für ein Geschäftsobjekt (z. B. Angebot, Helpdesk-Ticket) soll eine passende Mailvorlage ermittelt werden.
|
||||
Fakt: `MailTemplateBL.MailTemplate` (private Methode) löst die zu verwendende Mailvorlage über eine fest dokumentierte Prioritätskette auf: 1. Konto/Kunde (Account), 2. persönlich (Mitarbeiter), 3. Niederlassung (Branch), 4. global, 5. hartkodierter Fallback (leere Vorlage mit Referenzwerten). Eine Vorlage wird nur akzeptiert, wenn sowohl Betreff als auch Klartext-Body nicht leer sind (`CheckMailTemplate`); fehlt Betreff oder Body, wird der jeweilige Default-Text aus der `MailTemplateReference` (`DefaultSubject`/`DefaultBody`) eingesetzt.
|
||||
Aussage: Das System soll bei der Ermittlung einer E-Mail-Vorlage eine mehrstufige Fallback-Kette (kundenspezifisch → personenspezifisch → niederlassungsspezifisch → global → Systemstandard) anwenden und dabei unvollständige Vorlagen (fehlender Betreff/Text) automatisch durch definierte Standardtexte ergänzen.
|
||||
Ergebnis: Vorhersagbare, konfigurierbare Mailtexte je Kontext ohne Gefahr leerer Betreffs/Inhalte.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/Templates/MailTemplateBL.cs:248-317 (MailTemplate-Methode inkl. XML-Doc-Kommentar "MailTemplate priority fallback order") - Begründung: Enthält sowohl expliziten Kommentar zur Reihenfolge als auch die Implementierung inkl. CheckMailTemplate/HandleIfSubjectOrBodyNotDefined.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/Templates/MailTemplateBL.cs:319-361 (GetMailTemplate mit Logging pulledLocation) - Begründung: Zeigt, dass die tatsächlich verwendete Ebene ("customer"/"personal"/"branch"/"global"/"hardcoded default fallback") geloggt wird - starkes Indiz für bewusst gestaltete Fallback-Logik.
|
||||
Prüfidee: Testmatrix: Für dieselbe MailTemplateReference gezielt nur Branch- und Global-Vorlage anlegen (keine Account-/Personal-Vorlage), erwartete Ergebnis-Ebene "branch" prüfen.
|
||||
Konsolidierungshinweis: Zusammenhang mit ADM-20 (Identitätsschema) und ADM-22 (RTF-Konvertierung).
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-20
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: Systemadministrator/Entwickler
|
||||
Vorbedingung: Eine Mailvorlage soll eindeutig einem fachlichen Anwendungsfall zugeordnet werden.
|
||||
Fakt: Jede Mailvorlage wird laut Entwicklerdokumentation eindeutig über die Kombination der Felder `ObjectKind`, `ObjectI3D`, `SubObjectKind` und `TemplatePrio` identifiziert (Klasse `MailTemplateReference`); z. B. haben Angebots-Mails `ObjectKind=Offer` mit allen übrigen Feldern NULL, während `ObjectKind=Escalation` mehrere Vorlagen über unterschiedliche `SubObjectKind`-Werte unterscheidet, da kein Bezug zu einer anderen Datenbankzeile (`ObjectI3D`) existiert.
|
||||
Aussage: Das System soll Mailvorlagen über ein generisches, viergliedriges Identitätsschema (Objektart, Objekt-ID, Unterobjektart, Priorität) eindeutig referenzieren, das sowohl global gültige als auch objekt- oder fallspezifische Vorlagen abbildet.
|
||||
Ergebnis: Ein einheitliches, erweiterbares Datenmodell für beliebig viele fachliche Mailvorlagen-Typen ohne Schemaänderung je neuem Anwendungsfall.
|
||||
Belege:
|
||||
- [SEKUNDÄR] docs/guides/development/create-mail-templates.md:6-33 - Begründung: Erläutert explizit das Identitätsschema mit Beispielen (Offer, Escalation, HelpdeskType).
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/Templates/MailTemplateBL.cs:133-156 (CreateExpression) - Begründung: Konkrete Filterlogik nach ObjectKind/SubObjectKind/ObjectI3D/BranchI3D/AccountI3D/IsPersonalMailTemplate/IsActive bestätigt das Schema.
|
||||
Prüfidee: Datenmodell-Review: Prüfen ob für jede fachliche Verwendung (Offer, Order, Helpdesk, Escalation, ...) eine eindeutige MailTemplateReference in `MailTemplateReferences` registriert ist ohne Kollisionen.
|
||||
Konsolidierungshinweis: Ergänzt ADM-19.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-21
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: Sachbearbeiter
|
||||
Vorbedingung: Mailvorlage/Signatur enthält Platzhalter, die vor Versand ersetzt werden sollen.
|
||||
Fakt: `MailTemplateBL.GenerateVariables` definiert für Outlook-Mailvorlagen benannte Variablen (`TextVariableWithReplacementStrategy`), gruppiert nach fachlichen Kategorien ("Allgemein", "Bearbeiter", "Kunde", "Adresse", "Ansprechpartner"), jeweils mit einer Lambda-Ersetzungsfunktion. Mehrere Variablen besitzen zusätzlich `AlternativeNames` (z. B. "KundenNummer" alternativ "KdNummer"), um Abwärtskompatibilität zu älteren Vorlagen-Platzhaltern sicherzustellen. Die Liste wird abschließend mit `EnsureValidVariableKeys()` validiert.
|
||||
Aussage: Das System soll ein gruppiertes, benanntes Variablensystem für Mailvorlagen-Platzhalter bereitstellen, das für einzelne Variablen mehrere gültige (auch historische) Bezeichner unterstützt und die Variablendefinitionen beim Laden konsistenzprüft.
|
||||
Ergebnis: Fachlich verständliche, kategorisierte Platzhalterliste im Vorlagen-Editor; Bestandsvorlagen mit alten Variablennamen bleiben funktionsfähig.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/Templates/MailTemplateBL.cs:531-1037 (GenerateVariables) - Begründung: Vollständige Liste der Variablengruppen inkl. AlternativeNames-Mechanismus.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/Templates/MailTemplateBL.cs:1037 (`.EnsureValidVariableKeys()`) - Begründung: Zeigt explizite Validierungsroutine für Variablenschlüssel.
|
||||
Prüfidee: Test: Vorlage mit historischem Platzhalter "KdNummer" gegen aktuelle Variable "KundenNummer" prüfen, ob beide Schreibweisen korrekt ersetzt werden.
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-22
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System (technisch)
|
||||
Vorbedingung: Eine Mailvorlage mit Klartext-Body oder leerem/platzhalterartigem Inhalt wird geladen.
|
||||
Fakt: `MailTemplateBL.GetRichText` konvertiert Klartext automatisch in RTF anhand der globalen Mailschrift-Einstellungen (`MailSettingsDTO.FontFamily/FontSize/MailFontArt`), sofern der Text noch nicht im RTF-Format vorliegt (`text.IsRtf()`). Zusätzlich existiert ein dokumentierter Sonderfall: Enthält der (in Klartext umgewandelte) Body ausschließlich das Zeichen "-", wird der Body als leer behandelt ("special case when the customer wants to have an empty body").
|
||||
Aussage: Das System soll Mailvorlagen-Inhalte unabhängig vom Ursprungsformat einheitlich als RTF mit den global konfigurierten Schrifteinstellungen bereitstellen und einen projektspezifischen Sonderfall für "bewusst leerer Body" (Platzhalterzeichen "-") unterstützen.
|
||||
Ergebnis: Einheitliche Darstellung unabhängig vom Speicherformat; Kundenwunsch nach explizit leerem Mailbody wird technisch abgebildet (kein generisches, dokumentiertes Feature, sondern Einzelfall-Workaround).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/Templates/MailTemplateBL.cs:1049-1061 (GetRichText) - Begründung: Zeigt bedingte RTF-Konvertierung anhand globaler Mailschrift-Settings.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/Templates/MailTemplateBL.cs:331-333 (bodyContainsDash) - Begründung: Codekommentar bestätigt Kundenspezifischen Sonderfall.
|
||||
Prüfidee: Test: Vorlage mit Body-Inhalt "-" laden, prüfen dass der zurückgegebene Body leer ist statt des RTF-formatierten Bindestrichs.
|
||||
Konsolidierungshinweis: Ergänzt ADM-19. Für Web-Neuimplementierung klären, ob RTF als internes Format beibehalten werden soll oder durch HTML/Markdown ersetzt wird (Formatentscheidung).
|
||||
Status: belegt; Workaround (Bindestrich-Sonderfall wirkt als kundenspezifischer Einzelfall, nicht als generische Regel)
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-23
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Systemadministrator/Sachbearbeiter
|
||||
Vorbedingung: Ausgehende Mails (allgemein, Helpdesk intern, Helpdesk extern) sollen eine Signatur erhalten.
|
||||
Fakt: `MailSignatureBL` unterscheidet drei unabhängig konfigurierbare Signaturkontexte (Standard `MailSignatureKind`, `HelpdeskInternalMailSignatureKind`, `HelpdeskExternalMailSignatureKind`) und je Kontext eine Signaturquelle (`MailSignatureKind`-Enum: None/Outlook/Centron). Bei Quelle "Outlook" wird die Signatur aus lokalen Outlook-RTF-Dateien plus Windows-Registry-Konfiguration (`HKCU\...\Outlook\Profiles\...`) gelesen; bei Quelle "Centron" aus einer in der Datenbank hinterlegten Signatur (`AppSettingData`, Encoding 1252).
|
||||
Aussage: Das System soll pro Mail-Kontext (Standard, Helpdesk intern, Helpdesk extern) eine unabhängig konfigurierbare Signaturquelle unterstützen, wahlweise aus lokalem Outlook-Profil oder zentral in der Datenbank gepflegter Signatur.
|
||||
Ergebnis: Fachlich getrennte, kontextabhängige Signaturgestaltung; Outlook-Quelle ist jedoch an lokale Windows-Umgebung/Registry gebunden (Client-seitige Abhängigkeit).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/MailSignatureBL.cs:111-182 (GetHelpdeskExternalSignature, GetHelpdeskInternalSignature, GetDefaultSignature, GetSignature) - Begründung: Drei parallele, strukturell identische Methoden für die drei Kontexte.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/MailSignatureBL.cs:41-96 (GetDefaultOutlookSignature) - Begründung: Zeigt Registry-/Dateisystem-Abhängigkeit der Outlook-Signaturquelle inkl. `OperatingSystem.IsWindows()`-Prüfung mit Fehler "Outlook default signature can only be loaded on windows".
|
||||
Prüfidee: Für Web-/SaaS-Migration klären: Outlook-Signaturquelle ist im Web-/SaaS-Kontext (kein lokales Windows-Client-Profil) nicht sinnvoll übertragbar - Anforderung an Nachfolgesystem prüfen (nur noch zentrale Signaturverwaltung?).
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt; HYPOTHESE bzgl. Weiterverwendung der Outlook-Quelle im Web/SaaS-Kontext (technische Prämisse "lokaler Windows-Client mit Outlook" entfällt vermutlich in einer SaaS-Architektur - im Code nicht explizit als Migrationsentscheidung dokumentiert)
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-24
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Systemadministrator
|
||||
Vorbedingung: Eine E-Mail soll an eine bestimmte Domain versendet werden.
|
||||
Fakt: `DomainBlacklistBL.IsBlacklisted` prüft die Ziel-Domain der E-Mail-Adresse gegen eine Liste von `DomainBlacklistItem`. Einträge, die mit "@" beginnen, werden als exakte Domain-Sperre behandelt (Exact-Match auf "@"+Domain); alle übrigen Einträge werden über eine dynamisch aus dem Domainstring generierte Regex geprüft (`Regex.Replace(f.Domain, "(.)", "[$1]")` erzeugt ein Zeichen-für-Zeichen-Zeichenklassen-Pattern, kombiniert mit Anker `[@.]`), wodurch Teilstring-/Wildcard-artige Sperren auf Sub-Domain-Ebene möglich sind. Bei nicht auswertbarer E-Mail-Adresse (keine Domain extrahierbar) wird ein Fehler "Malformed E-Mail address" zurückgegeben.
|
||||
Aussage: Das System soll den Versand von E-Mails an domainbasierte Sperrlisten verhindern können, mit Unterstützung für exakte Domainsperren und musterbasierte (Teil-/Sub-Domain-)Sperren.
|
||||
Ergebnis: Verhinderung von Mailversand an unerwünschte/gesperrte Empfängerdomains (z. B. Wettbewerber, bekannte Spam-Fallen).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/Blacklist/DomainBlacklistBL.cs:15-36 (IsBlacklisted) - Begründung: Vollständige Implementierung inkl. beider Prüfmodi und Fehlerfall.
|
||||
Prüfidee: Test: Blacklist-Eintrag "@spam.de" (exakt) und "test" (Muster) anlegen; prüfen dass "user@spam.de" gesperrt ist und "user@mytest.de" ebenfalls über Musterprüfung erkannt wird; ungültige Adresse ohne "@" liefert Fehler.
|
||||
Konsolidierungshinweis: HYPOTHESE bzgl. genauer fachlicher Bedeutung des Nicht-"@"-Musters, da die Regex-Konstruktion technisch komplex/unklar dokumentiert ist (keine Kommentare im Code) - Klärung mit Fachbereich empfohlen, ob dies bewusst Sub-Domain-Wildcards abbilden soll.
|
||||
Status: belegt; Detailverhalten der Musterprüfung als HYPOTHESE markiert (fehlende Dokumentation der Regex-Absicht im Code)
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-25
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: Systemadministrator
|
||||
Vorbedingung: Ausgehende Mails zu verschiedenen Geschäftsvorgängen sollen im Antworttext erkennbar sein (Tracking).
|
||||
Fakt: `MailSettingsBL.GetMailTrackingSettings`/`UpdateMailTrackingSettings` verwalten pro Geschäftsobjekt-Typ ein eigenes Tracking-Schlüsselwort: Angebot (`MailTrackingOffer`), Auftrag (`MailTrackingOrder`), Lieferschein (`MailTrackingDeliveryList`), Rechnung (`MailTrackingInvoice`), Helpdesk (`MailTrackingHelpdesk`).
|
||||
Aussage: Das System soll für die zentralen vertriebs-/serviceseitigen Mailvorgänge (Angebot, Auftrag, Lieferschein, Rechnung, Helpdesk) jeweils ein eigenständig konfigurierbares Tracking-Schlüsselwort unterstützen.
|
||||
Ergebnis: Zuordenbarkeit eingehender Antwortmails zu ursprünglichen Geschäftsvorgängen anhand konfigurierbarer Schlüsselwörter.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Mail/MailSettingsBL.cs:233-270 (GetMailTrackingSettings, UpdateMailTrackingSettings) - Begründung: Vollständige DTO-Feldliste der fünf Tracking-Bereiche.
|
||||
Prüfidee: Funktionstest: Tracking-Keyword für "Angebot" setzen, prüfen dass es korrekt persistiert und beim Laden zurückgegeben wird; Zusammenspiel mit MailScanner (Zuordnungslogik) als Anschlussfrage prüfen.
|
||||
Konsolidierungshinweis: Zusammenhang mit MailScanner-Cluster (ADM-26 ff.) - technischer Verwendungszweck der Keywords in der Zuordnungslogik des MailScanners wurde in diesem Rechercheumfang nicht weiter verfolgt.
|
||||
Status: belegt; HYPOTHESE bzgl. exakter Verwendung der Tracking-Keywords beim Mailempfang (Code der Auswertung nicht in diesem Rechercheumfang gelesen)
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-26
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Systemadministrator
|
||||
Vorbedingung: MailScanner-Profil mit Zugangsdaten (Passwort, OAuth-Client-Secret) für automatisiertes Postfach-Abholen wird gespeichert/gelesen.
|
||||
Fakt: `MailScannerBL.EncryptProperties`/`DecryptProperties` verschlüsseln/entschlüsseln die Felder `Password` und `ClientSecret` eines `MailScannerProfile` über `CentronConfigurationDbBL.EncryptWithMasterKey`/`DecryptWithMasterKey`. Diese Methoden verwenden einen zentralen, separat verwalteten "Hotline-Masterkey" (`GetHotlineMasterKey`) für eine zusätzliche AES-Verschlüsselungsebene; ist kein Masterkey hinterlegt, liefert die Operation den Fehler "Es wurde kein Masterkey hinterlegt" statt eines unverschlüsselten Werts.
|
||||
Aussage: Das System soll Zugangsgeheimnisse für automatisierte Postfachanbindungen (MailScanner-Profile) nur unter Verwendung eines zentral hinterlegten Masterkeys speichern/entschlüsseln können und die Operation bei fehlendem Masterkey mit einer definierten Fehlermeldung verweigern statt unverschlüsselt zu persistieren.
|
||||
Ergebnis: Zusätzliche Schutzebene für hochsensible Postfach-Zugangsdaten (u. a. OAuth Client Secrets); "Fail-safe" bei fehlendem Masterkey statt stillem Klartext-Fallback.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/MailScanner/MailScannerBL.cs:90-116 (DecryptProperties, EncryptProperties) - Begründung: Zeigt zwei verschlüsselte Felder und Fehlerweiterleitung bei Fehlschlag.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/CentronConfigDb/CentronConfigurationDbBL.cs:78-110 (EncryptWithMasterKey, DecryptWithMasterKey) - Begründung: Zeigt exakte Fehlermeldung "Es wurde kein Masterkey hinterlegt" und AES-Verschlüsselung mit Masterkey als Parameter.
|
||||
- [KONTEXT] src/backend/Centron.Entities/Entities/MailScanner/MailScannerProfile.cs:9-23 - Begründung: Zeigt betroffene Felder (Password, ClientSecret, ClientId, TenantId) im Datenmodell.
|
||||
Prüfidee: Test: Masterkey aus Konfiguration entfernen, SaveProfile mit gesetztem Password aufrufen, erwarteter Fehler statt Speicherung im Klartext.
|
||||
Konsolidierungshinweis: Vergleich mit ADM-15 (inkonsistentes Schutzniveau je Zugangsdaten-Typ im Gesamtsystem).
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-27
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Systemadministrator
|
||||
Vorbedingung: Der "Hotline-Masterkey" (siehe ADM-26) muss irgendwo persistiert werden.
|
||||
Fakt: `CentronConfigurationDbBL` unterstützt zwei austauschbare Speicherorte für den Masterkey über das Strategy-Pattern `IMasterPasswordStorage`: `MasterPasswordConfigurationDatabaseStorage` (Konfigurationsdatenbank) und `MasterPasswordSecureFileStorage` (sichere Datei), gesteuert über die Einstellung `MasterPasswordSaveLocation` aus den Password-Manager-Einstellungen.
|
||||
Aussage: Das System soll dem Administrator die Wahl lassen, den zentralen Masterkey wahlweise in der Konfigurationsdatenbank oder in einer separaten sicheren Datei außerhalb der Datenbank zu speichern.
|
||||
Ergebnis: Flexibilität zwischen zentraler (datenbankgebundener) und dezentraler (dateibasierter) Schlüsselverwahrung je nach Sicherheitsanforderung des Kunden.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/CentronConfigDb/CentronConfigurationDbBL.cs:20-33,52-66 (Dictionary _masterPasswordStorages, IsHotlineMasterKeyAvailable, SetHotlineMasterKey) - Begründung: Zeigt zwei konkrete Storage-Implementierungen und settingsgesteuerte Auswahl.
|
||||
Prüfidee: Konfigurationstest: MasterPasswordSaveLocation zwischen beiden Werten umschalten und prüfen, dass GetHotlineMasterKey konsistent aus dem jeweils aktiven Speicherort liest.
|
||||
Konsolidierungshinweis: Ergänzt ADM-26. Für SaaS-Neuimplementierung: Datei-basierte Speicherung (SecureFile) ist in einer gehosteten Multi-Tenant-Umgebung ggf. nicht sinnvoll übertragbar (HYPOTHESE, da lokale Serverdatei voraussetzt) - Klärung mit Fachbereich empfohlen.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-28
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Systemadministrator
|
||||
Vorbedingung: Ein Benutzer möchte MailScanner-Profile (Postfach-Abholkonfigurationen) einsehen.
|
||||
Fakt: `MailScannerBL.GetProfiles` prüft vor dem Laden der Profile explizit das Recht `UserRightsConst.VirtualMailAssistant.ACCESS_VMA_MODULE` über `AppRightsBL.CheckRightsFromUser`; fehlt das Recht, wird ein Fehler "Fehlendes Recht VMA Profile zu laden" mit Code `DefaultMessageCodes.RightCheckFailed` zurückgegeben, ohne dass Profildaten (inkl. verschlüsselter Zugangsdaten) geladen werden. Andere Methoden derselben Klasse (`SaveProfile`, `DeleteProfile`, `SaveTasks`) enthalten keine sichtbare Rechteprüfung.
|
||||
Aussage: Das System soll den lesenden Zugriff auf MailScanner-Profile an ein dediziertes Benutzerrecht ("Virtual Mail Assistant"-Modulzugriff) knüpfen.
|
||||
Ergebnis: Eingeschränkte Sichtbarkeit sensibler Postfach-Konfigurationen auf berechtigte Benutzer.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/MailScanner/MailScannerBL.cs:57-72 (GetProfiles) - Begründung: Enthält konkrete Rechteprüfung und Fehlermeldungstext.
|
||||
Prüfidee: Berechtigungstest: Benutzer ohne ACCESS_VMA_MODULE-Recht ruft GetProfiles auf, erwartet Fehlermeldung statt Daten. Ergänzend: Rechteprüfung für Save/Delete/SaveTasks im Code verifizieren (evtl. Lücke).
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt; HYPOTHESE bzgl. Vollständigkeit der Rechteprüfung (Save/Delete/SaveTasks zeigten im gelesenen Code keine erkennbare Rechteprüfung - ggf. an anderer Stelle z. B. WebService-Layer abgesichert, nicht abschließend verifiziert)
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-29
|
||||
Ebene: StRS
|
||||
Typ: Daten
|
||||
Akteur: Systemadministrator
|
||||
Vorbedingung: Unternehmensstammdaten (Mandant) sollen gepflegt und für Belegdruck/Kommunikation verwendet werden.
|
||||
Fakt: `MandatorBL` erwartet genau einen als Standard markierten Mandanten (`Default == 1`, `GetDefaultMandator`/`GetDefaultMandatorExtended`); ein Mandant kann bis zu acht unterschiedliche Logo-/Bildvarianten hinterlegen (`PictureOne` … `PictureEight`, Zugriff über `GetMandatorLogoByIndex` mit Index 1-8, sonst Fehler "image index was out of range (index can be between 1 and 8)"). Für ESR/QR-Zahlungsreferenzen kann eines von vier hinterlegten Bankkonten je Mandant als aktiv markiert werden (`UseBankForEsr` 1-4, `GetEsrBankIndex`/`GetIBANFromEsrIndex`).
|
||||
Aussage: Das System soll pro Mandant genau einen als Standard gekennzeichneten Datensatz mit bis zu acht wählbaren Firmenlogos sowie bis zu vier hinterlegten Bankverbindungen verwalten, von denen eine für ESR/QR-Referenzen aktiv gewählt werden kann.
|
||||
Ergebnis: Mandantenfähige Stammdatenverwaltung als Grundlage für Corporate-Design (Logo) und Zahlungsverkehr je Mandant.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Company/MandatorBL.cs:19-27 (GetDefaultMandator, GetDefaultMandatorExtended) - Begründung: Zeigt Default-Flag-Semantik.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Company/MandatorBL.cs:90-125 (GetMandatorLogoByIndex) - Begründung: Zeigt Acht-Bilder-Struktur inkl. Fehlermeldung bei ungültigem Index.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Company/MandatorBL.cs:54-88 (GetEsrBankIndex, GetIBANFromEsrIndex) - Begründung: Zeigt Vier-Konten-Struktur mit wählbarem Referenzkonto.
|
||||
Prüfidee: Datenmodelltest: Mehrere Mandanten mit Default=1 in Testdaten anlegen und prüfen, welches Verhalten GetDefaultMandator zeigt (GetEntity liefert vermutlich undefiniertes Verhalten bei Mehrfachtreffern - Eindeutigkeit als Datenintegritätsregel prüfen/erzwingen).
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ADM-30
|
||||
Ebene: SyRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: IT-Verantwortlicher
|
||||
Vorbedingung: Die Anwendung soll ihre Lizenzberechtigung prüfen.
|
||||
Fakt: `LicenseManager` bezieht Lizenzinformationen über einen externen "c-entron Office"-Lizenzserver-Client (`OfficeClient`/`FakeOfficeClient`), wobei Zusatzdaten zur Lizenzbindung aus der Zieldatenbank stammen (`DatabaseId`, `DatabaseName`, `DatabaseCreatedDate`, `DatabaseOwnerSid` über `SQLManagementBL.GetDatabaseInfosForLicenseServer`) sowie Maschinenname und Windows-Dienstname. Für den Web-Service-Kontext wird statt eines direkten Office-Clients ein `FakeOfficeClient` verwendet, der die Lizenzdatei stattdessen über den eigenen Web-Service bezieht, mit deaktivierter Hardware-ID-Prüfung (`CheckIfLicenseIsValidForHardwareIDs = false`).
|
||||
Aussage: Das System soll seine Nutzungsberechtigung über einen zentralen, produktübergreifenden Lizenzserver prüfen, wobei die Lizenz an eine konkrete Datenbankinstanz (nicht nur an Hardware) gebunden werden kann, und im mehrstufigen Web-Service-Betrieb einen alternativen Lizenzbezugsweg ohne Hardware-Bindung unterstützen.
|
||||
Ergebnis: Zentral steuerbare Produktlizenzierung (Feature-/Anzahl-Gating je Lizenz), die für eine SaaS-Multi-Tenant-Architektur grundlegend überarbeitet werden müsste (Hardware-/Einzel-DB-Bindung passt nicht zu Multi-Tenant-SaaS).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Licensing/LicenseManager.cs:26-40 (ILicenseManager Interface: HasLicense, CheckLicense, GetLicenseCount, GetLicenseProducts) - Begründung: Zeigt Funktionsumfang der Lizenzprüfung.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Licensing/LicenseManager.cs:47-115 (SettingsForWebService, GetAdditionalData) - Begründung: Zeigt Datenbank-/Maschinenbindung der Lizenz.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Licensing/LicenseManager.cs:117-139 (SettingsForCentronNet, FakeOfficeClient, CheckIfLicenseIsValidForHardwareIDs=false) - Begründung: Zeigt alternativen Lizenzweg für Web-Service-Kontext.
|
||||
Prüfidee: Architekturklärung mit Fachbereich: Wie soll Lizenzierung/Feature-Gating in einer Multi-Tenant-SaaS-Architektur erfolgen (aktuelles Modell ist On-Premise/Einzelinstallation-zentriert)?
|
||||
Konsolidierungshinweis: Zentrale, potenziell größte Architekturänderung für SaaS-Migration - sollte in Konsolidierung mit hoher Priorität markiert werden.
|
||||
Status: belegt; HYPOTHESE bzgl. Übertragbarkeit des Lizenzmodells auf SaaS (im Code keine Aussage zu geplanter SaaS-Lizenzierung, nur aktuelles On-Premise-Modell belegt)
|
||||
|
||||
---
|
||||
|
||||
## Abdeckung
|
||||
|
||||
**Gelesen (tiefgehend, mit Zeilenbezug zitiert):**
|
||||
- src/backend/Centron.BL/Administration/Settings/AppSettingsBL.cs
|
||||
- src/backend/Centron.BL/Administration/Settings/SettingsCollection.cs
|
||||
- src/backend/Centron.BL/Administration/Settings/UpdateSettingsCollection.cs
|
||||
- src/backend/Centron.Interfaces/Administration/Settings/ApplicationSettingID.cs (Ausschnitt: ID-Zähler)
|
||||
- src/backend/Centron.BL/Modules/ModuleBL.cs
|
||||
- src/backend/Centron.BL/Modules/ModuleCategoryBL.cs
|
||||
- src/backend/Centron.BL/Modules/ModuleClass.cs
|
||||
- src/backend/Centron.BL/Notifications/CentronNotificationsBL.cs
|
||||
- src/backend/Centron.BL/Notifications/UserNotificationBL.cs
|
||||
- src/webservice/Centron.WebServices.Core/Entities/Notifications/CentronNotificationsSettingsDTO.cs
|
||||
- src/webservice/Centron.WebServices.Core/Entities/Notifications/LogKind.cs
|
||||
- src/backend/Centron.BL/Administration/Settings/AppSettingsGroupBL.cs (Ausschnitte: CentronNotifications, RmaSettings)
|
||||
- src/backend/Centron.BL/Mail/MailSettingsBL.cs
|
||||
- src/backend/Centron.BL/Mail/Blacklist/DomainBlacklistBL.cs
|
||||
- src/backend/Centron.BL/Mail/Templates/MailTemplateBL.cs (vollständig)
|
||||
- src/backend/Centron.BL/Mailings/MailingTemplateBL.cs
|
||||
- src/backend/Centron.BL/Mailings/MailingDataBL.cs
|
||||
- src/backend/Centron.BL/Customizations/CustomTables/CustomTableBL.cs
|
||||
- src/backend/Centron.BL/MailScanner/MailScannerBL.cs
|
||||
- src/backend/Centron.BL/Mail/Factory/CentronMailFactory.cs
|
||||
- src/backend/Centron.BL/Mail/Factory/TestMails.cs
|
||||
- src/backend/Centron.BL/Mail/Protocols/SMTPMail.cs
|
||||
- src/backend/Centron.BL/Mail/Protocols/TestMail.cs
|
||||
- src/backend/Centron.BL/Mail/Protocols/GraphMail.cs (Fehlerbehandlung, stichprobenartig via Grep)
|
||||
- src/backend/Centron.BL/Mail/MailSignatureBL.cs
|
||||
- src/backend/Centron.BL/Administration/CentronConfigDb/CentronConfigurationDbBL.cs
|
||||
- src/backend/Centron.BL/Administration/Company/MandatorBL.cs
|
||||
- src/backend/Centron.BL/Administration/Licensing/LicenseManager.cs (erste ~150 Zeilen)
|
||||
- src/backend/Centron.Entities/Entities/MailScanner/MailScannerProfile.cs
|
||||
- docs/guides/development/settings-management.md (vollständig)
|
||||
- docs/guides/development/create-mail-templates.md (vollständig)
|
||||
|
||||
**Ausgelassen / nur oberflächlich gestreift (bekannte Lücken):**
|
||||
- src/backend/Centron.BL/Mail/Exchange/* (ExchangeMail.cs, EwsHelper) - nicht gelesen; Exchange-Protokoll-Details (EWS-spezifische Validierung/Fehlermeldungen) fehlen.
|
||||
- src/backend/Centron.BL/Mail/Protocols/GraphMail.cs - nur Fehlermeldungstexte per Grep erfasst, keine Volllektüre (OAuth-Flow, Token-Handling nicht im Detail analysiert).
|
||||
- src/backend/Centron.BL/Mail/MailFormatting/* (RichEditMailMessageExporter, SignatureReplacementBL, StringToHtmlConverter) - nur indirekt über Aufrufe in SMTPMail/MailSignatureBL erschlossen, keine Volllektüre.
|
||||
- src/backend/Centron.BL/Mail/VariableReplacement/PlmReplacementBL.cs - nicht gelesen.
|
||||
- src/backend/Centron.BL/Administration/AccessTokens, Applications, ArtificialIntelligence, BackgroundServices, BookKeepingAccountSystems, Connections, DataSecurity, Documents, Employees, FileManagement, Logins, PerformanceTests, PhoneSettings, Portal, Profiling, Rights, SQLManagement, Scripts, Themes, WebServiceConfiguration, Masterdata - nicht untersucht (teilweise thematisch näher an anderen Clustern wie Rechte/Sicherheit oder Stammdaten, ggf. Überschneidung mit Parallel-Agenten).
|
||||
- src/backend/Centron.BL/Administration/Mandatory/* (u. a. TextFormattingBL, referenziert von MandatorBL) - nicht gelesen.
|
||||
- src/backend/Centron.BL/Administration/Environments/* (RegistryBL, ReportPrintingBL, SqlServerBL) - nur Verzeichnisliste erfasst, keine Lektüre (Betriebs-/Infrastruktur-Einstellungen, potenziell SyRS-relevant für Web-/SaaS-Migration).
|
||||
- src/backend/Centron.BL/Administration/CentronConfigDb/MasterPasswordConfigurationDatabaseStorage.cs und MasterPasswordSecureFileStorage.cs - nur indirekt über CentronConfigurationDbBL erschlossen, keine Volllektüre der konkreten Speicherimplementierungen.
|
||||
- src/backend/Centron.BL/Administration/CompanyInformations/CompanyBL.cs, Company/BranchBL.cs, NumberGroupBL.cs - nicht gelesen (Filialen-/Nummernkreisverwaltung, ggf. eigenständige Kandidaten für Stammdaten-Cluster).
|
||||
- src/backend/Centron.BL/SystemArea/SystemTableI3DBL.cs - nicht gelesen.
|
||||
- Mail-Repositories/DAO-Schicht (z. B. MailTemplateRepository, MailTemplateFolderRepository) - nicht gelesen, nur über BL-Aufrufe referenziert.
|
||||
- WebService-/API-Schicht (ICentronRestService.Administration.cs, CentronRestService.Administration.cs) - nicht im Detail geprüft; API-Signaturen (Parameter, Rückgabetypen, Rechteprüfungen auf Service-Ebene) wurden nicht verifiziert, nur aus BL-Layer erschlossen.
|
||||
- Frontend/WPF-Views (ViewModels, XAML) für Settings/Module/Mail-Verwaltung - nicht untersucht; UI-Texte/Validierungsmeldungen dort ggf. zusätzlich relevant für SwRS.
|
||||
- ApplicationSettingDefinitions.cs (Beschreibungstexte) - nicht vollständig gelesen (nur referenziert), könnte weitere Detailregeln zu einzelnen Settings enthalten.
|
||||
|
||||
**Bekannte generelle Lücken:**
|
||||
- Statusmaschinen für Mailings (MailingData.Version=2-Filterung deutet auf eine ältere Version-1-Struktur hin, die nicht weiter untersucht wurde) - Migrationslogik zwischen Version 1 und 2 unklar.
|
||||
- Fachliche Bedeutung des MailScanner-Workflow-Engine-Zusammenspiels (ProcessBL, MailScannerWorkflowProcessDTO) wurde nur oberflächlich behandelt, nicht die eigentliche Verarbeitungslogik (Regeln, wann/wie eingehende Mails verarbeitet werden).
|
||||
- Rechteprüfung war nur für MailScannerBL.GetProfiles eindeutig im BL-Code sichtbar; ob andere Administrations-/Settings-Endpunkte in der WebService-Schicht (nicht BL) zusätzliche Rechteprüfungen haben, wurde nicht verifiziert.
|
||||
+570
@@ -0,0 +1,570 @@
|
||||
# Cluster ARCH — Anwendungsarchitektur / Shell / Querschnittsfunktionen
|
||||
|
||||
Rohbefunde (Zwischenformat) für Reverse Requirements Engineering an CentronERP (c-entron.NET, C#/WPF/XAML, MSSQL).
|
||||
Quellbasis: `C:\DEV\MasterArbeit\QuellCode\CentronERP` (nur gelesen, nicht verändert).
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-01
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (ISO25010: Übertragbarkeit / Anpassbarkeit)
|
||||
Akteur: IT-Administrator (Betreiber), Systemarchitekt
|
||||
Vorbedingung: Installation der c-entron.NET Desktop-Anwendung
|
||||
Fakt: Der Client unterstützt wahlweise eine direkte SQL-Server-Verbindung oder eine Verbindung über den c-entron Web-Service (`CentronConnectionType.SqlServer` vs. `CentronConnectionType.CentronWebServices`). Jedes Fachmodul deklariert über `ICentronAppModuleController.SupportsConnectionTypes`, welche Verbindungsarten es unterstützt (laut Doku-Kommentar "sollte immer beides sein").
|
||||
Aussage: Das System soll wahlweise über eine direkte Datenbankverbindung oder über eine Web-Service-Schicht (REST/SOAP-artig) betrieben werden können, wobei Fachmodule beide Betriebsarten unterstützen müssen.
|
||||
Ergebnis: Zwei-Schichten-Architektur mit austauschbarer Datenzugriffsstrategie; Grundlage für spätere Web-/SaaS-Migration (Web-Service-Pfad ist der näher an SaaS liegende Modus).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Interfaces/Administration/Connections/CentronConnectionType.cs:6-12 - Enum mit den zwei Werten SqlServer/CentronWebServices
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI.Extension/Modules/ICentronAppModuleController.cs:46-49 - Property SupportsConnectionTypes mit Kommentar "this should always be both sql and webservice!"
|
||||
- [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Administration/Connections/LoginDialogViewModel.cs:296-313 - Verzweigung PreDoLoginToCentron je nach ConnectionType
|
||||
Prüfidee: Stichprobenartig prüfen, ob alle 84 registrierten Module tatsächlich beide ConnectionTypes deklarieren; Abweichungen dokumentieren.
|
||||
Konsolidierungshinweis: Grundlage für alle modulspezifischen Cluster (Voraussetzung: Web-Service-fähig für SaaS-Neuimplementierung).
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-02
|
||||
Ebene: SyRS
|
||||
Typ: funktional / Sicherheit
|
||||
Akteur: Endanwender (c-entron.NET Benutzer)
|
||||
Vorbedingung: Anwendungsstart, LoginDialog wird angezeigt
|
||||
Fakt: Die Authentifizierung unterstützt mehrere Verfahren: `Basic` (c-entron-eigenes Login), `ActiveDirectory`, `OpenIdConnect` (Microsoft Entra ID via MSAL/OIDC) sowie `WebAccount` (Kunden-Login für Web-Funktionen). `AuthenticatorFactory` wählt anhand der Systemeinstellung `SystemAuthenticationMethod` und ggf. Benutzer-spezifischer `AuthentificationKind` mit Fallback-Kette (`FallbackAuthenticator`) den passenden Authenticator.
|
||||
Aussage: Das System soll mehrere konfigurierbare Authentifizierungsverfahren (Benutzername/Passwort, Active Directory, OpenID Connect/Microsoft Entra ID) unterstützen und pro Benutzer mit Fallback-Logik kombinieren können.
|
||||
Ergebnis: Zentraler Authentifizierungs-Einstiegspunkt mit Erweiterbarkeit für weitere Identity-Provider; wichtig für SaaS (SSO-Fähigkeit vorhanden).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Logins/Auth/AuthenticatorFactory.cs:44-146 - GetAuthenticatorWithSystemAuth/GetMainAuthenticator mit Switch über BasicAuthObject/WebAccountAuthObject/OpenIdConnectAuthObject
|
||||
- [PRIMÄR] docs/reference/security/anmelden-mit-microsoft-technische-anleitung.md:1-197 - vollständiger OIDC-Login-Flow inkl. Sequenzdiagramm
|
||||
- [SEKUNDÄR] src/backend/Centron.Interfaces/Administration/Settings/ApplicationSettingID.cs (JwtAuthority=10351, JwtAudience=10352, SystemAuthenticationMethod=10360) - Konfigurationspunkte laut Doku
|
||||
Prüfidee: End-to-End-Test aller vier Login-Pfade inkl. Fallback bei Fehlkonfiguration (z.B. AD nicht erreichbar).
|
||||
Konsolidierungshinweis: Ergänzt durch ARCH-03 (OIDC-Detailfluss) und ARCH-04 (2FA).
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-03
|
||||
Ebene: SwRS
|
||||
Typ: Schnittstelle / Sicherheit
|
||||
Akteur: Endanwender, externe Client-Anwendung
|
||||
Vorbedingung: OpenID Connect ist serverseitig aktiviert (`JwtEnabled`)
|
||||
Fakt: Der OIDC-Login-Flow läuft über `GET /config/jwt` (anonym, liefert Authority/Audience/Enabled), MSAL-Tokenakquise (ID-Token, Scopes `openid`,`profile`), `POST /jwt/login` (Bearer-ID-Token, Body `Application`/`AppVersion`/`Device`) und liefert ein c-entron-Ticket (Plain-Text-String) mit 30 Minuten Gültigkeit zurück. Nutzerzuordnung erfolgt über `oid`-Claim gegen Spalte `OpenIdConnectSubjectIdentifier` in Tabelle `Sichbenu`.
|
||||
Aussage: Das System soll ein Microsoft-Entra-ID-basiertes Single-Sign-On über einen definierten Token-Austausch-Endpunkt (`/jwt/login`) bereitstellen, der ein zeitlich begrenztes Sitzungs-Ticket ausstellt.
|
||||
Ergebnis: SSO-fähige Schnittstelle, die für Web-/SaaS-Clients wiederverwendbar ist (keine c-entron-spezifischen Credentials nötig, sofern Konto verknüpft).
|
||||
Belege:
|
||||
- [PRIMÄR] docs/reference/security/anmelden-mit-microsoft-technische-anleitung.md:150-157 - Ticket-Erstellung mit `expireDate = DateTime.Now.AddMinutes(30)`
|
||||
- [PRIMÄR] src/webservice/Centron.Controllers/Controllers/Unversioned/JwtAuthController.cs (referenziert in Doku Zeile 395) - `/jwt/login` Endpoint
|
||||
- [KONTEXT] src/backend/Centron.BL/Administration/Logins/Auth/OpenIdConnectAuthenticator.cs (Doku Zeile 397) - User-Lookup per oid-Claim
|
||||
Prüfidee: Verifizieren der Ticket-Lebensdauer und ob ein Refresh-Mechanismus existiert (nicht in Doku beschrieben).
|
||||
Konsolidierungshinweis: Detaillierung von ARCH-02.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-04
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Endanwender, Administrator
|
||||
Vorbedingung: Benutzer hat einen Zwei-Faktor-Schlüssel in der Personalverwaltung hinterlegt
|
||||
Fakt: Es existiert eine TOTP-basierte Zwei-Faktor-Authentifizierung (`TwoFactorAuthenticationBL`, `Centron.Core.GoogleAuthenticator.TwoFactorAuthenticator`, Entität `TwoFactorAuthLastLogin`). `ValidateAuthenticationPin` prüft eine eingegebene PIN gegen den hinterlegten Schlüssel.
|
||||
Aussage: Das System soll optional eine Zwei-Faktor-Authentifizierung (TOTP, z.B. Authenticator-App) pro Benutzer als zusätzliche Absicherung des Logins unterstützen.
|
||||
Ergebnis: Zusätzliche Sicherheitsstufe für sensible Konten; relevant für SaaS-Compliance-Anforderungen (z.B. Zugriffsschutz bei extern erreichbarem Login).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/TwoFactorAuthenticator/TwoFactorAuthenticationBL.cs:43-54 - ValidateAuthenticationPin nutzt GoogleAuthenticator.TwoFactorAuthenticator.ValidatePin
|
||||
- [SEKUNDÄR] src/backend/Centron.Entities/Entities/Administration/TwoFactorAuthLastLogin.cs - Entität für letzten 2FA-Login
|
||||
- [KONTEXT] src/shared/Centron.Core/GoogleAuthenticator/TwoFactorAuthenticator.cs, src/shared/Centron.Core/TotpAuth/* - TOTP-Implementierung
|
||||
Prüfidee: Prüfen, ob 2FA erzwingbar (Pflicht) konfiguriert werden kann oder rein optional ist; wie Wiederherstellung bei Verlust des Geräts erfolgt (nicht recherchiert).
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt; Umfang (Pflicht vs. optional) nicht abschließend geklärt [HYPOTHESE: es fehlt Beleg für eine erzwingende Policy]
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-05
|
||||
Ebene: StRS
|
||||
Typ: funktional / Lizenzierung
|
||||
Akteur: c-entron-Vertrieb, Kunde, Systemadministrator
|
||||
Vorbedingung: Kunde hat einen Lizenzvertrag
|
||||
Fakt: Lizenzen sind GUID-basierte Merkmale mit optionalem `count`, `valid until date`, `valid until version`. Es wird zwischen `Applications` (dürfen sich am Web-Service anmelden, Liste in `ApplicationKind.cs`, ca. 40 Einträge z.B. Centron, ServiceBoard, WebCart, PasswordManager, Outlook Add-In) und reinen Einzel-Feature-Lizenzen (`LicenseGuids.cs`) unterschieden. Single Source of Truth ist ein zentraler Lizenzserver.
|
||||
Aussage: Das System soll ein zentrales, GUID-basiertes Lizenzmodell mit Zähler-, Ablaufdatum- und Versionsbindung besitzen, das sowohl den Zugang ganzer Anwendungen als auch einzelner Features steuert.
|
||||
Ergebnis: Feingranulare kommerzielle Steuerung von Funktionsumfang und Zugriff; zentrale Voraussetzung für Feature-Gating in einer SaaS-Variante (z.B. Tarif-/Paketmodell).
|
||||
Belege:
|
||||
- [PRIMÄR] docs/reference/security/licensing-system.md:1-44 - Beschreibung GUID/count/valid until date/valid until version, Applications vs. Only Licenses
|
||||
- [PRIMÄR] src/backend/Centron.Interfaces/Administration/Logins/ApplicationKind.cs:11-53 - ca. 40 ApplicationKind-Einträge mit LicenseGuids, teils mit `licenseUsageKind: LicenseUsageKind.PerUser`, `expirationKind`
|
||||
- [SEKUNDÄR] src/backend/Centron.BL/Administration/Licensing/LicenseManager.cs:26-40 - ILicenseManager Interface (HasLicense, GetLicenseCount, CheckLicense)
|
||||
Prüfidee: Klären, ob Lizenzprüfung offline (Dongle/Cache) funktionsfähig bleibt und wie oft synchronisiert wird (`FileLicenseCache`, `UpdateLicenseInterval`).
|
||||
Konsolidierungshinweis: Basis für alle modulspezifischen "nur mit Lizenz X verfügbar"-Anforderungen in den Fachclustern.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-06
|
||||
Ebene: SyRS
|
||||
Typ: funktional / Sicherheit
|
||||
Akteur: Systemadministrator
|
||||
Vorbedingung: Anwendung läuft im DEBUG-Build (Entwicklungsumgebung)
|
||||
Fakt: `DeveloperSecurity.cs` ersetzt in DEBUG-Builds alle E-Mail-Adressen außerhalb der Domain `nexoware.com` automatisch durch `test@nexoware.com`, um versehentliches Versenden an echte Kunden zu verhindern. In RELEASE-Builds ist dieser Schutz nicht aktiv.
|
||||
Aussage: Das System soll in Entwicklungs-/Testumgebungen automatisch verhindern, dass E-Mails an reale externe Empfänger versendet werden.
|
||||
Ergebnis: Reduziertes Risiko von Datenlecks/fehlgeleiteter Kommunikation während Entwicklung und Test; Hinweis für Testkonzept einer SaaS-Neuimplementierung (Sandbox-Mailing-Regel sollte übernommen werden).
|
||||
Belege:
|
||||
- [PRIMÄR] docs/reference/security/developer-security.md:11-23 - Beschreibung des Verhaltens inkl. Domainregel
|
||||
Prüfidee: Verifizieren, dass die Regel tatsächlich in `DeveloperSecurity.cs` so implementiert ist (Doku nicht Code gelesen) und ob ein äquivalenter Schutz für RELEASE-Testinstanzen fehlt.
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt; Basis nur Dokumentation, Quellcode `DeveloperSecurity.cs` nicht gegengelesen [HYPOTHESE: exakte Implementierungsdetails ungeprüft]
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-07
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (ISO25010: Modularität / Erweiterbarkeit)
|
||||
Akteur: Entwickler, Systemarchitekt
|
||||
Vorbedingung: -
|
||||
Fakt: Fachmodule implementieren `ICentronAppModuleController` (ID, ModuleName, Description, Icons, MainCategory, SupportsConnectionTypes, CreateModuleInstance, GetSettings, GetRights, Dispose) und werden zentral in `ModuleRegistration.cs` registriert. Aktuell sind 84 Module über `ModuleRegistrationItem.For<T>(...)` eingetragen, gruppiert in 18 Hauptkategorien (`CentronModuleCategory`: MyCentron, Sales, Ticket, Contract, Billing, DataExchange, Logistic, Purchasing, Controlling, Administration, BaseData, PasswordManager, Help, Tests, Automate, Production, QM, NexowareConnect).
|
||||
Aussage: Das System soll Fachfunktionen als eigenständige, über ein einheitliches Interface registrierte Module bereitstellen, die zur Laufzeit anhand von Rechte- und Feature-Flag-Prüfung ein-/ausgeblendet werden.
|
||||
Ergebnis: Plugin-artige, kategorisierte Modularchitektur als fachliche Gliederung des Gesamtsystems; direkte Vorlage für die Bounded-Context-/Microservice-Gliederung einer Web-Neuimplementierung.
|
||||
Belege:
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI.Extension/Modules/ICentronAppModuleController.cs:11-71 - vollständiges Interface
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/Modules/ModuleRegistration.cs:414-416 sowie Zählung (grep) - 84 ModuleRegistrationItem.For-Aufrufe
|
||||
- [PRIMÄR] src/backend/Centron.Interfaces/UI/Modules/CentronModuleCategory.cs:3-23 - 18 Kategorien
|
||||
- [SEKUNDÄR] docs/guides/ui/create-module.md:1-116 - Entwickler-Anleitung zur Modulerstellung
|
||||
Prüfidee: Kategorien gegen die tatsächlich in den Fachclustern untersuchten Module abgleichen (Vollständigkeitscheck der Systemübersicht).
|
||||
Konsolidierungshinweis: Liefert die Rahmen-Taxonomie für alle anderen RRE-Cluster (jedes Fachcluster sollte sich einer/mehreren CentronModuleCategory zuordnen lassen).
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-08
|
||||
Ebene: SyRS
|
||||
Typ: funktional / Sicherheit
|
||||
Akteur: Administrator, Endanwender
|
||||
Vorbedingung: Modul ist registriert
|
||||
Fakt: Jede `ModuleRegistrationItem.For<T>` Registrierung erhält einen optionalen Rechte-Ausdruck (`Expression<Func<bool>> rightsCheck`, z.B. `Helper.HasAnyRight(...)`) und einen optionalen Feature-Flag-Check (`Func<bool> moduleFeatureCheck`, z.B. `() => ModuleFeatures.IsThingiesAvailable` oder `() => Debugger.IsAttached`). `ModuleRightsExpressionParser` wertet die Rechte-Ausdrücke zur Laufzeit aus (`CheckRights`, `GetRights`).
|
||||
Aussage: Das System soll die Sichtbarkeit jedes Fachmoduls unabhängig über (a) ein deklaratives Rechtesystem und (b) Feature-Flags steuern können, ohne Codeänderung am Modul selbst.
|
||||
Ergebnis: Feingranulare Zugriffssteuerung und kontrollierte Feature-Auslieferung (z.B. Module "in Entwicklung" ausblenden); Vorlage für Rollen-/Rechtekonzept einer SaaS-Variante.
|
||||
Belege:
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/Modules/ModuleRegistration.cs:910-951 - Klasse ModuleRegistrationItem mit CheckModuleFeatures/CheckRights/GetRights
|
||||
- [SEKUNDÄR] docs/guides/ui/create-module.md:105-116 - Beschreibung "erster Parameter Rechte, zweiter Parameter Feature-Flag"
|
||||
- [KONTEXT] CentronRights.md:1-80 - Beispielhafte, granulare Rechte inkl. "restricting rights" (nur eigene/nur eigene Filiale)
|
||||
Prüfidee: Prüfen, ob Rechte pro Mandant/Filiale unterschiedlich vergeben werden können (Hinweis "nur eigene Filiale" in CentronRights.md).
|
||||
Konsolidierungshinweis: Ergänzt ARCH-07; Rechte-Details sind Gegenstand der Fachcluster, hier nur das Rahmenkonzept.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-09
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (ISO25010: Übertragbarkeit / Anpassbarkeit)
|
||||
Akteur: Entwickler, Drittanbieter/Partner
|
||||
Vorbedingung: DLLs liegen im Unterordner "Extensions" des Anwendungsverzeichnisses
|
||||
Fakt: `ExtensionLogic.LoadExtensionEngine()` nutzt MEF (`System.ComponentModel.Composition`, `DirectoryCatalog`) um zur Laufzeit alle `*.dll` im Ordner "Extensions" zu laden und exportierte `ICore`-Implementierungen zu sammeln; `RegisterExtensions()`/`UnregisterExtensions()` rufen `Register(CentronApplication.Instance)`/`Unregister()` auf jeder gefundenen Extension auf.
|
||||
Aussage: Das System soll eine Plugin-Schnittstelle bereitstellen, über die zusätzliche Erweiterungen als separate Assemblies zur Laufzeit geladen und in die Anwendung integriert werden können, ohne den Kern neu zu kompilieren.
|
||||
Ergebnis: Erweiterbarkeit für Partner-/Individualintegrationen; architektonisches Merkmal, das bei einer Web-Neuimplementierung durch ein äquivalentes Plugin-/Extension-API (z.B. Webhooks, serverseitige Module) ersetzt werden müsste.
|
||||
Belege:
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/Extension/ExtensionLogic.cs:29-52 - LoadExtensionEngine mit DirectoryCatalog/CompositionContainer
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/Extension/ExtensionLogic.cs:54-67 - RegisterExtensions
|
||||
- [SEKUNDÄR] src/centron/Centron.WPF.UI/App.xaml.cs:322-325 - DoInitializeExtensionEngine als Teil der Startsequenz
|
||||
Prüfidee: Prüfen, wie viele produktive Extensions aktuell existieren und ob die Schnittstelle stabil versioniert ist.
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-10
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (ISO25010: Zuverlässigkeit / Reife)
|
||||
Akteur: Endanwender
|
||||
Vorbedingung: Anwendungsstart mit Kommandozeilenargumenten (z.B. Deep-Link via URL-Protokoll)
|
||||
Fakt: `StartupArgSynchronizer` verwendet einen computerweiten, pfadgebundenen `Mutex`, um zu erkennen, ob bereits eine Instanz der c-entron.NET läuft. Falls ja, werden Argumente über eine Memory-Mapped-File (`FileArgSeparator`, `ArgFileLength=1024`) an den laufenden Prozess übergeben statt eine zweite Instanz zu starten; bei mehreren laufenden Prozessen wird ein Auswahldialog (`SelectTargetProcessView`) gezeigt.
|
||||
Aussage: Das System soll sicherstellen, dass pro Benutzer/Pfad nur eine Instanz der Anwendung aktiv ist, und Start-Argumente/Deep-Links an eine bereits laufende Instanz weiterleiten können.
|
||||
Ergebnis: Konsistentes Single-Instance-Verhalten und URL-Protokoll-Aktivierung (z.B. aus E-Mail/Browser heraus ein bestimmtes Modul öffnen); bei Web-Migration äquivalent durch Tab-/Session-Handling und Deep-Links zu ersetzen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/StartupArgs/StartupArgSynchronizer.cs:18-49 - Mutex-basierte Instanzerkennung
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/App.xaml.cs:97-126 - Nutzung im Startup (TryPassArgsToRunningApp, ReceivedArgs)
|
||||
- [KONTEXT] src/centron/Centron.WPF.UI/StartupArgs/SelectTargetProcessView.xaml - UI bei mehreren laufenden Instanzen
|
||||
Prüfidee: Testen des Verhaltens bei mehreren parallel angemeldeten Terminal-Server-Sitzungen (RDP/Citrix) desselben Benutzers.
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-11
|
||||
Ebene: StRS
|
||||
Typ: nicht-funktional (ISO25010: Kompatibilität / Systemumgebung)
|
||||
Akteur: IT-Administrator, Endanwender
|
||||
Vorbedingung: -
|
||||
Fakt: Der Client (`Centron.WPF.UI.csproj`) zielt auf `net10.0-windows`, ist ein `WinExe` (WPF, WinForms-Abhängigkeiten wie `System.Windows.Forms.Screen`), bindet COM-Interop zu Microsoft Outlook (`Microsoft.Office.Interop.Outlook`) sowie ein modifiziertes Drittanbieter-TAPI-Modul (`Traysoft.AddTapi.dll`) ein. `global.json` fixiert die .NET-SDK-Version auf 10.0.100.
|
||||
Aussage: Das System (c-entron.NET) soll als natives Windows-Desktop-Programm mit lokalen Windows-/Outlook-/TAPI-Abhängigkeiten betrieben werden und ist somit nicht plattformunabhängig.
|
||||
Ergebnis: Klare Systemvoraussetzung "Windows + .NET 10 Runtime + ggf. Outlook/TAPI-Hardware" für den Bestandsclient; zentrale Motivation für die geplante Web-/SaaS-Neuimplementierung (Plattformunabhängigkeit als Ziel).
|
||||
Belege:
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/Centron.WPF.UI.csproj:1-24 - TargetFramework net10.0-windows, WinExe, COM-Interop-Referenzen
|
||||
- [PRIMÄR] global.json:1-6 - SDK-Version 10.0.100
|
||||
- [SEKUNDÄR] docs/reference/architecture/tapi.md:1-10 - TAPI-Integration nur für Windows-Produkte (c-entron.NET, Outlook Add-In, ServiceBoard)
|
||||
Prüfidee: Abgleich mit Kunden-Systemvoraussetzungsdokument (falls vorhanden) auf weitere Hardware-/Software-Voraussetzungen (z.B. Terminalserver-Freigabe).
|
||||
Konsolidierungshinweis: Begründet die grundsätzliche Zielsetzung des RRE-Projekts (StRS "Business Need").
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-12
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (ISO25010: Internationalisierbarkeit / Anpassbarkeit)
|
||||
Akteur: Endanwender
|
||||
Vorbedingung: -
|
||||
Fakt: Lokalisierung erfolgt über .NET-Standard-Ressourcendateien (.resx) pro Assembly (`LocalizedStrings.resx` = Deutsch/Standard, `LocalizedStrings.en.resx` = Englisch), gesteuert über `CultureInfo.CurrentUICulture`. Getrennte Ressourcen existieren für WPF-UI-Layer und Business-Logic-Layer. Web-Service-Antworten werden über den HTTP-Header `Accept-Language` lokalisiert.
|
||||
Aussage: Das System soll Benutzeroberfläche und fachliche Meldungen mehrsprachig (mind. Deutsch als Standard, Englisch als Zusatzsprache) über eine schichtenweise Ressourcendatei-Struktur bereitstellen, wobei Web-Service-Aufrufe die Sprache über den Accept-Language-Header steuern können.
|
||||
Ergebnis: Grundlage für Mehrsprachigkeit im gesamten System; Struktur (getrennte Ressourcen je Schicht/Assembly) ist relevant für Übertragung in eine Web-Architektur (z.B. i18n-Framework, Sprachverhandlung über HTTP).
|
||||
Belege:
|
||||
- [PRIMÄR] docs/guides/ui/localization.md:1-35 - Ressourcenstruktur, CultureInfo.CurrentUICulture
|
||||
- [PRIMÄR] docs/guides/ui/localization.md:275-280 - Accept-Language Header Beispiel für Web-Service-Calls
|
||||
Prüfidee: Vollständigkeitsprüfung, ob wirklich alle Layer (auch Webservice-Fehlermeldungen) konsistent lokalisiert sind (laut Doku-Beispiel nur "einige" Codepfade).
|
||||
Konsolidierungshinweis: Ergänzt durch ARCH-13 (Sprachauswahl im Client eingeschränkt).
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-13
|
||||
Ebene: StRS
|
||||
Typ: nicht-funktional (ISO25010: Internationalisierbarkeit) — Abweichung/Workaround
|
||||
Akteur: Endanwender
|
||||
Vorbedingung: LoginDialog wird angezeigt
|
||||
Fakt: Im `LoginDialogViewModel` wird die Sprachliste initial nur mit `de-DE` befüllt; `en-US` wird nur hinzugefügt, wenn `IsDevBuild` (Compile-Symbol `DEV_BUILD`) aktiv ist. Standardsprache ist explizit "German is the default language" (Kommentar im Code). Produktivbenutzer können in der UI somit i.d.R. nur Deutsch wählen, obwohl englische Ressourcendateien im Code existieren.
|
||||
Aussage: Das System soll (Soll-Zustand im Ist offen) die im Backend vorhandene Mehrsprachigkeit (Deutsch/Englisch) auch produktiv über die Login-/Spracheinstellung zugänglich machen.
|
||||
Ergebnis: Diskrepanz zwischen technischer Lokalisierungs-Infrastruktur (ARCH-12) und tatsächlich für Endanwender nutzbarer Sprachauswahl; für SaaS-Zielbild zu klären, ob Mehrsprachigkeit ein echtes Geschäftsziel ist oder nur Entwickler-/Testzweck.
|
||||
Belege:
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Administration/Connections/LoginDialogViewModel.cs:93-98 - Languages.Add(en-US) nur `if (IsDevBuild)`
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Administration/Connections/LoginDialogViewModel.cs:197-206 - IsDevBuild liest Compile-Symbol DEV_BUILD
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Administration/Connections/LoginDialogViewModel.cs:239 - Kommentar "German is the default language."
|
||||
Prüfidee: Produktentscheidung/Product Owner befragen, ob Englisch-Support als Geschäftsziel für die Web-Neuimplementierung gilt (aktuell nur "verstecktes" Dev-Feature).
|
||||
Konsolidierungshinweis: Präzisiert ARCH-12; wichtig für StRS "Stakeholder-Bedürfnisse: internationale Kunden".
|
||||
Status: belegt; Soll-Anforderung nicht ableitbar [HYPOTHESE: fehlende Produktentscheidung, ob Mehrsprachigkeit für Endkunden freigeschaltet werden soll]
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-14
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Kunde mit mehreren Gesellschaften/Niederlassungen, Administrator
|
||||
Vorbedingung: Lizenz "branch functionality" vorhanden (laut licensing-system.md Beispiel)
|
||||
Fakt: Es existiert ein Modul "Mandantenverwaltung" (`MandatorManagementAppModuleController`, ID `{717AD6A2-...}`, Kategorie Administration) sowie ein separates "BranchManagement" (Filialverwaltung, Nummernkreise) unter demselben Namensraum `Administration.MandatorManagement`.
|
||||
Aussage: Das System soll die Verwaltung mehrerer Mandanten/Gesellschaften bzw. Filialen (Niederlassungen) innerhalb einer c-entron-Instanz unterstützen, inklusive eigener Nummernkreise je Filiale.
|
||||
Ergebnis: Mehrmandantenfähigkeit auf Ebene "mehrere Unternehmenseinheiten in einer Datenbank" (kein Hinweis auf Datenbank-pro-Kunde-Mandantentrennung im Sinne von SaaS-Multi-Tenancy); wichtig für SyRS-Datenmodell-Entscheidung bei Neuimplementierung.
|
||||
Belege:
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Administration/MandatorManagement/MandatorManagementAppModuleController.cs:9-45 - Modul "Mandanten Verwaltung"
|
||||
- [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Administration/MandatorManagement/BranchManagement/* - BranchManagementView/ViewModel, NumberGroupsViewModel (Dateiliste)
|
||||
- [KONTEXT] CentronRights.md:14-26 - Rechte mit Filial-Einschränkung ("nur eigene Filiale") als Beleg für aktive fachliche Nutzung von Filialen/Mandanten in Rechten
|
||||
Prüfidee: Klären, ob "Mandant" hier = rechtlich eigenständige Gesellschaft (mit eigener Buchhaltung) oder nur Organisationseinheit ist; Datenmodell (MandantI3D-Spalten) verifizieren.
|
||||
Konsolidierungshinweis: Grundlegend für Datenmodell-Cluster (Rechnungswesen/Finance) — dort ggf. mit ARCH-14 verknüpfen statt duplizieren.
|
||||
Status: belegt; genaue fachliche Abgrenzung "Mandant" vs. "Filiale" nicht abschließend verifiziert [HYPOTHESE: Begriffsdefinition nur aus Namensgebung/Icon abgeleitet, keine Fachdoku gelesen]
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-15
|
||||
Ebene: SwRS
|
||||
Typ: Daten / nicht-funktional (ISO25010: Wartbarkeit)
|
||||
Akteur: Entwickler (indirekt: alle Endanwender über Datenkonsistenz)
|
||||
Vorbedingung: -
|
||||
Fakt: Die Architektur trennt strikt drei Objekttypen: `Entity` (BL-Layer, NHibernate-Mapping via Fluent NHibernate, Primärschlüssel "I3D", ausschließlich virtuelle Properties, keine Logik), `DTO` (WebService/Logics-Layer, `[DataContract]`/`[DataMember]`, `List<T>` statt `IEnumerable<T>` zur JSON-Serialisierung, `DateTime?` statt `DateTime` wegen .NET-Default-Wert-Problem) und `ViewModel` (UI-Layer). Konvertierung Entity→DTO über `ObjectMapper.Map<TEntity,TDTO>()`, DTO→Entity manuell (ObjectMapper hierfür explizit verboten).
|
||||
Aussage: Das System soll intern konsequent zwischen Datenbank-Entities, Transport-DTOs und UI-ViewModels trennen und definierte Konvertierungsregeln (automatisiertes Mapping nur Entity→DTO, manuelles Mapping DTO→Entity) einhalten.
|
||||
Ergebnis: Klare Schichtentrennung als Wartbarkeits-/Kapselungsprinzip; wesentliche Randbedingung für Neuimplementierung des Datenzugriffs (z.B. Wahl von EF Core/Dapper und äquivalentem DTO-Konzept für eine Web-API).
|
||||
Belege:
|
||||
- [PRIMÄR] docs/reference/architecture/dtos-and-entities.md:15-118 - vollständige Beschreibung Entity/DTO/Mapping-Regeln
|
||||
Prüfidee: Stichprobe an realen Entity/DTO-Paaren (z.B. Helpdesk/Ticket) auf Einhaltung der Regeln (List<T>, DateTime?, kein ObjectMapper bei DTO→Entity).
|
||||
Konsolidierungshinweis: Basis-Pattern, das in allen Fachclustern bei Datenmodell-Anforderungen als Kontext zitiert werden kann statt neu zu belegen.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-16
|
||||
Ebene: SwRS
|
||||
Typ: nicht-funktional (ISO25010: Wartbarkeit) / Schnittstelle
|
||||
Akteur: Entwickler
|
||||
Vorbedingung: -
|
||||
Fakt: Fehlerbehandlung folgt einem zweistufigen Muster: `Result`/`Result<T>` (Business-Logic-Layer, Status Success/Error/Warning, Factory-Methoden `AsSuccess`/`AsError`/`AsWarning`/`FromException`) wird über `Response.FromBLResult(...)`/`Response<T>.FromBLResult(...)` in ein API-`Response`-Objekt (Status Success/Failed, `MessageCode`) übersetzt; `Warning` wird auf API-Ebene als `Success` gemappt.
|
||||
Aussage: Das System soll einen einheitlichen, geschichteten Result/Response-Mechanismus für Operationsergebnisse und Fehlerbehandlung verwenden, der in der Business-Logik feiner granuliert (inkl. Warnungen) als an der API-Grenze.
|
||||
Ergebnis: Konsistentes Fehler-/Statusmodell über alle Schichten; direkte Vorlage für ein äquivalentes Response-Envelope-Format einer REST/GraphQL-API in der Web-Neuimplementierung.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/reference/architecture/results-and-responses.md:18-147 - Result/Response-Klassenstruktur, Statuswerte, Mapping-Logik
|
||||
- [SEKUNDÄR] src/centron/Centron.WPF.UI/Managers/CentronExceptionHandler.cs:24-59 - clientseitige Zuordnung von `MessageCode` zu lokalisierten Fehlermeldungen (z.B. RightCheckFailed, LicenseNotFound, MandatoryFieldsNotFilled)
|
||||
Prüfidee: Prüfen, ob alle Webservice-Endpunkte konsequent `Response`/`Response<T>` statt roher Exceptions zurückgeben.
|
||||
Konsolidierungshinweis: Ergänzt ARCH-15; beide bilden zusammen das SwRS-Basisdatenmodell/Fehlerkonzept, auf das Fachcluster verweisen sollten statt es zu wiederholen.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-17
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (ISO25010: Zuverlässigkeit)
|
||||
Akteur: Endanwender, Support
|
||||
Vorbedingung: Unbehandelte Exception oder unbeobachtete Task-Exception tritt auf
|
||||
Fakt: `App.xaml.cs` registriert globale Handler (`DispatcherUnhandledException`, `TaskScheduler.UnobservedTaskException`), die an `CentronApplication.Instance.ExceptionHandler` (Typ `CentronExceptionHandler`) delegieren. Dieser kennt eine Liste bekannter, bewusst zu ignorierender Exceptions (mit Typ + Stacktrace-Marker, max. Rekursionstiefe 2) sowie eine Tabelle von `MessageCode`→lokalisierter Nutzermeldung.
|
||||
Aussage: Das System soll unbehandelte Ausnahmen zentral abfangen, protokollieren (NLog) und dem Benutzer eine lokalisierte, verständliche Fehlermeldung anzeigen, statt abzustürzen, mit Ausnahme explizit als harmlos bekannter Fehlerbilder.
|
||||
Ergebnis: Erhöhte gefühlte Stabilität der Desktop-Anwendung trotz Einzel-Ausnahmen; Verhaltens-Vorlage für zentrales Error-Handling/Logging-Konzept einer Web-Anwendung (globaler Error-Boundary + strukturiertes Logging).
|
||||
Belege:
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/App.xaml.cs:130-232 - Registrierung globaler Exception-Handler inkl. Fallback-MessageBox vor Initialisierung
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/Managers/CentronExceptionHandler.cs:18-85 - HandleException, ignorierte Exceptions, Message-Mapping
|
||||
Prüfidee: Prüfen, ob äquivalentes zentrales Error-Handling auch auf Web-Service-Seite existiert (nicht recherchiert in diesem Cluster).
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-18
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (ISO25010: Effizienz / Startzeitverhalten)
|
||||
Akteur: Endanwender
|
||||
Vorbedingung: Anwendungsstart
|
||||
Fakt: Der Start läuft über eine sichtbare Splash-Screen-Sequenz mit fünf benannten, sequentiellen Initialisierungsschritten (`DoInitializeClassContainer`, `DoInitializeDevExpressControls`, `DoInitializeObjectMapper`, `DoInitializeDaoFactory`, `DoInitializeExtensionEngine`), jeweils mit lokalisiertem Fortschrittstext. Vor der Anmeldung wird zusätzlich `ProfileOptimization` (.NET Startup-Profil) aktiviert und mehrere produktspezifische Workarounds (FastReport, DevExpress-Ribbon) ausgeführt.
|
||||
Aussage: Das System soll dem Benutzer während des Anwendungsstarts sichtbares, stufenweises Feedback über den Initialisierungsfortschritt geben und dabei zeitkritische Subsysteme (DB-Zugriff, Objektmapper, Extension-Engine, UI-Theme) in definierter Reihenfolge vorbereiten.
|
||||
Ergebnis: Vorhersehbare, für den Benutzer nachvollziehbare Startsequenz; bei Web-Migration i.d.R. obsolet (Server-seitiges Preloading statt Client-Splash), aber die fachliche Reihenfolge (Konfiguration→Datenbank→Objektmapper→Erweiterungen) bleibt als Abhängigkeitsgraph relevant.
|
||||
Belege:
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/App.xaml.cs:236-285 - DoInitializeWithSplashScreen mit Actions-Liste
|
||||
- [SEKUNDÄR] src/centron/Centron.WPF.UI/App.xaml.cs:287-360 - Einzelmethoden der Initialisierungsschritte
|
||||
Prüfidee: Startzeit messen und mit Zielwert (falls vorhanden) vergleichen; klären ob preload (DAOFactory/ObjectMapper) bei Web-Service-Verbindung übersprungen wird (Code zeigt: ja, abhängig von `IsDefaultConnectionAWebServiceConnection`/`RememberLogin`).
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-19
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (ISO25010: Benutzbarkeit)
|
||||
Akteur: Endanwender (Power-User)
|
||||
Vorbedingung: Anwendung läuft
|
||||
Fakt: Es existiert eine "Command Palette" (`Start/CommandPalette/*`, u.a. `CommandPaletteViewModel`, diverse `*CommandProvider`-Klassen für Kundensuche, Artikelsuche, Belegsuche, Ticketnummern, Modul-Liste etc.) als zentrales Tastatur-gesteuertes Schnellzugriffs-/Such-Werkzeug über viele Fachbereiche hinweg.
|
||||
Aussage: Das System soll eine anwendungsweite, tastaturbasierte Befehls-/Suchpalette bereitstellen, über die Module, Datensätze (Kunden, Artikel, Belege, Tickets, Seriennummern) und Aktionen schnell gefunden und ausgeführt werden können.
|
||||
Ergebnis: Zentrales, cross-modulares Produktivitätsfeature; sollte als eigenständige, modulunabhängige Querschnittsfunktion auch in einer Web-Neuimplementierung erhalten bleiben (z.B. als globale Suchleiste/Command-K-Pattern).
|
||||
Belege:
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/Start/CommandPalette/CommandPaletteViewModel.cs (Dateiname/Struktur) - zentrale ViewModel-Klasse
|
||||
- [SEKUNDÄR] src/centron/Centron.WPF.UI/Start/CommandPalette/Provider/*.cs (Dateiliste, u.a. CustomerSearchCommandProvider, ArticleSearchCommandProvider, DocumentSearchCommandProvider, ReceiptNumberCommandProvider, HelpdeskNumberCommandProvider, ModuleListCommandProvider) - modulübergreifende Provider
|
||||
Prüfidee: Nutzungshäufigkeit/Bedeutung beim Kunden erfragen (aus Code allein nicht ableitbar, ob zentrales oder Nischenfeature).
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt; Bedeutung/Priorität aus Endnutzersicht nicht belegt [HYPOTHESE: keine Nutzungsstatistik verfügbar]
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-20
|
||||
Ebene: SwRS
|
||||
Typ: nicht-funktional (ISO25010: Benutzbarkeit) / Daten
|
||||
Akteur: Endanwender
|
||||
Vorbedingung: Benutzer passt Ansicht (Grid-Spalten, Fensteranordnung, Docking) an
|
||||
Fakt: Es existiert eine eigene Layout-Persistenz-Schicht (`Layout/*LayoutSerializer.cs`) für diverse DevExpress-Steuerelemente (GridControl, TreeListControl, DockLayoutManager, NavBarControl, ComboBoxEdit, DateEdit u.a.), die Benutzeroberflächen-Zustand (Spaltenreihenfolge, Fensterlayout etc.) persistiert und wiederherstellt (`ICustomLayoutSavingControl`, `ILayoutSerializerOnlyIfSaveLayoutActive`).
|
||||
Aussage: Das System soll benutzerspezifische Anpassungen von Ansichten (Spalten, Fensteranordnung, Docking-Layout) dauerhaft je Benutzer speichern und beim nächsten Start wiederherstellen.
|
||||
Ergebnis: Personalisierung der Arbeitsumgebung als etabliertes Feature; funktionale Anforderung, die in einer Web-Anwendung durch äquivalente Persistenz von UI-Zustand (z.B. je Benutzer serverseitig gespeicherte Grid-/Layout-Einstellungen) nachgebildet werden müsste.
|
||||
Belege:
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/Layout/GridControlLayoutSerializer.cs, DockLayoutManagerLayoutSerializer.cs, TreeListControlLayoutSerializer.cs (Dateiliste) - konkrete Serializer je Steuerelement
|
||||
- [KONTEXT] src/centron/Centron.WPF.UI/Layout/ILayoutSerializerOnlyIfSaveLayoutActive.cs - Hinweis auf konfigurierbares "Layout speichern"-Verhalten
|
||||
Prüfidee: Prüfen, wo (Registry/DB/Datei) das Layout gespeichert wird und ob es geräteübergreifend synchronisiert wird (nicht recherchiert).
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt; Speicherort/Synchronisationsverhalten nicht verifiziert [HYPOTHESE: fehlende Information zu Speicherort]
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-21
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (ISO25010: Funktionale Eignung) / Datenschutz
|
||||
Akteur: Produktmanagement, Endanwender (indirekt betroffen)
|
||||
Vorbedingung: Anwendung ist eingeloggt
|
||||
Fakt: `CentronAnalyticsManager` abonniert `ModuleOpenedEvent`/`ModuleClosedEvent` über einen zentralen `EventAggregator` und sendet Nutzungsereignisse (Modul-Nutzung) über einen `AnalyticEventsManager`, identifiziert über eine aus der Lizenz abgeleitete `dongleId` (Kundennummer) und die interne Mitarbeiter-ID (`employeeId`). Fehlen beide IDs, wird das Tracking deaktiviert ("Initialisiert...NULL. No events will be tracked!").
|
||||
Aussage: Das System soll Nutzungstelemetrie (welche Module wie genutzt werden) kundenbezogen (Lizenznummer) und benutzerbezogen erfassen können, sofern eine gültige Lizenz- und Benutzerzuordnung vorliegt.
|
||||
Ergebnis: Grundlage für produktseitige Nutzungsauswertung; für SaaS-Neuimplementierung datenschutzrechtlich (DSGVO) zu bewerten, da personenbezogene Nutzungsdaten erfasst werden.
|
||||
Belege:
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/Managers/CentronAnalyticsManager.cs:23-50 - Initialize(), Subscribe auf ModuleOpenedEvent/ModuleClosedEvent, dongleId/employeeId-Ermittlung
|
||||
Prüfidee: Prüfen, ob eine Einwilligung/Opt-out für Telemetrie existiert und wie/wo die Daten gespeichert werden (nicht im gelesenen Ausschnitt ersichtlich).
|
||||
Konsolidierungshinweis: Ggf. mit DSGVO-Modul (`Modules.Administration.DSGVO`, siehe ModuleRegistration.cs Zeile 12) im Sicherheits-/Datenschutz-Cluster verknüpfen.
|
||||
Status: belegt; Opt-out/Einwilligungsmechanismus nicht verifiziert [HYPOTHESE: fehlende Information zu Consent-Handling]
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-22
|
||||
Ebene: SyRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: Endanwender (Telefonie-Nutzer), Administrator
|
||||
Vorbedingung: TAPI-fähige Telefonanlage/Software-Client vorhanden
|
||||
Fakt: Telefonie-Integration erfolgt über die kommerzielle Komponente "TraySoft AddTAPI.NET", die firmenintern für .NET 5/6-Kompatibilität modifiziert wurde (`ProcessIncomingCall` Workaround wegen entferntem `BeginInvoke`). Genutzt in c-entron.NET (`PhoneManager.cs`, `TapiPhoneConnectionManager.cs`), Outlook Add-In und ServiceBoard.
|
||||
Aussage: Das System soll eine TAPI-basierte Telefonieanbindung (eingehende/ausgehende Anrufe, Rufnummererkennung) über eine modifizierte Drittanbieterkomponente bereitstellen, die produktübergreifend (Desktop-Client, Outlook Add-In, ServiceBoard) genutzt wird.
|
||||
Ergebnis: Cross-Produkt-Abhängigkeit von einer proprietären, Windows-gebundenen TAPI-Bibliothek; kritischer Migrationsaspekt für Web-/SaaS-Variante (TAPI ist ein reines Windows-Desktop-Konzept, erfordert Alternativkonzept z.B. Cloud-Telefonie/CTI-API).
|
||||
Belege:
|
||||
- [PRIMÄR] docs/reference/architecture/tapi.md:1-36 - Komponente, Produkte, Modifikation, Debugging-Hinweise
|
||||
- [KONTEXT] src/centron/Centron.WPF.UI/Managers/PhoneManager.cs, TapiPhoneConnectionManager.cs (Dateiliste) - produktinterne Nutzung
|
||||
Prüfidee: Umfang der TAPI-Nutzung beim Kunden erheben (Pflichtfeature oder Nischenfunktion) für Entscheidung über Migrationsstrategie.
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-23
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Kunde des Kunden (Web-Account-Benutzer)
|
||||
Vorbedingung: Web-Account wurde in c-entron.NET Adressstamm angelegt, Sonderpreise hinterlegt
|
||||
Fakt: README.md beschreibt "WebCart" als Feature primär für Kunden der Kunden: Login als Web-Account bei "c-entron Nexus" (separate Web-Anwendung, "c-entron Web"), Artikelanzeige basiert auf hinterlegten "Sonderpreisen" im c-entron.NET Adressstamm, Zugriff über Menüpunkt "Shop".
|
||||
Aussage: Das System soll einen webbasierten Bestellkanal (WebCart) für Endkunden der c-entron-Kunden bereitstellen, dessen Sortiment/Preise zentral im ERP (c-entron.NET) gepflegt werden.
|
||||
Ergebnis: Bereits vorhandener Web-Kanal (c-entron Nexus) als Blaupause/Vorstufe für die geplante SaaS-Neuimplementierung — zeigt, dass Teile des Systems bereits heute web-basiert sind und mit dem ERP-Kern über Web-Accounts/Sonderpreise integriert sind.
|
||||
Belege:
|
||||
- [PRIMÄR] README.md:1,29-35 - Beschreibung WebCart, Web-Account-Login, Sonderpreise, "Shop"
|
||||
- [SEKUNDÄR] src/centron/Centron.WPF.UI/Modules/Administration/WebCart (Namensraum in ModuleRegistration.cs Zeile 40) - zugehöriges WPF-Verwaltungsmodul
|
||||
Prüfidee: Architektur von "c-entron Nexus" (separates Blazor-Projekt laut README-Kontext "azure-blazor") im Detail untersuchen — ggf. eigener Cluster/Repository-Bereich außerhalb des hier untersuchten Scopes.
|
||||
Konsolidierungshinweis: Wichtiger Kontext für ein SaaS-Zielbild: c-entron Nexus zeigt bereits Web-first-Muster (Blazor/DevExpress-Blazor-Komponenten), das ggf. als Ausgangspunkt dient.
|
||||
Status: belegt; Detailarchitektur von c-entron Nexus außerhalb des recherchierten Bereichs [HYPOTHESE: Nexus/Blazor-Code nicht gelesen, nur README]
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-24
|
||||
Ebene: SwRS
|
||||
Typ: nicht-funktional (ISO25010: Wartbarkeit) / MVVM
|
||||
Akteur: Entwickler
|
||||
Vorbedingung: -
|
||||
Fakt: Alle recherchierten ViewModels (`LoginDialogViewModel`, Modul-ViewModels) implementieren/erben von DevExpress-MVVM-Basisklassen (`ViewModelBase`, `BindableBase`) sowie einer eigenen Basis `CentronBindableBase` (in `Centron.Core.Mvvm`). Views erben von einer eigenen `BaseModule`-Basisklasse (statt UserControl) für Fachmodule bzw. `BaseSettingControl` für Einstellungsseiten; Rechtevergabe, Initialisierung (`DoInitalize`) und Speichern (`DoSave`) folgen festen Konventionen.
|
||||
Aussage: Das System soll ein einheitliches MVVM-Grundgerüst mit klar getrennten Verantwortlichkeiten (View: Anzeige/Ribbon, ViewModel: Zustand/Async-Init/Save, Container: Rechte-/Feature-Prüfung) für alle Fachmodule und Einstellungsseiten verwenden.
|
||||
Ergebnis: Konsistente Entwicklungskonventionen als Wartbarkeitsfaktor; die eigentliche `mvvm-in-centron.md`-Referenzdokumentation ist inhaltsleer (Platzhalter "I don't know, but I would like to - please tell me."), das Muster musste daher aus Code-Konventionen (create-module.md, create-settings-page.md) rekonstruiert werden.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/guides/ui/create-module.md:52-103 - BaseModule, IRibbonControlModule*, ViewModel-Konventionen
|
||||
- [PRIMÄR] docs/guides/ui/create-settings-page.md:1-45 - BaseSettingControl, DoInitalize/DoSave/CanSave/DoAfterSave-Konvention, explizites Verbot eigener MessageBoxen bei Fehlern
|
||||
- [KONTEXT] src/shared/Centron.Core/Mvvm/CentronBindableBase.cs (Dateiname) - eigene MVVM-Basisklasse
|
||||
- [KONTEXT] docs/reference/architecture/mvvm-in-centron.md:1-3 - Dokument explizit als Platzhalter/unvollständig markiert
|
||||
Prüfidee: `CentronBindableBase.cs` und mind. 2-3 reale ViewModel-Klassen lesen, um das Muster über Doku-Rekonstruktion hinaus zu verifizieren.
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt; Referenzdokumentation "mvvm-in-centron.md" ist explizit leer/unvollständig [HYPOTHESE: Muster aus Nachbardokumenten und Namenskonventionen rekonstruiert, nicht aus einer autoritativen MVVM-Spezifikation]
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-25
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Systemadministrator
|
||||
Vorbedingung: Aktivierung der Windows-Anmeldung (SSO) über Entra ID gewünscht
|
||||
Fakt: Für OIDC ist neben der App-Registration in Azure AD eine Verknüpfung jedes c-entron-Benutzers mit seiner Microsoft-Entra-Object-ID (Spalte `OpenIdConnectSubjectIdentifier` in Tabelle `Sichbenu`) nötig, entweder per Self-Service-Endpoint (`POST /jwt/connect_accounts`) oder Admin-Zuweisung über die WPF-UI unter "Persönliche Einstellungen".
|
||||
Aussage: Das System soll die Verknüpfung eines c-entron-Benutzerkontos mit einem externen Identitätsanbieter-Konto (Microsoft Entra ID) sowohl per Selbstbedienung durch den Benutzer als auch administrativ ermöglichen.
|
||||
Ergebnis: Flexibles Account-Linking-Modell als Voraussetzung für produktives SSO; Vorlage für generisches "externe Identität verknüpfen"-Konzept bei SaaS mit mehreren Identity Providern.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/reference/security/anmelden-mit-microsoft-technische-anleitung.md:180-196 - Self-Service/Admin-Zuweisung, Endpoint-Tabelle
|
||||
- [KONTEXT] src/centron/Centron.WPF.UI/Modules/MyCentron/PersonalSettings/OpenIdConnectAccount (Namensraum, ModuleRegistration.cs Zeile 137) - zugehöriges UI-Modul "Persönliche Einstellungen"
|
||||
Prüfidee: Prüfen, ob Entkopplung (Verknüpfung aufheben) ebenfalls möglich ist und wie der Fall "Entra-Konto bereits mit anderem c-entron-User verknüpft" behandelt wird.
|
||||
Konsolidierungshinweis: Ergänzt ARCH-02/ARCH-03.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-26
|
||||
Ebene: SyRS
|
||||
Typ: funktional / Sicherheit
|
||||
Akteur: c-entron-Kunde (Endkunde des Kunden), Web-Account-Benutzer
|
||||
Vorbedingung: -
|
||||
Fakt: Neben Mitarbeiter-Logins existiert ein separater Authentifizierungspfad `WebAccountAuthObject`/`WebAccountAuthenticator` sowie `WebLoginType.Customer` (vs. `WebLoginType.User`/`WebLoginType.Domain`), der eigene Kundenkonten (z.B. für WebCart/Web-Shop) gegenüber internen Mitarbeiterkonten unterscheidet.
|
||||
Aussage: Das System soll zwischen internen Mitarbeiter-Logins und externen Kunden-("Web-Account")-Logins mit eigenem Authentifizierungspfad und eigenen Berechtigungen unterscheiden.
|
||||
Ergebnis: Grundlage für ein zweistufiges Nutzermodell (intern/extern) im Gesamtsystem; direkt relevant für die Zielarchitektur eines Kundenportals in der SaaS-Variante.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Logins/Auth/AuthenticatorFactory.cs:89-95,122-123,163-186 - WebAccountAuthObject-Zweig, WebLoginType.Customer
|
||||
- [KONTEXT] src/backend/Centron.Entities/Entities/Administration/Logins/WebAccount.cs (Dateiname) - eigene Entität für Web-Konten
|
||||
Prüfidee: Rechte-/Rollenmodell für WebAccount-Benutzer im Detail prüfen (vermutlich stark eingeschränkt ggü. Mitarbeitern).
|
||||
Konsolidierungshinweis: Ergänzt ARCH-23 (WebCart).
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-27
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (ISO25010: Kompatibilität)
|
||||
Akteur: Systemadministrator (Terminalserver-Betrieb)
|
||||
Vorbedingung: Betrieb über Remote-Desktop-Sitzung (RDP/Terminalserver/Citrix)
|
||||
Fakt: Es existiert (inzwischen deaktivierter, aber im Code dokumentierter) produktionsrelevanter Workaround-Code für den Fall, dass sich eine RDP-Sitzung neu verbindet: Dies löst laut Kommentar einen bekannten DevExpress-Performance-Bug aus (massive Verlangsamung nach Reconnect), wofür früher ein Warnhinweis mit Neustart-Option angezeigt wurde (Ticket 115706, seit 2024-05 testweise entfernt, Ticket erwähnt in Kommentar SKA 2024-05-08).
|
||||
Aussage: Das System soll (historisch) den Betrieb über Remote-Desktop-Sitzungen mit Reconnect-Verhalten unterstützen und Performance-Einbußen nach Reconnect erkennen bzw. dem Benutzer eine Neustart-Option anbieten.
|
||||
Ergebnis: Hinweis auf reale Betriebsumgebung "Terminalserver/RDP" als verbreitetes Deployment-Szenario beim Kunden; relevant für StRS "unterstützte Umgebungen", auch wenn der spezifische Workaround aktuell deaktiviert ist.
|
||||
Belege:
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/App.xaml.cs:151-155 - Auskommentierter SystemEvents.UserPreferenceChanged-Hook mit Verweis auf Ticket 147477/115706
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/App.xaml.cs:464-526 - vollständige (tote, aber vorhandene) Implementierung SystemEventsOnUserPreferenceChanged inkl. Benutzertext zu RDP-Verbindungsabbruch
|
||||
Prüfidee: Klären, ob der Workaround dauerhaft entfernt bleibt oder nur testweise; Terminalserver-Nutzung beim Kunden quantitativ erheben.
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt; Funktion aktuell im Code deaktiviert (auskommentiert) [HYPOTHESE: Unklar ob RDP-Betrieb weiterhin offizielle Systemvoraussetzung ist oder nur Altlast]
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-28
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Systemadministrator
|
||||
Vorbedingung: Active-Directory-Anmeldung konfiguriert (`ActiveDirectoryAuthEnabled`)
|
||||
Fakt: `AuthenticatorFactory` unterscheidet klar zwischen dem global konfigurierten `SystemAuthenticationMethod` (None/Basic/ActiveDirectory/OpenIdConnect) und einer pro-Benutzer hinterlegten `AuthentificationKind` (CentronLogin/WindowsAuth[obsolet]/OpenIdConnectAuth). Bei Konflikt (z.B. Benutzer ist für WindowsAuth markiert, aber AD ist nicht korrekt konfiguriert) wird ein klar lokalisierter Fehler über `FailingAuthenticator` zurückgegeben statt eines stillen Fallbacks.
|
||||
Aussage: Das System soll bei inkonsistenter Authentifizierungs-Konfiguration (z.B. Benutzer für einen nicht verfügbaren Auth-Mechanismus markiert) eine eindeutige, lokalisierte Fehlermeldung liefern statt unsicherer stiller Fallbacks.
|
||||
Ergebnis: Robustheit/Nachvollziehbarkeit bei Fehlkonfiguration von Authentifizierungsmechanismen; wichtige Sicherheitsanforderung, die bei Multi-Provider-Login-Konzepten (SaaS) übernommen werden sollte.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Logins/Auth/AuthenticatorFactory.cs:66-82 - FallbackAuthenticator mit FailingAuthenticator und lokalisierter Fehlermeldung `AuthenticatorFactory_FallbackMisconfiguredErrorMessage`
|
||||
Prüfidee: End-to-End-Test: Benutzer mit AuthentificationKind=WindowsAuth bei deaktiviertem AD anmelden lassen, erwartete Fehlermeldung verifizieren.
|
||||
Konsolidierungshinweis: Ergänzt ARCH-02.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-29
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Produktmanagement, Entwickler
|
||||
Vorbedingung: -
|
||||
Fakt: `ApplicationKind.cs` listet neben dem Kern-ERP ("NEXOWARE c-entron ERP") ca. 40 weitere, separat lizenzierte Anwendungen/Produkte im selben Ökosystem (u.a. Service-Board, Service-Board Online, c-entron Nexus, Outlook Add-In, PasswordManager, WebCart, WebSuitePro, DocumentSync, Riversuite-Familie [Inventory/Compliance/Monitoring/Mobile/Online/Pro/N13/RFlow/SupRemo], TAPI-Server, Communicator, MailScanner/MailScannerNET, diverse ExternalApp-Connectoren zu Drittsystemen wie c-pra, DocBee, Visoma, WOASI).
|
||||
Aussage: Das System ist Teil eines breiten Produkt-/Anwendungsportfolios (nicht nur ein einzelnes ERP), das über ein gemeinsames Lizenz- und Authentifizierungssystem am zentralen Web-Service andockt.
|
||||
Ergebnis: Wichtige Erkenntnis für den StRS-Systemüberblick: Die Web-/SaaS-Neuimplementierung des ERP-Kerns muss die Schnittstellen zu diesem breiteren Produktportfolio (mind. Authentifizierung/Lizenzierung) weiterhin bedienen können, auch wenn die Einzelprodukte selbst außerhalb des Scopes liegen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Interfaces/Administration/Logins/ApplicationKind.cs:11-53 - vollständige Liste der ApplicationKind-Instanzen
|
||||
Prüfidee: Mit Produktmanagement klären, welche dieser Anwendungen im Rahmen der SaaS-Neuimplementierung migriert/integriert werden müssen vs. weiterhin als separate Legacy-Clients bestehen bleiben.
|
||||
Konsolidierungshinweis: Kontext für ARCH-05 (Lizenzmodell); ggf. im finalen StRS als "System-Kontext-Diagramm" darstellen.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat ARCH-30
|
||||
Ebene: SwRS
|
||||
Typ: nicht-funktional (ISO25010: Wartbarkeit) / Sonstiges
|
||||
Akteur: Entwickler
|
||||
Vorbedingung: -
|
||||
Fakt: Zentrale technische Basis-Dokumentation (`stanislaus-secret-api-documentation.md`) verweist für die "eigentliche" Web-Service-API-Dokumentation nur auf eine externe PDF-Datei auf einem internen Netzlaufwerk (`P:\Entwicklung C#\...`), nicht auf ein im Repository verfügbares oder generiertes Dokument.
|
||||
Aussage: (Kein direktes Systemsoll ableitbar) — Dokumentationslücke: Eine vollständige, versionierte API-Referenz der c-entron Web-Service-Schnittstelle ist im Repository nicht auffindbar.
|
||||
Ergebnis: Für ein RRE-Projekt mit Ziel Web-/SaaS-Neuimplementierung fehlt eine zentrale, im Code-Repository gepflegte API-Spezifikation; dies ist selbst ein Befund (Prozess-/Dokumentationslücke), kein Produktmerkmal.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/reference/architecture/stanislaus-secret-api-documentation.md:1-10 - Verweis auf externe PDF ohne Repository-Zugriff
|
||||
Prüfidee: Klären, ob die referenzierte PDF beschafft werden kann, um die Web-Service-API (`ICentronRestService`) vollständiger zu dokumentieren, ggf. stattdessen `ICentronRestService`-Interface direkt im Code als Quelle nutzen (in anderen Clustern ggf. bereits geschehen).
|
||||
Konsolidierungshinweis: Meta-Befund, keine Systemanforderung im engeren Sinn — ggf. bei der Konsolidierung als "Wissenslücke" statt als ARCH-Kandidat führen.
|
||||
Status: HYPOTHESE (fehlende Information: externe PDF nicht zugreifbar/nicht gelesen)
|
||||
|
||||
---
|
||||
|
||||
## Abdeckung
|
||||
|
||||
**Gelesen (tief, mit Zeilenreferenzen):**
|
||||
- README.md (Projektwurzel)
|
||||
- CentronRights.md (Auszug, erste ~80 Zeilen)
|
||||
- docs/reference/architecture/dtos-and-entities.md, requests-and-responses.md (leer), results-and-responses.md, tapi.md, mvvm-in-centron.md (Platzhalter), stanislaus-secret-api-documentation.md
|
||||
- docs/reference/security/licensing-system.md, developer-security.md, anmelden-mit-microsoft-technische-anleitung.md
|
||||
- docs/guides/ui/create-module.md, create-dialog.md (Platzhalter), create-settings-page.md, localization.md
|
||||
- src/centron/Centron.WPF.UI/App.xaml.cs (vollständig)
|
||||
- src/centron/Centron.WPF.UI/Modules/ModuleRegistration.cs (Header/Imports, Konstruktor-Ende, ModuleRegistrationItem-Klasse; die ca. 800 Zeilen der eigentlichen Modul-Registrierungsliste wurden nicht Zeile für Zeile gelesen, nur strukturell über Imports und grep-Zählung [84 Einträge] erfasst)
|
||||
- src/centron/Centron.WPF.UI.Extension/Modules/ICentronAppModuleController.cs
|
||||
- src/backend/Centron.Interfaces/Administration/Connections/CentronConnectionType.cs
|
||||
- src/backend/Centron.Interfaces/UI/Modules/CentronModuleCategory.cs
|
||||
- src/backend/Centron.BL/Administration/Licensing/LicenseManager.cs (erste ~220 Zeilen)
|
||||
- src/backend/Centron.Interfaces/Administration/Logins/ApplicationKind.cs (erste 60 Zeilen)
|
||||
- src/backend/Centron.BL/Administration/Logins/Auth/AuthenticatorFactory.cs (vollständig)
|
||||
- src/centron/Centron.WPF.UI/Modules/Administration/Connections/LoginDialogViewModel.cs (erste ~360 Zeilen, DoLogin/PreDoLoginToCentron)
|
||||
- src/centron/Centron.WPF.UI/Modules/Administration/MandatorManagement/MandatorManagementAppModuleController.cs
|
||||
- src/centron/Centron.WPF.UI/Managers/CentronExceptionHandler.cs (erste 100 Zeilen), CentronDialogManager.cs (Ausschnitt), CentronAnalyticsManager.cs (erste 50 Zeilen)
|
||||
- src/centron/Centron.WPF.UI/Extension/ExtensionLogic.cs (erste 80 Zeilen)
|
||||
- src/centron/Centron.WPF.UI/StartupArgs/StartupArgManager.cs (Ausschnitt), StartupArgSynchronizer.cs (Ausschnitt)
|
||||
- src/backend/Centron.BL/TwoFactorAuthenticator/TwoFactorAuthenticationBL.cs (erste 60 Zeilen)
|
||||
- src/backend/Centron.Common/UtilClasses/CultureUtils.cs (Ausschnitt)
|
||||
- src/centron/Centron.WPF.UI/Centron.WPF.UI.csproj (erste 40 Zeilen)
|
||||
- global.json
|
||||
|
||||
**Nur strukturell erfasst (Dateilisten via Glob, nicht Inhalt gelesen):**
|
||||
- src/centron/Centron.WPF.UI/Start/CommandPalette/** (Dateistruktur/Namen als Beleg für ARCH-19, Inhalte nicht gelesen)
|
||||
- src/centron/Centron.WPF.UI/Wizards/** (nicht inhaltlich ausgewertet — kein eigener Kandidat, da zu generisch/kein aussagekräftiger Fakt gefunden)
|
||||
- src/centron/Centron.WPF.UI/Layout/** (Dateinamen als Beleg für ARCH-20)
|
||||
- src/centron/Centron.WPF.UI/Managers/** (PhoneManager.cs, SoftPhoneConnectionManager.cs, TapiPhoneConnectionManager.cs, CentronHelpManager.cs, CentronMailManager.cs, CentronNotificationManager.cs, CentronReportManager.cs, CentronStatusBarManager.cs, CentronThemeManager.cs, IconManager.cs — nur Namen erfasst, nicht gelesen)
|
||||
- src/shared/Centron.Core/** (Dateiliste vollständig erfasst als Beleg für Basis-Utility-Landschaft; nur Guard.cs, Mvvm/CentronBindableBase.cs referenziert, nicht inhaltlich gelesen)
|
||||
- src/centron/Centron.WPF.UI/Modules/Administration/MandatorManagement/BranchManagement/** (nur Dateiliste)
|
||||
|
||||
**Bekannte Lücken / nicht recherchiert:**
|
||||
- `docs/reference/architecture/requests-and-responses.md` ist im Repository **leer** (0 Byte) — kein Beleg ableitbar, obwohl im Auftrag als Startpunkt genannt.
|
||||
- `docs/guides/ui/create-dialog.md` und `docs/reference/architecture/mvvm-in-centron.md` sind reine Platzhalter ("I don't know, but I would like to - please tell me.") — MVVM- und Dialog-Erstellungsmuster wurden daher nur indirekt über `create-module.md`/`create-settings-page.md` rekonstruiert (siehe ARCH-24, als HYPOTHESE markiert).
|
||||
- `CentronThemeManager.cs` (Theming/Dark-Mode) wurde nicht gelesen — mögliches weiteres Usability-Merkmal (Theme aus Registry laden, `DuplicateThemeAndReload`) nur indirekt über App.xaml.cs-Aufrufe bekannt, kein eigener Kandidat formuliert.
|
||||
- `CentronStartupArgManager.cs` (Manager-Wrapper um StartupArgManager) nicht gelesen, nur der darunterliegende `StartupArgManager`/`StartupArgSynchronizer`.
|
||||
- Vollständige Liste aller 84 Modul-Registrierungen (Rechte-/Feature-Flag-Ausdrücke) wurde nicht einzeln geprüft — nur Muster und Beispiele (ModuleRegistrationItem-Klasse, Doku-Beispiel) belegt.
|
||||
- `Centron.Api.docuFORM`, `azure/`, `azure-blazor/`, `docker/`, `deployment/` (Repository-Wurzelverzeichnisse) wurden nicht untersucht — potenziell relevant für Deployment-/Betriebsarchitektur (Docker/Azure), aber außerhalb der im Auftrag genannten Startpunkte und aus Zeitgründen nicht vertieft. Mögliche Lücke für SyRS "Deployment-Architektur".
|
||||
- c-entron Nexus (separate Web-/Blazor-Anwendung, im README erwähnt) wurde nur über die kurze README-Erwähnung erfasst, nicht über eigenen Quellcode — echte Web-Architektur-Erkenntnisse für das SaaS-Zielbild könnten dort zusätzlich vorhanden sein (potenziell wertvoller Zusatz-Cluster für spätere Iterationen).
|
||||
- Rechte-System (`UserRightsConst`, `ModuleRightsExpressionParser`) wurde nur strukturell (Existenz, Parser-Konzept) belegt, nicht im Detail (z.B. Rechte-Vererbung, Rollenkonzept) — Grenze zu den Fachclustern bewusst nicht überschritten.
|
||||
- Kein Zugriff/Prüfung auf tatsächliche Systemvoraussetzungsdokumente für Kunden (Hardware/Betriebssystemversionen/Terminalserver-Freigabe) außerhalb des Codes — ARCH-11/ARCH-27 beruhen ausschließlich auf Code-/Projektdatei-Indizien.
|
||||
+542
@@ -0,0 +1,542 @@
|
||||
# Rohbefunde Cluster BILL – Abrechnung, Fakturierung & Verträge
|
||||
|
||||
Recherche-Agent für RRE an CentronERP. Fokus: Belege (Rechnung/Gutschrift/Vertrag), Preisfindung, Contract-Billing, ZUGFeRD/XRechnung, Mahnwesen, Statusmaschinen.
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-01
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Buchhaltung / Finanzbuchhaltung
|
||||
Vorbedingung: Rechnung/Gutschrift ist im System erfasst und soll elektronisch versendet werden
|
||||
Fakt: c-entron generiert beim Rechnungs-/Gutschriftexport automatisiert ZUGFeRD- bzw. XRechnung-konforme XML-Dateien (Versionen 1.0 bis 2.1/XRechnung 3.0.1), implementiert in `InvoiceZugferdBL.cs`. Die Formatwahl (ZUGFeRD Comfort vs. XRechnung) erfolgt automatisch anhand des Vorhandenseins einer Leitweg-ID.
|
||||
Aussage: Das System soll rechtssichere elektronische Rechnungen (ZUGFeRD/XRechnung) automatisiert aus den erfassten Rechnungs- und Gutschriftdaten erzeugen können, ohne manuelle Nacharbeit der Anwenderin.
|
||||
Ergebnis: Verkäufer kann gesetzeskonforme E-Rechnungen (auch für öffentliche Auftraggeber) versenden.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/DataExchange/EDI/SaleInvoices/InvoiceZugferdBL.cs:124-156 (GenerateZugferdFile, Formatwahl anhand leitwegID) - Begründung: Kernmechanik der automatisierten E-Rechnungserzeugung im Code nachgewiesen
|
||||
- [SEKUNDÄR] docs/reference/zugferd-feldzuordnung-anwender.md:9-14 - Begründung: Anwenderdokumentation bestätigt unterstützte Versionen
|
||||
Prüfidee: Export einer Rechnung ohne und mit Leitweg-ID durchführen, resultierendes Dateiformat/-schema prüfen (KOSIT-Validator)
|
||||
Konsolidierungshinweis: Details siehe BILL-10 bis BILL-16 (SyRS/SwRS-Ebene)
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-02
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Vertriebsinnendienst / Vertragsmanagement
|
||||
Vorbedingung: Kunde hat einen laufenden Wartungs-/Servicevertrag mit wiederkehrender Abrechnung
|
||||
Fakt: c-entron bietet ein eigenständiges Contract-Billing-Subsystem (`ReceiptContract`, `AutomaticFacturaBL.Contracts`), das Verträge nach konfigurierbaren Intervallen (Daily/Monthly/Quarterly/Yearly) automatisiert abrechnet, inkl. Integration externer RMM-Nutzungsdaten (Riverbird) und Kontingentverwaltung.
|
||||
Aussage: Das System soll wiederkehrende Vertragsleistungen automatisiert, nach konfigurierbarem Abrechnungsintervall und unter Berücksichtigung von Nutzungsdaten/Kontingenten korrekt fakturieren.
|
||||
Ergebnis: Reduzierter manueller Aufwand bei der Abrechnung von Wartungs-/MSP-Verträgen, korrekte periodengerechte Rechnungsstellung.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/Sales/Receipts/ContractLists/ReceiptContract.cs (Felder BillingIntervalKind, BillingIntervalDuration, AutomatedBilling) - Begründung: Entität trägt Konfigurationsfelder für automatisierte Intervallabrechnung
|
||||
- [PRIMÄR] src/backend/Centron.BL/WebServices/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaWebServiceBL.cs:721-802 (CheckRMMArticle) - Begründung: Ausführbare Logik zur automatisierten RMM-basierten Rechnungspositionserzeugung
|
||||
Prüfidee: Testvertrag mit monatlichem Intervall anlegen, automatische Abrechnung anstoßen, Rechnungsperiode/-betrag verifizieren
|
||||
Konsolidierungshinweis: Details in BILL-17, BILL-18, BILL-19
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-03
|
||||
Ebene: StRS
|
||||
Typ: funktional
|
||||
Akteur: Finanzbuchhaltung / Mahnwesen
|
||||
Vorbedingung: Kunde hat offene, überfällige Forderungen
|
||||
Fakt: Das System führt ein Mahnstufen-Modell (`DunningLevel1Fees/2/3`, `DunningLetterAfterDays1-3`) je Kunde und kann konfigurierbar ab einer bestimmten Mahnstufe die Neuanlage von Belegen (z.B. Aufträgen) sperren (`LockOrderAfterDunningLevel`, durchgesetzt in `ReceiptBL.CanUserCreateNewReceiptsAtCustomerOrSupplier`).
|
||||
Aussage: Das System soll säumige Kunden anhand eines Mahnstufenmodells identifizieren und optional automatisch von der Neuanlage weiterer Belege ausschließen, um das Ausfallrisiko zu begrenzen.
|
||||
Ergebnis: Kreditrisikobegrenzung; Vertrieb kann keine neuen Aufträge/Belege für gesperrte Kunden anlegen, solange die Mahnstufe nicht sinkt.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs:10194-10219 (CanUserCreateNewReceiptsAtCustomerOrSupplier, exakte Fehlermeldung "Aufgrund der Mahnstufe darf kein neuer Beleg ... angelegt werden.") - Begründung: Durchgesetzte Regel im Code, inkl. Fehlermeldungstext
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/Accounts/AccountCustomer.cs:25 (LockOrderAfterDunningLevel) - Begründung: Persistiertes Feld je Kunde als Datengrundlage der Regel
|
||||
Prüfidee: Kunde mit LockOrderAfterDunningLevel=2 und aktueller Mahnstufe 2 anlegen, Versuch neuen Auftrag zu erstellen -> erwartete Fehlermeldung
|
||||
Konsolidierungshinweis: Details in BILL-20, BILL-21
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-04
|
||||
Ebene: StRS
|
||||
Typ: nicht-funktional (Compliance/Datenintegrität)
|
||||
Akteur: Buchhaltung / Wirtschaftsprüfung
|
||||
Vorbedingung: Eine Rechnung wurde bereits weiterverarbeitet (z.B. exportiert, in Buchhaltung übernommen) oder ist eine Barrechnung
|
||||
Fakt: `ReceiptInvoiceBL.CancelInvoice` verweigert die Stornierung, wenn die Rechnung bereits storniert ist, es sich um eine Barrechnung handelt, sie bereits weiterverarbeitet oder bereits an die Buchhaltung exportiert wurde, oder es sich bei einer Vertragsrechnung nicht um die zuletzt erstellte handelt.
|
||||
Aussage: Das System soll die Stornierung von Rechnungen nur zulassen, solange keine downstream-Verarbeitung (Export, Weiterverarbeitung) stattgefunden hat, um Inkonsistenzen mit Buchhaltung/Finanzamt zu vermeiden.
|
||||
Ergebnis: Verhinderung nachträglicher Inkonsistenzen zwischen ERP und exportierten/gebuchten Finanzdaten.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs:143-206 (CancelInvoice, komplette Prüfkette) - Begründung: Vollständige, im Code durchgesetzte Vorbedingungskette mit exakten Fehlermeldungen
|
||||
Prüfidee: Testrechnung exportieren (BookKeepingExportBL) und danach Stornoversuch -> Fehlermeldung "...bereits exportiert wurde." erwarten
|
||||
Konsolidierungshinweis: Detaillierung in BILL-06
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-05
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System (Belegverwaltung)
|
||||
Vorbedingung: Beleg (Angebot/Auftrag/Lieferschein/Rechnung/Vertrag/Gutschrift/Abholliste) existiert
|
||||
Fakt: Alle Belegtypen teilen sich eine gemeinsame Statusmaschine `ReceiptState` mit exakt drei Zuständen: `Active` ("offen"), `Completed` ("abgeschlossen"), `Canceled` ("storniert"). Der Enum wird u.a. für Zahlungsstatus (Completed=bezahlt) und Stornostatus verwendet.
|
||||
Aussage: Das System soll für alle Belegtypen einen einheitlichen, dreiwertigen Lebenszyklus-Status (offen/abgeschlossen/storniert) führen und konsistent für Status- und Zahlungslogik verwenden.
|
||||
Ergebnis: Einheitliche, belegtypübergreifende Zustandslogik als Basis für Folgeprozesse (Storno, Zahlungsstatus, Reporting).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Interfaces/Sales/Receipts/ReceiptState.cs:6-14 - Begründung: Enum-Definition mit deutschen Beschreibungen, direkter Code-Beleg
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs:4942-4951 (UpdateReceiptIsPaid nutzt ReceiptState.Completed/Active für isPaid) - Begründung: Zeigt Wiederverwendung der Statusmaschine für Zahlungsstatus
|
||||
Prüfidee: Alle Belegtypen (Angebot, Auftrag, Rechnung, Vertrag, Gutschrift) auf konsistente State-Werte in DB prüfen
|
||||
Konsolidierungshinweis: Basis für BILL-06, BILL-08
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-06
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: Buchhaltung
|
||||
Vorbedingung: Rechnung mit State != Canceled liegt vor
|
||||
Fakt: `CancelInvoice` (ReceiptInvoiceBL.cs:143-206) prüft nacheinander: Recht `RIGHT_RECHNUNGSTORNIEREN`, State != Canceled, `IsCashAsset == false`, keine Weiterverarbeitung (`GetReceiptForwardedInto`), kein Buchhaltungsexport (`BookKeepingExportBL.IsReceiptExported`), bei Vertragsrechnung Prüfung auf letzte Rechnung des Vertrags (`IsLastContractInvoice`). Erst danach wird eine neue Version mit Menge=0 je Artikel-/Rabattposition erzeugt und State auf `Canceled` gesetzt.
|
||||
Aussage: Das System soll eine Rechnungsstornierung als neue, versionierte Belegrevision mit auf Null gesetzten Mengen realisieren und dabei alle genannten Vorbedingungen hart erzwingen.
|
||||
Ergebnis: Nachvollziehbare, versionierte Stornohistorie statt Löschung; harte Sperren bei bereits verarbeiteten Belegen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs:157-186 - Begründung: Exakte Prüfkette und Storno-Mechanik (Menge=0, neue Version, State=Canceled) im Code
|
||||
Prüfidee: Stornierung einer Barrechnung (IsCashAsset=true) versuchen -> Fehlermeldung "...da es sich um eine Barrechnung handelt." erwarten
|
||||
Konsolidierungshinweis: Verfeinerung von BILL-04
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-07
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: Buchhaltung
|
||||
Vorbedingung: Rechnung ist noch nicht festgeschrieben (IsFixed=false)
|
||||
Fakt: `FixInvoice` setzt per Raw-SQL `UPDATE RechKopf SET IsFixed = 1 WHERE I3D = @I3D` und protokolliert den Vorgang im Log (`ReceiptLogKind.FixedState`). `CheckIfInvoiceIsFixed` liefert bei bereits festgeschriebener Rechnung eine Warnung "Die Rechnung ist festgeschrieben. Änderungen nicht möglich."
|
||||
Aussage: Das System soll eine Funktion zur Festschreibung von Rechnungen bereitstellen, die weitere inhaltliche Änderungen an der Rechnung nach Festschreibung verhindert.
|
||||
Ergebnis: Nachträgliche Manipulation festgeschriebener (i.d.R. bereits gebuchter/exportierter) Rechnungen wird verhindert.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs:86-141 (FixInvoice) - Begründung: Direkte SQL-Persistenz des Fixier-Flags plus Audit-Log-Eintrag
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs:273-291 (CheckIfInvoiceIsFixed) - Begründung: Exakte Warnmeldung im Code
|
||||
Prüfidee: Rechnung festschreiben, danach Änderungsversuch an Positionen -> erwartete Blockade/Warnung
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-08
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: Zahlungseingang / Buchhaltung
|
||||
Vorbedingung: Beleg unterstützt Zahlungsinformationen (`IReceiptWithPayment` oder Gutschrift)
|
||||
Fakt: `ReceiptBL.UpdateReceiptIsPaid` (Zeilen 4902-4971) verweigert die Statusänderung bei stornierten Belegen ("...wurde stoniert und kann daher nicht als bezahlt oder nicht bezahlt eingestellt werden."), prüft optimistisches Locking via `ConcurrencyControlGuid` und mappt `isPaid=true/false` auf `ReceiptState.Completed/Active`.
|
||||
Aussage: Das System soll den Zahlungsstatus eines Belegs nur bei nicht-stornierten Belegen und unter Berücksichtigung von Optimistic-Concurrency-Control ändern lassen.
|
||||
Ergebnis: Konsistenter Zahlungsstatus, keine widersprüchlichen Parallel-Änderungen, keine Zahlungsbuchung auf stornierten Belegen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs:4936-4951 - Begründung: Durchgesetzte Prüfungen inkl. exakter Fehlermeldung im Code
|
||||
Prüfidee: Stornierte Rechnung als "bezahlt" markieren -> erwartete Fehlermeldung
|
||||
Konsolidierungshinweis: siehe BILL-05
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-09
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System (Belegnummernkreis)
|
||||
Vorbedingung: Neuer Beleg wird angelegt und benötigt eine Belegnummer
|
||||
Fakt: `NumberGroupBL.GetNextNumber`/`FindNextNumber` (Zeilen 50-134) ermittelt die nächste freie Nummer durch iterative Prüfung gegen die Zieltabelle (SELECT COUNT), inkrementiert um `Interval`, und persistiert die neue "Current"-Nummer nur, wenn ein optimistischer Update (`WHERE I3D = @I3D AND Current = @altCurrent`) genau 1 Zeile ändert; andernfalls wird die Schleife wiederholt (Race-Condition-Schutz bei paralleler Nummernvergabe).
|
||||
Aussage: Das System soll Belegnummern eindeutig, kollisionsfrei und race-condition-sicher unter gleichzeitigem Zugriff mehrerer Benutzer vergeben.
|
||||
Ergebnis: Keine doppelten Belegnummern auch bei paralleler Rechnungserstellung durch mehrere Benutzer/Filialen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/Company/NumberGroupBL.cs:62-134 - Begründung: Konkrete Optimistic-Locking-Implementierung mit Retry-Schleife im Code
|
||||
Prüfidee: Lasttest mit parallelen Rechnungsanlagen; auf doppelte Nummern in RechKopf prüfen
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-10
|
||||
Ebene: SyRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: System (E-Rechnungs-Export)
|
||||
Vorbedingung: Rechnungs-/Gutschriftexport wird angestoßen, optional mit Leitweg-ID
|
||||
Fakt: `InvoiceZugferdBL.GenerateZugferdFile` (Zeilen 124-156) wählt `ZugferdFileKind.Comfort`, wenn `leitwegID` leer/whitespace ist, sonst `ZugferdFileKind.XInvoice`. Ebenso bestimmt `CreateZugferdConformPdfDocument` (Zeile 193) das PDF-Konformitätslevel (`EN16931` vs. `XRechnung`) anhand desselben Kriteriums.
|
||||
Aussage: Das System soll automatisch zwischen ZUGFeRD-Comfort- und XRechnung-Format wechseln, gesteuert einzig durch das Vorhandensein einer Leitweg-ID im Beleg.
|
||||
Ergebnis: Für Rechnungen an öffentliche Auftraggeber wird automatisch das gesetzlich vorgeschriebene XRechnung-Format erzeugt.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/DataExchange/EDI/SaleInvoices/InvoiceZugferdBL.cs:124-156,167-193 - Begründung: Direkte Verzweigungslogik im Code
|
||||
Prüfidee: Export mit und ohne Leitweg-ID vergleichen (Dateikennung/Namespace im XML)
|
||||
Konsolidierungshinweis: Verfeinerung von BILL-01
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-11
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System (Steuerlogik E-Rechnung)
|
||||
Vorbedingung: Rechnungsposition mit Steuersatz, Reverse-Charge-Flag und Handelsart (Inland/EU/Export) liegt vor
|
||||
Fakt: `InvoiceZugferdBL.GetTaxCategoryCode` (Zeilen 2092-2107) liefert deterministisch: "AE" bei Reverse Charge, sonst bei Steuersatz 0%: "E" (Inland), "K" (EU), "G" (Export außerhalb EU); sonst "S" (Standard).
|
||||
Aussage: Das System soll die UN/CEFACT-Steuerkategorie jeder Rechnungsposition automatisiert aus Steuersatz, Reverse-Charge-Kennzeichen und Handelsart ableiten.
|
||||
Ergebnis: Korrekte, normkonforme Steuerkategorien im E-Rechnungs-XML ohne manuelle Zuordnung.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/DataExchange/EDI/SaleInvoices/InvoiceZugferdBL.cs:2092-2107 - Begründung: Vollständige, deterministische Entscheidungslogik im Code nachgewiesen
|
||||
Prüfidee: Testfälle für alle vier Kombinationen (Reverse Charge, Inland 0%, EU 0%, Export 0%, Standard) durchspielen
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-12
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System (Steuerlogik E-Rechnung)
|
||||
Vorbedingung: Steuerkategorie einer Position wurde ermittelt (siehe BILL-11)
|
||||
Fakt: `GetTaxExemptionReason` (InvoiceZugferdBL.cs:2109-2122) liefert feste deutsche Begründungstexte: Reverse Charge -> "Steuerschuldnerschaft des Leistungsempfängers gem. §13B Abs 2 Nr. 10 UStG.", Inland 0% -> "Steuerfrei", EU 0% -> "Kein Ausweis der Umsatzsteuer bei innergemeinschaftlichen Lieferungen", Export 0% -> "Steuer nicht erhoben aufgrund von Export außerhalb der EU".
|
||||
Aussage: Das System soll bei steuerbefreiten oder Reverse-Charge-Positionen automatisch den vorgeschriebenen Befreiungstext im E-Rechnungs-XML hinterlegen.
|
||||
Ergebnis: E-Rechnungen erfüllen die formalen Anforderungen an Steuerbefreiungshinweise (§14 UStG / EN16931).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/DataExchange/EDI/SaleInvoices/InvoiceZugferdBL.cs:2109-2122 - Begründung: Exakte Texte im Code
|
||||
Prüfidee: Reverse-Charge-Rechnung exportieren, XML auf ExemptionReason-Text prüfen
|
||||
Konsolidierungshinweis: Ergänzt BILL-11
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-13
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional (Datenqualität)
|
||||
Akteur: System (E-Rechnungs-Export)
|
||||
Vorbedingung: Summe der Positionsnettobeträge weicht vom Rechnungskopf-Nettobetrag ab
|
||||
Fakt: Konstante `AMOUNT_DIFFERENCE_TOLERANCE = 3.0m` (InvoiceZugferdBL.cs:64); bei Abweichung < Toleranz wird eine Warnung geloggt und der Kopfbetrag automatisch korrigiert ("ZUGFeRD: Bei der Rechnung weicht das Netto der Rechnung ... ab. Bitte prüfen Sie die Rechnung."), bei Abweichung >= Toleranz wird der Export mit `Result.AsError` abgebrochen (Zeilen 1033-1043).
|
||||
Aussage: Das System soll beim E-Rechnungsexport die Konsistenz zwischen Kopf- und Positionssummen prüfen und bei Abweichungen über 3,00 Euro den Export verweigern statt eine fehlerhafte Rechnung zu versenden.
|
||||
Ergebnis: Verhindert Versand rechnerisch inkonsistenter E-Rechnungen; kleinere Rundungsdifferenzen werden toleriert und automatisch korrigiert.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/DataExchange/EDI/SaleInvoices/InvoiceZugferdBL.cs:64,1033-1043 - Begründung: Hartkodierte Toleranzgrenze und Fehlerpfad im Code
|
||||
Prüfidee: Rechnung mit manuell verändertem Kopfbetrag (Abweichung > 3€) exportieren -> Export muss fehlschlagen
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-14
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System (E-Rechnungs-Export)
|
||||
Vorbedingung: Rechnungs-/Gutschriftposition mit negativem Nettopreis liegt vor
|
||||
Fakt: ZUGFeRD/XRechnung unterstützt keine negativen Einzelpreise; c-entron macht laut Code-Kommentaren und Dokumentation den Preis positiv und negiert stattdessen die Menge, sodass die Positionssumme unverändert bleibt (`InvoiceZugferdBL.cs`, Kommentare Zeilen 994-999 zu Vorzeichenbehandlung bei Rabatten; Bestätigung in docs/reference/zugferd-field-mapping.md Abschnitt "Negative Prices").
|
||||
Aussage: Das System soll negative Einzelpreise beim E-Rechnungsexport durch Vorzeichenumkehr der Menge (statt des Preises) abbilden, um EN16931-Konformität zu wahren.
|
||||
Ergebnis: Rabatt-/Korrekturpositionen mit negativem Preis werden normkonform exportiert.
|
||||
Belege:
|
||||
- [SEKUNDÄR] docs/reference/zugferd-field-mapping.md:272-275,355-359 - Begründung: Ausführliche Beschreibung der Regel, jedoch nur indirekt über Code-Kommentare (Zeilen 994-999) im Quellcode rückbestätigt
|
||||
- [KONTEXT] src/backend/Centron.BL/DataExchange/EDI/SaleInvoices/InvoiceZugferdBL.cs:994-999 - Begründung: Verwandte Vorzeichenlogik für Rabatte im selben Modul bestätigt das Muster
|
||||
Prüfidee: Gutschriftposition mit negativem Preis exportieren, XML auf positiven ChargeAmount und negierte BilledQuantity prüfen
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-15
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System (E-Rechnungs-Export)
|
||||
Vorbedingung: Rechnung enthält Titelpositionen mit untergeordneten Positionen unterschiedlicher Steuersätze
|
||||
Fakt: Beim Aggregieren von Titelpositionen wird bei unterschiedlichen Steuersätzen der untergeordneten Positionen der Export mit Fehlermeldung abgebrochen: "In der Titelposition '{Text}' kommen unterschiedliche Mehrwertsteuern vor (...), dass wird nicht unterstützt! Bitte klappen Sie die Titelposition auf, oder splitten Sie die Positionen..." (InvoiceZugferdBL.cs:950-952). Ausgeklappte Titelpositionen werden generell nicht unterstützt (nur eingeklappte/kollabierte Titelpositionen mit Menge=1 werden exportiert).
|
||||
Aussage: Das System soll beim E-Rechnungsexport gemischte Steuersätze innerhalb einer eingeklappten Titelposition erkennen und den Export mit einer handlungsleitenden Fehlermeldung verweigern.
|
||||
Ergebnis: Verhindert steuerlich inkorrekte E-Rechnungen bei Titelpositionen; Anwenderin erhält konkrete Lösungshinweise.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/DataExchange/EDI/SaleInvoices/InvoiceZugferdBL.cs:938-953 - Begründung: Exakte Fehlermeldung und Abbruchlogik im Code
|
||||
Prüfidee: Titelposition mit Kindpositionen zu 19% und 7% MwSt. exportieren -> erwarteter Abbruch mit obiger Meldung
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-16
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: Buchhaltung
|
||||
Vorbedingung: Gutschrift wurde aus einer oder mehreren Rechnungen erzeugt
|
||||
Fakt: Beim E-Rechnungs-Export einer Gutschrift wird nur dann ein Verweis auf die Ursprungsrechnung (`InvoiceReferencedDocument`) gesetzt, wenn genau eine eindeutige Ursprungsrechnung ermittelt werden kann (`items.Count == 1`, ermittelt über `OriginKind == Invoice` und `DistinctBy(OriginReceiptI3D)`); bei mehreren oder keiner Ursprungsrechnung bleibt das Feld leer.
|
||||
Aussage: Das System soll bei Gutschriften automatisch auf die zugehörige Ursprungsrechnung im E-Rechnungs-XML verweisen, sofern die Zuordnung eindeutig ist.
|
||||
Ergebnis: Nachvollziehbarkeit von Gutschriften gegenüber Rechnungen für Kunden/Finanzamt, ohne fehlerhafte Mehrfachreferenzen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/DataExchange/EDI/SaleInvoices/InvoiceZugferdBL.cs:803-811,1873-1878 - Begründung: Eindeutigkeitsprüfung und bedingte Referenzsetzung im Code
|
||||
Prüfidee: Sammelgutschrift zu zwei Rechnungen exportieren -> InvoiceReferencedDocument darf nicht gesetzt sein
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-17
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System (Contract-Billing / RMM-Integration)
|
||||
Vorbedingung: Vertrag ist für RMM-Abrechnung konfiguriert (`WhetherRMM=true`) und automatische Rechnungserstellung wird ausgeführt
|
||||
Fakt: `CheckRMMArticle` (AutomaticFacturaWebServiceBL.cs:721-802) ruft für den Abrechnungszeitraum Nutzungsdaten des externen RMM-Systems (Riverbird, via `RiverConnectionBL.GetContractBillingAmounts`) ab. Ist der RMM-Service nicht erreichbar UND werden RMM-Artikel im Vertrag erwartet, wird eine `RMMServiceUnavailableException` mit Fehlermeldung "Die Rechnung kann nicht erstellt werden. {Message}" geworfen und die gesamte Rechnungserstellung abgebrochen.
|
||||
Aussage: Das System soll bei RMM-basierter Vertragsabrechnung die automatische Rechnungserstellung abbrechen, wenn die externe Nutzungsdatenquelle nicht erreichbar ist, um Rechnungen mit unvollständigen Nutzungsdaten zu verhindern.
|
||||
Ergebnis: Kunden werden nicht auf Basis unvollständiger/fehlerhafter Nutzungsdaten fakturiert; Fehlerprotokollierung ermöglicht Nachverfolgung.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/WebServices/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaWebServiceBL.cs:790-802,2412-2415 (Exception-Definition und Wurf-Stelle) - Begründung: Vollständige Fehlerbehandlungslogik direkt im Code
|
||||
- [SEKUNDÄR] docs/reference/receipts/Contract-Billing-RMM-Article-Logic.md:45-52 - Begründung: Bestätigt fachlichen Zweck der Regel
|
||||
Prüfidee: RMM-Service (Riverbird) für Testzeitraum offline simulieren, automatische Vertragsabrechnung anstoßen -> Abbruch mit Exception erwarten
|
||||
Konsolidierungshinweis: Detailliert BILL-02
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-18
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System (Contract-Billing)
|
||||
Vorbedingung: RMM-Nutzungsmenge für einen Vertragsartikel wurde ermittelt, Vertragsartikel hat konfigurierte Kontingentmenge (`ContractAmount`)
|
||||
Fakt: `ContractArticleReferenzes.CalculateContractBillingAmount(decimal riverbirdAmount)` (Entities/.../ContractArticleReferenzes.cs:27-39): Sind sowohl `ConsiderOverbooking` als auch `ConsiderUnderbooking` gesetzt, wird immer die feste `ContractAmount` abgerechnet; ist nur `ConsiderOverbooking` gesetzt und die Ist-Menge übersteigt die Kontingentmenge, wird auf `ContractAmount` gedeckelt; ist nur `ConsiderUnderbooking` gesetzt und die Ist-Menge liegt darunter, wird ebenfalls auf `ContractAmount` gedeckelt; ansonsten wird die tatsächliche RMM-Menge abgerechnet.
|
||||
Aussage: Das System soll die abzurechnende Menge eines RMM-Vertragsartikels regelbasiert aus Ist-Nutzung und konfigurierbarer Über-/Unterbuchungsdeckelung ableiten.
|
||||
Ergebnis: Kontrollierte Abrechnung bei schwankender Nutzung (z.B. Lizenzverträge mit Mindest-/Höchstmenge).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/Sales/CustomerAssets/Contracts/ContractArticleReferenzes.cs:27-39 - Begründung: Vollständige, deterministische Berechnungsmethode im Code
|
||||
Prüfidee: Testfälle mit ConsiderOverbooking/Underbooking-Kombinationen und Ist-Mengen über/unter ContractAmount durchspielen
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-19
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System (Vertrags-Kontingentverwaltung)
|
||||
Vorbedingung: Rechnung oder Gutschrift mit Bezug zu einem Vertrag mit Kontingent (Geld- oder Mengenkontingent) wird gebucht
|
||||
Fakt: `ReceiptContractBL.ContractContingentBalanceCalculation` (Zeilen 149-221) berechnet den Kontingentwert entweder als Nettobetrag (`ContingentKinds.Money`) oder als Menge (inkl. Zeitumrechnung via `CalculateContingentWithRecalculationArticle`); bei Gutschriften (`CentronObjectKindNumeric.CreditVoucherClass`) wird der Wert mit `-1` multipliziert (Zeilen 188-190, 194-196), d.h. Gutschriften reduzieren den Kontingentverbrauch. Das Ergebnis wird in der Zuordnungstabelle `VertragRechKopfZuordnung` persistiert.
|
||||
Aussage: Das System soll bei jeder vertragsbezogenen Rechnung den Kontingentverbrauch erhöhen und bei jeder vertragsbezogenen Gutschrift den Kontingentverbrauch entsprechend wieder verringern.
|
||||
Ergebnis: Korrekter, buchungsgenauer Kontingentsaldo je Vertrag über Rechnungs- und Gutschriftbuchungen hinweg.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ContractLists/ReceiptContractBL.cs:149-221 - Begründung: Vollständige Berechnungs- und Vorzeichenlogik im Code
|
||||
Prüfidee: Vertragsrechnung buchen, danach zugehörige Gutschrift buchen, Kontingentsaldo vor/nach vergleichen
|
||||
Konsolidierungshinweis: Ergänzt BILL-02/BILL-17
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-20
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: System (Auftrags-/Belegsperre)
|
||||
Vorbedingung: Benutzer versucht neuen Beleg (z.B. Auftrag) für einen Kunden/Lieferanten anzulegen
|
||||
Fakt: `ReceiptBL.CanUserCreateNewReceiptsAtCustomerOrSupplier<TReceipt>` (Zeilen 10194-10219) ermittelt zunächst die aktuelle Mahnstufe des Kunden (`GetCustomerOrSupplierDunningLevel<TReceipt>`) und den je Belegtyp konfigurierten Sperr-Schwellwert (`BlockNewReceiptsDunningLevel`, für Aufträge implementiert in `OrderSpecificLogic.cs:687-693` über `customerDetail.OrderLockAfterDunning`). Ist die aktuelle Mahnstufe >= Schwellwert, wird die Anlage mit Fehlermeldung "Aufgrund der Mahnstufe darf kein neuer Beleg vom Typ \"{...}\" angelegt werden." verweigert.
|
||||
Aussage: Das System soll je Belegtyp konfigurierbar prüfen, ob die aktuelle Mahnstufe eines Kunden die Neuanlage von Belegen sperrt, und die Anlage in diesem Fall mit einer sprechenden Fehlermeldung verweigern.
|
||||
Ergebnis: Automatisierte Kreditkontrolle direkt in der Belegerfassung.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs:10194-10219 - Begründung: Vollständige Sperrlogik inkl. exakter Fehlermeldung
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/Orders/OrderSpecificLogic.cs:687-693 - Begründung: Konkrete belegtypspezifische Implementierung des Schwellwerts für Aufträge
|
||||
Prüfidee: Kunde mit LockOrderAfterDunning=1 und aktueller Mahnstufe 1: Auftragsanlage -> Fehlermeldung erwarten; Mahnstufe 0 -> Anlage möglich
|
||||
Konsolidierungshinweis: Verfeinerung von BILL-03
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-21
|
||||
Ebene: SyRS
|
||||
Typ: Daten
|
||||
Akteur: Finanzbuchhaltung (Administration)
|
||||
Vorbedingung: Mahnlauf wird konfiguriert
|
||||
Fakt: Anwendungseinstellungen `DunningLevel1Fees=10127`, `DunningLevel2Fees=10128`, `DunningLevel3Fees=10129` (ApplicationSettingID.cs:855-857) sowie je-Kunde-Felder `DunningLetterAfterDays1-3` und `LockOrderAfterDunningLevel` definieren gestaffelte Mahngebühren und Fristen für bis zu drei Mahnstufen.
|
||||
Aussage: Das System soll bis zu drei konfigurierbare Mahnstufen mit jeweils eigener Gebühr, Frist (Tage nach Fälligkeit) und optionaler Beleg-Sperre unterstützen.
|
||||
Ergebnis: Flexibles, mehrstufiges Mahnwesen je Mandant konfigurierbar.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Interfaces/Administration/Settings/ApplicationSettingID.cs:855-857 - Begründung: Konkrete Einstellungs-IDs im Code
|
||||
- [PRIMÄR] src/backend/Centron.DAO/Repositories/Accounts/AccountRepository.cs:660-663 (Mapping MahnungNachTagen/2/3, AuftragsperreNachMahnung) - Begründung: Bestätigt Persistenzfelder je Kunde
|
||||
Prüfidee: Drei Mahnstufen mit unterschiedlichen Gebühren konfigurieren, Mahnlauf für überfälligen Kunden ausführen, erzeugte Mahngebühr prüfen
|
||||
Konsolidierungshinweis: Ergänzt BILL-03/BILL-20
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-22
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: Zahlungseingang / Buchhaltung
|
||||
Vorbedingung: Ein bereits erfasster Zahlungseingang zu einer Rechnung wird gelöscht
|
||||
Fakt: `PaymentsBL.DeleteIncomingPayment` (Zeilen 38-78) prüft das Recht `INCOMING_PAYMENT_TRANSACTIONS`; sofern `filter.DontChangeInvoice == false`, wird je betroffener Rechnung die Summe der zu löschenden Zahlungsbeträge negiert (`* -1`) und über `ReceiptBL.UpdateReceiptIsPaid` mit Währungsfaktor (`* invoice.CurrencyFactor`) und Log-Grund "Zahlungseingang gelöscht" zurückgebucht.
|
||||
Aussage: Das System soll beim Löschen eines Zahlungseingangs den zugehörigen offenen/bezahlten Betrag der Rechnung automatisch um den gelöschten Betrag korrigieren.
|
||||
Ergebnis: Konsistenter Rechnungssaldo auch nach nachträglicher Korrektur von Zahlungseingängen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Finances/Payments/PaymentsBL.cs:38-78 - Begründung: Vollständige Rückbuchungslogik im Code
|
||||
Prüfidee: Zahlungseingang zu Rechnung erfassen, Saldo prüfen, Zahlungseingang löschen, Saldo erneut prüfen
|
||||
Konsolidierungshinweis: Ergänzt BILL-08
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-23
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: Einkauf / Preispflege
|
||||
Vorbedingung: Aktionspreis (Distributor-Sonderpreis) für Artikel wurde erfasst
|
||||
Fakt: `PriceMatrixViewModel.GetPriceItemsFromArticleActionPrices` filtert Aktionspreise ausschließlich nach Gültigkeitsfenster: `EffectiveFrom.StartOfDay() <= DateTime.Now && EffectiveUntil >= DateTime.Now` (laut docs/reference/receipts/actionprice-system.md:312, im UI-Modul `PriceMatrixViewModel.cs`). Nur aktuell gültige Aktionspreise werden in der Preismatrix angezeigt.
|
||||
Aussage: Das System soll in der Preisfindung nur zeitlich gültige Aktionspreise (aktuelles Datum zwischen Gültig-von/-bis) berücksichtigen.
|
||||
Ergebnis: Verkäufer sehen ausschließlich aktuell gültige Sonderkonditionen bei der Preisfindung.
|
||||
Belege:
|
||||
- [SEKUNDÄR] docs/reference/receipts/actionprice-system.md:196-212,306-312 - Begründung: Dokumentierte Filterlogik mit Code-Referenz auf PriceMatrixViewModel.cs, jedoch nicht selbst im Quellcode gegengelesen
|
||||
Prüfidee: Aktionspreis mit EffectiveUntil in der Vergangenheit anlegen, Preismatrix öffnen -> Preis darf nicht erscheinen
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt; nicht im Quellcode direkt verifiziert (nur Dokumentation), daher SEKUNDÄR statt PRIMÄR
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-24
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit / Datenintegrität
|
||||
Akteur: Einkauf / Preispflege
|
||||
Vorbedingung: Neuer Aktionspreis wird über den Dialog "Aktionspreis hinzufügen" erfasst
|
||||
Fakt: Die Pflichtfeldprüfung (Distributor darf nicht leer sein; `EffectiveFrom` darf nicht nach `EffectiveUntil` liegen) ist ausschließlich in der WPF-ViewModel-Schicht implementiert (`AddActionPriceViewModel.cs:69-79`, `Ok()`-Methode mit MessageBox-Abbruch). Die Business-Logic-Schicht `ActionPriceBL.SaveOrUpdateActionPrice` (Zeilen 36-41) führt dagegen nur einen `Guard.NotNull`-Nullcheck durch, keine fachliche Validierung; auch über die REST-API (`SaveOrUpdateActionPrice`) ist kein serverseitiger Constraint ersichtlich.
|
||||
Aussage: Das System soll die Pflichtfeld- und Plausibilitätsprüfung für Aktionspreise (Distributor vorhanden, gültiger Zeitraum) serverseitig (BL/API/DB) durchsetzen, nicht nur im WPF-Client.
|
||||
Ergebnis: Verhindert, dass über die REST-API oder zukünftige Web-Clients ungültige Aktionspreise (leerer Distributor, invertierter Zeitraum) persistiert werden können.
|
||||
Belege:
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Warehousing/ArticleManagement/OpenDialog/ActionPrice/AddActionPriceViewModel.cs:69-79 - Begründung: Zeigt, dass die Validierung nur clientseitig erfolgt
|
||||
- [PRIMÄR] src/backend/Centron.BL/Warehousing/ActionPriceBL.cs:36-41 - Begründung: Zeigt Fehlen jeglicher fachlicher Validierung in der Business-Logic-Schicht
|
||||
Prüfidee: Aktionspreis direkt über REST-Endpoint `SaveOrUpdateActionPrice` mit leerem Distributor bzw. EffectiveFrom > EffectiveUntil senden -> prüfen ob Speicherung dennoch gelingt
|
||||
Konsolidierungshinweis: Wichtiger Befund für Web-/SaaS-Neuimplementierung: bestehende Lücke nicht unreflektiert übernehmen, sondern serverseitig nachrüsten
|
||||
Status: belegt; Workaround (Validierung nur im Legacy-WPF-Client vorhanden, kein serverseitiger Constraint nachweisbar)
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-25
|
||||
Ebene: SyRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: System (E-Rechnungs-Export, Zahlungsdaten)
|
||||
Vorbedingung: Rechnung wird für ZUGFeRD/XRechnung exportiert und benötigt eine Bankverbindung
|
||||
Fakt: Die Bankauswahl für den E-Rechnungs-Export erfolgt hierarchisch: zunächst über die Einstellung `ReceiptInvoiceSettings.UseMandatorBankForInvoice` (Bank1-4), die pro Kunde über `AccountCustomer.MandatorBank` überschrieben werden kann; die konkreten IBAN/BIC-Daten stammen aus den Mandantenstammdaten (`Mandator.Bank1Iban/Bic` ... `Bank4Iban/Bic`). Bei SEPA-Lastschrift wird stattdessen die Kunden-IBAN aus `BankAccount.Iban` sowie die SEPA-Mandatsreferenz aus `BankAccount.AuthorizationNumber` verwendet.
|
||||
Aussage: Das System soll die für den E-Rechnungsexport verwendete Bankverbindung nach einer festen Priorität (kundenspezifische Einstellung vor globaler Mandanteneinstellung) auflösen und zwischen Überweisung und SEPA-Lastschrift unterscheiden.
|
||||
Ergebnis: Korrekte Zahlungsinformationen je nach Zahlungsart und Kundeneinstellung im E-Rechnungs-XML.
|
||||
Belege:
|
||||
- [SEKUNDÄR] docs/reference/zugferd-field-mapping.md:157-160 - Begründung: Dokumentierte Bankauswahl-Hierarchie mit Verweis auf Datenquellen; Umsetzung im Code (InvoiceZugferdBL.cs Settlement-Bereich) nicht Zeile-für-Zeile nachgelesen
|
||||
Prüfidee: Kunde mit abweichender MandatorBank-Einstellung anlegen, Rechnung exportieren, verwendete IBAN/BIC im XML mit Erwartungswert vergleichen
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-26
|
||||
Ebene: SyRS
|
||||
Typ: Daten
|
||||
Akteur: System (Belegarchitektur)
|
||||
Vorbedingung: Ein Beleg (Angebot/Auftrag/Lieferschein/Rechnung/Vertrag/Gutschrift/Abholliste) wird gespeichert oder verändert
|
||||
Fakt: Jede Belegänderung wird über `AssetHeadDAO.SaveAssetVersion` als vollständige 1:1-Kopie in eine Versionstabelle geschrieben (z.B. `VertragKopfVersions`, `RechKopfVersions`); Versionstabellen müssen laut Doku und Code-Konvention exakt dieselben Spalten wie die Basistabelle enthalten (zzgl. `OriginalI3D`/`KopfVersionsI3D`), sonst schlägt die Versionierung zur Laufzeit fehl (`DoGetFieldList()`).
|
||||
Aussage: Das System soll für alle Belegtypen eine vollständige, spaltengenaue Versionshistorie (Audit-Trail) führen, die jede Änderung als eigenständige, abfragbare Version persistiert.
|
||||
Ergebnis: Lückenlose Nachvollziehbarkeit aller Belegänderungen inkl. Rollback-Fähigkeit; Grundlage für Compliance-Anforderungen (GoBD).
|
||||
Belege:
|
||||
- [PRIMÄR] docs/reference/receipts/receipts-backend-architecture.md:147-204 - Begründung: Detaillierte Beschreibung der 1:1-Versionierungsmechanik inkl. SQL-Beispiel; als architekturelle Konvention durchgängig in den Datenbank-Skripten (Kopf-/Pos-Versions-Tabellen) sichtbar
|
||||
- [KONTEXT] src/backend/Centron.BL/Sales/Receipts/ContractLists/ReceiptContractBL.cs (Nutzung versionierter Verträge über Contract-Version-Views) - Begründung: Bestätigt praktische Nutzung des Versionierungsmusters bei Verträgen
|
||||
Prüfidee: Vertrag mehrfach ändern, VertragKopfVersions auf lückenlose OriginalI3D-Kette prüfen
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-27
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: System (Audit-Log)
|
||||
Vorbedingung: Vertrag wird angelegt, geändert, abgerechnet oder gekündigt
|
||||
Fakt: Verträge protokollieren Ereignisse zentral über die Tabelle `AnlageLog` mit `AnlageArt = 22` (Contract-Identifier) und `AnlageI3D` als Verweis auf den Vertrag; dasselbe Muster (`AnlageI3D`+`AnlageArt`) wird für alle Belegtypen verwendet (z.B. 1=Angebot, 2=Auftrag, 4=Rechnung, 6=Gutschrift).
|
||||
Aussage: Das System soll geschäftsrelevante Ereignisse an Verträgen (Erstellung, Änderung, Abrechnung, Kündigung) in einem zentralen, belegtypübergreifenden Audit-Log erfassen.
|
||||
Ergebnis: Einheitliche, auswertbare Historie für Compliance- und Support-Zwecke über alle Belegtypen hinweg.
|
||||
Belege:
|
||||
- [SEKUNDÄR] docs/reference/receipts/contracts-backend.md:204-220 - Begründung: Dokumentiert Tabellenschema und Verwendung; korrespondierendes Enum/Konstantenwert (AnlageArt=22) nicht separat im Code verifiziert
|
||||
Prüfidee: Vertragsänderung durchführen, AnlageLog-Eintrag mit AnlageArt=22 und korrektem AnlageI3D erwarten
|
||||
Konsolidierungshinweis: Ergänzt BILL-26
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-28
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: System (Preisfindung Titelpositionen)
|
||||
Vorbedingung: E-Rechnungsexport einer Rechnung mit Titelposition ohne untergeordnete Positionen
|
||||
Fakt: Für Titelpositionen ohne Kindpositionen wird beim ZUGFeRD-Export standardmäßig ein Steuersatz von 19% angenommen (laut docs/reference/zugferd-feldzuordnung-anwender.md:331 "Standard-Steuersatz: Wenn eine Titelposition keine untergeordneten Positionen hat, wird 19% verwendet").
|
||||
Aussage: Das System soll für leere Titelpositionen beim E-Rechnungsexport einen definierten Standard-Steuersatz (19%) ansetzen, statt den Export mit unbestimmtem Steuersatz zu blockieren.
|
||||
Ergebnis: Robuster Export auch bei untypischen/leeren Titelpositionen, aber mit Risiko falscher Steuerangabe bei abweichendem tatsächlichem Steuersatz.
|
||||
Belege:
|
||||
- [SEKUNDÄR] docs/reference/zugferd-feldzuordnung-anwender.md:331 und docs/reference/zugferd-field-mapping.md:365 - Begründung: In zwei unabhängigen Dokumentationsartefakten übereinstimmend beschrieben, jedoch nicht im Quellcode zeilengenau verifiziert
|
||||
Prüfidee: Leere Titelposition (keine Kindpositionen) in Rechnung anlegen und exportieren, resultierenden Steuersatz im XML prüfen
|
||||
Konsolidierungshinweis: Ergänzt BILL-15
|
||||
Status: belegt; [HYPOTHESE]-nah, da nur SEKUNDÄR belegt (Code-Stelle nicht gegengelesen) - Risikobereich Steuerberechnung, vor Übernahme in Web-Neuimplementierung im Code verifizieren
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-29
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: Buchhaltung / Vertragsverwaltung
|
||||
Vorbedingung: Vertragsrechnung soll storniert werden
|
||||
Fakt: `ReceiptInvoiceBL.CancelInvoice` erlaubt die Stornierung einer Vertragsrechnung nur, wenn sie laut `IsLastContractInvoice` die aktuell für den Vertrag zuletzt erstellte Rechnung ist (Abgleich über `ReceiptContractBL.GetContractInfos(...).CurrentInvoiceI3D`); andernfalls Fehlermeldung: "Die Rechnung kann nicht storniert werden, da Sie nicht die letzte für den Vertrag erstellte Rechnung ist. Sie können nur jeweils die zuletzt für einen Vertrag erstellte Rechnung stornieren."
|
||||
Aussage: Das System soll bei Vertragsrechnungen die Stornierung auf die jeweils zuletzt erstellte Rechnung je Vertrag beschränken, um die Konsistenz der Vertragsabrechnungshistorie (Kontingente, Zuordnungen) zu erhalten.
|
||||
Ergebnis: Verhindert inkonsistente Kontingent-/Zuordnungshistorie bei Verträgen durch Storno "mittendrin liegender" Rechnungen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs:170-172,236-251 - Begründung: Exakte Prüf- und Fehlermeldungslogik im Code
|
||||
Prüfidee: Vertrag mit zwei Abrechnungsperioden abrechnen, Storno der ersten (nicht letzten) Rechnung versuchen -> erwartete Fehlermeldung
|
||||
Konsolidierungshinweis: Verfeinerung von BILL-06
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat BILL-30
|
||||
Ebene: SwRS
|
||||
Typ: Schnittstelle
|
||||
Akteur: System (Belegsuche)
|
||||
Vorbedingung: Anwenderin sucht über mehrere Belegtypen hinweg (inkl. Rechnungen, Verträge, Gutschriften)
|
||||
Fakt: `ReceiptSearcher.SearchReceipts` (ReceiptSearcher.cs) iteriert über alle registrierten `ReceiptSearchConfiguration`-Implementierungen je Belegtyp, generiert dynamisch parametrisierte Raw-SQL-Statements (Timeout 5 Minuten) und prüft je Belegtyp konfigurierbare Rechte (`ShowRight`, `OnlyOwnRight`, `OnlyOwnBranchRight`); fehlende Rechte führen dazu, dass für diesen Belegtyp `null` zurückgegeben und er stillschweigend aus dem Suchergebnis ausgeschlossen wird.
|
||||
Aussage: Das System soll bei der belegtypübergreifenden Suche serverseitig je Belegtyp und Benutzer prüfen, ob Zugriffsrechte bestehen, und Ergebnisse ohne Berechtigung nicht anzeigen.
|
||||
Ergebnis: Konsistente Rechtedurchsetzung auch in der übergreifenden Belegsuche (z.B. Rechnungen, Verträge), keine Informationslecks über Belegtypgrenzen.
|
||||
Belege:
|
||||
- [PRIMÄR] docs/reference/receipts/receipt-search-architecture.md:154-190 (mit Code-Zitat aus ReceiptSearcher.CreateSqlStatementAndParameters) - Begründung: Dokumentation zitiert die tatsächliche Rechteprüfungslogik im Code direkt
|
||||
Prüfidee: Benutzer ohne Vertragsrecht sucht belegtypübergreifend -> Verträge dürfen nicht im Ergebnis erscheinen
|
||||
Konsolidierungshinweis: Rahmenbedingung für alle BILL-Kandidaten mit Belegzugriff
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
## Abdeckung
|
||||
|
||||
**Vollständig gelesen (Docs):**
|
||||
- docs/reference/receipts/actionprice-system.md
|
||||
- docs/reference/receipts/Contract-Billing-RMM-Article-Logic.md
|
||||
- docs/reference/receipts/contracts-backend.md
|
||||
- docs/reference/receipts/receipt-search-architecture.md
|
||||
- docs/reference/receipts/receipts-backend-architecture.md
|
||||
- docs/reference/zugferd-feldzuordnung-anwender.md
|
||||
- docs/reference/zugferd-field-mapping.md
|
||||
- docs/guides/development/xrechnung.md (nur Linksammlung, kein fachlicher Inhalt)
|
||||
|
||||
**Code-Dateien gezielt gelesen/gegengeprüft (mit Zeilenangaben in den Belegen):**
|
||||
- src/backend/Centron.Interfaces/Sales/Receipts/ReceiptState.cs (vollständig)
|
||||
- src/backend/Centron.BL/Sales/Receipts/Invoices/ReceiptInvoiceBL.cs (Zeilen 1-320, insb. CancelInvoice, FixInvoice, CheckIfInvoiceIsFixed)
|
||||
- src/backend/Centron.BL/Sales/Receipts/ReceiptBL.cs (Ausschnitte: UpdateReceiptIsPaid Zeilen 4900-5000, CanUserCreateNewReceiptsAtCustomerOrSupplier Zeilen 10194-10230, GetNextReceiptTemplateNumber-Umfeld Zeile 7280ff.)
|
||||
- src/backend/Centron.BL/Administration/Company/NumberGroupBL.cs (Zeilen 1-140)
|
||||
- src/backend/Centron.BL/DataExchange/EDI/SaleInvoices/InvoiceZugferdBL.cs (mehrere gezielte Ausschnitte: Header/Formatwahl 100-200, Positionsverarbeitung 780-1050, Steuerlogik 2080-2130, Referenzdokument 1870-1900)
|
||||
- src/backend/Centron.BL/WebServices/Sales/CustomerAssets/AutomaticFactura/AutomaticFacturaWebServiceBL.cs (CheckRMMArticle-Umfeld Zeilen 700-810, 1900-2060, Exception-Klasse Zeilen 2400-2416)
|
||||
- src/backend/Centron.Entities/Entities/Sales/CustomerAssets/Contracts/ContractArticleReferenzes.cs (vollständig)
|
||||
- src/backend/Centron.BL/Sales/Receipts/ContractLists/ReceiptContractBL.cs (Zeilen 149-238, Methodenübersicht via Grep)
|
||||
- src/backend/Centron.BL/Sales/Receipts/Orders/OrderSpecificLogic.cs (BlockNewReceiptsDunningLevel-Umfeld)
|
||||
- src/backend/Centron.BL/Finances/Payments/PaymentsBL.cs (Zeilen 1-150)
|
||||
- src/backend/Centron.BL/VoucherManagement/VoucherManagementBL.cs (vollständig, sehr klein/dünn)
|
||||
- src/backend/Centron.BL/Warehousing/ActionPriceBL.cs (relevante Methode SaveOrUpdateActionPrice)
|
||||
- src/centron/Centron.WPF.UI/.../AddActionPriceViewModel.cs (Ok()-Methode)
|
||||
- src/backend/Centron.Interfaces/Administration/Settings/ApplicationSettingID.cs (Dunning-Settings-Ausschnitt)
|
||||
- src/backend/Centron.Entities/Entities/Accounts/AccountCustomer.cs / IAccountCustomer.cs (LockOrderAfterDunningLevel)
|
||||
- src/backend/Centron.DAO/Repositories/Accounts/AccountRepository.cs (Dunning-Feld-Mapping-Ausschnitt)
|
||||
- src/backend/Centron.BL/WebServices/Sales/Receipts/DunningWebServiceBL.cs (vollständig)
|
||||
|
||||
**Bewusst ausgelassen / nur oberflächlich per Grep gesichtet (Zeitbudget):**
|
||||
- src/backend/Centron.BL/Sales/Receipts/Invoices/Dunning/DunningBL.cs (nur referenziert, nicht Zeile für Zeile gelesen) – enthält vermutlich die eigentliche Mahnstufen-Berechnung; für tiefere SwRS-Kandidaten zur exakten Mahnstufen-Ermittlung empfehlenswert
|
||||
- src/backend/Centron.BL/DataExchange/EDI/SaleInvoices/InvoiceZugferdBL.Zugferd10.cs (Legacy-ZUGFeRD-1.0-Variante) nicht gelesen
|
||||
- src/backend/Centron.BL/WebServices/Sales/Receipts/DownPayment/DownPaymentWebServiceBL.cs (Anzahlungsrechnungen) nicht gelesen – potenzieller weiterer Kandidatenbereich für Nachfolgeanalyse
|
||||
- src/backend/Centron.BL/WebServices/Sales/Receipts/OposRunWebServiceBL.cs (OPOS-Liste/offene Posten) nicht gelesen
|
||||
- Preismatrix-Kernlogik (PriceMatrixViewModel.cs) nicht direkt gelesen, nur über Dokumentation referenziert (BILL-23)
|
||||
- Skonto-Berechnung (AssetConditionBL.GetPaymentConditionSkontoInBR_DE_18Format) nicht im Detail gelesen, nur referenziert
|
||||
- SupplierInvoice/SupplierCreditVoucher-seitige Spiegelprozesse (Kreditorenseite) nicht untersucht – Cluster-Fokus lag auf Debitoren-/Verkaufsseite gemäß Auftrag
|
||||
- Centron.DAO-Constraints (DB-Skripte, NOT NULL/CHECK-Constraints) wurden nicht systematisch nach zusätzlichen Abrechnungs-Constraints durchsucht; punktuell nur für ActionPrice (BILL-24) als Lückenbefund genutzt
|
||||
|
||||
**Bekannte Lücken für Konsolidierung:**
|
||||
- Kein dediziertes `InvoiceStatus`/`VoucherStatus`/`ContractStatus`-Enum gefunden; alle Belegtypen nutzen einheitlich `ReceiptState` (Active/Completed/Canceled) – ggf. mit anderen Clustern (z.B. Auftrags-/Logistik-Cluster) abgleichen, da dieselbe Statusmaschine auch dort verwendet wird.
|
||||
- BILL-23, BILL-25, BILL-27, BILL-28 sind nur SEKUNDÄR (Dokumentation) belegt, da aus Zeitgründen die referenzierten Code-Stellen (PriceMatrixViewModel.cs, InvoiceZugferdBL.cs Settlement-Bereich im Detail, AnlageLog-Konstanten) nicht zeilengenau gegengelesen wurden – vor Übernahme in die konsolidierte Spezifikation nachverifizieren.
|
||||
- BILL-24 ist ein Risikobefund (Gap): fehlende serverseitige Validierung bei ActionPrice – sollte in der Zielarchitektur (Web/SaaS) explizit als Anforderung "serverseitige Validierung" aufgenommen werden, nicht nur als Ist-Zustand dokumentiert.
|
||||
+506
@@ -0,0 +1,506 @@
|
||||
# RRE Rohbefunde – Cluster STAMMDATEN / CRM (Geschäftspartner, Kunden, Mitarbeiter-Stammdaten)
|
||||
|
||||
Quellbasis: `C:\DEV\MasterArbeit\QuellCode\CentronERP` (nur gelesen, keine Änderungen).
|
||||
Hinweis: Der im Auftrag genannte Ordner `Centron.BL/BusinessPartner` enthält faktisch nur Lieferanten-Suche/-Assets
|
||||
(`SearchSupplierBL.cs`, `SupplierAssetBL.cs`); die Kunden-/CRM-Kernlogik liegt unter `Centron.BL/Sales/Customers`
|
||||
(Namespace `Centron.BusinessLogic.Sales.Customers`). Beide Bereiche wurden einbezogen.
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-01
|
||||
Ebene: SwRS
|
||||
Typ: Daten / funktional
|
||||
Akteur: Vertrieb
|
||||
Vorbedingung: Neuanlage eines Kunden (Geschäftspartner Typ Kunde)
|
||||
Fakt: Beim Speichern eines neuen `Customer` prüft `StoreCustomerBL.DoValidateValues` ausschließlich, ob `entity.Name` leer/whitespace ist; ist dies der Fall, wird der Speichervorgang mit der Meldung "Bitte geben Sie einen Namen ein" abgebrochen. Kein anderes Feld (z. B. Adresse, USt-IdNr., Bankverbindung) wird beim Speichern serverseitig validiert.
|
||||
Aussage: Das System soll beim Anlegen und Ändern eines Kunden-Geschäftspartners zwingend einen nicht-leeren Namen verlangen und den Speichervorgang andernfalls mit einer Fehlermeldung ablehnen.
|
||||
Ergebnis: Speichern schlägt fehl mit Fehlermeldung "Bitte geben Sie einen Namen ein", solange `Name` leer ist; alle übrigen Felder sind serverseitig ungeprüft.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Customers/StoreCustomerBL.cs:39-51 (`DoValidateValues`) - Begründung: Einzige serverseitige Pflichtfeldprüfung beim Kunden-Speichern.
|
||||
Prüfidee: Kunde ohne Namen über Backend-API/BL anlegen und Fehlermeldungstext/-code prüfen; Kunde mit Namen aber ohne Adresse/USt-IdNr. anlegen und beobachten, dass kein Fehler auftritt.
|
||||
Konsolidierungshinweis: Ergänzt CRM-18 (fehlende Formatvalidierung USt-IdNr./IBAN).
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-02
|
||||
Ebene: SwRS
|
||||
Typ: Daten / funktional
|
||||
Akteur: Vertrieb
|
||||
Vorbedingung: Neuanlage eines Kunden über `CustomerBL.GetEmptyCustomer`
|
||||
Fakt: Ein neu instanziierter Kunde erhält per Default `State = 1` (aktiv) und `Locked = false` (nicht gesperrt); zusätzlich wird automatisch eine leere Standard-Adresse (`DefaultCustomer = true`) angelegt.
|
||||
Aussage: Das System soll neu angelegte Kunden standardmäßig als aktiv und ungesperrt initialisieren und automatisch eine als Standard markierte Adresse anlegen.
|
||||
Ergebnis: Neuer Kunde ist sofort `State=1`, `Locked=false`, mit genau einer Default-Adresse.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/CustomerArea/CustomerBase.cs:12-17 (`State = 1` im Konstruktor) - Begründung: Basis-Default.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Customers/CustomerBL.cs:198-211 (`GetEmptyCustomer`) - Begründung: Explizite Zuweisung `State=1; Locked=false;` plus Default-Adresse.
|
||||
- [SEKUNDÄR] src/backend/Centron.BL/Sales/Customers/StoreCustomerBL.cs:30-34 - Begründung: Bei `isNew` wird `State=1`/`Locked=false` beim Speichern erneut erzwungen.
|
||||
Prüfidee: Neuen Kunden über UI/BL anlegen, DB-Werte für `Status`/`Sperre` und Adress-Flag `DefaultCustomer` prüfen.
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-03
|
||||
Ebene: SyRS
|
||||
Typ: funktional / Daten
|
||||
Akteur: Vertrieb, Buchhaltung
|
||||
Vorbedingung: Kunde besitzt mehrere Adressen
|
||||
Fakt: `AddressBL.DoAfterStoreTrans` erzwingt nach dem Speichern einer Adresse mit `DefaultCustomer = true`, dass alle anderen Adressen desselben Kunden `DefaultCustomer = false` erhalten (analog für Lieferanten mit `DefaultCreditor`).
|
||||
Aussage: Das System soll sicherstellen, dass ein Kunde (bzw. Lieferant) zu jedem Zeitpunkt genau eine als Standard markierte Adresse besitzt.
|
||||
Ergebnis: Beim Setzen einer neuen Standardadresse werden alle vorherigen Standard-Flags desselben Kunden automatisch zurückgesetzt.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Customers/Addresses/AddressBL.cs:257-287 (`DoAfterStoreTrans`) - Begründung: Zeigt Kaskadenlogik für eindeutige Standardadresse/-kreditor.
|
||||
Prüfidee: Zweite Adresse eines Kunden als Standard markieren und speichern; prüfen, dass die erste Adresse automatisch entmarkiert wird.
|
||||
Konsolidierungshinweis: Zusammen mit CRM-04 (Standard-Ansprechpartner) und CRM-05 (Adresszuordnung) Kernregel der Adressverwaltung.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-04
|
||||
Ebene: SyRS
|
||||
Typ: funktional / Daten
|
||||
Akteur: Vertrieb
|
||||
Vorbedingung: Adresse besitzt mehrere Ansprechpartner
|
||||
Fakt: `ContactPersonBL.DoAfterStoreTrans` → `DoUpdateDefaultFlagFromOtherContacts` setzt beim Speichern eines Ansprechpartners mit `Default = true` alle anderen Ansprechpartner derselben Adresse auf `Default = false`.
|
||||
Aussage: Das System soll sicherstellen, dass jede Adresse höchstens einen als Standard markierten Ansprechpartner besitzt.
|
||||
Ergebnis: Eindeutigkeit des Standard-Ansprechpartners je Adresse wird durch die Business-Logik erzwungen (kein DB-Constraint, sondern Anwendungslogik).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Customers/ContactPersonBL.cs:190-220 (`DoAfterStoreTrans`, `DoUpdateDefaultFlagFromOtherContacts`) - Begründung: Explizite Kaskadenlogik.
|
||||
Prüfidee: Zwei Ansprechpartner derselben Adresse abwechselnd als Standard markieren, DB-Zustand prüfen.
|
||||
Konsolidierungshinweis: Ergänzt CRM-03.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-05
|
||||
Ebene: SwRS
|
||||
Typ: Daten / funktional
|
||||
Akteur: Vertrieb, Buchhaltung (Kunden und Lieferanten teilen die Adress-Entität)
|
||||
Vorbedingung: Anlage/Änderung einer Adresse
|
||||
Fakt: `AddressBL.DoValidateValues` verlangt, dass eine Adresse entweder einer `CustomerI3D` oder einer `SupplierI3D` zugeordnet ist; ansonsten Fehlermeldung "Die Anschrift muss entweder einem Kunden oder einem Lieferanten zugeordnet sein."
|
||||
Aussage: Das System soll jede Adresse zwingend genau einem Geschäftspartner (Kunde oder Lieferant) zuordnen und darf keine „verwaisten" Adressen speichern.
|
||||
Ergebnis: Speichern einer Adresse ohne Kunden- oder Lieferanten-Referenz wird abgelehnt.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Customers/Addresses/AddressBL.cs:225-238 (`DoValidateValues`) - Begründung: Wortlaut der Validierungsregel und Fehlermeldung.
|
||||
Prüfidee: Adresse ohne `CustomerI3D`/`SupplierI3D` speichern und Fehlermeldung prüfen.
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-06
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: Vertrieb
|
||||
Vorbedingung: Neuer Kunde ohne explizite Adresse/Ansprechpartner wird gespeichert
|
||||
Fakt: `StoreCustomerBL.DoBeforeStoreTrans` legt bei fehlender Default-Adresse automatisch eine neue Adresse an (`AddressBL.CreateNewAddressForCustomer`) bzw. markiert die erste vorhandene Adresse als Standard; analog wird bei fehlendem Standard-Ansprechpartner automatisch einer erzeugt (`ContactPersonBL.GetEmptyContactPersonForAddress`) oder der erste vorhandene als Standard markiert. Die I3D (Kundennummer) eines neuen Kunden wird, falls `<=0`, über `Session.GetGenericDAO<Customer>().GetMaxValue() + 1` vergeben.
|
||||
Aussage: Das System soll beim Anlegen eines Kunden automatisch eine gültige Mindeststruktur (genau eine Standardadresse mit genau einem Standard-Ansprechpartner) sowie eine fortlaufende Kundennummer sicherstellen.
|
||||
Ergebnis: Jeder gespeicherte Kunde besitzt danach mindestens eine Default-Adresse mit mindestens einem Default-Ansprechpartner und eine eindeutige numerische Kundennummer.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Customers/StoreCustomerBL.cs:53-106 (`DoBeforeStoreTrans`) - Begründung: Vollständige Auto-Vervollständigungslogik inkl. I3D-Vergabe (Zeile 61-64).
|
||||
Prüfidee: Kunde ohne Adressliste anlegen; DB-Zustand nach Speichern prüfen (Adresse + Ansprechpartner vorhanden, `DefaultCustomer=true`, `Default=true`).
|
||||
Konsolidierungshinweis: Ergänzt CRM-02.
|
||||
Status: belegt; Workaround (Kundennummernvergabe per `MAX(I3D)+1` ohne erkennbare Sperre/Transaktion gegen Race Conditions im gesichteten Code – HYPOTHESE bzgl. Nebenläufigkeitssicherheit, da keine expliziten Locks sichtbar sind)
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-07
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: Vertrieb, Buchhaltung
|
||||
Vorbedingung: Kunde wird für Folgeprozesse (Auftrag, Angebot, Rechnung) referenziert
|
||||
Fakt: `CustomerBL.IsCustomerActiveUnlocked(Customer)` definiert einen Kunden als "aktiv/entsperrt" genau dann, wenn `customer.State == 1 && !customer.Locked`; diese Prüfung wird u. a. in `GetActiveUnlockedCustomer` verwendet.
|
||||
Aussage: Das System soll einen Kunden als geschäftlich nutzbar (aktiv) nur dann behandeln, wenn sowohl der Status "aktiv" (`State=1`) gesetzt als auch keine Sperre (`Locked=false`) vorliegt.
|
||||
Ergebnis: Zwei unabhängige Felder (`State`, `Locked`) steuern gemeinsam die Nutzbarkeit eines Kunden im System.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Customers/CustomerBL.cs:382-391 (`IsCustomerActiveUnlocked`, `IsCustomerActiveAndNotLocked`) - Begründung: Zentrale Statuslogik.
|
||||
- [SEKUNDÄR] src/backend/Centron.BL/Sales/Customers/CustomerBL.cs:73-99, 182-196 (`SearchCustomerBySearchText`, `GetActiveCustomerCompact`) - Begründung: Kundensuche filtert konsistent auf `State==1 && !Locked`.
|
||||
Prüfidee: Kunden mit `State=1, Locked=true` und `State=0, Locked=false` anlegen und prüfen, dass beide in Standard-Kundensuchen nicht erscheinen.
|
||||
Konsolidierungshinweis: Grundlage für CRM-08 (Statusfeld-Bedeutung), CRM-19 (Dongle-Statusprüfung).
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-08
|
||||
Ebene: StRS
|
||||
Typ: Daten
|
||||
Akteur: Vertrieb, Buchhaltung
|
||||
Vorbedingung: -
|
||||
Fakt: Der Kundenstatus wird über zwei getrennte, unabhängig setzbare Attribute abgebildet: `State` (int, wirkt wie "aktiv/inaktiv", Vergleich `== 1`) und `Locked` (bool, "gesperrt"). Es existiert kein enumeriertes Statusmodell mit benannten Zuständen (z. B. "gelöscht", "archiviert", "Bonitätssperre") im gesichteten BL-Code.
|
||||
Aussage: Das System soll den Lebenszyklus-Status eines Kunden (aktiv/inaktiv, gesperrt/entsperrt) als eigenständiges fachliches Konzept abbilden, das im Zielsystem klar benannte, erweiterbare Zustände (z. B. Enum statt Rohint) unterstützt.
|
||||
Ergebnis: Migrationsrelevanter Fakt: Legacy-Datenmodell nutzt zwei binäre/int-Felder statt eines State-Machine-Modells.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/CustomerArea/CustomerBase.cs:15,30 (`State`, `Locked`) - Begründung: Felddefinition.
|
||||
- [KONTEXT] src/backend/Centron.Entities/Entities/Businesspartner/Supplier.cs:8-9 - Begründung: Lieferant besitzt nur `State`, kein `Locked`-Äquivalent – Asymmetrie zwischen Kunden- und Lieferanten-Stammdatenmodell.
|
||||
Prüfidee: Klärung mit Fachbereich, ob Lieferanten je gesperrt werden können und wie das aktuell (ohne `Locked`-Feld) gehandhabt wird.
|
||||
Konsolidierungshinweis: Bezug zu CRM-07.
|
||||
Status: HYPOTHESE (fehlende Information: ob Lieferanten-Sperre über anderes Feld/Modul realisiert wird – im gesichteten `Supplier`-Entity nicht vorhanden)
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-09
|
||||
Ebene: SwRS
|
||||
Typ: Schnittstelle / Daten
|
||||
Akteur: Vertrieb, IT-Administration
|
||||
Vorbedingung: Neuanlage eines Kunden
|
||||
Fakt: `CustomerBL.CreateCustomerDirectories` legt beim Neuanlegen eines Kunden automatisch eine feste Verzeichnisstruktur im Dokumentenmanagement an (u. a. Bestellungen, Angebote, Aufträge, Service, Lieferscheine, Abholscheine, Rechnungen, Helpdesk, Geräte, Verträge, Projekte, Aktivitäten, Mails, Gutschriften) plus konfigurierbare Zusatzverzeichnisse aus `CustomerDirectory`.
|
||||
Aussage: Das System soll bei Kundenanlage automatisch eine standardisierte, prozessbezogene Ablagestruktur im Dokumentenmanagement erzeugen.
|
||||
Ergebnis: Jeder neue Kunde erhält ~14 Standardverzeichnisse plus rekursive Zusatzverzeichnisse.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Customers/CustomerBL.cs:438-597 (`CreateCustomerDirectories`, `InsertSpecialCustomerDirectories`) - Begründung: Vollständige Verzeichnisliste und Rekursionslogik.
|
||||
Prüfidee: Neuen Kunden anlegen und Verzeichnisbaum im DMS-Modul auf Vollständigkeit prüfen.
|
||||
Konsolidierungshinweis: Relevant für spätere Cluster "Dokumentenmanagement" – hier nur als Kunden-Nebenwirkung erfasst.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-10
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: Personalabteilung
|
||||
Vorbedingung: Mitarbeiter-Stammdatensatz vorhanden
|
||||
Fakt: `EmployeeBL.GetEmployeeCompactValidationExpression<T>()` definiert einen Mitarbeiter als "aktiv" gemäß: `State == 1 AND (CommencementDate == null OR CommencementDate <= heute) AND (LeavingDate == null OR LeavingDate > heute OR LeavingDate <= 1900-01-01)`. Das Datum `1900-01-01` wird also als Sentinel-Wert für "kein Austrittsdatum gesetzt" interpretiert.
|
||||
Aussage: Das System soll einen Mitarbeiter automatisch anhand von Status, Eintritts- und Austrittsdatum als aktiv/inaktiv einstufen, ohne dass ein separates manuelles "Aktiv"-Flag gepflegt werden muss.
|
||||
Ergebnis: Aktivitätsstatus ergibt sich aus drei Feldern kombiniert; `1900-01-01` fungiert als technischer Nullwert-Ersatz für `LeavingDate`.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/EmployeeArea/EmployeeBL.cs:671-676 (`GetEmployeeCompactValidationExpression`) - Begründung: Exakte Formel der Aktiv-Berechnung.
|
||||
- [SEKUNDÄR] src/backend/Centron.Entities/Entities/EmployeeArea/EmployeeBase.cs:15-23 (`CommencementDate`, `LeavingDate`, `IsActive`) - Begründung: Zeigt, dass zusätzlich noch ein eigenständiges `IsActive`-Feld existiert, das parallel gepflegt werden kann (`GetAllInactiveEmployees` nutzt `IsActive==false` statt der Expression, Zeile 321-324).
|
||||
Prüfidee: Mitarbeiter mit `LeavingDate = 1899-01-01` bzw. `LeavingDate = null` anlegen und prüfen, ob beide als "aktiv" gelten (sofern `State=1`); Vergleich mit `IsActive`-Feld auf Inkonsistenzen prüfen.
|
||||
Konsolidierungshinweis: Zwei parallele Aktiv-Konzepte (`IsActive`-Flag vs. berechneter Ausdruck) – Klärungsbedarf für Zielsystem.
|
||||
Status: belegt; Workaround (Sentinel-Datum 1900-01-01 statt NULL-Semantik; zwei redundante Aktiv-Konzepte im Datenmodell)
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-11
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Personalabteilung
|
||||
Vorbedingung: Bearbeitung eines Mitarbeiter-Stammdatensatzes
|
||||
Fakt: `EmployeeBL.SaveOrUpdateEmployee` prüft vor jedem Speichern das Recht `UserRightsConst.Administration.EmployeeManagement.ADMINISTRATE_ALL_EMPLOYEES`; ohne dieses Recht wird der Aufruf mit "You do not have the necessary rights to perform this action." abgelehnt.
|
||||
Aussage: Das System soll das Anlegen und Ändern von Mitarbeiter-Stammdaten auf Benutzer mit dem Recht "Mitarbeiterverwaltung" beschränken.
|
||||
Ergebnis: Rechteprüfung vor jeder Mitarbeiter-Speicherung; Fehlermeldung bei fehlendem Recht.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/EmployeeArea/EmployeeBL.cs:128-131 (`SaveOrUpdateEmployee`) - Begründung: Explizite Rechteprüfung als erste Anweisung der Methode.
|
||||
Prüfidee: Benutzer ohne `ADMINISTRATE_ALL_EMPLOYEES` versuchen lassen, einen Mitarbeiter zu speichern; Fehlermeldung/-code prüfen.
|
||||
Konsolidierungshinweis: Analog CRM-12 (AppUser), CRM-13 (Kundenzugriff).
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-12
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit / Daten
|
||||
Akteur: Personalabteilung, IT-Administration
|
||||
Vorbedingung: Anlegen/Ändern eines Benutzerkontos (`AppUser`), das mit einem Mitarbeiter verknüpft ist
|
||||
Fakt: `AppUserBL.SaveOrUpdateAppUser` prüft das Recht `RIGHT_PERSONALMANAGEMENT`; verlangt bei Neuanlage einen bereits gespeicherten `Employee`; prüft die Eindeutigkeit des Login-Namens (`Name`, case-insensitive, getrimmt) unter allen `AppUser` UND zusätzlich gegen alle `WebAccount.Username` (kundengebundene Web-Zugänge); bei Kollision mit einem WebAccount wird der zugehörige Kunde in der Fehlermeldung genannt. Zusätzlich wird `OpenIdConnectSubjectIdentifier` global eindeutig geprüft.
|
||||
Aussage: Das System soll sicherstellen, dass ein Login-Name eines internen Benutzerkontos systemweit eindeutig ist – sowohl unter internen Benutzerkonten als auch gegenüber Web-Kundenzugängen – und dass eine externe SSO-Kennung (OpenID Connect Subject) global eindeutig bleibt.
|
||||
Ergebnis: Speichern schlägt fehl mit spezifischer Fehlermeldung, wenn Login-Name oder OIDC-Kennung bereits vergeben sind; Meldung nennt bei WebAccount-Kollision explizit Kundenname und -nummer.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/EmployeeArea/AppUserBL.cs:136-186 (`SaveOrUpdateAppUser`) - Begründung: Vollständige Validierungs-/Rechtekette inkl. Fehlermeldungstexte.
|
||||
Prüfidee: Zwei AppUser mit gleichem (Groß-/Kleinschreibung abweichendem) Login anlegen; AppUser-Login identisch zu bestehendem WebAccount-Username anlegen; Fehlermeldungen prüfen.
|
||||
Konsolidierungshinweis: Cross-Entity-Dublettenprüfung – relevant für spätere Cluster "Benutzer-/Rechteverwaltung" und "Web-Portal".
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-13
|
||||
Ebene: SyRS
|
||||
Typ: funktional / Daten
|
||||
Akteur: IT-Administration, Personalabteilung
|
||||
Vorbedingung: Ermittlung aktiver interner Benutzer
|
||||
Fakt: `AppUserBL.GetActiveAppUsers` definiert einen aktiven `AppUser` über eine Kombination aus `IsAccountDisabled == false`, einem Zeitfenster-Check auf `AccountDisabledFromDate`/`AccountDisabledToDate` (Konto kann zeitlich befristet deaktiviert sein) UND zusätzlich `Employee.IsActive == true`.
|
||||
Aussage: Das System soll ein Benutzerkonto nur dann als aktiv betrachten, wenn weder eine permanente noch eine zeitlich befristete Kontosperre vorliegt und der zugehörige Mitarbeiter als aktiv geführt wird.
|
||||
Ergebnis: Aktivstatus eines Logins hängt von drei Feldern des `AppUser` plus dem Aktivstatus des verknüpften `Employee` ab.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/EmployeeArea/AppUserBL.cs:38-55 (`GetActiveAppUsers`) - Begründung: Komplexe, mehrteilige Bedingung im Code sichtbar.
|
||||
Prüfidee: AppUser mit `AccountDisabledFromDate` in der Zukunft anlegen und prüfen, ob er aktuell noch als aktiv gilt (erwartet: ja, da Sperre erst ab Datum wirkt).
|
||||
Konsolidierungshinweis: Ergänzt CRM-10 (Mitarbeiter-Aktivstatus), da AppUser-Aktivstatus vom Employee-Aktivstatus abhängt, aber NICHT dieselbe Formel wie `GetEmployeeCompactValidationExpression` nutzt (Inkonsistenz).
|
||||
Status: belegt; Workaround (zwei unterschiedliche "Mitarbeiter aktiv"-Kriterien im Code: `EmployeeBL.GetEmployeeCompactValidationExpression` vs. hier direktes `Employee.IsActive` – mögliche Dateninkonsistenz)
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-14
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Vertrieb
|
||||
Vorbedingung: Kundensuche/-anzeige
|
||||
Fakt: `CustomerBL.HasUserReadCustomersRight` prüft das Recht `UserRightsConst.Sales.Customer.CustomerCommon.SEARCH_CUSTOMER`; `SearchCustomerBL.SearchCustomerBySearchTextWithPaging` prüft zusätzlich das (offenbar ältere/parallele) Recht `UserRightsConst.RIGHT_KUNDENSTAMM`.
|
||||
Aussage: Das System soll den lesenden Zugriff auf Kundenstammdaten an ein dediziertes Benutzerrecht koppeln.
|
||||
Ergebnis: Kundensuche/-liste liefert bei fehlendem Recht einen Fehler bzw. eine leere/verweigerte Antwort.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Customers/CustomerBL.cs:234-240 (`HasUserReadCustomersRight`) - Begründung: Rechteprüfung `SEARCH_CUSTOMER`.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Customers/SearchCustomerBL.cs:113-121 (`SearchCustomerBySearchTextWithPaging`) - Begründung: Zweites, abweichendes Recht `RIGHT_KUNDENSTAMM`.
|
||||
Prüfidee: Benutzer mit nur einem der beiden Rechte gegen beide Endpunkte testen, um Inkonsistenz zu bestätigen.
|
||||
Konsolidierungshinweis: Möglicher technischer Schulden-Befund: zwei unterschiedliche Rechte für denselben fachlichen Vorgang (Kunden lesen/suchen).
|
||||
Status: HYPOTHESE (fehlende Information: ob `RIGHT_KUNDENSTAMM` und `SEARCH_CUSTOMER` fachlich bewusst unterschiedliche Berechtigungsstufen abbilden oder ein historisches Duplikat sind)
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-15
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: Buchhaltung
|
||||
Vorbedingung: Kunde mit Umsatzsteuer-relevanten Daten
|
||||
Fakt: Die Umsatzsteuer-Identifikationsnummer wird redundant an zwei Stellen geführt: pro Adresse als `Address.AdressSalesTaxIdentificationNumber` und separat auf Kundenebene als `CustomerFinanceInfo.SalesTaxIdentificationNumber`; zusätzlich existiert `Customer.VATNotActive` (bool) sowie identisch benannt `CustomerFinanceInfo.VATNotActive`. Ein Format-/Prüfsummen-Check (z. B. gegen EU-USt-IdNr.-Schema) wurde im BL-Code nicht gefunden.
|
||||
Aussage: Das System soll die Umsatzsteuer-Identifikationsnummer als eindeutiges, konsistentes Attribut je Geschäftspartner führen und deren Format serverseitig validieren (kein Duplikat auf Adress- und Kundenebene).
|
||||
Ergebnis: Migrationsrelevanter Datenmodell-Befund: redundante/uneindeutige Führung der USt-IdNr., keine Formatprüfung serverseitig.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/CustomerArea/Address.cs:30 (`AdressSalesTaxIdentificationNumber`) - Begründung: Feld auf Adressebene.
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/Sales/Customers/CustomerFinanceInfo.cs:9,11 (`SalesTaxIdentificationNumber`, `VATNotActive`) - Begründung: Zweites, konkurrierendes Feld auf Kundenebene.
|
||||
- [KONTEXT] src/backend/Centron.Entities/Entities/CustomerArea/Customer.cs:131 (`VATNotActive`) - Begründung: Drittes Feld gleichen Namens direkt auf `Customer`.
|
||||
Prüfidee: Prüfen, welches der Felder tatsächlich in Rechnungsstellung/EDI (z. B. ZUGFeRD) verwendet wird; Format-Grep in Validierungs-/Regex-Bibliotheken.
|
||||
Konsolidierungshinweis: Wichtig für SwRS-Feindefinition bei Neuimplementierung (Single Source of Truth für USt-IdNr.).
|
||||
Status: HYPOTHESE (fehlende Information: welches Feld führend ist und ob eine Formatvalidierung an anderer Stelle – z. B. UI-Layer, hier nicht vollständig durchsucht – existiert)
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-16
|
||||
Ebene: SyRS
|
||||
Typ: nicht-funktional / Daten
|
||||
Akteur: Buchhaltung
|
||||
Vorbedingung: Erfassung von Bankverbindungen am Kunden
|
||||
Fakt: `Customer` führt zwei vollständige, redundant modellierte Bankverbindungssätze direkt als Entity-Felder (`BankIBAN`, `BankSWIFT`, `BankCountry`, `BankCity`, `BankStreet` sowie `Bank02`/`BankCode02`/`BankAccountNumber02`/`BankIBAN02`/`BankSWIFT02`/`BankCountry02`/`BankCity02`/`BankStreet02`) statt einer normalisierten 1:n-Beziehung zu Bankkonten.
|
||||
Aussage: Das System soll Bankverbindungen eines Kunden als normalisierte, beliebig erweiterbare Liste (nicht als fest verdrahtete Feldpaare "01"/"02") modellieren.
|
||||
Ergebnis: Datenmodell begrenzt einen Kunden technisch auf maximal zwei Bankverbindungen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/CustomerArea/Customer.cs:134-146 - Begründung: Zeigt die verdoppelten Feldsätze `Bank...`/`Bank...02`.
|
||||
Prüfidee: Fachbereich befragen, ob mehr als zwei Bankverbindungen je Kunde jemals benötigt wurden (z. B. bei Konzernkunden/Sammelkonten).
|
||||
Konsolidierungshinweis: Migrationsrelevanter Datenmodell-Befund für Zielarchitektur.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-17
|
||||
Ebene: SwRS
|
||||
Typ: nicht-funktional / Sicherheit
|
||||
Akteur: Buchhaltung, Vertrieb
|
||||
Vorbedingung: Erfassung/Änderung der Bankverbindung eines Kunden in der WPF-Oberfläche
|
||||
Fakt: Die IBAN-Prüfsummenvalidierung (Modulo-97-Verfahren nach ISO 7064) ist ausschließlich im WPF-Client implementiert (`IbanValidation.IbanChecksumCheck`) und wird konkret im Bankdaten-Formular des Kunden (`CrmFinanceView.xaml.cs`, Fehlertext "Keine gültige IBAN") aufgerufen. Im Backend (`Centron.BL`) wurde keine entsprechende Prüfung gefunden (weder in `StoreCustomerBL` noch in `BankAccountBL`).
|
||||
Aussage: Das System soll die Prüfsummenvalidität einer IBAN serverseitig (nicht nur clientseitig) vor dem Persistieren erzwingen.
|
||||
Ergebnis: Eine über einen anderen Kanal (z. B. API, Import, zukünftiges Web-Frontend) gespeicherte, prüfsummenungültige IBAN wird vom Backend nicht abgelehnt.
|
||||
Belege:
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/Modules/Finances/Crm/Finance/CrmFinanceView.xaml.cs:30-39 - Begründung: Aufruf der Validierung nur im UI-Eventhandler.
|
||||
- [PRIMÄR] src/centron/Centron.WPF.UI/Modules/DataExchange/DataImport/AccountImport/IbanValidation.cs:10-35 (`IbanChecksumCheck`) - Begründung: Implementierung des Mod-97-Verfahrens, referenziert externe Quelle "dotnet-snippets.de".
|
||||
- [SEKUNDÄR] src/backend/Centron.BL/Sales/Customers/StoreCustomerBL.cs:39-51 - Begründung: Zeigt, dass die serverseitige Validierung IBAN nicht prüft (Negativbeleg).
|
||||
Prüfidee: IBAN mit falscher Prüfsumme über eine Web-Service-/API-Schnittstelle (unter Umgehung der WPF-Oberfläche) speichern und prüfen, ob das Backend dies zulässt.
|
||||
Konsolidierungshinweis: Ergänzt CRM-15/CRM-16 (Bankdaten-Qualität); zentrale Erkenntnis für SyRS "serverseitige Validierung erforderlich".
|
||||
Status: belegt; Workaround (Validierung nur clientseitig vorhanden – Lücke bei Neuimplementierung als Web-/SaaS-System zu schließen, da UI-Client dort nicht die einzige Eingabequelle ist)
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-18
|
||||
Ebene: StRS
|
||||
Typ: Sicherheit / Compliance
|
||||
Akteur: Buchhaltung, Vertrieb, Datenschutzbeauftragter
|
||||
Vorbedingung: Löschantrag zu einer Kontaktperson (DSGVO/Art. 17 DSGVO)
|
||||
Fakt: `DataSecurityBL` implementiert eine "DSGVO löschen"-Funktion für `ContactPerson`: personenbezogene Felder (Geburtsdatum, Beruf, Telefon 1-5, Fax 1-2, E-Mail 1-2, Mailing-Flags, Kommentarfelder, Abteilung, Bild, Active-Directory-SID, Website, Web-Zugangsdaten) werden geleert bzw. mit dem Platzhaltertext "DSGVO: Auf Anfrage gelöscht. (Durchgeführt von {ShortSign} am {Datum} um {Uhrzeit} Uhr)" überschrieben; jeder gelöschte Wert wird vor dem Löschen in ein Lösch-Protokoll (`deleteProtocol`) geschrieben; die Kontaktperson erhält `IsDsgvoDeleted=true`, `DsgvoDeletedEmployeeI3D`, `DsgvoDeletedDate` und wird (außer bei `Standard`-Kontakt) deaktiviert (`Status=0`).
|
||||
Aussage: Das System soll auf Anfrage die personenbezogenen Daten einer Kontaktperson DSGVO-konform anonymisieren, den Vorgang inkl. verantwortlichem Mitarbeiter und Zeitpunkt nachvollziehbar protokollieren und die vorherigen Werte für Nachweiszwecke in einem Löschprotokoll festhalten.
|
||||
Ergebnis: Kontaktperson ist nach Ausführung anonymisiert, als DSGVO-gelöscht markiert und (i. d. R.) deaktiviert; ein Audit-Trail bleibt erhalten.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/DataSecurity/DataSecurityBL.cs:1152-1276 - Begründung: Vollständige Feld-für-Feld-Anonymisierungslogik inkl. Protokollierung und Statusmarkierung.
|
||||
- [SEKUNDÄR] src/backend/Centron.BL/Administration/DataSecurity/DataSecurityBL.cs:26-27 - Begründung: Konstanten für den Lösch-Kommentartext.
|
||||
Prüfidee: DSGVO-Löschung einer Testkontaktperson auslösen; prüfen, dass alle genannten Felder geleert sind, `IsDsgvoDeleted=true` gesetzt ist und ein lesbares Protokoll erzeugt wird.
|
||||
Konsolidierungshinweis: Ergänzt CRM-19 (fehlende Kunden-Löschung), CRM-20 (Retentions-Statistiken).
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-19
|
||||
Ebene: SwRS
|
||||
Typ: Compliance
|
||||
Akteur: Datenschutzbeauftragter, Buchhaltung
|
||||
Vorbedingung: DSGVO-Löschantrag bezieht sich auf einen gesamten Kunden (nicht nur eine Kontaktperson)
|
||||
Fakt: Die Methode `DataSecurityBL.DoDeleteCustomer(int i3d, bool isReferenceDelete)` ist im Quellcode vorhanden, wirft aber unbedingt `throw new NotImplementedException("DoDeleteCustomer is not ready for use!")`. Der zugehörige Aufrufcode ist zudem auskommentiert (`// DoDeleteCustomer(...)`).
|
||||
Aussage: Das System soll eine vollständige, DSGVO-konforme Löschung/Anonymisierung auf Kundenebene (nicht nur auf Ebene einzelner Kontaktpersonen) bereitstellen.
|
||||
Ergebnis: Im Ist-System existiert aktuell keine produktiv nutzbare Funktion zur Löschung eines kompletten Kundendatensatzes im Rahmen der DSGVO-Bereinigung.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/DataSecurity/DataSecurityBL.cs:856-858 (`DoDeleteCustomer`) - Begründung: Explizite `NotImplementedException`.
|
||||
- [SEKUNDÄR] src/backend/Centron.BL/Administration/DataSecurity/DataSecurityBL.cs:803 - Begründung: Auskommentierter Aufruf bestätigt, dass die Funktion nicht im aktiven Ablauf verwendet wird.
|
||||
Prüfidee: Im laufenden System versuchen, eine kundenbezogene DSGVO-Löschung auszuführen, und den resultierenden Fehler dokumentieren.
|
||||
Konsolidierungshinweis: Wichtige Lücke für StRS-Anforderung "vollständige Umsetzung des Rechts auf Löschung"; ergänzt CRM-18.
|
||||
Status: belegt; Workaround (Funktion bewusst deaktiviert/nicht fertiggestellt)
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-20
|
||||
Ebene: StRS
|
||||
Typ: Compliance / Sicherheit
|
||||
Akteur: Datenschutzbeauftragter
|
||||
Vorbedingung: Durchführung einer DSGVO-Datenbereinigung
|
||||
Fakt: `DataSecurityBL.GetDataSecurityCleanUpStats` liefert Statistiken zu löschrelevanten Datenbeständen (Kunden mit letzter Aktion älter als Datum X, bereits gelöschte Kunden, CRM-Aktivitäten älter als Datum X, Belege [Angebote/Aufträge/Lieferscheine/Abholscheine/Rechnungen/Gutschriften] älter als Datum X, mit Filter nach Kundenart/Objektart/Abschlussstatus). Zugriff ist an das Recht `UserRightsConst.DsgvoModule.ACCESS_CLEANUP_DATABASE` UND ein Feature-Flag `ModuleFeatures.IsDsgvoDatabaseCleanupAvailable` gekoppelt.
|
||||
Aussage: Das System soll autorisierten Benutzern eine Übersicht über lösch-/archivierungsrelevante Alt-Datenbestände (Kunden, CRM-Aktivitäten, Belege) auf Basis konfigurierbarer Aufbewahrungsfristen bereitstellen, bevor eine Bereinigung ausgeführt wird.
|
||||
Ergebnis: Statistik-Report vor Ausführung der eigentlichen Löschung; feature-geflaggt und rechtebeschränkt.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/DataSecurity/DataSecurityBL.cs:34-62 (`GetDataSecurityCleanUpStats`) - Begründung: Zeigt Filter- und Rechtekombination.
|
||||
- [SEKUNDÄR] src/backend/Centron.BL/Administration/DataSecurity/DataSecurityBL.cs:64-70 (`DataSecurityExecuteCleanUp`) - Begründung: Ausführungsmethode ist rechtegeschützt, der eigentliche Bereinigungsvorgang liefert im gesichteten Ausschnitt nur `Result.AsSuccess()` ohne sichtbare Löschlogik an dieser Stelle (weitere Implementierung evtl. in nicht gelesenen Codeteilen der 1900-Zeilen-Datei).
|
||||
Prüfidee: Statistikabruf mit und ohne Recht `ACCESS_CLEANUP_DATABASE` testen; Feature-Flag deaktivieren und Verhalten prüfen.
|
||||
Konsolidierungshinweis: Ergänzt CRM-18/CRM-19.
|
||||
Status: belegt (Ausführungslogik nur teilweise gesichtet – Datei hat 1900 Zeilen, nicht vollständig gelesen)
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-21
|
||||
Ebene: SwRS
|
||||
Typ: Daten / funktional
|
||||
Akteur: Vertrieb
|
||||
Vorbedingung: Kunde besitzt eine "Kundenherkunft" (`CustomerAncestry`, z. B. Konzernzugehörigkeit/Quelle)
|
||||
Fakt: `CustomerAncestryBL.DeleteCustomerAncestry` verhindert das Löschen eines `CustomerAncestry`-Datensatzes, solange mindestens ein `Customer` mit `CustomerOriginI3D` darauf verweist (`Count`-Prüfung vor `Delete`), und liefert sonst die (englischsprachige) Fehlermeldung "Couldn´t be deleted, because the ancestry is used by customers".
|
||||
Aussage: Das System soll referenzierte Stammdaten-Klassifikationswerte (hier: Kundenherkunft) erst dann zur Löschung zulassen, wenn keine Kunden mehr darauf verweisen.
|
||||
Ergebnis: Referentielle Integrität wird anwendungsseitig (nicht per DB-Fremdschlüssel-Exception) sichergestellt.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Customers/CustomerDetails/CustomerAncestryBL.cs:33-43 (`DeleteCustomerAncestry`) - Begründung: Zeigt Zähl-Check und Fehlermeldung.
|
||||
Prüfidee: Kundenherkunft löschen, die noch von einem Kunden referenziert wird; Fehlermeldung/-verhalten dokumentieren; feststellen, ob Fehlermeldung an Endnutzer tatsächlich englischsprachig ausgegeben wird (i18n-Lücke).
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-22
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: Vertrieb (Helpdesk/Support)
|
||||
Vorbedingung: Eingehende E-Mail soll automatisch einem Kunden/Ansprechpartner zugeordnet werden
|
||||
Fakt: `ContactPersonBL.SearchAddressContactByEmailAddress` sucht Kontaktpersonen anhand der Absender-E-Mail über eine benannte Query (`SearchAddressContactByEmailAddress`) mit mehreren Prioritätsstufen (exakte E-Mail, Domain, Domain+Web, Domain+TLD). Das Verhalten wird über `WorkflowSetting` gesteuert: `IsCustomerDetectionOverEMailDomainActive` schaltet die Domain-basierte Erkennung ein/aus; `CustomerDetectionOverContactEMail1`/`CustomerDetectionOverContactEMail2` steuern, ob E-Mail-Feld 1 bzw. 2 der Kontaktperson für die Zuordnung herangezogen wird; zusätzlich wird die Domain gegen eine Blacklist (`DomainBlacklistBL.IsBlacklisted`, z. B. generische Provider wie gmail.com) geprüft, bevor eine Domain-Zuordnung erfolgt.
|
||||
Aussage: Das System soll eingehende Kommunikation (z. B. Helpdesk-Mails) automatisch anhand konfigurierbarer Regeln (exakte Kontakt-E-Mail, Domain-Zugehörigkeit, Blacklist generischer Domains) einem Kunden bzw. einer Kontaktperson zuordnen können.
|
||||
Ergebnis: Priorisierte, konfigurierbare automatische Kunden-/Kontakterkennung über E-Mail.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Customers/ContactPersonBL.cs:310-411 (`SearchAddressContactByEmailAddress`, `FilterSearchAddressContactResults`) - Begründung: Zeigt vollständige Priorisierungs- und Konfigurationslogik.
|
||||
Prüfidee: Test-Mail von bekannter Domain mit und ohne aktivierte Domain-Erkennung senden; Blacklist-Domain (z. B. gmail.com) testen und prüfen, dass keine Domain-Zuordnung erfolgt.
|
||||
Konsolidierungshinweis: Schnittstellen-relevant für Cluster "Helpdesk/Ticketing" – hier nur aus CRM-Sicht (Kontaktzuordnung) erfasst.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-23
|
||||
Ebene: SwRS
|
||||
Typ: Daten / Sicherheit
|
||||
Akteur: Personalabteilung, IT-Administration
|
||||
Vorbedingung: Mitarbeiter erhält RFID-Token (z. B. für Zeiterfassung/Zutrittskontrolle)
|
||||
Fakt: `EmployeeRfidTokenBL.SaveOrUpdateEmployeeRfidTokens` speichert `EmployeeRfidToken`-Datensätze mit AES/Master-Key-verschlüsseltem `RfidTokenEncrypted`-Wert (`CentronConfigurationDbBL.EncryptWithMasterKey`), prüft dabei aber weder auf Ebene der Methode noch erkennbar per DB-Constraint, ob derselbe Token bereits einem anderen Mitarbeiter zugeordnet ist oder ob ein Mitarbeiter bereits einen Token besitzt.
|
||||
Aussage: Das System soll sicherstellen, dass ein RFID-Token eindeutig genau einem aktiven Mitarbeiter zugeordnet ist, um Fehlzuordnungen bei Zeiterfassung/Zutritt zu verhindern.
|
||||
Ergebnis: Ohne zusätzliche DB-Constraints besteht das Risiko doppelt vergebener Tokens.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/EmployeeArea/EmployeeRfidTokenBL.cs:39-57 (`SaveOrUpdateEmployeeRfidTokens`) - Begründung: Keine Duplikatsprüfung im Methodenkörper sichtbar (nur `Guard.NotNull`).
|
||||
Prüfidee: Zwei `EmployeeRfidToken`-Datensätze mit identischem entschlüsseltem Tokenwert für unterschiedliche Mitarbeiter anlegen und prüfen, ob dies zugelassen wird.
|
||||
Konsolidierungshinweis: -
|
||||
Status: HYPOTHESE (fehlende Information: ob Eindeutigkeit ggf. per DB-Unique-Index auf `RfidTokenEncrypted` sichergestellt ist – DAO/Mapping-Definitionen wurden für dieses Cluster nicht vollständig durchsucht)
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-24
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: Vertrieb
|
||||
Vorbedingung: Länderstammdaten für Adressen/Kunden
|
||||
Fakt: `CountryBL.GetDefaultCountry()`/`GetDefaultCountryI3D()` ermitteln genau ein Land mit `Default == true` (`.First()` bei der I3D-Variante, was bei keinem gesetzten Default-Land eine Exception auslösen würde); `GetInlandCountry` leitet das "Inland" hingegen aus `MandatorBL.GetDefaultMandator().Country` ab, mit explizitem TODO-Kommentar "TODO: Check the country of the branch for the current user...", d. h. eine niederlassungsspezifische (Branch-)Länderzuordnung ist noch nicht implementiert.
|
||||
Aussage: Das System soll für jede Adresse automatisch ein Vorgabeland setzen (Neuanlage), abgeleitet aus dem für den Benutzer/die Niederlassung gültigen Mandanten- bzw. Niederlassungsland.
|
||||
Ergebnis: Aktuell wird global das Mandanten-Standardland verwendet, unabhängig von der Niederlassung des angemeldeten Benutzers.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/CountryArea/CountryBL.cs:190-207 (`GetInlandCountry`, `GetDefaultCountryI3D`, `GetDefaultCountry`) - Begründung: Zeigt Implementierung und offenes TODO.
|
||||
- [SEKUNDÄR] src/backend/Centron.BL/Sales/Customers/Addresses/AddressBL.cs:46-51,248-249 - Begründung: `GetInlandCountry`/`GetDefaultCountry` werden beim Anlegen neuer Adressen als Default gesetzt.
|
||||
Prüfidee: Benutzer einer Niederlassung mit abweichendem Land eine neue Kundenadresse anlegen lassen und beobachten, welches Land vorbelegt wird.
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt; Workaround (TODO im Code bestätigt unvollständige Niederlassungs-Länderzuordnung)
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-25
|
||||
Ebene: SwRS
|
||||
Typ: funktional
|
||||
Akteur: Vertrieb
|
||||
Vorbedingung: Kunde besitzt Vertriebsbetreuer
|
||||
Fakt: `CustomerBase` besitzt sechs Betreuer-Referenzen `Adviser1I3D`…`Adviser6I3D`, von denen die ersten vier im Code kommentiert sind als "Innendienst" (Adviser1), "Aussendienst" (Adviser2), "Techniker 1" (Adviser3), "Techniker 2" (Adviser4); `SearchCustomerBL.GetCustomerFromEmployeeExpression` nutzt genau diese vier Felder, um Kunden eines Mitarbeiters zu ermitteln (Adviser5/6 werden dort nicht berücksichtigt).
|
||||
Aussage: Das System soll einem Kunden mehrere Betreuerrollen (u. a. Innendienst, Außendienst, Techniker) mit je einem zuständigen Mitarbeiter zuordnen können und Mitarbeitern ihre zugeordneten Kunden anzeigen.
|
||||
Ergebnis: Vier feste Betreuerrollen sind fachlich benannt und in der Kundensuche nach Mitarbeiter aktiv genutzt; zwei weitere Felder (`Adviser5/6I3D`) sind im Modell vorhanden, aber ohne erkennbare fachliche Bezeichnung/Verwendung in den gesichteten Dateien.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/CustomerArea/CustomerBase.cs:19-24 - Begründung: Kommentare benennen die Rollen.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Sales/Customers/SearchCustomerBL.cs:82-90 (`GetCustomerFromEmployeeExpression`) - Begründung: Nutzung von Adviser1-4, Auslassung von Adviser5/6.
|
||||
Prüfidee: UI-Bezeichnungen der Felder Adviser5/Adviser6 im WPF-Client (nicht Teil dieses Clusters) abgleichen, um deren fachliche Bedeutung zu klären.
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt (Rollen 1-4); HYPOTHESE bzgl. Adviser5/6 (fehlende Information zur fachlichen Bezeichnung)
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-26
|
||||
Ebene: SwRS
|
||||
Typ: Daten
|
||||
Akteur: Vertrieb
|
||||
Vorbedingung: Kunde benötigt Bestellnummer-Pflicht bei Auftragserfassung
|
||||
Fakt: `Customer.PurchaseOrderNumberRequiered` (bool) ist ein pro Kunde konfigurierbares Flag; ebenso `Customer.ProjNrNeeded` (Projektnummer-Pflicht) und `Customer.ProductionConfigurationRequiring`.
|
||||
Aussage: Das System soll pro Kunde konfigurierbar erzwingen können, dass bei der Auftrags-/Belegerfassung bestimmte Zusatzangaben (Bestellnummer des Kunden, Projektnummer, Produktionskonfiguration) verpflichtend sind.
|
||||
Ergebnis: Kundenindividuelle Pflichtfeld-Schalter, die vermutlich in nachgelagerten Modulen (Auftragserfassung) ausgewertet werden (dort nicht verifiziert, da außerhalb des Clusters).
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.Entities/Entities/CustomerArea/Customer.cs:48 (`PurchaseOrderNumberRequiered`) - Begründung: Feld inkl. auffälligem Schreibfehler im Bezeichner ("Requiered" statt "Required").
|
||||
- [KONTEXT] src/backend/Centron.Entities/Entities/CustomerArea/Customer.cs:208,235-236 (`ProjNrNeeded`, `ProductionConfigurationRequiring`, `PrintProductionConfiguration`) - Begründung: Weitere kundenindividuelle Pflicht-/Steuerflags.
|
||||
Prüfidee: Auftrag für Kunden mit `PurchaseOrderNumberRequiered=true` ohne Bestellnummer anlegen (im Auftragsmodul, nicht Teil dieses Clusters) und Systemverhalten prüfen.
|
||||
Konsolidierungshinweis: Für Cluster "Vertrieb/Auftragsabwicklung" ggf. gegenzuprüfen, wo diese Flags ausgewertet werden.
|
||||
Status: belegt (Feldexistenz); HYPOTHESE bzgl. Durchsetzung außerhalb dieses Clusters nicht verifiziert
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-27
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: Buchhaltung, Vertrieb
|
||||
Vorbedingung: Lieferant/Kontaktperson mit E-Mail-Adresse
|
||||
Fakt: `SearchSupplierBL.SearchSupplierByEmail` sucht zunächst Lieferanten mit exakt passender `Supplier.Email`; findet sie keine, sucht sie aktive `ContactPerson` mit passender `Email1`/`Email2`, deren Adresse `DefaultCreditor = true` markiert ist, und leitet daraus den zugehörigen Lieferanten ab.
|
||||
Aussage: Das System soll einen Lieferanten sowohl über eine direkt hinterlegte Firmen-E-Mail als auch über die E-Mail-Adresse des Standard-Ansprechpartners (an der als Standard-Kreditor markierten Adresse) auffindbar machen.
|
||||
Ergebnis: Zweistufige Fallback-Suche für Lieferantenidentifikation per E-Mail.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/BusinessPartner/SearchSupplierBL.cs:84-121 (`SearchSupplierByEmail`) - Begründung: Zeigt zweistufige Suchlogik inkl. `DefaultCreditor`-Filter.
|
||||
Prüfidee: Lieferant ohne eigene E-Mail, aber mit Standard-Ansprechpartner-E-Mail anlegen; Suche nach dieser E-Mail testen.
|
||||
Konsolidierungshinweis: Analog zu CRM-22 (Kunden-/Kontakterkennung per E-Mail), hier für Lieferanten.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat CRM-28
|
||||
Ebene: StRS
|
||||
Typ: nicht-funktional (Datenqualität)
|
||||
Akteur: Vertrieb, Buchhaltung
|
||||
Vorbedingung: Anlage/Pflege von Kunden- und Lieferanten-Stammdaten über die Zeit
|
||||
Fakt: Im gesamten gesichteten `Centron.BL`-Code (Customer-, Address-, ContactPerson-, Supplier-Bereich) wurde keine Dubletten-Erkennung (z. B. Ähnlichkeitssuche über Name/Adresse/USt-IdNr.) und keine Merge-Funktion für zwei Geschäftspartner-Datensätze gefunden; die einzige Unterstützung ist die Freitext-Suche nach Matchcode/Name/I3D vor manueller Neuanlage (`SearchCustomerBL`, `SearchCustomerBySearchText`).
|
||||
Aussage: Das System soll Vertriebs- und Buchhaltungsmitarbeiter bei der Neuanlage von Geschäftspartnern durch eine aktive Dubletten-Prüfung (z. B. Ähnlichkeitssuche) unterstützen und eine Funktion zum Zusammenführen (Merge) versehentlich doppelt angelegter Datensätze bereitstellen.
|
||||
Ergebnis: Fehlende Funktionalität im Ist-System; Dublettenvermeidung liegt vollständig in der manuellen Sorgfalt des Sachbearbeiters.
|
||||
Belege:
|
||||
- [KONTEXT] src/backend/Centron.BL/Sales/Customers/CustomerBL.cs:73-99 (`SearchCustomerBySearchText`) - Begründung: Zeigt, dass nur eine einfache Textsuche als Vorab-Prüfung existiert.
|
||||
- [KONTEXT] Negativbefund aus gezielter Suche (`grep -rniE "dublette|duplicate|merge"` über `Sales/Customers`, `EmployeeArea`, `CountryArea`, `BusinessPartner`) - Begründung: Keine Treffer zu fachlicher Dubletten-/Merge-Logik für Geschäftspartner (nur technische Login-Duplikatsprüfungen, siehe CRM-12).
|
||||
Prüfidee: Fachbereich befragen, ob Dublettenbereinigung ggf. über ein separates, hier nicht durchsuchtes Modul (z. B. externes Datenqualitäts-Tool) erfolgt, das nicht Teil von `Centron.BL` ist.
|
||||
Konsolidierungshinweis: Zentrale StRS-Anforderung für die Web-/SaaS-Neuimplementierung; unabhängig von CRM-12 (dort nur technische Login-Namen-Eindeutigkeit, keine fachliche Geschäftspartner-Dublette).
|
||||
Status: HYPOTHESE (fehlende Information: Negativbefund – Abwesenheit von Funktionalität kann nicht abschließend über Quellcode-Grep bewiesen werden, ggf. existiert Logik in einem nicht durchsuchten Modul oder als externes Tool)
|
||||
|
||||
---
|
||||
|
||||
## Abdeckung
|
||||
|
||||
**Gelesen (vollständig oder in relevanten Ausschnitten):**
|
||||
- `src/backend/Centron.BL/Sales/Customers/CustomerBL.cs` (komplett, 653 Zeilen)
|
||||
- `src/backend/Centron.BL/Sales/Customers/StoreCustomerBL.cs` (komplett, 135 Zeilen)
|
||||
- `src/backend/Centron.BL/Sales/Customers/Addresses/AddressBL.cs` (komplett, 309 Zeilen)
|
||||
- `src/backend/Centron.BL/Sales/Customers/ContactPersonBL.cs` (komplett, 518 Zeilen)
|
||||
- `src/backend/Centron.BL/Sales/Customers/SearchCustomerBL.cs` (Ausschnitt, erste 150 von 509 Zeilen)
|
||||
- `src/backend/Centron.BL/Sales/Customers/CustomerDetails/CustomerAncestryBL.cs` (komplett, 45 Zeilen)
|
||||
- `src/backend/Centron.BL/EmployeeArea/EmployeeBL.cs` (Ausschnitte: Zeilen 1-250, 316-345, 460-480, 640-690)
|
||||
- `src/backend/Centron.BL/EmployeeArea/AppUserBL.cs` (komplett, 252 Zeilen)
|
||||
- `src/backend/Centron.BL/EmployeeArea/EmployeeRfidTokenBL.cs` (komplett, 91 Zeilen)
|
||||
- `src/backend/Centron.BL/CountryArea/CountryBL.cs` (komplett, 219 Zeilen)
|
||||
- `src/backend/Centron.BL/BusinessPartner/SearchSupplierBL.cs` (Ausschnitt, erste 120 Zeilen)
|
||||
- `src/backend/Centron.BL/Administration/DataSecurity/DataSecurityBL.cs` (Ausschnitte: Zeilen 1-150, 1150-1300, plus Grep über Gesamtdatei; Datei hat 1900 Zeilen, nicht vollständig gelesen)
|
||||
- `src/backend/Centron.Entities/Entities/CustomerArea/Customer.cs`, `CustomerBase.cs`, `Address.cs` (komplett)
|
||||
- `src/backend/Centron.Entities/Entities/EmployeeArea/EmployeeBase.cs` (komplett)
|
||||
- `src/backend/Centron.Entities/Entities/Businesspartner/Supplier.cs` (komplett, 44 Zeilen)
|
||||
- `src/backend/Centron.Entities/Entities/Sales/Customers/CustomerFinanceInfo.cs` (komplett)
|
||||
- `src/centron/Centron.WPF.UI/Modules/DataExchange/DataImport/AccountImport/IbanValidation.cs` (komplett)
|
||||
- `src/centron/Centron.WPF.UI/Modules/Finances/Crm/Finance/CrmFinanceView.xaml.cs` (Ausschnitt, IBAN-Validierungshandler)
|
||||
|
||||
**Ausgelassen / nicht vertieft (bekannte Lücken):**
|
||||
- `Centron.BL/CustomerArea/*` (BusinessLineBL, ContactActivityBL, ContactDepartmentBL, InterestBL, ProductBL, RmaBL, RmaSendKindBL) – nur Dateiliste erfasst, Inhalte nicht gelesen.
|
||||
- `Centron.BL/Sales/Customers/CRM/*` (CustomerActivityBL, CustomerActivityStatisticBL, CustomerCRMStatisticBL), `CrmProjects/CrmProjectBL.cs`, `Contacts/ContactSalutationBL.cs`, `SalutationBL.cs`, `CustomerSettingBL.cs`, `TextBlock/BusinessTextBlockBL.cs`, `CustomerDetails/SalesAreaBL.cs`, `Addresses/AddressSpecialArticleBL.cs`, `ContactExt.cs`, `CustomerExt.cs` – nicht gelesen; potenziell weitere CRM-Aktivitäten-/Klassifikationsregeln.
|
||||
- `Centron.BL/EmployeeArea/*` außer den oben genannten (EmployeeArticleBL, EmployeeDepartmentBL, EmployeeHolidayBL, EmployeeStatisticBL, EmployeeUserSettingsBL, TeamManagement/TeamManagementBL) – nicht gelesen.
|
||||
- `Centron.BL/CountryArea/FederalStateBL.cs` – nicht gelesen.
|
||||
- `Centron.BL/BusinessPartner/SupplierAssetBL.cs` sowie Rest von `SearchSupplierBL.cs` (Zeilen 121-Ende) – nicht gelesen.
|
||||
- `Centron.DAO`-Mapping-/Constraint-Definitionen (z. B. NHibernate `.hbm.xml` oder Fluent-Mappings) wurden nicht systematisch nach DB-seitigen UNIQUE-/NOT-NULL-Constraints durchsucht; alle hier dokumentierten Pflichtfeld-/Eindeutigkeitsregeln stammen aus der BL-Schicht (Anwendungslogik), nicht aus verifizierten DB-Constraints. Dies ist eine grundsätzliche Einschränkung für alle Kandidaten mit Aussagen zu "eindeutig"/"Pflichtfeld".
|
||||
- Frontend (XAML/WPF-Views) wurde nur punktuell für CRM-17 (IBAN) herangezogen; UI-seitige Pflichtfeld-Kennzeichnungen (z. B. rote Sternchen, weitere Format-Validatoren wie E-Mail-Regex, Telefonnummer-Masken) wurden nicht systematisch erhoben.
|
||||
- `DataSecurityBL.cs` (1900 Zeilen) enthält augenscheinlich analoge Lösch-/Anonymisierungslogik auch für Lieferanten und Interessenten (Zeilen ~1580-1850, u. a. weitere `DoDelete...`-Methoden mit "Comment"/"Kommentar"-Feldern) – nur stichprobenartig erfasst, nicht vollständig ausgewertet.
|
||||
- Es wurde keine gezielte Suche nach IBAN/USt-IdNr.-Validierung in Web-Service-Schnittstellen (`Centron.BL/WebServices/**`) durchgeführt; CRM-17/CRM-15 könnten dort weitere (bislang nicht gefundene) Validierungen besitzen.
|
||||
+460
@@ -0,0 +1,460 @@
|
||||
# Cluster: Dokumente, Reporting & Textbausteine — Rohbefunde (RRE)
|
||||
|
||||
Analyseumfang: DocuBoard (BL/DAO/Entities/WebServices), DocumentationArea, Administration/FileManagement (Dokumentenverwaltung), ReportEngine, Reporting, TextModuleArea, Centron.Api.docuFORM.
|
||||
Hinweis vorab: Der Ordner `DocuBoard` enthält entgegen der Namenserwartung **kein** Dokumentenmodul, sondern IT-Asset-/Gerätemanagement (Partner, Artikelzuordnung, AD-Systembenutzer-Ausschluss). Die eigentliche Dokumentenverwaltung liegt unter `Administration/FileManagement` (`DocumentBL`, `Directory`, `SharedDocument`). Dies wird unten als eigener Befund (DOC-01) dokumentiert, weitere Anforderungen zu Dokumenten beziehen sich auf `FileManagement`.
|
||||
|
||||
---
|
||||
|
||||
### Kandidat DOC-01
|
||||
Ebene: KONTEXT (Namensraum-Klärung, keine eigene Anforderung)
|
||||
Typ: Daten
|
||||
Akteur: Entwickler/Architekt (Migrationsteam)
|
||||
Vorbedingung: -
|
||||
Fakt: Der Namespace/Ordner `Centron.BL/DocuBoard` (und korrespondierend `Centron.Entities/Entities/DocuBoard`, `Centron.DAO/Mappings/DocuBoard`, `Centron.BL/WebServices/DocuBoard`) enthält ausschließlich Klassen zu IT-Asset-Management (`AssetManagementPartnerBL`, `AssetManagementArticleAssignmentBL`, `AssetManagementADSystemUserExclusionBL`), keine Dokumentenverwaltung. Die tatsächliche Dokumentenverwaltung (Upload, Versionierung, Sperren, Volltextsuche) befindet sich in `Centron.BL/Administration/FileManagement/DocumentBL.cs`.
|
||||
Aussage: (kein SwRS-Kandidat; Migrationshinweis) Bei der Neumodellierung ist der Begriff „DocuBoard" nicht mit Dokumentenverwaltung gleichzusetzen; ein Modul „Asset-/Gerätemanagement" ist separat von „Dokumentenverwaltung" zu führen.
|
||||
Ergebnis: Vermeidung von Fehlinterpretation der Fachdomäne bei der Anforderungsableitung.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/DocuBoard/AssetManagementPartnerBL.cs:1-55 - Begründung: Klasseninhalt (Partner, Items, CustomerCompact) zeigt Gerätemanagement, kein Dokument-Bezug.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/FileManagement/DocumentBL.cs:49-72 - Begründung: Enthält die tatsächliche Dokument-CRUD-Logik (GetDocumentsByDirectory, GetDocument).
|
||||
Prüfidee: Abgleich mit Fachbereich/Product Owner, ob „DocuBoard" als Produktname für ein separates Asset-Modul vermarktet wird.
|
||||
Konsolidierungshinweis: Betrifft ggf. auch das Cluster „IT-Asset-Management", falls ein anderer Agent dieses Thema bearbeitet.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat DOC-02
|
||||
Ebene: StRS
|
||||
Typ: funktional (Geschäftsziel)
|
||||
Akteur: Sachbearbeiter (Vertrieb/Verwaltung), Administrator
|
||||
Vorbedingung: Benutzer ist an c-entron angemeldet und besitzt Zugriff auf einen Ordner (Directory)
|
||||
Fakt: `DocumentBL.AddFileToDirectory` legt Dokumente in einer Ordnerstruktur (`Directory`) ab, verknüpft Metainformationen (`DocumentMetaInformation`), setzt einen Dokumenttyp-abhängigen Icon-Index (`GetImageIndexForDocumentType`) und aktualisiert die Trefferanzahl des Ordners (`NumDocuments`). Bei Helpdesk-Ordnern wird zusätzlich ein Historieneintrag erzeugt (`HelpdeskHistoryBL.CreateHistoryForDocument`).
|
||||
Aussage: Das System soll es Sachbearbeitern ermöglichen, beliebige Dateien in einer hierarchischen Ordnerstruktur abzulegen, automatisch nach Dateityp zu kategorisieren (Icon/Typ) und bei fachlichem Bezug (z. B. Helpdesk-Vorgang) automatisch eine Historie zu führen.
|
||||
Ergebnis: Zentrale, typisierte Dokumentenablage mit Prozessanbindung.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/FileManagement/DocumentBL.cs:587-648 - Begründung: `AddFileToDirectory` Implementierung inkl. MetaInformations, ImageIndex, Historie.
|
||||
- [SEKUNDÄR] src/backend/Centron.Entities/Entities/Administration/FileManagement/Document.cs:17-54 - Begründung: Entity-Felder bestätigen Typ/Version/Directory-Modell.
|
||||
Prüfidee: UI-Test: Datei in Kundenordner hochladen, prüfen ob Icon nach Dateityp korrekt vergeben wird und `NumDocuments` im Elternordner steigt.
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat DOC-03
|
||||
Ebene: SyRS
|
||||
Typ: funktional
|
||||
Akteur: Sachbearbeiter
|
||||
Vorbedingung: Dokument existiert bereits (documentI3D > 0)
|
||||
Fakt: `DocumentBL.CheckOutDocument`/`CheckInDocument`/`UndoCheckOut` implementieren ein Sperr-(Lock-)Konzept über `LockedBy` (Employee), `LockedByWorkstation`, `LockedFilePath`. `CanCheckOutDocument` verweigert das Auschecken, wenn bereits gesperrt. `UpdateDocument` verweigert ein Update, wenn das Dokument von einem anderen Benutzer gesperrt ist (`document.LockedBy != currentUser.User.Employee` → return null, kein Fehlertext).
|
||||
Aussage: Das System soll ein Check-out/Check-in-Verfahren für Dokumente bereitstellen, das gleichzeitige Bearbeitung durch mehrere Benutzer durch eine Sperre (Employee, Workstation, Dateipfad) verhindert.
|
||||
Ergebnis: Kollisionsfreie kollaborative Dokumentbearbeitung.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/FileManagement/DocumentBL.cs:878-951 - Begründung: CanCheckOutDocument/CheckOutDocument/CheckInDocument/UndoCheckOut.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/FileManagement/DocumentBL.cs:538-585 - Begründung: UpdateDocument prüft Sperre vor Änderung, gibt bei Fremdsperre `null` zurück (kein sprechender Fehlercode).
|
||||
Prüfidee: Zwei parallele Sessions: Benutzer A checkt aus, Benutzer B versucht Update → erwartete Ablehnung.
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt; Workaround (UpdateDocument liefert bei Sperre `null` statt Fehlermeldung/Result-Objekt — inkonsistent zum übrigen Result-Pattern)
|
||||
|
||||
---
|
||||
|
||||
### Kandidat DOC-04
|
||||
Ebene: SwRS
|
||||
Typ: Daten / nicht-funktional (Versionierung)
|
||||
Akteur: System (automatisiert)
|
||||
Vorbedingung: Dokument wird aktualisiert (UpdateDocument, CheckInDocument, AddNewDocumentVersion)
|
||||
Fakt: Jede Dokumentaktualisierung erzeugt einen **neuen** `Document`-Datensatz mit inkrementierter `Version` (`document.Version + 1`) statt eines Updates des bestehenden Datensatzes; alle Versionen referenzieren über `OwnerDocument` den „Kopf"-Datensatz. `GetDocumentsFromDirectory` filtert pro `OwnerDocument`-Gruppe nur die jeweils neueste Version (`Max(f => f.Version)`).
|
||||
Aussage: Das System soll Dokumentversionen unveränderlich (append-only) verwalten: jede neue Version ist ein eigener Datensatz, verknüpft über eine Ankerreferenz (OwnerDocument), wobei Standardlisten nur die aktuellste Version anzeigen.
|
||||
Ergebnis: Nachvollziehbare Versionshistorie ohne Datenverlust.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/FileManagement/DocumentBL.cs:538-585 - Begründung: UpdateDocument-Methode, Erzeugung neues Document-Objekt mit Version+1.
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/FileManagement/DocumentBL.cs:94-112 - Begründung: GetDocumentsFromDirectory gruppiert nach OwnerDocument, wählt max. Version.
|
||||
- [SEKUNDÄR] src/backend/Centron.BL/Administration/FileManagement/DocumentBL.cs:843-876 - Begründung: AddNewDocumentVersion als expliziter Versionierungs-Endpunkt.
|
||||
Prüfidee: Datei zweimal hochladen (gleicher Name/Ordner) → prüfen ob zwei Datensätze mit Version 1/2 und gemeinsamer OwnerDocument-Referenz entstehen.
|
||||
Konsolidierungshinweis: -
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat DOC-05
|
||||
Ebene: SwRS
|
||||
Typ: nicht-funktional (Performance/Datenintegrität)
|
||||
Akteur: System (automatisiert)
|
||||
Vorbedingung: Dokument (z. B. PDF eines Belegs) wird wiederholt exportiert/gedruckt
|
||||
Fakt: `DocumentBL.GetIdenticalDocumentInDirectory` (referenziert Ticket 160276) prüft vor dem Speichern, ob im Zielordner bereits ein Dokument mit identischem Namen, identischer Version und identischer Dateigröße existiert, um mehrfaches Ablegen desselben Report-PDFs bei wiederholtem Druck/Export zu vermeiden.
|
||||
Aussage: Das System soll beim automatischen Ablegen generierter Belegdokumente (z. B. Rechnungs-PDFs) Duplikate anhand von Name, Version und Dateigröße erkennen und vermeiden.
|
||||
Ergebnis: Reduzierte Datenredundanz im Dokumentenarchiv.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/FileManagement/DocumentBL.cs:74-92 - Begründung: Methode inkl. Code-Kommentar mit Ticket-Referenz 160276.
|
||||
Prüfidee: Denselben Beleg zweimal exportieren, prüfen ob nur ein Dokumentdatensatz im Zielordner entsteht.
|
||||
Konsolidierungshinweis: Hängt mit DOC-13 (PDF-Archivierung) zusammen.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat DOC-06
|
||||
Ebene: SyRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Sachbearbeiter, Administrator
|
||||
Vorbedingung: Löschversuch eines Dokuments
|
||||
Fakt: `DocumentBL.CanDeleteDocument` verhindert das Löschen eines Dokuments, wenn es (a) in einem aktiven, noch nicht abgeschlossenen elektronischen Signierprozess (`SharedDocument`, `IsSigned == false`, nicht abgelaufen) als Basis-, Abrede-, Anrede- oder Signaturdatei verwendet wird, oder (b) in den globalen Einstellungen (`AppSettingsGroupBL.GetSharedDocumentSettings`) als Standard-Abrede/-Anrede/-Signatur für einen der sechs Belegtypen (Angebot, Auftrag, Lieferschein, Abholschein, Rechnung, Gutschrift, Vertrag) hinterlegt ist. Jeder Fall liefert eine spezifische deutsche Fehlermeldung mit `DefaultMessageCodes.DocumentInActiveSigningProcess` bzw. `.ErrorMessage`.
|
||||
Aussage: Das System soll das Löschen von Dokumenten verhindern, solange diese in einem laufenden elektronischen Unterschriftsprozess referenziert oder als Systemvorlage für Signaturprozesse konfiguriert sind, und dem Benutzer den konkreten Verwendungszweck als Fehlermeldung mitteilen.
|
||||
Ergebnis: Schutz vor Datenverlust bei referenzierten Vorlagen/aktiven Rechtsvorgängen.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/FileManagement/DocumentBL.cs:425-536 - Begründung: Vollständige CanDeleteDocument-Logik mit allen Fehlermeldungstexten.
|
||||
Prüfidee: Dokument, das als Signatur-Einstellung für Rechnungen hinterlegt ist, löschen → erwartete Fehlermeldung "...als Signatur für den Signierungs-Prozess für Rechnungen eingestellt".
|
||||
Konsolidierungshinweis: Überschneidet sich mit dem Cluster „C-Sign/Signierprozesse" (SharedDocument) — dort ggf. tiefergehend behandelt.
|
||||
Status: belegt
|
||||
|
||||
---
|
||||
|
||||
### Kandidat DOC-07
|
||||
Ebene: SwRS
|
||||
Typ: Sicherheit
|
||||
Akteur: Sachbearbeiter, Administrator
|
||||
Vorbedingung: Dokument (.msg/.eml) enthält S/MIME-Signatur
|
||||
Fakt: `DocumentBL.GetMailDocumentFromEml` verifiziert bei signierten E-Mail-Anhängen (MultipartSigned/ApplicationPkcs7Mime) die S/MIME-Signatur über `TemporarySecureMimeContext`. Bei Fehlschlag der Verifikation wird nur eine Warnung geloggt (`Logger.Warn`), die Mail wird trotzdem unverifiziert angezeigt.
|
||||
Aussage: Das System soll beim Anzeigen archivierter E-Mail-Dokumente (.eml) vorhandene S/MIME-Signaturen prüfen und dem Benutzer erkennbar machen, wenn die Signatur ungültig oder nicht verifizierbar ist.
|
||||
Ergebnis: Vertrauenswürdigkeit archivierter E-Mail-Kommunikation.
|
||||
Belege:
|
||||
- [PRIMÄR] src/backend/Centron.BL/Administration/FileManagement/DocumentBL.cs:196-234 - Begründung: Verifikationslogik inkl. Warn-Logging bei Fehlschlag.
|
||||
Prüfidee: Signierte E-Mail mit ungültiger Signatur importieren und im DocuBoard/FileManagement öffnen — prüfen ob Warnhinweis im UI sichtbar ist (aktuell nur Log, kein UI-Hinweis erkennbar).
|
||||
Konsolidierungshinweis: -
|
||||
Status: HYPOTHESE (fehlende Information: Es ist im BL-Code nicht erkennbar, ob die Warnung tatsächlich bis in die UI durchgereicht wird oder nur im Server-Log verbleibt — WPF-Client-Code wurde in diesem Cluster nicht geprüft.)
|
||||
|
||||
---
|
||||
|
||||
### Kandidat DOC-08
|
||||
Ebene: SwRS
|
||||
Typ: Daten / Validierung
|
||||
Akteur: System (automatisiert)
|
||||
Vorbedingung: Dokumentname enthält Nicht-ASCII/Sonderzeichen
|
||||
Fakt: `DocumentBL.SaveOrUpdateDocument` bereinigt den Dokumentnamen mit Regex `[^ | ||||