meldestelle/docs/01_Architecture/Roadmap_ZNS_Importer.md

4.8 KiB

type status owner last_update
Roadmap IN_PROGRESS Curator 2026-03-25

Roadmap: ZNS-Importer (MVP)

  1. 🏗️ [Lead Architect] | 5. April 2026

Kontext: Der ZNS-Importer wurde für die Verarbeitung der Datei RICHT01.dat optimiert. Es wurde klargestellt, dass Richter (SatzID 'X') und Parcoursbauer (SatzID 'Y') gemeinsam in dieser Datei geliefert werden. Eine separate PARCO01.dat existiert nicht. 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 kombiniert in einer Datei)

2. Phasen & Aufgabenverteilung

Phase 1: Backend-Infrastruktur & Parsing (👷 Backend Developer)

  • 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).
  • Job-Management:
  • Thread-sichere In-Memory-Registry (ImportJobRegistry, ConcurrentHashMap) implementiert.
  • Status-Enum: AUSSTEHEND, ENTPACKEN, LADE_VEREINE, LADE_REITER, LADE_PFERDE, LADE_RICHTER, ABGESCHLOSSEN, FEHLER.
  • Unzip-Service:
  • ZIP-Entpackung in-memory implementiert (ZnsImportService).
  • Legacy-Parser (CP850 Fixed-Width):
  • ZnsLegacyParsers in core:zns-parser (KMP-Modul) implementiert.
  • Alle 4 Dateitypen (VEREIN01, LIZENZ01, PFERDE01, RICHT01) bytegenau gemappt. RICHT01 verarbeitet Richter ('X') und Parcoursbauer ('Y').

Phase 2: Domain-Mapping & Persistenz (👷 Backend Developer)

  • 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.
  • 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)

  • 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.
  • 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.
  • 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.