feat: revue de code, doc CODE_REVIEW, forfaits 2026, traduction LLM, providers avec modèle
Made-with: Cursor
This commit is contained in:
100
schemas/glossary_schemas.py
Normal file
100
schemas/glossary_schemas.py
Normal file
@@ -0,0 +1,100 @@
|
||||
"""
|
||||
Pydantic schemas for glossary endpoints.
|
||||
Story 3.9: Glossaires - Endpoint CRUD
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
from uuid import UUID
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel, Field, field_validator
|
||||
|
||||
|
||||
class GlossaryTermCreate(BaseModel):
|
||||
"""Schema for creating a single term."""
|
||||
|
||||
source: str = Field(..., min_length=1, max_length=500, description="Terme source")
|
||||
target: str = Field(
|
||||
..., min_length=1, max_length=500, description="Traduction cible"
|
||||
)
|
||||
|
||||
@field_validator("source", "target")
|
||||
@classmethod
|
||||
def strip_whitespace(cls, v: str) -> str:
|
||||
return v.strip()
|
||||
|
||||
|
||||
class GlossaryTermResponse(BaseModel):
|
||||
"""Schema for term in response."""
|
||||
|
||||
id: str
|
||||
source: str
|
||||
target: str
|
||||
created_at: Optional[datetime] = None
|
||||
|
||||
model_config = {"from_attributes": True}
|
||||
|
||||
|
||||
class GlossaryCreate(BaseModel):
|
||||
"""Schema for creating a glossary."""
|
||||
|
||||
name: str = Field(..., min_length=1, max_length=255, description="Nom du glossaire")
|
||||
terms: list[GlossaryTermCreate] = Field(
|
||||
default_factory=list, description="Liste des termes"
|
||||
)
|
||||
|
||||
@field_validator("name")
|
||||
@classmethod
|
||||
def strip_name(cls, v: str) -> str:
|
||||
return v.strip()
|
||||
|
||||
|
||||
class GlossaryUpdate(BaseModel):
|
||||
"""Schema for updating a glossary (all fields optional)."""
|
||||
|
||||
name: Optional[str] = Field(None, min_length=1, max_length=255)
|
||||
terms: Optional[list[GlossaryTermCreate]] = Field(None)
|
||||
|
||||
@field_validator("name")
|
||||
@classmethod
|
||||
def strip_name(cls, v: Optional[str]) -> Optional[str]:
|
||||
return v.strip() if v else None
|
||||
|
||||
|
||||
class GlossaryResponse(BaseModel):
|
||||
"""Schema for glossary in response (with full terms)."""
|
||||
|
||||
id: str
|
||||
name: str
|
||||
terms: list[GlossaryTermResponse] = []
|
||||
created_at: Optional[datetime] = None
|
||||
updated_at: Optional[datetime] = None
|
||||
|
||||
model_config = {"from_attributes": True}
|
||||
|
||||
|
||||
class GlossaryListItem(BaseModel):
|
||||
"""Schema for glossary in list (without full terms)."""
|
||||
|
||||
id: str
|
||||
name: str
|
||||
terms_count: int = Field(
|
||||
default=0, description="Nombre de termes dans le glossaire"
|
||||
)
|
||||
created_at: Optional[datetime] = None
|
||||
|
||||
model_config = {"from_attributes": True}
|
||||
|
||||
|
||||
class GlossaryListResponse(BaseModel):
|
||||
"""Schema for glossaries list response."""
|
||||
|
||||
data: list[GlossaryListItem] = []
|
||||
meta: dict = Field(default_factory=dict)
|
||||
|
||||
|
||||
class GlossaryDetailResponse(BaseModel):
|
||||
"""Schema for single glossary response."""
|
||||
|
||||
data: GlossaryResponse
|
||||
meta: dict = Field(default_factory=dict)
|
||||
Reference in New Issue
Block a user