chore: VPS-Pfad in Skills von /opt/bollwerk auf /opt/krisenvorrat korrigiert

This commit is contained in:
Jens Reinemann 2026-05-17 18:51:21 +02:00
parent 66a5a7d7a5
commit 1485c0ba9c
5 changed files with 71 additions and 282 deletions

View file

@ -163,216 +163,4 @@ Korrektur: <wie es sein sollte>
- **Sachlich, nicht persönlich**: Kritisiere Code, nicht den Autor.
- **Konkret**: Jede Beanstandung nennt die betroffene Datei und den betroffenen Bereich.
- **Konstruktiv**: Zu jeder Beanstandung gibt es eine klare Korrekturempfehlung.
- **Verhältnismäßig**: Unterscheide klar zwischen blockierenden Problemen und optionalen Verbesserungen.
---
name: Swift Code Reviewer
description: Verifiziert die Änderungen des Swift Implementer Agenten als erfahrener Senior-Entwickler. Prüft Vollständigkeit, Korrektheit, Coding Standards, Codedopplung und Vereinfachungspotenzial. Gibt einen strukturierten Review-Bericht zurück der Swift Implementer wertet ihn aus und entscheidet über Korrekturen. Nutze diesen Agenten immer nach einem Implementierungsschritt des Swift Implementers.
tools: ["read/readFile", "edit", "create", "search", "run_in_terminal", "agent"]
model: claude-opus-4-6
---
Du bist ein erfahrener Senior iOS-Entwickler mit hohen Qualitätsansprüchen. Du prüfst die Arbeit des Swift Implementer Agenten mit dem Blick eines Code-Reviewers: sachlich, präzise und konstruktiv. Dein Ziel ist es, sicherzustellen, dass jeder implementierte Schritt vollständig, korrekt und wartbar ist bevor der nächste Schritt beginnt.
Du schreibst keinen Code selbst. Du analysierst, bewertest und formulierst klare Korrekturaufgaben.
---
## Vorgehensweise
Arbeite strikt in dieser Reihenfolge.
### Phase 1 Kontext laden
1. **Migrationsschritt lesen**: Lies die originale Schritt-Beschreibung aus dem Migrationsplan vollständig:
- Ziel des Schritts
- Scope / enthaltene Aufgaben (Soll-Zustand)
- Ausgeschlossene Aufgaben
- Testkriterien (Typ, Assertions, Akzeptanzkriterien)
2. **Geänderte Dateien ermitteln**: Identifiziere alle Dateien, die der Implementierer angelegt oder verändert hat. Nutze dazu `git diff` oder das vom Implementierer hinterlassene Ergebnisprotokoll.
3. **Gesamten relevanten Code lesen**: Lies nicht nur die geänderten Stellen, sondern auch den umgebenden Code vorhandene Basisklassen, Protokolle, ähnliche Implementierungen im Projekt. Nur so erkennst du Dopplung und Stilbrüche.
### Phase 2 Vollständigkeitsprüfung
Gleiche den implementierten Scope mit dem Soll-Zustand aus dem Migrationsplan ab:
- Ist jede im Scope gelistete Aufgabe implementiert?
- Sind alle im Migrationsplan vorgeschriebenen Tests vorhanden (nicht nur lauffähig existent)?
- Decken die Tests die geforderten Assertions und Akzeptanzkriterien ab?
- Gibt es Dateien, die laut Plan hätten angelegt werden sollen, aber fehlen?
Erstelle eine Checkliste:
```
### Vollständigkeit
- [x] <Aufgabe aus dem Scope> vorhanden
- [ ] <Aufgabe aus dem Scope> FEHLT
- [x] Unit Tests für <X> vorhanden
- [ ] XCUITest für <Y> FEHLT
```
### Phase 3 Korrektheitsprüfung
Prüfe für jede geänderte/neue Datei:
**Logik & Verhalten**
- Stimmt die Implementierung mit der fachlichen Anforderung überein?
- Gibt es offensichtliche Logikfehler, Off-by-One-Fehler, falsche Bedingungen?
- Werden Fehlerfälle korrekt behandelt (kein „Happy Path only")?
- Werden alle relevanten Edge Cases abgedeckt?
**Swift Concurrency**
- Wird `@MainActor` korrekt eingesetzt (kein UI-Update von einem Background-Thread)?
- Sind `async/await`-Ketten vollständig und ohne unbehandelte Fehler (`try await` mit `do/catch` oder `throws`)?
- Gibt es potenzielle Data Races (shared mutable state ohne `Actor`-Schutz)?
**Speicherverwaltung**
- Gibt es Retain Cycles in Closures (fehlende `[weak self]`)?
- Werden `AnyCancellable`-Subscriptions korrekt gehalten?
**API-Korrektheit**
- Werden Apple-APIs korrekt verwendet (keine deprecated APIs ohne Begründung)?
- Werden SwiftUI State-Management-Konzepte korrekt eingesetzt (`@State`, `@StateObject`, `@ObservedObject`, `@EnvironmentObject` am richtigen Ort)?
### Phase 4 Coding Standards
Prüfe die Einhaltung der Projektstandards (siehe Swift Implementer Coding Standards):
**Benennung**
- Typen in `UpperCamelCase`, Funktionen/Variablen in `lowerCamelCase`?
- Boolean-Eigenschaften mit `is`, `has`, `can`, `should`, `will` präfixiert?
- Namen am Verwendungsort klar lesbar (kein kryptisches Abkürzen)?
**Struktur & Zugriffsmodifikatoren**
- Zugriffsmodifikatoren so restriktiv wie möglich (`private` > `internal` > `public`)?
- Kein unnötiges `public` ohne klaren Grund?
- Trennung von Concerns eingehalten (View kennt keine Logik, ViewModel kennt keine UI-Typen)?
**Verbotene Patterns**
- Keine Force-Unwraps (`!`) in Produktionscode?
- Keine `print()`-Statements (stattdessen Projekt-Logger)?
- Keine ungenutzten Imports oder Symbole?
- Keine auskommentierten Code-Blöcke?
**Dokumentation**
- Alle öffentlichen und internen Typen, Protokolle und Methoden mit `///` dokumentiert?
- Kommentare beschreiben „was" und „warum", nicht „wie"?
- Komplexe Stellen mit `// MARK:` oder erklärendem Kommentar versehen?
**Tests**
- Testmethoden nach Schema `test_<WasGetestetWird>_<Vorbedingung>_<ErwartetesErgebnis>()`?
- `// Given`, `// When`, `// Assert`-Gliederung vorhanden?
- Keine Testlogik in `setUp`/`tearDown`, die nicht für alle Tests des Typs gilt?
### Phase 5 Codedopplung
Suche aktiv nach Duplikaten:
- Gibt es Logik, die an mehreren Stellen identisch oder fast identisch implementiert ist?
- Gibt es neue Typen/Extensions, die bestehende Funktionalität duplizieren?
- Gibt es Hilfsfunktionen, die projektübergreifend nützlich wären, aber lokal vergraben sind?
Für jeden Fund: Beschreibe genau, welche Stellen betroffen sind und wie die Duplikation aufzulösen wäre (z. B. in eine gemeinsame Extension oder einen Service auslagern).
### Phase 6 Vereinfachungspotenzial
Prüfe, ob Code ohne Funktionsänderung vereinfacht werden kann:
- Übermäßig verschachtelte `if`/`guard`-Ketten, die als `switch` lesbarer wären?
- Explizite Schleifen, die durch `map`, `filter`, `reduce`, `compactMap` ersetzbar sind?
- Boilerplate, das durch ein bereits vorhandenes Protokoll oder eine Extension eliminiert werden kann?
- `ViewModel`-Code, der in das Modell gehört (zu viel Logik in der falschen Schicht)?
- Unnötige `@Published`-Eigenschaften, die durch `Computed Properties` ersetzt werden könnten?
Weise nur auf Vereinfachungen hin, die die Lesbarkeit oder Wartbarkeit verbessern. Keine Mikrooptimierungen ohne Mehrwert.
### Phase 7 Bewertung und Ausgabe
Fasse alle Befunde in einem strukturierten Review-Bericht zusammen:
```
# Code Review: Schritt N <Titel>
## Gesamtbewertung
✅ Abgenommen / ⚠️ Kleinere Korrekturen erforderlich / ❌ Wesentliche Mängel Korrektur notwendig
## Vollständigkeit
<Checkliste aus Phase 2>
## Korrektheitsprobleme
### [KRITISCH] <Kurztitel>
Datei: `<Pfad>`
Problem: <Beschreibung>
Erwartetes Verhalten: <Beschreibung>
### [WARNUNG] <Kurztitel>
## Coding-Standard-Verletzungen
### [<Schwere>] <Kurztitel>
Datei: `<Pfad>`, Zeile/Bereich: <Angabe>
Verstoß: <Beschreibung>
Korrektur: <wie es sein sollte>
## Codedopplung
### <Kurztitel>
Betroffene Stellen: `<Pfad1>`, `<Pfad2>`
Beschreibung: <was doppelt ist>
Empfehlung: <wie aufzulösen>
## Vereinfachungspotenzial
### <Kurztitel>
Datei: `<Pfad>`
Ist-Zustand: <kurze Beschreibung oder Code-Snippet>
Empfehlung: <wie vereinfachen>
## Korrekturaufgaben für den Swift Implementer
<Nur wenn Gesamtbewertung oder >
### Aufgabe 1 <Titel> [KRITISCH / WICHTIG / OPTIONAL]
**Datei(en):** `<Pfad>`
**Problem:** <knappe Beschreibung>
**Erwartetes Ergebnis:** <was nach der Korrektur der Fall sein soll>
**Akzeptanzkriterium:** <wie der Reviewer erkennt, dass es behoben ist>
### Aufgabe 2
```
#### Schweregrade
| Schwere | Bedeutung |
| ------------ | --------------------------------------------------------------------------------------------------- |
| **KRITISCH** | Falsches Verhalten, Crash-Potenzial, Sicherheitslücke, fehlende Pflicht-Tests muss behoben werden |
| **WICHTIG** | Standard-Verletzung, Codedopplung, schlechte Lesbarkeit sollte behoben werden |
| **OPTIONAL** | Vereinfachung ohne funktionalen Einfluss kann behoben werden |
#### Gesamtbewertung
- **✅ Abgenommen**: Keine KRITISCHEN oder WICHTIGEN Mängel. Der nächste Implementierungsschritt kann beginnen.
- **⚠️ Kleinere Korrekturen**: Nur WICHTIGE oder OPTIONALE Mängel. Korrektur vor dem nächsten Schritt empfohlen, aber nicht blockierend.
- **❌ Wesentliche Mängel**: Mindestens ein KRITISCHER Mangel. Der Swift Implementer muss korrigieren, bevor der nächste Schritt beginnt.
---
## Kommunikationsprinzipien
- **Sachlich, nicht persönlich**: Kritisiere Code, nicht den Autor. „Diese Funktion verletzt das Single-Responsibility-Prinzip" statt „Du hast das falsch gemacht."
- **Konkret**: Jede Beanstandung nennt die betroffene Datei und den betroffenen Bereich. Keine vagen Aussagen wie „der Code könnte besser sein."
- **Konstruktiv**: Zu jeder Beanstandung gibt es eine klare Korrekturempfehlung.
- **Verhältnismäßig**: Unterscheide klar zwischen blockierenden Problemen und optionalen Verbesserungen. Kein Perfektionismus, der den Fortschritt blockiert.
---
### Phase 8 Bericht zurückgeben
Gib den vollständigen Review-Bericht aus Phase 7 als dein **finales Ergebnis** zurück. Starte keine weiteren Agenten. Der **Swift Implementer** wertet den Bericht aus und entscheidet eigenständig über interne Korrekturen und den weiteren Ablauf.
- **Verhältnismäßig**: Unterscheide klar zwischen blockierenden Problemen und optionalen Verbesserungen.

View file

@ -17,7 +17,6 @@ Jedes Issue MUSS genau **eines** dieser Type-Labels tragen:
| ---------------- | ------ | ------------------------------------------------------------------------------ |
| `block-planning` | [B] | Grobplanung zerlegt Projekt in Blocks, erstellt [T]- und [P]-Tickets |
| `feature` | [F] | Feature-Entwicklung Neuentwicklung ohne Referenz-Altcode |
| `migration` | [M] | C# → Swift Migrationsschritt (Portierung von bestehendem Code) |
| `refactoring` | [F] | Architektur-Refactoring wird wie Feature behandelt (workflow-implementation) |
| `tech-decision` | [T] | Technologie-Entscheidung (User trifft die Wahl) |
| `infrastructure` | [I] | Infrastruktur, Prozess, Tooling, Dokumentation |

View file

@ -17,13 +17,13 @@ Dieser Skill deckt den vollständigen Workflow ab, um eine neue App-Version auf
```
App (lokal) VPS (bollwerk.online)
───────────── ─────────────────────
app/build.gradle.kts /opt/bollwerk/
app/build.gradle.kts /opt/krisenvorrat/
versionCode / versionName ├── docker-compose.yml (BOLLWERK_APP_VERSION_CODE/NAME)
├── data/app-latest.apk (statisch ausgeliefert)
./gradlew assembleDebug └── Server-Container (Ktor)
→ app-debug.apk ├── GET / → Homepage mit QR-Code
├── GET /api/version → JSON {versionCode, versionName, apkUrl}
scp → /opt/bollwerk/data/ └── GET /static/* → Dateien aus data/
scp → /opt/krisenvorrat/data/ └── GET /static/* → Dateien aus data/
```
### Wie die Update-Prüfung funktioniert
@ -44,6 +44,7 @@ scp → /opt/bollwerk/data/ └── GET /static/* → Dateien au
### Schritt 1 Version bumpen
In `app/build.gradle.kts`:
- `versionCode` um 1 erhöhen
- `versionName` passend anpassen (z.B. "1.2" → "1.3")
@ -58,7 +59,7 @@ Die APK liegt danach unter: `app/build/outputs/apk/debug/app-debug.apk`
### Schritt 3 APK auf VPS hochladen
```powershell
scp app/build/outputs/apk/debug/app-debug.apk root@195.246.231.210:/opt/bollwerk/data/app-latest.apk
scp app/build/outputs/apk/debug/app-debug.apk root@195.246.231.210:/opt/krisenvorrat/data/app-latest.apk
```
**Voraussetzung:** SSH-Agent muss laufen und Key geladen sein (siehe vps-deploy Skill).
@ -69,19 +70,19 @@ Die Version wird über Environment-Variablen in der `docker-compose.yml` auf dem
```powershell
# Neue Werte per sed in docker-compose.yml eintragen
ssh root@195.246.231.210 "cd /opt/bollwerk && sed -i 's/BOLLWERK_APP_VERSION_CODE=.*/BOLLWERK_APP_VERSION_CODE=<neuer_code>/' docker-compose.yml && sed -i 's/BOLLWERK_APP_VERSION_NAME=.*/BOLLWERK_APP_VERSION_NAME=<neuer_name>/' docker-compose.yml"
ssh root@195.246.231.210 "cd /opt/krisenvorrat && sed -i 's/BOLLWERK_APP_VERSION_CODE=.*/BOLLWERK_APP_VERSION_CODE=<neuer_code>/' docker-compose.yml && sed -i 's/BOLLWERK_APP_VERSION_NAME=.*/BOLLWERK_APP_VERSION_NAME=<neuer_name>/' docker-compose.yml"
```
Falls die Env-Vars noch nicht in der docker-compose.yml stehen, müssen sie einmalig hinzugefügt werden:
```powershell
ssh root@195.246.231.210 "cd /opt/bollwerk && sed -i '/BOLLWERK_JWT_SECRET/a\ - BOLLWERK_APP_VERSION_CODE=<code>\n - BOLLWERK_APP_VERSION_NAME=<name>' docker-compose.yml"
ssh root@195.246.231.210 "cd /opt/krisenvorrat && sed -i '/BOLLWERK_JWT_SECRET/a\ - BOLLWERK_APP_VERSION_CODE=<code>\n - BOLLWERK_APP_VERSION_NAME=<name>' docker-compose.yml"
```
### Schritt 5 Server neustarten
```powershell
ssh root@195.246.231.210 "cd /opt/bollwerk && docker compose up -d"
ssh root@195.246.231.210 "cd /opt/krisenvorrat && docker compose up -d"
```
### Schritt 6 Verifizieren
@ -95,6 +96,7 @@ Invoke-WebRequest -Uri "https://bollwerk.online/" -UseBasicParsing | Select-Obje
```
Erwartete Ausgabe von `/api/version`:
```json
{"versionCode":<neuer_code>,"versionName":"<neuer_name>","apkUrl":"https://bollwerk.online/static/app-latest.apk"}
```
@ -111,25 +113,25 @@ Das Skript `publish-apk.ps1` in diesem Skill-Ordner automatisiert Schritte 36
**Parameter:**
| Parameter | Pflicht | Beschreibung |
| -------------- | ------- | --------------------------------------------- |
| `-VersionCode` | ja | Neuer versionCode (Integer) |
| `-VersionName` | ja | Neuer versionName (String, z.B. "1.3") |
| `-ApkPath` | nein | Pfad zur APK (Default: debug-APK) |
| `-SkipVerify` | nein | Verifizierung überspringen |
| Parameter | Pflicht | Beschreibung |
| -------------- | ------- | -------------------------------------- |
| `-VersionCode` | ja | Neuer versionCode (Integer) |
| `-VersionName` | ja | Neuer versionName (String, z.B. "1.3") |
| `-ApkPath` | nein | Pfad zur APK (Default: debug-APK) |
| `-SkipVerify` | nein | Verifizierung überspringen |
---
## Wichtige Dateien
| Datei | Beschreibung |
|-------|-------------|
| `app/build.gradle.kts` (L18-19) | `versionCode` / `versionName` |
| `server/src/main/resources/application.conf` (L18-21) | Server-Version-Defaults + Env-Var-Override |
| `server/src/main/kotlin/.../routes/VersionRoutes.kt` | Homepage + `/api/version` Endpoint |
| `server/src/main/kotlin/.../plugins/Routing.kt` | `staticFiles("/static", File("data"))` |
| `app/src/main/java/.../usecase/CheckForUpdateUseCase.kt` | Update-Prüfung in der App |
| `app/src/main/java/.../ui/update/UpdateViewModel.kt` | Update-UI + Download-Logik |
| Datei | Beschreibung |
| -------------------------------------------------------- | ------------------------------------------ |
| `app/build.gradle.kts` (L18-19) | `versionCode` / `versionName` |
| `server/src/main/resources/application.conf` (L18-21) | Server-Version-Defaults + Env-Var-Override |
| `server/src/main/kotlin/.../routes/VersionRoutes.kt` | Homepage + `/api/version` Endpoint |
| `server/src/main/kotlin/.../plugins/Routing.kt` | `staticFiles("/static", File("data"))` |
| `app/src/main/java/.../usecase/CheckForUpdateUseCase.kt` | Update-Prüfung in der App |
| `app/src/main/java/.../ui/update/UpdateViewModel.kt` | Update-UI + Download-Logik |
---

View file

@ -11,19 +11,19 @@ Deployt den Bollwerk Ktor-Server auf den 1984 Hosting VPS in Island.
## VPS-Infrastruktur
| Eigenschaft | Wert |
| --------------- | ------------------------------------------------- |
| Anbieter | 1984 Hosting (1984.is), Reykjavik, Island |
| VPS-Name | vpshoxc2sc |
| IP | `195.246.231.210` |
| DNS PTR | vps-195-246-231-210.1984.is |
| OS | Debian 12 (Bookworm) |
| RAM | 1024 MB |
| CPU | 1 |
| Disk | 25 GB SSD |
| Transfer | 1 TB/Monat |
| Docker | Docker CE 29.x + docker-compose-plugin |
| App-Verzeichnis | `/opt/bollwerk/` |
| Eigenschaft | Wert |
| --------------- | ----------------------------------------- |
| Anbieter | 1984 Hosting (1984.is), Reykjavik, Island |
| VPS-Name | vpshoxc2sc |
| IP | `195.246.231.210` |
| DNS PTR | vps-195-246-231-210.1984.is |
| OS | Debian 12 (Bookworm) |
| RAM | 1024 MB |
| CPU | 1 |
| Disk | 25 GB SSD |
| Transfer | 1 TB/Monat |
| Docker | Docker CE 29.x + docker-compose-plugin |
| App-Verzeichnis | `/opt/krisenvorrat/` |
---
@ -53,13 +53,13 @@ ssh-add -l
### SSH-Key-Details
| Eigenschaft | Wert |
| ----------- | ------------------------------------------------------------- |
| Typ | Ed25519 (256 Bit) |
| Fingerprint | `SHA256:J/qjVt9r8CqnoshZFQWutau+3KG7JxDzRLHPyX41+gA` |
| Private Key | `C:\Users\JensR\.ssh\id_ed25519` (passphrase-geschützt) |
| Public Key | `C:\Users\JensR\.ssh\id_ed25519.pub` |
| Kommentar | `bollwerk-vps` |
| Eigenschaft | Wert |
| ----------- | ------------------------------------------------------- |
| Typ | Ed25519 (256 Bit) |
| Fingerprint | `SHA256:J/qjVt9r8CqnoshZFQWutau+3KG7JxDzRLHPyX41+gA` |
| Private Key | `C:\Users\JensR\.ssh\id_ed25519` (passphrase-geschützt) |
| Public Key | `C:\Users\JensR\.ssh\id_ed25519.pub` |
| Kommentar | `bollwerk-vps` |
---
@ -73,23 +73,23 @@ cd x:\bollwerk
.\gradlew.bat :server:buildFatJar
# 2. JAR auf VPS kopieren
scp x:\bollwerk\server\build\libs\server.jar root@195.246.231.210:/opt/bollwerk/server.jar
scp x:\bollwerk\server\build\libs\server.jar root@195.246.231.210:/opt/krisenvorrat/server.jar
# 3. Container neu bauen und starten
ssh root@195.246.231.210 "cd /opt/bollwerk && docker compose up -d --build"
ssh root@195.246.231.210 "cd /opt/krisenvorrat && docker compose up -d --build"
```
### Nur Container neustarten (ohne neues JAR)
```powershell
ssh root@195.246.231.210 "cd /opt/bollwerk && docker compose restart"
ssh root@195.246.231.210 "cd /opt/krisenvorrat && docker compose restart"
```
---
## Docker-Konfiguration auf dem VPS
### Dockerfile (`/opt/bollwerk/Dockerfile`)
### Dockerfile (`/opt/krisenvorrat/Dockerfile`)
```dockerfile
FROM eclipse-temurin:21-jre-alpine
@ -101,7 +101,7 @@ ENTRYPOINT ["java", "-Xmx384m", "-jar", "server.jar"]
**Hinweis:** `-Xmx384m` begrenzt den JVM-Heap, weil der VPS nur 1 GB RAM hat.
### docker-compose.yml (`/opt/bollwerk/docker-compose.yml`)
### docker-compose.yml (`/opt/krisenvorrat/docker-compose.yml`)
```yaml
services:
@ -110,7 +110,7 @@ services:
container_name: bollwerk-server
restart: unless-stopped
ports:
- '8080:8080'
- "8080:8080"
environment:
- BOLLWERK_JWT_SECRET=<secret>
volumes:
@ -134,28 +134,28 @@ Der Server nutzt JWT-basierte Authentifizierung (kein API-Key mehr).
### Environment-Variablen
| Variable | Pflicht | Beschreibung |
| ------------------------------- | ------- | --------------------------------------------------- |
| `BOLLWERK_JWT_SECRET` | ja | Secret für JWT-Token-Signierung (mind. 32 Zeichen) |
| `BOLLWERK_ADMIN_PASSWORD` | nein | Admin-Passwort beim ersten Start (sonst auto-gen.) |
| Variable | Pflicht | Beschreibung |
| ------------------------- | ------- | -------------------------------------------------- |
| `BOLLWERK_JWT_SECRET` | ja | Secret für JWT-Token-Signierung (mind. 32 Zeichen) |
| `BOLLWERK_ADMIN_PASSWORD` | nein | Admin-Passwort beim ersten Start (sonst auto-gen.) |
---
## Server-Endpunkte
| Endpunkt | Auth | Beschreibung |
| ------------------------------ | ----- | ------------------------------------- |
| `GET /api/health` | nein | Health-Check → "OK" |
| `POST /api/auth/login` | nein | Login → JWT (Access + Refresh Token) |
| `POST /api/auth/refresh` | nein | Access-Token erneuern |
| `GET /api/inventory` | JWT | Inventar des Users abrufen |
| `PUT /api/inventory` | JWT | Inventar des Users hochladen |
| `PATCH /api/inventory/items/{id}` | JWT | Einzelnen Artikel updaten |
| `GET /api/admin/users` | Admin | Alle User auflisten |
| `POST /api/admin/users` | Admin | Neuen User anlegen |
| `PUT /api/admin/users/{id}` | Admin | Passwort ändern |
| `DELETE /api/admin/users/{id}` | Admin | User löschen |
| `WS /ws/sync` | JWT | WebSocket für Push-Benachrichtigungen |
| Endpunkt | Auth | Beschreibung |
| --------------------------------- | ----- | ------------------------------------- |
| `GET /api/health` | nein | Health-Check → "OK" |
| `POST /api/auth/login` | nein | Login → JWT (Access + Refresh Token) |
| `POST /api/auth/refresh` | nein | Access-Token erneuern |
| `GET /api/inventory` | JWT | Inventar des Users abrufen |
| `PUT /api/inventory` | JWT | Inventar des Users hochladen |
| `PATCH /api/inventory/items/{id}` | JWT | Einzelnen Artikel updaten |
| `GET /api/admin/users` | Admin | Alle User auflisten |
| `POST /api/admin/users` | Admin | Neuen User anlegen |
| `PUT /api/admin/users/{id}` | Admin | Passwort ändern |
| `DELETE /api/admin/users/{id}` | Admin | User löschen |
| `WS /ws/sync` | JWT | WebSocket für Push-Benachrichtigungen |
JWT wird als `Authorization: Bearer <accessToken>` Header mitgeschickt.
@ -192,9 +192,9 @@ ssh root@195.246.231.210 "curl -s http://localhost:8080/api/health"
### Container stoppen/starten
```powershell
ssh root@195.246.231.210 "cd /opt/bollwerk && docker compose stop"
ssh root@195.246.231.210 "cd /opt/bollwerk && docker compose start"
ssh root@195.246.231.210 "cd /opt/bollwerk && docker compose down" # Container entfernen
ssh root@195.246.231.210 "cd /opt/krisenvorrat && docker compose stop"
ssh root@195.246.231.210 "cd /opt/krisenvorrat && docker compose start"
ssh root@195.246.231.210 "cd /opt/krisenvorrat && docker compose down" # Container entfernen
```
### RAM-Nutzung prüfen
@ -205,7 +205,7 @@ ssh root@195.246.231.210 "free -h && echo '---' && docker stats --no-stream"
### Daten-Persistenz
Die SQLite-Datenbank wird unter `/opt/bollwerk/data/` auf dem Host gemountet und überlebt Container-Neustarts.
Die SQLite-Datenbank wird unter `/opt/krisenvorrat/data/` auf dem Host gemountet und überlebt Container-Neustarts.
---
@ -214,5 +214,5 @@ Die SQLite-Datenbank wird unter `/opt/bollwerk/data/` auf dem Host gemountet und
- **1 GB RAM:** JVM-Heap auf 384 MB begrenzt. Kein Spielraum für weitere Dienste.
- **Kein HTTPS:** Server läuft aktuell nur auf HTTP Port 8080. Für HTTPS → Caddy als Reverse Proxy einrichten.
- **Kein CI/CD:** Deployment ist manuell (JAR bauen → scp → docker compose up). Ggf. GitHub Actions Pipeline ergänzen.
- **Dockerfile lokal:** Das Dockerfile auf dem VPS (`/opt/bollwerk/Dockerfile`) ist ein schlankes Runtime-Only-Image. Das Multi-Stage-Dockerfile im Repo-Root ist für lokale Builds gedacht.
- **Dockerfile lokal:** Das Dockerfile auf dem VPS (`/opt/krisenvorrat/Dockerfile`) ist ein schlankes Runtime-Only-Image. Das Multi-Stage-Dockerfile im Repo-Root ist für lokale Builds gedacht.
- **SSH-Escape-Problem:** Beim Schreiben von Dateien via SSH-Heredoc werden JSON-Quotes zerstört. Dateien immer lokal erstellen und per `scp` hochladen.