全部项目详解

Ürünereklam

已完成

贴上商品链接,就能拿到做好的土耳其语和英语视频广告和图片广告,每一条在花钱投放之前都会先由预测模型打分。项目起步于 2026 年的 BTK Akademi Hackathon。

我的角色
独立完成设计与开发
年份
2026
使用技术
Next.js · Inngest · Supabase · Gemini · Veo · ElevenLabs · Remotion · PyTorch on Modal · Polar
SCRAPER: PYTHON, HARDENEDFETCHSTRATEGY + FRAMES: GEMINIVIDEO: VEO / SEEDANCEVOICE + MUSIC: ELEVENLABSEDIT: REMOTION, CAPTIONS, CTASCORE: TRIBE V2 ON MODAL GPUSUPABASE: STATE, CREDITLEDGERFACTSFRAMESWORD TIMINGADSRANKEDONE PRODUCT LINK INSPAWN + POLL: GPU JOB OUTLIVES EDGE TIMEOUTSTEP DIES → CREDITS REFUNDED ONCE

横向滚动可以看到完整的图。

架构SCRAPE → GENERATE → RENDER → SCORE, REFUND ON FAILURE

问题

要按网店需要的量做两种语言的广告,通常意味着要长期雇一家代理公司。即便如此,在预算花出去之前,谁也不知道哪个版本会有效。

实现方式

Next.js 应用负责编排 Inngest 的持久化任务。Python 爬虫读取商品页面,碰到难抓的店铺页面,会走一条加固过的抓取路径。Gemini 写策略、文案和分镜,Veo 或 Seedance 渲染视频,ElevenLabs 配音,Remotion 加上逐词对齐的字幕、水印和 CTA。另有一个独立的工作台,用来制作静态图片广告和广告文案。之后,每个变体都要经过一个自托管的模型(TRIBE v2),预测人们会对它有什么反应。模型跑在 Modal 的 GPU 上,先启动任务再轮询结果,因为一次渲染的耗时会超过边缘函数的超时时间。Supabase 保存状态,由行级安全保护,媒体用短时有效的签名 URL。积分记在只追加的账本里,扣费和退款都是原子操作;结账走 Polar,价格以里拉和美元标示。

关键决策

  • 失败的步骤会自动退款

    流水线由持久化任务组成,每一步都有失败处理器。某一步挂掉时,会把它的积分恰好退还一次,并释放这次运行,而不是让它卡住。

  • 媒体文件默认私有

    原始渲染文件放在私有存储桶里,列级 SELECT 权限已撤销,媒体链接都是短时有效的签名 URL。包括免费版在内,没有任何媒体地址能被猜到。

  • 每条广告在有人为它花钱之前都会打分

    没有分数的广告不会离开工作台。在有人为某个变体投入预算之前,模型就已经给各个变体排好了名次。

仓库里的代码

server/inngest/functions.ts恰好退还一次积分的失败处理器
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
});
  1. 第 8 行. 退款失败时不抛异常,而是记录一个 RECONCILE-NEEDED 标记,这样积分不会悄无声息地丢失,流水线也照样会释放这次运行。

  2. 第 27 行. 每个事件一个幂等键:失败处理器可能会再次运行,但账本只会记录一次退款。

  3. 第 28 行. 退款原因用的是土耳其语,因为这个产品从头到尾都是双语的。

目前进展

它从一个黑客松 demo 成长为一个带 GPU 打分的双语产品。现在已闭源,正在准备付费上线。

下一篇Pistochia