# 旧 Python 网关数据字典与 ID 迁移映射

> 由 `scripts/export_legacy_dictionary.py` 从旧工程 SQLAlchemy metadata 生成。
> `audit_log_views` 是兼容查询投影，不作为独立持久化实体，因此这里统计 38 个实体。

## 映射约定

- 旧整数主键统一通过 `gateway.legacy_id_mappings` 映射为 UUID，不在新业务表保留双主键。
- UUID 使用固定 namespace 的 UUIDv5 生成，输入为 `source_system/entity_type/legacy_id`，重复导入保持幂等。
- 外键迁移必须先查映射表；缺失映射时整批失败，不允许写入悬空引用。
- 旧密文不能直接复用：Provider、TOTP、内部服务 Key 等敏感字段在导入时解密后用新用途标签重新加密。
- `audit_logs` 的完整请求/响应正文不进入新库，只迁移受长度约束的预览与结构化元数据。

## 实体去向

| 旧表 | 新域/目标 | 状态 |
|---|---|---|
| `admin_accounts` | gateway.admin_accounts（已落地） | 已建表，待批量导入器 |
| `application_revisions` | gateway.application_versions | 已建表，待批量导入器转换 config 引用 |
| `application_runs` | gateway.application_runs | 已建表，待批量导入器 |
| `applications` | gateway.applications | 已建表，待批量导入器 |
| `audit_logs` | gateway.audit_events（已落地，不迁移无限长正文） | 已建表，待批量导入器 |
| `audit_search_records` | 对应 M2–M4 领域表 | 已登记，随对应里程碑建表 |
| `audit_settings` | 对应 M2–M4 领域表 | 已登记，随对应里程碑建表 |
| `content_audit_scopes` | 对应 M2–M4 领域表 | 已登记，随对应里程碑建表 |
| `departments` | gateway.departments（已落地） | 已建表，待批量导入器 |
| `dept_budgets` | 对应 M2–M4 领域表 | 已登记，随对应里程碑建表 |
| `feishu_auth_settings` | 对应 M2–M4 领域表 | 已登记，随对应里程碑建表 |
| `filter_rules` | 对应 M2–M4 领域表 | 已登记，随对应里程碑建表 |
| `hallucination_events` | 对应 M2–M4 领域表 | 已登记，随对应里程碑建表 |
| `hallucination_policies` | 对应 M2–M4 领域表 | 已登记，随对应里程碑建表 |
| `hallucination_settings` | 对应 M2–M4 领域表 | 已登记，随对应里程碑建表 |
| `internal_service_keys` | 对应 M2–M4 领域表 | 已登记，随对应里程碑建表 |
| `knowledge_bases` | gateway.knowledge_bases | 已建表，旧 embedding_model 转检索器迁移策略待导入器处理 |
| `knowledge_chunks` | gateway.knowledge_chunks | 已建表，基线重新分块/建 PostgreSQL 搜索向量 |
| `knowledge_documents` | gateway.knowledge_documents | 已建表，只导入不超过 2 MiB 的提取文本 |
| `managed_conversations` | 对应 M2–M4 领域表 | 已登记，随对应里程碑建表 |
| `managed_messages` | 对应 M2–M4 领域表 | 已登记，随对应里程碑建表 |
| `model_aliases` | 对应 M2–M4 领域表 | 已登记，随对应里程碑建表 |
| `model_pricing` | 对应 M2–M4 领域表 | 已登记，随对应里程碑建表 |
| `model_qps_configs` | 对应 M2–M4 领域表 | 已登记，随对应里程碑建表 |
| `model_requests` | 对应 M2–M4 领域表 | 已登记，随对应里程碑建表 |
| `notify_config` | gateway.notification_channels | 已建表，待解密后重新加密签名密钥 |
| `pricing_config` | 对应 M2–M4 领域表 | 已登记，随对应里程碑建表 |
| `prompt_categories` | gateway.prompt_categories | 已建表，待批量导入器 |
| `prompt_favorites` | 对应 M2–M4 领域表 | 已登记，随对应里程碑建表 |
| `prompt_templates` | gateway.prompt_templates | 已建表，待批量导入器 |
| `prompt_versions` | gateway.prompt_versions | 已建表，待批量导入器 |
| `providers` | gateway.providers + gateway.provider_models（已落地，models 拆表） | 已建表，待批量导入器 |
| `rate_limit_rules` | 对应 M2–M4 领域表 | 已登记，随对应里程碑建表 |
| `routing_groups` | 对应 M2–M4 领域表 | 已登记，随对应里程碑建表 |
| `routing_targets` | 对应 M2–M4 领域表 | 已登记，随对应里程碑建表 |
| `tool_definitions` | gateway.tool_definitions | 已建表，待解密后用新用途标签加密请求头 |
| `users` | gateway.portal_users（已落地） | 已建表，待批量导入器 |
| `virtual_keys` | gateway.api_keys（已落地，字段需转换） | 已建表，待批量导入器 |

## 字段字典

### `admin_accounts`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `username` | `VARCHAR(64)` | 否 | `—` | UNIQUE |
| `password_hash` | `VARCHAR(128)` | 否 | `—` | — |
| `display_name` | `VARCHAR(64)` | 是 | `` | — |
| `role` | `VARCHAR(16)` | 是 | `superadmin` | — |
| `active` | `BOOLEAN` | 是 | `True` | — |
| `last_login` | `DATETIME` | 是 | `—` | — |
| `failed_logins` | `INTEGER` | 是 | `0` | — |
| `locked_until` | `DATETIME` | 是 | `—` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |
| `totp_secret` | `VARCHAR(255)` | 是 | `` | — |
| `totp_enabled` | `BOOLEAN` | 是 | `False` | — |
| `totp_last_step` | `INTEGER` | 是 | `—` | — |
| `totp_backup_codes` | `TEXT` | 是 | `[]` | — |
| `totp_confirmed_at` | `DATETIME` | 是 | `—` | — |

### `application_revisions`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `application_id` | `INTEGER` | 否 | `—` | FK → `applications.id` |
| `version` | `INTEGER` | 否 | `—` | — |
| `config` | `TEXT` | 否 | `—` | — |
| `change_note` | `VARCHAR(256)` | 是 | `` | — |
| `published_by` | `VARCHAR(128)` | 是 | `` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |

### `application_runs`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `application_id` | `INTEGER` | 否 | `—` | FK → `applications.id` |
| `version` | `INTEGER` | 是 | `0` | — |
| `user_id` | `INTEGER` | 是 | `—` | FK → `users.id` |
| `status` | `VARCHAR(16)` | 是 | `success` | — |
| `latency_ms` | `INTEGER` | 是 | `0` | — |
| `retrieval_count` | `INTEGER` | 是 | `0` | — |
| `tool_calls` | `INTEGER` | 是 | `0` | — |
| `error` | `VARCHAR(512)` | 是 | `` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |

### `applications`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `app_code` | `VARCHAR(64)` | 否 | `—` | UNIQUE |
| `name` | `VARCHAR(128)` | 否 | `—` | — |
| `description` | `TEXT` | 是 | `` | — |
| `dept_id` | `INTEGER` | 是 | `—` | FK → `departments.id` |
| `owner_user_id` | `INTEGER` | 是 | `—` | FK → `users.id` |
| `status` | `VARCHAR(16)` | 是 | `active` | — |
| `allowed_models` | `TEXT` | 是 | `[]` | — |
| `quota_tokens` | `INTEGER` | 是 | `—` | — |
| `rpm_limit` | `INTEGER` | 是 | `—` | — |
| `draft_config` | `TEXT` | 是 | `{}` | — |
| `published_config` | `TEXT` | 是 | `{}` | — |
| `release_version` | `INTEGER` | 是 | `0` | — |
| `published_at` | `DATETIME` | 是 | `—` | — |
| `runtime_key_id` | `INTEGER` | 是 | `—` | — |
| `runtime_key_secret` | `TEXT` | 是 | `` | — |
| `created_by` | `VARCHAR(128)` | 是 | `` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |
| `updated_at` | `DATETIME` | 是 | `now` | — |

### `audit_logs`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `event_id` | `VARCHAR(32)` | 是 | `—` | UNIQUE |
| `ts` | `DATETIME` | 是 | `now` | — |
| `key_id` | `INTEGER` | 是 | `—` | — |
| `key_name` | `VARCHAR(128)` | 是 | `` | — |
| `user_id` | `INTEGER` | 是 | `—` | — |
| `owner` | `VARCHAR(128)` | 是 | `—` | — |
| `model` | `VARCHAR(64)` | 是 | `—` | — |
| `client_ip` | `VARCHAR(64)` | 是 | `—` | — |
| `request_body` | `TEXT` | 是 | `—` | — |
| `response_body` | `TEXT` | 是 | `—` | — |
| `request_body_ref` | `VARCHAR(512)` | 是 | `` | — |
| `response_body_ref` | `VARCHAR(512)` | 是 | `` | — |
| `request_body_size` | `INTEGER` | 是 | `0` | — |
| `response_body_size` | `INTEGER` | 是 | `0` | — |
| `request_body_sha256` | `VARCHAR(64)` | 是 | `` | — |
| `response_body_sha256` | `VARCHAR(64)` | 是 | `` | — |
| `prompt_tokens` | `INTEGER` | 是 | `0` | — |
| `completion_tokens` | `INTEGER` | 是 | `0` | — |
| `filter_hits` | `TEXT` | 是 | `[]` | — |
| `outcome` | `VARCHAR(16)` | 是 | `pass` | — |
| `blocked` | `BOOLEAN` | 是 | `False` | — |
| `status_code` | `INTEGER` | 是 | `200` | — |
| `latency_ms` | `INTEGER` | 是 | `0` | — |
| `search_text` | `TEXT` | 是 | `` | — |

### `audit_search_records`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `viewer` | `VARCHAR(128)` | 否 | `—` | — |
| `query_hash` | `VARCHAR(64)` | 否 | `—` | — |
| `start_at` | `DATETIME` | 否 | `—` | — |
| `end_at` | `DATETIME` | 否 | `—` | — |
| `owner_filter` | `VARCHAR(128)` | 是 | `` | — |
| `model_filter` | `VARCHAR(128)` | 是 | `` | — |
| `result_count` | `INTEGER` | 是 | `0` | — |
| `duration_ms` | `INTEGER` | 是 | `0` | — |
| `ts` | `DATETIME` | 是 | `now` | — |

### `audit_settings`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `image_audit_enabled` | `BOOLEAN` | 是 | `True` | — |
| `media_audit_async` | `BOOLEAN` | 是 | `False` | — |
| `text_audit_enabled` | `BOOLEAN` | 是 | `False` | — |
| `deep_scan_enabled` | `BOOLEAN` | 是 | `False` | — |
| `text_audit_api_base` | `VARCHAR(256)` | 是 | `` | — |
| `text_audit_api_key` | `VARCHAR(512)` | 是 | `` | — |
| `text_audit_model` | `VARCHAR(128)` | 是 | `` | — |
| `image_audit_api_base` | `VARCHAR(256)` | 是 | `` | — |
| `image_audit_api_key` | `VARCHAR(512)` | 是 | `` | — |
| `image_audit_model` | `VARCHAR(128)` | 是 | `` | — |
| `updated_at` | `DATETIME` | 是 | `now` | — |

### `content_audit_scopes`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `kind` | `VARCHAR(16)` | 否 | `—` | — |
| `scope` | `VARCHAR(32)` | 否 | `—` | — |
| `enabled` | `BOOLEAN` | 是 | `True` | — |
| `mode` | `VARCHAR(16)` | 是 | `async` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |

### `departments`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `name` | `VARCHAR(64)` | 否 | `—` | UNIQUE |
| `created_at` | `DATETIME` | 是 | `now` | — |

### `dept_budgets`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `dept_id` | `INTEGER` | 否 | `—` | UNIQUE；FK → `departments.id` |
| `monthly_point_budget` | `FLOAT` | 是 | `0.0` | — |
| `alert_threshold_pct` | `INTEGER` | 是 | `80` | — |
| `notify_enabled` | `BOOLEAN` | 是 | `True` | — |
| `last_alert_period` | `VARCHAR(7)` | 是 | `` | — |
| `last_alert_threshold` | `INTEGER` | 是 | `0` | — |
| `updated_at` | `DATETIME` | 是 | `now` | — |

### `feishu_auth_settings`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `enabled` | `BOOLEAN` | 是 | `False` | — |
| `app_id` | `VARCHAR(128)` | 是 | `` | — |
| `app_secret` | `VARCHAR(512)` | 是 | `` | — |
| `default_dept` | `VARCHAR(128)` | 是 | `飞书用户` | — |
| `allowed_tenants` | `TEXT` | 是 | `[]` | — |
| `provisioning_mode` | `VARCHAR(16)` | 是 | `pending` | — |
| `updated_at` | `DATETIME` | 是 | `now` | — |

### `filter_rules`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `name` | `VARCHAR(64)` | 否 | `—` | — |
| `rule_type` | `VARCHAR(16)` | 是 | `keyword` | — |
| `pattern` | `TEXT` | 否 | `—` | — |
| `action` | `VARCHAR(16)` | 是 | `block` | — |
| `severity` | `VARCHAR(8)` | 是 | `中` | — |
| `enabled` | `BOOLEAN` | 是 | `True` | — |
| `builtin` | `BOOLEAN` | 是 | `False` | — |
| `scope` | `VARCHAR(32)` | 是 | `global` | — |
| `dimension` | `VARCHAR(32)` | 是 | `sensitive_content` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |

### `hallucination_events`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `request_id` | `VARCHAR(64)` | 是 | `` | — |
| `key_id` | `INTEGER` | 是 | `—` | FK → `virtual_keys.id` |
| `application_id` | `INTEGER` | 是 | `—` | FK → `applications.id` |
| `dept_id` | `INTEGER` | 是 | `—` | FK → `departments.id` |
| `model` | `VARCHAR(128)` | 是 | `` | — |
| `mode` | `VARCHAR(16)` | 是 | `async` | — |
| `action` | `VARCHAR(16)` | 是 | `observe` | — |
| `verdict` | `VARCHAR(24)` | 是 | `insufficient` | — |
| `support_score` | `INTEGER` | 是 | `0` | — |
| `question` | `TEXT` | 是 | `` | — |
| `answer` | `TEXT` | 是 | `` | — |
| `claims` | `TEXT` | 是 | `[]` | — |
| `evidence` | `TEXT` | 是 | `[]` | — |
| `latency_ms` | `INTEGER` | 是 | `0` | — |
| `error` | `VARCHAR(512)` | 是 | `` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |

### `hallucination_policies`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `scope` | `VARCHAR(32)` | 否 | `global` | — |
| `enabled` | `BOOLEAN` | 是 | `False` | — |
| `mode` | `VARCHAR(16)` | 是 | `async` | — |
| `action` | `VARCHAR(16)` | 是 | `observe` | — |
| `kb_ids` | `TEXT` | 是 | `[]` | — |
| `support_threshold` | `INTEGER` | 是 | `70` | — |
| `evidence_threshold` | `FLOAT` | 是 | `0.35` | — |
| `top_k` | `INTEGER` | 是 | `4` | — |
| `max_claims` | `INTEGER` | 是 | `8` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |
| `updated_at` | `DATETIME` | 是 | `now` | — |

### `hallucination_settings`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `1` | PK |
| `api_base` | `VARCHAR(256)` | 是 | `` | — |
| `api_key` | `VARCHAR(512)` | 是 | `` | — |
| `model` | `VARCHAR(128)` | 是 | `` | — |
| `timeout_seconds` | `INTEGER` | 是 | `15` | — |
| `updated_at` | `DATETIME` | 是 | `now` | — |

### `internal_service_keys`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `virtual_key_id` | `INTEGER` | 是 | `—` | FK → `virtual_keys.id` |
| `raw_key_encrypted` | `VARCHAR(512)` | 是 | `` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |

### `knowledge_bases`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `name` | `VARCHAR(128)` | 否 | `—` | UNIQUE |
| `description` | `TEXT` | 是 | `` | — |
| `embedding_model` | `VARCHAR(128)` | 否 | `—` | — |
| `chunk_size` | `INTEGER` | 是 | `800` | — |
| `chunk_overlap` | `INTEGER` | 是 | `100` | — |
| `dept_scope` | `TEXT` | 是 | `[]` | — |
| `enabled` | `BOOLEAN` | 是 | `True` | — |
| `created_by` | `VARCHAR(128)` | 是 | `` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |
| `updated_at` | `DATETIME` | 是 | `now` | — |

### `knowledge_chunks`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `kb_id` | `INTEGER` | 否 | `—` | FK → `knowledge_bases.id` |
| `doc_id` | `INTEGER` | 否 | `—` | FK → `knowledge_documents.id` |
| `chunk_index` | `INTEGER` | 是 | `0` | — |
| `content` | `TEXT` | 是 | `` | — |
| `embedding` | `TEXT` | 是 | `[]` | — |
| `token_count` | `INTEGER` | 是 | `0` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |

### `knowledge_documents`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `kb_id` | `INTEGER` | 否 | `—` | FK → `knowledge_bases.id` |
| `filename` | `VARCHAR(256)` | 是 | `` | — |
| `source_type` | `VARCHAR(16)` | 是 | `upload` | — |
| `status` | `VARCHAR(16)` | 是 | `pending` | — |
| `status_message` | `TEXT` | 是 | `` | — |
| `content` | `TEXT` | 是 | `` | — |
| `char_count` | `INTEGER` | 是 | `0` | — |
| `chunk_count` | `INTEGER` | 是 | `0` | — |
| `uploaded_by` | `VARCHAR(128)` | 是 | `` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |
| `updated_at` | `DATETIME` | 是 | `now` | — |

### `managed_conversations`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `VARCHAR(48)` | 否 | `—` | PK |
| `user_id` | `INTEGER` | 否 | `—` | FK → `users.id` |
| `application_id` | `INTEGER` | 否 | `—` | FK → `applications.id` |
| `title` | `VARCHAR(160)` | 是 | `新会话` | — |
| `status` | `VARCHAR(16)` | 否 | `active` | — |
| `next_seq` | `INTEGER` | 否 | `1` | — |
| `head_hash` | `VARCHAR(64)` | 否 | `` | — |
| `busy` | `BOOLEAN` | 否 | `False` | — |
| `busy_token` | `VARCHAR(48)` | 否 | `` | — |
| `busy_since` | `DATETIME` | 是 | `—` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |
| `updated_at` | `DATETIME` | 是 | `now` | — |

### `managed_messages`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `conversation_id` | `VARCHAR(48)` | 否 | `—` | FK → `managed_conversations.id` |
| `seq` | `INTEGER` | 否 | `—` | — |
| `role` | `VARCHAR(16)` | 否 | `—` | — |
| `content` | `TEXT` | 否 | `—` | — |
| `content_sha256` | `VARCHAR(64)` | 否 | `—` | — |
| `prev_hash` | `VARCHAR(64)` | 否 | `` | — |
| `chain_hash` | `VARCHAR(64)` | 否 | `—` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |

### `model_aliases`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `alias` | `VARCHAR(128)` | 否 | `—` | UNIQUE |
| `target_model` | `VARCHAR(128)` | 否 | `—` | — |
| `enabled` | `BOOLEAN` | 是 | `True` | — |
| `note` | `VARCHAR(256)` | 是 | `` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |
| `updated_at` | `DATETIME` | 是 | `now` | — |

### `model_pricing`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `model` | `VARCHAR(128)` | 否 | `—` | — |
| `input_price_per_1k` | `FLOAT` | 是 | `0.0` | — |
| `output_price_per_1k` | `FLOAT` | 是 | `0.0` | — |
| `effective_from` | `DATETIME` | 是 | `now` | — |
| `note` | `VARCHAR(256)` | 是 | `` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |

### `model_qps_configs`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `model` | `VARCHAR(128)` | 否 | `—` | UNIQUE |
| `qps` | `INTEGER` | 否 | `—` | — |
| `enabled` | `BOOLEAN` | 是 | `True` | — |
| `updated_at` | `DATETIME` | 是 | `now` | — |

### `model_requests`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `ts` | `DATETIME` | 是 | `now` | — |
| `user_id` | `INTEGER` | 否 | `—` | FK → `users.id` |
| `dept_id` | `INTEGER` | 是 | `—` | — |
| `user_snapshot` | `VARCHAR(128)` | 是 | `` | — |
| `model_name` | `VARCHAR(128)` | 否 | `—` | — |
| `provider_name` | `VARCHAR(64)` | 是 | `` | — |
| `purpose` | `TEXT` | 是 | `` | — |
| `quota_required` | `INTEGER` | 是 | `—` | — |
| `status` | `VARCHAR(16)` | 是 | `pending` | — |
| `target_key_id` | `INTEGER` | 是 | `—` | — |
| `reviewer` | `VARCHAR(128)` | 是 | `` | — |
| `review_comment` | `TEXT` | 是 | `` | — |
| `reviewed_at` | `DATETIME` | 是 | `—` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |

### `notify_config`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `enabled` | `BOOLEAN` | 是 | `False` | — |
| `webhook_url` | `VARCHAR(512)` | 是 | `` | — |
| `signing_secret` | `VARCHAR(512)` | 是 | `` | — |
| `notify_actions` | `VARCHAR(32)` | 是 | `block,redact` | — |
| `dept_scope` | `TEXT` | 是 | `[]` | — |
| `updated_at` | `DATETIME` | 是 | `now` | — |

### `pricing_config`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `points_per_yuan` | `FLOAT` | 是 | `100.0` | — |
| `overhead_factor` | `FLOAT` | 是 | `1.0` | — |
| `updated_at` | `DATETIME` | 是 | `now` | — |

### `prompt_categories`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `name` | `VARCHAR(64)` | 否 | `—` | UNIQUE |
| `description` | `VARCHAR(256)` | 是 | `` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |

### `prompt_favorites`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `user_id` | `INTEGER` | 否 | `—` | FK → `users.id` |
| `template_id` | `INTEGER` | 否 | `—` | FK → `prompt_templates.id` |
| `created_at` | `DATETIME` | 是 | `now` | — |

### `prompt_templates`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `name` | `VARCHAR(128)` | 否 | `—` | UNIQUE |
| `description` | `TEXT` | 是 | `` | — |
| `category_id` | `INTEGER` | 是 | `—` | FK → `prompt_categories.id` |
| `tags` | `TEXT` | 是 | `[]` | — |
| `dept_scope` | `TEXT` | 是 | `[]` | — |
| `current_version_id` | `INTEGER` | 是 | `—` | — |
| `use_count` | `INTEGER` | 是 | `0` | — |
| `enabled` | `BOOLEAN` | 是 | `True` | — |
| `created_by` | `VARCHAR(128)` | 是 | `` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |
| `updated_at` | `DATETIME` | 是 | `now` | — |

### `prompt_versions`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `template_id` | `INTEGER` | 否 | `—` | FK → `prompt_templates.id` |
| `version_number` | `INTEGER` | 否 | `—` | — |
| `content` | `TEXT` | 否 | `—` | — |
| `variables` | `TEXT` | 是 | `[]` | — |
| `change_note` | `VARCHAR(256)` | 是 | `` | — |
| `created_by` | `VARCHAR(128)` | 是 | `` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |

### `providers`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `name` | `VARCHAR(64)` | 否 | `—` | UNIQUE |
| `base_url` | `VARCHAR(256)` | 否 | `—` | — |
| `api_key` | `VARCHAR(512)` | 是 | `` | — |
| `models` | `TEXT` | 是 | `[]` | — |
| `backends` | `TEXT` | 是 | `` | — |
| `enabled` | `BOOLEAN` | 是 | `True` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |

### `rate_limit_rules`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `name` | `VARCHAR(64)` | 否 | `—` | — |
| `enabled` | `BOOLEAN` | 是 | `True` | — |
| `dimension` | `VARCHAR(16)` | 是 | `consumer` | — |
| `field_name` | `VARCHAR(64)` | 是 | `` | — |
| `match_type` | `VARCHAR(16)` | 是 | `any` | — |
| `pattern` | `VARCHAR(256)` | 是 | `` | — |
| `limit_count` | `INTEGER` | 否 | `60` | — |
| `window_seconds` | `INTEGER` | 是 | `60` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |
| `updated_at` | `DATETIME` | 是 | `now` | — |

### `routing_groups`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `virtual_model` | `VARCHAR(128)` | 否 | `—` | UNIQUE |
| `strategy` | `VARCHAR(16)` | 是 | `priority` | — |
| `description` | `VARCHAR(256)` | 是 | `` | — |
| `enabled` | `BOOLEAN` | 是 | `True` | — |
| `created_by` | `VARCHAR(128)` | 是 | `` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |
| `updated_at` | `DATETIME` | 是 | `now` | — |

### `routing_targets`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `group_id` | `INTEGER` | 否 | `—` | FK → `routing_groups.id` |
| `target_model` | `VARCHAR(128)` | 否 | `—` | — |
| `priority` | `INTEGER` | 是 | `100` | — |
| `capability_tags` | `TEXT` | 是 | `[]` | — |
| `enabled` | `BOOLEAN` | 是 | `True` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |

### `tool_definitions`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `name` | `VARCHAR(128)` | 否 | `—` | UNIQUE |
| `description` | `TEXT` | 是 | `` | — |
| `endpoint_url` | `VARCHAR(512)` | 否 | `—` | — |
| `http_method` | `VARCHAR(8)` | 是 | `POST` | — |
| `headers_template` | `TEXT` | 是 | `` | — |
| `input_schema` | `TEXT` | 是 | `{}` | — |
| `timeout_seconds` | `INTEGER` | 是 | `15` | — |
| `dept_scope` | `TEXT` | 是 | `[]` | — |
| `enabled` | `BOOLEAN` | 是 | `True` | — |
| `created_by` | `VARCHAR(128)` | 是 | `` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |
| `updated_at` | `DATETIME` | 是 | `now` | — |

### `users`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `account` | `VARCHAR(128)` | 否 | `—` | UNIQUE |
| `name` | `VARCHAR(64)` | 是 | `` | — |
| `dept_id` | `INTEGER` | 是 | `—` | FK → `departments.id` |
| `password_hash` | `VARCHAR(128)` | 是 | `` | — |
| `feishu_open_id` | `VARCHAR(128)` | 是 | `—` | UNIQUE |
| `feishu_union_id` | `VARCHAR(128)` | 是 | `—` | — |
| `auth_source` | `VARCHAR(16)` | 是 | `local` | — |
| `active` | `BOOLEAN` | 是 | `True` | — |
| `provisioning_status` | `VARCHAR(16)` | 是 | `active` | — |
| `failed_logins` | `INTEGER` | 是 | `0` | — |
| `locked_until` | `DATETIME` | 是 | `—` | — |
| `deleted_name_snapshot` | `VARCHAR(128)` | 是 | `` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |
| `totp_secret` | `VARCHAR(255)` | 是 | `` | — |
| `totp_enabled` | `BOOLEAN` | 是 | `False` | — |
| `totp_last_step` | `INTEGER` | 是 | `—` | — |
| `totp_backup_codes` | `TEXT` | 是 | `[]` | — |
| `totp_confirmed_at` | `DATETIME` | 是 | `—` | — |

### `virtual_keys`

| 字段 | 旧类型 | 可空 | 默认值 | 键/引用 |
|---|---|---:|---|---|
| `id` | `INTEGER` | 否 | `—` | PK |
| `key_hash` | `VARCHAR(64)` | 否 | `—` | UNIQUE |
| `key_prefix` | `VARCHAR(16)` | 是 | `—` | — |
| `name` | `VARCHAR(128)` | 是 | `—` | — |
| `user_id` | `INTEGER` | 是 | `—` | FK → `users.id` |
| `application_id` | `INTEGER` | 是 | `—` | FK → `applications.id` |
| `owner` | `VARCHAR(128)` | 是 | `—` | — |
| `allowed_models` | `TEXT` | 是 | `[]` | — |
| `quota_tokens` | `INTEGER` | 是 | `—` | — |
| `used_tokens` | `INTEGER` | 是 | `0` | — |
| `rpm_limit` | `INTEGER` | 是 | `—` | — |
| `active` | `BOOLEAN` | 是 | `True` | — |
| `expires_at` | `DATETIME` | 是 | `—` | — |
| `created_at` | `DATETIME` | 是 | `now` | — |
