kt-template-online-api/docs/specs/2026-06-14-api-full-module-architecture-schema-plugin-platform-design.md

19 KiB
Raw Blame History

API 全模块架构、全库表设计与 QQBot 插件平台设计

背景

kt-template-online-api 已经从一个相对紧凑的 NestJS 后端,演进为承接 Admin、Blog、WordPress、MinIO、QQBot、NapCat、Loki 运行期事件和线上部署 观测的多领域服务。第一期 Runtime Foundation 已经补上 /health/runtime、 运行时配置检查和证据格式,为后续重构提供了基础观测能力。

第二期不是继续只修 QQBot 或 NapCat而是进入 API 全模块架构规划。当前线上 数据不重要,因此后续实现阶段允许从头设计数据库表,允许重命名表、删除旧字段、 拆分或合并旧表,并重建初始化 SQL。即便允许破坏式重建实现阶段仍必须保留 备份、回滚和线上 smoke避免线上动作不可追踪。

范围决策

本阶段是用户确认的 B 阶段:先完成全局规划,不写业务实现代码。

规划范围:

  1. 定义 API 目标模块架构。
  2. 从头设计全库 schema。
  3. 设计 QQBot 插件平台,支持 worker/child process 隔离、线上安装、热插拔和 CLI 脚手架。
  4. 定义后续 C 阶段的迁移矩阵和实施顺序。

本文件不实现代码、SQL、Admin 页面或运行时行为。用户 review 通过后,下一步 进入 KT workflow KT plan writing。完整 C 阶段迁移开始前,必须重新走一轮 KT requirements and design review。

目标

  • 明确每个 controller、use case、entity、repository、外部集成和测试的模块归属。
  • 用干净的新 schema 替代当前补丁式表历史。
  • 默认保持外部 API 兼容,确实需要破坏兼容时提前列入 breaking changes。
  • 将 QQBot 插件从硬编码 Nest provider 集合升级为统一插件平台。
  • 通过 CLI 脚手架让插件创建、校验、打包和本地安装可重复。
  • 支持线上插件安装、校验、启用、禁用、升级和卸载,不重启整个 API 进程。
  • 将现有 BangDream、FF14 Market、FFLogs、Repeater 按统一插件契约重写。
  • 继承第一期 Runtime Foundation 的可靠性和证据模型,作为后续模块迁移的验证底座。

非目标

  • 本规划阶段不写实现代码。
  • 不为了旧数据迁移方便而保留旧表结构。
  • 不把 Jenkins/K8s rollout 成功当作功能成功。
  • 本阶段不改 Admin 前端。Admin 联动只在本文规划,后续实现前重新 brainstorming。
  • 不绕过 QQ 或腾讯安全校验。NapCat 验证码和新设备验证仍然由用户驱动。
  • 不允许线上安装的插件代码直接访问后端真实密钥、TypeORM Repository 或任意 Nest DI。

目标架构

目标源码结构按平台基础、通用能力和业务模块拆分:

src/
  runtime/
  common/
  modules/
    admin/
    blog/
    wordpress/
    asset/
    qqbot/

runtime 负责运行时基础能力:

  • 类型化运行时配置 profile。
  • 带超时、安全摘要和错误分类的 HTTP/process client。
  • 健康检查和 /health/runtime
  • 运行证据记录。
  • 清理语义。

common 只保留稳定通用能力:

  • Vben 响应和错误工具。
  • 全局 filter/interceptor。
  • 时间字段装饰器和序列化工具。
  • Snowflake ID。
  • 低层文本、对象工具。
  • 非业务专属的日志基础能力。

业务模块内部统一结构:

module/
  contract/
  application/
  domain/
  infrastructure/
    persistence/
    integration/
  schema/
  tests/

分层职责

contractController、请求 DTO、响应 DTO、Swagger 元信息和现有路由兼容适配。

application:用例编排、事务边界、权限检查和状态流转。可以依赖 domain、 repository 和 integration port但不能直接拼外部 HTTP、Docker 脚本或临时 SQL。

domain纯业务规则、状态机、策略和值对象。Domain 代码应能脱离 Nest、TypeORM、 Docker、HTTP 和外部凭据做单元测试。

infrastructure/persistenceTypeORM Entity、Repository 实现、查询模型和 schema mapper。

infrastructure/integrationWordPress HTTP、MinIO SDK、Loki query、OneBot WebSocket、 NapCat WebUI、插件 worker RPC 和 runtime process 适配器。

schema:模块表设计说明、初始化 SQL 归属、重建脚本和验证 SQL。

tests:模块级 unit、contract、repository 和 integration smoke。跨模块用户流程测试可以 继续放在根 test/ 下。

兼容规则

  • 外部 route path 默认保持稳定,除非实现计划明确列入 breaking changes。
  • Admin-facing 业务接口继续使用当前 Vben success/error wrapperstream、file、WebSocket 和 plain JSON 接口除外。
  • /health/runtime 继续返回 plain JSON。
  • Snowflake ID 在 MySQL 中继续使用 BIGINT,在 JavaScript/API 边界按字符串语义处理。
  • 时间字段继续使用 KtDateTime extends Date 和 KT 时间装饰器。
  • 后续实现阶段可以替换旧 SQL 文件为全量新库初始化文件,但本规划阶段不改 SQL 实现。

全库表设计

后续实现阶段允许从头重建 schema。由于当前数据不重要目标 schema 优先服务清晰 数据域和模块所有权,而不是旧表兼容。实现阶段仍必须在破坏式数据库动作前备份, 并提供回滚或恢复命令。

全局表约定

  • 主键使用 Snowflake BIGINT
  • 外键列命名为 *_id 并建立索引。
  • 稳定关系表使用组合唯一约束。
  • 高频日志和事件表避免硬数据库外键,减少 retention 和清理成本。
  • 只有可恢复、可隐藏的业务配置使用软删。
  • 运行事件、命令日志、消息日志、插件运行事件使用 append-only 加 retention。
  • 通用时间字段使用 create_timeupdate_time,需要软删时加 delete_time
  • 状态字段使用明确的 varchar 枚举,并在 schema 说明中列出允许值。
  • JSON 字段只承载外部原始 payload、插件 metadata、低频配置或证据详情可查询字段必须结构化。
  • 有 UI 或存储长度限制的文本字段必须写明截断规则。
  • 新初始化 SQL 应是干净的全量 schema不再累积历史 ALTER TABLE 补丁。

数据域表规划

数据域 目标表 说明
Admin Identity admin_useradmin_roleadmin_permissionadmin_menuadmin_departmentadmin_user_roleadmin_role_permissionadmin_role_menu 保持 Admin 登录和菜单行为稳定,同时拆清路由菜单与权限原子。部门为树结构。头像、时区和首页路径属于用户 profile。
Platform Config platform_dict_groupplatform_dict_itemplatform_component_templateplatform_setting 字典和组件模板从 Admin 杂项中抽离。字典用 group/item 替代当前扁平重载行。
Blog Content blog_postblog_taxonomyblog_termblog_post_termblog_theme_profileblog_import_job 分类、标签使用关系表,不再依赖逗号或长文本字段。主题配置改为可命名 profile。
WordPress Mirror wordpress_sitewordpress_auth_sessionwordpress_remote_postwordpress_remote_termwordpress_sync_jobwordpress_sync_mapping 远端 WordPress 状态与本地 Blog 内容分离。mapping 表连接远端 ID 和本地 post/term。
Asset/MinIO asset_bucketasset_objectasset_referenceasset_access_grant 统一记录对象归属、来源模块、MIME/type 元数据和临时访问授权,避免 MinIO URL 散落在业务表。
System Event system_noticesystem_eventsystem_event_dedupesystem_event_delivery Loki 仍是日志查询源。MySQL 只保存可处理通知、去重状态和通知投递状态。
Runtime Evidence runtime_evidence_index 只存重要运行证据文件的安全索引,不存完整日志和 secrets。大 JSON 证据仍保留在 .kt-workspace/test-artifacts 或部署产物存储。
QQBot Core qqbot_accountqqbot_connection_sessionqqbot_capability_bindingqqbot_permission_policyqqbot_commandqqbot_command_aliasqqbot_ruleqqbot_conversationqqbot_messageqqbot_send_taskqqbot_send_logqqbot_dedupe_event 拆分账号身份、连接态、权限、路由、会话、消息历史和发送队列/历史。
NapCat Runtime napcat_containernapcat_device_identitynapcat_account_bindingnapcat_login_sessionnapcat_login_challengenapcat_runtime_cleanup 设备身份是一等表,记录 MAC、hostname、machine-id 路径、data dir 和验证状态。登录 challenge 覆盖验证码和新设备验证。清理记录用于阻断假成功。
QQBot Plugin Platform qqbot_pluginqqbot_plugin_versionqqbot_plugin_installationqqbot_plugin_operationqqbot_plugin_event_handlerqqbot_plugin_account_bindingqqbot_plugin_configqqbot_plugin_assetqqbot_plugin_runtime_event 插件 metadata、版本、operation、event、账号绑定、配置、资产和运行事件属于平台不属于某个插件硬编码。
Plugin-Owned Data qqbot_plugin_data_* 或插件命名空间表 插件 migration 可创建命名空间表。表名必须以 plugin key 或已注册 namespace 开头,避免冲突。

破坏式重建策略

实现阶段可按以下流程重建数据库:

  1. 对线上数据库做带时间戳的备份。
  2. 在破坏式 schema 动作期间停止或限制 API 写流量。
  3. 按已批准脚本 drop 或 rename 旧 API 表。
  4. 应用新的全量初始化 SQL。
  5. 初始化必要 Admin 用户、角色、菜单、平台设置、字典、核心 QQBot 插件 metadata 和默认在线命令。
  6. 让 API 使用新 schema 启动。
  7. 运行本地或线上 smokeAdmin 登录、菜单加载、Blog 公开读取、MinIO check、QQBot command registry、plugin registry、NapCat 账号状态、/health/runtime
  8. 关键 smoke 失败时,恢复备份或重新应用旧 schema bundle并回滚到上一个 API 镜像。

QQBot 插件平台

QQBot 插件升级为平台能力,不再是硬编码 Nest service 注册。命令插件、事件插件、 渲染插件、外部查询插件和自动化插件使用同一套 contract。

插件包结构

plugins/<pluginKey>/
  plugin.json
  src/
    index.ts
    operations/
    events/
    config/
    migrations/
    assets/
    tests/

plugin.json 是插件元信息的单一来源:

  • plugin key、名称、描述、版本、作者、license 和主页。
  • 最低 API plugin SDK 版本。
  • 请求的 host 权限。
  • operations 和 event handlers。
  • config schema 和默认值。
  • assets 声明。
  • migrations 声明。
  • runtime 要求,例如 timeout、memory limit 和 worker type。

Worker 隔离运行时

已确认的运行模型是进程隔离:

  • API 主进程负责安装包、校验 manifest、维护 registry、路由 command/event。
  • 插件代码运行在独立 worker 或 child process 中。
  • 插件崩溃只将插件实例标记为 degradedoffline,不拖垮 API 主进程。
  • 启用、禁用、升级、卸载会启动或停止 worker并在运行时刷新 registry。
  • Worker 和 API 通过窄 RPC 协议通信。

RPC 协议至少支持:

  • load:加载 manifest 和编译入口。
  • activate:初始化运行态。
  • deactivate:停止接收新任务。
  • executeOperation:执行命令或查询能力。
  • handleEvent:处理消息或账号事件。
  • health:返回插件健康状态。
  • dispose:关闭前释放资源。

RPC 消息携带 operation ID、correlation ID、timeout budget、脱敏后的输入和结构化输出。 超时由 host 统一控制。

插件 SDK 边界

插件代码不能访问 Nest DI、TypeORM 原始 Repository、后端原始环境变量或任意文件路径。 插件只能拿到受控 SDK

  • 通过 host 发送队列发送 QQBot 消息。
  • 通过插件配置服务读写插件配置。
  • 读写插件自有 storage。
  • 发送插件运行事件。
  • 请求 host 提供的 runtime HTTP 能力,带 timeout 和安全证据。
  • 从插件 asset root 加载已声明静态资源。
  • 读取当前 operation 或 event context。

插件必须在安装前声明权限。Manifest 请求未支持权限,或代码包 hash 与校验记录不一致时, host 必须拒绝安装或启用。

CLI 脚手架

仓库应新增插件作者 CLI

pnpm qqbot-plugin create <pluginKey>
pnpm qqbot-plugin validate <path>
pnpm qqbot-plugin pack <path>
pnpm qqbot-plugin install-local <package>

create 自动生成:

  • plugin.json
  • createPlugin()src/index.ts
  • 一个 operation handler 模板。
  • 一个 event handler 模板。
  • config schema 和默认值。
  • migration/schema 模板。
  • contract tests。
  • package metadata。
  • README/API 片段草稿。

validate 校验 manifest shape、operation key、event key、权限、schema 文件、migrations、 包大小、禁用路径和基础测试是否存在。

pack 输出带版本和 content hash 的插件包。

install-local 使用与线上安装相同的校验链路,将插件包安装到本地开发插件根目录。

线上安装和热插拔状态机

插件安装状态流转:

uploaded -> validated -> installed -> enabled
enabled -> disabled
installed -> uninstalled
enabled -> upgrading -> enabled
enabled -> failed

Admin 上传插件包后API 校验 manifest、包 hash、版本兼容、权限、migration 和 assets。 插件包保存到受控运行时插件目录,不能写入 src/

启用插件时启动 worker注册 operations 和 event handlers并记录运行状态。禁用插件时 停止 worker并从路由中移除 active operation/event不删除数据。卸载插件时停止 worker、 移除 registry、解绑 command/event然后按数据策略处理插件数据默认保留只有管理员 明确选择清理时才删除。

现有插件重写计划

BangDream 作为大型参考插件。现有业务能力拆分可以保留在插件包内:

bangDream/
  operations/
  song/
  card/
  character/
  event/
  gacha/
  player/
  cutoff/
  provider/
  renderer/
  theme/
  assets/

现有 BangDream operation registry 改为由 manifest 支撑 operation metadata。 handlerName 仍作为 worker 内部实现细节。现有图片 smoke 预期继续保留,包括 event stage 拆图输出行为。

FF14 Market 改为外部查询插件,通过 host runtime HTTP SDK 调用 XIVAPI 和 Universalis。

FFLogs 改为外部查询插件,通过 host runtime HTTP SDK 调用 GraphQL/token并通过插件 config 引用客户端凭据。

Repeater 改为事件插件,由 host 管理账号绑定,由插件持有 transient state且必须走 host 发送队列,不能直接绕过限流和发送排队。

模块迁移矩阵

后续实现阶段拆成可审计批次:

批次 范围 结果
0 迁移准备 新 schema map、全量初始化 SQL 计划、破坏式重建脚本计划、备份/恢复命令、验证 SQL、模块模板和 breaking-change 清单。
1 Runtime/Common 保持 runtime foundation 稳定,补齐模块 adapter 需要的 runtime client/evidence 原语,收缩 common 到稳定共享能力。
2 Admin/Auth/Platform Config 重建身份、菜单、权限、字典、组件模板和系统通知模型。Admin 登录和菜单加载必须先通过。
3 Blog/WordPress/Asset 重建 Blog 内容关系、WordPress mirror/sync 和 MinIO asset 归属。Blog 公开读取和 Admin Blog 管理必须通过。
4 QQBot Core 重建账号、连接、权限、命令、规则、会话、消息和发送队列模型。命令匹配和发送队列测试必须通过。
5 QQBot Plugin Platform 新增插件 manifest 校验、数据库 registry、CLI 脚手架、worker runtime、RPC、线上安装、热插拔状态和 Admin/API 管理契约。
6 Existing Plugin Rewrite 将 BangDream、FF14 Market、FFLogs、Repeater 重写为隔离插件包。现有命令 smoke 行为必须继续可用。
7 NapCat Runtime 在新 QQBot/NapCat 模型上实现容器设备持久化、登录 session 状态机、验证码/新设备流程和清理证据。
8 线上闭环 发布后观察 Jenkins/K8s运行 /health/runtime、Admin smoke、Blog smoke、插件安装/启用 smoke、QQBot command smoke 和真实 NapCat 账号登录 smoke。

NapCat 故意排在 QQBot Core 和 Plugin Platform 后面。它依赖新账号模型,并和 command/event 路由共同参与线上验证,但它本身不是插件。

契约和破坏兼容策略

默认保持外部 API 兼容。任何实现任务如果改变 route path、请求字段、响应字段、状态语义、 SSE 事件名、Admin API wrapper 或 SQL seed 标识,都必须在编码前写入 breaking-change 表。

允许的计划内破坏:

  • 数据库表名、字段、索引和初始化 SQL 可以自由改变,因为 schema 从头设计。
  • Admin 页面可能需要在实现阶段同步 API wrapper。
  • 插件管理接口是新增能力,可以使用新的 route shape。

必须保护的行为:

  • Admin 登录和菜单加载。
  • 业务 API 的 Vben 响应 wrapper。
  • /health/runtime plain JSON。
  • Blog public article list/detail。
  • QQBot command test flow。
  • QQBot 账号状态继续区分 OneBot 连接、容器、WebUI 和 QQ 登录态。
  • NapCat 登录安全校验、验证码回交、新设备验证和运行态密码清理失败阻断成功语义。

验证策略

本规划阶段验证:

  • spec 自检:未决标记、内部矛盾和模糊范围。
  • git diff --check
  • KT 文档同步检查。
  • KT global review 扫描变更文件。

后续实现阶段必须包含:

  • domain policy 和状态机的定向单测。
  • 新 SQL 和 TypeORM mapping 的 repository/schema 测试。
  • CLI 生成的插件 contract tests。
  • worker runtime 的 load、activate、execute、health、deactivate 和崩溃隔离测试。
  • 变更接口的真实本地 API 请求。
  • Admin caller 变化时的 Admin UI smoke。
  • 破坏式线上数据库动作前,本地数据库重建 dry run。
  • 线上备份、重建、恢复路径、Jenkins/K8s 观测和功能 smoke。

本规划阶段验收标准

本阶段完成条件:

  1. 设计文档写入 docs/specs/
  2. 设计文档已提交。
  3. 用户 review 已提交文档。
  4. 下一步进入 KT workflow KT plan writing,不是直接实现代码。
  5. 后续完整迁移开始前,重新走 KT requirements and design review。

交接到下一阶段

用户 review 通过后,KT plan writing 阶段应产出计划文档,把本文转换成可执行 work packages、 schema 文档、插件平台任务和验证清单。

后续完整实现必须重新 brainstorming因为它会涉及破坏式 schema 工作、Admin/API 契约决策、 插件运行时安全边界和线上闭环。