From 102cd1f9d07ffc6516a7e61c6000b3f54681caee Mon Sep 17 00:00:00 2001 From: curo1305 Date: Fri, 26 Jun 2026 22:28:57 +0200 Subject: [PATCH] docs(14.1-04): complete browse-parity and row-navigation plan --- .planning/ROADMAP.md | 6 +- .planning/STATE.md | 9 +- .../14.1-04-SUMMARY.md | 253 ++++++++++++++++++ 3 files changed, 261 insertions(+), 7 deletions(-) create mode 100644 .planning/phases/14.1-cloud-local-file-parity-hardening/14.1-04-SUMMARY.md diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index d27a967..8ceb1f9 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -26,7 +26,7 @@ Before any phase is marked complete: | 12 | 6/6 | Complete | 2026-06-21 | | 13 | 11/11 | Complete | 2026-06-23 | | 14 | 9/9 | Complete | 2026-06-23 | -| 14.1 | 3/5 | In Progress| | +| 14.1 | 4/5 | In Progress| | | 14.2 | Cross-Codebase Review and Cleanup | Cross-reference backend/frontend code, remove duplication and dead code, consolidate shared paths, and fix inefficiencies without behavior changes | Cross-cutting quality gates | | 15 | Unified Smart Search | Search local and analyzed cloud documents by exact text or semantic ideas without downloading files during queries | SEARCH-01..07 | | 16 | Change Tracking and Reliability | Detect external provider changes, mark stale indexes, remove deleted items, and harden refresh behavior | SYNC-02..04 | @@ -141,7 +141,7 @@ Plans: **Goal:** Cloud files opened, viewed, downloaded, analyzed, and displayed in results use the same user-facing behavior as local files, while preserving provider ownership, cache boundaries, authorization, and no-provider-mutation guarantees. **Requirements:** CLOUD-02, ANALYZE-01, ANALYZE-02, ANALYZE-03, ANALYZE-04, ANALYZE-05, ANALYZE-06, ANALYZE-07, CACHE-03, CACHE-04, CACHE-05 **Depends on:** Phase 14 -**Plans:** 3/5 plans executed +**Plans:** 4/5 plans executed **Execution waves:** Wave 1: 14.1-01 (RED tests); Wave 2: 14.1-02 after 01 (backend detail/force/retry); Wave 3: 14.1-03 after 01-02 (shared detail surface + cloud route/view); Wave 4: 14.1-04 after 01-03 (browser row parity + cloud row navigation); Wave 5: 14.1-05 after 01-04 (gates, security, docs, version, commit). Plans: @@ -149,7 +149,7 @@ Plans: - [x] 14.1-01-PLAN.md — RED backend + frontend parity tests (cloud detail endpoint, force re-analyze, single-item retry, route + row parity). - [x] 14.1-02-PLAN.md — Backend cloud detail endpoint (CloudItemDetailOut + resolve_owned_cloud_item_detail), force re-analyze flag, single-item retry-job creation. - [x] 14.1-03-PLAN.md — Shared DocumentDetailSurface extraction, DocumentView refactor (Re-analyze copy), CloudDetailView + cloud-file-detail route + getCloudItemDetail. -- [ ] 14.1-04-PLAN.md — Browse row topics/analysis_status/stale, StorageBrowser row parity via store translator, cloud row click → cloud detail route (no auto preview/download). +- [x] 14.1-04-PLAN.md — Browse row topics/analysis_status/stale, StorageBrowser row parity via store translator, cloud row click → cloud detail route (no auto preview/download). - [ ] 14.1-05-PLAN.md — Full test suites, security gate, dependency/secret audits, CLAUDE.md/README updates, version bump, atomic commit. **Success Criteria:** diff --git a/.planning/STATE.md b/.planning/STATE.md index 5c35ff1..8bc38cd 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -6,14 +6,14 @@ current_phase: 14.1 current_phase_name: cloud-local-file-parity-hardening status: executing stopped_at: Phase 14.1 UI-SPEC approved -last_updated: "2026-06-26T20:14:05.841Z" +last_updated: "2026-06-26T20:28:34.275Z" last_activity: 2026-06-26 last_activity_desc: Phase 14.1 execution started progress: total_phases: 8 completed_phases: 4 total_plans: 35 - completed_plans: 33 + completed_plans: 34 percent: 50 --- @@ -26,7 +26,7 @@ progress: ## Current Position Phase: 14.1 (cloud-local-file-parity-hardening) — EXECUTING -Plan: 4 of 5 +Plan: 5 of 5 Status: Ready to execute Last activity: 2026-06-26 — Phase 14.1 execution started @@ -76,6 +76,7 @@ Last activity: 2026-06-26 — Phase 14.1 execution started | Phase 14.1 P01 | 13m | 2 tasks | 4 files | | Phase 14.1 P02 | 18m | 2 tasks | 5 files | | Phase 14.1 P03 | 5m | 2 tasks | 6 files | +| Phase 14.1 P04 | 15m | 2 tasks | 5 files | ## Accumulated Context @@ -128,7 +129,7 @@ _Updated at each phase transition._ | Field | Value | |---|---| -| Last session | 2026-06-26T20:13:33.570Z | +| Last session | 2026-06-26T20:28:34.269Z | | Next action | Plan 14.1 | | Pending decisions | None | | Resume file | .planning/phases/14.1-cloud-local-file-parity-hardening/14.1-UI-SPEC.md | diff --git a/.planning/phases/14.1-cloud-local-file-parity-hardening/14.1-04-SUMMARY.md b/.planning/phases/14.1-cloud-local-file-parity-hardening/14.1-04-SUMMARY.md new file mode 100644 index 0000000..a3502d7 --- /dev/null +++ b/.planning/phases/14.1-cloud-local-file-parity-hardening/14.1-04-SUMMARY.md @@ -0,0 +1,253 @@ +--- +phase: 14.1-cloud-local-file-parity-hardening +plan: "04" +subsystem: cloud-browse-parity-frontend +status: complete +tags: [backend, frontend, browse, parity, analysis-status, topics, cloud-detail-route, row-click] +requirements: [CLOUD-02, ANALYZE-01, ANALYZE-02, ANALYZE-03, ANALYZE-04, ANALYZE-05, ANALYZE-06, CACHE-03] + +dependency_graph: + requires: + - 14.1-01 (RED tests — StorageBrowser.parity.test.js must go green) + - 14.1-02 (backend detail endpoint and CloudItemOut schema) + - 14.1-03 (cloud-file-detail route in router/index.js + CloudDetailView) + provides: + - backend/api/cloud/schemas.py (CloudItemOut gains topics, analysis_status, is_stale) + - backend/api/cloud/browse.py (_item_out populates parity fields; _batch_load_topics) + - frontend/src/components/storage/StorageBrowser.vue (row parity slots; store translator) + - frontend/src/views/CloudFolderView.vue (onFileOpen navigates to cloud-file-detail) + - frontend/src/views/__tests__/CloudFolderOpenPreview.test.js (updated to new behavior) + affects: + - frontend/src/views/CloudDetailView.vue (is the target of cloud row navigation) + +tech_stack: + added: [] + patterns: + - Batch topic-name JOIN query to avoid N+1 browse rows (T-14.1-10) + - Single analysis action slot in name cell (Analyze/Re-analyze/Retry by state — D-08/D-10) + - Store translateAnalysisStatus as single status translation source (D-06) + - Row click navigates to internal named route (cloud-file-detail); no auto preview/download (D-14) + - Inline status badge in cloud file rows (green/amber/blue/red per UI-SPEC) + +key_files: + created: [] + modified: + - backend/api/cloud/schemas.py + - backend/api/cloud/browse.py + - frontend/src/components/storage/StorageBrowser.vue + - frontend/src/views/CloudFolderView.vue + - frontend/src/views/__tests__/CloudFolderOpenPreview.test.js + +decisions: + - CloudItemOut row fields (topics/analysis_status/is_stale) are an allowlist — no extracted_text (T-14.1-10) + - _batch_load_topics uses a single JOIN over CloudItemTopic + Topic for all file ids in the page + - Folder rows always receive analysis_status=None and topics=[] from _item_out + - cloudRowActionKind() drives the single analysis action slot — exactly one of Analyze/Re-analyze/Retry renders at a time + - translateStatus in StorageBrowser now delegates to cloudStore.translateAnalysisStatus (D-06 CLAUDE.md rule) + - onFileOpen in CloudFolderView replaced with router.push to cloud-file-detail (D-01/D-14/CACHE-03) + - CloudFolderOpenPreview.test.js updated to assert route navigation instead of openCloudFile calls + +metrics: + duration: "15m" + completed_date: "2026-06-26" + tasks_completed: 2 + files_created: 0 + files_modified: 5 + backend_tests_passing: 88 + frontend_tests_passing: 489 + test_suite_delta: +1 (pre-existing RED test for Re-analyze now green; 0 new failures) +--- + +# Phase 14.1 Plan 04: Browse Row Parity + Cloud Row Navigation Summary + +Make cloud browser rows/cards match local rows: surface lightweight topics + analysis status + current/stale state from the browse endpoint, render them in the same relative slots in StorageBrowser, route cloud row clicks to the cloud detail route (not auto preview/download), and collapse the duplicate status translator so the store is the single source. + +## Tasks Completed + +### Task 1: Browse rows carry lightweight topics + analysis_status + stale; StorageBrowser renders parity slots via store translator + +**`backend/api/cloud/schemas.py`:** + +Extended `CloudItemOut` with three lightweight, allowlisted row fields: +- `topics: List[str] = []` — topic name strings; empty for folders/unanalyzed files +- `analysis_status: Optional[str] = None` — None for folder rows +- `is_stale: bool = False` — True when `analysis_status == "stale"` (D-07 convenience flag) + +`extracted_text` is deliberately absent from `CloudItemOut` (T-14.1-10 allowlist rule — row payload must stay lightweight; full text stays on `CloudItemDetailOut` only). + +**`backend/api/cloud/browse.py`:** + +- Added `from db.models import CloudItemTopic, Topic` and `from sqlalchemy import select` imports. +- `_item_out` updated to accept optional `topic_names: list[str] | None` and populate `analysis_status`, `is_stale`, and `topics` from the passed topics list. Folder rows always receive `analysis_status=None`, `topics=[]`. +- Added `_batch_load_topics(session, file_ids)` — a single `SELECT cloud_item_topics.cloud_item_id, topics.name FROM cloud_item_topics JOIN topics ON ...` query over the page's file item ids. Returns a dict mapping `cloud_item_id → [str]`. Avoids N+1 queries (T-14.1-10). +- `browse_connection_items` computes `file_ids`, calls `_batch_load_topics`, then passes `topic_names=topics_by_item.get(item.id)` to `_item_out` for each row. + +**`frontend/src/components/storage/StorageBrowser.vue`:** + +- Imported `useCloudConnectionsStore` and instantiated `cloudStore` at the top of `