From 5287efd34c4e046acf18bb45a066930efbe9e805 Mon Sep 17 00:00:00 2001 From: curo1305 Date: Thu, 18 Jun 2026 23:32:41 +0200 Subject: [PATCH] docs(12-03): add plan 03 execution summary --- .../12-03-SUMMARY.md | 132 ++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 .planning/phases/12-cloud-resource-foundation/12-03-SUMMARY.md diff --git a/.planning/phases/12-cloud-resource-foundation/12-03-SUMMARY.md b/.planning/phases/12-cloud-resource-foundation/12-03-SUMMARY.md new file mode 100644 index 0000000..25c12ba --- /dev/null +++ b/.planning/phases/12-cloud-resource-foundation/12-03-SUMMARY.md @@ -0,0 +1,132 @@ +--- +phase: "12" +plan: "03" +subsystem: cloud-ui-foundation +tags: [cloud, routing, capabilities, breadcrumb, freshness, accessibility, session-storage] +dependency_graph: + requires: + - "12-02" # connection-ID browse API, CloudResourceAdapter, cloud_items metadata + provides: + - connection-ID routing (/cloud/:connectionId/:folderId) + - capability-aware action rendering (StorageBrowser) + - breadcrumb freshness indicators (BreadcrumbBar) + - session-only folder memory (cloudConnections store) + - display-name rename for cloud connections + affects: + - frontend/src/api/cloud.js + - frontend/src/stores/cloudConnections.js + - frontend/src/router/index.js + - frontend/src/views/CloudStorageView.vue + - frontend/src/views/CloudFolderView.vue + - frontend/src/components/settings/SettingsCloudTab.vue + - frontend/src/components/storage/StorageBrowser.vue + - frontend/src/components/ui/BreadcrumbBar.vue + - frontend/src/components/ui/AppIcon.vue + - frontend/src/utils/formatters.js + - backend/main.py +tech_stack: + added: + - CapabilityButton inline render-function component (StorageBrowser.vue) + - formatRelativeTime (formatters.js) + - saveLastFolder / loadLastFolder (cloudConnections.js session helpers) + patterns: + - capability-aware rendering (aria-disabled, not native disabled) + - session-storage for navigation state only (never tokens/credentials) + - connection UUID as routing identity (opaque, not provider slug) + - immediate watcher for freshness state transitions +key_files: + created: + - frontend/src/views/__tests__/CloudFolderView.test.js + - frontend/src/views/__tests__/CloudStorageView.test.js + - frontend/src/components/storage/__tests__/StorageBrowser.capabilities.test.js + modified: + - frontend/src/api/cloud.js + - frontend/src/stores/cloudConnections.js + - frontend/src/stores/__tests__/cloudConnections.test.js + - frontend/src/router/index.js + - frontend/src/views/CloudStorageView.vue + - frontend/src/views/CloudFolderView.vue + - frontend/src/components/settings/SettingsCloudTab.vue + - frontend/src/components/settings/__tests__/SettingsCloudTab.test.js + - frontend/src/components/storage/StorageBrowser.vue + - frontend/src/components/ui/BreadcrumbBar.vue + - frontend/src/components/ui/__tests__/BreadcrumbBar.test.js + - frontend/src/components/ui/AppIcon.vue + - frontend/src/utils/formatters.js + - backend/main.py + - frontend/package.json + - AGENTS.md + - README.md +decisions: + - "Connection identity is the connection UUID, never a provider slug, in routes and API calls" + - "CapabilityButton uses aria-disabled (not native disabled) so controls remain keyboard-focusable" + - "Local mode uses full capability defaults — no mode==='local' gates remain in action rendering" + - "session-only folder memory stored under namespaced key docuvault:cloud:folder:{uuid}" + - "Fresh indicator fades after 3s using immediate watcher + fake-timer-tested setTimeout" + - "formatRelativeTime added to formatters.js — not duplicated inline" +metrics: + duration: "~45 minutes" + completed: "2026-06-18" + tasks: 3 + files: 18 +--- + +# Phase 12 Plan 03: Cloud UI Foundation Summary + +## One-liner + +Connection-UUID routing, CapabilityButton-based action rendering, and BreadcrumbBar freshness indicators unify cloud and local file navigation under one shared StorageBrowser. + +## What was built + +### Task 1: Route and store cloud navigation by connection identity + +- `api/cloud.js`: added `getCloudFoldersByConnectionId(connectionId, folderId)` and `renameCloudConnection(id, displayName)`; deprecated provider-keyed `getCloudFolders` +- `cloudConnections.js` store: added `rename`, `selectConnection`, `setBrowseState`, `defaultDisplayName` (4-char UUID suffix for duplicate same-provider connections), and `saveLastFolder`/`loadLastFolder` session helpers +- Router: `/cloud/:provider/:folderId` → `/cloud/:connectionId/:folderId` +- `CloudStorageView`: thin data provider — maps connections to folder-like items and passes them to `StorageBrowser`; no parallel grid markup +- `CloudFolderView`: thin data provider — uses `connectionId` param, calls `getCloudFoldersByConnectionId`, saves last folder in sessionStorage on navigate +- `SettingsCloudTab`: added inline rename input per ACTIVE connection with Rename / Save / Cancel flow + +### Task 2: Replace mode-gated actions with accessible capability rendering + +- `StorageBrowser`: removed all `mode === 'local'` action visibility gates +- Added props: `capabilities`, `connectionRoot`, `folderFreshness`, `lastRefreshedAt`, `byteAvailability` +- `LOCAL_CAPS` constant provides full-supported defaults so local mode unchanged +- `CapabilityButton` inline component: `aria-disabled="true"` (never native `disabled`), click/Enter/Space/touchend all suppressed for non-supported states; emits `explain` → `capability-explain` event and shows inline dismissible notice +- Gray styling for `unsupported`; amber for `temporarily_unavailable` +- Cached-byte marker (`clock` icon) on size column when `byteAvailability === 'cached'`; no marker for `cloud_only` +- `AppIcon`: added `info` and `clock` icons + +### Task 3: Breadcrumb freshness and plan protocol + +- `BreadcrumbBar`: optional `folderFreshness` and `lastRefreshedAt` props; refreshing spinner (animated SVG), fresh checkmark (fades 3s via immediate watcher), persistent stale warning banner +- All freshness states have `role="status"` and `aria-label` for screen readers +- `formatters.js`: `formatRelativeTime` — human-readable relative time, no inline duplication +- Version bumped 0.1.5 → 0.1.6 in `backend/main.py` and `frontend/package.json` +- `AGENTS.md` and `README.md` updated with new state, shared module map, and feature text + +## Test results + +- 323 frontend tests pass (39 test files) +- Production build: `✓ built in 510ms` + +## Deviations from Plan + +None — plan executed exactly as written. + +## Threat surface scan + +No new network endpoints introduced by this plan. Frontend adds: + +| Flag | File | Description | +|------|------|-------------| +| threat_flag: sessionStorage-check | cloudConnections.js | `saveLastFolder` stores only folder path string under namespaced key; negative test asserts value is not `{` (not an object with credentials) | + +## Known Stubs + +None — StorageBrowser capability props are connected through CloudFolderView; default `LOCAL_CAPS` wires all local actions. + +## Self-Check: PASSED + +All key files found. All commits verified (bf9af11, 4424433, c6c0742). 323 tests pass. Production build clean.