From 77136cc7ec44bae019f44a5d44da51002ee5489f Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Sun, 28 Jan 2024 04:33:53 +0300 Subject: [PATCH 01/30] feat: add an extension to simplify attributes --- .../Extensions/BadRequestResponseAttribute.cs | 8 ++++++++ Endpoint/Common/Extensions/ErrorResponseVm.cs | 18 ++++++++++++++++++ .../Extensions/NotFoundResponseAttribute.cs | 8 ++++++++ 3 files changed, 34 insertions(+) create mode 100644 Endpoint/Common/Extensions/BadRequestResponseAttribute.cs create mode 100644 Endpoint/Common/Extensions/ErrorResponseVm.cs create mode 100644 Endpoint/Common/Extensions/NotFoundResponseAttribute.cs diff --git a/Endpoint/Common/Extensions/BadRequestResponseAttribute.cs b/Endpoint/Common/Extensions/BadRequestResponseAttribute.cs new file mode 100644 index 0000000..171da23 --- /dev/null +++ b/Endpoint/Common/Extensions/BadRequestResponseAttribute.cs @@ -0,0 +1,8 @@ +using Microsoft.AspNetCore.Http; +using System; +using Microsoft.AspNetCore.Mvc; + +namespace Mirea.Api.Endpoint.Common.Extensions; + +[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)] +public class BadRequestResponseAttribute() : ProducesResponseTypeAttribute(typeof(ErrorResponseVm), StatusCodes.Status400BadRequest); \ No newline at end of file diff --git a/Endpoint/Common/Extensions/ErrorResponseVm.cs b/Endpoint/Common/Extensions/ErrorResponseVm.cs new file mode 100644 index 0000000..7c4a099 --- /dev/null +++ b/Endpoint/Common/Extensions/ErrorResponseVm.cs @@ -0,0 +1,18 @@ +namespace Mirea.Api.Endpoint.Common.Extensions; + +/// +/// A class for providing information about an error +/// +public class ErrorResponseVm +{ + /// + /// The text or translation code of the error. This field may not contain information in specific scenarios. + /// For example, it might be empty for HTTP 204 responses where no content is returned or if the validation texts have not been configured. + /// + public required string Error { get; set; } + /// + /// In addition to returning the response code in the header, it is also duplicated in this field. + /// Represents the HTTP response code. + /// + public required int Code { get; set; } +} \ No newline at end of file diff --git a/Endpoint/Common/Extensions/NotFoundResponseAttribute.cs b/Endpoint/Common/Extensions/NotFoundResponseAttribute.cs new file mode 100644 index 0000000..15db1cc --- /dev/null +++ b/Endpoint/Common/Extensions/NotFoundResponseAttribute.cs @@ -0,0 +1,8 @@ +using Microsoft.AspNetCore.Http; +using System; +using Microsoft.AspNetCore.Mvc; + +namespace Mirea.Api.Endpoint.Common.Extensions; + +[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)] +public class NotFoundResponseAttribute() : ProducesResponseTypeAttribute(typeof(ErrorResponseVm), StatusCodes.Status404NotFound); \ No newline at end of file -- 2.43.0 From 7b584b2dc5ebc02e2e68124e77bf5de780e7cbe7 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Sun, 28 Jan 2024 04:34:33 +0300 Subject: [PATCH 02/30] feat: add a basic controller --- Endpoint/Controllers/BaseController.cs | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Endpoint/Controllers/BaseController.cs diff --git a/Endpoint/Controllers/BaseController.cs b/Endpoint/Controllers/BaseController.cs new file mode 100644 index 0000000..82c4c7a --- /dev/null +++ b/Endpoint/Controllers/BaseController.cs @@ -0,0 +1,7 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Mirea.Api.Endpoint.Controllers; + +[ApiController] +[Route("api/[controller]/[action]")] +public class BaseController : ControllerBase; \ No newline at end of file -- 2.43.0 From 335298fd910359fb960b55eb1f309a7059c8ba83 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Sun, 28 Jan 2024 04:34:56 +0300 Subject: [PATCH 03/30] feat: add a basic controller for API version 1 --- Endpoint/Controllers/V1/BaseControllerV1.cs | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 Endpoint/Controllers/V1/BaseControllerV1.cs diff --git a/Endpoint/Controllers/V1/BaseControllerV1.cs b/Endpoint/Controllers/V1/BaseControllerV1.cs new file mode 100644 index 0000000..6ebe1f3 --- /dev/null +++ b/Endpoint/Controllers/V1/BaseControllerV1.cs @@ -0,0 +1,8 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Mirea.Api.Endpoint.Controllers.V1; + +[ApiVersion("1.0")] +[Produces("application/json")] +[Route("api/v{version:apiVersion}/[controller]/[action]")] +public class BaseControllerV1 : BaseController; \ No newline at end of file -- 2.43.0 From a4dfccbc229737ae4df526322342ed1ea84d768c Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Sun, 28 Jan 2024 04:33:53 +0300 Subject: [PATCH 04/30] feat: add an extension to simplify attributes --- .../Extensions/BadRequestResponseAttribute.cs | 8 ++++++++ Endpoint/Common/Extensions/ErrorResponseVm.cs | 18 ++++++++++++++++++ .../Extensions/NotFoundResponseAttribute.cs | 8 ++++++++ 3 files changed, 34 insertions(+) create mode 100644 Endpoint/Common/Extensions/BadRequestResponseAttribute.cs create mode 100644 Endpoint/Common/Extensions/ErrorResponseVm.cs create mode 100644 Endpoint/Common/Extensions/NotFoundResponseAttribute.cs diff --git a/Endpoint/Common/Extensions/BadRequestResponseAttribute.cs b/Endpoint/Common/Extensions/BadRequestResponseAttribute.cs new file mode 100644 index 0000000..171da23 --- /dev/null +++ b/Endpoint/Common/Extensions/BadRequestResponseAttribute.cs @@ -0,0 +1,8 @@ +using Microsoft.AspNetCore.Http; +using System; +using Microsoft.AspNetCore.Mvc; + +namespace Mirea.Api.Endpoint.Common.Extensions; + +[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)] +public class BadRequestResponseAttribute() : ProducesResponseTypeAttribute(typeof(ErrorResponseVm), StatusCodes.Status400BadRequest); \ No newline at end of file diff --git a/Endpoint/Common/Extensions/ErrorResponseVm.cs b/Endpoint/Common/Extensions/ErrorResponseVm.cs new file mode 100644 index 0000000..7c4a099 --- /dev/null +++ b/Endpoint/Common/Extensions/ErrorResponseVm.cs @@ -0,0 +1,18 @@ +namespace Mirea.Api.Endpoint.Common.Extensions; + +/// +/// A class for providing information about an error +/// +public class ErrorResponseVm +{ + /// + /// The text or translation code of the error. This field may not contain information in specific scenarios. + /// For example, it might be empty for HTTP 204 responses where no content is returned or if the validation texts have not been configured. + /// + public required string Error { get; set; } + /// + /// In addition to returning the response code in the header, it is also duplicated in this field. + /// Represents the HTTP response code. + /// + public required int Code { get; set; } +} \ No newline at end of file diff --git a/Endpoint/Common/Extensions/NotFoundResponseAttribute.cs b/Endpoint/Common/Extensions/NotFoundResponseAttribute.cs new file mode 100644 index 0000000..15db1cc --- /dev/null +++ b/Endpoint/Common/Extensions/NotFoundResponseAttribute.cs @@ -0,0 +1,8 @@ +using Microsoft.AspNetCore.Http; +using System; +using Microsoft.AspNetCore.Mvc; + +namespace Mirea.Api.Endpoint.Common.Extensions; + +[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)] +public class NotFoundResponseAttribute() : ProducesResponseTypeAttribute(typeof(ErrorResponseVm), StatusCodes.Status404NotFound); \ No newline at end of file -- 2.43.0 From fb6ca5df7715b5e95fb8c226606a2b738d7a5922 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Sun, 28 Jan 2024 04:34:33 +0300 Subject: [PATCH 05/30] feat: add a basic controller --- Endpoint/Controllers/BaseController.cs | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Endpoint/Controllers/BaseController.cs diff --git a/Endpoint/Controllers/BaseController.cs b/Endpoint/Controllers/BaseController.cs new file mode 100644 index 0000000..82c4c7a --- /dev/null +++ b/Endpoint/Controllers/BaseController.cs @@ -0,0 +1,7 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Mirea.Api.Endpoint.Controllers; + +[ApiController] +[Route("api/[controller]/[action]")] +public class BaseController : ControllerBase; \ No newline at end of file -- 2.43.0 From 8852351ca63044f3a377acd84d4b6b5ea3d7fa96 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Sun, 28 Jan 2024 04:34:56 +0300 Subject: [PATCH 06/30] feat: add a basic controller for API version 1 --- Endpoint/Controllers/V1/BaseControllerV1.cs | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 Endpoint/Controllers/V1/BaseControllerV1.cs diff --git a/Endpoint/Controllers/V1/BaseControllerV1.cs b/Endpoint/Controllers/V1/BaseControllerV1.cs new file mode 100644 index 0000000..6ebe1f3 --- /dev/null +++ b/Endpoint/Controllers/V1/BaseControllerV1.cs @@ -0,0 +1,8 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Mirea.Api.Endpoint.Controllers.V1; + +[ApiVersion("1.0")] +[Produces("application/json")] +[Route("api/v{version:apiVersion}/[controller]/[action]")] +public class BaseControllerV1 : BaseController; \ No newline at end of file -- 2.43.0 From 96a820deaddebd3a147b58ff4c505193205c067c Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Sun, 28 Jan 2024 04:33:53 +0300 Subject: [PATCH 07/30] feat: add an extension to simplify attributes --- .../Extensions/BadRequestResponseAttribute.cs | 8 ++++++++ Endpoint/Common/Extensions/ErrorResponseVm.cs | 18 ++++++++++++++++++ .../Extensions/NotFoundResponseAttribute.cs | 8 ++++++++ 3 files changed, 34 insertions(+) create mode 100644 Endpoint/Common/Extensions/BadRequestResponseAttribute.cs create mode 100644 Endpoint/Common/Extensions/ErrorResponseVm.cs create mode 100644 Endpoint/Common/Extensions/NotFoundResponseAttribute.cs diff --git a/Endpoint/Common/Extensions/BadRequestResponseAttribute.cs b/Endpoint/Common/Extensions/BadRequestResponseAttribute.cs new file mode 100644 index 0000000..171da23 --- /dev/null +++ b/Endpoint/Common/Extensions/BadRequestResponseAttribute.cs @@ -0,0 +1,8 @@ +using Microsoft.AspNetCore.Http; +using System; +using Microsoft.AspNetCore.Mvc; + +namespace Mirea.Api.Endpoint.Common.Extensions; + +[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)] +public class BadRequestResponseAttribute() : ProducesResponseTypeAttribute(typeof(ErrorResponseVm), StatusCodes.Status400BadRequest); \ No newline at end of file diff --git a/Endpoint/Common/Extensions/ErrorResponseVm.cs b/Endpoint/Common/Extensions/ErrorResponseVm.cs new file mode 100644 index 0000000..7c4a099 --- /dev/null +++ b/Endpoint/Common/Extensions/ErrorResponseVm.cs @@ -0,0 +1,18 @@ +namespace Mirea.Api.Endpoint.Common.Extensions; + +/// +/// A class for providing information about an error +/// +public class ErrorResponseVm +{ + /// + /// The text or translation code of the error. This field may not contain information in specific scenarios. + /// For example, it might be empty for HTTP 204 responses where no content is returned or if the validation texts have not been configured. + /// + public required string Error { get; set; } + /// + /// In addition to returning the response code in the header, it is also duplicated in this field. + /// Represents the HTTP response code. + /// + public required int Code { get; set; } +} \ No newline at end of file diff --git a/Endpoint/Common/Extensions/NotFoundResponseAttribute.cs b/Endpoint/Common/Extensions/NotFoundResponseAttribute.cs new file mode 100644 index 0000000..15db1cc --- /dev/null +++ b/Endpoint/Common/Extensions/NotFoundResponseAttribute.cs @@ -0,0 +1,8 @@ +using Microsoft.AspNetCore.Http; +using System; +using Microsoft.AspNetCore.Mvc; + +namespace Mirea.Api.Endpoint.Common.Extensions; + +[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)] +public class NotFoundResponseAttribute() : ProducesResponseTypeAttribute(typeof(ErrorResponseVm), StatusCodes.Status404NotFound); \ No newline at end of file -- 2.43.0 From 07e04b99c571755d5ac408a504dea425b46c2b20 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Sun, 28 Jan 2024 04:34:33 +0300 Subject: [PATCH 08/30] feat: add a basic controller --- Endpoint/Controllers/BaseController.cs | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Endpoint/Controllers/BaseController.cs diff --git a/Endpoint/Controllers/BaseController.cs b/Endpoint/Controllers/BaseController.cs new file mode 100644 index 0000000..82c4c7a --- /dev/null +++ b/Endpoint/Controllers/BaseController.cs @@ -0,0 +1,7 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Mirea.Api.Endpoint.Controllers; + +[ApiController] +[Route("api/[controller]/[action]")] +public class BaseController : ControllerBase; \ No newline at end of file -- 2.43.0 From 2403cb35eca32fb006c0aebc11435427cafef5f9 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Sun, 28 Jan 2024 04:34:56 +0300 Subject: [PATCH 09/30] feat: add a basic controller for API version 1 --- Endpoint/Controllers/V1/BaseControllerV1.cs | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 Endpoint/Controllers/V1/BaseControllerV1.cs diff --git a/Endpoint/Controllers/V1/BaseControllerV1.cs b/Endpoint/Controllers/V1/BaseControllerV1.cs new file mode 100644 index 0000000..6ebe1f3 --- /dev/null +++ b/Endpoint/Controllers/V1/BaseControllerV1.cs @@ -0,0 +1,8 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Mirea.Api.Endpoint.Controllers.V1; + +[ApiVersion("1.0")] +[Produces("application/json")] +[Route("api/v{version:apiVersion}/[controller]/[action]")] +public class BaseControllerV1 : BaseController; \ No newline at end of file -- 2.43.0 From 88b4eb594ec7ef53e25547c0d6b7aa0c087d7469 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Sun, 28 Jan 2024 06:05:27 +0300 Subject: [PATCH 10/30] feat: add a controller for discipline --- .../Controllers/V1/DisciplineController.cs | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 Endpoint/Controllers/V1/DisciplineController.cs diff --git a/Endpoint/Controllers/V1/DisciplineController.cs b/Endpoint/Controllers/V1/DisciplineController.cs new file mode 100644 index 0000000..6589d31 --- /dev/null +++ b/Endpoint/Controllers/V1/DisciplineController.cs @@ -0,0 +1,53 @@ +using MediatR; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Mirea.Api.DataAccess.Application.Cqrs.Discipline.Queries.GetDisciplineDetails; +using Mirea.Api.DataAccess.Application.Cqrs.Discipline.Queries.GetDisciplineList; +using Mirea.Api.Endpoint.Common.Extensions; +using System.Threading.Tasks; + +namespace Mirea.Api.Endpoint.Controllers.V1 +{ + public class DisciplineController(IMediator mediator) : BaseControllerV1 + { + /// + /// Gets a paginated list of disciplines. + /// + /// Page number. Start from 0. + /// Number of items per page. + /// Paginated list of disciplines. + [HttpGet] + [ProducesResponseType(StatusCodes.Status200OK)] + [BadRequestResponse] + public async Task> Get([FromQuery] int? page, [FromQuery] int? pageSize) + { + var result = await mediator.Send(new GetDisciplineListQuery() + { + Page = page, + PageSize = pageSize + }); + + return Ok(result); + } + + /// + /// Gets details of a specific discipline by ID. + /// + /// Discipline ID. + /// Details of the specified discipline. + /// + [HttpGet("{id:int}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [BadRequestResponse] + [NotFoundResponse] + public async Task> GetDetails(int id) + { + var result = await mediator.Send(new GetDisciplineInfoQuery() + { + Id = id + }); + + return Ok(result); + } + } +} -- 2.43.0 From dfc9caf921599d6bf074f47388221c2a26fba51d Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Sun, 28 Jan 2024 06:05:54 +0300 Subject: [PATCH 11/30] feat: add a controller for campus --- Endpoint/Controllers/V1/CampusController.cs | 45 +++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 Endpoint/Controllers/V1/CampusController.cs diff --git a/Endpoint/Controllers/V1/CampusController.cs b/Endpoint/Controllers/V1/CampusController.cs new file mode 100644 index 0000000..c383608 --- /dev/null +++ b/Endpoint/Controllers/V1/CampusController.cs @@ -0,0 +1,45 @@ +using MediatR; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Mirea.Api.DataAccess.Application.Cqrs.Campus.Queries.GetCampusBasicInfoList; +using Mirea.Api.DataAccess.Application.Cqrs.Campus.Queries.GetCampusDetails; +using Mirea.Api.Endpoint.Common.Extensions; +using System.Threading.Tasks; + +namespace Mirea.Api.Endpoint.Controllers.V1 +{ + public class CampusController(IMediator mediator) : BaseControllerV1 + { + /// + /// Gets basic information about campuses. + /// + /// Basic information about campuses. + [HttpGet] + [ProducesResponseType(StatusCodes.Status200OK)] + public async Task> GetBasicInfo() + { + var result = await mediator.Send(new GetCampusBasicInfoListQuery()); + + return Ok(result); + } + + /// + /// Gets details of a specific campus by ID. + /// + /// Campus ID. + /// Details of the specified campus. + [HttpGet("{id:int}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [BadRequestResponse] + [NotFoundResponse] + public async Task> GetDetails(int id) + { + var result = await mediator.Send(new GetCampusDetailsQuery() + { + Id = id + }); + + return Ok(result); + } + } +} -- 2.43.0 From 810c8ec5cf5b35523453bc091e407ca785e7cfd2 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Sun, 28 Jan 2024 06:28:14 +0300 Subject: [PATCH 12/30] refactor: move files --- .../{Extensions => Attributes}/BadRequestResponseAttribute.cs | 3 ++- .../{Extensions => Attributes}/NotFoundResponseAttribute.cs | 3 ++- Endpoint/{ => Configuration}/ConfigureSwaggerOptions.cs | 2 +- Endpoint/{ => Configuration}/EnvironmentManager.cs | 2 +- Endpoint/{Common/Extensions => Models}/ErrorResponseVm.cs | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) rename Endpoint/Common/{Extensions => Attributes}/BadRequestResponseAttribute.cs (90%) rename Endpoint/Common/{Extensions => Attributes}/NotFoundResponseAttribute.cs (90%) rename Endpoint/{ => Configuration}/ConfigureSwaggerOptions.cs (96%) rename Endpoint/{ => Configuration}/EnvironmentManager.cs (93%) rename Endpoint/{Common/Extensions => Models}/ErrorResponseVm.cs (92%) diff --git a/Endpoint/Common/Extensions/BadRequestResponseAttribute.cs b/Endpoint/Common/Attributes/BadRequestResponseAttribute.cs similarity index 90% rename from Endpoint/Common/Extensions/BadRequestResponseAttribute.cs rename to Endpoint/Common/Attributes/BadRequestResponseAttribute.cs index 171da23..b81f692 100644 --- a/Endpoint/Common/Extensions/BadRequestResponseAttribute.cs +++ b/Endpoint/Common/Attributes/BadRequestResponseAttribute.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Http; -using System; using Microsoft.AspNetCore.Mvc; +using Mirea.Api.Endpoint.Models; +using System; namespace Mirea.Api.Endpoint.Common.Extensions; diff --git a/Endpoint/Common/Extensions/NotFoundResponseAttribute.cs b/Endpoint/Common/Attributes/NotFoundResponseAttribute.cs similarity index 90% rename from Endpoint/Common/Extensions/NotFoundResponseAttribute.cs rename to Endpoint/Common/Attributes/NotFoundResponseAttribute.cs index 15db1cc..8f05a69 100644 --- a/Endpoint/Common/Extensions/NotFoundResponseAttribute.cs +++ b/Endpoint/Common/Attributes/NotFoundResponseAttribute.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Http; -using System; using Microsoft.AspNetCore.Mvc; +using Mirea.Api.Endpoint.Models; +using System; namespace Mirea.Api.Endpoint.Common.Extensions; diff --git a/Endpoint/ConfigureSwaggerOptions.cs b/Endpoint/Configuration/ConfigureSwaggerOptions.cs similarity index 96% rename from Endpoint/ConfigureSwaggerOptions.cs rename to Endpoint/Configuration/ConfigureSwaggerOptions.cs index 9b53140..39280bb 100644 --- a/Endpoint/ConfigureSwaggerOptions.cs +++ b/Endpoint/Configuration/ConfigureSwaggerOptions.cs @@ -5,7 +5,7 @@ using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; using System; -namespace Mirea.Api.Endpoint; +namespace Mirea.Api.Endpoint.Configuration; public class ConfigureSwaggerOptions(IApiVersionDescriptionProvider provider) : IConfigureOptions { diff --git a/Endpoint/EnvironmentManager.cs b/Endpoint/Configuration/EnvironmentManager.cs similarity index 93% rename from Endpoint/EnvironmentManager.cs rename to Endpoint/Configuration/EnvironmentManager.cs index 3cbe859..cc2b201 100644 --- a/Endpoint/EnvironmentManager.cs +++ b/Endpoint/Configuration/EnvironmentManager.cs @@ -1,7 +1,7 @@ using System; using System.IO; -namespace Mirea.Api.Endpoint; +namespace Mirea.Api.Endpoint.Configuration; internal static class EnvironmentManager { diff --git a/Endpoint/Common/Extensions/ErrorResponseVm.cs b/Endpoint/Models/ErrorResponseVm.cs similarity index 92% rename from Endpoint/Common/Extensions/ErrorResponseVm.cs rename to Endpoint/Models/ErrorResponseVm.cs index 7c4a099..d409ae1 100644 --- a/Endpoint/Common/Extensions/ErrorResponseVm.cs +++ b/Endpoint/Models/ErrorResponseVm.cs @@ -1,4 +1,4 @@ -namespace Mirea.Api.Endpoint.Common.Extensions; +namespace Mirea.Api.Endpoint.Models; /// /// A class for providing information about an error -- 2.43.0 From 93a1b6ea8ef47b69fbf51d3cdf484f3461778266 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Sun, 28 Jan 2024 06:29:47 +0300 Subject: [PATCH 13/30] refactor move files --- Endpoint/{ => Configuration}/SwaggerDefaultValues.cs | 4 ++-- Endpoint/Program.cs | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) rename Endpoint/{ => Configuration}/SwaggerDefaultValues.cs (93%) diff --git a/Endpoint/SwaggerDefaultValues.cs b/Endpoint/Configuration/SwaggerDefaultValues.cs similarity index 93% rename from Endpoint/SwaggerDefaultValues.cs rename to Endpoint/Configuration/SwaggerDefaultValues.cs index d47c591..cefb307 100644 --- a/Endpoint/SwaggerDefaultValues.cs +++ b/Endpoint/Configuration/SwaggerDefaultValues.cs @@ -6,7 +6,7 @@ using System; using System.Linq; using System.Text.Json; -namespace Mirea.Api.Endpoint; +namespace Mirea.Api.Endpoint.Configuration; public class SwaggerDefaultValues : IOperationFilter { @@ -38,7 +38,7 @@ public class SwaggerDefaultValues : IOperationFilter { var description = apiDescription.ParameterDescriptions.First(p => p.Name == parameter.Name); - parameter.Description ??= description.ModelMetadata?.Description; + parameter.Description ??= description.ModelMetadata.Description; if (parameter.Schema.Default == null && description.DefaultValue != null && diff --git a/Endpoint/Program.cs b/Endpoint/Program.cs index 920ce15..c71f6c9 100644 --- a/Endpoint/Program.cs +++ b/Endpoint/Program.cs @@ -8,6 +8,8 @@ using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Options; using Mirea.Api.DataAccess.Application; using Mirea.Api.DataAccess.Persistence; +using Mirea.Api.Endpoint.Configuration; +using Mirea.Api.Endpoint.Middleware; using Mirea.Api.Endpoint.Properties; using Swashbuckle.AspNetCore.SwaggerGen; using System; -- 2.43.0 From 851eccd876dd8bac432eb69b447cfcff3ca728bf Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Sun, 28 Jan 2024 06:32:43 +0300 Subject: [PATCH 14/30] fix: error CS0234 --- Endpoint/Program.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Endpoint/Program.cs b/Endpoint/Program.cs index c71f6c9..3607500 100644 --- a/Endpoint/Program.cs +++ b/Endpoint/Program.cs @@ -9,7 +9,6 @@ using Microsoft.Extensions.Options; using Mirea.Api.DataAccess.Application; using Mirea.Api.DataAccess.Persistence; using Mirea.Api.Endpoint.Configuration; -using Mirea.Api.Endpoint.Middleware; using Mirea.Api.Endpoint.Properties; using Swashbuckle.AspNetCore.SwaggerGen; using System; -- 2.43.0 From 1b8c82949ac1471ed5d583d112fc4a35863c8eb6 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Fri, 16 Feb 2024 23:54:52 +0300 Subject: [PATCH 15/30] feat: write a dto in a separate project --- ApiDto/ApiDto.csproj | 23 +++++++++++++++ ApiDto/Responses/CampusBasicInfoResponse.cs | 22 ++++++++++++++ ApiDto/Responses/CampusDetailsResponse.cs | 27 +++++++++++++++++ ApiDto/Responses/DisciplineResponse.cs | 17 +++++++++++ ApiDto/Responses/ErrorResponse.cs | 18 ++++++++++++ ApiDto/Responses/FacultyDetailsResponse.cs | 32 +++++++++++++++++++++ ApiDto/Responses/FacultyResponse.cs | 22 ++++++++++++++ ApiDto/Responses/GroupDetailsResponse.cs | 27 +++++++++++++++++ ApiDto/Responses/GroupResponse.cs | 22 ++++++++++++++ ApiDto/Responses/ProfessorResponse.cs | 22 ++++++++++++++ 10 files changed, 232 insertions(+) create mode 100644 ApiDto/ApiDto.csproj create mode 100644 ApiDto/Responses/CampusBasicInfoResponse.cs create mode 100644 ApiDto/Responses/CampusDetailsResponse.cs create mode 100644 ApiDto/Responses/DisciplineResponse.cs create mode 100644 ApiDto/Responses/ErrorResponse.cs create mode 100644 ApiDto/Responses/FacultyDetailsResponse.cs create mode 100644 ApiDto/Responses/FacultyResponse.cs create mode 100644 ApiDto/Responses/GroupDetailsResponse.cs create mode 100644 ApiDto/Responses/GroupResponse.cs create mode 100644 ApiDto/Responses/ProfessorResponse.cs diff --git a/ApiDto/ApiDto.csproj b/ApiDto/ApiDto.csproj new file mode 100644 index 0000000..f806393 --- /dev/null +++ b/ApiDto/ApiDto.csproj @@ -0,0 +1,23 @@ + + + + net8.0 + disable + enable + Winsomnia + 1.0.0-a0 + 1.0.0.0 + 1.0.0.0 + Mirea.Api.Dto + $(AssemblyName) + True + ApiDtoDocs.xml + + + + + Always + + + + diff --git a/ApiDto/Responses/CampusBasicInfoResponse.cs b/ApiDto/Responses/CampusBasicInfoResponse.cs new file mode 100644 index 0000000..0232050 --- /dev/null +++ b/ApiDto/Responses/CampusBasicInfoResponse.cs @@ -0,0 +1,22 @@ +namespace Mirea.Api.Dto.Responses; + +/// +/// Represents basic information about a campus. +/// +public class CampusBasicInfoResponse +{ + /// + /// Gets or sets the unique identifier of the campus. + /// + public int Id { get; set; } + + /// + /// Gets or sets the code name of the campus. + /// + public required string CodeName { get; set; } + + /// + /// Gets or sets the full name of the campus (optional). + /// + public string? FullName { get; set; } +} \ No newline at end of file diff --git a/ApiDto/Responses/CampusDetailsResponse.cs b/ApiDto/Responses/CampusDetailsResponse.cs new file mode 100644 index 0000000..7caff6b --- /dev/null +++ b/ApiDto/Responses/CampusDetailsResponse.cs @@ -0,0 +1,27 @@ +namespace Mirea.Api.Dto.Responses; + +/// +/// Represents detailed information about a campus. +/// +public class CampusDetailsResponse +{ + /// + /// Gets or sets the unique identifier of the campus. + /// + public int Id { get; set; } + + /// + /// Gets or sets the code name of the campus. + /// + public required string CodeName { get; set; } + + /// + /// Gets or sets the full name of the campus (optional). + /// + public string? FullName { get; set; } + + /// + /// Gets or sets the address of the campus (optional). + /// + public string? Address { get; set; } +} diff --git a/ApiDto/Responses/DisciplineResponse.cs b/ApiDto/Responses/DisciplineResponse.cs new file mode 100644 index 0000000..d98b723 --- /dev/null +++ b/ApiDto/Responses/DisciplineResponse.cs @@ -0,0 +1,17 @@ +namespace Mirea.Api.Dto.Responses; + +/// +/// Represents information about a discipline. +/// +public class DisciplineResponse +{ + /// + /// Gets or sets the unique identifier of the discipline. + /// + public int Id { get; set; } + + /// + /// Gets or sets the name of the discipline. + /// + public required string Name { get; set; } +} \ No newline at end of file diff --git a/ApiDto/Responses/ErrorResponse.cs b/ApiDto/Responses/ErrorResponse.cs new file mode 100644 index 0000000..b67377c --- /dev/null +++ b/ApiDto/Responses/ErrorResponse.cs @@ -0,0 +1,18 @@ +namespace Mirea.Api.Dto.Responses; + +/// +/// A class for providing information about an error +/// +public class ErrorResponse +{ + /// + /// The text or translation code of the error. This field may not contain information in specific scenarios. + /// For example, it might be empty for HTTP 204 responses where no content is returned or if the validation texts have not been configured. + /// + public required string Error { get; set; } + /// + /// In addition to returning the response code in the header, it is also duplicated in this field. + /// Represents the HTTP response code. + /// + public required int Code { get; set; } +} \ No newline at end of file diff --git a/ApiDto/Responses/FacultyDetailsResponse.cs b/ApiDto/Responses/FacultyDetailsResponse.cs new file mode 100644 index 0000000..ff86c47 --- /dev/null +++ b/ApiDto/Responses/FacultyDetailsResponse.cs @@ -0,0 +1,32 @@ +namespace Mirea.Api.Dto.Responses; + +/// +/// Represents detailed information about a faculty. +/// +public class FacultyDetailsResponse +{ + /// + /// Gets or sets the unique identifier of the faculty. + /// + public int Id { get; set; } + + /// + /// Gets or sets the name of the faculty. + /// + public required string Name { get; set; } + + /// + /// Gets or sets the unique identifier of the campus to which the faculty belongs (optional). + /// + public int? CampusId { get; set; } + + /// + /// Gets or sets the name of the campus to which the faculty belongs (optional). + /// + public string? CampusName { get; set; } + + /// + /// Gets or sets the code name of the campus to which the faculty belongs (optional). + /// + public string? CampusCode { get; set; } +} \ No newline at end of file diff --git a/ApiDto/Responses/FacultyResponse.cs b/ApiDto/Responses/FacultyResponse.cs new file mode 100644 index 0000000..136655d --- /dev/null +++ b/ApiDto/Responses/FacultyResponse.cs @@ -0,0 +1,22 @@ +namespace Mirea.Api.Dto.Responses; + +/// +/// Represents basic information about a faculty. +/// +public class FacultyResponse +{ + /// + /// Gets or sets the unique identifier of the faculty. + /// + public int Id { get; set; } + + /// + /// Gets or sets the name of the faculty. + /// + public required string Name { get; set; } + + /// + /// Gets or sets the unique identifier of the campus to which the faculty belongs (optional). + /// + public int? CampusId { get; set; } +} \ No newline at end of file diff --git a/ApiDto/Responses/GroupDetailsResponse.cs b/ApiDto/Responses/GroupDetailsResponse.cs new file mode 100644 index 0000000..35c665b --- /dev/null +++ b/ApiDto/Responses/GroupDetailsResponse.cs @@ -0,0 +1,27 @@ +namespace Mirea.Api.Dto.Responses; + +/// +/// Represents detailed information about a group. +/// +public class GroupDetailsResponse +{ + /// + /// Gets or sets the unique identifier of the group. + /// + public int Id { get; set; } + + /// + /// Gets or sets the name of the group. + /// + public required string Name { get; set; } + + /// + /// Gets or sets the unique identifier of the faculty to which the group belongs (optional). + /// + public int? FacultyId { get; set; } + + /// + /// Gets or sets the name of the faculty to which the group belongs (optional). + /// + public string? FacultyName { get; set; } +} \ No newline at end of file diff --git a/ApiDto/Responses/GroupResponse.cs b/ApiDto/Responses/GroupResponse.cs new file mode 100644 index 0000000..4526e72 --- /dev/null +++ b/ApiDto/Responses/GroupResponse.cs @@ -0,0 +1,22 @@ +namespace Mirea.Api.Dto.Responses; + +/// +/// Represents basic information about a group. +/// +public class GroupResponse +{ + /// + /// Gets or sets the unique identifier of the group. + /// + public int Id { get; set; } + + /// + /// Gets or sets the name of the group. + /// + public required string Name { get; set; } + + /// + /// Gets or sets the unique identifier of the faculty to which the group belongs (optional). + /// + public int? FacultyId { get; set; } +} \ No newline at end of file diff --git a/ApiDto/Responses/ProfessorResponse.cs b/ApiDto/Responses/ProfessorResponse.cs new file mode 100644 index 0000000..3a7b761 --- /dev/null +++ b/ApiDto/Responses/ProfessorResponse.cs @@ -0,0 +1,22 @@ +namespace Mirea.Api.Dto.Responses; + +/// +/// Represents information about a professor. +/// +public class ProfessorResponse +{ + /// + /// Gets or sets the unique identifier of the professor. + /// + public int Id { get; set; } + + /// + /// Gets or sets the name of the professor. + /// + public required string Name { get; set; } + + /// + /// Gets or sets the alternate name of the professor (optional). + /// + public string? AltName { get; set; } +} \ No newline at end of file -- 2.43.0 From 1caaa4759e1dee14ef08ca28146bce6fc0348509 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Fri, 16 Feb 2024 23:56:45 +0300 Subject: [PATCH 16/30] refactor: rewrite the api for the dto project --- .../Attributes/BadRequestResponseAttribute.cs | 6 ++--- .../Attributes/NotFoundResponseAttribute.cs | 6 ++--- Endpoint/Controllers/V1/CampusController.cs | 26 +++++++++++++++---- .../Controllers/V1/DisciplineController.cs | 26 ++++++++++++++----- Endpoint/Endpoint.csproj | 1 + Endpoint/Models/ErrorResponseVm.cs | 18 ------------- 6 files changed, 47 insertions(+), 36 deletions(-) delete mode 100644 Endpoint/Models/ErrorResponseVm.cs diff --git a/Endpoint/Common/Attributes/BadRequestResponseAttribute.cs b/Endpoint/Common/Attributes/BadRequestResponseAttribute.cs index b81f692..85f9ed8 100644 --- a/Endpoint/Common/Attributes/BadRequestResponseAttribute.cs +++ b/Endpoint/Common/Attributes/BadRequestResponseAttribute.cs @@ -1,9 +1,9 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Mirea.Api.Endpoint.Models; +using Mirea.Api.Dto.Responses; using System; -namespace Mirea.Api.Endpoint.Common.Extensions; +namespace Mirea.Api.Endpoint.Common.Attributes; [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)] -public class BadRequestResponseAttribute() : ProducesResponseTypeAttribute(typeof(ErrorResponseVm), StatusCodes.Status400BadRequest); \ No newline at end of file +public class BadRequestResponseAttribute() : ProducesResponseTypeAttribute(typeof(ErrorResponse), StatusCodes.Status400BadRequest); \ No newline at end of file diff --git a/Endpoint/Common/Attributes/NotFoundResponseAttribute.cs b/Endpoint/Common/Attributes/NotFoundResponseAttribute.cs index 8f05a69..39527ea 100644 --- a/Endpoint/Common/Attributes/NotFoundResponseAttribute.cs +++ b/Endpoint/Common/Attributes/NotFoundResponseAttribute.cs @@ -1,9 +1,9 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Mirea.Api.Endpoint.Models; +using Mirea.Api.Dto.Responses; using System; -namespace Mirea.Api.Endpoint.Common.Extensions; +namespace Mirea.Api.Endpoint.Common.Attributes; [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)] -public class NotFoundResponseAttribute() : ProducesResponseTypeAttribute(typeof(ErrorResponseVm), StatusCodes.Status404NotFound); \ No newline at end of file +public class NotFoundResponseAttribute() : ProducesResponseTypeAttribute(typeof(ErrorResponse), StatusCodes.Status404NotFound); \ No newline at end of file diff --git a/Endpoint/Controllers/V1/CampusController.cs b/Endpoint/Controllers/V1/CampusController.cs index c383608..4ee93c8 100644 --- a/Endpoint/Controllers/V1/CampusController.cs +++ b/Endpoint/Controllers/V1/CampusController.cs @@ -3,7 +3,10 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Mirea.Api.DataAccess.Application.Cqrs.Campus.Queries.GetCampusBasicInfoList; using Mirea.Api.DataAccess.Application.Cqrs.Campus.Queries.GetCampusDetails; -using Mirea.Api.Endpoint.Common.Extensions; +using Mirea.Api.Dto.Responses; +using Mirea.Api.Endpoint.Common.Attributes; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; namespace Mirea.Api.Endpoint.Controllers.V1 @@ -16,11 +19,18 @@ namespace Mirea.Api.Endpoint.Controllers.V1 /// Basic information about campuses. [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> GetBasicInfo() + public async Task>> GetBasicInfo() { var result = await mediator.Send(new GetCampusBasicInfoListQuery()); - return Ok(result); + return Ok(result.Campuses + .Select(c => new CampusBasicInfoResponse() + { + Id = c.Id, + CodeName = c.CodeName, + FullName = c.FullName + }) + ); } /// @@ -32,14 +42,20 @@ namespace Mirea.Api.Endpoint.Controllers.V1 [ProducesResponseType(StatusCodes.Status200OK)] [BadRequestResponse] [NotFoundResponse] - public async Task> GetDetails(int id) + public async Task> GetDetails(int id) { var result = await mediator.Send(new GetCampusDetailsQuery() { Id = id }); - return Ok(result); + return Ok(new CampusDetailsResponse() + { + Id = result.Id, + CodeName = result.CodeName, + FullName = result.FullName, + Address = result.Address + }); } } } diff --git a/Endpoint/Controllers/V1/DisciplineController.cs b/Endpoint/Controllers/V1/DisciplineController.cs index 6589d31..056b208 100644 --- a/Endpoint/Controllers/V1/DisciplineController.cs +++ b/Endpoint/Controllers/V1/DisciplineController.cs @@ -3,7 +3,10 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Mirea.Api.DataAccess.Application.Cqrs.Discipline.Queries.GetDisciplineDetails; using Mirea.Api.DataAccess.Application.Cqrs.Discipline.Queries.GetDisciplineList; -using Mirea.Api.Endpoint.Common.Extensions; +using Mirea.Api.Dto.Responses; +using Mirea.Api.Endpoint.Common.Attributes; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; namespace Mirea.Api.Endpoint.Controllers.V1 @@ -19,7 +22,7 @@ namespace Mirea.Api.Endpoint.Controllers.V1 [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] [BadRequestResponse] - public async Task> Get([FromQuery] int? page, [FromQuery] int? pageSize) + public async Task>> Get([FromQuery] int? page, [FromQuery] int? pageSize) { var result = await mediator.Send(new GetDisciplineListQuery() { @@ -27,27 +30,36 @@ namespace Mirea.Api.Endpoint.Controllers.V1 PageSize = pageSize }); - return Ok(result); + return Ok(result.Disciplines + .Select(d => new DisciplineResponse() + { + Id = d.Id, + Name = d.Name + }) + ); } /// /// Gets details of a specific discipline by ID. /// /// Discipline ID. - /// Details of the specified discipline. - /// + /// Details of the specified discipline. [HttpGet("{id:int}")] [ProducesResponseType(StatusCodes.Status200OK)] [BadRequestResponse] [NotFoundResponse] - public async Task> GetDetails(int id) + public async Task> GetDetails(int id) { var result = await mediator.Send(new GetDisciplineInfoQuery() { Id = id }); - return Ok(result); + return Ok(new DisciplineResponse() + { + Id = result.Id, + Name = result.Name + }); } } } diff --git a/Endpoint/Endpoint.csproj b/Endpoint/Endpoint.csproj index 84dcfc2..0191a2e 100644 --- a/Endpoint/Endpoint.csproj +++ b/Endpoint/Endpoint.csproj @@ -28,6 +28,7 @@ + diff --git a/Endpoint/Models/ErrorResponseVm.cs b/Endpoint/Models/ErrorResponseVm.cs deleted file mode 100644 index d409ae1..0000000 --- a/Endpoint/Models/ErrorResponseVm.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Mirea.Api.Endpoint.Models; - -/// -/// A class for providing information about an error -/// -public class ErrorResponseVm -{ - /// - /// The text or translation code of the error. This field may not contain information in specific scenarios. - /// For example, it might be empty for HTTP 204 responses where no content is returned or if the validation texts have not been configured. - /// - public required string Error { get; set; } - /// - /// In addition to returning the response code in the header, it is also duplicated in this field. - /// Represents the HTTP response code. - /// - public required int Code { get; set; } -} \ No newline at end of file -- 2.43.0 From aad3c74fba610c00aa6c40b908442fe51f3e6c2b Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Fri, 16 Feb 2024 23:57:05 +0300 Subject: [PATCH 17/30] feat: add controller for faculty --- Endpoint/Controllers/V1/FacultyController.cs | 73 ++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 Endpoint/Controllers/V1/FacultyController.cs diff --git a/Endpoint/Controllers/V1/FacultyController.cs b/Endpoint/Controllers/V1/FacultyController.cs new file mode 100644 index 0000000..fe0190d --- /dev/null +++ b/Endpoint/Controllers/V1/FacultyController.cs @@ -0,0 +1,73 @@ +using MediatR; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Mirea.Api.DataAccess.Application.Cqrs.Faculty.Queries.GetFacultyDetails; +using Mirea.Api.DataAccess.Application.Cqrs.Faculty.Queries.GetFacultyList; +using Mirea.Api.Dto.Responses; +using Mirea.Api.Endpoint.Common.Attributes; +using Swashbuckle.AspNetCore.Annotations; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Mirea.Api.Endpoint.Controllers.V1 +{ + public class FacultyController(IMediator mediator) : BaseControllerV1 + { + /// + /// Gets a paginated list of faculties. + /// + /// Page number. Start from 0. + /// Number of items per page. + /// Paginated list of faculties. + [HttpGet] + [ProducesResponseType(StatusCodes.Status200OK)] + [BadRequestResponse] + public async Task>> Get( + [SwaggerDefault("0")][SwaggerSchema(Nullable = true)][FromQuery] int? page, + [SwaggerDefault("25")][SwaggerSchema(Nullable = true)][FromQuery] int? pageSize) + { + var result = await mediator.Send(new GetFacultyListQuery() + { + Page = page, + PageSize = pageSize + }); + + return Ok(result.Faculties + .Select(f => new FacultyResponse() + { + Id = f.Id, + Name = f.Name, + CampusId = f.CampusId + }) + ); + } + + /// + /// Gets details of a specific faculty by ID. + /// + /// Faculty ID. + /// Details of the specified faculty. + [HttpGet("{id:int}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [BadRequestResponse] + [NotFoundResponse] + public async Task> GetDetails( + [SwaggerDefault("1")] int id) + { + var result = await mediator.Send(new GetFacultyInfoQuery() + { + Id = id + }); + + return Ok(new FacultyDetailsResponse() + { + Id = result.Id, + Name = result.Name, + CampusId = result.CampusId, + CampusCode = result.CampusCode, + CampusName = result.CampusName + }); + } + } +} -- 2.43.0 From 14aedf9d46bb694a5938087e9a2337ea465c98a6 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Fri, 16 Feb 2024 23:57:13 +0300 Subject: [PATCH 18/30] feat: add controller for group --- Endpoint/Controllers/V1/GroupController.cs | 68 ++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 Endpoint/Controllers/V1/GroupController.cs diff --git a/Endpoint/Controllers/V1/GroupController.cs b/Endpoint/Controllers/V1/GroupController.cs new file mode 100644 index 0000000..970bc66 --- /dev/null +++ b/Endpoint/Controllers/V1/GroupController.cs @@ -0,0 +1,68 @@ +using MediatR; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Mirea.Api.DataAccess.Application.Cqrs.Group.Queries.GetGroupDetails; +using Mirea.Api.DataAccess.Application.Cqrs.Group.Queries.GetGroupList; +using Mirea.Api.Dto.Responses; +using Mirea.Api.Endpoint.Common.Attributes; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Mirea.Api.Endpoint.Controllers.V1 +{ + public class GroupController(IMediator mediator) : BaseControllerV1 + { + /// + /// Retrieves a list of groups. + /// + /// The page number for pagination (optional). + /// The page size for pagination (optional). + /// A list of groups. + [HttpGet] + [ProducesResponseType(StatusCodes.Status200OK)] + [BadRequestResponse] + public async Task>> Get([FromQuery] int? page, [FromQuery] int? pageSize) + { + var result = await mediator.Send(new GetGroupListQuery() + { + Page = page, + PageSize = pageSize + }); + + return Ok(result.Groups + .Select(g => new GroupResponse() + { + Id = g.Id, + Name = g.Name, + FacultyId = g.FacultyId + }) + ); + } + + /// + /// Retrieves detailed information about a specific group. + /// + /// The ID of the group to retrieve. + /// Detailed information about the group. + [HttpGet("{id:int}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [BadRequestResponse] + [NotFoundResponse] + public async Task> GetDetails(int id) + { + var result = await mediator.Send(new GetGroupInfoQuery() + { + Id = id + }); + + return Ok(new GroupDetailsResponse() + { + Id = result.Id, + Name = result.Name, + FacultyId = result.FacultyId, + FacultyName = result.Faculty + }); + } + } +} -- 2.43.0 From 5cfc07ab7d929b5c659e3f536b56d35dfb2a6773 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Fri, 16 Feb 2024 23:57:22 +0300 Subject: [PATCH 19/30] feat: add controller for professor --- .../Controllers/V1/ProfessorController.cs | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 Endpoint/Controllers/V1/ProfessorController.cs diff --git a/Endpoint/Controllers/V1/ProfessorController.cs b/Endpoint/Controllers/V1/ProfessorController.cs new file mode 100644 index 0000000..5a9053a --- /dev/null +++ b/Endpoint/Controllers/V1/ProfessorController.cs @@ -0,0 +1,66 @@ +using MediatR; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Mirea.Api.DataAccess.Application.Cqrs.Professor.Queries.GetProfessorDetails; +using Mirea.Api.DataAccess.Application.Cqrs.Professor.Queries.GetProfessorList; +using Mirea.Api.Dto.Responses; +using Mirea.Api.Endpoint.Common.Attributes; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Mirea.Api.Endpoint.Controllers.V1; + +public class ProfessorController(IMediator mediator) : BaseControllerV1 +{ + /// + /// Retrieves a list of professors. + /// + /// The page number for pagination (optional). + /// The page size for pagination (optional). + /// A list of professors. + [HttpGet] + [ProducesResponseType(StatusCodes.Status200OK)] + [BadRequestResponse] + public async Task>> Get([FromQuery] int? page, [FromQuery] int? pageSize) + { + var result = await mediator.Send(new GetProfessorListQuery() + { + Page = page, + PageSize = pageSize + }); + + return Ok(result.Professors + .Select(p => new ProfessorResponse() + { + Id = p.Id, + Name = p.Name, + AltName = p.AltName + }) + ); + } + + /// + /// Retrieves detailed information about a specific professor. + /// + /// The ID of the professor to retrieve. + /// Detailed information about the professor. + [HttpGet("{id:int}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [BadRequestResponse] + [NotFoundResponse] + public async Task> GetDetails(int id) + { + var result = await mediator.Send(new GetProfessorInfoQuery() + { + Id = id + }); + + return Ok(new ProfessorResponse() + { + Id = result.Id, + Name = result.Name, + AltName = result.AltName + }); + } +} \ No newline at end of file -- 2.43.0 From 84872a5d6d0c100445ba69ccf2d22c1d3d85828c Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Sat, 17 Feb 2024 01:49:37 +0300 Subject: [PATCH 20/30] feat: add course information --- ApiDto/Responses/GroupDetailsResponse.cs | 5 +++++ ApiDto/Responses/GroupResponse.cs | 5 +++++ Endpoint/Controllers/V1/GroupController.cs | 20 ++++++++++++++++++-- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/ApiDto/Responses/GroupDetailsResponse.cs b/ApiDto/Responses/GroupDetailsResponse.cs index 35c665b..d4f5cae 100644 --- a/ApiDto/Responses/GroupDetailsResponse.cs +++ b/ApiDto/Responses/GroupDetailsResponse.cs @@ -15,6 +15,11 @@ public class GroupDetailsResponse /// public required string Name { get; set; } + /// + /// Gets or sets the course number of the group. + /// + public int CourseNumber { get; set; } + /// /// Gets or sets the unique identifier of the faculty to which the group belongs (optional). /// diff --git a/ApiDto/Responses/GroupResponse.cs b/ApiDto/Responses/GroupResponse.cs index 4526e72..63b91b3 100644 --- a/ApiDto/Responses/GroupResponse.cs +++ b/ApiDto/Responses/GroupResponse.cs @@ -15,6 +15,11 @@ public class GroupResponse /// public required string Name { get; set; } + /// + /// Gets or sets the course number of the group. + /// + public int CourseNumber { get; set; } + /// /// Gets or sets the unique identifier of the faculty to which the group belongs (optional). /// diff --git a/Endpoint/Controllers/V1/GroupController.cs b/Endpoint/Controllers/V1/GroupController.cs index 970bc66..3dc7966 100644 --- a/Endpoint/Controllers/V1/GroupController.cs +++ b/Endpoint/Controllers/V1/GroupController.cs @@ -5,6 +5,7 @@ using Mirea.Api.DataAccess.Application.Cqrs.Group.Queries.GetGroupDetails; using Mirea.Api.DataAccess.Application.Cqrs.Group.Queries.GetGroupList; using Mirea.Api.Dto.Responses; using Mirea.Api.Endpoint.Common.Attributes; +using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -13,6 +14,19 @@ namespace Mirea.Api.Endpoint.Controllers.V1 { public class GroupController(IMediator mediator) : BaseControllerV1 { + private static int GetCourseNumber(string groupName) + { + var current = DateTime.Now; + if (!int.TryParse(groupName[2..], out var yearOfGroup) + && !int.TryParse(groupName.Split('-')[^1][..2], out yearOfGroup)) + return -1; + + // Convert a two-digit year to a four-digit one + yearOfGroup += current.Year / 100 * 100; + + return current.Year - yearOfGroup + (current.Month < 9 ? 0 : 1); + } + /// /// Retrieves a list of groups. /// @@ -35,7 +49,8 @@ namespace Mirea.Api.Endpoint.Controllers.V1 { Id = g.Id, Name = g.Name, - FacultyId = g.FacultyId + FacultyId = g.FacultyId, + CourseNumber = GetCourseNumber(g.Name) }) ); } @@ -61,7 +76,8 @@ namespace Mirea.Api.Endpoint.Controllers.V1 Id = result.Id, Name = result.Name, FacultyId = result.FacultyId, - FacultyName = result.Faculty + FacultyName = result.Faculty, + CourseNumber = GetCourseNumber(result.Name) }); } } -- 2.43.0 From 6396d8a318a454aa6283385b37cd8b9b1744e462 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Sat, 17 Feb 2024 09:07:47 +0300 Subject: [PATCH 21/30] refactor: add an understanding of nullable for swagger gen --- ApiDto/Responses/CampusBasicInfoResponse.cs | 6 +++++- ApiDto/Responses/CampusDetailsResponse.cs | 6 +++++- ApiDto/Responses/DisciplineResponse.cs | 6 +++++- ApiDto/Responses/ErrorResponse.cs | 6 +++++- ApiDto/Responses/FacultyDetailsResponse.cs | 6 +++++- ApiDto/Responses/FacultyResponse.cs | 6 +++++- ApiDto/Responses/GroupDetailsResponse.cs | 7 ++++++- ApiDto/Responses/GroupResponse.cs | 7 ++++++- ApiDto/Responses/ProfessorResponse.cs | 6 +++++- 9 files changed, 47 insertions(+), 9 deletions(-) diff --git a/ApiDto/Responses/CampusBasicInfoResponse.cs b/ApiDto/Responses/CampusBasicInfoResponse.cs index 0232050..4ad46a7 100644 --- a/ApiDto/Responses/CampusBasicInfoResponse.cs +++ b/ApiDto/Responses/CampusBasicInfoResponse.cs @@ -1,4 +1,6 @@ -namespace Mirea.Api.Dto.Responses; +using System.ComponentModel.DataAnnotations; + +namespace Mirea.Api.Dto.Responses; /// /// Represents basic information about a campus. @@ -8,11 +10,13 @@ public class CampusBasicInfoResponse /// /// Gets or sets the unique identifier of the campus. /// + [Required] public int Id { get; set; } /// /// Gets or sets the code name of the campus. /// + [Required] public required string CodeName { get; set; } /// diff --git a/ApiDto/Responses/CampusDetailsResponse.cs b/ApiDto/Responses/CampusDetailsResponse.cs index 7caff6b..82db94e 100644 --- a/ApiDto/Responses/CampusDetailsResponse.cs +++ b/ApiDto/Responses/CampusDetailsResponse.cs @@ -1,4 +1,6 @@ -namespace Mirea.Api.Dto.Responses; +using System.ComponentModel.DataAnnotations; + +namespace Mirea.Api.Dto.Responses; /// /// Represents detailed information about a campus. @@ -8,11 +10,13 @@ public class CampusDetailsResponse /// /// Gets or sets the unique identifier of the campus. /// + [Required] public int Id { get; set; } /// /// Gets or sets the code name of the campus. /// + [Required] public required string CodeName { get; set; } /// diff --git a/ApiDto/Responses/DisciplineResponse.cs b/ApiDto/Responses/DisciplineResponse.cs index d98b723..9b35e13 100644 --- a/ApiDto/Responses/DisciplineResponse.cs +++ b/ApiDto/Responses/DisciplineResponse.cs @@ -1,4 +1,6 @@ -namespace Mirea.Api.Dto.Responses; +using System.ComponentModel.DataAnnotations; + +namespace Mirea.Api.Dto.Responses; /// /// Represents information about a discipline. @@ -8,10 +10,12 @@ public class DisciplineResponse /// /// Gets or sets the unique identifier of the discipline. /// + [Required] public int Id { get; set; } /// /// Gets or sets the name of the discipline. /// + [Required] public required string Name { get; set; } } \ No newline at end of file diff --git a/ApiDto/Responses/ErrorResponse.cs b/ApiDto/Responses/ErrorResponse.cs index b67377c..f0dc33c 100644 --- a/ApiDto/Responses/ErrorResponse.cs +++ b/ApiDto/Responses/ErrorResponse.cs @@ -1,4 +1,6 @@ -namespace Mirea.Api.Dto.Responses; +using System.ComponentModel.DataAnnotations; + +namespace Mirea.Api.Dto.Responses; /// /// A class for providing information about an error @@ -9,10 +11,12 @@ public class ErrorResponse /// The text or translation code of the error. This field may not contain information in specific scenarios. /// For example, it might be empty for HTTP 204 responses where no content is returned or if the validation texts have not been configured. /// + [Required] public required string Error { get; set; } /// /// In addition to returning the response code in the header, it is also duplicated in this field. /// Represents the HTTP response code. /// + [Required] public required int Code { get; set; } } \ No newline at end of file diff --git a/ApiDto/Responses/FacultyDetailsResponse.cs b/ApiDto/Responses/FacultyDetailsResponse.cs index ff86c47..09c863b 100644 --- a/ApiDto/Responses/FacultyDetailsResponse.cs +++ b/ApiDto/Responses/FacultyDetailsResponse.cs @@ -1,4 +1,6 @@ -namespace Mirea.Api.Dto.Responses; +using System.ComponentModel.DataAnnotations; + +namespace Mirea.Api.Dto.Responses; /// /// Represents detailed information about a faculty. @@ -8,11 +10,13 @@ public class FacultyDetailsResponse /// /// Gets or sets the unique identifier of the faculty. /// + [Required] public int Id { get; set; } /// /// Gets or sets the name of the faculty. /// + [Required] public required string Name { get; set; } /// diff --git a/ApiDto/Responses/FacultyResponse.cs b/ApiDto/Responses/FacultyResponse.cs index 136655d..adcf127 100644 --- a/ApiDto/Responses/FacultyResponse.cs +++ b/ApiDto/Responses/FacultyResponse.cs @@ -1,4 +1,6 @@ -namespace Mirea.Api.Dto.Responses; +using System.ComponentModel.DataAnnotations; + +namespace Mirea.Api.Dto.Responses; /// /// Represents basic information about a faculty. @@ -8,11 +10,13 @@ public class FacultyResponse /// /// Gets or sets the unique identifier of the faculty. /// + [Required] public int Id { get; set; } /// /// Gets or sets the name of the faculty. /// + [Required] public required string Name { get; set; } /// diff --git a/ApiDto/Responses/GroupDetailsResponse.cs b/ApiDto/Responses/GroupDetailsResponse.cs index d4f5cae..44670fe 100644 --- a/ApiDto/Responses/GroupDetailsResponse.cs +++ b/ApiDto/Responses/GroupDetailsResponse.cs @@ -1,4 +1,6 @@ -namespace Mirea.Api.Dto.Responses; +using System.ComponentModel.DataAnnotations; + +namespace Mirea.Api.Dto.Responses; /// /// Represents detailed information about a group. @@ -8,16 +10,19 @@ public class GroupDetailsResponse /// /// Gets or sets the unique identifier of the group. /// + [Required] public int Id { get; set; } /// /// Gets or sets the name of the group. /// + [Required] public required string Name { get; set; } /// /// Gets or sets the course number of the group. /// + [Required] public int CourseNumber { get; set; } /// diff --git a/ApiDto/Responses/GroupResponse.cs b/ApiDto/Responses/GroupResponse.cs index 63b91b3..0177459 100644 --- a/ApiDto/Responses/GroupResponse.cs +++ b/ApiDto/Responses/GroupResponse.cs @@ -1,4 +1,6 @@ -namespace Mirea.Api.Dto.Responses; +using System.ComponentModel.DataAnnotations; + +namespace Mirea.Api.Dto.Responses; /// /// Represents basic information about a group. @@ -8,16 +10,19 @@ public class GroupResponse /// /// Gets or sets the unique identifier of the group. /// + [Required] public int Id { get; set; } /// /// Gets or sets the name of the group. /// + [Required] public required string Name { get; set; } /// /// Gets or sets the course number of the group. /// + [Required] public int CourseNumber { get; set; } /// diff --git a/ApiDto/Responses/ProfessorResponse.cs b/ApiDto/Responses/ProfessorResponse.cs index 3a7b761..02361f9 100644 --- a/ApiDto/Responses/ProfessorResponse.cs +++ b/ApiDto/Responses/ProfessorResponse.cs @@ -1,4 +1,6 @@ -namespace Mirea.Api.Dto.Responses; +using System.ComponentModel.DataAnnotations; + +namespace Mirea.Api.Dto.Responses; /// /// Represents information about a professor. @@ -8,11 +10,13 @@ public class ProfessorResponse /// /// Gets or sets the unique identifier of the professor. /// + [Required] public int Id { get; set; } /// /// Gets or sets the name of the professor. /// + [Required] public required string Name { get; set; } /// -- 2.43.0 From 2b4065bbdf7d60e80567067af87d6d11817c5526 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Sat, 17 Feb 2024 09:09:18 +0300 Subject: [PATCH 22/30] fix: error CS0234 --- Endpoint/Controllers/V1/CampusController.cs | 2 +- Endpoint/Controllers/V1/FacultyController.cs | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Endpoint/Controllers/V1/CampusController.cs b/Endpoint/Controllers/V1/CampusController.cs index 4ee93c8..ae83834 100644 --- a/Endpoint/Controllers/V1/CampusController.cs +++ b/Endpoint/Controllers/V1/CampusController.cs @@ -19,7 +19,7 @@ namespace Mirea.Api.Endpoint.Controllers.V1 /// Basic information about campuses. [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetBasicInfo() + public async Task>> Get() { var result = await mediator.Send(new GetCampusBasicInfoListQuery()); diff --git a/Endpoint/Controllers/V1/FacultyController.cs b/Endpoint/Controllers/V1/FacultyController.cs index fe0190d..745e673 100644 --- a/Endpoint/Controllers/V1/FacultyController.cs +++ b/Endpoint/Controllers/V1/FacultyController.cs @@ -23,9 +23,7 @@ namespace Mirea.Api.Endpoint.Controllers.V1 [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] [BadRequestResponse] - public async Task>> Get( - [SwaggerDefault("0")][SwaggerSchema(Nullable = true)][FromQuery] int? page, - [SwaggerDefault("25")][SwaggerSchema(Nullable = true)][FromQuery] int? pageSize) + public async Task>> Get([FromQuery] int? page, [FromQuery] int? pageSize) { var result = await mediator.Send(new GetFacultyListQuery() { @@ -52,8 +50,7 @@ namespace Mirea.Api.Endpoint.Controllers.V1 [ProducesResponseType(StatusCodes.Status200OK)] [BadRequestResponse] [NotFoundResponse] - public async Task> GetDetails( - [SwaggerDefault("1")] int id) + public async Task> GetDetails(int id) { var result = await mediator.Send(new GetFacultyInfoQuery() { -- 2.43.0 From 477cec2f98415793797e6cdff65fa8dc89b73350 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Sat, 17 Feb 2024 10:58:25 +0300 Subject: [PATCH 23/30] fix: error CS0234 --- Endpoint/Controllers/V1/FacultyController.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Endpoint/Controllers/V1/FacultyController.cs b/Endpoint/Controllers/V1/FacultyController.cs index 745e673..3b4cd61 100644 --- a/Endpoint/Controllers/V1/FacultyController.cs +++ b/Endpoint/Controllers/V1/FacultyController.cs @@ -5,7 +5,6 @@ using Mirea.Api.DataAccess.Application.Cqrs.Faculty.Queries.GetFacultyDetails; using Mirea.Api.DataAccess.Application.Cqrs.Faculty.Queries.GetFacultyList; using Mirea.Api.Dto.Responses; using Mirea.Api.Endpoint.Common.Attributes; -using Swashbuckle.AspNetCore.Annotations; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -- 2.43.0 From 59eccf8b93fbad16f33fa97ec03107871bad2068 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Sat, 17 Feb 2024 14:21:52 +0300 Subject: [PATCH 24/30] feat: add model for lecture hall --- .../Responses/LectureHallDetailsResponse.cs | 37 +++++++++++++++++++ ApiDto/Responses/LectureHallResponse.cs | 27 ++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 ApiDto/Responses/LectureHallDetailsResponse.cs create mode 100644 ApiDto/Responses/LectureHallResponse.cs diff --git a/ApiDto/Responses/LectureHallDetailsResponse.cs b/ApiDto/Responses/LectureHallDetailsResponse.cs new file mode 100644 index 0000000..67b1a66 --- /dev/null +++ b/ApiDto/Responses/LectureHallDetailsResponse.cs @@ -0,0 +1,37 @@ +using System.ComponentModel.DataAnnotations; + +namespace Mirea.Api.Dto.Responses; + +/// +/// Represents the detailed response model for a lecture hall. +/// +public class LectureHallDetailsResponse +{ + /// + /// Gets or sets the ID of the lecture hall. + /// + [Required] + public int Id { get; set; } + + /// + /// Gets or sets the name of the lecture hall. + /// + [Required] + public required string Name { get; set; } + + /// + /// Gets or sets the ID of the campus to which the lecture hall belongs. + /// + [Required] + public int CampusId { get; set; } + + /// + /// Gets or sets the name of the campus. + /// + public string? CampusName { get; set; } + + /// + /// Gets or sets the code of the campus. + /// + public string? CampusCode { get; set; } +} \ No newline at end of file diff --git a/ApiDto/Responses/LectureHallResponse.cs b/ApiDto/Responses/LectureHallResponse.cs new file mode 100644 index 0000000..6bb288f --- /dev/null +++ b/ApiDto/Responses/LectureHallResponse.cs @@ -0,0 +1,27 @@ +using System.ComponentModel.DataAnnotations; + +namespace Mirea.Api.Dto.Responses; + +/// +/// Represents the response model for a lecture hall. +/// +public class LectureHallResponse +{ + /// + /// Gets or sets the ID of the lecture hall. + /// + [Required] + public int Id { get; set; } + + /// + /// Gets or sets the name of the lecture hall. + /// + [Required] + public required string Name { get; set; } + + /// + /// Gets or sets the ID of the campus to which the lecture hall belongs. + /// + [Required] + public int CampusId { get; set; } +} \ No newline at end of file -- 2.43.0 From e3d74c373e741764552cd2064dcbcdd208eaabc4 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Sat, 17 Feb 2024 14:22:29 +0300 Subject: [PATCH 25/30] feat: add controller for lecture hall --- .../Controllers/V1/LectureHallController.cs | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 Endpoint/Controllers/V1/LectureHallController.cs diff --git a/Endpoint/Controllers/V1/LectureHallController.cs b/Endpoint/Controllers/V1/LectureHallController.cs new file mode 100644 index 0000000..4ccede5 --- /dev/null +++ b/Endpoint/Controllers/V1/LectureHallController.cs @@ -0,0 +1,63 @@ +using MediatR; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Mirea.Api.DataAccess.Application.Cqrs.LectureHall.Queries.GetLectureHallDetails; +using Mirea.Api.DataAccess.Application.Cqrs.LectureHall.Queries.GetLectureHallList; +using Mirea.Api.DataAccess.Persistence; +using Mirea.Api.Dto.Responses; +using Mirea.Api.Endpoint.Common.Attributes; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Mirea.Api.Endpoint.Controllers.V1 +{ + public class LectureHallController(IMediator mediator, UberDbContext dbContext) : BaseControllerV1 + { + /// + /// Retrieves a list of all lecture halls. + /// + /// A list of lecture halls. + [HttpGet] + [ProducesResponseType(StatusCodes.Status200OK)] + public async Task>> Get() + { + var result = await mediator.Send(new GetLectureHallListQuery()); + + return Ok(result.LectureHalls + .Select(l => new LectureHallResponse() + { + Id = l.Id, + Name = l.Name, + CampusId = l.CampusId + }) + ); + } + + /// + /// Retrieves details of a specific lecture hall by its ID. + /// + /// The ID of the lecture hall to retrieve. + /// The details of the specified lecture hall. + [HttpGet("{id:int}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [BadRequestResponse] + [NotFoundResponse] + public async Task> GetDetails(int id) + { + var result = await mediator.Send(new GetLectureHallInfoQuery() + { + Id = id + }); + + return Ok(new LectureHallDetailsResponse() + { + Id = result.Id, + Name = result.Name, + CampusId = result.CampusId, + CampusCode = result.CampusCode, + CampusName = result.CampusName + }); + } + } +} -- 2.43.0 From e3e7c4550f08ea73fb7952c76783c2598ae36a53 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Mon, 19 Feb 2024 10:06:44 +0300 Subject: [PATCH 26/30] feat: add a query to get schedule data --- .../GetScheduleList/GetScheduleListQuery.cs | 12 +++ .../GetScheduleListQueryHandler.cs | 85 +++++++++++++++++++ .../Queries/GetScheduleList/ScheduleListVm.cs | 14 +++ .../GetScheduleList/ScheduleLookupDto.cs | 80 +++++++++++++++++ 4 files changed, 191 insertions(+) create mode 100644 Application/Cqrs/Schedule/Queries/GetScheduleList/GetScheduleListQuery.cs create mode 100644 Application/Cqrs/Schedule/Queries/GetScheduleList/GetScheduleListQueryHandler.cs create mode 100644 Application/Cqrs/Schedule/Queries/GetScheduleList/ScheduleListVm.cs create mode 100644 Application/Cqrs/Schedule/Queries/GetScheduleList/ScheduleLookupDto.cs diff --git a/Application/Cqrs/Schedule/Queries/GetScheduleList/GetScheduleListQuery.cs b/Application/Cqrs/Schedule/Queries/GetScheduleList/GetScheduleListQuery.cs new file mode 100644 index 0000000..939e1c6 --- /dev/null +++ b/Application/Cqrs/Schedule/Queries/GetScheduleList/GetScheduleListQuery.cs @@ -0,0 +1,12 @@ +using MediatR; + +namespace Mirea.Api.DataAccess.Application.Cqrs.Schedule.Queries.GetScheduleList; + +public class GetScheduleListQuery : IRequest +{ + public int[]? GroupIds { get; set; } + public int[]? DisciplineIds { get; set; } + public int[]? LectureHallIds { get; set; } + public int[]? ProfessorIds { get; set; } + public bool? IsEven { get; set; } +} \ No newline at end of file diff --git a/Application/Cqrs/Schedule/Queries/GetScheduleList/GetScheduleListQueryHandler.cs b/Application/Cqrs/Schedule/Queries/GetScheduleList/GetScheduleListQueryHandler.cs new file mode 100644 index 0000000..76993c1 --- /dev/null +++ b/Application/Cqrs/Schedule/Queries/GetScheduleList/GetScheduleListQueryHandler.cs @@ -0,0 +1,85 @@ +using MediatR; +using Microsoft.EntityFrameworkCore; +using Mirea.Api.DataAccess.Application.Interfaces.DbContexts.Schedule; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Mirea.Api.DataAccess.Application.Cqrs.Schedule.Queries.GetScheduleList; + +public class GetScheduleListQueryHandler(ILessonDbContext dbContext) : IRequestHandler +{ + public async Task Handle(GetScheduleListQuery request, CancellationToken cancellationToken) + { + var query = dbContext.Lessons.Include(l => l.LessonAssociations) + .ThenInclude(la => la.LectureHall) + .ThenInclude(lh => lh!.Campus) + .Include(l => l.LessonAssociations) + .ThenInclude(la => la.Professor) + .Include(l => l.Group) + .Include(l => l.TypeOfOccupation) + .Include(l => l.Discipline) + .AsQueryable(); + + if (request.IsEven != null) + query = query.Where(l => l.IsEven == request.IsEven); + + if (request.GroupIds != null && request.GroupIds.Length != 0) + query = query.Where(l => request.GroupIds.Contains(l.GroupId)); + + if (request.DisciplineIds != null && request.DisciplineIds.Length != 0) + query = query.Where(l => request.DisciplineIds.Contains(l.DisciplineId)); + + if (request.LectureHallIds != null && request.LectureHallIds.Length != 0) + query = query.Where(l => l.LessonAssociations!.Any(la => + la.LectureHallId != null && request.LectureHallIds.Contains(la.LectureHallId.Value))); + + if (request.ProfessorIds != null && request.ProfessorIds.Length != 0) + query = query.Where(l => + l.LessonAssociations!.Any(la => + la.ProfessorId != null && request.ProfessorIds.Contains(la.ProfessorId.Value))); + + var data = await query.ToArrayAsync(cancellationToken); + + var result = data.Select(l => new ScheduleLookupDto() + { + DayOfWeek = l.DayOfWeek, + PairNumber = l.PairNumber, + IsEven = l.IsEven, + Discipline = l.Discipline!.Name, + TypeOfOccupation = l.TypeOfOccupation!.ShortName, + + Group = l.Group!.Name, + GroupId = l.GroupId, + + LectureHalls = l.LessonAssociations! + .Where(la => !string.IsNullOrEmpty(la.LectureHall?.Name)) + .Select(la => la.LectureHall?.Name), + LectureHallsId = l.LessonAssociations! + .Where(la => la.LectureHallId != null) + .Select(la => la.LectureHallId), + + Campus = l.LessonAssociations! + .Where(la => !string.IsNullOrEmpty(la.LectureHall?.Campus?.CodeName)) + .Select(la => la.LectureHall?.Campus?.CodeName), + CampusId = l.LessonAssociations! + .Where(la => la.LectureHall?.Campus != null) + .Select(la => la.LectureHall?.CampusId), + + + Professors = l.LessonAssociations! + .Where(la => !string.IsNullOrEmpty(la.Professor?.Name)) + .Select(la => la.Professor?.Name), + ProfessorsId = l.LessonAssociations! + .Where(la => la.ProfessorId != null) + .Select(la => la.ProfessorId), + + LinkToMeet = l.LessonAssociations!.Select(la => la.LinkToMeet) + }).ToList(); + + return new ScheduleListVm + { + Schedules = result + }; + } +} \ No newline at end of file diff --git a/Application/Cqrs/Schedule/Queries/GetScheduleList/ScheduleListVm.cs b/Application/Cqrs/Schedule/Queries/GetScheduleList/ScheduleListVm.cs new file mode 100644 index 0000000..565e5b9 --- /dev/null +++ b/Application/Cqrs/Schedule/Queries/GetScheduleList/ScheduleListVm.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; + +namespace Mirea.Api.DataAccess.Application.Cqrs.Schedule.Queries.GetScheduleList; + +/// +/// Represents a view model for a list of schedules. +/// +public class ScheduleListVm +{ + /// + /// Gets or sets the list of schedules. + /// + public IList Schedules { get; set; } = new List(); +} \ No newline at end of file diff --git a/Application/Cqrs/Schedule/Queries/GetScheduleList/ScheduleLookupDto.cs b/Application/Cqrs/Schedule/Queries/GetScheduleList/ScheduleLookupDto.cs new file mode 100644 index 0000000..028a190 --- /dev/null +++ b/Application/Cqrs/Schedule/Queries/GetScheduleList/ScheduleLookupDto.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; + +namespace Mirea.Api.DataAccess.Application.Cqrs.Schedule.Queries.GetScheduleList; + +/// +/// Represents a data transfer object for schedule lookup. +/// +public class ScheduleLookupDto +{ + /// + /// Gets or sets the day of the week. + /// + public DayOfWeek DayOfWeek { get; set; } + + /// + /// Gets or sets the pair number. + /// + public int PairNumber { get; set; } + + /// + /// Gets or sets a value indicating whether the pair is on an even week. + /// + public bool IsEven { get; set; } + + /// + /// Gets or sets the name of the discipline. + /// + public required string Discipline { get; set; } + + /// + /// Gets or sets the type of occupation. + /// + public required string TypeOfOccupation { get; set; } + + /// + /// Gets or sets the name of the group. + /// + public required string Group { get; set; } + + /// + /// Gets or sets the ID of the group. + /// + public required int GroupId { get; set; } + + /// + /// Gets or sets the names of the lecture halls. + /// + public required IEnumerable LectureHalls { get; set; } + + /// + /// Gets or sets the IDs of the lecture halls. + /// + public required IEnumerable LectureHallsId { get; set; } + + /// + /// Gets or sets the names of the professors. + /// + public required IEnumerable Professors { get; set; } + + /// + /// Gets or sets the IDs of the professors. + /// + public required IEnumerable ProfessorsId { get; set; } + + /// + /// Gets or sets the names of the campuses. + /// + public required IEnumerable Campus { get; set; } + + /// + /// Gets or sets the IDs of the campuses. + /// + public required IEnumerable CampusId { get; set; } + + /// + /// Gets or sets the links to online meetings. + /// + public required IEnumerable LinkToMeet { get; set; } +} \ No newline at end of file -- 2.43.0 From 29485368f88374900e3d45a7c9c1b24ece2304f1 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Mon, 19 Feb 2024 11:20:05 +0300 Subject: [PATCH 27/30] fix: add discipline id --- .../Queries/GetScheduleList/GetScheduleListQueryHandler.cs | 4 +++- .../Schedule/Queries/GetScheduleList/ScheduleLookupDto.cs | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Application/Cqrs/Schedule/Queries/GetScheduleList/GetScheduleListQueryHandler.cs b/Application/Cqrs/Schedule/Queries/GetScheduleList/GetScheduleListQueryHandler.cs index 76993c1..ba08003 100644 --- a/Application/Cqrs/Schedule/Queries/GetScheduleList/GetScheduleListQueryHandler.cs +++ b/Application/Cqrs/Schedule/Queries/GetScheduleList/GetScheduleListQueryHandler.cs @@ -46,9 +46,11 @@ public class GetScheduleListQueryHandler(ILessonDbContext dbContext) : IRequestH DayOfWeek = l.DayOfWeek, PairNumber = l.PairNumber, IsEven = l.IsEven, - Discipline = l.Discipline!.Name, TypeOfOccupation = l.TypeOfOccupation!.ShortName, + Discipline = l.Discipline!.Name, + DisciplineId = l.DisciplineId, + Group = l.Group!.Name, GroupId = l.GroupId, diff --git a/Application/Cqrs/Schedule/Queries/GetScheduleList/ScheduleLookupDto.cs b/Application/Cqrs/Schedule/Queries/GetScheduleList/ScheduleLookupDto.cs index 028a190..bd3808f 100644 --- a/Application/Cqrs/Schedule/Queries/GetScheduleList/ScheduleLookupDto.cs +++ b/Application/Cqrs/Schedule/Queries/GetScheduleList/ScheduleLookupDto.cs @@ -28,6 +28,11 @@ public class ScheduleLookupDto /// public required string Discipline { get; set; } + /// + /// Gets or sets the ID of the discipline. + /// + public required int DisciplineId { get; set; } + /// /// Gets or sets the type of occupation. /// -- 2.43.0 From ee2351b5ed4ff0fda6424aa07fd338c70b4cd492 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Mon, 19 Feb 2024 11:20:49 +0300 Subject: [PATCH 28/30] feat: add controller --- ApiDto/Requests/ScheduleRequest.cs | 37 +++ .../Schedule/DisciplineScheduleResponse.cs | 106 ++++++ .../Schedule/GroupScheduleResponse.cs | 106 ++++++ .../Schedule/LectureHallScheduleResponse.cs | 105 ++++++ .../Schedule/ProfessorScheduleResponse.cs | 108 +++++++ ApiDto/Responses/Schedule/ScheduleResponse.cs | 94 ++++++ Endpoint/Controllers/V1/ScheduleController.cs | 304 ++++++++++++++++++ 7 files changed, 860 insertions(+) create mode 100644 ApiDto/Requests/ScheduleRequest.cs create mode 100644 ApiDto/Responses/Schedule/DisciplineScheduleResponse.cs create mode 100644 ApiDto/Responses/Schedule/GroupScheduleResponse.cs create mode 100644 ApiDto/Responses/Schedule/LectureHallScheduleResponse.cs create mode 100644 ApiDto/Responses/Schedule/ProfessorScheduleResponse.cs create mode 100644 ApiDto/Responses/Schedule/ScheduleResponse.cs create mode 100644 Endpoint/Controllers/V1/ScheduleController.cs diff --git a/ApiDto/Requests/ScheduleRequest.cs b/ApiDto/Requests/ScheduleRequest.cs new file mode 100644 index 0000000..476d8f3 --- /dev/null +++ b/ApiDto/Requests/ScheduleRequest.cs @@ -0,0 +1,37 @@ +namespace Mirea.Api.Dto.Requests; + +/// +/// Represents a request object for retrieving schedules based on various filters. +/// +public class ScheduleRequest +{ + /// + /// Gets or sets an array of group IDs. + /// + /// This array can contain null values. + public int[]? Groups { get; set; } = null; + + /// + /// Gets or sets a value indicating whether to retrieve schedules for even weeks. + /// + /// This property can contain null. + public bool? IsEven { get; set; } = null; + + /// + /// Gets or sets an array of discipline IDs. + /// + /// This array can contain null values. + public int[]? Disciplines { get; set; } = null; + + /// + /// Gets or sets an array of professor IDs. + /// + /// This array can contain null values. + public int[]? Professors { get; set; } = null; + + /// + /// Gets or sets an array of lecture hall IDs. + /// + /// This array can contain null values. + public int[]? LectureHalls { get; set; } = null; +} diff --git a/ApiDto/Responses/Schedule/DisciplineScheduleResponse.cs b/ApiDto/Responses/Schedule/DisciplineScheduleResponse.cs new file mode 100644 index 0000000..bf4a337 --- /dev/null +++ b/ApiDto/Responses/Schedule/DisciplineScheduleResponse.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace Mirea.Api.Dto.Responses.Schedule; + +/// +/// Represents information about a specific schedule entry for a professor. +/// +public class DisciplineScheduleInfo +{ + /// + /// Gets or sets the day of the week for the schedule entry. + /// + [Required] + public DayOfWeek DayOfWeek { get; set; } + + /// + /// Gets or sets the pair number for the schedule entry. + /// + [Required] + public int PairNumber { get; set; } + + /// + /// Gets or sets a value indicating whether the pair is on an even week. + /// + [Required] + public bool IsEven { get; set; } + + /// + /// Gets or sets the type of occupation for the schedule entry. + /// + [Required] + public required string TypeOfOccupation { get; set; } + + /// + /// Gets or sets the names of the group for the schedule entry. + /// + [Required] + + public required string Group { get; set; } + /// + /// Gets or sets the IDs of the group for the schedule entry. + /// + [Required] + public required int GroupId { get; set; } + + /// + /// Gets or sets the names of the lecture halls for the schedule entry. + /// + public required IEnumerable LectureHalls { get; set; } + + /// + /// Gets or sets the IDs of the lecture halls for the schedule entry. + /// + public required IEnumerable LectureHallsId { get; set; } + + /// + /// Gets or sets the names of the professors for the schedule entry. + /// + public required IEnumerable Professors { get; set; } + + /// + /// Gets or sets the IDs of the professors for the schedule entry. + /// + public required IEnumerable ProfessorsId { get; set; } + + /// + /// Gets or sets the names of the campuses for the schedule entry. + /// + public required IEnumerable Campus { get; set; } + + /// + /// Gets or sets the IDs of the campuses for the schedule entry. + /// + public required IEnumerable CampusId { get; set; } + + /// + /// Gets or sets the links to online meetings for the schedule entry. + /// + public required IEnumerable LinkToMeet { get; set; } +} + +/// +/// Represents a response containing schedule information for a professor. +/// +public class DisciplineScheduleResponse +{ + /// + /// Gets or sets the name of the discipline. + /// + [Required] + public required string Discipline { get; set; } + + /// + /// Gets or sets the ID of the discipline. + /// + [Required] + public required int DisciplineId { get; set; } + + /// + /// Gets or sets the schedules for the professor. + /// + [Required] + public required IEnumerable Schedules { get; set; } +} diff --git a/ApiDto/Responses/Schedule/GroupScheduleResponse.cs b/ApiDto/Responses/Schedule/GroupScheduleResponse.cs new file mode 100644 index 0000000..7fa13d1 --- /dev/null +++ b/ApiDto/Responses/Schedule/GroupScheduleResponse.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace Mirea.Api.Dto.Responses.Schedule; + +/// +/// Represents information about a specific schedule entry for a group. +/// +public class GroupScheduleInfo +{ + /// + /// Gets or sets the day of the week for the schedule entry. + /// + [Required] + public DayOfWeek DayOfWeek { get; set; } + + /// + /// Gets or sets the pair number for the schedule entry. + /// + [Required] + public int PairNumber { get; set; } + + /// + /// Gets or sets a value indicating whether the pair is on an even week. + /// + [Required] + public bool IsEven { get; set; } + + /// + /// Gets or sets the name of the discipline for the schedule entry. + /// + [Required] + public required string Discipline { get; set; } + + /// + /// Gets or sets the ID of the discipline for the schedule entry. + /// + [Required] + public required int DisciplineId { get; set; } + + /// + /// Gets or sets the type of occupation for the schedule entry. + /// + [Required] + public required string TypeOfOccupation { get; set; } + + /// + /// Gets or sets the names of the lecture halls for the schedule entry. + /// + public required IEnumerable LectureHalls { get; set; } + + /// + /// Gets or sets the IDs of the lecture halls for the schedule entry. + /// + public required IEnumerable LectureHallsId { get; set; } + + /// + /// Gets or sets the names of the professors for the schedule entry. + /// + public required IEnumerable Professors { get; set; } + + /// + /// Gets or sets the IDs of the professors for the schedule entry. + /// + public required IEnumerable ProfessorsId { get; set; } + + /// + /// Gets or sets the names of the campuses for the schedule entry. + /// + public required IEnumerable Campus { get; set; } + + /// + /// Gets or sets the IDs of the campuses for the schedule entry. + /// + public required IEnumerable CampusId { get; set; } + + /// + /// Gets or sets the links to online meetings for the schedule entry. + /// + public required IEnumerable LinkToMeet { get; set; } +} + +/// +/// Represents a response containing schedule information for a group. +/// +public class GroupScheduleResponse +{ + /// + /// Gets or sets the name of the group. + /// + [Required] + public required string Group { get; set; } + + /// + /// Gets or sets the ID of the group. + /// + [Required] + public required int GroupId { get; set; } + + /// + /// Gets or sets the schedules for the group. + /// + [Required] + public required IEnumerable Schedules { get; set; } +} diff --git a/ApiDto/Responses/Schedule/LectureHallScheduleResponse.cs b/ApiDto/Responses/Schedule/LectureHallScheduleResponse.cs new file mode 100644 index 0000000..369a8f5 --- /dev/null +++ b/ApiDto/Responses/Schedule/LectureHallScheduleResponse.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace Mirea.Api.Dto.Responses.Schedule; + +/// +/// Represents information about a specific schedule entry for a lecture hall. +/// +public class LectureHallScheduleInfo +{ + /// + /// Gets or sets the day of the week for the schedule entry. + /// + [Required] + public DayOfWeek DayOfWeek { get; set; } + + /// + /// Gets or sets the pair number for the schedule entry. + /// + [Required] + public int PairNumber { get; set; } + + /// + /// Gets or sets a value indicating whether the pair is on an even week. + /// + [Required] + public bool IsEven { get; set; } + + /// + /// Gets or sets the name of the discipline for the schedule entry. + /// + [Required] + public required string Discipline { get; set; } + + /// + /// Gets or sets the ID of the discipline for the schedule entry. + /// + [Required] + public required int DisciplineId { get; set; } + + /// + /// Gets or sets the type of occupation for the schedule entry. + /// + [Required] + public required string TypeOfOccupation { get; set; } + + /// + /// Gets or sets the names of the group for the schedule entry. + /// + [Required] + public required string Group { get; set; } + /// + /// Gets or sets the IDs of the group for the schedule entry. + /// + [Required] + public required int GroupId { get; set; } + + /// + /// Gets or sets the names of the campuses for the schedule entry. + /// + public required IEnumerable Campus { get; set; } + + /// + /// Gets or sets the IDs of the campuses for the schedule entry. + /// + public required IEnumerable CampusId { get; set; } + + /// + /// Gets or sets the names of the professors for the schedule entry. + /// + public required IEnumerable Professors { get; set; } + + /// + /// Gets or sets the IDs of the professors for the schedule entry. + /// + public required IEnumerable ProfessorsId { get; set; } + + /// + /// Gets or sets the links to online meetings for the schedule entry. + /// + public required IEnumerable LinkToMeet { get; set; } +} + +/// +/// Represents a response containing schedule information for a lecture hall. +/// +public class LectureHallScheduleResponse +{ + /// + /// Gets or sets the names of the lecture halls. + /// + public required string LectureHalls { get; set; } + + /// + /// Gets or sets the IDs of the lecture halls. + /// + public required int LectureHallsId { get; set; } + + /// + /// Gets or sets the schedules for the lecture hall. + /// + [Required] + public required IEnumerable Schedules { get; set; } +} diff --git a/ApiDto/Responses/Schedule/ProfessorScheduleResponse.cs b/ApiDto/Responses/Schedule/ProfessorScheduleResponse.cs new file mode 100644 index 0000000..3a53ebf --- /dev/null +++ b/ApiDto/Responses/Schedule/ProfessorScheduleResponse.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace Mirea.Api.Dto.Responses.Schedule; + +/// +/// Represents information about a specific schedule entry for a professor. +/// +public class ProfessorScheduleInfo +{ + /// + /// Gets or sets the day of the week for the schedule entry. + /// + [Required] + public DayOfWeek DayOfWeek { get; set; } + + /// + /// Gets or sets the pair number for the schedule entry. + /// + [Required] + public int PairNumber { get; set; } + + /// + /// Gets or sets a value indicating whether the pair is on an even week. + /// + [Required] + public bool IsEven { get; set; } + + /// + /// Gets or sets the name of the discipline for the schedule entry. + /// + [Required] + public required string Discipline { get; set; } + + /// + /// Gets or sets the ID of the discipline for the schedule entry. + /// + [Required] + public required int DisciplineId { get; set; } + + /// + /// Gets or sets the type of occupation for the schedule entry. + /// + [Required] + public required string TypeOfOccupation { get; set; } + + /// + /// Gets or sets the names of the group for the schedule entry. + /// + [Required] + + public required string Group { get; set; } + /// + /// Gets or sets the IDs of the group for the schedule entry. + /// + [Required] + public required int GroupId { get; set; } + + /// + /// Gets or sets the names of the lecture halls for the schedule entry. + /// + public required IEnumerable LectureHalls { get; set; } + + /// + /// Gets or sets the IDs of the lecture halls for the schedule entry. + /// + public required IEnumerable LectureHallsId { get; set; } + + /// + /// Gets or sets the names of the campuses for the schedule entry. + /// + public required IEnumerable Campus { get; set; } + + /// + /// Gets or sets the IDs of the campuses for the schedule entry. + /// + public required IEnumerable CampusId { get; set; } + + /// + /// Gets or sets the links to online meetings for the schedule entry. + /// + public required IEnumerable LinkToMeet { get; set; } +} + +/// +/// Represents a response containing schedule information for a professor. +/// +public class ProfessorScheduleResponse +{ + /// + /// Gets or sets the name of the professor. + /// + [Required] + public required string Professor { get; set; } + + /// + /// Gets or sets the ID of the professor. + /// + [Required] + public required int ProfessorId { get; set; } + + /// + /// Gets or sets the schedules for the professor. + /// + [Required] + public required IEnumerable Schedules { get; set; } +} diff --git a/ApiDto/Responses/Schedule/ScheduleResponse.cs b/ApiDto/Responses/Schedule/ScheduleResponse.cs new file mode 100644 index 0000000..2a03178 --- /dev/null +++ b/ApiDto/Responses/Schedule/ScheduleResponse.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace Mirea.Api.Dto.Responses.Schedule; + +/// +/// Represents a response object containing schedule information. +/// +public class ScheduleResponse +{ + /// + /// Gets or sets the day of the week for the schedule entry. + /// + [Required] + public DayOfWeek DayOfWeek { get; set; } + + /// + /// Gets or sets the pair number for the schedule entry. + /// + [Required] + public int PairNumber { get; set; } + + /// + /// Gets or sets a value indicating whether the pair is on an even week. + /// + [Required] + public bool IsEven { get; set; } + + /// + /// Gets or sets the name of the discipline for the schedule entry. + /// + [Required] + public required string Discipline { get; set; } + + /// + /// Gets or sets the ID of the discipline for the schedule entry. + /// + [Required] + public required int DisciplineId { get; set; } + + /// + /// Gets or sets the type of occupation for the schedule entry. + /// + [Required] + public required string TypeOfOccupation { get; set; } + + /// + /// Gets or sets the name of the group for the schedule entry. + /// + [Required] + public required string Group { get; set; } + + /// + /// Gets or sets the ID of the group for the schedule entry. + /// + [Required] + public required int GroupId { get; set; } + + /// + /// Gets or sets the names of the lecture halls for the schedule entry. + /// + public required IEnumerable LectureHalls { get; set; } + + /// + /// Gets or sets the IDs of the lecture halls for the schedule entry. + /// + public required IEnumerable LectureHallsId { get; set; } + + /// + /// Gets or sets the names of the professors for the schedule entry. + /// + public required IEnumerable Professors { get; set; } + + /// + /// Gets or sets the IDs of the professors for the schedule entry. + /// + public required IEnumerable ProfessorsId { get; set; } + + /// + /// Gets or sets the names of the campuses for the schedule entry. + /// + public required IEnumerable Campus { get; set; } + + /// + /// Gets or sets the IDs of the campuses for the schedule entry. + /// + public required IEnumerable CampusId { get; set; } + + /// + /// Gets or sets the links to online meetings for the schedule entry. + /// + public required IEnumerable LinkToMeet { get; set; } +} diff --git a/Endpoint/Controllers/V1/ScheduleController.cs b/Endpoint/Controllers/V1/ScheduleController.cs new file mode 100644 index 0000000..43b47ad --- /dev/null +++ b/Endpoint/Controllers/V1/ScheduleController.cs @@ -0,0 +1,304 @@ +using MediatR; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Mirea.Api.DataAccess.Application.Cqrs.Schedule.Queries.GetScheduleList; +using Mirea.Api.Dto.Requests; +using Mirea.Api.Dto.Responses; +using Mirea.Api.Dto.Responses.Schedule; +using Mirea.Api.Endpoint.Common.Attributes; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Mirea.Api.Endpoint.Controllers.V1; + +public class ScheduleController(IMediator mediator) : BaseControllerV1 +{ + /// + /// Retrieves schedules based on various filters. + /// + /// The request object containing filter criteria. + /// A list of schedules matching the filter criteria. + [HttpPost] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [BadRequestResponse] + [NotFoundResponse] + public async Task>> Get([FromBody] ScheduleRequest request) + + { + if ((request.Groups == null || !request.Groups.Any()) && + (request.Disciplines == null || !request.Disciplines.Any()) && + (request.Professors == null || !request.Professors.Any()) && + (request.LectureHalls == null || !request.LectureHalls.Any())) + { + return BadRequest(new ErrorResponse() + { + Error = "At least one of the arguments must be selected." + + (request.IsEven.HasValue + ? $" \"{nameof(request.IsEven)}\" is not a strong argument" + : string.Empty), + Code = StatusCodes.Status400BadRequest + }); + } + + var result = (await mediator.Send(new GetScheduleListQuery() + { + IsEven = request.IsEven, + DisciplineIds = request.Disciplines, + GroupIds = request.Groups, + LectureHallIds = request.LectureHalls, + ProfessorIds = request.Professors + })).Schedules; + + if (result.Count == 0) NoContent(); + + return Ok(result.Select(s => new ScheduleResponse() + { + DayOfWeek = s.DayOfWeek, + PairNumber = s.PairNumber, + IsEven = s.IsEven, + Discipline = s.Discipline, + DisciplineId = s.DisciplineId, + TypeOfOccupation = s.TypeOfOccupation, + Group = s.Group, + GroupId = s.GroupId, + LectureHalls = s.LectureHalls, + LectureHallsId = s.LectureHallsId, + Professors = s.Professors, + ProfessorsId = s.ProfessorsId, + Campus = s.Campus, + CampusId = s.CampusId, + LinkToMeet = s.LinkToMeet + })); + + } + + /// + /// Retrieves schedules for a specific group based on various filters. + /// + /// The ID of the group. + /// A value indicating whether to retrieve schedules for even weeks. + /// An array of discipline IDs. + /// An array of professor IDs. + /// An array of lecture hall IDs. + /// A response containing schedules for the specified group. + [HttpGet("{id:int}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [BadRequestResponse] + [NotFoundResponse] + public async Task> GetByGroup(int id, + [FromQuery] bool? isEven = null, + [FromQuery] int[]? disciplines = null, + [FromQuery] int[]? professors = null, + [FromQuery] int[]? lectureHalls = null) + + { + var result = (await mediator.Send(new GetScheduleListQuery() + { + IsEven = isEven, + DisciplineIds = disciplines, + GroupIds = [id], + LectureHallIds = lectureHalls, + ProfessorIds = professors + })).Schedules; + + if (result.Count == 0) NoContent(); + + return Ok(new GroupScheduleResponse() + { + Group = result[0].Group, + GroupId = result[0].GroupId, + Schedules = result.Select(g => new GroupScheduleInfo() + { + DayOfWeek = g.DayOfWeek, + PairNumber = g.PairNumber, + IsEven = g.IsEven, + Discipline = g.Discipline, + DisciplineId = g.DisciplineId, + TypeOfOccupation = g.TypeOfOccupation, + LectureHalls = g.LectureHalls, + LectureHallsId = g.LectureHallsId, + Professors = g.Professors, + ProfessorsId = g.ProfessorsId, + Campus = g.Campus, + CampusId = g.CampusId, + LinkToMeet = g.LinkToMeet + }) + }); + } + + /// + /// Retrieves schedules for a specific professor based on various filters. + /// + /// The ID of the professor. + /// A value indicating whether to retrieve schedules for even weeks. + /// An array of discipline IDs. + /// An array of group IDs. + /// An array of lecture hall IDs. + /// A response containing schedules for the specified professor. + [HttpGet("{id:int}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [BadRequestResponse] + [NotFoundResponse] + public async Task> GetByProfessor(int id, + [FromQuery] bool? isEven = null, + [FromQuery] int[]? disciplines = null, + [FromQuery] int[]? groups = null, + [FromQuery] int[]? lectureHalls = null) + + { + var result = (await mediator.Send(new GetScheduleListQuery() + { + IsEven = isEven, + DisciplineIds = disciplines, + GroupIds = groups, + LectureHallIds = lectureHalls, + ProfessorIds = [id] + })).Schedules; + + if (result.Count == 0) NoContent(); + + return Ok(new ProfessorScheduleResponse() + { + Professor = result.Select(professor => + professor.Professors.FirstOrDefault(x => !string.IsNullOrEmpty(x)) + ).First()!, + ProfessorId = result.Select(professor => + professor.ProfessorsId.FirstOrDefault(x => x != null) + ).First()!.Value, + Schedules = result.Select(p => new ProfessorScheduleInfo() + { + DayOfWeek = p.DayOfWeek, + PairNumber = p.PairNumber, + IsEven = p.IsEven, + Discipline = p.Discipline, + DisciplineId = p.DisciplineId, + TypeOfOccupation = p.TypeOfOccupation, + Group = p.Group, + GroupId = p.GroupId, + LectureHalls = p.LectureHalls, + LectureHallsId = p.LectureHallsId, + Campus = p.Campus, + CampusId = p.CampusId, + LinkToMeet = p.LinkToMeet + }) + }); + } + + /// + /// Retrieves schedules for a specific lecture hall based on various filters. + /// + /// The ID of the lecture hall. + /// A value indicating whether to retrieve schedules for even weeks. + /// An array of discipline IDs. + /// An array of professor IDs. + /// An array of group IDs. + /// A response containing schedules for the specified lecture hall. + [HttpGet("{id:int}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [BadRequestResponse] + [NotFoundResponse] + public async Task> GetByLectureHall(int id, + [FromQuery] bool? isEven = null, + [FromQuery] int[]? disciplines = null, + [FromQuery] int[]? groups = null, + [FromQuery] int[]? professors = null) + + { + var result = (await mediator.Send(new GetScheduleListQuery() + { + IsEven = isEven, + DisciplineIds = disciplines, + GroupIds = groups, + LectureHallIds = [id], + ProfessorIds = professors + })).Schedules; + + if (result.Count == 0) NoContent(); + + return Ok(new LectureHallScheduleResponse() + { + LectureHalls = result.Select(lectureHall => + lectureHall.LectureHalls.FirstOrDefault(x => !string.IsNullOrEmpty(x)) + ).First()!, + LectureHallsId = result.Select(lectureHall => + lectureHall.LectureHallsId.FirstOrDefault(x => x != null) + ).First()!.Value, + Schedules = result.Select(l => new LectureHallScheduleInfo() + { + DayOfWeek = l.DayOfWeek, + PairNumber = l.PairNumber, + IsEven = l.IsEven, + Discipline = l.Discipline, + DisciplineId = l.DisciplineId, + TypeOfOccupation = l.TypeOfOccupation, + Group = l.Group, + GroupId = l.GroupId, + Professors = l.Professors, + ProfessorsId = l.ProfessorsId, + Campus = l.Campus, + CampusId = l.CampusId, + LinkToMeet = l.LinkToMeet + }) + }); + } + + /// + /// Retrieves schedules for a specific discipline based on various filters. + /// + /// The ID of the discipline. + /// A value indicating whether to retrieve schedules for even weeks. + /// An array of group IDs. + /// An array of professor IDs. + /// An array of lecture hall IDs. + /// A response containing schedules for the specified discipline. + [HttpGet("{id:int}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [BadRequestResponse] + [NotFoundResponse] + public async Task> GetByDiscipline(int id, + [FromQuery] bool? isEven = null, + [FromQuery] int[]? groups = null, + [FromQuery] int[]? professors = null, + [FromQuery] int[]? lectureHalls = null) + + { + var result = (await mediator.Send(new GetScheduleListQuery() + { + IsEven = isEven, + DisciplineIds = [id], + GroupIds = groups, + LectureHallIds = [id], + ProfessorIds = professors + })).Schedules; + + if (result.Count == 0) NoContent(); + + return Ok(new DisciplineScheduleResponse() + { + Discipline = result[0].Discipline, + DisciplineId = result[0].DisciplineId, + Schedules = result.Select(d => new DisciplineScheduleInfo() + { + DayOfWeek = d.DayOfWeek, + PairNumber = d.PairNumber, + IsEven = d.IsEven, + TypeOfOccupation = d.TypeOfOccupation, + Group = d.Group, + GroupId = d.GroupId, + LectureHalls = d.LectureHalls, + LectureHallsId = d.LectureHallsId, + Professors = d.Professors, + ProfessorsId = d.ProfessorsId, + Campus = d.Campus, + CampusId = d.CampusId, + LinkToMeet = d.LinkToMeet + }) + }); + } +} \ No newline at end of file -- 2.43.0 From 5536162521b8831224505353892f026f99fb12d3 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Mon, 19 Feb 2024 12:02:37 +0300 Subject: [PATCH 29/30] feat: add get group by faculty id --- Endpoint/Controllers/V1/GroupController.cs | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Endpoint/Controllers/V1/GroupController.cs b/Endpoint/Controllers/V1/GroupController.cs index 3dc7966..cead029 100644 --- a/Endpoint/Controllers/V1/GroupController.cs +++ b/Endpoint/Controllers/V1/GroupController.cs @@ -80,5 +80,29 @@ namespace Mirea.Api.Endpoint.Controllers.V1 CourseNumber = GetCourseNumber(result.Name) }); } + + /// + /// Retrieves a list of groups by faculty ID. + /// + /// The ID of the faculty. + /// A list of groups belonging to the specified faculty. + [HttpGet("{id:int}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [BadRequestResponse] + [NotFoundResponse] + public async Task>> GetByFaculty(int id) + { + var result = await mediator.Send(new GetGroupListQuery()); + + return Ok(result.Groups + .Where(g => g.FacultyId == id) + .Select(g => new GroupResponse() + { + Id = g.Id, + Name = g.Name, + CourseNumber = GetCourseNumber(g.Name), + FacultyId = g.FacultyId + })); + } } } -- 2.43.0 From d02fb8becbb964e942b289ab712c0561c0e2c776 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Mon, 19 Feb 2024 12:03:10 +0300 Subject: [PATCH 30/30] feat: get lecture halls by campus --- .../Controllers/V1/LectureHallController.cs | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/Endpoint/Controllers/V1/LectureHallController.cs b/Endpoint/Controllers/V1/LectureHallController.cs index 4ccede5..de2f21f 100644 --- a/Endpoint/Controllers/V1/LectureHallController.cs +++ b/Endpoint/Controllers/V1/LectureHallController.cs @@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Mirea.Api.DataAccess.Application.Cqrs.LectureHall.Queries.GetLectureHallDetails; using Mirea.Api.DataAccess.Application.Cqrs.LectureHall.Queries.GetLectureHallList; -using Mirea.Api.DataAccess.Persistence; using Mirea.Api.Dto.Responses; using Mirea.Api.Endpoint.Common.Attributes; using System.Collections.Generic; @@ -12,7 +11,7 @@ using System.Threading.Tasks; namespace Mirea.Api.Endpoint.Controllers.V1 { - public class LectureHallController(IMediator mediator, UberDbContext dbContext) : BaseControllerV1 + public class LectureHallController(IMediator mediator) : BaseControllerV1 { /// /// Retrieves a list of all lecture halls. @@ -59,5 +58,27 @@ namespace Mirea.Api.Endpoint.Controllers.V1 CampusName = result.CampusName }); } + + /// + /// Retrieves a list of lecture halls by campus ID. + /// + /// The ID of the campus. + /// A list of lecture halls in the specified campus. + [HttpGet("{id:int}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [BadRequestResponse] + [NotFoundResponse] + public async Task>> GetByCampus(int id) + { + var result = await mediator.Send(new GetLectureHallListQuery()); + + return Ok(result.LectureHalls.Where(l => l.CampusId == id) + .Select(l => new LectureHallResponse() + { + Id = l.Id, + Name = l.Name, + CampusId = l.CampusId + })); + } } } -- 2.43.0