Files
new-api-key-usage/apps/server/src/lib/env.ts
T
skycurtain c26012a040 feat(server): 上游客户端与 key 管理(阶段 2)
- 上游客户端接口化:UpstreamClient + HTTP / fixture 两实现(env UPSTREAM_SOURCE 切换;fixture 读仓库根样例快照,错误分支由 key 内容约定触发)
- 失败分类:401 / 403 → key_rejected;其余非 2xx / 网络故障 / 超时 / 响应异常 → upstream_unavailable
- /api/manage/api-keys 三端点:清单(按 id 升序,敏感列不出接口)· 登记(上游验证 → 上游字段全组入库)· 启停(幂等、启用需验证并清 consecutive_401s)
- 登记成功触发「立即异步补一轮」hook(引擎骨架占位,阶段 4 填充)
- 统一错误信封:onError → 500 internal · notFound → 404
- 修正:load-env 未被服务端接线(此前只有 drizzle-kit 接了),env.ts 顶部补副作用导入
- 实施计划:进度表阶段 2 ✅ · 实现假设 #11–#14
2026-09-15 00:37:22 +08:00

35 lines
1.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 环境变量(部署时经 env 注入;全量清单见仓库根 `.env.example`)。
* 缺关键变量时在「首次使用处」报错,不在进程启动时硬崩(便于本地起骨架)。
*/
// 副作用导入:显式加载仓库根 `.env`(Bun 只自动加载 cwd 的 .env,见 load-env.ts)
import './load-env'
function required(name: string): string {
const v = process.env[name]
if (!v) {
throw new Error(`缺少环境变量 ${name}(见 .env.example)`)
}
return v
}
export const env = {
/** 监听端口(Vite dev 代理与生产反代都指向它) */
port: Number(process.env.PORT ?? 3000),
/** PostgreSQL 连接串 */
databaseUrl: process.env.DATABASE_URL ?? '',
/** 管理面口令(X-Manage-Token;见 API 契约 约定 6) */
manageToken: process.env.MANAGE_TOKEN ?? '',
/** 凭证主密钥(HKDF 派生 hmac / aes 子密钥;丢失 = 全部 key 需重新登记) */
keysMasterKey: process.env.KEYS_MASTER_KEY ?? '',
/** 上游 NewAPI 站点地址(同步引擎调用的 BaseURL) */
newapiBase: process.env.NEWAPI_BASE ?? '',
/** 上游客户端实现:`http`(默认,真实站点)/ `fixture`(开发期样例文件,见实施计划 §6) */
upstreamSource:
process.env.UPSTREAM_SOURCE === 'fixture' ? ('fixture' as const) : ('http' as const),
/** 样例文件目录(仅 fixture 实现使用;空 = 仓库根) */
newapiFixtureDir: process.env.NEWAPI_FIXTURE_DIR ?? '',
}
export { required }