# 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 Von–Bis** 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://: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