Skip to content

853: create /leaderboard/current endpoint#863

Open
luoh00 wants to merge 4 commits intomainfrom
853
Open

853: create /leaderboard/current endpoint#863
luoh00 wants to merge 4 commits intomainfrom
853

Conversation

@luoh00
Copy link
Collaborator

@luoh00 luoh00 commented Mar 17, 2026

853

Description of changes

Added /leaderboard/current endpoint in admin route to update current leaderboard

Checklist before review

  • I have done a thorough self-review of the PR
  • Copilot has reviewed my latest changes, and all comments have been fixed and/or closed.
  • If I have made database changes, I have made sure I followed all the db repo rules listed in the wiki here. (check if no db changes)
  • All tests have passed
  • I have successfully deployed this PR to staging
  • I have done manual QA in both dev (and staging if possible) and attached screenshots below.

Screenshots

Dev

Screen.Recording.2026-03-17.at.7.45.33.PM.mov

Staging

Screen.Recording.2026-03-18.at.7.51.07.PM.mov

@github-actions
Copy link
Contributor

Available PR Commands

  • /ai - Triggers all AI review commands at once
  • /review - AI review of the PR changes
  • /describe - AI-powered description of the PR
  • /improve - AI-powered suggestions
  • /deploy - Deploy to staging

See: https://github.com/tahminator/codebloom/wiki/CI-Commands

@github-actions
Copy link
Contributor

Title

853: create /leaderboard/current endpoint


PR Type

Enhancement


Description

  • Adds admin endpoint to update current leaderboard.

  • Introduces DTO for leaderboard update request validation.

  • Updates leaderboard name, expiration, and syntax language.

  • Modifies repository to persist leaderboard expiration.


Diagram Walkthrough

flowchart LR
  AdminController["AdminController"] -- "Handles PUT /leaderboard/current" --> EditLeaderboardBody["EditLeaderboardBody (Validation)"];
  EditLeaderboardBody -- "Validated data" --> AdminController;
  AdminController -- "Updates Leaderboard via" --> LeaderboardSqlRepository["LeaderboardSqlRepository"];
  LeaderboardSqlRepository -- "Persists changes" --> Database["Database"];
Loading

File Walkthrough

Relevant files
Enhancement
AdminController.java
Add endpoint for current leaderboard updates                         

src/main/java/org/patinanetwork/codebloom/api/admin/AdminController.java

  • Added a new PUT /leaderboard/current endpoint for admin users.
  • Implemented validation for admin session and the EditLeaderboardBody
    request.
  • Retrieves the current leaderboard, constructs an updated Leaderboard
    object, and persists changes.
  • Consolidated import statements for body classes and Spring
    annotations.
+28/-10 
EditLeaderboardBody.java
Introduce DTO for leaderboard update requests                       

src/main/java/org/patinanetwork/codebloom/api/admin/body/EditLeaderboardBody.java

  • Created a new DTO EditLeaderboardBody for updating leaderboard
    details.
  • Includes fields for name, shouldExpireBy, and
    syntaxHighlightingLanguage.
  • Implemented a validate() method to ensure name length, future
    shouldExpireBy date, and non-empty syntaxHighlightingLanguage.
+51/-0   
LeaderboardSqlRepository.java
Update SQL to include leaderboard expiration                         

src/main/java/org/patinanetwork/codebloom/common/db/repos/leaderboard/LeaderboardSqlRepository.java

  • Modified the updateLeaderboard SQL query to include the shouldExpireBy
    field.
  • Updated the NamedPreparedStatement to bind the shouldExpireBy
    parameter.
+2/-0     

@github-actions
Copy link
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

**🎫 Ticket compliance analysis **

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Missing Annotation

The EditLeaderboardBody class is missing the @Jacksonized annotation. According to the "Database Repository Best Practices" section, this annotation is required for classes that are deserialized from JSON into Java objects, which applies to request bodies.

@Getter
@Builder
@AllArgsConstructor
@ToString
public class EditLeaderboardBody {
Error Handling

The editLeaderboardBody.validate() method throws a ValidationException. If there isn't a global exception handler configured to map ValidationException to an appropriate HTTP status code (e.g., 400 Bad Request), this could result in a generic 500 Internal Server Error for invalid input.

editLeaderboardBody.validate();
Edge Case Handling

If no current leaderboard is found (i.e., leaderboardRepository.getRecentLeaderboardMetadata() returns an empty Optional), the endpoint still returns a 200 OK success response, even though no update occurred. It might be more appropriate to return a 404 Not Found or a more specific message indicating that no leaderboard was available to update.

    Optional<Leaderboard> currentLeaderboard = leaderboardRepository.getRecentLeaderboardMetadata();
    currentLeaderboard.ifPresent(lb -> {
        OffsetDateTime shouldExpireBy =
                StandardizedOffsetDateTime.normalize(editLeaderboardBody.getShouldExpireBy());

        Leaderboard updated = Leaderboard.builder()
                .name(editLeaderboardBody.getName())
                .deletedAt(lb.getDeletedAt())
                .createdAt(lb.getCreatedAt())
                .shouldExpireBy(Optional.of(shouldExpireBy).map(d -> d.toLocalDateTime()))
                .syntaxHighlightingLanguage(Optional.of(editLeaderboardBody.getSyntaxHighlightingLanguage()))
                .id(lb.getId())
                .build();

        leaderboardRepository.updateLeaderboard(updated);
    });

    return ResponseEntity.ok().body(ApiResponder.success("Leaderboard updated successfully", Empty.of()));
}

@github-actions
Copy link
Contributor

Title

853: create /leaderboard/current endpoint


PR Type

Enhancement


Description

  • Add admin endpoint to update current leaderboard

  • Introduce request body for leaderboard updates

  • Update leaderboard expiration and syntax language

  • Include unit tests for new functionality


Diagram Walkthrough

flowchart LR
  AdminController -- "PUT /leaderboard/current" --> EditLeaderboardBody["Validate Request Body"]
  EditLeaderboardBody --> LeaderboardRepository["Get & Update Leaderboard"]
  LeaderboardRepository --> AdminController["Return Success"]
Loading

File Walkthrough

Relevant files
Api endpoint
AdminController.java
Add PUT endpoint for current leaderboard                                 

src/main/java/org/patinanetwork/codebloom/api/admin/AdminController.java

  • Added @PutMapping annotation and wildcard import for admin body
    classes.
  • Implemented editCurrentLeaderboard endpoint to update the current
    leaderboard.
  • Validates admin session and EditLeaderboardBody content.
  • Updates leaderboard's name, expiration, and syntax highlighting
    language.
+28/-10 
New feature
EditLeaderboardBody.java
Define request body for leaderboard updates                           

src/main/java/org/patinanetwork/codebloom/api/admin/body/EditLeaderboardBody.java

  • Created new class EditLeaderboardBody for leaderboard update requests.
  • Defines fields for name, shouldExpireBy, and
    syntaxHighlightingLanguage.
  • Includes a validate() method to enforce constraints on name length and
    future expiration date.
+51/-0   
Database
LeaderboardSqlRepository.java
Update leaderboard with expiration date                                   

src/main/java/org/patinanetwork/codebloom/common/db/repos/leaderboard/LeaderboardSqlRepository.java

  • Modified the updateLeaderboard SQL query.
  • Added shouldExpireBy field to the UPDATE statement.
  • Included shouldExpireBy in the NamedPreparedStatement parameters.
+2/-0     
Tests
AdminControllerTest.java
Add test for current leaderboard update                                   

src/test/java/org/patinanetwork/codebloom/api/admin/AdminControllerTest.java

  • Added EditLeaderboardBody and StandardizedOffsetDateTime imports.
  • Implemented testEditCurrentLeaderboardSuccess unit test.
  • Mocks repository calls and verifies the editCurrentLeaderboard
    endpoint's success.
+21/-0   

@github-actions
Copy link
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

**🎫 Ticket compliance analysis **

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Missing Documentation

The new /leaderboard/current endpoint lacks Swagger annotations such as @Operation and @ApiResponse. These are crucial for auto-generating API documentation and ensuring clarity for API consumers.

@PutMapping("/leaderboard/current")
public ResponseEntity<ApiResponder<Empty>> editCurrentLeaderboard(
        @RequestBody final EditLeaderboardBody editLeaderboardBody, final HttpServletRequest request) {
    protector.validateAdminSession(request);
    editLeaderboardBody.validate();

    Optional<Leaderboard> currentLeaderboard = leaderboardRepository.getRecentLeaderboardMetadata();
    currentLeaderboard.ifPresent(lb -> {
        OffsetDateTime shouldExpireBy =
                StandardizedOffsetDateTime.normalize(editLeaderboardBody.getShouldExpireBy());

        Leaderboard updated = Leaderboard.builder()
                .name(editLeaderboardBody.getName())
                .deletedAt(lb.getDeletedAt())
                .createdAt(lb.getCreatedAt())
                .shouldExpireBy(Optional.ofNullable(shouldExpireBy).map(d -> d.toLocalDateTime()))
                .syntaxHighlightingLanguage(Optional.of(editLeaderboardBody.getSyntaxHighlightingLanguage()))
                .id(lb.getId())
                .build();

        leaderboardRepository.updateLeaderboard(updated);
    });

    return ResponseEntity.ok().body(ApiResponder.success("Leaderboard updated successfully", Empty.of()));
}
Incomplete Test

The testEditCurrentLeaderboardSuccess test does not mock the interactions with leaderboardRepository.getRecentLeaderboardMetadata() and leaderboardRepository.updateLeaderboard(). This means the test currently only verifies the admin session validation and the ApiResponder structure, but not the actual logic of fetching and updating the leaderboard within the controller.

@Test
void testEditCurrentLeaderboardSuccess() {
    OffsetDateTime date = StandardizedOffsetDateTime.normalize(OffsetDateTime.parse("4096-01-01T00:00:00Z"));

    EditLeaderboardBody body = EditLeaderboardBody.builder()
            .name("std::string name = new lb")
            .syntaxHighlightingLanguage("cpp")
            .shouldExpireBy(date)
            .build();

    ResponseEntity<ApiResponder<Empty>> response = adminController.editCurrentLeaderboard(body, request);
    assertEquals(HttpStatus.OK, response.getStatusCode());
    assertNotNull(response.getBody());
    assertTrue(response.getBody().isSuccess());
    assertEquals("Leaderboard updated successfully", response.getBody().getMessage());

    verify(protector).validateAdminSession(request);
}
Wildcard Imports

The PR introduces wildcard imports (import org.patinanetwork.codebloom.api.admin.body.*; and import org.springframework.web.bind.annotation.*;). While functional, it's generally recommended to use specific imports for better code readability and to prevent potential naming conflicts, aligning with the existing pattern in the file.

import org.patinanetwork.codebloom.api.admin.body.*;

@github-actions
Copy link
Contributor

Title

853: create /leaderboard/current endpoint


PR Type

Enhancement, Tests


Description

  • Adds admin endpoint to update current leaderboard.

  • Validates leaderboard name and expiration date.

  • Updates database repository for leaderboard changes.

  • Includes comprehensive unit tests for new functionality.


Diagram Walkthrough

flowchart LR
  AdminController["AdminController"] -- "PUT /leaderboard/current" --> EditLeaderboardBody["EditLeaderboardBody (Validation)"]
  EditLeaderboardBody -- "Validates name & expiry" --> AdminController
  AdminController -- "Updates Leaderboard" --> LeaderboardSqlRepository["LeaderboardSqlRepository"]
  LeaderboardSqlRepository -- "Persists changes" --> Database["Database"]
Loading

File Walkthrough

Relevant files
Enhancement
AdminController.java
Add admin endpoint to edit current leaderboard                     

src/main/java/org/patinanetwork/codebloom/api/admin/AdminController.java

  • Added a new editCurrentLeaderboard endpoint accessible via PUT
    /leaderboard/current.
  • This endpoint allows administrators to update the name,
    shouldExpireBy, and syntaxHighlightingLanguage of the current
    leaderboard.
  • Implemented validation for the request body and handles cases where no
    current leaderboard is found.
  • Updated imports to include EditLeaderboardBody.
+35/-10 
New feature
EditLeaderboardBody.java
New DTO for editing leaderboard details                                   

src/main/java/org/patinanetwork/codebloom/api/admin/body/EditLeaderboardBody.java

  • Introduced a new DTO EditLeaderboardBody to encapsulate request
    parameters for editing a leaderboard.
  • Utilizes Lombok annotations (@Getter, @Builder, @Jacksonized,
    @AllArgsConstructor, @ToString) for boilerplate reduction.
  • Implemented a validate() method to ensure the leaderboard name is not
    null/empty and within length constraints (1-512 characters).
  • Added validation to ensure shouldExpireBy date is in the future.
+49/-0   
Database
LeaderboardSqlRepository.java
Update leaderboard repository for expiration date               

src/main/java/org/patinanetwork/codebloom/common/db/repos/leaderboard/LeaderboardSqlRepository.java

  • Modified the updateLeaderboard SQL query to include the shouldExpireBy
    field.
  • Updated the parseResultSetToLeaderboard method to correctly retrieve
    the shouldExpireBy timestamp.
  • Added a shouldExpireBy private field for consistent column naming.
+4/-1     
Tests
AdminControllerTest.java
Add tests for edit current leaderboard endpoint                   

src/test/java/org/patinanetwork/codebloom/api/admin/AdminControllerTest.java

  • Added comprehensive unit tests for the new editCurrentLeaderboard
    endpoint in AdminController.
  • Includes tests for successful leaderboard updates, handling cases with
    no current leaderboard, and various validation failures (name length,
    past expiration date).
  • Imported EditLeaderboardBody and ValidationException for testing the
    new functionality.
+105/-0 

@github-actions
Copy link
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

**🎫 Ticket compliance analysis **

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Potential Bug

The leaderboardRepository.updateLeaderboard(updated) call does not check the boolean return value of the updateLeaderboard method. If the update operation fails in the database (e.g., no rows affected), the controller will still return a success response, which could be misleading. Consider checking the return value and responding with an appropriate error if the update was not successful.

leaderboardRepository.updateLeaderboard(updated);
Code Style

The use of wildcard imports (import org.patinanetwork.codebloom.api.admin.body.*; and import org.springframework.web.bind.annotation.*;) is generally discouraged in Java for better readability and to prevent potential naming conflicts. It is recommended to explicitly list all imported classes.

import org.patinanetwork.codebloom.api.admin.body.*;

@luoh00
Copy link
Collaborator Author

luoh00 commented Mar 18, 2026

/deploy

@luoh00 luoh00 force-pushed the 853 branch 2 times, most recently from 9d909da to 5931e4e Compare March 18, 2026 23:56
@github-actions
Copy link
Contributor

Title

853: create /leaderboard/current endpoint


PR Type

Enhancement


Description

  • Adds admin endpoint to update current leaderboard.

  • Introduces EditLeaderboardBody with validation rules.

  • Extends leaderboard update to include expiration date.

  • Includes comprehensive unit tests for new functionality.


Diagram Walkthrough

flowchart LR
  A["AdminController"] -- "PUT /leaderboard/current" --> B["EditLeaderboardBody"];
  B -- "validates input" --> C["ValidationException"];
  A -- "uses" --> D["LeaderboardRepository"];
  D -- "implements" --> E["LeaderboardSqlRepository"];
  E -- "updates" --> F["Leaderboard Table"];
Loading

File Walkthrough

Relevant files
Api changes
AdminController.java
Adds PUT endpoint for current leaderboard updates               

src/main/java/org/patinanetwork/codebloom/api/admin/AdminController.java

  • Added a new PUT /leaderboard/current endpoint to allow administrators
    to modify the current leaderboard.
  • Implemented logic to retrieve the most recent leaderboard, apply
    updates from EditLeaderboardBody, and persist changes.
  • Included validation for admin sessions and handled cases where no
    current leaderboard is found.
  • Updated import statements to include EditLeaderboardBody and
    PutMapping annotation.
+35/-10 
New feature
EditLeaderboardBody.java
Introduces request body for leaderboard edits with validation

src/main/java/org/patinanetwork/codebloom/api/admin/body/EditLeaderboardBody.java

  • Created a new data transfer object EditLeaderboardBody for updating
    leaderboard details.
  • Includes fields for name, shouldExpireBy, and
    syntaxHighlightingLanguage.
  • Implemented a validate() method to enforce business rules for
    leaderboard name length and future expiration dates.
  • Utilizes Lombok annotations (@Getter, @Builder, @Jacksonized,
    @AllArgsConstructor, @ToString) for boilerplate code reduction.
+49/-0   
Database changes
LeaderboardSqlRepository.java
Updates leaderboard SQL repository to include expiration date

src/main/java/org/patinanetwork/codebloom/common/db/repos/leaderboard/LeaderboardSqlRepository.java

  • Modified the updateLeaderboard SQL query to include the shouldExpireBy
    column.
  • Updated the NamedPreparedStatement to correctly set the shouldExpireBy
    value from the Leaderboard object.
+2/-0     
Tests
AdminControllerTest.java
Adds unit tests for current leaderboard edit endpoint       

src/test/java/org/patinanetwork/codebloom/api/admin/AdminControllerTest.java

  • Added comprehensive unit tests for the new editCurrentLeaderboard
    endpoint in AdminController.
  • Covered successful update scenarios, including setting name, syntax
    highlighting, and expiration date.
  • Included tests for failure cases such as no current leaderboard found
    and various ValidationException scenarios (name length, past
    expiration date).
  • Mocked LeaderboardRepository and Protector to isolate the controller
    logic for testing.
+105/-0 

@github-actions
Copy link
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

🎫 Ticket compliance analysis ✅

853 - PR Code Verified

Compliant requirements:

  • Add new /leaderboard/current endpoint in admin route.
  • Endpoint should update the current leaderboard.
  • Thorough self-review of the PR.
  • Copilot has reviewed latest changes, and all comments have been fixed and/or closed.
  • All tests have passed.
  • Successfully deployed this PR to staging.
  • Manual QA done in both dev (and staging if possible) and screenshots attached.

Requires further human verification:

  • If database changes were made, ensure all db repo rules listed in the wiki are followed.
⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Database Schema

The PR modifies the LeaderboardSqlRepository to include shouldExpireBy in the UPDATE statement. This implies a change to the Leaderboard database table and the Leaderboard Java model. The PR description states "check if no db changes", which might be misleading if a schema change was indeed made. It's important to verify that the corresponding database migration was performed and is reversible/safe, and that the Leaderboard model was updated correctly to include this field.

"shouldExpireBy" = :shouldExpireBy,

@luoh00
Copy link
Collaborator Author

luoh00 commented Mar 19, 2026

/deploy

@github-actions
Copy link
Contributor

Title

853: create /leaderboard/current endpoint


PR Type

Enhancement


Description

  • Adds endpoint to update current leaderboard

  • Introduces request body with validation

  • Updates leaderboard database repository

  • Includes comprehensive unit tests


Diagram Walkthrough

flowchart LR
  AdminController["Admin Controller"] -- "PUT /leaderboard/current" --> EditLeaderboardBody["EditLeaderboardBody (Validation)"]
  EditLeaderboardBody -- "Validates input" --> LeaderboardRepository["Leaderboard Repository"]
  LeaderboardRepository -- "Updates 'Leaderboard' table" --> LeaderboardSqlRepository["LeaderboardSqlRepository"]
Loading

File Walkthrough

Relevant files
Enhancement
AdminController.java
Add PUT /leaderboard/current endpoint                                       

src/main/java/org/patinanetwork/codebloom/api/admin/AdminController.java

  • Added a new PUT /leaderboard/current endpoint for admin users.
  • This endpoint allows updating the name, expiration date, and syntax
    highlighting language of the current leaderboard.
  • Utilizes the new EditLeaderboardBody for request data and performs
    validation.
  • Fetches the most recent leaderboard, updates its properties, and
    persists changes via LeaderboardRepository.
  • Handles cases where no current leaderboard is found, returning a 404
    NOT_FOUND status.
+35/-10 
EditLeaderboardBody.java
Introduce EditLeaderboardBody DTO with validation               

src/main/java/org/patinanetwork/codebloom/api/admin/body/EditLeaderboardBody.java

  • Created a new DTO EditLeaderboardBody to encapsulate request
    parameters for updating a leaderboard.
  • Includes fields for name, shouldExpireBy, and
    syntaxHighlightingLanguage.
  • Implements a validate() method to ensure data integrity, checking for
    null/empty name, name length constraints, and future expiration date.
  • Uses Lombok annotations (@Getter, @Builder, @Jacksonized,
    @AllArgsConstructor, @ToString) for boilerplate code generation.
+49/-0   
LeaderboardSqlRepository.java
Update LeaderboardSqlRepository for shouldExpireBy field 

src/main/java/org/patinanetwork/codebloom/common/db/repos/leaderboard/LeaderboardSqlRepository.java

  • Introduced a constant shouldExpireBy for consistent column name usage.
  • Modified parseResultSetToLeaderboard and addNewLeaderboard to use the
    new shouldExpireBy constant.
  • Updated the updateLeaderboard SQL query to include the shouldExpireBy
    column in the SET clause.
  • Ensured the updateLeaderboard method correctly sets the shouldExpireBy
    parameter in the prepared statement.
+5/-2     
Tests
AdminControllerTest.java
Add unit tests for editCurrentLeaderboard endpoint             

src/test/java/org/patinanetwork/codebloom/api/admin/AdminControllerTest.java

  • Added comprehensive unit tests for the new editCurrentLeaderboard
    endpoint.
  • Tested successful leaderboard update scenarios.
  • Included tests for failure cases such as no current leaderboard found.
  • Verified validation logic for EditLeaderboardBody, including name
    length constraints and future expiration date.
+105/-0 

@github-actions
Copy link
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

**🎫 Ticket compliance analysis **

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Wildcard Imports

The use of wildcard imports like import org.patinanetwork.codebloom.api.admin.body.*; and import org.springframework.web.bind.annotation.*; can sometimes lead to less explicit dependencies and potential naming conflicts. While not strictly forbidden by the style guide, it's generally considered better practice to import specific classes.

import org.patinanetwork.codebloom.api.admin.body.*;

@github-actions
Copy link
Contributor

Title

853: create /leaderboard/current endpoint


PR Type

Enhancement, Tests


Description

  • Adds admin endpoint to update current leaderboard.

  • Implements request body validation for updates.

  • Updates leaderboard SQL to include expiration date.

  • Adds comprehensive tests for new functionality.


Diagram Walkthrough

flowchart LR
  AdminController["AdminController"] -- "PUT /leaderboard/current" --> EditLeaderboardBody["EditLeaderboardBody (Validation)"]
  EditLeaderboardBody -- "Validates input" --> LeaderboardRepository["LeaderboardRepository"]
  LeaderboardRepository -- "Fetches & Updates" --> LeaderboardSqlRepository["LeaderboardSqlRepository (SQL Update)"]
Loading

File Walkthrough

Relevant files
Api
AdminController.java
Adds admin endpoint to update current leaderboard.             

src/main/java/org/patinanetwork/codebloom/api/admin/AdminController.java

  • Adds a new @PutMapping("/leaderboard/current") endpoint for admin
    users.
  • Allows updating the current leaderboard's name, expiration, and syntax
    highlighting language.
  • Includes input validation via EditLeaderboardBody.validate() and
    interacts with LeaderboardRepository.
+35/-10 
New feature
EditLeaderboardBody.java
Defines request body and validation for leaderboard updates.

src/main/java/org/patinanetwork/codebloom/api/admin/body/EditLeaderboardBody.java

  • Introduces EditLeaderboardBody class to define the request payload for
    updating a leaderboard.
  • Contains fields for name, shouldExpireBy, and
    syntaxHighlightingLanguage.
  • Implements a validate() method to ensure name is not empty/null, has
    valid length, and shouldExpireBy is in the future.
+49/-0   
Database
LeaderboardSqlRepository.java
Updates leaderboard SQL to include expiration date.           

src/main/java/org/patinanetwork/codebloom/common/db/repos/leaderboard/LeaderboardSqlRepository.java

  • Introduces a constant shouldExpireBy for the column name.
  • Modifies the updateLeaderboard SQL query to include the shouldExpireBy
    field.
  • Updates parameter binding in updateLeaderboard to set the
    shouldExpireBy value.
+5/-2     
Tests
AdminControllerTest.java
Adds tests for admin leaderboard update endpoint.               

src/test/java/org/patinanetwork/codebloom/api/admin/AdminControllerTest.java

  • Adds new test cases for the editCurrentLeaderboard endpoint.
  • Includes tests for successful leaderboard updates and scenarios where
    no current leaderboard is found.
  • Covers validation failures such as invalid leaderboard name length and
    past expiration dates.
+105/-0 

@github-actions
Copy link
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

**🎫 Ticket compliance analysis **

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Unchecked Repository Update Result

The editCurrentLeaderboard method calls leaderboardRepository.updateLeaderboard(updated) but does not check the boolean return value. If the update operation in the repository fails (e.g., no rows were actually updated), the API would still return a success response, which could be misleading. Consider checking the return value and responding appropriately.

leaderboardRepository.updateLeaderboard(updated);

@github-actions
Copy link
Contributor

Title

853: create /leaderboard/current endpoint


PR Type

Enhancement, Tests


Description

  • Add PUT /leaderboard/current admin endpoint.

  • Introduce EditLeaderboardBody for leaderboard updates.

  • Enable updating shouldExpireBy field in database.

  • Include comprehensive unit tests for the new endpoint.


Diagram Walkthrough

flowchart LR
  AdminController["AdminController (PUT /leaderboard/current)"] --> EditLeaderboardBody["EditLeaderboardBody (Validation)"]
  EditLeaderboardBody --> LeaderboardRepository["LeaderboardRepository (updateLeaderboard)"]
  LeaderboardRepository --> LeaderboardSqlRepository["LeaderboardSqlRepository (SQL Update)"]
  AdminController --> AdminControllerTest["AdminControllerTest (Unit Tests)"]
Loading

File Walkthrough

Relevant files
Enhancement
AdminController.java
Add PUT /leaderboard/current endpoint                                       

src/main/java/org/patinanetwork/codebloom/api/admin/AdminController.java

  • Added a new PUT /leaderboard/current endpoint to update the current
    leaderboard.
  • The endpoint validates admin sessions and the EditLeaderboardBody
    input.
  • It retrieves the most recent leaderboard, updates its fields, and
    persists changes via leaderboardRepository.
  • Imports EditLeaderboardBody for the new endpoint's request body.
+35/-10 
EditLeaderboardBody.java
Introduce EditLeaderboardBody DTO with validation               

src/main/java/org/patinanetwork/codebloom/api/admin/body/EditLeaderboardBody.java

  • Created a new DTO EditLeaderboardBody for updating leaderboard
    details.
  • Includes fields for name, shouldExpireBy, and
    syntaxHighlightingLanguage.
  • Implements a validate() method with checks for name length and future
    expiration date.
  • Uses Lombok annotations for boilerplate code generation.
+49/-0   
LeaderboardSqlRepository.java
Enable shouldExpireBy updates in LeaderboardSqlRepository

src/main/java/org/patinanetwork/codebloom/common/db/repos/leaderboard/LeaderboardSqlRepository.java

  • Added shouldExpireBy field to the UPDATE SQL query in
    updateLeaderboard method.
  • Ensured shouldExpireBy is correctly set in the NamedPreparedStatement
    for updates.
  • Introduced a constant SHOULD_EXPIRE_BY for consistency in SQL
    operations.
+5/-2     
Tests
AdminControllerTest.java
Add unit tests for editCurrentLeaderboard endpoint             

src/test/java/org/patinanetwork/codebloom/api/admin/AdminControllerTest.java

  • Added comprehensive unit tests for the new editCurrentLeaderboard
    endpoint.
  • Includes tests for successful updates, no current leaderboard found,
    and various validation failures (name length, past expiration date).
  • Imports EditLeaderboardBody for test case setup.
+105/-0 

@github-actions
Copy link
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

🎫 Ticket compliance analysis 🔶

853 - Partially compliant

Compliant requirements:

  • Add a new /leaderboard/current endpoint in the admin route.
  • The endpoint should allow updating the current leaderboard.
  • The PR should include a thorough self-review.
  • Copilot review comments should be addressed.
  • All tests must pass.
  • The PR should be successfully deployed to staging.
  • Manual QA in dev and staging (if applicable) with screenshots.

Non-compliant requirements:

  • Database repository rules should be followed if database changes are made.

Requires further human verification:

  • Verify that the database schema includes the shouldExpireBy column in the Leaderboard table, or that a corresponding database migration has been applied.
⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Wildcard Imports

The use of wildcard imports (import org.patinanetwork.codebloom.api.admin.body.*; and import org.springframework.web.bind.annotation.*;) can sometimes lead to less readable code, potential naming conflicts, or pulling in unnecessary dependencies. While not strictly forbidden by the style guide, it's generally considered better practice to import specific classes explicitly.

import org.patinanetwork.codebloom.api.admin.body.*;
import org.patinanetwork.codebloom.api.admin.body.jda.DeleteMessageBody;
import org.patinanetwork.codebloom.common.components.DiscordClubManager;
import org.patinanetwork.codebloom.common.components.LeaderboardManager;
import org.patinanetwork.codebloom.common.db.models.announcement.Announcement;
import org.patinanetwork.codebloom.common.db.models.discord.DiscordClub;
import org.patinanetwork.codebloom.common.db.models.leaderboard.Leaderboard;
import org.patinanetwork.codebloom.common.db.models.question.QuestionWithUser;
import org.patinanetwork.codebloom.common.db.models.user.User;
import org.patinanetwork.codebloom.common.db.repos.announcement.AnnouncementRepository;
import org.patinanetwork.codebloom.common.db.repos.discord.club.DiscordClubRepository;
import org.patinanetwork.codebloom.common.db.repos.leaderboard.LeaderboardRepository;
import org.patinanetwork.codebloom.common.db.repos.question.QuestionRepository;
import org.patinanetwork.codebloom.common.db.repos.user.UserRepository;
import org.patinanetwork.codebloom.common.dto.ApiResponder;
import org.patinanetwork.codebloom.common.dto.Empty;
import org.patinanetwork.codebloom.common.dto.autogen.UnsafeGenericFailureResponse;
import org.patinanetwork.codebloom.common.dto.question.QuestionWithUserDto;
import org.patinanetwork.codebloom.common.dto.user.UserDto;
import org.patinanetwork.codebloom.common.security.Protector;
import org.patinanetwork.codebloom.common.time.StandardizedOffsetDateTime;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
Missing Javadoc

The new editCurrentLeaderboard method in AdminController is missing Javadoc comments. According to the documentation guidelines, controllers should have auto-generated documentation via Springdoc, but Javadoc comments are also encouraged for non-controllers or to clarify important details. Adding Javadoc to this public endpoint method would improve clarity for future maintainers.

@PutMapping("/leaderboard/current")
public ResponseEntity<ApiResponder<Empty>> editCurrentLeaderboard(
        @RequestBody final EditLeaderboardBody editLeaderboardBody, final HttpServletRequest request) {
    protector.validateAdminSession(request);
    editLeaderboardBody.validate();

    Optional<Leaderboard> currentLeaderboard = leaderboardRepository.getRecentLeaderboardMetadata();
    currentLeaderboard.ifPresent(lb -> {
        OffsetDateTime shouldExpireBy =
                StandardizedOffsetDateTime.normalize(editLeaderboardBody.getShouldExpireBy());

        Leaderboard updated = Leaderboard.builder()
                .name(editLeaderboardBody.getName())
                .deletedAt(lb.getDeletedAt())
                .createdAt(lb.getCreatedAt())
                .shouldExpireBy(Optional.ofNullable(shouldExpireBy).map(d -> d.toLocalDateTime()))
                .syntaxHighlightingLanguage(
                        Optional.ofNullable(editLeaderboardBody.getSyntaxHighlightingLanguage()))
                .id(lb.getId())
                .build();

        leaderboardRepository.updateLeaderboard(updated);
    });

    if (currentLeaderboard.isEmpty()) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND)
                .body(ApiResponder.failure("No current leaderboard found"));
    }

    return ResponseEntity.ok().body(ApiResponder.success("Leaderboard updated successfully", Empty.of()));
}

@luoh00
Copy link
Collaborator Author

luoh00 commented Mar 19, 2026

/deploy

@luoh00
Copy link
Collaborator Author

luoh00 commented Mar 21, 2026

/deploy

@github-actions
Copy link
Contributor

Title

853: create /leaderboard/current endpoint


PR Type

Enhancement, Tests


Description

  • Add admin endpoint to update current leaderboard.

  • Introduce EditLeaderboardBody for request validation.

  • Update LeaderboardSqlRepository to persist expiration date.

  • Implement comprehensive unit tests for new endpoint.


Diagram Walkthrough

flowchart LR
  AdminController["AdminController"] -- "PUT /leaderboard/current" --> EditLeaderboardBody["Validate Request Body"];
  EditLeaderboardBody -- "Validates name & expiration" --> LeaderboardRepository["Get & Update Leaderboard"];
  LeaderboardRepository -- "Updates 'shouldExpireBy' field" --> AdminController;
  AdminController -- "Returns success/failure" --> Client;
Loading

File Walkthrough

Relevant files
Enhancement
AdminController.java
Add PUT endpoint to edit current leaderboard                         

src/main/java/org/patinanetwork/codebloom/api/admin/AdminController.java

  • Imports EditLeaderboardBody for the new endpoint.
  • Adds a new PUT /leaderboard/current endpoint to modify the current
    leaderboard's name, expiration, and syntax highlighting language.
  • Validates the EditLeaderboardBody and retrieves the most recent
    leaderboard metadata.
  • Throws a ResponseStatusException with HttpStatus.NOT_FOUND if no
    current leaderboard is found.
+34/-10 
New feature
EditLeaderboardBody.java
Define request body for editing leaderboard                           

src/main/java/org/patinanetwork/codebloom/api/admin/body/EditLeaderboardBody.java

  • Introduces a new data transfer object EditLeaderboardBody for updating
    leaderboard details.
  • Includes fields for name, shouldExpireBy, and
    syntaxHighlightingLanguage.
  • Implements a validate() method to ensure the leaderboard name is not
    empty, not too short (1 character), not too long (>512 characters),
    and that shouldExpireBy is a future date.
  • Uses Lombok annotations like @Getter, @Builder, @Jacksonized,
    @AllArgsConstructor, and @ToString.
+49/-0   
Database
LeaderboardSqlRepository.java
Update leaderboard repository for expiration date               

src/main/java/org/patinanetwork/codebloom/common/db/repos/leaderboard/LeaderboardSqlRepository.java

  • Adds a constant SHOULD_EXPIRE_BY for consistent column naming.
  • Modifies parseResultSetToLeaderboard to use the SHOULD_EXPIRE_BY
    constant when reading the shouldExpireBy field.
  • Updates the addNewLeaderboard and updateLeaderboard SQL queries to
    correctly include and set the shouldExpireBy column.
+5/-2     
Tests
AdminControllerTest.java
Add unit tests for edit current leaderboard endpoint         

src/test/java/org/patinanetwork/codebloom/api/admin/AdminControllerTest.java

  • Adds EditLeaderboardBody and ValidationException imports for testing.
  • Introduces testEditCurrentLeaderboardSuccess to verify successful
    leaderboard updates.
  • Includes tests for failure scenarios:
    testEditCurrentLeaderboardFailureNoCurrentLeaderboard,
    testEditCurrentLeaderboardFailureNameTooShort,
    testEditCurrentLeaderboardFailureNameTooLong, and
    testEditCurrentLeaderboardFailurePastDate.
  • These tests ensure proper validation and error handling for the new
    endpoint.
+105/-0 

@github-actions
Copy link
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

**🎫 Ticket compliance analysis **

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Potential Bug

The editCurrentLeaderboard method calls leaderboardRepository.updateLeaderboard(updated); but does not check its boolean return value. If the update operation in the repository fails (e.g., due to a database error), the controller will still return a 200 OK response with a success message, which could be misleading. Consider checking the return value and responding with an appropriate error status if the update was not successful.

leaderboardRepository.updateLeaderboard(updated);

@Getter
@Builder
@Jacksonized
@AllArgsConstructor
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: unnecessary; @Builder will generate the constructor it needs and make it private

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants