refactor: 后端仓库层收口(A1:课程/产品/素材)+ 收进工作区既有对象化重构

本提交含两部分。第一部分是本轮工作;第二部分是此前一直留在工作区、
从未提交的对象化重构,与第一部分在文件上互相咬合(internal/repository
整个包都是未跟踪状态,且 api 层已有文件引用它),无法拆成两个可编译的提交。

一、仓库层收口 A1 批(本轮工作)

把 api 层手写的 store.DB 查询收进具名仓库方法,只给真正获益的对象做方法,
不机械包裹全量。本批迁移 22 处裸查询(courses.go 9 / media.go 12 / products.go 1),
新增方法:

- MediaFileRepo.ListByBind / ListForAudit / MarkExtracted
- KnowledgeChunkRepo.CountByMediaFile
- ProductRepo.GetVisibleByID

两条业务口径改由仓库单点持有,避免各处手写漂移:
「只有 approved 素材出现在课程详情」与「已停用产品不在课程详情露出」。

修掉两个真实缺陷:
- ProductRepo.GetByID 缺 Where 条件。此前 GET /api/products/{id} 对任意 id 都返回
  第一条产品、对不存在的 id 返回 200,且 PUT /api/products/{id} 会覆盖第一条产品
  —— 数据损坏级。全仓扫描确认这是唯一一处同型写法。
- ProductRepo.Delete 写 status="deleted",而 DELETE 处理器文档与回包都声称
  "inactive",接口在说谎;管理员用 status=all 拉列表会看到前端不认识的状态。
  已对齐为 inactive(与 CourseRepo.Delete 一致)。

删除 8 个零调用且列名不存在的死方法(一调即 SQL 报错):
- media_file 上的 file_path / file_type / approval_status 三列并不存在,
  GetByPath / ListByType / UpdateStatus 全废
- knowledge_chunk 上的 space_id 列不存在(模型早已改为 knowledge_space_key),
  List / Total / ListBySpaceIDs / DeleteBySpace / SearchByVector 全废
取舍边界:能对当前 schema 跑通的死方法保留,跑不通的删或修。

CourseRepo.List 补齐 status=all 档(此前传给它会当作 status='all' 过滤出空列表)。
该方法此前零调用,现与产品列表语义对齐。

验证:go build ./... 与 go test ./... 全绿;另用真实 HTTP 请求验证 34 项
(课程 17 / 产品 3 / 素材 14),跑在数据库副本与独立 KB_DATA_DIR 上,
含 multipart 真上传 → 审批 → pdftotext 提取 → 分片入库的完整链路。

二、此前未提交的对象化重构(非本轮工作)

- 新增 internal/repository 仓库层、connectors、skills、specialists、xapps、jsonutil,
  model/task_record|task_run|task_artifact、api/task_runtime|action_definition|chat_message
- 删除 api/app_definition、connectors、my_app_center、notification、office_skill、
  export_docx|pptx|xlsx、official_account_* 等,随 XApp/Skill/Specialist/Connector
  可插拔打包方向(AR10/AR11)调整
- 资产目录归位:backend-go/knowledge_source → assets/knowledge/source、
  training_materials → assets/training/materials;README 内相对路径同步加深两级;
  deploy env 补 ASSET_ROOT_DIR 并改 KNOWLEDGE_SOURCE_DIR / TRAINING_MATERIALS_DIR
- 前端新增 skills/ specialists/ connectors/ xapps/ 目录与对应页面

验证:前端 npm run build 通过(7.26s)。

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
eaiadmin
2026-09-19 01:23:51 +08:00
co-authored by Claude Code
parent ddd2d2cbd8
commit 14f303459e
448 changed files with 18792 additions and 17027 deletions
+132 -475
View File
@@ -1,68 +1,70 @@
# 对象命名标准化清单
> 日期:2026-09-17
> 性质:代码目录、文件名、变量名、函数名的对象命名标准化清单
> 性质:**阶段性清单 / 历史记录**
> 2026-09-18 补注:本文原本记录的是 09-17 当天的待改项。其后代码与规范已大幅收口,**请勿再把本文当作当前现状说明**。当前规范以 `AR09_Object_Naming_Standard.md`、`TOP_CODING_RULES.md` 与代码现实为准。
> 关联文档:
> - `docs/对象标准化与解耦总则.md`
> - `docs/2026-09-17_六层架构与三对象建设重点阶段性复盘.md`
> - `docs/02_Architecture/AR09_Object_Naming_Standard.md`
> - `更名收尾说明.md`
---
## 一、结论
## 一、这份清单现在该怎么读
当前代码目录整体上已经开始围绕对象收口,
但命名层面仍然处于**新旧术语混用**的过渡态。
这不是“还有哪些问题没修”的现状文档,
而是一次命名收口行动的**问题发现记录**。
最准确的判断是:
它现在有两个用途:
- **目录结构基本清楚**
- **对象落点已经清楚**
- **命名标准还不统一**
- **旧词残留仍在持续污染对象边界**
1. 解释我们当时为什么要动那些名字
2. 给后来者留一份“哪些误导性命名曾真实存在过”的反例库
当前最主要的问题不是“找不到代码在哪”,
而是:
如果本文与当前代码冲突:
**看名字时,仍然经常不知道它到底指的是专员、技能、应用、默认助手,还是历史遗留概念。**
```text
以当前代码 + AR09 + 更名收尾说明 为准
```
---
## 二、当前对象落点是否清楚
## 二、09-18 后的总状态
### 1. 后端主模型落点是清楚的
### 1. 已完成的主收口
- 专员:`backend-go/internal/model/specialist.go`
- 技能:`backend-go/internal/model/skill_definition.go`
- 应用:`backend-go/internal/model/app_definition.go`
- 连接器:`backend-go/internal/connector/*`
以下问题已经在 09-18 这轮重构中完成:
其中三大对象模型命名基本准确:
| 项 | 09-17 问题 | 09-18 结果 |
|---|---|---|
| 应用对象主词 | `app` 与对象体系冲突 | 已统一为 `xapp` |
| 任务运行命名 | `worker_*` 混杂“专员形态 / 任务运行”两层语义 | 已统一为 `task_*` |
| 技能对象分类字段 | `RoleKind / role_kind` 带旧 `role` 心智 | 已迁到 `ObjectKind / object_kind` |
| AI 用量字段 | `capability` 停留在存储层 | 已迁到 `usage_kind` |
| 工作台入口协议 | 写读参数不一致 | 已统一为 `xapp_specialist / xapp_skill / xapp_prompt`,并抽成共享常量 |
| 静态旧目录变量 | `businessApps`、`availableSkills` | 前者已删;后者已更名 `staticSkillCatalog` |
| 默认聊天入口旧名 | `assistant.js` / `smart_assistant.go` | 已收口到 `chatMessage.js` / `chat_message.go` |
| XApp 中心旧存储 key | `eai-app-center` 长期兼容 | 已改为一次迁移后清旧 key |
- [specialist.go](file:///home/eaiadmin/eaifiles/codebase/pj0235-eai_agentplatform-ubu/eai_agentplatform/backend-go/internal/model/specialist.go)
- [skill_definition.go](file:///home/eaiadmin/eaifiles/codebase/pj0235-eai_agentplatform-ubu/eai_agentplatform/backend-go/internal/model/skill_definition.go#L5-L32)
- [app_definition.go](file:///home/eaiadmin/eaifiles/codebase/pj0235-eai_agentplatform-ubu/eai_agentplatform/backend-go/internal/model/app_definition.go#L5-L38)
### 2. 仍可继续优化,但不再是主阻塞
### 2. 前端 catalog store 方向也是清楚的
这些点还值得继续做,但已经不是“命名体系没立住”的主问题:
- `specialistCatalog`
- `skillCatalog`
- `appCatalog`
对应文件:
- [specialistCatalog.js](file:///home/eaiadmin/eaifiles/codebase/pj0235-eai_agentplatform-ubu/eai_agentplatform/frontend/src/store/specialistCatalog.js#L17-L88)
- [skillCatalog.js](file:///home/eaiadmin/eaifiles/codebase/pj0235-eai_agentplatform-ubu/eai_agentplatform/frontend/src/store/skillCatalog.js)
- [appCatalog.js](file:///home/eaiadmin/eaifiles/codebase/pj0235-eai_agentplatform-ubu/eai_agentplatform/frontend/src/store/appCatalog.js#L22-L155)
这一层说明:**对象目录化方向是正确的。**
| 项 | 当前状态 |
|---|---|
| `projectStore.js` 文件名后缀 | 仍是孤例,可继续收口为 `project.js` |
| 某些历史方案文档 | 仍保留旧路径名,需逐步补“历史映射”说明 |
| 一些研究/阶段性文档中的 `app_*` 或 `capability` | 多属历史语境,不应再回流到代码实现 |
---
## 三、当前命名不清晰的主要问题
## 三、09-17 当时识别出的核心问题
## 3.1 旧术语和新术语混用
下面这些判断在当时是成立的,之所以保留,是因为它们解释了后续为什么要那样改。
当前代码中同时混着:
### 3.1 旧术语和新术语混用
当时代码里同时混着:
- `role`
- `assistant`
@@ -72,478 +74,133 @@
- `worker`
- `capability`
这会导致以下问题:
这个判断是对的,也是后续重构的出发点。
1. 同一个对象被多个词指代
2. 同一个词被多个对象复用
3. 页面层很容易把对象边界重新写乱
### 3.2 文件名、字段名、变量名在讲旧故事
### 典型例子
当时最典型的误导项包括:
技能模型已经叫 `SkillDefinition`,
但字段仍叫 `RoleKind`:
[skill_definition.go:L5-L25](file:///home/eaiadmin/eaifiles/codebase/pj0235-eai_agentplatform-ubu/eai_agentplatform/backend-go/internal/model/skill_definition.go#L5-L25)
这说明:
- 模型名是新的
- 字段语义还是旧的
这类命名会误导人以为 `role` 仍然是正式一级对象。
## 3.2 文件名与真实职责不完全一致
最典型的是:
- [capability_definition.go](file:///home/eaiadmin/eaifiles/codebase/pj0235-eai_agentplatform-ubu/eai_agentplatform/backend-go/internal/api/capability_definition.go#L1-L120)
这个文件名叫 `capability_definition`,
但里面做的是:
- `skillDefinitionReq`
- `actionDefinitionReq`
- `ListSkillDefinitions`
问题不只是不好看,
而是它在语义上制造了一个模糊的一级概念:`capability`。
当前系统正式对象语言应是:
- `specialist`
- `skill`
- `app`
- `connector`
- `action`(底层)
不应再让 `capability` 作为主要文件名继续扩散。
## 3.3 历史静态目录变量名不准
最典型的旧变量在:
[workbench.js:L99-L105](file:///home/eaiadmin/eaifiles/codebase/pj0235-eai_agentplatform-ubu/eai_agentplatform/frontend/src/config/workbench.js#L99-L105)
[workbench.js:L1434-L1443](file:///home/eaiadmin/eaifiles/codebase/pj0235-eai_agentplatform-ubu/eai_agentplatform/frontend/src/config/workbench.js#L1434-L1443)
包括:
- `availableSkills`
- `capability_definition.go`
- `RoleKind`
- `businessApps`
- `connectors`
- `availableSkills`
- 页面局部 `const app = specialistCatalog.getByKey(...)`
- `assistant.js`
- `workerRuntime.js`
其中问题最大的是:
这些名字的共同问题不是“难看”,而是**让对象边界持续失真**。
- `businessApps` 实际装的是专员目录,不是应用目录
- `availableSkills` 现在更像静态 fallback,不是正式生产技能目录
### 3.3 入口协议写读不对称
所以这些名字会把开发者带偏。
09-17 时,应用目录与工作台的 query 参数协议不统一,这不是风格问题,而是功能 bug。
## 3.4 页面局部变量有失真
例如:
[SmartAssistantPage.vue:L311-L334](file:///home/eaiadmin/eaifiles/codebase/pj0235-eai_agentplatform-ubu/eai_agentplatform/frontend/src/views/workbench/SmartAssistantPage.vue#L311-L334)
这里:
```js
const app = specialistCatalog.getByKey(key)
```
拿到的是专员对象,却命名成 `app`。
这类局部变量不会影响编译,
但会持续破坏对象认知。
## 3.5 路由参数协议不统一
应用目录里拼路由时使用:
[appCatalog.js:L135-L145](file:///home/eaiadmin/eaifiles/codebase/pj0235-eai_agentplatform-ubu/eai_agentplatform/frontend/src/store/appCatalog.js#L135-L145)
- `specialist`
- `skill`
- `prompt`
但工作台页面读取的是:
[SmartAssistantPage.vue:L602-L626](file:///home/eaiadmin/eaifiles/codebase/pj0235-eai_agentplatform-ubu/eai_agentplatform/frontend/src/views/workbench/SmartAssistantPage.vue#L602-L626)
- `app_specialist`
- `app_skill`
- `app_prompt`
这已经不是风格差异,
而是**入口协议不统一**。
## 3.6 默认助手概念没有完全收口
当前存在:
- API 文件名:`assistant.js`
- 默认技能 key:`smart-assistant`
- 默认专员 key:`general-assistant`
见:
- [assistant.js:L1-L3](file:///home/eaiadmin/eaifiles/codebase/pj0235-eai_agentplatform-ubu/eai_agentplatform/frontend/src/api/assistant.js#L1-L3)
- [workerRuntime.js:L17-L21](file:///home/eaiadmin/eaifiles/codebase/pj0235-eai_agentplatform-ubu/eai_agentplatform/frontend/src/store/workerRuntime.js#L17-L21)
这说明“assistant”当前同时在承担:
- 默认聊天接口名
- 默认技能语义
- 默认专员语义
需要明确边界,不然以后越做越乱。
这一条后来直接推动了共享常量 `XAPP_ENTRY_QUERY_KEYS` 的建立。
---
## 四、标准命名原则
## 四、旧结论与新现实映射表
## 4.1 正式对象术语
为了避免后续阅读时把旧清单直接套到现代码,这里给出一张映射表。
对外和对内统一如下:
| 本文旧说法 | 当前应理解为 |
|---|---|
| `app` 对象 | `xapp` 对象 |
| `appCatalog.js` | `xappCatalog.js` |
| `assistant.js` | `chatMessage.js` |
| `smart_assistant.go` | `chat_message.go` |
| `workerRuntime.js` | `taskRuntime.js` |
| `api/worker.js` | `api/taskRuntime.js` |
| `worker_task.go` / `worker_run.go` / `worker_artifact.go` | `task_record.go` / `task_run.go` / `task_artifact.go` |
| `app_specialist / app_skill / app_prompt` | `xapp_specialist / xapp_skill / xapp_prompt` |
| `RoleKind` | `ObjectKind` |
| `capability`(AI 用量字段) | `usage_kind` |
| `capability_definition.go` | `skill_action_definition.go` |
| `businessApps` | 已删除,不应复活 |
| `availableSkills` | `staticSkillCatalog` |
- 专员:`specialist`
- 技能:`skill`
- 应用:`app`
- 连接器:`connector`
- 动作:`action`
---
## 4.2 非正式或历史兼容词的处理原则
## 五、保留下来的有效原则
以下词允许保留在历史兼容层,
但**不再继续扩散为新的正式命名**:
这份旧清单里,有些原则到今天仍然完全成立:
- `role`
- `businessApps`
- `availableSkills`
- `capability`(除非明确表示“泛能力总称”,不能再充当对象级文件名)
- `assistant`(除非明确指聊天接口或默认助手)
## 4.3 命名优先级
命名时遵守:
### 5.1 对象名必须准确
```text
对象准确性 > 历史兼容性 > 书写简短
```
意思是:
这条没有过时。
- 宁可名字长一点
- 也不要再用会误导对象边界的旧词
### 5.2 旧词只能留在兼容层
---
像下面这些旧词:
## 五、标准化建议
- `role`
- `worker`
- `capability`
- `assistant`
## 5.1 P0:立即统一入口协议和最容易误导人的命名
只有在这三类位置允许保留:
### A. 统一应用入口 query 参数
1. 迁移逻辑
2. 迁移测试
3. 历史说明文档
当前应统一为一套,
不要一边写 `specialist/skill/prompt`,
一边读 `app_specialist/app_skill/app_prompt`。
不能再回流到业务模型、API、store、组件和新文档标题。
建议二选一,但必须全链路统一。
### 5.3 页面局部变量也会污染认知
推荐统一成:
`const app = specialistCatalog.getByKey(...)` 这种问题之所以要修,
不是因为会报错,
而是因为它会被后续代码继续照抄。
- `app_specialist`
- `app_skill`
- `app_prompt`
这一判断现在仍然成立。
原因:
### 5.4 入口协议必须抽成共享常量
- 一眼能看出这是“应用带入工作台”的预置参数
- 不会和普通页面 query 混淆
### B. 修正页面里的失真变量名
例如:
- `const app = specialistCatalog.getByKey(...)`
应改成:
- `const specialist = ...`
这类改动优先级很高,
因为它们会直接影响后续开发者理解对象边界。
### C. 停止新增 `businessApps` / `availableSkills` 这类旧变量名
现有代码可暂时保留兼容,
但后续新增代码禁止继续使用这些命名。
---
## 5.2 P1:统一文件名与对象职责
### A. `capability_definition.go`
当前建议拆或改名:
方案 1:
- `skill_definition.go`
- `action_definition.go`
方案 2:
- 保留文件不拆,但改名为 `skill_and_action_definition.go`
不建议继续用:
- `capability_definition.go`
因为它已经不能准确表达该文件实际职责。
### B. `assistant.js`
当前如果它只是默认聊天接口,
建议更明确地表达为:
- `smartAssistant.js`
或
- `assistantChat.js`
而不是继续模糊地叫 `assistant.js`。
---
## 5.3 P1:统一 store 与 fallback 的命名语义
### A. `availableSkills`
如果继续保留作为静态补丁源,
建议改名为:
- `staticSkillCatalog`
或
- `legacySkillCatalog`
不要再叫:
- `availableSkills`
因为现在真正“可用技能目录”已经是后端 + `skillCatalog`。
### B. `businessApps`
如果继续保留作为专员静态兼容源,
建议改名为:
- `staticSpecialistCatalog`
或
- `legacySpecialistCatalog`
不要再叫:
- `businessApps`
因为它和 `app` 已经明确冲突。
---
## 5.4 P2:统一字段语义
### A. `RoleKind`
当前字段:
[skill_definition.go:L13](file:///home/eaiadmin/eaifiles/codebase/pj0235-eai_agentplatform-ubu/eai_agentplatform/backend-go/internal/model/skill_definition.go#L13)
建议后续迁移为更准确的名字,例如:
- `object_kind`
或
- `owner_kind`
如果业务语义是“这个技能归属于哪类对象”。
如果短期不迁字段,
至少要在文档中明确:
- `RoleKind` 是历史兼容字段
- 不再代表正式 `role` 概念
### B. `assistant` 的语义边界
需要明确规定:
- `assistant` 只用于默认通用助手的聊天接口语义
- `specialist` 才是正式对象名
否则会继续出现:
- 默认助手既像 skill 又像 specialist
- 页面里又再抽象成 role
---
## 六、按文件的具体清单
## 6.1 后端
### `backend-go/internal/model/skill_definition.go`
问题:
- `RoleKind` 仍带旧语义
建议:
- 文档先标记为历史兼容字段
- 后续统一迁移为更准确字段名
### `backend-go/internal/api/capability_definition.go`
问题:
- 文件名与实际职责不匹配
- `capability` 不是当前正式对象主词
建议:
- 重命名或拆分
### `backend-go/internal/api/router.go`
优点:
- `/api/specialists`
- `/api/skills`
- `/api/apps`
- `/api/connectors`
这层命名已经较清楚:
[router.go:L39-L49](file:///home/eaiadmin/eaifiles/codebase/pj0235-eai_agentplatform-ubu/eai_agentplatform/backend-go/internal/api/router.go#L39-L49)
建议:
- 保持这层对象 API 命名不再回退
## 6.2 前端
### `frontend/src/config/workbench.js`
问题:
- 是历史静态大杂烩
- `businessApps` 命名错误
- `availableSkills` 命名已过时
建议:
- 不再作为生产目录源
- 继续降级为静态 fallback
- 变量名按对象真实语义重命名
### `frontend/src/views/workbench/SmartAssistantPage.vue`
问题:
- 局部变量名存在失真
- `currentRolePresentation` 仍有旧 `role` 心智残留
建议:
- 局部变量全部改成对象准确名
- 将 `role presentation` 逐步收敛为 `currentObjectPresentation`
或明确区分:
- `currentSpecialistPresentation`
- `currentSkillPresentation`
- `defaultAssistantPresentation`
### `frontend/src/api/assistant.js`
问题:
- 文件名语义太宽
建议:
- 仅在确认其职责是“默认助手聊天接口”后保留
- 否则改名为更准确的接口文件名
### `frontend/src/store/appCatalog.js`
优点:
- `normalizeRemoteApp`
- `normalizeCustomApp`
- `resolveOpenRoute`
这套命名整体清楚:
[appCatalog.js:L22-L145](file:///home/eaiadmin/eaifiles/codebase/pj0235-eai_agentplatform-ubu/eai_agentplatform/frontend/src/store/appCatalog.js#L22-L145)
问题:
- 路由 query 命名与工作台读取不一致
建议:
- 先统一 query 协议
### `frontend/src/store/specialistCatalog.js`
优点:
- 命名整体比较准确
- `normalizeSpecialist / getByKey / getByPath` 清楚
见:
[specialistCatalog.js:L17-L87](file:///home/eaiadmin/eaifiles/codebase/pj0235-eai_agentplatform-ubu/eai_agentplatform/frontend/src/store/specialistCatalog.js#L17-L87)
建议:
- 继续作为专员目录的标准写法模板
---
## 七、执行顺序
建议按下面顺序做命名清理:
1. **统一入口协议**
- app query 参数统一
2. **清理页面级失真变量**
- 特别是 `SmartAssistantPage.vue`
- `CurrentObjectChip.vue`
- `PlusMenu.vue`
3. **清理历史静态变量名**
- `businessApps`
- `availableSkills`
4. **清理文件名级旧词**
- `capability_definition.go`
- `assistant.js`
5. **最后处理字段迁移**
- 如 `RoleKind`
这样做的原因是:
- 先收敛入口协议,避免继续产生新分叉
- 再清局部变量,马上提升可读性
- 最后再碰数据库字段,避免一次性改太重
---
## 八、最终判断
当前代码不是“命名完全混乱”,
而是:
**目录已经开始清楚,但命名标准还没有真正收口。**
最核心的问题不是技术能力,
而是术语迁移还没做完。
后续只要坚持:
09-17 的诊断后来被证明完全正确:
```text
对象名必须准确
旧词只做兼容
页面变量不得歪曲对象语义
路由 / API / store 使用同一套对象协议
能用结构消除的协议分叉,不要靠人工扫描补漏
```
这套代码的可读性会明显上一个台阶。
---
## 六、当前建议的阅读顺序
如果现在要继续做命名与对象规范工作,建议按这个顺序看:
1. [AR09_Object_Naming_Standard.md](file:///home/eaiadmin/eaifiles/codebase/pj0235-eai_agentplatform-ubu/docs/02_Architecture/AR09_Object_Naming_Standard.md)
2. [更名收尾说明.md](file:///home/eaiadmin/eaifiles/codebase/pj0235-eai_agentplatform-ubu/更名收尾说明.md)
3. 本文
原因很简单:
- `AR09` 讲**当前正式规范**
- `更名收尾说明` 讲**这轮收口后哪些旧名只该留在迁移里**
- 本文只讲**09-17 当时发现过什么问题**
---
## 七、结论
09-17 这份清单的价值不在于“它现在还是不是待办列表”,
而在于它准确记录了当时的混乱来源:
- 对象主词混用
- 路径协议分叉
- 旧变量名继续扩散
- 局部变量失真
- 历史术语假装仍是正式术语
而 09-18 的重构已经把这些主问题大体收口。
所以现在最准确的判断是:
```text
这份文档应被视为历史问题记录,而不是当前待办清单。
```
后续若继续优化,应优先清理仍会误导人的历史文档与剩余孤例,
而不是回头按本文旧路径逐项“照单执行”。