- libs/ai-services: new POST /neighborhood/score router computing weighted 6-axis livability score from per-category POI counts; algorithm versioned for future iteration (sigmoid curves, percentile thresholds). - apps/api: HttpNeighborhoodScoreService proxies to Python first, falls back to PrismaNeighborhoodScoreService when AI service unavailable. Mirrors the HttpAVMService pattern. Existing GET /analytics/neighborhoods/:district/score endpoint and CQRS handler now flow through the proxy. - AnalyticsModule binds Http variant by default, retains Prisma variant as injectable fallback. - Tests: 5 pytest cases for Python heuristic, 4 vitest cases for HTTP proxy fallback behaviour. Co-Authored-By: Paperclip <noreply@paperclip.ing>
13 lines
526 B
Python
13 lines
526 B
Python
from fastapi import APIRouter
|
|
|
|
from app.models.neighborhood import NeighborhoodScoreRequest, NeighborhoodScoreResponse
|
|
from app.services.neighborhood_service import neighborhood_score_service
|
|
|
|
router = APIRouter(prefix="/neighborhood", tags=["Neighborhood"])
|
|
|
|
|
|
@router.post("/score", response_model=NeighborhoodScoreResponse)
|
|
def score(req: NeighborhoodScoreRequest) -> NeighborhoodScoreResponse:
|
|
"""Compute weighted 0-100 livability score from per-category POI counts."""
|
|
return neighborhood_score_service.score(req)
|