# Phase 13: Virtual-Local Cloud Operations - Context

**Gathered:** 2026-06-22
**Status:** Ready for planning

<domain>
## Phase Boundary

Deliver owner-authorized connection maintenance and the main cloud file-management operations through the same shared browser interactions used for local files: test/reconnect/disconnect, open/preview, upload, create folder, rename, move within one connection, and delete. Mutations must respect normalized provider capabilities, promptly reconcile metadata, refresh affected listings, and emit metadata-only audit events. Phase 14 owns temporary byte-cache lifecycle and analysis; permanent cloud-to-local import remains future requirement `IMPORT-01`.

</domain>

<decisions>
## Implementation Decisions

### Shared open, preview, and upload experience
- **D-01:** Cloud open, preview, and upload must feel the same as local storage and reuse the same shared components, progress presentation, and interaction paths. `CloudFolderView` remains a thin data provider; cloud-specific transport does not justify parallel UI.
- **D-02:** Preview stays inside DocuVault and must not trigger a browser-to-device download. Unsupported preview formats fall back to an ownership-checked authorized download; provider credentials and raw provider URLs are never exposed.
- **D-03:** A same-name upload opens a conflict dialog and never overwrites silently. The available decisions are Keep both with a renamed item, Replace where supported, Skip, and Cancel all.
- **D-04:** Multi-file uploads run as a sequential queue. A conflict or error pauses the whole queue for user input without losing remaining items. Conflict actions are Keep both, Replace, Skip, and Cancel all; error actions are Retry, Skip, and Cancel all. Retry/Keep both/Replace/Skip resume the queue, while Cancel all stops it.

### Naming and concurrency conflicts
- **D-05:** Create-folder and rename collisions automatically choose a non-conflicting human-readable counter name: `Report (1).pdf`, `Report (2).pdf`, or `Projects (1)` for folders.
- **D-06:** If a concurrent client takes the candidate name between checking and mutation, retry with the next counter within a small bounded number of attempts.
- **D-07:** Rename, move, or delete must not operate on stale metadata when the item changed externally. Stop the mutation, refresh the affected folder, explain what changed, and ask the user to retry.

### Move and delete safeguards
- **D-08:** Moving cloud items matches local storage: support both drag-to-folder and the shared folder picker. Destinations are restricted to the same cloud connection; cross-provider transfer remains out of scope.
- **D-09:** Invalid folder destinations, including the folder itself and its descendants, are disabled before submission and independently rejected by the backend.
- **D-10:** Delete confirmation is context-sensitive. Files receive a standard confirmation; folders clearly warn that nested contents are included.
- **D-11:** Prefer the provider's trash/recycle-bin operation when supported. When only permanent deletion is available, the confirmation must say so explicitly.

### Connection health and recovery
- **D-12:** Connection health appears in both places users need it: compact status plus Reconnect in the cloud browser, and full diagnostics plus Test/Reconnect controls in Settings.
- **D-13:** Test automatically after connect/reconnect and after credential-related failures, and allow an explicit Test action. Do not probe the provider on every folder navigation.
- **D-14:** A successful reconnect keeps cached metadata visible as stale, invalidates provider/listing/capability caches, and immediately refreshes the current folder.
- **D-15:** A timeout or temporarily unreachable provider is an unhealthy connection state only. Preserve credentials and cached metadata, show an actionable warning, and allow retry/reconnect; never delete data because of transient failure.
- **D-16:** Explicit user-initiated Disconnect requires confirmation, removes credentials and connection-scoped cloud metadata, and leaves all provider files untouched. Phase 13 has no byte cache to migrate.

### Codex's Discretion
- Choose exact accessible dialog wording, progress labels, icons, and controlled provider-error translations while preserving the decisions above.
- Choose the bounded retry count for automatic collision suffixing and safe provider-specific mechanics for trash versus permanent delete.
- Choose endpoint shapes and service decomposition consistent with the existing owner-scoped cloud API, canonical adapter, reconciliation service, and shared frontend architecture.

</decisions>

<canonical_refs>
## Canonical References

**Downstream agents MUST read these before planning or implementing.**

### Milestone and prior phase contracts
- `.planning/ROADMAP.md` — Phase 13 goal, requirements, success criteria, and Phase 14 boundary.
- `.planning/REQUIREMENTS.md` — canonical CONN-01 through CONN-03 and CLOUD-02 through CLOUD-07/CLOUD-09 requirements; `IMPORT-01` remains future scope.
- `.planning/PROJECT.md` — virtual-local storage model, privacy boundary, and shared-component direction.
- `.planning/phases/12-cloud-resource-foundation/12-CONTEXT.md` — normalized capability, shared browser, freshness, metadata, and no-byte browse decisions inherited by this phase.
- `.planning/phases/12.1-fix-nextcloud-root-listing-and-sync-visibility/12.1-CONTEXT.md` — truthful listing/freshness and provider-neutral correctness constraints.
- `AGENTS.md` — non-negotiable architecture, security, testing, documentation, environment, and Git rules.

### Backend cloud contracts
- `backend/storage/cloud_base.py` — canonical normalized actions, capability states, cloud resources/listings, and read-only adapter to extend for Phase 13 mutations.
- `backend/storage/google_drive_backend.py` — Google Drive provider integration and operation semantics.
- `backend/storage/onedrive_backend.py` — OneDrive/Graph provider integration and token lifecycle.
- `backend/storage/nextcloud_backend.py` — Nextcloud adapter behavior.
- `backend/storage/webdav_backend.py` — WebDAV behavior and SSRF/path safety boundary.
- `backend/services/cloud_items.py` — sole metadata reconciliation entry point and stable item identity behavior.
- `backend/api/cloud/browse.py` — owner-scoped connection-ID browse path, cache/freshness response, and capability serialization.
- `backend/api/cloud/connections.py` — connect, health check, credential update, display-name rename, and disconnect behavior.
- `backend/api/cloud/schemas.py` — credential-free whitelisted cloud response types.

### Shared frontend and verification
- `frontend/src/components/storage/StorageBrowser.vue` — single local/cloud browser and existing shared upload, rename, move, delete, drag/drop, and capability UI.
- `frontend/src/views/CloudFolderView.vue` — thin cloud data-provider integration and current upload/open placeholders.
- `frontend/src/views/FileManagerView.vue` — canonical local interaction behavior that cloud operations must match.
- `frontend/src/stores/cloudConnections.js` — connection and browse state, capabilities, freshness, and session-only navigation state.
- `frontend/src/api/cloud.js` — cloud connection/browse API client surface to extend.
- `backend/tests/test_cloud_backends.py` — provider contract test patterns.
- `backend/tests/test_cloud.py` — connection and browse API integration patterns.
- `backend/tests/test_cloud_security.py` — owner/admin/credential/SSRF/no-byte negative contract.
- `frontend/src/components/storage/__tests__/StorageBrowser.capabilities.test.js` — shared capability rendering and interaction coverage.
- `frontend/src/views/__tests__/CloudFolderRenderedFlow.test.js` — rendered shared-browser cloud flow coverage.

</canonical_refs>

<code_context>
## Existing Code Insights

### Reusable Assets
- `StorageBrowser.vue`: already owns the local/cloud rows, drop zone, upload progress, inline folder rename, move picker, drag-to-move, delete actions, and capability-aware controls; Phase 13 should extend its generic events rather than add cloud-only layout.
- `CloudFolderView.vue`: already maps normalized `kind`, opaque `provider_item_id`, explicit breadcrumbs, upload queue state, and browse refresh; replace placeholders with thin API/store handlers.
- `CloudResourceAdapter` and `CloudCapability`: already define normalized action vocabulary and provider-neutral capability reporting; mutation operations should extend this contract without provider-specific API branches.
- `resolve_owned_connection`, `upsert_cloud_item`, and `reconcile_cloud_listing`: existing owner-scoped service primitives and the single metadata reconciliation path.

### Established Patterns
- Views own stores and route state; `StorageBrowser` owns interaction/layout and emits events; providers never update `cloud_items` directly.
- Cloud navigation and mutations use connection UUID plus opaque `provider_item_id`; provider IDs are never parsed into paths.
- Cached metadata remains usable through provider failures, and freshness comes from the backend rather than inferred client-side.
- Credentials are decrypted only at the provider/task boundary and never enter responses, broker payloads, logs, snapshots, or browser storage.

### Integration Points
- Add provider-neutral mutation methods and normalized conflict/error results to the cloud adapter layer, then implement them for Google Drive, OneDrive, Nextcloud, and WebDAV.
- Add owner-scoped schemas, service orchestration, connection-ID mutation/open endpoints, cache invalidation, reconciliation, and metadata-only auditing under `backend/api/cloud/` and `backend/services/`.
- Feed shared operation events, sequential upload queue resolution, connection health, and mutation refresh results through `CloudFolderView`/the Pinia store into `StorageBrowser`.
- Extend provider contract, API/security integration, store/view/component, and rendered-flow tests; preserve explicit unsupported-capability coverage.

</code_context>

<specifics>
## Specific Ideas

- The intended rule is literal: if local and cloud operations look the same to the user, they are the same component and interaction in code.
- Upload conflict resolution is queue-level: the current item blocks later items until the user resumes or cancels all.
- Automatic collision names place the counter before the file extension.
- Reconnect should feel non-destructive: stale metadata stays visible while DocuVault revalidates it.

</specifics>

<deferred>
## Deferred Ideas

- Phase 14 must place bytes used for in-app cloud preview into DocuVault's temporary cache and remove them through normal cache eviction/clearing; preview must not become a browser-to-device download.
- Future `IMPORT-01`: on explicit disconnect, convert cached/downloaded cloud files into local DocuVault documents under a folder named after the connection's current display name, preserve the cloud hierarchy, continue counting those bytes toward quota, and leave provider files untouched. This is a permanent import capability and remains outside Phase 13 and the current v0.3 scope.

</deferred>

---

*Phase: 13-virtual-local-cloud-operations*
*Context gathered: 2026-06-22*
