Conversation
#70(后端):引入 rusqlite(bundled)作为统一本地存储。 - 新增横切 db.rs:Database 句柄(Mutex<Connection>)、PRAGMA user_version 迁移 runner、 全部 DDL(config_blob / tracked_pr / dispatch_key|event / review_session|history_item)、 with_conn/with_tx;setup 内 manage 为 tauri::State。 - config/pr-registry/pr-ledger 的 load/save 由 tauri-plugin-store 改 SQLite(保留 migrate_value/validate 与 WRITE_LOCK 语义、serde golden)。 - 新增 review/history_store:会话元数据 + 历史内容持久化;pump emit 后 best-effort 落库(按 item_id 合并 delta),状态转移镜像到 review_session。 - 新命令 get_session_history / get_pr_sessions(注册于 lib.rs)。 - 一次性 legacy JSON→SQLite 导入(meta 守卫,旧文件保留可回退)。 - webhook PR 经现有 ingest 落 tracked_pr,gh 不可用时仍可存可查。 #67(前端):合并 ProjectSwitcher + PrList 为单列 ProjectNav(项目 H2 一级分组、 活动项目展开其 PR),消除两条分离边栏;会话面板保持独立。 - useReviewStore.focus 改为从持久历史水合(打开历史会话看之前内容)。 - ReviewSessions 改为按选中 PR 展示其会话(durable getPrSessions + 实时叠加)。 - api/types 增 getSessionHistory / getPrSessions。 Closes #67 Closes #70 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- F2 可靠性:去掉 review_history_item → review_session 的 FK 约束(best-effort 历史捕获不应因 session 行缺失而 FK 违反静默丢整段历史;孤儿行可读优于丢失)。 - F1 产品:focus 水合历史改为「合并」而非覆写——await 窗口内到达的 live deltas (新 itemId)不再被 history 覆盖丢弃。 - F3 安全:history_store::status_wire 的 unwrap_or_default 改 expect fail-fast。 - F4 产品:ReviewSessions 切 PR 时同步清空旧 durable(消除 stale flash)+ 增加 loading / 加载失败 错误态(避免静默空列表)。 - F5 测试:补 get_pr_sessions 排序、SessionStatus 存储往返(锁 Deserialize 路径)、 corrupt labels_json 降级、去 FK 后孤儿 append 等测试。 - F6 DX:批量订正迁移后过时注释(prs.json/ledger.json/Store::set/key-prefix), 修正 config/model.rs 中 id 校验的过时技术理由(project_id 现为列非键前缀)。 遗留(large / 需人工决策,见 pm:ship 评论):会话/历史无界增长保留策略、 u64→i64 类型、persist 失败 UI 可见性、会话按时间排序(需 wire 加 createdAt)、 import_legacy_stores 跨切片集成测试。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🛠 ship review + fixreviewer 6(六维度并行,diff 2351 行 ≥1500 → 6 档)· Findings 11(已修 small 6 · 遗留 large 5 · OUT_OF_SCOPE 0)
完整详表(根因 + 证据 + 建议 + 方案种子,/fix 读此)F1 [P1·small·产品]
F2 [P2·small·可靠性]
F3 [P2·small·安全]
F4 [P2·small·产品]
F5 [P2·small·测试]
F6 [P2·small·DX] scheduler/commands/registry/ledger/config 多处
F7 [P2·large·可靠性]
F8 [P2·large·安全] registry/ledger/history
F9 [P2·large·安全]
F10 [P3·large·产品]
F11 [P2·large·测试]
下一步:切 🤖 PR #71 · Generated with Claude Code · branch Feature/67-70-sqlite-nav · worktree worktrees/Feature/67-70-sqlite-nav · session — |
CI 检查结果状态:通过(已通过 2 / 共 2 个检查)
🤖 PR #71 · Generated with Claude Code · branch Feature/67-70-sqlite-nav · worktree worktrees/Feature/67-70-sqlite-nav · session — |
Summary
引入 SQLite 作为统一本地持久化(config / PR / ledger 迁入 + 新增会话元数据·历史内容·webhook-PR),并把主页面合并为「项目 → PR」单列导航、会话面板独立支持回看历史内容。
Why / 背景
tauri-plugin-store的 JSON;review 会话只在内存SessionRegistry、流式 deltas emit 后即丢。后果:gh不可用时 webhook PR 无法稳妥暂存;重启后会话 ID 丢失;历史会话「点击前已产生的内容」无法回看。引入 SQLite 作为统一存储并提供清晰的 schema + 迁移/初始化逻辑。ProjectSwitcher(边栏1) +PrList(边栏2) 两条分离边栏 + 全局会话列表。改为「项目作为一级 H2 分组、PR 嵌入其下」,消除分离边栏结构。Refs
Closes #67
Closes #70
ref:
src-tauri/src/db.rs(横切 SQLite 句柄 + 迁移 runner + 全部 DDL)ref:
src-tauri/src/review/history_store.rs(会话/历史持久化)ref:
src/pr/ProjectNav.vue(合并 ProjectSwitcher + PrList)Risk / 兼容性
lib::import_legacy_stores,meta('legacyImported')守卫只跑一次,插入与守卫同一事务可重跑)。旧config.json/prs.json/ledger.json保留不删(可回退/降级,导入守卫令其惰性失效)。config 以原始值入config_blob,load仍跑migrate_value,已测。config/service、pr/registry、pr/ledger的 load/save 由 store 改 SQLite;保留migrate_value/validate、WRITE_LOCK/LEDGER_WRITE_LOCK语义与全部既有 serde golden / 行为测试(已移植为 SQLite 往返测试)。HistoryItem(= 前端StreamItem同形,serde golden 锁 camelCase);新增命令get_session_history/get_pr_sessions注册于lib.rs。model.rs↔types.ts共享契约未变。ProjectSwitcher.vue/PrList.vue(合并入ProjectNav.vue);useReviewStore.focus改为 async(从历史水合);ReviewSessions改为按选中 PR 取 durable 会话。切片边界(slice-boundary.test.ts)保持。rusqlite(bundled特性,编译期需 C 编译器;无系统 sqlite 依赖)。Test plan
pnpm build本地通过(vue-tsc 类型检查 + vite build)cargo build --manifest-path src-tauri/Cargo.toml --locked本地通过cargo clippy --manifest-path src-tauri/Cargo.toml --all-targets --locked -- -D warnings0 告警cargo fmt --manifest-path src-tauri/Cargo.toml --all -- --check干净cargo test --manifest-path src-tauri/Cargo.toml --locked通过(238 通过)pnpm test(vitest)通过(114 通过,含 slice-boundary、useReviewStore 历史水合)🤖 Generated with Claude Code