app-template/packages/trpc/AGENTS.md

78 lines
3.6 KiB
Markdown
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.

# AGENTS.md — @app/trpc
## 职责
API 层:**tRPC 路由 + service 业务逻辑**。service 可不依赖 tRPC 独立调用(脚本/测试);DB 读写经 `@app/dao`,不直接写 SQL。
域划分:
- 账户域:`user`、`auth`
- 媒体域:挂在 `media` 路由下的 mount / library / stream / danmaku / scrape / playback
新域按同样模式追加。
## 结构
```
src/
context.ts # initTRPC 单例 + TrpcContext
router/
index.ts # appRouter 组装(权威定义:user / auth / media)
user.router.ts # user 路由(与 index.ts 内定义重复,改路由时两边同步或收敛到一处)
auth.router.ts # auth 路由
media.router.ts # 媒体域扁平 procedure(mount* / library* / scrape* / playback* / danmaku*)
services/
user.service.ts # userService
auth.service.ts # authService:会话 / 密码
password.ts # scrypt 哈希(与 @app/db seed 一致)
procedure.ts # protectedProcedure 等
secret.ts # 媒体流密钥
mount.service.ts # mountService:WebDAV 挂载
webdav-client.ts # WebDAV 客户端(含单测)
library.service.ts # libraryService:扫描 / 分组 / 剧集
stream.service.ts # 流式输出(含单测)
danmaku.service.ts # danmakuService:弹幕拉取 / 导入 / 设置(含单测)
scrape.service.ts # scrapeService:番剧识别 / 绑定(含单测)
playback.service.ts # playbackService:进度上报 / 续播
load-env.ts
server.ts # 独立 HTTP 服务(PORT,默认 4000)
index.ts # 对外:appRouter、类型、services
router.ts # 兼容旧入口的再导出
```
构建:`vite build`(`emptyOutDir: false`)→ `tsc -p tsconfig.dts.json` 产出 `.d.ts`。勿开 dts 的 incremental(vite 会先清产物,缓存会导致 tsc 跳过 emit);勿改回 vite-plugin-dts。
## 请求流
```
web /api/trpc ──► appRouter ──► service ──► @app/dao ──► @app/db
```
也可 `yarn dev:api` 跑 `server.ts`(独立端口);web SSR 内嵌时通常不用。
媒体域 procedure 用 `protectedProcedure`(需登录,取 `ctx.userId`);路由层只做 input 映射 + 调 service。
## 修改指南
1. **改入参**:先改 `@app/types` 的 Zod schema,再挂到 `t.procedure.input(...)`。
2. **加 procedure**:路由只做 input 映射 + 调 service;业务在 `services/*.service.ts`;SQL 在 `@app/dao`。
3. **加领域**:新建 `services/x.service.ts` + 在 `media.router.ts`(或新 `router/x.router.ts`)挂 procedure,接到 `appRouter`,并在 `index.ts` 导出。
4. 导出给前端的类型用 `RouterInputs` / `RouterOutputs`(来自 `router/index.ts`)。
5. 外部 API(弹幕/刮削)调用集中在对应 service,注意超时与错误包装;SSRF/路径穿越防护见 `stream.service` / `webdav-client`。
## 约束
- `exactOptionalPropertyTypes`:service 的 update 入参写成 `name?: string | undefined`。
- `noUncheckedIndexedAccess`:判空逻辑在 DAO 内处理(参考 `userDao.create`)。
- 不要在 router/service 里写 SQL;不在 service 里依赖 HTTP/tRPC context(除非鉴权明确需要)。
- `router.ts` 仅兼容旧 import,新代码从 `index.ts` / `./router/index.js` 引入。
- service 旁的 `*.test.ts` 用 vitest/vite 跑(`vite.config.ts`),改行为时同步补测。
## 命令
```bash
yarn workspace @app/trpc typecheck
yarn workspace @app/trpc lint
yarn workspace @app/trpc build
yarn workspace @app/trpc dev # tsx watch src/server.ts
```