Skip to content

Choose where trips are stored: this PC, OneDrive or Google Drive - #6

Merged
Torgh merged 3 commits into
mainfrom
cloud-storage
Oct 16, 2026
Merged

Torgh merged 3 commits into
mainfrom
cloud-storage

Conversation

@Torgh

@Torgh Torgh commented Oct 16, 2026

Copy link
Copy Markdown
Owner

Summary

Settings has a new Where your trips are stored section with three options: This PC, OneDrive and Google Drive. Switching copies the trips to the new place; when a trip exists in both, the newer version wins. The MCP server uses the same choice.

OneDrive (synced folder, no sign-in)

  • Trips are saved in the TripDeck folder inside the OneDrive folder on this PC, and the OneDrive app syncs it to other devices, including the OneDrive phone app.
  • The folder is found through %OneDrive% (Windows) or ~/Library/CloudStorage/OneDrive-… (macOS). It can also be set in Settings or with TRIPDECK_ONEDRIVE_FOLDER.
  • Why not the Graph API: personal Microsoft accounts can no longer register apps outside an Entra directory; getting one means an Azure signup. The synced folder avoids registration entirely.
  • Conflict copies: a trip's file is identified by the id inside it, so OneDrive's conflict copies and renamed files still work. The newest copy is read, and a save never deletes a copy newer than the version being saved.

Google Drive (visible folder)

  • Trips move from the hidden appDataFolder to My Drive › TripDeck, using the drive.file scope. TripDeck still only sees files it created.
  • Existing connections: an account connected before this change keeps using the hidden folder until the user clicks Reconnect, which copies the trips into the visible folder. The originals in the hidden folder are kept as a backup.

Shared

  • File names: each trip is stored as Name (id).tripdeck.json, in the same format as Export → JSON, so the files can be imported directly.
  • OAuth: moved to lib/server/cloudAuth.ts and /api/auth/[provider]/…. The Google redirect URI (/api/auth/google/callback) is unchanged, so existing OAuth clients keep working.
  • New endpoint: /api/storage switches storage and copies the trips.
  • Docs: README and .env.example updated.

Test plan

  • bun run test: 40 tests pass. New tests cover the OneDrive folder store (renames, conflict copies, non-trip files, folder detection), the Google Drive visible folder and hidden-folder migration against a fake Drive API, storage fallback, and copyTrips.
  • bun run typecheck and next build
  • End-to-end on an isolated instance with a fake OneDrive folder: loaded the demo, switched to OneDrive in Settings, and the trip file appeared in TripDeck/ with the badge showing "☁ OneDrive"
  • Reconnect a real Google account and check that trips move to My Drive › TripDeck

🤖 Generated with Claude Code

…Drive

Settings now has a storage picker. Switching copies the trips to the new
place (per trip the newer version wins), and the MCP server uses the same
choice.

- OneDrive: trips go into the TripDeck folder inside the OneDrive folder on
  this PC, which the OneDrive app syncs. No Microsoft sign-in or app
  registration is needed (personal accounts can no longer register apps
  outside a directory). The folder is found through %OneDrive% or
  ~/Library/CloudStorage, or set in Settings / TRIPDECK_ONEDRIVE_FOLDER.
  OneDrive's conflict copies are handled by reading the newest one.
- Google Drive: trips move from the hidden appDataFolder to a visible
  My Drive > TripDeck folder with the drive.file scope. Existing
  connections keep working on the hidden folder until the user reconnects,
  which copies the trips over.
- Cloud files are named "Name (id).tripdeck.json" in the Export JSON
  format, so they can be imported directly.
- OAuth moves to lib/server/cloudAuth.ts and /api/auth/[provider]; the
  Google redirect URI is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Torgh and others added 2 commits October 16, 2026 18:05
… tests

CI now runs `bun run check` (typecheck, ESLint, tests with coverage, build)
and the tests again on Windows. Coverage goes from ~32 % to ~88 % of
statements, with thresholds that fail the run when it drops.

New tests:
- http: localhost-only guard, DNS rebinding, cross-site origin, JSON body
  validation, error mapping
- cloudAuth: PKCE auth URL and scopes, code exchange, token refresh and
  revocation, offline errors
- API routes: trips CRUD and id checks, storage switching, config never
  returning secrets, Google sign-in (state/CSRF check, hidden-folder
  migration) and disconnect
- browser sync: newest wins, deletes, storage switch, offline; store
  actions; trip import
- MCP server: the real server over stdio, planning a trip end to end
- tripOps, maps fallback to OpenStreetMap, time and place helpers

ESLint (eslint-config-next core-web-vitals + typescript) found and this
fixes: a ref written during render in OsmMap, setState in effects in
Settings and Splitter, and an unused MCP helper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Raise the quality bar for pull requests: lint, coverage gate, broader tests
@Torgh
Torgh merged commit da713e9 into main Oct 16, 2026
2 checks passed
@Torgh
Torgh deleted the cloud-storage branch October 16, 2026 20:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant