Refactoring, database structure changed

This commit is contained in:
2025-03-03 00:56:32 +01:00
Unverified
parent d3805ef3db
commit c603c41c0b
913 changed files with 21764 additions and 32775 deletions

View File

@@ -0,0 +1,108 @@
using WatchIt.Database.Model.People;
using WatchIt.DTO.Models.Controllers.Genders;
using WatchIt.DTO.Models.Controllers.People.Person;
using WatchIt.DTO.Models.Generics.Image;
using WatchIt.DTO.Models.Generics.Rating;
using WatchIt.DTO.Models.Generics.ViewCount;
namespace WatchIt.DTO.Models.Controllers.People;
public static class PeopleMappers
{
#region PUBLIC METHODS
#region Person
public static Database.Model.People.Person ToEntity(this PersonRequest request) => new Database.Model.People.Person
{
Name = request.Name,
FullName = request.FullName,
Description = request.Description,
BirthDate = request.BirthDate,
DeathDate = request.DeathDate,
GenderId = request.GenderId,
};
public static void UpdateWithRequest(this Database.Model.People.Person entity, PersonRequest request)
{
entity.Name = request.Name;
entity.FullName = request.FullName;
entity.Description = request.Description;
entity.BirthDate = request.BirthDate;
entity.DeathDate = request.DeathDate;
entity.GenderId = request.GenderId;
}
public static PersonResponse ToResponse(this Database.Model.People.Person entity)
{
PersonResponse response = new PersonResponse();
response.SetPersonResponseProperties(entity);
return response;
}
public static PersonUserRatedResponse ToResponse(this Database.Model.People.Person entity, long accountId)
{
PersonUserRatedResponse response = new PersonUserRatedResponse();
response.SetPersonResponseProperties(entity);
response.RatingUser = entity.Roles
.SelectMany(x => x.Ratings
.Where(y => y.AccountId == accountId))
.ToUserOverallResponse();
return response;
}
public static PersonRequest ToRequest(this PersonResponse response) => new PersonRequest
{
Name = response.Name,
FullName = response.FullName,
Description = response.Description,
BirthDate = response.BirthDate,
DeathDate = response.DeathDate,
GenderId = response.Gender?.Id,
};
#endregion
#region PersonPicture
public static Database.Model.People.PersonPicture ToEntity(this ImageRequest request, long personId) => new Database.Model.People.PersonPicture
{
PersonId = personId,
Image = request.Image,
MimeType = request.MimeType,
};
#endregion
#region MediumViewCount
public static PersonViewCount CreatePersonViewCountEntity(long personId) => new PersonViewCount
{
PersonId = personId,
ViewCount = 1,
};
#endregion
#endregion
#region PRIVATE METHODS
private static void SetPersonResponseProperties(this PersonResponse response, Database.Model.People.Person entity)
{
response.Id = entity.Id;
response.Name = entity.Name;
response.FullName = entity.FullName;
response.Description = entity.Description;
response.BirthDate = entity.BirthDate;
response.DeathDate = entity.DeathDate;
response.Gender = entity.Gender?.ToResponse();
response.Rating = entity.Roles.SelectMany(x => x.Ratings).ToOverallResponse();
response.ViewCount = entity.ViewCounts.ToResponse();
response.Picture = entity.Picture?.ToResponse();
}
#endregion
}

View File

@@ -0,0 +1,13 @@
using WatchIt.DTO.Query;
namespace WatchIt.DTO.Models.Controllers.People.Person.Filters;
public record PersonBirthDateFromFilter : Filter<Database.Model.People.Person>
{
public PersonBirthDateFromFilter(DateOnly? query) : base(x =>
(
query == null
||
x.BirthDate >= query
)) { }
}

View File

@@ -0,0 +1,13 @@
using WatchIt.DTO.Query;
namespace WatchIt.DTO.Models.Controllers.People.Person.Filters;
public record PersonBirthDateToFilter : Filter<Database.Model.People.Person>
{
public PersonBirthDateToFilter(DateOnly? query) : base(x =>
(
query == null
||
x.BirthDate <= query
)) { }
}

View File

@@ -0,0 +1,13 @@
using WatchIt.DTO.Query;
namespace WatchIt.DTO.Models.Controllers.People.Person.Filters;
public record PersonDeathDateFromFilter : Filter<Database.Model.People.Person>
{
public PersonDeathDateFromFilter(DateOnly? query) : base(x =>
(
query == null
||
x.DeathDate >= query
)) { }
}

View File

@@ -0,0 +1,13 @@
using WatchIt.DTO.Query;
namespace WatchIt.DTO.Models.Controllers.People.Person.Filters;
public record PersonDeathDateToFilter : Filter<Database.Model.People.Person>
{
public PersonDeathDateToFilter(DateOnly? query) : base(x =>
(
query == null
||
x.DeathDate <= query
)) { }
}

View File

@@ -0,0 +1,18 @@
using System.Text.RegularExpressions;
using WatchIt.DTO.Query;
namespace WatchIt.DTO.Models.Controllers.People.Person.Filters;
public record PersonDescriptionFilter : Filter<Database.Model.People.Person>
{
public PersonDescriptionFilter(string? descriptionRegex) : base(x =>
(
string.IsNullOrWhiteSpace(descriptionRegex)
||
(
!string.IsNullOrWhiteSpace(x.Description)
&&
Regex.IsMatch(x.Description, descriptionRegex, RegexOptions.IgnoreCase)
)
)) { }
}

View File

@@ -0,0 +1,18 @@
using System.Text.RegularExpressions;
using WatchIt.DTO.Query;
namespace WatchIt.DTO.Models.Controllers.People.Person.Filters;
public record PersonFullNameFilter : Filter<Database.Model.People.Person>
{
public PersonFullNameFilter(string? fullNameRegex) : base(x =>
(
string.IsNullOrWhiteSpace(fullNameRegex)
||
(
!string.IsNullOrWhiteSpace(x.FullName)
&&
Regex.IsMatch(x.FullName, fullNameRegex, RegexOptions.IgnoreCase)
)
)) { }
}

View File

@@ -0,0 +1,13 @@
using WatchIt.DTO.Query;
namespace WatchIt.DTO.Models.Controllers.People.Person.Filters;
public record PersonGenderIdFilter : Filter<Database.Model.People.Person>
{
public PersonGenderIdFilter(short? query) : base(x =>
(
query == null
||
x.GenderId == query
)) { }
}

View File

@@ -0,0 +1,18 @@
using System.Text.RegularExpressions;
using WatchIt.DTO.Query;
namespace WatchIt.DTO.Models.Controllers.People.Person.Filters;
public record PersonNameFilter : Filter<Database.Model.People.Person>
{
public PersonNameFilter(string? nameRegex) : base(x =>
(
string.IsNullOrWhiteSpace(nameRegex)
||
(
!string.IsNullOrWhiteSpace(x.Name)
&&
Regex.IsMatch(x.Name, nameRegex, RegexOptions.IgnoreCase)
)
)) { }
}

View File

@@ -0,0 +1,17 @@
using WatchIt.DTO.Query;
namespace WatchIt.DTO.Models.Controllers.People.Person.Filters;
public record PersonRatingAverageFromFilter : Filter<Database.Model.People.Person>
{
public PersonRatingAverageFromFilter(decimal? query) : base(x =>
(
query == null
||
(
x.Roles.SelectMany(y => y.Ratings).Any()
&&
(decimal)x.Roles.SelectMany(y => y.Ratings).Average(y => y.Rating) >= query
)
)) { }
}

View File

@@ -0,0 +1,17 @@
using WatchIt.DTO.Query;
namespace WatchIt.DTO.Models.Controllers.People.Person.Filters;
public record PersonRatingAverageToFilter : Filter<Database.Model.People.Person>
{
public PersonRatingAverageToFilter(decimal? query) : base(x =>
(
query == null
||
(
x.Roles.SelectMany(y => y.Ratings).Any()
&&
(decimal)x.Roles.SelectMany(y => y.Ratings).Average(y => y.Rating) <= query
)
)) { }
}

View File

@@ -0,0 +1,13 @@
using WatchIt.DTO.Query;
namespace WatchIt.DTO.Models.Controllers.People.Person.Filters;
public record PersonRatingCountFromFilter : Filter<Database.Model.People.Person>
{
public PersonRatingCountFromFilter(long? query) : base(x =>
(
query == null
||
x.Roles.SelectMany(y => y.Ratings).Count() >= query
)) { }
}

View File

@@ -0,0 +1,13 @@
using WatchIt.DTO.Query;
namespace WatchIt.DTO.Models.Controllers.People.Person.Filters;
public record PersonRatingCountToFilter : Filter<Database.Model.People.Person>
{
public PersonRatingCountToFilter(long? query) : base(x =>
(
query == null
||
x.Roles.SelectMany(y => y.Ratings).Count() <= query
)) { }
}

View File

@@ -0,0 +1,22 @@
using WatchIt.DTO.Query;
namespace WatchIt.DTO.Models.Controllers.People.Person.Filters;
public record PersonRatingUserAverageFromFilter : Filter<Database.Model.People.Person>
{
public PersonRatingUserAverageFromFilter(decimal? query, long accountId) : base(x =>
(
query == null
||
(
x.Roles
.SelectMany(y => y.Ratings)
.Any(y => y.AccountId == accountId)
&&
(decimal)x.Roles
.SelectMany(y => y.Ratings)
.Where(y => y.AccountId == accountId)
.Average(y => y.Rating) >= query
)
)) { }
}

View File

@@ -0,0 +1,22 @@
using WatchIt.DTO.Query;
namespace WatchIt.DTO.Models.Controllers.People.Person.Filters;
public record PersonRatingUserAverageToFilter : Filter<Database.Model.People.Person>
{
public PersonRatingUserAverageToFilter(decimal? query, long accountId) : base(x =>
(
query == null
||
(
x.Roles
.SelectMany(y => y.Ratings)
.Any(y => y.AccountId == accountId)
&&
(decimal)x.Roles
.SelectMany(y => y.Ratings)
.Where(y => y.AccountId == accountId)
.Average(y => y.Rating) <= query
)
)) { }
}

View File

@@ -0,0 +1,15 @@
using WatchIt.DTO.Query;
namespace WatchIt.DTO.Models.Controllers.People.Person.Filters;
public record PersonRatingUserCountFromFilter : Filter<Database.Model.People.Person>
{
public PersonRatingUserCountFromFilter(long? query, long accountId) : base(x =>
(
query == null
||
x.Roles
.SelectMany(y => y.Ratings)
.Count(y => y.AccountId == accountId) >= query
)) { }
}

View File

@@ -0,0 +1,15 @@
using WatchIt.DTO.Query;
namespace WatchIt.DTO.Models.Controllers.People.Person.Filters;
public record PersonRatingUserCountToFilter : Filter<Database.Model.People.Person>
{
public PersonRatingUserCountToFilter(long? query, long accountId) : base(x =>
(
query == null
||
x.Roles
.SelectMany(y => y.Ratings)
.Count(y => y.AccountId == accountId) <= query
)) { }
}

View File

@@ -0,0 +1,22 @@
using WatchIt.DTO.Query;
namespace WatchIt.DTO.Models.Controllers.People.Person.Filters;
public record PersonRatingUserLastRatingDateFromFilter : Filter<Database.Model.People.Person>
{
public PersonRatingUserLastRatingDateFromFilter(DateOnly? query, long accountId) : base(x =>
(
query == null
||
(
x.Roles
.SelectMany(y => y.Ratings)
.Any(y => y.AccountId == accountId)
&&
x.Roles
.SelectMany(y => y.Ratings)
.Where(y => y.AccountId == accountId)
.Max(y => y.Date) >= query.Value.ToDateTime(new TimeOnly(0, 0))
)
)) { }
}

View File

@@ -0,0 +1,22 @@
using WatchIt.DTO.Query;
namespace WatchIt.DTO.Models.Controllers.People.Person.Filters;
public record PersonRatingUserLastRatingDateToFilter : Filter<Database.Model.People.Person>
{
public PersonRatingUserLastRatingDateToFilter(DateOnly? query, long accountId) : base(x =>
(
query == null
||
(
x.Roles
.SelectMany(y => y.Ratings)
.Any(y => y.AccountId == accountId)
&&
x.Roles
.SelectMany(y => y.Ratings)
.Where(y => y.AccountId == accountId)
.Max(y => y.Date) <= query.Value.ToDateTime(new TimeOnly(23, 59))
)
)) { }
}

View File

@@ -0,0 +1,30 @@
using System.Linq.Expressions;
namespace WatchIt.DTO.Models.Controllers.People.Person;
public class PersonOrderKeys
{
public static readonly Dictionary<string, Expression<Func<Database.Model.People.Person, object?>>> Base = new Dictionary<string, Expression<Func<Database.Model.People.Person, object?>>>
{
{ "id", x => x.Id },
{ "name", x => x.Name },
{ "full_name", x => x.FullName },
{ "description", x => x.Description },
{ "birth_date", x => x.BirthDate },
{ "death_date", x => x.BirthDate },
{ "gender", x => x.Gender != null ? x.Gender.Name : null },
{ "rating.average", x => x.Roles.SelectMany(y => y.Ratings).Any() ? x.Roles.SelectMany(y => y.Ratings).Average(y => y.Rating) : 0 },
{ "rating.count", x => x.Roles.SelectMany(y => y.Ratings).Count() },
{ "view_count.last_24_hours", x => x.ViewCounts.Where(y => y.Date >= DateOnly.FromDateTime(DateTime.Now.AddDays(-1))).Sum(y => y.ViewCount) },
{ "view_count.last_week", x => x.ViewCounts.Where(y => y.Date >= DateOnly.FromDateTime(DateTime.Now.AddDays(-7))).Sum(y => y.ViewCount) },
{ "view_count.last_month", x => x.ViewCounts.Where(y => y.Date >= DateOnly.FromDateTime(DateTime.Now.AddMonths(-1))).Sum(y => y.ViewCount) },
{ "view_count.last_year", x => x.ViewCounts.Where(y => y.Date >= DateOnly.FromDateTime(DateTime.Now.AddYears(-1))).Sum(y => y.ViewCount) }
};
public static Dictionary<string, Expression<Func<Database.Model.People.Person, object?>>> UserRated(long accountId) => new Dictionary<string, Expression<Func<Database.Model.People.Person, object?>>>
{
{ "rating_user.average", x => x.Roles.SelectMany(y => y.Ratings).Where(y => y.AccountId == accountId).Average(y => y.Rating) },
{ "rating_user.count", x => x.Roles.SelectMany(y => y.Ratings).Count(y => y.AccountId == accountId) },
{ "rating_user.last_date", x => x.Roles.SelectMany(y => y.Ratings).Where(y => y.AccountId == accountId).Max(y => y.Date) },
};
}

View File

@@ -0,0 +1,15 @@
namespace WatchIt.DTO.Models.Controllers.People.Person;
public class PersonRequest
{
#region PROPERTIES
public string Name { get; set; } = null!;
public string? FullName { get; set; }
public string? Description { get; set; }
public DateOnly? BirthDate { get; set; }
public DateOnly? DeathDate { get; set; }
public short? GenderId { get; set; }
#endregion
}

View File

@@ -0,0 +1,22 @@
using FluentValidation;
using WatchIt.Database;
namespace WatchIt.DTO.Models.Controllers.People.Person;
public class PersonRequestValidator : AbstractValidator<PersonRequest>
{
#region CONSTRUCTORS
public PersonRequestValidator(DatabaseContext database)
{
RuleFor(x => x.Name).NotEmpty()
.MaximumLength(100);
RuleFor(x => x.FullName).MaximumLength(200);
RuleFor(x => x.Description).MaximumLength(1000);
When(x => x.GenderId.HasValue, () =>
{
RuleFor(x => x.GenderId!.Value).MustBeIn(database.Genders.Select(g => g.Id));
});
}
#endregion
}

View File

@@ -0,0 +1,24 @@
using WatchIt.DTO.Models.Controllers.Genders.Gender;
using WatchIt.DTO.Models.Generics.Image;
using WatchIt.DTO.Models.Generics.Rating;
using WatchIt.DTO.Models.Generics.ViewCount;
namespace WatchIt.DTO.Models.Controllers.People.Person;
public class PersonResponse
{
#region PROPERTIES
public long Id { get; set; }
public string Name { get; set; } = null!;
public string? FullName { get; set; }
public string? Description { get; set; }
public DateOnly? BirthDate { get; set; }
public DateOnly? DeathDate { get; set; }
public GenderResponse? Gender { get; set; }
public RatingOverallResponse Rating { get; set; } = null!;
public ViewCountResponse ViewCount { get; set; } = null!;
public ImageResponse? Picture { get; set; }
#endregion
}

View File

@@ -0,0 +1,12 @@
using WatchIt.DTO.Models.Generics.Rating;
namespace WatchIt.DTO.Models.Controllers.People.Person;
public class PersonUserRatedResponse : PersonResponse
{
#region PROPERTIES
public RatingUserOverallResponse RatingUser { get; set; } = null!;
#endregion
}

View File

@@ -0,0 +1,81 @@
using Microsoft.AspNetCore.Mvc;
using Refit;
using WatchIt.DTO.Models.Controllers.People.Person.Filters;
using WatchIt.DTO.Query;
namespace WatchIt.DTO.Models.Controllers.People.Person.Query;
public class PersonFilterQuery : IFilterQuery<Database.Model.People.Person>
{
#region PROPERTIES
[FromQuery(Name = "name")]
public string? Name { get; set; }
[FromQuery(Name = "full_name")]
[AliasAs("full_name")]
public string? FullName { get; set; }
[FromQuery(Name = "description")]
public string? Description { get; set; }
[FromQuery(Name = "birth_date_from")]
[AliasAs("birth_date_from")]
public DateOnly? BirthDateFrom { get; set; }
[FromQuery(Name = "birth_date_to")]
[AliasAs("birth_date_to")]
public DateOnly? BirthDateTo { get; set; }
[FromQuery(Name = "death_date_from")]
[AliasAs("death_date_from")]
public DateOnly? DeathDateFrom { get; set; }
[FromQuery(Name = "death_date_to")]
[AliasAs("death_date_to")]
public DateOnly? DeathDateTo { get; set; }
[FromQuery(Name = "gender_id")]
[AliasAs("gender_id")]
public short? GenderId { get; set; }
[FromQuery(Name = "rating_average_from")]
[AliasAs("rating_average_from")]
public decimal? RatingAverageFrom { get; set; }
[FromQuery(Name = "rating_average_to")]
[AliasAs("rating_average_to")]
public decimal? RatingAverageTo { get; set; }
[FromQuery(Name = "rating_count_from")]
[AliasAs("rating_count_from")]
public long? RatingCountFrom { get; set; }
[FromQuery(Name = "rating_count_to")]
[AliasAs("rating_count_to")]
public long? RatingCountTo { get; set; }
#endregion
#region PUBLIC METHODS
public IEnumerable<Filter<Database.Model.People.Person>> GetFilters() =>
[
new PersonNameFilter(Name),
new PersonFullNameFilter(FullName),
new PersonDescriptionFilter(Description),
new PersonBirthDateFromFilter(BirthDateFrom),
new PersonBirthDateToFilter(BirthDateTo),
new PersonDeathDateFromFilter(DeathDateFrom),
new PersonDeathDateToFilter(DeathDateTo),
new PersonGenderIdFilter(GenderId),
new PersonRatingAverageFromFilter(RatingAverageFrom),
new PersonRatingAverageToFilter(RatingAverageTo),
new PersonRatingCountFromFilter(RatingCountFrom),
new PersonRatingCountToFilter(RatingCountTo),
];
#endregion
}

View File

@@ -0,0 +1,57 @@
using Microsoft.AspNetCore.Mvc;
using Refit;
using WatchIt.DTO.Models.Controllers.People.Person.Filters;
using WatchIt.DTO.Query;
namespace WatchIt.DTO.Models.Controllers.People.Person.Query;
public class PersonUserRatedFilterQuery : IFilterQuery<Database.Model.People.Person>
{
#region PROPERTIES
[FromQuery(Name = "rating_user_average_from")]
[AliasAs("rating_user_average_from")]
public decimal? RatingUserAverageFrom { get; set; }
[FromQuery(Name = "rating_user_average_to")]
[AliasAs("rating_user_average_to")]
public decimal? RatingUserAverageTo { get; set; }
[FromQuery(Name = "rating_user_count_from")]
[AliasAs("rating_user_count_from")]
public long? RatingUserCountFrom { get; set; }
[FromQuery(Name = "rating_user_count_to")]
[AliasAs("rating_user_count_to")]
public long? RatingUserCountTo { get; set; }
[FromQuery(Name = "rating_user_last_rating_date_from")]
[AliasAs("rating_user_last_rating_date_from")]
public DateOnly? RatingUserLastRatingDateFrom { get; set; }
[FromQuery(Name = "rating_user_last_rating_date_to")]
[AliasAs("rating_user_last_rating_date_to")]
public DateOnly? RatingUserLastRatingDateTo { get; set; }
[FromRoute(Name = "id")]
public long AccountId { get; set; }
#endregion
#region PUBLIC METHODS
public IEnumerable<Filter<Database.Model.People.Person>> GetFilters() =>
[
new PersonRatingUserAverageFromFilter(RatingUserAverageFrom, AccountId),
new PersonRatingUserAverageToFilter(RatingUserAverageTo, AccountId),
new PersonRatingUserCountFromFilter(RatingUserCountFrom, AccountId),
new PersonRatingUserCountToFilter(RatingUserCountTo, AccountId),
new PersonRatingUserLastRatingDateFromFilter(RatingUserLastRatingDateFrom, AccountId),
new PersonRatingUserLastRatingDateToFilter(RatingUserLastRatingDateTo, AccountId),
];
#endregion
}