Skip to content

Commit da97a2b

Browse files
committed
fix: review findings -- timezone safety, cache empty list bug, return type annotations
1. indexing.py: naive datetime comparison could TypeError when expires_at has no tzinfo. Now normalizes to UTC before comparing. Added TypeError to except clause as safety net. 2. search.py: 'if cached_results' treated empty list [] as cache miss, causing re-search. Changed to 'if cached_results is not None'. 3. Added return type annotations (-> dict) to all 8 playground endpoint functions per CLAUDE.md. Skipped: X-Forwarded-For trust (always behind Railway proxy), load_demo_repos sync (runs once at startup), Redis pre-check (redundant, outer except handles), create_session error (exception propagates, response never sent), _resolve_repo_id sync (rare fallback path). 289 tests pass.
1 parent 41f3428 commit da97a2b

4 files changed

Lines changed: 13 additions & 10 deletions

File tree

backend/routes/playground/indexing.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ async def start_anonymous_indexing(
4444
req: Request,
4545
response: Response,
4646
background_tasks: BackgroundTasks,
47-
):
47+
) -> dict:
4848
"""Start indexing a public GitHub repository for anonymous users."""
4949
start_time = time.time()
5050
limiter = get_limiter()
@@ -69,8 +69,11 @@ async def start_anonymous_indexing(
6969
if expires_at_str:
7070
try:
7171
expires_at = datetime.fromisoformat(expires_at_str.replace("Z", "+00:00"))
72+
# Ensure timezone-aware comparison
73+
if expires_at.tzinfo is None:
74+
expires_at = expires_at.replace(tzinfo=timezone.utc)
7275
is_expired = datetime.now(timezone.utc) > expires_at
73-
except (ValueError, AttributeError):
76+
except (ValueError, AttributeError, TypeError):
7477
is_expired = True
7578

7679
if not is_expired:
@@ -189,7 +192,7 @@ async def start_anonymous_indexing(
189192

190193

191194
@router.get("/index/{job_id}")
192-
async def get_indexing_status(job_id: str, req: Request):
195+
async def get_indexing_status(job_id: str, req: Request) -> dict:
193196
"""Check the status of an anonymous indexing job."""
194197
if not job_id or not job_id.startswith("idx_"):
195198
raise HTTPException(status_code=400, detail={

backend/routes/playground/search.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ async def playground_search(
111111
request: PlaygroundSearchRequest,
112112
req: Request,
113113
response: Response,
114-
):
114+
) -> dict:
115115
"""Public playground search - rate limited by session/IP."""
116116
session_token = get_session_token(req)
117117
client_ip = get_client_ip(req)
@@ -145,7 +145,7 @@ async def playground_search(
145145
cache_key = f"{sanitized_query}:v3={request.use_v3}:tests={request.include_tests}"
146146

147147
cached_results = cache.get_search_results(cache_key, repo_id)
148-
if cached_results:
148+
if cached_results is not None:
149149
return {
150150
"results": cached_results, "count": len(cached_results),
151151
"cached": True, "remaining_searches": limit_result.remaining,
@@ -200,7 +200,7 @@ async def playground_search(
200200

201201

202202
@router.get("/repos")
203-
async def list_playground_repos():
203+
async def list_playground_repos() -> dict:
204204
"""List available demo repositories."""
205205
return {
206206
"repos": [
@@ -212,7 +212,7 @@ async def list_playground_repos():
212212

213213

214214
@router.get("/stats")
215-
async def get_playground_stats():
215+
async def get_playground_stats() -> dict:
216216
"""Get playground usage stats (for monitoring/debugging)."""
217217
limiter = get_limiter()
218218
return limiter.get_usage_stats()

backend/routes/playground/session.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212

1313
@router.get("/limits")
14-
async def get_playground_limits(req: Request):
14+
async def get_playground_limits(req: Request) -> dict:
1515
"""
1616
Get current rate limit status for this user.
1717
@@ -32,7 +32,7 @@ async def get_playground_limits(req: Request):
3232

3333

3434
@router.get("/session")
35-
async def get_session_info(req: Request, response: Response):
35+
async def get_session_info(req: Request, response: Response) -> dict:
3636
"""
3737
Get current session state including indexed repo info.
3838

backend/routes/playground/validation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ async def count_code_files(
115115

116116

117117
@router.post("/validate-repo")
118-
async def validate_github_repo(request: ValidateRepoRequest, req: Request):
118+
async def validate_github_repo(request: ValidateRepoRequest, req: Request) -> dict:
119119
"""Validate a GitHub repository URL for anonymous indexing."""
120120
start_time = time.time()
121121

0 commit comments

Comments
 (0)