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

71 KiB

API/Admin Full Refactor V3 Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

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, Superpowers 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 Superpowers review before claiming a batch is finished:

superpowers:requesting-code-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 and Superpowers review are clean.
  • No Node/Vite validation process started by the run remains alive.