- 新增 openapi-miniapp-company.yaml 文件,定义 tbl_company 的基础 CRUD 接口文档,包括查询、创建、更新和删除公司记录的详细描述和示例。 - 新增 pocketbase.file-fields-to-attachments.js 脚本,用于迁移 PocketBase 中的文件字段到文本字段,并处理 tbl_attachments 集合的公开规则。
10 KiB
OpenSpec 开发归档
归档日期
- 2026-03-28
归档范围
本次归档覆盖 PocketBase hooks 项目在附件统一存储、文档管理页增强、字典项图片、用户图片字段附件化、SDK 直连权限页、文档文件字段 document_file、大文件上传 body limit 修复、以及对应 OpenAPI / 表结构文档同步方面的工作,涉及:
- 所有业务文件统一收敛到
tbl_attachments - 业务表只保存
attachments_id,并由 hooks 联表返回文件流链接 tbl_document新增document_file,与document_image、document_video一样支持多附件和|分隔存储manage/document-manage页面新增文件附件区、初始隐藏编辑区、保存后保持当前编辑态、局部状态提示、拖拽上传与全屏图片预览manage/dictionary-manage页面支持字典枚举项图片上传和全屏查看原图manage/sdk-permission-manage页面支持按角色配置 collection CRUD 直连权限,并优化为即时保存- 上传路由显式放宽 PocketBase custom route
bodyLimit - 使用
POCKETBASE_AUTH_TOKEN在线补齐tbl_document.document_file - 新增 OpenSpec 归档目录
openspec/changes/archive/2026-03-28-pocketbase-manage-media-and-sdk-permissions/
一、附件集中存储
1. 附件表作为唯一文件存储点
- 仅
tbl_attachments.attachments_link保留真实file字段 - 其他业务表不再保存实际文件
- 文档、字典、用户图片字段统一改为保存
attachments_id
2. 附件回读策略
hooks 查询时统一联查 tbl_attachments,并补充:
- 文件流链接
- 下载链接
- 附件元数据对象
适用对象包括:
- 文档图片 / 视频 / 文件
- 字典枚举项图片
- 用户头像 / 身份图 / 资质图
3. 附件访问控制
- PocketBase 原生
tbl_attachments已放开公开读取与下载 - hooks 层原有
ManagePlatform限制保持不变 - 业务访问控制继续由保存附件 ID 的业务表承担
二、文档管理增强
1. tbl_document 新增 document_file
- 新字段:
document_file - 类型:
text - 用途:保存多个文件类
attachments_id - 存储格式:
id1|id2|id3
2. 文档管理页行为
- 首次进入页面时只显示列表,不显示编辑区
- 点击“新建模式”或“编辑”后才进入编辑区
- 保存成功后保持当前文档编辑态,不再强制清空回到新建
- 保存 / 报错信息同时显示在顶部与保存按钮下方
- 图片、视频、文件三块附件区都支持拖拽上传
3. 上传链路修复
- 上传接口继续使用
/pb/api/attachment/upload - 为自定义路由显式增加更大的
bodyLimit - 解决了文件未超过数据库与网关限制但仍在 hooks 层被 413 拒绝的问题
三、SDK 直连权限管理
1. 管理页能力
- 新增
/pb/manage/sdk-permission-manage - 支持创建角色后按角色给
tbl_auth_users用户授权 - 支持逐 collection 配置
list / view / create / update / delete
2. 页面交互约束
- 页面不显示角色 ID,只显示角色名称
- 勾选权限后立即保存
public和custom规则不允许在页面里继续勾选改写- 支持集合级
全选 - 当某集合下所有操作都不可编辑时,
全选自动禁用
四、OpenSpec 记录
本次新增的 OpenSpec 记录包括:
openspec/specs/attachment-backed-media/spec.mdopenspec/specs/document-manage-console/spec.mdopenspec/specs/sdk-collection-permissions/spec.mdopenspec/changes/archive/2026-03-28-pocketbase-manage-media-and-sdk-permissions/
归档日期
- 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-helloworldPOST /api/system/healthPOST /api/wechat/loginPOST /api/wechat/profilePOST /api/wechat/refresh-token
当前认证规则
- 正式鉴权仅使用
Authorization: Bearer <token> Open-Authorization不属于接口契约users_wx_openidHeader 已移除- 业务身份由当前 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
五、当前边界
tbl_auth_users作为 PocketBaseauth集合,仍受 PocketBase 内置 auth 规则影响。- schema 脚本放宽自定义字段必填约束时,PocketBase 服务端更新 auth 集合可能返回通用 500,需要结合服务端日志进一步确认。
- 若线上仍报旧错误,通常表示最新 hooks 或 schema 尚未部署生效。
归档日期
- 2026-03-20
归档范围
本次归档覆盖微信小程序后端交互相关接口的设计、实现、规范同步与部署调整,涉及:
- 接口路径统一收敛到
/api - 微信登录/注册合一
- 微信资料完善接口重构
- 微信手机号服务端换取
users_type自动维护- JWT 认证与刷新 token
- PocketBase Token 模式访问
- OpenAPI 与项目文档同步
- dist 构建与部署产物
一、接口演进结果
系统接口
POST /api/test-helloworldPOST /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_nameusers_phone_codeusers_picture
- 服务端调用微信接口换取真实手机号后写入
users_phone
- 从 headers 读取
-
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_nameusers_phoneusers_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_URLPOCKETBASE_AUTH_TOKEN
已移除:
POCKETBASE_USER_NAMEPOCKETBASE_PASSWORD
六、部署与产物
后端已支持 dist 构建:
npm run build- 产物目录:
back-end/dist/
当前发布目录包含:
dist/src/dist/spec/dist/package.jsondist/package-lock.jsondist/.env
生产启动方式:
npm start- 实际运行:
node dist/src/index.js
七、文档同步结果
已同步更新:
back-end/spec/openapi.yamldocs/api.mddocs/deployment.mdREADME.md
其中 openapi.yaml 已与当前真实接口行为对齐。
八、质量验证结果
本次归档前已验证通过:
npm run lintnpm run testnpm run build
测试覆盖包括:
- 系统接口
- 统一 404
- 登录/注册合一
- 非 JSON 拒绝
- 资料更新
- token 刷新
users_type升级逻辑is_info_complete返回逻辑
九、当前已知边界
refresh-token当前仅依赖users_wx_openid,未校验旧 token- 微信手机号能力依赖微信官方
access_token与users_phone_code - 当前后端为 JavaScript + Express 架构,未引入 TypeScript 编译链