Files
vps-manager/app/schemas/asset.py
T

170 lines
4.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""资产相关 Schema(请求/响应模型)
设计说明:
- *In 系列:详情表输入模型(不含 id/asset_id,由服务端填充)
- AssetCreate/AssetUpdate:主表字段 + 按类型嵌套的可选 detail
- AssetRead:完整输出,含计算字段 days_to_expiry(距到期天数)
"""
from datetime import date, datetime
from typing import Optional
from sqlmodel import SQLModel
from app.models.asset import AssetStatus, AssetType
# --------------------------------------------------------------------------- #
# 详情表输入模型
# --------------------------------------------------------------------------- #
class VPSDetailIn(SQLModel):
"""VPS 详情输入"""
ip_address: str
tailscale_ip: Optional[str] = None
region: Optional[str] = None
os: Optional[str] = None
cpu_cores: int = 1
memory_gb: float = 1
disk_gb: int = 20
bandwidth_gb: Optional[int] = None
ssh_port: int = 22
panel_url: Optional[str] = None
ssh_user: Optional[str] = None
login_method: Optional[str] = "key"
ssh_key: Optional[str] = None # 明文输入,服务端加密存储
password: Optional[str] = None # 明文输入,服务端加密存储
purpose: Optional[str] = None
class DomainDetailIn(SQLModel):
"""域名详情输入"""
domain_name: str
registrar: Optional[str] = None
dns_provider: Optional[str] = None
cloudflare_account: Optional[str] = None
is_using: bool = True
redirect_target: Optional[str] = None
bind_asset_id: Optional[int] = None
class AIAccountIn(SQLModel):
"""AI 账号详情输入"""
provider: str
api_key: Optional[str] = None
plan: Optional[str] = None
balance: Optional[float] = None
currency: str = "USD"
monthly_usage: Optional[float] = None
monthly_limit: Optional[float] = None
# --------------------------------------------------------------------------- #
# 资产主表模型
# --------------------------------------------------------------------------- #
class AssetBase(SQLModel):
"""资产主表公共字段"""
name: str
asset_type: AssetType
provider: str
provider_id: Optional[int] = None
renewal_cycle: Optional[str] = None
account: Optional[str] = None
expiry_date: Optional[date] = None
auto_renew: bool = False
cost: float = 0
currency: str = "USD"
status: AssetStatus = AssetStatus.ACTIVE
is_archived: bool = False
remark: Optional[str] = None
class AssetCreate(AssetBase):
"""创建资产:按 asset_type 携带对应 detail"""
vps_detail: Optional[VPSDetailIn] = None
domain_detail: Optional[DomainDetailIn] = None
ai_detail: Optional[AIAccountIn] = None
class AssetUpdate(SQLModel):
"""更新资产:所有字段可选,仅更新传入项"""
name: Optional[str] = None
asset_type: Optional[AssetType] = None
provider: Optional[str] = None
provider_id: Optional[int] = None
renewal_cycle: Optional[str] = None
account: Optional[str] = None
expiry_date: Optional[date] = None
auto_renew: Optional[bool] = None
cost: Optional[float] = None
currency: Optional[str] = None
status: Optional[AssetStatus] = None
is_archived: Optional[bool] = None
remark: Optional[str] = None
vps_detail: Optional[VPSDetailIn] = None
domain_detail: Optional[DomainDetailIn] = None
ai_detail: Optional[AIAccountIn] = None
# --------------------------------------------------------------------------- #
# 输出模型
# --------------------------------------------------------------------------- #
class VPSDetailRead(SQLModel):
"""VPS 详情输出(不含敏感明文,仅返回凭证存在标记)"""
id: int
asset_id: int
ip_address: str
tailscale_ip: Optional[str] = None
region: Optional[str] = None
os: Optional[str] = None
cpu_cores: int = 1
memory_gb: float = 1
disk_gb: int = 20
bandwidth_gb: Optional[int] = None
ssh_port: int = 22
panel_url: Optional[str] = None
ssh_user: Optional[str] = None
login_method: Optional[str] = "key"
purpose: Optional[str] = None
has_ssh_key: bool = False
has_password: bool = False
class DomainDetailRead(DomainDetailIn):
id: int
asset_id: int
class AIAccountRead(SQLModel):
"""AI 账号输出(不暴露 API Key 明文,仅返回 has_api_key"""
id: int
asset_id: int
provider: str
plan: Optional[str] = None
balance: Optional[float] = None
currency: str = "USD"
monthly_usage: Optional[float] = None
monthly_limit: Optional[float] = None
last_synced_at: Optional[datetime] = None
has_api_key: bool = False
class AssetRead(AssetBase):
"""资产完整输出"""
id: int
created_at: datetime
updated_at: datetime
days_to_expiry: Optional[int] = None
provider_name: Optional[str] = None
vps_detail: Optional[VPSDetailRead] = None
domain_detail: Optional[DomainDetailRead] = None
ai_detail: Optional[AIAccountRead] = None