From 7dfcc45b2ef29769f25d979d4ea8d888939d4deb Mon Sep 17 00:00:00 2001 From: "Brian M. Long" Date: Mon, 27 May 2024 12:44:45 -0400 Subject: [PATCH] added round API --- .../com/poststats/golf/rs/api/RoundApi.java | 44 +++++++++++++++++ .../com/poststats/golf/rs/api/RoundsApi.java | 38 +++++++++++++++ .../golf/rs/api/model/BaseRound.java | 48 +++++++++++++++++++ .../golf/rs/api/model/ReferenceableRound.java | 9 ++++ .../poststats/golf/rs/api/model/Round.java | 48 +++++++++++++++++++ 5 files changed, 187 insertions(+) create mode 100644 src/main/java/com/poststats/golf/rs/api/RoundApi.java create mode 100644 src/main/java/com/poststats/golf/rs/api/RoundsApi.java create mode 100644 src/main/java/com/poststats/golf/rs/api/model/BaseRound.java create mode 100644 src/main/java/com/poststats/golf/rs/api/model/ReferenceableRound.java create mode 100644 src/main/java/com/poststats/golf/rs/api/model/Round.java diff --git a/src/main/java/com/poststats/golf/rs/api/RoundApi.java b/src/main/java/com/poststats/golf/rs/api/RoundApi.java new file mode 100644 index 0000000..08f724f --- /dev/null +++ b/src/main/java/com/poststats/golf/rs/api/RoundApi.java @@ -0,0 +1,44 @@ +package com.poststats.golf.rs.api; + +import java.math.BigInteger; + +import com.poststats.golf.rs.api.model.Round; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.security.RolesAllowed; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.PUT; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; + +/** + * @author brian.long@poststats.com + */ +@Path("/golf/round/{roundId}") +@Tag(name = "Round API") +@ApiResponses({ + @ApiResponse(responseCode = "200", description = "Success"), + @ApiResponse(responseCode = "404", description = "A round with the specified ID could not be found") +}) +public interface RoundApi { + + @GET + @Produces(Constants.V1_JSON) + @Operation(summary = "Retrieves limited meta-data about a round.") + Round get(@NotNull @Positive @PathParam("roundId") BigInteger roundId); + + @PUT + @Path("/recompute") + @RolesAllowed(Constants.ADMIN_ROLE) + @SecurityRequirement(name = "basic") + @Operation(summary = "Recomputes a round's score and its impact on leaderboards and future handicaps.") + void recompute(@NotNull @Positive @PathParam("roundId") BigInteger roundId); + +} diff --git a/src/main/java/com/poststats/golf/rs/api/RoundsApi.java b/src/main/java/com/poststats/golf/rs/api/RoundsApi.java new file mode 100644 index 0000000..ac6717c --- /dev/null +++ b/src/main/java/com/poststats/golf/rs/api/RoundsApi.java @@ -0,0 +1,38 @@ +package com.poststats.golf.rs.api; + +import java.util.List; + +import com.poststats.golf.rs.api.model.Round; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; + +/** + * @author brian.long@poststats.com + */ +@Path("/golf/rounds") +@Tag(name = "Round API") +@ApiResponses({ + @ApiResponse(responseCode = "200", description = "Success"), + @ApiResponse(responseCode = "400", description = "A query parameter is not valid"), + @ApiResponse(responseCode = "404", description = "No matching rounds were found") +}) +public interface RoundsApi { + + // FIXME String to LocalDate + @GET + @Path("/byDate") + @Produces(Constants.V1_JSON) + @Operation(summary = "Finds rounds before a date.", description = "Searches for rounds by date, exclusive.") + List findByDate(@NotNull @Positive @QueryParam("personId") long personId, + @QueryParam("cutoffDate") String cutoffDate); + +} diff --git a/src/main/java/com/poststats/golf/rs/api/model/BaseRound.java b/src/main/java/com/poststats/golf/rs/api/model/BaseRound.java new file mode 100644 index 0000000..7ebc396 --- /dev/null +++ b/src/main/java/com/poststats/golf/rs/api/model/BaseRound.java @@ -0,0 +1,48 @@ +package com.poststats.golf.rs.api.model; + +import java.time.LocalDate; +import java.time.LocalTime; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.poststats.rs.api.annotation.MapEntry; +import com.poststats.rs.api.model.BaseModel; + +@JsonIgnoreProperties(ignoreUnknown = true) +public abstract class BaseRound> extends BaseModel { + + @JsonProperty + @MapEntry + private LocalDate teedate; + + @JsonProperty + @MapEntry + private LocalTime teetime; + + public LocalDate getTeedate() { + return teedate; + } + + public void setTeedate(LocalDate teedate) { + this.teedate = teedate; + } + + public LocalTime getTeetime() { + return teetime; + } + + public void setTeetime(LocalTime teetime) { + this.teetime = teetime; + } + + public ConcreteT withTeedate(LocalDate teedate) { + this.teedate = teedate; + return this.withThis(); + } + + public ConcreteT withTeetime(LocalTime teetime) { + this.teetime = teetime; + return this.withThis(); + } + +} diff --git a/src/main/java/com/poststats/golf/rs/api/model/ReferenceableRound.java b/src/main/java/com/poststats/golf/rs/api/model/ReferenceableRound.java new file mode 100644 index 0000000..cfb0c14 --- /dev/null +++ b/src/main/java/com/poststats/golf/rs/api/model/ReferenceableRound.java @@ -0,0 +1,9 @@ +package com.poststats.golf.rs.api.model; + +import java.math.BigInteger; + +public interface ReferenceableRound { + + BigInteger getId(); + +} diff --git a/src/main/java/com/poststats/golf/rs/api/model/Round.java b/src/main/java/com/poststats/golf/rs/api/model/Round.java new file mode 100644 index 0000000..1db9771 --- /dev/null +++ b/src/main/java/com/poststats/golf/rs/api/model/Round.java @@ -0,0 +1,48 @@ +package com.poststats.golf.rs.api.model; + +import java.math.BigInteger; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonProperty.Access; +import com.poststats.rs.api.annotation.MapEntry; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class Round extends BaseRound implements ReferenceableRound { + + @JsonProperty(required = true, access = Access.READ_ONLY) + @MapEntry("roundID") + private BigInteger roundId; + + @JsonProperty + @MapEntry + private Golfer golfer; + + @Override + public BigInteger getId() { + return roundId; + } + + public void setId(BigInteger roundId) { + this.roundId = roundId; + } + + public Golfer getGolfer() { + return golfer; + } + + public void setGolfer(Golfer golfer) { + this.golfer = golfer; + } + + public Round withId(BigInteger roundId) { + this.roundId = roundId; + return this; + } + + public Round withGolfer(Golfer golfer) { + this.golfer = golfer; + return this; + } + +}