BrandLoop (videogen)

KI-Video-Generierung mit lernender Brand-Knowledge-Base (Elo-Scoring über Attribute).

  • Prototyp: prototyp-app.html statische Preview unter videogen.project.webklar.com
  • Desktop-Ansicht: Design-Handoff für die Desktop-Adaption in design/desktop-ansicht/ (Spezifikation: README.md)
  • Backend: selbst gehostetes Appwrite (https://appwrite.webklar.com/v1), Projekt BrandLoop 6a5cee34002bb8360c34, Datenbank brandloop

App (client/)

Expo / React Native, eine Codebase für Web und nativ. Stand: Gerüst aus E1 drei Tabs, sonst leer.

npm --prefix client run web

Bildgenerierung

Die Warteschlange aus jobs arbeitet der Dispatcher ab serverseitig, weil der Anbieter-Schlüssel nicht ins Client-Bundle darf:

BILD_ANBIETER=stub node scripts/job-dispatcher.mjs

stub erzeugt Platzhalterbilder und macht die ganze Kette prüfbar, ohne Kosten. ark und openrouter sprechen die echten Modelle an beide setzen voraus, dass das jeweilige Konto freigeschaltet bzw. aufgeladen ist:

  • BytePlus Ark: Modell in der Konsole unter Model Service aktivieren
  • OpenRouter: Guthaben aufladen

Danach reicht BILD_ANBIETER=ark node scripts/job-dispatcher.mjs am Code ändert sich nichts.

Demo-Daten

Demo-Daten zum Anschauen (Marke, zwei Ordner, vier Modelle mit echten Bildern aus uploads/) legt alles als Client an, belegt damit nebenbei die Rechte, und ist idempotent:

node scripts/seed-demo.mjs

Die Mandantentrennung lässt sich jederzeit nachprüfen legt zwei echte Konten an, prüft über die API und räumt sich selbst auf:

node scripts/test-mandanten.mjs

Die Appwrite-SDKs sind exakt gepinnt (appwrite@23.0.0, react-native-appwrite@0.25.0): der Server läuft 1.8.1, neuere SDKs sprechen Response-Format 1.9.x. Beim Server-Upgrade beide zusammen anheben.

Konfiguration (Endpoint, Projekt-ID, DB-ID) steht in client/app.json unter expo.extra.appwrite. Der Appwrite-Server-Key gehört dort nicht hinein er landet sonst im Client-Bundle; er steht in der .env im Repo-Root und wird nur von scripts/ und später von Appwrite-Functions benutzt.

Datenbank-Setup

Das komplette Schema (22 Tabellen, Indizes, 5 Storage-Buckets, internes Dev-Team) legt scripts/setup-appwrite.mjs an idempotent, kann nach Plan-Erweiterungen jederzeit erneut laufen:

# 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/ (Konventionen und Slot-Registry: prompts/README.md) und werden mit 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.

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 attribute_scores (brand_id, folder_id, category_id, 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)
Description
videogen
Readme 3.7 MiB
Languages
HTML 46.8%
JavaScript 31.4%
TypeScript 20.2%
CSS 1.6%