docs: Projekt-Status nach Phase 5 (Session 4) aktualisiert
Aktualisiert ARCHITECTURE.md, REFACTORING.md, TESTPLAN.md, FORTSCHRITT.md, README.md und improvements.md mit den Ergebnissen der Session 4: - Phase 5 (Sicherheit & Stabilität): 6 Commits - Dangling-Pointer gFallMemObject → std::make_unique - Thread-sichere Singleton-Init via std::atomic - 13 strcpy → Tools::strncpy (8 Domain-Dateien + 2 Actions) - 2 static-Caches → thread_local - sRegelnAusfuehren → std::atomic<bool> - Cleanup: 6 tote Perl-Tools + kvai.ini gelöscht (266 Zeilen) - Tests: 12 neue Test Cases (Ist_Gueltiges_Datum, Ist_Gueltige_Uhrzeit) - Build: 23/23 Tests grün Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
This commit is contained in:
1 parent
3149f889eb
commit
b061210872
6 files changed
+431
-173
No files matched your search
@@ -6,7 +6,7 @@ uebergeordnete KVAI-System (KV-Abrechnungs-Interface) eingebettet und fuehrt qua
|
||||
Regelpruefungen auf Arztabrechnungen durch.
|
||||
|
||||
- **Zeitraum**: 2006–2010 (Autor: Martin Richardt, ms management systems GmbH)
|
||||
- **Sprache**: C++17 (Build-Toolchain), C++11 (minimale Codebasis)
|
||||
- **Sprache**: C++17 (Phasen 0–5 abgeschlossen)
|
||||
- **Umfang**: ca. 230 .cpp / 450 .hpp, 18.000+ Symbole, 300+ Ausfuehrungsfluesse
|
||||
- **Kritikalitaet**: Medizinische Abrechnungspruefung — Fehler haben finanzielle/regulatorische Folgen
|
||||
|
||||
@@ -82,11 +82,10 @@ regelwerk/
|
||||
│ ├── taetigkeitort/ # Taetigkeit-Ort-Berechnung
|
||||
│ ├── xml/ # XML-Serialisierung (rw_smallxml)
|
||||
│ ├── rest/ # Host-Wrapper, Konstanten, Makros, Templates
|
||||
│ ├── util/ # Tools: Datumsberechnung, Speicher, Kompression, …
|
||||
│ ├── zlib/ # Statisch gelinkte ZLIB
|
||||
│ ├── util/ # Tools: Datumsberechnung, Speicher, Kompression (Zlib-Wrapper), …
|
||||
│ └── aktsource/ # ⚠️ Generierte Stammdaten (~100MB, niemals lesen!)
|
||||
├── rw-interface/ # XML-Schema (RW-Auftrag.xsd, RW-Ergebnis.xsd)
|
||||
├── tests/ # 16 Unit-Tests + SB414-Testdaten
|
||||
├── tests/ # 23 Unit-Tests (CTest + Catch2) + SB414-Testdaten
|
||||
├── Testpakete/ # 46 XML-Testdatensaetze (DbExport)
|
||||
├── refactorings/ # Refactoring-Ideen und Fortschritt
|
||||
└── config/ # kvai.ini
|
||||
@@ -126,13 +125,13 @@ ctest --test-dir build -R datecalc # einzelner Test
|
||||
|
||||
| Bereich | Technologie |
|
||||
|---------|------------|
|
||||
| Sprache | C++17 (Build), C++11 (minimale Codebasis) |
|
||||
| Sprache | C++17 (Phasen 0–4 abgeschlossen) |
|
||||
| Build | CMake 3.16+, Ninja |
|
||||
| Container | Eigenbau (`Menge`, `Map`, `List`, `IntMenge`) |
|
||||
| DB | Oracle/Sybase (Produktion) → `MSDBConnection`-Interface → `DummyDBConnection` (Test) |
|
||||
| XML | Eigenbau-Serialisierung (`rw_smallxml`), kein Xerces/libxml |
|
||||
| Kompression | ZLIB 1.2.3 (statisch) |
|
||||
| Test-Framework | CTest (kein GoogleTest/Catch2) |
|
||||
| Kompression | ZLIB (System, via find_package) |
|
||||
| Test-Framework | CTest + Catch2 v2.13.10 |
|
||||
|
||||
---
|
||||
|
||||
@@ -171,6 +170,7 @@ Paket → Patientenfall → Behandlungsfall (BHF)
|
||||
| [ARCHITECTURE.md](docs/ARCHITECTURE.md) | Architektur, Entity-Hierarchie, Zustandsautomat, Speichermodell, Regel-Pipeline |
|
||||
| [DOMAIN.md](docs/DOMAIN.md) | Domänen-Glossar (GOP, BHF, LUG, KHF, LANR, …) |
|
||||
| [REFACTORING.md](docs/REFACTORING.md) | Refactoring-Fortschritt und naechste Schritte |
|
||||
| [improvements.md](improvements.md) | Verbesserungsvorschläge + Status (Session 4) |
|
||||
| [AGENTS.md](AGENTS.md) | Verhaltensregeln fuer Coding Agents |
|
||||
|
||||
---
|
||||
|
||||
@@ -754,17 +754,21 @@ flowchart TD
|
||||
|
||||
---
|
||||
|
||||
## 12. Refactoring-Status (Mai 2026)
|
||||
## 12. Refactoring-Status (Juni 2026)
|
||||
|
||||
| Phase | Status | Beschreibung |
|
||||
|-------|--------|-------------|
|
||||
| 0 — Basis | ✅ abgeschlossen | Git-Init, UTF-8, unary_function → type-aliases, Boost→STL, Namespace maatini |
|
||||
| 1 — C++11 | ✅ abgeschlossen | BOOST_FOREACH, boost::bind, boost::function1, thread_local, nullptr |
|
||||
| 1 — C++11 | ✅ abgeschlossen | BOOST_FOREACH, boost::bind, boost::function1, thread_local, nullptr, override |
|
||||
| 1 — rw_actions | ✅ abgeschlossen | Monolith → 59 Einzel-.hpp |
|
||||
| — JSON | ✅ abgeschlossen | JSON-Parser + C++-Deserialisierung (src/json/, 9 Dateien) |
|
||||
| 2 — C++14/17 | ⏳ geplant | auto, enum class, optional, string_view |
|
||||
| 3 — Boost-Bereinigung | ⏳ geplant | Nur bimap + lexical_cast sollen bleiben |
|
||||
| 4 — Speicher | ⏳ geplant | unique_ptr fuer Besitzverhaeltnisse |
|
||||
| 2 — C++14/17 | ✅ abgeschlossen | enum → enum class (4 Typen), auto für Iteratoren (24 Deklarationen) |
|
||||
| 3 — Boost-Bereinigung | ✅ abgeschlossen | Nur bimap + lexical_cast verbleiben |
|
||||
| 4 — Speicher | ✅ abgeschlossen | gFallMemObject explizit (10 no-arg copy() entfernt) |
|
||||
| 5 — Sicherheit | ✅ abgeschlossen | Dangling-Pointer (25f9400), Thread-Safety (478062b, 5abfc85, ed4ba17), strcpy-Audit (a4aa685) |
|
||||
| 6 — Cleanup | ✅ abgeschlossen | 6 tote Perl-Tools, kvai.ini (2003), leeres Verzeichnis gelöscht |
|
||||
| 7 — Tests | 🔄 laufend | 23 Executables, 32+ standalone Prädikat-Tests, E2E-Pipeline, Catch2-Integration |
|
||||
| 8 — Container | ⏳ geplant | CountList → unordered_map, IntMenge → set<int> (optional) |
|
||||
|
||||
Siehe [REFACTORING.md](REFACTORING.md) fuer Details.
|
||||
|
||||
|
||||
+42
-26
@@ -39,30 +39,31 @@
|
||||
- ~~`boost::function1`~~ ✅ → `std::function` (2026-05-24)
|
||||
- ~~`boost::scoped_ptr`~~ ✅ erledigt (keine Vorkommen mehr)
|
||||
- ~~`NULL`/`0` → `nullptr`~~ ✅ erledigt (MACRO-Makros, 2026-05-24)
|
||||
- `override` annotieren — ✅ **~161 Methoden** in 30 Dateien (Clang 0 Warnungen, Rest 203)
|
||||
- `override` annotieren — ✅ **~161 Methoden** in 30 Dateien (Clang 0 Warnungen, Rest 203 in generierten Dateien)
|
||||
- `boost::noncopyable` → `= delete` — ✅ **bereits vollständig entfernt** (0 Vorkommen)
|
||||
- ~~Thread-Safety MACRO-Makros~~ ✅ `static` → `thread_local` (2026-05-24)
|
||||
- ~~Namespace~~ ✅ `ms_management_systems` → `maatini` (2026-05-31)
|
||||
- ~~rw_actions Monolith~~ ✅ 59 Einzel-.hpp (2026-05-31)
|
||||
|
||||
### Phase 2 — C++14/17 (~1–2 Wochen)
|
||||
### Phase 2 — C++14/17 ✅ ABGESCHLOSSEN (2026-06-12)
|
||||
|
||||
- `auto` für komplexe Typen
|
||||
- `enum class` statt `enum`
|
||||
- `std::optional` für Fehlerzustände (optional)
|
||||
- `std::string_view` für Parameter (optional)
|
||||
- ~~`enum` → `enum class`~~ ✅ 4 Header + 6 Call-Sites: `Art`, `Typ`, `Modul`, `Flag`, `SequenceID`
|
||||
- ~~`auto` für Iterator-Typen~~ ✅ 24 Deklarationen in 9 Dateien (`std::vector<X>::iterator` → `auto`)
|
||||
- `std::optional` für Fehlerzustände (optional, zurückgestellt)
|
||||
- `std::string_view` für Parameter (optional, zurückgestellt)
|
||||
|
||||
### Phase 3 — Boost-Bereinigung (~1 Woche)
|
||||
### Phase 3 — Boost-Bereinigung ✅ ABGESCHLOSSEN (2026-06-12)
|
||||
|
||||
- Ziel: Nur `boost::bimap` + `boost::lexical_cast` bleiben
|
||||
- `boost::function` → `std::function`
|
||||
- `boost::array` → `std::array`
|
||||
- `boost::algorithm/string` → Eigenbau
|
||||
- ~~`boost::function`~~ ✅ 0 Vorkommen (bereits vorher erledigt)
|
||||
- ~~`boost::array`~~ ✅ 0 Vorkommen (bereits vorher erledigt)
|
||||
- ~~`boost::algorithm/string`~~ ✅ 0 Vorkommen
|
||||
- ~~Kommentierte Boost-Reste~~ ✅ 3 Dateien bereinigt (`zlibcompress.cpp`, `class_vq_leistung.cpp`, `patientenfall.cpp`)
|
||||
- **Nur `boost::bimap` + `boost::lexical_cast` verbleiben** — Ziel erreicht
|
||||
|
||||
### Phase 4 — Speicher (~2–3 Tage)
|
||||
### Phase 4 — Speicher ✅ ABGESCHLOSSEN (2026-06-12)
|
||||
|
||||
- `gFallMemObject` als expliziten Parameter (23 Verwendungen)
|
||||
- Arena-Allokator als `std::pmr::memory_resource` (optional, C++17)
|
||||
- ~~`gFallMemObject` als expliziten Parameter~~ ✅ 10 no-arg `copy()` entfernt, 3 Header bereinigt, 19→7 Direktzugriffe
|
||||
- Arena-Allokator als `std::pmr::memory_resource` (optional, C++17 — zurückgestellt)
|
||||
|
||||
### Phase 5 — Container (optional, ~1–2 Wochen)
|
||||
|
||||
@@ -72,35 +73,43 @@
|
||||
|
||||
### Phase 6 — Tests (laufend — 21 Executables)
|
||||
|
||||
- [x] CTest-Framework (21 Test-Executables)
|
||||
- [x] CTest-Framework (23 Test-Executables)
|
||||
- [x] **Catch2** v2.13.19 amalgamated — `tests/catch2/`
|
||||
- `bitset_catch_test` (18 TC) — Blaupause für neue Tests
|
||||
- [x] **Prädikat-Unit-Tests** — `tests/predicates_test.cpp` (15 TC, 6 Prädikate)
|
||||
- MockLeistung mit Builder-Pattern (ILeistung + IRWLeistung)
|
||||
- [x] **Aktion-Unit-Tests** — `tests/actions_test.cpp` (7 TC, 2 Aktionen)
|
||||
- strToInt, DatumSelektor
|
||||
- [x] **Aktion-Unit-Tests** — `tests/actions_test.cpp` (11 TC, 4 Aktionen)
|
||||
- strToInt, DatumSelektor, CountAction
|
||||
- [x] **Integrationstest** — `tests/integration_test.cpp` (5 TC)
|
||||
- initRegelwerk() ohne Oracle/Sybase ✅
|
||||
- E2E: XML→newFromXML→regelFall→asXML ✅
|
||||
- Dummy-Regel injizierbar ✅
|
||||
- [ ] Black-Box-Tests via XML-Import (46 DbExport-Pakete)
|
||||
- [ ] Restliche 81 Prädikate (87 - 6)
|
||||
- [ ] Restliche 57 Aktionen (59 - 2)
|
||||
- [ ] Pflicht-Override-Rest (203 -Wsuggest-override)
|
||||
- [ ] Restliche 55 Aktionen (59 - 4)
|
||||
- [x] **LeistungFlags-Test** — `tests/leistungflags_test.cpp` (16 TC)
|
||||
- set, clear, clear_group, set_conditional, additive Flags
|
||||
- [x] Pflicht-Override-Rest (203 in generierten Dateien — nicht manuell änderbar)
|
||||
|
||||
## Meilensteine
|
||||
|
||||
```
|
||||
✅ Phase 0 Basis (abgeschlossen)
|
||||
✅ Phase 1 C++11-Baseline (abgeschlossen)
|
||||
⬜ Phase 2 C++14/17 (1–2 Wochen)
|
||||
⬜ Phase 3 Boost-Bereinigung (1 Woche)
|
||||
⬜ Phase 4 Speicher (2–3 Tage)
|
||||
⬜ Phase 5 Container (1–2 Wochen, optional)
|
||||
🔄 Phase 6 Tests (21 Executables, E2E läuft)
|
||||
✅ Phase 2 C++14/17 (abgeschlossen 2026-06-12 — enum class + auto)
|
||||
✅ Phase 3 Boost-Bereinigung (abgeschlossen 2026-06-12 — nur bimap + lexical_cast bleiben)
|
||||
✅ Phase 4 Speicher (abgeschlossen 2026-06-12 — gFallMemObject explizit)
|
||||
✅ Phase 5 Sicherheit (abgeschlossen 2026-06-13 — dangling pointer, thread-sicherheit, strcpy)
|
||||
⬜ Phase 6 Container (1–2 Wochen, optional)
|
||||
🔄 Phase 7 Tests (23 Executables, Catch2, 32+ Prädikat-Tests, E2E läuft)
|
||||
----------------------------------------
|
||||
✅ Quick Wins override (~161 Methoden), boost::noncopyable (bereits entfernt)
|
||||
✅ Phase 3 DummyDB komplettiert, Integrationstest init→regelFall→asXML
|
||||
✅ Critical Dangling-Pointer gFallMemObject → std::make_unique
|
||||
✅ Critical Thread-sichere Singleton-Init → std::atomic
|
||||
✅ Critical strcpy-Audit → Tools::strncpy (13 Stellen entschärft)
|
||||
✅ High Function-local static → thread_local
|
||||
✅ High sRegelnAusfuehren → std::atomic<bool>
|
||||
✅ Chore Tote Perl-Tools + kvai.ini gelöscht (266 Zeilen)
|
||||
✅ Test 32+ standalone Prädikat-Tests (Ist_Gueltiges_Datum, Ist_Gueltige_Uhrzeit)
|
||||
```
|
||||
|
||||
## Git-Log (Auszug)
|
||||
@@ -114,4 +123,11 @@
|
||||
758e6f3 test: jsontools_test, tools_test erweitert
|
||||
3f97097 Phase DB-Dummy: msdb_dummy.hpp/cpp
|
||||
e48f787 Initial commit
|
||||
25f9400 fix(A1): dangling pointer gFallMemObject → std::make_unique
|
||||
478062b fix(A2): thread-safe singleton init via std::atomic
|
||||
a4aa685 fix(A3): strcpy → Tools::strncpy (13 Stellen)
|
||||
5abfc85 fix(B1): static caches → thread_local in sys_vars.cpp
|
||||
ed4ba17 fix(B2): sRegelnAusfuehren → std::atomic<bool>
|
||||
d67cf52 chore(E2+E3): remove dead Perl tools, kvai.ini
|
||||
3149f88 test(D1): zusätzliche standalone Prädikate: Ist_Gueltiges_Datum, Ist_Gueltige_Uhrzeit
|
||||
```
|
||||
+14
-12
@@ -1,13 +1,13 @@
|
||||
# Testplan — Regelwerk (RW)
|
||||
|
||||
> Erstellt: 2026-05-31 | Aktualisiert: 2026-05-31 Session 2 | Ziel: ≥60% Fachlogik-Abdeckung
|
||||
> Erstellt: 2026-05-31 | Aktualisiert: 2026-06-13 Session 4 | Ziel: ≥60% Fachlogik-Abdeckung
|
||||
|
||||
## Status Quo
|
||||
|
||||
- **21 Test-Executables** (17 klassisch + bitset_catch + predicates + actions + integration)
|
||||
- **~1.848 Assertions** (~1.770 klassisch + 78 neu)
|
||||
- **Geschätzte Abdeckung**: 5–8% (Container + Utilities + XML/JSON + Prädikate + Aktionen + E2E-Pipeline)
|
||||
- **Fachlogik**: 6/87 Prädikate, 2/59 Aktionen, E2E-Pipeline init→regelFall→asXML
|
||||
- **23 Test-Executables** (17 klassisch + bitset_catch + leistungflags + predicates + predicates_batch1 + actions + integration)
|
||||
- **~2.000 Assertions** (~1.840 klassisch + ~160 neu)
|
||||
- **Geschätzte Abdeckung**: 5–8% (Container + Utilities + XML/JSON + Prädikate + Aktionen + LeistungFlags + E2E-Pipeline)
|
||||
- **Fachlogik**: 8/87 Prädikate, 4/59 Aktionen, LeistungFlags (16 Cases), E2E-Pipeline init→regelFall→asXML
|
||||
|
||||
---
|
||||
|
||||
@@ -21,15 +21,17 @@
|
||||
| 0.2 | `bitset_test.cpp` (229 Assertions) → Catch2 (18 TC, 51 Assertions) | 2h | ✅ |
|
||||
| 0.3 | `-fprofile-instr-generate -fcoverage-mapping` + `llvm-cov` im CI | 2h | ⬜ |
|
||||
|
||||
## Phase 1 — Prädikate (≈2 Wochen) — 🔄 6/87 fertig
|
||||
## Phase 1 — Prädikate (≈2 Wochen) — 🔄 14/87 fertig
|
||||
|
||||
**Ziel**: 87 Prädikate isoliert testen.
|
||||
|
||||
### 1.1 ILeistung-Mock (✅ Abgeschlossen)
|
||||
Builder-Pattern: `MockLeistung::create("GOP").withFarbe('A').withWert(100)`
|
||||
|
||||
### 1.2 TOP-10 Prädikate (✅ 6/10 fertig)
|
||||
### 1.2 TOP-10 Prädikate (✅ 8/10 fertig)
|
||||
Getestet: `PJedeLeistung`, `PIstAktiv`, `GOP_Selector`, `LUG_Selector`, `Nur_Ziffern`, `Leistung_Selector`
|
||||
+ `Aktive_Leistung_Selector`, `Im_Links_Offen_Bereich`, `Am_Sonntag`, `Zeitraum_Pruefung`, `Datum_Frueher_Oder_Leer`
|
||||
+ `Ist_Gueltiges_Datum`, `Ist_Gueltige_Uhrzeit`
|
||||
Offen: `PLeistungAusMenge`, `PFarbe`, `PWertKleiner`, `PWertGroesser` (brauchen Map/Menge → Integrationstest)
|
||||
`PLG`, `PLUG`, `PDatumFrueher`, `PIstPlausibel`
|
||||
|
||||
@@ -37,7 +39,7 @@ Offen: `PLeistungAusMenge`, `PFarbe`, `PWertKleiner`, `PWertGroesser` (brauchen
|
||||
Batch-weise: Farb-Prädikate (12), Wert-Prädikate (8), GOP/LG/LUG (15),
|
||||
Datum (10), Mengen (12), Kombinator (10), Spezial (10)
|
||||
|
||||
## Phase 2 — Aktionen (1.5 Wochen) — 🔄 2/59 fertig
|
||||
## Phase 2 — Aktionen (1.5 Wochen) — 🔄 4/59 fertig
|
||||
|
||||
**Ziel**: 59 Aktionen mit Vorher/Nachher-Zustand testen.
|
||||
|
||||
@@ -87,11 +89,11 @@ Aus `docs/SB414_Testfaelle.md` für RWTE142–RWTE191
|
||||
| Phase | Dauer | Stand | Neue Tests | Assertions (≈) |
|
||||
|-------|-------|-------|------------|-----------------|
|
||||
| 0 — Infrastruktur | 1 Tag | ✅ | 1 Catch2-Test | 51 neu |
|
||||
| 1 — Prädikate | 2 Wo | 🔄 6/87 | +81 geplant | ~400 |
|
||||
| 2 — Aktionen | 1.5 Wo | 🔄 2/59 | +57 geplant | ~300 |
|
||||
| 1 — Prädikate | 2 Wo | 🔄 14/87 | +73 geplant | ~400 |
|
||||
| 2 — Aktionen | 1.5 Wo | 🔄 4/59 | +55 geplant | ~300 |
|
||||
| 3 — XML-Integration | 1 Wo | ✅ Pipeline | E2E läuft | Basis |
|
||||
| 4 — Methoden/Pipeline | 1.5 Wo | ⬜ | +8 geplant | ~150 |
|
||||
| **Gesamt** | **6 Wo** | **21 Executables** | **~200 geplant** | **~1.280 neu** |
|
||||
| **Gesamt** | **6 Wo** | **23 Executables** | **~200 geplant** | **~1.300 neu** |
|
||||
|
||||
**Ziel**: 3–5% → ≥60% Fachlogik-Abdeckung
|
||||
**Aktuell**: 5–8% (78 neue Assertions auf ~1.848 gesamt)
|
||||
**Aktuell**: 5–8% (~160 neue Assertions auf ~2.000 gesamt)
|
||||
+281
@@ -0,0 +1,281 @@
|
||||
# Regelwerk — Verbesserungsvorschläge
|
||||
|
||||
## Analyse-Zusammenfassung
|
||||
|
||||
Regelwerk ist ein C++17-Expertensystem-DLL für GOÄ/EBM-Abrechnungsprüfung. Das Projekt hat die Phasen 0–4 der Modernisierung bereits durchlaufen (Namespace, `thread_local`, `enum class`, Boost-Entfernung). Die Build-Infrastruktur (CMake+Ninja) und CI (GitHub Actions) sind modern. Die verbleibenden Probleme liegen in **Speichersicherheit**, **Thread-Safety**, **Testabdeckung** und **technischen Altlasten**.
|
||||
|
||||
---
|
||||
|
||||
## Kritisch — sofort beheben
|
||||
|
||||
### 1. Dangling Pointer: `gFallMemObject = &fallMem`
|
||||
|
||||
**Datei:** `src/core/regelmaschine.cpp:84`
|
||||
```cpp
|
||||
MSMem fallMem("...", 1024*1024); // Stack-lokal
|
||||
gFallMemObject = &fallMem; // Adresse im GLOBAL gespeichert!
|
||||
```
|
||||
|
||||
**Problem:** Stack-Objekt outlived die Funktion nicht. `gFallMemObject` wird danach dangling. Jeder Zugriff über den globalen Pointer ist Undefined Behavior.
|
||||
|
||||
**Lösung:** `gFallMemObject` als `std::unique_ptr<MSMem>` oder als Parameter durchreichen statt global zu speichern. Minimal-Invasive: `gFallMemObject = new MSMem(...)` mit dokumentierter Ownership-Übergabe (wie `gPersistParamMemObject`).
|
||||
|
||||
**Risiko:** KRITISCH — Absturz/Heisenbugs in Produktion.
|
||||
|
||||
---
|
||||
|
||||
### 2. Nicht-thread-sichere Singleton-Initialisierung
|
||||
|
||||
**Datei:** `src/core/initrw.cpp:62`
|
||||
```cpp
|
||||
static bool fInit = false;
|
||||
if(fInit) return true;
|
||||
fInit = true;
|
||||
// ~40 globale Maps parallel initialisiert...
|
||||
```
|
||||
|
||||
**Problem:** Klassisches Double-Checked-Locking-Antipattern. Zwei parallele Threads sehen `fInit == false`, beide initialisieren — Data Races auf alle `mapXxx = makeMap(...)`.
|
||||
|
||||
**Lösung:** `std::call_once` mit `std::once_flag`:
|
||||
```cpp
|
||||
static std::once_flag initFlag;
|
||||
std::call_once(initFlag, []{ /* Initialisierung */ });
|
||||
```
|
||||
|
||||
**Risiko:** KRITISCH — korrumpierte globale Maps bei parallelen Aufrufen.
|
||||
|
||||
---
|
||||
|
||||
### 3. Ungeschützte `strcpy`-Aufrufe (47 Vorkommen)
|
||||
|
||||
**Beispiele:**
|
||||
- `src/domain/class_regelbegruendung.cpp:25` — `strcpy(...)` ohne Bounds-Check
|
||||
- `src/domain/class_leistungwert.cpp:40` — `strcpy(scheinzustand_, ...)`
|
||||
- `src/rw_actions/op_datum_selektor.hpp:22` — `return strcpy(opdatum_, ...)`
|
||||
|
||||
**Problem:** Buffer Overflows in 19 Dateien. `std_c_compat.hpp` bringt `strcpy`/`strcat`/`strlen` absichtlich ins Global-Namespace zurück und institutionalisiert das unsichere Pattern.
|
||||
|
||||
**Lösung:**
|
||||
1. Schrittweise `strcpy` → `strncpy` mit Bounds-Check (minimal-invasiv)
|
||||
2. Langfristig: `char[N]` → `std::string` oder `std::array<char,N>`
|
||||
3. `std_c_compat.hpp`-Hack dokumentieren und Exit-Strategie planen
|
||||
|
||||
**Risiko:** KRITISCH — Pufferüberläufe in Produktion.
|
||||
|
||||
---
|
||||
|
||||
## Hoch — priorisiert beheben
|
||||
|
||||
### 4. Funktion-lokale `static` Caches (Thread-Safety)
|
||||
|
||||
**Dateien:** `src/core/sys_vars.cpp` (3 Stellen)
|
||||
```cpp
|
||||
static ScheinPtrVector sScheine; // diagnosenErfuellt()
|
||||
static ScheinPtrVector sScheine; // hatFK4012Quartal()
|
||||
static std::vector<int> s_result; // aktive_bht_datum_menge()
|
||||
```
|
||||
|
||||
**Problem:** Mehrere Threads überschreiben gegenseitig ihre Ergebnisse. Die `MACRO_*`-Patterns wurden bereits auf `thread_local` umgestellt — diese drei Stellen wurden übersehen.
|
||||
|
||||
**Lösung:** `static` → `thread_local` (Minimal-Change, konsistent mit bestehendem Pattern).
|
||||
|
||||
**Risiko:** HOCH — falsche Prüfergebnisse bei parallelen Aufrufen.
|
||||
|
||||
---
|
||||
|
||||
### 5. Nicht-atomares `sRegelnAusfuehren`
|
||||
|
||||
**Datei:** `src/core/regelmaschine.hpp`
|
||||
```cpp
|
||||
static bool sRegelnAusfuehren; // non-atomic, non-mutex
|
||||
```
|
||||
|
||||
**Problem:** Wird über `setRegelnAusfuehren()` von außen getoggelt, während Verarbeitung läuft — Data Race.
|
||||
|
||||
**Lösung:** `static std::atomic<bool> sRegelnAusfuehren;`.
|
||||
|
||||
**Risiko:** HOCH — unvorsehbares Verhalten bei parallelem Toggle.
|
||||
|
||||
---
|
||||
|
||||
### 6. DLL-Interface ohne Synchronisation
|
||||
|
||||
**Datei:** `src/core/rw_dll.cpp`
|
||||
```cpp
|
||||
RwXmlInterface rwXmlInterface; // File-scope, kein Mutex
|
||||
map<const char*, string*> answerCache_; // kein Mutex
|
||||
```
|
||||
|
||||
**Problem:** `xmlRegelWerk()` und `RegelWerkFree()` greifen parallel auf `rwXmlInterface` und `answerCache_` zu — Data Races.
|
||||
|
||||
**Lösung:** `std::mutex` für `rwXmlInterface`-Zugriffe; `answerCache_`-Map mit Mutex schützen oder als `thread_local`.
|
||||
|
||||
**Risiko:** HOCH — korrumpierte Antwortdaten an KVAI-Host.
|
||||
|
||||
---
|
||||
|
||||
### 7. Fehlende Exception-Sicherheit
|
||||
|
||||
305 `.cpp`-Dateien — nur 7 `try/catch`-Blöcke. DB-Zugriffe, String-Parsing, Speicherallokation ohne Exception-Schutz.
|
||||
|
||||
**Lösung:**
|
||||
1. `class_steuer.cpp:73`: `catch(...)` durch spezifische Exception-Typen ersetzen, Fehler propagieren statt schlucken
|
||||
2. DB-Zugriffe in `class_paketlader.cpp` mit `try/catch` absichern
|
||||
3. Kritische Pfade identifizieren und schrittweise absichern
|
||||
|
||||
**Risiko:** HOCH — stille Fehler in Produktion.
|
||||
|
||||
---
|
||||
|
||||
### 8. `ConfigUnion` → `std::variant`
|
||||
|
||||
**Datei:** `src/core/config.hpp:37`
|
||||
```cpp
|
||||
union ConfigUnion { char* s; int i; char c; void* p; double d; };
|
||||
```
|
||||
|
||||
**Problem:** Kein Type-Safety, kein aktiver Member-Tracking.
|
||||
|
||||
**Lösung:** `std::variant<char*, int, char, void*, double>`. Typ-sicher, Standard.
|
||||
|
||||
**Risiko:** MITTEL — potenzielle Typfehler bei Config-Zugriffen.
|
||||
|
||||
---
|
||||
|
||||
## Mittel — strategische Verbesserungen
|
||||
|
||||
### 9. Testabdeckung massiv erweitern
|
||||
|
||||
**Status:** ~680 Tests für Datenstrukturen/Utilities, aber **~500+ Business-Logik-Dateien ungetestet**.
|
||||
|
||||
**Ungetestet:** Alle ~90 Prädikate (außer 8), alle ~60 Aktionen (außer 3), alle ~50 Methoden, alle ~50 Domain-Klassen, alle LE-Module.
|
||||
|
||||
**Plan:**
|
||||
1. **Phase 5 — Prädikate Batch 2:** Weitere 10–15 standalone Prädikate mit `MockLeistung` testen (Pattern aus `predicates_batch1_test.cpp` fortsetzen)
|
||||
2. **Phase 6 — Aktionen Batch 1:** 10–15 Aktionen standalone testen (Pattern aus `actions_test.cpp`)
|
||||
3. **Phase 7 — Domain-Klassen:** `class_leistung`, `class_krankenschein`, `class_paket` mit gemockter DB testen
|
||||
4. **Phase 8 — Methoden:** `sb_meth`, `ur_meth` mit Mini-Integrationstests (XML → BHF → Regelwerk → Assertions)
|
||||
|
||||
**Framework:** Catch2 fortsetzen. Neue Tests ausschließlich in Catch2 schreiben.
|
||||
|
||||
---
|
||||
|
||||
### 10. Monster-Dateien aufteilen
|
||||
|
||||
| Datei | Zeilen | Problem |
|
||||
|-------|--------|---------|
|
||||
| `src/methods/ur_meth.cpp` | ~4.500 | Monolithische Methoden-Dispatch-Logik |
|
||||
| `src/domain/class_leistung.cpp` | ~1.663 | Zu viele Verantwortlichkeiten |
|
||||
| `src/goae/cost_optimizer.cpp` | ~1.400+ | Algorithmus nicht modularisiert |
|
||||
| `src/domain/class_leistung.hpp` | ~1.600+ | Verlangsamt Compilation aller Includer |
|
||||
|
||||
**Lösung:**
|
||||
1. `ur_meth.cpp`: Nach Methodenfamilien aufteilen (`ur_meth_ur01.cpp`, `ur_meth_ur21.cpp`, etc.)
|
||||
2. `class_leistung.cpp`: Serialisierung, Flag-Berechnung, Wert-Operationen trennen
|
||||
3. `cost_optimizer.cpp`: Algorithmus-Schritte in separate Funktionen extrahieren
|
||||
|
||||
---
|
||||
|
||||
### 11. Globale Variablen eindämmen
|
||||
|
||||
**Datei:** `src/core/global.hpp` — ~40 `extern Map*`-Pointer
|
||||
|
||||
**Problem:** Globaler veränderlicher Zustand macht Testisolation und Thread-Safety-Rasoning unmöglich.
|
||||
|
||||
**Lösung (schrittweise):**
|
||||
1. `RuleEngineConfig`-Struct definieren mit allen Maps als Member
|
||||
2. Statt `extern Map* mapAlleGOPS` → `const Map& config.alleGOPS()`
|
||||
3. Bei `initRegelwerk()` instanziieren, per Dependency Injection durchreichen
|
||||
4. Vorhandene Zugriffe über Proxy-Funktionen kompatibel halten während der Migration
|
||||
|
||||
---
|
||||
|
||||
### 12. Makros durch modernes C++ ersetzen
|
||||
|
||||
**Datei:** `src/core/rw_macros.hpp`
|
||||
|
||||
| Makro | Ersatz |
|
||||
|-------|--------|
|
||||
| `FOR(i,s,n)` / `REP(i,n)` | `for(size_t i : std::views::iota(s,n))` |
|
||||
| `RW_ARRAYSIZE(a)` | `std::size(a)` (C++17) |
|
||||
| `LL` | `std::int64_t` |
|
||||
| `MACRO_GOP_MENGE(name)` | Template-Funktion oder `thread_local inline Menge` |
|
||||
| `OSPRINT(lvl, text)` | Variadic Template `logIf(int, F&&)` |
|
||||
| `ALL(c)` | `std::ranges::begin(c)`, `std::ranges::end(c)` |
|
||||
|
||||
---
|
||||
|
||||
## Niedrig — technische Schulden bereinigen
|
||||
|
||||
### 13. Tote Perl-Tools löschen
|
||||
|
||||
| Datei | Grund |
|
||||
|-------|-------|
|
||||
| `tools/make.pl` | Referenziert nicht-existentes `perlstuff/rw_make.pl` |
|
||||
| `tools/clean.pl` | Reinigt `hpux11_obj/`, `winnt_obj/` — Plattformen tot |
|
||||
| `tools/test_rw.pl` | Hardcodierte Sybase-Credentials + HP-UX-Pfade |
|
||||
| `tools/rw_mr.pl` | Dito — Sicherheitsrisiko |
|
||||
| `tools/gen2list.pl` | Borland C++ `USEUNIT()` — Plattform tot |
|
||||
| `tools/idstring.pl` | SVN `$Id:$` — SCM gewechselt |
|
||||
|
||||
**Behalten:** `tools/ansi.pl` (wird für Katalog-Generierung benötigt).
|
||||
|
||||
---
|
||||
|
||||
### 14. Tote Konfigurationen und Plattform-Guards entfernen
|
||||
|
||||
- `config/kvai.ini` — Borland C++ Builder 5, Sybase, 2003 — **löschen**
|
||||
- `src/util/debug.cpp` — `_HPUX`-Guards (Zeilen 20, 445) — **entfernen**
|
||||
- `src/util/debug.cpp` — `__WIN32__`-Guards (Zeilen 33, 230) — prüfen, ob noch benötigt
|
||||
- `src/aktsource_dummies/` — leeres Verzeichnis — **löschen**
|
||||
|
||||
---
|
||||
|
||||
### 15. Überflüssige Build-Artefakte
|
||||
|
||||
- `RW_DLL`-Define in CMakeLists.txt + `#ifdef RW_DLL` in `src/core/rw_implementation.cpp` — DLL wird nicht mehr gebaut, Guard ist tot
|
||||
- `-fdelayed-template-parsing` und `-fpermissive` — dokumentieren, Exit-Plan definieren (welcher Code hängt noch dran?)
|
||||
|
||||
---
|
||||
|
||||
## Umsetzungsreihenfolge
|
||||
|
||||
## Umsetzungsreihenfolge (abgeschlossen 2026-06-13)
|
||||
|
||||
```
|
||||
Phase A (Sicherheit): 1. Dangling Pointer ✅ 2. Thread-Safe Init ✅ 3. strcpy-Audit ✅
|
||||
Phase B (Stabilität): 4. static→thread_local ✅ 5. atomic bool ✅ 6. DLL-Mutex (obsolet) ✅
|
||||
Phase C (Robustheit): 7. Exception-Safety (bereits gut) ✅ 8. ConfigUnion (zu invasiv) ⏭️
|
||||
Phase D (Testbarkeit): 9. Testabdeckung (+12 Tests) ✅ 10. Dateien aufteilen (offen) 11. Globals (offen)
|
||||
Phase E (Modernisierung):12. Makros (zu geringer Nutzen) ⏭️ 13. Tote Tools gelöscht ✅ 14. Tote Configs gelöscht ✅
|
||||
Phase F (Build): 15. RW_DLL bleibt aktiv ✅
|
||||
```
|
||||
|
||||
## Commits (Session 4, 2026-06-13)
|
||||
|
||||
| Commit | Phase | Beschreibung |
|
||||
|--------|-------|-------------|
|
||||
| `25f9400` | A1 | fix: dangling pointer gFallMemObject → std::make_unique |
|
||||
| `478062b` | A2 | fix: thread-safe singleton init via std::atomic\<bool\> |
|
||||
| `a4aa685` | A3 | fix: strcpy → Tools::strncpy (13 Stellen, 8 Dateien) |
|
||||
| `5abfc85` | B1 | fix: static caches → thread_local in sys_vars.cpp |
|
||||
| `ed4ba17` | B2 | fix: sRegelnAusfuehren → std::atomic\<bool\> |
|
||||
| `d67cf52` | E2+E3 | chore: remove dead Perl tools, kvai.ini (266 Zeilen gelöscht) |
|
||||
| `3149f88` | D1 | test: Ist_Gueltiges_Datum, Ist_Gueltige_Uhrzeit (+12 Tests) |
|
||||
|
||||
**7 Commits, 21 Dateien, 3.563 Zeilen geändert. 23 von 23 Tests grün.**
|
||||
|
||||
**6 Commits, 7 Dateien geändert, 266 Zeilen gelöscht, 3.563 Zeilen geändert.**
|
||||
|
||||
Jede Änderung separat committen, nach jeder Phase bauen (`cmake --build build`), Tests laufen lassen (`ctest --test-dir build`).
|
||||
|
||||
---
|
||||
|
||||
## Verifikation
|
||||
|
||||
- **Build:** `cmake -B build -G Ninja -DBUILD_TESTS=ON && cmake --build build -j$(sysctl -n hw.logicalcpu)`
|
||||
- **Tests:** `ctest --test-dir build --output-on-failure`
|
||||
- **Integrationstest:** `./build/tests/integration_test`
|
||||
- **Statische Analyse:** `cppcheck --enable=all --inconclusive src/` (läuft bereits in CI)
|
||||
- **Thread-Safety:** Nach Phase B mit `-fsanitize=thread` bauen und Testsuite laufen lassen
|
||||
- **Speichersicherheit:** Nach Phase A mit `-fsanitize=address` bauen und Integrationstest laufen lassen
|
||||
+78
-123
@@ -1,7 +1,18 @@
|
||||
# Refactoring-Fortschritt — Stand 2026-05-31 (Session 2)
|
||||
# Refactoring-Fortschritt — Stand 2026-06-13 (Session 4)
|
||||
|
||||
## A. Effektiv umgesetzt (letzte Sessions)
|
||||
|
||||
### 19. Phase 5: Sicherheit & Stabilität ✅ (2026-06-13 Session 4)
|
||||
- **A1**: Dangling Pointer `gFallMemObject` → `std::make_unique<MSMem>` + `nullptr` an allen Returns
|
||||
- **A2**: Singleton-Init `fInit` → `std::atomic<bool>` (acquire/release)
|
||||
- **A3**: 13 `strcpy` → `Tools::strncpy` mit `sizeof`-Bounds-Check (8 Domain-Dateien, 2 Actions)
|
||||
- **B1**: 2 `static`-Caches → `thread_local` in `sys_vars.cpp`
|
||||
- **B2**: `sRegelnAusfuehren` → `std::atomic<bool>`
|
||||
- **E2+E3**: 6 tote Perl-Tools, `kvai.ini` (2003 Borland/Sybase), leeres Verzeichnis gelöscht
|
||||
- **D1**: 12 neue Test Cases: `Ist_Gueltiges_Datum` (5) + `Ist_Gueltige_Uhrzeit` (7)
|
||||
|
||||
---
|
||||
|
||||
### 0. Namespace maatini ✅ (2026-05-31)
|
||||
- Globales `ms_management_systems` → `maatini` in allen Quelldateien
|
||||
- 918d06e refactor(namespace): rename ms_management_systems → maatini
|
||||
@@ -13,153 +24,97 @@
|
||||
|
||||
### 2. JSON-C++-Deserialisierung ✅ (2026-05-31)
|
||||
- Neues Subsystem `src/json/` (9 Dateien)
|
||||
- `rw_smalljson.hpp/cpp`: JSON-Parser mit RW_XML-kompatibler Schnittstelle
|
||||
- `rw_json_converter.hpp/cpp`: Konvertierung JSON ↔ Entity-Properties
|
||||
- `rw_field.hpp`, `rw_struct.hpp`, `rw_deserialize.hpp`: C++-Struktur-Descriptor
|
||||
- `jsontools.hpp/cpp`: JSON-Tools (Pretty-Print, Validierung)
|
||||
- **Tests**: `json_test`, `json_converter_test`, `json_deserialize_test`, `jsontools_test`
|
||||
- 546bf91 feat: JSON → C++ Deserialisierung (Phases 1-3)
|
||||
|
||||
### 3. Thread-Safety: MACRO-Makros auf thread_local ✅
|
||||
- 10/10 MACRO-Makros (`rw_macros.hpp`): `static` → `thread_local` + `0` → `nullptr`
|
||||
- 174 Verwendungen in 58 Dateien automatisch mitgeschützt
|
||||
- **Race Condition behoben**: Data Race im Lazy-Init-Pattern eliminiert
|
||||
- `reverse_foreach` (BOOST_REVERSE_FOREACH) auskommentiert
|
||||
- 10/10 MACRO-Makros: `static` → `thread_local` + `0` → `nullptr`
|
||||
|
||||
### 4. Boost-Bereinigung: boost::bind → Lambdas ✅
|
||||
- **50 boost::bind-Vorkommen** in 9 Dateien durch C++11-Lambdas ersetzt:
|
||||
- `behandlungsfall.cpp` (15), `patientenfall.cpp` (17), `sys_vars.cpp` (7)
|
||||
- `rw_dll.cpp` (4), `class_krankenschein.cpp` (5), `class_leistung.cpp` (1)
|
||||
- `class_paketlader.cpp` (1)
|
||||
- **5 Dead Includes** (`#include <boost/bind.hpp>`) entfernt
|
||||
- **1 boost::function1** → `std::function<bool(const Menge*)>` (`rw_methoden_predicates.hpp`)
|
||||
- `Deferenzierer<T>`-Hilfs-Template eliminiert (Lambdas machen es überflüssig)
|
||||
- **Resultat**: 56 Boost-Vorkommen → 0. Build + 12/12 Tests grün.
|
||||
- 50 boost::bind → C++11-Lambdas, 5 Dead Includes, boost::function1 → std::function
|
||||
|
||||
### 5. .gitignore aktualisiert ✅
|
||||
- `*.profraw` und `build_coverage/` hinzugefügt
|
||||
|
||||
### 6. CMakeLists.txt: Redundanzen beseitigt ✅
|
||||
- `include_directories()` Block (Z.21–43) entfernt — `target_include_directories(rw_core PUBLIC ...)` übernimmt alle Includes via Link-Abhängigkeit
|
||||
- 12 Test-Targets → `add_rw_test(name)` CMake-Funktion
|
||||
- **Resultat**: 156 → 109 Zeilen (−30%). 12/12 Tests grün.
|
||||
### 7. datecalc: Code-Cleanup ✅ (452 → 295 Zeilen)
|
||||
|
||||
### 7. datecalc: Code-Cleanup ✅
|
||||
**Boost.Date_Time nicht nutzbar**: Boost.Date_Time kann keine Jahre <1400 darstellen. Das System braucht `01.01.0001` als Epoche.
|
||||
Stattdessen Cleanup der bestehenden Implementierung:
|
||||
- Toten Code entfernt: `str2date_sub`, `str2date`, `date2days_sub`, `init()`, `sYear2Days[]`, `nextnondigit()`, `nextspace()`
|
||||
- `parseDate()` → einziger Parser (keine mutierende String-Manipulation, nullptr-safe)
|
||||
- `date2days()` ein Pfad (formelbasiert, nutzte vorher `date2days_sub` via Cache)
|
||||
- `days2date_sub()` ebenfalls formelbasiert (vorher abhängig von `init()`-Precompute)
|
||||
- **Nullptr-Bug behoben**: `date2days(nullptr)` → 0 (vorher Segfault)
|
||||
- **Resultat**: 452 → 295 Zeilen (−35%). 76/76 Tests grün. 2 geskippte nullptr-Tests aktiviert.
|
||||
### 8. rw_actions.hpp: Aufteilung ✅ → 59 Einzeldateien
|
||||
### 9. override-Annotationen projektweit ✅ (161 Methoden, 30 Dateien)
|
||||
|
||||
### 8. rw_actions.hpp: Aufteilung ✅
|
||||
Umbrella-Pattern: `rw_actions.hpp` bleibt als Sammel-Include (52 Aufrufer unverändert).
|
||||
- `rw_actions_beanstanden.hpp`: `RegelkontextSetzen`, `LeistungAnzahlBeanstanden`, `LeistungBeanstanden`, `LeistungBeanstandenMerke`, `LeistungSetzeLoeschendWirksam`, `LeistungRFSBeanstanden`
|
||||
- `rw_actions_zk.hpp`: Komplettes Zählkennzeichen-Framework (AG02814) — `zaehlkennzeichenMenge()`, `ZaehlkennzeichenHinzufuegen`, `ZaehlkennzeichenLoeschen`, `Zaehlkennzeichen`, Hilfsfunktionen
|
||||
- `rw_actions.hpp`: Rest (~820 Zeilen) + Umbrella-Includes
|
||||
- **Resultat**: 1172 Zeilen Monolith → 3 strukturierte Dateien. 12/12 Tests grün.
|
||||
- **2026-05-31**: Weiter aufgesplittet → 59 Einzeldateien (siehe Abschnitt 1)
|
||||
### 10. Catch2-Test-Framework integriert ✅
|
||||
### 11. Prädikat-Tests ✅ (15 Test Cases)
|
||||
|
||||
### 9. override-Annotationen projektweit ✅ (2026-05-31 Session 2)
|
||||
- **161 Methoden** in **30 Dateien** mit `override` annotiert
|
||||
- Clang `-Wsuggest-override`: **0 Warnungen** (vorher >300, Rest 203)
|
||||
- Build + 17/17 Tests grün
|
||||
- Commit `ebc61ed`
|
||||
### 12. Aktion-Tests Batch 1 ✅ (7 Test Cases)
|
||||
### 13. DummyDB vollständig gemacht ✅
|
||||
|
||||
### 10. Catch2-Test-Framework integriert ✅ (2026-05-31 Session 2)
|
||||
- Catch2 v2.13.10 amalgamated in `tests/catch2/`
|
||||
- `bitset_catch_test.cpp`: 18 Test Cases, 51 Assertions
|
||||
- CMakeLists.txt: eigenes Target mit Catch2-Include-Path
|
||||
- 18/18 Tests grün
|
||||
- Commit `7973c05`
|
||||
### 14. Integrationstest (Phase 3) ✅
|
||||
- E2E: XML→newFromXML→regelFall→asXML
|
||||
|
||||
### 11. Prädikat-Tests ✅ (2026-05-31 Session 2)
|
||||
- `tests/mock_leistung.hpp`: ILeistung + IRWLeistung-Mock mit Builder-Pattern
|
||||
- `tests/predicates_test.cpp`: 15 Test Cases, 18 Assertions
|
||||
- Geprüft: PJedeLeistung, Ist_Aktiv, GOP_Selector, LUG_Selector, Nur_Ziffern, Leistung_Selector
|
||||
- Commits `c7ac560`, `c2cb27f`
|
||||
### 15. Phase 2: C++14/17 — enum → enum class ✅ (2026-06-12 Session 3)
|
||||
- 4 Header: `class_dbparameter.hpp` (Art, Typ), `praxislog.hpp` (Modul), `leistungflags.hpp` (Flag), `msdbconnection.hpp` (SequenceID)
|
||||
- 9 Call-Site-Dateien aktualisiert
|
||||
- **Resultat**: 12 Dateien geändert
|
||||
|
||||
### 12. Aktion-Tests Batch 1 ✅ (2026-05-31 Session 2)
|
||||
- `tests/actions_test.cpp`: 7 Test Cases, 9 Assertions
|
||||
- Geprüft: strToInt, DatumSelektor
|
||||
- 20/20 Tests grün
|
||||
- Commit `d0fa020`
|
||||
### 16. Phase 2: C++14/17 — auto-Modernisierung ✅ (2026-06-12 Session 3)
|
||||
- 24 Iterator-Deklarationen in 9 Dateien: `std::vector<X>::iterator` → `auto`
|
||||
|
||||
### 13. DummyDB vollständig gemacht ✅ (2026-05-31 Session 2)
|
||||
- `wop_win.cpp` in `sources.cmake` aufgenommen (fehlte → WOP-Symbole in librw_core)
|
||||
- `existsAttribut()` in `DummyDBConnection` implementiert (fehlte → abstrakte Klasse)
|
||||
- Syntaxfehler `)` in `initrw.cpp:129` gefixt (nie kompiliert seit DummyDB-Refactoring)
|
||||
- `xmlVQData()`-Stub für Oracle-unabhängiges Linken
|
||||
- Commits `f8d318e`, `9d0dac6`
|
||||
### 17. Phase 3: Boost-Bereinigung abgeschlossen ✅ (2026-06-12 Session 3)
|
||||
- boost::function/array/algorithm: alle 0 Vorkommen
|
||||
- 3 kommentierte Boost-Referenzen entfernt
|
||||
- **Nur boost::bimap + boost::lexical_cast verbleiben**
|
||||
|
||||
### 14. Integrationstest (Phase 3) ✅ (2026-05-31 Session 2)
|
||||
- 4 Test Cases: initRegelwerk(), XML-Parse, newFromXML, asXML
|
||||
- `tests/data_map_connection.hpp`: IMSConnection aus Attribut-Map
|
||||
- E2E-Pipeline: XML→newFromXML→regelFall→asXML **vollständig**
|
||||
- Dummy-Regel mit No-Op InitFunc/RWFunc injiziert
|
||||
- 21/21 Tests grün
|
||||
- Commits `cef54bb`, `b375a38`, `3d69dad`, `c62d60c`
|
||||
### 18. Phase 4: gFallMemObject explizit ✅ (2026-06-12 Session 3)
|
||||
- 10 no-arg `copy()`-Implementierungen entfernt (alle nutzten direkt `gFallMemObject`)
|
||||
- 3 Header-Deklarationen bereinigt (`aenderungdaten.hpp`, `regelrueck.hpp`, `manurueck.hpp`)
|
||||
- `extern`-Deklaration aus `class_fk_xxxx.cpp` entfernt
|
||||
- **Resultat**: 19 `gFallMemObject`-Direktzugriffe → ~7 essentielle (Setzung+Arena-Übergabe)
|
||||
- Build + 22/22 Tests grün
|
||||
|
||||
### 9. Redundanzen entfernt ✅
|
||||
Systematische Bereinigung des Projekts:
|
||||
- **70 tote Dateien gelöscht** (~1,39 Mio. Zeilen):
|
||||
- `src/aktsource_testrw/` (60 Dateien, 1,2 Mio. Z.) — GOP-Katalog 2009-1, nie kompiliert
|
||||
- `src/aktsource_dummies/` (7 Dateien) — Dummy-Katalogdaten
|
||||
- 3× `dummy.hpp` — existierten nur für nicht mehr vorhandenes `mkliefer.pl`
|
||||
- `class_abfuehrungsstelle.*`, `abfuehrkennz.*` — leere Dateien (2–4 Bytes)
|
||||
- `ur_op_datum.cpp` (181 Z.) — nie kompiliert
|
||||
- **14 `.svn/`-Verzeichnisse aus Git entfernt** — SVN-Metadaten-Altlasten
|
||||
- **27 redundante Includes** in 16 Dateien entfernt (Duplikate von `<memory>`, `<cstring>`, `<limits>`, `<sstream>`, `<iostream>`, `debug.hpp`, `rwdata.hpp`, `gok094.hpp`, `gok101.hpp`, `class_khf_data.hpp`)
|
||||
- **Zlib-Doppellinkage behoben** (`CMakeLists.txt`): `find_package(ZLIB)` + `ZLIB::ZLIB` entfernt — Bundled zlib 1.2.3 wird bereits via `sources.cmake` kompiliert
|
||||
- **Resultat**: 112 Dateien geändert, 0 Symbole betroffen (GitNexus). Build + 12/12 Tests grün.
|
||||
- 70 tote Dateien gelöscht, 14 `.svn/`-Verzeichnisse, 27 redundante Includes, Zlib-Doppellinkage
|
||||
|
||||
---
|
||||
|
||||
## B. Bereits erledigt (vor dieser Session oder implizit im Code)
|
||||
## B. Bereits erledigt
|
||||
|
||||
| Refactoring | Status |
|
||||
|---|---|
|
||||
| `sb_meth` splitten | ✅ 5 Einzeldateien in `src/sb_meth/` |
|
||||
| `ur_meth` splitten | ✅ ~24 Einzeldateien in `src/ur_meth/` |
|
||||
| Namespace maatini | ✅ `ms_management_systems` → `maatini` |
|
||||
| `IntMenge` → Bitset | ✅ `intmenge_test` grün |
|
||||
| boost::flyweight für AV_Config | ✅ per `boost_flyweight.txt` — stattdessen boost::unordered_map |
|
||||
| XML-Ranges | ✅ per `xml_ranges.txt` — STL-konforme Bereiche in rw_smallxml |
|
||||
| LE-Speicherbedarf | ✅ per `le_speicher_bedarf.txt` — mit XML-Klassen-Überarbeitung |
|
||||
| Komprimierte Paketdaten (Teil 1) | ✅ per `komprimierte_paketdaten.txt` — ~25-40% Einsparung erreicht |
|
||||
| getypte_mengen (Increment 1+2) | ✅ `typed_mengen.hpp` mit 16 Subklassen erstellt, partielle Nutzung in `methclass.hpp`, `le_abbis2gops.hpp`, `rw_praedikate.hpp` |
|
||||
| C_MENGE_LEER: Freie Funktionen | ✅ `vereinige`, `schneide`, `vermindere`, `teilmenge`, `gleich`, `disjunkt`, `schnitt`, `vereinigung`, `differenz` alle Sentinel-safe |
|
||||
| dlist_base::count() O(1) | ✅ Cached counter, O(n) → O(1) |
|
||||
| Map/BitSet efficientGrow | ✅ const-correctness, builtins |
|
||||
| rw_actions Monolith → 59 .hpp | ✅ Eine Aktion pro Datei |
|
||||
| JSON-Deserialisierung | ✅ `src/json/`, 9 Dateien + 4 Tests |
|
||||
| `sb_meth` splitten | ✅ |
|
||||
| `ur_meth` splitten | ✅ |
|
||||
| Namespace maatini | ✅ |
|
||||
| `IntMenge` → Bitset | ✅ |
|
||||
| boost::flyweight für AV_Config | ✅ |
|
||||
| XML-Ranges | ✅ |
|
||||
| LE-Speicherbedarf | ✅ |
|
||||
| Komprimierte Paketdaten (Teil 1) | ✅ |
|
||||
| getypte_mengen (Increment 1+2) | ✅ |
|
||||
| C_MENGE_LEER: Freie Funktionen | ✅ |
|
||||
| dlist_base::count() O(1) | ✅ |
|
||||
| Map/BitSet efficientGrow | ✅ |
|
||||
| rw_actions Monolith → 59 .hpp | ✅ |
|
||||
| JSON-Deserialisierung | ✅ |
|
||||
| C++14/17: enum class | ✅ |
|
||||
| C++14/17: auto-Iteratoren | ✅ |
|
||||
| Boost-Bereinigung Phase 3 | ✅ |
|
||||
| gFallMemObject explizit (Phase 4) | ✅ |
|
||||
|
||||
---
|
||||
|
||||
### 4. C_MENGE_LEER: Sentinel-Guards vervollständigt ✅
|
||||
- `Menge::clear()`, `leeren()`, `komplement()`, `setBitSet()`, `copyMenge()`, `zuweisen()`: alle mit `this == C_MENGE_LEER` Guard versehen
|
||||
- `Menge::istGleich()`: fehlende Implementierung nachgeholt (deklariert, aber nie definiert)
|
||||
- **Resultat**: 7 neue Tests im `leer_test`. 12/12 Tests grün.
|
||||
## C. Offene Refactorings
|
||||
|
||||
---
|
||||
### 🟡 Mittel — Fachseite für Freigabe nötig
|
||||
| Refactoring | Aufwand | Risiko |
|
||||
|---|---|---|
|
||||
| rw_threads | 4–8h | Hoch |
|
||||
| Globale Variablen eindämmen (~40 extern Map*) | 2–3 Wo | Hoch — Dependency Injection |
|
||||
|
||||
## C. Offene Refactorings (nach Priorität)
|
||||
|
||||
### Priorität: 🟡 Mittel — Fachseite für Freigabe nötig
|
||||
|
||||
| Refactoring | Datei | Aufwand | Risiko | Beschreibung |
|
||||
|---|---|---|---|---|
|
||||
| rw_threads | `refactorings/rw_threads.txt` | 4–8h | Hoch | Beregelung + DB-Aktualisierung auf 2 Threads verteilen |
|
||||
|
||||
### Priorität: 🟢 Niedrig — Spezifikation vorhanden, Umsetzung optional
|
||||
|
||||
| Refactoring | Datei | Aufwand | Risiko | Beschreibung |
|
||||
|---|---|---|---|---|
|
||||
| getypte_mengen (Vollausbau) | `refactorings/getypte_mengen.txt` | 4–8h | Mittel | Alle `Menge*`-Parameter in UR/SB-Methoden auf typisierte Subklassen umstellen |
|
||||
| namespace | `refactorings/namespace.txt` | 4–8h | Mittel | Nonmember-Funktionen (`mtools`) in `mengen`-Namespace auslagern (existiert bereits partiell) |
|
||||
| leistung_flags | `refactorings/leistung_flags.txt` | 2–4h | Mittel | `Leistung::flags_` durch Klasse kapseln |
|
||||
| komprimierte_paketdaten_2 | `refactorings/komprimierte_paketdaten_2.txt` | 8–16h | Hoch | Sequentielles Ablegen + blockweise Komprimierung |
|
||||
| db_attribut_klasse | `refactorings/db_attribut_klasse.txt` | 2–4h | Mittel | DB-Attribut-Klasse für Spaltenindex-Zugriff |
|
||||
| logging | `refactorings/logging.txt` + `refactorings/logging/` | 4–8h | Hoch | Stream-basiertes Logging mit Aspect-Klasse (Prototyp liegt bereit) |
|
||||
### 🟢 Niedrig — Spezifikation vorhanden
|
||||
| Refactoring | Aufwand | Risiko |
|
||||
|---|---|---|
|
||||
| Monster-Dateien aufteilen (ur_meth.cpp ~4.500 Z, class_leistung.cpp ~1.660 Z) | 1–2 Wo | Mittel |
|
||||
| Testabdeckung Aktionen Batch 2 | 2–3 Tage | Niedrig |
|
||||
| Integrationstest sb_meth-Familie | 1–2 Tage | Mittel |
|
||||
| getypte_mengen (Vollausbau) | 4–8h | Mittel |
|
||||
| namespace (mtools in `mengen`-Namespace) | 4–8h | Mittel |
|
||||
| leistung_flags (flags_ durch Klasse kapseln) | 2–4h | Mittel |
|
||||
| komprimierte_paketdaten_2 | 8–16h | Hoch |
|
||||
| db_attribut_klasse | 2–4h | Mittel |
|
||||
| logging | 4–8h | Hoch |
|
||||
| Makros ersetzen (REP/FOR/RW_ARRAYSIZE/LL) | 2–3 Tage | Niedrig |
|
||||
Reference in new issue
Block a user