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 alembic/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
# Import your Base and all models
from app.db.database import Base
from app.models.user import User # noqa: F401 - Import to register with Base
from app.models.global_preference import GlobalPreference # noqa: F401
from app.models.route_preference import RoutePreference # noqa: F401


# this is the Alembic Config object, which provides
Expand Down
76 changes: 76 additions & 0 deletions alembic/versions/8f2fc156b3bb_.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"""

Revision ID: 8f2fc156b3bb
Revises: ecd62863c9d0
Create Date: 2025-11-13 14:11:13.445064

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision: str = '8f2fc156b3bb'
down_revision: Union[str, Sequence[str], None] = 'ecd62863c9d0'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('global_preferences',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('user_id', sa.Integer(), nullable=False),
sa.Column('prompt', sa.String(), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_global_preferences_id'), 'global_preferences', ['id'], unique=False)
op.create_index(op.f('ix_global_preferences_user_id'), 'global_preferences', ['user_id'], unique=False)
op.create_table('route_preferences',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('user_id', sa.Integer(), nullable=False),
sa.Column('prompt', sa.String(), nullable=False),
sa.Column('from_latitude', sa.Float(), nullable=False),
sa.Column('from_longitude', sa.Float(), nullable=False),
sa.Column('to_latitude', sa.Float(), nullable=False),
sa.Column('to_longitude', sa.Float(), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_route_preferences_id'), 'route_preferences', ['id'], unique=False)
op.create_index(op.f('ix_route_preferences_user_id'), 'route_preferences', ['user_id'], unique=False)
op.drop_index(op.f('ix_preference_id'), table_name='preference')
op.drop_index(op.f('ix_preference_user_id'), table_name='preference')
op.drop_table('preference')
# ### end Alembic commands ###


def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('preference',
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
sa.Column('user_id', sa.INTEGER(), autoincrement=False, nullable=False),
sa.Column('prompt', sa.VARCHAR(), autoincrement=False, nullable=False),
sa.Column('created_at', postgresql.TIMESTAMP(timezone=True), server_default=sa.text('now()'), autoincrement=False, nullable=True),
sa.Column('updated_at', postgresql.TIMESTAMP(timezone=True), autoincrement=False, nullable=True),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], name=op.f('preference_user_id_fkey')),
sa.PrimaryKeyConstraint('id', name=op.f('preference_pkey'))
)
op.create_index(op.f('ix_preference_user_id'), 'preference', ['user_id'], unique=False)
op.create_index(op.f('ix_preference_id'), 'preference', ['id'], unique=False)
op.drop_index(op.f('ix_route_preferences_user_id'), table_name='route_preferences')
op.drop_index(op.f('ix_route_preferences_id'), table_name='route_preferences')
op.drop_table('route_preferences')
op.drop_index(op.f('ix_global_preferences_user_id'), table_name='global_preferences')
op.drop_index(op.f('ix_global_preferences_id'), table_name='global_preferences')
op.drop_table('global_preferences')
# ### end Alembic commands ###
25 changes: 14 additions & 11 deletions app/api/v1/endpoints/preferences.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,40 @@

from app.db.database import get_db
from app.models.user import User
from app.schemas.preference import PreferenceCreate, PreferenceResponse
from app.schemas.global_preference import (
GlobalPreferenceCreate,
GlobalPreferenceResponse,
)
from app.services.auth_service import auth_service
from app.services.preference_service import preference_service
from app.services.global_preference_service import global_preference_service

router = APIRouter()


@router.get("", response_model=List[PreferenceResponse])
@router.get("", response_model=List[GlobalPreferenceResponse])
async def get_user_preferences(
current_user: User = Depends(auth_service.get_current_user),
db: Session = Depends(get_db),
) -> Any:
"""
Get all preferences for the authenticated user.
Get all global preferences for the authenticated user.
"""
preferences = preference_service.get_user_preferences(
preferences = global_preference_service.get_user_preferences(
db, int(current_user.id)
)
return preferences


@router.post("", response_model=PreferenceResponse, status_code=201)
@router.post("", response_model=GlobalPreferenceResponse, status_code=201)
async def create_preference(
preference_in: PreferenceCreate,
preference_in: GlobalPreferenceCreate,
current_user: User = Depends(auth_service.get_current_user),
db: Session = Depends(get_db),
) -> Any:
"""
Create a new preference for the authenticated user.
Create a new global preference for the authenticated user.
"""
preference = preference_service.create_preference(
preference = global_preference_service.create_preference(
db, int(current_user.id), preference_in
)
return preference
Expand All @@ -48,8 +51,8 @@ async def delete_preference(
db: Session = Depends(get_db),
) -> None:
"""
Delete a preference for the authenticated user.
Delete a global preference for the authenticated user.
"""
preference_service.delete_preference(
global_preference_service.delete_preference(
db, int(current_user.id), preference_id
)
6 changes: 3 additions & 3 deletions app/api/v1/endpoints/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from app.schemas.routes import RouteSearchRequest, RouteSearchResponse
from app.services.ai_agents_service import ai_agents_service
from app.services.auth_service import auth_service
from app.services.preference_service import preference_service
from app.services.global_preference_service import global_preference_service
from app.services.routing_service import (
RoutingAPIError,
RoutingDataError,
Expand Down Expand Up @@ -76,9 +76,9 @@ async def search_routes(
for pref in request.preferences:
user_preferences.append({"prompt": pref})

# 2. Add stored preferences from authenticated user
# 2. Add stored global preferences from authenticated user
try:
stored_prefs = preference_service.get_user_preferences(
stored_prefs = global_preference_service.get_user_preferences(
db, int(current_user.id)
)
for pref in stored_prefs:
Expand Down
4 changes: 4 additions & 0 deletions app/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from app.models.global_preference import GlobalPreference
from app.models.route_preference import RoutePreference

__all__ = ["GlobalPreference", "RoutePreference"]
6 changes: 3 additions & 3 deletions app/models/preference.py → app/models/global_preference.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from app.db.database import Base


class Preference(Base):
__tablename__ = "preference"
class GlobalPreference(Base):
__tablename__ = "global_preferences"

id = Column(Integer, primary_key=True, index=True)
user_id = Column(
Expand All @@ -16,7 +16,7 @@ class Preference(Base):
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())

user = relationship("User", back_populates="preferences")
user = relationship("User", back_populates="global_preferences")

def __init__(self, user_id, prompt):
self.user_id = user_id
Expand Down
39 changes: 39 additions & 0 deletions app/models/route_preference.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from sqlalchemy import Column, DateTime, Float, ForeignKey, Integer, String
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func

from app.db.database import Base


class RoutePreference(Base):
__tablename__ = "route_preferences"

id = Column(Integer, primary_key=True, index=True)
user_id = Column(
Integer, ForeignKey("users.id"), nullable=False, index=True
)
prompt = Column(String, nullable=False)
from_latitude = Column(Float, nullable=False)
from_longitude = Column(Float, nullable=False)
to_latitude = Column(Float, nullable=False)
to_longitude = Column(Float, nullable=False)
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())

user = relationship("User", back_populates="route_preferences")

def __init__(
self,
user_id,
prompt,
from_latitude,
from_longitude,
to_latitude,
to_longitude,
):
self.user_id = user_id
self.prompt = prompt
self.from_latitude = from_latitude
self.from_longitude = from_longitude
self.to_latitude = to_latitude
self.to_longitude = to_longitude
8 changes: 5 additions & 3 deletions app/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from sqlalchemy.sql import func

from app.db.database import Base
from app.models.preference import Preference


class User(Base):
Expand All @@ -15,8 +14,11 @@ class User(Base):
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())

preferences = relationship(
Preference, back_populates="user", cascade="all, delete-orphan"
global_preferences = relationship(
"GlobalPreference", back_populates="user", cascade="all, delete-orphan"
)
route_preferences = relationship(
"RoutePreference", back_populates="user", cascade="all, delete-orphan"
)

def __init__(self, username, hashed_password):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
from pydantic import BaseModel, ConfigDict


class PreferenceBase(BaseModel):
class GlobalPreferenceBase(BaseModel):
prompt: str


class PreferenceCreate(PreferenceBase):
class GlobalPreferenceCreate(GlobalPreferenceBase):
pass


class PreferenceResponse(PreferenceBase):
class GlobalPreferenceResponse(GlobalPreferenceBase):
id: int
created_at: datetime
updated_at: Optional[datetime] = None
Expand Down
24 changes: 24 additions & 0 deletions app/schemas/route_preference.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from datetime import datetime
from typing import Optional

from pydantic import BaseModel, ConfigDict, Field


class RoutePreferenceBase(BaseModel):
prompt: str
from_latitude: float = Field(..., ge=-90, le=90)
from_longitude: float = Field(..., ge=-180, le=180)
to_latitude: float = Field(..., ge=-90, le=90)
to_longitude: float = Field(..., ge=-180, le=180)


class RoutePreferenceCreate(RoutePreferenceBase):
pass


class RoutePreferenceResponse(RoutePreferenceBase):
id: int
created_at: datetime
updated_at: Optional[datetime] = None

model_config = ConfigDict(from_attributes=True)
Loading