From adcf1bda48bf85557d0c257274c6dbe04e9f6445 Mon Sep 17 00:00:00 2001 From: Adam French Date: Sat, 7 Mar 2026 16:43:08 +0000 Subject: [PATCH] Check that paces are reasonable --- backend/handlers/handle_rowing.go | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/backend/handlers/handle_rowing.go b/backend/handlers/handle_rowing.go index 568212a..ce8ba18 100644 --- a/backend/handlers/handle_rowing.go +++ b/backend/handlers/handle_rowing.go @@ -110,7 +110,6 @@ No text, no markdown, no explanation. Just the JSON object.`), }, }, }) - if err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{ "raw": message.Content[0].Text, @@ -153,7 +152,37 @@ No text, no markdown, no explanation. Just the JSON object.`), totalSeconds := extractedData.TimeMinutes*60 + extractedData.TimeSeconds + // Validate for anomalous values + const ( + minDistance = 100 // metres + maxDistance = 100000 // metres + minTotalSecs = 30 // 30 seconds + maxTotalSecs = 7200 // 2 hours + minPacePer500m = 80 // ~1:20 /500m (faster than any human) + maxPacePer500m = 150 // ~2:30 /500m (slow, not important) + ) + if extractedData.Distance < minDistance || extractedData.Distance > maxDistance { + ctx.JSON(http.StatusBadRequest, gin.H{"error": "anomalous distance value"}) + return + } + if totalSeconds < minTotalSecs || totalSeconds > maxTotalSecs { + ctx.JSON(http.StatusBadRequest, gin.H{"error": "anomalous time value"}) + return + } + per500m := float64(totalSeconds) / float64(extractedData.Distance) * 500.0 + if per500m < minPacePer500m || per500m > maxPacePer500m { + ctx.JSON(http.StatusBadRequest, gin.H{"error": "anomalous pace value"}) + return + } + + // Reject duplicates: same EXIF datetime already recorded + var existing models.Rowing + if err := store.DB.Where("date = ?", dateTaken).First(&existing).Error; err == nil { + ctx.JSON(http.StatusConflict, gin.H{"error": "duplicate entry for this date"}) + return + } + calories := float64(extractedData.Distance) / 7500.0 * 500.0 rowing := models.Rowing{