Initial commit of mtgonline project
This commit is contained in:
@@ -0,0 +1,232 @@
|
||||
"""
|
||||
Pydantic schemas for request/response validation.
|
||||
|
||||
Provides typed data structures for API endpoints.
|
||||
"""
|
||||
from pydantic import BaseModel, EmailStr, Field
|
||||
from typing import Optional, List
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
# ===== Authentication Schemas =====
|
||||
|
||||
class LoginRequest(BaseModel):
|
||||
"""Login request payload."""
|
||||
username: str = Field(..., min_length=3, max_length=64)
|
||||
password: str = Field(..., min_length=6, max_length=128)
|
||||
|
||||
|
||||
class LoginResponse(BaseModel):
|
||||
"""Login response payload."""
|
||||
access_token: str
|
||||
refresh_token: str
|
||||
token_type: str = "bearer"
|
||||
user: dict
|
||||
|
||||
|
||||
class RefreshTokenRequest(BaseModel):
|
||||
"""Refresh token request."""
|
||||
refresh_token: str
|
||||
|
||||
|
||||
class TokenResponse(BaseModel):
|
||||
"""Token response."""
|
||||
access_token: str
|
||||
token_type: str = "bearer"
|
||||
|
||||
|
||||
# ===== User Schemas =====
|
||||
|
||||
class UserBase(BaseModel):
|
||||
"""User base fields."""
|
||||
username: str
|
||||
email: Optional[str] = None
|
||||
country: Optional[str] = Field(None, max_length=2)
|
||||
real_name: Optional[str] = None
|
||||
|
||||
|
||||
class UserCreate(UserBase):
|
||||
"""User registration fields."""
|
||||
password: str = Field(..., min_length=8)
|
||||
|
||||
class Config:
|
||||
json_schema_extra = {
|
||||
"example": {
|
||||
"username": "player123",
|
||||
"password": "securepassword123",
|
||||
"email": "player@example.com",
|
||||
"country": "US"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class UserUpdate(BaseModel):
|
||||
"""User update fields."""
|
||||
email: Optional[str] = None
|
||||
country: Optional[str] = None
|
||||
real_name: Optional[str] = None
|
||||
new_password: Optional[str] = Field(None, min_length=8, max_length=128)
|
||||
|
||||
|
||||
class UserResponse(BaseModel):
|
||||
"""User response payload."""
|
||||
id: int
|
||||
username: str
|
||||
email: Optional[str]
|
||||
country: Optional[str]
|
||||
real_name: Optional[str]
|
||||
privlevel: str
|
||||
vip_status: int
|
||||
is_active: bool
|
||||
is_banned: bool
|
||||
ban_reason: Optional[str]
|
||||
creation_date: datetime
|
||||
last_login: Optional[datetime]
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# ===== Deck Schemas =====
|
||||
|
||||
class DeckCreate(BaseModel):
|
||||
"""Deck creation request."""
|
||||
name: str = Field(..., min_length=1, max_length=255)
|
||||
content: str = Field(..., min_length=1)
|
||||
folder_id: Optional[int] = None
|
||||
format: str = Field("native", pattern="^(native|plain)$")
|
||||
|
||||
|
||||
class DeckUpdate(BaseModel):
|
||||
"""Deck update request."""
|
||||
name: Optional[str] = None
|
||||
content: Optional[str] = None
|
||||
folder_id: Optional[int] = None
|
||||
|
||||
|
||||
class DeckResponse(BaseModel):
|
||||
"""Deck response payload."""
|
||||
id: int
|
||||
name: str
|
||||
content: str
|
||||
format: str
|
||||
folder_id: Optional[int]
|
||||
owner_id: int
|
||||
creation_date: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
class FolderCreate(BaseModel):
|
||||
"""Folder creation request."""
|
||||
name: str = Field(..., min_length=1, max_length=255)
|
||||
parent_id: Optional[int] = None
|
||||
|
||||
|
||||
class FolderResponse(BaseModel):
|
||||
"""Folder response payload."""
|
||||
id: int
|
||||
name: str
|
||||
parent_id: Optional[int]
|
||||
owner_id: int
|
||||
creation_date: datetime
|
||||
children: List["FolderResponse"] = []
|
||||
files: List[DeckResponse] = []
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# ===== Game Schemas =====
|
||||
|
||||
class GameCreate(BaseModel):
|
||||
"""Game creation request."""
|
||||
room_id: int
|
||||
game_type: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
password: Optional[str] = None
|
||||
|
||||
|
||||
class GameResponse(BaseModel):
|
||||
"""Game response payload."""
|
||||
id: int
|
||||
room_id: int
|
||||
game_type: Optional[str]
|
||||
description: Optional[str]
|
||||
with_password: bool
|
||||
max_players: int
|
||||
player_count: int
|
||||
started: bool
|
||||
creation_date: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# ===== Room Schemas =====
|
||||
|
||||
class RoomResponse(BaseModel):
|
||||
"""Room response payload."""
|
||||
id: int
|
||||
name: str
|
||||
description: Optional[str]
|
||||
is_password_protected: bool
|
||||
game_types: List[str] = []
|
||||
player_count: int = 0
|
||||
creation_date: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# ===== Ban Schemas =====
|
||||
|
||||
class BanCreate(BaseModel):
|
||||
"""Ban creation request."""
|
||||
user_id: int
|
||||
reason: str = Field(..., min_length=1, max_length=1000)
|
||||
expiration_time: Optional[datetime] = None
|
||||
|
||||
|
||||
class BanResponse(BaseModel):
|
||||
"""Ban response payload."""
|
||||
id: int
|
||||
user_id: int
|
||||
reason: str
|
||||
moderators: Optional[str]
|
||||
expiration_time: Optional[datetime]
|
||||
active: bool
|
||||
creation_date: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
|
||||
# ===== Auth Error Responses =====
|
||||
|
||||
class ErrorResponse(BaseModel):
|
||||
"""Standard error response."""
|
||||
detail: str
|
||||
|
||||
|
||||
class ValidationErrorResponse(BaseModel):
|
||||
"""Validation error response."""
|
||||
detail: List[dict] # Pydantic validation errors
|
||||
|
||||
|
||||
# ===== Pagination Schemas =====
|
||||
|
||||
class PaginationParams(BaseModel):
|
||||
"""Common pagination parameters."""
|
||||
page: int = Field(1, ge=1)
|
||||
page_size: int = Field(50, ge=1, le=100)
|
||||
|
||||
|
||||
class PaginatedResponse(BaseModel):
|
||||
"""Generic paginated response."""
|
||||
items: List[dict]
|
||||
total: int
|
||||
page: int
|
||||
page_size: int
|
||||
total_pages: int
|
||||
Reference in New Issue
Block a user