docs: 补充API重构中文规划

This commit is contained in:
sunlei 2026-06-14 23:59:05 +08:00
parent 8883c11051
commit f5d656e1f8

View File

@ -1,68 +1,56 @@
# API Full Module Architecture, Schema, and Plugin Platform Design # API 全模块架构、全库表设计与 QQBot 插件平台设计
## Background ## 背景
The API project has grown from a compact NestJS service into a multi-domain `kt-template-online-api` 已经从一个相对紧凑的 NestJS 后端,演进为承接
backend for Admin, Blog, WordPress, MinIO, QQBot, NapCat, Loki-backed runtime Admin、Blog、WordPress、MinIO、QQBot、NapCat、Loki 运行期事件和线上部署
events, and online deployment observation. The first runtime foundation phase 观测的多领域服务。第一期 Runtime Foundation 已经补上 `/health/runtime`
added the shared `/health/runtime` endpoint, typed runtime checks, and evidence 运行时配置检查和证据格式,为后续重构提供了基础观测能力。
patterns needed to observe future refactors safely.
The next phase is not another QQBot-only repair. It is an API-wide architecture 第二期不是继续只修 QQBot 或 NapCat而是进入 API 全模块架构规划。当前线上
planning phase that prepares a full module refactor and a database redesign 数据不重要,因此后续实现阶段允许从头设计数据库表,允许重命名表、删除旧字段、
from scratch. Existing production data is considered unimportant for this 拆分或合并旧表,并重建初始化 SQL。即便允许破坏式重建实现阶段仍必须保留
phase, so the target design may rename tables, drop obsolete columns, split 备份、回滚和线上 smoke避免线上动作不可追踪。
or merge tables, and rebuild initialization SQL. Even with that freedom, the
implementation phase must keep backups, rollback commands, and smoke checks so
online deployment remains auditable.
## Scope Decision ## 范围决策
This document covers the planning-only phase selected by the user: 本阶段是用户确认的 B 阶段:先完成全局规划,不写业务实现代码。
1. Define the API target module architecture. 规划范围:
2. Redesign the database schema from scratch across all API domains.
3. Design a first-class QQBot plugin platform with worker isolation, online
installation, hot-plug enable/disable, and CLI scaffolding.
4. Define the migration matrix and the future implementation order.
This document does not implement code, SQL, Admin UI, or runtime behavior. 1. 定义 API 目标模块架构。
After this planning phase is reviewed, the full migration implementation must 2. 从头设计全库 schema。
start a new Superpowers brainstorming loop before touching code. 3. 设计 QQBot 插件平台,支持 worker/child process 隔离、线上安装、热插拔和
CLI 脚手架。
4. 定义后续 C 阶段的迁移矩阵和实施顺序。
## Goals 本文件不实现代码、SQL、Admin 页面或运行时行为。用户 review 通过后,下一步
进入 Superpowers `writing-plans`。完整 C 阶段迁移开始前,必须重新走一轮
Superpowers brainstorming。
- Make module ownership explicit enough that every controller, use case, ## 目标
entity, repository, external integration, and test has a clear home.
- Replace the current patch-based table history with a clean target schema.
- Keep external API compatibility by default, while listing deliberate breaking
changes before implementation.
- Turn QQBot plugins into a unified platform instead of a set of hard-coded
Nest providers.
- Make plugin creation repeatable through a CLI scaffold.
- Allow online plugin installation, validation, enable/disable, upgrade, and
uninstall without restarting the entire API process.
- Plan existing plugin rewrites for BangDream, FF14 Market, FFLogs, and
Repeater under the same plugin contract.
- Preserve the runtime reliability work from Phase 1 as the foundation for
future module and deployment verification.
## Non-Goals - 明确每个 controller、use case、entity、repository、外部集成和测试的模块归属。
- 用干净的新 schema 替代当前补丁式表历史。
- 默认保持外部 API 兼容,确实需要破坏兼容时提前列入 breaking changes。
- 将 QQBot 插件从硬编码 Nest provider 集合升级为统一插件平台。
- 通过 CLI 脚手架让插件创建、校验、打包和本地安装可重复。
- 支持线上插件安装、校验、启用、禁用、升级和卸载,不重启整个 API 进程。
- 将现有 BangDream、FF14 Market、FFLogs、Repeater 按统一插件契约重写。
- 继承第一期 Runtime Foundation 的可靠性和证据模型,作为后续模块迁移的验证底座。
- Do not write implementation code in this planning phase. ## 非目标
- Do not preserve the old database structure merely for migration convenience.
- Do not treat Jenkins/K8s rollout success as functional success.
- Do not move Admin frontend code in this phase. Admin changes are planned here
and implemented after a separate brainstorming loop.
- Do not bypass QQ or Tencent security checks. NapCat captcha and new-device
verification stay user-driven.
- Do not let installed plugin code access raw backend secrets, raw TypeORM
repositories, or arbitrary Nest dependency injection.
## Target Architecture - 本规划阶段不写实现代码。
- 不为了旧数据迁移方便而保留旧表结构。
- 不把 Jenkins/K8s rollout 成功当作功能成功。
- 本阶段不改 Admin 前端。Admin 联动只在本文规划,后续实现前重新 brainstorming。
- 不绕过 QQ 或腾讯安全校验。NapCat 验证码和新设备验证仍然由用户驱动。
- 不允许线上安装的插件代码直接访问后端真实密钥、TypeORM Repository 或任意 Nest DI。
The target source layout separates platform foundation, shared primitives, and ## 目标架构
business modules:
目标源码结构按平台基础、通用能力和业务模块拆分:
```text ```text
src/ src/
@ -76,26 +64,24 @@ src/
qqbot/ qqbot/
``` ```
`runtime` owns operational primitives: `runtime` 负责运行时基础能力:
- typed runtime config profiles. - 类型化运行时配置 profile。
- HTTP and process clients with timeouts, safe summaries, and classified - 带超时、安全摘要和错误分类的 HTTP/process client。
errors. - 健康检查和 `/health/runtime`
- health probes and `/health/runtime`. - 运行证据记录。
- runtime evidence records. - 清理语义。
- cleanup semantics.
`common` owns stable shared primitives: `common` 只保留稳定通用能力:
- Vben response and error helpers. - Vben 响应和错误工具。
- exception filters and interceptors. - 全局 filter/interceptor。
- date/time decorators and serialization helpers. - 时间字段装饰器和序列化工具。
- Snowflake ID generation. - Snowflake ID
- low-level text and object utilities. - 低层文本、对象工具。
- logging primitives that are not domain-specific. - 非业务专属的日志基础能力。
Business modules own user-facing behavior. Each module follows the same 业务模块内部统一结构:
internal shape:
```text ```text
module/ module/
@ -109,117 +95,91 @@ module/
tests/ tests/
``` ```
### Layer Responsibilities ### 分层职责
`contract` contains controllers, request DTOs, response DTOs, Swagger metadata, `contract`Controller、请求 DTO、响应 DTO、Swagger 元信息和现有路由兼容适配。
and compatibility adapters for existing routes.
`application` contains use cases, transaction boundaries, authorization checks, `application`:用例编排、事务边界、权限检查和状态流转。可以依赖 domain、
and state orchestration. It may depend on domain services, repositories, and repository 和 integration port但不能直接拼外部 HTTP、Docker 脚本或临时 SQL。
integration ports. It must not hand-build external HTTP requests, Docker
scripts, or ad hoc SQL strings.
`domain` contains pure business rules, state machines, policy objects, and `domain`纯业务规则、状态机、策略和值对象。Domain 代码应能脱离 Nest、TypeORM、
value objects. Domain code should be testable without Nest, TypeORM, Docker, Docker、HTTP 和外部凭据做单元测试。
HTTP, or external credentials.
`infrastructure/persistence` contains TypeORM entities, repository `infrastructure/persistence`TypeORM Entity、Repository 实现、查询模型和 schema mapper。
implementations, query models, and schema-specific mappers.
`infrastructure/integration` contains external adapters such as WordPress HTTP, `infrastructure/integration`WordPress HTTP、MinIO SDK、Loki query、OneBot WebSocket、
MinIO SDK, Loki query, OneBot WebSocket, NapCat WebUI, plugin worker RPC, and NapCat WebUI、插件 worker RPC 和 runtime process 适配器。
runtime process calls.
`schema` contains table design notes, initialization SQL ownership, migration `schema`:模块表设计说明、初始化 SQL 归属、重建脚本和验证 SQL。
or rebuild scripts, and validation SQL for the module.
`tests` contains module-level unit, contract, repository, and integration `tests`:模块级 unit、contract、repository 和 integration smoke。跨模块用户流程测试可以
smoke tests. Cross-module smoke tests may stay under the root `test/` folder 继续放在根 `test/` 下。
when they verify a user workflow instead of a single module.
### Compatibility Rules ### 兼容规则
- Existing route paths remain stable unless the implementation plan lists a - 外部 route path 默认保持稳定,除非实现计划明确列入 breaking changes。
breaking change. - Admin-facing 业务接口继续使用当前 Vben success/error wrapperstream、file、WebSocket
- Admin-facing responses keep the current Vben success/error wrapper unless an 和 plain JSON 接口除外。
endpoint is explicitly documented as stream, file, WebSocket, or plain JSON. - `/health/runtime` 继续返回 plain JSON。
- Public runtime health remains plain JSON. - Snowflake ID 在 MySQL 中继续使用 `BIGINT`,在 JavaScript/API 边界按字符串语义处理。
- Snowflake IDs stay `BIGINT` in MySQL and string-like values at JavaScript/API - 时间字段继续使用 `KtDateTime extends Date` 和 KT 时间装饰器。
boundaries. - 后续实现阶段可以替换旧 SQL 文件为全量新库初始化文件,但本规划阶段不改 SQL 实现。
- Runtime time fields use `KtDateTime extends Date` through the existing KT
date-time decorators.
- Existing SQL filenames may be replaced by new full-build files during the
implementation phase, but this planning phase does not modify them.
## Data Architecture Redesign ## 全库表设计
The implementation phase may rebuild the schema from scratch. Because current 后续实现阶段允许从头重建 schema。由于当前数据不重要目标 schema 优先服务清晰
data is not important, the target schema should be optimized for clean domain 数据域和模块所有权,而不是旧表兼容。实现阶段仍必须在破坏式数据库动作前备份,
ownership rather than old compatibility. The implementation phase must still 并提供回滚或恢复命令。
capture a backup before destructive online database work and must provide a
rollback or restore command.
### Global Schema Conventions ### 全局表约定
- Primary keys use Snowflake `BIGINT`. - 主键使用 Snowflake `BIGINT`
- Foreign key columns use `*_id` and are indexed. - 外键列命名为 `*_id` 并建立索引。
- Stable relation tables use composite unique keys. - 稳定关系表使用组合唯一约束。
- High-write log and event tables avoid hard database foreign keys when they - 高频日志和事件表避免硬数据库外键,减少 retention 和清理成本。
would make retention or cleanup difficult. - 只有可恢复、可隐藏的业务配置使用软删。
- Business config tables use soft delete only when restore is valuable. - 运行事件、命令日志、消息日志、插件运行事件使用 append-only 加 retention。
- Append-only runtime events, command logs, message logs, and plugin runtime - 通用时间字段使用 `create_time`、`update_time`,需要软删时加 `delete_time`
events use retention instead of soft delete. - 状态字段使用明确的 varchar 枚举,并在 schema 说明中列出允许值。
- Common timestamps are `create_time`, `update_time`, and optional - JSON 字段只承载外部原始 payload、插件 metadata、低频配置或证据详情可查询字段必须结构化。
`delete_time`. - 有 UI 或存储长度限制的文本字段必须写明截断规则。
- Status columns use explicit string enums documented in schema notes. - 新初始化 SQL 应是干净的全量 schema不再累积历史 `ALTER TABLE` 补丁。
- JSON columns are reserved for raw external payload snapshots, plugin
metadata, low-frequency config, or evidence details. Queryable fields must be
first-class columns.
- Text fields with known UI or storage limits must document the truncation
rule.
- New initialization SQL should be generated as a clean full schema, not as an
accumulated stack of historical `ALTER TABLE` patches.
### Domain Table Plan ### 数据域表规划
| Domain | Target Tables | Notes | | 数据域 | 目标表 | 说明 |
| --- | --- | --- | | --- | --- | --- |
| Admin Identity | `admin_user`, `admin_role`, `admin_permission`, `admin_menu`, `admin_department`, `admin_user_role`, `admin_role_permission`, `admin_role_menu` | Keep Admin route behavior stable while separating route menus from permission atoms. Department is hierarchical. User avatar, timezone, and home path remain user profile fields. | | Admin Identity | `admin_user`、`admin_role`、`admin_permission`、`admin_menu`、`admin_department`、`admin_user_role`、`admin_role_permission`、`admin_role_menu` | 保持 Admin 登录和菜单行为稳定,同时拆清路由菜单与权限原子。部门为树结构。头像、时区和首页路径属于用户 profile。 |
| Platform Config | `platform_dict_group`, `platform_dict_item`, `platform_component_template`, `platform_setting` | Move dictionary and component-template ownership out of miscellaneous Admin services. Dict group/item replace overloaded flat dict rows. | | Platform Config | `platform_dict_group`、`platform_dict_item`、`platform_component_template`、`platform_setting` | 字典和组件模板从 Admin 杂项中抽离。字典用 group/item 替代当前扁平重载行。 |
| Blog Content | `blog_post`, `blog_taxonomy`, `blog_term`, `blog_post_term`, `blog_theme_profile`, `blog_import_job` | Replace comma/text category and tag storage with relation tables. Theme config becomes a named profile. | | Blog Content | `blog_post`、`blog_taxonomy`、`blog_term`、`blog_post_term`、`blog_theme_profile`、`blog_import_job` | 分类、标签使用关系表,不再依赖逗号或长文本字段。主题配置改为可命名 profile。 |
| WordPress Mirror | `wordpress_site`, `wordpress_auth_session`, `wordpress_remote_post`, `wordpress_remote_term`, `wordpress_sync_job`, `wordpress_sync_mapping` | Separate remote WordPress state from local Blog content. Mapping table connects remote IDs to local posts or terms. | | WordPress Mirror | `wordpress_site`、`wordpress_auth_session`、`wordpress_remote_post`、`wordpress_remote_term`、`wordpress_sync_job`、`wordpress_sync_mapping` | 远端 WordPress 状态与本地 Blog 内容分离。mapping 表连接远端 ID 和本地 post/term。 |
| Asset/MinIO | `asset_bucket`, `asset_object`, `asset_reference`, `asset_access_grant` | Track object ownership, source module, MIME/type metadata, and temporary access grants without scattering MinIO URLs across business tables. | | Asset/MinIO | `asset_bucket`、`asset_object`、`asset_reference`、`asset_access_grant` | 统一记录对象归属、来源模块、MIME/type 元数据和临时访问授权,避免 MinIO URL 散落在业务表。 |
| System Event | `system_notice`, `system_event`, `system_event_dedupe`, `system_event_delivery` | Keep Loki as the log query source. Store only actionable notices, dedupe state, and notification delivery state in MySQL. | | System Event | `system_notice`、`system_event`、`system_event_dedupe`、`system_event_delivery` | Loki 仍是日志查询源。MySQL 只保存可处理通知、去重状态和通知投递状态。 |
| Runtime Evidence | `runtime_evidence_index` | Store safe index metadata for important runtime evidence files, not full logs or secrets. Large JSON evidence remains under `.kt-workspace/test-artifacts` or deployment artifact storage. | | Runtime Evidence | `runtime_evidence_index` | 只存重要运行证据文件的安全索引,不存完整日志和 secrets。大 JSON 证据仍保留在 `.kt-workspace/test-artifacts` 或部署产物存储。 |
| QQBot Core | `qqbot_account`, `qqbot_connection_session`, `qqbot_capability_binding`, `qqbot_permission_policy`, `qqbot_command`, `qqbot_command_alias`, `qqbot_rule`, `qqbot_conversation`, `qqbot_message`, `qqbot_send_task`, `qqbot_send_log`, `qqbot_dedupe_event` | Split account identity, connection state, permissions, routing, conversation state, message history, and send queue/history. | | QQBot Core | `qqbot_account`、`qqbot_connection_session`、`qqbot_capability_binding`、`qqbot_permission_policy`、`qqbot_command`、`qqbot_command_alias`、`qqbot_rule`、`qqbot_conversation`、`qqbot_message`、`qqbot_send_task`、`qqbot_send_log`、`qqbot_dedupe_event` | 拆分账号身份、连接态、权限、路由、会话、消息历史和发送队列/历史。 |
| NapCat Runtime | `napcat_container`, `napcat_device_identity`, `napcat_account_binding`, `napcat_login_session`, `napcat_login_challenge`, `napcat_runtime_cleanup` | Device identity is a first-class table for MAC, hostname, machine-id path, data dir, and verification state. Login challenges cover captcha and new-device flows. Cleanup records block false success. | | NapCat Runtime | `napcat_container`、`napcat_device_identity`、`napcat_account_binding`、`napcat_login_session`、`napcat_login_challenge`、`napcat_runtime_cleanup` | 设备身份是一等表,记录 MAC、hostname、machine-id 路径、data dir 和验证状态。登录 challenge 覆盖验证码和新设备验证。清理记录用于阻断假成功。 |
| QQBot Plugin Platform | `qqbot_plugin`, `qqbot_plugin_version`, `qqbot_plugin_installation`, `qqbot_plugin_operation`, `qqbot_plugin_event_handler`, `qqbot_plugin_account_binding`, `qqbot_plugin_config`, `qqbot_plugin_asset`, `qqbot_plugin_runtime_event` | Installed plugin metadata, versions, operations, events, account bindings, config, assets, and runtime events belong to the platform, not to individual plugin code. | | QQBot Plugin Platform | `qqbot_plugin`、`qqbot_plugin_version`、`qqbot_plugin_installation`、`qqbot_plugin_operation`、`qqbot_plugin_event_handler`、`qqbot_plugin_account_binding`、`qqbot_plugin_config`、`qqbot_plugin_asset`、`qqbot_plugin_runtime_event` | 插件 metadata、版本、operation、event、账号绑定、配置、资产和运行事件属于平台不属于某个插件硬编码。 |
| Plugin-Owned Data | `qqbot_plugin_data_*` or module-specific plugin tables | Plugin migrations may create namespaced tables. Names must start with the plugin key or a registered namespace to avoid collisions. | | Plugin-Owned Data | `qqbot_plugin_data_*` 或插件命名空间表 | 插件 migration 可创建命名空间表。表名必须以 plugin key 或已注册 namespace 开头,避免冲突。 |
### Destructive Rebuild Strategy ### 破坏式重建策略
The implementation phase may use this rebuild flow: 实现阶段可按以下流程重建数据库:
1. Capture a timestamped online database backup. 1. 对线上数据库做带时间戳的备份。
2. Stop or gate write traffic for the API during destructive schema work. 2. 在破坏式 schema 动作期间停止或限制 API 写流量。
3. Drop or rename old API tables according to the approved rebuild script. 3. 按已批准脚本 drop 或 rename 旧 API 表。
4. Apply the new full initialization SQL. 4. 应用新的全量初始化 SQL。
5. Seed required Admin user, roles, menus, platform settings, dictionaries, 5. 初始化必要 Admin 用户、角色、菜单、平台设置、字典、核心 QQBot 插件 metadata 和默认在线命令。
core QQBot plugin metadata, and default online commands. 6. 让 API 使用新 schema 启动。
6. Start the API against the new schema. 7. 运行本地或线上 smokeAdmin 登录、菜单加载、Blog 公开读取、MinIO check、QQBot command registry、plugin registry、NapCat 账号状态、`/health/runtime`。
7. Run local or online smoke checks for Admin login, menu loading, Blog public 8. 关键 smoke 失败时,恢复备份或重新应用旧 schema bundle并回滚到上一个 API 镜像。
reads, MinIO check, QQBot command registry, plugin registry, NapCat account
status, and `/health/runtime`.
8. If a critical smoke fails, restore the backup or reapply the previous schema
bundle and redeploy the previous API image.
## QQBot Plugin Platform ## QQBot 插件平台
QQBot plugins become a platform capability instead of hard-coded Nest service QQBot 插件升级为平台能力,不再是硬编码 Nest service 注册。命令插件、事件插件、
registrations. Command plugins, event plugins, renderers, external-query 渲染插件、外部查询插件和自动化插件使用同一套 contract。
plugins, and automation plugins use one contract.
### Plugin Package Structure ### 插件包结构
```text ```text
plugins/<pluginKey>/ plugins/<pluginKey>/
@ -234,65 +194,59 @@ plugins/<pluginKey>/
tests/ tests/
``` ```
`plugin.json` is the source of truth for: `plugin.json` 是插件元信息的单一来源:
- plugin key, name, description, version, author, license, and homepage. - plugin key、名称、描述、版本、作者、license 和主页。
- minimum API plugin SDK version. - 最低 API plugin SDK 版本。
- permissions requested from the host. - 请求的 host 权限。
- operations and event handlers. - operations 和 event handlers。
- config schema and defaults. - config schema 和默认值。
- asset declarations. - assets 声明。
- migration declarations. - migrations 声明。
- runtime requirements such as timeout, memory limit, and worker type. - runtime 要求,例如 timeout、memory limit 和 worker type。
### Worker-Isolated Runtime ### Worker 隔离运行时
The approved runtime model is process isolation: 已确认的运行模型是进程隔离:
- API main process installs packages, validates manifests, owns the registry, - API 主进程负责安装包、校验 manifest、维护 registry、路由 command/event。
and routes commands/events. - 插件代码运行在独立 worker 或 child process 中。
- Plugin code runs in a dedicated worker or child process. - 插件崩溃只将插件实例标记为 `degraded``offline`,不拖垮 API 主进程。
- A plugin crash marks the plugin instance `degraded` or `offline` without - 启用、禁用、升级、卸载会启动或停止 worker并在运行时刷新 registry。
crashing the API process. - Worker 和 API 通过窄 RPC 协议通信。
- Enable, disable, upgrade, and uninstall operations start or stop workers and
refresh the registry at runtime.
- Workers communicate with the API through a narrow RPC protocol.
The RPC protocol must support these commands: RPC 协议至少支持:
- `load`: load manifest and compiled entry. - `load`:加载 manifest 和编译入口。
- `activate`: initialize runtime state. - `activate`:初始化运行态。
- `deactivate`: stop accepting work. - `deactivate`:停止接收新任务。
- `executeOperation`: execute a command or query operation. - `executeOperation`:执行命令或查询能力。
- `handleEvent`: handle message or account events. - `handleEvent`:处理消息或账号事件。
- `health`: return plugin health. - `health`:返回插件健康状态。
- `dispose`: release resources before shutdown. - `dispose`:关闭前释放资源。
RPC messages carry operation IDs, correlation IDs, timeout budgets, sanitized RPC 消息携带 operation ID、correlation ID、timeout budget、脱敏后的输入和结构化输出。
input, and structured output. The host owns timeout enforcement. 超时由 host 统一控制。
### Plugin SDK Boundary ### 插件 SDK 边界
Plugin code cannot access Nest dependency injection, raw TypeORM repositories, 插件代码不能访问 Nest DI、TypeORM 原始 Repository、后端原始环境变量或任意文件路径。
raw backend environment variables, or arbitrary filesystem paths. It receives a 插件只能拿到受控 SDK
controlled SDK with explicit capabilities:
- send QQBot messages through the host send queue. - 通过 host 发送队列发送 QQBot 消息。
- read and write plugin config through the plugin config service. - 通过插件配置服务读写插件配置。
- read and write plugin-owned storage. - 读写插件自有 storage。
- emit plugin runtime events. - 发送插件运行事件。
- request host-provided runtime HTTP calls with configured timeout and safe - 请求 host 提供的 runtime HTTP 能力,带 timeout 和安全证据。
evidence. - 从插件 asset root 加载已声明静态资源。
- load declared static assets from the plugin asset root. - 读取当前 operation 或 event context。
- inspect the current operation or event context.
Plugins must declare permissions before installation. The host rejects packages 插件必须在安装前声明权限。Manifest 请求未支持权限,或代码包 hash 与校验记录不一致时,
whose manifest requests unsupported permissions or whose code package does not host 必须拒绝安装或启用。
match the validated hash.
### CLI Scaffold ### CLI 脚手架
The repository should add a CLI for plugin authors: 仓库应新增插件作者 CLI
```bash ```bash
pnpm qqbot-plugin create <pluginKey> pnpm qqbot-plugin create <pluginKey>
@ -301,30 +255,28 @@ pnpm qqbot-plugin pack <path>
pnpm qqbot-plugin install-local <package> pnpm qqbot-plugin install-local <package>
``` ```
`create` generates: `create` 自动生成:
- `plugin.json`. - `plugin.json`
- `src/index.ts` with `createPlugin()`. - `createPlugin()``src/index.ts`
- one operation handler template. - 一个 operation handler 模板。
- one event handler template. - 一个 event handler 模板。
- config schema and defaults. - config schema 和默认值。
- migration/schema template. - migration/schema 模板。
- contract tests. - contract tests
- package metadata. - package metadata
- README/API draft fragments. - README/API 片段草稿。
`validate` checks manifest shape, operation keys, event keys, permissions, `validate` 校验 manifest shape、operation key、event key、权限、schema 文件、migrations、
schema files, migrations, package size, disallowed paths, and basic test 包大小、禁用路径和基础测试是否存在。
presence.
`pack` produces a versioned plugin package with a content hash. `pack` 输出带版本和 content hash 的插件包。
`install-local` installs a package into the local development plugin root using `install-local` 使用与线上安装相同的校验链路,将插件包安装到本地开发插件根目录。
the same validation path as online installation.
### Online Installation and Hot-Plug State Machine ### 线上安装和热插拔状态机
Plugin installation state moves through: 插件安装状态流转:
```text ```text
uploaded -> validated -> installed -> enabled uploaded -> validated -> installed -> enabled
@ -334,21 +286,17 @@ enabled -> upgrading -> enabled
enabled -> failed enabled -> failed
``` ```
Admin uploads a plugin package. The API validates manifest, package hash, Admin 上传插件包后API 校验 manifest、包 hash、版本兼容、权限、migration 和 assets。
version compatibility, permissions, migrations, and declared assets. The package 插件包保存到受控运行时插件目录,不能写入 `src/`
is stored under a controlled runtime plugin directory, never under `src/`.
Enabling a plugin starts its worker, registers operations and event handlers, 启用插件时启动 worker注册 operations 和 event handlers并记录运行状态。禁用插件时
and records the runtime status. Disabling a plugin stops the worker and removes 停止 worker并从路由中移除 active operation/event不删除数据。卸载插件时停止 worker、
its active operations/events from routing without deleting data. Uninstalling a 移除 registry、解绑 command/event然后按数据策略处理插件数据默认保留只有管理员
plugin stops workers, removes registry entries, unbinds commands/events, and 明确选择清理时才删除。
then follows the selected data policy: preserve plugin data by default, delete
only when the admin explicitly chooses cleanup.
### Existing Plugin Rewrite Plan ### 现有插件重写计划
BangDream becomes the large reference plugin. Its current business capability BangDream 作为大型参考插件。现有业务能力拆分可以保留在插件包内:
split can stay inside the plugin package:
```text ```text
bangDream/ bangDream/
@ -366,108 +314,92 @@ bangDream/
assets/ assets/
``` ```
The existing BangDream operation registry becomes manifest-backed operation 现有 BangDream operation registry 改为由 manifest 支撑 operation metadata。
metadata. Handler names remain implementation details inside the plugin worker. handlerName 仍作为 worker 内部实现细节。现有图片 smoke 预期继续保留,包括
The current image rendering smoke expectations, including event stage split event stage 拆图输出行为。
output behavior, remain acceptance tests.
FF14 Market becomes an external-query plugin using the host runtime HTTP SDK FF14 Market 改为外部查询插件,通过 host runtime HTTP SDK 调用 XIVAPI 和 Universalis。
for XIVAPI and Universalis calls.
FFLogs becomes an external-query plugin using the host runtime HTTP SDK for FFLogs 改为外部查询插件,通过 host runtime HTTP SDK 调用 GraphQL/token并通过插件
GraphQL/token calls and plugin config for client credentials references. config 引用客户端凭据。
Repeater becomes an event plugin with host-managed account binding and Repeater 改为事件插件,由 host 管理账号绑定,由插件持有 transient state且必须走 host
plugin-owned transient state. It must not bypass the host send queue. 发送队列,不能直接绕过限流和发送排队。
## Module Migration Matrix ## 模块迁移矩阵
The future implementation phase should be split into auditable batches: 后续实现阶段拆成可审计批次:
| Batch | Scope | Outcome | | 批次 | 范围 | 结果 |
| --- | --- | --- | | --- | --- | --- |
| 0 | Migration preparation | New schema map, full initialization SQL plan, destructive rebuild script plan, backup/restore commands, validation SQL, module template, and breaking-change list. | | 0 | 迁移准备 | 新 schema map、全量初始化 SQL 计划、破坏式重建脚本计划、备份/恢复命令、验证 SQL、模块模板和 breaking-change 清单。 |
| 1 | Runtime/Common | Keep runtime foundation stable, add missing runtime client/evidence primitives needed by module adapters, and shrink common to stable shared primitives. | | 1 | Runtime/Common | 保持 runtime foundation 稳定,补齐模块 adapter 需要的 runtime client/evidence 原语,收缩 common 到稳定共享能力。 |
| 2 | Admin/Auth/Platform Config | Rebuild identity, menu, permission, dictionary, component template, and system notice models. Admin login and menu loading must pass first. | | 2 | Admin/Auth/Platform Config | 重建身份、菜单、权限、字典、组件模板和系统通知模型。Admin 登录和菜单加载必须先通过。 |
| 3 | Blog/WordPress/Asset | Rebuild Blog content relations, WordPress mirror/sync, and MinIO asset ownership. Public Blog reads and Admin Blog management must pass. | | 3 | Blog/WordPress/Asset | 重建 Blog 内容关系、WordPress mirror/sync 和 MinIO asset 归属。Blog 公开读取和 Admin Blog 管理必须通过。 |
| 4 | QQBot Core | Rebuild account, connection, permission, command, rule, conversation, message, and send queue models. Command matching and send queue tests must pass. | | 4 | QQBot Core | 重建账号、连接、权限、命令、规则、会话、消息和发送队列模型。命令匹配和发送队列测试必须通过。 |
| 5 | QQBot Plugin Platform | Add plugin manifest validation, database registry, CLI scaffold, worker runtime, RPC, online install, hot-plug state, and Admin/API management contracts. | | 5 | QQBot Plugin Platform | 新增插件 manifest 校验、数据库 registry、CLI 脚手架、worker runtime、RPC、线上安装、热插拔状态和 Admin/API 管理契约。 |
| 6 | Existing Plugin Rewrite | Rewrite BangDream, FF14 Market, FFLogs, and Repeater as isolated plugin packages. Existing command smoke behavior must remain available. | | 6 | Existing Plugin Rewrite | 将 BangDream、FF14 Market、FFLogs、Repeater 重写为隔离插件包。现有命令 smoke 行为必须继续可用。 |
| 7 | NapCat Runtime | Implement container device persistence, login session state machine, captcha/new-device flow, and cleanup evidence on the new QQBot/NapCat model. | | 7 | NapCat Runtime | 在新 QQBot/NapCat 模型上实现容器设备持久化、登录 session 状态机、验证码/新设备流程和清理证据。 |
| 8 | Online Closure | Deploy, observe Jenkins/K8s, run `/health/runtime`, Admin smoke, Blog smoke, plugin install/enable smoke, QQBot command smoke, and real NapCat account login smoke. | | 8 | 线上闭环 | 发布后观察 Jenkins/K8s运行 `/health/runtime`、Admin smoke、Blog smoke、插件安装/启用 smoke、QQBot command smoke 和真实 NapCat 账号登录 smoke。 |
NapCat is intentionally after QQBot Core and Plugin Platform. It depends on the NapCat 故意排在 QQBot Core 和 Plugin Platform 后面。它依赖新账号模型,并和 command/event
new account model and shares runtime verification with command/event routing, 路由共同参与线上验证,但它本身不是插件。
but it is not itself a plugin.
## Contract and Breaking-Change Policy ## 契约和破坏兼容策略
External API compatibility is the default. Any implementation task that changes 默认保持外部 API 兼容。任何实现任务如果改变 route path、请求字段、响应字段、状态语义、
route paths, request fields, response fields, status semantics, SSE event names, SSE 事件名、Admin API wrapper 或 SQL seed 标识,都必须在编码前写入 breaking-change 表。
Admin API wrappers, or SQL seed identifiers must add the change to a
breaking-change table before coding.
Allowed planned breakages: 允许的计划内破坏:
- Database table names, columns, indexes, and initialization SQL may change - 数据库表名、字段、索引和初始化 SQL 可以自由改变,因为 schema 从头设计。
freely because the schema is redesigned from scratch. - Admin 页面可能需要在实现阶段同步 API wrapper。
- Admin pages may need API-wrapper updates during the implementation phase. - 插件管理接口是新增能力,可以使用新的 route shape。
- Plugin management endpoints are new and can use new route shapes.
Protected behavior: 必须保护的行为:
- Admin login and menu loading. - Admin 登录和菜单加载。
- Vben response wrapper for business APIs. - 业务 API 的 Vben 响应 wrapper。
- `/health/runtime` plain JSON. - `/health/runtime` plain JSON。
- Blog public article list/detail behavior. - Blog public article list/detail。
- QQBot command test flow. - QQBot command test flow。
- QQBot account status distinction between OneBot connection, container, - QQBot 账号状态继续区分 OneBot 连接、容器、WebUI 和 QQ 登录态。
WebUI, and QQ login state. - NapCat 登录安全校验、验证码回交、新设备验证和运行态密码清理失败阻断成功语义。
- NapCat login safety checks, captcha handoff, new-device verification, and
runtime password cleanup blocking semantics.
## Verification Strategy ## 验证策略
Planning-only verification for this spec: 本规划阶段验证:
- spec self-review for missing markers, contradictions, and ambiguous scope. - spec 自检:未决标记、内部矛盾和模糊范围。
- `git diff --check`. - `git diff --check`
- KT documentation sync check. - KT 文档同步检查。
- KT global review on changed files. - KT global review 扫描变更文件。
Future implementation verification must include: 后续实现阶段必须包含:
- targeted unit tests for domain policies and state machines. - domain policy 和状态机的定向单测。
- repository/schema tests for new SQL and TypeORM mappings. - 新 SQL 和 TypeORM mapping 的 repository/schema 测试。
- plugin contract tests generated by the CLI scaffold. - CLI 生成的插件 contract tests。
- worker runtime tests for load, activate, execute, health, deactivate, and - worker runtime 的 load、activate、execute、health、deactivate 和崩溃隔离测试。
crash isolation. - 变更接口的真实本地 API 请求。
- local API requests for changed endpoints. - Admin caller 变化时的 Admin UI smoke。
- Admin UI smoke when Admin callers change. - 破坏式线上数据库动作前,本地数据库重建 dry run。
- database rebuild dry run against a local database before online destructive - 线上备份、重建、恢复路径、Jenkins/K8s 观测和功能 smoke。
work.
- online backup, rebuild, restore path, Jenkins/K8s observation, and functional
smoke after deploy.
## Acceptance Criteria for This Planning Phase ## 本规划阶段验收标准
This planning phase is complete when: 本阶段完成条件:
1. The design document is written under `docs/superpowers/specs/`. 1. 设计文档写入 `docs/superpowers/specs/`
2. The design document is committed. 2. 设计文档已提交。
3. The user reviews the committed document. 3. 用户 review 已提交文档。
4. The next step is a Superpowers writing-plans phase for the planning output, 4. 下一步进入 Superpowers `writing-plans`,不是直接实现代码。
not code implementation. 5. 后续完整迁移开始前,重新走 Superpowers brainstorming。
5. The subsequent full migration starts a fresh Superpowers brainstorming loop
before implementation begins.
## Handoff to the Next Phase ## 交接到下一阶段
After user review, the writing-plans phase should produce a plan document for 用户 review 通过后,`writing-plans` 阶段应产出计划文档,把本文转换成可执行 work packages、
the planning deliverable. That plan should describe how to turn this design into schema 文档、插件平台任务和验证清单。
implementation-ready work packages, schema documents, plugin platform tasks,
and validation checklists.
The subsequent full implementation must start from a new brainstorming loop 后续完整实现必须重新 brainstorming因为它会涉及破坏式 schema 工作、Admin/API 契约决策、
because it will involve destructive schema work, Admin/API contract decisions, 插件运行时安全边界和线上闭环。
runtime plugin security boundaries, and online closure.