Fix five code-review findings: token auth, sync rate-limiting, model drift, FK cascade
- garmin_connect_sync: revert to garth.loads() for token auth — login(tokenstore=) dispatches on len>512, treating compact tokens as filesystem paths and forcing a full re-login on every sync. Explicitly set display_name from the embedded profile. - garmin_connect_sync: restore incremental sync for both activities and wellness — always re-fetching the full lookback window was generating ~270 Garmin API calls per wellness sync run, risking rate-limits. Now uses since-1d when since is set. Add 0.25s per-day sleep in sync_wellness as an additional rate-limit guard. - models/user.py: replace the dropped uq_pr_current UniqueConstraint in PersonalRecord.__table_args__ with the partial Index the DB actually has, so the model and live schema no longer permanently diverge. - models/user.py: add ondelete="SET NULL" to Activity.named_route_id FK so the DB cascade handles unlinks if routes are deleted outside the API endpoint. - main.py: add startup migration to re-add activities_named_route_id_fkey with ON DELETE SET NULL on existing deployments. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -68,6 +68,22 @@ async def init_db():
|
||||
except Exception as e:
|
||||
print(f"PR constraint migration skipped: {e}")
|
||||
|
||||
# Ensure named_route_id FK has ON DELETE SET NULL so routes can be deleted
|
||||
# without first manually unlinking every activity.
|
||||
try:
|
||||
async with engine.begin() as conn:
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE activities "
|
||||
"DROP CONSTRAINT IF EXISTS activities_named_route_id_fkey"
|
||||
))
|
||||
await conn.execute(text(
|
||||
"ALTER TABLE activities "
|
||||
"ADD CONSTRAINT activities_named_route_id_fkey "
|
||||
"FOREIGN KEY (named_route_id) REFERENCES named_routes(id) ON DELETE SET NULL"
|
||||
))
|
||||
except Exception as e:
|
||||
print(f"FK migration skipped: {e}")
|
||||
|
||||
# Seed admin user (only if password is configured)
|
||||
if not settings.admin_password:
|
||||
print("ADMIN_PASSWORD not set - skipping admin user seed")
|
||||
|
||||
Reference in New Issue
Block a user