Профиль: история партий игрока и настройки её витрины
Выборки партий по игроку в бэкенде не было — только по группе. Добавлен
stats_service.user_match_list: завершённые партии игрока, свежие сверху;
сборка элементов вынесена из group_match_list в общий _match_items, чтобы
не дублировать её в двух местах.
Витрина профиля задаётся двумя колонками в users (миграция 0011):
history_mode (all/best) и history_detail (compact/full). Режим применяется
на бэкенде, а не на клиенте: это витрина владельца, и в том же виде
профиль видят гости. В режиме best берётся партия с максимальными League
Points из SCORED_CTE (при равных очках — более свежая).
GET /api/users/{user_id}/matches отдаёт список вместе с mode и detail —
гостю хватает одного запроса, чтобы отрисовать историю как задумал владелец.
#1
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,8 @@ def build_me(session: Session, user: User) -> s.MeRead:
|
||||
bio=user.bio,
|
||||
avatar_url=user_service.avatar_url_for(user.id, user.avatar_path, user.updated_at), # type: ignore[arg-type]
|
||||
favorite_faction_id=user.favorite_faction_id,
|
||||
history_mode=user.history_mode,
|
||||
history_detail=user.history_detail,
|
||||
groups=groups,
|
||||
)
|
||||
|
||||
@@ -73,6 +75,8 @@ def update_me(
|
||||
bio=user.bio,
|
||||
avatar_url=user_service.avatar_url_for(user.id, user.avatar_path, user.updated_at), # type: ignore[arg-type]
|
||||
favorite_faction_id=user.favorite_faction_id,
|
||||
history_mode=user.history_mode,
|
||||
history_detail=user.history_detail,
|
||||
)
|
||||
|
||||
|
||||
@@ -90,6 +94,13 @@ def update_my_profile(
|
||||
user_service.update_bio(session, user, changed["bio"])
|
||||
if "favorite_faction_id" in changed:
|
||||
user_service.update_favorite_faction(session, user, changed["favorite_faction_id"])
|
||||
if "history_mode" in changed or "history_detail" in changed:
|
||||
user_service.update_history_prefs(
|
||||
session,
|
||||
user,
|
||||
mode=changed.get("history_mode"),
|
||||
detail=changed.get("history_detail"),
|
||||
)
|
||||
audit_service.record(
|
||||
session,
|
||||
actor_id=user.id,
|
||||
@@ -155,6 +166,26 @@ def get_user_profile(
|
||||
return user_service.public_profile(session, user_id)
|
||||
|
||||
|
||||
@router.get("/{user_id}/matches", response_model=s.MatchHistory)
|
||||
def user_matches(
|
||||
user_id: int,
|
||||
limit: int = Query(20, ge=1, le=100),
|
||||
offset: int = Query(0, ge=0),
|
||||
session: Session = Depends(get_session),
|
||||
_user: User = Depends(get_current_user),
|
||||
) -> dict:
|
||||
"""История партий игрока. Режим — витрина владельца профиля: её видят и гости."""
|
||||
owner = user_service.get_user(session, user_id)
|
||||
data = stats_service.user_match_list(
|
||||
session,
|
||||
user_id,
|
||||
limit=limit,
|
||||
offset=offset,
|
||||
best_only=owner.history_mode == "best",
|
||||
)
|
||||
return {**data, "mode": owner.history_mode, "detail": owner.history_detail}
|
||||
|
||||
|
||||
@router.get("/me/stats", response_model=s.ProfileStats)
|
||||
def my_stats(
|
||||
session: Session = Depends(get_session),
|
||||
|
||||
Reference in New Issue
Block a user