Skip to content

refactor(api): use squad number for PUT and DELETE endpoints#524

Merged
nanotaboada merged 2 commits intomasterfrom
refactor/use-squad-number-for-mutation-endpoints
Mar 17, 2026
Merged

refactor(api): use squad number for PUT and DELETE endpoints#524
nanotaboada merged 2 commits intomasterfrom
refactor/use-squad-number-for-mutation-endpoints

Conversation

@nanotaboada
Copy link
Owner

@nanotaboada nanotaboada commented Mar 17, 2026

Closes #521


This change is Reviewable

Summary by CodeRabbit

Release Notes

  • Breaking Changes

    • Updated player update and delete endpoints to use squad number as the identifier instead of player ID. PUT and DELETE requests now target /players/squadnumber/{squad_number} endpoints.
  • Documentation

    • Updated API reference and REST specifications to reflect new endpoint routing.
  • Configuration

    • Added linting and AI settings configuration files.

@coderabbitai
Copy link

coderabbitai bot commented Mar 17, 2026

Warning

Rate limit exceeded

@nanotaboada has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 8 minutes and 6 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b20993f2-be37-4764-8a1c-ffb0904208f1

📥 Commits

Reviewing files that changed from the base of the PR and between ad9e5cd and 12eaff0.

📒 Files selected for processing (10)
  • .claude/settings.json
  • .github/copilot-instructions.md
  • .gitignore
  • .markdownlint.json
  • CHANGELOG.md
  • README.md
  • rest/players.rest
  • routes/player_route.py
  • services/player_service.py
  • tests/test_main.py

Walkthrough

The pull request refactors PUT and DELETE player endpoints to use Squad Number (natural key) instead of UUID (surrogate key). Service methods are renamed to update_by_squad_number_async and delete_by_squad_number_async, routes are updated from /players/{player_id} to /players/squadnumber/{squad_number}, and all related documentation and tests are updated accordingly.

Changes

Cohort / File(s) Summary
Configuration & Linting
.claude/settings.local.json, .markdownlint.json
Added local AI settings and Markdown linting configuration files.
Documentation & API Reference
README.md, CHANGELOG.md, .github/copilot-instructions.md, rest/players.rest
Updated API reference and examples to reflect endpoint changes from /players/{player_id} to /players/squadnumber/{squad_number} for PUT and DELETE operations. Documented breaking changes in changelog and API documentation.
Route Handler
routes/player_route.py
Changed PUT and DELETE endpoint routes to accept squad_number: int instead of player_id: UUID. Updated route paths and internal service method calls to use retrieve_by_squad_number_async, update_by_squad_number_async, and delete_by_squad_number_async.
Service Layer
services/player_service.py
Renamed update_async to update_by_squad_number_async and delete_async to delete_by_squad_number_async. Both methods now accept squad_number: int as the lookup key and retrieve the target Player via retrieve_by_squad_number_async before modification or deletion.
Test Suite
tests/test_main.py
Updated PUT and DELETE test cases to use /players/squadnumber/{squad_number} endpoints with squad_number parameter instead of player_id.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Assessment against linked issues

Objective Addressed Explanation
Refactor PUT endpoint to use Squad Number instead of UUID [#521]
Refactor DELETE endpoint to use Squad Number instead of UUID [#521]
Add update_by_squad_number_async service method [#521]
Add delete_by_squad_number_async service method [#521]

Out-of-scope changes

Code Change Explanation
Added local Claude settings configuration (.claude/settings.local.json) Configuration file for local development environment; unrelated to the Squad Number refactoring objective.
Added Markdown linting rules (.markdownlint.json) Linting configuration file; not directly related to API endpoint or service layer changes required by the issue.

Possibly related issues

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed Title uses Conventional Commits format (refactor), is 60 characters (under 80 limit), and accurately describes the main change of using squad number for PUT and DELETE endpoints.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

📋 Issue Planner

Built with CodeRabbit's Coding Plans for faster development and fewer bugs.

View plan used: #521

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/use-squad-number-for-mutation-endpoints
  • 🛠️ sync documentation: Commit on current branch
  • 🛠️ sync documentation: Create PR
  • 🛠️ enforce http error handling: Commit on current branch
  • 🛠️ enforce http error handling: Create PR
  • 🛠️ idiomatic review: Commit on current branch
  • 🛠️ idiomatic review: Create PR
  • 🛠️ verify api contract: Commit on current branch
  • 🛠️ verify api contract: Create PR
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Mar 17, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (8056837) to head (12eaff0).
⚠️ Report is 3 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff            @@
##            master      #524   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            3         3           
  Lines          110       111    +1     
=========================================
+ Hits           110       111    +1     
Components Coverage Δ
Services 100.00% <100.00%> (ø)
Routes 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
routes/player_route.py (1)

185-189: Use Annotated[...] for FastAPI params/dependencies to resolve the Sonar gate issue.

Line [229] is already flagged by Sonar; applying Annotated to Path/Body/Depends in these handlers will make typing explicit and consistent.

♻️ Suggested refactor
-from typing import List
+from typing import Annotated, List
@@
 async def put_async(
-    squad_number: int = Path(..., title="The Squad Number of the Player"),
-    player_model: PlayerRequestModel = Body(...),
-    async_session: AsyncSession = Depends(generate_async_session),
+    squad_number: Annotated[
+        int, Path(..., title="The Squad Number of the Player")
+    ],
+    player_model: Annotated[PlayerRequestModel, Body(...)],
+    async_session: Annotated[AsyncSession, Depends(generate_async_session)],
 ):
@@
 async def delete_async(
-    squad_number: int = Path(..., title="The Squad Number of the Player"),
-    async_session: AsyncSession = Depends(generate_async_session),
+    squad_number: Annotated[
+        int, Path(..., title="The Squad Number of the Player")
+    ],
+    async_session: Annotated[AsyncSession, Depends(generate_async_session)],
 ):

Also applies to: 228-230

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@routes/player_route.py` around lines 185 - 189, The FastAPI handler put_async
currently uses Path, Body and Depends directly which triggers the Sonar typing
gate; update the parameter annotations to use typing.Annotated for the FastAPI
metadata so types are explicit (e.g., annotate squad_number as Annotated[int,
Path(...)] and player_model as Annotated[PlayerRequestModel, Body(...)] and
async_session as Annotated[AsyncSession, Depends(generate_async_session)]), keep
the same default values and imports, and ensure typing.Annotated is imported
where put_async is defined so the function signature uses Annotated for
Path/Body/Depends.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@services/player_service.py`:
- Around line 120-122: The update_by_squad_number_async function currently uses
player_model.squad_number which allows the request body to re-key the resource;
change this to enforce path/body consistency by either (a) validating that
player_model.squad_number equals the path param squad_number and
returning/raising a 400 if they differ, or (b) ignoring the body value and
overriding player_model.squad_number = squad_number before performing the
update; update the logic in update_by_squad_number_async (and the same pattern
in the nearby block handling lines ~135-143) to use the path param as the
canonical key and reference only squad_number (path) for lookups and uniqueness
checks.
- Around line 174-176: The code calls await async_session.delete(player) without
checking if player is None and performs the delete outside the try/except;
update the delete path (the block using retrieve_by_squad_number_async and
async_session.delete) to first check if player is None and return False if so,
then move the await async_session.delete(player) call inside the try/except
(same pattern used in update_by_squad_number_async) so any exceptions are caught
and the function returns False on failure; reference
retrieve_by_squad_number_async, the local variable player, and
async_session.delete when making the change.

---

Nitpick comments:
In `@routes/player_route.py`:
- Around line 185-189: The FastAPI handler put_async currently uses Path, Body
and Depends directly which triggers the Sonar typing gate; update the parameter
annotations to use typing.Annotated for the FastAPI metadata so types are
explicit (e.g., annotate squad_number as Annotated[int, Path(...)] and
player_model as Annotated[PlayerRequestModel, Body(...)] and async_session as
Annotated[AsyncSession, Depends(generate_async_session)]), keep the same default
values and imports, and ensure typing.Annotated is imported where put_async is
defined so the function signature uses Annotated for Path/Body/Depends.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e9b0fbf2-70b7-4297-96a8-e2e84669f42f

📥 Commits

Reviewing files that changed from the base of the PR and between 8056837 and ad9e5cd.

📒 Files selected for processing (9)
  • .claude/settings.local.json
  • .github/copilot-instructions.md
  • .markdownlint.json
  • CHANGELOG.md
  • README.md
  • rest/players.rest
  • routes/player_route.py
  • services/player_service.py
  • tests/test_main.py

BREAKING CHANGE: PUT /players/{player_id}
  → PUT /players/squadnumber/{squad_number}
BREAKING CHANGE: DELETE /players/{player_id}
  → DELETE /players/squadnumber/{squad_number}

Co-authored-by: Claude <noreply@anthropic.com>
@nanotaboada nanotaboada force-pushed the refactor/use-squad-number-for-mutation-endpoints branch from 8997f6e to 39cf3bf Compare March 17, 2026 18:37
- Use Annotated for FastAPI Path/Body/Depends across all route handlers
- Define SQUAD_NUMBER_TITLE constant to avoid literal duplication
- Enforce path param as canonical key in update_by_squad_number_async
- Add None guard and move delete inside try/except
  in delete_by_squad_number_async

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
@nanotaboada nanotaboada force-pushed the refactor/use-squad-number-for-mutation-endpoints branch from 39cf3bf to 12eaff0 Compare March 17, 2026 18:40
@sonarqubecloud
Copy link

@nanotaboada nanotaboada merged commit fc081b6 into master Mar 17, 2026
9 checks passed
@nanotaboada nanotaboada deleted the refactor/use-squad-number-for-mutation-endpoints branch March 17, 2026 18:43
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.

[REFACTOR] PUT and DELETE endpoints should use Squad Number (natural key) instead of UUID (surrogate key)

1 participant