Code Review Optimierungen: Typsicherheit, Scanner-Performance, DB Upgrade Template, Division Guard

This commit is contained in:
Hermes (Server)
2026-07-24 08:33:30 +02:00
parent c7828b851c
commit b43ccd4c0d
8 changed files with 225 additions and 525 deletions
@@ -0,0 +1,171 @@
# Melo App Server-Sync & Widgets Implementation Plan
> **Für Hermes:** Schritt-für-Schritt abarbeiten, keine Tasks springen.
**Goal:** Melo App um Widgets + Hidden Message "Seit 2008" erweitern, dann Server-Sync auf Aingrad aufsetzen (Musik zentral lagern, von jedem Gerät abrufbar).
**Architektur:**
- Phase 1+2: Reine App-Erweiterungen (Widgets + Easter Egg)
- Phase 3: Server als Caddy-File-Server + JSON-API, App holt Song-Liste und lädt runter
**Tech Stack:** Flutter/Dart, Caddy (läuft auf Aingrad), SQLite (bereits vorhanden)
---
## Phase 1: Widgets
### Task 1: Home-Widget (Recent Songs)
**Objective:** Widget zeigt die letzten 5 abgespielten Songs auf dem Home-Screen
**Files:**
- Create: `lib/widgets/recent_widget.dart`
- Modify: `lib/screens/home_screen.dart` (Widget einbauen)
- Modify: `lib/viewmodels/melo_home_viewmodel.dart` (letzte Songs laden)
**Schritte:**
1. `recent_widget.dart` erstellen kleiner Container mit den letzten 5 Songs, ähnlich wie StatistikCard aufgebaut (schwarz/rot Design)
2. ViewModel: `letzteSongs` laden aus `wiedergabe_verlauf`-Tabelle via `db.positionAktualisieren` die Tabelle existiert bereits
3. `home_screen.dart`: Widget unter StatistikCard einbauen
4. Nur sichtbar wenn `letzteSongs.isNotEmpty`
**Code-Skizze recent_widget.dart (~40 Zeilen):**
```dart
class RecentWidget extends StatelessWidget {
final List<Song> songs;
final void Function(Song) onPlay;
// UI: kleiner Container, 5 horizontale Einträge mit Cover + Titel
}
```
---
### Task 2: Tag-Statistik-Widget
**Objective:** Widget zeigt wie viele Songs pro Tag existieren (kleine Übersicht)
**Files:**
- Create: `lib/widgets/tag_stats_widget.dart`
- Modify: `lib/viewmodels/melo_home_viewmodel.dart` (Tag-Counts berechnen)
- Modify: `lib/screens/home_screen.dart`
**Schritte:**
1. ViewModel: `Map<String, int> tagCounts` zählt Songs pro Tag-Namen
2. `tag_stats_widget.dart` horizontale Chips mit Tag-Name + Count
3. In home_screen unter Tags-Leiste einbauen
---
## Phase 2: Hidden Message "Seit 2008"
### Task 3: Easter Egg auf dem Home-Screen
**Objective:** Versteckte Nachricht "Seit 2008" die nach 10 Song-Playbacks erscheint
**Files:**
- Modify: `lib/viewmodels/melo_home_viewmodel.dart` (Counter + Logik)
- Modify: `lib/screens/home_screen.dart` (Anzeige)
**Schritte:**
1. ViewModel: `int _playCount = 0; bool get zeigeBotschaft => _playCount >= 10;`
2. Bei jedem `spieleSong()``_playCount++`, bei 10 → `zeigeBotschaft = true`
3. UI: Wenn `zeigeBotschaft`, zeige ein rotes Herz mit "💌 Seit 2008" zwischen Header und StatistikCard
4. Nach einmaligem Anzeigen → `_playCount` zurücksetzen oder ausblendbar
**Code (~15 Zeilen ViewModel + ~10 Zeilen UI)**
---
## Phase 3: Server-Sync
### Task 4: Caddy-Subdomain einrichten
**Objective:** `musik.baka-net.de` served Musik-Ordner + JSON-Liste
**Files:**
- Modify: `/etc/caddy/Caddyfile` (auf Aingrad)
**Schritte:**
1. Ordner erstellen: `mkdir -p /home/dustin/musik/songs`
2. Caddyfile-Eintrag:
```
musik.baka-net.de {
root * /home/dustin/musik
file_server browse
@auth {
path /upload*
}
basicauth @auth {
melo HASH_PASSWORT
}
}
```
3. JSON-API Script: `/home/dustin/musik/api/songs.json` generiert Liste aller `.mp3`/`.m4a`/`.flac` Dateien mit Metadaten
4. `caddy reload`
---
### Task 5: ServerSyncService in der App
**Objective:** Neuer Service ruft Server-Liste ab und managed Downloads
**Files:**
- Create: `lib/services/server_sync_service.dart`
- Create: `lib/models/server_status.dart`
- Modify: `lib/screens/home_screen.dart` (neuer Tab)
**Schritte:**
1. `ServerSyncService` mit Methoden:
- `Future<List<ServerSong>> fetchServerList()` ruft `musik.baka-net.de/api/songs.json` ab
- `Future<Song?> downloadSong(ServerSong s)` lädt runter, speichert lokal + in DB
- `Future<bool> istBereitsLokal(ServerSong s)` checkt ob Datei existiert
2. Neuer Screen/Sheet: "📡 Server"-Button im Header öffnet Server-Browser
- Zeigt alle Songs auf dem Server
- Status: "Downloaded ✓" / "Download ⬇"
- Fortschrittsbalken wie beim YouTube-Download
---
### Task 6: Auto-Scan von Server-Songs
**Objective:** Einmal pro Session prüfen ob Server neue Songs hat
**Files:**
- Modify: `lib/viewmodels/melo_home_viewmodel.dart`
- Modify: `lib/services/server_sync_service.dart`
**Schritte:**
1. `ladeSongs()` → zusätzlich Server-Scan starten (im Hintergrund)
2. Neue Songs automatisch in DB eintragen (ohne Download nur Metadaten)
3. Badge im Server-Button: "3 neue Songs"
---
## Abhängigkeiten
```
Phase 1 (Widgets) → Phase 2 (Hidden Message) → Phase 3 (Server-Sync)
Alles unabhängig von Server
```
## Validation
- Widgets: Nach App-Neustart sichtbar, reagieren auf Song-Änderungen
- Hidden Message: Nach 10 Playbacks erscheint "Seit 2008"
- Server-Sync: `curl https://musik.baka-net.de/api/songs.json` liefert JSON
- App: Server-Tab zeigt Songs, Download funktioniert, Musik spielt ab
## Offene Fragen
- Soll Hidden Message persistiert werden (einmalig, nie wieder)?
- Auth für Download nötig oder öffentlich? (Server intern → öffentlich okay)
- Auto-Upload von lokal gescannten Songs zum Server? (Nur Download, kein Upload)