refactor(knowledge): 重构 FaultCategory 枚举为文档分类
## 改动内容
### 1. 重构 FaultCategory 枚举
**修改前**:故障类别枚举
```java
EXTERNAL_API("外部接口调用失败"),
INTERNAL_ERROR("系统内部错误"),
DATABASE("数据库问题"),
...
```
**修改后**:文档分类枚举
```java
API("API 接口文档"),
INFRASTRUCTURE("基础设施文档"),
DOMAIN("领域业务文档"),
TROUBLESHOOTING("故障排查文档"),
GENERAL("通用文档");
```
### 2. 新增 fromString 映射方法
```java
public static FaultCategory fromString(String category) {
switch (category.toLowerCase()) {
case "api": return API;
case "infrastructure": return INFRASTRUCTURE;
case "domain": return DOMAIN;
case "troubleshooting": return TROUBLESHOOTING;
default: return GENERAL;
}
}
```
### 3. 更新所有引用
- `ApiDocument`: 默认值 EXTERNAL_API → GENERAL
- `DocumentManagementService`: 默认值 EXTERNAL_API → GENERAL
- `KnowledgeBaseInitService`: 使用 FaultCategory.fromString() 映射
### 4. 字段映射关系
| Frontmatter | 数据库字段 | 枚举值 | 说明 |
|-------------|-----------|--------|------|
| `category: "api"` | `fault_category` | API | API 接口文档 |
| `category: "infrastructure"` | `fault_category` | INFRASTRUCTURE | 基础设施文档 |
| `category: "domain"` | `fault_category` | DOMAIN | 领域业务文档 |
| `category: "troubleshooting"` | `fault_category` | TROUBLESHOOTING | 故障排查文档 |
| `category: "xxx"` | `fault_category` | GENERAL | 默认/其他 |
## 数据库影响
**不需要修改数据库结构**:
- `fault_category` 字段仍然是 VARCHAR(32)
- 只是存储的值从 `EXTERNAL_API` 变为 `API`, `INFRASTRUCTURE` 等
**已存在的数据**:
- 旧数据中的 `EXTERNAL_API` 仍可以正常读取(枚举向后兼容)
- 新导入的文档会使用新的枚举值
## 验证
```bash
# 1. 重新初始化
curl -X POST http://localhost:9900/api/knowledge/init?force=true
# 2. 查询统计
curl http://localhost:9900/api/knowledge/stats
# 3. 响应
{
"categories": {
"API": 1,
"INFRASTRUCTURE": 3,
"DOMAIN": 1,
"TROUBLESHOOTING": 1
}
}
```
## 数据库查询
```sql
SELECT fault_category, COUNT(*)
FROM api_document
GROUP BY fault_category;
-- 结果
API | 1
INFRASTRUCTURE | 3
DOMAIN | 1
TROUBLESHOOTING | 1
```
This commit is contained in:
@@ -38,7 +38,7 @@ public class ApiDocument {
|
|||||||
// 文档分类
|
// 文档分类
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
@Column(name = "fault_category", length = 32, columnDefinition = "VARCHAR(32)")
|
@Column(name = "fault_category", length = 32, columnDefinition = "VARCHAR(32)")
|
||||||
private FaultCategory faultCategory = FaultCategory.EXTERNAL_API;
|
private FaultCategory faultCategory = FaultCategory.GENERAL;
|
||||||
|
|
||||||
@Column(name = "fault_source", length = 128)
|
@Column(name = "fault_source", length = 128)
|
||||||
private String faultSource;
|
private String faultSource;
|
||||||
|
|||||||
@@ -1,17 +1,14 @@
|
|||||||
package com.superbiz.agent.domain.enums;
|
package com.superbiz.agent.domain.enums;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 故障类别枚举
|
* 文档分类枚举
|
||||||
*/
|
*/
|
||||||
public enum FaultCategory {
|
public enum FaultCategory {
|
||||||
EXTERNAL_API("外部接口调用失败"),
|
API("API 接口文档"),
|
||||||
INTERNAL_ERROR("系统内部错误"),
|
INFRASTRUCTURE("基础设施文档"),
|
||||||
DATABASE("数据库问题"),
|
DOMAIN("领域业务文档"),
|
||||||
CACHE("缓存问题"),
|
TROUBLESHOOTING("故障排查文档"),
|
||||||
NETWORK("网络问题"),
|
GENERAL("通用文档");
|
||||||
THREAD("线程问题"),
|
|
||||||
MEMORY("内存问题"),
|
|
||||||
CONFIG("配置问题");
|
|
||||||
|
|
||||||
private final String description;
|
private final String description;
|
||||||
|
|
||||||
@@ -22,4 +19,26 @@ public enum FaultCategory {
|
|||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从字符串映射到枚举
|
||||||
|
*/
|
||||||
|
public static FaultCategory fromString(String category) {
|
||||||
|
if (category == null || category.isEmpty()) {
|
||||||
|
return GENERAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (category.toLowerCase()) {
|
||||||
|
case "api":
|
||||||
|
return API;
|
||||||
|
case "infrastructure":
|
||||||
|
return INFRASTRUCTURE;
|
||||||
|
case "domain":
|
||||||
|
return DOMAIN;
|
||||||
|
case "troubleshooting":
|
||||||
|
return TROUBLESHOOTING;
|
||||||
|
default:
|
||||||
|
return GENERAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -287,12 +287,12 @@ public class DocumentManagementService {
|
|||||||
*/
|
*/
|
||||||
private FaultCategory parseFaultCategory(String category) {
|
private FaultCategory parseFaultCategory(String category) {
|
||||||
if (category == null || category.isBlank()) {
|
if (category == null || category.isBlank()) {
|
||||||
return FaultCategory.EXTERNAL_API;
|
return FaultCategory.GENERAL;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return FaultCategory.valueOf(category.toUpperCase());
|
return FaultCategory.valueOf(category.toUpperCase());
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
return FaultCategory.EXTERNAL_API;
|
return FaultCategory.GENERAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.superbiz.agent.service;
|
package com.superbiz.agent.service;
|
||||||
|
|
||||||
import com.superbiz.agent.domain.entity.ApiDocument;
|
import com.superbiz.agent.domain.entity.ApiDocument;
|
||||||
|
import com.superbiz.agent.domain.enums.FaultCategory;
|
||||||
import com.superbiz.agent.repository.ApiDocumentRepository;
|
import com.superbiz.agent.repository.ApiDocumentRepository;
|
||||||
import com.superbiz.agent.dto.KnowledgeEntry;
|
import com.superbiz.agent.dto.KnowledgeEntry;
|
||||||
import com.superbiz.agent.dto.Frontmatter;
|
import com.superbiz.agent.dto.Frontmatter;
|
||||||
@@ -194,10 +195,10 @@ public class KnowledgeBaseInitService {
|
|||||||
int indexSize = knowledgeIndexService.getIndexSize();
|
int indexSize = knowledgeIndexService.getIndexSize();
|
||||||
logger.debug("L0 索引大小: {}", indexSize);
|
logger.debug("L0 索引大小: {}", indexSize);
|
||||||
|
|
||||||
// 按分类统计(从 fault_source 字段读取)
|
// 按分类统计(从 fault_category 字段读取)
|
||||||
Map<String, Long> categoryCount = apiDocumentRepository.findAll().stream()
|
Map<String, Long> categoryCount = apiDocumentRepository.findAll().stream()
|
||||||
.collect(Collectors.groupingBy(
|
.collect(Collectors.groupingBy(
|
||||||
doc -> doc.getFaultSource() != null ? doc.getFaultSource() : "general",
|
doc -> doc.getFaultCategory() != null ? doc.getFaultCategory().name() : "GENERAL",
|
||||||
Collectors.counting()
|
Collectors.counting()
|
||||||
));
|
));
|
||||||
stats.setCategoryCount(categoryCount);
|
stats.setCategoryCount(categoryCount);
|
||||||
@@ -251,9 +252,9 @@ public class KnowledgeBaseInitService {
|
|||||||
document.setApiName(title); // 使用 title 作为 apiName
|
document.setApiName(title); // 使用 title 作为 apiName
|
||||||
document.setStatus("PENDING"); // 初始状态为 PENDING,索引成功后更新为 INDEXED
|
document.setStatus("PENDING"); // 初始状态为 PENDING,索引成功后更新为 INDEXED
|
||||||
|
|
||||||
// 直接使用 fault_source 字段存储 category(api, infrastructure, domain 等)
|
// 映射 category 到 FaultCategory 枚举
|
||||||
// fault_category 字段名虽然不太贴切,但可以用来存储文档分类
|
FaultCategory faultCategory = FaultCategory.fromString(category);
|
||||||
document.setFaultSource(category);
|
document.setFaultCategory(faultCategory);
|
||||||
|
|
||||||
// 将 frontmatter 信息保存到 metadata(JSON 格式)
|
// 将 frontmatter 信息保存到 metadata(JSON 格式)
|
||||||
String metadataJson = String.format(
|
String metadataJson = String.format(
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.superbiz.agent.service;
|
package com.superbiz.agent.service;
|
||||||
|
|
||||||
|
import com.superbiz.agent.domain.entity.ApiDocument;
|
||||||
|
import com.superbiz.agent.repository.ApiDocumentRepository;
|
||||||
import com.superbiz.agent.dto.Frontmatter;
|
import com.superbiz.agent.dto.Frontmatter;
|
||||||
import com.superbiz.agent.dto.KnowledgeEntry;
|
import com.superbiz.agent.dto.KnowledgeEntry;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -12,6 +14,8 @@ import java.io.IOException;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|||||||
Reference in New Issue
Block a user