feat: 添加 PocketBase MiniApp 公司 API 文档和文件字段迁移脚本
- 新增 openapi-miniapp-company.yaml 文件,定义 tbl_company 的基础 CRUD 接口文档,包括查询、创建、更新和删除公司记录的详细描述和示例。 - 新增 pocketbase.file-fields-to-attachments.js 脚本,用于迁移 PocketBase 中的文件字段到文本字段,并处理 tbl_attachments 集合的公开规则。
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-03-28
|
||||
@@ -0,0 +1,77 @@
|
||||
## Context
|
||||
|
||||
当前 PocketBase hooks 项目已经不再是单一的微信登录接口集合,而是同时承担管理端页面、附件上传、文档管理、字典管理和 PocketBase SDK 直连权限配置。最近一轮需求把“所有业务文件集中存入 `tbl_attachments`”和“管理用户可直接为角色配置 collection CRUD 权限”两个方向一起落地,涉及数据库字段、路由 body limit、返回模型、页面交互和线上 schema 变更。
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- 用 OpenSpec 为已完成能力建立正式归档,明确能力边界。
|
||||
- 记录“仅 `tbl_attachments` 保存真实文件,其他表只保存附件 ID”的统一模型。
|
||||
- 记录文档管理页的三类附件与保存体验要求。
|
||||
- 记录 SDK 权限页的角色驱动授权模型和 UI 约束。
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- 不替代现有 OpenAPI 文档。
|
||||
- 不重新设计 PocketBase 的 `_superusers` 体系。
|
||||
- 不把所有复杂业务权限都迁移成 PocketBase 原生 rules 以外的自定义表达式语言。
|
||||
|
||||
## Decisions
|
||||
|
||||
### 1. 业务文件统一收敛到 `tbl_attachments`
|
||||
|
||||
除 `tbl_attachments.attachments_link` 外,不再保留其他业务 `file` 字段。文档、字典、用户资料等业务记录统一保存 `attachments_id`,读取时再由 hooks 反查附件元数据与文件流链接。
|
||||
|
||||
这样做的原因:
|
||||
|
||||
- 避免多个业务表重复持有文件字段,降低 schema 演化成本。
|
||||
- 统一附件上传、回读、删除引用校验逻辑。
|
||||
- 让 PocketBase SDK 与 hooks API 在附件访问上共享同一套标识。
|
||||
|
||||
### 2. 多附件字段统一使用 `|` 分隔的文本存储
|
||||
|
||||
`document_image`、`document_video`、`document_file` 等多附件字段继续使用 `text`,并以 `|` 分隔多个 `attachments_id`。hooks service 负责序列化、反序列化和联查回读。
|
||||
|
||||
这样做的原因:
|
||||
|
||||
- 与项目现有字典聚合字段设计风格一致。
|
||||
- 避免为每类附件单独引入子表或 relation migration。
|
||||
- 在 PocketBase JSVM hooks 环境里实现最简单直接。
|
||||
|
||||
### 3. 大文件上传继续走 hooks 自定义路由,但显式放宽 body limit
|
||||
|
||||
上传接口仍使用 `/pb/api/attachment/upload`,并通过 PocketBase custom route 的 `$apis.bodyLimit(...)` 放宽请求体限制。数据库字段 `attachments_link.maxSize` 已解除额外限制,上传链路重点落在自定义路由与网关配置协同。
|
||||
|
||||
这样做的原因:
|
||||
|
||||
- 保持现有 `ManagePlatform` 鉴权、业务字段补充和返回结构不变。
|
||||
- 避免直接开放 `tbl_attachments.createRule` 给 SDK 原生写入。
|
||||
|
||||
### 4. SDK 直连权限按“角色 -> 集合 -> CRUD”建模
|
||||
|
||||
权限页以角色为中心展示每个 collection 的 `list/view/create/update/delete` 五类直连权限,并直接映射到 PocketBase collection rules。页面不显示角色 ID,只显示角色名称;勾选后立即保存;公开和 custom 规则不提供可编辑勾选框。
|
||||
|
||||
这样做的原因:
|
||||
|
||||
- 用户理解成本比“直接编辑 rule 字符串”更低。
|
||||
- 保持 `ManagePlatform` 用户通过 hooks 页面管理,而不是要求他们成为 `_superusers`。
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- `[PocketBase rule 冲突]` → 如果 collection 已经使用复杂 custom rule,权限页只做只读提示,不强行覆盖。
|
||||
- `[大文件上传依赖基础设施]` → 即使 hooks 已放宽 body limit,仍需同步保证 Nginx / 反代允许更大请求体。
|
||||
- `[文本分隔字段的一致性]` → 所有写入都必须经由 service 统一序列化,避免手工写入脏值。
|
||||
- `[附件公开读取]` → `tbl_attachments` 公开 list/view 使文件流可直接访问,因此真正的业务访问控制必须由保存附件 ID 的业务表承担。
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. 通过 schema 脚本和 `POCKETBASE_AUTH_TOKEN` 为 `tbl_document` 增加 `document_file` 字段。
|
||||
2. 部署更新后的 hooks 路由、service 与管理页面。
|
||||
3. 校验文档管理页三类附件上传、编辑与回显。
|
||||
4. 校验 SDK 权限页角色分配、即时保存和 collection rules 同步。
|
||||
5. 归档到 OpenSpec 与项目既有归档文档。
|
||||
|
||||
## Open Questions
|
||||
|
||||
- 暂无新的未决问题;当前能力范围已经按现有实现归档。
|
||||
@@ -0,0 +1,29 @@
|
||||
## Why
|
||||
|
||||
PocketBase hooks 项目最近连续完成了附件集中存储、文档管理增强、字典项图片、用户图片字段收敛、SDK 直连权限管理等一批跨模块能力,但仓库里还没有对应的 OpenSpec 记录。现在这些功能已经全部落地,需要把需求范围、能力边界和影响面正式归档,避免后续继续开发时只能依赖聊天记录回溯。
|
||||
|
||||
## What Changes
|
||||
|
||||
- 将业务表中的上传文件统一收敛为 `tbl_attachments.attachments_id` 引用,实际文件仅保存在 `tbl_attachments.attachments_link`。
|
||||
- 扩展 `tbl_document`,新增 `document_file`,并让 `document_image`、`document_video`、`document_file` 全部支持多附件、`|` 分隔存储与联表回读。
|
||||
- 增强 `manage/document-manage` 页面,补齐三类附件上传、拖拽上传、编辑态保持、局部状态提示、全屏图片预览和大文件上传体验。
|
||||
- 新增 `manage/sdk-permission-manage` 页面,用于按角色为 `tbl_auth_users` 用户分配 PocketBase SDK 直连 CRUD 权限,并把角色授权与 collection rules 管理收敛到 hooks 页面中。
|
||||
- 同步更新 OpenAPI、项目归档文档、PocketBase schema 脚本与线上 `document_file` 字段。
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `attachment-backed-media`: 统一附件存储、附件 ID 引用、附件回读与公开下载策略。
|
||||
- `document-manage-console`: 文档管理页面的三类附件编辑、上传体验和保存反馈。
|
||||
- `sdk-collection-permissions`: 面向角色的 PocketBase SDK 直连权限分配与可视化管理。
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- None.
|
||||
|
||||
## Impact
|
||||
|
||||
- 受影响代码位于 `pocket-base/bai_api_pb_hooks/`、`pocket-base/bai_web_pb_hooks/`、`script/`、`docs/`、`pocket-base/spec/`。
|
||||
- 受影响系统包括 PocketBase schema、PocketBase hooks 页面、附件上传路由、文档管理 API、字典管理 API、用户资料返回结构与 SDK 直连权限页。
|
||||
- 线上已通过 `POCKETBASE_AUTH_TOKEN` 补齐 `tbl_document.document_file` 字段,后续部署需继续保持 hooks 与 schema 一致。
|
||||
@@ -0,0 +1,62 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Business records SHALL reference attachments by ID
|
||||
|
||||
The system SHALL store business media references as `tbl_attachments.attachments_id` values, and `tbl_attachments.attachments_link` SHALL remain the only business file field that stores actual uploaded file data.
|
||||
|
||||
#### Scenario: Document media is stored by attachment ID
|
||||
|
||||
- **WHEN** a document is created or updated with images, videos, or files
|
||||
- **THEN** the document record SHALL store attachment IDs in `document_image`, `document_video`, and `document_file` instead of raw file payloads
|
||||
|
||||
#### Scenario: Dictionary item images are stored by attachment ID
|
||||
|
||||
- **WHEN** a dictionary item image is uploaded from the dictionary management page
|
||||
- **THEN** the dictionary record SHALL persist the returned `attachments_id` in the aggregated dictionary image field
|
||||
|
||||
#### Scenario: User image fields are stored by attachment ID
|
||||
|
||||
- **WHEN** user profile-related image fields are written through hooks
|
||||
- **THEN** `users_picture`, `users_id_pic_a`, `users_id_pic_b`, and `users_title_picture` SHALL store attachment IDs only
|
||||
|
||||
### Requirement: Hooks SHALL resolve attachment metadata for referenced media
|
||||
|
||||
The system SHALL resolve attachment-backed fields to include file stream URLs and attachment metadata when hooks return documents, dictionaries, or user records.
|
||||
|
||||
#### Scenario: Document query returns attachment-backed links
|
||||
|
||||
- **WHEN** a document list or detail request is handled
|
||||
- **THEN** the response SHALL include attachment-backed URL and metadata fields for images, videos, and files derived from the stored attachment IDs
|
||||
|
||||
#### Scenario: Dictionary query returns item image links
|
||||
|
||||
- **WHEN** a dictionary list or detail request is handled
|
||||
- **THEN** each dictionary item with an image SHALL include the stored attachment ID, a resolved file URL, and the corresponding attachment metadata
|
||||
|
||||
#### Scenario: User query returns image URLs
|
||||
|
||||
- **WHEN** a user-facing hooks response contains attachment-backed image fields
|
||||
- **THEN** the response SHALL include resolved `..._url` and `..._attachment` fields for those image references
|
||||
|
||||
### Requirement: Attachment access SHALL separate read visibility from write control
|
||||
|
||||
The system SHALL allow public read access to attachment records and file streams at the PocketBase collection level, while write access SHALL continue to be controlled by hooks and existing `ManagePlatform` restrictions.
|
||||
|
||||
#### Scenario: Attachment records are publicly readable
|
||||
|
||||
- **WHEN** a client reads `tbl_attachments` through PocketBase list or view access
|
||||
- **THEN** the collection SHALL allow reading attachment metadata and downloading the linked file stream
|
||||
|
||||
#### Scenario: Hooks upload endpoint remains managed
|
||||
|
||||
- **WHEN** a client calls the hooks attachment management endpoints
|
||||
- **THEN** the existing `ManagePlatform` restrictions for hooks-controlled upload and management flows SHALL remain in effect
|
||||
|
||||
### Requirement: Attachment upload SHALL support large multipart requests
|
||||
|
||||
The hooks attachment upload route SHALL explicitly configure a larger PocketBase custom-route body limit so that large files can pass through the hooks layer without being rejected by the default request size limit.
|
||||
|
||||
#### Scenario: Large upload is accepted by custom route
|
||||
|
||||
- **WHEN** a client uploads a file larger than the default PocketBase custom-route body threshold to `/pb/api/attachment/upload`
|
||||
- **THEN** the route SHALL accept the multipart request as long as it remains within the configured hooks and infrastructure limits
|
||||
@@ -0,0 +1,57 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Document management SHALL support three attachment categories
|
||||
|
||||
The document management console SHALL provide separate upload and editing areas for image attachments, video attachments, and generic file attachments, and the three categories SHALL all persist attachment IDs to the document record.
|
||||
|
||||
#### Scenario: User uploads generic files to a document
|
||||
|
||||
- **WHEN** a management user adds files in the file attachment area and saves the document
|
||||
- **THEN** the saved document SHALL persist those attachment IDs in `document_file`
|
||||
|
||||
#### Scenario: Existing attachments are editable by category
|
||||
|
||||
- **WHEN** a management user opens a document in edit mode
|
||||
- **THEN** the page SHALL show existing images, videos, and files in their corresponding sections and allow removing them from the document
|
||||
|
||||
### Requirement: Document editor visibility and state SHALL follow editing intent
|
||||
|
||||
The document management page SHALL load with the document list only, keep the editor hidden until the user enters create or edit mode, and SHALL remain in the current editing context after upload or save operations.
|
||||
|
||||
#### Scenario: Page loads without editor
|
||||
|
||||
- **WHEN** the user first opens `/pb/manage/document-manage`
|
||||
- **THEN** the page SHALL show the document list and SHALL NOT show the editor section until create or edit mode is entered
|
||||
|
||||
#### Scenario: Save keeps current editing context
|
||||
|
||||
- **WHEN** the user successfully creates or updates a document
|
||||
- **THEN** the page SHALL stay on the current document editing context instead of clearing the form and forcing a return to blank create mode
|
||||
|
||||
#### Scenario: Upload does not reset editor mode
|
||||
|
||||
- **WHEN** the user uploads attachments while editing a document
|
||||
- **THEN** the page SHALL keep the current editor state and SHALL NOT implicitly switch modes
|
||||
|
||||
### Requirement: Document management SHALL provide immediate user feedback
|
||||
|
||||
The document management console SHALL show operation feedback both in the global page status area and near the save actions so that users receive confirmation or error context without scrolling.
|
||||
|
||||
#### Scenario: Local save feedback is visible
|
||||
|
||||
- **WHEN** a save or upload request succeeds or fails
|
||||
- **THEN** the page SHALL show the status message below the save controls in addition to the top-level message area
|
||||
|
||||
#### Scenario: Long-running requests show blocking feedback
|
||||
|
||||
- **WHEN** the page is waiting for a long-running upload, save, delete, or query response
|
||||
- **THEN** it SHALL show a full-screen loading mask so the user can tell the action is in progress
|
||||
|
||||
### Requirement: Document and dictionary images SHALL support full-screen preview
|
||||
|
||||
Image previews rendered in the management pages SHALL support opening the original image in a full-screen preview overlay.
|
||||
|
||||
#### Scenario: User previews an image
|
||||
|
||||
- **WHEN** the user clicks an image preview in document or dictionary management
|
||||
- **THEN** the page SHALL open a full-screen overlay showing the original image and SHALL allow closing it with explicit controls
|
||||
@@ -0,0 +1,57 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Role-based SDK direct access SHALL be configurable from hooks pages
|
||||
|
||||
The system SHALL provide a hooks-mounted management page that allows `ManagePlatform` users to assign roles to auth users and configure PocketBase SDK direct-access CRUD permissions by role and collection.
|
||||
|
||||
#### Scenario: Role is assigned to an auth user
|
||||
|
||||
- **WHEN** a management user selects a role for an auth user and saves the assignment
|
||||
- **THEN** the system SHALL persist the role mapping used by the SDK direct-access permission model
|
||||
|
||||
#### Scenario: Collection operation is granted by role
|
||||
|
||||
- **WHEN** a management user authorizes a role for a collection operation such as list, view, create, update, or delete
|
||||
- **THEN** the corresponding PocketBase collection access rule SHALL be updated for that role
|
||||
|
||||
### Requirement: Role identity SHALL be name-based in the management UI
|
||||
|
||||
The hooks permission page SHALL hide internal role IDs from the UI and present role assignments and selectors by role name only.
|
||||
|
||||
#### Scenario: Current role display hides role ID
|
||||
|
||||
- **WHEN** a management user views the role assignment page
|
||||
- **THEN** current role labels and selectors SHALL show the role name without exposing the internal role ID
|
||||
|
||||
### Requirement: Permission editing SHALL be immediate and constrained by rule type
|
||||
|
||||
The permission page SHALL save authorization changes immediately after a checkbox toggle, SHALL render CRUD labels in Chinese, and SHALL prevent editing for operations already governed by public or custom rules.
|
||||
|
||||
#### Scenario: Authorization change auto-saves
|
||||
|
||||
- **WHEN** a management user toggles an editable permission checkbox
|
||||
- **THEN** the change SHALL be persisted immediately without requiring a separate save button
|
||||
|
||||
#### Scenario: Public operation is read-only
|
||||
|
||||
- **WHEN** a collection operation is already publicly accessible
|
||||
- **THEN** the page SHALL show a brief `可公开访问` notice and SHALL NOT render an editable authorization checkbox for that operation
|
||||
|
||||
#### Scenario: Custom operation is read-only
|
||||
|
||||
- **WHEN** a collection operation is governed by a custom rule
|
||||
- **THEN** the page SHALL show `当前操作使用 custom 规则,禁止修改` and SHALL NOT render an editable authorization checkbox for that operation
|
||||
|
||||
### Requirement: Collection-level bulk selection SHALL respect editable operations only
|
||||
|
||||
The permission page SHALL provide a collection-level select-all control that applies only to editable operations, and the control SHALL be disabled when the collection has no editable operations.
|
||||
|
||||
#### Scenario: Collection select-all grants editable operations
|
||||
|
||||
- **WHEN** a management user enables the collection-level select-all control
|
||||
- **THEN** all editable CRUD operations for the current role on that collection SHALL be granted and auto-saved
|
||||
|
||||
#### Scenario: Collection select-all is disabled when nothing is editable
|
||||
|
||||
- **WHEN** every operation in a collection is either public, custom, or otherwise not editable
|
||||
- **THEN** the collection-level select-all control SHALL be disabled
|
||||
@@ -0,0 +1,22 @@
|
||||
## 1. Attachment-backed Media
|
||||
|
||||
- [x] 1.1 将非 `tbl_attachments` 的业务文件字段收敛为附件 ID 语义并同步 hooks 返回结构。
|
||||
- [x] 1.2 为 `tbl_document` 增加 `document_file` 字段,并让文档附件三类字段统一支持多值存储和联查回读。
|
||||
- [x] 1.3 放宽附件上传自定义路由 body limit,修复大文件上传链路。
|
||||
|
||||
## 2. Document Manage Console
|
||||
|
||||
- [x] 2.1 扩展文档管理页面,支持图片、视频、文件三块上传区域与拖拽上传。
|
||||
- [x] 2.2 调整文档管理页交互,使编辑区默认隐藏、保存后保持当前编辑态,并在按钮区域补充局部状态提示。
|
||||
- [x] 2.3 为文档与字典页面的图片预览增加全屏查看原图能力。
|
||||
|
||||
## 3. SDK Collection Permissions
|
||||
|
||||
- [x] 3.1 新增 SDK 权限管理页面,并支持角色名称视图、用户角色绑定与 collection CRUD 权限分配。
|
||||
- [x] 3.2 将权限页交互调整为即时保存,并对 public/custom 规则提供只读说明。
|
||||
- [x] 3.3 增加集合全选、中文文案与无横向滚动布局优化。
|
||||
|
||||
## 4. Documentation and Archive
|
||||
|
||||
- [x] 4.1 同步 OpenAPI、表结构说明和 README 中与附件、文档、权限页相关的行为说明。
|
||||
- [x] 4.2 使用 OpenSpec 记录本次变更并完成归档。
|
||||
Reference in New Issue
Block a user