-
Notifications
You must be signed in to change notification settings - Fork 0
Feature: Add Commander Management System #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,299 @@ | ||||||||||||||
| namespace game_sessions.Features.Sessions.Controllers; | ||||||||||||||
|
|
||||||||||||||
| using Microsoft.AspNetCore.Mvc; | ||||||||||||||
| using game_sessions.Features.Sessions.Models; | ||||||||||||||
| using game_sessions.Features.Sessions.Services; | ||||||||||||||
|
|
||||||||||||||
| /// <summary> | ||||||||||||||
| /// Controller for managing commanders | ||||||||||||||
| /// SOLID Principle: Single Responsibility Principle (SRP) | ||||||||||||||
| /// </summary> | ||||||||||||||
| [ApiController] | ||||||||||||||
| [Route("api/[controller]")] | ||||||||||||||
| public class TotoCommandersController : ControllerBase | ||||||||||||||
| { | ||||||||||||||
| private readonly ITotoCommanderService _commanderService; | ||||||||||||||
|
|
||||||||||||||
| public TotoCommandersController(ITotoCommanderService commanderService) | ||||||||||||||
| { | ||||||||||||||
| _commanderService = commanderService; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// <summary> | ||||||||||||||
| /// Retrieves all commanders | ||||||||||||||
| /// </summary> | ||||||||||||||
| /// <returns>List of all commanders</returns> | ||||||||||||||
| [HttpGet] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status200OK)] | ||||||||||||||
| public async Task<ActionResult<IEnumerable<TotoCommander>>> GetAllCommanders() | ||||||||||||||
| { | ||||||||||||||
| var commanders = await _commanderService.GetAllCommandersAsync(); | ||||||||||||||
| return Ok(commanders); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// <summary> | ||||||||||||||
| /// Retrieves a commander by its ID | ||||||||||||||
| /// </summary> | ||||||||||||||
| /// <param name="id">The commander identifier</param> | ||||||||||||||
| /// <returns>The corresponding commander</returns> | ||||||||||||||
| [HttpGet("{id}")] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status200OK)] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | ||||||||||||||
| public async Task<ActionResult<TotoCommander>> GetCommanderById(int id) | ||||||||||||||
| { | ||||||||||||||
| var commander = await _commanderService.GetCommanderByIdAsync(id); | ||||||||||||||
| if (commander == null) | ||||||||||||||
| { | ||||||||||||||
| return NotFound($"Commander with ID {id} not found."); | ||||||||||||||
| } | ||||||||||||||
| return Ok(commander); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// <summary> | ||||||||||||||
| /// Searches for commanders by name | ||||||||||||||
| /// </summary> | ||||||||||||||
| /// <param name="name">The name or partial name of the commander</param> | ||||||||||||||
| /// <returns>List of matching commanders</returns> | ||||||||||||||
| [HttpGet("search/{name}")] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status200OK)] | ||||||||||||||
| public async Task<ActionResult<IEnumerable<TotoCommander>>> SearchCommandersByName(string name) | ||||||||||||||
| { | ||||||||||||||
| var commanders = await _commanderService.SearchCommandersByNameAsync(name); | ||||||||||||||
| return Ok(commanders); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// <summary> | ||||||||||||||
| /// Filters commanders by color identity (exact match) | ||||||||||||||
| /// </summary> | ||||||||||||||
| /// <param name="colors">The color identity (comma-separated, e.g., "Red,Blue")</param> | ||||||||||||||
| /// <returns>List of commanders with matching color identity</returns> | ||||||||||||||
| [HttpGet("color-identity")] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status200OK)] | ||||||||||||||
| public async Task<ActionResult<IEnumerable<TotoCommander>>> GetCommandersByColorIdentity([FromQuery] string colors) | ||||||||||||||
| { | ||||||||||||||
| var colorList = colors.Split(',') | ||||||||||||||
| .Select(c => Enum.Parse<ManaColor>(c.Trim(), true)) | ||||||||||||||
| .ToList(); | ||||||||||||||
|
|
||||||||||||||
| var commanders = await _commanderService.GetCommandersByColorIdentityAsync(colorList); | ||||||||||||||
| return Ok(commanders); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// <summary> | ||||||||||||||
| /// Filters commanders by single color (contains) | ||||||||||||||
| /// </summary> | ||||||||||||||
| /// <param name="color">The mana color</param> | ||||||||||||||
| /// <returns>List of commanders containing this color in their identity</returns> | ||||||||||||||
| [HttpGet("color/{color}")] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status200OK)] | ||||||||||||||
| public async Task<ActionResult<IEnumerable<TotoCommander>>> GetCommandersByColor(ManaColor color) | ||||||||||||||
| { | ||||||||||||||
| var commanders = await _commanderService.GetCommandersByColorAsync(color); | ||||||||||||||
| return Ok(commanders); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// <summary> | ||||||||||||||
| /// Filters commanders by type | ||||||||||||||
| /// </summary> | ||||||||||||||
| /// <param name="type">The creature type (e.g., "Dragon", "Elf")</param> | ||||||||||||||
| /// <returns>List of commanders of the specified type</returns> | ||||||||||||||
| [HttpGet("type/{type}")] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status200OK)] | ||||||||||||||
| public async Task<ActionResult<IEnumerable<TotoCommander>>> GetCommandersByType(string type) | ||||||||||||||
| { | ||||||||||||||
| var commanders = await _commanderService.GetCommandersByTypeAsync(type); | ||||||||||||||
| return Ok(commanders); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// <summary> | ||||||||||||||
| /// Filters commanders by minimum power | ||||||||||||||
| /// </summary> | ||||||||||||||
| /// <param name="minPower">The minimum power</param> | ||||||||||||||
| /// <returns>List of commanders with at least this power</returns> | ||||||||||||||
| [HttpGet("power/{minPower}")] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status200OK)] | ||||||||||||||
| public async Task<ActionResult<IEnumerable<TotoCommander>>> GetCommandersByMinPower(int minPower) | ||||||||||||||
| { | ||||||||||||||
| var commanders = await _commanderService.GetCommandersByMinPowerAsync(minPower); | ||||||||||||||
| return Ok(commanders); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// <summary> | ||||||||||||||
| /// Filters commanders by minimum toughness | ||||||||||||||
| /// </summary> | ||||||||||||||
| /// <param name="minToughness">The minimum toughness</param> | ||||||||||||||
| /// <returns>List of commanders with at least this toughness</returns> | ||||||||||||||
| [HttpGet("toughness/{minToughness}")] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status200OK)] | ||||||||||||||
| public async Task<ActionResult<IEnumerable<TotoCommander>>> GetCommandersByMinToughness(int minToughness) | ||||||||||||||
| { | ||||||||||||||
| var commanders = await _commanderService.GetCommandersByMinToughnessAsync(minToughness); | ||||||||||||||
| return Ok(commanders); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// <summary> | ||||||||||||||
| /// Retrieves all commanders with partner ability | ||||||||||||||
| /// </summary> | ||||||||||||||
| /// <returns>List of partner commanders</returns> | ||||||||||||||
| [HttpGet("partner")] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status200OK)] | ||||||||||||||
| public async Task<ActionResult<IEnumerable<TotoCommander>>> GetPartnerCommanders() | ||||||||||||||
| { | ||||||||||||||
| var commanders = await _commanderService.GetPartnerCommandersAsync(); | ||||||||||||||
| return Ok(commanders); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// <summary> | ||||||||||||||
| /// Filters commanders by ability | ||||||||||||||
| /// </summary> | ||||||||||||||
| /// <param name="ability">The ability to search for</param> | ||||||||||||||
| /// <returns>List of commanders with this ability</returns> | ||||||||||||||
| [HttpGet("ability/{ability}")] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status200OK)] | ||||||||||||||
| public async Task<ActionResult<IEnumerable<TotoCommander>>> GetCommandersByAbility(CreatureAbility ability) | ||||||||||||||
| { | ||||||||||||||
| var commanders = await _commanderService.GetCommandersByAbilityAsync(ability); | ||||||||||||||
| return Ok(commanders); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// <summary> | ||||||||||||||
| /// Adds a new commander | ||||||||||||||
| /// </summary> | ||||||||||||||
| /// <param name="commander">The commander to add</param> | ||||||||||||||
| /// <returns>The added commander with its ID</returns> | ||||||||||||||
| [HttpPost] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status201Created)] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status400BadRequest)] | ||||||||||||||
| public async Task<ActionResult<TotoCommander>> AddCommander([FromBody] TotoCommander commander) | ||||||||||||||
| { | ||||||||||||||
| if (string.IsNullOrWhiteSpace(commander.Name)) | ||||||||||||||
| { | ||||||||||||||
| return BadRequest("The commander name is required."); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| var addedCommander = await _commanderService.AddCommanderAsync(commander); | ||||||||||||||
| return CreatedAtAction(nameof(GetCommanderById), new { id = addedCommander.Id }, addedCommander); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// <summary> | ||||||||||||||
| /// Updates an existing commander | ||||||||||||||
| /// </summary> | ||||||||||||||
| /// <param name="id">The commander identifier</param> | ||||||||||||||
| /// <param name="commander">The updated data</param> | ||||||||||||||
| /// <returns>The result of the operation</returns> | ||||||||||||||
| [HttpPut("{id}")] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status204NoContent)] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | ||||||||||||||
| public async Task<IActionResult> UpdateCommander(int id, [FromBody] TotoCommander commander) | ||||||||||||||
| { | ||||||||||||||
| var success = await _commanderService.UpdateCommanderAsync(id, commander); | ||||||||||||||
| if (!success) | ||||||||||||||
| { | ||||||||||||||
| return NotFound($"Commander with ID {id} not found."); | ||||||||||||||
| } | ||||||||||||||
| return NoContent(); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// <summary> | ||||||||||||||
| /// Deletes a commander | ||||||||||||||
| /// </summary> | ||||||||||||||
| /// <param name="id">The commander identifier</param> | ||||||||||||||
| /// <returns>The result of the operation</returns> | ||||||||||||||
| [HttpDelete("{id}")] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status204NoContent)] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | ||||||||||||||
| public async Task<IActionResult> DeleteCommander(int id) | ||||||||||||||
| { | ||||||||||||||
| var success = await _commanderService.DeleteCommanderAsync(id); | ||||||||||||||
| if (!success) | ||||||||||||||
| { | ||||||||||||||
| return NotFound($"Commander with ID {id} not found."); | ||||||||||||||
| } | ||||||||||||||
| return NoContent(); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// <summary> | ||||||||||||||
| /// Calculates the commander tax for a commander | ||||||||||||||
| /// </summary> | ||||||||||||||
| /// <param name="id">The commander identifier</param> | ||||||||||||||
| /// <returns>The additional mana cost due to commander tax</returns> | ||||||||||||||
| [HttpGet("{id}/tax")] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status200OK)] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | ||||||||||||||
| public async Task<ActionResult<int>> CalculateCommanderTax(int id) | ||||||||||||||
| { | ||||||||||||||
| var commander = await _commanderService.GetCommanderByIdAsync(id); | ||||||||||||||
| if (commander == null) | ||||||||||||||
| { | ||||||||||||||
| return NotFound($"Commander with ID {id} not found."); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| var tax = await _commanderService.CalculateCommanderTaxAsync(id); | ||||||||||||||
| return Ok(new { CommanderId = id, CommanderTax = tax }); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// <summary> | ||||||||||||||
| /// Records commander damage dealt to a player | ||||||||||||||
| /// </summary> | ||||||||||||||
| /// <param name="id">The commander identifier</param> | ||||||||||||||
| /// <param name="playerId">The target player identifier</param> | ||||||||||||||
| /// <param name="damage">The amount of damage dealt</param> | ||||||||||||||
| /// <returns>The result of the operation</returns> | ||||||||||||||
| [HttpPost("{id}/damage")] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status200OK)] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | ||||||||||||||
| public async Task<IActionResult> RecordCommanderDamage(int id, [FromQuery] int playerId, [FromQuery] int damage) | ||||||||||||||
| { | ||||||||||||||
| var success = await _commanderService.RecordCommanderDamageAsync(id, playerId, damage); | ||||||||||||||
| if (!success) | ||||||||||||||
| { | ||||||||||||||
| return NotFound($"Commander with ID {id} not found."); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| var totalDamage = await _commanderService.GetCommanderDamageToPlayerAsync(id, playerId); | ||||||||||||||
| return Ok(new { CommanderId = id, PlayerId = playerId, DamageDealt = damage, TotalDamage = totalDamage }); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// <summary> | ||||||||||||||
| /// Gets total commander damage dealt to a player | ||||||||||||||
| /// </summary> | ||||||||||||||
| /// <param name="id">The commander identifier</param> | ||||||||||||||
| /// <param name="playerId">The target player identifier</param> | ||||||||||||||
| /// <returns>Total damage dealt</returns> | ||||||||||||||
| [HttpGet("{id}/damage/{playerId}")] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status200OK)] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | ||||||||||||||
| public async Task<ActionResult<int>> GetCommanderDamageToPlayer(int id, int playerId) | ||||||||||||||
| { | ||||||||||||||
| var commander = await _commanderService.GetCommanderByIdAsync(id); | ||||||||||||||
| if (commander == null) | ||||||||||||||
| { | ||||||||||||||
| return NotFound($"Commander with ID {id} not found."); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| var totalDamage = await _commanderService.GetCommanderDamageToPlayerAsync(id, playerId); | ||||||||||||||
| return Ok(new { CommanderId = id, PlayerId = playerId, TotalDamage = totalDamage }); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// <summary> | ||||||||||||||
| /// Moves a commander to a different zone | ||||||||||||||
| /// </summary> | ||||||||||||||
| /// <param name="id">The commander identifier</param> | ||||||||||||||
| /// <param name="zone">The destination zone</param> | ||||||||||||||
| /// <returns>The result of the operation</returns> | ||||||||||||||
| [HttpPost("{id}/move")] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status200OK)] | ||||||||||||||
| [ProducesResponseType(StatusCodes.Status404NotFound)] | ||||||||||||||
| public async Task<IActionResult> MoveCommanderToZone(int id, [FromQuery] CommanderZone zone) | ||||||||||||||
| { | ||||||||||||||
| var success = await _commanderService.MoveCommanderToZoneAsync(id, zone); | ||||||||||||||
| if (!success) | ||||||||||||||
| { | ||||||||||||||
| return NotFound($"Commander with ID {id} not found."); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| var commander = await _commanderService.GetCommanderByIdAsync(id); | ||||||||||||||
| return Ok(new { CommanderId = id, CurrentZone = commander!.CurrentZone, CommanderTaxCount = commander.CommanderTaxCount }); | ||||||||||||||
|
||||||||||||||
| return Ok(new { CommanderId = id, CurrentZone = commander!.CurrentZone, CommanderTaxCount = commander.CommanderTaxCount }); | |
| if (commander == null) | |
| { | |
| return NotFound($"Commander with ID {id} not found after move."); | |
| } | |
| return Ok(new { CommanderId = id, CurrentZone = commander.CurrentZone, CommanderTaxCount = commander.CommanderTaxCount }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enum.Parse will throw an exception for invalid color values. Wrap this in a try-catch block and return a BadRequest with a descriptive error message listing valid ManaColor values when parsing fails.