Harden auth/upload, fix PR-delete cascade and sync backfill
- OIDC: require signed short-lived state on login callback; reject missing userinfo sub (account-takeover guard); validate token exchange + userinfo responses - Upload: safe zip extraction (path-traversal + zip-bomb cap), streamed size-capped writes, sanitised filenames - Garmin: increasing lookback resets last_sync_at for one-time backfill - Activities: delete/reprocess remove PersonalRecord rows (no FK cascade) - Profile: validate /weight limit; sync lookback UI copy - Dashboard: sleep shading uses same day as charted body battery Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,7 @@ from datetime import datetime
|
||||
|
||||
from app.core.database import get_db
|
||||
from app.core.security import get_current_user
|
||||
from app.models.user import User, Activity, ActivityDataPoint, ActivityLap
|
||||
from app.models.user import User, Activity, ActivityDataPoint, ActivityLap, PersonalRecord
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@@ -266,6 +266,10 @@ async def delete_activity(
|
||||
activity = result.scalar_one_or_none()
|
||||
if not activity:
|
||||
raise HTTPException(status_code=404, detail="Activity not found")
|
||||
# PersonalRecord.activity_id has no cascade, so remove the activity's PR rows
|
||||
# first or the delete fails the FK constraint. (segment_efforts cascade in DB;
|
||||
# data_points/laps cascade via the ORM relationship.)
|
||||
await db.execute(delete(PersonalRecord).where(PersonalRecord.activity_id == activity_id))
|
||||
await db.delete(activity)
|
||||
await db.commit()
|
||||
|
||||
@@ -297,6 +301,8 @@ async def reprocess_activity(
|
||||
|
||||
await db.execute(delete(ActivityDataPoint).where(ActivityDataPoint.activity_id == activity_id))
|
||||
await db.execute(delete(ActivityLap).where(ActivityLap.activity_id == activity_id))
|
||||
# Drop PR rows referencing this activity (no cascade); the re-parse re-computes them.
|
||||
await db.execute(delete(PersonalRecord).where(PersonalRecord.activity_id == activity_id))
|
||||
await db.delete(activity)
|
||||
await db.commit()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user