--- type: Roadmap status: IN_PROGRESS owner: Curator last_update: 2026-03-25 --- # Roadmap: ZNS-Importer (MVP) đŸ§č **[Curator]** | 25. MĂ€rz 2026 **Kontext:** Um den `registration-context` und `actor-context` unter realistischen Bedingungen testen zu können, benötigen wir echte Stammdaten (Reiter, Pferde, Vereine, FunktionĂ€re). Diese Daten werden vom ÖPS (Österreichischer Pferdesportverband) in Form einer `ZNS.zip` bereitgestellt. **Ziel:** Entwicklung eines asynchronen, robusten Importers fĂŒr die Legacy-ZNS-Daten (`ZNS.zip`), der ĂŒber die Compose-Desktop-App gesteuert wird und die Daten persistent im Backend (`actor-context`) ablegt. --- ## 1. Spezifikationen & Rahmenbedingungen * **Dateiformat:** Fixed-Width ASCII (Feste Spaltenbreiten, keine Trennzeichen). * **Encoding:** Zwingend **Codepage 850 (CP850)**. (Achtung: Umlaute!). * **Architektur-Muster:** Asynchroner Upload & Processing (Job-Pattern). * **Import-Reihenfolge (AbhĂ€ngigkeiten beachten!):** 1. `VEREIN01.dat` (Vereine) 2. `LIZENZ01.dat` (Reiter/Lizenzen) 3. `PFERDE01.dat` (Pferde - benötigt Vereins-ID) 4. `RICHT01.dat` (Richter/Parcoursbauer) --- ## 2. Phasen & Aufgabenverteilung ### Phase 1: Backend-Infrastruktur & Parsing (đŸ‘· Backend Developer) * [x] **API Design:** * `POST /api/v1/import/zns` (Multipart/form-data, nimmt `.zip` oder `.dat` entgegen). * RĂŒckgabe: `202 Accepted` mit einer `JobId` (UUID). * `GET /api/v1/import/zns/{jobId}/status` (Gibt aktuellen Fortschritt und Statusmeldungen zurĂŒck). * Implementiert in `backend:services:zns-import:zns-import-service` (`ZnsImportController`). ✅ * [x] **Job-Management:** * Thread-sichere In-Memory-Registry (`ImportJobRegistry`, `ConcurrentHashMap`) implementiert. * Status-Enum: `AUSSTEHEND`, `ENTPACKEN`, `LADE_VEREINE`, `LADE_REITER`, `LADE_PFERDE`, `LADE_RICHTER`, `ABGESCHLOSSEN`, `FEHLER`. ✅ * [x] **Unzip-Service:** * ZIP-Entpackung in-memory implementiert (`ZnsImportService`). * [x] **Legacy-Parser (CP850 Fixed-Width):** * `ZnsLegacyParsers` in `core:zns-parser` (KMP-Modul) implementiert. * Alle 4 Dateitypen (VEREIN01, LIZENZ01, PFERDE01, RICHT01) bytegenau gemappt. 4 Unit-Tests grĂŒn. ### Phase 2: Domain-Mapping & Persistenz (đŸ‘· Backend Developer) * [x] **Mapper-Logik:** * `DomVerein`, `DomReiter`, `DomPferd`, `DomFunktionaer` vollstĂ€ndig gemappt. * *SonderfĂ€lle umgesetzt:* * `PFERDE01.dat`: AuslĂ€ndische Systemnummern werden ignoriert. ✅ * `LIZENZ01.dat`: Sperrlisten-Flag (`S`) korrekt auf `DomReiter` gemappt. ✅ * [x] **Upsert-Strategie (DB):** * `ZnsImportService` implementiert find + save Logik (Upsert). 7 Unit-Tests grĂŒn. * Fehler pro Zeile werden gesammelt (kein Abbruch bei Einzelfehlern). `ZnsImportResult` mit ZĂ€hlern & Fehlerlisten. ### Phase 3: Frontend-Integration (🎹 Frontend Expert) * [x] **UI-Komponenten (Compose Desktop):** * `StammdatenImportScreen` in `meldestelle-desktop` erstellt. ✅ * Nativer File-Picker (`JFileChooser`, nur `.zip`) integriert. ✅ * `AppScreen.StammdatenImport` + Nav-Rail-Eintrag "Stammdaten-Import" hinzugefĂŒgt. ✅ * [x] **Netzwerk & State-Management (KMP):** * `ZnsImportViewModel` mit Ktor Multipart-Upload (`POST /api/v1/import/zns`). ✅ * Polling-Mechanismus (alle 2 Sekunden, `GET /api/v1/import/zns/{jobId}/status`). ✅ * `ZnsImportViewModel` via Koin `viewModel { }` in `desktopModule` registriert. ✅ * [x] **User Feedback:** * `LinearProgressIndicator` mit Live-Prozent + `progressDetail`-Text. ✅ * `StatusChip` fĂŒr alle Job-ZustĂ€nde (AUSSTEHEND → ABGESCHLOSSEN/FEHLER). ✅ * Fehler-Banner + scrollbare Fehler-Liste (max. 50 EintrĂ€ge). ✅ ### Phase 4: Testing & QA (🧐 QA Specialist) * [ ] **Test-Datensatz prĂŒfen:** * Einlesen der `docs/OePS/ZNS.zip` und ÜberprĂŒfung der Umlaute (CP850 Encoding Test). * [ ] **AbhĂ€ngigkeits-Test:** * Sicherstellen, dass Pferde korrekt ihren Vereinen zugeordnet werden. * [ ] **Edge-Cases:** * Upload einer fehlerhaften Zip-Datei. * Abbruch des Uploads/Imports. --- ## 3. Offene Fragen / Risiken * Werden die Legacy-Daten in der Datenbank (PostgreSQL) mit UUIDs oder mit den ZNS-Satznummern als Primary Keys abgelegt? * *Architektur-Beschluss:* Wir sollten interne UUIDs als Primary Keys verwenden und die ZNS-Nummern als eindeutige Business-Keys (`UNIQUE CONSTRAINT`) ablegen. * Wie gehen wir mit gelöschten DatensĂ€tzen aus dem ZNS um? * *Vorerst:* Der ZNS-Import ist ein "Add/Update"-Only Vorgang. Löschungen mĂŒssen manuell oder in einer spĂ€teren Phase synchronisiert werden.