Commit 5adbe9db33f4c91547c6a84c1eb02f8425b885e1

Authored by zichun
1 parent c3a7467c

templates(test-db): drop ALLOW_REMOTE/ALLOW_PROD_NAME hatches and slim env-local warnings

skills/plan/skeleton-gen/templates/env-local-template
1   -# .env.local — 本地开å‘凭æ®ï¼ˆå…¥ .gitignoreï¼Œä¸æäº¤ï¼‰
2   -#
3   -# 规则:
4   -# 1. å€¼å« `$`ã€å引å·ã€ç©ºæ ¼ã€`!` ç­‰ shell 特殊字符时,必须用å•引å·åŒ…裹:
5   -# DB_PASSWORD='p@ss$w0rd!'
6   -# å¦åˆ™ `set -a; . .env.local; set +a` 会åšå˜é‡å±•开导致密ç é”™ä¹±ã€‚
7   -# 2. DB_HOST å»ºè®®ä¿æŒ localhost / 127.0.0.1ï¼›éžæœ¬åœ° host 默认会被 scripts/setup-test-db.mjs 防护拒ç»ã€‚
8   -# 若必须用远程测试库,把 host 列入下方 TEST_DB_ALLOWED_HOSTS。
9   -# 3. DB_SCHEMA 建议命åå« test / _dev / _local / _ci,é¿å…与生产库åŒå。
  1 +# Local dev credentials — gitignored.
  2 +# Quote values containing $/space/!/backtick with single quotes: DB_PASSWORD='p@ss$w0rd!'
10 3  
11 4 DB_HOST=ã€äººå·¥å¡«å†™ï¼šMySQL host,推è localhost】
12 5 DB_PORT=ã€äººå·¥å¡«å†™ï¼šMySQL port,默认 3306】
... ... @@ -15,11 +8,5 @@ DB_PASSWORD=ã€äººå·¥å¡«å†™ï¼šå¯¹åº”密ç ï¼Œå«ç‰¹æ®Šå­—符时用å•引å·åŒ…è£
15 8 DB_SCHEMA=ã€äººå·¥å¡«å†™ï¼šschema å,推èå« test/_dev/_local,例如 erp_dev】
16 9 JWT_SECRET=ã€äººå·¥å¡«å†™ï¼šJWT ç­¾å密钥,256+ bit éšæœºä¸²ã€‘
17 10  
18   -# å¯é€‰ï¼šé¢å¤–å…许 DROP CREATE 的远程 host(空格或逗å·åˆ†éš”)。仅当 DB_HOST 指å‘公叿µ‹è¯• MySQL ç­‰
19   -# éžæœ¬åœ°æœåŠ¡å™¨æ—¶å¡«å†™ï¼›ç•™ç©ºè¡¨ç¤ºåªå…许 localhost / 127.0.0.1 / ::1。
20   -# 示例:TEST_DB_ALLOWED_HOSTS="118.178.19.35 test-mysql.internal"
21   -#
22   -# âš ï¸ åˆ—å…¥åŽè¯¥ host æ¯æ¬¡ test.mjs 都会被 DROP CREATE(无二次确认)。
23   -# ä»…ç”¨äºŽä½ å®Œå…¨å¯æŽ§çš„æµ‹è¯•åº“ï¼›ç”Ÿäº§/共享库/多人共享的 staging 库**åƒä¸‡åˆ«åˆ—**。
24   -# (防护 2 还会检查 schema åé¡»å« test/_dev/_local/_ci,独立兜底。)
  11 +# å¯é€‰ï¼šé¢å¤–å…许 DROP CREATE 的远程 host(空格或逗å·åˆ†éš”)。
25 12 TEST_DB_ALLOWED_HOSTS=
... ...
skills/plan/skeleton-gen/templates/scripts-setup-test-db-template.mjs
1 1 #!/usr/bin/env node
2   -// scripts/setup-test-db.mjs — 数据库重置脚本:drop + create 空库。
3   -// schema apply 由 Flyway 在 Spring Boot 启动时自动处理(见 docs/04 技术栈 + sql/migrations/V*.sql)。
4   -// seed 数据由测试框架负责(Spring @Sql / Flyway R__seed.sql / data.sql)。
5   -//
6   -// 使用场景:
7   -// - scripts/test.mjs 开头:清空库,让 Spring 启动时 Flyway 从 V1 开始重放所有 migration
8   -// - scripts/test.mjs 结尾:清空库,避免测试遗留污染下次运行
9   -// - 手动调试时:reset 到零状态
10   -//
11   -// 跨平台:用纯 JS 解析 .env.local(dotenv 风格,逐行 KEY=VALUE),**绝不** shell-source,
12   -// 因此 mac / Windows 原生 node 均可运行,且消除 shell 注入 / 变量展开隐患。
13   -// DROP/CREATE 通过 `mysql` 客户端以 argv 数组方式执行(不经 shell),密码不进命令行解析层。
14   -//
15   -// 防护:本脚本只允许在本地 host + 测试库名上执行;非预期目标会被拒绝,
16   -// 避免 .env.local 误指向 staging/prod 时触发不可逆 DROP。
  2 +// scripts/setup-test-db.mjs — DROP + CREATE 空测试库。
  3 +// 由 coding.mjs 的 test-gate 调用;schema 由 Flyway 在 Spring Boot 启动时重放。
  4 +// 只允许本地 host(或 TEST_DB_ALLOWED_HOSTS 白名单内的 host)+ 测试库名(含 test/_dev/_local/_ci)。
17 5  
18 6 import { spawnSync } from 'node:child_process'
19 7 import { existsSync, readFileSync } from 'node:fs'
... ... @@ -23,8 +11,6 @@ import { fileURLToPath } from 'node:url'
23 11 const SCRIPT_DIR = dirname(fileURLToPath(import.meta.url))
24 12 const ENV_FILE = join(SCRIPT_DIR, '..', '.env.local')
25 13  
26   -// dotenv 风格解析:逐行 KEY=VALUE,跳过空行与 # 注释,去除两侧空白,
27   -// 可选地剥离一层成对单/双引号。**不做**变量展开,特殊字符按字面保留。
28 14 function parseEnv(text) {
29 15 const env = {}
30 16 for (const rawLine of text.split(/\r?\n/)) {
... ... @@ -59,9 +45,6 @@ const DB_PORT = env.DB_PORT ?? '3306'
59 45 const DB_USER = env.DB_USER ?? ''
60 46 const DB_PASSWORD = env.DB_PASSWORD ?? ''
61 47 const DB_SCHEMA = env.DB_SCHEMA ?? ''
62   -const TEST_DB_ALLOW_REMOTE = env.TEST_DB_ALLOW_REMOTE ?? process.env.TEST_DB_ALLOW_REMOTE ?? '0'
63   -const TEST_DB_ALLOW_PROD_NAME =
64   - env.TEST_DB_ALLOW_PROD_NAME ?? process.env.TEST_DB_ALLOW_PROD_NAME ?? '0'
65 48  
66 49 // 防护 1:默认只允许本地 host(localhost / 127.0.0.1 / ::1)。
67 50 // 额外允许的远程 host 在 .env.local 的 TEST_DB_ALLOWED_HOSTS 中(空格或逗号分隔)。
... ... @@ -73,22 +56,19 @@ if (!allowedHosts.includes(DB_HOST)) {
73 56 console.error(`[setup-test-db] 拒绝在非白名单 host (${DB_HOST}) 上执行 DROP DATABASE`)
74 57 console.error(` 当前白名单:${allowedHosts.join(' ')}`)
75 58 console.error(' 加入 host:在 .env.local 追加 TEST_DB_ALLOWED_HOSTS="<host1> <host2>"')
76   - console.error(' 一次性绕过:在 .env.local 设 TEST_DB_ALLOW_REMOTE=1')
77   - if (TEST_DB_ALLOW_REMOTE !== '1') process.exit(1)
  59 + process.exit(1)
78 60 }
79 61  
80   -// 防护 2:schema 名需像测试/开发库(含 test / _dev / _local / _ci),否则要求显式确认
  62 +// 防护 2:schema 名需像测试/开发库(含 test / _dev / _local / _ci),否则拒绝
81 63 const schemaLooksLikeTest =
82 64 /test/.test(DB_SCHEMA) || /_dev$/.test(DB_SCHEMA) || /_local$/.test(DB_SCHEMA) || /_ci$/.test(DB_SCHEMA)
83 65 if (!schemaLooksLikeTest) {
84 66 console.error(
85 67 `[setup-test-db] schema '${DB_SCHEMA}' 不像测试库(期望命名含 test / _dev / _local / _ci)`
86 68 )
87   - console.error(' 如确为期望行为,请显式声明:在 .env.local 设 TEST_DB_ALLOW_PROD_NAME=1')
88   - if (TEST_DB_ALLOW_PROD_NAME !== '1') process.exit(1)
  69 + process.exit(1)
89 70 }
90 71  
91   -// 防护 3:显式 banner,让人看见自己在 drop 什么;远程 host 额外提示白名单内容。
92 72 console.log(`[setup-test-db] 即将 DROP + CREATE \`${DB_SCHEMA}\` on ${DB_HOST}:${DB_PORT}`)
93 73 if (!['localhost', '127.0.0.1', '::1'].includes(DB_HOST)) {
94 74 console.log(
... ... @@ -104,7 +84,6 @@ const sql =
104 84 `DROP DATABASE IF EXISTS \`${DB_SCHEMA}\`; ` +
105 85 `CREATE DATABASE \`${DB_SCHEMA}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;`
106 86  
107   -// 以 argv 数组调用 mysql(不经 shell):密码不进 shell 解析,跨平台一致。
108 87 const mysqlArgs = [
109 88 `-h${DB_HOST}`,
110 89 `-P${DB_PORT}`,
... ...