# PocketBase Hooks API Project

这是从 `back-end/` 迁移出来的 PocketBase `bai_api_pb_hooks` 原生 API 项目。

## 目标

- 使用 PocketBase 自定义路由承载对外 API
- 最终部署时只复制 `bai_api_pb_hooks/` 整个目录到服务器的 PocketBase 实例目录
- 按接口类型拆分不同子目录，便于维护

## 目录结构

```text
pocket-base/
├─ bai-api-main.pb.js
├─ bai_api_pb_hooks/
│  ├─ bai_api_routes/
│  │  ├─ system/
│  │  └─ wechat/
│  └─ bai_api_shared/
│     ├─ config/
│     ├─ middlewares/
│     ├─ services/
│     └─ utils/
├─ spec/
├─ tests/
└─ scripts/
```

## 当前接口

- `POST /api/system/test-helloworld`
- `POST /api/system/health`
- `POST /api/system/refresh-token`
- `POST /api/platform/register`
- `POST /api/platform/login`
- `POST /api/wechat/login`
- `POST /api/wechat/profile`

> 当前自定义路由统一使用 `/api/...` 前缀。

## 鉴权说明

- 当前接口统一使用 PocketBase 原生 `Authorization: Bearer <token>`。
- `Open-Authorization` 不是本项目接口定义的 Header，如调试工具里出现，通常是工具全局预设，应删除。
- `users_wx_openid` Header 已移除，不再需要客户端额外传递。
- 当前用户身份以 PocketBase auth record 中的 `openid` 字段为准。
- `openid` 现已定义为**全平台统一身份锚点**：
	- 微信用户：`openid = 微信 openid`
	- 平台用户：`openid = 服务端生成的 GUID`
- 当前登录/注册成功后返回的 `token` 为 PocketBase 原生 auth token，可直接用于 PocketBase SDK 与本项目 hooks 接口调用。

## 平台用户与微信用户说明

### 平台用户

- 注册接口：`POST /api/platform/register`
- 登录接口：`POST /api/platform/login`
- 平台用户注册时会自动生成 GUID 并写入 `tbl_auth_users.openid`
- 同时写入 `users_idtype = ManagePlatform`
- 平台登录对前端暴露为 `login_account + password`，其中 `login_account` 支持邮箱或手机号
- 服务端内部仍使用 PocketBase 原生 password auth，以确保返回原生 `token`

### 通用认证能力

- 刷新 token 接口：`POST /api/system/refresh-token`
- 该接口属于系统级通用认证接口，不区分微信用户或平台用户
- body 中 `users_wx_code` 允许为空
- 服务端会优先验证 `Authorization`：若 token 仍有效，直接续签，不调用微信接口
- 仅当 token 失效时，且提供了 `users_wx_code`，才走微信 code 重签流程（逻辑独立于 `/api/wechat/login` 的完整返回）
- 若 token 失效且未提供 `users_wx_code`，返回：`token已过期，请上传users_wx_code`
- 返回体为精简结构，仅返回新 `token`

### 微信用户

- 登录/注册接口：`POST /api/wechat/login`
- 微信用户以微信 code 换取微信侧 openid，并写入统一 `tbl_auth_users.openid`
- 首次注册时写入 `users_idtype = WeChat`

## 部署方式

由于服务器只有一个公共 `pb_hooks/` 目录，部署时请将以下内容复制到服务器 `pb_hooks/` 根目录下：

- `bai-api-main.pb.js`
- `bai_api_pb_hooks/`

建议部署后的结构类似：

```text
pb_hooks/
├─ bai-api-main.pb.js
└─ bai_api_pb_hooks/
	├─ bai_api_routes/
	└─ bai_api_shared/
```

## 环境配置

PocketBase JSVM 不会自动读取 `back-end/.env`。当前 Hook 运行配置来自 **PocketBase 进程环境变量**。

已补充模板文件：

- `pocket-base/bai_api_pb_hooks/bai_api_shared/config/env.example`
- `pocket-base/bai_api_pb_hooks/bai_api_shared/config/runtime.example.js`

至少需要在服务器的 PocketBase 运行环境中提供，或写入 `runtime.js`：

- `WECHAT_APPID`
- `WECHAT_SECRET`

可选保留：

- `APP_BASE_URL`
- `POCKETBASE_API_URL`
- `POCKETBASE_AUTH_TOKEN`

说明：

- `WECHAT_APPID` / `WECHAT_SECRET` 是必须的，因为微信登录逻辑会直接调用微信官方接口。
- 旧 `back-end/.env` 中的这些值可以作为来源参考，但 **不会被 pb_hooks 自动读取**。
- 如果不方便改 PocketBase 进程环境，可在服务器创建：`pb_hooks/bai_api_pb_hooks/bai_api_shared/config/runtime.js`。
- `runtime.js` 的内容可直接参考 `runtime.example.js`。
- 若 hooks 内部需要回源调用 PocketBase REST（如 `auth-with-password`），`POCKETBASE_API_URL` 不应使用外部 HTTPS 域名，建议使用 PocketBase 进程/容器内可达地址，例如 `http://127.0.0.1:8080`，以避免 Nginx 443 回环失败。
- 当前 Hook 代码已不依赖自定义 JWT，因此 `JWT_SECRET`、`JWT_EXPIRES_IN` 不是运行必需项。

## 额外要求

部署前请确认 PocketBase 所在环境提供以下环境变量：

- `WECHAT_APPID`
- `WECHAT_SECRET`
如果你还需要构建时间展示，可额外提供：

- `BUILD_TIME`

## 注意

PocketBase JSVM 不是 Node.js 运行时：

- 不能直接复用 axios/jsonwebtoken/express 中间件
- 只能使用 PocketBase 暴露的全局对象，如 `$app`、`$apis`、`$http`、`$security`
- 共享逻辑必须通过 `require(`${__hooks}/...`)` 方式加载本地 CommonJS 模块

## 建议验证

迁移完成后，在 PocketBase 服务器上检查：

1. 自定义路由是否生效
2. `tbl_auth_users`、`tbl_company` 集合名是否与当前数据库一致
3. PocketBase 所在服务器是否能访问微信开放接口
4. 反向代理是否放行 `/api/` 路由

## OpenSpec 变更记录

本项目 active hooks 相关的最新规范记录见：

- `pocket-base/spec/openapi.yaml`
- `pocket-base/spec/changes.2026-03-23-pocketbase-hooks-auth-hardening.md`
- `openspec/specs/attachment-backed-media/spec.md`
- `openspec/specs/document-manage-console/spec.md`
- `openspec/specs/sdk-collection-permissions/spec.md`
- `openspec/changes/archive/2026-03-28-pocketbase-manage-media-and-sdk-permissions/`

本次变更重点包括：

- 微信登录链路错误显式返回
- 平台用户注册/登录接口补充完成
- 刷新 token 接口调整到 system 分类
- `recordAuthResponse` 使用空 `authMethod`
- active hooks 中移除 `-created` 排序
- `users_phone` 索引由唯一改为普通索引
- `tbl_auth_users` 以全平台统一 `openid` 为业务身份锚点
- auth 集合兼容占位 `email`、随机密码与 `passwordConfirm`
- 业务文件统一收敛到 `tbl_attachments`
- `tbl_document` 新增 `document_file`
- 文档管理页支持图片 / 视频 / 文件三类附件
- SDK 直连权限页支持按角色配置 collection CRUD 权限

## 与原项目关系

- 原 `back-end/` 保留不动
- 当前 `pocket-base/` 为新的正式 Hook 项目
- 后续只部署 `bai_api_pb_hooks/` 的内部内容到服务器 `pb_hooks/` 即可
