Start scripts (PS1 + Shell), Dockerfile, E2E sync tests, and README documentation for Phase 2 LAN server deployment. New files: - start-server.ps1 / start-server.sh: one-command server startup with auto-build, LAN-IP detection, and configurable API key - Dockerfile: multi-stage build (Gradle → JRE Alpine) for container deployment with volume mount for persistent data - .dockerignore: excludes app/, .git, build artifacts from Docker context - EndToEndSyncTest.kt: 7 E2E tests covering full push/pull sync cycle, multi-client overwrite, empty DB pull, multiple round-trips, and auth rejection for unauthenticated requests - README.md: project overview, build instructions, and complete Phase 2 server setup docs (4 start options, LAN setup, API reference, security) Changed files: - AndroidManifest.xml: added usesCleartextTraffic=true for HTTP in LAN Closes #46
143 lines
4.2 KiB
Markdown
143 lines
4.2 KiB
Markdown
# Krisenvorrat
|
||
|
||
Android-App zur Verwaltung eines Krisenvorrats-Inventars mit lokaler Datenhaltung und Sync-Möglichkeit über einen LAN-Server.
|
||
|
||
## Projektstruktur
|
||
|
||
| Modul | Beschreibung |
|
||
|----------|-------------------------------------------------|
|
||
| `app` | Android-App (Kotlin, Jetpack Compose, Room) |
|
||
| `server` | Ktor REST-Server (H2-Datenbank, Fat-JAR) |
|
||
| `shared` | Gemeinsame DTOs (kotlinx.serialization) |
|
||
|
||
## Voraussetzungen
|
||
|
||
- **Android Studio** oder IntelliJ IDEA
|
||
- **JDK 21** (für Server) / JDK 11+ (für App)
|
||
- **Android SDK** (API Level 35)
|
||
|
||
## App bauen
|
||
|
||
```powershell
|
||
# Windows
|
||
.\gradlew assembleDebug
|
||
|
||
# Linux/Mac
|
||
./gradlew assembleDebug
|
||
```
|
||
|
||
## Tests ausführen
|
||
|
||
```bash
|
||
# Alle Tests (App + Server)
|
||
./gradlew test
|
||
|
||
# Nur Server-Tests
|
||
./gradlew :server:test
|
||
|
||
# Nur App-Tests
|
||
./gradlew :app:test
|
||
```
|
||
|
||
---
|
||
|
||
## Phase 2: Server-Setup (LAN-Sync)
|
||
|
||
### Übersicht
|
||
|
||
Der Sync-Server empfängt das Inventar der App als JSON und gibt es an andere App-Instanzen im selben LAN weiter. Die Kommunikation läuft über einfaches HTTP mit API-Key-Authentifizierung.
|
||
|
||
```
|
||
┌──────────┐ PUT /api/inventory ┌──────────┐
|
||
│ App A │ ───────────────────────► │ Server │
|
||
│ (Upload) │ │ :8080 │
|
||
└──────────┘ └────┬─────┘
|
||
│
|
||
┌──────────┐ GET /api/inventory ┌────┴─────┐
|
||
│ App B │ ◄─────────────────────── │ Server │
|
||
│(Download)│ │ :8080 │
|
||
└──────────┘ └──────────┘
|
||
```
|
||
|
||
### Schnellstart
|
||
|
||
#### Option A: Direkt starten (empfohlen für Entwicklung)
|
||
|
||
```powershell
|
||
# Windows
|
||
.\start-server.ps1
|
||
|
||
# Linux/Mac
|
||
chmod +x start-server.sh
|
||
./start-server.sh
|
||
```
|
||
|
||
Das Skript baut automatisch das Fat-JAR und zeigt die LAN-IP an.
|
||
|
||
#### Option B: Manuell mit Gradle
|
||
|
||
```bash
|
||
./gradlew :server:run
|
||
```
|
||
|
||
#### Option C: Fat-JAR
|
||
|
||
```bash
|
||
# JAR bauen
|
||
./gradlew :server:buildFatJar
|
||
|
||
# Starten
|
||
java -jar server/build/libs/server.jar
|
||
```
|
||
|
||
#### Option D: Docker
|
||
|
||
```bash
|
||
# Image bauen
|
||
docker build -t krisenvorrat-server .
|
||
|
||
# Container starten
|
||
docker run -d \
|
||
--name krisenvorrat \
|
||
-p 8080:8080 \
|
||
-e KRISENVORRAT_API_KEY="mein-sicherer-api-key" \
|
||
-v krisenvorrat-data:/app/data \
|
||
krisenvorrat-server
|
||
```
|
||
|
||
### LAN-Setup
|
||
|
||
1. **Server-IP ermitteln:**
|
||
- Windows: `ipconfig` → IPv4-Adresse des WLAN/LAN-Adapters
|
||
- Linux/Mac: `ip addr` oder `ifconfig`
|
||
- Die Start-Skripte zeigen die IP automatisch an
|
||
|
||
2. **Firewall-Regel:** Port **8080** (TCP eingehend) muss freigeschaltet sein:
|
||
- Windows: `netsh advfirewall firewall add rule name="Krisenvorrat" dir=in action=allow protocol=TCP localport=8080`
|
||
- Linux: `sudo ufw allow 8080/tcp`
|
||
|
||
3. **App konfigurieren:**
|
||
- Einstellungen → Server-URL: `http://<SERVER-IP>:8080`
|
||
- Einstellungen → API-Key: den gleichen Key wie beim Server-Start
|
||
|
||
### API-Endpunkte
|
||
|
||
| Methode | Pfad | Auth | Beschreibung |
|
||
|---------|-------------------|-----------|------------------------------------|
|
||
| GET | `/api/health` | – | Health-Check, gibt "OK" zurück |
|
||
| GET | `/api/inventory` | API-Key | Inventar vom Server laden (Pull) |
|
||
| PUT | `/api/inventory` | API-Key | Inventar auf Server speichern (Push)|
|
||
|
||
**Authentifizierung:** API-Key als `X-API-Key`-Header oder `Bearer`-Token.
|
||
|
||
### Umgebungsvariablen
|
||
|
||
| Variable | Standard | Beschreibung |
|
||
|-----------------------|-------------------------------------------------|-------------------|
|
||
| `KRISENVORRAT_API_KEY` | `change-me-to-a-secure-key-at-least-32-chars` | API-Key für Auth |
|
||
|
||
### Sicherheitshinweise
|
||
|
||
- Der Dev-Server nutzt **HTTP** (kein HTTPS) – nur im vertrauenswürdigen LAN verwenden.
|
||
- Für Produktionseinsatz: HTTPS mit Reverse-Proxy (z.B. nginx/Caddy) konfigurieren.
|
||
- API-Key sollte mindestens 32 Zeichen lang sein.
|