From f574a6b4cbf5c57818941223506458466d4b14e9 Mon Sep 17 00:00:00 2001 From: tleodev Date: Thu, 9 Jan 2025 08:27:20 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Introduice=20exercices=20entity=20a?= =?UTF-8?q?nd=20correspondant=20routes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Infrastructure/Entities/Exercice.cs | 22 +++++ Infrastructure/Entities/Program.cs | 19 +++++ Infrastructure/Entities/Session.cs | 17 ++++ .../Repositories/ExerciceRepository.cs | 10 +++ .../Repositories/GenericRepository.cs | 2 - .../Repositories/IExerciceRepository.cs | 7 ++ Server/Controller/v1/ExercicesController.cs | 82 +++++++++++++++++++ Server/Dto/Request/RequestExerciceDto.cs | 22 +++++ Server/Dto/Request/RequestProgramDto.cs | 20 +++++ Server/Dto/Request/RequestSessionDto.cs | 17 ++++ Server/Dto/Response/ResponseExerciceDto.cs | 21 +++++ Server/Dto/Response/ResponseProgramDto.cs | 19 +++++ Server/Dto/Response/ResponseSessionDto.cs | 17 ++++ Server/IServices/IExerciceService.cs | 14 ++++ Server/Mappers/ExerciceProfile.cs | 15 ++++ .../{UsersMappers.cs => UserProfile.cs} | 4 +- Server/Program.cs | 10 ++- Server/Services/ExerciceService.cs | 66 +++++++++++++++ Server/Services/UsersService.cs | 4 +- 19 files changed, 380 insertions(+), 8 deletions(-) create mode 100644 Infrastructure/Entities/Exercice.cs create mode 100644 Infrastructure/Entities/Program.cs create mode 100644 Infrastructure/Entities/Session.cs create mode 100644 Infrastructure/Repositories/ExerciceRepository.cs create mode 100644 Infrastructure/Repositories/IExerciceRepository.cs create mode 100644 Server/Controller/v1/ExercicesController.cs create mode 100644 Server/Dto/Request/RequestExerciceDto.cs create mode 100644 Server/Dto/Request/RequestProgramDto.cs create mode 100644 Server/Dto/Request/RequestSessionDto.cs create mode 100644 Server/Dto/Response/ResponseExerciceDto.cs create mode 100644 Server/Dto/Response/ResponseProgramDto.cs create mode 100644 Server/Dto/Response/ResponseSessionDto.cs create mode 100644 Server/IServices/IExerciceService.cs create mode 100644 Server/Mappers/ExerciceProfile.cs rename Server/Mappers/{UsersMappers.cs => UserProfile.cs} (96%) create mode 100644 Server/Services/ExerciceService.cs diff --git a/Infrastructure/Entities/Exercice.cs b/Infrastructure/Entities/Exercice.cs new file mode 100644 index 0000000..bfad362 --- /dev/null +++ b/Infrastructure/Entities/Exercice.cs @@ -0,0 +1,22 @@ +using System.ComponentModel.DataAnnotations; +using Infrastructure.Base; + +namespace Infrastructure.Entities; + +public class Exercice : EntityBase +{ + [Required] + public string Name { get; set; } + + public string Description { get; set; } + + public float Duration { get; set; } + + public string Image { get; set; } + + public string Video { get; set; } + + public int NbSeries { get; set; } + + public int NbRepetitions { get; set; } +} \ No newline at end of file diff --git a/Infrastructure/Entities/Program.cs b/Infrastructure/Entities/Program.cs new file mode 100644 index 0000000..82398fe --- /dev/null +++ b/Infrastructure/Entities/Program.cs @@ -0,0 +1,19 @@ +using System.Collections.ObjectModel; +using System.ComponentModel.DataAnnotations; +using Infrastructure.Base; + +namespace Infrastructure.Entities; + +public class Program : EntityBase +{ + [Required] + public string Name { get; set; } + + public int WeekDuration { get; set; } + + public string Description { get; set; } + + public string Difficulty { get; set; } + + public virtual ICollection Sessions { get; set; } = new Collection(); +} \ No newline at end of file diff --git a/Infrastructure/Entities/Session.cs b/Infrastructure/Entities/Session.cs new file mode 100644 index 0000000..a17cf14 --- /dev/null +++ b/Infrastructure/Entities/Session.cs @@ -0,0 +1,17 @@ +using System.Collections.ObjectModel; +using System.ComponentModel.DataAnnotations; +using Infrastructure.Base; + +namespace Infrastructure.Entities; + +public class Session : EntityBase +{ + [Required] + public string Name { get; set; } + + public string Description { get; set; } + + public float Duration { get; set; } + + public virtual ICollection Exercices { get; set; } = new Collection(); +} \ No newline at end of file diff --git a/Infrastructure/Repositories/ExerciceRepository.cs b/Infrastructure/Repositories/ExerciceRepository.cs new file mode 100644 index 0000000..1e46340 --- /dev/null +++ b/Infrastructure/Repositories/ExerciceRepository.cs @@ -0,0 +1,10 @@ +using Infrastructure.Entities; + +namespace Infrastructure.Repositories; + +public class ExerciceRepository : GenericRepository, IExerciceRepository +{ + public ExerciceRepository(OptifitDbContext context) : base(context) + { + } +} \ No newline at end of file diff --git a/Infrastructure/Repositories/GenericRepository.cs b/Infrastructure/Repositories/GenericRepository.cs index ca8a5dc..7034d8b 100644 --- a/Infrastructure/Repositories/GenericRepository.cs +++ b/Infrastructure/Repositories/GenericRepository.cs @@ -2,8 +2,6 @@ using System.Linq.Expressions; using Infrastructure.Base; using Microsoft.EntityFrameworkCore; using Shared; -using System.Linq.Expressions; -using System.Threading.Tasks; using System.Linq.Dynamic.Core; namespace Infrastructure.Repositories; diff --git a/Infrastructure/Repositories/IExerciceRepository.cs b/Infrastructure/Repositories/IExerciceRepository.cs new file mode 100644 index 0000000..03e31cc --- /dev/null +++ b/Infrastructure/Repositories/IExerciceRepository.cs @@ -0,0 +1,7 @@ +using Infrastructure.Entities; + +namespace Infrastructure.Repositories; + +public interface IExerciceRepository : IRepository +{ +} \ No newline at end of file diff --git a/Server/Controller/v1/ExercicesController.cs b/Server/Controller/v1/ExercicesController.cs new file mode 100644 index 0000000..4b7daf7 --- /dev/null +++ b/Server/Controller/v1/ExercicesController.cs @@ -0,0 +1,82 @@ +using Asp.Versioning; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Server.Dto.Request; +using Server.Dto.Response; +using Server.IServices; + +namespace Server.Controller.v1; + +[ApiController] +[ApiVersion("1.0")] +[Route("api/v{version:apiVersion}/[controller]")] +public class ExercicesController : ControllerBase +{ + private readonly ILogger _logger; + private readonly IExerciceService _dataServices; + + public ExercicesController(ILogger logger, IExerciceService dataServices) + { + _logger = logger; + _dataServices = dataServices; + } + + [HttpGet] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [RequireHttps] + [AllowAnonymous] + public async Task GetExercices([FromQuery] int pageIndex = 1, [FromQuery] int pageSize = 5, [FromQuery] bool ascending = true) + { + var exercices = await _dataServices.GetExercices(pageIndex, pageSize, ascending); + return exercices.TotalCount == 0 ? NoContent() : Ok(exercices); + } + + [HttpGet("{id}")] + [ProducesResponseType(typeof(ResponseExerciceDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [RequireHttps] + [AllowAnonymous] + public async Task GetExerciceById(string id) + { + var exercice = await _dataServices.GetExerciceById(id); + return exercice == null ? NotFound() : Ok(exercice); + } + + [HttpPost] + [ProducesResponseType(typeof(ResponseExerciceDto), StatusCodes.Status201Created)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [AllowAnonymous] + public async Task CreateExercice([FromBody] RequestExerciceDto request) + { + if (!ModelState.IsValid) return BadRequest(ModelState); + + var createdExercice = await _dataServices.CreateExercice(request); + return CreatedAtAction(nameof(GetExerciceById), new { id = createdExercice.Id }, createdExercice); + } + + [HttpPut("{id}")] + [ProducesResponseType(typeof(ResponseExerciceDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [RequireHttps] + [AllowAnonymous] + public async Task UpdateExercice(string id, [FromBody] RequestExerciceDto request) + { + if (!ModelState.IsValid) return BadRequest(ModelState); + + var updatedExercice = await _dataServices.UpdateExercice(id, request); + return updatedExercice == null ? NotFound() : Ok(updatedExercice); + } + + [HttpDelete("{id}")] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [RequireHttps] + [AllowAnonymous] + public async Task DeleteExercice(string id) + { + var deleted = await _dataServices.DeleteExercice(id); + return deleted ? NoContent() : NotFound(); + } +} \ No newline at end of file diff --git a/Server/Dto/Request/RequestExerciceDto.cs b/Server/Dto/Request/RequestExerciceDto.cs new file mode 100644 index 0000000..5c9dd85 --- /dev/null +++ b/Server/Dto/Request/RequestExerciceDto.cs @@ -0,0 +1,22 @@ +using System.ComponentModel.DataAnnotations; + +namespace Server.Dto.Request +{ + public class RequestExerciceDto + { + [Required] + public string Name { get; set; } + + public string Description { get; set; } + + public float Duration { get; set; } + + public string Image { get; set; } + + public string Video { get; set; } + + public int NbSeries { get; set; } + + public int NbRepetitions { get; set; } + } +} \ No newline at end of file diff --git a/Server/Dto/Request/RequestProgramDto.cs b/Server/Dto/Request/RequestProgramDto.cs new file mode 100644 index 0000000..2fd5c59 --- /dev/null +++ b/Server/Dto/Request/RequestProgramDto.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace Server.Dto.Request +{ + public class RequestProgramDto + { + [Required] + public string Name { get; set; } + + [Required] + public int WeekDuration { get; set; } + + public string Description { get; set; } + + public string Difficulty { get; set; } + + public List Sessions { get; set; } = new List(); + } +} \ No newline at end of file diff --git a/Server/Dto/Request/RequestSessionDto.cs b/Server/Dto/Request/RequestSessionDto.cs new file mode 100644 index 0000000..ad334a6 --- /dev/null +++ b/Server/Dto/Request/RequestSessionDto.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace Server.Dto.Request +{ + public class RequestSessionDto + { + [Required] + public string Name { get; set; } + + public string Description { get; set; } + + public float Duration { get; set; } + + public List Exercices { get; set; } = new List(); + } +} \ No newline at end of file diff --git a/Server/Dto/Response/ResponseExerciceDto.cs b/Server/Dto/Response/ResponseExerciceDto.cs new file mode 100644 index 0000000..88a8a1c --- /dev/null +++ b/Server/Dto/Response/ResponseExerciceDto.cs @@ -0,0 +1,21 @@ +namespace Server.Dto.Response +{ + public class ResponseExerciceDto + { + public string Id { get; set; } + + public string Name { get; set; } + + public string Description { get; set; } + + public float Duration { get; set; } + + public string Image { get; set; } + + public string Video { get; set; } + + public int NbSeries { get; set; } + + public int NbRepetitions { get; set; } + } +} \ No newline at end of file diff --git a/Server/Dto/Response/ResponseProgramDto.cs b/Server/Dto/Response/ResponseProgramDto.cs new file mode 100644 index 0000000..39c8998 --- /dev/null +++ b/Server/Dto/Response/ResponseProgramDto.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; + +namespace Server.Dto.Response +{ + public class ResponseProgramDto + { + public string Id { get; set; } + + public string Name { get; set; } + + public int WeekDuration { get; set; } + + public string Description { get; set; } + + public string Difficulty { get; set; } + + public List Sessions { get; set; } = new List(); + } +} \ No newline at end of file diff --git a/Server/Dto/Response/ResponseSessionDto.cs b/Server/Dto/Response/ResponseSessionDto.cs new file mode 100644 index 0000000..351a206 --- /dev/null +++ b/Server/Dto/Response/ResponseSessionDto.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; + +namespace Server.Dto.Response +{ + public class ResponseSessionDto + { + public string Id { get; set; } + + public string Name { get; set; } + + public string Description { get; set; } + + public float Duration { get; set; } + + public List Exercices { get; set; } = new List(); + } +} \ No newline at end of file diff --git a/Server/IServices/IExerciceService.cs b/Server/IServices/IExerciceService.cs new file mode 100644 index 0000000..cf5904e --- /dev/null +++ b/Server/IServices/IExerciceService.cs @@ -0,0 +1,14 @@ +using Server.Dto.Request; +using Server.Dto.Response; +using Shared; + +namespace Server.IServices; + +public interface IExerciceService +{ + Task> GetExercices(int page, int size, bool ascending = true); + Task GetExerciceById(string id); + Task CreateExercice(RequestExerciceDto request); + Task UpdateExercice(string id, RequestExerciceDto request); + Task DeleteExercice(string id); +} \ No newline at end of file diff --git a/Server/Mappers/ExerciceProfile.cs b/Server/Mappers/ExerciceProfile.cs new file mode 100644 index 0000000..c1d37ab --- /dev/null +++ b/Server/Mappers/ExerciceProfile.cs @@ -0,0 +1,15 @@ +using AutoMapper; +using Infrastructure.Entities; +using Server.Dto.Request; +using Server.Dto.Response; + +namespace Server.Mappers; + +public class ExerciceProfile : Profile +{ + public ExerciceProfile() + { + CreateMap(); + CreateMap(); + } +} \ No newline at end of file diff --git a/Server/Mappers/UsersMappers.cs b/Server/Mappers/UserProfile.cs similarity index 96% rename from Server/Mappers/UsersMappers.cs rename to Server/Mappers/UserProfile.cs index cfd7c73..fefb0f6 100644 --- a/Server/Mappers/UsersMappers.cs +++ b/Server/Mappers/UserProfile.cs @@ -5,9 +5,9 @@ using AutoMapper; namespace Server.Mappers; -public class UsersMappers : Profile +public class UserProfile : Profile { - public UsersMappers() + public UserProfile() { _ = CreateMap() .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id)) diff --git a/Server/Program.cs b/Server/Program.cs index bcb7bd5..e4ecf5d 100644 --- a/Server/Program.cs +++ b/Server/Program.cs @@ -12,13 +12,19 @@ var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddScoped(); -builder.Services.AddScoped(); // Register UserRepository +builder.Services.AddScoped(); + +builder.Services.AddScoped(); +builder.Services.AddScoped(); + + builder.Services.AddControllers(); builder.Services.AddDbContext(options => options.UseSqlite("Data Source=FirstTest.db")); // Register AutoMapper -builder.Services.AddAutoMapper(typeof(UsersMappers)); +builder.Services.AddAutoMapper(typeof(UserProfile)); +builder.Services.AddAutoMapper(typeof(ExerciceProfile)); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); diff --git a/Server/Services/ExerciceService.cs b/Server/Services/ExerciceService.cs new file mode 100644 index 0000000..dffef9f --- /dev/null +++ b/Server/Services/ExerciceService.cs @@ -0,0 +1,66 @@ +using AutoMapper; +using Infrastructure; +using Infrastructure.Entities; +using Infrastructure.Repositories; +using Server.Dto.Request; +using Server.Dto.Response; +using Server.IServices; +using Shared; + +namespace Server.Services; + +public class ExerciceService : IExerciceService +{ + private readonly OptifitDbContext _context; + private readonly IExerciceRepository _exerciceRepository; + private readonly IMapper _mapper; + + public ExerciceService(OptifitDbContext context, IExerciceRepository exerciceRepository, IMapper mapper) + { + _context = context; + _exerciceRepository = exerciceRepository; + _mapper = mapper; + } + + public async Task> GetExercices(int page, int size, bool ascending = true) + { + var exercices = await _exerciceRepository.GetPaginatedListAsync(page - 1, size, null, null); + var result = _mapper.Map>(exercices); + return result; + } + + public async Task GetExerciceById(string id) + { + var exercice = await _exerciceRepository.GetByIdAsync(id); + return exercice == null ? null : _mapper.Map(exercice); + } + + public async Task CreateExercice(RequestExerciceDto request) + { + var exercice = _mapper.Map(request); + await _exerciceRepository.InsertAsync(exercice); + await _context.SaveChangesAsync(); + return _mapper.Map(exercice); + } + + public async Task UpdateExercice(string id, RequestExerciceDto request) + { + var exercice = await _exerciceRepository.GetByIdAsync(id); + if (exercice == null) return null; + + _mapper.Map(request, exercice); + _exerciceRepository.Update(exercice); + await _context.SaveChangesAsync(); + return _mapper.Map(exercice); + } + + public async Task DeleteExercice(string id) + { + var exercice = await _exerciceRepository.GetByIdAsync(id); + if (exercice == null) return false; + + _exerciceRepository.Delete(id); + await _context.SaveChangesAsync(); + return true; + } +} \ No newline at end of file diff --git a/Server/Services/UsersService.cs b/Server/Services/UsersService.cs index 84076be..84e3105 100644 --- a/Server/Services/UsersService.cs +++ b/Server/Services/UsersService.cs @@ -10,10 +10,10 @@ namespace Server.Services; public class UsersService : IUsersService { private readonly OptifitDbContext _context; - private readonly UserRepository _userRepository; + private readonly IUserRepository _userRepository; private readonly IMapper _mapper; - public UsersService(OptifitDbContext context, UserRepository userRepository, IMapper mapper) + public UsersService(OptifitDbContext context, IUserRepository userRepository, IMapper mapper) { _context = context; _userRepository = userRepository;