# 前后端通信约定 当前后端是相邻的 `hono-api` 仓库,默认根地址 `http://localhost:3000`。业务接口由 Hono 提供,认证由 Better Auth 提供;旧 `opencloud-backend` FastAPI 项目不参与当前调用。 ## 职责 | 层 | 文件 | 负责内容 | | ------------ | ------------------------------------------------- | ----------------------------------------------------------- | | HTTP 传输 | `src/lib/api.ts` | Cookie、查询编码、JSON/FormData、HTTP 错误和 401 事件 | | 业务调用 | `src/features/{clouds,profile,admin}/api.ts` | 资源路径、输入/输出类型、批量分块、分页收集、响应适配 | | 响应适配 | `src/lib/api-adapters.ts` | 生成 DTO 到前端视图模型的明确映射,图片 URL | | 后端契约 | `src/types/api-contract.ts` | 从后端 schema 生成并同步,禁止手改 | | 前端模型 | `src/types/models.ts`、`src/types/view-models.ts` | 页面需要的 Cloud、CloudType、Profile、CloudDetail、AuthUser | | 认证客户端 | `src/features/auth/authClient.ts` | Better Auth SDK 与其独立错误协议 | | 页面与 store | `src/features/` | 交互、缓存、业务展示;调用业务 API 模块 | 页面不再直接调用 `apiRequest`;ESLint 会检查该规则。传输层不引用云图/用户模型,也不承担认证 SDK 的职责。后端数据库命名、HTTP 字段命名和页面显示字段各自有明确适配位置。稀有度统一使用后端数值,不再伪造 `common` 分类。 ## 请求与响应 `apiRequest` 的路径相对于后端根地址,如 `/clouds`,不要加入 `/api/v1`。查询条件通过 `query` 对象传入,由传输层编码一次。JSON body 是普通对象,上传模块接受类型化参数并构建 FormData,浏览器生成 multipart Content-Type。 所有请求携带 Cookie。`auth: false` 表示该公开请求的 401 不触发清空登录状态,并不禁止携带 Cookie。需要登录的请求默认派发 `opencloud:auth-expired`。传输层不会重试写操作;网络错误、非法成功响应及结构化 HTTP 错误会抛给调用者。 业务错误为 `{message, issues?}`,保存在 `ApiError.message/status/detail`。成功 JSON 响应必须能解析;204 返回 undefined。图片 URL 直接用于媒体元素,不通过 JSON 请求函数。 云图分页使用 `{items, page, page_size, has_more}`。页面通过 `has_more` 控制下一页;热力图、点赞集合与当前管理统计需要完整集合时,由业务 API 使用 `collectPages` 收集。地图为上限 1000 条的时间范围数组,用户管理与云类型目录目前为非分页数组。没有实时订阅或跨页快照。 批量变更每次最多 100 个 UUID。已完成的删除批次立即修补缓存,后续批次失败不会回滚。上传仍逐张进行,失败前已上传的云图保留;没有恢复上传或自动整批重试。 ## 契约同步与验证 后端 `src/schemas/` 是单一事实来源。后端生成的 `contracts/api.ts` 只含 HTTP 类型,不引入数据库、SDK、服务端配置或运行时包。前端保存类型快照,独立构建不依赖旁边存在后端仓库。 两仓库配套修改时: ```bash # 在 hono-api 中 npm run contract:generate npm run check # 在 opencloud 中 npm run api:sync npm run api:check npm run check npm run build ``` 后端不在默认位置时,设置 `OPENCLOUD_API_DIR` 为实际路径。`api:check` 比较已生成的后端类型与前端快照,不会替代后端的 `contract:check`;两者都通过才能确认契约一致。前端 `npm test` 使用 Node 内置测试与 TypeScript 类型剥离,需要 Node 22.18+,不新增测试框架依赖。 ## 部署与迁移 此次改动需要两端一起发布或回滚。旧路径 `/cloud`、`/profile`、`/image`、`/info/cloudtype` 改为 `/clouds`、`/profiles`、`/images`、`/cloud-types`;旧请求字段 `type_id/user_name/user_role` 改为 `cloud_type_id/username/role`。云图响应使用 `cloud_type/review_status`,日期统一 ISO UTC,批量 ID 为字符串数组。 认证仍在 `/auth/*`,VITE_API_URL 仍为后端根地址。完整端点与迁移表在后端 `API.md`。本次不需要数据库迁移,TypeScript 字段改名显式映射原数据库列。