- 上游客户端接口化: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
35 lines
1.5 KiB
TypeScript
35 lines
1.5 KiB
TypeScript
/**
|
||
* 环境变量(部署时经 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 }
|