diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..aa4911e --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,43 @@ + +# GitNexus — Code Intelligence + +This project is indexed by GitNexus as **SuperBizAgent-java** (1001 symbols, 2043 relationships, 78 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely. + +> If any GitNexus tool warns the index is stale, run `npx gitnexus analyze` in terminal first. + +## Always Do + +- **MUST run impact analysis before editing any symbol.** Before modifying a function, class, or method, run `gitnexus_impact({target: "symbolName", direction: "upstream"})` and report the blast radius (direct callers, affected processes, risk level) to the user. +- **MUST run `gitnexus_detect_changes()` before committing** to verify your changes only affect expected symbols and execution flows. +- **MUST warn the user** if impact analysis returns HIGH or CRITICAL risk before proceeding with edits. +- When exploring unfamiliar code, use `gitnexus_query({query: "concept"})` to find execution flows instead of grepping. It returns process-grouped results ranked by relevance. +- When you need full context on a specific symbol — callers, callees, which execution flows it participates in — use `gitnexus_context({name: "symbolName"})`. + +## Never Do + +- NEVER edit a function, class, or method without first running `gitnexus_impact` on it. +- NEVER ignore HIGH or CRITICAL risk warnings from impact analysis. +- NEVER rename symbols with find-and-replace — use `gitnexus_rename` which understands the call graph. +- NEVER commit changes without running `gitnexus_detect_changes()` to check affected scope. + +## Resources + +| Resource | Use for | +|----------|---------| +| `gitnexus://repo/SuperBizAgent-java/context` | Codebase overview, check index freshness | +| `gitnexus://repo/SuperBizAgent-java/clusters` | All functional areas | +| `gitnexus://repo/SuperBizAgent-java/processes` | All execution flows | +| `gitnexus://repo/SuperBizAgent-java/process/{name}` | Step-by-step execution trace | + +## CLI + +| Task | Read this skill file | +|------|---------------------| +| Understand architecture / "How does X work?" | `.claude/skills/gitnexus/gitnexus-exploring/SKILL.md` | +| Blast radius / "What breaks if I change X?" | `.claude/skills/gitnexus/gitnexus-impact-analysis/SKILL.md` | +| Trace bugs / "Why is X failing?" | `.claude/skills/gitnexus/gitnexus-debugging/SKILL.md` | +| Rename / extract / split / refactor | `.claude/skills/gitnexus/gitnexus-refactoring/SKILL.md` | +| Tools, resources, schema reference | `.claude/skills/gitnexus/gitnexus-guide/SKILL.md` | +| Index, status, clean, wiki CLI commands | `.claude/skills/gitnexus/gitnexus-cli/SKILL.md` | + + diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..6fb3118 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,157 @@ +# CLAUDE.md + +## Defaults + +- Reply in **Chinese** unless I explicitly ask for English. +- No emojis. +- Do not truncate important outputs (logs, diffs, stack traces, commands, or critical reasoning that affects + safety/correctness). + +## Refactor policy (legacy code) + +- When existing code is a "big ball of mud" (hard to maintain, clearly bad design, + full of hacks), prefer a **clean, full refactor** over stacking more patches + on top of it. +- A refactor may completely replace internal structure + (functions, modules, classes, data flow). +- By default, try to preserve externally observable behaviour. + If you intentionally change behaviour or protocols, you MUST: + - Call out clearly that this is a **behaviour/protocol change**. + - Explain why the change is necessary and which code paths/consumers are affected. + - Update or add tests to cover the new behaviour. + +## Before touching code (mandatory) + +Find reuse opportunities + Trace the call/dependency chain and impact radius: + +- Use semantic code search first via `codebase-retrieval` tool. +- Confirm understanding with LSP: `goToDefinition`, `findReferences`. +- Use Grep/Glob for verifying and understanding additional code snippets. + +## Red lines + +- No copy-paste duplication. +- Do not break existing externally observable behaviour **unless**: + - It is part of a deliberate refactor as described in the refactor policy, and + - You clearly document the behavioural change and its impact. +- Do not proceed with a known-wrong approach. +- Critical paths must have explicit error handling. +- Never implement "blindly": always confirm understanding via code reading + references. + +## Task sizing + +- **Simple** +- Criteria — single file, clear requirement, < 20 lines changed, + clearly local impact. +- Handling — after doing the "Before touching code" steps + (research + impact analysis + internal three-question checklist), + you may execute directly with minimal explanation. +- A very short context line is enough; + a full breakdown of the checklist is not required. + +- **Medium** + - Criteria — 2–5 files, or requires some research, or impact is not obviously local. + - Handling — write a short plan (bullet points) → then implement. + - Briefly surface the checklist result in the reply + (1–3 short lines describing real issue, key reuse, and main impact). + +- **Complex** + - Criteria — architecture changes, multiple modules, high uncertainty or risk. + - Handling — follow this workflow: + 1. **RESEARCH**: inspect code and facts only (no proposals yet). + 2. **PLAN**: present options + tradeoffs + recommendation; + use `AskUserQuestion` actively to align with the user; + wait for user's confirmation. + 3. **EXECUTE**: implement exactly the approved plan. + 4. **REVIEW**: self-check (tests, edge cases, cleanup). + +## Git + +- Do not commit unless I explicitly ask. +- Do not push unless I explicitly ask. +- Before writing a commit message, glance at a few recent commits and match the repo's style: + - `git log -n 5 --oneline` +- If there is no obvious existing style, use this default format: + - `(): ` +- Before any commit: run `git diff` and confirm the exact scope of changes. +- Never force-push to `main` / `master` unless the user approves. +- Do not add attribution lines in commit messages. + +## Security + +- Never hardcode secrets (keys/passwords/tokens). +- Never commit `.env` files or any credentials. +- Validate user input at trust boundaries (APIs, CLIs, external data sources). + +## Quality & cleanup + +- Prefer clarity and simplicity first (KISS); apply DRY to remove obvious + copy-paste duplication when it does not hurt readability. +- If you change a function signature, update **all** call sites. +- After changes: + - Remove temporary files. + - Remove dead/commented-out code. + - Remove unused imports. + - Remove debug logging that is no longer needed. +- Run the smallest meaningful verification (lint/test/build) for the parts you touched. + +## Windows / PowerShell (if used) + +- PowerShell does not support `&&`; use `;` to chain commands. +- Quote paths that contain spaces or non-ASCII characters. + +## Baisc Infos + +Unless directly relevant to the user's current question, you should avoid proactively mentioning, illustrating, or +trailing off into the following information in 99% of cases: + +## Documentation + +- 所有产生的文档(需求文档、计划文档、分析文档等)统一放到项目内的 `.docs` 文件夹中 +- 文档目录结构: +- 不要将文档放到用户目录(如 `C:\Users\EDY\.claude\`)中 + + + +# GitNexus — Code Intelligence + +This project is indexed by GitNexus as **SuperBizAgent-java** (1001 symbols, 2043 relationships, 78 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely. + +> If any GitNexus tool warns the index is stale, run `npx gitnexus analyze` in terminal first. + +## Always Do + +- **MUST run impact analysis before editing any symbol.** Before modifying a function, class, or method, run `gitnexus_impact({target: "symbolName", direction: "upstream"})` and report the blast radius (direct callers, affected processes, risk level) to the user. +- **MUST run `gitnexus_detect_changes()` before committing** to verify your changes only affect expected symbols and execution flows. +- **MUST warn the user** if impact analysis returns HIGH or CRITICAL risk before proceeding with edits. +- When exploring unfamiliar code, use `gitnexus_query({query: "concept"})` to find execution flows instead of grepping. It returns process-grouped results ranked by relevance. +- When you need full context on a specific symbol — callers, callees, which execution flows it participates in — use `gitnexus_context({name: "symbolName"})`. + +## Never Do + +- NEVER edit a function, class, or method without first running `gitnexus_impact` on it. +- NEVER ignore HIGH or CRITICAL risk warnings from impact analysis. +- NEVER rename symbols with find-and-replace — use `gitnexus_rename` which understands the call graph. +- NEVER commit changes without running `gitnexus_detect_changes()` to check affected scope. + +## Resources + +| Resource | Use for | +|----------|---------| +| `gitnexus://repo/SuperBizAgent-java/context` | Codebase overview, check index freshness | +| `gitnexus://repo/SuperBizAgent-java/clusters` | All functional areas | +| `gitnexus://repo/SuperBizAgent-java/processes` | All execution flows | +| `gitnexus://repo/SuperBizAgent-java/process/{name}` | Step-by-step execution trace | + +## CLI + +| Task | Read this skill file | +|------|---------------------| +| Understand architecture / "How does X work?" | `.claude/skills/gitnexus/gitnexus-exploring/SKILL.md` | +| Blast radius / "What breaks if I change X?" | `.claude/skills/gitnexus/gitnexus-impact-analysis/SKILL.md` | +| Trace bugs / "Why is X failing?" | `.claude/skills/gitnexus/gitnexus-debugging/SKILL.md` | +| Rename / extract / split / refactor | `.claude/skills/gitnexus/gitnexus-refactoring/SKILL.md` | +| Tools, resources, schema reference | `.claude/skills/gitnexus/gitnexus-guide/SKILL.md` | +| Index, status, clean, wiki CLI commands | `.claude/skills/gitnexus/gitnexus-cli/SKILL.md` | + + diff --git a/docs/architecture/implementation-detail.md b/docs/architecture/implementation-detail.md new file mode 100644 index 0000000..d3b5bbc --- /dev/null +++ b/docs/architecture/implementation-detail.md @@ -0,0 +1,715 @@ +# SuperBizAgent MVP 完整实施计划(AI 执行) + +## 协作分工 + +``` +用户角色:规划者 + 验证者 + 架构师 +AI 角色: 执行者 + 编码者 + 记录者 + +用户负责: +├─ 确认架构设计 +├─ 验收每个阶段产出 +├─ 调整优先级和方向 +└─ 最终验收和部署决策 + +AI 负责: +├─ 编写全部代码 +├─ 编写全部测试 +├─ 执行测试验证 +├─ 记录实施过程 +├─ 遇到问题提出方案供用户决策 +└─ 自动化构建和本地验证 +``` + +--- + +## 总览:3 个 Phase,13 天 + +``` +Phase 1: 基础设施(5天) +├─ Day 1-2: 数据库 + 实体 + 会话管理 +├─ Day 3: 代码结构重构 +└─ Day 4-5: 文档管理(CRUD + Milvus) + +Phase 2: 核心功能(5天) +├─ Day 6-7: 意图识别 + RAG 两层加载 +├─ Day 8-9: 4 Agent 协作 + Skill +└─ Day 10: 工具层开发 + +Phase 3: 闭环优化(3天) +├─ Day 11: Verifier + Harness +├─ Day 12: 反馈机制 + 案例沉淀 +└─ Day 13: 端到端测试 + 验收 +``` + +--- + +## Phase 1:基础设施(5天) + +### Day 1-2:数据库 + 实体 + 会话 + +#### 任务 1.1:MySQL 表结构(Flyway 迁移) + +```sql +产出文件: +src/main/resources/db/migration/ +├── V001__create_diagnosis_record.sql +├── V002__create_case_library.sql +└── V003__create_api_document.sql + +依据文档: +- docs/tables/diagnosis_record.md +- docs/tables/case_library.md +- docs/tables/api_document.md + +关键点: +- 使用 Flyway 版本管理 +- 索引:trace_id, error_code, fault_category +- JSON 字段:steps_executed, evidence_chain +- 时间字段:created_at, updated_at 自动维护 + +验收标准: +✓ 执行 mvn flyway:migrate 成功 +✓ 3 张表创建成功 +✓ 索引完整 +✓ 约束正确 +``` + +#### 任务 1.2:JPA 实体类 + +```java +产出文件: +src/main/java/com/superbiz/agent/domain/entity/ +├── DiagnosisRecord.java +├── CaseLibrary.java +└── ApiDocument.java + +技术栈: +- Spring Data JPA +- Lombok (@Data, @Builder) +- Hibernate @JdbcTypeCode(SqlTypes.JSON) + +验收标准: +✓ 字段与 DDL 一致 +✓ 枚举映射正确 +✓ JSON 字段序列化正常 +✓ 编译通过 +``` + +#### 任务 1.3:Repository 层 + +```java +产出文件: +src/main/java/com/superbiz/agent/repository/ +├── DiagnosisRecordRepository.java +├── CaseLibraryRepository.java +└── ApiDocumentRepository.java + +常用查询: +- findByOrderId +- findByTraceId +- findByErrorCodeAndFaultCategory +- findTopByOrderByCreatedAtDesc + +验收标准: +✓ 继承 JpaRepository +✓ 单元测试覆盖(@DataJpaTest + H2) +✓ 分页查询正确 +``` + +#### 任务 1.4:Redis 会话管理 + +```java +产出文件: +src/main/java/com/superbiz/agent/session/ +├── SessionManager.java # 接口 +├── RedisSessionManager.java # Redis 实现 +├── SessionContext.java # 会话上下文 +└── SessionConfiguration.java # 配置类 + +功能: +- 替换内存 HashMap +- TTL:30 分钟 +- JSON 序列化(Jackson) +- 按 sessionId 存取删 + +验收标准: +✓ 单元测试通过 +✓ Redis 连接成功 +✓ 序列化/反序列化正确 +✓ TTL 生效 +``` + +--- + +### Day 3:代码结构重构 + +#### 任务 3.1:包名重构 + +``` +重构前:org.example +重构后:com.superbiz.agent + +操作: +1. IDEA Refactor → Rename Package +2. 全局搜索替换 import +3. pom.xml 更新 mainClass + +验收标准: +✓ 编译通过 +✓ 无遗漏的 org.example +✓ 启动成功 +``` + +#### 任务 3.2:分层结构优化 + +``` +目标结构: +src/main/java/com/superbiz/agent/ +├── controller/ # REST 接口 +├── service/ # 业务逻辑 +├── repository/ # 数据访问 +├── domain/ +│ ├── entity/ # JPA 实体 +│ ├── dto/ # 数据传输对象 +│ ├── vo/ # 视图对象 +│ └── enums/ # 枚举 +├── agent/ # Agent 层 +│ ├── supervisor/ +│ ├── planner/ +│ ├── executor/ +│ └── verifier/ +├── tool/ # 工具层 +├── harness/ # Harness 控制 +│ ├── gate/ +│ └── interrupt/ +├── skill/ # Skill 定义 +├── session/ # 会话管理 +├── intent/ # 意图识别 +├── rag/ # RAG 加载 +└── config/ # 配置 + +验收标准: +✓ 目录结构清晰 +✓ 职责单一 +✓ 编译通过 +``` + +#### 任务 3.3:DTO 抽离 + +```java +产出文件: +src/main/java/com/superbiz/agent/domain/dto/ +├── DiagnosisRequest.java +├── DiagnosisResponse.java +├── DocumentUploadRequest.java +├── CaseQueryRequest.java +└── ... + +要求: +- Controller 不直接依赖 Entity +- MapStruct 做对象转换 +- 校验注解 @Valid + @NotNull +- 统一响应包装类 Result + +验收标准: +✓ Controller 不 import Entity +✓ 原有接口兼容 +✓ 编译通过 +``` + +--- + +### Day 4-5:文档管理 + +#### 任务 4.1:文档上传 + +```java +产出文件: +controller/DocumentController.java +service/DocumentService.java +service/TextExtractor.java +service/VectorService.java + +接口:POST /api/documents/upload +功能: +1. 接收文件(Word/PDF/Markdown) +2. 提取纯文本 +3. 分块(chunk_size=500, overlap=50) +4. 向量化(DashScopeEmbedding) +5. 写 MySQL + Milvus + +验收标准: +✓ 上传成功返回 document_id +✓ MySQL 记录正确 +✓ Milvus 向量正确 +✓ 单元测试覆盖 +``` + +#### 任务 4.2:文档查询 + +```java +接口: +- GET /api/documents/{id} +- GET /api/documents?province=XX&category=YY + +验收标准: +✓ 分页查询 +✓ 过滤生效 +✓ 性能可接受(< 100ms) +``` + +#### 任务 4.3:文档删除同步 + +```java +接口:DELETE /api/documents/{id} + +功能: +- 删除 MySQL 记录 +- 同步删除 Milvus 向量 +- 事务一致性 + +验收标准: +✓ MySQL + Milvus 同步删除 +✓ 事务回滚正确 +``` + +#### 任务 4.4:混合检索实现 + +```java +产出文件: +tool/DocumentSearchTool.java + +策略: +1. 精确匹配(MySQL) +2. 语义检索(Milvus) +3. RRF 融合排序 + +验收标准: +✓ 精确匹配优先 +✓ 语义检索补漏 +✓ 返回 Top 3 +✓ 单元测试覆盖 +``` + +--- + +## Phase 2:核心功能(5天) + +### Day 6-7:意图识别 + RAG + +#### 任务 6.1:意图识别模块 + +```java +产出文件: +intent/IntentClassifier.java +intent/L0RulesMatcher.java +intent/L1AgentClassifier.java +intent/IntentResult.java + +L0 规则匹配: +- 正则:订单号、traceId、错误码 +- 关键词:报错、异常、失败 +- 返回:诊断/文档/案例/闲聊 + +L1 小模型 Agent: +- 输入:用户原始输入 +- Prompt:分类意图 +- 输出:意图 + 置信度 + +验收标准: +✓ L0 命中率 80%+ +✓ L1 准确率 90%+ +✓ 延迟 < 200ms +✓ 单元测试覆盖 +``` + +#### 任务 6.2:RAG 两层加载 + +```java +产出文件: +rag/RagLoader.java +rag/L1PreloadService.java +rag/L2OnDemandService.java + +L1 预加载: +- 触发时机:意图识别后,Planner 启动前 +- 内容:通用领域知识(架构、流程、高频错误码) +- 注入:Planner System Prompt + +L2 按需加载: +- 触发时机:Executor 拿到 errorCode 后 +- 内容:具体接口文档 +- 调用:searchDoc + +验收标准: +✓ L1 预加载成功 +✓ L2 按需调用成功 +✓ 单元测试覆盖 +``` + +--- + +### Day 8-9:4 Agent 协作 + Skill + +#### 任务 8.1:4 Agent 定义 + +```java +产出文件: +agent/supervisor/SupervisorAgent.java +agent/planner/PlannerAgent.java +agent/executor/ExecutorAgent.java +agent/verifier/VerifierAgent.java + +配置文件: +src/main/resources/prompts/ +├── supervisor-system.md +├── planner-system.md +├── executor-system.md +└── verifier-system.md + +技术栈: +- Spring AI Alibaba +- SupervisorAgent + ReactAgent +- @Tool 注解 + +验收标准: +✓ 4 Agent 注册成功 +✓ 协作流程跑通 +✓ Supervisor 调度正确 +``` + +#### 任务 8.2:Skill 实现 + +```java +产出文件: +skill/SkillDefinition.java +skill/DiagnoseByOrderIdSkill.java +skill/SkillRegistry.java + +工作流(6 步): +1. queryOrder +2. searchDoc (L2 按需) +3. queryLogs (Mock) +4. recommendCase +5. 生成报告 +6. Verifier 验证 + +验收标准: +✓ 6 步流程正确 +✓ 失败处理正确(ABORT/SKIP) +✓ 单元测试覆盖 +``` + +--- + +### Day 10:工具层开发 + +#### 任务 10.1:queryOrder 工具 + +```java +产出文件: +tool/QueryOrderTool.java + +功能: +- 只读查询 MySQL +- 返回订单信息 + 错误信息 +- SQL 注入防护 + +验收标准: +✓ 查询正确 +✓ 超时控制(10s) +✓ 单元测试覆盖 +``` + +#### 任务 10.2:searchDoc 工具 + +```java +产出文件: +tool/SearchDocTool.java + +功能: +- 调用混合检索 +- 返回 Top 3 文档片段 + +验收标准: +✓ 调用成功 +✓ 结果格式正确 +✓ 单元测试覆盖 +``` + +#### 任务 10.3:recommendCase 工具 + +```java +产出文件: +tool/RecommendCaseTool.java + +功能: +- 精确匹配:error_code + fault_category +- 语义检索:description 向量相似度 +- RRF 融合 + +验收标准: +✓ 推荐准确 +✓ 返回 Top 3 +✓ 单元测试覆盖 +``` + +#### 任务 10.4:getCurrentTime 工具 + +```java +产出文件: +tool/GetCurrentTimeTool.java + +功能: +- 返回当前时间戳 +- 格式化输出 + +验收标准: +✓ 返回正确 +``` + +--- + +## Phase 3:闭环优化(3天) + +### Day 11:Verifier + Harness + +#### 任务 11.1:Verifier Agent + +```java +产出文件: +agent/verifier/VerifierAgent.java + +验证逻辑: +1. 事实核查(报告数据 vs 工具返回数据) +2. 完整性检查(3 章节不能为空) + +判决: +- PASS:通过 +- REVISE:需修正 +- REJECT:驳回 + +验收标准: +✓ 事实核查正确 +✓ 编造检测生效 +✓ 单元测试覆盖 +``` + +#### 任务 11.2:Harness 5 Gates + +```java +产出文件: +harness/gate/InputGates.java +harness/gate/ExecutionGates.java +harness/gate/OutputGates.java + +门禁清单: +- Gate 1: 输入参数非空 +- Gate 2: 5 分钟内重复 → 缓存 +- Gate 3: 工具超时(10s) +- Gate 4: 报告完整性 +- Gate 5: 置信度阈值(60) + +验收标准: +✓ 5 Gates 生效 +✓ 中断机制正确 +✓ 单元测试覆盖 +``` + +--- + +### Day 12:反馈机制 + 案例沉淀 + +#### 任务 12.1:反馈接口 + +```java +产出文件: +controller/FeedbackController.java +service/FeedbackService.java + +接口:POST /api/diagnosis/{id}/feedback +参数:useful / not_useful + +功能: +- 更新 diagnosis_record.feedback +- useful → 自动生成 case_library + +验收标准: +✓ 反馈记录成功 +✓ 案例生成正确 +✓ 单元测试覆盖 +``` + +#### 任务 12.2:案例自动生成 + +```java +产出文件: +service/CaseGenerationService.java + +触发条件: +- feedback = useful +- confidence >= 80 + +生成逻辑: +- 提取关键信息 +- 生成 case_library 记录 +- 向量化 solution_steps + +验收标准: +✓ 案例生成正确 +✓ 向量化成功 +✓ 单元测试覆盖 +``` + +--- + +### Day 13:端到端测试 + 验收 + +#### 任务 13.1:Mock 5 个场景 + +``` +场景 1:外部接口故障(广东社保 40003) +场景 2:内部空指针异常 +场景 3:数据库连接超时 +场景 4:意图不明(闲聊) +场景 5:缓存命中(重复诊断) + +验收标准: +✓ 5 个场景全部跑通 +✓ 诊断报告正确 +✓ 反馈闭环完整 +``` + +#### 任务 13.2:性能测试 + +``` +指标: +- 诊断延迟 < 10s(P95) +- 意图识别 < 200ms +- 文档检索 < 500ms +- 并发 10 QPS 稳定 + +验收标准: +✓ 性能达标 +✓ 无内存泄漏 +✓ 无明显瓶颈 +``` + +#### 任务 13.3:文档更新 + +``` +产出文件: +docs/ +├── API.md # 接口文档 +├── DEPLOYMENT.md # 部署指南 +└── TEST_REPORT.md # 测试报告 + +验收标准: +✓ 文档完整 +✓ 部署可复现 +✓ 测试报告详实 +``` + +--- + +## 测试要求 + +### 单元测试 + +``` +框架:JUnit 5 + Mockito +覆盖率: +- Repository: 100% +- Service: 80%+ +- Tool: 80%+ +- Agent: 70%+ +- Controller: 70%+ +``` + +### 集成测试 + +``` +框架:@SpringBootTest +覆盖: +- Redis 集成 +- MySQL 集成 +- Milvus 集成 +- Agent 协作 +``` + +### E2E 测试 + +``` +工具:RestAssured +场景:5 个 Mock 场景 +``` + +--- + +## 实施记录格式 + +每完成一个任务,AI 在此文档追加: + +```markdown +--- + +## [完成] 任务 X.X:任务名称 + +**执行时间**:2026-XX-XX HH:mm + +**产出文件**: +- path/to/file1.java (126 行) +- path/to/file2.java (89 行) + +**关键决策**: +- 决策点:选择方案 A,因为... +- 权衡点:备选方案 B 的劣势是... + +**遇到的问题**: +- 问题:XXX +- 解决方案:YYY +- 影响范围:ZZZ + +**测试结果**: +✓ 单元测试:8/8 通过 +✓ 集成测试:3/3 通过 +✓ 代码覆盖率:85% + +**验收状态**:⏳ 等待用户确认 / ✅ 已通过 + +**用户反馈**:(用户确认后填写) +``` + +--- + +## 当前进度 + +``` +Phase 1: 基础设施(5天) [ ] 0% +├─ Day 1-2: 数据库 + 实体 [ ] 未开始 +├─ Day 3: 代码结构重构 [ ] 未开始 +└─ Day 4-5: 文档管理 [ ] 未开始 + +Phase 2: 核心功能(5天) [ ] 0% +├─ Day 6-7: 意图识别 + RAG [ ] 未开始 +├─ Day 8-9: Agent + Skill [ ] 未开始 +└─ Day 10: 工具层 [ ] 未开始 + +Phase 3: 闭环优化(3天) [ ] 0% +├─ Day 11: Verifier + Harness [ ] 未开始 +├─ Day 12: 反馈 + 案例 [ ] 未开始 +└─ Day 13: E2E 测试 [ ] 未开始 + +总体进度:0/13 天 +``` + +--- + +## 下一步 + +等待用户确认: +1. ✅ 这个完整计划是否符合预期? +2. 有没有需要调整的优先级? +3. 有没有需要增删的任务? +4. 确认后开始执行 Phase 1 Day 1-2。 diff --git a/openspec/changes/phase-1-infrastructure/.commit b/openspec/changes/phase-1-infrastructure/.commit new file mode 100644 index 0000000..e20be6b --- /dev/null +++ b/openspec/changes/phase-1-infrastructure/.commit @@ -0,0 +1 @@ +COMMITTED diff --git a/openspec/changes/phase-1-infrastructure/decisions.md b/openspec/changes/phase-1-infrastructure/decisions.md new file mode 100644 index 0000000..1ae611e --- /dev/null +++ b/openspec/changes/phase-1-infrastructure/decisions.md @@ -0,0 +1,112 @@ +# Phase 1 Infrastructure - Decisions Log + +## Grill 阶段澄清记录 + +### 2026-06-23 + +#### Q1: SessionContext 字段设计 +**问题**: Redis 会话需要存储哪些字段? + +**决策**: +```java +class SessionContext { + String sessionId; + String diagnosisId; + String currentStep; + Map collectedEvidence; + List toolCallHistory; + String intentType; // 预留 Phase 2 意图识别 + LocalDateTime createdAt; + LocalDateTime lastAccessAt; +} +``` + +**理由**: +- 支持多轮对话恢复上下文 +- intentType 预留 Phase 2,避免后续修改结构 +- tool_calls 同时存 Redis(临时)和 MySQL(持久) + +**用户确认**: 已确认 + +--- + +#### Q2: 包名重构策略 +**问题**: org.example → com.superbiz.agent 是否需要兼容层? + +**决策**: 直接全量替换,不保留兼容层 + +**理由**: +- 内部项目,无外部依赖者 +- 兼容层增加复杂度 +- MVP 阶段保持简单 + +**用户确认**: 已确认 + +--- + +#### Q3: Redis 降级策略 +**问题**: Redis 故障时如何处理? + +**决策**: Phase 1 不做降级,Redis 故障直接失败 + +**理由**: +- MVP 优先跑通核心流程 +- 降级策略增加复杂度 +- 单元测试可用内存 Mock + +**备选方案** (Phase 2/3): +- 自动降级到内存实现 +- 返回友好错误提示 + +**用户确认**: 已确认(先跑通 MVP) + +--- + +## Evidence-Driven 查证结果 + +### 诊断记录 vs 案例的边界 +**查证文件**: docs/tables/diagnosis_record.md, docs/tables/case_library.md + +**结论**: +- 诊断记录:每次诊断都记录 +- 案例:从诊断记录中筛选(成功诊断 + 用户反馈 useful) +- 转换触发:diagnosis_record.feedback = 'useful' + confidence >= 80 + +**状态**: 已查证,边界清晰 + +--- + +### 文档范围 +**查证文件**: docs/tables/api_document.md + +**结论**: +- Phase 1: 只处理接口文档(API 文档、错误码说明) +- Phase 2/3: 可扩展为其他类型(运维手册、FAQ) + +**状态**: 已查证,范围明确 + +--- + +### 单元测试覆盖率标准 +**查证文件**: docs/architecture/implementation-detail.md + +**结论**: +- 目标:行覆盖率 70%+ +- Repository: 100% +- Service: 80%+ +- Tool: 80%+ +- Controller: 70%+ + +**状态**: 已查证,标准明确 + +--- + +## 待写入 CONTEXT.md 的术语 + +无新增术语。现有术语已在 docs/ 中定义清楚。 + +--- + +## 待创建 ADR + +无。Phase 1 都是标准技术选型,无需 ADR。 diff --git a/openspec/changes/phase-1-infrastructure/design.md b/openspec/changes/phase-1-infrastructure/design.md new file mode 100644 index 0000000..5c419bb --- /dev/null +++ b/openspec/changes/phase-1-infrastructure/design.md @@ -0,0 +1,267 @@ +# Phase 1 Infrastructure - Design + +## 架构设计 + +### 1. 数据持久化层 + +``` +┌─────────────────────────────────────────┐ +│ Application Layer │ +│ (Service / Controller / Agent) │ +└──────────────┬──────────────────────────┘ + │ + ↓ +┌─────────────────────────────────────────┐ +│ Repository Layer (JPA) │ +│ - DiagnosisRecordRepository │ +│ - CaseLibraryRepository │ +│ - ApiDocumentRepository │ +└──────────────┬──────────────────────────┘ + │ + ↓ +┌─────────────────────────────────────────┐ +│ MySQL 8.0+ │ +│ - diagnosis_record (诊断记录) │ +│ - case_library (案例库) │ +│ - api_document (文档元数据) │ +│ - flyway_schema_history (版本管理) │ +└─────────────────────────────────────────┘ +``` + +**Flyway 迁移流程**: +1. 启动时自动扫描 `db/migration/V*.sql` +2. 检查 `flyway_schema_history` 表 +3. 执行未运行的脚本 +4. 记录版本号 + +### 2. 会话管理层 + +``` +┌─────────────────────────────────────────┐ +│ Diagnosis Flow │ +└──────────────┬──────────────────────────┘ + │ + ↓ +┌─────────────────────────────────────────┐ +│ SessionManager (Interface) │ +└──────────────┬──────────────────────────┘ + │ + ↓ +┌─────────────────────────────────────────┐ +│ RedisSessionManager (Impl) │ +│ - get(sessionId): SessionContext │ +│ - save(context): void │ +│ - delete(sessionId): void │ +└──────────────┬──────────────────────────┘ + │ + ↓ +┌─────────────────────────────────────────┐ +│ Redis 6.0+ │ +│ Key: session:{sessionId} │ +│ Value: SessionContext (JSON) │ +│ TTL: 30 minutes │ +└─────────────────────────────────────────┘ +``` + +**SessionContext 结构**: +```java +{ + "sessionId": "uuid", + "diagnosisId": "uuid", + "currentStep": "queryOrder", + "collectedEvidence": { + "orderInfo": {...}, + "logs": [...] + }, + "toolCallHistory": [ + { + "toolName": "queryOrder", + "params": {...}, + "result": {...}, + "timestamp": "2026-06-23T10:00:00" + } + ], + "intentType": "诊断", + "createdAt": "2026-06-23T09:55:00", + "lastAccessAt": "2026-06-23T10:00:00" +} +``` + +### 3. 包结构设计 + +``` +com.superbiz.agent/ +├── SuperBizAgentApplication.java # 启动类 +│ +├── controller/ # REST 控制器 +│ ├── DiagnosisController.java +│ ├── DocumentController.java +│ └── CaseController.java +│ +├── service/ # 业务服务 +│ ├── DiagnosisService.java +│ ├── DocumentService.java +│ ├── CaseService.java +│ ├── TextExtractor.java # 文本提取 +│ └── VectorService.java # 向量化服务 +│ +├── repository/ # 数据访问 +│ ├── DiagnosisRecordRepository.java +│ ├── CaseLibraryRepository.java +│ └── ApiDocumentRepository.java +│ +├── domain/ # 领域模型 +│ ├── entity/ # JPA 实体 +│ │ ├── DiagnosisRecord.java +│ │ ├── CaseLibrary.java +│ │ └── ApiDocument.java +│ ├── dto/ # 数据传输对象 +│ │ ├── DiagnosisRequest.java +│ │ ├── DiagnosisResponse.java +│ │ ├── DocumentUploadRequest.java +│ │ └── DocumentQueryResponse.java +│ └── enums/ # 枚举 +│ ├── FaultCategory.java +│ ├── DiagnosisStatus.java +│ └── SourceType.java +│ +├── session/ # 会话管理 +│ ├── SessionManager.java # 接口 +│ ├── RedisSessionManager.java # Redis 实现 +│ ├── SessionContext.java # 会话上下文 +│ └── ToolCall.java # 工具调用记录 +│ +├── tool/ # 工具层 +│ ├── DocumentSearchTool.java # 混合检索 +│ └── (其他 tool 保留 Phase 2) +│ +├── config/ # 配置 +│ ├── JpaConfig.java +│ ├── RedisConfig.java +│ ├── MilvusConfig.java # 保留现有 +│ └── DashScopeConfig.java # 保留现有 +│ +└── exception/ # 异常处理 + ├── GlobalExceptionHandler.java + ├── SessionNotFoundException.java + └── DocumentProcessException.java +``` + +### 4. 文档管理流程 + +``` +文档上传流程: +User → POST /api/documents/upload + ↓ +DocumentController.upload() + ↓ +DocumentService.uploadDocument() + ↓ (并行) + ├─→ TextExtractor.extract() # 提取文本 + ├─→ chunkText() # 分块 + ├─→ VectorService.embed() # 向量化 + ├─→ ApiDocumentRepository.save() # 存 MySQL + └─→ MilvusClient.insert() # 存 Milvus + ↓ +返回 document_id +``` + +``` +混合检索流程: +Agent → DocumentSearchTool.search(errorCode, province) + ↓ + ├─→ MySQL 精确匹配 + │ SELECT * FROM api_document + │ WHERE error_code = ? AND province = ? + │ + ├─→ Milvus 语义检索 + │ 向量化查询 → 相似度搜索 → Top 10 + │ + └─→ RRF 融合排序 + (精确匹配优先 + 语义补漏) + ↓ +返回 Top 3 文档片段 +``` + +### 5. 数据库配置 + +**application.yml 新增**: +```yaml +spring: + datasource: + url: jdbc:mysql://localhost:3306/superbiz_agent?useUnicode=true&characterEncoding=utf8mb4&serverTimezone=Asia/Shanghai + username: ${DB_USERNAME:root} + password: ${DB_PASSWORD:your-password} + driver-class-name: com.mysql.cj.jdbc.Driver + + jpa: + hibernate: + ddl-auto: validate # 生产用 validate,Flyway 管理表结构 + show-sql: true + properties: + hibernate: + format_sql: true + dialect: org.hibernate.dialect.MySQL8Dialect + + flyway: + enabled: true + baseline-on-migrate: true + locations: classpath:db/migration + + data: + redis: + host: localhost + port: 6379 + password: ${REDIS_PASSWORD:} + database: 0 + timeout: 3000 + lettuce: + pool: + max-active: 8 + max-idle: 8 + min-idle: 0 +``` + +### 6. 测试策略 + +**Repository 测试**: +- 使用 @DataJpaTest + H2 内存数据库 +- 测试 CRUD + 自定义查询 + +**Service 测试**: +- 使用 @SpringBootTest + Mockito +- Mock Repository 和外部依赖 + +**Controller 测试**: +- 使用 @WebMvcTest + MockMvc +- Mock Service 层 + +**集成测试**: +- 使用 @SpringBootTest + Testcontainers(可选) +- 测试完整流程 + +## 技术决策 + +### Flyway vs Liquibase +**选择**:Flyway + +**理由**: +- 更简单,SQL-first +- Spring Boot 官方推荐 +- 社区活跃 + +### Jackson vs Gson +**选择**:Jackson(Spring Boot 默认) + +**理由**: +- Spring Boot 内置 +- 性能更好 +- 与 Spring MVC 集成好 + +### Lettuce vs Jedis +**选择**:Lettuce(Spring Data Redis 默认) + +**理由**: +- 异步支持 +- 线程安全 +- Spring Boot 默认 diff --git a/openspec/changes/phase-1-infrastructure/proposal.md b/openspec/changes/phase-1-infrastructure/proposal.md new file mode 100644 index 0000000..0bb3fcd --- /dev/null +++ b/openspec/changes/phase-1-infrastructure/proposal.md @@ -0,0 +1,171 @@ +# Proposal: Phase 1 基础设施搭建 + +## 问题 + +当前项目是一个 Demo,需要改造为 MVP 诊断 Agent 系统。Phase 1 需要搭建基础设施: +- 缺少持久化层(MySQL + JPA) +- 缺少分布式会话管理(Redis) +- 代码结构需要重构(包名、分层) +- 缺少文档管理基础功能 + +## 建议方案 + +### 1. 数据持久化 + +**方案**:Spring Data JPA + MySQL + Flyway + +**理由**: +- JPA 是 Spring Boot 标准持久化方案 +- Flyway 管理数据库版本,团队协作友好 +- 3 张表设计已完成(docs/tables/) + +**实现**: +1. 添加依赖(spring-boot-starter-data-jpa, mysql-connector-j, flyway-core) +2. 创建 3 个 Flyway 迁移脚本(V001/V002/V003) +3. 创建 JPA 实体类(DiagnosisRecord, CaseLibrary, ApiDocument) +4. 创建 Repository 接口(继承 JpaRepository) + +### 2. 会话管理 + +**方案**:Redis 替代内存 HashMap + +**理由**: +- 支持分布式部署 +- 自动 TTL(30 分钟) +- Spring Data Redis 集成简单 + +**实现**: +1. 添加 spring-boot-starter-data-redis 依赖 +2. 创建 SessionManager 接口 + RedisSessionManager 实现 +3. SessionContext 使用 JSON 序列化 + +### 3. 代码结构重构 + +**方案**:包名重构 + 分层优化 + DTO 抽离 + +**包名重构**: +- `org.example` → `com.superbiz.agent` +- 工具:IDEA Refactor → Rename Package + +**分层结构**: +``` +com.superbiz.agent/ +├── controller/ # REST API +├── service/ # 业务逻辑 +├── repository/ # 数据访问 +├── domain/ +│ ├── entity/ # JPA 实体 +│ ├── dto/ # DTO +│ └── enums/ # 枚举 +├── agent/ # Agent 层(Phase 2) +├── tool/ # 工具层 +├── session/ # 会话管理 +└── config/ # 配置 +``` + +**DTO 抽离**: +- Controller 不直接依赖 Entity +- 使用 MapStruct 做对象转换 + +### 4. 文档管理 + +**方案**:CRUD + Milvus 向量同步 + +**功能**: +1. 上传接口:文件 → 文本提取 → 分块 → 向量化 → MySQL + Milvus +2. 查询接口:分页、过滤 +3. 删除接口:MySQL + Milvus 同步删除 +4. 检索工具:精确匹配(MySQL)+ 语义检索(Milvus)+ RRF 融合 + +## 范围 + +**包含**: +- Day 1-2: MySQL 表 + JPA + Repository + Redis 会话 +- Day 3: 包名重构 + 分层优化 + DTO 抽离 +- Day 4-5: 文档管理 4 个接口 + 混合检索工具 + +**不包含**: +- Agent 功能(Phase 2) +- 意图识别和 RAG(Phase 2) +- Verifier 和 Harness(Phase 3) + +## 非目标 + +- 性能优化(后续优化) +- 完整的权限控制(MVP 不需要) +- 前端界面(只做后端 API) + +## 来自 devflow 的上下文约束 + +无(这是首个 OpenSpec,devflow 目录为空) + +## 风险 + +1. **包名重构影响范围大** + - 缓解:先提交当前代码,独立分支重构 + - 验证:重构后编译通过 + 启动成功 + +2. **Flyway 首次运行可能失败** + - 缓解:本地 MySQL 先手动测试 + - 回退:Flyway 支持 repair 修复 + +3. **Redis 本地环境依赖** + - 缓解:提供 Docker Compose 配置 + - 回退:可降级为内存实现(测试用) + +## 关键假设 + +1. MySQL 8.0+ 和 Redis 6.0+ 可用(本地或 Docker) +2. 现有 Milvus 集成不需要改动 +3. 单元测试覆盖率目标:70%+ + +## 成功标准 + +1. ✅ 3 张表创建成功,索引完整 +2. ✅ Repository 层单元测试通过 +3. ✅ Redis 会话存取正常,TTL 生效 +4. ✅ 包名重构完成,编译通过 +5. ✅ 文档上传/查询/删除接口可用 +6. ✅ 混合检索工具返回正确结果 +7. ✅ 整体测试覆盖率 ≥ 70% + +## 产出文件(预期) + +**数据库迁移**: +- `src/main/resources/db/migration/V001__create_diagnosis_record.sql` +- `src/main/resources/db/migration/V002__create_case_library.sql` +- `src/main/resources/db/migration/V003__create_api_document.sql` + +**实体类**: +- `com.superbiz.agent.domain.entity.DiagnosisRecord` +- `com.superbiz.agent.domain.entity.CaseLibrary` +- `com.superbiz.agent.domain.entity.ApiDocument` + +**Repository**: +- `com.superbiz.agent.repository.DiagnosisRecordRepository` +- `com.superbiz.agent.repository.CaseLibraryRepository` +- `com.superbiz.agent.repository.ApiDocumentRepository` + +**会话管理**: +- `com.superbiz.agent.session.SessionManager` +- `com.superbiz.agent.session.RedisSessionManager` +- `com.superbiz.agent.session.SessionContext` + +**文档管理**: +- `com.superbiz.agent.controller.DocumentController` +- `com.superbiz.agent.service.DocumentService` +- `com.superbiz.agent.service.TextExtractor` +- `com.superbiz.agent.tool.DocumentSearchTool` + +**配置**: +- `pom.xml`(增加依赖) +- `application.yml`(增加 MySQL + Redis 配置) + +**测试**: +- `*RepositoryTest.java` +- `*ServiceTest.java` +- `*ControllerTest.java` + +## 工期估算 + +5 天(按实施计划) diff --git a/openspec/changes/phase-1-infrastructure/specs/functional-specs.md b/openspec/changes/phase-1-infrastructure/specs/functional-specs.md new file mode 100644 index 0000000..816f3e1 --- /dev/null +++ b/openspec/changes/phase-1-infrastructure/specs/functional-specs.md @@ -0,0 +1,312 @@ +# 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 findByDiagnosisId(String diagnosisId); +Optional findByBusinessId(String businessId); +Optional findByTraceId(String traceId); +List findByFaultCategoryAndErrorCode( + FaultCategory category, String errorCode); +Page 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 { + "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` +- HTTP 状态码语义化 +- 异常统一处理 + +### 统一响应格式 +```java +class Result { + 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) + +### 必须覆盖的场景 +- 正常流程 +- 边界条件 +- 异常处理 +- 并发安全 diff --git a/openspec/changes/phase-1-infrastructure/tasks.md b/openspec/changes/phase-1-infrastructure/tasks.md new file mode 100644 index 0000000..32e7852 --- /dev/null +++ b/openspec/changes/phase-1-infrastructure/tasks.md @@ -0,0 +1,400 @@ +# Phase 1 Infrastructure - Tasks + +## 任务清单 + +### Day 1-2: 数据库 + 实体 + 会话(8 个任务) + +#### Task 1.1: 添加依赖到 pom.xml +**优先级**: P0(阻塞后续任务) +**预估时间**: 15 分钟 +**产出**: +- 修改 `pom.xml` +- 添加:spring-boot-starter-data-jpa, mysql-connector-j, flyway-core, flyway-mysql, spring-boot-starter-data-redis, spring-boot-starter-test, h2 +**验收**: `mvn clean compile` 成功 + +--- + +#### Task 1.2: 创建 Flyway 迁移脚本 - diagnosis_record +**优先级**: P0 +**预估时间**: 30 分钟 +**产出**: +- `src/main/resources/db/migration/V001__create_diagnosis_record.sql` +**依据**: `docs/tables/diagnosis_record.md` +**验收**: +- 表结构与文档一致 +- 索引完整 +- 注释完整 +- 本地 MySQL 执行成功 + +--- + +#### Task 1.3: 创建 Flyway 迁移脚本 - case_library +**优先级**: P0 +**预估时间**: 20 分钟 +**产出**: +- `src/main/resources/db/migration/V002__create_case_library.sql` +**依据**: `docs/tables/case_library.md` +**验收**: 同 Task 1.2 + +--- + +#### Task 1.4: 创建 Flyway 迁移脚本 - api_document +**优先级**: P0 +**预估时间**: 20 分钟 +**产出**: +- `src/main/resources/db/migration/V003__create_api_document.sql` +**依据**: `docs/tables/api_document.md` +**验收**: 同 Task 1.2 + +--- + +#### Task 1.5: 配置 MySQL + Redis + Flyway +**优先级**: P0 +**预估时间**: 20 分钟 +**产出**: +- 修改 `src/main/resources/application.yml` +- 添加 spring.datasource, spring.jpa, spring.flyway, spring.data.redis 配置 +**验收**: +- 应用启动成功 +- Flyway 自动执行迁移 +- 3 张表创建成功 + +--- + +#### Task 1.6: 创建 JPA 实体类 +**优先级**: P0 +**预估时间**: 45 分钟 +**产出**: +- `com.superbiz.agent.domain.entity.DiagnosisRecord` +- `com.superbiz.agent.domain.entity.CaseLibrary` +- `com.superbiz.agent.domain.entity.ApiDocument` +**依赖**: Task 1.2, 1.3, 1.4 +**验收**: +- 字段与数据库一致 +- Lombok 注解完整 +- JSON 字段序列化正确 +- 编译通过 + +--- + +#### Task 1.7: 创建 Repository 接口 +**优先级**: P0 +**预估时间**: 30 分钟 +**产出**: +- `com.superbiz.agent.repository.DiagnosisRecordRepository` +- `com.superbiz.agent.repository.CaseLibraryRepository` +- `com.superbiz.agent.repository.ApiDocumentRepository` +**依赖**: Task 1.6 +**验收**: +- 继承 JpaRepository +- 常用查询方法定义 +- 编译通过 + +--- + +#### Task 1.8: Repository 单元测试 +**优先级**: P1 +**预估时间**: 60 分钟 +**产出**: +- `DiagnosisRecordRepositoryTest` +- `CaseLibraryRepositoryTest` +- `ApiDocumentRepositoryTest` +**依赖**: Task 1.7 +**测试框架**: @DataJpaTest + H2 +**验收**: +- 测试覆盖率 100% +- CRUD 测试通过 +- 自定义查询测试通过 + +--- + +#### Task 1.9: 创建会话管理接口 +**优先级**: P0 +**预估时间**: 30 分钟 +**产出**: +- `com.superbiz.agent.session.SessionManager` (接口) +- `com.superbiz.agent.session.SessionContext` (数据类) +- `com.superbiz.agent.session.ToolCall` (数据类) +**验收**: +- 接口定义清晰 +- SessionContext 字段完整(含 intentType) +- 编译通过 + +--- + +#### Task 1.10: Redis 会话管理实现 +**优先级**: P0 +**预估时间**: 45 分钟 +**产出**: +- `com.superbiz.agent.session.RedisSessionManager` +- `com.superbiz.agent.session.SessionConfiguration` +**依赖**: Task 1.9 +**验收**: +- 实现 SessionManager 接口 +- TTL 设置为 30 分钟 +- JSON 序列化配置正确 +- 编译通过 + +--- + +#### Task 1.11: Redis 会话管理单元测试 +**优先级**: P1 +**预估时间**: 45 分钟 +**产出**: +- `RedisSessionManagerTest` +**依赖**: Task 1.10 +**测试框架**: @SpringBootTest + Mock RedisTemplate +**验收**: +- 存取删测试通过 +- TTL 测试通过 +- 序列化测试通过 + +--- + +### Day 3: 代码结构重构(3 个任务) + +#### Task 3.1: 包名重构 +**优先级**: P0 +**预估时间**: 30 分钟 +**操作**: +1. IDEA Refactor → Rename Package +2. `org.example` → `com.superbiz.agent` +3. 更新 `pom.xml` 中的 mainClass +4. 全局搜索确认无遗漏 +**验收**: +- 编译通过 +- 启动成功 +- 无遗漏的 org.example + +--- + +#### Task 3.2: 分层结构优化 +**优先级**: P1 +**预估时间**: 45 分钟 +**产出**: +- 创建目录结构(controller/service/repository/domain/tool/config/exception) +- 移动现有类到对应目录 +**验收**: +- 目录结构符合 design.md +- 编译通过 +- 启动成功 + +--- + +#### Task 3.3: DTO 抽离 +**优先级**: P1 +**预估时间**: 60 分钟 +**产出**: +- `com.superbiz.agent.domain.dto.DiagnosisRequest` +- `com.superbiz.agent.domain.dto.DiagnosisResponse` +- `com.superbiz.agent.domain.dto.DocumentUploadRequest` +- `com.superbiz.agent.domain.dto.DocumentQueryResponse` +- `com.superbiz.agent.domain.dto.Result` (统一响应) +**验收**: +- Controller 不 import Entity +- 编译通过 + +--- + +### Day 4-5: 文档管理(7 个任务) + +#### Task 4.1: 创建 TextExtractor 服务 +**优先级**: P0 +**预估时间**: 60 分钟 +**产出**: +- `com.superbiz.agent.service.TextExtractor` +**功能**: +- 支持 .txt, .md, .docx, .pdf +- 提取纯文本 +**依赖**: 可能需要添加 Apache POI / PDFBox 依赖 +**验收**: +- 4 种格式提取成功 +- 单元测试覆盖 + +--- + +#### Task 4.2: 文档分块服务 +**优先级**: P0 +**预估时间**: 30 分钟 +**产出**: +- `com.superbiz.agent.service.DocumentChunkService` (可能已存在,重构) +**功能**: +- chunk_size=500 +- overlap=50 +**验收**: +- 分块逻辑正确 +- 单元测试通过 + +--- + +#### Task 4.3: 文档上传接口 +**优先级**: P0 +**预估时间**: 90 分钟 +**产出**: +- `com.superbiz.agent.controller.DocumentController#upload` +- `com.superbiz.agent.service.DocumentService#uploadDocument` +**依赖**: Task 4.1, 4.2 +**验收**: +- 上传成功返回 documentId +- MySQL + Milvus 数据一致 +- 异常处理完整 +- 单元测试覆盖 + +--- + +#### Task 4.4: 文档查询接口 +**优先级**: P1 +**预估时间**: 30 分钟 +**产出**: +- `DocumentController#query` +- `DocumentService#queryDocuments` +**验收**: +- 分页查询正确 +- 过滤条件生效 +- 单元测试覆盖 + +--- + +#### Task 4.5: 文档删除接口 +**优先级**: P1 +**预估时间**: 45 分钟 +**产出**: +- `DocumentController#delete` +- `DocumentService#deleteDocument` +**验收**: +- MySQL 删除成功 +- Milvus 删除成功 +- 幂等性保证 +- 单元测试覆盖 + +--- + +#### Task 4.6: 混合检索工具 +**优先级**: P0 +**预估时间**: 90 分钟 +**产出**: +- `com.superbiz.agent.tool.DocumentSearchTool` +**功能**: +- 精确匹配(MySQL) +- 语义检索(Milvus) +- RRF 融合 +**验收**: +- 精确匹配优先 +- 语义检索补漏 +- 返回 Top 3 +- 单元测试覆盖 + +--- + +#### Task 4.7: 集成测试 +**优先级**: P1 +**预估时间**: 60 分钟 +**产出**: +- `DocumentIntegrationTest` +**测试场景**: +- 上传 → 查询 → 检索 → 删除 完整流程 +**验收**: +- 端到端测试通过 + +--- + +### 全局任务 + +#### Task G.1: 统一异常处理 +**优先级**: P1 +**预估时间**: 30 分钟 +**产出**: +- `com.superbiz.agent.exception.GlobalExceptionHandler` +- `com.superbiz.agent.exception.SessionNotFoundException` +- `com.superbiz.agent.exception.DocumentProcessException` +**验收**: +- 异常统一捕获 +- 返回格式统一 + +--- + +#### Task G.2: Docker Compose 配置 +**优先级**: P2 +**预估时间**: 20 分钟 +**产出**: +- `docker-compose.yml` (MySQL + Redis + Milvus) +**验收**: +- `docker-compose up -d` 启动成功 +- 应用连接成功 + +--- + +#### Task G.3: README 更新 +**优先级**: P2 +**预估时间**: 15 分钟 +**产出**: +- 更新 `README.md` +- 添加 Phase 1 安装说明 +- 添加本地开发指南 + +--- + +## 任务依赖关系图 + +``` +Day 1-2: +Task 1.1 → Task 1.5 + ↓ +Task 1.2, 1.3, 1.4 → Task 1.6 → Task 1.7 → Task 1.8 + ↓ +Task 1.5 → Task 1.9 → Task 1.10 → Task 1.11 + +Day 3: +Task 3.1 (阻塞) → Task 3.2 → Task 3.3 + +Day 4-5: +Task 4.1, 4.2 → Task 4.3 → Task 4.7 + ↓ + Task 4.4 + ↓ + Task 4.5 + ↓ + Task 4.6 → Task 4.7 + +全局: +Task G.1 (并行) +Task G.2 (并行) +Task G.3 (最后) +``` + +--- + +## 关键路径 + +``` +Task 1.1 → 1.5 → 1.6 → 1.7 → 3.1 → 3.2 → 4.1 → 4.3 → 4.6 → 4.7 +``` + +--- + +## 预估总工时 + +- Day 1-2: 5.5 小时(11 个任务) +- Day 3: 2 小时(3 个任务) +- Day 4-5: 6 小时(7 个任务) +- 全局: 1 小时(3 个任务) + +**总计**: 14.5 小时(约 2 个完整工作日) + +--- + +## 里程碑 + +**Milestone 1**: Day 2 结束 +- ✅ 数据库表就绪 +- ✅ JPA + Repository 可用 +- ✅ Redis 会话管理可用 + +**Milestone 2**: Day 3 结束 +- ✅ 包名重构完成 +- ✅ 代码结构清晰 + +**Milestone 3**: Day 5 结束 +- ✅ 文档管理 CRUD 完整 +- ✅ 混合检索工具可用 +- ✅ 单元测试覆盖率达标(70%+)