docs: add invite code design and backlog for user_agents trigger
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"mcp": {
|
||||
"supabase_mcp": {
|
||||
"type": "remote",
|
||||
"url": "http://localhost:8001/mcp",
|
||||
"oauth": false,
|
||||
"enabled": true,
|
||||
"timeout": 10000
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
# Backlog - Known Issues & Improvements
|
||||
|
||||
## Database Triggers
|
||||
|
||||
### [TRIGGER-001] user_agents 自动创建
|
||||
|
||||
**Status**: Pending
|
||||
**Priority**: Medium
|
||||
**Created**: 2026-02-27
|
||||
|
||||
**Description**:
|
||||
当新用户注册时,`user_agents` 表未自动创建默认 Agent 配置记录。
|
||||
|
||||
**Current Behavior**:
|
||||
- `auth.users` → `profiles` 已有 trigger 自动创建
|
||||
- `user_agents` 无自动创建机制
|
||||
|
||||
**Expected Behavior**:
|
||||
新用户注册后,应有默认的 Agent 配置(如 INTENT_RECOGNITION、TASK_EXECUTION、RESULT_REPORTING 三种类型)。
|
||||
|
||||
**Impact**:
|
||||
- 用户首次使用 Agent Chat 功能时可能失败
|
||||
- 需要应用层手动初始化或前端引导配置
|
||||
|
||||
**Implementation Notes**:
|
||||
- 需要先确定 `user_agents` 的默认配置设计
|
||||
- 可通过 `on_auth_user_created` trigger 扩展
|
||||
- 或在 `profiles` trigger 中调用
|
||||
|
||||
**Related Files**:
|
||||
- `backend/alembic/versions/20260226_0001_initial_schema.py` (现有 trigger)
|
||||
- `backend/src/models/user_agents.py`
|
||||
- `backend/src/models/profile.py`
|
||||
|
||||
---
|
||||
@@ -0,0 +1,161 @@
|
||||
# 邀请码机制设计
|
||||
|
||||
**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:**
|
||||
```json
|
||||
{
|
||||
"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 表查询:
|
||||
|
||||
```sql
|
||||
-- 查询某个邀请码的使用记录
|
||||
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_by(owner_id = NULL)
|
||||
Reference in New Issue
Block a user