Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
6.8 KiB
Phase 5: Cloud Storage Backends - Discussion Log
Audit trail only. Do not use as input to planning, research, or execution agents. Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.
Date: 2026-05-28 Phase: 5-cloud-storage-backends Areas discussed: Backend scope, OAuth flow & token refresh, Storage selection UX, Cloud document retrieval
Backend Scope
| Option | Description | Selected |
|---|---|---|
| All 4 in one phase | OneDrive, Google Drive, Nextcloud, WebDAV all in Phase 5 | ✓ |
| WebDAV + Nextcloud first | Ship simpler (credential-based) backends first; OAuth providers in Phase 6 | |
| Just one provider as MVP | One end-to-end provider to prove the pattern, others follow |
User's choice: All 4 in one phase Notes: User wants the full feature set shipped together.
OAuth Flow & Token Refresh
OAuth callback architecture
| Option | Description | Selected |
|---|---|---|
| FastAPI handles it, then redirects to Vue | Backend exchanges code for tokens, saves encrypted creds, redirects browser to Vue with success/error query param | ✓ |
| Vue intercepts the callback | Frontend catches redirect, POSTs code to FastAPI — auth code briefly in frontend | |
| You decide | Claude chooses |
User's choice: FastAPI handles it, then redirects to Vue Notes: Keeps tokens entirely server-side; consistent with existing auth architecture.
Token refresh strategy
| Option | Description | Selected |
|---|---|---|
| On-demand refresh | Catch 401, refresh silently, retry — transparent to user | ✓ (via Other) |
| Proactive Celery beat refresh | Background task refreshes before expiry | |
| Fail and prompt re-auth | Mark REQUIRES_REAUTH on expiry, no silent refresh |
User's choice: Automatic refresh (on-demand, transparent). Also explicitly requested disconnect per-connection + "Disconnect all" option.
Notes: Falls back to REQUIRES_REAUTH only on invalid_grant (refresh token itself revoked).
Nextcloud/WebDAV credential method
| Option | Description | Selected |
|---|---|---|
| URL + username + app password | App passwords revocable individually — recommended | ✓ (via Other) |
| URL + username + real password | Simpler; revocation requires changing entire account password | |
| You decide | Claude picks |
User's choice: Show both options in the UI with explanations and trade-offs; recommend app passwords. Backend stores whichever the user picks. Notes: Both use HTTP Basic Auth at the protocol level. UI copy explains the difference.
Storage Selection UX
Sidebar cloud folder tree depth
| Option | Description | Selected |
|---|---|---|
| Lazy-load one level at a time | Expand a node → fetch its children from cloud API | ✓ |
| Show only root of each provider | Single node per provider, click opens full-screen cloud browser | |
| Pre-fetch 2 levels deep on connect | Eager fetch on connect; faster browsing, stale quickly |
User's choice: Lazy-load one level at a time Notes: Cloud providers appear as top-level sidebar nodes alongside local MinIO folders, matching a Windows Explorer / Nextcloud-style file manager layout.
Upload destination
| Option | Description | Selected |
|---|---|---|
| Follows the active folder | Upload goes to the backend of the folder the user is viewing | ✓ |
| Default backend in settings | Global setting overridden per-upload | |
| Per-upload choice at upload time | Dropdown on every upload dialog |
User's choice: Follows the active folder (context-driven) Notes: No explicit setting needed — the active folder's backend determines the destination.
Existing document migration
| Option | Description | Selected |
|---|---|---|
| Stay in MinIO — no migration | Existing docs unaffected; local and cloud coexist | ✓ |
| Optional migration | Post-connect prompt to migrate existing docs | |
| You decide |
User's choice: Stay in MinIO — no migration Notes: CLOUD-03 satisfied by coexistence without migration.
Cloud provider management location
| Option | Description | Selected |
|---|---|---|
| Existing SettingsView, new "Cloud Storage" tab | Add tab to SettingsView alongside existing tabs | ✓ |
| Dedicated /cloud-storage route | New full-page view | |
| Sidebar action on cloud provider node | Gear icon → management popover |
User's choice: New "Cloud Storage" tab in SettingsView
Cloud Document Retrieval
Upload path for cloud backends
| Option | Description | Selected |
|---|---|---|
| FastAPI intermediary | File bytes go through FastAPI → cloud provider API | ✓ |
| Cloud-native resumable upload URLs | Provider-specific upload session URL generated and sent to browser | |
| You decide |
User's choice: FastAPI intermediary for cloud uploads
Notes: Presigned-PUT-URL flow stays MinIO-only. Cloud backends' generate_presigned_put_url raises NotImplementedError.
Download/preview path
| Option | Description | Selected |
|---|---|---|
| Same /api/documents/{id}/content proxy | Backend resolves StorageBackend from document.storage_backend | ✓ |
| Separate /api/documents/{id}/cloud-content | Parallel endpoint for cloud docs | |
| Temporary cloud provider URL (redirect) | Return provider's signed download URL to browser — exposes cloud URLs |
User's choice: Same proxy endpoint Notes: Frontend remains storage-backend-agnostic.
Cloud folder tree freshness
| Option | Description | Selected |
|---|---|---|
| Live calls + 60s in-memory TTL cache | Per-folder cache keyed by user+provider+path; 60s TTL | ✓ |
| Live calls only, no cache | Always fresh; no protection against rapid UI interactions | |
| You decide |
User's choice: Live calls + 60s in-memory TTL cache Notes: User raised valid concern about cloud API rate limits and potential throttling. Claude explained: human-paced browsing is well within all provider limits (Google Drive: 12k req/100s per user); TTL cache protects against collapse/re-expand patterns. No DB sync needed.
Claude's Discretion
- Python OAuth library choice (Google:
google-auth-oauthlib; Microsoft:msal) - WebDAV Python library choice (
webdavclient3vs.aiohttpwith manual PROPFIND) - TTL cache implementation (
cachetools.TTLCachevs. dict + timestamp) - OAuth state store implementation (Redis / short-lived DB row / signed JWT)
Deferred Ideas
- Document migration between backends (local → cloud)
- Cloud-native resumable upload URLs (performance optimization)
- Shared/team cloud storage
- Cloud folder tree DB sync / offline cache
- Email notifications on REQUIRES_REAUTH