docs: 补充API重构中文规划
This commit is contained in:
parent
8883c11051
commit
f5d656e1f8
@ -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
|
||||
backend for Admin, Blog, WordPress, MinIO, QQBot, NapCat, Loki-backed runtime
|
||||
events, and online deployment observation. The first runtime foundation phase
|
||||
added the shared `/health/runtime` endpoint, typed runtime checks, and evidence
|
||||
patterns needed to observe future refactors safely.
|
||||
`kt-template-online-api` 已经从一个相对紧凑的 NestJS 后端,演进为承接
|
||||
Admin、Blog、WordPress、MinIO、QQBot、NapCat、Loki 运行期事件和线上部署
|
||||
观测的多领域服务。第一期 Runtime Foundation 已经补上 `/health/runtime`、
|
||||
运行时配置检查和证据格式,为后续重构提供了基础观测能力。
|
||||
|
||||
The next phase is not another QQBot-only repair. It is an API-wide architecture
|
||||
planning phase that prepares a full module refactor and a database redesign
|
||||
from scratch. Existing production data is considered unimportant for this
|
||||
phase, so the target design may rename tables, drop obsolete columns, split
|
||||
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.
|
||||
第二期不是继续只修 QQBot 或 NapCat,而是进入 API 全模块架构规划。当前线上
|
||||
数据不重要,因此后续实现阶段允许从头设计数据库表,允许重命名表、删除旧字段、
|
||||
拆分或合并旧表,并重建初始化 SQL。即便允许破坏式重建,实现阶段仍必须保留
|
||||
备份、回滚和线上 smoke,避免线上动作不可追踪。
|
||||
|
||||
## 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.
|
||||
After this planning phase is reviewed, the full migration implementation must
|
||||
start a new Superpowers brainstorming loop before touching code.
|
||||
1. 定义 API 目标模块架构。
|
||||
2. 从头设计全库 schema。
|
||||
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
|
||||
src/
|
||||
@ -76,26 +64,24 @@ src/
|
||||
qqbot/
|
||||
```
|
||||
|
||||
`runtime` owns operational primitives:
|
||||
`runtime` 负责运行时基础能力:
|
||||
|
||||
- typed runtime config profiles.
|
||||
- HTTP and process clients with timeouts, safe summaries, and classified
|
||||
errors.
|
||||
- health probes and `/health/runtime`.
|
||||
- runtime evidence records.
|
||||
- cleanup semantics.
|
||||
- 类型化运行时配置 profile。
|
||||
- 带超时、安全摘要和错误分类的 HTTP/process client。
|
||||
- 健康检查和 `/health/runtime`。
|
||||
- 运行证据记录。
|
||||
- 清理语义。
|
||||
|
||||
`common` owns stable shared primitives:
|
||||
`common` 只保留稳定通用能力:
|
||||
|
||||
- Vben response and error helpers.
|
||||
- exception filters and interceptors.
|
||||
- date/time decorators and serialization helpers.
|
||||
- Snowflake ID generation.
|
||||
- low-level text and object utilities.
|
||||
- logging primitives that are not domain-specific.
|
||||
- Vben 响应和错误工具。
|
||||
- 全局 filter/interceptor。
|
||||
- 时间字段装饰器和序列化工具。
|
||||
- Snowflake ID。
|
||||
- 低层文本、对象工具。
|
||||
- 非业务专属的日志基础能力。
|
||||
|
||||
Business modules own user-facing behavior. Each module follows the same
|
||||
internal shape:
|
||||
业务模块内部统一结构:
|
||||
|
||||
```text
|
||||
module/
|
||||
@ -109,117 +95,91 @@ module/
|
||||
tests/
|
||||
```
|
||||
|
||||
### Layer Responsibilities
|
||||
### 分层职责
|
||||
|
||||
`contract` contains controllers, request DTOs, response DTOs, Swagger metadata,
|
||||
and compatibility adapters for existing routes.
|
||||
`contract`:Controller、请求 DTO、响应 DTO、Swagger 元信息和现有路由兼容适配。
|
||||
|
||||
`application` contains use cases, transaction boundaries, authorization checks,
|
||||
and state orchestration. It may depend on domain services, repositories, and
|
||||
integration ports. It must not hand-build external HTTP requests, Docker
|
||||
scripts, or ad hoc SQL strings.
|
||||
`application`:用例编排、事务边界、权限检查和状态流转。可以依赖 domain、
|
||||
repository 和 integration port,但不能直接拼外部 HTTP、Docker 脚本或临时 SQL。
|
||||
|
||||
`domain` contains pure business rules, state machines, policy objects, and
|
||||
value objects. Domain code should be testable without Nest, TypeORM, Docker,
|
||||
HTTP, or external credentials.
|
||||
`domain`:纯业务规则、状态机、策略和值对象。Domain 代码应能脱离 Nest、TypeORM、
|
||||
Docker、HTTP 和外部凭据做单元测试。
|
||||
|
||||
`infrastructure/persistence` contains TypeORM entities, repository
|
||||
implementations, query models, and schema-specific mappers.
|
||||
`infrastructure/persistence`:TypeORM Entity、Repository 实现、查询模型和 schema mapper。
|
||||
|
||||
`infrastructure/integration` contains external adapters such as WordPress HTTP,
|
||||
MinIO SDK, Loki query, OneBot WebSocket, NapCat WebUI, plugin worker RPC, and
|
||||
runtime process calls.
|
||||
`infrastructure/integration`:WordPress HTTP、MinIO SDK、Loki query、OneBot WebSocket、
|
||||
NapCat WebUI、插件 worker RPC 和 runtime process 适配器。
|
||||
|
||||
`schema` contains table design notes, initialization SQL ownership, migration
|
||||
or rebuild scripts, and validation SQL for the module.
|
||||
`schema`:模块表设计说明、初始化 SQL 归属、重建脚本和验证 SQL。
|
||||
|
||||
`tests` contains module-level unit, contract, repository, and integration
|
||||
smoke tests. Cross-module smoke tests may stay under the root `test/` folder
|
||||
when they verify a user workflow instead of a single module.
|
||||
`tests`:模块级 unit、contract、repository 和 integration smoke。跨模块用户流程测试可以
|
||||
继续放在根 `test/` 下。
|
||||
|
||||
### Compatibility Rules
|
||||
### 兼容规则
|
||||
|
||||
- Existing route paths remain stable unless the implementation plan lists a
|
||||
breaking change.
|
||||
- Admin-facing responses keep the current Vben success/error wrapper unless an
|
||||
endpoint is explicitly documented as stream, file, WebSocket, or plain JSON.
|
||||
- Public runtime health remains plain JSON.
|
||||
- Snowflake IDs stay `BIGINT` in MySQL and string-like values at JavaScript/API
|
||||
boundaries.
|
||||
- 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.
|
||||
- 外部 route path 默认保持稳定,除非实现计划明确列入 breaking changes。
|
||||
- Admin-facing 业务接口继续使用当前 Vben success/error wrapper,stream、file、WebSocket
|
||||
和 plain JSON 接口除外。
|
||||
- `/health/runtime` 继续返回 plain JSON。
|
||||
- Snowflake ID 在 MySQL 中继续使用 `BIGINT`,在 JavaScript/API 边界按字符串语义处理。
|
||||
- 时间字段继续使用 `KtDateTime extends Date` 和 KT 时间装饰器。
|
||||
- 后续实现阶段可以替换旧 SQL 文件为全量新库初始化文件,但本规划阶段不改 SQL 实现。
|
||||
|
||||
## Data Architecture Redesign
|
||||
## 全库表设计
|
||||
|
||||
The implementation phase may rebuild the schema from scratch. Because current
|
||||
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.
|
||||
后续实现阶段允许从头重建 schema。由于当前数据不重要,目标 schema 优先服务清晰
|
||||
数据域和模块所有权,而不是旧表兼容。实现阶段仍必须在破坏式数据库动作前备份,
|
||||
并提供回滚或恢复命令。
|
||||
|
||||
### Global Schema Conventions
|
||||
### 全局表约定
|
||||
|
||||
- Primary keys use Snowflake `BIGINT`.
|
||||
- Foreign key columns use `*_id` and are indexed.
|
||||
- Stable relation tables use composite unique keys.
|
||||
- High-write log and event tables avoid hard database foreign keys when they
|
||||
would make retention or cleanup difficult.
|
||||
- Business config tables use soft delete only when restore is valuable.
|
||||
- Append-only runtime events, command logs, message logs, and plugin runtime
|
||||
events use retention instead of soft delete.
|
||||
- Common timestamps are `create_time`, `update_time`, and optional
|
||||
`delete_time`.
|
||||
- Status columns use explicit string enums documented in schema notes.
|
||||
- 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.
|
||||
- 主键使用 Snowflake `BIGINT`。
|
||||
- 外键列命名为 `*_id` 并建立索引。
|
||||
- 稳定关系表使用组合唯一约束。
|
||||
- 高频日志和事件表避免硬数据库外键,减少 retention 和清理成本。
|
||||
- 只有可恢复、可隐藏的业务配置使用软删。
|
||||
- 运行事件、命令日志、消息日志、插件运行事件使用 append-only 加 retention。
|
||||
- 通用时间字段使用 `create_time`、`update_time`,需要软删时加 `delete_time`。
|
||||
- 状态字段使用明确的 varchar 枚举,并在 schema 说明中列出允许值。
|
||||
- JSON 字段只承载外部原始 payload、插件 metadata、低频配置或证据详情;可查询字段必须结构化。
|
||||
- 有 UI 或存储长度限制的文本字段必须写明截断规则。
|
||||
- 新初始化 SQL 应是干净的全量 schema,不再累积历史 `ALTER TABLE` 补丁。
|
||||
|
||||
### 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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` | 字典和组件模板从 Admin 杂项中抽离。字典用 group/item 替代当前扁平重载行。 |
|
||||
| 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` | 远端 WordPress 状态与本地 Blog 内容分离。mapping 表连接远端 ID 和本地 post/term。 |
|
||||
| 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` | Loki 仍是日志查询源。MySQL 只保存可处理通知、去重状态和通知投递状态。 |
|
||||
| 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` | 拆分账号身份、连接态、权限、路由、会话、消息历史和发送队列/历史。 |
|
||||
| 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` | 插件 metadata、版本、operation、event、账号绑定、配置、资产和运行事件属于平台,不属于某个插件硬编码。 |
|
||||
| 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.
|
||||
2. Stop or gate write traffic for the API during destructive schema work.
|
||||
3. Drop or rename old API tables according to the approved rebuild script.
|
||||
4. Apply the new full initialization SQL.
|
||||
5. Seed required Admin user, roles, menus, platform settings, dictionaries,
|
||||
core QQBot plugin metadata, and default online commands.
|
||||
6. Start the API against the new schema.
|
||||
7. Run local or online smoke checks for Admin login, menu loading, Blog public
|
||||
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.
|
||||
1. 对线上数据库做带时间戳的备份。
|
||||
2. 在破坏式 schema 动作期间停止或限制 API 写流量。
|
||||
3. 按已批准脚本 drop 或 rename 旧 API 表。
|
||||
4. 应用新的全量初始化 SQL。
|
||||
5. 初始化必要 Admin 用户、角色、菜单、平台设置、字典、核心 QQBot 插件 metadata 和默认在线命令。
|
||||
6. 让 API 使用新 schema 启动。
|
||||
7. 运行本地或线上 smoke:Admin 登录、菜单加载、Blog 公开读取、MinIO check、QQBot command registry、plugin registry、NapCat 账号状态、`/health/runtime`。
|
||||
8. 关键 smoke 失败时,恢复备份或重新应用旧 schema bundle,并回滚到上一个 API 镜像。
|
||||
|
||||
## QQBot Plugin Platform
|
||||
## QQBot 插件平台
|
||||
|
||||
QQBot plugins become a platform capability instead of hard-coded Nest service
|
||||
registrations. Command plugins, event plugins, renderers, external-query
|
||||
plugins, and automation plugins use one contract.
|
||||
QQBot 插件升级为平台能力,不再是硬编码 Nest service 注册。命令插件、事件插件、
|
||||
渲染插件、外部查询插件和自动化插件使用同一套 contract。
|
||||
|
||||
### Plugin Package Structure
|
||||
### 插件包结构
|
||||
|
||||
```text
|
||||
plugins/<pluginKey>/
|
||||
@ -234,65 +194,59 @@ plugins/<pluginKey>/
|
||||
tests/
|
||||
```
|
||||
|
||||
`plugin.json` is the source of truth for:
|
||||
`plugin.json` 是插件元信息的单一来源:
|
||||
|
||||
- plugin key, name, description, version, author, license, and homepage.
|
||||
- minimum API plugin SDK version.
|
||||
- permissions requested from the host.
|
||||
- operations and event handlers.
|
||||
- config schema and defaults.
|
||||
- asset declarations.
|
||||
- migration declarations.
|
||||
- runtime requirements such as timeout, memory limit, and worker type.
|
||||
- plugin key、名称、描述、版本、作者、license 和主页。
|
||||
- 最低 API plugin SDK 版本。
|
||||
- 请求的 host 权限。
|
||||
- operations 和 event handlers。
|
||||
- config schema 和默认值。
|
||||
- assets 声明。
|
||||
- migrations 声明。
|
||||
- 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,
|
||||
and routes commands/events.
|
||||
- Plugin code runs in a dedicated worker or child process.
|
||||
- A plugin crash marks the plugin instance `degraded` or `offline` without
|
||||
crashing the API process.
|
||||
- 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.
|
||||
- API 主进程负责安装包、校验 manifest、维护 registry、路由 command/event。
|
||||
- 插件代码运行在独立 worker 或 child process 中。
|
||||
- 插件崩溃只将插件实例标记为 `degraded` 或 `offline`,不拖垮 API 主进程。
|
||||
- 启用、禁用、升级、卸载会启动或停止 worker,并在运行时刷新 registry。
|
||||
- Worker 和 API 通过窄 RPC 协议通信。
|
||||
|
||||
The RPC protocol must support these commands:
|
||||
RPC 协议至少支持:
|
||||
|
||||
- `load`: load manifest and compiled entry.
|
||||
- `activate`: initialize runtime state.
|
||||
- `deactivate`: stop accepting work.
|
||||
- `executeOperation`: execute a command or query operation.
|
||||
- `handleEvent`: handle message or account events.
|
||||
- `health`: return plugin health.
|
||||
- `dispose`: release resources before shutdown.
|
||||
- `load`:加载 manifest 和编译入口。
|
||||
- `activate`:初始化运行态。
|
||||
- `deactivate`:停止接收新任务。
|
||||
- `executeOperation`:执行命令或查询能力。
|
||||
- `handleEvent`:处理消息或账号事件。
|
||||
- `health`:返回插件健康状态。
|
||||
- `dispose`:关闭前释放资源。
|
||||
|
||||
RPC messages carry operation IDs, correlation IDs, timeout budgets, sanitized
|
||||
input, and structured output. The host owns timeout enforcement.
|
||||
RPC 消息携带 operation ID、correlation ID、timeout budget、脱敏后的输入和结构化输出。
|
||||
超时由 host 统一控制。
|
||||
|
||||
### Plugin SDK Boundary
|
||||
### 插件 SDK 边界
|
||||
|
||||
Plugin code cannot access Nest dependency injection, raw TypeORM repositories,
|
||||
raw backend environment variables, or arbitrary filesystem paths. It receives a
|
||||
controlled SDK with explicit capabilities:
|
||||
插件代码不能访问 Nest DI、TypeORM 原始 Repository、后端原始环境变量或任意文件路径。
|
||||
插件只能拿到受控 SDK:
|
||||
|
||||
- send QQBot messages through the host send queue.
|
||||
- read and write plugin config through the plugin config service.
|
||||
- read and write plugin-owned storage.
|
||||
- emit plugin runtime events.
|
||||
- request host-provided runtime HTTP calls with configured timeout and safe
|
||||
evidence.
|
||||
- load declared static assets from the plugin asset root.
|
||||
- inspect the current operation or event context.
|
||||
- 通过 host 发送队列发送 QQBot 消息。
|
||||
- 通过插件配置服务读写插件配置。
|
||||
- 读写插件自有 storage。
|
||||
- 发送插件运行事件。
|
||||
- 请求 host 提供的 runtime HTTP 能力,带 timeout 和安全证据。
|
||||
- 从插件 asset root 加载已声明静态资源。
|
||||
- 读取当前 operation 或 event context。
|
||||
|
||||
Plugins must declare permissions before installation. The host rejects packages
|
||||
whose manifest requests unsupported permissions or whose code package does not
|
||||
match the validated hash.
|
||||
插件必须在安装前声明权限。Manifest 请求未支持权限,或代码包 hash 与校验记录不一致时,
|
||||
host 必须拒绝安装或启用。
|
||||
|
||||
### CLI Scaffold
|
||||
### CLI 脚手架
|
||||
|
||||
The repository should add a CLI for plugin authors:
|
||||
仓库应新增插件作者 CLI:
|
||||
|
||||
```bash
|
||||
pnpm qqbot-plugin create <pluginKey>
|
||||
@ -301,30 +255,28 @@ pnpm qqbot-plugin pack <path>
|
||||
pnpm qqbot-plugin install-local <package>
|
||||
```
|
||||
|
||||
`create` generates:
|
||||
`create` 自动生成:
|
||||
|
||||
- `plugin.json`.
|
||||
- `src/index.ts` with `createPlugin()`.
|
||||
- one operation handler template.
|
||||
- one event handler template.
|
||||
- config schema and defaults.
|
||||
- migration/schema template.
|
||||
- contract tests.
|
||||
- package metadata.
|
||||
- README/API draft fragments.
|
||||
- `plugin.json`。
|
||||
- 带 `createPlugin()` 的 `src/index.ts`。
|
||||
- 一个 operation handler 模板。
|
||||
- 一个 event handler 模板。
|
||||
- config schema 和默认值。
|
||||
- migration/schema 模板。
|
||||
- contract tests。
|
||||
- package metadata。
|
||||
- README/API 片段草稿。
|
||||
|
||||
`validate` checks manifest shape, operation keys, event keys, permissions,
|
||||
schema files, migrations, package size, disallowed paths, and basic test
|
||||
presence.
|
||||
`validate` 校验 manifest shape、operation key、event key、权限、schema 文件、migrations、
|
||||
包大小、禁用路径和基础测试是否存在。
|
||||
|
||||
`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
|
||||
the same validation path as online installation.
|
||||
`install-local` 使用与线上安装相同的校验链路,将插件包安装到本地开发插件根目录。
|
||||
|
||||
### Online Installation and Hot-Plug State Machine
|
||||
### 线上安装和热插拔状态机
|
||||
|
||||
Plugin installation state moves through:
|
||||
插件安装状态流转:
|
||||
|
||||
```text
|
||||
uploaded -> validated -> installed -> enabled
|
||||
@ -334,21 +286,17 @@ enabled -> upgrading -> enabled
|
||||
enabled -> failed
|
||||
```
|
||||
|
||||
Admin uploads a plugin package. The API validates manifest, package hash,
|
||||
version compatibility, permissions, migrations, and declared assets. The package
|
||||
is stored under a controlled runtime plugin directory, never under `src/`.
|
||||
Admin 上传插件包后,API 校验 manifest、包 hash、版本兼容、权限、migration 和 assets。
|
||||
插件包保存到受控运行时插件目录,不能写入 `src/`。
|
||||
|
||||
Enabling a plugin starts its worker, registers operations and event handlers,
|
||||
and records the runtime status. Disabling a plugin stops the worker and removes
|
||||
its active operations/events from routing without deleting data. Uninstalling a
|
||||
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.
|
||||
启用插件时启动 worker,注册 operations 和 event handlers,并记录运行状态。禁用插件时
|
||||
停止 worker,并从路由中移除 active operation/event,不删除数据。卸载插件时停止 worker、
|
||||
移除 registry、解绑 command/event,然后按数据策略处理插件数据:默认保留,只有管理员
|
||||
明确选择清理时才删除。
|
||||
|
||||
### Existing Plugin Rewrite Plan
|
||||
### 现有插件重写计划
|
||||
|
||||
BangDream becomes the large reference plugin. Its current business capability
|
||||
split can stay inside the plugin package:
|
||||
BangDream 作为大型参考插件。现有业务能力拆分可以保留在插件包内:
|
||||
|
||||
```text
|
||||
bangDream/
|
||||
@ -366,108 +314,92 @@ bangDream/
|
||||
assets/
|
||||
```
|
||||
|
||||
The existing BangDream operation registry becomes manifest-backed operation
|
||||
metadata. Handler names remain implementation details inside the plugin worker.
|
||||
The current image rendering smoke expectations, including event stage split
|
||||
output behavior, remain acceptance tests.
|
||||
现有 BangDream operation registry 改为由 manifest 支撑 operation metadata。
|
||||
handlerName 仍作为 worker 内部实现细节。现有图片 smoke 预期继续保留,包括
|
||||
event stage 拆图输出行为。
|
||||
|
||||
FF14 Market becomes an external-query plugin using the host runtime HTTP SDK
|
||||
for XIVAPI and Universalis calls.
|
||||
FF14 Market 改为外部查询插件,通过 host runtime HTTP SDK 调用 XIVAPI 和 Universalis。
|
||||
|
||||
FFLogs becomes an external-query plugin using the host runtime HTTP SDK for
|
||||
GraphQL/token calls and plugin config for client credentials references.
|
||||
FFLogs 改为外部查询插件,通过 host runtime HTTP SDK 调用 GraphQL/token,并通过插件
|
||||
config 引用客户端凭据。
|
||||
|
||||
Repeater becomes an event plugin with host-managed account binding and
|
||||
plugin-owned transient state. It must not bypass the host send queue.
|
||||
Repeater 改为事件插件,由 host 管理账号绑定,由插件持有 transient state,且必须走 host
|
||||
发送队列,不能直接绕过限流和发送排队。
|
||||
|
||||
## 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. |
|
||||
| 1 | Runtime/Common | Keep runtime foundation stable, add missing runtime client/evidence primitives needed by module adapters, and shrink common to stable shared primitives. |
|
||||
| 2 | Admin/Auth/Platform Config | Rebuild identity, menu, permission, dictionary, component template, and system notice models. Admin login and menu loading must pass first. |
|
||||
| 3 | Blog/WordPress/Asset | Rebuild Blog content relations, WordPress mirror/sync, and MinIO asset ownership. Public Blog reads and Admin Blog management must pass. |
|
||||
| 4 | QQBot Core | Rebuild account, connection, permission, command, rule, conversation, message, and send queue models. Command matching and send queue tests must pass. |
|
||||
| 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. |
|
||||
| 6 | Existing Plugin Rewrite | Rewrite BangDream, FF14 Market, FFLogs, and Repeater as isolated plugin packages. Existing command smoke behavior must remain available. |
|
||||
| 7 | NapCat Runtime | Implement container device persistence, login session state machine, captcha/new-device flow, and cleanup evidence on the new QQBot/NapCat model. |
|
||||
| 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. |
|
||||
| 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 is intentionally after QQBot Core and Plugin Platform. It depends on the
|
||||
new account model and shares runtime verification with command/event routing,
|
||||
but it is not itself a plugin.
|
||||
NapCat 故意排在 QQBot Core 和 Plugin Platform 后面。它依赖新账号模型,并和 command/event
|
||||
路由共同参与线上验证,但它本身不是插件。
|
||||
|
||||
## Contract and Breaking-Change Policy
|
||||
## 契约和破坏兼容策略
|
||||
|
||||
External API compatibility is the default. Any implementation task that changes
|
||||
route paths, request fields, response fields, status semantics, SSE event names,
|
||||
Admin API wrappers, or SQL seed identifiers must add the change to a
|
||||
breaking-change table before coding.
|
||||
默认保持外部 API 兼容。任何实现任务如果改变 route path、请求字段、响应字段、状态语义、
|
||||
SSE 事件名、Admin API wrapper 或 SQL seed 标识,都必须在编码前写入 breaking-change 表。
|
||||
|
||||
Allowed planned breakages:
|
||||
允许的计划内破坏:
|
||||
|
||||
- Database table names, columns, indexes, and initialization SQL may change
|
||||
freely because the schema is redesigned from scratch.
|
||||
- Admin pages may need API-wrapper updates during the implementation phase.
|
||||
- Plugin management endpoints are new and can use new route shapes.
|
||||
- 数据库表名、字段、索引和初始化 SQL 可以自由改变,因为 schema 从头设计。
|
||||
- Admin 页面可能需要在实现阶段同步 API wrapper。
|
||||
- 插件管理接口是新增能力,可以使用新的 route shape。
|
||||
|
||||
Protected behavior:
|
||||
必须保护的行为:
|
||||
|
||||
- Admin login and menu loading.
|
||||
- Vben response wrapper for business APIs.
|
||||
- `/health/runtime` plain JSON.
|
||||
- Blog public article list/detail behavior.
|
||||
- QQBot command test flow.
|
||||
- QQBot account status distinction between OneBot connection, container,
|
||||
WebUI, and QQ login state.
|
||||
- NapCat login safety checks, captcha handoff, new-device verification, and
|
||||
runtime password cleanup blocking semantics.
|
||||
- Admin 登录和菜单加载。
|
||||
- 业务 API 的 Vben 响应 wrapper。
|
||||
- `/health/runtime` plain JSON。
|
||||
- Blog public article list/detail。
|
||||
- QQBot command test flow。
|
||||
- QQBot 账号状态继续区分 OneBot 连接、容器、WebUI 和 QQ 登录态。
|
||||
- NapCat 登录安全校验、验证码回交、新设备验证和运行态密码清理失败阻断成功语义。
|
||||
|
||||
## Verification Strategy
|
||||
## 验证策略
|
||||
|
||||
Planning-only verification for this spec:
|
||||
本规划阶段验证:
|
||||
|
||||
- spec self-review for missing markers, contradictions, and ambiguous scope.
|
||||
- `git diff --check`.
|
||||
- KT documentation sync check.
|
||||
- KT global review on changed files.
|
||||
- spec 自检:未决标记、内部矛盾和模糊范围。
|
||||
- `git diff --check`。
|
||||
- KT 文档同步检查。
|
||||
- KT global review 扫描变更文件。
|
||||
|
||||
Future implementation verification must include:
|
||||
后续实现阶段必须包含:
|
||||
|
||||
- targeted unit tests for domain policies and state machines.
|
||||
- repository/schema tests for new SQL and TypeORM mappings.
|
||||
- plugin contract tests generated by the CLI scaffold.
|
||||
- worker runtime tests for load, activate, execute, health, deactivate, and
|
||||
crash isolation.
|
||||
- local API requests for changed endpoints.
|
||||
- Admin UI smoke when Admin callers change.
|
||||
- database rebuild dry run against a local database before online destructive
|
||||
work.
|
||||
- online backup, rebuild, restore path, Jenkins/K8s observation, and functional
|
||||
smoke after deploy.
|
||||
- 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。
|
||||
|
||||
## Acceptance Criteria for This Planning Phase
|
||||
## 本规划阶段验收标准
|
||||
|
||||
This planning phase is complete when:
|
||||
本阶段完成条件:
|
||||
|
||||
1. The design document is written under `docs/superpowers/specs/`.
|
||||
2. The design document is committed.
|
||||
3. The user reviews the committed document.
|
||||
4. The next step is a Superpowers writing-plans phase for the planning output,
|
||||
not code implementation.
|
||||
5. The subsequent full migration starts a fresh Superpowers brainstorming loop
|
||||
before implementation begins.
|
||||
1. 设计文档写入 `docs/superpowers/specs/`。
|
||||
2. 设计文档已提交。
|
||||
3. 用户 review 已提交文档。
|
||||
4. 下一步进入 Superpowers `writing-plans`,不是直接实现代码。
|
||||
5. 后续完整迁移开始前,重新走 Superpowers brainstorming。
|
||||
|
||||
## Handoff to the Next Phase
|
||||
## 交接到下一阶段
|
||||
|
||||
After user review, the writing-plans phase should produce a plan document for
|
||||
the planning deliverable. That plan should describe how to turn this design into
|
||||
implementation-ready work packages, schema documents, plugin platform tasks,
|
||||
and validation checklists.
|
||||
用户 review 通过后,`writing-plans` 阶段应产出计划文档,把本文转换成可执行 work packages、
|
||||
schema 文档、插件平台任务和验证清单。
|
||||
|
||||
The subsequent full implementation must start from a new brainstorming loop
|
||||
because it will involve destructive schema work, Admin/API contract decisions,
|
||||
runtime plugin security boundaries, and online closure.
|
||||
后续完整实现必须重新 brainstorming,因为它会涉及破坏式 schema 工作、Admin/API 契约决策、
|
||||
插件运行时安全边界和线上闭环。
|
||||
|
||||
Loading…
Reference in New Issue
Block a user