Add FastAPI backend with PostGIS-backed nearby search
FastAPI service backed by PostgreSQL+PostGIS: cities/places/place_content schema (normalized per-language, per-length content for easy future re-ingestion), Alembic migration, an iterative-radius-expansion nearby search endpoint, a name-search fallback for denied-location flows, and a YAML seed loader CLI. Verified end-to-end against a live Docker Postgres+PostGIS instance (migration, city seed, place/content CRUD, and nearby radius expansion all confirmed working via curl). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
2acc5dfa2e
commit
d2ab424e7e
43 changed files with 1058 additions and 0 deletions
0
backend/tests/__init__.py
Normal file
0
backend/tests/__init__.py
Normal file
11
backend/tests/test_health.py
Normal file
11
backend/tests/test_health.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
from fastapi.testclient import TestClient
|
||||
|
||||
from app.main import app
|
||||
|
||||
client = TestClient(app)
|
||||
|
||||
|
||||
def test_health() -> None:
|
||||
response = client.get("/api/v1/health")
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {"status": "ok"}
|
||||
25
backend/tests/test_nearby.py
Normal file
25
backend/tests/test_nearby.py
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
"""Integration test — assumes the DB has been migrated and seeded
|
||||
(see README: alembic upgrade head + seed_loader for all 3 place files)
|
||||
before running `docker compose exec api pytest`.
|
||||
"""
|
||||
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from app.main import app
|
||||
|
||||
client = TestClient(app)
|
||||
|
||||
|
||||
def test_nearby_red_square_returns_at_least_five_places() -> None:
|
||||
response = client.get(
|
||||
"/api/v1/nearby",
|
||||
params={"lat": 55.7539, "lon": 37.6208, "city_slug": "moscow", "lang": "ru", "length": "short"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
body = response.json()
|
||||
assert body["count"] >= 5
|
||||
assert len(body["places"]) == body["count"]
|
||||
|
||||
distances = [p["distance_m"] for p in body["places"]]
|
||||
assert distances == sorted(distances)
|
||||
Loading…
Add table
Add a link
Reference in a new issue