57 KiB
API/Admin Architecture Convergence 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: Make the third-phase target architecture true in code by migrating all API legacy roots into src/modules/**, enforcing structure tests, slimming every API/Admin domain, preserving behavior, and deleting src/admin, src/blog, src/minio, src/wordpress, and src/qqbot.
Architecture: Work from hard RED structure gates, then migrate one domain at a time. Each domain task includes three inseparable pieces: move ownership into the target module, remove duplicate/unused transitional code, and run behavior checks that prove existing routes and Admin pages still work. The final task deletes old roots and runs the full convergence gate.
Tech Stack: NestJS 11, TypeORM 0.3, MySQL, Jest, pnpm 9 API workspace, Vben Admin 5, Vue 3 TSX/Vue SFC, Vitest, pnpm 10 Admin workspace, ktWorkflow global review, KT global review.
Scope Check
This plan covers two repos because the approved spec requires API and Admin to converge together:
- API repo:
D:\MyFiles\KT\Node\kt-template-online-api, branchdev-api-architecture-convergence-v3. - Admin repo:
D:\MyFiles\KT\Vue\kt-template-admin, branchdev-admin-architecture-convergence-v3. - Root repo:
D:\MyFiles\KT, branchmain, used only forTASKS.mdrecord updates.
The work is one architecture-convergence batch, not a new product phase. Do not split into an API-only plan and an Admin-only plan; the Admin caller/page slimming is part of the same completion gate.
Current State Evidence
API old roots currently exist:
| Root | Files | Directories |
|---|---|---|
src/admin |
42 | 11 |
src/blog |
13 | 0 |
src/minio |
5 | 0 |
src/wordpress |
9 | 0 |
src/qqbot |
55 | 14 |
src/modules/** currently imports old roots:
| Alias | Hits |
|---|---|
@/admin/ |
37 |
@/blog/ |
7 |
@/minio/ |
3 |
@/wordpress/ |
7 |
@/qqbot/ |
50 |
Admin current touched domains:
- API callers:
apps/web-antdv-next/src/api/system/**,apps/web-antdv-next/src/api/blog/**,apps/web-antdv-next/src/api/qqbot/**. - Pages:
apps/web-antdv-next/src/views/system/**,apps/web-antdv-next/src/views/blog/**,apps/web-antdv-next/src/views/qqbot/**.
Execution Rules
- Do not push.
- Do not deploy.
- Do not run online database writes.
- Do not create
.worktree. - Use
apply_patchfor manual code edits. - Use
git mvfor file moves when practical so history stays readable. - Before deleting a file, run
rgfor the exported class/function/type and for the relative path stem. - Every task must leave the repo status understandable: only paths named by the task should be changed.
- Every domain migration must record its slimming decisions in
docs/refactor-v3/architecture-convergence-inventory.md. - If a domain has a feature that is only reachable by reflection, SQL seed, menu route, plugin manifest, or Nest DI, prove it with a test or smoke before deleting it.
- Keep route paths and response shapes stable unless the task explicitly updates Admin callers and smoke evidence.
File Structure Map
API Files To Create
| Path | Responsibility |
|---|---|
test/refactor-v3/architecture-convergence.spec.ts |
Hard API structure gate for old roots, forbidden imports, target modules, and app module imports. |
docs/refactor-v3/architecture-convergence-inventory.md |
Per-domain slimming evidence: delete, merge, keep, and uncertain decisions. |
docs/refactor-v3/architecture-convergence-verification.md |
Final command evidence and smoke summary. |
API Files To Move Or Rewrite
| Source | Target |
|---|---|
src/admin/auth/** |
src/modules/admin/identity/auth/** |
src/admin/user/** |
src/modules/admin/identity/user/** |
src/admin/role/** |
src/modules/admin/identity/role/** |
src/admin/menu/** |
src/modules/admin/identity/menu/** |
src/admin/dept/** |
src/modules/admin/identity/dept/** |
src/admin/admin.types.ts |
src/modules/admin/contract/admin.types.ts |
src/admin/component/** |
src/modules/admin/platform-config/component/** |
src/admin/dict/** |
src/modules/admin/platform-config/dict/** |
src/admin/notice/** |
src/modules/admin/platform-config/notice/** |
src/admin/system-log/** |
src/modules/admin/platform-config/system-log/** |
src/admin/timezone/** |
src/modules/admin/platform-config/timezone/** |
src/admin/example/** |
Delete unless route/menu/test evidence proves it is active. |
src/blog/** |
src/modules/blog/**, split controller/DTO/service/entity by local responsibility. |
src/wordpress/** |
src/modules/wordpress/**, split controller/DTO/service/types by local responsibility. |
src/minio/** |
src/modules/asset/**, keep /minio/* routes but remove old source root. |
src/qqbot/account/qqbot-napcat-login.service.ts |
src/modules/qqbot/napcat/login/qqbot-napcat-login.service.ts |
src/qqbot/account/qqbot-napcat-watchdog.service.ts |
src/modules/qqbot/napcat/login/qqbot-napcat-watchdog.service.ts |
src/qqbot/napcat/** |
src/modules/qqbot/napcat/** |
src/qqbot/account/** except NapCat login services |
src/modules/qqbot/core/account/** |
src/qqbot/command/** |
src/modules/qqbot/core/command/** |
src/qqbot/config/** |
src/modules/qqbot/core/config/** |
src/qqbot/connection/** |
src/modules/qqbot/core/connection/** |
src/qqbot/dashboard/** |
src/modules/qqbot/core/dashboard/** |
src/qqbot/dedupe/** |
src/modules/qqbot/core/dedupe/** |
src/qqbot/event/** |
src/modules/qqbot/core/event/** |
src/qqbot/message/** |
src/modules/qqbot/core/message/** |
src/qqbot/mqtt/** |
src/modules/qqbot/core/mqtt/** |
src/qqbot/permission/** |
src/modules/qqbot/core/permission/** |
src/qqbot/rule/** |
src/modules/qqbot/core/rule/** |
src/qqbot/send/** |
src/modules/qqbot/core/send/** |
src/qqbot/plugin/** |
Replace with src/modules/qqbot/plugin-platform/** contracts or delete old registry. |
src/qqbot/qqbot.types.ts |
src/modules/qqbot/core/contract/qqbot.types.ts |
src/qqbot/qqbot.constants.ts |
src/modules/qqbot/core/contract/qqbot.constants.ts |
src/qqbot/qqbot-cooldown.policy.ts |
src/modules/qqbot/core/domain/qqbot-cooldown.policy.ts |
src/qqbot/qqbot.module.ts |
Delete after QqbotCoreModule and QqbotPluginPlatformModule own all providers. |
Admin Files To Create Or Modify
| Path | Responsibility |
|---|---|
apps/web-antdv-next/src/api/qqbot/index.ts |
QQBot core caller/type boundary. |
apps/web-antdv-next/src/api/qqbot/plugin.ts |
Plugin platform caller/type boundary. |
apps/web-antdv-next/src/api/qqbot/napcat.ts |
NapCat device/login/SSE helpers and Chinese progress labels. |
apps/web-antdv-next/src/api/system/*.ts |
System caller cleanup and type de-duplication. |
apps/web-antdv-next/src/api/blog/*.ts |
Blog/WordPress/Asset caller cleanup and type de-duplication. |
apps/web-antdv-next/src/views/system/** |
System page slimming and route/menu consistency. |
apps/web-antdv-next/src/views/blog/** |
Blog/WordPress/Asset page slimming and shared list/upload/import state. |
apps/web-antdv-next/src/views/qqbot/modules/status.ts |
Shared QQBot status/tag/progress mappings. |
apps/web-antdv-next/src/views/qqbot/modules/actions.tsx |
Shared QQBot table and operation actions. |
apps/web-antdv-next/src/views/qqbot/** |
QQBot Core, Plugin Platform, and NapCat page cleanup. |
apps/web-antdv-next/src/api/qqbot/napcat.spec.ts |
Keep and extend NapCat helper tests. |
Task 0: Preflight And Inventory Baseline
Files:
-
Create:
D:\MyFiles\KT\Node\kt-template-online-api\docs\refactor-v3\architecture-convergence-inventory.md -
Modify:
D:\MyFiles\KT\TASKS.md -
Step 1: Confirm clean repos and branches
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
git -C D:\MyFiles\KT status --short --branch
Expected:
## dev-api-architecture-convergence-v3
## dev-admin-architecture-convergence-v3
## main
- Step 2: Confirm package managers
Run:
Get-Content D:\MyFiles\KT\Node\kt-template-online-api\package.json | Select-String '"packageManager"'
Get-Content D:\MyFiles\KT\Vue\kt-template-admin\package.json | Select-String '"packageManager"|"engines"'
Get-Content D:\MyFiles\KT\Vue\kt-template-admin\.node-version
Expected:
"packageManager": "pnpm@9.15.9+sha512
"packageManager": "pnpm@10.28.2"
22.22.0
- Step 3: Add inventory document
Use apply_patch to create D:\MyFiles\KT\Node\kt-template-online-api\docs\refactor-v3\architecture-convergence-inventory.md:
# Architecture Convergence Inventory
## Baseline
| Area | Current Evidence | Target Evidence |
| --- | --- | --- |
| API legacy roots | `src/admin`, `src/blog`, `src/minio`, `src/wordpress`, `src/qqbot` exist. | These paths do not exist. |
| API forbidden module imports | `src/modules/**` imports old roots. | No import from `@/admin`, `@/blog`, `@/minio`, `@/wordpress`, or `@/qqbot`. |
| Admin System | System pages and callers exist under `views/system` and `api/system`. | No duplicate caller/type/page state after cleanup. |
| Admin Blog/Asset | Blog, WordPress, and Asset callers/pages exist under `api/blog` and `views/blog`. | Shared list/upload/import state where behavior repeats. |
| Admin QQBot | QQBot callers/pages exist under `api/qqbot` and `views/qqbot`. | Core, Plugin Platform, and NapCat state boundaries are explicit. |
## Domain Decisions
| Domain | Deleted | Merged | Kept | Evidence |
| --- | --- | --- | --- | --- |
| Admin/Auth/Platform Config | none yet | none yet | current files before migration | baseline only |
| Blog/WordPress/Asset | none yet | none yet | current files before migration | baseline only |
| Runtime/Common | none yet | none yet | current files before migration | baseline only |
| QQBot Core/NapCat | none yet | none yet | current files before migration | baseline only |
| Plugin Platform/Plugins | none yet | none yet | current files before migration | baseline only |
| Admin UI | none yet | none yet | current files before migration | baseline only |
- Step 4: Run baseline scans
Run:
$api = 'D:\MyFiles\KT\Node\kt-template-online-api'
$roots = @('src/admin','src/blog','src/minio','src/wordpress','src/qqbot')
foreach ($root in $roots) {
$path = Join-Path $api $root
if (Test-Path $path) {
$files = @(rg --files $path)
Write-Output "$root files=$($files.Count)"
}
}
rg -n '@/(admin|blog|minio|wordpress|qqbot)/' D:\MyFiles\KT\Node\kt-template-online-api\src\modules
Expected: old roots and forbidden imports are present before migration.
- Step 5: Commit baseline inventory
Run:
git -C D:\MyFiles\KT\Node\kt-template-online-api add docs/refactor-v3/architecture-convergence-inventory.md
git -C D:\MyFiles\KT\Node\kt-template-online-api commit -m "docs: 建立架构收敛清理清单"
Expected: commit succeeds and includes only the inventory document.
Task 1: API RED Structure Gate
Files:
-
Create:
D:\MyFiles\KT\Node\kt-template-online-api\test\refactor-v3\architecture-convergence.spec.ts -
Step 1: Write failing structure test
Create D:\MyFiles\KT\Node\kt-template-online-api\test\refactor-v3\architecture-convergence.spec.ts with this content:
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
import { join, relative } from 'node:path';
const repoRoot = join(__dirname, '..', '..');
const srcRoot = join(repoRoot, 'src');
const legacyRoots = ['admin', 'blog', 'minio', 'wordpress', 'qqbot'];
const moduleRoots = ['admin', 'asset', 'blog', 'wordpress', 'qqbot'];
const qqbotRoots = ['core', 'napcat', 'plugin-platform', 'plugins'];
function listFiles(dir: string): string[] {
if (!existsSync(dir)) return [];
return readdirSync(dir).flatMap((entry) => {
const absolute = join(dir, entry);
const stat = statSync(absolute);
if (stat.isDirectory()) return listFiles(absolute);
return [absolute];
});
}
function readTextFiles(dir: string): Array<{ file: string; text: string }> {
return listFiles(dir)
.filter((file) => /\.(ts|tsx|vue|js|mjs|cjs)$/.test(file))
.map((file) => ({
file: relative(repoRoot, file).replace(/\\/g, '/'),
text: readFileSync(file, 'utf8'),
}));
}
describe('architecture convergence', () => {
it('does not keep API legacy source roots', () => {
const existing = legacyRoots.filter((root) =>
existsSync(join(srcRoot, root)),
);
expect(existing).toEqual([]);
});
it('keeps all business modules under src/modules', () => {
const missing = moduleRoots.filter(
(root) => !existsSync(join(srcRoot, 'modules', root)),
);
expect(missing).toEqual([]);
});
it('keeps QQBot subdomains under src/modules/qqbot', () => {
const missing = qqbotRoots.filter(
(root) => !existsSync(join(srcRoot, 'modules', 'qqbot', root)),
);
expect(missing).toEqual([]);
});
it('does not import old roots from src/modules', () => {
const forbidden = /@\/(?:admin|blog|minio|wordpress|qqbot)\//;
const offenders = readTextFiles(join(srcRoot, 'modules'))
.filter(({ text }) => forbidden.test(text))
.map(({ file }) => file);
expect(offenders).toEqual([]);
});
it('does not import old roots from app module', () => {
const appModule = readFileSync(join(srcRoot, 'app.module.ts'), 'utf8');
expect(appModule).not.toMatch(/from ['"]\.\/(?:admin|blog|minio|wordpress|qqbot)/);
expect(appModule).not.toMatch(/from ['"]@\/(?:admin|blog|minio|wordpress|qqbot)\//);
});
});
- Step 2: Run the RED test
Run:
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api exec jest --runInBand --runTestsByPath test/refactor-v3/architecture-convergence.spec.ts
Expected: FAIL. The failure must mention existing old roots and forbidden imports.
- Step 3: Commit the RED gate
Run:
git -C D:\MyFiles\KT\Node\kt-template-online-api add test/refactor-v3/architecture-convergence.spec.ts
git -C D:\MyFiles\KT\Node\kt-template-online-api commit -m "test: 增加架构收敛结构门禁"
Expected: commit succeeds with the failing test. The failure is intentional and will turn green after migration.
Task 2: Admin/Auth/Platform Config Migration And Slimming
Files:
-
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\admin\auth\** -
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\admin\user\** -
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\admin\role\** -
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\admin\menu\** -
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\admin\dept\** -
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\admin\component\** -
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\admin\dict\** -
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\admin\notice\** -
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\admin\system-log\** -
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\admin\timezone\** -
Modify:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\admin\identity\admin-identity.module.ts -
Modify:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\admin\platform-config\admin-platform-config.module.ts -
Modify:
D:\MyFiles\KT\Node\kt-template-online-api\docs\refactor-v3\architecture-convergence-inventory.md -
Tests:
D:\MyFiles\KT\Node\kt-template-online-api\test\modules\admin\admin-contract.spec.ts -
Tests:
D:\MyFiles\KT\Node\kt-template-online-api\test\admin\** -
Step 1: Move Admin identity files
Run:
$api = 'D:\MyFiles\KT\Node\kt-template-online-api'
New-Item -ItemType Directory -Force -Path "$api\src\modules\admin\identity\auth" | Out-Null
New-Item -ItemType Directory -Force -Path "$api\src\modules\admin\identity\user" | Out-Null
New-Item -ItemType Directory -Force -Path "$api\src\modules\admin\identity\role" | Out-Null
New-Item -ItemType Directory -Force -Path "$api\src\modules\admin\identity\menu" | Out-Null
New-Item -ItemType Directory -Force -Path "$api\src\modules\admin\identity\dept" | Out-Null
git -C $api mv src/admin/auth/* src/modules/admin/identity/auth/
git -C $api mv src/admin/user/* src/modules/admin/identity/user/
git -C $api mv src/admin/role/* src/modules/admin/identity/role/
git -C $api mv src/admin/menu/* src/modules/admin/identity/menu/
git -C $api mv src/admin/dept/* src/modules/admin/identity/dept/
git -C $api mv src/admin/admin.types.ts src/modules/admin/contract/admin.types.ts
Expected: moved files appear under src/modules/admin/identity/** and src/modules/admin/contract/admin.types.ts.
- Step 2: Move platform config files
Run:
$api = 'D:\MyFiles\KT\Node\kt-template-online-api'
New-Item -ItemType Directory -Force -Path "$api\src\modules\admin\platform-config\component" | Out-Null
New-Item -ItemType Directory -Force -Path "$api\src\modules\admin\platform-config\dict" | Out-Null
New-Item -ItemType Directory -Force -Path "$api\src\modules\admin\platform-config\notice" | Out-Null
New-Item -ItemType Directory -Force -Path "$api\src\modules\admin\platform-config\system-log" | Out-Null
New-Item -ItemType Directory -Force -Path "$api\src\modules\admin\platform-config\timezone" | Out-Null
git -C $api mv src/admin/component/* src/modules/admin/platform-config/component/
git -C $api mv src/admin/dict/* src/modules/admin/platform-config/dict/
git -C $api mv src/admin/notice/* src/modules/admin/platform-config/notice/
git -C $api mv src/admin/system-log/* src/modules/admin/platform-config/system-log/
git -C $api mv src/admin/timezone/* src/modules/admin/platform-config/timezone/
Expected: moved files appear under src/modules/admin/platform-config/**.
- Step 3: Decide and remove Admin example
Run:
$api = 'D:\MyFiles\KT\Node\kt-template-online-api'
rg -n 'AdminExampleController|admin/example|example' "$api\src" "$api\sql" "$api\test"
Expected: if the only source entry is src/admin/example/admin-example.controller.ts, delete it. If a menu, SQL seed, or test proves it is active, move it to src/modules/admin/platform-config/example/ and add a contract test for the route.
For the delete path, run:
git -C D:\MyFiles\KT\Node\kt-template-online-api rm -r src/admin/example
- Step 4: Update imports to target Admin paths
Replace imports using these mappings:
@/admin/auth/ -> @/modules/admin/identity/auth/
@/admin/user/ -> @/modules/admin/identity/user/
@/admin/role/ -> @/modules/admin/identity/role/
@/admin/menu/ -> @/modules/admin/identity/menu/
@/admin/dept/ -> @/modules/admin/identity/dept/
@/admin/component/ -> @/modules/admin/platform-config/component/
@/admin/dict/ -> @/modules/admin/platform-config/dict/
@/admin/notice/ -> @/modules/admin/platform-config/notice/
@/admin/system-log/ -> @/modules/admin/platform-config/system-log/
@/admin/timezone/ -> @/modules/admin/platform-config/timezone/
@/admin/admin.types -> @/modules/admin/contract/admin.types
Run a focused check:
rg -n '@\/admin\/' D:\MyFiles\KT\Node\kt-template-online-api\src D:\MyFiles\KT\Node\kt-template-online-api\test
Expected: no @/admin/ imports remain in API source or tests.
- Step 5: Rewrite admin module imports
Update:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\admin\identity\admin-identity.module.ts
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\admin\platform-config\admin-platform-config.module.ts
The module files must import controllers, services, entities, and submodules from @/modules/admin/**, not from @/admin/**.
- Step 6: Update inventory
Append to docs/refactor-v3/architecture-convergence-inventory.md:
| Admin/Auth/Platform Config | `src/admin/example` if no active route evidence; empty old admin subdirectories | auth/user/role/menu/dept/component/dict/notice/system-log/timezone moved into `src/modules/admin/**`; duplicate old imports removed | route paths and public DTO class names kept | `rg '@/admin/' src test` returns no source hits; admin focused Jest passes |
- Step 7: Verify Admin API domain
Run:
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api exec jest --runInBand --runTestsByPath test/modules/admin/admin-contract.spec.ts 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.controller.spec.ts test/admin/notice/admin-notice.service.spec.ts test/admin/system-log/system-log.controller.spec.ts test/admin/system-log/system-log.service.spec.ts
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api run typecheck
Expected: PASS.
- Step 8: Commit Admin API migration
Run:
git -C D:\MyFiles\KT\Node\kt-template-online-api add src/modules/admin test docs/refactor-v3/architecture-convergence-inventory.md
git -C D:\MyFiles\KT\Node\kt-template-online-api add -u src/admin src/modules/admin test
git -C D:\MyFiles\KT\Node\kt-template-online-api commit -m "refactor: 收敛Admin与平台配置模块"
Expected: commit succeeds. src/admin may still exist if non-empty from cross-domain imports, but no code should import @/admin/.
Task 3: Blog, WordPress, And Asset Migration And Slimming
Files:
-
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\blog\** -
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\wordpress\** -
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\minio\** -
Modify:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\blog\blog-content.module.ts -
Modify:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\wordpress\wordpress-mirror.module.ts -
Modify:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\asset\asset.module.ts -
Modify:
D:\MyFiles\KT\Node\kt-template-online-api\docs\refactor-v3\architecture-convergence-inventory.md -
Tests:
D:\MyFiles\KT\Node\kt-template-online-api\test\modules\blog\blog-module-contract.spec.ts -
Tests:
D:\MyFiles\KT\Node\kt-template-online-api\test\modules\wordpress\wordpress-module-contract.spec.ts -
Tests:
D:\MyFiles\KT\Node\kt-template-online-api\test\modules\asset\asset-module-contract.spec.ts -
Tests:
D:\MyFiles\KT\Node\kt-template-online-api\test\blog\** -
Tests:
D:\MyFiles\KT\Node\kt-template-online-api\test\wordpress\wordpress.service.spec.ts -
Step 1: Move Blog files into target subfolders
Run:
$api = 'D:\MyFiles\KT\Node\kt-template-online-api'
New-Item -ItemType Directory -Force -Path "$api\src\modules\blog\contract" | Out-Null
New-Item -ItemType Directory -Force -Path "$api\src\modules\blog\application" | Out-Null
New-Item -ItemType Directory -Force -Path "$api\src\modules\blog\infrastructure\persistence" | Out-Null
git -C $api mv src/blog/*controller.ts src/modules/blog/contract/
git -C $api mv src/blog/*dto.ts src/modules/blog/contract/
git -C $api mv src/blog/*service.ts src/modules/blog/application/
git -C $api mv src/blog/*entity.ts src/modules/blog/infrastructure/persistence/
git -C $api mv src/blog/blog.module.ts src/modules/blog/blog-content.legacy-module.ts
Expected: old src/blog has no files after the move.
- Step 2: Move WordPress files into target subfolders
Run:
$api = 'D:\MyFiles\KT\Node\kt-template-online-api'
New-Item -ItemType Directory -Force -Path "$api\src\modules\wordpress\contract" | Out-Null
New-Item -ItemType Directory -Force -Path "$api\src\modules\wordpress\application" | Out-Null
New-Item -ItemType Directory -Force -Path "$api\src\modules\wordpress\domain" | Out-Null
git -C $api mv src/wordpress/*controller.ts src/modules/wordpress/contract/
git -C $api mv src/wordpress/*dto.ts src/modules/wordpress/contract/
git -C $api mv src/wordpress/*types.ts src/modules/wordpress/domain/
git -C $api mv src/wordpress/*service.ts src/modules/wordpress/application/
git -C $api mv src/wordpress/wordpress.module.ts src/modules/wordpress/wordpress-mirror.legacy-module.ts
Expected: old src/wordpress has no files after the move.
- Step 3: Move MinIO files into Asset module
Run:
$api = 'D:\MyFiles\KT\Node\kt-template-online-api'
New-Item -ItemType Directory -Force -Path "$api\src\modules\asset\contract" | Out-Null
New-Item -ItemType Directory -Force -Path "$api\src\modules\asset\application" | Out-Null
New-Item -ItemType Directory -Force -Path "$api\src\modules\asset\domain" | Out-Null
git -C $api mv src/minio/minio.controller.ts src/modules/asset/contract/asset-minio.controller.ts
git -C $api mv src/minio/minio.dto.ts src/modules/asset/contract/asset-minio.dto.ts
git -C $api mv src/minio/minio.service.ts src/modules/asset/application/asset-minio.service.ts
git -C $api mv src/minio/minio.types.ts src/modules/asset/domain/asset-minio.types.ts
git -C $api mv src/minio/minio.module.ts src/modules/asset/asset-minio.legacy-module.ts
Expected: old src/minio has no files after the move. Public route decorators may remain /minio/*.
- Step 4: Update imports for Blog/WordPress/Asset
Replace imports using these mappings:
@/blog/ -> @/modules/blog/
@/wordpress/ -> @/modules/wordpress/
@/minio/minio.controller -> @/modules/asset/contract/asset-minio.controller
@/minio/minio.dto -> @/modules/asset/contract/asset-minio.dto
@/minio/minio.service -> @/modules/asset/application/asset-minio.service
@/minio/minio.types -> @/modules/asset/domain/asset-minio.types
@/minio/minio.module -> @/modules/asset/asset-minio.legacy-module
Run:
rg -n '@\/(blog|wordpress|minio)\/' D:\MyFiles\KT\Node\kt-template-online-api\src D:\MyFiles\KT\Node\kt-template-online-api\test
Expected: no old Blog, WordPress, or MinIO imports remain.
- Step 5: Collapse legacy module wrappers
Update these module files so they import local target classes directly and do not import the moved *.legacy-module.ts wrappers:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\blog\blog-content.module.ts
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\wordpress\wordpress-mirror.module.ts
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\asset\asset.module.ts
After each module imports local controllers/services/entities directly, delete:
git -C D:\MyFiles\KT\Node\kt-template-online-api rm src/modules/blog/blog-content.legacy-module.ts
git -C D:\MyFiles\KT\Node\kt-template-online-api rm src/modules/wordpress/wordpress-mirror.legacy-module.ts
git -C D:\MyFiles\KT\Node\kt-template-online-api rm src/modules/asset/asset-minio.legacy-module.ts
- Step 6: Run slimming scans for Blog/WordPress/Asset
Run:
rg -n 'BlogModule|WordpressModule|MinioClientModule|MinioClientService|MinioUploadFile' D:\MyFiles\KT\Node\kt-template-online-api\src D:\MyFiles\KT\Node\kt-template-online-api\test
rg -n 'blog-content\.legacy|wordpress-mirror\.legacy|asset-minio\.legacy' D:\MyFiles\KT\Node\kt-template-online-api\src D:\MyFiles\KT\Node\kt-template-online-api\test
Expected: old module wrapper names have no hits. Public class names may remain only when route behavior or tests depend on them.
- Step 7: Update inventory
Append:
| Blog/WordPress/Asset | old `src/blog`, `src/wordpress`, `src/minio`; legacy module wrappers after local imports replaced | MinIO internal files renamed into Asset module; Blog and WordPress controller/service/entity files moved under target modules | existing route decorators and response DTO behavior | `rg '@/blog/|@/wordpress/|@/minio/' src test` has no hits; Blog/WordPress/Asset focused tests pass |
- Step 8: Verify Blog/WordPress/Asset
Run:
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api exec jest --runInBand --runTestsByPath test/modules/blog/blog-module-contract.spec.ts test/modules/wordpress/wordpress-module-contract.spec.ts test/modules/asset/asset-module-contract.spec.ts test/blog/blog-article.service.spec.ts test/blog/blog-term.service.spec.ts test/blog/blog-theme-config.service.spec.ts test/wordpress/wordpress.service.spec.ts
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api run typecheck
Expected: PASS.
- Step 9: Commit Blog/WordPress/Asset migration
Run:
git -C D:\MyFiles\KT\Node\kt-template-online-api add src/modules/blog src/modules/wordpress src/modules/asset test docs/refactor-v3/architecture-convergence-inventory.md
git -C D:\MyFiles\KT\Node\kt-template-online-api add -u src/blog src/wordpress src/minio src/modules/blog src/modules/wordpress src/modules/asset test
git -C D:\MyFiles\KT\Node\kt-template-online-api commit -m "refactor: 收敛Blog WordPress Asset模块"
Expected: commit succeeds.
Task 4: QQBot Core And NapCat Migration And Slimming
Files:
-
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\qqbot\account\** -
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\qqbot\command\** -
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\qqbot\config\** -
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\qqbot\connection\** -
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\qqbot\dashboard\** -
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\qqbot\dedupe\** -
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\qqbot\event\** -
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\qqbot\message\** -
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\qqbot\mqtt\** -
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\qqbot\permission\** -
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\qqbot\rule\** -
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\qqbot\send\** -
Move:
D:\MyFiles\KT\Node\kt-template-online-api\src\qqbot\napcat\** -
Modify:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\qqbot\core\qqbot-core.module.ts -
Modify:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\qqbot\napcat\** -
Modify:
D:\MyFiles\KT\Node\kt-template-online-api\docs\refactor-v3\architecture-convergence-inventory.md -
Tests:
D:\MyFiles\KT\Node\kt-template-online-api\test\modules\qqbot\core\** -
Tests:
D:\MyFiles\KT\Node\kt-template-online-api\test\modules\qqbot\napcat\** -
Tests:
D:\MyFiles\KT\Node\kt-template-online-api\test\qqbot\** -
Step 1: Move QQBot core directories
Run:
$api = 'D:\MyFiles\KT\Node\kt-template-online-api'
$core = "$api\src\modules\qqbot\core"
foreach ($name in @('account','command','config','connection','dashboard','dedupe','event','message','mqtt','permission','rule','send')) {
New-Item -ItemType Directory -Force -Path "$core\$name" | Out-Null
git -C $api mv "src/qqbot/$name/*" "src/modules/qqbot/core/$name/"
}
New-Item -ItemType Directory -Force -Path "$core\contract" | Out-Null
New-Item -ItemType Directory -Force -Path "$core\domain" | Out-Null
git -C $api mv src/qqbot/qqbot.types.ts src/modules/qqbot/core/contract/qqbot.types.ts
git -C $api mv src/qqbot/qqbot.constants.ts src/modules/qqbot/core/contract/qqbot.constants.ts
git -C $api mv src/qqbot/qqbot-cooldown.policy.ts src/modules/qqbot/core/domain/qqbot-cooldown.policy.ts
Expected: core files are under src/modules/qqbot/core/**.
- Step 2: Move NapCat runtime files
Run:
$api = 'D:\MyFiles\KT\Node\kt-template-online-api'
$napcat = "$api\src\modules\qqbot\napcat"
New-Item -ItemType Directory -Force -Path "$napcat\login" | Out-Null
New-Item -ItemType Directory -Force -Path "$napcat\infrastructure\persistence" | Out-Null
git -C $api mv src/modules/qqbot/core/account/qqbot-napcat-login.service.ts src/modules/qqbot/napcat/login/qqbot-napcat-login.service.ts
git -C $api mv src/modules/qqbot/core/account/qqbot-napcat-watchdog.service.ts src/modules/qqbot/napcat/login/qqbot-napcat-watchdog.service.ts
git -C $api mv src/qqbot/napcat/qqbot-account-napcat.entity.ts src/modules/qqbot/napcat/infrastructure/persistence/qqbot-account-napcat.entity.ts
git -C $api mv src/qqbot/napcat/qqbot-napcat-container.entity.ts src/modules/qqbot/napcat/infrastructure/persistence/qqbot-napcat-container.entity.ts
git -C $api mv src/qqbot/napcat/qqbot-napcat-container.service.ts src/modules/qqbot/napcat/qqbot-napcat-container.service.ts
Expected: NapCat files are under src/modules/qqbot/napcat/**.
- Step 3: Remove old QQBot module wrapper after providers are local
Update src/modules/qqbot/core/qqbot-core.module.ts so it imports from @/modules/qqbot/core/** and @/modules/qqbot/napcat/**.
Run:
rg -n '@\/qqbot\/' D:\MyFiles\KT\Node\kt-template-online-api\src\modules\qqbot\core D:\MyFiles\KT\Node\kt-template-online-api\src\modules\qqbot\napcat
Expected: no hits in core or napcat modules.
After all providers are local, delete old wrapper:
git -C D:\MyFiles\KT\Node\kt-template-online-api rm src/qqbot/qqbot.module.ts
- Step 4: Update source and test imports
Replace:
@/qqbot/account/ -> @/modules/qqbot/core/account/
@/qqbot/command/ -> @/modules/qqbot/core/command/
@/qqbot/config/ -> @/modules/qqbot/core/config/
@/qqbot/connection/ -> @/modules/qqbot/core/connection/
@/qqbot/dashboard/ -> @/modules/qqbot/core/dashboard/
@/qqbot/dedupe/ -> @/modules/qqbot/core/dedupe/
@/qqbot/event/ -> @/modules/qqbot/core/event/
@/qqbot/message/ -> @/modules/qqbot/core/message/
@/qqbot/mqtt/ -> @/modules/qqbot/core/mqtt/
@/qqbot/permission/ -> @/modules/qqbot/core/permission/
@/qqbot/rule/ -> @/modules/qqbot/core/rule/
@/qqbot/send/ -> @/modules/qqbot/core/send/
@/qqbot/napcat/ -> @/modules/qqbot/napcat/
@/qqbot/qqbot.types -> @/modules/qqbot/core/contract/qqbot.types
@/qqbot/qqbot.constants -> @/modules/qqbot/core/contract/qqbot.constants
@/qqbot/qqbot-cooldown.policy -> @/modules/qqbot/core/domain/qqbot-cooldown.policy
Run:
rg -n '@\/qqbot\/' D:\MyFiles\KT\Node\kt-template-online-api\src D:\MyFiles\KT\Node\kt-template-online-api\test
Expected: only plugin-platform migration leftovers may remain before Task 5; no core or napcat imports should target old roots.
- Step 5: Run QQBot core and NapCat slimming scans
Run:
rg -n 'QqbotModule|@\/qqbot\/qqbot\.module|qqbot-napcat-login\.service|qqbot-napcat-watchdog\.service' D:\MyFiles\KT\Node\kt-template-online-api\src D:\MyFiles\KT\Node\kt-template-online-api\test
rg -n 'quick-login|password-login|new-device|CaptchaLogin|GetNewDeviceQRCode|PollNewDeviceQR|NewDeviceLogin' D:\MyFiles\KT\Node\kt-template-online-api\src\modules\qqbot\napcat D:\MyFiles\KT\Node\kt-template-online-api\test\modules\qqbot\napcat
Expected: old QqbotModule has no hits. NapCat login flow terms remain in target module and tests.
- Step 6: Update inventory
Append:
| QQBot Core/NapCat | old `src/qqbot/qqbot.module.ts`; old core and napcat roots after moves | account/command/config/connection/dashboard/dedupe/event/message/mqtt/permission/rule/send moved into `src/modules/qqbot/core`; NapCat login/container/persistence moved into `src/modules/qqbot/napcat` | route decorators, command parsing, send queue, device persistence, captcha, new-device, and manual QR semantics | core and NapCat focused Jest pass; `rg '@/qqbot/' src/modules/qqbot/core src/modules/qqbot/napcat` has no hits |
- Step 7: Verify QQBot core and NapCat
Run:
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api exec jest --runInBand --runTestsByPath test/modules/qqbot/core/qqbot-core-module-contract.spec.ts test/modules/qqbot/core/qqbot-core-command-contract.spec.ts test/modules/qqbot/core/qqbot-core-command-smoke.spec.ts test/modules/qqbot/core/qqbot-core-send-contract.spec.ts test/modules/qqbot/core/qqbot-core-status-contract.spec.ts test/modules/qqbot/napcat/device-identity.spec.ts test/modules/qqbot/napcat/login-state-machine.spec.ts test/modules/qqbot/napcat/new-device-flow.spec.ts test/qqbot/connection/qqbot-reverse-ws.service.spec.ts test/qqbot/send/qqbot-send.service.spec.ts test/qqbot/send/qqbot-rate-limit.service.spec.ts test/qqbot/command/qqbot-command-parser.service.spec.ts test/qqbot/account/qqbot-account.service.spec.ts test/qqbot/account/qqbot-napcat-login.service.spec.ts test/qqbot/account/qqbot-napcat-watchdog.service.spec.ts
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api run typecheck
Expected: PASS.
- Step 8: Commit QQBot core and NapCat migration
Run:
git -C D:\MyFiles\KT\Node\kt-template-online-api add src/modules/qqbot/core src/modules/qqbot/napcat test docs/refactor-v3/architecture-convergence-inventory.md
git -C D:\MyFiles\KT\Node\kt-template-online-api add -u src/qqbot src/modules/qqbot/core src/modules/qqbot/napcat test
git -C D:\MyFiles\KT\Node\kt-template-online-api commit -m "refactor: 收敛QQBot核心与NapCat模块"
Expected: commit succeeds.
Task 5: Plugin Platform And Existing Plugin Slimming
Files:
-
Modify:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\qqbot\plugin-platform\** -
Modify:
D:\MyFiles\KT\Node\kt-template-online-api\src\modules\qqbot\plugins\** -
Delete:
D:\MyFiles\KT\Node\kt-template-online-api\src\qqbot\plugin\** -
Modify:
D:\MyFiles\KT\Node\kt-template-online-api\docs\refactor-v3\architecture-convergence-inventory.md -
Tests:
D:\MyFiles\KT\Node\kt-template-online-api\test\modules\qqbot\plugin-platform\** -
Tests:
D:\MyFiles\KT\Node\kt-template-online-api\test\modules\qqbot\plugins\** -
Tests:
D:\MyFiles\KT\Node\kt-template-online-api\test\qqbot\plugins\** -
Step 1: Replace old plugin registry imports
Run:
rg -n '@\/qqbot\/plugin|QqbotPluginRegistryService|QqbotEventPluginRegistryService|QqbotIntegrationPlugin' D:\MyFiles\KT\Node\kt-template-online-api\src\modules\qqbot D:\MyFiles\KT\Node\kt-template-online-api\test
Expected: hits exist before this task.
Update target code so:
QqbotIntegrationPlugin imports come from `@/modules/qqbot/core/contract/qqbot.types`.
Plugin registry behavior comes from `@/modules/qqbot/plugin-platform/**`.
No target module imports `@/qqbot/plugin/**`.
- Step 2: Delete old plugin registry root
After imports are replaced, run:
rg -n '@\/qqbot\/plugin|QqbotPluginRegistryService|QqbotEventPluginRegistryService' D:\MyFiles\KT\Node\kt-template-online-api\src D:\MyFiles\KT\Node\kt-template-online-api\test
Expected: no hits that require src/qqbot/plugin/**.
Then run:
git -C D:\MyFiles\KT\Node\kt-template-online-api rm -r src/qqbot/plugin
- Step 3: Scan existing plugins for full-module slimming
Run:
rg -n 'axios|fetch\(|http\.|@\/admin\/|@\/qqbot\/|legacyKeys|bangDream|ff14Market' D:\MyFiles\KT\Node\kt-template-online-api\src\modules\qqbot\plugins
Expected:
-
Direct HTTP clients in FF14 Market and FFLogs are absent or replaced by host runtime HTTP SDK.
-
@/admin/and@/qqbot/imports are removed. -
legacyKeysremain only in plugin metadata objects where external compatibility requires them. -
bangDreamandff14Marketlegacy strings remain only in compatibility mappings or tests that prove alias behavior. -
Step 4: Remove plugin internal dead buckets
Create a candidate list from files that contain old-root imports, direct HTTP calls, or legacy aliases:
Run:
$api = 'D:\MyFiles\KT\Node\kt-template-online-api'
$candidateFiles = @(
'src/modules/qqbot/plugins/ff14-market/qqbot-ff14-client.service.ts',
'src/modules/qqbot/plugins/ff14-market/qqbot-ff14-worlds.ts',
'src/modules/qqbot/plugins/ff14-market/qqbot-ff14-market.plugin.ts',
'src/modules/qqbot/plugins/fflogs/qqbot-fflogs-client.service.ts',
'src/modules/qqbot/plugins/fflogs/qqbot-fflogs.plugin.ts',
'src/modules/qqbot/plugins/repeater/qqbot-repeater.plugin.ts',
'src/modules/qqbot/plugins/bangdream/src/application/bangdream-renderer.facade.ts',
'src/modules/qqbot/plugins/bangdream/src/qqbot-bangdream.plugin.ts'
)
foreach ($file in $candidateFiles) {
$absolute = Join-Path $api $file
if (Test-Path $absolute) {
Write-Output "===== $file ====="
Select-String -Path $absolute -Pattern 'export (class|function|interface|type|const) ' | ForEach-Object { $_.Line.Trim() }
$stem = [System.IO.Path]::GetFileNameWithoutExtension($file)
rg -n --fixed-strings $stem "$api\src" "$api\test"
}
}
Delete a candidate file only when this scan shows no live references outside the file itself and no manifest or test depends on it. Keep the file when a manifest, registry, or test references it, then remove only the old import/direct-call line.
Record each deletion or keep decision in the inventory table.
- Step 5: Verify plugin platform and plugin behavior
Run:
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api exec jest --runInBand --runTestsByPath test/modules/qqbot/plugin-platform/manifest.spec.ts test/modules/qqbot/plugin-platform/cli.spec.ts test/modules/qqbot/plugin-platform/persistence-contract.spec.ts test/modules/qqbot/plugin-platform/plugin-platform-api-contract.spec.ts test/modules/qqbot/plugin-platform/worker-runtime.spec.ts test/modules/qqbot/plugins/plugin-registry-compat.spec.ts test/modules/qqbot/plugins/plugin-platform-migration.spec.ts test/modules/qqbot/plugins/plugin-controller-http-smoke.spec.ts 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/qqbot/plugins/bangdream/manifest/operation-manifest.spec.ts test/qqbot/plugins/bangdream/manifest/command-sql.spec.ts
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api run typecheck
Expected: PASS.
- Step 6: Update inventory
Append:
| Plugin Platform/Plugins | old `src/qqbot/plugin`; plugin files with no external or test references | registry behavior moved to plugin platform; plugin interfaces moved to target contracts; direct old-root imports removed | plugin manifest, legacy alias compatibility, worker runtime, host HTTP SDK, operation registry, event behavior | plugin platform focused Jest passes; plugin scan has no `@/admin/` or `@/qqbot/` imports |
- Step 7: Commit plugin migration
Run:
git -C D:\MyFiles\KT\Node\kt-template-online-api add src/modules/qqbot/plugin-platform src/modules/qqbot/plugins test docs/refactor-v3/architecture-convergence-inventory.md
git -C D:\MyFiles\KT\Node\kt-template-online-api add -u src/qqbot src/modules/qqbot/plugin-platform src/modules/qqbot/plugins test
git -C D:\MyFiles\KT\Node\kt-template-online-api commit -m "refactor: 收敛QQBot插件平台与现有插件"
Expected: commit succeeds.
Task 6: Admin Full-Domain Slimming And Caller Boundaries
Files:
-
Modify:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\api\system\** -
Modify:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\api\blog\** -
Modify:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\api\qqbot\** -
Modify:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\views\system\** -
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\views\qqbot\** -
Create:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\views\qqbot\modules\status.ts -
Create:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\views\qqbot\modules\actions.tsx -
Modify:
D:\MyFiles\KT\Node\kt-template-online-api\docs\refactor-v3\architecture-convergence-inventory.md -
Test:
D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\api\qqbot\napcat.spec.ts -
Step 1: Scan Admin callers and pages
Run:
$admin = 'D:\MyFiles\KT\Vue\kt-template-admin'
rg -n 'deprecated|legacy|兼容|旧|废弃|console\.log' "$admin\apps\web-antdv-next\src\api\system" "$admin\apps\web-antdv-next\src\api\blog" "$admin\apps\web-antdv-next\src\api\qqbot" "$admin\apps\web-antdv-next\src\views\system" "$admin\apps\web-antdv-next\src\views\blog" "$admin\apps\web-antdv-next\src\views\qqbot"
rg -n '登录成功|登录失败|需要验证码|新设备|运行态清理失败|online|offline|enabled|disabled|pending' "$admin\apps\web-antdv-next\src\views" "$admin\apps\web-antdv-next\src\api"
Expected: scan output identifies duplicated state labels and legacy comments before cleanup.
- Step 2: Create shared QQBot status module
Create apps/web-antdv-next/src/views/qqbot/modules/status.ts:
import type { TagProps } from 'antdv-next';
export const qqbotStatusLabels = {
disabled: '已禁用',
enabled: '已启用',
failed: '失败',
offline: '离线',
online: '在线',
pending: '处理中',
unknown: '未知',
} as const;
export type QqbotStatusKey = keyof typeof qqbotStatusLabels;
export function getQqbotStatusLabel(status: string | undefined): string {
if (!status) return qqbotStatusLabels.unknown;
return qqbotStatusLabels[(status as QqbotStatusKey)] ?? status;
}
export function getQqbotStatusColor(status: string | undefined): TagProps['color'] {
if (status === 'online' || status === 'enabled') return 'success';
if (status === 'offline' || status === 'disabled') return 'default';
if (status === 'failed') return 'error';
if (status === 'pending') return 'processing';
return 'default';
}
- Step 3: Create shared QQBot actions module
Create apps/web-antdv-next/src/views/qqbot/modules/actions.tsx:
import { Button, Popconfirm, Space } from 'antdv-next';
import type { Component } from 'vue';
export interface QqbotActionItem {
danger?: boolean;
disabled?: boolean;
icon?: Component;
key: string;
label: string;
loading?: boolean;
confirmText?: string;
onClick: () => void | Promise<void>;
}
export function renderQqbotActions(actions: QqbotActionItem[]) {
return (
<Space size="small">
{actions.map((action) => {
const button = (
<Button
danger={action.danger}
disabled={action.disabled}
icon={action.icon ? <action.icon /> : undefined}
loading={action.loading}
size="small"
type="link"
onClick={action.confirmText ? undefined : action.onClick}
>
{action.label}
</Button>
);
if (!action.confirmText) return <span key={action.key}>{button}</span>;
return (
<Popconfirm
key={action.key}
title={action.confirmText}
onConfirm={action.onClick}
>
{button}
</Popconfirm>
);
})}
</Space>
);
}
- Step 4: Replace duplicate QQBot status/action logic
Update these pages to import getQqbotStatusLabel, getQqbotStatusColor, or renderQqbotActions where they duplicate status tags or action buttons:
apps/web-antdv-next/src/views/qqbot/account/list.tsx
apps/web-antdv-next/src/views/qqbot/command/list.tsx
apps/web-antdv-next/src/views/qqbot/rule/list.tsx
apps/web-antdv-next/src/views/qqbot/message/list.tsx
apps/web-antdv-next/src/views/qqbot/permission/list.tsx
apps/web-antdv-next/src/views/qqbot/plugin/list.tsx
apps/web-antdv-next/src/views/qqbot/sendLog/list.tsx
Run:
rg -n '登录成功|登录失败|需要验证码|新设备二维码|运行态清理失败' D:\MyFiles\KT\Vue\kt-template-admin\apps\web-antdv-next\src\views\qqbot
Expected: NapCat-specific progress labels remain in api/qqbot/napcat.ts and NapCat UI only; other QQBot pages do not copy these strings.
- Step 5: Slim System and Blog/Admin pages
Run reference scans:
$admin = 'D:\MyFiles\KT\Vue\kt-template-admin'
rg -n 'ktTableDemo|clipboard|demo|legacy|deprecated|兼容旧|旧路由' "$admin\apps\web-antdv-next\src\views\system" "$admin\apps\web-antdv-next\src\views\blog" "$admin\apps\web-antdv-next\src\api\system" "$admin\apps\web-antdv-next\src\api\blog"
rg -n 'views/system/ktTableDemo|system/ktTableDemo|ktTableDemo' "$admin\apps\web-antdv-next\src\router" "$admin\apps\web-antdv-next\src\views" "$admin\apps\web-antdv-next\src\api"
Expected: if views/system/ktTableDemo has no menu/route/test entry, delete it. If a route or menu entry proves it is active, keep it and record the evidence.
Delete inactive demo files only after the scan proves no active entry:
git -C D:\MyFiles\KT\Vue\kt-template-admin rm -r apps/web-antdv-next/src/views/system/ktTableDemo
- Step 6: Keep NapCat helper tests green
Extend apps/web-antdv-next/src/api/qqbot/napcat.spec.ts so it also asserts shared progress labels remain centralized:
it('keeps new-device labels centralized in the NapCat caller helpers', () => {
expect(NAPCAT_LOGIN_PROGRESS_LABELS['new-device-required']).toBe(
'需要新设备验证二维码',
);
expect(NAPCAT_LOGIN_PROGRESS_LABELS['new-device-scanned']).toBe(
'新设备二维码已扫码',
);
expect(NAPCAT_LOGIN_PROGRESS_LABELS['new-device-confirming']).toBe(
'新设备确认中',
);
});
- Step 7: Verify Admin
Run:
pnpm --dir D:\MyFiles\KT\Vue\kt-template-admin exec vitest run apps/web-antdv-next/src/api/qqbot/napcat.spec.ts
pnpm --dir D:\MyFiles\KT\Vue\kt-template-admin -F @vben/web-antdv-next run typecheck
Expected: PASS.
- Step 8: Update inventory
Append to the API inventory document:
| Admin UI | inactive demo pages and no-entry components proven by `rg`; duplicated status/action helpers | QQBot status/action rendering centralized under `views/qqbot/modules`; repeated NapCat progress labels kept in caller helper | System, Blog/WordPress/Asset, QQBot, Plugin, and NapCat visible behavior | Admin Vitest helper test and typecheck pass |
- Step 9: Commit Admin changes and API inventory
Run:
git -C D:\MyFiles\KT\Vue\kt-template-admin add apps/web-antdv-next/src/api apps/web-antdv-next/src/views
git -C D:\MyFiles\KT\Vue\kt-template-admin commit -m "refactor: 收敛Admin全域管理边界"
git -C D:\MyFiles\KT\Node\kt-template-online-api add docs/refactor-v3/architecture-convergence-inventory.md
git -C D:\MyFiles\KT\Node\kt-template-online-api commit -m "docs: 记录Admin全域瘦身证据"
Expected: two commits succeed, one per repo.
Task 7: Final Legacy Root Deletion And Green Structure Gate
Files:
-
Delete:
D:\MyFiles\KT\Node\kt-template-online-api\src\admin -
Delete:
D:\MyFiles\KT\Node\kt-template-online-api\src\blog -
Delete:
D:\MyFiles\KT\Node\kt-template-online-api\src\minio -
Delete:
D:\MyFiles\KT\Node\kt-template-online-api\src\wordpress -
Delete:
D:\MyFiles\KT\Node\kt-template-online-api\src\qqbot -
Modify:
D:\MyFiles\KT\Node\kt-template-online-api\docs\refactor-v3\architecture-convergence-verification.md -
Modify:
D:\MyFiles\KT\TASKS.md -
Step 1: Prove no old imports remain
Run:
rg -n '@\/(admin|blog|minio|wordpress|qqbot)\/' D:\MyFiles\KT\Node\kt-template-online-api\src D:\MyFiles\KT\Node\kt-template-online-api\test
Expected: no hits.
- Step 2: Delete remaining empty old roots
Run:
$api = 'D:\MyFiles\KT\Node\kt-template-online-api'
foreach ($root in @('src/admin','src/blog','src/minio','src/wordpress','src/qqbot')) {
$path = Join-Path $api $root
if (Test-Path $path) {
git -C $api rm -r $root
}
}
Expected: any remaining old root path is removed from Git.
- Step 3: Run the structure gate green
Run:
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api exec jest --runInBand --runTestsByPath test/refactor-v3/architecture-convergence.spec.ts
Expected: PASS.
- Step 4: Run final API verification
Run:
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
Expected: PASS.
- Step 5: Run final Admin verification
Run:
pnpm --dir D:\MyFiles\KT\Vue\kt-template-admin exec vitest run apps/web-antdv-next/src/api/qqbot/napcat.spec.ts
pnpm --dir D:\MyFiles\KT\Vue\kt-template-admin -F @vben/web-antdv-next run typecheck
Expected: PASS.
- Step 6: Run local behavior smoke
Run API smoke using the existing bounded script:
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api run typecheck
Then start or reuse the local API only when a real interface smoke is needed. Required smoke evidence:
GET /health/runtime
Admin login and menu load
Blog public list/detail
Asset upload/download/remove through existing MinIO routes
QQBot command test
Plugin validate/install-local/enable/health
NapCat simulated login state machine
Expected: every smoke either passes or records a concrete blocker and stable next action. Do not call the work complete with a missing smoke.
- Step 7: Write final verification document
Create docs/refactor-v3/architecture-convergence-verification.md:
# Architecture Convergence Verification
## Structure
- API old roots: removed.
- Forbidden imports from `src/modules/**` to old roots: zero.
- `src/app.module.ts`: imports target modules only.
## API Verification
- Structure gate: pass.
- Typecheck: pass.
- Jest: pass.
- Local smoke: pass with recorded command evidence.
## Admin Verification
- NapCat helper Vitest: pass.
- Typecheck: pass.
- Page smoke: pass with recorded routes.
## Review
- KT global review: pass.
- KT global review: pass.
- Step 8: Update TASKS
Update D:\MyFiles\KT\TASKS.md with a short record:
### 2026-06-15:API/Admin 第三期架构收敛完成
- 范围:`Node/kt-template-online-api`、`Vue/kt-template-admin`、`TASKS.md`。
- 关键词:旧根删除、`src/modules/**` 强门禁、全模块瘦身、Admin 全域边界、结构测试、API/Admin 本地验证。
- 验证:记录结构 gate、API typecheck/Jest、Admin Vitest/typecheck、local smoke、KT global review 的最终结果。
- Step 9: Run review gates
Run:
pnpm --dir D:\MyFiles\KT\mcp\ktWorkflow run global-review -- --contentScanMode changed --includeContentScan true
Expected: findings=[].
Use KT workflow KT global review before declaring implementation complete.
- Step 10: Commit final verification
Run:
git -C D:\MyFiles\KT\Node\kt-template-online-api add src test docs/refactor-v3/architecture-convergence-inventory.md docs/refactor-v3/architecture-convergence-verification.md
git -C D:\MyFiles\KT\Node\kt-template-online-api commit -m "test: 完成架构收敛验证闭环"
git -C D:\MyFiles\KT add TASKS.md
git -C D:\MyFiles\KT commit -m "docs: 记录架构收敛闭环"
Expected: commits succeed and worktrees remain clean.
Final Completion Gate
Before reporting the goal complete, 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
git -C D:\MyFiles\KT status --short --branch
rg --files D:\MyFiles\KT\Node\kt-template-online-api\src\admin D:\MyFiles\KT\Node\kt-template-online-api\src\blog D:\MyFiles\KT\Node\kt-template-online-api\src\minio D:\MyFiles\KT\Node\kt-template-online-api\src\wordpress D:\MyFiles\KT\Node\kt-template-online-api\src\qqbot
rg -n '@\/(admin|blog|minio|wordpress|qqbot)\/' D:\MyFiles\KT\Node\kt-template-online-api\src\modules
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api exec jest --runInBand --runTestsByPath test/refactor-v3/architecture-convergence.spec.ts
pnpm --dir D:\MyFiles\KT\Node\kt-template-online-api run typecheck
pnpm --dir D:\MyFiles\KT\Vue\kt-template-admin -F @vben/web-antdv-next run typecheck
pnpm --dir D:\MyFiles\KT\mcp\ktWorkflow run global-review -- --contentScanMode changed --includeContentScan true
Expected:
API/Admin/root status clean.
Old root scan returns no files.
Forbidden import scan returns no hits.
Structure gate passes.
API typecheck passes.
Admin typecheck passes.
global-review findings=[].
Plan Self-Review
Spec Coverage
| Spec Requirement | Plan Coverage |
|---|---|
| Clean worktree before work | Task 0 |
| API old roots deleted | Tasks 1, 2, 3, 4, 5, 7 |
src/modules/** forbidden old imports |
Tasks 1 and 7 |
| Admin/Auth/Platform Config migration and slimming | Task 2 |
| Blog/WordPress/Asset migration and slimming | Task 3 |
| QQBot Core and NapCat migration and slimming | Task 4 |
| Plugin Platform and existing plugin slimming | Task 5 |
| Admin full-domain slimming | Task 6 |
| Runtime/Common slimming rule | Task 0 inventory and Task 7 final scan; module-private utilities discovered during Tasks 2-5 are moved back into domains before commit |
| Behavior preservation | Focused Jest, typecheck, local smoke, Admin Vitest/typecheck |
| No meaningless backup artifacts | Execution Rules and commit scopes |
| Documentation and TASKS update | Tasks 0 and 7 |
| KT global review | Task 7 |
Placeholder Scan
No deferred placeholder work is allowed. Each task names the files to move or modify, the commands to run, and the expected result. Discovery commands have bounded decision rules: delete only with no-reference evidence, keep only with route/menu/test/manifest evidence.
Type And Path Consistency
- API paths use
D:\MyFiles\KT\Node\kt-template-online-api. - Admin paths use
D:\MyFiles\KT\Vue\kt-template-admin. - Old API roots always mean
src/admin,src/blog,src/minio,src/wordpress, andsrc/qqbot. - Target API root is always
src/modules/**. - Admin route/page smoke remains under
apps/web-antdv-next/src/**.