kt-template-online-api/docs/plans/2026-06-15-api-admin-full-refactor-v3.md

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 branch dev-api-full-refactor-v3, package manager pnpm@9.15.9, no .node-version, no engines.
  • Admin repo: D:\MyFiles\KT\Vue\kt-template-admin, implementation branch dev-admin-full-refactor-v3, package manager pnpm@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.md
    • apps/web-antdv-next/src/api/qqbot/index.ts
    • apps/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, with api, views, router, components, store, locales.

Execution Rules

  • Use apply_patch for 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.md
    • D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\api\qqbot\index.ts
    • D:\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
  • NewDeviceLogin completes
  • 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/runtime returns service and status
  • Admin login succeeds
  • Admin menu loads
  • Blog public pages work
  • plugin package install/enable/health succeeds
  • /qqbot/command/test uses 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.