diff --git a/.github/workflows/dependabot_automerge.yml b/.github/workflows/dependabot_automerge.yml
index eb912398..5132852e 100644
--- a/.github/workflows/dependabot_automerge.yml
+++ b/.github/workflows/dependabot_automerge.yml
@@ -12,7 +12,7 @@ jobs:
steps:
- name: Dependabot metadata
id: metadata
- uses: dependabot/fetch-metadata@v2.2.0
+ uses: dependabot/fetch-metadata@v2.3.0
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
- name: Enable auto-merge for Dependabot PRs
diff --git a/PathfinderHonorManager.Tests/PathfinderHonorManager.Tests.csproj b/PathfinderHonorManager.Tests/PathfinderHonorManager.Tests.csproj
index 95c90ea3..59e5a5d5 100644
--- a/PathfinderHonorManager.Tests/PathfinderHonorManager.Tests.csproj
+++ b/PathfinderHonorManager.Tests/PathfinderHonorManager.Tests.csproj
@@ -8,20 +8,20 @@
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
-
-
-
+
+
+
+
-
+
diff --git a/PathfinderHonorManager/Controllers/ClubController.cs b/PathfinderHonorManager/Controllers/ClubController.cs
index 93cd84d9..331a9c88 100644
--- a/PathfinderHonorManager/Controllers/ClubController.cs
+++ b/PathfinderHonorManager/Controllers/ClubController.cs
@@ -7,6 +7,8 @@
using Microsoft.AspNetCore.Mvc;
using PathfinderHonorManager.Model;
using PathfinderHonorManager.Service.Interfaces;
+using Microsoft.Extensions.Logging;
+using System.Linq;
namespace PathfinderHonorManager.Controllers
{
@@ -20,10 +22,12 @@ namespace PathfinderHonorManager.Controllers
public class ClubsController : ControllerBase
{
private readonly IClubService _clubService;
+ private readonly ILogger _logger;
- public ClubsController(IClubService clubService)
+ public ClubsController(IClubService clubService, ILogger logger)
{
_clubService = clubService;
+ _logger = logger;
}
// GET Clubs
@@ -39,24 +43,30 @@ public async Task>> GetClubs(CancellationToken to
{
if (clubcode == null)
{
+ _logger.LogInformation("Getting all clubs");
var clubs = await _clubService.GetAllAsync(token);
if (clubs == default)
{
+ _logger.LogWarning("No clubs found");
return NotFound();
}
+ _logger.LogInformation("Retrieved {Count} clubs", clubs.Count());
return Ok(clubs);
}
else
{
+ _logger.LogInformation("Getting club with code {ClubCode}", clubcode);
var club = await _clubService.GetByCodeAsync(clubcode.ToUpper(), token);
if (club == default)
{
+ _logger.LogWarning("Club with code {ClubCode} not found", clubcode);
return NotFound();
}
+ _logger.LogInformation("Retrieved club with code {ClubCode}", clubcode);
return Ok(club);
}
}
@@ -73,13 +83,16 @@ public async Task>> GetClubs(CancellationToken to
[HttpGet("{id:guid}")]
public async Task GetByIdAsync(Guid id, CancellationToken token)
{
+ _logger.LogInformation("Getting club with ID {ClubId}", id);
var club = await _clubService.GetByIdAsync(id, token);
if (club == default)
{
+ _logger.LogWarning("Club with ID {ClubId} not found", id);
return NotFound();
}
+ _logger.LogInformation("Retrieved club with ID {ClubId}", id);
return Ok(club);
}
}
diff --git a/PathfinderHonorManager/Controllers/HonorsController.cs b/PathfinderHonorManager/Controllers/HonorsController.cs
index 7f9034cd..0f88972a 100644
--- a/PathfinderHonorManager/Controllers/HonorsController.cs
+++ b/PathfinderHonorManager/Controllers/HonorsController.cs
@@ -9,6 +9,8 @@
using PathfinderHonorManager.Service.Interfaces;
using Incoming = PathfinderHonorManager.Dto.Incoming;
using Microsoft.AspNetCore.Authorization;
+using Microsoft.Extensions.Logging;
+using System.Linq;
namespace PathfinderHonorManager.Controllers
{
@@ -22,10 +24,12 @@ namespace PathfinderHonorManager.Controllers
public class HonorsController : CustomApiController
{
private readonly IHonorService _honorService;
+ private readonly ILogger _logger;
- public HonorsController(IHonorService honorService)
+ public HonorsController(IHonorService honorService, ILogger logger)
{
_honorService = honorService;
+ _logger = logger;
}
// GET Honors
@@ -38,13 +42,16 @@ public HonorsController(IHonorService honorService)
[HttpGet]
public async Task>> GetHonors(CancellationToken token)
{
+ _logger.LogInformation("Getting all honors");
var honors = await this._honorService.GetAllAsync(token);
if (honors == default)
{
+ _logger.LogWarning("No honors found");
return NotFound();
}
+ _logger.LogInformation("Retrieved {Count} honors", honors.Count());
return Ok(honors);
}
@@ -60,13 +67,16 @@ public async Task>> GetHonors(CancellationToken
[HttpGet("{id:guid}")]
public async Task GetByIdAsync(Guid id, CancellationToken token)
{
+ _logger.LogInformation("Getting honor with ID {HonorId}", id);
var honor = await this._honorService.GetByIdAsync(id, token);
if (honor == default)
{
+ _logger.LogWarning("Honor with ID {HonorId} not found", id);
return NotFound();
}
+ _logger.LogInformation("Retrieved honor with ID {HonorId}", id);
return Ok(new { id = honor.HonorID, honor });
}
@@ -83,21 +93,25 @@ public async Task GetByIdAsync(Guid id, CancellationToken token)
[HttpPost]
public async Task> Post([FromBody] Incoming.HonorDto newHonor, CancellationToken token)
{
+ _logger.LogInformation("Creating new honor");
try
{
var honor = await _honorService.AddAsync(newHonor, token);
+ _logger.LogInformation("Created honor with ID {HonorId}", honor.HonorID);
return CreatedAtRoute(
routeValues: GetByIdAsync(honor.HonorID, token),
honor);
}
catch (FluentValidation.ValidationException ex)
{
+ _logger.LogWarning(ex, "Validation failed while creating honor");
UpdateModelState(ex);
return ValidationProblem(ModelState);
}
catch (DbUpdateException ex)
{
+ _logger.LogError(ex, "Database error while creating honor");
return ValidationProblem(ex.Message);
}
}
@@ -116,20 +130,37 @@ public async Task> Post([FromBody] Incoming.HonorDto newHono
[HttpPut("{id:guid}")]
public async Task Put(Guid id, [FromBody] Incoming.HonorDto updatedHonor, CancellationToken token)
{
+ _logger.LogInformation("Updating honor with ID {HonorId}", id);
var honor = await _honorService.GetByIdAsync(id, token);
if (honor == default)
{
+ _logger.LogWarning("Honor with ID {HonorId} not found", id);
return NotFound();
}
- await _honorService.UpdateAsync(id, updatedHonor, token);
+ try
+ {
+ await _honorService.UpdateAsync(id, updatedHonor, token);
- honor = await _honorService.GetByIdAsync(id, token);
+ honor = await _honorService.GetByIdAsync(id, token);
+ _logger.LogInformation("Updated honor with ID {HonorId}", id);
- return honor != default
- ? Ok(honor)
- : NotFound();
+ return honor != default
+ ? Ok(honor)
+ : NotFound();
+ }
+ catch (FluentValidation.ValidationException ex)
+ {
+ _logger.LogWarning(ex, "Validation failed while updating honor with ID {HonorId}", id);
+ UpdateModelState(ex);
+ return ValidationProblem(ModelState);
+ }
+ catch (DbUpdateException ex)
+ {
+ _logger.LogError(ex, "Database error while updating honor with ID {HonorId}", id);
+ return ValidationProblem(ex.Message);
+ }
}
}
}
diff --git a/PathfinderHonorManager/Controllers/PathfinderController.cs b/PathfinderHonorManager/Controllers/PathfinderController.cs
index 5e2ee064..8c0a94b1 100644
--- a/PathfinderHonorManager/Controllers/PathfinderController.cs
+++ b/PathfinderHonorManager/Controllers/PathfinderController.cs
@@ -11,6 +11,7 @@
using Microsoft.AspNetCore.Authorization;
using System.Linq;
using Microsoft.AspNetCore.Routing;
+using Microsoft.Extensions.Logging;
namespace PathfinderHonorManager.Controllers
{
@@ -24,6 +25,7 @@ namespace PathfinderHonorManager.Controllers
public class PathfindersController : CustomApiController
{
private readonly IPathfinderService _pathfinderService;
+ private readonly ILogger _logger;
private string GetClubCodeFromContext()
{
@@ -31,9 +33,10 @@ private string GetClubCodeFromContext()
return clubCode;
}
- public PathfindersController(IPathfinderService pathfinderService)
+ public PathfindersController(IPathfinderService pathfinderService, ILogger logger)
{
_pathfinderService = pathfinderService;
+ _logger = logger;
}
// GET Pathfinders
@@ -48,13 +51,17 @@ public PathfindersController(IPathfinderService pathfinderService)
public async Task>> GetAll(CancellationToken token, bool showInactive = false)
{
var clubCode = GetClubCodeFromContext();
+ _logger.LogInformation("Getting all pathfinders for club {ClubCode}, showInactive: {ShowInactive}", clubCode, showInactive);
+
var pathfinders = await _pathfinderService.GetAllAsync(clubCode, showInactive, token);
if (pathfinders == null || !pathfinders.Any())
{
+ _logger.LogWarning("No pathfinders found for club {ClubCode}", clubCode);
return NotFound();
}
+ _logger.LogInformation("Retrieved {Count} pathfinders for club {ClubCode}", pathfinders.Count(), clubCode);
return Ok(pathfinders);
}
@@ -71,13 +78,17 @@ public PathfindersController(IPathfinderService pathfinderService)
public async Task GetByIdAsync(Guid id, CancellationToken token)
{
var clubCode = GetClubCodeFromContext();
+ _logger.LogInformation("Getting pathfinder with ID {PathfinderId} for club {ClubCode}", id, clubCode);
+
var pathfinder = await _pathfinderService.GetByIdAsync(id, clubCode, token);
if (pathfinder == default)
{
+ _logger.LogWarning("Pathfinder with ID {PathfinderId} not found for club {ClubCode}", id, clubCode);
return NotFound();
}
+ _logger.LogInformation("Retrieved pathfinder with ID {PathfinderId} for club {ClubCode}", id, clubCode);
return Ok(pathfinder);
}
@@ -95,24 +106,28 @@ public async Task GetByIdAsync(Guid id, CancellationToken token)
public async Task PostAsync([FromBody] Incoming.PathfinderDto newPathfinder, CancellationToken token)
{
var clubCode = GetClubCodeFromContext();
+ _logger.LogInformation("Creating new pathfinder for club {ClubCode}", clubCode);
+
try
{
var pathfinder = await _pathfinderService.AddAsync(newPathfinder, clubCode, token);
+ _logger.LogInformation("Created pathfinder with ID {PathfinderId} for club {ClubCode}", pathfinder.PathfinderID, clubCode);
return CreatedAtRoute(
routeValues: GetByIdAsync(pathfinder.PathfinderID, token),
pathfinder);
}
catch (FluentValidation.ValidationException ex)
{
+ _logger.LogWarning(ex, "Validation failed while creating pathfinder for club {ClubCode}", clubCode);
UpdateModelState(ex);
return ValidationProblem(ModelState);
}
catch (DbUpdateException ex)
{
+ _logger.LogError(ex, "Database error while creating pathfinder for club {ClubCode}", clubCode);
return ValidationProblem(ex.Message);
}
-
}
// PUT Pathfinders/{pathfinderId}
@@ -130,21 +145,30 @@ public async Task PostAsync([FromBody] Incoming.PathfinderDto new
public async Task PutAsync(Guid pathfinderId, [FromBody] Incoming.PutPathfinderDto updatedPathfinder, CancellationToken token)
{
var clubCode = GetClubCodeFromContext();
+ _logger.LogInformation("Updating pathfinder with ID {PathfinderId} for club {ClubCode}", pathfinderId, clubCode);
+
try
{
var pathfinder = await _pathfinderService.UpdateAsync(pathfinderId, updatedPathfinder, clubCode, token);
- return pathfinder != default
- ? Ok(pathfinder)
- : NotFound();
+ if (pathfinder == default)
+ {
+ _logger.LogWarning("Pathfinder with ID {PathfinderId} not found for club {ClubCode}", pathfinderId, clubCode);
+ return NotFound();
+ }
+
+ _logger.LogInformation("Updated pathfinder with ID {PathfinderId} for club {ClubCode}", pathfinderId, clubCode);
+ return Ok(pathfinder);
}
catch (FluentValidation.ValidationException ex)
{
+ _logger.LogWarning(ex, "Validation failed while updating pathfinder with ID {PathfinderId} for club {ClubCode}", pathfinderId, clubCode);
UpdateModelState(ex);
return ValidationProblem(ModelState);
}
catch (DbUpdateException ex)
{
+ _logger.LogError(ex, "Database error while updating pathfinder with ID {PathfinderId} for club {ClubCode}", pathfinderId, clubCode);
return ValidationProblem(ex.Message);
}
}
@@ -163,6 +187,8 @@ public async Task PutAsync(Guid pathfinderId, [FromBody] Incoming
public async Task BulkPutPathfindersAsync([FromBody] IEnumerable bulkData, CancellationToken token)
{
var clubCode = GetClubCodeFromContext();
+ _logger.LogInformation("Bulk updating {Count} pathfinders for club {ClubCode}", bulkData.Count(), clubCode);
+
var responses = new List