From 4e8ed21ac09a899398d47cd62876626679a360bc Mon Sep 17 00:00:00 2001 From: Stefan Mogeritsch Date: Wed, 25 Mar 2026 12:19:58 +0100 Subject: [PATCH] feat(docs): add ZNS-Importer roadmap and update MASTER_ROADMAP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Documented `Roadmap_ZNS_Importer.md` outlining goals, phases, and specifications for the ZNS importer MVP. - Updated `MASTER_ROADMAP.md` to include ZNS roadmap reference and detailed task breakdown for ZNS importer. - Marked progress on ÖTO/FEI rulebook tasks for CAN and CVN, with partial resolutions documented. Signed-off-by: Stefan Mogeritsch --- docs/01_Architecture/MASTER_ROADMAP.md | 28 +++++- docs/01_Architecture/Roadmap_ZNS_Importer.md | 97 ++++++++++++++++++++ 2 files changed, 120 insertions(+), 5 deletions(-) create mode 100644 docs/01_Architecture/Roadmap_ZNS_Importer.md diff --git a/docs/01_Architecture/MASTER_ROADMAP.md b/docs/01_Architecture/MASTER_ROADMAP.md index fca15840..39143362 100644 --- a/docs/01_Architecture/MASTER_ROADMAP.md +++ b/docs/01_Architecture/MASTER_ROADMAP.md @@ -2,18 +2,18 @@ type: Roadmap status: ACTIVE owner: Lead Architect -last_update: 2026-03-24 +last_update: 2026-03-25 --- # MASTER ROADMAP: Meldestelle-Biest -🏗️ **[Lead Architect]** | 24. März 2026 +🏗️ **[Lead Architect]** | 25. März 2026 **Strategisches Ziel:** Entwicklung einer ÖTO-konformen, offline-fähigen Turnier-Meldestelle als Compose Desktop App (KMP). Vollständige Self-Hosted Infrastruktur (Gitea, Pangolin, Zora). Datensouveränität, Offline-First, saubere Wissensbasis. -**Aktueller technischer Stand (24.03.2026):** +**Aktueller technischer Stand (25.03.2026):** * **Infrastruktur:** ✅ "Zora" (MS-R1, ARM64) ist live. Gitea & Registry laufen. * **Networking:** ✅ Pangolin Tunnel ersetzt Cloudflare. * **CI/CD:** ✅ Gitea Actions mit ARM64-Runner (VM 102) aktiv. Docker-Publish Pipeline grün. @@ -125,11 +125,28 @@ und über definierte Schnittstellen kommunizieren. #### 📜 Agent: ÖTO/FEI Rulebook Expert -* [ ] **Voltigieren (CVN):** Abteilungs-Trennungsregeln aus B-Teil § 400 ff. auswerten (offene Frage #3). -* [ ] **Fahren (CAN):** Starter-Schwellenwerte jenseits der Reitertreffen-Regel klären (offene Frage #4). +* [x] **Voltigieren (CVN):** Abteilungs-Trennungsregeln aus B-Teil § 400 ff. ausgewertet (offene Frage #3 teilweise + geklärt). + → B IV enthält keine eigenen Regeln – verweist auf OEPS-Reglement CVN. § 39 Abs. 1 gilt nicht für CVN. § 39 Abs. + 2 (> 80 Starter) gilt als Fallback. + → `docs/03_Domain/02_Reference/OETO_Regelwerk/Abteilungs-Trennungs-Schwellenwerte.md` (Abschnitt 2.6) +* [x] **Fahren (CAN):** Starter-Schwellenwerte jenseits der Reitertreffen-Regel geklärt (offene Frage #4 teilweise + geklärt). + → B VII enthält keine eigenen Regeln – verweist auf OEPS-Reglement „Turnierordnung für Gespanne". § 39 Abs. 1 gilt + nicht für CAN. § 39 Abs. 2 (> 80 Starter) gilt als Fallback. Einzige gesicherte Lizenzregel: § 850 Abs. 9 (F1+ bei + Fahrertreffen). + → `docs/03_Domain/02_Reference/OETO_Regelwerk/Abteilungs-Trennungs-Schwellenwerte.md` (Abschnitt 2.5) * [x] **Warn-Logik:** Spezifikation der `competition-context` Warn-Logik für Abteilungs-Schwellenwerte. → `docs/03_Domain/02_Reference/OETO_Regelwerk/Warn-Logik-Spezifikation-competition-context.md` +#### 🧹 Agent: Curator & Lead Architect (ZNS-Importer) + +* [ ] **ZNS-Importer (MVP):** Implementierung des ZNS-Importers für Stammdaten. + → Detaillierte Planung: `docs/01_Architecture/Roadmap_ZNS_Importer.md` + * [ ] Backend-Infrastruktur & CP850 Parser (Phase 1) + * [ ] Domain-Mapping & Upsert in DB (Phase 2) + * [ ] Frontend-Integration mit File-Picker & Status-Polling (Phase 3) + --- ## 3. Geplante Phasen @@ -192,3 +209,4 @@ und über definierte Schnittstellen kommunizieren. | CI/CD | `.gitea/workflows/docker-publish.yaml` | | Agent Playbooks | `docs/04_Agents/Playbooks/` | | ADR-Verzeichnis | `docs/01_Architecture/adr/` | +| ZNS-Importer Roadmap | `docs/01_Architecture/Roadmap_ZNS_Importer.md` | diff --git a/docs/01_Architecture/Roadmap_ZNS_Importer.md b/docs/01_Architecture/Roadmap_ZNS_Importer.md new file mode 100644 index 00000000..02029dd4 --- /dev/null +++ b/docs/01_Architecture/Roadmap_ZNS_Importer.md @@ -0,0 +1,97 @@ +--- +type: Roadmap +status: PLANNED +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) + +* [ ] **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). +* [ ] **Job-Management:** + * Implementierung einer Thread-sicheren In-Memory-Registry oder einfachen DB-Tabelle für den Import-Status (z. B. " + ENTPACKEN", "LADE_VEREINE_40%", "ABGESCHLOSSEN"). +* [ ] **Unzip-Service:** + * Entpacken der übermittelten `ZNS.zip` in ein temporäres Verzeichnis (bzw. in den Speicher). +* [ ] **Legacy-Parser (CP850 Fixed-Width):** + * Schreiben von robusten Mapping-Funktionen, die die Strings bytegenau auslesen. + * Berücksichtigung der Spezifikationen aus `OETO-2026_Meldestelle_Pflichtenheft_V2.4_2021-07-28.md`. + +### Phase 2: Domain-Mapping & Persistenz (👷 Backend Developer) + +* [ ] **Mapper-Logik:** + * Konvertierung der geparsten Legacy-Daten in unsere Domain-Modelle (`DomVerein`, `DomReiter`, `DomPferd`, + `DomFunktionaer`). + * *Sonderfälle:* + * `PFERDE01.dat`: Ausländische Systemnummern ignorieren (keine echten Lebensnummern). + * `LIZENZ01.dat`: Sperrlisten-Flag (`S`) korrekt auf das `DomReiter`-Modell mappen. +* [ ] **Upsert-Strategie (DB):** + * Sicherstellen, dass bei mehrfachem Import keine Duplikate entstehen. + * Abgleich über eindeutige ZNS-IDs (Satznummern). `INSERT` bei neuen, `UPDATE` bei bestehenden Datensätzen. + +### Phase 3: Frontend-Integration (🎨 Frontend Expert) + +* [ ] **UI-Komponenten (Compose Desktop):** + * Erstellung eines "Stammdaten-Import" Screens in der Master-Desktop-App. + * Integration eines nativen File-Pickers (nur Auswahl von `.zip` zulassen). +* [ ] **Netzwerk & State-Management (KMP):** + * Ktor-Client anpassen für Multipart-Uploads. + * Implementierung eines Polling-Mechanismus: Nach erfolgreichem Upload alle X Sekunden den Status-Endpunkt abfragen. +* [ ] **User Feedback:** + * Anzeige einer Progress-Bar mit Live-Updates (z. B. "Verarbeite Reiter: 1250/5000"). + * Fehler-Handling (z. B. falsches Dateiformat, Timeouts) sauber darstellen. + +### 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.