44
55import java .net .URI ;
66import java .util .List ;
7+ import java .util .UUID ;
78
89import org .springframework .http .HttpStatus ;
910import org .springframework .http .ResponseEntity ;
3738 * <h3>Base Path:</h3>
3839 * <ul>
3940 * <li><b>GET</b> {@code /players} - Retrieve all players</li>
40- * <li><b>GET</b> {@code /players/{id}} - Retrieve player by ID </li>
41+ * <li><b>GET</b> {@code /players/{id}} - Retrieve player by UUID (admin/internal use) </li>
4142 * <li><b>GET</b> {@code /players/search/league/{league}} - Search players by league name</li>
42- * <li><b>GET</b> {@code /players/squadnumber/{number }} - Retrieve player by squad number</li>
43+ * <li><b>GET</b> {@code /players/squadnumber/{squadNumber }} - Retrieve player by squad number</li>
4344 * <li><b>POST</b> {@code /players} - Create a new player</li>
44- * <li><b>PUT</b> {@code /players/{id }} - Update an existing player</li>
45- * <li><b>DELETE</b> {@code /players/{id }} - Delete a player by ID </li>
45+ * <li><b>PUT</b> {@code /players/{squadNumber }} - Update an existing player by squad number </li>
46+ * <li><b>DELETE</b> {@code /players/{squadNumber }} - Delete a player by squad number </li>
4647 * </ul>
4748 *
4849 * <h3>Response Codes:</h3>
@@ -74,12 +75,8 @@ public class PlayersController {
7475 /**
7576 * Creates a new player resource.
7677 * <p>
77- * Validates the request body and creates a new player in the database. Returns a 201 Created response with a Location
78- * header pointing to the new resource.
79- * </p>
80- * <p>
81- * <b>Conflict Detection:</b> If a player with the same squad number already exists, returns 409 Conflict.
82- * Squad numbers must be unique (jersey numbers like Messi's #10).
78+ * Validates the request body and creates a new player. Returns 201 Created with a Location
79+ * header pointing to the new resource (UUID-based path).
8380 * </p>
8481 *
8582 * @param playerDTO the player data to create (validated with JSR-380 constraints)
@@ -115,9 +112,6 @@ public ResponseEntity<Void> post(@RequestBody @Valid PlayerDTO playerDTO) {
115112
116113 /**
117114 * Retrieves all players in the squad.
118- * <p>
119- * Returns the complete Argentina 2022 FIFA World Cup squad (26 players).
120- * </p>
121115 *
122116 * @return 200 OK with array of all players (empty array if none found)
123117 */
@@ -132,28 +126,27 @@ public ResponseEntity<List<PlayerDTO>> getAll() {
132126 }
133127
134128 /**
135- * Retrieves a single player by their unique identifier .
129+ * Retrieves a single player by their surrogate UUID (admin/internal use only) .
136130 *
137- * @param id the unique identifier of the player
131+ * @param id the UUID surrogate key of the player
138132 * @return 200 OK with player data, or 404 Not Found if player doesn't exist
139133 */
140134 @ GetMapping ("/players/{id}" )
141- @ Operation (summary = "Retrieves a player by ID " )
135+ @ Operation (summary = "Retrieves a player by UUID (admin/internal use) " )
142136 @ ApiResponses (value = {
143137 @ ApiResponse (responseCode = "200" , description = "OK" , content = @ Content (mediaType = "application/json" , schema = @ Schema (implementation = PlayerDTO .class ))),
144138 @ ApiResponse (responseCode = "404" , description = "Not Found" , content = @ Content )
145139 })
146- public ResponseEntity <PlayerDTO > getById (@ PathVariable Long id ) {
140+ public ResponseEntity <PlayerDTO > getById (@ PathVariable UUID id ) {
147141 PlayerDTO playerDTO = playersService .retrieveById (id );
148142 return (playerDTO != null )
149143 ? ResponseEntity .status (HttpStatus .OK ).body (playerDTO )
150144 : ResponseEntity .status (HttpStatus .NOT_FOUND ).build ();
151145 }
152146
153147 /**
154- * Retrieves a player by their squad number (unique identifier) .
148+ * Retrieves a player by their squad number.
155149 * <p>
156- * Squad numbers are unique jersey numbers (e.g., Messi is #10). This is a direct lookup similar to getById().
157150 * Example: {@code /players/squadnumber/10} returns Lionel Messi
158151 * </p>
159152 *
@@ -199,30 +192,29 @@ public ResponseEntity<List<PlayerDTO>> searchByLeague(@PathVariable String leagu
199192 */
200193
201194 /**
202- * Updates an existing player resource (full update).
195+ * Updates an existing player resource (full update) identified by squad number .
203196 * <p>
204- * Performs a complete replacement of the player entity. The ID in the path must match the ID in the request body.
197+ * Performs a complete replacement of the player entity. The squad number in the path
198+ * must match the squad number in the request body (if provided).
205199 * </p>
206200 *
207- * @param id the unique identifier of the player to update
201+ * @param squadNumber the squad number (natural key) of the player to update
208202 * @param playerDTO the complete player data (must pass validation)
209- * @return 204 No Content if successful, 404 Not Found if player doesn't exist, or 400 Bad Request if validation fails or
210- * ID mismatch
203+ * @return 204 No Content if successful, 404 Not Found if player doesn't exist, or 400 Bad Request if validation fails
211204 */
212- @ PutMapping ("/players/{id }" )
213- @ Operation (summary = "Updates (entirely) a player by ID " )
205+ @ PutMapping ("/players/{squadNumber }" )
206+ @ Operation (summary = "Updates (entirely) a player by squad number " )
214207 @ ApiResponses (value = {
215208 @ ApiResponse (responseCode = "204" , description = "No Content" , content = @ Content ),
216209 @ ApiResponse (responseCode = "400" , description = "Bad Request" , content = @ Content ),
217210 @ ApiResponse (responseCode = "404" , description = "Not Found" , content = @ Content )
218211 })
219- public ResponseEntity <Void > put (@ PathVariable Long id , @ RequestBody @ Valid PlayerDTO playerDTO ) {
220- // Ensure path ID matches body ID
221- if (playerDTO .getId () != null && !playerDTO .getId ().equals (id )) {
212+ public ResponseEntity <Void > put (@ PathVariable Integer squadNumber , @ RequestBody @ Valid PlayerDTO playerDTO ) {
213+ if (playerDTO .getSquadNumber () != null && !playerDTO .getSquadNumber ().equals (squadNumber )) {
222214 return ResponseEntity .status (HttpStatus .BAD_REQUEST ).build ();
223215 }
224- playerDTO .setId ( id ); // Set ID from path to ensure consistency
225- boolean updated = playersService .update (playerDTO );
216+ playerDTO .setSquadNumber ( squadNumber );
217+ boolean updated = playersService .update (squadNumber , playerDTO );
226218 return (updated )
227219 ? ResponseEntity .status (HttpStatus .NO_CONTENT ).build ()
228220 : ResponseEntity .status (HttpStatus .NOT_FOUND ).build ();
@@ -235,19 +227,19 @@ public ResponseEntity<Void> put(@PathVariable Long id, @RequestBody @Valid Playe
235227 */
236228
237229 /**
238- * Deletes a player resource by their unique identifier .
230+ * Deletes a player resource by their squad number .
239231 *
240- * @param id the unique identifier of the player to delete
232+ * @param squadNumber the squad number of the player to delete
241233 * @return 204 No Content if successful, or 404 Not Found if player doesn't exist
242234 */
243- @ DeleteMapping ("/players/{id }" )
244- @ Operation (summary = "Deletes a player by ID " )
235+ @ DeleteMapping ("/players/{squadNumber }" )
236+ @ Operation (summary = "Deletes a player by squad number " )
245237 @ ApiResponses (value = {
246238 @ ApiResponse (responseCode = "204" , description = "No Content" , content = @ Content ),
247239 @ ApiResponse (responseCode = "404" , description = "Not Found" , content = @ Content )
248240 })
249- public ResponseEntity <Void > delete (@ PathVariable Long id ) {
250- boolean deleted = playersService .delete ( id );
241+ public ResponseEntity <Void > delete (@ PathVariable Integer squadNumber ) {
242+ boolean deleted = playersService .deleteBySquadNumber ( squadNumber );
251243 return (deleted )
252244 ? ResponseEntity .status (HttpStatus .NO_CONTENT ).build ()
253245 : ResponseEntity .status (HttpStatus .NOT_FOUND ).build ();
0 commit comments