diff --git a/Infrastructure/Entities/Program.cs b/Infrastructure/Entities/TrainingProgram.cs
similarity index 91%
rename from Infrastructure/Entities/Program.cs
rename to Infrastructure/Entities/TrainingProgram.cs
index 82398fe..6df8f45 100644
--- a/Infrastructure/Entities/Program.cs
+++ b/Infrastructure/Entities/TrainingProgram.cs
@@ -4,7 +4,7 @@ using Infrastructure.Base;
namespace Infrastructure.Entities;
-public class Program : EntityBase
+public class TrainingProgram : EntityBase
{
[Required]
public string Name { get; set; }
diff --git a/Infrastructure/Migrations/20250109094119_TrainingProgram.Designer.cs b/Infrastructure/Migrations/20250109094119_TrainingProgram.Designer.cs
new file mode 100644
index 0000000..6e63217
--- /dev/null
+++ b/Infrastructure/Migrations/20250109094119_TrainingProgram.Designer.cs
@@ -0,0 +1,191 @@
+//
+using Infrastructure;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace Infrastructure.Migrations
+{
+ [DbContext(typeof(OptifitDbContext))]
+ [Migration("20250109094119_TrainingProgram")]
+ partial class TrainingProgram
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder.HasAnnotation("ProductVersion", "8.0.1");
+
+ modelBuilder.Entity("Infrastructure.Entities.Exercice", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Duration")
+ .HasColumnType("REAL");
+
+ b.Property("Image")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("NbRepetitions")
+ .HasColumnType("INTEGER");
+
+ b.Property("NbSeries")
+ .HasColumnType("INTEGER");
+
+ b.Property("SessionId")
+ .HasColumnType("TEXT");
+
+ b.Property("Video")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("SessionId");
+
+ b.ToTable("Exercices");
+ });
+
+ modelBuilder.Entity("Infrastructure.Entities.Program", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Difficulty")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("WeekDuration")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.ToTable("Programs");
+ });
+
+ modelBuilder.Entity("Infrastructure.Entities.Session", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Duration")
+ .HasColumnType("REAL");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("ProgramId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ProgramId");
+
+ b.ToTable("Sessions");
+ });
+
+ modelBuilder.Entity("Infrastructure.Entities.User", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("Age")
+ .HasColumnType("INTEGER");
+
+ b.Property("EGoal")
+ .HasColumnType("TEXT");
+
+ b.Property("ESleepLevel")
+ .HasColumnType("TEXT");
+
+ b.Property("ESportLevel")
+ .HasColumnType("TEXT");
+
+ b.Property("HashPassword")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Height")
+ .HasColumnType("REAL");
+
+ b.Property("Logo")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("NbSessionPerWeek")
+ .HasColumnType("INTEGER");
+
+ b.Property("OAuthId")
+ .HasColumnType("TEXT");
+
+ b.Property("OAuthProvider")
+ .HasColumnType("TEXT");
+
+ b.Property("Sexe")
+ .HasColumnType("INTEGER");
+
+ b.Property("Weight")
+ .HasColumnType("REAL");
+
+ b.HasKey("Id");
+
+ b.ToTable("Users");
+ });
+
+ modelBuilder.Entity("Infrastructure.Entities.Exercice", b =>
+ {
+ b.HasOne("Infrastructure.Entities.Session", null)
+ .WithMany("Exercices")
+ .HasForeignKey("SessionId");
+ });
+
+ modelBuilder.Entity("Infrastructure.Entities.Session", b =>
+ {
+ b.HasOne("Infrastructure.Entities.Program", null)
+ .WithMany("Sessions")
+ .HasForeignKey("ProgramId");
+ });
+
+ modelBuilder.Entity("Infrastructure.Entities.Program", b =>
+ {
+ b.Navigation("Sessions");
+ });
+
+ modelBuilder.Entity("Infrastructure.Entities.Session", b =>
+ {
+ b.Navigation("Exercices");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Infrastructure/Migrations/20250109094119_TrainingProgram.cs b/Infrastructure/Migrations/20250109094119_TrainingProgram.cs
new file mode 100644
index 0000000..3237c77
--- /dev/null
+++ b/Infrastructure/Migrations/20250109094119_TrainingProgram.cs
@@ -0,0 +1,94 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace Infrastructure.Migrations
+{
+ ///
+ public partial class TrainingProgram : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AddColumn(
+ name: "SessionId",
+ table: "Exercices",
+ type: "TEXT",
+ nullable: true);
+
+ migrationBuilder.CreateTable(
+ name: "Programs",
+ columns: table => new
+ {
+ Id = table.Column(type: "TEXT", nullable: false),
+ Name = table.Column(type: "TEXT", nullable: false),
+ WeekDuration = table.Column(type: "INTEGER", nullable: false),
+ Description = table.Column(type: "TEXT", nullable: false),
+ Difficulty = table.Column(type: "TEXT", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Programs", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Sessions",
+ columns: table => new
+ {
+ Id = table.Column(type: "TEXT", nullable: false),
+ Name = table.Column(type: "TEXT", nullable: false),
+ Description = table.Column(type: "TEXT", nullable: false),
+ Duration = table.Column(type: "REAL", nullable: false),
+ ProgramId = table.Column(type: "TEXT", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Sessions", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Sessions_Programs_ProgramId",
+ column: x => x.ProgramId,
+ principalTable: "Programs",
+ principalColumn: "Id");
+ });
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Exercices_SessionId",
+ table: "Exercices",
+ column: "SessionId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Sessions_ProgramId",
+ table: "Sessions",
+ column: "ProgramId");
+
+ migrationBuilder.AddForeignKey(
+ name: "FK_Exercices_Sessions_SessionId",
+ table: "Exercices",
+ column: "SessionId",
+ principalTable: "Sessions",
+ principalColumn: "Id");
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropForeignKey(
+ name: "FK_Exercices_Sessions_SessionId",
+ table: "Exercices");
+
+ migrationBuilder.DropTable(
+ name: "Sessions");
+
+ migrationBuilder.DropTable(
+ name: "Programs");
+
+ migrationBuilder.DropIndex(
+ name: "IX_Exercices_SessionId",
+ table: "Exercices");
+
+ migrationBuilder.DropColumn(
+ name: "SessionId",
+ table: "Exercices");
+ }
+ }
+}
diff --git a/Infrastructure/Migrations/OptifitDbContextModelSnapshot.cs b/Infrastructure/Migrations/OptifitDbContextModelSnapshot.cs
index 5a17324..c8283ee 100644
--- a/Infrastructure/Migrations/OptifitDbContextModelSnapshot.cs
+++ b/Infrastructure/Migrations/OptifitDbContextModelSnapshot.cs
@@ -42,15 +42,71 @@ namespace Infrastructure.Migrations
b.Property("NbSeries")
.HasColumnType("INTEGER");
+ b.Property("SessionId")
+ .HasColumnType("TEXT");
+
b.Property("Video")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
+ b.HasIndex("SessionId");
+
b.ToTable("Exercices");
});
+ modelBuilder.Entity("Infrastructure.Entities.Program", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Difficulty")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("WeekDuration")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.ToTable("Programs");
+ });
+
+ modelBuilder.Entity("Infrastructure.Entities.Session", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Duration")
+ .HasColumnType("REAL");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("ProgramId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ProgramId");
+
+ b.ToTable("Sessions");
+ });
+
modelBuilder.Entity("Infrastructure.Entities.User", b =>
{
b.Property("Id")
@@ -108,6 +164,30 @@ namespace Infrastructure.Migrations
b.ToTable("Users");
});
+
+ modelBuilder.Entity("Infrastructure.Entities.Exercice", b =>
+ {
+ b.HasOne("Infrastructure.Entities.Session", null)
+ .WithMany("Exercices")
+ .HasForeignKey("SessionId");
+ });
+
+ modelBuilder.Entity("Infrastructure.Entities.Session", b =>
+ {
+ b.HasOne("Infrastructure.Entities.Program", null)
+ .WithMany("Sessions")
+ .HasForeignKey("ProgramId");
+ });
+
+ modelBuilder.Entity("Infrastructure.Entities.Program", b =>
+ {
+ b.Navigation("Sessions");
+ });
+
+ modelBuilder.Entity("Infrastructure.Entities.Session", b =>
+ {
+ b.Navigation("Exercices");
+ });
#pragma warning restore 612, 618
}
}
diff --git a/Infrastructure/OptifitDbContext.cs b/Infrastructure/OptifitDbContext.cs
index b39b5b5..a8c454c 100644
--- a/Infrastructure/OptifitDbContext.cs
+++ b/Infrastructure/OptifitDbContext.cs
@@ -7,6 +7,8 @@ namespace Infrastructure
{
public virtual DbSet Users { get; set; }
public virtual DbSet Exercices { get; set; }
+ public virtual DbSet Sessions { get; set; }
+ public virtual DbSet Programs { get; set; }
public OptifitDbContext()
{
diff --git a/Infrastructure/Repositories/ITrainingProgramRepository.cs b/Infrastructure/Repositories/ITrainingProgramRepository.cs
new file mode 100644
index 0000000..24a14d7
--- /dev/null
+++ b/Infrastructure/Repositories/ITrainingProgramRepository.cs
@@ -0,0 +1,7 @@
+using Infrastructure.Entities;
+
+namespace Infrastructure.Repositories;
+
+public interface ITrainingProgramRepository : IRepository
+{
+}
diff --git a/Infrastructure/Repositories/TrainingProgramRepository.cs b/Infrastructure/Repositories/TrainingProgramRepository.cs
new file mode 100644
index 0000000..c742a6b
--- /dev/null
+++ b/Infrastructure/Repositories/TrainingProgramRepository.cs
@@ -0,0 +1,10 @@
+using Infrastructure.Entities;
+
+namespace Infrastructure.Repositories;
+
+public class TrainingProgramRepository : GenericRepository, ITrainingProgramRepository
+{
+ public TrainingProgramRepository(OptifitDbContext context) : base(context)
+ {
+ }
+}
\ No newline at end of file
diff --git a/Server/Controller/v1/ExercicesController.cs b/Server/Controller/v1/ExercicesController.cs
index 4b7daf7..ef44e5a 100644
--- a/Server/Controller/v1/ExercicesController.cs
+++ b/Server/Controller/v1/ExercicesController.cs
@@ -24,7 +24,6 @@ public class ExercicesController : ControllerBase
[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)
{
@@ -35,7 +34,6 @@ public class ExercicesController : ControllerBase
[HttpGet("{id}")]
[ProducesResponseType(typeof(ResponseExerciceDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
- [RequireHttps]
[AllowAnonymous]
public async Task GetExerciceById(string id)
{
@@ -59,7 +57,6 @@ public class ExercicesController : ControllerBase
[ProducesResponseType(typeof(ResponseExerciceDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
- [RequireHttps]
[AllowAnonymous]
public async Task UpdateExercice(string id, [FromBody] RequestExerciceDto request)
{
diff --git a/Server/Controller/v1/SessionsController.cs b/Server/Controller/v1/SessionsController.cs
index b7b348d..04d7511 100644
--- a/Server/Controller/v1/SessionsController.cs
+++ b/Server/Controller/v1/SessionsController.cs
@@ -1,6 +1,79 @@
-namespace Server.Controller.v1;
+using Asp.Versioning;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Server.Dto.Request;
+using Server.Dto.Response;
+using Server.IServices;
-public class SessionsController
+namespace Server.Controller.v1
{
-
+ [ApiController]
+ [ApiVersion("1.0")]
+ [Route("api/v{version:apiVersion}/[controller]")]
+ public class SessionsController : ControllerBase
+ {
+ private readonly ILogger _logger;
+ private readonly ISessionService _dataServices;
+
+ public SessionsController(ILogger logger, ISessionService dataServices)
+ {
+ _logger = logger;
+ _dataServices = dataServices;
+ }
+
+ [HttpGet]
+ [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status204NoContent)]
+ [AllowAnonymous]
+ public async Task GetSessions([FromQuery] int pageIndex = 1, [FromQuery] int pageSize = 5, [FromQuery] bool ascending = true)
+ {
+ var sessions = await _dataServices.GetSessions(pageIndex, pageSize, ascending);
+ return sessions.TotalCount == 0 ? NoContent() : Ok(sessions);
+ }
+
+ [HttpGet("{id}")]
+ [ProducesResponseType(typeof(ResponseSessionDto), StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status404NotFound)]
+ [AllowAnonymous]
+ public async Task GetSessionById(string id)
+ {
+ var session = await _dataServices.GetSessionById(id);
+ return session == null ? NotFound() : Ok(session);
+ }
+
+ [HttpPost]
+ [ProducesResponseType(typeof(ResponseSessionDto), StatusCodes.Status201Created)]
+ [ProducesResponseType(StatusCodes.Status400BadRequest)]
+ [AllowAnonymous]
+ public async Task CreateSession([FromBody] RequestSessionDto request)
+ {
+ if (!ModelState.IsValid) return BadRequest(ModelState);
+
+ var createdSession = await _dataServices.CreateSession(request);
+ return CreatedAtAction(nameof(GetSessionById), new { id = createdSession.Id }, createdSession);
+ }
+
+ [HttpPut("{id}")]
+ [ProducesResponseType(typeof(ResponseSessionDto), StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status404NotFound)]
+ [ProducesResponseType(StatusCodes.Status400BadRequest)]
+ [AllowAnonymous]
+ public async Task UpdateSession(string id, [FromBody] RequestSessionDto request)
+ {
+ if (!ModelState.IsValid) return BadRequest(ModelState);
+
+ var updatedSession = await _dataServices.UpdateSession(id, request);
+ return updatedSession == null ? NotFound() : Ok(updatedSession);
+ }
+
+ [HttpDelete("{id}")]
+ [ProducesResponseType(StatusCodes.Status204NoContent)]
+ [ProducesResponseType(StatusCodes.Status404NotFound)]
+ [AllowAnonymous]
+ public async Task DeleteSession(string id)
+ {
+ var deleted = await _dataServices.DeleteSession(id);
+ return deleted ? NoContent() : NotFound();
+ }
+ }
}
\ No newline at end of file
diff --git a/Server/Controller/v1/TrainingProgramController.cs b/Server/Controller/v1/TrainingProgramController.cs
new file mode 100644
index 0000000..cd6cd5f
--- /dev/null
+++ b/Server/Controller/v1/TrainingProgramController.cs
@@ -0,0 +1,79 @@
+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 TrainingProgramsController : ControllerBase
+ {
+ private readonly ILogger _logger;
+ private readonly ITrainingProgramService _dataServices;
+
+ public TrainingProgramsController(ILogger logger, ITrainingProgramService dataServices)
+ {
+ _logger = logger;
+ _dataServices = dataServices;
+ }
+
+ [HttpGet]
+ [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status204NoContent)]
+ [AllowAnonymous]
+ public async Task GetTrainingPrograms([FromQuery] int pageIndex = 1, [FromQuery] int pageSize = 5, [FromQuery] bool ascending = true)
+ {
+ var programs = await _dataServices.GetTrainingPrograms(pageIndex, pageSize, ascending);
+ return programs.TotalCount == 0 ? NoContent() : Ok(programs);
+ }
+
+ [HttpGet("{id}")]
+ [ProducesResponseType(typeof(ResponseTrainingProgramDto), StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status404NotFound)]
+ [AllowAnonymous]
+ public async Task GetTrainingProgramById(string id)
+ {
+ var program = await _dataServices.GetTrainingProgramById(id);
+ return program == null ? NotFound() : Ok(program);
+ }
+
+ [HttpPost]
+ [ProducesResponseType(typeof(ResponseTrainingProgramDto), StatusCodes.Status201Created)]
+ [ProducesResponseType(StatusCodes.Status400BadRequest)]
+ [AllowAnonymous]
+ public async Task CreateTrainingProgram([FromBody] RequestTrainingProgramDto request)
+ {
+ if (!ModelState.IsValid) return BadRequest(ModelState);
+
+ var createdProgram = await _dataServices.CreateTrainingProgram(request);
+ return CreatedAtAction(nameof(GetTrainingProgramById), new { id = createdProgram.Id }, createdProgram);
+ }
+
+ [HttpPut("{id}")]
+ [ProducesResponseType(typeof(ResponseTrainingProgramDto), StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status404NotFound)]
+ [ProducesResponseType(StatusCodes.Status400BadRequest)]
+ [AllowAnonymous]
+ public async Task UpdateTrainingProgram(string id, [FromBody] RequestTrainingProgramDto request)
+ {
+ if (!ModelState.IsValid) return BadRequest(ModelState);
+
+ var updatedProgram = await _dataServices.UpdateTrainingProgram(id, request);
+ return updatedProgram == null ? NotFound() : Ok(updatedProgram);
+ }
+
+ [HttpDelete("{id}")]
+ [ProducesResponseType(StatusCodes.Status204NoContent)]
+ [ProducesResponseType(StatusCodes.Status404NotFound)]
+ [AllowAnonymous]
+ public async Task DeleteTrainingProgram(string id)
+ {
+ var deleted = await _dataServices.DeleteTrainingProgram(id);
+ return deleted ? NoContent() : NotFound();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Server/Controller/v1/UsersController.cs b/Server/Controller/v1/UsersController.cs
index 6bc7875..4209c78 100644
--- a/Server/Controller/v1/UsersController.cs
+++ b/Server/Controller/v1/UsersController.cs
@@ -23,7 +23,6 @@ public class UsersController : ControllerBase
[HttpGet]
[ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
- [RequireHttps]
public IActionResult GetUsers([FromQuery] int pageIndex = 1, [FromQuery] int pageSize = 5, [FromQuery] bool ascending = true)
{
var users = _dataServices.GetUsers(pageIndex, pageSize, ascending);
@@ -35,8 +34,6 @@ public class UsersController : ControllerBase
[HttpGet("{id}")]
[ProducesResponseType(typeof(ResponseUserDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
-
- [RequireHttps]
public IActionResult GetAlumniById(string id)
{
var alumni = _dataServices.GetUserById(id);
diff --git a/Server/Dto/Request/RequestSessionDto.cs b/Server/Dto/Request/RequestSessionDto.cs
index ad334a6..b2d2910 100644
--- a/Server/Dto/Request/RequestSessionDto.cs
+++ b/Server/Dto/Request/RequestSessionDto.cs
@@ -1,4 +1,3 @@
-using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Server.Dto.Request
@@ -12,6 +11,6 @@ namespace Server.Dto.Request
public float Duration { get; set; }
- public List Exercices { get; set; } = new List();
+ public List ExerciceIds { get; set; } = new List();
}
}
\ No newline at end of file
diff --git a/Server/Dto/Request/RequestProgramDto.cs b/Server/Dto/Request/RequestTrainingProgramDto.cs
similarity index 90%
rename from Server/Dto/Request/RequestProgramDto.cs
rename to Server/Dto/Request/RequestTrainingProgramDto.cs
index 2fd5c59..bbc4b89 100644
--- a/Server/Dto/Request/RequestProgramDto.cs
+++ b/Server/Dto/Request/RequestTrainingProgramDto.cs
@@ -3,7 +3,7 @@ using System.ComponentModel.DataAnnotations;
namespace Server.Dto.Request
{
- public class RequestProgramDto
+ public class RequestTrainingProgramDto
{
[Required]
public string Name { get; set; }
diff --git a/Server/Dto/Response/ResponseSessionDto.cs b/Server/Dto/Response/ResponseSessionDto.cs
index 351a206..aff29c4 100644
--- a/Server/Dto/Response/ResponseSessionDto.cs
+++ b/Server/Dto/Response/ResponseSessionDto.cs
@@ -1,5 +1,3 @@
-using System.Collections.Generic;
-
namespace Server.Dto.Response
{
public class ResponseSessionDto
diff --git a/Server/Dto/Response/ResponseProgramDto.cs b/Server/Dto/Response/ResponseTrainingProgramDto.cs
similarity index 89%
rename from Server/Dto/Response/ResponseProgramDto.cs
rename to Server/Dto/Response/ResponseTrainingProgramDto.cs
index 39c8998..ac1ec81 100644
--- a/Server/Dto/Response/ResponseProgramDto.cs
+++ b/Server/Dto/Response/ResponseTrainingProgramDto.cs
@@ -2,7 +2,7 @@ using System.Collections.Generic;
namespace Server.Dto.Response
{
- public class ResponseProgramDto
+ public class ResponseTrainingProgramDto
{
public string Id { get; set; }
diff --git a/Server/FirstTest.db b/Server/FirstTest.db
index da709d8..10fd111 100644
Binary files a/Server/FirstTest.db and b/Server/FirstTest.db differ
diff --git a/Server/IServices/ISessionService.cs b/Server/IServices/ISessionService.cs
index 7975f0c..104c5bc 100644
--- a/Server/IServices/ISessionService.cs
+++ b/Server/IServices/ISessionService.cs
@@ -1,6 +1,15 @@
-namespace Server.IServices;
+using Server.Dto.Request;
+using Server.Dto.Response;
+using Shared;
-public class ISessionService
+namespace Server.IServices
{
-
+ public interface ISessionService
+ {
+ Task> GetSessions(int page, int size, bool ascending = true);
+ Task GetSessionById(string id);
+ Task CreateSession(RequestSessionDto request);
+ Task UpdateSession(string id, RequestSessionDto request);
+ Task DeleteSession(string id);
+ }
}
\ No newline at end of file
diff --git a/Server/IServices/ITrainingProgramService.cs b/Server/IServices/ITrainingProgramService.cs
new file mode 100644
index 0000000..3d78d23
--- /dev/null
+++ b/Server/IServices/ITrainingProgramService.cs
@@ -0,0 +1,15 @@
+using Server.Dto.Request;
+using Server.Dto.Response;
+using Shared;
+
+namespace Server.IServices
+{
+ public interface ITrainingProgramService
+ {
+ Task> GetTrainingPrograms(int page, int size, bool ascending = true);
+ Task GetTrainingProgramById(string id);
+ Task CreateTrainingProgram(RequestTrainingProgramDto request);
+ Task UpdateTrainingProgram(string id, RequestTrainingProgramDto request);
+ Task DeleteTrainingProgram(string id);
+ }
+}
\ No newline at end of file
diff --git a/Server/Mappers/PaginatedResultProfile.cs b/Server/Mappers/PaginatedResultProfile.cs
index 3f1ec90..abbef06 100644
--- a/Server/Mappers/PaginatedResultProfile.cs
+++ b/Server/Mappers/PaginatedResultProfile.cs
@@ -1,6 +1,16 @@
-namespace Server.Mappers;
+using AutoMapper;
+using Shared;
+using Infrastructure.Entities;
+using Server.Dto.Response;
-public class PaginatedResultProfile
+namespace Server.Mappers
{
-
+ public class PaginatedResultProfile : Profile
+ {
+ public PaginatedResultProfile()
+ {
+ CreateMap, PaginatedResult>()
+ .ForMember(dest => dest.Data, opt => opt.MapFrom(src => src.Data));
+ }
+ }
}
\ No newline at end of file
diff --git a/Server/Mappers/SessionProfile.cs b/Server/Mappers/SessionProfile.cs
index 16d5291..e57cb4e 100644
--- a/Server/Mappers/SessionProfile.cs
+++ b/Server/Mappers/SessionProfile.cs
@@ -1,6 +1,19 @@
-namespace Server.Mappers;
+using AutoMapper;
+using Infrastructure.Entities;
+using Server.Dto.Request;
+using Server.Dto.Response;
-public class SessionProfile
+namespace Server.Mappers
{
-
+ public class SessionProfile : Profile
+ {
+ public SessionProfile()
+ {
+ CreateMap()
+ .ForMember(dest => dest.Exercices, opt => opt.MapFrom(src => src.Exercices));
+
+ CreateMap()
+ .ForMember(dest => dest.Exercices, opt => opt.Ignore());
+ }
+ }
}
\ No newline at end of file
diff --git a/Server/Mappers/TrainingProgramProfile.cs b/Server/Mappers/TrainingProgramProfile.cs
new file mode 100644
index 0000000..3eb1a08
--- /dev/null
+++ b/Server/Mappers/TrainingProgramProfile.cs
@@ -0,0 +1,19 @@
+using AutoMapper;
+using Infrastructure.Entities;
+using Server.Dto.Request;
+using Server.Dto.Response;
+
+namespace Server.Mappers
+{
+ public class TrainingProgramProfile : Profile
+ {
+ public TrainingProgramProfile()
+ {
+ CreateMap()
+ .ForMember(dest => dest.Sessions, opt => opt.MapFrom(src => src.Sessions));
+
+ CreateMap()
+ .ForMember(dest => dest, opt => opt.Ignore());
+ }
+ }
+}
\ No newline at end of file
diff --git a/Server/Program.cs b/Server/Program.cs
index e4ecf5d..9640653 100644
--- a/Server/Program.cs
+++ b/Server/Program.cs
@@ -13,18 +13,26 @@ var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddScoped();
builder.Services.AddScoped();
+builder.Services.AddScoped();
+builder.Services.AddScoped();
builder.Services.AddScoped();
builder.Services.AddScoped();
+builder.Services.AddScoped();
+builder.Services.AddScoped();
builder.Services.AddControllers();
builder.Services.AddDbContext(options =>
- options.UseSqlite("Data Source=FirstTest.db"));
+ options.UseSqlite("Data Source=../Server/FirstTest.db", b => b.MigrationsAssembly("Infrastructure")));
// Register AutoMapper
builder.Services.AddAutoMapper(typeof(UserProfile));
builder.Services.AddAutoMapper(typeof(ExerciceProfile));
+builder.Services.AddAutoMapper(typeof(SessionProfile));
+builder.Services.AddAutoMapper(typeof(PaginatedResultProfile));
+builder.Services.AddAutoMapper(typeof(TrainingProgramProfile));
+
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
diff --git a/Server/Services/SessionService.cs b/Server/Services/SessionService.cs
index eb953b5..35dd57f 100644
--- a/Server/Services/SessionService.cs
+++ b/Server/Services/SessionService.cs
@@ -1,6 +1,71 @@
-namespace Server.Services;
+using AutoMapper;
+using Infrastructure;
+using Infrastructure.Entities;
+using Infrastructure.Repositories;
+using Server.Dto.Request;
+using Server.Dto.Response;
+using Server.IServices;
+using Shared;
-public class SessionService
+namespace Server.Services
{
-
+ public class SessionService : ISessionService
+ {
+ private readonly OptifitDbContext _context;
+ private readonly ISessionRepository _sessionRepository;
+ private readonly IExerciceRepository _exerciceRepository;
+ private readonly IMapper _mapper;
+
+ public SessionService(OptifitDbContext context, ISessionRepository sessionRepository, IExerciceRepository exerciceRepository, IMapper mapper)
+ {
+ _context = context;
+ _sessionRepository = sessionRepository;
+ _exerciceRepository = exerciceRepository;
+ _mapper = mapper;
+ }
+
+ public async Task> GetSessions(int page, int size, bool ascending = true)
+ {
+ var sessions = await _sessionRepository.GetPaginatedListAsync(page - 1, size, null, null);
+ var result = _mapper.Map>(sessions);
+ return result;
+ }
+
+ public async Task GetSessionById(string id)
+ {
+ var session = await _sessionRepository.GetByIdAsync(id, s => s.Exercices);
+ return session == null ? null : _mapper.Map(session);
+ }
+
+ public async Task CreateSession(RequestSessionDto request)
+ {
+ var session = _mapper.Map(request);
+ session.Exercices = (ICollection)await _exerciceRepository.GetAllAsync(e => request.ExerciceIds.Contains(e.Id));
+ await _sessionRepository.InsertAsync(session);
+ await _context.SaveChangesAsync();
+ return _mapper.Map(session);
+ }
+
+ public async Task UpdateSession(string id, RequestSessionDto request)
+ {
+ var session = await _sessionRepository.GetByIdAsync(id, s => s.Exercices);
+ if (session == null) return null;
+
+ _mapper.Map(request, session);
+ session.Exercices = (ICollection)await _exerciceRepository.GetAllAsync(e => request.ExerciceIds.Contains(e.Id));
+ _sessionRepository.Update(session);
+ await _context.SaveChangesAsync();
+ return _mapper.Map(session);
+ }
+
+ public async Task DeleteSession(string id)
+ {
+ var session = await _sessionRepository.GetByIdAsync(id);
+ if (session == null) return false;
+
+ _sessionRepository.Delete(id);
+ await _context.SaveChangesAsync();
+ return true;
+ }
+ }
}
\ No newline at end of file
diff --git a/Server/Services/TrainingProgramService.cs b/Server/Services/TrainingProgramService.cs
new file mode 100644
index 0000000..8ab11a9
--- /dev/null
+++ b/Server/Services/TrainingProgramService.cs
@@ -0,0 +1,67 @@
+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 TrainingProgramService : ITrainingProgramService
+ {
+ private readonly OptifitDbContext _context;
+ private readonly ITrainingProgramRepository _trainingProgramRepository;
+ private readonly IMapper _mapper;
+
+ public TrainingProgramService(OptifitDbContext context, ITrainingProgramRepository trainingProgramRepository, IMapper mapper)
+ {
+ _context = context;
+ _trainingProgramRepository = trainingProgramRepository;
+ _mapper = mapper;
+ }
+
+ public async Task> GetTrainingPrograms(int page, int size, bool ascending = true)
+ {
+ var programs = await _trainingProgramRepository.GetPaginatedListAsync(page - 1, size, null, null);
+ var result = _mapper.Map>(programs);
+ return result;
+ }
+
+ public async Task GetTrainingProgramById(string id)
+ {
+ var program = await _trainingProgramRepository.GetByIdAsync(id, p => p.Sessions);
+ return program == null ? null : _mapper.Map(program);
+ }
+
+ public async Task CreateTrainingProgram(RequestTrainingProgramDto request)
+ {
+ var program = _mapper.Map(request);
+ await _trainingProgramRepository.InsertAsync(program);
+ await _context.SaveChangesAsync();
+ return _mapper.Map(program);
+ }
+
+ public async Task UpdateTrainingProgram(string id, RequestTrainingProgramDto request)
+ {
+ var program = await _trainingProgramRepository.GetByIdAsync(id, p => p.Sessions);
+ if (program == null) return null;
+
+ _mapper.Map(request, program);
+ _trainingProgramRepository.Update(program);
+ await _context.SaveChangesAsync();
+ return _mapper.Map(program);
+ }
+
+ public async Task DeleteTrainingProgram(string id)
+ {
+ var program = await _trainingProgramRepository.GetByIdAsync(id);
+ if (program == null) return false;
+
+ _trainingProgramRepository.Delete(id);
+ await _context.SaveChangesAsync();
+ return true;
+ }
+ }
+}
\ No newline at end of file