Commit Graph
164 Commits
Author SHA1 Message Date
curo1305 b1a9f436c4 fix(13): WR-06 read result.status (not result.state) in testConnection to reflect actual server field name 2026-06-23 00:30:01 +02:00
curo1305 e68faf3051 chore(13-11): bump to v0.3.0, update docs, roadmap, and Phase 13 security gate evidence
- Version bump: 0.2.6 → 0.3.0 (Phase 13 complete — full cloud mutation surface shipped)
- CLAUDE.md: update current-state, shared module map, and Phase 13 non-negotiable rules
- README.md: add cloud file management, connection health, and authorized preview features; add Phase 13 mutation API table; mark Phase 13 complete
- ROADMAP.md: mark Phase 13 11/11 plans complete
- SECURITY.md: add Phase 13 threat register (T-13-01 through T-13-34), gate evidence (766 backend + 429 frontend tests pass, bandit 0 HIGH, npm audit 0 high/critical, gitleaks 3 pre-existing)
2026-06-23 00:14:57 +02:00
curo1305 a7e55d1bb0 feat(13-10): reactive mock store in rendered-flow test surfaces health banner and no-probe assertions
- CloudFolderRenderedFlow.test.js: mock store uses Vue refs so folderFreshness propagates
  reactively to StorageBrowser via CloudFolderView's template binding (D-12 GREEN)
- setBrowseState in mock now updates _mockFolderFreshness so cloud-health-banner appears
  when API returns warning freshness (T-13-30 mitigated)
- Added testCloudConnection to API mock so D-13 no-probe assertion can verify it was not called
- beforeEach resets reactive refs for test isolation
- 11 rendered-flow tests pass; 70 total across health/store/view/rendered-flow suites
2026-06-22 23:56:13 +02:00
curo1305 60afb028bf feat(13-10): store-backed health mapping, reconnect UX, no-probe-on-navigation, and Google Drive consent copy
- D-12: connectionHealth ref as single source for browser compact status and Settings diagnostics
- D-13: handleHealthFailure schedules pendingHealthRetest; navigation never triggers probe
- D-13: testConnection method in store (explicit action only, not navigation side-effect)
- D-14: markReconnecting preserves cached browseItems as stale; markReconnectRefreshPending flag
- D-15: degraded vs requires_reauth health states distinguished in store vocabulary
- D-17: Google Drive scope notice in SettingsCloudTab for all connect/reconnect paths
- StorageBrowser: cloud-health-banner (warning/stale) and requires-reauth prompt with reconnect action
- 59 tests passing: store, Settings, and CloudFolderView health/reconnect suites
2026-06-22 23:55:58 +02:00
curo1305 3351e63458 feat(13-07): wire binary-only preview and authorized download through shared actions
- CloudFolderView: onFileOpen calls openCloudFile(connectionId, provider_item_id, file) — never window.open()
- CloudFolderView: D-18 fallback calls downloadCloudFile for unsupported formats
- api/cloud.js: add openCloudFile optional fileContext param (third argument) for test matching
- api/cloud.js: add downloadCloudFile authorized download endpoint helper
- CloudFolderOpenPreview.test.js: fix makeBrowserStub missing name (findComponent by name)
- All 8 preview suite tests pass — binary-only preview + authorized fallback download
2026-06-22 19:42:48 +02:00
curo1305 e7e62bbab8 feat(13-07): implement sequential cloud upload queue with typed pause/resume
- StorageBrowser: add conflict dialog (D-03) and error dialog (D-04) for paused queue states
- StorageBrowser: add upload-queue-resolve emit for Keep both / Replace / Skip / Retry / Cancel all actions
- StorageBrowser: add upload-queue-list with upload-queue-item rows for remaining queued items
- StorageBrowser: suppress UploadProgress in cloud mode (replaced by queue dialogs)
- CloudFolderView: replace placeholder onFilesSelected with sequential queue runner
- CloudFolderView: handle upload-queue-resolve events for all conflict/error resolution actions
- api/cloud.js: add conflictAction param to uploadCloudFile for keep_both/replace paths
- api/cloud.js: add downloadCloudFile authorized fallback helper
- CloudFolderView.test.js: fix CapturingStub missing name, add uploadCloudFile mock
- All 34 queue and thin-view tests pass (StorageBrowser.cloud-queue + CloudFolderView)
2026-06-22 19:42:29 +02:00
curo1305 5c0bc2a3b4 feat(13-04): upgrade Google Drive scope to drive, add health/reconnect/content API helpers
- connections.py: Update Google Drive OAuth to broader `drive` scope (D-17)
  instead of `drive.file` so authorized users can operate on all existing Drive
  items, not just files created by this app. Both initiation and callback flows
  updated to keep scopes consistent.
- schemas.py: Add Phase 13 typed response schemas — ConnectionHealthOut, ReconnectOut,
  ContentResultOut, MutationResultOut, and request schemas CreateFolderRequest,
  RenameItemRequest, MoveItemRequest. All credential-free (T-13-14, CONN-03).
- api/cloud.js: Add centralized frontend helpers for getConnectionHealth,
  reconnectCloudConnection, testCloudConnection (D-12, D-13), plus authorized
  cloud content and mutation helpers: openCloudFile, previewCloudFile,
  createCloudFolder, renameCloudItem, moveCloudItem, deleteCloudItem, uploadCloudFile.

All reconnect/health/test tests pass (14/14). Security suite passes (19/19).
2026-06-22 18:49:47 +02:00
curo1305 8923ed5b3c test(13-02): add red store, health-flow, reconnect, and no-probe tests
- SettingsCloudTab.health.test.js: Test/Reconnect/Disconnect per-connection actions,
  explicit confirmation before credential removal, Google Drive broader scope consent
  copy (D-12/D-13/D-15/D-16/D-17/T-13-09)
- cloudConnections.test.js: connectionHealth state map, setConnectionHealth translation,
  degraded vs requires_reauth distinction, pendingHealthRetest after failure, reconnect
  preserves cached items, auto-test after connect, no-probe-on-navigation (D-12..D-15)
- CloudFolderRenderedFlow.test.js: warning+reconnect banner alongside cached items,
  requires_reauth renders actionable prompt, folder-navigate never triggers health probe
  (D-12/D-13/D-14/CONN-02/T-13-06)
2026-06-22 18:13:39 +02:00
curo1305 514925bd4c test(13-02): add red shared-browser queue/preview and thin-view tests
- StorageBrowser.cloud-queue.test.js: sequential upload queue, paused_conflict
  dialog (Keep both/Replace/Skip/Cancel all), paused_error dialog (Retry/Skip/
  Cancel all), backend-typed conflict/error bodies, no window.open() (D-01/D-03/D-04)
- CloudFolderOpenPreview.test.js: authorized file-open via API, no raw provider
  URLs, Office/Workspace authorized download fallback, no anchor-click download
  hack, no re-emitted file-open to router (D-02/D-18/T-13-07)
- CloudFolderView.test.js: extends thin-view invariants for Phase 13 queue prop
  forwarding and upload-event queue semantics (D-01/D-04)
2026-06-22 18:10:16 +02:00
curo1305 64ddb50cd6 fix(cloud): show provider root items in browser 2026-06-22 13:55:07 +02:00
curo1305 46b7ea6c12 test(12.1): verify live cloud browse integration
Phase 12.1 close — docs, version, and security evidence:
- Bump version 0.2.5 → 0.2.6 in backend/main.py, frontend/package.json
- CLAUDE.md: update current state to Phase 12.1 complete v0.2.6
- README.md: add Phase 12.1 corrections, live smoke variable names, Phase 13/14 exclusions
- RUNBOOK.md: add live smoke invocation, warning semantics table, fixture reconciliation procedure
- SECURITY.md: add Phase 12.1 Plan 04 threat table (T-12.1-16..20, T-12.1-SC) and gate evidence
- 12.1-VALIDATION.md: mark Plan 04 complete with final gate evidence
2026-06-22 09:46:25 +02:00
curo1305 6d294ea7e6 test(12.1): add rendered-flow integration tests and security gate evidence
- Add CloudFolderRenderedFlow.test.js: 7 tests mounting real CloudFolderView
  with real StorageBrowser/BreadcrumbBar (only API and router stubbed)
  — mixed root render, opaque-ref folder navigation, breadcrumb lineage,
    warning freshness cached rows, fresh freshness, XSS text escaping
- Update 12.1-VALIDATION.md with Task 3 security gate results:
  bandit 0 HIGH, npm audit 0 critical, no Phase-12.1 gitleaks findings,
  595 backend / 376 frontend tests pass, build clean
2026-06-22 09:41:36 +02:00
curo1305 7bb046ac41 fix(12.1): align cloud browser contract — kind, provider_item_id, server freshness
Normalized cloud frontend for DocuVault v0.2.5:
- Cloud UI classifies items by kind=folder/file (is_dir removed from all active paths)
- Folder navigation uses provider_item_id (opaque provider ref) — DocuVault id kept for row identity
- Server freshness (refresh_state, last_refreshed_at) mapped verbatim — no browser-clock evidence
- Breadcrumb lineage built from explicit visited nodes — never split(provider_item_id)
- CloudFolderTreeItem: expandable/icon/navigate/loadChildren all use kind and provider_item_id
- Version bump 0.2.4 → 0.2.5
- SECURITY.md: T-12.1-11 through T-12.1-15 closed
- 369 tests pass, npm audit clean, production build clean
2026-06-22 08:51:14 +02:00
curo1305 dc3e1725da feat(12.1-03): align cloud browser contract — kind, provider_item_id, server freshness
- CloudFolderView: folders/files classified by kind=folder/file (remove is_dir)
- CloudFolderView: navigateTo uses item.provider_item_id for route param (not item.id)
- CloudFolderView: handleBreadcrumbNavigate uses named route; opaque refs intact
- CloudFolderView: setBrowseState maps server freshness.refresh_state verbatim
- CloudFolderView: refreshedAt = server last_refreshed_at (not new Date())
- CloudFolderView: breadcrumb lineage built explicitly from visited nodes
- CloudProviderTreeItem: loadChildren filters by kind=folder (not is_dir)
- CloudFolderTreeItem: expandable = kind===folder; icon = kind===folder
- CloudFolderTreeItem: navigate() uses provider_item_id (not folder.id)
- CloudFolderTreeItem: loadChildren uses provider_item_id as parent_ref
- CloudFolderTreeItem: isActive checks provider_item_id first
All 82 focused tests pass; full suite: 369/369
2026-06-22 08:49:19 +02:00
curo1305 9974fca2cb test(12.1-03): add RED tests for server freshness mapping
- cloudConnections: setBrowseState warning/refreshing/fresh states
- cloudConnections: cached items remain during warning
- cloudConnections: selectConnection clears browse state
- cloudConnections: does_not_use_browser_clock_as_refresh_evidence
- CloudFolderView: maps_server_warning_and_last_success
- CloudFolderView: http_200_does_not_imply_fresh
- CloudFolderView: does_not_use_browser_clock_as_refresh_evidence
- CloudFolderView: cached_items_remain_visible_during_warning
3 new failures against unconditional fresh/new Date() behavior
2026-06-22 08:45:50 +02:00
curo1305 ba7f652cde test(12.1-03): add RED tests for kind/provider_item_id/freshness regressions
- CloudFolderView: renders_kind_folder_and_file_in_shared_browser (is_dir → kind)
- CloudFolderView: folder_click_uses_provider_item_id_not_id
- CloudFolderView: stable_docuvault_id_remains_row_key
- CloudFolderView: opaque_reference_round_trip (reserved chars)
- CloudFolderTreeItem: nested_tree_uses_provider_item_id (navigation + loadChildren)
- CloudFolderTreeItem: expandable based on kind=folder, not is_dir
- CloudFolderTreeItem: opaque OneDrive ref used intact
- CloudProviderTreeItem: tree_expansion_filters_kind_folder
- StorageBrowser: cloud folder/file rendering with normalized items
- CloudBreadcrumbNavigation: explicit lineage tests (pass against current code)
9 tests fail against is_dir/item.id behavior as expected
2026-06-22 08:44:27 +02:00
curo1305 70a543a8c1 fix(12.1): make cloud freshness authoritative — plan 02 documentation and version
- Version bump 0.2.3 → 0.2.4 (user-visible sync status corrected)
- CLAUDE.md: update current state; add apply_listing_and_finalize to module map; add no-independent-fresh rule
- README.md: bump version
- RUNBOOK.md: update freshness state docs; explain complete=True gate and last_refreshed_at behavior
- SECURITY.md: add T-12.1-06..10 threat closure evidence for Plan 02
2026-06-22 08:34:51 +02:00
curo1305 62128730e8 fix(12.1-01): restore asyncio import, bump version to 0.2.3, update docs
- Restore asyncio import removed when legacy list_folder was deleted (health_check
  still uses asyncio.to_thread); fixes test_nextcloud_connect_persists regression
- Bump backend/main.py and frontend/package.json version to 0.2.3
- Update CLAUDE.md: note Phase 12.1 Plan 01 complete, add normalize_nextcloud_url
  to shared module map, add NextcloudBackend no-override rule
- Update README.md: version 0.2.3, note canonical Nextcloud URL normalization and
  OneDrive nextLink origin guard
- Full backend suite: 585 passed, 1 pre-existing failure (missing python-docx module)
2026-06-22 08:18:23 +02:00
curo1305 692600c755 test(12): close Nyquist validation gap 2026-06-22 06:44:33 +02:00
curo1305 c85e4abd91 chore(12-06): bump version 0.2.1 → 0.2.2 2026-06-21 22:30:11 +02:00
curo1305 057b4999fd feat(12-06): UUID-only cloud navigation, breadcrumb hierarchy, route-aware sidebar
- CloudProviderTreeItem: getCloudFoldersByConnectionId(connection.id) + /cloud/{uuid}/root
- CloudFolderTreeItem: connectionId prop replaces provider slug in browse + route
- AppSidebar: Cloud Storage active only on exact /cloud; connection nodes use per-connection isActive
- New tests: CloudProviderTreeItem, CloudFolderTreeItem, AppSidebar cloud active-state
2026-06-21 22:30:05 +02:00
curo1305 731b65ecdd feat(12-06): connection-ID native lifecycle — always INSERT, PUT credentials, connectionsFor multi-account
- Replace _upsert_cloud_connection with _insert_cloud_connection (always inserts new UUID row)
- Add PUT /connections/{id}/credentials endpoint (owner-scoped, SSRF + health-check, password-preserve)
- SettingsCloudTab: connectionsFor() renders all same-provider connections with Add account row
- CloudCredentialModal.submit: calls updateWebDavCredentials on edit, connectWebDav on create
- utils.js: FastAPI validation arrays normalised to concise field messages (Rule 2)
- Backend tests: same-provider independence + IDOR negative test for credential update
2026-06-21 22:29:59 +02:00
curo1305 3ca57dcd0c fix(12-05): bump version to 0.2.1 and update docs for migration-gated startup
- backend/main.py, frontend/package.json: version 0.2.0 → 0.2.1
- CLAUDE.md, AGENTS.md: current state updated to reflect gap-closure
- README.md: startup instructions note migrate runs automatically; update migration commands
- RUNBOOK.md: startup diagram includes migrate service; migration gate explanation
- SECURITY.md: Phase 12 gap-closure threat register and security gate evidence
2026-06-20 10:49:21 +02:00
curo1305andClaude Sonnet 4.6 b6911fb4ed fix(12): resolve critical code review findings (CR-01 through CR-04)
- CR-01: fix browse URL from /folders/{id} to /items?parent_ref= (broken feature)
- CR-02: remove raw provider exception text from _TerminalProviderError messages
- CR-03: add user_id predicate to get_or_create_folder_state query (ownership boundary)
- CR-04: add max_length=255 to ConnectionRenameRequest.display_name

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 02:00:05 +02:00
curo1305 c441fc63e5 chore(12-04): bump version to 0.2.0 and finalize Phase 12 documentation
- backend/main.py, frontend/package.json: 0.1.6 → 0.2.0 (phase-complete minor bump)
- AGENTS.md: current state updated to Phase 12 complete; cloud-resource-foundation
  summary with browse contract, security suite, and Phase 13/14 boundary note
- README.md: version updated to 0.2.0
- All existing shared module map rules and frontend architecture constraints unchanged
2026-06-19 01:54:24 +02:00
curo1305 c6c0742267 feat(12-03): breadcrumb freshness, formatRelativeTime, v0.1.6, docs
- BreadcrumbBar: refreshing spinner, fresh checkmark (fades 3s), stale warning banner
- Accessible labels and role=status for all freshness states
- formatters.js: add formatRelativeTime (shared, no duplication)
- Version bump 0.1.5 → 0.1.6 in backend/main.py and frontend/package.json
- AGENTS.md: update state, shared module map (formatRelativeTime)
- README.md: unified connection-root browsing and capability explanations feature text
- 17 BreadcrumbBar tests pass; 323 total; production build clean
2026-06-18 23:31:50 +02:00
curo1305 44244335a1 feat(12-03): capability-aware action rendering in StorageBrowser
- Add capabilities, connectionRoot, folderFreshness, lastRefreshedAt, byteAvailability props
- CapabilityButton inline component: aria-disabled, click/Enter/Space/touch suppression
- Gray for unsupported, amber for temporarily_unavailable — no native disabled
- Local defaults preserve all pre-Phase-12 drag/share/move/delete behavior
- Cached-byte marker (clock icon) on size column when byteAvailability='cached'
- No marker for cloud_only
- AppIcon: add info, clock icons
- 50 StorageBrowser tests pass
2026-06-18 23:29:10 +02:00
curo1305 bf9af11274 feat(12-03): connection-ID routing, rename, session folder memory, thin views
- Route /cloud/:connectionId/:folderId replaces /cloud/:provider/:folderId
- api/cloud.js: getCloudFoldersByConnectionId + renameCloudConnection
- cloudConnections store: rename, selectConnection, setBrowseState, defaultDisplayName, session storage helpers
- CloudStorageView: thin — passes connectionRoots to StorageBrowser
- CloudFolderView: thin — uses connectionId param, never provider slug
- SettingsCloudTab: inline rename input for each active connection
- 27 tests pass: store, view, settings
2026-06-18 23:25:29 +02:00
curo1305 c6237ca57f feat(12-02): add refresh_cloud_folder Celery task, staleness trigger, version 0.1.5
- Add tasks/cloud_tasks.py: durable refresh_cloud_folder task with 3-retry
  bounded backoff (30s/90s/270s +jitter), credential decryption in worker only
- Register tasks.cloud_tasks.* on documents queue in celery_app.py
- Add stale-while-revalidate staleness trigger in browse.py (5-min threshold)
- Add 4 Task 3 tests: idempotency, cached-row retention on failure, task structure,
  no-byte-download contract; add background-refresh scheduling integration test
- Bump backend version 0.1.4 → 0.1.5, frontend package.json 0.1.4 → 0.1.5
- Update AGENTS.md with Phase 12 Plan 02 state and new shared module map entries
- Update README with connection-ID browse API table and v0.1.5
2026-06-18 23:17:34 +02:00
curo1305 aaf57eae80 fix(milestone): close v0.2 audit gaps 2026-06-17 12:42:20 +02:00
curo1305 595b33a68c fix(phase-11): close mobile storage UAT gaps 2026-06-17 10:48:35 +02:00
curo1305 64aa960d20 test(phase-11): add Nyquist validation coverage 2026-06-17 09:58:59 +02:00
curo1305 28e75e971d fix(11): TreeItem.vue — focus-visible ring on all interactive elements; skeleton width → static Tailwind
- Expand/collapse button, router-link label, and button label all get focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-1
- :style skeleton width replaced with :class w-12/w-16/w-20 (same fix applied to AppSidebar in 11-05)
- Closes VISUAL-01 and VISUAL-03 gaps found by verifier
2026-06-17 09:35:06 +02:00
curo1305 a928b54781 chore(11-06): dead-code cleanup — delete FolderRow.vue, retain admin tab tests
Task 2 — admin test classification:
  - AdminAiConfigTab.test.js: RETAINED (tests AdminAiView.vue, a live component)
  - AdminQuotasTab.test.js: RETAINED (tests AdminQuotasView.vue, a live component)
  - AdminUsersTab.test.js: RETAINED (tests AdminUsersView.vue, a live component)

Task 3 — confirmed absent: HomeView.vue, FolderView.vue, AdminView.vue all absent

Task 4 — dead-code scan:
  - FolderRow.vue: DELETED — no import in any live component; StorageBrowser renders
    folder rows inline; FolderRow had no active route or active import (CLAUDE.md rule)

Task 5 — stale test removal:
  - dropdown.test.js: removed 2 FolderRow tests (tested dead component);
    kept 2 DocumentCard Teleport tests (protect live surface)
  - No unused named imports found in live components

268/268 tests pass.
2026-06-17 07:56:00 +02:00
curo1305 a8e0a199f2 chore(11-06): delete orphaned AccountView.vue
- AccountView.vue had no active route component reference
- /account path uses redirect: '/settings' with no component import
- No imports found across the entire codebase
- Satisfies CODE-07: no unreferenced route views remain
2026-06-17 00:39:05 +02:00
curo1305 2af5b7c313 feat(11-05): visual consistency pass — typography, focus-visible, hover/active states, skeleton cleanup
- Normalize page titles to text-2xl font-semibold (was font-bold in TopicsView, DocumentView, SharedView)
- Normalize section titles to text-lg font-semibold (was text-xl in SettingsPreferencesTab, SettingsAiTab, SettingsCloudTab, BackupCodesDisplay, CloudCredentialModal)
- Normalize panel headings to text-sm font-semibold (SettingsAccountTab, DocumentView)
- Normalize AdminOverviewView page title from text-xl to text-2xl font-semibold
- Replace decorative sidebar skeleton inline styles with static Tailwind width classes (w-12/w-16/w-20)
- Add focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-1 to all interactive buttons across the app
- Add active:bg-* states to primary and secondary buttons for coherent press feedback
- Update nav-link scoped CSS in AppSidebar and AdminSidebar to include active:bg-gray-200 and focus-visible ring
- Add 7 new tests: VISUAL-01 skeleton class invariant, VISUAL-04 focus-visible invariant, VISUAL-03 typography invariant (36 test files, 270 tests pass)
2026-06-16 21:48:56 +02:00
curo1305 86d28046ca chore: merge executor worktree (worktree-agent-acd1ece9cc8092915) 2026-06-16 21:37:59 +02:00
curo1305 df53cef3b7 feat(11-04): mobile-safe modals and form baseline verification
- Add max-h-[90vh] overflow-y-auto to ShareModal, CloudCredentialModal,
  FolderDeleteModal, and DocumentView cloud-delete modal panels
- Add responsive px-4 sm:px-6 to DocumentPreviewModal header for narrow viewports
- Add data-test attributes to all modal panels for testability
- Confirm @tailwindcss/forms active in tailwind.config.js (no drift found)
- Audit forms: focus:outline-none focus:ring-2 pattern is consistent throughout
- Add 4 test files covering mobile-safe modal classes and form baseline:
  ShareModal.mobile.test.js, CloudCredentialModal.mobile.test.js,
  FolderDeleteModal.mobile.test.js, DocumentPreviewModal.mobile.test.js

VISUAL-02, RESP-04
2026-06-16 21:33:57 +02:00
curo1305 e32793c126 chore: merge executor worktree (worktree-agent-ae52d6537a4569901) 2026-06-16 21:26:09 +02:00
curo1305 d914761120 feat(11-03): responsive shells and storage rows
- App.vue: mobile header with hamburger button; slide-in overlay drawer
  with Teleport backdrop, translate-x-0/-translate-x-full transition;
  drawer state owned by App.vue (D-04/D-05); route-change auto-close
- AdminLayout.vue: matching responsive treatment — hamburger, backdrop,
  drawer, route-change close (RESP-05)
- StorageBrowser.vue: responsive grid templates
  (mobile: grid-cols-[2rem_1fr_6rem], sm: +modified, md: all 5 cols);
  Size hidden below md, Modified hidden below sm; action buttons get
  min-w-[36px] min-h-[36px] touch targets (RESP-02, RESP-03)
- Tests: drawer open/close/backdrop-close/route-change behaviour;
  admin drawer; responsive column and touch-target class assertions
2026-06-16 21:22:59 +02:00
curo1305 4fa07b3874 perf(11-02): lazy-load non-critical routes — PERF-03
- Keep FileManagerView synchronous for / per D-10 (critical first authenticated surface)
- Lazy-load TopicsView, DocumentView, SettingsView, CloudStorageView, CloudFolderView
- /folders/:folderId reuses synchronous FileManagerView (no split, same component)
- Main bundle reduced from 264.63 kB to 180.17 kB (split into 5 new route chunks)
- Extend router guard tests: admin child route blocking, refresh-before-guard flow,
  lazy-loaded route resolution — 234 tests pass (15 new tests added)
2026-06-16 21:10:48 +02:00
curo1305 0fb2a53a4f chore(11-01): add ANALYZE=true opt-in for rollup-plugin-visualizer in vite.config.js
- Wrapped config in async defineConfig factory so visualizer can be dynamically
  imported only when ANALYZE=true; normal builds incur zero overhead
- Added frontend/stats.html to .gitignore (ephemeral artifact; canonical copy
  lives in .planning/perf/)
2026-06-16 21:04:54 +02:00
curo1305 339f5a0c82 test(10-13): regression tests for all 6 UAT gaps
- keyboard.test.js: Gap 4 test — matched.find(r => r.instances?.default) resolves to FileManagerView
- TreeItem.test.js: Gap 1 tests — animate-pulse present, 'Loading' text absent during shimmer state
- StorageBrowser.showSearch.test.js: Gap 2 tests — showSearch true for local+cloud at root
- All 219 tests pass (8 new, 211 existing)
2026-06-16 19:19:02 +02:00
curo1305 bac5dcfe3d fix(10-13): escape modifier and capture-phase OS drop
- SearchBar.vue: add .prevent.stop to @keydown.escape to suppress browser native blur (Gap 5)
- OsDragOverlay.vue: register window drop listener with capture=true to fire before folder-row handlers (Gap 6)
2026-06-16 19:12:57 +02:00
curo1305 5972a62041 fix(10-13): admin sidebar bleed and keyboard instance resolution
- App.vue: add v-else-if branch for admin routes that renders only router-view (no AppSidebar)
- App.vue: replace routeViewRef with getFileManagerInstance() using matched.find(r => r.instances?.default)
- App.vue: remove unused ref import (Gap 3 + Gap 4)
2026-06-16 19:12:05 +02:00
curo1305 76785b4d96 fix(10-13): sidebar shimmer rows and search-at-root visibility
- TreeItem.vue: replace 'Loading…' text with 3 animate-pulse shimmer rows
- StorageBrowser.vue: showSearch now true for mode=local OR mode=cloud (Gap 1 + Gap 2)
2026-06-16 19:11:25 +02:00
curo1305 11228306e4 Merge cleanup branch 2026-06-16 15:40:33 +02:00
curo1305 3307282570 Fix Docker stack bootstrap 2026-06-16 15:35:06 +02:00
curo1305andClaude Sonnet 4.6 ce67b9f98a fix(cloud): skeleton on first render + informative toast when opening cloud files
- loading initialised to true so skeleton rows show immediately on mount
  instead of the empty state flashing before data arrives
- @file-open no longer a silent no-op; shows an info toast explaining the
  file must be opened via the cloud provider directly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 13:57:18 +02:00
curo1305 e97ca164d7 Refactor backend and frontend cleanup paths 2026-06-16 11:50:17 +02:00