Skip to content
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

Access layer for admin notes #431

Merged
merged 3 commits into from
Sep 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions API/DTOs/AdminNoteDTO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
namespace API.DTOs;

/// <summary>
/// Represents a note for an entity created by an admin
/// </summary>
public class AdminNoteDTO
{
/// <summary>
/// Id
/// </summary>
public int Id { get; init; }

/// <summary>
/// Timestamp of creation
/// </summary>
public DateTime Created { get; init; }

/// <summary>
/// Timestamp of the last update if available
/// </summary>
public DateTime? Updated { get; init; }

/// <summary>
/// Id of the parent entity
/// </summary>
public int ReferenceId { get; init; }

/// <summary>
/// Id of the admin user that created the note
/// </summary>
public int AdminUserId { get; set; }

/// <summary>
/// Username of the admin user that created the note
/// </summary>
public string? AdminUsername { get; init; }

/// <summary>
/// Content of the note
/// </summary>
public string Note { get; init; } = string.Empty;
}
67 changes: 67 additions & 0 deletions API/Services/Implementations/AdminNoteService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using API.DTOs;
using API.Services.Interfaces;
using AutoMapper;
using Database.Entities;
using Database.Repositories.Interfaces;

namespace API.Services.Implementations;

public class AdminNoteService(
IAdminNoteRepository adminNoteRepository,
IUserRepository userRepository,
IMapper mapper
) : IAdminNoteService
{
public async Task<AdminNoteDTO?> CreateAsync<TAdminNote>(int referenceId, int adminUserId, string note)
where TAdminNote : AdminNoteEntityBase, new()
{
if (!await userRepository.ExistsAsync(adminUserId))
{
return null;
}

var entity = new TAdminNote
{
ReferenceId = referenceId,
AdminUserId = adminUserId,
Note = note
};

await adminNoteRepository.CreateAsync(entity);
return mapper.Map<AdminNoteDTO>(entity);
}

public async Task<AdminNoteDTO?> GetAsync<TAdminNote>(int id) where TAdminNote : AdminNoteEntityBase =>
mapper.Map<AdminNoteDTO>(await adminNoteRepository.GetAsync<TAdminNote>(id));

public async Task<IEnumerable<AdminNoteDTO>> ListAsync<TAdminNote>(int referenceId) where TAdminNote : AdminNoteEntityBase =>
mapper.Map<IEnumerable<AdminNoteDTO>>(await adminNoteRepository.ListAsync<TAdminNote>(referenceId));

public async Task<AdminNoteDTO?> UpdateAsync<TAdminNote>(int id, string note) where TAdminNote : AdminNoteEntityBase
{
TAdminNote? adminNote = await adminNoteRepository.GetAsync<TAdminNote>(id);

if (adminNote is null)
{
return null;
}

adminNote.Note = note;
await adminNoteRepository.UpdateAsync(adminNote);

return mapper.Map<AdminNoteDTO>(adminNote);
}

public async Task<bool> DeleteAsync<TAdminNote>(int id) where TAdminNote : AdminNoteEntityBase
{
TAdminNote? adminNote = await adminNoteRepository.GetAsync<TAdminNote>(id);

if (adminNote is null)
{
return false;
}

await adminNoteRepository.DeleteAsync(adminNote);
return true;
}
}
60 changes: 60 additions & 0 deletions API/Services/Interfaces/IAdminNoteService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using API.DTOs;
using Database.Entities;

namespace API.Services.Interfaces;

public interface IAdminNoteService
{
/// <summary>
/// Creates a <typeparamref name="TAdminNote"/>
/// </summary>
/// <param name="referenceId">Id of the parent entity</param>
/// <param name="adminUserId">Id of the admin <see cref="User"/> creating the <typeparamref name="TAdminNote"/></param>
/// <param name="note">Content of the <typeparamref name="TAdminNote"/></param>
/// <typeparam name="TAdminNote">The type of admin note being created</typeparam>
/// <returns>
/// The created <see cref="AdminNoteDTO"/> if successful, or null if a <see cref="User"/> for the
/// given <paramref name="adminUserId"/> does not exist
/// </returns>
/// <remarks>
/// This method checks for existence of the admin <see cref="User"/>, but checking for existence of the parent
/// entity should be handled by the caller
/// </remarks>
Task<AdminNoteDTO?> CreateAsync<TAdminNote>(int referenceId, int adminUserId, string note)
where TAdminNote : AdminNoteEntityBase, new();

/// <summary>
/// Gets an <see cref="AdminNoteDTO"/>
/// </summary>
/// <param name="id">Id of the <typeparamref name="TAdminNote"/></param>
/// <typeparam name="TAdminNote">The type of admin note being retrieved</typeparam>
/// <returns>The <see cref="AdminNoteDTO"/>, or null if not found</returns>
Task<AdminNoteDTO?> GetAsync<TAdminNote>(int id) where TAdminNote : AdminNoteEntityBase;

/// <summary>
/// Gets a collection of <see cref="AdminNoteDTO"/>s by their parent reference Id.
/// </summary>
/// <param name="referenceId">Id of the parent entity</param>
/// <typeparam name="TAdminNote">The type of admin note being retrieved</typeparam>
/// <returns>A collection of <see cref="AdminNoteDTO"/>s for the given referenceId</returns>
Task<IEnumerable<AdminNoteDTO>> ListAsync<TAdminNote>(int referenceId) where TAdminNote : AdminNoteEntityBase;

/// <summary>
/// Updates the <see cref="AdminNoteEntityBase.Note"/> of a <typeparamref name="TAdminNote"/>
/// </summary>
/// <param name="id">Id of the <typeparamref name="TAdminNote"/></param>
/// <param name="note">The new note</param>
/// <typeparam name="TAdminNote">The type of admin note being updated</typeparam>
/// <returns>The updated <see cref="AdminNoteDTO"/>, or null if not found</returns>
Task<AdminNoteDTO?> UpdateAsync<TAdminNote>(int id, string note) where TAdminNote : AdminNoteEntityBase;

/// <summary>
/// Deletes a <typeparamref name="TAdminNote"/>
/// </summary>
/// <param name="id">Id of the <typeparamref name="TAdminNote"/></param>
/// <typeparam name="TAdminNote">The type of admin note being deleted</typeparam>
/// <returns>
/// True if successful, false if a <see cref="AdminNoteDTO"/> for the given id does not exist
/// </returns>
Task<bool> DeleteAsync<TAdminNote>(int id) where TAdminNote : AdminNoteEntityBase;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ public async Task CreateAsync<TAdminNote>(TAdminNote entity) where TAdminNote :
}

public async Task<TAdminNote?> GetAsync<TAdminNote>(int id) where TAdminNote : AdminNoteEntityBase =>
await context.Set<TAdminNote>().FirstOrDefaultAsync(an => an.Id == id);
await context.Set<TAdminNote>()
.Include(an => an.AdminUser.Player)
.AsSingleQuery()
.FirstOrDefaultAsync(an => an.Id == id);

public async Task<IEnumerable<TAdminNote>> ListAsync<TAdminNote>(int referenceId) where TAdminNote : AdminNoteEntityBase =>
await context.Set<TAdminNote>()
Expand Down
6 changes: 5 additions & 1 deletion Database/Repositories/Interfaces/IAdminNoteRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ public interface IAdminNoteRepository
/// <param name="id">Id of the <typeparamref name="TAdminNote"/></param>
/// <typeparam name="TAdminNote">The type of admin note being retrieved</typeparam>
/// <returns>The <typeparamref name="TAdminNote"/>, or null if not found</returns>
/// <remarks>
/// Includes the <see cref="AdminNoteEntityBase.AdminUser"/> and <see cref="User.Player"/>.
/// Returned entities are tracked by the context
/// </remarks>
Task<TAdminNote?> GetAsync<TAdminNote>(int id) where TAdminNote : AdminNoteEntityBase;

/// <summary>
/// Gets a collection of <typeparamref name="TAdminNote"/> entities by their parent reference Id.
/// </summary>
/// <param name="referenceId">The id of the parent entity.</param>
/// <param name="referenceId">Id of the parent entity.</param>
/// <typeparam name="TAdminNote">The type of admin note being retrieved</typeparam>
/// <returns>A collection of <typeparamref name="TAdminNote"/>s for the given referenceId</returns>
/// <remarks>
Expand Down
Loading