A desktop app that pools several Google accounts (e.g. 3 × 15 GB) into one unified ~45 GB virtual drive. Everything runs on the user’s machine; file data flows directly between the user and Google, never through a server of yours.
| Decision | Choice | Why |
|---|---|---|
| Runtime | Desktop app, Python | Clean FUSE bindings, first-class Google client, simple parallelism. Reversible: Electron/TS if you later want a polished GUI. |
| Server | None | Data flows user → Google directly. Zero hosting cost, lighter security review. |
| Auth | OAuth “Desktop app” client + PKCE, loopback on localhost | Standard serverless desktop flow; no client secret to hide. |
| Scope | drive.file |
App only touches files it created — far lighter verification than full drive scope. Chunks count as app-created, so this is sufficient even with splitting. |
| Storage model (v1) | Whole-file placement | One lost/locked account can’t corrupt other files; native Drive preview stays intact. |
| Storage model (v2) | Chunking across accounts | Needed only for single files larger than one account’s free space. |
| Metadata index | SQLite, local | Folder tree via parent_id self-reference. B+ tree indexing gives fast path lookups; no graph DB needed. |
| Quota accounting | In quota units, not request counts | New projects (post-May 2026) use the unit model: list = 100, download = 200, etc. |
Milestone: app launches, empty SQLite DB on disk, Google project ready.
The load-bearing phase. Get this right first.
localhost listener catches the redirect → exchange code for access + refresh tokens.keyring), never plaintext on disk.https://www.googleapis.com/auth/drive.file.Milestone: user logs into 3 accounts; app holds and can refresh 3 token sets.
about.get with storageQuota to read total / used / free bytes.Milestone: dashboard shows real aggregated free space. This is where the idea first feels real.
SQLite schema (starting point):
accounts — id, email, encrypted-token ref, last quota snapshotfolders — id, name, parent_id (self-referential tree)files — virtual id, name, parent_id, size, timestamps, home account id, real Drive file idchunks — reserved for Phase 6 (file id, sequence, account id, real Drive id, hash)Build the file browser: query the index, render one unified tree regardless of which account each file physically lives on. The index is the source of truth for the UI.
Milestone: unified browser renders files across accounts as one drive.
The core write path — whole files, no chunking yet.
403 User rate limit exceeded / 429 Too many requests. Budget in units (list 100, download 200, etc.), not request counts.Milestone: drop a file in → uploads to best-fit account → appears in the unified view.
Milestone: full create/read/delete lifecycle is reliable; index self-heals.
End of v1. Phases 0–5 give a genuinely usable “combined Drive.” ~2–3 focused weeks solo.
Only once v1 is solid. This unlocks single files bigger than any one account’s free space, at the cost of many more failure modes.
asyncio or ThreadPoolExecutor.chunks) and verify on reassembly — now one lost account can corrupt whole files, so integrity checks are mandatory.(Optional here: content-aware compression before chunking — but skip compressing already-compressed media like video/zip; it burns CPU for near-zero gain.)
Mount the pool as a real local disk (the way rclone does), so the OS file manager treats it like any other drive. Nicest possible UX; Python has clean FUSE bindings. Purely additive once the core works.
These change and are worth confirming, not trusting from memory or this plan:
drive.file once you leave testing mode for public release (sensitive/restricted scopes can trigger a security assessment at scale).Phase 1 → 2 → 3 → 4 → 5 = a working product. Everything else (chunking, FUSE, compression) is additive and should wait until that spine is stable.