feat(api): 添加测试,小修小补

- **未经测试**
This commit is contained in:
jimmy-sketch
2025-07-26 10:28:48 +08:00
parent 3b697785fc
commit 7ea4570c17
10 changed files with 266 additions and 59 deletions

View File

@@ -87,7 +87,7 @@ class BeatmapsetBase(SQLModel):
# Beatmapset
artist: str = Field(index=True)
artist_unicode: str = Field(index=True)
covers: BeatmapCovers = Field(sa_column=Column(JSON))
covers: BeatmapCovers | None = Field(sa_column=Column(JSON))
creator: str
favourite_count: int
nsfw: bool = Field(default=False)

View File

@@ -4,6 +4,7 @@ from typing import TYPE_CHECKING
from sqlalchemy import JSON, Column, DateTime
from sqlmodel import Field, Relationship, SQLModel
from sqlalchemy.orm import Mapped
if TYPE_CHECKING:
from .user import User
@@ -70,7 +71,7 @@ class LegacyUserStatistics(SQLModel, table=True):
)
# 关联关系
user: "User" = Relationship(back_populates="statistics")
user: Mapped["User"] = Relationship(back_populates="statistics")
class LegacyOAuthToken(SQLModel, table=True):

View File

@@ -4,7 +4,7 @@ from datetime import datetime
import math
from typing import Literal, TYPE_CHECKING, List
from app.models.score import Rank, APIMod, GameMode
from app.models.score import Rank, APIMod, GameMode, MODE_TO_INT
from .beatmap import Beatmap, BeatmapResp
from .beatmapset import Beatmapset, BeatmapsetResp
@@ -84,6 +84,7 @@ class ScoreResp(ScoreBase):
legacy_total_score: int = 0 # FIXME
processed: bool = False # solo_score
weight: float = 0.0
ruleset_id: int | None
beatmap: BeatmapResp | None = None
beatmapset: BeatmapsetResp | None = None
# FIXME: user: APIUser | None = None
@@ -96,6 +97,7 @@ class ScoreResp(ScoreBase):
s.beatmapset = BeatmapsetResp.from_db(score.beatmap.beatmapset)
s.is_perfect_combo = s.max_combo == s.beatmap.max_combo
s.legacy_perfect = s.max_combo == s.beatmap.max_combo
s.ruleset_id=MODE_TO_INT[score.ruleset_id]
if score.best_id:
# https://osu.ppy.sh/wiki/Performance_points/Weighting_system
s.weight = math.pow(0.95, score.best_id)

View File

@@ -3,6 +3,7 @@ from datetime import datetime
from typing import TYPE_CHECKING
from sqlalchemy import Column, DateTime
from sqlalchemy.orm import Mapped
from sqlmodel import Field, Relationship, SQLModel
if TYPE_CHECKING:
@@ -20,7 +21,7 @@ class Team(SQLModel, table=True):
default_factory=datetime.utcnow, sa_column=Column(DateTime)
)
members: list["TeamMember"] = Relationship(back_populates="team")
members: Mapped[list["TeamMember"]] = Relationship(back_populates="team")
class TeamMember(SQLModel, table=True):
@@ -33,5 +34,5 @@ class TeamMember(SQLModel, table=True):
default_factory=datetime.utcnow, sa_column=Column(DateTime)
)
user: "User" = Relationship(back_populates="team_membership")
team: "Team" = Relationship(back_populates="members")
user: Mapped["User"] = Relationship(back_populates="team_membership")
team: Mapped["Team"] = Relationship(back_populates="members")

View File

@@ -10,6 +10,7 @@ from .team import TeamMember
from sqlalchemy import DECIMAL, JSON, Column, Date, DateTime, Text
from sqlalchemy.dialects.mysql import VARCHAR
from sqlalchemy.orm import Mapped
from sqlmodel import BigInteger, Field, Relationship, SQLModel
@@ -69,31 +70,31 @@ class User(SQLModel, table=True):
return datetime.fromtimestamp(latest_activity) if latest_activity > 0 else None
# 关联关系
lazer_profile: Optional["LazerUserProfile"] = Relationship(back_populates="user")
lazer_statistics: list["LazerUserStatistics"] = Relationship(back_populates="user")
lazer_counts: Optional["LazerUserCounts"] = Relationship(back_populates="user")
lazer_achievements: list["LazerUserAchievement"] = Relationship(
lazer_profile: Mapped[Optional["LazerUserProfile"]] = Relationship(back_populates="user")
lazer_statistics: Mapped[list["LazerUserStatistics"]] = Relationship(back_populates="user")
lazer_counts: Mapped[Optional["LazerUserCounts"]] = Relationship(back_populates="user")
lazer_achievements: Mapped[list["LazerUserAchievement"]] = Relationship(
back_populates="user"
)
lazer_profile_sections: list["LazerUserProfileSections"] = Relationship(
lazer_profile_sections: Mapped[list["LazerUserProfileSections"]] = Relationship(
back_populates="user"
)
statistics: list[LegacyUserStatistics] = Relationship(back_populates="user")
team_membership: list[TeamMember] = Relationship(back_populates="user")
daily_challenge_stats: Optional["DailyChallengeStats"] = Relationship(
statistics: list["LegacyUserStatistics"] = Relationship(back_populates="user")
team_membership: Mapped[list["TeamMember"]] = Relationship(back_populates="user")
daily_challenge_stats: Mapped[Optional["DailyChallengeStats"]] = Relationship(
back_populates="user"
)
rank_history: list["RankHistory"] = Relationship(back_populates="user")
avatar: Optional["UserAvatar"] = Relationship(back_populates="user")
active_banners: list["LazerUserBanners"] = Relationship(back_populates="user")
lazer_badges: list["LazerUserBadge"] = Relationship(back_populates="user")
lazer_monthly_playcounts: list["LazerUserMonthlyPlaycounts"] = Relationship(
rank_history: Mapped[list["RankHistory"]] = Relationship(back_populates="user")
avatar: Mapped[Optional["UserAvatar"]] = Relationship(back_populates="user")
active_banners: Mapped[list["LazerUserBanners"]] = Relationship(back_populates="user")
lazer_badges: Mapped[list["LazerUserBadge"]] = Relationship(back_populates="user")
lazer_monthly_playcounts: Mapped[list["LazerUserMonthlyPlaycounts"]] = Relationship(
back_populates="user"
)
lazer_previous_usernames: list["LazerUserPreviousUsername"] = Relationship(
lazer_previous_usernames: Mapped[list["LazerUserPreviousUsername"]] = Relationship(
back_populates="user"
)
lazer_replays_watched: list["LazerUserReplaysWatched"] = Relationship(
lazer_replays_watched: Mapped[list["LazerUserReplaysWatched"]] = Relationship(
back_populates="user"
)
@@ -154,7 +155,7 @@ class LazerUserProfile(SQLModel, table=True):
)
# 关联关系
user: "User" = Relationship(back_populates="lazer_profile")
user: Mapped["User"] = Relationship(back_populates="lazer_profile")
class LazerUserProfileSections(SQLModel, table=True):
@@ -172,7 +173,7 @@ class LazerUserProfileSections(SQLModel, table=True):
default_factory=datetime.utcnow, sa_column=Column(DateTime)
)
user: "User" = Relationship(back_populates="lazer_profile_sections")
user: Mapped["User"] = Relationship(back_populates="lazer_profile_sections")
class LazerUserCountry(SQLModel, table=True):
@@ -237,7 +238,7 @@ class LazerUserCounts(SQLModel, table=True):
)
# 关联关系
user: "User" = Relationship(back_populates="lazer_counts")
user: Mapped["User"] = Relationship(back_populates="lazer_counts")
class LazerUserStatistics(SQLModel, table=True):
@@ -297,7 +298,7 @@ class LazerUserStatistics(SQLModel, table=True):
)
# 关联关系
user: "User" = Relationship(back_populates="lazer_statistics")
user: Mapped["User"] = Relationship(back_populates="lazer_statistics")
class LazerUserBanners(SQLModel, table=True):
@@ -310,7 +311,7 @@ class LazerUserBanners(SQLModel, table=True):
is_active: bool | None = Field(default=None)
# 修正user关系的back_populates值
user: "User" = Relationship(back_populates="active_banners")
user: Mapped["User"] = Relationship(back_populates="active_banners")
class LazerUserAchievement(SQLModel, table=True):
@@ -323,7 +324,7 @@ class LazerUserAchievement(SQLModel, table=True):
default_factory=datetime.utcnow, sa_column=Column(DateTime)
)
user: "User" = Relationship(back_populates="lazer_achievements")
user: Mapped["User"] = Relationship(back_populates="lazer_achievements")
class LazerUserBadge(SQLModel, table=True):
@@ -344,7 +345,7 @@ class LazerUserBadge(SQLModel, table=True):
default_factory=datetime.utcnow, sa_column=Column(DateTime)
)
user: "User" = Relationship(back_populates="lazer_badges")
user: Mapped["User"] = Relationship(back_populates="lazer_badges")
class LazerUserMonthlyPlaycounts(SQLModel, table=True):
@@ -362,7 +363,7 @@ class LazerUserMonthlyPlaycounts(SQLModel, table=True):
default_factory=datetime.utcnow, sa_column=Column(DateTime)
)
user: "User" = Relationship(back_populates="lazer_monthly_playcounts")
user: Mapped["User"] = Relationship(back_populates="lazer_monthly_playcounts")
class LazerUserPreviousUsername(SQLModel, table=True):
@@ -380,7 +381,7 @@ class LazerUserPreviousUsername(SQLModel, table=True):
default_factory=datetime.utcnow, sa_column=Column(DateTime)
)
user: "User" = Relationship(back_populates="lazer_previous_usernames")
user: Mapped["User"] = Relationship(back_populates="lazer_previous_usernames")
class LazerUserReplaysWatched(SQLModel, table=True):
@@ -398,7 +399,7 @@ class LazerUserReplaysWatched(SQLModel, table=True):
default_factory=datetime.utcnow, sa_column=Column(DateTime)
)
user: "User" = Relationship(back_populates="lazer_replays_watched")
user: Mapped["User"] = Relationship(back_populates="lazer_replays_watched")
# 类型转换用的 UserAchievement不是 SQLAlchemy 模型)
@@ -426,7 +427,7 @@ class DailyChallengeStats(SQLModel, table=True):
weekly_streak_best: int = Field(default=0)
weekly_streak_current: int = Field(default=0)
user: "User" = Relationship(back_populates="daily_challenge_stats")
user: Mapped["User"] = Relationship(back_populates="daily_challenge_stats")
class RankHistory(SQLModel, table=True):
@@ -440,7 +441,7 @@ class RankHistory(SQLModel, table=True):
default_factory=datetime.utcnow, sa_column=Column(DateTime)
)
user: "User" = Relationship(back_populates="rank_history")
user: Mapped["User"] = Relationship(back_populates="rank_history")
class UserAvatar(SQLModel, table=True):
@@ -458,4 +459,4 @@ class UserAvatar(SQLModel, table=True):
r2_original_url: str | None = Field(default=None, max_length=500)
r2_game_url: str | None = Field(default=None, max_length=500)
user: "User" = Relationship(back_populates="avatar")
user: Mapped["User"] = Relationship(back_populates="avatar")