Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,10 @@
## 2025-02-27 - UploadFile Validation Blocking
**Learning:** `UploadFile` validation using `python-magic` and file seeking is synchronous and CPU/IO bound. In FastAPI async endpoints, this blocks the event loop.
**Action:** Wrap file validation logic in `run_in_threadpool` and await it.
## 2024-07-13 - Scratchpad Files and Test Runners
**Learning:** Temporary scratchpad files (like `test_spatial.py` or `test_perf.py`) created in the repository root will be automatically discovered by test runners like `pytest` because they start with `test_`. If these files contain top-level execution code (like creating arrays of 100k items), they will block test suites and pollute standard output.
**Action:** Always clean up temporary files immediately after use (e.g. `rm test_perf.py`) before running project test suites or requesting code review.

## 2024-07-13 - Haversine Distance Optimization
**Learning:** Calculating `haversine_distance` for every point in a large dataset is O(N) and extremely slow due to repeated trigonometric functions (`math.sin`, `math.cos`, etc.).
**Action:** For spatial radius queries, always apply a cheap bounding box pre-filter first (e.g., `get_bounding_box` with a 5% epsilon for safety). This reduces the complexity to O(N) fast arithmetic checks + O(K) slow trigonometric functions, where K << N.
12 changes: 12 additions & 0 deletions backend/spatial_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,22 @@ def find_nearby_issues(
"""
nearby_issues = []

# ⚡ Bolt Optimization: Use bounding box pre-filter with 5% epsilon to
# skip expensive haversine distance calculations for issues far away.
# This reduces time complexity from O(N) expensive trig functions to
# O(N) simple bounds checks + O(K) trig functions (where K << N).
min_lat, max_lat, min_lon, max_lon = get_bounding_box(
target_lat, target_lon, radius_meters * 1.05
)

for issue in issues:
if issue.latitude is None or issue.longitude is None:
continue

# Fast pre-filter check
if not (min_lat <= issue.latitude <= max_lat and min_lon <= issue.longitude <= max_lon):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The bounding-box pre-filter doesn't handle antimeridian wrapping (±180° longitude). If the target is near the Pacific antimeridian (longitude ~±180°) and the 5% epsilon pushes the bounding box past 180°, valid nearby issues on the opposite side of the antimeridian will fail the bounds check and be silently missed. For typical city-scale searches (default 50m radius) the offset is negligible, but this becomes a correctness risk at larger radii or near the dateline. Consider normalizing the bounding box coordinates to [-180, 180] and splitting the check into two intervals when the box crosses the antimeridian.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At backend/spatial_utils.py, line 92:

<comment>The bounding-box pre-filter doesn't handle antimeridian wrapping (±180° longitude). If the target is near the Pacific antimeridian (longitude ~±180°) and the 5% epsilon pushes the bounding box past 180°, valid nearby issues on the opposite side of the antimeridian will fail the bounds check and be silently missed. For typical city-scale searches (default 50m radius) the offset is negligible, but this becomes a correctness risk at larger radii or near the dateline. Consider normalizing the bounding box coordinates to [-180, 180] and splitting the check into two intervals when the box crosses the antimeridian.</comment>

<file context>
@@ -76,10 +76,22 @@ def find_nearby_issues(
             continue
 
+        # Fast pre-filter check
+        if not (min_lat <= issue.latitude <= max_lat and min_lon <= issue.longitude <= max_lon):
+            continue
+
</file context>

continue

distance = haversine_distance(
target_lat, target_lon,
issue.latitude, issue.longitude
Expand Down
Loading