entity/skill/SKILL.md

76 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: entity
description: 实体管理模块W-03——实体表entityCRUD、列表查询、实体文件导入entity_import 记录),通过 load_entity() 挂载。
---
# entity 模块
## 概述
实体管理模块提供实体表entity增删改查与文件导入entity_import 记录表)。依赖 world、scene 模块(逻辑关联,不加物理外键)。
## 数据模型
### 表 `entity`models/entity.json
| 字段 | 类型 | 说明 |
|------|------|------|
| id | str(32) | 主键 |
| world_id | str(32) | 所属世界→world.id 逻辑关联) |
| scene_id | str(32) | 所属场景→scene.id 逻辑关联codes 段配置,不加物理外键) |
| name | str(255) | 实体名称 |
| code | str(64) | 实体编码唯一idx_entity_code |
| entity_type | str(16) | 实体类型appcodes entity_type |
| status | str(16) | 状态appcodes entity_status |
| attributes_json | text | 属性 JSON |
| created_at | timestamp | 创建时间 |
| updated_at | timestamp | 更新时间 |
- 主键 `["id"]`;唯一索引 `idx_entity_code(code)`;索引 `idx_entity_world(world_id)``idx_entity_scene(scene_id)`
- codesworld_id → world(id/name)、scene_id → scene(id/name)、entity_type → appcodes_kv(parentid='entity_type')、status → appcodes_kv(parentid='entity_status')
### 表 `entity_import`models/entity_import.json只读
| 字段 | 类型 | 说明 |
|------|------|------|
| id | str(32) | 主键 |
| world_id | str(32) | 目标世界 |
| scene_id | str(32) | 目标场景 |
| file_name | str(255) | 导入文件名 |
| total / success / fail | int | 总数 / 成功 / 失败(默认 0 |
| status | str(16) | 导入状态appcodes import_status0 进行中/1 成功/2 失败) |
| created_at | timestamp | 导入时间 |
- 主键 `["id"]`;索引 `idx_entity_import_world(world_id)`**只读记录,不可手工增删改**
## 关键接口load_entity() 挂载到 ServerEnv
- `list_entities(params)``{list, total}`sqlPaging 分页,支持 world_id/scene_id/entity_type/status/name/code 过滤 + sort/order
- `get_entity({id})``{data}` 或错误
- `create_entity(ns)` → 校验 + world/scene 存在校验 + 自动 id/created_at/updated_at返回 `{success, id}`
- `update_entity(ns)` → 写 updated_at、剔除 `_text` 后缀、world/scene 校验
- `delete_entity({id})``{success, id}`
- `import_entities({world_id, scene_id, file_name, rows})``{success, total, success_count, fail, file_name}`
**事务批量**:先全量解析+校验含文件内编码查重再逐条插入任一条失败整批回滚无脏数据success_count 避免与布尔 success 冲突)
- `parse_entity_file(content, filename)``{rows: [...]}`JSON 数组 / JSON Lines / CSV 表头)
- `get_world_options()` / `get_scene_options()` / `get_entity_type_options()` / `get_entity_status_options()` / `get_import_status_options()``[{value, text}]`
### wwwroot/api/*.dspyREST 统一前缀 /api/*,宿主挂载后为 /entity/api/*.dspy
- `entity_list.dspy`(分页 `{list,total}`)、`entity_get.dspy``entity_create.dspy``entity_update.dspy``entity_delete.dspy`
- `entity_import.dspy`world_id + file → parse_entity_file → import_entities
- `get_search_world_id.dspy` / `get_search_scene_id.dspy` / `get_search_entity_type.dspy` / `get_search_status.dspy` / `get_search_import_status.dspy`(字典下拉)
### 错误结构(统一)
`{code, message, field, detail}`codePARAM_REQUIRED / FIELD_REQUIRED / FIELD_TOO_LONG /
WORLD_NOT_FOUND / SCENE_NOT_FOUND / DUPLICATE_CODE / PARSE_ERROR / INVALID_JSON / DB_ERROR / NOT_FOUND。
非法输入 100% 拦截不落库。
## 陷阱
- 库名禁止硬编码:.py 用 `ServerEnv().get_module_dbname("entity")`.dspy 用 `get_module_dbname("entity")`全局world/scene 表分别在 world/scene 模块库(`get_module_dbname("world"/"scene")`appcodes 在 `get_module_dbname("appbase")`
- dspy 无 importjson/get_sor_context/debug/params_kw 均预加载全局);函数经 load_entity() 注册后为全局,直接调用
- `create_entity` / `import_entities` 必须显式设置 `created_at = curDateString()`,否则 sor.C 静默丢记录
- `entity_import` 记录 total/success/fail 必须为 int
- `import_entities` 返回用 `success_count`(避免与布尔 `success` 键冲突)
- 三处同步注册entity/__init__.py 导出 ← entity/init.py 实现 ← load_entity() 注册(含复数别名 create_entities/update_entities/delete_entities
- 返回 `{list,total}` 分页用 `sor.sqlPaging`,不要硬编码 LIMIT/OFFSET
- CRUD json `new_data_url` 指向自定义 `api/entity_create.dspy`entity_import 为只读列表,无 editable
## 依赖
- worldworld_id 逻辑关联 + 世界下拉、scenescene_id 逻辑关联 + 场景下拉、appbaseappcodes 字典、rbac权限