Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1690da3fab | |||
| cb6e0103e7 |
Vendored
-41
@@ -1,41 +0,0 @@
|
||||
## 🚀 Identität & Arbeitsmodus (Chamäleon-Modus)
|
||||
Du bist ein hochqualifizierter KI-Assistent für das Softwareprojekt "Meldestelle" von Stefan.
|
||||
Ich weise dir in meinen Prompts Aufgaben zu. Nimm sofort die entsprechende Rolle an, beginne deine Antwort zwingend mit dem passenden Badge und passe dein Vokabular an:
|
||||
|
||||
* 🏗️ **[Lead Architect]:** System-Design, Gradle-Build-Logik, Modulstruktur.
|
||||
* 📜 **[Rulebook Expert]:** Validiert Business-Rules gegen das ÖTO/FEI Regelwerk.
|
||||
* 👷 **[Backend Developer]:** Kotlin & Spring Boot Experte.
|
||||
* 🎨 **[Frontend Expert]:** KMP & Compose Desktop Spezialist.
|
||||
* 🐧 **[DevOps Engineer]:** Infrastruktur (Docker, CI/CD, Proxmox).
|
||||
|
||||
**Arbeitsanweisung:** Bearbeite pro Antwort immer nur EINE fachliche Aufgabe.
|
||||
|
||||
|
||||
|
||||
## 🏗️ Projekt-Strategie (Reality-Reset)
|
||||
1. **Desktop-First & Offline-First:** Das Primärziel ist eine autarke Compose Desktop App (KMP). Sie muss auf Turnieren ohne Internet funktionieren (lokale Persistenz).
|
||||
2. **Optionales Backend:** Ein Spring Boot Stack (PostgreSQL, Valkey, Keycloak) wird nur für Multi-Tenant-Verwaltung, Registrierung und P2P-Sync genutzt.
|
||||
3. **Domain-Driven Design (DDD):** Die absolute Business-Hierarchie lautet: Veranstaltung -> Turnier -> Bewerb/Abteilung.
|
||||
4. **Der System-Akteur:** Der primäre "Actor" in allen Use-Cases ist *nicht* der Veranstalter, sondern zwingend die Person, die die Meldestelle betreut (Actor = Meldestelle).
|
||||
|
||||
|
||||
|
||||
## 🛠️ Der verbindliche Tech-Stack
|
||||
Generiere Code ausschließlich für diese exakten Versionen und Paradigmen:
|
||||
* **Frontend (KMP):** Kotlin 2.3.21, Compose Multiplatform 1.10.3, Ktor Client 3.4.1, SQLDelight.
|
||||
* **Backend:** Spring Boot 3.5.9 (JDK 25), Ktor Server (wo spezifiziert), Exposed 1.1.1.
|
||||
* **Infrastruktur:** Gitea (CI/CD), Docker, Pangolin Tunnel. (KEIN GitHub, KEIN Cloudflare).
|
||||
|
||||
|
||||
|
||||
## 👁️ Anti-Halluzinations-Protokoll
|
||||
Du bist an strikte, evidenzbasierte Entwicklung gebunden:
|
||||
1. **Kein "Erledigt" ohne Beweis:** Ein Task ist erst abgeschlossen, wenn Test-Logs oder ein Build vorliegen.
|
||||
2. **Verifikation ausstehend:** Generierter, ungetesteter Code muss diesen Vermerk zwingend tragen.
|
||||
3. **Fakten-Check:** Wenn du den Code nicht im Kontext hast (z.B. eine spezifische Gradle-Datei), fordere sie aktiv vom User an, anstatt blind zu raten.
|
||||
|
||||
|
||||
|
||||
## ⚙️ Provider-Spezifika (Google Gemini / Web-Meta-Modus)
|
||||
* Du agierst als "Gemini" über die Web-Oberfläche. Deine primäre Aufgabe ist die strategische Meta-Ebene, Architektur-Analyse, Review von CI/CD-Pipelines und das Sparring bei komplexen Refactoring-Plänen.
|
||||
* **Antwort-Stil:** Antworte prägnant, strukturiert und nutze das bereitgestellte Formatierungstoolkit (Markdown, klare Hierarchien, Code-Blöcke). Vermeide unnötige Floskeln und komm direkt auf den technischen Punkt.
|
||||
Vendored
-34
@@ -1,34 +0,0 @@
|
||||
## 🚀 Identität & Arbeitsmodus (Chamäleon-Modus)
|
||||
Du bist ein hochqualifizierter KI-Assistent für das Softwareprojekt "Meldestelle" von Stefan.
|
||||
Ich weise dir in meinen Prompts Aufgaben zu. Nimm sofort die entsprechende Rolle an, beginne deine Antwort zwingend mit dem passenden Badge und passe dein Vokabular an:
|
||||
|
||||
* 🏗️ **[Lead Architect]:** System-Design, Gradle-Build-Logik, Modulstruktur.
|
||||
* 📜 **[Rulebook Expert]:** Validiert Business-Rules gegen das ÖTO/FEI Regelwerk.
|
||||
* 👷 **[Backend Developer]:** Kotlin & Spring Boot Experte.
|
||||
* 🎨 **[Frontend Expert]:** KMP & Compose Desktop Spezialist.
|
||||
* 🐧 **[DevOps Engineer]:** Infrastruktur (Docker, CI/CD, Proxmox).
|
||||
|
||||
**Arbeitsanweisung:** Bearbeite pro Antwort immer nur EINE fachliche Aufgabe.
|
||||
|
||||
## 🏗️ Projekt-Strategie (Reality-Reset)
|
||||
1. **Desktop-First & Offline-First:** Das Primärziel ist eine autarke Compose Desktop App (KMP). Sie muss auf Turnieren ohne Internet funktionieren (lokale Persistenz).
|
||||
2. **Optionales Backend:** Ein Spring Boot Stack (PostgreSQL, Valkey, Keycloak) wird nur für Multi-Tenant-Verwaltung, Registrierung und P2P-Sync genutzt.
|
||||
3. **Domain-Driven Design (DDD):** Die absolute Business-Hierarchie lautet: Veranstaltung -> Turnier -> Bewerb/Abteilung.
|
||||
4. **Der System-Akteur:** Der primäre "Actor" in allen Use-Cases ist *nicht* der Veranstalter, sondern zwingend die Person, die die Meldestelle betreut (Actor = Meldestelle).
|
||||
|
||||
## 🛠️ Der verbindliche Tech-Stack
|
||||
Generiere Code ausschließlich für diese exakten Versionen und Paradigmen:
|
||||
* **Frontend (KMP):** Kotlin 2.3.21, Compose Multiplatform 1.10.3, Ktor Client 3.4.1, SQLDelight.
|
||||
* **Backend:** Spring Boot 3.5.9 (JDK 25), Ktor Server (wo spezifiziert), Exposed 1.1.1.
|
||||
* **Infrastruktur:** Gitea (CI/CD), Docker, Pangolin Tunnel. (KEIN GitHub, KEIN Cloudflare).
|
||||
|
||||
## 👁️ Anti-Halluzinations-Protokoll
|
||||
Du bist an strikte, evidenzbasierte Entwicklung gebunden:
|
||||
1. **Kein "Erledigt" ohne Beweis:** Ein Task ist erst abgeschlossen, wenn Test-Logs oder ein Build vorliegen.
|
||||
2. **Verifikation ausstehend:** Generierter, ungetesteter Code muss diesen Vermerk zwingend tragen.
|
||||
3. **Fakten-Check:** Wenn du den Code nicht im Kontext hast (z.B. eine spezifische Gradle-Datei), fordere sie aktiv vom User an, anstatt blind zu raten.
|
||||
|
||||
## ⚙️ Provider-Spezifika (JetBrains Junie / IDE-Modus)
|
||||
* Dein Name ist "Junie". Du arbeitest als hochintegrierter KI-Assistent direkt innerhalb von IntelliJ IDEA.
|
||||
* **Kontext-Fokus:** Nutze die lokalen Projektdateien, Indizes und das Git-Log intensiv. Wenn Refactorings oder Code-Generierungen anstehen, achte penibel darauf, dass bestehende Datei-Imports (Kotlin-Packages) nicht zerschossen werden.
|
||||
* **Generierungs-Gate:** Halte dich strikt an die im Projekt hinterlegten Formatierungsregeln für Detekt und Ktlint.
|
||||
@@ -0,0 +1,50 @@
|
||||
#!/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
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/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
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#!/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
|
||||
@@ -0,0 +1,127 @@
|
||||
#!/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(github.event.head_commit.message, '[planb]') }}
|
||||
if: ${{ vars.DESKTOP_CI_ENABLED == 'true' && !contains(gitea.event.head_commit.message, '[planb]') }}
|
||||
name: Compose Desktop — Tests (headless) & Build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: Build and Publish Docker Images
|
||||
run-name: Build & Publish by @${{ github.actor }}
|
||||
run-name: Build & Publish by @${{ gitea.actor }}
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -117,8 +117,8 @@ jobs:
|
||||
images: ${{ env.REGISTRY_INTERNAL }}/${{ env.IMAGE_PREFIX }}/${{ matrix.image }}
|
||||
tags: |
|
||||
type=ref,event=tag
|
||||
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
|
||||
type=sha,format=long,enable=${{ github.ref == 'refs/heads/main' }}
|
||||
type=raw,value=latest,enable=${{ gitea.ref == 'refs/heads/main' }}
|
||||
type=sha,format=long,enable=${{ gitea.ref == 'refs/heads/main' }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v6
|
||||
@@ -132,5 +132,5 @@ jobs:
|
||||
provenance: false
|
||||
sbom: false
|
||||
build-args: |
|
||||
BUILD_DATE=${{ github.event.head_commit.timestamp || 'unknown' }}
|
||||
VERSION=${{ github.sha }}
|
||||
BUILD_DATE=${{ gitea.event.head_commit.timestamp || 'unknown' }}
|
||||
VERSION=${{ gitea.sha }}
|
||||
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
chmod +x install-conveyor.sh
|
||||
./install-conveyor.sh
|
||||
fi
|
||||
echo "$HOME/.conveyor/bin" >> $GITHUB_PATH
|
||||
echo "$HOME/.conveyor/bin" >> $GITEA_PATH
|
||||
|
||||
- name: Windows .msi mit Conveyor bauen
|
||||
run: |
|
||||
|
||||
@@ -5,7 +5,7 @@ on:
|
||||
jobs:
|
||||
no-hardcoded-versions:
|
||||
# Für Plan-B-Builds überspringen: Commit-Message enthält [planb]
|
||||
if: ${{ !contains(github.event.head_commit.message, '[planb]') }}
|
||||
if: ${{ !contains(gitea.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(github.event.head_commit.message, '[planb]') }}
|
||||
if: ${{ !contains(gitea.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' && github.event.inputs.dry_run != 'true'
|
||||
if: steps.check-tag.outputs.already_tagged == 'false' && gitea.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(github.event.head_commit.message, '[planb]') }}
|
||||
if: ${{ vars.DESKTOP_CI_ENABLED == 'true' && !contains(gitea.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 21 (Temurin)
|
||||
- name: Setup JDK 25 (Temurin)
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: '21'
|
||||
java-version: '25'
|
||||
|
||||
- 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(github.event.head_commit.message, '[planb]') }}
|
||||
if: ${{ vars.DESKTOP_CI_ENABLED == 'true' && !contains(gitea.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 21 (Temurin)
|
||||
- name: Setup JDK 25 (Temurin)
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: '21'
|
||||
java-version: '25'
|
||||
|
||||
- name: Gradle cache
|
||||
uses: actions/cache@v4
|
||||
@@ -179,11 +179,11 @@ jobs:
|
||||
steps:
|
||||
- name: Summary ausgeben
|
||||
run: |
|
||||
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
|
||||
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
|
||||
|
||||
@@ -1,43 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# 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
|
||||
# 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,9 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
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
|
||||
# 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" "$@"
|
||||
|
||||
@@ -1,136 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# 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
|
||||
# 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" "$@"
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# .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
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/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" "$@"
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/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,7 +3,7 @@
|
||||
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 (Reality-Reset 15.06.2026)
|
||||
## 🚀 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.
|
||||
@@ -17,21 +17,21 @@ abgeschlossene Phasen ohne entsprechende Implementierung sind untersagt.
|
||||
Jede Agenten-Antwort **muss** mit dem entsprechenden Badge beginnen, um den Kontext und die Verantwortlichkeit zu klären.
|
||||
|
||||
* **🏗️ [Lead Architect]**: Hüter der **MASTER_ROADMAP**. Verantwortlich für System-Design, Build-Logik (Gradle), Modulstruktur und ADRs.
|
||||
* [Playbook](docs/05_Governance/Agents/Playbooks/Architect.md)
|
||||
* [Playbook](docs/04_Agents/Playbooks/Architect.md)
|
||||
* **📜 [Rulebook Expert]**: Wächter über **ÖTO & FEI**. Validiert Business-Rules gegen das offizielle Pferdesport-Regelwerk.
|
||||
* [Playbook](docs/05_Governance/Agents/Playbooks/RulebookExpert.md)
|
||||
* [Playbook](docs/04_Agents/Playbooks/RulebookExpert.md)
|
||||
* **👷 [Backend Developer]**: Kotlin & Spring Boot Experte. Fokus auf DDD, Persistenz (Postgres) und **Delta-Sync APIs**.
|
||||
* [Playbook](docs/05_Governance/Agents/Playbooks/BackendDeveloper.md)
|
||||
* [Playbook](docs/04_Agents/Playbooks/BackendDeveloper.md)
|
||||
* **🎨 [Frontend Expert]**: KMP & Compose Desktop Spezialist. Implementiert State-Management und High-Performance UI.
|
||||
* [Playbook](docs/05_Governance/Agents/Playbooks/FrontendExpert.md)
|
||||
* [Playbook](docs/04_Agents/Playbooks/FrontendExpert.md)
|
||||
* **🖌️ [UI/UX Designer]**: "Toolsmith" für High-Density Enterprise-UIs. Fokus auf Tastatur-Bedienbarkeit und Effizienz.
|
||||
* [Playbook](docs/05_Governance/Agents/Playbooks/UIUXDesigner.md)
|
||||
* [Playbook](docs/04_Agents/Playbooks/UIUXDesigner.md)
|
||||
* **🐧 [DevOps Engineer]**: Infrastruktur-Automatisierung (Docker, Gitea-Actions). Fokus auf Stabilität und lokale Dev-Umgebung.
|
||||
* [Playbook](docs/05_Governance/Agents/Playbooks/DevOpsEngineer.md)
|
||||
* [Playbook](docs/04_Agents/Playbooks/DevOpsEngineer.md)
|
||||
* **🧐 [QA Specialist]**: Test-Stratege (Shift-Left). Fokus auf Unit-, Integration- und Edge-Case-Tests (Testing Pyramid).
|
||||
* [Playbook](docs/05_Governance/Agents/Playbooks/QASpecialist.md)
|
||||
* [Playbook](docs/04_Agents/Playbooks/QASpecialist.md)
|
||||
* **🧹 [Curator]**: Wissens-Management & Dokumentations-Check (ADR, Reference, Journal). Beendet jede Session.
|
||||
* [Playbook](docs/05_Governance/Agents/Playbooks/Curator.md)
|
||||
* [Playbook](docs/04_Agents/Playbooks/Curator.md)
|
||||
|
||||
## 2. Der "Meldestelle"-Workflow
|
||||
1. **Kontext-Check:** Lies immer zuerst die `MASTER_ROADMAP` in `docs/01_Architecture/`.
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
type: Roadmap
|
||||
status: ACTIVE
|
||||
owner: Lead Architect
|
||||
last_update: 2026-06-15
|
||||
last_update: 2026-05-06
|
||||
---
|
||||
|
||||
# MASTER ROADMAP: Meldestelle
|
||||
|
||||
🏗️ **[Lead Architect]** | 15. Juni 2026
|
||||
🏗️ **[Lead Architect]** | 30. April 2026
|
||||
|
||||
**Strategisches Ziel:**
|
||||
Entwicklung einer ÖTO-konformen, offline-fähigen Turnier-Meldestelle als Compose Desktop App (KMP).
|
||||
@@ -17,16 +17,16 @@ Vollständige Self-Hosted Infrastruktur (Gitea, Pangolin, Zora). Datensouveräni
|
||||
- Desktop-App ist der primäre Client (Compose Desktop, KMP) — „Desktop-First“ gilt für UX und Architektur.
|
||||
- Offline-First Betrieb mit lokaler Persistenz und opportunistischer Synchronisation.
|
||||
|
||||
**Aktueller technischer Stand (15.06.2026):**
|
||||
**Aktueller technischer Stand (30.04.2026):**
|
||||
* **Infrastruktur:** ✅ "Zora" (MS-R1, ARM64) ist live. Gitea & Registry laufen.
|
||||
* **Networking:** ✅ Pangolin Tunnel ersetzt Cloudflare.
|
||||
* **CI/CD:** ✅ Gitea Actions mit ARM64-Runner (VM 102) aktiv. Docker-Publish Pipeline grün.
|
||||
* **Code-Basis:** ✅ Backend (Java 25 / Spring Boot / Kotlin), Frontend (KMP/Compose Desktop).
|
||||
* **Domain-Design:** ✅ 6 Bounded Contexts (SCS-Architektur) definiert. Ubiquitous Language erstellt.
|
||||
* **Domain-Modelle:** ✅ `Reiter`, `Nennung`, `NennungsTransfer`, `Pferd`, `Funktionaer`, `Verein`,
|
||||
`Bewerb`, `Abteilung`, `DomStartliste`, `Veranstaltung`, `Turnier`, `Ausschreibung` implementiert.
|
||||
* **Domain-Modelle:** ✅ `Reiter`, `DomNennung`, `DomNennungsTransfer`, `Pferd`, `Funktionaer`, `Verein`,
|
||||
`DomBewerb`, `DomAbteilung`, `DomStartliste`, `DomVeranstaltung`, `DomTurnier`, `DomAusschreibung` implementiert.
|
||||
Enums ÖTO-konform.
|
||||
* **Dokumentation:** 🧹 Sanierung abgeschlossen (5-Säulen-Struktur). Reality-Reset durchgeführt.
|
||||
* **Dokumentation:** ✅ Konsolidiert. ÖTO-Regelwerk-Referenzen (Abteilungs-Schwellenwerte) dokumentiert.
|
||||
|
||||
---
|
||||
|
||||
@@ -155,15 +155,15 @@ Code-Stand.*
|
||||
|
||||
| Dokument | Pfad |
|
||||
|-------------------------------|----------------------------------------------------------------------------------------------|
|
||||
| Ubiquitous Language | `docs/02_Domain/01_Glossary/Ubiquitous_Language.md` |
|
||||
| Abteilungs-Schwellenwerte | `docs/02_Domain/02_Reference/OETO_Regelwerk/Abteilungs-Trennungs-Schwellenwerte.md` |
|
||||
| Warn-Logik-Spezifikation | `docs/02_Domain/02_Reference/OETO_Regelwerk/Warn-Logik-Spezifikation-competition-context.md` |
|
||||
| Session Log (DDD) | `docs/05_Governance/Journal/_archive/2026-03-24_Session_Log_DDD_Ubiquitous_Language.md` |
|
||||
| Infrastruktur | `docs/04_Operations/Infrastructure/Zora_System_Architektur.md` |
|
||||
| Deployment Guide | `docs/04_Operations/Infrastructure/Guides/Setup_Git_Deployment_Zora.md` |
|
||||
| Backup Guide | `docs/04_Operations/Infrastructure/Guides/Setup_Backup_Zora.md` |
|
||||
| Ubiquitous Language | `docs/03_Domain/01_Glossary/Ubiquitous_Language.md` |
|
||||
| Abteilungs-Schwellenwerte | `docs/03_Domain/02_Reference/OETO_Regelwerk/Abteilungs-Trennungs-Schwellenwerte.md` |
|
||||
| Warn-Logik-Spezifikation | `docs/03_Domain/02_Reference/OETO_Regelwerk/Warn-Logik-Spezifikation-competition-context.md` |
|
||||
| Session Log (DDD) | `docs/99_Journal/2026-03-24_Session_Log_DDD_Ubiquitous_Language.md` |
|
||||
| Infrastruktur | `docs/07_Infrastructure/Zora_System_Architektur.md` |
|
||||
| Deployment Guide | `docs/07_Infrastructure/Guides/Setup_Git_Deployment_Zora.md` |
|
||||
| Backup Guide | `docs/07_Infrastructure/Guides/Setup_Backup_Zora.md` |
|
||||
| CI/CD | `.gitea/workflows/docker-publish.yaml` |
|
||||
| Agent Playbooks | `docs/05_Governance/Agents/Playbooks/` |
|
||||
| Agent Playbooks | `docs/04_Agents/Playbooks/` |
|
||||
| ADR-Verzeichnis | `docs/01_Architecture/adr/` |
|
||||
| ADR-0025: Plan-USB | `docs/01_Architecture/adr/0025-plan-usb-offline-integritaet.md` |
|
||||
| ADR-0026: Lizenzierung | `docs/01_Architecture/adr/0026-offline-lizenzierung-pay-per-event.md` |
|
||||
|
||||
+5
-6
@@ -2,12 +2,11 @@
|
||||
type: Reference
|
||||
status: ACTIVE
|
||||
owner: Lead Architect & ÖTO/FEI Rulebook Expert
|
||||
last_update: 2026-06-15
|
||||
last_update: 2026-04-05
|
||||
sources:
|
||||
- ÖTO 2026, Abschnitt A I, § 2 & § 3 & § 4
|
||||
- Domain Workshop 2026-03-17
|
||||
- Session 2026-03-24 (Architektur-Diskussion)
|
||||
- Sanierung 2026-06-15 (Reality-Reset)
|
||||
---
|
||||
|
||||
# Ubiquitous Language – Offizielle Domänen-Terminologie
|
||||
@@ -147,7 +146,7 @@ Veranstalter (OEPS-Mitgliedsverein)
|
||||
| **Sparte** | Die unterschiedlichen Arten von Turnieren oder Bewerben (z.B. Dressur = CDN, Springen = CSN). Bestimmt das anzuwendende Richtverfahren und das Regelwerk. | ÖTO § 2 Abs. 9, § 3 Abs. 2 |
|
||||
| **Sperrliste** | Vom Verband geführte Liste von Personen oder Pferden, die aktuell nicht startberechtigt sind (meist wegen offener Zahlungen). | – |
|
||||
| **Sportförderbeitrag** | Gebühr, die **pro Start** anfällt (nicht pro Nennung!). Relevant bei Mehrfach-Starts. | ÖTO Gebührenordnung |
|
||||
| **Stammdaten** | Die zentrale Library of Truth (`masterdata-context`) für alle statischen Informationen: Personen, Pferde, Vereine, sowie das ÖTO-Regelwerk (Richtverfahren, Paragraphen, Gebührensätze). | – |
|
||||
| **Stammdaten** | (Früher: Akteur-Context). Die zentrale Library of Truth (`master-data-context`) für alle statischen Informationen: Personen, Pferde, Vereine, sowie das ÖTO-Regelwerk (Richtverfahren, Paragraphen, Gebührensätze). | – |
|
||||
| **Startkarte** | Nachweis, dass die Jahresgebühr für die Lizenz bezahlt wurde. Ohne aktive Startkarte ist national kein Start möglich. | ÖTO Teilnahmeberechtigung |
|
||||
| **Startwunsch** | Präferenz eines Reiters bezüglich seiner Position in der Startliste (vorne/hinten). | Registration Context |
|
||||
|
||||
@@ -189,7 +188,7 @@ Veranstalter (OEPS-Mitgliedsverein)
|
||||
| Veranstaltung, Turnier, Ausschreibung, Veranstalter | `event-management-context` |
|
||||
| Bewerb, Abteilung, Startliste, Ergebnis, Richtverfahren | `competition-context` |
|
||||
| Nennung, Nennungs-Transfer, Startwunsch, ZNS-Import | `registration-context` |
|
||||
| Reiter, Pferd, Lizenz, Funktionär, Kopfnummer, Satznummer, Verein | `masterdata-context` |
|
||||
| Reiter, Pferd, Lizenz, Funktionär, Kopfnummer, Satznummer, Verein | `actor-context` |
|
||||
| Nenngeld, Startgeld, Konto, Transaktion, Sportförderbeitrag | `billing-context` |
|
||||
| Cup, Serie, Meisterschaft, Reglement, Endklassement | `series-context` *(Phase 2+)* |
|
||||
| Login, Rolle, Berechtigung | `identity-context` |
|
||||
@@ -223,7 +222,7 @@ Ein Reglement definiert typischerweise:
|
||||
- Verschiedene Cups/Serien können **unterschiedliche Punktesysteme** haben → das Berechnungsmodell muss pluggable sein.
|
||||
- Die **Paar-Bindung** (Punkte an Reiter+Pferd vs. nur Reiter) ist eine kritische Designentscheidung pro Reglement.
|
||||
- Referenz-Dokument: [
|
||||
`docs/02_Domain/02_Reference/OETO_Regelwerk/Struktur-Meisterschafts-Cup-Reglements_OETO.md`](../02_Reference/OETO_Regelwerk/Struktur-Meisterschafts-Cup-Reglements_OETO.md)
|
||||
`docs/03_Domain/02_Reference/OETO_Regelwerk/Struktur-Meisterschafts-Cup-Reglements_OETO.md`](../02_Reference/OETO_Regelwerk/Struktur-Meisterschafts-Cup-Reglements_OETO.md)
|
||||
|
||||
---
|
||||
|
||||
@@ -242,4 +241,4 @@ Ein Reglement definiert typischerweise:
|
||||
---
|
||||
|
||||
*Erstellt: 2026-03-24 | Autoren: Lead Architect, ÖTO/FEI Rulebook Expert, Curator*
|
||||
*Basiert auf: ÖTO 2026 § 2, § 3, § 4 | Domain Workshop 2026-03-17 | Session 2026-03-24 | Update: 2026-06-15 (Reality-Reset & Alignment)*
|
||||
*Basiert auf: ÖTO 2026 § 2, § 3, § 4 | Domain Workshop 2026-03-17 | Session 2026-03-24 | Update: 2026-04-05 (Verein-Renaming & Bereinigung)*
|
||||
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 325 KiB After Width: | Height: | Size: 325 KiB |
@@ -0,0 +1,35 @@
|
||||
# 🧹 Session Journal - 15. April 2026 (Nachmittag)
|
||||
|
||||
## 🏗️ Status-Check (Lead Architect)
|
||||
|
||||
- **Phase 13 (Export & Billing):** Die Gebührenlogik wurde für das Neumarkt-Turnier (April 2026) finalisiert.
|
||||
- **ÖTO-Konformität:** Der Sportförderbeitrag gemäß § 16 ÖTO wird nun bei jeder Nennung automatisch verbucht.
|
||||
|
||||
## 👷 Durchgeführte Arbeiten (Backend)
|
||||
|
||||
1. **Billing (billing-domain & service):**
|
||||
- `BuchungsTyp.SPORTFOERDERBEITRAG` zum Enum hinzugefügt.
|
||||
- `TeilnehmerKontoService` um die Validierung für diesen neuen Typ erweitert (automatische Soll-Buchung).
|
||||
2. **Entries (entries-service):**
|
||||
- `NennungUseCases` aktualisiert: Bei jeder Nennungseingabe wird nun automatisch 1,00 EUR Sportförderbeitrag auf das
|
||||
Teilnehmerkonto gebucht, zusätzlich zu Nenngeld und Nachnenngebühr.
|
||||
3. **ZNS-Export (Bewerbe-SCS):**
|
||||
- Prüfung des `B-Satz` Exports im `BewerbeController`. Die Logik zur Generierung des strukturierten Textformats für
|
||||
den OEPS ist vorhanden und nutzt die `ZnsBewerb`-Modelle.
|
||||
|
||||
## 🧐 QA-Status & Bekannte Themen
|
||||
|
||||
- [x] **Billing-Check:** Die automatische Buchungskette (Nennung -> Konto -> Buchung) ist nun vollständig für alle
|
||||
Pflichtgebühren integriert.
|
||||
- [x] **Integrationstests:** `NennungBillingIntegrationTest` wurde an die neue Gebührenlogik angepasst (1,00 EUR
|
||||
Sportförderbeitrag).
|
||||
- [ ] **Export-Validierung:** Der generierte B-Satz muss noch gegen ein offizielles OEPS-Beispiel validiert werden (
|
||||
geplant für die nächste Session).
|
||||
|
||||
## 🧹 Curator's Note
|
||||
|
||||
- Die ROADMAP Phase 13 wurde in der Vormittags-Session bereits aktualisiert.
|
||||
- Der Fokus für morgen liegt auf der **ZNS-Export-Validierung** und der Vorbereitung des **Teilnehmer-Exports** (
|
||||
A-Satz).
|
||||
|
||||
**Abschluss:** Das Billing-System ist "ÖTO-ready" für Neumarkt. 🐎🏦
|
||||
@@ -0,0 +1,47 @@
|
||||
# 🧹 Session Journal - 15. April 2026 (Desktop UX & Onboarding)
|
||||
|
||||
## 🏗️ Status-Check (Lead Architect)
|
||||
|
||||
- **Workflow-Fokus:** Abkehr vom verfrühten Deployment hin zur ehrlichen "Workflow-First" Entwicklung der Desktop-App.
|
||||
- **Identität & Sicherheit:** Die App verfügt nun über ein robustes Onboarding-System für die lokale Identität und
|
||||
Sicherheit.
|
||||
- **UX-Optimierung:** Die Navigation wurde um Hover-Tooltips erweitert, um die Bedienbarkeit ohne Textlabels in der
|
||||
NavRail zu gewährleisten.
|
||||
|
||||
## 👷 Durchgeführte Arbeiten (Frontend & UX)
|
||||
|
||||
1. **Onboarding & Setup ("Geburtsurkunde"):**
|
||||
- Komplette Neugestaltung des `OnboardingScreen` (v2).
|
||||
- Erfassung von Gerätename, Sicherheitsschlüssel (Shared Secret) und Datenbank-Sicherungspfad.
|
||||
- Integration von interaktiven Auswahl-Dialogen: `JFileChooser` für Pfade und `PrintServiceLookup` für installierte
|
||||
Drucker.
|
||||
- Einführung des `SettingsManager` zur persistenten Speicherung der Einstellungen in `settings.json`.
|
||||
- Implementierung des `OnboardingValidator` zur Sicherstellung valider Pflichtangaben (Name, Key, Backup-Pfad).
|
||||
|
||||
2. **Navigation & Layout:**
|
||||
- Erweiterung der `DesktopNavRail` um ein dediziertes "Setup"-Icon (`AppRegistration`) am unteren Ende.
|
||||
- Auslagerung des Ping-Service ("Sync") als eigenständiges Icon (`WifiTethering`).
|
||||
- Implementierung von **Hover-Tooltips** für alle Navigations-Items (`NavRailItem`) unter Verwendung von Material3
|
||||
`TooltipBox`.
|
||||
- Tooltips sind rechtsbündig (`TooltipAnchorPosition.Right`) positioniert und zeigen den Namen des Moduls ("Admin", "
|
||||
Vereine", "Mails", "Sync", "Setup").
|
||||
|
||||
3. **Code-Qualität & Refactoring:**
|
||||
- Bereinigung veralteter Onboarding-Screens und Konsolidierung auf das v2-Datenmodell.
|
||||
- Integration von `@Preview`-Blöcken direkt in den Screen-Komponenten zur IDE-gestützten Entwicklung.
|
||||
- Erfolgreiche Kompilierung des `meldestelle-desktop` Moduls nach Behebung von Typ-Konflikten.
|
||||
|
||||
## 🧐 QA-Status & Bekannte Themen
|
||||
|
||||
- [x] **Onboarding-Workflow:** App erzwingt Setup bei fehlender Konfiguration.
|
||||
- [x] **Drucker-Anbindung:** Systemdrucker werden korrekt gelistet.
|
||||
- [x] **Tooltip-UX:** Hover-Effekt in der Navigationsleiste ist aktiv und informativ.
|
||||
- [ ] **E2E-Integration:** Die Anbindung des `NennungsEingangScreen` an den echten `mail-service` (Server-Daten abholen)
|
||||
ist der nächste logische Schritt.
|
||||
|
||||
## 🧹 Curator's Note
|
||||
|
||||
- Die Strategie hat sich von "Live-Gang" zurück auf "Ehrliches Desktop-Fundament" verschoben.
|
||||
- Das "Biest" hat jetzt einen Namen und einen Platz für seine Backups. 💾
|
||||
|
||||
**Abschluss:** Onboarding und Basis-Navigation sind "Enterprise-Ready". 🚀
|
||||
@@ -0,0 +1,43 @@
|
||||
# 🧹 Session Journal - 15. April 2026 (Live-Gang Vorbereitung)
|
||||
|
||||
## 🏗️ Status-Check (Lead Architect)
|
||||
|
||||
- **Phase 13 (Export & Mail-Service):** Infrastruktur und Deployment-Vorbereitungen für den Live-Gang des Online-Nennens
|
||||
sind abgeschlossen.
|
||||
- **Ziel erreicht:** Das System kann nun auf dem Produktions-Server deployt werden.
|
||||
|
||||
## 👷 Durchgeführte Arbeiten (DevOps & Frontend)
|
||||
|
||||
1. **Infrastruktur (Docker & Mail):**
|
||||
- Dockerfile für `mail-service` erstellt.
|
||||
- `dc-backend.yaml` um den `mail-service` erweitert (inkl. Postgres-Link, Consul-Discovery und SMTP-Konfiguration).
|
||||
- Port-Kollision zwischen `events-service` und `mail-service` behoben (`mail-service` Host-Port auf 8083).
|
||||
- `.env` und `.env.example` (SSoT) umfassend für alle Microservices (Standard-Ports, Debug, SMTP) vervollständigt.
|
||||
- `application.yaml` im `mail-service` auf SMTP-Versand (World4You Standard) optimiert und IMAP-Reste entfernt.
|
||||
- **Plus-Addressing:** Backend-Logik im `MailController` implementiert, um Mails dynamisch als
|
||||
`online-nennen+[TurnierNr]@mo-code.at` zu versenden.
|
||||
2. **Frontend (Konfigurierbarkeit):**
|
||||
- Common `PlatformConfig` erweitert um `resolveMailServiceUrl`.
|
||||
- Implementierung für Wasm, JS und JVM hinzugefügt, um Backend-URLs zur Laufzeit steuern zu können (Wasm: via global
|
||||
JS variables).
|
||||
- `NennungRemoteRepository` nutzt nun die dynamisch aufgelöste Mail-Service-URL.
|
||||
- Fehlende Projekt-Abhängigkeit (`frontend.core.network`) im `nennung-feature` ergänzt.
|
||||
3. **Sicherheit:**
|
||||
- CORS im `MailController` auf Ziel-Domains eingeschränkt (`nennung.mo-code.at`).
|
||||
- Bean-Validierung für `NennungRequest` (Email-Format, Pflichtfelder) implementiert.
|
||||
4. **Dokumentation:**
|
||||
- `docs/05_Deployment/2026-04-15_Online-Nennung-Deployment.md` erstellt.
|
||||
|
||||
## 🧐 QA-Status & Bekannte Themen
|
||||
|
||||
- [x] **Infrastruktur-Check:** Docker-Stack ist bereit für `up -d mail-service`.
|
||||
- [x] **Frontend-URL:** Die harte Verdrahtung auf `localhost:8085` wurde durch eine flexible Runtime-Konfiguration
|
||||
ersetzt.
|
||||
- [ ] **Mail-Versand:** Der tatsächliche Versand muss in der Ziel-Umgebung mit echten SMTP-Credentials validiert werden.
|
||||
|
||||
## 🧹 Curator's Note
|
||||
|
||||
- Die ROADMAP Phase 13 wurde in der Vormittags-Session bereits aktualisiert.
|
||||
- Das "Biest" ist nun technologisch "Live-ready". 🚀
|
||||
|
||||
**Abschluss:** Online-Nennung bereit für das Neumarkt-Turnier (April 2026). 🐎
|
||||
@@ -0,0 +1,29 @@
|
||||
# 🧹 Session Journal - 15. April 2026
|
||||
|
||||
## 🏗️ Status-Check (Lead Architect)
|
||||
- **Phase 13 (Export & Mail-Service):** Signifikanter Fortschritt. Die Online-Nennung (Web -> Backend) ist nun funktional integriert.
|
||||
- **Deadline-Fokus:** Neumarkt-Turnier (24. April 2026). Das System ist bereit für die ersten Online-Nennungen über die Web-Plattform.
|
||||
|
||||
## 👷 Durchgeführte Arbeiten (Backend & Frontend)
|
||||
1. **Backend (mail-service):**
|
||||
- `MailController` implementiert (`/api/mail/nennung`).
|
||||
- REST-Endpunkt zur direkten Aufnahme von Web-Nennungen (Bypass für Polling-Latenz).
|
||||
- Automatische Bestätigungs-Mails an Reiter via Spring Mail.
|
||||
- Nennungen werden direkt in der Nennungs-Tabelle persistiert.
|
||||
2. **Frontend (nennung-feature):**
|
||||
- `NennungRemoteRepository` (KMP) für Ktor-API-Calls erstellt.
|
||||
- Ktor-Client Abhängigkeiten und Kotlin-Serialization integriert.
|
||||
3. **Frontend (meldestelle-web):**
|
||||
- `WebMainScreen` mit dem Remote-Repository verknüpft.
|
||||
- Echte Datenübertragung statt bloßer Konsolenausgabe.
|
||||
- Erfolgsscreen nach erfolgreichem API-Call.
|
||||
|
||||
## 🧐 QA-Status & Bekannte Themen
|
||||
- [ ] **DI-Check:** Die Koin-Registrierung des `HttpClient` im `nennung-feature` zeigt in der IDE Typ-Inferenz-Probleme (wahrscheinlich KMP/Compose Compiler Sync-Thema). Muss beim Build final validiert werden.
|
||||
- [ ] **CORS:** Im `MailController` auf `*` gesetzt für den Wasm-Prototyp. In Prod auf Domain einschränken.
|
||||
|
||||
## 🧹 Curator's Note
|
||||
- Die `MASTER_ROADMAP` wurde aktualisiert.
|
||||
- Der Fokus für die nächste Session liegt auf dem **Billing-Check** (Gebühren-Validierung für Neumarkt) und dem ersten **Probelauf des ZNS-Exports**.
|
||||
|
||||
**Abschluss:** Das "Biest" ist nun "online-fähig" für Neumarkt. 🚀
|
||||
@@ -0,0 +1,45 @@
|
||||
# SCS Workflow Journal: Stammdaten & Nennungs-Eingang
|
||||
|
||||
Datum: 15. April 2026, 22:30 Uhr
|
||||
Agent: 🏗️ [Lead Architect] & 🧹 [Curator]
|
||||
|
||||
## 🎯 Tagesziel: SCS Event-Management & Identity
|
||||
|
||||
Nach dem erfolgreichen Onboarding am Vormittag lag der Fokus nun auf der fachlichen Vertiefung der Workflows für das
|
||||
Turnier in Neumarkt.
|
||||
|
||||
### 1. SCS Identity (Backend & Infrastructure) - Fixes
|
||||
|
||||
* **KMP-Zeitstempel:** Umstellung des `identity`-Moduls auf `kotlin.time.Instant`, um Deprecation-Warnungen und
|
||||
Typ-Konflikte (Java vs. Kotlin) in der Persistenz-Schicht (`ExposedDeviceRepository`) zu beheben.
|
||||
* **Build-Stabilität:** Erfolgreiche Kompilierung nach Korrektur unsicherer Casts im `turnier-feature`.
|
||||
|
||||
### 2. SCS Event-Management (ZNS & Turnieranlage)
|
||||
|
||||
* **ZNS-Import-Workflow:** Verifizierung der asynchronen Import-Kette. Das Frontend (`StammdatenImportScreen`) ist nun
|
||||
technologisch bereit, ZIP-Daten an den `zns-import-service` zu senden.
|
||||
* **Turnier-Wizard (ÖTO-Fokus):** Der `TurnierWizardV2` wurde auf ÖTO-Konformität geprüft. Er validiert Turnierdaten
|
||||
gegen die übergeordnete Veranstaltung und bietet Auto-Mapping für bekannte Turniere (Neumarkt ID 26128).
|
||||
|
||||
### 3. SCS Online-Nennung (Nennungs-Eingang)
|
||||
|
||||
* **Live-Daten-Integration:** Der `NennungsEingangScreen` wurde von Mock-Daten auf echte Daten vom `mail-service`
|
||||
umgestellt.
|
||||
* **Repository-Erweiterung:** Das `NennungRemoteRepository` (nennung-feature) beherrscht nun `holeNennungen()` und
|
||||
integriert sich via Koin in die Desktop-App.
|
||||
* **Port-Harmonisierung:** Korrektur des Fallback-Ports für den `mail-service` auf `8083` in `PlatformConfig.jvm.kt`.
|
||||
|
||||
---
|
||||
|
||||
## 🚩 Status & Nächste Schritte
|
||||
|
||||
Das "Biest" ist nun in der Lage, Stammdaten zu importieren, Turniere anzulegen und echte Online-Nennungen vom Server
|
||||
abzurufen.
|
||||
|
||||
**Nächster Fokus:**
|
||||
|
||||
1. **SCS Masterdata:** Finalisierung der Reiter- und Pferdestammdaten-Editoren (Detail-Ansichten).
|
||||
2. **SCS Results:** Vorbereitung des ersten Bewerbs-Protokolls (Starterlisten-Generierung).
|
||||
3. **OEPS-Validierung:** Export-Tests für den A-Satz (Teilnehmerliste).
|
||||
|
||||
**Status:** Workflows für Neumarkt sind zu 85% einsatzbereit. 🚀🐎
|
||||
@@ -0,0 +1,153 @@
|
||||
# Journal-Eintrag: Plan-B Online-Nenn-Formulare
|
||||
|
||||
**Datum:** 23. April 2026
|
||||
**Agenten:** 🎨 [Frontend Expert], 🖌️ [UI/UX Designer], 👷 [Backend Developer], 🧹 [Curator]
|
||||
|
||||
## 🎯 Zielsetzung
|
||||
Erstellung von zwei hoch-optimierten Web-Formularen für die Turniere in Neumarkt (25. & 26. April 2026) im Rahmen des "Plan-B" (Offline-Meldestelle mit E-Mail-Sync).
|
||||
|
||||
## 🛠️ Durchgeführte Änderungen
|
||||
|
||||
### 🎨 Frontend & UI/UX
|
||||
- **`OnlineNennungFormular.kt`**: Komplette Neugestaltung des Formulars.
|
||||
- Integration der spezifischen Bewerbe für **CSN-C Neumarkt (25.04.)** und **CDN-C Neumarkt (26.04.)**.
|
||||
- Implementierung der Validierungslogik für den "Jetzt nennen" Button (Bernstein-Orange).
|
||||
- Hinzufügen von Feldern für Reiter-Name, Kontakt (E-Mail/Tel), Pferdename und Anmerkungen.
|
||||
- Information Density: Alle Bewerbe direkt auswählbar.
|
||||
- **Mobile-First Optimierung**: Responsives Layout mittels `BoxWithConstraints`. Vertikaler Stack für Formularfelder auf Mobile, optimierte Paddings, Schriftgrößen und Touch-Targets.
|
||||
- **`WebMainScreen.kt`**: Aktualisierung der Landing-Page mit den realen Turnierdaten für Neumarkt.
|
||||
- **Mobile-First Optimierung**: Turnier-Karten passen sich an schmale Bildschirme an (Buttons nebeneinander, Icons für bessere UX).
|
||||
|
||||
### 👷 Backend & Integration
|
||||
- **`NennungRemoteRepository.kt`**: Verknüpfung des neuen Payloads mit dem `mail-service`.
|
||||
- **`MailController.kt`**: Validierung der API-Schnittstelle. Der Service ist so konfiguriert, dass er:
|
||||
1. Die Nennung in der Datenbank persistiert.
|
||||
2. Eine Benachrichtigungs-Mail an die Meldestelle (`online-nennen@mo-code.at`) sendet.
|
||||
3. Eine automatische Bestätigung an den Reiter schickt.
|
||||
|
||||
## 🏁 Ergebnis
|
||||
Die "Hallo Du!" Test-UI wurde durch produktive, fachlich korrekte Formulare ersetzt. Sobald ein Reiter auf "Jetzt nennen" klickt, wird der E-Mail-Workflow ausgelöst.
|
||||
|
||||
**Status:** Bereit für den Live-Einsatz am Wochenende. 🚀
|
||||
|
||||
### 2026-04-23 09:35 - Version 12: Hard-coded HTTPS & Injektions-Fix
|
||||
- **Problem**: 'Mixed Content' Fehler blockierte API-Aufrufe, da die Wasm-App trotz HTTPS-Origin versuchte, 'http://10.0.0.50' (Lokale IP) via HTTP zu kontaktieren.
|
||||
- **Lösung**:
|
||||
- `PlatformConfig.wasmJs.kt`: Implementierung eines sicheren HTTPS-Fallbacks auf `https://api.mo-code.at` im Code, falls die Docker-Injektion (z.B. durch Browser-Cache) fehlschlägt.
|
||||
- `dc-planb.yaml`: Statische Konfiguration der HTTPS-URLs ohne Umgebungsvariablen-Platzhalter, um Fehlkonfigurationen am Host auszuschließen.
|
||||
- UI-Marker auf `v2026-04-23.12 - HARD-CODED HTTPS` aktualisiert.
|
||||
- Fehlerbehandlung in `OnlineNennungFormular.kt` zeigt nun explizit Netzwerkfehler an, falls diese auftreten.
|
||||
|
||||
### 2026-04-23 10:15 - Version 13: Radikale HTTPS-Priorisierung
|
||||
- **Problem**: Trotz harten Fallbacks im Code versuchte der Browser weiterhin `http://10.0.0.50` (Mixed Content) aufzurufen. Ursache war die Priorisierung von dynamischen Variablen und `window.location.origin` in der `PlatformConfig.wasmJs.kt`.
|
||||
- **Lösung**:
|
||||
- `PlatformConfig.wasmJs.kt`: Alle Logiken zur Erkennung von URLs wurden temporär deaktiviert. Die Funktionen `resolveMailServiceUrl()` und `resolveApiBaseUrl()` geben nun **zwingend** `https://api.mo-code.at` zurück.
|
||||
- Dies umgeht jegliches Caching von `index.html` oder fälschlich injizierte Umgebungsvariablen.
|
||||
- UI-Marker auf `v2026-04-23.13 - RADICAL HTTPS PRIORITIZATION` aktualisiert.
|
||||
|
||||
### 2026-04-23 10:45 - Version 14: CORS Reanimation
|
||||
- **Problem**: Trotz HTTPS-Fix blockierte die CORS-Policy im Backend die Anfragen von `https://app.mo-code.at`.
|
||||
- **Lösung**:
|
||||
- `GlobalSecurityConfig.kt`: CORS explizit wieder aktiviert (`.cors { }`), da Microservices im Plan-B direkt (ohne Gateway) angesprochen werden könnten.
|
||||
- `MailController.kt`: `@CrossOrigin` um explizite Header (`allowedHeaders = ["*"]`) und Methoden (`methods = [...]`) erweitert, um Preflight-Checks (OPTIONS) korrekt zu bedienen.
|
||||
- UI-Marker auf `v2026-04-23.14 - CORS REANIMATION` aktualisiert.
|
||||
|
||||
### 2026-04-23 11:45 - Version 17: Security Dependency Fix
|
||||
- **Problem**: Trotz Version 16 und dem `scanBasePackages` Fix im `mail-service` bestand der CORS-Fehler weiterhin. Ursache: Dem `mail-service` fehlten die notwendigen Spring Security Abhängigkeiten in der `build.gradle.kts`, wodurch die Security-Konfiguration (und damit CORS) ignoriert wurde.
|
||||
- **Lösung**:
|
||||
- `build.gradle.kts` (mail-service): `spring-boot-starter-security`, `spring-boot-starter-oauth2-resource-server` und das `infrastructure:security` Modul explizit als Abhängigkeiten hinzugefügt.
|
||||
- UI-Marker auf `v2026-04-23.17 - SECURITY DEPENDENCY FIX` aktualisiert.
|
||||
|
||||
### v2026-04-23.19 - NUCLEAR CORS FIX
|
||||
- **Problem**: Trotz Patterns in der Security-Konfiguration fehlte der `Access-Control-Allow-Origin` Header bei Preflight-Anfragen.
|
||||
- **Lösung**:
|
||||
- Implementierung einer `WebMvcConfigurer` Bean direkt in `MailServiceApplication.kt` für ein zweites, redundantes CORS-Mapping.
|
||||
- Lockerung der `allowedOriginPatterns` in `GlobalSecurityConfig.kt` auf `*`.
|
||||
- **Status**: Versionsmarker auf v19 aktualisiert.
|
||||
|
||||
### v2026-04-23.20 - CLOUDFLARE DNS VERIFIED & CORS POLISHING
|
||||
- **Analyse**: DNS-Einträge in Cloudflare geprüft (Screenshot). Alle Einträge stehen auf "Nur DNS" (graue Wolke). Cloudflare-Proxy ist inaktiv, daher kann Cloudflare keine CORS-Probleme verursachen.
|
||||
- **Lösung**:
|
||||
- CORS-Konfiguration in `GlobalSecurityConfig.kt` finalisiert: Whitelist für `https://*.mo-code.at` und `http://localhost:[*]` verfeinert.
|
||||
- `allowedMethods` um `HEAD` erweitert und `exposedHeaders` hinzugefügt, um Browser-Warnungen zu eliminieren.
|
||||
- **Status**: Versionsmarker auf v2026-04-23.20 aktualisiert.
|
||||
|
||||
### v2026-04-23.21 - CADDY CORS PROXY FIX
|
||||
- **Problem**: Trotz umfangreicher Backend-Konfiguration (v20) meldete der Browser weiterhin fehlende CORS-Header bei Preflight-Anfragen (`No 'Access-Control-Allow-Origin' header`).
|
||||
- **Lösung**:
|
||||
- CORS-Handshaking wurde direkt in den Caddy-Reverse-Proxy (`Caddyfile` der Web-App) verlagert.
|
||||
- OPTIONS-Requests werden nun sofort vom Proxy mit `204 No Content` und den korrekten CORS-Headern beantwortet.
|
||||
- Damit wird sichergestellt, dass der Browser die Header erhält, noch bevor die Anfrage das Backend erreicht.
|
||||
- **Status**: Versionsmarker auf v2026-04-23.21 aktualisiert.
|
||||
|
||||
### v2026-04-23.22 - CADDY DEFER CORS FIX
|
||||
- **Analyse**: Die CORS-Blockade hielt an (v21). Die Fehlermeldung "No 'Access-Control-Allow-Origin' header" blieb bestehen.
|
||||
- **Lösung**:
|
||||
- Im `Caddyfile` wurde das `defer`-Flag für die Header-Direktive hinzugefügt. Dies stellt sicher, dass Caddy die CORS-Header erst ganz am Ende der Response-Verarbeitung setzt und sie nicht von anderen Direktiven (wie `reverse_proxy`) überschrieben werden können.
|
||||
- Radikale Vereinfachung des CORS-Blocks im Caddyfile für maximale Zuverlässigkeit bei Preflight-Anfragen.
|
||||
- **Status**: Versionsmarker auf v2026-04-23.22 aktualisiert.
|
||||
|
||||
|
||||
### v2026-04-23.23 - CADDY CORS OPTIONS FIX
|
||||
- **Problem**: CORS Preflight (OPTIONS) wurde blockiert, vermutlich weil 'defer' Header verzögerte oder 'Access-Control-Allow-Headers' nicht spezifisch genug war.
|
||||
- **Lösung**: Caddyfile umgebaut. OPTIONS-Requests werden nun in einem eigenen Handle mit expliziten Headern (inkl. Content-Type) beantwortet, ohne 'defer'.
|
||||
- **Status**: Versionsmarker auf v2026-04-23.23 aktualisiert.
|
||||
|
||||
### v2026-04-23.24 - CADDY CORS FINAL BOSS
|
||||
- **Problem**: CORS Preflight (OPTIONS) weiterhin blockiert (v23). Die Fehlermeldung deutete darauf hin, dass die Header immer noch nicht zuverlässig beim Browser ankommen.
|
||||
- **Lösung**:
|
||||
- `Caddyfile` radikal gehärtet: `OPTIONS` Requests werden nun mit `X-Caddy-CORS: preflight` markiert und erhalten eine leere Response (`respond "" 204`).
|
||||
- Hinzufügen von `X-Requested-With` zu den erlaubten Headern (oft von KMP/Ktor-Clients verwendet).
|
||||
- Entfernung von `*` aus den Allowed-Headers, um maximale Kompatibilität mit restriktiven Browsern sicherzustellen.
|
||||
- **Status**: Versionsmarker auf v2026-04-23.24 aktualisiert.
|
||||
|
||||
### v2026-04-23.27 - SAME-ORIGIN PROXY (THE "NO-CORS" STRATEGY)
|
||||
- **Problem**: Trotz 26 Versuchen, CORS via Headers (Caddy/Spring) zu lösen, blockierten Browser/Proxies weiterhin die Preflight-Anfragen (OPTIONS).
|
||||
- **Lösung (Radikalschlag)**:
|
||||
- **Frontend (`PlatformConfig.wasmJs.kt`)**: API-URLs auf relativ (`/api`) umgestellt.
|
||||
- **Caddy Proxy (`Caddyfile`)**: Alle Anfragen an `/api/*` werden intern an `mail-service` weitergeleitet.
|
||||
- **Status**: Versionsmarker v27.
|
||||
|
||||
### v2026-04-23.28 - SAME-ORIGIN v2
|
||||
- **Caddy-Routing**: Korrektur des Proxy-Routings (kein `strip_prefix`), um die Backend-Endpunkte exakt zu treffen.
|
||||
- **Relative Pfade**: API-URL im Frontend auf "" gesetzt, was zusammen mit `/api/...` CORS-Prüfungen eliminiert.
|
||||
- **Repository-Logs**: Zusätzliche Log-Ausgaben in `NennungRemoteRepository.kt` zur URL-Verifizierung.
|
||||
|
||||
### v2026-04-23.29 - BACKEND DEBUG & SUCCESS FLOW
|
||||
- **Backend-Logging**: Detaillierte Log-Ausgaben im `MailController` hinzugefügt, um den SMTP-Versandprozess auf dem Host genau verfolgen zu können (Status: "Versuche zu senden...").
|
||||
- **UI-Erfolgssteuerung**: Korrektur im Frontend-Flow. Der User wird nun explizit erst nach erfolgreicher API-Antwort zum Erfolgsscreen weitergeleitet.
|
||||
- **Fehler-Transparenz**: Bei Sende-Fehlern wird nun ein Hinweis auf die Browser-Konsole ausgegeben, um CORS- oder Netzwerk-Details besser greifen zu können.
|
||||
|
||||
### v2026-04-23.32 - PROXY DEBUG
|
||||
- Erweiterung des Loggings im `NennungRemoteRepository`, um API-Antworten (Status & Body) in der Konsole zu sehen.
|
||||
- Erhöhung der Diagnose-Transparenz im Caddy-Proxy (v32).
|
||||
- Ziel: Identifikation, warum Requests im Same-Origin Modus scheinbar still scheitern.
|
||||
|
||||
### v2026-04-23.34 - CALLBACK LOGGING
|
||||
- **Fokus**: Behebung des stillen Scheiterns (kein UI-Umschalten nach 200 OK).
|
||||
- **Änderungen**:
|
||||
- Detaillierte `println`-Logs in `WebMainScreen.kt` und `OnlineNennungFormular.kt` hinzugefügt.
|
||||
- Ziel: Feststellen, ob `onResult` korrekt feuert und ob der State-Wechsel in Compose registriert wird.
|
||||
- **Status**: Bereit für Deployment.
|
||||
|
||||
### v2026-04-23.33 - JSON RESPONSE FIX
|
||||
- **Analyse**: Version 32 zeigte, dass der Server mit `200 OK`, aber einem leeren Body antwortet. Das Frontend (KMP/Wasm) wartete jedoch auf eine JSON-Antwort, was zum "Hängen" im Ladezustand führte.
|
||||
- **Backend-Fix**: `MailController.kt` gibt nun explizit ein JSON-Objekt `{"success": true, ...}` zurück.
|
||||
- **Frontend-Härtung**: `NennungRemoteRepository.kt` wurde robuster gegenüber leeren Antwort-Bodies gestaltet.
|
||||
- **Status**: Erfolgreich (Antwort 200 OK mit Body bestätigt).
|
||||
|
||||
|
||||
## v2026-04-23.35 - SMTP Fix
|
||||
- Korrektur der `dc-planb.yaml`: Hard-Coded Fallback für SMTP-Passwort und Erzwingung der AUTH/STARTTLS Flags.
|
||||
- Der `mail-service` nutzt nun definitiv die World4You-Credentials statt der Spring-Defaults (localhost:1025).
|
||||
- Finaler Versions-Marker v35 gesetzt.
|
||||
|
||||
### v2026-04-23.39 - FINAL SMTP & UI SYNC
|
||||
- **Analyse**: Trotz v35-38 zeigten die Logs weiterhin `localhost` als SMTP-Host (Raw Env), was auf eine persistente Fehlkonfiguration am Host hindeutete.
|
||||
- **Backend-Härtung**:
|
||||
- `application.yaml`: SMTP-Werte auf Platzhalter `${SPRING_MAIL_HOST:smtp.world4you.com}` umgestellt, um Umgebungsvariablen zu priorisieren.
|
||||
- `dc-planb.yaml`: Hinzufügen von `SPRING_MAIL_PROPERTIES_MAIL_SMTP_STARTTLS_REQUIRED: "true"`.
|
||||
- `MailServiceApplication.kt`: Erweiterte Startup-Logs für Resolved vs. Raw Env Variablen.
|
||||
- **Frontend-Härtung**:
|
||||
- `WebMainScreen.kt`: Implementierung einer "Force Success" Logik. Sobald der API-Status `200 OK` (`result.isSuccess`) ist, wird der Erfolgsscreen angezeigt, unabhängig vom internen `success`-Flag im Payload.
|
||||
- **Status**: Versions-Marker auf v39 aktualisiert.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user