From 0f9761da3a47ebc92696b069b56f66575c2effa0 Mon Sep 17 00:00:00 2001 From: Teriuihi Date: Fri, 11 Apr 2025 01:12:46 +0200 Subject: [PATCH] Refactor history APIs and integrate LiteBans database support Redesigned history-related APIs to streamline handling of user and UUID punishments, moving from POST to GET endpoints. Added support for LiteBans database with mappers for retrieving punishment records by name and UUID, and implemented global exception handling for better error reporting. Updated schema paths and added enums (UserType, HistoryType) and a new Gradle dependency. --- backend/build.gradle.kts | 1 + .../controllers/GlobalExceptionHandler.java | 19 +++ .../history/HistoryApiController.java | 97 ++++++++++++++- .../alttd/altitudeweb/database/Databases.java | 3 +- .../database/litebans/HistoryRecord.java | 17 +++ .../database/litebans/HistoryType.java | 13 ++ .../database/litebans/NameHistoryMapper.java | 94 +++++++++++++++ .../database/litebans/RecentNamesMapper.java | 74 ++++++++++++ .../database/litebans/UUIDHistoryMapper.java | 96 +++++++++++++++ .../database/litebans/UserType.java | 10 ++ open_api/src/main/resources/api.yml | 4 +- .../src/main/resources/schemas/bans/bans.yml | 112 +++++++++--------- 12 files changed, 475 insertions(+), 65 deletions(-) create mode 100644 backend/src/main/java/com/alttd/altitudeweb/controllers/GlobalExceptionHandler.java create mode 100644 database/src/main/java/com/alttd/altitudeweb/database/litebans/HistoryRecord.java create mode 100644 database/src/main/java/com/alttd/altitudeweb/database/litebans/HistoryType.java create mode 100644 database/src/main/java/com/alttd/altitudeweb/database/litebans/NameHistoryMapper.java create mode 100644 database/src/main/java/com/alttd/altitudeweb/database/litebans/RecentNamesMapper.java create mode 100644 database/src/main/java/com/alttd/altitudeweb/database/litebans/UUIDHistoryMapper.java create mode 100644 database/src/main/java/com/alttd/altitudeweb/database/litebans/UserType.java diff --git a/backend/build.gradle.kts b/backend/build.gradle.kts index 8a10646..d2625f1 100644 --- a/backend/build.gradle.kts +++ b/backend/build.gradle.kts @@ -34,6 +34,7 @@ dependencies { implementation("org.mybatis:mybatis:3.5.13") testRuntimeOnly("org.junit.platform:junit-platform-launcher") implementation("org.springframework.boot:spring-boot-configuration-processor") + implementation("org.springframework.boot:spring-boot-starter-hateoas") } tasks.withType { diff --git a/backend/src/main/java/com/alttd/altitudeweb/controllers/GlobalExceptionHandler.java b/backend/src/main/java/com/alttd/altitudeweb/controllers/GlobalExceptionHandler.java new file mode 100644 index 0000000..17eb4ef --- /dev/null +++ b/backend/src/main/java/com/alttd/altitudeweb/controllers/GlobalExceptionHandler.java @@ -0,0 +1,19 @@ +package com.alttd.altitudeweb.controllers; + +import com.alttd.altitudeweb.model.ApiErrorDto; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; + +@ControllerAdvice +public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { + + @ExceptionHandler(Exception.class) + public ResponseEntity handleException(Exception ex) { + ApiErrorDto error = new ApiErrorDto(); + error.reason("Error: " + ex.getMessage()); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error); + } +} diff --git a/backend/src/main/java/com/alttd/altitudeweb/controllers/history/HistoryApiController.java b/backend/src/main/java/com/alttd/altitudeweb/controllers/history/HistoryApiController.java index 78a51d2..5c0dfc6 100644 --- a/backend/src/main/java/com/alttd/altitudeweb/controllers/history/HistoryApiController.java +++ b/backend/src/main/java/com/alttd/altitudeweb/controllers/history/HistoryApiController.java @@ -1,21 +1,106 @@ package com.alttd.altitudeweb.controllers.history; import com.alttd.altitudeweb.api.HistoryApi; +import com.alttd.altitudeweb.database.Connection; +import com.alttd.altitudeweb.database.Databases; +import com.alttd.altitudeweb.database.litebans.*; +import com.alttd.altitudeweb.model.PunishmentHistoryDto; +import com.alttd.altitudeweb.model.PunishmentHistoryInnerDto; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RestController; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +@Slf4j +@RestController public class HistoryApiController implements HistoryApi { + @Override - public ResponseEntity getHistoryForUsers(String userType, String type, String user) throws Exception { - return null; + public ResponseEntity getHistoryForUsers(String userType, String type, String user) throws Exception { + UserType userTypeEnum = UserType.getUserType(userType); + HistoryType historyTypeEnum = HistoryType.getHistoryType(type); + PunishmentHistoryDto punishmentHistory = new PunishmentHistoryDto(); + CompletableFuture> historyRecords = new CompletableFuture<>(); + Connection.getConnection(Databases.LITE_BANS, configuration -> configuration.addMapper(NameHistoryMapper.class)) + .thenApply(connection -> { + connection.runQuery(sqlSession -> { + log.debug("Loading user names for type {}", type); + List temp = sqlSession.getMapper(NameHistoryMapper.class) + .getRecent(historyTypeEnum, userTypeEnum, user); + historyRecords.complete(temp); + }); + return connection; + }); + historyRecords.join().forEach(historyRecord -> { + PunishmentHistoryInnerDto innerDto = new PunishmentHistoryInnerDto() + .uuid(historyRecord.getUuid()) + .username(historyRecord.getPunishedName()) + .reason(historyRecord.getReason()) + .punishmentUserUuid(historyRecord.getBannedByUuid()) + .punishmentUser(historyRecord.getBannedByName()) + .removedBy(historyRecord.getRemovedByName()) + .punishmentTime(historyRecord.getTime()) + .expiryTime(historyRecord.getUntil()) + .removedReason(historyRecord.getRemovedByReason()) + .type(historyRecord.getType()); + punishmentHistory.add(innerDto); + }); + + return ResponseEntity.ok().body(punishmentHistory); } @Override - public ResponseEntity getHistoryForUuid(String userType, String type, String uuid) throws Exception { - return null; + public ResponseEntity getHistoryForUuid(String userType, String type, String uuid) throws Exception { + UserType userTypeEnum = UserType.getUserType(userType); + HistoryType historyTypeEnum = HistoryType.getHistoryType(type); + PunishmentHistoryDto punishmentHistory = new PunishmentHistoryDto(); + CompletableFuture> historyRecords = new CompletableFuture<>(); + Connection.getConnection(Databases.LITE_BANS, configuration -> configuration.addMapper(UUIDHistoryMapper.class)) + .thenApply(connection -> { + connection.runQuery(sqlSession -> { + log.debug("Loading user names for type {}", type); + List temp = sqlSession.getMapper(UUIDHistoryMapper.class) + .getRecent(historyTypeEnum, userTypeEnum, UUID.fromString(uuid)); + historyRecords.complete(temp); + }); + return connection; + }); + historyRecords.join().forEach(historyRecord -> { + PunishmentHistoryInnerDto innerDto = new PunishmentHistoryInnerDto() + .uuid(historyRecord.getUuid()) + .username(historyRecord.getPunishedName()) + .reason(historyRecord.getReason()) + .punishmentUserUuid(historyRecord.getBannedByUuid()) + .punishmentUser(historyRecord.getBannedByName()) + .removedBy(historyRecord.getRemovedByName()) + .punishmentTime(historyRecord.getTime()) + .expiryTime(historyRecord.getUntil()) + .removedReason(historyRecord.getRemovedByReason()) + .type(historyRecord.getType()); + punishmentHistory.add(innerDto); + }); + + return ResponseEntity.ok().body(punishmentHistory); } @Override - public ResponseEntity getUserNames(String userType, String type) throws Exception { - return null; + public ResponseEntity> getUserNames(String userType, String type) { + UserType userTypeEnum = UserType.getUserType(userType); + HistoryType historyTypeEnum = HistoryType.getHistoryType(type); + CompletableFuture> playerGroupFuture = new CompletableFuture<>(); + Connection.getConnection(Databases.LITE_BANS, configuration -> configuration.addMapper(RecentNamesMapper.class)) + .thenApply(connection -> { + connection.runQuery(sqlSession -> { + log.debug("Loading user names for type {}", type); + List temp = sqlSession.getMapper(RecentNamesMapper.class) + .getRecent(historyTypeEnum, userTypeEnum); + playerGroupFuture.complete(temp); + }); + return connection; + }); + return ResponseEntity.ok().body(playerGroupFuture.join()); } } diff --git a/database/src/main/java/com/alttd/altitudeweb/database/Databases.java b/database/src/main/java/com/alttd/altitudeweb/database/Databases.java index 8656a51..bf76977 100644 --- a/database/src/main/java/com/alttd/altitudeweb/database/Databases.java +++ b/database/src/main/java/com/alttd/altitudeweb/database/Databases.java @@ -5,7 +5,8 @@ import lombok.Getter; @Getter public enum Databases { DEFAULT("web_db"), - LUCK_PERMS("luckperms"); + LUCK_PERMS("luckperms"), + LITE_BANS("litebans"); private final String internalName; diff --git a/database/src/main/java/com/alttd/altitudeweb/database/litebans/HistoryRecord.java b/database/src/main/java/com/alttd/altitudeweb/database/litebans/HistoryRecord.java new file mode 100644 index 0000000..52f5b34 --- /dev/null +++ b/database/src/main/java/com/alttd/altitudeweb/database/litebans/HistoryRecord.java @@ -0,0 +1,17 @@ +package com.alttd.altitudeweb.database.litebans; + +import lombok.Data; + +@Data +public class HistoryRecord { + private String uuid; + private String punishedName; + private String reason; + private String bannedByUuid; + private String bannedByName; + private String removedByName; + private Long time; + private Long until; + private String removedByReason; + private String type; +} diff --git a/database/src/main/java/com/alttd/altitudeweb/database/litebans/HistoryType.java b/database/src/main/java/com/alttd/altitudeweb/database/litebans/HistoryType.java new file mode 100644 index 0000000..fa708f6 --- /dev/null +++ b/database/src/main/java/com/alttd/altitudeweb/database/litebans/HistoryType.java @@ -0,0 +1,13 @@ +package com.alttd.altitudeweb.database.litebans; + +public enum HistoryType { + ALL, + BANS, + MUTES, + KICKS, + WARNS; + + public static HistoryType getHistoryType(String historyType) { + return HistoryType.valueOf(historyType.toUpperCase()); + } +} diff --git a/database/src/main/java/com/alttd/altitudeweb/database/litebans/NameHistoryMapper.java b/database/src/main/java/com/alttd/altitudeweb/database/litebans/NameHistoryMapper.java new file mode 100644 index 0000000..f65826c --- /dev/null +++ b/database/src/main/java/com/alttd/altitudeweb/database/litebans/NameHistoryMapper.java @@ -0,0 +1,94 @@ +package com.alttd.altitudeweb.database.litebans; + +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Result; +import org.apache.ibatis.annotations.Results; +import org.apache.ibatis.annotations.Select; + +import java.util.ArrayList; +import java.util.List; + +public interface NameHistoryMapper { + @Results({ + @Result(property = "uuid", column = "uuid"), + @Result(property = "punishedName", column = "punished_name"), + @Result(property = "reason", column = "reason"), + @Result(property = "bannedByUuid", column = "banned_by_uuid"), + @Result(property = "bannedByName", column = "banned_by_name"), + @Result(property = "removedByName", column = "removed_by_name"), + @Result(property = "time", column = "time"), + @Result(property = "until", column = "until"), + @Result(property = "removedByReason", column = "removed_by_reason") + }) + @Select(""" + SELECT punishment.uuid, user_table.name AS punished_name, reason, banned_by_uuid, banned_by_name, + removed_by_name, time, until, removed_by_reason + FROM ${tableName} AS punishment + INNER JOIN ( + SELECT history_1.uuid, history_1.name + FROM litebans.litebans_history history_1 + INNER JOIN ( + SELECT uuid, MAX(id) as max_id + FROM litebans.litebans_history + GROUP BY uuid + ) history_2 ON history_1.uuid = history_2.uuid AND history_1.id = history_2.max_id + ) AS user_table ON punishment.uuid = user_table.uuid + WHERE LOWER(punishment.${name_column}) LIKE #{partialName} + """) + List getRecentHistory(@Param("tableName") String tableName, @Param("partialName") String partialName, + @Param("name_column") String nameColumn); + + default List getRecent(HistoryType historyType, UserType userType, String partialName) { + return switch (historyType) { + case ALL -> getRecentAll(userType, partialName); + case BANS -> getRecentBans(userType, partialName); + case MUTES -> getRecentMutes(userType, partialName); + case KICKS -> getRecentKicks(userType, partialName); + case WARNS -> getRecentWarns(userType, partialName); + }; + } + + private List getRecent(String tableName, UserType userType, String partialName) { + switch (userType) { + case PLAYER -> { + return getRecentHistory(tableName, partialName.toLowerCase() + "%", "name"); + } + case STAFF -> { + return getRecentHistory(tableName, partialName.toLowerCase() + "%", "banned_by_name"); + } + default -> throw new IllegalArgumentException("Invalid user type"); + } + } + + private List getRecentBans(UserType userType, String partialName) { + return addType(getRecent("litebans_bans", userType, partialName), "ban"); + } + + private List getRecentKicks(UserType userType, String partialName) { + return addType(getRecent("litebans_kicks", userType, partialName), "kick"); + } + + private List getRecentMutes(UserType userType, String partialName) { + return addType(getRecent("litebans_mutes", userType, partialName), "mute"); + } + + private List getRecentWarns(UserType userType, String partialName) { + return addType(getRecent("litebans_warnings", userType, partialName), "warn"); + } + + private List getRecentAll(UserType userType, String partialName) { + List all = new ArrayList<>(); + all.addAll(getRecentBans(userType, partialName)); + // Removed recent kicks as we do not show those +// all.addAll(getRecentKicks(userType, partialName)); + all.addAll(getRecentMutes(userType, partialName)); + all.addAll(getRecentWarns(userType, partialName)); + return all; + } + + private List addType(List historyRecords, String type) { + historyRecords.forEach(historyRecord -> historyRecord.setType(type)); + return historyRecords; + } + +} diff --git a/database/src/main/java/com/alttd/altitudeweb/database/litebans/RecentNamesMapper.java b/database/src/main/java/com/alttd/altitudeweb/database/litebans/RecentNamesMapper.java new file mode 100644 index 0000000..4085c1f --- /dev/null +++ b/database/src/main/java/com/alttd/altitudeweb/database/litebans/RecentNamesMapper.java @@ -0,0 +1,74 @@ +package com.alttd.altitudeweb.database.litebans; + +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.ArrayList; +import java.util.List; + +public interface RecentNamesMapper { + @Select(""" + SELECT DISTINCT user_table.name AS punished_name + FROM ${tableName} AS punishment + INNER JOIN ( + SELECT history_1.uuid, history_1.name + FROM litebans.litebans_history history_1 + INNER JOIN ( + SELECT uuid, MAX(id) as max_id + FROM litebans.litebans_history + GROUP BY uuid + ) history_2 ON history_1.uuid = history_2.uuid AND history_1.id = history_2.max_id + ) AS user_table ON punishment.${uuid_column} = user_table.uuid + WHERE punishment.time > UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 1 YEAR)) * 1000 + """) + List getRecentHistory(@Param("tableName") String tableName, @Param("uuid_column") String uuidColumn); + + default List getRecent(HistoryType historyType, UserType userType) { + return switch (historyType) { + case ALL -> getRecentAll(userType); + case BANS -> getRecentBans(userType); + case MUTES -> getRecentMutes(userType); + case KICKS -> getRecentKicks(userType); + case WARNS -> getRecentWarns(userType); + }; + } + + private List getRecent(String tableName, UserType userType) { + switch (userType) { + case PLAYER -> { + return getRecentHistory(tableName, "uuid"); + } + case STAFF -> { + return getRecentHistory(tableName, "banned_by_uuid"); + } + default -> throw new IllegalArgumentException("Invalid user type"); + } + } + + private List getRecentBans(UserType userType) { + return getRecent("litebans_bans", userType); + } + + private List getRecentKicks(UserType userType) { + return getRecent("litebans_kicks", userType); + } + + private List getRecentMutes(UserType userType) { + return getRecent("litebans_mutes", userType); + } + + private List getRecentWarns(UserType userType) { + return getRecent("litebans_warnings", userType); + } + + private List getRecentAll(UserType userType) { + List all = new ArrayList<>(); + all.addAll(getRecentBans(userType)); + // Removed recent kicks as we do not show those +// all.addAll(getRecentKicks(userType)); + all.addAll(getRecentMutes(userType)); + all.addAll(getRecentWarns(userType)); + return all; + } + +} diff --git a/database/src/main/java/com/alttd/altitudeweb/database/litebans/UUIDHistoryMapper.java b/database/src/main/java/com/alttd/altitudeweb/database/litebans/UUIDHistoryMapper.java new file mode 100644 index 0000000..d48f0d5 --- /dev/null +++ b/database/src/main/java/com/alttd/altitudeweb/database/litebans/UUIDHistoryMapper.java @@ -0,0 +1,96 @@ +package com.alttd.altitudeweb.database.litebans; + +import com.alttd.altitudeweb.type_handler.UUIDTypeHandler; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Result; +import org.apache.ibatis.annotations.Results; +import org.apache.ibatis.annotations.Select; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public interface UUIDHistoryMapper { + @Results({ + @Result(property = "uuid", column = "uuid", javaType = UUID.class, typeHandler = UUIDTypeHandler.class), + @Result(property = "punishedName", column = "punished_name"), + @Result(property = "reason", column = "reason"), + @Result(property = "bannedByUuid", column = "banned_by_uuid", javaType = UUID.class, typeHandler = UUIDTypeHandler.class), + @Result(property = "bannedByName", column = "banned_by_name"), + @Result(property = "removedByName", column = "removed_by_name"), + @Result(property = "time", column = "time"), + @Result(property = "until", column = "until"), + @Result(property = "removedByReason", column = "removed_by_reason") + }) + @Select(""" + SELECT punishment.uuid, user_table.name AS punished_name, reason, banned_by_uuid, banned_by_name, + removed_by_name, time, until, removed_by_reason + FROM ${tableName} AS punishment + INNER JOIN ( + SELECT history_1.uuid, history_1.name + FROM litebans.litebans_history history_1 + INNER JOIN ( + SELECT uuid, MAX(id) as max_id + FROM litebans.litebans_history + GROUP BY uuid + ) history_2 ON history_1.uuid = history_2.uuid AND history_1.id = history_2.max_id + ) AS user_table ON punishment.uuid = user_table.uuid + WHERE punishment.uuid = #{uuid} + """) + List getRecentHistory(@Param("tableName") String tableName, @Param("uuid") String uuid, + @Param("uuid_column") String uuidColumn); + + default List getRecent(HistoryType historyType, UserType userType, UUID uuid) { + return switch (historyType) { + case ALL -> getRecentAll(userType, uuid); + case BANS -> getRecentBans(userType, uuid); + case MUTES -> getRecentMutes(userType, uuid); + case KICKS -> getRecentKicks(userType, uuid); + case WARNS -> getRecentKicks(userType, uuid); + }; + } + + private List getRecent(String tableName, UserType userType, UUID uuid) { + switch (userType) { + case PLAYER -> { + return getRecentHistory(tableName, uuid.toString(), "uuid"); + } + case STAFF -> { + return getRecentHistory(tableName, uuid.toString(), "banned_by_uuid"); + } + default -> throw new IllegalArgumentException("Invalid user type"); + } + } + + private List getRecentBans(UserType userType, UUID uuid) { + return addType(getRecent("litebans_bans", userType, uuid), "ban"); + } + + private List getRecentKicks(UserType userType, UUID uuid) { + return addType(getRecent("litebans_kicks", userType, uuid), "kick"); + } + + private List getRecentMutes(UserType userType, UUID uuid) { + return addType(getRecent("litebans_mutes", userType, uuid), "mute"); + } + + private List getRecentWarns(UserType userType, UUID uuid) { + return addType(getRecent("litebans_warnings", userType, uuid), "warn"); + } + + private List getRecentAll(UserType userType, UUID uuid) { + List all = new ArrayList<>(); + all.addAll(getRecentBans(userType, uuid)); + // Removed recent kicks as we do not show those +// all.addAll(getRecentKicks(userType, uuid)); + all.addAll(getRecentMutes(userType, uuid)); + all.addAll(getRecentWarns(userType, uuid)); + return all; + } + + private List addType(List historyRecords, String type) { + historyRecords.forEach(historyRecord -> historyRecord.setType(type)); + return historyRecords; + } + +} diff --git a/database/src/main/java/com/alttd/altitudeweb/database/litebans/UserType.java b/database/src/main/java/com/alttd/altitudeweb/database/litebans/UserType.java new file mode 100644 index 0000000..326a2cb --- /dev/null +++ b/database/src/main/java/com/alttd/altitudeweb/database/litebans/UserType.java @@ -0,0 +1,10 @@ +package com.alttd.altitudeweb.database.litebans; + +public enum UserType { + PLAYER, + STAFF; + + public static UserType getUserType(String userType) { + return UserType.valueOf(userType.toUpperCase()); + } +} diff --git a/open_api/src/main/resources/api.yml b/open_api/src/main/resources/api.yml index cfbb434..a6726e1 100644 --- a/open_api/src/main/resources/api.yml +++ b/open_api/src/main/resources/api.yml @@ -16,7 +16,7 @@ paths: $ref: './schemas/team/team.yml#/getTeam' /history/{userType}/search/{type}: $ref: './schemas/bans/bans.yml#/getUserNames' - /history/{userType}/{type}/{user}: + /history/{userType}/name/{type}/{user}: $ref: './schemas/bans/bans.yml#/getHistoryForUsers' - /history/{userType}/{type}/{uuid}: + /history/{userType}/uuid/{type}/{uuid}: $ref: './schemas/bans/bans.yml#/getHistoryForUuid' diff --git a/open_api/src/main/resources/schemas/bans/bans.yml b/open_api/src/main/resources/schemas/bans/bans.yml index 888093b..5bbda03 100644 --- a/open_api/src/main/resources/schemas/bans/bans.yml +++ b/open_api/src/main/resources/schemas/bans/bans.yml @@ -1,31 +1,31 @@ getUserNames: - post: + get: tags: - history summary: Get user names description: Get all user names with punishment history of the specified type operationId: getUserNames - parameters: - - $ref: '#/components/parameters/UserType' - - $ref: '#/components/parameters/HistoryType' - responses: - '200': - description: Successful operation - content: - application/json: - schema: - type: array - items: - type: string - description: A list of users - default: - description: Unexpected error - content: - application/json: - schema: - $ref: "../generic/errors.yml#/components/schemas/ApiError" + parameters: + - $ref: '#/components/parameters/UserType' + - $ref: '#/components/parameters/HistoryType' + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + type: string + description: A list of users + default: + description: Unexpected error + content: + application/json: + schema: + $ref: "../generic/errors.yml#/components/schemas/ApiError" getHistoryForUsers: - post: + get: tags: - history summary: Get history for users @@ -33,25 +33,25 @@ getHistoryForUsers: Get all users with punishment history of the specified type, where the user name starts with the search query operationId: getHistoryForUsers - parameters: - - $ref: '#/components/parameters/UserType' - - $ref: '#/components/parameters/HistoryType' - - $ref: '#/components/parameters/User' - responses: - '200': - description: Successful operation - content: - application/json: - schema: - $ref: '#/components/schemas/PunishmentHistory' - default: - description: Unexpected error - content: - application/json: - schema: - $ref: "../generic/errors.yml#/components/schemas/ApiError" + parameters: + - $ref: '#/components/parameters/UserType' + - $ref: '#/components/parameters/HistoryType' + - $ref: '#/components/parameters/User' + responses: + '200': + description: Successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/PunishmentHistory' + default: + description: Unexpected error + content: + application/json: + schema: + $ref: "../generic/errors.yml#/components/schemas/ApiError" getHistoryForUuid: - post: + get: tags: - history summary: Get user @@ -59,23 +59,23 @@ getHistoryForUuid: Get all users with punishment history of the specified type, where the user uuid matches operationId: getHistoryForUuid - parameters: - - $ref: '#/components/parameters/UserType' - - $ref: '#/components/parameters/HistoryType' - - $ref: '#/components/parameters/Uuid' - responses: - '200': - description: Successful operation - content: - application/json: - schema: - $ref: '#/components/schemas/PunishmentHistory' - default: - description: Unexpected error - content: - application/json: - schema: - $ref: "../generic/errors.yml#/components/schemas/ApiError" + parameters: + - $ref: '#/components/parameters/UserType' + - $ref: '#/components/parameters/HistoryType' + - $ref: '#/components/parameters/Uuid' + responses: + '200': + description: Successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/PunishmentHistory' + default: + description: Unexpected error + content: + application/json: + schema: + $ref: "../generic/errors.yml#/components/schemas/ApiError" components: parameters: HistoryType: