refactor: split shared models and DTOs
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
using ASTRAIN.Shared;
|
||||
using ASTRAIN.Shared.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace ASTRAIN.Api.Data;
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using ASTRAIN.Api.Data;
|
||||
using ASTRAIN.Api.Services;
|
||||
using ASTRAIN.Shared;
|
||||
using ASTRAIN.Shared.Dtos;
|
||||
using ASTRAIN.Shared.Models;
|
||||
using ASTRAIN.Shared.Requests;
|
||||
using ASTRAIN.Shared.Responses;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System.Net.Http.Json;
|
||||
using ASTRAIN.Shared;
|
||||
using ASTRAIN.Shared.Dtos;
|
||||
using ASTRAIN.Shared.Requests;
|
||||
using ASTRAIN.Shared.Responses;
|
||||
|
||||
namespace ASTRAIN.Client.Services;
|
||||
|
||||
|
||||
@@ -9,5 +9,7 @@
|
||||
@using ASTRAIN.Client
|
||||
@using ASTRAIN.Client.Layout
|
||||
@using ASTRAIN.Client.Services
|
||||
@using ASTRAIN.Shared
|
||||
@using ASTRAIN.Shared.Dtos
|
||||
@using ASTRAIN.Shared.Requests
|
||||
@using ASTRAIN.Shared.Responses
|
||||
@using ASTRAIN.Client.Pages
|
||||
|
||||
@@ -1,139 +1 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace ASTRAIN.Shared;
|
||||
|
||||
public class User
|
||||
{
|
||||
[Key]
|
||||
[MaxLength(8)]
|
||||
public string Id { get; set; } = string.Empty;
|
||||
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
public List<Exercise> Exercises { get; set; } = new();
|
||||
public List<Routine> Routines { get; set; } = new();
|
||||
}
|
||||
|
||||
public class Exercise
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
[MaxLength(120)]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[Required]
|
||||
[MaxLength(8)]
|
||||
public string UserId { get; set; } = string.Empty;
|
||||
|
||||
public User? User { get; set; }
|
||||
|
||||
public List<RoutineExercise> RoutineExercises { get; set; } = new();
|
||||
}
|
||||
|
||||
public class Routine
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
[MaxLength(120)]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[Required]
|
||||
[MaxLength(8)]
|
||||
public string UserId { get; set; } = string.Empty;
|
||||
|
||||
public User? User { get; set; }
|
||||
|
||||
public List<RoutineExercise> Exercises { get; set; } = new();
|
||||
public List<RoutineRun> Runs { get; set; } = new();
|
||||
}
|
||||
|
||||
public class RoutineExercise
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
public int RoutineId { get; set; }
|
||||
|
||||
public Routine? Routine { get; set; }
|
||||
|
||||
[Required]
|
||||
public int ExerciseId { get; set; }
|
||||
|
||||
public Exercise? Exercise { get; set; }
|
||||
|
||||
public int Order { get; set; }
|
||||
}
|
||||
|
||||
public class RoutineRun
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
public int RoutineId { get; set; }
|
||||
|
||||
public Routine? Routine { get; set; }
|
||||
|
||||
[Required]
|
||||
[MaxLength(8)]
|
||||
public string UserId { get; set; } = string.Empty;
|
||||
|
||||
public DateTime PerformedAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
public List<RoutineRunEntry> Entries { get; set; } = new();
|
||||
}
|
||||
|
||||
public class RoutineRunEntry
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
public int RoutineRunId { get; set; }
|
||||
|
||||
public RoutineRun? RoutineRun { get; set; }
|
||||
|
||||
[Required]
|
||||
public int ExerciseId { get; set; }
|
||||
|
||||
public Exercise? Exercise { get; set; }
|
||||
|
||||
public double Weight { get; set; }
|
||||
|
||||
public bool Completed { get; set; }
|
||||
}
|
||||
|
||||
public record EnsureUserResponse(string UserId);
|
||||
|
||||
public record ExerciseDto(int Id, string Name);
|
||||
|
||||
public record ExerciseUpsertRequest(string Name);
|
||||
|
||||
public record RoutineExerciseDto(int ExerciseId, string Name, int Order);
|
||||
|
||||
public record RoutineDto(int Id, string Name, List<RoutineExerciseDto> Exercises);
|
||||
|
||||
public record RoutineUpsertRequest(string Name, List<int> ExerciseIds);
|
||||
|
||||
public class RoutineRunEntryDto
|
||||
{
|
||||
public int ExerciseId { get; set; }
|
||||
public double Weight { get; set; }
|
||||
public bool Completed { get; set; }
|
||||
|
||||
public RoutineRunEntryDto()
|
||||
{
|
||||
}
|
||||
|
||||
public RoutineRunEntryDto(int exerciseId, double weight, bool completed)
|
||||
{
|
||||
ExerciseId = exerciseId;
|
||||
Weight = weight;
|
||||
Completed = completed;
|
||||
}
|
||||
}
|
||||
|
||||
public record RoutineRunRequest(List<RoutineRunEntryDto> Entries);
|
||||
|
||||
public record RoutineRunSummaryDto(DateTime PerformedAt, List<RoutineRunEntryDto> Entries);
|
||||
// Legacy file intentionally left empty. Types were moved into dedicated files.
|
||||
|
||||
8
src/ASTRAIN.Shared/Dtos/ExerciseDto.cs
Normal file
8
src/ASTRAIN.Shared/Dtos/ExerciseDto.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace ASTRAIN.Shared.Dtos;
|
||||
|
||||
/// <summary>
|
||||
/// Data transfer object for an exercise.
|
||||
/// </summary>
|
||||
/// <param name="Id">Exercise identifier.</param>
|
||||
/// <param name="Name">Exercise name.</param>
|
||||
public record ExerciseDto(int Id, string Name);
|
||||
9
src/ASTRAIN.Shared/Dtos/RoutineDto.cs
Normal file
9
src/ASTRAIN.Shared/Dtos/RoutineDto.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace ASTRAIN.Shared.Dtos;
|
||||
|
||||
/// <summary>
|
||||
/// Data transfer object for a routine and its exercises.
|
||||
/// </summary>
|
||||
/// <param name="Id">Routine identifier.</param>
|
||||
/// <param name="Name">Routine name.</param>
|
||||
/// <param name="Exercises">Ordered exercises.</param>
|
||||
public record RoutineDto(int Id, string Name, List<RoutineExerciseDto> Exercises);
|
||||
9
src/ASTRAIN.Shared/Dtos/RoutineExerciseDto.cs
Normal file
9
src/ASTRAIN.Shared/Dtos/RoutineExerciseDto.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace ASTRAIN.Shared.Dtos;
|
||||
|
||||
/// <summary>
|
||||
/// Data transfer object for a routine exercise entry.
|
||||
/// </summary>
|
||||
/// <param name="ExerciseId">Exercise identifier.</param>
|
||||
/// <param name="Name">Exercise name.</param>
|
||||
/// <param name="Order">Order within the routine.</param>
|
||||
public record RoutineExerciseDto(int ExerciseId, string Name, int Order);
|
||||
39
src/ASTRAIN.Shared/Dtos/RoutineRunEntryDto.cs
Normal file
39
src/ASTRAIN.Shared/Dtos/RoutineRunEntryDto.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
namespace ASTRAIN.Shared.Dtos;
|
||||
|
||||
/// <summary>
|
||||
/// Data transfer object for a routine run entry.
|
||||
/// </summary>
|
||||
public class RoutineRunEntryDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the exercise identifier.
|
||||
/// </summary>
|
||||
public int ExerciseId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the weight used.
|
||||
/// </summary>
|
||||
public double Weight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the exercise was completed.
|
||||
/// </summary>
|
||||
public bool Completed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance for serialization.
|
||||
/// </summary>
|
||||
public RoutineRunEntryDto()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance with values.
|
||||
/// </summary>
|
||||
public RoutineRunEntryDto(int exerciseId, double weight, bool completed)
|
||||
{
|
||||
ExerciseId = exerciseId;
|
||||
Weight = weight;
|
||||
Completed = completed;
|
||||
}
|
||||
}
|
||||
8
src/ASTRAIN.Shared/Dtos/RoutineRunSummaryDto.cs
Normal file
8
src/ASTRAIN.Shared/Dtos/RoutineRunSummaryDto.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace ASTRAIN.Shared.Dtos;
|
||||
|
||||
/// <summary>
|
||||
/// Data transfer object for a routine run summary.
|
||||
/// </summary>
|
||||
/// <param name="PerformedAt">Run timestamp in UTC.</param>
|
||||
/// <param name="Entries">Entries recorded in the run.</param>
|
||||
public record RoutineRunSummaryDto(DateTime PerformedAt, List<RoutineRunEntryDto> Entries);
|
||||
38
src/ASTRAIN.Shared/Models/Exercise.cs
Normal file
38
src/ASTRAIN.Shared/Models/Exercise.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace ASTRAIN.Shared.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a single exercise item (e.g., a machine or movement).
|
||||
/// </summary>
|
||||
public class Exercise
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the database identifier.
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the exercise display name.
|
||||
/// </summary>
|
||||
[Required]
|
||||
[MaxLength(120)]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the owning user's identifier.
|
||||
/// </summary>
|
||||
[Required]
|
||||
[MaxLength(8)]
|
||||
public string UserId { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the owning user.
|
||||
/// </summary>
|
||||
public User? User { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets routine associations for this exercise.
|
||||
/// </summary>
|
||||
public List<RoutineExercise> RoutineExercises { get; set; } = new();
|
||||
}
|
||||
43
src/ASTRAIN.Shared/Models/Routine.cs
Normal file
43
src/ASTRAIN.Shared/Models/Routine.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace ASTRAIN.Shared.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a routine consisting of ordered exercises.
|
||||
/// </summary>
|
||||
public class Routine
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the database identifier.
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the routine name.
|
||||
/// </summary>
|
||||
[Required]
|
||||
[MaxLength(120)]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the owning user's identifier.
|
||||
/// </summary>
|
||||
[Required]
|
||||
[MaxLength(8)]
|
||||
public string UserId { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the owning user.
|
||||
/// </summary>
|
||||
public User? User { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ordered exercises in this routine.
|
||||
/// </summary>
|
||||
public List<RoutineExercise> Exercises { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the run history for this routine.
|
||||
/// </summary>
|
||||
public List<RoutineRun> Runs { get; set; } = new();
|
||||
}
|
||||
41
src/ASTRAIN.Shared/Models/RoutineExercise.cs
Normal file
41
src/ASTRAIN.Shared/Models/RoutineExercise.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace ASTRAIN.Shared.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Join entity linking a routine to an exercise with an explicit order.
|
||||
/// </summary>
|
||||
public class RoutineExercise
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the database identifier.
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the routine identifier.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int RoutineId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the routine.
|
||||
/// </summary>
|
||||
public Routine? Routine { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the exercise identifier.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int ExerciseId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the exercise.
|
||||
/// </summary>
|
||||
public Exercise? Exercise { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the display order within the routine.
|
||||
/// </summary>
|
||||
public int Order { get; set; }
|
||||
}
|
||||
42
src/ASTRAIN.Shared/Models/RoutineRun.cs
Normal file
42
src/ASTRAIN.Shared/Models/RoutineRun.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace ASTRAIN.Shared.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a single execution of a routine.
|
||||
/// </summary>
|
||||
public class RoutineRun
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the database identifier.
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the routine identifier.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int RoutineId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the routine.
|
||||
/// </summary>
|
||||
public Routine? Routine { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the user identifier for this run.
|
||||
/// </summary>
|
||||
[Required]
|
||||
[MaxLength(8)]
|
||||
public string UserId { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the run timestamp in UTC.
|
||||
/// </summary>
|
||||
public DateTime PerformedAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the entries completed during the run.
|
||||
/// </summary>
|
||||
public List<RoutineRunEntry> Entries { get; set; } = new();
|
||||
}
|
||||
46
src/ASTRAIN.Shared/Models/RoutineRunEntry.cs
Normal file
46
src/ASTRAIN.Shared/Models/RoutineRunEntry.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace ASTRAIN.Shared.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Represents an exercise entry within a routine run.
|
||||
/// </summary>
|
||||
public class RoutineRunEntry
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the database identifier.
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the parent routine run identifier.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int RoutineRunId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the parent routine run.
|
||||
/// </summary>
|
||||
public RoutineRun? RoutineRun { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the exercise identifier.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int ExerciseId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the exercise.
|
||||
/// </summary>
|
||||
public Exercise? Exercise { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the used weight.
|
||||
/// </summary>
|
||||
public double Weight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the exercise was completed.
|
||||
/// </summary>
|
||||
public bool Completed { get; set; }
|
||||
}
|
||||
31
src/ASTRAIN.Shared/Models/User.cs
Normal file
31
src/ASTRAIN.Shared/Models/User.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace ASTRAIN.Shared.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Represents an application user identified by an 8-character key.
|
||||
/// </summary>
|
||||
public class User
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the unique 8-character user identifier.
|
||||
/// </summary>
|
||||
[Key]
|
||||
[MaxLength(8)]
|
||||
public string Id { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the creation timestamp in UTC.
|
||||
/// </summary>
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the exercises owned by this user.
|
||||
/// </summary>
|
||||
public List<Exercise> Exercises { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the routines owned by this user.
|
||||
/// </summary>
|
||||
public List<Routine> Routines { get; set; } = new();
|
||||
}
|
||||
7
src/ASTRAIN.Shared/Requests/ExerciseUpsertRequest.cs
Normal file
7
src/ASTRAIN.Shared/Requests/ExerciseUpsertRequest.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace ASTRAIN.Shared.Requests;
|
||||
|
||||
/// <summary>
|
||||
/// Request payload to create or update an exercise.
|
||||
/// </summary>
|
||||
/// <param name="Name">Exercise name.</param>
|
||||
public record ExerciseUpsertRequest(string Name);
|
||||
9
src/ASTRAIN.Shared/Requests/RoutineRunRequest.cs
Normal file
9
src/ASTRAIN.Shared/Requests/RoutineRunRequest.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using ASTRAIN.Shared.Dtos;
|
||||
|
||||
namespace ASTRAIN.Shared.Requests;
|
||||
|
||||
/// <summary>
|
||||
/// Request payload to save a routine run.
|
||||
/// </summary>
|
||||
/// <param name="Entries">Run entries.</param>
|
||||
public record RoutineRunRequest(List<RoutineRunEntryDto> Entries);
|
||||
8
src/ASTRAIN.Shared/Requests/RoutineUpsertRequest.cs
Normal file
8
src/ASTRAIN.Shared/Requests/RoutineUpsertRequest.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace ASTRAIN.Shared.Requests;
|
||||
|
||||
/// <summary>
|
||||
/// Request payload to create or update a routine.
|
||||
/// </summary>
|
||||
/// <param name="Name">Routine name.</param>
|
||||
/// <param name="ExerciseIds">Ordered exercise identifiers.</param>
|
||||
public record RoutineUpsertRequest(string Name, List<int> ExerciseIds);
|
||||
7
src/ASTRAIN.Shared/Responses/EnsureUserResponse.cs
Normal file
7
src/ASTRAIN.Shared/Responses/EnsureUserResponse.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace ASTRAIN.Shared.Responses;
|
||||
|
||||
/// <summary>
|
||||
/// Response payload for ensuring a user exists.
|
||||
/// </summary>
|
||||
/// <param name="UserId">The resolved user identifier.</param>
|
||||
public record EnsureUserResponse(string UserId);
|
||||
Reference in New Issue
Block a user