Files
videogen/README.md

67 lines
3.2 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.
# BrandLoop (videogen)
KI-Video-Generierung mit lernender Brand-Knowledge-Base (Elo-Scoring über Attribute).
- **Prototyp:** [prototyp-app.html](prototyp-app.html) statische Preview unter `videogen.project.webklar.com`
- **Backend:** selbst gehostetes Appwrite (`https://appwrite.webklar.com/v1`), Projekt **BrandLoop** `6a5cee34002bb8360c34`, Datenbank `brandloop`
## Datenbank-Setup
Das komplette Schema (15 Tabellen, Indizes, 4 Storage-Buckets, internes Dev-Team) legt
[scripts/setup-appwrite.mjs](scripts/setup-appwrite.mjs) an idempotent, kann nach
Plan-Erweiterungen jederzeit erneut laufen:
```bash
# API-Key liegt als BRANDLOOP_APPWRITE_API_KEY in /home/webklar/apps/.env, dann einfach:
node scripts/setup-appwrite.mjs
# oder explizit:
APPWRITE_API_KEY=... node scripts/setup-appwrite.mjs
```
Der API-Key braucht die Scopes **Databases/Tables (read+write), Storage/Buckets (read+write), Teams (read+write)**.
## Prompt-Templates (P1P18)
Alle 18 Prompts des Prompt-Inventars liegen versioniert in [prompts/](prompts/) (Konventionen
und Slot-Registry: [prompts/README.md](prompts/README.md)) und werden mit
[scripts/seed-prompts.mjs](scripts/seed-prompts.mjs) in die Tabelle `prompt_templates`
geseedet — idempotent: Inhaltsänderung ⇒ neue Zeile `version+1`, alte Zeilen `aktiv=false`.
P8 ist eine Familie (1× Regie-Kern + 4 Modell-Adapter seedance/veo/sora/wan) = 22 Zeilen.
Das Skript seedet außerdem die 4 globalen Brand-Regeln in `rules`.
```bash
node scripts/seed-prompts.mjs
```
### Bewusste Abweichungen vom DB-Plan
- **Referenzen als indizierte String-Spalten (size 64) statt Relationship-Spalten.**
Appwrite-Relationships sind nicht filter-/indizierbar der Top-N-Index auf
`attributes` (`brand_id, category_id, status, score DESC`) und alle Listen-Queries
brauchen aber genau das. Many-to-many (`videos.attribute_ids`) ist ein String-Array
(`Query.contains`). IDs mit 64 Zeichen, weil uuid4 = 36 Zeichen.
- **`created_at`-Spalten entfallen** Appwrite pflegt `$createdAt` automatisch
(Indizes nutzen `$createdAt` direkt, z. B. `score_events`, `jobs`).
- **Enum-Werte ohne Umlaute** (`laeuft` statt `läuft`).
- **`attributes.tags`: Key-Index statt Volltext-Index** Appwrite verbietet
Fulltext auf Array-Spalten; Tag-Suche läuft über `Query.contains`.
- **S3/Hetzner-Backend für Storage** ist eine *instanzweite* Appwrite-Einstellung
(`_APP_STORAGE_DEVICE`) und betrifft alle Projekte auf dem Server wird daher
nicht vom Skript gesetzt, sondern muss bewusst am Server konfiguriert werden.
Aktuell: lokales Storage.
### Rechte-Modell
- `rules` + `prompt_templates`: Tabellen-Rechte nur für Team `internal` (Dev-Modus) 🔒
- Alle anderen Tabellen: `rowSecurity` an, keine Tabellen-Rechte Zeilen bekommen
beim Anlegen die Team-Permission der jeweiligen Brand (Multi-Tenant).
- `consents`-Bucket: zusätzlich Lese-Recht für Team `internal`.
- Append-only per Konvention (Server-Key schreibt): `score_events`, `video_metrics`, `jobs`.
### Noch offen (laut Plan)
- Appwrite **Functions**: `elo-update`, `favorit-berechnen`, `ads-metriken-holen`,
`kategorie-durchschnitt`, `archivierung`, `job-dispatcher`
- Stripe-Anbindung (metered billing über `usage_records`)