Files
SuperBizAgent-java/openspec/changes/phase-1-infrastructure/specs/functional-specs.md
T
zhuyongxin 3f15778b28 docs: 添加 Phase 1 完整实施计划和 OpenSpec
- 添加项目级 CLAUDE.md 和 AGENTS.md 配置
- 添加完整实施计划(docs/architecture/implementation-detail.md)
- 创建 OpenSpec phase-1-infrastructure:
  - proposal.md: 需求和方案
  - design.md: 架构设计
  - specs/functional-specs.md: 功能规格
  - tasks.md: 21 个任务清单
  - decisions.md: grill 阶段决策记录
  - .commit: 标记为 Committed OpenSpec

OpenSpec 已通过 sm-flow 完整流程(clarify → context → propose → grill → specify → audit → commit)
2026-06-23 10:58:11 +08:00

313 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Phase 1 Infrastructure - Specifications
## 功能规格
### 1. 数据库表创建
#### 1.1 diagnosis_record 表
**输入**:Flyway 迁移脚本 V001
**输出**:MySQL 表创建成功
**验收标准**:
- ✅ 表结构与 docs/tables/diagnosis_record.md 一致
- ✅ 所有索引创建成功
- ✅ JSON 字段类型正确
- ✅ 默认值和注释完整
#### 1.2 case_library 表
**输入**:Flyway 迁移脚本 V002
**输出**:MySQL 表创建成功
**验收标准**:
- ✅ 表结构与 docs/tables/case_library.md 一致
- ✅ 外键约束正确
- ✅ 索引覆盖查询场景
#### 1.3 api_document 表
**输入**:Flyway 迁移脚本 V003
**输出**:MySQL 表创建成功
**验收标准**:
- ✅ 表结构与 docs/tables/api_document.md 一致
- ✅ province 和 category 索引就绪
---
### 2. JPA 实体与 Repository
#### 2.1 DiagnosisRecord 实体
**字段映射**:
- `@Id @GeneratedValue` - id
- `@Column(unique=true)` - diagnosis_id
- `@JdbcTypeCode(SqlTypes.JSON)` - tool_calls
- `@Enumerated(EnumType.STRING)` - fault_category, status
- `LocalDateTime` - created_at, updated_at
**验收标准**:
- ✅ 所有字段与数据库一致
- ✅ JSON 字段序列化正确
- ✅ 枚举映射正确
- ✅ Lombok 注解完整
#### 2.2 Repository 查询方法
**DiagnosisRecordRepository**:
```java
Optional<DiagnosisRecord> findByDiagnosisId(String diagnosisId);
Optional<DiagnosisRecord> findByBusinessId(String businessId);
Optional<DiagnosisRecord> findByTraceId(String traceId);
List<DiagnosisRecord> findByFaultCategoryAndErrorCode(
FaultCategory category, String errorCode);
Page<DiagnosisRecord> findByCreatedAtBetween(
LocalDateTime start, LocalDateTime end, Pageable pageable);
```
**验收标准**:
- ✅ 单元测试通过(@DataJpaTest + H2)
- ✅ 分页查询正确
- ✅ 复杂查询性能可接受(< 100ms)
---
### 3. Redis 会话管理
#### 3.1 SessionManager 接口
```java
public interface SessionManager {
SessionContext get(String sessionId);
void save(SessionContext context);
void delete(String sessionId);
boolean exists(String sessionId);
}
```
#### 3.2 RedisSessionManager 实现
**存储格式**:
- Key: `session:{sessionId}`
- Value: SessionContext 的 JSON 字符串
- TTL: 1800 秒(30 分钟)
**异常处理**:
- Redis 连接失败 → 抛出 RedisConnectionException
- 序列化失败 → 抛出 SessionSerializationException
- Session 不存在 → 返回 null(get 方法)
**验收标准**:
- ✅ 存取删操作成功
- ✅ TTL 自动刷新(每次 get/save)
- ✅ JSON 序列化/反序列化正确
- ✅ 单元测试覆盖(Mock RedisTemplate)
---
### 4. 文档管理
#### 4.1 文档上传接口
**接口**:`POST /api/documents/upload`
**请求**:
```json
{
"file": "multipart/form-data",
"province": "广东",
"category": "社保接口"
}
```
**响应**:
```json
{
"code": 200,
"message": "上传成功",
"data": {
"documentId": "uuid",
"fileName": "社保接口文档.docx",
"chunkCount": 12
}
}
```
**处理流程**:
1. 文件类型校验(.txt, .md, .docx, .pdf)
2. 文本提取
3. 分块(chunk_size=500, overlap=50)
4. DashScope 向量化
5. MySQL 存元数据
6. Milvus 存向量
**错误处理**:
- 文件类型不支持 → 400 Bad Request
- 文件大小超限(10MB) → 413 Payload Too Large
- 向量化失败 → 500 Internal Server Error(回滚 MySQL)
**验收标准**:
- ✅ 支持 .txt, .md, .docx, .pdf
- ✅ MySQL + Milvus 事务一致
- ✅ 单元测试覆盖
#### 4.2 文档查询接口
**接口**:`GET /api/documents?province=广东&category=社保接口&page=0&size=10`
**响应**:
```json
{
"code": 200,
"data": {
"content": [
{
"documentId": "uuid",
"fileName": "社保接口文档.docx",
"province": "广东",
"category": "社保接口",
"createdAt": "2026-06-23T10:00:00"
}
],
"totalElements": 1,
"totalPages": 1
}
}
```
**验收标准**:
- ✅ 分页正确
- ✅ 过滤生效
- ✅ 性能可接受(< 100ms)
#### 4.3 文档删除接口
**接口**:`DELETE /api/documents/{documentId}`
**响应**:
```json
{
"code": 200,
"message": "删除成功"
}
```
**处理流程**:
1. 删除 MySQL 记录
2. 根据 document_id 删除 Milvus 向量
**事务性**:
- MySQL 删除失败 → 不删除 Milvus
- Milvus 删除失败 → 记录日志(容忍)
**验收标准**:
- ✅ MySQL 记录删除
- ✅ Milvus 向量删除
- ✅ 幂等性(重复删除不报错)
#### 4.4 混合检索工具
**接口**:`DocumentSearchTool.search(errorCode, province)`
**输入**:
```java
{
"errorCode": "40003",
"province": "广东"
}
```
**输出**:
```java
List<DocumentChunk> {
"documentId": "uuid",
"chunkId": "uuid",
"content": "错误码 40003 表示...",
"score": 0.95
}
```
**检索策略**:
1. **精确匹配**(MySQL):
```sql
SELECT * FROM api_document
WHERE error_code = '40003' AND province = '广东'
```
2. **语义检索**(Milvus):
- 向量化查询文本
- 相似度搜索 Top 10
3. **RRF 融合**:
- 精确匹配分数 = 1.0
- 语义检索分数 = Milvus 相似度
- 合并排序,返回 Top 3
**验收标准**:
- ✅ 精确匹配优先
- ✅ 语义检索补漏
- ✅ 返回 Top 3
- ✅ 单元测试覆盖
---
## 接口规格
### API 设计原则
- RESTful 风格
- 统一响应格式 `Result<T>`
- HTTP 状态码语义化
- 异常统一处理
### 统一响应格式
```java
class Result<T> {
int code; // 业务状态码
String message; // 提示信息
T data; // 数据
long timestamp; // 时间戳
}
```
### 错误码约定
- 200: 成功
- 400: 参数错误
- 404: 资源不存在
- 500: 服务器错误
---
## 性能规格
### 响应时间要求
- 文档上传:< 5s(单文件 < 5MB)
- 文档查询:< 100ms
- 文档删除:< 200ms
- 混合检索:< 500ms
- Repository 查询:< 50ms
### 并发要求
- 支持 10 QPS(Phase 1 目标)
- 后续扩展至 100 QPS(Phase 2/3)
---
## 安全规格
### 输入校验
- 文件类型白名单
- 文件大小限制(10MB)
- SQL 注入防护(JPA Prepared Statement)
- XSS 防护(输入转义)
### 数据安全
- Redis 密码保护
- MySQL 用户权限最小化
- 敏感日志脱敏
---
## 测试规格
### 单元测试覆盖率
- Repository: 100%
- Service: 80%+
- Tool: 80%+
- Controller: 70%+
### 测试类型
- 单元测试(JUnit 5 + Mockito)
- 集成测试(@SpringBootTest)
- 接口测试(MockMvc)
### 必须覆盖的场景
- 正常流程
- 边界条件
- 异常处理
- 并发安全