Files
social-app/docs/plans/2026-02-27-invite-code-design.md
T

7.1 KiB
Raw Blame History

邀请码机制设计

Date: 2026-02-27 Status: Approved Author: User + AI

背景

为用户注册增加邀请码机制,支持:

  • 每个用户注册后自动获得专属邀请码
  • 注册时可填写他人邀请码
  • 记录邀请关系和使用统计
  • 支持运营邀请码(批量、限额、过期、禁用)
  • 预留奖励策略配置

数据模型

invite_codes 表

字段 类型 约束 说明
id UUID PK 主键
code VARCHAR(8) UNIQUE, NOT NULL 邀请码
owner_id UUID FK → profiles.id, nullable 所属用户,NULL 为运营码
max_uses INT nullable 最大使用次数,NULL 无限制
used_count INT DEFAULT 0 已用次数
expires_at TIMESTAMPTZ nullable 过期时间,NULL 永不过期
status VARCHAR(20) NOT NULL active / disabled
reward_config JSONB DEFAULT '{}' 奖励策略配置
created_at TIMESTAMPTZ NOT NULL 创建时间
updated_at TIMESTAMPTZ NOT NULL 更新时间
deleted_at TIMESTAMPTZ nullable 软删除

索引:

  • ix_invite_codes_code ON (code) UNIQUE
  • ix_invite_codes_owner_id ON (owner_id)
  • ix_invite_codes_status_expires ON (status, expires_at)

CHECK 约束:

  • status IN ('active', 'disabled')
  • used_count >= 0
  • max_uses IS NULL OR max_uses > 0

profiles 表变更

字段 类型 约束 说明
referred_by UUID FK → profiles.id, nullable 被谁邀请

索引:

  • ix_profiles_referred_by ON (referred_by)

API 变更

POST /auth/verifications

Request:

{
  "username": "string (3-30 chars)",
  "email": "string (email)",
  "password": "string (min 6 chars)",
  "redirect_to": "string?",
  "invite_code": "string (8 chars)?"  // 新增,可选
}

Response: 202 Accepted(不变)

注册流程

┌─────────────────────────────────────────────────────────────────┐
│ 1. POST /auth/verifications                                      │
│    - 存储 username + invite_code 到 Supabase metadata           │
│    - 发送 OTP 邮件                                               │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│ 2. POST /auth/verifications/verify                               │
│    - 验证 OTP                                                    │
│    - 创建 auth.users 记录                                        │
│    - 触发 on_auth_user_created trigger                          │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│ 3. Trigger: on_auth_user_created                                │
│    a. INSERT INTO profiles (id, username, ...)                  │
│    b. 生成 8 位随机邀请码                                         │
│    c. INSERT INTO invite_codes (code, owner_id, ...)            │
│    d. 从 metadata 取 invite_code,执行邀请校验逻辑                 │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│ 4. 邀请码校验逻辑                                                 │
│    IF invite_code 存在 AND                                       │
│       status = 'active' AND                                      │
│       (expires_at IS NULL OR expires_at > now()) AND            │
│       (max_uses IS NULL OR used_count < max_uses)               │
│    THEN                                                          │
│       UPDATE profiles SET referred_by = invite_codes.owner_id   │
│       UPDATE invite_codes SET used_count = used_count + 1       │
│    END IF                                                        │
└─────────────────────────────────────────────────────────────────┘

邀请码生成规则

  • 8 位随机字符串
  • 字符集:ABCDEFGHJKLMNPQRSTUVWXYZ23456789(排除易混淆字符 0/O/1/I/L
  • 唯一性:数据库 UNIQUE 约束 + 生成时冲突重试(最多 10 次)

使用记录查询

通过 profiles 表查询:

-- 查询某个邀请码的使用记录
SELECT p.id, p.username, p.created_at
FROM profiles p
JOIN invite_codes ic ON ic.owner_id = :owner_id
WHERE p.referred_by = ic.owner_id
ORDER BY p.created_at DESC;

-- 查询某个用户邀请了多少人
SELECT COUNT(*) FROM profiles WHERE referred_by = :user_id;

边界情况

场景 处理方式
邀请码不存在 跳过邀请,注册正常成功
邀请码已禁用 跳过邀请
邀请码已过期 跳过邀请
邀请码已达上限 跳过邀请
用户自邀(用自己的码) 不可能,用户注册时还没有邀请码
重复使用同一邀请码 允许(until max_uses

后续扩展

  1. 奖励系统:通过 reward_config JSONB 字段配置不同奖励策略
  2. 运营批量码owner_id = NULL 的邀请码,支持市场推广
  3. 邀请排行榜:基于 used_count 或 profiles 关联查询
  4. 邀请码回收:软删除 deleted_at,保留历史记录

迁移计划

  1. 新增迁移文件创建 invite_codes
  2. 新增迁移文件给 profiles 表添加 referred_by 字段
  3. 修改 on_auth_user_created trigger 增加邀请码逻辑
  4. 修改 VerificationCreateRequest schema 添加 invite_code 字段
  5. 修改 create_verification gateway 传递 invite_code 到 metadata

测试用例

  1. 注册时不填邀请码 → 正常注册,生成专属邀请码
  2. 注册时填写有效邀请码 → 关联邀请关系,used_count +1
  3. 注册时填写无效邀请码 → 正常注册,无邀请关系
  4. 邀请码达上限后使用 → 正常注册,无邀请关系
  5. 运营邀请码使用 → 正常注册,无 referred_byowner_id = NULL