drop obsolete files

This commit is contained in:
2025-11-20 21:50:43 +01:00
parent 57b4d7d762
commit 19a3dfdd65
18 changed files with 0 additions and 2842 deletions

View File

@@ -1,171 +0,0 @@
# UI Service - Docker
FastAPI + Jinja2 + HTMX Dashboard für Home Automation
## Build
```bash
docker build -t ui:dev -f apps/ui/Dockerfile .
```
## Run
### Lokal
```bash
docker run --rm -p 8002:8002 -e API_BASE=http://localhost:8001 ui:dev
```
### Docker Compose
```yaml
services:
ui:
build:
context: .
dockerfile: apps/ui/Dockerfile
ports:
- "8002:8002"
environment:
- API_BASE=http://api:8001
depends_on:
- api
```
### Kubernetes
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: ui
spec:
replicas: 2
selector:
matchLabels:
app: ui
template:
metadata:
labels:
app: ui
spec:
containers:
- name: ui
image: ui:dev
ports:
- containerPort: 8002
env:
- name: API_BASE
value: "http://api-service:8001"
livenessProbe:
httpGet:
path: /health
port: 8002
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 8002
initialDelaySeconds: 3
periodSeconds: 5
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
name: ui-service
spec:
selector:
app: ui
ports:
- protocol: TCP
port: 8002
targetPort: 8002
type: LoadBalancer
```
## Umgebungsvariablen
| Variable | Default | Beschreibung |
|----------|---------|--------------|
| `API_BASE` | `http://api:8001` | URL des API-Services |
| `UI_PORT` | `8002` | Port der UI-Anwendung |
| `PYTHONDONTWRITEBYTECODE` | `1` | Keine .pyc Files |
| `PYTHONUNBUFFERED` | `1` | Unbuffered Output |
## Endpoints
- `GET /` - Dashboard
- `GET /health` - Health Check
- `GET /dashboard` - Dashboard (alias)
## Security
- Container läuft als **non-root** User `app` (UID: 10001)
- Minimales Python 3.11-slim Base Image
- Keine unnötigen System-Pakete
- Health Check integriert
## Features
- ✅ FastAPI Backend
- ✅ Jinja2 Templates
- ✅ HTMX für reactive UI
- ✅ Server-Sent Events (SSE)
- ✅ Responsive Design
- ✅ Docker & Kubernetes ready
- ✅ Health Check Endpoint
- ✅ Non-root Container
- ✅ Configurable API Backend
## Entwicklung
### Lokales Testing
```bash
# Build
docker build -t ui:dev -f apps/ui/Dockerfile .
# Run
docker run -d --name ui-test -p 8002:8002 -e API_BASE=http://localhost:8001 ui:dev
# Logs
docker logs -f ui-test
# Health Check
curl http://localhost:8002/health
# Cleanup
docker stop ui-test && docker rm ui-test
```
### Tests
```bash
bash /tmp/test_ui_dockerfile.sh
```
## Troubleshooting
### Container startet nicht
```bash
docker logs ui-test
```
### Health Check schlägt fehl
```bash
docker exec ui-test curl http://localhost:8002/health
```
### API_BASE nicht korrekt
```bash
docker logs ui-test 2>&1 | grep "UI using API_BASE"
```
### Non-root Verifizieren
```bash
docker exec ui-test id
# Sollte zeigen: uid=10001(app) gid=10001(app)
```

View File

@@ -1,188 +0,0 @@
/**
Copilot-Aufgabe: Erzeuge eine neue Home-Dashboard-Seite mit Raum-Kacheln.
Ziel:
Die Seite soll alle Räume als kleine Kacheln darstellen. Auf dem iPhone
sollen immer zwei Kacheln nebeneinander passen. Jede Kachel zeigt:
- Raumname
- Icon (z. B. Wohnzimmer, Küche, Bad, etc.) basierend auf room_id oder einem Mapping
- Anzahl der Geräte im Raum
- Optional: Zusammenfassung wichtiger States (z.B. Anzahl offener Fenster, aktive Lichter)
Datenquelle:
- GET /layout → { "rooms": [{ "name": "...", "devices": [...] }] }
(Achtung: rooms ist ein Array, kein Dictionary!)
- GET /devices → Geräteliste für Feature-Checks
Interaktion:
- Beim Klick/Touch auf eine Raum-Kachel → Navigation zu /room/{room_name}
Layout-Anforderungen:
- 2-Spalten-Grid auf kleinen Screens (max-width ~ 600px)
- 34 Spalten auf größeren Screens
- Kachelgröße kompakt (ca. 140px x 110px)
- Icon ~32px
- Text ~1416px
- Responsive via CSS-Grid oder Flexbox
- Minimaler Einsatz von Tailwind (bevorzugt vanilla CSS)
Akzeptanzkriterien:
- Die Seite lädt alle Räume über die API (fetch).
- Räume werden in der Reihenfolge aus layout.yaml angezeigt.
- Jede Kachel zeigt: Icon + Raumname + Geräteanzahl.
- iPhone-Darstellung verifiziert: zwei Kacheln nebeneinander.
- Funktionierende Navigation zu /room/{room_name}.
- Die Komponente ist vollständig lauffähig.
- Fehlerbehandlung bei API-Fehlern implementiert.
*/
/**
Copilot-Aufgabe: Erzeuge eine Geräte-Grid-Ansicht für einen Raum.
Ziel:
Die Seite zeigt alle Geräte, die in diesem Raum laut layout.yaml liegen.
Die Darstellung erfolgt als kompakte Kacheln, ebenfalls 2 Spalten auf iPhone.
Datenquelle:
- GET /layout → Räume + device_id + title
- GET /devices → Typ + Features
- GET /devices/{id}/state (optional zur Initialisierung)
- Live-Updates: SSE /realtime
Auf einer Gerät-Kachel sollen erscheinen:
- passendes Icon (abhängig von type)
- title (aus layout)
- wichtigste Eigenschaft aus dem State:
- light: power on/off oder brightness in %
- thermostat: current temperature
- contact: open/closed
- temp_humidity: temperature und/oder humidity
- outlet: on/off
- cover: position %
Interaktion:
- Klick/Touch → Navigation zu /device/{device_id}
Akzeptanzkriterien:
- Der Raum wird anhand room_id aus der URL geladen.
- Geräte werden über Join(layout, devices) des Raums selektiert.
- Kacheln sind 2-spaltig auf iPhone.
- State wird initial geladen und per SSE aktualisiert.
- Navigation zu /device/{id} funktioniert.
- Icons passend zum Typ generiert.
*/
/**
Copilot-Aufgabe: Erzeuge eine Detailansicht für ein einzelnes Gerät.
Ziel:
Die Seite zeigt:
- Titel des Geräts (title aus layout)
- Raumname
- Gerätetyp
- State-Werte aus GET /devices/{id}/state
- Live-Updates via SSE
- Steuer-Elemente abhängig vom type + features:
- light: toggle, brightness-slider, optional color-picker
- thermostat: target-temp-slider
- outlet: toggle
- contact: nur Anzeige
- temp_humidity: nur Anzeigen von Temperatur/Humidity
- cover: position-slider und open/close/stop Buttons
API-Integration:
- Set-Kommandos senden via POST /devices/{id}/set
- Validierung: Nur unterstützte Features sichtbar machen
UI-Vorgaben:
- Kompakt, aber komplett
- Buttons gut für Touch erreichbar
- Slider in voller Breite
- Werte (temperature, humidity, battery) übersichtlich gruppiert
Akzeptanzkriterien:
- Device wird korrekt geladen (layout + devices + state).
- Steuerung funktioniert (light on/off, brightness, target temp etc.).
- SSE aktualisiert alle angezeigten Werte live.
- Fehler (z. B. POST /set nicht erreichbar) werden UI-seitig angezeigt.
*/
/**
Copilot-Aufgabe: Erzeuge einen API-Client für das UI.
Der Client soll bereitstellen:
- getLayout(): Layout-Daten
- getDevices(): Device-Basisdaten
- getDeviceState(device_id)
- setDeviceState(device_id, type, payload)
- connectRealtime(onEvent): SSE-Listener
Anforderungen:
- API_BASE aus .env oder UI-Konfiguration
- Fehlerbehandlung
- Timeout optional
- Types für:
- Room
- Device
- DeviceState
- RealtimeEvent
Akzeptanzkriterien:
- Der Client ist voll funktionsfähig und wird im UI genutzt.
- Ein Hook useRealtime(device_id) wird erzeugt.
- Ein Hook useRooms() and useDevices() existieren.
*/
/**
Copilot-Aufgabe: Erzeuge das UI-Routing.
Routen:
- "/" → Home (Räume)
- "/room/:roomId" → RoomView
- "/device/:deviceId" → DeviceView
Anforderungen:
- React Router v6 oder v7
- Layout-Komponente optional
- Loading/Fehlerzustände
- Responsive Verhalten beibehalten
Akzeptanzkriterien:
- Navigation funktioniert zwischen allen Seiten.
- Browser-Back funktioniert erwartungsgemäß.
- Routes unterstützen Refresh ohne Fehler.
*/
/**
Copilot-Aufgabe: Implementiere einen React-Hook useRealtime(deviceId: string | null).
Ziel:
- SSE-Stream /realtime abonnieren
- Nur Events für deviceId liefern
- onMessage → setState
- automatische Reconnects
- Fehlerlogging
Akzeptanz:
- Der Hook kann in RoomView & DeviceView genutzt werden.
- Live-Updates werden korrekt gemerged.
- Disconnect/Reload funktioniert sauber.
*/
/**
Copilot-Aufgabe: Erzeuge eine Icon-Komponente.
Ziel:
Basierend auf device.type und ggf. features ein passendes SVG ausliefern:
- light → Lightbulb
- thermostat → Thermostat
- contact → Door/Window-Sensor
- temp_humidity → Thermometer+Droplet
- outlet → Power-Plug
- cover → Blinds/Rollershutter
Akzeptanz:
- Icons skalieren sauber
- funktionieren in allen Kachel-Komponenten
*/