apps/server/docs/ai-context/architecture-overview.md
apps/server 是一个基于 Hono 的 Node 服务端,负责认证、角色/聊天/Provider 配置、Flux 余额、Stripe 充值和面向 gateway 的 LLM 代理。整体模式是:
Postgres 负责持久化与账本真相Redis 负责缓存、配置 KV、Pub/Sub(不再使用 Streams)injeca 负责把这些依赖组装成一个可启动应用核心入口在 src/app.ts:
createApp()
runApiServer()
uncaughtException / unhandledRejectionCLI 入口在 src/bin/run.ts,只有一种角色:
api(HTTP/WS;没有常驻后台 loop,也没有 fire-and-forget 异步任务。admin flux grant 在 POST 请求线程内同步处理完返回;详见 workers-and-runtime.md)app.ts 使用 injeca.provide() 注册依赖,依赖关系大致如下:
envoteldbredisconfigKVauthcharacterServiceproviderServicechatServicestripeServicefluxTransactionServicefluxServicerequestLogServicebillingServiceadminFluxGrantsServicettsMeteruserDeletionServiceemailService这个装配顺序说明了几个事实:
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_transaction ledger;事务提交后 best-effort 刷 Redis 余额缓存这是服务端最重要的边界之一,尽量不要把写余额逻辑重新塞回 flux.ts。
/api/v1/openai 由 services/domain/llm-router 读取 LLM_ROUTER_CONFIG 后按 upstream 链路 + key rotator 直接调 provider(OpenRouter、Azure Speech、阿里云 DashScope、火山引擎 等),不再依赖外部 knoway sidecar。因此:
services/domain/llm-router 与 services/adapters/tts 的 adapter 完成Redis 在这里同时承担:
flux-meter.md)但余额真相仍然在 Postgres。Redis Streams 已全部移除,详见 redis-boundaries-and-pubsub.md 的 NOTICE。
/api/v1/openai 当前开放:POST /chat/completions、POST /chat/completion、POST /audio/speech、GET /audio/voices。handleTranscription 路由尚未挂载。flux_grant_batch schema 已被简化版 admin-flux-grants 取代,代码 + schema 都已清理。drizzle/0011_open_unus.sql 是 drop migration(DROP TABLE flux_grant_batch / flux_grant_batch_recipient CASCADE,顺带清掉 6 个 index)。这条 DDL 是不可逆破坏,需要操作员在合适的部署窗口手动 pnpm db:push 推到 prod;只要 prod DB 还没 apply 0011,回滚 server image 不会丢数据。