Starsoup Image Platform — 項目整體定義文件
版本: 0.1(討論稿) 日期: 2026-03-23 作者: Starsoup
一、項目概述
項目名稱(暫定)
Starsoup Image Platform(內部代號:sip)
一句話定義
一個自托管的 AI 輔助圖片自動化平台,由視覺模版編輯器、程式化渲染 API 組成,供 Starsoup 旗下所有項目調用,替代 Bannerbear / Placid 等 SaaS 服務。
背景與動機
Starsoup 旗下的 @crystal/erp 和 @crystal/ec 需要為水晶商品自動生成詳情頁圖片與 marketing 圖,未來懶人包長圖等需求也將逐步加入。現有 SaaS 方案(Bannerbear $49/月起)存在三個問題:
- 無 AI 素材生成能力,模版底圖仍需人工設計
- 按渲染量計費,規模化後成本高
- 無法完全私有化,數據經過第三方服務器
二、市場定位
現有競品對比
| 功能維度 | Bannerbear / Placid | RendrKit | Starsoup Image Platform |
|---|---|---|---|
| 模版視覺編輯器 | ✅ 雲端 | ❌ 無 | ✅ 自建(vue-konva) |
| AI 背景素材生成 | ❌ | ⚠️ 全自動但無模版控制 | ✅ Jaaz 生成,人工確認入模版 |
| 程式化渲染 API | ✅ | ✅ | ✅ 自建(Hono + Satori) |
| 自托管 / 私有部署 | ❌ | ❌ | ✅ |
| 費用模式 | $19–$49/月 + 渲染費 | 同上 | 僅 Vercel + R2 運算成本 |
| 與自有 ERP/EC 整合 | 需 Webhook/Zapier | API | ✅ 原生直調 |
差異化定位
市場上目前沒有任何工具同時具備以下四點:
- AI 素材生成層(Jaaz 生成背景,非黑盒全自動)
- 視覺化 zone 定義編輯器(所見即所得,含字體、顏色、預覽)
- 私有部署渲染 API(無廠商依賴,無按量計費)
- 原生整合自有業務系統
這個空缺使本項目不僅是 Starsoup 的內部工具,也是未來可對外提供的 SaaS 或自托管方案。
三、系統架構
三層職責分離
【外部工具】Jaaz(AI 圖片生成)
└─→ 生成水晶氛圍背景圖 / 商品去背圖等素材
└─→ 人工確認後下載,上傳至 Cloudflare R2
【Layer 1】Template Studio(本項目前端)
└─→ 從 R2 載入背景圖
└─→ 在背景圖上以 vue-konva 視覺化定義 zones
每個 zone:位置(x,y)、尺寸(w,h)、類型(text/image)
text zone:字體、字號、顏色、對齊、最大行數
image zone:圓角、object-fit
└─→ 存入 Supabase(template JSON)
【Layer 2】Render API(本項目後端)
└─→ 接收 { templateId, data }
└─→ 從 Supabase 取 template JSON,從 R2 取背景圖
└─→ Satori 合成 → 輸出 PNG → 上傳 R2
└─→ 返回永久圖片 URL
【調用方】
@crystal/erp ─→ Render API
@crystal/ec ─→ Render API
其他 Starsoup 項目 ─→ Render APIRepo 結構(單一 Repo)
starsoup-image-platform/
apps/
studio/ ← Template Studio(Vue 3 + vue-konva)
api/ ← Render API(Hono)
packages/
shared/ ← 共用 types、Supabase client、R2 utils
supabase/
migrations/ ← DB schema單一 Repo 的理由: Template Studio 和 Render API 共用同一套 template JSON schema、Supabase 連線、R2 bucket。分開 repo 反而增加 schema 同步維護成本。
四、核心數據結構
Template JSON(系統核心契約)
所有三個角色(Studio、API、調用方)都依賴這份 schema。
interface Template {
id: string
name: string
width: number // px,例如 1080
height: number // px,例如 1080
background_url: string // R2 URL
zones: Zone[]
created_at: string
project_id?: string // 多項目隔離用(未來擴展)
}
interface Zone {
id: string // 對應 API 呼叫時 data 的 key
type: 'text' | 'image'
x: number
y: number
width: number
height: number
// text zone 專用
font_family?: string
font_size?: number
font_weight?: string
color?: string
align?: 'left' | 'center' | 'right'
line_height?: number
max_lines?: number
prefix?: string // 例如 "¥"
// image zone 專用
border_radius?: number
object_fit?: 'cover' | 'contain' | 'fill'
}Render API
POST /v1/render
Authorization: Bearer <starsoup-internal-key>
Request:
{
"template_id": "crystal-detail-1x1",
"data": {
"product_image": "https://r2.../products/amethyst.jpg",
"crystal_name": "天然紫水晶原石",
"price": "3,800",
"description": "來自烏拉圭深礦..."
}
}
Response:
{
"image_url": "https://r2.../generated/uuid.png",
"template_id": "crystal-detail-1x1",
"rendered_at": "2026-03-23T10:00:00Z"
}調用方只需傳入純文字和圖片 URL,所有樣式細節(字體、顏色、排版)完全由 template JSON 決定。
Supabase Tables
-- 模版定義
CREATE TABLE templates (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
width INT NOT NULL,
height INT NOT NULL,
background_url TEXT NOT NULL,
zones JSONB NOT NULL,
project_id TEXT, -- 多項目隔離
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- 渲染記錄(可選,用於統計)
CREATE TABLE render_logs (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
template_id TEXT REFERENCES templates(id),
caller TEXT, -- 呼叫來源,例如 "crystal-erp"
image_url TEXT,
rendered_at TIMESTAMPTZ DEFAULT NOW()
);R2 Bucket 結構
starsoup-images/
templates/backgrounds/ ← Jaaz 生成的背景底圖(永久保存)
templates/assets/ ← 其他模版素材
generated/ ← API 渲染輸出(可設定 TTL 或永久)五、技術棧與授權
| 技術 | 用途 | 授權 | 商用 |
|---|---|---|---|
| Vue 3 | Studio 前端框架 | MIT | ✅ |
| vue-konva / Konva.js | Zone 拖拽編輯器 | MIT | ✅ |
| Hono | Render API server | MIT | ✅ |
| Satori(Vercel) | HTML/CSS → SVG 渲染 | Apache 2.0 | ✅ |
| @resvg/resvg-js | SVG → PNG 轉換 | Apache 2.0 | ✅ |
| Supabase JS | 資料庫 client | MIT | ✅ |
| Cloudflare R2 | 圖片儲存 | 商業服務 | ✅ |
| Vercel | 部署平台 | 商業服務 | ✅ |
| Google Fonts / Noto TC | 中文字體 | OFL 1.1 | ✅ |
版權風險:零。 唯一需要注意的是字體,只使用 OFL 授權的 Google Fonts 系列即可完全規避商業字體版權問題。
六、開發計劃
Phase 0:規格確認(現在)
- [ ] Template JSON schema 定案
- [ ] Supabase table 設計確認
- [ ] R2 bucket 命名規則確認
- [ ] API endpoint 設計確認
- [ ] Repo 建立(
starsoup-image-platform)
Phase 1:核心渲染鏈(MVP)
目標:從硬編碼模版到能夠生成水晶詳情圖的完整鏈路
- [ ] Hono API server 基礎架構
- [ ] Satori 渲染引擎整合(含 R2 背景圖載入)
- [ ] Noto Serif/Sans TC 字體嵌入
- [ ] 硬編碼第一個模版(crystal-detail-1x1)進行端到端測試
- [ ] 渲染結果上傳 R2,返回永久 URL
- [ ] 部署至 Vercel
- [ ]
@crystal/erp整合呼叫
Phase 2:Template Studio
目標:視覺化模版編輯器,取代 Phase 1 的硬編碼模版
- [ ] Vue 3 + vue-konva 專案搭建
- [ ] 背景圖從 R2 載入至 canvas
- [ ] Zone 拖拽新增(text / image 兩種類型)
- [ ] Zone 樣式面板(字體選擇、字號、顏色、對齊)
- [ ] 即時預覽(canvas 直接顯示樣式效果)
- [ ] Template 存入 Supabase
- [ ] Template 列表管理(CRUD)
Phase 3:Starsoup 化(未來)
目標:使本平台可服務 Starsoup 旗下所有項目,並為對外開放做準備
- [ ]
project_id多項目隔離 - [ ] API key 管理(每個呼叫方獨立 key)
- [ ] 渲染記錄與統計後台
- [ ] 懶人包長圖支援(動態高度模版)
七、外部依賴關係
Jaaz(外部工具,非本項目組成部分)
Jaaz 是獨立的桌面 AI 創意工具,在本平台中的角色是背景素材生成工具,工作流程如下:
設計師在 Jaaz 生成背景圖
→ 下載 PNG
→ 上傳至 R2(starsoup-images/templates/backgrounds/)
→ 在 Template Studio 中以此背景圖建立新模版Jaaz 與本平台沒有程式層面的耦合,任何 AI 圖片生成工具(Midjourney、Flux、其他)均可替代。
八、待確認事項
在正式進入 Phase 0 規格確認之前,以下問題需要決定:
Q1:Template Studio 是部署為獨立的 URL(例如 studio.starsoup.co),還是內嵌在 @crystal/erp 的 admin 頁面中?
Q2:Supabase 使用現有的 ERP Supabase project,還是為本平台建立獨立的 Supabase project?
Q3:Render API 的 Vercel 部署是作為獨立 project(image-api.starsoup.co),還是與 Studio 在同一個 Vercel project 下作為不同 path?
Q4:Phase 1 的第一個模版(crystal-detail-1x1)的尺寸和 zone 佈局,是現在就設計,還是等 Phase 2 Studio 做好後再正式定義?
本文件為討論稿,所有決策在 Phase 0 規格確認後定案。