Files
Dennis Nemec 6a9b5872e1 Backend-Arbeitsstand: ERP-Sync, Lieferlebenszyklus, Reports + config.toml
Bringt das Backend vom initialen Skeleton auf den aktuellen Arbeitsstand
(Clean Architecture: domain → application → infrastructure → api).

Wesentliche Bereiche:
- ERP-Anbindung (MSSQL-Pull der Touren, Import-Scheduler, Rückschreiben)
- Lieferlebenszyklus: Scan/Hold/Cancel/Complete, Gutschriften, Notizen,
  Bild-Anhänge, Unterschriften, PDF-Lieferreport → DOCUframe
- Stammdaten: Kunden, Artikel, Lager, Zahlungsarten, Services
- Keycloak-JWT-Gate + Fahrer-Provisionierung via Admin-API
- Admin-API-Key-Gate (X-Admin-Api-Key) für Maschinen-Endpunkte

Jüngste Änderungen dieser Session:
- Belegspezifische Kontaktdaten: alle ERP-Adressen (Beleg-/Liefer-/
  Rechnungsadresse, Ansprechpartner, Kundenstamm) mit Telefon/Mobil/
  E-Mail werden gesynct (Migration 0029, MSSQL-Query, TourDetails)
- Konfiguration von .env (envy/dotenvy) auf config.toml (toml/serde)
  umgestellt; Vorlage config.example.toml, Pfad via HOLZLEITNER_CONFIG

Nicht im Repo (per .gitignore): config.toml (Secrets), data/ (Laufzeit-/
Kundendaten), demo.mp4, .claude/, variocontrol-ai/.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 17:52:58 +02:00

80 lines
3.3 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# Fährt das Backend im USB-Tunnel-Modus hoch — für App-Tests in fremden
# Netzwerken, in denen das Android-Gerät den Mac nicht über eine LAN-IP
# erreicht. Statt LAN-IP läuft alles über `adb reverse` auf localhost.
#
# Was dieses Skript macht:
# 1. Keycloak mit KC_HOSTNAME=localhost (neu)starten, damit das 'iss'-Claim
# auf http://localhost:8080/... lautet.
# 2. adb-reverse-Tunnel für API (3000) und Keycloak (8080) setzen.
# 3. Backend mit einer von config.toml abgeleiteten Temp-Config starten,
# in der nur `issuer_url` auf localhost überschrieben ist. Der Pfad
# wird per HOLZLEITNER_CONFIG injiziert; config.toml bleibt unangetastet.
#
# App-Seite (separat): mit dem passenden Flag bauen/starten:
# flutter run --dart-define=HL_BACKEND=usb
#
# Aufruf:
# ./tool/dev_usb.sh
#
# Rückkehr in den LAN-Modus:
# docker compose up -d # Keycloak wieder mit LAN-IP-Hostname
# adb reverse --remove-all # Tunnel abbauen
# cargo run # Backend mit config.toml (LAN-IP-Issuer)
set -euo pipefail
KC_HOST="${KC_HOSTNAME_OVERRIDE:-localhost}"
API_PORT="${API_PORT:-3000}"
KC_PORT="${KC_PORT:-8080}"
ISSUER="http://${KC_HOST}:${KC_PORT}/realms/holzleitner"
echo "→ USB-Tunnel-Modus (Issuer: ${ISSUER})"
# ── 1. Keycloak mit localhost-Hostname (neu)starten ──────────────────────
echo "→ Keycloak mit KC_HOSTNAME=${KC_HOST} starten …"
KC_HOSTNAME="${KC_HOST}" docker compose up -d keycloak postgres
# ── 2. adb-reverse-Tunnel ────────────────────────────────────────────────
if ! command -v adb >/dev/null 2>&1; then
echo "✗ adb nicht gefunden. Android-Platform-Tools installieren oder PATH prüfen." >&2
exit 1
fi
if [ -z "$(adb devices | sed -n '2p')" ]; then
echo "✗ Kein Gerät über adb sichtbar. USB-Kabel + USB-Debugging prüfen." >&2
exit 1
fi
echo "→ adb reverse: localhost:${API_PORT} (API) + localhost:${KC_PORT} (Keycloak)"
adb reverse "tcp:${API_PORT}" "tcp:${API_PORT}"
adb reverse "tcp:${KC_PORT}" "tcp:${KC_PORT}"
adb reverse --list
# ── 3. Backend mit localhost-Issuer starten ──────────────────────────────
# Config ist jetzt datei-basiert (config.toml). Statt einer Env-Variablen
# leiten wir eine Temp-Config ab, in der nur `issuer_url` auf localhost zeigt,
# und reichen sie per HOLZLEITNER_CONFIG rein. So bleibt die echte config.toml
# (LAN-IP-Issuer) unverändert.
BASE_CONFIG="${HOLZLEITNER_CONFIG:-config.toml}"
if [ ! -f "${BASE_CONFIG}" ]; then
echo "${BASE_CONFIG} nicht gefunden (cp config.example.toml config.toml)." >&2
exit 1
fi
TMP_CONFIG="$(mktemp -t holzleitner-usb-config.XXXXXX)"
trap 'rm -f "${TMP_CONFIG}"' EXIT
# Nur die issuer_url-Zeile ersetzen (es gibt genau eine, unter [keycloak]).
awk -v iss="${ISSUER}" '
/^[[:space:]]*issuer_url[[:space:]]*=/ { print "issuer_url = \"" iss "\""; next }
{ print }
' "${BASE_CONFIG}" > "${TMP_CONFIG}"
echo "→ Backend starten (issuer_url=${ISSUER}, Temp-Config ${TMP_CONFIG}) …"
echo " Tipp: App in einem zweiten Terminal mit"
echo " flutter run --dart-define=HL_BACKEND=usb"
echo
HOLZLEITNER_CONFIG="${TMP_CONFIG}" cargo run