Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package org.bytefight.webserver.competition.application;

import lombok.RequiredArgsConstructor;

import java.util.List;

import org.bytefight.webserver.competition.domain.dto.PlayerCompetitionDto;
import org.bytefight.webserver.glicko.infra.TeamStatsRepository;
import org.bytefight.webserver.player.domain.Player;
import org.bytefight.webserver.team.domain.Team;
import org.bytefight.webserver.team.domain.TeamMember;
import org.bytefight.webserver.team.infra.TeamMemberRepository;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class PlayerCompetitionService {
private final TeamMemberRepository teamMemberRepository;
private final TeamStatsRepository teamStatsRepository;

public List<PlayerCompetitionDto> getPlayerCompetitions(Player player) {
List<TeamMember> memberships = teamMemberRepository.findByPlayerAndTeamIsDeletedFalse(player);

return memberships.stream()
.map(membership -> {
Team team = membership.getTeam();
var competition = team.getCompetition();

List<PlayerCompetitionDto.MemberDto> memberDtos =
teamMemberRepository.findByTeam(team).stream()
.map(TeamMember::getPlayer)
.map(p -> new PlayerCompetitionDto.MemberDto(
p.getUser().getUuid().toString(), p.getUsername()))
.toList();

List<PlayerCompetitionDto.RankingDto> rankingDtos =
teamStatsRepository
.findTeamRanksByCompetition(competition.getId(), team.getId())
.stream()
.map(r -> new PlayerCompetitionDto.RankingDto(r.getLadder(), r.getRank()))
.toList();

return new PlayerCompetitionDto(
competition.getSlug(),
competition.getName(),
team.getName(),
team.getUuid().toString(),
memberDtos,
rankingDtos);
})
.toList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.bytefight.webserver.competition.domain.dto;

import jakarta.validation.constraints.NotNull;
import lombok.Value;

import java.util.List;

@Value
public class PlayerCompetitionDto {
@NotNull String competitionSlug;
@NotNull String competitionName;
@NotNull String teamName;
@NotNull String teamUuid;
@NotNull List<MemberDto> members;
@NotNull List<RankingDto> rankings;

@Value
public static class MemberDto {
@NotNull String uuid;
@NotNull String username;
}

@Value
public static class RankingDto {
@NotNull String ladder;
Integer rank;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.bytefight.webserver.glicko.domain;

public interface TeamRankRow {
String getLadder();

Integer getRank();
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.Optional;

import org.bytefight.webserver.competition.domain.Competition;
import org.bytefight.webserver.glicko.domain.TeamRankRow;
import org.bytefight.webserver.glicko.domain.TeamStats;
import org.bytefight.webserver.glicko.domain.TeamStatsAggregate;
import org.bytefight.webserver.leaderboard.domain.LeaderboardRow;
Expand Down Expand Up @@ -39,6 +40,30 @@ List<TeamStats> findAllByCompetitionAndLadderOrderByGlickoRatingDesc(
TeamStatsAggregate getTeamStatsAggregateByTeamAndLadder(
@Param("team") Team team, @Param("ladders") Collection<String> ladders);

@Query(
value =
"""
SELECT ladder, rank FROM (
SELECT
ts.ladder AS ladder,
ts.team_id AS team_id,
CASE
WHEN ts.matches_played = 0 THEN NULL
ELSE DENSE_RANK() OVER (
PARTITION BY ts.ladder
ORDER BY (CASE WHEN ts.matches_played = 0 THEN NULL ELSE ts.glicko_rating END) DESC NULLS LAST
)
END AS rank
FROM team_stats ts
JOIN teams t ON t.id = ts.team_id AND t.is_deleted = false
WHERE ts.competition_id = :competitionId
) AS subquery
WHERE team_id = :teamId
""",
nativeQuery = true)
List<TeamRankRow> findTeamRanksByCompetition(
@Param("competitionId") Long competitionId, @Param("teamId") Long teamId);

@Query(
value =
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;

import java.util.List;

import org.bytefight.webserver.competition.application.PlayerCompetitionService;
import org.bytefight.webserver.competition.domain.dto.PlayerCompetitionDto;
import org.bytefight.webserver.player.application.PlayerService;
import org.bytefight.webserver.player.domain.Player;
import org.bytefight.webserver.player.domain.SelfPlayerDto;
Expand All @@ -14,6 +18,7 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
Expand All @@ -30,6 +35,7 @@
public class PrivatePlayerController {
private final PlayerService playerService;
private final TeamService teamService;
private final PlayerCompetitionService playerCompetitionService;

@Operation(operationId = "getCurrentPlayer", summary = "Get current player profile")
@GetMapping("/me")
Expand All @@ -41,6 +47,19 @@ public ResponseEntity<SelfPlayerDto> getCurrentPlayer(@AuthenticationPrincipal U
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND))));
}

@Operation(operationId = "getMyCompetitions", summary = "Get all competitions the current player has participated in")
@GetMapping("/me/competitions")
@Transactional
public ResponseEntity<List<PlayerCompetitionDto>> getMyCompetitions(
@AuthenticationPrincipal User user) {
Player player =
playerService
.getPlayer(user)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));

return ResponseEntity.ok(playerCompetitionService.getPlayerCompetitions(player));
}

@Operation(operationId = "updateCurrentPlayer", summary = "Update current player profile")
@PatchMapping("/me")
public ResponseEntity<SelfPlayerDto> updateCurrentPlayer(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

@Repository
public interface TeamMemberRepository extends JpaRepository<TeamMember, Long> {
List<TeamMember> findByPlayerAndTeamIsDeletedFalse(Player player);

boolean existsByCompetitionAndPlayerAndTeamIsDeletedFalse(Competition competition, Player player);

Optional<TeamMember> findByCompetitionAndPlayerAndTeamIsDeletedFalse(
Expand Down