# eai_agentplatform — 数据库 Schema > **版本:V1.3 | 引擎:SQLite(单文件,GORM AutoMigrate 建表)** > **最后更新:2026-08-16** ## 约定 - 数据库使用 **SQLite 单文件** `data/eai_agentplatform.db`(GORM AutoMigrate 首次启动自动建表) - AI 知识检索为 **Go 原生 brute-force 向量检索**(余弦相似度)+ 关键词兜底(不依赖外部向量库) - 主键 `id` 为 `INTEGER PRIMARY KEY AUTOINCREMENT` - 时间字段 `created_at` / `updated_at` 为 `DATETIME`,默认 `CURRENT_TIMESTAMP` - 索引命名规则:`idx_{表}_{字段}` - `INTEGER` 用于 `BIGINT` 场景(Go `uint`/`uint64`) - `VARCHAR(n)` 映射为 `TEXT(n)` - SQLite 外键默认关闭,需 `PRAGMA foreign_keys = ON` --- ## 1. `user` — 用户表 ``` CREATE TABLE user ( 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` 枚举:`employee` / `admin` - `status` 枚举:`active` / `disabled` - `disabled` 时 token 校验拒绝访问 - 仅管理员可创建/禁用账号 --- ## 2. `product` — 产品表 ``` 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` — 课程表 ``` 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` — 素材文件表 ``` 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` — 知识块表 ``` 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` — 题目表 ``` 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` — 考试配置表 ``` 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` — 考试记录表 ``` CREATE TABLE exam_record ( 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` — 系统参数配置表 ``` CREATE TABLE system_config ( 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); ``` ### 默认配置项 | config_key | 默认值 | 说明 | |-----------|--------|------| | `llm_base_url` | `http://localhost:11434/v1` | LLM 服务地址 | | `llm_api_key` | `sk-xxx` | LLM API Key | | `llm_model` | `qwen2.5:7b` | LLM 模型名 | | `jwt_expire_minutes` | `480` | Token 过期分钟数 | | `file_max_size_doc` | `209715200` | 文档最大字节(200MB) | | `file_max_size_video` | `2147483648` | 视频最大字节(2GB) | | `chunk_threshold` | `104857600` | 分片上传阈值(100MB) | --- ## 10. `knowledge_source` — 结构化知识源表 完整设计见 `04_Backend/BE05_Knowledge_Ingest_Module.md`。 ``` 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` --- ## 附:ER 关系 ``` user ──< media_file (submitter_id / audit_by) user ──< exam_record (user_id) user ──< question (course_id → course) user ──< knowledge_source (audit_by) product ──< course (related_product_id) course ──< question (course_id, optional) media_file ──< knowledge_chunk (media_file_id) knowledge_source ──< knowledge_chunk (knowledge_source_id) exam_paper ──< exam_record (paper_id) ``` ## 附:V1.4–V1.7 新增表 | 版本 | 表名 | 用途 | |------|------|------| | V1.4 | `position` | 岗位字典 | | V1.4 | `position_knowledge` | 岗位 → 知识映射(域/课程/产品 + 级别 L1-L4 + 权重 + 必学)| | V1.5 | `position_exam_blueprint` | 岗位考试蓝图(按域+题型+题量抽题)| | V1.5 | `mistake_record` | 错题本(按 user+question 去重,标记已掌握)| | V1.6 | `point_event` | 学习积分流水(可审计)| | 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)。