Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a74b0bb815 | |||
| 40cf1e5d22 | |||
| ce63303b2c | |||
| e4988b4397 | |||
| 8816e8d297 |
Vendored
+41
@@ -0,0 +1,41 @@
|
|||||||
|
## 🚀 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
@@ -0,0 +1,34 @@
|
|||||||
|
## 🚀 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.
|
||||||
@@ -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
|
TODO*.md
|
||||||
NOTES*.md
|
NOTES*.md
|
||||||
.junie/
|
**/.junie/
|
||||||
|
|
||||||
# ===================================================================
|
# ===================================================================
|
||||||
# Keep essential files (override exclusions)
|
# Keep essential files (override exclusions)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ jobs:
|
|||||||
desktop-tests:
|
desktop-tests:
|
||||||
# Komplett deaktivierbar über Repo-Variable: Settings → Variables → DESKTOP_CI_ENABLED=true
|
# 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
|
# 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
|
name: Compose Desktop — Tests (headless) & Build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: Build and Publish Docker Images
|
name: Build and Publish Docker Images
|
||||||
run-name: Build & Publish by @${{ gitea.actor }}
|
run-name: Build & Publish by @${{ github.actor }}
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -117,8 +117,8 @@ jobs:
|
|||||||
images: ${{ env.REGISTRY_INTERNAL }}/${{ env.IMAGE_PREFIX }}/${{ matrix.image }}
|
images: ${{ env.REGISTRY_INTERNAL }}/${{ env.IMAGE_PREFIX }}/${{ matrix.image }}
|
||||||
tags: |
|
tags: |
|
||||||
type=ref,event=tag
|
type=ref,event=tag
|
||||||
type=raw,value=latest,enable=${{ gitea.ref == 'refs/heads/main' }}
|
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
|
||||||
type=sha,format=long,enable=${{ gitea.ref == 'refs/heads/main' }}
|
type=sha,format=long,enable=${{ github.ref == 'refs/heads/main' }}
|
||||||
|
|
||||||
- name: Build and push Docker image
|
- name: Build and push Docker image
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
@@ -132,5 +132,5 @@ jobs:
|
|||||||
provenance: false
|
provenance: false
|
||||||
sbom: false
|
sbom: false
|
||||||
build-args: |
|
build-args: |
|
||||||
BUILD_DATE=${{ gitea.event.head_commit.timestamp || 'unknown' }}
|
BUILD_DATE=${{ github.event.head_commit.timestamp || 'unknown' }}
|
||||||
VERSION=${{ gitea.sha }}
|
VERSION=${{ github.sha }}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ jobs:
|
|||||||
chmod +x install-conveyor.sh
|
chmod +x install-conveyor.sh
|
||||||
./install-conveyor.sh
|
./install-conveyor.sh
|
||||||
fi
|
fi
|
||||||
echo "$HOME/.conveyor/bin" >> $GITEA_PATH
|
echo "$HOME/.conveyor/bin" >> $GITHUB_PATH
|
||||||
|
|
||||||
- name: Windows .msi mit Conveyor bauen
|
- name: Windows .msi mit Conveyor bauen
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
no-hardcoded-versions:
|
no-hardcoded-versions:
|
||||||
# Für Plan-B-Builds überspringen: Commit-Message enthält [planb]
|
# 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
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ jobs:
|
|||||||
tag-release:
|
tag-release:
|
||||||
name: 🏷️ Git-Tag setzen
|
name: 🏷️ Git-Tag setzen
|
||||||
# Für Plan-B-Builds überspringen: Commit-Message enthält [planb]
|
# 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
|
runs-on: ubuntu-latest
|
||||||
outputs:
|
outputs:
|
||||||
version: ${{ steps.read-version.outputs.version }}
|
version: ${{ steps.read-version.outputs.version }}
|
||||||
@@ -64,7 +64,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Git-Tag erstellen & pushen
|
- 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: |
|
run: |
|
||||||
TAG="${{ steps.read-version.outputs.tag }}"
|
TAG="${{ steps.read-version.outputs.tag }}"
|
||||||
VERSION="${{ steps.read-version.outputs.version }}"
|
VERSION="${{ steps.read-version.outputs.version }}"
|
||||||
@@ -80,7 +80,7 @@ jobs:
|
|||||||
package-linux:
|
package-linux:
|
||||||
name: 📦 Linux .deb Packaging
|
name: 📦 Linux .deb Packaging
|
||||||
# Nur ausführen, wenn Desktop-CI explizit aktiviert ist UND kein Plan‑B Commit
|
# 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
|
runs-on: ubuntu-latest
|
||||||
needs: tag-release
|
needs: tag-release
|
||||||
|
|
||||||
@@ -88,11 +88,11 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup JDK 25 (Temurin)
|
- name: Setup JDK 21 (Temurin)
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: temurin
|
distribution: temurin
|
||||||
java-version: '25'
|
java-version: '21'
|
||||||
|
|
||||||
- name: Gradle cache
|
- name: Gradle cache
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
@@ -128,7 +128,7 @@ jobs:
|
|||||||
package-windows:
|
package-windows:
|
||||||
name: 📦 Windows .msi Packaging
|
name: 📦 Windows .msi Packaging
|
||||||
# Nur ausführen, wenn Desktop-CI explizit aktiviert ist UND kein Plan‑B Commit
|
# 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
|
runs-on: windows-latest
|
||||||
needs: tag-release
|
needs: tag-release
|
||||||
|
|
||||||
@@ -136,11 +136,11 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup JDK 25 (Temurin)
|
- name: Setup JDK 21 (Temurin)
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: temurin
|
distribution: temurin
|
||||||
java-version: '25'
|
java-version: '21'
|
||||||
|
|
||||||
- name: Gradle cache
|
- name: Gradle cache
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
@@ -179,11 +179,11 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Summary ausgeben
|
- name: Summary ausgeben
|
||||||
run: |
|
run: |
|
||||||
echo "## 🚀 Release ${{ needs.tag-release.outputs.version }}" >> $GITEA_STEP_SUMMARY
|
echo "## 🚀 Release ${{ needs.tag-release.outputs.version }}" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITEA_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "| Artefakt | Status |" >> $GITEA_STEP_SUMMARY
|
echo "| Artefakt | Status |" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "|----------|--------|" >> $GITEA_STEP_SUMMARY
|
echo "|----------|--------|" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "| Linux .deb | ${{ needs.package-linux.result }} |" >> $GITEA_STEP_SUMMARY
|
echo "| Linux .deb | ${{ needs.package-linux.result }} |" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "| Windows .msi | ${{ needs.package-windows.result }} |" >> $GITEA_STEP_SUMMARY
|
echo "| Windows .msi | ${{ needs.package-windows.result }} |" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "" >> $GITEA_STEP_SUMMARY
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
echo "**Git-Tag:** \`${{ needs.tag-release.outputs.tag }}\`" >> $GITEA_STEP_SUMMARY
|
echo "**Git-Tag:** \`${{ needs.tag-release.outputs.tag }}\`" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|||||||
@@ -1,7 +1,43 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
# Shim: Weiterleitung auf zentrale Guardrail in .ai/
|
# check-docs-drift.sh
|
||||||
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)"
|
# Zweck: sehr schlanke Drift-Checks gegen die neue Doku-Struktur.
|
||||||
ROOT_DIR="$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel 2>/dev/null || echo "$SCRIPT_DIR")"
|
# - Kein Guidelines-System mehr.
|
||||||
exec "$ROOT_DIR/.ai/scripts/check-docs-drift.sh" "$@"
|
# - 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
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
# Shim: Weiterleitung auf zentrale Guardrail in .ai/
|
mkdir -p build/diagrams
|
||||||
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)"
|
shopt -s nullglob
|
||||||
ROOT_DIR="$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel 2>/dev/null || echo "$SCRIPT_DIR")"
|
for f in docs/architecture/c4/*.puml; do
|
||||||
exec "$ROOT_DIR/.ai/scripts/render-plantuml.sh" "$@"
|
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
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
# Shim: Weiterleitung auf zentrale Guardrail in .ai/
|
# validate-links.sh - Link-Validierung für Projektdokumentation (`docs/**`).
|
||||||
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)"
|
# Zweck: Guardrail für die "Docs-as-Code"-Strategie.
|
||||||
ROOT_DIR="$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel 2>/dev/null || echo "$SCRIPT_DIR")"
|
|
||||||
exec "$ROOT_DIR/.ai/scripts/validate-links.sh" "$@"
|
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,7 +3,7 @@
|
|||||||
Dieses Dokument definiert die Zusammenarbeit zwischen dem User (Owner) und den spezialisierten KI-Agenten.
|
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.
|
Es dient als zentraler **System-Prompt-Erweiterung** für neue Chat-Sessions.
|
||||||
|
|
||||||
## 🚀 Strategische Ausrichtung (Reality-Reset 28.04.2026)
|
## 🚀 Strategische Ausrichtung (Reality-Reset 15.06.2026)
|
||||||
|
|
||||||
Das Projekt **"Meldestelle"** entwickelt eine ÖTO/FEI-konforme, offline-fähige Turnier-Software.
|
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.
|
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.
|
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.
|
* **🏗️ [Lead Architect]**: Hüter der **MASTER_ROADMAP**. Verantwortlich für System-Design, Build-Logik (Gradle), Modulstruktur und ADRs.
|
||||||
* [Playbook](docs/04_Agents/Playbooks/Architect.md)
|
* [Playbook](docs/05_Governance/Agents/Playbooks/Architect.md)
|
||||||
* **📜 [Rulebook Expert]**: Wächter über **ÖTO & FEI**. Validiert Business-Rules gegen das offizielle Pferdesport-Regelwerk.
|
* **📜 [Rulebook Expert]**: Wächter über **ÖTO & FEI**. Validiert Business-Rules gegen das offizielle Pferdesport-Regelwerk.
|
||||||
* [Playbook](docs/04_Agents/Playbooks/RulebookExpert.md)
|
* [Playbook](docs/05_Governance/Agents/Playbooks/RulebookExpert.md)
|
||||||
* **👷 [Backend Developer]**: Kotlin & Spring Boot Experte. Fokus auf DDD, Persistenz (Postgres) und **Delta-Sync APIs**.
|
* **👷 [Backend Developer]**: Kotlin & Spring Boot Experte. Fokus auf DDD, Persistenz (Postgres) und **Delta-Sync APIs**.
|
||||||
* [Playbook](docs/04_Agents/Playbooks/BackendDeveloper.md)
|
* [Playbook](docs/05_Governance/Agents/Playbooks/BackendDeveloper.md)
|
||||||
* **🎨 [Frontend Expert]**: KMP & Compose Desktop Spezialist. Implementiert State-Management und High-Performance UI.
|
* **🎨 [Frontend Expert]**: KMP & Compose Desktop Spezialist. Implementiert State-Management und High-Performance UI.
|
||||||
* [Playbook](docs/04_Agents/Playbooks/FrontendExpert.md)
|
* [Playbook](docs/05_Governance/Agents/Playbooks/FrontendExpert.md)
|
||||||
* **🖌️ [UI/UX Designer]**: "Toolsmith" für High-Density Enterprise-UIs. Fokus auf Tastatur-Bedienbarkeit und Effizienz.
|
* **🖌️ [UI/UX Designer]**: "Toolsmith" für High-Density Enterprise-UIs. Fokus auf Tastatur-Bedienbarkeit und Effizienz.
|
||||||
* [Playbook](docs/04_Agents/Playbooks/UIUXDesigner.md)
|
* [Playbook](docs/05_Governance/Agents/Playbooks/UIUXDesigner.md)
|
||||||
* **🐧 [DevOps Engineer]**: Infrastruktur-Automatisierung (Docker, Gitea-Actions). Fokus auf Stabilität und lokale Dev-Umgebung.
|
* **🐧 [DevOps Engineer]**: Infrastruktur-Automatisierung (Docker, Gitea-Actions). Fokus auf Stabilität und lokale Dev-Umgebung.
|
||||||
* [Playbook](docs/04_Agents/Playbooks/DevOpsEngineer.md)
|
* [Playbook](docs/05_Governance/Agents/Playbooks/DevOpsEngineer.md)
|
||||||
* **🧐 [QA Specialist]**: Test-Stratege (Shift-Left). Fokus auf Unit-, Integration- und Edge-Case-Tests (Testing Pyramid).
|
* **🧐 [QA Specialist]**: Test-Stratege (Shift-Left). Fokus auf Unit-, Integration- und Edge-Case-Tests (Testing Pyramid).
|
||||||
* [Playbook](docs/04_Agents/Playbooks/QASpecialist.md)
|
* [Playbook](docs/05_Governance/Agents/Playbooks/QASpecialist.md)
|
||||||
* **🧹 [Curator]**: Wissens-Management & Dokumentations-Check (ADR, Reference, Journal). Beendet jede Session.
|
* **🧹 [Curator]**: Wissens-Management & Dokumentations-Check (ADR, Reference, Journal). Beendet jede Session.
|
||||||
* [Playbook](docs/04_Agents/Playbooks/Curator.md)
|
* [Playbook](docs/05_Governance/Agents/Playbooks/Curator.md)
|
||||||
|
|
||||||
## 2. Der "Meldestelle"-Workflow
|
## 2. Der "Meldestelle"-Workflow
|
||||||
1. **Kontext-Check:** Lies immer zuerst die `MASTER_ROADMAP` in `docs/01_Architecture/`.
|
1. **Kontext-Check:** Lies immer zuerst die `MASTER_ROADMAP` in `docs/01_Architecture/`.
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
type: Roadmap
|
type: Roadmap
|
||||||
status: ACTIVE
|
status: ACTIVE
|
||||||
owner: Lead Architect
|
owner: Lead Architect
|
||||||
last_update: 2026-05-06
|
last_update: 2026-06-15
|
||||||
---
|
---
|
||||||
|
|
||||||
# MASTER ROADMAP: Meldestelle
|
# MASTER ROADMAP: Meldestelle
|
||||||
|
|
||||||
🏗️ **[Lead Architect]** | 30. April 2026
|
🏗️ **[Lead Architect]** | 15. Juni 2026
|
||||||
|
|
||||||
**Strategisches Ziel:**
|
**Strategisches Ziel:**
|
||||||
Entwicklung einer ÖTO-konformen, offline-fähigen Turnier-Meldestelle als Compose Desktop App (KMP).
|
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.
|
- 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.
|
- Offline-First Betrieb mit lokaler Persistenz und opportunistischer Synchronisation.
|
||||||
|
|
||||||
**Aktueller technischer Stand (30.04.2026):**
|
**Aktueller technischer Stand (15.06.2026):**
|
||||||
* **Infrastruktur:** ✅ "Zora" (MS-R1, ARM64) ist live. Gitea & Registry laufen.
|
* **Infrastruktur:** ✅ "Zora" (MS-R1, ARM64) ist live. Gitea & Registry laufen.
|
||||||
* **Networking:** ✅ Pangolin Tunnel ersetzt Cloudflare.
|
* **Networking:** ✅ Pangolin Tunnel ersetzt Cloudflare.
|
||||||
* **CI/CD:** ✅ Gitea Actions mit ARM64-Runner (VM 102) aktiv. Docker-Publish Pipeline grün.
|
* **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).
|
* **Code-Basis:** ✅ Backend (Java 25 / Spring Boot / Kotlin), Frontend (KMP/Compose Desktop).
|
||||||
* **Domain-Design:** ✅ 6 Bounded Contexts (SCS-Architektur) definiert. Ubiquitous Language erstellt.
|
* **Domain-Design:** ✅ 6 Bounded Contexts (SCS-Architektur) definiert. Ubiquitous Language erstellt.
|
||||||
* **Domain-Modelle:** ✅ `Reiter`, `DomNennung`, `DomNennungsTransfer`, `Pferd`, `Funktionaer`, `Verein`,
|
* **Domain-Modelle:** ✅ `Reiter`, `Nennung`, `NennungsTransfer`, `Pferd`, `Funktionaer`, `Verein`,
|
||||||
`DomBewerb`, `DomAbteilung`, `DomStartliste`, `DomVeranstaltung`, `DomTurnier`, `DomAusschreibung` implementiert.
|
`Bewerb`, `Abteilung`, `DomStartliste`, `Veranstaltung`, `Turnier`, `Ausschreibung` implementiert.
|
||||||
Enums ÖTO-konform.
|
Enums ÖTO-konform.
|
||||||
* **Dokumentation:** ✅ Konsolidiert. ÖTO-Regelwerk-Referenzen (Abteilungs-Schwellenwerte) dokumentiert.
|
* **Dokumentation:** 🧹 Sanierung abgeschlossen (5-Säulen-Struktur). Reality-Reset durchgeführt.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -155,15 +155,15 @@ Code-Stand.*
|
|||||||
|
|
||||||
| Dokument | Pfad |
|
| Dokument | Pfad |
|
||||||
|-------------------------------|----------------------------------------------------------------------------------------------|
|
|-------------------------------|----------------------------------------------------------------------------------------------|
|
||||||
| Ubiquitous Language | `docs/03_Domain/01_Glossary/Ubiquitous_Language.md` |
|
| Ubiquitous Language | `docs/02_Domain/01_Glossary/Ubiquitous_Language.md` |
|
||||||
| Abteilungs-Schwellenwerte | `docs/03_Domain/02_Reference/OETO_Regelwerk/Abteilungs-Trennungs-Schwellenwerte.md` |
|
| Abteilungs-Schwellenwerte | `docs/02_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` |
|
| Warn-Logik-Spezifikation | `docs/02_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` |
|
| Session Log (DDD) | `docs/05_Governance/Journal/_archive/2026-03-24_Session_Log_DDD_Ubiquitous_Language.md` |
|
||||||
| Infrastruktur | `docs/07_Infrastructure/Zora_System_Architektur.md` |
|
| Infrastruktur | `docs/04_Operations/Infrastructure/Zora_System_Architektur.md` |
|
||||||
| Deployment Guide | `docs/07_Infrastructure/Guides/Setup_Git_Deployment_Zora.md` |
|
| Deployment Guide | `docs/04_Operations/Infrastructure/Guides/Setup_Git_Deployment_Zora.md` |
|
||||||
| Backup Guide | `docs/07_Infrastructure/Guides/Setup_Backup_Zora.md` |
|
| Backup Guide | `docs/04_Operations/Infrastructure/Guides/Setup_Backup_Zora.md` |
|
||||||
| CI/CD | `.gitea/workflows/docker-publish.yaml` |
|
| CI/CD | `.gitea/workflows/docker-publish.yaml` |
|
||||||
| Agent Playbooks | `docs/04_Agents/Playbooks/` |
|
| Agent Playbooks | `docs/05_Governance/Agents/Playbooks/` |
|
||||||
| ADR-Verzeichnis | `docs/01_Architecture/adr/` |
|
| ADR-Verzeichnis | `docs/01_Architecture/adr/` |
|
||||||
| ADR-0025: Plan-USB | `docs/01_Architecture/adr/0025-plan-usb-offline-integritaet.md` |
|
| 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` |
|
| ADR-0026: Lizenzierung | `docs/01_Architecture/adr/0026-offline-lizenzierung-pay-per-event.md` |
|
||||||
|
|||||||
+6
-5
@@ -2,11 +2,12 @@
|
|||||||
type: Reference
|
type: Reference
|
||||||
status: ACTIVE
|
status: ACTIVE
|
||||||
owner: Lead Architect & ÖTO/FEI Rulebook Expert
|
owner: Lead Architect & ÖTO/FEI Rulebook Expert
|
||||||
last_update: 2026-04-05
|
last_update: 2026-06-15
|
||||||
sources:
|
sources:
|
||||||
- ÖTO 2026, Abschnitt A I, § 2 & § 3 & § 4
|
- ÖTO 2026, Abschnitt A I, § 2 & § 3 & § 4
|
||||||
- Domain Workshop 2026-03-17
|
- Domain Workshop 2026-03-17
|
||||||
- Session 2026-03-24 (Architektur-Diskussion)
|
- Session 2026-03-24 (Architektur-Diskussion)
|
||||||
|
- Sanierung 2026-06-15 (Reality-Reset)
|
||||||
---
|
---
|
||||||
|
|
||||||
# Ubiquitous Language – Offizielle Domänen-Terminologie
|
# Ubiquitous Language – Offizielle Domänen-Terminologie
|
||||||
@@ -146,7 +147,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 |
|
| **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). | – |
|
| **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 |
|
| **Sportförderbeitrag** | Gebühr, die **pro Start** anfällt (nicht pro Nennung!). Relevant bei Mehrfach-Starts. | ÖTO Gebührenordnung |
|
||||||
| **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). | – |
|
| **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). | – |
|
||||||
| **Startkarte** | Nachweis, dass die Jahresgebühr für die Lizenz bezahlt wurde. Ohne aktive Startkarte ist national kein Start möglich. | ÖTO Teilnahmeberechtigung |
|
| **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 |
|
| **Startwunsch** | Präferenz eines Reiters bezüglich seiner Position in der Startliste (vorne/hinten). | Registration Context |
|
||||||
|
|
||||||
@@ -188,7 +189,7 @@ Veranstalter (OEPS-Mitgliedsverein)
|
|||||||
| Veranstaltung, Turnier, Ausschreibung, Veranstalter | `event-management-context` |
|
| Veranstaltung, Turnier, Ausschreibung, Veranstalter | `event-management-context` |
|
||||||
| Bewerb, Abteilung, Startliste, Ergebnis, Richtverfahren | `competition-context` |
|
| Bewerb, Abteilung, Startliste, Ergebnis, Richtverfahren | `competition-context` |
|
||||||
| Nennung, Nennungs-Transfer, Startwunsch, ZNS-Import | `registration-context` |
|
| Nennung, Nennungs-Transfer, Startwunsch, ZNS-Import | `registration-context` |
|
||||||
| Reiter, Pferd, Lizenz, Funktionär, Kopfnummer, Satznummer, Verein | `actor-context` |
|
| Reiter, Pferd, Lizenz, Funktionär, Kopfnummer, Satznummer, Verein | `masterdata-context` |
|
||||||
| Nenngeld, Startgeld, Konto, Transaktion, Sportförderbeitrag | `billing-context` |
|
| Nenngeld, Startgeld, Konto, Transaktion, Sportförderbeitrag | `billing-context` |
|
||||||
| Cup, Serie, Meisterschaft, Reglement, Endklassement | `series-context` *(Phase 2+)* |
|
| Cup, Serie, Meisterschaft, Reglement, Endklassement | `series-context` *(Phase 2+)* |
|
||||||
| Login, Rolle, Berechtigung | `identity-context` |
|
| Login, Rolle, Berechtigung | `identity-context` |
|
||||||
@@ -222,7 +223,7 @@ Ein Reglement definiert typischerweise:
|
|||||||
- Verschiedene Cups/Serien können **unterschiedliche Punktesysteme** haben → das Berechnungsmodell muss pluggable sein.
|
- 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.
|
- Die **Paar-Bindung** (Punkte an Reiter+Pferd vs. nur Reiter) ist eine kritische Designentscheidung pro Reglement.
|
||||||
- Referenz-Dokument: [
|
- Referenz-Dokument: [
|
||||||
`docs/03_Domain/02_Reference/OETO_Regelwerk/Struktur-Meisterschafts-Cup-Reglements_OETO.md`](../02_Reference/OETO_Regelwerk/Struktur-Meisterschafts-Cup-Reglements_OETO.md)
|
`docs/02_Domain/02_Reference/OETO_Regelwerk/Struktur-Meisterschafts-Cup-Reglements_OETO.md`](../02_Reference/OETO_Regelwerk/Struktur-Meisterschafts-Cup-Reglements_OETO.md)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -241,4 +242,4 @@ Ein Reglement definiert typischerweise:
|
|||||||
---
|
---
|
||||||
|
|
||||||
*Erstellt: 2026-03-24 | Autoren: Lead Architect, ÖTO/FEI Rulebook Expert, Curator*
|
*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-04-05 (Verein-Renaming & Bereinigung)*
|
*Basiert auf: ÖTO 2026 § 2, § 3, § 4 | Domain Workshop 2026-03-17 | Session 2026-03-24 | Update: 2026-06-15 (Reality-Reset & Alignment)*
|
||||||
|
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 |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user