Files
HousemannandClaude Sonnet 4.6 3f253ffe81 Initial commit: Filebot Media Browser
Vue 3 + FastAPI Webapp zur Anzeige von Filebot/n8n-Medienmetadaten aus PostgreSQL.
Enthält Frontend, API, Nginx-Config, SQL-Migrationen und Docker-Compose-Setup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 05:38:37 +02:00

202 lines
6.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Projekt-Kontext für KI-Assistenten (Filebot Media Browser)
Diese Datei fasst zusammen, **was gebaut wurde** und wie das Projekt betrieben wird. Bei weiteren Änderungen zuerst hier und in der `README.md` nachschlagen.
---
## Zweck
Interne Web-App im Heimnetz zum Anzeigen und Verwalten von **Filebot/n8n-Medienmetadaten** aus PostgreSQL. Schwerpunkt: **Original- vs. neuem Dateinamen** nebeneinander (Rename-Kontrolle), plus technische Metadaten (Codec, Bitrate, Auflösung, …).
**Produktiv nur auf dem Server** unter `/opt/nginx_filebot` nicht lokal auf dem Mac entwickeln/ausführen.
---
## Infrastruktur
| Komponente | Details |
|------------|---------|
| Server-Pfad | `/opt/nginx_filebot` |
| Docker Compose | Projektname `nginx_filebot` |
| Web | Nginx, Port **8080** → Container 80 |
| API | FastAPI (Python 3.12), intern `api:8000` |
| PostgreSQL | Host typisch `192.168.30.186` |
| Datenbank | `n8n_filebot` (Name in config) |
| Schema | **`n8n`** (nicht `public`!) |
| Tabelle | **`movie_files`** (nicht `n8n_filebot`!) |
| Vollqualifizierter Name | `"n8n"."movie_files"` |
Config: `config/config.yaml` (nur auf Server, nicht committen). Beispiel: `config/config.example.yaml`.
**Wichtig:** Feld `schema` in YAML funktioniert, intern heißt es `db_schema` (Pydantic-Konflikt mit `BaseModel.schema`).
---
## Tech-Stack
- **Frontend:** Vue 3, TypeScript, Vite, TanStack Table
- **Backend:** FastAPI, asyncpg
- **Webserver:** Nginx (Multi-Stage-Build: Node baut Vue, Nginx liefert aus)
- **DB:** PostgreSQL
---
## Datenbank-Spalten (relevant)
Standard-Spalten aus n8n/Filebot (siehe `api/main.py``COLUMNS`), u. a.:
- `id`, `file_name_original`, `file_name_new`
- `movie_rating`, `movie_votes`
- Video/Audio: `standard_video_format`, `video_codec_library`, `audio_codec`, `container_format`, Bitraten, Auflösung, …
- `created_at`
**Zusätzlich per Migration:**
| Spalte | Typ | Bedeutung |
|--------|-----|-----------|
| `seen_at` | `TIMESTAMPTZ NULL` | `NULL` = ungesehen; gesetzt = in UI als gesehen markiert |
| `cover_url` | `TEXT NULL` | Poster-URL (z. B. TVMaze), erste Tabellenspalte |
SQL-Dateien: `sql/001_add_seen_at.sql`, `sql/002_add_cover_url.sql`
**n8n:** Bei INSERT/UPDATE `seen_at` und `cover_url` nicht ungewollt überschreiben.
---
## UI-Funktionen (Stand Projektabschluss)
### Layout
- **Desktop:** Tabelle mit vielen Spalten; **erste Spalte Cover** (ca. 76×114 px), dann Dateinamen-Paar
- **Mobile (≤900px):** Karten mit Cover links
- **Helles Dark-Theme** (`frontend/src/styles.css`, CSS-Variablen)
### Dateinamen
- Immer **Original** und **Neu** sichtbar (`NamePair.vue`)
- Kein „Rename prüfen“-Badge mehr (Heuristik entfernt)
### Filter (`FilterBar.vue`)
- Textsuche in Original + Neu
- **Buttons** (keine Dropdowns): Format, Codec, Container
- **Datum/Uhrzeit VonBis** mit Kalender-Popup + HH:MM-Dropdowns (`DateTimeRangeFilter.vue`)
- **Gesehen:** „Nur ungesehen“, „Alle als gesehen“, Zähler „X neu“
- Aktualisieren / Zurücksetzen
### Gesehen-Status
- Ungesehene Zeilen: blauer linker Rand + Hintergrund (`row-unseen` / `card-unseen`)
- **Tippen auf Zeile** (nicht Scroll): Toggle gesehen/ungesehen via `PATCH /api/records/{id}/seen`
- Mülleimer löscht Eintrag (kein Toggle)
### Tabelle
- Sortierung Standard: `created_at` absteigend (neueste oben)
- Schnellfilter in geladenen Daten
- **Löschen:** roter Mülleimer pro Zeile → `DELETE /api/records/{id}`
### Cover
- `CoverImage.vue`: lazy load, Platzhalter bei Fehler, URL-Bereinigung (extra `"` entfernen)
---
## API-Endpunkte
| Methode | Pfad | Beschreibung |
|---------|------|--------------|
| GET | `/api/health` | DB-Ping |
| GET | `/api/status` | Diagnose (Config, Tabellenliste bei Fehler) |
| GET | `/api/columns` | Spaltenliste |
| GET | `/api/records` | Daten; Query: `search`, `format`, `codec`, `container`, `created_from`, `created_to`, `unseen_only` |
| GET | `/api/filters` | Distinct-Werte für Filter-Buttons |
| PATCH | `/api/records/{id}/seen` | Body: `{ "seen": true \| false }` |
| POST | `/api/records/mark-all-seen` | Alle gefilterten als gesehen |
| DELETE | `/api/records/{id}` | Zeile löschen |
Nginx proxied `/api/``http://api:8000/api/`.
---
## Projektstruktur
```text
/opt/nginx_filebot/
├── docker-compose.yml # absolute Pfade für Server
├── config/
│ ├── config.example.yaml
│ └── config.yaml # nur Server
├── api/
│ ├── main.py
│ ├── config.py
│ ├── Dockerfile
│ └── scripts/list-tables.py
├── frontend/
│ └── src/
│ ├── App.vue
│ ├── api.ts
│ ├── components/ # DataTable, FilterBar, CoverImage, …
│ ├── composables/ # (useSeenObserver entfernt)
│ └── utils/
├── nginx/
│ ├── Dockerfile # Multi-Stage Frontend-Build
│ └── nginx.conf
├── sql/ # DB-Migrationen
├── PROMPT.md # diese Datei
└── README.md
```
---
## Deployment (Kurz)
```bash
cd /opt/nginx_filebot
docker compose up -d --build
# Browser: http://<server-ip>:8080
```
Nach Frontend-Änderungen: `docker compose up -d --build web`
Nach API-Änderungen: `docker compose up -d --build api`
Oft: komplett `--build`
---
## Typische Fehler (bereits aufgetreten)
1. **`relation "n8n_filebot" does not exist`** → Tabelle heißt `movie_files`, DB `n8n_filebot`
2. **`schema: n8n` ignoriert** → `db_schema` / API-Fix mit `validation_alias`
3. **Leere DB-Liste** → falsche Datenbank oder leere Tabelle
4. **API 500 ohne `seen_at`/`cover_url`** → SQL-Migration ausführen
5. **Design ändert sich nicht**`web` neu bauen + Browser Hard-Reload
Diagnose:
```bash
docker compose logs api --tail 50
curl -s http://localhost:8080/api/status
docker compose exec api python /app/scripts/list-tables.py
```
---
## Konventionen für weitere Entwicklung
- Antworten an Nutzer oft **auf Deutsch**
- Keine Commits unless asked
- `config.yaml` nie ins Git
- Server-only Deployment kommunizieren
- Nach Änderungen: welche Dateien hochladen + `docker compose up -d --build`
- Minimale Diffs, bestehenden Stil beibehalten (Vue 3 Composition API, FastAPI async)
---
## Nutzer-Präferenzen (aus Session)
- Rename-Kontrolle: `file_name_original` + `file_name_new` immer sichtbar
- Filter als Buttons, nebeneinander (mobil gestapelt)
- Gesehen per **Tap**, nicht Scroll
- Cover in erster Spalte, etwas höhere Zeilen
- Etwas **helleres** UI-Theme