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.patinanetwork.patchats.api.match;

import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.patinanetwork.patchats.api.match.dto.CreateMatchCycleRequest;
import org.patinanetwork.patchats.api.match.dto.MatchCycleResponse;
import org.patinanetwork.patchats.api.match.dto.UpdateMatchCycleRequest;
import org.patinanetwork.patchats.common.dto.ApiResponder;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/admin/match_cycles")
@Tag(name = "Match Cycles")
@RequiredArgsConstructor
public class MatchCycleController {

private final MatchCycleService matchCycleService;

@PostMapping
public ResponseEntity<ApiResponder<MatchCycleResponse>> createMatchCycle(
@Valid @RequestBody final CreateMatchCycleRequest request) {
final MatchCycleResponse response = matchCycleService.createMatchCycle(request);
return ResponseEntity.ok(ApiResponder.success("Match Cycle created successfully", response));
}

@PatchMapping("/{id}")
public ResponseEntity<ApiResponder<MatchCycleResponse>> updateMatchCycle(
@Valid @RequestBody final UpdateMatchCycleRequest request, @PathVariable final Integer id) {
final MatchCycleResponse response = matchCycleService.updateMatchCycle(request, id);
return ResponseEntity.ok(ApiResponder.success("Match Cycle updated successfully", response));
}

@GetMapping("/{id}")
public ResponseEntity<ApiResponder<MatchCycleResponse>> getMatchCycleById(@PathVariable final Integer id) {
final MatchCycleResponse response = matchCycleService.getMatchCycleById(id);
return ResponseEntity.ok(ApiResponder.success("Match Cycle retrieved successfully", response));
}

@DeleteMapping("/{id}")
public ResponseEntity<ApiResponder<MatchCycleResponse>> deleteMatchCycle(@PathVariable final Integer id) {
final MatchCycleResponse response = matchCycleService.deleteMatchCycleById(id);
return ResponseEntity.ok(ApiResponder.success("Match Cycle deleted successfully", response));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package org.patinanetwork.patchats.api.match;

import java.time.Instant;
import java.util.Optional;
import java.util.stream.Stream;
import lombok.RequiredArgsConstructor;
import org.patinanetwork.patchats.api.match.db.models.MatchCycle;
import org.patinanetwork.patchats.api.match.db.repos.MatchCycleRepo;
import org.patinanetwork.patchats.api.match.dto.CreateMatchCycleRequest;
import org.patinanetwork.patchats.api.match.dto.MatchCycleResponse;
import org.patinanetwork.patchats.api.match.dto.UpdateMatchCycleRequest;
import org.patinanetwork.patchats.common.web.exception.MatchCycleDuplicateException;
import org.patinanetwork.patchats.common.web.exception.MatchCycleNotFoundException;
import org.patinanetwork.patchats.common.web.exception.ValidationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class MatchCycleService {

private final MatchCycleRepo matchCycleRepo;

public MatchCycleResponse createMatchCycle(CreateMatchCycleRequest request) {
if (matchCycleRepo.getMatchCycleByPeriod(request.period()).isPresent()) {
throw new MatchCycleDuplicateException(request.period());
}

MatchCycle matchCycle = MatchCycle.builder()
.period(request.period())
.runAt(request.runAt())
.isDraft(request.isDraft())
.build();

try {
MatchCycle createdMatchCycle = matchCycleRepo.createMatchCycle(matchCycle);
return MatchCycleResponse.from(createdMatchCycle);
} catch (DuplicateKeyException e) {

Check warning on line 38 in src/main/java/org/patinanetwork/patchats/api/match/MatchCycleService.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace "e" with an unnamed pattern.

See more on https://sonarcloud.io/project/issues?id=Patina-Network_patchats&issues=AaCSDXw4M4B2wCqo-f-D&open=AaCSDXw4M4B2wCqo-f-D&pullRequest=74
throw new MatchCycleDuplicateException(request.period());
}
}

public MatchCycleResponse updateMatchCycle(UpdateMatchCycleRequest request, Integer id) {
MatchCycle matchCycle =
matchCycleRepo.getMatchCycleById(id).orElseThrow(() -> new MatchCycleNotFoundException(id));

boolean hasNoUpdates =
Stream.of(request.period(), request.runAt(), request.isDraft()).noneMatch(Optional::isPresent);
if (hasNoUpdates) {
return MatchCycleResponse.from(matchCycle);
}

if (request.period().isPresent()) {
String period = request.period().get();
if (period.isBlank()) {
throw new ValidationException("period cannot be empty");
}
matchCycle.setPeriod(period);
}
request.runAt().ifPresent(matchCycle::setRunAt);
request.isDraft().ifPresent(matchCycle::setIsDraft);

try {
MatchCycle updated =
matchCycleRepo.updateMatchCycle(matchCycle).orElseThrow(() -> new MatchCycleNotFoundException(id));
return MatchCycleResponse.from(updated);
} catch (DuplicateKeyException e) {

Check warning on line 67 in src/main/java/org/patinanetwork/patchats/api/match/MatchCycleService.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace "e" with an unnamed pattern.

See more on https://sonarcloud.io/project/issues?id=Patina-Network_patchats&issues=AaBzUQqWqb6JvJKRP6nv&open=AaBzUQqWqb6JvJKRP6nv&pullRequest=74
throw new MatchCycleDuplicateException(request.period().orElse(matchCycle.getPeriod()));
}
}

public MatchCycleResponse setMatchCyclePeriod(Integer id, String period) {
if (period == null || period.isBlank()) {
throw new ValidationException("period cannot be empty");
}
MatchCycle matchCycle =
matchCycleRepo.setMatchCyclePeriod(id, period).orElseThrow(() -> new MatchCycleNotFoundException(id));
return MatchCycleResponse.from(matchCycle);
}

public MatchCycleResponse setMatchCycleRunAt(Integer id, Instant runAt) {
MatchCycle matchCycle =
matchCycleRepo.setMatchCycleRunAt(id, runAt).orElseThrow(() -> new MatchCycleNotFoundException(id));
return MatchCycleResponse.from(matchCycle);
}

public MatchCycleResponse setMatchCycleIsDraft(Integer id, boolean isDraft) {
MatchCycle matchCycle =
matchCycleRepo.setMatchCycleIsDraft(id, isDraft).orElseThrow(() -> new MatchCycleNotFoundException(id));
return MatchCycleResponse.from(matchCycle);
}

public MatchCycleResponse getMatchCycleById(Integer id) {
MatchCycle matchCycle =
matchCycleRepo.getMatchCycleById(id).orElseThrow(() -> new MatchCycleNotFoundException(id));
return MatchCycleResponse.from(matchCycle);
}

public MatchCycleResponse deleteMatchCycleById(Integer id) {
MatchCycle matchCycle =
matchCycleRepo.deleteMatchCycleById(id).orElseThrow(() -> new MatchCycleNotFoundException(id));
return MatchCycleResponse.from(matchCycle);
}

public MatchCycleResponse getMatchCycleByPeriod(String period) {
MatchCycle matchCycle =
matchCycleRepo.getMatchCycleByPeriod(period).orElseThrow(() -> new MatchCycleNotFoundException(period));
return MatchCycleResponse.from(matchCycle);
}

// public MatchCycleResponse filterMatchCycles(MatchCycleFilterCriteria
// criteria) {}

Check warning on line 112 in src/main/java/org/patinanetwork/patchats/api/match/MatchCycleService.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

This block of commented-out lines of code should be removed.

See more on https://sonarcloud.io/project/issues?id=Patina-Network_patchats&issues=AaCSDXw4M4B2wCqo-f-E&open=AaCSDXw4M4B2wCqo-f-E&pullRequest=74
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,18 @@
import lombok.ToString;

@Getter
@Builder
@ToString
@Builder
@EqualsAndHashCode(of = "id")
public class MatchCycle {

private Integer id;

@Setter
private String period;

@Setter
private Instant runAt;

@Setter
private Boolean isDraft;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import java.util.Optional;

public record MatchCycleFilterCriteria(
Optional<String> period, Optional<Instant> startTime, Optional<Instant> endTime) {
Optional<String> period, Optional<Instant> startTime, Optional<Instant> endTime, Optional<Boolean> isDraft) {

public static MatchCycleFilterCriteria empty() {
return new MatchCycleFilterCriteria(Optional.empty(), Optional.empty(), Optional.empty());
return new MatchCycleFilterCriteria(Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty());
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.patinanetwork.patchats.api.match.db.repos;

import java.time.Instant;
import java.util.List;
import java.util.Optional;
import org.patinanetwork.patchats.api.match.db.models.MatchCycle;
Expand All @@ -10,13 +11,12 @@ public interface MatchCycleRepo {
* @note - The provided object's methods will be overridden with any returned data from the database.
* @param matchCycle - required fields:
* <ul>
* <li>runAt
* <li>period
* </ul>
* Optional fields:
* <ul>
* <li>period
* <li>totalMembers
* <li>totalMatched
* <li>runAt
* <li>isDraft
* </ul>
* The id field will be auto-generated by the database.
*/
Expand All @@ -28,14 +28,21 @@ public interface MatchCycleRepo {
* <ul>
* <li>period
* <li>runAt
* <li>totalMembers
* <li>totalMatched
* <li>isDraft
* </ul>
*/
Optional<MatchCycle> updateMatchCycle(MatchCycle matchCycle);

Optional<MatchCycle> getMatchCycleById(Integer id);

Optional<MatchCycle> getMatchCycleByPeriod(String period);

Optional<MatchCycle> setMatchCyclePeriod(Integer id, String period);

Optional<MatchCycle> setMatchCycleRunAt(Integer id, Instant runAt);

Optional<MatchCycle> setMatchCycleIsDraft(Integer id, boolean isDraft);

Optional<MatchCycle> deleteMatchCycleById(Integer id);

List<MatchCycle> filterMatchCycles(MatchCycleFilterCriteria criteria);
Expand Down
Loading
Loading