OncoLit: a multi-tenant oncology literature search, feed, and collaboration platform. Built with FastAPI + Vue 3 + PostgreSQL. Includes PubMed pipeline, drug approvals, AI summaries, and systematic review tools.
71 lines
1.7 KiB
Python
71 lines
1.7 KiB
Python
from __future__ import annotations
|
|
|
|
from pydantic import BaseModel, EmailStr, Field, field_validator
|
|
|
|
|
|
def validate_password_strength(v: str) -> str:
|
|
if len(v) < 8:
|
|
raise ValueError("密码至少 8 个字符")
|
|
if not any(c.isupper() for c in v):
|
|
raise ValueError("密码需包含至少一个大写字母")
|
|
if not any(c.islower() for c in v):
|
|
raise ValueError("密码需包含至少一个小写字母")
|
|
if not any(c.isdigit() for c in v):
|
|
raise ValueError("密码需包含至少一个数字")
|
|
return v
|
|
|
|
|
|
class RegisterRequest(BaseModel):
|
|
email: EmailStr
|
|
password: str = Field(..., min_length=8)
|
|
display_name: str = Field(..., min_length=1)
|
|
hospital_name: str | None = None
|
|
department_name: str | None = None
|
|
verify_token: str | None = None # 验证码通过后获取的一次性令牌
|
|
|
|
_check_password = field_validator("password")(validate_password_strength)
|
|
|
|
|
|
class LoginRequest(BaseModel):
|
|
email: EmailStr
|
|
password: str = Field(..., min_length=1)
|
|
|
|
|
|
class TokenResponse(BaseModel):
|
|
access_token: str
|
|
refresh_token: str
|
|
token_type: str = "bearer"
|
|
|
|
|
|
class RefreshRequest(BaseModel):
|
|
refresh_token: str
|
|
|
|
|
|
class UserProfile(BaseModel):
|
|
id: str
|
|
email: str
|
|
display_name: str
|
|
title: str | None = None
|
|
avatar_url: str | None = None
|
|
platform_role: str | None = None
|
|
notify_email: bool = True
|
|
digest_frequency: str = "daily"
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class TenantInfo(BaseModel):
|
|
id: str
|
|
name: str
|
|
slug: str
|
|
plan_type: str
|
|
role: str
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class AuthResponse(BaseModel):
|
|
user: UserProfile
|
|
token: TokenResponse
|
|
tenants: list[TenantInfo] = []
|