Deploy Stride with encrypted manual and scheduled Garmin sync

This commit is contained in:
Peter Stockings
2026-10-01 20:42:28 +10:00
parent 24c7fc2c6a
commit 8555695c5e
28 changed files with 900 additions and 56 deletions
+17 -7
View File
@@ -27,7 +27,7 @@ account exists. Subsequent accounts start empty.
The local app uses SQLite in `instance/dashboard.db`. Set `DATABASE_URL` to a
PostgreSQL connection string to use PostgreSQL. Database changes use Alembic
migrations. Local schema creation/upgrade has been verified on SQLite; PostgreSQL
runtime validation remains pending because Docker was unavailable locally.
runtime validation is recorded in docs/DEPLOYMENT.md.
### Accounts and sharing
@@ -38,7 +38,12 @@ runtime validation remains pending because Docker was unavailable locally.
the in-app request. No invitation email is sent by this local version.
- Accepted friends see each other's shared activities and full recorded routes.
- Removing a friend immediately revokes access to shared profiles, pages and JSON.
- There is no Explore page, public feed, or anonymous access to activity data.
- Use the link icon on your run page to copy a public link. Anyone with that link
can view the run, full route and charts without signing in. Public links are
separate from friend visibility; disable a link in the run's sharing settings
to revoke access. There is no Explore page or public feed.
- Share links use the address you opened the app with. A localhost link only works
on your own computer; sharing with others requires a reachable app address.
- Routes are not masked or trimmed. Access control, rather than geographic masking,
determines who can see the full route, including start and finish.
@@ -58,7 +63,7 @@ uv run --locked flask --app app import-local --email owner@example.com --account
The application uses CSRF protection, hashed passwords, login throttling, and
server-side authorization on every activity page and data endpoint. Before public
deployment, finish email verification/recovery, shared production rate-limit
storage, encrypted token uploads, scheduled jobs and PostgreSQL/Dokku validation.
storage, and account recovery. Deployment instructions and sync behavior are in docs/DEPLOYMENT.md.
The current server binds only to loopback and runs without debug mode.
Users will upload FIT files or connect Garmin by authenticating locally with
@@ -134,8 +139,7 @@ operations, but possession of its token file provides broader account access.
Local credential storage is plain JSON with restricted permissions on POSIX; on
Windows it relies on your directory ACLs. Use a private Windows user directory or
restrict this workspace's ACLs on a shared machine. Encrypted database credential
storage belongs to the future web implementation, not this local proof of concept.
restrict this workspace's ACLs on a shared machine. Uploaded web sessions are encrypted in PostgreSQL using TOKEN_ENCRYPTION_KEY.
No credentials or real activity files should be committed to Git.
## Verification
@@ -151,10 +155,16 @@ A live verification requires running login, syncing at least one activity, then
running sync again to confirm it skips the previously downloaded files. Record
the actual outcome in `docs/SYNC_VALIDATION.md`.
Current scope: local Flask app and sync CLI. Scheduled worker, token-upload web
endpoint, email verification/recovery, and Dokku deployment remain to be implemented.
The web app supports encrypted Garmin session uploads, manual queued sync, hourly scheduled sync, and a Dokku worker. Email verification/recovery remains unimplemented.
For an isolated browser test with synthetic data, run
`uv run python scripts/preview-fixture.py` and visit port 5001. This test process
uses an in-memory database and auto-login, never reads Garmin files, and must not
be deployed. The regular app does not have auto-login or seeded test accounts.
## Server sync
Under Settings & imports, upload your exported Garmin session JSON to connect.
Use **Sync now** for manual sync; hourly sync is enabled for new connections.
Both use a separate persistent worker and import the latest 100 activities privately.
Pause hourly sync or disconnect at any time. See [deployment notes](docs/DEPLOYMENT.md).