Tiancheng Lu
← Back home

Private product · sanitized case study · in active iteration

Ecom Image · E-commerce AI asset workbench

A full-pipeline workbench for e-commerce assets — collect → reference → generate → review → deliver — hardening from a local tool into a multi-tenant service with a controlled public trial.

Role
Solo developer
Period
2026.07 – present (active iteration)
Scale
Private repo · 52 commits
Status
Release-gate driven · not public yet

The problem

E-commerce asset production has three real pain points: version explosion — the same product needs different styles per country / platform, and manual prompt-and-output management quickly spirals; reference-driven — good images are not conjured from nothing, operators first study what hot products are shipping and distill best-sellers into reference assets; cost & quality must close the loop — every generation costs compute, delivery needs QA, and opening to external users demands identity, isolation, quotas and a ledger.

Benchmarked for feature parity against an overseas e-commerce design SaaS, but with fully self-owned branding, backend, model routing and billing. Currently in active iteration — not a one-off demo.

System boundary

Runtime shape: Next.js web UI + unified Python API (single process) + Postgres / Redis / MinIO.

LayerResponsibility
Web (Next.js) Inspiration feed, main workbench, AI tool workbench (in-canvas inline editing); same-origin /api/* proxy only — the browser never talks to any model SDK directly
Unified API (single Python package, domain modules) projects (main pipeline + job executor), prompts (templates + style profiles), model_gateway (channel routing), billing (quote → ledger), qa, assets (storage proxy), crawler (collection scheduling), auth (identity & tenancy), brand_profiles
Infrastructure Postgres (metadata), Redis (queues), MinIO (image objects, private bucket + signed URLs)
  • Main chain: Project → MarketVersion → GenerationJob → DeliveryAsset — one product one project, one market one version, delivery assets carry full lineage.

Key decisions

  1. 1

    Dropped n8n and multi-service splits for a single modular FastAPI package

    An orchestration engine is a liability for solo iteration — types, tests and deployment all converge into one Python package organized by domain, with a single uvicorn entrypoint. The early n8n orchestration was fully removed from the runtime (archived JSON only, never loaded).

  2. 2

    Model Channel abstraction, not single-provider lock-in

    A Channel = one upstream connection (auth, endpoint, model list, capability tags, priority); supports OpenAI-compatible / Gemini / Alibaba Bailian / Volcano Ark providers with capability-based routing and automatic fallback; keys stored as reference names only (api_key_ref), never plaintext; MOCK mode is dev-only and explicitly not an acceptance capability.

  3. 3

    Hot-product collection → reference-image asset governance

    Embedded APScheduler scheduling (business-friendly cron config), two-layer idempotent dedup (source+external ID, source URL), separate stores and tags for hot-product vs reference images, explicit "add to reference set" promotion; references + locale/platform style profiles + versioned templates assemble prompts.

  4. 4

    No mock placeholders — as a hard rule

    Core backend paths must be real implementations; faking projects, jobs, assets or billing with mocks is forbidden by repository rules.

  5. 5

    Supabase issues identity only; authorization always in our API

    FastAPI verifies JWKS asymmetric signatures (signature / issuer / audience / expiry / kid, with one bounded refresh for unknown kids); browser-claimed email / role are never trusted; local storage keeps subject mapping only, never passwords.

  6. 6

    Invite-based controlled trial: harden first, open later

    Invite codes stored as HMAC-SHA256 fingerprints, replay-protected, with persistent rate limiting and same-transaction consumption; if upstream account creation succeeds but local persistence fails, a compensating deletion fires, escalating to critical alerts; operator password resets require a reason and write redacted audit events.

  7. 7

    Release-gate-driven rollout

    Before any public trial, six gate categories must pass item by item — identity & access, tenant isolation & storage, credits & execution (quote / reserve / deduct / release all idempotent + immutable ledger), operator console, production runtime (config validated at boot, no exposed ports, backup/restore drill), staging demo evidence (including cross-tenant negative tests). Every item requires evidence; no gate, no open.

View sanitized architecture (Mermaid source) ›

The diagram uses generic role labels only — no competitor names, credentials or tenant data.

%% Ecom Image 脱敏架构图(公开版 · 2026-07 现役运行时)
%% 不含竞品名、真实域名、密钥、供应商内部细节
flowchart TB
  User([运营 / 设计者])
  Operator([平台运营者])

  subgraph Web["Web UI · Next.js"]
    Insp["灵感流首页<br/>热卖参考"]
    Bench["主工作台<br/>Project → MarketVersion → Job → DeliveryAsset"]
    Tools["AI 工具工作台<br/>画布内联 AI 编辑"]
    Web2["同源 /api/* 代理<br/>浏览器不直连模型 SDK"]
  end

  subgraph API["统一 Python API · FastAPI 单进程(ecom 包)"]
    Auth["auth<br/>JWT 验签(JWKS) · 邀请激活<br/>租户隔离 · 审计"]
    Projects["projects<br/>主链路 + 任务执行器"]
    Prompts["prompts<br/>模板 + 地区风格档案组装"]
    Gateway["model_gateway<br/>Channel 抽象 · 能力路由 · fallback<br/>密钥只存引用"]
    Billing["billing<br/>估价 → 报价/预占/扣减/释放 → 账本"]
    QA["qa<br/>质量检查"]
    Assets["assets<br/>资产 CRUD · 存储代理"]
    Crawler["crawler<br/>内嵌调度 · 两层幂等去重<br/>爆款图 → 参考集升格"]
  end

  subgraph Infra["基础设施"]
    DB[("Postgres<br/>元数据 / 租户 / 账本")]
    Redis[("Redis<br/>队列支持")]
    S3[("MinIO<br/>私有桶 + 签名 URL")]
  end

  IdP["身份提供方<br/>仅签发身份 · 授权在自有 API"]
  Models["外部模型服务(多 provider)<br/>OpenAI 兼容 / Gemini / 百炼 / 方舟<br/>按能力路由"]
  Sources["电商平台公开数据<br/>热卖榜 / 店铺 / 关键词"]

  User --> Web
  Web -->|同源| Auth
  Auth --> IdP
  Web --> Projects
  Projects --> Prompts --> Gateway
  Projects --> QA
  Projects --> Assets
  Gateway --> Billing
  Crawler --> Sources
  Crawler --> Assets
  API --> DB
  API --> Redis
  Assets --> S3
  Gateway --> Models
  Operator -->|"console · 邀请 / 配额 / 通道管理<br/>敏感操作写脱敏审计"| Auth

Verification

  • 37 pytest test files covering auth / assets / billing / brand_profiles / crawler / model_gateway / projects / prompts / shared; every commit ships its verification command and result (latest round: 27 passed);
  • Web-side tsc --noEmit zero errors as a pre-commit gate;
  • Production runtime boot validation: missing Supabase / Postgres / MinIO / migrations / model-channel config refuses to start;
  • Known risks publicly recorded: some settings / log routes are marked as release blockers until tenant isolation completes.

Public artifacts

  • Status: the product is still iterating; the public-trial release gates are not all passed yet (multi-tenant isolation in progress), so there is no public URL
  • Test evidence maintained in-repo; screenshots and demos will be recorded with synthetic brand assets after gates pass

Redaction boundary

The following are intentionally excluded from this case study:

  • Benchmarked competitor name, static assets and crawled data;
  • Model-provider credentials and raw provider responses;
  • Real merchant assets and unauthorized brand elements;
  • Real invite codes, audit data, tenant data;
  • Screenshots / demos always use synthetic brands and synthetic products.