a400130c67
Add coach review APIs, pose calibration thresholds, Gitea CI, Kubernetes skeleton, H5 practice page, and mini program tab bar. Co-authored-by: Cursor <cursoragent@cursor.com>
171 lines
3.9 KiB
Python
171 lines
3.9 KiB
Python
from datetime import date, datetime
|
|
from enum import Enum
|
|
from typing import Any
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class LoginType(str, Enum):
|
|
phone_code = "phone_code"
|
|
wechat = "wechat"
|
|
|
|
|
|
class UserRole(str, Enum):
|
|
parent = "parent"
|
|
coach = "coach"
|
|
org_admin = "org_admin"
|
|
platform_admin = "platform_admin"
|
|
|
|
|
|
class Gender(str, Enum):
|
|
male = "male"
|
|
female = "female"
|
|
unknown = "unknown"
|
|
|
|
|
|
class VideoScene(str, Enum):
|
|
front_posture = "front_posture"
|
|
side_posture = "side_posture"
|
|
squat = "squat"
|
|
balance = "balance"
|
|
gait = "gait"
|
|
|
|
|
|
class TaskType(str, Enum):
|
|
posture_screening = "posture_screening"
|
|
movement_scoring = "movement_scoring"
|
|
reassessment = "reassessment"
|
|
|
|
|
|
class TaskStatus(str, Enum):
|
|
CREATED = "CREATED"
|
|
QUEUED = "QUEUED"
|
|
PROCESSING = "PROCESSING"
|
|
SUCCEEDED = "SUCCEEDED"
|
|
FAILED = "FAILED"
|
|
CANCELLED = "CANCELLED"
|
|
|
|
|
|
class RiskLevel(str, Enum):
|
|
low = "low"
|
|
medium = "medium"
|
|
high = "high"
|
|
review_required = "review_required"
|
|
|
|
|
|
class PlanStatus(str, Enum):
|
|
draft = "draft"
|
|
active = "active"
|
|
completed = "completed"
|
|
paused = "paused"
|
|
|
|
|
|
class LoginRequest(BaseModel):
|
|
login_type: LoginType = Field(alias="loginType")
|
|
credential: str
|
|
code: str | None = None
|
|
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class User(BaseModel):
|
|
id: int
|
|
phone_masked: str = Field(alias="phoneMasked")
|
|
role: UserRole
|
|
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class ChildCreateRequest(BaseModel):
|
|
name: str
|
|
birthday: date
|
|
gender: Gender = Gender.unknown
|
|
height: float | None = None
|
|
weight: float | None = None
|
|
contraindications: str | None = None
|
|
|
|
|
|
class ChildUpdateRequest(ChildCreateRequest):
|
|
pass
|
|
|
|
|
|
class Child(BaseModel):
|
|
id: int
|
|
name: str
|
|
birthday: date
|
|
age: int
|
|
height: float | None = None
|
|
weight: float | None = None
|
|
status: str = "active"
|
|
|
|
|
|
class UploadTokenRequest(BaseModel):
|
|
child_id: int = Field(alias="childId")
|
|
file_name: str = Field(alias="fileName")
|
|
content_type: str = Field(alias="contentType")
|
|
size: int
|
|
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class VideoCreateRequest(BaseModel):
|
|
child_id: int = Field(alias="childId")
|
|
object_key: str = Field(alias="objectKey")
|
|
scene: VideoScene
|
|
capture_hint: str | None = Field(default=None, alias="captureHint")
|
|
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class AnalysisTaskCreateRequest(BaseModel):
|
|
child_id: int = Field(alias="childId")
|
|
video_id: int = Field(alias="videoId")
|
|
task_type: TaskType = Field(alias="taskType")
|
|
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class AnalysisTaskWebhook(BaseModel):
|
|
task_id: int = Field(alias="taskId")
|
|
status: TaskStatus
|
|
progress: int | None = None
|
|
error_code: str | None = Field(default=None, alias="errorCode")
|
|
result: dict[str, Any] | None = None
|
|
signature: str | None = None
|
|
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class TrainingPlanCreateRequest(BaseModel):
|
|
child_id: int = Field(alias="childId")
|
|
report_id: int | None = Field(default=None, alias="reportId")
|
|
goal: str
|
|
cycle_days: int = Field(alias="cycleDays", ge=7)
|
|
exercise_ids: list[int] | None = Field(default=None, alias="exerciseIds")
|
|
constraints: dict[str, Any] | None = None
|
|
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class TrainingRecordCreateRequest(BaseModel):
|
|
exercise_id: int = Field(alias="exerciseId")
|
|
completed: bool
|
|
score: int | None = Field(default=None, ge=0, le=100)
|
|
duration_seconds: int | None = Field(default=None, alias="durationSeconds")
|
|
note: str | None = None
|
|
media: list[str] | None = None
|
|
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class ReportMetric(BaseModel):
|
|
name: str
|
|
value: float
|
|
level: str
|
|
confidence: float
|
|
|
|
|
|
class ReportReviewRequest(BaseModel):
|
|
action: str = Field(description="approve or reject")
|
|
note: str | None = None
|