122 lines
3.0 KiB
Python
122 lines
3.0 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import date, datetime, time
|
|
from typing import Literal
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
from backend.features.accounts.service import PROFILE_PRIVACY_NOTICE
|
|
|
|
|
|
class CredentialsInput(BaseModel):
|
|
username: str
|
|
password: str
|
|
|
|
|
|
class PasswordChangeInput(BaseModel):
|
|
current_password: str
|
|
new_password: str
|
|
confirmation: str
|
|
|
|
|
|
class AccountIdentityResponse(BaseModel):
|
|
id: int
|
|
username: str
|
|
is_admin: bool
|
|
membership_status: str
|
|
membership_active: bool
|
|
smart_access: bool
|
|
badges: list[str]
|
|
|
|
|
|
class AuthResponse(BaseModel):
|
|
account: AccountIdentityResponse
|
|
csrf_token: str
|
|
|
|
|
|
class MessageResponse(BaseModel):
|
|
message: str
|
|
|
|
|
|
class BirthProfileInput(BaseModel):
|
|
birth_date: date
|
|
birth_time: time
|
|
gender: Literal["male", "female"]
|
|
|
|
|
|
class BirthProfileResponse(BaseModel):
|
|
configured: bool
|
|
birth_date: date | None = None
|
|
birth_time: time | None = None
|
|
gender: str | None = None
|
|
updated_at: datetime | None = None
|
|
privacy_notice: str = PROFILE_PRIVACY_NOTICE
|
|
|
|
|
|
class MembershipStatusResponse(BaseModel):
|
|
status: str
|
|
active: bool
|
|
is_permanent: bool
|
|
expires_at: datetime | None
|
|
remaining_days: int | None
|
|
daily_limit: int
|
|
used_today: int
|
|
remaining_today: int | None
|
|
quota_exempt: bool
|
|
smart_access: bool
|
|
description: str = "开通会员后可使用智能选股、问师、问天、复盘助手等智能功能。"
|
|
usage_package_available: bool = False
|
|
|
|
|
|
class MembershipAdminResponse(BaseModel):
|
|
user_id: int
|
|
username: str
|
|
is_admin: bool
|
|
membership: MembershipStatusResponse
|
|
|
|
|
|
class MembershipUpdateInput(BaseModel):
|
|
action: Literal["activate", "disable", "set_limit"]
|
|
duration: Literal["1_month", "3_months", "12_months", "3_years", "permanent"] | None = None
|
|
daily_limit: int | None = Field(default=None, ge=1, le=1000)
|
|
|
|
|
|
class CredentialStatusResponse(BaseModel):
|
|
name: str
|
|
configured: bool
|
|
updated_at: datetime | None
|
|
|
|
|
|
class CredentialInput(BaseModel):
|
|
value: str = Field(min_length=1, max_length=4096)
|
|
|
|
|
|
class ModelInput(BaseModel):
|
|
display_name: str = Field(min_length=1, max_length=40)
|
|
base_url: str = Field(min_length=1, max_length=2048)
|
|
model_identifier: str = Field(min_length=1, max_length=128)
|
|
api_key: str = Field(min_length=1, max_length=4096)
|
|
|
|
|
|
class ModelUpdateInput(BaseModel):
|
|
display_name: str = Field(min_length=1, max_length=40)
|
|
base_url: str = Field(min_length=1, max_length=2048)
|
|
model_identifier: str = Field(min_length=1, max_length=128)
|
|
api_key: str | None = Field(default=None, min_length=1, max_length=4096)
|
|
|
|
|
|
class ModelPoolItemResponse(BaseModel):
|
|
id: int
|
|
display_name: str
|
|
base_url: str
|
|
model_identifier: str
|
|
has_api_key: bool
|
|
is_primary: bool
|
|
is_fallback: bool
|
|
updated_at: datetime
|
|
|
|
|
|
class ModelSelectionInput(BaseModel):
|
|
primary_model_id: int = Field(ge=1)
|
|
fallback_model_id: int | None = Field(default=None, ge=1)
|