From 56b6fe87c5a48452dc7eeae6f68fdd86607e1ad6 Mon Sep 17 00:00:00 2001 From: maurobernal Date: Fri, 26 Apr 2024 21:08:07 -0300 Subject: [PATCH] feat:MB: crud for skills add methos for put, delete, get and getlist --- src/Application/Application.csproj | 4 - .../DeleteSkillComand/DeleteSkillsComands.cs | 29 +++ .../UpdateSkillComand/UpdateSkillComands.cs | 35 +++ .../UpdateSkillComand/UpdateSkillValidator.cs | 9 + .../GetListSkillsQueries.cs | 22 ++ .../GetSkillQueriesDTO.cs | 18 ++ .../Queries/GetSkillQueries/GetSkillDTO.cs | 16 ++ .../GetSkillQueries/GetSkillsQueries.cs | 29 +++ .../Common/Bases/PaginatedBaseDTO.cs | 6 + src/Web/Endpoints/Skills.cs | 53 ++++- src/Web/Web.csproj | 95 +++++---- src/Web/wwwroot/api/specification.json | 199 ++++++++++++++++++ 12 files changed, 461 insertions(+), 54 deletions(-) create mode 100644 src/Application/CQRS/Skills/Commands/DeleteSkillComand/DeleteSkillsComands.cs create mode 100644 src/Application/CQRS/Skills/Commands/UpdateSkillComand/UpdateSkillComands.cs create mode 100644 src/Application/CQRS/Skills/Commands/UpdateSkillComand/UpdateSkillValidator.cs create mode 100644 src/Application/CQRS/Skills/Queries/GetListSkillsQueries/GetListSkillsQueries.cs create mode 100644 src/Application/CQRS/Skills/Queries/GetListSkillsQueries/GetSkillQueriesDTO.cs create mode 100644 src/Application/CQRS/Skills/Queries/GetSkillQueries/GetSkillDTO.cs create mode 100644 src/Application/CQRS/Skills/Queries/GetSkillQueries/GetSkillsQueries.cs create mode 100644 src/Application/Common/Bases/PaginatedBaseDTO.cs diff --git a/src/Application/Application.csproj b/src/Application/Application.csproj index 4d0289b..2246a4d 100644 --- a/src/Application/Application.csproj +++ b/src/Application/Application.csproj @@ -17,10 +17,6 @@ - - - - diff --git a/src/Application/CQRS/Skills/Commands/DeleteSkillComand/DeleteSkillsComands.cs b/src/Application/CQRS/Skills/Commands/DeleteSkillComand/DeleteSkillsComands.cs new file mode 100644 index 0000000..d4e1a35 --- /dev/null +++ b/src/Application/CQRS/Skills/Commands/DeleteSkillComand/DeleteSkillsComands.cs @@ -0,0 +1,29 @@ + +using ca.Application.Common.Exceptions; +using ca.Application.Common.Interfaces; + +namespace ca.Application.CQRS.Skills.Commands.DeleteSkillComand; +public class DeleteSkillsComands : IRequest +{ + public int Id { get; set; } +} + + +public class DeleteSkillsHandler : IRequestHandler +{ + private readonly IApplicationDbContext _context; + + public DeleteSkillsHandler(IApplicationDbContext context) => _context = context; + + public async Task Handle(DeleteSkillsComands request, CancellationToken cancellationToken) + { + var ent= await _context.Skills.AsNoTracking() + .FirstOrDefaultAsync(f => f.Id == request.Id); + + if (ent == null) throw new Common.Exceptions.NotFoundException($"La entidad no existe. Id:{request.Id}"); + + var res= _context.Skills.Remove(ent); + await _context.SaveChangesAsync(cancellationToken); + return request.Id; + } +} diff --git a/src/Application/CQRS/Skills/Commands/UpdateSkillComand/UpdateSkillComands.cs b/src/Application/CQRS/Skills/Commands/UpdateSkillComand/UpdateSkillComands.cs new file mode 100644 index 0000000..1b4c94f --- /dev/null +++ b/src/Application/CQRS/Skills/Commands/UpdateSkillComand/UpdateSkillComands.cs @@ -0,0 +1,35 @@ + +using ca.Application.Common.Interfaces; + +namespace ca.Application.CQRS.Skills.Commands.UpdateSkillComand; +public class UpdateSkillComands: IRequest +{ + public int Id { get; set; } + public string Title { get; set; } = string.Empty; +} + + + + + +public class UpdateSkillHandler : IRequestHandler +{ + private readonly IApplicationDbContext _context; + private readonly IMapper _mapper; + + public UpdateSkillHandler(IMapper mapper, IApplicationDbContext context) + { + _context = context; + _mapper = mapper; + } + public async Task Handle(UpdateSkillComands request, CancellationToken cancellationToken) + { + var entity = await _context.Skills.FirstOrDefaultAsync(s => s.Id == request.Id); + if (entity == null) throw new Common.Exceptions.NotFoundException($"No existe el registro {request.Id}"); + + entity.Title = request.Title; + await _context.SaveChangesAsync(cancellationToken); + + return entity.Id; + } +} diff --git a/src/Application/CQRS/Skills/Commands/UpdateSkillComand/UpdateSkillValidator.cs b/src/Application/CQRS/Skills/Commands/UpdateSkillComand/UpdateSkillValidator.cs new file mode 100644 index 0000000..e7e385f --- /dev/null +++ b/src/Application/CQRS/Skills/Commands/UpdateSkillComand/UpdateSkillValidator.cs @@ -0,0 +1,9 @@ +namespace ca.Application.CQRS.Skills.Commands.UpdateSkillComand; +public class UpdateSkillValidator : AbstractValidator +{ + public UpdateSkillValidator() + { + + RuleFor(f => f.Title).NotNull().NotEmpty().MaximumLength(100).MinimumLength(5); + } +} diff --git a/src/Application/CQRS/Skills/Queries/GetListSkillsQueries/GetListSkillsQueries.cs b/src/Application/CQRS/Skills/Queries/GetListSkillsQueries/GetListSkillsQueries.cs new file mode 100644 index 0000000..3a1c8dc --- /dev/null +++ b/src/Application/CQRS/Skills/Queries/GetListSkillsQueries/GetListSkillsQueries.cs @@ -0,0 +1,22 @@ + +using ca.Application.Common.Bases; +using ca.Application.Common.Interfaces; +using ca.Application.Common.Mappings; +using ca.Application.Common.Models; + +namespace ca.Application.CQRS.Skills.Queries.GetListSkillsQueries; +public class GetListSkillsQueries : PaginatedBaseDTO, IRequest> +{ +} + +public class GetListSkillsHandler( IMapper _mapper, IApplicationDbContext _context) : IRequestHandler> +{ + public async Task> Handle(GetListSkillsQueries request, CancellationToken cancellationToken) + { + var res = await _context.Skills + .ProjectTo(_mapper.ConfigurationProvider) + .PaginatedListAsync(request.PageNumber, request.PageSize); + + return res; + } +} diff --git a/src/Application/CQRS/Skills/Queries/GetListSkillsQueries/GetSkillQueriesDTO.cs b/src/Application/CQRS/Skills/Queries/GetListSkillsQueries/GetSkillQueriesDTO.cs new file mode 100644 index 0000000..aec985f --- /dev/null +++ b/src/Application/CQRS/Skills/Queries/GetListSkillsQueries/GetSkillQueriesDTO.cs @@ -0,0 +1,18 @@ +using ca.Application.CQRS.Skills.Queries.GetSkillQueries; +using ca.Domain.Entities; + +namespace ca.Application.CQRS.Skills.Queries.GetListSkillsQueries; +public class GetSkillQueriesDTO +{ + public int Id { get; set; } + public string Title { get; set; } = string.Empty; + + + private class Mapping : Profile + { + public Mapping() + { + CreateMap(); + } + } +} diff --git a/src/Application/CQRS/Skills/Queries/GetSkillQueries/GetSkillDTO.cs b/src/Application/CQRS/Skills/Queries/GetSkillQueries/GetSkillDTO.cs new file mode 100644 index 0000000..3769569 --- /dev/null +++ b/src/Application/CQRS/Skills/Queries/GetSkillQueries/GetSkillDTO.cs @@ -0,0 +1,16 @@ +using ca.Domain.Entities; + +namespace ca.Application.CQRS.Skills.Queries.GetSkillQueries; +public class GetSkillDTO +{ + public int Id{ get; set; } + public string Title { get; set; } = string.Empty; + + private class Mapping : Profile + { + public Mapping() + { + CreateMap(); + } + } +} diff --git a/src/Application/CQRS/Skills/Queries/GetSkillQueries/GetSkillsQueries.cs b/src/Application/CQRS/Skills/Queries/GetSkillQueries/GetSkillsQueries.cs new file mode 100644 index 0000000..d16ef57 --- /dev/null +++ b/src/Application/CQRS/Skills/Queries/GetSkillQueries/GetSkillsQueries.cs @@ -0,0 +1,29 @@ + +using AutoMapper.QueryableExtensions; +using ca.Application.Common.Exceptions; +using ca.Application.Common.Interfaces; + +namespace ca.Application.CQRS.Skills.Queries.GetSkillQueries; +public class GetSkillsQueries : IRequest +{ + internal int Id { get; set; } + + public void AssignId(int id ) => Id = id; +} + + +public class GetSkillsHandler(IMapper _mapper, IApplicationDbContext _context) : IRequestHandler +{ + + public async Task Handle(GetSkillsQueries request, CancellationToken cancellationToken) + { + var res = await _context.Skills + .ProjectTo(_mapper.ConfigurationProvider) + .SingleOrDefaultAsync(s => s.Id == request.Id); + + if (res == null) throw new Common.Exceptions.NotFoundException($"No existe el registro {request.Id}"); + + return res; + + } +} diff --git a/src/Application/Common/Bases/PaginatedBaseDTO.cs b/src/Application/Common/Bases/PaginatedBaseDTO.cs new file mode 100644 index 0000000..d35b138 --- /dev/null +++ b/src/Application/Common/Bases/PaginatedBaseDTO.cs @@ -0,0 +1,6 @@ +namespace ca.Application.Common.Bases; +public abstract class PaginatedBaseDTO +{ + public int PageNumber { get; init; } = 1; + public int PageSize { get; init; } = 3; +} diff --git a/src/Web/Endpoints/Skills.cs b/src/Web/Endpoints/Skills.cs index 923adb8..5c58ee6 100644 --- a/src/Web/Endpoints/Skills.cs +++ b/src/Web/Endpoints/Skills.cs @@ -1,10 +1,44 @@ -using ca.Application.CQRS.Skills.Commands.CreateSkillCommand; +using ca.Application.Common.Models; +using ca.Application.CQRS.Skills.Commands.CreateSkillCommand; +using ca.Application.CQRS.Skills.Commands.DeleteSkillComand; +using ca.Application.CQRS.Skills.Commands.UpdateSkillComand; +using ca.Application.CQRS.Skills.Queries.GetListSkillsQueries; +using ca.Application.CQRS.Skills.Queries.GetSkillQueries; +using ca.Application.CQRS.Students.Queries.GetStudentQueries; +using ca.Application.CQRS.TodoItems.Queries.GetTodoItemsWithPagination; using Microsoft.AspNetCore.Authorization; + namespace ca.Web.Endpoints; public class Skills : EndpointGroupBase { + public override void Map(WebApplication app) + { + app.MapGroup(this) + .MapGet(GetSkills,"{id}") + .MapGet(GetListSkills) + .MapPost(PostSkill) + .MapPut(PutSkills, "{id}") + .MapDelete(DeleteSkills, "{id}"); + } + + [AllowAnonymous] + public Task GetSkills(ISender sender, int id) + { + var command = new GetSkillsQueries(); + command.AssignId(id); + + return sender.Send(command); + } + + [AllowAnonymous] + public async Task> GetListSkills(ISender sender, [AsParameters] GetListSkillsQueries query) + { + + var res = await sender.Send(query); + return res; + } [AllowAnonymous] public Task PostSkill(ISender sender, CreateSkillCommands command) @@ -12,9 +46,20 @@ public Task PostSkill(ISender sender, CreateSkillCommands command) return sender.Send(command); } - public override void Map(WebApplication app) + [AllowAnonymous] + public async Task PutSkills(ISender sender,int id, UpdateSkillComands command) { - app.MapGroup(this) - .MapPost(PostSkill); + if (id != command.Id) return Results.BadRequest(); + await sender.Send(command); + return Results.Ok(command.Id); } + + [AllowAnonymous] + public async Task DeleteSkills(ISender sender, int id) + { + await sender.Send(new DeleteSkillsComands() { Id=id}); + return Results.Ok(id); + } + + } diff --git a/src/Web/Web.csproj b/src/Web/Web.csproj index 1599ff7..bbf16d5 100644 --- a/src/Web/Web.csproj +++ b/src/Web/Web.csproj @@ -1,46 +1,49 @@ - - - - ca.Web - ca.Web - - - - - - - - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - OnBuildSuccess - - - - - - - - - - - - - - + + + + ca.Web + ca.Web + + + + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + OnBuildSuccess + + + + + + + + + + + + + diff --git a/src/Web/wwwroot/api/specification.json b/src/Web/wwwroot/api/specification.json index 149b0a0..d40b72b 100644 --- a/src/Web/wwwroot/api/specification.json +++ b/src/Web/wwwroot/api/specification.json @@ -6,7 +6,137 @@ "version": "1.0.0" }, "paths": { + "/api/Skills/{id}": { + "get": { + "tags": [ + "Skills" + ], + "operationId": "GetSkills", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + }, + "x-position": 1 + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetSkillDTO" + } + } + } + } + } + }, + "put": { + "tags": [ + "Skills" + ], + "operationId": "PutSkills", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + }, + "x-position": 1 + } + ], + "requestBody": { + "x-name": "command", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSkillComands" + } + } + }, + "required": true, + "x-position": 2 + }, + "responses": { + "200": { + "description": "" + } + } + }, + "delete": { + "tags": [ + "Skills" + ], + "operationId": "DeleteSkills", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + }, + "x-position": 1 + } + ], + "responses": { + "200": { + "description": "" + } + } + } + }, "/api/Skills": { + "get": { + "tags": [ + "Skills" + ], + "operationId": "GetListSkills", + "parameters": [ + { + "name": "PageNumber", + "in": "query", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + }, + "x-position": 1 + }, + { + "name": "PageSize", + "in": "query", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + }, + "x-position": 2 + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaginatedListOfGetSkillQueriesDTO" + } + } + } + } + } + }, "post": { "tags": [ "Skills" @@ -780,6 +910,62 @@ }, "components": { "schemas": { + "GetSkillDTO": { + "type": "object", + "additionalProperties": false, + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "title": { + "type": "string" + } + } + }, + "PaginatedListOfGetSkillQueriesDTO": { + "type": "object", + "additionalProperties": false, + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GetSkillQueriesDTO" + } + }, + "pageNumber": { + "type": "integer", + "format": "int32" + }, + "totalPages": { + "type": "integer", + "format": "int32" + }, + "totalCount": { + "type": "integer", + "format": "int32" + }, + "hasPreviousPage": { + "type": "boolean" + }, + "hasNextPage": { + "type": "boolean" + } + } + }, + "GetSkillQueriesDTO": { + "type": "object", + "additionalProperties": false, + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "title": { + "type": "string" + } + } + }, "CreateSkillCommands": { "type": "object", "additionalProperties": false, @@ -789,6 +975,19 @@ } } }, + "UpdateSkillComands": { + "type": "object", + "additionalProperties": false, + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "title": { + "type": "string" + } + } + }, "GetStudentDto": { "type": "object", "additionalProperties": false,