shinkan-jinkendo/backend/models.py
Lars e1397277a7
All checks were successful
Deploy Development / deploy (push) Successful in 41s
fix: Add missing password reset models to models.py
2026-04-21 16:04:22 +02:00

233 lines
6.5 KiB
Python

"""
Pydantic Models for Shinkan Jinkendo API
Request/Response schemas for all endpoints
"""
from pydantic import BaseModel, EmailStr, Field
from typing import Optional, List
from datetime import date, time, datetime
# ============================================================================
# Auth & Profiles (von Mitai übernommen)
# ============================================================================
class LoginRequest(BaseModel):
email: EmailStr
password: str
class RegisterRequest(BaseModel):
email: EmailStr
password: str
name: Optional[str] = None
class PasswordResetRequest(BaseModel):
email: str
class PasswordResetConfirm(BaseModel):
token: str
new_password: str
class ProfileResponse(BaseModel):
id: int
email: str
name: Optional[str]
role: str
tier: str
email_verified: bool
created_at: datetime
# ============================================================================
# Clubs & Groups
# ============================================================================
class ClubCreate(BaseModel):
name: str
abbreviation: Optional[str] = None
description: Optional[str] = None
class ClubResponse(BaseModel):
id: int
name: str
abbreviation: Optional[str]
description: Optional[str]
status: str
created_at: datetime
class TrainingGroupCreate(BaseModel):
club_id: int
division_id: Optional[int] = None
name: str
focus: Optional[str] = None
level: Optional[str] = None
age_group: Optional[str] = None
weekday: Optional[str] = None
time_start: Optional[time] = None
time_end: Optional[time] = None
location: Optional[str] = None
trainer_id: Optional[int] = None
co_trainer_ids: Optional[List[int]] = []
class TrainingGroupResponse(BaseModel):
id: int
club_id: int
name: str
focus: Optional[str]
level: Optional[str]
age_group: Optional[str]
weekday: Optional[str]
time_start: Optional[time]
time_end: Optional[time]
location: Optional[str]
trainer_id: Optional[int]
status: str
created_at: datetime
# ============================================================================
# Skills & Methods
# ============================================================================
class SkillCreate(BaseModel):
name: str
category: Optional[str] = None
description: Optional[str] = None
importance: Optional[int] = Field(None, ge=1, le=5)
keywords: Optional[List[str]] = []
class SkillResponse(BaseModel):
id: int
name: str
category: Optional[str]
description: Optional[str]
importance: Optional[int]
keywords: Optional[List[str]]
status: str
created_at: datetime
class MethodCreate(BaseModel):
name: str
abbreviation: Optional[str] = None
category: Optional[str] = None
description: Optional[str] = None
typical_duration: Optional[int] = None
typical_group_size: Optional[str] = None
related_skills: Optional[List[int]] = []
keywords: Optional[List[str]] = []
class MethodResponse(BaseModel):
id: int
name: str
abbreviation: Optional[str]
category: Optional[str]
description: Optional[str]
typical_duration: Optional[int]
typical_group_size: Optional[str]
related_skills: Optional[List[int]]
keywords: Optional[List[str]]
status: str
created_at: datetime
# ============================================================================
# Exercises (Kernobjekt)
# ============================================================================
class ExerciseCreate(BaseModel):
title: str
summary: Optional[str] = None
goal: str
execution: str
preparation: Optional[str] = None
trainer_notes: Optional[str] = None
equipment: Optional[List[str]] = []
duration_min: Optional[int] = None
duration_max: Optional[int] = None
group_size_min: Optional[int] = None
group_size_max: Optional[int] = None
age_groups: Optional[List[str]] = []
focus_area: Optional[str] = None
secondary_areas: Optional[List[str]] = []
training_character: Optional[str] = None
primary_method_id: Optional[int] = None
secondary_method_ids: Optional[List[int]] = []
visibility: Optional[str] = "private"
club_id: Optional[int] = None
class ExerciseResponse(BaseModel):
id: int
title: str
summary: Optional[str]
goal: str
execution: str
preparation: Optional[str]
trainer_notes: Optional[str]
equipment: Optional[List[str]]
duration_min: Optional[int]
duration_max: Optional[int]
group_size_min: Optional[int]
group_size_max: Optional[int]
age_groups: Optional[List[str]]
focus_area: Optional[str]
secondary_areas: Optional[List[str]]
training_character: Optional[str]
primary_method_id: Optional[int]
secondary_method_ids: Optional[List[int]]
visibility: str
status: str
created_by: int
club_id: Optional[int]
created_at: datetime
updated_at: datetime
class ExerciseSkillCreate(BaseModel):
exercise_id: int
skill_id: int
is_primary: bool = False
intensity: Optional[int] = Field(None, ge=1, le=5)
development_contribution: Optional[str] = None
required_level: Optional[int] = None
target_level: Optional[int] = None
# ============================================================================
# Training Planning
# ============================================================================
class TrainingUnitCreate(BaseModel):
group_id: int
date: date
time_start: Optional[time] = None
time_end: Optional[time] = None
derived_from_template_id: Optional[int] = None
derived_from_unit_id: Optional[int] = None
title: Optional[str] = None
goal: Optional[str] = None
focus_areas: Optional[List[str]] = []
class TrainingUnitResponse(BaseModel):
id: int
group_id: int
date: date
time_start: Optional[time]
time_end: Optional[time]
title: Optional[str]
goal: Optional[str]
focus_areas: Optional[List[str]]
completion_status: str
created_by: int
created_at: datetime
updated_at: datetime
# ============================================================================
# Import
# ============================================================================
class WikiImportRequest(BaseModel):
import_type: str # skill, method, exercise
wiki_url: Optional[str] = None
dry_run: bool = False
class WikiImportResponse(BaseModel):
import_status: str
items_total: int
items_imported: int
items_failed: int
error_log: Optional[List[str]]