GEO 平台需求规格说明书
文档版本: v1.0
创建日期: 2026-05-01
状态: 待评审
依据文档: GEO平台PRD v1.0
评审记录: 详见 专家讨论总览
目录
- 概述
- 功能需求规格
- 接口需求规格
- 数据需求规格
- 非功能需求规格
- 约束条件
- 需求追踪矩阵
- 附录
1. 概述
1.1 文档目的
本需求规格说明书旨在详细定义GEO平台的功能性需求和非功能性需求,作为产品设计、开发、测试和验收的依据。本文档是PRD文档的细化,包含所有用户故事的详细验收标准。
1.2 范围
包含范围:
- GEO平台v1.0版本的所有功能需求
- 前后端系统的接口定义
- 数据库设计的数据实体
- 性能、安全、可用性等非功能需求
不包含范围:
- v1.5及后续版本的情感分析、白标等功能
- 移动App相关需求
- 第三方支付集成细节
1.3 定义与缩略语
| 术语 |
定义 |
| GEO |
Generative Engine Optimization,生成式引擎优化 |
| AI曝光度评分 |
品牌在AI搜索中的综合表现分数 (0-100) |
| SOV |
Share of Voice,品牌提及占比 |
| 引用记录 |
AI回答中提及品牌的一次记录 |
| Prompt |
向AI平台发送的查询指令 |
| 品牌别名 |
品牌的常见简称或昵称 |
2. 功能需求规格
2.1 用户认证模块 (F-AUTH)
2.1.1 用户注册
| 属性 |
内容 |
| 需求ID |
F-AUTH-001 |
| 需求名称 |
用户注册 |
| 优先级 |
P0 |
| 描述 |
新用户可以通过邮箱注册成为平台用户 |
详细规格:
| 字段 |
类型 |
必填 |
验证规则 |
| 邮箱 |
string |
是 |
邮箱格式,255字符内,唯一 |
| 密码 |
string |
是 |
8-32字符,需包含大小写字母和数字 |
| 确认密码 |
string |
是 |
必须与密码一致 |
| 验证码 |
string |
是 |
6位数字,有效期10分钟 |
业务流程:
1. 用户输入邮箱、密码、确认密码
2. 系统发送验证码到邮箱
3. 用户输入验证码
4. 系统验证通过后创建用户
5. 发送欢迎邮件
6. 自动登录并跳转到品牌添加页
异常处理:
| 异常场景 |
处理方式 |
| 邮箱已被注册 |
提示"该邮箱已注册",引导登录 |
| 验证码错误 |
提示"验证码错误",可重新发送 |
| 验证码过期 |
提示"验证码已过期",自动重新发送 |
| 密码不符合要求 |
实时显示密码强度提示 |
2.1.2 用户登录
| 属性 |
内容 |
| 需求ID |
F-AUTH-002 |
| 需求名称 |
用户登录 |
| 优先级 |
P0 |
| 描述 |
已注册用户可以登录平台 |
详细规格:
| 字段 |
类型 |
必填 |
验证规则 |
| 邮箱 |
string |
是 |
邮箱格式 |
| 密码 |
string |
是 |
8-32字符 |
| 记住我 |
boolean |
否 |
勾选后30天免登录 |
登录方式:
业务流程:
1. 用户输入邮箱和密码
2. 系统验证凭证
3. 验证通过后签发JWT Token
4. 跳转到大屏中心
异常处理:
| 异常场景 |
处理方式 |
| 邮箱未注册 |
提示"该邮箱未注册",引导注册 |
| 密码错误 |
提示"密码错误",剩余次数显示 |
| 账户被禁用 |
提示"账户已被禁用",联系客服 |
| 登录过于频繁 |
15分钟后重试,限流5次/分钟 |
2.1.3 密码重置
| 属性 |
内容 |
| 需求ID |
F-AUTH-003 |
| 需求名称 |
密码重置 |
| 优先级 |
P1 |
业务流程:
1. 用户输入注册邮箱
2. 系统发送重置链接到邮箱
3. 用户点击链接(有效期24小时)
4. 用户输入新密码
5. 系统更新密码
6. 登录页提示"密码已重置"
2.2 品牌管理模块 (F-BRAND)
2.2.1 添加品牌
| 属性 |
内容 |
| 需求ID |
F-BRAND-001 |
| 需求名称 |
添加品牌 |
| 优先级 |
P0 |
| 用户故事 |
US-001 |
| 描述 |
用户可以添加要监控的品牌 |
详细规格:
| 字段 |
类型 |
必填 |
验证规则 |
来源依据 |
| 品牌名称 |
string |
是 |
2-50字符,唯一 |
用户输入 |
| 品牌别名 |
string[] |
否 |
每个2-20字符,最多10个 |
用户输入 |
| 官方网站 |
string |
否 |
URL格式 |
用户输入 |
| 所属行业 |
enum |
否 |
预定义行业列表 |
用户选择 |
| 监控平台 |
string[] |
是 |
至少选择1个,最多7个 |
用户选择 |
支持的AI平台:
业务流程:
1. 用户点击"添加品牌"按钮
2. 填写品牌基本信息
3. 选择要监控的AI平台
4. 设置查询频率(每日/每周/每月)
5. 点击"确认添加"
6. 系统创建品牌记录
7. 触发首次数据采集
8. 跳转到品牌看板
约束条件:
- 免费用户最多添加1个品牌
- Pro用户最多添加5个品牌
- 品牌名称唯一性校验(不区分大小写)
2.2.2 编辑品牌
| 属性 |
内容 |
| 需求ID |
F-BRAND-002 |
| 需求名称 |
编辑品牌 |
| 优先级 |
P1 |
可编辑字段:
不可编辑字段:
2.2.3 删除品牌
| 属性 |
内容 |
| 需求ID |
F-BRAND-003 |
| 需求名称 |
删除品牌 |
| 优先级 |
P1 |
业务流程:
1. 用户点击"删除品牌"
2. 弹出确认对话框:"确定删除品牌 [名称]?此操作不可恢复。"
3. 用户确认删除
4. 级联删除该品牌的所有引用记录
5. 刷新品牌列表
2.2.4 竞品管理
| 属性 |
内容 |
| 需求ID |
F-BRAND-004 |
| 需求名称 |
竞品管理 |
| 优先级 |
P1 |
| 用户故事 |
US-003 |
详细规格:
| 字段 |
类型 |
必填 |
验证规则 |
| 竞品名称 |
string |
是 |
2-50字符 |
| 竞品别名 |
string[] |
否 |
每个2-20字符 |
约束条件:
- 每个品牌最多添加5个竞品
- 竞品名称不能与己方品牌重复
2.3 数据采集模块 (F-DATA)
2.3.1 定时数据采集
| 属性 |
内容 |
| 需求ID |
F-DATA-001 |
| 需求名称 |
定时数据采集 |
| 优先级 |
P0 |
| 描述 |
系统按照用户设定的频率自动采集数据 |
采集频率:
| 频率 |
说明 |
技术实现 |
| 每日 |
每天凌晨2点执行 |
APScheduler每日触发 |
| 每周 |
每周一凌晨2点执行 |
APScheduler周触发 |
| 每月 |
每月1日凌晨2点执行 |
APScheduler月触发 |
采集流程:
1. 调度器扫描所有待采集品牌
2. 按品牌生成查询任务
3. 遍历各AI平台适配器
4. 构造Prompt并调用平台API
5. 解析响应,提取引用信息
6. 计算品牌匹配得分
7. 存储引用记录
8. 更新品牌下次采集时间
错误处理:
| 错误类型 |
处理方式 |
重试策略 |
| 平台API超时 |
记录错误,继续其他平台 |
3次重试,间隔5分钟 |
| 平台返回错误 |
记录错误码,跳过该平台 |
不重试 |
| 网络中断 |
暂停采集,告警通知 |
恢复后继续 |
| 配额超限 |
暂停采集,记录日志 |
次日重试 |
2.3.2 手动立即查询
| 属性 |
内容 |
| 需求ID |
F-DATA-002 |
| 需求名称 |
手动立即查询 |
| 优先级 |
P0 |
| 用户故事 |
US-002 |
业务流程:
1. 用户点击品牌看板的"立即查询"按钮
2. 选择要查询的平台(默认全部)
3. 点击"确认"
4. 显示执行进度条
5. 实时显示各平台执行状态
6. 执行完成后刷新看板数据
限流规则:
- 免费用户: 10次/天
- Pro用户: 100次/天
- 超过限制提示升级
2.3.3 数据清洗与标准化
| 属性 |
内容 |
| 需求ID |
F-DATA-003 |
| 需求名称 |
数据清洗与标准化 |
| 优先级 |
P0 |
处理流程:
-
原始响应清洗
- 移除控制字符
- 截断超长文本(保留前10000字符)
- 编码转换(统一UTF-8)
-
品牌匹配检测
匹配流程:
1. 精确匹配: 品牌名称完整出现在文本中
2. 别名匹配: 任意别名出现在文本中
3. 模糊匹配: 相似度 > 0.4 的候选词
4. 返回匹配结果: cited, confidence, match_type, position
-
竞品检测
2.4 分析引擎模块 (F-ANALYTICS)
2.4.1 AI曝光度评分
| 属性 |
内容 |
| 需求ID |
F-ANALYTICS-001 |
| 需求名称 |
AI曝光度评分 |
| 优先级 |
P0 |
| 用户故事 |
US-001 |
| 参考依据 |
Visibili.ai评分模型 |
评分公式:
综合评分 = MIN(100, 提及率得分 × 0.3 + SOV得分 × 0.4 + 引用质量得分 × 0.3)
其中:
- 提及率得分 = (品牌被引用次数 / 查询总次数) × 100 → 范围: 0-100
- SOV得分 = (品牌引用次数 / (品牌+所有竞品引用次数)) × 100 → 范围: 0-100
- 引用质量得分 = (情感系数 × 0.4 + 位置系数 × 0.3 + 长度系数 × 0.3) × 100 → 范围: 0-100
情感系数:
- 正面: 1.0
- 中性: 0.6
- 负面: 0.2
位置系数:
- 第1位: 1.0
- 第2-3位: 0.8
- 第4-5位: 0.6
- 5位以后: 0.4
长度系数:
- 引用文本 > 100字: 1.0
- 引用文本 50-100字: 0.8
- 引用文本 < 50字: 0.6
计算示例:
假设:
- 查询总次数: 100次
- 品牌被引用次数: 60次 → 提及率得分 = 60/100 × 100 = 60
- 品牌引用次数: 60, 竞品引用次数: 40 → SOV得分 = 60/(60+40) × 100 = 60
- 引用质量得分: (1.0×0.4 + 0.8×0.3 + 0.8×0.3) × 100 = 72
综合评分 = MIN(100, 60×0.3 + 60×0.4 + 72×0.3) = MIN(100, 63.6) = 63.6 ≈ 64分
评分展示:
- 综合评分: 0-100整数
- 平台评分: 0-100整数
- 趋势: 较昨日/上周/上月变化
2.4.2 竞品对比分析
| 属性 |
内容 |
| 需求ID |
F-ANALYTICS-002 |
| 需求名称 |
竞品对比分析 |
| 优先级 |
P1 |
| 用户故事 |
US-003 |
分析维度:
| 维度 |
计算方式 |
展示形式 |
| 综合评分对比 |
各方综合评分差值 |
雷达图 |
| 平台分别对比 |
各平台评分差值 |
柱状图 |
| 趋势对比 |
30天评分变化趋势 |
折线图 |
| 份额对比 |
SOV占比 |
饼图 |
2.4.3 数据统计
| 属性 |
内容 |
| 需求ID |
F-ANALYTICS-003 |
| 需求名称 |
数据统计 |
| 优先级 |
P1 |
统计指标:
| 指标 |
说明 |
计算方式 |
| 总查询次数 |
累计查询次数 |
COUNT(*) |
| 总引用次数 |
被引用次数 |
SUM(cited=1) |
| 今日引用数 |
今日被引用 |
COUNT(*) WHERE date=today |
| 平均评分 |
历史平均评分 |
AVG(score) |
| 最高评分 |
历史最高评分 |
MAX(score) |
| 最低评分 |
历史最低评分 |
MIN(score) |
2.5 报告模块 (F-REPORT)
2.5.1 报告生成
| 属性 |
内容 |
| 需求ID |
F-REPORT-001 |
| 需求名称 |
报告生成 |
| 优先级 |
P1 |
| 用户故事 |
US-004 |
报告类型:
| 类型 |
内容 |
生成频率 |
| 仪表盘快照 |
关键指标截图 |
随时 |
| 周报 |
本周数据汇总 |
每周一自动 |
| 月报 |
月度分析与建议 |
每月1日自动 |
| 竞品分析 |
竞品动态 |
按需 |
报告内容:
PDF报告结构:
├── 执行摘要
│ ├── 综合评分
│ ├── 环比变化
│ └── 关键洞察
├── 品牌曝光度分析
│ ├── 各平台评分
│ ├── 引用趋势
│ └── 情感分布
├── 竞品对比
│ ├── 综合对比
│ ├── 平台对比
│ └── 差距分析
├── 引用详情
│ ├── 引用片段
│ ├── 引用位置
│ └── 情感倾向
└── 优化建议
├── 短期建议
└── 长期建议
2.5.2 报告导出
| 属性 |
内容 |
| 需求ID |
F-REPORT-002 |
| 需求名称 |
报告导出 |
| 优先级 |
P1 |
导出格式:
| 格式 |
适用场景 |
文件名格式 |
| PDF |
正式汇报 |
{brand}report{date}.pdf |
| CSV |
数据分析 |
{brand}data{date}.csv |
| PNG |
截图分享 |
{brand}snapshot{date}.png |
2.6 预警模块 (F-ALERT)
2.6.1 预警规则配置
| 属性 |
内容 |
| 需求ID |
F-ALERT-001 |
| 需求名称 |
预警规则配置 |
| 优先级 |
P2 |
预警类型:
| 类型 |
触发条件 |
通知方式 |
| 评分骤降 |
综合评分下降 > 20 |
邮件 |
| 竞品超越 |
竞品评分 > 己方评分 |
邮件 |
| 数据异常 |
单日引用量为0 |
邮件 |
| 查询失败 |
连续3次查询失败 |
邮件 |
配置项:
| 配置项 |
说明 |
默认值 |
| 评分骤降阈值 |
百分比 |
20% |
| 预警通知邮箱 |
接收邮箱 |
用户注册邮箱 |
| 预警开关 |
启用/禁用 |
启用 |
2.7 系统管理模块 (F-SYSTEM)
2.7.1 用户管理
| 属性 |
内容 |
| 需求ID |
F-SYSTEM-001 |
| 需求名称 |
用户管理 |
| 优先级 |
P0 |
功能点:
| 功能 |
说明 |
| 个人信息 |
查看/编辑昵称、手机号 |
| 修改密码 |
原密码+新密码+确认密码 |
| 套餐信息 |
查看当前套餐、用量统计 |
| 注销账户 |
30天冷静期后生效 |
2.7.2 套餐管理
| 属性 |
内容 |
| 需求ID |
F-SYSTEM-002 |
| 需求名称 |
套餐管理 |
| 优先级 |
P1 |
套餐规格:
| 套餐 |
价格 |
品牌数 |
竞品数/品牌 |
每日查询 |
报告导出 |
| Free |
¥0 |
1 |
2 |
5 |
1份/周 |
| Pro |
¥999/月 |
5 |
5 |
100 |
不限 |
| Enterprise |
¥2999/月 |
无限 |
10 |
不限 |
不限 |
3. 接口需求规格
3.1 API设计原则
| 原则 |
说明 |
| RESTful |
使用标准HTTP方法 |
| JSON格式 |
请求/响应均为JSON |
| 版本控制 |
URL包含版本号 /api/v1/ |
| 认证 |
Bearer Token |
| 限流 |
全局100次/分钟 |
3.2 认证接口
3.2.1 用户注册
POST /api/v1/auth/register
Request:
{
"email": "user@example.com",
"password": "Password123",
"confirm_password": "Password123",
"code": "123456"
}
Response 201:
{
"id": "uuid",
"email": "user@example.com",
"name": null,
"plan": "free",
"created_at": "2026-05-01T00:00:00Z"
}
3.2.2 用户登录
POST /api/v1/auth/login
Request:
{
"email": "user@example.com",
"password": "Password123"
}
Response 200:
{
"access_token": "eyJhbG...",
"token_type": "bearer",
"expires_in": 86400,
"user": {
"id": "uuid",
"email": "user@example.com",
"name": "张三",
"plan": "free"
}
}
3.2.3 获取当前用户
GET /api/v1/auth/me
Headers:
Authorization: Bearer {token}
Response 200:
{
"id": "uuid",
"email": "user@example.com",
"name": "张三",
"plan": "pro",
"max_queries": 100,
"is_admin": false
}
3.3 品牌接口
3.3.1 品牌列表
GET /api/v1/brands/
Headers:
Authorization: Bearer {token}
Query:
skip: int (default 0)
limit: int (default 20, max 100)
Response 200:
{
"items": [
{
"id": "uuid",
"name": "示例品牌",
"aliases": ["示例", "example"],
"platforms": ["wenxin", "kimi"],
"frequency": "daily",
"status": "active",
"score": 78,
"last_queried_at": "2026-05-01T00:00:00Z",
"next_query_at": "2026-05-02T00:00:00Z"
}
],
"total": 1
}
3.3.2 创建品牌
POST /api/v1/brands/
Headers:
Authorization: Bearer {token}
Request:
{
"name": "示例品牌",
"aliases": ["示例", "example"],
"website": "https://example.com",
"industry": "technology",
"platforms": ["wenxin", "kimi"],
"frequency": "daily"
}
Response 201:
{
"id": "uuid",
"name": "示例品牌",
"aliases": ["示例", "example"],
"platforms": ["wenxin", "kimi"],
"frequency": "daily",
"status": "active",
"created_at": "2026-05-01T00:00:00Z"
}
3.3.3 品牌详情
GET /api/v1/brands/{brand_id}/
Headers:
Authorization: Bearer {token}
Response 200:
{
"id": "uuid",
"name": "示例品牌",
"aliases": ["示例", "example"],
"website": "https://example.com",
"industry": "technology",
"platforms": ["wenxin", "kimi", "tongyi"],
"frequency": "daily",
"status": "active",
"score": {
"overall": 78,
"wenxin": 85,
"kimi": 72,
"tongyi": 68
},
"competitors": [
{
"id": "uuid",
"name": "竞品A",
"score": 65
}
],
"last_queried_at": "2026-05-01T00:00:00Z",
"next_query_at": "2026-05-02T00:00:00Z"
}
3.3.4 立即查询
POST /api/v1/brands/{brand_id}/query/
Headers:
Authorization: Bearer {token}
Request:
{
"platforms": ["wenxin", "kimi"] // 可选,默认全部
}
Response 202:
{
"task_id": "uuid",
"status": "pending",
"message": "查询任务已加入队列"
}
3.4 竞品接口
3.4.1 竞品列表
GET /api/v1/brands/{brand_id}/competitors/
Response 200:
{
"items": [
{
"id": "uuid",
"name": "竞品A",
"aliases": ["别名"],
"score": 65,
"last_queried_at": "2026-05-01T00:00:00Z"
}
],
"total": 1
}
3.4.2 添加竞品
POST /api/v1/brands/{brand_id}/competitors/
Request:
{
"name": "竞品A",
"aliases": ["别名"]
}
Response 201:
{
"id": "uuid",
"name": "竞品A",
"aliases": ["别名"]
}
3.5 引用记录接口
3.5.1 引用记录列表
GET /api/v1/citations/
Headers:
Authorization: Bearer {token}
Query:
brand_id: uuid (optional)
platform: string (optional)
start_date: ISO date (optional)
end_date: ISO date (optional)
skip: int (default 0)
limit: int (default 20, max 100)
Response 200:
{
"items": [
{
"id": "uuid",
"brand_id": "uuid",
"platform": "wenxin",
"cited": true,
"citation_text": "示例品牌是...",
"position": 1,
"sentiment": "positive",
"competitor_brands": ["竞品A"],
"queried_at": "2026-05-01T00:00:00Z"
}
],
"total": 100
}
3.5.2 引用统计
GET /api/v1/citations/stats/
Headers:
Authorization: Bearer {token}
Query:
brand_id: uuid (optional)
Response 200:
{
"total_queries": 1000,
"total_citations": 350,
"citation_rate": 35.0,
"platform_breakdown": {
"wenxin": {"queries": 150, "citations": 60, "rate": 40.0},
"kimi": {"queries": 150, "citations": 45, "rate": 30.0}
},
"sentiment_breakdown": {
"positive": 200,
"neutral": 120,
"negative": 30
},
"trend": [
{"date": "2026-04-01", "score": 72},
{"date": "2026-04-02", "score": 75}
]
}
3.6 报告接口
3.6.1 导出CSV
GET /api/v1/reports/export/csv?brand_id={brand_id}&start_date={date}&end_date={date}
Headers:
Authorization: Bearer {token}
Response 200:
Content-Type: text/csv
Content-Disposition: attachment; filename="brand_data_2026-05-01.csv"
3.6.2 导出PDF
GET /api/v1/reports/export/pdf?brand_id={brand_id}&type={weekly|monthly|custom}
Headers:
Authorization: Bearer {token}
Response 200:
Content-Type: application/pdf
Content-Disposition: attachment; filename="brand_report_2026-05-01.pdf"
4. 数据需求规格
4.1 数据实体设计
4.1.1 User (用户)
| 字段名 |
类型 |
约束 |
说明 |
| id |
UUID |
PK |
主键 |
| email |
VARCHAR(255) |
UNIQUE, NOT NULL |
邮箱 |
| password_hash |
VARCHAR(255) |
NOT NULL |
密码哈希 |
| name |
VARCHAR(100) |
NULL |
昵称 |
| plan |
VARCHAR(20) |
DEFAULT 'free' |
套餐 |
| max_queries |
INT |
DEFAULT 5 |
最大查询数 |
| is_active |
BOOLEAN |
DEFAULT TRUE |
账户状态 |
| email_verified |
BOOLEAN |
DEFAULT FALSE |
邮箱验证 |
| verification_code |
VARCHAR(6) |
NULL |
验证码 |
| reset_token |
VARCHAR(255) |
NULL |
重置令牌 |
| created_at |
TIMESTAMP |
NOT NULL |
创建时间 |
| updated_at |
TIMESTAMP |
NOT NULL |
更新时间 |
4.1.2 Brand (品牌)
| 字段名 |
类型 |
约束 |
说明 |
| id |
UUID |
PK |
主键 |
| user_id |
UUID |
FK(users.id), NOT NULL |
所属用户 |
| name |
VARCHAR(50) |
UNIQUE, NOT NULL |
品牌名称 |
| aliases |
JSON |
DEFAULT [] |
品牌别名 |
| website |
VARCHAR(500) |
NULL |
官网 |
| industry |
VARCHAR(50) |
NULL |
行业 |
| platforms |
JSON |
NOT NULL |
监控平台 |
| frequency |
VARCHAR(20) |
DEFAULT 'weekly' |
查询频率 |
| status |
VARCHAR(20) |
DEFAULT 'active' |
状态 |
| last_queried_at |
TIMESTAMP |
NULL |
上次查询 |
| next_query_at |
TIMESTAMP |
NULL |
下次查询 |
| created_at |
TIMESTAMP |
NOT NULL |
创建时间 |
| updated_at |
TIMESTAMP |
NOT NULL |
更新时间 |
索引:
- idx_brands_user_id
- idx_brands_status
4.1.3 Competitor (竞品)
| 字段名 |
类型 |
约束 |
说明 |
| id |
UUID |
PK |
主键 |
| brand_id |
UUID |
FK(brands.id), NOT NULL |
所属品牌 |
| name |
VARCHAR(50) |
NOT NULL |
竞品名称 |
| aliases |
JSON |
DEFAULT [] |
竞品别名 |
| created_at |
TIMESTAMP |
NOT NULL |
创建时间 |
索引:
4.1.4 CitationRecord (引用记录)
| 字段名 |
类型 |
约束 |
说明 |
| id |
UUID |
PK |
主键 |
| brand_id |
UUID |
FK(brands.id), NOT NULL |
所属品牌 |
| platform |
VARCHAR(50) |
NOT NULL |
平台 |
| cited |
BOOLEAN |
NOT NULL |
是否引用 |
| citation_text |
TEXT |
NULL |
引用文本 |
| citation_position |
INT |
NULL |
引用位置 |
| sentiment |
VARCHAR(20) |
NULL |
情感倾向 |
| competitor_brands |
JSON |
DEFAULT [] |
竞品列表 |
| raw_response |
TEXT |
NULL |
原始响应 |
| confidence |
FLOAT |
NULL |
置信度 |
| match_type |
VARCHAR(20) |
NULL |
匹配类型 |
| queried_at |
TIMESTAMP |
NOT NULL |
查询时间 |
索引:
- idx_citations_brand_id
- idx_citations_platform
- idx_citations_queried_at
4.1.5 QueryTask (查询任务)
| 字段名 |
类型 |
约束 |
说明 |
| id |
UUID |
PK |
主键 |
| brand_id |
UUID |
FK(brands.id), NOT NULL |
所属品牌 |
| platform |
VARCHAR(50) |
NOT NULL |
平台 |
| status |
VARCHAR(20) |
NOT NULL |
状态 |
| error_message |
TEXT |
NULL |
错误信息 |
| scheduled_at |
TIMESTAMP |
NOT NULL |
计划时间 |
| started_at |
TIMESTAMP |
NULL |
开始时间 |
| completed_at |
TIMESTAMP |
NULL |
完成时间 |
索引:
- idx_query_tasks_brand_id
- idx_query_tasks_status
4.2 数据保留策略
| 数据类型 |
保留期限 |
处理方式 |
| 引用记录 |
2年 |
2年前的记录归档到冷存储 |
| 查询任务 |
90天 |
90天后删除 |
| 用户行为日志 |
180天 |
180天后删除 |
| 审计日志 |
1年 |
1年后归档 |
5. 非功能需求规格
5.1 性能需求
| 指标 |
目标值 |
说明 |
| 页面首次加载 (FCP) |
< 3秒 |
Dashboard首屏 |
| API平均响应时间 |
< 200ms |
查询类接口 |
| API P99响应时间 |
< 500ms |
查询类接口 |
| 并发用户数 |
1000+ |
v1.0目标 |
| 数据采集延迟 |
< 24小时 |
定时任务完成后 |
5.2 可用性需求
| 指标 |
目标值 |
说明 |
| 系统可用性 |
99.5% |
月度计算 |
| 故障恢复时间 (MTTR) |
< 4小时 |
平均恢复时间 |
| 故障间隔时间 (MTBF) |
> 720小时 |
30天内 |
| 数据备份 |
每日全量 |
保留30天 |
5.3 安全需求
| 需求 |
实现方式 |
| 传输加密 |
TLS 1.2+ |
| 密码存储 |
bcrypt |
| 会话管理 |
JWT,24小时过期 |
| 访问控制 |
RBAC |
| 数据隔离 |
租户级逻辑隔离 |
| SQL注入防护 |
参数化查询 |
| XSS防护 |
输出编码 |
| CSRF防护 |
Token验证 |
5.4 兼容性需求
| 类型 |
要求 |
| 浏览器 |
Chrome/Firefox/Safari/Edge 最近2个版本 |
| 移动端 |
响应式,支持1024px+ |
| API版本 |
保持v1版本兼容2年 |
6. 约束条件
6.1 技术约束
| 约束项 |
说明 |
| 技术栈 |
现有Python FastAPI + Next.js不可变更 |
| 数据库 |
PostgreSQL + Redis |
| 部署方式 |
Docker Compose |
6.2 时间约束
| 里程碑 |
截止日期 |
| v1.0 MVP完成 |
2026-Q2末 |
6.3 资源约束
| 资源 |
限制 |
| 开发团队 |
5人 |
| 服务器成本 |
< ¥10万/月 |
7. 需求追踪矩阵
7.1 需求-用户故事追踪
| 需求ID |
用户故事 |
功能模块 |
优先级 |
状态 |
| F-AUTH-001 |
- |
认证模块 |
P0 |
待开发 |
| F-AUTH-002 |
- |
认证模块 |
P0 |
待开发 |
| F-AUTH-003 |
- |
认证模块 |
P1 |
待开发 |
| F-BRAND-001 |
US-001 |
品牌管理 |
P0 |
待开发 |
| F-BRAND-002 |
- |
品牌管理 |
P1 |
待开发 |
| F-BRAND-003 |
- |
品牌管理 |
P1 |
待开发 |
| F-BRAND-004 |
US-003 |
竞品管理 |
P1 |
待开发 |
| F-DATA-001 |
US-002 |
数据采集 |
P0 |
待开发 |
| F-DATA-002 |
US-002 |
数据采集 |
P0 |
待开发 |
| F-DATA-003 |
- |
数据采集 |
P0 |
待开发 |
| F-ANALYTICS-001 |
US-001 |
分析引擎 |
P0 |
待开发 |
| F-ANALYTICS-002 |
US-003 |
分析引擎 |
P1 |
待开发 |
| F-ANALYTICS-003 |
- |
分析引擎 |
P1 |
待开发 |
| F-REPORT-001 |
US-004 |
报告模块 |
P1 |
待开发 |
| F-REPORT-002 |
US-004 |
报告模块 |
P1 |
待开发 |
| F-ALERT-001 |
- |
预警模块 |
P2 |
待开发 |
| F-SYSTEM-001 |
- |
系统管理 |
P0 |
待开发 |
7.2 需求-接口追踪
| 需求ID |
对应API端点 |
方法 |
| F-AUTH-001 |
/api/v1/auth/register |
POST |
| F-AUTH-002 |
/api/v1/auth/login |
POST |
| F-AUTH-003 |
/api/v1/auth/forgot-password |
POST |
| F-BRAND-001 |
/api/v1/brands/ |
POST |
| F-BRAND-002 |
/api/v1/brands/{id} |
PUT |
| F-BRAND-003 |
/api/v1/brands/{id} |
DELETE |
| F-BRAND-004 |
/api/v1/brands/{id}/competitors/ |
POST |
| F-DATA-002 |
/api/v1/brands/{id}/query/ |
POST |
| F-ANALYTICS-001 |
/api/v1/citations/stats/ |
GET |
| F-ANALYTICS-002 |
/api/v1/analytics/compare/ |
GET |
| F-REPORT-001 |
/api/v1/reports/generate/ |
POST |
| F-REPORT-002 |
/api/v1/reports/export/{format} |
GET |
8. 附录
8.1 错误码定义
| 错误码 |
HTTP状态码 |
说明 |
| AUTH_001 |
400 |
邮箱格式错误 |
| AUTH_002 |
409 |
邮箱已被注册 |
| AUTH_003 |
401 |
认证失败 |
| AUTH_004 |
403 |
账户已被禁用 |
| BRAND_001 |
404 |
品牌不存在 |
| BRAND_002 |
400 |
品牌数量超限 |
| BRAND_003 |
409 |
品牌名称重复 |
| QUERY_001 |
429 |
查询次数超限 |
| QUERY_002 |
500 |
平台API调用失败 |
8.2 变更记录
| 版本 |
日期 |
变更内容 |
作者 |
| v1.0 |
2026-05-01 |
初稿创建 |
GEO产品团队 |
审批签名:
| 角色 |
姓名 |
日期 |
签名 |
| 产品负责人 |
|
|
|
| 技术负责人 |
|
|
|
| 测试负责人 |
|
|
|