From 16319e5625cc28bfb5a890faeaa6693166cd08b5 Mon Sep 17 00:00:00 2001 From: Nguyen Quang Chien Date: Sat, 27 May 2023 21:16:54 +0700 Subject: [PATCH 01/11] refactor: controller endpoints --- src/Api/Controllers/AuthController.cs | 53 ++++-- src/Api/Controllers/DepartmentsController.cs | 50 +++--- src/Api/Controllers/DocumentsController.cs | 91 ++++++---- src/Api/Controllers/FoldersController.cs | 24 ++- src/Api/Controllers/LockersController.cs | 72 +++++--- .../Payload/Requests/Auth/LoginModel.cs | 7 + .../{ => Auth}/RefreshTokenRequest.cs | 2 +- .../UpdateDepartmentRequest.cs | 2 +- ...GetAllDocumentsPaginatedQueryParameters.cs | 13 ++ .../Payload/Requests/LoginModel.cs | 7 - .../GetAllRoomsPaginatedQueryParameters.cs | 9 + ...EmptyContainersPaginatedQueryParameters.cs | 7 + .../Requests/{ => Rooms}/UpdateRoomRequest.cs | 2 +- src/Api/Controllers/RoomsController.cs | 163 +++++++++++------- src/Api/Controllers/StaffsController.cs | 5 +- src/Api/Controllers/UsersController.cs | 46 +++-- .../GetAllDocumentsPaginatedQuery.cs | 1 + .../GetDocumentById/GetDocumentByIdQuery.cs | 4 +- .../GetEmptyContainersPaginatedQuery.cs | 10 +- 19 files changed, 353 insertions(+), 215 deletions(-) create mode 100644 src/Api/Controllers/Payload/Requests/Auth/LoginModel.cs rename src/Api/Controllers/Payload/Requests/{ => Auth}/RefreshTokenRequest.cs (71%) rename src/Api/Controllers/Payload/Requests/{ => Departments}/UpdateDepartmentRequest.cs (60%) create mode 100644 src/Api/Controllers/Payload/Requests/Documents/GetAllDocumentsPaginatedQueryParameters.cs delete mode 100644 src/Api/Controllers/Payload/Requests/LoginModel.cs create mode 100644 src/Api/Controllers/Payload/Requests/Rooms/GetAllRoomsPaginatedQueryParameters.cs create mode 100644 src/Api/Controllers/Payload/Requests/Rooms/GetEmptyContainersPaginatedQueryParameters.cs rename src/Api/Controllers/Payload/Requests/{ => Rooms}/UpdateRoomRequest.cs (76%) diff --git a/src/Api/Controllers/AuthController.cs b/src/Api/Controllers/AuthController.cs index efdd1591..3701f480 100644 --- a/src/Api/Controllers/AuthController.cs +++ b/src/Api/Controllers/AuthController.cs @@ -1,6 +1,7 @@ using System.IdentityModel.Tokens.Jwt; using System.Security.Authentication; using Api.Controllers.Payload.Requests; +using Api.Controllers.Payload.Requests.Auth; using Api.Controllers.Payload.Responses; using Application.Common.Interfaces; using Application.Common.Models; @@ -23,6 +24,11 @@ public AuthController(IIdentityService identityService) _identityService = identityService; } + /// + /// Login + /// + /// Login credentials + /// A LoginResult indicating the result of logging in [AllowAnonymous] [HttpPost] [ProducesResponseType(StatusCodes.Status200OK)] @@ -48,23 +54,11 @@ public async Task>> Login([FromBody] LoginModel return Ok(Result.Succeed(loginResult)); } - - [HttpPost] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public async Task Logout() - { - var refreshToken = Request.Cookies[nameof(RefreshToken)]; - var jweToken = Request.Cookies["JweToken"]; - - RemoveJweToken(); - RemoveRefreshToken(); - - await _identityService.LogoutAsync(jweToken!, refreshToken!); - - return Ok(); - } - + + /// + /// Refresh session and token + /// + /// An IActionResult indicating the result of refreshing token [HttpPost] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] @@ -90,6 +84,10 @@ public async Task Refresh() return Ok(); } + /// + /// Validate current user + /// + /// An IActionResult indicating the result of validating the user [Authorize] [HttpPost] [ProducesResponseType(StatusCodes.Status200OK)] @@ -99,11 +97,32 @@ public IActionResult Validate() return Ok(); } + /// + /// Logout of the system + /// + /// An IActionResult indicating the result of logging out of the system + [HttpPost] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + public async Task Logout() + { + var refreshToken = Request.Cookies[nameof(RefreshToken)]; + var jweToken = Request.Cookies["JweToken"]; + + RemoveJweToken(); + RemoveRefreshToken(); + + await _identityService.LogoutAsync(jweToken!, refreshToken!); + + return Ok(); + } + private void SetJweToken(SecurityToken jweToken, RefreshTokenDto newRefreshToken) { var cookieOptions = new CookieOptions { HttpOnly = true, + Expires = newRefreshToken.ExpiryDateTime }; var handler = new JwtSecurityTokenHandler(); Response.Cookies.Append("JweToken", handler.WriteToken(jweToken), cookieOptions); diff --git a/src/Api/Controllers/DepartmentsController.cs b/src/Api/Controllers/DepartmentsController.cs index 98045cf7..950cbef5 100644 --- a/src/Api/Controllers/DepartmentsController.cs +++ b/src/Api/Controllers/DepartmentsController.cs @@ -1,4 +1,5 @@ using Api.Controllers.Payload.Requests; +using Api.Controllers.Payload.Requests.Departments; using Application.Common.Models; using Application.Departments.Commands.DeleteDepartment; using Application.Departments.Commands.UpdateDepartment; @@ -15,52 +16,53 @@ namespace Api.Controllers; public class DepartmentsController : ApiControllerBase { /// - /// Create a department + /// Get back a department based on its id /// - /// command parameter to create a department - /// Result[DepartmentDto] - [RequiresRole(IdentityData.Roles.Admin)] - [HttpPost] + /// id of the department to be retrieved + /// A DepartmentDto of the retrieved department + [HttpGet("{departmentId:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] - [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> AddDepartment([FromBody] AddDepartmentCommand command) + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task>> GetById([FromRoute] Guid departmentId) { - var result = await Mediator.Send(command); + var query = new GetDepartmentByIdQuery() + { + DepartmentId = departmentId + }; + var result = await Mediator.Send(query); return Ok(Result.Succeed(result)); } - + /// /// Get all documents /// - /// a Result of an IEnumerable of DepartmentDto + /// A list of DocumentDto [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] - public async Task>>> GetAllDepartments() + public async Task>>> GetAll() { var result = await Mediator.Send(new GetAllDepartmentsQuery()); return Ok(Result>.Succeed(result)); } /// - /// Get back a department based on its id + /// Add a department /// - /// id of the department to be retrieved - /// A DepartmentDto of the retrieved department - [HttpGet("{departmentId:guid}")] + /// command parameter to add a department + /// A DepartmentDto of the the added department + [RequiresRole(IdentityData.Roles.Admin)] + [HttpPost] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] - public async Task>> GetDepartmentById([FromRoute] Guid departmentId) + [ProducesResponseType(StatusCodes.Status409Conflict)] + public async Task>> Add([FromBody] AddDepartmentCommand command) { - var query = new GetDepartmentByIdQuery() - { - DepartmentId = departmentId - }; - var result = await Mediator.Send(query); + var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); } - + /// /// Update a department /// @@ -72,7 +74,7 @@ public async Task>> GetDepartmentById([FromRo [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task>> UpdateDepartment([FromRoute] Guid departmentId, [FromBody] UpdateDepartmentRequest request) + public async Task>> Update([FromRoute] Guid departmentId, [FromBody] UpdateDepartmentRequest request) { var command = new UpdateDepartmentCommand() { @@ -93,7 +95,7 @@ public async Task>> UpdateDepartment([FromRou [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task>> DeleteDepartment([FromRoute] Guid departmentId) + public async Task>> Delete([FromRoute] Guid departmentId) { var command = new DeleteDepartmentCommand() { diff --git a/src/Api/Controllers/DocumentsController.cs b/src/Api/Controllers/DocumentsController.cs index 41f8fb3d..2fba9633 100644 --- a/src/Api/Controllers/DocumentsController.cs +++ b/src/Api/Controllers/DocumentsController.cs @@ -15,65 +15,86 @@ namespace Api.Controllers; public class DocumentsController : ApiControllerBase { - [RequiresRole(IdentityData.Roles.Admin, IdentityData.Roles.Staff)] - [HttpPost] + /// + /// Get a document by id + /// + /// Id of the document to be retrieved + /// A DocumentDto of the retrieved document + [HttpGet("{documentId:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> ImportDocument([FromBody] ImportDocumentCommand command) + public async Task>> GetById(Guid documentId) { - var result = await Mediator.Send(command); + var query = new GetDocumentByIdQuery() + { + DocumentId = documentId + }; + var result = await Mediator.Send(query); return Ok(Result.Succeed(result)); } - [RequiresRole(IdentityData.Roles.Admin, IdentityData.Roles.Staff)] - [HttpGet("types")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status403Forbidden)] - public async Task>>> GetAllDocumentTypes() - { - var result = await Mediator.Send(new GetAllDocumentTypesQuery()); - return Ok(Result>.Succeed(result)); - } - + /// + /// Get all documents paginated + /// + /// Get all documents query parameters + /// A paginated list of DocumentDto [RequiresRole(IdentityData.Roles.Admin, IdentityData.Roles.Staff)] [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>>> GetAllDocuments(Guid? roomId, Guid? lockerId, Guid? folderId, int? page, int? size, string? sortBy, string? sortOrder) + public async Task>>> GetAllPaginated( + [FromQuery] GetAllDocumentsPaginatedQueryParameters queryParameters) { var query = new GetAllDocumentsPaginatedQuery() { - RoomId = roomId, - LockerId = lockerId, - FolderId = folderId, - Page = page, - Size = size, - SortBy = sortBy, - SortOrder = sortOrder + RoomId = queryParameters.RoomId, + LockerId = queryParameters.LockerId, + FolderId = queryParameters.FolderId, + SearchTerm = queryParameters.SearchTerm, + Page = queryParameters.Page, + Size = queryParameters.Size, + SortBy = queryParameters.SortBy, + SortOrder = queryParameters.SortOrder, }; var result = await Mediator.Send(query); return Ok(Result>.Succeed(result)); } - [HttpGet("{id:guid}")] + /// + /// Get all document types + /// + /// A list of document types + [RequiresRole(IdentityData.Roles.Admin, IdentityData.Roles.Staff)] + [HttpGet("types")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + public async Task>>> GetAllDocumentTypes() + { + var result = await Mediator.Send(new GetAllDocumentTypesQuery()); + return Ok(Result>.Succeed(result)); + } + + /// + /// Import a document + /// + /// Import document details + /// A DocumentDto of the imported document + [RequiresRole(IdentityData.Roles.Admin, IdentityData.Roles.Staff)] + [HttpPost] [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task>> GetDocumentById(Guid id) + [ProducesResponseType(StatusCodes.Status409Conflict)] + public async Task>> Import([FromBody] ImportDocumentCommand command) { - var query = new GetDocumentByIdQuery() - { - Id = id - }; - var result = await Mediator.Send(query); + var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); } - + /// /// Update a document /// @@ -86,7 +107,7 @@ public async Task>> GetDocumentById(Guid id) [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> UpdateDocument([FromRoute] Guid documentId, [FromBody] UpdateDocumentRequest request) + public async Task>> Update([FromRoute] Guid documentId, [FromBody] UpdateDocumentRequest request) { var query = new UpdateDocumentCommand() { @@ -98,7 +119,7 @@ public async Task>> UpdateDocument([FromRoute] var result = await Mediator.Send(query); return Ok(Result.Succeed(result)); } - + /// /// Delete a document /// @@ -108,7 +129,7 @@ public async Task>> UpdateDocument([FromRoute] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task>> UpdateDocument([FromRoute] Guid documentId) + public async Task>> Delete([FromRoute] Guid documentId) { var query = new DeleteDocumentCommand() { diff --git a/src/Api/Controllers/FoldersController.cs b/src/Api/Controllers/FoldersController.cs index 8ea03dd6..f8aadd8f 100644 --- a/src/Api/Controllers/FoldersController.cs +++ b/src/Api/Controllers/FoldersController.cs @@ -39,7 +39,7 @@ public async Task>> GetById([FromRoute] Guid fold /// /// Get all folders paginated /// - /// Get all folders query parameters + /// Get all folders paginated query parameters /// A paginated list of FolderDto [RequiresRole(IdentityData.Roles.Admin, IdentityData.Roles.Staff)] [HttpGet] @@ -104,17 +104,21 @@ public async Task>> RemoveFolder([FromRoute] Guid /// /// Enable a folder /// - /// Enable folder details + /// Id of the folder to be enabled /// A FolderDto of the enabled folder [RequiresRole(IdentityData.Roles.Admin, IdentityData.Roles.Staff)] - [HttpPut("enable")] - [ProducesResponseType(StatusCodes.Status200OK)] + [HttpPut("enable/{folderId:guid}")] + [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> EnableFolder([FromBody] EnableFolderCommand command) + public async Task>> EnableFolder([FromRoute] Guid folderId) { + var command = new EnableFolderCommand() + { + FolderId = folderId, + }; var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); } @@ -122,17 +126,21 @@ public async Task>> EnableFolder([FromBody] Enabl /// /// Disable a folder /// - /// Disable folder details + /// Id of the disabled folder /// A FolderDto of the disabled folder [RequiresRole(IdentityData.Roles.Admin, IdentityData.Roles.Staff)] - [HttpPut("disable")] + [HttpPut("disable/{folderId:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> DisableFolder([FromBody] DisableFolderCommand command) + public async Task>> DisableFolder([FromRoute] Guid folderId) { + var command = new DisableFolderCommand() + { + FolderId = folderId + }; var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); } diff --git a/src/Api/Controllers/LockersController.cs b/src/Api/Controllers/LockersController.cs index f064090e..54e85fef 100644 --- a/src/Api/Controllers/LockersController.cs +++ b/src/Api/Controllers/LockersController.cs @@ -30,7 +30,7 @@ public async Task>> GetById([FromRoute] Guid lock { var query = new GetLockerByIdQuery() { - LockerId = lockerId + LockerId = lockerId, }; var result = await Mediator.Send(query); return Ok(Result.Succeed(result)); @@ -39,7 +39,7 @@ public async Task>> GetById([FromRoute] Guid lock /// /// Get all lockers paginated /// - /// Get all lockers query parameters + /// Get all lockers paginated query parameters /// A paginated list of LockerDto [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] @@ -66,77 +66,95 @@ public async Task>>> GetAllPaginate [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> AddLocker([FromBody] AddLockerCommand command) + public async Task>> Add([FromBody] AddLockerCommand command) { var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); } - [RequiresRole(IdentityData.Roles.Admin, IdentityData.Roles.Staff)] - [HttpPut("disable")] + /// + /// Remove a locker + /// + /// Id of the locker to be removed + /// A LockerDto of the removed locker + [HttpDelete("{lockerId:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> DisableLocker([FromBody] DisableLockerCommand command) + public async Task>> Remove([FromRoute] Guid lockerId) { + var command = new RemoveLockerCommand() + { + LockerId = lockerId, + }; var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); } + /// + /// Enable a locker + /// + /// Id of the locker to be enabled + /// A LockerDto of the enabled locker [RequiresRole(IdentityData.Roles.Admin, IdentityData.Roles.Staff)] - [HttpPut("enable")] + [HttpPut("enable/{lockerId:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> EnableLocker([FromBody] EnableLockerCommand command) + public async Task>> Enable([FromRoute] Guid lockerId) { + var command = new EnableLockerCommand() + { + LockerId = lockerId, + }; var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); } /// - /// Update a locker + /// Disable a locker /// - /// Id of the locker to be updated - /// Update locker details - /// A LockerDto of the updated locker - [HttpPut("{lockerId:guid}")] + /// Id of the locker to be disabled + /// A LockerDto of the disabled locker + [RequiresRole(IdentityData.Roles.Admin, IdentityData.Roles.Staff)] + [HttpPut("disable/{lockerId:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> Update([FromRoute] Guid lockerId, [FromBody] UpdateLockerRequest request) + public async Task>> Disable([FromRoute] Guid lockerId) { - var command = new UpdateLockerCommand() + var command = new DisableLockerCommand() { LockerId = lockerId, - Name = request.Name, - Description = request.Description, - Capacity = request.Capacity }; var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); } - + /// - /// Remove a locker + /// Update a locker /// - /// Id of the locker to be removed - /// A LockerDto of the removed locker - [HttpDelete("{lockerId:guid}")] + /// Id of the locker to be updated + /// Update locker details + /// A LockerDto of the updated locker + [HttpPut("{lockerId:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> Remove([FromRoute] Guid lockerId) + public async Task>> Update([FromRoute] Guid lockerId, [FromBody] UpdateLockerRequest request) { - var command = new RemoveLockerCommand() + var command = new UpdateLockerCommand() { - LockerId = lockerId + LockerId = lockerId, + Name = request.Name, + Description = request.Description, + Capacity = request.Capacity, }; var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); diff --git a/src/Api/Controllers/Payload/Requests/Auth/LoginModel.cs b/src/Api/Controllers/Payload/Requests/Auth/LoginModel.cs new file mode 100644 index 00000000..bee75df4 --- /dev/null +++ b/src/Api/Controllers/Payload/Requests/Auth/LoginModel.cs @@ -0,0 +1,7 @@ +namespace Api.Controllers.Payload.Requests.Auth; + +public class LoginModel +{ + public string Email { get; set; } = null!; + public string Password { get; set; } = null!; +} \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/RefreshTokenRequest.cs b/src/Api/Controllers/Payload/Requests/Auth/RefreshTokenRequest.cs similarity index 71% rename from src/Api/Controllers/Payload/Requests/RefreshTokenRequest.cs rename to src/Api/Controllers/Payload/Requests/Auth/RefreshTokenRequest.cs index bcc3d8e2..12ebbd03 100644 --- a/src/Api/Controllers/Payload/Requests/RefreshTokenRequest.cs +++ b/src/Api/Controllers/Payload/Requests/Auth/RefreshTokenRequest.cs @@ -1,4 +1,4 @@ -namespace Api.Controllers.Payload.Requests; +namespace Api.Controllers.Payload.Requests.Auth; public class RefreshTokenRequest { diff --git a/src/Api/Controllers/Payload/Requests/UpdateDepartmentRequest.cs b/src/Api/Controllers/Payload/Requests/Departments/UpdateDepartmentRequest.cs similarity index 60% rename from src/Api/Controllers/Payload/Requests/UpdateDepartmentRequest.cs rename to src/Api/Controllers/Payload/Requests/Departments/UpdateDepartmentRequest.cs index 467ceeb5..c327c2a4 100644 --- a/src/Api/Controllers/Payload/Requests/UpdateDepartmentRequest.cs +++ b/src/Api/Controllers/Payload/Requests/Departments/UpdateDepartmentRequest.cs @@ -1,4 +1,4 @@ -namespace Api.Controllers.Payload.Requests; +namespace Api.Controllers.Payload.Requests.Departments; public class UpdateDepartmentRequest { diff --git a/src/Api/Controllers/Payload/Requests/Documents/GetAllDocumentsPaginatedQueryParameters.cs b/src/Api/Controllers/Payload/Requests/Documents/GetAllDocumentsPaginatedQueryParameters.cs new file mode 100644 index 00000000..0b56668c --- /dev/null +++ b/src/Api/Controllers/Payload/Requests/Documents/GetAllDocumentsPaginatedQueryParameters.cs @@ -0,0 +1,13 @@ +namespace Api.Controllers.Payload.Requests.Documents; + +public class GetAllDocumentsPaginatedQueryParameters +{ + public Guid? RoomId { get; set; } + public Guid? LockerId { get; set; } + public Guid? FolderId { get; set; } + public string? SearchTerm { get; set; } + public int? Page { get; set; } + public int? Size { get; set; } + public string? SortBy { get; set; } + public string? SortOrder { get; set; } +} \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/LoginModel.cs b/src/Api/Controllers/Payload/Requests/LoginModel.cs deleted file mode 100644 index d5bd6c61..00000000 --- a/src/Api/Controllers/Payload/Requests/LoginModel.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Api.Controllers.Payload.Requests; - -public class LoginModel -{ - public string Email { get; set; } - public string Password { get; set; } -} \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Rooms/GetAllRoomsPaginatedQueryParameters.cs b/src/Api/Controllers/Payload/Requests/Rooms/GetAllRoomsPaginatedQueryParameters.cs new file mode 100644 index 00000000..107661c0 --- /dev/null +++ b/src/Api/Controllers/Payload/Requests/Rooms/GetAllRoomsPaginatedQueryParameters.cs @@ -0,0 +1,9 @@ +namespace Api.Controllers.Payload.Requests.Rooms; + +public class GetAllRoomsPaginatedQueryParameters +{ + public int? Page { get; set; } + public int? Size { get; set; } + public string? SortBy { get; set; } + public string? SortOrder { get; set; } +} \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Rooms/GetEmptyContainersPaginatedQueryParameters.cs b/src/Api/Controllers/Payload/Requests/Rooms/GetEmptyContainersPaginatedQueryParameters.cs new file mode 100644 index 00000000..18490a71 --- /dev/null +++ b/src/Api/Controllers/Payload/Requests/Rooms/GetEmptyContainersPaginatedQueryParameters.cs @@ -0,0 +1,7 @@ +namespace Api.Controllers.Payload.Requests.Rooms; + +public class GetEmptyContainersPaginatedQueryParameters +{ + public int? Page { get; set; } + public int? Size { get; set; } +} \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/UpdateRoomRequest.cs b/src/Api/Controllers/Payload/Requests/Rooms/UpdateRoomRequest.cs similarity index 76% rename from src/Api/Controllers/Payload/Requests/UpdateRoomRequest.cs rename to src/Api/Controllers/Payload/Requests/Rooms/UpdateRoomRequest.cs index a579a447..56df0abe 100644 --- a/src/Api/Controllers/Payload/Requests/UpdateRoomRequest.cs +++ b/src/Api/Controllers/Payload/Requests/Rooms/UpdateRoomRequest.cs @@ -1,4 +1,4 @@ -namespace Api.Controllers.Payload.Requests; +namespace Api.Controllers.Payload.Requests.Rooms; public class UpdateRoomRequest { diff --git a/src/Api/Controllers/RoomsController.cs b/src/Api/Controllers/RoomsController.cs index 3cbeb8dd..6ff5829f 100644 --- a/src/Api/Controllers/RoomsController.cs +++ b/src/Api/Controllers/RoomsController.cs @@ -1,4 +1,5 @@ -using Api.Controllers.Payload.Requests; +using Api.Controllers.Payload.Requests.Lockers; +using Api.Controllers.Payload.Requests.Rooms; using Application.Common.Models; using Application.Common.Models.Dtos.Physical; using Application.Identity; @@ -17,135 +18,173 @@ namespace Api.Controllers; public class RoomsController : ApiControllerBase { - [RequiresRole(IdentityData.Roles.Admin)] - [HttpPost] + /// + /// Get a room by id + /// + /// Id of the room to be retrieved + /// A RoomDto of the retrieved room + [HttpGet("{roomId:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] - [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> AddRoom(AddRoomCommand command) + public async Task>> GetById([FromRoute] Guid roomId) { - var result = await Mediator.Send(command); + var query = new GetRoomByIdQuery() + { + RoomId = roomId, + }; + var result = await Mediator.Send(query); return Ok(Result.Succeed(result)); } - + + /// + /// Get all rooms paginated + /// + /// Get all rooms paginated details + /// A paginated list of rooms + [HttpGet] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + public async Task>>> GetAllPaginated( + [FromQuery] GetAllLockersPaginatedQueryParameters queryParameters) + { + var query = new GetAllRoomsPaginatedQuery() + { + Page = queryParameters.Page, + Size = queryParameters.Size, + SortBy = queryParameters.SortBy, + SortOrder = queryParameters.SortOrder, + }; + var result = await Mediator.Send(query); + return Ok(Result>.Succeed(result)); + } + + /// + /// Get empty containers in a room + /// + /// Get empty containers paginated details + /// A paginated list of EmptyLockerDto [RequiresRole(IdentityData.Roles.Staff)] [HttpPost("empty-containers")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task>> GetEmptyContainers(GetEmptyContainersPaginatedQuery query) + public async Task>> GetEmptyContainers( + [FromRoute] Guid roomId, + [FromQuery] GetEmptyContainersPaginatedQueryParameters queryParameters) { + var query = new GetEmptyContainersPaginatedQuery() + { + RoomId = roomId, + Page = queryParameters.Page, + Size = queryParameters.Size, + }; var result = await Mediator.Send(query); return Ok(Result>.Succeed(result)); } - + + /// + /// Add a room + /// + /// Add room details + /// A RoomDto of the added room [RequiresRole(IdentityData.Roles.Admin)] - [HttpPut("disable")] + [HttpPost] [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> DisableRoom(DisableRoomCommand command) + public async Task>> AddRoom([FromBody] AddRoomCommand command) { var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); } - + + /// + /// Remove a room + /// + /// Id of the room to be removed + /// A RoomDto of the removed room [RequiresRole(IdentityData.Roles.Admin)] - [HttpDelete] + [HttpDelete("{roomId:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> RemoveRoom(RemoveRoomCommand command) + public async Task>> RemoveRoom([FromRoute] Guid roomId) { + var command = new RemoveRoomCommand() + { + RoomId = roomId, + }; var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); } - + /// /// Enable a room /// - /// Enable room details + /// Id of the room to be enabled /// A RoomDto of the enabled room - [HttpPut("enable")] + [HttpPut("enable/{roomId:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> EnableRoom([FromBody] EnableRoomCommand command) + public async Task>> EnableRoom([FromRoute] Guid roomId) { + var command = new EnableRoomCommand() + { + RoomId = roomId, + }; var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); } /// - /// Update a room + /// Disable a room /// - /// Id of the room to be updated - /// Update room details - /// A RoomDto of the updated room - [HttpPut("{roomId:guid}")] + /// Id of the room to be disabled + /// A RoomDto of the disabled room + [RequiresRole(IdentityData.Roles.Admin)] + [HttpPut("disable/{roomId:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> Update([FromRoute] Guid roomId, [FromBody] UpdateRoomRequest request) + public async Task>> DisableRoom([FromRoute] Guid roomId) { - Console.WriteLine(request.Description); - var command = new UpdateRoomCommand() + var command = new DisableRoomCommand() { RoomId = roomId, - Name = request.Name, - Description = request.Description, - Capacity = request.Capacity, }; var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); } - + /// - /// Get a room by id + /// Update a room /// - /// Id of the room to be retrieved - /// A RoomDto of the retrieved room - [HttpGet("{roomId:guid}")] + /// Id of the room to be updated + /// Update room details + /// A RoomDto of the updated room + [HttpPut("{roomId:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task>> GetById([FromRoute] Guid roomId) + [ProducesResponseType(StatusCodes.Status409Conflict)] + public async Task>> Update([FromRoute] Guid roomId, [FromBody] UpdateRoomRequest request) { - var query = new GetRoomByIdQuery() + Console.WriteLine(request.Description); + var command = new UpdateRoomCommand() { RoomId = roomId, + Name = request.Name, + Description = request.Description, + Capacity = request.Capacity, }; - var result = await Mediator.Send(query); + var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); } - - /// - /// Get all rooms paginated - /// - /// The page index - /// The size number - /// Criteria - /// The order in which the rooms are sorted - /// A paginated list of rooms - [HttpGet] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status403Forbidden)] - public async Task>>> GetAllPaginated(int? page, int? size, string? sortBy, string? sortOrder) - { - var query = new GetAllRoomsPaginatedQuery() - { - Page = page, - Size = size, - SortBy = sortBy, - SortOrder = sortOrder - }; - var result = await Mediator.Send(query); - return Ok(Result>.Succeed(result)); - } } \ No newline at end of file diff --git a/src/Api/Controllers/StaffsController.cs b/src/Api/Controllers/StaffsController.cs index 1ad6fff1..5c2637af 100644 --- a/src/Api/Controllers/StaffsController.cs +++ b/src/Api/Controllers/StaffsController.cs @@ -79,7 +79,7 @@ public async Task>>> GetAllPaginated [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task>> AddStaff([FromBody] AddStaffCommand command) + public async Task>> Add([FromBody] AddStaffCommand command) { var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); @@ -95,7 +95,8 @@ public async Task>> AddStaff([FromBody] AddStaffCo [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task>> RemoveStaffFromRoom([FromRoute] Guid staffId, + public async Task>> RemoveFromRoom( + [FromRoute] Guid staffId, [FromBody] RemoveStaffFromRoomRequest request) { var command = new RemoveStaffFromRoomCommand() diff --git a/src/Api/Controllers/UsersController.cs b/src/Api/Controllers/UsersController.cs index f7d93173..d712f4e6 100644 --- a/src/Api/Controllers/UsersController.cs +++ b/src/Api/Controllers/UsersController.cs @@ -27,7 +27,7 @@ public class UsersController : ApiControllerBase [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task>> GetUserById([FromRoute] Guid userId) + public async Task>> GetById([FromRoute] Guid userId) { var query = new GetUserByIdQuery { @@ -40,7 +40,7 @@ public async Task>> GetUserById([FromRoute] Guid us /// /// Get all users paginated /// - /// Get all users query parameters + /// Get all users query parameters /// A paginated list of UserDto [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] @@ -61,6 +61,11 @@ public async Task>>> GetAllPaginated( return Ok(Result>.Succeed(result)); } + /// + /// Add a user + /// + /// Add user details + /// A UserDto of the added user [RequiresRole(IdentityData.Roles.Admin)] [HttpPost] [ProducesResponseType(StatusCodes.Status200OK)] @@ -68,30 +73,14 @@ public async Task>>> GetAllPaginated( [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> AddUser([FromBody] AddUserCommand command) + public async Task>> Add([FromBody] AddUserCommand command) { var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); } - - // [RequiresRole(IdentityData.Roles.Admin)] - // [HttpGet] - // [ProducesResponseType(StatusCodes.Status200OK)] - // [ProducesResponseType(StatusCodes.Status403Forbidden)] - // public async Task>>> GetUsersByName(string? searchTerm, int? page, int? size) - // { - // var query = new GetUsersByNameQuery - // { - // SearchTerm = searchTerm, - // Page = page, - // Size = size - // }; - // var result = await Mediator.Send(query); - // return Ok(Result>.Succeed(result)); - // } - + /// - /// Disable a user + /// Enable a user /// /// Id of the user to be enabled /// A UserDto of the enabled user @@ -100,7 +89,7 @@ public async Task>> AddUser([FromBody] AddUserComma [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task>> EnableUser([FromRoute] Guid userId) + public async Task>> Enable([FromRoute] Guid userId) { var command = new EnableUserCommand() { @@ -110,14 +99,23 @@ public async Task>> EnableUser([FromRoute] Guid use return Ok(Result.Succeed(result)); } + /// + /// Disable a user + /// + /// Id of the user to be disabled + /// A UserDto of the disabled user [RequiresRole(IdentityData.Roles.Admin)] - [HttpPost("disable")] + [HttpPut("disable/{userId:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> DisableUser([FromBody] DisableUserCommand command) + public async Task>> Disable([FromRoute] Guid userId) { + var command = new DisableUserCommand() + { + UserId = userId, + }; var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); } diff --git a/src/Application/Documents/Queries/GetAllDocumentsPaginated/GetAllDocumentsPaginatedQuery.cs b/src/Application/Documents/Queries/GetAllDocumentsPaginated/GetAllDocumentsPaginatedQuery.cs index ff2de9ad..566df131 100644 --- a/src/Application/Documents/Queries/GetAllDocumentsPaginated/GetAllDocumentsPaginatedQuery.cs +++ b/src/Application/Documents/Queries/GetAllDocumentsPaginated/GetAllDocumentsPaginatedQuery.cs @@ -16,6 +16,7 @@ public record GetAllDocumentsPaginatedQuery : IRequest { - public Guid Id { get; init; } + public Guid DocumentId { get; init; } } public class GetDocumentByIdQueryHandler : IRequestHandler @@ -29,7 +29,7 @@ public async Task Handle(GetDocumentByIdQuery request, Cancellation .Include(x => x.Folder) .ThenInclude(y => y.Locker) .ThenInclude(z => z.Room) - .FirstOrDefaultAsync(x => x.Id == request.Id, cancellationToken); + .FirstOrDefaultAsync(x => x.Id == request.DocumentId, cancellationToken); if (document is null) { diff --git a/src/Application/Rooms/Queries/GetEmptyContainersPaginated/GetEmptyContainersPaginatedQuery.cs b/src/Application/Rooms/Queries/GetEmptyContainersPaginated/GetEmptyContainersPaginatedQuery.cs index 166881aa..95be60d7 100644 --- a/src/Application/Rooms/Queries/GetEmptyContainersPaginated/GetEmptyContainersPaginatedQuery.cs +++ b/src/Application/Rooms/Queries/GetEmptyContainersPaginated/GetEmptyContainersPaginatedQuery.cs @@ -10,8 +10,8 @@ namespace Application.Rooms.Queries.GetEmptyContainersPaginated; public record GetEmptyContainersPaginatedQuery : IRequest> { public Guid RoomId { get; init; } - public int Page { get; init; } - public int Size { get; init; } + public int? Page { get; init; } + public int? Size { get; init; } } public class GetEmptyContainersPaginatedQueryHandler : IRequestHandler> @@ -31,7 +31,9 @@ public async Task> Handle(GetEmptyContainersPagina { throw new KeyNotFoundException("Room does not exist."); } - + + var pageNumber = request.Page ?? 1; + var sizeNumber = request.Size ?? 5; var lockers = _context.Lockers .Where(x => x.Room.Id == request.RoomId && x.IsAvailable @@ -42,7 +44,7 @@ public async Task> Handle(GetEmptyContainersPagina lockers.ForEach(x => x.Folders = x.Folders.Where(y => y.Slot > 0)); - var result = new PaginatedList(lockers.ToList(), lockers.Count(), request.Page, request.Size); + var result = new PaginatedList(lockers.ToList(), lockers.Count, pageNumber, sizeNumber); return result; } } \ No newline at end of file From 808beebc66f2443de0fefad674718208ec41f519 Mon Sep 17 00:00:00 2001 From: Nguyen Quang Chien Date: Sat, 27 May 2023 23:15:58 +0700 Subject: [PATCH 02/11] refactor: application features' name --- src/Api/Controllers/AuthController.cs | 1 - src/Api/Controllers/DepartmentsController.cs | 18 ++++----- src/Api/Controllers/DocumentsController.cs | 22 +++++----- src/Api/Controllers/FoldersController.cs | 23 +++++------ src/Api/Controllers/LockersController.cs | 26 +++++------- src/Api/Controllers/RoomsController.cs | 31 ++++++-------- src/Api/Controllers/StaffsController.cs | 19 ++++----- src/Api/Controllers/UsersController.cs | 28 ++++++------- src/Api/Services/CurrentUserService.cs | 1 - .../Common/Models/Dtos/Physical/RoomDto.cs | 1 - .../Common/Models/Dtos/Physical/StaffDto.cs | 4 +- .../Command.cs} | 8 ++-- .../Command.cs} | 11 +++-- .../Command.cs} | 4 +- .../Query.cs} | 11 +++-- .../Departments/Queries/GetById/Query.cs | 9 +++++ .../GetDepartmentByIdQuery.cs | 9 ----- .../Documents/Commands/Delete/Command.cs | 9 +++++ .../DeleteDocument/DeleteDocumentCommand.cs | 9 ----- .../Command.cs} | 10 ++--- .../Command.cs} | 4 +- .../DocumentItemDto.cs | 3 +- .../Query.cs} | 8 ++-- .../Validator.cs} | 6 +-- .../Query.cs} | 10 ++--- .../GetDocumentTypes/GetDocumentTypesQuery.cs | 23 ----------- .../{GetAllDocumentTypesQuery.cs => Query.cs} | 8 ++-- .../AddFolderCommand.cs => Add/Command.cs} | 10 ++--- .../Validator.cs} | 6 +-- .../Command.cs} | 10 ++--- .../Validator.cs} | 6 +-- .../Folders/Commands/Enable/Command.cs | 9 +++++ .../EnableFolder/EnableFolderCommand.cs | 9 ----- .../Folders/Commands/Remove/Command.cs | 9 +++++ .../RemoveFolder/RemoveFolderCommand.cs | 9 ----- .../Command.cs} | 4 +- .../Query.cs} | 4 +- .../Folders/Queries/GetById/Query.cs | 9 +++++ .../GetFolderById/GetFolderByIdQuery.cs | 9 ----- src/Application/Identity/IdentityData.cs | 6 --- .../AddLockerCommand.cs => Add/Command.cs} | 10 ++--- .../Validator.cs} | 10 ++--- .../Command.cs} | 8 ++-- .../Lockers/Commands/Disable/Validator.cs | 14 +++++++ .../DisableLockerCommandValidator.cs | 13 ------ .../Command.cs} | 11 +++-- .../Lockers/Commands/Enable/Validator.cs | 14 +++++++ .../EnableLockerCommandValidator.cs | 13 ------ .../Lockers/Commands/Remove/Command.cs | 9 +++++ .../RemoveLocker/RemoveLockerCommand.cs | 9 ----- .../Lockers/Commands/Update/Command.cs | 12 ++++++ .../UpdateLocker/UpdateLockerCommand.cs | 12 ------ .../Query.cs} | 4 +- .../Lockers/Queries/GetById/Query.cs | 9 +++++ .../GetLockerById/GetLockerByIdQuery.cs | 9 ----- .../AddRoomCommand.cs => Add/Command.cs} | 11 +++-- .../Validator.cs} | 6 +-- .../Command.cs} | 8 ++-- .../Validator.cs} | 6 +-- .../Enable/Command.cs} | 4 +- .../Command.cs} | 8 ++-- .../Validator.cs} | 6 +-- .../Command.cs} | 4 +- .../Query.cs} | 4 +- .../GetById/Query.cs} | 4 +- ...tyContainersPaginatedQuery.cs => Query.cs} | 8 ++-- .../AddStaffCommand.cs => Add/Command.cs} | 12 +++--- .../Staffs/Commands/RemoveFromRoom/Command.cs | 10 +++++ .../RemoveStaffFromRoomCommand.cs | 10 ----- .../Query.cs} | 6 +-- .../Staffs/Queries/GetById/Query.cs | 9 +++++ .../Staffs/Queries/GetByRoom/Query.cs | 9 +++++ .../Queries/GetStaffById/GetStaffByIdQuery.cs | 9 ----- .../GetStaffByRoom/GetStaffByRoomQuery.cs | 9 ----- .../AddUserCommand.cs => Add/Command.cs} | 8 ++-- .../Validator.cs} | 6 +-- .../Command.cs} | 10 ++--- .../Users/Commands/Enable/Command.cs | 9 +++++ .../Commands/EnableUser/EnableUserCommand.cs | 9 ----- .../Command.cs} | 4 +- .../Query.cs} | 4 +- .../Users/Queries/GetById/Query.cs | 8 ++++ .../Queries/GetUserById/GetUserByIdQuery.cs | 8 ---- .../GetUsersByName/GetUsersByNameQuery.cs | 40 ------------------- src/Infrastructure/Infrastructure.csproj | 4 -- .../BaseClassFixture.cs | 4 +- .../CustomApiFactory.cs | 2 +- .../Commands/AddDepartmentTests.cs | 1 - .../Queries/GetAllDepartmentsTests.cs | 6 +-- .../Queries/GetAllDocumentTypesTests.cs | 4 +- .../Queries/GetAllDocumentsPaginatedTests.cs | 28 ++++++------- .../Folders/Commands/AddFolderTests.cs | 13 +++--- .../Folders/Commands/DisableFolderTests.cs | 10 ++--- .../Lockers/Commands/AddLockerTests.cs | 14 +++---- .../Lockers/Commands/DisableLockerTests.cs | 15 +++---- .../Lockers/Commands/EnableLockerTests.cs | 19 ++++----- .../Rooms/Commands/DisableRoomTests.cs | 11 +++-- .../Rooms/Commands/RemoveRoomTests.cs | 8 ++-- .../GetEmptyContainersPaginatedTests.cs | 5 +-- .../Users/Commands/AddUserTests.cs | 4 +- .../Common/Mappings/MappingTests.cs | 2 +- 101 files changed, 432 insertions(+), 540 deletions(-) rename src/Application/Departments/Commands/{AddDepartment/AddDepartmentCommand.cs => Add/Command.cs} (77%) rename src/Application/Departments/Commands/{DeleteDepartment/DeleteDepartmentCommand.cs => Delete/Command.cs} (63%) rename src/Application/Departments/Commands/{UpdateDepartment/UpdateDepartmentCommand.cs => Update/Command.cs} (53%) rename src/Application/Departments/Queries/{GetAllDepartments/GetAllDepartmentsQuery.cs => GetAll/Query.cs} (53%) create mode 100644 src/Application/Departments/Queries/GetById/Query.cs delete mode 100644 src/Application/Departments/Queries/GetDepartmentById/GetDepartmentByIdQuery.cs create mode 100644 src/Application/Documents/Commands/Delete/Command.cs delete mode 100644 src/Application/Documents/Commands/DeleteDocument/DeleteDocumentCommand.cs rename src/Application/Documents/Commands/{ImportDocument/ImportDocumentCommand.cs => Import/Command.cs} (84%) rename src/Application/Documents/Commands/{UpdateDocument/UpdateDocumentCommand.cs => Update/Command.cs} (68%) rename src/Application/Documents/Queries/{GetAllDocumentsPaginated => GetAllPaginated}/DocumentItemDto.cs (86%) rename src/Application/Documents/Queries/{GetAllDocumentsPaginated/GetAllDocumentsPaginatedQuery.cs => GetAllPaginated/Query.cs} (92%) rename src/Application/Documents/Queries/{GetAllDocumentsPaginated/GetAllDocumentsPaginatedQueryValidator.cs => GetAllPaginated/Validator.cs} (71%) rename src/Application/Documents/Queries/{GetDocumentById/GetDocumentByIdQuery.cs => GetById/Query.cs} (68%) delete mode 100644 src/Application/Documents/Queries/GetDocumentTypes/GetDocumentTypesQuery.cs rename src/Application/Documents/Queries/GetDocumentTypes/{GetAllDocumentTypesQuery.cs => Query.cs} (54%) rename src/Application/Folders/Commands/{AddFolder/AddFolderCommand.cs => Add/Command.cs} (83%) rename src/Application/Folders/Commands/{AddFolder/AddFolderCommandValidator.cs => Add/Validator.cs} (80%) rename src/Application/Folders/Commands/{DisableFolder/DisableFolderCommand.cs => Disable/Command.cs} (74%) rename src/Application/Folders/Commands/{DisableFolder/DisableFolderCommandValidator.cs => Disable/Validator.cs} (50%) create mode 100644 src/Application/Folders/Commands/Enable/Command.cs delete mode 100644 src/Application/Folders/Commands/EnableFolder/EnableFolderCommand.cs create mode 100644 src/Application/Folders/Commands/Remove/Command.cs delete mode 100644 src/Application/Folders/Commands/RemoveFolder/RemoveFolderCommand.cs rename src/Application/Folders/Commands/{UpdateFolder/UpdateFolderCommand.cs => Update/Command.cs} (68%) rename src/Application/Folders/Queries/{GetAllFoldersPaginated/GetAllFoldersPaginatedQuery.cs => GetAllPaginated/Query.cs} (70%) create mode 100644 src/Application/Folders/Queries/GetById/Query.cs delete mode 100644 src/Application/Folders/Queries/GetFolderById/GetFolderByIdQuery.cs rename src/Application/Lockers/Commands/{AddLocker/AddLockerCommand.cs => Add/Command.cs} (83%) rename src/Application/Lockers/Commands/{AddLocker/AddLockerCommandValidator.cs => Add/Validator.cs} (72%) rename src/Application/Lockers/Commands/{DisableLocker/DisableLockerCommand.cs => Disable/Command.cs} (84%) create mode 100644 src/Application/Lockers/Commands/Disable/Validator.cs delete mode 100644 src/Application/Lockers/Commands/DisableLocker/DisableLockerCommandValidator.cs rename src/Application/Lockers/Commands/{EnableLocker/EnableLockerCommand.cs => Enable/Command.cs} (70%) create mode 100644 src/Application/Lockers/Commands/Enable/Validator.cs delete mode 100644 src/Application/Lockers/Commands/EnableLocker/EnableLockerCommandValidator.cs create mode 100644 src/Application/Lockers/Commands/Remove/Command.cs delete mode 100644 src/Application/Lockers/Commands/RemoveLocker/RemoveLockerCommand.cs create mode 100644 src/Application/Lockers/Commands/Update/Command.cs delete mode 100644 src/Application/Lockers/Commands/UpdateLocker/UpdateLockerCommand.cs rename src/Application/Lockers/Queries/{GetAllLockersPaginated/GetAllLockersPaginatedQuery.cs => GetAllPaginated/Query.cs} (67%) create mode 100644 src/Application/Lockers/Queries/GetById/Query.cs delete mode 100644 src/Application/Lockers/Queries/GetLockerById/GetLockerByIdQuery.cs rename src/Application/Rooms/Commands/{AddRoom/AddRoomCommand.cs => Add/Command.cs} (77%) rename src/Application/Rooms/Commands/{AddRoom/AddRoomCommandValidator.cs => Add/Validator.cs} (83%) rename src/Application/Rooms/Commands/{DisableRoom/DisableRoomCommand.cs => Disable/Command.cs} (86%) rename src/Application/Rooms/Commands/{DisableRoom/DisableRoomCommandValidator.cs => Disable/Validator.cs} (51%) rename src/Application/Rooms/{Queries/GetRoomById/GetRoomByIdQuery.cs => Commands/Enable/Command.cs} (51%) rename src/Application/Rooms/Commands/{RemoveRoom/RemoveRoomCommand.cs => Remove/Command.cs} (81%) rename src/Application/Rooms/Commands/{RemoveRoom/RemoveRoomCommandValidator.cs => Remove/Validator.cs} (52%) rename src/Application/Rooms/Commands/{UpdateRoom/UpdateRoomCommand.cs => Update/Command.cs} (70%) rename src/Application/Rooms/Queries/{GetAllRoomPaginated/GetAllRoomsPaginatedQuery.cs => GetAllPaginated/Query.cs} (66%) rename src/Application/Rooms/{Commands/EnableRoom/EnableRoomCommand.cs => Queries/GetById/Query.cs} (50%) rename src/Application/Rooms/Queries/GetEmptyContainersPaginated/{GetEmptyContainersPaginatedQuery.cs => Query.cs} (75%) rename src/Application/Staffs/Commands/{AddStaff/AddStaffCommand.cs => Add/Command.cs} (74%) create mode 100644 src/Application/Staffs/Commands/RemoveFromRoom/Command.cs delete mode 100644 src/Application/Staffs/Commands/RemoveStaffFromRoom/RemoveStaffFromRoomCommand.cs rename src/Application/Staffs/Queries/{GetAllStaffsPaginated/GetAllStaffsPaginatedQuery.cs => GetAllPaginated/Query.cs} (58%) create mode 100644 src/Application/Staffs/Queries/GetById/Query.cs create mode 100644 src/Application/Staffs/Queries/GetByRoom/Query.cs delete mode 100644 src/Application/Staffs/Queries/GetStaffById/GetStaffByIdQuery.cs delete mode 100644 src/Application/Staffs/Queries/GetStaffByRoom/GetStaffByRoomQuery.cs rename src/Application/Users/Commands/{AddUser/AddUserCommand.cs => Add/Command.cs} (89%) rename src/Application/Users/Commands/{AddUser/AddUserCommandValidator.cs => Add/Validator.cs} (89%) rename src/Application/Users/Commands/{DisableUser/DisableUserCommand.cs => Disable/Command.cs} (71%) create mode 100644 src/Application/Users/Commands/Enable/Command.cs delete mode 100644 src/Application/Users/Commands/EnableUser/EnableUserCommand.cs rename src/Application/Users/Commands/{UpdateUser/UpdateUserCommand.cs => Update/Command.cs} (78%) rename src/Application/Users/Queries/{GetAllUsersPaginated/GetAllUsersPaginatedQuery.cs => GetAllPaginated/Query.cs} (69%) create mode 100644 src/Application/Users/Queries/GetById/Query.cs delete mode 100644 src/Application/Users/Queries/GetUserById/GetUserByIdQuery.cs delete mode 100644 src/Application/Users/Queries/GetUsersByName/GetUsersByNameQuery.cs diff --git a/src/Api/Controllers/AuthController.cs b/src/Api/Controllers/AuthController.cs index 3701f480..a770a036 100644 --- a/src/Api/Controllers/AuthController.cs +++ b/src/Api/Controllers/AuthController.cs @@ -1,6 +1,5 @@ using System.IdentityModel.Tokens.Jwt; using System.Security.Authentication; -using Api.Controllers.Payload.Requests; using Api.Controllers.Payload.Requests.Auth; using Api.Controllers.Payload.Responses; using Application.Common.Interfaces; diff --git a/src/Api/Controllers/DepartmentsController.cs b/src/Api/Controllers/DepartmentsController.cs index 950cbef5..1b55c7a9 100644 --- a/src/Api/Controllers/DepartmentsController.cs +++ b/src/Api/Controllers/DepartmentsController.cs @@ -1,15 +1,11 @@ -using Api.Controllers.Payload.Requests; using Api.Controllers.Payload.Requests.Departments; using Application.Common.Models; -using Application.Departments.Commands.DeleteDepartment; -using Application.Departments.Commands.UpdateDepartment; -using Application.Departments.Commands.AddDepartment; -using Application.Departments.Queries.GetAllDepartments; -using Application.Departments.Queries.GetDepartmentById; using Application.Identity; using Application.Users.Queries; using Infrastructure.Identity.Authorization; using Microsoft.AspNetCore.Mvc; +using DepartmentQueries = Application.Departments.Queries; +using DepartmentCommands = Application.Departments.Commands; namespace Api.Controllers; @@ -26,7 +22,7 @@ public class DepartmentsController : ApiControllerBase [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> GetById([FromRoute] Guid departmentId) { - var query = new GetDepartmentByIdQuery() + var query = new DepartmentQueries.GetById.Query() { DepartmentId = departmentId }; @@ -43,7 +39,7 @@ public async Task>> GetById([FromRoute] Guid [ProducesResponseType(StatusCodes.Status403Forbidden)] public async Task>>> GetAll() { - var result = await Mediator.Send(new GetAllDepartmentsQuery()); + var result = await Mediator.Send(new DepartmentQueries.GetAll.Query()); return Ok(Result>.Succeed(result)); } @@ -57,7 +53,7 @@ public async Task>>> GetAll() [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> Add([FromBody] AddDepartmentCommand command) + public async Task>> Add([FromBody] DepartmentCommands.Add.Command command) { var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); @@ -76,7 +72,7 @@ public async Task>> Add([FromBody] AddDepartm [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> Update([FromRoute] Guid departmentId, [FromBody] UpdateDepartmentRequest request) { - var command = new UpdateDepartmentCommand() + var command = new DepartmentCommands.Update.Command() { DepartmentId = departmentId, Name = request.Name @@ -97,7 +93,7 @@ public async Task>> Update([FromRoute] Guid d [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> Delete([FromRoute] Guid departmentId) { - var command = new DeleteDepartmentCommand() + var command = new DepartmentCommands.Delete.Command() { DepartmentId = departmentId, }; diff --git a/src/Api/Controllers/DocumentsController.cs b/src/Api/Controllers/DocumentsController.cs index 2fba9633..f62f21bb 100644 --- a/src/Api/Controllers/DocumentsController.cs +++ b/src/Api/Controllers/DocumentsController.cs @@ -1,15 +1,11 @@ using Api.Controllers.Payload.Requests.Documents; using Application.Common.Models; using Application.Common.Models.Dtos.Physical; -using Application.Documents.Commands.DeleteDocument; -using Application.Documents.Commands.ImportDocument; -using Application.Documents.Commands.UpdateDocument; -using Application.Documents.Queries.GetAllDocumentsPaginated; -using Application.Documents.Queries.GetDocumentById; -using Application.Documents.Queries.GetDocumentTypes; using Application.Identity; using Infrastructure.Identity.Authorization; using Microsoft.AspNetCore.Mvc; +using DocumentCommands = Application.Documents.Commands; +using DocumentQueries = Application.Documents.Queries; namespace Api.Controllers; @@ -26,9 +22,9 @@ public class DocumentsController : ApiControllerBase [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> GetById(Guid documentId) { - var query = new GetDocumentByIdQuery() + var query = new DocumentQueries.GetById.Query() { - DocumentId = documentId + DocumentId = documentId, }; var result = await Mediator.Send(query); return Ok(Result.Succeed(result)); @@ -48,7 +44,7 @@ public async Task>> GetById(Guid documentId) public async Task>>> GetAllPaginated( [FromQuery] GetAllDocumentsPaginatedQueryParameters queryParameters) { - var query = new GetAllDocumentsPaginatedQuery() + var query = new DocumentQueries.GetAllPaginated.Query() { RoomId = queryParameters.RoomId, LockerId = queryParameters.LockerId, @@ -73,7 +69,7 @@ public async Task>>> GetAllPagina [ProducesResponseType(StatusCodes.Status403Forbidden)] public async Task>>> GetAllDocumentTypes() { - var result = await Mediator.Send(new GetAllDocumentTypesQuery()); + var result = await Mediator.Send(new DocumentQueries.GetDocumentTypes.Query()); return Ok(Result>.Succeed(result)); } @@ -89,7 +85,7 @@ public async Task>>> GetAllDocumentTypes [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> Import([FromBody] ImportDocumentCommand command) + public async Task>> Import([FromBody] DocumentCommands.Import.Command command) { var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); @@ -109,7 +105,7 @@ public async Task>> Import([FromBody] ImportDoc [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> Update([FromRoute] Guid documentId, [FromBody] UpdateDocumentRequest request) { - var query = new UpdateDocumentCommand() + var query = new DocumentCommands.Update.Command() { DocumentId = documentId, Title = request.Title, @@ -131,7 +127,7 @@ public async Task>> Update([FromRoute] Guid doc [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> Delete([FromRoute] Guid documentId) { - var query = new DeleteDocumentCommand() + var query = new DocumentCommands.Delete.Command() { DocumentId = documentId, }; diff --git a/src/Api/Controllers/FoldersController.cs b/src/Api/Controllers/FoldersController.cs index f8aadd8f..6e07fdfc 100644 --- a/src/Api/Controllers/FoldersController.cs +++ b/src/Api/Controllers/FoldersController.cs @@ -1,16 +1,11 @@ using Api.Controllers.Payload.Requests.Folders; using Application.Common.Models; using Application.Common.Models.Dtos.Physical; -using Application.Folders.Commands.AddFolder; -using Application.Folders.Commands.DisableFolder; -using Application.Folders.Commands.EnableFolder; -using Application.Folders.Commands.RemoveFolder; -using Application.Folders.Commands.UpdateFolder; -using Application.Folders.Queries.GetAllFoldersPaginated; -using Application.Folders.Queries.GetFolderById; using Application.Identity; using Infrastructure.Identity.Authorization; using Microsoft.AspNetCore.Mvc; +using FolderCommands = Application.Folders.Commands; +using FolderQueries = Application.Folders.Queries; namespace Api.Controllers; @@ -28,7 +23,7 @@ public class FoldersController : ApiControllerBase [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> GetById([FromRoute] Guid folderId) { - var query = new GetFolderByIdQuery() + var query = new FolderQueries.GetById.Query() { FolderId = folderId }; @@ -48,7 +43,7 @@ public async Task>> GetById([FromRoute] Guid fold public async Task>>> GetAllPaginated( [FromQuery] GetAllFoldersPaginatedQueryParameters queryParameters) { - var query = new GetAllFoldersPaginatedQuery() + var query = new FolderQueries.GetAllPaginated.Query() { RoomId = queryParameters.RoomId, LockerId = queryParameters.LockerId, @@ -73,7 +68,7 @@ public async Task>>> GetAllPaginate [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> AddFolder([FromBody] AddFolderCommand command) + public async Task>> AddFolder([FromBody] FolderCommands.Add.Command command) { var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); @@ -93,7 +88,7 @@ public async Task>> AddFolder([FromBody] AddFolde [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> RemoveFolder([FromRoute] Guid folderId) { - var command = new RemoveFolderCommand() + var command = new FolderCommands.Remove.Command() { FolderId = folderId, }; @@ -115,7 +110,7 @@ public async Task>> RemoveFolder([FromRoute] Guid [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> EnableFolder([FromRoute] Guid folderId) { - var command = new EnableFolderCommand() + var command = new FolderCommands.Enable.Command() { FolderId = folderId, }; @@ -137,7 +132,7 @@ public async Task>> EnableFolder([FromRoute] Guid [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> DisableFolder([FromRoute] Guid folderId) { - var command = new DisableFolderCommand() + var command = new FolderCommands.Disable.Command() { FolderId = folderId }; @@ -158,7 +153,7 @@ public async Task>> DisableFolder([FromRoute] Gui [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> Update([FromRoute] Guid folderId, [FromBody] UpdateFolderRequest request) { - var command = new UpdateFolderCommand() + var command = new FolderCommands.Update.Command() { FolderId = folderId, Name = request.Name, diff --git a/src/Api/Controllers/LockersController.cs b/src/Api/Controllers/LockersController.cs index 54e85fef..84f648c8 100644 --- a/src/Api/Controllers/LockersController.cs +++ b/src/Api/Controllers/LockersController.cs @@ -1,17 +1,11 @@ -using Api.Controllers.Payload.Requests; -using Api.Controllers.Payload.Requests.Lockers; +using Api.Controllers.Payload.Requests.Lockers; using Application.Common.Models; using Application.Common.Models.Dtos.Physical; using Application.Identity; -using Application.Lockers.Commands.AddLocker; -using Application.Lockers.Commands.DisableLocker; -using Application.Lockers.Commands.EnableLocker; -using Application.Lockers.Commands.RemoveLocker; -using Application.Lockers.Commands.UpdateLocker; -using Application.Lockers.Queries.GetAllLockersPaginated; -using Application.Lockers.Queries.GetLockerById; using Infrastructure.Identity.Authorization; using Microsoft.AspNetCore.Mvc; +using LockerCommands = Application.Lockers.Commands; +using LockerQueries = Application.Lockers.Queries; namespace Api.Controllers; @@ -28,7 +22,7 @@ public class LockersController : ApiControllerBase [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> GetById([FromRoute] Guid lockerId) { - var query = new GetLockerByIdQuery() + var query = new LockerQueries.GetById.Query() { LockerId = lockerId, }; @@ -47,7 +41,7 @@ public async Task>> GetById([FromRoute] Guid lock public async Task>>> GetAllPaginated( [FromQuery] GetAllLockersPaginatedQueryParameters queryParameters) { - var query = new GetAllLockersPaginatedQuery() + var query = new LockerQueries.GetAllPaginated.Query() { RoomId = queryParameters.RoomId, Page = queryParameters.Page, @@ -66,7 +60,7 @@ public async Task>>> GetAllPaginate [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> Add([FromBody] AddLockerCommand command) + public async Task>> Add([FromBody] LockerCommands.Add.Command command) { var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); @@ -84,7 +78,7 @@ public async Task>> Add([FromBody] AddLockerComma [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> Remove([FromRoute] Guid lockerId) { - var command = new RemoveLockerCommand() + var command = new LockerCommands.Remove.Command() { LockerId = lockerId, }; @@ -106,7 +100,7 @@ public async Task>> Remove([FromRoute] Guid locke [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> Enable([FromRoute] Guid lockerId) { - var command = new EnableLockerCommand() + var command = new LockerCommands.Enable.Command() { LockerId = lockerId, }; @@ -128,7 +122,7 @@ public async Task>> Enable([FromRoute] Guid locke [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> Disable([FromRoute] Guid lockerId) { - var command = new DisableLockerCommand() + var command = new LockerCommands.Disable.Command() { LockerId = lockerId, }; @@ -149,7 +143,7 @@ public async Task>> Disable([FromRoute] Guid lock [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> Update([FromRoute] Guid lockerId, [FromBody] UpdateLockerRequest request) { - var command = new UpdateLockerCommand() + var command = new LockerCommands.Update.Command() { LockerId = lockerId, Name = request.Name, diff --git a/src/Api/Controllers/RoomsController.cs b/src/Api/Controllers/RoomsController.cs index 6ff5829f..38f0b339 100644 --- a/src/Api/Controllers/RoomsController.cs +++ b/src/Api/Controllers/RoomsController.cs @@ -3,16 +3,10 @@ using Application.Common.Models; using Application.Common.Models.Dtos.Physical; using Application.Identity; -using Application.Rooms.Commands.AddRoom; -using Application.Rooms.Commands.DisableRoom; -using Application.Rooms.Commands.EnableRoom; -using Application.Rooms.Commands.RemoveRoom; -using Application.Rooms.Commands.UpdateRoom; -using Application.Rooms.Queries.GetAllRoomPaginated; -using Application.Rooms.Queries.GetEmptyContainersPaginated; -using Application.Rooms.Queries.GetRoomById; using Infrastructure.Identity.Authorization; using Microsoft.AspNetCore.Mvc; +using RoomCommands = Application.Rooms.Commands; +using RoomQueries = Application.Rooms.Queries; namespace Api.Controllers; @@ -29,7 +23,7 @@ public class RoomsController : ApiControllerBase [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> GetById([FromRoute] Guid roomId) { - var query = new GetRoomByIdQuery() + var query = new RoomQueries.GetById.Query() { RoomId = roomId, }; @@ -48,7 +42,7 @@ public async Task>> GetById([FromRoute] Guid roomId public async Task>>> GetAllPaginated( [FromQuery] GetAllLockersPaginatedQueryParameters queryParameters) { - var query = new GetAllRoomsPaginatedQuery() + var query = new RoomQueries.GetAllPaginated.Query() { Page = queryParameters.Page, Size = queryParameters.Size, @@ -69,18 +63,18 @@ public async Task>>> GetAllPaginated( [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task>> GetEmptyContainers( + public async Task>> GetEmptyContainers( [FromRoute] Guid roomId, [FromQuery] GetEmptyContainersPaginatedQueryParameters queryParameters) { - var query = new GetEmptyContainersPaginatedQuery() + var query = new RoomQueries.GetEmptyContainersPaginated.Query() { RoomId = roomId, Page = queryParameters.Page, Size = queryParameters.Size, }; var result = await Mediator.Send(query); - return Ok(Result>.Succeed(result)); + return Ok(Result>.Succeed(result)); } /// @@ -95,7 +89,7 @@ public async Task>> GetEmptyContainer [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> AddRoom([FromBody] AddRoomCommand command) + public async Task>> AddRoom([FromBody] RoomCommands.Add.Command command) { var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); @@ -114,7 +108,7 @@ public async Task>> AddRoom([FromBody] AddRoomComma [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> RemoveRoom([FromRoute] Guid roomId) { - var command = new RemoveRoomCommand() + var command = new RoomCommands.Remove.Command() { RoomId = roomId, }; @@ -134,7 +128,7 @@ public async Task>> RemoveRoom([FromRoute] Guid roo [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> EnableRoom([FromRoute] Guid roomId) { - var command = new EnableRoomCommand() + var command = new RoomCommands.Enable.Command() { RoomId = roomId, }; @@ -155,7 +149,7 @@ public async Task>> EnableRoom([FromRoute] Guid roo [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> DisableRoom([FromRoute] Guid roomId) { - var command = new DisableRoomCommand() + var command = new RoomCommands.Disable.Command() { RoomId = roomId, }; @@ -176,8 +170,7 @@ public async Task>> DisableRoom([FromRoute] Guid ro [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> Update([FromRoute] Guid roomId, [FromBody] UpdateRoomRequest request) { - Console.WriteLine(request.Description); - var command = new UpdateRoomCommand() + var command = new RoomCommands.Update.Command() { RoomId = roomId, Name = request.Name, diff --git a/src/Api/Controllers/StaffsController.cs b/src/Api/Controllers/StaffsController.cs index 5c2637af..717c9e44 100644 --- a/src/Api/Controllers/StaffsController.cs +++ b/src/Api/Controllers/StaffsController.cs @@ -1,14 +1,11 @@ using Api.Controllers.Payload.Requests.Staffs; using Application.Common.Models; +using Application.Common.Models.Dtos.Physical; using Application.Identity; -using Application.Staffs.Commands.RemoveStaffFromRoom; -using Application.Staffs.Queries.GetAllStaffsPaginated; -using Application.Staffs.Queries.GetStaffById; -using Application.Staffs.Queries.GetStaffByRoom; -using Application.Staffs.Commands.AddStaff; -using Application.Users.Queries.Physical; using Infrastructure.Identity.Authorization; using Microsoft.AspNetCore.Mvc; +using StaffCommands = Application.Staffs.Commands; +using StaffQueries = Application.Staffs.Queries; namespace Api.Controllers; @@ -25,7 +22,7 @@ public class StaffsController : ApiControllerBase [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> GetById([FromRoute] Guid staffId) { - var query = new GetStaffByIdQuery() + var query = new StaffQueries.GetById.Query() { StaffId = staffId }; @@ -44,7 +41,7 @@ public async Task>> GetById([FromRoute] Guid staff [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> GetByRoom([FromRoute] Guid roomId) { - var query = new GetStaffByRoomQuery() + var query = new StaffQueries.GetByRoom.Query() { RoomId = roomId }; @@ -63,7 +60,7 @@ public async Task>> GetByRoom([FromRoute] Guid roo public async Task>>> GetAllPaginated( [FromQuery] GetAllStaffsPaginatedQueryParameters queryParameters) { - var query = new GetAllStaffsPaginatedQuery() + var query = new StaffQueries.GetAllPaginated.Query() { Page = queryParameters.Page, Size = queryParameters.Size, @@ -79,7 +76,7 @@ public async Task>>> GetAllPaginated [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task>> Add([FromBody] AddStaffCommand command) + public async Task>> Add([FromBody] StaffCommands.Add.Command command) { var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); @@ -99,7 +96,7 @@ public async Task>> RemoveFromRoom( [FromRoute] Guid staffId, [FromBody] RemoveStaffFromRoomRequest request) { - var command = new RemoveStaffFromRoomCommand() + var command = new StaffCommands.RemoveFromRoom.Command() { StaffId = staffId, RoomId = request.RoomId, diff --git a/src/Api/Controllers/UsersController.cs b/src/Api/Controllers/UsersController.cs index d712f4e6..4e37540e 100644 --- a/src/Api/Controllers/UsersController.cs +++ b/src/Api/Controllers/UsersController.cs @@ -2,17 +2,17 @@ using Application.Common.Models; using Application.Common.Models.Dtos.Physical; using Application.Identity; -using Application.Users.Commands.AddUser; -using Application.Users.Commands.DisableUser; -using Application.Users.Commands.EnableUser; -using Application.Users.Commands.UpdateUser; +using Application.Users.Commands.Add; +using Application.Users.Commands.Disable; +using Application.Users.Commands.Update; using Application.Users.Queries; -using Application.Users.Queries.GetAllUsersPaginated; -using Application.Users.Queries.GetUserById; -using Application.Users.Queries.GetUsersByName; +using Application.Users.Queries.GetAllPaginated; +using Application.Users.Queries.GetById; using Infrastructure.Identity.Authorization; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using UserCommands = Application.Users.Commands; +using UserQueries = Application.Users.Queries; namespace Api.Controllers; @@ -29,7 +29,7 @@ public class UsersController : ApiControllerBase [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> GetById([FromRoute] Guid userId) { - var query = new GetUserByIdQuery + var query = new UserQueries.GetById.Query { UserId = userId, }; @@ -48,7 +48,7 @@ public async Task>> GetById([FromRoute] Guid userId public async Task>>> GetAllPaginated( [FromQuery] GetAllUsersPaginatedQueryParameters queryParameters) { - var query = new GetAllUsersPaginatedQuery() + var query = new UserQueries.GetAllPaginated.Query() { DepartmentId = queryParameters.DepartmentId, SearchTerm = queryParameters.SearchTerm, @@ -68,12 +68,12 @@ public async Task>>> GetAllPaginated( /// A UserDto of the added user [RequiresRole(IdentityData.Roles.Admin)] [HttpPost] - [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> Add([FromBody] AddUserCommand command) + public async Task>> Add([FromBody] UserCommands.Add.Command command) { var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); @@ -91,7 +91,7 @@ public async Task>> Add([FromBody] AddUserCommand c [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> Enable([FromRoute] Guid userId) { - var command = new EnableUserCommand() + var command = new UserCommands.Enable.Command() { UserId = userId }; @@ -112,7 +112,7 @@ public async Task>> Enable([FromRoute] Guid userId) [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> Disable([FromRoute] Guid userId) { - var command = new DisableUserCommand() + var command = new UserCommands.Disable.Command() { UserId = userId, }; @@ -133,7 +133,7 @@ public async Task>> Disable([FromRoute] Guid userId [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> Update([FromRoute] Guid userId, [FromBody] UpdateUserRequest request) { - var command = new UpdateUserCommand() + var command = new UserCommands.Update.Command() { UserId = userId, Username = request.Username, diff --git a/src/Api/Services/CurrentUserService.cs b/src/Api/Services/CurrentUserService.cs index 34a4b5be..d8b6c481 100644 --- a/src/Api/Services/CurrentUserService.cs +++ b/src/Api/Services/CurrentUserService.cs @@ -1,6 +1,5 @@ using System.IdentityModel.Tokens.Jwt; using Application.Common.Interfaces; -using Application.Identity; namespace Api.Services; diff --git a/src/Application/Common/Models/Dtos/Physical/RoomDto.cs b/src/Application/Common/Models/Dtos/Physical/RoomDto.cs index 5426161f..209c6ef6 100644 --- a/src/Application/Common/Models/Dtos/Physical/RoomDto.cs +++ b/src/Application/Common/Models/Dtos/Physical/RoomDto.cs @@ -1,5 +1,4 @@ using Application.Common.Mappings; -using Application.Users.Queries.Physical; using AutoMapper; using Domain.Entities.Physical; diff --git a/src/Application/Common/Models/Dtos/Physical/StaffDto.cs b/src/Application/Common/Models/Dtos/Physical/StaffDto.cs index b4ff5a80..ade92bb9 100644 --- a/src/Application/Common/Models/Dtos/Physical/StaffDto.cs +++ b/src/Application/Common/Models/Dtos/Physical/StaffDto.cs @@ -1,8 +1,8 @@ using Application.Common.Mappings; -using Application.Common.Models.Dtos.Physical; +using Application.Users.Queries; using Domain.Entities.Physical; -namespace Application.Users.Queries.Physical; +namespace Application.Common.Models.Dtos.Physical; public class StaffDto : IMapFrom { diff --git a/src/Application/Departments/Commands/AddDepartment/AddDepartmentCommand.cs b/src/Application/Departments/Commands/Add/Command.cs similarity index 77% rename from src/Application/Departments/Commands/AddDepartment/AddDepartmentCommand.cs rename to src/Application/Departments/Commands/Add/Command.cs index 00f42e5c..00d6cfba 100644 --- a/src/Application/Departments/Commands/AddDepartment/AddDepartmentCommand.cs +++ b/src/Application/Departments/Commands/Add/Command.cs @@ -6,14 +6,14 @@ using MediatR; using Microsoft.EntityFrameworkCore; -namespace Application.Departments.Commands.AddDepartment; +namespace Application.Departments.Commands.Add; -public record AddDepartmentCommand : IRequest +public record Command : IRequest { public string Name { get; init; } = null!; } -public class AddDepartmentCommandHandler : IRequestHandler +public class AddDepartmentCommandHandler : IRequestHandler { private readonly IApplicationDbContext _context; private readonly IMapper _mapper; @@ -23,7 +23,7 @@ public AddDepartmentCommandHandler(IApplicationDbContext context, IMapper mapper _mapper = mapper; } - public async Task Handle(AddDepartmentCommand request, CancellationToken cancellationToken) + public async Task Handle(Command request, CancellationToken cancellationToken) { var department = await _context.Departments.FirstOrDefaultAsync(x => x.Name.Trim().ToLower().Equals(request.Name.Trim().ToLower()), cancellationToken); diff --git a/src/Application/Departments/Commands/DeleteDepartment/DeleteDepartmentCommand.cs b/src/Application/Departments/Commands/Delete/Command.cs similarity index 63% rename from src/Application/Departments/Commands/DeleteDepartment/DeleteDepartmentCommand.cs rename to src/Application/Departments/Commands/Delete/Command.cs index 93ea7708..1790c454 100644 --- a/src/Application/Departments/Commands/DeleteDepartment/DeleteDepartmentCommand.cs +++ b/src/Application/Departments/Commands/Delete/Command.cs @@ -1,28 +1,27 @@ -using Application.Common.Exceptions; using Application.Common.Interfaces; using Application.Users.Queries; using AutoMapper; using MediatR; using Microsoft.EntityFrameworkCore; -namespace Application.Departments.Commands.DeleteDepartment; +namespace Application.Departments.Commands.Delete; -public record DeleteDepartmentCommand : IRequest +public record Command : IRequest { public Guid DepartmentId { get; init; } } -public class DeleteDepartmentCommandHandler : IRequestHandler +public class CommandHandler : IRequestHandler { private readonly IApplicationDbContext _context; private readonly IMapper _mapper; - public DeleteDepartmentCommandHandler(IApplicationDbContext context, IMapper mapper) + public CommandHandler(IApplicationDbContext context, IMapper mapper) { _context = context; _mapper = mapper; } - public async Task Handle(DeleteDepartmentCommand request, CancellationToken cancellationToken) + public async Task Handle(Command request, CancellationToken cancellationToken) { var department = await _context.Departments.FirstOrDefaultAsync(x => x.Id == request.DepartmentId, cancellationToken); diff --git a/src/Application/Departments/Commands/UpdateDepartment/UpdateDepartmentCommand.cs b/src/Application/Departments/Commands/Update/Command.cs similarity index 53% rename from src/Application/Departments/Commands/UpdateDepartment/UpdateDepartmentCommand.cs rename to src/Application/Departments/Commands/Update/Command.cs index 941879af..214df268 100644 --- a/src/Application/Departments/Commands/UpdateDepartment/UpdateDepartmentCommand.cs +++ b/src/Application/Departments/Commands/Update/Command.cs @@ -1,9 +1,9 @@ using Application.Users.Queries; using MediatR; -namespace Application.Departments.Commands.UpdateDepartment; +namespace Application.Departments.Commands.Update; -public record UpdateDepartmentCommand : IRequest +public record Command : IRequest { public Guid DepartmentId { get; set; } public string Name { get; init; } = null!; diff --git a/src/Application/Departments/Queries/GetAllDepartments/GetAllDepartmentsQuery.cs b/src/Application/Departments/Queries/GetAll/Query.cs similarity index 53% rename from src/Application/Departments/Queries/GetAllDepartments/GetAllDepartmentsQuery.cs rename to src/Application/Departments/Queries/GetAll/Query.cs index a0af15e1..42da4085 100644 --- a/src/Application/Departments/Queries/GetAllDepartments/GetAllDepartmentsQuery.cs +++ b/src/Application/Departments/Queries/GetAll/Query.cs @@ -2,26 +2,25 @@ using Application.Common.Interfaces; using Application.Users.Queries; using AutoMapper; -using Domain.Entities; using MediatR; using Microsoft.EntityFrameworkCore; -namespace Application.Departments.Queries.GetAllDepartments; +namespace Application.Departments.Queries.GetAll; -public record GetAllDepartmentsQuery : IRequest>; +public record Query : IRequest>; -public class GetAllDepartmentsQueryHandler : IRequestHandler> +public class QueryHandler : IRequestHandler> { private readonly IApplicationDbContext _context; private readonly IMapper _mapper; - public GetAllDepartmentsQueryHandler(IApplicationDbContext context, IMapper mapper) + public QueryHandler(IApplicationDbContext context, IMapper mapper) { _context = context; _mapper = mapper; } - public async Task> Handle(GetAllDepartmentsQuery request, CancellationToken cancellationToken) + public async Task> Handle(Query request, CancellationToken cancellationToken) { var departments = await _context.Departments.ToListAsync(cancellationToken); var result = new ReadOnlyCollection(_mapper.Map>(departments)); diff --git a/src/Application/Departments/Queries/GetById/Query.cs b/src/Application/Departments/Queries/GetById/Query.cs new file mode 100644 index 00000000..4748a984 --- /dev/null +++ b/src/Application/Departments/Queries/GetById/Query.cs @@ -0,0 +1,9 @@ +using Application.Users.Queries; +using MediatR; + +namespace Application.Departments.Queries.GetById; + +public record Query : IRequest +{ + public Guid DepartmentId { get; init; } +} \ No newline at end of file diff --git a/src/Application/Departments/Queries/GetDepartmentById/GetDepartmentByIdQuery.cs b/src/Application/Departments/Queries/GetDepartmentById/GetDepartmentByIdQuery.cs deleted file mode 100644 index fe0ec11a..00000000 --- a/src/Application/Departments/Queries/GetDepartmentById/GetDepartmentByIdQuery.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Application.Users.Queries; -using MediatR; - -namespace Application.Departments.Queries.GetDepartmentById; - -public record GetDepartmentByIdQuery : IRequest -{ - public Guid DepartmentId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Documents/Commands/Delete/Command.cs b/src/Application/Documents/Commands/Delete/Command.cs new file mode 100644 index 00000000..9453adfc --- /dev/null +++ b/src/Application/Documents/Commands/Delete/Command.cs @@ -0,0 +1,9 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Documents.Commands.Delete; + +public record Command : IRequest +{ + public Guid DocumentId { get; init; } +} \ No newline at end of file diff --git a/src/Application/Documents/Commands/DeleteDocument/DeleteDocumentCommand.cs b/src/Application/Documents/Commands/DeleteDocument/DeleteDocumentCommand.cs deleted file mode 100644 index eefecf87..00000000 --- a/src/Application/Documents/Commands/DeleteDocument/DeleteDocumentCommand.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Documents.Commands.DeleteDocument; - -public record DeleteDocumentCommand : IRequest -{ - public Guid DocumentId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Documents/Commands/ImportDocument/ImportDocumentCommand.cs b/src/Application/Documents/Commands/Import/Command.cs similarity index 84% rename from src/Application/Documents/Commands/ImportDocument/ImportDocumentCommand.cs rename to src/Application/Documents/Commands/Import/Command.cs index 7989bf5a..260e0a16 100644 --- a/src/Application/Documents/Commands/ImportDocument/ImportDocumentCommand.cs +++ b/src/Application/Documents/Commands/Import/Command.cs @@ -6,9 +6,9 @@ using MediatR; using Microsoft.EntityFrameworkCore; -namespace Application.Documents.Commands.ImportDocument; +namespace Application.Documents.Commands.Import; -public record ImportDocumentCommand : IRequest +public record Command : IRequest { public string Title { get; init; } = null!; public string? Description { get; init; } @@ -17,18 +17,18 @@ public record ImportDocumentCommand : IRequest public Guid FolderId { get; init; } } -public class ImportDocumentCommandHandler : IRequestHandler +public class CommandHandler : IRequestHandler { private readonly IApplicationDbContext _context; private readonly IMapper _mapper; - public ImportDocumentCommandHandler(IApplicationDbContext context, IMapper mapper) + public CommandHandler(IApplicationDbContext context, IMapper mapper) { _context = context; _mapper = mapper; } - public async Task Handle(ImportDocumentCommand request, CancellationToken cancellationToken) + public async Task Handle(Command request, CancellationToken cancellationToken) { var importer = await _context.Users .Include(x => x.Department) diff --git a/src/Application/Documents/Commands/UpdateDocument/UpdateDocumentCommand.cs b/src/Application/Documents/Commands/Update/Command.cs similarity index 68% rename from src/Application/Documents/Commands/UpdateDocument/UpdateDocumentCommand.cs rename to src/Application/Documents/Commands/Update/Command.cs index d7b06736..c8bc2cb0 100644 --- a/src/Application/Documents/Commands/UpdateDocument/UpdateDocumentCommand.cs +++ b/src/Application/Documents/Commands/Update/Command.cs @@ -1,9 +1,9 @@ using Application.Common.Models.Dtos.Physical; using MediatR; -namespace Application.Documents.Commands.UpdateDocument; +namespace Application.Documents.Commands.Update; -public record UpdateDocumentCommand : IRequest +public record Command : IRequest { public Guid DocumentId { get; init; } public string Title { get; init; } = null!; diff --git a/src/Application/Documents/Queries/GetAllDocumentsPaginated/DocumentItemDto.cs b/src/Application/Documents/Queries/GetAllPaginated/DocumentItemDto.cs similarity index 86% rename from src/Application/Documents/Queries/GetAllDocumentsPaginated/DocumentItemDto.cs rename to src/Application/Documents/Queries/GetAllPaginated/DocumentItemDto.cs index 86cc8533..5eae4124 100644 --- a/src/Application/Documents/Queries/GetAllDocumentsPaginated/DocumentItemDto.cs +++ b/src/Application/Documents/Queries/GetAllPaginated/DocumentItemDto.cs @@ -1,10 +1,9 @@ using Application.Common.Mappings; using Application.Common.Models.Dtos.Physical; using Application.Users.Queries; -using AutoMapper; using Domain.Entities.Physical; -namespace Application.Documents.Queries.GetAllDocumentsPaginated; +namespace Application.Documents.Queries.GetAllPaginated; [Obsolete] public class DocumentItemDto : IMapFrom diff --git a/src/Application/Documents/Queries/GetAllDocumentsPaginated/GetAllDocumentsPaginatedQuery.cs b/src/Application/Documents/Queries/GetAllPaginated/Query.cs similarity index 92% rename from src/Application/Documents/Queries/GetAllDocumentsPaginated/GetAllDocumentsPaginatedQuery.cs rename to src/Application/Documents/Queries/GetAllPaginated/Query.cs index 566df131..f39b14b0 100644 --- a/src/Application/Documents/Queries/GetAllDocumentsPaginated/GetAllDocumentsPaginatedQuery.cs +++ b/src/Application/Documents/Queries/GetAllPaginated/Query.cs @@ -9,9 +9,9 @@ using MediatR; using Microsoft.EntityFrameworkCore; -namespace Application.Documents.Queries.GetAllDocumentsPaginated; +namespace Application.Documents.Queries.GetAllPaginated; -public record GetAllDocumentsPaginatedQuery : IRequest> +public record Query : IRequest> { public Guid? RoomId { get; init; } public Guid? LockerId { get; init; } @@ -23,7 +23,7 @@ public record GetAllDocumentsPaginatedQuery : IRequest> +public class GetAllDocumentsPaginatedQueryHandler : IRequestHandler> { private readonly IApplicationDbContext _context; private readonly IMapper _mapper; @@ -34,7 +34,7 @@ public GetAllDocumentsPaginatedQueryHandler(IApplicationDbContext context, IMapp _mapper = mapper; } - public async Task> Handle(GetAllDocumentsPaginatedQuery request, + public async Task> Handle(Query request, CancellationToken cancellationToken) { var documents = _context.Documents.AsQueryable(); diff --git a/src/Application/Documents/Queries/GetAllDocumentsPaginated/GetAllDocumentsPaginatedQueryValidator.cs b/src/Application/Documents/Queries/GetAllPaginated/Validator.cs similarity index 71% rename from src/Application/Documents/Queries/GetAllDocumentsPaginated/GetAllDocumentsPaginatedQueryValidator.cs rename to src/Application/Documents/Queries/GetAllPaginated/Validator.cs index d95c7e3d..d5bcd880 100644 --- a/src/Application/Documents/Queries/GetAllDocumentsPaginated/GetAllDocumentsPaginatedQueryValidator.cs +++ b/src/Application/Documents/Queries/GetAllPaginated/Validator.cs @@ -1,10 +1,10 @@ using FluentValidation; -namespace Application.Documents.Queries.GetAllDocumentsPaginated; +namespace Application.Documents.Queries.GetAllPaginated; -public class GetAllDocumentsPaginatedQueryValidator : AbstractValidator +public class Validator : AbstractValidator { - public GetAllDocumentsPaginatedQueryValidator() + public Validator() { RuleLevelCascadeMode = CascadeMode.Stop; diff --git a/src/Application/Documents/Queries/GetDocumentById/GetDocumentByIdQuery.cs b/src/Application/Documents/Queries/GetById/Query.cs similarity index 68% rename from src/Application/Documents/Queries/GetDocumentById/GetDocumentByIdQuery.cs rename to src/Application/Documents/Queries/GetById/Query.cs index d8dca176..ab15e257 100644 --- a/src/Application/Documents/Queries/GetDocumentById/GetDocumentByIdQuery.cs +++ b/src/Application/Documents/Queries/GetById/Query.cs @@ -4,24 +4,24 @@ using MediatR; using Microsoft.EntityFrameworkCore; -namespace Application.Documents.Queries.GetDocumentById; +namespace Application.Documents.Queries.GetById; -public record GetDocumentByIdQuery : IRequest +public record Query : IRequest { public Guid DocumentId { get; init; } } -public class GetDocumentByIdQueryHandler : IRequestHandler +public class QueryHandler : IRequestHandler { private readonly IApplicationDbContext _context; private readonly IMapper _mapper; - public GetDocumentByIdQueryHandler(IApplicationDbContext context, IMapper mapper) + public QueryHandler(IApplicationDbContext context, IMapper mapper) { _context = context; _mapper = mapper; } - public async Task Handle(GetDocumentByIdQuery request, CancellationToken cancellationToken) + public async Task Handle(Query request, CancellationToken cancellationToken) { var document = await _context.Documents .Include(x => x.Department) diff --git a/src/Application/Documents/Queries/GetDocumentTypes/GetDocumentTypesQuery.cs b/src/Application/Documents/Queries/GetDocumentTypes/GetDocumentTypesQuery.cs deleted file mode 100644 index b6f65030..00000000 --- a/src/Application/Documents/Queries/GetDocumentTypes/GetDocumentTypesQuery.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Collections.ObjectModel; -using Application.Common.Interfaces; -using MediatR; -using Microsoft.EntityFrameworkCore; - -namespace Application.Documents.Queries.GetDocumentTypes; - -public record GetDocumentTypesQuery : IRequest>; - -public class GetDocumentTypesQueryHandler : IRequestHandler> -{ - private readonly IApplicationDbContext _context; - - public GetDocumentTypesQueryHandler(IApplicationDbContext context) - { - _context = context; - } - public async Task> Handle(GetDocumentTypesQuery request, CancellationToken cancellationToken) - { - return new ReadOnlyCollection(await _context.Documents.Select(x => x.DocumentType) - .ToListAsync(cancellationToken)); - } -} \ No newline at end of file diff --git a/src/Application/Documents/Queries/GetDocumentTypes/GetAllDocumentTypesQuery.cs b/src/Application/Documents/Queries/GetDocumentTypes/Query.cs similarity index 54% rename from src/Application/Documents/Queries/GetDocumentTypes/GetAllDocumentTypesQuery.cs rename to src/Application/Documents/Queries/GetDocumentTypes/Query.cs index 841aa23e..c0875551 100644 --- a/src/Application/Documents/Queries/GetDocumentTypes/GetAllDocumentTypesQuery.cs +++ b/src/Application/Documents/Queries/GetDocumentTypes/Query.cs @@ -5,17 +5,17 @@ namespace Application.Documents.Queries.GetDocumentTypes; -public record GetAllDocumentTypesQuery : IRequest>; +public record Query : IRequest>; -public class GetAllDocumentTypesQueryHandler : IRequestHandler> +public class QueryHandler : IRequestHandler> { private readonly IApplicationDbContext _context; - public GetAllDocumentTypesQueryHandler(IApplicationDbContext context) + public QueryHandler(IApplicationDbContext context) { _context = context; } - public async Task> Handle(GetAllDocumentTypesQuery request, CancellationToken cancellationToken) + public async Task> Handle(Query request, CancellationToken cancellationToken) { return new ReadOnlyCollection(await _context.Documents.Select(x => x.DocumentType).Distinct() .ToListAsync(cancellationToken)); diff --git a/src/Application/Folders/Commands/AddFolder/AddFolderCommand.cs b/src/Application/Folders/Commands/Add/Command.cs similarity index 83% rename from src/Application/Folders/Commands/AddFolder/AddFolderCommand.cs rename to src/Application/Folders/Commands/Add/Command.cs index bf974013..5fa9f0ae 100644 --- a/src/Application/Folders/Commands/AddFolder/AddFolderCommand.cs +++ b/src/Application/Folders/Commands/Add/Command.cs @@ -7,9 +7,9 @@ using MediatR; using Microsoft.EntityFrameworkCore; -namespace Application.Folders.Commands.AddFolder; +namespace Application.Folders.Commands.Add; -public record AddFolderCommand : IRequest +public record Command : IRequest { public string Name { get; init; } = null!; public string? Description { get; init; } @@ -17,18 +17,18 @@ public record AddFolderCommand : IRequest public Guid LockerId { get; init; } } -public class AddFolderCommandHandler : IRequestHandler +public class CommandHandler : IRequestHandler { private readonly IApplicationDbContext _context; private readonly IMapper _mapper; - public AddFolderCommandHandler(IApplicationDbContext context, IMapper mapper) + public CommandHandler(IApplicationDbContext context, IMapper mapper) { _context = context; _mapper = mapper; } - public async Task Handle(AddFolderCommand request, CancellationToken cancellationToken) + public async Task Handle(Command request, CancellationToken cancellationToken) { var locker = await _context.Lockers.FirstOrDefaultAsync(l => l.Id == request.LockerId, cancellationToken); diff --git a/src/Application/Folders/Commands/AddFolder/AddFolderCommandValidator.cs b/src/Application/Folders/Commands/Add/Validator.cs similarity index 80% rename from src/Application/Folders/Commands/AddFolder/AddFolderCommandValidator.cs rename to src/Application/Folders/Commands/Add/Validator.cs index f7717f54..89eb45d5 100644 --- a/src/Application/Folders/Commands/AddFolder/AddFolderCommandValidator.cs +++ b/src/Application/Folders/Commands/Add/Validator.cs @@ -1,10 +1,10 @@ using FluentValidation; -namespace Application.Folders.Commands.AddFolder; +namespace Application.Folders.Commands.Add; -public class AddFolderCommandValidator : AbstractValidator +public class Validator : AbstractValidator { - public AddFolderCommandValidator() + public Validator() { RuleLevelCascadeMode = CascadeMode.Stop; diff --git a/src/Application/Folders/Commands/DisableFolder/DisableFolderCommand.cs b/src/Application/Folders/Commands/Disable/Command.cs similarity index 74% rename from src/Application/Folders/Commands/DisableFolder/DisableFolderCommand.cs rename to src/Application/Folders/Commands/Disable/Command.cs index adf845df..9538e7cd 100644 --- a/src/Application/Folders/Commands/DisableFolder/DisableFolderCommand.cs +++ b/src/Application/Folders/Commands/Disable/Command.cs @@ -5,25 +5,25 @@ using MediatR; using Microsoft.EntityFrameworkCore; -namespace Application.Folders.Commands.DisableFolder; +namespace Application.Folders.Commands.Disable; -public record DisableFolderCommand : IRequest +public record Command : IRequest { public Guid FolderId { get; init; } } -public class DisableFolderCommandHandler : IRequestHandler +public class CommandHandler : IRequestHandler { private readonly IApplicationDbContext _context; private readonly IMapper _mapper; - public DisableFolderCommandHandler(IApplicationDbContext context, IMapper mapper) + public CommandHandler(IApplicationDbContext context, IMapper mapper) { _context = context; _mapper = mapper; } - public async Task Handle(DisableFolderCommand request, CancellationToken cancellationToken) + public async Task Handle(Command request, CancellationToken cancellationToken) { var folder = await _context.Folders .FirstOrDefaultAsync(f => f.Id.Equals(request.FolderId), cancellationToken); diff --git a/src/Application/Folders/Commands/DisableFolder/DisableFolderCommandValidator.cs b/src/Application/Folders/Commands/Disable/Validator.cs similarity index 50% rename from src/Application/Folders/Commands/DisableFolder/DisableFolderCommandValidator.cs rename to src/Application/Folders/Commands/Disable/Validator.cs index 04621166..d0d22562 100644 --- a/src/Application/Folders/Commands/DisableFolder/DisableFolderCommandValidator.cs +++ b/src/Application/Folders/Commands/Disable/Validator.cs @@ -1,10 +1,10 @@ using FluentValidation; -namespace Application.Folders.Commands.DisableFolder; +namespace Application.Folders.Commands.Disable; -public class DisableFolderCommandValidator : AbstractValidator +public class Validator : AbstractValidator { - public DisableFolderCommandValidator() + public Validator() { RuleLevelCascadeMode = CascadeMode.Stop; diff --git a/src/Application/Folders/Commands/Enable/Command.cs b/src/Application/Folders/Commands/Enable/Command.cs new file mode 100644 index 00000000..086e96c3 --- /dev/null +++ b/src/Application/Folders/Commands/Enable/Command.cs @@ -0,0 +1,9 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Folders.Commands.Enable; + +public record Command : IRequest +{ + public Guid FolderId { get; init; } +} diff --git a/src/Application/Folders/Commands/EnableFolder/EnableFolderCommand.cs b/src/Application/Folders/Commands/EnableFolder/EnableFolderCommand.cs deleted file mode 100644 index eb7f49f9..00000000 --- a/src/Application/Folders/Commands/EnableFolder/EnableFolderCommand.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Folders.Commands.EnableFolder; - -public record EnableFolderCommand : IRequest -{ - public Guid FolderId { get; init; } -} diff --git a/src/Application/Folders/Commands/Remove/Command.cs b/src/Application/Folders/Commands/Remove/Command.cs new file mode 100644 index 00000000..85928dfe --- /dev/null +++ b/src/Application/Folders/Commands/Remove/Command.cs @@ -0,0 +1,9 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Folders.Commands.Remove; + +public record Command : IRequest +{ + public Guid FolderId { get; init; } +} \ No newline at end of file diff --git a/src/Application/Folders/Commands/RemoveFolder/RemoveFolderCommand.cs b/src/Application/Folders/Commands/RemoveFolder/RemoveFolderCommand.cs deleted file mode 100644 index 91db8b5e..00000000 --- a/src/Application/Folders/Commands/RemoveFolder/RemoveFolderCommand.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Folders.Commands.RemoveFolder; - -public record RemoveFolderCommand : IRequest -{ - public Guid FolderId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Folders/Commands/UpdateFolder/UpdateFolderCommand.cs b/src/Application/Folders/Commands/Update/Command.cs similarity index 68% rename from src/Application/Folders/Commands/UpdateFolder/UpdateFolderCommand.cs rename to src/Application/Folders/Commands/Update/Command.cs index 30ebea09..1231e98a 100644 --- a/src/Application/Folders/Commands/UpdateFolder/UpdateFolderCommand.cs +++ b/src/Application/Folders/Commands/Update/Command.cs @@ -1,9 +1,9 @@ using Application.Common.Models.Dtos.Physical; using MediatR; -namespace Application.Folders.Commands.UpdateFolder; +namespace Application.Folders.Commands.Update; -public record UpdateFolderCommand : IRequest +public record Command : IRequest { public Guid FolderId { get; init; } public string Name { get; init; } = null!; diff --git a/src/Application/Folders/Queries/GetAllFoldersPaginated/GetAllFoldersPaginatedQuery.cs b/src/Application/Folders/Queries/GetAllPaginated/Query.cs similarity index 70% rename from src/Application/Folders/Queries/GetAllFoldersPaginated/GetAllFoldersPaginatedQuery.cs rename to src/Application/Folders/Queries/GetAllPaginated/Query.cs index ecd9fbb2..d66d1fc8 100644 --- a/src/Application/Folders/Queries/GetAllFoldersPaginated/GetAllFoldersPaginatedQuery.cs +++ b/src/Application/Folders/Queries/GetAllPaginated/Query.cs @@ -2,9 +2,9 @@ using Application.Common.Models.Dtos.Physical; using MediatR; -namespace Application.Folders.Queries.GetAllFoldersPaginated; +namespace Application.Folders.Queries.GetAllPaginated; -public record GetAllFoldersPaginatedQuery : IRequest> +public record Query : IRequest> { public Guid? RoomId { get; init; } public Guid? LockerId { get; init; } diff --git a/src/Application/Folders/Queries/GetById/Query.cs b/src/Application/Folders/Queries/GetById/Query.cs new file mode 100644 index 00000000..3891c3c4 --- /dev/null +++ b/src/Application/Folders/Queries/GetById/Query.cs @@ -0,0 +1,9 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Folders.Queries.GetById; + +public record Query : IRequest +{ + public Guid FolderId { get; init; } +} \ No newline at end of file diff --git a/src/Application/Folders/Queries/GetFolderById/GetFolderByIdQuery.cs b/src/Application/Folders/Queries/GetFolderById/GetFolderByIdQuery.cs deleted file mode 100644 index bf422997..00000000 --- a/src/Application/Folders/Queries/GetFolderById/GetFolderByIdQuery.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Folders.Queries.GetFolderById; - -public record GetFolderByIdQuery : IRequest -{ - public Guid FolderId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Identity/IdentityData.cs b/src/Application/Identity/IdentityData.cs index a9742b72..165e74e7 100644 --- a/src/Application/Identity/IdentityData.cs +++ b/src/Application/Identity/IdentityData.cs @@ -2,12 +2,6 @@ namespace Application.Identity; public static class IdentityData { - public static class Claims - { - public const string Role = "role"; - public const string Department = "department"; - } - public static class Roles { public const string Admin = "Admin"; diff --git a/src/Application/Lockers/Commands/AddLocker/AddLockerCommand.cs b/src/Application/Lockers/Commands/Add/Command.cs similarity index 83% rename from src/Application/Lockers/Commands/AddLocker/AddLockerCommand.cs rename to src/Application/Lockers/Commands/Add/Command.cs index 7a47bd87..3ce0f7e3 100644 --- a/src/Application/Lockers/Commands/AddLocker/AddLockerCommand.cs +++ b/src/Application/Lockers/Commands/Add/Command.cs @@ -7,9 +7,9 @@ using MediatR; using Microsoft.EntityFrameworkCore; -namespace Application.Lockers.Commands.AddLocker; +namespace Application.Lockers.Commands.Add; -public record AddLockerCommand : IRequest +public record Command : IRequest { public string Name { get; init; } = null!; public string? Description { get; init; } @@ -17,18 +17,18 @@ public record AddLockerCommand : IRequest public int Capacity { get; init; } } -public class AddLockerCommandHandler : IRequestHandler +public class CommandHandler : IRequestHandler { private readonly IApplicationDbContext _context; private readonly IMapper _mapper; - public AddLockerCommandHandler(IApplicationDbContext context, IMapper mapper) + public CommandHandler(IApplicationDbContext context, IMapper mapper) { _context = context; _mapper = mapper; } - public async Task Handle(AddLockerCommand request, CancellationToken cancellationToken) + public async Task Handle(Command request, CancellationToken cancellationToken) { var room = await _context.Rooms.FirstOrDefaultAsync(x => x.Id == request.RoomId, cancellationToken); diff --git a/src/Application/Lockers/Commands/AddLocker/AddLockerCommandValidator.cs b/src/Application/Lockers/Commands/Add/Validator.cs similarity index 72% rename from src/Application/Lockers/Commands/AddLocker/AddLockerCommandValidator.cs rename to src/Application/Lockers/Commands/Add/Validator.cs index 4a919d32..834261bf 100644 --- a/src/Application/Lockers/Commands/AddLocker/AddLockerCommandValidator.cs +++ b/src/Application/Lockers/Commands/Add/Validator.cs @@ -1,14 +1,14 @@ -using Application.Common.Interfaces; -using FluentValidation; +using FluentValidation; -namespace Application.Lockers.Commands.AddLocker; +namespace Application.Lockers.Commands.Add; -public class AddLockerCommandValidator : AbstractValidator +public class Validator : AbstractValidator { - public AddLockerCommandValidator() + public Validator() { RuleLevelCascadeMode = CascadeMode.Stop; + RuleFor(x => x.Capacity) .GreaterThan(0).WithMessage("Locker's capacity cannot be less than 1"); diff --git a/src/Application/Lockers/Commands/DisableLocker/DisableLockerCommand.cs b/src/Application/Lockers/Commands/Disable/Command.cs similarity index 84% rename from src/Application/Lockers/Commands/DisableLocker/DisableLockerCommand.cs rename to src/Application/Lockers/Commands/Disable/Command.cs index e3785e25..dfbeb5a3 100644 --- a/src/Application/Lockers/Commands/DisableLocker/DisableLockerCommand.cs +++ b/src/Application/Lockers/Commands/Disable/Command.cs @@ -5,14 +5,14 @@ using MediatR; using Microsoft.EntityFrameworkCore; -namespace Application.Lockers.Commands.DisableLocker; +namespace Application.Lockers.Commands.Disable; -public record DisableLockerCommand : IRequest +public record Command : IRequest { public Guid LockerId { get; init; } } -public class RemoveLockerCommandHandler : IRequestHandler +public class RemoveLockerCommandHandler : IRequestHandler { private readonly IApplicationDbContext _context; private readonly IMapper _mapper; @@ -23,7 +23,7 @@ public RemoveLockerCommandHandler(IApplicationDbContext context, IMapper mapper) _mapper = mapper; } - public async Task Handle(DisableLockerCommand request, CancellationToken cancellationToken) + public async Task Handle(Command request, CancellationToken cancellationToken) { var locker = await _context.Lockers .FirstOrDefaultAsync(x => x.Id.Equals(request.LockerId), cancellationToken); diff --git a/src/Application/Lockers/Commands/Disable/Validator.cs b/src/Application/Lockers/Commands/Disable/Validator.cs new file mode 100644 index 00000000..03e69143 --- /dev/null +++ b/src/Application/Lockers/Commands/Disable/Validator.cs @@ -0,0 +1,14 @@ +using FluentValidation; + +namespace Application.Lockers.Commands.Disable; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleLevelCascadeMode = CascadeMode.Stop; + + RuleFor(x => x.LockerId) + .NotEmpty().WithMessage("LockerId is required."); + } +} \ No newline at end of file diff --git a/src/Application/Lockers/Commands/DisableLocker/DisableLockerCommandValidator.cs b/src/Application/Lockers/Commands/DisableLocker/DisableLockerCommandValidator.cs deleted file mode 100644 index e6192be6..00000000 --- a/src/Application/Lockers/Commands/DisableLocker/DisableLockerCommandValidator.cs +++ /dev/null @@ -1,13 +0,0 @@ -using FluentValidation; - -namespace Application.Lockers.Commands.DisableLocker; - -public class DisableLockerCommandValidator : AbstractValidator -{ - public DisableLockerCommandValidator() - { - RuleLevelCascadeMode = CascadeMode.Stop; - RuleFor(x => x.LockerId) - .NotEmpty().WithMessage("Locker Id is required."); - } -} \ No newline at end of file diff --git a/src/Application/Lockers/Commands/EnableLocker/EnableLockerCommand.cs b/src/Application/Lockers/Commands/Enable/Command.cs similarity index 70% rename from src/Application/Lockers/Commands/EnableLocker/EnableLockerCommand.cs rename to src/Application/Lockers/Commands/Enable/Command.cs index 4c1cb485..8f050747 100644 --- a/src/Application/Lockers/Commands/EnableLocker/EnableLockerCommand.cs +++ b/src/Application/Lockers/Commands/Enable/Command.cs @@ -2,29 +2,28 @@ using Application.Common.Interfaces; using Application.Common.Models.Dtos.Physical; using AutoMapper; -using Domain.Exceptions; using MediatR; using Microsoft.EntityFrameworkCore; -namespace Application.Lockers.Commands.EnableLocker; +namespace Application.Lockers.Commands.Enable; -public record EnableLockerCommand : IRequest +public record Command : IRequest { public Guid LockerId { get; init; } } -public class EnableLockerCommandHandler : IRequestHandler +public class CommandHandler : IRequestHandler { private readonly IApplicationDbContext _context; private readonly IMapper _mapper; - public EnableLockerCommandHandler(IApplicationDbContext context, IMapper mapper) + public CommandHandler(IApplicationDbContext context, IMapper mapper) { _context = context; _mapper = mapper; } - public async Task Handle(EnableLockerCommand request, CancellationToken cancellationToken) + public async Task Handle(Command request, CancellationToken cancellationToken) { var locker = await _context.Lockers .FirstOrDefaultAsync(x => x.Id.Equals(request.LockerId), cancellationToken); diff --git a/src/Application/Lockers/Commands/Enable/Validator.cs b/src/Application/Lockers/Commands/Enable/Validator.cs new file mode 100644 index 00000000..8d73c584 --- /dev/null +++ b/src/Application/Lockers/Commands/Enable/Validator.cs @@ -0,0 +1,14 @@ +using FluentValidation; + +namespace Application.Lockers.Commands.Enable; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleLevelCascadeMode = CascadeMode.Stop; + + RuleFor(x => x.LockerId) + .NotEmpty().WithMessage("LockerId is required."); + } +} \ No newline at end of file diff --git a/src/Application/Lockers/Commands/EnableLocker/EnableLockerCommandValidator.cs b/src/Application/Lockers/Commands/EnableLocker/EnableLockerCommandValidator.cs deleted file mode 100644 index 2fcbbec9..00000000 --- a/src/Application/Lockers/Commands/EnableLocker/EnableLockerCommandValidator.cs +++ /dev/null @@ -1,13 +0,0 @@ -using FluentValidation; - -namespace Application.Lockers.Commands.EnableLocker; - -public class EnableLockerCommandValidator : AbstractValidator -{ - public EnableLockerCommandValidator() - { - RuleLevelCascadeMode = CascadeMode.Stop; - RuleFor(x => x.LockerId) - .NotEmpty().WithMessage("Locker Id is required."); - } -} \ No newline at end of file diff --git a/src/Application/Lockers/Commands/Remove/Command.cs b/src/Application/Lockers/Commands/Remove/Command.cs new file mode 100644 index 00000000..91613358 --- /dev/null +++ b/src/Application/Lockers/Commands/Remove/Command.cs @@ -0,0 +1,9 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Lockers.Commands.Remove; + +public record Command : IRequest +{ + public Guid LockerId { get; init; } +} \ No newline at end of file diff --git a/src/Application/Lockers/Commands/RemoveLocker/RemoveLockerCommand.cs b/src/Application/Lockers/Commands/RemoveLocker/RemoveLockerCommand.cs deleted file mode 100644 index 412df4b7..00000000 --- a/src/Application/Lockers/Commands/RemoveLocker/RemoveLockerCommand.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Lockers.Commands.RemoveLocker; - -public record RemoveLockerCommand : IRequest -{ - public Guid LockerId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Lockers/Commands/Update/Command.cs b/src/Application/Lockers/Commands/Update/Command.cs new file mode 100644 index 00000000..f3423fcd --- /dev/null +++ b/src/Application/Lockers/Commands/Update/Command.cs @@ -0,0 +1,12 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Lockers.Commands.Update; + +public record Command : IRequest +{ + public Guid LockerId { get; init; } + public string Name { get; init; } = null!; + public string? Description { get; init; } + public int Capacity { get; init; } +} \ No newline at end of file diff --git a/src/Application/Lockers/Commands/UpdateLocker/UpdateLockerCommand.cs b/src/Application/Lockers/Commands/UpdateLocker/UpdateLockerCommand.cs deleted file mode 100644 index 540ceeef..00000000 --- a/src/Application/Lockers/Commands/UpdateLocker/UpdateLockerCommand.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Lockers.Commands.UpdateLocker; - -public record UpdateLockerCommand : IRequest -{ - public Guid LockerId { get; set; } - public string Name { get; set; } = null!; - public string? Description { get; set; } - public int Capacity { get; init; } -} \ No newline at end of file diff --git a/src/Application/Lockers/Queries/GetAllLockersPaginated/GetAllLockersPaginatedQuery.cs b/src/Application/Lockers/Queries/GetAllPaginated/Query.cs similarity index 67% rename from src/Application/Lockers/Queries/GetAllLockersPaginated/GetAllLockersPaginatedQuery.cs rename to src/Application/Lockers/Queries/GetAllPaginated/Query.cs index 4e0e8eb7..0dde471b 100644 --- a/src/Application/Lockers/Queries/GetAllLockersPaginated/GetAllLockersPaginatedQuery.cs +++ b/src/Application/Lockers/Queries/GetAllPaginated/Query.cs @@ -2,9 +2,9 @@ using Application.Common.Models.Dtos.Physical; using MediatR; -namespace Application.Lockers.Queries.GetAllLockersPaginated; +namespace Application.Lockers.Queries.GetAllPaginated; -public record GetAllLockersPaginatedQuery : IRequest> +public record Query : IRequest> { public Guid? RoomId { get; init; } public int? Page { get; init; } diff --git a/src/Application/Lockers/Queries/GetById/Query.cs b/src/Application/Lockers/Queries/GetById/Query.cs new file mode 100644 index 00000000..1e152dad --- /dev/null +++ b/src/Application/Lockers/Queries/GetById/Query.cs @@ -0,0 +1,9 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Lockers.Queries.GetById; + +public record Query : IRequest +{ + public Guid LockerId { get; init; } +} \ No newline at end of file diff --git a/src/Application/Lockers/Queries/GetLockerById/GetLockerByIdQuery.cs b/src/Application/Lockers/Queries/GetLockerById/GetLockerByIdQuery.cs deleted file mode 100644 index 1a592104..00000000 --- a/src/Application/Lockers/Queries/GetLockerById/GetLockerByIdQuery.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Lockers.Queries.GetLockerById; - -public record GetLockerByIdQuery : IRequest -{ - public Guid LockerId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Rooms/Commands/AddRoom/AddRoomCommand.cs b/src/Application/Rooms/Commands/Add/Command.cs similarity index 77% rename from src/Application/Rooms/Commands/AddRoom/AddRoomCommand.cs rename to src/Application/Rooms/Commands/Add/Command.cs index f255b988..634aa1d1 100644 --- a/src/Application/Rooms/Commands/AddRoom/AddRoomCommand.cs +++ b/src/Application/Rooms/Commands/Add/Command.cs @@ -6,27 +6,26 @@ using MediatR; using Microsoft.EntityFrameworkCore; -namespace Application.Rooms.Commands.AddRoom; +namespace Application.Rooms.Commands.Add; -public record AddRoomCommand : IRequest +public record Command : IRequest { public string Name { get; init; } = null!; public string? Description { get; init; } public int Capacity { get; init; } - } -public class AddRoomCommandHandler : IRequestHandler +public class CommandHandler : IRequestHandler { private readonly IApplicationDbContext _context; private readonly IMapper _mapper; - public AddRoomCommandHandler(IApplicationDbContext context, IMapper mapper) + public CommandHandler(IApplicationDbContext context, IMapper mapper) { _context = context; _mapper = mapper; } - public async Task Handle(AddRoomCommand request, CancellationToken cancellationToken) + public async Task Handle(Command request, CancellationToken cancellationToken) { var room = await _context.Rooms.FirstOrDefaultAsync(r => diff --git a/src/Application/Rooms/Commands/AddRoom/AddRoomCommandValidator.cs b/src/Application/Rooms/Commands/Add/Validator.cs similarity index 83% rename from src/Application/Rooms/Commands/AddRoom/AddRoomCommandValidator.cs rename to src/Application/Rooms/Commands/Add/Validator.cs index bfa65d1a..249543c8 100644 --- a/src/Application/Rooms/Commands/AddRoom/AddRoomCommandValidator.cs +++ b/src/Application/Rooms/Commands/Add/Validator.cs @@ -1,12 +1,12 @@ using Application.Common.Interfaces; using FluentValidation; -namespace Application.Rooms.Commands.AddRoom; +namespace Application.Rooms.Commands.Add; -public class AddRoomCommandValidator : AbstractValidator +public class Validator : AbstractValidator { private readonly IApplicationDbContext _context; - public AddRoomCommandValidator(IApplicationDbContext context) + public Validator(IApplicationDbContext context) { _context = context; diff --git a/src/Application/Rooms/Commands/DisableRoom/DisableRoomCommand.cs b/src/Application/Rooms/Commands/Disable/Command.cs similarity index 86% rename from src/Application/Rooms/Commands/DisableRoom/DisableRoomCommand.cs rename to src/Application/Rooms/Commands/Disable/Command.cs index 91ca9bdb..d4fd4ac5 100644 --- a/src/Application/Rooms/Commands/DisableRoom/DisableRoomCommand.cs +++ b/src/Application/Rooms/Commands/Disable/Command.cs @@ -5,14 +5,14 @@ using MediatR; using Microsoft.EntityFrameworkCore; -namespace Application.Rooms.Commands.DisableRoom; +namespace Application.Rooms.Commands.Disable; -public record DisableRoomCommand : IRequest +public record Command : IRequest { public Guid RoomId { get; init; } } -public class DisableRoomCommandHandler : IRequestHandler +public class DisableRoomCommandHandler : IRequestHandler { private readonly IApplicationDbContext _context; private readonly IMapper _mapper; @@ -23,7 +23,7 @@ public DisableRoomCommandHandler(IApplicationDbContext context, IMapper mapper) _mapper = mapper; } - public async Task Handle(DisableRoomCommand request, CancellationToken cancellationToken) + public async Task Handle(Command request, CancellationToken cancellationToken) { var room = await _context.Rooms .Include(x => x.Lockers) diff --git a/src/Application/Rooms/Commands/DisableRoom/DisableRoomCommandValidator.cs b/src/Application/Rooms/Commands/Disable/Validator.cs similarity index 51% rename from src/Application/Rooms/Commands/DisableRoom/DisableRoomCommandValidator.cs rename to src/Application/Rooms/Commands/Disable/Validator.cs index de317f88..72c9fa84 100644 --- a/src/Application/Rooms/Commands/DisableRoom/DisableRoomCommandValidator.cs +++ b/src/Application/Rooms/Commands/Disable/Validator.cs @@ -1,10 +1,10 @@ using FluentValidation; -namespace Application.Rooms.Commands.DisableRoom; +namespace Application.Rooms.Commands.Disable; -public class DisableRoomCommandValidator : AbstractValidator +public class Validator : AbstractValidator { - public DisableRoomCommandValidator() + public Validator() { RuleLevelCascadeMode = CascadeMode.Stop; diff --git a/src/Application/Rooms/Queries/GetRoomById/GetRoomByIdQuery.cs b/src/Application/Rooms/Commands/Enable/Command.cs similarity index 51% rename from src/Application/Rooms/Queries/GetRoomById/GetRoomByIdQuery.cs rename to src/Application/Rooms/Commands/Enable/Command.cs index 638e9b51..be029106 100644 --- a/src/Application/Rooms/Queries/GetRoomById/GetRoomByIdQuery.cs +++ b/src/Application/Rooms/Commands/Enable/Command.cs @@ -1,9 +1,9 @@ using Application.Common.Models.Dtos.Physical; using MediatR; -namespace Application.Rooms.Queries.GetRoomById; +namespace Application.Rooms.Commands.Enable; -public record GetRoomByIdQuery : IRequest +public record Command : IRequest { public Guid RoomId { get; init; } } \ No newline at end of file diff --git a/src/Application/Rooms/Commands/RemoveRoom/RemoveRoomCommand.cs b/src/Application/Rooms/Commands/Remove/Command.cs similarity index 81% rename from src/Application/Rooms/Commands/RemoveRoom/RemoveRoomCommand.cs rename to src/Application/Rooms/Commands/Remove/Command.cs index 43e7f575..d980fa60 100644 --- a/src/Application/Rooms/Commands/RemoveRoom/RemoveRoomCommand.cs +++ b/src/Application/Rooms/Commands/Remove/Command.cs @@ -4,14 +4,14 @@ using MediatR; using Microsoft.EntityFrameworkCore; -namespace Application.Rooms.Commands.RemoveRoom; +namespace Application.Rooms.Commands.Remove; -public record RemoveRoomCommand : IRequest +public record Command : IRequest { public Guid RoomId { get; init; } } -public class RemoveRoomCommandHandler : IRequestHandler +public class RemoveRoomCommandHandler : IRequestHandler { private readonly IApplicationDbContext _context; private readonly IMapper _mapper; @@ -22,7 +22,7 @@ public RemoveRoomCommandHandler(IApplicationDbContext context, IMapper mapper) _mapper = mapper; } - public async Task Handle(RemoveRoomCommand request, CancellationToken cancellationToken) + public async Task Handle(Command request, CancellationToken cancellationToken) { var room = await _context.Rooms .FirstOrDefaultAsync(x => x.Id.Equals(request.RoomId), cancellationToken: cancellationToken); diff --git a/src/Application/Rooms/Commands/RemoveRoom/RemoveRoomCommandValidator.cs b/src/Application/Rooms/Commands/Remove/Validator.cs similarity index 52% rename from src/Application/Rooms/Commands/RemoveRoom/RemoveRoomCommandValidator.cs rename to src/Application/Rooms/Commands/Remove/Validator.cs index d138ba88..c9339293 100644 --- a/src/Application/Rooms/Commands/RemoveRoom/RemoveRoomCommandValidator.cs +++ b/src/Application/Rooms/Commands/Remove/Validator.cs @@ -1,10 +1,10 @@ using FluentValidation; -namespace Application.Rooms.Commands.RemoveRoom; +namespace Application.Rooms.Commands.Remove; -public class RemoveRoomCommandValidator : AbstractValidator +public class Validator : AbstractValidator { - public RemoveRoomCommandValidator() + public Validator() { RuleLevelCascadeMode = CascadeMode.Stop; diff --git a/src/Application/Rooms/Commands/UpdateRoom/UpdateRoomCommand.cs b/src/Application/Rooms/Commands/Update/Command.cs similarity index 70% rename from src/Application/Rooms/Commands/UpdateRoom/UpdateRoomCommand.cs rename to src/Application/Rooms/Commands/Update/Command.cs index 2e603d9d..d5a2c8a4 100644 --- a/src/Application/Rooms/Commands/UpdateRoom/UpdateRoomCommand.cs +++ b/src/Application/Rooms/Commands/Update/Command.cs @@ -1,9 +1,9 @@ using Application.Common.Models.Dtos.Physical; using MediatR; -namespace Application.Rooms.Commands.UpdateRoom; +namespace Application.Rooms.Commands.Update; -public record UpdateRoomCommand : IRequest +public record Command : IRequest { public Guid RoomId { get; init; } public string Name { get; set; } = null!; diff --git a/src/Application/Rooms/Queries/GetAllRoomPaginated/GetAllRoomsPaginatedQuery.cs b/src/Application/Rooms/Queries/GetAllPaginated/Query.cs similarity index 66% rename from src/Application/Rooms/Queries/GetAllRoomPaginated/GetAllRoomsPaginatedQuery.cs rename to src/Application/Rooms/Queries/GetAllPaginated/Query.cs index c691570f..4867dbc3 100644 --- a/src/Application/Rooms/Queries/GetAllRoomPaginated/GetAllRoomsPaginatedQuery.cs +++ b/src/Application/Rooms/Queries/GetAllPaginated/Query.cs @@ -2,9 +2,9 @@ using Application.Common.Models.Dtos.Physical; using MediatR; -namespace Application.Rooms.Queries.GetAllRoomPaginated; +namespace Application.Rooms.Queries.GetAllPaginated; -public record GetAllRoomsPaginatedQuery : IRequest> +public record Query : IRequest> { public int? Page { get; init; } public int? Size { get; init; } diff --git a/src/Application/Rooms/Commands/EnableRoom/EnableRoomCommand.cs b/src/Application/Rooms/Queries/GetById/Query.cs similarity index 50% rename from src/Application/Rooms/Commands/EnableRoom/EnableRoomCommand.cs rename to src/Application/Rooms/Queries/GetById/Query.cs index d89c52a5..616e3bc5 100644 --- a/src/Application/Rooms/Commands/EnableRoom/EnableRoomCommand.cs +++ b/src/Application/Rooms/Queries/GetById/Query.cs @@ -1,9 +1,9 @@ using Application.Common.Models.Dtos.Physical; using MediatR; -namespace Application.Rooms.Commands.EnableRoom; +namespace Application.Rooms.Queries.GetById; -public record EnableRoomCommand : IRequest +public record Query : IRequest { public Guid RoomId { get; init; } } \ No newline at end of file diff --git a/src/Application/Rooms/Queries/GetEmptyContainersPaginated/GetEmptyContainersPaginatedQuery.cs b/src/Application/Rooms/Queries/GetEmptyContainersPaginated/Query.cs similarity index 75% rename from src/Application/Rooms/Queries/GetEmptyContainersPaginated/GetEmptyContainersPaginatedQuery.cs rename to src/Application/Rooms/Queries/GetEmptyContainersPaginated/Query.cs index 95be60d7..60ad95b2 100644 --- a/src/Application/Rooms/Queries/GetEmptyContainersPaginated/GetEmptyContainersPaginatedQuery.cs +++ b/src/Application/Rooms/Queries/GetEmptyContainersPaginated/Query.cs @@ -7,24 +7,24 @@ namespace Application.Rooms.Queries.GetEmptyContainersPaginated; -public record GetEmptyContainersPaginatedQuery : IRequest> +public record Query : IRequest> { public Guid RoomId { get; init; } public int? Page { get; init; } public int? Size { get; init; } } -public class GetEmptyContainersPaginatedQueryHandler : IRequestHandler> +public class QueryHandler : IRequestHandler> { private readonly IApplicationDbContext _context; private readonly IMapper _mapper; - public GetEmptyContainersPaginatedQueryHandler(IApplicationDbContext context, IMapper mapper) + public QueryHandler(IApplicationDbContext context, IMapper mapper) { _context = context; _mapper = mapper; } - public async Task> Handle(GetEmptyContainersPaginatedQuery request, CancellationToken cancellationToken) + public async Task> Handle(Query request, CancellationToken cancellationToken) { var room = await _context.Rooms.FirstOrDefaultAsync(x => x.Id == request.RoomId, cancellationToken); if (room is null) diff --git a/src/Application/Staffs/Commands/AddStaff/AddStaffCommand.cs b/src/Application/Staffs/Commands/Add/Command.cs similarity index 74% rename from src/Application/Staffs/Commands/AddStaff/AddStaffCommand.cs rename to src/Application/Staffs/Commands/Add/Command.cs index 409e8cf9..53d90614 100644 --- a/src/Application/Staffs/Commands/AddStaff/AddStaffCommand.cs +++ b/src/Application/Staffs/Commands/Add/Command.cs @@ -1,30 +1,30 @@ using Application.Common.Interfaces; -using Application.Users.Queries.Physical; +using Application.Common.Models.Dtos.Physical; using AutoMapper; using Domain.Entities.Physical; using MediatR; using Microsoft.EntityFrameworkCore; -namespace Application.Staffs.Commands.AddStaff; +namespace Application.Staffs.Commands.Add; -public record AddStaffCommand : IRequest +public record Command : IRequest { public Guid UserId { get; init; } public Guid RoomId { get; init; } } -public class AddStaffCommandHandler : IRequestHandler +public class CommandHandler : IRequestHandler { private readonly IApplicationDbContext _context; private readonly IMapper _mapper; - public AddStaffCommandHandler(IApplicationDbContext context, IMapper mapper) + public CommandHandler(IApplicationDbContext context, IMapper mapper) { _context = context; _mapper = mapper; } - public async Task Handle(AddStaffCommand request, CancellationToken cancellationToken) + public async Task Handle(Command request, CancellationToken cancellationToken) { var user = await _context.Users.FirstOrDefaultAsync(x => x.Id == request.UserId, cancellationToken); if (user is null) diff --git a/src/Application/Staffs/Commands/RemoveFromRoom/Command.cs b/src/Application/Staffs/Commands/RemoveFromRoom/Command.cs new file mode 100644 index 00000000..df64dcf8 --- /dev/null +++ b/src/Application/Staffs/Commands/RemoveFromRoom/Command.cs @@ -0,0 +1,10 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Staffs.Commands.RemoveFromRoom; + +public record Command : IRequest +{ + public Guid StaffId { get; init; } + public Guid RoomId { get; init; } +} \ No newline at end of file diff --git a/src/Application/Staffs/Commands/RemoveStaffFromRoom/RemoveStaffFromRoomCommand.cs b/src/Application/Staffs/Commands/RemoveStaffFromRoom/RemoveStaffFromRoomCommand.cs deleted file mode 100644 index c25f18ca..00000000 --- a/src/Application/Staffs/Commands/RemoveStaffFromRoom/RemoveStaffFromRoomCommand.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Application.Users.Queries.Physical; -using MediatR; - -namespace Application.Staffs.Commands.RemoveStaffFromRoom; - -public record RemoveStaffFromRoomCommand : IRequest -{ - public Guid StaffId { get; init; } - public Guid RoomId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Staffs/Queries/GetAllStaffsPaginated/GetAllStaffsPaginatedQuery.cs b/src/Application/Staffs/Queries/GetAllPaginated/Query.cs similarity index 58% rename from src/Application/Staffs/Queries/GetAllStaffsPaginated/GetAllStaffsPaginatedQuery.cs rename to src/Application/Staffs/Queries/GetAllPaginated/Query.cs index a640b907..b3911b3d 100644 --- a/src/Application/Staffs/Queries/GetAllStaffsPaginated/GetAllStaffsPaginatedQuery.cs +++ b/src/Application/Staffs/Queries/GetAllPaginated/Query.cs @@ -1,10 +1,10 @@ using Application.Common.Models; -using Application.Users.Queries.Physical; +using Application.Common.Models.Dtos.Physical; using MediatR; -namespace Application.Staffs.Queries.GetAllStaffsPaginated; +namespace Application.Staffs.Queries.GetAllPaginated; -public class GetAllStaffsPaginatedQuery : IRequest> +public class Query : IRequest> { public string? SearchTerm { get; set; } public int? Page { get; set; } diff --git a/src/Application/Staffs/Queries/GetById/Query.cs b/src/Application/Staffs/Queries/GetById/Query.cs new file mode 100644 index 00000000..432aea43 --- /dev/null +++ b/src/Application/Staffs/Queries/GetById/Query.cs @@ -0,0 +1,9 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Staffs.Queries.GetById; + +public record Query : IRequest +{ + public Guid StaffId { get; init; } +} \ No newline at end of file diff --git a/src/Application/Staffs/Queries/GetByRoom/Query.cs b/src/Application/Staffs/Queries/GetByRoom/Query.cs new file mode 100644 index 00000000..4bdd850a --- /dev/null +++ b/src/Application/Staffs/Queries/GetByRoom/Query.cs @@ -0,0 +1,9 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Staffs.Queries.GetByRoom; + +public record Query : IRequest +{ + public Guid RoomId { get; init; } +} \ No newline at end of file diff --git a/src/Application/Staffs/Queries/GetStaffById/GetStaffByIdQuery.cs b/src/Application/Staffs/Queries/GetStaffById/GetStaffByIdQuery.cs deleted file mode 100644 index 7efed7f2..00000000 --- a/src/Application/Staffs/Queries/GetStaffById/GetStaffByIdQuery.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Application.Users.Queries.Physical; -using MediatR; - -namespace Application.Staffs.Queries.GetStaffById; - -public record GetStaffByIdQuery : IRequest -{ - public Guid StaffId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Staffs/Queries/GetStaffByRoom/GetStaffByRoomQuery.cs b/src/Application/Staffs/Queries/GetStaffByRoom/GetStaffByRoomQuery.cs deleted file mode 100644 index 0d3d8a1f..00000000 --- a/src/Application/Staffs/Queries/GetStaffByRoom/GetStaffByRoomQuery.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Application.Users.Queries.Physical; -using MediatR; - -namespace Application.Staffs.Queries.GetStaffByRoom; - -public record GetStaffByRoomQuery : IRequest -{ - public Guid RoomId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Users/Commands/AddUser/AddUserCommand.cs b/src/Application/Users/Commands/Add/Command.cs similarity index 89% rename from src/Application/Users/Commands/AddUser/AddUserCommand.cs rename to src/Application/Users/Commands/Add/Command.cs index 5f5f684c..c5089184 100644 --- a/src/Application/Users/Commands/AddUser/AddUserCommand.cs +++ b/src/Application/Users/Commands/Add/Command.cs @@ -9,9 +9,9 @@ using Microsoft.EntityFrameworkCore; using NodaTime; -namespace Application.Users.Commands.AddUser; +namespace Application.Users.Commands.Add; -public record AddUserCommand : IRequest +public record Command : IRequest { public string Username { get; init; } = null!; public string Email { get; init; } = null!; @@ -23,7 +23,7 @@ public record AddUserCommand : IRequest public string? Position { get; init; } } -public class AddUserCommandHandler : IRequestHandler +public class AddUserCommandHandler : IRequestHandler { private readonly IApplicationDbContext _context; private readonly IMapper _mapper; @@ -32,7 +32,7 @@ public AddUserCommandHandler(IApplicationDbContext context, IMapper mapper) _context = context; _mapper = mapper; } - public async Task Handle(AddUserCommand request, CancellationToken cancellationToken) + public async Task Handle(Command request, CancellationToken cancellationToken) { var user = await _context.Users.FirstOrDefaultAsync( x => x.Username.Equals(request.Username) || x.Email.Equals(request.Email), cancellationToken); diff --git a/src/Application/Users/Commands/AddUser/AddUserCommandValidator.cs b/src/Application/Users/Commands/Add/Validator.cs similarity index 89% rename from src/Application/Users/Commands/AddUser/AddUserCommandValidator.cs rename to src/Application/Users/Commands/Add/Validator.cs index 16d07c05..2eb3a1d0 100644 --- a/src/Application/Users/Commands/AddUser/AddUserCommandValidator.cs +++ b/src/Application/Users/Commands/Add/Validator.cs @@ -1,11 +1,11 @@ using Application.Identity; using FluentValidation; -namespace Application.Users.Commands.AddUser; +namespace Application.Users.Commands.Add; -public class AddUserCommandValidator : AbstractValidator +public class Validator : AbstractValidator { - public AddUserCommandValidator() + public Validator() { RuleLevelCascadeMode = CascadeMode.Stop; diff --git a/src/Application/Users/Commands/DisableUser/DisableUserCommand.cs b/src/Application/Users/Commands/Disable/Command.cs similarity index 71% rename from src/Application/Users/Commands/DisableUser/DisableUserCommand.cs rename to src/Application/Users/Commands/Disable/Command.cs index 43abac74..78f028cd 100644 --- a/src/Application/Users/Commands/DisableUser/DisableUserCommand.cs +++ b/src/Application/Users/Commands/Disable/Command.cs @@ -5,24 +5,24 @@ using MediatR; using Microsoft.EntityFrameworkCore; -namespace Application.Users.Commands.DisableUser; +namespace Application.Users.Commands.Disable; -public record DisableUserCommand : IRequest +public record Command : IRequest { public Guid UserId { get; init; } } -public class DisableUserCommandHandler : IRequestHandler +public class CommandHandler : IRequestHandler { private readonly IApplicationDbContext _context; private readonly IMapper _mapper; - public DisableUserCommandHandler(IApplicationDbContext context, IMapper mapper) + public CommandHandler(IApplicationDbContext context, IMapper mapper) { _context = context; _mapper = mapper; } - public async Task Handle(DisableUserCommand request, CancellationToken cancellationToken) + public async Task Handle(Command request, CancellationToken cancellationToken) { var user = await _context.Users.FirstOrDefaultAsync(x => x.Id == request.UserId, cancellationToken); if (user is null) diff --git a/src/Application/Users/Commands/Enable/Command.cs b/src/Application/Users/Commands/Enable/Command.cs new file mode 100644 index 00000000..b44eb202 --- /dev/null +++ b/src/Application/Users/Commands/Enable/Command.cs @@ -0,0 +1,9 @@ +using Application.Users.Queries; +using MediatR; + +namespace Application.Users.Commands.Enable; + +public record Command : IRequest +{ + public Guid UserId { get; init; } +} \ No newline at end of file diff --git a/src/Application/Users/Commands/EnableUser/EnableUserCommand.cs b/src/Application/Users/Commands/EnableUser/EnableUserCommand.cs deleted file mode 100644 index 047f13d5..00000000 --- a/src/Application/Users/Commands/EnableUser/EnableUserCommand.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Application.Users.Queries; -using MediatR; - -namespace Application.Users.Commands.EnableUser; - -public record EnableUserCommand : IRequest -{ - public Guid UserId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Users/Commands/UpdateUser/UpdateUserCommand.cs b/src/Application/Users/Commands/Update/Command.cs similarity index 78% rename from src/Application/Users/Commands/UpdateUser/UpdateUserCommand.cs rename to src/Application/Users/Commands/Update/Command.cs index 0f3736ea..44de6990 100644 --- a/src/Application/Users/Commands/UpdateUser/UpdateUserCommand.cs +++ b/src/Application/Users/Commands/Update/Command.cs @@ -1,9 +1,9 @@ using Application.Users.Queries; using MediatR; -namespace Application.Users.Commands.UpdateUser; +namespace Application.Users.Commands.Update; -public record UpdateUserCommand : IRequest +public record Command : IRequest { public Guid UserId { get; init; } public string Username { get; init; } = null!; diff --git a/src/Application/Users/Queries/GetAllUsersPaginated/GetAllUsersPaginatedQuery.cs b/src/Application/Users/Queries/GetAllPaginated/Query.cs similarity index 69% rename from src/Application/Users/Queries/GetAllUsersPaginated/GetAllUsersPaginatedQuery.cs rename to src/Application/Users/Queries/GetAllPaginated/Query.cs index 0c3146c7..a09e16f9 100644 --- a/src/Application/Users/Queries/GetAllUsersPaginated/GetAllUsersPaginatedQuery.cs +++ b/src/Application/Users/Queries/GetAllPaginated/Query.cs @@ -1,9 +1,9 @@ using Application.Common.Models; using MediatR; -namespace Application.Users.Queries.GetAllUsersPaginated; +namespace Application.Users.Queries.GetAllPaginated; -public record GetAllUsersPaginatedQuery : IRequest> +public record Query : IRequest> { public Guid? DepartmentId { get; init; } public string? SearchTerm { get; init; } diff --git a/src/Application/Users/Queries/GetById/Query.cs b/src/Application/Users/Queries/GetById/Query.cs new file mode 100644 index 00000000..4b42b38f --- /dev/null +++ b/src/Application/Users/Queries/GetById/Query.cs @@ -0,0 +1,8 @@ +using MediatR; + +namespace Application.Users.Queries.GetById; + +public record Query : IRequest +{ + public Guid UserId { get; init; } +} \ No newline at end of file diff --git a/src/Application/Users/Queries/GetUserById/GetUserByIdQuery.cs b/src/Application/Users/Queries/GetUserById/GetUserByIdQuery.cs deleted file mode 100644 index 9f2e60d7..00000000 --- a/src/Application/Users/Queries/GetUserById/GetUserByIdQuery.cs +++ /dev/null @@ -1,8 +0,0 @@ -using MediatR; - -namespace Application.Users.Queries.GetUserById; - -public record GetUserByIdQuery : IRequest -{ - public Guid UserId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Users/Queries/GetUsersByName/GetUsersByNameQuery.cs b/src/Application/Users/Queries/GetUsersByName/GetUsersByNameQuery.cs deleted file mode 100644 index 76604efb..00000000 --- a/src/Application/Users/Queries/GetUsersByName/GetUsersByNameQuery.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Application.Common.Interfaces; -using Application.Common.Mappings; -using Application.Common.Models; -using AutoMapper; -using AutoMapper.QueryableExtensions; -using MediatR; - -namespace Application.Users.Queries.GetUsersByName; - -public record GetUsersByNameQuery : IRequest> -{ - public string? SearchTerm { get; init; } - public int? Page { get; init; } - public int? Size { get; init; } -} - -public class GetUsersByNameQueryHandler : IRequestHandler> -{ - private readonly IApplicationDbContext _context; - private readonly IMapper _mapper; - public GetUsersByNameQueryHandler(IApplicationDbContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - - public async Task> Handle(GetUsersByNameQuery request, CancellationToken cancellationToken) - { - var pageNumber = request.Page ?? 1; - var sizeNumber = request.Size ?? 5; - var users = await _context.Users - .Where(x => string.IsNullOrEmpty(request.SearchTerm) - || x.FirstName.ToLower().Contains(request.SearchTerm.ToLower()) - || x.LastName.ToLower().Contains(request.SearchTerm.ToLower())) - .ProjectTo(_mapper.ConfigurationProvider) - .OrderBy(x => x.Username) - .PaginatedListAsync(pageNumber, sizeNumber); - return users; - } -} \ No newline at end of file diff --git a/src/Infrastructure/Infrastructure.csproj b/src/Infrastructure/Infrastructure.csproj index 911a81f6..8537748f 100644 --- a/src/Infrastructure/Infrastructure.csproj +++ b/src/Infrastructure/Infrastructure.csproj @@ -21,8 +21,4 @@ - - - - diff --git a/tests/Application.Tests.Integration/BaseClassFixture.cs b/tests/Application.Tests.Integration/BaseClassFixture.cs index 7e0d22c0..6633884f 100644 --- a/tests/Application.Tests.Integration/BaseClassFixture.cs +++ b/tests/Application.Tests.Integration/BaseClassFixture.cs @@ -1,4 +1,4 @@ -using Application.Departments.Commands.AddDepartment; +using Application.Departments.Commands.Add; using Bogus; using Domain.Common; using Domain.Entities; @@ -15,7 +15,7 @@ namespace Application.Tests.Integration; [Collection(nameof(BaseCollectionFixture))] public class BaseClassFixture { - protected readonly Faker _departmentGenerator = new Faker() + protected readonly Faker _departmentGenerator = new Faker() .RuleFor(x => x.Name, faker => faker.Commerce.Department()); protected static IServiceScopeFactory _scopeFactory = null!; diff --git a/tests/Application.Tests.Integration/CustomApiFactory.cs b/tests/Application.Tests.Integration/CustomApiFactory.cs index 9d30c073..5d14c8ec 100644 --- a/tests/Application.Tests.Integration/CustomApiFactory.cs +++ b/tests/Application.Tests.Integration/CustomApiFactory.cs @@ -28,7 +28,7 @@ protected override void ConfigureWebHost(IWebHostBuilder builder) var databaseSettings = GetConfiguration().GetSection(nameof(DatabaseSettings)).Get(); services.AddDbContext(options => { - options.UseNpgsql(databaseSettings?.ConnectionString, optionsBuilder => optionsBuilder.UseNodaTime()); + options.UseNpgsql("Server=localhost;Port=5432;Database=mytestdb;User ID=profiletester;Password=supasupasecured;", optionsBuilder => optionsBuilder.UseNodaTime()); }); }); } diff --git a/tests/Application.Tests.Integration/Departments/Commands/AddDepartmentTests.cs b/tests/Application.Tests.Integration/Departments/Commands/AddDepartmentTests.cs index 8823a9fb..0e9ebf10 100644 --- a/tests/Application.Tests.Integration/Departments/Commands/AddDepartmentTests.cs +++ b/tests/Application.Tests.Integration/Departments/Commands/AddDepartmentTests.cs @@ -1,5 +1,4 @@ using Application.Common.Exceptions; -using Application.Departments.Commands.DeleteDepartment; using Domain.Entities; using FluentAssertions; using Xunit; diff --git a/tests/Application.Tests.Integration/Departments/Queries/GetAllDepartmentsTests.cs b/tests/Application.Tests.Integration/Departments/Queries/GetAllDepartmentsTests.cs index 6bd82481..d6e6c864 100644 --- a/tests/Application.Tests.Integration/Departments/Queries/GetAllDepartmentsTests.cs +++ b/tests/Application.Tests.Integration/Departments/Queries/GetAllDepartmentsTests.cs @@ -1,5 +1,5 @@ using Application.Common.Mappings; -using Application.Departments.Queries.GetAllDepartments; +using Application.Departments.Queries.GetAll; using Application.Identity; using Application.Users.Queries; using AutoMapper; @@ -30,7 +30,7 @@ public async Task ShouldReturnDepartments_WhenDepartmentsExist() Name = new Faker().Commerce.Department() }; await AddAsync(department); - var query = new GetAllDepartmentsQuery(); + var query = new Query(); // Act var result = await SendAsync(query); @@ -46,7 +46,7 @@ public async Task ShouldReturnDepartments_WhenDepartmentsExist() public async Task ShouldReturnEmptyList_WhenNoDepartmentsExist() { // Arrange - var query = new GetAllDepartmentsQuery(); + var query = new Query(); // Act var result = await SendAsync(query); diff --git a/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentTypesTests.cs b/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentTypesTests.cs index bf83e5f5..6e12eb56 100644 --- a/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentTypesTests.cs +++ b/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentTypesTests.cs @@ -23,7 +23,7 @@ public async Task ShouldReturnDocumentTypes_WhenDocumentTypesExist() DocumentType = new Faker().Commerce.ProductName(), }; await AddAsync(document); - var query = new GetAllDocumentTypesQuery(); + var query = new Query(); // Act var result = await SendAsync(query); @@ -39,7 +39,7 @@ public async Task ShouldReturnDocumentTypes_WhenDocumentTypesExist() public async Task ShouldReturnEmptyList_WhenNoDocumentTypesExist() { // Arrange - var query = new GetAllDocumentTypesQuery(); + var query = new Query(); // Act var result = await SendAsync(query); diff --git a/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentsPaginatedTests.cs b/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentsPaginatedTests.cs index b051e093..504e2db3 100644 --- a/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentsPaginatedTests.cs +++ b/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentsPaginatedTests.cs @@ -2,7 +2,7 @@ using Application.Common.Extensions; using Application.Common.Mappings; using Application.Common.Models.Dtos.Physical; - using Application.Documents.Queries.GetAllDocumentsPaginated; + using Application.Documents.Queries.GetAllPaginated; using AutoMapper; using Bogus; using Domain.Entities.Physical; @@ -31,7 +31,7 @@ public async Task ShouldReturnAllDocuments_WhenNoContainersAreDefined() var room = CreateRoom(locker); await AddAsync(room); - var query = new GetAllDocumentsPaginatedQuery(); + var query = new Query(); // Act var result = await SendAsync(query); @@ -54,7 +54,7 @@ public async Task ShouldReturnEmptyPaginatedList_WhenNoDocumentsExist() await AddAsync(room); - var query = new GetAllDocumentsPaginatedQuery() + var query = new Query() { RoomId = room.Id }; @@ -92,7 +92,7 @@ public async Task ShouldReturnDocumentsOfRoom_WhenOnlyRoomIdIsPresent() await AddAsync(room1); await AddAsync(room2); - var query = new GetAllDocumentsPaginatedQuery() + var query = new Query() { RoomId = room1.Id }; @@ -123,7 +123,7 @@ public async Task ShouldReturnDocumentsOfRoom_WhenOnlyRoomIdIsPresent() public async Task ShouldThrowKeyNotFoundException_WhenOnlyRoomIdIsPresentButDoesNotExist() { // Arrange - var query = new GetAllDocumentsPaginatedQuery() + var query = new Query() { RoomId = Guid.NewGuid() }; @@ -155,7 +155,7 @@ public async Task ShouldReturnDocumentsOfLocker_WhenOnlyRoomIdAndLockerIdArePres await AddAsync(room); - var query = new GetAllDocumentsPaginatedQuery() + var query = new Query() { RoomId = room.Id, LockerId = locker1.Id @@ -187,7 +187,7 @@ public async Task ShouldThrowKeyNotFoundException_WhenOnlyRoomIdAndLockerIdArePr var room = CreateRoom(); await AddAsync(room); - var query = new GetAllDocumentsPaginatedQuery() + var query = new Query() { RoomId = room.Id, LockerId = Guid.NewGuid() @@ -216,7 +216,7 @@ public async Task ShouldThrowConflictException_WhenOnlyRoomIdAndLockerIdArePrese await AddAsync(room1); await AddAsync(room2); - var query = new GetAllDocumentsPaginatedQuery() + var query = new Query() { RoomId = room1.Id, LockerId = locker.Id @@ -248,7 +248,7 @@ public async Task ShouldReturnDocumentsOfFolder_WhenAllIdsArePresentAndFolderIsI var room = CreateRoom(locker); await AddAsync(room); - var query = new GetAllDocumentsPaginatedQuery() + var query = new Query() { RoomId = room.Id, LockerId = locker.Id, @@ -282,7 +282,7 @@ public async Task ShouldThrowKeyNotFoundException_WhenAllIdsArePresentAndValidAn await AddAsync(room); - var query = new GetAllDocumentsPaginatedQuery() + var query = new Query() { RoomId = room.Id, LockerId = locker.Id, @@ -315,14 +315,14 @@ public async Task ShouldThrowConflictException_WhenAllIdsArePresentAndFolderIsNo await AddAsync(room1); await AddAsync(room2); - var query1 = new GetAllDocumentsPaginatedQuery() + var query1 = new Query() { RoomId = room1.Id, LockerId = locker2.Id, FolderId = folder1.Id }; - var query2 = new GetAllDocumentsPaginatedQuery() + var query2 = new Query() { RoomId = room1.Id, LockerId = locker2.Id, @@ -357,7 +357,7 @@ public async Task ShouldReturnSortedByIdPaginatedList_WhenSortByIsNotPresent() await AddAsync(room); - var query = new GetAllDocumentsPaginatedQuery() + var query = new Query() { RoomId = room.Id }; @@ -395,7 +395,7 @@ public async Task ShouldReturnSortedByPropertyPaginatedList_WhenSortByIsPresent( await AddAsync(room); - var query = new GetAllDocumentsPaginatedQuery() + var query = new Query() { RoomId = room.Id, SortBy = sortBy, diff --git a/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs b/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs index 8832e0c3..787d92ee 100644 --- a/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs +++ b/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs @@ -1,29 +1,30 @@ using Application.Common.Exceptions; using Application.Common.Models.Dtos.Physical; -using Application.Folders.Commands.AddFolder; -using Application.Lockers.Commands.AddLocker; -using Application.Rooms.Commands.AddRoom; +using Application.Folders.Commands.Add; +using Application.Lockers.Commands.Add; +using Application.Rooms.Commands.Add; using Bogus; using Domain.Entities.Physical; using Domain.Exceptions; using FluentAssertions; using Xunit; +using Command = Application.Lockers.Commands.Add.Command; namespace Application.Tests.Integration.Folders.Commands; public class AddFolderTests : BaseClassFixture { - private readonly Faker _folderGenerator = new Faker() + private readonly Faker _folderGenerator = new Faker() .RuleFor(f => f.Name, faker => faker.Commerce.ProductName()) .RuleFor(f => f.Description, faker => faker.Commerce.ProductDescription()) .RuleFor(f => f.Capacity, faker => faker.Random.Int(1,9999)); - private readonly Faker _roomGenerator = new Faker() + private readonly Faker _roomGenerator = new Faker() .RuleFor(r => r.Name, faker => faker.Commerce.ProductName()) .RuleFor(r => r.Description, faker => faker.Commerce.ProductDescription()) .RuleFor(r => r.Capacity, faker => faker.Random.Int(1,9999)); - private readonly Faker _lockerGenerator = new Faker() + private readonly Faker _lockerGenerator = new Faker() .RuleFor(l => l.Name, faker => faker.Commerce.ProductName()) .RuleFor(l => l.Description, faker => faker.Commerce.ProductDescription()) .RuleFor(l => l.Capacity, faker => faker.Random.Int(1,9999)); diff --git a/tests/Application.Tests.Integration/Folders/Commands/DisableFolderTests.cs b/tests/Application.Tests.Integration/Folders/Commands/DisableFolderTests.cs index 1dee5f9d..e3ee20b8 100644 --- a/tests/Application.Tests.Integration/Folders/Commands/DisableFolderTests.cs +++ b/tests/Application.Tests.Integration/Folders/Commands/DisableFolderTests.cs @@ -1,5 +1,5 @@ using Application.Common.Exceptions; -using Application.Folders.Commands.DisableFolder; +using Application.Folders.Commands.Disable; using Domain.Entities.Physical; using FluentAssertions; using Xunit; @@ -46,7 +46,7 @@ public async Task ShouldDisableFolder_WhenFolderHaveNoDocument() }; await AddAsync(folder); - var disableFolderCommand = new DisableFolderCommand() + var disableFolderCommand = new Command() { FolderId = folder.Id }; @@ -67,7 +67,7 @@ public async Task ShouldDisableFolder_WhenFolderHaveNoDocument() public async Task ShouldThrowKeyNotFoundException_WhenFolderDoesNotExist() { // Arrange - var disableFolderCommand = new DisableFolderCommand() + var disableFolderCommand = new Command() { FolderId = Guid.NewGuid() }; @@ -113,7 +113,7 @@ public async Task ShouldThrowInvalidOperationException_WhenFolderIsAlreadyDisabl Locker = locker }; await AddAsync(folder); - var disableFolderCommand = new DisableFolderCommand() + var disableFolderCommand = new Command() { FolderId = folder.Id }; @@ -173,7 +173,7 @@ public async Task ShouldThrowInvalidOperationException_WhenFolderHasDocuments() }; await AddAsync(document); - var disableFolderCommand = new DisableFolderCommand() + var disableFolderCommand = new Command() { FolderId = folder.Id }; diff --git a/tests/Application.Tests.Integration/Lockers/Commands/AddLockerTests.cs b/tests/Application.Tests.Integration/Lockers/Commands/AddLockerTests.cs index 8f3d30e0..138c0ec2 100644 --- a/tests/Application.Tests.Integration/Lockers/Commands/AddLockerTests.cs +++ b/tests/Application.Tests.Integration/Lockers/Commands/AddLockerTests.cs @@ -1,5 +1,5 @@ using Application.Common.Exceptions; -using Application.Lockers.Commands.AddLocker; +using Application.Lockers.Commands.Add; using Bogus; using Domain.Entities.Physical; using Domain.Exceptions; @@ -33,7 +33,7 @@ public async Task ShouldReturnLocker_WhenCreateDetailsAreValid() await AddAsync(room); - var addLockerCommand = new AddLockerCommand() + var addLockerCommand = new Command() { Name = new Faker().Name.JobTitle(), Description = new Faker().Lorem.Sentence(), @@ -77,7 +77,7 @@ public async Task ShouldThrowConflictException_WhenLockerAlreadyExistsInTheSameR await AddAsync(room); - var addLockerCommand = new AddLockerCommand() + var addLockerCommand = new Command() { Name = new Faker().Name.JobTitle(), Description = new Faker().Lorem.Sentence(), @@ -126,7 +126,7 @@ public async Task ShouldReturnLocker_WhenLockersHasSameNameButInDifferentRooms() await AddAsync(room2); - var addLockerCommand = new AddLockerCommand() + var addLockerCommand = new Command() { Name = new Faker().Name.JobTitle(), Description = new Faker().Lorem.Sentence(), @@ -134,7 +134,7 @@ public async Task ShouldReturnLocker_WhenLockersHasSameNameButInDifferentRooms() RoomId = room1.Id, }; - var addLockerCommand2 = new AddLockerCommand() + var addLockerCommand2 = new Command() { Name = addLockerCommand.Name, Description = new Faker().Lorem.Sentence(), @@ -181,7 +181,7 @@ public async Task ShouldThrowLimitExceededException_WhenGoingOverCapacity() await AddAsync(room); - var addLockerCommand = new AddLockerCommand() + var addLockerCommand = new Command() { Name = new Faker().Name.JobTitle(), Description = new Faker().Lorem.Sentence(), @@ -189,7 +189,7 @@ public async Task ShouldThrowLimitExceededException_WhenGoingOverCapacity() RoomId = room.Id, }; - var addLockerCommand2 = new AddLockerCommand() + var addLockerCommand2 = new Command() { Name = new Faker().Name.JobTitle(), Description = new Faker().Lorem.Sentence(), diff --git a/tests/Application.Tests.Integration/Lockers/Commands/DisableLockerTests.cs b/tests/Application.Tests.Integration/Lockers/Commands/DisableLockerTests.cs index 28538e7b..0ccc1d0a 100644 --- a/tests/Application.Tests.Integration/Lockers/Commands/DisableLockerTests.cs +++ b/tests/Application.Tests.Integration/Lockers/Commands/DisableLockerTests.cs @@ -1,10 +1,11 @@ using Application.Common.Exceptions; -using Application.Lockers.Commands.AddLocker; -using Application.Lockers.Commands.DisableLocker; +using Application.Lockers.Commands.Add; +using Application.Lockers.Commands.Disable; using Bogus; using Domain.Entities.Physical; using FluentAssertions; using Xunit; +using Command = Application.Lockers.Commands.Disable.Command; namespace Application.Tests.Integration.Lockers.Commands; @@ -31,7 +32,7 @@ public async Task ShouldDisableLocker_WhenLockerExistsAndIsAvailable() await AddAsync(room); - var createLockerCommand = new AddLockerCommand() + var createLockerCommand = new Application.Lockers.Commands.Add.Command() { Name = new Faker().Commerce.ProductName(), Description = new Faker().Lorem.Sentence(), @@ -42,7 +43,7 @@ public async Task ShouldDisableLocker_WhenLockerExistsAndIsAvailable() var locker = await SendAsync(createLockerCommand); room.NumberOfLockers += 1; - var disableLockerCommand = new DisableLockerCommand() + var disableLockerCommand = new Command() { LockerId = locker.Id, }; @@ -66,7 +67,7 @@ public async Task ShouldDisableLocker_WhenLockerExistsAndIsAvailable() public async Task ShouldThrowKeyNotFoundException_WhenLockerDoesNotExist() { // Arrange - var disableLockerCommand = new DisableLockerCommand() + var disableLockerCommand = new Command() { LockerId = Guid.NewGuid(), }; @@ -96,7 +97,7 @@ public async Task ShouldThrowConflictException_WhenLockerIsAlreadyDisabled() await AddAsync(room); - var createLockerCommand = new AddLockerCommand() + var createLockerCommand = new Application.Lockers.Commands.Add.Command() { Name = new Faker().Commerce.ProductName(), Description = new Faker().Lorem.Sentence(), @@ -105,7 +106,7 @@ public async Task ShouldThrowConflictException_WhenLockerIsAlreadyDisabled() }; var locker = await SendAsync(createLockerCommand); - var disableLockerCommand = new DisableLockerCommand() + var disableLockerCommand = new Command() { LockerId = locker.Id, }; diff --git a/tests/Application.Tests.Integration/Lockers/Commands/EnableLockerTests.cs b/tests/Application.Tests.Integration/Lockers/Commands/EnableLockerTests.cs index 7f3a9dbb..afceb135 100644 --- a/tests/Application.Tests.Integration/Lockers/Commands/EnableLockerTests.cs +++ b/tests/Application.Tests.Integration/Lockers/Commands/EnableLockerTests.cs @@ -1,12 +1,13 @@ using Application.Common.Exceptions; -using Application.Lockers.Commands.AddLocker; -using Application.Lockers.Commands.DisableLocker; -using Application.Lockers.Commands.EnableLocker; +using Application.Lockers.Commands.Add; +using Application.Lockers.Commands.Disable; +using Application.Lockers.Commands.Enable; using Bogus; using Domain.Entities.Physical; using Domain.Exceptions; using FluentAssertions; using Xunit; +using Command = Application.Lockers.Commands.Disable.Command; namespace Application.Tests.Integration.Lockers.Commands; @@ -33,7 +34,7 @@ public async Task ShouldEnableLocker_WhenLockerExistsAndIsNotAvailable() await AddAsync(room); - var createLockerCommand = new AddLockerCommand() + var createLockerCommand = new Application.Lockers.Commands.Add.Command() { Name = new Faker().Commerce.ProductName(), Description = new Faker().Lorem.Sentence(), @@ -43,7 +44,7 @@ public async Task ShouldEnableLocker_WhenLockerExistsAndIsNotAvailable() var locker = await SendAsync(createLockerCommand); - var disableLockerCommand = new DisableLockerCommand() + var disableLockerCommand = new Command() { LockerId = locker.Id, }; @@ -52,7 +53,7 @@ public async Task ShouldEnableLocker_WhenLockerExistsAndIsNotAvailable() // Act - var enableLockerCommand = new EnableLockerCommand() + var enableLockerCommand = new Application.Lockers.Commands.Enable.Command() { LockerId = locker.Id, }; @@ -71,7 +72,7 @@ public async Task ShouldEnableLocker_WhenLockerExistsAndIsNotAvailable() public async Task ShouldThrowKeyNotFoundException_WhenLockerDoesNotExist() { // Arrange - var enableLockerCommand = new EnableLockerCommand() + var enableLockerCommand = new Application.Lockers.Commands.Enable.Command() { LockerId = Guid.NewGuid(), }; @@ -101,7 +102,7 @@ public async Task ShouldThrowConflictException_WhenLockerIsAlreadyEnabled() await AddAsync(room); - var createLockerCommand = new AddLockerCommand() + var createLockerCommand = new Application.Lockers.Commands.Add.Command() { Name = new Faker().Commerce.ProductName(), Description = new Faker().Lorem.Sentence(), @@ -110,7 +111,7 @@ public async Task ShouldThrowConflictException_WhenLockerIsAlreadyEnabled() }; var locker = await SendAsync(createLockerCommand); - var enableLockerCommand = new EnableLockerCommand() + var enableLockerCommand = new Application.Lockers.Commands.Enable.Command() { LockerId = locker.Id, }; diff --git a/tests/Application.Tests.Integration/Rooms/Commands/DisableRoomTests.cs b/tests/Application.Tests.Integration/Rooms/Commands/DisableRoomTests.cs index 9fefabc4..18576bd1 100644 --- a/tests/Application.Tests.Integration/Rooms/Commands/DisableRoomTests.cs +++ b/tests/Application.Tests.Integration/Rooms/Commands/DisableRoomTests.cs @@ -1,7 +1,6 @@ using Application.Common.Exceptions; using Application.Helpers; -using Application.Lockers.Commands.AddLocker; -using Application.Rooms.Commands.DisableRoom; +using Application.Rooms.Commands.Disable; using Bogus; using Domain.Entities; using Domain.Entities.Physical; @@ -26,7 +25,7 @@ public async Task ShouldDisableRoom_WhenRoomHaveNoDocument() var room = CreateRoom(locker); await AddAsync(room); - var disableRoomCommand = new DisableRoomCommand() + var disableRoomCommand = new Command() { RoomId = room.Id }; @@ -52,7 +51,7 @@ public async Task ShouldDisableRoom_WhenRoomHaveNoDocument() public async Task ShouldThrowKeyNotFoundException_WhenRoomDoesNotExist() { // Arrange - var disableRoomCommand = new DisableRoomCommand() + var disableRoomCommand = new Command() { RoomId = Guid.NewGuid() }; @@ -76,7 +75,7 @@ public async Task ShouldThrowInvalidOperationException_WhenRoomIsNotEmptyOfDocum await AddAsync(room); - var disableRoomCommand = new DisableRoomCommand() + var disableRoomCommand = new Command() { RoomId = room.Id }; @@ -103,7 +102,7 @@ public async Task ShouldThrowInvalidOperationException_WhenRoomIsNotAvailable() room.IsAvailable = false; await AddAsync(room); - var command = new DisableRoomCommand() + var command = new Command() { RoomId = room.Id }; diff --git a/tests/Application.Tests.Integration/Rooms/Commands/RemoveRoomTests.cs b/tests/Application.Tests.Integration/Rooms/Commands/RemoveRoomTests.cs index 70954ce7..26c8e857 100644 --- a/tests/Application.Tests.Integration/Rooms/Commands/RemoveRoomTests.cs +++ b/tests/Application.Tests.Integration/Rooms/Commands/RemoveRoomTests.cs @@ -1,4 +1,4 @@ -using Application.Rooms.Commands.RemoveRoom; +using Application.Rooms.Commands.Remove; using Bogus; using Domain.Entities.Physical; using FluentAssertions; @@ -19,7 +19,7 @@ public async Task ShouldRemoveRoom_WhenRoomHasNoDocuments() var room = CreateRoom(); await Add(room); - var command = new RemoveRoomCommand() + var command = new Command() { RoomId = room.Id }; @@ -42,7 +42,7 @@ public async Task ShouldThrowInvalidOperationException_WhenRoomHaveDocuments() var room = CreateRoom(locker); await AddAsync(room); - var command = new RemoveRoomCommand() + var command = new Command() { RoomId = room.Id }; @@ -65,7 +65,7 @@ await action.Should().ThrowAsync() public async Task ShouldThrowKeyNotFoundException_WhenRoomDoesNotExist() { // Arrange - var command = new RemoveRoomCommand() + var command = new Command() { RoomId = Guid.NewGuid() }; diff --git a/tests/Application.Tests.Integration/Rooms/Queries/GetEmptyContainersPaginatedTests.cs b/tests/Application.Tests.Integration/Rooms/Queries/GetEmptyContainersPaginatedTests.cs index c0c001b1..7fa1ebb3 100644 --- a/tests/Application.Tests.Integration/Rooms/Queries/GetEmptyContainersPaginatedTests.cs +++ b/tests/Application.Tests.Integration/Rooms/Queries/GetEmptyContainersPaginatedTests.cs @@ -1,4 +1,3 @@ -using Application.Lockers.Commands.AddLocker; using Application.Rooms.Queries.GetEmptyContainersPaginated; using Bogus; using Domain.Entities.Physical; @@ -21,7 +20,7 @@ public async Task ShouldReturnLockersWithEmptyFolders() { // Arrange var room = await SetupTestEntities(); - var query = new GetEmptyContainersPaginatedQuery() + var query = new Query() { Page = 1, Size = 2, @@ -52,7 +51,7 @@ public async Task ShouldReturnLockersWithEmptyFolders() public async Task ShouldThrowNotFound_WhenRoomDoesNotExist() { // Arrange - var query = new GetEmptyContainersPaginatedQuery() + var query = new Query() { Page = 1, Size = 2, diff --git a/tests/Application.Tests.Integration/Users/Commands/AddUserTests.cs b/tests/Application.Tests.Integration/Users/Commands/AddUserTests.cs index 52a431c9..b140781f 100644 --- a/tests/Application.Tests.Integration/Users/Commands/AddUserTests.cs +++ b/tests/Application.Tests.Integration/Users/Commands/AddUserTests.cs @@ -1,4 +1,4 @@ -using Application.Users.Commands.AddUser; +using Application.Users.Commands.Add; using Bogus; using Domain.Entities; using FluentAssertions; @@ -8,7 +8,7 @@ namespace Application.Tests.Integration.Users.Commands; public class AddUserTests : BaseClassFixture { - private readonly Faker _userGenerator = new Faker() + private readonly Faker _userGenerator = new Faker() .RuleFor(x => x.Username, faker => faker.Person.UserName) .RuleFor(x => x.Email, faker => faker.Person.Email) .RuleFor(x => x.FirstName, faker => faker.Person.FirstName) diff --git a/tests/Application.Tests.Unit/Common/Mappings/MappingTests.cs b/tests/Application.Tests.Unit/Common/Mappings/MappingTests.cs index 36b57359..dcb2967c 100644 --- a/tests/Application.Tests.Unit/Common/Mappings/MappingTests.cs +++ b/tests/Application.Tests.Unit/Common/Mappings/MappingTests.cs @@ -2,7 +2,7 @@ using Application.Common.Mappings; using Application.Common.Models.Dtos; using Application.Common.Models.Dtos.Physical; -using Application.Documents.Queries.GetAllDocumentsPaginated; +using Application.Documents.Queries.GetAllPaginated; using Application.Rooms.Queries.GetEmptyContainersPaginated; using Application.Users.Queries; using AutoMapper; From 550f1d45a9b3812d571d35c86dd97410fbfd8f55 Mon Sep 17 00:00:00 2001 From: Nguyen Quang Chien Date: Sat, 27 May 2023 23:25:22 +0700 Subject: [PATCH 03/11] refactor: remove some dependencies from tests --- tests/Application.Tests.Integration/BaseClassFixture.cs | 2 -- tests/Application.Tests.Integration/CustomApiFactory.cs | 4 ++-- .../Documents/Queries/GetAllDocumentsPaginatedTests.cs | 2 -- .../Folders/Commands/AddFolderTests.cs | 3 --- .../Lockers/Commands/AddLockerTests.cs | 2 -- .../Lockers/Commands/DisableLockerTests.cs | 2 -- .../Lockers/Commands/EnableLockerTests.cs | 4 ---- .../Rooms/Commands/DisableRoomTests.cs | 4 ---- .../Rooms/Commands/RemoveRoomTests.cs | 1 - .../Rooms/Queries/GetEmptyContainersPaginatedTests.cs | 1 - 10 files changed, 2 insertions(+), 23 deletions(-) diff --git a/tests/Application.Tests.Integration/BaseClassFixture.cs b/tests/Application.Tests.Integration/BaseClassFixture.cs index 6633884f..a1b50091 100644 --- a/tests/Application.Tests.Integration/BaseClassFixture.cs +++ b/tests/Application.Tests.Integration/BaseClassFixture.cs @@ -1,9 +1,7 @@ using Application.Departments.Commands.Add; using Bogus; using Domain.Common; -using Domain.Entities; using Domain.Entities.Physical; -using FluentAssertions; using Infrastructure.Persistence; using MediatR; using Microsoft.EntityFrameworkCore; diff --git a/tests/Application.Tests.Integration/CustomApiFactory.cs b/tests/Application.Tests.Integration/CustomApiFactory.cs index 5d14c8ec..d6ab68e9 100644 --- a/tests/Application.Tests.Integration/CustomApiFactory.cs +++ b/tests/Application.Tests.Integration/CustomApiFactory.cs @@ -14,7 +14,7 @@ public class CustomApiFactory : WebApplicationFactory { protected override void ConfigureWebHost(IWebHostBuilder builder) { - builder.ConfigureServices((builderContext, services) => + builder.ConfigureServices((_, services) => { var descriptor = services.SingleOrDefault( d => d.ServiceType == @@ -28,7 +28,7 @@ protected override void ConfigureWebHost(IWebHostBuilder builder) var databaseSettings = GetConfiguration().GetSection(nameof(DatabaseSettings)).Get(); services.AddDbContext(options => { - options.UseNpgsql("Server=localhost;Port=5432;Database=mytestdb;User ID=profiletester;Password=supasupasecured;", optionsBuilder => optionsBuilder.UseNodaTime()); + options.UseNpgsql(databaseSettings!.ConnectionString, optionsBuilder => optionsBuilder.UseNodaTime()); }); }); } diff --git a/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentsPaginatedTests.cs b/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentsPaginatedTests.cs index 504e2db3..b5bc4b16 100644 --- a/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentsPaginatedTests.cs +++ b/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentsPaginatedTests.cs @@ -4,8 +4,6 @@ using Application.Common.Models.Dtos.Physical; using Application.Documents.Queries.GetAllPaginated; using AutoMapper; - using Bogus; - using Domain.Entities.Physical; using FluentAssertions; using Xunit; diff --git a/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs b/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs index 787d92ee..cd6328e3 100644 --- a/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs +++ b/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs @@ -1,8 +1,5 @@ using Application.Common.Exceptions; using Application.Common.Models.Dtos.Physical; -using Application.Folders.Commands.Add; -using Application.Lockers.Commands.Add; -using Application.Rooms.Commands.Add; using Bogus; using Domain.Entities.Physical; using Domain.Exceptions; diff --git a/tests/Application.Tests.Integration/Lockers/Commands/AddLockerTests.cs b/tests/Application.Tests.Integration/Lockers/Commands/AddLockerTests.cs index 138c0ec2..aab654d2 100644 --- a/tests/Application.Tests.Integration/Lockers/Commands/AddLockerTests.cs +++ b/tests/Application.Tests.Integration/Lockers/Commands/AddLockerTests.cs @@ -4,8 +4,6 @@ using Domain.Entities.Physical; using Domain.Exceptions; using FluentAssertions; -using MediatR; -using Microsoft.Extensions.DependencyInjection; using Xunit; namespace Application.Tests.Integration.Lockers.Commands; diff --git a/tests/Application.Tests.Integration/Lockers/Commands/DisableLockerTests.cs b/tests/Application.Tests.Integration/Lockers/Commands/DisableLockerTests.cs index 0ccc1d0a..0dfa0101 100644 --- a/tests/Application.Tests.Integration/Lockers/Commands/DisableLockerTests.cs +++ b/tests/Application.Tests.Integration/Lockers/Commands/DisableLockerTests.cs @@ -1,6 +1,4 @@ using Application.Common.Exceptions; -using Application.Lockers.Commands.Add; -using Application.Lockers.Commands.Disable; using Bogus; using Domain.Entities.Physical; using FluentAssertions; diff --git a/tests/Application.Tests.Integration/Lockers/Commands/EnableLockerTests.cs b/tests/Application.Tests.Integration/Lockers/Commands/EnableLockerTests.cs index afceb135..17717c78 100644 --- a/tests/Application.Tests.Integration/Lockers/Commands/EnableLockerTests.cs +++ b/tests/Application.Tests.Integration/Lockers/Commands/EnableLockerTests.cs @@ -1,10 +1,6 @@ using Application.Common.Exceptions; -using Application.Lockers.Commands.Add; -using Application.Lockers.Commands.Disable; -using Application.Lockers.Commands.Enable; using Bogus; using Domain.Entities.Physical; -using Domain.Exceptions; using FluentAssertions; using Xunit; using Command = Application.Lockers.Commands.Disable.Command; diff --git a/tests/Application.Tests.Integration/Rooms/Commands/DisableRoomTests.cs b/tests/Application.Tests.Integration/Rooms/Commands/DisableRoomTests.cs index 18576bd1..999e5745 100644 --- a/tests/Application.Tests.Integration/Rooms/Commands/DisableRoomTests.cs +++ b/tests/Application.Tests.Integration/Rooms/Commands/DisableRoomTests.cs @@ -1,11 +1,7 @@ using Application.Common.Exceptions; -using Application.Helpers; using Application.Rooms.Commands.Disable; -using Bogus; -using Domain.Entities; using Domain.Entities.Physical; using FluentAssertions; -using NodaTime; using Xunit; namespace Application.Tests.Integration.Rooms.Commands; diff --git a/tests/Application.Tests.Integration/Rooms/Commands/RemoveRoomTests.cs b/tests/Application.Tests.Integration/Rooms/Commands/RemoveRoomTests.cs index 26c8e857..20bbacaf 100644 --- a/tests/Application.Tests.Integration/Rooms/Commands/RemoveRoomTests.cs +++ b/tests/Application.Tests.Integration/Rooms/Commands/RemoveRoomTests.cs @@ -1,5 +1,4 @@ using Application.Rooms.Commands.Remove; -using Bogus; using Domain.Entities.Physical; using FluentAssertions; using Xunit; diff --git a/tests/Application.Tests.Integration/Rooms/Queries/GetEmptyContainersPaginatedTests.cs b/tests/Application.Tests.Integration/Rooms/Queries/GetEmptyContainersPaginatedTests.cs index 7fa1ebb3..ad8b7791 100644 --- a/tests/Application.Tests.Integration/Rooms/Queries/GetEmptyContainersPaginatedTests.cs +++ b/tests/Application.Tests.Integration/Rooms/Queries/GetEmptyContainersPaginatedTests.cs @@ -4,7 +4,6 @@ using FluentAssertions; using Infrastructure.Persistence; using Microsoft.Extensions.DependencyInjection; -using Microsoft.VisualBasic; using Xunit; namespace Application.Tests.Integration.Rooms.Queries; From 3fa38c651bb8946f7544535cbc88bac982bd09d5 Mon Sep 17 00:00:00 2001 From: Nguyen Quang Chien Date: Sun, 28 May 2023 05:50:32 +0700 Subject: [PATCH 04/11] refactor: swagger schema and controller parameters --- docker-compose.test.yml | 2 +- src/Api/Controllers/DepartmentsController.cs | 8 ++++++-- src/Api/Controllers/DocumentsController.cs | 12 +++++++++-- src/Api/Controllers/FoldersController.cs | 11 ++++++++-- src/Api/Controllers/LockersController.cs | 16 +++++++++++++-- .../Departments/AddDepartmentRequest.cs | 6 ++++++ .../Documents/ImportDocumentRequest.cs | 10 ++++++++++ .../Requests/Folders/AddFolderRequest.cs | 9 +++++++++ .../Requests/Lockers/AddLockerRequest.cs | 9 +++++++++ .../Payload/Requests/Rooms/AddRoomRequest.cs | 8 ++++++++ .../Requests/Staffs/AddStaffRequest.cs | 7 +++++++ .../Payload/Requests/Users/AddUserRequest.cs | 13 ++++++++++++ src/Api/Controllers/RoomsController.cs | 10 ++++++++-- src/Api/Controllers/StaffsController.cs | 12 ++++++++++- src/Api/Controllers/UsersController.cs | 15 ++++++++++++-- .../Extensions/WebApplicationExtensions.cs | 16 +++++++++++++-- src/Api/Program.cs | 8 ++------ src/Api/appsettings.Testing.json | 20 +++++++++++++++++++ .../Departments/Commands/Delete/Command.cs | 2 +- .../CustomApiFactory.cs | 2 +- .../Queries/GetAllDepartmentsTests.cs | 3 +-- 21 files changed, 173 insertions(+), 26 deletions(-) create mode 100644 src/Api/Controllers/Payload/Requests/Departments/AddDepartmentRequest.cs create mode 100644 src/Api/Controllers/Payload/Requests/Documents/ImportDocumentRequest.cs create mode 100644 src/Api/Controllers/Payload/Requests/Folders/AddFolderRequest.cs create mode 100644 src/Api/Controllers/Payload/Requests/Lockers/AddLockerRequest.cs create mode 100644 src/Api/Controllers/Payload/Requests/Rooms/AddRoomRequest.cs create mode 100644 src/Api/Controllers/Payload/Requests/Staffs/AddStaffRequest.cs create mode 100644 src/Api/Controllers/Payload/Requests/Users/AddUserRequest.cs create mode 100644 src/Api/appsettings.Testing.json diff --git a/docker-compose.test.yml b/docker-compose.test.yml index d7d44b92..993b5ad1 100644 --- a/docker-compose.test.yml +++ b/docker-compose.test.yml @@ -8,7 +8,7 @@ services: ports: - '8888:80' environment: - - ASPNETCORE_ENVIRONMENT=Development + - ASPNETCORE_ENVIRONMENT=Testing - PROFILE_DatabaseSettings__ConnectionString=Server=database;Port=5432;Database=mytestdb;User ID=profiletester;Password=supasupasecured; depends_on: database: diff --git a/src/Api/Controllers/DepartmentsController.cs b/src/Api/Controllers/DepartmentsController.cs index 1b55c7a9..a86c719b 100644 --- a/src/Api/Controllers/DepartmentsController.cs +++ b/src/Api/Controllers/DepartmentsController.cs @@ -46,15 +46,19 @@ public async Task>>> GetAll() /// /// Add a department /// - /// command parameter to add a department + /// Add department details /// A DepartmentDto of the the added department [RequiresRole(IdentityData.Roles.Admin)] [HttpPost] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> Add([FromBody] DepartmentCommands.Add.Command command) + public async Task>> Add([FromBody] AddDepartmentRequest request) { + var command = new DepartmentCommands.Add.Command() + { + Name = request.Name, + }; var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); } diff --git a/src/Api/Controllers/DocumentsController.cs b/src/Api/Controllers/DocumentsController.cs index f62f21bb..f3ea9e99 100644 --- a/src/Api/Controllers/DocumentsController.cs +++ b/src/Api/Controllers/DocumentsController.cs @@ -76,7 +76,7 @@ public async Task>>> GetAllDocumentTypes /// /// Import a document /// - /// Import document details + /// Import document details /// A DocumentDto of the imported document [RequiresRole(IdentityData.Roles.Admin, IdentityData.Roles.Staff)] [HttpPost] @@ -85,8 +85,16 @@ public async Task>>> GetAllDocumentTypes [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> Import([FromBody] DocumentCommands.Import.Command command) + public async Task>> Import([FromBody] ImportDocumentRequest request) { + var command = new DocumentCommands.Import.Command() + { + Title = request.Title, + Description = request.Description, + DocumentType = request.DocumentType, + FolderId = request.FolderId, + ImporterId = request.ImporterId, + }; var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); } diff --git a/src/Api/Controllers/FoldersController.cs b/src/Api/Controllers/FoldersController.cs index 6e07fdfc..6155ad45 100644 --- a/src/Api/Controllers/FoldersController.cs +++ b/src/Api/Controllers/FoldersController.cs @@ -59,7 +59,7 @@ public async Task>>> GetAllPaginate /// /// Add a folder /// - /// Add folder details + /// Add folder details /// A FolderDto of the added folder [RequiresRole(IdentityData.Roles.Admin)] [HttpPost] @@ -68,8 +68,15 @@ public async Task>>> GetAllPaginate [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> AddFolder([FromBody] FolderCommands.Add.Command command) + public async Task>> AddFolder([FromBody] AddFolderRequest request) { + var command = new FolderCommands.Add.Command() + { + Name = request.Name, + Description = request.Description, + Capacity = request.Capacity, + LockerId = request.LockerId, + }; var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); } diff --git a/src/Api/Controllers/LockersController.cs b/src/Api/Controllers/LockersController.cs index 84f648c8..55740894 100644 --- a/src/Api/Controllers/LockersController.cs +++ b/src/Api/Controllers/LockersController.cs @@ -53,15 +53,27 @@ public async Task>>> GetAllPaginate return Ok(Result>.Succeed(result)); } - [RequiresRole(IdentityData.Roles.Staff)] + /// + /// Add a locker + /// + /// Add locker details + /// A LockerDto of the added locker + [RequiresRole(IdentityData.Roles.Admin)] [HttpPost] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> Add([FromBody] LockerCommands.Add.Command command) + public async Task>> Add([FromBody] AddLockerRequest request) { + var command = new LockerCommands.Add.Command() + { + Name = request.Name, + Description = request.Description, + Capacity = request.Capacity, + RoomId = request.RoomId, + }; var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); } diff --git a/src/Api/Controllers/Payload/Requests/Departments/AddDepartmentRequest.cs b/src/Api/Controllers/Payload/Requests/Departments/AddDepartmentRequest.cs new file mode 100644 index 00000000..6bc9ec9c --- /dev/null +++ b/src/Api/Controllers/Payload/Requests/Departments/AddDepartmentRequest.cs @@ -0,0 +1,6 @@ +namespace Api.Controllers.Payload.Requests.Departments; + +public class AddDepartmentRequest +{ + public string Name { get; init; } = null!; +} \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Documents/ImportDocumentRequest.cs b/src/Api/Controllers/Payload/Requests/Documents/ImportDocumentRequest.cs new file mode 100644 index 00000000..648d71c5 --- /dev/null +++ b/src/Api/Controllers/Payload/Requests/Documents/ImportDocumentRequest.cs @@ -0,0 +1,10 @@ +namespace Api.Controllers.Payload.Requests.Documents; + +public class ImportDocumentRequest +{ + public string Title { get; init; } = null!; + public string? Description { get; init; } + public string DocumentType { get; init; } = null!; + public Guid ImporterId { get; init; } + public Guid FolderId { get; init; } +} \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Folders/AddFolderRequest.cs b/src/Api/Controllers/Payload/Requests/Folders/AddFolderRequest.cs new file mode 100644 index 00000000..6285152a --- /dev/null +++ b/src/Api/Controllers/Payload/Requests/Folders/AddFolderRequest.cs @@ -0,0 +1,9 @@ +namespace Api.Controllers.Payload.Requests.Folders; + +public class AddFolderRequest +{ + public string Name { get; init; } = null!; + public string? Description { get; init; } + public int Capacity { get; init; } + public Guid LockerId { get; init; } +} \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Lockers/AddLockerRequest.cs b/src/Api/Controllers/Payload/Requests/Lockers/AddLockerRequest.cs new file mode 100644 index 00000000..5820e413 --- /dev/null +++ b/src/Api/Controllers/Payload/Requests/Lockers/AddLockerRequest.cs @@ -0,0 +1,9 @@ +namespace Api.Controllers.Payload.Requests.Lockers; + +public class AddLockerRequest +{ + public string Name { get; init; } = null!; + public string? Description { get; init; } + public Guid RoomId { get; init; } + public int Capacity { get; init; } +} \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Rooms/AddRoomRequest.cs b/src/Api/Controllers/Payload/Requests/Rooms/AddRoomRequest.cs new file mode 100644 index 00000000..482583c1 --- /dev/null +++ b/src/Api/Controllers/Payload/Requests/Rooms/AddRoomRequest.cs @@ -0,0 +1,8 @@ +namespace Api.Controllers.Payload.Requests.Rooms; + +public class AddRoomRequest +{ + public string Name { get; init; } = null!; + public string? Description { get; init; } + public int Capacity { get; init; } +} \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Staffs/AddStaffRequest.cs b/src/Api/Controllers/Payload/Requests/Staffs/AddStaffRequest.cs new file mode 100644 index 00000000..1a29a1b8 --- /dev/null +++ b/src/Api/Controllers/Payload/Requests/Staffs/AddStaffRequest.cs @@ -0,0 +1,7 @@ +namespace Api.Controllers.Payload.Requests.Staffs; + +public class AddStaffRequest +{ + public Guid UserId { get; init; } + public Guid RoomId { get; init; } +} \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Users/AddUserRequest.cs b/src/Api/Controllers/Payload/Requests/Users/AddUserRequest.cs new file mode 100644 index 00000000..c3907b52 --- /dev/null +++ b/src/Api/Controllers/Payload/Requests/Users/AddUserRequest.cs @@ -0,0 +1,13 @@ +namespace Api.Controllers.Payload.Requests.Users; + +public class AddUserRequest +{ + public string Username { get; init; } = null!; + public string Email { get; init; } = null!; + public string Password { get; init; } = null!; + public string? FirstName { get; init; } + public string? LastName { get; init; } + public Guid DepartmentId { get; init; } + public string Role { get; init; } = null!; + public string? Position { get; init; } +} \ No newline at end of file diff --git a/src/Api/Controllers/RoomsController.cs b/src/Api/Controllers/RoomsController.cs index 38f0b339..6c23a765 100644 --- a/src/Api/Controllers/RoomsController.cs +++ b/src/Api/Controllers/RoomsController.cs @@ -80,7 +80,7 @@ public async Task>>> GetAllPaginated( /// /// Add a room /// - /// Add room details + /// Add room details /// A RoomDto of the added room [RequiresRole(IdentityData.Roles.Admin)] [HttpPost] @@ -89,8 +89,14 @@ public async Task>>> GetAllPaginated( [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> AddRoom([FromBody] RoomCommands.Add.Command command) + public async Task>> AddRoom([FromBody] AddRoomRequest request) { + var command = new RoomCommands.Add.Command() + { + Name = request.Name, + Description = request.Description, + Capacity = request.Capacity, + }; var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); } diff --git a/src/Api/Controllers/StaffsController.cs b/src/Api/Controllers/StaffsController.cs index 717c9e44..4edac7c7 100644 --- a/src/Api/Controllers/StaffsController.cs +++ b/src/Api/Controllers/StaffsController.cs @@ -71,13 +71,23 @@ public async Task>>> GetAllPaginated return Ok(Result>.Succeed(result)); } + /// + /// Add a staff + /// + /// Add staff details + /// A StaffDto of the added staff [RequiresRole(IdentityData.Roles.Admin)] [HttpPost] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task>> Add([FromBody] StaffCommands.Add.Command command) + public async Task>> Add([FromBody] AddStaffRequest request) { + var command = new StaffCommands.Add.Command() + { + RoomId = request.RoomId, + UserId = request.UserId, + }; var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); } diff --git a/src/Api/Controllers/UsersController.cs b/src/Api/Controllers/UsersController.cs index 4e37540e..f514c935 100644 --- a/src/Api/Controllers/UsersController.cs +++ b/src/Api/Controllers/UsersController.cs @@ -64,7 +64,7 @@ public async Task>>> GetAllPaginated( /// /// Add a user /// - /// Add user details + /// Add user details /// A UserDto of the added user [RequiresRole(IdentityData.Roles.Admin)] [HttpPost] @@ -73,8 +73,19 @@ public async Task>>> GetAllPaginated( [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task>> Add([FromBody] UserCommands.Add.Command command) + public async Task>> Add([FromBody] AddUserRequest request) { + var command = new UserCommands.Add.Command() + { + Username = request.Username, + Email = request.Email, + Password = request.Password, + FirstName = request.FirstName, + LastName = request.LastName, + Role = request.Role, + Position = request.Position, + DepartmentId = request.DepartmentId, + }; var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); } diff --git a/src/Api/Extensions/WebApplicationExtensions.cs b/src/Api/Extensions/WebApplicationExtensions.cs index e0a90371..63e834ee 100644 --- a/src/Api/Extensions/WebApplicationExtensions.cs +++ b/src/Api/Extensions/WebApplicationExtensions.cs @@ -1,10 +1,12 @@ using Api.Middlewares; +using Infrastructure.Persistence; +using Serilog; namespace Api.Extensions; public static class WebApplicationExtensions { - public static void UseInfrastructure(this WebApplication app) + public static void UseInfrastructure(this WebApplication app, IConfiguration configuration) { // Configure the HTTP request pipeline. @@ -15,10 +17,20 @@ public static void UseInfrastructure(this WebApplication app) { app.UseSwagger(); app.UseSwaggerUI(); + app.UseCors("AllowAllOrigins"); + + app.MigrateDatabase((context, _) => + { + ApplicationDbContextSeed.Seed(context, configuration, Log.Logger).Wait(); + }); } - else + + if (app.Environment.IsEnvironment("Testing")) { + app.MigrateDatabase((_, _) => + { + }); } app.UseAuthentication(); diff --git a/src/Api/Program.cs b/src/Api/Program.cs index 42a37f8f..829f0873 100644 --- a/src/Api/Program.cs +++ b/src/Api/Program.cs @@ -21,13 +21,9 @@ var app = builder.Build(); - app.UseInfrastructure(); + app.UseInfrastructure(builder.Configuration); - app.MigrateDatabase((context, _) => - { - ApplicationDbContextSeed.Seed(context, builder.Configuration, Log.Logger).Wait(); - }) - .Run(); + app.Run(); } catch (Exception ex) { diff --git a/src/Api/appsettings.Testing.json b/src/Api/appsettings.Testing.json new file mode 100644 index 00000000..5dbdc362 --- /dev/null +++ b/src/Api/appsettings.Testing.json @@ -0,0 +1,20 @@ +{ + "JweSettings": { + "SigningKeyId": "4bd28be8eac5414fb01c5cbe343b50144bd2", + "EncryptionKeyId": "4bd28be8eac5414fb01c5cbe343b5014", + "TokenLifetime": "00:20:00", + "RefreshTokenLifetimeInDays": 3 + }, + "Seed": true, + "Serilog" : { + "MinimumLevel" : { + "Default": "Debug", + "Override": { + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information", + "Microsoft.AspNetCore.Authentication": "Debug", + "System": "Warning" + } + } + } +} diff --git a/src/Application/Departments/Commands/Delete/Command.cs b/src/Application/Departments/Commands/Delete/Command.cs index 1790c454..840cdc42 100644 --- a/src/Application/Departments/Commands/Delete/Command.cs +++ b/src/Application/Departments/Commands/Delete/Command.cs @@ -27,7 +27,7 @@ public async Task Handle(Command request, CancellationToken cance if (department is null) { - throw new KeyNotFoundException("Department does not exist"); + throw new KeyNotFoundException("Department does not exist."); } var result = _context.Departments.Remove(department); diff --git a/tests/Application.Tests.Integration/CustomApiFactory.cs b/tests/Application.Tests.Integration/CustomApiFactory.cs index d6ab68e9..f76d4ac3 100644 --- a/tests/Application.Tests.Integration/CustomApiFactory.cs +++ b/tests/Application.Tests.Integration/CustomApiFactory.cs @@ -14,7 +14,7 @@ public class CustomApiFactory : WebApplicationFactory { protected override void ConfigureWebHost(IWebHostBuilder builder) { - builder.ConfigureServices((_, services) => + builder.ConfigureServices((builderContext, services) => { var descriptor = services.SingleOrDefault( d => d.ServiceType == diff --git a/tests/Application.Tests.Integration/Departments/Queries/GetAllDepartmentsTests.cs b/tests/Application.Tests.Integration/Departments/Queries/GetAllDepartmentsTests.cs index d6e6c864..a1ea2694 100644 --- a/tests/Application.Tests.Integration/Departments/Queries/GetAllDepartmentsTests.cs +++ b/tests/Application.Tests.Integration/Departments/Queries/GetAllDepartmentsTests.cs @@ -52,7 +52,6 @@ public async Task ShouldReturnEmptyList_WhenNoDepartmentsExist() var result = await SendAsync(query); // Assert - result.Count().Should().Be(1); - result.First().Name.Should().Be(IdentityData.Roles.Admin); + result.Count().Should().Be(0); } } \ No newline at end of file From 64800bf898fdc2ba9bec71d9d9eb70c514b81069 Mon Sep 17 00:00:00 2001 From: Nguyen Quang Chien Date: Sun, 28 May 2023 06:00:49 +0700 Subject: [PATCH 05/11] add: base class fixture methods --- src/Application/Identity/IdentityData.cs | 1 + .../BaseClassFixture.cs | 40 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/Application/Identity/IdentityData.cs b/src/Application/Identity/IdentityData.cs index 165e74e7..6e69dbb7 100644 --- a/src/Application/Identity/IdentityData.cs +++ b/src/Application/Identity/IdentityData.cs @@ -6,5 +6,6 @@ public static class Roles { public const string Admin = "Admin"; public const string Staff = "Staff"; + public const string Employee = "Employee"; } } \ No newline at end of file diff --git a/tests/Application.Tests.Integration/BaseClassFixture.cs b/tests/Application.Tests.Integration/BaseClassFixture.cs index a1b50091..f662baeb 100644 --- a/tests/Application.Tests.Integration/BaseClassFixture.cs +++ b/tests/Application.Tests.Integration/BaseClassFixture.cs @@ -1,11 +1,14 @@ using Application.Departments.Commands.Add; +using Application.Helpers; using Bogus; using Domain.Common; +using Domain.Entities; using Domain.Entities.Physical; using Infrastructure.Persistence; using MediatR; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; +using NodaTime; using Xunit; namespace Application.Tests.Integration; @@ -158,4 +161,41 @@ protected Room CreateRoom(params Locker[] lockers) return room; } + + protected static Department CreateDepartment() + { + return new Department() + { + Id = Guid.NewGuid(), + Name = new Faker().Commerce.Department() + }; + } + + protected static User CreateUser(string role, string password) + { + return new User() + { + Id = Guid.NewGuid(), + Username = new Faker().Person.UserName, + Email = new Faker().Person.Email, + FirstName = new Faker().Person.FirstName, + LastName = new Faker().Person.LastName, + Role = role, + Position = new Faker().Random.Word(), + IsActivated = true, + IsActive = true, + Created = LocalDateTime.FromDateTime(DateTime.Now), + PasswordHash = SecurityUtil.Hash(password) + }; + } + + protected static Staff CreateStaff(User user, Room? room) + { + return new Staff() + { + Id = user.Id, + User = user, + Room = room, + }; + } } \ No newline at end of file From 31d0a3e2bfebbff32c953cf7dc1c158ce77fa57c Mon Sep 17 00:00:00 2001 From: Nguyen Quang Chien Date: Sun, 28 May 2023 07:01:34 +0700 Subject: [PATCH 06/11] refactor: alter some schema --- .../Requests/Staffs/AddStaffRequest.cs | 2 +- .../Common/Models/Dtos/Physical/StaffDto.cs | 4 +- .../Departments/Commands/Add/Command.cs | 4 +- src/Application/Rooms/Commands/Add/Command.cs | 11 +- .../Staffs/Commands/Add/Command.cs | 6 +- src/Domain/Entities/Department.cs | 3 + src/Domain/Entities/Physical/Room.cs | 2 + src/Domain/Entities/Physical/Staff.cs | 2 +- src/Domain/Entities/User.cs | 2 +- .../Configurations/DepartmentConfiguration.cs | 6 + .../Configurations/RoomConfiguration.cs | 6 + .../Configurations/StaffConfiguration.cs | 2 +- .../Configurations/UserConfiguration.cs | 2 +- ...00000000007_Add_Refresh_Token.Designer.cs} | 0 ...cs => 00000000000007_Add_Refresh_Token.cs} | 0 ...dRoomAndDepartmentRelationship.Designer.cs | 475 ++++++++++++++++++ ...ionshipAndRoomAndDepartmentRelationship.cs | 123 +++++ .../ApplicationDbContextModelSnapshot.cs | 27 +- 18 files changed, 659 insertions(+), 18 deletions(-) rename src/Infrastructure/Persistence/Migrations/{20230524080300_Add_Refresh_Token.Designer.cs => 00000000000007_Add_Refresh_Token.Designer.cs} (100%) rename src/Infrastructure/Persistence/Migrations/{20230524080300_Add_Refresh_Token.cs => 00000000000007_Add_Refresh_Token.cs} (100%) create mode 100644 src/Infrastructure/Persistence/Migrations/00000000000008_UpdateRoomAndStaffRelationshipAndRoomAndDepartmentRelationship.Designer.cs create mode 100644 src/Infrastructure/Persistence/Migrations/00000000000008_UpdateRoomAndStaffRelationshipAndRoomAndDepartmentRelationship.cs diff --git a/src/Api/Controllers/Payload/Requests/Staffs/AddStaffRequest.cs b/src/Api/Controllers/Payload/Requests/Staffs/AddStaffRequest.cs index 1a29a1b8..a61c0b66 100644 --- a/src/Api/Controllers/Payload/Requests/Staffs/AddStaffRequest.cs +++ b/src/Api/Controllers/Payload/Requests/Staffs/AddStaffRequest.cs @@ -3,5 +3,5 @@ namespace Api.Controllers.Payload.Requests.Staffs; public class AddStaffRequest { public Guid UserId { get; init; } - public Guid RoomId { get; init; } + public Guid? RoomId { get; init; } } \ No newline at end of file diff --git a/src/Application/Common/Models/Dtos/Physical/StaffDto.cs b/src/Application/Common/Models/Dtos/Physical/StaffDto.cs index ade92bb9..84563c1b 100644 --- a/src/Application/Common/Models/Dtos/Physical/StaffDto.cs +++ b/src/Application/Common/Models/Dtos/Physical/StaffDto.cs @@ -6,6 +6,6 @@ namespace Application.Common.Models.Dtos.Physical; public class StaffDto : IMapFrom { - public UserDto User { get; set; } - public RoomDto Room { get; set; } + public UserDto User { get; set; } = null!; + public RoomDto? Room { get; set; } } \ No newline at end of file diff --git a/src/Application/Departments/Commands/Add/Command.cs b/src/Application/Departments/Commands/Add/Command.cs index 00d6cfba..1c7f043e 100644 --- a/src/Application/Departments/Commands/Add/Command.cs +++ b/src/Application/Departments/Commands/Add/Command.cs @@ -25,12 +25,14 @@ public AddDepartmentCommandHandler(IApplicationDbContext context, IMapper mapper public async Task Handle(Command request, CancellationToken cancellationToken) { - var department = await _context.Departments.FirstOrDefaultAsync(x => x.Name.Trim().ToLower().Equals(request.Name.Trim().ToLower()), cancellationToken); + var department = await _context.Departments.FirstOrDefaultAsync(x + => x.Name.Trim().ToLower().Equals(request.Name.Trim().ToLower()), cancellationToken); if (department is not null) { throw new ConflictException("Department name already exists."); } + var entity = new Department { Name = request.Name diff --git a/src/Application/Rooms/Commands/Add/Command.cs b/src/Application/Rooms/Commands/Add/Command.cs index 634aa1d1..d508e8bb 100644 --- a/src/Application/Rooms/Commands/Add/Command.cs +++ b/src/Application/Rooms/Commands/Add/Command.cs @@ -13,6 +13,7 @@ public record Command : IRequest public string Name { get; init; } = null!; public string? Description { get; init; } public int Capacity { get; init; } + public Guid DepartmentId { get; set; } } public class CommandHandler : IRequestHandler @@ -27,7 +28,14 @@ public CommandHandler(IApplicationDbContext context, IMapper mapper) public async Task Handle(Command request, CancellationToken cancellationToken) { + var department = + await _context.Departments.FirstOrDefaultAsync(x => x.Id == request.DepartmentId, cancellationToken); + if (department is null) + { + throw new KeyNotFoundException("Department does not exists."); + } + var room = await _context.Rooms.FirstOrDefaultAsync(r => r.Name.Trim().ToLower().Equals(request.Name.Trim().ToLower()), cancellationToken); @@ -41,7 +49,8 @@ public async Task Handle(Command request, CancellationToken cancellatio Name = request.Name.Trim(), Description = request.Description?.Trim(), NumberOfLockers = 0, - Capacity = request.Capacity + Capacity = request.Capacity, + Department = department, }; var result = await _context.Rooms.AddAsync(entity, cancellationToken); await _context.SaveChangesAsync(cancellationToken); diff --git a/src/Application/Staffs/Commands/Add/Command.cs b/src/Application/Staffs/Commands/Add/Command.cs index 53d90614..ffed9ca2 100644 --- a/src/Application/Staffs/Commands/Add/Command.cs +++ b/src/Application/Staffs/Commands/Add/Command.cs @@ -10,7 +10,7 @@ namespace Application.Staffs.Commands.Add; public record Command : IRequest { public Guid UserId { get; init; } - public Guid RoomId { get; init; } + public Guid? RoomId { get; init; } } public class CommandHandler : IRequestHandler @@ -33,10 +33,6 @@ public async Task Handle(Command request, CancellationToken cancellati } var room = await _context.Rooms.FirstOrDefaultAsync(x => x.Id == request.RoomId, cancellationToken); - if (room is null) - { - throw new KeyNotFoundException("Room does not exist."); - } var staff = new Staff { diff --git a/src/Domain/Entities/Department.cs b/src/Domain/Entities/Department.cs index 6513aa25..654a0228 100644 --- a/src/Domain/Entities/Department.cs +++ b/src/Domain/Entities/Department.cs @@ -1,8 +1,11 @@ using Domain.Common; +using Domain.Entities.Physical; namespace Domain.Entities; public class Department : BaseEntity { public string Name { get; set; } = null!; + public Guid? RoomId { get; set; } + public Room? Room { get; set; } } \ No newline at end of file diff --git a/src/Domain/Entities/Physical/Room.cs b/src/Domain/Entities/Physical/Room.cs index 517ab146..19bda6ff 100644 --- a/src/Domain/Entities/Physical/Room.cs +++ b/src/Domain/Entities/Physical/Room.cs @@ -7,10 +7,12 @@ public class Room : BaseEntity public string Name { get; set; } = null!; public string? Description { get; set; } public Staff? Staff { get; set; } + public Guid? DepartmentId { get; set; } public int Capacity { get; set; } public int NumberOfLockers { get; set; } public bool IsAvailable { get; set; } // Navigation property + public Department? Department { get; set; } public ICollection Lockers { get; set; } = new List(); } \ No newline at end of file diff --git a/src/Domain/Entities/Physical/Staff.cs b/src/Domain/Entities/Physical/Staff.cs index 1184a040..bb6f2a28 100644 --- a/src/Domain/Entities/Physical/Staff.cs +++ b/src/Domain/Entities/Physical/Staff.cs @@ -5,5 +5,5 @@ namespace Domain.Entities.Physical; public class Staff : BaseEntity { public User User { get; set; } = null!; - public Room Room { get; set; } = null!; + public Room? Room { get; set; } } \ No newline at end of file diff --git a/src/Domain/Entities/User.cs b/src/Domain/Entities/User.cs index 210a75a5..cc8c2345 100644 --- a/src/Domain/Entities/User.cs +++ b/src/Domain/Entities/User.cs @@ -6,7 +6,7 @@ namespace Domain.Entities; public class User : BaseAuditableEntity { public string Username { get; set; } = null!; - public string? Email { get; set; } + public string Email { get; set; } = null!; public string PasswordHash { get; set; } = null!; public string? FirstName { get; set; } public string? LastName { get; set; } diff --git a/src/Infrastructure/Persistence/Configurations/DepartmentConfiguration.cs b/src/Infrastructure/Persistence/Configurations/DepartmentConfiguration.cs index 8af33bea..b0c26706 100644 --- a/src/Infrastructure/Persistence/Configurations/DepartmentConfiguration.cs +++ b/src/Infrastructure/Persistence/Configurations/DepartmentConfiguration.cs @@ -1,4 +1,5 @@ using Domain.Entities; +using Domain.Entities.Physical; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.ValueGeneration; @@ -16,5 +17,10 @@ public void Configure(EntityTypeBuilder builder) builder.HasAlternateKey(x => x.Name); builder.Property(x => x.Name) .HasMaxLength(64); + + builder.HasOne(x => x.Room) + .WithOne(x => x.Department) + .HasForeignKey(x => x.DepartmentId) + .IsRequired(false); } } \ No newline at end of file diff --git a/src/Infrastructure/Persistence/Configurations/RoomConfiguration.cs b/src/Infrastructure/Persistence/Configurations/RoomConfiguration.cs index 636a330b..399a1214 100644 --- a/src/Infrastructure/Persistence/Configurations/RoomConfiguration.cs +++ b/src/Infrastructure/Persistence/Configurations/RoomConfiguration.cs @@ -1,3 +1,4 @@ +using Domain.Entities; using Domain.Entities.Physical; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; @@ -21,6 +22,11 @@ public void Configure(EntityTypeBuilder builder) .HasMaxLength(256) .IsRequired(false); + builder.HasOne(x => x.Department) + .WithOne(x => x.Room) + .HasForeignKey(x => x.RoomId) + .IsRequired(false); + builder.Property(x => x.Capacity) .IsRequired(); diff --git a/src/Infrastructure/Persistence/Configurations/StaffConfiguration.cs b/src/Infrastructure/Persistence/Configurations/StaffConfiguration.cs index 316bf414..b2881567 100644 --- a/src/Infrastructure/Persistence/Configurations/StaffConfiguration.cs +++ b/src/Infrastructure/Persistence/Configurations/StaffConfiguration.cs @@ -22,6 +22,6 @@ public void Configure(EntityTypeBuilder builder) builder.HasOne(x => x.Room) .WithOne(x => x.Staff) .HasForeignKey("RoomId") - .IsRequired(); + .IsRequired(false); } } \ No newline at end of file diff --git a/src/Infrastructure/Persistence/Configurations/UserConfiguration.cs b/src/Infrastructure/Persistence/Configurations/UserConfiguration.cs index a12b422f..b3e55685 100644 --- a/src/Infrastructure/Persistence/Configurations/UserConfiguration.cs +++ b/src/Infrastructure/Persistence/Configurations/UserConfiguration.cs @@ -19,7 +19,7 @@ public void Configure(EntityTypeBuilder builder) builder.Property(x => x.Email) .HasMaxLength(320) - .IsRequired(false); + .IsRequired(); builder.Property(x => x.PasswordHash) .HasMaxLength(64) diff --git a/src/Infrastructure/Persistence/Migrations/20230524080300_Add_Refresh_Token.Designer.cs b/src/Infrastructure/Persistence/Migrations/00000000000007_Add_Refresh_Token.Designer.cs similarity index 100% rename from src/Infrastructure/Persistence/Migrations/20230524080300_Add_Refresh_Token.Designer.cs rename to src/Infrastructure/Persistence/Migrations/00000000000007_Add_Refresh_Token.Designer.cs diff --git a/src/Infrastructure/Persistence/Migrations/20230524080300_Add_Refresh_Token.cs b/src/Infrastructure/Persistence/Migrations/00000000000007_Add_Refresh_Token.cs similarity index 100% rename from src/Infrastructure/Persistence/Migrations/20230524080300_Add_Refresh_Token.cs rename to src/Infrastructure/Persistence/Migrations/00000000000007_Add_Refresh_Token.cs diff --git a/src/Infrastructure/Persistence/Migrations/00000000000008_UpdateRoomAndStaffRelationshipAndRoomAndDepartmentRelationship.Designer.cs b/src/Infrastructure/Persistence/Migrations/00000000000008_UpdateRoomAndStaffRelationshipAndRoomAndDepartmentRelationship.Designer.cs new file mode 100644 index 00000000..1ff0d731 --- /dev/null +++ b/src/Infrastructure/Persistence/Migrations/00000000000008_UpdateRoomAndStaffRelationshipAndRoomAndDepartmentRelationship.Designer.cs @@ -0,0 +1,475 @@ +// +using System; +using Infrastructure.Persistence; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using NodaTime; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Infrastructure.Persistence.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20230527234317_UpdateRoomAndStaffRelationshipAndRoomAndDepartmentRelationship")] + partial class UpdateRoomAndStaffRelationshipAndRoomAndDepartmentRelationship + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.5") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Domain.Entities.Department", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("RoomId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasAlternateKey("Name"); + + b.HasIndex("RoomId") + .IsUnique(); + + b.ToTable("Departments"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Borrow", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("BorrowTime") + .HasColumnType("timestamp without time zone"); + + b.Property("BorrowerId") + .HasColumnType("uuid"); + + b.Property("DocumentId") + .HasColumnType("uuid"); + + b.Property("DueTime") + .HasColumnType("timestamp without time zone"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("BorrowerId"); + + b.HasIndex("DocumentId"); + + b.ToTable("Borrows"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Document", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("DepartmentId") + .HasColumnType("uuid"); + + b.Property("Description") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("DocumentType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("FolderId") + .HasColumnType("uuid"); + + b.Property("ImporterId") + .HasColumnType("uuid"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.HasKey("Id"); + + b.HasIndex("DepartmentId"); + + b.HasIndex("FolderId"); + + b.HasIndex("ImporterId"); + + b.ToTable("Documents"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Folder", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Capacity") + .HasColumnType("integer"); + + b.Property("Description") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("IsAvailable") + .HasColumnType("boolean"); + + b.Property("LockerId") + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("NumberOfDocuments") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("LockerId"); + + b.ToTable("Folders"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Locker", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Capacity") + .HasColumnType("integer"); + + b.Property("Description") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("IsAvailable") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("NumberOfFolders") + .HasColumnType("integer"); + + b.Property("RoomId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("RoomId"); + + b.ToTable("Lockers"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Room", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Capacity") + .HasColumnType("integer"); + + b.Property("DepartmentId") + .HasColumnType("uuid"); + + b.Property("Description") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("IsAvailable") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("NumberOfLockers") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasAlternateKey("Name"); + + b.ToTable("Rooms"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Staff", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("UserId"); + + b.Property("RoomId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("RoomId") + .IsUnique(); + + b.ToTable("Staffs"); + }); + + modelBuilder.Entity("Domain.Entities.RefreshToken", b => + { + b.Property("Token") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationDateTime") + .HasColumnType("timestamp without time zone"); + + b.Property("ExpiryDateTime") + .HasColumnType("timestamp without time zone"); + + b.Property("IsInvalidated") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("IsUsed") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("JwtId") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Token"); + + b.HasIndex("UserId"); + + b.ToTable("RefreshTokens"); + }); + + modelBuilder.Entity("Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Created") + .HasColumnType("timestamp without time zone"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("DepartmentId") + .HasColumnType("uuid"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(320) + .HasColumnType("character varying(320)"); + + b.Property("FirstName") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("IsActivated") + .HasColumnType("boolean"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("LastModified") + .HasColumnType("timestamp without time zone"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastName") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("PasswordHash") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Position") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Role") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("DepartmentId"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Domain.Entities.Department", b => + { + b.HasOne("Domain.Entities.Physical.Room", "Room") + .WithOne("Department") + .HasForeignKey("Domain.Entities.Department", "RoomId"); + + b.Navigation("Room"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Borrow", b => + { + b.HasOne("Domain.Entities.User", "Borrower") + .WithMany() + .HasForeignKey("BorrowerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Domain.Entities.Physical.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Borrower"); + + b.Navigation("Document"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Document", b => + { + b.HasOne("Domain.Entities.Department", "Department") + .WithMany() + .HasForeignKey("DepartmentId"); + + b.HasOne("Domain.Entities.Physical.Folder", "Folder") + .WithMany("Documents") + .HasForeignKey("FolderId"); + + b.HasOne("Domain.Entities.User", "Importer") + .WithMany() + .HasForeignKey("ImporterId"); + + b.Navigation("Department"); + + b.Navigation("Folder"); + + b.Navigation("Importer"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Folder", b => + { + b.HasOne("Domain.Entities.Physical.Locker", "Locker") + .WithMany("Folders") + .HasForeignKey("LockerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Locker"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Locker", b => + { + b.HasOne("Domain.Entities.Physical.Room", "Room") + .WithMany("Lockers") + .HasForeignKey("RoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Room"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Staff", b => + { + b.HasOne("Domain.Entities.User", "User") + .WithOne() + .HasForeignKey("Domain.Entities.Physical.Staff", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Domain.Entities.Physical.Room", "Room") + .WithOne("Staff") + .HasForeignKey("Domain.Entities.Physical.Staff", "RoomId"); + + b.Navigation("Room"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Domain.Entities.RefreshToken", b => + { + b.HasOne("Domain.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Domain.Entities.User", b => + { + b.HasOne("Domain.Entities.Department", "Department") + .WithMany() + .HasForeignKey("DepartmentId"); + + b.Navigation("Department"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Folder", b => + { + b.Navigation("Documents"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Locker", b => + { + b.Navigation("Folders"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Room", b => + { + b.Navigation("Department"); + + b.Navigation("Lockers"); + + b.Navigation("Staff"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Infrastructure/Persistence/Migrations/00000000000008_UpdateRoomAndStaffRelationshipAndRoomAndDepartmentRelationship.cs b/src/Infrastructure/Persistence/Migrations/00000000000008_UpdateRoomAndStaffRelationshipAndRoomAndDepartmentRelationship.cs new file mode 100644 index 00000000..6bd9968b --- /dev/null +++ b/src/Infrastructure/Persistence/Migrations/00000000000008_UpdateRoomAndStaffRelationshipAndRoomAndDepartmentRelationship.cs @@ -0,0 +1,123 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Infrastructure.Persistence.Migrations +{ + /// + public partial class UpdateRoomAndStaffRelationshipAndRoomAndDepartmentRelationship : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Staffs_Rooms_RoomId", + table: "Staffs"); + + migrationBuilder.AlterColumn( + name: "Email", + table: "Users", + type: "character varying(320)", + maxLength: 320, + nullable: false, + defaultValue: "", + oldClrType: typeof(string), + oldType: "character varying(320)", + oldMaxLength: 320, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "RoomId", + table: "Staffs", + type: "uuid", + nullable: true, + oldClrType: typeof(Guid), + oldType: "uuid"); + + migrationBuilder.AddColumn( + name: "DepartmentId", + table: "Rooms", + type: "uuid", + nullable: true); + + migrationBuilder.AddColumn( + name: "RoomId", + table: "Departments", + type: "uuid", + nullable: true); + + migrationBuilder.CreateIndex( + name: "IX_Departments_RoomId", + table: "Departments", + column: "RoomId", + unique: true); + + migrationBuilder.AddForeignKey( + name: "FK_Departments_Rooms_RoomId", + table: "Departments", + column: "RoomId", + principalTable: "Rooms", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Staffs_Rooms_RoomId", + table: "Staffs", + column: "RoomId", + principalTable: "Rooms", + principalColumn: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Departments_Rooms_RoomId", + table: "Departments"); + + migrationBuilder.DropForeignKey( + name: "FK_Staffs_Rooms_RoomId", + table: "Staffs"); + + migrationBuilder.DropIndex( + name: "IX_Departments_RoomId", + table: "Departments"); + + migrationBuilder.DropColumn( + name: "DepartmentId", + table: "Rooms"); + + migrationBuilder.DropColumn( + name: "RoomId", + table: "Departments"); + + migrationBuilder.AlterColumn( + name: "Email", + table: "Users", + type: "character varying(320)", + maxLength: 320, + nullable: true, + oldClrType: typeof(string), + oldType: "character varying(320)", + oldMaxLength: 320); + + migrationBuilder.AlterColumn( + name: "RoomId", + table: "Staffs", + type: "uuid", + nullable: false, + defaultValue: new Guid("00000000-0000-0000-0000-000000000000"), + oldClrType: typeof(Guid), + oldType: "uuid", + oldNullable: true); + + migrationBuilder.AddForeignKey( + name: "FK_Staffs_Rooms_RoomId", + table: "Staffs", + column: "RoomId", + principalTable: "Rooms", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/src/Infrastructure/Persistence/Migrations/ApplicationDbContextModelSnapshot.cs b/src/Infrastructure/Persistence/Migrations/ApplicationDbContextModelSnapshot.cs index a69d09d2..237d5b96 100644 --- a/src/Infrastructure/Persistence/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/src/Infrastructure/Persistence/Migrations/ApplicationDbContextModelSnapshot.cs @@ -34,10 +34,16 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasMaxLength(64) .HasColumnType("character varying(64)"); + b.Property("RoomId") + .HasColumnType("uuid"); + b.HasKey("Id"); b.HasAlternateKey("Name"); + b.HasIndex("RoomId") + .IsUnique(); + b.ToTable("Departments"); }); @@ -189,6 +195,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Capacity") .HasColumnType("integer"); + b.Property("DepartmentId") + .HasColumnType("uuid"); + b.Property("Description") .HasMaxLength(256) .HasColumnType("character varying(256)"); @@ -218,7 +227,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("uuid") .HasColumnName("UserId"); - b.Property("RoomId") + b.Property("RoomId") .HasColumnType("uuid"); b.HasKey("Id"); @@ -281,6 +290,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("uuid"); b.Property("Email") + .IsRequired() .HasMaxLength(320) .HasColumnType("character varying(320)"); @@ -330,6 +340,15 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("Users"); }); + modelBuilder.Entity("Domain.Entities.Department", b => + { + b.HasOne("Domain.Entities.Physical.Room", "Room") + .WithOne("Department") + .HasForeignKey("Domain.Entities.Department", "RoomId"); + + b.Navigation("Room"); + }); + modelBuilder.Entity("Domain.Entities.Physical.Borrow", b => { b.HasOne("Domain.Entities.User", "Borrower") @@ -402,9 +421,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasOne("Domain.Entities.Physical.Room", "Room") .WithOne("Staff") - .HasForeignKey("Domain.Entities.Physical.Staff", "RoomId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); + .HasForeignKey("Domain.Entities.Physical.Staff", "RoomId"); b.Navigation("Room"); @@ -443,6 +460,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("Domain.Entities.Physical.Room", b => { + b.Navigation("Department"); + b.Navigation("Lockers"); b.Navigation("Staff"); From 0febce982779793ad7d6f531c8013966f3e477a2 Mon Sep 17 00:00:00 2001 From: Nguyen Quang Chien Date: Sun, 28 May 2023 07:28:25 +0700 Subject: [PATCH 07/11] fix: add folder tests --- .../Folders/Commands/AddFolderTests.cs | 219 ++++++------------ 1 file changed, 69 insertions(+), 150 deletions(-) diff --git a/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs b/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs index cd6328e3..f266077d 100644 --- a/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs +++ b/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs @@ -5,26 +5,12 @@ using Domain.Exceptions; using FluentAssertions; using Xunit; -using Command = Application.Lockers.Commands.Add.Command; +using Application.Folders.Commands.Add; namespace Application.Tests.Integration.Folders.Commands; public class AddFolderTests : BaseClassFixture { - private readonly Faker _folderGenerator = new Faker() - .RuleFor(f => f.Name, faker => faker.Commerce.ProductName()) - .RuleFor(f => f.Description, faker => faker.Commerce.ProductDescription()) - .RuleFor(f => f.Capacity, faker => faker.Random.Int(1,9999)); - - private readonly Faker _roomGenerator = new Faker() - .RuleFor(r => r.Name, faker => faker.Commerce.ProductName()) - .RuleFor(r => r.Description, faker => faker.Commerce.ProductDescription()) - .RuleFor(r => r.Capacity, faker => faker.Random.Int(1,9999)); - - private readonly Faker _lockerGenerator = new Faker() - .RuleFor(l => l.Name, faker => faker.Commerce.ProductName()) - .RuleFor(l => l.Description, faker => faker.Commerce.ProductDescription()) - .RuleFor(l => l.Capacity, faker => faker.Random.Int(1,9999)); public AddFolderTests(CustomApiFactory apiFactory) : base(apiFactory) { } @@ -33,30 +19,24 @@ public AddFolderTests(CustomApiFactory apiFactory) : base(apiFactory) public async Task ShouldAddFolder_WhenAddDetailsAreValid() { // Arrange - var addRoomCommand = _roomGenerator.Generate(); - var room = await SendAsync(addRoomCommand); - - var addLockerCommand = _lockerGenerator.Generate(); - addLockerCommand = addLockerCommand with - { - RoomId = room.Id, - Capacity = 1 - }; - var locker = await SendAsync(addLockerCommand); + var locker = CreateLocker(); + var room = CreateRoom(locker); + await AddAsync(room); - var addFolderCommand = _folderGenerator.Generate(); - addFolderCommand = addFolderCommand with + var command = new Command() { LockerId = locker.Id, - Capacity = 1 + Capacity = 1, + Name = "something" }; // Act - var folder = await SendAsync(addFolderCommand); + var folder = await SendAsync(command); + // Assert - folder.Name.Should().Be(addFolderCommand.Name); - folder.Description.Should().Be(addFolderCommand.Description); - folder.Capacity.Should().Be(addFolderCommand.Capacity); + folder.Name.Should().Be(command.Name); + folder.Description.Should().Be(command.Description); + folder.Capacity.Should().Be(command.Capacity); folder.Locker.Id.Should().Be(locker.Id); folder.Locker.NumberOfFolders.Should().Be(locker.NumberOfFolders + 1); folder.NumberOfDocuments.Should().Be(0); @@ -64,182 +44,121 @@ public async Task ShouldAddFolder_WhenAddDetailsAreValid() // Clean up var folderEntity = await FindAsync(folder.Id); - var lockerEntity = await FindAsync(locker.Id); - var roomEntity = await FindAsync(room.Id); Remove(folderEntity); - Remove(lockerEntity); - Remove(roomEntity); + Remove(locker); + Remove(room); } [Fact] public async Task ShouldAddFolder_WhenFoldersHasSameNameButInDifferentLockers() { // Arrange - var sameFolderName = new Faker().Commerce.ProductName(); - var addRoomCommand = _roomGenerator.Generate(); - addRoomCommand = addRoomCommand with - { - Capacity = 2 - }; - - var room = await SendAsync(addRoomCommand); - - var addLockerCommand = _lockerGenerator.Generate(); + var folder1 = CreateFolder(); + var locker1 = CreateLocker(folder1); + var locker2 = CreateLocker(); + var room = CreateRoom(locker1, locker2); + await AddAsync(room); - var addLockerACommand = addLockerCommand with - { - RoomId = room.Id, - Capacity = 1 - }; - var addLockerBCommand = addLockerCommand with - { - RoomId = room.Id, - Name = new Faker().Commerce.ProductName(), - Capacity = 1 - }; - - var lockerA = await SendAsync(addLockerACommand); - var lockerB = await SendAsync(addLockerBCommand); - - var addFolderCommand = _folderGenerator.Generate(); - var addFolderCommandForLockerA = addFolderCommand with - { - Name = sameFolderName, - LockerId = lockerA.Id - }; - var addFolderCommandForLockerB = addFolderCommand with + var command = new Command() { - Name = sameFolderName, - LockerId = lockerB.Id + LockerId = locker2.Id, + Name = folder1.Name, + Capacity = 3, }; - var folderA = await SendAsync(addFolderCommandForLockerA); // Act - var folderB = await SendAsync(addFolderCommandForLockerB); + var folder2 = await SendAsync(command); // Assert - folderA.Locker.Id.Should().NotBe(folderB.Locker.Id); - folderA.Name.Should().Be(folderB.Name); + folder1.Name.Should().Be(folder2.Name); // Cleanup - var folderAEntity = await FindAsync(folderA.Id); - var folderBEntity = await FindAsync(folderB.Id); - var lockerAEntity = await FindAsync(lockerA.Id); - var lockerBEntity = await FindAsync(lockerB.Id); - var roomEntity = await FindAsync(room.Id); - Remove(folderAEntity); - Remove(folderBEntity); - Remove(lockerAEntity); - Remove(lockerBEntity); - Remove(roomEntity); + Remove(folder1); + Remove(await FindAsync(folder2.Id)); + Remove(locker1); + Remove(locker2); + Remove(room); } [Fact] public async Task ShouldThrowConflictException_WhenFolderAlreadyExistsInTheSameLocker() { // Arrange - var sameFolderName = new Faker().Commerce.ProductName(); - var addRoomCommand = _roomGenerator.Generate(); - var room = await SendAsync(addRoomCommand); - - var addLockerCommand = _lockerGenerator.Generate(); - addLockerCommand = addLockerCommand with - { - RoomId = room.Id, - Capacity = 2 - }; - var locker = await SendAsync(addLockerCommand); - - var addFolderCommand = _folderGenerator.Generate(); - var addFolderCommandForLockerA = addFolderCommand with - { - Name = sameFolderName, - LockerId = locker.Id - }; - var addFolderCommandForLockerB = addFolderCommand with + var folder = CreateFolder(); + var locker = CreateLocker(folder); + var room = CreateRoom(locker); + await AddAsync(room); + + var command = new Command() { - Name = sameFolderName, - LockerId = locker.Id + Name = folder.Name, + LockerId = locker.Id, + Capacity = 3 }; - var folder = await SendAsync(addFolderCommandForLockerA); // Act - var action = async () => await SendAsync(addFolderCommandForLockerB); + var action = async () => await SendAsync(command); // Assert - await action.Should().ThrowAsync().WithMessage("Folder's name already exists."); + await action.Should().ThrowAsync() + .WithMessage("Folder's name already exists."); // Cleanup - var folderEntity = await FindAsync(folder.Id); - var lockerEntity = await FindAsync(locker.Id); - var roomEntity = await FindAsync(room.Id); - Remove(folderEntity); - Remove(lockerEntity); - Remove(roomEntity); + Remove(folder); + Remove(locker); + Remove(room); } [Fact] public async Task ShouldThrowLimitExceededException_WhenGoingOverCapacity() { // Arrange - var addRoomCommand = _roomGenerator.Generate(); - var room = await SendAsync(addRoomCommand); - - var addLockerCommand = _lockerGenerator.Generate(); - addLockerCommand = addLockerCommand with + var folder1 = CreateFolder(); + var folder2 = CreateFolder(); + var folder3 = CreateFolder(); + var locker = CreateLocker(folder1, folder2, folder3); + var room = CreateRoom(locker); + await AddAsync(room); + + var command = new Command() { - RoomId = room.Id, - Capacity = new Faker().Random.Int(1,10) + Name = "something", + Capacity = 3, + LockerId = locker.Id, + Description = "something else", }; - var locker = await SendAsync(addLockerCommand); - var list = new List(); // Act - var action = async () => - { - - for (var i = 0; i <= locker.Capacity; i++) - { - var addFolderCommand = _folderGenerator.Generate(); - addFolderCommand = addFolderCommand with - { - LockerId = locker.Id - }; - list.Add(await SendAsync(addFolderCommand)); - } - }; + var action = async () => await SendAsync(command); // Assert await action.Should().ThrowAsync() .WithMessage("This locker cannot accept more folders."); // Cleanup - foreach (var f in list) - { - var folderEntity = await FindAsync(f.Id); - Remove(folderEntity); - } - var lockerEntity = await FindAsync(locker.Id); - var roomEntity = await FindAsync(room.Id); - Remove(lockerEntity); - Remove(roomEntity); + Remove(folder1); + Remove(folder2); + Remove(folder3); + Remove(locker); + Remove(room); } [Fact] public async Task ShouldThrowKeyNotFoundException_WhenLockerIdNotExists() { // Arrange - var addFolderCommand = _folderGenerator.Generate(); - addFolderCommand = addFolderCommand with + var command = new Command() { - LockerId = Guid.NewGuid() + LockerId = Guid.NewGuid(), + Name = "something", + Capacity = 3 }; // Act - var folder = async () => await SendAsync(addFolderCommand); + var action = async () => await SendAsync(command); // Assert - await folder.Should().ThrowAsync() + await action.Should().ThrowAsync() .WithMessage("Locker does not exist."); } } \ No newline at end of file From e77aec44430506c088882aaa04c39e3733cea6c6 Mon Sep 17 00:00:00 2001 From: Nguyen Quang Chien Date: Sun, 28 May 2023 19:33:43 +0700 Subject: [PATCH 08/11] refactor: again --- src/Api/Controllers/DepartmentsController.cs | 14 +- src/Api/Controllers/DocumentsController.cs | 18 +-- src/Api/Controllers/FoldersController.cs | 24 +-- src/Api/Controllers/LockersController.cs | 18 +-- .../Requests/Users/UpdateUserRequest.cs | 2 - src/Api/Controllers/RoomsController.cs | 24 +-- src/Api/Controllers/StaffsController.cs | 14 +- src/Api/Controllers/UsersController.cs | 24 +-- .../Models/Dtos/Physical}/DocumentItemDto.cs | 3 +- .../Models/Dtos/Physical}/EmptyFolderDto.cs | 2 +- .../Models/Dtos/Physical}/EmptyLockerDto.cs | 3 +- .../Departments/Commands/Add/Command.cs | 45 ------ .../Departments/Commands/AddDepartment.cs | 49 +++++++ .../Departments/Commands/Delete/Command.cs | 37 ----- .../Departments/Commands/DeleteDepartment.cs | 40 +++++ .../Departments/Commands/Update/Command.cs | 10 -- .../Departments/Commands/UpdateDepartment.cs | 13 ++ .../Departments/Queries/GetAll/Query.cs | 29 ---- .../Departments/Queries/GetAllDepartments.cs | 32 ++++ .../Departments/Queries/GetById/Query.cs | 9 -- .../Departments/Queries/GetDepartmentById.cs | 12 ++ .../Documents/Commands/Delete/Command.cs | 9 -- .../Documents/Commands/DeleteDocument.cs | 12 ++ .../Documents/Commands/Import/Command.cs | 73 --------- .../Documents/Commands/ImportDocument.cs | 76 ++++++++++ .../Documents/Commands/Update/Command.cs | 12 -- .../Documents/Commands/UpdateDocument.cs | 15 ++ .../Documents/Queries/GetAllDocumentTypes.cs | 26 ++++ .../Queries/GetAllDocumentsPaginated.cs | 138 ++++++++++++++++++ .../Queries/GetAllPaginated/Query.cs | 110 -------------- .../Queries/GetAllPaginated/Validator.cs | 27 ---- .../Documents/Queries/GetById/Query.cs | 41 ------ .../Documents/Queries/GetDocumentById.cs | 44 ++++++ .../Queries/GetDocumentTypes/Query.cs | 23 --- .../Folders/Commands/Add/Command.cs | 68 --------- .../Folders/Commands/Add/Validator.cs | 27 ---- src/Application/Folders/Commands/AddFolder.cs | 95 ++++++++++++ .../Folders/Commands/Disable/Command.cs | 51 ------- .../Folders/Commands/Disable/Validator.cs | 14 -- .../Folders/Commands/DisableFolder.cs | 66 +++++++++ .../Folders/Commands/Enable/Command.cs | 9 -- .../Folders/Commands/EnableFolder.cs | 12 ++ .../Folders/Commands/Remove/Command.cs | 9 -- .../Folders/Commands/RemoveFolder.cs | 12 ++ .../Folders/Commands/Update/Command.cs | 12 -- .../Folders/Commands/UpdateFolder.cs | 15 ++ .../Folders/Queries/GetAllFoldersPaginated.cs | 18 +++ .../Folders/Queries/GetAllPaginated/Query.cs | 15 -- .../Folders/Queries/GetById/Query.cs | 9 -- .../Folders/Queries/GetFolderById.cs | 12 ++ .../Lockers/Commands/Add/Command.cs | 69 --------- .../Lockers/Commands/Add/Validator.cs | 25 ---- src/Application/Lockers/Commands/AddLocker.cs | 96 ++++++++++++ .../Lockers/Commands/Disable/Command.cs | 63 -------- .../Lockers/Commands/Disable/Validator.cs | 14 -- .../Lockers/Commands/DisableLocker.cs | 78 ++++++++++ .../Lockers/Commands/Enable/Command.cs | 45 ------ .../Lockers/Commands/Enable/Validator.cs | 14 -- .../Lockers/Commands/EnableLocker.cs | 60 ++++++++ .../Lockers/Commands/Remove/Command.cs | 9 -- .../Lockers/Commands/RemoveLocker.cs | 12 ++ .../Lockers/Commands/Update/Command.cs | 12 -- .../Lockers/Commands/UpdateLocker.cs | 15 ++ .../Lockers/Queries/GetAllLockersPaginated.cs | 17 +++ .../Lockers/Queries/GetAllPaginated/Query.cs | 14 -- .../Lockers/Queries/GetById/Query.cs | 9 -- .../Lockers/Queries/GetLockerById.cs | 12 ++ src/Application/Rooms/Commands/Add/Command.cs | 59 -------- .../Rooms/Commands/Add/Validator.cs | 32 ---- src/Application/Rooms/Commands/AddRoom.cs | 91 ++++++++++++ .../Rooms/Commands/Disable/Command.cs | 69 --------- .../Rooms/Commands/Disable/Validator.cs | 14 -- src/Application/Rooms/Commands/DisableRoom.cs | 84 +++++++++++ .../Rooms/Commands/Enable/Command.cs | 9 -- src/Application/Rooms/Commands/EnableRoom.cs | 12 ++ .../Rooms/Commands/Remove/Command.cs | 49 ------- .../Rooms/Commands/Remove/Validator.cs | 14 -- src/Application/Rooms/Commands/RemoveRoom.cs | 64 ++++++++ .../Rooms/Commands/Update/Command.cs | 12 -- src/Application/Rooms/Commands/UpdateRoom.cs | 15 ++ .../Rooms/Queries/GetAllPaginated/Query.cs | 13 -- .../Rooms/Queries/GetAllRoomsPaginated.cs | 16 ++ .../Rooms/Queries/GetById/Query.cs | 9 -- .../Queries/GetEmptyContainersPaginated.cs | 54 +++++++ .../GetEmptyContainersPaginated/Query.cs | 50 ------- src/Application/Rooms/Queries/GetRoomById.cs | 12 ++ .../Staffs/Commands/Add/Command.cs | 48 ------ src/Application/Staffs/Commands/AddStaff.cs | 51 +++++++ .../Staffs/Commands/RemoveFromRoom/Command.cs | 10 -- .../Staffs/Commands/RemoveStaffFromRoom.cs | 13 ++ .../Staffs/Queries/GetAllPaginated/Query.cs | 14 -- .../Staffs/Queries/GetAllStaffsPaginated.cs | 17 +++ .../Staffs/Queries/GetById/Query.cs | 9 -- .../Staffs/Queries/GetByRoom/Query.cs | 9 -- .../Staffs/Queries/GetStaffById.cs | 12 ++ .../Staffs/Queries/GetStaffByRoom.cs | 12 ++ src/Application/Users/Commands/Add/Command.cs | 73 --------- .../Users/Commands/Add/Validator.cs | 43 ------ src/Application/Users/Commands/AddUser.cs | 118 +++++++++++++++ .../Users/Commands/Disable/Command.cs | 44 ------ src/Application/Users/Commands/DisableUser.cs | 47 ++++++ .../Users/Commands/Enable/Command.cs | 9 -- src/Application/Users/Commands/EnableUser.cs | 12 ++ .../Users/Commands/Update/Command.cs | 15 -- src/Application/Users/Commands/UpdateUser.cs | 16 ++ .../Users/Queries/GetAllPaginated/Query.cs | 14 -- .../Users/Queries/GetAllUsersPaginated.cs | 17 +++ .../Users/Queries/GetById/Query.cs | 8 - src/Application/Users/Queries/GetUserById.cs | 11 ++ .../BaseClassFixture.cs | 20 +-- .../Commands/AddDepartmentTests.cs | 17 ++- .../Queries/GetAllDepartmentsTests.cs | 7 +- .../Queries/GetAllDocumentTypesTests.cs | 6 +- .../Queries/GetAllDocumentsPaginatedTests.cs | 28 ++-- .../Folders/Commands/AddFolderTests.cs | 14 +- .../Folders/Commands/DisableFolderTests.cs | 10 +- .../Lockers/Commands/AddLockerTests.cs | 15 +- .../Lockers/Commands/DisableLockerTests.cs | 53 +------ .../Lockers/Commands/EnableLockerTests.cs | 70 ++------- .../Rooms/Commands/DisableRoomTests.cs | 10 +- .../Rooms/Commands/RemoveRoomTests.cs | 8 +- .../GetEmptyContainersPaginatedTests.cs | 10 +- .../Users/Commands/AddUserTests.cs | 43 +++--- .../Common/Mappings/MappingTests.cs | 2 - 124 files changed, 1830 insertions(+), 1819 deletions(-) rename src/Application/{Documents/Queries/GetAllPaginated => Common/Models/Dtos/Physical}/DocumentItemDto.cs (82%) rename src/Application/{Rooms/Queries/GetEmptyContainersPaginated => Common/Models/Dtos/Physical}/EmptyFolderDto.cs (89%) rename src/Application/{Rooms/Queries/GetEmptyContainersPaginated => Common/Models/Dtos/Physical}/EmptyLockerDto.cs (86%) delete mode 100644 src/Application/Departments/Commands/Add/Command.cs create mode 100644 src/Application/Departments/Commands/AddDepartment.cs delete mode 100644 src/Application/Departments/Commands/Delete/Command.cs create mode 100644 src/Application/Departments/Commands/DeleteDepartment.cs delete mode 100644 src/Application/Departments/Commands/Update/Command.cs create mode 100644 src/Application/Departments/Commands/UpdateDepartment.cs delete mode 100644 src/Application/Departments/Queries/GetAll/Query.cs create mode 100644 src/Application/Departments/Queries/GetAllDepartments.cs delete mode 100644 src/Application/Departments/Queries/GetById/Query.cs create mode 100644 src/Application/Departments/Queries/GetDepartmentById.cs delete mode 100644 src/Application/Documents/Commands/Delete/Command.cs create mode 100644 src/Application/Documents/Commands/DeleteDocument.cs delete mode 100644 src/Application/Documents/Commands/Import/Command.cs create mode 100644 src/Application/Documents/Commands/ImportDocument.cs delete mode 100644 src/Application/Documents/Commands/Update/Command.cs create mode 100644 src/Application/Documents/Commands/UpdateDocument.cs create mode 100644 src/Application/Documents/Queries/GetAllDocumentTypes.cs create mode 100644 src/Application/Documents/Queries/GetAllDocumentsPaginated.cs delete mode 100644 src/Application/Documents/Queries/GetAllPaginated/Query.cs delete mode 100644 src/Application/Documents/Queries/GetAllPaginated/Validator.cs delete mode 100644 src/Application/Documents/Queries/GetById/Query.cs create mode 100644 src/Application/Documents/Queries/GetDocumentById.cs delete mode 100644 src/Application/Documents/Queries/GetDocumentTypes/Query.cs delete mode 100644 src/Application/Folders/Commands/Add/Command.cs delete mode 100644 src/Application/Folders/Commands/Add/Validator.cs create mode 100644 src/Application/Folders/Commands/AddFolder.cs delete mode 100644 src/Application/Folders/Commands/Disable/Command.cs delete mode 100644 src/Application/Folders/Commands/Disable/Validator.cs create mode 100644 src/Application/Folders/Commands/DisableFolder.cs delete mode 100644 src/Application/Folders/Commands/Enable/Command.cs create mode 100644 src/Application/Folders/Commands/EnableFolder.cs delete mode 100644 src/Application/Folders/Commands/Remove/Command.cs create mode 100644 src/Application/Folders/Commands/RemoveFolder.cs delete mode 100644 src/Application/Folders/Commands/Update/Command.cs create mode 100644 src/Application/Folders/Commands/UpdateFolder.cs create mode 100644 src/Application/Folders/Queries/GetAllFoldersPaginated.cs delete mode 100644 src/Application/Folders/Queries/GetAllPaginated/Query.cs delete mode 100644 src/Application/Folders/Queries/GetById/Query.cs create mode 100644 src/Application/Folders/Queries/GetFolderById.cs delete mode 100644 src/Application/Lockers/Commands/Add/Command.cs delete mode 100644 src/Application/Lockers/Commands/Add/Validator.cs create mode 100644 src/Application/Lockers/Commands/AddLocker.cs delete mode 100644 src/Application/Lockers/Commands/Disable/Command.cs delete mode 100644 src/Application/Lockers/Commands/Disable/Validator.cs create mode 100644 src/Application/Lockers/Commands/DisableLocker.cs delete mode 100644 src/Application/Lockers/Commands/Enable/Command.cs delete mode 100644 src/Application/Lockers/Commands/Enable/Validator.cs create mode 100644 src/Application/Lockers/Commands/EnableLocker.cs delete mode 100644 src/Application/Lockers/Commands/Remove/Command.cs create mode 100644 src/Application/Lockers/Commands/RemoveLocker.cs delete mode 100644 src/Application/Lockers/Commands/Update/Command.cs create mode 100644 src/Application/Lockers/Commands/UpdateLocker.cs create mode 100644 src/Application/Lockers/Queries/GetAllLockersPaginated.cs delete mode 100644 src/Application/Lockers/Queries/GetAllPaginated/Query.cs delete mode 100644 src/Application/Lockers/Queries/GetById/Query.cs create mode 100644 src/Application/Lockers/Queries/GetLockerById.cs delete mode 100644 src/Application/Rooms/Commands/Add/Command.cs delete mode 100644 src/Application/Rooms/Commands/Add/Validator.cs create mode 100644 src/Application/Rooms/Commands/AddRoom.cs delete mode 100644 src/Application/Rooms/Commands/Disable/Command.cs delete mode 100644 src/Application/Rooms/Commands/Disable/Validator.cs create mode 100644 src/Application/Rooms/Commands/DisableRoom.cs delete mode 100644 src/Application/Rooms/Commands/Enable/Command.cs create mode 100644 src/Application/Rooms/Commands/EnableRoom.cs delete mode 100644 src/Application/Rooms/Commands/Remove/Command.cs delete mode 100644 src/Application/Rooms/Commands/Remove/Validator.cs create mode 100644 src/Application/Rooms/Commands/RemoveRoom.cs delete mode 100644 src/Application/Rooms/Commands/Update/Command.cs create mode 100644 src/Application/Rooms/Commands/UpdateRoom.cs delete mode 100644 src/Application/Rooms/Queries/GetAllPaginated/Query.cs create mode 100644 src/Application/Rooms/Queries/GetAllRoomsPaginated.cs delete mode 100644 src/Application/Rooms/Queries/GetById/Query.cs create mode 100644 src/Application/Rooms/Queries/GetEmptyContainersPaginated.cs delete mode 100644 src/Application/Rooms/Queries/GetEmptyContainersPaginated/Query.cs create mode 100644 src/Application/Rooms/Queries/GetRoomById.cs delete mode 100644 src/Application/Staffs/Commands/Add/Command.cs create mode 100644 src/Application/Staffs/Commands/AddStaff.cs delete mode 100644 src/Application/Staffs/Commands/RemoveFromRoom/Command.cs create mode 100644 src/Application/Staffs/Commands/RemoveStaffFromRoom.cs delete mode 100644 src/Application/Staffs/Queries/GetAllPaginated/Query.cs create mode 100644 src/Application/Staffs/Queries/GetAllStaffsPaginated.cs delete mode 100644 src/Application/Staffs/Queries/GetById/Query.cs delete mode 100644 src/Application/Staffs/Queries/GetByRoom/Query.cs create mode 100644 src/Application/Staffs/Queries/GetStaffById.cs create mode 100644 src/Application/Staffs/Queries/GetStaffByRoom.cs delete mode 100644 src/Application/Users/Commands/Add/Command.cs delete mode 100644 src/Application/Users/Commands/Add/Validator.cs create mode 100644 src/Application/Users/Commands/AddUser.cs delete mode 100644 src/Application/Users/Commands/Disable/Command.cs create mode 100644 src/Application/Users/Commands/DisableUser.cs delete mode 100644 src/Application/Users/Commands/Enable/Command.cs create mode 100644 src/Application/Users/Commands/EnableUser.cs delete mode 100644 src/Application/Users/Commands/Update/Command.cs create mode 100644 src/Application/Users/Commands/UpdateUser.cs delete mode 100644 src/Application/Users/Queries/GetAllPaginated/Query.cs create mode 100644 src/Application/Users/Queries/GetAllUsersPaginated.cs delete mode 100644 src/Application/Users/Queries/GetById/Query.cs create mode 100644 src/Application/Users/Queries/GetUserById.cs diff --git a/src/Api/Controllers/DepartmentsController.cs b/src/Api/Controllers/DepartmentsController.cs index a86c719b..ff481f66 100644 --- a/src/Api/Controllers/DepartmentsController.cs +++ b/src/Api/Controllers/DepartmentsController.cs @@ -1,11 +1,11 @@ using Api.Controllers.Payload.Requests.Departments; using Application.Common.Models; +using Application.Departments.Commands; +using Application.Departments.Queries; using Application.Identity; using Application.Users.Queries; using Infrastructure.Identity.Authorization; using Microsoft.AspNetCore.Mvc; -using DepartmentQueries = Application.Departments.Queries; -using DepartmentCommands = Application.Departments.Commands; namespace Api.Controllers; @@ -22,7 +22,7 @@ public class DepartmentsController : ApiControllerBase [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> GetById([FromRoute] Guid departmentId) { - var query = new DepartmentQueries.GetById.Query() + var query = new GetDepartmentById.Query() { DepartmentId = departmentId }; @@ -39,7 +39,7 @@ public async Task>> GetById([FromRoute] Guid [ProducesResponseType(StatusCodes.Status403Forbidden)] public async Task>>> GetAll() { - var result = await Mediator.Send(new DepartmentQueries.GetAll.Query()); + var result = await Mediator.Send(new GetAllDepartments.Query()); return Ok(Result>.Succeed(result)); } @@ -55,7 +55,7 @@ public async Task>>> GetAll() [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> Add([FromBody] AddDepartmentRequest request) { - var command = new DepartmentCommands.Add.Command() + var command = new AddDepartment.Command() { Name = request.Name, }; @@ -76,7 +76,7 @@ public async Task>> Add([FromBody] AddDepartm [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> Update([FromRoute] Guid departmentId, [FromBody] UpdateDepartmentRequest request) { - var command = new DepartmentCommands.Update.Command() + var command = new UpdateDepartment.Command() { DepartmentId = departmentId, Name = request.Name @@ -97,7 +97,7 @@ public async Task>> Update([FromRoute] Guid d [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> Delete([FromRoute] Guid departmentId) { - var command = new DepartmentCommands.Delete.Command() + var command = new DeleteDepartment.Command() { DepartmentId = departmentId, }; diff --git a/src/Api/Controllers/DocumentsController.cs b/src/Api/Controllers/DocumentsController.cs index f3ea9e99..5c56986b 100644 --- a/src/Api/Controllers/DocumentsController.cs +++ b/src/Api/Controllers/DocumentsController.cs @@ -1,11 +1,11 @@ using Api.Controllers.Payload.Requests.Documents; using Application.Common.Models; using Application.Common.Models.Dtos.Physical; +using Application.Documents.Commands; +using Application.Documents.Queries; using Application.Identity; using Infrastructure.Identity.Authorization; using Microsoft.AspNetCore.Mvc; -using DocumentCommands = Application.Documents.Commands; -using DocumentQueries = Application.Documents.Queries; namespace Api.Controllers; @@ -20,9 +20,9 @@ public class DocumentsController : ApiControllerBase [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task>> GetById(Guid documentId) + public async Task>> GetById([FromRoute] Guid documentId) { - var query = new DocumentQueries.GetById.Query() + var query = new GetDocumentById.Query() { DocumentId = documentId, }; @@ -44,7 +44,7 @@ public async Task>> GetById(Guid documentId) public async Task>>> GetAllPaginated( [FromQuery] GetAllDocumentsPaginatedQueryParameters queryParameters) { - var query = new DocumentQueries.GetAllPaginated.Query() + var query = new GetAllDocumentsPaginated.Query() { RoomId = queryParameters.RoomId, LockerId = queryParameters.LockerId, @@ -69,7 +69,7 @@ public async Task>>> GetAllPagina [ProducesResponseType(StatusCodes.Status403Forbidden)] public async Task>>> GetAllDocumentTypes() { - var result = await Mediator.Send(new DocumentQueries.GetDocumentTypes.Query()); + var result = await Mediator.Send(new GetAllDocumentTypes.Query()); return Ok(Result>.Succeed(result)); } @@ -87,7 +87,7 @@ public async Task>>> GetAllDocumentTypes [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> Import([FromBody] ImportDocumentRequest request) { - var command = new DocumentCommands.Import.Command() + var command = new ImportDocument.Command() { Title = request.Title, Description = request.Description, @@ -113,7 +113,7 @@ public async Task>> Import([FromBody] ImportDoc [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> Update([FromRoute] Guid documentId, [FromBody] UpdateDocumentRequest request) { - var query = new DocumentCommands.Update.Command() + var query = new UpdateDocument.Command() { DocumentId = documentId, Title = request.Title, @@ -135,7 +135,7 @@ public async Task>> Update([FromRoute] Guid doc [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> Delete([FromRoute] Guid documentId) { - var query = new DocumentCommands.Delete.Command() + var query = new DeleteDocument.Command() { DocumentId = documentId, }; diff --git a/src/Api/Controllers/FoldersController.cs b/src/Api/Controllers/FoldersController.cs index 6155ad45..3365ec81 100644 --- a/src/Api/Controllers/FoldersController.cs +++ b/src/Api/Controllers/FoldersController.cs @@ -1,11 +1,11 @@ using Api.Controllers.Payload.Requests.Folders; using Application.Common.Models; using Application.Common.Models.Dtos.Physical; +using Application.Folders.Commands; +using Application.Folders.Queries; using Application.Identity; using Infrastructure.Identity.Authorization; using Microsoft.AspNetCore.Mvc; -using FolderCommands = Application.Folders.Commands; -using FolderQueries = Application.Folders.Queries; namespace Api.Controllers; @@ -23,9 +23,9 @@ public class FoldersController : ApiControllerBase [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> GetById([FromRoute] Guid folderId) { - var query = new FolderQueries.GetById.Query() + var query = new GetFolderById.Query() { - FolderId = folderId + FolderId = folderId, }; var result = await Mediator.Send(query); return Ok(Result.Succeed(result)); @@ -43,7 +43,7 @@ public async Task>> GetById([FromRoute] Guid fold public async Task>>> GetAllPaginated( [FromQuery] GetAllFoldersPaginatedQueryParameters queryParameters) { - var query = new FolderQueries.GetAllPaginated.Query() + var query = new GetAllFoldersPaginated.Query() { RoomId = queryParameters.RoomId, LockerId = queryParameters.LockerId, @@ -70,7 +70,7 @@ public async Task>>> GetAllPaginate [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> AddFolder([FromBody] AddFolderRequest request) { - var command = new FolderCommands.Add.Command() + var command = new AddFolder.Command() { Name = request.Name, Description = request.Description, @@ -95,7 +95,7 @@ public async Task>> AddFolder([FromBody] AddFolde [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> RemoveFolder([FromRoute] Guid folderId) { - var command = new FolderCommands.Remove.Command() + var command = new RemoveFolder.Command() { FolderId = folderId, }; @@ -117,7 +117,7 @@ public async Task>> RemoveFolder([FromRoute] Guid [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> EnableFolder([FromRoute] Guid folderId) { - var command = new FolderCommands.Enable.Command() + var command = new EnableFolder.Command() { FolderId = folderId, }; @@ -139,9 +139,9 @@ public async Task>> EnableFolder([FromRoute] Guid [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> DisableFolder([FromRoute] Guid folderId) { - var command = new FolderCommands.Disable.Command() + var command = new DisableFolder.Command() { - FolderId = folderId + FolderId = folderId, }; var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); @@ -160,12 +160,12 @@ public async Task>> DisableFolder([FromRoute] Gui [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> Update([FromRoute] Guid folderId, [FromBody] UpdateFolderRequest request) { - var command = new FolderCommands.Update.Command() + var command = new UpdateFolder.Command() { FolderId = folderId, Name = request.Name, Description = request.Description, - Capacity = request.Capacity + Capacity = request.Capacity, }; var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); diff --git a/src/Api/Controllers/LockersController.cs b/src/Api/Controllers/LockersController.cs index 55740894..373a0cee 100644 --- a/src/Api/Controllers/LockersController.cs +++ b/src/Api/Controllers/LockersController.cs @@ -2,10 +2,10 @@ using Application.Common.Models; using Application.Common.Models.Dtos.Physical; using Application.Identity; +using Application.Lockers.Commands; +using Application.Lockers.Queries; using Infrastructure.Identity.Authorization; using Microsoft.AspNetCore.Mvc; -using LockerCommands = Application.Lockers.Commands; -using LockerQueries = Application.Lockers.Queries; namespace Api.Controllers; @@ -22,7 +22,7 @@ public class LockersController : ApiControllerBase [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> GetById([FromRoute] Guid lockerId) { - var query = new LockerQueries.GetById.Query() + var query = new GetLockerById.Query() { LockerId = lockerId, }; @@ -41,7 +41,7 @@ public async Task>> GetById([FromRoute] Guid lock public async Task>>> GetAllPaginated( [FromQuery] GetAllLockersPaginatedQueryParameters queryParameters) { - var query = new LockerQueries.GetAllPaginated.Query() + var query = new GetAllLockersPaginated.Query() { RoomId = queryParameters.RoomId, Page = queryParameters.Page, @@ -67,7 +67,7 @@ public async Task>>> GetAllPaginate [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> Add([FromBody] AddLockerRequest request) { - var command = new LockerCommands.Add.Command() + var command = new AddLocker.Command() { Name = request.Name, Description = request.Description, @@ -90,7 +90,7 @@ public async Task>> Add([FromBody] AddLockerReque [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> Remove([FromRoute] Guid lockerId) { - var command = new LockerCommands.Remove.Command() + var command = new RemoveLocker.Command() { LockerId = lockerId, }; @@ -112,7 +112,7 @@ public async Task>> Remove([FromRoute] Guid locke [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> Enable([FromRoute] Guid lockerId) { - var command = new LockerCommands.Enable.Command() + var command = new EnableLocker.Command() { LockerId = lockerId, }; @@ -134,7 +134,7 @@ public async Task>> Enable([FromRoute] Guid locke [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> Disable([FromRoute] Guid lockerId) { - var command = new LockerCommands.Disable.Command() + var command = new DisableLocker.Command() { LockerId = lockerId, }; @@ -155,7 +155,7 @@ public async Task>> Disable([FromRoute] Guid lock [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> Update([FromRoute] Guid lockerId, [FromBody] UpdateLockerRequest request) { - var command = new LockerCommands.Update.Command() + var command = new UpdateLocker.Command() { LockerId = lockerId, Name = request.Name, diff --git a/src/Api/Controllers/Payload/Requests/Users/UpdateUserRequest.cs b/src/Api/Controllers/Payload/Requests/Users/UpdateUserRequest.cs index 77bcb0e4..c1f113d6 100644 --- a/src/Api/Controllers/Payload/Requests/Users/UpdateUserRequest.cs +++ b/src/Api/Controllers/Payload/Requests/Users/UpdateUserRequest.cs @@ -2,8 +2,6 @@ namespace Api.Controllers.Payload.Requests.Users; public class UpdateUserRequest { - public string Username { get; set; } = null!; - public string Email { get; set; } = null!; public string? FirstName { get; set; } public string? LastName { get; set; } public string Role { get; set; } = null!; diff --git a/src/Api/Controllers/RoomsController.cs b/src/Api/Controllers/RoomsController.cs index 6c23a765..7c98b984 100644 --- a/src/Api/Controllers/RoomsController.cs +++ b/src/Api/Controllers/RoomsController.cs @@ -3,10 +3,10 @@ using Application.Common.Models; using Application.Common.Models.Dtos.Physical; using Application.Identity; +using Application.Rooms.Commands; +using Application.Rooms.Queries; using Infrastructure.Identity.Authorization; using Microsoft.AspNetCore.Mvc; -using RoomCommands = Application.Rooms.Commands; -using RoomQueries = Application.Rooms.Queries; namespace Api.Controllers; @@ -23,7 +23,7 @@ public class RoomsController : ApiControllerBase [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> GetById([FromRoute] Guid roomId) { - var query = new RoomQueries.GetById.Query() + var query = new GetRoomById.Query() { RoomId = roomId, }; @@ -42,7 +42,7 @@ public async Task>> GetById([FromRoute] Guid roomId public async Task>>> GetAllPaginated( [FromQuery] GetAllLockersPaginatedQueryParameters queryParameters) { - var query = new RoomQueries.GetAllPaginated.Query() + var query = new GetAllRoomsPaginated.Query() { Page = queryParameters.Page, Size = queryParameters.Size, @@ -63,18 +63,18 @@ public async Task>>> GetAllPaginated( [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task>> GetEmptyContainers( + public async Task>> GetEmptyContainers( [FromRoute] Guid roomId, [FromQuery] GetEmptyContainersPaginatedQueryParameters queryParameters) { - var query = new RoomQueries.GetEmptyContainersPaginated.Query() + var query = new GetEmptyContainersPaginated.Query() { RoomId = roomId, Page = queryParameters.Page, Size = queryParameters.Size, }; var result = await Mediator.Send(query); - return Ok(Result>.Succeed(result)); + return Ok(Result>.Succeed(result)); } /// @@ -91,7 +91,7 @@ public async Task>>> GetAllPaginated( [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> AddRoom([FromBody] AddRoomRequest request) { - var command = new RoomCommands.Add.Command() + var command = new AddRoom.Command() { Name = request.Name, Description = request.Description, @@ -114,7 +114,7 @@ public async Task>> AddRoom([FromBody] AddRoomReque [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> RemoveRoom([FromRoute] Guid roomId) { - var command = new RoomCommands.Remove.Command() + var command = new RemoveRoom.Command() { RoomId = roomId, }; @@ -134,7 +134,7 @@ public async Task>> RemoveRoom([FromRoute] Guid roo [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> EnableRoom([FromRoute] Guid roomId) { - var command = new RoomCommands.Enable.Command() + var command = new EnableRoom.Command() { RoomId = roomId, }; @@ -155,7 +155,7 @@ public async Task>> EnableRoom([FromRoute] Guid roo [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> DisableRoom([FromRoute] Guid roomId) { - var command = new RoomCommands.Disable.Command() + var command = new DisableRoom.Command() { RoomId = roomId, }; @@ -176,7 +176,7 @@ public async Task>> DisableRoom([FromRoute] Guid ro [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> Update([FromRoute] Guid roomId, [FromBody] UpdateRoomRequest request) { - var command = new RoomCommands.Update.Command() + var command = new UpdateRoom.Command() { RoomId = roomId, Name = request.Name, diff --git a/src/Api/Controllers/StaffsController.cs b/src/Api/Controllers/StaffsController.cs index 4edac7c7..71dc888f 100644 --- a/src/Api/Controllers/StaffsController.cs +++ b/src/Api/Controllers/StaffsController.cs @@ -2,10 +2,10 @@ using Application.Common.Models; using Application.Common.Models.Dtos.Physical; using Application.Identity; +using Application.Staffs.Commands; +using Application.Staffs.Queries; using Infrastructure.Identity.Authorization; using Microsoft.AspNetCore.Mvc; -using StaffCommands = Application.Staffs.Commands; -using StaffQueries = Application.Staffs.Queries; namespace Api.Controllers; @@ -22,7 +22,7 @@ public class StaffsController : ApiControllerBase [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> GetById([FromRoute] Guid staffId) { - var query = new StaffQueries.GetById.Query() + var query = new GetStaffById.Query() { StaffId = staffId }; @@ -41,7 +41,7 @@ public async Task>> GetById([FromRoute] Guid staff [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> GetByRoom([FromRoute] Guid roomId) { - var query = new StaffQueries.GetByRoom.Query() + var query = new GetStaffByRoom.Query() { RoomId = roomId }; @@ -60,7 +60,7 @@ public async Task>> GetByRoom([FromRoute] Guid roo public async Task>>> GetAllPaginated( [FromQuery] GetAllStaffsPaginatedQueryParameters queryParameters) { - var query = new StaffQueries.GetAllPaginated.Query() + var query = new GetAllStaffsPaginated.Query() { Page = queryParameters.Page, Size = queryParameters.Size, @@ -83,7 +83,7 @@ public async Task>>> GetAllPaginated [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> Add([FromBody] AddStaffRequest request) { - var command = new StaffCommands.Add.Command() + var command = new AddStaff.Command() { RoomId = request.RoomId, UserId = request.UserId, @@ -106,7 +106,7 @@ public async Task>> RemoveFromRoom( [FromRoute] Guid staffId, [FromBody] RemoveStaffFromRoomRequest request) { - var command = new StaffCommands.RemoveFromRoom.Command() + var command = new RemoveStaffFromRoom.Command() { StaffId = staffId, RoomId = request.RoomId, diff --git a/src/Api/Controllers/UsersController.cs b/src/Api/Controllers/UsersController.cs index f514c935..dc2b406e 100644 --- a/src/Api/Controllers/UsersController.cs +++ b/src/Api/Controllers/UsersController.cs @@ -1,18 +1,10 @@ using Api.Controllers.Payload.Requests.Users; using Application.Common.Models; -using Application.Common.Models.Dtos.Physical; using Application.Identity; -using Application.Users.Commands.Add; -using Application.Users.Commands.Disable; -using Application.Users.Commands.Update; +using Application.Users.Commands; using Application.Users.Queries; -using Application.Users.Queries.GetAllPaginated; -using Application.Users.Queries.GetById; using Infrastructure.Identity.Authorization; -using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -using UserCommands = Application.Users.Commands; -using UserQueries = Application.Users.Queries; namespace Api.Controllers; @@ -29,7 +21,7 @@ public class UsersController : ApiControllerBase [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> GetById([FromRoute] Guid userId) { - var query = new UserQueries.GetById.Query + var query = new GetUserById.Query { UserId = userId, }; @@ -48,7 +40,7 @@ public async Task>> GetById([FromRoute] Guid userId public async Task>>> GetAllPaginated( [FromQuery] GetAllUsersPaginatedQueryParameters queryParameters) { - var query = new UserQueries.GetAllPaginated.Query() + var query = new GetAllUsersPaginated.Query() { DepartmentId = queryParameters.DepartmentId, SearchTerm = queryParameters.SearchTerm, @@ -75,7 +67,7 @@ public async Task>>> GetAllPaginated( [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> Add([FromBody] AddUserRequest request) { - var command = new UserCommands.Add.Command() + var command = new AddUser.Command() { Username = request.Username, Email = request.Email, @@ -102,7 +94,7 @@ public async Task>> Add([FromBody] AddUserRequest r [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> Enable([FromRoute] Guid userId) { - var command = new UserCommands.Enable.Command() + var command = new EnableUser.Command() { UserId = userId }; @@ -123,7 +115,7 @@ public async Task>> Enable([FromRoute] Guid userId) [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> Disable([FromRoute] Guid userId) { - var command = new UserCommands.Disable.Command() + var command = new DisableUser.Command() { UserId = userId, }; @@ -144,11 +136,9 @@ public async Task>> Disable([FromRoute] Guid userId [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task>> Update([FromRoute] Guid userId, [FromBody] UpdateUserRequest request) { - var command = new UserCommands.Update.Command() + var command = new UpdateUser.Command() { UserId = userId, - Username = request.Username, - Email = request.Email, FirstName = request.FirstName, LastName = request.LastName, Role = request.Role, diff --git a/src/Application/Documents/Queries/GetAllPaginated/DocumentItemDto.cs b/src/Application/Common/Models/Dtos/Physical/DocumentItemDto.cs similarity index 82% rename from src/Application/Documents/Queries/GetAllPaginated/DocumentItemDto.cs rename to src/Application/Common/Models/Dtos/Physical/DocumentItemDto.cs index 5eae4124..a9e3e455 100644 --- a/src/Application/Documents/Queries/GetAllPaginated/DocumentItemDto.cs +++ b/src/Application/Common/Models/Dtos/Physical/DocumentItemDto.cs @@ -1,9 +1,8 @@ using Application.Common.Mappings; -using Application.Common.Models.Dtos.Physical; using Application.Users.Queries; using Domain.Entities.Physical; -namespace Application.Documents.Queries.GetAllPaginated; +namespace Application.Common.Models.Dtos.Physical; [Obsolete] public class DocumentItemDto : IMapFrom diff --git a/src/Application/Rooms/Queries/GetEmptyContainersPaginated/EmptyFolderDto.cs b/src/Application/Common/Models/Dtos/Physical/EmptyFolderDto.cs similarity index 89% rename from src/Application/Rooms/Queries/GetEmptyContainersPaginated/EmptyFolderDto.cs rename to src/Application/Common/Models/Dtos/Physical/EmptyFolderDto.cs index 0398e867..10e77646 100644 --- a/src/Application/Rooms/Queries/GetEmptyContainersPaginated/EmptyFolderDto.cs +++ b/src/Application/Common/Models/Dtos/Physical/EmptyFolderDto.cs @@ -2,7 +2,7 @@ using AutoMapper; using Domain.Entities.Physical; -namespace Application.Rooms.Queries.GetEmptyContainersPaginated; +namespace Application.Common.Models.Dtos.Physical; public class EmptyFolderDto : IMapFrom { diff --git a/src/Application/Rooms/Queries/GetEmptyContainersPaginated/EmptyLockerDto.cs b/src/Application/Common/Models/Dtos/Physical/EmptyLockerDto.cs similarity index 86% rename from src/Application/Rooms/Queries/GetEmptyContainersPaginated/EmptyLockerDto.cs rename to src/Application/Common/Models/Dtos/Physical/EmptyLockerDto.cs index f9f80d7b..6d7537c7 100644 --- a/src/Application/Rooms/Queries/GetEmptyContainersPaginated/EmptyLockerDto.cs +++ b/src/Application/Common/Models/Dtos/Physical/EmptyLockerDto.cs @@ -1,9 +1,8 @@ using Application.Common.Mappings; -using Application.Common.Models.Dtos.Physical; using AutoMapper; using Domain.Entities.Physical; -namespace Application.Rooms.Queries.GetEmptyContainersPaginated; +namespace Application.Common.Models.Dtos.Physical; public class EmptyLockerDto : IMapFrom { diff --git a/src/Application/Departments/Commands/Add/Command.cs b/src/Application/Departments/Commands/Add/Command.cs deleted file mode 100644 index 1c7f043e..00000000 --- a/src/Application/Departments/Commands/Add/Command.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Application.Common.Exceptions; -using Application.Common.Interfaces; -using Application.Users.Queries; -using AutoMapper; -using Domain.Entities; -using MediatR; -using Microsoft.EntityFrameworkCore; - -namespace Application.Departments.Commands.Add; - -public record Command : IRequest -{ - public string Name { get; init; } = null!; -} - -public class AddDepartmentCommandHandler : IRequestHandler -{ - private readonly IApplicationDbContext _context; - private readonly IMapper _mapper; - public AddDepartmentCommandHandler(IApplicationDbContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - - public async Task Handle(Command request, CancellationToken cancellationToken) - { - var department = await _context.Departments.FirstOrDefaultAsync(x - => x.Name.Trim().ToLower().Equals(request.Name.Trim().ToLower()), cancellationToken); - - if (department is not null) - { - throw new ConflictException("Department name already exists."); - } - - var entity = new Department - { - Name = request.Name - }; - - var result = await _context.Departments.AddAsync(entity, cancellationToken); - await _context.SaveChangesAsync(cancellationToken); - return _mapper.Map(result.Entity); - } -} \ No newline at end of file diff --git a/src/Application/Departments/Commands/AddDepartment.cs b/src/Application/Departments/Commands/AddDepartment.cs new file mode 100644 index 00000000..a321afb6 --- /dev/null +++ b/src/Application/Departments/Commands/AddDepartment.cs @@ -0,0 +1,49 @@ +using Application.Common.Exceptions; +using Application.Common.Interfaces; +using Application.Users.Queries; +using AutoMapper; +using Domain.Entities; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace Application.Departments.Commands; + +public class AddDepartment +{ + public record Command : IRequest + { + public string Name { get; init; } = null!; + } + + public class AddDepartmentCommandHandler : IRequestHandler + { + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + + public AddDepartmentCommandHandler(IApplicationDbContext context, IMapper mapper) + { + _context = context; + _mapper = mapper; + } + + public async Task Handle(Command request, CancellationToken cancellationToken) + { + var department = await _context.Departments.FirstOrDefaultAsync(x + => x.Name.Trim().ToLower().Equals(request.Name.Trim().ToLower()), cancellationToken); + + if (department is not null) + { + throw new ConflictException("Department name already exists."); + } + + var entity = new Department + { + Name = request.Name + }; + + var result = await _context.Departments.AddAsync(entity, cancellationToken); + await _context.SaveChangesAsync(cancellationToken); + return _mapper.Map(result.Entity); + } + } +} \ No newline at end of file diff --git a/src/Application/Departments/Commands/Delete/Command.cs b/src/Application/Departments/Commands/Delete/Command.cs deleted file mode 100644 index 840cdc42..00000000 --- a/src/Application/Departments/Commands/Delete/Command.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Application.Common.Interfaces; -using Application.Users.Queries; -using AutoMapper; -using MediatR; -using Microsoft.EntityFrameworkCore; - -namespace Application.Departments.Commands.Delete; - -public record Command : IRequest -{ - public Guid DepartmentId { get; init; } -} - -public class CommandHandler : IRequestHandler -{ - private readonly IApplicationDbContext _context; - private readonly IMapper _mapper; - public CommandHandler(IApplicationDbContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - - public async Task Handle(Command request, CancellationToken cancellationToken) - { - var department = await _context.Departments.FirstOrDefaultAsync(x => x.Id == request.DepartmentId, cancellationToken); - - if (department is null) - { - throw new KeyNotFoundException("Department does not exist."); - } - - var result = _context.Departments.Remove(department); - await _context.SaveChangesAsync(cancellationToken); - return _mapper.Map(result.Entity); - } -} \ No newline at end of file diff --git a/src/Application/Departments/Commands/DeleteDepartment.cs b/src/Application/Departments/Commands/DeleteDepartment.cs new file mode 100644 index 00000000..ad8b0d8a --- /dev/null +++ b/src/Application/Departments/Commands/DeleteDepartment.cs @@ -0,0 +1,40 @@ +using Application.Common.Interfaces; +using Application.Users.Queries; +using AutoMapper; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace Application.Departments.Commands; + +public class DeleteDepartment +{ + public record Command : IRequest + { + public Guid DepartmentId { get; init; } + } + + public class CommandHandler : IRequestHandler + { + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + public CommandHandler(IApplicationDbContext context, IMapper mapper) + { + _context = context; + _mapper = mapper; + } + + public async Task Handle(Command request, CancellationToken cancellationToken) + { + var department = await _context.Departments.FirstOrDefaultAsync(x => x.Id == request.DepartmentId, cancellationToken); + + if (department is null) + { + throw new KeyNotFoundException("Department does not exist."); + } + + var result = _context.Departments.Remove(department); + await _context.SaveChangesAsync(cancellationToken); + return _mapper.Map(result.Entity); + } + } +} \ No newline at end of file diff --git a/src/Application/Departments/Commands/Update/Command.cs b/src/Application/Departments/Commands/Update/Command.cs deleted file mode 100644 index 214df268..00000000 --- a/src/Application/Departments/Commands/Update/Command.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Application.Users.Queries; -using MediatR; - -namespace Application.Departments.Commands.Update; - -public record Command : IRequest -{ - public Guid DepartmentId { get; set; } - public string Name { get; init; } = null!; -} \ No newline at end of file diff --git a/src/Application/Departments/Commands/UpdateDepartment.cs b/src/Application/Departments/Commands/UpdateDepartment.cs new file mode 100644 index 00000000..68863f7e --- /dev/null +++ b/src/Application/Departments/Commands/UpdateDepartment.cs @@ -0,0 +1,13 @@ +using Application.Users.Queries; +using MediatR; + +namespace Application.Departments.Commands; + +public class UpdateDepartment +{ + public record Command : IRequest + { + public Guid DepartmentId { get; set; } + public string Name { get; init; } = null!; + } +} \ No newline at end of file diff --git a/src/Application/Departments/Queries/GetAll/Query.cs b/src/Application/Departments/Queries/GetAll/Query.cs deleted file mode 100644 index 42da4085..00000000 --- a/src/Application/Departments/Queries/GetAll/Query.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Collections.ObjectModel; -using Application.Common.Interfaces; -using Application.Users.Queries; -using AutoMapper; -using MediatR; -using Microsoft.EntityFrameworkCore; - -namespace Application.Departments.Queries.GetAll; - -public record Query : IRequest>; - -public class QueryHandler : IRequestHandler> -{ - private readonly IApplicationDbContext _context; - private readonly IMapper _mapper; - - public QueryHandler(IApplicationDbContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - - public async Task> Handle(Query request, CancellationToken cancellationToken) - { - var departments = await _context.Departments.ToListAsync(cancellationToken); - var result = new ReadOnlyCollection(_mapper.Map>(departments)); - return result; - } -} \ No newline at end of file diff --git a/src/Application/Departments/Queries/GetAllDepartments.cs b/src/Application/Departments/Queries/GetAllDepartments.cs new file mode 100644 index 00000000..5832ca48 --- /dev/null +++ b/src/Application/Departments/Queries/GetAllDepartments.cs @@ -0,0 +1,32 @@ +using System.Collections.ObjectModel; +using Application.Common.Interfaces; +using Application.Users.Queries; +using AutoMapper; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace Application.Departments.Queries; + +public class GetAllDepartments +{ + public record Query : IRequest>; + + public class QueryHandler : IRequestHandler> + { + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + + public QueryHandler(IApplicationDbContext context, IMapper mapper) + { + _context = context; + _mapper = mapper; + } + + public async Task> Handle(Query request, CancellationToken cancellationToken) + { + var departments = await _context.Departments.ToListAsync(cancellationToken); + var result = new ReadOnlyCollection(_mapper.Map>(departments)); + return result; + } + } +} \ No newline at end of file diff --git a/src/Application/Departments/Queries/GetById/Query.cs b/src/Application/Departments/Queries/GetById/Query.cs deleted file mode 100644 index 4748a984..00000000 --- a/src/Application/Departments/Queries/GetById/Query.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Application.Users.Queries; -using MediatR; - -namespace Application.Departments.Queries.GetById; - -public record Query : IRequest -{ - public Guid DepartmentId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Departments/Queries/GetDepartmentById.cs b/src/Application/Departments/Queries/GetDepartmentById.cs new file mode 100644 index 00000000..cc78ffab --- /dev/null +++ b/src/Application/Departments/Queries/GetDepartmentById.cs @@ -0,0 +1,12 @@ +using Application.Users.Queries; +using MediatR; + +namespace Application.Departments.Queries; + +public class GetDepartmentById +{ + public record Query : IRequest + { + public Guid DepartmentId { get; init; } + } +} \ No newline at end of file diff --git a/src/Application/Documents/Commands/Delete/Command.cs b/src/Application/Documents/Commands/Delete/Command.cs deleted file mode 100644 index 9453adfc..00000000 --- a/src/Application/Documents/Commands/Delete/Command.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Documents.Commands.Delete; - -public record Command : IRequest -{ - public Guid DocumentId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Documents/Commands/DeleteDocument.cs b/src/Application/Documents/Commands/DeleteDocument.cs new file mode 100644 index 00000000..7b22f634 --- /dev/null +++ b/src/Application/Documents/Commands/DeleteDocument.cs @@ -0,0 +1,12 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Documents.Commands; + +public class DeleteDocument +{ + public record Command : IRequest + { + public Guid DocumentId { get; init; } + } +} \ No newline at end of file diff --git a/src/Application/Documents/Commands/Import/Command.cs b/src/Application/Documents/Commands/Import/Command.cs deleted file mode 100644 index 260e0a16..00000000 --- a/src/Application/Documents/Commands/Import/Command.cs +++ /dev/null @@ -1,73 +0,0 @@ -using Application.Common.Exceptions; -using Application.Common.Interfaces; -using Application.Common.Models.Dtos.Physical; -using AutoMapper; -using Domain.Entities.Physical; -using MediatR; -using Microsoft.EntityFrameworkCore; - -namespace Application.Documents.Commands.Import; - -public record Command : IRequest -{ - public string Title { get; init; } = null!; - public string? Description { get; init; } - public string DocumentType { get; init; } = null!; - public Guid ImporterId { get; init; } - public Guid FolderId { get; init; } -} - -public class CommandHandler : IRequestHandler -{ - private readonly IApplicationDbContext _context; - private readonly IMapper _mapper; - - public CommandHandler(IApplicationDbContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - - public async Task Handle(Command request, CancellationToken cancellationToken) - { - var importer = await _context.Users - .Include(x => x.Department) - .FirstOrDefaultAsync(x => x.Id == request.ImporterId, cancellationToken); - if (importer is null) - { - throw new KeyNotFoundException("User does not exist."); - } - - var document = _context.Documents.FirstOrDefault(x => - x.Title.Trim().ToLower().Equals(request.Title.Trim().ToLower()) - && x.Importer != null - && x.Importer.Id == request.ImporterId); - if (document is not null) - { - throw new ConflictException($"Document title already exists for user {importer.LastName}."); - } - - var folder = await _context.Folders - .FirstOrDefaultAsync(x => x.Id == request.FolderId, cancellationToken); - if (folder is null) - { - throw new KeyNotFoundException("Folder does not exist."); - } - - var entity = new Document() - { - Title = request.Title.Trim(), - Description = request.Description?.Trim(), - DocumentType = request.DocumentType.Trim(), - Importer = importer, - Department = importer.Department, - Folder = folder - }; - - var result = await _context.Documents.AddAsync(entity, cancellationToken); - folder.NumberOfDocuments += 1; - _context.Folders.Update(folder); - await _context.SaveChangesAsync(cancellationToken); - return _mapper.Map(result.Entity); - } -} \ No newline at end of file diff --git a/src/Application/Documents/Commands/ImportDocument.cs b/src/Application/Documents/Commands/ImportDocument.cs new file mode 100644 index 00000000..2f5e8c02 --- /dev/null +++ b/src/Application/Documents/Commands/ImportDocument.cs @@ -0,0 +1,76 @@ +using Application.Common.Exceptions; +using Application.Common.Interfaces; +using Application.Common.Models.Dtos.Physical; +using AutoMapper; +using Domain.Entities.Physical; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace Application.Documents.Commands; + +public class ImportDocument +{ + public record Command : IRequest + { + public string Title { get; init; } = null!; + public string? Description { get; init; } + public string DocumentType { get; init; } = null!; + public Guid ImporterId { get; init; } + public Guid FolderId { get; init; } + } + + public class CommandHandler : IRequestHandler + { + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + + public CommandHandler(IApplicationDbContext context, IMapper mapper) + { + _context = context; + _mapper = mapper; + } + + public async Task Handle(Command request, CancellationToken cancellationToken) + { + var importer = await _context.Users + .Include(x => x.Department) + .FirstOrDefaultAsync(x => x.Id == request.ImporterId, cancellationToken); + if (importer is null) + { + throw new KeyNotFoundException("User does not exist."); + } + + var document = _context.Documents.FirstOrDefault(x => + x.Title.Trim().ToLower().Equals(request.Title.Trim().ToLower()) + && x.Importer != null + && x.Importer.Id == request.ImporterId); + if (document is not null) + { + throw new ConflictException($"Document title already exists for user {importer.LastName}."); + } + + var folder = await _context.Folders + .FirstOrDefaultAsync(x => x.Id == request.FolderId, cancellationToken); + if (folder is null) + { + throw new KeyNotFoundException("Folder does not exist."); + } + + var entity = new Document() + { + Title = request.Title.Trim(), + Description = request.Description?.Trim(), + DocumentType = request.DocumentType.Trim(), + Importer = importer, + Department = importer.Department, + Folder = folder + }; + + var result = await _context.Documents.AddAsync(entity, cancellationToken); + folder.NumberOfDocuments += 1; + _context.Folders.Update(folder); + await _context.SaveChangesAsync(cancellationToken); + return _mapper.Map(result.Entity); + } + } +} \ No newline at end of file diff --git a/src/Application/Documents/Commands/Update/Command.cs b/src/Application/Documents/Commands/Update/Command.cs deleted file mode 100644 index c8bc2cb0..00000000 --- a/src/Application/Documents/Commands/Update/Command.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Documents.Commands.Update; - -public record Command : IRequest -{ - public Guid DocumentId { get; init; } - public string Title { get; init; } = null!; - public string? Description { get; init; } - public string DocumentType { get; init; } = null!; -} \ No newline at end of file diff --git a/src/Application/Documents/Commands/UpdateDocument.cs b/src/Application/Documents/Commands/UpdateDocument.cs new file mode 100644 index 00000000..b0cac569 --- /dev/null +++ b/src/Application/Documents/Commands/UpdateDocument.cs @@ -0,0 +1,15 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Documents.Commands; + +public class UpdateDocument +{ + public record Command : IRequest + { + public Guid DocumentId { get; init; } + public string Title { get; init; } = null!; + public string? Description { get; init; } + public string DocumentType { get; init; } = null!; + } +} \ No newline at end of file diff --git a/src/Application/Documents/Queries/GetAllDocumentTypes.cs b/src/Application/Documents/Queries/GetAllDocumentTypes.cs new file mode 100644 index 00000000..41e53d1b --- /dev/null +++ b/src/Application/Documents/Queries/GetAllDocumentTypes.cs @@ -0,0 +1,26 @@ +using System.Collections.ObjectModel; +using Application.Common.Interfaces; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace Application.Documents.Queries; + +public class GetAllDocumentTypes +{ + public record Query : IRequest>; + + public class QueryHandler : IRequestHandler> + { + private readonly IApplicationDbContext _context; + + public QueryHandler(IApplicationDbContext context) + { + _context = context; + } + public async Task> Handle(Query request, CancellationToken cancellationToken) + { + return new ReadOnlyCollection(await _context.Documents.Select(x => x.DocumentType).Distinct() + .ToListAsync(cancellationToken)); + } + } +} \ No newline at end of file diff --git a/src/Application/Documents/Queries/GetAllDocumentsPaginated.cs b/src/Application/Documents/Queries/GetAllDocumentsPaginated.cs new file mode 100644 index 00000000..cc77ee82 --- /dev/null +++ b/src/Application/Documents/Queries/GetAllDocumentsPaginated.cs @@ -0,0 +1,138 @@ +using Application.Common.Exceptions; +using Application.Common.Extensions; +using Application.Common.Interfaces; +using Application.Common.Mappings; +using Application.Common.Models; +using Application.Common.Models.Dtos.Physical; +using AutoMapper; +using AutoMapper.QueryableExtensions; +using FluentValidation; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace Application.Documents.Queries; + +public class GetAllDocumentsPaginated +{ + public class Validator : AbstractValidator + { + public Validator() + { + RuleLevelCascadeMode = CascadeMode.Stop; + + RuleFor(x => x.RoomId) + .Must((query, roomId) => + { + if (roomId is null) + { + return query.LockerId is null && query.FolderId is null; + } + + if (query.LockerId is null) + { + return query.FolderId is null; + } + + return true; + }).WithMessage("Container orientation is not consistent"); + } + } + + public record Query : IRequest> + { + public Guid? RoomId { get; init; } + public Guid? LockerId { get; init; } + public Guid? FolderId { get; init; } + public string? SearchTerm { get; set; } + public int? Page { get; init; } + public int? Size { get; init; } + public string? SortBy { get; init; } + public string? SortOrder { get; init; } + } + + public class QueryHandler : IRequestHandler> + { + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + + public QueryHandler(IApplicationDbContext context, IMapper mapper) + { + _context = context; + _mapper = mapper; + } + + public async Task> Handle(Query request, + CancellationToken cancellationToken) + { + var documents = _context.Documents.AsQueryable(); + var roomExists = request.RoomId is not null; + var lockerExists = request.LockerId is not null; + var folderExists = request.FolderId is not null; + + documents = documents.Include(x => x.Department); + + if (folderExists) + { + var folder = await _context.Folders + .Include(x => x.Locker) + .ThenInclude(y => y.Room) + .FirstOrDefaultAsync(x => x.Id == request.FolderId + && x.IsAvailable, cancellationToken); + if (folder is null) + { + throw new KeyNotFoundException("Folder does not exist."); + } + + if (folder.Locker.Id != request.LockerId + || folder.Locker.Room.Id != request.RoomId) + { + throw new ConflictException("Either locker or room does not match folder."); + } + + documents = documents + .Where(x => x.Folder!.Id == request.FolderId); + } + else if (lockerExists) + { + var locker = await _context.Lockers + .Include(x => x.Room) + .FirstOrDefaultAsync(x => x.Id == request.LockerId + && x.IsAvailable, cancellationToken); + if (locker is null) + { + throw new KeyNotFoundException("Locker does not exist."); + } + + if (locker.Room.Id != request.RoomId) + { + throw new ConflictException("Room does not match locker."); + } + + documents = documents.Where(x => x.Folder!.Locker.Id == request.LockerId); + } + else if (roomExists) + { + var room = await _context.Rooms + .FirstOrDefaultAsync(x => x.Id == request.RoomId + && x.IsAvailable, cancellationToken); + if (room is null) + { + throw new KeyNotFoundException("Room does not exist."); + } + + documents = documents.Where(x => x.Folder!.Locker.Room.Id == request.RoomId); + } + + var sortBy = request.SortBy ?? nameof(DocumentDto.Id); + var sortOrder = request.SortOrder ?? "asc"; + var pageNumber = request.Page ?? 1; + var sizeNumber = request.Size ?? 5; + var result = await documents + .ProjectTo(_mapper.ConfigurationProvider) + .OrderByCustom(sortBy, sortOrder) + .PaginatedListAsync(pageNumber, sizeNumber); + + return result; + } + } +} \ No newline at end of file diff --git a/src/Application/Documents/Queries/GetAllPaginated/Query.cs b/src/Application/Documents/Queries/GetAllPaginated/Query.cs deleted file mode 100644 index f39b14b0..00000000 --- a/src/Application/Documents/Queries/GetAllPaginated/Query.cs +++ /dev/null @@ -1,110 +0,0 @@ -using Application.Common.Exceptions; -using Application.Common.Extensions; -using Application.Common.Interfaces; -using Application.Common.Mappings; -using Application.Common.Models; -using Application.Common.Models.Dtos.Physical; -using AutoMapper; -using AutoMapper.QueryableExtensions; -using MediatR; -using Microsoft.EntityFrameworkCore; - -namespace Application.Documents.Queries.GetAllPaginated; - -public record Query : IRequest> -{ - public Guid? RoomId { get; init; } - public Guid? LockerId { get; init; } - public Guid? FolderId { get; init; } - public string? SearchTerm { get; set; } - public int? Page { get; init; } - public int? Size { get; init; } - public string? SortBy { get; init; } - public string? SortOrder { get; init; } -} - -public class GetAllDocumentsPaginatedQueryHandler : IRequestHandler> -{ - private readonly IApplicationDbContext _context; - private readonly IMapper _mapper; - - public GetAllDocumentsPaginatedQueryHandler(IApplicationDbContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - - public async Task> Handle(Query request, - CancellationToken cancellationToken) - { - var documents = _context.Documents.AsQueryable(); - var roomExists = request.RoomId is not null; - var lockerExists = request.LockerId is not null; - var folderExists = request.FolderId is not null; - - documents = documents.Include(x => x.Department); - - if (folderExists) - { - var folder = await _context.Folders - .Include(x => x.Locker) - .ThenInclude(y => y.Room) - .FirstOrDefaultAsync(x => x.Id == request.FolderId - && x.IsAvailable, cancellationToken); - if (folder is null) - { - throw new KeyNotFoundException("Folder does not exist."); - } - - if (folder.Locker.Id != request.LockerId - || folder.Locker.Room.Id != request.RoomId) - { - throw new ConflictException("Either locker or room does not match folder."); - } - - documents = documents - .Where(x => x.Folder!.Id == request.FolderId); - } - else if (lockerExists) - { - var locker = await _context.Lockers - .Include(x => x.Room) - .FirstOrDefaultAsync(x => x.Id == request.LockerId - && x.IsAvailable, cancellationToken); - if (locker is null) - { - throw new KeyNotFoundException("Locker does not exist."); - } - - if (locker.Room.Id != request.RoomId) - { - throw new ConflictException("Room does not match locker."); - } - - documents = documents.Where(x => x.Folder!.Locker.Id == request.LockerId); - } - else if (roomExists) - { - var room = await _context.Rooms - .FirstOrDefaultAsync(x => x.Id == request.RoomId - && x.IsAvailable, cancellationToken); - if (room is null) - { - throw new KeyNotFoundException("Room does not exist."); - } - - documents = documents.Where(x => x.Folder!.Locker.Room.Id == request.RoomId); - } - - var sortBy = request.SortBy ?? nameof(DocumentDto.Id); - var sortOrder = request.SortOrder ?? "asc"; - var pageNumber = request.Page ?? 1; - var sizeNumber = request.Size ?? 5; - var result = await documents - .ProjectTo(_mapper.ConfigurationProvider) - .OrderByCustom(sortBy, sortOrder) - .PaginatedListAsync(pageNumber, sizeNumber); - - return result; - } -} \ No newline at end of file diff --git a/src/Application/Documents/Queries/GetAllPaginated/Validator.cs b/src/Application/Documents/Queries/GetAllPaginated/Validator.cs deleted file mode 100644 index d5bcd880..00000000 --- a/src/Application/Documents/Queries/GetAllPaginated/Validator.cs +++ /dev/null @@ -1,27 +0,0 @@ -using FluentValidation; - -namespace Application.Documents.Queries.GetAllPaginated; - -public class Validator : AbstractValidator -{ - public Validator() - { - RuleLevelCascadeMode = CascadeMode.Stop; - - RuleFor(x => x.RoomId) - .Must((query, roomId) => - { - if (roomId is null) - { - return query.LockerId is null && query.FolderId is null; - } - - if (query.LockerId is null) - { - return query.FolderId is null; - } - - return true; - }).WithMessage("Container orientation is not consistent"); - } -} \ No newline at end of file diff --git a/src/Application/Documents/Queries/GetById/Query.cs b/src/Application/Documents/Queries/GetById/Query.cs deleted file mode 100644 index ab15e257..00000000 --- a/src/Application/Documents/Queries/GetById/Query.cs +++ /dev/null @@ -1,41 +0,0 @@ -using Application.Common.Interfaces; -using Application.Common.Models.Dtos.Physical; -using AutoMapper; -using MediatR; -using Microsoft.EntityFrameworkCore; - -namespace Application.Documents.Queries.GetById; - -public record Query : IRequest -{ - public Guid DocumentId { get; init; } -} - -public class QueryHandler : IRequestHandler -{ - private readonly IApplicationDbContext _context; - private readonly IMapper _mapper; - - public QueryHandler(IApplicationDbContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - public async Task Handle(Query request, CancellationToken cancellationToken) - { - var document = await _context.Documents - .Include(x => x.Department) - .Include(x => x.Importer) - .Include(x => x.Folder) - .ThenInclude(y => y.Locker) - .ThenInclude(z => z.Room) - .FirstOrDefaultAsync(x => x.Id == request.DocumentId, cancellationToken); - - if (document is null) - { - throw new KeyNotFoundException("Document does not exist."); - } - - return _mapper.Map(document); - } -} \ No newline at end of file diff --git a/src/Application/Documents/Queries/GetDocumentById.cs b/src/Application/Documents/Queries/GetDocumentById.cs new file mode 100644 index 00000000..bf7c29d7 --- /dev/null +++ b/src/Application/Documents/Queries/GetDocumentById.cs @@ -0,0 +1,44 @@ +using Application.Common.Interfaces; +using Application.Common.Models.Dtos.Physical; +using AutoMapper; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace Application.Documents.Queries; + +public class GetDocumentById +{ + public record Query : IRequest + { + public Guid DocumentId { get; init; } + } + + public class QueryHandler : IRequestHandler + { + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + + public QueryHandler(IApplicationDbContext context, IMapper mapper) + { + _context = context; + _mapper = mapper; + } + public async Task Handle(Query request, CancellationToken cancellationToken) + { + var document = await _context.Documents + .Include(x => x.Department) + .Include(x => x.Importer) + .Include(x => x.Folder) + .ThenInclude(y => y.Locker) + .ThenInclude(z => z.Room) + .FirstOrDefaultAsync(x => x.Id == request.DocumentId, cancellationToken); + + if (document is null) + { + throw new KeyNotFoundException("Document does not exist."); + } + + return _mapper.Map(document); + } + } +} \ No newline at end of file diff --git a/src/Application/Documents/Queries/GetDocumentTypes/Query.cs b/src/Application/Documents/Queries/GetDocumentTypes/Query.cs deleted file mode 100644 index c0875551..00000000 --- a/src/Application/Documents/Queries/GetDocumentTypes/Query.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Collections.ObjectModel; -using Application.Common.Interfaces; -using MediatR; -using Microsoft.EntityFrameworkCore; - -namespace Application.Documents.Queries.GetDocumentTypes; - -public record Query : IRequest>; - -public class QueryHandler : IRequestHandler> -{ - private readonly IApplicationDbContext _context; - - public QueryHandler(IApplicationDbContext context) - { - _context = context; - } - public async Task> Handle(Query request, CancellationToken cancellationToken) - { - return new ReadOnlyCollection(await _context.Documents.Select(x => x.DocumentType).Distinct() - .ToListAsync(cancellationToken)); - } -} \ No newline at end of file diff --git a/src/Application/Folders/Commands/Add/Command.cs b/src/Application/Folders/Commands/Add/Command.cs deleted file mode 100644 index 5fa9f0ae..00000000 --- a/src/Application/Folders/Commands/Add/Command.cs +++ /dev/null @@ -1,68 +0,0 @@ -using Application.Common.Exceptions; -using Application.Common.Interfaces; -using Application.Common.Models.Dtos.Physical; -using AutoMapper; -using Domain.Entities.Physical; -using Domain.Exceptions; -using MediatR; -using Microsoft.EntityFrameworkCore; - -namespace Application.Folders.Commands.Add; - -public record Command : IRequest -{ - public string Name { get; init; } = null!; - public string? Description { get; init; } - public int Capacity { get; init; } - public Guid LockerId { get; init; } -} - -public class CommandHandler : IRequestHandler -{ - private readonly IApplicationDbContext _context; - private readonly IMapper _mapper; - - public CommandHandler(IApplicationDbContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - - public async Task Handle(Command request, CancellationToken cancellationToken) - { - var locker = await _context.Lockers.FirstOrDefaultAsync(l => l.Id == request.LockerId, cancellationToken); - - if (locker is null) - { - throw new KeyNotFoundException("Locker does not exist."); - } - - if (locker.NumberOfFolders >= locker.Capacity) - { - throw new LimitExceededException("This locker cannot accept more folders."); - } - - var folder = await _context.Folders.FirstOrDefaultAsync(x => x.Name.Trim().ToLower().Equals(request.Name.Trim().ToLower()) - && x.Locker.Id.Equals(request.LockerId), cancellationToken); - - if (folder is not null) - { - throw new ConflictException("Folder's name already exists."); - } - - var entity = new Folder - { - Name = request.Name.Trim(), - Description = request.Description, - NumberOfDocuments = 0, - Capacity = request.Capacity, - Locker = locker, - IsAvailable = true - }; - var result = await _context.Folders.AddAsync(entity, cancellationToken); - locker.NumberOfFolders += 1; - _context.Lockers.Update(locker); - await _context.SaveChangesAsync(cancellationToken); - return _mapper.Map(result.Entity); - } -} diff --git a/src/Application/Folders/Commands/Add/Validator.cs b/src/Application/Folders/Commands/Add/Validator.cs deleted file mode 100644 index 89eb45d5..00000000 --- a/src/Application/Folders/Commands/Add/Validator.cs +++ /dev/null @@ -1,27 +0,0 @@ -using FluentValidation; - -namespace Application.Folders.Commands.Add; - -public class Validator : AbstractValidator -{ - public Validator() - { - - RuleLevelCascadeMode = CascadeMode.Stop; - - RuleFor(f => f.Name) - .NotEmpty().WithMessage("Name is required.") - .MaximumLength(64).WithMessage("Name cannot exceed 64 characters."); - - RuleFor(f => f.Description) - .MaximumLength(256).WithMessage("Description cannot exceed 256 characters."); - - RuleFor(f => f.Capacity) - .NotEmpty().WithMessage("Folder capacity is required.") - .GreaterThanOrEqualTo(1).WithMessage("Folder's capacity cannot be less than 1."); - - RuleFor(f => f.LockerId) - .NotEmpty().WithMessage("LockerId is required."); - } - -} \ No newline at end of file diff --git a/src/Application/Folders/Commands/AddFolder.cs b/src/Application/Folders/Commands/AddFolder.cs new file mode 100644 index 00000000..c8c76a07 --- /dev/null +++ b/src/Application/Folders/Commands/AddFolder.cs @@ -0,0 +1,95 @@ +using Application.Common.Exceptions; +using Application.Common.Interfaces; +using Application.Common.Models.Dtos.Physical; +using AutoMapper; +using Domain.Entities.Physical; +using Domain.Exceptions; +using FluentValidation; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace Application.Folders.Commands; + +public class AddFolder +{ + public class Validator : AbstractValidator + { + public Validator() + { + RuleLevelCascadeMode = CascadeMode.Stop; + + RuleFor(f => f.Name) + .NotEmpty().WithMessage("Name is required.") + .MaximumLength(64).WithMessage("Name cannot exceed 64 characters."); + + RuleFor(f => f.Description) + .MaximumLength(256).WithMessage("Description cannot exceed 256 characters."); + + RuleFor(f => f.Capacity) + .NotEmpty().WithMessage("Folder capacity is required.") + .GreaterThanOrEqualTo(1).WithMessage("Folder's capacity cannot be less than 1."); + + RuleFor(f => f.LockerId) + .NotEmpty().WithMessage("LockerId is required."); + } + } + + public record Command : IRequest + { + public string Name { get; init; } = null!; + public string? Description { get; init; } + public int Capacity { get; init; } + public Guid LockerId { get; init; } + } + + public class CommandHandler : IRequestHandler + { + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + + public CommandHandler(IApplicationDbContext context, IMapper mapper) + { + _context = context; + _mapper = mapper; + } + + public async Task Handle(Command request, CancellationToken cancellationToken) + { + var locker = await _context.Lockers.FirstOrDefaultAsync(l => l.Id == request.LockerId, cancellationToken); + + if (locker is null) + { + throw new KeyNotFoundException("Locker does not exist."); + } + + if (locker.NumberOfFolders >= locker.Capacity) + { + throw new LimitExceededException("This locker cannot accept more folders."); + } + + var folder = await _context.Folders.FirstOrDefaultAsync(x => + x.Name.Trim().ToLower().Equals(request.Name.Trim().ToLower()) + && x.Locker.Id.Equals(request.LockerId), cancellationToken); + + if (folder is not null) + { + throw new ConflictException("Folder's name already exists."); + } + + var entity = new Folder + { + Name = request.Name.Trim(), + Description = request.Description, + NumberOfDocuments = 0, + Capacity = request.Capacity, + Locker = locker, + IsAvailable = true + }; + var result = await _context.Folders.AddAsync(entity, cancellationToken); + locker.NumberOfFolders += 1; + _context.Lockers.Update(locker); + await _context.SaveChangesAsync(cancellationToken); + return _mapper.Map(result.Entity); + } + } +} \ No newline at end of file diff --git a/src/Application/Folders/Commands/Disable/Command.cs b/src/Application/Folders/Commands/Disable/Command.cs deleted file mode 100644 index 9538e7cd..00000000 --- a/src/Application/Folders/Commands/Disable/Command.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Application.Common.Exceptions; -using Application.Common.Interfaces; -using Application.Common.Models.Dtos.Physical; -using AutoMapper; -using MediatR; -using Microsoft.EntityFrameworkCore; - -namespace Application.Folders.Commands.Disable; - -public record Command : IRequest -{ - public Guid FolderId { get; init; } -} - -public class CommandHandler : IRequestHandler -{ - private readonly IApplicationDbContext _context; - private readonly IMapper _mapper; - - public CommandHandler(IApplicationDbContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - - public async Task Handle(Command request, CancellationToken cancellationToken) - { - var folder = await _context.Folders - .FirstOrDefaultAsync(f => f.Id.Equals(request.FolderId), cancellationToken); - - if (folder is null) - { - throw new KeyNotFoundException("Folder does not exist."); - } - - if (!folder.IsAvailable) - { - throw new ConflictException("Folder has already been disabled."); - } - - if (folder.NumberOfDocuments > 0) - { - throw new InvalidOperationException("Folder cannot be disabled because it contains documents."); - } - - folder.IsAvailable = false; - _context.Folders.Update(folder); - await _context.SaveChangesAsync(cancellationToken); - return _mapper.Map(folder); - } -} \ No newline at end of file diff --git a/src/Application/Folders/Commands/Disable/Validator.cs b/src/Application/Folders/Commands/Disable/Validator.cs deleted file mode 100644 index d0d22562..00000000 --- a/src/Application/Folders/Commands/Disable/Validator.cs +++ /dev/null @@ -1,14 +0,0 @@ -using FluentValidation; - -namespace Application.Folders.Commands.Disable; - -public class Validator : AbstractValidator -{ - public Validator() - { - RuleLevelCascadeMode = CascadeMode.Stop; - - RuleFor(f => f.FolderId) - .NotEmpty().WithMessage("FolderId is required."); - } -} \ No newline at end of file diff --git a/src/Application/Folders/Commands/DisableFolder.cs b/src/Application/Folders/Commands/DisableFolder.cs new file mode 100644 index 00000000..020bc1fe --- /dev/null +++ b/src/Application/Folders/Commands/DisableFolder.cs @@ -0,0 +1,66 @@ +using Application.Common.Exceptions; +using Application.Common.Interfaces; +using Application.Common.Models.Dtos.Physical; +using AutoMapper; +using FluentValidation; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace Application.Folders.Commands; + +public class DisableFolder +{ + public class Validator : AbstractValidator + { + public Validator() + { + RuleLevelCascadeMode = CascadeMode.Stop; + + RuleFor(f => f.FolderId) + .NotEmpty().WithMessage("FolderId is required."); + } + } + + public record Command : IRequest + { + public Guid FolderId { get; init; } + } + + public class CommandHandler : IRequestHandler + { + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + + public CommandHandler(IApplicationDbContext context, IMapper mapper) + { + _context = context; + _mapper = mapper; + } + + public async Task Handle(Command request, CancellationToken cancellationToken) + { + var folder = await _context.Folders + .FirstOrDefaultAsync(f => f.Id.Equals(request.FolderId), cancellationToken); + + if (folder is null) + { + throw new KeyNotFoundException("Folder does not exist."); + } + + if (!folder.IsAvailable) + { + throw new ConflictException("Folder has already been disabled."); + } + + if (folder.NumberOfDocuments > 0) + { + throw new InvalidOperationException("Folder cannot be disabled because it contains documents."); + } + + folder.IsAvailable = false; + _context.Folders.Update(folder); + await _context.SaveChangesAsync(cancellationToken); + return _mapper.Map(folder); + } + } +} \ No newline at end of file diff --git a/src/Application/Folders/Commands/Enable/Command.cs b/src/Application/Folders/Commands/Enable/Command.cs deleted file mode 100644 index 086e96c3..00000000 --- a/src/Application/Folders/Commands/Enable/Command.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Folders.Commands.Enable; - -public record Command : IRequest -{ - public Guid FolderId { get; init; } -} diff --git a/src/Application/Folders/Commands/EnableFolder.cs b/src/Application/Folders/Commands/EnableFolder.cs new file mode 100644 index 00000000..33e3cb23 --- /dev/null +++ b/src/Application/Folders/Commands/EnableFolder.cs @@ -0,0 +1,12 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Folders.Commands; + +public class EnableFolder +{ + public record Command : IRequest + { + public Guid FolderId { get; init; } + } +} \ No newline at end of file diff --git a/src/Application/Folders/Commands/Remove/Command.cs b/src/Application/Folders/Commands/Remove/Command.cs deleted file mode 100644 index 85928dfe..00000000 --- a/src/Application/Folders/Commands/Remove/Command.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Folders.Commands.Remove; - -public record Command : IRequest -{ - public Guid FolderId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Folders/Commands/RemoveFolder.cs b/src/Application/Folders/Commands/RemoveFolder.cs new file mode 100644 index 00000000..528184ce --- /dev/null +++ b/src/Application/Folders/Commands/RemoveFolder.cs @@ -0,0 +1,12 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Folders.Commands; + +public class RemoveFolder +{ + public record Command : IRequest + { + public Guid FolderId { get; init; } + } +} \ No newline at end of file diff --git a/src/Application/Folders/Commands/Update/Command.cs b/src/Application/Folders/Commands/Update/Command.cs deleted file mode 100644 index 1231e98a..00000000 --- a/src/Application/Folders/Commands/Update/Command.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Folders.Commands.Update; - -public record Command : IRequest -{ - public Guid FolderId { get; init; } - public string Name { get; init; } = null!; - public string? Description { get; init; } - public int Capacity { get; init; } -} \ No newline at end of file diff --git a/src/Application/Folders/Commands/UpdateFolder.cs b/src/Application/Folders/Commands/UpdateFolder.cs new file mode 100644 index 00000000..a467f7e3 --- /dev/null +++ b/src/Application/Folders/Commands/UpdateFolder.cs @@ -0,0 +1,15 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Folders.Commands; + +public class UpdateFolder +{ + public record Command : IRequest + { + public Guid FolderId { get; init; } + public string Name { get; init; } = null!; + public string? Description { get; init; } + public int Capacity { get; init; } + } +} \ No newline at end of file diff --git a/src/Application/Folders/Queries/GetAllFoldersPaginated.cs b/src/Application/Folders/Queries/GetAllFoldersPaginated.cs new file mode 100644 index 00000000..280a4c5c --- /dev/null +++ b/src/Application/Folders/Queries/GetAllFoldersPaginated.cs @@ -0,0 +1,18 @@ +using Application.Common.Models; +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Folders.Queries; + +public class GetAllFoldersPaginated +{ + public record Query : IRequest> + { + public Guid? RoomId { get; init; } + public Guid? LockerId { get; init; } + public int? Page { get; init; } + public int? Size { get; init; } + public string? SortBy { get; init; } + public string? SortOrder { get; init; } + } +} \ No newline at end of file diff --git a/src/Application/Folders/Queries/GetAllPaginated/Query.cs b/src/Application/Folders/Queries/GetAllPaginated/Query.cs deleted file mode 100644 index d66d1fc8..00000000 --- a/src/Application/Folders/Queries/GetAllPaginated/Query.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Application.Common.Models; -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Folders.Queries.GetAllPaginated; - -public record Query : IRequest> -{ - public Guid? RoomId { get; init; } - public Guid? LockerId { get; init; } - public int? Page { get; init; } - public int? Size { get; init; } - public string? SortBy { get; init; } - public string? SortOrder { get; init; } -} \ No newline at end of file diff --git a/src/Application/Folders/Queries/GetById/Query.cs b/src/Application/Folders/Queries/GetById/Query.cs deleted file mode 100644 index 3891c3c4..00000000 --- a/src/Application/Folders/Queries/GetById/Query.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Folders.Queries.GetById; - -public record Query : IRequest -{ - public Guid FolderId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Folders/Queries/GetFolderById.cs b/src/Application/Folders/Queries/GetFolderById.cs new file mode 100644 index 00000000..fd0d0b57 --- /dev/null +++ b/src/Application/Folders/Queries/GetFolderById.cs @@ -0,0 +1,12 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Folders.Queries; + +public class GetFolderById +{ + public record Query : IRequest + { + public Guid FolderId { get; init; } + } +} \ No newline at end of file diff --git a/src/Application/Lockers/Commands/Add/Command.cs b/src/Application/Lockers/Commands/Add/Command.cs deleted file mode 100644 index 3ce0f7e3..00000000 --- a/src/Application/Lockers/Commands/Add/Command.cs +++ /dev/null @@ -1,69 +0,0 @@ -using Application.Common.Exceptions; -using Application.Common.Interfaces; -using Application.Common.Models.Dtos.Physical; -using AutoMapper; -using Domain.Entities.Physical; -using Domain.Exceptions; -using MediatR; -using Microsoft.EntityFrameworkCore; - -namespace Application.Lockers.Commands.Add; - -public record Command : IRequest -{ - public string Name { get; init; } = null!; - public string? Description { get; init; } - public Guid RoomId { get; init; } - public int Capacity { get; init; } -} - -public class CommandHandler : IRequestHandler -{ - private readonly IApplicationDbContext _context; - private readonly IMapper _mapper; - - public CommandHandler(IApplicationDbContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - - public async Task Handle(Command request, CancellationToken cancellationToken) - { - var room = await _context.Rooms.FirstOrDefaultAsync(x => x.Id == request.RoomId, cancellationToken); - - if (room is null) - { - throw new KeyNotFoundException("Room does not exist."); - } - - if (room.NumberOfLockers >= room.Capacity) - { - throw new LimitExceededException( - "This room cannot accept more lockers." - ); - } - - var locker = await _context.Lockers.FirstOrDefaultAsync(x => x.Name.Trim().ToLower().Equals(request.Name.Trim().ToLower()) && x.Room.Id.Equals(request.RoomId) ,cancellationToken); - if (locker is not null) - { - throw new ConflictException("Locker name already exists."); - } - - var entity = new Locker - { - Name = request.Name.Trim(), - Description = request.Description?.Trim(), - NumberOfFolders = 0, - Capacity = request.Capacity, - Room = room, - IsAvailable = true - }; - - var result = await _context.Lockers.AddAsync(entity, cancellationToken); - room.NumberOfLockers += 1; - _context.Rooms.Update(room); - await _context.SaveChangesAsync(cancellationToken); - return _mapper.Map(result.Entity); - } -} \ No newline at end of file diff --git a/src/Application/Lockers/Commands/Add/Validator.cs b/src/Application/Lockers/Commands/Add/Validator.cs deleted file mode 100644 index 834261bf..00000000 --- a/src/Application/Lockers/Commands/Add/Validator.cs +++ /dev/null @@ -1,25 +0,0 @@ -using FluentValidation; - -namespace Application.Lockers.Commands.Add; - -public class Validator : AbstractValidator -{ - - public Validator() - { - RuleLevelCascadeMode = CascadeMode.Stop; - - RuleFor(x => x.Capacity) - .GreaterThan(0).WithMessage("Locker's capacity cannot be less than 1"); - - RuleFor(x => x.Name) - .NotEmpty().WithMessage("Locker's name is required.") - .MaximumLength(64).WithMessage("Locker's name cannot exceed 64 characters."); - - RuleFor(x => x.Description) - .MaximumLength(256).WithMessage("Locker's description cannot exceed 256 characters."); - - RuleFor(x => x.RoomId) - .NotEmpty().WithMessage("RoomId is required."); - } -} diff --git a/src/Application/Lockers/Commands/AddLocker.cs b/src/Application/Lockers/Commands/AddLocker.cs new file mode 100644 index 00000000..78cbb371 --- /dev/null +++ b/src/Application/Lockers/Commands/AddLocker.cs @@ -0,0 +1,96 @@ +using Application.Common.Exceptions; +using Application.Common.Interfaces; +using Application.Common.Models.Dtos.Physical; +using AutoMapper; +using Domain.Entities.Physical; +using Domain.Exceptions; +using FluentValidation; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace Application.Lockers.Commands; + +public class AddLocker +{ + public class Validator : AbstractValidator + { + public Validator() + { + RuleLevelCascadeMode = CascadeMode.Stop; + + RuleFor(x => x.Capacity) + .GreaterThan(0).WithMessage("Locker's capacity cannot be less than 1"); + + RuleFor(x => x.Name) + .NotEmpty().WithMessage("Locker's name is required.") + .MaximumLength(64).WithMessage("Locker's name cannot exceed 64 characters."); + + RuleFor(x => x.Description) + .MaximumLength(256).WithMessage("Locker's description cannot exceed 256 characters."); + + RuleFor(x => x.RoomId) + .NotEmpty().WithMessage("RoomId is required."); + } + } + + public record Command : IRequest + { + public string Name { get; init; } = null!; + public string? Description { get; init; } + public Guid RoomId { get; init; } + public int Capacity { get; init; } + } + + public class CommandHandler : IRequestHandler + { + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + + public CommandHandler(IApplicationDbContext context, IMapper mapper) + { + _context = context; + _mapper = mapper; + } + + public async Task Handle(Command request, CancellationToken cancellationToken) + { + var room = await _context.Rooms.FirstOrDefaultAsync(x => x.Id == request.RoomId, cancellationToken); + + if (room is null) + { + throw new KeyNotFoundException("Room does not exist."); + } + + if (room.NumberOfLockers >= room.Capacity) + { + throw new LimitExceededException( + "This room cannot accept more lockers." + ); + } + + var locker = await _context.Lockers.FirstOrDefaultAsync( + x => x.Name.Trim().ToLower().Equals(request.Name.Trim().ToLower()) && x.Room.Id.Equals(request.RoomId), + cancellationToken); + if (locker is not null) + { + throw new ConflictException("Locker name already exists."); + } + + var entity = new Locker + { + Name = request.Name.Trim(), + Description = request.Description?.Trim(), + NumberOfFolders = 0, + Capacity = request.Capacity, + Room = room, + IsAvailable = true + }; + + var result = await _context.Lockers.AddAsync(entity, cancellationToken); + room.NumberOfLockers += 1; + _context.Rooms.Update(room); + await _context.SaveChangesAsync(cancellationToken); + return _mapper.Map(result.Entity); + } + } +} \ No newline at end of file diff --git a/src/Application/Lockers/Commands/Disable/Command.cs b/src/Application/Lockers/Commands/Disable/Command.cs deleted file mode 100644 index dfbeb5a3..00000000 --- a/src/Application/Lockers/Commands/Disable/Command.cs +++ /dev/null @@ -1,63 +0,0 @@ -using Application.Common.Exceptions; -using Application.Common.Interfaces; -using Application.Common.Models.Dtos.Physical; -using AutoMapper; -using MediatR; -using Microsoft.EntityFrameworkCore; - -namespace Application.Lockers.Commands.Disable; - -public record Command : IRequest -{ - public Guid LockerId { get; init; } -} - -public class RemoveLockerCommandHandler : IRequestHandler -{ - private readonly IApplicationDbContext _context; - private readonly IMapper _mapper; - - public RemoveLockerCommandHandler(IApplicationDbContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - - public async Task Handle(Command request, CancellationToken cancellationToken) - { - var locker = await _context.Lockers - .FirstOrDefaultAsync(x => x.Id.Equals(request.LockerId), cancellationToken); - - if (locker is null) - { - throw new KeyNotFoundException("Locker does not exist."); - } - - if (!locker.IsAvailable) - { - throw new ConflictException("Locker has already been disabled."); - } - - var canNotDisable = await _context.Documents - .CountAsync(x => x.Folder!.Locker.Id.Equals(request.LockerId), cancellationToken) - > 0; - - if (canNotDisable) - { - throw new InvalidOperationException("Locker cannot be disabled because it contains documents."); - } - - var folders = _context.Folders.Where(x => x.Locker.Room.Id.Equals(locker.Id)); - - foreach (var folder in folders) - { - folder.IsAvailable = false; - } - _context.Folders.UpdateRange(folders); - - locker.IsAvailable = false; - var result = _context.Lockers.Update(locker); - await _context.SaveChangesAsync(cancellationToken); - return _mapper.Map(result.Entity); - } -} \ No newline at end of file diff --git a/src/Application/Lockers/Commands/Disable/Validator.cs b/src/Application/Lockers/Commands/Disable/Validator.cs deleted file mode 100644 index 03e69143..00000000 --- a/src/Application/Lockers/Commands/Disable/Validator.cs +++ /dev/null @@ -1,14 +0,0 @@ -using FluentValidation; - -namespace Application.Lockers.Commands.Disable; - -public class Validator : AbstractValidator -{ - public Validator() - { - RuleLevelCascadeMode = CascadeMode.Stop; - - RuleFor(x => x.LockerId) - .NotEmpty().WithMessage("LockerId is required."); - } -} \ No newline at end of file diff --git a/src/Application/Lockers/Commands/DisableLocker.cs b/src/Application/Lockers/Commands/DisableLocker.cs new file mode 100644 index 00000000..eaa4f40b --- /dev/null +++ b/src/Application/Lockers/Commands/DisableLocker.cs @@ -0,0 +1,78 @@ +using Application.Common.Exceptions; +using Application.Common.Interfaces; +using Application.Common.Models.Dtos.Physical; +using AutoMapper; +using FluentValidation; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace Application.Lockers.Commands; + +public class DisableLocker +{ + public class Validator : AbstractValidator + { + public Validator() + { + RuleLevelCascadeMode = CascadeMode.Stop; + + RuleFor(x => x.LockerId) + .NotEmpty().WithMessage("LockerId is required."); + } + } + + public record Command : IRequest + { + public Guid LockerId { get; init; } + } + + public class RemoveLockerCommandHandler : IRequestHandler + { + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + + public RemoveLockerCommandHandler(IApplicationDbContext context, IMapper mapper) + { + _context = context; + _mapper = mapper; + } + + public async Task Handle(Command request, CancellationToken cancellationToken) + { + var locker = await _context.Lockers + .FirstOrDefaultAsync(x => x.Id.Equals(request.LockerId), cancellationToken); + + if (locker is null) + { + throw new KeyNotFoundException("Locker does not exist."); + } + + if (!locker.IsAvailable) + { + throw new ConflictException("Locker has already been disabled."); + } + + var canNotDisable = await _context.Documents + .CountAsync(x => x.Folder!.Locker.Id.Equals(request.LockerId), cancellationToken) + > 0; + + if (canNotDisable) + { + throw new InvalidOperationException("Locker cannot be disabled because it contains documents."); + } + + var folders = _context.Folders.Where(x => x.Locker.Room.Id.Equals(locker.Id)); + + foreach (var folder in folders) + { + folder.IsAvailable = false; + } + _context.Folders.UpdateRange(folders); + + locker.IsAvailable = false; + var result = _context.Lockers.Update(locker); + await _context.SaveChangesAsync(cancellationToken); + return _mapper.Map(result.Entity); + } + } +} \ No newline at end of file diff --git a/src/Application/Lockers/Commands/Enable/Command.cs b/src/Application/Lockers/Commands/Enable/Command.cs deleted file mode 100644 index 8f050747..00000000 --- a/src/Application/Lockers/Commands/Enable/Command.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Application.Common.Exceptions; -using Application.Common.Interfaces; -using Application.Common.Models.Dtos.Physical; -using AutoMapper; -using MediatR; -using Microsoft.EntityFrameworkCore; - -namespace Application.Lockers.Commands.Enable; - -public record Command : IRequest -{ - public Guid LockerId { get; init; } -} - -public class CommandHandler : IRequestHandler -{ - private readonly IApplicationDbContext _context; - private readonly IMapper _mapper; - - public CommandHandler(IApplicationDbContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - - public async Task Handle(Command request, CancellationToken cancellationToken) - { - var locker = await _context.Lockers - .FirstOrDefaultAsync(x => x.Id.Equals(request.LockerId), cancellationToken); - if (locker is null) - { - throw new KeyNotFoundException("Locker does not exist."); - } - - if (locker.IsAvailable) - { - throw new ConflictException("Locker has already been enabled."); - } - - locker.IsAvailable = true; - var result = _context.Lockers.Update(locker); - await _context.SaveChangesAsync(cancellationToken); - return _mapper.Map(result.Entity); - } -} diff --git a/src/Application/Lockers/Commands/Enable/Validator.cs b/src/Application/Lockers/Commands/Enable/Validator.cs deleted file mode 100644 index 8d73c584..00000000 --- a/src/Application/Lockers/Commands/Enable/Validator.cs +++ /dev/null @@ -1,14 +0,0 @@ -using FluentValidation; - -namespace Application.Lockers.Commands.Enable; - -public class Validator : AbstractValidator -{ - public Validator() - { - RuleLevelCascadeMode = CascadeMode.Stop; - - RuleFor(x => x.LockerId) - .NotEmpty().WithMessage("LockerId is required."); - } -} \ No newline at end of file diff --git a/src/Application/Lockers/Commands/EnableLocker.cs b/src/Application/Lockers/Commands/EnableLocker.cs new file mode 100644 index 00000000..32dee1aa --- /dev/null +++ b/src/Application/Lockers/Commands/EnableLocker.cs @@ -0,0 +1,60 @@ +using Application.Common.Exceptions; +using Application.Common.Interfaces; +using Application.Common.Models.Dtos.Physical; +using AutoMapper; +using FluentValidation; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace Application.Lockers.Commands; + +public class EnableLocker +{ + public class Validator : AbstractValidator + { + public Validator() + { + RuleLevelCascadeMode = CascadeMode.Stop; + + RuleFor(x => x.LockerId) + .NotEmpty().WithMessage("LockerId is required."); + } + } + + public record Command : IRequest + { + public Guid LockerId { get; init; } + } + + public class CommandHandler : IRequestHandler + { + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + + public CommandHandler(IApplicationDbContext context, IMapper mapper) + { + _context = context; + _mapper = mapper; + } + + public async Task Handle(Command request, CancellationToken cancellationToken) + { + var locker = await _context.Lockers + .FirstOrDefaultAsync(x => x.Id.Equals(request.LockerId), cancellationToken); + if (locker is null) + { + throw new KeyNotFoundException("Locker does not exist."); + } + + if (locker.IsAvailable) + { + throw new ConflictException("Locker has already been enabled."); + } + + locker.IsAvailable = true; + var result = _context.Lockers.Update(locker); + await _context.SaveChangesAsync(cancellationToken); + return _mapper.Map(result.Entity); + } + } +} \ No newline at end of file diff --git a/src/Application/Lockers/Commands/Remove/Command.cs b/src/Application/Lockers/Commands/Remove/Command.cs deleted file mode 100644 index 91613358..00000000 --- a/src/Application/Lockers/Commands/Remove/Command.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Lockers.Commands.Remove; - -public record Command : IRequest -{ - public Guid LockerId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Lockers/Commands/RemoveLocker.cs b/src/Application/Lockers/Commands/RemoveLocker.cs new file mode 100644 index 00000000..11c6472b --- /dev/null +++ b/src/Application/Lockers/Commands/RemoveLocker.cs @@ -0,0 +1,12 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Lockers.Commands; + +public class RemoveLocker +{ + public record Command : IRequest + { + public Guid LockerId { get; init; } + } +} \ No newline at end of file diff --git a/src/Application/Lockers/Commands/Update/Command.cs b/src/Application/Lockers/Commands/Update/Command.cs deleted file mode 100644 index f3423fcd..00000000 --- a/src/Application/Lockers/Commands/Update/Command.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Lockers.Commands.Update; - -public record Command : IRequest -{ - public Guid LockerId { get; init; } - public string Name { get; init; } = null!; - public string? Description { get; init; } - public int Capacity { get; init; } -} \ No newline at end of file diff --git a/src/Application/Lockers/Commands/UpdateLocker.cs b/src/Application/Lockers/Commands/UpdateLocker.cs new file mode 100644 index 00000000..580c1e6f --- /dev/null +++ b/src/Application/Lockers/Commands/UpdateLocker.cs @@ -0,0 +1,15 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Lockers.Commands; + +public class UpdateLocker +{ + public record Command : IRequest + { + public Guid LockerId { get; init; } + public string Name { get; init; } = null!; + public string? Description { get; init; } + public int Capacity { get; init; } + } +} \ No newline at end of file diff --git a/src/Application/Lockers/Queries/GetAllLockersPaginated.cs b/src/Application/Lockers/Queries/GetAllLockersPaginated.cs new file mode 100644 index 00000000..f7935335 --- /dev/null +++ b/src/Application/Lockers/Queries/GetAllLockersPaginated.cs @@ -0,0 +1,17 @@ +using Application.Common.Models; +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Lockers.Queries; + +public class GetAllLockersPaginated +{ + public record Query : IRequest> + { + public Guid? RoomId { get; init; } + public int? Page { get; init; } + public int? Size { get; init; } + public string? SortBy { get; init; } + public string? SortOrder { get; init; } + } +} \ No newline at end of file diff --git a/src/Application/Lockers/Queries/GetAllPaginated/Query.cs b/src/Application/Lockers/Queries/GetAllPaginated/Query.cs deleted file mode 100644 index 0dde471b..00000000 --- a/src/Application/Lockers/Queries/GetAllPaginated/Query.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Application.Common.Models; -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Lockers.Queries.GetAllPaginated; - -public record Query : IRequest> -{ - public Guid? RoomId { get; init; } - public int? Page { get; init; } - public int? Size { get; init; } - public string? SortBy { get; init; } - public string? SortOrder { get; init; } -} \ No newline at end of file diff --git a/src/Application/Lockers/Queries/GetById/Query.cs b/src/Application/Lockers/Queries/GetById/Query.cs deleted file mode 100644 index 1e152dad..00000000 --- a/src/Application/Lockers/Queries/GetById/Query.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Lockers.Queries.GetById; - -public record Query : IRequest -{ - public Guid LockerId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Lockers/Queries/GetLockerById.cs b/src/Application/Lockers/Queries/GetLockerById.cs new file mode 100644 index 00000000..65c31416 --- /dev/null +++ b/src/Application/Lockers/Queries/GetLockerById.cs @@ -0,0 +1,12 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Lockers.Queries; + +public class GetLockerById +{ + public record Query : IRequest + { + public Guid LockerId { get; init; } + } +} \ No newline at end of file diff --git a/src/Application/Rooms/Commands/Add/Command.cs b/src/Application/Rooms/Commands/Add/Command.cs deleted file mode 100644 index d508e8bb..00000000 --- a/src/Application/Rooms/Commands/Add/Command.cs +++ /dev/null @@ -1,59 +0,0 @@ -using Application.Common.Exceptions; -using Application.Common.Interfaces; -using Application.Common.Models.Dtos.Physical; -using AutoMapper; -using Domain.Entities.Physical; -using MediatR; -using Microsoft.EntityFrameworkCore; - -namespace Application.Rooms.Commands.Add; - -public record Command : IRequest -{ - public string Name { get; init; } = null!; - public string? Description { get; init; } - public int Capacity { get; init; } - public Guid DepartmentId { get; set; } -} - -public class CommandHandler : IRequestHandler -{ - private readonly IApplicationDbContext _context; - private readonly IMapper _mapper; - public CommandHandler(IApplicationDbContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - - public async Task Handle(Command request, CancellationToken cancellationToken) - { - var department = - await _context.Departments.FirstOrDefaultAsync(x => x.Id == request.DepartmentId, cancellationToken); - - if (department is null) - { - throw new KeyNotFoundException("Department does not exists."); - } - - var room = await _context.Rooms.FirstOrDefaultAsync(r => - r.Name.Trim().ToLower().Equals(request.Name.Trim().ToLower()), cancellationToken); - - if (room is not null) - { - throw new ConflictException("Room name already exists."); - } - - var entity = new Room - { - Name = request.Name.Trim(), - Description = request.Description?.Trim(), - NumberOfLockers = 0, - Capacity = request.Capacity, - Department = department, - }; - var result = await _context.Rooms.AddAsync(entity, cancellationToken); - await _context.SaveChangesAsync(cancellationToken); - return _mapper.Map(result.Entity); - } -} \ No newline at end of file diff --git a/src/Application/Rooms/Commands/Add/Validator.cs b/src/Application/Rooms/Commands/Add/Validator.cs deleted file mode 100644 index 249543c8..00000000 --- a/src/Application/Rooms/Commands/Add/Validator.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Application.Common.Interfaces; -using FluentValidation; - -namespace Application.Rooms.Commands.Add; - -public class Validator : AbstractValidator -{ - private readonly IApplicationDbContext _context; - public Validator(IApplicationDbContext context) - { - _context = context; - - RuleLevelCascadeMode = CascadeMode.Stop; - - RuleFor(x => x.Capacity) - .GreaterThanOrEqualTo(1).WithMessage("Room's capacity cannot be less than 1"); - - RuleFor(x => x.Name) - .NotEmpty().WithMessage("Name is required.") - .MaximumLength(64).WithMessage("Name cannot exceed 64 characters.") - .Must(BeUnique).WithMessage("Room name already exists."); - - RuleFor(x => x.Description) - .NotEmpty().WithMessage("Description is required.") - .MaximumLength(256).WithMessage("Description cannot exceed 256 characters."); - } - - private bool BeUnique(string name) - { - return _context.Rooms.FirstOrDefault(x => x.Name.Equals(name)) is null; - } -} \ No newline at end of file diff --git a/src/Application/Rooms/Commands/AddRoom.cs b/src/Application/Rooms/Commands/AddRoom.cs new file mode 100644 index 00000000..1ac4fe6c --- /dev/null +++ b/src/Application/Rooms/Commands/AddRoom.cs @@ -0,0 +1,91 @@ +using Application.Common.Exceptions; +using Application.Common.Interfaces; +using Application.Common.Models.Dtos.Physical; +using AutoMapper; +using Domain.Entities.Physical; +using FluentValidation; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace Application.Rooms.Commands; + +public class AddRoom +{ + public class Validator : AbstractValidator + { + private readonly IApplicationDbContext _context; + public Validator(IApplicationDbContext context) + { + _context = context; + + RuleLevelCascadeMode = CascadeMode.Stop; + + RuleFor(x => x.Capacity) + .GreaterThanOrEqualTo(1).WithMessage("Room's capacity cannot be less than 1"); + + RuleFor(x => x.Name) + .NotEmpty().WithMessage("Name is required.") + .MaximumLength(64).WithMessage("Name cannot exceed 64 characters.") + .Must(BeUnique).WithMessage("Room name already exists."); + + RuleFor(x => x.Description) + .NotEmpty().WithMessage("Description is required.") + .MaximumLength(256).WithMessage("Description cannot exceed 256 characters."); + } + + private bool BeUnique(string name) + { + return _context.Rooms.FirstOrDefault(x => x.Name.Equals(name)) is null; + } + } + + public record Command : IRequest + { + public string Name { get; init; } = null!; + public string? Description { get; init; } + public int Capacity { get; init; } + public Guid DepartmentId { get; set; } + } + + public class CommandHandler : IRequestHandler + { + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + public CommandHandler(IApplicationDbContext context, IMapper mapper) + { + _context = context; + _mapper = mapper; + } + + public async Task Handle(Command request, CancellationToken cancellationToken) + { + var department = + await _context.Departments.FirstOrDefaultAsync(x => x.Id == request.DepartmentId, cancellationToken); + + if (department is null) + { + throw new KeyNotFoundException("Department does not exists."); + } + + var room = await _context.Rooms.FirstOrDefaultAsync(r => + r.Name.Trim().ToLower().Equals(request.Name.Trim().ToLower()), cancellationToken); + + if (room is not null) + { + throw new ConflictException("Room name already exists."); + } + + var entity = new Room + { + Name = request.Name.Trim(), + Description = request.Description?.Trim(), + NumberOfLockers = 0, + Capacity = request.Capacity, + Department = department, + }; + var result = await _context.Rooms.AddAsync(entity, cancellationToken); + await _context.SaveChangesAsync(cancellationToken); + return _mapper.Map(result.Entity); + } + } +} \ No newline at end of file diff --git a/src/Application/Rooms/Commands/Disable/Command.cs b/src/Application/Rooms/Commands/Disable/Command.cs deleted file mode 100644 index d4fd4ac5..00000000 --- a/src/Application/Rooms/Commands/Disable/Command.cs +++ /dev/null @@ -1,69 +0,0 @@ -using Application.Common.Exceptions; -using Application.Common.Interfaces; -using Application.Common.Models.Dtos.Physical; -using AutoMapper; -using MediatR; -using Microsoft.EntityFrameworkCore; - -namespace Application.Rooms.Commands.Disable; - -public record Command : IRequest -{ - public Guid RoomId { get; init; } -} - -public class DisableRoomCommandHandler : IRequestHandler -{ - private readonly IApplicationDbContext _context; - private readonly IMapper _mapper; - - public DisableRoomCommandHandler(IApplicationDbContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - - public async Task Handle(Command request, CancellationToken cancellationToken) - { - var room = await _context.Rooms - .Include(x => x.Lockers) - .ThenInclude(y => y.Folders) - .FirstOrDefaultAsync(x => x.Id.Equals(request.RoomId), cancellationToken: cancellationToken); - - if (room is null) - { - throw new KeyNotFoundException("Room does not exist."); - } - - if (!room.IsAvailable) - { - throw new ConflictException("Room have already been disabled."); - } - - var canNotDisable = await _context.Documents - .CountAsync(x => x.Folder!.Locker.Room.Id.Equals(request.RoomId), cancellationToken) - > 0; - - if (canNotDisable) - { - throw new InvalidOperationException("Room cannot be disabled because it contains documents."); - } - - var lockers = _context.Lockers.Include(x=> x.Folders) - .Where(x => x.Room.Id.Equals(room.Id)); - - foreach (var locker in lockers) - { - foreach (var folder in locker.Folders) - { - folder.IsAvailable = false; - } - locker.IsAvailable = false; - } - _context.Lockers.UpdateRange(lockers); - room.IsAvailable = false; - var result = _context.Rooms.Update(room); - await _context.SaveChangesAsync(cancellationToken); - return _mapper.Map(result.Entity); - } -} \ No newline at end of file diff --git a/src/Application/Rooms/Commands/Disable/Validator.cs b/src/Application/Rooms/Commands/Disable/Validator.cs deleted file mode 100644 index 72c9fa84..00000000 --- a/src/Application/Rooms/Commands/Disable/Validator.cs +++ /dev/null @@ -1,14 +0,0 @@ -using FluentValidation; - -namespace Application.Rooms.Commands.Disable; - -public class Validator : AbstractValidator -{ - public Validator() - { - RuleLevelCascadeMode = CascadeMode.Stop; - - RuleFor(x => x.RoomId) - .NotEmpty().WithMessage("RoomId is required."); - } -} \ No newline at end of file diff --git a/src/Application/Rooms/Commands/DisableRoom.cs b/src/Application/Rooms/Commands/DisableRoom.cs new file mode 100644 index 00000000..580b62c6 --- /dev/null +++ b/src/Application/Rooms/Commands/DisableRoom.cs @@ -0,0 +1,84 @@ +using Application.Common.Exceptions; +using Application.Common.Interfaces; +using Application.Common.Models.Dtos.Physical; +using AutoMapper; +using FluentValidation; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace Application.Rooms.Commands; + +public class DisableRoom +{ + public class Validator : AbstractValidator + { + public Validator() + { + RuleLevelCascadeMode = CascadeMode.Stop; + + RuleFor(x => x.RoomId) + .NotEmpty().WithMessage("RoomId is required."); + } + } + + public record Command : IRequest + { + public Guid RoomId { get; init; } + } + + public class DisableRoomCommandHandler : IRequestHandler + { + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + + public DisableRoomCommandHandler(IApplicationDbContext context, IMapper mapper) + { + _context = context; + _mapper = mapper; + } + + public async Task Handle(Command request, CancellationToken cancellationToken) + { + var room = await _context.Rooms + .Include(x => x.Lockers) + .ThenInclude(y => y.Folders) + .FirstOrDefaultAsync(x => x.Id.Equals(request.RoomId), cancellationToken: cancellationToken); + + if (room is null) + { + throw new KeyNotFoundException("Room does not exist."); + } + + if (!room.IsAvailable) + { + throw new ConflictException("Room have already been disabled."); + } + + var canNotDisable = await _context.Documents + .CountAsync(x => x.Folder!.Locker.Room.Id.Equals(request.RoomId), cancellationToken) + > 0; + + if (canNotDisable) + { + throw new InvalidOperationException("Room cannot be disabled because it contains documents."); + } + + var lockers = _context.Lockers.Include(x=> x.Folders) + .Where(x => x.Room.Id.Equals(room.Id)); + + foreach (var locker in lockers) + { + foreach (var folder in locker.Folders) + { + folder.IsAvailable = false; + } + locker.IsAvailable = false; + } + _context.Lockers.UpdateRange(lockers); + room.IsAvailable = false; + var result = _context.Rooms.Update(room); + await _context.SaveChangesAsync(cancellationToken); + return _mapper.Map(result.Entity); + } + } +} \ No newline at end of file diff --git a/src/Application/Rooms/Commands/Enable/Command.cs b/src/Application/Rooms/Commands/Enable/Command.cs deleted file mode 100644 index be029106..00000000 --- a/src/Application/Rooms/Commands/Enable/Command.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Rooms.Commands.Enable; - -public record Command : IRequest -{ - public Guid RoomId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Rooms/Commands/EnableRoom.cs b/src/Application/Rooms/Commands/EnableRoom.cs new file mode 100644 index 00000000..0e0cf048 --- /dev/null +++ b/src/Application/Rooms/Commands/EnableRoom.cs @@ -0,0 +1,12 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Rooms.Commands; + +public class EnableRoom +{ + public record Command : IRequest + { + public Guid RoomId { get; init; } + } +} \ No newline at end of file diff --git a/src/Application/Rooms/Commands/Remove/Command.cs b/src/Application/Rooms/Commands/Remove/Command.cs deleted file mode 100644 index d980fa60..00000000 --- a/src/Application/Rooms/Commands/Remove/Command.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Application.Common.Interfaces; -using Application.Common.Models.Dtos.Physical; -using AutoMapper; -using MediatR; -using Microsoft.EntityFrameworkCore; - -namespace Application.Rooms.Commands.Remove; - -public record Command : IRequest -{ - public Guid RoomId { get; init; } -} - -public class RemoveRoomCommandHandler : IRequestHandler -{ - private readonly IApplicationDbContext _context; - private readonly IMapper _mapper; - - public RemoveRoomCommandHandler(IApplicationDbContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - - public async Task Handle(Command request, CancellationToken cancellationToken) - { - var room = await _context.Rooms - .FirstOrDefaultAsync(x => x.Id.Equals(request.RoomId), cancellationToken: cancellationToken); - - if (room is null) - { - throw new KeyNotFoundException("Room does not exist."); - } - - var canNotRemove = await _context.Documents - .CountAsync(x => x.Folder!.Locker.Room.Id.Equals(request.RoomId), cancellationToken: cancellationToken) - > 0; - - if (canNotRemove) - { - throw new InvalidOperationException("Room cannot be removed because it contains documents."); - } - - room.IsAvailable = false; - var result = _context.Rooms.Remove(room); - await _context.SaveChangesAsync(cancellationToken); - return _mapper.Map(result.Entity); - } -} \ No newline at end of file diff --git a/src/Application/Rooms/Commands/Remove/Validator.cs b/src/Application/Rooms/Commands/Remove/Validator.cs deleted file mode 100644 index c9339293..00000000 --- a/src/Application/Rooms/Commands/Remove/Validator.cs +++ /dev/null @@ -1,14 +0,0 @@ -using FluentValidation; - -namespace Application.Rooms.Commands.Remove; - -public class Validator : AbstractValidator -{ - public Validator() - { - RuleLevelCascadeMode = CascadeMode.Stop; - - RuleFor(x => x.RoomId) - .NotEmpty().WithMessage("RoomId is required."); - } -} \ No newline at end of file diff --git a/src/Application/Rooms/Commands/RemoveRoom.cs b/src/Application/Rooms/Commands/RemoveRoom.cs new file mode 100644 index 00000000..805be223 --- /dev/null +++ b/src/Application/Rooms/Commands/RemoveRoom.cs @@ -0,0 +1,64 @@ +using Application.Common.Interfaces; +using Application.Common.Models.Dtos.Physical; +using AutoMapper; +using FluentValidation; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace Application.Rooms.Commands; + +public class RemoveRoom +{ + public class Validator : AbstractValidator + { + public Validator() + { + RuleLevelCascadeMode = CascadeMode.Stop; + + RuleFor(x => x.RoomId) + .NotEmpty().WithMessage("RoomId is required."); + } + } + + public record Command : IRequest + { + public Guid RoomId { get; init; } + } + + public class RemoveRoomCommandHandler : IRequestHandler + { + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + + public RemoveRoomCommandHandler(IApplicationDbContext context, IMapper mapper) + { + _context = context; + _mapper = mapper; + } + + public async Task Handle(Command request, CancellationToken cancellationToken) + { + var room = await _context.Rooms + .FirstOrDefaultAsync(x => x.Id.Equals(request.RoomId), cancellationToken: cancellationToken); + + if (room is null) + { + throw new KeyNotFoundException("Room does not exist."); + } + + var canNotRemove = await _context.Documents + .CountAsync(x => x.Folder!.Locker.Room.Id.Equals(request.RoomId), cancellationToken: cancellationToken) + > 0; + + if (canNotRemove) + { + throw new InvalidOperationException("Room cannot be removed because it contains documents."); + } + + room.IsAvailable = false; + var result = _context.Rooms.Remove(room); + await _context.SaveChangesAsync(cancellationToken); + return _mapper.Map(result.Entity); + } + } +} \ No newline at end of file diff --git a/src/Application/Rooms/Commands/Update/Command.cs b/src/Application/Rooms/Commands/Update/Command.cs deleted file mode 100644 index d5a2c8a4..00000000 --- a/src/Application/Rooms/Commands/Update/Command.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Rooms.Commands.Update; - -public record Command : IRequest -{ - public Guid RoomId { get; init; } - public string Name { get; set; } = null!; - public string? Description { get; init; } - public int Capacity { get; init; } -} \ No newline at end of file diff --git a/src/Application/Rooms/Commands/UpdateRoom.cs b/src/Application/Rooms/Commands/UpdateRoom.cs new file mode 100644 index 00000000..3dc20417 --- /dev/null +++ b/src/Application/Rooms/Commands/UpdateRoom.cs @@ -0,0 +1,15 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Rooms.Commands; + +public class UpdateRoom +{ + public record Command : IRequest + { + public Guid RoomId { get; init; } + public string Name { get; set; } = null!; + public string? Description { get; init; } + public int Capacity { get; init; } + } +} \ No newline at end of file diff --git a/src/Application/Rooms/Queries/GetAllPaginated/Query.cs b/src/Application/Rooms/Queries/GetAllPaginated/Query.cs deleted file mode 100644 index 4867dbc3..00000000 --- a/src/Application/Rooms/Queries/GetAllPaginated/Query.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Application.Common.Models; -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Rooms.Queries.GetAllPaginated; - -public record Query : IRequest> -{ - public int? Page { get; init; } - public int? Size { get; init; } - public string? SortBy { get; init; } - public string? SortOrder { get; init; } -} \ No newline at end of file diff --git a/src/Application/Rooms/Queries/GetAllRoomsPaginated.cs b/src/Application/Rooms/Queries/GetAllRoomsPaginated.cs new file mode 100644 index 00000000..8094f631 --- /dev/null +++ b/src/Application/Rooms/Queries/GetAllRoomsPaginated.cs @@ -0,0 +1,16 @@ +using Application.Common.Models; +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Rooms.Queries; + +public class GetAllRoomsPaginated +{ + public record Query : IRequest> + { + public int? Page { get; init; } + public int? Size { get; init; } + public string? SortBy { get; init; } + public string? SortOrder { get; init; } + } +} \ No newline at end of file diff --git a/src/Application/Rooms/Queries/GetById/Query.cs b/src/Application/Rooms/Queries/GetById/Query.cs deleted file mode 100644 index 616e3bc5..00000000 --- a/src/Application/Rooms/Queries/GetById/Query.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Rooms.Queries.GetById; - -public record Query : IRequest -{ - public Guid RoomId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Rooms/Queries/GetEmptyContainersPaginated.cs b/src/Application/Rooms/Queries/GetEmptyContainersPaginated.cs new file mode 100644 index 00000000..3534dacb --- /dev/null +++ b/src/Application/Rooms/Queries/GetEmptyContainersPaginated.cs @@ -0,0 +1,54 @@ +using Application.Common.Interfaces; +using Application.Common.Models; +using Application.Common.Models.Dtos.Physical; +using AutoMapper; +using AutoMapper.QueryableExtensions; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace Application.Rooms.Queries; + +public class GetEmptyContainersPaginated +{ + public record Query : IRequest> + { + public Guid RoomId { get; init; } + public int? Page { get; init; } + public int? Size { get; init; } + } + + public class QueryHandler : IRequestHandler> + { + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + public QueryHandler(IApplicationDbContext context, IMapper mapper) + { + _context = context; + _mapper = mapper; + } + + public async Task> Handle(Query request, CancellationToken cancellationToken) + { + var room = await _context.Rooms.FirstOrDefaultAsync(x => x.Id == request.RoomId, cancellationToken); + if (room is null) + { + throw new KeyNotFoundException("Room does not exist."); + } + + var pageNumber = request.Page ?? 1; + var sizeNumber = request.Size ?? 5; + var lockers = _context.Lockers + .Where(x => x.Room.Id == request.RoomId + && x.IsAvailable + && x.Folders.Any(y => y.Capacity > y.NumberOfDocuments && y.IsAvailable)) + .ProjectTo(_mapper.ConfigurationProvider) + .AsEnumerable() + .ToList(); + + lockers.ForEach(x => x.Folders = x.Folders.Where(y => y.Slot > 0)); + + var result = new PaginatedList(lockers.ToList(), lockers.Count, pageNumber, sizeNumber); + return result; + } + } +} \ No newline at end of file diff --git a/src/Application/Rooms/Queries/GetEmptyContainersPaginated/Query.cs b/src/Application/Rooms/Queries/GetEmptyContainersPaginated/Query.cs deleted file mode 100644 index 60ad95b2..00000000 --- a/src/Application/Rooms/Queries/GetEmptyContainersPaginated/Query.cs +++ /dev/null @@ -1,50 +0,0 @@ -using Application.Common.Interfaces; -using Application.Common.Models; -using AutoMapper; -using AutoMapper.QueryableExtensions; -using MediatR; -using Microsoft.EntityFrameworkCore; - -namespace Application.Rooms.Queries.GetEmptyContainersPaginated; - -public record Query : IRequest> -{ - public Guid RoomId { get; init; } - public int? Page { get; init; } - public int? Size { get; init; } -} - -public class QueryHandler : IRequestHandler> -{ - private readonly IApplicationDbContext _context; - private readonly IMapper _mapper; - public QueryHandler(IApplicationDbContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - - public async Task> Handle(Query request, CancellationToken cancellationToken) - { - var room = await _context.Rooms.FirstOrDefaultAsync(x => x.Id == request.RoomId, cancellationToken); - if (room is null) - { - throw new KeyNotFoundException("Room does not exist."); - } - - var pageNumber = request.Page ?? 1; - var sizeNumber = request.Size ?? 5; - var lockers = _context.Lockers - .Where(x => x.Room.Id == request.RoomId - && x.IsAvailable - && x.Folders.Any(y => y.Capacity > y.NumberOfDocuments && y.IsAvailable)) - .ProjectTo(_mapper.ConfigurationProvider) - .AsEnumerable() - .ToList(); - - lockers.ForEach(x => x.Folders = x.Folders.Where(y => y.Slot > 0)); - - var result = new PaginatedList(lockers.ToList(), lockers.Count, pageNumber, sizeNumber); - return result; - } -} \ No newline at end of file diff --git a/src/Application/Rooms/Queries/GetRoomById.cs b/src/Application/Rooms/Queries/GetRoomById.cs new file mode 100644 index 00000000..6a3657bd --- /dev/null +++ b/src/Application/Rooms/Queries/GetRoomById.cs @@ -0,0 +1,12 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Rooms.Queries; + +public class GetRoomById +{ + public record Query : IRequest + { + public Guid RoomId { get; init; } + } +} \ No newline at end of file diff --git a/src/Application/Staffs/Commands/Add/Command.cs b/src/Application/Staffs/Commands/Add/Command.cs deleted file mode 100644 index ffed9ca2..00000000 --- a/src/Application/Staffs/Commands/Add/Command.cs +++ /dev/null @@ -1,48 +0,0 @@ -using Application.Common.Interfaces; -using Application.Common.Models.Dtos.Physical; -using AutoMapper; -using Domain.Entities.Physical; -using MediatR; -using Microsoft.EntityFrameworkCore; - -namespace Application.Staffs.Commands.Add; - -public record Command : IRequest -{ - public Guid UserId { get; init; } - public Guid? RoomId { get; init; } -} - -public class CommandHandler : IRequestHandler -{ - private readonly IApplicationDbContext _context; - private readonly IMapper _mapper; - - public CommandHandler(IApplicationDbContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - - public async Task Handle(Command request, CancellationToken cancellationToken) - { - var user = await _context.Users.FirstOrDefaultAsync(x => x.Id == request.UserId, cancellationToken); - if (user is null) - { - throw new KeyNotFoundException("User does not exist."); - } - - var room = await _context.Rooms.FirstOrDefaultAsync(x => x.Id == request.RoomId, cancellationToken); - - var staff = new Staff - { - Id = user.Id, - User = user, - Room = room - }; - - var result = await _context.Staffs.AddAsync(staff, cancellationToken); - await _context.SaveChangesAsync(cancellationToken); - return _mapper.Map(result.Entity); - } -} \ No newline at end of file diff --git a/src/Application/Staffs/Commands/AddStaff.cs b/src/Application/Staffs/Commands/AddStaff.cs new file mode 100644 index 00000000..c3415e00 --- /dev/null +++ b/src/Application/Staffs/Commands/AddStaff.cs @@ -0,0 +1,51 @@ +using Application.Common.Interfaces; +using Application.Common.Models.Dtos.Physical; +using AutoMapper; +using Domain.Entities.Physical; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace Application.Staffs.Commands; + +public class AddStaff +{ + public record Command : IRequest + { + public Guid UserId { get; init; } + public Guid? RoomId { get; init; } + } + + public class CommandHandler : IRequestHandler + { + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + + public CommandHandler(IApplicationDbContext context, IMapper mapper) + { + _context = context; + _mapper = mapper; + } + + public async Task Handle(Command request, CancellationToken cancellationToken) + { + var user = await _context.Users.FirstOrDefaultAsync(x => x.Id == request.UserId, cancellationToken); + if (user is null) + { + throw new KeyNotFoundException("User does not exist."); + } + + var room = await _context.Rooms.FirstOrDefaultAsync(x => x.Id == request.RoomId, cancellationToken); + + var staff = new Staff + { + Id = user.Id, + User = user, + Room = room + }; + + var result = await _context.Staffs.AddAsync(staff, cancellationToken); + await _context.SaveChangesAsync(cancellationToken); + return _mapper.Map(result.Entity); + } + } +} \ No newline at end of file diff --git a/src/Application/Staffs/Commands/RemoveFromRoom/Command.cs b/src/Application/Staffs/Commands/RemoveFromRoom/Command.cs deleted file mode 100644 index df64dcf8..00000000 --- a/src/Application/Staffs/Commands/RemoveFromRoom/Command.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Staffs.Commands.RemoveFromRoom; - -public record Command : IRequest -{ - public Guid StaffId { get; init; } - public Guid RoomId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Staffs/Commands/RemoveStaffFromRoom.cs b/src/Application/Staffs/Commands/RemoveStaffFromRoom.cs new file mode 100644 index 00000000..8ef73843 --- /dev/null +++ b/src/Application/Staffs/Commands/RemoveStaffFromRoom.cs @@ -0,0 +1,13 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Staffs.Commands; + +public class RemoveStaffFromRoom +{ + public record Command : IRequest + { + public Guid StaffId { get; init; } + public Guid RoomId { get; init; } + } +} \ No newline at end of file diff --git a/src/Application/Staffs/Queries/GetAllPaginated/Query.cs b/src/Application/Staffs/Queries/GetAllPaginated/Query.cs deleted file mode 100644 index b3911b3d..00000000 --- a/src/Application/Staffs/Queries/GetAllPaginated/Query.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Application.Common.Models; -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Staffs.Queries.GetAllPaginated; - -public class Query : IRequest> -{ - public string? SearchTerm { get; set; } - public int? Page { get; set; } - public int? Size { get; set; } - public string? SortBy { get; set; } - public string? SortOrder { get; set; } -} \ No newline at end of file diff --git a/src/Application/Staffs/Queries/GetAllStaffsPaginated.cs b/src/Application/Staffs/Queries/GetAllStaffsPaginated.cs new file mode 100644 index 00000000..270dfe77 --- /dev/null +++ b/src/Application/Staffs/Queries/GetAllStaffsPaginated.cs @@ -0,0 +1,17 @@ +using Application.Common.Models; +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Staffs.Queries; + +public class GetAllStaffsPaginated +{ + public class Query : IRequest> + { + public string? SearchTerm { get; set; } + public int? Page { get; set; } + public int? Size { get; set; } + public string? SortBy { get; set; } + public string? SortOrder { get; set; } + } +} \ No newline at end of file diff --git a/src/Application/Staffs/Queries/GetById/Query.cs b/src/Application/Staffs/Queries/GetById/Query.cs deleted file mode 100644 index 432aea43..00000000 --- a/src/Application/Staffs/Queries/GetById/Query.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Staffs.Queries.GetById; - -public record Query : IRequest -{ - public Guid StaffId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Staffs/Queries/GetByRoom/Query.cs b/src/Application/Staffs/Queries/GetByRoom/Query.cs deleted file mode 100644 index 4bdd850a..00000000 --- a/src/Application/Staffs/Queries/GetByRoom/Query.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Application.Common.Models.Dtos.Physical; -using MediatR; - -namespace Application.Staffs.Queries.GetByRoom; - -public record Query : IRequest -{ - public Guid RoomId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Staffs/Queries/GetStaffById.cs b/src/Application/Staffs/Queries/GetStaffById.cs new file mode 100644 index 00000000..7510235e --- /dev/null +++ b/src/Application/Staffs/Queries/GetStaffById.cs @@ -0,0 +1,12 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Staffs.Queries; + +public class GetStaffById +{ + public record Query : IRequest + { + public Guid StaffId { get; init; } + } +} \ No newline at end of file diff --git a/src/Application/Staffs/Queries/GetStaffByRoom.cs b/src/Application/Staffs/Queries/GetStaffByRoom.cs new file mode 100644 index 00000000..9f1ac07b --- /dev/null +++ b/src/Application/Staffs/Queries/GetStaffByRoom.cs @@ -0,0 +1,12 @@ +using Application.Common.Models.Dtos.Physical; +using MediatR; + +namespace Application.Staffs.Queries; + +public class GetStaffByRoom +{ + public record Query : IRequest + { + public Guid RoomId { get; init; } + } +} \ No newline at end of file diff --git a/src/Application/Users/Commands/Add/Command.cs b/src/Application/Users/Commands/Add/Command.cs deleted file mode 100644 index c5089184..00000000 --- a/src/Application/Users/Commands/Add/Command.cs +++ /dev/null @@ -1,73 +0,0 @@ -using Application.Common.Exceptions; -using Application.Common.Interfaces; -using Application.Helpers; -using Application.Users.Queries; -using AutoMapper; -using Domain.Entities; -using Domain.Events; -using MediatR; -using Microsoft.EntityFrameworkCore; -using NodaTime; - -namespace Application.Users.Commands.Add; - -public record Command : IRequest -{ - public string Username { get; init; } = null!; - public string Email { get; init; } = null!; - public string Password { get; init; } = null!; - public string? FirstName { get; init; } - public string? LastName { get; init; } - public Guid DepartmentId { get; init; } - public string Role { get; init; } = null!; - public string? Position { get; init; } -} - -public class AddUserCommandHandler : IRequestHandler -{ - private readonly IApplicationDbContext _context; - private readonly IMapper _mapper; - public AddUserCommandHandler(IApplicationDbContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - public async Task Handle(Command request, CancellationToken cancellationToken) - { - var user = await _context.Users.FirstOrDefaultAsync( - x => x.Username.Equals(request.Username) || x.Email.Equals(request.Email), cancellationToken); - - if (user is not null) - { - throw new ConflictException("Username or Email has been taken."); - } - - var department = await _context.Departments - .FirstOrDefaultAsync(x => x.Id == request.DepartmentId, cancellationToken); - - if (department is null) - { - throw new KeyNotFoundException("Department does not exist."); - } - - var entity = new User - { - Username = request.Username, - PasswordHash = SecurityUtil.Hash(request.Password), - Email = request.Email, - FirstName = request.FirstName?.Trim(), - LastName = request.LastName?.Trim(), - Department = department, - Role = request.Role, - Position = request.Position, - IsActive = true, - IsActivated = false, - Created = LocalDateTime.FromDateTime(DateTime.UtcNow) - }; - entity.AddDomainEvent(new UserCreatedEvent(entity)); - var result = await _context.Users.AddAsync(entity, cancellationToken); - await _context.SaveChangesAsync(cancellationToken); - return _mapper.Map(result.Entity); - } -} - diff --git a/src/Application/Users/Commands/Add/Validator.cs b/src/Application/Users/Commands/Add/Validator.cs deleted file mode 100644 index 2eb3a1d0..00000000 --- a/src/Application/Users/Commands/Add/Validator.cs +++ /dev/null @@ -1,43 +0,0 @@ -using Application.Identity; -using FluentValidation; - -namespace Application.Users.Commands.Add; - -public class Validator : AbstractValidator -{ - public Validator() - { - RuleLevelCascadeMode = CascadeMode.Stop; - - RuleFor(x => x.Username) - .NotEmpty().WithMessage("Username is required.") - .MaximumLength(50).WithMessage("Username cannot exceed 64 characters."); - - RuleFor(x => x.Email) - .NotEmpty().WithMessage("Email is required.") - .EmailAddress().WithMessage("Require valid email.") - .MaximumLength(320).WithMessage("Email length too long."); - - RuleFor(x => x.Password) - .NotEmpty().WithMessage("Password is required."); - - RuleFor(x => x.Role) - .NotEmpty().WithMessage("Role is required.") - .MaximumLength(64).WithMessage("Role cannot exceed 64 characters.") - .Must(BeNotAdmin).WithMessage("Cannot add a user as Administrator."); - - RuleFor(x => x.FirstName) - .MaximumLength(50).WithMessage("First name cannot exceed 50 characters."); - - RuleFor(x => x.LastName) - .MaximumLength(50).WithMessage("Last name cannot exceed 50 characters."); - - RuleFor(x => x.Position) - .MaximumLength(64).WithMessage("Position cannot exceed 64 characters."); - } - - private static bool BeNotAdmin(string role) - { - return !role.Equals(IdentityData.Roles.Admin); - } -} \ No newline at end of file diff --git a/src/Application/Users/Commands/AddUser.cs b/src/Application/Users/Commands/AddUser.cs new file mode 100644 index 00000000..448b8c08 --- /dev/null +++ b/src/Application/Users/Commands/AddUser.cs @@ -0,0 +1,118 @@ +using Application.Common.Exceptions; +using Application.Common.Interfaces; +using Application.Helpers; +using Application.Identity; +using Application.Users.Queries; +using AutoMapper; +using Domain.Entities; +using Domain.Events; +using FluentValidation; +using MediatR; +using Microsoft.EntityFrameworkCore; +using NodaTime; + +namespace Application.Users.Commands; + +public class AddUser +{ + public class Validator : AbstractValidator + { + public Validator() + { + RuleLevelCascadeMode = CascadeMode.Stop; + + RuleFor(x => x.Username) + .NotEmpty().WithMessage("Username is required.") + .MaximumLength(50).WithMessage("Username cannot exceed 64 characters."); + + RuleFor(x => x.Email) + .NotEmpty().WithMessage("Email is required.") + .EmailAddress().WithMessage("Require valid email.") + .MaximumLength(320).WithMessage("Email length too long."); + + RuleFor(x => x.Password) + .NotEmpty().WithMessage("Password is required."); + + RuleFor(x => x.Role) + .NotEmpty().WithMessage("Role is required.") + .MaximumLength(64).WithMessage("Role cannot exceed 64 characters.") + .Must(BeNotAdmin).WithMessage("Cannot add a user as Administrator."); + + RuleFor(x => x.FirstName) + .MaximumLength(50).WithMessage("First name cannot exceed 50 characters."); + + RuleFor(x => x.LastName) + .MaximumLength(50).WithMessage("Last name cannot exceed 50 characters."); + + RuleFor(x => x.Position) + .MaximumLength(64).WithMessage("Position cannot exceed 64 characters."); + } + + private static bool BeNotAdmin(string role) + { + return !role.Equals(IdentityData.Roles.Admin); + } + } + + public record Command : IRequest + { + public string Username { get; init; } = null!; + public string Email { get; init; } = null!; + public string Password { get; init; } = null!; + public string? FirstName { get; init; } + public string? LastName { get; init; } + public Guid DepartmentId { get; init; } + public string Role { get; init; } = null!; + public string? Position { get; init; } + } + + public class AddUserCommandHandler : IRequestHandler + { + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + + public AddUserCommandHandler(IApplicationDbContext context, IMapper mapper) + { + _context = context; + _mapper = mapper; + } + + public async Task Handle(Command request, CancellationToken cancellationToken) + { + var user = await _context.Users.FirstOrDefaultAsync( + x => x.Username.Equals(request.Username) || x.Email.Equals(request.Email), cancellationToken); + + if (user is not null) + { + throw new ConflictException("Username or Email has been taken."); + } + + var department = await _context.Departments + .FirstOrDefaultAsync(x => x.Id == request.DepartmentId, cancellationToken); + + if (department is null) + { + throw new KeyNotFoundException("Department does not exist."); + } + + var entity = new User + { + Username = request.Username, + PasswordHash = SecurityUtil.Hash(request.Password), + Email = request.Email, + FirstName = request.FirstName?.Trim(), + LastName = request.LastName?.Trim(), + Department = department, + Role = request.Role, + Position = request.Position, + IsActive = true, + IsActivated = false, + Created = LocalDateTime.FromDateTime(DateTime.UtcNow) + }; + entity.AddDomainEvent(new UserCreatedEvent(entity)); + var result = await _context.Users.AddAsync(entity, cancellationToken); + await _context.SaveChangesAsync(cancellationToken); + return _mapper.Map(result.Entity); + } + } +} \ No newline at end of file diff --git a/src/Application/Users/Commands/Disable/Command.cs b/src/Application/Users/Commands/Disable/Command.cs deleted file mode 100644 index 78f028cd..00000000 --- a/src/Application/Users/Commands/Disable/Command.cs +++ /dev/null @@ -1,44 +0,0 @@ -using Application.Common.Exceptions; -using Application.Common.Interfaces; -using Application.Users.Queries; -using AutoMapper; -using MediatR; -using Microsoft.EntityFrameworkCore; - -namespace Application.Users.Commands.Disable; - -public record Command : IRequest -{ - public Guid UserId { get; init; } -} - -public class CommandHandler : IRequestHandler -{ - private readonly IApplicationDbContext _context; - private readonly IMapper _mapper; - public CommandHandler(IApplicationDbContext context, IMapper mapper) - { - _context = context; - _mapper = mapper; - } - - public async Task Handle(Command request, CancellationToken cancellationToken) - { - var user = await _context.Users.FirstOrDefaultAsync(x => x.Id == request.UserId, cancellationToken); - if (user is null) - { - throw new KeyNotFoundException("User does not exist."); - } - - if (!user.IsActive) - { - throw new ConflictException("User has already been disabled."); - } - - user.IsActive = false; - - var result = _context.Users.Update(user); - await _context.SaveChangesAsync(cancellationToken); - return _mapper.Map(result.Entity); - } -} \ No newline at end of file diff --git a/src/Application/Users/Commands/DisableUser.cs b/src/Application/Users/Commands/DisableUser.cs new file mode 100644 index 00000000..dafb4b31 --- /dev/null +++ b/src/Application/Users/Commands/DisableUser.cs @@ -0,0 +1,47 @@ +using Application.Common.Exceptions; +using Application.Common.Interfaces; +using Application.Users.Queries; +using AutoMapper; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace Application.Users.Commands; + +public class DisableUser +{ + public record Command : IRequest + { + public Guid UserId { get; init; } + } + + public class CommandHandler : IRequestHandler + { + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + public CommandHandler(IApplicationDbContext context, IMapper mapper) + { + _context = context; + _mapper = mapper; + } + + public async Task Handle(Command request, CancellationToken cancellationToken) + { + var user = await _context.Users.FirstOrDefaultAsync(x => x.Id == request.UserId, cancellationToken); + if (user is null) + { + throw new KeyNotFoundException("User does not exist."); + } + + if (!user.IsActive) + { + throw new ConflictException("User has already been disabled."); + } + + user.IsActive = false; + + var result = _context.Users.Update(user); + await _context.SaveChangesAsync(cancellationToken); + return _mapper.Map(result.Entity); + } + } +} \ No newline at end of file diff --git a/src/Application/Users/Commands/Enable/Command.cs b/src/Application/Users/Commands/Enable/Command.cs deleted file mode 100644 index b44eb202..00000000 --- a/src/Application/Users/Commands/Enable/Command.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Application.Users.Queries; -using MediatR; - -namespace Application.Users.Commands.Enable; - -public record Command : IRequest -{ - public Guid UserId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Users/Commands/EnableUser.cs b/src/Application/Users/Commands/EnableUser.cs new file mode 100644 index 00000000..7da8ab48 --- /dev/null +++ b/src/Application/Users/Commands/EnableUser.cs @@ -0,0 +1,12 @@ +using Application.Users.Queries; +using MediatR; + +namespace Application.Users.Commands; + +public class EnableUser +{ + public record Command : IRequest + { + public Guid UserId { get; init; } + } +} \ No newline at end of file diff --git a/src/Application/Users/Commands/Update/Command.cs b/src/Application/Users/Commands/Update/Command.cs deleted file mode 100644 index 44de6990..00000000 --- a/src/Application/Users/Commands/Update/Command.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Application.Users.Queries; -using MediatR; - -namespace Application.Users.Commands.Update; - -public record Command : IRequest -{ - public Guid UserId { get; init; } - public string Username { get; init; } = null!; - public string Email { get; init; } = null!; - public string? FirstName { get; init; } - public string? LastName { get; init; } - public string Role { get; init; } = null!; - public string? Position { get; init; } -} \ No newline at end of file diff --git a/src/Application/Users/Commands/UpdateUser.cs b/src/Application/Users/Commands/UpdateUser.cs new file mode 100644 index 00000000..4d894cc0 --- /dev/null +++ b/src/Application/Users/Commands/UpdateUser.cs @@ -0,0 +1,16 @@ +using Application.Users.Queries; +using MediatR; + +namespace Application.Users.Commands; + +public class UpdateUser +{ + public record Command : IRequest + { + public Guid UserId { get; init; } + public string? FirstName { get; init; } + public string? LastName { get; init; } + public string Role { get; init; } = null!; + public string? Position { get; init; } + } +} \ No newline at end of file diff --git a/src/Application/Users/Queries/GetAllPaginated/Query.cs b/src/Application/Users/Queries/GetAllPaginated/Query.cs deleted file mode 100644 index a09e16f9..00000000 --- a/src/Application/Users/Queries/GetAllPaginated/Query.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Application.Common.Models; -using MediatR; - -namespace Application.Users.Queries.GetAllPaginated; - -public record Query : IRequest> -{ - public Guid? DepartmentId { get; init; } - public string? SearchTerm { get; init; } - public int? Page { get; init; } - public int? Size { get; init; } - public string? SortBy { get; init; } - public string? SortOrder { get; init; } -} \ No newline at end of file diff --git a/src/Application/Users/Queries/GetAllUsersPaginated.cs b/src/Application/Users/Queries/GetAllUsersPaginated.cs new file mode 100644 index 00000000..738ed5ea --- /dev/null +++ b/src/Application/Users/Queries/GetAllUsersPaginated.cs @@ -0,0 +1,17 @@ +using Application.Common.Models; +using MediatR; + +namespace Application.Users.Queries; + +public class GetAllUsersPaginated +{ + public record Query : IRequest> + { + public Guid? DepartmentId { get; init; } + public string? SearchTerm { get; init; } + public int? Page { get; init; } + public int? Size { get; init; } + public string? SortBy { get; init; } + public string? SortOrder { get; init; } + } +} \ No newline at end of file diff --git a/src/Application/Users/Queries/GetById/Query.cs b/src/Application/Users/Queries/GetById/Query.cs deleted file mode 100644 index 4b42b38f..00000000 --- a/src/Application/Users/Queries/GetById/Query.cs +++ /dev/null @@ -1,8 +0,0 @@ -using MediatR; - -namespace Application.Users.Queries.GetById; - -public record Query : IRequest -{ - public Guid UserId { get; init; } -} \ No newline at end of file diff --git a/src/Application/Users/Queries/GetUserById.cs b/src/Application/Users/Queries/GetUserById.cs new file mode 100644 index 00000000..e34b58d2 --- /dev/null +++ b/src/Application/Users/Queries/GetUserById.cs @@ -0,0 +1,11 @@ +using MediatR; + +namespace Application.Users.Queries; + +public class GetUserById +{ + public record Query : IRequest + { + public Guid UserId { get; init; } + } +} \ No newline at end of file diff --git a/tests/Application.Tests.Integration/BaseClassFixture.cs b/tests/Application.Tests.Integration/BaseClassFixture.cs index f662baeb..05de90de 100644 --- a/tests/Application.Tests.Integration/BaseClassFixture.cs +++ b/tests/Application.Tests.Integration/BaseClassFixture.cs @@ -1,4 +1,3 @@ -using Application.Departments.Commands.Add; using Application.Helpers; using Bogus; using Domain.Common; @@ -16,19 +15,16 @@ namespace Application.Tests.Integration; [Collection(nameof(BaseCollectionFixture))] public class BaseClassFixture { - protected readonly Faker _departmentGenerator = new Faker() - .RuleFor(x => x.Name, faker => faker.Commerce.Department()); - - protected static IServiceScopeFactory _scopeFactory = null!; + protected static IServiceScopeFactory ScopeFactory = null!; protected BaseClassFixture(CustomApiFactory apiFactory) { - _scopeFactory = apiFactory.Services.GetRequiredService(); + ScopeFactory = apiFactory.Services.GetRequiredService(); } protected static async Task SendAsync(IRequest request) { - using var scope = _scopeFactory.CreateScope(); + using var scope = ScopeFactory.CreateScope(); var mediator = scope.ServiceProvider.GetRequiredService(); @@ -37,7 +33,7 @@ protected static async Task SendAsync(IRequest protected void Remove(TEntity entity) where TEntity : BaseEntity? { - using var scope = _scopeFactory.CreateScope(); + using var scope = ScopeFactory.CreateScope(); var dbContext = scope.ServiceProvider.GetRequiredService(); @@ -48,7 +44,7 @@ protected void Remove(TEntity entity) where TEntity : BaseEntity? protected static async Task FindAsync(params object[] keyValues) where TEntity : class { - using var scope = _scopeFactory.CreateScope(); + using var scope = ScopeFactory.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); @@ -58,7 +54,7 @@ protected void Remove(TEntity entity) where TEntity : BaseEntity? protected static async Task AddAsync(TEntity entity) where TEntity : class { - using var scope = _scopeFactory.CreateScope(); + using var scope = ScopeFactory.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); @@ -70,7 +66,7 @@ protected static async Task AddAsync(TEntity entity) protected static async Task Add(TEntity entity) where TEntity : class { - using var scope = _scopeFactory.CreateScope(); + using var scope = ScopeFactory.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); @@ -81,7 +77,7 @@ protected static async Task Add(TEntity entity) protected static async Task CountAsync() where TEntity : class { - using var scope = _scopeFactory.CreateScope(); + using var scope = ScopeFactory.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); diff --git a/tests/Application.Tests.Integration/Departments/Commands/AddDepartmentTests.cs b/tests/Application.Tests.Integration/Departments/Commands/AddDepartmentTests.cs index 0e9ebf10..db3746e7 100644 --- a/tests/Application.Tests.Integration/Departments/Commands/AddDepartmentTests.cs +++ b/tests/Application.Tests.Integration/Departments/Commands/AddDepartmentTests.cs @@ -1,4 +1,5 @@ using Application.Common.Exceptions; +using Application.Departments.Commands; using Domain.Entities; using FluentAssertions; using Xunit; @@ -15,7 +16,10 @@ public AddDepartmentTests(CustomApiFactory apiFactory) : base(apiFactory) public async Task ShouldCreateDepartment_WhenDepartmentNameIsValid() { // Arrange - var createDepartmentCommand = _departmentGenerator.Generate(); + var createDepartmentCommand = new AddDepartment.Command() + { + Name = "something", + }; // Act var department = await SendAsync(createDepartmentCommand); @@ -32,11 +36,16 @@ public async Task ShouldCreateDepartment_WhenDepartmentNameIsValid() public async Task ShouldReturnConflict_WhenDepartmentNameHasExisted() { // Arrange - var createDepartmentCommand = _departmentGenerator.Generate(); - var department = await SendAsync(createDepartmentCommand); + var department = CreateDepartment(); + await AddAsync(department); + + var command = new AddDepartment.Command() + { + Name = department.Name, + }; // Act - var action = async () => await SendAsync(createDepartmentCommand); + var action = async () => await SendAsync(command); // Assert await action.Should().ThrowAsync().WithMessage("Department name already exists."); diff --git a/tests/Application.Tests.Integration/Departments/Queries/GetAllDepartmentsTests.cs b/tests/Application.Tests.Integration/Departments/Queries/GetAllDepartmentsTests.cs index a1ea2694..90b39fd9 100644 --- a/tests/Application.Tests.Integration/Departments/Queries/GetAllDepartmentsTests.cs +++ b/tests/Application.Tests.Integration/Departments/Queries/GetAllDepartmentsTests.cs @@ -1,6 +1,5 @@ using Application.Common.Mappings; -using Application.Departments.Queries.GetAll; -using Application.Identity; +using Application.Departments.Queries; using Application.Users.Queries; using AutoMapper; using Bogus; @@ -30,7 +29,7 @@ public async Task ShouldReturnDepartments_WhenDepartmentsExist() Name = new Faker().Commerce.Department() }; await AddAsync(department); - var query = new Query(); + var query = new GetAllDepartments.Query(); // Act var result = await SendAsync(query); @@ -46,7 +45,7 @@ public async Task ShouldReturnDepartments_WhenDepartmentsExist() public async Task ShouldReturnEmptyList_WhenNoDepartmentsExist() { // Arrange - var query = new Query(); + var query = new GetAllDepartments.Query(); // Act var result = await SendAsync(query); diff --git a/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentTypesTests.cs b/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentTypesTests.cs index 6e12eb56..8d74f004 100644 --- a/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentTypesTests.cs +++ b/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentTypesTests.cs @@ -1,4 +1,4 @@ -using Application.Documents.Queries.GetDocumentTypes; +using Application.Documents.Queries; using Bogus; using Domain.Entities.Physical; using FluentAssertions; @@ -23,7 +23,7 @@ public async Task ShouldReturnDocumentTypes_WhenDocumentTypesExist() DocumentType = new Faker().Commerce.ProductName(), }; await AddAsync(document); - var query = new Query(); + var query = new GetAllDocumentTypes.Query(); // Act var result = await SendAsync(query); @@ -39,7 +39,7 @@ public async Task ShouldReturnDocumentTypes_WhenDocumentTypesExist() public async Task ShouldReturnEmptyList_WhenNoDocumentTypesExist() { // Arrange - var query = new Query(); + var query = new GetAllDocumentTypes.Query(); // Act var result = await SendAsync(query); diff --git a/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentsPaginatedTests.cs b/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentsPaginatedTests.cs index b5bc4b16..70e69946 100644 --- a/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentsPaginatedTests.cs +++ b/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentsPaginatedTests.cs @@ -2,7 +2,7 @@ using Application.Common.Extensions; using Application.Common.Mappings; using Application.Common.Models.Dtos.Physical; - using Application.Documents.Queries.GetAllPaginated; + using Application.Documents.Queries; using AutoMapper; using FluentAssertions; using Xunit; @@ -29,7 +29,7 @@ public async Task ShouldReturnAllDocuments_WhenNoContainersAreDefined() var room = CreateRoom(locker); await AddAsync(room); - var query = new Query(); + var query = new GetAllDocumentsPaginated.Query(); // Act var result = await SendAsync(query); @@ -52,7 +52,7 @@ public async Task ShouldReturnEmptyPaginatedList_WhenNoDocumentsExist() await AddAsync(room); - var query = new Query() + var query = new GetAllDocumentsPaginated.Query() { RoomId = room.Id }; @@ -90,7 +90,7 @@ public async Task ShouldReturnDocumentsOfRoom_WhenOnlyRoomIdIsPresent() await AddAsync(room1); await AddAsync(room2); - var query = new Query() + var query = new GetAllDocumentsPaginated.Query() { RoomId = room1.Id }; @@ -121,7 +121,7 @@ public async Task ShouldReturnDocumentsOfRoom_WhenOnlyRoomIdIsPresent() public async Task ShouldThrowKeyNotFoundException_WhenOnlyRoomIdIsPresentButDoesNotExist() { // Arrange - var query = new Query() + var query = new GetAllDocumentsPaginated.Query() { RoomId = Guid.NewGuid() }; @@ -153,7 +153,7 @@ public async Task ShouldReturnDocumentsOfLocker_WhenOnlyRoomIdAndLockerIdArePres await AddAsync(room); - var query = new Query() + var query = new GetAllDocumentsPaginated.Query() { RoomId = room.Id, LockerId = locker1.Id @@ -185,7 +185,7 @@ public async Task ShouldThrowKeyNotFoundException_WhenOnlyRoomIdAndLockerIdArePr var room = CreateRoom(); await AddAsync(room); - var query = new Query() + var query = new GetAllDocumentsPaginated.Query() { RoomId = room.Id, LockerId = Guid.NewGuid() @@ -214,7 +214,7 @@ public async Task ShouldThrowConflictException_WhenOnlyRoomIdAndLockerIdArePrese await AddAsync(room1); await AddAsync(room2); - var query = new Query() + var query = new GetAllDocumentsPaginated.Query() { RoomId = room1.Id, LockerId = locker.Id @@ -246,7 +246,7 @@ public async Task ShouldReturnDocumentsOfFolder_WhenAllIdsArePresentAndFolderIsI var room = CreateRoom(locker); await AddAsync(room); - var query = new Query() + var query = new GetAllDocumentsPaginated.Query() { RoomId = room.Id, LockerId = locker.Id, @@ -280,7 +280,7 @@ public async Task ShouldThrowKeyNotFoundException_WhenAllIdsArePresentAndValidAn await AddAsync(room); - var query = new Query() + var query = new GetAllDocumentsPaginated.Query() { RoomId = room.Id, LockerId = locker.Id, @@ -313,14 +313,14 @@ public async Task ShouldThrowConflictException_WhenAllIdsArePresentAndFolderIsNo await AddAsync(room1); await AddAsync(room2); - var query1 = new Query() + var query1 = new GetAllDocumentsPaginated.Query() { RoomId = room1.Id, LockerId = locker2.Id, FolderId = folder1.Id }; - var query2 = new Query() + var query2 = new GetAllDocumentsPaginated.Query() { RoomId = room1.Id, LockerId = locker2.Id, @@ -355,7 +355,7 @@ public async Task ShouldReturnSortedByIdPaginatedList_WhenSortByIsNotPresent() await AddAsync(room); - var query = new Query() + var query = new GetAllDocumentsPaginated.Query() { RoomId = room.Id }; @@ -393,7 +393,7 @@ public async Task ShouldReturnSortedByPropertyPaginatedList_WhenSortByIsPresent( await AddAsync(room); - var query = new Query() + var query = new GetAllDocumentsPaginated.Query() { RoomId = room.Id, SortBy = sortBy, diff --git a/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs b/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs index f266077d..7b211420 100644 --- a/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs +++ b/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs @@ -1,11 +1,9 @@ using Application.Common.Exceptions; -using Application.Common.Models.Dtos.Physical; -using Bogus; +using Application.Folders.Commands; using Domain.Entities.Physical; using Domain.Exceptions; using FluentAssertions; using Xunit; -using Application.Folders.Commands.Add; namespace Application.Tests.Integration.Folders.Commands; @@ -23,7 +21,7 @@ public async Task ShouldAddFolder_WhenAddDetailsAreValid() var room = CreateRoom(locker); await AddAsync(room); - var command = new Command() + var command = new AddFolder.Command() { LockerId = locker.Id, Capacity = 1, @@ -59,7 +57,7 @@ public async Task ShouldAddFolder_WhenFoldersHasSameNameButInDifferentLockers() var room = CreateRoom(locker1, locker2); await AddAsync(room); - var command = new Command() + var command = new AddFolder.Command() { LockerId = locker2.Id, Name = folder1.Name, @@ -89,7 +87,7 @@ public async Task ShouldThrowConflictException_WhenFolderAlreadyExistsInTheSameL var room = CreateRoom(locker); await AddAsync(room); - var command = new Command() + var command = new AddFolder.Command() { Name = folder.Name, LockerId = locker.Id, @@ -120,7 +118,7 @@ public async Task ShouldThrowLimitExceededException_WhenGoingOverCapacity() var room = CreateRoom(locker); await AddAsync(room); - var command = new Command() + var command = new AddFolder.Command() { Name = "something", Capacity = 3, @@ -147,7 +145,7 @@ await action.Should().ThrowAsync() public async Task ShouldThrowKeyNotFoundException_WhenLockerIdNotExists() { // Arrange - var command = new Command() + var command = new AddFolder.Command() { LockerId = Guid.NewGuid(), Name = "something", diff --git a/tests/Application.Tests.Integration/Folders/Commands/DisableFolderTests.cs b/tests/Application.Tests.Integration/Folders/Commands/DisableFolderTests.cs index e3ee20b8..02a9e97b 100644 --- a/tests/Application.Tests.Integration/Folders/Commands/DisableFolderTests.cs +++ b/tests/Application.Tests.Integration/Folders/Commands/DisableFolderTests.cs @@ -1,5 +1,5 @@ using Application.Common.Exceptions; -using Application.Folders.Commands.Disable; +using Application.Folders.Commands; using Domain.Entities.Physical; using FluentAssertions; using Xunit; @@ -46,7 +46,7 @@ public async Task ShouldDisableFolder_WhenFolderHaveNoDocument() }; await AddAsync(folder); - var disableFolderCommand = new Command() + var disableFolderCommand = new DisableFolder.Command() { FolderId = folder.Id }; @@ -67,7 +67,7 @@ public async Task ShouldDisableFolder_WhenFolderHaveNoDocument() public async Task ShouldThrowKeyNotFoundException_WhenFolderDoesNotExist() { // Arrange - var disableFolderCommand = new Command() + var disableFolderCommand = new DisableFolder.Command() { FolderId = Guid.NewGuid() }; @@ -113,7 +113,7 @@ public async Task ShouldThrowInvalidOperationException_WhenFolderIsAlreadyDisabl Locker = locker }; await AddAsync(folder); - var disableFolderCommand = new Command() + var disableFolderCommand = new DisableFolder.Command() { FolderId = folder.Id }; @@ -173,7 +173,7 @@ public async Task ShouldThrowInvalidOperationException_WhenFolderHasDocuments() }; await AddAsync(document); - var disableFolderCommand = new Command() + var disableFolderCommand = new DisableFolder.Command() { FolderId = folder.Id }; diff --git a/tests/Application.Tests.Integration/Lockers/Commands/AddLockerTests.cs b/tests/Application.Tests.Integration/Lockers/Commands/AddLockerTests.cs index aab654d2..2da1413f 100644 --- a/tests/Application.Tests.Integration/Lockers/Commands/AddLockerTests.cs +++ b/tests/Application.Tests.Integration/Lockers/Commands/AddLockerTests.cs @@ -1,5 +1,5 @@ using Application.Common.Exceptions; -using Application.Lockers.Commands.Add; +using Application.Lockers.Commands; using Bogus; using Domain.Entities.Physical; using Domain.Exceptions; @@ -12,7 +12,6 @@ public class AddLockerTests : BaseClassFixture { public AddLockerTests(CustomApiFactory apiFactory) : base(apiFactory) { - } [Fact] @@ -31,7 +30,7 @@ public async Task ShouldReturnLocker_WhenCreateDetailsAreValid() await AddAsync(room); - var addLockerCommand = new Command() + var addLockerCommand = new AddLocker.Command() { Name = new Faker().Name.JobTitle(), Description = new Faker().Lorem.Sentence(), @@ -75,7 +74,7 @@ public async Task ShouldThrowConflictException_WhenLockerAlreadyExistsInTheSameR await AddAsync(room); - var addLockerCommand = new Command() + var addLockerCommand = new AddLocker.Command() { Name = new Faker().Name.JobTitle(), Description = new Faker().Lorem.Sentence(), @@ -124,7 +123,7 @@ public async Task ShouldReturnLocker_WhenLockersHasSameNameButInDifferentRooms() await AddAsync(room2); - var addLockerCommand = new Command() + var addLockerCommand = new AddLocker.Command() { Name = new Faker().Name.JobTitle(), Description = new Faker().Lorem.Sentence(), @@ -132,7 +131,7 @@ public async Task ShouldReturnLocker_WhenLockersHasSameNameButInDifferentRooms() RoomId = room1.Id, }; - var addLockerCommand2 = new Command() + var addLockerCommand2 = new AddLocker.Command() { Name = addLockerCommand.Name, Description = new Faker().Lorem.Sentence(), @@ -179,7 +178,7 @@ public async Task ShouldThrowLimitExceededException_WhenGoingOverCapacity() await AddAsync(room); - var addLockerCommand = new Command() + var addLockerCommand = new AddLocker.Command() { Name = new Faker().Name.JobTitle(), Description = new Faker().Lorem.Sentence(), @@ -187,7 +186,7 @@ public async Task ShouldThrowLimitExceededException_WhenGoingOverCapacity() RoomId = room.Id, }; - var addLockerCommand2 = new Command() + var addLockerCommand2 = new AddLocker.Command() { Name = new Faker().Name.JobTitle(), Description = new Faker().Lorem.Sentence(), diff --git a/tests/Application.Tests.Integration/Lockers/Commands/DisableLockerTests.cs b/tests/Application.Tests.Integration/Lockers/Commands/DisableLockerTests.cs index 0dfa0101..99e3d39c 100644 --- a/tests/Application.Tests.Integration/Lockers/Commands/DisableLockerTests.cs +++ b/tests/Application.Tests.Integration/Lockers/Commands/DisableLockerTests.cs @@ -1,9 +1,9 @@ using Application.Common.Exceptions; +using Application.Lockers.Commands; using Bogus; using Domain.Entities.Physical; using FluentAssertions; using Xunit; -using Command = Application.Lockers.Commands.Disable.Command; namespace Application.Tests.Integration.Lockers.Commands; @@ -11,37 +11,17 @@ public class DisableLockerTests : BaseClassFixture { public DisableLockerTests(CustomApiFactory apiFactory) : base(apiFactory) { - } [Fact] public async Task ShouldDisableLocker_WhenLockerExistsAndIsAvailable() { // Arrange - var room = new Room() - { - Id = Guid.NewGuid(), - Name = new Faker().Commerce.ProductName(), - Description = new Faker().Lorem.Sentence(), - Capacity = 1, - IsAvailable = true, - NumberOfLockers = 0, - }; - + var locker = CreateLocker(); + var room = CreateRoom(locker); await AddAsync(room); - var createLockerCommand = new Application.Lockers.Commands.Add.Command() - { - Name = new Faker().Commerce.ProductName(), - Description = new Faker().Lorem.Sentence(), - Capacity = 2, - RoomId = room.Id, - }; - - var locker = await SendAsync(createLockerCommand); - room.NumberOfLockers += 1; - - var disableLockerCommand = new Command() + var disableLockerCommand = new DisableLocker.Command() { LockerId = locker.Id, }; @@ -65,7 +45,7 @@ public async Task ShouldDisableLocker_WhenLockerExistsAndIsAvailable() public async Task ShouldThrowKeyNotFoundException_WhenLockerDoesNotExist() { // Arrange - var disableLockerCommand = new Command() + var disableLockerCommand = new DisableLocker.Command() { LockerId = Guid.NewGuid(), }; @@ -83,28 +63,11 @@ await action.Should() public async Task ShouldThrowConflictException_WhenLockerIsAlreadyDisabled() { // Arrange - var room = new Room() - { - Id = Guid.NewGuid(), - Name = new Faker().Commerce.ProductName(), - Description = new Faker().Lorem.Sentence(), - Capacity = 1, - IsAvailable = true, - NumberOfLockers = 0, - }; - + var locker = CreateLocker(); + var room = CreateRoom(locker); await AddAsync(room); - - var createLockerCommand = new Application.Lockers.Commands.Add.Command() - { - Name = new Faker().Commerce.ProductName(), - Description = new Faker().Lorem.Sentence(), - Capacity = 2, - RoomId = room.Id, - }; - var locker = await SendAsync(createLockerCommand); - var disableLockerCommand = new Command() + var disableLockerCommand = new DisableLocker.Command() { LockerId = locker.Id, }; diff --git a/tests/Application.Tests.Integration/Lockers/Commands/EnableLockerTests.cs b/tests/Application.Tests.Integration/Lockers/Commands/EnableLockerTests.cs index 17717c78..66d381cb 100644 --- a/tests/Application.Tests.Integration/Lockers/Commands/EnableLockerTests.cs +++ b/tests/Application.Tests.Integration/Lockers/Commands/EnableLockerTests.cs @@ -1,9 +1,9 @@ using Application.Common.Exceptions; +using Application.Lockers.Commands; using Bogus; using Domain.Entities.Physical; using FluentAssertions; using Xunit; -using Command = Application.Lockers.Commands.Disable.Command; namespace Application.Tests.Integration.Lockers.Commands; @@ -18,63 +18,37 @@ public EnableLockerTests(CustomApiFactory apiFactory) : base(apiFactory) public async Task ShouldEnableLocker_WhenLockerExistsAndIsNotAvailable() { // Arrange - var room = new Room() - { - Id = Guid.NewGuid(), - Name = new Faker().Commerce.ProductName(), - Description = new Faker().Lorem.Sentence(), - Capacity = 1, - IsAvailable = true, - NumberOfLockers = 0, - }; - + var locker = CreateLocker(); + locker.IsAvailable = false; + var room = CreateRoom(locker); await AddAsync(room); - var createLockerCommand = new Application.Lockers.Commands.Add.Command() - { - Name = new Faker().Commerce.ProductName(), - Description = new Faker().Lorem.Sentence(), - Capacity = 2, - RoomId = room.Id, - }; - - var locker = await SendAsync(createLockerCommand); - - var disableLockerCommand = new Command() - { - LockerId = locker.Id, - }; - - await SendAsync(disableLockerCommand); - // Act - - var enableLockerCommand = new Application.Lockers.Commands.Enable.Command() + var command = new EnableLocker.Command() { LockerId = locker.Id, }; - var result = await SendAsync(enableLockerCommand); + var result = await SendAsync(command); // Assert result.IsAvailable.Should().BeTrue(); // Cleanup - var roomEntity = await FindAsync(room.Id); - Remove(roomEntity); + Remove(room); } [Fact] public async Task ShouldThrowKeyNotFoundException_WhenLockerDoesNotExist() { // Arrange - var enableLockerCommand = new Application.Lockers.Commands.Enable.Command() + var command = new EnableLocker.Command() { LockerId = Guid.NewGuid(), }; // Act - var action = async () => await SendAsync(enableLockerCommand); + var action = async () => await SendAsync(command); // Assert await action.Should() @@ -86,28 +60,11 @@ await action.Should() public async Task ShouldThrowConflictException_WhenLockerIsAlreadyEnabled() { // Arrange - var room = new Room() - { - Id = Guid.NewGuid(), - Name = new Faker().Commerce.ProductName(), - Description = new Faker().Lorem.Sentence(), - Capacity = 1, - IsAvailable = true, - NumberOfLockers = 0, - }; - + var locker = CreateLocker(); + var room = CreateRoom(locker); await AddAsync(room); - - var createLockerCommand = new Application.Lockers.Commands.Add.Command() - { - Name = new Faker().Commerce.ProductName(), - Description = new Faker().Lorem.Sentence(), - Capacity = 2, - RoomId = room.Id, - }; - var locker = await SendAsync(createLockerCommand); - var enableLockerCommand = new Application.Lockers.Commands.Enable.Command() + var enableLockerCommand = new EnableLocker.Command() { LockerId = locker.Id, }; @@ -121,7 +78,6 @@ await action.Should() .WithMessage("Locker has already been enabled."); // Cleanup - var roomEntity = await FindAsync(room.Id); - Remove(roomEntity); + Remove(room); } } diff --git a/tests/Application.Tests.Integration/Rooms/Commands/DisableRoomTests.cs b/tests/Application.Tests.Integration/Rooms/Commands/DisableRoomTests.cs index 999e5745..b1327cf2 100644 --- a/tests/Application.Tests.Integration/Rooms/Commands/DisableRoomTests.cs +++ b/tests/Application.Tests.Integration/Rooms/Commands/DisableRoomTests.cs @@ -1,5 +1,5 @@ using Application.Common.Exceptions; -using Application.Rooms.Commands.Disable; +using Application.Rooms.Commands; using Domain.Entities.Physical; using FluentAssertions; using Xunit; @@ -21,7 +21,7 @@ public async Task ShouldDisableRoom_WhenRoomHaveNoDocument() var room = CreateRoom(locker); await AddAsync(room); - var disableRoomCommand = new Command() + var disableRoomCommand = new DisableRoom.Command() { RoomId = room.Id }; @@ -47,7 +47,7 @@ public async Task ShouldDisableRoom_WhenRoomHaveNoDocument() public async Task ShouldThrowKeyNotFoundException_WhenRoomDoesNotExist() { // Arrange - var disableRoomCommand = new Command() + var disableRoomCommand = new DisableRoom.Command() { RoomId = Guid.NewGuid() }; @@ -71,7 +71,7 @@ public async Task ShouldThrowInvalidOperationException_WhenRoomIsNotEmptyOfDocum await AddAsync(room); - var disableRoomCommand = new Command() + var disableRoomCommand = new DisableRoom.Command() { RoomId = room.Id }; @@ -98,7 +98,7 @@ public async Task ShouldThrowInvalidOperationException_WhenRoomIsNotAvailable() room.IsAvailable = false; await AddAsync(room); - var command = new Command() + var command = new DisableRoom.Command() { RoomId = room.Id }; diff --git a/tests/Application.Tests.Integration/Rooms/Commands/RemoveRoomTests.cs b/tests/Application.Tests.Integration/Rooms/Commands/RemoveRoomTests.cs index 20bbacaf..92919e45 100644 --- a/tests/Application.Tests.Integration/Rooms/Commands/RemoveRoomTests.cs +++ b/tests/Application.Tests.Integration/Rooms/Commands/RemoveRoomTests.cs @@ -1,4 +1,4 @@ -using Application.Rooms.Commands.Remove; +using Application.Rooms.Commands; using Domain.Entities.Physical; using FluentAssertions; using Xunit; @@ -18,7 +18,7 @@ public async Task ShouldRemoveRoom_WhenRoomHasNoDocuments() var room = CreateRoom(); await Add(room); - var command = new Command() + var command = new RemoveRoom.Command() { RoomId = room.Id }; @@ -41,7 +41,7 @@ public async Task ShouldThrowInvalidOperationException_WhenRoomHaveDocuments() var room = CreateRoom(locker); await AddAsync(room); - var command = new Command() + var command = new RemoveRoom.Command() { RoomId = room.Id }; @@ -64,7 +64,7 @@ await action.Should().ThrowAsync() public async Task ShouldThrowKeyNotFoundException_WhenRoomDoesNotExist() { // Arrange - var command = new Command() + var command = new RemoveRoom.Command() { RoomId = Guid.NewGuid() }; diff --git a/tests/Application.Tests.Integration/Rooms/Queries/GetEmptyContainersPaginatedTests.cs b/tests/Application.Tests.Integration/Rooms/Queries/GetEmptyContainersPaginatedTests.cs index ad8b7791..42246842 100644 --- a/tests/Application.Tests.Integration/Rooms/Queries/GetEmptyContainersPaginatedTests.cs +++ b/tests/Application.Tests.Integration/Rooms/Queries/GetEmptyContainersPaginatedTests.cs @@ -1,4 +1,4 @@ -using Application.Rooms.Queries.GetEmptyContainersPaginated; +using Application.Rooms.Queries; using Bogus; using Domain.Entities.Physical; using FluentAssertions; @@ -19,7 +19,7 @@ public async Task ShouldReturnLockersWithEmptyFolders() { // Arrange var room = await SetupTestEntities(); - var query = new Query() + var query = new GetEmptyContainersPaginated.Query() { Page = 1, Size = 2, @@ -50,7 +50,7 @@ public async Task ShouldReturnLockersWithEmptyFolders() public async Task ShouldThrowNotFound_WhenRoomDoesNotExist() { // Arrange - var query = new Query() + var query = new GetEmptyContainersPaginated.Query() { Page = 1, Size = 2, @@ -125,7 +125,7 @@ private async Task SetupTestEntities() NumberOfDocuments = 1 }; - using var scope = _scopeFactory.CreateScope(); + using var scope = ScopeFactory.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); await context.Rooms.AddAsync(room); @@ -142,7 +142,7 @@ private async Task SetupTestEntities() private async Task CleanupTestEntities(Room room) { - using var scope = _scopeFactory.CreateScope(); + using var scope = ScopeFactory.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); context.RemoveRange(room.Lockers.SelectMany(l => l.Folders)); diff --git a/tests/Application.Tests.Integration/Users/Commands/AddUserTests.cs b/tests/Application.Tests.Integration/Users/Commands/AddUserTests.cs index b140781f..89842090 100644 --- a/tests/Application.Tests.Integration/Users/Commands/AddUserTests.cs +++ b/tests/Application.Tests.Integration/Users/Commands/AddUserTests.cs @@ -1,4 +1,4 @@ -using Application.Users.Commands.Add; +using Application.Users.Commands; using Bogus; using Domain.Entities; using FluentAssertions; @@ -8,14 +8,6 @@ namespace Application.Tests.Integration.Users.Commands; public class AddUserTests : BaseClassFixture { - private readonly Faker _userGenerator = new Faker() - .RuleFor(x => x.Username, faker => faker.Person.UserName) - .RuleFor(x => x.Email, faker => faker.Person.Email) - .RuleFor(x => x.FirstName, faker => faker.Person.FirstName) - .RuleFor(x => x.LastName, faker => faker.Person.LastName) - .RuleFor(x => x.Password, faker => faker.Random.String()) - .RuleFor(x => x.Role, faker => faker.Random.Word()) - .RuleFor(x => x.Position, faker => faker.Random.Word()); public AddUserTests(CustomApiFactory apiFactory) : base(apiFactory) { } @@ -24,29 +16,32 @@ public AddUserTests(CustomApiFactory apiFactory) : base(apiFactory) public async Task ShouldCreateUser_WhenCreateDetailsAreValid() { // Arrange - var department = new Department() - { - Id = Guid.NewGuid(), - Name = new Faker().Commerce.Department() - }; + var department = CreateDepartment(); await AddAsync(department); - var createUserCommand = _userGenerator.Generate(); - createUserCommand = createUserCommand with + + var command = new AddUser.Command() { - DepartmentId = department.Id + Username = new Faker().Person.UserName, + Email = new Faker().Person.Email, + FirstName = new Faker().Person.FirstName, + LastName = new Faker().Person.LastName, + Password = new Faker().Random.Word(), + Role = new Faker().Random.Word(), + DepartmentId = department.Id, + Position = new Faker().Random.Word(), }; // Act - var user = await SendAsync(createUserCommand); + var user = await SendAsync(command); // Assert - user.Username.Should().Be(createUserCommand.Username); - user.FirstName.Should().Be(createUserCommand.FirstName); - user.LastName.Should().Be(createUserCommand.LastName); + user.Username.Should().Be(command.Username); + user.FirstName.Should().Be(command.FirstName); + user.LastName.Should().Be(command.LastName); user.Department.Should().BeEquivalentTo(new { department.Id, department.Name }); - user.Email.Should().Be(createUserCommand.Email); - user.Role.Should().Be(createUserCommand.Role); - user.Position.Should().Be(createUserCommand.Position); + user.Email.Should().Be(command.Email); + user.Role.Should().Be(command.Role); + user.Position.Should().Be(command.Position); user.IsActive.Should().Be(true); user.IsActivated.Should().Be(false); diff --git a/tests/Application.Tests.Unit/Common/Mappings/MappingTests.cs b/tests/Application.Tests.Unit/Common/Mappings/MappingTests.cs index dcb2967c..28df4253 100644 --- a/tests/Application.Tests.Unit/Common/Mappings/MappingTests.cs +++ b/tests/Application.Tests.Unit/Common/Mappings/MappingTests.cs @@ -2,8 +2,6 @@ using Application.Common.Mappings; using Application.Common.Models.Dtos; using Application.Common.Models.Dtos.Physical; -using Application.Documents.Queries.GetAllPaginated; -using Application.Rooms.Queries.GetEmptyContainersPaginated; using Application.Users.Queries; using AutoMapper; using Domain.Entities; From 3faa1872c4c22bb387b4025ac5b4ce2552edc01a Mon Sep 17 00:00:00 2001 From: Nguyen Quang Chien Date: Sun, 28 May 2023 22:31:19 +0700 Subject: [PATCH 09/11] add: api documentation --- src/Api/Api.csproj | 1 + src/Api/ConfigureServices.cs | 15 ++++++++++++++- src/Application/Folders/Commands/AddFolder.cs | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Api/Api.csproj b/src/Api/Api.csproj index 09720f26..11e16ecd 100644 --- a/src/Api/Api.csproj +++ b/src/Api/Api.csproj @@ -4,6 +4,7 @@ net6.0 enable enable + true diff --git a/src/Api/ConfigureServices.cs b/src/Api/ConfigureServices.cs index 6dea0c7d..39dabb10 100644 --- a/src/Api/ConfigureServices.cs +++ b/src/Api/ConfigureServices.cs @@ -1,6 +1,8 @@ +using System.Reflection; using Api.Middlewares; using Api.Policies; using Microsoft.AspNetCore.Mvc.ApplicationModels; +using Microsoft.OpenApi.Models; namespace Api; @@ -31,7 +33,18 @@ public static IServiceCollection AddApiServices(this IServiceCollection services // For swagger services.AddEndpointsApiExplorer(); - services.AddSwaggerGen(); + services.AddSwaggerGen(options => + { + options.SwaggerDoc("v1", new OpenApiInfo + { + Version = "v1", + Title = "ProFile API", + Description = "An ASP.NET Core Web API for managing documents", + }); + + var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; + options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename)); + }); return services; } diff --git a/src/Application/Folders/Commands/AddFolder.cs b/src/Application/Folders/Commands/AddFolder.cs index c8c76a07..4b7bd9b9 100644 --- a/src/Application/Folders/Commands/AddFolder.cs +++ b/src/Application/Folders/Commands/AddFolder.cs @@ -73,7 +73,7 @@ public async Task Handle(Command request, CancellationToken cancellat if (folder is not null) { - throw new ConflictException("Folder's name already exists."); + throw new ConflictException("Folder name already exists."); } var entity = new Folder From 0aff15dddec3202adba4e49daf74ad5636dbfb04 Mon Sep 17 00:00:00 2001 From: Nguyen Quang Chien Date: Sun, 28 May 2023 23:05:37 +0700 Subject: [PATCH 10/11] fix: i forgot this --- .../Folders/Commands/AddFolderTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs b/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs index 7b211420..f266b8b6 100644 --- a/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs +++ b/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs @@ -99,7 +99,7 @@ public async Task ShouldThrowConflictException_WhenFolderAlreadyExistsInTheSameL // Assert await action.Should().ThrowAsync() - .WithMessage("Folder's name already exists."); + .WithMessage("Folder name already exists."); // Cleanup Remove(folder); From f48e300fe217fa67e5374f01306398365aec04b3 Mon Sep 17 00:00:00 2001 From: Nguyen Quang Chien Date: Mon, 29 May 2023 02:05:06 +0700 Subject: [PATCH 11/11] migrations: a room now link to a department, fixed all problems related to tests --- src/Api/Controllers/DepartmentsController.cs | 1 + .../Payload/Requests/Auth/LoginModel.cs | 9 + .../Requests/Auth/RefreshTokenRequest.cs | 13 +- .../Departments/AddDepartmentRequest.cs | 6 + .../Departments/UpdateDepartmentRequest.cs | 6 + ...GetAllDocumentsPaginatedQueryParameters.cs | 27 + .../Documents/ImportDocumentRequest.cs | 28 +- .../Documents/UpdateDocumentRequest.cs | 12 + .../Requests/Folders/AddFolderRequest.cs | 16 +- .../GetAllFoldersPaginatedQueryParameters.cs | 21 + .../Requests/Folders/UpdateFolderRequest.cs | 12 + .../Requests/Lockers/AddLockerRequest.cs | 15 + .../GetAllLockersPaginatedQueryParameters.cs | 19 +- .../Requests/Lockers/UpdateLockerRequest.cs | 12 + .../Payload/Requests/Rooms/AddRoomRequest.cs | 22 +- .../GetAllRoomsPaginatedQueryParameters.cs | 15 + ...EmptyContainersPaginatedQueryParameters.cs | 9 + .../Requests/Rooms/UpdateRoomRequest.cs | 12 + .../Requests/Staffs/AddStaffRequest.cs | 9 + .../GetAllStaffsPaginatedQueryParameters.cs | 18 + .../Staffs/RemoveStaffFromRoomRequest.cs | 6 - .../Payload/Requests/Users/AddUserRequest.cs | 27 + .../GetAllUsersPaginatedQueryParameters.cs | 21 + .../Requests/Users/UpdateUserRequest.cs | 15 + .../Payload/Responses/LoginResult.cs | 1 + src/Api/Controllers/RoomsController.cs | 1 + src/Api/Controllers/StaffsController.cs | 6 +- .../Common/Models/Dtos/DepartmentDto.cs | 6 +- .../Models/Dtos/Physical/DocumentItemDto.cs | 1 - .../Common/Models/Dtos/Physical/RoomDto.cs | 8 +- src/Application/Common/Models/Dtos/UserDto.cs | 1 + .../Departments/Commands/AddDepartment.cs | 1 + .../Departments/Commands/DeleteDepartment.cs | 1 + .../Departments/Commands/UpdateDepartment.cs | 1 + .../Departments/Queries/GetAllDepartments.cs | 2 +- .../Departments/Queries/GetDepartmentById.cs | 2 +- .../Queries/GetAllDocumentsPaginated.cs | 2 +- src/Application/Rooms/Commands/AddRoom.cs | 2 +- src/Application/Rooms/Commands/RemoveRoom.cs | 1 - .../Staffs/Commands/RemoveStaffFromRoom.cs | 1 - src/Domain/Entities/Department.cs | 1 - src/Domain/Entities/Physical/Room.cs | 4 +- .../Configurations/DepartmentConfiguration.cs | 5 - .../Configurations/RoomConfiguration.cs | 5 - ...000009_RoomMustHaveADepartment.Designer.cs | 477 ++++++++++ .../00000000000009_RoomMustHaveADepartment.cs | 22 + .../ApplicationDbContextModelSnapshot.cs | 38 +- .../BaseClassFixture.cs | 8 +- .../Commands/AddDepartmentTests.cs | 2 +- .../Queries/GetAllDepartmentsTests.cs | 2 +- .../Queries/GetAllDocumentTypesTests.cs | 9 +- .../Queries/GetAllDocumentsPaginatedTests.cs | 812 +++++++++--------- .../Folders/Commands/AddFolderTests.cs | 17 +- .../Lockers/Commands/DisableLockerTests.cs | 16 +- .../Lockers/Commands/EnableLockerTests.cs | 11 +- .../Rooms/Commands/DisableRoomTests.cs | 13 +- .../Rooms/Commands/RemoveRoomTests.cs | 15 +- .../GetEmptyContainersPaginatedTests.cs | 118 +-- 58 files changed, 1369 insertions(+), 594 deletions(-) delete mode 100644 src/Api/Controllers/Payload/Requests/Staffs/RemoveStaffFromRoomRequest.cs create mode 100644 src/Infrastructure/Persistence/Migrations/00000000000009_RoomMustHaveADepartment.Designer.cs create mode 100644 src/Infrastructure/Persistence/Migrations/00000000000009_RoomMustHaveADepartment.cs diff --git a/src/Api/Controllers/DepartmentsController.cs b/src/Api/Controllers/DepartmentsController.cs index ff481f66..bf01c28a 100644 --- a/src/Api/Controllers/DepartmentsController.cs +++ b/src/Api/Controllers/DepartmentsController.cs @@ -1,5 +1,6 @@ using Api.Controllers.Payload.Requests.Departments; using Application.Common.Models; +using Application.Common.Models.Dtos; using Application.Departments.Commands; using Application.Departments.Queries; using Application.Identity; diff --git a/src/Api/Controllers/Payload/Requests/Auth/LoginModel.cs b/src/Api/Controllers/Payload/Requests/Auth/LoginModel.cs index bee75df4..99f49b03 100644 --- a/src/Api/Controllers/Payload/Requests/Auth/LoginModel.cs +++ b/src/Api/Controllers/Payload/Requests/Auth/LoginModel.cs @@ -1,7 +1,16 @@ namespace Api.Controllers.Payload.Requests.Auth; +/// +/// Login credentials to login +/// public class LoginModel { + /// + /// Email of user + /// public string Email { get; set; } = null!; + /// + /// Password of user + /// public string Password { get; set; } = null!; } \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Auth/RefreshTokenRequest.cs b/src/Api/Controllers/Payload/Requests/Auth/RefreshTokenRequest.cs index 12ebbd03..979dc447 100644 --- a/src/Api/Controllers/Payload/Requests/Auth/RefreshTokenRequest.cs +++ b/src/Api/Controllers/Payload/Requests/Auth/RefreshTokenRequest.cs @@ -1,7 +1,16 @@ namespace Api.Controllers.Payload.Requests.Auth; +/// +/// Request details to refresh token +/// public class RefreshTokenRequest { - public string Token { get; set; } - public string RefreshToken { get; set; } + /// + /// Access token + /// + public string Token { get; set; } = null!; + /// + /// Refresh token + /// + public string RefreshToken { get; set; } = null!; } \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Departments/AddDepartmentRequest.cs b/src/Api/Controllers/Payload/Requests/Departments/AddDepartmentRequest.cs index 6bc9ec9c..2f6444f7 100644 --- a/src/Api/Controllers/Payload/Requests/Departments/AddDepartmentRequest.cs +++ b/src/Api/Controllers/Payload/Requests/Departments/AddDepartmentRequest.cs @@ -1,6 +1,12 @@ namespace Api.Controllers.Payload.Requests.Departments; +/// +/// Request details to add a department +/// public class AddDepartmentRequest { + /// + /// Name of the department to be added + /// public string Name { get; init; } = null!; } \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Departments/UpdateDepartmentRequest.cs b/src/Api/Controllers/Payload/Requests/Departments/UpdateDepartmentRequest.cs index c327c2a4..48ad1052 100644 --- a/src/Api/Controllers/Payload/Requests/Departments/UpdateDepartmentRequest.cs +++ b/src/Api/Controllers/Payload/Requests/Departments/UpdateDepartmentRequest.cs @@ -1,6 +1,12 @@ namespace Api.Controllers.Payload.Requests.Departments; +/// +/// Request details to update a department +/// public class UpdateDepartmentRequest { + /// + /// New name of the department to be updated + /// public string Name { get; set; } = null!; } \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Documents/GetAllDocumentsPaginatedQueryParameters.cs b/src/Api/Controllers/Payload/Requests/Documents/GetAllDocumentsPaginatedQueryParameters.cs index 0b56668c..7f134c04 100644 --- a/src/Api/Controllers/Payload/Requests/Documents/GetAllDocumentsPaginatedQueryParameters.cs +++ b/src/Api/Controllers/Payload/Requests/Documents/GetAllDocumentsPaginatedQueryParameters.cs @@ -1,13 +1,40 @@ namespace Api.Controllers.Payload.Requests.Documents; +/// +/// Query parameters for getting all documents with pagination +/// public class GetAllDocumentsPaginatedQueryParameters { + /// + /// Id of the room to find documents in + /// public Guid? RoomId { get; set; } + /// + /// Id of the locker to find documents in + /// public Guid? LockerId { get; set; } + /// + /// Id of the folder to find documents in + /// public Guid? FolderId { get; set; } + /// + /// Search term + /// public string? SearchTerm { get; set; } + /// + /// Page number + /// public int? Page { get; set; } + /// + /// Size number + /// public int? Size { get; set; } + /// + /// Sort criteria + /// public string? SortBy { get; set; } + /// + /// Sort direction + /// public string? SortOrder { get; set; } } \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Documents/ImportDocumentRequest.cs b/src/Api/Controllers/Payload/Requests/Documents/ImportDocumentRequest.cs index 648d71c5..0bbb2723 100644 --- a/src/Api/Controllers/Payload/Requests/Documents/ImportDocumentRequest.cs +++ b/src/Api/Controllers/Payload/Requests/Documents/ImportDocumentRequest.cs @@ -1,10 +1,28 @@ namespace Api.Controllers.Payload.Requests.Documents; +/// +/// Request details to import a document +/// public class ImportDocumentRequest { - public string Title { get; init; } = null!; - public string? Description { get; init; } - public string DocumentType { get; init; } = null!; - public Guid ImporterId { get; init; } - public Guid FolderId { get; init; } + /// + /// Title of the document to be imported + /// + public string Title { get; set; } = null!; + /// + /// Description of the document to be imported + /// + public string? Description { get; set; } + /// + /// Document type of the document to be imported + /// + public string DocumentType { get; set; } = null!; + /// + /// Id of the importer + /// + public Guid ImporterId { get; set; } + /// + /// Id of the folder that this document will be in + /// + public Guid FolderId { get; set; } } \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Documents/UpdateDocumentRequest.cs b/src/Api/Controllers/Payload/Requests/Documents/UpdateDocumentRequest.cs index e6a0885b..a31cec88 100644 --- a/src/Api/Controllers/Payload/Requests/Documents/UpdateDocumentRequest.cs +++ b/src/Api/Controllers/Payload/Requests/Documents/UpdateDocumentRequest.cs @@ -1,8 +1,20 @@ namespace Api.Controllers.Payload.Requests.Documents; +/// +/// Request details to update a document +/// public class UpdateDocumentRequest { + /// + /// New title of the document to be updated + /// public string Title { get; set; } = null!; + /// + /// New description of the document to be updated + /// public string? Description { get; set; } + /// + /// New document type of the document to be updated + /// public string DocumentType { get; set; } = null!; } \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Folders/AddFolderRequest.cs b/src/Api/Controllers/Payload/Requests/Folders/AddFolderRequest.cs index 6285152a..1dd731c0 100644 --- a/src/Api/Controllers/Payload/Requests/Folders/AddFolderRequest.cs +++ b/src/Api/Controllers/Payload/Requests/Folders/AddFolderRequest.cs @@ -1,9 +1,23 @@ namespace Api.Controllers.Payload.Requests.Folders; - +/// +/// Request details to add a folder +/// public class AddFolderRequest { + /// + /// Name of the folder to be added + /// public string Name { get; init; } = null!; + /// + /// Description of the folder to be added + /// public string? Description { get; init; } + /// + /// Number of documents this folder can hold + /// public int Capacity { get; init; } + /// + /// Id of the locker that this folder will be in + /// public Guid LockerId { get; init; } } \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Folders/GetAllFoldersPaginatedQueryParameters.cs b/src/Api/Controllers/Payload/Requests/Folders/GetAllFoldersPaginatedQueryParameters.cs index db642122..1be3d84f 100644 --- a/src/Api/Controllers/Payload/Requests/Folders/GetAllFoldersPaginatedQueryParameters.cs +++ b/src/Api/Controllers/Payload/Requests/Folders/GetAllFoldersPaginatedQueryParameters.cs @@ -1,11 +1,32 @@ namespace Api.Controllers.Payload.Requests.Folders; +/// +/// Query parameters for getting all folders with pagination +/// public class GetAllFoldersPaginatedQueryParameters { + /// + /// Id of the room to find folders in + /// public Guid? RoomId { get; set; } + /// + /// Id of the locker to find folders in + /// public Guid? LockerId { get; set; } + /// + /// Page number + /// public int? Page { get; set; } + /// + /// Size number + /// public int? Size { get; set; } + /// + /// Sort criteria + /// public string? SortBy { get; set; } + /// + /// Sort direction + /// public string? SortOrder { get; set; } } \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Folders/UpdateFolderRequest.cs b/src/Api/Controllers/Payload/Requests/Folders/UpdateFolderRequest.cs index 97e9691f..e26cf33b 100644 --- a/src/Api/Controllers/Payload/Requests/Folders/UpdateFolderRequest.cs +++ b/src/Api/Controllers/Payload/Requests/Folders/UpdateFolderRequest.cs @@ -1,8 +1,20 @@ namespace Api.Controllers.Payload.Requests.Folders; +/// +/// Request details to update a folder +/// public class UpdateFolderRequest { + /// + /// New name of the folder to be updated + /// public string Name { get; set; } = null!; + /// + /// New description of the folder to be updated + /// public string? Description { get; set; } + /// + /// New capacity of the folder to be updated + /// public int Capacity { get; set; } } \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Lockers/AddLockerRequest.cs b/src/Api/Controllers/Payload/Requests/Lockers/AddLockerRequest.cs index 5820e413..67988e72 100644 --- a/src/Api/Controllers/Payload/Requests/Lockers/AddLockerRequest.cs +++ b/src/Api/Controllers/Payload/Requests/Lockers/AddLockerRequest.cs @@ -1,9 +1,24 @@ namespace Api.Controllers.Payload.Requests.Lockers; +/// +/// Request details to add a locker +/// public class AddLockerRequest { + /// + /// Name of the locker to be updated + /// public string Name { get; init; } = null!; + /// + /// Description of the locker to be updated + /// public string? Description { get; init; } + /// + /// Id of the room that this locker will be in + /// public Guid RoomId { get; init; } + /// + /// Number of folders this locker can hold + /// public int Capacity { get; init; } } \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Lockers/GetAllLockersPaginatedQueryParameters.cs b/src/Api/Controllers/Payload/Requests/Lockers/GetAllLockersPaginatedQueryParameters.cs index b4b7f837..656b96f6 100644 --- a/src/Api/Controllers/Payload/Requests/Lockers/GetAllLockersPaginatedQueryParameters.cs +++ b/src/Api/Controllers/Payload/Requests/Lockers/GetAllLockersPaginatedQueryParameters.cs @@ -2,12 +2,29 @@ namespace Api.Controllers.Payload.Requests.Lockers; - +/// +/// Query parameters for getting all lockers with pagination +/// public class GetAllLockersPaginatedQueryParameters { + /// + /// Id of the room to find lockers in + /// public Guid? RoomId { get; set; } + /// + /// Page number + /// public int? Page { get; set; } + /// + /// Size number + /// public int? Size { get; set; } + /// + /// Sort criteria + /// public string? SortBy { get; set; } + /// + /// Sort direction + /// public string? SortOrder { get; set; } } \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Lockers/UpdateLockerRequest.cs b/src/Api/Controllers/Payload/Requests/Lockers/UpdateLockerRequest.cs index a7f69036..5558c1ce 100644 --- a/src/Api/Controllers/Payload/Requests/Lockers/UpdateLockerRequest.cs +++ b/src/Api/Controllers/Payload/Requests/Lockers/UpdateLockerRequest.cs @@ -1,8 +1,20 @@ namespace Api.Controllers.Payload.Requests.Lockers; +/// +/// Request details to update a locker +/// public class UpdateLockerRequest { + /// + /// New name of the locker to be updated + /// public string Name { get; set; } = null!; + /// + /// New description of the locker to be updated + /// public string? Description { get; set; } + /// + /// New capacity of the locker to be updated + /// public int Capacity { get; set; } } \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Rooms/AddRoomRequest.cs b/src/Api/Controllers/Payload/Requests/Rooms/AddRoomRequest.cs index 482583c1..4228f4da 100644 --- a/src/Api/Controllers/Payload/Requests/Rooms/AddRoomRequest.cs +++ b/src/Api/Controllers/Payload/Requests/Rooms/AddRoomRequest.cs @@ -1,8 +1,24 @@ namespace Api.Controllers.Payload.Requests.Rooms; +/// +/// Request details to add a room +/// public class AddRoomRequest { - public string Name { get; init; } = null!; - public string? Description { get; init; } - public int Capacity { get; init; } + /// + /// Name of the room to be added + /// + public string Name { get; set; } = null!; + /// + /// Description of the room to be added + /// + public string? Description { get; set; } + /// + /// Number of lockers this room can hold + /// + public int Capacity { get; set; } + /// + /// Id of the department this room belongs to + /// + public Guid DepartmentId { get; set; } } \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Rooms/GetAllRoomsPaginatedQueryParameters.cs b/src/Api/Controllers/Payload/Requests/Rooms/GetAllRoomsPaginatedQueryParameters.cs index 107661c0..34721c39 100644 --- a/src/Api/Controllers/Payload/Requests/Rooms/GetAllRoomsPaginatedQueryParameters.cs +++ b/src/Api/Controllers/Payload/Requests/Rooms/GetAllRoomsPaginatedQueryParameters.cs @@ -1,9 +1,24 @@ namespace Api.Controllers.Payload.Requests.Rooms; +/// +/// Query parameters for getting all rooms with pagination +/// public class GetAllRoomsPaginatedQueryParameters { + /// + /// Page number + /// public int? Page { get; set; } + /// + /// Size number + /// public int? Size { get; set; } + /// + /// Sort criteria + /// public string? SortBy { get; set; } + /// + /// Sort direction + /// public string? SortOrder { get; set; } } \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Rooms/GetEmptyContainersPaginatedQueryParameters.cs b/src/Api/Controllers/Payload/Requests/Rooms/GetEmptyContainersPaginatedQueryParameters.cs index 18490a71..2d60bb6d 100644 --- a/src/Api/Controllers/Payload/Requests/Rooms/GetEmptyContainersPaginatedQueryParameters.cs +++ b/src/Api/Controllers/Payload/Requests/Rooms/GetEmptyContainersPaginatedQueryParameters.cs @@ -1,7 +1,16 @@ namespace Api.Controllers.Payload.Requests.Rooms; +/// +/// Query parameters for getting all empty containers in a room +/// public class GetEmptyContainersPaginatedQueryParameters { + /// + /// Page number + /// public int? Page { get; set; } + /// + /// Size number + /// public int? Size { get; set; } } \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Rooms/UpdateRoomRequest.cs b/src/Api/Controllers/Payload/Requests/Rooms/UpdateRoomRequest.cs index 56df0abe..40d4965c 100644 --- a/src/Api/Controllers/Payload/Requests/Rooms/UpdateRoomRequest.cs +++ b/src/Api/Controllers/Payload/Requests/Rooms/UpdateRoomRequest.cs @@ -1,8 +1,20 @@ namespace Api.Controllers.Payload.Requests.Rooms; +/// +/// Request details to update a room +/// public class UpdateRoomRequest { + /// + /// New name of the room to be updated + /// public string Name { get; set; } = null!; + /// + /// New description of the room to be updated + /// public string? Description { get; set; } + /// + /// New capacity of the room to be updated + /// public int Capacity { get; set; } } \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Staffs/AddStaffRequest.cs b/src/Api/Controllers/Payload/Requests/Staffs/AddStaffRequest.cs index a61c0b66..47ebbc06 100644 --- a/src/Api/Controllers/Payload/Requests/Staffs/AddStaffRequest.cs +++ b/src/Api/Controllers/Payload/Requests/Staffs/AddStaffRequest.cs @@ -1,7 +1,16 @@ namespace Api.Controllers.Payload.Requests.Staffs; +/// +/// Request details to add a staff +/// public class AddStaffRequest { + /// + /// User id of the new staff + /// public Guid UserId { get; init; } + /// + /// Id of the room this staff will be in + /// public Guid? RoomId { get; init; } } \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Staffs/GetAllStaffsPaginatedQueryParameters.cs b/src/Api/Controllers/Payload/Requests/Staffs/GetAllStaffsPaginatedQueryParameters.cs index bcb47cb4..53fcbb87 100644 --- a/src/Api/Controllers/Payload/Requests/Staffs/GetAllStaffsPaginatedQueryParameters.cs +++ b/src/Api/Controllers/Payload/Requests/Staffs/GetAllStaffsPaginatedQueryParameters.cs @@ -1,10 +1,28 @@ namespace Api.Controllers.Payload.Requests.Staffs; +/// +/// Query parameters for getting all staffs with pagination +/// public class GetAllStaffsPaginatedQueryParameters { + /// + /// Search term + /// public string? SearchTerm { get; set; } + /// + /// Page number + /// public int? Page { get; set; } + /// + /// Size number + /// public int? Size { get; set; } + /// + /// Sort criteria + /// public string? SortBy { get; set; } + /// + /// Sort direction + /// public string? SortOrder { get; set; } } \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Staffs/RemoveStaffFromRoomRequest.cs b/src/Api/Controllers/Payload/Requests/Staffs/RemoveStaffFromRoomRequest.cs deleted file mode 100644 index 811608df..00000000 --- a/src/Api/Controllers/Payload/Requests/Staffs/RemoveStaffFromRoomRequest.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Api.Controllers.Payload.Requests.Staffs; - -public class RemoveStaffFromRoomRequest -{ - public Guid RoomId { get; set; } -} \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Users/AddUserRequest.cs b/src/Api/Controllers/Payload/Requests/Users/AddUserRequest.cs index c3907b52..2c449aff 100644 --- a/src/Api/Controllers/Payload/Requests/Users/AddUserRequest.cs +++ b/src/Api/Controllers/Payload/Requests/Users/AddUserRequest.cs @@ -1,13 +1,40 @@ namespace Api.Controllers.Payload.Requests.Users; +/// +/// Request details to add a user +/// public class AddUserRequest { + /// + /// Username of the user to be added + /// public string Username { get; init; } = null!; + /// + /// Email of the user to be added + /// public string Email { get; init; } = null!; + /// + /// Password of the user to be added + /// public string Password { get; init; } = null!; + /// + /// First name of the user to be added + /// public string? FirstName { get; init; } + /// + /// Last name of the user to be added + /// public string? LastName { get; init; } + /// + /// Department of the user to be added + /// public Guid DepartmentId { get; init; } + /// + /// Role of the user to be added + /// public string Role { get; init; } = null!; + /// + /// Position of the user to be added + /// public string? Position { get; init; } } \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Users/GetAllUsersPaginatedQueryParameters.cs b/src/Api/Controllers/Payload/Requests/Users/GetAllUsersPaginatedQueryParameters.cs index d3484660..9f47d022 100644 --- a/src/Api/Controllers/Payload/Requests/Users/GetAllUsersPaginatedQueryParameters.cs +++ b/src/Api/Controllers/Payload/Requests/Users/GetAllUsersPaginatedQueryParameters.cs @@ -1,11 +1,32 @@ namespace Api.Controllers.Payload.Requests.Users; +/// +/// Query parameters for getting all users with pagination +/// public class GetAllUsersPaginatedQueryParameters { + /// + /// Id of the department to find users in + /// public Guid? DepartmentId { get; set; } + /// + /// Search term + /// public string? SearchTerm { get; set; } + /// + /// Page number + /// public int? Page { get; set; } + /// + /// Size number + /// public int? Size { get; set; } + /// + /// Sort criteria + /// public string? SortBy { get; set; } + /// + /// Sort direction + /// public string? SortOrder { get; set; } } \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Requests/Users/UpdateUserRequest.cs b/src/Api/Controllers/Payload/Requests/Users/UpdateUserRequest.cs index c1f113d6..d162c28a 100644 --- a/src/Api/Controllers/Payload/Requests/Users/UpdateUserRequest.cs +++ b/src/Api/Controllers/Payload/Requests/Users/UpdateUserRequest.cs @@ -1,9 +1,24 @@ namespace Api.Controllers.Payload.Requests.Users; +/// +/// Request details to update a user +/// public class UpdateUserRequest { + /// + /// New first name of the user to be updated + /// public string? FirstName { get; set; } + /// + /// New last name of the user to be updated + /// public string? LastName { get; set; } + /// + /// New role of the user to be updated + /// public string Role { get; set; } = null!; + /// + /// New position of the user to be updated + /// public string? Position { get; set; } } \ No newline at end of file diff --git a/src/Api/Controllers/Payload/Responses/LoginResult.cs b/src/Api/Controllers/Payload/Responses/LoginResult.cs index 29fb21c4..f731ac4a 100644 --- a/src/Api/Controllers/Payload/Responses/LoginResult.cs +++ b/src/Api/Controllers/Payload/Responses/LoginResult.cs @@ -1,3 +1,4 @@ +using Application.Common.Models.Dtos; using Application.Users.Queries; namespace Api.Controllers.Payload.Responses; diff --git a/src/Api/Controllers/RoomsController.cs b/src/Api/Controllers/RoomsController.cs index 7c98b984..d46390cc 100644 --- a/src/Api/Controllers/RoomsController.cs +++ b/src/Api/Controllers/RoomsController.cs @@ -96,6 +96,7 @@ public async Task>> AddRoom([FromBody] AddRoomReque Name = request.Name, Description = request.Description, Capacity = request.Capacity, + DepartmentId = request.DepartmentId, }; var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); diff --git a/src/Api/Controllers/StaffsController.cs b/src/Api/Controllers/StaffsController.cs index 71dc888f..048f1b4c 100644 --- a/src/Api/Controllers/StaffsController.cs +++ b/src/Api/Controllers/StaffsController.cs @@ -62,6 +62,7 @@ public async Task>>> GetAllPaginated { var query = new GetAllStaffsPaginated.Query() { + SearchTerm = queryParameters.SearchTerm, Page = queryParameters.Page, Size = queryParameters.Size, SortBy = queryParameters.SortBy, @@ -96,20 +97,17 @@ public async Task>> Add([FromBody] AddStaffRequest /// Remove a staff from room /// /// Id of the staff to be removed from room - /// Remove details /// A StaffDto of the removed staff [HttpPut("{staffId:guid}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task>> RemoveFromRoom( - [FromRoute] Guid staffId, - [FromBody] RemoveStaffFromRoomRequest request) + [FromRoute] Guid staffId) { var command = new RemoveStaffFromRoom.Command() { StaffId = staffId, - RoomId = request.RoomId, }; var result = await Mediator.Send(command); return Ok(Result.Succeed(result)); diff --git a/src/Application/Common/Models/Dtos/DepartmentDto.cs b/src/Application/Common/Models/Dtos/DepartmentDto.cs index 286a4b08..68d00db4 100644 --- a/src/Application/Common/Models/Dtos/DepartmentDto.cs +++ b/src/Application/Common/Models/Dtos/DepartmentDto.cs @@ -1,10 +1,12 @@ using Application.Common.Mappings; +using Application.Common.Models.Dtos.Physical; using Domain.Entities; -namespace Application.Users.Queries; +namespace Application.Common.Models.Dtos; public class DepartmentDto : IMapFrom { public Guid Id { get; set; } - public string Name { get; set; } + public string Name { get; set; } = null!; + public RoomDto? Room { get; set; } } \ No newline at end of file diff --git a/src/Application/Common/Models/Dtos/Physical/DocumentItemDto.cs b/src/Application/Common/Models/Dtos/Physical/DocumentItemDto.cs index a9e3e455..7420ad90 100644 --- a/src/Application/Common/Models/Dtos/Physical/DocumentItemDto.cs +++ b/src/Application/Common/Models/Dtos/Physical/DocumentItemDto.cs @@ -4,7 +4,6 @@ namespace Application.Common.Models.Dtos.Physical; -[Obsolete] public class DocumentItemDto : IMapFrom { public Guid Id { get; set; } diff --git a/src/Application/Common/Models/Dtos/Physical/RoomDto.cs b/src/Application/Common/Models/Dtos/Physical/RoomDto.cs index 209c6ef6..a2ed7b95 100644 --- a/src/Application/Common/Models/Dtos/Physical/RoomDto.cs +++ b/src/Application/Common/Models/Dtos/Physical/RoomDto.cs @@ -1,4 +1,5 @@ using Application.Common.Mappings; +using Application.Users.Queries; using AutoMapper; using Domain.Entities.Physical; @@ -7,9 +8,10 @@ namespace Application.Common.Models.Dtos.Physical; public class RoomDto : IMapFrom { public Guid Id { get; set; } - public string Name { get; set; } - public string Description { get; set; } - public StaffDto Staff { get; set; } + public string Name { get; set; } = null!; + public string? Description { get; set; } + public StaffDto? Staff { get; set; } + public DepartmentDto? Department { get; set; } public int Capacity { get; set; } public int NumberOfLockers { get; set; } public bool IsAvailable { get; set; } diff --git a/src/Application/Common/Models/Dtos/UserDto.cs b/src/Application/Common/Models/Dtos/UserDto.cs index ccb4ba64..64cf73dc 100644 --- a/src/Application/Common/Models/Dtos/UserDto.cs +++ b/src/Application/Common/Models/Dtos/UserDto.cs @@ -1,4 +1,5 @@ using Application.Common.Mappings; +using Application.Common.Models.Dtos; using AutoMapper; using Domain.Entities; diff --git a/src/Application/Departments/Commands/AddDepartment.cs b/src/Application/Departments/Commands/AddDepartment.cs index a321afb6..525d83c4 100644 --- a/src/Application/Departments/Commands/AddDepartment.cs +++ b/src/Application/Departments/Commands/AddDepartment.cs @@ -1,5 +1,6 @@ using Application.Common.Exceptions; using Application.Common.Interfaces; +using Application.Common.Models.Dtos; using Application.Users.Queries; using AutoMapper; using Domain.Entities; diff --git a/src/Application/Departments/Commands/DeleteDepartment.cs b/src/Application/Departments/Commands/DeleteDepartment.cs index ad8b0d8a..b744630b 100644 --- a/src/Application/Departments/Commands/DeleteDepartment.cs +++ b/src/Application/Departments/Commands/DeleteDepartment.cs @@ -1,4 +1,5 @@ using Application.Common.Interfaces; +using Application.Common.Models.Dtos; using Application.Users.Queries; using AutoMapper; using MediatR; diff --git a/src/Application/Departments/Commands/UpdateDepartment.cs b/src/Application/Departments/Commands/UpdateDepartment.cs index 68863f7e..a080e22d 100644 --- a/src/Application/Departments/Commands/UpdateDepartment.cs +++ b/src/Application/Departments/Commands/UpdateDepartment.cs @@ -1,3 +1,4 @@ +using Application.Common.Models.Dtos; using Application.Users.Queries; using MediatR; diff --git a/src/Application/Departments/Queries/GetAllDepartments.cs b/src/Application/Departments/Queries/GetAllDepartments.cs index 5832ca48..a4e5d711 100644 --- a/src/Application/Departments/Queries/GetAllDepartments.cs +++ b/src/Application/Departments/Queries/GetAllDepartments.cs @@ -1,6 +1,6 @@ using System.Collections.ObjectModel; using Application.Common.Interfaces; -using Application.Users.Queries; +using Application.Common.Models.Dtos; using AutoMapper; using MediatR; using Microsoft.EntityFrameworkCore; diff --git a/src/Application/Departments/Queries/GetDepartmentById.cs b/src/Application/Departments/Queries/GetDepartmentById.cs index cc78ffab..e4120c64 100644 --- a/src/Application/Departments/Queries/GetDepartmentById.cs +++ b/src/Application/Departments/Queries/GetDepartmentById.cs @@ -1,4 +1,4 @@ -using Application.Users.Queries; +using Application.Common.Models.Dtos; using MediatR; namespace Application.Departments.Queries; diff --git a/src/Application/Documents/Queries/GetAllDocumentsPaginated.cs b/src/Application/Documents/Queries/GetAllDocumentsPaginated.cs index cc77ee82..c6c34a92 100644 --- a/src/Application/Documents/Queries/GetAllDocumentsPaginated.cs +++ b/src/Application/Documents/Queries/GetAllDocumentsPaginated.cs @@ -43,7 +43,7 @@ public record Query : IRequest> public Guid? RoomId { get; init; } public Guid? LockerId { get; init; } public Guid? FolderId { get; init; } - public string? SearchTerm { get; set; } + public string? SearchTerm { get; init; } public int? Page { get; init; } public int? Size { get; init; } public string? SortBy { get; init; } diff --git a/src/Application/Rooms/Commands/AddRoom.cs b/src/Application/Rooms/Commands/AddRoom.cs index 1ac4fe6c..a317d7cf 100644 --- a/src/Application/Rooms/Commands/AddRoom.cs +++ b/src/Application/Rooms/Commands/AddRoom.cs @@ -44,7 +44,7 @@ public record Command : IRequest public string Name { get; init; } = null!; public string? Description { get; init; } public int Capacity { get; init; } - public Guid DepartmentId { get; set; } + public Guid DepartmentId { get; init; } } public class CommandHandler : IRequestHandler diff --git a/src/Application/Rooms/Commands/RemoveRoom.cs b/src/Application/Rooms/Commands/RemoveRoom.cs index 805be223..ef079f47 100644 --- a/src/Application/Rooms/Commands/RemoveRoom.cs +++ b/src/Application/Rooms/Commands/RemoveRoom.cs @@ -55,7 +55,6 @@ public async Task Handle(Command request, CancellationToken cancellatio throw new InvalidOperationException("Room cannot be removed because it contains documents."); } - room.IsAvailable = false; var result = _context.Rooms.Remove(room); await _context.SaveChangesAsync(cancellationToken); return _mapper.Map(result.Entity); diff --git a/src/Application/Staffs/Commands/RemoveStaffFromRoom.cs b/src/Application/Staffs/Commands/RemoveStaffFromRoom.cs index 8ef73843..607eb057 100644 --- a/src/Application/Staffs/Commands/RemoveStaffFromRoom.cs +++ b/src/Application/Staffs/Commands/RemoveStaffFromRoom.cs @@ -8,6 +8,5 @@ public class RemoveStaffFromRoom public record Command : IRequest { public Guid StaffId { get; init; } - public Guid RoomId { get; init; } } } \ No newline at end of file diff --git a/src/Domain/Entities/Department.cs b/src/Domain/Entities/Department.cs index 654a0228..b43bbfe7 100644 --- a/src/Domain/Entities/Department.cs +++ b/src/Domain/Entities/Department.cs @@ -6,6 +6,5 @@ namespace Domain.Entities; public class Department : BaseEntity { public string Name { get; set; } = null!; - public Guid? RoomId { get; set; } public Room? Room { get; set; } } \ No newline at end of file diff --git a/src/Domain/Entities/Physical/Room.cs b/src/Domain/Entities/Physical/Room.cs index 19bda6ff..3d2318ac 100644 --- a/src/Domain/Entities/Physical/Room.cs +++ b/src/Domain/Entities/Physical/Room.cs @@ -7,12 +7,12 @@ public class Room : BaseEntity public string Name { get; set; } = null!; public string? Description { get; set; } public Staff? Staff { get; set; } - public Guid? DepartmentId { get; set; } + public Guid DepartmentId { get; set; } public int Capacity { get; set; } public int NumberOfLockers { get; set; } public bool IsAvailable { get; set; } // Navigation property - public Department? Department { get; set; } + public Department Department { get; set; } = null!; public ICollection Lockers { get; set; } = new List(); } \ No newline at end of file diff --git a/src/Infrastructure/Persistence/Configurations/DepartmentConfiguration.cs b/src/Infrastructure/Persistence/Configurations/DepartmentConfiguration.cs index b0c26706..1c7f00ca 100644 --- a/src/Infrastructure/Persistence/Configurations/DepartmentConfiguration.cs +++ b/src/Infrastructure/Persistence/Configurations/DepartmentConfiguration.cs @@ -17,10 +17,5 @@ public void Configure(EntityTypeBuilder builder) builder.HasAlternateKey(x => x.Name); builder.Property(x => x.Name) .HasMaxLength(64); - - builder.HasOne(x => x.Room) - .WithOne(x => x.Department) - .HasForeignKey(x => x.DepartmentId) - .IsRequired(false); } } \ No newline at end of file diff --git a/src/Infrastructure/Persistence/Configurations/RoomConfiguration.cs b/src/Infrastructure/Persistence/Configurations/RoomConfiguration.cs index 399a1214..2ad65961 100644 --- a/src/Infrastructure/Persistence/Configurations/RoomConfiguration.cs +++ b/src/Infrastructure/Persistence/Configurations/RoomConfiguration.cs @@ -22,11 +22,6 @@ public void Configure(EntityTypeBuilder builder) .HasMaxLength(256) .IsRequired(false); - builder.HasOne(x => x.Department) - .WithOne(x => x.Room) - .HasForeignKey(x => x.RoomId) - .IsRequired(false); - builder.Property(x => x.Capacity) .IsRequired(); diff --git a/src/Infrastructure/Persistence/Migrations/00000000000009_RoomMustHaveADepartment.Designer.cs b/src/Infrastructure/Persistence/Migrations/00000000000009_RoomMustHaveADepartment.Designer.cs new file mode 100644 index 00000000..a20e242e --- /dev/null +++ b/src/Infrastructure/Persistence/Migrations/00000000000009_RoomMustHaveADepartment.Designer.cs @@ -0,0 +1,477 @@ +// +using System; +using Infrastructure.Persistence; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using NodaTime; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Infrastructure.Persistence.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20230528182741_RoomMustHaveADepartment")] + partial class RoomMustHaveADepartment + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.5") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Domain.Entities.Department", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.HasKey("Id"); + + b.HasAlternateKey("Name"); + + b.ToTable("Departments"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Borrow", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("BorrowTime") + .HasColumnType("timestamp without time zone"); + + b.Property("BorrowerId") + .HasColumnType("uuid"); + + b.Property("DocumentId") + .HasColumnType("uuid"); + + b.Property("DueTime") + .HasColumnType("timestamp without time zone"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("BorrowerId"); + + b.HasIndex("DocumentId"); + + b.ToTable("Borrows"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Document", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("DepartmentId") + .HasColumnType("uuid"); + + b.Property("Description") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("DocumentType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("FolderId") + .HasColumnType("uuid"); + + b.Property("ImporterId") + .HasColumnType("uuid"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.HasKey("Id"); + + b.HasIndex("DepartmentId"); + + b.HasIndex("FolderId"); + + b.HasIndex("ImporterId"); + + b.ToTable("Documents"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Folder", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Capacity") + .HasColumnType("integer"); + + b.Property("Description") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("IsAvailable") + .HasColumnType("boolean"); + + b.Property("LockerId") + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("NumberOfDocuments") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("LockerId"); + + b.ToTable("Folders"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Locker", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Capacity") + .HasColumnType("integer"); + + b.Property("Description") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("IsAvailable") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("NumberOfFolders") + .HasColumnType("integer"); + + b.Property("RoomId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("RoomId"); + + b.ToTable("Lockers"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Room", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Capacity") + .HasColumnType("integer"); + + b.Property("DepartmentId") + .HasColumnType("uuid"); + + b.Property("Description") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("IsAvailable") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("NumberOfLockers") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasAlternateKey("Name"); + + b.HasIndex("DepartmentId") + .IsUnique(); + + b.ToTable("Rooms"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Staff", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid") + .HasColumnName("UserId"); + + b.Property("RoomId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("RoomId") + .IsUnique(); + + b.ToTable("Staffs"); + }); + + modelBuilder.Entity("Domain.Entities.RefreshToken", b => + { + b.Property("Token") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationDateTime") + .HasColumnType("timestamp without time zone"); + + b.Property("ExpiryDateTime") + .HasColumnType("timestamp without time zone"); + + b.Property("IsInvalidated") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("IsUsed") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false); + + b.Property("JwtId") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Token"); + + b.HasIndex("UserId"); + + b.ToTable("RefreshTokens"); + }); + + modelBuilder.Entity("Domain.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Created") + .HasColumnType("timestamp without time zone"); + + b.Property("CreatedBy") + .HasColumnType("uuid"); + + b.Property("DepartmentId") + .HasColumnType("uuid"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(320) + .HasColumnType("character varying(320)"); + + b.Property("FirstName") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("IsActivated") + .HasColumnType("boolean"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("LastModified") + .HasColumnType("timestamp without time zone"); + + b.Property("LastModifiedBy") + .HasColumnType("uuid"); + + b.Property("LastName") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("PasswordHash") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Position") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Role") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Username") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("DepartmentId"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Borrow", b => + { + b.HasOne("Domain.Entities.User", "Borrower") + .WithMany() + .HasForeignKey("BorrowerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Domain.Entities.Physical.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Borrower"); + + b.Navigation("Document"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Document", b => + { + b.HasOne("Domain.Entities.Department", "Department") + .WithMany() + .HasForeignKey("DepartmentId"); + + b.HasOne("Domain.Entities.Physical.Folder", "Folder") + .WithMany("Documents") + .HasForeignKey("FolderId"); + + b.HasOne("Domain.Entities.User", "Importer") + .WithMany() + .HasForeignKey("ImporterId"); + + b.Navigation("Department"); + + b.Navigation("Folder"); + + b.Navigation("Importer"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Folder", b => + { + b.HasOne("Domain.Entities.Physical.Locker", "Locker") + .WithMany("Folders") + .HasForeignKey("LockerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Locker"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Locker", b => + { + b.HasOne("Domain.Entities.Physical.Room", "Room") + .WithMany("Lockers") + .HasForeignKey("RoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Room"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Room", b => + { + b.HasOne("Domain.Entities.Department", "Department") + .WithOne("Room") + .HasForeignKey("Domain.Entities.Physical.Room", "DepartmentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Department"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Staff", b => + { + b.HasOne("Domain.Entities.User", "User") + .WithOne() + .HasForeignKey("Domain.Entities.Physical.Staff", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Domain.Entities.Physical.Room", "Room") + .WithOne("Staff") + .HasForeignKey("Domain.Entities.Physical.Staff", "RoomId"); + + b.Navigation("Room"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Domain.Entities.RefreshToken", b => + { + b.HasOne("Domain.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Domain.Entities.User", b => + { + b.HasOne("Domain.Entities.Department", "Department") + .WithMany() + .HasForeignKey("DepartmentId"); + + b.Navigation("Department"); + }); + + modelBuilder.Entity("Domain.Entities.Department", b => + { + b.Navigation("Room"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Folder", b => + { + b.Navigation("Documents"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Locker", b => + { + b.Navigation("Folders"); + }); + + modelBuilder.Entity("Domain.Entities.Physical.Room", b => + { + b.Navigation("Lockers"); + + b.Navigation("Staff"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Infrastructure/Persistence/Migrations/00000000000009_RoomMustHaveADepartment.cs b/src/Infrastructure/Persistence/Migrations/00000000000009_RoomMustHaveADepartment.cs new file mode 100644 index 00000000..a9fa4a85 --- /dev/null +++ b/src/Infrastructure/Persistence/Migrations/00000000000009_RoomMustHaveADepartment.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Infrastructure.Persistence.Migrations +{ + /// + public partial class RoomMustHaveADepartment : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/src/Infrastructure/Persistence/Migrations/ApplicationDbContextModelSnapshot.cs b/src/Infrastructure/Persistence/Migrations/ApplicationDbContextModelSnapshot.cs index 237d5b96..49740741 100644 --- a/src/Infrastructure/Persistence/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/src/Infrastructure/Persistence/Migrations/ApplicationDbContextModelSnapshot.cs @@ -34,16 +34,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasMaxLength(64) .HasColumnType("character varying(64)"); - b.Property("RoomId") - .HasColumnType("uuid"); - b.HasKey("Id"); b.HasAlternateKey("Name"); - b.HasIndex("RoomId") - .IsUnique(); - b.ToTable("Departments"); }); @@ -195,7 +189,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Capacity") .HasColumnType("integer"); - b.Property("DepartmentId") + b.Property("DepartmentId") .HasColumnType("uuid"); b.Property("Description") @@ -217,6 +211,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasAlternateKey("Name"); + b.HasIndex("DepartmentId") + .IsUnique(); + b.ToTable("Rooms"); }); @@ -340,15 +337,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("Users"); }); - modelBuilder.Entity("Domain.Entities.Department", b => - { - b.HasOne("Domain.Entities.Physical.Room", "Room") - .WithOne("Department") - .HasForeignKey("Domain.Entities.Department", "RoomId"); - - b.Navigation("Room"); - }); - modelBuilder.Entity("Domain.Entities.Physical.Borrow", b => { b.HasOne("Domain.Entities.User", "Borrower") @@ -411,6 +399,17 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("Room"); }); + modelBuilder.Entity("Domain.Entities.Physical.Room", b => + { + b.HasOne("Domain.Entities.Department", "Department") + .WithOne("Room") + .HasForeignKey("Domain.Entities.Physical.Room", "DepartmentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Department"); + }); + modelBuilder.Entity("Domain.Entities.Physical.Staff", b => { b.HasOne("Domain.Entities.User", "User") @@ -448,6 +447,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("Department"); }); + modelBuilder.Entity("Domain.Entities.Department", b => + { + b.Navigation("Room"); + }); + modelBuilder.Entity("Domain.Entities.Physical.Folder", b => { b.Navigation("Documents"); @@ -460,8 +464,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("Domain.Entities.Physical.Room", b => { - b.Navigation("Department"); - b.Navigation("Lockers"); b.Navigation("Staff"); diff --git a/tests/Application.Tests.Integration/BaseClassFixture.cs b/tests/Application.Tests.Integration/BaseClassFixture.cs index 05de90de..370fbc40 100644 --- a/tests/Application.Tests.Integration/BaseClassFixture.cs +++ b/tests/Application.Tests.Integration/BaseClassFixture.cs @@ -139,7 +139,7 @@ protected Locker CreateLocker(params Folder[] folders) return locker; } - protected Room CreateRoom(params Locker[] lockers) + protected Room CreateRoom(Department department, params Locker[] lockers) { var room = new Room() { @@ -147,7 +147,9 @@ protected Room CreateRoom(params Locker[] lockers) Name = new Faker().Commerce.ProductName(), Capacity = 3, NumberOfLockers = lockers.Length, - IsAvailable = true + IsAvailable = true, + Department = department, + DepartmentId = department.Id, }; foreach (var locker in lockers) @@ -163,7 +165,7 @@ protected static Department CreateDepartment() return new Department() { Id = Guid.NewGuid(), - Name = new Faker().Commerce.Department() + Name = new Faker().Random.Word() }; } diff --git a/tests/Application.Tests.Integration/Departments/Commands/AddDepartmentTests.cs b/tests/Application.Tests.Integration/Departments/Commands/AddDepartmentTests.cs index db3746e7..dc3d31e1 100644 --- a/tests/Application.Tests.Integration/Departments/Commands/AddDepartmentTests.cs +++ b/tests/Application.Tests.Integration/Departments/Commands/AddDepartmentTests.cs @@ -12,7 +12,7 @@ public AddDepartmentTests(CustomApiFactory apiFactory) : base(apiFactory) { } - [Fact(Timeout = 200)] + [Fact] public async Task ShouldCreateDepartment_WhenDepartmentNameIsValid() { // Arrange diff --git a/tests/Application.Tests.Integration/Departments/Queries/GetAllDepartmentsTests.cs b/tests/Application.Tests.Integration/Departments/Queries/GetAllDepartmentsTests.cs index 90b39fd9..f126e367 100644 --- a/tests/Application.Tests.Integration/Departments/Queries/GetAllDepartmentsTests.cs +++ b/tests/Application.Tests.Integration/Departments/Queries/GetAllDepartmentsTests.cs @@ -1,4 +1,5 @@ using Application.Common.Mappings; +using Application.Common.Models.Dtos; using Application.Departments.Queries; using Application.Users.Queries; using AutoMapper; @@ -22,7 +23,6 @@ public GetAllDepartmentsTests(CustomApiFactory apiFactory) : base(apiFactory) public async Task ShouldReturnDepartments_WhenDepartmentsExist() { // Arrange - var department = new Department() { Id = Guid.NewGuid(), diff --git a/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentTypesTests.cs b/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentTypesTests.cs index 8d74f004..672aec9a 100644 --- a/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentTypesTests.cs +++ b/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentTypesTests.cs @@ -1,6 +1,4 @@ using Application.Documents.Queries; -using Bogus; -using Domain.Entities.Physical; using FluentAssertions; using Xunit; @@ -16,12 +14,7 @@ public GetAllDocumentTypesTests(CustomApiFactory apiFactory) : base(apiFactory) public async Task ShouldReturnDocumentTypes_WhenDocumentTypesExist() { // Arrange - var document = new Document() - { - Id = Guid.NewGuid(), - Title = new Faker().Name.JobTitle(), - DocumentType = new Faker().Commerce.ProductName(), - }; + var document = CreateNDocuments(1).First(); await AddAsync(document); var query = new GetAllDocumentTypes.Query(); diff --git a/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentsPaginatedTests.cs b/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentsPaginatedTests.cs index 70e69946..42d3b5d1 100644 --- a/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentsPaginatedTests.cs +++ b/tests/Application.Tests.Integration/Documents/Queries/GetAllDocumentsPaginatedTests.cs @@ -1,420 +1,438 @@ - using Application.Common.Exceptions; - using Application.Common.Extensions; - using Application.Common.Mappings; - using Application.Common.Models.Dtos.Physical; - using Application.Documents.Queries; - using AutoMapper; - using FluentAssertions; - using Xunit; - - namespace Application.Tests.Integration.Documents.Queries; - - public class GetAllDocumentsPaginatedTests : BaseClassFixture +using Application.Common.Exceptions; +using Application.Common.Extensions; +using Application.Common.Mappings; +using Application.Common.Models.Dtos.Physical; +using Application.Documents.Queries; +using AutoMapper; +using Domain.Entities; +using FluentAssertions; +using Xunit; + +namespace Application.Tests.Integration.Documents.Queries; + +public class GetAllDocumentsPaginatedTests : BaseClassFixture +{ + private readonly IMapper _mapper; + public GetAllDocumentsPaginatedTests(CustomApiFactory apiFactory) : base(apiFactory) { - private readonly IMapper _mapper; - public GetAllDocumentsPaginatedTests(CustomApiFactory apiFactory) : base(apiFactory) - { - var configuration = new MapperConfiguration(config => config.AddProfile()); + var configuration = new MapperConfiguration(config => config.AddProfile()); - _mapper = configuration.CreateMapper(); - } + _mapper = configuration.CreateMapper(); + } - [Fact] - public async Task ShouldReturnAllDocuments_WhenNoContainersAreDefined() - { - // Arrange - var documents = CreateNDocuments(1); - var folder = CreateFolder(documents); - var locker = CreateLocker(folder); - var room = CreateRoom(locker); - await AddAsync(room); - - var query = new GetAllDocumentsPaginated.Query(); - - // Act - var result = await SendAsync(query); - - // Assert - result.Items.Should().ContainEquivalentOf(_mapper.Map(documents.First())); - - // Cleanup - Remove(documents.First()); - Remove(folder); - Remove(locker); - Remove(room); - } - - [Fact] - public async Task ShouldReturnEmptyPaginatedList_WhenNoDocumentsExist() - { - // Arrange - var room = CreateRoom(); + [Fact] + public async Task ShouldReturnAllDocuments_WhenNoContainersAreDefined() + { + // Arrange + var department = CreateDepartment(); + var documents = CreateNDocuments(1); + documents.First().Department = department; + var folder = CreateFolder(documents); + var locker = CreateLocker(folder); + var room = CreateRoom(department, locker); + await AddAsync(room); + + var query = new GetAllDocumentsPaginated.Query(); + + // Act + var result = await SendAsync(query); + + // Assert + result.Items.First().Title.Should().Be(documents.First().Title); + + // Cleanup + Remove(documents.First()); + Remove(folder); + Remove(locker); + Remove(room); + Remove(await FindAsync(department.Id)); + } + + [Fact] + public async Task ShouldReturnEmptyPaginatedList_WhenNoDocumentsExist() + { + // Arrange + var department = CreateDepartment(); + var room = CreateRoom(department); - await AddAsync(room); + await AddAsync(room); - var query = new GetAllDocumentsPaginated.Query() - { - RoomId = room.Id - }; + var query = new GetAllDocumentsPaginated.Query() + { + RoomId = room.Id + }; - // Act - var result = await SendAsync(query); + // Act + var result = await SendAsync(query); - // Assert - result.Items.Should().BeEmpty(); - - // Cleanup - Remove(room); - } + // Assert + result.Items.Should().BeEmpty(); + + // Cleanup + Remove(room); + Remove(await FindAsync(department.Id)); + } - [Fact] - public async Task ShouldReturnDocumentsOfRoom_WhenOnlyRoomIdIsPresent() + [Fact] + public async Task ShouldReturnDocumentsOfRoom_WhenOnlyRoomIdIsPresent() + { + // Arrange + var department1 = CreateDepartment(); + var department2 = CreateDepartment(); + var documents1 = CreateNDocuments(2); + var folder1 = CreateFolder(documents1); + var locker1 = CreateLocker(folder1); + var room1 = CreateRoom(department1, locker1); + var documents2 = CreateNDocuments(2); + var folder2 = CreateFolder(documents2); + var locker2 = CreateLocker(folder2); + var room2 = CreateRoom(department2, locker2); + await AddAsync(room1); + await AddAsync(room2); + + var query = new GetAllDocumentsPaginated.Query() { - // Arrange - var documents1 = CreateNDocuments(2); - - var folder1 = CreateFolder(documents1); - - var locker1 = CreateLocker(folder1); - - var room1 = CreateRoom(locker1); - - var documents2 = CreateNDocuments(2); - - var folder2 = CreateFolder(documents2); - - var locker2 = CreateLocker(folder2); - - var room2 = CreateRoom(locker2); - - await AddAsync(room1); - await AddAsync(room2); - - var query = new GetAllDocumentsPaginated.Query() - { - RoomId = room1.Id - }; - - // Act - var result = await SendAsync(query); - - // Assert - result.Items.Should().ContainEquivalentOf(_mapper.Map(documents1[0])); - result.Items.Should().ContainEquivalentOf(_mapper.Map(documents1[1])); - result.Items.Should().NotContainEquivalentOf(_mapper.Map(documents2[0])); - result.Items.Should().NotContainEquivalentOf(_mapper.Map(documents2[1])); - - // Cleanup - Remove(documents1[0]); - Remove(documents1[1]); - Remove(documents2[0]); - Remove(documents2[1]); - Remove(folder1); - Remove(folder2); - Remove(locker1); - Remove(locker2); - Remove(room1); - Remove(room2); - } - - [Fact] - public async Task ShouldThrowKeyNotFoundException_WhenOnlyRoomIdIsPresentButDoesNotExist() + RoomId = room1.Id + }; + + // Act + var result = await SendAsync(query); + + // Assert + result.Items.Should() + .BeEquivalentTo(_mapper.Map(documents1), x => x.IgnoringCyclicReferences()); + result.Items.Should() + .NotBeEquivalentTo(_mapper.Map(documents2), x => x.IgnoringCyclicReferences()); + + // Cleanup + Remove(documents1[0]); + Remove(documents1[1]); + Remove(documents2[0]); + Remove(documents2[1]); + Remove(folder1); + Remove(folder2); + Remove(locker1); + Remove(locker2); + Remove(room1); + Remove(room2); + Remove(await FindAsync(department1.Id)); + Remove(await FindAsync(department2.Id)); + } + + [Fact] + public async Task ShouldThrowKeyNotFoundException_WhenOnlyRoomIdIsPresentButDoesNotExist() + { + // Arrange + var query = new GetAllDocumentsPaginated.Query() { - // Arrange - var query = new GetAllDocumentsPaginated.Query() - { - RoomId = Guid.NewGuid() - }; - - // Act - var action = async () => await SendAsync(query); - - // Assert - await action.Should().ThrowAsync("Room does not exist."); - } - - [Fact] - public async Task ShouldReturnDocumentsOfLocker_WhenOnlyRoomIdAndLockerIdArePresentAndLockerIsInRoom() + RoomId = Guid.NewGuid(), + }; + + // Act + var action = async () => await SendAsync(query); + + // Assert + await action.Should().ThrowAsync("Room does not exist."); + } + + [Fact] + public async Task ShouldReturnDocumentsOfLocker_WhenOnlyRoomIdAndLockerIdArePresentAndLockerIsInRoom() + { + // Arrange + var department = CreateDepartment(); + var documents1 = CreateNDocuments(2); + var folder1 = CreateFolder(documents1); + var locker1 = CreateLocker(folder1); + var documents2 = CreateNDocuments(2); + var folder2 = CreateFolder(documents2); + var locker2 = CreateLocker(folder2); + var room = CreateRoom(department, locker1, locker2); + await AddAsync(room); + + var query = new GetAllDocumentsPaginated.Query() { - // Arrange - var documents1 = CreateNDocuments(2); - - var folder1 = CreateFolder(documents1); - - var locker1 = CreateLocker(folder1); - - var documents2 = CreateNDocuments(2); - - var folder2 = CreateFolder(documents2); - - var locker2 = CreateLocker(folder2); - - var room = CreateRoom(locker1, locker2); - - await AddAsync(room); - - var query = new GetAllDocumentsPaginated.Query() - { - RoomId = room.Id, - LockerId = locker1.Id - }; - - // Act - var result = await SendAsync(query); - - // Assert - result.Items.Should().BeEquivalentTo(_mapper.Map>(documents1)); - result.Items.Should().NotContainEquivalentOf(_mapper.Map>(documents2)); - - // Cleanup - Remove(documents1[0]); - Remove(documents1[1]); - Remove(documents2[0]); - Remove(documents2[1]); - Remove(folder1); - Remove(folder2); - Remove(locker1); - Remove(locker2); - Remove(room); - } - - [Fact] - public async Task ShouldThrowKeyNotFoundException_WhenOnlyRoomIdAndLockerIdArePresentAndLockerDoesNotExist() + RoomId = room.Id, + LockerId = locker1.Id + }; + + // Act + var result = await SendAsync(query); + + // Assert + result.Items.Should() + .BeEquivalentTo(_mapper.Map(documents1), x => x.IgnoringCyclicReferences()); + result.Items.Should() + .NotBeEquivalentTo(_mapper.Map(documents2), x => x.IgnoringCyclicReferences()); + + // Cleanup + Remove(documents1[0]); + Remove(documents1[1]); + Remove(documents2[0]); + Remove(documents2[1]); + Remove(folder1); + Remove(folder2); + Remove(locker1); + Remove(locker2); + Remove(room); + Remove(await FindAsync(department.Id)); + } + + [Fact] + public async Task ShouldThrowKeyNotFoundException_WhenOnlyRoomIdAndLockerIdArePresentAndLockerDoesNotExist() + { + // Arrange + var department = CreateDepartment(); + var room = CreateRoom(department); + await AddAsync(room); + + var query = new GetAllDocumentsPaginated.Query() { - // Arrange - var room = CreateRoom(); - await AddAsync(room); - - var query = new GetAllDocumentsPaginated.Query() - { - RoomId = room.Id, - LockerId = Guid.NewGuid() - }; - - // Act - var action = async () => await SendAsync(query); - - // Assert - await action.Should().ThrowAsync("Locker does not exist."); - - // Cleanup - Remove(room); - } + RoomId = room.Id, + LockerId = Guid.NewGuid() + }; + + // Act + var action = async () => await SendAsync(query); + + // Assert + await action.Should().ThrowAsync("Locker does not exist."); - [Fact] - public async Task ShouldThrowConflictException_WhenOnlyRoomIdAndLockerIdArePresentAndLockerIsNotInRoom() + // Cleanup + Remove(room); + Remove(await FindAsync(department.Id)); + } + + [Fact] + public async Task ShouldThrowConflictException_WhenOnlyRoomIdAndLockerIdArePresentAndLockerIsNotInRoom() + { + // Arrange + var department1 = CreateDepartment(); + var department2 = CreateDepartment(); + var locker = CreateLocker(); + var room1 = CreateRoom(department1); + var room2 = CreateRoom(department2, locker); + await AddAsync(room1); + await AddAsync(room2); + + var query = new GetAllDocumentsPaginated.Query() { - // Arrange - var locker = CreateLocker(); - - var room1 = CreateRoom(); - - var room2 = CreateRoom(locker); - - await AddAsync(room1); - await AddAsync(room2); - - var query = new GetAllDocumentsPaginated.Query() - { - RoomId = room1.Id, - LockerId = locker.Id - }; - - // Act - var action = async () => await SendAsync(query); - - // Assert - await action.Should().ThrowAsync("Room does not match locker."); - - // Cleanup - Remove(locker); - Remove(room1); - Remove(room2); - } + RoomId = room1.Id, + LockerId = locker.Id + }; + + // Act + var action = async () => await SendAsync(query); + + // Assert + await action.Should().ThrowAsync("Room does not match locker."); - [Fact] - public async Task ShouldReturnDocumentsOfFolder_WhenAllIdsArePresentAndFolderIsInBothLockerAndRoom() + // Cleanup + Remove(locker); + Remove(room1); + Remove(room2); + Remove(await FindAsync(department1.Id)); + Remove(await FindAsync(department2.Id)); + } + + [Fact] + public async Task ShouldReturnDocumentsOfFolder_WhenAllIdsArePresentAndFolderIsInBothLockerAndRoom() + { + // Arrange + var department = CreateDepartment(); + var documents1 = CreateNDocuments(2); + documents1[0].Department = department; + documents1[1].Department = department; + var folder1 = CreateFolder(documents1); + var documents2 = CreateNDocuments(2); + documents2[0].Department = department; + documents2[1].Department = department; + var folder2 = CreateFolder(documents2); + var locker = CreateLocker(folder1, folder2); + var room = CreateRoom(department, locker); + await AddAsync(room); + + var query = new GetAllDocumentsPaginated.Query() + { + RoomId = room.Id, + LockerId = locker.Id, + FolderId = folder1.Id + }; + + // Act + var result = await SendAsync(query); + + // Assert + result.Items.Should() + .BeEquivalentTo(_mapper.Map(documents1), x => x.IgnoringCyclicReferences()); + result.Items.Should() + .NotBeEquivalentTo(_mapper.Map(documents2), x => x.IgnoringCyclicReferences()); + + // Cleanup + Remove(documents1[0]); + Remove(documents1[1]); + Remove(documents2[0]); + Remove(documents2[1]); + Remove(folder1); + Remove(folder2); + Remove(locker); + Remove(room); + Remove(await FindAsync(department.Id)); + } + + [Fact] + public async Task ShouldThrowKeyNotFoundException_WhenAllIdsArePresentAndValidAndFolderDoesNotExist() + { + // Arrange + var department = CreateDepartment(); + var locker = CreateLocker(); + var room = CreateRoom(department, locker); + + await AddAsync(room); + + var query = new GetAllDocumentsPaginated.Query() { - // Arrange - var documents1 = CreateNDocuments(2); - var folder1 = CreateFolder(documents1); - - var documents2 = CreateNDocuments(2); - var folder2 = CreateFolder(documents2); - - var locker = CreateLocker(folder1, folder2); - var room = CreateRoom(locker); - await AddAsync(room); - - var query = new GetAllDocumentsPaginated.Query() - { - RoomId = room.Id, - LockerId = locker.Id, - FolderId = folder1.Id - }; - - // Act - var result = await SendAsync(query); - - // Assert - result.Items.Should().BeEquivalentTo(_mapper.Map(documents1)); - result.Items.Should().NotBeEquivalentTo(_mapper.Map(documents2)); - - // Cleanup - Remove(documents1[0]); - Remove(documents1[1]); - Remove(documents2[0]); - Remove(documents2[1]); - Remove(folder1); - Remove(folder2); - Remove(locker); - Remove(room); - } + RoomId = room.Id, + LockerId = locker.Id, + FolderId = Guid.NewGuid() + }; + + // Act + var action = async () => await SendAsync(query); + + // Assert + await action.Should().ThrowAsync("Folder does not exist."); - [Fact] - public async Task ShouldThrowKeyNotFoundException_WhenAllIdsArePresentAndValidAndFolderDoesNotExist() + // Cleanup + Remove(locker); + Remove(room); + Remove(await FindAsync(department.Id)); + } + + [Fact] + public async Task ShouldThrowConflictException_WhenAllIdsArePresentAndFolderIsNotInLockerOrInRoom() + { + // Arrange + var department1 = CreateDepartment(); + var department2 = CreateDepartment(); + var folder1 = CreateFolder(); + var locker1 = CreateLocker(folder1); + var room1 = CreateRoom(department1, locker1); + var folder2 = CreateFolder(); + var locker2 = CreateLocker(folder2); + var room2 = CreateRoom(department2, locker2); + await AddAsync(room1); + await AddAsync(room2); + + var query1 = new GetAllDocumentsPaginated.Query() { - // Arrange - var locker = CreateLocker(); - var room = CreateRoom(locker); - - await AddAsync(room); - - var query = new GetAllDocumentsPaginated.Query() - { - RoomId = room.Id, - LockerId = locker.Id, - FolderId = Guid.NewGuid() - }; - - // Act - var action = async () => await SendAsync(query); - - // Assert - await action.Should().ThrowAsync("Folder does not exist."); - - // Cleanup - Remove(locker); - Remove(room); - } + RoomId = room1.Id, + LockerId = locker2.Id, + FolderId = folder1.Id + }; - [Fact] - public async Task ShouldThrowConflictException_WhenAllIdsArePresentAndFolderIsNotInLockerOrInRoom() + var query2 = new GetAllDocumentsPaginated.Query() { - // Arrange - var folder1 = CreateFolder(); - var locker1 = CreateLocker(folder1); - var room1 = CreateRoom(locker1); - - var folder2 = CreateFolder(); - var locker2 = CreateLocker(folder2); - var room2 = CreateRoom(locker2); - - await AddAsync(room1); - await AddAsync(room2); - - var query1 = new GetAllDocumentsPaginated.Query() - { - RoomId = room1.Id, - LockerId = locker2.Id, - FolderId = folder1.Id - }; - - var query2 = new GetAllDocumentsPaginated.Query() - { - RoomId = room1.Id, - LockerId = locker2.Id, - FolderId = folder2.Id - }; - - // Act - var action1 = async () => await SendAsync(query1); - var action2 = async () => await SendAsync(query2); - - // Assert - await action1.Should().ThrowAsync("Either locker or room does not match folder."); - await action1.Should().ThrowAsync("Either locker or room does not match folder."); - - // Cleanup - Remove(folder1); - Remove(folder2); - Remove(locker1); - Remove(locker2); - Remove(room1); - Remove(room2); - } + RoomId = room1.Id, + LockerId = locker2.Id, + FolderId = folder2.Id + }; + + // Act + var action1 = async () => await SendAsync(query1); + var action2 = async () => await SendAsync(query2); + + // Assert + await action1.Should().ThrowAsync("Either locker or room does not match folder."); + await action2.Should().ThrowAsync("Either locker or room does not match folder."); - [Fact] - public async Task ShouldReturnSortedByIdPaginatedList_WhenSortByIsNotPresent() + // Cleanup + Remove(folder1); + Remove(folder2); + Remove(locker1); + Remove(locker2); + Remove(room1); + Remove(room2); + Remove(await FindAsync(department1.Id)); + Remove(await FindAsync(department2.Id)); + } + + [Fact] + public async Task ShouldReturnSortedByIdPaginatedList_WhenSortByIsNotPresent() + { + // Arrange + var department = CreateDepartment(); + var documents = CreateNDocuments(2); + var folder = CreateFolder(documents); + var locker = CreateLocker(folder); + var room = CreateRoom(department, locker); + await AddAsync(room); + + var query = new GetAllDocumentsPaginated.Query() { - // Arrange - var documents = CreateNDocuments(2); - var folder = CreateFolder(documents); - var locker = CreateLocker(folder); - var room = CreateRoom(locker); - - await AddAsync(room); - - var query = new GetAllDocumentsPaginated.Query() - { - RoomId = room.Id - }; - - // Act - var result = await SendAsync(query); - - // Assert - result.Items.First().Should().BeEquivalentTo(_mapper.Map(documents[0].Id.CompareTo(documents[1].Id) <= 0 ? documents[0] : documents[1])); - - // Cleanup - Remove(documents[0]); - Remove(documents[1]); - Remove(folder); - Remove(locker); - Remove(room); - } - - [Theory] - [InlineData(nameof(DocumentDto.Id), "asc")] - [InlineData(nameof(DocumentDto.Title), "asc")] - [InlineData(nameof(DocumentDto.DocumentType), "asc")] - [InlineData(nameof(DocumentDto.Description), "asc")] - [InlineData(nameof(DocumentDto.Id), "desc")] - [InlineData(nameof(DocumentDto.Title), "desc")] - [InlineData(nameof(DocumentDto.DocumentType), "desc")] - [InlineData(nameof(DocumentDto.Description), "desc")] - public async Task ShouldReturnSortedByPropertyPaginatedList_WhenSortByIsPresent(string sortBy, string sortOrder) + RoomId = room.Id, + }; + + // Act + var result = await SendAsync(query); + + // Assert + result.Items.First().Should() + .BeEquivalentTo( + _mapper.Map(documents[0].Id.CompareTo(documents[1].Id) <= 0 ? documents[0] : documents[1]), + x => x.IgnoringCyclicReferences()); + + // Cleanup + Remove(documents[0]); + Remove(documents[1]); + Remove(folder); + Remove(locker); + Remove(room); + Remove(await FindAsync(department.Id)); + } + + [Theory] + [InlineData(nameof(DocumentDto.Id), "asc")] + [InlineData(nameof(DocumentDto.Title), "asc")] + [InlineData(nameof(DocumentDto.DocumentType), "asc")] + [InlineData(nameof(DocumentDto.Description), "asc")] + [InlineData(nameof(DocumentDto.Id), "desc")] + [InlineData(nameof(DocumentDto.Title), "desc")] + [InlineData(nameof(DocumentDto.DocumentType), "desc")] + [InlineData(nameof(DocumentDto.Description), "desc")] + public async Task ShouldReturnSortedByPropertyPaginatedList_WhenSortByIsPresent(string sortBy, string sortOrder) + { + // Arrange + var department = CreateDepartment(); + var documents = CreateNDocuments(2); + var folder = CreateFolder(documents); + var locker = CreateLocker(folder); + var room = CreateRoom(department, locker); + + await AddAsync(room); + + var query = new GetAllDocumentsPaginated.Query() { - // Arrange - var documents = CreateNDocuments(2); - var folder = CreateFolder(documents); - var locker = CreateLocker(folder); - var room = CreateRoom(locker); - - await AddAsync(room); - - var query = new GetAllDocumentsPaginated.Query() - { - RoomId = room.Id, - SortBy = sortBy, - SortOrder = sortOrder - }; - - var list = new EnumerableQuery(_mapper.Map>(documents)); - var list2 = list.OrderByCustom(sortBy, sortOrder); - var expected = list2.ToList(); - - // Act - var result = await SendAsync(query); - - // Assert - result.Items.Should().BeEquivalentTo(expected); - - // Cleanup - Remove(documents[0]); - Remove(documents[1]); - Remove(folder); - Remove(locker); - Remove(room); - } - } \ No newline at end of file + RoomId = room.Id, + SortBy = sortBy, + SortOrder = sortOrder + }; + + var list = new EnumerableQuery(_mapper.Map>(documents)); + var list2 = list.OrderByCustom(sortBy, sortOrder); + var expected = list2.ToList(); + + // Act + var result = await SendAsync(query); + + // Assert + result.Items.Should().BeEquivalentTo(expected, x => x.IgnoringCyclicReferences()); + + // Cleanup + Remove(documents[0]); + Remove(documents[1]); + Remove(folder); + Remove(locker); + Remove(room); + Remove(await FindAsync(department.Id)); + } +} \ No newline at end of file diff --git a/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs b/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs index f266b8b6..42601c21 100644 --- a/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs +++ b/tests/Application.Tests.Integration/Folders/Commands/AddFolderTests.cs @@ -1,5 +1,6 @@ using Application.Common.Exceptions; using Application.Folders.Commands; +using Domain.Entities; using Domain.Entities.Physical; using Domain.Exceptions; using FluentAssertions; @@ -17,8 +18,9 @@ public AddFolderTests(CustomApiFactory apiFactory) : base(apiFactory) public async Task ShouldAddFolder_WhenAddDetailsAreValid() { // Arrange + var department = CreateDepartment(); var locker = CreateLocker(); - var room = CreateRoom(locker); + var room = CreateRoom(department, locker); await AddAsync(room); var command = new AddFolder.Command() @@ -45,16 +47,18 @@ public async Task ShouldAddFolder_WhenAddDetailsAreValid() Remove(folderEntity); Remove(locker); Remove(room); + Remove(await FindAsync(department.Id)); } [Fact] public async Task ShouldAddFolder_WhenFoldersHasSameNameButInDifferentLockers() { // Arrange + var department = CreateDepartment(); var folder1 = CreateFolder(); var locker1 = CreateLocker(folder1); var locker2 = CreateLocker(); - var room = CreateRoom(locker1, locker2); + var room = CreateRoom(department, locker1, locker2); await AddAsync(room); var command = new AddFolder.Command() @@ -76,15 +80,17 @@ public async Task ShouldAddFolder_WhenFoldersHasSameNameButInDifferentLockers() Remove(locker1); Remove(locker2); Remove(room); + Remove(await FindAsync(department.Id)); } [Fact] public async Task ShouldThrowConflictException_WhenFolderAlreadyExistsInTheSameLocker() { // Arrange + var department = CreateDepartment(); var folder = CreateFolder(); var locker = CreateLocker(folder); - var room = CreateRoom(locker); + var room = CreateRoom(department, locker); await AddAsync(room); var command = new AddFolder.Command() @@ -105,17 +111,19 @@ await action.Should().ThrowAsync() Remove(folder); Remove(locker); Remove(room); + Remove(await FindAsync(department.Id)); } [Fact] public async Task ShouldThrowLimitExceededException_WhenGoingOverCapacity() { // Arrange + var department = CreateDepartment(); var folder1 = CreateFolder(); var folder2 = CreateFolder(); var folder3 = CreateFolder(); var locker = CreateLocker(folder1, folder2, folder3); - var room = CreateRoom(locker); + var room = CreateRoom(department, locker); await AddAsync(room); var command = new AddFolder.Command() @@ -139,6 +147,7 @@ await action.Should().ThrowAsync() Remove(folder3); Remove(locker); Remove(room); + Remove(await FindAsync(department.Id)); } [Fact] diff --git a/tests/Application.Tests.Integration/Lockers/Commands/DisableLockerTests.cs b/tests/Application.Tests.Integration/Lockers/Commands/DisableLockerTests.cs index 99e3d39c..5cf76d23 100644 --- a/tests/Application.Tests.Integration/Lockers/Commands/DisableLockerTests.cs +++ b/tests/Application.Tests.Integration/Lockers/Commands/DisableLockerTests.cs @@ -1,6 +1,6 @@ using Application.Common.Exceptions; using Application.Lockers.Commands; -using Bogus; +using Domain.Entities; using Domain.Entities.Physical; using FluentAssertions; using Xunit; @@ -17,8 +17,9 @@ public DisableLockerTests(CustomApiFactory apiFactory) : base(apiFactory) public async Task ShouldDisableLocker_WhenLockerExistsAndIsAvailable() { // Arrange + var department = CreateDepartment(); var locker = CreateLocker(); - var room = CreateRoom(locker); + var room = CreateRoom(department, locker); await AddAsync(room); var disableLockerCommand = new DisableLocker.Command() @@ -37,8 +38,8 @@ public async Task ShouldDisableLocker_WhenLockerExistsAndIsAvailable() result.NumberOfFolders.Should().Be(locker.NumberOfFolders); // Cleanup - var roomEntity = await FindAsync(room.Id); - Remove(roomEntity); + Remove(room); + Remove(await FindAsync(department.Id)); } [Fact] @@ -63,8 +64,9 @@ await action.Should() public async Task ShouldThrowConflictException_WhenLockerIsAlreadyDisabled() { // Arrange + var department = CreateDepartment(); var locker = CreateLocker(); - var room = CreateRoom(locker); + var room = CreateRoom(department, locker); await AddAsync(room); var disableLockerCommand = new DisableLocker.Command() @@ -80,7 +82,7 @@ public async Task ShouldThrowConflictException_WhenLockerIsAlreadyDisabled() await action.Should().ThrowAsync().WithMessage("Locker has already been disabled."); // Cleanup - var roomEntity = await FindAsync(room.Id); - Remove(roomEntity); + Remove(room); + Remove(await FindAsync(department.Id)); } } \ No newline at end of file diff --git a/tests/Application.Tests.Integration/Lockers/Commands/EnableLockerTests.cs b/tests/Application.Tests.Integration/Lockers/Commands/EnableLockerTests.cs index 66d381cb..b4ec3df7 100644 --- a/tests/Application.Tests.Integration/Lockers/Commands/EnableLockerTests.cs +++ b/tests/Application.Tests.Integration/Lockers/Commands/EnableLockerTests.cs @@ -1,7 +1,6 @@ using Application.Common.Exceptions; using Application.Lockers.Commands; -using Bogus; -using Domain.Entities.Physical; +using Domain.Entities; using FluentAssertions; using Xunit; @@ -18,9 +17,10 @@ public EnableLockerTests(CustomApiFactory apiFactory) : base(apiFactory) public async Task ShouldEnableLocker_WhenLockerExistsAndIsNotAvailable() { // Arrange + var department = CreateDepartment(); var locker = CreateLocker(); locker.IsAvailable = false; - var room = CreateRoom(locker); + var room = CreateRoom(department, locker); await AddAsync(room); // Act @@ -36,6 +36,7 @@ public async Task ShouldEnableLocker_WhenLockerExistsAndIsNotAvailable() // Cleanup Remove(room); + Remove(await FindAsync(department.Id)); } [Fact] @@ -60,8 +61,9 @@ await action.Should() public async Task ShouldThrowConflictException_WhenLockerIsAlreadyEnabled() { // Arrange + var department = CreateDepartment(); var locker = CreateLocker(); - var room = CreateRoom(locker); + var room = CreateRoom(department, locker); await AddAsync(room); var enableLockerCommand = new EnableLocker.Command() @@ -79,5 +81,6 @@ await action.Should() // Cleanup Remove(room); + Remove(await FindAsync(department.Id)); } } diff --git a/tests/Application.Tests.Integration/Rooms/Commands/DisableRoomTests.cs b/tests/Application.Tests.Integration/Rooms/Commands/DisableRoomTests.cs index b1327cf2..39badcb8 100644 --- a/tests/Application.Tests.Integration/Rooms/Commands/DisableRoomTests.cs +++ b/tests/Application.Tests.Integration/Rooms/Commands/DisableRoomTests.cs @@ -1,5 +1,6 @@ using Application.Common.Exceptions; using Application.Rooms.Commands; +using Domain.Entities; using Domain.Entities.Physical; using FluentAssertions; using Xunit; @@ -16,9 +17,10 @@ public DisableRoomTests(CustomApiFactory apiFactory) : base(apiFactory) public async Task ShouldDisableRoom_WhenRoomHaveNoDocument() { // Arrange + var department = CreateDepartment(); var folder = CreateFolder(); var locker = CreateLocker(folder); - var room = CreateRoom(locker); + var room = CreateRoom(department, locker); await AddAsync(room); var disableRoomCommand = new DisableRoom.Command() @@ -41,6 +43,7 @@ public async Task ShouldDisableRoom_WhenRoomHaveNoDocument() Remove(folder); Remove(locker); Remove(room); + Remove(await FindAsync(department.Id)); } [Fact] @@ -64,10 +67,11 @@ await action.Should().ThrowAsync() public async Task ShouldThrowInvalidOperationException_WhenRoomIsNotEmptyOfDocuments() { // Arrange + var department = CreateDepartment(); var documents = CreateNDocuments(1); var folder = CreateFolder(documents); var locker = CreateLocker(folder); - var room = CreateRoom(locker); + var room = CreateRoom(department, locker); await AddAsync(room); @@ -88,13 +92,15 @@ await action.Should().ThrowAsync() Remove(folder); Remove(locker); Remove(room); + Remove(await FindAsync(department.Id)); } [Fact] public async Task ShouldThrowInvalidOperationException_WhenRoomIsNotAvailable() { // Arrange - var room = CreateRoom(); + var department = CreateDepartment(); + var room = CreateRoom(department); room.IsAvailable = false; await AddAsync(room); @@ -112,5 +118,6 @@ await action.Should().ThrowAsync() // Cleanup Remove(room); + Remove(await FindAsync(department.Id)); } } \ No newline at end of file diff --git a/tests/Application.Tests.Integration/Rooms/Commands/RemoveRoomTests.cs b/tests/Application.Tests.Integration/Rooms/Commands/RemoveRoomTests.cs index 92919e45..69fff2e8 100644 --- a/tests/Application.Tests.Integration/Rooms/Commands/RemoveRoomTests.cs +++ b/tests/Application.Tests.Integration/Rooms/Commands/RemoveRoomTests.cs @@ -1,4 +1,5 @@ using Application.Rooms.Commands; +using Domain.Entities; using Domain.Entities.Physical; using FluentAssertions; using Xunit; @@ -15,30 +16,35 @@ public RemoveRoomTests(CustomApiFactory apiFactory) : base(apiFactory) public async Task ShouldRemoveRoom_WhenRoomHasNoDocuments() { // Arrange - var room = CreateRoom(); + var department = CreateDepartment(); + var room = CreateRoom(department); await Add(room); var command = new RemoveRoom.Command() { RoomId = room.Id }; + // Act - var result = await SendAsync(command); + await SendAsync(command); // Assert var deletedRoom = await FindAsync(room.Id); - result.IsAvailable.Should().BeFalse(); deletedRoom.Should().BeNull(); + + // Cleanup + Remove(await FindAsync(department.Id)); } [Fact] public async Task ShouldThrowInvalidOperationException_WhenRoomHaveDocuments() { // Arrange + var department = CreateDepartment(); var documents = CreateNDocuments(1); var folder = CreateFolder(documents); var locker = CreateLocker(folder); - var room = CreateRoom(locker); + var room = CreateRoom(department, locker); await AddAsync(room); var command = new RemoveRoom.Command() @@ -58,6 +64,7 @@ await action.Should().ThrowAsync() Remove(folder); Remove(locker); Remove(room); + Remove(await FindAsync(department.Id)); } [Fact] diff --git a/tests/Application.Tests.Integration/Rooms/Queries/GetEmptyContainersPaginatedTests.cs b/tests/Application.Tests.Integration/Rooms/Queries/GetEmptyContainersPaginatedTests.cs index 42246842..05ca1bf0 100644 --- a/tests/Application.Tests.Integration/Rooms/Queries/GetEmptyContainersPaginatedTests.cs +++ b/tests/Application.Tests.Integration/Rooms/Queries/GetEmptyContainersPaginatedTests.cs @@ -18,7 +18,18 @@ public GetEmptyContainersPaginatedTests(CustomApiFactory apiFactory) : base(apiF public async Task ShouldReturnLockersWithEmptyFolders() { // Arrange - var room = await SetupTestEntities(); + var department = CreateDepartment(); + var folder1 = CreateFolder(); + var folder2 = CreateFolder(); + var folder3 = CreateFolder(); + folder3.IsAvailable = false; + var locker1 = CreateLocker(folder1, folder2); + locker1.Capacity = 2; + var locker2 = CreateLocker(folder3); + locker2.Capacity = 2; + var room = CreateRoom(department, locker1, locker2); + await AddAsync(room); + var query = new GetEmptyContainersPaginated.Query() { Page = 1, @@ -34,16 +45,17 @@ public async Task ShouldReturnLockersWithEmptyFolders() result.Items.First().Id.Should().Be(room.Lockers.ElementAt(0).Id); result.Items.First().Name.Should().Be(room.Lockers.ElementAt(0).Name); result.Items.First().Description.Should().Be(room.Lockers.ElementAt(0).Description); - result.Items.First().NumberOfFreeFolders.Should().Be(1); - result.Items.First().Capacity.Should().Be(4); - result.Items.First().NumberOfFolders.Should().Be(2); - result.Items.First().Folders.First().Id.Should().Be(room.Lockers.ElementAt(0).Folders.First().Id); - result.Items.First().Folders.First().Name.Should().Be(room.Lockers.ElementAt(0).Folders.First().Name); - result.Items.First().Folders.First().Description.Should().Be(room.Lockers.ElementAt(0).Folders.First().Description); - result.Items.First().Folders.First().Slot.Should().Be(3); + result.Items.First().NumberOfFreeFolders.Should().Be(2); + result.Items.First().Capacity.Should().Be(2); // Cleanup - await CleanupTestEntities(room); + Remove(folder1); + Remove(folder2); + Remove(folder3); + Remove(locker1); + Remove(locker2); + Remove(room); + Remove(department); } [Fact] @@ -63,92 +75,4 @@ public async Task ShouldThrowNotFound_WhenRoomDoesNotExist() // Assert await action.Should().ThrowAsync("Room does not exist"); } - - private async Task SetupTestEntities() - { - var room = new Room() - { - Id = Guid.NewGuid(), - Name = new Faker().Person.FirstName, - Capacity = 3, - IsAvailable = true, - NumberOfLockers = 2, - }; - - var locker1 = new Locker() - { - Id = Guid.NewGuid(), - Name = new Faker().Person.LastName, - Room = room, - Capacity = 4, - IsAvailable = true, - NumberOfFolders = 2 - }; - - var locker2 = new Locker() - { - Id = Guid.NewGuid(), - Name = new Faker().Person.UserName, - Room = room, - Capacity = 4, - IsAvailable = false, - NumberOfFolders = 1 - }; - - var folder1 = new Folder() - { - Id = Guid.NewGuid(), - Name = new Faker().Person.FirstName, - Locker = locker1, - IsAvailable = true, - Capacity = 3, - NumberOfDocuments = 0, - }; - - var folder2 = new Folder() - { - Id = Guid.NewGuid(), - Name = new Faker().Person.LastName, - Locker = locker1, - IsAvailable = true, - Capacity = 2, - NumberOfDocuments = 3 - }; - - var folder3 = new Folder() - { - Id = Guid.NewGuid(), - Name = new Faker().Person.UserName, - Locker = locker2, - IsAvailable = false, - Capacity = 3, - NumberOfDocuments = 1 - }; - - using var scope = ScopeFactory.CreateScope(); - var context = scope.ServiceProvider.GetRequiredService(); - - await context.Rooms.AddAsync(room); - await context.Lockers.AddAsync(locker1); - await context.Lockers.AddAsync(locker2); - await context.Folders.AddAsync(folder1); - await context.Folders.AddAsync(folder2); - await context.Folders.AddAsync(folder3); - - await context.SaveChangesAsync(); - - return room; - } - - private async Task CleanupTestEntities(Room room) - { - using var scope = ScopeFactory.CreateScope(); - var context = scope.ServiceProvider.GetRequiredService(); - - context.RemoveRange(room.Lockers.SelectMany(l => l.Folders)); - context.RemoveRange(room.Lockers); - context.Remove(room); - - await context.SaveChangesAsync(); - } } \ No newline at end of file