Commit Graph

6 Commits

Author SHA1 Message Date
imbytecat ebe0970df1 feat(mysql): 接入只读电池数据源 2026-05-11 20:51:24 +08:00
imbytecat fafe02bdbd refactor: 主动审计修复多处可观测性、依赖、代码质量缺口
通过并行 explore + librarian + 自查发现并修复:

代码缺陷
- shutdown.ts: db.$client.end().finally(...) 静默吞错——关闭失败会
  谎报 "DB pool closed" 后照常 exit 0。改用 await + try/catch
  分别记录成功/失败,setTimeout 也换成 Bun.sleep。
- interceptors.ts: 两条 instanceof ORPCError && instanceof
  ValidationError 重复检查,改用 early return + 单 if 分支区分 code。
- types.ts: 移除从未被引用的 RouterInputs 死代码(仅 RouterOutputs
  被 TodoItem 用到)。

Bun 原生 API(删/换 Node 兼容层)
- fields.ts: uuid v7 → Bun.randomUUIDv7(),删除 uuid 依赖
- migrate.ts: node:crypto.createHash → Bun.CryptoHasher.hash,
  少一个 Promise.all 项 + 一个 import
- shutdown.ts: setTimeout → Bun.sleep(顺带)

Biome 2.4 规则补强
- domains.types: "all"——开启类型感知规则集(noFloatingPromises /
  noMisusedPromises / useAwaitThenable / noUnnecessaryConditions
  等 Promise/异步陷阱)
- domains.drizzle: "recommended"、domains.react: "recommended"
- 显式开启 suspicious.noImportCycles(2.4 已 promote)

文档
- AGENTS.md 在 Stack & runtime 段加 "Prefer Bun-native APIs"
  原则,列出 UUIDv7/SHA-256/sleep/Bun.file 的优先路径
- AGENTS.md 在 Code style (Biome) 段记录本次启用的 lint domain
  与 noImportCycles 规则

验证:fix / typecheck / test 3/3 / build 568ms / compile 117M /
docker compose 全套(migrate JSON 日志 ✓、UUIDv7 写入 ✓、SIGTERM
shutdown 正确序列化 ✓)
2026-04-25 17:06:22 +08:00
imbytecat 34d2cbb1cd refactor(logging): 二次审计修复 oracle 漏掉的可观测性缺口与占位符冗余
二次深度审计发现:

1. shutdown.ts SIGINT/SIGTERM 路径完全沉默——生产环境 k8s pod 终止时
   操作者在日志里看不到任何痕迹。补 getLogger(['shutdown']) 三条日志:
   - "Draining for shutdown" {signal, graceMs} (优雅关停起点)
   - "Forcing exit on repeated signal" {signal} (二次信号强制退出)
   - "DB pool closed, exiting" (干净退出确认)

2. interceptors.ts 与 shutdown.ts 的 {error}/{signal} 占位符在 JSON 模式
   下导致 message 字段重复 inspect 转义 properties 里的同一份内容
   (Error/对象会被 JSON.stringify 内联进 message,引号被反斜杠转义)。
   规则收敛:占位符仅用于"想要内联渲染"的基本类型(id、count、duration),
   对象/Error 直接放 properties,message 保持人类可读短句。

3. AGENTS.md Logging 段更新示例与规则,反映实际最佳实践。

端到端验证(compose + Postgres 18-alpine):
- /api/rpc/todo/list 成功 → logger=db level=INFO 输出 SQL ✓
- /api/rpc/todo/create 校验失败 → logger=api level=ERROR
  message="Unhandled error in ORPC handler" 干净,properties.error
  完整保留 code/status/message/data 字段 ✓
- SIGTERM → 三条 shutdown logger 事件按预期输出 ✓
- typecheck / test 3/3 / build / compile 117M 全绿 ✓
2026-04-25 16:24:00 +08:00
imbytecat 830c908712 refactor(arch): 移除 experimental_defaults,提炼 useInvalidateTodos,闭环若干悬挂配置
- orpc.ts: 改为纯 createTanstackQueryUtils,不再依赖 experimental_ API
- 抽出 src/client/queries/todo.ts 的 useInvalidateTodos,避免 query key 散落页面
- shutdown: setTimeout 内 db.$client.end() 失败也走 process.exit
- 删除 db/index.ts 未被使用的 DB 类型导出
- 删除 env.ts 未被消费的 VITE_APP_TITLE,根 title 改为 package.json name
- 清理 routes/index.tsx 的 JSX 区段注释、compose.yaml 注释掉的端口块、robots.txt URL 注释
2026-04-25 13:31:16 +08:00
imbytecat d15b22ad1b refactor(db): 去掉 lazy singleton,改为模块级 const db
getDB/closeDB + 可空单例是 Cloudflare Workers 场景的模式——每个请求独
立上下文、不允许模块加载期副作用。在 Bun 单进程长驻服务下这些都是冗余
的仪式,徒增心智。

改为模块级 const db:
- src/server/db/index.ts 直接 export drizzle(...) 实例
- shutdown 插件用 db.$client.end() 收尾
- db.middleware.ts 跟随内部重命名以避免同名遮蔽(本身的去留放到下一
  次提交)
2026-04-24 20:36:16 +08:00
imbytecat 1af5d4e3c0 fix: 修复编译二进制 Ctrl+C 无法退出的问题 2026-04-02 07:48:25 +08:00