问题
- 4 处运行时 DDL(scheduling / ele / feedback / mileage 日报)分散在路由与 store 里;
- 只读保护只按 HTTP 方法拦截,而建表由 GET 处理器触发,
于是 DB_READ_ONLY=1 的"只读预览"仍可能执行 CREATE TABLE / ALTER TABLE(已记录在案的漏洞)。
改动
- 新增 src/server/db/schema/{guard,scheduling,ele,feedback,mileage-report}.ts:
建表/改表的唯一位置;guard 提供 ddlAllowed(),DB_READ_ONLY=1 时每个 ensure* 直接跳过并打印一行日志。
- daily-report-store 的表名改为从 schema 模块导出,避免两处各写一份表名。
- 移除 feedback/index.ts 与 ele/migration.ts 中的内联 DDL。
验证
- 实测:DB_READ_ONLY=1 下依次调用 4 个 ensure*,全部跳过且未触碰数据库(无连接错误/挂起)。
- 架构测试新增 2 条:DDL 只允许出现在 server/db/schema;每个 schema 模块必须检查 ddlAllowed()。
lint / test(139) / build 全绿。
17 lines
546 B
TypeScript
17 lines
546 B
TypeScript
import { isDbReadOnly } from '../../config.js';
|
|
|
|
/**
|
|
* 运行时建表守卫。
|
|
*
|
|
* 只读预览(DB_READ_ONLY=1)下不允许任何 DDL。此前只读保护只按 HTTP 方法拦截,
|
|
* 而建表实际由 GET 处理器触发,于是"只读"预览仍可能执行 CREATE TABLE。
|
|
*/
|
|
export function ddlAllowed(): boolean {
|
|
return !isDbReadOnly();
|
|
}
|
|
|
|
/** 统一的跳过日志,避免每个 schema 模块各写一份。 */
|
|
export function logDdlSkipped(name: string): void {
|
|
console.log(`[schema] ${name} skipped (DB_READ_ONLY=1)`);
|
|
}
|