69 lines
2.5 KiB
Python
69 lines
2.5 KiB
Python
import uuid
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
from pydantic import BaseModel, field_validator
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from ...auth import verify_token
|
|
from ...languages import SUPPORTED_LANGUAGES, SUPPORTED_LEVELS
|
|
from ...outbound.postgres.database import get_db
|
|
from ...outbound.postgres.repositories import learnable_language_repository
|
|
|
|
router = APIRouter(prefix="/learnable_languages", tags=["api"])
|
|
|
|
|
|
class LearnableLanguageRequest(BaseModel):
|
|
source_language: str
|
|
target_language: str
|
|
proficiencies: list[str]
|
|
|
|
@field_validator("proficiencies")
|
|
@classmethod
|
|
def validate_proficiencies(cls, v: list[str]) -> list[str]:
|
|
if not (1 <= len(v) <= 2):
|
|
raise ValueError("proficiencies must contain 1 or 2 levels")
|
|
invalid = [p for p in v if p not in SUPPORTED_LEVELS]
|
|
if invalid:
|
|
raise ValueError(f"Invalid proficiency levels: {invalid}. Supported: {sorted(SUPPORTED_LEVELS)}")
|
|
return v
|
|
|
|
|
|
class LearnableLanguageResponse(BaseModel):
|
|
id: str
|
|
source_language: str
|
|
target_language: str
|
|
proficiencies: list[str]
|
|
|
|
|
|
@router.post("", response_model=LearnableLanguageResponse, status_code=200)
|
|
async def upsert_learnable_language(
|
|
request: LearnableLanguageRequest,
|
|
db: AsyncSession = Depends(get_db),
|
|
token_data: dict = Depends(verify_token),
|
|
) -> LearnableLanguageResponse:
|
|
if request.source_language not in SUPPORTED_LANGUAGES:
|
|
raise HTTPException(
|
|
status_code=400,
|
|
detail=f"Unsupported source language '{request.source_language}'. Supported: {list(SUPPORTED_LANGUAGES)}",
|
|
)
|
|
if request.target_language not in SUPPORTED_LANGUAGES:
|
|
raise HTTPException(
|
|
status_code=400,
|
|
detail=f"Unsupported target language '{request.target_language}'. Supported: {list(SUPPORTED_LANGUAGES)}",
|
|
)
|
|
if request.source_language == request.target_language:
|
|
raise HTTPException(status_code=400, detail="source_language and target_language must differ")
|
|
|
|
result = await learnable_language_repository.upsert(
|
|
db,
|
|
user_id=uuid.UUID(token_data["sub"]),
|
|
source_language=request.source_language,
|
|
target_language=request.target_language,
|
|
proficiencies=request.proficiencies,
|
|
)
|
|
return LearnableLanguageResponse(
|
|
id=result.id,
|
|
source_language=result.source_language,
|
|
target_language=result.target_language,
|
|
proficiencies=result.proficiencies,
|
|
)
|