26 KiB
GOV-009 应用工程脚手架基线实施计划
For agentic workers: REQUIRED SUB-SKILL: Use
superpowers:subagent-driven-development(recommended) orsuperpowers:executing-plansto implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.
Goal: 建立可启动、测试、构建和独立部署的 Vue 3 Web 与 NestJS API/Scheduler/Worker 工程,并修正开发 Schema 的本地配置、固定远程白名单和空库基线能力。
Architecture: 根 pnpm workspace 只编排 web 与 server。HTTP 契约由 Server 的 DTO 和 OpenAPI 单向发布,Web 生成自己的客户端;RocketMQ 消息契约只在 Server 内共享。Schema 安全门禁继续固定开发环境与数据库,只增加代码内固定远程主机和 captured_empty 状态。
Tech Stack: Node.js 22.x、pnpm 10.25.0、TypeScript 5.9.3、Vue 3.5.41、Vite 7.3.6、Naive UI 2.44.1、Dart Sass 1.102.0、Vitest 3.2.7、Playwright 1.62.1、NestJS 11.1.29、TypeORM 0.3.31、mysql2 3.23.3、ioredis 5.11.1、MySQL 5.7、Redis、RocketMQ 5.x。
Global Constraints
- 本机当前 Node.js 是
20.20.2,不得用于正式安装或验收;源码运行前由开发机提供 Node 22,项目不安装 Node。实施期间可使用node:22.22.0-bookworm-slim执行安装、测试和构建。 - pnpm 固定
10.25.0,根package.json写入精确packageManager,依赖提交精确版本及pnpm-lock.yaml,禁止latest。 - 所有关键业务边界、配置安全、异常恢复和架构取舍使用准确中文注释,不做逐行翻译式注释。
- Web 不得导入
server/;RocketMQ 消息契约不得进入 Web;数据库实体不得作为 HTTP DTO。 - MySQL 只允许 5.7.x、
a_share_analysis_dev、utf8mb4、utf8mb4_general_ci和+08:00会话时区,禁止synchronize: true。 - Schema 只读取开发配置,只允许回环地址或固定白名单
112.192.20.11,不得接触生产环境。 - RocketMQ 在 GOV-009 中保持默认关闭;打开但没有已验证客户端时必须失败,不提供内存队列伪降级。
- 每个行为遵循 RED-GREEN-REFACTOR:先运行并确认测试因行为缺失而失败,再写最小实现;测试断言真实结果,不断言 Mock 自身。
- 每个提交使用中文 Conventional Commit 并带
GOV-009,验证后立即精确推送当前分支到 Gitea。
Task 1: 修正 Schema 开发配置与空库基线
Files:
- Modify:
tools/database/schema-baseline.mjs - Modify:
tools/database/schema-baseline.test.mjs - Modify:
docs/governance/development-workflow.md - Modify:
docs/governance/code-development-standards.md - Modify:
docs/deployment/local-development.md
Interfaces:
-
Produces:
resolveFixedDevelopmentEnv(repositoryRoot): string,优先返回deploy/env/development/api.env.local,缺失时退回模板。 -
Produces:
assertSafeDevelopmentConfiguration(config): Readonly<SchemaConfig>,只接受回环地址或112.192.20.11。 -
Produces:
buildCapturedEmptyArtifacts(metadata): BaselineArtifacts,状态为captured_empty、format v2,只保存结构化清单、object_counts和空结构 SHA-256,不创建schema.sql。 -
Preserves:
assertCurrentReleasedBaselinePublished(repositoryRoot)的已提交、已推送和远程标签严格门禁。 -
Step 1: 写入配置路径和主机白名单失败测试
在 schema-baseline.test.mjs 增加行为测试:临时目录同时存在 api.env.local 与模板时必须选择 local;112.192.20.11 被接受;112.192.20.12、域名和空主机被拒绝。期望值直接使用固定路径和错误类型,不复用实现常量。
assert.equal(
resolveFixedDevelopmentEnv(repositoryRoot),
path.join(repositoryRoot, 'deploy/env/development/api.env.local'),
);
assert.doesNotThrow(() =>
assertSafeDevelopmentConfiguration({
...validConfig,
MYSQL_HOST: '112.192.20.11',
}),
);
assert.throws(
() => assertSafeDevelopmentConfiguration({ ...validConfig, MYSQL_HOST: '112.192.20.12' }),
/固定开发数据库主机白名单/,
);
- Step 2: 运行测试并确认 RED
Run: node --test --test-name-pattern='配置路径|远程开发库白名单' tools/database/schema-baseline.test.mjs
Expected: FAIL,原因分别为 api.env.local 未被选择、固定远程地址仍被拒绝。
- Step 3: 实现固定配置解析与白名单
在代码内使用不可变集合,不读取动态白名单变量:
const DEVELOPMENT_HOSTS = new Set([
'127.0.0.1',
'localhost',
'::1',
'112.192.20.11',
]);
export function resolveFixedDevelopmentEnv(repositoryRoot) {
const localEnv = path.join(repositoryRoot, 'deploy', 'env', 'development', 'api.env.local');
if (existsSync(localEnv)) return localEnv;
return path.join(repositoryRoot, 'deploy', 'env', 'development', 'api.env.example');
}
错误文案只输出主机,不输出用户名或密码。导出 resolveFixedDevelopmentEnv 供真实行为测试调用。
- Step 4: 写入空库 captured 失败测试
模拟 metadata 查询返回合法 MySQL 5.7 元数据,mysqldump 返回空结构;断言结果为 captured_empty、format v2、文件集合只有 manifest.yaml、object_counts 全为零、摘要为 SHA-256 空串,且没有 schema.sql。另加 fixture 回归测试证明既有 format v1 的 not_applicable 与 captured 清单仍可验证,并且当前运行配置改变不会静默重写历史。
- Step 5: 运行测试并确认 RED
Run: node --test --test-name-pattern='空库|历史不适用基线' tools/database/schema-baseline.test.mjs
Expected: FAIL,现有实现以“真实 Schema SQL 不能为空”拒绝空库,并重新读取当前配置否定历史 N/A 清单。
- Step 6: 实现
captured_empty和不可变历史语义
buildCapturedArtifacts 在规范化 SQL 为空时调用:
export function buildCapturedEmptyArtifacts(metadata) {
assertMysql57Metadata(metadata);
return Object.freeze({
status: 'captured_empty',
files: Object.freeze({
'manifest.yaml': buildManifest({
...metadata,
status: 'captured_empty',
captured: false,
schemaSha256: sha256(''),
}),
}),
});
}
新生成的 format v2 Manifest 增加 object_counts,空库固定为零;普通 captured 从导出 SQL 解析并记录非负计数。既有 format v1 的 objects 布尔结构保持只读兼容,验证器按格式版本与状态校验精确文件集合。已发布 N/A 清单只验证生成事实,不在 schema:verify 阶段用当前 env 改写历史;下一版本生成时才读取当前 local 配置。
- Step 7: 验证真实固定开发库
先运行只读元数据查询确认目标仍为空,再使用项目支持的 MySQL 5.7 原生客户端或 Docker 客户端执行一次临时目录生成测试;不得覆盖 database/schema-baselines/v0.0.7/。
Expected: 服务端 5.7.42、数据库 a_share_analysis_dev、字符集 utf8mb4、排序规则 utf8mb4_general_ci、对象计数 0。
- Step 8: 全量 Schema 回归、影响检测、提交和推送
Run:
npm run test:schema-baseline
npm run schema:verify
npm run test:governance
git diff --check
Expected: 全部 PASS,v0.0.7 清单逐字节不变。运行 GitNexus detect_changes,风险只能落在本报告列出的 Schema/governance 流程。
Commit: feat(GOV-009): 支持固定开发库结构基线
Push: git push origin "$(git branch --show-current)"
Task 2: 建立 Node 22 与 pnpm workspace 质量基线
Files:
- Modify:
package.json - Create:
pnpm-workspace.yaml - Create:
pnpm-lock.yaml - Create:
.npmrc - Create:
eslint.config.mjs - Create:
.prettierrc.json - Create:
tools/runtime/verify-runtime.mjs - Create:
tools/runtime/verify-runtime.test.mjs
Interfaces:
-
Produces:
assertSupportedRuntime({ nodeVersion, pnpmVersion })。 -
Produces root scripts:
check:runtime,lint,format:check,typecheck,test,build,verify。 -
Step 1: 写运行时门禁失败测试
覆盖 Node 22.0.0 与 pnpm 10.25.0 通过,Node 20/24、pnpm 9/11 拒绝;错误消息包含实际版本,不执行安装。
- Step 2: 运行并确认 RED
Run: node --test tools/runtime/verify-runtime.test.mjs
Expected: FAIL with ERR_MODULE_NOT_FOUND。
- Step 3: 实现运行时门禁和 workspace
export function assertSupportedRuntime({ nodeVersion, pnpmVersion }) {
if (Number(nodeVersion.split('.')[0]) !== 22) {
throw new Error(`Node.js 必须为 22.x,实际 ${nodeVersion}`);
}
if (Number(pnpmVersion.split('.')[0]) !== 10) {
throw new Error(`pnpm 必须为 10.x,实际 ${pnpmVersion}`);
}
}
pnpm-workspace.yaml 只包含:
packages:
- web
- server
根 package.json 写入 engines.node: 22.x、packageManager: pnpm@10.25.0,根脚本通过 pnpm --filter 编排两个工程,不创建业务依赖。
- Step 4: 在 Node 22 容器安装精确依赖并生成锁文件
Run: docker run --rm --user "$(id -u):$(id -g)" -e COREPACK_HOME=/tmp/corepack -v "$PWD:/workspace" -w /workspace node:22.22.0-bookworm-slim sh -lc 'corepack pnpm install --lockfile-only'
Expected: 生成单一 pnpm-lock.yaml,无 latest,宿主项目文件归当前用户可读写。
- Step 5: 验证、提交和推送
Run: Node 22 容器中的 corepack pnpm check:runtime、运行时单测、git diff --check。
Commit: build(GOV-009): 建立 Node 与工作区基线
Push current branch and verify local/remote SHA equality.
Task 3: 建立 Vue 3 Web 工程
Files:
- Delete:
web/.gitkeep - Create:
web/package.json - Create:
web/tsconfig.json - Create:
web/tsconfig.node.json - Create:
web/vite.config.ts - Create:
web/vitest.config.ts - Create:
web/playwright.config.ts - Create:
web/index.html - Create:
web/src/main.ts - Create:
web/src/app/App.vue - Create:
web/src/app/router.ts - Create:
web/src/app/providers.ts - Create:
web/src/styles/index.scss - Create:
web/src/env.d.ts - Create:
web/src/app/App.test.ts - Create:
web/tests/smoke.spec.ts
Interfaces:
-
Produces:
createAppRouter()和installAppProviders(app)。 -
Consumes: only
VITE_APP_ENV,VITE_API_BASE_URL,VITE_APP_TITLEfromweb.env.local。 -
Preserves: FEAT-MO-001 将在
src/features/market-overview/添加首屏,不需要重构应用入口。 -
Step 1: 写 Web 应用外壳失败测试
使用真实 Pinia、Router 和 Naive UI provider 挂载 App.vue,断言应用标题和主内容区域可访问;禁止 mock 子组件。
- Step 2: 运行并确认 RED
Run: pnpm --filter @a-share-analysis/web test --run
Expected: FAIL,因为 Web 包和应用入口尚不存在。
- Step 3: 创建精确依赖和最小应用外壳
Web dependencies 精确锁定 Vue 3.5.41、Vue Router 4.6.4、Pinia 3.0.4、Naive UI 2.44.1;dev dependencies 锁定 Vite 7.3.6、plugin-vue 6.0.8、TypeScript 5.9.3、vue-tsc 3.3.9、Sass 1.102.0、Vitest 3.2.7、Vue Test Utils 2.4.11、jsdom 26.1.0、Playwright 1.62.1。
main.ts 固定从项目外部加载开发 env:
const app = createApp(App);
installAppProviders(app);
app.mount('#app');
Vite envDir 指向 ../deploy/env/development,开发模式通过 --mode web 加载 web.env.local;生产构建只接受部署注入的 VITE_ 值。样式仅建立字体、颜色 token、页面高度和可访问焦点基线,不提前设计市场概览。
- Step 4: 运行单测、类型和构建
Run:
pnpm --filter @a-share-analysis/web test --run
pnpm --filter @a-share-analysis/web typecheck
pnpm --filter @a-share-analysis/web build
Expected: PASS,web/dist 不包含 MYSQL_、REDIS_、ROCKETMQ_、密码或 Server 消息字段。
- Step 5: 写 Playwright 冒烟测试并确认 RED/GREEN
测试访问 /,验证 main 存在、无页面错误和水平溢出,视口覆盖 1440x900 与 390x844。先在未配置 webServer 时确认失败,再配置 Vite webServer 并通过。
- Step 6: 提交和推送
Commit: feat(GOV-009): 建立 Vue 前端工程基线
Push current branch and verify remote SHA.
Task 4: 建立 NestJS 三进程与最小权限配置
Files:
- Delete:
server/.gitkeep - Create:
server/package.json - Create:
server/nest-cli.json - Create:
server/tsconfig.json - Create:
server/tsconfig.build.json - Create:
server/apps/api/src/main.ts - Create:
server/apps/api/src/api.module.ts - Create:
server/apps/scheduler/src/main.ts - Create:
server/apps/scheduler/src/scheduler.module.ts - Create:
server/apps/worker/src/main.ts - Create:
server/apps/worker/src/worker.module.ts - Create:
server/libs/config/src/runtime-config.ts - Create:
server/libs/config/src/runtime-config.test.ts - Create:
server/libs/config/src/load-process-env.ts - Create:
server/test/process-smoke.test.ts
Interfaces:
-
Produces:
loadApiConfig,loadSchedulerConfig,loadWorkerConfig,返回冻结且不含未知字段的配置。 -
Produces:
bootstrapApi,bootstrapScheduler,bootstrapWorker,支持依赖注入端口和优雅关闭。 -
Consumes:
deploy/env/development/<process>.env.localonly in development; production only consumesprocess.envinjected by Compose/systemd. -
Step 1: 写进程配置失败测试
分别证明 API 不要求 Scheduler/Worker 变量、Scheduler 不读取 MySQL 密码、Worker 不要求 API 端口;MySQL 启用时缺少时区或密码失败;日志序列化不包含敏感值。
- Step 2: 运行并确认 RED
Run: pnpm --filter @a-share-analysis/server test -- runtime-config.test.ts
Expected: FAIL,因为配置模块不存在。
- Step 3: 实现进程级配置
使用纯函数解析、显式条件必填和对象冻结。公共字段保持在同一文件连续阅读,避免每个变量一个文件。MySQL 配置接口固定:
export interface MysqlRuntimeConfig {
enabled: boolean;
host: string;
port: number;
database: 'a_share_analysis_dev' | string;
username: string;
password: string;
charset: 'utf8mb4';
collation: 'utf8mb4_general_ci';
timezone: '+08:00';
}
生产配置不从仓库路径加载;开发入口根据自身 import.meta.url 定位唯一 local 文件,不接受用户传入 env 路径。
- Step 4: 写三进程启动关闭失败测试
测试调用三个 bootstrap 函数,使用真实 Nest application/context 和只在基础设施端口注入的轻量 fake;断言 API 监听给定端口,Scheduler/Worker 不打开 HTTP 端口,三者收到关闭信号后释放资源。
- Step 5: 运行并确认 RED 后实现入口
API 使用 NestFactory.create;Scheduler/Worker 使用 NestFactory.createApplicationContext。所有进程启用 shutdown hooks,启动日志只记录进程名、环境和非敏感端口。
- Step 6: 验证构建产物路径
Run:
pnpm --filter @a-share-analysis/server test
pnpm --filter @a-share-analysis/server typecheck
pnpm --filter @a-share-analysis/server build
test -f server/dist/apps/api/main.js
test -f server/dist/apps/scheduler/main.js
test -f server/dist/apps/worker/main.js
Expected: 与现有 systemd/Compose 命令完全一致。
- Step 7: 提交和推送
Commit: feat(GOV-009): 建立 NestJS 三进程基线
Task 5: 建立后端契约、基础设施与 API 健康检查
Files:
- Create:
server/libs/http-contracts/src/health.dto.ts - Create:
server/libs/message-contracts/src/message-envelope.ts - Create:
server/libs/message-contracts/src/message-envelope.test.ts - Create:
server/libs/infrastructure/src/message-bus.adapter.ts - Create:
server/libs/infrastructure/src/disabled-message-bus.adapter.ts - Create:
server/libs/infrastructure/src/redis-health.client.ts - Create:
server/libs/infrastructure/src/mysql-health.client.ts - Create:
server/libs/infrastructure/src/typeorm-options.ts - Create:
server/apps/api/src/health.controller.ts - Create:
server/apps/api/src/health.service.ts - Create:
server/apps/api/test/health.e2e-spec.ts - Create:
server/tools/export-openapi.ts - Create:
server/openapi/openapi.json - Modify:
deploy/env/development/api.env.example - Modify:
deploy/env/development/worker.env.example - Modify:
deploy/env/production/api.env.example - Modify:
deploy/env/production/worker.env.example - Modify ignored local API/Worker env files to retain
MYSQL_TIMEZONE=+08:00without staging them.
Interfaces:
-
Produces:
GET /api/v1/health -> HealthResponseDto。 -
Produces:
MessageEnvelope<TPayload>withversion,eventType,idempotencyKey,occurredAt,payload。 -
Produces:
MessageBusAdapter.publish/subscribe/close,disabled adapter rejects publish/subscribe with a typed error。 -
Produces: TypeORM options with
synchronize: false, MySQL 5.7 charset/collation/timezone. -
Step 1: 写消息契约与禁用 adapter 失败测试
覆盖有效信封、缺失幂等键、非法时间、未知版本;disabled adapter 的发布/订阅必须拒绝且不缓存消息。
- Step 2: RED 后实现 Server 内部契约
export interface MessageEnvelope<TPayload> {
version: 1;
eventType: string;
idempotencyKey: string;
occurredAt: string;
payload: TPayload;
}
验证函数返回规范化冻结对象;Web 无路径别名能够解析此目录。
- Step 3: 写健康检查 E2E 失败测试
启动真实 Nest API,注入确定性的 Redis/MySQL health ports,调用 /api/v1/health,断言 HTTP 200、进程状态、Redis/MySQL 分项和 RocketMQ disabled;依赖失败时 HTTP 503 且错误体不包含凭据。
- Step 4: RED 后实现只读健康客户端
Redis 只执行 PING;MySQL 使用 SELECT VERSION(), DATABASE(), @@character_set_database, @@collation_database, @@session.time_zone,连接建立时设置 +08:00。TypeORM options 明确:
{
type: 'mysql',
connectorPackage: 'mysql2',
charset: 'utf8mb4',
timezone: '+08:00',
synchronize: false,
migrationsRun: false,
}
如果 TypeORM 实际类型不支持 connectorPackage,删除该字段并通过安装的 mysql2 驱动解析;不得用类型断言掩盖错误。
- Step 5: 写 OpenAPI 导出失败测试并实现
导出命令从真实 Controller/DTO 生成排序稳定的 server/openapi/openapi.json。测试解析 JSON,断言 /api/v1/health 与 HealthResponseDto 存在;再次生成后 git diff --exit-code -- server/openapi/openapi.json 必须通过。
- Step 6: 更新环境模板并运行契约测试
四份 MySQL 模板增加 MYSQL_TIMEZONE=+08:00,开发/生产同进程键集合继续一致,生产密码保持空值。
Run: Server tests, npm run test:environment-baseline, typecheck, OpenAPI drift check.
- Step 7: 使用真实开发基础设施只读冒烟
Redis DB 0/1/2 分别 PING;API/Worker MySQL 连接验证版本、库名、字符集、排序规则和时区。RocketMQ 只检查既有 NameServer/Broker/Proxy 管理链路,Node adapter 保持 disabled。
- Step 8: 提交和推送
Commit: feat(GOV-009): 建立后端契约与健康检查
Task 6: 生成 Web OpenAPI 客户端并强制边界
Files:
- Create:
web/src/api/generated/schema.ts - Create:
web/src/api/client.ts - Create:
web/src/api/adapters/health.adapter.ts - Create:
web/src/api/adapters/health.adapter.test.ts - Create:
tools/boundaries/verify-project-boundaries.mjs - Create:
tools/boundaries/verify-project-boundaries.test.mjs - Modify:
web/package.json - Modify: root
package.json
Interfaces:
-
Consumes:
server/openapi/openapi.jsonas the only cross-project contract artifact. -
Produces:
createApiClient(baseUrl)usingopenapi-fetchand generatedpathstype. -
Produces:
toHealthViewModel(dto): HealthViewModel,页面模型不暴露后端枚举细节。 -
Step 1: 写项目边界失败测试
在临时 fixture 中创建 Web 对 server/libs 的 import 和消息字段,运行真实边界检查器并断言失败;合法的 web/src/api/generated/schema.ts 通过。检查器解析 TypeScript import/export specifier,不用简单 grep 代替模块边界。
- Step 2: RED 后实现边界检查器
检查 Web 源文件的静态 import、动态 import 和路径别名,拒绝解析到仓库 server/;检查生成 OpenAPI schema 不包含 MessageEnvelope 或 message-contracts。
- Step 3: 生成 Web 客户端
Run: openapi-typescript ../server/openapi/openapi.json -o src/api/generated/schema.ts
client.ts 只包装 base URL 和错误归一化;健康 adapter 使用手写页面模型和显式映射,不把生成 DTO 传入 Vue 组件。
- Step 4: 写 adapter 失败测试并实现
使用手写完整 DTO fixture,断言 healthy/degraded/unavailable 映射和未知依赖状态拒绝。先运行确认函数缺失失败,再实现最小映射。
- Step 5: 运行边界、生成漂移、Web 测试和构建
Run root check:contracts twice; second run must leave clean diff. Scan web/dist for Server env keys, message fields and secrets; expected no match.
- Step 6: 提交和推送
Commit: feat(GOV-009): 建立前端 OpenAPI 客户端边界
Task 7: 对齐 Docker、Compose、systemd 与源码开发命令
Files:
- Create:
web/Dockerfile - Create:
web/nginx.conf - Create:
server/Dockerfile - Modify:
deploy/compose/production.yml.example - Modify:
deploy/nginx/a-share-analysis.conf.example - Modify:
deploy/systemd/a-share-api.service.example - Modify:
deploy/systemd/a-share-scheduler.service.example - Modify:
deploy/systemd/a-share-worker.service.example - Modify:
docs/deployment/local-development.md - Modify:
docs/deployment/docker-compose-production.md - Modify:
docs/deployment/ubuntu-source-production.md - Modify:
README.md - Modify:
tools/governance/environment-baseline.test.mjs
Interfaces:
-
Produces immutable Web image serving
/and proxying/api/according to deployment contract. -
Produces one Server image with commands
dist/apps/api/main.js,dist/apps/scheduler/main.js,dist/apps/worker/main.js. -
Step 1: 扩展部署行为测试并确认 RED
使用 docker build 和 docker compose config 作为真实行为测试;验证镜像入口文件存在、非 root 运行、生产 Compose 必填不可变镜像、systemd ExecStart 对应真实 dist 文件。不要只断言文档文本。
- Step 2: 实现多阶段 Dockerfile
Builder 使用固定 Node 22.22.0 与 pnpm 10.25.0;Server runtime 只复制生产依赖和 dist,使用非 root 用户;Web runtime 使用固定 Nginx 镜像并复制 dist。镜像层不得复制 deploy/env/development/*.local。
- Step 3: 更新双部署说明
本地命令明确 Node 22 前置、pnpm install --frozen-lockfile、四进程启动顺序和 env 路径;生产说明分别给出 Compose 与 Ubuntu/systemd 的构建、迁移、启动、健康检查和回退命令。不得记录真实开发密码或远程库账号。
- Step 4: 构建并启动容器冒烟
Build Web/Server images with local-only tags. 使用临时生产 env(无真实生产密钥)验证配置缺失会失败;使用开发只读配置只启动 API 健康检查,不启动 Scheduler/Worker 的 RocketMQ 消费。
- Step 5: 提交和推送
Commit: build(GOV-009): 对齐应用部署与运行入口
Task 8: 完成全量验证、Review 与发布留痕
Files:
- Update:
docs/features/GOV-009-application-scaffold-baseline/manifest.yaml - Create:
docs/features/GOV-009-application-scaffold-baseline/gitnexus/detected-changes.md - Create:
docs/features/GOV-009-application-scaffold-baseline/gitnexus/after.md - Create:
docs/features/GOV-009-application-scaffold-baseline/gitnexus/comparison.md - Create:
docs/features/GOV-009-application-scaffold-baseline/qa/test-results.md - Create:
docs/features/GOV-009-application-scaffold-baseline/qa/visual-qa.md - Create:
docs/features/GOV-009-application-scaffold-baseline/review/code-review.md - Create:
docs/features/GOV-009-application-scaffold-baseline/review/standards-review.md - Create:
docs/features/GOV-009-application-scaffold-baseline/release-notes.md - Create:
docs/features/GOV-009-application-scaffold-baseline/rollback.md - Modify:
VERSION - Modify:
CHANGELOG.md
Interfaces:
-
Produces: reproducible evidence for tests, builds, browser screenshots, GitNexus changes, reviews, release and rollback.
-
Step 1: 在固定 Node 22 环境运行完整验证
Run root pnpm verify, all four governance suites, schema:verify, Web Playwright at desktop/mobile, both Docker builds, development and production Compose validation, secret scan and git diff --check.
Expected: zero failures and zero unexpected warnings. Save exact commands, versions and result counts in qa/test-results.md.
- Step 2: 保存视觉证据
启动 Web/API 本地服务,Playwright 保存 1440x900 与 390x844 截图;检查无空白画面、溢出、重叠和控制台错误。GOV-009 只验证应用外壳,不评价市场概览视觉质量。
- Step 3: 执行 GitNexus 变更检测和结束门禁
Run GitNexus detect_changes,核对新增 API、Scheduler、Worker、OpenAPI 和 Web 流程,记录与开发前 23 条流程的差异。运行 npm run governance:finish -- GOV-009 application-scaffold-baseline。
- Step 4: 独立代码与规范 Review
代码 Review 检查配置泄漏、MySQL 5.7、进程生命周期、契约方向、Docker 产物和真实测试。规范 Review 逐条核对中文注释、文件拆分、中文提交、GitNexus 和文档追溯。两份报告必须包含精确行:
最终结论:passed
- Step 5: 更新版本、发布说明和回退
将版本提升到 0.0.8,说明工程能力而不声称市场概览已实现。回退说明不得删除远程数据库或 Redis 数据,只回退应用代码和镜像。
- Step 6: 最终提交、推送与标签
Commit: docs(GOV-009): 封存应用脚手架验证结果
Push current branch, compare local and remote SHA, create annotated tag v0.0.8, then run git push origin v0.0.8。禁止 --tags 和任何 force 选项。
- Step 7: 刷新 GitNexus 并确认干净状态
Run npx gitnexus status; stale 时运行 analyze。最终要求工作区干净、main 与 origin/main 一致、远程 v0.0.8^{} 指向本地标签提交。