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>
Cloud upload uses typed conflict and error bodies instead of hidden overwrite semantics.
Provider upload differences stay behind the mutable adapter and service contract.
Refreshed provider credentials can be handed upward during upload work without provider-owned database writes.
path
provides
backend/api/cloud/operations.py
Connection-ID upload endpoint with typed conflict and retry result bodies.
path
provides
backend/services/cloud_operations.py
Upload dispatch that normalizes keep-both, replace, retryable error, and unsupported-replace outcomes.
from
to
via
pattern
provider upload result
shared queue resume decisions
typed kind/reason response bodies
conflict
from
to
via
pattern
refreshed provider credentials
service-layer persistence handoff
upload success and retry paths
credentials
Implement the bounded backend upload mechanics slice of Phase 13: connection-ID upload routing, typed conflict and retry bodies, provider-normalized keep-both or replace handling, and refreshed-credential handoff without yet folding in reconcile or audit follow-through.
Purpose: Finish the provider and route mechanics the shared upload queue needs before the authoritative success path is layered on top.
Output: Upload-capable provider adapters, route and service dispatch, and passing backend upload mechanics suites.
Upload support in backend/api/cloud/operations.py and backend/services/cloud_operations.py.
Provider-normalized keep-both, replace, retry, skip, and unsupported-replace semantics across Google Drive, OneDrive, Nextcloud-via-WebDAV, and generic WebDAV.
Passing upload and provider-contract suites for the mechanics half of CLOUD-03.
backend/tests/test_cloud_backends.py and backend/tests/test_cloud_provider_contract.py — four-provider normalization assertions.
backend/services/cloud_operations.py from 13-03 — refreshed-credential handoff and typed domain-result pattern.
Task 1: Implement provider-normalized upload conflict semantics across the adapter boundary
backend/storage/google_drive_backend.py, backend/storage/onedrive_backend.py, backend/storage/webdav_backend.py, backend/tests/test_cloud_backends.py, backend/tests/test_cloud_provider_contract.py
- backend/storage/google_drive_backend.py
- backend/storage/onedrive_backend.py
- backend/storage/webdav_backend.py
- backend/tests/test_cloud_backends.py
- backend/tests/test_cloud_provider_contract.py
- .planning/phases/13-virtual-local-cloud-operations/13-CONTEXT.md
- Test 1: upload can return success, typed conflict, typed retryable error, or explicit unsupported-replace results
- Test 2: keep-both naming is authoritative and inserts the counter before the file extension
- Test 3: provider-specific conflict semantics normalize into one shared contract across all four providers
Implement D-03 and D-04 inside the provider layer so Google Drive, OneDrive, and the shared WebDAV path normalize upload conflicts, replace support, keep-both suffixing, and retryable transient failures into one mutable-operation contract. Preserve broader Google Drive access assumptions, OneDrive refreshed-credential handoff, and SSRF validation on every WebDAV upload request. Keep Nextcloud on the shared WebDAV mutation path unless a narrow override is strictly required.
- upload provider suites pass for all four supported providers
- keep-both naming is authoritative and consistent across providers
- provider code returns typed results and never writes `cloud_items`, audit rows, or router-visible provider payloads directly
docker compose run --rm backend pytest -v tests/test_cloud_backends.py tests/test_cloud_provider_contract.py -k "upload or replace or conflict" -x
The adapter layer now exposes typed, provider-normalized upload mechanics for the shared queue.
Task 2: Expose connection-ID upload dispatch with typed route and service results
backend/api/cloud/operations.py, backend/api/cloud/schemas.py, backend/services/cloud_operations.py, backend/tests/test_cloud_mutations.py
- backend/api/cloud/operations.py
- backend/api/cloud/schemas.py
- backend/services/cloud_operations.py
- backend/tests/test_cloud_mutations.py
- .planning/phases/13-virtual-local-cloud-operations/13-CONTEXT.md
- Test 1: the upload route returns typed success, conflict, retryable error, and unsupported-replace bodies
- Test 2: the service layer owns refreshed-credential persistence handoff above the provider boundary
- Test 3: queue-control semantics come from backend-authored results instead of Vue-side inference
Wire the connection-ID upload endpoint through `backend/services/cloud_operations.py` and `backend/api/cloud/schemas.py` so the route returns stable `kind` and `reason` bodies for Keep both, Replace, Skip, Retry, Cancel all, or unsupported-replace outcomes. Keep this plan bounded to mechanics: normalize provider results, surface refreshed credentials upward for encrypted persistence, and leave centralized reconciliation plus metadata-only audit follow-through to the next plan.
- upload route and mutation suites pass for typed mechanics and credential-safe results
- queue-control semantics are backend-authored and credential-safe
- this plan does not yet add upload-specific reconciliation or success-audit behavior outside the existing foundations
docker compose run --rm backend pytest -v tests/test_cloud_mutations.py tests/test_cloud_backends.py tests/test_cloud_provider_contract.py -k "upload or replace or conflict" -x
The backend now exposes the bounded upload mechanics the next follow-through plan can finish.
<threat_model>
Trust Boundaries
Boundary
Description
browser upload → provider write
User content enters a provider-owned mutation path through DocuVault authorization only.
provider SDK/HTTP → route result
Provider conflict, retry, and replace behavior must be normalized before Vue consumes it.
STRIDE Threat Register
Threat ID
Category
Component
Disposition
Mitigation Plan
T-13-16
T
upload conflict handling
mitigate
Typed upload result bodies and provider-contract tests forbid silent overwrite behavior.
T-13-17
I
route result typing
mitigate
Upload route tests verify no provider URLs, tokens, or raw payloads escape typed responses.
T-13-18
T
provider boundary
mitigate
WebDAV SSRF and OneDrive refresh handoff remain covered by provider suites.
</threat_model>
- Pass the bounded backend upload and provider-contract suites.
- Confirm all backend pytest invocations are direct containerized commands.
- Confirm upload mechanics stop at typed route and service results, leaving reconcile and audit follow-through to the next plan.
<success_criteria>
The backend can upload into the current cloud folder with typed conflict and retry semantics.
Provider-specific differences remain behind the shared contract and service layer.
The upload mechanics plan stays within 9 files and leaves reconcile plus audit follow-through for the next bounded plan.
</success_criteria>
Create `.planning/phases/13-virtual-local-cloud-operations/13-05-SUMMARY.md` when done