体验资格发放文档

baozi 体验资格(trial):注册用户通过专属渠道链接领取 7 天 ¥38 coding-lite 套餐体验,先验证产品被接受和需求真实存在,再考虑商业化。限额总 100 名 = 9 渠道独立配额之和,邀请机制可累加。

1. 用户视角流程

1.1 领体验资格

微信群/微博/V2EX 渠道专属链接
  ↓
点链接 → 进 baozi 首页
  ↓
未登录 → 走 Logto OIDC 注册/登录
  ↓
登录后自动调 POST /api/v1/trial/claim { channel_code: "wechat-group" }
  ↓
扣减渠道配额 +1 + 写 trial_claims + 返体验额度
  ↓
前端跳 /dashboard 看到体验激活 (7 天倒计时 + ¥38 配额)

1.2 看自己状态

# 登录后调
GET /api/v1/trial/status
# 返: has_trial=true, active=[{remaining_days:7, quota_yuan:38}], invite_code="<user_id>"

1.3 邀请好友(飞轮)

# 查自己的邀请链接
GET /api/v1/trial/invite-link
# 返: invite_url="https://baozi.ohoooho.com/trial/invite-123"

# 好友点链接注册 → 好友填 channel_code=invite + invite_code=123 领体验
# → 邀请人配额 +1 名 + 体验延期 +7 天

2. 渠道配额总览

2.1 9 渠道默认配额(总 100 名)

渠道 名额 入口形态
微信群 (wechat-group) 20 群内专属链接
微博 (weibo) 15 文章末尾链接
Twitter/X (twitter) 10 推文链接
即刻 (jike) 10 动态链接
V2EX (v2ex) 10 帖子链接
GitHub (github) 10 README 链接
少数派 (sspai) 5 文章链接
邀请链接 (invite) 20 用户邀请飞轮(可累加)

2.2 公开查询(无需登录)

GET /api/v1/trial/quotas

返回示例(200):

{
  "success": true,
  "data": {
    "channels": [
      { "code": "invite",       "name": "邀请链接", "total": 20, "used": 0, "remaining": 20, "enabled": true },
      { "code": "wechat-group", "name": "微信群",   "total": 20, "used": 0, "remaining": 20, "enabled": true },
      { "code": "weibo",        "name": "微博",     "total": 15, "used": 0, "remaining": 15, "enabled": true },
      { "code": "github",       "name": "GitHub",   "total": 10, "used": 0, "remaining": 10, "enabled": true },
      { "code": "jike",         "name": "即刻",     "total": 10, "used": 0, "remaining": 10, "enabled": true },
      { "code": "twitter",      "name": "Twitter/X","total": 10, "used": 0, "remaining": 10, "enabled": true },
      { "code": "v2ex",         "name": "V2EX",     "total": 10, "used": 0, "remaining": 10, "enabled": true },
      { "code": "sspai",        "name": "少数派",   "total": 5,  "used": 0, "remaining": 5,  "enabled": true }
    ],
    "total": 100,
    "used": 0,
    "remaining": 100,
    "duration_days": 7,
    "quota_yuan": 38,
    "package_id": "coding-lite"
  }
}

3. API 全清单(5 端点)

3.1 GET /api/v1/trial/quotas — 公开

见 2.2 节。

3.2 POST /api/v1/trial/claim — 登录态

请求体:

{ "channel_code": "wechat-group" }

或邀请场景:

{ "channel_code": "invite", "invite_code": "123" }

返回示例(200):

{
  "success": true,
  "data": {
    "claim_id": 1,
    "user_id": 42,
    "username": "baozi-e2e-user-001",
    "channel_code": "wechat-group",
    "quota_yuan": 38,
    "package_id": "coding-lite",
    "expires_at": 1752384000000,
    "expires_at_iso": "2026-09-17T10:59:33.000Z",
    "duration_days": 7
  }
}

错误码:

状态码 code 含义
401 auth_required 未登录
400 channel_code 必填
404 渠道不存在
403 渠道已停用
409 quota_exhausted 渠道配额用完
409 already_claimed 同一用户同渠道已领

3.3 GET /api/v1/trial/status — 登录态

返回示例(200):

{
  "success": true,
  "data": {
    "has_trial": true,
    "active": [
      {
        "claim_id": 1,
        "channel_code": "wechat-group",
        "quota_yuan": 38,
        "package_id": "coding-lite",
        "expires_at": 1752384000000,
        "expires_at_iso": "2026-09-17T10:59:33.000Z",
        "remaining_days": 7
      }
    ],
    "converted": [],
    "expired_count": 0,
    "invite_code": "42"
  }
}

3.4 GET /api/v1/trial/invite-link — 登录态

返回示例(200):

{
  "success": true,
  "data": {
    "invite_code": "42",
    "invite_url": "https://baozi.ohoooho.com/trial/invite-42",
    "invited_count": 0,
    "my_claim": null,
    "reward_rule": "邀请 1 人体验, 你的配额 +1 名 + 你的体验延期 7 天"
  }
}

3.5 GET /api/v1/admin/trial/stats — admin 角色

返回示例(200):

{
  "success": true,
  "data": {
    "channels": [
      {
        "code": "wechat-group",
        "name": "微信群",
        "used": 3,
        "total": 20,
        "remaining": 17,
        "enabled": true,
        "claims_total": 3,
        "converted": 1,
        "conversion_rate_pct": "33.33"
      }
    ],
    "totals": {
      "used": 5,
      "total": 100,
      "claims": 5,
      "converted": 2,
      "remaining": 95,
      "overall_conversion_rate_pct": "40.00"
    },
    "last_updated": 1751777973000,
    "last_updated_iso": "2026-09-10T11:00:00.000Z"
  }
}

4. 数据库设计

4.1 trial_quotas(渠道配额表)

字段 类型 说明
channel_code TEXT PK 渠道 code(wechat-group / weibo / ...)
channel_name TEXT 显示名
total_quota INTEGER 总配额
used_quota INTEGER 已用(默认 0)
enabled INTEGER 1=启用 / 0=停用
reset_at INTEGER NULL 配额重置时间(NULL=永久)
created_at INTEGER 创建时间(毫秒)
updated_at INTEGER 更新时间(毫秒)

4.2 trial_claims(用户领取记录表)

字段 类型 说明
id INTEGER PK AUTOINCREMENT
user_id INTEGER FK → users.id
channel_code TEXT 领取渠道
invite_code TEXT NULL 邀请人 code(仅 invite 渠道)
quota_yuan INTEGER 体验额度(默认 38)
expires_at INTEGER 体验到期时间(毫秒)
claimed_at INTEGER 领取时间
converted_at INTEGER NULL 转付费时间(NULL=未转)
converted_order_id TEXT NULL 转付费的订单 ID

唯一约束:UNIQUE(user_id, channel_code) 防同一用户重复领。

4.3 索引

CREATE INDEX idx_trial_claims_user       ON trial_claims(user_id);
CREATE INDEX idx_trial_claims_channel   ON trial_claims(channel_code, claimed_at DESC);
CREATE INDEX idx_trial_claims_invite    ON trial_claims(invite_code) WHERE invite_code IS NOT NULL;
CREATE INDEX idx_trial_claims_conversion ON trial_claims(converted_at) WHERE converted_at IS NOT NULL;

5. 邀请机制(增长飞轮)

5.1 触发

  • 用户 A 调 /api/v1/trial/invite-link → 拿 invite_url = https://baozi.ohoooho.com/trial/invite-${A.id}
  • 用户 B 点链接注册 → 注册流程自动带 ?invite=A.id
  • 用户 B 登录后调 POST /api/v1/trial/claim { channel_code: &quot;invite&quot;, invite_code: &quot;A.id&quot; }

5.2 奖励(事务内)

  • 扣减 invite 渠道配额 +1(claim 已自动)
  • invite 渠道 total_quota +1(邀请人奖励)
  • 邀请人 A 的 trial_claims expires_at +7 天

5.3 防滥用

  • invite_code 不能是自己(inviterId === me.id → 400)
  • invite_code 必须对应真实 user(user_id 404 → 404)

6. 转化追踪(验证 PMF)

6.1 trial → 付费链路

用户体验到期前
  ↓
续费提醒 (cron) 调 /api/v1/trial/status 查 remaining_days <= 1
  ↓
发邮件 / 站内信 → "你的体验还剩 1 天, ¥38 续 coding-lite?"
  ↓
用户下单 → POST /api/v1/orders
  ↓
订单支付成功 → 写 trial_claims.converted_at + converted_order_id

6.2 PMF 验证指标

指标 目标 查询
渠道转化率 > 10% admin/trial/statsconversion_rate_pct
整体转化率 > 15% admin/trial/statsoverall_conversion_rate_pct
邀请转化率 > 20% invite 渠道 conversion_rate_pct
体验期用户活跃 > 60% trial_claims.claimed_at + 7 天内 user_tokens 有调用

7. Phase 2+ 待办

  • [ ] 前端 UI: 首页「领体验资格」卡片,实时显示各渠道剩余配额 + 一键登录领
  • [ ] playwright e2e: 注册 → 领体验 → 查 status → 邀请 → 转化全链路真浏览器跑
  • [ ] admin 看板: baozi-system-admin 加渠道 ROI 图表(转化率 + 配额水位 + 时间趋势)
  • [ ] 转化提醒: cron 每天扫 trial_claims.expires_at &lt;= now + 1d 发提醒邮件
  • [ ] 渠道动态调整: admin 端点 PUT/POST 调 total_quota / enabled
  • [ ] 过期清理: 过期体验不主动删 user_tokens,仅打 expired(已实现)

8. 真实部署记录

2026-09-10 Phase 1 部署

  • 代码: /Users/xuyu/xianyun/projects/baozi-service/server.js(2001 行)
  • 部署: /opt/baozi-service/server.js on 140.143.246.15
  • 启动: systemctl restart baozi-service
  • journal 验证: [trial] ✓ 默认 8 渠道配额 seed 完成 (总 100 名) + baozi-auth running on port 3041
  • 端点真测: 5 端点全 200/401 预期(0 个 500 错)

文档问题反馈:飞书群 @ 闲云 · 体验资格发放文档