Skip to content
Merged
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
2 changes: 2 additions & 0 deletions example.env
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ POSTGRES_TEST_DB=cars_test_db
DATABASE_HOST_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432"
DATABASE_URL="${DATABASE_HOST_URL}/${POSTGRES_DB}?sslmode=disable"

GEOAPIFY_API_KEY=your_geoapify_key

# Super token for trusted services. Send it as Authorization: Bearer ${API_TOKEN}.
#API_TOKEN=change-me

Expand Down
42 changes: 38 additions & 4 deletions src/routers/routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import requests
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy import func, or_
from sqlalchemy import func, or_, text
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session

Expand Down Expand Up @@ -44,6 +44,41 @@
# Сначала зоны грубо сортируются по прямому расстоянию, потом лучшие идут в API.
MAX_MATRIX_TARGETS = 200

PUBLIC_ROUTING_USER_EMAIL = "public-routing@parktrack.local"


def _get_public_routing_user_id(db: Session) -> int:
"""
/routing/new теперь публичный, но routes.user_id в БД NOT NULL.
Поэтому сохраняем публичные маршруты на технического пользователя.
"""
result = db.execute(
text(
"""
INSERT INTO users (
full_name,
email,
hashed_password,
global_role,
is_active
)
VALUES (
'Public Routing User',
:email,
'disabled-public-routing-user',
CAST('user' AS global_roles),
TRUE
)
ON CONFLICT (email)
DO UPDATE SET email = EXCLUDED.email
RETURNING user_id
"""
),
{"email": PUBLIC_ROUTING_USER_EMAIL},
)

return int(result.scalar_one())


# ---------------------------------------------------------------------------
# Внутренние типы
Expand Down Expand Up @@ -647,7 +682,6 @@ def _selected_candidate_or_422(
@router.post("/search", response_model=SearchRoutingResponse)
def search_routing(
body: SearchRoutingRequest,
current_user: Annotated[User, require("routing.create")],
db: Annotated[Session, Depends(get_db)],
):
try:
Expand Down Expand Up @@ -687,7 +721,6 @@ def search_routing(
@router.post("/new", status_code=status.HTTP_201_CREATED, response_model=RouteResponse)
def create_route(
body: CreateRouteRequest,
current_user: Annotated[User, require("routing.create")],
db: Annotated[Session, Depends(get_db)],
):
if body.selected_zone_id is not None:
Expand Down Expand Up @@ -730,9 +763,10 @@ def create_route(

best = result.candidates[0]
now = datetime.now(timezone.utc)
public_user_id = _get_public_routing_user_id(db)

route = Route(
user_id=current_user.user_id,
user_id=public_user_id,
mode=RouteMode(body.mode),
provider=GEOAPIFY_PROVIDER_NAME,
origin_latitude=body.origin.latitude,
Expand Down
Loading