# T6 · 知识库·实体与图谱 > 对应任务:`T-P2-01`(12 类实体可存取)、`T-P2-05`(1~3 跳可解释路径)| 需求:`FR-KB-*`、架构 §6.2 kb 域、`TD-09` | 分支:`task/t6-kb-entity` | worktree:`/home/xsl/meida_backend-t6` > 先读《README.md(协作规程)》,遵守全部纪律。 ## 1. 目标 知识库的实体底座:12 类实体统一表的 CRUD 与状态机、`kb_relation` 邻接表 + 递归 CTE 的 1~3 跳图谱查询(可解释路径)、`kb_color` 自建色板存取。这是知识库可运营(M2 出口)的第一块。 ## 2. 已就绪的契约(协调提交已提供,禁改 models/migrations) ### 表(迁移 `0005` 已建,ORM 已加:`KbEntity`/`KbRelation`/`KbColor`,先读 `packages/shared/models.py` 核对列名) - `kb_entity`:`entity_id` PK 雪花、`entity_type` varchar(32)、`name` varchar(128)、`attrs` JSONB、`status` draft/reviewing/published/archived、`version` int、`source`、`license`、`updated_by`、`created_at/updated_at`;UNIQUE(entity_type,name)、Index(entity_type,status) - `kb_relation`:`relation_id` PK、`from_id`/`to_id` bigint、`rel_type` varchar(64)、`weight` Numeric(4,3)、`confidence` Numeric(4,3)、`evidence` varchar(255);UNIQUE(from_id,rel_type,to_id)、Index(to_id) - `kb_color`:`color_id` PK、`season_code` varchar(16)、`role` base/accent/avoid、`lab_l/lab_a/lab_b` Numeric(6,2)、`hex` varchar(7)、`name_cn` varchar(64);Index(season_code) ### 12 类 entity_type(知识库文档 §3.1,写进 schemas 的 Literal 校验) `item / color / style / body_shape / face_hair / occasion / material / accessory / makeup / rule / outfit / trend` ### 状态机(写进 service,非法跃迁抛 `AppError(STATE_CONFLICT)`) `draft → reviewing → published → archived`;`archived` 终态;`draft/reviewing → archived` 允许(撤稿);其余跃迁非法。每次**内容修改** version+1 且**不允许直接改 published 实体**——published 实体要改必须先回 draft(新版本走评审,这是知识库文档"发布回滚"的语义)。 ### 路由骨架 `apps/api/routers/kb.py` 空路由(prefix `/kb`)已注册 main.py——你填充。 ## 3. 实现要点 允许改动:`packages/kb/**`(service.py / repo.py / schemas.py / README.md)、`apps/api/routers/kb.py`、测试文件。**`packages/kb` 现只有 README + 空 `__init__`;`packages/rules`、`packages/retrieval` 归 T7/T8,禁碰。** 1. **schemas.py**(Pydantic):`EntityCreate`(entity_type/name/attrs)、`EntityUpdate`(仅 draft/reviewing 可用)、`EntityOut`(含 status/version/时间戳)、`RelationCreate`、`GraphPath`(路径节点序列 + 每跳 rel_type)、`ColorOut`。**跨域响应模型放本包**,apps/api/schemas.py 禁改。 2. **repo.py**:CRUD + `search_entities(entity_type, status, name_ilike, limit, offset)` + `traverse(from_id, max_hops)` —— 递归 CTE 用 `sqlalchemy.text()` 写原生 SQL(返回 hop 序列),1~3 跳,**防环**(CTE 里用 path 数组 + `NOT path @> ARRAY[to_id]` 判重)。参考架构 TD-09 的理由:浅层有界遍历,不需要图数据库。 3. **service.py**:状态机校验、版本递增、relation 写入(自环/重复抛 `AppError(BAD_REQUEST)`)、色板 CRUD(role/hex 格式校验,`#RRGGBB`)。实体创建时 `entity_id=next_id()`(`packages.domain.ids`)。 4. **路由**:`GET /kb/items`(分页 + entity_type/status 过滤)、`GET /kb/items/{id}`、`POST /kb/items`、`PATCH /kb/items/{id}`、`GET /kb/items/{id}/graph?max_hops=3`(1~3 跳,超界 422/400)。写接口**暂不挂鉴权以外的前置**(后台运营角色属 T-P2-09,先 CurrentUserId)。 ## 4. 测试要求 - 单测 `tests/unit/test_kb_entity.py`:状态机全跃迁矩阵(合法/非法)、12 类 Literal 校验、非法 entity_type 拒绝、色板 hex 校验。(纯逻辑部分;repo/service 层用集成覆盖。) - 集成 `tests/integration/test_kb_entity.py`(新文件):建实体→reviewing→published;改 published 被拒;draft 改→version+1;建 relation→graph 2 跳返回可解释路径(含每跳 rel_type);自环拒绝;`GET /v1/kb/items` 过滤分页。 ## 5. 禁改清单 通用禁改之外:`packages/rules/**`、`packages/retrieval/**`、`packages/identity/**`、`apps/api/routers/{auth,auth_sms}.py`、全部已有测试文件。 ## 6. 验收标准(T-P2-01/05) 1. 12 类实体可存取,`attrs` JSONB 差异化承载; 2. 状态机非法跃迁 100% 被拦(有测试矩阵证明); 3. 图谱 1~3 跳返回可解释路径且防环; 4. 全部检查绿(mypy 范围:`apps packages/shared packages/identity packages/billing packages/task packages/agent packages/compliance packages/analytics packages/storage packages/kb`)。 ## 7. 提交信息 ``` feat(kb): entity store with lifecycle, graph traversal and color palette 12 类实体统一表 + 状态机 + version 递增 + kb_relation 递归 CTE 1~3 跳 可解释路径(防环)+ kb_color 色板(T-P2-01/05,TD-09/18)。 偏差说明:<如有写在这里,无则写"无"> ```