# OpenSpec 开发归档 ## 归档日期 - 2026-03-23 ## 归档范围 本次归档覆盖 PocketBase hooks 项目在微信登录注册、PocketBase 原生 token、openid 身份收敛、错误观测、索引修复与 auth 兼容字段方面的修复与规范同步,涉及: - `pocket-base/` 作为正式 hooks 项目继续收敛规范 - 微信登录链路错误显式返回 - `recordAuthResponse` 使用空 `authMethod` - 登录/资料更新阶段 auth 保存失败信息透传 - 移除 hooks 查询中的 `-created` 排序,修复 `invalid sort field "created"` - `users_phone` 唯一索引改普通索引,允许空手机号用户注册 - `tbl_auth_users` 继续以 `openid` 作为业务身份锚点 - 为 PocketBase `auth` 集合兼容写入占位 `email`、随机密码与 `passwordConfirm` - OpenSpec 变更文档补录到 `pocket-base/spec/` --- ## 一、接口与认证结果 ### 当前 active hooks 接口 - `POST /api/system/test-helloworld` - `POST /api/system/health` - `POST /api/wechat/login` - `POST /api/wechat/profile` - `POST /api/wechat/refresh-token` ### 当前认证规则 - 正式鉴权仅使用 `Authorization: Bearer ` - `Open-Authorization` 不属于接口契约 - `users_wx_openid` Header 已移除 - 业务身份由当前 auth record 的 `openid` 唯一确定 --- ## 二、数据模型与落库策略 ### 1. `tbl_auth_users` - 维持 PocketBase `auth` 集合 - 业务身份锚点为 `openid` - 目标规则:除 `openid` 外,自定义业务字段均允许为空 ### 2. auth 集合兼容字段 由于 `tbl_auth_users` 是 auth 集合,为满足 PocketBase 原生 auth 保存要求,登录创建阶段补充: - `email = @wechat.local` - 随机密码 - `passwordConfirm` 说明: - 上述 `email` 为占位认证标识,不代表真实邮箱。 --- ## 三、问题修复归档 ### 1. 通用 400 `Something went wrong while processing your request.` 处理方式: - 登录路由本地 try/catch 显式返回 `{ code, msg, data }` - 全局错误包装提前注册 - 保存 auth 用户时透传原始错误信息 ### 2. `invalid sort field "created"` 原因: - hooks 内多个精确查询误用了 `-created` 排序 处理方式: - 统一移除 active hooks 中所有 `-created` 排序 ### 3. 注册成功前数据库无新记录 已识别的高风险点: - `users_phone` 唯一索引会让空手机号重复冲突 处理方式: - 改为普通索引 - 手机号唯一性改由资料完善阶段业务校验负责 --- ## 四、规范同步位置 本次 OpenSpec 记录新增: - `pocket-base/spec/changes.2026-03-23-pocketbase-hooks-auth-hardening.md` 当前 active 契约文件: - `pocket-base/spec/openapi.yaml` --- ## 五、当前边界 1. `tbl_auth_users` 作为 PocketBase `auth` 集合,仍受 PocketBase 内置 auth 规则影响。 2. schema 脚本放宽自定义字段必填约束时,PocketBase 服务端更新 auth 集合可能返回通用 500,需要结合服务端日志进一步确认。 3. 若线上仍报旧错误,通常表示最新 hooks 或 schema 尚未部署生效。 --- ## 归档日期 - 2026-03-20 ## 归档范围 本次归档覆盖微信小程序后端交互相关接口的设计、实现、规范同步与部署调整,涉及: - 接口路径统一收敛到 `/api` - 微信登录/注册合一 - 微信资料完善接口重构 - 微信手机号服务端换取 - `users_type` 自动维护 - JWT 认证与刷新 token - PocketBase Token 模式访问 - OpenAPI 与项目文档同步 - dist 构建与部署产物 --- ## 一、接口演进结果 ### 系统接口 - `POST /api/test-helloworld` - `POST /api/health` ### 微信小程序接口 - `POST /api/wechat/login` - 登录/注册合一 - 接收 `users_wx_code` - 自动换取 `users_wx_openid` - 若无账号则自动创建游客账号 - 返回 `status`、`is_info_complete`、`token`、完整用户信息 - `POST /api/wechat/profile` - 从 headers 读取 `users_wx_openid` - 需要 `Authorization` - body 接收: - `users_name` - `users_phone_code` - `users_picture` - 服务端调用微信接口换取真实手机号后写入 `users_phone` - `POST /api/wechat/refresh-token` - 仅依赖 `users_wx_openid` - 不要求旧 `Authorization` - 返回新的 JWT token --- ## 二、关键业务规则 ### 1. 用户类型 `users_type` - 新账号初始化:`游客` - 当且仅当用户首次从: - `users_name` 为空 - `users_phone` 为空 - `users_picture` 为空 变为: - 三项全部完整 时,自动升级为:`注册用户` - 后续资料修改不再覆盖已确定类型 ### 2. 用户资料完整度 `is_info_complete` 以下三项同时存在时为 `true`: - `users_name` - `users_phone` - `users_picture` 否则为 `false` ### 3. 微信手机号获取 服务端使用微信官方接口: - `getuserphonenumber` 通过 `users_phone_code` 换取真实手机号,再写入数据库字段 `users_phone`。 --- ## 三、鉴权规则 ### 标准请求头 - `Authorization: Bearer ` - `users_wx_openid: ` ### 当前规则 - `/api/wechat/login`:不需要 token - `/api/wechat/profile`:需要 `users_wx_openid + Authorization` - `/api/wechat/refresh-token`:**只需要** `users_wx_openid` --- ## 四、请求格式规则 所有微信写接口统一要求: - `Content-Type: application/json` 不符合时返回: - `415 请求体必须为 application/json` --- ## 五、PocketBase 访问策略 当前统一使用: - `POCKETBASE_API_URL` - `POCKETBASE_AUTH_TOKEN` 已移除: - `POCKETBASE_USER_NAME` - `POCKETBASE_PASSWORD` --- ## 六、部署与产物 后端已支持 dist 构建: - `npm run build` - 产物目录:`back-end/dist/` 当前发布目录包含: - `dist/src/` - `dist/spec/` - `dist/package.json` - `dist/package-lock.json` - `dist/.env` 生产启动方式: - `npm start` - 实际运行:`node dist/src/index.js` --- ## 七、文档同步结果 已同步更新: - `back-end/spec/openapi.yaml` - `docs/api.md` - `docs/deployment.md` - `README.md` 其中 `openapi.yaml` 已与当前真实接口行为对齐。 --- ## 八、质量验证结果 本次归档前已验证通过: - `npm run lint` - `npm run test` - `npm run build` 测试覆盖包括: - 系统接口 - 统一 404 - 登录/注册合一 - 非 JSON 拒绝 - 资料更新 - token 刷新 - `users_type` 升级逻辑 - `is_info_complete` 返回逻辑 --- ## 九、当前已知边界 1. `refresh-token` 当前仅依赖 `users_wx_openid`,未校验旧 token 2. 微信手机号能力依赖微信官方 `access_token` 与 `users_phone_code` 3. 当前后端为 JavaScript + Express 架构,未引入 TypeScript 编译链