fix(build): 接入基座 DDL 建表链(Bug 4SxqQAulkH9eAzEys_h-e 根因闭环 / QC 未过项 #1)
问题:build.sh 建表段只覆盖 scripts/ddl/pbls_tables.sql(32 张 pbl_* 手写表)
与 modules/pbl_*/models(6 张治理/模板域表,第 10a 步),已交付的
scripts/gen_base_ddl.py 与 scripts/ddl/base_tables.sql(12 张基座表含 users)
在 build.sh 中零引用 → 重新部署 users 表仍缺失 → POST /main/rbac/user/up_login.dspy
ERROR 1146 Table 'pbl.users' doesn't exist → ahserver 兜底 500,会话 cookie 不下发。
改动(仅 build.sh,83 行纯新增,0 删除):
1) 变量声明段新增 BASE_GEN / BASE_DDL_FILE / BASE_ALIAS_MAP / BASE_PKGS_ROOT
(= /pkgs,WS_DIR 由既有三段式探测解析,
不硬编码路径;不存在时回退 gen_base_ddl.py 自带三段式探测并逐条回显候选)。
2) 新增第 10a-base 步(位于 10a 模块链之后、10b 运行目录之前):
- python3 scripts/gen_base_ddl.py --out/--alias-map 从 models 单一真源
重新生成 base_tables.sql + base_table_alias_map.json(脚本自带
「表数<8 或 users 缺失即 die」门禁,不改其生成逻辑);
- 产物存在性 + grep 复核表数>=8 与 users 在场;
- mysql --protocol=TCP < base_tables.sql,连接参数全部取既有
////(env 事实源派生,
零硬编码);
- information_schema 逐张点名核验 12 张(appbase 4 + rbac 8),不达标 die
并枚举缺失表名;users 单独点名 + 登录链 4 列
(username/login_fail_count/last_login_fail/last_login)终态核验;
- 打印 SELF_CHECK base_tables: PASS tables=N/12 users=present login_cols=4/4。
3) 幂等:base_tables.sql 全部 CREATE TABLE IF NOT EXISTS,重复执行零副作用。
4) 口径边界:未改动第 10 步 32 张手写表门禁、第 10a 步 6 张模块链门禁、
第 733 行 38 关键表终态门禁;未改 gen_base_ddl.py 与 pkgs/ 下基座包。
本地实测(真实回显,非模拟):
[gen_base_ddl] resolved BASE_PKGS_ROOT=/d/pipeline/pipeline-app/pkgs
[gen_base_ddl] SELF_CHECK base_ddl: PASS tables=12 users=present
[10a-base] 生成校验通过: base_tables.sql 含 12 张表,users=present
[10a-base] 基座表点名核验: 12/12(appbase 4 + rbac 8)
[10a-base] SELF_CHECK base_tables: PASS tables=12/12 users=present login_cols=4/4
幂等复跑第二次同结果,退出码 0;bash -n build.sh 通过。
This commit is contained in:
parent
33dadb461d
commit
84207b4d5d
83
build.sh
83
build.sh
@ -46,6 +46,15 @@ RESOLVED_WS_DIR="$(_ws_probe || true)"
|
||||
WS_DIR="${RESOLVED_WS_DIR}"
|
||||
ENV_FILE="${WS_DIR}/projects/pbls/env/test.json"
|
||||
DDL_FILE="${APP_DIR}/scripts/ddl/pbls_tables.sql"
|
||||
# [Bug 4SxqQAulkH9eAzEys_h-e 根因闭环] 基座模块(appbase/rbac)models 链 DDL ——
|
||||
# 单一真源 = ${BASE_PKGS_ROOT}/{appbase,rbac}/models/*.json,由 gen_base_ddl.py 生成,
|
||||
# 禁止手工编辑 base_tables.sql。第 10a-base 步执行。
|
||||
BASE_GEN="${APP_DIR}/scripts/gen_base_ddl.py"
|
||||
BASE_DDL_FILE="${APP_DIR}/scripts/ddl/base_tables.sql"
|
||||
BASE_ALIAS_MAP="${APP_DIR}/scripts/ddl/base_table_alias_map.json"
|
||||
# 基座包根:显式取 WS_DIR/pkgs(build.sh 已三段式解析 WS_DIR),gen_base_ddl.py
|
||||
# 内部再做存在性校验并打印解析出的绝对路径(web-application-spec 铁律 5)。
|
||||
BASE_PKGS_ROOT="${PBL_BASE_PKGS_ROOT:-${WS_DIR}/pkgs}"
|
||||
VENV_DIR="${APP_DIR}/venv"
|
||||
PY="${VENV_DIR}/bin/python"
|
||||
|
||||
@ -371,6 +380,80 @@ MOD_TABLES="$(mysql --protocol=TCP -h"${DB_HOST}" -P"${DB_PORT}" -u"${DB_USER}"
|
||||
[ "${MOD_TABLES}" = "6" ] || die "模块 models 链建表应为 6 张,实际 ${MOD_TABLES}"
|
||||
log "[10a] 模块 models 链建表完成: 6/6(governance 4 含 privacy_consent + template 2)"
|
||||
|
||||
# ---- 10a-base. 基座模块(appbase / rbac)models 链建表 ----
|
||||
# [Bug 4SxqQAulkH9eAzEys_h-e 根因闭环 / QC 未过项 #1]
|
||||
# 症状链:POST /main/rbac/user/up_login.dspy → 500 "Server got itself in trouble"
|
||||
# ← ERROR 1146 (42S02) Table 'pbl.users' doesn't exist
|
||||
# ← build.sh 建表段只覆盖 scripts/ddl/pbls_tables.sql(32 张 pbl_* 手写表)
|
||||
# 与 modules/pbl_*/models(6 张治理/模板域表,第 10a 步),
|
||||
# 基座 appbase(appcodes/appcodes_kv/params/svgicon)与
|
||||
# rbac(users/role/permission/rolepermission/userrole/organization/orgtypes/audit_log)
|
||||
# 的 models 链从未被建表。
|
||||
# 本段职责:① 从 models 单一真源重新生成 base_tables.sql + alias map(脚本自带
|
||||
# 「表数<8 或 users 缺失即 die」门禁);② 用 env 派生的连接参数执行建表;
|
||||
# ③ information_schema 逐张点名自校验(防计数虚高);④ 全部 IF NOT EXISTS,幂等。
|
||||
# 口径边界:本段只新增 12 张基座表,不触碰第 10 步 32 张手写表门禁、
|
||||
# 第 10a 步 6 张模块链表门禁,也不改动后续 38 关键表终态门禁的口径。
|
||||
[ -f "${BASE_GEN}" ] || die "缺少基座 DDL 生成器 ${BASE_GEN}"
|
||||
|
||||
# gen_base_ddl.py 只用标准库;优先用 venv 解释器(与 10a 一致),venv 不在位时回退 python3
|
||||
BASE_GEN_PY="${PY}"
|
||||
[ -x "${BASE_GEN_PY}" ] || BASE_GEN_PY="python3"
|
||||
|
||||
# 把 WS_DIR 交给生成器(其候选链第 2 项 = ${WS_DIR}/pkgs);BASE_PKGS_ROOT 仅在
|
||||
# 真实存在时导出,否则留给生成器自带的三段式探测(会逐条打印候选与存在性,不静默)。
|
||||
export WS_DIR
|
||||
if [ -d "${BASE_PKGS_ROOT}" ]; then
|
||||
export BASE_PKGS_ROOT
|
||||
log "[10a-base] BASE_PKGS_ROOT=${BASE_PKGS_ROOT} exists=yes(显式导出)"
|
||||
else
|
||||
log "[10a-base][WARN] BASE_PKGS_ROOT=${BASE_PKGS_ROOT} exists=no —— 交由 gen_base_ddl.py 三段式探测基座包根(其候选含 /d/pipeline/pipeline-app/pkgs),探测过程逐条回显"
|
||||
fi
|
||||
log "[10a-base] 生成基座 DDL: ${BASE_GEN_PY} ${BASE_GEN}"
|
||||
log "[10a-base] 输出: ${BASE_DDL_FILE} / ${BASE_ALIAS_MAP}"
|
||||
"${BASE_GEN_PY}" "${BASE_GEN}" \
|
||||
--out "${BASE_DDL_FILE}" \
|
||||
--alias-map "${BASE_ALIAS_MAP}" \
|
||||
|| die "[10a-base] gen_base_ddl.py 失败(基座 models 读取不完整 / users 缺失 / BASE_PKGS_ROOT 不可达,详见上方 [gen_base_ddl] 真实错误链)"
|
||||
|
||||
# 生成产物存在性 + 生成器 SELF_CHECK 口径复核(不依赖 stderr 抓取,直接数 SQL 文件)
|
||||
[ -f "${BASE_DDL_FILE}" ] || die "[10a-base] 生成器未产出 ${BASE_DDL_FILE}"
|
||||
[ -f "${BASE_ALIAS_MAP}" ] || die "[10a-base] 生成器未产出 ${BASE_ALIAS_MAP}(声明表名→真源表名对照,test/deploy 探针据此改用真名消除 1146 误报)"
|
||||
BASE_SQL_TABLES="$(grep -c 'CREATE TABLE IF NOT EXISTS' "${BASE_DDL_FILE}" || true)"
|
||||
[ "${BASE_SQL_TABLES}" -ge 8 ] || die "[10a-base] base_tables.sql 仅含 ${BASE_SQL_TABLES} 张表(<8),基座 models 读取不完整"
|
||||
grep -q 'CREATE TABLE IF NOT EXISTS `users`' "${BASE_DDL_FILE}" \
|
||||
|| die "[10a-base] base_tables.sql 不含 users 表 —— up_login.dspy 500 根因未消除"
|
||||
log "[10a-base] 生成校验通过: base_tables.sql 含 ${BASE_SQL_TABLES} 张表,users=present"
|
||||
|
||||
log "[10a-base] 执行基座 DDL: ${BASE_DDL_FILE} → ${DB_NAME}@${DB_HOST}:${DB_PORT}"
|
||||
mysql --protocol=TCP -h"${DB_HOST}" -P"${DB_PORT}" -u"${DB_USER}" -p"${DB_PASS}" \
|
||||
--default-character-set=utf8mb4 "${DB_NAME}" < "${BASE_DDL_FILE}" \
|
||||
|| die "[10a-base] 基座 DDL 执行失败(连接参数取自 ${ENV_FILE},请核对 db.host/port/user/password 可达性)"
|
||||
|
||||
# 自校验:逐张点名(IN 列表),不用 LIKE —— LIKE 会被同前缀表/迁移备份表干扰而虚高判死。
|
||||
# 期望 12 张:appbase 4(appcodes/appcodes_kv/params/svgicon)
|
||||
# + rbac 8(audit_log/organization/orgtypes/permission/role/rolepermission/userrole/users)
|
||||
BASE_TABLES="'appcodes','appcodes_kv','params','svgicon','audit_log','organization','orgtypes','permission','role','rolepermission','userrole','users'"
|
||||
BASE_ACTUAL="$(mysql --protocol=TCP -h"${DB_HOST}" -P"${DB_PORT}" -u"${DB_USER}" -p"${DB_PASS}" \
|
||||
-N -B -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='${DB_NAME}' AND table_name IN (${BASE_TABLES})" "${DB_NAME}")"
|
||||
log "[10a-base] 基座表点名核验: ${BASE_ACTUAL}/12(appbase 4 + rbac 8)"
|
||||
[ "${BASE_ACTUAL}" = "12" ] || {
|
||||
MISSING="$(mysql --protocol=TCP -h"${DB_HOST}" -P"${DB_PORT}" -u"${DB_USER}" -p"${DB_PASS}" \
|
||||
-N -B -e "SELECT t.n FROM (SELECT 'appcodes' n UNION ALL SELECT 'appcodes_kv' UNION ALL SELECT 'params' UNION ALL SELECT 'svgicon' UNION ALL SELECT 'audit_log' UNION ALL SELECT 'organization' UNION ALL SELECT 'orgtypes' UNION ALL SELECT 'permission' UNION ALL SELECT 'role' UNION ALL SELECT 'rolepermission' UNION ALL SELECT 'userrole' UNION ALL SELECT 'users') t LEFT JOIN information_schema.tables i ON i.table_schema='${DB_NAME}' AND i.table_name=t.n WHERE i.table_name IS NULL" "${DB_NAME}" | tr '\n' ' ')"
|
||||
die "[10a-base] 基座表在场数应为 12,实际 ${BASE_ACTUAL};缺失: ${MISSING:-(无法枚举)}"
|
||||
}
|
||||
|
||||
# users 表单独点名(登录链路命门,QC 验收项要求显式回显 users=present)
|
||||
USERS_PRESENT="$(mysql --protocol=TCP -h"${DB_HOST}" -P"${DB_PORT}" -u"${DB_USER}" -p"${DB_PASS}" \
|
||||
-N -B -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='${DB_NAME}' AND table_name='users'" "${DB_NAME}")"
|
||||
[ "${USERS_PRESENT}" = "1" ] || die "[10a-base] users 表不存在 —— up_login.dspy 仍会 ERROR 1146 → 500"
|
||||
# up_login.dspy 锁定检查/成功登录写的三列必须在位(来源 pkgs/rbac/migration/*.sql,
|
||||
# models/users.json 未含,由 gen_base_ddl.py 补齐;此处对已存在的旧表做终态核验)
|
||||
USERS_LOGIN_COLS="$(mysql --protocol=TCP -h"${DB_HOST}" -P"${DB_PORT}" -u"${DB_USER}" -p"${DB_PASS}" \
|
||||
-N -B -e "SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='${DB_NAME}' AND table_name='users' AND column_name IN ('username','login_fail_count','last_login_fail','last_login')" "${DB_NAME}")"
|
||||
[ "${USERS_LOGIN_COLS}" = "4" ] || die "[10a-base] users 表登录链列不全(username/login_fail_count/last_login_fail/last_login 应在场 4,实际 ${USERS_LOGIN_COLS})"
|
||||
log "[10a-base] SELF_CHECK base_tables: PASS tables=${BASE_ACTUAL}/12 users=present login_cols=${USERS_LOGIN_COLS}/4"
|
||||
|
||||
# ---- 10b. 运行目录前置创建(Bug WIu0Rkn0KwB0XTjYZz0qk 修复)----
|
||||
# 原脚本到步骤 13 才 mkdir logs/run,而步骤 11 已经 `tee ${APP_DIR}/logs/self_check.log`。
|
||||
# 全新克隆(仓库不含 logs/,.gitignore 也排除 *.log)时 tee 打不开文件 →
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user