1
0
Files
nex/backend/migrations/20260421000001_initial_schema.sql
lanyuanxiaoyao 395887667d feat: 实现统一模型 ID 机制
实现统一模型 ID 格式 (provider_id/model_name),支持跨协议模型标识和 Smart Passthrough。

核心变更:
- 新增 pkg/modelid 包:解析、格式化、校验统一模型 ID
- 数据库迁移:models 表使用 UUID 主键 + UNIQUE(provider_id, model_name) 约束
- Repository 层:FindByProviderAndModelName、ListEnabled 方法
- Service 层:联合唯一校验、provider ID 字符集校验
- Conversion 层:ExtractModelName、RewriteRequestModelName/RewriteResponseModelName 方法
- Handler 层:统一模型 ID 路由、Smart Passthrough、Models API 本地聚合
- 新增 error-responses、unified-model-id 规范

测试覆盖:
- 单元测试:modelid、conversion、handler、service、repository
- 集成测试:统一模型 ID 路由、Smart Passthrough 保真性、跨协议转换
- 迁移测试:UUID 主键、UNIQUE 约束、级联删除

OpenSpec:
- 归档 unified-model-id 变更到 archive/2026-04-21-unified-model-id
- 同步 11 个 delta specs 到 main specs
- 新增 error-responses、unified-model-id 规范文件
2026-04-21 18:14:10 +08:00

46 lines
1.5 KiB
SQL
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.
-- +goose Up
-- 统一初始迁移providers、models、usage_stats 完整表结构
-- models 表使用 UUID 主键 + UNIQUE(provider_id, model_name) 联合唯一约束
CREATE TABLE IF NOT EXISTS providers (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
api_key TEXT NOT NULL,
base_url TEXT NOT NULL,
protocol TEXT DEFAULT 'openai',
enabled INTEGER DEFAULT 1,
created_at DATETIME,
updated_at DATETIME
);
CREATE TABLE IF NOT EXISTS models (
id TEXT PRIMARY KEY,
provider_id TEXT NOT NULL,
model_name TEXT NOT NULL,
enabled INTEGER DEFAULT 1,
created_at DATETIME,
FOREIGN KEY (provider_id) REFERENCES providers(id) ON DELETE CASCADE,
UNIQUE(provider_id, model_name)
);
CREATE TABLE IF NOT EXISTS usage_stats (
id INTEGER PRIMARY KEY AUTOINCREMENT,
provider_id TEXT NOT NULL,
model_name TEXT NOT NULL,
request_count INTEGER DEFAULT 0,
date DATE NOT NULL,
UNIQUE(provider_id, model_name, date)
);
CREATE INDEX IF NOT EXISTS idx_models_provider_id ON models(provider_id);
CREATE INDEX IF NOT EXISTS idx_models_model_name ON models(model_name);
CREATE INDEX IF NOT EXISTS idx_usage_stats_provider_model_date ON usage_stats(provider_id, model_name, date);
-- +goose Down
DROP INDEX IF EXISTS idx_usage_stats_provider_model_date;
DROP INDEX IF EXISTS idx_models_model_name;
DROP INDEX IF EXISTS idx_models_provider_id;
DROP TABLE IF EXISTS usage_stats;
DROP TABLE IF EXISTS models;
DROP TABLE IF EXISTS providers;