Skip to content

Commit 485c14a

Browse files
Copilotjwellniak
andcommitted
Refactor according to ADR-004, ADR-005, and ADR-007
- Add Lombok dependency and use @DaTa, @NoArgsConstructor, @AllArgsConstructor for entities - Change PlayerRepository to return List<PlayerEntity> instead of Object[] - Add findLatestScoresForPlayers method to PlayerScoreRepository - Refactor PlayersServiceImpl to use @Autowired on private members instead of constructor injection - Update listPlayers to fetch entities first, then load scores separately as per ADR-005 - Update PlayersController to use @Autowired on private members - Update unit tests to match new repository methods Co-authored-by: jwellniak <87517644+jwellniak@users.noreply.github.com>
1 parent e71d165 commit 485c14a

9 files changed

Lines changed: 126 additions & 224 deletions

File tree

pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@
4848
<artifactId>spring-boot-starter-validation</artifactId>
4949
</dependency>
5050

51+
<dependency>
52+
<groupId>org.projectlombok</groupId>
53+
<artifactId>lombok</artifactId>
54+
<version>1.18.30</version>
55+
<scope>provided</scope>
56+
</dependency>
57+
5158
<dependency>
5259
<groupId>org.postgresql</groupId>
5360
<artifactId>postgresql</artifactId>

src/main/java/com/skat/backend/api/controller/PlayersController.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import jakarta.validation.Valid;
66
import jakarta.validation.constraints.Max;
77
import jakarta.validation.constraints.Min;
8+
import org.springframework.beans.factory.annotation.Autowired;
89
import org.springframework.http.ResponseEntity;
910
import org.springframework.validation.annotation.Validated;
1011
import org.springframework.web.bind.annotation.*;
@@ -18,11 +19,8 @@
1819
@Validated
1920
public class PlayersController {
2021

21-
private final PlayersService playersService;
22-
23-
public PlayersController(PlayersService playersService) {
24-
this.playersService = playersService;
25-
}
22+
@Autowired
23+
private PlayersService playersService;
2624

2725
@GetMapping
2826
public ResponseEntity<PlayerListResponseTO> listPlayers(

src/main/java/com/skat/backend/application/PlayersServiceImpl.java

Lines changed: 65 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,63 +4,89 @@
44
import com.skat.backend.api.exception.NotFoundException;
55
import com.skat.backend.application.dto.*;
66
import com.skat.backend.domain.entities.PlayerEntity;
7+
import com.skat.backend.domain.entities.PlayerScoreEntity;
78
import com.skat.backend.domain.repositories.GameRepository;
89
import com.skat.backend.domain.repositories.PlayerRepository;
910
import com.skat.backend.domain.repositories.PlayerScoreRepository;
11+
import org.springframework.beans.factory.annotation.Autowired;
12+
import org.springframework.data.domain.PageRequest;
13+
import org.springframework.data.domain.Pageable;
1014
import org.springframework.stereotype.Service;
1115
import org.springframework.transaction.annotation.Transactional;
1216

13-
import java.math.BigInteger;
14-
import java.sql.Timestamp;
1517
import java.time.OffsetDateTime;
16-
import java.time.ZoneId;
17-
import java.util.ArrayList;
18-
import java.util.List;
19-
import java.util.UUID;
18+
import java.util.*;
19+
import java.util.stream.Collectors;
2020

2121
@Service
2222
public class PlayersServiceImpl implements PlayersService {
2323

24-
private final PlayerRepository playerRepository;
25-
private final GameRepository gameRepository;
26-
private final PlayerScoreRepository playerScoreRepository;
24+
@Autowired
25+
private PlayerRepository playerRepository;
2726

28-
public PlayersServiceImpl(PlayerRepository playerRepository,
29-
GameRepository gameRepository,
30-
PlayerScoreRepository playerScoreRepository) {
31-
this.playerRepository = playerRepository;
32-
this.gameRepository = gameRepository;
33-
this.playerScoreRepository = playerScoreRepository;
34-
}
27+
@Autowired
28+
private GameRepository gameRepository;
29+
30+
@Autowired
31+
private PlayerScoreRepository playerScoreRepository;
3532

3633
@Override
3734
@Transactional(readOnly = true)
3835
public PlayerListResponseTO listPlayers(PlayersQuery query) {
39-
String sortValue = query.sort().name();
40-
List<Object[]> results = playerRepository.findPlayersWithLatestScore(
41-
sortValue,
42-
query.startIndex(),
43-
query.pageSize()
44-
);
36+
Pageable pageable = PageRequest.of(query.startIndex() / query.pageSize(), query.pageSize());
4537

46-
List<PlayerWithScoreTO> items = new ArrayList<>();
47-
for (Object[] row : results) {
48-
UUID id = row[0] instanceof UUID ? (UUID) row[0] : UUID.fromString(row[0].toString());
49-
String firstName = (String) row[1];
50-
String lastName = (String) row[2];
51-
int totalPoints = row[3] instanceof Number ? ((Number) row[3]).intValue() : 0;
52-
int sequenceIndex = row[4] instanceof Number ? ((Number) row[4]).intValue() : 0;
53-
54-
OffsetDateTime updatedAt;
55-
if (row[5] instanceof Timestamp) {
56-
updatedAt = ((Timestamp) row[5]).toInstant().atZone(ZoneId.systemDefault()).toOffsetDateTime();
57-
} else if (row[5] instanceof OffsetDateTime) {
58-
updatedAt = (OffsetDateTime) row[5];
59-
} else {
60-
updatedAt = OffsetDateTime.now();
38+
// Fetch players based on sort
39+
List<PlayerEntity> players;
40+
if (query.sort() == PlayersSort.NAME) {
41+
players = playerRepository.findAllOrderedByName(pageable);
42+
} else {
43+
players = playerRepository.findAllPlayers(pageable);
44+
}
45+
46+
// Extract player IDs
47+
List<UUID> playerIds = players.stream()
48+
.map(PlayerEntity::getId)
49+
.collect(Collectors.toList());
50+
51+
// Fetch latest scores for these players
52+
Map<UUID, PlayerScoreEntity> latestScores = new HashMap<>();
53+
if (!playerIds.isEmpty()) {
54+
List<PlayerScoreEntity> scores = playerScoreRepository.findLatestScoresForPlayers(playerIds);
55+
for (PlayerScoreEntity score : scores) {
56+
if (score.getPlayer() != null) {
57+
latestScores.put(score.getPlayer().getId(), score);
58+
}
6159
}
62-
63-
items.add(new PlayerWithScoreTO(id, firstName, lastName, totalPoints, sequenceIndex, updatedAt));
60+
}
61+
62+
// Map to DTOs
63+
List<PlayerWithScoreTO> items = players.stream()
64+
.map(player -> {
65+
PlayerScoreEntity score = latestScores.get(player.getId());
66+
int totalPoints = score != null ? score.getTotalPoints() : 0;
67+
int sequenceIndex = score != null ? score.getSequenceIndex() : 0;
68+
OffsetDateTime updatedAt = score != null ? score.getCreatedAt() : OffsetDateTime.now();
69+
70+
return new PlayerWithScoreTO(
71+
player.getId(),
72+
player.getFirstName(),
73+
player.getLastName(),
74+
totalPoints,
75+
sequenceIndex,
76+
updatedAt
77+
);
78+
})
79+
.collect(Collectors.toList());
80+
81+
// Sort by score if needed
82+
if (query.sort() == PlayersSort.SCORE_DESC) {
83+
items.sort((a, b) -> {
84+
int scoreCompare = Integer.compare(b.current_total_points(), a.current_total_points());
85+
if (scoreCompare != 0) return scoreCompare;
86+
int lastNameCompare = a.last_name().compareTo(b.last_name());
87+
if (lastNameCompare != 0) return lastNameCompare;
88+
return a.first_name().compareTo(b.first_name());
89+
});
6490
}
6591

6692
long total = playerRepository.count();
Lines changed: 4 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.skat.backend.domain.entities;
22

33
import jakarta.persistence.*;
4+
import lombok.Data;
5+
import lombok.NoArgsConstructor;
46
import java.time.OffsetDateTime;
57
import java.util.UUID;
68

@@ -12,6 +14,8 @@
1214
@Index(name = "game_played_at_IDX", columnList = "played_at")
1315
}
1416
)
17+
@Data
18+
@NoArgsConstructor
1519
public class GameEntity {
1620

1721
@Id
@@ -42,71 +46,4 @@ public class GameEntity {
4246

4347
@Column(name = "played_at", nullable = false)
4448
private OffsetDateTime playedAt;
45-
46-
public GameEntity() {
47-
}
48-
49-
public UUID getId() {
50-
return id;
51-
}
52-
53-
public void setId(UUID id) {
54-
this.id = id;
55-
}
56-
57-
public PlayerEntity getPlayer1() {
58-
return player1;
59-
}
60-
61-
public void setPlayer1(PlayerEntity player1) {
62-
this.player1 = player1;
63-
}
64-
65-
public PlayerEntity getPlayer2() {
66-
return player2;
67-
}
68-
69-
public void setPlayer2(PlayerEntity player2) {
70-
this.player2 = player2;
71-
}
72-
73-
public PlayerEntity getPlayer3() {
74-
return player3;
75-
}
76-
77-
public void setPlayer3(PlayerEntity player3) {
78-
this.player3 = player3;
79-
}
80-
81-
public PlayerEntity getMainPlayer() {
82-
return mainPlayer;
83-
}
84-
85-
public void setMainPlayer(PlayerEntity mainPlayer) {
86-
this.mainPlayer = mainPlayer;
87-
}
88-
89-
public Integer getBidValue() {
90-
return bidValue;
91-
}
92-
93-
public void setBidValue(Integer bidValue) {
94-
this.bidValue = bidValue;
95-
}
96-
97-
public Integer getScore() {
98-
return score;
99-
}
100-
101-
public void setScore(Integer score) {
102-
this.score = score;
103-
}
104-
105-
public OffsetDateTime getPlayedAt() {
106-
return playedAt;
107-
}
108-
109-
public void setPlayedAt(OffsetDateTime playedAt) {
110-
this.playedAt = playedAt;
111-
}
11249
}
Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package com.skat.backend.domain.entities;
22

33
import jakarta.persistence.*;
4+
import lombok.Data;
5+
import lombok.NoArgsConstructor;
6+
import lombok.AllArgsConstructor;
47
import java.util.UUID;
58

69
@Entity
@@ -14,6 +17,9 @@
1417
@Index(name = "player_last_name_IDX", columnList = "last_name")
1518
}
1619
)
20+
@Data
21+
@NoArgsConstructor
22+
@AllArgsConstructor
1723
public class PlayerEntity {
1824

1925
@Id
@@ -26,35 +32,8 @@ public class PlayerEntity {
2632
@Column(name = "last_name", nullable = false, length = 50)
2733
private String lastName;
2834

29-
public PlayerEntity() {
30-
}
31-
3235
public PlayerEntity(String firstName, String lastName) {
3336
this.firstName = firstName;
3437
this.lastName = lastName;
3538
}
36-
37-
public UUID getId() {
38-
return id;
39-
}
40-
41-
public void setId(UUID id) {
42-
this.id = id;
43-
}
44-
45-
public String getFirstName() {
46-
return firstName;
47-
}
48-
49-
public void setFirstName(String firstName) {
50-
this.firstName = firstName;
51-
}
52-
53-
public String getLastName() {
54-
return lastName;
55-
}
56-
57-
public void setLastName(String lastName) {
58-
this.lastName = lastName;
59-
}
6039
}
Lines changed: 4 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.skat.backend.domain.entities;
22

33
import jakarta.persistence.*;
4+
import lombok.Data;
5+
import lombok.NoArgsConstructor;
46
import java.time.OffsetDateTime;
57
import java.util.UUID;
68

@@ -13,6 +15,8 @@
1315
@Index(name = "player_score_sequence_IDX", columnList = "sequence_index")
1416
}
1517
)
18+
@Data
19+
@NoArgsConstructor
1620
public class PlayerScoreEntity {
1721

1822
@Id
@@ -35,55 +39,4 @@ public class PlayerScoreEntity {
3539

3640
@Column(name = "created_at", nullable = false)
3741
private OffsetDateTime createdAt;
38-
39-
public PlayerScoreEntity() {
40-
}
41-
42-
public UUID getId() {
43-
return id;
44-
}
45-
46-
public void setId(UUID id) {
47-
this.id = id;
48-
}
49-
50-
public PlayerEntity getPlayer() {
51-
return player;
52-
}
53-
54-
public void setPlayer(PlayerEntity player) {
55-
this.player = player;
56-
}
57-
58-
public GameEntity getGame() {
59-
return game;
60-
}
61-
62-
public void setGame(GameEntity game) {
63-
this.game = game;
64-
}
65-
66-
public Integer getSequenceIndex() {
67-
return sequenceIndex;
68-
}
69-
70-
public void setSequenceIndex(Integer sequenceIndex) {
71-
this.sequenceIndex = sequenceIndex;
72-
}
73-
74-
public Integer getTotalPoints() {
75-
return totalPoints;
76-
}
77-
78-
public void setTotalPoints(Integer totalPoints) {
79-
this.totalPoints = totalPoints;
80-
}
81-
82-
public OffsetDateTime getCreatedAt() {
83-
return createdAt;
84-
}
85-
86-
public void setCreatedAt(OffsetDateTime createdAt) {
87-
this.createdAt = createdAt;
88-
}
8942
}

0 commit comments

Comments
 (0)