Commit Graph

14 Commits

Author SHA1 Message Date
Bastian Wagner
8d73dea7dd Live-update dashboard rows and show toasts after sync actions
"Sync now" and "Sync all now" now return the freshly reloaded rider
row(s) plus an out-of-band toast instead of navigating to a separate
result page. The "sync already running" case is a 200 + info toast
now instead of a 409 special case.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-16 13:16:10 +02:00
Bastian Wagner
a0890126bc Add dashboard summary tiles
Shows rider count, activities imported in the last 7 days, 7-day
sync success rate, and how many riders currently need attention,
right above the rider list where an admin looks first.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-16 12:48:44 +02:00
Bastian Wagner
a74ab95f3f Show next scheduled sync time on every page
Exposes the scheduler's next_tick in the topbar via a safe Jinja
helper (falls back to nothing if the scheduler isn't running yet),
and converts the server-rendered UTC timestamp to the visitor's local
time client-side so it reads correctly regardless of timezone.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-16 10:58:53 +02:00
Bastian Wagner
ff5dab6f0d intervall 2026-08-15 21:44:13 +02:00
Bastian Wagner
f7b04337ce auth für user 2026-08-15 21:34:40 +02:00
Bastian Wagner
420d089760 log 2026-08-15 20:54:35 +02:00
Bastian Wagner
2aba1265af mail notification 2026-08-15 20:47:02 +02:00
Bastian Wagner
85b0d861b4 feat: restyle admin UI and add per-user sync run history
Adds a self-hosted stylesheet (no CDN dependencies) with a card-based
dashboard and color-coded status badges, and shows the last 10 sync
runs per user on the detail page.
2026-08-15 20:19:31 +02:00
Bastian Wagner
6657124983 feat: handle Garmin MFA and activity retries 2026-08-15 16:33:16 +02:00
Bastian Wagner
c2f13611b9 feat: add operational sync controls 2026-08-15 16:24:11 +02:00
Bastian Wagner
49aba8efb4 fix: address final review findings for foundation plan
- C1: drop module-level app singleton in app/main.py so importing the
  package no longer validates Settings or creates DATA_DIR; run uvicorn
  with --factory in the Dockerfile. pytest now collects and passes with
  no ambient env vars.
- I2: add missing app/auth, app/security, app/web __init__.py so
  setuptools discovers all five packages.
- I3: resolve the Jinja2 template directory relative to __file__ instead
  of the process CWD.
- I4: add .gitignore covering .env, data/, .venv/, caches and build
  artifacts so example deployment secrets cannot be committed.
- I5: assert UserRepository.list_enabled() excludes disabled users.
- M6: encode both operands before hmac.compare_digest in validate_csrf so
  a non-ASCII token yields 403 instead of an unhandled 500.
- M9: remove unused relationship / HealthState imports.
- M11: make session cookie https_only configurable via SESSION_HTTPS_ONLY
  (default unchanged: false).
- M13: dispose SQLAlchemy engines in the db_session and client fixtures.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 10:14:26 +02:00
Bastian Wagner
d2ac079870 fix: reject empty credential fields with 400 instead of 500
Add an explicit non-empty check before encrypting user-submitted
email/password fields in the create and update user routes, so a
request that bypasses the HTML `required` attribute gets a clean
400 instead of an unhandled ValueError from CredentialCipher.encrypt
propagating as a 500. Applies to all four credential fields on
create, and to the two email fields on update (the password-blank-
means-keep-existing behavior on update is unchanged).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 09:50:05 +02:00
Bastian Wagner
b39842fe2c feat: add encrypted sync user management
Adds full CRUD for sync users (create/list/detail/edit) behind admin
auth and CSRF protection. Passwords are encrypted at rest and never
decrypted into a template context; only emails may be decrypted for
display on the edit form. Blank password fields on edit preserve the
existing encrypted password.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 09:41:21 +02:00
Bastian Wagner
da6b94ca2f feat: add local admin authentication 2026-08-15 09:33:27 +02:00