Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e1bf4d8454 | |||
| 5a08361f83 | |||
| 5d6d9efd27 |
@@ -1,50 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
|
||||
# shellcheck disable=SC1091
|
||||
source "$SCRIPT_DIR/lib/common.sh"
|
||||
|
||||
REPO_ROOT="$(resolve_repo_root)"
|
||||
cd "$REPO_ROOT"
|
||||
|
||||
# check-docs-drift.sh
|
||||
# Zweck: sehr schlanke Drift-Checks gegen die neue Doku-Struktur.
|
||||
# - Kein Guidelines-System mehr.
|
||||
# - Single Source of Truth: `docs/`
|
||||
|
||||
err=0
|
||||
|
||||
has() { grep -q "$2" "$1" || { echo "[DRIFT] '$2' fehlt in $1"; err=1; }; }
|
||||
miss() { grep -q "$2" "$1" && { echo "[DRIFT] Veralteter Begriff '$2' in $1"; err=1; }; }
|
||||
|
||||
# Harte Altlast-Pfade dürfen nicht mehr vorkommen
|
||||
if git grep -n "docs/00_Domain/" -- docs >/dev/null 2>&1; then
|
||||
echo "[DRIFT] Veralteter Pfad 'docs/00_Domain/' in docs/* gefunden"
|
||||
err=1
|
||||
fi
|
||||
if git grep -n "docs/adr/" -- docs >/dev/null 2>&1; then
|
||||
echo "[DRIFT] Veralteter Pfad 'docs/adr/' in docs/* gefunden"
|
||||
err=1
|
||||
fi
|
||||
if git grep -n "docs/c4/" -- docs >/dev/null 2>&1; then
|
||||
echo "[DRIFT] Veralteter Pfad 'docs/c4/' in docs/* gefunden"
|
||||
err=1
|
||||
fi
|
||||
if git grep -n "docs/how-to/" -- docs >/dev/null 2>&1; then
|
||||
echo "[DRIFT] Veralteter Pfad 'docs/how-to/' in docs/* gefunden"
|
||||
err=1
|
||||
fi
|
||||
if git grep -n "docs/reference/" -- docs >/dev/null 2>&1; then
|
||||
echo "[DRIFT] Veralteter Pfad 'docs/reference/' in docs/* gefunden"
|
||||
err=1
|
||||
fi
|
||||
|
||||
# Quelle der Wahrheit: Gateway-Technologie (sollte in Architektur/ADRs/C4 konsistent sein)
|
||||
has docs/01_Architecture/ARCHITECTURE.md "Spring Cloud Gateway"
|
||||
has docs/01_Architecture/adr/0007-api-gateway-pattern-de.md "Spring Cloud Gateway"
|
||||
miss docs/01_Architecture/adr/0007-api-gateway-pattern-de.md "Ktor"
|
||||
has docs/01_Architecture/c4/02-container-de.puml "Spring Cloud Gateway"
|
||||
miss docs/01_Architecture/c4/02-container-de.puml "Ktor"
|
||||
|
||||
exit $err
|
||||
@@ -1,27 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Common helpers for AI guardrail scripts
|
||||
|
||||
# Robustly resolve the repository root directory.
|
||||
# Strategy: prefer Git; fallback to marker search upwards; last resort: current dir.
|
||||
resolve_repo_root() {
|
||||
local start
|
||||
start="${1:-$(cd -- "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)}"
|
||||
if command -v git >/dev/null 2>&1; then
|
||||
if git -C "$start" rev-parse --show-toplevel >/dev/null 2>&1; then
|
||||
git -C "$start" rev-parse --show-toplevel
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
local dir
|
||||
dir="$(cd "$start" && pwd)"
|
||||
while [ "$dir" != "/" ]; do
|
||||
if [ -f "$dir/gradlew" ] || [ -f "$dir/settings.gradle.kts" ] || [ -d "$dir/.git" ]; then
|
||||
echo "$dir"
|
||||
return 0
|
||||
fi
|
||||
dir="$(dirname "$dir")"
|
||||
done
|
||||
pwd
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
|
||||
# shellcheck disable=SC1091
|
||||
source "$SCRIPT_DIR/lib/common.sh"
|
||||
|
||||
REPO_ROOT="$(resolve_repo_root)"
|
||||
cd "$REPO_ROOT"
|
||||
|
||||
mkdir -p build/diagrams
|
||||
shopt -s nullglob
|
||||
for f in docs/architecture/c4/*.puml; do
|
||||
docker run --rm -v "$PWD":/data plantuml/plantuml -tsvg "/data/$f" -o "/data/build/diagrams"
|
||||
echo "Rendered build/diagrams/$(basename "${f%.puml}").svg"
|
||||
done
|
||||
@@ -1,127 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
|
||||
# shellcheck disable=SC1091
|
||||
source "$SCRIPT_DIR/lib/common.sh"
|
||||
|
||||
REPO_ROOT="$(resolve_repo_root)"
|
||||
cd "$REPO_ROOT"
|
||||
|
||||
QUICK_MODE=false
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--quick)
|
||||
QUICK_MODE=true
|
||||
shift
|
||||
;;
|
||||
--help|-h)
|
||||
cat << 'EOF'
|
||||
Docs Link-Validierung
|
||||
|
||||
USAGE:
|
||||
./.ai/scripts/validate-links.sh [--quick]
|
||||
|
||||
BESCHREIBUNG:
|
||||
Prüft Markdown-Links in `docs/**/*.md` auf gebrochene relative Pfade.
|
||||
Ignoriert externe Links (http/https/mailto) sowie reine Anchors (#...).
|
||||
|
||||
OPTIONEN:
|
||||
--quick Führt nur eine Teilmenge der Prüfungen durch (aktuell nicht implementiert).
|
||||
EOF
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "[ERROR] Unbekannter Parameter: $1" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
python3 - <<'PY'
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from urllib.parse import unquote
|
||||
|
||||
root = Path.cwd()
|
||||
docs_dir = root / "docs"
|
||||
|
||||
if not docs_dir.is_dir():
|
||||
print(f"[ERROR] docs-Verzeichnis nicht gefunden: {docs_dir}", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
# Veraltete Pfad-Prüfungen wurden entfernt; Fokus auf Link-Integrität.
|
||||
FORBIDDEN_SUBSTRINGS = []
|
||||
|
||||
md_files = sorted(docs_dir.rglob("*.md"))
|
||||
|
||||
link_pattern = re.compile(r"\]\(([^)]+)\)")
|
||||
|
||||
errors = 0
|
||||
|
||||
def is_external(target: str) -> bool:
|
||||
t = target.lower()
|
||||
return t.startswith("http://") or t.startswith("https://") or t.startswith("mailto:")
|
||||
|
||||
def strip_fragment_and_query(target: str) -> str:
|
||||
target = target.split("#", 1)[0]
|
||||
target = target.split("?", 1)[0]
|
||||
return target
|
||||
|
||||
for f in md_files:
|
||||
text = f.read_text(encoding="utf-8", errors="replace")
|
||||
|
||||
for forbidden in FORBIDDEN_SUBSTRINGS:
|
||||
if forbidden in text:
|
||||
print(f"[ERROR] Veralteter Pfad '{forbidden}' in {f}")
|
||||
errors += 1
|
||||
|
||||
for match in link_pattern.finditer(text):
|
||||
target = match.group(1).strip()
|
||||
|
||||
if not target:
|
||||
continue
|
||||
if is_external(target):
|
||||
continue
|
||||
if target.startswith("#"):
|
||||
continue
|
||||
|
||||
if target.startswith("<") and target.endswith(">"):
|
||||
target = target[1:-1]
|
||||
|
||||
target = unquote(strip_fragment_and_query(target))
|
||||
|
||||
if target.startswith("/"):
|
||||
continue
|
||||
|
||||
if ":" in target.split("/", 1)[0]:
|
||||
# z.B. "vscode:..."
|
||||
continue
|
||||
|
||||
resolved = (f.parent / target).resolve()
|
||||
|
||||
try:
|
||||
resolved.relative_to(root.resolve())
|
||||
except ValueError:
|
||||
print(f"[ERROR] Link zeigt außerhalb des Repos: {f} -> {target}")
|
||||
errors += 1
|
||||
continue
|
||||
|
||||
if resolved.is_dir():
|
||||
if not (resolved / "README.md").is_file():
|
||||
print(f"[ERROR] Verlinktes Verzeichnis ohne README.md: {f} -> {target}")
|
||||
errors += 1
|
||||
continue
|
||||
|
||||
if not resolved.exists():
|
||||
print(f"[ERROR] Broken link: {f} -> {target}")
|
||||
errors += 1
|
||||
|
||||
if errors:
|
||||
print(f"[ERROR] Link-Validierung fehlgeschlagen: {errors} Fehler")
|
||||
sys.exit(1)
|
||||
|
||||
print(f"[OK] Link-Validierung erfolgreich: {len(md_files)} Markdown-Dateien geprüft")
|
||||
PY
|
||||
+1
-1
@@ -193,7 +193,7 @@ secrets/
|
||||
# ===================================================================
|
||||
TODO*.md
|
||||
NOTES*.md
|
||||
.junie/
|
||||
**/.junie/
|
||||
|
||||
# ===================================================================
|
||||
# Keep essential files (override exclusions)
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
desktop-tests:
|
||||
# Komplett deaktivierbar über Repo-Variable: Settings → Variables → DESKTOP_CI_ENABLED=true
|
||||
# Zusätzlich: Für Plan‑B‑Builds überspringen, wenn Commit-Message [planb] enthält
|
||||
if: ${{ vars.DESKTOP_CI_ENABLED == 'true' && !contains(gitea.event.head_commit.message, '[planb]') }}
|
||||
if: ${{ vars.DESKTOP_CI_ENABLED == 'true' && !contains(github.event.head_commit.message, '[planb]') }}
|
||||
name: Compose Desktop — Tests (headless) & Build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ run-name: Build & Publish by @${{ github.actor }}
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
tags:
|
||||
- 'v*'
|
||||
paths:
|
||||
- 'backend/**'
|
||||
- 'platform/**'
|
||||
@@ -114,8 +116,9 @@ jobs:
|
||||
with:
|
||||
images: ${{ env.REGISTRY_INTERNAL }}/${{ env.IMAGE_PREFIX }}/${{ matrix.image }}
|
||||
tags: |
|
||||
type=raw,value=latest
|
||||
type=sha,format=long
|
||||
type=ref,event=tag
|
||||
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
|
||||
type=sha,format=long,enable=${{ github.ref == 'refs/heads/main' }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v6
|
||||
|
||||
@@ -5,7 +5,7 @@ on:
|
||||
jobs:
|
||||
no-hardcoded-versions:
|
||||
# Für Plan-B-Builds überspringen: Commit-Message enthält [planb]
|
||||
if: ${{ !contains(gitea.event.head_commit.message, '[planb]') }}
|
||||
if: ${{ !contains(github.event.head_commit.message, '[planb]') }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
tag-release:
|
||||
name: 🏷️ Git-Tag setzen
|
||||
# Für Plan-B-Builds überspringen: Commit-Message enthält [planb]
|
||||
if: ${{ !contains(gitea.event.head_commit.message, '[planb]') }}
|
||||
if: ${{ !contains(github.event.head_commit.message, '[planb]') }}
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ steps.read-version.outputs.version }}
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Git-Tag erstellen & pushen
|
||||
if: steps.check-tag.outputs.already_tagged == 'false' && gitea.event.inputs.dry_run != 'true'
|
||||
if: steps.check-tag.outputs.already_tagged == 'false' && github.event.inputs.dry_run != 'true'
|
||||
run: |
|
||||
TAG="${{ steps.read-version.outputs.tag }}"
|
||||
VERSION="${{ steps.read-version.outputs.version }}"
|
||||
@@ -80,7 +80,7 @@ jobs:
|
||||
package-linux:
|
||||
name: 📦 Linux .deb Packaging
|
||||
# Nur ausführen, wenn Desktop-CI explizit aktiviert ist UND kein Plan‑B Commit
|
||||
if: ${{ vars.DESKTOP_CI_ENABLED == 'true' && !contains(gitea.event.head_commit.message, '[planb]') }}
|
||||
if: ${{ vars.DESKTOP_CI_ENABLED == 'true' && !contains(github.event.head_commit.message, '[planb]') }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: tag-release
|
||||
|
||||
@@ -88,11 +88,11 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup JDK 25 (Temurin)
|
||||
- name: Setup JDK 21 (Temurin)
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: '25'
|
||||
java-version: '21'
|
||||
|
||||
- name: Gradle cache
|
||||
uses: actions/cache@v4
|
||||
@@ -128,7 +128,7 @@ jobs:
|
||||
package-windows:
|
||||
name: 📦 Windows .msi Packaging
|
||||
# Nur ausführen, wenn Desktop-CI explizit aktiviert ist UND kein Plan‑B Commit
|
||||
if: ${{ vars.DESKTOP_CI_ENABLED == 'true' && !contains(gitea.event.head_commit.message, '[planb]') }}
|
||||
if: ${{ vars.DESKTOP_CI_ENABLED == 'true' && !contains(github.event.head_commit.message, '[planb]') }}
|
||||
runs-on: windows-latest
|
||||
needs: tag-release
|
||||
|
||||
@@ -136,11 +136,11 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup JDK 25 (Temurin)
|
||||
- name: Setup JDK 21 (Temurin)
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: '25'
|
||||
java-version: '21'
|
||||
|
||||
- name: Gradle cache
|
||||
uses: actions/cache@v4
|
||||
@@ -179,11 +179,11 @@ jobs:
|
||||
steps:
|
||||
- name: Summary ausgeben
|
||||
run: |
|
||||
echo "## 🚀 Release ${{ needs.tag-release.outputs.version }}" >> $GITEA_STEP_SUMMARY
|
||||
echo "" >> $GITEA_STEP_SUMMARY
|
||||
echo "| Artefakt | Status |" >> $GITEA_STEP_SUMMARY
|
||||
echo "|----------|--------|" >> $GITEA_STEP_SUMMARY
|
||||
echo "| Linux .deb | ${{ needs.package-linux.result }} |" >> $GITEA_STEP_SUMMARY
|
||||
echo "| Windows .msi | ${{ needs.package-windows.result }} |" >> $GITEA_STEP_SUMMARY
|
||||
echo "" >> $GITEA_STEP_SUMMARY
|
||||
echo "**Git-Tag:** \`${{ needs.tag-release.outputs.tag }}\`" >> $GITEA_STEP_SUMMARY
|
||||
echo "## 🚀 Release ${{ needs.tag-release.outputs.version }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Artefakt | Status |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|----------|--------|" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Linux .deb | ${{ needs.package-linux.result }} |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Windows .msi | ${{ needs.package-windows.result }} |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "**Git-Tag:** \`${{ needs.tag-release.outputs.tag }}\`" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
@@ -1,7 +1,43 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Shim: Weiterleitung auf zentrale Guardrail in .ai/
|
||||
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)"
|
||||
ROOT_DIR="$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel 2>/dev/null || echo "$SCRIPT_DIR")"
|
||||
exec "$ROOT_DIR/.ai/scripts/check-docs-drift.sh" "$@"
|
||||
# check-docs-drift.sh
|
||||
# Zweck: sehr schlanke Drift-Checks gegen die neue Doku-Struktur.
|
||||
# - Kein Guidelines-System mehr.
|
||||
# - Single Source of Truth: `docs/`
|
||||
|
||||
err=0
|
||||
|
||||
has() { grep -q "$2" "$1" || { echo "[DRIFT] '$2' fehlt in $1"; err=1; }; }
|
||||
miss() { grep -q "$2" "$1" && { echo "[DRIFT] Veralteter Begriff '$2' in $1"; err=1; }; }
|
||||
|
||||
# Harte Altlast-Pfade dürfen nicht mehr vorkommen
|
||||
if git grep -n "docs/00_Domain/" -- docs >/dev/null 2>&1; then
|
||||
echo "[DRIFT] Veralteter Pfad 'docs/00_Domain/' in docs/* gefunden"
|
||||
err=1
|
||||
fi
|
||||
if git grep -n "docs/adr/" -- docs >/dev/null 2>&1; then
|
||||
echo "[DRIFT] Veralteter Pfad 'docs/adr/' in docs/* gefunden"
|
||||
err=1
|
||||
fi
|
||||
if git grep -n "docs/c4/" -- docs >/dev/null 2>&1; then
|
||||
echo "[DRIFT] Veralteter Pfad 'docs/c4/' in docs/* gefunden"
|
||||
err=1
|
||||
fi
|
||||
if git grep -n "docs/how-to/" -- docs >/dev/null 2>&1; then
|
||||
echo "[DRIFT] Veralteter Pfad 'docs/how-to/' in docs/* gefunden"
|
||||
err=1
|
||||
fi
|
||||
if git grep -n "docs/reference/" -- docs >/dev/null 2>&1; then
|
||||
echo "[DRIFT] Veralteter Pfad 'docs/reference/' in docs/* gefunden"
|
||||
err=1
|
||||
fi
|
||||
|
||||
# Quelle der Wahrheit: Gateway-Technologie (sollte in Architektur/ADRs/C4 konsistent sein)
|
||||
has docs/01_Architecture/ARCHITECTURE.md "Spring Cloud Gateway"
|
||||
has docs/01_Architecture/adr/0007-api-gateway-pattern-de.md "Spring Cloud Gateway"
|
||||
miss docs/01_Architecture/adr/0007-api-gateway-pattern-de.md "Ktor"
|
||||
has docs/01_Architecture/c4/02-container-de.puml "Spring Cloud Gateway"
|
||||
miss docs/01_Architecture/c4/02-container-de.puml "Ktor"
|
||||
|
||||
exit $err
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Shim: Weiterleitung auf zentrale Guardrail in .ai/
|
||||
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)"
|
||||
ROOT_DIR="$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel 2>/dev/null || echo "$SCRIPT_DIR")"
|
||||
exec "$ROOT_DIR/.ai/scripts/render-plantuml.sh" "$@"
|
||||
mkdir -p build/diagrams
|
||||
shopt -s nullglob
|
||||
for f in docs/architecture/c4/*.puml; do
|
||||
docker run --rm -v "$PWD":/data plantuml/plantuml -tsvg "/data/$f" -o "/data/build/diagrams"
|
||||
echo "Rendered build/diagrams/$(basename "${f%.puml}").svg"
|
||||
done
|
||||
|
||||
@@ -1,7 +1,136 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Shim: Weiterleitung auf zentrale Guardrail in .ai/
|
||||
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)"
|
||||
ROOT_DIR="$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel 2>/dev/null || echo "$SCRIPT_DIR")"
|
||||
exec "$ROOT_DIR/.ai/scripts/validate-links.sh" "$@"
|
||||
# validate-links.sh - Link-Validierung für Projektdokumentation (`docs/**`).
|
||||
# Zweck: Guardrail für die "Docs-as-Code"-Strategie.
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
QUICK_MODE=false
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--quick)
|
||||
QUICK_MODE=true
|
||||
shift
|
||||
;;
|
||||
--help|-h)
|
||||
cat << 'EOF'
|
||||
Docs Link-Validierung
|
||||
|
||||
USAGE:
|
||||
./.junie/scripts/validate-links.sh [--quick]
|
||||
|
||||
BESCHREIBUNG:
|
||||
Prüft Markdown-Links in `docs/**/*.md` auf gebrochene relative Pfade.
|
||||
Ignoriert externe Links (http/https/mailto) sowie reine Anchors (#...).
|
||||
|
||||
OPTIONEN:
|
||||
--quick Führt nur eine Teilmenge der Prüfungen durch (aktuell nicht implementiert).
|
||||
EOF
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "[ERROR] Unbekannter Parameter: $1" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
python3 - <<'PY'
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from urllib.parse import unquote
|
||||
|
||||
root = Path.cwd()
|
||||
docs_dir = root / "docs"
|
||||
|
||||
if not docs_dir.is_dir():
|
||||
print(f"[ERROR] docs-Verzeichnis nicht gefunden: {docs_dir}", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
# Veraltete Pfad-Prüfungen wurden entfernt, da sie zu wartungsintensiv waren.
|
||||
# Das Skript konzentriert sich nun auf die Validierung der Link-Integrität.
|
||||
FORBIDDEN_SUBSTRINGS = []
|
||||
|
||||
md_files = sorted(docs_dir.rglob("*.md"))
|
||||
|
||||
link_pattern = re.compile(r"\]\(([^)]+)\)")
|
||||
|
||||
errors = 0
|
||||
|
||||
def is_external(target: str) -> bool:
|
||||
t = target.lower()
|
||||
return t.startswith("http://") or t.startswith("https://") or t.startswith("mailto:")
|
||||
|
||||
def strip_fragment_and_query(target: str) -> str:
|
||||
# remove fragment and query parts
|
||||
target = target.split("#", 1)[0]
|
||||
target = target.split("?", 1)[0]
|
||||
return target
|
||||
|
||||
for f in md_files:
|
||||
text = f.read_text(encoding="utf-8", errors="replace")
|
||||
|
||||
for forbidden in FORBIDDEN_SUBSTRINGS:
|
||||
if forbidden in text:
|
||||
print(f"[ERROR] Veralteter Pfad '{forbidden}' in {f}")
|
||||
errors += 1
|
||||
|
||||
for match in link_pattern.finditer(text):
|
||||
target = match.group(1).strip()
|
||||
|
||||
if not target:
|
||||
continue
|
||||
if is_external(target):
|
||||
continue
|
||||
if target.startswith("#"):
|
||||
continue
|
||||
|
||||
# drop angle brackets <...> used in markdown for urls with spaces
|
||||
if target.startswith("<") and target.endswith(">"):
|
||||
target = target[1:-1]
|
||||
|
||||
target = unquote(strip_fragment_and_query(target))
|
||||
|
||||
# ignore absolute paths in the repo (we treat them as doc-style links; validate only if relative)
|
||||
if target.startswith("/"):
|
||||
continue
|
||||
|
||||
# ignore non-file targets (e.g. empty or protocol-less anchors)
|
||||
if ":" in target.split("/", 1)[0]:
|
||||
# things like "vscode:..." etc.
|
||||
continue
|
||||
|
||||
# treat as file path relative to markdown file
|
||||
resolved = (f.parent / target).resolve()
|
||||
|
||||
# keep validation within repo
|
||||
try:
|
||||
resolved.relative_to(root.resolve())
|
||||
except ValueError:
|
||||
print(f"[ERROR] Link zeigt außerhalb des Repos: {f} -> {target}")
|
||||
errors += 1
|
||||
continue
|
||||
|
||||
# allow directories if they contain README.md
|
||||
if resolved.is_dir():
|
||||
if not (resolved / "README.md").is_file():
|
||||
print(f"[ERROR] Verlinktes Verzeichnis ohne README.md: {f} -> {target}")
|
||||
errors += 1
|
||||
continue
|
||||
|
||||
if not resolved.exists():
|
||||
print(f"[ERROR] Broken link: {f} -> {target}")
|
||||
errors += 1
|
||||
|
||||
if errors:
|
||||
print(f"[ERROR] Link-Validierung fehlgeschlagen: {errors} Fehler")
|
||||
sys.exit(1)
|
||||
|
||||
print(f"[OK] Link-Validierung erfolgreich: {len(md_files)} Markdown-Dateien geprüft")
|
||||
PY
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
# .aiignore - Verhindert Token-Waste für Nolik
|
||||
|
||||
# Abhängigkeiten & Binaries
|
||||
build/
|
||||
.gradle/
|
||||
*.jar
|
||||
*.deb
|
||||
*.msi
|
||||
|
||||
# Sensible Daten (auch lokal!)
|
||||
.env
|
||||
.env.*
|
||||
config/docker/certs/
|
||||
*.pem
|
||||
*.jks
|
||||
postgres-data/
|
||||
valkey-data/
|
||||
|
||||
# Doku-Builds (Nolik soll die Source-Files in docs/ lesen, nicht die HTML-Exporte)
|
||||
build/dokka/
|
||||
docs/Neumarkt2026/*.pdf
|
||||
@@ -1,7 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Shim: Weiterleitung auf zentrale Guardrail in .ai/
|
||||
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)"
|
||||
ROOT_DIR="$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel 2>/dev/null || echo "$SCRIPT_DIR")"
|
||||
exec "$ROOT_DIR/.ai/scripts/check-docs-drift.sh" "$@"
|
||||
@@ -1,7 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Shim: Weiterleitung auf zentrale Guardrail in .ai/
|
||||
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)"
|
||||
ROOT_DIR="$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel 2>/dev/null || echo "$SCRIPT_DIR")"
|
||||
exec "$ROOT_DIR/.ai/scripts/validate-links.sh" "$@"
|
||||
@@ -3,12 +3,15 @@
|
||||
Dieses Dokument definiert die Zusammenarbeit zwischen dem User (Owner) und den spezialisierten KI-Agenten.
|
||||
Es dient als zentraler **System-Prompt-Erweiterung** für neue Chat-Sessions.
|
||||
|
||||
## 🚀 Strategische Ausrichtung
|
||||
## 🚀 Strategische Ausrichtung (Reality-Reset 28.04.2026)
|
||||
|
||||
Das Projekt **"Meldestelle"** entwickelt eine ÖTO/FEI-konforme, offline-fähige Turnier-Software.
|
||||
1. **Desktop-First:** Primäres Ziel ist die Compose Desktop App (KMP). UX & Performance sind auf Profis optimiert.
|
||||
2. **Offline-First:** Das System muss autark (ohne Internet) funktionieren. Sync-Logik ist Kernbestandteil.
|
||||
3. **Domain-Driven:** 6 Bounded Contexts (SCS) bilden den fachlichen Rahmen.
|
||||
2. **Offline-First:** Das System muss autark (ohne Internet) funktionieren.
|
||||
3. **Domain-Driven:** Die Hierarchie **Veranstaltung -> Turnier -> Bewerb/Abteilung** ist das absolute Fundament.
|
||||
|
||||
**WICHTIG:** Alle Agenten arbeiten ab sofort nur noch auf Basis von verifiziertem Code. "Halluzinationen" über
|
||||
abgeschlossene Phasen ohne entsprechende Implementierung sind untersagt.
|
||||
|
||||
## 1. Protokoll & Rollen-Badges
|
||||
Jede Agenten-Antwort **muss** mit dem entsprechenden Badge beginnen, um den Kontext und die Verantwortlichkeit zu klären.
|
||||
|
||||
+10
-209
@@ -17,218 +17,19 @@ Versionierung folgt [Semantic Versioning](https://semver.org/lang/de/).
|
||||
|
||||
### Hinzugefügt
|
||||
|
||||
- **Onboarding & Desktop-UX - 15.04.2026:**
|
||||
- **Desktop-App:** Dynamisierung der Statusanzeigen im App-Footer ("Cloud synchronisiert" & "Verbunden").
|
||||
- **Connectivity-Tracking:** Implementierung des `ConnectivityTracker` (KMP) zur Echtzeit-Überwachung der API-Gateway
|
||||
Erreichbarkeit.
|
||||
- **LAN-Erkennung:** Integration des `NetworkDiscoveryService` (mDNS) im Footer zur Anzeige aktiver Instanzen im
|
||||
lokalen Netzwerk.
|
||||
- **Onboarding:** Datenfluss vom `SettingsManager` bis in den Footer finalisiert (Anzeige des echten Gerätenamens).
|
||||
- **Online-Nennung & Integration - 15.04.2026:**
|
||||
- **Backend (Mail-Service):** Finalisierung des `MailController` für Web-Nennungen inkl. SMTP-Versand via World4You.
|
||||
- **Frontend (Desktop):** `NennungsEingangScreen` an Live-Daten vom `mail-service` angebunden.
|
||||
- **Repository:** `NennungRemoteRepository` (KMP) um `holeNennungen()` erweitert.
|
||||
- **Billing & ÖTO - 15.04.2026:**
|
||||
- **Sportförderbeitrag:** Automatische Buchung von 1,00 EUR (§16 ÖTO) bei jeder Nennung im `entries-service`
|
||||
implementiert.
|
||||
- **Basis-Infrastruktur & Domain-Definition:**
|
||||
- DDD-Modelle für `Veranstaltung`, `Turnier`, `Bewerb` und `Abteilung` gemäß ÖTO definiert.
|
||||
- ZNS-Parser Prototyp für Dateiformate (VEREIN01, LIZENZ01, PFERD01, RICHT01).
|
||||
- Plan-B Mail-Service (Spring Boot) für Nennungs-Versand via World4You.
|
||||
- Desktop-App Skelett mit Navigation und UI-Hüllen (Compose Desktop).
|
||||
|
||||
### Behoben
|
||||
### Reality-Reset (28.04.2026)
|
||||
|
||||
- **Frontend (Desktop):** Behebung von Kompilierungsfehlern in `ScreenPreviews.kt` durch Implementierung der fehlenden
|
||||
`getStats()` Methode in den `MasterdataRepository`-Mocks.
|
||||
- **Identity-Modul:** Umstellung auf `kotlin.time.Instant` zur Vermeidung von Deprecation-Warnungen und Behebung von
|
||||
Persistenz-Konflikten im `ExposedDeviceRepository`.
|
||||
- **Koin DI:** Korrektur von Typ-Inferenz-Fehlern beim `HttpClient` im `nennung-feature` durch explizite Qualifier.
|
||||
- **Turnier-Feature:** Behebung eines unsicheren Casts (`Any!` zu `List<String>`) in `TurnierStammdatenTab.kt`.
|
||||
- **Konfiguration:** Harmonisierung der Ports (Mail-Service auf 8083) in `.env`, `dc-backend.yaml` und
|
||||
`PlatformConfig.jvm.kt`.
|
||||
- **Korrektur:** Vormalige Einträge über "abgeschlossene" Billing-, Results- und Zeitplan-Features wurden entfernt, da
|
||||
diese im Code nicht funktional hinterlegt waren.
|
||||
- **Status:** Fokus zurück auf die Kern-Hierarchie (Veranstaltung -> Turnier -> Bewerb).
|
||||
|
||||
### Hinzugefügt
|
||||
- **Phase 12 (Abrechnung & Infrastruktur) - 12.04.2026:**
|
||||
- **Infrastruktur:** Docker-Integration für `billing-service` (Port 8087) und API-Gateway Routing vervollständigt.
|
||||
- **Service Discovery:** Alle relevanten Microservices (`masterdata`, `events`, `results`, `series`, `billing`) sind nun bei Consul registriert.
|
||||
- **Frontend Billing:** `BillingRepository` und `BillingViewModel` auf reale API-Anbindung (Ktor) umgestellt; `BillingScreen` funktionalisiert.
|
||||
- **Backend (Series):** JPA-Entitäten `Serie` und `SeriePunkt` im `series-service` stabilisiert und Flyway-Migrationen für das Datenbankschema erstellt.
|
||||
- **Fix:** Behebung von IDE-Mapping-Warnungen durch explizite `@Column` Namen in den JPA-Entitäten.
|
||||
- **Backend Fixes - 12.04.2026:**
|
||||
- **Infrastruktur:** Behebung von Startfehlern im `events-service` (DataSource) und `masterdata-service` (Consul).
|
||||
- **Build:** Integration von `results-service` und `series-service` in `settings.gradle.kts`.
|
||||
- **Domain:** `Serie` und `SeriePunkt` zu `data class` konvertiert (copy() Unterstützung).
|
||||
- **Phase 11 (Ergebniserfassung & Platzierung) - 12.04.2026:**
|
||||
- **Backend (Results):** `results-service` um JPA-Entitäten, Repositories und Business-Logik für Platzierungsberechnungen (Wertnote, Zeit, Fehler) ergänzt.
|
||||
- **Infrastructure:** `dc-backend.yaml` und `GatewayConfig.kt` um den Service `results` (Port 8088) erweitert.
|
||||
- **Frontend Domain:** `ErgebnisRepository` und `Ergebnis`-Modell für Wertnoten, Zeiten und Status erstellt.
|
||||
- **Frontend UI:** `ErgebnisEditDialog` zur schnellen Ergebniserfassung hinzugefügt; `TurnierStartlistenTab` ermöglicht nun Erfassung per Zeilen-Klick.
|
||||
- **Frontend UI:** `TurnierErgebnislistenTab` vervollständigt: Buttons für "Platzierung berechnen" und "Drucken" (PDF) funktionalisiert.
|
||||
- **Fix:** Kompilierungsprobleme im `TurnierFeatureModule` und `ScreenPreviews.kt` behoben (fehlende `ergebnisRepo` Parameter).
|
||||
|
||||
### Hinzugefügt
|
||||
- **Phase 10.4 (Series-Context Vertiefung) - 12.04.2026:**
|
||||
- **Backend (Series):** `series-service` um Logik für Streichresultate (`ReglementTyp`) und Bindungsarten (Reiter-zentriert, Pferde-zentriert, Paar-Bindung) erweitert.
|
||||
- **Infrastructure:** `dc-backend.yaml` und `GatewayConfig.kt` um den Service `series` (Port 8089) erweitert.
|
||||
- **Frontend Domain:** `SeriesRepository` und Modelle an das neue Ranking-Format (`SerieStandEntry`) angepasst.
|
||||
- **UI:** `SeriesScreen.kt` überarbeitet: Zeigt nun Reiter- und Pferde-IDs sowie Fortschritt pro Teilnehmer an.
|
||||
- **Dokumentation:** `MASTER_ROADMAP.md` aktualisiert (Phase 10 & 11 auf 'Completed' gesetzt).
|
||||
|
||||
### Hinzugefügt
|
||||
- **Phase 10.3 (Echter Datenverkehr & Infrastruktur) - 12.04.2026:**
|
||||
- **Infrastructure:** Docker-Services für `masterdata`, `events` und `zns-import` in `dc-backend.yaml` ergänzt.
|
||||
- **Gateway:** API-Gateway Routing für Masterdata (`/api/v1/masterdata`) und Events (`/api/v1/events`) konfiguriert.
|
||||
- **Frontend (Vereine):** `VereinRepository` (Ktor) und `VereinViewModel` implementiert für echtes Anlegen von Veranstaltern.
|
||||
- **Frontend (Events):** `TurnierViewModel` an das reale `TurnierRepository` angebunden.
|
||||
- **Fix:** `verein-feature` Abhängigkeiten korrigiert (Network/Ktor).
|
||||
- **Fix:** Polling-Endpoints im `ZnsImportViewModel` an das neue Gateway-Routing angepasst.
|
||||
|
||||
### Hinzugefügt
|
||||
- **Phase 10.2 (Masterdata-Editoren & Organisation) - 12.04.2026:**
|
||||
- **Frontend:** `MasterdataEditDialogs.kt` für die Bearbeitung von Reiter- und Pferdedaten direkt im Turnier-Kontext.
|
||||
- **Frontend:** Erweiterung des `MasterdataRepository` um Schreibzugriffe (`saveReiter`, `savePferd`).
|
||||
- **Frontend:** Funktionale Suche für Turnierleiter im `Organisation`-Tab via `NennungViewModel` und Masterdata-API.
|
||||
- **Frontend:** State-Management für Stammdaten-Editoren im `NennungViewModel`.
|
||||
- **Fix:** Kompilierungsfehler in `ScreenPreviews.kt` behoben (fehlende Interface-Methoden in Mocks).
|
||||
- **Fix (Desktop Shell):** Fehlendes `turnierFeatureModule` in `main.kt` registriert und Login-Gate in `DesktopApp.kt` optimiert.
|
||||
|
||||
### Hinzugefügt
|
||||
- **Phase 10 (Series-Context & Stammdaten) - 11.04.2026:**
|
||||
- **Frontend:** Stammdaten-Infrastruktur im `turnier-feature` (Repositories, DTOs, Domänenmodelle) für Reiter, Pferde, Funktionäre und Vereine.
|
||||
- **Frontend:** `NennungViewModel` zur Steuerung der Suche und Status-Verwaltung von Nennungen.
|
||||
- **Frontend:** Funktionalisierung des `Nennungen`-Tabs (Suche, Echt-Datenanbindung) und Vorbereitung des `Organisation`-Tabs.
|
||||
- **Frontend:** `DefaultMasterdataRepository` zur Suche in Reitern, Pferden und Funktionären via Backend-API.
|
||||
- **Netzwerk:** Erweiterung der `ApiRoutes` um Endpunkte für Masterdata und Nennungen.
|
||||
- **Phase 10 (Series-Context) Vorbereitung:**
|
||||
- **Frontend:** Neuer `SeriesScreen.kt` für die Verwaltung von Cups und Meisterschaften (konfigurierbare Reglements).
|
||||
- **Frontend:** Erweiterung des `AdminUebersichtScreen` (Cockpit) um KPI-Kacheln mit Direkt-Links zu Cups und Meisterschaften.
|
||||
- **Frontend:** Integration der Series-Navigation in die Breadcrumbs und das globale Routing (`Meisterschaften`, `Cups`).
|
||||
- **Turnier-Feature Hardening:**
|
||||
- **Frontend:** `STARTLISTEN` und `ERGEBNISLISTEN` Tabs vollständig an das `BewerbViewModel` angebunden (Bewerbs-Auswahl mit echten Daten).
|
||||
- **Frontend:** Implementierung der Starter-Anzeige in der Startliste (LazyColumn).
|
||||
|
||||
### Geändert
|
||||
- **Turnier-Feature:** Sichtbarkeit von `BewerbViewModel.generateStartliste()` auf `public` geändert, um den Aufruf aus dem Tab zu ermöglichen.
|
||||
- **Frontend (Desktop):** `ScreenPreviews.kt` aktualisiert zur Berücksichtigung der neuen ViewModel-Abhängigkeiten (`NennungViewModel`, `MasterdataRepository`).
|
||||
|
||||
### [Phase 9] - 11.04.2026
|
||||
- **Frontend:** Interaktiver Drag & Drop Zeitplan mit automatischem 5-Minuten-Snapping und Konflikt-Visualisierung.
|
||||
- **Frontend:** "B-Satz Export (ZNS)" Toolbar-Aktion mit integriertem Vorschau-Dialog.
|
||||
- **Frontend:** "Änderungs-Historie" (Audit-Log) Sektion zur Nachverfolgung von Zeitplan-Anpassungen.
|
||||
- **Backend:** `audit_log` Persistenz und Abfrage-API für manuelle Eingriffe in Bewerbe.
|
||||
- **Backend:** ZNS B-Satz Export Endpunkt (`/export/zns/b-satz`) zur Generierung von `BBEWERBE` Datensätzen.
|
||||
- **Core:** `FixedWidthLineBuilder` zur präzisen Generierung von ZNS-konformen Festbreiten-Formaten.
|
||||
|
||||
### Behoben
|
||||
- **Infrastruktur:** Veraltete `newSuspendedTransaction` in `DatabaseFactory.kt` durch moderne `suspendTransaction` (Exposed v1) ersetzt.
|
||||
- **Frontend (Desktop):** Kompilierfehler in `ScreenPreviews.kt` behoben, indem fehlende Interface-Methoden im Mock-Repository implementiert wurden.
|
||||
- **Backend (Tests):** `JdbcSQLSyntaxErrorException` im `BewerbeZeitplanIntegrationTest` durch Korrektur des Schema-Setups (Audit-Log Tabelle) gelöst.
|
||||
|
||||
### Hinzugefügt
|
||||
- **Bugfix**: Behebung von Build-Fehlern im `veranstalter-feature` nach der Paket-Konsolidierung.
|
||||
- **Frontend**: `FakeVeranstalterRepository` in `commonMain` implementiert, um saubere KMP-DI zu ermöglichen.
|
||||
- **Frontend**: Veraltete Imports und Referenzen im `meldestelle-desktop` Shell und Previews korrigiert.
|
||||
- **Architektur:** Fachliches Konzept für Zeitplan-Optimierung (Drag & Drop) erstellt (`konzept-zeitplan-optimierung-de.md`).
|
||||
- **Architektur:** Spezifikation des Status-Automaten für Nennungen und Synchronisations-Logik (`status-automat-nennungen-de.md`).
|
||||
- **Rulebook:** Überprüfung und Spezifikation der Parcoursbesichtigung zu Pferd (§43 ÖTO) inkl. 5-Minuten-Puffer-Regel.
|
||||
- **Backend (Entries):** Erweiterung der Domain-Modelle `Bewerb` und `Abteilung` um Besichtigungs- und Pausen-Konfigurationen.
|
||||
- **Backend (Entries):** Neues Datenmodell `BesichtigungsBlock` für wettbewerbsübergreifende Parcoursbesichtigungen.
|
||||
- **Backend (Entries):** API-Endpunkt `PATCH /bewerbe/{id}/zeitplan` für schnelle Zeitplan-Updates implementiert.
|
||||
- **Backend (Entries):** `StartlistenService` um ÖTO-konforme Zeitberechnung (Besichtigungs-Puffer, Pausen-Intervalle) erweitert.
|
||||
|
||||
### Geändert
|
||||
- Masterdata/Domain: Umbenennungen zur Vereinheitlichung der Terminologie (DE):
|
||||
- `MasterdataLicenseRepository` → `LizenzRepository`
|
||||
- `LicenseMatrixService` → `LizenzMatrixService`
|
||||
- `LicenseMatrixServiceImpl` → `LizenzMatrixServiceImpl`
|
||||
- Test: `LicenseMatrixServiceTest` → `LiznezMatrixServiceTest` (exakt nach Vorgabe)
|
||||
- Infrastructure (Exposed): `LicenseTable` → `LizenzTable`
|
||||
- Docs: Begriff „reit_lizenzen“ → „reiterlizenzen“ in Glossar/UL konsolidiert.
|
||||
|
||||
### Hinzugefügt
|
||||
|
||||
- **Events-Service Bundle:** Vollständige Stabilisierung der `events` Services (Domain, Infrastructure, API, Service).
|
||||
- **Domain:** Umstellung auf `kotlin.time.Instant` zur Vermeidung von Deprecation-Warnungen (Kotlin 2.1.20+) und Harmonisierung mit dem Rulebook-Expert.
|
||||
- **Infrastructure:** Anpassung an den `org.jetbrains.exposed.v1` Namespace und Implementierung von UUID-Konvertierungen zwischen `kotlin.uuid.Uuid` (Domain) und `java.util.UUID` (DB).
|
||||
- **API:** Refactoring des `VeranstaltungController` zur direkten Repository-Nutzung (Alignment mit `entries` Service).
|
||||
- **Service-Config:** Umstellung auf Flyway-basiertes Tenant-Schema-Management in `EventsDatabaseConfiguration`.
|
||||
- **Build:** Behebung des `shadowJar` Fehlers in `events-infrastructure` durch Entfernen des unnötigen `ktor` Plugins in der Library-Schicht.
|
||||
|
||||
- Masterdata: Automatisches Seeding aller Reiterlizenzen (license_matrix) beim Start des `masterdata-service` via `ReiterlizenzenSeeder` (idempotent; SPRINGEN: LIZENZFREI,R1–R4; DRESSUR: LIZENZFREI,RD1–RD3).
|
||||
|
||||
- **ZNS-Import (LIZENZ01.dat):** Robuster Lizenz-Tokenizer und Normalizer implementiert.
|
||||
- Erkennung: `RD1..RD4`, `R1..R4`, `S1..S4`, `D2..D4`, Kombis `R{n}D{m}`, `R{n}S{k}`, `RDS4` (rechts-/letztes Vorkommen gewinnt).
|
||||
- Normalisierung: `S*→R*`, `D*→RD*`, `RD4→RD3` (bis Enum verfügbar), `R{n}S{k}→Rmax(n,k)`, `R{n}D{m}→R{n}+RD{m}`.
|
||||
- Integration: `ZnsReiterParser` füllt `lizenzen`-Liste (1:n) entsprechend und leitet `lizenzKlasse` bei fehlendem 4‑Spalten‑Code aus Token ab.
|
||||
- QA: Neue Unit-Tests (Tokenizer) für Beispiele `R2S3`, `R2D4`, `RD2` u. a.; alle Parser-Tests grün.
|
||||
|
||||
- **Core:** Modularisierte ZNS-Parser eingeführt (`ZnsVereinParser`, `ZnsReiterParser`, `ZnsPferdParser`, `ZnsFunktionaerParser`) zur Verbesserung der Wartbarkeit und Unterstützung von Einzelimporten.
|
||||
- **Fix:** SQL-Migrationsfehler in `V010` behoben, indem die Umbenennung der Spalte `name` in `verein_name` durch einen idempotenten `DO`-Block abgesichert wurde (behebt "Unable to resolve column 'name'").
|
||||
- **Infrastructure:** Datenbank-Migration `V010` hinzugefügt, um das Schema final mit den `Exposed`-Modellen zu synchronisieren.
|
||||
- **Infrastructure:** Datei-Archivierung für hochgeladene ZNS-ZIP-Dateien im `ZnsImportOrchestrator` implementiert.
|
||||
- **Infrastructure:** `ZnsImportService` vollständig auf die neuen spezialisierten Parser umgestellt und als Spring-Bean im Backend registriert.
|
||||
- **QA:** Umfassende Test-Suite `ZnsParserTest.kt` mit realen ZNS-Daten (Hämmerle, Neuwirth, etc.) erstellt; Korrektur der Extraktions-Logik für Mitgliedsnummern (Position 147) und Funktionär-Daten (RICHT01).
|
||||
- **QA:** Neue Betriebsanleitung für ZNS-Importer Tests erstellt: `docs/07_Infrastructure/runbooks/ZNS_Importer_Test_Manual.md`.
|
||||
- **Infrastructure:** `MasterdataDatabaseConfiguration` korrigiert: Expliziter Aufruf von `Database.connect()` hinzugefügt, um Abstürze beim Anwendungsstart ("No database specified") zu beheben.
|
||||
- **Infrastructure:** `application.yml` im `masterdata-service` vervollständigt (DataSource-Konfiguration mit `pg-user`/`pg-password` und Flyway-Aktivierung).
|
||||
- **Domain:** Legacy-Spezifikationen für ZNS-Schnittstellen (Import/Export) formalisiert:
|
||||
- `docs/03_Domain/02_Reference/Legacy_Specs/OETO-2026_Meldestelle_Pflichtenheft_V2.4.md` (Basis-Satzarten A-N)
|
||||
- `docs/03_Domain/02_Reference/Legacy_Specs/OETO-2026_Meldestelle_Erweiterung-Schnittstelle_2014.md` (XML-Erweiterung, LinkID-Logik)
|
||||
- **QA B-2:** `OnboardingValidator`-Objekt extrahiert; `OnboardingValidatorTest.kt` (17 Unit-Tests: Pflichtfeld-Guard,
|
||||
Doppelklick-Schutz, Abbrechen-Reset, rememberSaveable-Regression)
|
||||
- **QA B-3:** `AbteilungsRegelServiceTest.kt` um 14 Tests erweitert: CSN-C-NEU ≤95 cm / ≥100 cm Pflicht-Teilung,
|
||||
ORGANISATORISCH, SEPARATE_SIEGEREHRUNG, Caprilli-Regression, Grenzfälle 90/110 cm
|
||||
- **Domain:** `AbteilungsTeilungsTypE` um `ORGANISATORISCH` und `SEPARATE_SIEGEREHRUNG` erweitert
|
||||
|
||||
### Behoben
|
||||
|
||||
- **Masterdata/Infrastructure:** Kompilierfehler in `AltersklasseRepositoryImpl` durch Vereinheitlichung der Exposed-Tabellendefinition behoben:
|
||||
- `AltersklassenTable` → `AltersklasseTable`
|
||||
- Spalte `altersklassen_code` → `altersklasse_code`
|
||||
- Tabellenname `altersklassen` → `altersklasse`
|
||||
- **Masterdata/API:** Fehlendes Interface-Mapping ergänzt: `RegulationRepository` enthält nun `findAllTurnierklassen()`; `ExposedRegulationRepository` implementiert die Methode und `RegulationController` kompiliert wieder.
|
||||
- **ZNS-Import:** `AltersklassenExposedRepository` korrigiert (richtiger Domain-Typ `AltersklasseDefinition`, Mapping von `SparteE` und Zeitstempeln).
|
||||
|
||||
- **Migration V013:** Idempotent und robust gemacht. Alle `ALTER TABLE ... RENAME`-Operationen laufen nun nur, wenn die Quell-Tabelle existiert (Fix für "Unable to resolve table 'bundesland'/'turnierklasse'").
|
||||
- **Lizenz-Validierung:** `LicenseMatrixServiceImpl` um Cross-Discipline-Mapping R↔RD (ÖTO-Äquivalenzen) erweitert. Damit funktionieren Fälle wie Dressur-Starts mit Spring-Lizenz (R1→RD1, R2→RD2, R3/R4→RD3) bzw. umgekehrt konsistent.
|
||||
|
||||
- **Domain:** Striktere Spartenlizenz-Prüfung in `Reiter.hasLizenzForSparte` implementiert (RD1..RD3 nur DRESSUR; R1..R4 nur SPRINGEN). Behebt Testfehler „isEligible verweigert Start ohne passende Spartenlizenz“ im `LicenseMatrixServiceTest`.
|
||||
|
||||
### Behoben
|
||||
- **Backend (Entries):** Fehlschlagenden Unit-Test `berechneStartzeiten sollte Zeiten korrekt aufsummieren` korrigiert; der Test berücksichtigt nun den neuen 5-minütigen ÖTO-konformen Puffer nach der Parcoursbesichtigung (§43).
|
||||
- **Frontend (Desktop):** Build-Fehler ("No matching variant") beim `funktionaer-feature` behoben; fehlendes `build.gradle.kts` mit JVM-Target und Compose/Koin-Abhängigkeiten ergänzt.
|
||||
- **Frontend (Desktop):** Massive Inkonsistenzen in der Paketstruktur des `veranstalter-feature` bereinigt; alle Komponenten (ViewModel, Screens, Mocks) auf das Standardpaket `at.mocode.frontend.features.veranstalter` konsolidiert, um Redeklarationen und Import-Fehler zu beheben.
|
||||
- **Frontend (Desktop):** Kompilierfehler im `VeranstalterDetailScreen` durch korrekte Paket-Referenzierung des `FakeVeranstaltungStore` gelöst.
|
||||
|
||||
### Dokumentation
|
||||
- **Masterdata/Docs:** `REITER_LIZENZEN.md` überarbeitet:
|
||||
- Strikte Sparten-Trennung dokumentiert (RD1..RD3 nur Dressur; R1..R4 nur Springen).
|
||||
- Dressur-Tabelle korrigiert (R-Lizenzen entfernen; RD-Pflicht je Klasse).
|
||||
- Validierungslogik ergänzt (2-stufig: Spartenlizenz → Max-Turnierklasse; R↔RD Mapping nur zur Kappung, nicht zur Eligibility).
|
||||
- Vielseitigkeit (CCN/CCI) ergänzt: kumulative Anforderungen (Dressur RD* UND Springen R* je Klasse); Startkartenregel für Einsteiger.
|
||||
- Fahren (CAN/CAI) ergänzt: aktueller Systemzustand ohne `F*`‑Lizenzen dokumentiert; Teilnahme über Startkarte/Ausschreibung, geplante Enum‑Erweiterung vermerkt.
|
||||
- §15‑Tabelle (kompakt) integriert und auf ÖTO‑Referenz verlinkt; Bedeutungen „B,C“ und „LP“ erläutert. Hinweis aufgenommen, dass `RD4` derzeit nicht als Enum vorhanden ist und wie `RD3` behandelt wird.
|
||||
- Kombinationsreihen gemäß §15 ergänzt: `R1S2`, `R1S3`, `R1S4`, `R2S3`, `R2S4`, `R3S4` (neuer Unterabschnitt 2.6 mit Tabelle, identische Spalten wie 2.5).
|
||||
|
||||
### Behoben
|
||||
|
||||
- **Masterdata:** Qualifikations-Management für Funktionäre (Richter/Parcoursbauer) professionalisiert: Umstellung von unstrukturiertem Text auf offizielle ÖTO/FEI Master-Daten Referenzen (`QualifikationMasterTable`).
|
||||
- **Masterdata:** Fehlende Tabelle `funktionaer_qualifikation` in der Initialisierung beider Services (`masterdata` und `zns-import`) ergänzt, um `PSQLException` während des ZNS-Imports zu beheben.
|
||||
- **Infrastructure:** Start-Probleme des `masterdata-service` endgültig behoben: Port-Konflikt zwischen Spring Boot (Management/Actuator) und dem Gateway (8081) durch Umzug auf Port 8086 (gemäß Infrastruktur-Vorgaben) gelöst.
|
||||
- **Infrastructure:** Port-Konflikt im `masterdata-service` durch Trennung der Bind-Adressen (Spring: 127.0.0.1, Ktor: 0.0.0.0) und Bereinigung verwaister Prozesse stabilisiert.
|
||||
- **Core:** Veraltete `ZnsLegacyParsersTest.kt` entfernt; alle Tests sind nun in `ZnsParserTest.kt` konsolidiert.
|
||||
- **Domain:** Fehlschlagenden `LicenseMatrixServiceTest` behoben; fehlende `reiterLizenz`-Daten in Test-Reitern ergänzt und Fallback-Logik in `LicenseMatrixServiceImpl` für spartenübergreifende Lizenzen (z.B. Springlizenz für Dressur-Basis) stabilisiert.
|
||||
- **Infrastructure:** Fehlschlagenden `RegulationSeedVerificationTest` behoben; Testdaten an das neue Modell (`reiterLizenz` Feld) angepasst.
|
||||
- **Infrastructure:** Kompilierfehler 'Unresolved reference lizenzKlasse' in `ReiterExposedRepository` behoben; fehlendes Feld `lizenzKlasse` zu `ReiterTable` und Datenbank-Migration `V010` hinzugefügt.
|
||||
- **Onboarding:** `remember` → `rememberSaveable` für `geraetName`, `sharedKey`, `znsStatus` in `OnboardingScreen.kt` (
|
||||
Felder gingen bei Zurück-Navigation verloren)
|
||||
- **AbteilungsRegelService:** CSN-C-NEU Pflicht-Teilungslogik implementiert (≤95 cm: ohne/mit Lizenz; ≥100 cm: R1/R2+);
|
||||
`SparteE`-Import ergänzt
|
||||
|
||||
- Desktop-Packaging konfiguriert: `.deb` (Linux), `.msi` (Windows), `.dmg` (macOS)
|
||||
- Zentrale Versionsdatei `version.properties` (Single Source of Truth für SemVer)
|
||||
- Automatisches Git-Tagging via CI/CD (`release.yml` Gitea Actions Workflow)
|
||||
- `CHANGELOG.md` eingeführt (dieses Dokument)
|
||||
|
||||
---
|
||||
|
||||
## [1.0.6-SNAPSHOT] — 2026-04-10
|
||||
### [1.0.6-SNAPSHOT] — 2026-04-10
|
||||
|
||||
### Hinzugefügt
|
||||
- **Entries-Domain:** Strukturiertes Abteilungs-Warnungssystem gemäß ÖTO § 39 implementiert.
|
||||
|
||||
@@ -51,337 +51,88 @@ und über definierte Schnittstellen kommunizieren.
|
||||
|
||||
---
|
||||
|
||||
## 1. Abgeschlossene Phasen
|
||||
## 1. Abgeschlossene Phasen (Verifiziert)
|
||||
|
||||
### PHASE 1: Documentation Cleanup ✅ ABGESCHLOSSEN
|
||||
*Ziel: Eine einzige, vertrauenswürdige Quelle der Wahrheit (SSOT) schaffen.*
|
||||
### PHASE 1: Domain-Design & Ubiquitous Language ✅
|
||||
|
||||
#### 🧹 Agent: Curator
|
||||
* [x] **Archivierung:** Veraltete Docs (Cloudflare, GitHub-Workflows, alte Roadmaps) nach `docs/_archive/` verschoben.
|
||||
* [x] **Konsolidierung:** `Zora_System_Architektur.md` als zentrale Infrastruktur-Doku etablieren.
|
||||
* [x] **Struktur:** `docs/` Ordner aufräumen (unnötige Root-Files in Unterordner).
|
||||
* [x] **Index:** `README.md` im Root als Einstiegspunkt aktualisieren.
|
||||
*Status: Fachliche Grundlage vorhanden.*
|
||||
|
||||
### PHASE 2: Infrastructure Hardening ✅ ABGESCHLOSSEN
|
||||
*Ziel: Stabilisierung der neuen Self-Hosted Umgebung.*
|
||||
* [x] **DDD-Analyse:** 6 Bounded Contexts (SCS-Architektur) definiert.
|
||||
* [x] **Terminologie:** `Veranstaltung` ≠ `Turnier` gemäß ÖTO § 2 Abs. 1 festgelegt.
|
||||
* [x] **Ubiquitous Language:** Offizielle Domänen-Terminologie erstellt.
|
||||
|
||||
#### 🐧 Agent: DevOps Engineer
|
||||
### PHASE 2: Infrastruktur & ZNS-Importer (Prototyp) ✅
|
||||
|
||||
* [x] **Keycloak Fix:** Verbindungsprobleme innerhalb des Docker-Netzwerks behoben (Alias `auth.mo-code.at`).
|
||||
* [x] **Backup Strategy:** Automatisierte Backups für Gitea & Datenbanken auf Zora (`config/scripts/backup.sh`).
|
||||
* [x] **Monitoring:** Prometheus/Grafana Dashboard für Zora finalisiert (`dc-ops.yaml`).
|
||||
* [x] **Deployment:** Git-basiertes Deployment-Skript (`config/scripts/deploy.sh`) erstellt.
|
||||
*Status: Grundgerüst steht, Performance-Probleme bekannt.*
|
||||
|
||||
### PHASE 3: Domain-Design & Ubiquitous Language ✅ ABGESCHLOSSEN
|
||||
|
||||
*Ziel: Fachliche Grundlage für die Implementierung schaffen.*
|
||||
|
||||
#### 🏗️ Agent: Lead Architect
|
||||
|
||||
* [x] **DDD-Analyse:** 6 Bounded Contexts (SCS-Architektur) definiert und priorisiert.
|
||||
* [x] **Terminologie:** `Veranstaltung` ≠ `Turnier` gemäß ÖTO § 2 Abs. 1 festgelegt (ADR).
|
||||
* [x] **Design-Baseline:** Vision_03 (Figma) als offizieller Design-Baseline festgelegt.
|
||||
* [x] **Technologie:** Desktop-First-Strategie mit KMP/Compose Desktop beschlossen.
|
||||
|
||||
#### 📜 Agent: ÖTO/FEI Rulebook Expert
|
||||
|
||||
* [x] **Ubiquitous Language:** Offizielle Domänen-Terminologie mit ÖTO-Referenzen erstellt.
|
||||
* [x] **Abteilungs-Schwellenwerte:** Alle Trennungs-Schwellenwerte (§ 39 + spartenspezifisch) dokumentiert.
|
||||
→ `docs/03_Domain/02_Reference/OETO_Regelwerk/Abteilungs-Trennungs-Schwellenwerte.md`
|
||||
|
||||
#### 👷 Agent: Backend Developer
|
||||
|
||||
* [x] **Enums:** `SparteE`, `TurnierkategorieE`, `VeranstaltungsTypE`, `LizenzKlasseE`, `NennungsStatusE`,
|
||||
`StartwunschE` – ÖTO-konform.
|
||||
* [x] **Domain-Modelle:** `DomReiter` (actor-context), `DomNennung`, `DomNennungsTransfer` (registration-context).
|
||||
* [x] **Modul:** `entries-domain` als KMP-Modul aufgesetzt und in `settings.gradle.kts` registriert.
|
||||
* [x] **ZNS-Parser:** Grundsätzliche Fähigkeit zum Parsen von ZNS-Daten (Reiter, Pferde, Vereine, Funktionäre).
|
||||
* [x] **UI-Gerüst:** Navigation und Dialog-Hüllen in Compose Desktop vorhanden.
|
||||
* [x] **Plan-B:** Rudimentärer Mail-Service für Nennungs-Versand (funktional).
|
||||
|
||||
---
|
||||
|
||||
## 2. Aktuelle Phase
|
||||
## 2. Der neue Weg: Fachliche Realität (Roadmap 2026)
|
||||
|
||||
### PHASE 4: MVP-Implementierung ✅ ABGESCHLOSSEN
|
||||
Fokus: Physische Implementierung der Turnier-Hierarchie.
|
||||
|
||||
*Ziel: Lauffähiger MVP für `registration-context` und `actor-context` (P1-Contexts).*
|
||||
### MEILENSTEIN 1: Die Basis-Hierarchie (Prio 1) 🔵 IN ARBEIT
|
||||
|
||||
#### 🧐 Agent: QA Specialist
|
||||
*Ziel: Veranstaltung -> Turnier -> Bewerb/Abteilung physisch anlegen und speichern.*
|
||||
|
||||
* [x] **Actor Context Stabilization:** Funktionär-Datenmodell (Richter/Parcoursbauer) auf professionelle Master-Daten-Referenzierung umgestellt und mit Reiter-Daten verknüpft (Import-Idempotenz via `satzNummer`). Redundante Kontakt-/Adressdaten entfernt. Alle ZNS-Import-Tests (9/9) stabilisiert und verwaiste Parser-Reste entfernt.
|
||||
* [x] **Masterdata Standardization:** Bereinigung und Standardisierung der Masterdaten-Tabellen (Mehrzahl-Konvention: `bundeslaender`, `funktionaers_qualifikationen`, `reit_lizenzen`, `turnier_klassen`).
|
||||
* [x] **ÖTO Data Seeding:** Umfassende Seeder für Funktionärs-Qualifikationen, Turnierklassen und Turnier-Sparten gemäß ÖTO implementiert. Einführung der Tabelle `turnier_sparten`.
|
||||
* [x] **ZNS-Import Optimization:** Automatische Verknüpfung von Funktionären mit Reitern (Reihenfolge: VEREIN -> LIZENZ -> PFERDE -> RICHT). `ZnsImportService` für sequentielle Imports in Tests gehärtet.
|
||||
* [x] **Service Stability:** Port-Konflikt des `masterdata-service` (Spring Management Port 8081 vs. Gateway) durch Umzug auf Port 8086 und explizite Bind-Adressen (Spring: 127.0.0.1, Ktor: 0.0.0.0) dauerhaft gelöst.
|
||||
* [x] **Documentation:** `CHANGELOG.md` aktualisiert und Port-Konfiguration in `application.yml` dokumentiert.
|
||||
→ Note: `IdempotencyApiIntegrationTest` bleibt vorerst @Disabled, da das Hochfahren des Spring-Contexts in der
|
||||
Testumgebung blockiert (unabhängig vom Plugin).
|
||||
→ Task: Integration-Test Umgebung (Port-Binding/Server-Lifecycle) für `masterdata-service` untersuchen.
|
||||
* [ ] **Persistenz-Layer:** Implementierung der lokalen Speicherung für alle Ebenen der Hierarchie.
|
||||
* [ ] **Turnier-Wizard (Echt):** Umstellung des Wizards von `println`-Dummies auf echte Datenbank-Transaktionen.
|
||||
* [ ] **Validierung:** Sicherstellen, dass Pflichtfelder (Turniernummer, Sparte) korrekt erfasst werden.
|
||||
|
||||
#### 🏗️ Agent: Lead Architect
|
||||
### MEILENSTEIN 2: ZNS-Performance & Daten-Qualität (Prio 2)
|
||||
|
||||
* [x] **ADRs vervollständigen:** Bounded Context Mapping und Context Map dokumentieren.
|
||||
→ `docs/01_Architecture/adr/0014-bounded-context-mapping-de.md`
|
||||
→ `docs/01_Architecture/adr/0015-context-map-de.md`
|
||||
* [x] **API-Design:** Schnittstellen zwischen den Contexts definieren (Anti-Corruption Layer).
|
||||
→ `docs/01_Architecture/adr/0016-api-design-acl-de.md`
|
||||
* [x] **ÖTO-Validation-Seeds:** Seed-Daten für Lizenz-Matrix und Altersklassen finalisiert (V008).
|
||||
*Ziel: Import der ZNS.zip in < 2 Minuten statt 30+ Minuten.*
|
||||
|
||||
#### 👷 Agent: Backend Developer
|
||||
* [ ] **Batch-Processing:** Umstellung des `ZnsImportService` auf Batch-Inserts (JDBC/Exposed).
|
||||
* [ ] **Fortschritts-Anzeige:** Reale Rückmeldung über den Import-Status in der UI.
|
||||
|
||||
* [x] **ZNS-Importer:** Support für Richter-Import (RICHT01.DAT) und Reiter-Refactoring (LIZENZ01.DAT) vervollständigt. ✓
|
||||
* [x] **Masterdata:** Qualifikations-System und Personen-Referenzen (Vereine, Bundesländer, Nationen) stabilisiert (Consul & MasterdataSeeder). ✓
|
||||
* [x] **Infrastruktur:** Service-Discovery (Consul) für alle Microservices (incl. Masterdata) aktiviert.
|
||||
* [x] **Infrastruktur:** Bean-Definitionen und Dependency-Injection im `zns-import-service` bereinigt.
|
||||
* [x] **Database:** Initialisierung der Funktionärs-Tabellen stabilisiert (PSQLException Fix).
|
||||
* [x] **`actor-context`:** Domain-Modelle für `Pferd`, `Funktionaer`, `Verein` implementiert.
|
||||
* [x] **`registration-context`:** `DomBewerb`, `DomAbteilung`, `DomStartliste` implementiert.
|
||||
* [x] **`event-management-context`:** `DomVeranstaltung`, `DomTurnier`, `DomAusschreibung` implementiert.
|
||||
* [x] **Persistenz:** Repository-Interfaces und erste DB-Migrationen (Flyway/Liquibase).
|
||||
* [x] **API:** REST-Endpunkte für Nennungs-Workflow (Kern-Use-Cases).
|
||||
* [x] **Infrastruktur-Stabilisierung:** Kompilierfehler in `masterdata-infrastructure` behoben.
|
||||
* [x] **Identity-Schnittstellen:** Endpunkte für ZNS-Linking über `identity-service` bereitgestellt.
|
||||
### MEILENSTEIN 3: Richtverfahren & Bewerbs-Konfiguration (Prio 3)
|
||||
|
||||
#### 🎨 Agent: Frontend Expert
|
||||
*Ziel: Bewerbe mit fachlich korrekten Regeln (ÖTO) anlegen.*
|
||||
|
||||
* [x] **KMP/Compose Desktop:** Projektstruktur aufgesetzt (`frontend/shells/meldestelle-desktop`).
|
||||
* [x] **Navigation:** Sidebar-Navigation gemäß Vision_03 implementiert (Veranstaltungen, Reiter, Pferde, Funktionäre,
|
||||
Meisterschaften, Cups).
|
||||
* [x] **Nennungs-Screen:** `TurnierDetailScreen` integriert `NennungsMaske` aus `nennung-feature` (Bewerbe-Tab ⭐).
|
||||
|
||||
#### 📜 Agent: ÖTO/FEI Rulebook Expert
|
||||
|
||||
* [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)
|
||||
|
||||
* [x] **ZNS-Importer (MVP) – Phase 1 & 2:** `core:zns-parser` (KMP), `ZnsLegacyParsers` (alle 4 Dateitypen, CP850),
|
||||
`ZnsImportService` (Orchestrator, ZIP in-memory, Upsert), Unit-Tests grün.
|
||||
→ Detaillierte Planung: `docs/01_Architecture/Roadmap_ZNS_Importer.md`
|
||||
* [x] Backend-Infrastruktur & CP850 Parser (Phase 1 – Parser/Modul)
|
||||
* [x] Domain-Mapping & Upsert in DB (Phase 2)
|
||||
* [x] REST-API & Job-Management (Phase 1 – Controller/Job-Registry)
|
||||
* [x] Frontend-Integration mit File-Picker & Status-Polling (Phase 3)
|
||||
* [ ] **Richtverfahren-Engine:** Validierungslogik für verschiedene Richtverfahren (Fehler/Zeit, Wertnoten).
|
||||
* [ ] **Abteilungs-Logik:** Automatische Teilungsvorschläge gemäß ÖTO § 39.
|
||||
|
||||
---
|
||||
|
||||
## 3. Initiative: Wizard-Orchestrator & Offline-Drafts (Q2/Q3 2026)
|
||||
## 3. Zukünftige Module (Status: Geplant / Vision)
|
||||
|
||||
🏗️ Verantwortlich: Lead Architect · 🎨 Frontend · 🖌️ UI/UX · 👷 Backend · 🧐 QA · 🧹 Curator
|
||||
*Diese Module existieren derzeit nur als Konzepte oder leere Hüllen.*
|
||||
|
||||
Ziel: Konsolidierung aller „Wizards“ auf ein deklaratives Orchestrierungs-Framework (Graph + Guards + Effects), vereinheitlichte Validierung und Offline-Draft-Fähigkeit inkl. Delta‑Sync. Desktop-first, tastaturbedienbar, testbar.
|
||||
|
||||
### 3.1 Kernbausteine
|
||||
- Orchestrator Runtime & DSL: `StepId`, `WizardContext`, `WizardState`, `Guard`, `Transition`, `StepEffects`.
|
||||
- WizardScaffold: Breadcrumb, Kontext-Chips, Footer mit Hotkeys (Enter/Shift+Enter/Alt+S), Fehler-Summary.
|
||||
- DraftStore: Autosave pro Step (`onLeave`), Resume, `flowVersion`, Konfliktanzeige.
|
||||
- DevTools: strukturierte Transition-Logs, Graph-Export (DOT/PlantUML).
|
||||
|
||||
Referenzen/Dokumente:
|
||||
- ADR‑0025: Wizard-Orchestrator (State‑Machine, DSL, Guards, Effects) → `docs/01_Architecture/adr/0025-wizard-orchestrator-de.md`
|
||||
- ADR‑0026: Step-Validation-Policy (sync vs. async, Fehlersichtbarkeit, Hotkeys) → `docs/01_Architecture/adr/0026-validation-policy-de.md`
|
||||
- ADR‑0027: Draft-Domain & Delta‑Sync (Versionierung, Konfliktlösung, Idempotenz) → `docs/01_Architecture/adr/0027-draft-domain-and-delta-sync-de.md`
|
||||
- Reference: Wizard‑DSL README (Beispiel-Flow Event) → `docs/01_Architecture/Reference/Wizard-DSL-README.md`
|
||||
|
||||
### 3.2 Migrationsstrategie (Strangler)
|
||||
1) Parallelbetrieb: Neuer Orchestrator in `frontend/core/wizard`; bestehende VMs delegieren schrittweise.
|
||||
2) Inkrement 1: Event‑Flow – zunächst 2 Steps (ZNS_CHECK, VERANSTALTER_SELECTION), dann alle 6 Steps.
|
||||
3) Feature‑Flag `WizardRuntimeEnabled` für risikoarmen Rollout.
|
||||
|
||||
### 3.3 Phasenplanung (Auszug)
|
||||
- Phase 1 (Core & Tooling, 2–3 Wochen): Runtime/DSL, DevLogs, Graph‑Export, Scaffold‑MVP, Unit‑Tests.
|
||||
- Phase 2 (Event‑Flow, 2–3 Wochen): `EventStep/Acc/Guards`, Flow‑DSL, VM‑Delegation, Validierung, Autosave/Resume.
|
||||
- Phase 3 (Backend, 2–4 Wochen): Draft-/Validate‑APIs, Offline‑Queue, Delta‑Sync für Turniere.
|
||||
- Phase 4 (Skalierung, 6–10 Wochen, parallel): Weitere Flows je Bounded Context.
|
||||
- Phase 5–7 (2–3 + 1–2 + 1–2 Wochen): UX‑Härtung, Observability/Rollout‑Gates, Stabilisierung & Abschaltung Altlogik.
|
||||
|
||||
Grobe Gesamtdauer: 17–29 Wochen je nach Parallelisierung.
|
||||
|
||||
### 3.4 Akzeptanzkriterien (DoD Initiative)
|
||||
- Alle priorisierten Flows laufen über Orchestrator; Next/Back/History deterministisch; Graph‑Export aktuell.
|
||||
- DraftStore produktiv; Resume deterministisch; Delta‑Sync idempotent; Konflikte nicht‑blockierend sichtbar.
|
||||
- Validierungs‑Policy konsistent; Tastatur‑Bedienung vollständig; Performance‑Gates eingehalten.
|
||||
- ADR‑0025/0026/0027 veröffentlicht; Wizard‑DSL‑Reference vorhanden; CI grün; Metriken/Alerts aktiv.
|
||||
|
||||
### 3.5 10‑Tage‑Startplan
|
||||
- Tag 1–2: Runtime/DSL‑Skelett, Scaffold‑MVP, Feature‑Flag, README Skeleton.
|
||||
- Tag 3: EventStep/Acc/Guards, EventFlow (2 Steps), VM‑Delegation minimal.
|
||||
- Tag 4: Tests Runtime/Guards, Graph‑Export, Dev‑Logs.
|
||||
- Tag 5–6: META_DATA/ANSPRECHPERSON migrieren, Validierungs‑API, Fehler‑Summary.
|
||||
- Tag 7: DraftStore lokal (Autosave/Resume), Property‑Test Resume.
|
||||
- Tag 8: TURNIER_ANLAGE einbetten, Sync via `onComplete`.
|
||||
- Tag 9: SUMMARY + Finalisierung, Offload in Offline‑Queue (Stub).
|
||||
- Tag 10: ADR‑0025/0026/0027 Review+Merge; Journal‑Eintrag.
|
||||
|
||||
Journal: `docs/99_Journal/2026-04-21_Wizard-Orchestrator_Roadmap_Anchoring.md`
|
||||
* **Nennungs-Management:** Erfassung von Nennungen gegen den ZNS-Datenbestand.
|
||||
* **Zeitplan:** Dynamische Zeitplanung (Drag & Drop).
|
||||
* **Ergebnisse:** Erfassung von Wertungen und Platzierungsberechnung.
|
||||
* **Abrechnung:** Vollständiger `billing-context`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Aktuelle Phase
|
||||
## 4. Archiv der fiktiven Meilensteine (Reality-Check am 28.04.2026)
|
||||
|
||||
### Progress Checkpoint – 2026-04-21 (Wizard-Orchestrator Initiative)
|
||||
*Die folgenden Einträge wurden in früheren Sitzungen als "Abgeschlossen" markiert, entsprachen aber nicht dem realen
|
||||
Code-Stand.*
|
||||
|
||||
- Core/DSL: angelegt in `frontend/core/wizard` (Runtime, DSL), erste Tests grün.
|
||||
- UI: `WizardScaffold` (MVP) + Hotkeys-Wrapper (Enter/Shift+Enter/Alt+S) vorhanden.
|
||||
- Feature-Integration: Veranstaltungs-Wizard hinter Flag teilweise delegiert.
|
||||
- Drafts: In‑Memory DraftStore (Autosave/Resume Hooks) angebunden.
|
||||
- DI: Koin-Parameterübergabe für `EventWizardViewModel` vereinheitlicht.
|
||||
- Flag: `WizardRuntimeEnabled = false` (Standard AUS; Dev-Verprobung manuell).
|
||||
<details>
|
||||
<summary>Frühere (fiktive) Meilensteine anzeigen</summary>
|
||||
|
||||
Nächste Schritte (Kurz): Tests für `needsContactPerson` (beide Zweige), VM‑Delegation für weitere Steps, Footer‑Fehler‑Summary, persistenter DraftStore, Dev‑Overlay.
|
||||
### PHASE 4: MVP-Implementierung (Früherer Status: Abgeschlossen)
|
||||
|
||||
### PHASE 5: P2-Contexts & Integration ✅ ABGESCHLOSSEN
|
||||
* [ ] ZNS-Import Optimierung (Batching) -> In MEILENSTEIN 2 verschoben.
|
||||
* [ ] `event-management-context` Implementierung -> In MEILENSTEIN 1 verschoben.
|
||||
|
||||
*Ziel: `competition-context` und `event-management-context` implementieren.*
|
||||
### PHASE 5-13 (Früherer Status: Abgeschlossen/In Arbeit)
|
||||
|
||||
* [x] **`competition-context`:** Bewerbe, Startlisten, Ergebnisse, Abteilungs-Warn-Logik.
|
||||
* [x] **`event-management-context`:** Veranstaltungs- und Turnier-Verwaltung, Ausschreibungs-Generator.
|
||||
* [x] **ZNS-Integration:** Schnittstelle zum Zentralen Nennungs-System (A-Satz / B-Satz).
|
||||
* [x] **Offline-Sync:** Offline-First-Strategie für Desktop-App implementieren.
|
||||
* [ ] `competition-context` (Bewerbe, Startlisten) -> Fachlogik fehlt weitgehend.
|
||||
* [ ] `billing-context` (Abrechnung) -> Nur Infrastruktur-Hülle vorhanden.
|
||||
* [ ] `results-service` -> Geschäftslogik fehlt.
|
||||
|
||||
### PHASE 6: P3-Contexts & Billing ✅ ABGESCHLOSSEN
|
||||
|
||||
*Ziel: `billing-context` und `identity-context` implementieren.*
|
||||
|
||||
* [x] **`billing-context`:** Gebührenberechnung, Kassa, Abrechnung.
|
||||
* [x] **`identity-context`:** Rollen-Modell (TBA, Veranstalter, Richter etc.) mit Keycloak.
|
||||
* [x] **Reporting:** Startlisten- und Ergebnislisten-Druck (PDF).
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## 4. Geplante Phasen
|
||||
|
||||
### PHASE 7: Desktop-Vernetzung & Zentrale Verwaltung ✅ ABGESCHLOSSEN
|
||||
|
||||
*Ziel: LAN-Kommunikation Vorbereitung und Etablierung der "Veranstaltung-Verwaltung" als zentrale Schaltstelle.*
|
||||
|
||||
* [x] **Zentrale Verwaltung:** Etablierung der `Veranstaltung-Verwaltung` (Zentrale) als administratives Cockpit.
|
||||
* [x] **Navigation:** Implementierung eines Back-Stack-Systems für intelligente "Zurück"-Navigation.
|
||||
* [x] **Domänen-Synchronisation:** Anpassung der Frontend-Stores an die Backend-Masterdata-Modelle (Reiter, Pferde,
|
||||
Vereine, Funktionäre).
|
||||
* [x] **ZNS-Integration (Frontend):** ZNS-Importer in die Zentrale integriert; Konzept "Globaler Pool -> Lokale
|
||||
Synchronisation" gefestigt.
|
||||
* [x] **Terminologie:** UI-weit Umstellung von "Event" auf "Veranstaltung" (ÖTO-konform).
|
||||
* [x] **Konzept:** LAN-Discovery (mDNS) und Echtzeit-Sync (WebSockets) entworfen.
|
||||
* [x] **ADR:** ADR-0020 (Lokale Netzwerk-Kommunikation) erstellt.
|
||||
|
||||
### PHASE 8: Bewerbe-Management & Startlisten ✅ ABGESCHLOSSEN
|
||||
|
||||
*Ziel: Fachliche Tiefe in den Turnieren (Import, Generierung, Zeitberechnung).*
|
||||
|
||||
* [x] **Konzept/ADR:** LAN‑Sync (ADR‑0022) und Offline‑First Desktop↔Backend Konzept definiert und verlinkt.
|
||||
* [x] **Bewerbe-Import:** Implementierung der Merge-Logik (ZNS-XML -> BewerbUiModel). ✓
|
||||
* [x] **Startlisten-Automatisierung:** Generierung und Zeitberechnung (Pausen, Umbauzeiten). ✓
|
||||
* [x] **Discovery:** Implementierung des mDNS-Service (JmDNS) für die Geräte-Suche. ✓
|
||||
* [x] **Transport:** Aufbau der WebSocket-Infrastruktur für P2P-Sync (Ktor WebSockets, SyncManager). ✓
|
||||
* [x] **Offline-First Desktop↔Backend:** Umsetzung gemäß Konzept „Offline-First Synchronisation (Desktop ↔ Backend)“ → `docs/01_Architecture/konzept-offline-first-desktop-backend-de.md`. ✓
|
||||
* [x] **Regelwerks-Validierung:** Implementierung des strukturierten Abteilungs-Warnungssystems gemäß ÖTO § 39 inkl. UI-Integration. ✓
|
||||
|
||||
### PHASE 9: Zeitplan-Optimierung & Protokollierung ✅ ABGESCHLOSSEN
|
||||
|
||||
*Ziel: Dynamische Zeitplan-Anpassungen, Protokollierung von Änderungen und Export-Funktionen.*
|
||||
|
||||
* [x] **Billing-Service:** Initialisierung, Teilnehmer-Konten & Buchungs-Logik (v1). ✓
|
||||
* [x] **Entries-Integration:** Automatische Buchung von Nenngeldern bei Nennungs-Abgabe. ✓
|
||||
* [x] **ZNS-Importer:** Hardening & Integrationstests für Funktionärs-Updates. ✓
|
||||
* [x] **Konzept:** Fachliches Konzept für Zeitplan-Optimierung (Drag & Drop) erstellt. ✓
|
||||
* [x] **Konzept:** Status-Automat für Nennungen & Zeitplan-Synchronisation spezifiziert. ✓
|
||||
* [x] **Frontend-Standardisierung:** `nennung-feature` refactored und in Desktop-Shell integriert. ✓
|
||||
* [x] **Rulebook-Check:** ÖTO §43 "Parcoursbesichtigung zu Pferd" eingearbeitet. ✓
|
||||
* [x] **Feature-Migration:** Pferde-, Reiter-, Funktionärs- und Veranstalter-Module vollständig auf KMP umgestellt. ✓
|
||||
* [x] **Cleanup:** `FRONTEND_CLEANUP_TODO.md` für Migration von `v2` Screens weitestgehend abgeschlossen. ✓
|
||||
* [x] **Zeitplan:** Dynamische Verschiebung von Bewerben (Drag & Drop im Kalender). ✓
|
||||
* [x] **Protokoll:** Implementierung eines Event-Logs für manuelle Eingriffe in Startlisten (Audit-Log). ✓
|
||||
* [x] **Export:** Startlisten-Export für ZNS (XML-B-Satz). ✓
|
||||
|
||||
### PHASE 10: Series-Context & Stammdaten ✅ ABGESCHLOSSEN
|
||||
|
||||
*Ziel: Stammdaten-Integration (Reiter, Pferde, Funktionäre) und Series-Context (Cups).*
|
||||
|
||||
* [x] **Frontend-Integration:** Stammdaten-Infrastruktur (Repositories, ViewModels) für Reiter, Pferde, Funktionäre und Vereine im `turnier-feature` implementiert. ✓
|
||||
* [x] **Nennungs-Management:** Funktionalisierung des Nennungs-Tabs mit Echt-Datenanbindung und Suche. ✓
|
||||
* [x] **`series-context`:** Pluggable Berechnungsmodell (Streichresultate, Alles zählt), konfigurierbare Paar-Bindung (Reiter+Pferd vs. Einzelwertung) implementiert. ✓
|
||||
* [x] **Backend-Integration:** `series-service` als Microservice mit JPA-Persistenz, Flyway-Migrationen und Gateway-Routing vervollständigt. ✓
|
||||
|
||||
## 4. Geplante Phasen
|
||||
|
||||
### PHASE 11: Ergebniserfassung & Platzierung ✅ ABGESCHLOSSEN
|
||||
|
||||
*Ziel: Vollständige Ergebniserfassung und automatisierte Platzierungsberechnung.*
|
||||
|
||||
* [x] **Backend (Results):** Implementierung der Geschäftslogik für Wertnoten, Zeitfehler und ÖTO-konforme Platzierungen. ✓
|
||||
* [x] **Backend-Infrastruktur:** `results-service` in Docker-Compose und API-Gateway integriert; Service-Discovery via Consul aktiviert. ✓
|
||||
* [x] **Frontend UI:** `ErgebnisEditDialog` zur schnellen Ergebniserfassung und `TurnierErgebnislistenTab` zur Anzeige realer Ergebnisse. ✓
|
||||
* [x] **PDF-Export:** Generierung von PDF-Ergebnislisten (Bewerbe und Serien). ✓
|
||||
|
||||
### PHASE 12: Abrechnung & Billing 🔵 IN ARBEIT
|
||||
|
||||
*Ziel: Vollständige Kassa-Funktionalität und Turnier-Abrechnung.*
|
||||
|
||||
* [x] **Backend-Infrastruktur:** `billing-service` initialisiert, Docker-Integration und Gateway-Routing (Port 8087) konfiguriert. ✓
|
||||
* [x] **Frontend-Anbindung:** `BillingRepository` (Ktor) und `BillingViewModel` auf reale API-Kommunikation umgestellt. ✓
|
||||
* [x] **Buchungs-Logik:** Implementierung von Soll/Haben-Buchungen (Startgebühren, Nenngelder, Boxen). ✓
|
||||
* [x] **Offene Posten:** Liste aller unbezahlten Beträge pro Teilnehmer/Pferd. ✓
|
||||
* [x] **Rechnungserstellung:** Generierung von PDF-Rechnungen und Zahlungsbestätigungen. ✓
|
||||
* [x] **Kassa-Management:** Tagesabschluss, Storno-Logik und verschiedene Zahlungsarten. ✓
|
||||
|
||||
---
|
||||
|
||||
## 4. Geplante Phasen
|
||||
|
||||
### PHASE 13: Frontend-Modernisierung & Cleanup ✅ ABGESCHLOSSEN (20. April 2026)
|
||||
*Ziel: Finalisierung der Turnier-Daten, Rückübermittlung an den OEPS und architektonische Bereinigung.*
|
||||
|
||||
* [x] **"V2"-Bereinigung:** Vollständige Eliminierung aller "V2"-Suffixe in Dateinamen und Symbolen (z.B. `TurnierWizardV2`, `VeranstalterAuswahlV2`). ✓ (20. April 2026)
|
||||
* [x] **Plug-and-Play (Turnier):** Umstellung des `turnier-feature` auf ADR-0024. Entfernung von Reflection-Zugriffen auf die Shell und Einführung von ViewModel-Hoisting. ✓ (20. April 2026)
|
||||
* [x] **Plug-and-Play (Veranstalter):** Umstellung des `veranstalter-feature` auf ADR-0024. Einführung des `VeranstalterDetailViewModel` und Konsolidierung der Screens in der Desktop-Shell. ✓ (20. April 2026)
|
||||
* [x] **Device-Setup ("Lock-and-Edit"):** Einführung eines Review-Modus mit Konfigurations-Sperre, Drucker-Integration und Maskierung des SharedKeys. ✓ (20. April 2026)
|
||||
* [x] **Veranstaltungs-Wizard:** Implementierung eines 6-stufigen Profi-Workflows mit Sticky Preview-Card (WYSIWYG), ZNS-Guard und OEPS-Satznummer-Mapping. ✓ (20. April 2026)
|
||||
* [x] **Code-Hygiene:** Beseitigung von Code-Smells, redundanten Validierungen und ungenutzten Parametern in den zentralen Frontend-Modulen. ✓ (20. April 2026)
|
||||
* [x] **Connectivity-Diagnose:** Stabiles Diagnose-Tool für Backend-, DB- und Auth-Verbindung in der Desktop-App. ✓ (18. April 2026)
|
||||
* [x] **WASM-Transition:** Projektweite Umstellung auf JVM (Desktop) und wasmJs (Web). Eliminierung von `js(IR)`. ✓ (18. April 2026)
|
||||
* [x] **Geräte-Initialisierung:** Refactoring des Onboarding-Prozesses in das Plug-and-Play Modul `device-initialization`. ✓ (18. April 2026)
|
||||
* [ ] **XML-Export:** Vollständiger B-Satz Export (inkl. Ergebnisse und Platzierungen).
|
||||
* [ ] **ZNS-Portal:** Upload-Integration in das OEPS-ZNS.
|
||||
* [ ] **Archivierung:** Langzeit-Archivierung abgeschlossener Turniere.
|
||||
|
||||
---
|
||||
|
||||
## 5. Wichtige Architektur-Entscheidungen (ADRs)
|
||||
|
||||
| # | Entscheidung | Status | Dokument |
|
||||
|----|--------------------------------------------------------------|--------|------------------------------|
|
||||
| 1 | Vision_03 = Design-Baseline | ✅ | Session Log 2026-03-24 |
|
||||
| 2 | Desktop-First mit KMP/Compose Desktop | ✅ | ADR-0009 |
|
||||
| 3 | `Veranstaltung` ≠ `Turnier` (ÖTO § 2 Abs. 1) | ✅ | Ubiquitous Language |
|
||||
| 4 | 6 Bounded Contexts als SCS-Architektur | ✅ | Session Log 2026-03-24 |
|
||||
| 5 | `series-context` ist Phase 2+ (Architektur vorbereitet) | ✅ | Session Log 2026-03-24 |
|
||||
| 6 | Cups/Serien benötigen konfigurierbare Reglements | ✅ | Session Log 2026-03-24 |
|
||||
| 7 | Warn-Logik statt harter Fehler (Override-Event) | ✅ | Abteilungs-Schwellenwerte.md |
|
||||
| 8 | 6 Bounded Contexts: Mapping & Aggregate Roots | ✅ | ADR-0014 |
|
||||
| 9 | Context Map: Integration Patterns & ACL-Strategie | ✅ | ADR-0015 |
|
||||
| 10 | API-Design & ACL: Ports, DTOs, REST-Endpunkte, Domain Events | ✅ | ADR-0016 |
|
||||
| 11 | Masterdata: Importer-Einbettung als Worker | ✅ | ADR-0017 |
|
||||
| 12 | Masterdata: Rule-Versionierung (Regulation-as-Data) | ✅ | ADR-0018 |
|
||||
| 13 | Masterdata: API-Schichten (REST vs. Ingestion) | ✅ | ADR-0019 |
|
||||
| 14 | Lokale Netzwerk-Kommunikation und Daten-Isolierung | ✅ | ADR-0020 |
|
||||
| 15 | Masterdata: Observability & Operations | ✅ | masterdata-ops.md, CHANGELOG |
|
||||
| 16 | Tenant-Resolution: Schema-per-Tenant | ✅ | ADR-0021 |
|
||||
| 17 | LAN-Sync-Protokoll (Lamport-Uhren, Event-Sourcing Light) | ✅ | ADR-0022 |
|
||||
| 18 | Domain-Naming: Kein `Dom`-Präfix für Entitäten | ✅ | ADR-0023 |
|
||||
| 19 | Plug-and-Play Architektur für UI-Komponenten | ✅ | ADR-0024 |
|
||||
|
||||
---
|
||||
|
||||
## 5. Wichtige Referenzen
|
||||
|
||||
@@ -404,50 +155,3 @@ Nächste Schritte (Kurz): Tests für `needsContactPerson` (beide Zweige), VM‑D
|
||||
| Zeitplan-Optimierung | `docs/01_Architecture/konzept-zeitplan-optimierung-de.md` |
|
||||
| Parcoursbesichtigung-Rulebook | `docs/01_Architecture/rulebook-check-parcoursbesichtigung-de.md` |
|
||||
| Status-Automat-Nennungen | `docs/01_Architecture/status-automat-nennungen-de.md` |
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 3. Zukünftige Phase (April 2026)
|
||||
|
||||
### PHASE 5: Web-App & Neumarkt-Vorbereitung 🔵 IN ARBEIT (Start 13. April 2026)
|
||||
|
||||
*Ziel: Fertigstellung der Web-App für Online-Nennungen und Vorbereitung des Neumarkt-Turniers (24. April).*
|
||||
|
||||
#### 🎨 Agent: Frontend Expert
|
||||
* [x] **Web-App Shell:** Modul `frontend:shells:meldestelle-web` (Compose WasmJS) initialisiert.
|
||||
* [x] **UI-Komponenten:** `VeranstaltungsCard` und `TurnierCard` für Web implementiert (mit PDF- & Nenn-Button).
|
||||
* [x] **Workflow:** `NennungWebFormular` Prototyp erstellt (mit simuliertem Mail-Versand).
|
||||
|
||||
#### 👷 Agent: Backend Developer
|
||||
* [x] **Daten-Seeding:** Desktop-Stores mit echten Daten für Neumarkt (April 2026) vorbefüllt.
|
||||
* [ ] **Mail-Service:** Integration eines E-Mail-Dienstes für eingehende Nennungen.
|
||||
|
||||
#### 🧐 Agent: QA Specialist
|
||||
* [x] **Verifikation:** Desktop-Screens (Veranstalter, Turnier, Bewerbe) mit echten Daten geprüft.
|
||||
* [ ] **End-to-End Test:** Online-Nennung (Web) -> E-Mail -> Desktop-Verarbeitung.
|
||||
|
||||
---
|
||||
|
||||
### PHASE 5: Desktop-Zentrale & Synchronisation 🔵 IN ARBEIT
|
||||
|
||||
*Ziel: Ein einsatzbereiter Desktop-Client für das Neumarkt-Turnier.*
|
||||
|
||||
#### 🎨 Agent: Frontend Expert
|
||||
|
||||
* [x] **Onboarding UI:** Implementierung des Onboarding-Screens (Name, Key, Backup, Rolle, Sync, Drucker) mit
|
||||
validierten Eingaben.
|
||||
* [x] **Navigation:** Navigations-Rail mit Hover-Tooltips und dedizierten Icons für "Setup" und "Sync".
|
||||
* [x] **Settings:** Persistente Speicherung der Onboarding-Daten in `settings.json`.
|
||||
|
||||
#### 👷 Agent: Backend Developer
|
||||
|
||||
* [x] **Device Management:** Domain-Modell (`Device`), Tabelle (`identity_devices`) und Repository zur
|
||||
Geräteverwaltung implementiert.
|
||||
* [x] **Security Key Auth:** Implementierung des `DeviceSecurityFilter` zur Authentifizierung via `X-Security-Key`
|
||||
Header.
|
||||
* [x] **Onboarding API:** REST-Endpunkte zur Registrierung und Abfrage von Desktop-Instanzen erstellt.
|
||||
|
||||
#### 🧹 Agent: Curator
|
||||
|
||||
* [x] **Dokumentation:** Erstellung der Architektur-Doku für das Onboarding-Backend.
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
type: Guide
|
||||
status: ACTIVE
|
||||
owner: Lead Architect
|
||||
last_update: 2026-04-28
|
||||
---
|
||||
|
||||
# Git Branching & Deployment Strategy (Meldestelle)
|
||||
|
||||
Um parallele Weiterentwicklung und stabile Feld-Tests zu ermöglichen, nutzen wir einen vereinfachten **GitHub Flow** mit Release-Tags. Da wir ein kleines Team (bzw. Solo-Entwickler mit KI-Agents) sind, verzichten wir auf übermäßig komplexe Git-Flow-Modelle (wie `develop`, `release/*`, `hotfix/*`), stellen aber Stabilität für Deployments sicher.
|
||||
|
||||
## 1. Branching-Struktur
|
||||
|
||||
### `main` (Source of Truth / Production)
|
||||
* **Zweck:** Enthält *immer* den aktuellen, stabilen und im Feld getesteten/auslieferbaren Code.
|
||||
* **Regel:** Direkte Commits auf `main` sind tabu (außer Notfall-Hotfixes).
|
||||
* **Deployment:** Ein Push/Merge auf `main` bedeutet **nicht** zwingend ein sofortiges Deployment auf Zora, aber der Code ist *bereit* dafür.
|
||||
|
||||
### Feature Branches (`feature/*` oder `fix/*`)
|
||||
* **Zweck:** Hier findet die eigentliche Entwicklung statt (z.B. neue Bounded Contexts, Wizards).
|
||||
* **Namenskonvention:** `feature/event-wizard-neu`, `fix/zns-import-bug`
|
||||
* **Lebensdauer:** So kurz wie möglich. Sobald ein Feature/Fix *in sich geschlossen* und lokal getestet ist, wird ein Pull Request (PR) auf `main` erstellt.
|
||||
|
||||
### Release Tags (`v1.x.x`)
|
||||
* **Zweck:** Markiert einen spezifischen, stabilen Punkt auf dem `main`-Branch, der tatsächlich für ein Turnier (Feld-Test) deployed wurde.
|
||||
* **Szenario:** Du hast Version `v1.2.0` (Plan-B) für ein Turnier deployed. Du entwickelst weiter auf `feature/*` und mergest in `main`. Das nächste Turnier bekommt dann Tag `v1.3.0`.
|
||||
|
||||
## 2. Der Workflow im Alltag
|
||||
|
||||
1. **Start:** `git checkout main` -> `git pull` -> `git checkout -b feature/mein-neues-feature`
|
||||
2. **Entwicklung:** Arbeiten, KI-Agents nutzen, Commits machen.
|
||||
3. **Abschluss:** Feature ist fertig.
|
||||
4. **Merge:** Pull Request in Gitea erstellen (oder lokal: `git checkout main`, `git merge feature/mein-neues-feature`, `git push`).
|
||||
5. **Aufräumen:** `git branch -d feature/mein-neues-feature`
|
||||
|
||||
## 3. Strategie für Feld-Tests (Turnier-Einsatz)
|
||||
|
||||
Wenn ein Turnier ansteht und ein stabiler Stand eingefroren werden muss:
|
||||
|
||||
1. Stelle sicher, dass `main` den gewünschten Zustand hat.
|
||||
2. Setze einen Tag in Git: `git tag -a v1.2.0 -m "Release für Turnier in Neumarkt"`
|
||||
3. Pushe den Tag: `git push origin v1.2.0`
|
||||
4. **Deployment:** Das Deployment-Skript zieht sich *diesen* Tag auf Zora (oder baut den Docker-Container aus diesem Tag).
|
||||
|
||||
### Was passiert, wenn während des Turniers ein Bug auftritt (Hotfix)?
|
||||
|
||||
*Szenario: Das Turnier läuft auf `v1.2.0`. Auf `main` gibt es schon neuere Features (unfertig).*
|
||||
|
||||
1. Checkout des stabilen Tags: `git checkout -b hotfix/turnier-fix v1.2.0`
|
||||
2. Bug fixen, committen.
|
||||
3. Neuen Tag für das Deployment setzen: `git tag -a v1.2.1 -m "Hotfix ZNS Import"`
|
||||
4. `git push origin v1.2.1` -> Fix wird auf Zora deployed.
|
||||
5. **WICHTIG (Backport):** Damit der Fix nicht verloren geht, den Hotfix-Branch danach in `main` mergen: `git checkout main`, `git merge hotfix/turnier-fix`.
|
||||
|
||||
## 4. Gitea Actions (CI/CD)
|
||||
* **Pushes auf `feature/*`:** Führen Code-Checks/Tests aus.
|
||||
* **Pushes auf `main`:** Führen erweiterte Tests aus und bauen Docker-Images mit dem Tag `latest` sowie dem Git-SHA in die interne Registry (`10.0.0.22:3000`).
|
||||
* **Erstellung eines Tags (`v*`):** Triggert automatisch den Build und Push von Docker-Images in die interne Registry. Das Image erhält den Namen des Tags (z.B. `:v1.2.0`). Dies ist die Basis für stabile Deployments auf Zora.
|
||||
@@ -32,6 +32,8 @@ Deine Aufgaben:
|
||||
6. **Handover:** Stelle Architekturentscheidungen nicht nur als Text, sondern auch als Diagramm (Mermaid/PlantUML) bereit.
|
||||
7. Erstelle und pflege die MASTER ROADMAP. Du bist der "Hüter des Plans". Du delegierst Aufgaben an die spezialisierten Agenten (Backend, Frontend, DevOps, QA), führst sie aber nicht selbst aus, es sei denn, es betrifft direkt die Architektur oder das Build-System.
|
||||
8. **Bounded Context Awareness:** Stelle sicher, dass Änderungen immer einem der 6 SCS (Self-Contained Systems) zugeordnet sind und die Grenzen gewahrt bleiben.
|
||||
9. **Active Task Manifest:** Nutze die Datei `docs/ACTIVE_TASK.md`, um den aktuellen Arbeitsstand zu dokumentieren und für die nächste Session/KI bereitzustellen.
|
||||
10. **Scout-Prinzip:** Wenn eine Aufgabe unklar ist, delegiere zuerst an Junie als "Scout", um Code-Snippets in `docs/04_Agents/Research_Snippet.md` zu sammeln, bevor architektonische Entscheidungen getroffen werden.
|
||||
|
||||
Don't:
|
||||
- Implementiere keine Business-Logik in Backend-Services (→ Backend Developer).
|
||||
|
||||
@@ -23,6 +23,7 @@ Ziel:
|
||||
- Jede Session endet mit genau einem Artefakt in `docs/`.
|
||||
- Veraltetes Wissen wird sauber archiviert.
|
||||
- Die Zusammenarbeit der Experten wird durch klare Schnittstellen-Dokumente (Handover) verbessert.
|
||||
- **Context-Handover:** Am Ende jeder Session wird ein standardisierter `🔄 NEXT SESSION CONTEXT` Block ausgegeben und die Datei `docs/ACTIVE_TASK.md` aktualisiert.
|
||||
|
||||
Regeln:
|
||||
1. Single Source of Truth ist `docs/`.
|
||||
@@ -31,11 +32,22 @@ Regeln:
|
||||
- Reference / technische Wahrheit pro System (z.B. `docs/05_Backend/Services/<service>.md`)
|
||||
- How-to / Runbook (passender Bereich)
|
||||
- Journal Entry (`docs/99_Journal/`)
|
||||
3. **Quality Gate:** Prüfe, ob die Artefakte den Standards entsprechen:
|
||||
3. **Session-Abschluss Checkliste:**
|
||||
- [ ] Wurden alle geänderten/neuen Dateien im Journal/Artefakt mit absolutem Pfad erwähnt?
|
||||
- [ ] Wurde ein "Warum" dokumentiert (nicht nur das "Was")?
|
||||
- [ ] Wurde die Datei `docs/ACTIVE_TASK.md` auf den neuesten Stand gebracht?
|
||||
- [ ] Enthält die finale Antwort den `🔄 NEXT SESSION CONTEXT` Block?
|
||||
4. **🔄 NEXT SESSION CONTEXT Struktur:**
|
||||
- **Focus:** [SCS / Feature-Name]
|
||||
- **Last State:** [Kurz-Zusammenfassung des aktuellen Stands]
|
||||
- **Critical Files:** [Liste der wichtigsten Dateien für die nächste Session]
|
||||
- **Open Threads:** [Offene Fragen oder nächste konkrete Schritte]
|
||||
- **Agent-Handover:** [Spezifische Anweisungen für die nächste KI-Rolle]
|
||||
5. **Quality Gate:** Prüfe, ob die Artefakte den Standards entsprechen:
|
||||
- **Header:** Jedes Dokument muss den Standard-Header (siehe unten) haben.
|
||||
- **Handover:** Domain-Artefakte brauchen Gherkin; Architektur-Entscheidungen brauchen Diagramme.
|
||||
- **ADR-Pflicht:** Bei größeren Entscheidungen (z.B. Tech-Stack-Änderungen) muss ein ADR eingefordert werden.
|
||||
4. **Lifecycle & Archivierung:**
|
||||
6. **Lifecycle & Archivierung:**
|
||||
- Veraltete Dokumente (z.B. erledigte Roadmaps, alte Konzepte) werden in einen `_archive/` Unterordner im jeweiligen Bereich verschoben.
|
||||
- Dateiname bei Archivierung: `YYYY-MM-DD_OriginalName.md`.
|
||||
- Status im Header auf `ARCHIVED` setzen.
|
||||
|
||||
@@ -17,6 +17,8 @@ Gemini wird genutzt für **Konzeptarbeit**: Varianten vergleichen, Argumente/Tra
|
||||
* Immer 2–4 Optionen mit Vor-/Nachteilen liefern.
|
||||
* Offene Fragen explizit als Liste zurückgeben.
|
||||
* Formuliere Outputs so, dass sie **direkt** in ein `docs/*` Artefakt übernommen werden können.
|
||||
* **Richter-Prinzip:** Nutze von Junie bereitgestellte Code-Snippets in `docs/04_Agents/Research_Snippet.md`, um fundierte Entscheidungen zu treffen, ohne den Code selbst im Detail lesen zu müssen.
|
||||
* **Manifest-Pflicht:** Nutze die `docs/ACTIVE_TASK.md`, um den Kontext-Handover zwischen Sessions zu gewährleisten.
|
||||
|
||||
## Don’t
|
||||
* Keine Annahmen als Fakten verkaufen.
|
||||
|
||||
@@ -21,6 +21,8 @@ Junie wird genutzt für **Repo-nahe Arbeit**: Code lesen, reale Pfade/Module fin
|
||||
## Don’t
|
||||
* Keine „zweite Wahrheit“ in `.junie/*` etablieren (Tooling bleibt Tooling).
|
||||
* Keine Entscheidungen „im Chat verlieren“ – am Ende muss ein Artefakt in `docs/` stehen.
|
||||
* **Scout-Prinzip:** Agiere bei Bedarf als technischer Scout für Gemini. Sammele Code-Beweise und Snippets in `docs/04_Agents/Research_Snippet.md`, um architektonische Entscheidungen vorzubereiten.
|
||||
* **Manifest-Pflicht:** Lies bei Session-Start immer zuerst die `MASTER_ROADMAP` und dann die `docs/ACTIVE_TASK.md`.
|
||||
|
||||
## Abschluss (Pflicht)
|
||||
Am Ende der Session genau **ein** Artefakt gemäß `docs/03_Agents/README.md` erzeugen (oder aktualisieren).
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
---
|
||||
type: How-to
|
||||
status: ACTIVE
|
||||
owner: DevOps Engineer
|
||||
---
|
||||
|
||||
# Runbook: Caddy & Pangolin Deployment (Plan-B Setup)
|
||||
|
||||
Dieses Dokument sichert das Wissen über die Konfiguration von Caddy als Webserver/Reverse-Proxy in Kombination mit Pangolin-Tunneln, welches während der "Plan-B" Online-Nennung erarbeitet wurde.
|
||||
|
||||
## 1. Architektur-Übersicht
|
||||
|
||||
* **Pangolin:** Stellt den sicheren Tunnel vom lokalen Netzwerk (Zora) ins Internet her (ersetzt Cloudflare). Leitet Traffic auf spezifische lokale Ports weiter.
|
||||
* **Caddy:** Agiert als Reverse-Proxy und TLS-Terminierungspunkt. Nimmt Traffic von Pangolin (und lokalem Netz) an und routet ihn zu den internen Docker-Services (z.B. Frontend-Web, API-Gateway).
|
||||
|
||||
## 2. Caddy Konfiguration (`Caddyfile`)
|
||||
|
||||
Die Konfiguration befindet sich in `config/docker/caddy/web-app/Caddyfile`.
|
||||
|
||||
### Wichtige Erkenntnisse / Fallstricke:
|
||||
* **TLS/SSL:** Caddy wurde mit `auto_https off` konfiguriert, da die SSL-Terminierung extern (Pangolin/Edge) erfolgt. Caddy läuft intern auf Port 80.
|
||||
* **Same-Origin Strategy:** Um CORS-Probleme im Browser zu vermeiden, werden alle API-Anfragen (`/api/*`) über Caddy an den `mail-service:8085` geproxt. Dies macht die App robuster gegen Browser-Security-Policies.
|
||||
* **MIME-Types:** Explizite Setzung von `application/wasm` für `.wasm` Dateien ist für KMP-Web-Apps kritisch (siehe Snippet).
|
||||
* **COOP/COEP Header:** Für WASM/KMP-Web-Apps sind `Cross-Origin-Embedder-Policy "require-corp"` und `Cross-Origin-Opener-Policy "same-origin"` essentiell, damit SharedArrayBuffer etc. funktionieren.
|
||||
* **Caching:**
|
||||
* Assets mit Hashes im Namen sind `immutable` (max-age 1 Jahr).
|
||||
* `.wasm` und `.js` Dateien wurden während Plan-B auf `no-store, no-cache, must-revalidate` gesetzt, um sicherzustellen, dass Teilnehmer immer die aktuellste Logik erhalten.
|
||||
* **Header-Weiterleitung:** Wichtige Header für das Backend: `X-Real-IP`, `X-Forwarded-For`, `X-Forwarded-Proto`.
|
||||
|
||||
### Aktuelles Plan-B Snippet:
|
||||
```caddyfile
|
||||
{
|
||||
auto_https off
|
||||
}
|
||||
|
||||
:80 {
|
||||
root * /usr/share/caddy
|
||||
|
||||
header {
|
||||
Cross-Origin-Embedder-Policy "require-corp"
|
||||
Cross-Origin-Opener-Policy "same-origin"
|
||||
}
|
||||
|
||||
# API Proxy (Same-Origin Strategy)
|
||||
handle /api/* {
|
||||
reverse_proxy mail-service:8085 {
|
||||
header_up Host {upstream_hostport}
|
||||
header_up X-Real-IP {remote_host}
|
||||
header_up X-Forwarded-For {remote_host}
|
||||
header_up X-Forwarded-Proto {scheme}
|
||||
}
|
||||
}
|
||||
|
||||
# Wasm MIME & Caching
|
||||
@wasm path *.wasm
|
||||
header @wasm Content-Type "application/wasm"
|
||||
|
||||
@wasm_js path *.wasm *.js
|
||||
header @wasm_js Cache-Control "no-store, no-cache, must-revalidate"
|
||||
|
||||
# SPA Fallback
|
||||
handle {
|
||||
try_files {path} /index.html
|
||||
file_server
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 3. Pangolin Konfiguration
|
||||
|
||||
### Erkenntnisse aus Plan-B:
|
||||
* **Tunnel-Endpunkt:** Pangolin leitet den Traffic von der öffentlichen Domain (z.B. `meldestelle.mo-code.at`) auf den lokalen Port der Zora-Instanz weiter (standardmäßig Port 80, gemappt auf Host-Port via Docker).
|
||||
* **Stabilität:** Der Pangolin-Client läuft als persistenter Dienst auf der Zora-Node. Er ist extrem stabil gegenüber IP-Wechseln des ISP (DSL-Reconnect).
|
||||
* **Konfiguration:** Erfolgt primär über das Pangolin-Dashboard (Web-UI). Wichtig ist das Mapping der Resource auf die interne IP von Zora.
|
||||
|
||||
## 4. Deployment-Workflow (Erkenntnisse)
|
||||
|
||||
### SMTP-Härtung (Plan-B Mail-Service)
|
||||
In `dc-planb.yaml` wurden folgende Einstellungen für World4You (SMTP) als stabil verifiziert:
|
||||
```yaml
|
||||
SPRING_MAIL_HOST: "smtp.world4you.com"
|
||||
SPRING_MAIL_PORT: "587"
|
||||
SPRING_MAIL_PROPERTIES_MAIL_SMTP_STARTTLS_ENABLE: "true"
|
||||
SPRING_MAIL_PROPERTIES_MAIL_SMTP_STARTTLS_REQUIRED: "true"
|
||||
```
|
||||
Wichtig: `STARTTLS_REQUIRED` verhindert den Versand, falls keine verschlüsselte Verbindung aufgebaut werden kann.
|
||||
|
||||
### Infrastruktur-Optimierung
|
||||
* **Zero-Downtime:** `docker compose exec web-app caddy reload --config /etc/caddy/Caddyfile` ermöglicht Konfigurationsänderungen ohne Container-Neustart.
|
||||
* **Health-Check:** Der `/health` Endpunkt in Caddy wurde genutzt, um die Erreichbarkeit des Containers zu prüfen.
|
||||
* **In-Memory DB:** Für Plan-B wurde die H2-Datenbank (In-Memory) genutzt, da keine Persistenz über den Turnier-Zeitraum hinaus (außer E-Mail-Kopien) nötig war. Dies vereinfachte das Deployment massiv.
|
||||
|
||||
---
|
||||
*Hinweis: Dieses Dokument basiert auf den erfolgreichen Feld-Tests vom April 2026.*
|
||||
@@ -0,0 +1,45 @@
|
||||
# Journal Entry: Prozess-Optimierung & TurnierAnlage Vorbereitung
|
||||
|
||||
---
|
||||
type: Journal
|
||||
status: ACTIVE
|
||||
owner: Curator
|
||||
last_update: 2026-04-28
|
||||
---
|
||||
|
||||
## 📝 Zusammenfassung
|
||||
In dieser Session haben wir die KI-Zusammenarbeit durch neue Protokolle geschärft und die Grundlage für den "TurnierAnlage"-Wizard in der Desktop-App gelegt.
|
||||
|
||||
## 🏗️ Architektur- & Prozess-Updates
|
||||
- **Context-Handover Protokoll:** Einführung des `🔄 NEXT SESSION CONTEXT` Blocks zur nahtlosen Übergabe zwischen KI-Instanzen.
|
||||
- **Active Task Manifest:** Erstellung von `docs/ACTIVE_TASK.md` als Single Source of Truth für den aktuellen Arbeitsstand.
|
||||
- **Playbook Updates:**
|
||||
- `Curator.md`: Neue Checkliste für den Session-Abschluss.
|
||||
- `Architect.md`: Integration des "Scout-Prinzips" und Manifest-Pflicht.
|
||||
- `Junie.md` & `Gemini.md`: Rollen-Schärfung (Scout vs. Richter).
|
||||
|
||||
## 🐎 TurnierAnlage (Event Management)
|
||||
- **Status-Quo Analyse:**
|
||||
- Backend: `Turnier.kt` ist bereits gut auf ÖTO-Validierungen vorbereitet.
|
||||
- Frontend: `CreateBewerbWizardScreen.kt` existiert als Tab-UI, muss aber auf den `WizardOrchestrator` (ADR-0025) migriert werden.
|
||||
- Flow: `EventWizardFlow.kt` ist noch ein Platzhalter.
|
||||
- **Strategische Entscheidung:** Wir nutzen den neuen `WizardCore` für die TurnierAnlage, um komplexe ÖTO-Regelwerke (z.B. § 39 Abteilungstrennung) zustandsbasiert und mit klaren Guards abzubilden.
|
||||
|
||||
## 🛠️ CI/CD & Deployment (DevOps)
|
||||
- **Gitea-Actions:** Erweiterung der `docker-publish.yaml`, um bei Git-Tags (`v*`) automatisch Docker-Images zu bauen.
|
||||
- **Tagging-Logik:** Docker-Images erhalten nun dedizierte Tags aus Git, was stabile Rollbacks und Feld-Tests ermöglicht.
|
||||
- **Dokumentation:** Update der `Git_Branching_Strategy.md` um die automatisierte Build-Logik.
|
||||
|
||||
## 🔗 Betroffene Dateien
|
||||
- `docs/ACTIVE_TASK.md` (NEU)
|
||||
- `docs/04_Agents/Playbooks/Curator.md` (Update)
|
||||
- `docs/04_Agents/Playbooks/Architect.md` (Update)
|
||||
- `docs/04_Agents/Playbooks/Junie.md` (Update)
|
||||
- `docs/04_Agents/Playbooks/Gemini.md` (Update)
|
||||
- `backend/services/events/events-domain/src/main/kotlin/at/mocode/events/domain/model/Turnier.kt` (Gelesen/Analyse)
|
||||
|
||||
## ✅ Session-Abschluss Checkliste
|
||||
- [x] Dateipfade absolut erwähnt?
|
||||
- [x] "Warum" dokumentiert?
|
||||
- [x] `docs/ACTIVE_TASK.md` aktuell?
|
||||
- [x] Handover-Block vorhanden?
|
||||
@@ -0,0 +1,32 @@
|
||||
# ⚡ ACTIVE TASK: Event- & TurnierAnlage-Wizard Migration
|
||||
|
||||
**Status:** 🏗️ In Arbeit
|
||||
**SCS:** Event Management / Desktop App
|
||||
**Branch:** `feature/turnier-anlage-wizard`
|
||||
|
||||
## 🎯 Aktuelles Ziel
|
||||
1. **Event-Wizard Migration:** Migration des Veranstaltungs-Wizards auf den deklarativen Orchestrator (ADR-0025) abgeschlossen. ✓
|
||||
2. **TurnierAnlage:** Implementierung des Wizards zur Anlage von Turnieren, Bewerben und Abteilungen nach ÖTO-Regeln in der Desktop-App.
|
||||
3. **ÖTO-Validierung:** Integration der Abteilungs-Trennungs-Regeln (§ 39) als Warn-Logik im Wizard.
|
||||
|
||||
## 🛠️ Letzte Änderungen
|
||||
- Event-Wizard: `EventFlowSample.kt` erfolgreich nach `EventWizardFlow.kt` migriert, umbenannt und um ÖTO-Schritte erweitert. ✓
|
||||
- Wissens-Sicherung Plan-B: Caddy & Pangolin Runbook vervollständigt (MIME, COOP/COEP, SMTP-Härtung). ✓
|
||||
- CI/CD: Gitea-Action für automatisierte Docker-Builds bei Git-Tags (`v*`) aktiviert. ✓
|
||||
- TurnierAnlage: `TurnierAnlageFlow.kt` Skelett erstellt. ✓
|
||||
|
||||
## 📍 Fokus-Dateien
|
||||
- `frontend/features/veranstaltung-feature/src/commonMain/kotlin/at/mocode/veranstaltung/feature/wizard/EventWizardFlow.kt`
|
||||
- `frontend/features/turnier-feature/src/commonMain/kotlin/at/mocode/frontend/features/turnier/wizard/TurnierAnlageFlow.kt`
|
||||
- `docs/03_Domain/02_Reference/OETO_Regelwerk/Abteilungs-Trennungs-Schwellenwerte.md`
|
||||
- `frontend/features/turnier-feature/src/jvmMain/kotlin/at/mocode/frontend/features/turnier/presentation/CreateBewerbWizardScreen.kt`
|
||||
|
||||
## 🚧 Offene Punkte / Blocker
|
||||
- [ ] Erstellung der Compose-Screens für `TurnierBasisdatenStep`.
|
||||
- [ ] Erstellung der Compose-Screens für `TurnierKategorieStep`.
|
||||
- [ ] Implementierung der ÖTO-Check Logik für Abteilungen.
|
||||
- [ ] Sync-Logik zum Backend für die Web-Generierung vorbereiten.
|
||||
|
||||
## 🔄 Nächste Schritte
|
||||
- [ ] Implementierung von `TurnierBasisdatenScreen` (Compose Desktop).
|
||||
- [ ] Verknüpfung des `TurnierAnlageFlow` mit dem UI-Orchestrator.
|
||||
@@ -0,0 +1,123 @@
|
||||
A26128CSN-C-NEU CSNP-C-NEU NEUM2026042520260425CSN-C-Neu CSNP-C_Neu 2.2PSO v1.07
|
||||
B010Stilspringprüfung - CSNP-C_N006000000001
|
||||
C010001307002129000000000000000000000000000000000000021771000000
|
||||
D001PG47Paddy's Nikita 170107Remplbauer Selina 00080000000 000000AUT*
|
||||
D002PK06H-S Button 196040Gillinger Marlene 00067000000 000000AUT*
|
||||
D003P824Pit 3 184759Krenn Eva 00055000000 000000AUT*
|
||||
D004P814Balu 6 193244Remplbauer Sophia 00000000000 000000AUT
|
||||
D004P901Daneder's Blitz 195501Weidinger Janina 00000000000 000000AUT
|
||||
D004PB70Daneder's Caramello 163545Montgomery Helena 00000000000 000000AUT
|
||||
B021Einlaufspringprüfung - CSN-C-Ne008000000002
|
||||
C021001307002129000000000000000000000000000000000000021771000000
|
||||
D0001781Ritual Do Vizo 126532Layr Bianca 00000000000 000000AUT*
|
||||
D000P816Aldensfarm Breaking Dawn 159405Starzengruber Marie-Theres 00000000000 000000AUT*
|
||||
D000P901Daneder's Blitz 195501Weidinger Janina 00000000000 000000AUT*
|
||||
D000PB70Daneder's Caramello 163545Montgomery Helena 00000000000 000000AUT*
|
||||
D000PE14SD Antonette 929451Mayrhofer Simon 00000000000 000000AUT*
|
||||
D000PG47Paddy's Nikita 170107Remplbauer Selina 00000000000 000000AUT*
|
||||
D000P824Pit 3 184759Krenn Eva 00003000000 000000AUT
|
||||
D000P814Balu 6 193244Remplbauer Sophia 00000000000 000000AUT
|
||||
B022Einlaufspringprüfung - CSN-C-Ne003000000002
|
||||
C022001307002129000000000000000000000000000000000000021771000000
|
||||
D000AR70Chocolate Kiss 2 147265Vanova Nina 00000000000 000000AUT*10258795
|
||||
D000P561Ginger Bread Girl 153601Winter Maja Sophie 00000000000 000000AUT*
|
||||
D997Z001Wildberry Gold RPZ 168660Zechmeister-Paster Diana A00000000000 000000AUT
|
||||
B030Stilspringprüfung - CSNP-C_N006000000003
|
||||
C030001307002129000000000000000000000000000000000000021771000000
|
||||
D001PA53Rathcline Star 178474Schmidmayr Nena Sophie 00072000000 000000AUT*
|
||||
D002P152Verena 3 170454Krenn Miriam 00070000000 000000AUT*
|
||||
D003P816Aldensfarm Breaking Dawn 159405Starzengruber Marie-Theres 00068000000 000000AUT*
|
||||
D004P561Ginger Bread Girl 153601Winter Maja Sophie 00067000000 000000AUT*
|
||||
D997PE14SD Antonette 929451Mayrhofer Simon A00000000000 000000AUT
|
||||
D997PK06H-S Button 196040Gillinger Marlene A00000000000 000000AUT
|
||||
B041Einlaufspringprüfung - CSNP-C_N006000000004
|
||||
C041001307002129000000000000000000000000000000000000021771000000
|
||||
D0002M80Handsome 186927Lengauer Jelena 00000000000 000000AUT* 106KB09
|
||||
D000AN19Exklusiv EM 187665Mück Hannah 00000000000 000000AUT*
|
||||
D0001781Ritual Do Vizo 126532Layr Bianca 00040000000 000000AUT
|
||||
D0004Y59Legolas 196 925183Schreiber Tamina 00047000000 000000GER
|
||||
D000AB83HB Vijola 920327Reisinger Marlene 00056000000 000000AUT
|
||||
D0003E99Quinet 906586Kapeller Emilia 00000000000 000000AUT
|
||||
B042Einlaufspringprüfung - CSNP-C_N007000000004
|
||||
C042001307002129000000000000000000000000000000000000021771000000
|
||||
D0003K69Lillet 18 150620Reitetschläger Lena 00000000000 000000AUT*
|
||||
D0005789Furiosa de la Bryere CE 140156Ehrentraut Carina 00000000000 000000AUT*
|
||||
D000A099Quintessa 2 609548Aichinger Bianca 00000000000 000000AUT*
|
||||
D0003M58Samantha 25 609771Karl Reinhard 00040000000 000000AUT
|
||||
D000H606Moondancer 070156Alberer Manuela 00040000000 000000AUT
|
||||
D000Z001Wildberry Gold RPZ 168660Zechmeister-Paster Diana 00092500000 000000AUT
|
||||
D000AR70Chocolate Kiss 2 147265Vanova Nina 00129000000 000000AUT 10258795
|
||||
B050Stilspringprüfung - CSNP-C_N003000000005
|
||||
C050001307002129000000000000000000000000000000000000021771000000
|
||||
D001P152Verena 3 170454Krenn Miriam 00074000000 000000AUT*
|
||||
D002P985Taffy 2 193430Schartmüller Sarah 00072000000 000000AUT*
|
||||
D003PA53Rathcline Star 906580Egger Julia 00065000000 000000AUT*
|
||||
B061Stilspringprüfung - CSNP-C_N009000000006
|
||||
C061001307002129000000000000000000000000000000000000021771000000
|
||||
D0012B41Guccini 922710Simlinger Marlies 00075000000 000000AUT*
|
||||
D002AN19Exklusiv EM 187665Mück Hannah 00072000000 000000AUT*
|
||||
D0033E99Quinet 906586Kapeller Emilia 00071000000 000000AUT*
|
||||
D0042M80Handsome 186927Lengauer Jelena 00070000000 000000AUT* 106KB09
|
||||
D004AF41Cäsar 55 916541Dugandzic Sarah 00070000000 000000AUT*
|
||||
D006PA53Rathcline Star 906580Egger Julia 00068000000 000000AUT
|
||||
D0074Y59Legolas 196 925183Schreiber Tamina 00062000000 000000GER
|
||||
D0083785Coeur 17 145963Obermüller Hannah 00061000000 000000AUT
|
||||
D009AB83HB Vijola 920327Reisinger Marlene 00057000000 000000AUT
|
||||
B062Stilspringprüfung - CSNP-C_N007000000006
|
||||
C062001307002129000000000000000000000000000000000000021771000000
|
||||
D001A099Quintessa 2 609548Aichinger Bianca 00082000000 000000AUT*
|
||||
D0025789Furiosa de la Bryere CE 140156Ehrentraut Carina 00072000000 000000AUT*
|
||||
D0033K69Lillet 18 150620Reitetschläger Lena 00067000000 000000AUT*
|
||||
D004KSS1Charity Coke 053749Eichler Eva 00065000000 000000AUT*
|
||||
D0053M58Samantha 25 609771Karl Reinhard 00060000000 000000AUT
|
||||
D005H606Moondancer 070156Alberer Manuela 00060000000 000000AUT
|
||||
D9971A11Gradan 102783Steyrer Anna A00000000000 000000AUT
|
||||
B070Stilspringprüfung - CSNP-C_N002000000007
|
||||
C070001307002129000000000000000000000000000000000000021771000000
|
||||
D001Y001Bella Graziella 144315Gaugl Laura 00075000000 000000AUT*
|
||||
D002P985Taffy 2 193430Schartmüller Sarah 00000000000 000000AUT
|
||||
B080Springreiterbewerb - CSNP-C_N003000000008
|
||||
C080001307002129000000000000000000000000000000000000021771000000
|
||||
D0013785Coeur 17 145963Obermüller Hannah 00080000000 000000AUT*
|
||||
D0022M80Handsome 186927Lengauer Jelena 00072000000 000000AUT* 106KB09
|
||||
D9973E99Quinet 178474Schmidmayr Nena Sophie A00000000000 000000AUT
|
||||
B091Standardspringprüfung - CSNP-C_N005000000009
|
||||
C091001307002129000000000000000000000000000000000000021771000000
|
||||
D0012062Grover 157407Pröll Leonie 00000005416 000000AUT*
|
||||
D0022B41Guccini 160813Grubmüller Lea 00000005463 000000AUT*
|
||||
D0031317Quality's Finest 612295Stroblmair Victoria 00000005492 000000AUT*
|
||||
D0041A11Gradan 102783Steyrer Anna 00000005858 000000AUT*
|
||||
D005KSS1Charity Coke 053749Eichler Eva 00040006428 000000AUT
|
||||
B092Standardspringprüfung - CSNP-C_N007000000009
|
||||
C092001307002129000000000000000000000000000000000000021771000000
|
||||
D001A024D Day 075374Ambros Susanne 00000005940 000000AUT*10071068 108EH50
|
||||
D0021G88Hamira 3 074007Beißmann Andreas 00000005991 000000AUT*
|
||||
D0032G77S Mirrallas 605835Ellmer Kassandra 00000006298 000000AUT*
|
||||
D0043966Capitaine 601366Madlmayr Carina 00040005862 000000AUT
|
||||
D0051942Obora's Agnetha 601300Hofer Michaela 00040005966 000000AUT
|
||||
D006Y001Bella Graziella 144315Gaugl Laura 00080005012 000000AUT
|
||||
D9972785Herr Frodo 144315Gaugl Laura A00000000000 000000AUT
|
||||
B100Springpferdeprüfung - CSN-C-Ne000000000010
|
||||
C100001307002129000000000000000000000000000000000000021771000000
|
||||
B110Stilspringprüfung - CSN-C-Ne002000000011
|
||||
C110001307002129000000000000000000000000000000000000021771000000
|
||||
D0012062Grover 157407Pröll Leonie 00085000000 000000AUT*
|
||||
D0021317Quality's Finest 612295Stroblmair Victoria 00080000000 000000AUT*
|
||||
B121Standardspringprüfung - CSN-C-Ne002000000012
|
||||
C121001307002129000000000000000000000000000000000000021771000000
|
||||
D0012062Grover 157407Pröll Leonie 00040005651 000000AUT*
|
||||
D0022B41Guccini 160813Grubmüller Lea 00080005774 000000AUT
|
||||
B122Standardspringprüfung - CSN-C-Ne004000000012
|
||||
C122001307002129000000000000000000000000000000000000021771000000
|
||||
D001AS94Landliebe 3 162776Höllmüller Anna 00000005557 000000AUT*10294537
|
||||
D0022G77S Mirrallas 605835Ellmer Kassandra 00000006212 000000AUT*
|
||||
D0031942Obora's Agnetha 601300Hofer Michaela 00000006723 000000AUT*
|
||||
D004A024D Day 075374Ambros Susanne 00040005943 000000AUT 10071068 108EH50
|
||||
B130Stilspringprüfung - CSN-C-Ne001000000013
|
||||
C130001307002129000000000000000000000000000000000000021771000000
|
||||
D0014258Casino East 601300Hofer Michaela 00075000000 000000AUT*
|
||||
B140Standardspringprüfung - CSN-C-Ne003000000014
|
||||
C140001307002129000000000000000000000000000000000000021771000000
|
||||
D0012010Leonidas van de Zuuthoeve Z 145960Fischerlehner Leonie 00000005368 000000AUT*
|
||||
D002AS94Landliebe 3 162776Höllmüller Anna 00000005745 000000AUT*10294537
|
||||
D0034258Casino East 601300Hofer Michaela 00000006261 000000AUT*
|
||||
Binary file not shown.
@@ -0,0 +1,96 @@
|
||||
A26129CDN-C-NEU CDNP-C_NEU NEUM2026042620260426 2.2PSO v1.07
|
||||
B010Dressurprüfung lzf CDN-C_Ne002000000001
|
||||
C010000000038705000000000000000000000000000000000000000000000000
|
||||
D001PB70Daneder's Caramello 163545Montgomery Helena 00062000000 000000AUT*
|
||||
D0022892Amore 5 AUT Stadler Caroline 00060000000 000000AUT*
|
||||
B020Dressurprüfung lzf CDN-C_Ne003000000002
|
||||
C020000000038705000000000000000000000000000000000000000000000000
|
||||
D0014208Sahib Silver G 195331Neuhauser Lara 00075000000 000000AUT*
|
||||
D0022892Amore 5 AUT Stadler Caroline 00068000000 000000AUT*
|
||||
D003PB70Daneder's Caramello 163545Montgomery Helena 00060000000 000000AUT*
|
||||
B030Dressurreiterprüfung lzf CDN-C_Ne005000000003
|
||||
C030035110000000000000000000000000000000000000000000000000000000
|
||||
D001PC62Flora HP 917397Altendorfer Pia 00080000000 000000AUT*
|
||||
D002Z002Abrakadabra S 107926Fürbäck Melanie 00077000000 000000AUT*
|
||||
D0034Y59Legolas 196 184074Stöbich Enya 00068000000 000000AUT*
|
||||
D004HKTBAcceptius FA 196261Salzinger Luisa Marie 00064000000 000000AUT
|
||||
D005PA53Rathcline Star 922380Kropfreiter Ines 00062000000 000000AUT
|
||||
B040Dressurreiterprüfung lzf CDN-C_Ne006000000004
|
||||
C040000000038705000000000000000000000000000000000000000000000000
|
||||
D001PC62Flora HP 917397Altendorfer Pia 00078000000 000000AUT*
|
||||
D0024208Sahib Silver G 195331Neuhauser Lara 00076000000 000000AUT*
|
||||
D003Z002Abrakadabra S 107926Fürbäck Melanie 00068000000 000000AUT*
|
||||
D004HKTBAcceptius FA 196261Salzinger Luisa Marie 00064000000 000000AUT
|
||||
D0054Y59Legolas 196 184074Stöbich Enya 00062000000 000000AUT
|
||||
D006PA53Rathcline Star 922380Kropfreiter Ines 00060000000 000000AUT
|
||||
B050Dressurreiterprüfung lzf CDN-C_Ne001000000005
|
||||
C050035110000000000000000000000000000000000000000000000000000000
|
||||
D001PF06Domino N AUT Stelzl Helena 00080000000 000000AUT*
|
||||
B060Dressurreiterprüfung lzf CDN-C_Ne000000000006
|
||||
C060035110000000000000000000000000000000000000000000000000000000
|
||||
B070Pony Dressurprüfung A CSNP-C_N003000000007
|
||||
C070000000038705000000000000000000000000000000000000000000000000
|
||||
D001PT24Daneder's Captain 146663Steinmetz Sinah-Marie 00065000000 000000AUT*
|
||||
D002P561Ginger Bread Girl 153601Winter Maja Sophie 00060000000 000000AUT*
|
||||
D003PA53Rathcline Star 906592Emsenhuber Tanja 00058000000 000000AUT
|
||||
B081Dressurreiterprüfung A CDN-C_Ne006000000008
|
||||
C081035110038705000000000000000000000000000000000000000000000000
|
||||
D0013888Ravasz 123156Scheiblechner Sonja 00072000000 000000AUT*
|
||||
D0024307Makker 146066Gstöttenbauer Olivia 00064000000 000000AUT*
|
||||
D003P561Ginger Bread Girl 153601Winter Maja Sophie 00062000000 000000AUT*
|
||||
D0042083Light Blue 194297Hazoth Anna-Maria 00060000000 000000AUT*
|
||||
D0053M58Samantha 25 609771Karl Reinhard 00058000000 000000AUT
|
||||
D005KSS1Charity Coke 053749Eichler Eva 00058000000 000000AUT
|
||||
B082Dressurreiterprüfung A CDN-C_Ne002000000008
|
||||
C082035110038705000000000000000000000000000000000000000000000000
|
||||
D001GIGIGigi D'Agostidinina 076742Klein Elisabeth 00068000000 000000AUT*10144403
|
||||
D002A590Queeny 8 612592Panzirsch Anna 00064000000 000000AUT*
|
||||
B091Dressurprüfung A CDN-C_Ne007000000009
|
||||
C091035110038705000000000000000000000000000000000000000000000000
|
||||
D0013888Ravasz 123156Scheiblechner Sonja 00070000000 000000AUT*
|
||||
D002AN19Exklusiv EM 187665Mück Hannah 00064000000 000000AUT*
|
||||
D0032083Light Blue 194297Hazoth Anna-Maria 00062000000 000000AUT*
|
||||
D0044B66Vingino's Victory 616957Kiesenhofer Sarah 00058000000 000000AUT
|
||||
D0053M58Samantha 25 609771Karl Reinhard 00055000000 000000AUT
|
||||
D005KSS1Charity Coke 053749Eichler Eva 00055000000 000000AUT
|
||||
D0074307Makker 146066Gstöttenbauer Olivia 00053000000 000000AUT
|
||||
B092Dressurprüfung A CDN-C_Ne004000000009
|
||||
C092035110038705000000000000000000000000000000000000000000000000
|
||||
D001GIGIGigi D'Agostidinina 076742Klein Elisabeth 00068000000 000000AUT*10144403
|
||||
D002AL46Superbunt 616836Lengauer Julia 00065000000 000000AUT*
|
||||
D0032010Leonidas van de Zuuthoeve Z 145960Fischerlehner Leonie 00064000000 000000AUT*
|
||||
D004A590Queeny 8 612592Panzirsch Anna 00058000000 000000AUT
|
||||
B100Pony Dressurprüfung L CSNP-C_N001000000010
|
||||
C100035110038705000000000000000000000000000000000000000000000000
|
||||
D001P540Pieter V 153601Winter Maja Sophie 00056000000 000000AUT*
|
||||
B110Dressurreiterprüfung L CDN-C_Ne003000000011
|
||||
C110035110038705000000000000000000000000000000000000000000000000
|
||||
D0011317Quality's Finest 612295Stroblmair Victoria 00074000000 000000AUT*
|
||||
D0021F34Ferro Felicis 146066Gstöttenbauer Olivia 00064000000 000000AUT*
|
||||
D003P540Pieter V 153601Winter Maja Sophie 00062000000 000000AUT*
|
||||
B121Dressurprüfung L CDN-C_Ne003000000012
|
||||
C121035110038705000000000000000000000000000000000000000000000000
|
||||
D001AN19Exklusiv EM 187665Mück Hannah 00068000000 000000AUT*
|
||||
D0021F34Ferro Felicis 146066Gstöttenbauer Olivia 00062000000 000000AUT*
|
||||
D003AE11Merlin SH 061601Povacz Gisela 00060000000 000000AUT*
|
||||
B122Dressurprüfung L CDN-C_Ne002000000012
|
||||
C122035110038705000000000000000000000000000000000000000000000000
|
||||
D001A024D Day 075374Ambros Susanne 00066000000 000000AUT*10071068 108EH50
|
||||
D0023966Capitaine 601366Madlmayr Carina 00060000000 000000AUT*
|
||||
B131Dressurpferdeprüfung A CDN-C_Ne003000000013
|
||||
C131035110038705000000000000000000000000000000000000000000000000
|
||||
D001AX99Bon Sai 102783Steyrer Anna 00073400000 000000AUT*
|
||||
D0020214SHS Donna Verdi 169981Süss Sarah 00066000000 000000AUT*
|
||||
D003PT24Daneder's Captain 146663Steinmetz Sinah-Marie 00061200000 000000AUT*
|
||||
B132Dressurpferdeprüfung A CDN-C_Ne005000000013
|
||||
C132035110038705000000000000000000000000000000000000000000000000
|
||||
D001MAXIVerstappen 2 075374Ambros Susanne 00074600000 000000AUT*10071068
|
||||
D0022H08SHS Weltmädel 169981Süss Sarah 00074200000 000000AUT*
|
||||
D003P983Daneders Tornado 153601Winter Maja Sophie 00064800000 000000AUT*
|
||||
D0044B03SHS Roubinjo 169981Süss Sarah 00064200000 000000AUT*
|
||||
D0054B66Vingino's Victory 616957Kiesenhofer Sarah 00063000000 000000AUT*
|
||||
B140Dressurpferdeprüfung L CDN-C_Ne003000000014
|
||||
C140035110038705000000000000000000000000000000000000000000000000
|
||||
D0012H08SHS Weltmädel 169981Süss Sarah 00067800000 000000AUT*
|
||||
D002P983Daneders Tornado 153601Winter Maja Sophie 00064800000 000000AUT*
|
||||
D0034B03SHS Roubinjo 169981Süss Sarah 00063000000 000000AUT*
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 9.4 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 325 KiB |
@@ -24,6 +24,7 @@ kotlin {
|
||||
|
||||
sourceSets {
|
||||
commonMain.dependencies {
|
||||
api(projects.core.coreDomain)
|
||||
implementation(libs.kotlinx.serialization.json)
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ kotlin {
|
||||
implementation(projects.frontend.core.navigation)
|
||||
implementation(projects.frontend.features.billingFeature)
|
||||
implementation(projects.frontend.features.nennungFeature)
|
||||
implementation(projects.frontend.core.wizard)
|
||||
implementation(projects.core.znsParser)
|
||||
|
||||
implementation(compose.foundation)
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package at.mocode.frontend.features.turnier.wizard
|
||||
|
||||
import at.mocode.core.domain.model.ReglementE
|
||||
import at.mocode.core.domain.model.SparteE
|
||||
import at.mocode.core.domain.model.TurnierkategorieE
|
||||
import at.mocode.frontend.core.wizard.dsl.flow
|
||||
import at.mocode.frontend.core.wizard.runtime.StepId
|
||||
|
||||
/**
|
||||
* Definiert die Schritte für den Turnier-Anlage-Wizard.
|
||||
* Orientiert sich an der ÖTO-Logik und dem SCS-Rahmen.
|
||||
*/
|
||||
sealed interface TurnierAnlageStep : StepId {
|
||||
/** 1. Basisdaten (Name, Nummer, Datum, Sparte) */
|
||||
data object Basisdaten : TurnierAnlageStep
|
||||
/** 2. Kategorie & Reglement (CSN-C, CDN, etc. / ÖTO vs FEI) */
|
||||
data object KategorieReglement : TurnierAnlageStep
|
||||
/** 3. Funktionäre (TB, Parcoursbauer, etc.) */
|
||||
data object Funktionaere : TurnierAnlageStep
|
||||
/** 4. Nenn-Konfiguration (Nennschluss, Gebühren, Tauschbörse) */
|
||||
data object NennKonfig : TurnierAnlageStep
|
||||
/** 5. Zusammenfassung & Validierung (ÖTO-Warnungen prüfen) */
|
||||
data object Summary : TurnierAnlageStep
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulator für den Turnier-Wizard.
|
||||
* Sammelt die Daten, bevor sie als [DomTurnier] ans Backend gesendet werden.
|
||||
*/
|
||||
data class TurnierAnlageAcc(
|
||||
val name: String = "",
|
||||
val turnierNummer: String = "",
|
||||
val sparte: SparteE = SparteE.SPRINGEN,
|
||||
val kategorie: TurnierkategorieE = TurnierkategorieE.C,
|
||||
val reglement: ReglementE = ReglementE.OETO,
|
||||
val datum: String? = null, // ISO LocalDate
|
||||
val tbId: String? = null,
|
||||
val pbId: String? = null,
|
||||
val nennschluss: String? = null, // ISO Instant
|
||||
val nachnenngebuehrVerlangt: Boolean = false,
|
||||
val nenntauschboerseAktiv: Boolean = false
|
||||
)
|
||||
|
||||
/**
|
||||
* Der Wizard-Flow für die Turnier-Anlage.
|
||||
*/
|
||||
val TurnierAnlageFlow = flow<TurnierAnlageStep, TurnierAnlageAcc>(start = TurnierAnlageStep.Basisdaten) {
|
||||
step(TurnierAnlageStep.Basisdaten) {
|
||||
otherwise(TurnierAnlageStep.KategorieReglement)
|
||||
}
|
||||
step(TurnierAnlageStep.KategorieReglement) {
|
||||
otherwise(TurnierAnlageStep.Funktionaere)
|
||||
}
|
||||
step(TurnierAnlageStep.Funktionaere) {
|
||||
otherwise(TurnierAnlageStep.NennKonfig)
|
||||
}
|
||||
step(TurnierAnlageStep.NennKonfig) {
|
||||
otherwise(TurnierAnlageStep.Summary)
|
||||
}
|
||||
}
|
||||
+73
-4
@@ -1,7 +1,76 @@
|
||||
package at.mocode.veranstaltung.feature.wizard
|
||||
|
||||
// Platzhalter für den Event-Flow.
|
||||
// Hinweis: Der echte Flow lebt zunächst als Demo in :frontend:core:wizard (samples),
|
||||
// bis die VM-Delegation hinter dem Feature-Flag integriert wird.
|
||||
import at.mocode.frontend.core.navigation.AppScreen
|
||||
import at.mocode.frontend.core.wizard.dsl.flow
|
||||
import at.mocode.frontend.core.wizard.runtime.Guard
|
||||
import at.mocode.frontend.core.wizard.runtime.StepId
|
||||
import at.mocode.frontend.core.wizard.runtime.WizardContext
|
||||
import at.mocode.frontend.core.wizard.runtime.WizardState
|
||||
|
||||
object EventWizardPlaceholder
|
||||
sealed interface EventWizardStep : StepId {
|
||||
data object ZnsCheck : EventWizardStep
|
||||
data object VeranstalterSelection : EventWizardStep
|
||||
data object AnsprechpersonMapping : EventWizardStep
|
||||
data object MetaData : EventWizardStep
|
||||
data object TurnierKonfiguration : EventWizardStep
|
||||
data object BewerbKonfiguration : EventWizardStep
|
||||
data object AbteilungKonfiguration : EventWizardStep
|
||||
data object Summary : EventWizardStep
|
||||
}
|
||||
|
||||
data class EventWizardAcc(
|
||||
val veranstalterId: String? = null,
|
||||
val veranstalterNr: String = ""
|
||||
)
|
||||
|
||||
object EventWizardGuards {
|
||||
val hasZns: Guard<EventWizardStep, EventWizardAcc> = { ctx, _ ->
|
||||
val stats = ctx.stats
|
||||
if (stats == null) false
|
||||
else {
|
||||
val hasData = stats.vereinCount > 0
|
||||
hasData && !stats.lastImport.isNullOrBlank()
|
||||
}
|
||||
}
|
||||
|
||||
val needsContactPerson: Guard<EventWizardStep, EventWizardAcc> = { _, acc ->
|
||||
acc.veranstalterId == null || acc.veranstalterNr.startsWith("ORG-")
|
||||
}
|
||||
|
||||
val hasSelectedVeranstalter: Guard<EventWizardStep, EventWizardAcc> = { _, acc ->
|
||||
!acc.veranstalterId.isNullOrBlank()
|
||||
}
|
||||
}
|
||||
|
||||
val EventWizardFlow = flow<EventWizardStep, EventWizardAcc>(start = EventWizardStep.ZnsCheck) {
|
||||
step(EventWizardStep.ZnsCheck) {
|
||||
whenGuard("hasZns", EventWizardGuards.hasZns, go = EventWizardStep.VeranstalterSelection)
|
||||
otherwise(EventWizardStep.VeranstalterSelection)
|
||||
}
|
||||
step(EventWizardStep.VeranstalterSelection) {
|
||||
whenGuard("notSelected", { ctx, acc -> !EventWizardGuards.hasSelectedVeranstalter(ctx, acc) }, go = EventWizardStep.VeranstalterSelection)
|
||||
whenGuard("needsContactPerson", EventWizardGuards.needsContactPerson, go = EventWizardStep.AnsprechpersonMapping)
|
||||
otherwise(EventWizardStep.MetaData)
|
||||
}
|
||||
step(EventWizardStep.AnsprechpersonMapping) {
|
||||
otherwise(EventWizardStep.MetaData)
|
||||
}
|
||||
step(EventWizardStep.MetaData) {
|
||||
otherwise(EventWizardStep.TurnierKonfiguration)
|
||||
}
|
||||
step(EventWizardStep.TurnierKonfiguration) {
|
||||
otherwise(EventWizardStep.BewerbKonfiguration)
|
||||
}
|
||||
step(EventWizardStep.BewerbKonfiguration) {
|
||||
otherwise(EventWizardStep.AbteilungKonfiguration)
|
||||
}
|
||||
step(EventWizardStep.AbteilungKonfiguration) {
|
||||
otherwise(EventWizardStep.Summary)
|
||||
}
|
||||
step(EventWizardStep.Summary) {
|
||||
// End-Step
|
||||
}
|
||||
}
|
||||
|
||||
fun eventWizardStartState(origin: AppScreen, acc: EventWizardAcc = EventWizardAcc()): WizardState<EventWizardStep, EventWizardAcc> =
|
||||
WizardState(current = EventWizardStep.ZnsCheck, acc = acc)
|
||||
|
||||
Reference in New Issue
Block a user