107 lines
2.9 KiB
Python
107 lines
2.9 KiB
Python
|
|
from uuid import UUID
|
||
|
|
|
||
|
|
from fastapi import APIRouter, Depends
|
||
|
|
from sqlalchemy import select
|
||
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||
|
|
|
||
|
|
from app.core.auth import AuthUser, require_auth
|
||
|
|
from app.core.database import get_session
|
||
|
|
from app.models.user import User
|
||
|
|
from app.schemas.base import CamelModel
|
||
|
|
|
||
|
|
router = APIRouter()
|
||
|
|
|
||
|
|
|
||
|
|
class UserResponse(CamelModel):
|
||
|
|
id: UUID
|
||
|
|
email: str
|
||
|
|
display_name: str | None = None
|
||
|
|
|
||
|
|
|
||
|
|
@router.post("/me", response_model=UserResponse)
|
||
|
|
async def sync_current_user(
|
||
|
|
session: AsyncSession = Depends(get_session),
|
||
|
|
auth_user: AuthUser = Depends(require_auth),
|
||
|
|
):
|
||
|
|
"""
|
||
|
|
Sync the current authenticated user from Supabase to local DB.
|
||
|
|
Creates user on first login, updates email if changed.
|
||
|
|
"""
|
||
|
|
user_id = UUID(auth_user.id)
|
||
|
|
|
||
|
|
result = await session.execute(select(User).where(User.id == user_id))
|
||
|
|
user = result.scalar_one_or_none()
|
||
|
|
|
||
|
|
if user is None:
|
||
|
|
# First login - create user record
|
||
|
|
user = User(
|
||
|
|
id=user_id,
|
||
|
|
email=auth_user.email or "",
|
||
|
|
display_name=None,
|
||
|
|
)
|
||
|
|
session.add(user)
|
||
|
|
elif auth_user.email and user.email != auth_user.email:
|
||
|
|
# Email changed in Supabase - update local record
|
||
|
|
user.email = auth_user.email
|
||
|
|
|
||
|
|
await session.commit()
|
||
|
|
await session.refresh(user)
|
||
|
|
return user
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/me", response_model=UserResponse)
|
||
|
|
async def get_current_user(
|
||
|
|
session: AsyncSession = Depends(get_session),
|
||
|
|
auth_user: AuthUser = Depends(require_auth),
|
||
|
|
):
|
||
|
|
"""Get the current authenticated user's profile."""
|
||
|
|
user_id = UUID(auth_user.id)
|
||
|
|
|
||
|
|
result = await session.execute(select(User).where(User.id == user_id))
|
||
|
|
user = result.scalar_one_or_none()
|
||
|
|
|
||
|
|
if user is None:
|
||
|
|
# Auto-create if not exists (shouldn't happen if /me POST is called on login)
|
||
|
|
user = User(
|
||
|
|
id=user_id,
|
||
|
|
email=auth_user.email or "",
|
||
|
|
display_name=None,
|
||
|
|
)
|
||
|
|
session.add(user)
|
||
|
|
await session.commit()
|
||
|
|
await session.refresh(user)
|
||
|
|
|
||
|
|
return user
|
||
|
|
|
||
|
|
|
||
|
|
class UserUpdateRequest(CamelModel):
|
||
|
|
display_name: str | None = None
|
||
|
|
|
||
|
|
|
||
|
|
@router.patch("/me", response_model=UserResponse)
|
||
|
|
async def update_current_user(
|
||
|
|
data: UserUpdateRequest,
|
||
|
|
session: AsyncSession = Depends(get_session),
|
||
|
|
auth_user: AuthUser = Depends(require_auth),
|
||
|
|
):
|
||
|
|
"""Update the current user's profile (display name)."""
|
||
|
|
user_id = UUID(auth_user.id)
|
||
|
|
|
||
|
|
result = await session.execute(select(User).where(User.id == user_id))
|
||
|
|
user = result.scalar_one_or_none()
|
||
|
|
|
||
|
|
if user is None:
|
||
|
|
user = User(
|
||
|
|
id=user_id,
|
||
|
|
email=auth_user.email or "",
|
||
|
|
display_name=data.display_name,
|
||
|
|
)
|
||
|
|
session.add(user)
|
||
|
|
else:
|
||
|
|
if data.display_name is not None:
|
||
|
|
user.display_name = data.display_name
|
||
|
|
|
||
|
|
await session.commit()
|
||
|
|
await session.refresh(user)
|
||
|
|
return user
|