Skip to content

Commit

Permalink
Merge pull request #3 from maurobernal/CA-3-crud-for-skills
Browse files Browse the repository at this point in the history
feat:MB: crud for skills
  • Loading branch information
maurobernal authored Apr 27, 2024
2 parents 2ebd5a3 + e734322 commit 122e8e2
Show file tree
Hide file tree
Showing 12 changed files with 461 additions and 54 deletions.
4 changes: 0 additions & 4 deletions src/Application/Application.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@
</ItemGroup>

<ItemGroup>
<Folder Include="CQRS\Skills\Commands\DeleteSkillComand\" />
<Folder Include="CQRS\Skills\Commands\UpdateSkillComand\" />
<Folder Include="CQRS\Skills\Queries\GetSkillQueries\" />
<Folder Include="CQRS\Skills\Queries\GetListSkillsQueries\" />
<Folder Include="CQRS\Students\Queries\GetStudentsQueries\" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -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<int>
{
public int Id { get; set; }
}


public class DeleteSkillsHandler : IRequestHandler<DeleteSkillsComands, int>
{
private readonly IApplicationDbContext _context;

public DeleteSkillsHandler(IApplicationDbContext context) => _context = context;

public async Task<int> 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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@

using ca.Application.Common.Interfaces;

namespace ca.Application.CQRS.Skills.Commands.UpdateSkillComand;
public class UpdateSkillComands: IRequest<int>
{
public int Id { get; set; }
public string Title { get; set; } = string.Empty;
}





public class UpdateSkillHandler : IRequestHandler<UpdateSkillComands, int>
{
private readonly IApplicationDbContext _context;
private readonly IMapper _mapper;

public UpdateSkillHandler(IMapper mapper, IApplicationDbContext context)
{
_context = context;
_mapper = mapper;
}
public async Task<int> 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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace ca.Application.CQRS.Skills.Commands.UpdateSkillComand;
public class UpdateSkillValidator : AbstractValidator<UpdateSkillComands>
{
public UpdateSkillValidator()
{

RuleFor(f => f.Title).NotNull().NotEmpty().MaximumLength(100).MinimumLength(5);
}
}
Original file line number Diff line number Diff line change
@@ -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<PaginatedList<GetSkillQueriesDTO>>
{
}

public class GetListSkillsHandler( IMapper _mapper, IApplicationDbContext _context) : IRequestHandler<GetListSkillsQueries, PaginatedList<GetSkillQueriesDTO>>
{
public async Task<PaginatedList<GetSkillQueriesDTO>> Handle(GetListSkillsQueries request, CancellationToken cancellationToken)
{
var res = await _context.Skills
.ProjectTo<GetSkillQueriesDTO>(_mapper.ConfigurationProvider)
.PaginatedListAsync(request.PageNumber, request.PageSize);

return res;
}
}
Original file line number Diff line number Diff line change
@@ -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<Skill, GetSkillQueriesDTO>();
}
}
}
16 changes: 16 additions & 0 deletions src/Application/CQRS/Skills/Queries/GetSkillQueries/GetSkillDTO.cs
Original file line number Diff line number Diff line change
@@ -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<Skill, GetSkillDTO>();
}
}
}
Original file line number Diff line number Diff line change
@@ -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<GetSkillDTO>
{
internal int Id { get; set; }

public void AssignId(int id ) => Id = id;
}


public class GetSkillsHandler(IMapper _mapper, IApplicationDbContext _context) : IRequestHandler<GetSkillsQueries, GetSkillDTO>
{

public async Task<GetSkillDTO> Handle(GetSkillsQueries request, CancellationToken cancellationToken)
{
var res = await _context.Skills
.ProjectTo<GetSkillDTO>(_mapper.ConfigurationProvider)
.SingleOrDefaultAsync(s => s.Id == request.Id);

if (res == null) throw new Common.Exceptions.NotFoundException($"No existe el registro {request.Id}");

return res;

}
}
6 changes: 6 additions & 0 deletions src/Application/Common/Bases/PaginatedBaseDTO.cs
Original file line number Diff line number Diff line change
@@ -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;
}
53 changes: 49 additions & 4 deletions src/Web/Endpoints/Skills.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,65 @@
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<GetSkillDTO> GetSkills(ISender sender, int id)
{
var command = new GetSkillsQueries();
command.AssignId(id);

return sender.Send(command);
}

[AllowAnonymous]
public async Task<PaginatedList<GetSkillQueriesDTO>> GetListSkills(ISender sender, [AsParameters] GetListSkillsQueries query)
{

var res = await sender.Send(query);
return res;
}

[AllowAnonymous]
public Task<int> PostSkill(ISender sender, CreateSkillCommands command)
{
return sender.Send(command);
}

public override void Map(WebApplication app)
[AllowAnonymous]
public async Task<IResult> 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<IResult> DeleteSkills(ISender sender, int id)
{
await sender.Send(new DeleteSkillsComands() { Id=id});
return Results.Ok(id);
}


}
95 changes: 49 additions & 46 deletions src/Web/Web.csproj
Original file line number Diff line number Diff line change
@@ -1,46 +1,49 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<RootNamespace>ca.Web</RootNamespace>
<AssemblyName>ca.Web</AssemblyName>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Application\Application.csproj" />
<ProjectReference Include="..\Infrastructure\Infrastructure.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Azure.Extensions.AspNetCore.Configuration.Secrets" />
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" />
<PackageReference Include="NSwag.AspNetCore" />
<PackageReference Include="NSwag.MSBuild">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

<PackageReference Include="FluentValidation.AspNetCore" />
</ItemGroup>


<!-- Auto-generated Open API specification and Angular TypeScript clients -->
<PropertyGroup>
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
</PropertyGroup>


<Target Name="NSwag" AfterTargets="PostBuildEvent" Condition=" '$(Configuration)' == 'Debug' And '$(SkipNSwag)' != 'True' ">
<Exec ConsoleToMSBuild="true" ContinueOnError="true" WorkingDirectory="$(ProjectDir)" EnvironmentVariables="ASPNETCORE_ENVIRONMENT=Development" Command="$(NSwagExe_Net80) run config.nswag /variables:Configuration=$(Configuration)">
<Output TaskParameter="ExitCode" PropertyName="NSwagExitCode" />
<Output TaskParameter="ConsoleOutput" PropertyName="NSwagOutput" />
</Exec>

<Message Text="$(NSwagOutput)" Condition="'$(NSwagExitCode)' == '0'" Importance="low" />
<Error Text="$(NSwagOutput)" Condition="'$(NSwagExitCode)' != '0'" />
</Target>

</Project>
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<RootNamespace>ca.Web</RootNamespace>
<AssemblyName>ca.Web</AssemblyName>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Application\Application.csproj" />
<ProjectReference Include="..\Infrastructure\Infrastructure.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Azure.Extensions.AspNetCore.Configuration.Secrets" />
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" />
<PackageReference Include="NSwag.AspNetCore" />
<PackageReference Include="NSwag.MSBuild">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

<PackageReference Include="FluentValidation.AspNetCore" />
</ItemGroup>

<ItemGroup>
<Folder Include="wwwroot\api\" />
</ItemGroup>


<!-- Auto-generated Open API specification and Angular TypeScript clients -->
<PropertyGroup>
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
</PropertyGroup>

<Target Name="NSwag" AfterTargets="PostBuildEvent" Condition=" '$(Configuration)' == 'Debug' And '$(SkipNSwag)' != 'True' ">
<Exec ConsoleToMSBuild="true" ContinueOnError="true" WorkingDirectory="$(ProjectDir)" EnvironmentVariables="ASPNETCORE_ENVIRONMENT=Development" Command="$(NSwagExe_Net80) run config.nswag /variables:Configuration=$(Configuration)">
<Output TaskParameter="ExitCode" PropertyName="NSwagExitCode" />
<Output TaskParameter="ConsoleOutput" PropertyName="NSwagOutput" />
</Exec>

<Message Text="$(NSwagOutput)" Condition="'$(NSwagExitCode)' == '0'" Importance="low" />
<Error Text="$(NSwagOutput)" Condition="'$(NSwagExitCode)' != '0'" />
</Target>

</Project>
Loading

0 comments on commit 122e8e2

Please sign in to comment.