Compare commits
5 Commits
main
...
features/t
Author | SHA1 | Date |
---|---|---|
|
25a830f516 | 1 day ago |
|
f45ba72569 | 1 day ago |
|
2c791baa06 | 3 weeks ago |
|
143ba29d60 | 3 weeks ago |
|
4dc203b705 | 3 weeks ago |
@ -0,0 +1,70 @@
|
|||||||
|
using AutoMapper;
|
||||||
|
using CatalogService.Data;
|
||||||
|
using CatalogService.DTOs;
|
||||||
|
using CatalogService.Entities;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Shared.DTOs;
|
||||||
|
|
||||||
|
namespace CatalogService.Controllers;
|
||||||
|
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
[Route("api/catalog/[controller]")]
|
||||||
|
public class ExercicesTemplateController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly CatalogDbContext _context;
|
||||||
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
|
public ExercicesTemplateController(CatalogDbContext context, IMapper mapper)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
_mapper = mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[AllowAnonymous]
|
||||||
|
public async Task<IActionResult> Create([FromBody] CreateExerciceTemplateDto dto)
|
||||||
|
{
|
||||||
|
var exercice = _mapper.Map<ExerciceTemplate>(dto);
|
||||||
|
_context.Exercices.Add(exercice);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
return CreatedAtAction(nameof(GetById), new { id = exercice.Id }, _mapper.Map<ExerciceTemplateDto>(exercice));
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPut("{id}")]
|
||||||
|
[AllowAnonymous]
|
||||||
|
public async Task<IActionResult> Update(string id, [FromBody] UpdateExerciceTemplateDto dto)
|
||||||
|
{
|
||||||
|
var exercice = await _context.Exercices.FindAsync(id);
|
||||||
|
if (exercice == null) return NotFound();
|
||||||
|
|
||||||
|
_mapper.Map(dto, exercice);
|
||||||
|
exercice.UpdatedAt = DateTime.UtcNow;
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete("{id}")]
|
||||||
|
[AllowAnonymous]
|
||||||
|
public async Task<IActionResult> Delete(string id)
|
||||||
|
{
|
||||||
|
var exercice = await _context.Exercices.FindAsync(id);
|
||||||
|
if (exercice == null) return NotFound();
|
||||||
|
|
||||||
|
_context.Exercices.Remove(exercice);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id}")]
|
||||||
|
[AllowAnonymous]
|
||||||
|
public async Task<ActionResult<ExerciceTemplateDto>> GetById(string id)
|
||||||
|
{
|
||||||
|
var exercice = await _context.Exercices.FindAsync(id);
|
||||||
|
if (exercice == null) return NotFound();
|
||||||
|
|
||||||
|
return _mapper.Map<ExerciceTemplateDto>(exercice);
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
using Shared.Enum;
|
using Shared.Enum;
|
||||||
|
|
||||||
namespace Shared.DTOs;
|
namespace CatalogService.DTOs;
|
||||||
|
|
||||||
public class ExerciceTemplateDto
|
public class ExerciceTemplateDto
|
||||||
{
|
{
|
@ -0,0 +1,17 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using Shared.Enum;
|
||||||
|
|
||||||
|
namespace CatalogService.DTOs;
|
||||||
|
|
||||||
|
public class UpdateExerciceTemplateDto
|
||||||
|
{
|
||||||
|
public string? Name { get; set; }
|
||||||
|
|
||||||
|
public string? Description { get; set; }
|
||||||
|
|
||||||
|
public ETarget? Target { get; set; }
|
||||||
|
|
||||||
|
public string? ImageUrl { get; set; }
|
||||||
|
|
||||||
|
public string? VideoUrl { get; set; }
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
using AutoMapper;
|
||||||
|
using CatalogService.DTOs;
|
||||||
|
using CatalogService.Entities;
|
||||||
|
|
||||||
|
namespace CatalogService.RequestHelpers;
|
||||||
|
|
||||||
|
public class MappingProfiles : Profile
|
||||||
|
{
|
||||||
|
public MappingProfiles()
|
||||||
|
{
|
||||||
|
CreateMap<ExerciceTemplate, ExerciceTemplateDto>();
|
||||||
|
CreateMap<ExerciceTemplateDto, ExerciceTemplate>();
|
||||||
|
CreateMap<CreateExerciceTemplateDto, ExerciceTemplate>();
|
||||||
|
CreateMap<UpdateExerciceTemplateDto, ExerciceTemplate>();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace Shared.DTOs;
|
||||||
|
|
||||||
|
public class DeleteDto
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
public required string Id { get; set; }
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
namespace Shared.Enum;
|
||||||
|
|
||||||
|
public enum EDifficulty
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Beginner,
|
||||||
|
Intermediate,
|
||||||
|
Advanced,
|
||||||
|
Expert
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
namespace Shared.Enum;
|
||||||
|
|
||||||
|
public enum EGoal
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
MuscleGain,
|
||||||
|
WeightLoss,
|
||||||
|
Endurance,
|
||||||
|
Strength,
|
||||||
|
}
|
@ -0,0 +1,231 @@
|
|||||||
|
{
|
||||||
|
"info": {
|
||||||
|
"_postman_id": "c019ebd5-bed6-49ea-a584-086e91bfe503",
|
||||||
|
"name": "Catalog Exercices",
|
||||||
|
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
|
||||||
|
},
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"name": "Créer un exercice",
|
||||||
|
"event": [
|
||||||
|
{
|
||||||
|
"listen": "test",
|
||||||
|
"script": {
|
||||||
|
"exec": [
|
||||||
|
"var jsonData = pm.response.json();",
|
||||||
|
"pm.test('Status code is 201', function() {",
|
||||||
|
" pm.response.to.have.status(201);",
|
||||||
|
"});",
|
||||||
|
"pm.test('L\'exercice a un id', function() {",
|
||||||
|
" pm.expect(jsonData.id).to.be.a('string');",
|
||||||
|
"});",
|
||||||
|
"pm.environment.set('exerciceId', jsonData.id);"
|
||||||
|
],
|
||||||
|
"type": "text/javascript"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Content-Type",
|
||||||
|
"value": "application/json"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{\n \"name\": \"Pompes\",\n \"description\": \"Exercice de musculation pour les pectoraux\",\n \"target\": 1,\n \"imageUrl\": \"images/pompes.jpg\",\n \"videoUrl\": \"https://www.youtube.com/watch?v=IODxDxX7oi4\"\n}"
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "{{catalogApi}}/api/exercices",
|
||||||
|
"host": [
|
||||||
|
"{{catalogApi}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"exercices"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Récupérer l'exercice par id",
|
||||||
|
"event": [
|
||||||
|
{
|
||||||
|
"listen": "test",
|
||||||
|
"script": {
|
||||||
|
"exec": [
|
||||||
|
"var jsonData = pm.response.json();",
|
||||||
|
"pm.test('Status code is 200', function() {",
|
||||||
|
" pm.response.to.have.status(200);",
|
||||||
|
"});",
|
||||||
|
"pm.test('Nom de l\\'exercice est Pompes', function() {",
|
||||||
|
" pm.expect(jsonData.name).to.eq('Pompes');",
|
||||||
|
"});"
|
||||||
|
],
|
||||||
|
"type": "text/javascript"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{catalogApi}}/api/exercices/{{exerciceId}}",
|
||||||
|
"host": [
|
||||||
|
"{{catalogApi}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"exercices",
|
||||||
|
"{{exerciceId}}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Mettre à jour l'exercice",
|
||||||
|
"event": [
|
||||||
|
{
|
||||||
|
"listen": "test",
|
||||||
|
"script": {
|
||||||
|
"exec": [
|
||||||
|
"pm.test('Status code is 204', function() {",
|
||||||
|
" pm.response.to.have.status(204);",
|
||||||
|
"});"
|
||||||
|
],
|
||||||
|
"type": "text/javascript"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"request": {
|
||||||
|
"method": "PUT",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "Content-Type",
|
||||||
|
"value": "application/json"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{\n \"id\": \"{{exerciceId}}\",\n \"name\": \"Pompes modifiées\",\n \"description\": \"Exercice modifié\",\n \"target\": 2,\n \"imageUrl\": \"images/pompes_mod.jpg\",\n \"videoUrl\": \"https://www.youtube.com/watch?v=abcd\"\n}"
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"raw": "{{catalogApi}}/api/exercices/{{exerciceId}}",
|
||||||
|
"host": [
|
||||||
|
"{{catalogApi}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"exercices",
|
||||||
|
"{{exerciceId}}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Vérifier la mise à jour",
|
||||||
|
"event": [
|
||||||
|
{
|
||||||
|
"listen": "test",
|
||||||
|
"script": {
|
||||||
|
"exec": [
|
||||||
|
"var jsonData = pm.response.json();",
|
||||||
|
"pm.test('Status code is 200', function() {",
|
||||||
|
" pm.response.to.have.status(200);",
|
||||||
|
"});",
|
||||||
|
"pm.test('Nom de l\\'exercice est Pompes modifiées', function() {",
|
||||||
|
" pm.expect(jsonData.name).to.eq('Pompes modifiées');",
|
||||||
|
"});"
|
||||||
|
],
|
||||||
|
"type": "text/javascript"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{catalogApi}}/api/exercices/{{exerciceId}}",
|
||||||
|
"host": [
|
||||||
|
"{{catalogApi}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"exercices",
|
||||||
|
"{{exerciceId}}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Supprimer l'exercice",
|
||||||
|
"event": [
|
||||||
|
{
|
||||||
|
"listen": "test",
|
||||||
|
"script": {
|
||||||
|
"exec": [
|
||||||
|
"pm.test('Status code is 204', function() {",
|
||||||
|
" pm.response.to.have.status(204);",
|
||||||
|
"});"
|
||||||
|
],
|
||||||
|
"type": "text/javascript"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"request": {
|
||||||
|
"method": "DELETE",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{catalogApi}}/api/exercices/{{exerciceId}}",
|
||||||
|
"host": [
|
||||||
|
"{{catalogApi}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"exercices",
|
||||||
|
"{{exerciceId}}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Vérifier la suppression",
|
||||||
|
"event": [
|
||||||
|
{
|
||||||
|
"listen": "test",
|
||||||
|
"script": {
|
||||||
|
"exec": [
|
||||||
|
"pm.test('Status code is 404', function() {",
|
||||||
|
" pm.response.to.have.status(404);",
|
||||||
|
"});"
|
||||||
|
],
|
||||||
|
"type": "text/javascript"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{catalogApi}}/api/exercices/{{exerciceId}}",
|
||||||
|
"host": [
|
||||||
|
"{{catalogApi}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"exercices",
|
||||||
|
"{{exerciceId}}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"variable": [
|
||||||
|
{
|
||||||
|
"key": "catalogApi",
|
||||||
|
"value": "http://localhost:5000"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
using AutoMapper;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using TrainingSvc.Data;
|
||||||
|
using TrainingSvc.DTOs;
|
||||||
|
using TrainingSvc.Entities;
|
||||||
|
|
||||||
|
namespace TrainingSvc.Controllers;
|
||||||
|
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/training/[controller]")]
|
||||||
|
public class ExerciceController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly TrainingDbContext _context;
|
||||||
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
|
public ExerciceController(TrainingDbContext context, IMapper mapper)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
_mapper = mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<ActionResult<IEnumerable<ExerciceDto>>> GetAll()
|
||||||
|
{
|
||||||
|
var list = await _context.ExerciceInstances
|
||||||
|
.Include(e => e.ExerciceTemplate)
|
||||||
|
.ToListAsync();
|
||||||
|
return Ok(_mapper.Map<IEnumerable<ExerciceDto>>(list));
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id}")]
|
||||||
|
public async Task<ActionResult<ExerciceDto>> GetById(string id)
|
||||||
|
{
|
||||||
|
var entity = await _context.ExerciceInstances
|
||||||
|
.Include(e => e.ExerciceTemplate)
|
||||||
|
.FirstOrDefaultAsync(e => e.Id == id);
|
||||||
|
if (entity == null) return NotFound();
|
||||||
|
return _mapper.Map<ExerciceDto>(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<ActionResult<ExerciceDto>> Create([FromBody] CreateExerciceInstanceDto dto)
|
||||||
|
{
|
||||||
|
var entity = _mapper.Map<ExerciceInstance>(dto);
|
||||||
|
_context.ExerciceInstances.Add(entity);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
await _context.Entry(entity).Reference(e => e.ExerciceTemplate).LoadAsync();
|
||||||
|
return CreatedAtAction(nameof(GetById), new { id = entity.Id }, _mapper.Map<ExerciceDto>(entity));
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPut("{id}")]
|
||||||
|
public async Task<IActionResult> Update(string id, [FromBody] UpdateExerciceInstanceDto dto)
|
||||||
|
{
|
||||||
|
var entity = await _context.ExerciceInstances
|
||||||
|
.Include(e => e.ExerciceTemplate)
|
||||||
|
.FirstOrDefaultAsync(e => e.Id == id);
|
||||||
|
if (entity == null) return NotFound();
|
||||||
|
_mapper.Map(dto, entity);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete("{id}")]
|
||||||
|
public async Task<IActionResult> Delete(string id)
|
||||||
|
{
|
||||||
|
var entity = await _context.ExerciceInstances.FindAsync(id);
|
||||||
|
if (entity == null) return NotFound();
|
||||||
|
_context.ExerciceInstances.Remove(entity);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
namespace TrainingSvc.DTOs;
|
||||||
|
|
||||||
|
public class CreateExerciceInstanceDto
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string? ExerciceTemplateId { get; set; }
|
||||||
|
public float Duration { get; set; }
|
||||||
|
public int NbSets { get; set; }
|
||||||
|
public int NbReps { get; set; }
|
||||||
|
public float RestingTime { get; set; }
|
||||||
|
public float? Weight { get; set; }
|
||||||
|
public string SessionId { get; set; }
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
namespace TrainingSvc.DTOs;
|
||||||
|
|
||||||
|
public class ExerciceDto
|
||||||
|
{
|
||||||
|
public string Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string? ExerciceTemplateId { get; set; }
|
||||||
|
public float Duration { get; set; }
|
||||||
|
public int NbSets { get; set; }
|
||||||
|
public int NbReps { get; set; }
|
||||||
|
public float RestingTime { get; set; }
|
||||||
|
public float? Weight { get; set; }
|
||||||
|
public bool IsDone { get; set; }
|
||||||
|
public string SessionId { get; set; }
|
||||||
|
|
||||||
|
// Champs du template (préfixés)
|
||||||
|
public string? Name_Template { get; set; }
|
||||||
|
public string? Description_Template { get; set; }
|
||||||
|
public string? ImageUrl_Template { get; set; }
|
||||||
|
public string? VideoUrl_Template { get; set; }
|
||||||
|
public string? Target_Template { get; set; }
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
namespace TrainingSvc.DTOs;
|
||||||
|
|
||||||
|
public class UpdateExerciceInstanceDto
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public float Duration { get; set; }
|
||||||
|
public int NbSets { get; set; }
|
||||||
|
public int NbReps { get; set; }
|
||||||
|
public float RestingTime { get; set; }
|
||||||
|
public float? Weight { get; set; }
|
||||||
|
public bool IsDone { get; set; }
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
using CatalogService.Entities;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using TrainingSvc.Entities;
|
||||||
|
|
||||||
|
namespace TrainingSvc.Data;
|
||||||
|
|
||||||
|
public class TrainingDbContext : DbContext
|
||||||
|
{
|
||||||
|
public TrainingDbContext(DbContextOptions options) : base(options)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public DbSet<ExerciceTemplate> ExerciceTemplates { get; set; }
|
||||||
|
|
||||||
|
public DbSet<ExerciceInstance> ExerciceInstances { get; set; }
|
||||||
|
|
||||||
|
public DbSet<Session> Sessions { get; set; }
|
||||||
|
|
||||||
|
public DbSet<TrainingProgram> TrainingPrograms { get; set; }
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,138 @@
|
|||||||
|
using CatalogService.Entities;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using TrainingSvc.Entities;
|
||||||
|
|
||||||
|
namespace TrainingSvc.Data;
|
||||||
|
|
||||||
|
public class TrainingDbInitializer
|
||||||
|
{
|
||||||
|
public static void InitDb(WebApplication app)
|
||||||
|
{
|
||||||
|
using var scope = app.Services.CreateScope();
|
||||||
|
SeedData(scope.ServiceProvider.GetService<TrainingDbContext>());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SeedData(TrainingDbContext context)
|
||||||
|
{
|
||||||
|
context.Database.Migrate();
|
||||||
|
|
||||||
|
// 1. Seed ExerciceTemplates si vide
|
||||||
|
if (!context.ExerciceTemplates.Any())
|
||||||
|
{
|
||||||
|
var exercices = new List<ExerciceTemplate>()
|
||||||
|
{
|
||||||
|
new ExerciceTemplate
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid().ToString(),
|
||||||
|
Name = "Squat",
|
||||||
|
Description = "Squat is a compound exercise that targets the lower body, primarily the quadriceps, hamstrings, and glutes.",
|
||||||
|
Target = Shared.Enum.ETarget.Legs,
|
||||||
|
ImageUrl = "images/squat.jpg",
|
||||||
|
VideoUrl = "https://www.youtube.com/watch?v=dQw4w9WgXcQ&ab_channel=RickAstley",
|
||||||
|
},
|
||||||
|
new ExerciceTemplate
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid().ToString(),
|
||||||
|
Name = "Bench Press",
|
||||||
|
Description = "Bench Press is a compound exercise that primarily targets the chest, shoulders, and triceps.",
|
||||||
|
Target = Shared.Enum.ETarget.Chest,
|
||||||
|
ImageUrl = "images/bench_press.jpg",
|
||||||
|
VideoUrl = "https://www.youtube.com/watch?v=dQw4w9WgXcQ&ab_channel=RickAstley",
|
||||||
|
},
|
||||||
|
new ExerciceTemplate
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid().ToString(),
|
||||||
|
Name = "Deadlift",
|
||||||
|
Description = "Deadlift is a compound exercise that primarily targets the back, glutes, and hamstrings.",
|
||||||
|
Target = Shared.Enum.ETarget.Back,
|
||||||
|
ImageUrl = "images/deadlift.jpg",
|
||||||
|
VideoUrl = "https://www.youtube.com/watch?v=dQw4w9WgXcQ&ab_channel=RickAstley",
|
||||||
|
},
|
||||||
|
new ExerciceTemplate
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid().ToString(),
|
||||||
|
Name = "Shoulder Press",
|
||||||
|
Description = "Shoulder Press is a compound exercise that primarily targets the shoulders and triceps.",
|
||||||
|
Target = Shared.Enum.ETarget.Arms,
|
||||||
|
ImageUrl = "images/shoulder_press.jpg",
|
||||||
|
VideoUrl = "https://www.youtube.com/watch?v=dQw4w9WgXcQ&ab_channel=RickAstley",
|
||||||
|
},
|
||||||
|
new ExerciceTemplate
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid().ToString(),
|
||||||
|
Name = "Running on Treadmill",
|
||||||
|
Description = "Running on Treadmill is a cardiovascular exercise that primarily targets the legs and improves overall fitness.",
|
||||||
|
Target = Shared.Enum.ETarget.Cardio,
|
||||||
|
ImageUrl = "images/running_treadmill.jpg",
|
||||||
|
VideoUrl = "https://www.youtube.com/watch?v=dQw4w9WgXcQ&ab_channel=RickAstley",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
context.AddRange(exercices);
|
||||||
|
context.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Créer un TrainingProgram si aucun n'existe
|
||||||
|
var program = context.TrainingPrograms.FirstOrDefault();
|
||||||
|
if (program == null)
|
||||||
|
{
|
||||||
|
program = new TrainingProgram
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid().ToString(),
|
||||||
|
Name = "Programme de test"
|
||||||
|
};
|
||||||
|
context.TrainingPrograms.Add(program);
|
||||||
|
context.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Créer une session de test liée au programme si aucune n'existe
|
||||||
|
var session = context.Sessions.FirstOrDefault();
|
||||||
|
if (session == null)
|
||||||
|
{
|
||||||
|
session = new Session
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid().ToString(),
|
||||||
|
Name = "Session de test",
|
||||||
|
TrainingProgramId = program.Id
|
||||||
|
};
|
||||||
|
context.Sessions.Add(session);
|
||||||
|
context.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Seed ExerciceInstances si vide
|
||||||
|
if (!context.ExerciceInstances.Any() && context.ExerciceTemplates.Any())
|
||||||
|
{
|
||||||
|
var templates = context.ExerciceTemplates.ToList();
|
||||||
|
|
||||||
|
var instances = new List<ExerciceInstance>
|
||||||
|
{
|
||||||
|
new ExerciceInstance
|
||||||
|
{
|
||||||
|
Name = "Squat Série 1",
|
||||||
|
ExerciceTemplateId = templates.First().Id,
|
||||||
|
Duration = 60,
|
||||||
|
NbSets = 4,
|
||||||
|
NbReps = 10,
|
||||||
|
RestingTime = 90,
|
||||||
|
Weight = 80,
|
||||||
|
IsDone = false,
|
||||||
|
SessionId = session.Id
|
||||||
|
},
|
||||||
|
new ExerciceInstance
|
||||||
|
{
|
||||||
|
Name = "Bench Press Série 1",
|
||||||
|
ExerciceTemplateId = templates.Skip(1).First().Id,
|
||||||
|
Duration = 45,
|
||||||
|
NbSets = 3,
|
||||||
|
NbReps = 12,
|
||||||
|
RestingTime = 60,
|
||||||
|
Weight = 70,
|
||||||
|
IsDone = false,
|
||||||
|
SessionId = session.Id
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
context.ExerciceInstances.AddRange(instances);
|
||||||
|
context.SaveChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using CatalogService.Entities;
|
||||||
|
using Shared.Entities;
|
||||||
|
|
||||||
|
namespace TrainingSvc.Entities;
|
||||||
|
|
||||||
|
public class ExerciceInstance : EntityBase
|
||||||
|
{
|
||||||
|
public required string Name { get; set; }
|
||||||
|
|
||||||
|
public string? ExerciceTemplateId { get; set; }
|
||||||
|
|
||||||
|
public ExerciceTemplate? ExerciceTemplate { get; set; }
|
||||||
|
|
||||||
|
public float Duration { get; set; }
|
||||||
|
|
||||||
|
public int NbSets { get; set; }
|
||||||
|
|
||||||
|
public int NbReps { get; set; }
|
||||||
|
|
||||||
|
public float RestingTime { get; set; }
|
||||||
|
|
||||||
|
public float? Weight { get; set; }
|
||||||
|
|
||||||
|
public bool IsDone { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public string SessionId { get; set; }
|
||||||
|
|
||||||
|
public Session Session { get; set; }
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using Shared.Entities;
|
||||||
|
using Shared.Enum;
|
||||||
|
|
||||||
|
namespace TrainingSvc.Entities;
|
||||||
|
|
||||||
|
public class Session : EntityBase
|
||||||
|
{
|
||||||
|
public required string Name { get; set; }
|
||||||
|
|
||||||
|
public string? Description { get; set; }
|
||||||
|
|
||||||
|
[Range(1, 7)]
|
||||||
|
public int Day { get; set; }
|
||||||
|
|
||||||
|
public ETarget? Target { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public string TrainingProgramId { get; set; }
|
||||||
|
public TrainingProgram TrainingProgram { get; set; }
|
||||||
|
|
||||||
|
public virtual ICollection<ExerciceInstance> Exercices { get; set; } = new Collection<ExerciceInstance>();
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using Shared.Entities;
|
||||||
|
using Shared.Enum;
|
||||||
|
|
||||||
|
namespace TrainingSvc.Entities;
|
||||||
|
|
||||||
|
public class TrainingProgram : EntityBase
|
||||||
|
{
|
||||||
|
public string Lang { get; set; } = "en";
|
||||||
|
|
||||||
|
public required string Name { get; set; }
|
||||||
|
|
||||||
|
public string? Description { get; set; }
|
||||||
|
|
||||||
|
public int WeekDuration { get; set; } = 4;
|
||||||
|
|
||||||
|
public int NbDays { get; set; } = 3;
|
||||||
|
|
||||||
|
public string OwnerId { get; set; } = "";
|
||||||
|
|
||||||
|
public EGoal Goal { get; set; } = EGoal.MuscleGain;
|
||||||
|
|
||||||
|
public EDifficulty Difficulty { get; set; } = EDifficulty.Beginner;
|
||||||
|
|
||||||
|
public virtual ICollection<Session> Sessions { get; set; } = new Collection<Session>();
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
using TrainingSvc.Data;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
// Add services to the container.
|
||||||
|
builder.Services.AddControllers();
|
||||||
|
builder.Services.AddDbContext<TrainingDbContext>(opt =>
|
||||||
|
{
|
||||||
|
opt.UseNpgsql(builder.Configuration.GetConnectionString("TrainingDb"));
|
||||||
|
|
||||||
|
});
|
||||||
|
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
|
||||||
|
|
||||||
|
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
app.MapControllers();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TrainingDbInitializer.InitDb(app);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
app.Run();
|
||||||
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
|||||||
|
using AutoMapper;
|
||||||
|
using TrainingSvc.DTOs;
|
||||||
|
using TrainingSvc.Entities;
|
||||||
|
using CatalogService.Entities;
|
||||||
|
|
||||||
|
namespace TrainingSvc.RequestHelpers;
|
||||||
|
|
||||||
|
public class ExerciceInstanceProfile : Profile
|
||||||
|
{
|
||||||
|
public ExerciceInstanceProfile()
|
||||||
|
{
|
||||||
|
CreateMap<ExerciceInstance, ExerciceDto>()
|
||||||
|
.ForMember(dest => dest.Name_Template, opt => opt.MapFrom(src => src.ExerciceTemplate != null ? src.ExerciceTemplate.Name : null))
|
||||||
|
.ForMember(dest => dest.Description_Template, opt => opt.MapFrom(src => src.ExerciceTemplate != null ? src.ExerciceTemplate.Description : null))
|
||||||
|
.ForMember(dest => dest.ImageUrl_Template, opt => opt.MapFrom(src => src.ExerciceTemplate != null ? src.ExerciceTemplate.ImageUrl : null))
|
||||||
|
.ForMember(dest => dest.VideoUrl_Template, opt => opt.MapFrom(src => src.ExerciceTemplate != null ? src.ExerciceTemplate.VideoUrl : null))
|
||||||
|
.ForMember(dest => dest.Target_Template, opt => opt.MapFrom(src => src.ExerciceTemplate != null ? src.ExerciceTemplate.Target.ToString() : null));
|
||||||
|
|
||||||
|
CreateMap<CreateExerciceInstanceDto, ExerciceInstance>();
|
||||||
|
CreateMap<UpdateExerciceInstanceDto, ExerciceInstance>();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<InvariantGlobalization>true</InvariantGlobalization>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.15" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.15">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.11" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Shared\Shared.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
@ -0,0 +1,6 @@
|
|||||||
|
@TrainingSvc_HostAddress = http://localhost:5269
|
||||||
|
|
||||||
|
GET {{TrainingSvc_HostAddress}}/weatherforecast/
|
||||||
|
Accept: application/json
|
||||||
|
|
||||||
|
###
|
Loading…
Reference in new issue