(
challenge_id: str,
payload: PositionIn,
response: Response,
participant=Cookie(default=None, alias=COOKIE_NAME),
)
| 464 | |
| 465 | @app.post("/api/challenges/{challenge_id}/position") |
| 466 | def submit_position( |
| 467 | challenge_id: str, |
| 468 | payload: PositionIn, |
| 469 | response: Response, |
| 470 | participant=Cookie(default=None, alias=COOKIE_NAME), |
| 471 | ) -> dict: |
| 472 | current = get_or_create_participant(response, participant) |
| 473 | with connect() as conn: |
| 474 | challenge = conn.execute( |
| 475 | "SELECT * FROM challenges WHERE id = ? AND status = 'active'", |
| 476 | (challenge_id,), |
| 477 | ).fetchone() |
| 478 | if not challenge: |
| 479 | raise HTTPException(status_code=404, detail="Active challenge not found") |
| 480 | |
| 481 | if payload.accuracy_m is not None and payload.accuracy_m > MAX_ACCURACY_M: |
| 482 | record_event(conn, challenge_id, current["id"], "low_accuracy", payload) |
| 483 | return {"accepted": False, "reason": "low_accuracy"} |
| 484 | if payload.speed_mps is not None and payload.speed_mps > MAX_SPEED_MPS: |
| 485 | record_event(conn, challenge_id, current["id"], "too_fast", payload) |
| 486 | return {"accepted": False, "reason": "too_fast"} |
| 487 | |
| 488 | map_lat, map_lng = wgs84_to_gcj02(payload.lat, payload.lng) |
| 489 | cell_id = latlng_to_cell(map_lat, map_lng, int(challenge["h3_resolution"])) |
| 490 | exists = conn.execute( |
| 491 | """ |
| 492 | SELECT 1 FROM challenge_cells |
| 493 | WHERE challenge_id = ? AND cell_id = ? |
| 494 | """, |
| 495 | (challenge_id, cell_id), |
| 496 | ).fetchone() |
| 497 | if not exists: |
| 498 | record_event(conn, challenge_id, current["id"], "outside_area", payload) |
| 499 | return { |
| 500 | "accepted": False, |
| 501 | "reason": "outside_area", |
| 502 | "cell_id": cell_id, |
| 503 | "map_lat": map_lat, |
| 504 | "map_lng": map_lng, |
| 505 | } |
| 506 | |
| 507 | cur = conn.execute( |
| 508 | """ |
| 509 | INSERT OR IGNORE INTO user_unlocked_cells |
| 510 | (challenge_id, participant_id, cell_id, source, accuracy_m, speed_mps, created_at) |
| 511 | VALUES (?, ?, ?, 'gps', ?, ?, ?) |
| 512 | """, |
| 513 | ( |
| 514 | challenge_id, |
| 515 | current["id"], |
| 516 | cell_id, |
| 517 | payload.accuracy_m, |
| 518 | payload.speed_mps, |
| 519 | now_iso(), |
| 520 | ), |
| 521 | ) |
| 522 | return { |
| 523 | "accepted": True, |
nothing calls this directly
no test coverage detected