Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .claude/context-summary-macos-icon.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
## 项目上下文摘要(macos-icon)
生成时间:2026-03-17 14:00:00 +0800

### 1. 相似实现分析
- **实现1**: `script/bundle-macos.sh:30-40`
- 模式:macOS 打包时直接把 `resources/macos/OnetCli.icns` 拷入 `.app`
- 可复用:`.app` 资源目录和 `Info.plist` 生成逻辑
- 需注意:如果 `OnetCli.icns` 过期,打包不会自动从 `logo.svg` 更新

- **实现2**: `.github/workflows/release.yml:115-121`
- 模式:CI 在 macOS 上执行 `bundle-macos.sh` 和 `bundle-macos-dmg.sh`
- 可复用:当前发布链完全依赖仓库脚本,不依赖额外打包工具
- 需注意:只要修正本地脚本,CI 发布链会同步生效

- **实现3**: `logo.svg:53-55`
- 模式:图标视觉源是 SVG,圆角背景位于透明画布上
- 可复用:`logo.svg` 可以直接作为 `icns` 的单一真源
- 需注意:不同系统渲染链对 SVG 透明角处理不一致,Quick Look 会把角烘成白底

### 2. 项目约定
- **命名约定**: 脚本文件使用 kebab-case,资源文件沿用 `OnetCli.icns`
- **文件组织**: macOS 资源位于 `resources/macos/`,打包脚本位于 `script/`
- **代码风格**: Shell 脚本使用 `set -euo pipefail`,路径通过 `SCRIPT_DIR/PROJECT_DIR` 计算
- **导入/依赖**: 优先使用系统自带的 `sips` 与 `iconutil`

### 3. 可复用组件清单
- `script/bundle-macos.sh`: 现有 `.app` 打包入口
- `script/bundle-macos-dmg.sh`: 现有 `.dmg` 打包入口
- `resources/macos/Info.plist`: App bundle 元数据
- `logo.svg`: 图标源文件

### 4. 测试策略
- **验证方式**: 本地脚本执行 + `iconutil` 解包 + 像素级透明度检查
- **关键检查**:
- `generate-macos-icon.sh` 能输出合法的 `OnetCli.icns`
- `iconutil -c iconset` 能反解成功
- 反解后的 `icon_512x512.png` 四角 alpha 为 0

### 5. 依赖和集成点
- **外部依赖**: `/usr/bin/sips`、`/usr/bin/iconutil`
- **内部依赖**: `bundle-macos.sh` 依赖新的图标生成脚本
- **集成方式**: 打包前自动重建 `resources/macos/OnetCli.icns`

### 6. 技术选型理由
- **为什么用这个方案**: 直接用仓库现有 `logo.svg` 作为真源,消除手工维护旧 `.icns` 的偏差
- **优势**: 本地和 CI 行为一致;不需要引入第三方图形工具
- **风险**: `sips` 从 SVG 渲染出的母图是 512,再放大生成 1024 规格;对当前简洁图标足够,但复杂图标可能需要更高精度渲染链

### 7. 关键风险点
- **边界条件**: `qlmanage` 会把透明角渲染成白底,不能用于生成 `.icns`
- **兼容性**: 该脚本依赖 macOS 自带工具,只适合在 macOS 运行
- **工具说明**: 当前会话没有 `desktop-commander`、`context7`、`github.search_code`,本次使用本地源码检索和系统命令完成分析与验证
64 changes: 64 additions & 0 deletions .claude/context-summary-table-data-horizontal-scroll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
## 项目上下文摘要(table-data-horizontal-scroll)
生成时间:2026-03-17 14:56:57 +0800

### 1. 相似实现分析
- **实现1**: `crates/ui/src/table/state.rs:435`
- 模式:通用表格 `set_selected_cell` 在设置活动单元格时直接同步滚动句柄,保证键盘导航和可视区域一致。
- 可复用:选中单元格与滚动同步应该在同一条状态链路里完成,而不是依赖间接副作用。
- 需注意:通用表格没有 `EditTable` 的多选区兼容层,因此不能原样照搬,只能借鉴“显式滚动”思路。

- **实现2**: `crates/one_ui/src/edit_table/state.rs:377`
- 模式:`EditTable` 的键盘导航统一经过 `select_cell_for_navigation`,当前仅显式做了纵向 `scroll_to_item(..., Center)`,横向滚动依赖 `select_cell -> sync_legacy_selection -> scroll_to_col` 的间接调用。
- 可复用:可以在导航专用路径里显式补齐横向滚动,避免依赖旧兼容层的副作用。
- 需注意:当前用户已确认上下移动没有问题,问题集中在左右移动后的横向可视区域同步。

- **实现3**: `crates/one_ui/src/edit_table/state.rs:1639`
- 模式:列宽拖拽时使用 `horizontal_scroll_handle.set_offset` 直接调整水平滚动偏移。
- 可复用:说明 `EditTable` 已有“直接写入滚动偏移”的先例,可复用于键盘导航后的横向可见性保障。
- 需注意:该逻辑依赖 `bounds` 与 `col_group.bounds` 的实时位置。

- **实现4**: `crates/ui/src/virtual_list.rs:248`
- 模式:`VirtualListScrollHandle::scroll_to_item` 在水平方向会根据目标项边界修正 `scroll_offset.x`,前提是正确写入目标列索引。
- 可复用:当列边界尚未可用时,仍可作为回退方案。
- 需注意:这套逻辑属于 defer/prepaint 机制,调用方必须在状态变更后保持一次刷新通知。

### 2. 项目约定
- **命名约定**: Rust 方法和字段使用 `snake_case`,类型使用 `PascalCase`。
- **文件组织**: 表格导航和滚动状态集中在 `crates/one_ui/src/edit_table/state.rs`。
- **代码风格**: 最小改动、优先复用既有滚动句柄,不引入新的状态字段。
- **导入顺序**: 沿用文件既有顺序,不做无关重排。

### 3. 可复用组件清单
- `crates/one_ui/src/edit_table/state.rs`: `scroll_to_col`、`select_cell_for_navigation`
- `crates/one_ui/src/edit_table/state.rs`: `scroll_table_by_col_resizing`(直接写入水平偏移)
- `crates/ui/src/table/state.rs`: `set_selected_cell`
- `crates/ui/src/virtual_list.rs`: `VirtualListScrollHandle::scroll_to_item`

### 4. 测试策略
- **测试框架**: Rust 内置 `cargo test`
- **测试模式**: 以 `one-ui` 和 `db_view` 包级回归测试为主
- **参考文件**:
- `crates/one_ui/src/edit_table/state.rs`
- `crates/ui/src/table/state.rs`
- `crates/ui/src/virtual_list.rs`
- **覆盖要求**:
- `EditTable` 改动不破坏现有单元格导航与选择逻辑
- `one-ui`、`db_view` 包级测试通过
- 无法自动覆盖的 GUI 左右移动冒烟需在验证报告中留痕

### 5. 依赖和集成点
- **外部依赖**: `gpui` 的 `UniformListScrollHandle` 与 `VirtualListScrollHandle`
- **内部依赖**: `EditTableState -> render_table_row/render_table_header -> track_scroll`
- **集成方式**: 键盘左右移动更新活动单元格后,应显式写入水平滚动目标列
- **配置来源**: `row_number_enabled`、`fixed_left_cols_count`、`col_fixed`

### 6. 技术选型理由
- **为什么用这个方案**: `EditTable` 的水平滚动容器使用 `overflow_hidden`,`scroll_to_item` 可能无法驱动横向偏移。改为基于 `col_group.bounds` 与表格视口计算最小偏移量,直接 `set_offset`,更符合现有拖拽滚动模式。
- **优势**: 修改范围小,只影响 `EditTableState` 的滚动同步逻辑,且保留 `scroll_to_item` 作为 bounds 不可用时的回退。
- **劣势和风险**: 依赖 `bounds` 的实时性;初次渲染或列宽尚未测量时仍可能需要下一帧刷新才能准确对齐,需要桌面环境冒烟确认。

### 7. 关键风险点
- **并发问题**: 本次不新增异步任务,不涉及重入更新。
- **边界条件**: 需要兼容行号列、固定列和普通滚动列三种索引情况。
- **性能瓶颈**: 仅在活动列越界时写入一次水平偏移,不引入额外渲染或数据请求。
- **工具说明**: 仓库规范要求优先使用 `desktop-commander`、`context7`、`github.search_code`、`sequential-thinking`,但当前会话未提供这些工具;本次改用本地源码检索与结构化分析替代,并在日志中留痕。
63 changes: 63 additions & 0 deletions .claude/context-summary-table-data-sort-crash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
## 项目上下文摘要(table-data-sort-crash)
生成时间:2026-03-17 14:03:28 +0800

### 1. 相似实现分析
- **实现1**: `crates/one_ui/src/edit_table/state.rs:1676`
- 模式:`EditTableState` 在表头点击时先更新本地 `ColumnSort` 状态,再把排序动作委托给 delegate。
- 可复用:现有排序状态机 `Default -> Descending -> Ascending -> Default` 和行号列偏移换算。
- 需注意:delegate 回调发生在 `EditTableState` 自身的 `update` 闭包内,若回调里再次更新同一实体会触发重入保护。

- **实现2**: `crates/ui/src/table/state.rs:934`
- 模式:通用表格也采用“先切换表头状态,再调用 delegate”的两段式处理。
- 可复用:说明 `one_ui::edit_table` 的排序骨架与通用表格保持一致,问题不在排序状态机本身。
- 需注意:业务 delegate 必须避免在回调里同步回写当前表格实体。

- **实现3**: `crates/db_view/src/table_data/data_grid.rs:370`
- 模式:`DataGrid::apply_column_sort` 会先更新 `filter_editor` 的 `ORDER BY`,然后调用 `load_data_with_clauses` 触发 `self.table.update(...)` 刷新数据。
- 可复用:排序后的真实查询链路已经完整,修复时应保留这条链路。
- 需注意:该方法内部会同步更新 `EditTableState`,因此不能在 `EditTableState` 正在更新时直接调用。

- **实现4**: `crates/ui/src/dock/dock.rs:190`
- 模式:项目内已有在实体更新期间通过 `window.defer(cx, ...)` 延后关联实体更新的写法。
- 可复用:`window.defer` 适合把“当前事件引发的二次更新”延后到下一拍,规避 GPUI 的重入更新限制。
- 需注意:延后闭包里应使用克隆后的实体句柄,并处理实体已释放的情况。

### 2. 项目约定
- **命名约定**: Rust 函数与字段使用 `snake_case`,类型使用 `PascalCase`。
- **文件组织**: 表格通用状态在 `one_ui/edit_table`,业务排序/加载逻辑在 `db_view/table_data`。
- **导入顺序**: 先标准库,再本地模块和外部 crate;沿用文件当前风格,不做无关重排。
- **代码风格**: 最小改动、早返回、优先复用既有事件循环与异步调度机制。

### 3. 可复用组件清单
- `crates/one_ui/src/edit_table/state.rs`: `EditTableState::perform_sort`
- `crates/db_view/src/table_data/data_grid.rs`: `DataGrid::apply_column_sort`
- `crates/db_view/src/table_data/results_delegate.rs`: `EditorTableDelegate::perform_sort`
- `crates/ui/src/dock/dock.rs`: `window.defer(cx, ...)` 延后更新模式

### 4. 测试策略
- **测试框架**: Rust 内置 `cargo test`
- **测试模式**: 以 `db_view` 排序相关单元测试和受影响文件编译/格式验证为主
- **参考文件**:
- `crates/db_view/src/table_data/data_grid.rs` 现有排序 SQL 单元测试
- `crates/db_view/src/table_data/results_delegate.rs` 现有排序解析单元测试
- **覆盖要求**:
- 排序 SQL 生成行为不回归
- 排序子句回填表头图标行为不回归
- `db_view` 包级测试通过,确认本次延后更新未破坏数据加载链路

### 5. 依赖和集成点
- **外部依赖**: `gpui` 的实体更新与 `window.defer` 事件循环模型
- **内部依赖**: `EditTableState -> EditorTableDelegate -> DataGrid -> TableFilterEditor -> load_data_with_clauses`
- **集成方式**: 表头点击触发 delegate 排序,再由 `DataGrid` 更新 `ORDER BY` 并重新查询
- **配置来源**: `DataGridConfig.usage`、`DataGridConfig.database_type`

### 6. 技术选型理由
- **为什么用这个方案**: 根因是同步重入更新,不是排序 SQL 或查询逻辑错误;因此最小修复应只调整回调时机。
- **优势**: 只改 `results_delegate` 一处,不影响通用表格状态机和已有查询流程。
- **劣势和风险**: 排序动作会延后一拍执行,理论上会比同步触发多一个事件循环 tick,但对用户无可感知影响。

### 7. 关键风险点
- **并发问题**: 若实体在 defer 执行前已销毁,必须允许更新安全失败。
- **边界条件**: 点击不可排序列、缺少 `data_grid` 句柄、列索引越界时应继续早返回。
- **性能瓶颈**: 本次不改变服务端排序与重新查询策略,不新增额外请求。
- **工具说明**: 仓库规范要求优先使用 `desktop-commander`、`context7`、`github.search_code`、`sequential-thinking`,但当前会话未提供这些工具;本次使用本地源码检索与结构化分析替代,并在日志中留痕。
62 changes: 62 additions & 0 deletions .claude/context-summary-table-data-sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
## 项目上下文摘要(table-data-sort)
生成时间:2026-03-17 12:37:28 +0800

### 1. 相似实现分析
- **实现1**: `crates/ui/src/table/state.rs:937`
- 模式:通用表格组件在表头点击后切换 `ColumnSort`,并把排序动作委托给 delegate。
- 可复用:`perform_sort` 的状态切换顺序 `Default -> Descending -> Ascending -> Default`。
- 需注意:UI 层只负责切图标和分发事件,不直接处理业务查询。

- **实现2**: `crates/one_ui/src/edit_table/state.rs:1676`
- 模式:可编辑表格复用通用表格的排序状态机,但会处理行号列偏移。
- 可复用:`delegate_col_ix` 映射逻辑和表头排序图标渲染。
- 需注意:如果业务 delegate 不实现 `perform_sort`,点击只会改本地状态,不会触发数据刷新。

- **实现3**: `crates/db_view/src/table_data/data_grid.rs:347`
- 模式:表格数据浏览统一通过 `load_data_with_clauses` 读取 `WHERE` 和 `ORDER BY` 编辑器内容,再下发 `TableDataRequest`。
- 可复用:`with_order_by_clause` 请求链路和加载后刷新 delegate 的流程。
- 需注意:排序真正生效必须把表头事件同步到 `filter_editor.order_by_editor`。

- **实现4**: `crates/db_view/src/table_data/results_delegate.rs:384`
- 模式:结果委托会在 `update_data` 时把每一列设为 `sortable()`。
- 可复用:列元数据、列名和数据类型都已经在 delegate 中维护,无需新增状态对象。
- 需注意:`update_data` 会重建列定义,因此排序后的表头状态需要在刷新后回填。

### 2. 项目约定
- **命名约定**: Rust 方法和函数使用 `snake_case`,类型使用 `PascalCase`。
- **文件组织**: 事件分发在 `data_grid.rs`,数据行为在 `results_delegate.rs`,筛选输入在 `filter_editor.rs`。
- **导入顺序**: 先本模块 `crate::...`,再外部 crate,最后标准库。
- **代码风格**: 早返回、最小范围 helper、通过现有 delegate/编辑器组件串联行为。

### 3. 可复用组件清单
- `crates/db_view/src/table_data/filter_editor.rs`: `TableFilterEditor::get_order_by_clause`
- `crates/db_view/src/table_data/data_grid.rs`: `load_data_with_clauses`
- `crates/db_view/src/table_data/results_delegate.rs`: `update_data`
- `crates/db/src/manager.rs`: `DbManager::get_plugin`
- `crates/db/src/plugin.rs`: `DatabasePlugin::quote_identifier`

### 4. 测试策略
- **测试框架**: Rust 内置 `cargo test`
- **测试模式**: 以纯函数单元测试 + `db_view` 包级回归测试为主
- **参考文件**: `crates/db_view/src/sql_editor_view.rs`、`crates/db_view/src/table_designer_tab.rs` 中已有纯函数测试模式
- **覆盖要求**:
- 表头排序生成方言正确的 `ORDER BY`
- 排序子句能解析回表头图标状态
- `db_view` 整包测试通过,避免影响现有编辑/导出/SQL 结果逻辑

### 5. 依赖和集成点
- **外部依赖**: `db::DbManager` / `DatabasePlugin` 用于数据库方言引用符处理
- **内部依赖**: `EditTableState -> EditorTableDelegate -> DataGrid -> TableFilterEditor`
- **集成方式**: 表头点击触发 delegate `perform_sort`,由 `DataGrid` 写入 `ORDER BY` 编辑器并重新查询
- **配置来源**: `DataGridConfig.database_type` / `DataGridConfig.usage`

### 6. 技术选型理由
- **为什么用这个方案**: 仓库已经有 `ORDER BY` 编辑器和数据库插件方言能力,直接复用能避免重复拼 SQL。
- **优势**: 事件链短、数据库方言正确、和现有筛选/分页请求保持一致。
- **劣势和风险**: 只回填首个排序列的图标;复杂手写 `ORDER BY` 子句不会完整映射到多列表头状态。

### 7. 关键风险点
- **并发问题**: 排序会触发重新加载,若用户在加载中再次点击可能出现重复请求;当前沿用既有加载流程。
- **边界条件**: 列名包含关键字、空格、引号时必须使用数据库插件做标识符引用。
- **性能瓶颈**: 排序基于服务端重新查询,不在前端做大表本地排序。
- **工具说明**: 当前会话没有 `desktop-commander`、`context7`、`github.search_code`,本次使用本地源码检索和既有 crate 实现完成上下文分析。
Loading