(
challenge_id: str,
payload: UnlockIn,
response: Response,
participant=Cookie(default=None, alias=COOKIE_NAME),
)
| 409 | |
| 410 | @app.post("/api/challenges/{challenge_id}/unlock") |
| 411 | def unlock_cells( |
| 412 | challenge_id: str, |
| 413 | payload: UnlockIn, |
| 414 | response: Response, |
| 415 | participant=Cookie(default=None, alias=COOKIE_NAME), |
| 416 | ) -> dict: |
| 417 | if not manual_unlock_enabled(): |
| 418 | raise HTTPException(status_code=403, detail="Manual unlock is disabled") |
| 419 | current = get_or_create_participant(response, participant) |
| 420 | current_time = now_iso() |
| 421 | inserted = 0 |
| 422 | rejected: list[str] = [] |
| 423 | with connect() as conn: |
| 424 | challenge = conn.execute( |
| 425 | "SELECT * FROM challenges WHERE id = ? AND status = 'active'", |
| 426 | (challenge_id,), |
| 427 | ).fetchone() |
| 428 | if not challenge: |
| 429 | raise HTTPException(status_code=404, detail="Active challenge not found") |
| 430 | for cell_id in payload.cell_ids: |
| 431 | exists = conn.execute( |
| 432 | """ |
| 433 | SELECT 1 FROM challenge_cells |
| 434 | WHERE challenge_id = ? AND cell_id = ? |
| 435 | """, |
| 436 | (challenge_id, cell_id), |
| 437 | ).fetchone() |
| 438 | if not exists: |
| 439 | rejected.append(cell_id) |
| 440 | continue |
| 441 | cur = conn.execute( |
| 442 | """ |
| 443 | INSERT OR IGNORE INTO user_unlocked_cells |
| 444 | (challenge_id, participant_id, cell_id, source, accuracy_m, speed_mps, created_at) |
| 445 | VALUES (?, ?, ?, ?, ?, ?, ?) |
| 446 | """, |
| 447 | ( |
| 448 | challenge_id, |
| 449 | current["id"], |
| 450 | cell_id, |
| 451 | payload.source, |
| 452 | payload.accuracy_m, |
| 453 | payload.speed_mps, |
| 454 | current_time, |
| 455 | ), |
| 456 | ) |
| 457 | inserted += cur.rowcount |
| 458 | return { |
| 459 | "inserted": inserted, |
| 460 | "rejected": rejected, |
| 461 | "stats": challenge_stats(conn, challenge_id), |
| 462 | } |
| 463 | |
| 464 | |
| 465 | @app.post("/api/challenges/{challenge_id}/position") |
nothing calls this directly
no test coverage detected