12 KiB
Programmier-Plan
Stand: 28. Juli 2026
Repo: git.webklar.com/knso/videogen · Backend: Appwrite appwrite.webklar.com/v1, Projekt 6a5cee34002bb8360c34, DB brandloop
Grundlage: app-aufbau.md (Screens) · konzept-bilder-feed.md (Konzept) · datenbank-aufbau.md (Schema)
1. Ausgangslage – was schon da ist
| Stand | |
|---|---|
| Appwrite-Schema | 15 Tabellen, Indizes, 4 Buckets, Team internal – angelegt durch scripts/setup-appwrite.mjs, idempotent |
| Prompts | P1–P18 als 22 Zeilen geseedet (P8 = Kern + 4 Adapter) via scripts/seed-prompts.mjs, versioniert |
| Regeln | 4 globale Brand-Regeln in rules |
| Prototyp | prototyp-app.html, 21 Screens, Handy-Ansicht, vollständig ohne Backend |
| App-Code | existiert noch nicht – es gibt einen Expo-QR-Code, aber keine Anwendung |
Der entscheidende Punkt: Das Schema im Repo bildet den Stand vor dem Bild-/Feed-Konzept ab. Es fehlen alle Tabellen des neuen Produktteils. Wer jetzt anfängt, UI zu bauen, baut gegen Tabellen, die es nicht gibt.
2. Schema-Delta – was konkret fehlt
Abgeglichen gegen scripts/setup-appwrite.mjs.
2.1 Neue Tabellen (6)
| Tabelle | Zweck |
|---|---|
folders |
Wissens-Scope: brand_id, name, theme_md, zweck, startwert_modus, ist_default, post_count, signal_count |
attribute_scores |
Score je Attribut je Ordner – Herzstück |
posts |
Slot-Rezept, slot_summary, sichtbarkeit, feed_score |
post_images |
Bilderkette, typ = motiv | text_overlay |
post_folders |
m:n Post ↔ Ordner, ist_fremd, quelle |
post_metrics |
Views, Likes, Kopien, Social-Reichweite |
2.2 Neue Tabelle wegen des Folgen-Konzepts (1)
| Tabelle | Zweck |
|---|---|
follows |
follower_brand_id, followed_brand_id, unique auf beide, Index in beide Richtungen |
2.3 Änderungen an bestehenden Tabellen
| Tabelle | Änderung | Art |
|---|---|---|
brands |
+ nische, + plan, + anzeigename, + avatar_file_id, + follower_count, + ist_oeffentlich |
Spalten ergänzen |
attributes |
− score, k_factor, start_value, used_count, wins, losses, last_used_at → wandern nach attribute_scores; Index idx_topn entfällt hier |
Umbau |
categories |
+ folder_id |
Spalte + Index |
assets |
+ nische, + typ_tags[], + feed_score, + feed_score_updated_at, + ist_teilbar; typ-Enum um kulisse |
Spalten + Enum-Änderung |
score_events |
+ folder_id, + post_id; event_type-Enum um feed_import, post_reichweite |
Spalten + Enum-Änderung |
scenes |
+ folder_id |
Spalte |
jobs |
typ-Enum um slot_analyse, ordner_vorschlag, werbetext |
Enum-Änderung |
prompt_templates |
key-Enum P18 → P22 (P_KEYS im Skript: length: 18 → 22) |
Enum-Änderung |
2.4 Neuer Bucket
generated-images – öffentlich lesbar, sobald der zugehörige Post veröffentlicht ist.
2.5 Neue Functions (4)
ordner-initialisieren · feed-score-berechnen (Cron) · feed-import · social-reichweite-holen (Cron)
Dazu die aus dem alten Plan noch offenen: elo-update, favorit-berechnen, ads-metriken-holen, kategorie-durchschnitt, archivierung, job-dispatcher.
2.6 Zwei Fallen bei der Migration
Enum-Änderungen sind kein Anhängen. Vier Spalten brauchen neue Enum-Werte (assets.typ, score_events.event_type, jobs.typ, prompt_templates.key). Appwrite behandelt das als Spaltenänderung, nicht als Ergänzung – je nach Version bedeutet das Löschen und Neuanlegen der Spalte, also Datenverlust. Das ist der Grund, warum diese Änderung jetzt passieren muss, solange die Tabellen leer sind. In sechs Wochen mit echten Daten ist es ein Migrationsprojekt.
Die attributes-Auftrennung ist ein Umbau, kein Zusatz. Sieben Spalten verschwinden aus einer Tabelle und tauchen in einer neuen wieder auf, mit einer zusätzlichen Dimension. Solange keine Brand existiert, ist das eine Textänderung im Setup-Skript. Danach ist es eine Datenwanderung mit Ausfallzeit.
Deshalb ist „Fundament zuerst" nicht nur die aufgeräumte, sondern die einzig günstige Reihenfolge.
3. Etappen
Jede Etappe hat ein Abnahmekriterium – etwas, das man vorführen kann. Ohne das ist nicht entscheidbar, ob sie fertig ist.
E0 · Schema nachziehen
Inhalt: setup-appwrite.mjs um die 7 neuen Tabellen, die geänderten Spalten, die Enum-Erweiterungen und den Bucket ergänzen. attributes auftrennen. P_KEYS auf 22. Skript einmal komplett gegen eine leere Datenbank laufen lassen.
Abnahme: Skript läuft zweimal hintereinander fehlerfrei durch (idempotent), 22 Tabellen und 5 Buckets stehen in der Appwrite-Konsole.
Aufwand: klein. Reine Skriptarbeit, kein UI.
E1 · Projektgerüst Expo
Inhalt: Expo-Projekt anlegen, TypeScript, Navigation (Tabs + Stacks), Appwrite-SDK verdrahten, Theme aus dem Prototyp übernehmen (Farben, Typo, Glas-Effekte – ohne die Fake-Tastatur und ohne die Shader-Spielerei per setInterval).
Abnahme: App startet auf Handy und im Browser, drei Tabs sind klickbar, jeder Tab zeigt einen leeren Screen mit seinem Namen.
Aufwand: mittel. Hier entscheidet sich die Ordnerstruktur des Codes – sorgfältig sein.
E2 · Auth und Mandant
Inhalt: Registrieren, Anmelden, Abmelden. Bei der Registrierung: Appwrite-Team anlegen, brands-Zeile anlegen, Zeilenrechte setzen. Session-Persistenz.
Abnahme: Zwei Konten anlegen; Konto B sieht keine Daten von Konto A – geprüft über die API, nicht über das UI.
Aufwand: mittel. Die Rechte-Prüfung ist der eigentliche Inhalt, nicht die Formulare.
Das ist die Etappe, bei der man am ehesten schludert und es am teuersten wird. Die Mandantentrennung ist das Fundament des Rechte-Modells aus
datenbank-aufbau.md§5.
E3 · Onboarding
Inhalt: Die vier Onboarding-Screens mit echten Feldern, inklusive Nische. Uploads in den Bucket uploads. P2 als erster echter LLM-Aufruf über jobs.
Abnahme: Nach dem Onboarding stehen in brands sechs ausgefüllte Felder und in attribute_scores die ersten Attribute auf der brand-weiten Ebene (folder_id = null).
Aufwand: mittel.
E4 · Modelle
Inhalt: Modell anlegen (Person, Produkt, Kulisse), echte Referenzbild-Uploads, Versionierung mit Release-Prinzip, Modelle-Übersicht im Profil.
Abnahme: Ein Produkt-Modell mit 4 Referenzbildern anlegen, freigeben, in der Übersicht sehen. assets.released_version_id zeigt auf die richtige Version.
Aufwand: mittel. Ohne Modelle kann nichts generiert werden – deshalb vor der Generierung.
E5 · Ordner
Inhalt: Ordner-Liste, Anlegen mit den zwei Schaltern, Ordner-Detail, aktiver Ordner als App-Zustand. Function ordner-initialisieren.
Abnahme: Zwei Ordner anlegen – einen mit erben, einen mit aus_posts. In attribute_scores stehen danach unterschiedliche Startwerte mit korrekt gesetzter start_quelle.
Aufwand: mittel. Fachlich der anspruchsvollste Teil bis hierher.
E6 · Post erstellen (erste echte Generierung)
Inhalt: Create-Screen mit Ordner, Format, Kette, Slots. jobs + job-dispatcher + Realtime-Wartezustand. P7 auf das Slot-System umbauen. P22 als Bild-Tagger. Post-Ergebnis mit privat/veröffentlichen.
Abnahme: Ein Prompt erzeugt eine dreiteilige Bilderkette, die im Entwürfe-Screen auftaucht, auch wenn man die App zwischendurch schließt.
Aufwand: groß. Hier hängt die Auswahl des Bildmodells dran – offener Punkt 1.
E7 · Feed
Inhalt: Veröffentlichen mit Zeilen-Permission, Feed-Deck mit den drei Reitern, Post-Detail, post_metrics schreiben, Function feed-score-berechnen mit Decay und Explorations-Slot.
Abnahme: Ein veröffentlichter Post von Konto A erscheint im Feed von Konto B. prompt_sent ist über die API von Konto B nicht abrufbar.
Aufwand: groß.
E8 · Kopieren
Inhalt: P19 (Slot-Analyst), Kopier-Screen mit Chips und Kompatibilitätsprüfung, P21 (Werbetext), Function feed-import, copied_from_post_id, Kopien-Zähler.
Abnahme: Konto B kopiert den Post von Konto A, ersetzt beide Modelle, generiert – und in der Knowledge Base von Konto B stehen danach neue Attribute mit start_quelle = feed_import im gewählten Ordner.
Aufwand: groß. Das ist der Moment, in dem das Produkt das tut, was es verspricht.
E9 · Folgen
Inhalt: follows, Fremdprofil, Folgen-Button, Reiter „Folge ich" chronologisch, Blockieren und Melden.
Abnahme: Konto B folgt Konto A und sieht dessen neuen Post im Reiter „Folge ich", vor allem anderen.
Aufwand: mittel.
E10 · Video-Strecke
Inhalt: Die bestehende Video-Strecke aus dem Prototyp echt machen: scenes, P3/P4/P5/P8, videos, Vote, elo-update, gezielte Frage.
Abnahme: Ein Prompt erzeugt vier Videos von vier KI-Modellen; nach dem Vote haben sich Scores in attribute_scores messbar verändert und score_events hat die passenden Zeilen.
Aufwand: sehr groß, und mit laufenden Kosten ab dem ersten Test.
4. Reihenfolge und Abhängigkeiten
E0 Schema
└─ E1 Gerüst
└─ E2 Auth ──────────────┐
├─ E3 Onboarding │
├─ E4 Modelle ───────┤
└─ E5 Ordner ────────┤
└─ E6 Post erstellen
├─ E7 Feed
│ ├─ E8 Kopieren
│ └─ E9 Folgen
└─ E10 Video
E3, E4 und E5 sind untereinander unabhängig – sie können in beliebiger Reihenfolge oder parallel entstehen. Alles ab E6 hängt an allen dreien.
E10 (Video) steht bewusst hinten, obwohl es das Kernprodukt ist: Es ist die teuerste Strecke in der Umsetzung und im Betrieb, und der Bild-Strang erzeugt vorher die Daten, mit denen sich der Video-Teil überhaupt sinnvoll testen lässt.
5. Was im ersten Durchgang bewusst wegbleibt
| Weggelassen | Warum |
|---|---|
| Desktop-Ansicht | Handy zuerst; der Handoff im Repo ist laut dir noch nicht gültig |
| Stripe / Abrechnung | Preismodell ist offen (offener Punkt 3) – ohne Entscheidung nicht baubar |
| Meta-/TikTok-Ads-Anbindung | App-Reviews dauern; Antrag trotzdem jetzt stellen, unabhängig vom Code |
| Social-Reichweite (echte Instagram-Zahlen) | eigene App-Review; bis dahin läuft der Feed-Score nur auf In-App-Signalen |
| P12–P18, P20 | nachrüstbar, ohne sie funktioniert der Loop |
| Verbessern-Strecke | vorhanden im Prototyp, aber nicht auf dem kritischen Pfad |
| Developer-Modus | intern, kein Nutzerwert – erst wenn es echte Prompts zu debuggen gibt |
6. Risiken
| Risiko | Wirkung | Gegenmaßnahme |
|---|---|---|
| Enum-Migration nach dem Livegang | Datenverlust in vier Spalten | E0 vor allem anderen, solange die DB leer ist |
| Multi-Referenz-Komposition (Person + Produkt + Kulisse konsistent in einem Bild) | Der Kern des Bild-Modus funktioniert nicht wie gedacht | Vor E6 mit zwei, drei Kandidatenmodellen einen Wegwerf-Test fahren – bevor UI dafür gebaut wird |
| Generierungskosten im Test | schleichende Kosten ohne Gegenwert | jobs.cost_usd ab E6 mitschreiben und ein hartes Tageslimit einbauen |
| Leerer Feed | E7 ist nicht bewertbar, E8 nicht testbar | Vor E7 mit dem eigenen Konto 15–20 Posts erzeugen |
| Prototyp als Vorlage überschätzt | Screens werden 1:1 übernommen inklusive der Attrappen | app-aufbau.md §6 ist die verbindliche Liste, nicht die HTML-Datei |
| Öffentlich/privat nur im UI durchgesetzt | fremde Knowledge Bases werden über die API auslesbar | Abnahme von E7 ausdrücklich über die API prüfen, nicht über den Bildschirm |
7. Was vor E0 zu entscheiden ist
- Nischen-Liste und
typ_tags-Liste – beide sind Enums und wandern in E0 ins Schema. Später zu ändern heißt: dieselbe Migrationsfalle wie oben. - Bildmodell – blockiert nicht E0, aber E6. Der Test dafür sollte parallel zu E1–E5 laufen.
- Mindestalter und Moderationsweg – blockiert nicht den Code, aber E7 im Livebetrieb.