fix(api): requireDatabaseUrl 早失败守卫;typecheck 门禁;build 排除 test;池生命周期注释

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-10-20 19:10:19 +08:00
parent 514f37301e
commit 39734a7467
6 changed files with 45 additions and 7 deletions
+5 -1
View File
@@ -1,9 +1,13 @@
import './src/db/env.js'
import { requireDatabaseUrl } from './src/db/env.js'
import { defineConfig } from 'drizzle-kit'
// 故意不做 DATABASE_URL_TEST 回退:迁移永不指向临时测试库(Task 13 helper 用显式连接串迁移临时库)
const url = requireDatabaseUrl({ allowTestUrl: false })
export default defineConfig({
dialect: 'postgresql',
schema: './src/db/schema.ts',
out: './drizzle',
dbCredentials: { url: process.env.DATABASE_URL! },
dbCredentials: { url },
})
+2 -1
View File
@@ -4,7 +4,8 @@
"description": "SiteForge API:NestJS 模块化单体骨架(本切片以 standalone context 供 CLI 使用,不监听端口)+ Drizzle/postgres.js 接入",
"type": "module",
"scripts": {
"build": "tsc -p tsconfig.json",
"build": "tsc -p tsconfig.build.json",
"typecheck": "tsc -p tsconfig.json --noEmit",
"db:generate": "drizzle-kit generate",
"db:migrate": "drizzle-kit migrate"
},
+3 -5
View File
@@ -2,12 +2,10 @@ import './env.js'
import { drizzle } from 'drizzle-orm/postgres-js'
import postgres from 'postgres'
import * as schema from './schema.js'
import { requireDatabaseUrl } from './env.js'
// DATABASE_URL_TEST ?? DATABASE_URL 的回退链是 Task 13 集成测试的接线:
// 测试临时库优先,开发库兜底。env 加载见 ./env.ts(向上查找仓库根 .env)。
export function getDb(
connectionString = process.env.DATABASE_URL_TEST ?? process.env.DATABASE_URL!,
) {
// 每次调用都会新建连接池、由调用方持有其生命周期;`db.$client.end()` 可关闭(drizzle-orm 0.45 已暴露)。
export function getDb(connectionString = requireDatabaseUrl()) {
const sql = postgres(connectionString, { max: 5 })
return drizzle(sql, { schema })
}
+14
View File
@@ -16,3 +16,17 @@ for (;;) {
if (parent === dir) break
dir = parent
}
// 早失败守卫:postgres(undefined) 会静默回退到 OS 用户@localhost:5432(postgres.js 源码行为),
// 本机多 PG 实例时 select 1 仍会通过、迁移可能打错库,故必须在建客户端前拦截。
// allowTestUrl(默认 true):运行时连接允许 DATABASE_URL_TEST ?? DATABASE_URL 回退链(Task 13 集成测试接线);
// 传 false 则只认 DATABASE_URL——drizzle 迁移用它,保证迁移永不指向临时测试库。
export function requireDatabaseUrl({ allowTestUrl = true }: { allowTestUrl?: boolean } = {}): string {
const url = (allowTestUrl ? process.env.DATABASE_URL_TEST : undefined) ?? process.env.DATABASE_URL
if (!url) {
throw new Error(
'DATABASE_URL not set — copy .env.example to <repo-root>/.env (searched upward from cwd)',
)
}
return url
}
+14
View File
@@ -9,4 +9,18 @@ describe('数据库连接', () => {
const r = (await db.execute('select 1 as ok')) as any
expect(Number(r[0].ok)).toBe(1)
})
it('DATABASE_URL 缺失时 getDb 早失败并给出诊断信息(不静默连 localhost)', () => {
const savedTest = process.env.DATABASE_URL_TEST
const saved = process.env.DATABASE_URL
delete process.env.DATABASE_URL_TEST
delete process.env.DATABASE_URL
try {
// postgres(undefined) 会静默回退 OS 用户@localhost:5432,必须在此前置拦截
expect(() => getDb()).toThrow(/DATABASE_URL not set/)
} finally {
if (savedTest !== undefined) process.env.DATABASE_URL_TEST = savedTest
if (saved !== undefined) process.env.DATABASE_URL = saved
}
})
})
+7
View File
@@ -0,0 +1,7 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"rootDir": "."
},
"exclude": ["test"]
}