71 KiB
API/Admin Full Refactor V3 Implementation Plan
Execution note: Execute this plan task-by-task with the KT-local workflow and use the checkboxes to track plan state.
Goal: Complete the third-phase API/Admin full-module refactor from the approved design: rebuild schema, migrate all API modules, rebuild the QQBot plugin platform, finish NapCat device/login flow, sync Admin, and close locally before one unified push and online smoke.
Architecture: Execute as a batch-gated migration. API owns schema, domain contracts, runtime state, plugin execution, and deployment smoke; Admin follows API contracts in the same batch or the next immediate task. Each batch starts with RED checks, ends with local verification, KT review, KT global review, and separate API/Admin commits.
Tech Stack: NestJS 11, TypeORM 0.3, MySQL, pnpm 9 API workspace, Vben Admin 5 / Vue 3 / TSX / Ant Design Vue, pnpm 10 Admin workspace, Jest, Playwright, ktWorkflow MCP, Jenkins/K8s/NapCat runtime.
Scope Check
The approved spec spans several independent subsystems: database rebuild, API module migration, Admin contract sync, plugin runtime, existing plugin rewrite, NapCat runtime, and online release. Keep one master plan so the third-phase goal stays intact, but execute it as batch-gated work. Do not merge two batches into one commit window.
Every batch must leave the product in a locally verifiable state. Batch 8 is the only push/deploy batch.
Current State Evidence
- API repo:
D:\MyFiles\KT\Node\kt-template-online-api, implementation branchdev-api-full-refactor-v3, package managerpnpm@9.15.9, no.node-version, noengines. - Admin repo:
D:\MyFiles\KT\Vue\kt-template-admin, implementation branchdev-admin-full-refactor-v3, package managerpnpm@10.28.2,.node-version=22.22.0,engines.node >=20.19.0,engines.pnpm >=10.0.0. - Admin repo has three old dirty files authorized by the user to discard during implementation preparation:
README.mdapps/web-antdv-next/src/api/qqbot/index.tsapps/web-antdv-next/src/views/qqbot/account/list.tsx
- API existing top-level source roots:
src/admin,src/blog,src/common,src/middleware,src/minio,src/qqbot,src/runtime,src/wordpress. - API existing SQL roots:
sql/vben-admin-init.sql,sql/blog-init.sql,sql/blog-menu.sql,sql/qqbot-init.sql, plus migration/fix scripts. - Admin existing app root:
apps/web-antdv-next/src, withapi,views,router,components,store,locales.
Execution Rules
- Use
apply_patchfor manual file edits. - Do not push before Batch 8.
- Do not run destructive DB commands until Batch 8 and user confirms the action window.
- Do not treat Jenkins/K8s success as functional success.
- For API interface changes, run a real local request or a bounded smoke script.
- For Admin page changes, run a route/page smoke with browser evidence.
- If a local Node/Vite service is started, clean the process before ending the work turn.
- If a recurring blocker appears twice, record the stable solution before a third raw attempt.
File Structure Map
API Files To Create
| Path | Responsibility |
|---|---|
docs/refactor-v3/schema-map.md |
Batch 0 full schema ownership map. |
docs/refactor-v3/api-admin-contract-matrix.md |
API route, DTO, SSE, and Admin caller/page matrix. |
docs/refactor-v3/breaking-changes.md |
Approved route, DTO, schema, seed, and Admin contract breaks. |
docs/refactor-v3/rebuild-runbook.md |
Local dry run, online backup, schema rebuild, smoke, and rollback runbook. |
sql/refactor-v3/00-full-schema.sql |
Full new schema, no historical patch accumulation. |
sql/refactor-v3/01-seed-core.sql |
Initial seed for Admin, menus, platform settings, QQBot core, and plugin metadata. |
sql/refactor-v3/99-verify.sql |
SQL checks that prove required tables, seed rows, and indexes exist. |
scripts/refactor-v3/db-dry-run.ps1 |
Local empty DB rebuild smoke wrapper. |
scripts/refactor-v3/db-backup-online.ps1 |
Online backup command wrapper without secrets. |
scripts/refactor-v3/db-restore-online.ps1 |
Online rollback wrapper without secrets. |
scripts/refactor-v3/local-smoke.ps1 |
Bounded local smoke entry for API contract checks. |
src/modules/admin/** |
New Admin/Auth/Platform Config module. |
src/modules/blog/** |
New Blog content module. |
src/modules/wordpress/** |
New WordPress mirror/sync module. |
src/modules/asset/** |
New Asset/MinIO ownership module. |
src/modules/qqbot/core/** |
New QQBot account, command, message, permission, send queue core. |
src/modules/qqbot/plugin-platform/** |
Manifest, registry, CLI, worker runtime, RPC, installation lifecycle. |
src/modules/qqbot/plugins/** |
Rewritten BangDream, FF14 Market, FFLogs, Repeater plugin packages. |
src/modules/qqbot/napcat/** |
NapCat container, device identity, login session, challenge, cleanup runtime. |
test/refactor-v3/** |
Cross-batch schema, contract, smoke, and release guard tests. |
test/modules/** |
New module-scoped tests matching src/modules/**. |
API Files To Modify
| Path | Responsibility |
|---|---|
src/app.module.ts |
Replace legacy module imports with new src/modules/** modules when each batch is ready. |
src/runtime/** |
Keep /health/runtime stable, add runtime clients/adapters needed by modules. |
src/common/** |
Keep only shared response, error, time, Snowflake, logger, decorator helpers. |
src/admin/** |
Legacy module removed after Batch 2 compatibility tests pass. |
src/blog/** |
Legacy module removed after Batch 3 compatibility tests pass. |
src/wordpress/** |
Legacy module removed after Batch 3 compatibility tests pass. |
src/minio/** |
Replaced by src/modules/asset/** after Batch 3. |
src/qqbot/** |
Legacy core/plugin/NapCat modules removed after Batches 4-7. |
API.md |
API contract changes and breaking changes summary. |
README.md |
Refactor/development command entry updates. |
Admin Files To Create Or Modify
| Path | Responsibility |
|---|---|
apps/web-antdv-next/src/api/system/*.ts |
Sync Admin/Auth/Platform Config API contracts. |
apps/web-antdv-next/src/api/blog/*.ts |
Sync Blog/WordPress/Asset API contracts. |
apps/web-antdv-next/src/api/qqbot/index.ts |
Replace old QQBot API types and callers. |
apps/web-antdv-next/src/api/qqbot/plugin.ts |
Plugin platform API caller. |
apps/web-antdv-next/src/api/qqbot/napcat.ts |
NapCat login/device/SSE caller. |
apps/web-antdv-next/src/views/system/** |
Identity, menu, role, dept, dict, setting, notice pages. |
apps/web-antdv-next/src/views/blog/** |
Blog, WordPress, Asset management pages. |
apps/web-antdv-next/src/views/qqbot/** |
QQBot account, command, rule, message, send queue, plugin, NapCat pages. |
apps/web-antdv-next/src/router/routes/modules/system.ts |
Menu route sync if frontend routes change. |
apps/web-antdv-next/src/router/routes/modules/blog.ts |
Blog route sync. |
apps/web-antdv-next/src/router/routes/modules/qqbot.ts |
QQBot/plugin/NapCat route sync. |
apps/web-antdv-next/src/locales/langs/zh-CN/system.json |
Visible Chinese labels for new states and pages. |
Batch 0: Workspace And Migration Preparation
Task 0.1: Prepare API branch
Files:
-
No file edits in this task.
-
Step 1: Verify API worktree is clean
Run:
git -C D:\MyFiles\KT\Node\kt-template-online-api status --short --branch
Expected:
## main...origin/main [ahead 3]
- Step 2: Create API implementation branch
Run:
git -C D:\MyFiles\KT\Node\kt-template-online-api switch -c dev-api-full-refactor-v3
Expected:
Switched to a new branch 'dev-api-full-refactor-v3'
- Step 3: Confirm branch
Run:
git -C D:\MyFiles\KT\Node\kt-template-online-api branch --show-current
Expected:
dev-api-full-refactor-v3
Actual note: dev/api-full-refactor-v3 could not be created because the API repository already has a local dev branch, so Git cannot create a nested ref under refs/heads/dev. The implementation branch is dev-api-full-refactor-v3 to preserve the existing dev branch.
Task 0.2: Clean authorized Admin old artifacts and prepare branch
Files:
-
Restore only:
D:\MyFiles\KT\Vue\kt-template-admin\README.mdD:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\api\qqbot\index.tsD:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\views\qqbot\account\list.tsx
-
Step 1: Verify Admin dirty set is exactly authorized
Run:
git -C D:\MyFiles\KT\Vue\kt-template-admin status --short
Expected:
M README.md
M apps/web-antdv-next/src/api/qqbot/index.ts
M apps/web-antdv-next/src/views/qqbot/account/list.tsx
- Step 2: Stop if any extra path appears
If the output contains another path, stop and ask the user before cleanup.
- Step 3: Restore authorized old files
Run:
git -C D:\MyFiles\KT\Vue\kt-template-admin restore -- README.md apps/web-antdv-next/src/api/qqbot/index.ts apps/web-antdv-next/src/views/qqbot/account/list.tsx
Expected: command exits 0.
- Step 4: Confirm Admin worktree is clean
Run:
git -C D:\MyFiles\KT\Vue\kt-template-admin status --short --branch
Expected:
## main...origin/main
- Step 5: Create Admin implementation branch
Run:
git -C D:\MyFiles\KT\Vue\kt-template-admin switch -c dev-admin-full-refactor-v3
Expected:
Switched to a new branch 'dev-admin-full-refactor-v3'
Task 0.3: Create migration control documents
Files:
-
Create:
D:\MyFiles\KT\Node\kt-template-online-api\docs\refactor-v3\schema-map.md -
Create:
D:\MyFiles\KT\Node\kt-template-online-api\docs\refactor-v3\api-admin-contract-matrix.md -
Create:
D:\MyFiles\KT\Node\kt-template-online-api\docs\refactor-v3\breaking-changes.md -
Create:
D:\MyFiles\KT\Node\kt-template-online-api\docs\refactor-v3\rebuild-runbook.md -
Step 1: Add
schema-map.md
Use this content:
# Refactor V3 Schema Map
## Global Rules
- Primary keys are Snowflake `BIGINT`; API/Admin boundary treats IDs as strings.
- Table names use lower snake case.
- Queryable values are structured columns, not JSON-only fields.
- Event/log tables are append-only and have retention strategy.
- New schema is full initialization SQL, not historical `ALTER TABLE` patches.
## Domains
| Domain | Tables | Owner Batch | Notes |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -------------------------------------------------------------- |
| Admin Identity | `admin_user`, `admin_role`, `admin_permission`, `admin_menu`, `admin_department`, `admin_user_role`, `admin_role_permission`, `admin_role_menu` | Batch 2 | Login, menu, role, permission, department. |
| Platform Config | `platform_dict_group`, `platform_dict_item`, `platform_component_template`, `platform_setting` | Batch 2 | Dict and component template split from legacy Admin misc. |
| Blog Content | `blog_post`, `blog_taxonomy`, `blog_term`, `blog_post_term`, `blog_theme_profile`, `blog_import_job` | Batch 3 | Categories and tags use relation table. |
| WordPress Mirror | `wordpress_site`, `wordpress_auth_session`, `wordpress_remote_post`, `wordpress_remote_term`, `wordpress_sync_job`, `wordpress_sync_mapping` | Batch 3 | Remote state separate from local Blog content. |
| Asset | `asset_bucket`, `asset_object`, `asset_reference`, `asset_access_grant` | Batch 3 | MinIO object ownership and access grant. |
| System Event | `system_notice`, `system_event`, `system_event_dedupe`, `system_event_delivery` | Batch 2 | MySQL stores actionable events; Loki remains log query source. |
| Runtime Evidence | `runtime_evidence_index` | Batch 1 | Safe index only, no large logs or secrets. |
| 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` | Batch 4 | Account, connection, permission, command, message, send queue. |
| NapCat Runtime | `napcat_container`, `napcat_device_identity`, `napcat_account_binding`, `napcat_login_session`, `napcat_login_challenge`, `napcat_runtime_cleanup` | Batch 7 | Device identity and login challenge state. |
| 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` | Batch 5 | Manifest, install lifecycle, runtime health, bindings. |
| Plugin-Owned Data | plugin namespace tables | Batch 6 | Table names start with registered plugin namespace. |
- Step 2: Add
api-admin-contract-matrix.md
Use this content:
# API/Admin Contract Matrix
| Batch | API Contract | Admin Surface | Smoke Evidence |
| ----- | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | ----------------------------------------------------------- |
| 1 | `GET /health/runtime` plain JSON, runtime adapter internals | Runtime status remains available | `curl http://localhost:<port>/health/runtime` |
| 2 | `/auth/*`, `/admin/user/*`, `/admin/menu/*`, `/admin/role/*`, `/admin/dept/*`, `/admin/dict/*`, `/admin/notice/*` | Login, menu, system pages | Login request, menu load, route render |
| 3 | `/blog/*`, `/wordpress/*`, `/asset/*` | Blog, WordPress, Asset pages | Public blog request, Admin list request, asset upload smoke |
| 4 | `/qqbot/account/*`, `/qqbot/command/*`, `/qqbot/rule/*`, `/qqbot/message/*`, `/qqbot/send/*` | QQBot core pages | `/qqbot/command/test` local request |
| 5 | `/qqbot/plugin-platform/*` | Plugin upload/install/enable/config/health pages | local test plugin install and enable |
| 6 | plugin operations exposed through QQBot command/event routing | Existing plugin pages and operation views | BangDream, FF14, FFLogs, Repeater smoke |
| 7 | `/qqbot/napcat/*`, login SSE events | NapCat device/login progress pages | simulated captcha and new-device session |
| 8 | public deployed URLs | deployed Admin | online smoke bundle |
- Step 3: Add
breaking-changes.md
Use this content:
# Refactor V3 Breaking Changes
## Approved
| Area | Change | Reason | First Batch |
| --------------------- | --------------------------------------------------------- | -------------------------------------------------------------------------- | ----------- |
| Database | Rebuild all API-owned tables from new full schema | Current data is not important and old schema blocks clean module ownership | Batch 0 |
| SQL init | Replace historical patch scripts with `sql/refactor-v3/*` | Avoid accumulated `ALTER TABLE` history | Batch 0 |
| Admin QQBot API types | Replace old QQBot caller types with new contract | New QQBot Core, Plugin Platform, and NapCat state model | Batch 4 |
## Protected Behavior
- Admin login succeeds.
- Admin menu loads.
- Vben success/error wrappers remain stable for Admin APIs.
- `/health/runtime` remains plain JSON.
- Blog public list/detail remain available.
- QQBot command test remains available.
- QQBot status keeps OneBot, container, WebUI, and QQ login state separate.
- NapCat cleanup failure blocks success.
- Step 4: Add
rebuild-runbook.md
Use this content:
# Refactor V3 Rebuild Runbook
## Local Dry Run
1. Create an empty local database dedicated to refactor V3.
2. Apply `sql/refactor-v3/00-full-schema.sql`.
3. Apply `sql/refactor-v3/01-seed-core.sql`.
4. Run `sql/refactor-v3/99-verify.sql`.
5. Start API against the dry-run database.
6. Run `scripts/refactor-v3/local-smoke.ps1`.
## Online Backup
1. Confirm the exact API image tag and current database name.
2. Run `scripts/refactor-v3/db-backup-online.ps1`.
3. Record backup path, timestamp, source database, and restore command.
## Online Rebuild
1. Stop or limit API write traffic.
2. Apply full schema and seed scripts.
3. Run verify SQL.
4. Deploy API/Admin image versions bound to this schema.
5. Run online smoke bundle.
## Rollback
1. Stop write traffic.
2. Restore the recorded backup or previous schema bundle.
3. Roll back API/Admin images.
4. Re-run smoke for the restored version.
- Step 5: Verify docs exist
Run:
Test-Path D:\MyFiles\KT\Node\kt-template-online-api\docs\refactor-v3\schema-map.md
Test-Path D:\MyFiles\KT\Node\kt-template-online-api\docs\refactor-v3\api-admin-contract-matrix.md
Test-Path D:\MyFiles\KT\Node\kt-template-online-api\docs\refactor-v3\breaking-changes.md
Test-Path D:\MyFiles\KT\Node\kt-template-online-api\docs\refactor-v3\rebuild-runbook.md
Expected:
True
True
True
True
Task 0.4: Add schema skeleton and RED schema test
Files:
-
Create:
D:\MyFiles\KT\Node\kt-template-online-api\sql\refactor-v3\00-full-schema.sql -
Create:
D:\MyFiles\KT\Node\kt-template-online-api\sql\refactor-v3\01-seed-core.sql -
Create:
D:\MyFiles\KT\Node\kt-template-online-api\sql\refactor-v3\99-verify.sql -
Create:
D:\MyFiles\KT\Node\kt-template-online-api\test\refactor-v3\schema-map.spec.ts -
Step 1: Write failing schema test
Create test/refactor-v3/schema-map.spec.ts:
import { readFileSync } from 'fs';
import { join } from 'path';
const root = join(__dirname, '..', '..');
const requiredTables = [
'admin_user',
'admin_role',
'admin_permission',
'admin_menu',
'admin_department',
'platform_dict_group',
'platform_dict_item',
'blog_post',
'blog_taxonomy',
'blog_term',
'wordpress_site',
'asset_object',
'system_notice',
'runtime_evidence_index',
'qqbot_account',
'qqbot_command',
'qqbot_send_task',
'qqbot_plugin',
'qqbot_plugin_installation',
'qqbot_plugin_runtime_event',
'napcat_device_identity',
'napcat_login_session',
'napcat_login_challenge',
];
describe('refactor v3 schema skeleton', () => {
it('declares every required table in the full schema file', () => {
const sql = readFileSync(
join(root, 'sql/refactor-v3/00-full-schema.sql'),
'utf8',
);
for (const table of requiredTables) {
expect(sql).toContain(`CREATE TABLE IF NOT EXISTS ${table}`);
}
});
it('declares core seed and verification scripts', () => {
const seed = readFileSync(
join(root, 'sql/refactor-v3/01-seed-core.sql'),
'utf8',
);
const verify = readFileSync(
join(root, 'sql/refactor-v3/99-verify.sql'),
'utf8',
);
expect(seed).toContain('INSERT INTO admin_user');
expect(seed).toContain('INSERT INTO qqbot_command');
expect(seed).toContain('INSERT INTO qqbot_plugin');
expect(verify).toContain('admin_user');
expect(verify).toContain('qqbot_command');
expect(verify).toContain('qqbot_plugin');
expect(verify).toContain('napcat_device_identity');
});
});
- Step 2: Run RED check
Run:
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api exec jest --runInBand --runTestsByPath test/refactor-v3/schema-map.spec.ts
Expected: FAIL because sql/refactor-v3/00-full-schema.sql does not exist.
- Step 3: Add minimal SQL skeleton
Create the three SQL files with table declarations, seed markers, and verify markers. Use full table definitions before ending Batch 0; the initial minimal version only makes the RED check meaningful.
- Step 4: Run GREEN check
Run:
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api exec jest --runInBand --runTestsByPath test/refactor-v3/schema-map.spec.ts
Expected: PASS.
Task 0.5: Add DB dry-run wrappers
Files:
-
Create:
D:\MyFiles\KT\Node\kt-template-online-api\scripts\refactor-v3\db-dry-run.ps1 -
Create:
D:\MyFiles\KT\Node\kt-template-online-api\scripts\refactor-v3\db-backup-online.ps1 -
Create:
D:\MyFiles\KT\Node\kt-template-online-api\scripts\refactor-v3\db-restore-online.ps1 -
Create:
D:\MyFiles\KT\Node\kt-template-online-api\scripts\refactor-v3\local-smoke.ps1 -
Step 1: Add dry-run script
Create db-dry-run.ps1:
param(
[Parameter(Mandatory=$true)][string]$Database,
[string]$HostName = "127.0.0.1",
[int]$Port = 3306,
[string]$User = "root"
)
$ErrorActionPreference = "Stop"
if ($Database -notmatch '^[A-Za-z0-9_]+$') {
throw "Database must match ^[A-Za-z0-9_]+$"
}
$root = Resolve-Path (Join-Path $PSScriptRoot "..\..")
$schema = Join-Path $root "sql\refactor-v3\00-full-schema.sql"
$seed = Join-Path $root "sql\refactor-v3\01-seed-core.sql"
$verify = Join-Path $root "sql\refactor-v3\99-verify.sql"
function Invoke-MysqlSource {
param(
[Parameter(Mandatory = $true)][string]$Path
)
$sourcePath = (Resolve-Path -LiteralPath $Path).Path.Replace("\", "/")
mysql -h $HostName -P $Port -u $User $Database --execute="source $sourcePath"
}
mysql -h $HostName -P $Port -u $User -e "DROP DATABASE IF EXISTS ``$Database``; CREATE DATABASE ``$Database`` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
Invoke-MysqlSource -Path $schema
Invoke-MysqlSource -Path $seed
Invoke-MysqlSource -Path $verify
- Step 2: Add online backup script
Create db-backup-online.ps1:
param(
[Parameter(Mandatory=$true)][string]$Database,
[Parameter(Mandatory=$true)][string]$OutputDirectory
)
$ErrorActionPreference = "Stop"
if ($Database -notmatch '^[A-Za-z0-9_]+$') {
throw "Database must match ^[A-Za-z0-9_]+$"
}
$stamp = Get-Date -Format "yyyyMMdd-HHmmss"
$target = Join-Path $OutputDirectory "$Database-refactor-v3-$stamp.sql"
mysqldump --set-gtid-purged=OFF --single-transaction --routines --triggers --default-character-set=utf8mb4 "--result-file=$target" $Database
Write-Output $target
- Step 3: Add restore script
Create db-restore-online.ps1:
param(
[Parameter(Mandatory=$true)][string]$Database,
[Parameter(Mandatory=$true)][string]$BackupFile
)
$ErrorActionPreference = "Stop"
if ($Database -notmatch '^[A-Za-z0-9_]+$') {
throw "Database must match ^[A-Za-z0-9_]+$"
}
if (-not (Test-Path -LiteralPath $BackupFile -PathType Leaf)) {
throw "BackupFile does not exist"
}
$sourcePath = (Resolve-Path -LiteralPath $BackupFile).Path.Replace("\", "/")
mysql -e "DROP DATABASE IF EXISTS ``$Database``; CREATE DATABASE ``$Database`` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
mysql --default-character-set=utf8mb4 $Database --execute="source $sourcePath"
- Step 4: Add local smoke script
Create local-smoke.ps1:
param(
[string]$BaseUrl = "http://127.0.0.1:5320"
)
$ErrorActionPreference = "Stop"
$runtime = Invoke-RestMethod -Method Get -Uri "$BaseUrl/health/runtime" -TimeoutSec 10
if (-not $runtime.service) {
throw "Runtime health response did not include service"
}
Write-Output "runtime.service=$($runtime.service)"
- Step 5: Validate scripts parse
Run:
powershell -NoProfile -Command '$null = [scriptblock]::Create((Get-Content -Raw -LiteralPath "D:\MyFiles\KT\Node\kt-template-online-api\scripts\refactor-v3\db-dry-run.ps1")); "ok"'
powershell -NoProfile -Command '$null = [scriptblock]::Create((Get-Content -Raw -LiteralPath "D:\MyFiles\KT\Node\kt-template-online-api\scripts\refactor-v3\local-smoke.ps1")); "ok"'
powershell -NoProfile -Command '$null = [scriptblock]::Create((Get-Content -Raw -LiteralPath "D:\MyFiles\KT\Node\kt-template-online-api\scripts\refactor-v3\db-backup-online.ps1")); "ok"'
powershell -NoProfile -Command '$null = [scriptblock]::Create((Get-Content -Raw -LiteralPath "D:\MyFiles\KT\Node\kt-template-online-api\scripts\refactor-v3\db-restore-online.ps1")); "ok"'
Expected:
ok
ok
ok
ok
Task 0.6: Batch 0 verification and commits
Files:
-
Modify:
D:\MyFiles\KT\TASKS.md -
API commit includes only Batch 0 API files.
-
Root commit includes only
TASKS.md. -
Step 1: Run API Batch 0 checks
Run:
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api exec jest --runInBand --runTestsByPath test/refactor-v3/schema-map.spec.ts
git -C D:\MyFiles\KT\Node\kt-template-online-api diff --check
Expected: Jest PASS and diff check exits 0.
- Step 2: Run doc sync
Run MCP tool:
kt_change_doc_sync(project=api, taskType=docs)
Expected: all required docs are updated or explicitly reported as not needed.
- Step 3: Run KT global review
Run MCP tool:
kt_global_code_review(projects=["api","root"], contentScanMode="changed", includeContentScan=true)
Expected: findings=[].
- Step 4: Commit API Batch 0
Run:
git -C D:\MyFiles\KT\Node\kt-template-online-api add docs/refactor-v3 sql/refactor-v3 scripts/refactor-v3 test/refactor-v3
git -C D:\MyFiles\KT\Node\kt-template-online-api commit -m "chore: 准备第三期迁移脚手架"
- Step 5: Commit TASKS record
Run:
git -C D:\MyFiles\KT add TASKS.md
git -C D:\MyFiles\KT commit -m "docs: 记录第三期迁移准备"
Batch 1: Runtime/Common Foundation
Task 1.1: Add runtime adapter contracts
Files:
-
Create:
D:\MyFiles\KT\Node\kt-template-online-api\src\runtime\client\runtime-http-client.types.ts -
Create:
D:\MyFiles\KT\Node\kt-template-online-api\src\runtime\client\runtime-process-client.types.ts -
Create:
D:\MyFiles\KT\Node\kt-template-online-api\src\runtime\client\runtime-docker-client.types.ts -
Create:
D:\MyFiles\KT\Node\kt-template-online-api\test\runtime\runtime-client-contract.spec.ts -
Step 1: Write RED contract test
Test expectations:
describe('runtime client contracts', () => {
it('uses explicit timeout and redaction fields for external calls', () => {
const request = {
url: 'https://example.invalid',
method: 'GET' as const,
timeoutMs: 1000,
redactHeaders: ['authorization'],
};
expect(request.timeoutMs).toBeGreaterThan(0);
expect(request.redactHeaders).toContain('authorization');
});
});
- Step 2: Create type files
Define request/response types for HTTP, process, and Docker calls. Each request type includes timeoutMs, correlationId, and safeSummary.
- Step 3: Export contracts
Modify src/runtime/index.ts to export the new client contract types.
- Step 4: Verify
Run:
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api exec jest --runInBand --runTestsByPath test/runtime/runtime-client-contract.spec.ts test/runtime/runtime-health.service.spec.ts test/runtime/runtime-health.controller.spec.ts
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api run typecheck
Expected: PASS.
Task 1.2: Keep common narrow and stable
Files:
-
Modify:
D:\MyFiles\KT\Node\kt-template-online-api\src\common\index.ts -
Modify:
D:\MyFiles\KT\Node\kt-template-online-api\src\common\common.module.ts -
Test: existing
test/common/*.spec.ts -
Step 1: List exported common symbols
Run:
Get-Content D:\MyFiles\KT\Node\kt-template-online-api\src\common\index.ts
- Step 2: Remove only exports made obsolete by new runtime contracts
Keep response wrappers, filters, interceptors, time decorators, Snowflake, logger config, and generic tools.
Actual note: no runtime client or now-obsolete export was present in src/common/index.ts or src/common/common.module.ts, so Common stayed unchanged to avoid artificial churn.
- Step 3: Verify common tests
Run:
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api exec jest --runInBand --runTestsByPath test/common/tool.service.spec.ts test/common/swagger-response.spec.ts test/common/kt-date-time.decorator.spec.ts test/common/api-request-log.interceptor.spec.ts
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api run typecheck
Expected: PASS.
Task 1.3: Commit Batch 1
Files:
-
Modify:
D:\MyFiles\KT\TASKS.md -
API and root commits.
-
Step 1: Run Batch 1 review gates
Run MCP tools:
kt_change_doc_sync(project=api, taskType=refactor)
kt_global_code_review(projects=["api","root"], contentScanMode="changed", includeContentScan=true)
Expected: required docs resolved and findings=[].
- Step 2: Commit
Run:
git -C D:\MyFiles\KT\Node\kt-template-online-api add src/runtime src/common test/runtime test/common docs/refactor-v3
git -C D:\MyFiles\KT\Node\kt-template-online-api commit -m "refactor: 重整运行时与通用基础层"
git -C D:\MyFiles\KT add TASKS.md
git -C D:\MyFiles\KT commit -m "docs: 记录第三期基础层迁移"
Batch 2: Admin/Auth/Platform Config
Reusable guardrail for later module batches: route contract tests must prove both decorator route compatibility and module graph reachability. If a route remains available through an imported legacy module, assert the importing module metadata and assert that the imported controller is not also registered directly.
Task 2.1: Build new Admin module boundary
Files:
-
Create:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\admin\admin.module.ts -
Create:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\admin\identity\** -
Create:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\admin\platform-config\** -
Modify:
D:\MyFiles\KT\Node\kt-template-online-api\src\app.module.ts -
Test:
D:\MyFiles\KT\Node\kt-template-online-api\test\modules\admin\admin-contract.spec.ts -
Step 1: Write RED route compatibility test
Create assertions for login, menu, user, role, dept, dict, notice controller paths using test/helpers/controller-route.helper.ts.
- Step 2: Create module shell
Create src/modules/admin/admin.module.ts with controllers and providers grouped by identity and platform-config.
- Step 3: Move one domain at a time
Move identity first, then menu/permission, then dict/component/notice. After each move, run the related Jest file.
Actual: Batch 2 kept legacy src/admin/** files in place and created the new shell boundary by grouping identity and platform-config controllers/providers. Dict and notice remain reachable through imported legacy modules to avoid duplicate controller registration.
- Step 4: Verify
Run:
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api exec jest --runInBand --runTestsByPath test/admin/auth/admin-password-crypto.service.spec.ts test/admin/admin-menu.service.spec.ts test/admin/dict/dict.service.spec.ts test/admin/notice/admin-notice.service.spec.ts test/modules/admin/admin-contract.spec.ts
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api run typecheck
Expected: PASS.
Task 2.2: Sync Admin frontend system callers and pages
Files:
-
Modify:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\api\core\auth.ts -
Modify:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\api\core\menu.ts -
Modify:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\api\system\*.ts -
Modify:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\views\system\** -
Step 1: Update API types to string IDs
All ID fields crossing the API boundary use string.
Actual: no Admin frontend edit was needed. The targeted core and system API wrappers already use string IDs for user, role, menu, dept, dict, and notice contracts; the only id: number scan hit is the local SystemKtTableDemo demo row type, not a backend contract.
- Step 2: Ensure route page roots are stable
Every changed route page has a single stable root element.
Actual: targeted system pages already use a single Page root, with modal/drawer children inside the page root.
- Step 3: Verify Admin typecheck
Run:
pnpm --dir D:\MyFiles\KT\Vue\kt-template-admin -F @vben/web-antdv-next run typecheck
Expected: PASS.
- Step 4: Run local login/menu smoke
Start API and Admin only for this smoke. Save evidence under .kt-workspace/test-artifacts/admin-system/<date>/.
Actual: because Admin frontend had no code diff in this batch, full dev-server login was not started. The interface smoke used a local Nest TestingModule HTTP server with real Admin boundary controllers from ADMIN_IDENTITY_CONTROLLERS and ADMIN_PLATFORM_CONFIG_CONTROLLERS, then called GET /auth/password-public-key, GET /menu/all, GET /dict/codes, and GET /system/notice/list successfully.
Task 2.3: Commit Batch 2
Run:
git -C D:\MyFiles\KT\Node\kt-template-online-api add src/modules/admin src/app.module.ts test/modules/admin sql/refactor-v3 docs/refactor-v3
git -C D:\MyFiles\KT\Node\kt-template-online-api commit -m "refactor: 迁移后台身份权限与平台配置"
git -C D:\MyFiles\KT\Vue\kt-template-admin add apps/web-antdv-next/src/api/core apps/web-antdv-next/src/api/system apps/web-antdv-next/src/views/system apps/web-antdv-next/src/router
git -C D:\MyFiles\KT\Vue\kt-template-admin commit -m "refactor: 同步后台系统管理契约"
git -C D:\MyFiles\KT add TASKS.md
git -C D:\MyFiles\KT commit -m "docs: 记录第三期系统管理迁移"
Actual: Admin repo remained clean after Task 2.2 verification, so Batch 2 creates no Admin commit.
Batch 3: Blog/WordPress/Asset
Task 3.1: Build Blog, WordPress, and Asset modules
Files:
-
Create:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\blog\** -
Create:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\wordpress\** -
Create:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\asset\** -
Modify:
D:\MyFiles\KT\Node\kt-template-online-api\src\app.module.ts -
Test:
D:\MyFiles\KT\Node\kt-template-online-api\test\modules\blog\** -
Test:
D:\MyFiles\KT\Node\kt-template-online-api\test\modules\wordpress\** -
Test:
D:\MyFiles\KT\Node\kt-template-online-api\test\modules\asset\** -
Step 1: Write RED tests for public Blog behavior
Cover article list, article detail, term relation, and theme profile.
- Step 2: Write RED tests for WordPress mapping
Cover remote ID to local post/term mapping and sync job state.
- Step 3: Write RED tests for Asset ownership
Cover object owner module, MIME metadata, reference, and access grant.
- Step 4: Implement modules
Keep route compatibility for public Blog endpoints and Admin-facing endpoints. Move MinIO ownership out of legacy src/minio into src/modules/asset.
- Step 5: Verify
Run:
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api exec jest --runInBand --runTestsByPath test/blog/blog-article.service.spec.ts test/blog/blog-term.service.spec.ts test/wordpress/wordpress.service.spec.ts test/modules/blog test/modules/wordpress test/modules/asset
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api run typecheck
Expected: PASS.
Actual note: Batch 3 moved API ownership to transitional BlogContentModule, WordpressMirrorModule, and AssetModule boundaries while retaining legacy business internals behind imported modules for compatibility. Contract tests now parse sql/refactor-v3/00-full-schema.sql through test/helpers/sql-schema.helper.ts so domain expectations catch SQL schema drift instead of only repeating local constants. Route compatibility and duplicate-controller safety are covered by module graph tests, with QqbotModule mocked in metadata-only specs to avoid unrelated BangDream/NapCat side effects.
Task 3.2: Sync Admin Blog/WordPress/Asset pages
Files:
-
Modify:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\api\blog\index.ts -
Modify:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\api\blog\wordpress.ts -
Create:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\api\blog\asset.ts -
Modify:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\views\blog\** -
Modify:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\router\routes\modules\blog.ts -
Step 1: Update callers
Use string IDs and explicit response types.
- Step 2: Keep pages work-focused
Use KtTable or existing forms; avoid landing-page or card-heavy redesign.
- Step 3: Verify
Run:
pnpm --dir D:\MyFiles\KT\Vue\kt-template-admin -F @vben/web-antdv-next run typecheck
Expected: PASS.
Actual note: Admin Blog/WordPress ID-facing types were aligned to string IDs, api/blog/asset.ts was added against the existing /minio/* compatibility routes, and the Blog router/page layout was left unchanged because Batch 3 did not introduce a new visible page structure.
Task 3.3: Commit Batch 3
Run:
git -C D:\MyFiles\KT\Node\kt-template-online-api add src/modules/blog src/modules/wordpress src/modules/asset src/app.module.ts test/modules sql/refactor-v3 docs/refactor-v3 API.md README.md
git -C D:\MyFiles\KT\Node\kt-template-online-api commit -m "refactor: 迁移博客镜像与资产模块"
git -C D:\MyFiles\KT\Vue\kt-template-admin add apps/web-antdv-next/src/api/blog apps/web-antdv-next/src/views/blog apps/web-antdv-next/src/router/routes/modules/blog.ts
git -C D:\MyFiles\KT\Vue\kt-template-admin commit -m "refactor: 同步博客与资产管理页面"
Batch 4: QQBot Core
Task 4.1: Build QQBot core module
Files:
-
Create:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\qqbot\core\** -
Modify:
D:\MyFiles\KT\Node\kt-template-online-api\src\app.module.ts -
Test:
D:\MyFiles\KT\Node\kt-template-online-api\test\modules\qqbot\core\** -
Step 1: Write RED status-separation tests
Cover OneBot connection, container status, WebUI status, and QQ login status as separate fields.
- Step 2: Write RED command tests
Cover operation key lookup, command ID usage, aliases, cooldown, permission policy, and parser validation.
- Step 3: Write RED send queue tests
Cover queue reservation, rate limit, send log, and dedupe event behavior.
- Step 4: Implement core
Move account, connection, command, rule, message, permission, send, dedupe, and dashboard logic into src/modules/qqbot/core.
- Step 5: Verify
Run:
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api exec jest --runInBand --runTestsByPath test/qqbot/command/qqbot-command-parser.service.spec.ts test/qqbot/send/qqbot-send.service.spec.ts test/qqbot/send/qqbot-rate-limit.service.spec.ts test/qqbot/event/qqbot-event.service.spec.ts test/modules/qqbot/core
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api run typecheck
Expected: PASS.
Actual note: QqbotCoreModule now owns the QQBot Nest boundary directly with Config/AdminAuthGuard/Dict/TypeORM imports, full controller/provider/entity/export lists, and src/qqbot/qqbot.module.ts kept only as a compatibility shim. The RED contract tests failed first on missing QQBOT_CORE_ENTITIES / QQBOT_CORE_EXPORTS and missing qqbot-core.contract; after implementation, Turing review found that registered legacy TypeORM entities were not fully represented in sql/refactor-v3/00-full-schema.sql. The follow-up RED/GREEN guard now checks every registered QQBot Core entity table/column against the real v3 SQL, checks nullable entity columns, and rejects SQL-only required insert columns. The schema map and full SQL include transitional compatibility tables/columns for currently registered legacy QQBot, plugin-adjacent, and NapCat-adjacent entities; Batches 5-7 will replace those internals rather than treating this as the final plugin/NapCat design.
Task 4.2: Sync Admin QQBot core pages
Files:
-
Modify:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\api\qqbot\index.ts -
Modify:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\views\qqbot\account\** -
Modify:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\views\qqbot\command\list.tsx -
Modify:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\views\qqbot\rule\list.tsx -
Modify:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\views\qqbot\message\list.tsx -
Modify:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\views\qqbot\sendLog\list.tsx -
Step 1: Split status fields in the API types
Define oneBotStatus, containerStatus, webuiStatus, and qqLoginStatus separately.
- Step 2: Keep account page single-root
If modal/drawer components are siblings, wrap the route in one root container.
- Step 3: Verify
Run:
pnpm --dir D:\MyFiles\KT\Vue\kt-template-admin -F @vben/web-antdv-next run typecheck
Expected: PASS.
Actual note: QQBot account API types now expose oneBotStatus, containerStatus, webuiStatus, and qqLoginStatus as top-level split fields while preserving nested napcat fallbacks. The account page keeps its existing single route root and derives display/actions from the split status helpers, including disabling disconnect by OneBot status instead of the old collapsed connection status. Command/rule/message/sendLog pages did not need visible changes in this slice because their contracts did not consume the status fields. Admin typecheck passed.
Task 4.3: Run local QQBot command smoke
Run API locally, query enabled command by operationKey, pass commandId, and include full command text.
Expected evidence:
- request URL
- command ID
- operation key
- response status
- sanitized response summary without
replyText
Actual evidence: local Nest TestingModule HTTP smoke calls GET /qqbot/command/list?operationKey=bangdream.song.search&enabled=true&pageNo=1&pageSize=10, obtains command ID cmd-bangdream-song-search, then calls POST /qqbot/command/test with commandId and full text /查歌 FIRE BIRD. Response status is 200 and the asserted summary strips replyText while proving real QqbotCommandService.page, QqbotCommandEngineService.preview, parser, reply template, and plugin execution boundaries were exercised with mocked repository/plugin edges. Main-thread verification passed pnpm exec jest --runInBand --runTestsByPath test/refactor-v3/schema-map.spec.ts ... test/modules/qqbot/core/qqbot-core-command-smoke.spec.ts with 13 suites / 28 tests, API pnpm run typecheck, and Admin pnpm -F @vben/web-antdv-next run typecheck.
Task 4.4: Commit Batch 4
Run:
git -C D:\MyFiles\KT\Node\kt-template-online-api add src/modules/qqbot/core src/app.module.ts test/modules/qqbot/core sql/refactor-v3 docs/refactor-v3 API.md
git -C D:\MyFiles\KT\Node\kt-template-online-api commit -m "refactor: 迁移QQBot核心模块"
git -C D:\MyFiles\KT\Vue\kt-template-admin add apps/web-antdv-next/src/api/qqbot apps/web-antdv-next/src/views/qqbot apps/web-antdv-next/src/router/routes/modules/qqbot.ts
git -C D:\MyFiles\KT\Vue\kt-template-admin commit -m "refactor: 同步QQBot核心管理页"
Batch 5: QQBot Plugin Platform
Task 5.1: Build plugin platform schema and manifest contracts
Files:
-
Create:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\qqbot\plugin-platform\manifest\** -
Create:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\qqbot\plugin-platform\persistence\** -
Test:
D:\MyFiles\KT\Node\kt-template-online-api\test\modules\qqbot\plugin-platform\manifest.spec.ts -
Step 1: Write RED manifest validation tests
Cover plugin key, semantic version, SDK version, operations, events, config schema, assets, migrations, permissions, and runtime limits.
- Step 2: Implement manifest parser
Reject unknown permissions, duplicate operation keys, duplicate event keys, missing runtime budgets, and package paths outside plugin root.
- Step 3: Verify
Run:
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api exec jest --runInBand --runTestsByPath test/modules/qqbot/plugin-platform/manifest.spec.ts
Expected: PASS.
Actual note: Manifest RED first failed with missing src/modules/qqbot/plugin-platform/manifest. The parser now normalizes complete manifests and rejects unknown permissions, duplicate operation/event keys, missing runtime budgets, missing operation timeout, and paths outside the plugin root. Batch 5 persistence RED first failed with missing persistence; TypeORM entities now map all 9 plugin-platform v3 tables and are checked against real sql/refactor-v3/00-full-schema.sql.
Task 5.2: Build plugin CLI
Files:
-
Create:
D:\MyFiles\KT\Node\kt-template-online-api\scripts\qqbot-plugin\cli.ts -
Create:
D:\MyFiles\KT\Node\kt-template-online-api\scripts\qqbot-plugin\templates\basic\plugin.json -
Create:
D:\MyFiles\KT\Node\kt-template-online-api\scripts\qqbot-plugin\templates\basic\src\index.ts -
Modify:
D:\MyFiles\KT\Node\kt-template-online-api\package.json -
Test:
D:\MyFiles\KT\Node\kt-template-online-api\test\modules\qqbot\plugin-platform\cli.spec.ts -
Step 1: Add package script
Add:
{
"scripts": {
"qqbot-plugin": "ts-node -r tsconfig-paths/register scripts/qqbot-plugin/cli.ts"
}
}
Keep existing scripts.
- Step 2: Implement commands
Commands:
create <pluginKey>
validate <path>
pack <path>
install-local <package>
- Step 3: Verify CLI
Run:
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api qqbot-plugin create demo-plugin
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api qqbot-plugin validate .\plugins\demo-plugin
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api qqbot-plugin pack .\plugins\demo-plugin
Expected: commands exit 0, package includes content hash.
Actual note: Added pnpm qqbot-plugin backed by scripts/qqbot-plugin/cli.ts, with create, validate, pack, and install-local. CLI tests caught a package hash mismatch caused by undefined fields in stable serialization; stable stringify now skips undefined so pack and install-local verify the same content hash. Real CLI smoke created plugins/demo-plugin, validated it, packed demo-plugin-0.1.0-acc880b89e70.qqbot-plugin.json, installed it locally, and then removed the temporary directory.
Task 5.3: Build worker runtime and lifecycle
Files:
-
Create:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\qqbot\plugin-platform\runtime\** -
Create:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\qqbot\plugin-platform\sdk\** -
Test:
D:\MyFiles\KT\Node\kt-template-online-api\test\modules\qqbot\plugin-platform\worker-runtime.spec.ts -
Step 1: Write RED RPC tests
Cover load, activate, executeOperation, handleEvent, health, deactivate, dispose, timeout, and crash isolation.
- Step 2: Implement host-side runtime
Worker messages include correlation ID, timeout budget, operation ID, safe input summary, and structured output.
- Step 3: Implement SDK
Expose only send queue, plugin config, plugin storage, runtime HTTP client, plugin asset loader, operation context, and event context.
- Step 4: Verify
Run:
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api exec jest --runInBand --runTestsByPath test/modules/qqbot/plugin-platform/worker-runtime.spec.ts
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api run typecheck
Expected: PASS.
Actual note: Worker runtime RED first failed on missing runtime and sdk. QqbotPluginWorkerRuntime now sends lifecycle/execution RPC messages with correlation ID, timeout budget, operation ID/event key, and safe input summary without raw secret values. Worker crash and timeout become plugin-scoped runtime events and set the installation runtime status boundary to failed. createQqbotPluginSdk exposes only host-controlled send queue, config, storage, runtime HTTP, asset, operation context, event context, and runtime-event capabilities.
Task 5.4: Sync Admin plugin platform page
Files:
-
Create:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\api\qqbot\plugin.ts -
Modify:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\views\qqbot\plugin\list.tsx -
Modify:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\router\routes\modules\qqbot.ts -
Step 1: Add plugin caller
Caller methods: upload, validate, install, enable, disable, upgrade, uninstall, update config, list runtime events, list account bindings.
- Step 2: Build management page
Use tables, status tags, drawers/modals for upload/config/events, and Chinese operation labels.
- Step 3: Verify
Run:
pnpm --dir D:\MyFiles\KT\Vue\kt-template-admin -F @vben/web-antdv-next run typecheck
Expected: PASS.
Actual note: Added /qqbot/plugin-platform/* API controller/service/module before wiring Admin so the caller methods target real routes. Admin now has src/api/qqbot/plugin.ts with upload, validate, install, install-local, enable, disable, upgrade, uninstall, config update, runtime events, and account bindings. The existing plugin page remains a single Page root, keeps the operation table, and adds Chinese platform actions plus modal/drawer flows for Manifest JSON, installation records, runtime events, and account bindings. Admin route title changed from "插件能力" to "插件平台".
Task 5.5: Commit Batch 5
Run:
git -C D:\MyFiles\KT\Node\kt-template-online-api add src/modules/qqbot/plugin-platform scripts/qqbot-plugin test/modules/qqbot/plugin-platform package.json sql/refactor-v3 docs/refactor-v3 API.md README.md
git -C D:\MyFiles\KT\Node\kt-template-online-api commit -m "feat: 建立QQBot插件平台"
git -C D:\MyFiles\KT\Vue\kt-template-admin add apps/web-antdv-next/src/api/qqbot apps/web-antdv-next/src/views/qqbot/plugin apps/web-antdv-next/src/router/routes/modules/qqbot.ts
git -C D:\MyFiles\KT\Vue\kt-template-admin commit -m "feat: 增加QQBot插件管理页"
Batch 6: Existing Plugin Rewrite
Task 6.1: Rewrite BangDream as platform plugin
Files:
-
Create:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\qqbot\plugins\bangdream\plugin.json -
Create/modify:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\qqbot\plugins\bangdream\** -
Test:
D:\MyFiles\KT\Node\kt-template-online-api\test\modules\qqbot\plugins\bangdream\** -
Step 1: Preserve business directories
Keep business capabilities in domain/song, domain/card, domain/character, domain/event, domain/gacha, domain/player, domain/cutoff, and domain/catalog; keep orchestration in application, operations in operations, external APIs in infrastructure/integration, cache/static patch adapters in infrastructure/storage, dictionary/static config in config, and visual helpers in theme.
- Step 2: Convert operation registry to manifest metadata
Keep operation keys and aliases stable. handlerName becomes worker-internal.
- Step 3: Verify BangDream
Run:
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api exec jest --runInBand --runTestsByPath test/qqbot/plugins/bangdream/manifest/operation-manifest.spec.ts test/qqbot/plugins/bangdream/manifest/command-sql.spec.ts test/modules/qqbot/plugins/bangdream-rewrite/bangdream-operation-parity.spec.ts
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api run typecheck
Expected: PASS. Event stage smoke keeps imageCount=5.
Actual note: BangDream moved to src/modules/qqbot/plugins/bangdream/src with third-phase plugin ownership: business code in domain/*, orchestration in application, operations in operations, external APIs in infrastructure/integration, cache/static patch adapters in infrastructure/storage, dictionary/static config in config, and visual helpers in theme. Added plugin.json with platform key bangdream; manifest operations are the single metadata source for stable operation keys, aliases, names, and worker-internal handlerName. Runtime registry now uses platform key bangdream as primary while resolving legacy bangDream; /qqbot/plugin/* local HTTP smoke now proves the controller returns platform keys and resolves legacy bangDream to bangdream. Verification passed via focused manifest/command SQL Jest, plugin migration contract, QQBot core module contract path guard, plugin controller HTTP smoke, pnpm run typecheck, and scripts/bangdream-render-smoke.ps1 -OperationKey bangdream.event.stage -Text 310, which produced imageCount=5.
Task 6.2: Rewrite FF14 Market, FFLogs, and Repeater
Files:
-
Create:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\qqbot\plugins\ff14-market\** -
Create:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\qqbot\plugins\fflogs\** -
Create:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\qqbot\plugins\repeater\** -
Test:
D:\MyFiles\KT\Node\kt-template-online-api\test\modules\qqbot\plugins\ff14-market\** -
Test:
D:\MyFiles\KT\Node\kt-template-online-api\test\modules\qqbot\plugins\fflogs\** -
Test:
D:\MyFiles\KT\Node\kt-template-online-api\test\modules\qqbot\plugins\repeater\** -
Step 1: FF14 Market
Use host runtime HTTP SDK for external requests. No direct axios client in plugin code.
- Step 2: FFLogs
Use plugin config for credential references. No real secret in manifest, tests, docs, or commits.
- Step 3: Repeater
Use host send queue and account binding. Do not bypass rate limit.
- Step 4: Verify
Run:
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api exec jest --runInBand --runTestsByPath test/qqbot/plugins/ff14-market/qqbot-ff14-worlds.spec.ts test/qqbot/plugins/fflogs/qqbot-fflogs-client.service.spec.ts test/qqbot/plugins/repeater/qqbot-repeater.plugin.spec.ts test/modules/qqbot/plugins/ff14-market test/modules/qqbot/plugins/fflogs test/modules/qqbot/plugins/repeater
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api run typecheck
Expected: PASS.
Actual note: FF14 Market, FFLogs, and Repeater moved to src/modules/qqbot/plugins/* and each now has a platform plugin.json plus real third-phase package structure. FF14 Market splits operation binding into operations, use cases into application, world/market types into domain, external clients into infrastructure/integration, and config into config; FFLogs splits character-summary operation, application use case, GraphQL/OAuth client, config, and token cache; Repeater splits event handler, repeat policy/domain state, runtime config, application state, and host integration. Verification passed via focused plugin Jest, migration direct-HTTP scan for FF14/FFLogs, /qqbot/plugin/list and /qqbot/plugin/operation/list local HTTP smoke, and pnpm run typecheck; final focused Jest covered 9 suites / 27 tests.
Task 6.3: Commit Batch 6
Run:
git -C D:\MyFiles\KT\Node\kt-template-online-api add src/modules/qqbot/plugins test/modules/qqbot/plugins sql/refactor-v3 docs/refactor-v3 API.md
git -C D:\MyFiles\KT\Node\kt-template-online-api commit -m "refactor: 重写现有QQBot插件"
Batch 7: NapCat Runtime
Task 7.1: Build NapCat device persistence model
Files:
-
Create:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\qqbot\napcat\device\** -
Create:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\qqbot\napcat\container\** -
Test:
D:\MyFiles\KT\Node\kt-template-online-api\test\modules\qqbot\napcat\device-identity.spec.ts -
Step 1: Write RED persistence test
Assert that rebuilding a container for the same account reuses data directory, hostname, machine-id path, and MAC address from napcat_device_identity.
- Step 2: Implement device identity service
Device identity owns container name, data dir, hostname, machine ID path, MAC, account binding, verification status, and last login evidence.
- Step 3: Verify
Run:
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api exec jest --runInBand --runTestsByPath test/modules/qqbot/napcat/device-identity.spec.ts
Expected: PASS.
Task 7.2: Build NapCat login state machine
Files:
-
Create:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\qqbot\napcat\login\** -
Test:
D:\MyFiles\KT\Node\kt-template-online-api\test\modules\qqbot\napcat\login-state-machine.spec.ts -
Step 1: Write RED state tests
Cover this order:
quick-login -> password-login -> captcha -> new-device -> manual-qr -> success/failure
Also cover cleanup failure blocking success.
- Step 2: Implement login session and challenge states
Keep captcha and new-device challenge state pending until explicitly resolved, expired, or failed.
- Step 3: Verify
Run:
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api exec jest --runInBand --runTestsByPath test/modules/qqbot/napcat/login-state-machine.spec.ts
Expected: PASS.
Task 7.3: Implement new-device NapCat API flow
Files:
-
Create:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\qqbot\napcat\integration\napcat-login-api.client.ts -
Test:
D:\MyFiles\KT\Node\kt-template-online-api\test\modules\qqbot\napcat\new-device-flow.spec.ts -
Step 1: Write RED new-device flow test
Test sequence:
GetNewDeviceQRCode -> PollNewDeviceQR -> NewDeviceLogin
Expected state mapping:
qr-pending -> scanned -> confirming -> verified
- Step 2: Implement client methods
Methods:
getNewDeviceQRCode(sessionId: string): Promise<NewDeviceQrCode>
pollNewDeviceQR(sessionId: string): Promise<NewDeviceQrStatus>
newDeviceLogin(sessionId: string): Promise<NewDeviceLoginResult>
- Step 3: Verify
Run:
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api exec jest --runInBand --runTestsByPath test/modules/qqbot/napcat/new-device-flow.spec.ts
Expected: PASS.
Task 7.4: Sync Admin NapCat login page and SSE Chinese progress
Files:
-
Create:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\api\qqbot\napcat.ts -
Modify:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\views\qqbot\account\** -
Create:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\views\qqbot\napcat\** -
Modify:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\router\routes\modules\qqbot.ts -
Step 1: Add Chinese progress labels
Labels include:
正在快速登录
快速登录失败,进入密码登录
正在密码登录
需要验证码
验证码已提交,等待确认
需要新设备验证二维码
新设备二维码待扫码
新设备二维码已扫码
新设备确认中
新设备验证成功,继续登录
正在生成手动二维码
登录成功
登录失败
运行态清理失败
- Step 2: Render captcha and new-device states separately
Do not display new-device QR as captcha. Do not clear captcha state only because a subsequent poll omits URL.
- Step 3: Verify Admin typecheck
Run:
pnpm --dir D:\MyFiles\KT\Vue\kt-template-admin -F @vben/web-antdv-next run typecheck
Expected: PASS.
Task 7.5: Run local NapCat simulated smoke
Use mocked NapCat responses or a local controlled container. Evidence must show:
- device identity reused after container rebuild
- captcha challenge remains pending
- new-device QR generated through
GetNewDeviceQRCode - poll transitions to scanned/confirming
NewDeviceLogincompletes- cleanup failure blocks success
Task 7.6: Commit Batch 7
Run:
git -C D:\MyFiles\KT\Node\kt-template-online-api add src/modules/qqbot/napcat test/modules/qqbot/napcat sql/refactor-v3 docs/refactor-v3 API.md
git -C D:\MyFiles\KT\Node\kt-template-online-api commit -m "feat: 重建NapCat设备与登录运行时"
git -C D:\MyFiles\KT\Vue\kt-template-admin add apps/web-antdv-next/src/api/qqbot apps/web-antdv-next/src/views/qqbot apps/web-antdv-next/src/router/routes/modules/qqbot.ts
git -C D:\MyFiles\KT\Vue\kt-template-admin commit -m "feat: 完成NapCat登录进度管理页"
Batch 8: Unified Local Closure, Push, Deploy, Online Smoke
Task 8.1: Final local verification
Run:
git -C D:\MyFiles\KT\Node\kt-template-online-api status --short --branch
git -C D:\MyFiles\KT\Vue\kt-template-admin status --short --branch
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api run typecheck
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api exec jest --runInBand
pnpm --dir D:\MyFiles\KT\Vue\kt-template-admin -F @vben/web-antdv-next run typecheck
git -C D:\MyFiles\KT\Node\kt-template-online-api diff --check
git -C D:\MyFiles\KT\Vue\kt-template-admin diff --check
Expected: all commands exit 0.
Task 8.2: Run local full smoke
Required smoke evidence:
/health/runtime- Admin login
- Admin menu
- Blog public list/detail
- Asset upload/read
- QQBot command test
- Plugin install/enable/health
- Rewritten plugin operation
- NapCat simulated login flow
Task 8.3: Ask user for push and DB rebuild window
Do not push or run online DB rebuild until the user explicitly confirms.
Task 8.4: Push and observe deployment
After confirmation, push both repos.
Run:
git -C D:\MyFiles\KT\Node\kt-template-online-api push -u origin dev-api-full-refactor-v3
git -C D:\MyFiles\KT\Vue\kt-template-admin push -u origin dev-admin-full-refactor-v3
Then collect Jenkins/K8s evidence:
- build number
- commit hash
- image tag
- Deployment generation and observedGeneration
- desired/updated/ready counts
- selected Pod image
- restart count
- Pod logs/events if failing
Task 8.5: Online DB rebuild
Before writes:
- state source database
- state target database
- state backup path
- state restore command
- state SQL scripts to apply
Run online backup first. Apply schema only after backup succeeds.
Task 8.6: Online full smoke
Required online evidence:
/health/runtimereturns service and status- Admin login succeeds
- Admin menu loads
- Blog public pages work
- plugin package install/enable/health succeeds
/qqbot/command/testuses operationKey-derived command ID and full command text- NapCat real account login completes through the actual required path for that account
- if new-device appears, evidence includes
GetNewDeviceQRCode -> PollNewDeviceQR -> NewDeviceLogin - response summaries strip
replyText
Task 8.7: Final closeout
Run MCP tools:
kt_change_doc_sync(project=api, taskType=deploy)
kt_change_doc_sync(project=admin, taskType=deploy)
kt_global_code_review(projects=["api","admin","root"], contentScanMode="changed", includeContentScan=true)
kt_cleanup_history(dryRun=true)
kt_workflow_loop_audit(stage="finish", requireCompletion=true)
Expected: required docs resolved, review findings resolved, cleanup final deleted count is 0, and closeout can report complete.
Cross-Batch Review Gates
Run these before every batch commit:
kt_change_doc_sync(...)
kt_global_code_review(...)
Run KT global review before claiming a batch is finished:
`KT global review`
If review finds a real Important issue, fix it and re-review before commit.
Plan Self-Review
Spec Coverage
| Spec Requirement | Plan Coverage |
|---|---|
| API/Admin dual-repo refactor | Tasks 0.1, 0.2, 2.2, 3.2, 4.2, 5.4, 7.4, 8.1-8.7 |
| Clean Admin authorized old artifacts during implementation preparation | Task 0.2 |
| Full database redesign and destructive rebuild with rollback | Tasks 0.3-0.5, 8.5 |
| Batch 0-8 local-first rhythm | Batch sections 0-8 and Cross-Batch Review Gates |
| Runtime/Common migration | Batch 1 |
| Admin/Auth/Platform Config migration | Batch 2 |
| Blog/WordPress/Asset migration | Batch 3 |
| QQBot Core migration | Batch 4 |
| QQBot Plugin Platform | Batch 5 |
| Existing plugin rewrite | Batch 6 |
| NapCat device persistence and login state machine | Batch 7 |
New-device flow GetNewDeviceQRCode -> PollNewDeviceQR -> NewDeviceLogin |
Task 7.3 |
| SSE/Admin Chinese progress | Task 7.4 |
| Unified push, Jenkins/K8s, DB rebuild, online smoke | Batch 8 |
Type And Path Consistency
- API plan paths use
D:\MyFiles\KT\Node\kt-template-online-api. - Admin plan paths use
D:\MyFiles\KT\Vue\kt-template-admin. - New API implementation root is consistently
src/modules/**. - Legacy API roots are removed only after matching batch compatibility checks pass.
- Admin IDs crossing the API boundary are consistently planned as
string.
Final Completion Criteria
The third phase is complete only when all of these are true:
- API branch contains Batch 0-8 commits.
- Admin branch contains every Admin contract sync commit.
- API/Admin local verification passes.
- Online backup and rollback path are recorded.
- New schema is applied online.
- Jenkins/K8s observation matches pushed commits.
- Online functional smoke passes.
- NapCat real account flow completes, including device persistence and new-device flow when triggered.
- TASKS and required docs are updated.
- KT global review are clean.
- No Node/Vite validation process started by the run remains alive.