118 lines
3.4 KiB
Python
118 lines
3.4 KiB
Python
import uuid
|
|
|
|
from fastapi import APIRouter, Depends
|
|
from pydantic import BaseModel
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from ...auth import verify_token
|
|
from ...config import settings
|
|
from ...domain.services.account_service import AccountService
|
|
from ...languages import SUPPORTED_LANGUAGES, SUPPORTED_LEVELS, LEVEL_ORDER, LEVEL_DESCRIPTIONS
|
|
from ...outbound.postgres.database import get_db
|
|
from ...outbound.postgres.repositories import email_verification_token_repository
|
|
|
|
router = APIRouter(prefix="/account", tags=["bff"])
|
|
|
|
|
|
class LanguagePairOption(BaseModel):
|
|
value: str
|
|
label: str
|
|
description: str
|
|
|
|
|
|
class ProficiencyOption(BaseModel):
|
|
value: str
|
|
label: str
|
|
description: str
|
|
|
|
|
|
class OnboardingResponse(BaseModel):
|
|
_todo_remove_me_validate_account_link: str | None = None
|
|
language_pairs: list[LanguagePairOption]
|
|
proficiencies: list[ProficiencyOption]
|
|
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
def _build_language_pairs() -> list[LanguagePairOption]:
|
|
pairs = []
|
|
for source_code, source_name in SUPPORTED_LANGUAGES.items():
|
|
for target_code, target_name in SUPPORTED_LANGUAGES.items():
|
|
if source_code == target_code:
|
|
continue
|
|
pairs.append(
|
|
LanguagePairOption(
|
|
value=f"{source_code},{target_code}",
|
|
label=f"{source_name} to {target_name}",
|
|
description=f"You are a {source_name} speaker, learning {target_name}",
|
|
)
|
|
)
|
|
return pairs
|
|
|
|
|
|
def _build_proficiencies() -> list[ProficiencyOption]:
|
|
return [
|
|
ProficiencyOption(
|
|
value=level,
|
|
label=level,
|
|
description=LEVEL_DESCRIPTIONS[level],
|
|
)
|
|
for level in LEVEL_ORDER
|
|
if level in SUPPORTED_LEVELS
|
|
]
|
|
|
|
|
|
class AccountLanguagePair(BaseModel):
|
|
id: str
|
|
source_language: str
|
|
target_language: str
|
|
proficiencies: list[str]
|
|
|
|
|
|
class AccountResponse(BaseModel):
|
|
email: str
|
|
human_name: str | None
|
|
language_pairs: list[AccountLanguagePair]
|
|
|
|
|
|
@router.get("", response_model=AccountResponse)
|
|
async def get_account(
|
|
db: AsyncSession = Depends(get_db),
|
|
token_data: dict = Depends(verify_token),
|
|
) -> AccountResponse:
|
|
user_id = uuid.UUID(token_data["sub"])
|
|
account = await AccountService(db).get_account(user_id)
|
|
return AccountResponse(
|
|
email=account.email,
|
|
human_name=account.human_name,
|
|
language_pairs=[
|
|
AccountLanguagePair(
|
|
id=lang.id,
|
|
source_language=lang.source_language,
|
|
target_language=lang.target_language,
|
|
proficiencies=lang.proficiencies,
|
|
)
|
|
for lang in account.learnable_languages
|
|
],
|
|
)
|
|
|
|
|
|
@router.get("/onboarding", response_model=OnboardingResponse)
|
|
async def get_onboarding(
|
|
db: AsyncSession = Depends(get_db),
|
|
token_data: dict = Depends(verify_token),
|
|
) -> OnboardingResponse:
|
|
user_id = uuid.UUID(token_data["sub"])
|
|
|
|
active_token = await email_verification_token_repository.get_active_for_user(db, user_id)
|
|
link = (
|
|
f"{settings.api_base_url}/api/auth/verify-email?token={active_token.token}"
|
|
if active_token
|
|
else None
|
|
)
|
|
|
|
return OnboardingResponse(
|
|
**{"_todo_remove_me_validate_account_link": link},
|
|
language_pairs=_build_language_pairs(),
|
|
proficiencies=_build_proficiencies(),
|
|
)
|