7.9 KiB
GOV-007 开发数据库 Schema 基线与版本门禁实施计划
执行要求: 按测试驱动方式逐项实施;每个行为先观察失败,再写最小实现。实施期间不得连接、探测或读取任何数据库,真实导出入口仅通过固定样本和依赖注入验证。
目标: 建立只允许读取固定开发库、可确定性规范化和校验完整 MySQL 5.7 Schema,并在下一版本开发前强制验证上一已发布版本基线的治理门禁。
架构: tools/database/schema-baseline.mjs 集中维护安全配置、命令构造、SQL 规范化、产物生成及校验,避免将一条连续的安全流程过度拆分。governance:start 只调用“当前已发布版本基线是否存在且有效”的纯门禁,不负责静默生成或覆盖产物;生成基线必须先由独立命令完成、提交并推送。
技术栈: Node.js 22 LTS、Node 内置测试运行器、MySQL 5.7 mysql/mysqldump 客户端、SHA-256、GitNexus、Git/Gitea。
全局约束
- 数据来源只能是
APP_ENV=development、数据库a_share_analysis_dev。 - MySQL 客户端与服务端只能是 5.7.x,字符集固定
utf8mb4,排序规则固定utf8mb4_general_ci。 - 导出必须包含
--no-data --routines --triggers --events,密码不得出现在参数、日志、SQL 或清单中。 - 不接受环境类型、数据库名或 env 路径的命令行覆盖。
- 当前 MySQL 未启用,不运行真实数据库命令,只生成可验证的
not_applicable清单,且不创建空schema.sql。 - 已存在版本目录不得静默覆盖;真实 Schema 只含结构,不含任何数据。
- 修改关键符号前执行 GitNexus impact,提交前执行 GitNexus detect-changes。
任务 1:锁定安全边界和可观察契约
文件:
- 新建:
tools/database/schema-baseline.test.mjs - 新建:
tools/database/fixtures/mysql57-schema-input.sql - 新建:
tools/database/fixtures/mysql57-schema-expected.sql - 新建:
docs/features/GOV-007-development-schema-baseline/test-plan.md
接口:
-
消费:设计规格中固定的环境、版本、Schema 范围和禁止覆盖规则。
-
产出:后续实现必须满足的公开函数行为和固定 SQL 输入/输出。
-
编写配置测试,分别证明非
development、非a_share_analysis_dev、非 MySQL 5.7、错误字符集和错误排序规则被拒绝。 -
运行
node --test tools/database/schema-baseline.test.mjs,确认因实现模块不存在而失败。 -
编写命令构造测试,手工断言参数包含
--no-data、--routines、--triggers、--events,且密码字符串不出现在参数中。 -
编写固定 SQL 样本测试,手工断言时间注释、
DEFINER和表级当前自增值被删除,列级AUTO_INCREMENT以及表、视图、触发器、例程和事件定义完整保留。 -
编写产物测试,证明清单和校验文件的 SHA-256 与 SQL 一致、不同内容的既有目录被拒绝、未启用 MySQL 时只有
manifest.yaml而没有schema.sql。
任务 2:实现纯函数和文件产物
文件:
- 新建:
tools/database/schema-baseline.mjs - 修改:
package.json
接口:
-
产出:
assertSafeDevelopmentConfiguration(config)、assertMysql57Metadata(metadata)、buildMysqldumpArguments(config)、normalizeSchemaSql(sql)、buildCapturedArtifacts(metadata, sql)、buildNotApplicableArtifacts(metadata)、persistBaselineArtifacts(target, artifacts)、verifyBaselineDirectory(target, expectedRelease)。 -
实现最小配置与元数据校验,使安全边界测试通过。
-
实现参数数组构造;连接密码只允许由子进程环境传递,不进入参数。
-
实现确定性 SQL 规范化和敏感内容扫描,使固定样本逐字节匹配期望文件。
-
实现 SHA-256、平面可审计清单、标准 checksum 文件和目录校验。
-
采用同目录临时目录加原子改名写入;目标已存在时仅允许逐字节相同内容复用,其他情况报错。
-
运行 Schema 测试,确认所有测试转绿;再运行既有治理、MySQL 与环境基线测试,确认没有回归。
任务 3:实现真实入口但不连接数据库
文件:
- 修改:
tools/database/schema-baseline.mjs - 修改:
package.json - 修改:
deploy/env/development/api.env.example(仅在契约字段缺失时修改)
接口:
-
消费:固定路径
deploy/env/development/api.env;文件不存在且仓库模板明确MYSQL_ENABLED=false时允许生成不适用记录。 -
产出:
npm run schema:baseline与npm run schema:verify,版本自动从最近语义化版本标签解析。 -
测试命令行拒绝额外参数,证明不能传入 production env、数据库名或任意 env 路径。
-
测试未启用 MySQL 的入口不会调用数据库执行器,并为最近发布标签创建可验证不适用记录。
-
测试启用分支只构造固定
mysql/mysqldump参数,并在客户端/服务端版本或数据库字符规则不符时阻断。 -
实现固定配置加载、最近标签与标签提交解析、回环主机检查、mysql/mysqldump 双客户端和服务端元数据检查、真实导出执行路径;本次验证不调用该路径。
-
运行
npm run schema:baseline为v0.0.5生成not_applicable清单,并运行npm run schema:verify验证;确认不存在schema.sql。
任务 4:接入版本开发前门禁与治理规范
文件:
- 修改:
tools/governance/start.mjs - 修改:
tools/governance/feature-record.test.mjs或新增对应集成测试。 - 修改:
AGENTS.md - 修改:
docs/governance/development-workflow.md - 修改:
docs/governance/code-development-standards.md - 修改:
README.md - 修改:
docs/index.md
接口:
-
消费:
assertCurrentReleasedBaselinePublished(repositoryRoot)。 -
产出:治理开始命令只有在上一已发布版本 Schema 基线有效时才继续 GitNexus 开发前流程。
-
先写失败测试:基线缺失或失效时
governance:start的前置检查拒绝继续,有效 N/A 或真实基线时允许继续。 -
在
start.mjs刷新 GitNexus 之前调用严格发布验证,检查 Git 跟踪、工作区、origin 分支和远程标签;不自动生成、不覆盖基线。 -
文档明确顺序为“生成并验证基线 → 中文提交 → 推送 Gitea → 治理开始”,以及首次启用 MySQL 时必须从真实开发库导出。
-
代码规范增加 Schema 仅结构、MySQL 5.7 完整对象范围、确定性规范化、禁止生产数据库和禁止直接改共享表的规则。
任务 5:验证、Review 与发布
文件:
- 新建或更新:GOV-007 完整功能档案。
- 修改:
VERSION、CHANGELOG.md、docs/index.md。
接口:
-
产出:可追溯的
v0.0.6治理版本。 -
执行 Schema、治理、MySQL、环境测试,执行
git diff --check、敏感信息扫描和适用构建检查。 -
执行
npx gitnexus analyze与变更检测,保存开发前后差异和风险结论。 -
完成代码 Review 与开发规范符合性 Review;两份报告必须包含独立一行
最终结论:passed。 -
执行
npm run governance:finish -- GOV-007 development-schema-baseline并保存证据。 -
使用中文 Conventional Commit 提交并立即推送
origin/main,回填实现提交和远程 SHA。 -
封存最终验证结果,提交并推送;创建带注释标签
v0.0.6并只精确推送该标签。
计划自审
- 设计中的安全配置、完整对象范围、规范化、清单校验、禁止覆盖、未启用路径、治理门禁、双 Review 和发布要求均有对应任务。
- 所有实现接口在任务 2 明确定义,任务 3、4 只消费这些接口,没有命名漂移。
- 计划不包含待定项;真实数据库路径可实现但本次只以依赖注入和固定样本验证,符合禁止连接数据库的范围。