Files
orion/app/modules/tenancy/routes/api/user_account.py
Samir Boulahtit b3224ba13d fix(loyalty): replace broad exception handlers with specific types and rename onboarding service
- Replace `except Exception` with specific exception types in
  google_wallet_service.py (requests.RequestException, ValueError, etc.)
  and apple_wallet_service.py (httpx.HTTPError, OSError, ssl.SSLError)
- Rename loyalty_onboarding.py -> loyalty_onboarding_service.py to
  match NAM-002 naming convention (+ test file + imports)
- Add PasswordChangeResponse Pydantic model to user_account API,
  removing raw dict return and noqa suppression

Resolves 12 EXC-003 + 1 NAM-002 architecture warnings in loyalty module.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:09:23 +01:00

79 lines
2.5 KiB
Python

# app/modules/tenancy/routes/api/user_account.py
"""
Self-service account API routes.
Provides GET/PUT /account/me and PUT /account/me/password
for admin, store, and merchant frontends.
"""
import logging
from collections.abc import Callable
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from app.core.database import get_db
from app.modules.tenancy.schemas.auth import UserContext
from app.modules.tenancy.schemas.user_account import (
PasswordChangeResponse,
UserAccountResponse,
UserAccountUpdate,
UserPasswordChange,
)
from app.modules.tenancy.services.user_account_service import user_account_service
logger = logging.getLogger(__name__)
def create_account_router(auth_dependency: Callable) -> APIRouter:
"""Create an account/me router bound to the given auth dependency."""
router = APIRouter(prefix="/account/me")
@router.get("", response_model=UserAccountResponse)
async def get_my_account(
current_user: UserContext = Depends(auth_dependency),
db: Session = Depends(get_db),
):
"""Get the logged-in user's account info."""
return user_account_service.get_account(db, current_user.id)
@router.put("", response_model=UserAccountResponse)
async def update_my_account(
update_data: UserAccountUpdate,
current_user: UserContext = Depends(auth_dependency),
db: Session = Depends(get_db),
):
"""Update the logged-in user's account info."""
result = user_account_service.update_account(
db, current_user.id, update_data.model_dump(exclude_unset=True)
)
db.commit()
return result
@router.put("/password", response_model=PasswordChangeResponse)
async def change_my_password(
password_data: UserPasswordChange,
current_user: UserContext = Depends(auth_dependency),
db: Session = Depends(get_db),
):
"""Change the logged-in user's password."""
user_account_service.change_password(
db, current_user.id, password_data.model_dump()
)
db.commit()
return PasswordChangeResponse(message="Password changed successfully")
return router
# Create routers for each frontend
from app.api.deps import (
get_current_admin_api,
get_current_merchant_api,
get_current_store_api,
)
admin_account_router = create_account_router(get_current_admin_api)
store_account_router = create_account_router(get_current_store_api)
merchant_account_router = create_account_router(get_current_merchant_api)