Appearance
数据库结构 v4(外部 API Key 与分配 + Assignments step 绑定)
本版本新增两张表用于管理外部聚合服务的 API Key 以及其在学校/用户范围内的分配关系;并兼容此前的迁移记录与运行中库的重复执行。
依赖:Alembic 迁移 9f1e2d3c4b5a_add_external_api_key_tables.py(down_revision: 20250101_000002)。
变更摘要:
- 新增表
external_api_keys - 新增表
external_api_key_assignments - 旧列名
metadata调整为meta(迁移脚本将自动检查并重命名) - 对关键索引做了“幂等”检查,避免重复执行导致的 Duplicate 错误
- assignments 增加可选外键
step_id→chapter_steps.id(索引:ix_assignments_step_id,ON DELETE SET NULL)
external_api_keys
- id: int pk
- provider: varchar(32) not null, index(取值:
new_api/ai_intent) - name: varchar(128) not null, 用于检索显示
- remote_token_id: varchar(64) null,上游 token id(可选)
- key_encrypted: text not null,加密存储的密钥明文
- key_masked: varchar(128) not null,脱敏展示(如
sk-xxxx...abcd) - status: varchar(16) not null default
active(active/disabled/revoked) - meta: jsonb null(额度、分组等元信息)
- created_by_user_id: int null(记录创建人,当前未强制)
- created_at: timestamptz not null default now()
- deleted: boolean not null default false(软删除)
索引:
- ix_external_api_keys_provider(provider)
- ix_external_api_keys_status(status)
- ix_external_api_keys_deleted(deleted)
备注:
- 运行中库若存在
metadata列,会在迁移中自动重命名为meta。
external_api_key_assignments
- id: int pk
- provider: varchar(32) not null(
new_api/ai_intent) - api_key_id: int not null → fk external_api_keys.id
- scope_type: varchar(16) not null(
school/user) - scope_id: int not null(
school→ schools.id;user→ users.id) - is_default: boolean not null default false(同一学校+provider 仅允许 0/1 个默认,迁移不做约束,由业务写操作保证)
- created_by_user_id: int null
- created_at: timestamptz not null default now()
索引:
- ix_external_api_key_assignments_provider(provider)
- ix_external_api_key_assignments_scope(scope_type, scope_id)
- ix_external_api_key_assignments_is_default(is_default)
assignments 与步骤绑定(新增)
- 表:
assignments - 新增列:
step_id INT NULL→ 外键chapter_steps.id - 索引:
ix_assignments_step_id(step_id) - 级联:
ON DELETE SET NULL - 业务校验:当请求体提供
step_id时,需验证该chapter_steps.id通过其chapter_id归属于courses.id = assignments.course_id
迁移(示意 SQL):
sql
ALTER TABLE assignments ADD COLUMN step_id INT NULL;
CREATE INDEX IF NOT EXISTS ix_assignments_step_id ON assignments(step_id);
ALTER TABLE assignments
ADD CONSTRAINT fk_assignments_step_id_chapter_steps
FOREIGN KEY (step_id) REFERENCES chapter_steps(id) ON DELETE SET NULL;解析与使用
- 解析优先级:用户级 > 学校默认 > 全局默认(settings.NEW_API_KEY / settings.AI_INTENT_KEY)
- new_api 的 Bearer Token 需要
sk-前缀;后端在请求前会自动补齐(若存储为裸 key) - 学校管理员可只读查看本校被分配的 Key,并按 token / api_key_id 查询日志(仅透传,不落库)