# 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 <token>`
- `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 = <openid>@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 <token>`
- `users_wx_openid: <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 编译链
