chore: 工作台产品化进行中的改动

把工作区里其余在制品一并入库,主要是工作台产品化的推进:

  后端:新增 capability_definition / project / my_app_center / office_skill
        接口与 action_definition / skill_definition / project / user_app_center
        模型,config 加路由健康上报。
  前端:新增 frontend/src/skills(Office 技能与 workbuddy 复刻)、
        项目管理、应用中心、能力目录页,以及配套 api / store / config;
        聊天侧新增 SpecialistChip / SpecialistPanel / SkillStrip / AppChatRail
        等组件。
  清理:移除旧 views/tools 下的单页工具(已并入工作台)、_frozen 冻结组件、
        cmd/inspect_oa_debug 调试入口,以及两份调试笔记。
  其它:文档与启动脚本同步。

(这批改动与上一提交的 SY23 工作并行进行,此前已在同一工作区内交织。)

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
eaiadmin
2026-09-17 21:32:35 +08:00
co-authored by Claude Code
parent 8b136d4a10
commit 16d63de4e1
180 changed files with 22283 additions and 13850 deletions
+219 -223
View File
@@ -1,265 +1,260 @@
# eai_agentplatform_app — 数据库 Schema
# eai_agentplatform — 数据库 Schema
> **版本:V1.2 | 引擎:MySQL 8.0(关系数据)+ FAISS(向量检索)| ORM:GORM**
> **版本:V1.3 | 引擎:SQLite(单文件,GORM AutoMigrate 建表)**
> **最后更新:2026-08-16**
---
## 约定
> 数据库使用 **MySQL 8.0**(GORM AutoMigrate 建表),AI 知识检索采用 **MySQL 全文索引(关键词)+ FAISS 向量检索(语义)双路混合召回**。
> 下列 DDL 为权威字段定义;`ENUM`、`FULLTEXT ngram`、`ON DELETE` 外键级联为 MySQL 原生能力。
> V1.4–V1.7 新增表(岗位/积分/证书/部门/消息等)见文末「新增表清单」。
- 主键 `id` 为 `BIGINT UNSIGNED AUTO_INCREMENT`
- 数据库使用 **SQLite 单文件** `data/eai_agentplatform.db`(GORM AutoMigrate 首次启动自动建表)
- AI 知识检索为 **Go 原生 brute-force 向量检索**(余弦相似度)+ 关键词兜底(不依赖外部向量库)
- 主键 `id` 为 `INTEGER PRIMARY KEY AUTOINCREMENT`
- 时间字段 `created_at` / `updated_at` 为 `DATETIME`,默认 `CURRENT_TIMESTAMP`
- 外键命名规则:`fk_{本表}_{关联表}_{字段}`
- 索引命名规则:`idx_{表}_{字段}`
- `INTEGER` 用于 `BIGINT` 场景(Go `uint`/`uint64`)
- `VARCHAR(n)` 映射为 `TEXT(n)`
- SQLite 外键默认关闭,需 `PRAGMA foreign_keys = ON`
---
## 1. `user` — 用户表
```sql
```
CREATE TABLE user (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(64) NOT NULL UNIQUE COMMENT '登录用户名',
password_hash VARCHAR(256) NOT NULL COMMENT 'bcrypt 哈希',
full_name VARCHAR(64) NOT NULL COMMENT '显示姓名',
role ENUM('employee','admin') NOT NULL DEFAULT 'employee',
status ENUM('active','disabled') NOT NULL DEFAULT 'active',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
INDEX idx_user_role (role),
INDEX idx_user_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
full_name TEXT NOT NULL,
role TEXT NOT NULL DEFAULT 'employee',
status TEXT NOT NULL DEFAULT 'active',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_user_role ON user(role);
CREATE INDEX idx_user_status ON user(status);
```
**说明:**
- `role=admin` 为管理员,`role=employee` 为普通员工
- `status=disabled` 时 token 校验拒绝访问
- 仅管理员可创建 / 禁用账号
- `role` 枚举:`employee` / `admin`
- `status` 枚举:`active` / `disabled`
- `disabled` 时 token 校验拒绝访问
- 仅管理员可创建/禁用账号
---
## 2. `product` — 产品表
```sql
CREATE TABLE product (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
code VARCHAR(32) NOT NULL UNIQUE COMMENT '产品编号',
name VARCHAR(128) NOT NULL COMMENT '产品名称',
category ENUM('capital_consulting','qualification_counseling',
'ai_consulting','ai_tools_platform') NOT NULL
COMMENT '四大分类',
tags VARCHAR(256) DEFAULT '' COMMENT '标签,逗号分隔',
description TEXT COMMENT '业务内容说明',
pricing TEXT COMMENT '收费结构',
commission_recommend VARCHAR(128) DEFAULT '' COMMENT '推荐佣金比例',
commission_negotiate VARCHAR(128) DEFAULT '' COMMENT '谈单参与佣金比例',
public_course_bonus VARCHAR(128) DEFAULT '' COMMENT '公开课超额分成',
version_risk TEXT COMMENT '版本风险',
report_rules TEXT COMMENT '报备规则备注',
status ENUM('active','inactive') NOT NULL DEFAULT 'active',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
INDEX idx_product_category (category),
INDEX idx_product_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```
CREATE TABLE product (
id INTEGER PRIMARY KEY AUTOINCREMENT,
code TEXT NOT NULL UNIQUE,
name TEXT NOT NULL,
category TEXT NOT NULL,
tags TEXT DEFAULT '',
description TEXT,
pricing TEXT,
commission_recommend TEXT DEFAULT '',
commission_negotiate TEXT DEFAULT '',
public_course_bonus TEXT DEFAULT '',
version_risk TEXT,
report_rules TEXT,
status TEXT DEFAULT 'active',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_product_category ON product(category);
CREATE INDEX idx_product_status ON product(status);
```
**字段说明:**
- `category` 枚举:`capital_consulting` / `qualification_counseling` / `ai_consulting` / `ai_tools_platform`
- `status` 枚举:`active` / `inactive`
---
## 3. `course` — 课程表
```sql
CREATE TABLE course (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
code VARCHAR(32) NOT NULL UNIQUE COMMENT '课程编号',
name VARCHAR(128) NOT NULL COMMENT '课程名称',
category ENUM('capital_script','qualification_logic',
'ai_public_course','ai_platform_matching') NOT NULL
COMMENT '四大课程分类',
target_customers TEXT COMMENT '适配客户',
forbidden_customers TEXT COMMENT '禁接客户',
scripts TEXT COMMENT '标准话术',
sales_process TEXT COMMENT '谈单流程',
objection_handling TEXT COMMENT '异议处理',
delivery_pitfalls TEXT COMMENT '交付避坑',
report_rules TEXT COMMENT '报备规范',
related_product_id BIGINT UNSIGNED DEFAULT NULL COMMENT '绑定产品ID',
status ENUM('active','inactive') NOT NULL DEFAULT 'active',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
INDEX idx_course_category (category),
INDEX idx_course_status (status),
INDEX idx_course_product (related_product_id),
CONSTRAINT fk_course_product FOREIGN KEY (related_product_id) REFERENCES product(id)
ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```
CREATE TABLE course (
id INTEGER PRIMARY KEY AUTOINCREMENT,
code TEXT NOT NULL UNIQUE,
name TEXT NOT NULL,
category TEXT NOT NULL,
target_customers TEXT,
forbidden_customers TEXT,
scripts TEXT,
sales_process TEXT,
objection_handling TEXT,
delivery_pitfalls TEXT,
report_rules TEXT,
related_product_id INTEGER,
status TEXT DEFAULT 'active',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_course_category ON course(category);
CREATE INDEX idx_course_status ON course(status);
CREATE INDEX idx_course_product ON course(related_product_id);
```
**字段说明:**
- `category` 枚举:`capital_script` / `qualification_logic` / `ai_public_course` / `ai_platform_matching`
- `status` 枚举:`active` / `inactive`
- `related_product_id` 可空(外键应用层维护)
---
## 4. `media_file` — 素材文件表
```sql
CREATE TABLE media_file (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
filename VARCHAR(256) NOT NULL COMMENT '原始文件名',
stored_name VARCHAR(64) NOT NULL COMMENT '存储UUID文件名',
stored_path VARCHAR(512) NOT NULL COMMENT '存储相对路径',
file_ext VARCHAR(16) NOT NULL COMMENT '扩展名(小写无点)',
file_size BIGINT UNSIGNED NOT NULL COMMENT '文件大小(字节)',
status ENUM('pending','approved','rejected') NOT NULL DEFAULT 'pending',
source ENUM('employee','admin') NOT NULL COMMENT '上传来源',
submitter_id BIGINT UNSIGNED NOT NULL COMMENT '提交人ID',
remark VARCHAR(512) DEFAULT NULL COMMENT '提交备注(员工素材建议)',
bind_type ENUM('company','product','course','none') NOT NULL DEFAULT 'none'
COMMENT '绑定类型',
bind_id BIGINT UNSIGNED DEFAULT NULL COMMENT '绑定实体ID',
reject_reason VARCHAR(512) DEFAULT NULL COMMENT '驳回理由',
audit_by BIGINT UNSIGNED DEFAULT NULL COMMENT '审批人ID',
audit_at DATETIME(6) DEFAULT NULL COMMENT '审批时间',
extracted TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否已提取文本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
INDEX idx_media_status (status),
INDEX idx_media_submitter (submitter_id),
INDEX idx_media_bind (bind_type, bind_id),
INDEX idx_media_extracted (extracted),
CONSTRAINT fk_media_submitter FOREIGN KEY (submitter_id) REFERENCES user(id),
CONSTRAINT fk_media_auditor FOREIGN KEY (audit_by) REFERENCES user(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```
CREATE TABLE media_file (
id INTEGER PRIMARY KEY AUTOINCREMENT,
filename TEXT NOT NULL,
file_path TEXT NOT NULL,
file_size INTEGER,
file_type TEXT,
status TEXT DEFAULT 'pending',
source TEXT DEFAULT 'employee',
submitter_id INTEGER,
remark TEXT,
bind_type TEXT DEFAULT 'none',
bind_id INTEGER,
reject_reason TEXT,
audit_by INTEGER,
audit_at DATETIME,
file_category TEXT,
extract_status TEXT DEFAULT 'pending',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_media_status ON media_file(status);
CREATE INDEX idx_media_submitter ON media_file(submitter_id);
CREATE INDEX idx_media_bind ON media_file(bind_type, bind_id);
CREATE INDEX idx_media_extract ON media_file(extract_status);
```
**字段说明:**
- `status`:`pending` / `approved` / `rejected`
- `source`:`employee` / `admin`
- `bind_type`:`company` / `product` / `course` / `none`
- `extract_status`:`pending` / `extracting` / `completed` / `failed`
---
## 5. `knowledge_chunk` — 知识块表
```sql
CREATE TABLE knowledge_chunk (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
media_file_id BIGINT UNSIGNED DEFAULT NULL COMMENT '关联素材ID(与 knowledge_source_id 二选一)',
knowledge_source_id BIGINT UNSIGNED DEFAULT NULL COMMENT '关联知识源ID(与 media_file_id 二选一)',
source_type VARCHAR(32) NOT NULL COMMENT '来源类型(pdf/doc/md)',
source_id VARCHAR(64) DEFAULT NULL COMMENT '来源标识',
chunk_index INT UNSIGNED NOT NULL COMMENT '段落序号',
content TEXT NOT NULL COMMENT '文本内容',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
INDEX idx_kc_media (media_file_id),
INDEX idx_kc_source (knowledge_source_id),
FULLTEXT INDEX ft_kc_content (content) WITH PARSER ngram COMMENT 'MySQL全文索引(ngram 中文分词)用于AI检索',
CONSTRAINT fk_kc_media FOREIGN KEY (media_file_id) REFERENCES media_file(id)
ON DELETE CASCADE,
CONSTRAINT fk_kc_source FOREIGN KEY (knowledge_source_id) REFERENCES knowledge_source(id)
ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
> 约束说明:`media_file_id` 与 `knowledge_source_id` 二者必居其一(应用层校验,Fail Fast)。
```
CREATE TABLE knowledge_chunk (
id INTEGER PRIMARY KEY AUTOINCREMENT,
media_file_id INTEGER,
knowledge_source_id INTEGER,
source_type TEXT NOT NULL,
source_id TEXT,
knowledge_space_key TEXT,
chunk_index INTEGER NOT NULL,
content TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_kc_media ON knowledge_chunk(media_file_id);
CREATE INDEX idx_kc_source ON knowledge_chunk(knowledge_source_id);
CREATE INDEX idx_kc_space ON knowledge_chunk(knowledge_space_key);
```
**说明:**
- `media_file_id` 与 `knowledge_source_id` 二者必居其一(应用层校验)
- `source_type`:`pdf` / `doc` / `md`
- 文本存储不建全文索引,检索由 Go 层 brute-force 余弦完成
---
## 6. `question` — 题目表
```sql
CREATE TABLE question (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
domain ENUM('company','product','sales') NOT NULL
COMMENT '所属知识域',
course_id BIGINT UNSIGNED DEFAULT NULL COMMENT '绑定课程(sales域时可选)',
type ENUM('single','multiple','judge') NOT NULL
COMMENT '题型',
stem TEXT NOT NULL COMMENT '题干',
options JSON NOT NULL COMMENT '选项JSON',
answer JSON NOT NULL COMMENT '正确答案JSON',
explanation TEXT DEFAULT '' COMMENT '答案解析',
status ENUM('active','inactive') NOT NULL DEFAULT 'active',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
INDEX idx_question_domain (domain),
INDEX idx_question_course (course_id),
INDEX idx_question_status (status),
CONSTRAINT fk_question_course FOREIGN KEY (course_id) REFERENCES course(id)
ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```
CREATE TABLE question (
id INTEGER PRIMARY KEY AUTOINCREMENT,
domain TEXT NOT NULL,
course_id INTEGER,
type TEXT NOT NULL,
stem TEXT NOT NULL,
options TEXT NOT NULL,
answer TEXT NOT NULL,
explanation TEXT DEFAULT '',
status TEXT DEFAULT 'active',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_question_domain ON question(domain);
CREATE INDEX idx_question_course ON question(course_id);
CREATE INDEX idx_question_status ON question(status);
```
**字段说明:**
- `type` 枚举:`single` / `multiple` / `judge` / `essay`(V1.5 新增)
- `options` / `answer` 存储 JSON 文本
---
## 7. `exam_paper` — 考试配置表
```sql
CREATE TABLE exam_paper (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(128) NOT NULL COMMENT '考试名称',
type ENUM('self_test','formal') NOT NULL
COMMENT '考试类型',
domain VARCHAR(64) NOT NULL COMMENT '抽题知识域(逗号分隔)',
question_count INT UNSIGNED NOT NULL COMMENT '题量',
total_score INT UNSIGNED NOT NULL COMMENT '总分',
pass_score INT UNSIGNED NOT NULL COMMENT '合格线',
duration_minutes INT UNSIGNED NOT NULL COMMENT '考试时长(分钟)',
randomize TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否随机抽题',
status ENUM('active','inactive') NOT NULL DEFAULT 'active',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
INDEX idx_paper_type (type),
INDEX idx_paper_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```
CREATE TABLE exam_paper (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
type TEXT NOT NULL,
domain TEXT NOT NULL,
question_count INTEGER NOT NULL,
total_score INTEGER NOT NULL,
pass_score INTEGER NOT NULL,
duration_minutes INTEGER NOT NULL,
randomize INTEGER DEFAULT 1,
status TEXT DEFAULT 'active',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_paper_type ON exam_paper(type);
CREATE INDEX idx_paper_status ON exam_paper(status);
```
**字段说明:**
- `type`:`self_test` / `formal`
---
## 8. `exam_record` — 考试记录表
```sql
```
CREATE TABLE exam_record (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT UNSIGNED NOT NULL COMMENT '考生ID',
paper_id BIGINT UNSIGNED NOT NULL COMMENT '考试配置ID',
exam_name VARCHAR(128) NOT NULL COMMENT '考试名称(冗余)',
score INT UNSIGNED NOT NULL COMMENT '得分',
total_score INT UNSIGNED NOT NULL COMMENT '总分(冗余)',
pass_score INT UNSIGNED NOT NULL COMMENT '合格线(冗余)',
passed TINYINT(1) NOT NULL COMMENT '是否通过',
correct_count INT UNSIGNED NOT NULL COMMENT '答对数',
wrong_count INT UNSIGNED NOT NULL COMMENT '答错数',
detail_json JSON NOT NULL COMMENT '答题明细JSON',
submitted_at DATETIME(6) NOT NULL COMMENT '交卷时间',
INDEX idx_record_user (user_id),
INDEX idx_record_paper (paper_id),
INDEX idx_record_passed (passed),
INDEX idx_record_submitted (submitted_at),
CONSTRAINT fk_record_user FOREIGN KEY (user_id) REFERENCES user(id)
ON DELETE CASCADE,
CONSTRAINT fk_record_paper FOREIGN KEY (paper_id) REFERENCES exam_paper(id)
ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
paper_id INTEGER NOT NULL,
exam_name TEXT NOT NULL,
score INTEGER NOT NULL,
total_score INTEGER NOT NULL,
pass_score INTEGER NOT NULL,
passed INTEGER NOT NULL,
correct_count INTEGER NOT NULL,
wrong_count INTEGER NOT NULL,
detail_json TEXT NOT NULL,
submitted_at DATETIME NOT NULL
);
CREATE INDEX idx_record_user ON exam_record(user_id);
CREATE INDEX idx_record_paper ON exam_record(paper_id);
CREATE INDEX idx_record_passed ON exam_record(passed);
CREATE INDEX idx_record_submitted ON exam_record(submitted_at);
```
---
## 9. `system_config` — 系统参数配置表
```sql
```
CREATE TABLE system_config (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
config_key VARCHAR(64) NOT NULL UNIQUE COMMENT '配置键',
config_value TEXT NOT NULL COMMENT '配置值',
description VARCHAR(256) DEFAULT '' COMMENT '配置说明',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
INDEX idx_config_key (config_key)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
id INTEGER PRIMARY KEY AUTOINCREMENT,
config_key TEXT NOT NULL UNIQUE,
config_value TEXT NOT NULL,
description TEXT DEFAULT '',
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_config_key ON system_config(config_key);
```
### 默认配置项
@@ -278,29 +273,32 @@ CREATE TABLE system_config (
## 10. `knowledge_source` — 结构化知识源表
> 承载 `docs/knowledge_source/*.md` 的审批与摄入状态。完整设计见 `04_Backend/BE05_Knowledge_Ingest_Module.md`。
完整设计见 `04_Backend/BE05_Knowledge_Ingest_Module.md`。
```sql
CREATE TABLE knowledge_source (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(256) NOT NULL COMMENT '文档标题',
file_path VARCHAR(512) NOT NULL UNIQUE COMMENT 'md 相对路径(docs/knowledge_source/ 下)',
category VARCHAR(64) NOT NULL COMMENT '分类:general/capital_consulting/qualification_counseling/ai_consulting/ai_tools_platform',
domain ENUM('company','product','sales') NOT NULL DEFAULT 'product',
source_version VARCHAR(32) NOT NULL COMMENT '源版本,如 V1.0',
audit_status ENUM('pending','approved','rejected') NOT NULL DEFAULT 'pending',
audit_by BIGINT UNSIGNED DEFAULT NULL COMMENT '审批人ID',
audit_at DATETIME(6) DEFAULT NULL COMMENT '审批时间',
reject_reason VARCHAR(512) DEFAULT NULL COMMENT '驳回理由',
ingested TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否已摄入',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
INDEX idx_ks_status (audit_status),
INDEX idx_ks_category (category),
CONSTRAINT fk_ks_auditor FOREIGN KEY (audit_by) REFERENCES user(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```
CREATE TABLE knowledge_source (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
file_path TEXT NOT NULL UNIQUE,
category TEXT NOT NULL,
domain TEXT DEFAULT 'product',
source_version TEXT NOT NULL,
audit_status TEXT DEFAULT 'pending',
audit_by INTEGER,
audit_at DATETIME,
reject_reason TEXT,
ingested INTEGER DEFAULT 0,
knowledge_space_key TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_ks_status ON knowledge_source(audit_status);
CREATE INDEX idx_ks_category ON knowledge_source(category);
```
**字段说明:**
- `audit_status`:`pending` / `approved` / `rejected`
- `domain`:`company` / `product` / `sales`
---
@@ -318,9 +316,7 @@ knowledge_source ──< knowledge_chunk (knowledge_source_id)
exam_paper ──< exam_record (paper_id)
```
## 附:V1.4–V1.7 新增表清单
> 下表未在本文件给出完整 DDL,字段与建表细节以 `docs/changelog.md` 对应版本及 Go 后端 GORM 模型为准。
## 附:V1.4–V1.7 新增表
| 版本 | 表名 | 用途 |
|------|------|------|
@@ -329,8 +325,8 @@ exam_paper ──< exam_record (paper_id)
| V1.5 | `position_exam_blueprint` | 岗位考试蓝图(按域+题型+题量抽题)|
| V1.5 | `mistake_record` | 错题本(按 user+question 去重,标记已掌握)|
| V1.6 | `point_event` | 学习积分流水(可审计)|
| V1.6 | `certificate` | 考试合格证书(按 exam_record 幂等去重)|
| V1.6 | `certificate` | 考试合格证书(按 exam_record_id 幂等去重)|
| V1.7 | `department` | 部门字典(部门改名同步 user.department)|
| V1.7 | `notification` | 站内消息通知(事件钩子驱动)|
**列级变更:** `user.learning_points`(V1.6)、`user.position_id`(V1.4)、`user.department`(V1.7)、`exam_paper.position_id`(V1.4)、`question.type` 增加 `essay`(V1.5)。
**列级变更:** `user.learning_points`(V1.6)、`user.position_id`(V1.4)、`user.department`(V1.7)、`exam_paper.position_id`(V1.4)、`question.type` 增加 `essay`(V1.5)。