Files
kite/.planning/phases/05-cloud-storage-backends/05-DISCUSSION-LOG.md
T
2026-05-28 17:52:25 +02:00

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 (webdavclient3 vs. aiohttp with manual PROPFIND)
  • TTL cache implementation (cachetools.TTLCache vs. 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