diff --git a/apps/backend/schemas/task.py b/apps/backend/schemas/task.py index f9797dc..1a8d457 100644 --- a/apps/backend/schemas/task.py +++ b/apps/backend/schemas/task.py @@ -1,6 +1,6 @@ from datetime import datetime from typing import Optional -from pydantic import BaseModel, Field, field_validator +from pydantic import BaseModel, ConfigDict, Field, field_validator class TaskBase(BaseModel): @@ -132,6 +132,8 @@ class TaskUpdate(BaseModel): class TaskResponse(TaskBase): """打卡任务响应 Schema""" + model_config = ConfigDict(from_attributes=True) + id: int user_id: int created_at: datetime @@ -145,6 +147,3 @@ class TaskResponse(TaskBase): last_check_in_time: Optional[datetime] = Field(None, description="最后一次打卡时间") last_check_in_status: Optional[str] = Field(None, description="最后一次打卡状态") thread_id: Optional[str] = Field(None, description="接龙 ID(从 payload_config 中提取)") - - class Config: - from_attributes = True diff --git a/apps/backend/schemas/template.py b/apps/backend/schemas/template.py index bd759cd..8a22291 100644 --- a/apps/backend/schemas/template.py +++ b/apps/backend/schemas/template.py @@ -1,6 +1,6 @@ from datetime import datetime from typing import Optional, Dict, Any, List, Union -from pydantic import BaseModel, Field, field_validator +from pydantic import BaseModel, ConfigDict, Field, field_validator import json @@ -43,10 +43,7 @@ class FieldConfigItem(BaseModel): class FieldConfigValues(BaseModel): """Values 字段的嵌套配置(如 location, temperature 等)""" - pass - - class Config: - extra = "allow" # 允许任意字段 + model_config = ConfigDict(extra="allow") class FieldConfig(BaseModel): @@ -128,6 +125,8 @@ class TemplateUpdate(BaseModel): class TemplateResponse(BaseModel): """模板响应 Schema""" + model_config = ConfigDict(from_attributes=True) + id: int name: str description: Optional[str] @@ -137,9 +136,6 @@ class TemplateResponse(BaseModel): created_at: datetime updated_at: Optional[datetime] - class Config: - from_attributes = True - class TaskFromTemplateRequest(BaseModel): """从模板创建任务的请求 Schema""" diff --git a/apps/backend/schemas/user.py b/apps/backend/schemas/user.py index 2d9093e..5d211d7 100644 --- a/apps/backend/schemas/user.py +++ b/apps/backend/schemas/user.py @@ -1,6 +1,6 @@ from datetime import datetime from typing import Optional -from pydantic import BaseModel, Field, EmailStr +from pydantic import BaseModel, ConfigDict, EmailStr, Field class UserBase(BaseModel): @@ -45,6 +45,8 @@ class UserUpdateProfile(BaseModel): class UserResponse(BaseModel): """用户响应 Schema""" + model_config = ConfigDict(from_attributes=True) + id: int alias: str role: str @@ -55,9 +57,6 @@ class UserResponse(BaseModel): created_at: datetime updated_at: Optional[datetime] = None - class Config: - from_attributes = True - class UserWithToken(UserResponse): """带 Token 的用户响应 Schema""" diff --git a/tests/test_new_frontend_architecture.py b/tests/test_frontend_architecture.py similarity index 77% rename from tests/test_new_frontend_architecture.py rename to tests/test_frontend_architecture.py index a53a12b..ad28fb8 100644 --- a/tests/test_new_frontend_architecture.py +++ b/tests/test_frontend_architecture.py @@ -3,11 +3,11 @@ from __future__ import annotations from pathlib import Path -FRONTEND_ROOT = Path(__file__).resolve().parents[1] / "apps" / "new-frontend" +FRONTEND_ROOT = Path(__file__).resolve().parents[1] / "apps" / "frontend" SRC_ROOT = FRONTEND_ROOT / "src" -def test_new_frontend_has_business_app_structure() -> None: +def test_frontend_has_business_app_structure() -> None: expected_files = [ "api/client.ts", "api/index.ts", @@ -37,7 +37,7 @@ def test_new_frontend_has_business_app_structure() -> None: assert missing == [] -def test_new_frontend_routes_cover_user_and_admin_workflows() -> None: +def test_frontend_routes_cover_user_and_admin_workflows() -> None: router = (SRC_ROOT / "app" / "router.ts").read_text(encoding="utf-8") for path in [ @@ -57,15 +57,8 @@ def test_new_frontend_routes_cover_user_and_admin_workflows() -> None: assert path in router -def test_new_frontend_replaces_starter_component() -> None: +def test_frontend_replaces_starter_component() -> None: app = (SRC_ROOT / "App.vue").read_text(encoding="utf-8") assert "HelloWorld" not in app assert not (SRC_ROOT / "components" / "HelloWorld.vue").exists() - - -def test_theme_switch_is_icon_only_but_accessible() -> None: - layout = (SRC_ROOT / "components" / "AppLayout.vue").read_text(encoding="utf-8") - - assert "切换主题,当前${themeLabel}" in layout - assert "{{ themeLabel }}" not in layout