Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
61 KiB
后端-04:统一数据库 Schema(结构定义)-v1
- 版本:v7
- 更新日期:2026-05-13
- 目标读者:后端/架构/前端/数据库维护者
- 阅读时间:35–55 分钟
- 边界说明:本文件只定义持久化模型、表结构职责、关系、约束与索引策略;流程与状态跳转细节统一引用
架构-04-状态机与约束清单.md,接口输入输出统一引用后端-05-统一API契约-v1.md。本文描述目标 Schema(结构定义),不代表当前代码或 migration 都已实现。
1. 目标
这份 Schema(结构定义) 只做一件事:把 Muse 的双轨模型落成不会自相矛盾的数据结构。
本版直接固化以下设计决策:
Block.content使用结构化jsonb,不再退回纯文本。Work直接持有导入/解析状态,不另建工作流状态总表。- Shadow(待审层) 只存待审对象;历史进入 Archive(归档层)/Audit。
- 异步作业状态与审核状态分离:作业进
*_jobs,待审对象进suggestions/proposals。 - 保留
work_id冗余字段,但必须用复合唯一键与复合外键保证一致性,禁止只靠应用层“记得写对”。 - 所有业务主键和外键统一使用自定义字符串 ID,不再使用 UUID 或自增整数作为目标态业务 ID。
- 知识 Canonical(规范数据) 使用
jsonb快照,但必须补属性级变更日志,不能把来源链路弄丢。 meta_schemas采用三维分类:domain(content/world/narrative)+scope(work/chapter/entity/relation/event)+target_type。- Narrative State(叙事状态) 的运行态值不能只靠
meta_schemas;work/chapter/entity三个 scope 必须有真实持久化载体。 - PG 是唯一事实源;RAGFlow 和 Graph Query Provider 都是 PG 的投影,通过
projection_outbox异步同步。Neo4j 只是不满足 GraphRAG 能力时的条件交付 provider。 - Proposal 携带 source snapshot(source_kind/ref_id/revision/content_hash),用于 stale draft 检测。
- 管理员(Admin)配置能力进入 Admin BC,不混入普通用户作品工作台。
- Sa-Token 作为认证授权基座,负责登录认证、RBAC、接口鉴权、会话与 Token 生命周期、当前用户上下文和基础审计上下文。
- 全局知识库(Global Knowledge Base)与局域知识库(Local Knowledge Base)分层;全局知识库授权不自动写入作品事实。
- 元数据可见性至少表达
ui_visible、ai_context、user_editable、user_searchable、exportable。 - New-API 继续负责模型供应商、路由、用户分组限流、Token 成本策略和消耗日志;Muse 只同步用户、分组、配额、套餐和绑定状态。
2. 总体原则
2.1 持久化对象分类
系统内持久化对象按事实层级分类,不能把配置、事实、待审对象、任务和投影混成一张万能表。
| 类别 | 说明 | 代表表 |
|---|---|---|
| Canonical(规范数据) | 用户确认后的事实数据 | works / chapters / blocks / knowledge_entities / knowledge_relations / knowledge_events / narrative_states |
| Shadow(待审层) Active(活跃层) | 仍待审核的建议/提案 | suggestions / proposals |
| Job | 异步生成、解析、批处理状态 | generation_jobs / extraction_jobs |
| Configuration(系统配置) | 管理员配置、版本、启停和授权策略 | roles / permissions / user_roles / role_permissions / system_service_identities / meta_schemas / meta_fields / prompt_versions / agent_configs / global_knowledge_bases / global_knowledge_access_policies / newapi_user_bindings / newapi_plan_mappings / evaluation_datasets |
| History / Audit | 已完成审核、审计或评测记录 | suggestion_archive / proposal_archive / audit_logs / knowledge_attribute_changes / evaluation_runs |
| Projection | 投影基础设施(PG → 外部存储的异步同步) | projection_outbox / projection_watermarks / ragflow_id_mappings |
| Infrastructure(基础设施) | 非业务实体的系统支撑表 | id_sequence_segments |
2.2 通用列约定
- 主键和业务外键默认使用
varchar(96),由应用层 ID 生成器生成,不使用数据库自增或 UUID 默认值。长度放宽到 96 是为了容纳表名大写对象码,例如GLOBAL_KNOWLEDGE_ACCESS_POLICIES。 - 时间统一使用
timestamptz。 - 状态字段统一使用
text + CHECK,不使用 PostgreSQL 原生 enum,避免以后迁移把自己卡死。 - 计数字段统一为非负整数,写入端负责维护,读端允许按需回算校验。
- 所有跨表 ownership 约束优先使用复合唯一键 + 复合外键;只有表达不了的“写一次后不可改”规则才考虑触发器。
2.3 自定义字符串 ID 规则
目标态业务 ID 统一格式:
<OBJECT_CODE><YYYYMMDD><SEQ6><RAND6><HHMMSS>
ID 不带额外分隔符,示例:WORKS20260512000001A1B2C3153045。如果表名本身包含下划线,下划线属于对象码本身,不作为 ID 片段分隔符。
组成说明:
| 片段 | 规则 |
|---|---|
OBJECT_CODE |
默认采用所属表名大写,例如 USERS、WORKS、CHAPTERS、BLOCKS、KNOWLEDGE_ENTITIES;确需例外时必须在 S0-ID spec 中登记 |
YYYYMMDD |
生成日期,固定使用 Asia/Shanghai |
SEQ6 |
按 OBJECT_CODE + YYYYMMDD 独立递增的 6 位取号器,左侧补 0 |
RAND6 |
6 位大写 Base36 随机片段;应用层使用 Java SecureRandom 生成,不要再称为 UUID |
HHMMSS |
生成时间,补充可读性和粗粒度排序信息 |
取号器由数据库号段表管理,服务每次按对象码和日期领取 1000 个号段,并立即把数据库起始值推进到下一个未分配号段;服务进程只在内存中消费已领取号段。服务重启后未消费号段直接作废,重新领取下一个未分配号段,避免重复取号。
取号器超过 999999 时必须失败并告警,不能静默扩位破坏 ID 格式。API 契约对外只暴露字符串 ID,不再暴露迁移前的数字 ID 或 UUID。
迁移范围包含 users.id,以及作品、章节、Block、任务、建议、提案、知识、配置、审计、投影等所有业务和配置对象。对象码采用“表名大写 + 文档登记 + 代码常量”双维护:本文件和 S0-ID spec 是对象码的设计证据,代码实现必须用 enum 或常量集中定义;不引入数据库元数据表动态管理对象码。
S0-ID 采用停机清库/重建,不做双写过渡。基于“当前无重要数据,可以全部清理”的已确认前提,迁移方式改为清库/重建/重置式迁移:删除现有 schema,重建 schema,重新执行 migration,重新生成最小 smoke 数据,并一次性改表、改代码、改前端类型后跑全量回归。
该口径默认允许用于本地、隔离测试库和当前远程开发库。执行清理前必须记录环境标识、数据库连接摘要、操作者和清理范围;不要求快照或备份。若进入有价值数据或生产数据环境,必须停止执行该口径,重新评审是否需要数据保留和映射迁移方案。
最小 smoke 数据只覆盖验证主链路所需对象:管理员用户、普通用户、角色、权限、示例作品、章节、Block、基础 Prompt/Agent/MetaSchema/New-API 绑定配置,以及一组可触发建议、提案、知识确认和用量反馈的测试样本。不在 S0-ID 阶段重建完整演示小说样本。
2.4 冗余 work_id 的约束策略
既然决定保留冗余 work_id,那就别装作没成本。
必须满足:
chapters提供唯一键(work_id, id)。blocks提供唯一键(work_id, id),并通过(work_id, chapter_id)复合外键绑定到chapters。knowledge_entities提供唯一键(work_id, id)。suggestions、proposals、knowledge_relations只要同时保存work_id和下游对象 ID,就必须走复合外键校验同属一个work。
2.5 新产品形态表结构处理矩阵
本节只定义目标处理方式,不表示所有对象都已落地为当前 migration。
| 分类 | 对象 | 处理原则 |
|---|---|---|
| 优先复用 | meta_schemas、narrative_states、knowledge_entities、knowledge_relations、generation_jobs、extraction_jobs、audit_logs |
作品规划台、叙事状态、知识确认和任务记录优先复用这些目标模型;不要为每个 UI 面板新增孤立表 |
| 扩展字段 | 元数据可见性字段、知识库访问策略字段、任务来源和审计字段 | 在已有模型能承载时优先扩展字段;必须保留版本、来源、操作者和权限上下文 |
| 倾向新增 | roles、permissions、user_roles、role_permissions、system_service_identities、prompt_versions、agent_configs、newapi_user_bindings、newapi_plan_mappings、global_knowledge_bases、global_knowledge_access_policies、evaluation_datasets、evaluation_runs |
这些属于认证授权、系统级配置、授权或评测能力,适合独立建模;具体聚合职责见 后端-01 |
| 明确不新增 | local_knowledge_bases 独立表 |
局域知识库由 work_id + knowledge_entities / knowledge_relations / knowledge_events / narrative_states 隐式表达,不单独建容器表 |
| 明确不新增 | usage_logs 本地明细表或本地汇总表 |
New-API 是成本账本权威;Muse 只在任务记录、审计和个人中心响应中保留 New-API 引用、同步状态和任务级 usage 摘要 |
作品规划台(Planning Desk)的数据结构优先复用 MetaSchema、narrative_states、knowledge_entities、knowledge_relations、Work、Chapter 和 Block。产品可写“情节节拍 / 场景推进”,但本版不新增小说场景(Scene)独立一级表。
3. 表结构
3.1 Auth / User
users
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | 用户 ID |
| text | NOT NULL, UNIQUE | 登录邮箱,应用层统一 lower-case | |
| display_name | text | NOT NULL | 显示名称 |
| password_hash | text | NOT NULL | Argon2id 哈希 |
| status | text | NOT NULL, default 'active', CHECK IN ('active', 'pending_deletion') |
用户状态 |
| deletion_requested_at | timestamptz | nullable | 进入删除缓冲期的时间 |
| deleted_at | timestamptz | nullable | 物理删除前的最终标记时间 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
补充约束:
status = 'pending_deletion'时,deletion_requested_at必须非空。status = 'active'时,deleted_at必须为空。
roles
Sa-Token 使用的最小角色表。角色表达接口和后台能力,不表达某个作品的正文或知识确认权。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | 角色 ID |
| role_key | text | NOT NULL, UNIQUE | 角色标识,例如 admin、user |
| role_name | text | NOT NULL | 角色名称 |
| description | text | nullable | 说明 |
| builtin | boolean | NOT NULL, default false | 是否内置角色 |
| status | text | NOT NULL, default 'active', CHECK IN ('active', 'disabled') |
状态 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
内置角色至少包含:
admin:管理员控制台(Admin Console)能力。user:普通用户(User Workspace / Personal Center)能力。
permissions
Sa-Token 使用的最小权限点表。权限点用于接口鉴权、菜单展示和审计解释,不替代业务用例内的作品级校验。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | 权限 ID |
| permission_key | text | NOT NULL, UNIQUE | 权限标识,例如 admin:prompts:write、workspace:works:read |
| permission_name | text | NOT NULL | 权限名称 |
| resource_type | text | NOT NULL | 资源类型,如 admin_api、workspace_api、personal_api、system_job |
| action | text | NOT NULL | 动作,如 read、write、execute |
| description | text | nullable | 说明 |
| builtin | boolean | NOT NULL, default false | 是否内置权限 |
| status | text | NOT NULL, default 'active', CHECK IN ('active', 'disabled') |
状态 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
user_roles
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| user_id | varchar(96) | NOT NULL, FK → users.id ON DELETE CASCADE |
用户 |
| role_id | varchar(96) | NOT NULL, FK → roles.id ON DELETE CASCADE |
角色 |
| assigned_by | varchar(96) | nullable, FK → users.id ON DELETE SET NULL |
分配人 |
| assigned_at | timestamptz | NOT NULL, default now() |
分配时间 |
约束:
- PK (
user_id,role_id)。
role_permissions
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| role_id | varchar(96) | NOT NULL, FK → roles.id ON DELETE CASCADE |
角色 |
| permission_id | varchar(96) | NOT NULL, FK → permissions.id ON DELETE CASCADE |
权限 |
| assigned_by | varchar(96) | nullable, FK → users.id ON DELETE SET NULL |
分配人 |
| assigned_at | timestamptz | NOT NULL, default now() |
分配时间 |
约束:
- PK (
role_id,permission_id)。
system_service_identities
系统任务(System Job)服务身份表。服务身份用于投影消费、索引重建、同步重试、评测执行和清理任务,不允许伪装成普通用户做作品事实确认。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | 服务身份 ID |
| service_key | text | NOT NULL, UNIQUE | 服务身份标识,例如 projection-worker |
| service_name | text | NOT NULL | 展示名称 |
| permission_scope | jsonb | NOT NULL, default '{}'::jsonb |
允许执行的系统任务范围 |
| status | text | NOT NULL, default 'active', CHECK IN ('active', 'disabled') |
状态 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
约束:
- 服务身份只能进入明确的后台任务入口。
- 服务身份写入审计时必须标记
actor_type='system_job'或等价语义。 - 服务身份不得调用确认正文、确认知识草稿、接受 AI 候选等普通用户决策接口。
id_sequence_segments
自定义字符串 ID 的数据库号段表。它不是业务实体,只负责保证同一
OBJECT_CODE + YYYYMMDD下不会重复分配取号器区间。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| object_code | text | NOT NULL | 对象码,如 USERS、WORKS、CHAPTERS、BLOCKS |
| yyyymmdd | char(8) | NOT NULL | 生成日期 |
| next_value | int | NOT NULL, CHECK next_value BETWEEN 1 AND 1000000 |
下一个未分配取号器起始值 |
| segment_size | int | NOT NULL, default 1000, CHECK segment_size > 0 |
每次领取号段大小 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
约束:
- PK (
object_code,yyyymmdd)。 - 服务领取号段时必须在同一事务内锁定当前行,并把
next_value推进到next_value + 1000。 - 已领取但未消费的内存号段在服务重启后直接作废,不允许回收复用。
3.2 Content BC(内容上下文)
works
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | 作品 ID |
| user_id | varchar(96) | NOT NULL, FK → users.id ON DELETE RESTRICT |
所属用户 |
| title | text | NOT NULL | 标题 |
| genre | text | NOT NULL | 题材 |
| summary | text | nullable | 简介 |
| work_schema_id | varchar(96) | nullable, FK → meta_schemas.id ON DELETE SET NULL |
绑定的作品级 Schema(结构定义),要求 scope='work' |
| status | text | NOT NULL, default 'writing', CHECK IN ('writing', 'completed', 'archived') |
作品状态 |
| word_count | int | NOT NULL, default 0, CHECK word_count >= 0 |
总字数 |
| chapter_count | int | NOT NULL, default 0, CHECK chapter_count >= 0 |
章节数 |
| imported_at | timestamptz | nullable | 导入完成时间;只能从 null 写一次 |
| import_error | text | nullable | 导入失败原因 |
| parse_status | text | NOT NULL, default 'not_parsed', CHECK IN ('not_parsed', 'parsing', 'parsed', 'parse_failed') |
解析状态 |
| parse_progress | int | nullable, CHECK parse_progress BETWEEN 0 AND 100 |
解析进度百分比 |
| parse_error | text | nullable | 解析失败原因 |
| parsed_at | timestamptz | nullable | 解析成功完成时间 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
补充约束:
parsed_at只能在parse_status = 'parsed'时非空。parse_status = 'not_parsed'时,parsed_at必须为空。imported_at是 write-once 字段,应用层和触发器都要拒绝二次写入。
chapters
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | 章节 ID |
| work_id | varchar(96) | NOT NULL, FK → works.id ON DELETE CASCADE |
所属作品 |
| title | text | NOT NULL | 章节标题 |
| order_index | int | NOT NULL | 作品内顺序 |
| summary | text | nullable | 章节摘要 |
| block_count | int | NOT NULL, default 0, CHECK block_count >= 0 |
Block(文本块) 数 |
| word_count | int | NOT NULL, default 0, CHECK word_count >= 0 |
章节字数 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
约束:
- UNIQUE (
work_id,order_index) - UNIQUE (
work_id,id)
blocks
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | Block(文本块) ID |
| work_id | varchar(96) | NOT NULL | 冗余所有权,用于复合约束与热路径过滤 |
| chapter_id | varchar(96) | NOT NULL | 所属章节 |
| order_index | int | NOT NULL | 章节内顺序 |
| content | jsonb | NOT NULL | Tiptap(富文本编辑器)/结构化文档内容 |
| revision | int | NOT NULL, default 1, CHECK revision > 0 |
乐观锁版本 |
| word_count | int | NOT NULL, default 0, CHECK word_count >= 0 |
当前 Block(文本块) 字数 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
约束:
- FK (
work_id,chapter_id) →chapters(work_id, id)ON DELETE CASCADE - UNIQUE (
chapter_id,order_index) - UNIQUE (
work_id,id)
说明:
content是唯一 Canonical(规范数据) 正文载体;不再额外存status='canonical'这种废话字段。revision是写入锚点,任何正文写操作都必须基于它。
3.3 AI BC(人工智能上下文):Job
generation_jobs
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | 生成任务 ID |
| work_id | varchar(96) | NOT NULL, FK → works.id ON DELETE CASCADE |
所属作品 |
| requested_by | varchar(96) | NOT NULL, FK → users.id ON DELETE RESTRICT |
触发用户 |
| target_block_id | varchar(96) | nullable | 目标 Block(文本块) |
| suggestion_type | text | NOT NULL, CHECK IN ('continuation', 'rewrite', 'expand', 'planning', 'check') |
建议类型;覆盖写作台与作品规划台 AI 辅助 |
| context_block_ids | jsonb | NOT NULL, default '[]'::jsonb |
上下文 Block(文本块) ID 列表 |
| request_source | text | NOT NULL, default 'writing_desk', CHECK IN ('writing_desk', 'planning_desk', 'knowledge_check', 'import_parse', 'admin_evaluation') |
任务来源,用于区分写作、规划、检查、解析或评测触发 |
| config_snapshot | jsonb | NOT NULL, default '{}'::jsonb |
PromptVersion、AgentConfig、上下文策略、New-API 绑定和全局知识授权快照摘要 |
| audit_context | jsonb | NOT NULL, default '{}'::jsonb |
请求 ID、入口、用户意图、来源解释等审计上下文;禁止写正文全文 |
| status | text | NOT NULL, default 'queued', CHECK IN ('queued', 'running', 'succeeded', 'failed', 'canceled') |
作业状态 |
| pipeline_step | text | nullable, CHECK IN ('generating', 'extracting', 'validating', 'risk_routing', 'regenerating') |
Generation Pipeline 内部步骤追踪;只在 status=running 时有意义;外部 API(GenerationJobSummary)不暴露此字段(v4 修正:新增字段,支持 Pipeline 内部多步追踪) |
| error_code | text | nullable | 失败代码 |
| error_message | text | nullable | 失败信息 |
| started_at | timestamptz | nullable | 开始时间 |
| finished_at | timestamptz | nullable | 完成时间 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
约束:
- FK (
work_id,target_block_id) →blocks(work_id, id)ON DELETE SET NULL
extraction_jobs
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | 提取任务 ID |
| work_id | varchar(96) | NOT NULL, FK → works.id ON DELETE CASCADE |
所属作品 |
| requested_by | varchar(96) | nullable, FK → users.id ON DELETE SET NULL |
发起用户;导入批处理可为空 |
| trigger_type | text | NOT NULL, CHECK IN ('accept_suggestion', 'import_parse', 'manual_extract', 'block_save', 'planning_confirm') |
触发来源 |
| scope_type | text | NOT NULL, CHECK IN ('block', 'work') |
提取范围 |
| source_block_id | varchar(96) | nullable | 来源 Block(文本块) |
| source_suggestion_archive_id | varchar(96) | nullable | 来源建议归档 ID |
| request_source | text | NOT NULL, default 'writing_desk', CHECK IN ('writing_desk', 'planning_desk', 'knowledge_check', 'import_parse', 'admin_evaluation') |
任务来源 |
| config_snapshot | jsonb | NOT NULL, default '{}'::jsonb |
提取、校验、风险路由使用的配置快照摘要 |
| audit_context | jsonb | NOT NULL, default '{}'::jsonb |
来源、请求和审计上下文;禁止写正文全文 |
| status | text | NOT NULL, default 'queued', CHECK IN ('queued', 'running', 'succeeded', 'failed', 'canceled') |
作业状态 |
| error_code | text | nullable | 失败代码 |
| error_message | text | nullable | 失败信息 |
| started_at | timestamptz | nullable | 开始时间 |
| finished_at | timestamptz | nullable | 完成时间 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
约束:
- FK (
work_id,source_block_id) →blocks(work_id, id)ON DELETE SET NULL - FK (
source_suggestion_archive_id) →suggestion_archive(id)ON DELETE SET NULL
3.4 AI BC(人工智能上下文):Shadow(待审层) Active(活跃层)
suggestions
Active(活跃层) 表只存待审对象。行存在,就意味着
pending_review;接受、拒绝、过期后必须迁出到suggestion_archive。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | Suggestion(建议) ID |
| work_id | varchar(96) | NOT NULL, FK → works.id ON DELETE CASCADE |
所属作品 |
| generation_job_id | varchar(96) | NOT NULL, UNIQUE, FK → generation_jobs.id ON DELETE CASCADE |
来源生成任务 |
| target_block_id | varchar(96) | nullable | 目标 Block(文本块) |
| suggestion_type | text | NOT NULL, CHECK IN ('continuation', 'rewrite', 'expand') |
建议类型 |
| anchor_type | text | NOT NULL, CHECK IN ('replace_block', 'insert_after_block', 'replace_range') |
锚点类型 |
| anchor_payload | jsonb | NOT NULL | 锚点细节:位置、范围、上下文摘要 |
| base_block_revision | int | NOT NULL, CHECK base_block_revision > 0 |
生成时绑定的 Block(文本块) revision |
| content | jsonb | NOT NULL | 建议内容,结构与 blocks.content 同型 |
| source_context | jsonb | nullable | 生成上下文摘要 |
| conflict_warning | jsonb | nullable | 预检测冲突说明 |
| expires_at | timestamptz | NOT NULL | 过期时间 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
约束:
- FK (
work_id,target_block_id) →blocks(work_id, id)ON DELETE SET NULL expires_at > created_at
proposals
Active(活跃层) 表只存待审提案。终态进入
proposal_archive。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | Proposal(提案) ID |
| work_id | varchar(96) | NOT NULL, FK → works.id ON DELETE CASCADE |
所属作品 |
| extraction_job_id | varchar(96) | NOT NULL, FK → extraction_jobs.id ON DELETE CASCADE |
来源提取任务 |
| parse_job_id | varchar(96) | nullable, FK → extraction_jobs.id ON DELETE CASCADE |
全书解析批次 ID;仅 trigger_type='import_parse' 时使用,通常等于该行的 extraction_job_id |
| chapter_id | varchar(96) | nullable | 关联章节;全书解析场景下必填,表示当前 Proposal 属于哪个章节批次 |
| suggestion_id | varchar(96) | nullable, FK → suggestions.id ON DELETE SET NULL |
关联的 Suggestion(建议);生成链路中 Proposal 通过此字段关联到 Suggestion,实现 Knowledge Draft 数据合同 |
| entity_id | varchar(96) | nullable | 关联实体;创建新实体时为空 |
| proposal_type | text | NOT NULL, CHECK IN ('create_entity', 'update_attribute', 'add_relation') |
提案类型 |
| stage | text | NOT NULL, default 'raw', CHECK IN ('raw', 'validated') |
内部校验阶段 |
| risk_level | text | nullable, CHECK IN ('low', 'medium', 'high', 'critical') |
风险级别(v7 修正:新增 critical) |
| dedupe_group | text | nullable | 去重分组 ID |
| conflict_summary | jsonb | nullable | 冲突摘要 |
| proposed_data | jsonb | NOT NULL | 提议写入的数据 |
| current_data | jsonb | nullable | 当前 Canonical(规范数据) 快照 |
| source_block_id | varchar(96) | nullable | 来源 Block(文本块) |
| source_kind | text | nullable | 来源类型:block / suggestion / parse_job(v7 新增,Source Snapshot 合同) |
| source_ref_id | varchar(96) | nullable | 来源引用 ID(v7 新增) |
| source_block_revision | int | nullable | 来源 Block revision(v7 新增) |
| source_content_hash | text | nullable | 来源内容 hash,用于 stale draft 检测(v7 新增) |
| expires_at | timestamptz | NOT NULL | 过期时间 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
约束:
- FK (
work_id,entity_id) →knowledge_entities(work_id, id)ON DELETE SET NULL - FK (
work_id,chapter_id) →chapters(work_id, id)ON DELETE SET NULL - FK (
work_id,source_block_id) →blocks(work_id, id)ON DELETE SET NULL expires_at > created_atparse_job_id与chapter_id只在全书解析场景使用:parse_job_id IS NOT NULL时,chapter_id必须非空source_kind='parse_job'时,parse_job_id、chapter_id、source_content_hash必须非空- 缺少
source_kind、source_ref_id、source_block_revision或source_content_hash的历史 Proposal 在新链路下全部视为 stale draft,必须重新提取;不得 best-effort 补 snapshot 后继续确认 - 同一章节批量确认边界由
parse_job_id + chapter_id决定;Schema 允许同一边界下存在多条 Proposal,但确认提交必须由状态机按章节事务循环保证 all-or-nothing,不能实现成跨章节大事务
3.5 AI BC(人工智能上下文):Archive(归档层)
suggestion_archive
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK | 沿用原 Suggestion(建议) ID |
| work_id | varchar(96) | NOT NULL | 所属作品 |
| generation_job_id | varchar(96) | NOT NULL | 来源任务 |
| target_block_id | varchar(96) | nullable | 原目标 Block(文本块) |
| suggestion_type | text | NOT NULL | 建议类型 |
| anchor_type | text | NOT NULL | 锚点类型 |
| anchor_payload | jsonb | NOT NULL | 锚点快照 |
| base_block_revision | int | NOT NULL | 生成时 revision |
| original_content | jsonb | NOT NULL | 原建议内容 |
| final_content | jsonb | nullable | 用户修改 Block 后合并时写入正文的最终内容快照(仅用于归档/审计) |
| disposition | text | NOT NULL, CHECK IN ('accepted', 'rejected', 'expired') |
终态 |
| disposition_reason | text | nullable | 拒绝说明/过期原因 |
| archived_by | varchar(96) | nullable, FK → users.id ON DELETE SET NULL |
审核人;系统过期时为空 |
| archived_at | timestamptz | NOT NULL | 归档时间 |
| merged_block_id | varchar(96) | nullable | 接受后写入的 Block(文本块) |
| merged_block_revision | int | nullable | 接受后 Block(文本块) 的 revision |
| source_context | jsonb | nullable | 生成上下文 |
| conflict_warning | jsonb | nullable | 冲突警告 |
| created_at | timestamptz | NOT NULL | 原始创建时间 |
proposal_archive
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK | 沿用原 Proposal(提案) ID |
| work_id | varchar(96) | NOT NULL | 所属作品 |
| extraction_job_id | varchar(96) | NOT NULL | 来源任务 |
| parse_job_id | varchar(96) | nullable | 全书解析批次 ID 快照 |
| chapter_id | varchar(96) | nullable | 章节批次快照 |
| entity_id | varchar(96) | nullable | 原实体 |
| proposal_type | text | NOT NULL | 提案类型 |
| stage | text | NOT NULL | 归档前阶段 |
| risk_level | text | nullable | 风险级别 |
| dedupe_group | text | nullable | 去重分组 |
| conflict_summary | jsonb | nullable | 冲突摘要 |
| proposed_data | jsonb | NOT NULL | 提议数据 |
| current_data | jsonb | nullable | 原快照 |
| source_block_id | varchar(96) | nullable | 来源 Block(文本块) |
| source_kind | text | nullable | 来源类型快照 |
| source_ref_id | varchar(96) | nullable | 来源引用 ID 快照 |
| source_block_revision | int | nullable | 来源 Block revision 快照 |
| source_content_hash | text | nullable | 来源内容 hash 快照;用于 stale 检测留痕 |
| disposition | text | NOT NULL, CHECK IN ('accepted', 'rejected', 'expired') |
终态 |
| disposition_reason | text | nullable | 拒绝/过期原因 |
| archived_by | varchar(96) | nullable, FK → users.id ON DELETE SET NULL |
审核人;系统过期时为空 |
| archived_at | timestamptz | NOT NULL | 归档时间 |
| applied_entity_id | varchar(96) | nullable | 接受后最终作用到的实体 |
| applied_snapshot | jsonb | nullable | 接受后的实体快照 |
| created_at | timestamptz | NOT NULL | 原始创建时间 |
3.6 Knowledge BC(知识上下文)
knowledge_entities
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | 实体 ID |
| work_id | varchar(96) | NOT NULL, FK → works.id ON DELETE CASCADE |
所属作品 |
| name | text | NOT NULL | 实体名 |
| entity_type | text | NOT NULL | 实体类型,如 character / location / item,由 MetaSchema(domain=world, scope=entity) 定义 |
| entity_schema_id | varchar(96) | nullable, FK → meta_schemas.id ON DELETE SET NULL |
绑定的实体 Schema(结构定义),要求 scope='entity' |
| attributes | jsonb | NOT NULL, default '{}'::jsonb |
当前 Canonical(规范数据) 属性快照 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
约束:
- UNIQUE (
work_id,name,entity_type) - UNIQUE (
work_id,id)
knowledge_relations
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | 关系 ID |
| work_id | varchar(96) | NOT NULL, FK → works.id ON DELETE CASCADE |
所属作品 |
| source_entity_id | varchar(96) | NOT NULL | 起点实体 |
| target_entity_id | varchar(96) | NOT NULL | 终点实体 |
| relation_type | text | NOT NULL | 关系类型,由 MetaSchema(domain=world, scope=relation) 定义 |
| description | text | nullable | 关系描述 |
| properties | jsonb | nullable | 关系属性(JSONB),字段结构由 MetaSchema 约束 |
| since_chapter | int | nullable | 关系生效起始章节序号 |
| until_chapter | int | nullable | 关系失效章节序号,NULL 表示仍然有效 |
| source_block_id | varchar(96) | nullable | 来源 Block(文本块) |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
约束:
- FK (
work_id,source_entity_id) →knowledge_entities(work_id, id)ON DELETE CASCADE - FK (
work_id,target_entity_id) →knowledge_entities(work_id, id)ON DELETE CASCADE - FK (
work_id,source_block_id) →blocks(work_id, id)ON DELETE SET NULL - CHECK (
source_entity_id <> target_entity_id) - UNIQUE (
work_id,source_entity_id,target_entity_id,relation_type)
knowledge_events
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | 事件 ID |
| work_id | varchar(96) | NOT NULL, FK → works.id ON DELETE CASCADE |
所属作品 |
| event_type | text | NOT NULL | 事件类型,如 突破、相遇、冲突、转折,由 MetaSchema(domain=world, scope=event) 定义 |
| description | text | NOT NULL | 事件描述 |
| chapter_order | int | NOT NULL | 事件发生的章节序号 |
| source_block_id | varchar(96) | nullable | 来源 Block |
| properties | jsonb | NOT NULL, default '{}'::jsonb |
事件属性(JSONB),包含 involves(参与实体列表)和 causes(因果效果列表),字段结构由 MetaSchema 约束 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
| deleted | boolean | NOT NULL, default false |
软删除标记 |
knowledge_attribute_changes
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | 变更记录 ID |
| work_id | varchar(96) | NOT NULL, FK → works.id ON DELETE CASCADE |
所属作品 |
| entity_id | varchar(96) | NOT NULL | 目标实体 |
| attribute_key | text | NOT NULL | 属性键 |
| change_type | text | NOT NULL, CHECK IN ('set', 'unset', 'merge') |
变更类型 |
| old_value | jsonb | nullable | 旧值 |
| new_value | jsonb | nullable | 新值 |
| source_type | text | NOT NULL, CHECK IN ('proposal_accept', 'manual_edit', 'import') |
来源类型 |
| source_proposal_archive_id | varchar(96) | nullable | 来源归档提案 |
| source_block_id | varchar(96) | nullable | 来源 Block(文本块) |
| changed_by | varchar(96) | nullable, FK → users.id ON DELETE SET NULL |
操作者 |
| created_at | timestamptz | NOT NULL, default now() |
变更时间 |
约束:
- FK (
work_id,entity_id) →knowledge_entities(work_id, id)ON DELETE CASCADE - FK (
work_id,source_block_id) →blocks(work_id, id)ON DELETE SET NULL - FK (
source_proposal_archive_id) →proposal_archive(id)ON DELETE SET NULL
narrative_states
Narrative State(叙事状态) 的运行态值载体。
meta_schemas(domain=narrative)只定义字段形状,真正的运行态值必须落在这里,而不是挂在 Schema 定义本身。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | 叙事状态记录 ID |
| work_id | varchar(96) | NOT NULL, FK → works.id ON DELETE CASCADE |
所属作品 |
| scope | text | NOT NULL, CHECK IN ('work', 'chapter', 'entity') |
运行态作用域;只允许三个可写 scope |
| chapter_id | varchar(96) | nullable | scope='chapter' 时必填 |
| entity_id | varchar(96) | nullable | scope='entity' 时必填 |
| schema_id | varchar(96) | nullable, FK → meta_schemas.id ON DELETE SET NULL |
对应的 narrative Schema(结构定义) |
| state_payload | jsonb | NOT NULL, default '{}'::jsonb |
当前叙事状态值,如弧线进度、章节意图、角色目标/动机 |
| source_type | text | NOT NULL, CHECK IN ('manual_edit', 'proposal_accept', 'batch_confirm') |
最近一次写入来源 |
| source_proposal_archive_id | varchar(96) | nullable, FK → proposal_archive.id ON DELETE SET NULL |
由提案确认写入时记录来源 |
| invalidated_at | timestamptz | nullable | 失效时间;内容改写导致需要重提取时写入 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
约束:
-
FK (
work_id,chapter_id) →chapters(work_id, id)ON DELETE CASCADE -
FK (
work_id,entity_id) →knowledge_entities(work_id, id)ON DELETE CASCADE -
scope='work'时,chapter_id与entity_id必须为空 -
scope='chapter'时,chapter_id必须非空,entity_id必须为空 -
scope='entity'时,entity_id必须非空,chapter_id必须为空 唯一性: -
work scope:UNIQUE (
work_id,scope) WHEREscope='work' -
chapter scope:UNIQUE (
work_id,scope,chapter_id) WHEREscope='chapter' -
entity scope:UNIQUE (
work_id,scope,entity_id) WHEREscope='entity'
3.7 Admin BC(管理上下文)
meta_schemas
meta_schemas只定义字段、校验规则和继承关系。对于domain='narrative',它不是运行态存储;运行态值统一进入narrative_states。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | Schema(结构定义) ID |
| schema_key | text | NOT NULL, UNIQUE | 稳定标识,如 xuanhuan_work / character_base |
| name | text | NOT NULL | 展示名称 |
| description | text | nullable | 描述 |
| scope | text | NOT NULL, CHECK IN ('work', 'chapter', 'entity', 'relation', 'event') |
Schema(结构定义) 作用域 |
| target_type | text | NOT NULL | work 作用域时表示作品类型;entity 作用域时表示实体类型;relation/event 作用域时表示关系/事件类型 |
| domain | text | NOT NULL, DEFAULT 'world', CHECK IN ('content', 'world', 'narrative') |
领域分类:content(创作容器) / world(世界模型) / narrative(叙事模型)(v7 新增) |
| parent_schema_id | varchar(96) | nullable, FK → meta_schemas.id ON DELETE SET NULL |
父 Schema(结构定义) |
| is_builtin | bool | NOT NULL, default false |
是否内置 |
| version | int | NOT NULL, default 1, CHECK version > 0 |
配置版本;变更时创建新版本或保留可追溯变更记录 |
| status | text | NOT NULL, default 'active', CHECK IN ('draft', 'active', 'disabled', 'archived') |
配置状态 |
| ui_visible | bool | NOT NULL, default true |
该 Schema(结构定义)对应对象是否允许在普通用户 UI 展示 |
| ai_context | bool | NOT NULL, default false |
该 Schema 对象是否默认允许进入 AI 上下文 |
| user_editable | bool | NOT NULL, default false |
普通用户是否默认可编辑该 Schema 对象 |
| user_searchable | bool | NOT NULL, default true |
普通用户是否默认可检索该 Schema 对象 |
| exportable | bool | NOT NULL, default true |
是否默认允许随作品导出 |
| created_by | varchar(96) | nullable, FK → users.id ON DELETE SET NULL |
创建者 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
约束:
- UNIQUE (
scope,target_type,name) - UNIQUE (
domain,scope,target_type,name)(v7 修正:三维分类唯一约束)
meta_fields
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | 字段 ID |
| schema_id | varchar(96) | NOT NULL, FK → meta_schemas.id ON DELETE CASCADE |
所属 Schema(结构定义) |
| field_key | text | NOT NULL | 字段键 |
| field_label | text | NOT NULL | 字段显示名 |
| field_type | text | NOT NULL, CHECK IN ('text', 'number', 'enum', 'boolean', 'array', 'reference') |
字段类型 |
| is_required | bool | NOT NULL, default false |
是否必填 |
| default_value | jsonb | nullable | 默认值 |
| enum_options | jsonb | nullable | 枚举选项 |
| reference_target_type | text | nullable | 引用类型:仅 reference 时有效 |
| validation_rules | jsonb | NOT NULL, default '{}'::jsonb |
范围、正则、数组长度等规则 |
| order_index | int | NOT NULL | 字段顺序 |
| ui_visible | bool | NOT NULL, default true |
字段是否在普通用户 UI 展示 |
| ai_context | bool | NOT NULL, default false |
字段是否允许进入 AI 上下文 |
| user_editable | bool | NOT NULL, default false |
普通用户是否可编辑该字段 |
| user_searchable | bool | NOT NULL, default true |
普通用户是否可检索该字段 |
| exportable | bool | NOT NULL, default true |
字段是否允许随作品导出 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
约束:
- UNIQUE (
schema_id,field_key) - UNIQUE (
schema_id,order_index) - 字段级可见性优先于 Schema 默认值;
ui_visible=false不代表ai_context=false。 - 可见性变更必须写入审计,并触发用户可见投影重建或失效标记。
prompt_versions
指令模板(Prompt)版本表。Prompt 是系统级配置,普通用户不能通过作品工作台读取或修改原始 Prompt。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | Prompt 版本 ID |
| prompt_key | text | NOT NULL | 稳定标识,如 generation.default / planning.chapter |
| prompt_type | text | NOT NULL, CHECK IN ('system', 'task', 'genre', 'style', 'planning', 'validation') |
Prompt 类型 |
| version | int | NOT NULL, CHECK version > 0 |
版本号,同 prompt_key 下递增 |
| status | text | NOT NULL, default 'draft', CHECK IN ('draft', 'active', 'disabled', 'archived') |
生命周期状态 |
| content | text | NOT NULL | Prompt 正文 |
| variables_schema | jsonb | NOT NULL, default '{}'::jsonb |
变量结构与必填规则 |
| rollout_policy | jsonb | NOT NULL, default '{}'::jsonb |
灰度、回滚、适用范围 |
| change_summary | text | nullable | 变更摘要 |
| activated_by | varchar(96) | nullable, FK → users.id ON DELETE SET NULL |
激活人 |
| activated_at | timestamptz | nullable | 激活时间 |
| created_by | varchar(96) | nullable, FK → users.id ON DELETE SET NULL |
创建人 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
约束:
- UNIQUE (
prompt_key,version) - 同一
prompt_key同一时间最多一个 active 版本。 - 已激活版本不得原地静默修改;需要变更时创建新版本或显式回滚。
agent_configs
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | Agent 配置 ID |
| agent_key | text | NOT NULL | 稳定标识,如 generation.default / extraction.block |
| agent_type | text | NOT NULL, CHECK IN ('generation', 'extraction', 'validation', 'planning', 'retrieval') |
Agent 类型 |
| version | int | NOT NULL, CHECK version > 0 |
版本号 |
| status | text | NOT NULL, default 'draft', CHECK IN ('draft', 'active', 'disabled', 'archived') |
生命周期状态 |
| config_payload | jsonb | NOT NULL, default '{}'::jsonb |
Muse 侧编排配置,不保存模型供应商路由权威数据 |
| timeout_ms | int | NOT NULL, default 60000, CHECK timeout_ms > 0 |
超时配置 |
| retry_policy | jsonb | NOT NULL, default '{}'::jsonb |
重试策略 |
| fallback_policy | jsonb | NOT NULL, default '{}'::jsonb |
降级策略 |
| activated_by | varchar(96) | nullable, FK → users.id ON DELETE SET NULL |
激活人 |
| activated_at | timestamptz | nullable | 激活时间 |
| created_by | varchar(96) | nullable, FK → users.id ON DELETE SET NULL |
创建人 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
约束:
- UNIQUE (
agent_key,version) - 同一
agent_key同一时间最多一个 active 版本。 agent_configs不承载模型供应商、模型路由、用户分组限流、Token 成本策略和 New-API 消耗日志。
global_knowledge_bases
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | 全局知识库 ID |
| kb_key | text | NOT NULL | 稳定标识 |
| name | text | NOT NULL | 名称 |
| description | text | nullable | 描述 |
| version | int | NOT NULL, default 1, CHECK version > 0 |
内容版本 |
| status | text | NOT NULL, default 'preparing', CHECK IN ('preparing', 'active', 'disabled', 'archived') |
生命周期状态 |
| source_type | text | NOT NULL, CHECK IN ('upload', 'ragflow_dataset', 'manual', 'external') |
来源类型 |
| source_ref | text | nullable | 外部来源引用,如 RAGFlow dataset ID |
| index_status | text | NOT NULL, default 'not_indexed', CHECK IN ('not_indexed', 'indexing', 'indexed', 'index_failed') |
索引状态 |
| metadata | jsonb | NOT NULL, default '{}'::jsonb |
体裁、平台、标签等元信息 |
| created_by | varchar(96) | nullable, FK → users.id ON DELETE SET NULL |
创建人 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
约束:
- UNIQUE (
kb_key,version) - 停用后不得进入新的检索或生成上下文。
- 全局知识库不会自动写入任何作品的局域知识库(Local Knowledge Base)。
- 全局知识库是独立逻辑资料集;即使多个全局知识库共用同一个物理数据库、向量索引或 RAGFlow dataset,也必须保留可过滤的
global_kb_id或等价资料集标识。
global_knowledge_access_policies
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | 访问策略 ID |
| global_kb_id | varchar(96) | NOT NULL, FK → global_knowledge_bases.id ON DELETE CASCADE |
全局知识库 |
| version | int | NOT NULL, default 1, CHECK version > 0 |
策略版本 |
| status | text | NOT NULL, default 'draft', CHECK IN ('draft', 'active', 'disabled', 'archived') |
策略状态 |
| subject_type | text | NOT NULL, CHECK IN ('user', 'user_group', 'plan', 'all_users') |
授权对象类型 |
| subject_id | text | nullable | 授权对象 ID;all_users 可为空 |
| default_bound | bool | NOT NULL, default false |
是否默认绑定 |
| ui_visible | bool | NOT NULL, default false |
普通用户是否可见 |
| user_searchable | bool | NOT NULL, default false |
普通用户是否可主动检索 |
| ai_context | bool | NOT NULL, default false |
是否允许进入 AI 生成上下文 |
| user_bindable | bool | NOT NULL, default false |
用户是否可主动绑定 |
| user_unbindable | bool | NOT NULL, default false |
用户是否可主动解绑 |
| readonly | bool | NOT NULL, default true |
普通用户是否只读使用 |
| active_from | timestamptz | nullable | 生效时间 |
| active_until | timestamptz | nullable | 失效时间 |
| created_by | varchar(96) | nullable, FK → users.id ON DELETE SET NULL |
创建人 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
约束:
- 没有 active 策略时,全局知识库不得展示、检索或进入生成上下文。
- 策略变更不得改写任何作品的局域知识库事实。
- 全局知识库版本和访问策略版本可独立回滚。
- 授权撤销后的权限边界是请求时计算允许使用的
global_kb_id列表;被撤销资料集不得进入检索请求和上下文组装。 - 如果授权对象共用同一个物理索引或数据库,检索条件必须包含
global_kb_id IN allowedIds或等价过滤条件;异步索引失效、重建或清理只作为性能和数据清理手段,不能作为权限边界。
newapi_user_bindings
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | 绑定 ID |
| user_id | varchar(96) | NOT NULL, UNIQUE, FK → users.id ON DELETE CASCADE |
Muse 用户 |
| newapi_user_id | text | NOT NULL | New-API 侧用户 ID |
| newapi_group_key | text | nullable | New-API 分组 |
| plan_key | text | nullable | Muse 套餐标识 |
| quota_snapshot | jsonb | NOT NULL, default '{}'::jsonb |
最近一次同步得到的配额/套餐摘要 |
| status | text | NOT NULL, default 'syncing', CHECK IN ('syncing', 'active', 'error', 'disabled') |
同步状态 |
| last_synced_at | timestamptz | nullable | 最后同步时间 |
| last_sync_error | text | nullable | 最后同步失败原因 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
约束:
- UNIQUE (
newapi_user_id) - 同步必须幂等;失败保留原因和重试入口。
- 不保存 New-API 模型供应商、模型路由或消耗日志权威数据。
newapi_plan_mappings
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | 套餐映射 ID |
| muse_plan_key | text | NOT NULL | Muse 套餐标识 |
| newapi_group_key | text | NOT NULL | New-API 分组标识 |
| version | int | NOT NULL, default 1, CHECK version > 0 |
映射版本 |
| status | text | NOT NULL, default 'draft', CHECK IN ('draft', 'active', 'disabled', 'archived') |
状态 |
| quota_policy | jsonb | NOT NULL, default '{}'::jsonb |
配额策略摘要 |
| package_payload | jsonb | NOT NULL, default '{}'::jsonb |
套餐同步所需参数 |
| created_by | varchar(96) | nullable, FK → users.id ON DELETE SET NULL |
创建人 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
约束:
- UNIQUE (
muse_plan_key,version) - active 映射变更只影响后续 New-API 同步任务,不改写已完成任务记录。
evaluation_datasets
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | 评测集 ID |
| dataset_key | text | NOT NULL | 稳定标识 |
| version | int | NOT NULL, CHECK version > 0 |
版本号 |
| status | text | NOT NULL, default 'draft', CHECK IN ('draft', 'active', 'locked', 'archived') |
生命周期状态 |
| scenario | text | NOT NULL | 评测场景,如续写、改写、描写、作品规划、实体一致性、角色一致性、角色弧光、世界事实、大纲一致性、细纲一致性、叙事手法、伏笔与回收、张力曲线、节奏与信息释放、主题表达、文风匹配、全书解析、长程连载 |
| scoring_rubric | jsonb | NOT NULL | 固定评分标准 |
| dataset_payload | jsonb | NOT NULL | 固定输入、参考输出或样本集 |
| locked_at | timestamptz | nullable | 首次正式使用后的锁定时间 |
| created_by | varchar(96) | nullable, FK → users.id ON DELETE SET NULL |
创建人 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
约束:
- UNIQUE (
dataset_key,version) locked后不得原地修改样本和评分标准。
evaluation_runs
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | 评测运行 ID |
| dataset_id | varchar(96) | NOT NULL, FK → evaluation_datasets.id ON DELETE RESTRICT |
使用的评测集 |
| run_status | text | NOT NULL, default 'queued', CHECK IN ('queued', 'running', 'succeeded', 'failed', 'canceled') |
运行状态 |
| tested_config_snapshot | jsonb | NOT NULL, default '{}'::jsonb |
被测 Prompt、Agent、上下文策略快照 |
| judge_model_set | jsonb | NOT NULL, default '[]'::jsonb |
多模型评审集合 |
| result_summary | jsonb | nullable | 算法汇总评分、置信度和指标 |
| risk_summary | jsonb | nullable | 风险结论 |
| started_at | timestamptz | nullable | 开始时间 |
| finished_at | timestamptz | nullable | 完成时间 |
| created_by | varchar(96) | nullable, FK → users.id ON DELETE SET NULL |
发起人 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| updated_at | timestamptz | NOT NULL, default now() |
更新时间 |
约束:
- 评测运行只影响系统改进判断,不替代普通用户对正文、规划和作品知识的确认。
3.8 Audit & Projection(审计与投影)
audit_logs
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | 审计日志 ID |
| work_id | varchar(96) | nullable, FK → works.id ON DELETE CASCADE |
所属作品;全局认证行为可为空 |
| user_id | varchar(96) | nullable, FK → users.id ON DELETE SET NULL |
用户操作者;系统任务可为空 |
| service_identity_id | varchar(96) | nullable, FK → system_service_identities.id ON DELETE SET NULL |
系统任务服务身份 |
| actor_role | text | nullable, CHECK IN ('admin', 'user', 'system_job') |
操作角色 |
| action | text | NOT NULL | 动作名 |
| target_type | text | NOT NULL | 目标类型 |
| target_id | varchar(96) | nullable | 目标 ID |
| source_surface | text | nullable, CHECK IN ('admin_console', 'user_workspace', 'personal_center', 'system_job') |
来源入口 |
| request_id | text | nullable | 请求追踪 ID |
| metadata | jsonb | NOT NULL, default '{}'::jsonb |
结构化上下文;禁止写正文全文 |
| created_at | timestamptz | NOT NULL, default now() |
发生时间 |
projection_outbox
PG 事务内写业务数据 + outbox,保证原子性。投影消费者从 outbox 幂等消费,用 PG 稳定业务 ID 做幂等键。 只有 Canonical(规范数据) 正文与已确认知识会写入正式投影;
suggestions/proposals里的 Shadow draft 永不直接进入正式检索。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | varchar(96) | PK, 应用层生成 | 消息 ID |
| work_id | varchar(96) | NOT NULL | 所属作品 |
| event_type | text | NOT NULL | 事件类型,如 entity_created、attribute_changed、relation_added、event_recorded |
| payload | jsonb | NOT NULL | 事件载荷 |
| projection_target | text | NOT NULL | 投影目标:ragflow / graph_provider;若 Graph Query Provider 选型为 Neo4j,则由 graph_provider 消费者写入 Neo4j |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
| consumed_at | timestamptz | nullable | 消费时间,NULL 表示未消费 |
projection_watermarks
每个投影目标独立 watermark。Context Assembly 组装时读 watermark 判断投影是否追平,未追平时用 PG overlay 补齐。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| work_id | varchar(96) | PK (composite) | 所属作品 |
| projection_target | text | PK (composite) | 投影目标:ragflow / graph_provider |
| last_synced_revision | bigint | NOT NULL | 最后同步的 revision |
| last_synced_at | timestamptz | NOT NULL | 最后同步时间 |
3.9 Integration(外部集成)
ragflow_id_mappings
维护 PG 业务 ID ↔ RAGFlow document ID 的映射。Graph Query Provider 若落到 Neo4j,不需要单独映射表——图节点直接使用 PG 稳定业务 ID。
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| pg_id | varchar(96) | PK (composite) | PG 侧业务 ID(entity ID 或 block ID) |
| pg_type | text | PK (composite) | PG 侧类型:entity / block |
| ragflow_doc_id | text | NOT NULL | RAGFlow 侧文档 ID |
| work_id | varchar(96) | NOT NULL | 所属作品 |
| created_at | timestamptz | NOT NULL, default now() |
创建时间 |
4. 外键与删除策略
4.1 Canonical(规范数据)
users → works:RESTRICT。用户删除必须走缓冲期和应用层编排,不能裸删。works → chapters → blocks:CASCADE。作品删除时正文整体删除。works → knowledge_entities / knowledge_relations / knowledge_attribute_changes / narrative_states:CASCADE。
4.2 Shadow(待审层) Active(活跃层)
works → generation_jobs / extraction_jobs / suggestions / proposals:CASCADE。blocks → suggestions.target_block_id:SET NULL,保留待审对象直到过期或归档。knowledge_entities → proposals.entity_id:SET NULL,保留提案上下文。
4.3 Archive(归档层) / Audit
- Archive(归档层) 表不反向依赖 Active(活跃层) 表。
- Archive(归档层) 中保留原始业务 ID 与快照,允许下游对象被删除后仍保留审核证据。
audit_logs.user_id使用SET NULL,避免因用户删除破坏审计链。
5. 索引策略
5.1 热路径
| 索引 | 类型 | 用途 |
|---|---|---|
works(user_id, updated_at DESC) |
B-tree | 用户作品列表 |
chapters(work_id, order_index) |
B-tree, UNIQUE | 章节树 |
blocks(work_id, chapter_id, order_index) |
B-tree | 章节 Block(文本块) 有序分页 |
suggestions(work_id, target_block_id, created_at DESC) |
B-tree | Block(文本块) 待审建议 |
proposals(work_id, created_at DESC) |
B-tree | 提案列表 |
proposals(parse_job_id, chapter_id, created_at DESC) |
B-tree | 全书解析章节批量确认边界查询 |
generation_jobs(work_id, status, created_at DESC) |
B-tree | 生成作业查询 |
extraction_jobs(work_id, status, created_at DESC) |
B-tree | 提取作业查询 |
knowledge_entities(work_id, entity_type, name) |
B-tree | 实体列表/筛选 |
knowledge_relations(work_id, source_entity_id) |
B-tree | 关系展开 |
narrative_states(work_id, scope) |
B-tree, partial UNIQUE | work scope Narrative State 读取 |
narrative_states(work_id, scope, chapter_id) |
B-tree, partial UNIQUE | chapter scope Narrative State 读取 |
narrative_states(work_id, scope, entity_id) |
B-tree, partial UNIQUE | entity scope Narrative State 读取 |
prompt_versions(prompt_key, version) |
B-tree, UNIQUE | Prompt 版本追溯 |
prompt_versions(prompt_key) WHERE status='active' |
B-tree, partial UNIQUE | 每个 Prompt 当前 active 版本 |
agent_configs(agent_key, version) |
B-tree, UNIQUE | Agent 配置版本追溯 |
agent_configs(agent_key) WHERE status='active' |
B-tree, partial UNIQUE | 每个 Agent 当前 active 版本 |
global_knowledge_bases(kb_key, version) |
B-tree, UNIQUE | 全局知识库版本 |
global_knowledge_access_policies(global_kb_id, subject_type, subject_id, status) |
B-tree | 授权判断 |
newapi_user_bindings(user_id) |
B-tree, UNIQUE | 用户绑定读取 |
newapi_plan_mappings(muse_plan_key, version) |
B-tree, UNIQUE | 套餐映射版本 |
evaluation_datasets(dataset_key, version) |
B-tree, UNIQUE | 评测集版本 |
evaluation_runs(dataset_id, created_at DESC) |
B-tree | 评测运行历史 |
audit_logs(source_surface, created_at DESC) |
B-tree | 管理员/用户入口审计筛选 |
5.2 JSONB(二进制JSON)
| 索引 | 类型 | 用途 |
|---|---|---|
knowledge_entities(attributes) |
GIN | 按属性路径查询 |
suggestions(anchor_payload) |
GIN | 锚点范围查询 |
meta_fields(validation_rules) |
GIN | 规则检索/调试 |
(v4 修正:移除 knowledge_entities(embedding) HNSW/IVFFlat 向量索引,向量检索改为 RAGFlow)
说明:
- 语义检索由 RAGFlow 提供,不再依赖 PostgreSQL 向量索引。
6. 迁移建议
6.1 必须一次定死的东西
blocks.content的结构化 JSON(结构化文本) 形态works的导入/解析状态字段- Shadow(待审层) Active(活跃层) 与 Archive(归档层) 分层
meta_schemas.scope + target_type- 元数据可见性字段:
ui_visible、ai_context、user_editable、user_searchable、exportable knowledge_attribute_changesnarrative_states作为 Narrative State 真实运行态载体proposals.parse_job_id + chapter_id作为 Full Parse(全书解析) 章节批量确认边界- 管理员配置对象的版本与启停语义:
prompt_versions、agent_configs、global_knowledge_bases、global_knowledge_access_policies、evaluation_datasets
6.2 可以后补的东西
- 更细粒度的
anchor_type - Archive(归档层) 查询 API(接口)
- 不建
local_knowledge_bases显式表;局域知识库由work_id + knowledge_* / narrative_states表达 - 不建
usage_logs显式表或本地 usage 汇总表;用户可见用量由 New-API 汇总和 Muse 任务级 usage 摘要生成
6.3 与完整建表 SQL 的同步口径
后端-04a-完整建表SQL.sql 当前标注为 V1-V18 实际落地 SQL,不是本文件目标 Schema 的自动展开。只有当这些目标结构进入正式 migration 设计时,才同步改 后端-04a;不能为了让 SQL 看起来完整而把尚未确认的目标表伪装成已落地事实。
7. 非目标
以下内容不在本版 Schema(结构定义) 中解决:
- 多人协同编辑
- 版本回滚到任意历史快照
- 草稿层(用户私有 Draft(草稿层))与 Canonical(规范数据) 的双层正文模型
- 通用任务编排平台
- 把 New-API 的模型供应商、路由、成本策略和消耗日志复制到 Muse 作为新事实源
- 为作品规划台每个 UI 面板单独建表
8. 关联阅读
- 模型与双轨规则:
架构-02-核心数据结构与双轨模型.md - 接口契约:
后端-05-统一API契约-v1.md - 生命周期与约束:
架构-04-状态机与约束清单.md - 完整建表 SQL(当前实际落地状态):
后端-04a-完整建表SQL.sql