feat(bitable): 多维表格文件层 + 默认字段 + 表内字段操作 (Stage 1) #3

Merged
fischer merged 1 commits from feat/bitable-ui-stage1 into main 2026-06-29 09:25:30 +08:00
Owner

概述

实现多维表格 UI 完整性 Stage 1(U1-U6),对齐飞书/twenty 的文件层、默认字段与表内字段操作能力。本 PR 同时包含 ce-code-review 走查发现的 P0/P1 修复。

变更范围

后端(U1-U2)

  • 新增 BitableFile 实体(models/db/repository/service/routes),确立三级层级:文件 → 数据表 → 字段/记录
  • Schema V2 迁移:bitable_files 表 + tables.file_id 列,幂等(IF NOT EXISTS),保留 V1 孤儿表
  • 新建数据表自动创建 5 个默认字段(标题/状态/日期/创建人/创建时间)
  • agent-owned 字段在 create_record 时自动填充(按 type+owner 匹配,传入 actor_user_id
  • 7 个文件 REST 端点 + IDOR ownership 检查(404-before-403,internal token 旁路)

前端(U3-U5)

  • 文件列表页(FileCard 网格 + 新建/重命名/删除)+ 文件详情页(侧栏表格列表 + vxe-table 网格)
  • Vue Router 嵌套路由 /bitable/bitable/:fileId/bitable/:fileId/:tableId
  • 列头菜单(编辑/隐藏/删除字段)+ 末尾 + 列新增字段
  • select/multiselect 字段自定义单元格编辑器 + Tag 展示
  • Pinia store 扩展 file 状态与动作,深链直访回退 getFile,fileId 切换 watch

测试(U6)

  • 文件 CRUD(12 例)+ 默认字段(10 例)单元测试
  • 3 个 E2E spec(视图加载、文件流、字段操作),后端不可用时优雅跳过

ce-code-review 修复(P0/P1)

级别 问题 修复
P0 GET /files/{file_id} 遮蔽下载端点 下载改 /uploads/{filename}
P0 field/record/view 的 update/delete 缺 ownership(IDOR) 五端点补 _check_table_ownership
P1 is_initialized property 缺失致二次初始化崩溃 新增只读 property
P1 直接 URL 导航失效(files 数组为空) selectFile 回退 getFile
P1 fileId 切换不重载 增加 watch
P1 轮询丢弃最终公式值 wasCalculating 守卫 + 复用视图 filters
P1 测试断言 200 vs 201;test_db 无 URL 用例永不执行 改 201;解除模块级 postgres 标记
P2 _check_table_ownership 403 泄露存在性 改 404
P2 输入长度校验缺失;upload field-table 不一致;multiselect 浅比较 Field 约束 + 一致性校验 + 深比较

验证

  • ruff check 通过
  • pytest tests/unit/bitable/91 passed, 116 skipped(PG 依赖测试跳过)
  • vue-tsc --noEmit 通过
  • test_bitable_db_without_url_raises 现可执行(原被 postgres 标记跳过)

后续 Stage

Stage 2-4(视图配置面板、记录高级操作、agent 写入集成)见计划文档,本 PR 仅含 Stage 1。

计划文档

  • 需求:docs/brainstorms/2026-06-29-bitable-ui-completeness-requirements.md
  • 计划:docs/plans/2026-06-29-001-feat-bitable-ui-completeness-stage1-plan.md
## 概述 实现多维表格 UI 完整性 Stage 1(U1-U6),对齐飞书/twenty 的文件层、默认字段与表内字段操作能力。本 PR 同时包含 ce-code-review 走查发现的 P0/P1 修复。 ## 变更范围 ### 后端(U1-U2) - 新增 `BitableFile` 实体(models/db/repository/service/routes),确立三级层级:**文件 → 数据表 → 字段/记录** - Schema V2 迁移:`bitable_files` 表 + `tables.file_id` 列,幂等(`IF NOT EXISTS`),保留 V1 孤儿表 - 新建数据表自动创建 5 个默认字段(标题/状态/日期/创建人/创建时间) - agent-owned 字段在 `create_record` 时自动填充(按 type+owner 匹配,传入 `actor_user_id`) - 7 个文件 REST 端点 + IDOR ownership 检查(404-before-403,internal token 旁路) ### 前端(U3-U5) - 文件列表页(FileCard 网格 + 新建/重命名/删除)+ 文件详情页(侧栏表格列表 + vxe-table 网格) - Vue Router 嵌套路由 `/bitable` → `/bitable/:fileId` → `/bitable/:fileId/:tableId` - 列头菜单(编辑/隐藏/删除字段)+ 末尾 `+` 列新增字段 - select/multiselect 字段自定义单元格编辑器 + Tag 展示 - Pinia store 扩展 file 状态与动作,深链直访回退 `getFile`,fileId 切换 watch ### 测试(U6) - 文件 CRUD(12 例)+ 默认字段(10 例)单元测试 - 3 个 E2E spec(视图加载、文件流、字段操作),后端不可用时优雅跳过 ## ce-code-review 修复(P0/P1) | 级别 | 问题 | 修复 | |------|------|------| | P0 | `GET /files/{file_id}` 遮蔽下载端点 | 下载改 `/uploads/{filename}` | | P0 | field/record/view 的 update/delete 缺 ownership(IDOR) | 五端点补 `_check_table_ownership` | | P1 | `is_initialized` property 缺失致二次初始化崩溃 | 新增只读 property | | P1 | 直接 URL 导航失效(files 数组为空) | `selectFile` 回退 `getFile` | | P1 | fileId 切换不重载 | 增加 watch | | P1 | 轮询丢弃最终公式值 | `wasCalculating` 守卫 + 复用视图 filters | | P1 | 测试断言 200 vs 201;test_db 无 URL 用例永不执行 | 改 201;解除模块级 postgres 标记 | | P2 | `_check_table_ownership` 403 泄露存在性 | 改 404 | | P2 | 输入长度校验缺失;upload field-table 不一致;multiselect 浅比较 | Field 约束 + 一致性校验 + 深比较 | ## 验证 - `ruff check` 通过 - `pytest tests/unit/bitable/`:**91 passed, 116 skipped**(PG 依赖测试跳过) - `vue-tsc --noEmit` 通过 - `test_bitable_db_without_url_raises` 现可执行(原被 postgres 标记跳过) ## 后续 Stage Stage 2-4(视图配置面板、记录高级操作、agent 写入集成)见计划文档,本 PR 仅含 Stage 1。 ## 计划文档 - 需求:`docs/brainstorms/2026-06-29-bitable-ui-completeness-requirements.md` - 计划:`docs/plans/2026-06-29-001-feat-bitable-ui-completeness-stage1-plan.md`
fischer added 1 commit 2026-06-29 04:09:20 +08:00
Test / backend-test (pull_request) Has been cancelled Details
Test / frontend-unit (pull_request) Has been cancelled Details
Test / api-e2e (pull_request) Has been cancelled Details
Test / frontend-e2e (pull_request) Has been cancelled Details
a6e1bf5884
feat(bitable): 多维表格文件层 + 默认字段 + 表内字段操作 + ce-code-review 修复 (Stage 1)
实现多维表格 UI 完整性 Stage 1(U1-U6),补齐飞书/twenty 对齐缺失的文件层、
默认字段与表内字段操作能力,并修复 ce-code-review 走查发现的 P0/P1 级问题。

后端(U1-U2):
- 新增 BitableFile 实体(models/db/repository/service/routes),三级层级:文件→数据表→字段/记录
- Schema V2 迁移:bitable_files 表 + tables.file_id 列,幂等(IF NOT EXISTS),保留 V1 孤儿表
- 新建数据表自动创建 5 个默认字段(标题/状态/日期/创建人/创建时间)
- agent-owned 字段在 create_record 时自动填充(按 type+owner 匹配,传 actor_user_id)
- 7 个文件 REST 端点 + IDOR ownership 检查(404-before-403,internal token 旁路)

前端(U3-U5):
- 文件列表页(FileCard 网格 + 新建/重命名/删除)+ 文件详情页(侧栏表格列表 + vxe-table 网格)
- Vue Router 嵌套路由 /bitable → /bitable/:fileId → /bitable/:fileId/:tableId
- 列头菜单(编辑/隐藏/删除字段)+ 末尾 + 列新增字段
- select/multiselect 字段自定义单元格编辑器 + Tag 展示
- Pinia store 扩展 file 状态与动作,深链直访回退 getFile,fileId 切换 watch

测试(U6):
- 文件 CRUD(12 例)+ 默认字段(10 例)单元测试
- 3 个 E2E spec(视图加载、文件流、字段操作),后端不可用时优雅跳过

ce-code-review 修复(P0/P1):
- P0 路由冲突:GET /files/{file_id} 遮蔽下载端点 → 下载改 /uploads/{filename}
- P0 IDOR:update/delete field/record/view 五端点补 ownership 检查
- P1 is_initialized property 缺失致二次初始化崩溃
- P1 直接 URL 导航失效(files 数组为空)→ selectFile 回退 getFile
- P1 fileId 切换不重载 → 增加 watch
- P1 轮询丢弃最终公式值(wasCalculating 守卫)+ 复用视图 filters
- P1 测试断言 200→201;test_db 无 URL 用例解除 postgres 标记得以执行
- P2 _check_table_ownership 403→404;输入长度校验;upload field-table 一致性校验
- P2 multiselect 浅比较 → 深比较;E2E bitable-view 补 waitForServer 守卫

验证:ruff check 通过;pytest 91 passed/116 skipped;vue-tsc --noEmit 通过。
fischer merged commit 6e65352df8 into main 2026-06-29 09:25:30 +08:00
Sign in to join this conversation.
No reviewers
No Label
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: fischer/fischer-agentkit#3
No description provided.