apps/server/docs/ai-context/architecture-overview.md
apps/server 是一个基于 Hono 的 Node 服务端,负责认证、角色/聊天/Provider 配置、Flux 余额、Stripe 充值和面向 gateway 的 LLM 代理。整体模式是:
Postgres 负责持久化与账本真相Redis 负责缓存、配置 KV、Pub/Sub、Streamsinjeca 负责把这些依赖组装成一个可启动应用核心入口在 src/app.ts:
createApp()
runApiServer()
uncaughtException / unhandledRejectionCLI 入口在 src/bin/run.ts,支持两种角色:
apibilling-consumerapp.ts 使用 injeca.provide() 注册依赖,依赖关系大致如下:
envoteldbredisconfigKVauthcharacterServiceproviderServicechatServicestripeServicefluxTransactionServicefluxServicerequestLogServicebillingService这个装配顺序说明了几个事实:
billingService 依赖 db + redisfluxService 只读余额,不承担余额写入职责auth 直接绑定数据库 schema,不是外部独立服务在 src/routes/ 和 src/middlewares/:
valibotsessionMiddleware 和 authGuardApiErroronError 转成标准 JSON 错误响应在 src/services/:
characters.tschats.tsproviders.tsflux.tsbilling-service.tsstripe.ts这里是主要改动面。大多数业务改动都不应该直接写进 route handler。
在 src/schemas/:
@proj-airi/server-schema 提供app.ts 启动时会执行迁移全局中间件链路大致是:
/api/* 启用 CORShono/loggerotelMiddlewaresessionMiddlewarebodyLimit(1MB)需要记住的行为:
/ws/chat 在 bodyLimit 之前注册sessionMiddleware 不会阻断匿名请求,只是往 context 填 user/sessionauthGuard 才会真正返回 401rate-limit.ts 目前是内存限流,不是分布式限流统一错误类型在 src/utils/error.ts:
ApiError(statusCode, errorCode, message, details)约定:
ApiError500 INTERNAL_SERVER_ERRORFluxService
BillingService
这是服务端最重要的边界之一,尽量不要把写余额逻辑重新塞回 flux.ts。
/api/v1/openai 并不直接调具体模型 provider,而是转发到 config: GATEWAY_BASE_URL。因此:
Redis 在这里同时承担:
但余额真相仍然在 Postgres。
src/services/request-log.ts 和 src/services/llm-request-log.ts 职责重复,当前实际注入的是前者。src/schemas/accounts.ts 和 src/schemas/auth.ts 内容重复,createAuth() 使用的是 accounts.ts。src/routes/openai/v1/index.ts 已实现 handleTTS / handleTranscription,但路由仍被注释掉,当前只开放 chat completions。