Files
kite/.planning/phases/13-virtual-local-cloud-operations/13-PATTERNS.md
T
curo1305andClaude Sonnet 4.6 b67e77dd69 docs(13): add phase 13 planning artifacts — virtual local cloud operations
Plans 01–11, CONTEXT, PATTERNS, RESEARCH, REVIEW-FIX, and updated
SUMMARY and CONTEXT for the virtual-local-cloud-operations phase.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 20:34:57 +02:00

28 KiB
Raw Blame History

Phase 13: Virtual-Local Cloud Operations - Pattern Map

Mapped: 2026-06-22
Files analyzed: 33 likely new/modified files
Analogs found: 33 / 33 (6 are composite/no-exact)

Inherited phase rules that stay locked

  • Keep StorageBrowser.vue as the only file browser. Cloud behavior extends emitted events and props; it does not fork layout. See [AGENTS.md], Phase 12 patterns, and [frontend/src/components/storage/StorageBrowser.vue].
  • Keep cloud routing owner-scoped by connection UUID plus opaque provider_item_id; never parse provider refs on the client. Primary analogs: [backend/api/cloud/browse.py:183], [frontend/src/views/CloudFolderView.vue:42], [frontend/src/components/cloud/CloudFolderTreeItem.vue:42].
  • Keep metadata reconciliation centralized in reconcile_cloud_listing / apply_listing_and_finalize; provider adapters never write cloud_items rows directly. Primary analogs: [backend/services/cloud_items.py:163], [backend/services/cloud_items.py:271].
  • Keep service-layer exception discipline: services raise domain errors / ValueError, routers translate to HTTPException. Primary analogs: [AGENTS.md], [backend/services/cloud_items.py:1].
  • Keep audit writes metadata-only and in the callers transaction. Primary analog: [backend/services/audit.py:27].

File Classification

Likely file Role Data flow Closest analog Match
backend/api/cloud/operations.py route request-response + file-I/O + CRUD backend/api/cloud/browse.py, backend/api/documents/content.py, backend/api/documents/upload.py, backend/api/folders.py composite
backend/api/cloud/connections.py route request-response itself + backend/tasks/cloud_tasks.py exact
backend/api/cloud/schemas.py schema transform itself exact
backend/services/cloud_operations.py service CRUD + transform backend/services/cloud_items.py + backend/services/audit.py composite
backend/services/cloud_items.py service CRUD + batch reconcile itself exact
backend/storage/cloud_base.py contract transform itself exact
backend/storage/cloud_backend_factory.py factory request-response itself exact
backend/storage/google_drive_backend.py provider file-I/O + CRUD itself exact
backend/storage/onedrive_backend.py provider file-I/O + CRUD itself exact
backend/storage/webdav_backend.py provider file-I/O + CRUD itself exact
backend/storage/nextcloud_backend.py provider file-I/O itself + webdav_backend.py exact
backend/tasks/cloud_tasks.py task event-driven + batch itself exact
frontend/src/api/cloud.js API client request-response itself + frontend/src/api/documents.js exact
frontend/src/stores/cloudConnections.js store state transform itself exact
frontend/src/views/CloudFolderView.vue thin view request-response + queue orchestration itself + frontend/src/views/FileManagerView.vue exact
frontend/src/components/storage/StorageBrowser.vue smart component CRUD UI + queue UI itself exact
frontend/src/components/settings/SettingsCloudTab.vue smart component request-response itself exact
frontend/src/components/cloud/CloudCredentialModal.vue modal/form request-response itself exact
backend/tests/test_cloud.py integration test request-response itself exact
backend/tests/test_cloud_security.py security-negative test request-response itself exact
backend/tests/test_cloud_backends.py provider unit/contract test file-I/O itself exact
backend/tests/test_cloud_provider_contract.py provider contract test transform itself exact
backend/tests/test_cloud_items.py service/task test CRUD + batch itself exact
backend/tests/test_cloud_mutations.py integration/contract test CRUD + file-I/O test_cloud.py + test_cloud_security.py + test_cloud_items.py composite
backend/tests/test_cloud_reconnect.py integration/security test request-response + task test_cloud.py + test_cloud_items.py composite
backend/tests/test_cloud_audit.py integration test transform backend/tests/test_audit.py + backend/tests/test_cloud.py partial
frontend/src/views/__tests__/CloudFolderView.test.js view unit test request-response itself exact
frontend/src/views/__tests__/CloudFolderRenderedFlow.test.js rendered-flow test request-response itself exact
frontend/src/components/storage/__tests__/StorageBrowser.capabilities.test.js component unit test CRUD UI itself exact
frontend/src/components/storage/__tests__/StorageBrowser.cloud-queue.test.js component unit test queue UI StorageBrowser.capabilities.test.js + FileManagerView.vue upload flow composite
frontend/src/views/__tests__/CloudFolderOpenPreview.test.js rendered-flow test request-response + preview CloudFolderRenderedFlow.test.js + document content helpers composite
frontend/src/stores/__tests__/cloudConnections.test.js store unit test state transform itself exact
frontend/src/components/settings/__tests__/SettingsCloudTab.test.js component unit test request-response itself exact
frontend/src/components/settings/__tests__/SettingsCloudTab.health.test.js component unit test health/reconnect UI SettingsCloudTab.test.js + store freshness tests partial

Pattern Assignments

backend/api/cloud/operations.py

Primary analogs

  • Route/dependency skeleton: [backend/api/cloud/browse.py:19-42], [backend/api/cloud/browse.py:183-214]
  • Connection settings/test/update/disconnect patterns: [backend/api/cloud/connections.py:368-434], [backend/api/cloud/connections.py:492-579], [backend/api/cloud/connections.py:604-635]
  • Authorized byte streaming and cloud-error translation: [backend/api/documents/content.py:50-103]
  • Multipart upload proxy pattern: [backend/api/documents/upload.py:122-198]
  • Local create/rename/delete/move handler shape: [backend/api/folders.py:122-160], [backend/api/folders.py:232-265], [backend/api/folders.py:268-351], [backend/api/folders.py:357-375]

Copy these conventions

  • Use get_regular_user, get_db, account_limiter, and request.state.current_user = current_user exactly like cloud browse/connections.
  • Resolve ownership through resolve_owned_connection(...) before any provider action.
  • Translate provider/service failures to controlled HTTPException messages like document content/upload already do; do not surface raw provider text.
  • For open/preview/download, copy the StreamingResponse + CloudConnectionError mapping from content.py, but key authorization off cloud connection/item ownership instead of Document.
  • For upload/create/rename/move/delete, keep router bodies thin: validate request shape, call service, return whitelisted schema, write no inline reconciliation logic.

No exact analog

  • There is no existing single cloud route file that combines owner-scoped connection actions with content proxying and normalized mutation results. Keep the file shaped like browse.py, but borrow handler bodies from the document/folder routers above.

backend/api/cloud/connections.py

Primary analogs

  • WebDAV connect and health-check flow: [backend/api/cloud/connections.py:368-434]
  • Credential update flow: [backend/api/cloud/connections.py:492-579]
  • Display-name rename: [backend/api/cloud/connections.py:582-601]
  • Disconnect confirmation target: [backend/api/cloud/connections.py:604-635]

Copy these conventions

  • Keep _get_owned_connection(...) for owner checks.
  • Keep URL validation before backend construction.
  • Keep audit writes adjacent to the successful state change.
  • If reconnect/test routes are added, model them after connect_webdav + update_webdav_credentials: validate, health-check, persist, audit, commit.

Phase 13-specific caution

  • The current OAuth callback always inserts a new row (_upsert_cloud_connection = _insert_cloud_connection) at [backend/api/cloud/connections.py:128-129]. Do not copy that behavior for reconnect; Phase 13 needs connection-row preservation.

backend/api/cloud/schemas.py

Primary analog

  • Current cloud whitelist schemas: [backend/api/cloud/schemas.py:17-86]

Copy these conventions

  • Add only explicit allowlist response/request models.
  • Keep validators at schema level for user-submitted fields, as in ConnectionRenameRequest.
  • Keep credentials, provider URLs, and raw provider payloads out of every schema.

No exact analog

  • There is no current normalized mutation-result schema. Add new result types beside CloudBrowseResponse, not in routers.

backend/services/cloud_operations.py

Primary analogs

  • Owner resolution / stable identity / folder freshness: [backend/services/cloud_items.py:38-62], [backend/services/cloud_items.py:97-159], [backend/services/cloud_items.py:271-342]
  • Metadata-only audit helper: [backend/services/audit.py:27-58]
  • Background refresh orchestration: [backend/tasks/cloud_tasks.py:50-163]

Copy these conventions

  • Accept UUIDs/strings the same way cloud_items.py does.
  • Raise domain errors or ValueError, never HTTPException.
  • Reconcile and finalize folder state before returning success.
  • Write audit rows through write_audit_log(...), letting the caller own the transaction.

No exact analog

  • There is no existing service that turns provider mutation outcomes into normalized API results. Treat this as the new orchestration seam; do not push that logic into routers or providers.

backend/services/cloud_items.py

Primary analog

  • Keep using the current service itself.

Copy these conventions

  • Owner resolution: [backend/services/cloud_items.py:38-62]
  • Stable upsert-by-(connection_id, provider_item_id): [backend/services/cloud_items.py:97-159]
  • Complete-vs-incomplete reconciliation: [backend/services/cloud_items.py:163-213]
  • Single freshness gate: [backend/services/cloud_items.py:271-342]
  • Controlled folder-state updates: [backend/services/cloud_items.py:345-384]

Planner note

  • Any mutation service should feed its authoritative provider result back through these primitives instead of adding direct ORM writes elsewhere.

backend/storage/cloud_base.py

Primary analog

  • Keep extending the current contract file itself: [backend/storage/cloud_base.py:27-245]

Copy these conventions

  • Stable action vocabulary and reason codes live here, not in routers or Vue.
  • Immutable normalized dataclasses (CloudCapability, CloudResource, CloudListing) are the pattern to follow for new mutation result types.
  • Keep provider-specific branching out of the shared contract.

No exact analog

  • There is no Phase-13 mutation result/value type yet. New normalized result dataclasses belong here.

backend/storage/cloud_backend_factory.py

Primary analog

  • Current factory and adapter assertion: [backend/storage/cloud_backend_factory.py:7-66]

Copy these conventions

  • Keep lazy imports.
  • Keep Nextcloud URL normalization in the factory boundary.
  • If a mutable-adapter subclass is introduced, assert the interface here instead of switching on provider names in routers.

backend/storage/google_drive_backend.py

Primary analog

  • Existing upload/download/delete/list/capability patterns: [backend/storage/google_drive_backend.py:140-172], [backend/storage/google_drive_backend.py:174-207], [backend/storage/google_drive_backend.py:257-272], [backend/storage/google_drive_backend.py:276-417]

Copy these conventions

  • Wrap SDK calls in asyncio.to_thread().
  • Centralize provider error classification in helper methods like _handle_http_error(...).
  • Normalize provider metadata into CloudResource objects.
  • Keep the backend stateless: it may return refreshed credentials or typed errors, but must not write DB state directly.

backend/storage/onedrive_backend.py

Primary analog

  • Existing token lifecycle + upload/download/delete/list/capabilities: [backend/storage/onedrive_backend.py:83-154], [backend/storage/onedrive_backend.py:158-218], [backend/storage/onedrive_backend.py:220-245], [backend/storage/onedrive_backend.py:280-409]

Copy these conventions

  • Refresh token on demand inside the backend boundary.
  • Keep Graph HTTP async with httpx.
  • Keep CloudConnectionError unified across providers.

Gap to flag

  • There is no persistence pattern yet for refreshed OneDrive credentials; Phase 13 must add one above the backend, not inside it.

backend/storage/webdav_backend.py

Primary analog

  • Existing SSRF, PUT/GET/DELETE, list-folder, and capability patterns: [backend/storage/webdav_backend.py:66-137], [backend/storage/webdav_backend.py:139-174], [backend/storage/webdav_backend.py:222-237], [backend/storage/webdav_backend.py:241-370]

Copy these conventions

  • Re-run validate_cloud_url(...) before every outbound request.
  • Keep basename/path-traversal protection when building destination names.
  • Keep WebDAV-specific overwrite/conflict semantics inside this provider file.

backend/storage/nextcloud_backend.py

Primary analog

  • Minimal specialization over WebDAV: [backend/storage/nextcloud_backend.py:38-90]

Copy these conventions

  • Keep Nextcloud as a tiny specialization, not a parallel backend.
  • If Phase 13 needs Nextcloud-specific mutation quirks, implement them as narrow overrides that preserve the public contract.

backend/tasks/cloud_tasks.py

Primary analog

  • Current refresh worker: [backend/tasks/cloud_tasks.py:50-163], [backend/tasks/cloud_tasks.py:175-216]

Copy these conventions

  • Revalidate ownership inside the worker.
  • Decrypt credentials inside the worker, never in broker payload.
  • Use sentinel exceptions to separate retryable provider failures from terminal auth failures.
  • Reuse this task model if reconnect or stale-metadata recovery needs post-success refresh.

frontend/src/api/cloud.js

Primary analogs

  • Existing connection browse/config/update methods: [frontend/src/api/cloud.js:11-18], [frontend/src/api/cloud.js:36-50], [frontend/src/api/cloud.js:73-88]
  • Cloud upload helper shape: [frontend/src/api/documents.js:48-54]

Copy these conventions

  • Keep all Phase 13 cloud endpoints behind this domain module.
  • Keep connection UUID and encoded parent_ref handling here.
  • Add new open/preview/upload/create/rename/move/delete/test/reconnect helpers here instead of calling raw URLs from views/components.

frontend/src/stores/cloudConnections.js

Primary analog

  • Current store state and reset/mapping helpers: [frontend/src/stores/cloudConnections.js:33-138]

Copy these conventions

  • Keep server state translation centralized in the store.
  • Keep sessionStorage limited to folder refs only.
  • Reset browse state on connection switch.

No exact analog

  • There is no queue/conflict/resume state machine yet. Add it here only if it is shared across cloud views/settings; otherwise keep queue orchestration in CloudFolderView.

frontend/src/views/CloudFolderView.vue

Primary analogs

  • Existing cloud thin-view contract: [frontend/src/views/CloudFolderView.vue:1-20], [frontend/src/views/CloudFolderView.vue:125-170]
  • Local upload / create / rename / move / delete orchestration: [frontend/src/views/FileManagerView.vue:1-30], [frontend/src/views/FileManagerView.vue:103-182]

Copy these conventions

  • Keep the view thin: store/router/API orchestration only.
  • Pass everything into StorageBrowser; do not add layout or grid logic here.
  • Reuse the local upload queue orchestration style from FileManagerView, but Phase 13 needs sequential pause/resume instead of the current all-at-once Promise.allSettled(...) placeholder at [frontend/src/views/CloudFolderView.vue:172-181].
  • Use toasts and success/error handling the same way FileManagerView does.

frontend/src/components/storage/StorageBrowser.vue

Primary analog

  • Extend the current shared component itself: [frontend/src/components/storage/StorageBrowser.vue:140-275], [frontend/src/components/storage/StorageBrowser.vue:424-681]

Copy these conventions

  • Props/events are the contract; keep new behavior behind emitted events and prop-driven state.
  • Capability-aware buttons and notices stay in this component: [frontend/src/components/storage/StorageBrowser.vue:360-418], [frontend/src/components/storage/StorageBrowser.vue:495-530].
  • New folder / rename inline patterns already exist here: [frontend/src/components/storage/StorageBrowser.vue:118-135], [frontend/src/components/storage/StorageBrowser.vue:157-166], [frontend/src/components/storage/StorageBrowser.vue:543-593].
  • File move picker and drag-to-move patterns already exist here: [frontend/src/components/storage/StorageBrowser.vue:253-344], [frontend/src/components/storage/StorageBrowser.vue:595-621].

Gap to flag

  • There is no existing conflict dialog / paused upload queue UI. That is a real no-analog area inside the shared browser and should be added here rather than in a cloud-only component.

frontend/src/components/settings/SettingsCloudTab.vue

Primary analog

  • Existing settings actions and confirm flows: [frontend/src/components/settings/SettingsCloudTab.vue:21-102], [frontend/src/components/settings/SettingsCloudTab.vue:104-170], [frontend/src/components/settings/SettingsCloudTab.vue:293-359]

Copy these conventions

  • Keep provider rows, inline status badges, and destructive confirms in one shared settings tab.
  • Add Test/Reconnect controls beside existing Connect/Edit/Remove actions; do not create a parallel health screen.
  • Keep OAuth initiation in the component and store mutation calls behind the store/API layer.

frontend/src/components/cloud/CloudCredentialModal.vue

Primary analog

  • Existing submit branching for create vs edit: [frontend/src/components/cloud/CloudCredentialModal.vue:301-323]

Copy these conventions

  • Keep credential edits inside the modal for WebDAV/Nextcloud.
  • If Phase 13 adds explicit “Test connection” before save, hang it off the same API module and modal state machine instead of duplicating form state elsewhere.

backend/tests/test_cloud.py

Primary analog

  • Current integration coverage for connect/upload/status/browse/rename/refresh: [backend/tests/test_cloud.py:30-65], [backend/tests/test_cloud.py:473-527], [backend/tests/test_cloud.py:532-655], [backend/tests/test_cloud.py:998-1315]

Copy these conventions

  • Use the shared auth helper pattern and async_client.
  • Patch provider/network boundaries, not route internals, where possible.
  • Assert both HTTP contract and DB side effects.

backend/tests/test_cloud_security.py

Primary analog

  • Current security-negative suite: [backend/tests/test_cloud_security.py:37-117], [backend/tests/test_cloud_security.py:122-340]

Copy these conventions

  • Add Phase 13 wrong-owner/admin/credential/no-byte/cross-connection negatives here.
  • Keep raw-provider-error sanitization assertions here, not only in happy-path integration tests.

backend/tests/test_cloud_backends.py

Primary analog

  • Provider backend behavior tests: [backend/tests/test_cloud_backends.py:334-420] and the rest of the files provider sections

Copy these conventions

  • Provider-specific fixtures, normalized assertions.
  • Explicit “never download/mutate while browsing” checks.
  • Keep backend tests provider-neutral where possible and provider-specific only where semantics differ.

backend/tests/test_cloud_provider_contract.py

Primary analog

  • Canonical signature/identity/pagination/no-byte contract: [backend/tests/test_cloud_provider_contract.py:201-276], [backend/tests/test_cloud_provider_contract.py:376-536], [backend/tests/test_cloud_provider_contract.py:659-727]

Copy these conventions

  • Any new mutable adapter methods should get the same style of canonical contract tests: signature, normalized result, trusted caller identity, no forbidden side effects.

backend/tests/test_cloud_items.py

Primary analog

  • Owner-scoped service and folder-state tests: [backend/tests/test_cloud_items.py:368-529], [backend/tests/test_cloud_items.py:545-859]

Copy these conventions

  • Mutation reconciliation tests belong here: stable UUID across rename/move, complete/incomplete behavior, freshness truth, no quota mutation.

backend/tests/test_cloud_mutations.py

Closest analogs

  • API behavior: [backend/tests/test_cloud.py:473-527], [backend/tests/test_cloud.py:1112-1249]
  • Security negatives: [backend/tests/test_cloud_security.py:122-340]
  • Reconciliation truth: [backend/tests/test_cloud_items.py:411-499], [backend/tests/test_cloud_items.py:743-859]

No exact analog

  • There is no existing end-to-end mutation suite for cloud items. Build it as a new file, but follow the helper/fixture style of test_cloud.py.

backend/tests/test_cloud_reconnect.py

Closest analogs

  • Connection lifecycle/status: [backend/tests/test_cloud.py:532-655]
  • Worker/freshness behavior: [backend/tests/test_cloud.py:1251-1315], [backend/tests/test_cloud_items.py:545-609]

No exact analog

  • There is no dedicated reconnect/token-persistence suite today.

backend/tests/test_cloud_audit.py

Closest analogs

  • Audit helper behavior: [backend/services/audit.py:27-58]
  • Inline audit assertions in cloud routes: [backend/api/cloud/connections.py:351-359], [backend/api/cloud/connections.py:422-430], [backend/api/cloud/connections.py:567-575], [backend/api/cloud/connections.py:624-632]

No exact analog

  • There is no cloud-mutation audit suite today; create one that asserts metadata-only payloads and same-transaction persistence.

frontend/src/views/__tests__/CloudFolderView.test.js

Primary analog

  • Existing thin-view cloud tests: [frontend/src/views/tests/CloudFolderView.test.js:73-294]

Copy these conventions

  • Stub StorageBrowser when the test is about view orchestration only.
  • Assert route params, API calls, and props passed to the browser.

frontend/src/views/__tests__/CloudFolderRenderedFlow.test.js

Primary analog

  • Existing real-browser rendered flow: [frontend/src/views/tests/CloudFolderRenderedFlow.test.js:1-260]

Copy these conventions

  • Render the real StorageBrowser when testing end-to-end view/browser interactions.
  • Keep only router/API boundaries mocked.

frontend/src/components/storage/__tests__/StorageBrowser.capabilities.test.js

Primary analog

  • Current accessibility and unsupported-capability suite: [frontend/src/components/storage/tests/StorageBrowser.capabilities.test.js:47-257]

Copy these conventions

  • Assert emitted events, aria-disabled, notices, and touch-target classes from the real component.
  • Extend this file for new capability buttons only; do not hide cloud actions based on mode.

frontend/src/components/storage/__tests__/StorageBrowser.cloud-queue.test.js

Closest analogs

  • Capability interaction assertions: [frontend/src/components/storage/tests/StorageBrowser.capabilities.test.js:89-190]
  • Local upload queue behavior source: [frontend/src/views/FileManagerView.vue:103-128]

No exact analog

  • There is no existing paused sequential queue test file. Create it as a dedicated component suite around the shared browsers new queue/conflict UI.

frontend/src/views/__tests__/CloudFolderOpenPreview.test.js

Closest analogs

  • Rendered cloud flow: [frontend/src/views/tests/CloudFolderRenderedFlow.test.js:170-260]
  • Authorized document content fetch helper: [frontend/src/api/documents.js:60-81]

No exact analog

  • There is no cloud open/preview rendered-flow test today.

frontend/src/stores/__tests__/cloudConnections.test.js

Primary analog

  • Existing store tests for selection, freshness, session state: [frontend/src/stores/tests/cloudConnections.test.js:28-237]

Copy these conventions

  • Keep pure store tests focused on mapping and reset behavior.
  • If queue state or health-state translation lives in the store, test it here once.

frontend/src/components/settings/__tests__/SettingsCloudTab.test.js

Primary analog

  • Existing settings-tab tests: [frontend/src/components/settings/tests/SettingsCloudTab.test.js:1-132]

Copy these conventions

  • Mock the store and API module, not network.
  • Keep component tests structural and action-trigger oriented.

frontend/src/components/settings/__tests__/SettingsCloudTab.health.test.js

Closest analogs

  • Existing settings tab structure: [frontend/src/components/settings/tests/SettingsCloudTab.test.js:51-132]
  • Store freshness/health state assertions: [frontend/src/stores/tests/cloudConnections.test.js:160-237]

No exact analog

  • There is no dedicated health/test/reconnect settings suite yet.

Shared Patterns to Reuse Everywhere

Authentication / ownership

  • Regular-user-only dependency: [backend/api/cloud/browse.py:29-31], [backend/api/cloud/connections.py:25-27], [backend/api/documents/content.py:24-26]
  • Owner resolution before resource work: [backend/api/cloud/browse.py:205-214], [backend/api/cloud/connections.py:132-141], [backend/services/cloud_items.py:38-62]

Router shape

  • Thin routers with typed bodies + account_limiter: [backend/api/cloud/connections.py:281-304], [backend/api/cloud/browse.py:183-200], [backend/api/folders.py:122-149]
  • Response shaping through explicit Pydantic schemas or dict helpers, never raw ORM/provider payloads: [backend/api/cloud/browse.py:64-97], [backend/api/cloud/schemas.py:17-67]

Error translation

  • CloudConnectionError becomes controlled reconnect guidance: [backend/api/documents/upload.py:160-175], [backend/api/documents/content.py:61-76]
  • Incomplete/stale provider state becomes controlled warning, not fake success: [backend/services/cloud_items.py:319-342], [backend/api/cloud/browse.py:296-307]

Audit

  • Use write_audit_log(...) after successful state change, inside caller-owned transaction: [backend/services/audit.py:27-58]

Provider boundary

  • Providers normalize data and keep SDK/HTTP details private: [backend/storage/google_drive_backend.py:276-362], [backend/storage/onedrive_backend.py:300-386], [backend/storage/webdav_backend.py:241-332]
  • Factories own provider construction and URL normalization: [backend/storage/cloud_backend_factory.py:7-66]

Frontend architecture

  • Thin view -> shared browser: [frontend/src/views/CloudFolderView.vue:1-20], [frontend/src/views/FileManagerView.vue:1-30]
  • Shared browser owns interaction/layout/state: [frontend/src/components/storage/StorageBrowser.vue:424-681]
  • Settings tab owns connection controls, not provider-specific subviews: [frontend/src/components/settings/SettingsCloudTab.vue:21-214]

Testing

  • Integration tests assert API contract plus DB side effect: [backend/tests/test_cloud.py:532-655], [backend/tests/test_cloud.py:1112-1249]
  • Security tests assert absence of leaks and forbidden side effects: [backend/tests/test_cloud_security.py:197-301]
  • View tests stub the browser for orchestration-only checks; rendered-flow tests use the real browser: [frontend/src/views/tests/CloudFolderView.test.js:51-101], [frontend/src/views/tests/CloudFolderRenderedFlow.test.js:170-205]

No-Analog / planner watchlist

  1. Provider-neutral mutation result dataclasses do not exist yet. Add them in backend/storage/cloud_base.py; do not leak provider payloads.
  2. OAuth reconnect that patches an existing connection row does not exist yet. Current callback flow inserts a new row.
  3. Shared paused upload queue UI for cloud conflicts/errors does not exist yet. Add it in StorageBrowser.vue, not a cloud-only component.
  4. Authorized cloud-item preview/open endpoints do not exist yet. Reuse document content streaming patterns, but this is a new endpoint family.
  5. Dedicated reconnect/audit/open-preview test suites do not exist yet; create them instead of overloading unrelated files.
  1. Extend cloud_base.py + provider backends + factory.
  2. Add cloud_operations.py and keep all reconciliation through cloud_items.py.
  3. Add api/cloud/operations.py, then minimally extend connections.py / schemas.py.
  4. Extend api/cloud.js + cloudConnections.js + CloudFolderView.vue.
  5. Extend StorageBrowser.vue and SettingsCloudTab.vue.
  6. Add the missing dedicated backend/frontend test files before broad polish.

PATTERN MAPPING COMPLETE