Ürünereklam
FertiggestelltEinen Produktlink einfügen und fertige Video- und Bildanzeigen auf Türkisch und Englisch bekommen, jede einzelne von einem Vorhersagemodell bewertet, bevor überhaupt Geld ausgegeben wird. Angefangen hat es 2026 beim BTK Akademi Hackathon.
- Meine Rolle
- Design und Entwicklung, im Alleingang
- Jahr
- 2026
- Gebaut mit
- Next.js · Inngest · Supabase · Gemini · Veo · ElevenLabs · Remotion · PyTorch on Modal · Polar
Scroll seitlich, um das ganze Diagramm zu sehen.
Das Problem
Anzeigen in zwei Sprachen, in der Menge, die Onlineshops brauchen, bedeuten meist eine Agentur gegen feste Pauschale. Selbst dann weiß niemand, welche Version funktioniert, bevor das Budget ausgegeben ist.
Wie es gebaut ist
Eine Next.js-App orchestriert Durable Jobs mit Inngest. Ein Python-Scraper liest die Produktseite, mit einem gehärteten Fetch-Pfad für schwierige Shops. Gemini schreibt Strategie, Werbetexte und Frames, Veo oder Seedance rendert das Video, ElevenLabs liefert die Stimme, und Remotion fügt wortgenau getimte Untertitel, das Wasserzeichen und den Call-to-Action hinzu. Ein separates Studio erzeugt statische Bildanzeigen und Anzeigentexte. Danach durchläuft jede Variante ein selbst gehostetes Modell, das vorhersagt, wie Menschen darauf reagieren (TRIBE v2). Es läuft auf GPUs bei Modal und wird gestartet und dann gepollt, weil ein Render länger dauert als das Timeout einer Edge Function. Supabase hält den Zustand hinter Row-Level Security, mit kurzlebigen signierten Medien-URLs. Credits liegen in einem Append-only-Ledger mit atomaren Abbuchungen und Erstattungen, und der Checkout läuft über Polar mit Preisen in Lira und Dollar.
Entscheidungen, auf die es ankam
Ein fehlgeschlagener Schritt erstattet seine Credits selbst
Die Pipeline besteht aus Durable Jobs mit einem Fehler-Handler für jeden Schritt. Ein Schritt, der abstürzt, erstattet seine Credits genau einmal und gibt den Lauf frei, statt ihn hängen zu lassen.
Medien sind standardmäßig privat
Die rohen Renderings liegen in einem privaten Bucket, das SELECT-Recht auf Spaltenebene ist entzogen, und Medienlinks sind kurzlebige signierte URLs. Keine Medienadresse lässt sich erraten, auch nicht im Free Tier.
Jede Anzeige wird bewertet, bevor jemand dafür bezahlt
Keine Anzeige verlässt das Studio ohne Bewertung. Das Modell bringt die Varianten in eine Rangfolge, bevor jemand Budget in eine davon steckt.
Code aus dem Repo
async function safeRefund(
opts: Parameters<typeof refundCredits>[0],
): Promise<void> {
try {
await refundCredits(opts);
} catch (err) {
console.error(
`[billing][RECONCILE-NEEDED] refund failed user=${opts.userId} ` +1
`amount=${opts.amount} ref=${opts.refType}:${opts.refId} ` +
`key=${opts.idempotencyKey ?? "-"}`,
err,
);
}
}
// …
await safeRefund({
supa,
userId: campaign.user_id,
amount: campaignCreditCost({
videoCount: brief.videoCount ?? 1,
videoModel: brief.videoModel ?? "seedance",
durationSec: brief.durationSec,
}),
refType: "campaign",
refId: campaignId,
idempotencyKey: `refund:campaign-all:${campaignId}`,2
description: "Kampanya başlatılamadı — otomatik kredi iadesi",3
});
Zeile 8. Eine fehlgeschlagene Erstattung loggt den Marker RECONCILE-NEEDED, statt eine Exception zu werfen, so geht kein Credit unbemerkt verloren, und die Pipeline gibt den Lauf trotzdem frei.
Zeile 27. Ein Idempotenzschlüssel pro Ereignis: Der Fehler-Handler kann erneut laufen, aber das Ledger verbucht die Erstattung nur einmal.
Zeile 28. Der Erstattungsgrund ist auf Türkisch, weil das Produkt durchgehend zweisprachig ist.
Wo es heute steht
Aus einer Hackathon-Demo ist ein zweisprachiges Produkt mit GPU-Scoring geworden. Es ist inzwischen Closed Source, und der kostenpflichtige Launch wird vorbereitet.