|
|
@@ -0,0 +1,354 @@
|
|
|
+# 菌群知识并入 dan_knowledge_base 实施计划
|
|
|
+
|
|
|
+> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
|
+
|
|
|
+**Goal:** 将 809 篇菌群文章从 `health_knowledge_base` 并入 `dan_knowledge_base`,成为唯一知识条目表,管理端统一入口,langgraph 三源仍按 `metadata.source` 分流。
|
|
|
+
|
|
|
+**Architecture:** `dan_knowledge_base` 增加 `source_type='article'` 标记(该字段已存在且 39 条案例全为 `'file'`,无 title 唯一约束,809 篇零冲突);后端 list 接口增加 `sourceType`/`excludeSourceType` 参数;langgraph `dan_knowledge` 源用 `excludeSourceType='article'` 排除、`microbiome` 源用 `sourceType='article'` 拉取;前端知识库管理页增强后删除健康知识库页。
|
|
|
+
|
|
|
+**Tech Stack:** Spring Boot 2.7.18 + MyBatis-Plus(lambda wrapper)+ Vue 2.7 / Element UI + Python FastAPI / Chroma / httpx + MySQL 8.0.34
|
|
|
+
|
|
|
+**Spec:** `docs/superpowers/specs/2026-10-20-knowledge-unify-design.md`
|
|
|
+
|
|
|
+**关键事实(已勘察确认):**
|
|
|
+- `dan_knowledge_base` 唯一键:仅 PRIMARY(id),`title varchar(200)`,`content mediumtext`,现有 39 条全 `source_type='file'`
|
|
|
+- 809 篇文章 title 全部 ≤ 200 字符(无截断风险)
|
|
|
+- `DanKnowledgeBaseService.list` 的 `wrapper.orderByAsc(getSort)` **无 id tie-break**——所有文章 sort=0,重建索引可能漏块(与旧 `microbiome_article` 分页 bug 同类)
|
|
|
+- `knowledge_sync` 首次延迟 120s、之后每 3600s 定时全量重建三源,容器重启即重置计时
|
|
|
+
|
|
|
+## Global Constraints
|
|
|
+
|
|
|
+- 代码在 `111.228.6.214:/app/cfc`(git cfclub 分支),部署按 AGENTS.md:备份 → 构建 → 部署 → 验证 → 失败回滚
|
|
|
+- DB:`mysql -h mysql-internet-cn-north-1-23feae22680e4dfa.rds.jdcloud.com -P 3306 -u cfc -pcfc@1314 zxyj`
|
|
|
+- 后端 systemd `cfc-backend`(9082),生产 jar `/app/pro/cfc/backend/cfc-backend-1.0.0.jar`;langgraph `docker compose`(9000,容器 `cfc-langgraph-langgraph-svc-1`)
|
|
|
+- 管理端 API 统一 POST;管理端 axios 用 `import request from '@/utils/request'`(**不要用 `this.$axios`**,项目未注册该原型)
|
|
|
+- **category 字段丢弃**(不 ALTER 表)——Chroma metadata.category 写了从不读/过滤;`health_butler_graph` 读 category 走 `/api/health/knowledge/query`(读原表,不读 Chroma)
|
|
|
+- langgraph 新镜像 **必须先构建好(不部署)**,DB INSERT 后才 force-recreate 替换容器(避免窗口期双重索引)
|
|
|
+- 保留 `created_at`/`updated_at` 原始值(INSERT 显式指定列,不依赖默认 CURRENT_TIMESTAMP)
|
|
|
+- 生产目录 `/app/pro/cfc` 改动前必须先备份 jar;验证失败必须回滚 + 复验
|
|
|
+
|
|
|
+## Review Focus
|
|
|
+
|
|
|
+1. **langgraph 窗口期双重索引**(最高风险):DB INSERT 后若旧镜像仍在运行且定时同步触发,会把 848 条全部索引为 dan_knowledge。→ Task 2 先构建镜像,Task 3 立即 INSERT,Task 4 立即 force-recreate 替换容器。验证:重建日志 by_source 仅三源且块数与设计一致,`dan_knowledge` ≈ 1885。
|
|
|
+2. **分页稳定性**:`wrapper.orderByAsc(getSort)` 缺 id tie-break,809 篇 sort 全 0 → 重建漏块或重复。→ Task 1 加 `.orderByAsc(DanKnowledgeBase::getId)`。验证:重建后 microbiome 块数与 809 篇实际分块数一致,无重复 id。
|
|
|
+3. **dan_knowledge 源被误排除**:`excludeSourceType` 必须排除的是 `article`,不是 `file`。验证:`/api/admin/knowledge-base/list` 不传 sourceType 返回 848 条;传 excludeSourceType='article' 返回 39 条。
|
|
|
+4. **时间戳被覆盖**:INSERT 未显式指定 created_at/updated_at 会用 CURRENT_TIMESTAMP,809 篇 pub_date 全变 2026-10-20。验证:抽查 1 篇 pub_date = 原始健康表时间。
|
|
|
+5. **清理误删**:`DELETE` 必须限定 `item_type='article'`(表保留给未来指标条目)。验证:清理后表存在且 `COUNT(*)=0`,其他 item_type 行未动。
|
|
|
+6. **权限共享**:删路由与菜单共享 `knowledge:base` perm,删路由不应影响「知识库管理」页访问。验证:Layout.vue 与 router 均无 `health-knowledge`,知识库管理页仍可进入。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### Task 1: 后端 list 接口支持 sourceType/excludeSourceType + id tie-break
|
|
|
+
|
|
|
+**Files:**
|
|
|
+- Modify: `cfc-backend/src/main/java/com/etotem/cfc/service/DanKnowledgeBaseService.java:58-90`
|
|
|
+- Modify: `cfc-backend/src/main/java/com/etotem/cfc/controller/admin/KnowledgeBaseController.java:39-50`
|
|
|
+
|
|
|
+**Interfaces:**
|
|
|
+- Produces: `DanKnowledgeBaseService.list(String keyword, Integer status, int page, int size, Long tagId, Long dimensionId, String sourceType, String excludeSourceType)` — 8 参重载;保留 4 参/6 参重载委托 8 参(传 null),向后兼容现有调用方
|
|
|
+- Produces: API `POST /api/admin/knowledge-base/list` 接受 `sourceType`(精确匹配)与 `excludeSourceType`(排除匹配),不传则返回全部
|
|
|
+
|
|
|
+**Steps:**
|
|
|
+
|
|
|
+- [ ] **Step 1: Service 加 8 参重载与条件**
|
|
|
+
|
|
|
+在 `DanKnowledgeBaseService.java`:6 参 `list` 改为委托新 8 参方法(`list(keyword, status, page, size, tagId, dimensionId, null, null)`)。8 参方法内新增:
|
|
|
+
|
|
|
+```java
|
|
|
+if (sourceType != null && !sourceType.isEmpty()) {
|
|
|
+ wrapper.eq(DanKnowledgeBase::getSourceType, sourceType);
|
|
|
+}
|
|
|
+if (excludeSourceType != null && !excludeSourceType.isEmpty()) {
|
|
|
+ wrapper.ne(DanKnowledgeBase::getSourceType, excludeSourceType);
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+排序改为 `wrapper.orderByAsc(DanKnowledgeBase::getSort).orderByAsc(DanKnowledgeBase::getId)`(id 作为稳定 tie-break)。
|
|
|
+
|
|
|
+- [ ] **Step 2: Controller 解析新参数**
|
|
|
+
|
|
|
+`KnowledgeBaseController.list` 在解析 dimensionId 后追加:
|
|
|
+
|
|
|
+```java
|
|
|
+String sourceType = (String) params.get("sourceType");
|
|
|
+String excludeSourceType = (String) params.get("excludeSourceType");
|
|
|
+```
|
|
|
+
|
|
|
+调用改为 `danKnowledgeBaseService.list(keyword, status, page, size, tagId, dimensionId, sourceType, excludeSourceType)`。
|
|
|
+
|
|
|
+- [ ] **Step 3: 删除 /article/list 死端点**
|
|
|
+
|
|
|
+langgraph 改用 `/api/admin/knowledge-base/list` 后,`HealthKnowledgeBaseController.article/list` 无人调用。同文件删除该端点方法及 `HealthKnowledgeBaseService.pageArticles`(**保留** `/query` `/list` `/import` `/delete` 等其他端点——`health_butler_graph` 依赖 `/query`)。
|
|
|
+
|
|
|
+- [ ] **Step 4: 编译验证**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd /app/cfc/cfc-backend && mvn compile -DskipTests -q
|
|
|
+```
|
|
|
+Expected: BUILD SUCCESS,无编译错误。
|
|
|
+
|
|
|
+- [ ] **Step 5: 打包 + 备份 + 部署 + 验证**
|
|
|
+
|
|
|
+```bash
|
|
|
+BACKUP=/app/pro/cfc/backend/cfc-backend-$(date +%Y%m%d_%H%M%S)_b6_knowledge_unify.jar
|
|
|
+cp /app/pro/cfc/backend/cfc-backend-1.0.0.jar $BACKUP
|
|
|
+mvn package -DskipTests
|
|
|
+cp target/cfc-backend-1.0.0.jar /app/pro/cfc/backend/
|
|
|
+systemctl restart cfc-backend
|
|
|
+```
|
|
|
+
|
|
|
+验证(全部通过后才能进 Task 2):
|
|
|
+
|
|
|
+```bash
|
|
|
+curl -s -X POST http://localhost:9082/api/admin/knowledge-base/list -H 'Content-Type: application/json' -d '{"page":1,"size":1}' | jq '.data.total' # 期望 39
|
|
|
+curl -s -X POST http://localhost:9082/api/admin/knowledge-base/list -H 'Content-Type: application/json' -d '{"page":1,"size":1,"excludeSourceType":"article"}' | jq '.data.total' # 期望 39
|
|
|
+```
|
|
|
+Expected: 均 39(INSERT 前 article 为 0 条)。同时确认 `systemctl is-active cfc-backend` = active。
|
|
|
+
|
|
|
+- [ ] **Step 6: Commit**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd /app/cfc && git add cfc-backend/src/main/java/com/etotem/cfc/service/DanKnowledgeBaseService.java cfc-backend/src/main/java/com/etotem/cfc/service/HealthKnowledgeBaseService.java cfc-backend/src/main/java/com/etotem/cfc/controller/admin/KnowledgeBaseController.java cfc-backend/src/main/java/com/etotem/cfc/controller/HealthKnowledgeBaseController.java
|
|
|
+git commit -m "feat(knowledge): list 接口支持 sourceType/excludeSourceType 过滤 + id 稳定分页,移除废弃 /article/list 端点"
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### Task 2: langgraph 数据源改造 + 镜像构建(不部署)
|
|
|
+
|
|
|
+**Files:**
|
|
|
+- Modify: `cfc-langgraph/app/tools/java_client.py:146-166`(get_dan_knowledge_base)
|
|
|
+- Modify: `cfc-langgraph/app/tools/java_client.py:145-172`(get_microbiome_articles,当前调 `/api/health/knowledge/article/list`)
|
|
|
+
|
|
|
+**Interfaces:**
|
|
|
+- Consumes: Task 1 的 `POST /api/admin/knowledge-base/list`(`sourceType` / `excludeSourceType`)
|
|
|
+- Produces: `get_dan_knowledge_base()` → 仅案例报告(排除 article);`get_microbiome_articles()` → 仅菌群文章(article),返回结构与 `_build_chunks` 期望一致:`{id, title, content, category, source_url, sourceUrl, pubDate, createdAt, updatedAt}`
|
|
|
+
|
|
|
+**Steps:**
|
|
|
+
|
|
|
+- [ ] **Step 1: get_dan_knowledge_base 加排除**
|
|
|
+
|
|
|
+请求体改为 `{"page": page, "size": size, "status": 1, "excludeSourceType": "article"}`,size 保持 1000。docstring 补注:案例报告源,排除 article(菌群文章)。
|
|
|
+
|
|
|
+- [ ] **Step 2: get_microbiome_articles 改数据源**
|
|
|
+
|
|
|
+改为分页拉 `POST /api/admin/knowledge-base/list`,请求体 `{"page": page, "size": size, "status": 1, "sourceType": "article"}`(size 50,ORDER BY id 由后端保证)。字段映射对齐 `_build_chunks` 期望键(title/content/category 为空串/source_url 留空/pubDate 取 createdAt 或 updatedAt)。
|
|
|
+
|
|
|
+- [ ] **Step 3: 镜像构建(后台,不部署)**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd /app/cfc/cfc-langgraph && nohup bash -c 'docker compose build langgraph-svc > /tmp/langgraph-build5.log 2>&1' &
|
|
|
+```
|
|
|
+等待完成(检查 `/tmp/langgraph-build5.log` 末行含 `Successfully built` 或 `DONE`,`docker images` 确认新镜像 tag)。**不要执行 `docker compose up`**。
|
|
|
+
|
|
|
+- [ ] **Step 4: 提交**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd /app/cfc && git add cfc-langgraph/app/tools/java_client.py && git commit -m "feat(langgraph): microbiome 源改拉 dan_knowledge_base(source_type=article),dan 源排除 article"
|
|
|
+```
|
|
|
+
|
|
|
+**验收(进 Task 3 前):** 后端新接口可用 + langgraph 镜像已构建但容器未替换。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### Task 3: DB 迁移(备份 → INSERT 809 篇 → 校验)
|
|
|
+
|
|
|
+**Files:**
|
|
|
+- Create: `/tmp/migrate_articles.sql`(迁移脚本,上传远程执行)
|
|
|
+
|
|
|
+**Interfaces:**
|
|
|
+- Consumes: Task 1 的后端新接口(验证用)
|
|
|
+- Produces: `dan_knowledge_base` 含 848 条(39 file + 809 article),source_type 区分
|
|
|
+
|
|
|
+**Steps:**
|
|
|
+
|
|
|
+- [ ] **Step 1: 备份源表**
|
|
|
+
|
|
|
+```bash
|
|
|
+MY="mysql -h mysql-internet-cn-north-1-23feae22680e4dfa.rds.jdcloud.com -P 3306 -u cfc -pcfc@1314 zxyj"
|
|
|
+$MY -e "DROP TABLE IF EXISTS dan_knowledge_base_bak_20261020; CREATE TABLE dan_knowledge_base_bak_20261020 LIKE dan_knowledge_base; INSERT INTO dan_knowledge_base_bak_20261020 SELECT * FROM dan_knowledge_base;"
|
|
|
+$MY -e "DROP TABLE IF EXISTS health_knowledge_base_bak_20261020; CREATE TABLE health_knowledge_base_bak_20261020 LIKE health_knowledge_base; INSERT INTO health_knowledge_base_bak_20261020 SELECT * FROM health_knowledge_base;"
|
|
|
+```
|
|
|
+Expected: 两备份表行数 = 39 / 809。
|
|
|
+
|
|
|
+- [ ] **Step 2: INSERT 809 篇(保留原始时间戳)**
|
|
|
+
|
|
|
+```sql
|
|
|
+INSERT INTO dan_knowledge_base (title, content, sort, status, source_url, source_type, created_at, updated_at)
|
|
|
+SELECT item_name, description, 0, 1, source, 'article', created_at, updated_at
|
|
|
+FROM health_knowledge_base
|
|
|
+WHERE item_type = 'article';
|
|
|
+```
|
|
|
+Expected: `INSERT` 影响 809 行。
|
|
|
+
|
|
|
+- [ ] **Step 3: 校验**
|
|
|
+
|
|
|
+```bash
|
|
|
+$MY -e "SELECT source_type, COUNT(*) FROM dan_knowledge_base GROUP BY source_type;" # 期望 file=39, article=809
|
|
|
+$MY -e "SELECT COUNT(*) FROM dan_knowledge_base WHERE CHAR_LENGTH(title) > 200;" # 期望 0
|
|
|
+$MY -e "SELECT MIN(CHAR_LENGTH(content)), MAX(CHAR_LENGTH(content)) FROM dan_knowledge_base WHERE source_type='article';"
|
|
|
+$MY -e "SELECT MIN(created_at), MAX(created_at) FROM dan_knowledge_base WHERE source_type='article';" # 期望为原始时间,非 2026-10-20
|
|
|
+curl -s -X POST http://localhost:9082/api/admin/knowledge-base/list -H 'Content-Type: application/json' -d '{"page":1,"size":1}' | jq '.data.total' # 期望 848
|
|
|
+```
|
|
|
+若任一校验不符,**回滚**:`$MY -e "DELETE FROM dan_knowledge_base WHERE source_type='article';"` 后修正脚本重跑。
|
|
|
+
|
|
|
+- [ ] **Step 4: 提交迁移脚本**
|
|
|
+
|
|
|
+```bash
|
|
|
+mkdir -p /app/cfc/docs/migrations && cp /tmp/migrate_articles.sql /app/cfc/docs/migrations/20261020_articles_to_dan_knowledge.sql
|
|
|
+cd /app/cfc && git add docs/migrations && git commit -m "docs(knowledge): 809 篇菌群文章迁移至 dan_knowledge_base 脚本"
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### Task 4: 部署 langgraph 新镜像 + 全量重建索引
|
|
|
+
|
|
|
+**Files:** 无源码改动(仅部署 + 触发)
|
|
|
+
|
|
|
+**Interfaces:**
|
|
|
+- Consumes: Task 2 已构建镜像 + Task 3 已迁移数据
|
|
|
+- Produces: Chroma `cfc_knowledge` collection 三源重建完成,metadata 键 id/source/post_id/title/category/tags/source_url/pub_date/chunk_index/chunk_total
|
|
|
+
|
|
|
+**Steps:**
|
|
|
+
|
|
|
+- [ ] **Step 1: 替换容器**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd /app/cfc/cfc-langgraph && docker compose up -d --force-recreate langgraph-svc
|
|
|
+docker ps --filter name=langgraph -f status=healthy
|
|
|
+```
|
|
|
+Expected: 容器 healthy 且使用 Task 2 的新镜像 digest。
|
|
|
+
|
|
|
+- [ ] **Step 2: 触发全量重建**
|
|
|
+
|
|
|
+```bash
|
|
|
+curl -s -m 60 -X POST http://localhost:9000/api/v1/knowledge-base/sync
|
|
|
+```
|
|
|
+Expected: 同步任务启动(首次延迟 120s 后执行)。
|
|
|
+
|
|
|
+- [ ] **Step 3: 监控重建进度**
|
|
|
+
|
|
|
+```bash
|
|
|
+docker logs --tail -50 cfc-langgraph-langgraph-svc-1 2>&1 | grep -E "知识库同步|同步完成|ERROR"
|
|
|
+```
|
|
|
+Expected: 依次看到 article / microbiome / dan_knowledge 三源同步日志,microbiome 为 809 篇,无 ERROR。重建约 20–30 分钟(SiliconFlow 429 退避)。
|
|
|
+
|
|
|
+- [ ] **Step 4: 验证三源统计**
|
|
|
+
|
|
|
+```bash
|
|
|
+curl -s -X POST http://localhost:9000/api/v1/knowledge-base/stats | python3 -m json.tool
|
|
|
+```
|
|
|
+Expected: `by_source` 三源均有数据,microbiome 块数 ≈ 原 25369 量级,dan_knowledge ≈ 1885,**无 source='microbiome' 出现在 article 或反之**(窗口期双重索引检查)。
|
|
|
+
|
|
|
+**验收(进 Task 5 前):** 三源重建完成 + 计数符合预期 + 无 ERROR 日志。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### Task 5: 前端知识库管理页增强 + 删除健康知识库页
|
|
|
+
|
|
|
+**Files:**
|
|
|
+- Modify: `cfc-web/src/components/KnowledgeTable/index.vue:10-25`(加来源方式列)
|
|
|
+- Modify: `cfc-web/src/views/admin/knowledge/index.vue:40-50`(加 sourceType 筛选下拉)+ fetch 参数
|
|
|
+- Modify: `cfc-web/src/components/KnowledgeDialog/index.vue`(查看长文详情对话框,如现有 content 列已支持展开则跳过)
|
|
|
+- Delete: `cfc-web/src/views/admin/health-knowledge.vue`
|
|
|
+- Modify: `cfc-web/src/router/index.js:772-776`(删 health-knowledge 路由)
|
|
|
+- Modify: `cfc-web/src/Layout.vue:235`(删菜单项)
|
|
|
+
|
|
|
+**Interfaces:**
|
|
|
+- Consumes: Task 1 的 `sourceType` 参数
|
|
|
+- Produces: 知识库管理页统一展示 848 条(source_type 可筛选/可识别),健康知识库页入口消失
|
|
|
+
|
|
|
+**Steps:**
|
|
|
+
|
|
|
+- [ ] **Step 1: KnowledgeTable 加来源列**
|
|
|
+
|
|
|
+在 sort 列前插入:
|
|
|
+
|
|
|
+```html
|
|
|
+<el-table-column prop="sourceType" label="来源方式" width="110" align="center">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <el-tag size="mini" :type="row.sourceType === 'article' ? 'success' : 'info'">{{ row.sourceType === 'article' ? '菌群文章' : (row.sourceType || '案例报告') }}</el-tag>
|
|
|
+ </template>
|
|
|
+</el-table-column>
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] **Step 2: index.vue 加 sourceType 筛选**
|
|
|
+
|
|
|
+筛选区加下拉:
|
|
|
+
|
|
|
+```html
|
|
|
+<el-select v-model="filters.sourceType" placeholder="全部来源" clearable style="width:140px">
|
|
|
+ <el-option label="案例报告" value="file" />
|
|
|
+ <el-option label="菌群文章" value="article" />
|
|
|
+</el-select>
|
|
|
+```
|
|
|
+
|
|
|
+fetch 时传入 `sourceType`(不传则返回全部)。
|
|
|
+
|
|
|
+- [ ] **Step 3: 删除健康知识库页**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd /app/cfc/cfc-web
|
|
|
+rm src/views/admin/health-knowledge.vue
|
|
|
+# 删 router/index.js 772-776 的 health-knowledge 路由对象
|
|
|
+# 删 Layout.vue:235 的菜单项
|
|
|
+grep -rn "health-knowledge\|健康知识库" src/ # 期望无残留(api 文件若有引用一并清理)
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] **Step 4: 构建 + 部署 + 验证**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd /app/cfc/cfc-web && npm run build 2>&1 | tail -3
|
|
|
+rsync -a --delete dist/ /app/pro/cfc/frontend/
|
|
|
+curl -s -k https://cfc.etotem.com.cn/admin/ -o /dev/null -w "%{http_code}\n" # 期望 200
|
|
|
+```
|
|
|
+Expected: Build complete;前端 200;产物 js 中 grep 无 `health/knowledge` 残留。
|
|
|
+
|
|
|
+- [ ] **Step 5: Commit**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd /app/cfc && git add -A cfc-web/src cfc-web/.last_build_commit && git commit -m "feat(knowledge): 知识库管理页统一展示案例报告与菌群文章(sourceType 筛选/标识),删除健康知识库页与路由"
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+### Task 6: 全链路验证 + 清理源表文章 + 推送
|
|
|
+
|
|
|
+**Files:** 无源码改动
|
|
|
+
|
|
|
+**Steps:**
|
|
|
+
|
|
|
+- [ ] **Step 1: 全链路验证**
|
|
|
+
|
|
|
+```bash
|
|
|
+# 后端
|
|
|
+systemctl is-active cfc-backend
|
|
|
+curl -s -o /dev/null -w "%{http_code}" -X POST http://localhost:9082/api/cart/list # 期望 200
|
|
|
+# 前端
|
|
|
+curl -s -o /dev/null -w "%{http_code}" -k https://cfc.etotem.com.cn/admin/ # 期望 200
|
|
|
+# 后端日志无 ERROR
|
|
|
+grep -c " ERROR " /app/pro/cfc/backend/cfc-backend.log
|
|
|
+# langgraph 三源统计
|
|
|
+curl -s -X POST http://localhost:9000/api/v1/knowledge-base/stats | python3 -m json.tool
|
|
|
+# 磁盘
|
|
|
+du -sh /var/lib/docker/volumes/cfc-langgraph_langgraph-data/_data/
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] **Step 2: 清理源表文章数据(表保留)**
|
|
|
+
|
|
|
+```bash
|
|
|
+MY="mysql -h mysql-internet-cn-north-1-23feae22680e4dfa.rds.jdcloud.com -P 3306 -u cfc -pcfc@1314 zxyj"
|
|
|
+$MY -e "SELECT item_type, COUNT(*) FROM health_knowledge_base GROUP BY item_type;" # 确认仅 article
|
|
|
+$MY -e "DELETE FROM health_knowledge_base WHERE item_type='article';" # 期望删 809
|
|
|
+$MY -e "SHOW TABLES LIKE 'health_knowledge_base';" # 期望表仍存在
|
|
|
+$MY -e "SELECT COUNT(*) FROM health_knowledge_base;" # 期望 0
|
|
|
+```
|
|
|
+Expected: 表存在且 `COUNT(*)=0`,其他 item_type 行未被删除。
|
|
|
+
|
|
|
+- [ ] **Step 3: 推送 + 工作区干净**
|
|
|
+
|
|
|
+```bash
|
|
|
+cd /app/cfc && git push origin cfclub && git status --short # 期望空输出
|
|
|
+```
|
|
|
+
|
|
|
+**最终验收(全部通过):** 管理端「知识库管理」页 848 条统一展示且可筛选;「健康知识库」菜单/路由消失;向量库三源 by_source 计数符合设计(microbiome ≈ 25369、dan_knowledge ≈ 1885、article 不变);无 ERROR 日志;磁盘不膨胀;`health_knowledge_base` 表保留空置。
|