# PURO AI · 设计交付文档

> 把已有的 Claude / ChatGPT / Codex / Gemini 订阅聚合成统一 API · 让"已经付过钱的订阅"真正可编程

本文档面向**接手实现这套设计的工程团队 / Coding Agent**,说明每个 HTML 文件的用途、数据契约、交互逻辑,以及与后端的对接点。

---

## 0. 文件清单

| 文件 | 类型 | 说明 |
|---|---|---|
| `Landing.html` | 营销首页 | 未登录入口 · Hero / 模型墙 / 功能 / 代码示例 / Dashboard 预览 / Pricing / FAQ |
| `Pricing.html` | 定价页 | 完整定价 + 成本估算器 + 工具兼容墙 + 10 条 FAQ |
| `Docs.html` | 文档 | 快速开始 / 模型列表 / API 参考 / 各客户端配置 |
| `Login.html` | 登录 | 左侧叙事 + 右侧表单 · 支持 LinuxDO OAuth |
| `Register.html` | 注册 | 带密码强度 · 下一步引导 · 送 $5 |
| `Binding.html` | 订阅绑定 | 核心差异化流程 · OAuth 接入 Claude Pro / ChatGPT Plus |
| `Dashboard.html` | 控制台首页 | 余额 / 用量图表 / 近期请求 / 订阅池状态 |
| `API Keys.html` | Key 管理 | 创建 / 吊销 / 预算限制 / 模型白名单 |
| `Design System.html` | 设计系统 | 色板 / 字号 / 组件索引 |
| `puro.css` | 全站样式 | 所有页面共用的 tokens + primitives(.btn / .pill / .tag / .input 等) |

**所有页面必须首行 meta:** `<meta name="color-scheme" content="dark">` —— 防止浏览器 auto-darken 覆盖 cyan 按钮。

---

## 1. 设计 Tokens(见 `puro.css`)

```
--bg-0: #0a0e1a      页面底
--bg-1: #0f172a      raised
--bg-2: #111827      card alt
--bg-code: #020617   代码面板

--border:  #1e293b
--border-2:#334155
--border-3:#475569

--text-0: #f8fafc    主
--text-1: #cbd5e1    次
--text-2: #94a3b8    说明
--text-3: #64748b    弱

--cyan:   #22d3ee    主强调(primary btn / 链接 / 数据点)
--cyan-2: #67e8f9    hover
--purple: #a855f7    次强调 / 装饰
--amber:  #fbbf24    提醒 / 限时标签
--green:  #34d399    成功 / 在线
--red:    #f87171    错误 / 危险
```

字体:`Inter`(正文)+ `JetBrains Mono`(所有数值 / 代码 / 元信息)。
圆角:`--r-sm 6px / --r-md 8px / --r-lg 12px / --r-xl 16px`。

---

## 2. 页面 → 后端契约

### 2.1 Landing · 无后端依赖(纯营销)
锚点:`#pricing` / `#faq` / `#features` / `#code` / `#dashboard`。注册 CTA → `Register.html`。

### 2.2 Register
提交表单需要 **后端返回**:
```
POST /auth/register
{ email, password, linuxdo_token? }
→ 200 { user_id, jwt, balance_credits: 5.00 /* $5 注册赠送 */ }
```
前端验证规则:
- 邮箱格式 `^[^\s@]+@[^\s@]+\.[^\s@]+$`
- 密码强度 ≥ 2(长度 ≥ 8 + 字母大小写混合即可通过)
- 两次密码一致 + 勾选 terms
成功后跳 `Binding.html`。

### 2.3 Login
```
POST /auth/login
{ email, password } 或 { linuxdo_oauth_code }
→ 200 { jwt, user, has_subscriptions: boolean }
```
若 `has_subscriptions === false`,引导去 `Binding.html`;否则去 `Dashboard.html`。

### 2.4 Binding(核心差异化)
OAuth 流程,每个平台:
```
POST /bindings/oauth/start
{ provider: 'claude' | 'chatgpt' | 'codex' | 'gemini' }
→ { auth_url, state }
```
前端打开 `auth_url` 新窗口;OAuth 回调:
```
GET /bindings/oauth/callback?code=...&state=...
→ 302 → /binding/success?provider=claude&account_id=...
```
绑定列表:
```
GET /bindings
→ [ { id, provider, account_email, plan, status: 'healthy'|'cooling'|'error', quota_remaining_pct, bound_at } ]
DELETE /bindings/:id  解绑
POST /bindings/:id/test  发一条测试请求验证凭证有效
```

### 2.5 Dashboard
```
GET /me/overview
→ {
  balance: { credits: 45.23, bonus_credits: 12.00, expires_at: null },
  usage_today: { requests: 1842, tokens_in: 2.1e6, tokens_out: 4.8e5, cost: 1.23 },
  usage_30d: [{ date, cost, requests }, ...],
  recent_requests: [{ ts, model, route_to, status, latency_ms, tokens, cost }, ...],
  pool_status: [{ provider, accounts: [{ status, quota_pct }] }]
}
```
图表用 `usage_30d` 绘制折线(cyan 主线,purple 副线)。

### 2.6 API Keys
```
GET  /api-keys
POST /api-keys  { name, models?: string[], monthly_budget?: number }
DELETE /api-keys/:id
```
Key 前缀 `sk-puro-` + 32 字符。创建后仅显示一次完整值,之后只保留前 8 位。

### 2.7 Pricing
纯静态展示。充值 CTA 统一走:
```
POST /billing/topup
{ amount_usd, payment_method: 'alipay'|'wechat'|'usdt'|'stripe' }
→ { payment_url / qr_code, order_id }
```
阶梯赠送在前端计算并展示(见 `Pricing.html` 底部 script),**后端下单时再次校验**:
```
阶梯 = amount >= 500 ? 120%
     : amount >= 200 ? 110%
     : amount >= 99  ? 100%
     : amount >= 50  ? 70%
     : amount >= 30  ? 50%
     : amount >= 20  ? 35%
     : 21%
```

---

## 3. 统一 API Gateway(产品核心)

所有用户集成的终点:
```
https://api.puro.im/v1/chat/completions    # OpenAI 兼容
https://api.puro.im/v1/messages            # Anthropic 兼容
https://api.puro.im/v1beta/models/:m:generateContent  # Gemini 兼容
```
Header: `Authorization: Bearer sk-puro-xxx`

**调度逻辑(文档化在 `Docs.html`):**
1. 根据模型解析目标 provider
2. 从该 provider 的订阅池挑一个 `status=healthy` 的账号(权重:剩余配额 × 响应时延倒数)
3. 若 429 / 限流,标记 `cooling` 60-300s,failover 到下一个
4. 若该 provider 所有订阅都 cooling 且用户余额 > 0,fallback 到官方 API
5. 所有请求写入 `request_logs`(用户可见,保留周期按套餐)

---

## 4. 套餐与限制

| | Starter $9.9 | Pro $29.9 ⭐ | Scale $99 | Custom |
|---|---|---|---|---|
| 赠送 | +21% | +50% | +100% | 阶梯 |
| API Keys | 1 | 3 | 10 | 按 Pro |
| RPM | 60 | 120 | 300 | 按 Pro |
| 日志保留 | 7d | 30d | 90d | 按 Pro |
| 自带订阅 | ❌ | ∞ | ∞ | ✅ |
| 多账号 failover | — | ✅ | ✅ + 优先级 | ✅ |

**Enterprise** 走 Sales 线:私有化 / SLA / Invoice,不在普通订单流里。

---

## 5. 交互细节(容易漏)

- **余额不足**:Gateway 返回 `402 Payment Required`,Dashboard 顶部红色 banner + 发邮件(80% / 95% 两档预警)
- **订阅 cooling** 时 Dashboard 订阅卡片上角 amber 闪烁点
- **API Key 创建**:弹窗必须强制用户复制一次,关闭弹窗后永远看不到完整值
- **密码强度**:评分 0-4,label 对应 `— / 弱 / 中 / 强 / 极强`,颜色 `border / red / amber / cyan / green`
- **登录成功**:按钮变 green 显示 `✓ 登录成功`,800ms 后 window.location 跳转
- **LinuxDO OAuth** 是 PURO 的目标用户群(开发者社区),作为次要登录按钮展示

---

## 6. 响应式断点

- `<= 900px`:Login/Register 的 split 变单列,narrative 折叠
- `<= 820px`:Pricing grid 从 4 列 → 1 列
- `<= 820px`:Landing pricing-grid-landing 从 3 列 → 1 列
- `<= 960px`:Pricing 的 calculator 从 2 列 → 1 列

---

## 7. 后端技术建议(非设计范畴,仅供参考)

- **Gateway 层**:Go / Rust 写高吞吐代理,HTTP/2 + streaming,每 provider 起独立 worker pool
- **调度**:Redis ZSET 存每个订阅的健康分 + cooling 过期时间
- **日志**:写 ClickHouse(列存 + 按日分区),Dashboard 直接查
- **凭证加密**:每个订阅凭证用 AES-256-GCM 加密,key 放 KMS;解密只在 gateway worker 内存里,绝不落日志
- **计费**:Pulsar / Redis Streams 实时扣费,最终一致性,异步对账

---

## 8. 已知 TODO(设计层面暂不处理,开发阶段补)

- [ ] Dashboard 真实图表联动(目前是静态 SVG)
- [ ] Binding OAuth 回调 loading / 成功动效
- [ ] 邮件模板(注册验证 / 余额预警 / 充值成功)
- [ ] 忘记密码流程
- [ ] 团队 / 多人协作 UI(Enterprise 档需要)
- [ ] i18n:当前仅中文,英文版待出

---

生成时间:2026-04 · 设计稿版本:v1

联系 Sam / 产品负责人确认实现细节。
